mirror of
https://github.com/korenkonder/ReDIVA.git
synced 2026-10-04 04:37:55 +03:00
11002 lines
345 KiB
C++
11002 lines
345 KiB
C++
/*
|
||
by korenkonder
|
||
GitHub/GitLab: korenkonder
|
||
*/
|
||
|
||
#if defined(ReDIVA_DEV)
|
||
#include "x_pv_game.hpp"
|
||
#include "../CRE/light_param/light.hpp"
|
||
#include "../CRE/light_param.hpp"
|
||
#include "../CRE/rob/rob.hpp"
|
||
#include "../CRE/rob/motion.hpp"
|
||
#include "../CRE/rob/skin_param.hpp"
|
||
#include "../CRE/data.hpp"
|
||
#include "../CRE/effect.hpp"
|
||
#include "../CRE/item_table.hpp"
|
||
#include "../CRE/object.hpp"
|
||
#include "../CRE/pv_expression.hpp"
|
||
#include "../CRE/pv_param.hpp"
|
||
#include "../CRE/random.hpp"
|
||
#include "../CRE/shader_ft.hpp"
|
||
#include "../CRE/sound.hpp"
|
||
#include "../CRE/sprite.hpp"
|
||
#include "../KKdLib/io/file_stream.hpp"
|
||
#include "../KKdLib/io/json.hpp"
|
||
#include "../KKdLib/prj/algorithm.hpp"
|
||
#include "../KKdLib/farc.hpp"
|
||
#include "../KKdLib/interpolation.hpp"
|
||
#include "../KKdLib/msgpack.hpp"
|
||
#include "../KKdLib/sort.hpp"
|
||
#include "../KKdLib/str_utils.hpp"
|
||
#include <meshoptimizer/meshoptimizer.h>
|
||
#if BAKE_PNG
|
||
#include <lodepng/lodepng.h>
|
||
#endif
|
||
#if BAKE_VIDEO
|
||
#include <glad/glad_wgl.h>
|
||
#include <d3d11.h>
|
||
#include "../CRE/shader_dev.hpp"
|
||
#include "nvenc/nvenc_encoder.hpp"
|
||
#endif
|
||
#if BAKE_PV826
|
||
#include "../KKdLib/waitable_timer.hpp"
|
||
#endif
|
||
#include "information/dw_console.hpp"
|
||
#include "imgui_helper.hpp"
|
||
#include "input.hpp"
|
||
#include "print_work.hpp"
|
||
|
||
enum dsc_x_func {
|
||
DSC_X_END = 0,
|
||
DSC_X_TIME,
|
||
DSC_X_MIKU_MOVE,
|
||
DSC_X_MIKU_ROT,
|
||
DSC_X_MIKU_DISP,
|
||
DSC_X_MIKU_SHADOW,
|
||
DSC_X_TARGET,
|
||
DSC_X_SET_MOTION,
|
||
DSC_X_SET_PLAYDATA,
|
||
DSC_X_EFFECT,
|
||
DSC_X_FADEIN_FIELD,
|
||
DSC_X_EFFECT_OFF,
|
||
DSC_X_SET_CAMERA,
|
||
DSC_X_DATA_CAMERA,
|
||
DSC_X_CHANGE_FIELD,
|
||
DSC_X_HIDE_FIELD,
|
||
DSC_X_MOVE_FIELD,
|
||
DSC_X_FADEOUT_FIELD,
|
||
DSC_X_EYE_ANIM,
|
||
DSC_X_MOUTH_ANIM,
|
||
DSC_X_HAND_ANIM,
|
||
DSC_X_LOOK_ANIM,
|
||
DSC_X_EXPRESSION,
|
||
DSC_X_LOOK_CAMERA,
|
||
DSC_X_LYRIC,
|
||
DSC_X_MUSIC_PLAY,
|
||
DSC_X_MODE_SELECT,
|
||
DSC_X_EDIT_MOTION,
|
||
DSC_X_BAR_TIME_SET,
|
||
DSC_X_SHADOWHEIGHT,
|
||
DSC_X_EDIT_FACE,
|
||
DSC_X_DUMMY,
|
||
DSC_X_PV_END,
|
||
DSC_X_SHADOWPOS,
|
||
DSC_X_EDIT_LYRIC,
|
||
DSC_X_EDIT_TARGET,
|
||
DSC_X_EDIT_MOUTH,
|
||
DSC_X_SET_CHARA,
|
||
DSC_X_EDIT_MOVE,
|
||
DSC_X_EDIT_SHADOW,
|
||
DSC_X_EDIT_EYELID,
|
||
DSC_X_EDIT_EYE,
|
||
DSC_X_EDIT_ITEM,
|
||
DSC_X_EDIT_EFFECT,
|
||
DSC_X_EDIT_DISP,
|
||
DSC_X_EDIT_HAND_ANIM,
|
||
DSC_X_AIM,
|
||
DSC_X_HAND_ITEM,
|
||
DSC_X_EDIT_BLUSH,
|
||
DSC_X_NEAR_CLIP,
|
||
DSC_X_CLOTH_WET,
|
||
DSC_X_LIGHT_ROT,
|
||
DSC_X_SCENE_FADE,
|
||
DSC_X_TONE_TRANS,
|
||
DSC_X_SATURATE,
|
||
DSC_X_FADE_MODE,
|
||
DSC_X_AUTO_BLINK,
|
||
DSC_X_PARTS_DISP,
|
||
DSC_X_TARGET_FLYING_TIME,
|
||
DSC_X_CHARA_SIZE,
|
||
DSC_X_CHARA_HEIGHT_ADJUST,
|
||
DSC_X_ITEM_ANIM,
|
||
DSC_X_CHARA_POS_ADJUST,
|
||
DSC_X_SCENE_ROT,
|
||
DSC_X_EDIT_MOT_SMOOTH_LEN,
|
||
DSC_X_PV_BRANCH_MODE,
|
||
DSC_X_DATA_CAMERA_START,
|
||
DSC_X_MOVIE_PLAY,
|
||
DSC_X_MOVIE_DISP,
|
||
DSC_X_WIND,
|
||
DSC_X_OSAGE_STEP,
|
||
DSC_X_OSAGE_MV_CCL,
|
||
DSC_X_CHARA_COLOR,
|
||
DSC_X_SE_EFFECT,
|
||
DSC_X_CHARA_SHADOW_QUALITY,
|
||
DSC_X_STAGE_SHADOW_QUALITY,
|
||
DSC_X_COMMON_LIGHT,
|
||
DSC_X_TONE_MAP,
|
||
DSC_X_IBL_COLOR,
|
||
DSC_X_REFLECTION,
|
||
DSC_X_CHROMATIC_ABERRATION,
|
||
DSC_X_STAGE_SHADOW,
|
||
DSC_X_REFLECTION_QUALITY,
|
||
DSC_X_PV_END_FADEOUT,
|
||
DSC_X_CREDIT_TITLE,
|
||
DSC_X_BAR_POINT,
|
||
DSC_X_BEAT_POINT,
|
||
DSC_X_RESERVE1,
|
||
DSC_X_PV_AUTH_LIGHT_PRIORITY,
|
||
DSC_X_PV_CHARA_LIGHT,
|
||
DSC_X_PV_STAGE_LIGHT,
|
||
DSC_X_TARGET_EFFECT,
|
||
DSC_X_FOG,
|
||
DSC_X_BLOOM,
|
||
DSC_X_COLOR_CORRECTION,
|
||
DSC_X_DOF,
|
||
DSC_X_CHARA_ALPHA,
|
||
DSC_X_AUTO_CAPTURE_BEGIN,
|
||
DSC_X_MANUAL_CAPTURE,
|
||
DSC_X_TOON_EDGE,
|
||
DSC_X_SHIMMER,
|
||
DSC_X_ITEM_ALPHA,
|
||
DSC_X_MOVIE_CUT,
|
||
DSC_X_EDIT_CAMERA_BOX,
|
||
DSC_X_EDIT_STAGE_PARAM,
|
||
DSC_X_EDIT_CHANGE_FIELD,
|
||
DSC_X_MIKUDAYO_ADJUST,
|
||
DSC_X_LYRIC_2,
|
||
DSC_X_LYRIC_READ,
|
||
DSC_X_LYRIC_READ_2,
|
||
DSC_X_ANNOTATION,
|
||
DSC_X_STAGE_EFFECT,
|
||
DSC_X_SONG_EFFECT,
|
||
DSC_X_SONG_EFFECT_ATTACH,
|
||
DSC_X_LIGHT_AUTH,
|
||
DSC_X_FADE,
|
||
DSC_X_SET_STAGE_EFFECT_ENV,
|
||
DSC_X_RESERVE2,
|
||
DSC_X_COMMON_EFFECT_AET_FRONT,
|
||
DSC_X_COMMON_EFFECT_AET_FRONT_LOW,
|
||
DSC_X_COMMON_EFFECT_PARTICLE,
|
||
DSC_X_SONG_EFFECT_ALPHA_SORT,
|
||
DSC_X_LOOK_CAMERA_FACE_LIMIT,
|
||
DSC_X_ITEM_LIGHT,
|
||
DSC_X_CHARA_EFFECT,
|
||
DSC_X_MARKER,
|
||
DSC_X_CHARA_EFFECT_CHARA_LIGHT,
|
||
DSC_X_ENABLE_COMMON_LIGHT_TO_CHARA,
|
||
DSC_X_ENABLE_FXAA,
|
||
DSC_X_ENABLE_TEMPORAL_AA,
|
||
DSC_X_ENABLE_REFLECTION,
|
||
DSC_X_BANK_BRANCH,
|
||
DSC_X_BANK_END,
|
||
DSC_X_NULL1,
|
||
DSC_X_NULL2,
|
||
DSC_X_NULL3,
|
||
DSC_X_NULL4,
|
||
DSC_X_NULL5,
|
||
DSC_X_NULL6,
|
||
DSC_X_NULL7,
|
||
DSC_X_NULL8,
|
||
DSC_X_VR_LIVE_MOVIE,
|
||
DSC_X_VR_CHEER,
|
||
DSC_X_VR_CHARA_PSMOVE,
|
||
DSC_X_VR_MOVE_PATH,
|
||
DSC_X_VR_SET_BASE,
|
||
DSC_X_VR_TECH_DEMO_EFFECT,
|
||
DSC_X_VR_TRANSFORM,
|
||
DSC_X_GAZE,
|
||
DSC_X_TECH_DEMO_GESUTRE,
|
||
DSC_X_VR_CHEMICAL_LIGHT_COLOR,
|
||
DSC_X_VR_LIVE_MOB,
|
||
DSC_X_VR_LIVE_HAIR_OSAGE,
|
||
DSC_X_VR_LIVE_LOOK_CAMERA,
|
||
DSC_X_VR_LIVE_CHEER,
|
||
DSC_X_VR_LIVE_GESTURE,
|
||
DSC_X_VR_LIVE_CLONE,
|
||
DSC_X_VR_LOOP_EFFECT,
|
||
DSC_X_VR_LIVE_ONESHOT_EFFECT,
|
||
DSC_X_VR_LIVE_PRESENT,
|
||
DSC_X_VR_LIVE_TRANSFORM,
|
||
DSC_X_VR_LIVE_FLY,
|
||
DSC_X_VR_LIVE_CHARA_VOICE,
|
||
DSC_X_MAX,
|
||
};
|
||
|
||
#if BAKE_DOF
|
||
struct dof_cam {
|
||
std::vector<float_t> position_x;
|
||
std::vector<float_t> position_y;
|
||
std::vector<float_t> position_z;
|
||
std::vector<float_t> focus;
|
||
std::vector<float_t> focus_range;
|
||
std::vector<float_t> fuzzing_range;
|
||
std::vector<float_t> ratio;
|
||
prj::vector_pair<int32_t, bool> enable_frame;
|
||
int32_t frame;
|
||
bool enable;
|
||
|
||
dof_cam();
|
||
~dof_cam();
|
||
|
||
void reset();
|
||
};
|
||
#endif
|
||
|
||
static int32_t aet_index_table[] = { 0, 1, 2, 6, 5 };
|
||
|
||
#if BAKE_DOF
|
||
dof_cam dof_cam_data;
|
||
#endif
|
||
x_pv_game* x_pv_game_ptr;
|
||
|
||
prj::vector_pair<int32_t, prj::vector_pair<int32_t, std::string>> x_pv_game_str_array;
|
||
int32_t x_pv_game_str_array_lang_sel;
|
||
|
||
#if BAKE_X_PACK
|
||
XPVGameBaker* x_pv_game_baker_ptr;
|
||
#else
|
||
XPVGameSelector* x_pv_game_selector_ptr;
|
||
#endif
|
||
|
||
#if !BAKE_FAST
|
||
x_pv_game_music* x_pv_game_music_ptr;
|
||
#endif
|
||
|
||
extern render_context* rctx_ptr;
|
||
|
||
static vec4 bright_scale_get(int32_t index, float_t value);
|
||
|
||
static float_t dsc_time_to_frame(int64_t time);
|
||
static vec3 x_pv_game_dof_callback(void* data, int32_t chara_id);
|
||
static void x_pv_game_item_alpha_callback(void* data, int32_t chara_id, int32_t type, float_t alpha);
|
||
static void x_pv_game_change_field(x_pv_game* xpvgm, int32_t field, int64_t dsc_time, int64_t curr_time);
|
||
#if BAKE_PV826
|
||
static void x_pv_game_map_auth_3d_to_mot(x_pv_game* xpvgm, bool add_keys);
|
||
#endif
|
||
static void x_pv_game_reset_field(x_pv_game* xpvgm);
|
||
|
||
#if BAKE_X_PACK
|
||
static void x_pv_game_update_object_set(ObjsetInfo* info);
|
||
static void x_pv_game_write_aet(uint32_t aet_set_id,
|
||
const aet_database* aet_db, aet_database_file* x_pack_aet_db,
|
||
const sprite_database_file* x_pack_spr_db);
|
||
static bool x_pv_game_write_auth_3d(farc* f, auth_3d* auth,
|
||
auth_3d_database_file* auth_3d_db, const char* category);
|
||
static void x_pv_game_write_dsc(const dsc& d, int32_t pv_id);
|
||
static void x_pv_game_write_glitter(Glitter::EffectGroup* eff_group, const auth_3d_database* x_pack_auth_3d_db,
|
||
const object_database* obj_db, const object_database* x_pack_obj_db);
|
||
static void x_pv_game_write_object_set(ObjsetInfo* info,
|
||
object_database_file* x_pack_obj_db, const texture_database* tex_db,
|
||
const texture_database* x_pack_tex_db_base, texture_database_file* x_pack_tex_db);
|
||
static void x_pv_game_write_play_param(pvpp* play_param,
|
||
int32_t pv_id, const auth_3d_database* x_pack_auth_3d_db);
|
||
static void x_pv_game_write_stage_resource(pvsr* stage_resource,
|
||
int32_t stage_id, const auth_3d_database* x_pack_auth_3d_db);
|
||
static void x_pv_game_write_spr(uint32_t spr_set_id,
|
||
const sprite_database* spr_db, sprite_database_file* x_pack_spr_db);
|
||
#endif
|
||
|
||
static void print_dsc_command(dsc& dsc, dsc_data* dsc_data_ptr, int64_t time);
|
||
static void print_dsc_command(dsc& dsc, dsc_data* dsc_data_ptr, int64_t* time);
|
||
|
||
#if BAKE_FAST
|
||
static void replace_pv832(char* str);
|
||
static void replace_pv832(std::string& str);
|
||
#endif
|
||
|
||
#if BAKE_X_PACK
|
||
static bool get_replace_auth_name(char* name, size_t name_size, auth_3d* auth);
|
||
static void replace_names(char* str);
|
||
static void replace_names(std::string& str);
|
||
static size_t replace_stgpv_pv(char* str);
|
||
static void replace_stgpv_pv(std::string& str);
|
||
static object_info replace_object_info(object_info info,
|
||
const object_database* src_obj_db, const object_database* dst_obj_db);
|
||
static uint32_t replace_texture_id(uint32_t id,
|
||
const texture_database* src_tex_db, const texture_database* dst_tex_db);
|
||
#endif
|
||
|
||
bool x_pv_bar_beat_data::compare_bar_time_less(float_t time) {
|
||
return (time + 0.0001f) < bar_time;
|
||
}
|
||
|
||
x_pv_bar_beat::x_pv_bar_beat() : curr_time(), delta_time(), next_bar_time(),
|
||
curr_bar_time(), next_beat_time(), curr_beat_time(), bar(), counter() {
|
||
reset();
|
||
}
|
||
|
||
x_pv_bar_beat::~x_pv_bar_beat() {
|
||
|
||
}
|
||
|
||
float_t x_pv_bar_beat::get_bar_current_frame() {
|
||
return (curr_time - curr_bar_time) / (next_bar_time - curr_bar_time) * 120.0f;
|
||
}
|
||
|
||
float_t x_pv_bar_beat::get_delta_frame() {
|
||
return delta_time / (next_bar_time - curr_bar_time) * 120.0f;
|
||
}
|
||
|
||
int32_t x_pv_bar_beat::get_bar_beat_from_time(int32_t* beat, float_t time) {
|
||
if (!data.size()) {
|
||
int32_t bar = (int32_t)(float_t)(time / divisor);
|
||
if (beat)
|
||
*beat = (int32_t)(4.0f * (time - (float_t)(int32_t)(time / divisor) * divisor) / divisor) + 1;
|
||
return bar + 1;
|
||
}
|
||
|
||
x_pv_bar_beat_data* d = data.data();
|
||
const size_t size = data.size();
|
||
|
||
size_t length = size;
|
||
size_t temp;
|
||
while (length > 0)
|
||
if (d[temp = length / 2].compare_bar_time_less(time))
|
||
length = temp;
|
||
else {
|
||
d += temp + 1;
|
||
length -= temp + 1;
|
||
}
|
||
|
||
if (d == data.data() + size) {
|
||
float_t divisor = this->divisor;
|
||
float_t diff_time = time - data.back().bar_time;
|
||
|
||
if (size > 1)
|
||
divisor = data[size - 1].bar_time - data[size - 2].bar_time;
|
||
|
||
if (beat)
|
||
*beat = (int32_t)((float_t)data.back().beat_count * (diff_time
|
||
- (float_t)(int32_t)(diff_time / divisor) * divisor) / divisor) + 1;
|
||
return (int32_t)(diff_time / divisor) + data.back().bar;
|
||
}
|
||
|
||
int32_t bar = d->bar - 1;
|
||
if (beat) {
|
||
*beat = 1;
|
||
if (d == data.data())
|
||
*beat = (int32_t)((float_t)d->beat_count * time / d->bar_time) + 1;
|
||
else {
|
||
int32_t v18 = d[-1].beat_count - 1;
|
||
if (v18 >= 0) {
|
||
float_t* v19 = &d[-1].beat_time[v18];
|
||
for (; *v19 > time; v19--)
|
||
if (--v18 < 0)
|
||
return bar;
|
||
*beat = v18 + 1;
|
||
}
|
||
}
|
||
}
|
||
return bar;
|
||
}
|
||
|
||
float_t x_pv_bar_beat::get_next_bar_time(float_t time) {
|
||
x_pv_bar_beat_data* d = data.data();
|
||
const size_t size = data.size();
|
||
|
||
size_t length = size;
|
||
size_t temp;
|
||
while (length > 0)
|
||
if (d[temp = length / 2].compare_bar_time_less(time))
|
||
length = temp;
|
||
else {
|
||
d += temp + 1;
|
||
length -= temp + 1;
|
||
}
|
||
|
||
if (d == data.data() + data.size()) {
|
||
float_t v11 = 0.0f;
|
||
float_t v12 = divisor;
|
||
if (data.size())
|
||
v11 = data.back().bar_time;
|
||
|
||
float_t bar_time = (float_t)((int32_t)((time - v11) / v12) + 1) * v12 + v11;
|
||
if (bar_time < time + 0.00001f)
|
||
bar_time += v12;
|
||
return bar_time;
|
||
}
|
||
else
|
||
return d->bar_time;
|
||
}
|
||
|
||
float_t x_pv_bar_beat::get_next_beat_time(float_t time) {
|
||
x_pv_bar_beat_data* d = data.data();
|
||
const size_t size = data.size();
|
||
|
||
size_t length = size;
|
||
size_t temp;
|
||
while (length > 0)
|
||
if (d[temp = length / 2].compare_bar_time_less(time))
|
||
length = temp;
|
||
else {
|
||
d += temp + 1;
|
||
length -= temp + 1;
|
||
}
|
||
|
||
if (d == data.data() + size) {
|
||
float_t v12 = 0.0f;
|
||
float_t v13 = divisor * 0.25f;
|
||
if (size) {
|
||
v12 = data[size - 1].bar_time;
|
||
v13 = v12 - data[size - 2].beat_time[data[size - 2].beat_count - 1];
|
||
}
|
||
|
||
float_t beat_time = (float_t)((int32_t)((time - v12) / v13) + 1) * v13 + v12;
|
||
if (beat_time < time + 0.00001f)
|
||
beat_time += v13;
|
||
return beat_time;
|
||
}
|
||
else if (d != data.data()) {
|
||
int32_t v9 = d[-1].beat_count - 1;
|
||
if (v9 >= 0) {
|
||
float_t* beat_time = &d[-1].beat_time[v9];
|
||
for (; time >= *beat_time; beat_time--)
|
||
if (--v9 < 0)
|
||
return d->bar_time;
|
||
return *beat_time;
|
||
}
|
||
}
|
||
return d->bar_time;
|
||
}
|
||
|
||
float_t x_pv_bar_beat::get_time_from_bar_beat(int32_t bar, int32_t beat) {
|
||
if (bar < 0)
|
||
return 0.0f;
|
||
|
||
x_pv_bar_beat_data* d = data.data();
|
||
const size_t size = data.size();
|
||
|
||
int32_t beat_count;
|
||
if (size) {
|
||
int32_t bar_diff = bar - d->bar;
|
||
if (bar_diff < 0)
|
||
beat_count = d->beat_count;
|
||
else if (size > bar_diff)
|
||
beat_count = d[bar_diff].beat_count;
|
||
else
|
||
beat_count = d[size - 1].beat_count;
|
||
|
||
if (!beat_count)
|
||
beat_count = 4;
|
||
}
|
||
else
|
||
beat_count = 4;
|
||
|
||
beat--;
|
||
if (!size)
|
||
return (float_t)beat * divisor / (float_t)beat_count + (bar - 1) * divisor;
|
||
|
||
int32_t bar_diff = bar - d->bar;
|
||
if (bar_diff < 0)
|
||
return 0.0f;
|
||
|
||
if (size <= bar_diff) {
|
||
float_t divisor = this->divisor;
|
||
if (size > 1)
|
||
divisor = d[size - 1].bar_time - d[size - 2].bar_time;
|
||
return (float_t)beat * divisor / (float_t)beat_count
|
||
+ (bar - d[size - 1].bar) * divisor + d[size - 1].bar_time;
|
||
}
|
||
else if (beat < 0 || beat >= d[bar_diff].beat_count)
|
||
return d[bar_diff].bar_time;
|
||
else
|
||
return d[bar_diff].beat_time[beat];
|
||
}
|
||
|
||
void x_pv_bar_beat::reset() {
|
||
curr_time = 0.0f;
|
||
delta_time = 0.0f;
|
||
next_bar_time = 0.0f;
|
||
curr_bar_time = 0.0f;
|
||
next_beat_time = 0.0f;
|
||
curr_beat_time = 0.0f;
|
||
divisor = 2.0f;
|
||
bar = 0;
|
||
data.clear();
|
||
data.shrink_to_fit();
|
||
}
|
||
|
||
void x_pv_bar_beat::reset_time() {
|
||
curr_time = 0.0f;
|
||
delta_time = 0.0f;
|
||
curr_bar_time = 0.0f;
|
||
next_bar_time = get_next_bar_time(0.0f);
|
||
curr_beat_time = 0.0f;
|
||
next_beat_time = get_next_beat_time(0.0f);
|
||
bar = 1;
|
||
counter = 0;
|
||
}
|
||
|
||
void x_pv_bar_beat::set_frame(float_t curr_frame, float_t delta_frame) {
|
||
set_time(curr_frame * (float_t)(1.0 / 60.0), delta_frame * (float_t)(1.0 / 60.0));
|
||
}
|
||
|
||
void x_pv_bar_beat::set_time(float_t curr_time, float_t delta_time) {
|
||
if (next_bar_time <= 0.0f)
|
||
return;
|
||
|
||
this->curr_time = curr_time;
|
||
this->delta_time = delta_time;
|
||
counter = 0;
|
||
|
||
while (curr_time >= next_bar_time) {
|
||
curr_bar_time = next_bar_time;
|
||
bar++;
|
||
counter++;
|
||
next_bar_time = get_next_bar_time(next_bar_time);
|
||
}
|
||
|
||
while (curr_time >= next_beat_time) {
|
||
curr_beat_time = next_beat_time;
|
||
next_beat_time = get_next_beat_time(next_beat_time);
|
||
}
|
||
}
|
||
|
||
BPMFrameRateControl::BPMFrameRateControl() : bar_beat() {
|
||
|
||
}
|
||
|
||
BPMFrameRateControl::~BPMFrameRateControl() {
|
||
|
||
}
|
||
|
||
float_t BPMFrameRateControl::get_delta_frame() {
|
||
if (bar_beat)
|
||
return bar_beat->get_delta_frame();
|
||
return 0.0f;
|
||
}
|
||
|
||
void BPMFrameRateControl::reset() {
|
||
bar_beat = 0;
|
||
set_frame_speed(1.0f);
|
||
}
|
||
|
||
XPVFrameRateControl::XPVFrameRateControl() {
|
||
|
||
}
|
||
|
||
XPVFrameRateControl::~XPVFrameRateControl() {
|
||
|
||
}
|
||
|
||
float_t XPVFrameRateControl::get_delta_frame() {
|
||
return ::get_delta_frame() * frame_speed;
|
||
}
|
||
|
||
void XPVFrameRateControl::reset() {
|
||
frame_speed = 1.0f;
|
||
}
|
||
|
||
x_pv_play_data_motion_data::x_pv_play_data_motion_data() : rob_chr(), current_time(),
|
||
duration(), start_pos(), end_pos(), start_rot(), end_rot() {
|
||
mot_smooth_len = 12.0f;
|
||
}
|
||
|
||
x_pv_play_data_motion_data::~x_pv_play_data_motion_data() {
|
||
|
||
}
|
||
|
||
void x_pv_play_data_motion_data::reset() {
|
||
rob_chr = 0;
|
||
current_time = 0.0f;
|
||
duration = 0.0f;
|
||
start_pos = 0.0f;
|
||
end_pos = 0.0f;
|
||
start_rot = 0.0f;
|
||
end_rot = 0.0f;
|
||
mot_smooth_len = 12.0f;
|
||
set_motion.clear();
|
||
set_motion.shrink_to_fit();
|
||
set_item.clear();
|
||
set_item.shrink_to_fit();
|
||
}
|
||
|
||
x_pv_play_data::x_pv_play_data() : rob_chr(), disp() {
|
||
|
||
}
|
||
|
||
x_pv_play_data::~x_pv_play_data() {
|
||
|
||
}
|
||
|
||
x_pv_play_data_motion* x_pv_play_data::get_motion(int32_t motion_index) {
|
||
for (x_pv_play_data_motion& i : motion)
|
||
if (i.motion_index == motion_index)
|
||
return &i;
|
||
return 0;
|
||
}
|
||
|
||
void x_pv_play_data::reset() {
|
||
if (rob_chr) {
|
||
data_struct* aft_data = &data_list[DATA_AFT];
|
||
bone_database* aft_bone_data = &aft_data->data_ft.bone_data;
|
||
motion_database* aft_mot_db = &aft_data->data_ft.mot_db;
|
||
|
||
int32_t mottbl_index = hand_anim_id_to_mottbl_index(2);
|
||
|
||
rob_chr->reset_data(&rob_chr->pv_data, aft_bone_data, aft_mot_db);
|
||
rob_chr->set_hand_l_mottbl_motion(0, mottbl_index, 1.0f, 0, 0.0f, 0.0f, 1.0f, -1, 0.0f, aft_mot_db);
|
||
rob_chr->set_hand_r_mottbl_motion(0, mottbl_index, 1.0f, 0, 0.0f, 0.0f, 1.0f, -1, 0.0f, aft_mot_db);
|
||
rob_chr->set_visibility(false);
|
||
}
|
||
|
||
motion.clear();
|
||
motion.shrink_to_fit();
|
||
rob_chr = 0;
|
||
set_motion.clear();
|
||
disp = true;
|
||
motion_data.reset();
|
||
}
|
||
|
||
#if BAKE_PV826
|
||
x_pv_game_a3da_to_mot_keys::x_pv_game_a3da_to_mot_keys() {
|
||
|
||
}
|
||
|
||
x_pv_game_a3da_to_mot_keys::~x_pv_game_a3da_to_mot_keys() {
|
||
|
||
}
|
||
|
||
x_pv_game_a3da_to_mot::x_pv_game_a3da_to_mot(auth_3d_id id) {
|
||
this->id = id;
|
||
gblctr = -1;
|
||
n_hara = -1;
|
||
n_hara_y = -1;
|
||
j_hara_wj = -1;
|
||
n_kosi = -1;
|
||
j_mune_wj = -1;
|
||
n_mune_kl = -1;
|
||
j_mune_b_wj = -1;
|
||
j_kubi_wj = -1;
|
||
n_kao = -1;
|
||
j_kao_wj = -1;
|
||
j_kao_normal_wj = -1;
|
||
j_kao_close_wj = -1;
|
||
j_kao_smile_wj = -1;
|
||
j_kao_close_half_wj = -1;
|
||
j_kao_smile_half_wj = -1;
|
||
j_kuti_l_wj = -1;
|
||
j_kuti_u_wj = -1;
|
||
j_kuti_d_wj = -1;
|
||
j_kuti_r_wj = -1;
|
||
j_eye_r_wj = -1;
|
||
j_eye_l_wj = -1;
|
||
n_waki_l = -1;
|
||
j_waki_l_wj = -1;
|
||
n_kata_l = -1;
|
||
j_kata_l_wj = -1;
|
||
j_ude_l_wj = -1;
|
||
j_te_l_wj = -1;
|
||
j_te_sizen2_l_wj = -1;
|
||
j_te_close_l_wj = -1;
|
||
j_te_reset_l_wj = -1;
|
||
n_waki_r = -1;
|
||
j_waki_r_wj = -1;
|
||
n_kata_r = -1;
|
||
j_kata_r_wj = -1;
|
||
j_ude_r_wj = -1;
|
||
j_te_r_wj = -1;
|
||
j_te_sizen2_r_wj = -1;
|
||
j_te_close_r_wj = -1;
|
||
j_te_reset_r_wj = -1;
|
||
j_te_one_r_wj = -1;
|
||
j_kosi_wj = -1;
|
||
n_momo_l = -1;
|
||
j_momo_l_wj = -1;
|
||
j_sune_l_wj = -1;
|
||
j_asi_l_wj = -1;
|
||
n_momo_r = -1;
|
||
j_momo_r_wj = -1;
|
||
j_sune_r_wj = -1;
|
||
j_asi_r_wj = -1;
|
||
}
|
||
|
||
x_pv_game_a3da_to_mot::~x_pv_game_a3da_to_mot() {
|
||
|
||
}
|
||
|
||
static int32_t get_bone_index(auth_3d_object_hrc* oh, const char* name) {
|
||
uint32_t name_hash = hash_utf8_murmurhash(name);
|
||
for (auth_3d_object_node& i : oh->node)
|
||
if (hash_string_murmurhash(i.name) == name_hash)
|
||
return (int32_t)(&i - oh->node.data());
|
||
return -1;
|
||
}
|
||
|
||
void x_pv_game_a3da_to_mot::get_bone_indices(auth_3d_object_hrc* oh) {
|
||
gblctr = get_bone_index(oh, "gblctr");
|
||
n_hara = get_bone_index(oh, "n_hara");
|
||
n_hara_y = get_bone_index(oh, "n_hara_y");
|
||
j_hara_wj = get_bone_index(oh, "j_hara_wj");
|
||
n_kosi = get_bone_index(oh, "n_kosi");
|
||
j_mune_wj = get_bone_index(oh, "j_mune_wj");
|
||
n_mune_kl = get_bone_index(oh, "n_mune_kl");
|
||
j_mune_b_wj = get_bone_index(oh, "j_mune_b_wj");
|
||
j_kubi_wj = get_bone_index(oh, "j_kubi_wj");
|
||
n_kao = get_bone_index(oh, "n_kao");
|
||
j_kao_wj = get_bone_index(oh, "j_kao_wj");
|
||
j_kao_normal_wj = get_bone_index(oh, "j_kao_normal_wj");
|
||
j_kao_close_wj = get_bone_index(oh, "j_kao_close_wj");
|
||
j_kao_smile_wj = get_bone_index(oh, "j_kao_smile_wj");
|
||
j_kao_close_half_wj = get_bone_index(oh, "j_kao_close_half_wj");
|
||
j_kao_smile_half_wj = get_bone_index(oh, "j_kao_smile_half_wj");
|
||
j_kuti_l_wj = get_bone_index(oh, "j_kuti_l_wj");
|
||
j_kuti_u_wj = get_bone_index(oh, "j_kuti_u_wj");
|
||
j_kuti_d_wj = get_bone_index(oh, "j_kuti_d_wj");
|
||
j_kuti_r_wj = get_bone_index(oh, "j_kuti_r_wj");
|
||
j_eye_r_wj = get_bone_index(oh, "j_eye_r_wj");
|
||
j_eye_l_wj = get_bone_index(oh, "j_eye_l_wj");
|
||
n_waki_l = get_bone_index(oh, "n_waki_l");
|
||
j_waki_l_wj = get_bone_index(oh, "j_waki_l_wj");
|
||
n_kata_l = get_bone_index(oh, "n_kata_l");
|
||
j_kata_l_wj = get_bone_index(oh, "j_kata_l_wj");
|
||
j_ude_l_wj = get_bone_index(oh, "j_ude_l_wj");
|
||
j_te_l_wj = get_bone_index(oh, "j_te_l_wj");
|
||
j_te_sizen2_l_wj = get_bone_index(oh, "j_te_sizen2_l_wj");
|
||
j_te_close_l_wj = get_bone_index(oh, "j_te_close_l_wj");
|
||
j_te_reset_l_wj = get_bone_index(oh, "j_te_reset_l_wj");
|
||
n_waki_r = get_bone_index(oh, "n_waki_r");
|
||
j_waki_r_wj = get_bone_index(oh, "j_waki_r_wj");
|
||
n_kata_r = get_bone_index(oh, "n_kata_r");
|
||
j_kata_r_wj = get_bone_index(oh, "j_kata_r_wj");
|
||
j_ude_r_wj = get_bone_index(oh, "j_ude_r_wj");
|
||
j_te_r_wj = get_bone_index(oh, "j_te_r_wj");
|
||
j_te_sizen2_r_wj = get_bone_index(oh, "j_te_sizen2_r_wj");
|
||
j_te_close_r_wj = get_bone_index(oh, "j_te_close_r_wj");
|
||
j_te_reset_r_wj = get_bone_index(oh, "j_te_reset_r_wj");
|
||
j_te_one_r_wj = get_bone_index(oh, "j_te_one_r_wj");
|
||
j_kosi_wj = get_bone_index(oh, "j_kosi_wj");
|
||
n_momo_l = get_bone_index(oh, "n_momo_l");
|
||
j_momo_l_wj = get_bone_index(oh, "j_momo_l_wj");
|
||
j_sune_l_wj = get_bone_index(oh, "j_sune_l_wj");
|
||
j_asi_l_wj = get_bone_index(oh, "j_asi_l_wj");
|
||
n_momo_r = get_bone_index(oh, "n_momo_r");
|
||
j_momo_r_wj = get_bone_index(oh, "j_momo_r_wj");
|
||
j_sune_r_wj = get_bone_index(oh, "j_sune_r_wj");
|
||
j_asi_r_wj = get_bone_index(oh, "j_asi_r_wj");
|
||
}
|
||
#endif
|
||
|
||
x_pv_game_song_effect_auth_3d::x_pv_game_song_effect_auth_3d() {
|
||
|
||
}
|
||
|
||
x_pv_game_song_effect_auth_3d::x_pv_game_song_effect_auth_3d(auth_3d_id id) {
|
||
this->id = id;
|
||
}
|
||
|
||
void x_pv_game_song_effect_auth_3d::reset() {
|
||
id = {};
|
||
}
|
||
|
||
x_pv_game_song_effect_glitter::x_pv_game_song_effect_glitter() : scene_counter(), field_8(), field_9() {
|
||
reset();
|
||
}
|
||
|
||
x_pv_game_song_effect_glitter::~x_pv_game_song_effect_glitter() {
|
||
|
||
}
|
||
|
||
void x_pv_game_song_effect_glitter::reset() {
|
||
name.clear();
|
||
scene_counter = 0;
|
||
field_8 = false;
|
||
for (bool& i : field_9)
|
||
i = false;
|
||
}
|
||
|
||
x_pv_game_song_effect::x_pv_game_song_effect() : enable(), chara_id(), time() {
|
||
reset();
|
||
}
|
||
|
||
x_pv_game_song_effect::~x_pv_game_song_effect() {
|
||
|
||
}
|
||
|
||
void x_pv_game_song_effect::reset() {
|
||
enable = false;
|
||
chara_id = -1;
|
||
time = -1;
|
||
auth_3d.clear();
|
||
auth_3d.shrink_to_fit();
|
||
glitter.clear();
|
||
glitter.shrink_to_fit();
|
||
}
|
||
|
||
x_pv_game_camera::x_pv_game_camera() : state() {
|
||
reset();
|
||
}
|
||
|
||
x_pv_game_camera::~x_pv_game_camera() {
|
||
|
||
}
|
||
|
||
void x_pv_game_camera::ctrl(float_t curr_time) {
|
||
switch (state) {
|
||
case 10: {
|
||
if (!auth_3d_data_check_category_loaded(category.hash_murmurhash))
|
||
break;
|
||
|
||
auth_3d_id id = auth_3d_id(file.hash_murmurhash, &data_list[DATA_X], 0, 0);
|
||
if (id.check_not_empty()) {
|
||
id.read_file_modern();
|
||
id.set_enable(false);
|
||
id.set_repeat(false);
|
||
id.set_paused(false);
|
||
id.set_frame_rate(frame_rate_control);
|
||
}
|
||
|
||
this->id = id;
|
||
rctx_ptr->camera->reset();
|
||
state = 11;
|
||
} break;
|
||
case 11: {
|
||
if (id.check_not_empty() && id.check_loaded())
|
||
state = 20;
|
||
} break;
|
||
case 20: {
|
||
auth_3d_id& id = this->id;
|
||
id.set_enable(true);
|
||
id.set_repeat(false);
|
||
id.set_paused(false);
|
||
id.set_camera_root_update(true);
|
||
id.set_req_frame(curr_time * 60.0f);
|
||
} break;
|
||
}
|
||
}
|
||
|
||
void x_pv_game_camera::load(int32_t pv_id, int32_t stage_id, FrameRateControl* frame_rate_control) {
|
||
char buf[0x200];
|
||
sprintf_s(buf, sizeof(buf), "CAMPV%03d", pv_id);
|
||
category.assign(buf);
|
||
|
||
if ((pv_id % 100) >= 25 && (pv_id % 100) <= 30 && stage_id >= 25 && stage_id <= 30)
|
||
sprintf_s(buf, sizeof(buf), "CAMPV%03d_100", pv_id);
|
||
else
|
||
sprintf_s(buf, sizeof(buf), "CAMPV%03d_BASE", pv_id);
|
||
file.assign(buf);
|
||
|
||
this->frame_rate_control = frame_rate_control;
|
||
}
|
||
|
||
void x_pv_game_camera::load_data() {
|
||
if (state || !category.str.size())
|
||
return;
|
||
|
||
auth_3d_data_load_category(&data_list[DATA_X], category.c_str(), category.hash_murmurhash);
|
||
state = 10;
|
||
}
|
||
|
||
void x_pv_game_camera::reset() {
|
||
state = 0;
|
||
category.clear();
|
||
file.clear();
|
||
id = {};
|
||
}
|
||
|
||
void x_pv_game_camera::stop() {
|
||
if (id.check_not_empty())
|
||
id.set_enable(false);
|
||
}
|
||
|
||
void x_pv_game_camera::unload() {
|
||
unload_data();
|
||
}
|
||
|
||
void x_pv_game_camera::unload_data() {
|
||
if (state != 20)
|
||
return;
|
||
|
||
id.unload(rctx_ptr);
|
||
auth_3d_data_unload_category(category.hash_murmurhash);
|
||
state = 0;
|
||
}
|
||
|
||
x_pv_game_effect::x_pv_game_effect() : flags(), state(),
|
||
play_param(), change_fields(), frame_rate_control() {
|
||
reset();
|
||
}
|
||
|
||
x_pv_game_effect::~x_pv_game_effect() {
|
||
|
||
}
|
||
|
||
void x_pv_game_effect::ctrl(object_database* obj_db, texture_database* tex_db) {
|
||
switch (state) {
|
||
case 10: {
|
||
bool wait_load = false;
|
||
|
||
for (string_hash& i : pv_auth_3d)
|
||
if (!auth_3d_data_check_category_loaded(i.hash_murmurhash))
|
||
wait_load |= true;
|
||
|
||
for (string_hash& i : pv_obj_set)
|
||
if (object_storage_get_objset_info(i.hash_murmurhash)
|
||
&& object_storage_load_obj_set_check_not_read(i.hash_murmurhash, obj_db, tex_db))
|
||
wait_load |= true;
|
||
|
||
if (wait_load)
|
||
break;
|
||
|
||
data_struct* x_data = &data_list[DATA_X];
|
||
|
||
pvpp* play_param = this->play_param;
|
||
size_t song_effect_count = song_effect.size();
|
||
|
||
for (size_t i = 0; i < song_effect_count; i++) {
|
||
x_pv_game_song_effect& song_effect = this->song_effect[i];
|
||
pvpp_effect& effect = play_param->effect[i];
|
||
for (string_hash& j : effect.auth_3d) {
|
||
auth_3d_id id = auth_3d_id(j.hash_murmurhash, x_data, obj_db, tex_db);
|
||
if (!id.check_not_empty())
|
||
continue;
|
||
|
||
id.read_file_modern();
|
||
id.set_enable(false);
|
||
id.set_repeat(false);
|
||
id.set_paused(false);
|
||
id.set_visibility(false);
|
||
id.set_frame_rate(frame_rate_control);
|
||
song_effect.auth_3d.push_back(id);
|
||
}
|
||
}
|
||
state = 11;
|
||
} break;
|
||
case 11: {
|
||
bool wait_load = false;
|
||
|
||
for (x_pv_game_song_effect& i : song_effect)
|
||
for (x_pv_game_song_effect_auth_3d& j : i.auth_3d)
|
||
if (j.id.check_not_empty() && !j.id.check_loaded())
|
||
wait_load |= true;
|
||
|
||
for (string_hash& i : pv_glitter)
|
||
if (!Glitter::glt_particle_manager->CheckNoFileReaders(i.hash_murmurhash))
|
||
wait_load |= true;
|
||
|
||
if (wait_load)
|
||
break;
|
||
|
||
pvpp* play_param = this->play_param;
|
||
size_t chara_count = play_param->chara.size();
|
||
|
||
size_t song_effect_count = song_effect.size();
|
||
|
||
for (size_t i = 0; i < song_effect_count; i++) {
|
||
x_pv_game_song_effect& song_effect = this->song_effect[i];
|
||
pvpp_effect& effect = play_param->effect[i];
|
||
for (pvpp_glitter& j : effect.glitter) {
|
||
x_pv_game_song_effect_glitter v132;
|
||
v132.name.assign(j.name);
|
||
v132.scene_counter = 0;
|
||
v132.field_8 = !!(j.unk2 & 0x01);
|
||
for (bool& i : v132.field_9)
|
||
i = true;
|
||
|
||
for (int32_t k = 0; k < chara_count && k < ROB_CHARA_COUNT; k++) {
|
||
bool v121 = false;
|
||
if (k < play_param->chara.size()) {
|
||
pvpp_chara& chara = play_param->chara[k];
|
||
for (pvpp_glitter& l : chara.glitter)
|
||
if (j.name.hash_murmurhash == l.name.hash_murmurhash) {
|
||
v121 = true;
|
||
break;
|
||
}
|
||
}
|
||
v132.field_9[k] = v121;
|
||
}
|
||
song_effect.glitter.push_back(v132);
|
||
}
|
||
}
|
||
|
||
for (string_hash& i : pv_glitter)
|
||
Glitter::glt_particle_manager->SetSceneName(i.hash_murmurhash, i.c_str());
|
||
|
||
state = 12;
|
||
break;
|
||
}
|
||
case 12: {
|
||
state = 20;
|
||
break;
|
||
}
|
||
case 20: {
|
||
for (x_pv_game_song_effect& i : song_effect)
|
||
if (i.enable)
|
||
for (x_pv_game_song_effect_auth_3d& j : i.auth_3d)
|
||
j.id.set_chara_id(i.chara_id);
|
||
} break;
|
||
}
|
||
}
|
||
|
||
void x_pv_game_effect::load(int32_t pv_id, pvpp* play_param, FrameRateControl* frame_rate_control) {
|
||
this->play_param = play_param;
|
||
this->frame_rate_control = frame_rate_control;
|
||
|
||
size_t effect_count = play_param->effect.size();
|
||
if (!effect_count)
|
||
return;
|
||
|
||
song_effect.resize(effect_count);
|
||
|
||
for (size_t i = 0; i < effect_count; i++) {
|
||
pvpp_effect& eff = play_param->effect[i];
|
||
if (!eff.auth_3d.size())
|
||
continue;
|
||
|
||
char buf[0x200];
|
||
size_t len = sprintf_s(buf, sizeof(buf), "A3D_EFFPV%03d", pv_id);
|
||
pv_auth_3d.push_back(std::string(buf, len));
|
||
|
||
len = sprintf_s(buf, sizeof(buf), "effpv%03d", 800 + (pv_id % 100));
|
||
pv_obj_set.push_back(std::string(buf, len));
|
||
break;
|
||
}
|
||
}
|
||
|
||
void x_pv_game_effect::load_data(int32_t pv_id, object_database* obj_db, texture_database* tex_db) {
|
||
if (state)
|
||
return;
|
||
|
||
data_struct* x_data = &data_list[DATA_X];
|
||
|
||
for (string_hash& i : pv_obj_set)
|
||
object_storage_load_set_hash(x_data, i.hash_murmurhash);
|
||
|
||
for (string_hash& i : pv_auth_3d)
|
||
auth_3d_data_load_category(x_data, i.c_str(), i.hash_murmurhash);
|
||
|
||
size_t effect_count = play_param->effect.size();
|
||
for (size_t i = 0; i < effect_count; i++) {
|
||
pvpp_effect& eff = play_param->effect[i];
|
||
if (!eff.glitter.size())
|
||
continue;
|
||
|
||
char buf[0x200];
|
||
size_t len = sprintf_s(buf, sizeof(buf), "eff_pv%03d_main", pv_id);
|
||
uint32_t hash = (uint32_t)Glitter::glt_particle_manager->LoadFile(Glitter::X,
|
||
x_data, buf, 0, -1.0f, true, obj_db, tex_db);
|
||
if (hash != hash_murmurhash_empty)
|
||
pv_glitter.push_back(std::string(buf, len));
|
||
break;
|
||
}
|
||
|
||
state = 10;
|
||
}
|
||
|
||
void x_pv_game_effect::reset() {
|
||
flags = 0;
|
||
state = 0;
|
||
play_param = 0;
|
||
change_fields = 0;
|
||
pv_obj_set.clear();
|
||
pv_obj_set.shrink_to_fit();
|
||
pv_auth_3d.clear();
|
||
pv_auth_3d.shrink_to_fit();
|
||
pv_glitter.clear();
|
||
pv_glitter.shrink_to_fit();
|
||
song_effect.clear();
|
||
song_effect.shrink_to_fit();
|
||
frame_rate_control = 0;
|
||
}
|
||
|
||
void x_pv_game_effect::set_chara_id(int32_t index, int32_t chara_id, bool chara_item) {
|
||
if (index < 0 || index >= song_effect.size())
|
||
return;
|
||
|
||
x_pv_game_song_effect& song_effect = this->song_effect[index];
|
||
|
||
for (x_pv_game_song_effect_auth_3d& i : song_effect.auth_3d) {
|
||
i.id.set_chara_id(chara_id);
|
||
i.id.set_chara_item(chara_item);
|
||
}
|
||
|
||
song_effect.chara_id = chara_id;
|
||
}
|
||
|
||
void x_pv_game_effect::set_song_effect(int32_t index, int64_t time) {
|
||
if (state && state != 20)
|
||
return;
|
||
|
||
if (index < 0 || index >= song_effect.size())
|
||
return;
|
||
|
||
x_pv_game_song_effect& song_effect = this->song_effect[index];
|
||
|
||
if (song_effect.enable) {
|
||
set_song_effect_time_inner(index, time, false);
|
||
return;
|
||
}
|
||
|
||
pvpp* play_param = this->play_param;
|
||
size_t chara_count = play_param->chara.size();
|
||
|
||
int32_t chara_id = play_param->effect[index].chara_id;
|
||
if (chara_id < 0 || chara_id >= ROB_CHARA_COUNT || chara_id >= chara_count)
|
||
chara_id = -1;
|
||
song_effect.chara_id = chara_id;
|
||
|
||
for (x_pv_game_song_effect_auth_3d& i : song_effect.auth_3d) {
|
||
i.id.set_enable(true);
|
||
i.id.set_repeat(false);
|
||
i.id.set_req_frame(0.0f);
|
||
i.id.set_visibility(true);
|
||
}
|
||
|
||
#if !BAKE_VIDEO_ALPHA
|
||
for (x_pv_game_song_effect_glitter& i : song_effect.glitter) {
|
||
i.scene_counter = Glitter::glt_particle_manager->LoadSceneEffect(i.name.hash_murmurhash, i.name.c_str());
|
||
if (!i.scene_counter)
|
||
continue;
|
||
|
||
Glitter::glt_particle_manager->SetSceneFrameRate(i.scene_counter, 0);
|
||
}
|
||
#endif
|
||
|
||
song_effect.enable = true;
|
||
song_effect.time = time;
|
||
|
||
set_song_effect_time_inner(index, time, false);
|
||
|
||
for (x_pv_game_song_effect_auth_3d& i : song_effect.auth_3d)
|
||
i.id.set_chara_id(chara_id);
|
||
}
|
||
|
||
void x_pv_game_effect::set_song_effect_time(int32_t index, int64_t time, bool glitter) {
|
||
if (index >= 0 && index < song_effect.size() && song_effect[index].enable)
|
||
set_song_effect_time_inner(index, time, glitter);
|
||
}
|
||
|
||
void x_pv_game_effect::set_song_effect_time_inner(int32_t index, int64_t time, bool glitter) {
|
||
if (index < 0 || index >= song_effect.size())
|
||
return;
|
||
|
||
x_pv_game_song_effect& song_effect = this->song_effect[index];
|
||
|
||
float_t req_frame = (float_t)((double_t)(time - song_effect.time) * 0.000000001) * 60.0f;
|
||
float_t max_frame = -1.0f;
|
||
|
||
if (change_fields) {
|
||
int64_t* key = change_fields->data();
|
||
size_t length = change_fields->size();
|
||
size_t temp;
|
||
while (length > 0)
|
||
if (key[temp = length / 2] > time)
|
||
length = temp;
|
||
else {
|
||
key += temp + 1;
|
||
length -= temp + 1;
|
||
}
|
||
|
||
if (key != change_fields->data() + change_fields->size())
|
||
max_frame = (float_t)((double_t)(*key - song_effect.time) * 0.000000001) * 60.0f - 1.0f;
|
||
}
|
||
|
||
for (x_pv_game_song_effect_auth_3d& i : song_effect.auth_3d) {
|
||
i.id.set_req_frame(req_frame);
|
||
i.id.set_paused(false);
|
||
i.id.set_max_frame(max_frame);
|
||
}
|
||
|
||
if (glitter)
|
||
for (x_pv_game_song_effect_glitter& i : song_effect.glitter) {
|
||
if (!i.scene_counter)
|
||
continue;
|
||
|
||
float_t frame = Glitter::glt_particle_manager->GetSceneFrameLifeTime(i.scene_counter, 0);
|
||
Glitter::glt_particle_manager->SetSceneEffectReqFrame(i.scene_counter, req_frame - frame);
|
||
}
|
||
}
|
||
|
||
void x_pv_game_effect::set_time(int64_t time, bool glitter) {
|
||
size_t size = song_effect.size();
|
||
for (size_t i = 0; i < size; i++)
|
||
if (song_effect[i].enable)
|
||
set_song_effect_time_inner((int32_t)i, time, glitter);
|
||
}
|
||
|
||
void x_pv_game_effect::stop() {
|
||
size_t song_effect_count = song_effect.size();
|
||
for (size_t i = 0; i < song_effect_count; i++)
|
||
stop_song_effect((int32_t)i, false);
|
||
|
||
for (string_hash& i : pv_glitter)
|
||
Glitter::glt_particle_manager->FreeScene(i.hash_murmurhash);
|
||
}
|
||
|
||
void x_pv_game_effect::stop_song_effect(int32_t index, bool free_glitter) {
|
||
if ((state && state != 20) || index < 0 || index >= song_effect.size() || !song_effect[index].enable)
|
||
return;
|
||
|
||
x_pv_game_song_effect& song_effect = this->song_effect[index];
|
||
|
||
for (x_pv_game_song_effect_auth_3d& i : song_effect.auth_3d) {
|
||
auth_3d_id& id = i.id;
|
||
id.set_enable(false);
|
||
id.set_req_frame(0.0f);
|
||
id.set_visibility(false);
|
||
}
|
||
|
||
for (x_pv_game_song_effect_glitter& i : song_effect.glitter)
|
||
if (i.scene_counter) {
|
||
Glitter::glt_particle_manager->FreeSceneEffect(i.scene_counter, !free_glitter);
|
||
i.scene_counter = 0;
|
||
}
|
||
|
||
song_effect.chara_id = -1;
|
||
song_effect.enable = false;
|
||
}
|
||
|
||
void x_pv_game_effect::unload() {
|
||
unload_data();
|
||
}
|
||
|
||
void x_pv_game_effect::unload_data() {
|
||
if (state && state != 20)
|
||
return;
|
||
|
||
size_t song_effect_count = song_effect.size();
|
||
for (size_t i = 0; i < song_effect_count; i++)
|
||
stop_song_effect((int32_t)i, false);
|
||
|
||
for (string_hash& i : pv_glitter)
|
||
Glitter::glt_particle_manager->FreeScene(i.hash_murmurhash);
|
||
|
||
for (x_pv_game_song_effect& i : song_effect)
|
||
for (x_pv_game_song_effect_auth_3d& j : i.auth_3d) {
|
||
j.id.unload(rctx_ptr);
|
||
j.id = {};
|
||
}
|
||
|
||
for (string_hash& i : pv_auth_3d)
|
||
auth_3d_data_unload_category(i.hash_murmurhash);
|
||
|
||
for (string_hash& i : pv_obj_set)
|
||
object_storage_unload_set(i.hash_murmurhash);
|
||
|
||
for (string_hash& i : pv_glitter)
|
||
Glitter::glt_particle_manager->UnloadEffectGroup(i.hash_murmurhash);
|
||
|
||
song_effect.clear();
|
||
song_effect.resize(song_effect_count);
|
||
state = 0;
|
||
}
|
||
|
||
x_pv_game_chara_effect_auth_3d::x_pv_game_chara_effect_auth_3d()
|
||
: field_0(), src_chara(), dst_chara(), objhrc_index(), node_mat() {
|
||
id = {};
|
||
time = -1;
|
||
reset();
|
||
}
|
||
|
||
x_pv_game_chara_effect_auth_3d::~x_pv_game_chara_effect_auth_3d() {
|
||
|
||
}
|
||
|
||
void x_pv_game_chara_effect_auth_3d::reset() {
|
||
field_0 = false;
|
||
src_chara = CHARA_MAX;
|
||
dst_chara = CHARA_MAX;
|
||
file.clear();
|
||
category.clear();
|
||
object_set.clear();
|
||
id = {};
|
||
time = -1;
|
||
node_name.clear();
|
||
objhrc_index = -1;
|
||
node_mat = 0;
|
||
}
|
||
|
||
x_pv_game_chara_effect::x_pv_game_chara_effect() : state(), change_fields(), frame_rate_control() {
|
||
reset();
|
||
}
|
||
|
||
x_pv_game_chara_effect::~x_pv_game_chara_effect() {
|
||
|
||
}
|
||
|
||
#if BAKE_PV826
|
||
void x_pv_game_chara_effect::ctrl(object_database* obj_db, texture_database* tex_db,
|
||
int32_t pv_id, std::map<uint32_t, auth_3d_id>* effchrpv_auth_3d_mot_ids) {
|
||
#else
|
||
void x_pv_game_chara_effect::ctrl(object_database* obj_db, texture_database* tex_db) {
|
||
#endif
|
||
switch (state) {
|
||
case 20: {
|
||
bool wait_load = false;
|
||
|
||
for (std::vector<x_pv_game_chara_effect_auth_3d>& i : auth_3d)
|
||
for (x_pv_game_chara_effect_auth_3d j : i) {
|
||
if (!j.category.str.size())
|
||
continue;
|
||
|
||
if (!auth_3d_data_check_category_loaded(j.category.hash_murmurhash))
|
||
wait_load |= true;
|
||
|
||
if (object_storage_get_objset_info(j.object_set.hash_murmurhash)
|
||
&& object_storage_load_obj_set_check_not_read(j.object_set.hash_murmurhash, obj_db, tex_db))
|
||
wait_load |= true;
|
||
}
|
||
|
||
if (wait_load)
|
||
break;
|
||
|
||
data_struct* x_data = &data_list[DATA_X];
|
||
|
||
for (std::vector<x_pv_game_chara_effect_auth_3d>& i : auth_3d)
|
||
for (x_pv_game_chara_effect_auth_3d& j : i) {
|
||
if (!j.category.str.size())
|
||
continue;
|
||
|
||
auth_3d_id id = auth_3d_id(j.file.hash_murmurhash, x_data, obj_db, tex_db);
|
||
if (!id.check_not_empty()) {
|
||
j.id = {};
|
||
continue;
|
||
}
|
||
|
||
id.read_file_modern();
|
||
id.set_enable(false);
|
||
id.set_repeat(false);
|
||
id.set_paused(true);
|
||
id.set_visibility(false);
|
||
id.set_frame_rate(frame_rate_control);
|
||
|
||
if (j.field_0)
|
||
id.set_src_dst_chara(j.src_chara, j.dst_chara);
|
||
|
||
j.id = id;
|
||
|
||
#if BAKE_PV826
|
||
if (pv_id == 826 && effchrpv_auth_3d_mot_ids)
|
||
effchrpv_auth_3d_mot_ids->insert({ j.file.hash_murmurhash, id });
|
||
#endif
|
||
}
|
||
|
||
state = 21;
|
||
} break;
|
||
case 21: {
|
||
bool wait_load = false;
|
||
|
||
for (std::vector<x_pv_game_chara_effect_auth_3d>& i : auth_3d)
|
||
for (x_pv_game_chara_effect_auth_3d j : i) {
|
||
if (!j.category.str.size())
|
||
continue;
|
||
|
||
if (j.id.check_not_empty() && !j.id.check_loaded())
|
||
wait_load |= true;
|
||
}
|
||
|
||
if (!wait_load)
|
||
state = 30;
|
||
} break;
|
||
}
|
||
}
|
||
|
||
vec3 x_pv_game_chara_effect::get_node_translation(int32_t chara_id,
|
||
int32_t chara_effect, int32_t objhrc_index, const char* node_name) {
|
||
if (chara_id < 0 || chara_id >= ROB_CHARA_COUNT)
|
||
return 0.0f;
|
||
|
||
rob_chara* rob_chr = rob_chara_array_get(chara_id);
|
||
if (!rob_chr)
|
||
return 0.0f;
|
||
|
||
std::vector<x_pv_game_chara_effect_auth_3d>& chr_eff_auth = this->auth_3d[rob_chr->chara_id];
|
||
if (chara_effect < 0 || chara_effect >= chr_eff_auth.size())
|
||
return 0.0f;
|
||
|
||
x_pv_game_chara_effect_auth_3d& chr_eff = chr_eff_auth[chara_effect];
|
||
if (chr_eff.id.is_null())
|
||
return 0.0f;
|
||
|
||
::auth_3d* auth = chr_eff.id.get_auth_3d();
|
||
if (!auth || objhrc_index < 0 || objhrc_index >= auth->object_hrc.size())
|
||
return 0.0f;
|
||
|
||
if (!chr_eff.node_mat || chr_eff.objhrc_index != objhrc_index
|
||
|| chr_eff.node_name.compare(node_name)) {
|
||
mat4* mat = 0;
|
||
uint32_t node_name_hash = hash_utf8_murmurhash(node_name);
|
||
for (auth_3d_object_node& i : auth->object_hrc[objhrc_index].node)
|
||
if (hash_string_murmurhash(i.name) == node_name_hash) {
|
||
mat = i.mat;
|
||
break;
|
||
}
|
||
|
||
if (!mat)
|
||
return 0.0f;
|
||
|
||
chr_eff.node_mat = mat;
|
||
chr_eff.node_name.assign(node_name);
|
||
chr_eff.objhrc_index = objhrc_index;
|
||
}
|
||
|
||
vec3 trans;
|
||
mat4_get_translation(chr_eff.node_mat, &trans);
|
||
return trans;
|
||
}
|
||
|
||
#if BAKE_PV826
|
||
void x_pv_game_chara_effect::load(int32_t pv_id, pvpp* play_param,
|
||
FrameRateControl* frame_rate_control, chara_index charas[6],
|
||
std::unordered_map<std::string, string_hash>* effchrpv_auth_3d_mot_names) {
|
||
#else
|
||
void x_pv_game_chara_effect::load(int32_t pv_id, pvpp* play_param,
|
||
FrameRateControl* frame_rate_control, chara_index charas[6]) {
|
||
#endif
|
||
if (state)
|
||
return;
|
||
|
||
this->play_param = play_param;
|
||
this->frame_rate_control = frame_rate_control;
|
||
|
||
size_t chara_count = play_param->chara.size();
|
||
for (int32_t i = 0; i < chara_count && i < ROB_CHARA_COUNT; i++) {
|
||
pvpp_chara& chara = play_param->chara[i];
|
||
if (!chara.chara_effect_init)
|
||
continue;
|
||
|
||
pvpp_chara_effect& chara_effect = chara.chara_effect;
|
||
|
||
chara_index src_chara = (chara_index)chara_effect.base_chara;
|
||
chara_index dst_chara = charas[i];
|
||
chara_index dst_chara_mei = dst_chara == CHARA_SAKINE ? CHARA_MEIKO : dst_chara;
|
||
|
||
/*if (dst_chara == CHARA_EXTRA)
|
||
dst_chara = src_chara;*/
|
||
|
||
const char* src_chara_str = chara_index_get_auth_3d_name(src_chara);
|
||
const char* dst_chara_str = chara_index_get_auth_3d_name(dst_chara);
|
||
const char* dst_chara_mei_str = chara_index_get_auth_3d_name(dst_chara_mei);
|
||
|
||
#if BAKE_X_PACK
|
||
if (pv_id == 814) {
|
||
repeat:
|
||
dst_chara_mei = dst_chara == CHARA_SAKINE ? CHARA_MEIKO : dst_chara;
|
||
dst_chara_str = chara_index_get_auth_3d_name(dst_chara);
|
||
dst_chara_mei_str = chara_index_get_auth_3d_name(dst_chara_mei);
|
||
}
|
||
#endif
|
||
for (pvpp_chara_effect_auth_3d& j : chara_effect.auth_3d) {
|
||
std::string file(j.auth_3d.str);
|
||
std::string object_set;
|
||
#if BAKE_PV826
|
||
if (pv_id != 826) {
|
||
#endif
|
||
if (j.has_object_set)
|
||
object_set.assign(j.object_set.str);
|
||
else
|
||
object_set.assign(file);
|
||
|
||
if (src_chara != dst_chara) {
|
||
if (src_chara_str) {
|
||
size_t pos = object_set.find(src_chara_str);
|
||
if (pos != -1)
|
||
object_set.replace(pos, 3, dst_chara_str);
|
||
else if (dst_chara_mei_str) {
|
||
size_t pos = object_set.find(dst_chara_mei_str);
|
||
if (pos != -1)
|
||
object_set.replace(pos, 3, src_chara_str);
|
||
}
|
||
}
|
||
|
||
if (!j.u00)
|
||
if (src_chara_str) {
|
||
size_t pos = file.find(src_chara_str);
|
||
if (pos != -1)
|
||
file.replace(pos, 3, dst_chara_str);
|
||
else if (dst_chara_mei_str) {
|
||
size_t pos = file.find(dst_chara_mei_str);
|
||
if (pos != -1)
|
||
file.replace(pos, 3, src_chara_str);
|
||
}
|
||
}
|
||
}
|
||
#if BAKE_PV826
|
||
}
|
||
else {
|
||
if (!j.auth_3d.str.find("EFFCHRPV826"))
|
||
continue;
|
||
|
||
file.assign("EFFCHRPV826MIK001");
|
||
object_set.assign("EFFCHRPV826MIK001");
|
||
}
|
||
#endif
|
||
|
||
std::string category;
|
||
if (!file.find("EFFCHRPV")) {
|
||
size_t pos = file.find("_");
|
||
if (pos != -1)
|
||
category.assign(file.substr(0, pos));
|
||
else
|
||
category.assign(file);
|
||
category.insert(0, "A3D_");
|
||
}
|
||
else
|
||
category.assign(file);
|
||
|
||
x_pv_game_chara_effect_auth_3d auth_3d;
|
||
auth_3d.field_0 = j.u00;
|
||
auth_3d.src_chara = src_chara;
|
||
auth_3d.dst_chara = dst_chara;
|
||
auth_3d.file = file;
|
||
auth_3d.category = category;
|
||
auth_3d.object_set = object_set;
|
||
this->auth_3d[i].push_back(auth_3d);
|
||
|
||
#if BAKE_PV826
|
||
if (pv_id == 826 && effchrpv_auth_3d_mot_names)
|
||
effchrpv_auth_3d_mot_names->insert({ file, category });
|
||
#endif
|
||
}
|
||
#if BAKE_X_PACK
|
||
if (pv_id == 814) {
|
||
dst_chara = (chara_index)((int32_t)(dst_chara + 1));
|
||
if (dst_chara != CHARA_MAX)
|
||
goto repeat;
|
||
}
|
||
#endif
|
||
}
|
||
state = 10;
|
||
}
|
||
|
||
void x_pv_game_chara_effect::load_data() {
|
||
if (state != 10)
|
||
return;
|
||
|
||
data_struct* x_data = &data_list[DATA_X];
|
||
|
||
for (std::vector<x_pv_game_chara_effect_auth_3d>& i : auth_3d)
|
||
for (x_pv_game_chara_effect_auth_3d& j : i) {
|
||
if (!j.category.str.size())
|
||
continue;
|
||
|
||
auth_3d_data_load_category(x_data, j.category.c_str(), j.category.hash_murmurhash);
|
||
object_storage_load_set_hash(x_data, j.object_set.hash_murmurhash);
|
||
}
|
||
|
||
state = 20;
|
||
}
|
||
|
||
void x_pv_game_chara_effect::reset() {
|
||
state = 0;
|
||
play_param = 0;
|
||
change_fields = 0;
|
||
frame_rate_control = 0;
|
||
|
||
for (std::vector<x_pv_game_chara_effect_auth_3d>& i : auth_3d) {
|
||
i.clear();
|
||
i.shrink_to_fit();
|
||
}
|
||
}
|
||
|
||
void x_pv_game_chara_effect::set_chara_effect(int32_t chara_id, int32_t index, int64_t time) {
|
||
if (chara_id < 0 || chara_id >= ROB_CHARA_COUNT)
|
||
return;
|
||
|
||
std::vector<x_pv_game_chara_effect_auth_3d>& auth_3d = this->auth_3d[chara_id];
|
||
if (index < 0 || index >= auth_3d.size())
|
||
return;
|
||
|
||
auth_3d_id& id = auth_3d[index].id;
|
||
|
||
if (!id.check_not_empty())
|
||
return;
|
||
|
||
if (id.get_enable())
|
||
id.set_req_frame((float_t)((double_t)(time - auth_3d[index].time) * 0.000000001) * 60.0f);
|
||
else {
|
||
id.set_enable(true);
|
||
id.set_paused(false);
|
||
id.set_repeat(false);
|
||
id.set_req_frame(0.0f);
|
||
id.set_visibility(true);
|
||
auth_3d[index].time = time;
|
||
}
|
||
|
||
float_t max_frame = -1.0f;
|
||
if (change_fields) {
|
||
int64_t* key = change_fields->data();
|
||
size_t length = change_fields->size();
|
||
size_t temp;
|
||
while (length > 0)
|
||
if (key[temp = length / 2] > time)
|
||
length = temp;
|
||
else {
|
||
key += temp + 1;
|
||
length -= temp + 1;
|
||
}
|
||
|
||
if (key != change_fields->data() + change_fields->size())
|
||
max_frame = (float_t)((double_t)(*key - auth_3d[index].time) * 0.000000001) * 60.0f - 1.0f;
|
||
}
|
||
|
||
id.set_max_frame(max_frame);
|
||
}
|
||
|
||
void x_pv_game_chara_effect::set_chara_effect_time(int32_t chara_id, int32_t index, int64_t time) {
|
||
if (!state || chara_id < 0 || chara_id >= ROB_CHARA_COUNT)
|
||
return;
|
||
|
||
for (x_pv_game_chara_effect_auth_3d& i : auth_3d[chara_id]) {
|
||
if (!i.id.check_not_empty() || !i.id.get_enable())
|
||
continue;
|
||
|
||
i.id.set_req_frame((float_t)((double_t)(time - i.time) * 0.000000001) * 60.0f);
|
||
i.id.set_paused(false);
|
||
}
|
||
}
|
||
|
||
void x_pv_game_chara_effect::set_time(int64_t time) {
|
||
if (!state)
|
||
return;
|
||
|
||
for (auto& i : auth_3d)
|
||
for (x_pv_game_chara_effect_auth_3d& j : i) {
|
||
if (!j.id.check_not_empty() || !j.id.get_enable())
|
||
continue;
|
||
|
||
j.id.set_req_frame((float_t)((double_t)(time - j.time) * 0.000000001) * 60.0f);
|
||
j.id.set_paused(false);
|
||
}
|
||
}
|
||
|
||
void x_pv_game_chara_effect::stop() {
|
||
if (!state)
|
||
return;
|
||
|
||
for (std::vector<x_pv_game_chara_effect_auth_3d>& i : auth_3d)
|
||
for (x_pv_game_chara_effect_auth_3d& j : i)
|
||
if (j.id.check_not_empty())
|
||
j.id.set_enable(false);
|
||
}
|
||
|
||
void x_pv_game_chara_effect::stop_chara_effect(int32_t chara_id, int32_t index) {
|
||
if (chara_id < 0 || chara_id >= ROB_CHARA_COUNT)
|
||
return;
|
||
|
||
for (x_pv_game_chara_effect_auth_3d& i : auth_3d[chara_id])
|
||
if (i.id.check_not_empty())
|
||
i.id.set_enable(false);
|
||
}
|
||
|
||
void x_pv_game_chara_effect::unload() {
|
||
if (!state)
|
||
return;
|
||
|
||
unload_data();
|
||
|
||
for (std::vector<x_pv_game_chara_effect_auth_3d>& i : auth_3d) {
|
||
i.clear();
|
||
i.shrink_to_fit();
|
||
}
|
||
|
||
frame_rate_control = 0;
|
||
play_param = 0;
|
||
state = 0;
|
||
}
|
||
|
||
void x_pv_game_chara_effect::unload_data() {
|
||
if (!state)
|
||
return;
|
||
|
||
if (state == 10 || state == 30) {
|
||
for (std::vector<x_pv_game_chara_effect_auth_3d>& i : auth_3d)
|
||
for (x_pv_game_chara_effect_auth_3d& j : i) {
|
||
if (!j.category.str.size())
|
||
continue;
|
||
|
||
j.id.unload(rctx_ptr);
|
||
auth_3d_data_unload_category(j.category.hash_murmurhash);
|
||
object_storage_unload_set(j.object_set.hash_murmurhash);
|
||
}
|
||
|
||
state = 10;
|
||
}
|
||
}
|
||
|
||
x_pv_game_music_args::x_pv_game_music_args() : type(), start(), field_2C() {
|
||
|
||
}
|
||
|
||
x_pv_game_music_args::~x_pv_game_music_args() {
|
||
|
||
}
|
||
|
||
x_pv_game_music_ogg::x_pv_game_music_ogg() {
|
||
playback = ogg_playback_data_get(0);
|
||
}
|
||
|
||
x_pv_game_music_ogg::~x_pv_game_music_ogg() {
|
||
if (playback) {
|
||
playback->Reset();
|
||
playback = 0;
|
||
}
|
||
}
|
||
|
||
#if !BAKE_FAST
|
||
x_pv_game_music::x_pv_game_music() : flags(), pause(), channel_pair_volume(), fade_in(),
|
||
fade_out(), no_fade(), no_fade_remain(), fade_out_time_req(), fade_out_action_req(),
|
||
type(), start(), end(), play_on_end(), fade_in_time(), field_9C(), loaded(), ogg() {
|
||
volume = 100;
|
||
master_volume = 100;
|
||
for (int32_t& i : channel_pair_volume)
|
||
i = 100;
|
||
fade_out_time = 3.0f;
|
||
}
|
||
|
||
x_pv_game_music::~x_pv_game_music() {
|
||
|
||
}
|
||
|
||
bool x_pv_game_music::check_args(int32_t type, std::string&& file_path, float_t start) {
|
||
return args.type == type && !args.file_path.compare(file_path) && args.start == start;
|
||
}
|
||
|
||
void x_pv_game_music::ctrl(float_t delta_time) {
|
||
if (no_fade && !pause) {
|
||
no_fade_remain -= delta_time;
|
||
if (no_fade_remain <= 0.0f) {
|
||
fade_out.enable = true;
|
||
fade_out.start = get_volume(0);
|
||
fade_out.value = 0;
|
||
fade_out.time = fade_out_time_req;
|
||
fade_out.remain = fade_out_time_req;
|
||
fade_out.action = fade_out_action_req;
|
||
|
||
no_fade = false;
|
||
no_fade_remain = 0.0f;
|
||
fade_out_time_req = 0.0f;
|
||
fade_out_action_req = X_PV_GAME_MUSIC_ACTION_NONE;
|
||
}
|
||
}
|
||
|
||
if (fade_in.enable && !pause) {
|
||
fade_in.remain -= delta_time;
|
||
if (fade_in.remain > 0.0f) {
|
||
int32_t value = fade_in.value;
|
||
if (fade_in.time > 0.0)
|
||
value = (int32_t)((float_t)value - (float_t)(value
|
||
- fade_in.start) * (fade_in.remain / fade_in.time));
|
||
set_volume_map(0, value);
|
||
}
|
||
else
|
||
fade_in_end();
|
||
}
|
||
|
||
if (fade_out.enable && !pause) {
|
||
fade_out.remain -= delta_time;
|
||
if (fade_out.remain > 0.0f) {
|
||
int32_t value = fade_out.value;
|
||
if (fade_out.time > 0.0f)
|
||
value = (int32_t)(value - ((float_t)(value
|
||
- fade_out.start) * (fade_out.remain / fade_out.time)));
|
||
set_volume_map(0, value);
|
||
}
|
||
else
|
||
fade_out_end();
|
||
}
|
||
|
||
if (flags & X_PV_GAME_MUSIC_OGG) {
|
||
OggPlayback* playback = ogg->playback;
|
||
if (playback->GetFileState() == OGG_FILE_HANDLER_FILE_STATE_STOPPED)
|
||
playback->Stop();
|
||
if (playback->GetFileState() == OGG_FILE_HANDLER_FILE_STATE_STOPPED)
|
||
play_or_stop();
|
||
OggPlayback::SetChannelPairVolumePan(playback);
|
||
}
|
||
}
|
||
|
||
void x_pv_game_music::exclude_flags(x_pv_game_music_flags flags) {
|
||
if ((this->flags & X_PV_GAME_MUSIC_OGG) && (flags & X_PV_GAME_MUSIC_OGG))
|
||
ogg_free();
|
||
enum_and(this->flags, ~flags);
|
||
}
|
||
|
||
void x_pv_game_music::fade_in_end() {
|
||
if (!fade_in.enable)
|
||
return;
|
||
|
||
fade_in.enable = false;
|
||
fade_in.remain = 0.0f;
|
||
set_volume_map(0, fade_in.value);
|
||
|
||
switch (fade_in.action) {
|
||
case X_PV_GAME_MUSIC_ACTION_STOP:
|
||
stop();
|
||
break;
|
||
case X_PV_GAME_MUSIC_ACTION_PAUSE:
|
||
set_pause(1);
|
||
break;
|
||
case X_PV_GAME_MUSIC_ACTION_PLAY:
|
||
play();
|
||
break;
|
||
}
|
||
}
|
||
|
||
void x_pv_game_music::fade_out_end() {
|
||
if (!fade_out.enable)
|
||
return;
|
||
|
||
fade_out.enable = false;
|
||
fade_out.remain = 0.0f;
|
||
set_volume_map(0, fade_out.value);
|
||
|
||
switch (fade_out.action) {
|
||
case X_PV_GAME_MUSIC_ACTION_STOP:
|
||
stop();
|
||
break;
|
||
case X_PV_GAME_MUSIC_ACTION_PAUSE:
|
||
set_pause(1);
|
||
break;
|
||
case X_PV_GAME_MUSIC_ACTION_PLAY:
|
||
play();
|
||
break;
|
||
}
|
||
}
|
||
|
||
void x_pv_game_music::file_load(int32_t type, std::string&& file_path, bool play_on_end,
|
||
float_t start, float_t end, float_t fade_in_time, float_t fade_out_time, bool a9) {
|
||
this->type = type;
|
||
this->file_path.assign(file_path);
|
||
this->start = start;
|
||
this->end = end;
|
||
this->play_on_end = play_on_end;
|
||
this->fade_out_time = fade_out_time;
|
||
this->fade_in_time = fade_in_time;
|
||
this->field_9C = a9;
|
||
|
||
if (fade_in_time > 0.0f) {
|
||
fade_in.start = 0;
|
||
fade_in.value = 100;
|
||
fade_in.time = fade_in_time;
|
||
fade_in.remain = fade_in_time;
|
||
fade_in.action = X_PV_GAME_MUSIC_ACTION_NONE;
|
||
fade_in.enable = true;
|
||
}
|
||
|
||
if (end <= 0.0f) {
|
||
fade_out.start = get_volume(0);
|
||
fade_out.value = 0;
|
||
fade_out.time = 0.0f;
|
||
fade_out.remain = 0.0;
|
||
fade_out.action = play_on_end
|
||
? X_PV_GAME_MUSIC_ACTION_PLAY : X_PV_GAME_MUSIC_ACTION_STOP;
|
||
}
|
||
else {
|
||
no_fade = true;
|
||
no_fade_remain = end + fade_in_time;
|
||
fade_out_time_req = fade_out_time;
|
||
fade_out_action_req = play_on_end
|
||
? X_PV_GAME_MUSIC_ACTION_PLAY : X_PV_GAME_MUSIC_ACTION_STOP;
|
||
}
|
||
}
|
||
|
||
int32_t x_pv_game_music::get_master_volume(int32_t index) {
|
||
if (!index)
|
||
return master_volume;
|
||
return 0;
|
||
}
|
||
|
||
int32_t x_pv_game_music::get_volume(int32_t index) {
|
||
if (!index)
|
||
return volume;
|
||
return 0;
|
||
}
|
||
|
||
int32_t x_pv_game_music::include_flags(x_pv_game_music_flags flags) {
|
||
if (!((this->flags & X_PV_GAME_MUSIC_OGG) || !(flags & X_PV_GAME_MUSIC_OGG)))
|
||
ogg_init();
|
||
enum_or(this->flags, flags);
|
||
return 0;
|
||
}
|
||
|
||
int32_t x_pv_game_music::load(int32_t type, std::string&& file_path, bool wait_load, float_t time, bool a6) {
|
||
if (type == 4 && set_ogg_args(std::string(file_path), time, wait_load) < 0)
|
||
return -6;
|
||
|
||
reset();
|
||
reset_args();
|
||
set_args(type, std::string(file_path), time, a6);
|
||
pause = true;
|
||
return 0;
|
||
}
|
||
|
||
void x_pv_game_music::ogg_free() {
|
||
if (ogg) {
|
||
delete ogg;
|
||
ogg = 0;
|
||
}
|
||
}
|
||
|
||
int32_t x_pv_game_music::ogg_init() {
|
||
if (ogg)
|
||
return 0;
|
||
|
||
ogg = new x_pv_game_music_ogg;
|
||
return ogg->playback ? 0 : -1;
|
||
}
|
||
|
||
int32_t x_pv_game_music::ogg_load(std::string&& file_path, float_t start) {
|
||
if (!(flags & X_PV_GAME_MUSIC_OGG))
|
||
return -2;
|
||
|
||
start = max_def(start, 0.0f);
|
||
|
||
OggPlayback* playback = ogg->playback;
|
||
|
||
OggFileHandlerFileState file_state = playback->GetFileState();
|
||
OggFileHandlerPauseState pause_state = playback->GetPauseState();
|
||
|
||
if (!check_args(4, std::string(file_path), start)
|
||
|| file_state != OGG_FILE_HANDLER_FILE_STATE_PLAYING
|
||
|| pause_state != OGG_FILE_HANDLER_PAUSE_STATE_PAUSE) {
|
||
playback->Stop();
|
||
playback->SetLoadTimeSeek(start);
|
||
playback->SetPath(file_path);
|
||
}
|
||
|
||
playback->SetPauseState(OGG_FILE_HANDLER_PAUSE_STATE_PLAY);
|
||
ogg->file_path.assign(file_path);
|
||
loaded = true;
|
||
return 0;
|
||
}
|
||
|
||
int32_t x_pv_game_music::ogg_reset() {
|
||
sound_stream_array_reset();
|
||
include_flags(X_PV_GAME_MUSIC_OGG);
|
||
return 0;
|
||
}
|
||
|
||
int32_t x_pv_game_music::ogg_stop() {
|
||
if (!(flags & X_PV_GAME_MUSIC_OGG))
|
||
return -2;
|
||
|
||
ogg->playback->Stop();
|
||
ogg->file_path.clear();
|
||
loaded = false;
|
||
return 0;
|
||
}
|
||
|
||
int32_t x_pv_game_music::play() {
|
||
return play(type, std::string(file_path), play_on_end, start, end, fade_in_time, fade_out_time, false);
|
||
}
|
||
|
||
int32_t x_pv_game_music::play(int32_t type, std::string&& file_path, bool play_on_end,
|
||
float_t start, float_t end, float_t fade_in_time, float_t fade_out_time, bool a9) {
|
||
set_volume_map(0, 100);
|
||
if (type == 4 && ogg_load(std::string(file_path), start) < 0)
|
||
return -7;
|
||
|
||
reset();
|
||
reset_args();
|
||
file_load(type, std::string(file_path), play_on_end, start, end, fade_in_time, fade_out_time, a9);
|
||
pause = false;
|
||
return 0;
|
||
}
|
||
|
||
void x_pv_game_music::play_fade_in(int32_t type, std::string&& file_path, float_t start,
|
||
float_t end, bool play_on_end, bool a7, float_t fade_out_time, bool a10) {
|
||
play(type, std::string(file_path), play_on_end, start, end, 0.0f, fade_out_time, a10);
|
||
}
|
||
|
||
int32_t x_pv_game_music::play_or_stop() {
|
||
if (play_on_end)
|
||
return play();
|
||
else
|
||
return stop();
|
||
}
|
||
|
||
void x_pv_game_music::reset() {
|
||
fade_in = {};
|
||
fade_out = {};
|
||
no_fade = false;
|
||
no_fade_remain = 0.0f;
|
||
fade_out_time_req = 0.0f;
|
||
fade_out_action_req = X_PV_GAME_MUSIC_ACTION_NONE;
|
||
type = 0;
|
||
file_path.clear();
|
||
start = 0.0f;
|
||
end = 0.0f;
|
||
play_on_end = false;
|
||
fade_in_time = 0.0f;
|
||
fade_out_time = 3.0f;
|
||
field_9C = false;
|
||
}
|
||
|
||
void x_pv_game_music::reset_args() {
|
||
args.type = 0;
|
||
args.file_path.clear();
|
||
args.start = 0.0f;
|
||
args.field_2C = false;
|
||
}
|
||
|
||
void x_pv_game_music::set_args(int32_t type, std::string&& file_path, float_t start, bool a5) {
|
||
args.type = type;
|
||
args.file_path.assign(file_path);
|
||
args.start = start;
|
||
args.field_2C = a5;
|
||
}
|
||
|
||
int32_t x_pv_game_music::set_channel_pair_volume(int32_t channel_pair, int32_t value) {
|
||
if (!(flags & X_PV_GAME_MUSIC_OGG))
|
||
return -2;
|
||
|
||
ogg->playback->SetChannelPairVolume(channel_pair, ratio_to_db((float_t)value * 0.01f));
|
||
return 0;
|
||
}
|
||
|
||
int32_t x_pv_game_music::set_channel_pair_volume_map(int32_t channel_pair, int32_t value) {
|
||
if (channel_pair >= 0 && channel_pair <= 3) {
|
||
set_channel_pair_volume(channel_pair, value);
|
||
if (!channel_pair)
|
||
set_channel_pair_volume_map(2, value);
|
||
else if (channel_pair == 1)
|
||
set_channel_pair_volume_map(3, value);
|
||
channel_pair_volume[channel_pair] = value;
|
||
return 0;
|
||
}
|
||
return -1;
|
||
}
|
||
|
||
int32_t x_pv_game_music::set_fade_out(float_t time, bool stop) {
|
||
reset();
|
||
if (time == 0.0f)
|
||
x_pv_game_music::stop();
|
||
else {
|
||
fade_out.start = get_volume(0);
|
||
fade_out.value = 0;
|
||
fade_out.time = time;
|
||
fade_out.remain = time;
|
||
fade_out.enable = true;
|
||
fade_out.action = stop ? X_PV_GAME_MUSIC_ACTION_STOP
|
||
: X_PV_GAME_MUSIC_ACTION_PAUSE;
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
int32_t x_pv_game_music::set_master_volume(int32_t value) {
|
||
if (!(flags & X_PV_GAME_MUSIC_OGG))
|
||
return -2;
|
||
|
||
ogg->playback->SetMasterVolume(ratio_to_db(
|
||
(float_t)(value * get_master_volume(0) / 100) * 0.01f));
|
||
return 0;
|
||
}
|
||
|
||
int32_t x_pv_game_music::set_ogg_args(std::string&& file_path, float_t start, bool wait_load) {
|
||
if (!(flags & X_PV_GAME_MUSIC_OGG))
|
||
return -2;
|
||
|
||
start = max_def(start, 0.0f);
|
||
|
||
OggPlayback* playback = ogg->playback;
|
||
|
||
OggFileHandlerFileState file_state = playback->GetFileState();
|
||
OggFileHandlerPauseState pause_state = playback->GetPauseState();
|
||
|
||
if (!check_args(4, std::string(file_path), start)
|
||
|| file_state != OGG_FILE_HANDLER_FILE_STATE_PLAYING
|
||
|| pause_state != OGG_FILE_HANDLER_PAUSE_STATE_PAUSE) {
|
||
playback->Stop();
|
||
playback->SetLoadTimeSeek(start);
|
||
playback->SetPath(file_path);
|
||
playback->SetPauseState(OGG_FILE_HANDLER_PAUSE_STATE_PAUSE);
|
||
ogg->file_path.assign(file_path);
|
||
|
||
if (wait_load) {
|
||
OggFileHandlerFileState file_state = playback->GetFileState();
|
||
while (file_state != OGG_FILE_HANDLER_FILE_STATE_PLAYING
|
||
&& file_state != OGG_FILE_HANDLER_FILE_STATE_STOPPED
|
||
&& file_state != OGG_FILE_HANDLER_FILE_STATE_MAX)
|
||
file_state = playback->GetFileState();
|
||
}
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
int32_t x_pv_game_music::set_ogg_pause_state(uint8_t pause_state) {
|
||
if (!(flags & X_PV_GAME_MUSIC_OGG))
|
||
return -2;
|
||
|
||
OggPlayback* playback = ogg->playback;
|
||
if (playback->GetFileState() == OGG_FILE_HANDLER_FILE_STATE_PLAYING)
|
||
playback->SetPauseState((OggFileHandlerPauseState)pause_state);
|
||
return 0;
|
||
}
|
||
|
||
int32_t x_pv_game_music::set_pause(int32_t pause) {
|
||
if (flags & X_PV_GAME_MUSIC_OGG)
|
||
set_ogg_pause_state(pause != 0);
|
||
this->pause = pause == 1;
|
||
return 0;
|
||
}
|
||
|
||
void x_pv_game_music::set_volume_map(int32_t index, int32_t value) {
|
||
if (!index) {
|
||
if (flags & X_PV_GAME_MUSIC_OGG)
|
||
set_master_volume(value);
|
||
volume = value;
|
||
}
|
||
}
|
||
|
||
int32_t x_pv_game_music::stop() {
|
||
if (flags & X_PV_GAME_MUSIC_OGG)
|
||
ogg_stop();
|
||
reset();
|
||
reset_args();
|
||
pause = false;
|
||
return 0;
|
||
}
|
||
|
||
void x_pv_game_music::stop_reset_flags() {
|
||
stop();
|
||
exclude_flags(X_PV_GAME_MUSIC_ALL);
|
||
}
|
||
#endif
|
||
|
||
aet_obj_data_comp::aet_obj_data_comp() : aet_id(), layer_name() {
|
||
frame = -1.0f;
|
||
}
|
||
|
||
aet_obj_data_comp::~aet_obj_data_comp() {
|
||
|
||
}
|
||
|
||
const aet_layout_data* aet_obj_data_comp::find_layout(const char* name) {
|
||
return comp.Find(name);
|
||
}
|
||
|
||
bool aet_obj_data_comp::init_comp(uint32_t aet_id, const std::string&& layer_name,
|
||
float_t frame, const aet_database* aet_db, const sprite_database* spr_db) {
|
||
if (aet_id == hash_murmurhash_empty || aet_id == -1)
|
||
return false;
|
||
|
||
if (comp.data.size() && this->aet_id == aet_id && !strncmp(this->layer_name,
|
||
layer_name.c_str(), layer_name.size()) && fabsf(this->frame - frame) <= 0.000001f)
|
||
return true;
|
||
|
||
comp.Clear();
|
||
this->aet_id = aet_id;
|
||
|
||
size_t len = min_def(sizeof(this->layer_name) - 1, layer_name.size());
|
||
strncpy_s(this->layer_name, sizeof(this->layer_name), layer_name.c_str(), len);
|
||
this->layer_name[len] = 0;
|
||
this->frame = frame;
|
||
|
||
aet_manager_init_aet_layout(&comp, aet_id, layer_name.c_str(),
|
||
(AetFlags)0, RESOLUTION_MODE_HD, 0, frame, aet_db, spr_db);
|
||
return true;
|
||
}
|
||
|
||
aet_obj_data::aet_obj_data() : comp(), loop(), hidden(), field_2A(), frame_rate_control() {
|
||
hash = hash_murmurhash_empty;
|
||
|
||
reset();
|
||
}
|
||
|
||
aet_obj_data::~aet_obj_data() {
|
||
reset();
|
||
}
|
||
|
||
bool aet_obj_data::check_disp() {
|
||
return aet_manager_get_obj_end(id);
|
||
}
|
||
|
||
const aet_layout_data* aet_obj_data::find_aet_layout(const char* name,
|
||
const aet_database* aet_db, const sprite_database* spr_db) {
|
||
if (!name)
|
||
return 0;
|
||
|
||
if (!comp)
|
||
comp = new aet_obj_data_comp;
|
||
|
||
if (comp && comp->init_comp(hash, layer_name.c_str(), aet_manager_get_obj_frame(id), aet_db, spr_db))
|
||
return comp->find_layout(name);
|
||
|
||
return 0;
|
||
}
|
||
|
||
uint32_t aet_obj_data::init(AetArgs& args, const aet_database* aet_db) {
|
||
reset();
|
||
|
||
hash = args.id.id;
|
||
layer_name.assign(args.layer_name);
|
||
id = aet_manager_init_aet_object(args, aet_db);
|
||
if (!id)
|
||
return 0;
|
||
|
||
aet_manager_set_obj_frame_rate_control(id, frame_rate_control);
|
||
#if BAKE_VIDEO_ALPHA
|
||
aet_manager_set_obj_visible(id, false);
|
||
#else
|
||
aet_manager_set_obj_visible(id, !hidden);
|
||
#endif
|
||
field_2A = true;
|
||
loop = !!(args.flags & AET_LOOP);
|
||
return id;
|
||
}
|
||
|
||
void aet_obj_data::reset() {
|
||
field_2A = false;
|
||
|
||
if (id) {
|
||
aet_manager_free_aet_object(id);
|
||
id = 0;
|
||
}
|
||
|
||
hash = hash_murmurhash_empty;
|
||
layer_name.clear();
|
||
layer_name.shrink_to_fit();
|
||
|
||
if (comp) {
|
||
delete comp;
|
||
comp = 0;
|
||
}
|
||
}
|
||
|
||
x_pv_aet_disp_data::x_pv_aet_disp_data() : disp(), opacity() {
|
||
|
||
}
|
||
|
||
x_pv_aet_disp_string::x_pv_aet_disp_string() {
|
||
|
||
}
|
||
|
||
x_pv_aet_disp_string::~x_pv_aet_disp_string() {
|
||
|
||
}
|
||
|
||
void x_pv_aet_disp_string::ctrl(const char* name, aet_obj_data* aet, const aet_database* aet_db, const sprite_database* spr_db) {
|
||
if (!aet) {
|
||
data.disp = false;
|
||
return;
|
||
}
|
||
|
||
const aet_layout_data* layout = aet->find_aet_layout(name, aet_db, spr_db);
|
||
if (!layout) {
|
||
data.disp = false;
|
||
return;
|
||
}
|
||
|
||
data.disp = true;
|
||
data.rect.pos = *(vec2*)&layout->position;
|
||
data.rect.size.x = layout->height * layout->mat.row1.y * layout->mat.row0.x;
|
||
data.rect.size.y = layout->height * layout->mat.row1.y;
|
||
data.opacity = clamp_def((uint8_t)(int32_t)(layout->opacity * 255.0f), 0x00, 0xFF);
|
||
}
|
||
|
||
static const char* sub_8133DDF8(int32_t id) {
|
||
auto elem = x_pv_game_str_array[x_pv_game_str_array_lang_sel].second.find(id);
|
||
if (elem != x_pv_game_str_array[x_pv_game_str_array_lang_sel].second.end())
|
||
return elem->second.c_str();
|
||
return 0;
|
||
}
|
||
|
||
const char* x_pv_str_array_pv::get_song_name(int32_t index) {
|
||
if (!index)
|
||
return song_name;
|
||
|
||
int32_t id = 20000010 + 1000 * pv_id + 4 * (index - 1);
|
||
|
||
const char* str = sub_8133DDF8(id);
|
||
if (str)
|
||
return str;
|
||
return "";
|
||
}
|
||
|
||
const char* x_pv_str_array_pv::get_song_line_1(int32_t index) {
|
||
int32_t id = 20000002 + 1000 * pv_id;
|
||
|
||
if (index)
|
||
id = 20000011 + 1000 * pv_id + 4 * (index - 1);
|
||
|
||
const char* str = sub_8133DDF8(id);
|
||
if (str)
|
||
return str;
|
||
return "";
|
||
}
|
||
|
||
const char* x_pv_str_array_pv::get_song_line_2(int32_t index) {
|
||
int32_t id = 20000003 + 1000 * pv_id;
|
||
|
||
if (index)
|
||
id = 20000012 + 1000 * pv_id + 4 * (index - 1);
|
||
|
||
const char* str = sub_8133DDF8(id);
|
||
if (str)
|
||
return str;
|
||
return "";
|
||
}
|
||
|
||
const char* x_pv_str_array_pv::get_song_line_3(int32_t index) {
|
||
int32_t id = 20000004 + 1000 * pv_id;
|
||
if (index)
|
||
id = 20000013 + 1000 * pv_id + 4 * (index - 1);
|
||
|
||
const char* str = sub_8133DDF8(id);
|
||
if (str)
|
||
return str;
|
||
return "";
|
||
}
|
||
|
||
x_pv_game_title::x_pv_game_title() : state(), str_array(), txt_layer_index() {
|
||
aet_set_id = hash_murmurhash_empty;
|
||
spr_set_id = hash_murmurhash_empty;
|
||
aet_id = hash_murmurhash_empty;
|
||
}
|
||
|
||
x_pv_game_title::~x_pv_game_title() {
|
||
unload();
|
||
}
|
||
|
||
void x_pv_game_title::ctrl() {
|
||
switch (state) {
|
||
case 2:
|
||
if (!aet_manager_load_file_modern(aet_set_id, &aet_db)
|
||
&& !sprite_manager_load_file_modern(spr_set_id, &spr_db)) {
|
||
spr_set* set = sprite_manager_get_set(spr_set_id, &spr_db);
|
||
if (set) {
|
||
SpriteData* sprdata = set->sprdata;
|
||
for (uint32_t i = set->num_of_sprite; i; i--, sprdata++)
|
||
sprdata->resolution_mode = RESOLUTION_MODE_HD;
|
||
}
|
||
state = 3;
|
||
}
|
||
break;
|
||
case 4:
|
||
if (tit_layer.check_disp() && txt_layer.check_disp())
|
||
state = 3;
|
||
else if (txt_layer.id)
|
||
ctrl_txt_data();
|
||
break;
|
||
}
|
||
}
|
||
|
||
void x_pv_game_title::ctrl_txt_data() {
|
||
const char* comps[4] = {
|
||
"p_txt01_c",
|
||
"p_txt02_c",
|
||
"p_txt03_c",
|
||
"p_txt04_c",
|
||
};
|
||
|
||
const char** str = comps;
|
||
for (x_pv_aet_disp_string& i : txt_data)
|
||
i.ctrl(*str++, &txt_layer, &aet_db, &spr_db);
|
||
}
|
||
|
||
void x_pv_game_title::disp() {
|
||
if (state != 4)
|
||
return;
|
||
|
||
font_info font(16);
|
||
|
||
PrintWork print_work;
|
||
print_work.SetFont(&font);
|
||
print_work.prio = spr::SPR_PRIO_06;
|
||
|
||
for (x_pv_aet_disp_string& i : txt_data) {
|
||
if (!i.data.disp || !i.str.size())
|
||
continue;
|
||
|
||
font.set_glyph_size(i.data.rect.size.x, i.data.rect.size.y);
|
||
print_work.color.a = i.data.opacity;
|
||
print_work.line_origin_loc = i.data.rect.pos;
|
||
print_work.text_current_loc = print_work.line_origin_loc;
|
||
|
||
print_work.printf((app::text_flags)(app::TEXT_FLAG_ALIGN_FLAG_LOCATE_V_CENTER
|
||
| app::TEXT_FLAG_ALIGN_FLAG_H_CENTER
|
||
| app::TEXT_FLAG_FONT), i.str.c_str());
|
||
}
|
||
}
|
||
|
||
bool x_pv_game_title::get_id(int8_t cloud_index, uint32_t& aet_id) {
|
||
switch (cloud_index) {
|
||
case 1:
|
||
default:
|
||
aet_id = hash_utf8_murmurhash("AET_PV_TIT01_MAIN");
|
||
break;
|
||
case 2:
|
||
aet_id = hash_utf8_murmurhash("AET_PV_TIT02_MAIN");
|
||
break;
|
||
case 3:
|
||
aet_id = hash_utf8_murmurhash("AET_PV_TIT03_MAIN");
|
||
break;
|
||
case 4:
|
||
aet_id = hash_utf8_murmurhash("AET_PV_TIT04_MAIN");
|
||
break;
|
||
case 5:
|
||
aet_id = hash_utf8_murmurhash("AET_PV_TIT05_MAIN");
|
||
break;
|
||
}
|
||
return true;
|
||
}
|
||
|
||
bool x_pv_game_title::get_set_ids(int8_t cloud_index, uint32_t& aet_set_id, uint32_t& spr_set_id) {
|
||
switch (cloud_index) {
|
||
case 1:
|
||
default:
|
||
aet_set_id = hash_utf8_murmurhash("AET_PV_TIT01");
|
||
spr_set_id = hash_utf8_murmurhash("SPR_PV_TIT01");
|
||
break;
|
||
case 2:
|
||
aet_set_id = hash_utf8_murmurhash("AET_PV_TIT02");
|
||
spr_set_id = hash_utf8_murmurhash("SPR_PV_TIT02");
|
||
break;
|
||
case 3:
|
||
aet_set_id = hash_utf8_murmurhash("AET_PV_TIT03");
|
||
spr_set_id = hash_utf8_murmurhash("SPR_PV_TIT03");
|
||
break;
|
||
case 4:
|
||
aet_set_id = hash_utf8_murmurhash("AET_PV_TIT04");
|
||
spr_set_id = hash_utf8_murmurhash("SPR_PV_TIT04");
|
||
break;
|
||
case 5:
|
||
aet_set_id = hash_utf8_murmurhash("AET_PV_TIT05");
|
||
spr_set_id = hash_utf8_murmurhash("SPR_PV_TIT05");
|
||
break;
|
||
}
|
||
return true;
|
||
}
|
||
|
||
void x_pv_game_title::load(int32_t pv_id, FrameRateControl* frame_rate_control) {
|
||
if (state)
|
||
return;
|
||
|
||
str_array.pv_id = pv_id;
|
||
str_array.song_name = sub_8133DDF8(20000000 + 1000 * pv_id);
|
||
|
||
int32_t cloud_index = 1;
|
||
switch (pv_id) {
|
||
case 809:
|
||
case 810:
|
||
case 823:
|
||
case 824:
|
||
case 826:
|
||
case 830:
|
||
cloud_index = 1; // Classic
|
||
break;
|
||
case 807:
|
||
case 808:
|
||
case 811:
|
||
case 812:
|
||
case 813:
|
||
case 825:
|
||
cloud_index = 2; // Cute
|
||
break;
|
||
case 801:
|
||
case 805:
|
||
case 814:
|
||
case 819:
|
||
case 820:
|
||
case 827:
|
||
cloud_index = 3; // Cool
|
||
break;
|
||
case 802:
|
||
case 815:
|
||
case 816:
|
||
case 821:
|
||
case 822:
|
||
case 828:
|
||
cloud_index = 4; // Elegant
|
||
break;
|
||
case 803:
|
||
case 804:
|
||
case 806:
|
||
case 817:
|
||
case 818:
|
||
case 829:
|
||
cloud_index = 5; // Chaos
|
||
break;
|
||
case 831:
|
||
case 832:
|
||
cloud_index = 6; // DLC
|
||
break;
|
||
}
|
||
|
||
get_set_ids(cloud_index, aet_set_id, spr_set_id);
|
||
get_id(cloud_index, aet_id);
|
||
|
||
tit_layer.frame_rate_control = frame_rate_control;
|
||
aet_manager_set_obj_frame_rate_control(tit_layer.id, frame_rate_control);
|
||
|
||
txt_layer.frame_rate_control = frame_rate_control;
|
||
aet_manager_set_obj_frame_rate_control(txt_layer.id, frame_rate_control);
|
||
|
||
state = 1;
|
||
}
|
||
|
||
void x_pv_game_title::load_data() {
|
||
if (!state || state != 1)
|
||
return;
|
||
|
||
sprite_manager_read_file_modern(spr_set_id, &data_list[DATA_X], &spr_db);
|
||
aet_manager_read_file_modern(aet_set_id, &data_list[DATA_X], &aet_db);
|
||
state = 2;
|
||
}
|
||
|
||
void x_pv_game_title::reset() {
|
||
tit_layer.reset();
|
||
txt_layer.reset();
|
||
txt_data[0].data.disp = false;
|
||
txt_data[1].data.disp = false;
|
||
txt_data[2].data.disp = false;
|
||
txt_data[3].data.disp = false;
|
||
if (state == 4)
|
||
state = 3;
|
||
}
|
||
|
||
void x_pv_game_title::show(int32_t index) {
|
||
if (!state)
|
||
return;
|
||
|
||
txt_data[0].str.assign(str_array.get_song_name(index));
|
||
txt_data[1].str.assign(str_array.get_song_line_1(index));
|
||
txt_data[2].str.assign(str_array.get_song_line_2(index));
|
||
txt_data[3].str.assign(str_array.get_song_line_3(index));
|
||
|
||
txt_layer_index = 0;
|
||
|
||
int32_t txt_layer_index = 3;
|
||
while (!txt_data[txt_layer_index].str.size())
|
||
if (--txt_layer_index < 2)
|
||
break;
|
||
|
||
txt_layer_index = max_def(txt_layer_index + 1, 2);
|
||
this->txt_layer_index = txt_layer_index;
|
||
|
||
if (state != 3 || aet_id == hash_murmurhash_empty)
|
||
return;
|
||
|
||
AetArgs args;
|
||
args.id.id = aet_id;
|
||
args.layer_name = "tit_01";
|
||
args.prio = spr::SPR_PRIO_05;
|
||
args.spr_db = &spr_db;
|
||
|
||
tit_layer.init(args, &aet_db);
|
||
|
||
switch (txt_layer_index) {
|
||
case 0:
|
||
case 1:
|
||
case 2:
|
||
default:
|
||
args.layer_name = "txt01";
|
||
break;
|
||
case 3:
|
||
args.layer_name = "txt02";
|
||
break;
|
||
case 4:
|
||
args.layer_name = "txt03";
|
||
break;
|
||
}
|
||
|
||
txt_layer.init(args, &aet_db);
|
||
|
||
ctrl_txt_data();
|
||
|
||
state = 4;
|
||
}
|
||
|
||
void x_pv_game_title::unload() {
|
||
if (state >= 3)
|
||
unload_data();
|
||
|
||
aet_set_id = hash_murmurhash_empty;
|
||
spr_set_id = hash_murmurhash_empty;
|
||
aet_id = hash_murmurhash_empty;
|
||
state = 0;
|
||
}
|
||
|
||
void x_pv_game_title::unload_data() {
|
||
if (state && state != 2 && state != 1) {
|
||
reset();
|
||
sprite_manager_unload_set_modern(spr_set_id, &spr_db);
|
||
aet_manager_unload_set_modern(aet_set_id, &aet_db);
|
||
state = 1;
|
||
}
|
||
}
|
||
|
||
x_pv_game_pv_data::x_pv_game_pv_data() : pv_game(), dsc_data_ptr(), dsc_data_ptr_end(),
|
||
play(), chara_id(), dsc_time(), pv_end(), playdata(), scene_rot_y(), branch_mode() {
|
||
target_anim_fps = 60.0f;
|
||
anim_frame_speed = 1.0f;
|
||
scene_rot_mat = mat4_identity;
|
||
|
||
for (x_pv_play_data& i : playdata)
|
||
i.reset();
|
||
}
|
||
|
||
x_pv_game_pv_data::~x_pv_game_pv_data() {
|
||
|
||
}
|
||
|
||
void x_pv_game_pv_data::ctrl(bool a2, float_t curr_time, float_t delta_time) {
|
||
#pragma warning(suppress: 26451)
|
||
int64_t _curr_time = 1000 * (int64_t)(curr_time * 1000000.0f);
|
||
|
||
dsc_data* prev_dsc_data_ptr = dsc_data_ptr;
|
||
|
||
float_t dsc_time_offset = 0.0f;
|
||
while (dsc_data_ptr != dsc_data_ptr_end) {
|
||
bool music_play = false;
|
||
bool next = dsc_ctrl(delta_time, _curr_time, &dsc_time_offset);
|
||
|
||
if (prev_dsc_data_ptr != dsc_data_ptr)
|
||
print_dsc_command(dsc, prev_dsc_data_ptr, dsc_time);
|
||
|
||
prev_dsc_data_ptr = dsc_data_ptr;
|
||
|
||
if (!next)
|
||
break;
|
||
}
|
||
}
|
||
|
||
bool x_pv_game_pv_data::dsc_ctrl(float_t delta_time, int64_t curr_time,
|
||
float_t* dsc_time_offset) {
|
||
dsc_x_func func = (dsc_x_func)dsc_data_ptr->func;
|
||
int32_t* data = dsc.get_func_data(dsc_data_ptr);
|
||
|
||
if (branch_mode) {
|
||
bool v19;
|
||
if (pv_game->success)
|
||
v19 = branch_mode == 2;
|
||
else
|
||
v19 = branch_mode == 1;
|
||
if (!v19) {
|
||
if (func < 0 || func >= DSC_X_MAX) {
|
||
play = false;
|
||
return false;
|
||
}
|
||
else if (func != DSC_X_TIME
|
||
&& func != DSC_X_PV_END && func != DSC_X_PV_BRANCH_MODE) {
|
||
dsc_data_ptr++;
|
||
return true;
|
||
}
|
||
}
|
||
}
|
||
|
||
data_struct* aft_data = &data_list[DATA_AFT];
|
||
bone_database* aft_bone_data = &aft_data->data_ft.bone_data;
|
||
motion_database* aft_mot_db = &aft_data->data_ft.mot_db;
|
||
|
||
x_pv_play_data* playdata = &this->playdata[chara_id];
|
||
rob_chara* rob_chr = playdata->rob_chr;
|
||
|
||
switch (func) {
|
||
case DSC_X_END: {
|
||
play = false;
|
||
pv_game->state_old = 21;
|
||
return false;
|
||
} break;
|
||
case DSC_X_TIME: {
|
||
dsc_time = (int64_t)data[0] * 10000;
|
||
if (dsc_time > curr_time)
|
||
return false;
|
||
#if BAKE_X_PACK
|
||
pv_end = true;
|
||
#endif
|
||
} break;
|
||
case DSC_X_MIKU_MOVE: {
|
||
chara_id = data[0];
|
||
playdata = &this->playdata[chara_id];
|
||
rob_chr = playdata->rob_chr;
|
||
|
||
vec3 pos;
|
||
pos.x = (float_t)data[1] * 0.001f;
|
||
pos.y = (float_t)data[2] * 0.001f;
|
||
pos.z = (float_t)data[3] * 0.001f;
|
||
|
||
if (!rob_chr)
|
||
break;
|
||
|
||
mat4_transform_point(&scene_rot_mat, &pos, &pos);
|
||
rob_chr->set_data_miku_rot_position(pos);
|
||
rob_chr->set_osage_reset();
|
||
} break;
|
||
case DSC_X_MIKU_ROT: {
|
||
chara_id = data[0];
|
||
playdata = &this->playdata[chara_id];
|
||
rob_chr = playdata->rob_chr;
|
||
|
||
float_t rot_y = (float_t)data[0] * 0.001f;
|
||
|
||
if (!rob_chr)
|
||
break;
|
||
|
||
int16_t rot_y_int16 = (int32_t)((rot_y + scene_rot_y) * 32768.0f * (float_t)(1.0 / 180.0));
|
||
rob_chr->data.miku_rot.rot_y_int16 = rot_y_int16;
|
||
rob_chr->set_osage_reset();
|
||
} break;
|
||
case DSC_X_MIKU_DISP: {
|
||
chara_id = data[0];
|
||
playdata = &this->playdata[chara_id];
|
||
rob_chr = playdata->rob_chr;
|
||
|
||
int32_t disp = data[1];
|
||
|
||
playdata->disp = disp == 1;
|
||
|
||
if (!rob_chr)
|
||
break;
|
||
|
||
if (disp == 1) {
|
||
rob_chr->set_visibility(true);
|
||
if (rob_chr->check_for_ageageagain_module()) {
|
||
rob_chara_age_age_array_set_skip(rob_chr->chara_id, 1);
|
||
rob_chara_age_age_array_set_skip(rob_chr->chara_id, 2);
|
||
}
|
||
|
||
for (x_pv_play_data_set_motion& i : playdata->set_motion) {
|
||
bool set = rob_chr->set_motion_id(i.motion_id, i.frame, i.blend_duration,
|
||
i.blend, false, i.blend_type, aft_bone_data, aft_mot_db);
|
||
rob_chr->set_motion_reset_data(i.motion_id, i.dsc_frame);
|
||
rob_chr->bone_data->disable_eye_motion = i.disable_eye_motion;
|
||
rob_chr->data.motion.step_data.step = i.frame_speed;
|
||
if (set)
|
||
pv_expression_array_set_motion(pv_game->get_data()
|
||
.exp_file.hash_murmurhash, chara_id, i.motion_id);
|
||
set_motion_max_frame(chara_id, i.motion_index, i.dsc_time);
|
||
}
|
||
playdata->set_motion.clear();
|
||
}
|
||
else
|
||
rob_chr->set_visibility(false);
|
||
} break;
|
||
case DSC_X_MIKU_SHADOW: {
|
||
chara_id = data[0];
|
||
playdata = &this->playdata[chara_id];
|
||
rob_chr = playdata->rob_chr;
|
||
} break;
|
||
case DSC_X_TARGET: {
|
||
|
||
} break;
|
||
case DSC_X_SET_MOTION: {
|
||
chara_id = data[0];
|
||
playdata = &this->playdata[chara_id];
|
||
rob_chr = playdata->rob_chr;
|
||
|
||
if (!rob_chr)
|
||
break;
|
||
|
||
int32_t motion_index = data[1];
|
||
int32_t blend_duration_int = data[2];
|
||
int32_t frame_speed_int = data[3];
|
||
|
||
float_t blend_duration;
|
||
if (blend_duration_int != -1) {
|
||
blend_duration = (float_t)blend_duration_int * 0.001f * 60.0f;
|
||
if (blend_duration < 0.0f)
|
||
blend_duration = 0.0f;
|
||
}
|
||
else
|
||
blend_duration = 0.0f;
|
||
|
||
float_t frame_speed;
|
||
if (frame_speed_int != -1) {
|
||
frame_speed = (float_t)frame_speed_int * 0.001f;
|
||
if (frame_speed < 0.0f)
|
||
frame_speed = 0.0f;
|
||
}
|
||
else
|
||
frame_speed = 1.0f;
|
||
|
||
float_t frame = 0.0f;
|
||
float_t dsc_frame = 0.0f;
|
||
|
||
bool blend = false;
|
||
x_pv_play_data_motion* motion = playdata->get_motion(motion_index);
|
||
|
||
if (motion && motion->enable && (motion_index == motion->motion_index || !motion->motion_index)) {
|
||
if (dsc_time != motion->time) {
|
||
frame = dsc_time_to_frame(curr_time - motion->time);
|
||
dsc_frame = prj::roundf(dsc_time_to_frame(dsc_time - motion->time));
|
||
if (frame < dsc_frame)
|
||
frame = dsc_frame;
|
||
blend = curr_time > motion->time;
|
||
}
|
||
else
|
||
frame = 0.0f;
|
||
}
|
||
|
||
uint32_t motion_id = -1;
|
||
int32_t chara_id = 0;
|
||
for (pvpp_chara& i : pv_game->get_data().play_param->chara) {
|
||
if (chara_id++ != this->chara_id)
|
||
continue;
|
||
|
||
int32_t mot_idx = 1;
|
||
for (string_hash& j : i.motion) {
|
||
if (mot_idx++ != motion_index)
|
||
continue;
|
||
|
||
std::string name(j.str);
|
||
size_t pos = name.find("PV832");
|
||
if (pos != -1)
|
||
name.replace(pos, 5, "PV800", 5);
|
||
motion_id = aft_mot_db->get_motion_id(name.c_str());
|
||
break;
|
||
}
|
||
break;
|
||
}
|
||
|
||
if (motion_index) {
|
||
if (motion_id == -1)
|
||
motion_id = rob_chr->get_rob_cmn_mottbl_motion_id(0);
|
||
}
|
||
else if (motion_id == -1) {
|
||
motion_id = rob_chr->get_rob_cmn_mottbl_motion_id(5);
|
||
if (motion_id == -1)
|
||
motion_id = rob_chr->get_rob_cmn_mottbl_motion_id(0);
|
||
}
|
||
|
||
if (blend)
|
||
blend_duration = 0.0f;
|
||
else
|
||
blend_duration /= anim_frame_speed;
|
||
|
||
x_pv_play_data_set_motion set_motion;
|
||
set_motion.frame_speed = frame_speed * anim_frame_speed;
|
||
set_motion.motion_id = motion_id;
|
||
set_motion.frame = frame;
|
||
set_motion.blend_duration = blend_duration;
|
||
set_motion.blend = blend;
|
||
set_motion.blend_type = MOTION_BLEND_CROSS;
|
||
set_motion.disable_eye_motion = true;
|
||
set_motion.motion_index = motion_index;
|
||
set_motion.dsc_time = motion ? motion->time : dsc_time;
|
||
set_motion.dsc_frame = dsc_frame;
|
||
|
||
if (playdata->disp) {
|
||
bool set = rob_chr->set_motion_id(motion_id, frame, blend_duration,
|
||
blend, false, MOTION_BLEND_CROSS, aft_bone_data, aft_mot_db);
|
||
rob_chr->set_motion_reset_data(motion_id, dsc_frame);
|
||
rob_chr->set_motion_skin_param(motion_id, dsc_frame);
|
||
rob_chr->bone_data->disable_eye_motion = true;
|
||
rob_chr->data.motion.step_data.step = set_motion.frame_speed;
|
||
if (set)
|
||
pv_expression_array_set_motion(pv_game->get_data()
|
||
.exp_file.hash_murmurhash, this->chara_id, motion_id);
|
||
set_motion_max_frame(this->chara_id, motion_index, motion ? motion->time : 0);
|
||
}
|
||
else {
|
||
playdata->set_motion.clear();
|
||
playdata->set_motion.push_back(set_motion);
|
||
rob_chr->data.motion.step_data.step = set_motion.frame_speed;
|
||
}
|
||
} break;
|
||
case DSC_X_SET_PLAYDATA: {
|
||
chara_id = data[0];
|
||
playdata = &this->playdata[chara_id];
|
||
rob_chr = playdata->rob_chr;
|
||
|
||
int32_t motion_index = data[1];
|
||
if (motion_index >= 0) {
|
||
x_pv_play_data_motion* motion = playdata->get_motion(motion_index);
|
||
if (motion) {
|
||
motion->enable = true;
|
||
motion->motion_index = motion_index;
|
||
motion->time = dsc_time;
|
||
}
|
||
else
|
||
playdata->motion.push_back({ true, motion_index, dsc_time });
|
||
}
|
||
else
|
||
playdata->motion.clear();
|
||
} break;
|
||
case DSC_X_EFFECT: {
|
||
|
||
} break;
|
||
case DSC_X_FADEIN_FIELD: {
|
||
|
||
} break;
|
||
case DSC_X_EFFECT_OFF: {
|
||
|
||
} break;
|
||
case DSC_X_SET_CAMERA: {
|
||
|
||
} break;
|
||
case DSC_X_DATA_CAMERA: {
|
||
|
||
} break;
|
||
case DSC_X_CHANGE_FIELD: {
|
||
int32_t field = data[0];
|
||
if (field > 0)
|
||
x_pv_game_change_field(pv_game, field, dsc_time, curr_time);
|
||
else
|
||
x_pv_game_reset_field(pv_game);
|
||
|
||
pv_game->get_data().effect.set_time(dsc_time, false);
|
||
pv_game->get_data().chara_effect.set_time(dsc_time);
|
||
} break;
|
||
case DSC_X_HIDE_FIELD: {
|
||
|
||
} break;
|
||
case DSC_X_MOVE_FIELD: {
|
||
|
||
} break;
|
||
case DSC_X_FADEOUT_FIELD: {
|
||
|
||
} break;
|
||
case DSC_X_EYE_ANIM: {
|
||
chara_id = data[0];
|
||
playdata = &this->playdata[chara_id];
|
||
rob_chr = playdata->rob_chr;
|
||
|
||
int32_t v115 = data[1];
|
||
int32_t blend_duration_int = data[2];
|
||
|
||
float_t blend_duration;
|
||
if (blend_duration_int != -1)
|
||
blend_duration = (float_t)blend_duration_int * 0.001f * 60.0f;
|
||
else
|
||
blend_duration = 6.0f;
|
||
|
||
if (!rob_chr)
|
||
break;
|
||
|
||
blend_duration /= anim_frame_speed;
|
||
|
||
rob_chr->set_eyelid_mottbl_motion_from_face(v115, blend_duration, -1.0f, 0.0f, aft_mot_db);
|
||
} break;
|
||
case DSC_X_MOUTH_ANIM: {
|
||
chara_id = data[0];
|
||
playdata = &this->playdata[chara_id];
|
||
rob_chr = playdata->rob_chr;
|
||
|
||
int32_t mouth_anim_id = data[2];
|
||
int32_t blend_duration_int = data[3];
|
||
int32_t value_int = data[4];
|
||
|
||
float_t blend_duration;
|
||
if (blend_duration_int != -1) {
|
||
blend_duration = (float_t)blend_duration_int * 0.001f * 60.0f;
|
||
if (blend_duration < 0.0f)
|
||
blend_duration = 0.0f;
|
||
}
|
||
else
|
||
blend_duration = 6.0f;
|
||
|
||
float_t value;
|
||
if (value_int != -1) {
|
||
value = (float_t)value_int * 0.001f;
|
||
if (value < 0.0f || value > 1.0f)
|
||
value = 1.0f;
|
||
}
|
||
else
|
||
value = 1.0f;
|
||
|
||
if (!rob_chr)
|
||
break;
|
||
|
||
switch (mouth_anim_id) {
|
||
case 4: mouth_anim_id = 34; break;
|
||
case 5: mouth_anim_id = 35; break;
|
||
case 6: mouth_anim_id = 36; break;
|
||
case 7: mouth_anim_id = 37; break;
|
||
case 8: mouth_anim_id = 38; break;
|
||
case 9: mouth_anim_id = 39; break;
|
||
case 10: mouth_anim_id = 4; break;
|
||
case 11: mouth_anim_id = 5; break;
|
||
case 12: mouth_anim_id = 6; break;
|
||
case 13: mouth_anim_id = 7; break;
|
||
case 14: mouth_anim_id = 8; break;
|
||
case 15: mouth_anim_id = 9; break;
|
||
case 16: mouth_anim_id = 10; break;
|
||
case 17: mouth_anim_id = 11; break;
|
||
case 18: mouth_anim_id = 12; break;
|
||
case 19: mouth_anim_id = 13; break;
|
||
case 20: mouth_anim_id = 14; break;
|
||
case 21: mouth_anim_id = 15; break;
|
||
case 22: mouth_anim_id = 16; break;
|
||
case 23: mouth_anim_id = 17; break;
|
||
case 24: mouth_anim_id = 18; break;
|
||
case 25: mouth_anim_id = 19; break;
|
||
case 26: mouth_anim_id = 20; break;
|
||
case 27: mouth_anim_id = 21; break;
|
||
case 28: mouth_anim_id = 22; break;
|
||
case 29: mouth_anim_id = 40; break;
|
||
case 30: mouth_anim_id = 41; break;
|
||
case 31: mouth_anim_id = 42; break;
|
||
}
|
||
|
||
int32_t mottbl_index = mouth_anim_id_to_mottbl_index(mouth_anim_id);
|
||
blend_duration /= anim_frame_speed;
|
||
|
||
rob_chr->set_mouth_mottbl_motion(0, mottbl_index, value,
|
||
0, blend_duration, 0.0f, 1.0f, -1, 0.0f, aft_mot_db);
|
||
} break;
|
||
case DSC_X_HAND_ANIM: {
|
||
chara_id = data[0];
|
||
playdata = &this->playdata[chara_id];
|
||
rob_chr = playdata->rob_chr;
|
||
|
||
int32_t hand_index = data[1];
|
||
int32_t hand_anim_id = data[2];
|
||
int32_t blend_duration_int = data[3];
|
||
int32_t value_int = data[4];
|
||
|
||
float_t blend_duration;
|
||
if (blend_duration_int != -1) {
|
||
blend_duration = (float_t)blend_duration_int * 0.001f * 60.0f;
|
||
if (blend_duration < 0.0f)
|
||
blend_duration = 0.0f;
|
||
}
|
||
else
|
||
blend_duration = 0.0f;
|
||
|
||
float_t value;
|
||
if (value_int != -1) {
|
||
value = (float_t)value_int * 0.001f;
|
||
if (value < 0.0f || value > 1.0f)
|
||
value = 1.0f;
|
||
}
|
||
else
|
||
value = 1.0f;
|
||
|
||
if (!rob_chr)
|
||
break;
|
||
|
||
int32_t mottbl_index = hand_anim_id_to_mottbl_index(hand_anim_id);
|
||
blend_duration /= anim_frame_speed;
|
||
|
||
switch (hand_index) {
|
||
case 0:
|
||
rob_chr->set_hand_l_mottbl_motion(0, mottbl_index, value,
|
||
0, blend_duration, 0.0f, 1.0f, -1, 0.0f, aft_mot_db);
|
||
break;
|
||
case 1:
|
||
rob_chr->set_hand_r_mottbl_motion(0, mottbl_index, value,
|
||
0, blend_duration, 0.0f, 1.0f, -1, 0.0f, aft_mot_db);
|
||
break;
|
||
}
|
||
} break;
|
||
case DSC_X_LOOK_ANIM: {
|
||
chara_id = data[0];
|
||
playdata = &this->playdata[chara_id];
|
||
rob_chr = playdata->rob_chr;
|
||
|
||
int32_t look_anim_id = data[1];
|
||
int32_t blend_duration_int = data[2];
|
||
int32_t value_int = data[3];
|
||
|
||
float_t blend_duration;
|
||
if (blend_duration_int != -1) {
|
||
blend_duration = (float_t)blend_duration_int * 0.001f * 60.0f;
|
||
if (blend_duration < 0.0f)
|
||
blend_duration = 0.0f;
|
||
}
|
||
else
|
||
blend_duration = 6.0f;
|
||
|
||
float_t value;
|
||
if (value_int != -1) {
|
||
value = (float_t)value_int * 0.001f;
|
||
if (value < 0.0f || value > 1.0f)
|
||
value = 1.0f;
|
||
}
|
||
else
|
||
value = 1.0f;
|
||
|
||
if (!rob_chr)
|
||
break;
|
||
|
||
int32_t mottbl_index = look_anim_id_to_mottbl_index(look_anim_id);
|
||
blend_duration /= anim_frame_speed;
|
||
|
||
rob_chr->set_eyes_mottbl_motion(0, mottbl_index, value,
|
||
mottbl_index == 224 ? 1 : 0, blend_duration, 0.0f, 1.0f, -1, 0.0f, aft_mot_db);
|
||
} break;
|
||
case DSC_X_EXPRESSION: {
|
||
chara_id = data[0];
|
||
playdata = &this->playdata[chara_id];
|
||
rob_chr = playdata->rob_chr;
|
||
|
||
int32_t expression_id = data[1];
|
||
int32_t blend_duration_int = data[2];
|
||
int32_t value_int = data[3];
|
||
|
||
float_t blend_duration;
|
||
if (blend_duration_int != -1) {
|
||
blend_duration = (float_t)blend_duration_int * 0.001f * 60.0f;
|
||
if (blend_duration < 0.0f)
|
||
blend_duration = 0.0f;
|
||
}
|
||
else
|
||
blend_duration = 0.0f;
|
||
|
||
float_t value;
|
||
if (value_int != -1) {
|
||
value = (float_t)value_int * 0.001f;
|
||
if (value < 0.0f || value > 1.0f)
|
||
value = 1.0f;
|
||
}
|
||
else
|
||
value = 1.0f;
|
||
|
||
if (!rob_chr)
|
||
break;
|
||
|
||
int32_t mottbl_index = expression_id_to_mottbl_index(expression_id);
|
||
blend_duration /= anim_frame_speed;
|
||
|
||
rob_chr->set_face_mottbl_motion(0, mottbl_index, value, mottbl_index >= 214
|
||
&& mottbl_index <= 223 ? 1 : 0, blend_duration, 0.0f, 1.0f, -1, 0.0f, true, aft_mot_db);
|
||
|
||
} break;
|
||
case DSC_X_LOOK_CAMERA: {
|
||
|
||
} break;
|
||
case DSC_X_LYRIC: {
|
||
|
||
} break;
|
||
case DSC_X_MUSIC_PLAY: {
|
||
#if !BAKE_FAST
|
||
char buf[0x200];
|
||
sprintf_s(buf, sizeof(buf), "rom/sound/song/pv_%03d.ogg",
|
||
pv_game->get_data().pv_id == 832 ? 800 : pv_game->get_data().pv_id);
|
||
x_pv_game_music_ptr->play(4, buf, false, 0.0f, 0.0f, 0.0f, 3.0f, false);
|
||
x_pv_game_music_ptr->set_channel_pair_volume_map(1, 100);
|
||
x_pv_game_music_ptr->set_channel_pair_volume_map(0, 100);
|
||
#endif
|
||
} break;
|
||
case DSC_X_MODE_SELECT: {
|
||
|
||
} break;
|
||
case DSC_X_EDIT_MOTION: {
|
||
|
||
} break;
|
||
case DSC_X_BAR_TIME_SET: {
|
||
|
||
} break;
|
||
case DSC_X_SHADOWHEIGHT: {
|
||
chara_id = data[0];
|
||
playdata = &this->playdata[chara_id];
|
||
rob_chr = playdata->rob_chr;
|
||
} break;
|
||
case DSC_X_EDIT_FACE: {
|
||
int32_t expression_id = data[0];
|
||
|
||
if (!rob_chr)
|
||
break;
|
||
|
||
int32_t mottbl_index = expression_id_to_mottbl_index(expression_id);
|
||
|
||
rob_chr->set_face_mottbl_motion(0, mottbl_index, 1.0f, mottbl_index >= 214
|
||
&& mottbl_index <= 223 ? 1 : 0, 0.0f, 0.0f, 1.0f, -1, 0.0f, true, aft_mot_db);
|
||
} break;
|
||
case DSC_X_DUMMY: {
|
||
|
||
} break;
|
||
case DSC_X_PV_END: {
|
||
dsc_data_ptr++;
|
||
pv_end = true;
|
||
break;
|
||
} break;
|
||
case DSC_X_SHADOWPOS: {
|
||
chara_id = data[0];
|
||
playdata = &this->playdata[chara_id];
|
||
rob_chr = playdata->rob_chr;
|
||
} break;
|
||
case DSC_X_EDIT_LYRIC: {
|
||
|
||
} break;
|
||
case DSC_X_EDIT_TARGET: {
|
||
|
||
} break;
|
||
case DSC_X_EDIT_MOUTH: {
|
||
chara_id = data[0];
|
||
playdata = &this->playdata[chara_id];
|
||
rob_chr = playdata->rob_chr;
|
||
|
||
int32_t mouth_anim_id = data[1];
|
||
|
||
if (!rob_chr)
|
||
break;
|
||
|
||
int32_t mottbl_index = mouth_anim_id_to_mottbl_index(mouth_anim_id);
|
||
|
||
rob_chr->set_mouth_mottbl_motion(0, mottbl_index, 1.0f,
|
||
0, 0.1f, 0.0f, 1.0f, -1, 0.0f, aft_mot_db);
|
||
} break;
|
||
case DSC_X_SET_CHARA: {
|
||
chara_id = data[0];
|
||
playdata = &this->playdata[chara_id];
|
||
rob_chr = playdata->rob_chr;
|
||
} break;
|
||
case DSC_X_EDIT_MOVE: {
|
||
|
||
} break;
|
||
case DSC_X_EDIT_SHADOW: {
|
||
|
||
} break;
|
||
case DSC_X_EDIT_EYELID: {
|
||
|
||
} break;
|
||
case DSC_X_EDIT_EYE: {
|
||
|
||
} break;
|
||
case DSC_X_EDIT_ITEM: {
|
||
|
||
} break;
|
||
case DSC_X_EDIT_EFFECT: {
|
||
|
||
} break;
|
||
case DSC_X_EDIT_DISP: {
|
||
|
||
} break;
|
||
case DSC_X_EDIT_HAND_ANIM: {
|
||
|
||
} break;
|
||
case DSC_X_AIM: {
|
||
chara_id = data[0];
|
||
playdata = &this->playdata[chara_id];
|
||
rob_chr = playdata->rob_chr;
|
||
} break;
|
||
case DSC_X_HAND_ITEM: {
|
||
|
||
} break;
|
||
case DSC_X_EDIT_BLUSH: {
|
||
|
||
} break;
|
||
case DSC_X_NEAR_CLIP: {
|
||
|
||
} break;
|
||
case DSC_X_CLOTH_WET: {
|
||
chara_id = data[0];
|
||
playdata = &this->playdata[chara_id];
|
||
rob_chr = playdata->rob_chr;
|
||
|
||
float_t wet = (float_t)data[1] * 0.001f;
|
||
|
||
wet = clamp_def(wet, 0.0f, 1.0f);
|
||
|
||
if (rob_chr)
|
||
rob_chr->item_equip->wet = wet;
|
||
} break;
|
||
case DSC_X_LIGHT_ROT: {
|
||
|
||
} break;
|
||
case DSC_X_SCENE_FADE: {
|
||
|
||
} break;
|
||
case DSC_X_TONE_TRANS: {
|
||
vec3 start;
|
||
start.x = (float_t)data[0] * 0.001f;
|
||
start.y = (float_t)data[1] * 0.001f;
|
||
start.z = (float_t)data[2] * 0.001f;
|
||
|
||
vec3 end;
|
||
end.x = (float_t)data[3] * 0.001f;
|
||
end.y = (float_t)data[4] * 0.001f;
|
||
end.z = (float_t)data[5] * 0.001f;
|
||
|
||
rctx_ptr->render.set_tone_trans(start, end, 1);
|
||
} break;
|
||
case DSC_X_SATURATE: {
|
||
float_t saturate_coeff = (float_t)data[0] * 0.001f;
|
||
|
||
rctx_ptr->render.set_saturate_coeff(saturate_coeff, 1, false);
|
||
} break;
|
||
case DSC_X_FADE_MODE: {
|
||
int32_t blend_func = data[0];
|
||
|
||
rctx_ptr->render.set_scene_fade_blend_func(blend_func, 1);
|
||
} break;
|
||
case DSC_X_AUTO_BLINK: {
|
||
|
||
} break;
|
||
case DSC_X_PARTS_DISP: {
|
||
chara_id = data[0];
|
||
playdata = &this->playdata[chara_id];
|
||
rob_chr = playdata->rob_chr;
|
||
|
||
item_id id = (item_id)data[1];
|
||
int32_t disp = data[2];
|
||
|
||
if (!rob_chr)
|
||
break;
|
||
|
||
rob_chr->set_parts_disp(id, disp == 1);
|
||
} break;
|
||
case DSC_X_TARGET_FLYING_TIME: {
|
||
|
||
} break;
|
||
case DSC_X_CHARA_SIZE: {
|
||
chara_id = data[0];
|
||
playdata = &this->playdata[chara_id];
|
||
rob_chr = playdata->rob_chr;
|
||
|
||
int32_t chara_size = data[1];
|
||
|
||
if (!rob_chr)
|
||
break;
|
||
|
||
int32_t chara_size_index;
|
||
if (chara_size == 0)
|
||
chara_size_index = chara_init_data_get_chara_size_index(rob_chr->chara_index);
|
||
else if (chara_size == 1) {
|
||
::chara_index chara_index = CHARA_MIKU;
|
||
if (chara_id < pv_game->get_data().play_param->chara.size())
|
||
chara_index = (::chara_index)pv_game->get_data()
|
||
.play_param->chara[chara_id].chara_effect.base_chara;
|
||
else if (pv_game->get_data().pv_id == 826 && false)
|
||
chara_index = rob_chara_array_get(chara_id)->chara_index;
|
||
|
||
chara_size_index = chara_init_data_get_chara_size_index(chara_index);
|
||
}
|
||
else if (chara_size == 2)
|
||
chara_size_index = 1;
|
||
else if (chara_size == 3)
|
||
chara_size_index = rob_chr->pv_data.chara_size_index;
|
||
else {
|
||
rob_chr->set_chara_size((float_t)chara_size / 1000.0f);
|
||
break;
|
||
}
|
||
|
||
if (chara_size_index < 0 || chara_size_index > 4)
|
||
break;
|
||
|
||
rob_chr->set_chara_size(chara_size_table_get_value(chara_size_index));
|
||
rob_chr->set_chara_pos_adjust_y(chara_pos_adjust_y_table_get_value(chara_size_index));
|
||
} break;
|
||
case DSC_X_CHARA_HEIGHT_ADJUST: {
|
||
chara_id = data[0];
|
||
playdata = &this->playdata[chara_id];
|
||
rob_chr = playdata->rob_chr;
|
||
|
||
int32_t height_adjust = data[1];
|
||
|
||
if (rob_chr)
|
||
rob_chr->set_chara_height_adjust(height_adjust != 0);
|
||
} break;
|
||
case DSC_X_ITEM_ANIM: {
|
||
printf_debug("");
|
||
} break;
|
||
case DSC_X_CHARA_POS_ADJUST: {
|
||
chara_id = data[0];
|
||
playdata = &this->playdata[chara_id];
|
||
rob_chr = playdata->rob_chr;
|
||
|
||
vec3 pos;
|
||
pos.x = (float_t)data[2] * 0.001f;
|
||
pos.y = (float_t)data[3] * 0.001f;
|
||
pos.z = (float_t)data[4] * 0.001f;
|
||
|
||
if (!rob_chr)
|
||
break;
|
||
|
||
mat4_transform_point(&scene_rot_mat, &pos, &pos);
|
||
rob_chr->set_chara_pos_adjust(pos);
|
||
|
||
if (rob_chr->check_for_ageageagain_module()) {
|
||
rob_chara_age_age_array_set_skip(rob_chr->chara_id, 1);
|
||
rob_chara_age_age_array_set_skip(rob_chr->chara_id, 2);
|
||
}
|
||
} break;
|
||
case DSC_X_SCENE_ROT: {
|
||
float_t scene_rot = (float_t)data[0] * 0.001f;
|
||
|
||
scene_rot_y = scene_rot;
|
||
mat4_rotate_y(scene_rot * DEG_TO_RAD_FLOAT, &scene_rot_mat);
|
||
|
||
} break;
|
||
case DSC_X_EDIT_MOT_SMOOTH_LEN: {
|
||
|
||
} break;
|
||
case DSC_X_PV_BRANCH_MODE: {
|
||
int32_t branch_mode = data[0];
|
||
|
||
if (branch_mode >= 0 && branch_mode <= 2)
|
||
this->branch_mode = branch_mode;
|
||
} break;
|
||
case DSC_X_DATA_CAMERA_START: {
|
||
|
||
} break;
|
||
case DSC_X_MOVIE_PLAY: {
|
||
|
||
} break;
|
||
case DSC_X_MOVIE_DISP: {
|
||
|
||
} break;
|
||
case DSC_X_WIND: {
|
||
chara_id = data[0];
|
||
playdata = &this->playdata[chara_id];
|
||
rob_chr = playdata->rob_chr;
|
||
|
||
float_t wind_strength_kami = (float_t)data[1] * 0.001f;
|
||
float_t wind_strength_outer = (float_t)data[2] * 0.001f;
|
||
|
||
if (!rob_chr)
|
||
break;
|
||
|
||
rob_chr->set_wind_strength(wind_strength_outer);
|
||
} break;
|
||
case DSC_X_OSAGE_STEP: {
|
||
chara_id = data[0];
|
||
playdata = &this->playdata[chara_id];
|
||
rob_chr = playdata->rob_chr;
|
||
|
||
float_t osage_step_kami = (float_t)data[1] * 0.001f;
|
||
float_t osage_step_outer = (float_t)data[2] * 0.001f;
|
||
|
||
if (!rob_chr)
|
||
break;
|
||
|
||
rob_chr->set_osage_step(osage_step_outer);
|
||
} break;
|
||
case DSC_X_OSAGE_MV_CCL: {
|
||
chara_id = data[0];
|
||
playdata = &this->playdata[chara_id];
|
||
rob_chr = playdata->rob_chr;
|
||
|
||
float_t osage_mv_ccl_kami = (float_t)data[1] * 0.001f;
|
||
float_t osage_mv_ccl_outer = (float_t)data[2] * 0.001f;
|
||
|
||
if (!rob_chr)
|
||
break;
|
||
|
||
rob_chr->set_osage_move_cancel(1, osage_mv_ccl_kami);
|
||
rob_chr->set_osage_move_cancel(2, osage_mv_ccl_outer);
|
||
} break;
|
||
case DSC_X_CHARA_COLOR: {
|
||
|
||
} break;
|
||
case DSC_X_SE_EFFECT: {
|
||
|
||
} break;
|
||
case DSC_X_CHARA_SHADOW_QUALITY: {
|
||
|
||
} break;
|
||
case DSC_X_STAGE_SHADOW_QUALITY: {
|
||
|
||
} break;
|
||
case DSC_X_COMMON_LIGHT: {
|
||
|
||
} break;
|
||
case DSC_X_TONE_MAP: {
|
||
|
||
} break;
|
||
case DSC_X_IBL_COLOR: {
|
||
|
||
} break;
|
||
case DSC_X_REFLECTION: {
|
||
|
||
} break;
|
||
case DSC_X_CHROMATIC_ABERRATION: {
|
||
|
||
} break;
|
||
case DSC_X_STAGE_SHADOW: {
|
||
|
||
} break;
|
||
case DSC_X_REFLECTION_QUALITY: {
|
||
|
||
} break;
|
||
case DSC_X_PV_END_FADEOUT: {
|
||
|
||
} break;
|
||
case DSC_X_CREDIT_TITLE: {
|
||
int32_t index = data[0];
|
||
|
||
if (index)
|
||
pv_game->get_data().title.show(index - 1);
|
||
} break;
|
||
case DSC_X_BAR_POINT: {
|
||
|
||
} break;
|
||
case DSC_X_BEAT_POINT: {
|
||
|
||
} break;
|
||
case DSC_X_RESERVE1: {
|
||
|
||
} break;
|
||
case DSC_X_PV_AUTH_LIGHT_PRIORITY: {
|
||
|
||
} break;
|
||
case DSC_X_PV_CHARA_LIGHT: {
|
||
|
||
} break;
|
||
case DSC_X_PV_STAGE_LIGHT: {
|
||
|
||
} break;
|
||
case DSC_X_TARGET_EFFECT: {
|
||
|
||
} break;
|
||
case DSC_X_FOG: {
|
||
|
||
} break;
|
||
case DSC_X_BLOOM: {
|
||
int32_t id = data[0];
|
||
float_t duration = (float_t)data[1];
|
||
|
||
set_pv_param_post_process_bloom_data(true, id, duration);
|
||
} break;
|
||
case DSC_X_COLOR_CORRECTION: {
|
||
int32_t enable = data[0];
|
||
int32_t id = data[1];
|
||
float_t duration = (float_t)data[2];
|
||
|
||
set_pv_param_post_process_color_correction_data(enable == 1, id, duration);
|
||
} break;
|
||
case DSC_X_DOF: {
|
||
int32_t enable = data[0];
|
||
int32_t id = data[1];
|
||
float_t duration = (float_t)data[2];
|
||
|
||
set_pv_param_post_process_dof_data(enable == 1, id, duration);
|
||
} break;
|
||
case DSC_X_CHARA_ALPHA: {
|
||
chara_id = data[0];
|
||
playdata = &this->playdata[chara_id];
|
||
rob_chr = playdata->rob_chr;
|
||
|
||
float_t alpha = (float_t)data[1] * 0.001f;
|
||
float_t duration = (float_t)data[2];
|
||
int32_t type = data[3];
|
||
|
||
if (chara_id >= 0 && chara_id < ROB_CHARA_COUNT)
|
||
pv_param_task::post_process_task_set_chara_alpha(
|
||
chara_id, type, alpha, duration * 2.0f);
|
||
} break;
|
||
case DSC_X_AUTO_CAPTURE_BEGIN: {
|
||
|
||
} break;
|
||
case DSC_X_MANUAL_CAPTURE: {
|
||
|
||
} break;
|
||
case DSC_X_TOON_EDGE: {
|
||
|
||
} break;
|
||
case DSC_X_SHIMMER: {
|
||
|
||
} break;
|
||
case DSC_X_ITEM_ALPHA: {
|
||
chara_id = data[0];
|
||
playdata = &this->playdata[chara_id];
|
||
rob_chr = playdata->rob_chr;
|
||
|
||
float_t alpha = (float_t)data[1] * 0.001f;
|
||
float_t duration = (float_t)data[2];
|
||
int32_t type = data[3];
|
||
|
||
if (chara_id >= 0 && chara_id < ROB_CHARA_COUNT) {
|
||
pv_param_task::post_process_task_set_chara_item_alpha(
|
||
chara_id, type, alpha, duration * 2.0f,
|
||
x_pv_game_item_alpha_callback, this->pv_game);
|
||
}
|
||
} break;
|
||
case DSC_X_MOVIE_CUT: {
|
||
|
||
} break;
|
||
case DSC_X_EDIT_CAMERA_BOX: {
|
||
|
||
} break;
|
||
case DSC_X_EDIT_STAGE_PARAM: {
|
||
|
||
} break;
|
||
case DSC_X_EDIT_CHANGE_FIELD: {
|
||
|
||
} break;
|
||
case DSC_X_MIKUDAYO_ADJUST: {
|
||
|
||
} break;
|
||
case DSC_X_LYRIC_2: {
|
||
|
||
} break;
|
||
case DSC_X_LYRIC_READ: {
|
||
|
||
} break;
|
||
case DSC_X_LYRIC_READ_2: {
|
||
|
||
} break;
|
||
case DSC_X_ANNOTATION: {
|
||
|
||
} break;
|
||
case DSC_X_STAGE_EFFECT: {
|
||
int32_t stage_effect = data[0];
|
||
|
||
if (stage_effect >= 8 && stage_effect <= 9)
|
||
pv_game->stage_data.set_stage_effect(stage_effect);
|
||
} break;
|
||
case DSC_X_SONG_EFFECT: {
|
||
bool enable = data[0] ? true : false;
|
||
int32_t index = data[1];
|
||
int32_t unk2 = data[2];
|
||
|
||
if (unk2 && !(pv_game->get_data().field_1C & 0x10))
|
||
break;
|
||
|
||
x_pv_game_effect& effect = pv_game->get_data().effect;
|
||
if (enable) {
|
||
effect.set_song_effect(index, dsc_time);
|
||
//if (a2->field_18)
|
||
// effect.set_song_effect_time(index/*, a2->field_20*/, true);
|
||
//else
|
||
effect.set_song_effect_time(index, pv_game->time, false);
|
||
}
|
||
else
|
||
effect.stop_song_effect(index, true);
|
||
} break;
|
||
case DSC_X_SONG_EFFECT_ATTACH: {
|
||
int32_t index = data[0];
|
||
int32_t chara_id = data[1];
|
||
int32_t chara_item = data[2];
|
||
|
||
pv_game->get_data().effect.set_chara_id(index, chara_id, !!chara_item);
|
||
} break;
|
||
case DSC_X_LIGHT_AUTH: {
|
||
|
||
} break;
|
||
case DSC_X_FADE: {
|
||
|
||
} break;
|
||
case DSC_X_SET_STAGE_EFFECT_ENV: {
|
||
int32_t env_index = data[0];
|
||
int32_t trans = data[1];
|
||
pv_game->stage_data.set_env(env_index, (float_t)trans * (float_t)(1.0f / 60.0f), 0.0f);
|
||
printf_debug("Time: %8d; Frame %5d; Env: %2d; Trans: %3d\n",
|
||
(int32_t)(curr_time / 10000), pv_game->frame, env_index, trans);
|
||
} break;
|
||
case DSC_X_RESERVE2: {
|
||
|
||
} break;
|
||
case DSC_X_COMMON_EFFECT_AET_FRONT: {
|
||
|
||
} break;
|
||
case DSC_X_COMMON_EFFECT_AET_FRONT_LOW: {
|
||
|
||
} break;
|
||
case DSC_X_COMMON_EFFECT_PARTICLE: {
|
||
|
||
} break;
|
||
case DSC_X_SONG_EFFECT_ALPHA_SORT: {
|
||
|
||
} break;
|
||
case DSC_X_LOOK_CAMERA_FACE_LIMIT: {
|
||
|
||
} break;
|
||
case DSC_X_ITEM_LIGHT: {
|
||
|
||
} break;
|
||
case DSC_X_CHARA_EFFECT: {
|
||
int32_t chara_id = data[0];
|
||
bool enable = data[1] ? true : false;
|
||
int32_t index = data[2];
|
||
|
||
x_pv_game_chara_effect& chara_effect = pv_game->get_data().chara_effect;
|
||
if (enable) {
|
||
chara_effect.set_chara_effect(chara_id, index, dsc_time);
|
||
//if (a2->field_18)
|
||
// chara_effect.set_chara_effect_time(chara_id, index/*, a2->field_20*/);
|
||
//else
|
||
chara_effect.set_chara_effect_time(chara_id, index, pv_game->time);
|
||
}
|
||
else
|
||
chara_effect.stop_chara_effect(chara_id, index);
|
||
} break;
|
||
case DSC_X_MARKER: {
|
||
|
||
} break;
|
||
case DSC_X_CHARA_EFFECT_CHARA_LIGHT: {
|
||
|
||
} break;
|
||
case DSC_X_ENABLE_COMMON_LIGHT_TO_CHARA: {
|
||
|
||
} break;
|
||
case DSC_X_ENABLE_FXAA: {
|
||
|
||
} break;
|
||
case DSC_X_ENABLE_TEMPORAL_AA: {
|
||
|
||
} break;
|
||
case DSC_X_ENABLE_REFLECTION: {
|
||
|
||
} break;
|
||
case DSC_X_BANK_BRANCH: {
|
||
|
||
} break;
|
||
case DSC_X_BANK_END: {
|
||
|
||
} break;
|
||
case DSC_X_NULL1: {
|
||
|
||
} break;
|
||
case DSC_X_NULL2: {
|
||
|
||
} break;
|
||
case DSC_X_NULL3: {
|
||
|
||
} break;
|
||
case DSC_X_NULL4: {
|
||
|
||
} break;
|
||
case DSC_X_NULL5: {
|
||
|
||
} break;
|
||
case DSC_X_NULL6: {
|
||
|
||
} break;
|
||
case DSC_X_NULL7: {
|
||
|
||
} break;
|
||
case DSC_X_NULL8: {
|
||
|
||
} break;
|
||
case DSC_X_VR_LIVE_MOVIE: {
|
||
|
||
} break;
|
||
case DSC_X_VR_CHEER: {
|
||
|
||
} break;
|
||
case DSC_X_VR_CHARA_PSMOVE: {
|
||
|
||
} break;
|
||
case DSC_X_VR_MOVE_PATH: {
|
||
|
||
} break;
|
||
case DSC_X_VR_SET_BASE: {
|
||
|
||
} break;
|
||
case DSC_X_VR_TECH_DEMO_EFFECT: {
|
||
|
||
} break;
|
||
case DSC_X_VR_TRANSFORM: {
|
||
|
||
} break;
|
||
case DSC_X_GAZE: {
|
||
|
||
} break;
|
||
case DSC_X_TECH_DEMO_GESUTRE: {
|
||
|
||
} break;
|
||
case DSC_X_VR_CHEMICAL_LIGHT_COLOR: {
|
||
|
||
} break;
|
||
case DSC_X_VR_LIVE_MOB: {
|
||
|
||
} break;
|
||
case DSC_X_VR_LIVE_HAIR_OSAGE: {
|
||
|
||
} break;
|
||
case DSC_X_VR_LIVE_LOOK_CAMERA: {
|
||
|
||
} break;
|
||
case DSC_X_VR_LIVE_CHEER: {
|
||
|
||
} break;
|
||
case DSC_X_VR_LIVE_GESTURE: {
|
||
|
||
} break;
|
||
case DSC_X_VR_LIVE_CLONE: {
|
||
|
||
} break;
|
||
case DSC_X_VR_LOOP_EFFECT: {
|
||
|
||
} break;
|
||
case DSC_X_VR_LIVE_ONESHOT_EFFECT: {
|
||
|
||
} break;
|
||
case DSC_X_VR_LIVE_PRESENT: {
|
||
|
||
} break;
|
||
case DSC_X_VR_LIVE_TRANSFORM: {
|
||
|
||
} break;
|
||
case DSC_X_VR_LIVE_FLY: {
|
||
|
||
} break;
|
||
case DSC_X_VR_LIVE_CHARA_VOICE: {
|
||
|
||
} break;
|
||
}
|
||
|
||
dsc_data_ptr++;
|
||
return true;
|
||
}
|
||
|
||
dsc_data* x_pv_game_pv_data::find(int32_t func_name, int32_t* time,
|
||
int32_t* pv_branch_mode, dsc_data* start, dsc_data* end) {
|
||
int32_t _time = -1;
|
||
for (dsc_data* i = start; i != end; i++)
|
||
if (i->func == func_name) {
|
||
if (time)
|
||
*time = _time;
|
||
return i;
|
||
}
|
||
else if (i->func == DSC_X_END)
|
||
break;
|
||
else if (i->func == DSC_X_TIME) {
|
||
int32_t* data = dsc.get_func_data(i);
|
||
_time = data[0];
|
||
}
|
||
else if (i->func == DSC_X_PV_END)
|
||
break;
|
||
else if (i->func == DSC_X_PV_BRANCH_MODE) {
|
||
if (pv_branch_mode) {
|
||
int32_t* data = dsc.get_func_data(i);
|
||
*pv_branch_mode = data[0];
|
||
}
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
void x_pv_game_pv_data::find_bar_beat(x_pv_bar_beat& bar_beat) {
|
||
x_pv_bar_beat_data* bar_beat_data = 0;
|
||
int32_t beat_counter = 0;
|
||
|
||
int32_t time = -1;
|
||
for (dsc_data& i : dsc.data) {
|
||
if (i.func == DSC_X_END)
|
||
break;
|
||
|
||
int32_t* data = dsc.get_func_data(&i);
|
||
switch (i.func) {
|
||
case DSC_X_TIME: {
|
||
time = data[0];
|
||
} break;
|
||
case DSC_X_BAR_POINT: {
|
||
bar_beat.data.push_back({});
|
||
bar_beat_data = &bar_beat.data.back();
|
||
*bar_beat_data = {};
|
||
bar_beat_data->bar = data[0];
|
||
bar_beat_data->bar_time = (float_t)time * (float_t)(1.0 / 100000.0);
|
||
bar_beat_data->beat_counter = beat_counter;
|
||
} break;
|
||
case DSC_X_BEAT_POINT: {
|
||
if (!bar_beat_data)
|
||
break;
|
||
|
||
bar_beat_data->beat_counter = ++beat_counter;
|
||
bar_beat_data->beat_time[bar_beat_data->beat_count++] = (float_t)time * (float_t)(1.0 / 100000.0);
|
||
} break;
|
||
}
|
||
}
|
||
}
|
||
|
||
void x_pv_game_pv_data::find_change_fields(std::vector<int64_t>& change_fields) {
|
||
int32_t pv_branch_mode = 0;
|
||
int32_t time = -1;
|
||
int32_t prev_time = -1;
|
||
|
||
dsc_data* i = dsc.data.data();
|
||
dsc_data* i_end = dsc.data.data() + dsc.data.size();
|
||
while (i = find(DSC_X_CHANGE_FIELD, &time, &pv_branch_mode, i, i_end)) {
|
||
if (time < 0) {
|
||
time = prev_time;
|
||
if (prev_time < 0)
|
||
break;
|
||
}
|
||
|
||
change_fields.push_back((int64_t)time * 10000);
|
||
prev_time = time;
|
||
i++;
|
||
}
|
||
}
|
||
|
||
void x_pv_game_pv_data::find_playdata_item_anim(int32_t chara_id) {
|
||
if (chara_id < 0 || chara_id >= ROB_CHARA_COUNT)
|
||
return;
|
||
|
||
x_pv_play_data* playdata = &this->playdata[chara_id];
|
||
playdata->motion_data.set_item.clear();
|
||
|
||
int32_t pv_branch_mode = 0;
|
||
int32_t time = -1;
|
||
int32_t prev_time = -1;
|
||
|
||
dsc_data* i = dsc.data.data();
|
||
dsc_data* i_end = dsc.data.data() + dsc.data.size();
|
||
while (true) {
|
||
i = find(DSC_X_ITEM_ANIM, &time, &pv_branch_mode, i, i_end);
|
||
if (!i)
|
||
break;
|
||
|
||
if (time < 0) {
|
||
time = prev_time;
|
||
if (prev_time < 0)
|
||
break;
|
||
}
|
||
|
||
int32_t* data = dsc.get_func_data(i);
|
||
if (chara_id == data[0] && data[2] == 2)
|
||
playdata->motion_data.set_item.push_back({ time, data[1], pv_branch_mode });
|
||
prev_time = time;
|
||
i++;
|
||
}
|
||
}
|
||
|
||
void x_pv_game_pv_data::find_playdata_set_motion(int32_t chara_id) {
|
||
if (chara_id < 0 || chara_id >= ROB_CHARA_COUNT)
|
||
return;
|
||
|
||
x_pv_play_data* playdata = &this->playdata[chara_id];
|
||
playdata->motion_data.set_motion.clear();
|
||
|
||
int32_t pv_branch_mode = 0;
|
||
int32_t time = -1;
|
||
int32_t prev_time = -1;
|
||
|
||
dsc_data* i = dsc.data.data();
|
||
dsc_data* i_end = dsc.data.data() + dsc.data.size();
|
||
while (true) {
|
||
i = find(DSC_X_SET_MOTION, &time, &pv_branch_mode, i, i_end);
|
||
if (!i)
|
||
break;
|
||
|
||
if (time < 0) {
|
||
time = prev_time;
|
||
if (prev_time < 0)
|
||
break;
|
||
}
|
||
|
||
int32_t* data = dsc.get_func_data(i);
|
||
if (chara_id == data[0])
|
||
playdata->motion_data.set_motion.push_back({ time, data[1], pv_branch_mode });
|
||
prev_time = time;
|
||
i++;
|
||
}
|
||
}
|
||
|
||
int64_t x_pv_game_pv_data::find_pv_end() {
|
||
int32_t pv_branch_mode = 0;
|
||
int32_t pv_end_time = -1;
|
||
int32_t end_time = -1;
|
||
|
||
dsc_data* i = dsc.data.data();
|
||
dsc_data* i_end = dsc.data.data() + dsc.data.size();
|
||
find(DSC_X_PV_END, &pv_end_time, &pv_branch_mode, i, i_end);
|
||
|
||
pv_branch_mode = 0;
|
||
|
||
i = dsc.data.data();
|
||
i_end = dsc.data.data() + dsc.data.size();
|
||
find(DSC_X_END, &end_time, &pv_branch_mode, i, i_end);
|
||
return max_def(pv_end_time, end_time);
|
||
}
|
||
|
||
void x_pv_game_pv_data::find_set_motion() {
|
||
for (std::vector<pv_data_set_motion>& i : set_motion)
|
||
i.clear();
|
||
|
||
std::vector<x_pv_play_data_event> v98[6];
|
||
|
||
int32_t pv_branch_mode = 0;
|
||
int32_t time = -1;
|
||
int32_t prev_time = -1;
|
||
|
||
dsc_data* i = dsc.data.data();
|
||
dsc_data* i_end = dsc.data.data() + dsc.data.size();
|
||
while (true) {
|
||
i = find(DSC_X_SET_PLAYDATA, &time, &pv_branch_mode, i, i_end);
|
||
if (!i)
|
||
break;
|
||
|
||
if (time < 0)
|
||
time = prev_time;
|
||
|
||
int32_t* data = dsc.get_func_data(i);
|
||
|
||
int32_t chara_id = data[0];
|
||
int32_t motion_index = data[1];
|
||
|
||
v98[chara_id].push_back({ time, motion_index, pv_branch_mode });
|
||
|
||
prev_time = time;
|
||
i++;
|
||
}
|
||
|
||
pv_branch_mode = 0;
|
||
time = -1;
|
||
prev_time = -1;
|
||
|
||
i = dsc.data.data();
|
||
i_end = dsc.data.data() + dsc.data.size();
|
||
while (true) {
|
||
i = find(DSC_X_CHANGE_FIELD, &time, &pv_branch_mode, i, i_end);
|
||
if (!i)
|
||
break;
|
||
|
||
if (time < 0)
|
||
time = prev_time;
|
||
|
||
prev_time = time;
|
||
i++;
|
||
}
|
||
|
||
data_struct* aft_data = &data_list[DATA_AFT];
|
||
motion_database* aft_mot_db = &aft_data->data_ft.mot_db;
|
||
|
||
pvpp* play_param = pv_game->get_data().play_param;
|
||
|
||
for (int32_t i = 0; i < ROB_CHARA_COUNT; i++) {
|
||
x_pv_play_data& playdata = this->playdata[i];
|
||
std::vector<pv_data_set_motion>& set_motion = this->set_motion[i];
|
||
|
||
for (x_pv_play_data_event& j : playdata.motion_data.set_motion) {
|
||
int32_t time = -1;
|
||
int32_t v56 = 0;
|
||
|
||
x_pv_play_data_event* i_begin = v98[i].data() + v98[i].size();
|
||
x_pv_play_data_event* i_end = v98[i].data();
|
||
for (x_pv_play_data_event* i = i_begin; i != i_end; ) {
|
||
i--;
|
||
|
||
if (i->index == j.index && i->time <= j.time) {
|
||
time = i->time;
|
||
break;
|
||
}
|
||
}
|
||
|
||
if (time < 0)
|
||
time = j.time;
|
||
|
||
float_t frame = prj::roundf(dsc_time_to_frame(((int64_t)j.time - time) * 10000));
|
||
|
||
uint32_t motion_id = -1;
|
||
if (i >= 0 && i < play_param->chara.size()) {
|
||
pvpp_chara& chara = play_param->chara[i];
|
||
if (j.index > 0 && j.index <= chara.motion.size()) {
|
||
string_hash& motion = chara.motion[(size_t)j.index - 1];
|
||
|
||
std::string name(motion.str);
|
||
size_t pos = name.find("PV832");
|
||
if (pos != -1)
|
||
name.replace(pos, 5, "PV800", 5);
|
||
motion_id = aft_mot_db->get_motion_id(name.c_str());
|
||
}
|
||
}
|
||
|
||
if (motion_id != -1)
|
||
set_motion.push_back({ motion_id, { frame, -1 } });
|
||
}
|
||
}
|
||
|
||
for (int32_t i = 0; i < ROB_CHARA_COUNT; i++) {
|
||
if (i < 0 || i >= play_param->chara.size())
|
||
continue;
|
||
|
||
rob_chara* rob_chr = rob_chara_array_get(i);
|
||
int32_t pv_id = pv_game->get_data().pv_id;
|
||
|
||
std::vector<pv_data_set_motion>& set_motion = this->set_motion[i];
|
||
std::vector<osage_init_data> vec;
|
||
vec.reserve(set_motion.size());
|
||
for (pv_data_set_motion& j : set_motion) {
|
||
osage_init_data osage_init;
|
||
osage_init.rob_chr = rob_chr;
|
||
osage_init.pv_id = pv_id;
|
||
osage_init.motion_id = j.motion_id;
|
||
osage_init.frame = (int32_t)j.frame_stage_index.first;
|
||
vec.push_back(osage_init);
|
||
}
|
||
skin_param_manager_add_task(i, vec);
|
||
}
|
||
}
|
||
|
||
void x_pv_game_pv_data::find_stage_effects(prj::vector_pair<int64_t, int32_t>& stage_effects) {
|
||
int32_t pv_branch_mode = 0;
|
||
int32_t time = -1;
|
||
int32_t prev_time = -1;
|
||
|
||
dsc_data* i = dsc.data.data();
|
||
dsc_data* i_end = dsc.data.data() + dsc.data.size();
|
||
while (i = find(DSC_X_STAGE_EFFECT, &time, &pv_branch_mode, i, i_end)) {
|
||
if (time < 0) {
|
||
time = prev_time;
|
||
if (prev_time < 0)
|
||
break;
|
||
}
|
||
|
||
int32_t* data = dsc.get_func_data(i);
|
||
int32_t stage_effect = data[0];
|
||
|
||
if (stage_effect < 8 || stage_effect > 9)
|
||
stage_effects.push_back((int64_t)time * 10000, stage_effect);
|
||
prev_time = time;
|
||
i++;
|
||
}
|
||
}
|
||
|
||
void x_pv_game_pv_data::init(class x_pv_game* pv_game, bool music_play) {
|
||
this->pv_game = pv_game;
|
||
target_anim_fps = 60.0f;
|
||
anim_frame_speed = 1.0f;
|
||
scene_rot_mat = mat4_identity;
|
||
|
||
target_anim_fps = get_target_anim_fps();
|
||
anim_frame_speed = get_anim_frame_speed();
|
||
|
||
pv_expression_array_reset();
|
||
|
||
for (int32_t i = 0; i < ROB_CHARA_COUNT; i++) {
|
||
if (pv_game->rob_chara_ids[i] == -1)
|
||
continue;
|
||
|
||
x_pv_play_data& playdata = this->playdata[i];
|
||
playdata.reset();
|
||
playdata.set_motion.clear();
|
||
|
||
if (pv_game->rob_chara_ids[i] != -1)
|
||
playdata.rob_chr = rob_chara_array_get(pv_game->rob_chara_ids[i]);
|
||
|
||
if (playdata.rob_chr) {
|
||
playdata.rob_chr->frame_speed = anim_frame_speed;
|
||
playdata.rob_chr->data.motion.step_data.step = anim_frame_speed;
|
||
pv_expression_array_set(i, playdata.rob_chr, anim_frame_speed);
|
||
}
|
||
|
||
find_playdata_set_motion(i);
|
||
find_playdata_item_anim(i);
|
||
}
|
||
|
||
find_set_motion();
|
||
|
||
pv_end = false;
|
||
scene_rot_y = 0.0f;
|
||
scene_rot_mat = mat4_identity;
|
||
|
||
play = true;
|
||
|
||
find_change_fields(pv_game->get_data().change_fields);
|
||
|
||
Shadow* shad = shadow_ptr_get();
|
||
if (shad) {
|
||
shad->blur_filter_enable[0] = true;
|
||
shad->blur_filter_enable[1] = true;
|
||
}
|
||
|
||
chara_id = 0;
|
||
}
|
||
|
||
void x_pv_game_pv_data::reset() {
|
||
dsc.type = DSC_NONE;
|
||
dsc.signature = 0;
|
||
dsc.id = 0;
|
||
dsc.data.clear();
|
||
dsc.data.shrink_to_fit();
|
||
dsc.data_buffer.clear();
|
||
dsc.data_buffer.shrink_to_fit();
|
||
dsc_data_ptr = 0;
|
||
dsc_data_ptr_end = 0;
|
||
dsc_time = -1;
|
||
}
|
||
|
||
bool x_pv_game_pv_data::set_pv_param_post_process_bloom_data(bool set, int32_t id, float_t duration) {
|
||
pv_param::bloom& bloom = pv_param::post_process_data_get_bloom_data(id);
|
||
if (set)
|
||
pv_param_task::post_process_task_set_bloom_data(bloom, duration);
|
||
return true;
|
||
}
|
||
|
||
bool x_pv_game_pv_data::set_pv_param_post_process_color_correction_data(bool set, int32_t id, float_t duration) {
|
||
pv_param::color_correction& color_correction = pv_param::post_process_data_get_color_correction_data(id);
|
||
if (set)
|
||
pv_param_task::post_process_task_set_color_correction_data(color_correction, duration);
|
||
return true;
|
||
}
|
||
|
||
bool x_pv_game_pv_data::set_pv_param_post_process_dof_data(bool set, int32_t id, float_t duration) {
|
||
rctx_ptr->render.set_dof_enable(set);
|
||
rctx_ptr->render.set_dof_update(set);
|
||
|
||
pv_param::dof& dof = pv_param::post_process_data_get_dof_data(id);
|
||
if (set)
|
||
pv_param_task::post_process_task_set_dof_data(dof, duration,
|
||
x_pv_game_dof_callback, this->pv_game);
|
||
return true;
|
||
}
|
||
|
||
void x_pv_game_pv_data::set_motion_max_frame(int32_t chara_id, int32_t motion_index, int64_t time) {
|
||
if (chara_id < 0 || chara_id >= ROB_CHARA_COUNT || motion_index < 0)
|
||
return;
|
||
|
||
x_pv_play_data& playdata = this->playdata[chara_id];
|
||
|
||
std::vector<x_pv_play_data_event>& set_motion = playdata.motion_data.set_motion;
|
||
for (x_pv_play_data_event& i : set_motion)
|
||
if (10000LL * i.time > dsc_time && i.index == motion_index
|
||
&& (!branch_mode || branch_mode == i.pv_branch_mode)) {
|
||
playdata.rob_chr->bone_data->set_motion_max_frame(
|
||
prj::roundf(dsc_time_to_frame(10000LL * i.time - time)) - 1.0f);
|
||
break;
|
||
}
|
||
}
|
||
|
||
void x_pv_game_pv_data::stop() {
|
||
if (dsc.data.size()) {
|
||
dsc_data_ptr = dsc.data.data();
|
||
dsc_data_ptr_end = dsc_data_ptr + dsc.data.size();
|
||
}
|
||
else {
|
||
dsc_data_ptr = 0;
|
||
dsc_data_ptr_end = 0;
|
||
}
|
||
dsc_time = -1;
|
||
}
|
||
|
||
void x_pv_game_pv_data::unload() {
|
||
unload_data();
|
||
}
|
||
|
||
void x_pv_game_pv_data::unload_data() {
|
||
dsc.type = DSC_NONE;
|
||
dsc.signature = 0;
|
||
dsc.id = 0;
|
||
dsc.data.clear();
|
||
dsc.data.shrink_to_fit();
|
||
dsc.data_buffer.clear();
|
||
dsc.data_buffer.shrink_to_fit();
|
||
dsc_data_ptr = 0;
|
||
dsc_data_ptr_end = 0;
|
||
dsc_time = -1;
|
||
}
|
||
|
||
x_pv_game_data::x_pv_game_data() : pv_id(), play_param(), curr_time(), delta_time(), pv_end_time(),
|
||
time_float(), frame(), field_1C(), state(), stage_effect_index(), next_stage_effect_bar(), stage() {
|
||
|
||
}
|
||
|
||
x_pv_game_data::~x_pv_game_data() {
|
||
if (play_param) {
|
||
delete play_param;
|
||
play_param = 0;
|
||
}
|
||
}
|
||
|
||
#if BAKE_PV826
|
||
void x_pv_game_data::ctrl(float_t curr_time, float_t delta_time,
|
||
std::map<uint32_t, auth_3d_id>* effchrpv_auth_3d_mot_ids) {
|
||
#else
|
||
void x_pv_game_data::ctrl(float_t curr_time, float_t delta_time) {
|
||
#endif
|
||
this->curr_time = curr_time;
|
||
this->delta_time = delta_time;
|
||
|
||
switch (state) {
|
||
case 10: {
|
||
if (field_1C & 0x08) {
|
||
state = 20;
|
||
field_1C &= ~0x08;
|
||
}
|
||
else
|
||
state = 0;
|
||
} break;
|
||
case 20: {
|
||
effect.load_data(pv_id, &obj_db, &tex_db);
|
||
chara_effect.load_data();
|
||
title.load_data();
|
||
pv_expression_file_load(&data_list[DATA_X], "root+/pv_expression/", exp_file.hash_murmurhash);
|
||
state = 21;
|
||
} break;
|
||
case 21: {
|
||
if (stage->state != 20)
|
||
break;
|
||
|
||
camera.load_data();
|
||
|
||
state = 22;
|
||
} break;
|
||
case 22: {
|
||
bool wait_load = false;
|
||
|
||
wait_load |= pv_expression_file_check_not_ready(exp_file.hash_murmurhash);
|
||
wait_load |= camera.state && camera.state != 20;
|
||
wait_load |= effect.state && effect.state != 20;
|
||
wait_load |= chara_effect.state && chara_effect.state != 10 && chara_effect.state != 30;
|
||
wait_load |= title.state && title.state != 3 && title.state != 4;
|
||
|
||
if (wait_load)
|
||
break;
|
||
|
||
state = 23;
|
||
} break;
|
||
case 23: {
|
||
pv_data.find_bar_beat(bar_beat);
|
||
bar_beat.reset_time();
|
||
stage->bpm_frame_rate_control.bar_beat = &bar_beat;
|
||
state = 24;
|
||
} break;
|
||
case 24: {
|
||
pv_data.find_stage_effects(stage_effects);
|
||
|
||
int64_t pv_end_time = pv_data.find_pv_end();
|
||
if (pv_end_time >= 0)
|
||
this->pv_end_time = (float_t)((double_t)pv_end_time * 0.000000001);
|
||
state = 25;
|
||
} break;
|
||
case 25: {
|
||
pv_data.find_change_fields(change_fields);
|
||
effect.change_fields = &change_fields;
|
||
chara_effect.change_fields = &change_fields;
|
||
state = 30;
|
||
} break;
|
||
case 30: {
|
||
ctrl_stage_effect_index();
|
||
bar_beat.set_time(this->curr_time, this->delta_time);
|
||
pv_data.ctrl(true, curr_time, delta_time);
|
||
frame++;
|
||
} break;
|
||
case 40: {
|
||
//if (!sub_81254B9E())
|
||
state = 0;
|
||
} break;
|
||
}
|
||
|
||
camera.ctrl(this->curr_time);
|
||
effect.ctrl(&obj_db, &tex_db);
|
||
#if BAKE_PV826
|
||
chara_effect.ctrl(&obj_db, &tex_db, pv_id, effchrpv_auth_3d_mot_ids);
|
||
#else
|
||
chara_effect.ctrl(&obj_db, &tex_db);
|
||
#endif
|
||
title.ctrl();
|
||
field_1C &= ~0x02;
|
||
}
|
||
|
||
void x_pv_game_data::ctrl_stage_effect_index() {
|
||
if (stage_effect_index >= stage_effects.size())
|
||
return;
|
||
|
||
std::pair<int64_t, int32_t>* curr_stage_effect = &stage_effects[stage_effect_index];
|
||
if (next_stage_effect_bar > bar_beat.bar)
|
||
return;
|
||
|
||
stage->set_stage_effect(curr_stage_effect->second);
|
||
stage_effect_index++;
|
||
if (stage_effect_index >= stage_effects.size())
|
||
return;
|
||
|
||
std::pair<int64_t, int32_t>* next_stage_effect = &stage_effects[stage_effect_index];
|
||
|
||
float_t time = (float_t)((double_t)next_stage_effect->first * 0.000000001);
|
||
int32_t bar = bar_beat.get_bar_beat_from_time(0, time);
|
||
next_stage_effect_bar = --bar;
|
||
|
||
int32_t v14;
|
||
if (stage->check_stage_effect_has_change_effect(curr_stage_effect->second, next_stage_effect->second))
|
||
v14 = bar / 2 - 2;
|
||
else
|
||
v14 = bar / 2 - 1;
|
||
next_stage_effect_bar = 2 * max_def(v14, 0) + 1;
|
||
}
|
||
|
||
void x_pv_game_data::disp() {
|
||
title.disp();
|
||
}
|
||
|
||
#if BAKE_PV826
|
||
void x_pv_game_data::load(int32_t pv_id, FrameRateControl* frame_rate_control, chara_index charas[6],
|
||
std::unordered_map<std::string, string_hash>* effchrpv_auth_3d_mot_names) {
|
||
#else
|
||
void x_pv_game_data::load(int32_t pv_id, FrameRateControl* frame_rate_control, chara_index charas[6]) {
|
||
#endif
|
||
if (state)
|
||
return;
|
||
|
||
data_struct* x_data = &data_list[DATA_X];
|
||
|
||
title.load(pv_id, frame_rate_control);
|
||
effect.load(pv_id, play_param, frame_rate_control);
|
||
#if BAKE_PV826
|
||
chara_effect.load(pv_id, play_param, frame_rate_control, charas, effchrpv_auth_3d_mot_names);
|
||
#else
|
||
chara_effect.load(pv_id, play_param, frame_rate_control, charas);
|
||
#endif
|
||
|
||
char buf[0x200];
|
||
size_t len = sprintf_s(buf, sizeof(buf), "exp_PV%03d", pv_id);
|
||
exp_file.assign(buf, len);
|
||
|
||
camera.load(pv_id, stage->stage_id, frame_rate_control);
|
||
|
||
#if !BAKE_FAST
|
||
sprintf_s(buf, sizeof(buf), "rom/sound/song/pv_%03d.ogg", pv_id == 832 ? 800 : pv_id);
|
||
x_pv_game_music_ptr->ogg_reset();
|
||
x_pv_game_music_ptr->load(4, buf, true, 0.0f, false);
|
||
#endif
|
||
|
||
state = 10;
|
||
}
|
||
|
||
void x_pv_game_data::reset() {
|
||
#if !BAKE_FAST
|
||
x_pv_game_music_ptr->stop();
|
||
x_pv_game_music_ptr->set_volume_map(0, 0);
|
||
#endif
|
||
|
||
pv_id = 0;
|
||
play_param_file_handler.reset();
|
||
if (play_param) {
|
||
delete play_param;
|
||
play_param = 0;
|
||
}
|
||
curr_time = 0.0f;
|
||
delta_time = 0.0f;
|
||
pv_end_time = 0.0f;
|
||
time_float = 0.0f;
|
||
frame = 0;
|
||
field_1C = 0;
|
||
state = 0;
|
||
change_fields.clear();
|
||
change_fields.shrink_to_fit();
|
||
bar_beat.reset();
|
||
stage_effect_index = 0;
|
||
next_stage_effect_bar = 0;
|
||
stage_effects.clear();
|
||
stage_effects.shrink_to_fit();
|
||
camera.reset();
|
||
effect.reset();
|
||
chara_effect.reset();
|
||
pv_data.reset();
|
||
exp_file.clear();
|
||
//dof = {};
|
||
stage = 0;
|
||
obj_db.clear();
|
||
tex_db.clear();
|
||
}
|
||
|
||
void x_pv_game_data::stop() {
|
||
camera.stop();
|
||
stage->reset_stage_effect();
|
||
stage->reset_stage_env();
|
||
stage->curr_stage_effect = 0;
|
||
stage->next_stage_effect = 0;
|
||
stage->stage_effect_transition_state = 0;
|
||
effect.stop();
|
||
chara_effect.stop();
|
||
pv_data.stop();
|
||
bar_beat.reset_time();
|
||
stage_effect_index = 0;
|
||
next_stage_effect_bar = 0;
|
||
field_1C &= ~0xC0;
|
||
}
|
||
|
||
void x_pv_game_data::unload() {
|
||
stop();
|
||
|
||
camera.unload();
|
||
title.unload();
|
||
effect.unload();
|
||
chara_effect.unload();
|
||
//dof = {};
|
||
pv_data.unload();
|
||
pv_expression_file_unload(exp_file.hash_murmurhash);
|
||
|
||
obj_db.clear();
|
||
tex_db.clear();
|
||
|
||
#if !BAKE_FAST
|
||
x_pv_game_music_ptr->stop();
|
||
x_pv_game_music_ptr->set_channel_pair_volume_map(0, 100);
|
||
x_pv_game_music_ptr->set_channel_pair_volume_map(1, 100);
|
||
x_pv_game_music_ptr->exclude_flags(X_PV_GAME_MUSIC_OGG);
|
||
#endif
|
||
state = 40;
|
||
}
|
||
|
||
void x_pv_game_data::unload_data() {
|
||
if (state)
|
||
return;
|
||
|
||
stop();
|
||
|
||
camera.unload_data();
|
||
title.unload_data();
|
||
effect.unload_data();
|
||
chara_effect.unload_data();
|
||
//dof = {};
|
||
pv_data.unload_data();
|
||
pv_expression_file_unload(exp_file.hash_murmurhash);
|
||
|
||
obj_db.clear();
|
||
tex_db.clear();
|
||
|
||
#if !BAKE_FAST
|
||
x_pv_game_music_ptr->stop();
|
||
x_pv_game_music_ptr->set_channel_pair_volume_map(0, 100);
|
||
x_pv_game_music_ptr->set_channel_pair_volume_map(1, 100);
|
||
x_pv_game_music_ptr->exclude_flags(X_PV_GAME_MUSIC_OGG);
|
||
#endif
|
||
}
|
||
|
||
PVStageFrameRateControl::PVStageFrameRateControl() {
|
||
delta_frame = 1.0f;
|
||
}
|
||
|
||
PVStageFrameRateControl::~PVStageFrameRateControl() {
|
||
|
||
}
|
||
|
||
float_t PVStageFrameRateControl::get_delta_frame() {
|
||
return delta_frame;
|
||
}
|
||
|
||
x_pv_game_stage_env_data::x_pv_game_stage_env_data() {
|
||
|
||
}
|
||
|
||
x_pv_game_stage_env_aet::x_pv_game_stage_env_aet() : state(), prev(), next() {
|
||
duration = 1.0f;
|
||
}
|
||
|
||
x_pv_game_stage_env::x_pv_game_stage_env() : flags(),
|
||
state(), stage_resource(), trans_duration(), trans_remain() {
|
||
env_index = -1;
|
||
aet_gam_stgpv_id_hash = hash_murmurhash_empty;
|
||
spr_gam_stgpv_id_hash = hash_murmurhash_empty;
|
||
aet_gam_stgpv_id_main_hash = hash_murmurhash_empty;
|
||
|
||
for (auto& i : data)
|
||
for (auto& j : i.data)
|
||
for (auto& k : j)
|
||
k.frame_rate_control = &frame_rate_control;
|
||
}
|
||
|
||
x_pv_game_stage_env::~x_pv_game_stage_env() {
|
||
|
||
}
|
||
|
||
void x_pv_game_stage_env::ctrl(float_t delta_time) {
|
||
frame_rate_control.delta_frame = delta_time * 60.0f;
|
||
|
||
switch (state) {
|
||
case 10:
|
||
state = 11;
|
||
case 11:
|
||
if ((aet_gam_stgpv_id_hash == hash_murmurhash_empty
|
||
|| !aet_manager_load_file_modern(aet_gam_stgpv_id_hash, &aet_db))
|
||
&& (spr_gam_stgpv_id_hash == hash_murmurhash_empty
|
||
|| !sprite_manager_load_file_modern(spr_gam_stgpv_id_hash, &spr_db))) {
|
||
spr_set* set = sprite_manager_get_set(spr_gam_stgpv_id_hash, &spr_db);
|
||
if (set) {
|
||
SpriteData* sprdata = set->sprdata;
|
||
for (uint32_t i = set->num_of_sprite; i; i--, sprdata++)
|
||
sprdata->resolution_mode = RESOLUTION_MODE_HD;
|
||
}
|
||
state = 20;
|
||
}
|
||
break;
|
||
case 20:
|
||
if (env_index != -1 && !sub_810EE198(delta_time))
|
||
sub_810EE03E();
|
||
break;
|
||
}
|
||
}
|
||
|
||
pvsr_auth_2d* x_pv_game_stage_env::get_aet(int32_t env_index, int32_t type, int32_t index) {
|
||
if (env_index < 0 || env_index >= stage_resource->stage_effect_env.size())
|
||
return 0;
|
||
|
||
pvsr_stage_effect_env* env = &stage_resource->stage_effect_env[env_index];
|
||
|
||
switch (type) {
|
||
case 0:
|
||
default:
|
||
if (index < env->aet_front.size())
|
||
return &env->aet_front[index];
|
||
break;
|
||
case 1:
|
||
if (index < env->aet_front_low.size())
|
||
return &env->aet_front_low[index];
|
||
break;
|
||
case 2:
|
||
if (index < env->aet_back.size())
|
||
return &env->aet_back[index];
|
||
break;
|
||
case 3:
|
||
if (index < env->unk03.size())
|
||
return &env->unk03[index];
|
||
break;
|
||
case 4:
|
||
if (index < env->unk04.size())
|
||
return &env->unk04[index];
|
||
break;
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
void x_pv_game_stage_env::load(int32_t stage_id, pvsr* stage_resource) {
|
||
if (this->stage_resource || !stage_resource || stage_resource->stage_effect_env.size() > 64)
|
||
return;
|
||
|
||
this->stage_resource = stage_resource;
|
||
|
||
bool aet = false;
|
||
for (pvsr_stage_effect_env& i : stage_resource->stage_effect_env)
|
||
if (i.aet_front.size() || i.aet_front_low.size()
|
||
|| i.aet_back.size() || i.unk03.size() || i.unk04.size()) {
|
||
aet = true;
|
||
break;
|
||
}
|
||
|
||
if (aet) {
|
||
char buf[0x40];
|
||
sprintf_s(buf, sizeof(buf), "AET_GAM_STGPV%03d", stage_id);
|
||
aet_gam_stgpv_id_hash = hash_utf8_murmurhash(buf);
|
||
|
||
sprintf_s(buf, sizeof(buf), "SPR_GAM_STGPV%03d", stage_id);
|
||
spr_gam_stgpv_id_hash = hash_utf8_murmurhash(buf);
|
||
|
||
aet_manager_read_file_modern(aet_gam_stgpv_id_hash, &data_list[DATA_X], &aet_db);
|
||
sprite_manager_read_file_modern(spr_gam_stgpv_id_hash, &data_list[DATA_X], &spr_db);
|
||
|
||
sprintf_s(buf, sizeof(buf), "AET_GAM_STGPV%03d_MAIN", stage_id);
|
||
aet_gam_stgpv_id_main_hash = hash_utf8_murmurhash(buf);
|
||
}
|
||
|
||
state = 10;
|
||
}
|
||
|
||
void x_pv_game_stage_env::reset() {
|
||
flags = 0;
|
||
state = 0;
|
||
stage_resource = 0;
|
||
env_index = -1;
|
||
aet_gam_stgpv_id_hash = hash_murmurhash_empty;
|
||
spr_gam_stgpv_id_hash = hash_murmurhash_empty;
|
||
aet_gam_stgpv_id_main_hash = hash_murmurhash_empty;
|
||
frame_rate_control.delta_frame = 1.0f;
|
||
|
||
aet_db.clear();
|
||
spr_db.clear();
|
||
}
|
||
|
||
void x_pv_game_stage_env::reset_env() {
|
||
if (env_index == -1)
|
||
return;
|
||
|
||
for (auto& i : data[env_index].data)
|
||
for (auto& j : i)
|
||
j.reset();
|
||
|
||
trans_duration = 0.0f;
|
||
trans_remain = 0.0f;
|
||
aet = {};
|
||
env_index = -1;
|
||
}
|
||
|
||
static const float_t env_aet_opacity = 0.65f;
|
||
|
||
#pragma warning(push)
|
||
#pragma warning(disable: 6385)
|
||
void x_pv_game_stage_env::set(int32_t env_index, float_t end_time, float_t start_time) {
|
||
if (!stage_resource || env_index < 0 || env_index >= 64
|
||
|| env_index >= stage_resource->stage_effect_env.size() || this->env_index == env_index)
|
||
return;
|
||
|
||
float_t duration = max_def(end_time - start_time, 0.0f);
|
||
if (trans_duration > 0.0f) {
|
||
if (fabsf(end_time) > 0.000001f)
|
||
return;
|
||
|
||
trans_duration = 0.0f;
|
||
trans_remain = 0.0f;
|
||
aet = {};
|
||
}
|
||
|
||
if (this->env_index == -1 || fabsf(duration) <= 0.000001f) {
|
||
float_t frame = start_time * 60.0f;
|
||
if (this->env_index != -1)
|
||
for (auto& i : data[this->env_index].data)
|
||
for (auto& j : i)
|
||
j.reset();
|
||
|
||
if (!(flags & 0x04))
|
||
for (int32_t type = 0; type < 5; type++)
|
||
for (int32_t index = 0; index < 8; index++) {
|
||
pvsr_auth_2d* aet = get_aet(env_index, type, index);
|
||
if (!aet)
|
||
break;
|
||
|
||
aet_obj_data& aet_obj = data[env_index].data[type][index];
|
||
|
||
AetArgs args;
|
||
args.id.id = aet_gam_stgpv_id_main_hash;
|
||
args.layer_name = aet->name.c_str();
|
||
args.flags = AET_PLAY_ONCE;
|
||
switch (type) {
|
||
case 0:
|
||
args.index = 0;
|
||
args.prio = spr::SPR_PRIO_01;
|
||
break;
|
||
case 1:
|
||
args.index = 0;
|
||
args.prio = spr::SPR_PRIO_00;
|
||
break;
|
||
case 2:
|
||
args.index = 2;
|
||
args.prio = spr::SPR_PRIO_00;
|
||
break;
|
||
case 3:
|
||
args.index = 1;
|
||
args.prio = spr::SPR_PRIO_00;
|
||
break;
|
||
case 4:
|
||
args.index = 1;
|
||
args.prio = spr::SPR_PRIO_01;
|
||
break;
|
||
}
|
||
args.start_marker = 0;
|
||
args.end_marker = 0;
|
||
//args.color = bright_scale_get(aet_index_table[type], aet->bright_scale);
|
||
args.color = vec4(1.0f, 1.0f, 1.0f, env_aet_opacity);
|
||
args.spr_db = &spr_db;
|
||
aet_obj.init(args, &aet_db);
|
||
|
||
if (aet_obj.id)
|
||
aet_manager_set_obj_frame(aet_obj.id, frame);
|
||
}
|
||
}
|
||
else {
|
||
trans_duration = duration;
|
||
trans_remain = duration;
|
||
|
||
bool has_prev = false;
|
||
for (int32_t type = 0; type < 5; type++)
|
||
for (int32_t index = 0; index < 8; index++)
|
||
if (data[this->env_index].data[type][index].id) {
|
||
aet.prev[type][index] = &data[this->env_index].data[type][index];
|
||
has_prev = true;
|
||
}
|
||
else
|
||
break;
|
||
|
||
for (int32_t type = 0; type < 5; type++)
|
||
for (int32_t index = 0; index < 8; index++)
|
||
if (get_aet(env_index, type, index))
|
||
aet.next[type][index] = &data[env_index].data[type][index];
|
||
else
|
||
break;
|
||
|
||
if (has_prev) {
|
||
aet.state = 1;
|
||
aet.duration = duration * 0.5f;
|
||
}
|
||
else {
|
||
aet.state = 2;
|
||
aet.duration = duration;
|
||
}
|
||
}
|
||
|
||
this->env_index = env_index;
|
||
}
|
||
|
||
void x_pv_game_stage_env::unload() {
|
||
if (!state)
|
||
return;
|
||
|
||
if (aet_gam_stgpv_id_hash != hash_murmurhash_empty) {
|
||
aet_manager_unload_set_modern(aet_gam_stgpv_id_hash, &aet_db);
|
||
aet_gam_stgpv_id_hash = hash_murmurhash_empty;
|
||
}
|
||
|
||
if (spr_gam_stgpv_id_hash != hash_murmurhash_empty) {
|
||
sprite_manager_unload_set_modern(spr_gam_stgpv_id_hash, &spr_db);
|
||
spr_gam_stgpv_id_hash = hash_murmurhash_empty;
|
||
}
|
||
|
||
aet_gam_stgpv_id_main_hash = hash_murmurhash_empty;
|
||
|
||
state = 0;
|
||
stage_resource = 0;
|
||
|
||
aet_db.clear();
|
||
spr_db.clear();
|
||
}
|
||
|
||
void x_pv_game_stage_env::sub_810EE03E() {
|
||
if (env_index < 0 || env_index >= 64)
|
||
return;
|
||
|
||
for (int32_t type = 0; type < 5; type++)
|
||
for (int32_t index = 0; index < 8; index++) {
|
||
aet_obj_data& aet_obj = data[env_index].data[type][index];
|
||
if (!aet_obj.id || !aet_obj.check_disp())
|
||
continue;
|
||
|
||
AetArgs args;
|
||
if (stage_resource && env_index >= 0 && env_index < 64) {
|
||
pvsr_auth_2d* aet = get_aet(env_index, type, index);
|
||
if (aet) {
|
||
args.id.id = aet_gam_stgpv_id_main_hash;
|
||
args.layer_name = aet->name.c_str();
|
||
args.flags = AET_PLAY_ONCE;
|
||
switch (type) {
|
||
case 0:
|
||
args.index = 0;
|
||
args.prio = spr::SPR_PRIO_01;
|
||
break;
|
||
case 1:
|
||
args.index = 0;
|
||
args.prio = spr::SPR_PRIO_00;
|
||
break;
|
||
case 2:
|
||
args.index = 2;
|
||
args.prio = spr::SPR_PRIO_00;
|
||
break;
|
||
case 3:
|
||
args.index = 1;
|
||
args.prio = spr::SPR_PRIO_00;
|
||
break;
|
||
case 4:
|
||
args.index = 1;
|
||
args.prio = spr::SPR_PRIO_01;
|
||
break;
|
||
}
|
||
args.start_marker = 0;
|
||
args.end_marker = 0;
|
||
//args.color = bright_scale_get(aet_index_table[type], aet->bright_scale);
|
||
args.color = vec4(1.0f, 1.0f, 1.0f, env_aet_opacity);
|
||
}
|
||
}
|
||
args.spr_db = &spr_db;
|
||
aet_obj.init(args, &aet_db);
|
||
}
|
||
}
|
||
|
||
bool x_pv_game_stage_env::sub_810EE198(float_t delta_time) {
|
||
if (trans_remain <= 0.0f)
|
||
return false;
|
||
|
||
trans_remain = max_def(trans_remain - delta_time, 0.0f);
|
||
|
||
float_t t = 1.0f - trans_remain / trans_duration;
|
||
switch (aet.state) {
|
||
case 1: {
|
||
float_t alpha = 1.0f - t * 2.0f;
|
||
if (alpha > 0.0f) {
|
||
for (int32_t type = 0; type < 5; type++)
|
||
for (int32_t index = 0; index < 8; index++) {
|
||
aet_obj_data* aet_obj = aet.prev[type][index];
|
||
if (!aet_obj)
|
||
break;
|
||
|
||
aet_manager_set_obj_alpha(aet_obj->id, alpha * env_aet_opacity);
|
||
}
|
||
break;
|
||
}
|
||
|
||
for (int32_t type = 0; type < 5; type++)
|
||
for (int32_t index = 0; index < 8; index++) {
|
||
aet_obj_data* aet_obj = aet.prev[type][index];
|
||
if (!aet_obj)
|
||
break;
|
||
|
||
aet_obj->reset();
|
||
}
|
||
|
||
aet.state = 2;
|
||
}
|
||
case 2: {
|
||
for (int32_t type = 0; type < 5; type++)
|
||
for (int32_t index = 0; index < 8; index++) {
|
||
aet_obj_data* aet_obj = aet.next[type][index];
|
||
if (!aet_obj)
|
||
break;
|
||
|
||
AetArgs args;
|
||
if (stage_resource && env_index >= 0 && env_index < 64) {
|
||
pvsr_auth_2d* aet = get_aet(env_index, type, index);
|
||
if (aet) {
|
||
args.id.id = aet_gam_stgpv_id_main_hash;
|
||
args.layer_name = aet->name.c_str();
|
||
args.flags = AET_PLAY_ONCE;
|
||
switch (type) {
|
||
case 0:
|
||
args.index = 0;
|
||
args.prio = spr::SPR_PRIO_01;
|
||
break;
|
||
case 1:
|
||
args.index = 0;
|
||
args.prio = spr::SPR_PRIO_00;
|
||
break;
|
||
case 2:
|
||
args.index = 2;
|
||
args.prio = spr::SPR_PRIO_00;
|
||
break;
|
||
case 3:
|
||
args.index = 1;
|
||
args.prio = spr::SPR_PRIO_00;
|
||
break;
|
||
case 4:
|
||
args.index = 1;
|
||
args.prio = spr::SPR_PRIO_01;
|
||
break;
|
||
}
|
||
args.start_marker = 0;
|
||
args.end_marker = 0;
|
||
//args.color = bright_scale_get(aet_index_table[type], aet->bright_scale);
|
||
args.color = vec4(1.0f, 1.0f, 1.0f, env_aet_opacity);
|
||
}
|
||
}
|
||
args.spr_db = &spr_db;
|
||
aet_obj->init(args, &aet_db);
|
||
|
||
aet_manager_set_obj_alpha(aet_obj->id, 0.0f);
|
||
}
|
||
|
||
aet.state = 3;
|
||
} break;
|
||
case 3: {
|
||
float_t alpha = 1.0f - trans_remain / aet.duration;
|
||
for (int32_t type = 0; type < 5; type++)
|
||
for (int32_t index = 0; index < 8; index++) {
|
||
aet_obj_data* aet_obj = aet.next[type][index];
|
||
if (!aet_obj)
|
||
break;
|
||
|
||
aet_manager_set_obj_alpha(aet_obj->id, alpha * env_aet_opacity);
|
||
}
|
||
} break;
|
||
}
|
||
|
||
if (trans_remain <= 0.0f) {
|
||
trans_duration = 0.0f;
|
||
trans_remain = 0.0f;
|
||
aet = {};
|
||
}
|
||
return false;
|
||
}
|
||
#pragma warning(pop)
|
||
|
||
x_pv_game_stage_effect_auth_3d::x_pv_game_stage_effect_auth_3d() : repeat(), field_1(), id() {
|
||
reset();
|
||
}
|
||
|
||
void x_pv_game_stage_effect_auth_3d::reset() {
|
||
repeat = false;
|
||
field_1 = true;
|
||
id = {};
|
||
}
|
||
|
||
x_pv_game_stage_effect_glitter::x_pv_game_stage_effect_glitter() :
|
||
scene_counter(), fade_time(), fade_time_left(), force_disp() {
|
||
reset();
|
||
}
|
||
|
||
void x_pv_game_stage_effect_glitter::reset() {
|
||
name.clear();
|
||
scene_counter = 0;
|
||
fade_time = 0.0f;
|
||
fade_time_left = 0.0f;
|
||
force_disp = false;
|
||
}
|
||
|
||
x_pv_game_stage_change_effect::x_pv_game_stage_change_effect() : enable(), bars_left(), bar_count() {
|
||
|
||
}
|
||
|
||
x_pv_game_stage_change_effect::~x_pv_game_stage_change_effect() {
|
||
|
||
}
|
||
|
||
void x_pv_game_stage_change_effect::reset() {
|
||
enable = false;
|
||
auth_3d.clear();
|
||
auth_3d.shrink_to_fit();
|
||
glitter.clear();
|
||
glitter.shrink_to_fit();
|
||
bars_left = 0;
|
||
bar_count = 0;
|
||
}
|
||
|
||
x_pv_game_stage_effect::x_pv_game_stage_effect() : stage_effect(), set() {
|
||
main_auth_3d_index = -1;
|
||
}
|
||
|
||
x_pv_game_stage_effect::~x_pv_game_stage_effect() {
|
||
|
||
}
|
||
|
||
void x_pv_game_stage_effect::reset() {
|
||
stage_effect = 0;
|
||
auth_3d.clear();
|
||
auth_3d.shrink_to_fit();
|
||
glitter.clear();
|
||
glitter.shrink_to_fit();
|
||
main_auth_3d_index = -1;
|
||
set = false;
|
||
}
|
||
|
||
x_pv_game_stage_data::x_pv_game_stage_data() : flags(), state(), frame_rate_control() {
|
||
reset();
|
||
}
|
||
|
||
x_pv_game_stage_data::~x_pv_game_stage_data() {
|
||
|
||
}
|
||
|
||
bool x_pv_game_stage_data::check_not_loaded() {
|
||
return file_handler.check_not_ready() || (state && state != 2);
|
||
}
|
||
|
||
void x_pv_game_stage_data::ctrl(object_database* obj_db, texture_database* tex_db) {
|
||
switch (state) {
|
||
case 1: {
|
||
if (task_stage_modern_check_not_loaded())
|
||
break;
|
||
|
||
bool wait_load = false;
|
||
|
||
for (uint32_t& i : objhrc_hash)
|
||
if (object_storage_get_objset_info(i)
|
||
&& object_storage_load_obj_set_check_not_read(i, obj_db, tex_db))
|
||
wait_load |= true;
|
||
|
||
if (wait_load)
|
||
break;
|
||
|
||
state = 2;
|
||
} break;
|
||
}
|
||
}
|
||
|
||
void x_pv_game_stage_data::load(int32_t stage_id, FrameRateControl* frame_rate_control) {
|
||
if (flags & 0x02)
|
||
return;
|
||
|
||
this->frame_rate_control = frame_rate_control;
|
||
|
||
char buf[0x200];
|
||
sprintf_s(buf, sizeof(buf), "pv_stgpv%03d.stg", stage_id);
|
||
file_handler.read_file(&data_list[DATA_X], "root+/stage/", buf);
|
||
|
||
task_stage_modern_load_task("X_PV_STAGE");
|
||
|
||
size_t len = sprintf_s(buf, sizeof(buf), "STGPV%03d.stg", stage_id);
|
||
obj_hash.push_back(hash_murmurhash(buf, len));
|
||
|
||
flags |= 0x02;
|
||
}
|
||
|
||
#if BAKE_X_PACK
|
||
void x_pv_game_stage_data::load_objects(int32_t stage_id, object_database* obj_db, texture_database* tex_db) {
|
||
#else
|
||
void x_pv_game_stage_data::load_objects(object_database* obj_db, texture_database* tex_db) {
|
||
#endif
|
||
if (!(flags & 0x02) || file_handler.check_not_ready() || state && state != 2)
|
||
return;
|
||
|
||
const void* stg_data = file_handler.get_data();
|
||
size_t stg_size = file_handler.get_size();
|
||
|
||
stage_database_file stage_data_file;
|
||
stage_data_file.read(stg_data, stg_size, true);
|
||
stg_db.add(&stage_data_file);
|
||
|
||
std::vector<stage_data_modern*> stage_data;
|
||
|
||
obj_hash.clear();
|
||
objhrc_hash.clear();
|
||
for (stage_data_modern& i : stg_db.stage_modern) {
|
||
stage_data.push_back(&i);
|
||
|
||
std::string objhrc(i.name);
|
||
objhrc.append("HRC");
|
||
obj_hash.push_back(i.hash);
|
||
#if BAKE_X_PACK
|
||
if (stage_id != 29)
|
||
objhrc_hash.push_back(hash_string_murmurhash(objhrc));
|
||
#else
|
||
objhrc_hash.push_back(hash_string_murmurhash(objhrc));
|
||
#endif
|
||
}
|
||
|
||
data_struct* x_data = &data_list[DATA_X];
|
||
|
||
task_stage_modern_set_data(x_data, obj_db, tex_db, &stg_db);
|
||
task_stage_modern_set_stage_hashes(obj_hash, stage_data);
|
||
effect_manager_set_data(x_data, obj_db, tex_db, &stg_db);
|
||
|
||
for (uint32_t& i : objhrc_hash)
|
||
object_storage_load_set_hash(x_data, i);
|
||
|
||
state = 1;
|
||
flags |= 0x01;
|
||
}
|
||
|
||
void x_pv_game_stage_data::reset() {
|
||
flags = 0x04;
|
||
state = 0;
|
||
file_handler.reset();
|
||
stg_db.clear();
|
||
frame_rate_control = 0;
|
||
obj_hash.clear();
|
||
obj_hash.shrink_to_fit();
|
||
stage_info.clear();
|
||
stage_info.shrink_to_fit();
|
||
objhrc_hash.clear();
|
||
objhrc_hash.shrink_to_fit();
|
||
}
|
||
|
||
void x_pv_game_stage_data::set_default_stage() {
|
||
if (!(flags & 0x02) || state && state != 2)
|
||
return;
|
||
|
||
set_stage(hash_utf8_murmurhash("STGAETBACK"));
|
||
}
|
||
|
||
void x_pv_game_stage_data::set_stage(uint32_t hash) {
|
||
if (!(flags & 0x02) || state && state != 2)
|
||
return;
|
||
|
||
if (flags & 0x01) {
|
||
task_stage_modern_get_loaded_stage_infos(stage_info);
|
||
flags &= ~0x01;
|
||
}
|
||
|
||
task_stage_modern_info stg_info;
|
||
for (task_stage_modern_info& i : stage_info)
|
||
if (i.check() && i.get_stage_hash() == hash) {
|
||
stg_info = i;
|
||
break;
|
||
}
|
||
|
||
stg_info.set_stage();
|
||
#if BAKE_VIDEO_ALPHA
|
||
task_stage_modern_current_set_ground(false);
|
||
task_stage_modern_current_set_sky(false);
|
||
task_stage_modern_current_set_stage_display(false, false);
|
||
#else
|
||
if (stg_info.check())
|
||
stg_info.set_stage_display(!!(flags & 0x04), true);
|
||
else
|
||
task_stage_modern_current_set_stage_display(false, true);
|
||
#endif
|
||
}
|
||
|
||
void x_pv_game_stage_data::unload() {
|
||
for (uint32_t& i : objhrc_hash)
|
||
object_storage_unload_set(i);
|
||
|
||
task_stage_modern_unload_task();
|
||
|
||
flags &= ~0x02;
|
||
state = 0;
|
||
file_handler.reset();
|
||
frame_rate_control = 0;
|
||
obj_hash.clear();
|
||
obj_hash.shrink_to_fit();
|
||
stage_info.clear();
|
||
stage_info.shrink_to_fit();
|
||
objhrc_hash.clear();
|
||
objhrc_hash.shrink_to_fit();
|
||
}
|
||
|
||
x_pv_game_stage::x_pv_game_stage() : flags(), stage_id(), field_8(), state(), stage_resource(),
|
||
curr_stage_effect(), next_stage_effect(), stage_effect_transition_state() {
|
||
reset();
|
||
}
|
||
|
||
x_pv_game_stage::~x_pv_game_stage() {
|
||
if (stage_resource) {
|
||
delete stage_resource;
|
||
stage_resource = 0;
|
||
}
|
||
}
|
||
|
||
bool x_pv_game_stage::check_stage_effect_has_change_effect(int32_t curr_stage_effect, int32_t next_stage_effect) {
|
||
if (curr_stage_effect == 7)
|
||
return false;
|
||
|
||
curr_stage_effect--;
|
||
next_stage_effect--;
|
||
|
||
if (curr_stage_effect < 0 || next_stage_effect < 0)
|
||
return false;
|
||
|
||
size_t stage_effect_count = stage_resource->stage_effect.size();
|
||
if (curr_stage_effect >= stage_effect_count || next_stage_effect >= stage_effect_count)
|
||
return false;
|
||
|
||
pvsr_stage_change_effect& stg_chg_eff = stage_resource->
|
||
stage_change_effect[curr_stage_effect][next_stage_effect];
|
||
if (stg_chg_eff.enable)
|
||
return true;
|
||
return false;
|
||
}
|
||
|
||
void x_pv_game_stage::ctrl(float_t delta_time) {
|
||
switch (state) {
|
||
case 10: {
|
||
if (stage_data.check_not_loaded() || stage_resource_file_handler.check_not_ready())
|
||
break;
|
||
|
||
#if BAKE_X_PACK
|
||
if (stage_data.flags & 0x02)
|
||
stage_data.load_objects(stage_id, &obj_db, &tex_db);
|
||
#else
|
||
if (stage_data.flags & 0x02)
|
||
stage_data.load_objects(&obj_db, &tex_db);
|
||
#endif
|
||
|
||
const void* pvsr_data = stage_resource_file_handler.get_data();
|
||
size_t pvsr_size = stage_resource_file_handler.get_size();
|
||
|
||
pvsr* sr = new pvsr;
|
||
sr->read(pvsr_data, pvsr_size);
|
||
stage_resource = sr;
|
||
|
||
if (sr->stage_effect.size() > 12)
|
||
break;
|
||
|
||
bool has_auth_3d = false;
|
||
for (pvsr_stage_effect& i : sr->stage_effect)
|
||
if (i.auth_3d.size()) {
|
||
has_auth_3d = true;
|
||
break;
|
||
}
|
||
|
||
if (has_auth_3d) {
|
||
char buf[0x200];
|
||
size_t len = sprintf_s(buf, sizeof(buf), "EFFSTGPV%03d", stage_id);
|
||
stage_auth_3d.push_back(std::string(buf, len));
|
||
}
|
||
|
||
data_struct* x_data = &data_list[DATA_X];
|
||
|
||
for (pvsr_effect& i : sr->effect) {
|
||
uint32_t hash = (uint32_t)Glitter::glt_particle_manager->LoadFile(Glitter::X,
|
||
x_data, i.name.c_str(), 0, i.emission, true, &obj_db, &tex_db);
|
||
if (hash != hash_murmurhash_empty)
|
||
stage_glitter.push_back(hash);
|
||
}
|
||
|
||
for (string_hash& i : stage_auth_3d)
|
||
auth_3d_data_load_category(x_data, i.c_str(), i.hash_murmurhash);
|
||
|
||
env.load(stage_id, stage_resource);
|
||
state = 11;
|
||
} break;
|
||
case 11: {
|
||
if (stage_data.check_not_loaded())
|
||
break;
|
||
|
||
bool wait_load = false;
|
||
|
||
for (string_hash& i : stage_auth_3d)
|
||
if (!auth_3d_data_check_category_loaded(i.hash_murmurhash))
|
||
wait_load |= true;
|
||
|
||
for (uint32_t& i : stage_glitter)
|
||
if (!Glitter::glt_particle_manager->CheckNoFileReaders(i))
|
||
wait_load |= true;
|
||
|
||
if (wait_load)
|
||
break;
|
||
|
||
data_struct* x_data = &data_list[DATA_X];
|
||
|
||
for (pvsr_effect& i : stage_resource->effect)
|
||
Glitter::glt_particle_manager->SetSceneName(i.name.hash_murmurhash, i.name.c_str());
|
||
|
||
size_t stage_effect_count = stage_resource->stage_effect.size();
|
||
|
||
for (int32_t i = 0; i < X_PV_GAME_STAGE_EFFECT_COUNT && i < stage_effect_count; i++) {
|
||
pvsr_stage_effect& stg_eff = stage_resource->stage_effect[i];
|
||
x_pv_game_stage_effect& eff = effect[i];
|
||
|
||
eff.stage_effect = &stg_eff;
|
||
|
||
size_t auth_3d_count = stg_eff.auth_3d.size();
|
||
size_t glitter_count = stg_eff.glitter.size();
|
||
|
||
eff.auth_3d.resize(auth_3d_count);
|
||
eff.glitter.resize(glitter_count);
|
||
|
||
for (size_t j = 0; j < auth_3d_count; j++) {
|
||
pvsr_auth_3d& stg_eff_auth_3d = stg_eff.auth_3d[j];
|
||
x_pv_game_stage_effect_auth_3d& eff_auth_3d = eff.auth_3d[j];
|
||
|
||
eff_auth_3d.reset();
|
||
|
||
int32_t stage_effect = i + 1;
|
||
|
||
auto elem = auth_3d_ids.find(stg_eff_auth_3d.name.hash_murmurhash);
|
||
if (elem == auth_3d_ids.end()) {
|
||
auth_3d_id id = auth_3d_id(stg_eff_auth_3d
|
||
.name.hash_murmurhash, x_data, &obj_db, &tex_db);
|
||
if (!id.check_not_empty()) {
|
||
eff_auth_3d.id = {};
|
||
continue;
|
||
}
|
||
|
||
id.read_file_modern();
|
||
id.set_enable(false);
|
||
id.set_repeat(true);
|
||
id.set_paused(false);
|
||
id.set_visibility(false);
|
||
id.set_frame_rate(&bpm_frame_rate_control);
|
||
eff_auth_3d.id = id;
|
||
|
||
auth_3d_ids.insert({ stg_eff_auth_3d.name.hash_murmurhash, id });
|
||
}
|
||
else
|
||
eff_auth_3d.id = elem->second;
|
||
|
||
if (stage_effect >= 8 && stage_effect <= 9)
|
||
eff_auth_3d.repeat = false;
|
||
else if (stage_effect == 7)
|
||
eff_auth_3d.repeat = !!(stg_eff_auth_3d.flags & PVSR_AUTH_3D_REPEAT);
|
||
else
|
||
eff_auth_3d.repeat = true;
|
||
|
||
if (stg_eff_auth_3d.flags & PVSR_AUTH_3D_MAIN)
|
||
eff.main_auth_3d_index = (int32_t)j;
|
||
}
|
||
|
||
for (size_t i = 0; i < glitter_count; i++) {
|
||
pvsr_glitter& stg_eff_glt = stg_eff.glitter[i];
|
||
x_pv_game_stage_effect_glitter& eff_glt = eff.glitter[i];
|
||
|
||
eff_glt.reset();
|
||
eff_glt.name.assign(stg_eff_glt.name);
|
||
eff_glt.fade_time = (float_t)stg_eff_glt.fade_time;
|
||
eff_glt.force_disp = !!(stg_eff_glt.flags & PVSR_GLITTER_FORCE_DISP);
|
||
}
|
||
}
|
||
|
||
for (int32_t i = 1; i <= X_PV_GAME_STAGE_EFFECT_COUNT; i++)
|
||
for (int32_t j = 1; j <= X_PV_GAME_STAGE_EFFECT_COUNT; j++)
|
||
load_change_effect(i, j);
|
||
|
||
stage_data.set_default_stage();
|
||
state = 12;
|
||
}
|
||
case 12: {
|
||
if (env.state && env.state != 20)
|
||
break;
|
||
|
||
bool wait_load = false;
|
||
for (int32_t i = 0; i < X_PV_GAME_STAGE_EFFECT_COUNT; i++) {
|
||
x_pv_game_stage_effect& eff = effect[i];
|
||
for (x_pv_game_stage_effect_auth_3d& j : eff.auth_3d)
|
||
if (j.id.check_not_empty() && !j.id.check_loaded())
|
||
wait_load |= true;
|
||
}
|
||
|
||
for (int32_t i = 0; i < X_PV_GAME_STAGE_EFFECT_COUNT; i++)
|
||
for (int32_t j = 0; j < X_PV_GAME_STAGE_EFFECT_COUNT; j++) {
|
||
x_pv_game_stage_change_effect& chg_eff = change_effect[i][j];
|
||
for (x_pv_game_stage_effect_auth_3d& k : chg_eff.auth_3d)
|
||
if (k.id.check_not_empty() && !k.id.check_loaded())
|
||
wait_load |= true;
|
||
}
|
||
|
||
if (wait_load)
|
||
break;
|
||
|
||
state = 20;
|
||
}
|
||
case 20:
|
||
ctrl_inner();
|
||
break;
|
||
case 30:
|
||
if (!task_stage_modern_check_task_ready()) {
|
||
stage_data.stg_db.clear();
|
||
state = 0;
|
||
}
|
||
break;
|
||
}
|
||
|
||
stage_data.ctrl(&obj_db, &tex_db);
|
||
env.ctrl(delta_time);
|
||
}
|
||
|
||
void x_pv_game_stage::ctrl_inner() {
|
||
if (next_stage_effect && curr_stage_effect) {
|
||
x_pv_bar_beat* bar_beat = bpm_frame_rate_control.bar_beat;
|
||
if (!bar_beat)
|
||
return;
|
||
|
||
bool change_stage_effect = bar_beat && fabsf(bar_beat->delta_time) > 0.000001f
|
||
&& bar_beat->counter > 0 && !((bar_beat->bar - 1) % 2);
|
||
|
||
int32_t curr_stg_eff = curr_stage_effect;
|
||
if (curr_stg_eff >= 1 && curr_stg_eff <= 12)
|
||
curr_stg_eff--;
|
||
else
|
||
curr_stg_eff = 0;
|
||
|
||
int32_t next_stg_eff = next_stage_effect;
|
||
if (next_stg_eff >= 1 && next_stg_eff <= 12)
|
||
next_stg_eff--;
|
||
else
|
||
next_stg_eff = 0;
|
||
|
||
x_pv_game_stage_effect& eff = effect[curr_stg_eff];
|
||
x_pv_game_stage_change_effect& chg_eff = change_effect[curr_stg_eff][next_stg_eff];
|
||
|
||
switch (stage_effect_transition_state) {
|
||
case 0: {
|
||
if (change_stage_effect) {
|
||
if (set_change_effect_frame_part_1()) {
|
||
chg_eff.bars_left = chg_eff.bar_count;
|
||
stage_effect_transition_state = 1;
|
||
stop_stage_effect_auth_3d(curr_stage_effect);
|
||
|
||
set_change_effect_frame_part_2(bar_beat->get_bar_current_frame());
|
||
}
|
||
else {
|
||
stop_stage_effect_auth_3d(curr_stage_effect);
|
||
stop_stage_effect_glitter(curr_stage_effect);
|
||
|
||
set_stage_effect_auth_3d_frame(next_stage_effect, -1.0f);
|
||
#if !BAKE_VIDEO_ALPHA
|
||
set_stage_effect_glitter_frame(next_stage_effect, -1.0f);
|
||
#endif
|
||
curr_stage_effect = next_stage_effect;
|
||
next_stage_effect = 0;
|
||
stage_effect_transition_state = 0;
|
||
}
|
||
}
|
||
else if (bar_beat->counter > 0) {
|
||
std::vector<x_pv_game_stage_effect_auth_3d>& auth_3d = eff.auth_3d;
|
||
for (x_pv_game_stage_effect_auth_3d& i : auth_3d) {
|
||
auth_3d_id& id = i.id;
|
||
if (i.field_1)
|
||
id.set_repeat(false);
|
||
}
|
||
}
|
||
} break;
|
||
case 1: {
|
||
if (change_stage_effect) {
|
||
chg_eff.bars_left -= 2;
|
||
change_stage_effect = chg_eff.bars_left <= 0;
|
||
}
|
||
|
||
if (change_stage_effect) {
|
||
stop_stage_change_effect();
|
||
stop_stage_effect_glitter(curr_stage_effect);
|
||
|
||
set_stage_effect_auth_3d_frame(next_stage_effect, -1.0f);
|
||
#if !BAKE_VIDEO_ALPHA
|
||
set_stage_effect_glitter_frame(next_stage_effect, -1.0f);
|
||
#endif
|
||
curr_stage_effect = next_stage_effect;
|
||
next_stage_effect = 0;
|
||
stage_effect_transition_state = 0;
|
||
}
|
||
else {
|
||
float_t delta_time_bar_beat = bar_beat->delta_time / (bar_beat->next_bar_time - bar_beat->curr_bar_time);
|
||
|
||
std::vector<x_pv_game_stage_effect_glitter>& glitter = eff.glitter;
|
||
for (x_pv_game_stage_effect_glitter& i : glitter) {
|
||
if (fabsf(i.fade_time) <= 0.000001f)
|
||
Glitter::glt_particle_manager->SetSceneEffectExtColor(i.scene_counter, 0,
|
||
hash_murmurhash_empty, -1.0f, -1.0f, -1.0f, 0.0f);
|
||
else if (i.fade_time > 0.001f) {
|
||
i.fade_time_left -= delta_time_bar_beat * 4.0f;
|
||
if (i.fade_time_left < 0.0f)
|
||
i.fade_time_left = 0.0f;
|
||
Glitter::glt_particle_manager->SetSceneEffectExtColor(i.scene_counter, 0,
|
||
hash_murmurhash_empty, -1.0f, -1.0f, -1.0f, i.fade_time_left / i.fade_time);
|
||
}
|
||
}
|
||
}
|
||
} break;
|
||
}
|
||
}
|
||
else if (next_stage_effect)
|
||
return;
|
||
|
||
for (int32_t i = 8; i <= 9; i++) {
|
||
if (!(flags & (1 << i)))
|
||
continue;
|
||
|
||
int32_t stage_effect;
|
||
if (i > 0)
|
||
stage_effect = i - 1;
|
||
else
|
||
stage_effect = 0;
|
||
|
||
x_pv_game_stage_effect& eff = effect[stage_effect];
|
||
std::vector<x_pv_game_stage_effect_auth_3d>& auth_3d = eff.auth_3d;
|
||
std::vector<x_pv_game_stage_effect_glitter>& glitter = eff.glitter;
|
||
|
||
bool stop = false;
|
||
if (auth_3d.size())
|
||
stop = auth_3d[eff.main_auth_3d_index].id.get_ended();
|
||
|
||
if (!stop) {
|
||
for (x_pv_game_stage_effect_glitter& j : glitter)
|
||
if (Glitter::glt_particle_manager->CheckSceneEnded(j.scene_counter)) {
|
||
stop = true;
|
||
break;
|
||
}
|
||
}
|
||
|
||
if (stop) {
|
||
stop_stage_effect_auth_3d(i);
|
||
stop_stage_effect_glitter(i);
|
||
flags &= ~(1 << i);
|
||
}
|
||
}
|
||
}
|
||
|
||
void x_pv_game_stage::load(int32_t stage_id, FrameRateControl* frame_rate_control, bool a4) {
|
||
if (!stage_id)
|
||
return;
|
||
|
||
flags &= ~0x02;
|
||
if (a4)
|
||
flags |= 0x02;
|
||
|
||
field_8 = 1;
|
||
this->stage_id = stage_id;
|
||
|
||
stage_data.load(stage_id, frame_rate_control);
|
||
|
||
char buf[0x200];
|
||
sprintf_s(buf, sizeof(buf), "stgpv%03d_param.pvsr", stage_id);
|
||
stage_resource_file_handler.read_file(&data_list[DATA_X], "root+/pv_stage_rsrc/", buf);
|
||
state = 10;
|
||
}
|
||
|
||
void x_pv_game_stage::load_change_effect(int32_t curr_stage_effect, int32_t next_stage_effect) {
|
||
curr_stage_effect--;
|
||
next_stage_effect--;
|
||
|
||
if (curr_stage_effect < 0 || next_stage_effect < 0)
|
||
return;
|
||
|
||
size_t stage_effect_count = stage_resource->stage_effect.size();
|
||
if (curr_stage_effect >= stage_effect_count || next_stage_effect >= stage_effect_count)
|
||
return;
|
||
|
||
pvsr_stage_change_effect& stg_chg_eff = stage_resource->
|
||
stage_change_effect[curr_stage_effect][next_stage_effect];
|
||
x_pv_game_stage_change_effect& chg_eff = change_effect[curr_stage_effect][next_stage_effect];
|
||
|
||
if (!stg_chg_eff.enable) {
|
||
chg_eff.enable = false;
|
||
return;
|
||
}
|
||
|
||
chg_eff.enable = true;
|
||
chg_eff.bars_left = 0;
|
||
chg_eff.bar_count = stg_chg_eff.bar_count > -1 ? stg_chg_eff.bar_count : 2;
|
||
|
||
size_t auth_3d_count = stg_chg_eff.auth_3d.size();
|
||
size_t glitter_count = stg_chg_eff.glitter.size();
|
||
|
||
chg_eff.auth_3d.resize(auth_3d_count);
|
||
chg_eff.glitter.resize(glitter_count);
|
||
|
||
data_struct* x_data = &data_list[DATA_X];
|
||
|
||
for (size_t i = 0; i < auth_3d_count; i++) {
|
||
pvsr_auth_3d& stg_chg_eff_auth_3d = stg_chg_eff.auth_3d[i];
|
||
x_pv_game_stage_effect_auth_3d& chg_eff_auth_3d = chg_eff.auth_3d[i];
|
||
|
||
chg_eff_auth_3d.reset();
|
||
|
||
auto elem = auth_3d_ids.find(stg_chg_eff_auth_3d.name.hash_murmurhash);
|
||
if (elem == auth_3d_ids.end()) {
|
||
auth_3d_id id = auth_3d_id(stg_chg_eff_auth_3d
|
||
.name.hash_murmurhash, x_data, &obj_db, &tex_db);
|
||
if (!id.check_not_empty()) {
|
||
chg_eff_auth_3d.id = {};
|
||
continue;
|
||
}
|
||
|
||
id.read_file_modern();
|
||
id.set_enable(false);
|
||
id.set_repeat(false);
|
||
id.set_paused(false);
|
||
id.set_visibility(false);
|
||
id.set_frame_rate(&bpm_frame_rate_control);
|
||
chg_eff_auth_3d.id = id;
|
||
|
||
auth_3d_ids.insert({ stg_chg_eff_auth_3d.name.hash_murmurhash, id });
|
||
}
|
||
else
|
||
chg_eff_auth_3d.id = elem->second;
|
||
|
||
chg_eff_auth_3d.field_1 = true;
|
||
chg_eff_auth_3d.repeat = !!(stg_chg_eff_auth_3d.flags & PVSR_AUTH_3D_REPEAT);
|
||
}
|
||
|
||
for (size_t i = 0; i < glitter_count; i++) {
|
||
pvsr_glitter& stg_chg_eff_glt = stg_chg_eff.glitter[i];
|
||
x_pv_game_stage_effect_glitter& chg_eff_glt = chg_eff.glitter[i];
|
||
|
||
chg_eff_glt.reset();
|
||
chg_eff_glt.name.assign(stg_chg_eff_glt.name);
|
||
chg_eff_glt.force_disp = !!(stg_chg_eff_glt.flags & PVSR_GLITTER_FORCE_DISP);
|
||
}
|
||
}
|
||
|
||
void x_pv_game_stage::reset() {
|
||
flags = 0x01;
|
||
stage_id = 0;
|
||
field_8 = 0;
|
||
state = 0;
|
||
stage_resource_file_handler.reset();
|
||
if (stage_resource) {
|
||
delete stage_resource;
|
||
stage_resource = 0;
|
||
}
|
||
bpm_frame_rate_control.reset();
|
||
stage_auth_3d.clear();
|
||
stage_auth_3d.shrink_to_fit();
|
||
stage_glitter.clear();
|
||
stage_glitter.shrink_to_fit();
|
||
curr_stage_effect = 0;
|
||
next_stage_effect = 0;
|
||
stage_effect_transition_state = 0;
|
||
|
||
for (int32_t i = 0; i < X_PV_GAME_STAGE_EFFECT_COUNT; i++)
|
||
effect[i].reset();
|
||
|
||
for (int32_t i = 0; i < X_PV_GAME_STAGE_EFFECT_COUNT; i++)
|
||
for (int32_t j = 0; j < X_PV_GAME_STAGE_EFFECT_COUNT; j++)
|
||
change_effect[i][j].reset();
|
||
|
||
obj_db.clear();
|
||
tex_db.clear();
|
||
auth_3d_ids.clear();
|
||
}
|
||
|
||
void x_pv_game_stage::reset_stage_effect() {
|
||
stop_stage_effect(true);
|
||
|
||
for (int32_t i = 8; i <= 9; i++) {
|
||
if (!(flags & (1 << i)))
|
||
continue;
|
||
|
||
stop_stage_effect_auth_3d(i);
|
||
stop_stage_effect_glitter(i);
|
||
}
|
||
|
||
for (uint32_t& i : stage_glitter)
|
||
Glitter::glt_particle_manager->FreeScene(i);
|
||
}
|
||
|
||
void x_pv_game_stage::reset_stage_env() {
|
||
env.reset_env();
|
||
}
|
||
|
||
bool x_pv_game_stage::set_change_effect_frame_part_1() {
|
||
if (!curr_stage_effect || !next_stage_effect)
|
||
return false;
|
||
|
||
int32_t curr_stg_eff = curr_stage_effect;
|
||
if (curr_stg_eff >= 1 && curr_stg_eff <= 12)
|
||
curr_stg_eff--;
|
||
else
|
||
curr_stg_eff = 0;
|
||
|
||
int32_t next_sta_eff = next_stage_effect;
|
||
if (next_sta_eff >= 1 && next_sta_eff <= 12)
|
||
next_sta_eff--;
|
||
else
|
||
next_sta_eff = 0;
|
||
|
||
x_pv_game_stage_change_effect& chg_eff = change_effect[curr_stg_eff][next_sta_eff];
|
||
if (!chg_eff.enable)
|
||
return false;
|
||
return true;
|
||
}
|
||
|
||
void x_pv_game_stage::set_change_effect_frame_part_2(float_t frame) {
|
||
if (!curr_stage_effect || !next_stage_effect)
|
||
return;
|
||
|
||
int32_t curr_stg_eff = curr_stage_effect;
|
||
if (curr_stg_eff >= 1 && curr_stg_eff <= 12)
|
||
curr_stg_eff--;
|
||
else
|
||
curr_stg_eff = 0;
|
||
|
||
int32_t next_sta_eff = next_stage_effect;
|
||
if (next_sta_eff >= 1 && next_sta_eff <= 12)
|
||
next_sta_eff--;
|
||
else
|
||
next_sta_eff = 0;
|
||
|
||
x_pv_game_stage_change_effect& chg_eff = change_effect[curr_stg_eff][next_sta_eff];
|
||
if (!chg_eff.enable)
|
||
return;
|
||
|
||
for (x_pv_game_stage_effect_auth_3d& i : chg_eff.auth_3d) {
|
||
auth_3d_id& id = i.id;
|
||
id.set_camera_root_update(false);
|
||
#if BAKE_VIDEO_ALPHA
|
||
id.set_enable(false);
|
||
#else
|
||
id.set_enable(true);
|
||
#endif
|
||
id.set_repeat(i.repeat);
|
||
id.set_req_frame(frame);
|
||
id.set_max_frame(id.get_last_frame() - 1.0f);
|
||
id.set_paused(false);
|
||
id.set_visibility(!!(flags & 0x01));
|
||
id.set_frame_rate(&bpm_frame_rate_control);
|
||
}
|
||
|
||
#if !BAKE_VIDEO_ALPHA
|
||
for (x_pv_game_stage_effect_glitter& i : chg_eff.glitter) {
|
||
if (i.name.hash_murmurhash == hash_murmurhash_empty)
|
||
continue;
|
||
|
||
i.scene_counter = Glitter::glt_particle_manager->LoadSceneEffect(
|
||
i.name.hash_murmurhash, i.name.c_str(), true, 0x01);
|
||
if (!i.scene_counter)
|
||
continue;
|
||
|
||
Glitter::glt_particle_manager->SetSceneFrameRate(i.scene_counter, &bpm_frame_rate_control);
|
||
Glitter::glt_particle_manager->SetSceneEffectReqFrame(i.scene_counter, frame);
|
||
}
|
||
#endif
|
||
}
|
||
|
||
void x_pv_game_stage::set_env(int32_t env_index, float_t end_time, float_t start_time) {
|
||
env.set(env_index, end_time, start_time);
|
||
}
|
||
|
||
void x_pv_game_stage::set_stage_effect(int32_t stage_effect) {
|
||
if (stage_effect < 1 || stage_effect > 12)
|
||
return;
|
||
|
||
if (stage_effect >= 8 && stage_effect <= 9) {
|
||
if (flags & (1 << stage_effect)) {
|
||
stop_stage_effect_auth_3d(stage_effect);
|
||
stop_stage_effect_glitter(stage_effect);
|
||
}
|
||
|
||
set_stage_effect_auth_3d_frame(stage_effect, 0.0f);
|
||
#if !BAKE_VIDEO_ALPHA
|
||
set_stage_effect_glitter_frame(stage_effect, 0.0f);
|
||
#endif
|
||
flags |= 1 << stage_effect;
|
||
return;
|
||
}
|
||
|
||
if (curr_stage_effect == stage_effect && !next_stage_effect || next_stage_effect)
|
||
return;
|
||
else if (curr_stage_effect) {
|
||
if (!(flags & 0x10)) {
|
||
next_stage_effect = stage_effect;
|
||
stage_effect_transition_state = 0;
|
||
|
||
if (((bpm_frame_rate_control.bar_beat->bar - 1) % 2)
|
||
&& curr_stage_effect >= 1 && curr_stage_effect <= 12) {
|
||
std::vector<x_pv_game_stage_effect_auth_3d>& auth_3d = effect[curr_stage_effect - 1ULL].auth_3d;
|
||
for (x_pv_game_stage_effect_auth_3d& i : auth_3d) {
|
||
auth_3d_id& id = i.id;
|
||
if (i.field_1)
|
||
id.set_repeat(false);
|
||
}
|
||
}
|
||
return;
|
||
}
|
||
else if (curr_stage_effect >= 1 && curr_stage_effect <= 12) {
|
||
stop_stage_effect_auth_3d(curr_stage_effect);
|
||
stop_stage_effect_glitter(curr_stage_effect);
|
||
}
|
||
}
|
||
|
||
if (stage_data.obj_hash.size())
|
||
stage_data.set_stage(stage_data.obj_hash.front());
|
||
curr_stage_effect = stage_effect;
|
||
set_stage_effect_auth_3d_frame(stage_effect, -1.0f);
|
||
#if !BAKE_VIDEO_ALPHA
|
||
set_stage_effect_glitter_frame(stage_effect, -1.0f);
|
||
#endif
|
||
}
|
||
|
||
void x_pv_game_stage::set_stage_effect_auth_3d_frame(int32_t stage_effect, float_t frame) {
|
||
if (stage_effect < 1 || stage_effect > 12)
|
||
return;
|
||
|
||
if (frame < 0.0f)
|
||
frame = bpm_frame_rate_control.bar_beat->get_bar_current_frame();
|
||
|
||
std::vector<x_pv_game_stage_effect_auth_3d>& auth_3d = effect[stage_effect - 1ULL].auth_3d;
|
||
for (x_pv_game_stage_effect_auth_3d& i : auth_3d) {
|
||
auth_3d_id& id = i.id;
|
||
id.set_camera_root_update(false);
|
||
#if BAKE_VIDEO_ALPHA
|
||
id.set_enable(false);
|
||
#else
|
||
id.set_enable(true);
|
||
#endif
|
||
id.set_repeat(true);
|
||
float_t last_frame = id.get_last_frame();
|
||
if (i.repeat && last_frame <= frame) {
|
||
int32_t frame_offset = (int32_t)id.get_frame_offset();
|
||
int32_t _frame = frame_offset + (int32_t)(frame - (float_t)frame_offset) % (int32_t)last_frame;
|
||
|
||
frame = (float_t)_frame + (frame - prj::floorf(frame));
|
||
}
|
||
id.set_req_frame(frame);
|
||
id.set_max_frame(-1.0f);
|
||
id.set_paused(false);
|
||
id.set_visibility(true);
|
||
id.set_frame_rate(&bpm_frame_rate_control);
|
||
}
|
||
}
|
||
|
||
void x_pv_game_stage::set_stage_effect_glitter_frame(int32_t stage_effect, float_t frame) {
|
||
if (stage_effect < 1 || stage_effect > 12)
|
||
return;
|
||
|
||
if (frame < 0.0f)
|
||
frame = bpm_frame_rate_control.bar_beat->get_bar_current_frame();
|
||
|
||
std::vector<x_pv_game_stage_effect_glitter>& glitter = effect[stage_effect - 1ULL].glitter;
|
||
for (x_pv_game_stage_effect_glitter& i : glitter) {
|
||
i.scene_counter = Glitter::glt_particle_manager->LoadSceneEffect(
|
||
i.name.hash_murmurhash, i.name.c_str(), true, 0x01);
|
||
if (!i.scene_counter)
|
||
continue;
|
||
|
||
Glitter::glt_particle_manager->SetSceneFrameRate(i.scene_counter, &bpm_frame_rate_control);
|
||
|
||
int32_t life_time = 0;
|
||
Glitter::glt_particle_manager->GetSceneFrameLifeTime(i.scene_counter, &life_time);
|
||
if (life_time <= 0)
|
||
continue;
|
||
|
||
if (stage_effect < 8 || stage_effect > 9) {
|
||
float_t _life_time = (float_t)life_time;
|
||
while (frame >= _life_time)
|
||
frame -= _life_time;
|
||
Glitter::glt_particle_manager->SetSceneEffectReqFrame(i.scene_counter, frame);
|
||
}
|
||
else if (frame < (float_t)life_time)
|
||
Glitter::glt_particle_manager->SetSceneEffectReqFrame(i.scene_counter, frame);
|
||
else
|
||
Glitter::glt_particle_manager->FreeSceneEffect(i.scene_counter, false);
|
||
|
||
i.fade_time_left = i.fade_time;
|
||
}
|
||
}
|
||
|
||
void x_pv_game_stage::stop_stage_change_effect() {
|
||
if (!next_stage_effect)
|
||
return;
|
||
|
||
int32_t curr_stg_eff = curr_stage_effect;
|
||
if (curr_stg_eff >= 1 && curr_stg_eff <= 12)
|
||
curr_stg_eff--;
|
||
else
|
||
curr_stg_eff = 0;
|
||
|
||
int32_t next_stg_eff = next_stage_effect;
|
||
if (next_stg_eff >= 1 && next_stg_eff <= 12)
|
||
next_stg_eff--;
|
||
else
|
||
next_stg_eff = 0;
|
||
|
||
x_pv_game_stage_change_effect& chg_eff = change_effect[curr_stg_eff][next_stg_eff];
|
||
|
||
for (x_pv_game_stage_effect_auth_3d& i : chg_eff.auth_3d) {
|
||
auth_3d_id& id = i.id;
|
||
id.set_visibility(false);
|
||
id.set_enable(false);
|
||
}
|
||
|
||
for (x_pv_game_stage_effect_glitter& i : chg_eff.glitter)
|
||
if (i.scene_counter) {
|
||
Glitter::glt_particle_manager->FreeSceneEffect(i.scene_counter, false);
|
||
i.scene_counter = 0;
|
||
}
|
||
}
|
||
|
||
void x_pv_game_stage::stop_stage_effect(bool reset_stage) {
|
||
if (curr_stage_effect < 1 || curr_stage_effect > 12)
|
||
return;
|
||
|
||
if (next_stage_effect) {
|
||
switch (stage_effect_transition_state) {
|
||
case 0:
|
||
stop_stage_effect_auth_3d(curr_stage_effect);
|
||
break;
|
||
case 1:
|
||
stop_stage_change_effect();
|
||
break;
|
||
}
|
||
stop_stage_effect_glitter(curr_stage_effect);
|
||
}
|
||
else {
|
||
stop_stage_effect_auth_3d(curr_stage_effect);
|
||
stop_stage_effect_glitter(curr_stage_effect);
|
||
}
|
||
|
||
if (reset_stage)
|
||
stage_data.set_default_stage();
|
||
|
||
curr_stage_effect = 0;
|
||
next_stage_effect = 0;
|
||
}
|
||
|
||
void x_pv_game_stage::stop_stage_effect_auth_3d(int32_t stage_effect) {
|
||
if (stage_effect < 1 || stage_effect > 12)
|
||
return;
|
||
|
||
std::vector<x_pv_game_stage_effect_auth_3d>& auth_3d = effect[stage_effect - 1ULL].auth_3d;
|
||
for (x_pv_game_stage_effect_auth_3d& i : auth_3d) {
|
||
auth_3d_id& id = i.id;
|
||
id.set_visibility(false);
|
||
id.set_enable(false);
|
||
}
|
||
}
|
||
|
||
void x_pv_game_stage::stop_stage_effect_glitter(int32_t stage_effect) {
|
||
if (stage_effect < 1 || stage_effect > 12)
|
||
return;
|
||
|
||
std::vector<x_pv_game_stage_effect_glitter>& glitter = effect[stage_effect - 1ULL].glitter;
|
||
for (x_pv_game_stage_effect_glitter& i : glitter)
|
||
if (i.scene_counter) {
|
||
Glitter::glt_particle_manager->FreeSceneEffect(i.scene_counter, false);
|
||
i.scene_counter = 0;
|
||
}
|
||
}
|
||
|
||
void x_pv_game_stage::unload() {
|
||
if (!stage_resource || !stage_id)
|
||
return;
|
||
|
||
for (std::pair<uint32_t, auth_3d_id> i : auth_3d_ids)
|
||
i.second.unload(rctx_ptr);
|
||
|
||
auth_3d_ids.clear();
|
||
|
||
for (int32_t i = 0; i < X_PV_GAME_STAGE_EFFECT_COUNT; i++) {
|
||
x_pv_game_stage_effect& eff = effect[i];
|
||
for (x_pv_game_stage_effect_glitter& j : eff.glitter)
|
||
if (j.scene_counter) {
|
||
Glitter::glt_particle_manager->FreeSceneEffect(j.scene_counter, false);
|
||
j.scene_counter = 0;
|
||
}
|
||
}
|
||
|
||
if (stage_effect_transition_state == 1)
|
||
stop_stage_change_effect();
|
||
|
||
for (int32_t i = 0; i < X_PV_GAME_STAGE_EFFECT_COUNT; i++)
|
||
for (int32_t j = 0; j < X_PV_GAME_STAGE_EFFECT_COUNT; j++) {
|
||
x_pv_game_stage_change_effect& chg_eff = change_effect[i][j];
|
||
for (x_pv_game_stage_effect_glitter& k : chg_eff.glitter)
|
||
if (k.scene_counter) {
|
||
Glitter::glt_particle_manager->FreeSceneEffect(k.scene_counter, false);
|
||
k.scene_counter = 0;
|
||
}
|
||
|
||
chg_eff.enable = false;
|
||
chg_eff.auth_3d.clear();
|
||
chg_eff.auth_3d.shrink_to_fit();
|
||
chg_eff.glitter.clear();
|
||
chg_eff.glitter.shrink_to_fit();
|
||
chg_eff.bars_left = 0;
|
||
chg_eff.bar_count = 0;
|
||
}
|
||
|
||
for (uint32_t& i : stage_glitter)
|
||
Glitter::glt_particle_manager->UnloadEffectGroup(i);
|
||
|
||
stage_glitter.clear();
|
||
|
||
for (string_hash& i : stage_auth_3d)
|
||
auth_3d_data_unload_category(i.hash_murmurhash);
|
||
|
||
stage_auth_3d.clear();
|
||
|
||
env.unload();
|
||
|
||
delete stage_resource;
|
||
stage_resource = 0;
|
||
|
||
stage_data.unload();
|
||
|
||
stage_id = 0;
|
||
|
||
state = 30;
|
||
}
|
||
|
||
x_pv_game::x_pv_game() : state(), pv_count(), pv_index(), state_old(), frame(), frame_float(), time(),
|
||
rob_chara_ids(), success(), task_effect_init(), pause(), step_frame(), pv_id(), stage_id(), charas(), modules() {
|
||
light_auth_3d_id = {};
|
||
for (chara_index& i : charas)
|
||
i = CHARA_MAX;
|
||
for (int32_t& i : modules)
|
||
i = 0;
|
||
}
|
||
|
||
x_pv_game::~x_pv_game() {
|
||
|
||
}
|
||
|
||
bool x_pv_game::init() {
|
||
task_rob_manager_add_task();
|
||
return true;
|
||
}
|
||
|
||
#if BAKE_PNG || BAKE_VIDEO
|
||
static bool img_write = false;
|
||
#endif
|
||
|
||
#if BAKE_VIDEO
|
||
extern ID3D11Device* d3d_device;
|
||
extern ID3D11DeviceContext* d3d_device_context;
|
||
extern HANDLE d3d_gl_handle;
|
||
|
||
const int32_t d3d_in_flight_num = 3;
|
||
bool d3d_tex_write[d3d_in_flight_num];
|
||
int32_t d3d_curr_tex = 0;
|
||
int32_t d3d_tex_in_queue = 0;
|
||
|
||
ID3D11Texture2D* d3d_texture[d3d_in_flight_num];
|
||
|
||
GLuint d3d_query[d3d_in_flight_num];
|
||
GLuint d3d_gl_fbo[d3d_in_flight_num];
|
||
GLuint d3d_gl_rbo[d3d_in_flight_num];
|
||
HANDLE d3d_gl_rbo_handle[d3d_in_flight_num];
|
||
|
||
#if BAKE_VIDEO_ALPHA
|
||
bool d3d_alpha_tex_write[d3d_in_flight_num];
|
||
int32_t d3d_curr_alpha_tex = 0;
|
||
int32_t d3d_alpha_tex_in_queue = 0;
|
||
|
||
ID3D11Texture2D* d3d_alpha_texture[d3d_in_flight_num];
|
||
|
||
GLuint d3d_alpha_query[d3d_in_flight_num];
|
||
GLuint d3d_gl_alpha_fbo[d3d_in_flight_num];
|
||
GLuint d3d_gl_alpha_rbo[d3d_in_flight_num];
|
||
HANDLE d3d_gl_alpha_rbo_handle[d3d_in_flight_num];
|
||
#endif
|
||
|
||
waitable_timer d3d_timer;
|
||
|
||
const size_t nvenc_src_pixel_size = 8;
|
||
const size_t nvenc_dst_pixel_size = 4;
|
||
|
||
std::vector<uint8_t> nvenc_temp_pixels;
|
||
|
||
nvenc_encoder* nvenc_enc;
|
||
file_stream* nvenc_stream;
|
||
|
||
#if BAKE_VIDEO_ALPHA
|
||
nvenc_encoder* nvenc_alpha_enc;
|
||
file_stream* nvenc_alpha_stream;
|
||
#endif
|
||
#endif
|
||
|
||
#if BAKE_DOF
|
||
static void a3da_key_rev(a3da_key& k, std::vector<float_t>& values_src) {
|
||
std::vector<kft3> values;
|
||
int32_t type = interpolate_chs_reverse_sequence(values_src, values);
|
||
|
||
k = {};
|
||
switch (type) {
|
||
case 0:
|
||
default:
|
||
k.type = A3DA_KEY_NONE;
|
||
return;
|
||
case 1:
|
||
k.value = values[0].value;
|
||
k.type = A3DA_KEY_STATIC;
|
||
return;
|
||
case 2:
|
||
k.type = A3DA_KEY_LINEAR;
|
||
break;
|
||
case 3:
|
||
k.type = A3DA_KEY_HERMITE;
|
||
break;
|
||
}
|
||
|
||
k.keys.assign(values.begin(), values.end());
|
||
k.max_frame = (float_t)(values_src.size() + 1);
|
||
}
|
||
#endif
|
||
|
||
#if BAKE_PNG || BAKE_VIDEO
|
||
static int32_t frame_prev = -1;
|
||
#endif
|
||
|
||
bool x_pv_game::ctrl() {
|
||
#if BAKE_VIDEO
|
||
auto write_frame = [&](int32_t idx) {
|
||
int32_t res = 0;
|
||
glGetQueryObjectiv(d3d_query[idx], GL_QUERY_RESULT_AVAILABLE, &res);
|
||
if (res) {
|
||
nvenc_enc->write_frame(d3d_texture[idx], nvenc_stream);
|
||
nvenc_stream->flush();
|
||
d3d_tex_in_queue--;
|
||
d3d_tex_write[idx] = false;
|
||
}
|
||
};
|
||
|
||
#if BAKE_VIDEO_ALPHA
|
||
auto write_alpha_frame = [&](int32_t idx) {
|
||
int32_t res = 0;
|
||
glGetQueryObjectiv(d3d_alpha_query[idx], GL_QUERY_RESULT_AVAILABLE, &res);
|
||
if (res) {
|
||
nvenc_alpha_enc->write_frame(d3d_alpha_texture[idx], nvenc_alpha_stream);
|
||
nvenc_alpha_stream->flush();
|
||
d3d_alpha_tex_in_queue--;
|
||
d3d_alpha_tex_write[idx] = false;
|
||
}
|
||
};
|
||
#endif
|
||
|
||
if (GLAD_WGL_NV_DX_interop2 && d3d_tex_in_queue) {
|
||
if (frame_prev == x_pv_game_ptr->frame)
|
||
for (int32_t i = 0; i < d3d_in_flight_num && !d3d_tex_write[d3d_curr_tex]; i++)
|
||
d3d_curr_tex = (d3d_curr_tex + 1) % d3d_in_flight_num;
|
||
|
||
if (d3d_tex_write[d3d_curr_tex])
|
||
write_frame(d3d_curr_tex);
|
||
}
|
||
|
||
#if BAKE_VIDEO_ALPHA
|
||
if (GLAD_WGL_NV_DX_interop2 && d3d_alpha_tex_in_queue) {
|
||
if (frame_prev == x_pv_game_ptr->frame)
|
||
for (int32_t i = 0; i < d3d_in_flight_num && !d3d_alpha_tex_write[d3d_curr_alpha_tex]; i++)
|
||
d3d_curr_alpha_tex = (d3d_curr_alpha_tex + 1) % d3d_in_flight_num;
|
||
|
||
if (d3d_alpha_tex_write[d3d_curr_alpha_tex])
|
||
write_alpha_frame(d3d_curr_alpha_tex);
|
||
}
|
||
#endif
|
||
#endif
|
||
|
||
#if BAKE_PNG || BAKE_VIDEO
|
||
if (img_write && frame_prev != x_pv_game_ptr->frame) {
|
||
texture* tex = rctx_ptr->screen_buffer.color_texture;
|
||
int32_t width = tex->width;
|
||
int32_t height = tex->height;
|
||
|
||
#if BAKE_VIDEO
|
||
if (GLAD_WGL_NV_DX_interop2) {
|
||
int32_t idx = (d3d_curr_tex + 1) % d3d_in_flight_num;
|
||
d3d_curr_tex = idx;
|
||
int32_t next_idx = (idx + 2) % d3d_in_flight_num;
|
||
|
||
while (d3d_tex_write[next_idx]) {
|
||
d3d_timer.sleep_float(1.0);
|
||
write_frame(next_idx);
|
||
}
|
||
|
||
wglDXLockObjectsNV(d3d_gl_handle, 1, &d3d_gl_rbo_handle[next_idx]);
|
||
|
||
gl_state_bind_framebuffer(d3d_gl_fbo[next_idx]);
|
||
gl_state_active_bind_texture_2d(0, tex->tex);
|
||
glViewport(0, 0, width, height);
|
||
uniform_value[U_REDUCE] = 0;
|
||
shaders_ft.set(SHADER_FT_REDUCE);
|
||
glBeginQuery(GL_SAMPLES_PASSED, d3d_query[next_idx]);
|
||
rctx_ptr->render.draw_quad(width, height,
|
||
1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f);
|
||
glEndQuery(GL_SAMPLES_PASSED);
|
||
gl_state_bind_texture_2d(0);
|
||
gl_state_bind_framebuffer(0);
|
||
|
||
wglDXUnlockObjectsNV(d3d_gl_handle, 1, &d3d_gl_rbo_handle[next_idx]);
|
||
|
||
d3d_tex_in_queue++;
|
||
d3d_tex_write[next_idx] = true;
|
||
|
||
#if BAKE_VIDEO_ALPHA
|
||
int32_t alpha_idx = (d3d_curr_alpha_tex + 1) % d3d_in_flight_num;
|
||
d3d_curr_alpha_tex = alpha_idx;
|
||
int32_t next_alpha_idx = (alpha_idx + 2) % d3d_in_flight_num;
|
||
|
||
while (d3d_alpha_tex_write[next_alpha_idx]) {
|
||
d3d_timer.sleep_float(1.0);
|
||
write_alpha_frame(next_alpha_idx);
|
||
}
|
||
|
||
wglDXLockObjectsNV(d3d_gl_handle, 1, &d3d_gl_alpha_rbo_handle[next_alpha_idx]);
|
||
|
||
gl_state_bind_framebuffer(d3d_gl_alpha_fbo[next_alpha_idx]);
|
||
gl_state_active_bind_texture_2d(0, tex->tex);
|
||
|
||
GLint swizzle_aaa1[] = { GL_ALPHA, GL_ALPHA, GL_ALPHA, GL_ONE };
|
||
glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzle_aaa1);
|
||
|
||
glViewport(0, 0, width, height);
|
||
uniform_value[U_REDUCE] = 0;
|
||
shaders_ft.set(SHADER_FT_REDUCE);
|
||
glBeginQuery(GL_SAMPLES_PASSED, d3d_alpha_query[next_alpha_idx]);
|
||
rctx_ptr->render.draw_quad(width, height,
|
||
1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f);
|
||
glEndQuery(GL_SAMPLES_PASSED);
|
||
|
||
GLint swizzle_rgba[] = { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA };
|
||
glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzle_rgba);
|
||
|
||
gl_state_bind_texture_2d(0);
|
||
gl_state_bind_framebuffer(0);
|
||
|
||
wglDXUnlockObjectsNV(d3d_gl_handle, 1, &d3d_gl_alpha_rbo_handle[next_alpha_idx]);
|
||
|
||
d3d_alpha_tex_in_queue++;
|
||
d3d_alpha_tex_write[next_alpha_idx] = true;
|
||
#endif
|
||
}
|
||
else {
|
||
#if BAKE_VIDEO_ALPHA
|
||
D3D11_MAPPED_SUBRESOURCE mapped_res = {};
|
||
HRESULT result = d3d_device_context->Map(d3d_texture[0], 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped_res);
|
||
D3D11_MAPPED_SUBRESOURCE mapped_alpha_res = {};
|
||
HRESULT result_alpha = d3d_device_context->Map(d3d_alpha_texture[0], 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped_alpha_res);
|
||
if (SUCCEEDED(result) && SUCCEEDED(result_alpha)) {
|
||
gl_state_bind_texture_2d(tex->tex);
|
||
glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_HALF_FLOAT, nvenc_temp_pixels.data());
|
||
gl_state_bind_texture_2d(0);
|
||
|
||
uint8_t* src = (uint8_t*)nvenc_temp_pixels.data();
|
||
uint8_t* dst = (uint8_t*)mapped_res.pData;
|
||
uint8_t* dst_alpha = (uint8_t*)mapped_alpha_res.pData;
|
||
|
||
__m128 rgb_f32;
|
||
vec4i rgb_u10;
|
||
|
||
extern bool f16c;
|
||
if (f16c)
|
||
for (size_t y = 0, i = height; i; y++, i--) {
|
||
uint8_t* src1 = &src[y * width * nvenc_src_pixel_size];
|
||
uint8_t* dst1 = &dst[(height - y - 1) * width * nvenc_dst_pixel_size];
|
||
uint8_t* dst1_alpha = &dst_alpha[(height - y - 1) * width * nvenc_dst_pixel_size];
|
||
|
||
for (size_t x = 0, j = width; j; x++, j--, src1 += nvenc_src_pixel_size,
|
||
dst1 += nvenc_dst_pixel_size, dst1_alpha += nvenc_dst_pixel_size) {
|
||
rgb_f32 = _mm_cvtph_ps(_mm_loadl_epi64((__m128i*)src1));
|
||
rgb_f32 = _mm_min_ps(_mm_max_ps(rgb_f32, vec4::load_xmm(0.0f)), vec4::load_xmm(1.0f));
|
||
rgb_f32 = _mm_mul_ps(rgb_f32, vec4::load_xmm((float_t)((1 << 10) - 1)));
|
||
rgb_u10 = vec4i::store_xmm(_mm_cvtps_epi32(rgb_f32));
|
||
*(uint32_t*)dst1 = (uint32_t)rgb_u10.x | ((uint32_t)rgb_u10.y << 10)
|
||
| ((uint32_t)rgb_u10.z << 20) | (0x03 << 30);
|
||
*(uint32_t*)dst1_alpha = (uint32_t)rgb_u10.w | ((uint32_t)rgb_u10.w << 10)
|
||
| ((uint32_t)rgb_u10.w << 20) | (0x03 << 30);
|
||
}
|
||
}
|
||
else
|
||
for (size_t y = 0, i = height; i; y++, i--) {
|
||
uint8_t* src1 = &src[y * width * nvenc_src_pixel_size];
|
||
uint8_t* dst1 = &dst[(height - y - 1) * width * nvenc_dst_pixel_size];
|
||
uint8_t* dst1_alpha = &dst_alpha[(height - y - 1) * width * nvenc_dst_pixel_size];
|
||
|
||
for (size_t x = 0, j = width; j; x++, j--, src1 += nvenc_src_pixel_size,
|
||
dst1 += nvenc_dst_pixel_size, dst1_alpha += nvenc_dst_pixel_size) {
|
||
rgb_f32.m128_f32[0] = half_to_float_convert(((half_t*)src1)[0]);
|
||
rgb_f32.m128_f32[1] = half_to_float_convert(((half_t*)src1)[1]);
|
||
rgb_f32.m128_f32[2] = half_to_float_convert(((half_t*)src1)[2]);
|
||
rgb_f32.m128_f32[3] = half_to_float_convert(((half_t*)src1)[3]);
|
||
rgb_f32 = _mm_min_ps(_mm_max_ps(rgb_f32, vec4::load_xmm(0.0f)), vec4::load_xmm(1.0f));
|
||
rgb_f32 = _mm_mul_ps(rgb_f32, vec4::load_xmm((float_t)((1 << 10) - 1)));
|
||
rgb_u10 = vec4i::store_xmm(_mm_cvtps_epi32(rgb_f32));
|
||
*(uint32_t*)dst1 = (uint32_t)rgb_u10.x | ((uint32_t)rgb_u10.y << 10)
|
||
| ((uint32_t)rgb_u10.z << 20) | (0x03 << 30);
|
||
*(uint32_t*)dst1_alpha = (uint32_t)rgb_u10.w | ((uint32_t)rgb_u10.w << 10)
|
||
| ((uint32_t)rgb_u10.w << 20) | (0x03 << 30);
|
||
}
|
||
}
|
||
|
||
d3d_device_context->Unmap(d3d_texture[0], 0);
|
||
d3d_device_context->Unmap(d3d_alpha_texture[0], 0);
|
||
nvenc_enc->write_frame(d3d_texture[0], nvenc_stream);
|
||
nvenc_alpha_enc->write_frame(d3d_alpha_texture[0], nvenc_alpha_stream);
|
||
nvenc_stream->flush();
|
||
nvenc_alpha_stream->flush();
|
||
}
|
||
else {
|
||
if (SUCCEEDED(result))
|
||
d3d_device_context->Unmap(d3d_texture[0], 0);
|
||
if (SUCCEEDED(result_alpha))
|
||
d3d_device_context->Unmap(d3d_alpha_texture[0], 0);
|
||
}
|
||
#else
|
||
D3D11_MAPPED_SUBRESOURCE mapped_res = {};
|
||
if (SUCCEEDED(d3d_device_context->Map(d3d_texture[0], 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped_res))) {
|
||
gl_state_bind_texture_2d(tex->tex);
|
||
glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_HALF_FLOAT, nvenc_temp_pixels.data());
|
||
gl_state_bind_texture_2d(0);
|
||
|
||
uint8_t* src = (uint8_t*)nvenc_temp_pixels.data();
|
||
uint8_t* dst = (uint8_t*)mapped_res.pData;
|
||
|
||
__m128 rgb_f32;
|
||
vec4i rgb_u10;
|
||
|
||
extern bool f16c;
|
||
if (f16c)
|
||
for (size_t y = 0, i = height; i; y++, i--) {
|
||
uint8_t* src1 = &src[y * width * nvenc_src_pixel_size];
|
||
uint8_t* dst1 = &dst[(height - y - 1) * width * nvenc_dst_pixel_size];
|
||
|
||
for (size_t x = 0, j = width; j; x++, j--, src1 += nvenc_src_pixel_size, dst1 += nvenc_dst_pixel_size) {
|
||
rgb_f32 = _mm_cvtph_ps(_mm_loadl_epi64((__m128i*)src1));
|
||
rgb_f32 = _mm_min_ps(_mm_max_ps(rgb_f32, vec4::load_xmm(0.0f)), vec4::load_xmm(1.0f));
|
||
rgb_f32 = _mm_mul_ps(rgb_f32, vec4::load_xmm((float_t)((1 << 10) - 1)));
|
||
rgb_u10 = vec4i::store_xmm(_mm_cvtps_epi32(rgb_f32));
|
||
*(uint32_t*)dst1 = (uint32_t)rgb_u10.x | ((uint32_t)rgb_u10.y << 10)
|
||
| ((uint32_t)rgb_u10.z << 20) | (0x03 << 30);
|
||
}
|
||
}
|
||
else
|
||
for (size_t y = 0, i = height; i; y++, i--) {
|
||
uint8_t* src1 = &src[y * width * nvenc_src_pixel_size];
|
||
uint8_t* dst1 = &dst[(height - y - 1) * width * nvenc_dst_pixel_size];
|
||
|
||
for (size_t x = 0, j = width; j; x++, j--, src1 += nvenc_src_pixel_size, dst1 += nvenc_dst_pixel_size) {
|
||
rgb_f32.m128_f32[0] = half_to_float_convert(((half_t*)src1)[0]);
|
||
rgb_f32.m128_f32[1] = half_to_float_convert(((half_t*)src1)[1]);
|
||
rgb_f32.m128_f32[2] = half_to_float_convert(((half_t*)src1)[2]);
|
||
rgb_f32.m128_f32[3] = half_to_float_convert(((half_t*)src1)[3]);
|
||
rgb_f32 = _mm_min_ps(_mm_max_ps(rgb_f32, vec4::load_xmm(0.0f)), vec4::load_xmm(1.0f));
|
||
rgb_f32 = _mm_mul_ps(rgb_f32, vec4::load_xmm((float_t)((1 << 10) - 1)));
|
||
rgb_u10 = vec4i::store_xmm(_mm_cvtps_epi32(rgb_f32));
|
||
*(uint32_t*)dst1 = (uint32_t)rgb_u10.x | ((uint32_t)rgb_u10.y << 10)
|
||
| ((uint32_t)rgb_u10.z << 20) | (0x03 << 30);
|
||
}
|
||
}
|
||
|
||
d3d_device_context->Unmap(d3d_texture[0], 0);
|
||
nvenc_enc->write_frame(d3d_texture[0], nvenc_stream);
|
||
nvenc_stream->flush();
|
||
}
|
||
#endif
|
||
}
|
||
#elif BAKE_PNG
|
||
std::vector<uint8_t> temp_pixels;
|
||
temp_pixels.resize((size_t)width * (size_t)height * 4 * sizeof(uint8_t));
|
||
gl_state_bind_texture_2d(tex->tex);
|
||
glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, temp_pixels.data());
|
||
gl_state_bind_texture_2d(0);
|
||
|
||
std::vector<uint8_t> pixels;
|
||
pixels.resize((size_t)width * (size_t)height * 4 * sizeof(uint8_t));
|
||
|
||
uint8_t* src = (uint8_t*)temp_pixels.data();
|
||
uint8_t* dst = (uint8_t*)pixels.data();
|
||
for (size_t y = 0; y < height; y++) {
|
||
uint8_t* src1 = &src[y * width * 4];
|
||
uint8_t* dst1 = &dst[(height - y - 1) * width * 4];
|
||
for (size_t x = 0; x < width; x++) {
|
||
*dst1++ = *src1++;
|
||
*dst1++ = *src1++;
|
||
*dst1++ = *src1++;
|
||
*dst1++ = *src1++;
|
||
//*dst1++ = reverse_endianness_uint16_t(*src1++);
|
||
//*dst1++ = reverse_endianness_uint16_t(*src1++);
|
||
//*dst1++ = reverse_endianness_uint16_t(*src1++);
|
||
//*dst1++ = reverse_endianness_uint16_t(*src1++);
|
||
}
|
||
}
|
||
|
||
temp_pixels.clear();
|
||
temp_pixels.shrink_to_fit();
|
||
|
||
std::vector<uint8_t> png;
|
||
uint32_t error = lodepng::encode(png, pixels, (uint32_t)width, (uint32_t)height, LCT_RGBA, 8);
|
||
if (!error) {
|
||
char buf[0x200];
|
||
sprintf_s(buf, sizeof(buf), "G:\\ReDIVA\\Photos\\pv%03d",
|
||
x_pv_game_ptr->get_data().pv_id);
|
||
CreateDirectoryA(buf, 0);
|
||
|
||
sprintf_s(buf, sizeof(buf), "G:\\ReDIVA\\Photos\\pv%03d\\%05d.png",
|
||
x_pv_game_ptr->get_data().pv_id, x_pv_game_ptr->frame);
|
||
lodepng::save_file(png, buf);
|
||
}
|
||
#endif
|
||
|
||
frame_prev = x_pv_game_ptr->frame;
|
||
img_write = false;
|
||
}
|
||
#endif
|
||
|
||
if (state_old == 20)
|
||
ctrl((float_t)((frame_float + get_delta_frame()) * (1.0 / 60.0)), get_delta_frame() * (float_t)(1.0 / 60.0));
|
||
else
|
||
ctrl(0.0f, 0.0f);
|
||
|
||
switch (state_old) {
|
||
case 0:
|
||
return false;
|
||
case 1: {
|
||
pv_index = 0;
|
||
pv_count = 1;
|
||
|
||
get_data().pv_id = pv_id;
|
||
|
||
char buf[0x200];
|
||
for (int32_t i = 0; i < pv_count; i++) {
|
||
x_pv_game_data& pv_data = this->data[i];
|
||
|
||
sprintf_s(buf, sizeof(buf), "pv%03d.pvpp", pv_data.pv_id);
|
||
pv_data.play_param_file_handler.read_file(&data_list[DATA_X], "root+/pv/", buf);
|
||
pv_data.stage = &stage_data;
|
||
}
|
||
|
||
state_old = 2;
|
||
} break;
|
||
case 2: {
|
||
bool wait_load = false;
|
||
for (int32_t i = 0; i < pv_count; i++)
|
||
if (data[i].play_param_file_handler.check_not_ready())
|
||
wait_load |= true;
|
||
|
||
if (wait_load)
|
||
break;
|
||
|
||
stage_data.load(stage_id, &field_71994, false);
|
||
|
||
for (int32_t i = 0; i < pv_count; i++) {
|
||
x_pv_game_data& pv_data = this->data[i];
|
||
|
||
const void* pvpp_data = pv_data.play_param_file_handler.get_data();
|
||
size_t pvpp_size = pv_data.play_param_file_handler.get_size();
|
||
|
||
pv_data.play_param = new pvpp;
|
||
pv_data.play_param->read(pvpp_data, pvpp_size);
|
||
|
||
#if BAKE_PV826
|
||
pv_data.load(pv_id, &field_71994, charas,
|
||
pv_id == 826 ? &effchrpv_auth_3d_mot_names : 0);
|
||
#else
|
||
pv_data.load(pv_id, &field_71994, charas);
|
||
#endif
|
||
|
||
int32_t chara_index = 0;
|
||
for (pvpp_chara& i : pv_data.play_param->chara) {
|
||
if (i.motion.size() && rob_chara_ids[chara_index] == -1) {
|
||
rob_chara_pv_data pv_data;
|
||
pv_data.chara_size_index = chara_init_data_get_chara_size_index(charas[chara_index]);
|
||
rob_sleeve_handler_data_get_sleeve_data(
|
||
charas[chara_index], modules[chara_index] + 1, pv_data.sleeve_l, pv_data.sleeve_r);
|
||
int32_t chara_id = rob_chara_array_init_chara_index(
|
||
charas[chara_index], pv_data, modules[chara_index], true);
|
||
if (chara_id >= 0 && chara_id < ROB_CHARA_COUNT)
|
||
rob_chara_ids[chara_index] = chara_id;
|
||
}
|
||
|
||
if (++chara_index >= ROB_CHARA_COUNT)
|
||
break;
|
||
}
|
||
|
||
if (pv_data.play_param->chara.size() < 2)
|
||
rctx_ptr->render.update_res(false, 1);
|
||
else
|
||
rctx_ptr->render.update_res(false, 2);
|
||
|
||
#if BAKE_PV826
|
||
if (pv_id == 826) {
|
||
for (int32_t i = (int32_t)pv_data.play_param->chara.size(); i < ROB_CHARA_COUNT; i++) {
|
||
rob_chara_pv_data pv_data;
|
||
pv_data.chara_size_index = chara_init_data_get_chara_size_index(charas[i]);
|
||
int32_t chara_id = rob_chara_array_init_chara_index(charas[i], pv_data, modules[i], true);
|
||
if (chara_id >= 0 && chara_id < ROB_CHARA_COUNT)
|
||
rob_chara_ids[i] = chara_id;
|
||
effchrpv_rob_mot_ids.push_back(chara_id);
|
||
}
|
||
|
||
char buf[0x100];
|
||
pv_data.play_param->chara.resize(6);
|
||
pvpp_chara* chara = pv_data.play_param->chara.data();
|
||
for (int32_t i = 1; i < 6; i++) {
|
||
switch (i) {
|
||
case 1:
|
||
chara[i].chara_effect.base_chara = PVPP_CHARA_RIN;
|
||
chara[i].chara_effect_init = true;
|
||
break;
|
||
case 2:
|
||
chara[i].chara_effect.base_chara = PVPP_CHARA_LEN;
|
||
chara[i].chara_effect_init = true;
|
||
break;
|
||
case 3:
|
||
chara[i].chara_effect.base_chara = PVPP_CHARA_LUKA;
|
||
chara[i].chara_effect_init = true;
|
||
break;
|
||
case 4:
|
||
chara[i].chara_effect.base_chara = PVPP_CHARA_MEIKO;
|
||
chara[i].chara_effect_init = true;
|
||
break;
|
||
case 5:
|
||
chara[i].chara_effect.base_chara = PVPP_CHARA_KAITO;
|
||
chara[i].chara_effect_init = true;
|
||
break;
|
||
}
|
||
sprintf_s(buf, sizeof(buf), "PV%03d_%s_P%d_00", 826, "OST", i + 1);
|
||
|
||
chara[i].motion.push_back(buf);
|
||
}
|
||
}
|
||
#endif
|
||
}
|
||
|
||
state_old = 3;
|
||
} break;
|
||
case 3: {
|
||
bool wait_load = false;
|
||
for (int32_t i = 0; i < ROB_CHARA_COUNT; i++)
|
||
if (rob_chara_ids[i] != -1)
|
||
wait_load |= !task_rob_manager_check_chara_loaded(rob_chara_ids[i]);
|
||
|
||
if (wait_load)
|
||
break;
|
||
|
||
data_struct* x_data = &data_list[DATA_X];
|
||
|
||
light_param_data_storage_data_set_pv_id(get_data().pv_id == 832 ? 800 : get_data().pv_id);
|
||
|
||
auth_3d_data_load_category(light_category.c_str());
|
||
|
||
state_old = 7;
|
||
} break;
|
||
case 7: {
|
||
bool wait_load = false;
|
||
|
||
if (!auth_3d_data_check_category_loaded(light_category.c_str()))
|
||
wait_load |= true;
|
||
|
||
if (wait_load)
|
||
break;
|
||
|
||
data_struct* x_data = &data_list[DATA_X];
|
||
|
||
light_auth_3d_id = {};
|
||
{
|
||
data_struct* aft_data = &data_list[DATA_AFT];
|
||
auth_3d_database* aft_auth_3d_db = &aft_data->data_ft.auth_3d_db;
|
||
|
||
char buf[0x200];
|
||
sprintf_s(buf, sizeof(buf), "STGPV%03d_EFF_LT_000",
|
||
get_data().pv_id == 832 ? 800 : get_data().pv_id);
|
||
uint32_t light_auth_3d_hash = hash_utf8_murmurhash(buf);
|
||
int32_t uid = aft_auth_3d_db->get_uid(buf);
|
||
if (uid != -1) {
|
||
light_auth_3d_id = auth_3d_id(uid, aft_auth_3d_db);
|
||
if (light_auth_3d_id.check_not_empty()) {
|
||
light_auth_3d_id.read_file(aft_auth_3d_db);
|
||
light_auth_3d_id.set_enable(false);
|
||
light_auth_3d_id.set_visibility(false);
|
||
}
|
||
else
|
||
light_auth_3d_id = {};
|
||
}
|
||
}
|
||
|
||
state_old = 8;
|
||
} break;
|
||
case 8: {
|
||
bool wait_load = false;
|
||
|
||
if (light_auth_3d_id.check_not_empty() && !light_auth_3d_id.check_loaded())
|
||
wait_load |= true;
|
||
|
||
if (wait_load)
|
||
break;
|
||
|
||
x_pv_game_pv_data& pv_data = get_data().pv_data;
|
||
|
||
pv_param_task::post_process_task_add_task();
|
||
{
|
||
int32_t pv_id = get_data().pv_id;
|
||
|
||
data_struct* x_data = &data_list[DATA_X];
|
||
|
||
dsc dsc_mouth;
|
||
dsc dsc_scene;
|
||
dsc dsc_system;
|
||
dsc dsc_easy;
|
||
|
||
char path_buf[0x200];
|
||
char file_buf[0x200];
|
||
|
||
farc dsc_common_farc;
|
||
sprintf_s(path_buf, sizeof(path_buf), "root+/pv_script/pv%03d/", pv_id);
|
||
sprintf_s(file_buf, sizeof(file_buf), "pv_%03d_common.farc", pv_id);
|
||
x_data->load_file(&dsc_common_farc, path_buf, file_buf, farc::load_file);
|
||
|
||
sprintf_s(file_buf, sizeof(file_buf), "pv_%03d_mouth.dsc", pv_id);
|
||
farc_file* dsc_mouth_ff = dsc_common_farc.read_file(file_buf);
|
||
if (dsc_mouth_ff)
|
||
dsc_mouth.parse(dsc_mouth_ff->data, dsc_mouth_ff->size, DSC_X);
|
||
|
||
sprintf_s(file_buf, sizeof(file_buf), "pv_%03d_scene.dsc", pv_id);
|
||
farc_file* dsc_scene_ff = dsc_common_farc.read_file(file_buf);
|
||
if (dsc_scene_ff)
|
||
dsc_scene.parse(dsc_scene_ff->data, dsc_scene_ff->size, DSC_X);
|
||
|
||
sprintf_s(file_buf, sizeof(file_buf), "pv_%03d_system.dsc", pv_id);
|
||
farc_file* dsc_system_ff = dsc_common_farc.read_file(file_buf);
|
||
if (dsc_system_ff)
|
||
dsc_system.parse(dsc_system_ff->data, dsc_system_ff->size, DSC_X);
|
||
|
||
sprintf_s(file_buf, sizeof(file_buf), "pv_%03d_easy.dsc", pv_id);
|
||
dsc_easy.type = DSC_X;
|
||
x_data->load_file(&dsc_easy, path_buf, file_buf, dsc::load_file);
|
||
|
||
#if BAKE_PV826
|
||
if (pv_id == 826) {
|
||
dsc dsc_hand_keys[5];
|
||
|
||
char file_buf[0x200];
|
||
for (int32_t i = 2; i <= 6; i++) {
|
||
file_stream s;
|
||
sprintf_s(file_buf, sizeof(file_buf), "pv826\\pv_826_hand_%d.txt", i);
|
||
s.open(file_buf, "rb");
|
||
size_t length = s.length;
|
||
uint8_t* data = force_malloc<uint8_t>(length);
|
||
s.read(data, length);
|
||
s.close();
|
||
|
||
dsc& d = dsc_hand_keys[i - 2];
|
||
d.parse_text(data, length, DSC_X);
|
||
d.signature = 0x13120420;
|
||
free(data);
|
||
|
||
{
|
||
int32_t hand_l_time = -1;
|
||
int32_t hand_l_id = -1;
|
||
int32_t hand_l_duration = -1;
|
||
dsc_data* hand_l_data = 0;
|
||
int32_t time = -1;
|
||
for (dsc_data& j : d.data) {
|
||
if (j.func == DSC_X_END)
|
||
break;
|
||
|
||
int32_t* data = d.get_func_data(&j);
|
||
switch (j.func) {
|
||
case DSC_X_TIME:
|
||
time = data[0];
|
||
break;
|
||
case DSC_X_HAND_ANIM: {
|
||
if (data[1] == 0) {
|
||
if (hand_l_time > -1 && hand_l_duration > time - hand_l_time)
|
||
data[3] = (time - hand_l_time) / 100;
|
||
|
||
hand_l_time = time;
|
||
hand_l_id = data[2];
|
||
hand_l_duration = data[3] * 100;
|
||
hand_l_data = &j;
|
||
}
|
||
} break;
|
||
}
|
||
}
|
||
}
|
||
|
||
{
|
||
int32_t hand_r_time = -1;
|
||
int32_t hand_r_id = -1;
|
||
int32_t hand_r_duration = -1;
|
||
dsc_data* hand_r_data = 0;
|
||
int32_t time = -1;
|
||
for (dsc_data& j : d.data) {
|
||
if (j.func == DSC_X_END)
|
||
break;
|
||
|
||
int32_t* data = d.get_func_data(&j);
|
||
switch (j.func) {
|
||
case DSC_X_TIME:
|
||
time = data[0];
|
||
break;
|
||
case DSC_X_HAND_ANIM: {
|
||
if (data[1] == 1) {
|
||
if (hand_r_time > -1 && hand_r_duration > time - hand_r_time)
|
||
data[3] = (time - hand_r_time) / 100;
|
||
|
||
hand_r_time = time;
|
||
hand_r_id = data[2];
|
||
hand_r_duration = data[3] * 100;
|
||
hand_r_data = &j;
|
||
}
|
||
} break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
pv_data.dsc.merge(9, &dsc_mouth, &dsc_scene, &dsc_system, &dsc_easy,
|
||
&dsc_hand_keys[0], &dsc_hand_keys[1], &dsc_hand_keys[2], &dsc_hand_keys[3], dsc_hand_keys[4]);
|
||
}
|
||
else
|
||
#endif
|
||
pv_data.dsc.merge(4, &dsc_mouth, &dsc_scene, &dsc_system, &dsc_easy);
|
||
|
||
struct miku_state {
|
||
bool disp;
|
||
int32_t disp_time;
|
||
int32_t set_motion_time;
|
||
uint32_t set_motion_data_offset;
|
||
} state[6];
|
||
|
||
for (miku_state& i : state) {
|
||
i.disp = true;
|
||
i.disp_time = -1;
|
||
i.set_motion_time = -1;
|
||
i.set_motion_data_offset = 0;
|
||
}
|
||
|
||
std::vector<miku_state> state_vec;
|
||
|
||
x_pv_bar_beat_data* bar_beat_data = 0;
|
||
int32_t beat_counter = 0;
|
||
|
||
prj::vector_pair<int32_t, uint32_t> miku_disp;
|
||
prj::vector_pair<int32_t, uint32_t> set_motion;
|
||
prj::vector_pair<int32_t, uint32_t> set_playdata;
|
||
|
||
int32_t time = -1;
|
||
int32_t frame = -1;
|
||
bool hand_anim_set[ROB_CHARA_COUNT] = {};
|
||
int32_t hand_anim_set_time[ROB_CHARA_COUNT] = {};
|
||
for (dsc_data& i : pv_data.dsc.data) {
|
||
if (i.func == DSC_X_END)
|
||
break;
|
||
|
||
int32_t* data = pv_data.dsc.get_func_data(&i);
|
||
switch (i.func) {
|
||
case DSC_X_TIME: {
|
||
for (miku_state& i : state)
|
||
if (state[get_data().pv_data.chara_id].disp
|
||
&& i.disp_time == time && i.set_motion_time != time)
|
||
state_vec.push_back(i);
|
||
time = data[0];
|
||
frame = (int32_t)prj::roundf((float_t)time * (float_t)(60.0 / 100000.0));
|
||
} break;
|
||
case DSC_X_MIKU_DISP: {
|
||
int32_t chara_id = data[0];
|
||
state[chara_id].disp = data[1] == 1;
|
||
if (state[chara_id].disp)
|
||
state[chara_id].disp_time = time;
|
||
miku_disp.push_back(time, i.data_offset);
|
||
|
||
if (!hand_anim_set[chara_id]) {
|
||
hand_anim_set_time[chara_id] = time;
|
||
hand_anim_set[chara_id] = true;
|
||
}
|
||
} break;
|
||
case DSC_X_SET_MOTION: {
|
||
int32_t chara_id = data[0];
|
||
state[chara_id].set_motion_time = time;
|
||
state[chara_id].set_motion_data_offset = i.data_offset;
|
||
set_motion.push_back(time, i.data_offset);
|
||
} break;
|
||
case DSC_X_SET_PLAYDATA: {
|
||
set_playdata.push_back(time, i.data_offset);
|
||
} break;
|
||
}
|
||
}
|
||
|
||
for (int32_t i = 0; i < ROB_CHARA_COUNT; i++) {
|
||
if (!hand_anim_set[i])
|
||
continue;
|
||
|
||
int32_t* data = pv_data.dsc.add_func(dsc_x_get_func_name(DSC_X_TIME),
|
||
DSC_X_TIME, dsc_x_get_func_length(DSC_X_TIME));
|
||
data[0] = hand_anim_set_time[i];
|
||
|
||
int32_t* new_hand_anim_l_data = pv_data.dsc.add_func(dsc_x_get_func_name(DSC_X_HAND_ANIM),
|
||
DSC_X_HAND_ANIM, dsc_x_get_func_length(DSC_X_HAND_ANIM));
|
||
new_hand_anim_l_data[0] = i;
|
||
new_hand_anim_l_data[1] = 0;
|
||
new_hand_anim_l_data[2] = 9;
|
||
new_hand_anim_l_data[3] = -1;
|
||
new_hand_anim_l_data[4] = -1;
|
||
|
||
int32_t* new_hand_anim_r_data = pv_data.dsc.add_func(dsc_x_get_func_name(DSC_X_HAND_ANIM),
|
||
DSC_X_HAND_ANIM, dsc_x_get_func_length(DSC_X_HAND_ANIM));
|
||
new_hand_anim_r_data[0] = i;
|
||
new_hand_anim_r_data[1] = 1;
|
||
new_hand_anim_r_data[2] = 9;
|
||
new_hand_anim_r_data[3] = -1;
|
||
new_hand_anim_r_data[4] = -1;
|
||
}
|
||
|
||
if (state_vec.size()) {
|
||
int32_t time = -1;
|
||
for (miku_state& i : state_vec) {
|
||
if (i.disp_time != time) {
|
||
int32_t* data = pv_data.dsc.add_func(dsc_x_get_func_name(DSC_X_TIME),
|
||
DSC_X_TIME, dsc_x_get_func_length(DSC_X_TIME));
|
||
data[0] = i.disp_time;
|
||
time = i.disp_time;
|
||
}
|
||
|
||
int32_t* new_data = pv_data.dsc.add_func(dsc_x_get_func_name(DSC_X_SET_MOTION),
|
||
DSC_X_SET_MOTION, dsc_x_get_func_length(DSC_X_SET_MOTION));
|
||
int32_t* data = pv_data.dsc.data_buffer.data() + i.set_motion_data_offset;
|
||
memcpy(new_data, data, sizeof(int32_t) * dsc_x_get_func_length(DSC_X_SET_MOTION));
|
||
}
|
||
|
||
pv_data.dsc.rebuild();
|
||
}
|
||
|
||
#if BAKE_PV826
|
||
if (pv_id == 826 && (miku_disp.size() || set_motion.size() || set_playdata.size())) {
|
||
time = -1;
|
||
for (std::pair<int32_t, uint32_t>& i : miku_disp) {
|
||
if (i.first != time) {
|
||
int32_t* data = pv_data.dsc.add_func(dsc_x_get_func_name(DSC_X_TIME),
|
||
DSC_X_TIME, dsc_x_get_func_length(DSC_X_TIME));
|
||
data[0] = i.first;
|
||
time = i.first;
|
||
}
|
||
|
||
for (int32_t j = 1; j < 6; j++) {
|
||
int32_t* new_data = pv_data.dsc.add_func(dsc_x_get_func_name(DSC_X_MIKU_DISP),
|
||
DSC_X_MIKU_DISP, dsc_x_get_func_length(DSC_X_MIKU_DISP));
|
||
int32_t* data = pv_data.dsc.data_buffer.data() + i.second;
|
||
memcpy(new_data, data, sizeof(int32_t) * dsc_x_get_func_length(DSC_X_MIKU_DISP));
|
||
new_data[0] = j;
|
||
}
|
||
}
|
||
|
||
time = -1;
|
||
for (std::pair<int32_t, uint32_t>& i : set_motion) {
|
||
if (i.first != time) {
|
||
int32_t* data = pv_data.dsc.add_func(dsc_x_get_func_name(DSC_X_TIME),
|
||
DSC_X_TIME, dsc_x_get_func_length(DSC_X_TIME));
|
||
data[0] = i.first;
|
||
time = i.first;
|
||
}
|
||
|
||
for (int32_t j = 1; j < 6; j++) {
|
||
int32_t* new_data = pv_data.dsc.add_func(dsc_x_get_func_name(DSC_X_SET_MOTION),
|
||
DSC_X_SET_MOTION, dsc_x_get_func_length(DSC_X_SET_MOTION));
|
||
int32_t* data = pv_data.dsc.data_buffer.data() + i.second;
|
||
memcpy(new_data, data, sizeof(int32_t) * dsc_x_get_func_length(DSC_X_SET_MOTION));
|
||
new_data[0] = j;
|
||
}
|
||
}
|
||
|
||
time = -1;
|
||
for (std::pair<int32_t, uint32_t>& i : set_playdata) {
|
||
if (i.first != time) {
|
||
int32_t* data = pv_data.dsc.add_func(dsc_x_get_func_name(DSC_X_TIME),
|
||
DSC_X_TIME, dsc_x_get_func_length(DSC_X_TIME));
|
||
data[0] = i.first;
|
||
time = i.first;
|
||
}
|
||
|
||
for (int32_t j = 1; j < 6; j++) {
|
||
int32_t* new_data = pv_data.dsc.add_func(dsc_x_get_func_name(DSC_X_SET_PLAYDATA),
|
||
DSC_X_SET_PLAYDATA, dsc_x_get_func_length(DSC_X_SET_PLAYDATA));
|
||
int32_t* data = pv_data.dsc.data_buffer.data() + i.second;
|
||
memcpy(new_data, data, sizeof(int32_t) * dsc_x_get_func_length(DSC_X_SET_PLAYDATA));
|
||
new_data[0] = j;
|
||
}
|
||
}
|
||
|
||
pv_data.dsc.rebuild();
|
||
}
|
||
#endif
|
||
|
||
/*sprintf_s(file_buf, sizeof(file_buf), "pv_%03d_easy.dsc", pv_data.pv_id);
|
||
void* data = 0;
|
||
size_t size = 0;
|
||
dsc.unparse(&data, &size);
|
||
stream s;
|
||
s.open(file_buf, "wb");
|
||
s.write(data, size);
|
||
free_def(data);*/
|
||
}
|
||
|
||
get_data().pv_data.init(this, true);
|
||
|
||
Shadow* shad = shadow_ptr_get();
|
||
if (shad) {
|
||
shad->blur_filter_enable[0] = true;
|
||
shad->blur_filter_enable[1] = true;
|
||
}
|
||
|
||
state_old = 9;
|
||
} break;
|
||
case 9: {
|
||
if (skin_param_manager_array_check_task_ready())
|
||
break;
|
||
|
||
bool wait_load = false;
|
||
|
||
for (int32_t i = 0; i < pv_count; i++)
|
||
if (!data[i].state || data[i].state == 10) {
|
||
data[i].state = 10;
|
||
data[i].field_1C |= 0x08;
|
||
wait_load |= true;
|
||
}
|
||
|
||
if (wait_load)
|
||
break;
|
||
|
||
for (int32_t i = 0; i < ROB_CHARA_COUNT; i++) {
|
||
if (rob_chara_ids[i] == -1)
|
||
continue;
|
||
|
||
int32_t chara_id = rob_chara_ids[i];
|
||
rob_chara* rob_chr = rob_chara_array_get(chara_id);
|
||
if (!rob_chr)
|
||
continue;
|
||
|
||
pv_osage_manager_array_reset(chara_id);
|
||
pv_osage_manager_array_set_pv_set_motion(chara_id, get_data().pv_data.set_motion[chara_id]);
|
||
pv_osage_manager_array_set_pv_id(chara_id, get_data().pv_id == 832 ? 800 : get_data().pv_id, true);
|
||
}
|
||
|
||
state = 10;
|
||
state_old = 10;
|
||
} break;
|
||
case 10: {
|
||
if (pv_osage_manager_array_get_disp() || osage_play_data_manager_check_task_ready())
|
||
break;
|
||
|
||
bool wait_load = false;
|
||
|
||
for (int32_t i = 0; i < pv_count; i++)
|
||
if (data[i].state != 30)
|
||
wait_load |= true;
|
||
|
||
if (wait_load)
|
||
break;
|
||
|
||
#if BAKE_X_PACK
|
||
state_old = 18;
|
||
} break;
|
||
case 18: {
|
||
x_pv_game_data& pv_data = this->get_data();
|
||
|
||
XPVGameBaker* baker = x_pv_game_baker_ptr;
|
||
|
||
x_pv_game_write_dsc(pv_data.pv_data.dsc, pv_data.pv_id);
|
||
|
||
std::vector<auth_3d*> chara_effect_auth_3ds;
|
||
std::vector<auth_3d*> song_effect_auth_3ds;
|
||
std::vector<auth_3d*> stage_data_effect_auth_3ds;
|
||
std::vector<auth_3d*> stage_data_change_effect_auth_3ds;
|
||
|
||
auto add_auth_3d = [&](std::vector<auth_3d*>& auth_3ds, auth_3d_id id) {
|
||
if (!id.check_not_empty() || !id.check_loaded())
|
||
return;
|
||
|
||
auth_3d* auth = id.get_auth_3d();
|
||
if (auth && (auth->object.size() || auth->object_hrc.size()))
|
||
auth_3ds.push_back(auth);
|
||
};
|
||
|
||
for (auto& i : pv_data.chara_effect.auth_3d)
|
||
for (x_pv_game_chara_effect_auth_3d& j : i)
|
||
add_auth_3d(chara_effect_auth_3ds, j.id);
|
||
|
||
for (x_pv_game_song_effect& i : pv_data.effect.song_effect)
|
||
for (x_pv_game_song_effect_auth_3d& j : i.auth_3d)
|
||
add_auth_3d(song_effect_auth_3ds, j.id);
|
||
|
||
for (int32_t i = 0; i < X_PV_GAME_STAGE_EFFECT_COUNT; i++) {
|
||
x_pv_game_stage_effect& eff = stage_data.effect[i];
|
||
for (x_pv_game_stage_effect_auth_3d& j : eff.auth_3d)
|
||
add_auth_3d(stage_data_effect_auth_3ds, j.id);
|
||
}
|
||
|
||
for (int32_t i = 0; i < X_PV_GAME_STAGE_EFFECT_COUNT; i++)
|
||
for (int32_t j = 0; j < X_PV_GAME_STAGE_EFFECT_COUNT; j++) {
|
||
x_pv_game_stage_change_effect& chg_eff = stage_data.change_effect[i][j];
|
||
for (x_pv_game_stage_effect_auth_3d& k : chg_eff.auth_3d)
|
||
add_auth_3d(stage_data_change_effect_auth_3ds, k.id);
|
||
}
|
||
|
||
prj::sort_unique(chara_effect_auth_3ds);
|
||
prj::sort_unique(song_effect_auth_3ds);
|
||
prj::sort_unique(stage_data_effect_auth_3ds);
|
||
prj::sort_unique(stage_data_change_effect_auth_3ds);
|
||
|
||
for (auth_3d*& i : stage_data_effect_auth_3ds) {
|
||
auto j_begin = stage_data_change_effect_auth_3ds.begin();
|
||
auto j_end = stage_data_change_effect_auth_3ds.end();
|
||
for (auto j = j_begin; j != j_end;) {
|
||
if (*j != i)
|
||
j++;
|
||
else {
|
||
j = stage_data_change_effect_auth_3ds.erase(j);
|
||
j_end = stage_data_change_effect_auth_3ds.end();
|
||
}
|
||
}
|
||
}
|
||
|
||
std::vector<uint32_t> pv_object_set_ids;
|
||
std::vector<uint32_t> stage_object_set_ids;
|
||
std::vector<Glitter::EffectGroup*> pv_glitter_eff_groups;
|
||
std::vector<Glitter::EffectGroup*> stage_glitter_eff_groups;
|
||
|
||
{
|
||
char name[0x40];
|
||
sprintf_s(name, sizeof(name), "STGPV%03d", stage_data.stage_id);
|
||
if (stage_data.obj_db.get_object_set_id(name) != -1)
|
||
stage_object_set_ids.push_back(hash_utf8_murmurhash(name));
|
||
|
||
sprintf_s(name, sizeof(name), "STGPV%03dHRC", stage_data.stage_id);
|
||
if (stage_data.obj_db.get_object_set_id(name) != -1)
|
||
stage_object_set_ids.push_back(hash_utf8_murmurhash(name));
|
||
}
|
||
|
||
auto add_auth_3d_object_set_id = [&](auth_3d* auth, std::vector<uint32_t>& object_set_ids) {
|
||
object_set_ids.reserve(auth->object.size() + auth->object_hrc.size());
|
||
|
||
for (auth_3d_object& i : auth->object)
|
||
object_set_ids.push_back(i.object_info.set_id);
|
||
|
||
for (auth_3d_object_hrc& i : auth->object_hrc)
|
||
object_set_ids.push_back(i.object_info.set_id);
|
||
};
|
||
|
||
auto add_glitter_object_set_id = [&](uint32_t eff_group_hash,
|
||
std::vector<Glitter::EffectGroup*>& glitter_eff_groups, std::vector<uint32_t>& object_set_ids) {
|
||
Glitter::EffectGroup* eff_group = Glitter::glt_particle_manager->GetEffectGroup(eff_group_hash);
|
||
if (eff_group) {
|
||
glitter_eff_groups.push_back(eff_group);
|
||
|
||
object_set_ids.reserve(eff_group->meshes.size());
|
||
|
||
for (Glitter::Mesh& i : eff_group->meshes)
|
||
object_set_ids.push_back(i.object_set_hash);
|
||
}
|
||
};
|
||
|
||
for (auth_3d*& i : chara_effect_auth_3ds)
|
||
add_auth_3d_object_set_id(i, pv_object_set_ids);
|
||
|
||
for (auth_3d*& i : song_effect_auth_3ds)
|
||
add_auth_3d_object_set_id(i, pv_object_set_ids);
|
||
|
||
for (auth_3d*& i : stage_data_effect_auth_3ds)
|
||
add_auth_3d_object_set_id(i, stage_object_set_ids);
|
||
|
||
for (auth_3d*& i : stage_data_change_effect_auth_3ds)
|
||
add_auth_3d_object_set_id(i, stage_object_set_ids);
|
||
|
||
for (string_hash& i : pv_data.effect.pv_glitter)
|
||
add_glitter_object_set_id(i.hash_murmurhash, pv_glitter_eff_groups, pv_object_set_ids);
|
||
|
||
for (x_pv_game_song_effect& i : pv_data.effect.song_effect)
|
||
for (x_pv_game_song_effect_glitter& j : i.glitter)
|
||
add_glitter_object_set_id(j.name.hash_murmurhash, pv_glitter_eff_groups, pv_object_set_ids);
|
||
|
||
for (uint32_t& i : stage_data.stage_glitter)
|
||
add_glitter_object_set_id(i, stage_glitter_eff_groups, stage_object_set_ids);
|
||
|
||
prj::sort_unique(pv_object_set_ids);
|
||
prj::sort_unique(stage_object_set_ids);
|
||
|
||
std::vector<uint32_t> object_set_ids;
|
||
object_set_ids.insert(object_set_ids.end(), pv_object_set_ids.begin(), pv_object_set_ids.end());
|
||
object_set_ids.insert(object_set_ids.end(), stage_object_set_ids.begin(), stage_object_set_ids.end());
|
||
|
||
prj::sort_unique(object_set_ids);
|
||
|
||
for (uint32_t& i : object_set_ids) {
|
||
ObjsetInfo* info = object_storage_get_objset_info(i);
|
||
if (!info)
|
||
continue;
|
||
|
||
obj_set* set = info->obj_set;
|
||
|
||
prj::shared_ptr<prj::stack_allocator>& alloc = info->alloc_handler;
|
||
|
||
uint32_t obj_num = set->obj_num;
|
||
obj** obj_data = set->obj_data;
|
||
|
||
obj_vertex_buffer* objvb = info->objvb;
|
||
for (uint32_t j = 0; j < obj_num; j++)
|
||
objvb[j].unload();
|
||
|
||
obj_index_buffer* objib = info->objib;
|
||
for (uint32_t j = 0; j < obj_num; j++)
|
||
objib[j].unload();
|
||
|
||
for (uint32_t j = 0; j < obj_num; j++, obj_data++) {
|
||
obj* obj = *obj_data;
|
||
obj_mesh* mesh_array = obj->mesh_array;
|
||
uint32_t num_mesh = obj->num_mesh;
|
||
for (uint32_t k = 0; k < num_mesh; k++) {
|
||
obj_mesh* mesh = &mesh_array[k];
|
||
|
||
obj_sub_mesh* submesh_array = mesh->submesh_array;
|
||
uint32_t num_submesh = mesh->num_submesh;
|
||
for (uint32_t l = 0; l < num_submesh; l++) {
|
||
obj_sub_mesh* submesh = &submesh_array[l];
|
||
|
||
if (submesh->primitive_type != OBJ_PRIMITIVE_TRIANGLES || !submesh->num_index)
|
||
continue;
|
||
|
||
submesh->primitive_type = OBJ_PRIMITIVE_TRIANGLE_STRIP;
|
||
|
||
uint32_t* index_array = submesh->index_array;
|
||
submesh->index_array = alloc->allocate<uint32_t>(
|
||
meshopt_stripifyBound(submesh->num_index));
|
||
submesh->num_index = (uint32_t)meshopt_stripify(submesh->index_array,
|
||
index_array, submesh->num_index, mesh->num_vertex, 0xFFFFFFFF);
|
||
|
||
submesh->first_index = 0;
|
||
submesh->last_index = 0;
|
||
submesh->index_offset = 0;
|
||
}
|
||
}
|
||
}
|
||
|
||
obj_data = set->obj_data;
|
||
|
||
for (uint32_t j = 0; j < obj_num; j++)
|
||
objvb[j].load(obj_data[j]);
|
||
|
||
for (uint32_t j = 0; j < obj_num; j++)
|
||
objib[j].load(obj_data[j]);
|
||
}
|
||
|
||
object_set_ids.clear();
|
||
|
||
for (uint32_t& i : pv_object_set_ids) {
|
||
ObjsetInfo* info = object_storage_get_objset_info(i);
|
||
if (!info)
|
||
continue;
|
||
|
||
x_pv_game_update_object_set(info);
|
||
x_pv_game_write_object_set(info, &baker->obj_db,
|
||
&pv_data.tex_db, &baker->tex_db_base, &baker->tex_db);
|
||
}
|
||
|
||
for (uint32_t& i : stage_object_set_ids) {
|
||
ObjsetInfo* info = object_storage_get_objset_info(i);
|
||
if (!info)
|
||
continue;
|
||
|
||
x_pv_game_update_object_set(info);
|
||
x_pv_game_write_object_set(info, &baker->obj_db,
|
||
&stage_data.tex_db, &baker->tex_db_base, &baker->tex_db);
|
||
}
|
||
|
||
auth_3d_database_file& x_pack_auth_3d_db_file = baker->auth_3d_db;
|
||
|
||
{
|
||
auth_3d* auth = get_data().camera.id.get_auth_3d();
|
||
|
||
char category[0x40];
|
||
sprintf_s(category, sizeof(category), "CAMPV%03d", pv_data.pv_id);
|
||
replace_names(category);
|
||
|
||
char name[0x40];
|
||
sprintf_s(name, sizeof(name), "CAMPV%03d_BASE", pv_data.pv_id);
|
||
replace_names(name);
|
||
|
||
x_pack_auth_3d_db_file.category.push_back(category);
|
||
|
||
x_pack_auth_3d_db_file.uid.push_back({});
|
||
auth_3d_database_uid_file& uid = x_pack_auth_3d_db_file.uid.back();
|
||
uid.flags = (auth_3d_database_uid_flags)(AUTH_3D_DATABASE_UID_SIZE | AUTH_3D_DATABASE_UID_ORG_UID);
|
||
uid.category.assign(category);
|
||
uid.org_uid = x_pack_auth_3d_db_file.uid_max++;
|
||
uid.size = auth->play_control.size;
|
||
uid.value.assign("A ");
|
||
uid.value.append(name);
|
||
}
|
||
|
||
if (song_effect_auth_3ds.size()) {
|
||
char name[0x40];
|
||
sprintf_s(name, sizeof(name), "EFFPV%03d", pv_data.pv_id);
|
||
replace_names(name);
|
||
|
||
x_pack_auth_3d_db_file.category.push_back(name);
|
||
|
||
char path[MAX_PATH];
|
||
strcpy_s(path, sizeof(path), "patch\\!temp\\auth_3d\\");
|
||
strcat_s(path, sizeof(path), name);
|
||
|
||
farc* effpv_farc = new farc;
|
||
for (auth_3d*& i : song_effect_auth_3ds)
|
||
x_pv_game_write_auth_3d(effpv_farc, i, &x_pack_auth_3d_db_file, name);
|
||
|
||
effpv_farc->write(path, FARC_FArC, FARC_NONE, false);
|
||
delete effpv_farc;
|
||
}
|
||
|
||
for (auth_3d*& i : chara_effect_auth_3ds)
|
||
x_pv_game_write_auth_3d(0, i, &x_pack_auth_3d_db_file, 0);
|
||
|
||
{
|
||
char name[0x40];
|
||
sprintf_s(name, sizeof(name), "EFFSTGPV%03d", stage_data.stage_id);
|
||
replace_names(name);
|
||
|
||
x_pack_auth_3d_db_file.category.push_back(name);
|
||
|
||
char path[MAX_PATH];
|
||
strcpy_s(path, sizeof(path), "patch\\!temp\\auth_3d\\");
|
||
strcat_s(path, sizeof(path), name);
|
||
|
||
farc* effstgpv_farc = new farc;
|
||
for (stage_data_modern& i : stage_data.stage_data.stg_db.stage_modern)
|
||
for (uint32_t& j : i.auth_3d_ids) {
|
||
auth_3d* auth = auth_3d_data_get_auth_3d(j);
|
||
if (auth)
|
||
x_pv_game_write_auth_3d(effstgpv_farc, auth, &x_pack_auth_3d_db_file, name);
|
||
}
|
||
|
||
for (auth_3d*& i : stage_data_effect_auth_3ds)
|
||
x_pv_game_write_auth_3d(effstgpv_farc, i, &x_pack_auth_3d_db_file, name);
|
||
|
||
for (auth_3d*& i : stage_data_change_effect_auth_3ds)
|
||
x_pv_game_write_auth_3d(effstgpv_farc, i, &x_pack_auth_3d_db_file, name);
|
||
|
||
x_pv_game_write_auth_3d(effstgpv_farc,
|
||
light_auth_3d_id.get_auth_3d(), &x_pack_auth_3d_db_file, name);
|
||
|
||
if (effstgpv_farc->files.size())
|
||
effstgpv_farc->write(path, FARC_FArC, FARC_NONE, false);
|
||
delete effstgpv_farc;
|
||
}
|
||
|
||
auth_3d_database x_pack_auth_3d_db;
|
||
x_pack_auth_3d_db.add(&baker->auth_3d_db_base, false);
|
||
x_pack_auth_3d_db.add(&baker->auth_3d_db, true);
|
||
|
||
object_database x_pack_obj_db;
|
||
x_pack_obj_db.add(&baker->obj_db);
|
||
|
||
texture_database x_pack_tex_db;
|
||
x_pack_tex_db.add(&baker->tex_db);
|
||
|
||
for (Glitter::EffectGroup*& i : pv_glitter_eff_groups)
|
||
x_pv_game_write_glitter(i, &x_pack_auth_3d_db, &pv_data.obj_db, &x_pack_obj_db);
|
||
|
||
for (Glitter::EffectGroup*& i : stage_glitter_eff_groups)
|
||
x_pv_game_write_glitter(i, &x_pack_auth_3d_db, &stage_data.obj_db, &x_pack_obj_db);
|
||
|
||
x_pv_game_write_play_param(pv_data.play_param, pv_data.pv_id, &x_pack_auth_3d_db);
|
||
x_pv_game_write_stage_resource(stage_data.stage_resource, stage_data.stage_id, &x_pack_auth_3d_db);
|
||
|
||
x_pv_game_write_spr(stage_data.env.spr_gam_stgpv_id_hash,
|
||
&stage_data.env.spr_db, &baker->spr_db);
|
||
x_pv_game_write_aet(stage_data.env.aet_gam_stgpv_id_hash,
|
||
&stage_data.env.aet_db, &baker->aet_db, &baker->spr_db);
|
||
|
||
stage_database_file& x_pack_stg_db = baker->stage_data;
|
||
object_database& x_stage_obj_db = stage_data.obj_db;
|
||
texture_database& x_stage_tex_db = stage_data.tex_db;
|
||
stage_database& x_stg_db = stage_data.stage_data.stg_db;
|
||
|
||
int32_t stage_max_id = -1;
|
||
for (stage_data_file& i : baker->stage_data.stage_data)
|
||
stage_max_id = max_def(stage_max_id, i.id);
|
||
|
||
for (const stage_data_modern& i : x_stg_db.stage_modern) {
|
||
x_pack_stg_db.stage_data.push_back({});
|
||
stage_data_file& stage_data = x_pack_stg_db.stage_data.back();
|
||
stage_data.id = ++stage_max_id;
|
||
stage_data.name.assign(i.name);
|
||
replace_names(stage_data.name);
|
||
stage_data.auth_3d_name.assign("EFF");
|
||
stage_data.auth_3d_name.append(stage_data.name);
|
||
stage_data.object_set_id = x_pack_obj_db.get_object_set_id(stage_data.name.c_str());
|
||
stage_data.object_ground = replace_object_info(i.object_ground, &x_stage_obj_db, &x_pack_obj_db);
|
||
stage_data.object_ring = object_info();
|
||
stage_data.object_sky = replace_object_info(i.object_sky, &x_stage_obj_db, &x_pack_obj_db);
|
||
stage_data.object_shadow = replace_object_info(i.object_shadow, &x_stage_obj_db, &x_pack_obj_db);
|
||
stage_data.object_reflect = replace_object_info(i.object_reflect, &x_stage_obj_db, &x_pack_obj_db);
|
||
stage_data.object_refract = replace_object_info(i.object_refract, &x_stage_obj_db, &x_pack_obj_db);
|
||
stage_data.lens_flare_texture = -1;
|
||
stage_data.lens_shaft_texture = -1;
|
||
stage_data.lens_ghost_texture = -1;
|
||
stage_data.lens_shaft_inv_scale = 1.0f;
|
||
stage_data.unknown = 0;
|
||
|
||
stage_data.render_texture = replace_texture_id(i.render_texture, &x_stage_tex_db, &x_pack_tex_db);
|
||
if (stage_data.render_texture == -1) {
|
||
char name[0x40];
|
||
sprintf_s(name, sizeof(name), "F_DIVA_STGPV%03d_AM_FB05", this->stage_data.stage_id);
|
||
replace_names(name);
|
||
stage_data.render_texture = x_pack_tex_db.get_texture_id(name);
|
||
}
|
||
|
||
stage_data.movie_texture = replace_texture_id(i.movie_texture, &x_stage_tex_db, &x_pack_tex_db);
|
||
if (stage_data.movie_texture == -1) {
|
||
char name[0x40];
|
||
sprintf_s(name, sizeof(name), "F_DIVA_STGPV%03d_AM_FB04", this->stage_data.stage_id);
|
||
replace_names(name);
|
||
stage_data.movie_texture = x_pack_tex_db.get_texture_id(name);
|
||
}
|
||
|
||
stage_data.collision_file_path.assign("rom/STGTST_COLI.000.bin");
|
||
stage_data.reflect_type = STAGE_DATA_REFLECT_DISABLE;
|
||
stage_data.flags = (stage_data_flags)0;
|
||
stage_data.ring_rectangle_x = i.ring_rectangle_x;
|
||
stage_data.ring_rectangle_y = i.ring_rectangle_y;
|
||
stage_data.ring_rectangle_width = i.ring_rectangle_width;
|
||
stage_data.ring_rectangle_height = i.ring_rectangle_height;
|
||
stage_data.ring_height = i.ring_height;
|
||
stage_data.ring_out_height = i.ring_out_height;
|
||
|
||
stage_data.auth_3d_ids.reserve(i.auth_3d_ids.size());
|
||
for (const uint32_t& j : i.auth_3d_ids) {
|
||
auth_3d* auth = auth_3d_data_get_auth_3d(j);
|
||
if (!auth)
|
||
continue;
|
||
|
||
char name[0x200];
|
||
if (get_replace_auth_name(name, sizeof(name), auth)) {
|
||
int32_t uid = x_pack_auth_3d_db.get_uid(name);
|
||
if (uid != -1)
|
||
stage_data.auth_3d_ids.push_back(uid);
|
||
}
|
||
}
|
||
}
|
||
|
||
#endif
|
||
state_old = 19;
|
||
} break;
|
||
case 19: {
|
||
x_pv_game_change_field(this, 1, -1, -1);
|
||
|
||
Glitter::glt_particle_manager->SetPause(false);
|
||
get_data().bar_beat.reset_time();
|
||
|
||
extern float_t frame_speed;
|
||
frame_speed = 1.0f;
|
||
|
||
pause = false;
|
||
step_frame = false;
|
||
|
||
frame_float = 0.0;
|
||
frame = (int32_t)frame_float;
|
||
time = (int64_t)round(frame_float * (100000.0 / 60.0) * 10000.0);
|
||
|
||
x_pv_game_pv_data& pv_data = get_data().pv_data;
|
||
|
||
pv_data.dsc_data_ptr = pv_data.dsc.data.data();
|
||
pv_data.dsc_data_ptr_end = pv_data.dsc_data_ptr + pv_data.dsc.data.size();
|
||
|
||
pv_data.ctrl(false, 0.0f, 0.0f);
|
||
|
||
light_auth_3d_id.set_enable(true);
|
||
light_auth_3d_id.set_camera_root_update(false);
|
||
light_auth_3d_id.set_paused(false);
|
||
light_auth_3d_id.set_repeat(false);
|
||
light_auth_3d_id.set_visibility(true);
|
||
light_auth_3d_id.set_req_frame(0.0f);
|
||
|
||
#if BAKE_PV826
|
||
if (pv_id == 826) {
|
||
data_struct* aft_data = &data_list[DATA_AFT];
|
||
bone_database* aft_bone_data = &aft_data->data_ft.bone_data;
|
||
motion_database* aft_mot_db = &aft_data->data_ft.mot_db;
|
||
|
||
for (int32_t& i : effchrpv_rob_mot_ids) {
|
||
char buf[0x100];
|
||
sprintf_s(buf, sizeof(buf), "PV826_OST_P%d_00", i + 1);
|
||
uint32_t motion_id = aft_mot_db->get_motion_id(buf);
|
||
rob_chara* rob_chr = rob_chara_array_get(rob_chara_ids[i]);
|
||
rob_chr->set_motion_id(motion_id, 0.0f,
|
||
0.0f, false, false, MOTION_BLEND_CROSS, aft_bone_data, aft_mot_db);
|
||
rob_chr->set_motion_reset_data(motion_id, 0.0f);
|
||
rob_chr->set_motion_skin_param(motion_id, 0.0f);
|
||
|
||
sprintf_s(buf, sizeof(buf), "A3D_EFFCHRPV%03dMIK%03d", pv_id, i);
|
||
uint32_t hash = hash_utf8_murmurhash(buf);
|
||
for (auto j : effchrpv_auth_3d_mot_names)
|
||
if (j.second.hash_murmurhash == hash) {
|
||
uint32_t hash = hash_string_murmurhash(j.first);
|
||
effchrpv_auth_3d_rob_mot_ids.insert({ i, { effchrpv_auth_3d_mot_ids[hash] } });
|
||
break;
|
||
}
|
||
}
|
||
|
||
for (auto& i : effchrpv_auth_3d_rob_mot_ids) {
|
||
x_pv_game_a3da_to_mot& a2m = i.second;
|
||
auth_3d* auth = a2m.id.get_auth_3d();
|
||
a2m.get_bone_indices(&auth->object_hrc[0]);
|
||
}
|
||
|
||
for (auto& i : effchrpv_auth_3d_mot_ids) {
|
||
auth_3d_id& id = i.second;
|
||
id.set_repeat(false);
|
||
id.set_camera_root_update(false);
|
||
id.set_enable(true);
|
||
id.set_paused(false);
|
||
id.set_visibility(false);
|
||
id.set_req_frame(0.0f);
|
||
}
|
||
}
|
||
#endif
|
||
|
||
#if BAKE_PNG || BAKE_VIDEO
|
||
extern bool disable_cursor;
|
||
disable_cursor = true;
|
||
|
||
const int32_t width = BAKE_BASE_WIDTH * BAKE_RES_SCALE;
|
||
const int32_t height = BAKE_BASE_HEIGHT * BAKE_RES_SCALE;
|
||
|
||
#if BAKE_VIDEO
|
||
if (GLAD_WGL_NV_DX_interop2) {
|
||
glGenRenderbuffers(d3d_in_flight_num, d3d_gl_rbo);
|
||
glGenFramebuffers(d3d_in_flight_num, d3d_gl_fbo);
|
||
glGenQueries(d3d_in_flight_num, d3d_query);
|
||
|
||
#if BAKE_VIDEO_ALPHA
|
||
glGenRenderbuffers(d3d_in_flight_num, d3d_gl_alpha_rbo);
|
||
glGenFramebuffers(d3d_in_flight_num, d3d_gl_alpha_fbo);
|
||
glGenQueries(d3d_in_flight_num, d3d_alpha_query);
|
||
#endif
|
||
|
||
D3D11_TEXTURE2D_DESC tex_desc = { };
|
||
tex_desc.Width = width;
|
||
tex_desc.Height = height;
|
||
tex_desc.MipLevels = 1;
|
||
tex_desc.ArraySize = 1;
|
||
tex_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||
tex_desc.SampleDesc.Count = 1;
|
||
tex_desc.SampleDesc.Quality = 0;
|
||
tex_desc.Usage = D3D11_USAGE_DEFAULT;
|
||
tex_desc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
|
||
tex_desc.CPUAccessFlags = 0;
|
||
tex_desc.MiscFlags = 0;
|
||
|
||
for (int32_t i = 0; i < d3d_in_flight_num; i++)
|
||
d3d_device->CreateTexture2D(&tex_desc, 0, &d3d_texture[i]);
|
||
|
||
for (int32_t i = 0; i < d3d_in_flight_num; i++)
|
||
d3d_gl_rbo_handle[i] = wglDXRegisterObjectNV(d3d_gl_handle, d3d_texture[i],
|
||
d3d_gl_rbo[i], GL_RENDERBUFFER, WGL_ACCESS_READ_WRITE_NV);
|
||
|
||
for (int32_t i = 0; i < d3d_in_flight_num; i++) {
|
||
wglDXLockObjectsNV(d3d_gl_handle, 1, &d3d_gl_rbo_handle[i]);
|
||
gl_state_bind_framebuffer(d3d_gl_fbo[i]);
|
||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, d3d_gl_rbo[i]);
|
||
gl_state_bind_framebuffer(0);
|
||
wglDXUnlockObjectsNV(d3d_gl_handle, 1, &d3d_gl_rbo_handle[i]);
|
||
}
|
||
|
||
#if BAKE_VIDEO_ALPHA
|
||
for (int32_t i = 0; i < d3d_in_flight_num; i++)
|
||
d3d_device->CreateTexture2D(&tex_desc, 0, &d3d_alpha_texture[i]);
|
||
|
||
for (int32_t i = 0; i < d3d_in_flight_num; i++)
|
||
d3d_gl_alpha_rbo_handle[i] = wglDXRegisterObjectNV(d3d_gl_handle, d3d_alpha_texture[i],
|
||
d3d_gl_alpha_rbo[i], GL_RENDERBUFFER, WGL_ACCESS_READ_WRITE_NV);
|
||
|
||
for (int32_t i = 0; i < d3d_in_flight_num; i++) {
|
||
wglDXLockObjectsNV(d3d_gl_handle, 1, &d3d_gl_alpha_rbo_handle[i]);
|
||
gl_state_bind_framebuffer(d3d_gl_alpha_fbo[i]);
|
||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, d3d_gl_alpha_rbo[i]);
|
||
gl_state_bind_framebuffer(0);
|
||
wglDXUnlockObjectsNV(d3d_gl_handle, 1, &d3d_gl_alpha_rbo_handle[i]);
|
||
}
|
||
#endif
|
||
}
|
||
else {
|
||
D3D11_TEXTURE2D_DESC tex_desc = { };
|
||
tex_desc.Width = width;
|
||
tex_desc.Height = height;
|
||
tex_desc.MipLevels = 1;
|
||
tex_desc.ArraySize = 1;
|
||
tex_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||
tex_desc.SampleDesc.Count = 1;
|
||
tex_desc.SampleDesc.Quality = 0;
|
||
tex_desc.Usage = D3D11_USAGE_DYNAMIC;
|
||
tex_desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
|
||
tex_desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
|
||
tex_desc.MiscFlags = 0;
|
||
|
||
d3d_device->CreateTexture2D(&tex_desc, 0, &d3d_texture[0]);
|
||
|
||
nvenc_temp_pixels.resize((size_t)width* (size_t)height* nvenc_src_pixel_size);
|
||
}
|
||
|
||
#if BAKE_VIDEO_ALPHA
|
||
nvenc_enc = new nvenc_encoder(width, height, d3d_device);
|
||
nvenc_alpha_enc = new nvenc_encoder(width, height, d3d_device);
|
||
|
||
char buf[0x100];
|
||
sprintf_s(buf, sizeof(buf), "G:\\ReDIVA\\Videos\\ReDIVA_pv%03d_color.265", get_data().pv_id);
|
||
|
||
nvenc_stream = new file_stream();
|
||
nvenc_stream->open(buf, "wb");
|
||
|
||
sprintf_s(buf, sizeof(buf), "G:\\ReDIVA\\Videos\\ReDIVA_pv%03d_alpha.265", get_data().pv_id);
|
||
|
||
nvenc_alpha_stream = new file_stream();
|
||
nvenc_alpha_stream->open(buf, "wb");
|
||
#else
|
||
nvenc_enc = new nvenc_encoder(width, height, d3d_device);
|
||
|
||
char buf[0x100];
|
||
sprintf_s(buf, sizeof(buf), "G:\\ReDIVA\\Videos\\ReDIVA_pv%03d.265", get_data().pv_id);
|
||
|
||
nvenc_stream = new file_stream();
|
||
nvenc_stream->open(buf, "wb");
|
||
#endif
|
||
#endif
|
||
#endif
|
||
|
||
#if BAKE_PV826
|
||
x_pv_game_map_auth_3d_to_mot(this, true);
|
||
#endif
|
||
|
||
#if !BAKE_FAST
|
||
pause = true;
|
||
#endif
|
||
|
||
state_old = 20;
|
||
//sound_work_release_se("load01_2", false);
|
||
} break;
|
||
case 20: {
|
||
float_t delta_frame = get_delta_frame();
|
||
frame_float += delta_frame;
|
||
frame = (int32_t)frame_float;
|
||
time = (int64_t)round(frame_float * (100000.0 / 60.0) * 10000.0);
|
||
|
||
#if !BAKE_FAST
|
||
x_pv_game_music_ptr->set_pause(pause ? 1 : 0);
|
||
#endif
|
||
|
||
#if BAKE_PV826
|
||
x_pv_game_map_auth_3d_to_mot(this, delta_frame != 0.0f);
|
||
#endif
|
||
|
||
#if BAKE_PNG || BAKE_VIDEO
|
||
img_write = true;
|
||
#endif
|
||
|
||
if (!get_data().pv_data.play || get_data().pv_data.pv_end)
|
||
state_old = 21;
|
||
} break;
|
||
case 21: {
|
||
#if BAKE_PNG || BAKE_VIDEO
|
||
extern bool disable_cursor;
|
||
disable_cursor = false;
|
||
|
||
#if BAKE_VIDEO
|
||
if (GLAD_WGL_NV_DX_interop2) {
|
||
bool wait = false;
|
||
for (int32_t i = 0; i < d3d_in_flight_num; i++)
|
||
if (d3d_tex_write[i])
|
||
wait |= true;
|
||
|
||
#if BAKE_VIDEO_ALPHA
|
||
for (int32_t i = 0; i < d3d_in_flight_num; i++)
|
||
if (d3d_alpha_tex_write[i])
|
||
wait |= true;
|
||
#endif
|
||
|
||
if (wait)
|
||
break;
|
||
}
|
||
|
||
#if BAKE_VIDEO_ALPHA
|
||
nvenc_alpha_stream->close();
|
||
delete nvenc_alpha_stream;
|
||
nvenc_alpha_stream = 0;
|
||
#endif
|
||
|
||
nvenc_stream->close();
|
||
delete nvenc_stream;
|
||
nvenc_stream = 0;
|
||
|
||
#if BAKE_VIDEO_ALPHA
|
||
delete nvenc_alpha_enc;
|
||
nvenc_alpha_enc = 0;
|
||
#endif
|
||
|
||
delete nvenc_enc;
|
||
nvenc_enc = 0;
|
||
|
||
if (GLAD_WGL_NV_DX_interop2) {
|
||
#if BAKE_VIDEO_ALPHA
|
||
for (int32_t i = 0; i < d3d_in_flight_num; i++) {
|
||
wglDXUnregisterObjectNV(d3d_gl_handle, d3d_gl_alpha_rbo_handle[i]);
|
||
d3d_gl_alpha_rbo_handle[i] = 0;
|
||
}
|
||
|
||
for (int32_t i = 0; i < d3d_in_flight_num; i++) {
|
||
d3d_alpha_texture[i]->Release();
|
||
d3d_alpha_texture[i] = 0;
|
||
}
|
||
|
||
glDeleteQueries(d3d_in_flight_num, d3d_alpha_query);
|
||
|
||
glDeleteFramebuffers(d3d_in_flight_num, d3d_gl_alpha_fbo);
|
||
memset(d3d_gl_alpha_fbo, 0, sizeof(d3d_gl_alpha_fbo));
|
||
|
||
glDeleteRenderbuffers(d3d_in_flight_num, d3d_gl_alpha_rbo);
|
||
memset(d3d_gl_alpha_rbo, 0, sizeof(d3d_gl_alpha_rbo));
|
||
#endif
|
||
|
||
for (int32_t i = 0; i < d3d_in_flight_num; i++) {
|
||
wglDXUnregisterObjectNV(d3d_gl_handle, d3d_gl_rbo_handle[i]);
|
||
d3d_gl_rbo_handle[i] = 0;
|
||
}
|
||
|
||
for (int32_t i = 0; i < d3d_in_flight_num; i++) {
|
||
d3d_texture[i]->Release();
|
||
d3d_texture[i] = 0;
|
||
}
|
||
|
||
glDeleteQueries(d3d_in_flight_num, d3d_query);
|
||
|
||
glDeleteFramebuffers(d3d_in_flight_num, d3d_gl_fbo);
|
||
memset(d3d_gl_fbo, 0, sizeof(d3d_gl_fbo));
|
||
|
||
glDeleteRenderbuffers(d3d_in_flight_num, d3d_gl_rbo);
|
||
memset(d3d_gl_rbo, 0, sizeof(d3d_gl_rbo));
|
||
}
|
||
else {
|
||
nvenc_temp_pixels.clear();
|
||
nvenc_temp_pixels.shrink_to_fit();
|
||
|
||
d3d_texture[0]->Release();
|
||
d3d_texture[0] = 0;
|
||
}
|
||
#endif
|
||
#endif
|
||
|
||
for (int32_t i = 0; i < ROB_CHARA_COUNT; i++)
|
||
pv_expression_array_reset_motion(i);
|
||
|
||
#if BAKE_DOF
|
||
{
|
||
x_pv_game_data& pv_data = this->get_data();
|
||
|
||
data_struct* x_data = &data_list[DATA_X];
|
||
|
||
char buf[0x200];
|
||
sprintf_s(buf, sizeof(buf), "CAMPV%03d", pv_data.pv_id);
|
||
|
||
farc* f = new farc;
|
||
x_data->load_file(f, "root+/auth_3d/", hash_utf8_murmurhash(buf), ".farc", farc::load_file);
|
||
|
||
if ((pv_data.pv_id % 100) >= 25 && (pv_data.pv_id % 100) <= 30
|
||
&& stage_data.stage_id >= 25 && stage_data.stage_id <= 30)
|
||
sprintf_s(buf, sizeof(buf), "CAMPV%03d_100.a3da", pv_data.pv_id);
|
||
else
|
||
sprintf_s(buf, sizeof(buf), "CAMPV%03d_BASE.a3da", pv_data.pv_id);
|
||
|
||
a3da a;
|
||
farc_file* ff = f->read_file(buf);
|
||
if (ff)
|
||
a.read(ff->data, ff->size);
|
||
delete f;
|
||
|
||
if ((pv_data.pv_id % 100) >= 25 && (pv_data.pv_id % 100) <= 30
|
||
&& stage_data.stage_id >= 25 && stage_data.stage_id <= 30)
|
||
sprintf_s(buf, sizeof(buf), "DOF\\auth_3d\\CAMPV%03d_100", pv_data.pv_id);
|
||
else
|
||
sprintf_s(buf, sizeof(buf), "DOF\\auth_3d\\CAMPV%03d_BASE", pv_data.pv_id);
|
||
|
||
replace_pv832(buf);
|
||
replace_pv832(a._file_name);
|
||
|
||
a.ready = true;
|
||
a.compressed = true;
|
||
a.format = A3DA_FORMAT_AFT_X_PACK;
|
||
a.dof = {};
|
||
a.dof.has_dof = true;
|
||
|
||
std::thread position_x(a3da_key_rev,
|
||
std::ref(a.dof.model_transform.translation.x), std::ref(dof_cam_data.position_x));
|
||
std::thread position_y(a3da_key_rev,
|
||
std::ref(a.dof.model_transform.translation.y), std::ref(dof_cam_data.position_y));
|
||
std::thread position_z(a3da_key_rev,
|
||
std::ref(a.dof.model_transform.translation.z), std::ref(dof_cam_data.position_z));
|
||
std::thread focus_range(a3da_key_rev,
|
||
std::ref(a.dof.model_transform.scale.x), std::ref(dof_cam_data.focus_range));
|
||
//std::thread focus(a3da_key_rev,
|
||
// std::ref(a.dof.model_transform.scale.y), std::ref(dof_cam_data.focus));
|
||
std::thread fuzzing_range(a3da_key_rev,
|
||
std::ref(a.dof.model_transform.rotation.x), std::ref(dof_cam_data.fuzzing_range));
|
||
std::thread ratio(a3da_key_rev,
|
||
std::ref(a.dof.model_transform.rotation.y), std::ref(dof_cam_data.ratio));
|
||
SetThreadDescription((HANDLE)position_x.native_handle(), L"DoF A3DA Bake Thread: Position X");
|
||
SetThreadDescription((HANDLE)position_y.native_handle(), L"DoF A3DA Bake Thread: Position Y");
|
||
SetThreadDescription((HANDLE)position_z.native_handle(), L"DoF A3DA Bake Thread: Position Z");
|
||
SetThreadDescription((HANDLE)focus_range.native_handle(), L"DoF A3DA Bake Thread: Focus Range");
|
||
//SetThreadDescription((HANDLE)focus.native_handle(), L"DoF A3DA Bake Thread: Focus");
|
||
SetThreadDescription((HANDLE)fuzzing_range.native_handle(), L"DoF A3DA Bake Thread: Fuzzing Range");
|
||
SetThreadDescription((HANDLE)ratio.native_handle(), L"DoF A3DA Bake Thread: Ratio");
|
||
|
||
if (position_x.joinable())
|
||
position_x.join();
|
||
|
||
if (position_y.joinable())
|
||
position_y.join();
|
||
|
||
if (position_z.joinable())
|
||
position_z.join();
|
||
|
||
if (focus_range.joinable())
|
||
focus_range.join();
|
||
|
||
//if (focus.joinable())
|
||
// focus.join();
|
||
|
||
if (fuzzing_range.joinable())
|
||
fuzzing_range.join();
|
||
|
||
if (ratio.joinable())
|
||
ratio.join();
|
||
|
||
a.dof.model_transform.translation.x.raw_data = true;
|
||
a.dof.model_transform.translation.y.raw_data = true;
|
||
a.dof.model_transform.translation.z.raw_data = true;
|
||
|
||
a3da_key& rot_z = a.dof.model_transform.rotation.z;
|
||
if (dof_cam_data.enable_frame.size() > 1) {
|
||
rot_z.type = A3DA_KEY_HOLD;
|
||
rot_z.keys.reserve(dof_cam_data.enable_frame.size());
|
||
for (std::pair<int32_t, bool>& i : dof_cam_data.enable_frame)
|
||
rot_z.keys.push_back({ (float_t)i.first, i.second ? 1.00051f : 0.0f });
|
||
rot_z.max_frame = a.play_control.size;
|
||
}
|
||
else if (dof_cam_data.enable_frame.size()) {
|
||
rot_z.type = A3DA_KEY_STATIC;
|
||
rot_z.value = dof_cam_data.enable_frame[0].second ? 1.00051f : 0.0f;
|
||
}
|
||
else
|
||
rot_z.type = A3DA_KEY_NONE;
|
||
|
||
a.dof.model_transform.visibility.type = A3DA_KEY_STATIC;
|
||
a.dof.model_transform.visibility.value = 1.0f;
|
||
|
||
a.write(buf);
|
||
|
||
dof_cam_data.reset();
|
||
}
|
||
#endif
|
||
|
||
for (int32_t i = 0; i < pv_count; i++)
|
||
data[i].unload();
|
||
stage_data.unload();
|
||
state = 50;
|
||
|
||
state_old = 22;
|
||
} break;
|
||
case 22: {
|
||
if (state)
|
||
break;
|
||
|
||
Glitter::glt_particle_manager->FreeScenes();
|
||
|
||
del();
|
||
} break;
|
||
}
|
||
return false;
|
||
}
|
||
|
||
bool x_pv_game::dest() {
|
||
if (!unload())
|
||
return false;
|
||
|
||
task_rob_manager_del_task();
|
||
|
||
Glitter::glt_particle_manager->SetPause(false);
|
||
extern float_t frame_speed;
|
||
frame_speed = 1.0f;
|
||
|
||
extern bool close;
|
||
//close = true;
|
||
return true;
|
||
}
|
||
|
||
void x_pv_game::disp() {
|
||
if (state_old != 20)
|
||
return;
|
||
|
||
if (pv_index >= 0 && pv_index < pv_count)
|
||
get_data().disp();
|
||
}
|
||
|
||
void x_pv_game::basic() {
|
||
if (state_old != 20 && state_old != 21)
|
||
return;
|
||
|
||
#if BAKE_DOF
|
||
if (dof_cam_data.frame != frame) {
|
||
camera* cam = rctx_ptr->camera;
|
||
|
||
bool enable = rctx_ptr->render.get_dof_enable();
|
||
|
||
float_t focus;
|
||
float_t focus_range;
|
||
float_t fuzzing_range;
|
||
float_t ratio;
|
||
rctx_ptr->render.get_dof_data(focus, focus_range, fuzzing_range, ratio);
|
||
|
||
vec3 interest;
|
||
vec3 view_point;
|
||
cam->get_interest(interest);
|
||
cam->get_view_point(view_point);
|
||
|
||
interest = view_point + vec3::normalize(interest - view_point) * focus;
|
||
|
||
dof_cam_data.position_x.push_back(interest.x);
|
||
dof_cam_data.position_y.push_back(interest.y);
|
||
dof_cam_data.position_z.push_back(interest.z);
|
||
dof_cam_data.focus.push_back(focus);
|
||
dof_cam_data.focus_range.push_back(focus_range);
|
||
dof_cam_data.fuzzing_range.push_back(fuzzing_range);
|
||
dof_cam_data.ratio.push_back(ratio);
|
||
if (dof_cam_data.enable != enable) {
|
||
dof_cam_data.enable_frame.push_back(frame, enable);
|
||
dof_cam_data.enable = enable;
|
||
}
|
||
dof_cam_data.frame = frame;
|
||
}
|
||
#endif
|
||
|
||
if (step_frame)
|
||
if (pause)
|
||
pause = false;
|
||
else {
|
||
pause = true;
|
||
step_frame = false;
|
||
}
|
||
|
||
Glitter::glt_particle_manager->SetPause(pause);
|
||
extern float_t frame_speed;
|
||
frame_speed = pause ? 0.0f : 1.0f;
|
||
|
||
#if BAKE_PV826
|
||
for (auto& i : effchrpv_auth_3d_rob_mot_ids) {
|
||
rob_chara* rob_chr = rob_chara_array_get(rob_chara_ids[i.first]);
|
||
x_pv_game_a3da_to_mot& a2m = i.second;
|
||
|
||
rob_chara_bone_data* rob_bone_data = rob_chr->bone_data;
|
||
|
||
bone_database_skeleton_type skeleton_type = rob_bone_data->base_skeleton_type;
|
||
motion_blend_mot* mot = rob_bone_data->motion_loaded.front();
|
||
std::vector<bone_data>* bones = &mot->bone_data.bones;
|
||
std::vector<uint16_t>* bone_indices = &mot->bone_data.bone_indices;
|
||
|
||
bone_data* bones_data = bones->data();
|
||
for (uint16_t& i : *bone_indices) {
|
||
bone_data* data = &bones_data[i];
|
||
::motion_bone_index motion_bone_index = (::motion_bone_index)data->motion_bone_index;
|
||
if (!(motion_bone_index >= MOTION_BONE_N_HITO_L_EX
|
||
&& motion_bone_index <= MOTION_BONE_NL_OYA_C_L_WJ
|
||
|| motion_bone_index >= MOTION_BONE_N_HITO_R_EX
|
||
&& motion_bone_index <= MOTION_BONE_NL_OYA_C_R_WJ))
|
||
continue;
|
||
|
||
auto elem = a2m.bone_keys.find(motion_bone_index);
|
||
if (elem == a2m.bone_keys.end())
|
||
elem = a2m.bone_keys.insert({ motion_bone_index, {} }).first;
|
||
|
||
vec3 rotation;
|
||
mat4_get_rotation(&data->rot_mat[0], &rotation);
|
||
if (elem->second.x.size() == frame)
|
||
elem->second.x.push_back(rotation.x);
|
||
if (elem->second.y.size() == frame)
|
||
elem->second.y.push_back(rotation.y);
|
||
if (elem->second.z.size() == frame)
|
||
elem->second.z.push_back(rotation.z);
|
||
}
|
||
}
|
||
#endif
|
||
}
|
||
|
||
void x_pv_game::window() {
|
||
if (state_old != 20)
|
||
return;
|
||
|
||
if (Input::IsKeyTapped(GLFW_KEY_K, GLFW_MOD_CONTROL))
|
||
state_old = 21;
|
||
else if (Input::IsKeyTapped(GLFW_KEY_K))
|
||
pause ^= true;
|
||
|
||
if (Input::IsKeyTapped(GLFW_KEY_L)) {
|
||
pause = true;
|
||
step_frame = true;
|
||
}
|
||
|
||
if (!pause) {
|
||
basic();
|
||
return;
|
||
}
|
||
|
||
ImGuiIO& io = ImGui::GetIO();
|
||
ImGuiStyle& style = ImGui::GetStyle();
|
||
ImFont* font = ImGui::GetFont();
|
||
|
||
float_t w = 240.0f;
|
||
float_t h = 86.0f;
|
||
|
||
extern int32_t width;
|
||
ImGui::SetNextWindowPos({ (float_t)width - w, 0.0f }, ImGuiCond_Always);
|
||
ImGui::SetNextWindowSize({ w, h }, ImGuiCond_Always);
|
||
|
||
ImGuiWindowFlags window_flags = 0;
|
||
window_flags |= ImGuiWindowFlags_NoResize;
|
||
|
||
bool collapsed = !ImGui::Begin("X PV GAME", 0, window_flags);
|
||
if (collapsed) {
|
||
ImGui::End();
|
||
return;
|
||
}
|
||
|
||
w = ImGui::GetContentRegionAvailWidth();
|
||
if (ImGui::BeginTable("buttons", 2)) {
|
||
ImGui::TableSetupColumn("", ImGuiTableColumnFlags_WidthFixed, w * 0.5f);
|
||
|
||
ImGui::TableNextColumn();
|
||
w = ImGui::GetContentRegionAvailWidth();
|
||
if (ImGui::ButtonEnterKeyPressed(pause || (!pause && step_frame) ? "Play (K)" : "Pause (K)", { w, 0.0f }))
|
||
pause ^= true;
|
||
|
||
ImGui::TableNextColumn();
|
||
w = ImGui::GetContentRegionAvailWidth();
|
||
if (ImGui::ButtonEnterKeyPressed("Step Frame (L)", { w, 0.0f })) {
|
||
pause = true;
|
||
step_frame = true;
|
||
}
|
||
|
||
ImGui::TableNextColumn();
|
||
w = ImGui::GetContentRegionAvailWidth();
|
||
if (ImGui::ButtonEnterKeyPressed("Stop (Ctrl+K)", { w, 0.0f }))
|
||
state_old = 21;
|
||
|
||
ImGui::TableNextColumn();
|
||
w = ImGui::GetContentRegionAvailWidth();
|
||
char buf[0x200];
|
||
sprintf_s(buf, sizeof(buf), "%d/%d", frame, (int32_t)(time / 10000));
|
||
ImGui::PushStyleColor(ImGuiCol_Button, { 0.0f, 0.0f, 0.0f, 0.0f });
|
||
ImGui::PushStyleColor(ImGuiCol_ButtonActive, { 0.0f, 0.0f, 0.0f, 0.0f });
|
||
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, { 0.0f, 0.0f, 0.0f, 0.0f });
|
||
ImGui::ButtonExEnterKeyPressed(buf, { w, 0.0f }, ImGuiButtonFlags_DontClosePopups
|
||
| ImGuiButtonFlags_NoNavFocus | ImGuiButtonFlags_NoHoveredOnFocus);
|
||
ImGui::PopStyleColor(3);
|
||
ImGui::EndTable();
|
||
}
|
||
|
||
extern bool input_locked;
|
||
input_locked |= ImGui::IsWindowFocused();
|
||
ImGui::End();
|
||
|
||
basic();
|
||
}
|
||
|
||
void x_pv_game::load(int32_t pv_id, int32_t stage_id, chara_index charas[6], int32_t modules[6]) {
|
||
data_struct* aft_data = &data_list[DATA_AFT];
|
||
motion_database* aft_mot_db = &aft_data->data_ft.mot_db;
|
||
|
||
this->pv_id = pv_id;
|
||
this->stage_id = stage_id;
|
||
memmove(this->charas, charas, sizeof(this->charas));
|
||
memmove(this->modules, modules, sizeof(this->modules));
|
||
|
||
data_struct* x_data = &data_list[DATA_X];
|
||
|
||
char buf[0x200];
|
||
sprintf_s(buf, sizeof(buf), "PV%03d", pv_id == 832 ? 800 : pv_id);
|
||
uint32_t mot_set = aft_mot_db->get_motion_set_id(buf);
|
||
motion_set_load_motion(mot_set, "", aft_mot_db);
|
||
motion_set_load_mothead(mot_set, "", aft_mot_db);
|
||
|
||
pv_param::light_data_load_files(pv_id, "");
|
||
pv_param::post_process_data_load_files(pv_id, "");
|
||
|
||
{
|
||
dof d;
|
||
sprintf_s(buf, sizeof(buf), "pv%03d", pv_id);
|
||
x_data->load_file(&d, "root+/post_process_table/", hash_utf8_murmurhash(buf), ".dft", dof::load_file);
|
||
pv_param::post_process_data_set_dof(d);
|
||
}
|
||
|
||
sprintf_s(buf, sizeof(buf), "EFFSTGPV%03d", 800 + stage_id);
|
||
light_category = buf;
|
||
|
||
int32_t chara_index = 0;
|
||
|
||
success = true;
|
||
task_effect_init = false;
|
||
|
||
pause = false;
|
||
step_frame = false;
|
||
|
||
for (int32_t& i : rob_chara_ids)
|
||
i = -1;
|
||
|
||
state = 10;
|
||
state_old = 1;
|
||
this->frame = 0;
|
||
frame_float = 0.0;
|
||
time = 0;
|
||
|
||
Glitter::counter.Reset();
|
||
Glitter::glt_particle_manager->draw_all = false;
|
||
//sound_work_play_se(1, "load01_2", 1.0f);
|
||
}
|
||
|
||
#if BAKE_PV826
|
||
static void fix_rotation(std::vector<float_t>& vec) {
|
||
if (vec.size() < 2)
|
||
return;
|
||
|
||
const float_t half_pi = (float_t)(M_PI / 2.0);
|
||
|
||
int32_t curr_rot = 0;
|
||
float_t rot_fix = 0.0f;
|
||
float_t rot_prev = vec.data()[0];
|
||
float_t* i_begin = vec.data() + 1;
|
||
float_t* i_end = vec.data() + vec.size();
|
||
for (float_t* i = i_begin; i != i_end; i++) {
|
||
float_t rot = *i;
|
||
if (rot < -half_pi && rot_prev > half_pi && fabsf(rot - rot_prev) > half_pi) {
|
||
curr_rot++;
|
||
rot_fix = (float_t)(M_PI * 2.0 * (double_t)curr_rot);
|
||
}
|
||
else if (rot > half_pi && rot_prev < -half_pi && fabsf(rot - rot_prev) > half_pi) {
|
||
curr_rot--;
|
||
rot_fix = (float_t)(M_PI * 2.0 * (double_t)curr_rot);
|
||
}
|
||
|
||
if (curr_rot)
|
||
*i = rot + rot_fix;
|
||
rot_prev = rot;
|
||
}
|
||
}
|
||
|
||
struct mot_data_bake {
|
||
int32_t performer;
|
||
x_pv_game_a3da_to_mot* data;
|
||
lock<uint32_t> state;
|
||
|
||
mot_data_bake() : performer(), data() {
|
||
|
||
}
|
||
};
|
||
|
||
const int32_t bake_pv826_threads_count = 4;
|
||
|
||
const motion_set_info* bake_pv826_set_info;
|
||
std::thread* bake_pv826_thread;
|
||
mot_data_bake* bake_pv826_mot_data;
|
||
int32_t bake_pv826_performer;
|
||
std::mutex* bake_pv826_alloc_mutex;
|
||
prj::shared_ptr<prj::stack_allocator>* bake_pv826_alloc;
|
||
::mot_set* bake_pv826_mot_set;
|
||
|
||
static mot_key_set_type mot_write_motion_fit_keys_into_curve(std::vector<float_t>& values_src,
|
||
prj::shared_ptr<prj::stack_allocator> alloc, uint16_t*& frames, float_t*& values, size_t& keys_count) {
|
||
std::vector<uint16_t> _frames;
|
||
std::vector<float_t> _values;
|
||
mot_key_set_type type = mot_set::fit_keys_into_curve(values_src, _frames, _values);
|
||
switch (type) {
|
||
case MOT_KEY_SET_NONE:
|
||
keys_count = 0;
|
||
frames = 0;
|
||
values = 0;
|
||
break;
|
||
case MOT_KEY_SET_STATIC:
|
||
keys_count = 1;
|
||
{
|
||
std::unique_lock<std::mutex> u_lock(*bake_pv826_alloc_mutex);
|
||
frames = 0;
|
||
values = (*bake_pv826_alloc)->allocate<float_t>();
|
||
}
|
||
memcpy(values, _values.data(), sizeof(float_t));
|
||
break;
|
||
case MOT_KEY_SET_HERMITE:
|
||
keys_count = _frames.size();
|
||
{
|
||
std::unique_lock<std::mutex> u_lock(*bake_pv826_alloc_mutex);
|
||
frames = (*bake_pv826_alloc)->allocate<uint16_t>(_frames.data(), keys_count);
|
||
values = (*bake_pv826_alloc)->allocate<float_t>(keys_count);
|
||
}
|
||
memcpy(frames, _frames.data(), sizeof(uint16_t) * keys_count);
|
||
memcpy(values, _values.data(), sizeof(float_t) * keys_count);
|
||
break;
|
||
case MOT_KEY_SET_HERMITE_TANGENT:
|
||
keys_count = _frames.size();
|
||
{
|
||
std::unique_lock<std::mutex> u_lock(*bake_pv826_alloc_mutex);
|
||
frames = (*bake_pv826_alloc)->allocate<uint16_t>(keys_count);
|
||
values = (*bake_pv826_alloc)->allocate<float_t>(keys_count * 2);
|
||
}
|
||
memcpy(frames, _frames.data(), sizeof(uint16_t) * keys_count);
|
||
memcpy(values, _values.data(), sizeof(float_t) * keys_count * 2);
|
||
break;
|
||
}
|
||
return type;
|
||
}
|
||
|
||
static void mot_write_motion(mot_data_bake* bake) {
|
||
data_struct* aft_data = &data_list[DATA_AFT];
|
||
bone_database* aft_bone_data = &aft_data->data_ft.bone_data;
|
||
motion_database* aft_mot_db = &aft_data->data_ft.mot_db;
|
||
|
||
char buf[0x200];
|
||
sprintf_s(buf, sizeof(buf), "PV826_OST_P%d_00", bake->performer);
|
||
|
||
uint32_t motion_id = aft_mot_db->get_motion_id(buf);
|
||
|
||
size_t motion_index = -1;
|
||
const motion_set_info* set_info = bake_pv826_set_info;
|
||
for (const motion_info& j : set_info->motion)
|
||
if (j.id == motion_id) {
|
||
motion_index = &j - set_info->motion.data();
|
||
break;
|
||
}
|
||
|
||
mot_data* mot_data = &bake_pv826_mot_set->mot_data[motion_index];
|
||
|
||
uint16_t key_set_count = mot_data->key_set_count - 1;
|
||
if (!key_set_count)
|
||
return;
|
||
|
||
const char* name = bone_database_skeleton_type_to_string(BONE_DATABASE_SKELETON_COMMON);
|
||
std::string* bone_names = aft_mot_db->bone_name.data();
|
||
const std::vector<bone_database_bone>* bones = aft_bone_data->get_skeleton_bones(name);
|
||
if (!bones)
|
||
return;
|
||
|
||
prj::shared_ptr<prj::stack_allocator>& alloc = *bake_pv826_alloc;
|
||
x_pv_game_a3da_to_mot& a2m = *bake->data;
|
||
const mot_bone_info* bone_info = mot_data->bone_info_array;
|
||
for (size_t key_set_offset = 0, i = 0; key_set_offset < key_set_count; i++) {
|
||
motion_bone_index bone_index = (motion_bone_index)aft_bone_data->get_skeleton_bone_index(
|
||
name, bone_names[bone_info[i].index].c_str());
|
||
if (bone_index == -1) {
|
||
i++;
|
||
bone_index = (motion_bone_index)aft_bone_data->get_skeleton_bone_index(
|
||
name, bone_names[bone_info[i].index].c_str());
|
||
if (bone_index == -1)
|
||
break;
|
||
}
|
||
|
||
const bone_database_bone* bone = &(*bones)[bone_index];
|
||
|
||
auto elem = a2m.bone_keys.find(bone_index);
|
||
if (elem != a2m.bone_keys.end()) {
|
||
x_pv_game_a3da_to_mot_keys& keys = elem->second;
|
||
|
||
if (bone->type == BONE_DATABASE_BONE_ROTATION) {
|
||
fix_rotation(keys.x);
|
||
fix_rotation(keys.y);
|
||
fix_rotation(keys.z);
|
||
}
|
||
|
||
mot_key_set_data& key_set_data_x = mot_data->key_set_array[key_set_offset];
|
||
key_set_data_x.frames = 0;
|
||
key_set_data_x.values = 0;
|
||
size_t keys_x_count = 0;
|
||
key_set_data_x.type = mot_write_motion_fit_keys_into_curve(keys.x, alloc,
|
||
key_set_data_x.frames, key_set_data_x.values, keys_x_count);
|
||
key_set_data_x.keys_count = (uint16_t)keys_x_count;
|
||
key_set_data_x.data_type = MOT_KEY_SET_DATA_F32;
|
||
|
||
mot_key_set_data& key_set_data_y = mot_data->key_set_array[key_set_offset + 1];
|
||
key_set_data_y.frames = 0;
|
||
key_set_data_y.values = 0;
|
||
size_t keys_y_count = 0;
|
||
key_set_data_y.type = mot_write_motion_fit_keys_into_curve(keys.y, alloc,
|
||
key_set_data_y.frames, key_set_data_y.values, keys_y_count);
|
||
key_set_data_y.keys_count = (uint16_t)keys_y_count;
|
||
key_set_data_y.data_type = MOT_KEY_SET_DATA_F32;
|
||
|
||
mot_key_set_data& key_set_data_z = mot_data->key_set_array[key_set_offset + 2];
|
||
key_set_data_z.frames = 0;
|
||
key_set_data_z.values = 0;
|
||
size_t keys_z_count = 0;
|
||
key_set_data_z.type = mot_write_motion_fit_keys_into_curve(keys.z, alloc,
|
||
key_set_data_z.frames, key_set_data_z.values, keys_z_count);
|
||
key_set_data_z.keys_count = (uint16_t)keys_z_count;
|
||
key_set_data_z.data_type = MOT_KEY_SET_DATA_F32;
|
||
}
|
||
|
||
elem = a2m.sec_bone_keys.find(bone_index);
|
||
if (elem != a2m.sec_bone_keys.end()) {
|
||
x_pv_game_a3da_to_mot_keys& keys = elem->second;
|
||
|
||
fix_rotation(keys.x);
|
||
fix_rotation(keys.y);
|
||
fix_rotation(keys.z);
|
||
|
||
mot_key_set_data& key_set_data_x = mot_data->key_set_array[key_set_offset + 3];
|
||
key_set_data_x.frames = 0;
|
||
key_set_data_x.values = 0;
|
||
size_t keys_x_count = 0;
|
||
key_set_data_x.type = mot_write_motion_fit_keys_into_curve(keys.x, alloc,
|
||
key_set_data_x.frames, key_set_data_x.values, keys_x_count);
|
||
key_set_data_x.keys_count = (uint16_t)keys_x_count;
|
||
key_set_data_x.data_type = MOT_KEY_SET_DATA_F32;
|
||
|
||
mot_key_set_data& key_set_data_y = mot_data->key_set_array[key_set_offset + 4];
|
||
key_set_data_y.frames = 0;
|
||
key_set_data_y.values = 0;
|
||
size_t keys_y_count = 0;
|
||
key_set_data_y.type = mot_write_motion_fit_keys_into_curve(keys.y, alloc,
|
||
key_set_data_y.frames, key_set_data_y.values, keys_x_count);
|
||
key_set_data_y.keys_count = (uint16_t)keys_y_count;
|
||
key_set_data_y.data_type = MOT_KEY_SET_DATA_F32;
|
||
|
||
mot_key_set_data& key_set_data_z = mot_data->key_set_array[key_set_offset + 5];
|
||
key_set_data_z.frames = 0;
|
||
key_set_data_z.values = 0;
|
||
size_t keys_z_count = 0;
|
||
key_set_data_z.type = mot_write_motion_fit_keys_into_curve(keys.z, alloc,
|
||
key_set_data_z.frames, key_set_data_z.values, keys_z_count);
|
||
key_set_data_z.keys_count = (uint16_t)keys_z_count;
|
||
key_set_data_z.data_type = MOT_KEY_SET_DATA_F32;
|
||
}
|
||
|
||
if (bone_index == MOTION_BONE_KL_AGO_WJ) {
|
||
mot_key_set_data& key_set_data_x = mot_data->key_set_array[key_set_offset];
|
||
key_set_data_x.frames = 0;
|
||
{
|
||
std::unique_lock<std::mutex> u_lock(*bake_pv826_alloc_mutex);
|
||
key_set_data_x.values = alloc->allocate<float_t>();
|
||
key_set_data_x.values[0] = 0.0491406508f;
|
||
}
|
||
key_set_data_x.type = MOT_KEY_SET_STATIC;
|
||
key_set_data_x.keys_count = 1;
|
||
key_set_data_x.data_type = MOT_KEY_SET_DATA_F32;
|
||
|
||
mot_key_set_data& key_set_data_y = mot_data->key_set_array[key_set_offset + 1];
|
||
key_set_data_y.frames = 0;
|
||
key_set_data_y.values = 0;
|
||
key_set_data_y.type = MOT_KEY_SET_NONE;
|
||
key_set_data_y.keys_count = 0;
|
||
key_set_data_y.data_type = MOT_KEY_SET_DATA_F32;
|
||
|
||
mot_key_set_data& key_set_data_z = mot_data->key_set_array[key_set_offset + 2];
|
||
key_set_data_z.frames = 0;
|
||
key_set_data_z.values = 0;
|
||
key_set_data_z.type = MOT_KEY_SET_NONE;
|
||
key_set_data_z.keys_count = 0;
|
||
key_set_data_z.data_type = MOT_KEY_SET_DATA_F32;
|
||
}
|
||
else if (bone_index == MOTION_BONE_N_KUBI_WJ_EX) {
|
||
mot_key_set_data& key_set_data_x = mot_data->key_set_array[key_set_offset];
|
||
key_set_data_x.frames = 0;
|
||
key_set_data_x.values = 0;
|
||
key_set_data_x.type = MOT_KEY_SET_NONE;
|
||
key_set_data_x.keys_count = 1;
|
||
key_set_data_x.data_type = MOT_KEY_SET_DATA_F32;
|
||
|
||
mot_key_set_data& key_set_data_y = mot_data->key_set_array[key_set_offset + 1];
|
||
key_set_data_y.frames = 0;
|
||
{
|
||
std::unique_lock<std::mutex> u_lock(*bake_pv826_alloc_mutex);
|
||
key_set_data_y.values = alloc->allocate<float_t>();
|
||
key_set_data_y.values[0] = 0.0331281610f;
|
||
}
|
||
key_set_data_y.type = MOT_KEY_SET_STATIC;
|
||
key_set_data_y.keys_count = 0;
|
||
key_set_data_y.data_type = MOT_KEY_SET_DATA_F32;
|
||
|
||
mot_key_set_data& key_set_data_z = mot_data->key_set_array[key_set_offset + 2];
|
||
key_set_data_z.frames = 0;
|
||
key_set_data_z.values = 0;
|
||
key_set_data_z.type = MOT_KEY_SET_NONE;
|
||
key_set_data_z.keys_count = 0;
|
||
key_set_data_z.data_type = MOT_KEY_SET_DATA_F32;
|
||
}
|
||
|
||
if (bone->type >= BONE_DATABASE_BONE_POSITION_ROTATION)
|
||
key_set_offset += 6;
|
||
else
|
||
key_set_offset += 3;
|
||
}
|
||
|
||
bake->state.set(0);
|
||
}
|
||
|
||
static bool mot_write_motion_set(void* data, const char* path, const char* file, uint32_t hash) {
|
||
x_pv_game* xpvgm = (x_pv_game*)data;
|
||
|
||
data_struct* aft_data = &data_list[DATA_AFT];
|
||
bone_database* aft_bone_data = &aft_data->data_ft.bone_data;
|
||
motion_database* aft_mot_db = &aft_data->data_ft.mot_db;
|
||
|
||
char buf[0x200];
|
||
sprintf_s(buf, sizeof(buf), "PV%03d", xpvgm->pv_id);
|
||
bake_pv826_set_info = aft_mot_db->get_motion_set_by_name(buf);
|
||
if (!bake_pv826_set_info)
|
||
return true;
|
||
|
||
bake_pv826_alloc = new prj::shared_ptr<prj::stack_allocator>(new prj::stack_allocator);
|
||
bake_pv826_alloc_mutex = 0;
|
||
bake_pv826_thread = 0;
|
||
bake_pv826_mot_data = 0;
|
||
bake_pv826_performer = 1;
|
||
|
||
bake_pv826_mot_set = (*bake_pv826_alloc)->allocate<::mot_set>();
|
||
{
|
||
std::string mot_file;
|
||
mot_file.append("mot_");
|
||
mot_file.append(bake_pv826_set_info->name);
|
||
mot_file.append(".bin");
|
||
|
||
farc f;
|
||
farc::load_file(&f, path, file, hash);
|
||
|
||
farc_file* ff = f.read_file(mot_file.c_str());
|
||
if (!ff) {
|
||
delete bake_pv826_alloc;
|
||
bake_pv826_alloc = 0;
|
||
bake_pv826_mot_set = 0;
|
||
return true;
|
||
}
|
||
|
||
bake_pv826_mot_set->unpack_file(*bake_pv826_alloc, ff->data, ff->size, false);
|
||
}
|
||
|
||
if (!bake_pv826_mot_set->ready) {
|
||
delete bake_pv826_alloc;
|
||
bake_pv826_alloc = 0;
|
||
bake_pv826_mot_set = 0;
|
||
return true;
|
||
}
|
||
|
||
bake_pv826_alloc_mutex = new std::mutex;
|
||
bake_pv826_thread = new std::thread[bake_pv826_threads_count];
|
||
bake_pv826_mot_data = new mot_data_bake[bake_pv826_threads_count];
|
||
return true;
|
||
}
|
||
|
||
static void mot_write_motion_set(x_pv_game* xpvgm) {
|
||
if (!bake_pv826_set_info)
|
||
return;
|
||
|
||
data_struct* aft_data = &data_list[DATA_AFT];
|
||
bone_database* aft_bone_data = &aft_data->data_ft.bone_data;
|
||
motion_database* aft_mot_db = &aft_data->data_ft.mot_db;
|
||
|
||
{
|
||
std::string mot_file;
|
||
mot_file.append("mot_");
|
||
mot_file.append(bake_pv826_set_info->name);
|
||
mot_file.append(".bin");
|
||
|
||
farc f;
|
||
|
||
f.add_file(mot_file.c_str());
|
||
farc_file* ff = &f.files.back();
|
||
bake_pv826_mot_set->pack_file(&ff->data, &ff->size);
|
||
ff->compressed = true;
|
||
|
||
std::string mot_farc;
|
||
mot_farc.append("pv826\\mot_");
|
||
mot_farc.append(bake_pv826_set_info->name);
|
||
f.write(mot_farc.c_str(), FARC_FArC, FARC_NONE, false);
|
||
}
|
||
|
||
delete[] bake_pv826_thread;
|
||
delete[] bake_pv826_mot_data;
|
||
delete bake_pv826_alloc_mutex;
|
||
|
||
delete bake_pv826_alloc;
|
||
|
||
bake_pv826_thread = 0;
|
||
bake_pv826_mot_data = 0;
|
||
bake_pv826_alloc_mutex = 0;
|
||
bake_pv826_mot_set = 0;
|
||
bake_pv826_alloc = 0;
|
||
bake_pv826_set_info = 0;
|
||
}
|
||
#endif
|
||
|
||
bool x_pv_game::unload() {
|
||
pv_osage_manager_array_set_not_reset_true();
|
||
if (pv_osage_manager_array_get_disp())
|
||
return false;
|
||
|
||
#if BAKE_PV826
|
||
if (get_data().pv_id == 826) {
|
||
data_struct* aft_data = &data_list[DATA_AFT];
|
||
motion_database* aft_mot_db = &aft_data->data_ft.mot_db;
|
||
|
||
char buf[0x200];
|
||
sprintf_s(buf, sizeof(buf), "PV%03d", get_data().pv_id);
|
||
const motion_set_info* set_info = aft_mot_db->get_motion_set_by_name(buf);
|
||
if (set_info) {
|
||
std::string farc_file = "mot_" + set_info->name + ".farc";
|
||
aft_data->load_file(this, "rom/rob/", farc_file.c_str(), mot_write_motion_set);
|
||
}
|
||
|
||
if (bake_pv826_set_info) {
|
||
waitable_timer timer;
|
||
while (true) {
|
||
int32_t free_thread_count = 0;
|
||
for (int32_t i = 0; i < bake_pv826_threads_count; i++)
|
||
if (!bake_pv826_mot_data[i].state.get())
|
||
free_thread_count++;
|
||
|
||
if (free_thread_count && bake_pv826_performer < 6)
|
||
for (auto& i : effchrpv_auth_3d_rob_mot_ids) {
|
||
if (!free_thread_count)
|
||
break;
|
||
else if (bake_pv826_performer != i.first)
|
||
continue;
|
||
|
||
std::thread* thread = 0;
|
||
int32_t thread_index = -1;
|
||
for (int32_t j = 0; j < bake_pv826_threads_count; j++)
|
||
if (!bake_pv826_mot_data[j].state.get()) {
|
||
thread = &bake_pv826_thread[j];
|
||
thread_index = j;
|
||
break;
|
||
}
|
||
|
||
if (!thread)
|
||
break;
|
||
|
||
mot_data_bake* bake = &bake_pv826_mot_data[thread_index];
|
||
bake->performer = bake_pv826_performer + 1;
|
||
bake->data = &i.second;
|
||
bake->state.set(1);
|
||
|
||
if (thread->joinable())
|
||
thread->join();
|
||
|
||
*thread = std::thread(mot_write_motion, bake);
|
||
|
||
wchar_t buf[0x80];
|
||
swprintf_s(buf, sizeof(buf) / sizeof(wchar_t),
|
||
L"X PV GAME BAKE PV826 P%d", bake->performer);
|
||
SetThreadDescription((HANDLE)thread->native_handle(), buf);
|
||
|
||
bake_pv826_performer++;
|
||
free_thread_count--;
|
||
}
|
||
|
||
if (free_thread_count == 2)
|
||
break;
|
||
|
||
timer.sleep_float(1.0);
|
||
}
|
||
|
||
for (int32_t i = 0; i < bake_pv826_threads_count; i++)
|
||
bake_pv826_thread[i].join();
|
||
|
||
mot_write_motion_set(this);
|
||
}
|
||
}
|
||
#endif
|
||
|
||
for (int32_t& i : rob_chara_ids)
|
||
skin_param_manager_reset(i);
|
||
|
||
data_struct* aft_data = &data_list[DATA_AFT];
|
||
motion_database* aft_mot_db = &aft_data->data_ft.mot_db;
|
||
|
||
pv_param::light_data_clear_data();
|
||
pv_param::post_process_data_clear_data();
|
||
|
||
char buf[0x200];
|
||
sprintf_s(buf, sizeof(buf), "PV%03d", get_data().pv_id == 832 ? 800 : get_data().pv_id);
|
||
uint32_t mot_set = aft_mot_db->get_motion_set_id(buf);
|
||
motion_set_unload_motion(mot_set);
|
||
motion_set_unload_mothead(mot_set);
|
||
|
||
state_old = 0;
|
||
frame = 0;
|
||
frame_float = 0.0;
|
||
time = 0;
|
||
|
||
for (int32_t& i : rob_chara_ids)
|
||
if (i != -1) {
|
||
rob_chara_array_free_chara_id(i);
|
||
i = -1;
|
||
}
|
||
|
||
light_auth_3d_id.unload(rctx_ptr);
|
||
|
||
light_auth_3d_id = {};
|
||
|
||
auth_3d_data_unload_category(light_category.c_str());
|
||
|
||
light_category.clear();
|
||
light_category.shrink_to_fit();
|
||
|
||
for (int32_t i = 0; i < pv_count; i++)
|
||
data[i].reset();
|
||
stage_data.reset();
|
||
|
||
get_data().bar_beat.reset();
|
||
|
||
get_data().stage_effects.clear();
|
||
get_data().stage_effects.shrink_to_fit();
|
||
get_data().stage_effect_index = 0;
|
||
|
||
success = true;
|
||
task_effect_init = false;
|
||
|
||
pv_id = 0;
|
||
stage_id = 0;
|
||
for (chara_index& i : charas)
|
||
i = CHARA_MAX;
|
||
for (int32_t& i : modules)
|
||
i = 0;
|
||
|
||
Glitter::glt_particle_manager->draw_all = true;
|
||
|
||
osage_play_data_manager_reset();
|
||
|
||
skin_param_storage_reset();
|
||
|
||
light_param_data_storage_data_reset();
|
||
|
||
rndr::Render& rend = rctx_ptr->render;
|
||
rend.reset_saturate_coeff(0, true);
|
||
rend.set_dof_enable(false);
|
||
rend.set_dof_update(false);
|
||
rend.reset_scene_fade(0);
|
||
|
||
rend.set_taa(1);
|
||
rend.update_res(0, -1);
|
||
|
||
rctx_ptr->disp_manager->object_culling = true;
|
||
shadow_ptr_get()->shadow_range_factor = 1.0f;
|
||
rctx_ptr->render_manager->set_effect_texture(0);
|
||
|
||
sound_work_reset_all_se();
|
||
|
||
pv_param_task::post_process_task_del_task();
|
||
return true;
|
||
}
|
||
|
||
void x_pv_game::ctrl(float_t curr_time, float_t delta_time) {
|
||
#if !BAKE_FAST
|
||
x_pv_game_music_ptr->ctrl(delta_time);
|
||
#endif
|
||
|
||
#if BAKE_PV826
|
||
for (int32_t i = 0; i < pv_count; i++)
|
||
data[i].ctrl(curr_time, delta_time,
|
||
data[i].pv_id == 826 ? &effchrpv_auth_3d_mot_ids : 0);
|
||
#else
|
||
for (int32_t i = 0; i < pv_count; i++)
|
||
data[i].ctrl(curr_time, delta_time);
|
||
#endif
|
||
|
||
switch (state) {
|
||
case 10:
|
||
if (stage_data.state == 20)
|
||
state = 20;
|
||
break;
|
||
case 30: {
|
||
bool v38 = true;
|
||
for (int32_t i = 0; i < pv_count; i++)
|
||
if (data[i].state == 10 || data[i].state == 20) {
|
||
v38 = false;
|
||
break;
|
||
}
|
||
|
||
if (!v38)
|
||
break;
|
||
|
||
stop_current_pv();
|
||
this->data[pv_index].unload_data();
|
||
pv_index++;
|
||
|
||
state = 20;
|
||
} break;
|
||
case 40: {
|
||
bool v19 = true;
|
||
for (int32_t i = 0; i < pv_count; i++)
|
||
if (data[i].state == 10 || data[i].state == 20) {
|
||
v19 = false;
|
||
break;
|
||
}
|
||
|
||
if (!v19)
|
||
break;
|
||
|
||
stop_current_pv();
|
||
|
||
x_pv_game_data* data = this->data;
|
||
for (int32_t i = 0; i < pv_count; i++, data++) {
|
||
if (!data->state) {
|
||
rctx_ptr->camera->reset();
|
||
data->field_1C &= ~0xD1;
|
||
data->state = 0;
|
||
data->stage_effect_index = 0;
|
||
data->next_stage_effect_bar = 0;
|
||
data->pv_data.reset();
|
||
}
|
||
|
||
if (i > 0)
|
||
data->unload_data();
|
||
}
|
||
|
||
if (pv_index) {
|
||
pv_index = 0;
|
||
if (!data->state)
|
||
data->state = 20;
|
||
else if (data->state == 10)
|
||
data->field_1C |= 0x08;
|
||
}
|
||
state = 20;
|
||
}
|
||
case 50: {
|
||
bool v16 = false;
|
||
for (int32_t i = 0; i < pv_count; i++)
|
||
if (data[i].state)
|
||
v16 = true;
|
||
|
||
if (!v16 && stage_data.state != 20)
|
||
state = 0;
|
||
} break;
|
||
}
|
||
|
||
stage_data.ctrl(delta_time);
|
||
}
|
||
|
||
void x_pv_game::stop_current_pv() {
|
||
if (pv_count <= 0)
|
||
return;
|
||
|
||
data[pv_index].stop();
|
||
field_7198C.reset();
|
||
field_71994.reset();
|
||
}
|
||
|
||
#if BAKE_X_PACK
|
||
XPVGameBaker::XPVGameBaker() : charas(), modules(), start(), exit(), next() {
|
||
pv_id = 800;
|
||
stage_id = 0;
|
||
chara_index = CHARA_MIKU;
|
||
|
||
for (::chara_index& i : charas)
|
||
i = CHARA_MIKU;
|
||
|
||
for (int32_t& i : modules)
|
||
i = 0;
|
||
|
||
next = true;
|
||
}
|
||
|
||
XPVGameBaker::~XPVGameBaker() {
|
||
|
||
}
|
||
|
||
bool XPVGameBaker::init() {
|
||
data_struct* aft_data = &data_list[DATA_AFT];
|
||
|
||
aet_db.read("diva\\AFT_mod\\mdata\\MPF2\\rom\\2d\\mdata_aet_db", false);
|
||
auth_3d_db_base.read("diva\\AFT\\rom\\auth_3d\\auth_3d_db");
|
||
auth_3d_db.read("diva\\AFT_mod\\mdata\\MPF2\\rom\\auth_3d\\mdata_auth_3d_db");
|
||
obj_db.read("diva\\AFT_mod\\mdata\\MPF2\\rom\\objset\\mdata_obj_db", false);
|
||
spr_db.read("diva\\AFT_mod\\mdata\\MPF2\\rom\\2d\\mdata_spr_db", false);
|
||
stage_data.read("diva\\AFT_mod\\mdata\\MPF2\\rom\\mdata_stage_data", false);
|
||
{
|
||
texture_database_file tex_db_base;
|
||
tex_db_base.read("diva\\AFT\\rom\\objset\\tex_db", false);
|
||
this->tex_db_base.add(&tex_db_base);
|
||
}
|
||
tex_db.read("diva\\AFT_mod\\mdata\\MPF2\\rom\\objset\\mdata_tex_db", false);
|
||
return true;
|
||
}
|
||
|
||
bool XPVGameBaker::ctrl() {
|
||
if (!next)
|
||
return false;
|
||
|
||
next = false;
|
||
|
||
switch (pv_id) {
|
||
case 832:
|
||
exit = true;
|
||
return true;
|
||
}
|
||
|
||
pv_id++;
|
||
stage_id++;
|
||
start = true;
|
||
return false;
|
||
}
|
||
|
||
bool XPVGameBaker::dest() {
|
||
aet_db.write("patch\\!temp\\2d\\mdata_aet_db");
|
||
auth_3d_db.write("patch\\!temp\\auth_3d\\mdata_auth_3d_db");
|
||
obj_db.write("patch\\!temp\\objset\\mdata_obj_db");
|
||
spr_db.write("patch\\!temp\\2d\\mdata_spr_db");
|
||
stage_data.write("patch\\!temp\\mdata_stage_data");
|
||
tex_db.write("patch\\!temp\\objset\\mdata_tex_db");
|
||
return true;
|
||
}
|
||
#else
|
||
XPVGameSelector::XPVGameSelector() : charas(), modules(), start(), exit() {
|
||
pv_id = 823;
|
||
stage_id = 23;
|
||
|
||
for (chara_index& i : charas)
|
||
i = CHARA_MIKU;
|
||
|
||
for (int32_t& i : modules)
|
||
i = 0;
|
||
|
||
pv_id = 816;
|
||
stage_id = 16;
|
||
|
||
charas[0] = CHARA_LEN;
|
||
|
||
modules[0] = 0;
|
||
|
||
pv_id = 811;
|
||
stage_id = 11;
|
||
|
||
charas[0] = CHARA_MIKU;
|
||
|
||
modules[0] = 0;
|
||
|
||
#if BAKE_PV826
|
||
pv_id = 826;
|
||
stage_id = 26;
|
||
|
||
charas[0] = CHARA_MIKU;
|
||
charas[1] = CHARA_RIN;
|
||
charas[2] = CHARA_LEN;
|
||
charas[3] = CHARA_LUKA;
|
||
charas[4] = CHARA_KAITO;
|
||
charas[5] = CHARA_MEIKO;
|
||
|
||
modules[0] = 168;
|
||
modules[1] = 46;
|
||
modules[2] = 39;
|
||
modules[3] = 41;
|
||
modules[4] = 40;
|
||
modules[5] = 31;
|
||
#endif
|
||
|
||
const prj::vector_pair_combine<int32_t, module>& modules = module_table_handler_data_get_modules();
|
||
for (const auto& i : modules)
|
||
modules_data[i.second.chara].push_back(&i.second);
|
||
|
||
for (int32_t i = 0; i < ROB_CHARA_COUNT; i++)
|
||
for (const auto& j : modules_data[charas[i]])
|
||
if (this->modules[i] == j->cos) {
|
||
module_names[i].assign(j->name);
|
||
break;
|
||
}
|
||
}
|
||
|
||
XPVGameSelector::~XPVGameSelector() {
|
||
|
||
}
|
||
|
||
bool XPVGameSelector::init() {
|
||
start = false;
|
||
exit = false;
|
||
return true;
|
||
}
|
||
|
||
bool XPVGameSelector::ctrl() {
|
||
return false;
|
||
}
|
||
|
||
bool XPVGameSelector::dest() {
|
||
return true;
|
||
}
|
||
|
||
void XPVGameSelector::window() {
|
||
static const char* pv_names[] = {
|
||
u8"801. Strangers",
|
||
u8"802. Ai Dee",
|
||
u8"803. Streaming Heart",
|
||
u8"804. Babylon",
|
||
u8"805. The Lost One's Weeping",
|
||
u8"806. Slow Motion",
|
||
u8"807. Tale of the Deep-sea Lily",
|
||
u8"808. Love Trial",
|
||
u8"809. Love Song",
|
||
u8"810. The First Sound",
|
||
u8"811. LOL - lots of laugh -",
|
||
u8"812. Patchwork Staccato",
|
||
u8"813. Even a Kunoichi Needs Love",
|
||
u8"814. Calc.",
|
||
u8"815. A Single Red Leaf",
|
||
u8"816. Holy Lance Explosion Boy",
|
||
u8"817. Urotander, Underhanded Rangers",
|
||
u8"818. Humorous Dream of Mrs. Pumpkin",
|
||
u8"819. Solitary Envy",
|
||
u8"820. Raspberry * Monster",
|
||
u8"821. Brain Revolution Girl",
|
||
u8"822. Amazing Dolce",
|
||
u8"823. Name of the Sin",
|
||
u8"824. Satisfaction",
|
||
u8"825. Cute Medley - Idol Sounds",
|
||
u8"826. Beginning Medley - Primary Colors",
|
||
u8"827. Cool Medley - Cyber Rock Jam",
|
||
u8"828. Elegant Medley - Glossy Mixture",
|
||
u8"829. Quirky Medley - Giga-Remix",
|
||
u8"830. Ending Medley - Ultimate Exquisite Rampage",
|
||
u8"831. Sharing The World",
|
||
u8"832. Hand in Hand",
|
||
};
|
||
|
||
static const char* stage_names[] = {
|
||
u8"001. Nighttime Curb Stage",
|
||
u8"002. Digital Concert Stage",
|
||
u8"003. Secret Ruins Stage",
|
||
u8"004. Utopia Stage",
|
||
u8"005. Classroom Concert Stage",
|
||
u8"006. Capsule Room Stage",
|
||
u8"007. Deep Sea Stage",
|
||
u8"008. Verdict Stage",
|
||
u8"009. Sky Garden Stage",
|
||
u8"010. Musical Dawn Stage",
|
||
u8"011. Sweet Dreams Stage",
|
||
u8"012. Heart's Playroom Stage",
|
||
u8"013. Ninja Village Stage",
|
||
u8"014. Park of Promises Stage",
|
||
u8"015. Autumn Sakura Stage",
|
||
u8"016. Classy Lounge Stage",
|
||
u8"017. Secret Base Stage",
|
||
u8"018. Halloween Party Stage",
|
||
u8"019. Twilight Shrine Stage",
|
||
u8"020. Raspberry Stage",
|
||
u8"021. Cabaret Stage",
|
||
u8"022. Witch's House Stage",
|
||
u8"023. Lilies & Shadows Stage",
|
||
u8"024. Techno Club Stage",
|
||
u8"025. Cute Concert Hall",
|
||
u8"026. First Concert Hall",
|
||
u8"027. Cool Concert Hall",
|
||
u8"028. Elegant Concert Hall",
|
||
u8"029. Quirky Concert Hall",
|
||
u8"030. Ultimate Concert Hall",
|
||
u8"031. Highrise Stage",
|
||
u8"032. Mirai Concert Stage",
|
||
};
|
||
|
||
ImGuiIO& io = ImGui::GetIO();
|
||
ImGuiStyle& style = ImGui::GetStyle();
|
||
ImFont* font = ImGui::GetFont();
|
||
|
||
extern int32_t height;
|
||
extern int32_t width;
|
||
|
||
float_t w = 400.0f;
|
||
float_t h = (float_t)height;
|
||
h = min_def(h, 438.0f);
|
||
|
||
ImGui::SetNextWindowPos({ (float_t)width - w, 0.0f }, ImGuiCond_Always);
|
||
ImGui::SetNextWindowSize({ w, h }, ImGuiCond_Always);
|
||
|
||
ImGuiWindowFlags window_flags = 0;
|
||
window_flags |= ImGuiWindowFlags_NoResize;
|
||
|
||
focus = false;
|
||
bool open = true;
|
||
if (!ImGui::Begin("X PV Game Selector", &open, window_flags)) {
|
||
ImGui::End();
|
||
return;
|
||
}
|
||
else if (!open) {
|
||
start = false;
|
||
exit = true;
|
||
ImGui::End();
|
||
return;
|
||
}
|
||
|
||
pv_id -= 801;
|
||
pv_id = max_def(pv_id, 0);
|
||
ImGui::ColumnComboBox("PV", pv_names, 32, &pv_id, 0, false, &focus);
|
||
pv_id += 801;
|
||
|
||
stage_id--;
|
||
stage_id = max_def(stage_id, 0);
|
||
ImGui::ColumnComboBox("Stage", stage_names, 32, &stage_id, 0, false, &focus);
|
||
stage_id++;
|
||
|
||
char buf[0x200];
|
||
for (int32_t i = 0; i < ROB_CHARA_COUNT; i++) {
|
||
chara_index chara_old = charas[i];
|
||
|
||
sprintf_s(buf, sizeof(buf), "Chara %dP", i + 1);
|
||
ImGui::ColumnComboBox(buf, chara_full_names, CHARA_MAX,
|
||
(int32_t*)&charas[i], 0, false, &focus);
|
||
|
||
if (chara_old != charas[i]) {
|
||
modules[i] = 0;
|
||
module_names[i].clear();
|
||
|
||
for (const auto& j : modules_data[charas[i]])
|
||
if (modules[i] == j->cos) {
|
||
module_names[i].assign(j->name);
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
for (int32_t i = 0; i < ROB_CHARA_COUNT; i++) {
|
||
sprintf_s(buf, sizeof(buf), "Module %dP", i + 1);
|
||
|
||
ImGui::StartPropertyColumn(buf);
|
||
extern ImFont* imgui_font_arial;
|
||
if (imgui_font_arial)
|
||
ImGui::PushFont(imgui_font_arial);
|
||
if (ImGui::BeginCombo("", module_names[i].c_str(), 0)) {
|
||
for (const auto& j : modules_data[charas[i]]) {
|
||
if (j->cos == 499)
|
||
continue;
|
||
|
||
ImGui::PushID(&j);
|
||
if (ImGui::Selectable(j->name.c_str(), modules[i] == j->cos)
|
||
|| ImGui::ItemKeyPressed(ImGuiKey_Enter)
|
||
|| (ImGui::IsItemFocused() && modules[i] != j->cos)) {
|
||
modules[i] = j->cos;
|
||
module_names[i].assign(j->name);
|
||
}
|
||
ImGui::PopID();
|
||
|
||
if (modules[i] == j->cos)
|
||
ImGui::SetItemDefaultFocus();
|
||
}
|
||
|
||
focus |= true;
|
||
ImGui::EndCombo();
|
||
}
|
||
if (imgui_font_arial)
|
||
ImGui::PopFont();
|
||
ImGui::EndPropertyColumn();
|
||
}
|
||
|
||
if (ImGui::Button("Start")) {
|
||
start = true;
|
||
exit = true;
|
||
}
|
||
|
||
ImGui::End();
|
||
}
|
||
#endif
|
||
|
||
bool x_pv_game_init() {
|
||
x_pv_game_ptr = new x_pv_game;
|
||
#if !BAKE_FAST
|
||
x_pv_game_music_ptr = new x_pv_game_music;
|
||
#endif
|
||
return true;
|
||
}
|
||
|
||
x_pv_game* x_pv_game_get() {
|
||
return x_pv_game_ptr;
|
||
}
|
||
|
||
bool x_pv_game_free() {
|
||
if (x_pv_game_ptr) {
|
||
switch (x_pv_game_ptr->state_old) {
|
||
case 0:
|
||
break;
|
||
case 21:
|
||
case 22:
|
||
return false;
|
||
default:
|
||
x_pv_game_ptr->state_old = 21;
|
||
return false;
|
||
}
|
||
|
||
if (app::TaskWork::has_task(x_pv_game_ptr))
|
||
return false;
|
||
|
||
delete x_pv_game_ptr;
|
||
x_pv_game_ptr = 0;
|
||
|
||
#if !BAKE_FAST
|
||
x_pv_game_music_ptr->stop_reset_flags();
|
||
|
||
delete x_pv_game_music_ptr;
|
||
x_pv_game_music_ptr = 0;
|
||
#endif
|
||
|
||
}
|
||
return true;
|
||
}
|
||
|
||
void x_pv_game_str_array_parse(prj::vector_pair<int32_t, std::string>& str_array, const char* path) {
|
||
msgpack msg;
|
||
|
||
file_stream s;
|
||
s.open(path, "rb");
|
||
io_json_read(s, &msg);
|
||
s.close();
|
||
|
||
if (msg.type != MSGPACK_MAP)
|
||
return;
|
||
|
||
msgpack* curves = msg.read_array("STRA");
|
||
if (curves) {
|
||
msgpack_array* ptr = curves->data.arr;
|
||
str_array.reserve(ptr->size());
|
||
for (msgpack& i : *ptr) {
|
||
msgpack& string = i;
|
||
|
||
int32_t id = string.read_int32_t("ID");
|
||
if (id <= 0)
|
||
continue;
|
||
|
||
str_array.push_back(id, string.read_string("Str"));
|
||
}
|
||
}
|
||
|
||
str_array.sort();
|
||
}
|
||
|
||
void x_pv_game_data_init() {
|
||
x_pv_game_str_array.push_back(0, {});
|
||
x_pv_game_str_array.push_back(1, {});
|
||
x_pv_game_str_array_parse(x_pv_game_str_array[0].second, "patch\\str_array_jp.json");
|
||
x_pv_game_str_array_parse(x_pv_game_str_array[1].second, "patch\\str_array_en.json");
|
||
x_pv_game_str_array_lang_sel = 0;
|
||
}
|
||
|
||
void x_pv_game_data_free() {
|
||
x_pv_game_str_array.clear();
|
||
x_pv_game_str_array.shrink_to_fit();
|
||
}
|
||
|
||
#if BAKE_X_PACK
|
||
bool x_pv_game_baker_init() {
|
||
if (!x_pv_game_baker_ptr)
|
||
x_pv_game_baker_ptr = new XPVGameBaker;
|
||
return true;
|
||
}
|
||
|
||
XPVGameBaker* x_pv_game_baker_get() {
|
||
return x_pv_game_baker_ptr;
|
||
}
|
||
|
||
bool x_pv_game_baker_free() {
|
||
if (x_pv_game_baker_ptr) {
|
||
delete x_pv_game_baker_ptr;
|
||
x_pv_game_baker_ptr = 0;
|
||
}
|
||
return true;
|
||
}
|
||
#else
|
||
bool x_pv_game_selector_init() {
|
||
if (!x_pv_game_selector_ptr)
|
||
x_pv_game_selector_ptr = new XPVGameSelector;
|
||
return true;
|
||
}
|
||
|
||
XPVGameSelector* x_pv_game_selector_get() {
|
||
return x_pv_game_selector_ptr;
|
||
}
|
||
|
||
bool x_pv_game_selector_free() {
|
||
if (x_pv_game_selector_ptr) {
|
||
delete x_pv_game_selector_ptr;
|
||
x_pv_game_selector_ptr = 0;
|
||
}
|
||
return true;
|
||
}
|
||
#endif
|
||
|
||
#if BAKE_DOF
|
||
dof_cam::dof_cam() {
|
||
frame = -999999;
|
||
enable = false;
|
||
}
|
||
|
||
dof_cam::~dof_cam() {
|
||
|
||
}
|
||
|
||
void dof_cam::reset() {
|
||
position_x.clear();
|
||
position_y.clear();
|
||
position_z.clear();
|
||
focus.clear();
|
||
focus_range.clear();
|
||
fuzzing_range.clear();
|
||
ratio.clear();
|
||
enable_frame.clear();
|
||
frame = -999999;
|
||
enable = false;
|
||
}
|
||
#endif
|
||
|
||
static vec4 bright_scale_get(int32_t index, float_t value) {
|
||
static const float_t bright_scale_table[] = {
|
||
1.0f, 1.176f, 0.85f, 1.0f,
|
||
1.0f, 1.176f, 1.176f, 1.176f
|
||
};
|
||
|
||
value = bright_scale_table[index] * value;
|
||
return { value, value, value, 1.0f };
|
||
}
|
||
|
||
static float_t dsc_time_to_frame(int64_t time) {
|
||
return prj::roundf((float_t)time / 1000000000.0f * 60.0f);
|
||
}
|
||
|
||
static vec3 x_pv_game_dof_callback(void* data, int32_t chara_id) {
|
||
x_pv_game_data& pv_data = ((x_pv_game*)data)->get_data();
|
||
if (chara_id >= pv_data.play_param->chara.size())
|
||
return pv_data.chara_effect.get_node_translation(0,
|
||
(int32_t)(chara_id - pv_data.play_param->chara.size()), 0, "j_kao_wj");
|
||
|
||
if (chara_id < 0 && chara_id >= ROB_CHARA_COUNT)
|
||
return 0.0f;
|
||
|
||
rob_chara* rob_chr = rob_chara_array_get(chara_id);
|
||
if (!rob_chr)
|
||
return 0.0f;
|
||
|
||
vec3 trans;
|
||
mat4_get_translation(rob_chr->get_bone_data_mat(MOTION_BONE_CL_KAO), &trans);
|
||
return trans;
|
||
}
|
||
|
||
static void x_pv_game_item_alpha_callback(void* data, int32_t chara_id, int32_t type, float_t alpha) {
|
||
if (!data)
|
||
return;
|
||
|
||
x_pv_game_data& pv_data = ((x_pv_game*)data)->get_data();
|
||
|
||
if (chara_id < 0 || chara_id >= pv_data.play_param->chara.size())
|
||
return;
|
||
|
||
mdl::ObjFlags flags;
|
||
switch (type) {
|
||
case 0:
|
||
default:
|
||
flags = mdl::OBJ_ALPHA_ORDER_1;
|
||
break;
|
||
case 1:
|
||
flags = mdl::OBJ_ALPHA_ORDER_2;
|
||
break;
|
||
case 2:
|
||
flags = mdl::OBJ_ALPHA_ORDER_3;
|
||
break;
|
||
}
|
||
|
||
for (x_pv_game_song_effect& i : pv_data.effect.song_effect) {
|
||
if (i.chara_id != chara_id)
|
||
continue;
|
||
|
||
for (x_pv_game_song_effect_auth_3d& j : i.auth_3d)
|
||
j.id.set_alpha_obj_flags(alpha, flags);
|
||
|
||
for (x_pv_game_song_effect_glitter& j : i.glitter)
|
||
Glitter::glt_particle_manager->SetSceneEffectExtColor(j.scene_counter,
|
||
false, hash_murmurhash_empty, -1.0f, -1.0f, -1.0f, alpha);
|
||
}
|
||
}
|
||
|
||
static void x_pv_game_change_field(x_pv_game* xpvgm, int32_t field, int64_t dsc_time, int64_t curr_time) {
|
||
if (!xpvgm->task_effect_init && (dsc_time > -1 || curr_time > -1)) {
|
||
rand_state_array_4_set_seed_1393939();
|
||
effect_manager_reset();
|
||
xpvgm->task_effect_init = true;
|
||
}
|
||
|
||
light_param_data_storage_data_set_pv_cut(field);
|
||
}
|
||
|
||
#if BAKE_PV826
|
||
static void set_bone_key_set_data(bone_data* bone_data,
|
||
std::map<motion_bone_index, x_pv_game_a3da_to_mot_keys>& bone_keys,
|
||
std::map<motion_bone_index, x_pv_game_a3da_to_mot_keys>& second_bone_keys, bool add_keys,
|
||
motion_bone_index motion_bone_index, mot_key_set* key_set, vec3* data, int32_t count = 1) {
|
||
if (add_keys) {
|
||
auto elem = bone_keys.find(motion_bone_index);
|
||
if (elem == bone_keys.end())
|
||
elem = bone_keys.insert({ motion_bone_index, {} }).first;
|
||
|
||
x_pv_game_a3da_to_mot_keys& keys = elem->second;
|
||
keys.x.push_back(data[0].x);
|
||
keys.y.push_back(data[0].y);
|
||
keys.z.push_back(data[0].z);
|
||
|
||
if (count == 2) {
|
||
auto elem = second_bone_keys.find(motion_bone_index);
|
||
if (elem == second_bone_keys.end())
|
||
elem = second_bone_keys.insert({ motion_bone_index, {} }).first;
|
||
|
||
x_pv_game_a3da_to_mot_keys& keys = elem->second;
|
||
keys.x.push_back(data[1].x);
|
||
keys.y.push_back(data[1].y);
|
||
keys.z.push_back(data[1].z);
|
||
}
|
||
}
|
||
|
||
bone_data += motion_bone_index;
|
||
key_set += bone_data->key_set_offset;
|
||
while (count > 0) {
|
||
if (key_set[0].type == MOT_KEY_SET_STATIC && key_set[0].values)
|
||
*(float_t*)&key_set[0].values[0] = data->x;
|
||
if (key_set[1].type == MOT_KEY_SET_STATIC && key_set[1].values)
|
||
*(float_t*)&key_set[1].values[0] = data->y;
|
||
if (key_set[2].type == MOT_KEY_SET_STATIC && key_set[2].values)
|
||
*(float_t*)&key_set[2].values[0] = data->z;
|
||
key_set += 3;
|
||
data++;
|
||
count--;
|
||
}
|
||
}
|
||
|
||
static void x_pv_game_map_auth_3d_to_mot(x_pv_game* xpvgm, bool add_keys) {
|
||
for (auto& i : xpvgm->effchrpv_auth_3d_rob_mot_ids) {
|
||
rob_chara* rob_chr = rob_chara_array_get(xpvgm->rob_chara_ids[i.first]);
|
||
x_pv_game_a3da_to_mot& a2m = i.second;
|
||
auth_3d* auth = a2m.id.get_auth_3d();
|
||
auth_3d_object_hrc* oh = &auth->object_hrc[0];
|
||
|
||
float_t auth_frame = auth->frame;
|
||
bool auth_frame_changed = auth->frame_changed;
|
||
bool auth_paused = auth->paused;
|
||
auth->frame = (float_t)xpvgm->frame_float;
|
||
auth->frame_changed = false;
|
||
auth->paused = true;
|
||
auth->ctrl(rctx_ptr);
|
||
|
||
rob_chr->set_visibility(oh->node[0].model_transform.visible);
|
||
|
||
motion_blend_mot* mot = rob_chr->bone_data->motion_loaded.front();
|
||
::bone_data* bone_data = mot->bone_data.bones.data();
|
||
mot_key_set* key_set = mot->mot_key_data.mot.key_sets;
|
||
|
||
vec3 data[2];
|
||
data[0] = oh->node[a2m.gblctr].model_transform.translation_value;
|
||
data[0].y = oh->node[a2m.n_hara].model_transform.translation_value.y;
|
||
data[1] = 0.0f;
|
||
set_bone_key_set_data(bone_data, a2m.bone_keys, a2m.sec_bone_keys, add_keys,
|
||
MOTION_BONE_N_HARA_CP, key_set, data, 2);
|
||
|
||
data[0] = oh->node[a2m.n_hara_y].model_transform.rotation_value;
|
||
set_bone_key_set_data(bone_data, a2m.bone_keys, a2m.sec_bone_keys, add_keys,
|
||
MOTION_BONE_KG_HARA_Y, key_set, data);
|
||
|
||
data[0] = oh->node[a2m.j_hara_wj].model_transform.rotation_value;
|
||
set_bone_key_set_data(bone_data, a2m.bone_keys, a2m.sec_bone_keys, add_keys,
|
||
MOTION_BONE_KL_HARA_XZ, key_set, data);
|
||
|
||
data[0] = oh->node[a2m.n_kosi].model_transform.rotation_value;
|
||
set_bone_key_set_data(bone_data, a2m.bone_keys, a2m.sec_bone_keys, add_keys,
|
||
MOTION_BONE_N_HARA, key_set, data);
|
||
|
||
data[0] = { 0.0f, 0.945f, 0.0f };
|
||
mat4_transform_vector(&oh->node[a2m.j_mune_wj].model_transform.mat, &data[0], &data[1]);
|
||
mat4_get_translation(&oh->node[a2m.j_mune_wj].model_transform.mat, &data[0]);
|
||
data[0] += data[1];
|
||
data[1] = 0.0f;
|
||
set_bone_key_set_data(bone_data, a2m.bone_keys, a2m.sec_bone_keys, add_keys,
|
||
MOTION_BONE_CL_MUNE, key_set, data, 2);
|
||
|
||
data[0] = oh->node[a2m.j_mune_b_wj].model_transform.rotation_value;
|
||
set_bone_key_set_data(bone_data, a2m.bone_keys, a2m.sec_bone_keys, add_keys,
|
||
MOTION_BONE_KL_MUNE_B_WJ, key_set, data);
|
||
|
||
data[0] = oh->node[a2m.j_kubi_wj].model_transform.rotation_value;
|
||
set_bone_key_set_data(bone_data, a2m.bone_keys, a2m.sec_bone_keys, add_keys,
|
||
MOTION_BONE_KL_KUBI, key_set, data);
|
||
|
||
data[0] = { (float_t)(M_PI / 2.0), 0.0f, -(float_t)M_PI };
|
||
set_bone_key_set_data(bone_data, a2m.bone_keys, a2m.sec_bone_keys, add_keys,
|
||
MOTION_BONE_N_KAO, key_set, data);
|
||
|
||
data[0] = { 0.0f, 0.40f, 0.0f };
|
||
mat4_transform_vector(&oh->node[a2m.j_kao_wj].model_transform.mat, &data[0], &data[1]);
|
||
mat4_get_translation(&oh->node[a2m.j_kao_wj].model_transform.mat, &data[0]);
|
||
data[0] += data[1];
|
||
data[1] = oh->node[a2m.j_kao_wj].model_transform.rotation_value;
|
||
data[1].x = -data[1].x;
|
||
data[1].z = -data[1].z;
|
||
set_bone_key_set_data(bone_data, a2m.bone_keys, a2m.sec_bone_keys, add_keys,
|
||
MOTION_BONE_CL_KAO, key_set, data, 2);
|
||
|
||
data[0] = oh->node[a2m.j_eye_r_wj].model_transform.rotation_value;
|
||
data[0].x += (float_t)(M_PI / 2.0);
|
||
data[0].y = -data[0].z;
|
||
data[0].z = 0.0f;
|
||
set_bone_key_set_data(bone_data, a2m.bone_keys, a2m.sec_bone_keys, add_keys,
|
||
MOTION_BONE_KL_EYE_R, key_set, data);
|
||
|
||
data[0] = oh->node[a2m.j_eye_l_wj].model_transform.rotation_value;
|
||
data[0].x += (float_t)(M_PI / 2.0);
|
||
data[0].y = -data[0].z;
|
||
data[0].z = 0.0f;
|
||
set_bone_key_set_data(bone_data, a2m.bone_keys, a2m.sec_bone_keys, add_keys,
|
||
MOTION_BONE_KL_EYE_L, key_set, data);
|
||
|
||
data[0] = oh->node[a2m.n_waki_l].model_transform.rotation_value;
|
||
set_bone_key_set_data(bone_data, a2m.bone_keys, a2m.sec_bone_keys, add_keys,
|
||
MOTION_BONE_N_WAKI_L, key_set, data);
|
||
|
||
data[0] = oh->node[a2m.j_waki_l_wj].model_transform.rotation_value;
|
||
set_bone_key_set_data(bone_data, a2m.bone_keys, a2m.sec_bone_keys, add_keys,
|
||
MOTION_BONE_KL_WAKI_L_WJ, key_set, data);
|
||
|
||
{
|
||
vec3 pos_j_kata_l_wj;
|
||
vec3 pos_j_ude_l_wj;
|
||
vec3 pos_j_te_l_wj;
|
||
mat4_get_translation(&oh->node[a2m.j_kata_l_wj].model_transform.mat, &pos_j_kata_l_wj);
|
||
mat4_get_translation(&oh->node[a2m.j_ude_l_wj].model_transform.mat, &pos_j_ude_l_wj);
|
||
mat4_get_translation(&oh->node[a2m.j_te_l_wj].model_transform.mat, &pos_j_te_l_wj);
|
||
|
||
vec3 tl_up_kata_dir = pos_j_ude_l_wj - vec3::lerp(pos_j_kata_l_wj, pos_j_te_l_wj, 0.5f);
|
||
float_t pos_middle_dist = vec3::length(tl_up_kata_dir);
|
||
if (pos_middle_dist == 0.0f) {
|
||
mat4& mat = oh->node[a2m.j_kata_l_wj].model_transform.mat;
|
||
data[0] = { 0.0f, 0.3f, 0.0f };
|
||
mat4_transform_vector(&mat, &data[0], &tl_up_kata_dir);
|
||
}
|
||
else
|
||
tl_up_kata_dir *= 0.3f / pos_middle_dist;
|
||
|
||
vec3 tl_up_kata_pos = tl_up_kata_dir + pos_j_ude_l_wj;
|
||
mat4& mat = oh->node[a2m.j_mune_b_wj].model_transform.mat;
|
||
mat4_inverse_transform_point(&mat, &tl_up_kata_pos, &data[0]);
|
||
set_bone_key_set_data(bone_data, a2m.bone_keys, a2m.sec_bone_keys, add_keys,
|
||
MOTION_BONE_TL_UP_KATA_L, key_set, data);
|
||
}
|
||
|
||
mat4_get_translation(&oh->node[a2m.j_te_l_wj].model_transform.mat, &data[0]);
|
||
data[1] = { -(float_t)(M_PI / 2.0), -(float_t)(M_PI / 2.0), -(float_t)(M_PI / 2.0) };
|
||
set_bone_key_set_data(bone_data, a2m.bone_keys, a2m.sec_bone_keys, add_keys,
|
||
MOTION_BONE_C_KATA_L, key_set, data, 2);
|
||
|
||
data[0] = oh->node[a2m.j_te_l_wj].model_transform.rotation_value;
|
||
set_bone_key_set_data(bone_data, a2m.bone_keys, a2m.sec_bone_keys, add_keys,
|
||
MOTION_BONE_KL_TE_L_WJ, key_set, data);
|
||
|
||
data[0] = oh->node[a2m.n_waki_r].model_transform.rotation_value;
|
||
set_bone_key_set_data(bone_data, a2m.bone_keys, a2m.sec_bone_keys, add_keys,
|
||
MOTION_BONE_N_WAKI_R, key_set, data);
|
||
|
||
data[0] = oh->node[a2m.j_waki_l_wj].model_transform.rotation_value;
|
||
set_bone_key_set_data(bone_data, a2m.bone_keys, a2m.sec_bone_keys, add_keys,
|
||
MOTION_BONE_KL_WAKI_R_WJ, key_set, data);
|
||
|
||
{
|
||
vec3 pos_j_kata_r_wj;
|
||
vec3 pos_j_ude_r_wj;
|
||
vec3 pos_j_te_r_wj;
|
||
mat4_get_translation(&oh->node[a2m.j_kata_r_wj].model_transform.mat, &pos_j_kata_r_wj);
|
||
mat4_get_translation(&oh->node[a2m.j_ude_r_wj].model_transform.mat, &pos_j_ude_r_wj);
|
||
mat4_get_translation(&oh->node[a2m.j_te_r_wj].model_transform.mat, &pos_j_te_r_wj);
|
||
|
||
vec3 tl_up_kata_dir = pos_j_ude_r_wj - vec3::lerp(pos_j_kata_r_wj, pos_j_te_r_wj, 0.5f);
|
||
float_t pos_middle_dist = vec3::length(tl_up_kata_dir);
|
||
if (pos_middle_dist == 0.0f) {
|
||
mat4& mat = oh->node[a2m.j_kata_r_wj].model_transform.mat;
|
||
data[0] = { 0.0f, 0.3f, 0.0f };
|
||
mat4_transform_vector(&mat, &data[0], &tl_up_kata_dir);
|
||
}
|
||
else
|
||
tl_up_kata_dir *= 0.3f / pos_middle_dist;
|
||
|
||
vec3 tl_up_kata_pos = tl_up_kata_dir + pos_j_ude_r_wj;
|
||
mat4& mat = oh->node[a2m.j_mune_b_wj].model_transform.mat;
|
||
mat4_inverse_transform_point(&mat, &tl_up_kata_pos, &data[0]);
|
||
set_bone_key_set_data(bone_data, a2m.bone_keys, a2m.sec_bone_keys, add_keys,
|
||
MOTION_BONE_TL_UP_KATA_R, key_set, data);
|
||
}
|
||
|
||
mat4_get_translation(&oh->node[a2m.j_te_r_wj].model_transform.mat, &data[0]);
|
||
data[1] = { -(float_t)(M_PI / 2.0), (float_t)(M_PI / 2.0), (float_t)(M_PI / 2.0) };
|
||
set_bone_key_set_data(bone_data, a2m.bone_keys, a2m.sec_bone_keys, add_keys,
|
||
MOTION_BONE_C_KATA_R, key_set, data, 2);
|
||
|
||
data[0] = oh->node[a2m.j_te_r_wj].model_transform.rotation_value;
|
||
set_bone_key_set_data(bone_data, a2m.bone_keys, a2m.sec_bone_keys, add_keys,
|
||
MOTION_BONE_KL_TE_R_WJ, key_set, data);
|
||
|
||
mat4_get_translation(&oh->node[a2m.j_asi_l_wj].model_transform.mat, &data[0]);
|
||
data[0].y -= 0.033f;
|
||
if (data[0].y < 0.103f)
|
||
data[0].y = 0.103f;
|
||
data[1] = oh->node[a2m.j_momo_l_wj].model_transform.rotation_value;
|
||
data[1].z -= (float_t)(M_PI / 2.0);
|
||
set_bone_key_set_data(bone_data, a2m.bone_keys, a2m.sec_bone_keys, add_keys,
|
||
MOTION_BONE_CL_MOMO_L, key_set, data, 2);
|
||
|
||
mat4_get_translation(&oh->node[a2m.j_asi_r_wj].model_transform.mat, &data[0]);
|
||
data[0].y -= 0.033f;
|
||
if (data[0].y < 0.103f)
|
||
data[0].y = 0.103f;
|
||
data[1] = oh->node[a2m.j_momo_r_wj].model_transform.rotation_value;
|
||
data[1].z -= (float_t)(M_PI / 2.0);
|
||
set_bone_key_set_data(bone_data, a2m.bone_keys, a2m.sec_bone_keys, add_keys,
|
||
MOTION_BONE_CL_MOMO_R, key_set, data, 2);
|
||
|
||
data[0] = oh->node[a2m.j_asi_l_wj].model_transform.rotation_value;
|
||
set_bone_key_set_data(bone_data, a2m.bone_keys, a2m.sec_bone_keys, add_keys,
|
||
MOTION_BONE_KL_ASI_L_WJ_CO, key_set, data);
|
||
|
||
data[0] = oh->node[a2m.j_asi_r_wj].model_transform.rotation_value;
|
||
set_bone_key_set_data(bone_data, a2m.bone_keys, a2m.sec_bone_keys, add_keys,
|
||
MOTION_BONE_KL_ASI_R_WJ_CO, key_set, data);
|
||
|
||
data[0] = { 0.0491406508f, 0.0f, 0.0f };
|
||
set_bone_key_set_data(bone_data, a2m.bone_keys, a2m.sec_bone_keys, add_keys,
|
||
MOTION_BONE_KL_AGO_WJ, key_set, data);
|
||
|
||
data[0] = { 0.0f, 0.0331281610f, 0.0f };
|
||
set_bone_key_set_data(bone_data, a2m.bone_keys, a2m.sec_bone_keys, add_keys,
|
||
MOTION_BONE_N_KUBI_WJ_EX, key_set, data);
|
||
|
||
auth->frame = auth_frame;
|
||
auth->frame_changed = auth_frame_changed;
|
||
auth->paused = auth_paused;
|
||
}
|
||
}
|
||
#endif
|
||
|
||
static void x_pv_game_reset_field(x_pv_game* xpvgm) {
|
||
|
||
}
|
||
|
||
struct x_pv_game_auth_3d_hrc_obj_sub_mesh {
|
||
std::vector<uint32_t> indices;
|
||
|
||
x_pv_game_auth_3d_hrc_obj_sub_mesh() {
|
||
|
||
}
|
||
|
||
~x_pv_game_auth_3d_hrc_obj_sub_mesh() {
|
||
|
||
}
|
||
};
|
||
|
||
struct x_pv_game_auth_3d_hrc_obj_mesh {
|
||
std::vector<x_pv_game_auth_3d_hrc_obj_sub_mesh> sub_meshes;
|
||
std::vector<uint32_t> vertex_indices;
|
||
std::vector<obj_vertex_data> vertices;
|
||
|
||
x_pv_game_auth_3d_hrc_obj_mesh() {
|
||
|
||
}
|
||
|
||
~x_pv_game_auth_3d_hrc_obj_mesh() {
|
||
|
||
}
|
||
};
|
||
|
||
struct x_pv_game_auth_3d_hrc_obj_bone {
|
||
uint32_t src_id;
|
||
std::string dst_name;
|
||
int32_t index;
|
||
std::vector<x_pv_game_auth_3d_hrc_obj_mesh> meshes;
|
||
|
||
x_pv_game_auth_3d_hrc_obj_bone() {
|
||
src_id = -1;
|
||
index = -1;
|
||
}
|
||
|
||
~x_pv_game_auth_3d_hrc_obj_bone() {
|
||
|
||
}
|
||
};
|
||
|
||
static int x_pv_game_auth_3d_hrc_obj_bone_compare_func(void const* src1, void const* src2) {
|
||
x_pv_game_auth_3d_hrc_obj_bone* bone1 = (x_pv_game_auth_3d_hrc_obj_bone*)src1;
|
||
x_pv_game_auth_3d_hrc_obj_bone* bone2 = (x_pv_game_auth_3d_hrc_obj_bone*)src2;
|
||
return bone1->dst_name.compare(bone2->dst_name);
|
||
}
|
||
|
||
static void auth_3d_key_rev(auth_3d_key& k, std::vector<float_t>& values_src) {
|
||
std::vector<kft3> values;
|
||
int32_t type = interpolate_chs_reverse_sequence(values_src, values);
|
||
|
||
k = {};
|
||
switch (type) {
|
||
case A3DA_KEY_NONE:
|
||
k.type = AUTH_3D_KEY_NONE;
|
||
k.value = 0.0f;
|
||
return;
|
||
case A3DA_KEY_STATIC:
|
||
k.type = values[0].value != 0.0f ? AUTH_3D_KEY_STATIC : AUTH_3D_KEY_NONE;
|
||
k.value = values[0].value;
|
||
return;
|
||
case A3DA_KEY_LINEAR:
|
||
k.type = AUTH_3D_KEY_LINEAR;
|
||
break;
|
||
case A3DA_KEY_HERMITE:
|
||
default:
|
||
k.type = AUTH_3D_KEY_HERMITE;
|
||
break;
|
||
case A3DA_KEY_HOLD:
|
||
k.type = AUTH_3D_KEY_HOLD;
|
||
break;
|
||
}
|
||
|
||
k.max_frame = (float_t)(values_src.size() + 1);
|
||
k.frame_delta = k.max_frame;
|
||
k.value_delta = 0.0f;
|
||
|
||
size_t length = values.size();
|
||
if (length > 1) {
|
||
k.keys_vec.assign(values.begin(), values.end());
|
||
k.length = length;
|
||
k.keys = k.keys_vec.data();
|
||
|
||
kft3* first_key = &k.keys[0];
|
||
kft3* last_key = &k.keys[length - 1];
|
||
if (first_key->frame < last_key->frame
|
||
&& last_key->frame > 0.0f && k.max_frame > first_key->frame) {
|
||
k.ep_type_pre = AUTH_3D_EP_NONE;
|
||
k.ep_type_post = AUTH_3D_EP_NONE;
|
||
k.frame_delta = last_key->frame - first_key->frame;
|
||
k.value_delta = last_key->value - first_key->value;
|
||
}
|
||
}
|
||
else if (length == 1) {
|
||
float_t value = values.front().value;
|
||
k.type = value != 0.0f ? AUTH_3D_KEY_STATIC : AUTH_3D_KEY_NONE;
|
||
k.value = value;
|
||
}
|
||
else {
|
||
k.type = AUTH_3D_KEY_NONE;
|
||
k.value = 0.0f;
|
||
}
|
||
}
|
||
|
||
#if BAKE_X_PACK
|
||
static void x_pv_game_update_object_set(ObjsetInfo* info) {
|
||
prj::shared_ptr<prj::stack_allocator> old_alloc = info->alloc_handler;
|
||
|
||
prj::shared_ptr<prj::stack_allocator>& alloc = info->alloc_handler;
|
||
alloc = prj::shared_ptr<prj::stack_allocator>(new prj::stack_allocator);
|
||
|
||
obj_set* set = alloc->allocate<obj_set>();
|
||
set->move_data(info->obj_set, alloc);
|
||
info->obj_set = set;
|
||
}
|
||
|
||
static void x_pv_game_write_aet(uint32_t aet_set_id,
|
||
const aet_database* aet_db, aet_database_file* x_pack_aet_db,
|
||
const sprite_database_file* x_pack_spr_db) {
|
||
const aet_db_aet_set* aet_set_db = aet_db->get_aet_set_by_id(aet_set_id);
|
||
|
||
::aet_set* aet_set = aet_manager_get_set(aet_set_id, aet_db);
|
||
|
||
prj::shared_ptr<prj::stack_allocator> alloc(new prj::stack_allocator);
|
||
::aet_set* set = alloc->allocate<::aet_set>();
|
||
set->move_data(aet_set, alloc);
|
||
|
||
uint32_t id = -1;
|
||
uint32_t aet_id = -1;
|
||
for (aet_db_aet_set_file& i : x_pack_aet_db->aet_set) {
|
||
if ((int32_t)id < (int32_t)i.id)
|
||
id = i.id;
|
||
|
||
for (aet_db_aet_file& j : i.aet)
|
||
if ((int32_t)aet_id < (int32_t)j.id)
|
||
aet_id = i.id;
|
||
}
|
||
id++;
|
||
aet_id++;
|
||
|
||
|
||
uint32_t index = x_pack_aet_db->aet_set.back().index + 1;
|
||
|
||
x_pack_aet_db->aet_set.push_back({});
|
||
aet_db_aet_set_file& aet_db_aet_set = x_pack_aet_db->aet_set.back();
|
||
|
||
aet_db_aet_set.id = id++;
|
||
aet_db_aet_set.name.assign(aet_set_db->name);
|
||
aet_db_aet_set.file_name.assign(aet_set_db->file_name);
|
||
aet_db_aet_set.index = index;
|
||
|
||
replace_stgpv_pv(aet_db_aet_set.name);
|
||
replace_stgpv_pv(aet_db_aet_set.file_name);
|
||
|
||
size_t pos = aet_db_aet_set.file_name.rfind(".aec");
|
||
if (pos != -1)
|
||
aet_db_aet_set.file_name.replace(pos, 4, ".bin");
|
||
|
||
std::string sprite_set_name("SPR_");
|
||
sprite_set_name.append(aet_db_aet_set.name, 4);
|
||
|
||
uint32_t sprite_set_hash = hash_string_murmurhash(sprite_set_name);
|
||
for (const spr_db_spr_set_file& i : x_pack_spr_db->sprite_set)
|
||
if (sprite_set_hash == hash_string_murmurhash(i.name)) {
|
||
aet_db_aet_set.sprite_set_id = i.id;
|
||
break;
|
||
}
|
||
|
||
aet_db_aet_set.aet.reserve(1);
|
||
|
||
for (uint32_t i = 0; i < 1; i++) {
|
||
const aet_db_aet* aet = aet_db->get_aet_by_set_id_index(aet_set_id, i);
|
||
|
||
aet_db_aet_set.aet.push_back({});
|
||
aet_db_aet_file& aet_file = aet_db_aet_set.aet.back();
|
||
aet_file.name.assign(aet->name);
|
||
replace_stgpv_pv(aet_file.name);
|
||
aet_file.id = aet_id++;
|
||
aet_file.index = i;
|
||
}
|
||
|
||
set->modern = false;
|
||
set->big_endian = false;
|
||
set->is_x = false;
|
||
|
||
uint32_t scenes_count = set->scenes_count;
|
||
const aet_scene** scenes = set->scenes;
|
||
|
||
for (uint32_t i = 0; i < scenes_count; i++) {
|
||
const aet_scene* scene = scenes[i];
|
||
|
||
const aet_comp* comp = scene->comp;
|
||
for (uint32_t j = scene->comp_count; j; j--, comp++) {
|
||
const aet_layer* layer = comp->layers;
|
||
for (uint32_t k = comp->layers_count; k; k--, layer++) {
|
||
replace_stgpv_pv((char*)layer->name);
|
||
|
||
if (layer->markers) {
|
||
const aet_marker* marker = layer->markers;
|
||
for (uint32_t l = layer->markers_count; l; l--, marker++)
|
||
replace_stgpv_pv((char*)marker->name);
|
||
}
|
||
}
|
||
}
|
||
|
||
const aet_video* video = scene->video;
|
||
for (uint32_t j = scene->video_count; j; j--, video++) {
|
||
if (!video->sources)
|
||
continue;
|
||
|
||
const aet_video_src* source = video->sources;
|
||
for (uint32_t k = video->sources_count; k; k--, source++) {
|
||
replace_stgpv_pv((char*)source->sprite_name);
|
||
|
||
std::string name("SPR_");
|
||
name.append(source->sprite_name);
|
||
|
||
uint32_t hash = hash_string_murmurhash(name);
|
||
for (const spr_db_spr_set_file& l : x_pack_spr_db->sprite_set)
|
||
for (const spr_db_spr_file& m : l.sprite)
|
||
if (hash == hash_string_murmurhash(m.name)) {
|
||
*(uint32_t*)&source->sprite_index = m.id;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
replace_stgpv_pv((char*)scene->name);
|
||
}
|
||
|
||
file_stream s;
|
||
|
||
void* data = 0;
|
||
size_t size = 0;
|
||
set->pack_file(&data, &size);
|
||
|
||
char buf[0x200];
|
||
strcpy_s(buf, sizeof(buf), "patch\\!temp\\2d\\");
|
||
strcat_s(buf, sizeof(buf), aet_db_aet_set.file_name.c_str());
|
||
|
||
file_stream s_dsc;
|
||
s_dsc.open(buf, "wb");
|
||
s_dsc.write(data, size);
|
||
s_dsc.close();
|
||
free_def(data);
|
||
}
|
||
|
||
static bool x_pv_game_write_auth_3d(farc* f, auth_3d* auth,
|
||
auth_3d_database_file* auth_3d_db, const char* category) {
|
||
char name[0x200];
|
||
if (!get_replace_auth_name(name, sizeof(name), auth))
|
||
return false;
|
||
|
||
a3da a;
|
||
float_t max_frame = auth->max_frame;
|
||
auth->max_frame = auth->play_control.size;
|
||
auth->store(&a);
|
||
auth->max_frame = max_frame;
|
||
a._converter_version.assign("20111019");
|
||
a._file_name.assign(name);
|
||
a._file_name.append(".a3da");
|
||
a._property_version.assign("20110526");
|
||
a.ready = true;
|
||
a.compressed = true;
|
||
a.format = A3DA_FORMAT_AFT_X_PACK;
|
||
|
||
for (a3da_m_object_hrc& i : a.m_object_hrc) {
|
||
for (a3da_object_instance& j : i.instance) {
|
||
replace_names(j.name);
|
||
replace_names(j.uid_name);
|
||
}
|
||
|
||
replace_names(i.name);
|
||
}
|
||
|
||
for (std::string& i : a.m_object_hrc_list)
|
||
replace_names(i);
|
||
|
||
for (a3da_object& i : a.object) {
|
||
replace_names(i.name);
|
||
replace_names(i.parent_name);
|
||
replace_names(i.uid_name);
|
||
|
||
for (a3da_object_texture_pattern& j : i.texture_pattern)
|
||
replace_names(j.name);
|
||
|
||
for (a3da_object_texture_transform& j : i.texture_transform)
|
||
replace_names(j.name);
|
||
}
|
||
|
||
for (a3da_object_hrc& i : a.object_hrc) {
|
||
replace_names(i.name);
|
||
replace_names(i.parent_name);
|
||
replace_names(i.uid_name);
|
||
}
|
||
|
||
for (std::string& i : a.object_hrc_list)
|
||
replace_names(i);
|
||
|
||
|
||
for (std::string& i : a.object_list)
|
||
replace_names(i);
|
||
|
||
bool own_farc = !f;
|
||
|
||
if (own_farc)
|
||
f = new farc;
|
||
|
||
farc_file* ff = f->add_file(name);
|
||
ff->name.append(".a3da");
|
||
a.write(&ff->data, &ff->size);
|
||
|
||
if (own_farc) {
|
||
char path[MAX_PATH];
|
||
strcpy_s(path, sizeof(path), "patch\\!temp\\auth_3d\\");
|
||
strcat_s(path, sizeof(path), name);
|
||
|
||
f->write(path, FARC_FArC, FARC_NONE, false);
|
||
delete f;
|
||
|
||
auth_3d_db->category.push_back(name);
|
||
}
|
||
|
||
auth_3d_db->uid.push_back({});
|
||
auth_3d_database_uid_file& uid = auth_3d_db->uid.back();
|
||
uid.flags = (auth_3d_database_uid_flags)(AUTH_3D_DATABASE_UID_SIZE | AUTH_3D_DATABASE_UID_ORG_UID);
|
||
uid.category.assign(own_farc ? name : category);
|
||
uid.org_uid = auth_3d_db->uid_max++;
|
||
uid.size = auth->play_control.size;
|
||
uid.value.assign("A ");
|
||
uid.value.append(name);
|
||
return true;
|
||
}
|
||
|
||
static void x_pv_game_write_dsc(const dsc& d, int32_t pv_id) {
|
||
data_struct* aft_data = &data_list[DATA_AFT];
|
||
|
||
dsc _d = d;
|
||
{
|
||
std::vector<dsc_data> data_temp;
|
||
data_temp.reserve(_d.data.size());
|
||
|
||
for (const dsc_data& i : _d.data)
|
||
switch (i.func) {
|
||
case DSC_X_TARGET:
|
||
case DSC_X_TARGET_FLYING_TIME:
|
||
case DSC_X_DOF:
|
||
break;
|
||
default:
|
||
data_temp.push_back(i);
|
||
break;
|
||
}
|
||
|
||
_d.data.assign(data_temp.begin(), data_temp.end());
|
||
data_temp.clear();
|
||
_d.rebuild();
|
||
}
|
||
|
||
for (const dsc_data& i : _d.data) {
|
||
if (i.func != DSC_X_MOUTH_ANIM)
|
||
continue;
|
||
|
||
int32_t* data = _d.get_func_data(&i);
|
||
|
||
int32_t& mouth_anim_id = data[2];
|
||
switch (mouth_anim_id) {
|
||
case 4: mouth_anim_id = 34; break;
|
||
case 5: mouth_anim_id = 35; break;
|
||
case 6: mouth_anim_id = 36; break;
|
||
case 7: mouth_anim_id = 37; break;
|
||
case 8: mouth_anim_id = 38; break;
|
||
case 9: mouth_anim_id = 39; break;
|
||
case 10: mouth_anim_id = 4; break;
|
||
case 11: mouth_anim_id = 5; break;
|
||
case 12: mouth_anim_id = 6; break;
|
||
case 13: mouth_anim_id = 7; break;
|
||
case 14: mouth_anim_id = 8; break;
|
||
case 15: mouth_anim_id = 9; break;
|
||
case 16: mouth_anim_id = 10; break;
|
||
case 17: mouth_anim_id = 11; break;
|
||
case 18: mouth_anim_id = 12; break;
|
||
case 19: mouth_anim_id = 13; break;
|
||
case 20: mouth_anim_id = 14; break;
|
||
case 21: mouth_anim_id = 15; break;
|
||
case 22: mouth_anim_id = 16; break;
|
||
case 23: mouth_anim_id = 17; break;
|
||
case 24: mouth_anim_id = 18; break;
|
||
case 25: mouth_anim_id = 19; break;
|
||
case 26: mouth_anim_id = 20; break;
|
||
case 27: mouth_anim_id = 21; break;
|
||
case 28: mouth_anim_id = 22; break;
|
||
case 29: mouth_anim_id = 40; break;
|
||
case 30: mouth_anim_id = 41; break;
|
||
case 31: mouth_anim_id = 42; break;
|
||
}
|
||
}
|
||
|
||
_d.convert(DSC_FT);
|
||
_d.signature = 0x14050921;
|
||
|
||
char file_buf[0x200];
|
||
|
||
const char* dsc_diffs[] = {
|
||
"easy",
|
||
"normal",
|
||
"hard",
|
||
"extreme",
|
||
"extreme_1",
|
||
};
|
||
|
||
for (const char*& i : dsc_diffs) {
|
||
dsc dsc_chart;
|
||
sprintf_s(file_buf, sizeof(file_buf), "pv_%03d_%s.dsc", pv_id == 832 ? 800 : pv_id, i);
|
||
if (!aft_data->load_file(&dsc_chart, "rom/script/", file_buf, dsc::load_file))
|
||
continue;
|
||
|
||
{
|
||
std::vector<dsc_data> data_temp;
|
||
data_temp.reserve(dsc_chart.data.size());
|
||
|
||
for (const dsc_data& i : dsc_chart.data)
|
||
switch (i.func) {
|
||
case DSC_X_TIME:
|
||
case DSC_X_TARGET:
|
||
case DSC_X_TARGET_FLYING_TIME:
|
||
data_temp.push_back(i);
|
||
break;
|
||
}
|
||
|
||
dsc_chart.data.assign(data_temp.begin(), data_temp.end());
|
||
data_temp.clear();
|
||
dsc_chart.rebuild();
|
||
}
|
||
|
||
dsc dsc_merge;
|
||
dsc_merge.merge(2, &_d, &dsc_chart);
|
||
|
||
void* dsc_data = 0;
|
||
size_t dsc_length = 0;
|
||
dsc_merge.unparse(&dsc_data, &dsc_length);
|
||
|
||
char path[MAX_PATH];
|
||
strcpy_s(path, sizeof(path), "patch\\!temp\\script\\");
|
||
sprintf_s(file_buf, sizeof(file_buf), "pv_%03d_%s.dsc", pv_id == 832 ? 800 : pv_id, i);
|
||
strcat_s(path, sizeof(path), file_buf);
|
||
|
||
file_stream s_dsc;
|
||
s_dsc.open(path, "wb");
|
||
s_dsc.write(dsc_data, dsc_length);
|
||
s_dsc.close();
|
||
|
||
free_def(dsc_data);
|
||
}
|
||
|
||
_d = d;
|
||
{
|
||
std::vector<dsc_data> data_temp;
|
||
data_temp.reserve(_d.data.size());
|
||
|
||
for (const dsc_data& i : _d.data)
|
||
switch (i.func) {
|
||
case DSC_X_END:
|
||
case DSC_X_TIME:
|
||
case DSC_X_CHANGE_FIELD:
|
||
case DSC_X_CREDIT_TITLE:
|
||
case DSC_X_BAR_POINT:
|
||
case DSC_X_BEAT_POINT:
|
||
case DSC_X_STAGE_EFFECT:
|
||
case DSC_X_SONG_EFFECT:
|
||
case DSC_X_SONG_EFFECT_ATTACH:
|
||
case DSC_X_SET_STAGE_EFFECT_ENV:
|
||
case DSC_X_CHARA_EFFECT:
|
||
data_temp.push_back(i);
|
||
break;
|
||
}
|
||
|
||
_d.data.assign(data_temp.begin(), data_temp.end());
|
||
data_temp.clear();
|
||
_d.rebuild();
|
||
}
|
||
|
||
void* dsc_data = 0;
|
||
size_t dsc_length = 0;
|
||
_d.unparse(&dsc_data, &dsc_length);
|
||
|
||
char path[MAX_PATH];
|
||
strcpy_s(path, sizeof(path), "patch\\!temp\\pv_script\\");
|
||
sprintf_s(file_buf, sizeof(file_buf), "pv_%03d.dsc", pv_id == 832 ? 800 : pv_id);
|
||
strcat_s(path, sizeof(path), file_buf);
|
||
|
||
file_stream s_dsc;
|
||
s_dsc.open(path, "wb");
|
||
s_dsc.write(dsc_data, dsc_length);
|
||
s_dsc.close();
|
||
free_def(dsc_data);
|
||
}
|
||
|
||
static void x_pv_game_write_glitter(Glitter::EffectGroup* eff_group, const auth_3d_database* x_pack_auth_3d_db,
|
||
const object_database* obj_db, const object_database* x_pack_obj_db) {
|
||
Glitter::EffectGroup temp_eff_group(Glitter::X);
|
||
temp_eff_group.name.assign(eff_group->name);
|
||
temp_eff_group.version = eff_group->version;
|
||
|
||
temp_eff_group.effects.reserve(eff_group->effects.size());
|
||
for (Glitter::Effect* i : eff_group->effects) {
|
||
Glitter::Effect* eff = new Glitter::Effect(Glitter::X);
|
||
*eff = *i;
|
||
temp_eff_group.effects.push_back(eff);
|
||
}
|
||
|
||
temp_eff_group.emission = eff_group->emission;
|
||
temp_eff_group.resources_count = eff_group->resources_count;
|
||
temp_eff_group.resource_hashes.assign(
|
||
eff_group->resource_hashes.begin(), eff_group->resource_hashes.end());
|
||
temp_eff_group.resources_tex = eff_group->resources_tex;
|
||
temp_eff_group.version = eff_group->version;
|
||
|
||
char name[0x200];
|
||
strcpy_s(name, sizeof(name), eff_group->name.c_str());
|
||
|
||
replace_names(name);
|
||
|
||
data_struct* x_data = &data_list[DATA_X];
|
||
auto& hashes = x_data->glitter_list_murmurhash;
|
||
for (Glitter::Effect*& i : temp_eff_group.effects) {
|
||
if (!i)
|
||
continue;
|
||
|
||
Glitter::Effect* e = i;
|
||
e->name.clear();
|
||
if (e->data.name_hash == hash_murmurhash_empty)
|
||
continue;
|
||
|
||
auto elem = hashes.find(e->data.name_hash);
|
||
if (elem == hashes.end()) {
|
||
printf_debug("Couldn't find name for hash 0x%08X\n", e->data.name_hash);
|
||
continue;
|
||
}
|
||
|
||
e->name.assign(elem->second);
|
||
replace_names(e->name);
|
||
|
||
if (!e->data.ext_anim_x
|
||
|| (e->data.ext_anim_x->flags & Glitter::EFFECT_EXT_ANIM_CHARA_ANIM))
|
||
continue;
|
||
|
||
Glitter::Effect::ExtAnimX* ext_anim = e->data.ext_anim_x;
|
||
|
||
uint32_t file_name_hash = ext_anim->file_name_hash;
|
||
uint32_t object_hash = ext_anim->object_hash;
|
||
uint32_t instance_id = ext_anim->instance_id;
|
||
for (int32_t& i : auth_3d_data->loaded_ids) {
|
||
if (i < 0 || (i & 0x7FFF) >= AUTH_3D_DATA_COUNT)
|
||
continue;
|
||
|
||
auth_3d* auth = &auth_3d_data->data[i & 0x7FFF];
|
||
if (auth->id != i)
|
||
continue;
|
||
|
||
bool ret = false;
|
||
if (file_name_hash != hash_murmurhash_empty) {
|
||
if (auth->hash != file_name_hash)
|
||
continue;
|
||
|
||
ret = true;
|
||
}
|
||
|
||
std::string uid_name;
|
||
if (instance_id < 0) {
|
||
for (auth_3d_object& i : auth->object)
|
||
if (object_hash == i.object_hash) {
|
||
uid_name.assign(i.uid_name);
|
||
ret = false;
|
||
break;
|
||
}
|
||
|
||
if (!uid_name.size())
|
||
for (auth_3d_object_hrc& i : auth->object_hrc)
|
||
if (object_hash == i.object_hash) {
|
||
uid_name.assign(i.uid_name);
|
||
ret = false;
|
||
break;
|
||
}
|
||
}
|
||
else {
|
||
int32_t obj_instance = 0;
|
||
for (auth_3d_object& i : auth->object)
|
||
if (object_hash == i.object_hash) {
|
||
if (obj_instance == instance_id) {
|
||
uid_name.assign(i.uid_name);
|
||
ret = false;
|
||
break;
|
||
}
|
||
obj_instance++;
|
||
}
|
||
|
||
if (!uid_name.size()) {
|
||
int32_t obj_hrc_instance = 0;
|
||
for (auth_3d_object_hrc& i : auth->object_hrc)
|
||
if (object_hash == i.object_hash) {
|
||
if (obj_hrc_instance == instance_id) {
|
||
uid_name.assign(i.uid_name);
|
||
ret = false;
|
||
break;
|
||
}
|
||
obj_hrc_instance++;
|
||
}
|
||
}
|
||
}
|
||
|
||
if (ret) {
|
||
End:
|
||
free(e->data.ext_anim_x);
|
||
e->data.ext_anim_x = 0;
|
||
break;
|
||
}
|
||
else if (!uid_name.size())
|
||
continue;
|
||
|
||
replace_names(uid_name);
|
||
object_info info = x_pack_obj_db->get_object_info(uid_name.c_str());
|
||
ext_anim->object_hash = ((uint32_t)(uint16_t)info.set_id << 16) | (uint32_t)(uint16_t)info.id;
|
||
|
||
if (ext_anim->file_name_hash == hash_murmurhash_empty) {
|
||
ext_anim->file_name_hash = -1;
|
||
break;
|
||
}
|
||
|
||
char auth_name[0x200];
|
||
if (!get_replace_auth_name(auth_name, sizeof(auth_name), auth))
|
||
goto End;
|
||
|
||
ext_anim->file_name_hash = x_pack_auth_3d_db->get_uid(auth_name);
|
||
break;
|
||
}
|
||
}
|
||
|
||
for (Glitter::Effect*& i : temp_eff_group.effects) {
|
||
if (!i)
|
||
continue;
|
||
|
||
Glitter::Effect* eff = i;
|
||
if (eff->data.name_hash == hash_murmurhash_empty)
|
||
continue;
|
||
|
||
for (Glitter::Emitter*& j : eff->emitters) {
|
||
if (!j)
|
||
continue;
|
||
|
||
Glitter::Emitter* emit = j;
|
||
|
||
for (Glitter::Particle*& k : emit->particles) {
|
||
if (!k)
|
||
continue;
|
||
|
||
Glitter::Particle* ptcl = k;
|
||
if (ptcl->data.type != Glitter::PARTICLE_MESH)
|
||
continue;
|
||
|
||
object_info info;
|
||
info.set_id = (uint32_t)ptcl->data.mesh.object_set_name_hash;
|
||
info.id = (uint32_t)ptcl->data.mesh.object_name_hash;
|
||
info = replace_object_info(info, obj_db, x_pack_obj_db);
|
||
ptcl->data.mesh.object_set_name_hash = info.set_id;
|
||
ptcl->data.mesh.object_name_hash = info.id;
|
||
}
|
||
}
|
||
}
|
||
|
||
Glitter::FileWriter::Write(Glitter::X, &temp_eff_group, "patch\\!temp\\particle_x\\",
|
||
name, (Glitter::FileWriterFlags)(Glitter::FILE_WRITER_COMPRESS
|
||
| Glitter::FILE_WRITER_ENCRYPT | Glitter::FILE_WRITER_NO_LIST));
|
||
}
|
||
|
||
static void x_pv_game_write_object_set(ObjsetInfo* info,
|
||
object_database_file* x_pack_obj_db, const texture_database* tex_db,
|
||
const texture_database* x_pack_tex_db_base, texture_database_file* x_pack_tex_db) {
|
||
char name[0x200];
|
||
strcpy_s(name, sizeof(name), info->name.c_str());
|
||
|
||
for (size_t j = 0; j < sizeof(name) && name[j]; j++) {
|
||
char c = name[j];
|
||
if (c >= 'A' && c <= 'Z')
|
||
name[j] += 0x20;
|
||
}
|
||
|
||
replace_names(name);
|
||
|
||
if (strstr(name, "effchrpv826"))
|
||
return;
|
||
|
||
int32_t object_set_max_id = -1;
|
||
for (object_set_info_file& i : x_pack_obj_db->object_set)
|
||
object_set_max_id = max_def(object_set_max_id, (int32_t)i.id);
|
||
|
||
int32_t texture_max_id = -1;
|
||
for (texture_info_file& i : x_pack_tex_db->texture)
|
||
texture_max_id = max_def(texture_max_id, (int32_t)i.id);
|
||
|
||
for (size_t j = 0; j < sizeof(name) && name[j]; j++) {
|
||
char c = name[j];
|
||
if (c >= 'a' && c <= 'z')
|
||
name[j] -= 0x20;
|
||
}
|
||
|
||
x_pack_obj_db->object_set.push_back({});
|
||
object_set_info_file& obj_set_info = x_pack_obj_db->object_set.back();
|
||
obj_set_info.name.assign(name);
|
||
obj_set_info.id = ++object_set_max_id;
|
||
|
||
for (size_t j = 0; j < sizeof(name); j++) {
|
||
char c = name[j];
|
||
if (c >= 'A' && c <= 'Z')
|
||
name[j] += 0x20;
|
||
}
|
||
|
||
obj_set_info.object_file_name.assign(name);
|
||
obj_set_info.object_file_name.append("_obj.bin");
|
||
obj_set_info.texture_file_name.assign(name);
|
||
obj_set_info.texture_file_name.append("_tex.bin");
|
||
obj_set_info.archive_file_name.assign(name);
|
||
obj_set_info.archive_file_name.append(".farc");
|
||
|
||
farc f;
|
||
{
|
||
char buf[0x100];
|
||
strcpy_s(buf, sizeof(buf), name);
|
||
strcat_s(buf, sizeof(buf), "_obj.bin");
|
||
|
||
prj::shared_ptr<prj::stack_allocator> alloc(new prj::stack_allocator);
|
||
obj_set* set = alloc->allocate<obj_set>();
|
||
set->move_data(info->obj_set, alloc);
|
||
|
||
uint32_t tex_id_num = set->tex_id_num;
|
||
x_pack_tex_db->texture.reserve(tex_id_num);
|
||
for (uint32_t i = 0; i < tex_id_num; i++) {
|
||
uint32_t& id = set->tex_id_data[i];
|
||
const char* tex_name = tex_db->get_texture_name(id);
|
||
if (tex_name) {
|
||
char name_buf[0x200];
|
||
strcpy_s(name_buf, sizeof(name_buf), tex_name);
|
||
replace_names(name_buf);
|
||
|
||
bool found = false;
|
||
uint32_t hash = hash_utf8_murmurhash(name_buf);
|
||
for (texture_info_file& j : x_pack_tex_db->texture)
|
||
if (hash == hash_string_murmurhash(j.name)) {
|
||
id = j.id;
|
||
found = true;
|
||
break;
|
||
}
|
||
|
||
if (!found) {
|
||
uint32_t tex_id = x_pack_tex_db_base->get_texture_id(name_buf);
|
||
if (tex_id != -1) {
|
||
id = tex_id;
|
||
found = true;
|
||
}
|
||
}
|
||
|
||
if (!found) {
|
||
x_pack_tex_db->texture.push_back({});
|
||
texture_info_file& tex_info = x_pack_tex_db->texture.back();
|
||
id = ++texture_max_id;
|
||
tex_info.name.assign(name_buf);
|
||
tex_info.id = id;
|
||
}
|
||
}
|
||
else
|
||
id = -1;
|
||
}
|
||
|
||
uint32_t obj_num = set->obj_num;
|
||
obj_set_info.object.reserve(obj_num);
|
||
for (uint32_t i = 0; i < obj_num; i++) {
|
||
obj* obj = set->obj_data[i];
|
||
|
||
replace_names((char*)obj->name);
|
||
obj->id = i;
|
||
|
||
obj_set_info.object.push_back({});
|
||
obj_set_info.object.back().id = i;
|
||
obj_set_info.object.back().name.assign(obj->name);
|
||
|
||
uint32_t num_material = obj->num_material;
|
||
for (uint32_t j = 0; j < num_material; j++) {
|
||
obj_material& material = obj->material_array[j].material;
|
||
|
||
for (obj_material_texture_data& k : material.texdata) {
|
||
k.texture_index = 0;
|
||
if (k.tex_index == -1)
|
||
continue;
|
||
|
||
const char* tex_name = tex_db->get_texture_name(k.tex_index);
|
||
if (tex_name) {
|
||
char name_buf[0x200];
|
||
strcpy_s(name_buf, sizeof(name_buf), tex_name);
|
||
replace_names(name_buf);
|
||
|
||
k.tex_index = -1;
|
||
for (texture_info_file& i : x_pack_tex_db->texture)
|
||
if (!i.name.compare(name_buf)) {
|
||
k.tex_index = i.id;
|
||
break;
|
||
}
|
||
}
|
||
else
|
||
k.tex_index = -1;
|
||
|
||
}
|
||
|
||
if (*(int32_t*)&material.shader.name[4] == 0xDEADFF) {
|
||
*(int32_t*)&material.shader.name[4] = 0;
|
||
const char* shader_name = shaders_ft.get_name_by_index(material.shader.index);
|
||
strcpy_s(material.shader.name, sizeof(material.shader.name), shader_name);
|
||
}
|
||
}
|
||
}
|
||
|
||
set->modern = false;
|
||
|
||
farc_file* ff_obj = f.add_file(buf);
|
||
set->pack_file(&ff_obj->data, &ff_obj->size);
|
||
ff_obj->compressed = true;
|
||
}
|
||
|
||
{
|
||
char buf[0x100];
|
||
strcpy_s(buf, sizeof(buf), name);
|
||
strcat_s(buf, sizeof(buf), "_tex.bin");
|
||
|
||
uint32_t tex_num = info->tex_num;
|
||
texture** tex_data = info->tex_data;
|
||
|
||
txp_set txp;
|
||
txp.textures.resize(tex_num);
|
||
for (uint32_t j = 0; j < tex_num; j++)
|
||
texture_txp_store(tex_data[j], &txp.textures[j]);
|
||
|
||
farc_file* ff_tex = f.add_file(buf);
|
||
txp.pack_file(&ff_tex->data, &ff_tex->size, false);
|
||
ff_tex->compressed = true;
|
||
}
|
||
|
||
char buf[0x200];
|
||
strcpy_s(buf, sizeof(buf), "patch\\!temp\\objset\\");
|
||
strcat_s(buf, sizeof(buf), name);
|
||
|
||
f.write(buf, FARC_FArC, FARC_NONE, false);
|
||
}
|
||
|
||
inline static int64_t x_pv_game_write_strings_get_string_offset(
|
||
const prj::vector_pair<string_hash, int64_t>& vec, const std::string& str) {
|
||
std::string _str(str);
|
||
replace_names(_str);
|
||
|
||
uint64_t hash_fnv1a64m = hash_string_fnv1a64m(_str);
|
||
uint64_t hash_murmurhash = hash_string_murmurhash(_str);
|
||
for (auto& i : vec)
|
||
if (hash_fnv1a64m == i.first.hash_fnv1a64m && hash_murmurhash == i.first.hash_murmurhash)
|
||
return i.second;
|
||
return 0;
|
||
}
|
||
|
||
inline static bool x_pv_game_write_file_strings_push_back_check(stream& s,
|
||
prj::vector_pair<string_hash, int64_t>& vec, const std::string& str) {
|
||
std::string _str(str);
|
||
replace_names(_str);
|
||
|
||
uint64_t hash_fnv1a64m = hash_string_fnv1a64m(_str);
|
||
uint64_t hash_murmurhash = hash_string_murmurhash(_str);
|
||
for (auto& i : vec)
|
||
if (hash_fnv1a64m == i.first.hash_fnv1a64m && hash_murmurhash == i.first.hash_murmurhash)
|
||
return false;
|
||
|
||
vec.push_back({ _str, s.get_position() });
|
||
s.write_string_null_terminated(_str);
|
||
return true;
|
||
}
|
||
|
||
static void x_pv_game_write_play_param(pvpp* play_param,
|
||
int32_t pv_id, const auth_3d_database* x_pack_auth_3d_db) {
|
||
char path[MAX_PATH];
|
||
sprintf_s(path, sizeof(path), "patch\\!temp\\pv\\pv%03d.pvpp", pv_id == 832 ? 800 : pv_id);
|
||
|
||
size_t chara_count = 0;
|
||
size_t effect_count = play_param->effect.size();
|
||
|
||
for (pvpp_chara& i : play_param->chara)
|
||
if (i.auth_3d.size() || i.glitter.size()
|
||
|| i.chara_effect_init && i.chara_effect.auth_3d.size())
|
||
chara_count++;
|
||
|
||
int64_t chara_offset = 0;
|
||
int64_t effect_offset = 0;
|
||
|
||
file_stream s;
|
||
s.open(path, "wb");
|
||
s.write(0x20);
|
||
|
||
prj::vector_pair<string_hash, int64_t> strings;
|
||
|
||
for (pvpp_chara& i : play_param->chara) {
|
||
strings.reserve(i.auth_3d.size() + i.glitter.size());
|
||
for (string_hash& j : i.auth_3d)
|
||
x_pv_game_write_file_strings_push_back_check(s, strings, j.str);
|
||
|
||
for (pvpp_glitter& j : i.glitter)
|
||
x_pv_game_write_file_strings_push_back_check(s, strings, j.name.str);
|
||
|
||
if (i.chara_effect_init && i.chara_effect.auth_3d.size()) {
|
||
pvpp_chara_effect& chara_effect = i.chara_effect;
|
||
strings.reserve(chara_effect.auth_3d.size() * 2);
|
||
for (pvpp_chara_effect_auth_3d& j : chara_effect.auth_3d) {
|
||
x_pv_game_write_file_strings_push_back_check(s, strings, j.auth_3d.str);
|
||
|
||
if (j.has_object_set)
|
||
x_pv_game_write_file_strings_push_back_check(s, strings, j.object_set.str);
|
||
}
|
||
}
|
||
}
|
||
|
||
for (pvpp_effect& i : play_param->effect) {
|
||
strings.reserve(i.auth_3d.size() + i.glitter.size());
|
||
for (string_hash& j : i.auth_3d)
|
||
x_pv_game_write_file_strings_push_back_check(s, strings, j.str);
|
||
|
||
for (pvpp_glitter& j : i.glitter)
|
||
x_pv_game_write_file_strings_push_back_check(s, strings, j.name.str);
|
||
}
|
||
s.align_write(0x10);
|
||
|
||
if (chara_count) {
|
||
chara_offset = s.get_position();
|
||
s.write(0x20 * chara_count);
|
||
|
||
int64_t* auth_3d_offsets = force_malloc<int64_t>(chara_count);
|
||
int64_t* glitter_offsets = force_malloc<int64_t>(chara_count);
|
||
int64_t* chara_effect_offsets = force_malloc<int64_t>(chara_count);
|
||
|
||
for (pvpp_chara& i : play_param->chara) {
|
||
if (!i.auth_3d.size() && !i.glitter.size() && (!i.chara_effect_init
|
||
|| i.chara_effect_init && !i.chara_effect.auth_3d.size()))
|
||
continue;
|
||
|
||
if (i.auth_3d.size()) {
|
||
*auth_3d_offsets++ = s.get_position();
|
||
for (string_hash& j : i.auth_3d)
|
||
s.write_int64_t(x_pv_game_write_strings_get_string_offset(strings, j.str));
|
||
s.align_write(0x08);
|
||
}
|
||
else
|
||
*auth_3d_offsets++ = 0;
|
||
|
||
if (i.glitter.size()) {
|
||
*glitter_offsets++ = s.get_position();
|
||
for (pvpp_glitter& j : i.glitter) {
|
||
s.write_int64_t(x_pv_game_write_strings_get_string_offset(strings, j.name.str));
|
||
s.write_uint8_t(j.unk2);
|
||
s.align_write(0x08);
|
||
}
|
||
s.align_write(0x08);
|
||
}
|
||
else
|
||
*glitter_offsets++ = 0;
|
||
|
||
if (i.chara_effect_init && i.chara_effect.auth_3d.size()) {
|
||
*chara_effect_offsets = s.get_position();
|
||
s.write(0x10);
|
||
|
||
int64_t auth_3d_offset = s.get_position();
|
||
|
||
pvpp_chara_effect& chara_effect = i.chara_effect;
|
||
for (pvpp_chara_effect_auth_3d& j : chara_effect.auth_3d) {
|
||
s.write_int64_t(x_pv_game_write_strings_get_string_offset(strings, j.auth_3d.str));
|
||
|
||
if (j.has_object_set)
|
||
s.write_int64_t(x_pv_game_write_strings_get_string_offset(strings, j.object_set.str));
|
||
else
|
||
s.write_int64_t(0x00);
|
||
|
||
s.write_uint8_t(j.u00);
|
||
s.align_write(0x08);
|
||
}
|
||
s.align_write(0x08);
|
||
|
||
s.position_push(*chara_effect_offsets++, SEEK_SET);
|
||
s.write_int8_t(chara_effect.base_chara);
|
||
s.write_int8_t(chara_effect.chara_id);
|
||
s.write_int8_t((int8_t)chara_effect.auth_3d.size());
|
||
s.align_write(0x08);
|
||
s.write_int64_t(auth_3d_offset);
|
||
s.position_pop();
|
||
}
|
||
else
|
||
*chara_effect_offsets++ = 0;
|
||
}
|
||
auth_3d_offsets -= chara_count;
|
||
glitter_offsets -= chara_count;
|
||
chara_effect_offsets -= chara_count;
|
||
|
||
s.position_push(chara_offset, SEEK_SET);
|
||
for (pvpp_chara& i : play_param->chara) {
|
||
if (!i.auth_3d.size() && !i.glitter.size() && (!i.chara_effect_init
|
||
|| i.chara_effect_init && !i.chara_effect.auth_3d.size()))
|
||
continue;
|
||
|
||
s.write_int8_t((int8_t)i.auth_3d.size());
|
||
s.write_int8_t((int8_t)i.glitter.size());
|
||
s.align_write(0x08);
|
||
s.write_int64_t(*auth_3d_offsets++);
|
||
s.write_int64_t(*glitter_offsets++);
|
||
s.write_int64_t(*chara_effect_offsets++);
|
||
}
|
||
auth_3d_offsets -= chara_count;
|
||
glitter_offsets -= chara_count;
|
||
chara_effect_offsets -= chara_count;
|
||
s.position_pop();
|
||
|
||
free_def(auth_3d_offsets);
|
||
free_def(glitter_offsets);
|
||
free_def(chara_effect_offsets);
|
||
}
|
||
|
||
if (effect_count) {
|
||
effect_offset = s.get_position();
|
||
s.write(0x20 * effect_count);
|
||
|
||
int64_t* auth_3d_offsets = force_malloc<int64_t>(effect_count);
|
||
int64_t* glitter_offsets = force_malloc<int64_t>(effect_count);
|
||
|
||
for (pvpp_effect& i : play_param->effect) {
|
||
if (i.auth_3d.size()) {
|
||
*auth_3d_offsets++ = s.get_position();
|
||
for (string_hash& j : i.auth_3d)
|
||
s.write_int64_t(x_pv_game_write_strings_get_string_offset(strings, j.str));
|
||
s.align_write(0x08);
|
||
}
|
||
else
|
||
*auth_3d_offsets++ = 0;
|
||
|
||
if (i.glitter.size()) {
|
||
*glitter_offsets++ = s.get_position();
|
||
for (pvpp_glitter& j : i.glitter) {
|
||
s.write_int64_t(x_pv_game_write_strings_get_string_offset(strings, j.name.str));
|
||
s.write_uint8_t(j.unk2 ? 0x01 : 0x00);
|
||
s.align_write(0x08);
|
||
}
|
||
s.align_write(0x08);
|
||
}
|
||
else
|
||
*glitter_offsets++ = 0;
|
||
}
|
||
auth_3d_offsets -= effect_count;
|
||
glitter_offsets -= effect_count;
|
||
|
||
s.position_push(effect_offset, SEEK_SET);
|
||
for (pvpp_effect& i : play_param->effect) {
|
||
s.write_int8_t(i.chara_id);
|
||
s.write_int8_t((int8_t)i.auth_3d.size());
|
||
s.write_int8_t((int8_t)i.glitter.size());
|
||
s.align_write(0x08);
|
||
s.write_int64_t(*auth_3d_offsets++);
|
||
s.write_int64_t(*glitter_offsets++);
|
||
}
|
||
auth_3d_offsets -= effect_count;
|
||
glitter_offsets -= effect_count;
|
||
s.position_pop();
|
||
|
||
free_def(auth_3d_offsets);
|
||
free_def(glitter_offsets);
|
||
}
|
||
s.align_write(0x10);
|
||
|
||
s.position_push(0x00, SEEK_SET);
|
||
s.write_uint32_t(reverse_endianness_uint32_t('pvpp'));
|
||
s.write_int8_t((int8_t)chara_count);
|
||
s.write_int8_t((int8_t)effect_count);
|
||
s.align_write(0x08);
|
||
s.write_int64_t(chara_offset);
|
||
s.write_int64_t(effect_offset);
|
||
s.position_pop();
|
||
s.close();
|
||
}
|
||
|
||
static void x_pv_game_write_stage_resource(pvsr* stage_resource,
|
||
int32_t stage_id, const auth_3d_database* x_pack_auth_3d_db) {
|
||
struct x_pack_pvsr_effect {
|
||
char name[0x40];
|
||
float_t emission;
|
||
};
|
||
|
||
char path[MAX_PATH];
|
||
sprintf_s(path, sizeof(path), "patch\\!temp\\pv_stage_rsrc\\stgpv%03d_param.pvsr",
|
||
800 + (stage_id == 32 ? 00 : stage_id));
|
||
|
||
size_t effect_count = stage_resource->effect.size();
|
||
size_t stage_effect_count = stage_resource->stage_effect.size();
|
||
size_t stage_effect_env_count = stage_resource->stage_effect_env.size();
|
||
|
||
int64_t effect_offset = 0;
|
||
int64_t stage_effect_offset = 0;
|
||
int64_t stage_effect_env_offset = 0;
|
||
int64_t stage_change_effect_offset = 0;
|
||
|
||
file_stream s;
|
||
s.open(path, "wb");
|
||
s.write(0x30);
|
||
|
||
prj::vector_pair<string_hash, int64_t> strings;
|
||
|
||
for (pvsr_effect& i : stage_resource->effect)
|
||
x_pv_game_write_file_strings_push_back_check(s, strings, i.name.str);
|
||
|
||
for (pvsr_stage_effect& i : stage_resource->stage_effect) {
|
||
for (pvsr_auth_3d& j : i.auth_3d)
|
||
x_pv_game_write_file_strings_push_back_check(s, strings, j.name.str);
|
||
|
||
for (pvsr_glitter& j : i.glitter)
|
||
x_pv_game_write_file_strings_push_back_check(s, strings, j.name.str);
|
||
}
|
||
|
||
for (pvsr_stage_effect_env& i : stage_resource->stage_effect_env)
|
||
for (pvsr_auth_2d& j : i.aet_front_low)
|
||
x_pv_game_write_file_strings_push_back_check(s, strings, j.name.str);
|
||
|
||
for (int32_t i = 0; i < PVSR_STAGE_EFFECT_COUNT; i++)
|
||
for (int32_t j = 0; j < PVSR_STAGE_EFFECT_COUNT; j++) {
|
||
pvsr_stage_change_effect& chg_eff = stage_resource->stage_change_effect[i][j];
|
||
|
||
for (pvsr_auth_3d& k : chg_eff.auth_3d)
|
||
x_pv_game_write_file_strings_push_back_check(s, strings, k.name.str);
|
||
|
||
for (pvsr_glitter& k : chg_eff.glitter)
|
||
x_pv_game_write_file_strings_push_back_check(s, strings, k.name.str);
|
||
}
|
||
s.align_write(0x10);
|
||
|
||
if (effect_count) {
|
||
effect_offset = s.get_position();
|
||
|
||
for (pvsr_effect& i : stage_resource->effect) {
|
||
s.write_int64_t(x_pv_game_write_strings_get_string_offset(strings, i.name.str));
|
||
s.write_float_t(i.emission);
|
||
s.align_write(0x08);
|
||
}
|
||
s.align_write(0x08);
|
||
}
|
||
|
||
if (stage_effect_count) {
|
||
stage_effect_offset = s.get_position();
|
||
s.write(0x18 * stage_effect_count);
|
||
|
||
int64_t* auth_3d_offsets = force_malloc<int64_t>(stage_effect_count);
|
||
int64_t* glitter_offsets = force_malloc<int64_t>(stage_effect_count);
|
||
|
||
for (pvsr_stage_effect& i : stage_resource->stage_effect) {
|
||
if (i.auth_3d.size()) {
|
||
*auth_3d_offsets++ = s.get_position();
|
||
for (pvsr_auth_3d& j : i.auth_3d) {
|
||
s.write_int64_t(x_pv_game_write_strings_get_string_offset(strings, j.name.str));
|
||
s.write_uint8_t(j.flags);
|
||
s.align_write(0x08);
|
||
}
|
||
s.align_write(0x08);
|
||
}
|
||
else
|
||
*auth_3d_offsets++ = 0;
|
||
|
||
if (i.glitter.size()) {
|
||
*glitter_offsets++ = s.get_position();
|
||
for (pvsr_glitter& j : i.glitter) {
|
||
s.write_int64_t(x_pv_game_write_strings_get_string_offset(strings, j.name.str));
|
||
s.write_int8_t(j.fade_time);
|
||
s.write_uint8_t(j.flags);
|
||
s.align_write(0x08);
|
||
}
|
||
s.align_write(0x08);
|
||
}
|
||
else
|
||
*glitter_offsets++ = 0;
|
||
}
|
||
auth_3d_offsets -= stage_effect_count;
|
||
glitter_offsets -= stage_effect_count;
|
||
|
||
s.position_push(stage_effect_offset, SEEK_SET);
|
||
for (pvsr_stage_effect& i : stage_resource->stage_effect) {
|
||
s.write_int8_t((int8_t)i.auth_3d.size());
|
||
s.write_int8_t((int8_t)i.glitter.size());
|
||
s.align_write(0x08);
|
||
s.write_int64_t(*auth_3d_offsets++);
|
||
s.write_int64_t(*glitter_offsets++);
|
||
}
|
||
auth_3d_offsets -= stage_effect_count;
|
||
glitter_offsets -= stage_effect_count;
|
||
s.position_pop();
|
||
|
||
free_def(auth_3d_offsets);
|
||
free_def(glitter_offsets);
|
||
}
|
||
|
||
if (stage_effect_env_count) {
|
||
stage_effect_env_offset = s.get_position();
|
||
s.write(0x10 * stage_effect_env_count);
|
||
|
||
int64_t* aet_offsets = force_malloc<int64_t>(stage_effect_env_count);
|
||
|
||
for (pvsr_stage_effect_env& i : stage_resource->stage_effect_env) {
|
||
if (i.aet_front_low.size()) {
|
||
*aet_offsets++ = s.get_position();
|
||
for (pvsr_auth_2d& j : i.aet_front_low)
|
||
s.write_int64_t(x_pv_game_write_strings_get_string_offset(strings, j.name.str));
|
||
s.align_write(0x08);
|
||
}
|
||
else
|
||
*aet_offsets++ = 0;
|
||
}
|
||
aet_offsets -= stage_effect_env_count;
|
||
|
||
s.position_push(stage_effect_env_offset, SEEK_SET);
|
||
for (pvsr_stage_effect_env& i : stage_resource->stage_effect_env) {
|
||
s.write_int8_t((int8_t)i.aet_front_low.size());
|
||
s.align_write(0x08);
|
||
s.write_int64_t(*aet_offsets++);
|
||
}
|
||
aet_offsets -= stage_effect_env_count;
|
||
s.position_pop();
|
||
|
||
free_def(aet_offsets);
|
||
}
|
||
|
||
{
|
||
stage_change_effect_offset = s.get_position();
|
||
s.write(0x18 * PVSR_STAGE_EFFECT_COUNT * PVSR_STAGE_EFFECT_COUNT);
|
||
|
||
int64_t* auth_3d_offsets = force_malloc<int64_t>(PVSR_STAGE_EFFECT_COUNT * PVSR_STAGE_EFFECT_COUNT);
|
||
int64_t* glitter_offsets = force_malloc<int64_t>(PVSR_STAGE_EFFECT_COUNT * PVSR_STAGE_EFFECT_COUNT);
|
||
|
||
for (int32_t i = 0; i < PVSR_STAGE_EFFECT_COUNT; i++)
|
||
for (int32_t j = 0; j < PVSR_STAGE_EFFECT_COUNT; j++) {
|
||
pvsr_stage_change_effect& chg_eff = stage_resource->stage_change_effect[i][j];
|
||
|
||
if (chg_eff.auth_3d.size()) {
|
||
*auth_3d_offsets++ = s.get_position();
|
||
for (pvsr_auth_3d& k : chg_eff.auth_3d) {
|
||
s.write_int64_t(x_pv_game_write_strings_get_string_offset(strings, k.name.str));
|
||
s.write_uint8_t(k.flags);
|
||
s.align_write(0x08);
|
||
}
|
||
s.align_write(0x08);
|
||
}
|
||
else
|
||
*auth_3d_offsets++ = 0;
|
||
|
||
if (chg_eff.glitter.size()) {
|
||
*glitter_offsets++ = s.get_position();
|
||
for (pvsr_glitter& k : chg_eff.glitter) {
|
||
s.write_int64_t(x_pv_game_write_strings_get_string_offset(strings, k.name.str));
|
||
s.write_int8_t(k.fade_time);
|
||
s.write_uint8_t(k.flags);
|
||
s.align_write(0x08);
|
||
}
|
||
s.align_write(0x08);
|
||
}
|
||
else
|
||
*glitter_offsets++ = 0;
|
||
}
|
||
auth_3d_offsets -= PVSR_STAGE_EFFECT_COUNT * PVSR_STAGE_EFFECT_COUNT;
|
||
glitter_offsets -= PVSR_STAGE_EFFECT_COUNT * PVSR_STAGE_EFFECT_COUNT;
|
||
|
||
s.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++) {
|
||
pvsr_stage_change_effect& chg_eff = stage_resource->stage_change_effect[i][j];
|
||
|
||
s.write_uint8_t(chg_eff.enable ? 0x01 : 0x00);
|
||
s.write_int8_t(chg_eff.bar_count);
|
||
s.write_int8_t((int8_t)chg_eff.auth_3d.size());
|
||
s.write_int8_t((int8_t)chg_eff.glitter.size());
|
||
s.align_write(0x08);
|
||
s.write_int64_t(*auth_3d_offsets++);
|
||
s.write_int64_t(*glitter_offsets++);
|
||
}
|
||
auth_3d_offsets -= PVSR_STAGE_EFFECT_COUNT * PVSR_STAGE_EFFECT_COUNT;
|
||
glitter_offsets -= PVSR_STAGE_EFFECT_COUNT * PVSR_STAGE_EFFECT_COUNT;
|
||
s.position_pop();
|
||
|
||
free_def(auth_3d_offsets);
|
||
free_def(glitter_offsets);
|
||
}
|
||
s.align_write(0x10);
|
||
|
||
s.position_push(0x00, SEEK_SET);
|
||
s.write_uint32_t(reverse_endianness_uint32_t('pvsr'));
|
||
s.write_int8_t((int8_t)effect_count);
|
||
s.write_int8_t((int8_t)stage_effect_count);
|
||
s.write_int8_t((int8_t)stage_effect_env_count);
|
||
s.align_write(0x08);
|
||
s.write_int64_t(effect_offset);
|
||
s.write_int64_t(stage_effect_offset);
|
||
s.write_int64_t(stage_effect_env_offset);
|
||
s.write_int64_t(stage_change_effect_offset);
|
||
s.position_pop();
|
||
s.close();
|
||
}
|
||
|
||
static void x_pv_game_write_spr(uint32_t spr_set_id,
|
||
const sprite_database* spr_db, sprite_database_file* x_pack_spr_db) {
|
||
const spr_db_spr_set* spr_set_db = spr_db->get_spr_set_by_id(spr_set_id);
|
||
|
||
::spr_set* spr_set = sprite_manager_get_set(spr_set_id, spr_db);
|
||
|
||
prj::shared_ptr<prj::stack_allocator> alloc(new prj::stack_allocator);
|
||
::spr_set* set = alloc->allocate<::spr_set>();
|
||
set->move_data(spr_set, alloc);
|
||
|
||
uint32_t id = -1;
|
||
for (spr_db_spr_set_file& i : x_pack_spr_db->sprite_set) {
|
||
if ((int32_t)id < (int32_t)i.id)
|
||
id = i.id;
|
||
}
|
||
id++;
|
||
|
||
uint32_t index = x_pack_spr_db->sprite_set.back().index + 1;
|
||
|
||
x_pack_spr_db->sprite_set.push_back({});
|
||
spr_db_spr_set_file& spr_db_spr_set = x_pack_spr_db->sprite_set.back();
|
||
|
||
spr_db_spr_set.id = id;
|
||
spr_db_spr_set.name.assign(spr_set_db->name);
|
||
spr_db_spr_set.file_name.assign(spr_set_db->file_name);
|
||
spr_db_spr_set.index = index;
|
||
|
||
replace_stgpv_pv(spr_db_spr_set.name);
|
||
replace_stgpv_pv(spr_db_spr_set.file_name);
|
||
|
||
size_t pos = spr_db_spr_set.file_name.rfind(".spr");
|
||
if (pos != -1)
|
||
spr_db_spr_set.file_name.replace(pos, 4, ".bin");
|
||
|
||
spr_db_spr_set.sprite.reserve((size_t)set->num_of_sprite + set->num_of_texture);
|
||
|
||
uint32_t num_of_sprite = set->num_of_sprite;
|
||
for (uint32_t i = 0; i < num_of_sprite; i++) {
|
||
const spr_db_spr* spr = spr_db->get_spr_by_set_id_index(spr_set_id, i);
|
||
|
||
spr_db_spr_set.sprite.push_back({});
|
||
spr_db_spr_file& spr_file = spr_db_spr_set.sprite.back();
|
||
spr_file.name.assign(spr->name);
|
||
replace_stgpv_pv(spr_file.name);
|
||
spr_file.id = hash_string_murmurhash(spr_file.name);
|
||
spr_file.index = i;
|
||
spr_file.texture = false;
|
||
}
|
||
|
||
uint32_t num_of_texture = set->num_of_texture;
|
||
for (uint32_t i = 0; i < num_of_texture; i++) {
|
||
const spr_db_spr* spr = spr_db->get_tex_by_set_id_index(spr_set_id, i);
|
||
|
||
spr_db_spr_set.sprite.push_back({});
|
||
spr_db_spr_file& spr_file = spr_db_spr_set.sprite.back();
|
||
spr_file.name.assign(spr->name);
|
||
replace_stgpv_pv(spr_file.name);
|
||
spr_file.id = hash_string_murmurhash(spr_file.name);
|
||
spr_file.index = i;
|
||
spr_file.texture = true;
|
||
}
|
||
|
||
set->modern = false;
|
||
set->big_endian = false;
|
||
set->is_x = false;
|
||
|
||
farc f;
|
||
|
||
farc_file* ff_bin = f.add_file(spr_db_spr_set.file_name.c_str());
|
||
set->pack_file(&ff_bin->data, &ff_bin->size);
|
||
ff_bin->compressed = true;
|
||
|
||
char buf[0x200];
|
||
strcpy_s(buf, sizeof(buf), "patch\\!temp\\2d\\");
|
||
strncat_s(buf, sizeof(buf), spr_db_spr_set.file_name.c_str(), pos);
|
||
|
||
f.write(buf, FARC_FArC, FARC_NONE, false);
|
||
|
||
if (set->txp) {
|
||
delete set->txp;
|
||
set->txp = 0;
|
||
}
|
||
}
|
||
#endif
|
||
|
||
static void print_dsc_command(dsc& dsc, dsc_data* dsc_data_ptr, int64_t time) {
|
||
print_dsc_command(dsc, dsc_data_ptr, &time);
|
||
}
|
||
|
||
static void print_dsc_command(dsc& dsc, dsc_data* dsc_data_ptr, int64_t* time) {
|
||
if (dsc_data_ptr->func < 0 || dsc_data_ptr->func >= DSC_X_MAX) {
|
||
dw_console_printf(DW_CONSOLE_PV_SCRIPT, "UNKNOWN command(%d)\n", dsc_data_ptr->func);
|
||
return;
|
||
}
|
||
|
||
if (dsc_data_ptr->func == DSC_X_TIME) {
|
||
if (time)
|
||
return;
|
||
}
|
||
else {
|
||
if (time)
|
||
#pragma warning(suppress: 26451)
|
||
dw_console_printf(DW_CONSOLE_PV_SCRIPT, "%.3f:", (float_t)*time * 0.00001f);
|
||
}
|
||
|
||
dsc_get_func_length get_func_length = dsc.get_dsc_get_func_length();
|
||
|
||
dw_console_printf(DW_CONSOLE_PV_SCRIPT, "%s(", dsc_data_ptr->name);
|
||
|
||
int32_t* data = dsc.get_func_data(dsc_data_ptr);
|
||
|
||
int32_t length = get_func_length(dsc_data_ptr->func);
|
||
for (int32_t i = 0; i < length; i++)
|
||
if (i)
|
||
dw_console_printf(DW_CONSOLE_PV_SCRIPT, ", %d", ((int32_t*)data)[i]);
|
||
else
|
||
dw_console_printf(DW_CONSOLE_PV_SCRIPT, "%d", ((int32_t*)data)[i]);
|
||
|
||
dw_console_printf(DW_CONSOLE_PV_SCRIPT, ")\n");
|
||
}
|
||
|
||
#if BAKE_FAST
|
||
static void replace_pv832(char* str) {
|
||
char* pv;
|
||
pv = str;
|
||
while (true) {
|
||
pv = strstr(pv, "PV832");
|
||
if (!pv)
|
||
break;
|
||
|
||
memcpy(pv + 2, "800", 3);
|
||
pv += 5;
|
||
}
|
||
|
||
pv = str;
|
||
while (true) {
|
||
pv = strstr(pv, "pv832");
|
||
if (!pv)
|
||
break;
|
||
|
||
memcpy(pv + 2, "800", 3);
|
||
pv += 5;
|
||
}
|
||
}
|
||
|
||
inline static void replace_pv832(std::string& str) {
|
||
replace_pv832((char*)str.data());
|
||
}
|
||
#endif
|
||
|
||
#if BAKE_X_PACK
|
||
static bool get_replace_auth_name(char* name, size_t name_size, auth_3d* auth) {
|
||
if (!name)
|
||
return false;
|
||
|
||
strcpy_s(name, name_size, auth->file_name.c_str());
|
||
|
||
const char* a3da_ext = ".a3da";
|
||
|
||
char* ext = 0;
|
||
char* temp = name;
|
||
while (temp = strstr(temp, a3da_ext))
|
||
ext = temp++;
|
||
|
||
if (ext)
|
||
*ext = 0;
|
||
|
||
replace_names(name);
|
||
|
||
return !strstr(name, "EFFCHRPV826");
|
||
}
|
||
|
||
static void replace_names(char* str) {
|
||
char* stgpv;
|
||
stgpv = str;
|
||
while (true) {
|
||
stgpv = strstr(stgpv, "STGPV0");
|
||
if (!stgpv)
|
||
break;
|
||
|
||
stgpv[5] = '8';
|
||
stgpv += 6;
|
||
}
|
||
|
||
stgpv = str;
|
||
while (true) {
|
||
stgpv = strstr(stgpv, "stgpv0");
|
||
if (!stgpv)
|
||
break;
|
||
|
||
stgpv[5] = '8';
|
||
stgpv += 6;
|
||
}
|
||
|
||
replace_pv832(str);
|
||
}
|
||
|
||
inline static void replace_names(std::string& str) {
|
||
replace_names((char*)str.data());
|
||
}
|
||
|
||
static size_t replace_stgpv_pv(char* str) {
|
||
replace_names(str);
|
||
|
||
size_t len = utf8_length(str);
|
||
|
||
char* stgpv;
|
||
stgpv = str;
|
||
while (true) {
|
||
stgpv = strstr(stgpv, "STGPV");
|
||
if (!stgpv)
|
||
break;
|
||
|
||
memmove(stgpv, stgpv + 3, len - (stgpv + 3 - str));
|
||
len -= 3;
|
||
str[len] = 0;
|
||
}
|
||
|
||
stgpv = str;
|
||
while (true) {
|
||
stgpv = strstr(stgpv, "stgpv");
|
||
if (!stgpv)
|
||
break;
|
||
|
||
memmove(stgpv, stgpv + 3, len - (stgpv + 3 - str));
|
||
len -= 3;
|
||
str[len] = 0;
|
||
}
|
||
return len;
|
||
}
|
||
|
||
static void replace_stgpv_pv(std::string& str) {
|
||
str.resize(replace_stgpv_pv((char*)str.data()));
|
||
}
|
||
|
||
static object_info replace_object_info(object_info info,
|
||
const object_database* src_obj_db, const object_database* dst_obj_db) {
|
||
const char* _name = src_obj_db->get_object_name(info);
|
||
if (!_name)
|
||
return object_info();
|
||
|
||
std::string name(_name);
|
||
replace_names(name);
|
||
return dst_obj_db->get_object_info(name.c_str());
|
||
}
|
||
|
||
static uint32_t replace_texture_id(uint32_t id,
|
||
const texture_database* src_tex_db, const texture_database* dst_tex_db) {
|
||
const char* _name = src_tex_db->get_texture_name(id);
|
||
if (!_name)
|
||
return -1;
|
||
|
||
std::string name(_name);
|
||
replace_names(name);
|
||
return dst_tex_db->get_texture_id(name.c_str());
|
||
}
|
||
#endif
|
||
#endif
|