From ce420e52acbaaffcca7ccc454a333b9f712bd463 Mon Sep 17 00:00:00 2001 From: korenkonder Date: Sat, 3 Jun 2023 02:43:41 +0300 Subject: [PATCH] [WiP] Weird story still continues. Part 6. Test PV --- src/CRE/Glitter/glitter.hpp | 5 +- src/CRE/auth_2d.cpp | 48 +- src/CRE/auth_2d.hpp | 23 +- src/CRE/auth_3d.cpp | 20 +- src/CRE/auth_3d.hpp | 2 +- src/CRE/camera.cpp | 140 +- src/CRE/camera.hpp | 23 + src/CRE/customize_item_table.cpp | 237 + src/CRE/customize_item_table.hpp | 31 + src/CRE/draw_object.cpp | 2 +- src/CRE/hand_item.cpp | 19 +- src/CRE/hand_item.hpp | 5 +- src/CRE/item_table.cpp | 19 +- src/CRE/module_table.cpp | 226 + src/CRE/module_table.hpp | 29 + src/CRE/ogg_vorbis.cpp | 4 +- src/CRE/post_process.cpp | 111 + src/CRE/post_process.hpp | 47 +- src/CRE/pv_db.cpp | 366 +- src/CRE/pv_db.hpp | 33 +- src/CRE/pv_expression.cpp | 34 +- src/CRE/pv_expression.hpp | 6 +- src/CRE/pv_param.cpp | 647 ++- src/CRE/pv_param.hpp | 180 +- src/CRE/render_context.cpp | 4 +- src/CRE/render_context.hpp | 2 +- src/CRE/rob/ex_block.cpp | 24 +- src/CRE/rob/rob.cpp | 372 +- src/CRE/rob/rob.hpp | 74 +- src/CRE/sound.cpp | 6 +- src/CRE/sound.hpp | 6 +- src/CRE/stage.cpp | 187 +- src/CRE/stage.hpp | 26 +- src/CRE/stage_modern.cpp | 172 +- src/CRE/stage_modern.hpp | 23 +- src/CRE/task_effect.cpp | 30 +- src/KKdLib/database/aet.cpp | 4 + src/KKdLib/database/aet.hpp | 1 + src/KKdLib/database/auth_3d.cpp | 15 +- src/KKdLib/divafile.cpp | 2 - src/KKdLib/dsc.cpp | 314 +- src/KKdLib/dsc.hpp | 28 +- src/KKdLib/io/json.cpp | 125 +- src/KKdLib/io/stream.cpp | 2 +- src/KKdLib/mat.hpp | 1 + src/KKdLib/prj/algorithm.hpp | 10 + src/KKdLib/prj/time.cpp | 39 + src/KKdLib/prj/time.hpp | 27 + src/KKdLib/pv_exp.cpp | 4 +- src/ReDIVA/classes/glitter_editor.cpp | 11 +- src/ReDIVA/data_edit.cpp | 4 +- src/ReDIVA/data_initialize.cpp | 20 +- src/ReDIVA/data_test/auth_2d_test.cpp | 2 +- src/ReDIVA/data_test/glitter_test.cpp | 3 +- src/ReDIVA/game_state.cpp | 2 +- src/ReDIVA/pv_game.cpp | 1664 ------- src/ReDIVA/pv_game.hpp | 918 ---- src/ReDIVA/pv_game/game_2d.cpp | 522 ++ src/ReDIVA/pv_game/game_2d.hpp | 69 + src/ReDIVA/pv_game/player_data.cpp | 320 ++ src/ReDIVA/pv_game/player_data.hpp | 302 ++ src/ReDIVA/pv_game/pv_game.cpp | 5818 ++++++++++++++++++++++ src/ReDIVA/pv_game/pv_game.hpp | 815 +++ src/ReDIVA/pv_game/pv_game_camera.cpp | 297 ++ src/ReDIVA/pv_game/pv_game_camera.hpp | 24 + src/ReDIVA/pv_game/pv_game_music.cpp | 462 ++ src/ReDIVA/pv_game/pv_game_music.hpp | 125 + src/ReDIVA/pv_game/pv_game_play_data.cpp | 2217 +++++++++ src/ReDIVA/pv_game/pv_game_play_data.hpp | 323 ++ src/ReDIVA/pv_game/pv_game_pv_data.cpp | 2595 ++++++++++ src/ReDIVA/pv_game/pv_game_pv_data.hpp | 349 ++ src/ReDIVA/pv_game/target_pos.cpp | 22 + src/ReDIVA/pv_game/target_pos.hpp | 14 + src/ReDIVA/render.cpp | 10 +- src/ReDIVA/system_startup.cpp | 39 +- src/ReDIVA/x_pv_game.cpp | 247 +- src/ReDIVA/x_pv_game.hpp | 2 +- 77 files changed, 17145 insertions(+), 3806 deletions(-) create mode 100644 src/CRE/customize_item_table.cpp create mode 100644 src/CRE/customize_item_table.hpp create mode 100644 src/CRE/module_table.cpp create mode 100644 src/CRE/module_table.hpp create mode 100644 src/KKdLib/prj/time.cpp create mode 100644 src/KKdLib/prj/time.hpp delete mode 100644 src/ReDIVA/pv_game.cpp delete mode 100644 src/ReDIVA/pv_game.hpp create mode 100644 src/ReDIVA/pv_game/game_2d.cpp create mode 100644 src/ReDIVA/pv_game/game_2d.hpp create mode 100644 src/ReDIVA/pv_game/player_data.cpp create mode 100644 src/ReDIVA/pv_game/player_data.hpp create mode 100644 src/ReDIVA/pv_game/pv_game.cpp create mode 100644 src/ReDIVA/pv_game/pv_game.hpp create mode 100644 src/ReDIVA/pv_game/pv_game_camera.cpp create mode 100644 src/ReDIVA/pv_game/pv_game_camera.hpp create mode 100644 src/ReDIVA/pv_game/pv_game_music.cpp create mode 100644 src/ReDIVA/pv_game/pv_game_music.hpp create mode 100644 src/ReDIVA/pv_game/pv_game_play_data.cpp create mode 100644 src/ReDIVA/pv_game/pv_game_play_data.hpp create mode 100644 src/ReDIVA/pv_game/pv_game_pv_data.cpp create mode 100644 src/ReDIVA/pv_game/pv_game_pv_data.hpp create mode 100644 src/ReDIVA/pv_game/target_pos.cpp create mode 100644 src/ReDIVA/pv_game/target_pos.hpp diff --git a/src/CRE/Glitter/glitter.hpp b/src/CRE/Glitter/glitter.hpp index 4d63e268..bfb0cccb 100644 --- a/src/CRE/Glitter/glitter.hpp +++ b/src/CRE/Glitter/glitter.hpp @@ -1144,7 +1144,8 @@ namespace Glitter { FileReader(GLT, const wchar_t* path, const wchar_t* file, float_t emission); virtual ~FileReader(); - bool LoadFarc(void* data, const char* path, const char* file, uint64_t hash, object_database* obj_db); + bool LoadFarc(void* data, const char* path, const char* file, + uint64_t hash, object_database* obj_db = 0); void ParseAnimation(f2_struct* st, Animation* anim); void ParseCurve(f2_struct* st, Animation* anim); bool ParseDivaEffect(GPM, f2_struct* st, object_database* obj_db); @@ -1620,7 +1621,7 @@ namespace Glitter { SceneCounter GetSceneCounter(uint8_t index = 0); SceneCounter Load(uint64_t effect_group_hash, uint64_t effect_hash, bool use_existing); uint64_t LoadFile(GLT, void* data, const char* file, const char* path, - float_t emission, bool init_scene, object_database* obj_db); + float_t emission, bool init_scene, object_database* obj_db = 0); SceneCounter LoadScene(uint64_t effect_group_hash, uint64_t effect_hash, bool appear_now = true); SceneCounter LoadSceneEffect(uint64_t hash, bool appear_now = true, uint8_t load_flags = 0); SceneCounter LoadSceneEffect(uint64_t hash, const char* name, diff --git a/src/CRE/auth_2d.cpp b/src/CRE/auth_2d.cpp index bdb435d2..85dfdf9a 100644 --- a/src/CRE/auth_2d.cpp +++ b/src/CRE/auth_2d.cpp @@ -77,7 +77,7 @@ public: virtual bool GetPlay(); virtual bool GetVisible(); virtual float_t GetFrame(); - virtual bool GetDisp(); + virtual bool GetEnd(); virtual void CtrlComp(const aet_comp* comp, float_t frame); virtual void DispComp(const mat4& mat, const aet_comp* comp, float_t frame, float_t opacity, const sprite_database* spr_db); @@ -167,7 +167,7 @@ public: void FreeAetObject(std::map::iterator it); void FreeAetSetObjects(uint32_t set_index); AetObj* GetObj(uint32_t id); - bool GetObjDisp(uint32_t id); + bool GetObjEnd(uint32_t id); float_t GetObjFrame(uint32_t id); bool GetObjVisible(uint32_t id); AetSet* GetSet(uint32_t index); @@ -264,7 +264,7 @@ void AetComp::put_number_sprite(int32_t value, int32_t max_digits, spr::SPR_ATTR_CTR_CC, prio, pos, layout, spr_db); } } - + aet_layout_data::aet_layout_data() : width(), height() { mat = mat4_identity; @@ -338,8 +338,8 @@ void aet_manager_free_aet_set_objects(uint32_t set_id, const aet_database* aet_d aet_manager->FreeAetSetObjects(aet_db->get_aet_set_by_id(set_id)->index); } -bool aet_manager_get_obj_disp(uint32_t id) { - return aet_manager->GetObjDisp(id); +bool aet_manager_get_obj_end(uint32_t id) { + return aet_manager->GetObjEnd(id); } float_t aet_manager_get_obj_frame(uint32_t id) { @@ -396,15 +396,14 @@ bool aet_manager_get_set_ready(uint32_t set_id, const aet_database* aet_db) { return aet_manager->GetSetReady(aet_db->get_aet_set_by_id(set_id)->index); }; -void aet_manager_init_aet_layout(AetComp* comp, - AetArgs args, const aet_database* aet_db) { +void aet_manager_init_aet_layout(AetComp* comp, AetArgs args, const aet_database* aet_db) { args.id.info = aet_db->get_aet_by_id(args.id.id)->info; aet_manager->InitAetLayout(comp, args); } -void aet_manager_init_aet_layout(AetComp* comp, - uint32_t aet_id, const char* layer_name, AetFlags flags, resolution_mode mode, - const char* start_marker, float_t start_time, const aet_database* aet_db) { +void aet_manager_init_aet_layout(AetComp* comp, uint32_t aet_id, const char* layer_name, + AetFlags flags, resolution_mode mode, const char* start_marker, float_t start_time, + const aet_database* aet_db, const sprite_database* spr_db) { AetArgs args; args.id.info = aet_db->get_aet_by_id(aet_id)->info; args.layer_name = layer_name; @@ -412,6 +411,7 @@ void aet_manager_init_aet_layout(AetComp* comp, args.mode = mode; args.start_marker = start_marker; args.start_time = start_time; + args.spr_db = spr_db; aet_manager->InitAetLayout(comp, args); } @@ -420,8 +420,9 @@ uint32_t aet_manager_init_aet_object(AetArgs args, const aet_database* aet_db) { return aet_manager->InitAetObject(args); } -uint32_t aet_manager_init_aet_object(uint32_t id, const char* layer_name, spr::SprPrio prio, - AetFlags flags, const char* start_marker, const char* end_marker, const aet_database* aet_db) { +uint32_t aet_manager_init_aet_object(uint32_t id, const char* layer_name, + spr::SprPrio prio, AetFlags flags, const char* start_marker, const char* end_marker, + const aet_database* aet_db, const sprite_database* spr_db) { AetArgs args; args.id.info = aet_db->get_aet_by_id(id)->info; args.layer_name = layer_name; @@ -429,13 +430,14 @@ uint32_t aet_manager_init_aet_object(uint32_t id, const char* layer_name, spr::S args.flags = flags; args.start_marker = start_marker; args.end_marker = end_marker; + args.spr_db = spr_db; return aet_manager->InitAetObject(args); } -uint32_t aet_manager_init_aet_object(uint32_t aet_id, spr::SprPrio prio, - AetFlags flags, const char* layer_name, const vec2* pos, int32_t index, - const char* start_marker, const char* end_marker, float_t start_time, float_t end_time, - const vec2* scale, FrameRateControl* frame_rate_control, const aet_database* aet_db) { +uint32_t aet_manager_init_aet_object(uint32_t aet_id, spr::SprPrio prio, AetFlags flags, + const char* layer_name, const vec2* pos, int32_t index, const char* start_marker, const char* end_marker, + float_t start_time, float_t end_time, const vec2* scale, FrameRateControl* frame_rate_control, + const aet_database* aet_db, const sprite_database* spr_db) { AetArgs args; args.id.id = aet_id; args.prio = prio; @@ -465,6 +467,8 @@ uint32_t aet_manager_init_aet_object(uint32_t aet_id, spr::SprPrio prio, if (frame_rate_control) args.frame_rate_control = frame_rate_control; + + args.spr_db = spr_db; return aet_manager_init_aet_object(args, aet_db); } @@ -736,7 +740,7 @@ bool AetObj::StepFrame() { frame = start_time; else if (flags & AET_PLAY_ONCE) { frame = end_time; - enum_or(flags, AET_DISP); + enum_or(flags, AET_END); } else return true; @@ -749,7 +753,7 @@ bool AetObj::StepFrame() { frame = end_time; else if (flags & AET_PLAY_ONCE) { frame = start_time; - enum_or(flags, AET_DISP); + enum_or(flags, AET_END); } else return true; @@ -836,8 +840,8 @@ float_t AetObj::GetFrame() { return frame; } -bool AetObj::GetDisp() { - return !!(flags & AET_DISP); +bool AetObj::GetEnd() { + return !!(flags & AET_END); } void AetObj::CtrlComp(const aet_comp* comp, float_t frame) { @@ -1602,11 +1606,11 @@ AetObj* AetMgr::GetObj(uint32_t id) { return 0; } -bool AetMgr::GetObjDisp(uint32_t id) { +bool AetMgr::GetObjEnd(uint32_t id) { if (app::TaskWork::CheckTaskReady(this)) { AetObj* obj = AetMgr::GetObj(id); if (obj) - return obj->GetDisp(); + return obj->GetEnd(); } return true; } diff --git a/src/CRE/auth_2d.hpp b/src/CRE/auth_2d.hpp index 4f4f780a..3e1e2ab7 100644 --- a/src/CRE/auth_2d.hpp +++ b/src/CRE/auth_2d.hpp @@ -12,7 +12,7 @@ #include "sprite.hpp" enum AetFlags { - AET_DISP = 0x000001, + AET_END = 0x000001, AET_REVERSE = 0x000002, AET_PAUSE = 0x000004, AET_HIDDEN = 0x000008, @@ -109,7 +109,7 @@ extern bool aet_manager_del_task(); extern void aet_manager_free_aet_object(uint32_t id); extern void aet_manager_free_aet_object_reset(uint32_t* id); extern void aet_manager_free_aet_set_objects(uint32_t set_id, const aet_database* aet_db); -extern bool aet_manager_get_obj_disp(uint32_t id); +extern bool aet_manager_get_obj_end(uint32_t id); extern float_t aet_manager_get_obj_frame(uint32_t id); extern bool aet_manager_get_obj_visible(uint32_t id); extern void aet_manager_get_scene_comp_layer_names(std::vector& vec, @@ -129,16 +129,17 @@ extern uint32_t aet_manager_get_scenes_count(uint32_t set_id, const aet_database extern bool aet_manager_get_set_ready(uint32_t set_id, const aet_database* aet_db); extern void aet_manager_init_aet_layout(AetComp* composition, AetArgs args, const aet_database* aet_db); -extern void aet_manager_init_aet_layout(AetComp* composition, - uint32_t aet_id, const char* layer_name, AetFlags flags, resolution_mode mode, - const char* start_marker, float_t start_time, const aet_database* aet_db); +extern void aet_manager_init_aet_layout(AetComp* composition, uint32_t aet_id, const char* layer_name, + AetFlags flags, resolution_mode mode, const char* start_marker, float_t start_time, + const aet_database* aet_db, const sprite_database* spr_db); extern uint32_t aet_manager_init_aet_object(AetArgs args, const aet_database* aet_db); -extern uint32_t aet_manager_init_aet_object(uint32_t id, const char* layer_name, spr::SprPrio prio, - AetFlags flags, const char* start_marker, const char* end_marker, const aet_database* aet_db); -extern uint32_t aet_manager_init_aet_object(uint32_t aet_id, spr::SprPrio prio, - AetFlags flags, const char* layer_name, const vec2* pos, int32_t index, - const char* start_marker, const char* end_marker, float_t start_time, float_t end_time, - const vec2* scale, FrameRateControl* frame_rate_control, const aet_database* aet_db); +extern uint32_t aet_manager_init_aet_object(uint32_t id, const char* layer_name, + spr::SprPrio prio, AetFlags flags, const char* start_marker, const char* end_marker, + const aet_database* aet_db, const sprite_database* spr_db); +extern uint32_t aet_manager_init_aet_object(uint32_t aet_id, spr::SprPrio prio, AetFlags flags, + const char* layer_name, const vec2* pos, int32_t index, const char* start_marker, const char* end_marker, + float_t start_time, float_t end_time, const vec2* scale, FrameRateControl* frame_rate_control, + const aet_database* aet_db, const sprite_database* spr_db); extern bool aet_manager_load_file(uint32_t set_id, const aet_database* aet_db); extern bool aet_manager_load_file_modern(uint32_t set_hash, aet_database* aet_db); extern void aet_manager_read_file(uint32_t set_id, diff --git a/src/CRE/auth_3d.cpp b/src/CRE/auth_3d.cpp index f23c1cf9..eb69819e 100644 --- a/src/CRE/auth_3d.cpp +++ b/src/CRE/auth_3d.cpp @@ -2390,6 +2390,16 @@ void auth_3d_id::read_file_modern() { } } +void auth_3d_id::set_alpha_obj_flags(float_t alpha, mdl::ObjFlags obj_flags) { + if (id >= 0 && ((id & 0x7FFF) < AUTH_3D_DATA_COUNT)) { + auth_3d* auth = &auth_3d_data->data[id & 0x7FFF]; + if (auth->id == id) { + auth->alpha = alpha; + auth->obj_flags = obj_flags; + } + } +} + void auth_3d_id::set_camera_root_update(bool value) { if (id >= 0 && ((id & 0x7FFF) < AUTH_3D_DATA_COUNT)) { auth_3d* auth = &auth_3d_data->data[id & 0x7FFF]; @@ -2414,16 +2424,6 @@ void auth_3d_id::set_chara_item(bool value) { } } -void auth_3d_id::set_obj_flags_alpha(mdl::ObjFlags obj_flags, float_t alpha) { - if (id >= 0 && ((id & 0x7FFF) < AUTH_3D_DATA_COUNT)) { - auth_3d* auth = &auth_3d_data->data[id & 0x7FFF]; - if (auth->id == id) { - auth->obj_flags = obj_flags; - auth->alpha = alpha; - } - } -} - void auth_3d_id::set_enable(bool value) { if (id >= 0 && ((id & 0x7FFF) < AUTH_3D_DATA_COUNT)) { auth_3d* auth = &auth_3d_data->data[id & 0x7FFF]; diff --git a/src/CRE/auth_3d.hpp b/src/CRE/auth_3d.hpp index 61b87160..0fabfe74 100644 --- a/src/CRE/auth_3d.hpp +++ b/src/CRE/auth_3d.hpp @@ -829,10 +829,10 @@ struct auth_3d_id { int32_t get_uid(); void read_file(auth_3d_database* auth_3d_db); void read_file_modern(); + void set_alpha_obj_flags(float_t alpha, mdl::ObjFlags obj_flags); void set_camera_root_update(bool value); void set_chara_id(int32_t value); void set_chara_item(bool value); - void set_obj_flags_alpha(mdl::ObjFlags obj_flags, float_t alpha); void set_enable(bool value); void set_frame_rate(FrameRateControl* value); void set_last_frame(float_t value); diff --git a/src/CRE/camera.cpp b/src/CRE/camera.cpp index c3b7212a..90cf40a1 100644 --- a/src/CRE/camera.cpp +++ b/src/CRE/camera.cpp @@ -11,10 +11,10 @@ static void camera_calculate_view(camera* c); static void camera_calculate_forward(camera* c); camera::camera() : forward(), rotation(), view_point(), interest(), fov_correct_height(), -aet_depth(), render_width(), render_height(), sprite_width(), sprite_height(), -field_1E4(), field_1F0(), field_1FC(), field_208(), yaw(), pitch(), roll(), aspect(), -fov(), fov_rad(), max_distance(), min_distance(), changed_view(), changed_proj(), -changed_proj_aet(), fast_change(), fast_change_hist0(), fast_change_hist1() { +aet_depth(), use_up(), render_width(), render_height(), sprite_width(), sprite_height(), +field_1E4(), field_1F0(), field_1FC(), field_208(), yaw(), pitch(), roll(), aspect(), fov(), +fov_rad(), max_distance(), min_distance(), changed_view(), changed_proj(), changed_proj_aet(), +fast_change(), fast_change_hist0(), fast_change_hist1(), ignore_fov(), ignore_min_dist() { } @@ -30,8 +30,8 @@ void camera::initialize(double_t aspect, int32_t render_width, aet_depth = 0.0f; forward = { 0.0f, 0.0f, -1.0f }; rotation = { 0.0f, 0.0f, 0.0f }; - view_point = { 0.0, 0.0f, 0.0f }; - interest = { 0.0f, 0.0f, -1.0f }; + use_up = false; + up = { 0.0f, 1.0f, 0.0f }; this->render_width = render_width; this->render_height = render_height; this->sprite_width = sprite_width; @@ -44,14 +44,19 @@ void camera::initialize(double_t aspect, int32_t render_width, inv_view_projection = mat4_identity; view_projection_prev = mat4_identity; inv_view_projection_prev = mat4_identity; - min_distance = 0.05; - max_distance = 6000.0; changed_proj = true; changed_proj_aet = true; changed_view = true; fast_change = false; fast_change_hist0 = false; fast_change_hist1 = false; + ignore_fov = false; + ignore_min_dist = false; + + set_view_point({ 0.0, 0.0f, 0.0f }); + set_interest({ 0.0f, 0.0f, -1.0f }); + set_min_distance(0.05); + set_max_distance(6000.0); set_pitch(0.0); set_yaw(0.0); set_roll(0.0); @@ -66,7 +71,7 @@ double_t camera::get_min_distance() { } void camera::set_min_distance(double_t value) { - if (value != min_distance) { + if (!ignore_min_dist && min_distance != value) { min_distance = value; changed_proj = true; changed_proj_aet = true; @@ -78,7 +83,7 @@ double_t camera::get_max_distance() { } void camera::set_max_distance(double_t value) { - if (value != max_distance) { + if (max_distance != value) { max_distance = value; changed_proj = true; } @@ -89,7 +94,7 @@ double_t camera::get_aspect() { } void camera::set_aspect(double_t value) { - if (value != aspect) { + if (aspect != value) { aspect = value; changed_proj = true; } @@ -101,7 +106,7 @@ double_t camera::get_fov() { void camera::set_fov(double_t value) { value = clamp_def(value, 1.0, 180.0); - if (value != fov) { + if (!ignore_fov && fov != value) { fov = value; fov_rad = value * DEG_TO_RAD; changed_proj = true; @@ -155,14 +160,14 @@ void camera::get_view_point(vec4& value) { } void camera::set_view_point(const vec3& value) { - if (value != view_point) { + if (view_point != value) { view_point = value; changed_view = true; } } void camera::set_view_point(const vec3&& value) { - if (value != view_point) { + if (view_point != value) { view_point = value; changed_view = true; } @@ -173,19 +178,48 @@ void camera::get_interest(vec3& value) { } void camera::set_interest(const vec3& value) { - if (value != interest) { + if (interest != value) { interest = value; changed_view = true; } } void camera::set_interest(const vec3&& value) { - if (value != interest) { + if (interest != value) { interest = value; changed_view = true; } } +void camera::get_up(bool& use_up, vec3& value) { + use_up = this->use_up; + value = up; +} + +void camera::set_up(bool use_up, const vec3& value) { + if (this->use_up != use_up) { + this->use_up = use_up; + changed_view = true; + } + + if (up != value) { + up = value; + changed_view = true; + } +} + +void camera::set_up(bool use_up, const vec3&& value) { + if (this->use_up != use_up) { + this->use_up = use_up; + changed_view = true; + } + + if (up != value) { + up = value; + changed_view = true; + } +} + void camera::get_res(int32_t& render_width, int32_t& render_height, int32_t& sprite_width, int32_t& sprite_height) { render_width = this->render_width; @@ -219,6 +253,14 @@ void camera::set_fast_change_hist1(bool value) { fast_change_hist1 = value; } +void camera::set_ignore_fov(bool value) { + ignore_fov = value; +} + +void camera::set_ignore_min_dist(bool value) { + ignore_min_dist = value; +} + void camera::reset() { set_pitch(0.0); set_yaw(0.0); @@ -229,6 +271,8 @@ void camera::reset() { fast_change = false; fast_change_hist0 = false; fast_change_hist1 = false; + use_up = false; + up = { 0.0f, 1.0f, 0.0f }; camera_calculate_forward(this); set_position(0.0f); update_data(); @@ -402,24 +446,36 @@ static void camera_calculate_projection_aet(camera* c) { } static void camera_calculate_view(camera* c) { - vec3 direction = c->view_point - c->interest; + if (c->use_up) { + mat4_translate(&c->view_point, &c->inv_view); + vec3 z_axis = vec3::normalize(c->view_point - c->interest); + vec3 x_axis = vec3::normalize(vec3::cross(c->up, z_axis)); + vec3 y_axis = vec3::normalize(vec3::cross(z_axis, x_axis)); - vec3 rotation; - rotation.x = atan2f(-direction.y, sqrtf(direction.x * direction.x + direction.z * direction.z)); - rotation.y = atan2f(direction.x, direction.z); - rotation.z = (float_t)(c->roll * DEG_TO_RAD); + *(vec3*)&c->inv_view.row0 = x_axis; + *(vec3*)&c->inv_view.row1 = y_axis; + *(vec3*)&c->inv_view.row2 = z_axis; + mat4_inverse(&c->inv_view, &c->view); + mat4_get_rotation(&c->inv_view, &c->rotation); + } + else { + vec3 direction = c->view_point - c->interest; - c->rotation = rotation; - rotation = -rotation; + vec3 rotation; + rotation.x = atan2f(-direction.y, sqrtf(direction.x * direction.x + direction.z * direction.z)); + rotation.y = atan2f(direction.x, direction.z); + rotation.z = (float_t)(c->roll * DEG_TO_RAD); - vec3 view_point = -c->view_point; + c->rotation = rotation; + rotation = -rotation; - mat4_rotate_z(rotation.z, &c->view); - mat4_rotate_x_mult(&c->view, rotation.x, &c->view); - mat4_rotate_y_mult(&c->view, rotation.y, &c->view); - mat4_translate_mult(&c->view, &view_point, &c->view); + vec3 view_point = -c->view_point; + + mat4_rotate_zxy(&rotation, &c->view); + mat4_translate_mult(&c->view, &view_point, &c->view); + mat4_inverse(&c->view, &c->inv_view); + } - mat4_inverse(&c->view, &c->inv_view); mat3_from_mat4(&c->view, &c->view_mat3); mat3_inverse(&c->view_mat3, &c->inv_view_mat3); mat4_from_mat3(&c->view_mat3, &c->view_rot); @@ -432,3 +488,29 @@ static void camera_calculate_view(camera* c) { camera_calculate_forward(c); } } + +cam_struct::cam_struct() { + use_up = false; + view_point = { 0.0f, 1.0f, 6.0f }; + interest = { 0.0f, 1.0f, 0.0f }; + fov = (float_t)(32.2673416137695 * DEG_TO_RAD); + roll = 0.0f; + up = { 0.0f, 1.0f, 0.0f }; + min_distance = 0.05f; +} + +void cam_struct::get(camera* cam) { + cam->get_view_point(view_point); + cam->get_interest(interest); + fov = (float_t)cam->get_fov() * DEG_TO_RAD_FLOAT; + roll = (float_t)cam->get_roll() * DEG_TO_RAD_FLOAT; +} + +void cam_struct::set(camera* cam) { + cam->set_view_point(view_point); + cam->set_interest(interest); + cam->set_fov(fov * RAD_TO_DEG); + cam->set_roll(roll * RAD_TO_DEG); + cam->set_up(use_up, up); + cam->set_min_distance(min_distance); +} diff --git a/src/CRE/camera.hpp b/src/CRE/camera.hpp index cf1cbf86..1f4b91cc 100644 --- a/src/CRE/camera.hpp +++ b/src/CRE/camera.hpp @@ -30,6 +30,8 @@ struct camera { vec3 rotation; vec3 view_point; vec3 interest; + bool use_up; + vec3 up; int32_t render_width; int32_t render_height; int32_t sprite_width; @@ -52,6 +54,8 @@ struct camera { bool fast_change; bool fast_change_hist0; bool fast_change_hist1; + bool ignore_fov; + bool ignore_min_dist; camera(); ~camera(); @@ -79,6 +83,9 @@ struct camera { void get_interest(vec3& value); void set_interest(const vec3& value); void set_interest(const vec3&& value); + void get_up(bool& use_up, vec3& value); + void set_up(bool use_up, const vec3& value); + void set_up(bool use_up, const vec3&& value); void get_res(int32_t& render_width, int32_t& render_height, int32_t& sprite_width, int32_t& sprite_height); void set_res(int32_t render_width, int32_t render_height, @@ -86,6 +93,8 @@ struct camera { void set_fast_change(bool value); void set_fast_change_hist0(bool value); void set_fast_change_hist1(bool value); + void set_ignore_fov(bool value); + void set_ignore_min_dist(bool value); void reset(); void move(double_t move_x, double_t move_y); void rotate(double_t rotate_x, double_t rotate_y); @@ -98,3 +107,17 @@ struct camera { void update(); void update_data(); }; + +struct cam_struct { + bool use_up; + vec3 view_point; + vec3 interest; + float_t fov; + float_t roll; + vec3 up; + float_t min_distance; + + cam_struct(); + void get(camera* cam); + void set(camera* cam); +}; diff --git a/src/CRE/customize_item_table.cpp b/src/CRE/customize_item_table.cpp new file mode 100644 index 00000000..080444ed --- /dev/null +++ b/src/CRE/customize_item_table.cpp @@ -0,0 +1,237 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#include "customize_item_table.hpp" +#include "../KKdLib/io/path.hpp" +#include "../KKdLib/key_val.hpp" +#include "../KKdLib/str_utils.hpp" +#include "data.hpp" +#include "file_handler.hpp" +#include "mdata_manager.hpp" +#include + +struct customize_item_table_handler { + std::map name_map; + std::list file_handlers; + bool ready; + prj::vector_pair_combine customize_items; + + customize_item_table_handler(); + ~customize_item_table_handler(); + + void clear(); + void fill_name_map(); + int32_t find_value(std::string& key); + int32_t find_value(std::string&& key); + const customize_item* get_customize_item(int32_t id); + bool load(); + void parse(p_file_handler* pfhndl); + void read(); +}; + +customize_item_table_handler* customize_item_table_handler_data; + +customize_item::customize_item() : sort_index(), chara() { + id = -1; + obj_id = -1; + parts = -1; +} + +customize_item::~customize_item() { + +} + +void customize_item_table_handler_data_init() { + if (!customize_item_table_handler_data) + customize_item_table_handler_data = new customize_item_table_handler; +} + +const customize_item* customize_item_table_handler_data_get_customize_item(int32_t id) { + return customize_item_table_handler_data->get_customize_item(id); +} + +const prj::vector_pair_combine& customize_item_table_handler_data_get_customize_items() { + return customize_item_table_handler_data->customize_items; +} + +bool customize_item_table_handler_data_load() { + return customize_item_table_handler_data->load(); +} + +void customize_item_table_handler_data_read() { + customize_item_table_handler_data->read(); +} + +void customize_item_table_handler_data_free() { + + if (customize_item_table_handler_data) { + delete customize_item_table_handler_data; + customize_item_table_handler_data = 0; + } +} + +customize_item_table_handler::customize_item_table_handler() : ready() { + name_map.insert({ }); +} + +customize_item_table_handler::~customize_item_table_handler() { + clear(); +} + +void customize_item_table_handler::clear() { + ready = false; + customize_items.clear(); + + for (p_file_handler*& i : file_handlers) + if (i) { + delete i; + i = 0; + } + file_handlers.clear(); +} + +void customize_item_table_handler::fill_name_map() { + std::pair customize_item_table_names[] = { + { "MIKU" , 0 }, + { "RIN" , 1 }, + { "LEN" , 2 }, + { "LUKA" , 3 }, + { "NERU" , 4 }, + { "HAKU" , 5 }, + { "KAITO" , 6 }, + { "MEIKO" , 7 }, + { "SAKINE", 8 }, + { "TETO" , 9 }, + { "ALL" , 10 }, + { "ZUJO" , 0 }, + { "FACE" , 1 }, + { "NECK" , 2 }, + { "BACK" , 3 }, + { 0, 0 }, + }; + + std::pair* name = customize_item_table_names; + while (name->first) { + name_map.insert_or_assign(name->first, name->second); + name++; + } +} + +int32_t customize_item_table_handler::find_value(std::string& key) { + auto elem = name_map.find(key); + if (elem != name_map.end()) + return elem->second; + return 9999; +} + +int32_t customize_item_table_handler::find_value(std::string&& key) { + auto elem = name_map.find(key); + if (elem != name_map.end()) + return elem->second; + return 9999; +} + +const customize_item* customize_item_table_handler::get_customize_item(int32_t id) { + auto elem = customize_items.find(id); + if (elem != customize_items.end()) + return &elem->second; + return 0; +} + +bool customize_item_table_handler::load() { + if (ready) + return false; + + for (p_file_handler*& i : file_handlers) + if (i->check_not_ready()) + return true; + + for (p_file_handler*& i : file_handlers) { + if (!i) + continue; + + parse(i); + + delete i; + i = 0; + } + file_handlers.clear(); + + ready = true; + return false; +} + +void customize_item_table_handler::parse(p_file_handler* pfhndl) { + key_val kv; + kv.parse(pfhndl->get_data(), pfhndl->get_size()); + + int32_t count; + if (!kv.read("cstm_item", "data_list.length", count)) + return; + + for (int32_t i = 0; i < count; i++) { + if (!kv.open_scope_fmt(i)) + continue; + + customize_item customize_item; + + if (kv.has_key("id")) + kv.read("id", customize_item.id); + + if (kv.has_key("obj_id")) + kv.read("obj_id", customize_item.obj_id); + + if (kv.has_key("sort_index")) + kv.read("sort_index", customize_item.sort_index); + + if (kv.has_key("name")) + kv.read("name", customize_item.name); + + if (kv.has_key("chara")) { + const char* chara_str; + kv.read("chara", chara_str); + + int32_t chara = find_value(chara_str); + if (chara != 9999) + customize_item.chara = chara; + } + + if (kv.has_key("parts")) { + const char* parts_str; + kv.read("parts", parts_str); + + int32_t parts = find_value(parts_str); + if (parts != 9999) + customize_item.parts = parts; + } + + customize_items.push_back({ customize_item.id, customize_item }); + + kv.close_scope(); + } + + kv.close_scope(); + + customize_items.combine(); +} + +void customize_item_table_handler::read() { + ready = false; + + fill_name_map(); + + data_struct* aft_data = &data_list[DATA_AFT]; + for (const std::string& i : mdata_manager_get()->GetPrefixes()) { + std::string farc_file; + farc_file.assign(i); + farc_file.append("gm_customize_item_tbl.farc"); + + if (aft_data->check_file_exists("rom/", farc_file.c_str())) { + p_file_handler* pfhndl = new p_file_handler; + pfhndl->read_file(aft_data, "rom/", farc_file.c_str(), "gm_customize_item_id.bin", false); + file_handlers.push_back(pfhndl); + } + } +} diff --git a/src/CRE/customize_item_table.hpp b/src/CRE/customize_item_table.hpp new file mode 100644 index 00000000..9860a139 --- /dev/null +++ b/src/CRE/customize_item_table.hpp @@ -0,0 +1,31 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#pragma once + +#include +#include "../KKdLib/default.hpp" +#include "../KKdLib/database/item_table.hpp" +#include "../KKdLib/prj/vector_pair_combine.hpp" + +struct customize_item { + int32_t id; + int32_t obj_id; + int32_t sort_index; + std::string name; + int32_t chara; + int32_t parts; + + customize_item(); + ~customize_item(); +}; + +extern void customize_item_table_handler_data_init(); +extern const customize_item* customize_item_table_handler_data_get_customize_item(int32_t id); +extern const prj::vector_pair_combine& + customize_item_table_handler_data_get_customize_items(); +extern bool customize_item_table_handler_data_load(); +extern void customize_item_table_handler_data_read(); +extern void customize_item_table_handler_data_free(); diff --git a/src/CRE/draw_object.cpp b/src/CRE/draw_object.cpp index 3470f59f..8ef2a381 100644 --- a/src/CRE/draw_object.cpp +++ b/src/CRE/draw_object.cpp @@ -86,7 +86,7 @@ namespace mdl { GLuint vao = rctx->disp_manager.get_vertex_array(etc); if (!vao) return; - + vec4 g_material_state_diffuse = rctx->obj_batch.g_material_state_diffuse; vec4 g_material_state_ambient = rctx->obj_batch.g_material_state_ambient; vec4 g_material_state_specular = rctx->obj_batch.g_material_state_specular; diff --git a/src/CRE/hand_item.cpp b/src/CRE/hand_item.cpp index 4d34cb66..815780e0 100644 --- a/src/CRE/hand_item.cpp +++ b/src/CRE/hand_item.cpp @@ -153,18 +153,15 @@ void hand_item_handler::read() { data_struct* aft_data = &data_list[DATA_AFT]; for (const std::string& i : mdata_manager_get()->GetPrefixes()) { - std::string dir; - dir.assign("rom/"); - dir.append(i); + std::string file; + file.assign(i); + file.append("hand_item_data.txt"); - const char* file = "hand_item_data.txt"; - - if (!aft_data->check_file_exists(dir.c_str(), file)) - continue; - - p_file_handler* pfhndl = new p_file_handler; - pfhndl->read_file(aft_data, dir.c_str(), file); - file_handlers.push_back(pfhndl); + if (aft_data->check_file_exists("rom/", file.c_str())) { + p_file_handler* pfhndl = new p_file_handler; + pfhndl->read_file(aft_data, "rom/", file.c_str()); + file_handlers.push_back(pfhndl); + } } } diff --git a/src/CRE/hand_item.hpp b/src/CRE/hand_item.hpp index a6a49797..fd569462 100644 --- a/src/CRE/hand_item.hpp +++ b/src/CRE/hand_item.hpp @@ -5,12 +5,11 @@ #pragma once -#include +#include +#include #include "../KKdLib/default.hpp" #include "../KKdLib/database/item_table.hpp" #include "../KKdLib/database/object.hpp" -#include "../KKdLib/mat.hpp" -#include "../KKdLib/vec.hpp" struct hand_item { object_info obj_left; diff --git a/src/CRE/item_table.cpp b/src/CRE/item_table.cpp index 3d44a83a..86d9660b 100644 --- a/src/CRE/item_table.cpp +++ b/src/CRE/item_table.cpp @@ -214,18 +214,15 @@ void item_table_handler::read() { data_struct* aft_data = &data_list[DATA_AFT]; for (const std::string& i : mdata_manager_get()->GetPrefixes()) { - std::string dir; - dir.assign("rom/"); - dir.append(i); + std::string farc_file; + farc_file.assign(i); + farc_file.append("chritm_prop.farc"); - const char* farc_file = "chritm_prop.farc"; - - if (!aft_data->check_file_exists(dir.c_str(), farc_file)) - continue; - - p_file_handler* pfhndl = new p_file_handler; - pfhndl->read_file(aft_data, dir.c_str(), farc_file, file, false); - file_handlers.push_back(pfhndl); + if (aft_data->check_file_exists("rom/", farc_file.c_str())) { + p_file_handler* pfhndl = new p_file_handler; + pfhndl->read_file(aft_data, "rom/", farc_file.c_str(), file, false); + file_handlers.push_back(pfhndl); + } } } diff --git a/src/CRE/module_table.cpp b/src/CRE/module_table.cpp new file mode 100644 index 00000000..481c1ee1 --- /dev/null +++ b/src/CRE/module_table.cpp @@ -0,0 +1,226 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#include "module_table.hpp" +#include "../KKdLib/io/path.hpp" +#include "../KKdLib/key_val.hpp" +#include "../KKdLib/str_utils.hpp" +#include "data.hpp" +#include "file_handler.hpp" +#include "mdata_manager.hpp" +#include + +struct module_table_handler { + std::map name_map; + std::list file_handlers; + bool ready; + prj::vector_pair_combine modules; + + module_table_handler(); + ~module_table_handler(); + + void clear(); + void fill_name_map(); + int32_t find_value(std::string& key); + int32_t find_value(std::string&& key); + const module* get_module(int32_t id); + bool load(); + void parse(p_file_handler* pfhndl); + void read(); +}; + +module_table_handler* module_table_handler_data; + +module::module() : sort_index(), chara(), cos() { + id = -1; +} + +module::~module() { + +} + +void module_table_handler_data_init() { + if (!module_table_handler_data) + module_table_handler_data = new module_table_handler; +} + +const module* module_table_handler_data_get_module(int32_t id) { + return module_table_handler_data->get_module(id); +} + +const prj::vector_pair_combine& module_table_handler_data_get_modules() { + return module_table_handler_data->modules; +} + +bool module_table_handler_data_load() { + return module_table_handler_data->load(); +} + +void module_table_handler_data_read() { + module_table_handler_data->read(); +} + +void module_table_handler_data_free() { + + if (module_table_handler_data) { + delete module_table_handler_data; + module_table_handler_data = 0; + } +} + +module_table_handler::module_table_handler() : ready() { + name_map.insert({ }); +} + +module_table_handler::~module_table_handler() { + clear(); +} + +void module_table_handler::clear() { + ready = false; + modules.clear(); + + for (p_file_handler*& i : file_handlers) + if (i) { + delete i; + i = 0; + } + file_handlers.clear(); +} + +void module_table_handler::fill_name_map() { + std::pair module_table_names[] = { + { "MIKU" , 0 }, + { "RIN" , 1 }, + { "LEN" , 2 }, + { "LUKA" , 3 }, + { "NERU" , 4 }, + { "HAKU" , 5 }, + { "KAITO" , 6 }, + { "MEIKO" , 7 }, + { "SAKINE", 8 }, + { "TETO" , 9 }, + { 0, 0 }, + }; + + std::pair* name = module_table_names; + while (name->first) { + name_map.insert_or_assign(name->first, name->second); + name++; + } +} + +int32_t module_table_handler::find_value(std::string& key) { + auto elem = name_map.find(key); + if (elem != name_map.end()) + return elem->second; + return 9999; +} + +int32_t module_table_handler::find_value(std::string&& key) { + auto elem = name_map.find(key); + if (elem != name_map.end()) + return elem->second; + return 9999; +} + +const module* module_table_handler::get_module(int32_t id) { + auto elem = modules.find(id); + if (elem != modules.end()) + return &elem->second; + return 0; +} + +bool module_table_handler::load() { + if (ready) + return false; + + for (p_file_handler*& i : file_handlers) + if (i->check_not_ready()) + return true; + + for (p_file_handler*& i : file_handlers) { + if (!i) + continue; + + parse(i); + + delete i; + i = 0; + } + file_handlers.clear(); + + ready = true; + return false; +} + +void module_table_handler::parse(p_file_handler* pfhndl) { + key_val kv; + kv.parse(pfhndl->get_data(), pfhndl->get_size()); + + int32_t count; + if (!kv.read("module", "data_list.length", count)) + return; + + for (int32_t i = 0; i < count; i++) { + if (!kv.open_scope_fmt(i)) + continue; + + module module; + + if (kv.has_key("id")) + kv.read("id", module.id); + + if (kv.has_key("sort_index")) + kv.read("sort_index", module.sort_index); + + if (kv.has_key("name")) + kv.read("name", module.name); + + if (kv.has_key("chara")) { + const char* chara_str; + kv.read("chara", chara_str); + + int32_t chara = find_value(chara_str); + if (chara != 9999) + module.chara = chara; + } + + if (kv.has_key("cos")) { + int32_t cos; + kv.read("cos", cos); + cos--; + if (cos != 9999) + module.cos = cos; + } + + modules.push_back({ module.id, module }); + + kv.close_scope(); + } + + kv.close_scope(); + + modules.combine(); +} + +void module_table_handler::read() { + ready = false; + + fill_name_map(); + + data_struct* aft_data = &data_list[DATA_AFT]; + for (const std::string& i : mdata_manager_get()->GetPrefixes()) { + std::string farc_file; + farc_file.assign(i); + farc_file.append("gm_module_tbl.farc"); + + if (aft_data->check_file_exists("rom/", farc_file.c_str())) { + p_file_handler* pfhndl = new p_file_handler; + pfhndl->read_file(aft_data, "rom/", farc_file.c_str(), "gm_module_id.bin", false); + file_handlers.push_back(pfhndl); + } + } +} diff --git a/src/CRE/module_table.hpp b/src/CRE/module_table.hpp new file mode 100644 index 00000000..c8415693 --- /dev/null +++ b/src/CRE/module_table.hpp @@ -0,0 +1,29 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#pragma once + +#include +#include "../KKdLib/default.hpp" +#include "../KKdLib/database/item_table.hpp" +#include "../KKdLib/prj/vector_pair_combine.hpp" + +struct module { + int32_t id; + int32_t sort_index; + std::string name; + int32_t chara; + int32_t cos; + + module(); + ~module(); +}; + +extern void module_table_handler_data_init(); +extern const module* module_table_handler_data_get_module(int32_t id); +extern const prj::vector_pair_combine& module_table_handler_data_get_modules(); +extern bool module_table_handler_data_load(); +extern void module_table_handler_data_read(); +extern void module_table_handler_data_free(); diff --git a/src/CRE/ogg_vorbis.cpp b/src/CRE/ogg_vorbis.cpp index 39df7832..e24fe547 100644 --- a/src/CRE/ogg_vorbis.cpp +++ b/src/CRE/ogg_vorbis.cpp @@ -592,7 +592,7 @@ void OggFileHandler::SetPath(std::string& path) { } void OggFileHandler::SetPath(std::string&& path) { - SetPath(*(std::string*)&path); + SetPath(path); } void OggFileHandler::SetPauseState(OggFileHandlerPauseState value) { @@ -817,7 +817,7 @@ void OggPlayback::SetPath(std::string& path) { } void OggPlayback::SetPath(std::string&& path) { - SetPath(*(std::string*)&path); + SetPath(path); } void OggPlayback::SetPauseState(OggFileHandlerPauseState value) { diff --git a/src/CRE/post_process.cpp b/src/CRE/post_process.cpp index c2a257b8..abe7b679 100644 --- a/src/CRE/post_process.cpp +++ b/src/CRE/post_process.cpp @@ -18,6 +18,22 @@ extern bool task_stage_is_modern; extern render_context* rctx_ptr; +post_process_frame_texture_render_texture::post_process_frame_texture_render_texture() : texture() { + type = POST_PROCESS_FRAME_TEXTURE_MAX; +} + +post_process_frame_texture_render_texture::~post_process_frame_texture_render_texture() { + +} + +post_process_frame_texture::post_process_frame_texture() : capture() { + +} + +post_process_frame_texture::~post_process_frame_texture() { + +} + post_process::post_process() : ssaa(), mlaa(), ss_alpha_mask(), aet_back_tex(), render_textures_data(), movie_textures_data(), aet_back(), texture_counter(), lens_shaft_query(), lens_flare_query(), lens_shaft_query_data(), lens_flare_query_data(), lens_flare_query_index(), @@ -155,6 +171,8 @@ void post_process::apply(camera* cam, texture* light_proj_tex, int32_t npr_param draw_lens_ghost(&rend_texture); + get_frame_texture(rend_texture.color_texture->tex, POST_PROCESS_FRAME_TEXTURE_PRE_PP); + blur->get_blur(&rend_texture); exposure->get_exposure(cam, render_width, render_height, reset_exposure, blur->tex[4].color_texture->tex, blur->tex[2].color_texture->tex); @@ -184,6 +202,8 @@ void post_process::apply(camera* cam, texture* light_proj_tex, int32_t npr_param render_texture::draw_quad(&shaders_ft, render_width, render_height); } + get_frame_texture(rend_texture.color_texture->tex, POST_PROCESS_FRAME_TEXTURE_POST_PP); + fbo::blit(rend_texture.fbos[0], post_texture.fbos[0], 0, 0, render_width, render_height, 0, 0, render_width, render_height, GL_COLOR_BUFFER_BIT, GL_LINEAR); @@ -636,6 +656,70 @@ void post_process::init_fbo(int32_t render_width, int32_t render_height, this->screen_height = screen_height; } +bool post_process::frame_texture_cont_capture_set(bool value) { + frame_texture[0].capture = value; + return true; +} + +void post_process::frame_texture_free() { + for (post_process_frame_texture& i : frame_texture) { + for (post_process_frame_texture_render_texture& j : i.render_textures) { + j.texture = 0; + j.render_texture.free(); + j.type = POST_PROCESS_FRAME_TEXTURE_MAX; + } + + i.capture = false; + } +} + +int32_t post_process::frame_texture_load(int32_t slot, post_process_frame_texture_type type, texture* tex) { + if (!tex || slot < 0 || slot >= 6) + return -1; + + for (post_process_frame_texture_render_texture& i : frame_texture[slot].render_textures) + if (!i.texture) { + i.render_texture.set_color_depth_textures(tex->tex, 0, 0); + i.texture = tex; + i.type = type; + return (int32_t)(&i - frame_texture[slot].render_textures); + } + return -1; +} + +void post_process::frame_texture_reset() { + for (post_process_frame_texture& i : frame_texture) { + for (post_process_frame_texture_render_texture& j : i.render_textures) { + j.texture = 0; + j.type = POST_PROCESS_FRAME_TEXTURE_MAX; + } + + i.capture = false; + } +} + +bool post_process::frame_texture_slot_capture_set(int32_t index) { + if (index < 1 || index >= 5) + return false; + + frame_texture[index].capture = true; + return true; +} + +bool post_process::frame_texture_unload(int32_t slot, texture* tex) { + if (!tex || slot < 0 || slot >= 6) + return false; + + for (post_process_frame_texture_render_texture& i : frame_texture[slot].render_textures) + if (i.texture == tex) { + i.render_texture.free(); + i.texture = 0; + i.type = POST_PROCESS_FRAME_TEXTURE_MAX; + return true; + } + return false; +} + int32_t post_process::movie_texture_set(texture* movie_texture) { if (!movie_texture) return -1; @@ -650,6 +734,33 @@ int32_t post_process::movie_texture_set(texture* movie_texture) { return index; } +void post_process::get_frame_texture(GLuint tex, post_process_frame_texture_type type) { + for (post_process_frame_texture& i : frame_texture) { + if (!i.capture) + continue; + + for (auto& j : i.render_textures) { + if (!j.texture || j.type != type || j.render_texture.bind() < 0) + continue; + + texture* dst_tex = j.texture; + + glActiveTexture(GL_TEXTURE0); + gl_state_active_bind_texture_2d(GL_TEXTURE_2D, tex); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glViewport(0, 0, dst_tex->width, dst_tex->height); + uniform_value[U_REDUCE] = 0; + shaders_ft.set(SHADER_FT_REDUCE); + render_texture::draw_quad(&shaders_ft, dst_tex->width, dst_tex->height); + gl_state_bind_framebuffer(0); + } + + if (&i - frame_texture) + i.capture = false; + } +} + void post_process::movie_texture_free(texture* movie_texture) { if (!movie_texture) return; diff --git a/src/CRE/post_process.hpp b/src/CRE/post_process.hpp index bb527b12..13746dd1 100644 --- a/src/CRE/post_process.hpp +++ b/src/CRE/post_process.hpp @@ -15,14 +15,21 @@ #include "post_process/tone_map.hpp" #include "camera.hpp" +enum post_process_frame_texture_type { + POST_PROCESS_FRAME_TEXTURE_PRE_PP = 0, + POST_PROCESS_FRAME_TEXTURE_POST_PP, + POST_PROCESS_FRAME_TEXTURE_FB, + POST_PROCESS_FRAME_TEXTURE_MAX, +}; + enum post_process_mag_filter_type { - POST_PROCESS_MAG_FILTER_NEAREST = 0, - POST_PROCESS_MAG_FILTER_BILINEAR = 1, - POST_PROCESS_MAG_FILTER_SHARPEN_5_TAP = 2, - POST_PROCESS_MAG_FILTER_SHARPEN_4_TAP = 3, - POST_PROCESS_MAG_FILTER_CONE_4_TAP = 4, - POST_PROCESS_MAG_FILTER_CONE_2_TAP = 5, - POST_PROCESS_MAG_FILTER_MAX = 6, + POST_PROCESS_MAG_FILTER_NEAREST = 0, + POST_PROCESS_MAG_FILTER_BILINEAR, + POST_PROCESS_MAG_FILTER_SHARPEN_5_TAP, + POST_PROCESS_MAG_FILTER_SHARPEN_4_TAP, + POST_PROCESS_MAG_FILTER_CONE_4_TAP, + POST_PROCESS_MAG_FILTER_CONE_2_TAP, + POST_PROCESS_MAG_FILTER_MAX, }; struct sun_quad_shader_data { @@ -30,6 +37,24 @@ struct sun_quad_shader_data { vec4 g_emission; }; +struct post_process_frame_texture_render_texture { + texture* texture; + render_texture render_texture; + post_process_frame_texture_type type; + + post_process_frame_texture_render_texture(); + ~post_process_frame_texture_render_texture(); +}; + + +struct post_process_frame_texture { + post_process_frame_texture_render_texture render_textures[4]; + bool capture; + + post_process_frame_texture(); + ~post_process_frame_texture(); +}; + struct post_process { bool ssaa; bool mlaa; @@ -90,6 +115,7 @@ struct post_process { int32_t screen_width; int32_t screen_height; post_process_mag_filter_type mag_filter; + post_process_frame_texture frame_texture[6]; post_process(); ~post_process(); @@ -100,6 +126,13 @@ struct post_process { void draw_lens_ghost(render_texture* rt); void init_fbo(int32_t render_width, int32_t render_height, int32_t sprite_width, int32_t sprite_height, int32_t screen_width, int32_t screen_height); + bool frame_texture_cont_capture_set(bool value); + void frame_texture_free(); + int32_t frame_texture_load(int32_t slot, post_process_frame_texture_type type, texture* tex); + void frame_texture_reset(); + bool frame_texture_slot_capture_set(int32_t index); + bool frame_texture_unload(int32_t slot, texture* tex); + void get_frame_texture(GLuint tex, post_process_frame_texture_type type); int32_t movie_texture_set(texture* movie_texture); void movie_texture_free(texture* movie_texture); int32_t render_texture_set(texture* render_texture, bool task_photo); diff --git a/src/CRE/pv_db.cpp b/src/CRE/pv_db.cpp index 9d8ff082..9a988d4e 100644 --- a/src/CRE/pv_db.cpp +++ b/src/CRE/pv_db.cpp @@ -24,7 +24,7 @@ pv_db_pv_lyric::~pv_db_pv_lyric() { pv_db_pv_performer::pv_db_pv_performer() { type = PV_PERFORMER_VOCAL; - chara = -1; + chara = (chara_index)-1; costume = -1; pv_costume[0] = -1; pv_costume[1] = -1; @@ -244,6 +244,19 @@ pv_db_pv_difficulty::~pv_db_pv_difficulty() { } +const pv_db_pv_motion& pv_db_pv_difficulty::get_motion_or_default(int32_t chara_id, int32_t index) const { + static const pv_db_pv_motion pv_db_pv_motion_null; + + if (chara_id < 0 || chara_id >= ROB_CHARA_COUNT) + return pv_db_pv_motion_null; + + for (const pv_db_pv_motion& i : motion[chara_id]) + if (i.index == index) + return i; + + return pv_db_pv_motion_null; +} + void pv_db_pv_difficulty::reset() { difficulty = PV_DIFFICULTY_MAX; edition = -1; @@ -279,7 +292,7 @@ void pv_db_pv_difficulty::reset() { hand_item.clear(); hand_item.shrink_to_fit(); - for (std::vector& i : motion) { + for (auto& i : field_228) { i.clear(); i.shrink_to_fit(); } @@ -320,8 +333,8 @@ pv_db_pv_ex_song::~pv_db_pv_ex_song() { } void pv_db_pv_ex_song::reset() { - for (int32_t& i : chara) - i = -1; + for (chara_index& i : chara) + i = (chara_index)-1; file.clear(); file.shrink_to_fit(); name.clear(); @@ -468,25 +481,183 @@ pv_db_pv::~pv_db_pv() { } -pv_db_pv_difficulty* pv_db_pv::get_difficulty(int32_t difficulty, pv_attribute_type attribute_type) { +int32_t pv_db_pv::get_chrmot_motion_id(int32_t chara_id, + chara_index chara_index, const pv_db_pv_motion& motion) const { + if (!chrmot.size()) + return motion.id; + + data_struct* aft_data = &data_list[DATA_AFT]; + motion_database* aft_mot_db = &aft_data->data_ft.mot_db; + + for (const pv_db_pv_chrmot& i : chrmot) + if (i.id == chara_id && chara_index_get_from_chara_name(i.chara.c_str()) + == chara_index && !i.org_name.compare(motion.name)) { + int32_t motion_id = aft_mot_db->get_motion_id(i.name.c_str()); + if (motion_id != -1) + return motion_id; + break; + } + + return motion.id; +} + +const pv_db_pv_difficulty* pv_db_pv::get_difficulty(int32_t difficulty, pv_attribute_type attribute_type) const { if (attribute_type == PV_ATTRIBUTE_END) return 0; - std::vector& diff = this->difficulty[difficulty]; - for (pv_db_pv_difficulty& i : diff) + const std::vector& diff = this->difficulty[difficulty]; + for (const pv_db_pv_difficulty& i : diff) if (i.attribute.type == attribute_type) return &i; return 0; } -pv_db_pv_difficulty* pv_db_pv::get_difficulty(int32_t difficulty, int32_t edition) { - std::vector& diff = this->difficulty[difficulty]; - for (pv_db_pv_difficulty& i : diff) +const pv_db_pv_difficulty* pv_db_pv::get_difficulty(int32_t difficulty, int32_t edition) const { + const std::vector& diff = this->difficulty[difficulty]; + for (const pv_db_pv_difficulty& i : diff) if (i.edition == edition) return &i; return 0; } +chara_index pv_db_pv::get_performer_chara(int32_t performer) const { + if (performer < 0 || performer >= ROB_CHARA_COUNT || performer >= this->performer.size()) + return CHARA_MIKU; + + chara_index chara = this->performer[performer].chara; + pv_performer_type type = this->performer[performer].type; + if (type >= PV_PERFORMER_PSEUDO_DEFAULT && type <= PV_PERFORMER_PSEUDO_MYCHARA) { + performer = get_performer_pseudo_same_id(performer); + if (performer >= 0) + chara = this->performer[performer].chara; + } + + if (chara < 0 || chara >= CHARA_MAX) + chara = CHARA_MIKU; + + return chara; +} + +int32_t pv_db_pv::get_performer_costume(int32_t performer) const { + if (performer < 0 || performer >= ROB_CHARA_COUNT || performer >= this->performer.size()) + return -1; + + int32_t costume = this->performer[performer].costume; + pv_performer_type type = this->performer[performer].type; + if (type >= PV_PERFORMER_PSEUDO_DEFAULT && type <= PV_PERFORMER_PSEUDO_MYCHARA) { + performer = pv_db_pv::get_performer_pseudo_same_id(performer); + if (performer >= 0) { + const pv_db_pv_performer* perf = &this->performer[performer]; + costume = pv_db_pv::get_pseudo_costume(type, (chara_index)perf->chara, perf->costume); + } + } + return costume; +} + +size_t pv_db_pv::get_performer_count() const { + if (performer.size()) + return performer.size(); + return 1; +} + +int32_t pv_db_pv::get_performer_exclude(int32_t performer) const { + if (performer < 0 || performer >= ROB_CHARA_COUNT || performer >= this->performer.size()) + return -1; + + return this->performer[performer].exclude; +} + +bool pv_db_pv::get_performer_fixed(int32_t performer) const { + if (performer < 0 || performer >= ROB_CHARA_COUNT || performer >= this->performer.size()) + return false; + + return this->performer[performer].fixed; +} + +int32_t pv_db_pv::get_performer_item(int32_t performer, pv_performer_item item) const { + if (performer < 0 || performer >= ROB_CHARA_COUNT || performer >= this->performer.size()) + return -1; + + if (item >= 0 && item < PV_PERFORMER_ITEM_MAX) + return this->performer[performer].item[item]; + return -1; +} + +bool pv_db_pv::get_performer_pseudo_fixed(chara_index chara_index, int32_t performer, bool a4, bool a5) const { + if (performer < 0 || performer >= ROB_CHARA_COUNT + || chara_index < 0 || chara_index >= CHARA_MAX || performer >= this->performer.size()) + return false; + + ::chara_index chara = this->performer[performer].chara; + pv_performer_type type = this->performer[performer].type; + bool v11 = (!a5 ? !a4 : false) || get_performer_fixed(performer); + if (type >= PV_PERFORMER_PSEUDO_DEFAULT && type <= PV_PERFORMER_PSEUDO_MYCHARA) + return true; + else if (chara < 0 || chara >= CHARA_MAX) + return false; + return v11; +} + +int32_t pv_db_pv::get_performer_pseudo_same_id(int32_t performer) const { + if (performer < 0 || performer >= ROB_CHARA_COUNT || performer >= this->performer.size()) + return -1; + + pv_performer_type type = this->performer[performer].type; + if (type < PV_PERFORMER_PSEUDO_DEFAULT || type > PV_PERFORMER_PSEUDO_MYCHARA) + return -1; + + if (type == PV_PERFORMER_PSEUDO_SAME) { + int32_t perf = this->performer[performer].pseudo_same_id; + if (perf != -1) { + if (perf >= 0 && perf < this->performer.size() && performer > perf) + return perf; + return -1; + } + } + + while (--performer >= 0) { + if (this->performer[performer].type == PV_PERFORMER_VOCAL) + return performer; + } + return -1; +} + +pv_performer_size pv_db_pv::get_performer_size(int32_t performer) const { + if (performer < 0 || performer >= ROB_CHARA_COUNT || performer >= this->performer.size()) + return PV_PERFORMER_NORMAL; + + pv_performer_size size = this->performer[performer].size; + pv_performer_type type = this->performer[performer].type; + if (type >= PV_PERFORMER_PSEUDO_DEFAULT && type <= PV_PERFORMER_PSEUDO_MYCHARA) { + performer = get_performer_pseudo_same_id(performer); + if (performer >= 0) + size = this->performer[performer].size; + } + return size; +} + +pv_performer_type pv_db_pv::get_performer_type(int32_t performer) const { + if (performer < 0 || performer >= ROB_CHARA_COUNT || performer >= this->performer.size()) + return PV_PERFORMER_VOCAL; + + return this->performer[performer].type; +} + +bool pv_db_pv::is_performer_type_pseudo(int32_t performer) const { + if (performer < 0 || performer >= ROB_CHARA_COUNT || performer >= this->performer.size()) + return false; + + pv_performer_type type = this->performer[performer].type; + return type >= PV_PERFORMER_PSEUDO_DEFAULT && type <= PV_PERFORMER_PSEUDO_MYCHARA; +} + +bool pv_db_pv::is_performer_type_vocal(int32_t performer) const { + if (performer < 0 || performer >= ROB_CHARA_COUNT || performer >= this->performer.size()) + return false; + + return this->performer[performer].type == PV_PERFORMER_VOCAL; +} + void pv_db_pv::reset() { id = -1; date = -1; @@ -542,6 +713,21 @@ void pv_db_pv::reset() { auth_replace_by_module.shrink_to_fit(); } +int32_t pv_db_pv::get_pseudo_costume(pv_performer_type type, chara_index chara_index, int32_t costume) { + switch (type) { + case PV_PERFORMER_PSEUDO_SAME: + return costume; + case PV_PERFORMER_PSEUDO_SWIM: + return chara_init_data_get_swim_costume(chara_index); + case PV_PERFORMER_PSEUDO_SWIM_S: + return chara_init_data_get_swim_s_costume(chara_index); + case PV_PERFORMER_PSEUDO_MYCHARA: + return -1; + default: + return 0; + } +} + namespace pv_db { static const char* aet_names[] = { "aet_front", @@ -838,10 +1024,10 @@ namespace pv_db { pv->reset(); pv->id = pv_id; - pv->song_name = song_name; - pv->song_name_reading = song_name_reading; + pv->song_name.assign(song_name); + pv->song_name_reading.assign(song_name_reading); pv->bpm = bpm; - pv->song_file_name = song_file_name; + pv->song_file_name.assign(song_file_name); pv->date = date; int32_t remix_parent; @@ -966,15 +1152,15 @@ namespace pv_db { std::string chara; if (kv.read("chara", chara)) - chrcam.chara = chara; + chrcam.chara.assign(chara); std::string org_name; if (kv.read("org_name", org_name)) - chrcam.org_name = org_name; + chrcam.org_name.assign(org_name); std::string name; if (kv.read("name", name)) - chrcam.name = name; + chrcam.name.assign(name); kv.close_scope(); } @@ -995,15 +1181,15 @@ namespace pv_db { std::string chara; if (kv.read("chara", chara)) - chrmot.chara = chara; + chrmot.chara.assign(chara); std::string org_name; if (kv.read("org_name", org_name)) - chrmot.org_name = org_name; + chrmot.org_name.assign(org_name); std::string name; if (kv.read("name", name)) - chrmot.name = name; + chrmot.name.assign(name); kv.close_scope(); } @@ -1024,7 +1210,7 @@ namespace pv_db { std::string name; if (kv.read("name", name)) - chreff.name = name; + chreff.name.assign(name); int32_t count; if (kv.read("data", "length", count)) { @@ -1044,7 +1230,7 @@ namespace pv_db { std::string name; if (kv.read("name", name)) - chreff.name = name; + chreff.name.assign(name); kv.close_scope(); } @@ -1182,7 +1368,7 @@ namespace pv_db { continue; } - d.script_file_name = script_file_name; + d.script_file_name.assign(script_file_name); const char* level; if (kv.read("level", level)) @@ -1202,39 +1388,39 @@ namespace pv_db { std::string se_name; if (kv.read("se_name", se_name)) - d.se_name = se_name; + d.se_name.assign(se_name); std::string pvbranch_success_se_name; if (kv.read("pvbranch_success_se_name", pvbranch_success_se_name)) - d.pvbranch_success_se_name = pvbranch_success_se_name; + d.pvbranch_success_se_name.assign(pvbranch_success_se_name); std::string slide_name; if (kv.read("slide_name", slide_name)) - d.slide_name = slide_name; + d.slide_name.assign(slide_name); std::string chainslide_first_name; if (kv.read("chainslide_first_name", chainslide_first_name)) - d.chainslide_first_name = chainslide_first_name; + d.chainslide_first_name.assign(chainslide_first_name); std::string chainslide_sub_name; if (kv.read("chainslide_sub_name", chainslide_sub_name)) - d.chainslide_sub_name = chainslide_sub_name; + d.chainslide_sub_name.assign(chainslide_sub_name); std::string chainslide_success_name; if (kv.read("chainslide_success_name", chainslide_success_name)) - d.chainslide_success_name = chainslide_success_name; + d.chainslide_success_name.assign(chainslide_success_name); std::string chainslide_failure_name; if (kv.read("chainslide_failure_name", chainslide_failure_name)) - d.chainslide_failure_name = chainslide_failure_name; + d.chainslide_failure_name.assign(chainslide_failure_name); std::string slidertouch_name; if (kv.read("slidertouch_name", slidertouch_name)) - d.slidertouch_name = slidertouch_name; + d.slidertouch_name.assign(slidertouch_name); for (size_t l = 0; l < ROB_CHARA_COUNT; l++) { if (l) - sprintf_s(buf, sizeof(buf), "motion%zuP", l); + sprintf_s(buf, sizeof(buf), "motion%zuP", l + 1); if (!kv.open_scope_fmt(l ? buf : "motion")) continue; @@ -1267,7 +1453,7 @@ namespace pv_db { pv_db_pv_item item; item.index = (int32_t)k; - item.name = name; + item.name.assign(name); d.pv_item.push_back(item); kv.close_scope(); } @@ -1286,7 +1472,7 @@ namespace pv_db { pv_db_pv_hand_item hand_item; hand_item.index = (int32_t)k; hand_item.id = hand_item_handler_data_get_hand_item_uid(name.c_str()); - hand_item.name = name; + hand_item.name.assign(name); d.hand_item.push_back(hand_item); kv.close_scope(); } @@ -1304,7 +1490,7 @@ namespace pv_db { pv_db_pv_edit_effect edit_effect; edit_effect.index = atoi(name.c_str()); - edit_effect.name = name; + edit_effect.name.assign(name); d.edit_effect.push_back(edit_effect); kv.close_scope(); } @@ -1340,7 +1526,7 @@ namespace pv_db { std::string aet_name; if (kv.read("aet_name", aet_name)) - title_image.aet_name = aet_name; + title_image.aet_name.assign(aet_name); kv.close_scope(); } @@ -1350,27 +1536,27 @@ namespace pv_db { std::string music; if (kv.read("music", music)) - songinfo.music = music; + songinfo.music.assign(music); std::string lyrics; if (kv.read("lyrics", lyrics)) - songinfo.lyrics = lyrics; + songinfo.lyrics.assign(lyrics); std::string arranger; if (kv.read("arranger", arranger)) - songinfo.arranger = arranger; + songinfo.arranger.assign(arranger); std::string manipulator; if (kv.read("manipulator", manipulator)) - songinfo.manipulator = manipulator; + songinfo.manipulator.assign(manipulator); std::string pv_editor; if (kv.read("pv_editor", pv_editor)) - songinfo.pv_editor = pv_editor; + songinfo.pv_editor.assign(pv_editor); std::string guitar_player; if (kv.read("guitar_player", guitar_player)) - songinfo.guitar_player = guitar_player; + songinfo.guitar_player.assign(guitar_player); if (kv.open_scope("ex_info")) { std::pair* ex_info = songinfo.ex_info; @@ -1424,7 +1610,7 @@ namespace pv_db { if (kv.read("movie_file_name", movie_file_name)) { pv_db_pv_movie movie; movie.index = 0; - movie.name = movie_file_name; + movie.name.assign(movie_file_name); d.movie_list.push_back(movie); } @@ -1437,7 +1623,7 @@ namespace pv_db { std::string effect_se_file_name; if (kv.read("effect_se_file_name", effect_se_file_name)) - d.effect_se_file_name = effect_se_file_name; + d.effect_se_file_name.assign(effect_se_file_name); if (!k && kv.read("effect_se_name_list", "length", count)) { d.effect_se_name_list.reserve(count); @@ -1527,7 +1713,7 @@ namespace pv_db { bool v533 = false; for (size_t j = 1; j < ROB_CHARA_COUNT; j++) { - sprintf_s(buf, sizeof(buf), "chara%zuP", j); + sprintf_s(buf, sizeof(buf), "chara%zuP", j + 1); const char* chara; if (kv.read(buf, chara)) { @@ -1539,8 +1725,8 @@ namespace pv_db { v533 = true; } - ex_song.file = file; - ex_song.name = name; + ex_song.file.assign(file); + ex_song.name.assign(name); int32_t count; if (kv.read("ex_auth", "length", count)) { @@ -1552,10 +1738,10 @@ namespace pv_db { std::string org_name; std::string name; if (kv.read("org_name", org_name) - && kv.read("org_name", org_name)) { + && kv.read("name", name)) { pv_db_pv_ex_song_ex_auth ex_auth; - ex_auth.org_name = org_name; - ex_auth.name = name; + ex_auth.org_name.assign(org_name); + ex_auth.name.assign(name); ex_song.ex_auth.push_back(ex_auth); } kv.close_scope(); @@ -1594,7 +1780,7 @@ namespace pv_db { && kv.read("frame", frame) && kv.read("stage", stage)) { pv_db_pv_osage_init osage_init; - osage_init.motion = motion; + osage_init.motion.assign(motion); osage_init.frame = frame; osage_init.stage = aft_stage_data->get_stage_index(stage.c_str()); pv->osage_init.push_back(osage_init); @@ -1627,11 +1813,11 @@ namespace pv_db { std::string collision_file; if (kv.read("collision_file", collision_file)) - stage_param.collision_file = collision_file; + stage_param.collision_file.assign(collision_file); std::string wind_file; if (kv.read("collision_file", wind_file)) - stage_param.wind_file = wind_file; + stage_param.wind_file.assign(wind_file); pv->stage_param.push_back(stage_param); @@ -1645,7 +1831,7 @@ namespace pv_db { std::string set_name; if (kv.read("set_name", set_name)) - disp2d.set_name = set_name; + disp2d.set_name.assign(set_name); int32_t target_shadow_type; if (kv.read("target_shadow_type", target_shadow_type)) @@ -1677,7 +1863,7 @@ namespace pv_db { std::string title_2d_layer; if (kv.read("title_2d_layer", title_2d_layer)) - disp2d.title_2d_layer = title_2d_layer; + disp2d.title_2d_layer.assign(title_2d_layer); kv.close_scope(); } @@ -1688,7 +1874,7 @@ namespace pv_db { std::string pv_expression_file_name; if (kv.read("pv_expression.file_name", pv_expression_file_name)) - pv->pv_expression_file_name = pv_expression_file_name; + pv->pv_expression_file_name.assign(pv_expression_file_name); if (kv.read("another_song", "length", count)) { pv->another_song.reserve(count); @@ -1700,11 +1886,11 @@ namespace pv_db { std::string name; if (kv.read("name", name)) - another_song.name = name; + another_song.name.assign(name); std::string song_file_name; if (kv.read("song_file_name", song_file_name)) - another_song.song_file_name = song_file_name; + another_song.song_file_name.assign(song_file_name); pv->another_song.push_back(another_song); @@ -1721,7 +1907,7 @@ namespace pv_db { std::string data; if (kv.read(frame_texture_names[i], data)) - frame_texture.data = data; + frame_texture.data.assign(data); const char* type; if (kv.read(frame_texture_type_names[i], type)) { @@ -1783,7 +1969,7 @@ namespace pv_db { j.field.ex_stage_set = false; j.field.data.reserve(count); - for (int32_t k = 0; k < count; k++) { + for (int32_t k = 0; k <= count; k++) { if (!kv.open_scope_fmt("%02d", k)) continue; @@ -1924,11 +2110,25 @@ namespace pv_db { } } - kv.read("spr_set_back", field.spr_set_back); - kv.read("stage_flag", field.stage_flag); - kv.read("npr_type", field.npr_type); - kv.read("cam_blur", field.cam_blur); - kv.read("sdw_off", field.sdw_off); + bool spr_set_back; + if (kv.read("spr_set_back", spr_set_back)) + field.spr_set_back = spr_set_back; + + bool stage_flag; + if (kv.read("stage_flag", stage_flag)) + field.stage_flag = stage_flag; + + bool npr_type; + if (kv.read("npr_type", npr_type)) + field.npr_type = npr_type; + + bool cam_blur; + if (kv.read("cam_blur", cam_blur)) + field.cam_blur = cam_blur; + + bool sdw_off; + if (kv.read("sdw_off", sdw_off)) + field.sdw_off = sdw_off; if (kv.read("play_eff_list", "length", count)) { field.play_eff_list.reserve(count); @@ -1998,6 +2198,26 @@ namespace pv_db { } } +item_id pv_performer_item_to_item_id(pv_performer_item item) { + static const item_id pv_performer_item_id_to_item_id_table[] = { + ITEM_ZUJO, ITEM_MEGANE, ITEM_KUBI, ITEM_JOHA_USHIRO, + }; + + if (item >= 0 && item < PV_PERFORMER_ITEM_MAX) + return pv_performer_item_id_to_item_id_table[item]; + return ITEM_NONE; +} + +item_sub_id pv_performer_item_to_item_sub_id(pv_performer_item item) { + static const item_sub_id pv_performer_item_id_to_item_sub_id_table[] = { + ITEM_SUB_ZUJO, ITEM_SUB_MEGANE, ITEM_SUB_KUBI, ITEM_SUB_L_UDE, + }; + + if (item >= 0 && item < PV_PERFORMER_ITEM_MAX) + return pv_performer_item_id_to_item_sub_id_table[item]; + return ITEM_SUB_NONE; +} + void task_pv_db_init() { task_pv_db = new pv_db::TaskPvDB; } @@ -2047,22 +2267,20 @@ pv_db_pv* task_pv_db_get_pv(int32_t pv_id) { return 0; } -pv_db_pv_difficulty* task_pv_db_get_pv_difficulty(int32_t pv_id, +const pv_db_pv_difficulty* task_pv_db_get_pv_difficulty(int32_t pv_id, int32_t difficulty, pv_attribute_type attribute_type) { pv_db_pv* pv = task_pv_db_get_pv(pv_id); - if (!pv) - return 0; - - return pv->get_difficulty(difficulty, attribute_type); + if (pv) + return pv->get_difficulty(difficulty, attribute_type); + return 0; } -pv_db_pv_difficulty* task_pv_db_get_pv_difficulty(int32_t pv_id, +const pv_db_pv_difficulty* task_pv_db_get_pv_difficulty(int32_t pv_id, int32_t difficulty, int32_t edition) { pv_db_pv* pv = task_pv_db_get_pv(pv_id); - if (!pv) - return 0; - - return pv->get_difficulty(difficulty, edition); + if (pv) + return pv->get_difficulty(difficulty, edition); + return 0; } bool task_pv_db_is_paths_empty() { diff --git a/src/CRE/pv_db.hpp b/src/CRE/pv_db.hpp index feba20ee..f0b17f71 100644 --- a/src/CRE/pv_db.hpp +++ b/src/CRE/pv_db.hpp @@ -120,7 +120,7 @@ struct pv_db_pv_sabi { struct pv_db_pv_performer { pv_performer_type type; - int32_t chara; + chara_index chara; int32_t costume; int32_t pv_costume[PV_DIFFICULTY_MAX]; bool fixed; @@ -288,6 +288,7 @@ struct pv_db_pv_difficulty { pv_db_pv_field_parent field; std::vector pv_item; std::vector hand_item; + prj::vector_pair> field_228[3]; std::vector edit_effect; pv_db_pv_title_image title_image; pv_db_pv_songinfo songinfo; @@ -305,6 +306,7 @@ struct pv_db_pv_difficulty { pv_db_pv_difficulty(); ~pv_db_pv_difficulty(); + const pv_db_pv_motion& get_motion_or_default(int32_t chara_id, int32_t index) const; void reset(); }; @@ -317,7 +319,7 @@ struct pv_db_pv_ex_song_ex_auth { }; struct pv_db_pv_ex_song { - int32_t chara[ROB_CHARA_COUNT]; + chara_index chara[ROB_CHARA_COUNT]; std::string file; std::string name; std::vector ex_auth; @@ -490,9 +492,25 @@ struct pv_db_pv { pv_db_pv(); ~pv_db_pv(); - pv_db_pv_difficulty* get_difficulty(int32_t difficulty, pv_attribute_type attribute_type); - pv_db_pv_difficulty* get_difficulty(int32_t difficulty, int32_t edition); + int32_t get_chrmot_motion_id(int32_t chara_id, + chara_index chara_index, const pv_db_pv_motion& motion) const; + const pv_db_pv_difficulty* get_difficulty(int32_t difficulty, pv_attribute_type attribute_type) const; + const pv_db_pv_difficulty* get_difficulty(int32_t difficulty, int32_t edition) const; + chara_index get_performer_chara(int32_t performer) const; + int32_t get_performer_costume(int32_t performer) const; + size_t get_performer_count() const; + int32_t get_performer_exclude(int32_t performer) const; + bool get_performer_fixed(int32_t performer) const; + int32_t get_performer_item(int32_t performer, pv_performer_item item) const; + bool get_performer_pseudo_fixed(chara_index chara_index, int32_t performer, bool a4, bool a5) const; + int32_t get_performer_pseudo_same_id(int32_t performer) const; + pv_performer_size get_performer_size(int32_t performer) const; + pv_performer_type get_performer_type(int32_t performer) const; + bool is_performer_type_pseudo(int32_t performer) const; + bool is_performer_type_vocal(int32_t performer) const; void reset(); + + static int32_t get_pseudo_costume(pv_performer_type type, chara_index chara_index, int32_t costume); }; namespace pv_db { @@ -527,6 +545,9 @@ namespace pv_db { }; } +extern item_id pv_performer_item_to_item_id(pv_performer_item item); +extern item_sub_id pv_performer_item_to_item_sub_id(pv_performer_item item); + extern void task_pv_db_init(); extern void task_pv_db_add_paths(); extern bool task_pv_db_add_task(); @@ -535,9 +556,9 @@ extern bool task_pv_db_del_task(); extern pv_db::TaskPvDB* task_pv_db_get(); extern uint32_t task_pv_db_get_paths_count(); extern pv_db_pv* task_pv_db_get_pv(int32_t pv_id); -extern pv_db_pv_difficulty* task_pv_db_get_pv_difficulty(int32_t pv_id, +extern const pv_db_pv_difficulty* task_pv_db_get_pv_difficulty(int32_t pv_id, int32_t difficulty, pv_attribute_type attribute_type); -extern pv_db_pv_difficulty* task_pv_db_get_pv_difficulty(int32_t pv_id, +extern const pv_db_pv_difficulty* task_pv_db_get_pv_difficulty(int32_t pv_id, int32_t difficulty, int32_t edition); extern bool task_pv_db_is_paths_empty(); extern void task_pv_db_free(); diff --git a/src/CRE/pv_expression.cpp b/src/CRE/pv_expression.cpp index 07c69688..7eedba1c 100644 --- a/src/CRE/pv_expression.cpp +++ b/src/CRE/pv_expression.cpp @@ -118,8 +118,14 @@ bool pv_expression_array_set_motion(uint32_t hash, size_t chara_id, int32_t moti return false; } -bool pv_expression_file_check_not_ready(const char* file) { - uint32_t hash = hash_utf8_murmurhash(file); +bool pv_expression_file_check_not_ready(const char* path) { + if (!path || !*path) + return false; + + const char* file = strrchr(path, '/'); + if (!file) + file = strrchr(path, '\\'); + uint32_t hash = hash_utf8_murmurhash(file ? file : path); for (pv_expression_file*& i : pv_expression_file_storage) if (i && i->hash == hash) return i->file_handler.check_not_ready(); @@ -133,8 +139,15 @@ bool pv_expression_file_check_not_ready(uint32_t hash) { return true; } -void pv_expression_file_load(void* data, const char* path, const char* file) { - uint32_t hash = hash_utf8_murmurhash(file); +void pv_expression_file_load(void* data, const char* path) { + if (!path || !*path) + return; + + const char* file = strrchr(path, '/'); + if (!file) + file = strrchr(path, '\\'); + + uint32_t hash = hash_utf8_murmurhash(file ? file : path); for (pv_expression_file*& i : pv_expression_file_storage) if (i && i->hash == hash) { i->load_count++; @@ -142,7 +155,7 @@ void pv_expression_file_load(void* data, const char* path, const char* file) { } pv_expression_file* pv_exp_file = new pv_expression_file; - if (pv_exp_file->file_handler.read_file(data, path, file)) { + if (pv_exp_file->file_handler.read_file(data, path)) { pv_exp_file->data = new pv_exp; pv_exp_file->data->modern = false; @@ -178,8 +191,15 @@ void pv_expression_file_load(void* data, const char* path, uint32_t hash) { pv_expression_file_storage.push_back(pv_exp_file); } -void pv_expression_file_unload(const char* file) { - uint32_t hash = hash_utf8_murmurhash(file); +void pv_expression_file_unload(const char* path) { + if (!path || !*path) + return; + + const char* file = strrchr(path, '/'); + if (!file) + file = strrchr(path, '\\'); + + uint32_t hash = hash_utf8_murmurhash(file ? file : path); for (pv_expression_file*& i : pv_expression_file_storage) { if (!i || i->hash != hash) continue; diff --git a/src/CRE/pv_expression.hpp b/src/CRE/pv_expression.hpp index 85231688..eff10bb3 100644 --- a/src/CRE/pv_expression.hpp +++ b/src/CRE/pv_expression.hpp @@ -16,11 +16,11 @@ extern void pv_expression_array_reset_motion(size_t chara_id); extern bool pv_expression_array_set_motion(const char* file, size_t chara_id, int32_t motion_id); extern bool pv_expression_array_set_motion(uint32_t hash, size_t chara_id, int32_t motion_id); -extern bool pv_expression_file_check_not_ready(const char* file); +extern bool pv_expression_file_check_not_ready(const char* path); extern bool pv_expression_file_check_not_ready(uint32_t hash); -extern void pv_expression_file_load(void* data, const char* path, const char* file); +extern void pv_expression_file_load(void* data, const char* path); extern void pv_expression_file_load(void* data, const char* path, uint32_t hash); -extern void pv_expression_file_unload(const char* file); +extern void pv_expression_file_unload(const char* path); extern void pv_expression_file_unload(uint32_t hash); extern void pv_expression_file_storage_init(); diff --git a/src/CRE/pv_param.cpp b/src/CRE/pv_param.cpp index 56f4c489..1d274012 100644 --- a/src/CRE/pv_param.cpp +++ b/src/CRE/pv_param.cpp @@ -12,11 +12,69 @@ extern render_context* rctx_ptr; namespace pv_param { - static bool load_text_file(void* data, const char* path, const char* file, uint32_t hash); + struct file_data_struct { + std::vector dof_default; + std::vector cc_default; + std::vector bloom_default; + std::map> dof; + std::map> cc; + std::map> bloom; + + file_data_struct(); + ~file_data_struct(); + + std::vector& get_bloom_data(std::string& file); + std::vector& get_color_correction_data(std::string& file); + std::vector& get_dof_data(std::string& file); + bool load_bloom_file(std::string& file); + bool load_color_correction_file(std::string& file); + bool load_dof_file(std::string& file); + void unload_bloom_file(std::string& file); + void unload_color_correction_file(std::string& file); + void unload_dof_file(std::string& file); + }; + + struct light_data_struct { + light_param_light_data light_default; + std::string chara_light_file; + std::string stage_light_file; + std::map chara_light; + std::map stage_light; + + light_data_struct(); + ~light_data_struct(); + + void clear_data(); + bool load_file(std::string& file, std::map& map); + bool load_files(std::string& path); + }; + + struct post_process_data_struct { + dof dof_default; + color_correction cc_default; + bloom bloom_default; + std::string dof_file; + std::string cc_file; + std::string bloom_file; + std::vector dof; + std::vector cc; + std::vector bloom; + + post_process_data_struct(); + ~post_process_data_struct(); + + void clear_data(); + bool load_files(std::string& path); + void set_dof(::dof& d); + }; file_data_struct file_data; + light_data_struct light_data; post_process_data_struct post_process_data; + static char* get_next_item(char*& str); + static bool load_text_file(void* data, const char* path, const char* file, uint32_t hash); + bloom::bloom() { id = -1; color = 0.0f; @@ -52,6 +110,100 @@ namespace pv_param { contrast = 1.0f; } + void light_data_clear_data() { + light_data.clear_data(); + } + + light_param_light_data& light_data_get_chara_light_data(int32_t id) { + auto elem = light_data.chara_light.find(id); + if (elem != light_data.chara_light.end()) + return elem->second; + + return light_data.light_default; + } + + light_param_light_data& light_data_get_stage_light_data(int32_t id) { + auto elem = light_data.stage_light.find(id); + if (elem != light_data.stage_light.end()) + return elem->second; + + return light_data.light_default; + } + + bool light_data_load_files(int32_t pv_id, std::string&& mdata_dir) { + char buf[0x100]; + sprintf_s(buf, sizeof(buf), "pv%03d", pv_id); + + std::string path; + path.assign("rom/pv_param/"); + path.append(buf); + + if (mdata_dir.size()) { + std::string temp_path; + temp_path.assign(mdata_dir); + temp_path.append(path); + if (data_list[DATA_AFT].check_directory_exists(temp_path.c_str())) + path.assign(temp_path); + } + + if (data_list[DATA_AFT].check_directory_exists(path.c_str())) + return light_data.load_files(path); + return false; + } + + void post_process_data_clear_data() { + post_process_data.clear_data(); + } + + pv_param::bloom& post_process_data_get_bloom_data(int32_t id) { + for (pv_param::bloom& i : post_process_data.bloom) + if (i.id == id) + return i; + + return post_process_data.bloom_default; + } + + pv_param::color_correction& post_process_data_get_color_correction_data(int32_t id) { + for (pv_param::color_correction& i : post_process_data.cc) + if (i.id == id) + return i; + + return post_process_data.cc_default; + } + + pv_param::dof& post_process_data_get_dof_data(int32_t id) { + for (pv_param::dof& i : post_process_data.dof) + if (i.id == id) + return i; + + return post_process_data.dof_default; + } + + bool post_process_data_load_files(int32_t pv_id, std::string&& mdata_dir) { + char buf[0x100]; + sprintf_s(buf, sizeof(buf), "pv%03d", pv_id); + + std::string path; + path.assign("rom/pv_param/"); + path.append(buf); + + if (mdata_dir.size()) { + std::string temp_path; + temp_path.assign(mdata_dir); + temp_path.append(path); + if (data_list[DATA_AFT].check_directory_exists(temp_path.c_str())) + path.assign(temp_path); + } + + if (data_list[DATA_AFT].check_directory_exists(path.c_str())) + return post_process_data.load_files(path); + return false; + } + + void post_process_data_set_dof(::dof& d) { + post_process_data.set_dof(d); + } + file_data_struct::file_data_struct() { } @@ -104,8 +256,7 @@ namespace pv_param { if (!str_utils_text_file_parse(data.c_str(), data.size(), buf, lines, count)) return false; - if (count <= 1 || str_utils_compare(lines[0], - "ID,ColorR,ColorG,ColorB,BrightpassR,BrightpassG,BrightpassB,Range")) { + if (count <= 1 || str_utils_compare(get_next_item(lines[0]), "ID")) { free_def(buf); free_def(lines); return false; @@ -119,10 +270,15 @@ namespace pv_param { for (size_t i = 0; i < count; i++) { pv_param::bloom bloom_data; - if (sscanf_s(lines[i], "%d,%g,%g,%g,%g,%g,%g,%g", - &bloom_data.id, &bloom_data.color.x, &bloom_data.color.y, &bloom_data.color.z, - &bloom_data.brightpass.x, &bloom_data.brightpass.y, &bloom_data.brightpass.z, &bloom_data.range) == 8) - bloom.push_back(bloom_data); + bloom_data.id = atoi(get_next_item(lines[i])); + bloom_data.color.x = (float_t)atof(get_next_item(lines[i])); + bloom_data.color.y = (float_t)atof(get_next_item(lines[i])); + bloom_data.color.z = (float_t)atof(get_next_item(lines[i])); + bloom_data.brightpass.x = (float_t)atof(get_next_item(lines[i])); + bloom_data.brightpass.y = (float_t)atof(get_next_item(lines[i])); + bloom_data.brightpass.z = (float_t)atof(get_next_item(lines[i])); + bloom_data.range = (float_t)atof(get_next_item(lines[i])); + bloom.push_back(bloom_data); } this->bloom.insert_or_assign(file, bloom); @@ -145,8 +301,7 @@ namespace pv_param { if (!str_utils_text_file_parse(data.c_str(), data.size(), buf, lines, count)) return false; - if (count <= 1 || str_utils_compare(lines[0], - "ID,Hue,Saturation,Lightness,Exposure,GammaR,GammaG,GammaB,Contrast")) { + if (count <= 1 || str_utils_compare(get_next_item(lines[0]), "ID")) { free_def(buf); free_def(lines); return false; @@ -160,10 +315,16 @@ namespace pv_param { for (size_t i = 0; i < count; i++) { pv_param::color_correction cc_data; - if (sscanf_s(lines[i], "%d,%g,%g,%g,%g,%g,%g,%g,%g", - &cc_data.id, &cc_data.hue, &cc_data.saturation, &cc_data.lightness, - &cc_data.exposure, &cc_data.gamma.x, &cc_data.gamma.y, &cc_data.gamma.z, &cc_data.contrast) == 9) - cc.push_back(cc_data); + cc_data.id = atoi(get_next_item(lines[i])); + cc_data.hue = (float_t)atof(get_next_item(lines[i])); + cc_data.saturation = (float_t)atof(get_next_item(lines[i])); + cc_data.lightness = (float_t)atof(get_next_item(lines[i])); + cc_data.exposure = (float_t)atof(get_next_item(lines[i])); + cc_data.gamma.x = (float_t)atof(get_next_item(lines[i])); + cc_data.gamma.y = (float_t)atof(get_next_item(lines[i])); + cc_data.gamma.z = (float_t)atof(get_next_item(lines[i])); + cc_data.contrast = (float_t)atof(get_next_item(lines[i])); + cc.push_back(cc_data); } this->cc.insert_or_assign(file, cc); @@ -186,8 +347,7 @@ namespace pv_param { if (!str_utils_text_file_parse(data.c_str(), data.size(), buf, lines, count)) return false; - if (count <= 1 || str_utils_compare(lines[0], - "ID,Focus,FocusRange,FuzzingRange,Ratio,Quality")) { + if (count <= 1 || str_utils_compare(get_next_item(lines[0]), "ID")) { free_def(buf); free_def(lines); return false; @@ -201,10 +361,13 @@ namespace pv_param { for (size_t i = 0; i < count; i++) { pv_param::dof dof_data; - if (sscanf_s(lines[i], "%d,%g,%g,%g,%g,%g", - &dof_data.id, &dof_data.focus, &dof_data.focus_range, - &dof_data.fuzzing_range, &dof_data.ratio, &dof_data.quality) == 6) - dof.push_back(dof_data); + dof_data.id = atoi(get_next_item(lines[i])); + dof_data.focus = (float_t)atof(get_next_item(lines[i])); + dof_data.focus_range = (float_t)atof(get_next_item(lines[i])); + dof_data.fuzzing_range = (float_t)atof(get_next_item(lines[i])); + dof_data.ratio = (float_t)atof(get_next_item(lines[i])); + dof_data.quality = (float_t)atof(get_next_item(lines[i])); + dof.push_back(dof_data); } this->dof.insert_or_assign(file, dof); @@ -242,6 +405,138 @@ namespace pv_param { } + void light_data_struct::clear_data() { + chara_light_file.clear(); + stage_light_file.clear(); + chara_light.clear(); + stage_light.clear(); + } + + bool light_data_struct::load_file(std::string& file, std::map& map) { + std::string data; + if (!data_list[DATA_AFT].load_file(&data, file.c_str(), load_text_file)) + return false; + + char* buf; + char** lines; + size_t count; + if (!str_utils_text_file_parse(data.c_str(), data.size(), buf, lines, count)) + return false; + + if (count <= 1 || str_utils_compare(get_next_item(lines[0]), "Type")) { + free_def(buf); + free_def(lines); + return false; + } + + lines++; + count--; + + for (size_t i = 0; i < count; i++) { + light_param_light_data light; + + char* str = get_next_item(lines[i]); + if (!str_utils_compare(str, "PARALLEL")) + light.type = LIGHT_PARALLEL; + else if (!str_utils_compare(str, "POINT")) + light.type = LIGHT_POINT; + else if (!str_utils_compare(str, "SPOT")) + light.type = LIGHT_SPOT; + else + light.type = LIGHT_OFF; + light.has_type = true; + + if (sscanf_s(get_next_item(lines[i]), "%g", &light.ambient.x) == 1) + light.has_ambient = true; + + if (sscanf_s(get_next_item(lines[i]), "%g", &light.ambient.y) == 1) + light.has_ambient = true; + + if (sscanf_s(get_next_item(lines[i]), "%g", &light.ambient.z) == 1) + light.has_ambient = true; + + light.ambient.w = 1.0f; + + if (sscanf_s(get_next_item(lines[i]), "%g", &light.diffuse.x) == 1) + light.has_diffuse = true; + + if (sscanf_s(get_next_item(lines[i]), "%g", &light.diffuse.y) == 1) + light.has_diffuse = true; + + if (sscanf_s(get_next_item(lines[i]), "%g", &light.diffuse.z) == 1) + light.has_diffuse = true; + + light.diffuse.w = 1.0f; + + if (sscanf_s(get_next_item(lines[i]), "%g", &light.specular.x) == 1) + light.has_specular = true; + + if (sscanf_s(get_next_item(lines[i]), "%g", &light.specular.y) == 1) + light.has_specular = true; + + if (sscanf_s(get_next_item(lines[i]), "%g", &light.specular.z) == 1) + light.has_specular = true; + + if (sscanf_s(get_next_item(lines[i]), "%g", &light.specular.w) == 1) + light.has_specular = true; + + if (sscanf_s(get_next_item(lines[i]), "%g", &light.position.x) == 1) + light.has_position = true; + + if (sscanf_s(get_next_item(lines[i]), "%g", &light.position.y) == 1) + light.has_position = true; + + if (sscanf_s(get_next_item(lines[i]), "%g", &light.position.z) == 1) + light.has_position = true; + + if (sscanf_s(get_next_item(lines[i]), "%g", &light.tone_curve.start_point) == 1) + light.has_tone_curve = true; + + if (sscanf_s(get_next_item(lines[i]), "%g", &light.tone_curve.end_point) == 1) + light.has_tone_curve = true; + + if (sscanf_s(get_next_item(lines[i]), "%g", &light.tone_curve.coefficient) == 1) + light.has_tone_curve = true; + + int32_t id; + if (sscanf_s(get_next_item(lines[i]), "%d", &id) != 1) + id = -1; + + map.insert_or_assign(id, light); + } + + lines--; + + free_def(buf); + free_def(lines); + return true; + } + + bool light_data_struct::load_files(std::string& path) { + data_struct* aft_data = &data_list[DATA_AFT]; + + if (!aft_data->check_directory_exists(path.c_str())) + return true; + + if (aft_data->check_file_exists(path.c_str(), "/chara_light.txt")) { + chara_light_file.assign(path); + chara_light_file.append("/chara_light.txt"); + } + else + chara_light_file.clear(); + + if (aft_data->check_file_exists(path.c_str(), "/stage_light.txt")) { + stage_light_file.assign(path); + stage_light_file.append("/stage_light.txt"); + } + else + stage_light_file.clear(); + + load_file(chara_light_file, chara_light); + load_file(stage_light_file, stage_light); + return true; + } + post_process_data_struct::post_process_data_struct() { } @@ -282,23 +577,23 @@ namespace pv_param { if (!aft_data->check_directory_exists(path.c_str())) return false; - if (aft_data->check_file_exists(path.c_str(), "dof.txt")) { + if (aft_data->check_file_exists(path.c_str(), "/dof.txt")) { dof_file.assign(path); - dof_file.append("dof.txt"); + dof_file.append("/dof.txt"); } else dof_file.clear(); - if (aft_data->check_file_exists(path.c_str(), "cc.txt")) { - dof_file.assign(path); - dof_file.append("cc.txt"); + if (aft_data->check_file_exists(path.c_str(), "/cc.txt")) { + cc_file.assign(path); + cc_file.append("/cc.txt"); } else cc_file.clear(); - if (aft_data->check_file_exists(path.c_str(), "bloom.txt")) { - dof_file.assign(path); - dof_file.append("bloom.txt"); + if (aft_data->check_file_exists(path.c_str(), "/bloom.txt")) { + bloom_file.assign(path); + bloom_file.append("/bloom.txt"); } else bloom_file.clear(); @@ -346,70 +641,16 @@ namespace pv_param { } } - void post_process_data_clear_data() { - post_process_data.clear_data(); - } - - pv_param::bloom& post_process_data_get_bloom_data(int32_t id) { - for (pv_param::bloom& i : post_process_data.bloom) - if (i.id == id) - return i; - - return post_process_data.bloom_default; - } - - pv_param::color_correction& post_process_data_get_color_correction_data(int32_t id) { - for (pv_param::color_correction& i : post_process_data.cc) - if (i.id == id) - return i; - - return post_process_data.cc_default; - } - - pv_param::dof& post_process_data_get_dof_data(int32_t id) { - for (pv_param::dof& i : post_process_data.dof) - if (i.id == id) - return i; - - return post_process_data.dof_default; - } - - bool post_process_data_load_files(int32_t pv_id) { - char buf[0x100]; - sprintf_s(buf, sizeof(buf), "pv%03d/", pv_id); - - std::string path; - path.assign("rom/pv_param/"); - path.append(buf); - - if (data_list[DATA_AFT].check_directory_exists(path.c_str())) - return post_process_data.load_files(path); - return false; - } - - bool post_process_data_load_files(int32_t pv_id, std::string& mdata_dir) { - char buf[0x100]; - sprintf_s(buf, sizeof(buf), "pv%03d/", pv_id); - - std::string path; - path.assign("rom/pv_param/"); - path.append(buf); - - if (mdata_dir.size()) { - std::string temp_path; - temp_path.assign(mdata_dir); - temp_path.append(path); - if (data_list[DATA_AFT].check_directory_exists(temp_path.c_str())) - path.assign(temp_path); - } - - if (data_list[DATA_AFT].check_directory_exists(path.c_str())) - return post_process_data.load_files(path); - return false; - } - - void post_process_data_set_dof(::dof& d) { - post_process_data.set_dof(d); + static char* get_next_item(char*& str) { + char* orig_str = str; + while (*str) + if (*str == ',') { + *str++ = 0; + break; + } + else + str++; + return orig_str; } static bool load_text_file(void* data, const char* path, const char* file, uint32_t hash) { @@ -429,8 +670,171 @@ namespace pv_param { } namespace pv_param_task { + class PostProcessCtrl { + public: + float_t frame; + float_t duration; + + PostProcessCtrl(); + ~PostProcessCtrl(); + + virtual void Reset() = 0; + virtual void Set() = 0; + }; + + class PostProcessCtrlBloom : public PostProcessCtrl { + public: + struct Data { + pv_param::bloom data; + pv_param::bloom data_prev; + + Data(); + } data; + + PostProcessCtrlBloom(); + ~PostProcessCtrlBloom(); + + virtual void Reset() override; + virtual void Set() override; + }; + + class PostProcessCtrlCC : public PostProcessCtrl { + public: + struct Data { + pv_param::color_correction data; + pv_param::color_correction data_prev; + + Data(); + } data; + + PostProcessCtrlCC(); + ~PostProcessCtrlCC(); + + virtual void Reset() override; + virtual void Set() override; + + void CalcToneTrans(float_t value, float_t& tone_trans_start, float_t& tone_trans_end); + }; + + class PostProcessCtrlCharaAlpha : public PostProcessCtrl { + public: + struct Data { + pv_param::chara_alpha data[ROB_CHARA_COUNT]; + + Data(); + } data; + + PostProcessCtrlCharaAlpha(); + ~PostProcessCtrlCharaAlpha(); + + virtual void Reset() override; + virtual void Set() override; + }; + + class PostProcessCtrlCharaItemAlpha : public PostProcessCtrlCharaAlpha { + public: + post_process_task_set_chara_item_alpha_callback callback[ROB_CHARA_COUNT]; + void* callback_data[ROB_CHARA_COUNT]; + + PostProcessCtrlCharaItemAlpha(); + ~PostProcessCtrlCharaItemAlpha(); + + virtual void Reset() override; + virtual void Set() override; + }; + + class PostProcessCtrlDof : public PostProcessCtrl { + public: + struct Data { + pv_param::dof data; + pv_param::dof data_prev; + + Data(); + } data; + + PostProcessCtrlDof(); + ~PostProcessCtrlDof(); + + virtual void Reset() override; + virtual void Set() override; + + void SetData(pv_param::dof* dof, float_t duration); + }; + + class PostProcessTask : public app::Task { + public: + PostProcessCtrlDof dof; + PostProcessCtrlCC cc; + PostProcessCtrlBloom bloom; + PostProcessCtrlCharaAlpha chara_alpha; + PostProcessCtrlCharaItemAlpha chara_item_alpha; + + PostProcessTask(); + virtual ~PostProcessTask() override; + + virtual bool Init() override; + virtual bool Ctrl() override; + virtual bool Dest() override; + }; + PostProcessTask post_process_task; + bool post_process_task_add_task() { + return app::TaskWork::AddTask(&post_process_task, "PV POST PROCESS TASK"); + } + + void post_process_task_set_bloom_data( + pv_param::bloom& data, float_t duration) { + PostProcessCtrlBloom& bloom = post_process_task.bloom; + bloom.frame = 0.0f; + bloom.duration = duration; + bloom.data.data = data; + } + + void post_process_task_set_color_correction_data( + pv_param::color_correction& data, float_t duration) { + PostProcessCtrlCC& cc = post_process_task.cc; + cc.frame = 0.0f; + cc.duration = duration; + cc.data.data = data; + } + + void post_process_task_set_dof_data( + pv_param::dof& data, float_t duration) { + PostProcessCtrlDof& dof = post_process_task.dof; + dof.frame = 0.0f; + dof.duration = duration; + dof.data.data = data; + } + + void post_process_task_set_chara_alpha( + int32_t chara_id, int32_t type, float_t alpha, float_t duration) { + PostProcessCtrlCharaAlpha& chara_alpha = post_process_task.chara_alpha; + pv_param::chara_alpha& chara_alpha_data = chara_alpha.data.data[chara_id]; + chara_alpha_data.type = type; + chara_alpha_data.frame = 0.0f; + chara_alpha_data.alpha = alpha; + chara_alpha_data.duration = duration; + } + + void post_process_task_set_chara_item_alpha( + int32_t chara_id, int32_t type, float_t alpha, float_t duration, + post_process_task_set_chara_item_alpha_callback callback, void* callback_data) { + PostProcessCtrlCharaItemAlpha& chara_item_alpha = post_process_task.chara_item_alpha; + pv_param::chara_alpha& chara_item_alpha_data = chara_item_alpha.data.data[chara_id]; + chara_item_alpha_data.type = type; + chara_item_alpha_data.frame = 0.0f; + chara_item_alpha_data.alpha = alpha; + chara_item_alpha_data.duration = duration; + + chara_item_alpha.callback[chara_id] = callback; + chara_item_alpha.callback_data[chara_id] = callback_data; + } + + bool post_process_task_del_task() { + return post_process_task.DelTask(); + } + PostProcessCtrl::PostProcessCtrl() { frame = -1.0f; duration = -1.0f; @@ -628,7 +1032,7 @@ namespace pv_param_task { for (pv_param::chara_alpha& i : data.data) i = {}; - for (PostProcessCtrlCharaItemAlpha::Callback& i : callback) + for (post_process_task_set_chara_item_alpha_callback& i : callback) i = 0; for (void*& i : callback_data) @@ -653,9 +1057,6 @@ namespace pv_param_task { if (callback) callback[index](callback_data[index], index, i.type, value); - /*pv_game* v5 = pv_game_data_get(); - if (v5) - sub_140115EC0(v5, index, i.type, value);*/ i.frame += get_delta_frame(); if (i.frame > i.duration) { @@ -881,60 +1282,4 @@ namespace pv_param_task { chara_item_alpha.Reset(); return true; } - - bool post_process_task_add_task() { - return app::TaskWork::AddTask(&post_process_task, "PV POST PROCESS TASK"); - } - - void post_process_task_set_bloom_data( - pv_param::bloom& data, float_t duration) { - PostProcessCtrlBloom& bloom = post_process_task.bloom; - bloom.frame = 0.0f; - bloom.duration = duration; - bloom.data.data = data; - } - - void post_process_task_set_color_correction_data( - pv_param::color_correction& data, float_t duration) { - PostProcessCtrlCC& cc = post_process_task.cc; - cc.frame = 0.0f; - cc.duration = duration; - cc.data.data = data; - } - - void post_process_task_set_dof_data( - pv_param::dof& data, float_t duration) { - PostProcessCtrlDof& dof = post_process_task.dof; - dof.frame = 0.0f; - dof.duration = duration; - dof.data.data = data; - } - - void post_process_task_set_chara_alpha( - int32_t chara_id, int32_t type, float_t alpha, float_t duration) { - PostProcessCtrlCharaAlpha& chara_alpha = post_process_task.chara_alpha; - pv_param::chara_alpha& chara_alpha_data = chara_alpha.data.data[chara_id]; - chara_alpha_data.type = type; - chara_alpha_data.frame = 0.0f; - chara_alpha_data.alpha = alpha; - chara_alpha_data.duration = duration; - } - - void post_process_task_set_chara_item_alpha( - int32_t chara_id, int32_t type, float_t alpha, float_t duration, - PostProcessCtrlCharaItemAlpha::Callback callback, void* callback_data) { - PostProcessCtrlCharaItemAlpha& chara_item_alpha = post_process_task.chara_item_alpha; - pv_param::chara_alpha& chara_item_alpha_data = chara_item_alpha.data.data[chara_id]; - chara_item_alpha_data.type = type; - chara_item_alpha_data.frame = 0.0f; - chara_item_alpha_data.alpha = alpha; - chara_item_alpha_data.duration = duration; - - chara_item_alpha.callback[chara_id] = callback; - chara_item_alpha.callback_data[chara_id] = callback_data; - } - - bool post_process_task_del_task() { - return post_process_task.DelTask(); - } } diff --git a/src/CRE/pv_param.hpp b/src/CRE/pv_param.hpp index dd7a3f7a..25165ab1 100644 --- a/src/CRE/pv_param.hpp +++ b/src/CRE/pv_param.hpp @@ -59,176 +59,22 @@ namespace pv_param { color_correction(); }; - struct file_data_struct { - std::vector dof_default; - std::vector cc_default; - std::vector bloom_default; - std::map> dof; - std::map> cc; - std::map> bloom; + extern void light_data_clear_data(); + extern light_param_light_data& light_data_get_chara_light_data(int32_t id); + extern light_param_light_data& light_data_get_stage_light_data(int32_t id); + extern bool light_data_load_files(int32_t pv_id, std::string&& mdata_dir); - file_data_struct(); - ~file_data_struct(); - - std::vector& get_bloom_data(std::string& file); - std::vector& get_color_correction_data(std::string& file); - std::vector& get_dof_data(std::string& file); - bool load_bloom_file(std::string& file); - bool load_color_correction_file(std::string& file); - bool load_dof_file(std::string& file); - void unload_bloom_file(std::string& file); - void unload_color_correction_file(std::string& file); - void unload_dof_file(std::string& file); - }; - - struct light_data_struct { - light_param_light_data light_default; - std::string chara_light_file; - std::string stage_light_file; - std::map chara_light; - std::map stage_light; - - light_data_struct(); - ~light_data_struct(); - }; - - struct post_process_data_struct { - dof dof_default; - color_correction cc_default; - bloom bloom_default; - std::string dof_file; - std::string cc_file; - std::string bloom_file; - std::vector dof; - std::vector cc; - std::vector bloom; - - post_process_data_struct(); - ~post_process_data_struct(); - - void clear_data(); - bool load_files(std::string& path); - void set_dof(::dof& d); - }; - - void post_process_data_clear_data(); - pv_param::bloom& post_process_data_get_bloom_data(int32_t id); - pv_param::color_correction& post_process_data_get_color_correction_data(int32_t id); - pv_param::dof& post_process_data_get_dof_data(int32_t id); - bool post_process_data_load_files(int32_t pv_id); - bool post_process_data_load_files(int32_t pv_id, std::string& mdata_dir); - void post_process_data_set_dof(::dof& d); + extern void post_process_data_clear_data(); + extern pv_param::bloom& post_process_data_get_bloom_data(int32_t id); + extern pv_param::color_correction& post_process_data_get_color_correction_data(int32_t id); + extern pv_param::dof& post_process_data_get_dof_data(int32_t id); + extern bool post_process_data_load_files(int32_t pv_id, std::string&& mdata_dir); + extern void post_process_data_set_dof(::dof& d); } namespace pv_param_task { - class PostProcessCtrl { - public: - float_t frame; - float_t duration; - - PostProcessCtrl(); - ~PostProcessCtrl(); - - virtual void Reset() = 0; - virtual void Set() = 0; - }; - - class PostProcessCtrlBloom : public PostProcessCtrl { - public: - struct Data { - pv_param::bloom data; - pv_param::bloom data_prev; - - Data(); - } data; - - PostProcessCtrlBloom(); - ~PostProcessCtrlBloom(); - - virtual void Reset() override; - virtual void Set() override; - }; - - class PostProcessCtrlCC : public PostProcessCtrl { - public: - struct Data { - pv_param::color_correction data; - pv_param::color_correction data_prev; - - Data(); - } data; - - PostProcessCtrlCC(); - ~PostProcessCtrlCC(); - - virtual void Reset() override; - virtual void Set() override; - - void CalcToneTrans(float_t value, float_t& tone_trans_start, float_t& tone_trans_end); - }; - - class PostProcessCtrlCharaAlpha : public PostProcessCtrl { - public: - struct Data { - pv_param::chara_alpha data[ROB_CHARA_COUNT]; - - Data(); - } data; - - PostProcessCtrlCharaAlpha(); - ~PostProcessCtrlCharaAlpha(); - - virtual void Reset() override; - virtual void Set() override; - }; - - class PostProcessCtrlCharaItemAlpha : public PostProcessCtrlCharaAlpha { - public: - typedef void (*Callback)(void* data, int32_t chara_id, int32_t type, float_t alpha); - - Callback callback[ROB_CHARA_COUNT]; - void* callback_data[ROB_CHARA_COUNT]; - - PostProcessCtrlCharaItemAlpha(); - ~PostProcessCtrlCharaItemAlpha(); - - virtual void Reset() override; - virtual void Set() override; - }; - - class PostProcessCtrlDof : public PostProcessCtrl { - public: - struct Data { - pv_param::dof data; - pv_param::dof data_prev; - - Data(); - } data; - - PostProcessCtrlDof(); - ~PostProcessCtrlDof(); - - virtual void Reset() override; - virtual void Set() override; - - void SetData(pv_param::dof* dof, float_t duration); - }; - - class PostProcessTask : public app::Task { - public: - PostProcessCtrlDof dof; - PostProcessCtrlCC cc; - PostProcessCtrlBloom bloom; - PostProcessCtrlCharaAlpha chara_alpha; - PostProcessCtrlCharaItemAlpha chara_item_alpha; - - PostProcessTask(); - virtual ~PostProcessTask() override; - - virtual bool Init() override; - virtual bool Ctrl() override; - virtual bool Dest() override; - }; + typedef void (*post_process_task_set_chara_item_alpha_callback) + (void* data, int32_t chara_id, int32_t type, float_t alpha); extern bool post_process_task_add_task(); extern void post_process_task_set_bloom_data( @@ -241,6 +87,6 @@ namespace pv_param_task { int32_t chara_id, int32_t type, float_t alpha, float_t duration); extern void post_process_task_set_chara_item_alpha( int32_t chara_id, int32_t type, float_t alpha, float_t duration, - PostProcessCtrlCharaItemAlpha::Callback callback, void* callback_data); + post_process_task_set_chara_item_alpha_callback callback, void* callback_data); extern bool post_process_task_del_task(); } diff --git a/src/CRE/render_context.cpp b/src/CRE/render_context.cpp index 0dcb63dd..25e9b2d3 100644 --- a/src/CRE/render_context.cpp +++ b/src/CRE/render_context.cpp @@ -207,7 +207,7 @@ namespace mdl { pos[0] = { 0.0f, 0.0f, 0.0f }; pos[1] = { 0.0f, 0.0f, 1.0f }; } - + EtcObjEllipse::EtcObjEllipse() : wire() { radius = 1.0f; slices = 8; @@ -1595,7 +1595,7 @@ namespace mdl { etc_vertex_array_cache.push_back({}); etc_vertex_array = &etc_vertex_array_cache.back(); } - + if (!etc_vertex_array->vertex_array) { glGenVertexArrays(1, &etc_vertex_array->vertex_array); diff --git a/src/CRE/render_context.hpp b/src/CRE/render_context.hpp index 69248cdd..c13c7f85 100644 --- a/src/CRE/render_context.hpp +++ b/src/CRE/render_context.hpp @@ -365,7 +365,7 @@ namespace mdl { EtcObjCapsule(); }; - + struct EtcObjEllipse { // Added float_t radius; int32_t slices; diff --git a/src/CRE/rob/ex_block.cpp b/src/CRE/rob/ex_block.cpp index d5c0f24b..b3731b9a 100644 --- a/src/CRE/rob/ex_block.cpp +++ b/src/CRE/rob/ex_block.cpp @@ -816,20 +816,20 @@ void CLOTH::Init() { } } -void CLOTH::SetSkinParamColiR(float_t coli_r) { - skin_param_ptr->coli_r = coli_r; +void CLOTH::SetSkinParamColiR(float_t value) { + skin_param_ptr->coli_r = value; } -void CLOTH::SetSkinParamFriction(float_t friction) { - skin_param_ptr->friction = friction; +void CLOTH::SetSkinParamFriction(float_t value) { + skin_param_ptr->friction = value; } -void CLOTH::SetSkinParamWindAfc(float_t wind_afc) { - skin_param_ptr->wind_afc = wind_afc; +void CLOTH::SetSkinParamWindAfc(float_t value) { + skin_param_ptr->wind_afc = value; } -void CLOTH::SetWindDirection(vec3& wind_direction) { - this->wind_direction = wind_direction; +void CLOTH::SetWindDirection(vec3& value) { + this->wind_direction = value; } void CLOTH::Field_30(float_t a2) { @@ -1487,7 +1487,7 @@ void ExClothBlock::Field_20() { ColiSet(); rob_chara_item_equip* rob_itm_equip = item_equip_object->item_equip; - float_t step = get_delta_frame() * rob_itm_equip->step; + float_t step = get_delta_frame() * rob_itm_equip->osage_step; if (rob_itm_equip->opd_blend_data.size() && rob_itm_equip->opd_blend_data[0].field_C) step = 1.0f; sub_140218560(&rob, step, false); @@ -2062,7 +2062,7 @@ void ExOsageBlock::Field_10() { void ExOsageBlock::Field_18(int32_t stage, bool disable_external_force) { rob_chara_item_equip* rob_itm_equip = item_equip_object->item_equip; - float_t step = get_delta_frame() * rob_itm_equip->step; + float_t step = get_delta_frame() * rob_itm_equip->osage_step; if (rob_itm_equip->opd_blend_data.size() && rob_itm_equip->opd_blend_data[0].field_C) step = 1.0f; @@ -2103,7 +2103,7 @@ void ExOsageBlock::Field_20() { } rob_chara_item_equip* rob_itm_equip = item_equip_object->item_equip; - float_t step = get_delta_frame() * rob_itm_equip->step; + float_t step = get_delta_frame() * rob_itm_equip->osage_step; if (rob_itm_equip->opd_blend_data.size() && rob_itm_equip->opd_blend_data[0].field_C) step = 1.0f; @@ -2596,7 +2596,7 @@ void ExExpressionBlock::Field_50() { void ExExpressionBlock::Calc() { float_t delta_frame = get_delta_frame(); if (step) - delta_frame *= item_equip_object->item_equip->step; + delta_frame *= item_equip_object->item_equip->osage_step; float_t frame = this->frame + delta_frame; this->frame = frame >= 65535.0f ? frame - 65535.0f : frame; diff --git a/src/CRE/rob/rob.cpp b/src/CRE/rob/rob.cpp index 75e17948..5c1db043 100644 --- a/src/CRE/rob/rob.cpp +++ b/src/CRE/rob/rob.cpp @@ -134,6 +134,7 @@ struct osage_play_data_header { struct osage_play_data_node_header { uint16_t count; int16_t shift; +#pragma warning(suppress: 4200) int16_t data[]; }; @@ -159,9 +160,9 @@ public: virtual bool Ctrl() override; virtual bool Dest() override; virtual void Disp() override; - + bool AddTask(); - void AppendCharaMotionId(rob_chara* rob_chr, std::vector& motion_ids); + void AppendCharaMotionId(rob_chara* rob_chr, const std::vector& motion_ids); bool CheckTaskReady(); void GetOpdFileData(object_info obj_info, uint32_t motion_id, float_t*& data, uint32_t& count); @@ -523,7 +524,7 @@ public: void SetDisp(bool value); void SetNotReset(bool value); void SetPvId(int32_t pv_id, int32_t chara_id, bool reset); - void SetPvSetMotion(std::vector& set_motion); + void SetPvSetMotion(const std::vector& set_motion); void sub_1404F77E0(); bool sub_1404F7AF0(); @@ -1124,7 +1125,7 @@ static void rob_chara_load_default_motion_sub(rob_chara* rob_chr, int32_t skelet static void rob_chara_set_adjust(rob_chara* rob_chr, rob_chara_data_adjust* adjust_new, rob_chara_data_adjust* adjust, rob_chara_data_adjust* adjust_prev); static void rob_chara_set_pv_data(rob_chara* rob_chr, int8_t chara_id, - chara_index chara_index, int32_t module_index, rob_chara_pv_data* pv_data); + chara_index chara_index, int32_t module_index, const rob_chara_pv_data& pv_data); static void rob_cmn_mottbl_read(void* a1, const void* data, size_t size); @@ -2225,6 +2226,20 @@ int32_t chara_init_data_get_chara_size_index(chara_index chara_index) { return 1; } +int32_t chara_init_data_get_swim_costume(chara_index chara_index) { + const chara_init_data* chara_init_data = chara_init_data_get(chara_index); + if (chara_init_data) + return chara_init_data->field_848.swim_costume; + return 0; +} + +int32_t chara_init_data_get_swim_s_costume(chara_index chara_index) { + const chara_init_data* chara_init_data = chara_init_data_get(chara_index); + if (chara_init_data) + return chara_init_data->field_848.swim_s_costume; + return 0; +} + float_t chara_size_table_get_value(uint32_t index) { static const float_t chara_size_table[] = { 1.07f, 1.0f, 0.96f, 0.987f, 1.025f, 1.045f @@ -2251,6 +2266,14 @@ bool check_module_index_is_501(int32_t module_index) { return module_index == 501; } +const uint32_t* get_opd_motion_set_ids() { + static const uint32_t opd_motion_set_ids[] = { + 51, 194, 797, (uint32_t)-1, + }; + + return opd_motion_set_ids; +} + const float_t get_osage_gravity_const() { return 0.00299444468691945f; } @@ -2291,12 +2314,17 @@ bool osage_play_data_manager_add_task() { return osage_play_data_manager->AddTask(); } -void osage_play_data_manager_append_chara_motion_id(rob_chara* rob_chr, int32_t motion_id) { +void osage_play_data_manager_append_chara_motion_id(rob_chara* rob_chr, uint32_t motion_id) { std::vector motion_ids; motion_ids.push_back(motion_id); osage_play_data_manager->AppendCharaMotionId(rob_chr, motion_ids); } +void osage_play_data_manager_append_chara_motion_ids( + rob_chara* rob_chr, const std::vector& motion_ids) { + osage_play_data_manager->AppendCharaMotionId(rob_chr, motion_ids); +} + bool osage_play_data_manager_check_task_ready() { return osage_play_data_manager->CheckTaskReady(); } @@ -2404,7 +2432,7 @@ void rob_free() { delete osage_play_data_manager; osage_play_data_manager = 0; } - + if (opd_maker_array) { delete[] opd_maker_array; opd_maker_array = 0; @@ -2570,6 +2598,12 @@ mat4* rob_chara::get_bone_data_mat(size_t index) { return rob_chara_bone_data_get_mat(bone_data, index); } +object_info rob_chara::get_chara_init_data_face_object(int32_t index) { + if (index >= 0 && index < 15) + return chara_init_data->face_objects[index]; + return {}; +} + float_t rob_chara::get_frame() { return bone_data->get_frame(); } @@ -2644,10 +2678,6 @@ static void rob_chara_bone_data_set_motion_arm_length(rob_chara_bone_data* rob_b v3->bone_data.bones.data()[motion_bone_index].arm_length = value; } -static void rob_chara_bone_data_set_disable_eye_motion(rob_chara_bone_data* rob_bone_data, bool value) { - rob_bone_data->disable_eye_motion = value; -} - static void sub_1405F9520(rob_chara_item_equip_object* itm_eq_obj, rob_osage_parts_bit a2, bool a3) { for (ExOsageBlock*& i : itm_eq_obj->osage_blocks) if (i->rob.CheckPartsBits(a2)) @@ -2823,10 +2853,10 @@ static void sub_140555B00(rob_chara* rob_chr, bool a2) { if (v6) v9 = sub_14054FEE0(rob_chr); - float_t v12 = rob_chr->data.field_1588.field_0.field_8; + float_t v12 = rob_chr->data.field_1588.field_0.frame; float_t v13 = v12 - v9; if (v3 && v6 && (v13 < v11 || v13 <= v8)) { - float_t v14 = rob_chr->data.field_1588.field_0.field_8; + float_t v14 = rob_chr->data.field_1588.field_0.frame; v14 = (v12 - v8) * 0.5f; int32_t v15 = (int32_t)v14; if (v14 != -0.0f && (float_t)v15 != v14) @@ -2841,7 +2871,7 @@ static void sub_140555B00(rob_chara* rob_chr, bool a2) { v9 = v12 - v16; } else - v17 = rob_chr->data.field_1588.field_0.field_8 - v9; + v17 = rob_chr->data.field_1588.field_0.frame - v9; v10 = v17 - v8; } else { @@ -3044,9 +3074,9 @@ static void sub_14053A9C0(struc_223* a1, rob_chara* rob_chr, mothead_apply2(a1, rob_chr, v7->field_18.data()); if (a1->field_0.field_58 == 1) - a1->field_0.field_8 = frame_count - 1.0f; + a1->field_0.frame = frame_count - 1.0f; else - a1->field_0.field_8 = a1->field_0.frame_count; + a1->field_0.frame = a1->field_0.frame_count; if (a1->field_0.field_20.field_0 & 0x200000) a1->field_0.field_20.field_0 |= 0x100; @@ -3084,6 +3114,11 @@ static void sub_14053A9C0(struc_223* a1, rob_chara* rob_chr, } } +void rob_chara::load_body_parts_object_info(item_id item_id, object_info obj_info, + const bone_database* bone_data, void* data, const object_database* obj_db) { + item_equip->load_body_parts_object_info(item_id, obj_info, bone_data, data, obj_db); +} + void rob_chara::load_motion(int32_t motion_id, bool a3, float_t frame, MotionBlendType blend_type, const bone_database* bone_data, const motion_database* mot_db) { data.miku_rot.rot_y_int16 = sub_14054FE90(this, false); @@ -3130,7 +3165,7 @@ void rob_chara::load_motion(int32_t motion_id, bool a3, float_t frame, rob_chara_bone_data_set_motion_arm_length(this->bone_data, rob_motion_c_kata_bone_get(i), 0.0f); } - rob_chara_bone_data_set_disable_eye_motion(this->bone_data, false); + this->bone_data->set_disable_eye_motion(false); item_equip->set_osage_move_cancel(0, 0.0f); for (int32_t i = 0; i < ROB_OSAGE_PARTS_MAX; i++) @@ -3158,9 +3193,10 @@ void rob_chara::load_motion(int32_t motion_id, bool a3, float_t frame, data.motion.step_data.frame = data.motion.step_data.step; float_t step = data.motion.step; - if (step < 0.0f) + if (data.motion.step < 0.0f) step = data.motion.step_data.frame; - item_equip->set_step(step); + item_equip->set_osage_step(step); + rob_chara_bone_data_motion_load(this->bone_data, motion_id, blend_type, bone_data, mot_db); this->bone_data->set_motion_frame(data.motion.step_data.frame, data.motion.step_data.frame, data.field_1588.field_0.frame_count); @@ -3266,6 +3302,9 @@ void rob_chara::reset_osage() { for (rob_chara_data_adjust& i : data.motion.parts_adjust_prev) i.reset(); + for (int32_t i = 0; i < ROB_OSAGE_PARTS_MAX; i++) + item_equip->reset_nodes_external_force((rob_osage_parts)i); + data.motion.adjust_global.reset(); data.motion.adjust_global_prev.reset(); @@ -3274,7 +3313,7 @@ void rob_chara::reset_osage() { item_equip->parts_append = false; item_equip->parts_white_one_l = false; - set_step(-1.0f); + set_osage_step(-1.0f); } void rob_chara::set_bone_data_frame(float_t frame) { @@ -3283,12 +3322,16 @@ void rob_chara::set_bone_data_frame(float_t frame) { rob_chara_bone_data_update(bone_data, 0); } +void rob_chara::set_chara_color(bool value) { + item_equip->chara_color = value; +} + void rob_chara::set_chara_height_adjust(bool value) { data.adjust_data.height_adjust = value; } -void rob_chara::set_chara_pos_adjust(vec3* value) { - data.adjust_data.pos_adjust = *value; +void rob_chara::set_chara_pos_adjust(vec3& value) { + data.adjust_data.pos_adjust = value; } void rob_chara::set_chara_pos_adjust_y(float_t value) { @@ -3492,6 +3535,14 @@ static void sub_1405500F0(rob_chara* rob_chr) { } } +void rob_chara::set_data_miku_rot_position(vec3& value) { + data.miku_rot.position = value; +} + +void rob_chara::set_data_miku_rot_rot_y_int16(int16_t value) { + data.miku_rot.rot_y_int16 = value; +} + void rob_chara::set_eyelid_mottbl_motion_from_face(int32_t a2, float_t blend_duration, float_t value, float_t blend_offset, const motion_database* mot_db) { if (!a2) @@ -3757,6 +3808,17 @@ void rob_chara::set_face_mottbl_motion(int32_t type, } } +void rob_chara::set_face_object(object_info obj_info, int32_t a3) { + if (a3 == 2) + data.motion.field_3B0.face_object = obj_info; + else + data.motion.field_150.face_object = obj_info; +} + +void rob_chara::set_face_object_index(int32_t index) { + set_face_object(get_chara_init_data_face_object(index), 0); +} + void rob_chara::set_frame(float_t frame) { bone_data->set_frame(frame); data.motion.frame_data.frame = frame; @@ -3811,10 +3873,14 @@ void rob_chara::set_hand_r_mottbl_motion(int32_t type, rob_chara_set_hand_r_motion(this, &motion, type, mot_db); } +void rob_chara::set_left_hand_scale(float_t value) { + data.adjust_data.left_hand_scale = value; +} + bool rob_chara::set_motion_id(int32_t motion_id, - float_t frame, float_t blend_duration, bool a5, bool set_motion_reset_data, + float_t frame, float_t blend_duration, bool blend, bool set_motion_reset_data, MotionBlendType blend_type, const bone_database* bone_data, const motion_database* mot_db) { - if (!a5 && data.motion.motion_id == motion_id) + if (!blend && data.motion.motion_id == motion_id) return false; if (blend_duration <= 0.0f) @@ -3831,7 +3897,7 @@ bool rob_chara::set_motion_id(int32_t motion_id, item_equip->item_equip_object[ITEM_TE_L].osage_iterations = 60; item_equip->item_equip_object[ITEM_TE_R].osage_iterations = 60; - if (rob_chara_check_for_ageageagain_module(chara_index, module_index)) { + if (check_for_ageageagain_module()) { rob_chara_age_age_array_set_skip(chara_id, 1); rob_chara_age_age_array_set_skip(chara_id, 2); } @@ -3839,6 +3905,15 @@ bool rob_chara::set_motion_id(int32_t motion_id, return true; } +void rob_chara::set_motion_loop(float_t loop_begin, float_t loop_end, int32_t loop_count) { + bone_data->set_motion_loop_state(MOT_PLAY_FRAME_DATA_LOOP_CONTINUOUS); + bone_data->set_motion_loop(loop_begin, loop_count, loop_end); + if (data.field_1588.field_0.field_58 != 1) { + data.field_1588.field_0.field_58 = 1; + data.field_1588.field_0.frame = data.field_1588.field_0.frame_count - 1.0f; + } +} + void rob_chara::set_motion_reset_data(int32_t motion_id, float_t frame) { item_equip->set_motion_reset_data(motion_id, frame); } @@ -3847,6 +3922,10 @@ void rob_chara::set_motion_skin_param(int32_t motion_id, float_t frame) { item_equip->set_motion_skin_param(chara_id, motion_id, (int32_t)roundf(frame)); } +void rob_chara::set_motion_step(float_t value) { + data.motion.step_data.step = value; +} + void rob_chara::set_mouth_mottbl_motion(int32_t type, int32_t mottbl_index, float_t value, int32_t state, float_t blend_duration, float_t a7, float_t step, int32_t a9, float_t blend_offset, const motion_database* mot_db) { @@ -3882,6 +3961,13 @@ void rob_chara::set_osage_reset() { item_equip->set_osage_reset(); } +void rob_chara::set_osage_step(float_t value) { + data.motion.step = value; + if (value < 0.0f) + value = data.motion.step_data.frame; + item_equip->set_osage_step(value); +} + void rob_chara::set_parts_disp(item_id id, bool disp) { if (id < ITEM_BODY) return; @@ -3890,8 +3976,7 @@ void rob_chara::set_parts_disp(item_id id, bool disp) { else if (id == ITEM_MAX) for (int32_t i = ITEM_ATAMA; i <= ITEM_ITEM16; i++) { item_equip->item_equip_object[i].can_disp = disp; - if (i == ITEM_ATAMA - && rob_chara_check_for_ageageagain_module(chara_index, module_index)) { + if (i == ITEM_ATAMA && check_for_ageageagain_module()) { rob_chara_age_age_array_set_disp(chara_id, 1, disp); rob_chara_age_age_array_set_disp(chara_id, 2, disp); rob_chara_age_age_array_set_skip(chara_id, 1); @@ -3900,26 +3985,34 @@ void rob_chara::set_parts_disp(item_id id, bool disp) { } } -void rob_chara::set_step(float_t value) { - data.motion.step = value; - if (value < 0.0f) - value = data.motion.step_data.frame; - item_equip->set_step(value); +void rob_chara::set_right_hand_scale(float_t value) { + data.adjust_data.right_hand_scale = value; } -void rob_chara::set_step_motion_step(float_t step) { - data.motion.step_data.step = step; - if (step < 0.0f) +void rob_chara::set_shadow_cast(bool value) { + if (value) + item_equip->field_A0 |= 0x04; + else + item_equip->field_A0 &= ~0x04; +} + +void rob_chara::set_step_motion_step(float_t value) { + data.motion.step_data.step = value; + if (value < 0.0f) data.motion.step_data.frame = 1.0f; else - data.motion.step_data.frame = step; + data.motion.step_data.frame = value; rob_chara_bone_data_set_step(bone_data, data.motion.step_data.frame); - step = data.motion.step; - if (step < 0.0f) + float_t step = data.motion.step; + if (data.motion.step < 0.0f) step = data.motion.step_data.frame; - item_equip->set_step(step); + item_equip->set_osage_step(step); +} + +void rob_chara::set_use_opd(bool value) { + item_equip->use_opd = value; } void rob_chara::set_visibility(bool value) { @@ -3932,19 +4025,34 @@ void rob_chara::set_visibility(bool value) { data.field_3 &= ~0x01; } - if (rob_chara_check_for_ageageagain_module(chara_index, module_index)) { + if (check_for_ageageagain_module()) { rob_chara_age_age_array_set_disp(chara_id, 1, value); rob_chara_age_age_array_set_disp(chara_id, 2, value); } } +void rob_chara::set_wind_strength(float_t value) { + item_equip->wind_strength = value; +} + +static void sub_140554830(rob_chara* rob_chr, uint8_t a2, uint8_t a3, + float_t a4, float_t a5, float_t a6, float_t a7, float_t a8, bool a9); + +void rob_chara::sub_140554790(bool a2, float_t a3, float_t a5, float_t a6, float_t a7, float_t a8) { + sub_140554830(this, true, a2, a3, a5, a6, a7, a8, false); +} + +void rob_chara::sub_1405547E0(bool a2, float_t a3, float_t a5, float_t a6, float_t a7, float_t a8) { + sub_140554830(this, true, a2, a3, a5, a6, a7, a8, false); +} + osage_init_data::osage_init_data() : rob_chr() { pv_id = -1; motion_id = -1; frame = -1; } -osage_init_data::osage_init_data(rob_chara* rob_chr, int32_t motion_id) { +osage_init_data::osage_init_data(rob_chara* rob_chr, uint32_t motion_id) { this->rob_chr = rob_chr; pv_id = -1; this->motion_id = motion_id; @@ -5491,7 +5599,7 @@ static void mothead_func_32(mothead_func_data* func_data, if (rob_chr_data->motion.field_28 & 0x08) v5 = sub_140533440(v5); - float_t v7 = rob_chr_data->field_1588.field_0.field_8 - 1.0f + float_t v7 = rob_chr_data->field_1588.field_0.frame - 1.0f - rob_chr_data->motion.frame_data.frame; if (v7 >= v8) v7 = v8; @@ -5700,8 +5808,8 @@ static void mothead_func_59_set_rob_chara_head_object(mothead_func_data* func_da rob_chara_set_head_object(func_data->rob_chr, ((int32_t*)data)[0], mot_db); } -static void sub_14041C950(rob_chara_bone_data* rob_bone_data, uint8_t a2, bool a3, - float_t a4, float_t a5, float_t a6, float_t a7, float_t a8, uint8_t a9) { +static void sub_14041C950(rob_chara_bone_data* rob_bone_data, bool a2, bool a3, + float_t a4, float_t a5, float_t a6, float_t a7, float_t a8, bool a9) { struc_258* v11 = &rob_bone_data->field_788; bool v10 = !v11->field_8E && a3 || !a3 && v11->field_8E; @@ -5724,7 +5832,7 @@ static void sub_14041C950(rob_chara_bone_data* rob_bone_data, uint8_t a2, bool a } static void sub_140554830(rob_chara* rob_chr, uint8_t a2, uint8_t a3, - float_t a4, float_t a5, float_t a6, float_t a7, float_t a8, uint8_t a9) { + float_t a4, float_t a5, float_t a6, float_t a7, float_t a8, bool a9) { sub_14041C950(rob_chr->bone_data, a2, a3, a4, a5, a6, a7, a8, a9); if (fabsf(a6) <= 0.000001f) rob_chr->data.field_2 |= 0x80; @@ -5733,7 +5841,7 @@ static void sub_140554830(rob_chara* rob_chr, uint8_t a2, uint8_t a3, static void mothead_func_60(mothead_func_data* func_data, void* data, const mothead_data* mhd_data, int32_t frame, const motion_database* mot_db) { sub_140554830(func_data->rob_chr, 1, ((int32_t*)data)[0] != 0, - ((float_t*)data)[1], ((float_t*)data)[2], ((float_t*)data)[3] * 6.0f, 0.25f, 0.0f, 0); + ((float_t*)data)[1], ((float_t*)data)[2], ((float_t*)data)[3] * 6.0f, 0.25f, 0.0f, false); } static void mothead_func_61_set_eyelid_motion_from_face(mothead_func_data* func_data, @@ -5808,7 +5916,7 @@ static void mothead_func_65_motion_skin_param(mothead_func_data* func_data, static void mothead_func_66_osage_step(mothead_func_data* func_data, void* data, const mothead_data* mhd_data, int32_t frame, const motion_database* mot_db) { - func_data->rob_chr->set_step(((float_t*)data)[0]); + func_data->rob_chr->set_osage_step(((float_t*)data)[0]); } static void mothead_func_67_sleeve(mothead_func_data* func_data, @@ -5990,7 +6098,7 @@ static void mothead_func_76_rob_arm_adjust(mothead_func_data* func_data, static void mothead_func_77_disable_eye_motion(mothead_func_data* func_data, void* data, const mothead_data* mhd_data, int32_t frame, const motion_database* mot_db) { - rob_chara_bone_data_set_disable_eye_motion(func_data->rob_chr->bone_data, ((uint8_t*)data)[0] != 0); + func_data->rob_chr->bone_data->set_disable_eye_motion(((uint8_t*)data)[0] != 0); } static void mothead_func_78(mothead_func_data* func_data, @@ -6623,7 +6731,7 @@ static bool opd_decode(const osage_play_data_header* file_head, float_t** opd_de for (size_t i = 0; i < file_head->nodes_count; i++) for (uint32_t i = 3; i; i--) { - opd_data_decode(node->data, node->count, node->shift, buf); + opd_data_decode(node->data, node->count, (uint8_t)node->shift, buf); buf += file_head->frame_count; node = (const osage_play_data_node_header*)((size_t)node + sizeof(const osage_play_data_node_header) + node->count * sizeof(uint16_t)); @@ -6710,7 +6818,7 @@ void rob_chara_data_adjust_ctrl(rob_chara* rob_chr, rob_chara_data_adjust* adjus float_t v7 = 0.0f; adjust->frame += rob_chr->data.motion.step_data.frame; if (rob_chr->data.field_1588.field_0.field_58 == 1) - cycle *= (60.0f / rob_chr->data.field_1588.field_0.field_8); + cycle *= (60.0f / rob_chr->data.field_1588.field_0.frame); cycle *= adjust->frame * 2.0f * (float_t)M_PI * (float_t)(1.0 / 60.0f); switch (adjust->cycle_type) { @@ -7144,7 +7252,7 @@ static void sub_140505310(rob_chara* rob_chr, const bone_database* bone_data, co switch (rob_chr->data.field_1588.field_0.field_58) { case -1: { rob_chr->data.field_1588.field_0.field_20.field_0 &= ~0x81; - rob_chr->data.motion.frame_data.frame = rob_chr->data.field_1588.field_0.field_8; + rob_chr->data.motion.frame_data.frame = rob_chr->data.field_1588.field_0.frame; } break; case 0: { int32_t motion_id = rob_chr->data.field_1588.field_0.field_5C; @@ -7240,7 +7348,7 @@ static void sub_140505980(rob_chara* rob_chr) { LABEL_23: float_t v5 = rob_chr->data.field_1588.field_0.field_80; if (v5 >= 0.0f && v5 <= rob_chr->data.motion.frame_data.frame) { - if (v5 < (rob_chr->data.field_1588.field_0.field_8 - 1.0f) + if (v5 < (rob_chr->data.field_1588.field_0.frame - 1.0f) || rob_chr->data.field_1588.field_0.field_58 == -1 || rob_chr->data.field_1588.field_0.field_58 == 2) { rob_chr->data.field_1588.field_0.field_20.field_0 &= ~0x2020081; @@ -8021,12 +8129,12 @@ static void rob_disp_rob_chara_init(rob_chara* rob_chr, rob_itm_equip->load_outfit_object_info((item_id)i, chr_init_data->field_7E4[i], false, aft_bone_data, aft_data, aft_obj_db); rob_itm_equip->set_shadow_type(rob_chr->chara_id); - rob_chr->item_equip->field_A0 = 5; + rob_chr->item_equip->field_A0 = 0x05; rob_chr->item_cos_data.reload_items(rob_chr->chara_id, bone_data, data, obj_db); if (rob_chr->item_cos_data.check_for_npr_flag()) rob_chr->item_equip->npr_flag = true; - if (rob_chara_check_for_ageageagain_module(rob_chr->chara_index, rob_chr->module_index)) { + if (rob_chr->check_for_ageageagain_module()) { rob_chara_age_age_array_load(rob_chr->chara_id, 1); rob_chara_age_age_array_load(rob_chr->chara_id, 2); } @@ -8074,10 +8182,10 @@ static void rob_disp_rob_chara_ctrl_thread_main(rob_chara* rob_chr) { rob_chr->get_trans_scale(0, trans); rob_chr->item_equip->position = trans; rob_chara_item_equip_ctrl(rob_chr->item_equip); - if (rob_chara_check_for_ageageagain_module(rob_chr->chara_index, rob_chr->module_index)) { - rob_chara_age_age_array_set_step(rob_chr->chara_id, 1, rob_chr->item_equip->step); + if (rob_chr->check_for_ageageagain_module()) { + rob_chara_age_age_array_set_step(rob_chr->chara_id, 1, rob_chr->item_equip->osage_step); rob_chara_age_age_ctrl(rob_chr, 1, "j_tail_l_006_wj"); - rob_chara_age_age_array_set_step(rob_chr->chara_id, 2, rob_chr->item_equip->step); + rob_chara_age_age_array_set_step(rob_chr->chara_id, 2, rob_chr->item_equip->osage_step); rob_chara_age_age_ctrl(rob_chr, 2, "j_tail_r_006_wj"); } } @@ -8378,7 +8486,7 @@ static void sub_140407280(struc_258* a1, std::vector* a2, mat4* mat, } float_t v51 = (v48 - atan2f(-v68.x, v68.y)) * a1->field_198; - vec3 v71 = *(vec3*&)v73->row2; + vec3 v71 = *(vec3*)&v73->row2; v71.y += 1.0f; v71 *= 0.5f; @@ -9456,10 +9564,9 @@ static float_t sub_140406E90(bone_data* a1, bone_data* a2, float_t a3, vec3* a4) } static float_t sub_14064AD10(vec3* a1, float_t a2) { - task_stage_info v5; - task_stage_get_current_stage_info(&v5); - if (task_stage_has_stage_info(&v5)) { - stage* stg = task_stage_get_stage(v5); + task_stage_info stg_info = task_stage_get_current_stage_info(); + if (stg_info.check()) { + stage* stg = task_stage_get_stage(stg_info); if (!stg) return -1000.0f; @@ -11233,11 +11340,11 @@ static void rob_chara_set_adjust(rob_chara* rob_chr, rob_chara_data_adjust* adju } static void rob_chara_set_pv_data(rob_chara* rob_chr, int8_t chara_id, - chara_index chara_index, int32_t module_index, rob_chara_pv_data* pv_data) { + chara_index chara_index, int32_t module_index, const rob_chara_pv_data& pv_data) { rob_chr->chara_id = chara_id; rob_chr->chara_index = chara_index; rob_chr->module_index = module_index; - rob_chr->pv_data = *pv_data; + rob_chr->pv_data = pv_data; rob_chr->chara_init_data = chara_init_data_get(chara_index); if (!check_module_index_is_501(module_index)) { const item_cos_data* cos @@ -11245,7 +11352,7 @@ static void rob_chara_set_pv_data(rob_chara* rob_chr, int8_t chara_id, if (cos) rob_chr->item_cos_data.set_chara_index_item_nos(chara_index, cos->arr); } - rob_chr->item_cos_data.set_item_array(&pv_data->item); + rob_chr->item_cos_data.set_item_array(pv_data.item); } static void rob_cmn_mottbl_read(void* a1, const void* data, size_t size) { @@ -11391,9 +11498,9 @@ rob_chara_item_equip* rob_chara_array_get_item_equip(int32_t chara_id) { } int32_t rob_chara_array_init_chara_index(chara_index chara_index, - rob_chara_pv_data* pv_data, int32_t module_index, bool can_set_default) { + const rob_chara_pv_data& pv_data, int32_t module_index, bool can_set_default) { if (!app::TaskWork::CheckTaskReady(task_rob_manager) - || pv_data->type < ROB_CHARA_TYPE_0|| pv_data->type > ROB_CHARA_TYPE_3) + || pv_data.type < ROB_CHARA_TYPE_0|| pv_data.type > ROB_CHARA_TYPE_3) return -1; int32_t chara_id = 0; @@ -11405,7 +11512,7 @@ int32_t rob_chara_array_init_chara_index(chara_index chara_index, if (can_set_default && (module_index < 0 || module_index > 498)) module_index = 0; - rob_chara_pv_data_array[chara_id] = *pv_data; + rob_chara_pv_data_array[chara_id] = pv_data; rob_chara_set_pv_data(&rob_chara_array[chara_id], chara_id, chara_index, module_index, pv_data); task_rob_manager->AppendInitCharaList(&rob_chara_array[chara_id]); return chara_id; @@ -11423,7 +11530,7 @@ void rob_chara_array_reset_bone_data_item_equip(int32_t chara_id) { rob_chara_item_equip* rob_itm_equip = rob_chara_array[chara_id].item_equip; rob_itm_equip->reset_init_data(rob_chara_bone_data_get_node(rob_chara_array[chara_id].bone_data, 0)); rob_itm_equip->set_shadow_type(chara_id); - rob_itm_equip->field_A0 = 5; + rob_itm_equip->field_A0 = 0x05; } void rob_chara_array_set_alpha_obj_flags(int32_t chara_id, float_t alpha, mdl::ObjFlags flags) { @@ -11433,7 +11540,7 @@ void rob_chara_array_set_alpha_obj_flags(int32_t chara_id, float_t alpha, mdl::O rob_chr->item_equip->set_alpha_obj_flags(alpha, flags); - if (rob_chara_check_for_ageageagain_module(rob_chr->chara_index, rob_chr->module_index)) { + if (rob_chr->check_for_ageageagain_module()) { rob_chara_age_age_array_set_alpha(chara_id, 1, alpha); rob_chara_age_age_array_set_alpha(chara_id, 2, alpha); } @@ -11460,7 +11567,7 @@ void pv_osage_manager_array_set_pv_id(int32_t chara_id, int32_t pv_id, bool rese } void pv_osage_manager_array_set_pv_set_motion( - int32_t chara_id, std::vector& set_motion) { + int32_t chara_id, const std::vector& set_motion) { pv_osage_manager_array_get(chara_id)->SetPvSetMotion(set_motion); } @@ -12295,6 +12402,10 @@ void rob_chara_bone_data::reset() { sleeve_adjust.reset(); } +void rob_chara_bone_data::set_disable_eye_motion(bool value) { + disable_eye_motion = value; +} + void rob_chara_bone_data::set_frame(float_t frame) { motion_loaded.front()->mot_play_data.frame_data.set_frame(frame); } @@ -12368,8 +12479,34 @@ rob_chara_pv_data::rob_chara_pv_data() { eyes_adjust.pos = -1.0f; } -rob_chara_pv_data::~rob_chara_pv_data() { - +void rob_chara_pv_data::reset() { + type = ROB_CHARA_TYPE_2; + field_4 = true; + field_5 = false; + field_6 = false; + field_8 = 0.0f; + rot_y_int16 = 0; + field_16 = 0xC9; + sleeve_l = {}; + sleeve_r = {}; + field_70 = 0; + motion_face_ids[0] = -1; + motion_face_ids[1] = -1; + motion_face_ids[2] = -1; + motion_face_ids[3] = -1; + motion_face_ids[4] = -1; + motion_face_ids[5] = -1; + motion_face_ids[6] = -1; + motion_face_ids[7] = -1; + motion_face_ids[8] = -1; + motion_face_ids[9] = -1; + chara_size_index = 1; + height_adjust = false; + item = {}; + eyes_adjust.xrot_adjust = false; + eyes_adjust.base_adjust = EYES_BASE_ADJUST_DIRECTION; + eyes_adjust.neg = -1.0f; + eyes_adjust.pos = -1.0f; } rob_chara_item_equip_object::rob_chara_item_equip_object() : index(), mats(), @@ -12801,6 +12938,14 @@ void rob_chara_item_equip_object::reset_external_force() { i->rob.ResetExtrenalForce(); } +void rob_chara_item_equip_object::reset_nodes_external_force(rob_osage_parts_bit parts_bits) { + for (ExOsageBlock*& i : osage_blocks) + if (i->rob.CheckPartsBits(parts_bits)) { + i->rob.SetNodesExternalForce(0, 1.0f); + i->rob.SetNodesForce(1.0f); + } +} + void rob_chara_item_equip_object::set_alpha_obj_flags(float_t alpha, int32_t flags) { obj_flags = (mdl::ObjFlags)flags; this->alpha = clamp_def(alpha, 0.0f, 1.0f); @@ -13031,10 +13176,12 @@ field_B4(), field_D4(), disable_update(), field_DC(), texture_color_coefficients chara_color(), npr_flag(), mat(), field_13C(), field_8BC(), field_8C0(), field_8C4(), field_8C8(), field_8CC(), field_8D0(), field_8D4(), field_8D8(), field_8DC(), field_8E0(), field_8E4(), field_8E8(), field_8EC(), field_8F0(), field_8F4(), field_8F8(), field_8FC(), field_900(), field_908(), field_910(), field_918(), -field_920(), field_928(), field_930(), step(1.0f), use_opd(), parts_short(), parts_append(), parts_white_one_l() { +field_920(), field_928(), field_930(), use_opd(), parts_short(), parts_append(), parts_white_one_l() { item_equip_object = new rob_chara_item_equip_object[ITEM_MAX]; wind_strength = 1.0f; chara_color = true; + osage_step = 1.0f; + for (int32_t i = ITEM_BODY; i < ITEM_MAX; i++) item_equip_object[i].item_equip = this; } @@ -13098,7 +13245,7 @@ void rob_chara_item_equip::disp(int32_t chara_id, render_context* rctx) { mdl::DispManager& disp_manager = rctx->disp_manager; shadow* shad = rctx->render_manager.shadow_ptr; if (shadow_type != -1) { - if (field_A0 & 4) { + if (field_A0 & 0x04) { vec3 pos = position; pos.y -= 0.2f; shad->field_1D0[shadow_type].push_back(pos); @@ -13113,7 +13260,7 @@ void rob_chara_item_equip::disp(int32_t chara_id, render_context* rctx) { enum_or(flags, mdl::OBJ_SHADOW); } - if (field_A0 & 1) + if (field_A0 & 0x01) enum_or(flags, mdl::OBJ_4); } disp_manager.set_obj_flags(flags); @@ -13182,8 +13329,8 @@ const mat4* rob_chara_item_equip::get_ex_data_bone_node_mat(item_id id, const ch return item_equip_object[id].get_ex_data_bone_node_mat(name); } -void rob_chara_item_equip::load_body_parts_object_info(item_id id, - object_info obj_info, const bone_database* bone_data, void* data, const object_database* obj_db) { +void rob_chara_item_equip::load_body_parts_object_info(item_id id, object_info obj_info, + const bone_database* bone_data, void* data, const object_database* obj_db) { if (id <= ITEM_BODY || id >= ITEM_MAX) obj_info = {}; load_object_info(obj_info, id, false, bone_data, data, obj_db); @@ -13206,7 +13353,7 @@ void rob_chara_item_equip::reset() { item_equip_object[i].init_members(); item_equip_range = false; shadow_type = (shadow_type_enum)-1; - field_A0 = 5; + field_A0 = 0x05; texture_pattern.clear(); field_D0 = {}; field_D4 = -1; @@ -13214,7 +13361,7 @@ void rob_chara_item_equip::reset() { parts_short = false; parts_append = false; parts_white_one_l = false; - step = 1.0f; + osage_step = 1.0f; use_opd = false; first_item_equip_object = ITEM_ATAMA; max_item_equip_object = ITEM_ITEM16; @@ -13238,7 +13385,7 @@ void rob_chara_item_equip::reset_init_data(bone_node* bone_nodes) { *v7++ = mat4_identity; } - step = 1.0f; + osage_step = 1.0f; wet = 0.0f; wind_strength = 1.0f; chara_color = true; @@ -13246,6 +13393,11 @@ void rob_chara_item_equip::reset_init_data(bone_node* bone_nodes) { mat = mat4_identity; } +void rob_chara_item_equip::reset_nodes_external_force(rob_osage_parts parts) { + item_equip_object[parts == ROB_OSAGE_PARTS_MUFFLER ? ITEM_OUTER : ITEM_KAMI] + .reset_nodes_external_force((rob_osage_parts_bit)(1 << parts)); +} + void rob_chara_item_equip::set_alpha_obj_flags(float_t alpha, mdl::ObjFlags flags) { if (item_equip_range) for (int32_t i = first_item_equip_object; i < max_item_equip_object; i++) @@ -13333,6 +13485,10 @@ void rob_chara_item_equip::set_osage_reset() { task_wind->ptr->reset(); } +void rob_chara_item_equip::set_osage_step(float_t value) { + osage_step = value; +} + void rob_chara_item_equip::set_osage_move_cancel(uint8_t id, float_t value) { if (id == 0) for (int32_t i = first_item_equip_object; i < max_item_equip_object; i++) @@ -13355,10 +13511,6 @@ void rob_chara_item_equip::set_shadow_type(int32_t chara_id) { shadow_type = SHADOW_STAGE; } -void rob_chara_item_equip::set_step(float_t value) { - step = value; -} - void rob_chara_item_equip::set_texture_pattern(texture_pattern_struct* tex_pat, size_t count) { texture_pattern.clear(); if (count && tex_pat) @@ -13966,9 +14118,9 @@ void rob_chara_item_cos_data::set_item(int32_t item_no) { cos.arr[item->sub_id] = item_no; } -void rob_chara_item_cos_data::set_item_array(rob_chara_pv_data_item* item) { +void rob_chara_item_cos_data::set_item_array(const rob_chara_pv_data_item& item) { for (int32_t i = 0; i < 4; i++) - set_item(item->arr[i]); + set_item(item.arr[i]); } void rob_chara_item_cos_data::set_item_no(item_sub_id sub_id, int32_t item_no) { @@ -14565,7 +14717,7 @@ field_34(), field_38(), field_3C(), field_40(), field_44(), field_48() { } -struc_652::struc_652() : motion_id(), frame_count(), field_8(), field_C(), field_10(), field_20(), +struc_652::struc_652() : motion_id(), frame_count(), frame(), field_C(), field_10(), field_20(), field_30(), field_40(), field_50(), field_52(), field_54(), field_58(), field_5C(), field_60(), field_64(), field_68(), loop_count(), loop_begin(), loop_end(), field_78(), field_7C(), field_80(), field_84(), field_88(), field_8C(), field_90(), field_94(), field_96(), field_98(), field_9C(), @@ -14588,7 +14740,7 @@ struc_652::~struc_652() { void struc_652::reset() { motion_id = -1; frame_count = 0.0f; - field_8 = 0.0f; + frame = 0.0f; field_C = 0; sub_140536DD0(); field_50 = 0; @@ -15551,6 +15703,9 @@ static void sub_14053E810(rob_chara* rob_chr, void* data) { v16.strength = ((float_t*)data)[14]; v16.strength_transition = (float_t)((int32_t*)data)[15]; } + else + rob_chr->item_equip->reset_nodes_external_force((rob_osage_parts)((uint8_t*)data)[4]); + rob_chara_set_parts_adjust_by_index(rob_chr, (rob_osage_parts)((uint8_t*)data)[4], &v16); } @@ -16228,8 +16383,8 @@ static void sub_140479AA0(OpdMaker::Data* a1, rob_chara* rob_chr, std::vectorempty = false; } -static bool sub_140479090(struc_655* a1, chara_index chara_index) { - std::vector* v4 = a1->field_10[chara_index].field_0; +static bool sub_140479090(struc_655& a1, chara_index chara_index) { + std::vector* v4 = a1.field_10[chara_index].field_0; for (int32_t i = 0; i < ITEM_SUB_MAX; i++, v4++) if (v4->size()) return false; @@ -16258,7 +16413,7 @@ bool OpdMakeWorker::Ctrl() { rob_chr->item_equip->reset_init_data(rob_chara_bone_data_get_node( rob_chara_array[chara_id].bone_data, 0)); rob_chr->item_equip->set_shadow_type(chara_id); - rob_chr->item_equip->field_A0 = 5; + rob_chr->item_equip->field_A0 = 0x05; state = 2; } case 2: { @@ -16375,7 +16530,7 @@ bool OpdMakeWorker::Ctrl() { rob_chr->item_cos_data.reload_items(chara_id, aft_bone_data, aft_data, aft_obj_db); skin_param_manager_reset(chara_id); - if (sub_140479090(&opd_make_manager->field_88, chara_index)) + if (sub_140479090(opd_make_manager->field_88, chara_index)) return true; state = 1; } break; @@ -16463,7 +16618,7 @@ bool OsagePlayDataManager::AddTask() { return app::TaskWork::AddTask(this, "OSAGE_PLAY_DATA_MANAGER"); } -void OsagePlayDataManager::AppendCharaMotionId(rob_chara* rob_chr, std::vector& motion_ids) { +void OsagePlayDataManager::AppendCharaMotionId(rob_chara* rob_chr, const std::vector& motion_ids) { if (CheckTaskReady() || !rob_chr) return; @@ -16693,7 +16848,7 @@ bool OpdMakeManager::Ctrl() { case 5: { bool v8 = false; for (int32_t i = CHARA_MIKU; i < CHARA_MAX; i++) - if (!sub_140479090(&field_88, (chara_index)i)) { + if (!sub_140479090(field_88, (chara_index)i)) { chara = (chara_index)i; v8 = true; break; @@ -16701,9 +16856,9 @@ bool OpdMakeManager::Ctrl() { if (v8) { for (int32_t i = 0; i < 4; i++) { - rob_chara_pv_data v32; - v32.type = ROB_CHARA_TYPE_3; - rob_chara_array_init_chara_index(chara, &v32, 499, false); + rob_chara_pv_data pv_data; + pv_data.type = ROB_CHARA_TYPE_3; + rob_chara_array_init_chara_index(chara, pv_data, 499, false); } mode = 6; } @@ -17456,7 +17611,7 @@ rob_sleeve_handler::~rob_sleeve_handler() { void rob_sleeve_handler::clear() { ready = false; - + for (auto& i : sleeves) { delete i.second.l; delete i.second.r; @@ -17597,18 +17752,15 @@ void rob_sleeve_handler::read() { data_struct* aft_data = &data_list[DATA_AFT]; for (const std::string& i : mdata_manager_get()->GetPrefixes()) { - std::string dir; - dir.assign("rom/"); - dir.append(i); + std::string file; + file.assign(i); + file.append("rob_sleeve_data.txt"); - const char* file = "rob_sleeve_data.txt"; - - if (!aft_data->check_file_exists(dir.c_str(), file)) - continue; - - p_file_handler* pfhndl = new p_file_handler; - pfhndl->read_file(aft_data, dir.c_str(), file); - file_handlers.push_back(pfhndl); + if (aft_data->check_file_exists("rom/", file.c_str())) { + p_file_handler* pfhndl = new p_file_handler; + pfhndl->read_file(aft_data, "rom/", file.c_str()); + file_handlers.push_back(pfhndl); + } } } @@ -17776,7 +17928,7 @@ void PvOsageManager::SetPvId(int32_t pv_id, int32_t chara_id, bool reset) { cnd.notify_one(); } -void PvOsageManager::SetPvSetMotion(std::vector& set_motion) { +void PvOsageManager::SetPvSetMotion(const std::vector& set_motion) { pv_set_motion.assign(set_motion.begin(), set_motion.end()); } diff --git a/src/CRE/rob/rob.hpp b/src/CRE/rob/rob.hpp index 70e5da42..7933b8dc 100644 --- a/src/CRE/rob/rob.hpp +++ b/src/CRE/rob/rob.hpp @@ -1331,12 +1331,14 @@ struct rob_chara_bone_data { float_t get_frame_count(); bool get_motion_has_looped(); void reset(); + void set_disable_eye_motion(bool value); void set_frame(float_t frame); void set_motion_frame(float_t frame, float_t step, float_t frame_count); void set_motion_loop(float_t loop_begin, int32_t loop_count, float_t loop_end); void set_motion_loop_state(mot_play_frame_data_loop_state value); void set_motion_max_frame(float_t value); void set_motion_playback_state(mot_play_frame_data_playback_state value); + }; union rob_chara_pv_data_item { @@ -1367,7 +1369,8 @@ struct rob_chara_pv_data { eyes_adjust eyes_adjust; rob_chara_pv_data(); - ~rob_chara_pv_data(); + + void reset(); }; struct struc_218 { @@ -1782,10 +1785,10 @@ struct CLOTH { virtual ~CLOTH(); virtual void Init(); - virtual void SetSkinParamColiR(float_t coli_r); - virtual void SetSkinParamFriction(float_t friction); - virtual void SetSkinParamWindAfc(float_t wind_afc); - virtual void SetWindDirection(vec3& wind_direction); + virtual void SetSkinParamColiR(float_t value); + virtual void SetSkinParamFriction(float_t value); + virtual void SetSkinParamWindAfc(float_t value); + virtual void SetWindDirection(vec3& value); virtual void Field_30(float_t a2); virtual void SetSkinParamHinge(float_t hinge_y, float_t hinge_z); virtual CLOTHNode* GetNodes(); @@ -2178,6 +2181,7 @@ struct rob_chara_item_equip_object { void load_object_info_ex_data(object_info object_info, bone_node* bone_nodes, bool osage_reset, const bone_database* bone_data, void* data, const object_database* obj_db); void reset_external_force(); + void reset_nodes_external_force(rob_osage_parts_bit parts_bits); void set_alpha_obj_flags(float_t alpha, int32_t flags); bool set_boc(const skin_param_osage_root& skp_root, ExOsageBlock* osg); void set_collision_target_osage(const skin_param_osage_root& skp_root, skin_param* skp); @@ -2244,7 +2248,7 @@ struct rob_chara_item_equip { int64_t field_920; int64_t field_928; int64_t field_930; - float_t step; + float_t osage_step; bool use_opd; std::vector opd_blend_data; bool parts_short; @@ -2260,8 +2264,8 @@ struct rob_chara_item_equip { object_info get_object_info(item_id id); void get_parent_bone_nodes(bone_node* bone_nodes, const bone_database* bone_data); const mat4* get_ex_data_bone_node_mat(item_id id, const char* name); - void load_body_parts_object_info(item_id id, - object_info obj_info, const bone_database* bone_data, void* data, const object_database* obj_db); + void load_body_parts_object_info(item_id id, object_info obj_info, + const bone_database* bone_data, void* data, const object_database* obj_db); void load_object_info(object_info obj_info, item_id id, bool osage_reset, const bone_database* bone_data, void* data, const object_database* obj_db); void load_outfit_object_info(item_id id, object_info obj_info, @@ -2269,6 +2273,7 @@ struct rob_chara_item_equip { void reset(); void reset_external_force(); void reset_init_data(bone_node* bone_nodes); + void reset_nodes_external_force(rob_osage_parts parts); void set_alpha_obj_flags(float_t alpha, mdl::ObjFlags flags); void set_disp(item_id id, bool value); void set_item_equip_range(bool value); @@ -2280,9 +2285,9 @@ struct rob_chara_item_equip { void set_opd_blend_data(std::list* a2); void set_osage_play_data_init(item_id id, float_t* opdi_data); void set_osage_reset(); + void set_osage_step(float_t value); void set_osage_move_cancel(uint8_t id, float_t value); void set_shadow_type(int32_t chara_id); - void set_step(float_t value); void set_texture_pattern(texture_pattern_struct* tex_pat, size_t count); void skp_load(item_id id, const skin_param_osage_root& skp_root, std::vector& vec, skin_param_file_data* skp_file_data, const bone_database* bone_data); @@ -2323,8 +2328,8 @@ struct rob_chara_item_cos_data { void set_chara_index_item_nos(::chara_index chara_index, const int32_t* items); void set_chara_index_item_zero(::chara_index chara_index, int32_t item_no); void set_item(int32_t item_no); - void set_item_array(rob_chara_pv_data_item* item); - void set_item_no( item_sub_id sub_id, int32_t item_no); + void set_item_array(const rob_chara_pv_data_item& item); + void set_item_no(item_sub_id sub_id, int32_t item_no); void set_item_nos(const int32_t* item_nos); void set_item_zero(int32_t item_no); void set_texture_pattern(rob_chara_item_equip* rob_itm_equip, @@ -2977,7 +2982,7 @@ struct struc_306 { struct struc_652 { uint32_t motion_id; float_t frame_count; - float_t field_8; + float_t frame; int16_t field_C; struc_228 field_10; struc_228 field_20; @@ -3410,13 +3415,17 @@ struct rob_chara { void autoblink_disable(); void autoblink_enable(); + bool check_for_ageageagain_module(); mat4* get_bone_data_mat(size_t index); + object_info get_chara_init_data_face_object(int32_t index); float_t get_frame(); float_t get_frame_count(); float_t get_max_face_depth(); int32_t get_rob_cmn_mottbl_motion_id(int32_t id); float_t get_trans_scale(int32_t bone, vec3& trans); bool is_visible(); + void load_body_parts_object_info(item_id item_id, object_info obj_info, + const bone_database* bone_data, void* data, const object_database* obj_db); void load_motion(int32_t motion_id, bool a3, float_t frame, MotionBlendType blend_type, const bone_database* bone_data, const motion_database* mot_db); void load_outfit_object_info(item_id id, object_info obj_info, @@ -3425,10 +3434,13 @@ struct rob_chara { const bone_database* bone_data, const motion_database* mot_db); void reset_osage(); void set_bone_data_frame(float_t frame); + void set_chara_color(bool value); void set_chara_height_adjust(bool value); - void set_chara_pos_adjust(vec3* value); + void set_chara_pos_adjust(vec3& value); void set_chara_pos_adjust_y(float_t value); void set_chara_size(float_t value); + void set_data_miku_rot_position(vec3& value); + void set_data_miku_rot_rot_y_int16(int16_t value); void set_eyelid_mottbl_motion_from_face(int32_t a2, float_t blend_duration, float_t value, float_t blend_offset, const motion_database* mot_db); void set_eyelid_mottbl_motion(int32_t type, @@ -3440,6 +3452,8 @@ struct rob_chara { void set_face_mottbl_motion(int32_t type, int32_t mottbl_index, float_t value, int32_t state, float_t blend_duration, float_t a7, float_t step, int32_t a9, float_t blend_offset, bool a11, const motion_database* mot_db); + void set_face_object(object_info obj_info, int32_t a3); + void set_face_object_index(int32_t index); void set_frame(float_t frame); void set_hand_l_mottbl_motion(int32_t type, int32_t mottbl_index, float_t value, int32_t state, float_t blend_duration, float_t a7, @@ -3447,20 +3461,30 @@ struct rob_chara { void set_hand_r_mottbl_motion(int32_t type, int32_t mottbl_index, float_t value, int32_t state, float_t blend_duration, float_t a7, float_t step, int32_t a9, float_t blend_offset, const motion_database* mot_db); + void set_left_hand_scale(float_t value); bool set_motion_id(int32_t motion_id, float_t frame, - float_t blend_duration, bool a5, bool set_motion_reset_data, + float_t blend_duration, bool blend, bool set_motion_reset_data, MotionBlendType blend_type, const bone_database* bone_data, const motion_database* mot_db); + void set_motion_loop(float_t loop_begin, float_t loop_end, int32_t loop_count); void set_motion_reset_data(int32_t motion_id, float_t frame); void set_motion_skin_param(int32_t motion_id, float_t frame); + void set_motion_step(float_t value); void set_mouth_mottbl_motion(int32_t type, int32_t mottbl_index, float_t value, int32_t state, float_t blend_duration, float_t a7, float_t step, int32_t a9, float_t blend_offset, const motion_database* mot_db); void set_osage_move_cancel(uint8_t id, float_t value); void set_osage_reset(); + void set_osage_step(float_t value); void set_parts_disp(item_id id, bool disp); - void set_step(float_t step); + void set_right_hand_scale(float_t value); + void set_shadow_cast(bool value); void set_step_motion_step(float_t value); + void set_use_opd(bool value); void set_visibility(bool value); + void set_wind_strength(float_t value); + + void sub_140554790(bool a2, float_t a3, float_t a5, float_t a6, float_t a7, float_t a8); + void sub_1405547E0(bool a2, float_t a3, float_t a5, float_t a6, float_t a7, float_t a8); }; struct pv_data_set_motion { @@ -3471,12 +3495,12 @@ struct pv_data_set_motion { struct osage_init_data { rob_chara* rob_chr; int32_t pv_id; - int32_t motion_id; + uint32_t motion_id; std::string path; int32_t frame; osage_init_data(); - osage_init_data(rob_chara* rob_chr, int32_t motion_id); + osage_init_data(rob_chara* rob_chr, uint32_t motion_id = -1); ~osage_init_data(); }; @@ -3487,12 +3511,16 @@ extern rob_chara_pv_data* rob_chara_pv_data_array; extern const chara_init_data* chara_init_data_get(chara_index chara_index); extern int32_t chara_init_data_get_chara_size_index(chara_index chara_index); +extern int32_t chara_init_data_get_swim_costume(chara_index chara_index); +extern int32_t chara_init_data_get_swim_s_costume(chara_index chara_index); extern float_t chara_pos_adjust_y_table_get_value(uint32_t index); extern float_t chara_size_table_get_value(uint32_t index); extern bool check_module_index_is_501(int32_t module_index); +extern const uint32_t* get_opd_motion_set_ids();; + extern const float_t get_osage_gravity_const(); extern void motion_set_load_mothead(uint32_t set, std::string&& mdata_dir, const motion_database* mot_db); @@ -3501,7 +3529,9 @@ extern void motion_set_unload_mothead(uint32_t set); extern bool opd_make_manager_del_task(); extern bool osage_play_data_manager_add_task(); -extern void osage_play_data_manager_append_chara_motion_id(rob_chara* rob_chr, int32_t motion_id); +extern void osage_play_data_manager_append_chara_motion_id(rob_chara* rob_chr, uint32_t motion_id); +extern void osage_play_data_manager_append_chara_motion_ids( + rob_chara* rob_chr, const std::vector& motion_ids); extern bool osage_play_data_manager_check_task_ready(); extern void osage_play_data_manager_get_opd_file_data(object_info obj_info, int32_t motion_id, float_t*& data, uint32_t& count); @@ -3537,7 +3567,7 @@ extern float_t rob_chara_array_get_data_adjust_scale(int32_t chara_id); extern rob_chara_item_cos_data* rob_chara_array_get_item_cos_data(int32_t chara_id); extern rob_chara_item_equip* rob_chara_array_get_item_equip(int32_t chara_id); extern int32_t rob_chara_array_init_chara_index(chara_index chara_index, - rob_chara_pv_data* pv_data, int32_t module_index, bool can_set_default); + const rob_chara_pv_data& pv_data, int32_t module_index, bool can_set_default); extern void rob_chara_array_free_chara_id(int32_t chara_id); extern void rob_chara_array_reset_bone_data_item_equip(int32_t chara_id); extern void rob_chara_array_set_alpha_obj_flags(int32_t chara_id, float_t alpha, mdl::ObjFlags flags); @@ -3556,7 +3586,7 @@ extern bool pv_osage_manager_array_get_disp(); extern void pv_osage_manager_array_set_not_reset_true(); extern void pv_osage_manager_array_set_pv_id(int32_t chara_id, int32_t pv_id, bool reset); extern void pv_osage_manager_array_set_pv_set_motion( - int32_t chara_id, std::vector& set_motion); + int32_t chara_id, const std::vector& set_motion); extern bool task_rob_load_add_task(); extern bool task_rob_load_append_free_req_data(chara_index chara_index); @@ -3583,3 +3613,7 @@ extern int32_t expression_id_to_mottbl_index(int32_t expression_id); extern int32_t hand_anim_id_to_mottbl_index(int32_t hand_anim_id); extern int32_t look_anim_id_to_mottbl_index(int32_t look_anim_id); extern int32_t mouth_anim_id_to_mottbl_index(int32_t mouth_anim_id); + +inline bool rob_chara::check_for_ageageagain_module() { + return rob_chara_check_for_ageageagain_module(chara_index, module_index); +} diff --git a/src/CRE/sound.cpp b/src/CRE/sound.cpp index 35f6d9e2..e6bac293 100644 --- a/src/CRE/sound.cpp +++ b/src/CRE/sound.cpp @@ -1869,14 +1869,14 @@ void wave_audio_storage_clear() { wave_audio_storage_data.clear(); } -WaveAudio* wave_audio_storage_get_wave_audio(std::string& name) { +WaveAudio* wave_audio_storage_get_wave_audio(const std::string& name) { auto elem = wave_audio_storage_data.find(name); if (elem != wave_audio_storage_data.end()) return &elem->second; return 0; } -bool wave_audio_storage_load_wave_audio(std::string& name) { +bool wave_audio_storage_load_wave_audio(const std::string& name) { wave_audio_storage_unload_wave_audio(name); sound_db_property* property = sound_work->FindProperty(name.c_str()); @@ -1891,7 +1891,7 @@ bool wave_audio_storage_load_wave_audio(std::string& name) { return false; } -void wave_audio_storage_unload_wave_audio(std::string& name) { +void wave_audio_storage_unload_wave_audio(const std::string& name) { auto elem = wave_audio_storage_data.find(name); if (elem != wave_audio_storage_data.end()) { elem->second.Reset(); diff --git a/src/CRE/sound.hpp b/src/CRE/sound.hpp index 348d1331..7212ba1d 100644 --- a/src/CRE/sound.hpp +++ b/src/CRE/sound.hpp @@ -370,7 +370,7 @@ extern bool sound_work_unload_farc(const char* file_path); extern void wave_audio_storage_init(); extern void wave_audio_storage_clear(); -extern WaveAudio* wave_audio_storage_get_wave_audio(std::string& name); -extern bool wave_audio_storage_load_wave_audio(std::string& name); -extern void wave_audio_storage_unload_wave_audio(std::string& name); +extern WaveAudio* wave_audio_storage_get_wave_audio(const std::string& name); +extern bool wave_audio_storage_load_wave_audio(const std::string& name); +extern void wave_audio_storage_unload_wave_audio(const std::string& name); extern void wave_audio_storage_free(); diff --git a/src/CRE/stage.cpp b/src/CRE/stage.cpp index 59b77df5..4cc46c0e 100644 --- a/src/CRE/stage.cpp +++ b/src/CRE/stage.cpp @@ -16,17 +16,15 @@ namespace stage_detail { static void TaskStage_CtrlInner(stage_detail::TaskStage* a1); static void TaskStage_DispShadow(stage_detail::TaskStage* a1); static stage* TaskStage_GetCurrentStage(stage_detail::TaskStage* a1); - static stage* TaskStage_GetStage(stage_detail::TaskStage* a1, task_stage_info stg_info); - static void TaskStage_GetTaskStageInfo(stage_detail::TaskStage* a1, - task_stage_info* stg_info, size_t index); - static void TaskStage_GetCurrentStageInfo(stage_detail::TaskStage* a1, - task_stage_info* stg_info); + static stage* TaskStage_GetStage(stage_detail::TaskStage* a1, const task_stage_info stg_info); + static task_stage_info TaskStage_GetTaskStageInfo(stage_detail::TaskStage* a1, size_t index); + static task_stage_info TaskStage_GetCurrentStageInfo(stage_detail::TaskStage* a1); static void TaskStage_GetLoadedStageInfos(stage_detail::TaskStage* a1, - std::vector* vec); + std::vector& vec); static void TaskStage_Load(stage_detail::TaskStage* a1); static bool TaskStage_LoadTask(stage_detail::TaskStage* a1, const char* name); static void TaskStage_Reset(stage_detail::TaskStage* a1); - static void TaskStage_SetStage(stage_detail::TaskStage* a1, task_stage_info stg_info); + static void TaskStage_SetStage(stage_detail::TaskStage* a1, const task_stage_info stg_info); static void TaskStage_TaskWindAppend(stage_detail::TaskStage* a1); static void TaskStage_Unload(stage_detail::TaskStage* a1); } @@ -104,6 +102,53 @@ task_stage_info::task_stage_info() { load_counter = 0; } +task_stage_info::task_stage_info(int16_t load_index, uint16_t load_counter) { + this->load_index = load_index; + this->load_counter = load_counter; +} + +bool task_stage_info::check() const { + return task_stage_get_stage(*this) != 0; +} + +int32_t task_stage_info::get_stage_index() const { + stage* stg = task_stage_get_stage(*this); + if (stg) + return stg->index; + return -1; +} + +void task_stage_info::set_ground(bool value) const { + stage* stg = task_stage_get_stage(*this); + if (stg) + stg->ground = value; +} + +void task_stage_info::set_ring(bool value) const { + stage* stg = task_stage_get_stage(*this); + if (stg) + stg->ring = value; +} + +void task_stage_info::set_sky(bool value) const { + stage* stg = task_stage_get_stage(*this); + if (stg) + stg->sky = value; +} + +void task_stage_info::set_stage() const { + stage_detail::TaskStage_SetStage(task_stage, *this); +} + +void task_stage_info::set_stage_display(bool value, bool effect_enable) const { + stage* stg = task_stage_get_stage(*this); + if (stg) { + stg->stage_display = value; + if (effect_enable) + task_effect_parent_set_enable(value); + } +} + void task_stage_init() { task_stage = new stage_detail::TaskStage; } @@ -113,31 +158,27 @@ bool task_stage_check_not_loaded() { } void task_stage_current_set_ground(bool value) { - task_stage_info stg_info; - task_stage_get_current_stage_info(&stg_info); - if (task_stage_has_stage_info(&stg_info)) - task_stage_set_ground(&stg_info, value); + task_stage_info stg_info = task_stage_get_current_stage_info(); + if (stg_info.check()) + stg_info.set_ground(value); } void task_stage_current_set_ring(bool value) { - task_stage_info stg_info; - task_stage_get_current_stage_info(&stg_info); - if (task_stage_has_stage_info(&stg_info)) - task_stage_set_ring(&stg_info, value); + task_stage_info stg_info = task_stage_get_current_stage_info(); + if (stg_info.check()) + stg_info.set_ring(value); } void task_stage_current_set_sky(bool value) { - task_stage_info stg_info; - task_stage_get_current_stage_info(&stg_info); - if (task_stage_has_stage_info(&stg_info)) - task_stage_set_sky(&stg_info, value); + task_stage_info stg_info = task_stage_get_current_stage_info(); + if (stg_info.check()) + stg_info.set_sky(value); } void task_stage_current_set_stage_display(bool value, bool effect_enable) { - task_stage_info stg_info; - task_stage_get_current_stage_info(&stg_info); - if (task_stage_has_stage_info(&stg_info)) - task_stage_set_stage_display(&stg_info, value, effect_enable); + task_stage_info stg_info = task_stage_get_current_stage_info(); + if (stg_info.check()) + stg_info.set_stage_display(value, effect_enable); } void task_stage_disp_shadow() { @@ -149,74 +190,31 @@ stage* task_stage_get_current_stage() { } int32_t task_stage_get_current_stage_index() { - task_stage_info stg_info; - task_stage_get_current_stage_info(&stg_info); - if (task_stage_has_stage_info(&stg_info)) - return task_stage_get_stage_index(&stg_info); + task_stage_info stg_info = task_stage_get_current_stage_info(); + if (stg_info.check()) + return stg_info.get_stage_index(); return -1; } -void task_stage_get_current_stage_info(task_stage_info* stg_info) { - stage_detail::TaskStage_GetCurrentStageInfo(task_stage, stg_info); +task_stage_info task_stage_get_current_stage_info() { + return stage_detail::TaskStage_GetCurrentStageInfo(task_stage); } -void task_stage_get_loaded_stage_infos(std::vector* vec) { +void task_stage_get_loaded_stage_infos(std::vector& vec) { stage_detail::TaskStage_GetLoadedStageInfos(task_stage, vec); } -stage* task_stage_get_stage(task_stage_info stg_info) { +stage* task_stage_get_stage(const task_stage_info stg_info) { return stage_detail::TaskStage_GetStage(task_stage, stg_info); } -int32_t task_stage_get_stage_index(task_stage_info* stg_info) { - stage* stg = task_stage_get_stage(*stg_info); - if (stg) - return stg->index; - return -1; -} - -bool task_stage_has_stage_info(task_stage_info* stg_info) { - return task_stage_get_stage(*stg_info) != 0; -} - bool task_stage_load_task(const char* name) { task_stage_is_modern = false; return stage_detail::TaskStage_LoadTask(task_stage, name); } -void task_stage_set_ground(task_stage_info* stg_info, bool value) { - stage* stg = task_stage_get_stage(*stg_info); - if (stg) - stg->ground = value; -} - -void task_stage_set_mat(mat4* mat) { - task_stage->mat = *mat; -} - -void task_stage_set_ring(task_stage_info* stg_info, bool value) { - stage* stg = task_stage_get_stage(*stg_info); - if (stg) - stg->ring = value; -} - -void task_stage_set_sky(task_stage_info* stg_info, bool value) { - stage* stg = task_stage_get_stage(*stg_info); - if (stg) - stg->sky = value; -} - -void task_stage_set_stage(task_stage_info* stg_info) { - stage_detail::TaskStage_SetStage(task_stage, *stg_info); -} - -void task_stage_set_stage_display(task_stage_info* stg_info, bool value, bool effect_enable) { - stage* stg = task_stage_get_stage(*stg_info); - if (stg) { - stg->stage_display = value; - if (effect_enable) - task_effect_parent_set_enable(value); - } +void task_stage_set_mat(const mat4& mat) { + task_stage->mat = mat; } void task_stage_set_stage_index(int32_t stage_index) { @@ -232,7 +230,7 @@ void task_stage_set_stage_index(int32_t stage_index) { stage_indices.begin(), stage_indices.end()); } -void task_stage_set_stage_indices(std::vector& stage_indices) { +void task_stage_set_stage_indices(const std::vector& stage_indices) { task_stage->load_stage_indices.insert(task_stage->load_stage_indices.end(), stage_indices.begin(), stage_indices.end()); } @@ -280,7 +278,7 @@ static stage* stage_detail::TaskStage_GetCurrentStage(stage_detail::TaskStage* a return 0; } -static stage* stage_detail::TaskStage_GetStage(stage_detail::TaskStage* a1, task_stage_info stg_info) { +static stage* stage_detail::TaskStage_GetStage(stage_detail::TaskStage* a1, const task_stage_info stg_info) { if (stg_info.load_index >= 0 && stg_info.load_index <= TASK_STAGE_STAGE_COUNT) { stage* s = &a1->stages[stg_info.load_index]; if (s->index != -1 && s->counter == stg_info.load_counter) @@ -289,30 +287,23 @@ static stage* stage_detail::TaskStage_GetStage(stage_detail::TaskStage* a1, task return 0; } -static void stage_detail::TaskStage_GetTaskStageInfo(stage_detail::TaskStage* a1, - task_stage_info* stg_info, size_t index) { - *stg_info = {}; - if (index >= 0 && index < TASK_STAGE_STAGE_COUNT) { - stg_info->load_index = (int16_t)index; - stg_info->load_counter = a1->stages[index].counter; - } +static task_stage_info stage_detail::TaskStage_GetTaskStageInfo(stage_detail::TaskStage* a1, size_t index) { + if (index >= 0 && index < TASK_STAGE_STAGE_COUNT) + return { (int16_t)index, a1->stages[index].counter }; + return {}; } -static void stage_detail::TaskStage_GetCurrentStageInfo(stage_detail::TaskStage* a1, - task_stage_info* stg_info) { - stage_detail::TaskStage_GetTaskStageInfo(a1, stg_info, a1->current_stage); +static task_stage_info stage_detail::TaskStage_GetCurrentStageInfo(stage_detail::TaskStage* a1) { + return stage_detail::TaskStage_GetTaskStageInfo(a1, a1->current_stage); } static void stage_detail::TaskStage_GetLoadedStageInfos(stage_detail::TaskStage* a1, - std::vector* vec) { - vec->clear(); - vec->shrink_to_fit(); + std::vector& vec) { + vec.clear(); + vec.shrink_to_fit(); for (int32_t i = 0; i < TASK_STAGE_STAGE_COUNT; i++) - if (a1->stages[i].index != -1) { - task_stage_info stg_info; - stage_detail::TaskStage_GetTaskStageInfo(a1, &stg_info, i); - vec->push_back(stg_info); - } + if (a1->stages[i].index != -1) + vec.push_back(stage_detail::TaskStage_GetTaskStageInfo(a1, i)); } static void stage_detail::TaskStage_Load(stage_detail::TaskStage* a1) { @@ -345,9 +336,9 @@ static void stage_detail::TaskStage_Load(stage_detail::TaskStage* a1) { break; std::vector vec; - stage_detail::TaskStage_GetLoadedStageInfos(a1, &vec); + stage_detail::TaskStage_GetLoadedStageInfos(a1, vec); if (vec.size()) - stage_detail::TaskStage_SetStage(a1, vec[0]); + stage_detail::TaskStage_SetStage(a1, vec.front()); a1->state = 6; } break; } @@ -382,7 +373,7 @@ static void stage_detail::TaskStage_Reset(stage_detail::TaskStage* a1) { a1->field_FF8 = 0.0f; } -static void stage_detail::TaskStage_SetStage(stage_detail::TaskStage* a1, task_stage_info stg_info) { +static void stage_detail::TaskStage_SetStage(stage_detail::TaskStage* a1, const task_stage_info stg_info) { int16_t load_index = stg_info.load_index; stage* s = stage_detail::TaskStage_GetStage(a1, stg_info); stage* curr = stage_detail::TaskStage_GetCurrentStage(a1); diff --git a/src/CRE/stage.hpp b/src/CRE/stage.hpp index e21e7215..21c201cb 100644 --- a/src/CRE/stage.hpp +++ b/src/CRE/stage.hpp @@ -62,6 +62,15 @@ struct task_stage_info { uint16_t load_counter; task_stage_info(); + task_stage_info(int16_t load_index, uint16_t load_counter); + + bool check() const; + int32_t get_stage_index() const; + void set_ground(bool value) const; + void set_ring(bool value) const; + void set_sky(bool value) const; + void set_stage() const; + void set_stage_display(bool value, bool effect_enable) const; }; extern void task_stage_init(); @@ -73,19 +82,12 @@ extern void task_stage_current_set_stage_display(bool value, bool effect_enable) extern void task_stage_disp_shadow(); extern stage* task_stage_get_current_stage(); int32_t task_stage_get_current_stage_index(); -extern void task_stage_get_current_stage_info(task_stage_info* stg_info); -extern void task_stage_get_loaded_stage_infos(std::vector* vec); -extern stage* task_stage_get_stage(task_stage_info stg_info); -int32_t task_stage_get_stage_index(task_stage_info* stg_info); -extern bool task_stage_has_stage_info(task_stage_info* stg_info); +extern task_stage_info task_stage_get_current_stage_info(); +extern void task_stage_get_loaded_stage_infos(std::vector& vec); +extern stage* task_stage_get_stage(const task_stage_info stg_info); extern bool task_stage_load_task(const char* name); -extern void task_stage_set_ground(task_stage_info* stg_info, bool value); -extern void task_stage_set_mat(mat4* mat); -extern void task_stage_set_ring(task_stage_info* stg_info, bool value); -extern void task_stage_set_sky(task_stage_info* stg_info, bool value); -extern void task_stage_set_stage(task_stage_info* stg_info); -extern void task_stage_set_stage_display(task_stage_info* stg_info, bool value, bool effect_enable); +extern void task_stage_set_mat(const mat4& mat); extern void task_stage_set_stage_index(int32_t stage_index); -extern void task_stage_set_stage_indices(std::vector& stage_indices); +extern void task_stage_set_stage_indices(const std::vector& stage_indices); extern bool task_stage_unload_task(); extern void task_stage_free(); diff --git a/src/CRE/stage_modern.cpp b/src/CRE/stage_modern.cpp index c4348486..23ce4f21 100644 --- a/src/CRE/stage_modern.cpp +++ b/src/CRE/stage_modern.cpp @@ -16,17 +16,18 @@ namespace stage_detail { static void TaskStageModern_CtrlInner(stage_detail::TaskStageModern* a1); static void TaskStageModern_DispShadow(stage_detail::TaskStageModern* a1); static stage_modern* TaskStageModern_GetCurrentStage(stage_detail::TaskStageModern* a1); - static stage_modern* TaskStageModern_GetStage(stage_detail::TaskStageModern* a1, task_stage_modern_info stg_info); - static void TaskStageModern_GetTaskStageModernInfo(stage_detail::TaskStageModern* a1, - task_stage_modern_info* stg_info, size_t index); - static void TaskStageModern_GetCurrentStageInfo(stage_detail::TaskStageModern* a1, - task_stage_modern_info* stg_info); + static stage_modern* TaskStageModern_GetStage( + stage_detail::TaskStageModern* a1, const task_stage_modern_info stg_info); + static task_stage_modern_info TaskStageModern_GetTaskStageModernInfo( + stage_detail::TaskStageModern* a1, size_t index); + static task_stage_modern_info TaskStageModern_GetCurrentStageInfo(stage_detail::TaskStageModern* a1); static void TaskStageModern_GetLoadedStageInfos(stage_detail::TaskStageModern* a1, - std::vector* vec); + std::vector& vec); static void TaskStageModern_Load(stage_detail::TaskStageModern* a1); static bool TaskStageModern_LoadTask(stage_detail::TaskStageModern* a1, const char* name); static void TaskStageModern_Reset(stage_detail::TaskStageModern* a1); - static void TaskStageModern_SetStage(stage_detail::TaskStageModern* a1, task_stage_modern_info stg_info); + static void TaskStageModern_SetStage( + stage_detail::TaskStageModern* a1, const task_stage_modern_info stg_info); static void TaskStageModern_TaskWindAppend(stage_detail::TaskStageModern* a1); static void TaskStageModern_Unload(stage_detail::TaskStageModern* a1); } @@ -107,6 +108,47 @@ task_stage_modern_info::task_stage_modern_info() { load_counter = 0; } +task_stage_modern_info::task_stage_modern_info(int16_t load_index, uint16_t load_counter) { + this->load_index = load_index; + this->load_counter = load_counter; +} + +bool task_stage_modern_info::check() const { + return task_stage_modern_get_stage(*this) != 0; +} + +uint32_t task_stage_modern_info::get_stage_hash() const { + stage_modern* stg = task_stage_modern_get_stage(*this); + if (stg) + return stg->hash; + return -1; +} + +void task_stage_modern_info::set_ground(bool value) const { + stage_modern* stg = task_stage_modern_get_stage(*this); + if (stg) + stg->ground = value; +} + +void task_stage_modern_info::set_sky(bool value) const { + stage_modern* stg = task_stage_modern_get_stage(*this); + if (stg) + stg->sky = value; +} + +void task_stage_modern_info::set_stage() const { + stage_detail::TaskStageModern_SetStage(task_stage_modern, *this); +} + +void task_stage_modern_info::set_stage_display(bool value, bool effect_enable) const { + stage_modern* stg = task_stage_modern_get_stage(*this); + if (stg) { + stg->stage_display = value; + if (effect_enable) + task_effect_parent_set_enable(value); + } +} + void task_stage_modern_init() { task_stage_modern = new stage_detail::TaskStageModern; } @@ -120,24 +162,21 @@ bool task_stage_modern_check_task_ready() { } void task_stage_modern_current_set_ground(bool value) { - task_stage_modern_info stg_info; - task_stage_modern_get_current_stage_info(&stg_info); - if (task_stage_modern_has_stage_info(&stg_info)) - task_stage_modern_set_ground(&stg_info, value); + task_stage_modern_info stg_info = task_stage_modern_get_current_stage_info(); + if (stg_info.check()) + stg_info.set_ground(value); } void task_stage_modern_current_set_sky(bool value) { - task_stage_modern_info stg_info; - task_stage_modern_get_current_stage_info(&stg_info); - if (task_stage_modern_has_stage_info(&stg_info)) - task_stage_modern_set_sky(&stg_info, value); + task_stage_modern_info stg_info = task_stage_modern_get_current_stage_info(); + if (stg_info.check()) + stg_info.set_sky(value); } void task_stage_modern_current_set_stage_display(bool value, bool effect_enable) { - task_stage_modern_info stg_info; - task_stage_modern_get_current_stage_info(&stg_info); - if (task_stage_modern_has_stage_info(&stg_info)) - task_stage_modern_set_stage_display(&stg_info, value, effect_enable); + task_stage_modern_info stg_info = task_stage_modern_get_current_stage_info(); + if (stg_info.check()) + stg_info.set_stage_display(value, effect_enable); } void task_stage_modern_disp_shadow() { @@ -149,36 +188,24 @@ stage_modern* task_stage_modern_get_current_stage() { } uint32_t task_stage_modern_get_current_stage_hash() { - task_stage_modern_info stg_info; - task_stage_modern_get_current_stage_info(&stg_info); - if (task_stage_modern_has_stage_info(&stg_info)) - return task_stage_modern_get_stage_hash(&stg_info); + task_stage_modern_info stg_info = task_stage_modern_get_current_stage_info(); + if (stg_info.check()) + return stg_info.get_stage_hash(); return hash_murmurhash_empty; } -void task_stage_modern_get_current_stage_info(task_stage_modern_info* stg_info) { - stage_detail::TaskStageModern_GetCurrentStageInfo(task_stage_modern, stg_info); +task_stage_modern_info task_stage_modern_get_current_stage_info() { + return stage_detail::TaskStageModern_GetCurrentStageInfo(task_stage_modern); } -void task_stage_modern_get_loaded_stage_infos(std::vector* vec) { +void task_stage_modern_get_loaded_stage_infos(std::vector& vec) { stage_detail::TaskStageModern_GetLoadedStageInfos(task_stage_modern, vec); } -stage_modern* task_stage_modern_get_stage(task_stage_modern_info stg_info) { +stage_modern* task_stage_modern_get_stage(const task_stage_modern_info stg_info) { return stage_detail::TaskStageModern_GetStage(task_stage_modern, stg_info); } -uint32_t task_stage_modern_get_stage_hash(task_stage_modern_info* stg_info) { - stage_modern* stg = task_stage_modern_get_stage(*stg_info); - if (stg) - return stg->hash; - return -1; -} - -bool task_stage_modern_has_stage_info(task_stage_modern_info* stg_info) { - return task_stage_modern_get_stage(*stg_info) != 0; -} - bool task_stage_modern_load_task(const char* name) { task_stage_is_modern = true; return stage_detail::TaskStageModern_LoadTask(task_stage_modern, name); @@ -192,33 +219,8 @@ void task_stage_modern_set_data(void* data, task_stage_modern->stage_data = stage_data; } -void task_stage_modern_set_ground(task_stage_modern_info* stg_info, bool value) { - stage_modern* stg = task_stage_modern_get_stage(*stg_info); - if (stg) - stg->ground = value; -} - -void task_stage_modern_set_mat(mat4* mat) { - task_stage_modern->mat = *mat; -} - -void task_stage_modern_set_sky(task_stage_modern_info* stg_info, bool value) { - stage_modern* stg = task_stage_modern_get_stage(*stg_info); - if (stg) - stg->sky = value; -} - -void task_stage_modern_set_stage(task_stage_modern_info* stg_info) { - stage_detail::TaskStageModern_SetStage(task_stage_modern, *stg_info); -} - -void task_stage_modern_set_stage_display(task_stage_modern_info* stg_info, bool value, bool effect_enable) { - stage_modern* stg = task_stage_modern_get_stage(*stg_info); - if (stg) { - stg->stage_display = value; - if (effect_enable) - task_effect_parent_set_enable(value); - } +void task_stage_modern_set_mat(const mat4& mat) { + task_stage_modern->mat = mat; } void task_stage_modern_set_stage_hash(uint32_t stage_hash, stage_data_modern* stg_data) { @@ -286,7 +288,8 @@ static stage_modern* stage_detail::TaskStageModern_GetCurrentStage(stage_detail: return 0; } -static stage_modern* stage_detail::TaskStageModern_GetStage(stage_detail::TaskStageModern* a1, task_stage_modern_info stg_info) { +static stage_modern* stage_detail::TaskStageModern_GetStage( + stage_detail::TaskStageModern* a1, const task_stage_modern_info stg_info) { if (stg_info.load_index >= 0 && stg_info.load_index <= TASK_STAGE_STAGE_COUNT) { stage_modern* s = &a1->stages[stg_info.load_index]; if (s->hash != -1 && s->hash != hash_murmurhash_empty @@ -296,30 +299,24 @@ static stage_modern* stage_detail::TaskStageModern_GetStage(stage_detail::TaskSt return 0; } -static void stage_detail::TaskStageModern_GetTaskStageModernInfo(stage_detail::TaskStageModern* a1, - task_stage_modern_info* stg_info, size_t index) { - *stg_info = {}; - if (index >= 0 && index < TASK_STAGE_STAGE_COUNT) { - stg_info->load_index = (int16_t)index; - stg_info->load_counter = a1->stages[index].counter; - } +static task_stage_modern_info stage_detail::TaskStageModern_GetTaskStageModernInfo( + stage_detail::TaskStageModern* a1, size_t index) { + if (index >= 0 && index < TASK_STAGE_STAGE_COUNT) + return { (int16_t)index, a1->stages[index].counter }; + return {}; } -static void stage_detail::TaskStageModern_GetCurrentStageInfo(stage_detail::TaskStageModern* a1, - task_stage_modern_info* stg_info) { - stage_detail::TaskStageModern_GetTaskStageModernInfo(a1, stg_info, a1->current_stage); +static task_stage_modern_info stage_detail::TaskStageModern_GetCurrentStageInfo(stage_detail::TaskStageModern* a1) { + return stage_detail::TaskStageModern_GetTaskStageModernInfo(a1, a1->current_stage); } static void stage_detail::TaskStageModern_GetLoadedStageInfos(stage_detail::TaskStageModern* a1, - std::vector* vec) { - vec->clear(); - vec->shrink_to_fit(); + std::vector& vec) { + vec.clear(); + vec.shrink_to_fit(); for (int32_t i = 0; i < TASK_STAGE_STAGE_COUNT; i++) - if (a1->stages[i].hash != -1 && a1->stages[i].hash != hash_murmurhash_empty) { - task_stage_modern_info stg_info; - stage_detail::TaskStageModern_GetTaskStageModernInfo(a1, &stg_info, i); - vec->push_back(stg_info); - } + if (a1->stages[i].hash != -1 && a1->stages[i].hash != hash_murmurhash_empty) + vec.push_back(stage_detail::TaskStageModern_GetTaskStageModernInfo(a1, i)); } static void stage_detail::TaskStageModern_Load(stage_detail::TaskStageModern* a1) { @@ -353,9 +350,9 @@ static void stage_detail::TaskStageModern_Load(stage_detail::TaskStageModern* a1 break; std::vector vec; - stage_detail::TaskStageModern_GetLoadedStageInfos(a1, &vec); + stage_detail::TaskStageModern_GetLoadedStageInfos(a1, vec); if (vec.size()) - stage_detail::TaskStageModern_SetStage(a1, vec[0]); + stage_detail::TaskStageModern_SetStage(a1, vec.front()); a1->state = 6; } break; } @@ -391,7 +388,8 @@ static void stage_detail::TaskStageModern_Reset(stage_detail::TaskStageModern* a a1->field_FF8 = 0.0f; } -static void stage_detail::TaskStageModern_SetStage(stage_detail::TaskStageModern* a1, task_stage_modern_info stg_info) { +static void stage_detail::TaskStageModern_SetStage( + stage_detail::TaskStageModern* a1, const task_stage_modern_info stg_info) { int16_t load_index = stg_info.load_index; stage_modern* s = stage_detail::TaskStageModern_GetStage(a1, stg_info); stage_modern* curr = stage_detail::TaskStageModern_GetCurrentStage(a1); diff --git a/src/CRE/stage_modern.hpp b/src/CRE/stage_modern.hpp index 9042b391..884b21c1 100644 --- a/src/CRE/stage_modern.hpp +++ b/src/CRE/stage_modern.hpp @@ -66,6 +66,14 @@ struct task_stage_modern_info { uint16_t load_counter; task_stage_modern_info(); + task_stage_modern_info(int16_t load_index, uint16_t load_counter); + + bool check() const; + uint32_t get_stage_hash() const; + void set_ground(bool value) const; + void set_sky(bool value) const; + void set_stage() const; + void set_stage_display(bool value, bool effect_enable) const; }; extern void task_stage_modern_init(); @@ -77,19 +85,14 @@ extern void task_stage_modern_current_set_stage_display(bool value, bool effect_ extern void task_stage_modern_disp_shadow(); extern stage_modern* task_stage_modern_get_current_stage(); extern uint32_t task_stage_modern_get_current_stage_hash(); -extern void task_stage_modern_get_current_stage_info(task_stage_modern_info* stg_info); -extern void task_stage_modern_get_loaded_stage_infos(std::vector* vec); -extern stage_modern* task_stage_modern_get_stage(task_stage_modern_info stg_info); -extern uint32_t task_stage_modern_get_stage_hash(task_stage_modern_info* stg_info); -extern bool task_stage_modern_has_stage_info(task_stage_modern_info* stg_info); +extern task_stage_modern_info task_stage_modern_get_current_stage_info(); +extern void task_stage_modern_get_loaded_stage_infos(std::vector& vec); +extern stage_modern* task_stage_modern_get_stage(const task_stage_modern_info stg_info); extern bool task_stage_modern_load_task(const char* name); extern void task_stage_modern_set_data(void* data, object_database* obj_db, texture_database* tex_db, stage_database* stage_data); -extern void task_stage_modern_set_ground(task_stage_modern_info* stg_info, bool value); -extern void task_stage_modern_set_mat(mat4* mat); -extern void task_stage_modern_set_sky(task_stage_modern_info* stg_info, bool value); -extern void task_stage_modern_set_stage(task_stage_modern_info* stg_info); -extern void task_stage_modern_set_stage_display(task_stage_modern_info* stg_info, bool value, bool effect_enable); + +extern void task_stage_modern_set_mat(const mat4& mat); extern void task_stage_modern_set_stage_hash(uint32_t stage_hash, stage_data_modern* stg_data); extern void task_stage_modern_set_stage_hashes(std::vector& stage_hashes, std::vector& load_stage_data); diff --git a/src/CRE/task_effect.cpp b/src/CRE/task_effect.cpp index 9b4a035a..5cf05b4f 100644 --- a/src/CRE/task_effect.cpp +++ b/src/CRE/task_effect.cpp @@ -484,7 +484,7 @@ bool TaskEffectAuth3D::Ctrl() { * (float_t)(2.0 / 512.0)) * M_PI)) * 0.015f, &mat); mat4_rotate_z_mult(&mat, sinf((float_t)((double_t)((float_t)(frame_int % 360) * (float_t)(2.0 / 360.0)) * M_PI)) * 0.015f, &mat); - task_stage_set_mat(&mat); + task_stage_set_mat(mat); } return false; } @@ -1091,6 +1091,21 @@ void TaskEffectFogRing::Data::SetStageIndices(std::vector& stage_indice const size_t max_ptcls_vtx_count = (size_t)max_ptcls * 0x06; + if (ptcl_data) { + free(ptcl_data); + ptcl_data = 0; + } + + if (vao) { + glDeleteVertexArrays(1, &vao); + vao = 0; + } + + if (vbo) { + glDeleteBuffers(1, &vbo); + vbo = 0; + } + ptcl_data = force_malloc_s(fog_ring_data, max_ptcls); ptcl_data = new (ptcl_data) fog_ring_data[max_ptcls]; @@ -2048,7 +2063,7 @@ void ripple_emit::sub_1403587C0(const vec3 a2, const vec3 a3, float_t a4, struc_ v23 = 0.01f; v24 = 0.0f; } - + int32_t v33 = v20 - (int32_t)(v23 * -20.0f); int32_t v37 = (int32_t)(a4 * 60.0f); int32_t v27 = v33 >= v37 ? v37 : v33; @@ -2432,7 +2447,7 @@ void task_effect_init() { if (!task_effect_parent) task_effect_parent = new TaskEffectParent; - + if (!ripple_emit_data) ripple_emit_data = new ripple_emit; @@ -3087,7 +3102,7 @@ static void draw_ripple_emit(render_context* rctx, struc_101* data) { shader_data.g_transform.z = 0.0079498291f / (float_t)(width - 2); shader_data.g_transform.w = -0.0079498291f / (float_t)(height - 2); shader_data.g_framebuffer_size = { - 1.0f / (float_t)width, + 1.0f / (float_t)width, 1.0f / (float_t)height, 0.0f, 0.0f }; ripple_emit_scene_ubo.WriteMapMemory(shader_data); @@ -3394,8 +3409,7 @@ static void leaf_particle_free() { } static void particle_init(vec3* offset) { - if (ptcl_data) - delete[] ptcl_data; + particle_free(); const size_t ptcl_vtx_count = ptcl_count * 0x06; @@ -3676,6 +3690,8 @@ static void rain_particle_init(bool change_stage) { if (change_stage) return; + rain_particle_free(); + if (!rain_ptcl_vao) glGenVertexArrays(1, &rain_ptcl_vao); @@ -3848,7 +3864,7 @@ static void sub_1403B6F60(GLuint a1, GLuint a2, GLuint a3, ripple_emit_params& p }; ripple_scene.g_texcoord = { 1.0f, 0.0f, 0.0f, 0.0f }; ripple_scene_ubo.WriteMapMemory(ripple_scene); - + ripple_batch_shader_data ripple_batch = {}; ripple_batch.g_params = { params.wake_attn, params.speed, params.field_8, params.field_C }; ripple_batch_ubo.WriteMapMemory(ripple_batch); diff --git a/src/KKdLib/database/aet.cpp b/src/KKdLib/database/aet.cpp index 0bffa7d1..fab74342 100644 --- a/src/KKdLib/database/aet.cpp +++ b/src/KKdLib/database/aet.cpp @@ -490,6 +490,10 @@ const char* aet_database::get_aet_set_name(uint32_t set_id) const { return get_aet_set_by_id(set_id)->name.c_str(); } +uint32_t aet_database::get_aet_id_by_name(const char* name) const { + return get_aet_by_name(name)->id; +} + static void aet_database_file_classic_read_inner(aet_database_file* aet_db, stream& s) { uint32_t aet_sets_count = s.read_uint32_t(); uint32_t aet_sets_offset = s.read_uint32_t(); diff --git a/src/KKdLib/database/aet.hpp b/src/KKdLib/database/aet.hpp index 0289abbe..ef1e91da 100644 --- a/src/KKdLib/database/aet.hpp +++ b/src/KKdLib/database/aet.hpp @@ -156,4 +156,5 @@ struct aet_database { uint32_t get_aet_set_id_by_name(const char* name) const; uint32_t get_aet_set_id_by_name_index(uint32_t index) const; const char* get_aet_set_name(uint32_t set_id) const; + uint32_t get_aet_id_by_name(const char* name) const; }; diff --git a/src/KKdLib/database/auth_3d.cpp b/src/KKdLib/database/auth_3d.cpp index 30993936..2188cedf 100644 --- a/src/KKdLib/database/auth_3d.cpp +++ b/src/KKdLib/database/auth_3d.cpp @@ -256,22 +256,21 @@ static void auth_3d_database_load_uids(auth_3d_database* auth_3d_db, if (uid_file->value.c_str()[0] == 'A') uid->enabled = true; - uid->name = uid_file->value.substr(2, uid_file->value.size() - 2); + uid->name.assign(uid_file->value.substr(2, uid_file->value.size() - 2)); uid->name_hash = hash_string_murmurhash(uid->name); - uid->category = uid_file->category; + uid->category.assign(uid_file->category); uid->category_hash = hash_string_murmurhash(uid->category); } if (uid->enabled) { - uid_file->category = uid->category; - - if (uid->category.size() > 0) { - std::string& cat_file = uid->category; + uid_file->category.assign(uid->category); + if (uid->category.size() > 0) for (auth_3d_database_category& j : category) - if (!cat_file.compare(j.name)) + if (!uid->category.compare(j.name)) { j.uid.push_back(org_uid); - } + break; + } } if (uid_file->flags & AUTH_3D_DATABASE_UID_SIZE) diff --git a/src/KKdLib/divafile.cpp b/src/KKdLib/divafile.cpp index 3802ed9c..b0217a0f 100644 --- a/src/KKdLib/divafile.cpp +++ b/src/KKdLib/divafile.cpp @@ -97,8 +97,6 @@ namespace divafile { dec.open(data, file_length); free_def(data); } - void decrypt(memory_stream& s) { - } void encrypt(const char* path) { wchar_t* file_buf = utf8_to_utf16(path); diff --git a/src/KKdLib/dsc.cpp b/src/KKdLib/dsc.cpp index ab0c9b77..faf3aa93 100644 --- a/src/KKdLib/dsc.cpp +++ b/src/KKdLib/dsc.cpp @@ -1640,9 +1640,63 @@ static void dsc_convert_from_ac100_effect(dsc_replace* dr, dsc_replace_data* drd } static void dsc_convert_from_ac100_expression(dsc_replace* dr, dsc_replace_data* drd, uint32_t* data) { + int32_t expression_id; + switch (data[0]) { + case 0: + expression_id = 52; + break; + case 1: + expression_id = 66; + break; + case 2: + expression_id = 65; + break; + case 3: + expression_id = 53; + break; + case 4: + expression_id = 4; + break; + case 5: + expression_id = 68; + break; + case 6: + expression_id = 54; + break; + case 7: + expression_id = 70; + break; + case 8: + expression_id = 55; + break; + case 9: + expression_id = 56; + break; + case 10: + expression_id = 57; + break; + case 11: + expression_id = 58; + break; + case 12: + expression_id = 59; + break; + case 13: + expression_id = 72; + break; + case 14: + expression_id = 73; + break; + case 15: + expression_id = 23; + break; + default: + return; + } + uint32_t* expression = dsc_replace_add_func(dr, drd); expression[0] = 0; - expression[1] = data[0]; + expression[1] = expression_id; expression[2] = data[1]; expression[3] = data[2]; } @@ -1655,9 +1709,51 @@ static void dsc_convert_from_ac100_eye_anim(dsc_replace* dr, dsc_replace_data* d } static void dsc_convert_from_ac100_hand_anim(dsc_replace* dr, dsc_replace_data* drd, uint32_t* data) { + int32_t hand_anim_id; + switch (data[0]) { + case 0: + hand_anim_id = 0; + break; + case 1: + hand_anim_id = 1; + break; + case 2: + hand_anim_id = 2; + break; + case 3: + hand_anim_id = 3; + break; + case 4: + hand_anim_id = 4; + break; + case 5: + hand_anim_id = 5; + break; + case 6: + hand_anim_id = 6; + break; + case 7: + hand_anim_id = 14; + break; + case 8: + hand_anim_id = 9; + break; + case 9: + hand_anim_id = 10; + break; + case 10: + hand_anim_id = 12; + break; + case 11: + hand_anim_id = 13; + break; + default: + return; + } + uint32_t* hand_anim = dsc_replace_add_func(dr, drd); hand_anim[0] = 0; - hand_anim[1] = data[0]; + hand_anim[1] = hand_anim_id; hand_anim[2] = data[1]; hand_anim[3] = data[2]; hand_anim[4] = data[3]; @@ -1719,10 +1815,46 @@ static void dsc_convert_from_ac100_mode_select(dsc_replace* dr, dsc_replace_data } static void dsc_convert_from_ac100_mouth_anim(dsc_replace* dr, dsc_replace_data* drd, uint32_t* data) { + int32_t mouth_anim_id; + switch (data[0]) { + case 0: + mouth_anim_id = 24; + break; + case 1: + mouth_anim_id = 31; + break; + case 2: + mouth_anim_id = 25; + break; + case 3: + mouth_anim_id = 26; + break; + case 4: + mouth_anim_id = 27; + break; + case 5: + mouth_anim_id = 32; + break; + case 6: + mouth_anim_id = 28; + break; + case 7: + mouth_anim_id = 9; + break; + case 8: + mouth_anim_id = 29; + break; + case 9: + mouth_anim_id = 30; + break; + default: + return; + } + uint32_t* mouth_anim = dsc_replace_add_func(dr, drd); mouth_anim[0] = 0; mouth_anim[1] = 0; - mouth_anim[2] = data[0]; + mouth_anim[2] = mouth_anim_id; mouth_anim[3] = data[1]; mouth_anim[4] = data[2]; } @@ -1797,8 +1929,62 @@ static void dsc_convert_to_ac100_expression(dsc_replace* dr, dsc_replace_data* d if (data[0]) return; + int32_t expression_id; + switch (data[1]) { + case 52: + expression_id = 0; + break; + case 66: + expression_id = 1; + break; + case 65: + expression_id = 2; + break; + case 53: + expression_id = 3; + break; + case 4: + expression_id = 4; + break; + case 68: + expression_id = 5; + break; + case 54: + expression_id = 6; + break; + case 70: + expression_id = 7; + break; + case 55: + expression_id = 8; + break; + case 56: + expression_id = 9; + break; + case 57: + expression_id = 10; + break; + case 58: + expression_id = 11; + break; + case 59: + expression_id = 12; + break; + case 72: + expression_id = 13; + break; + case 73: + expression_id = 14; + break; + case 24: + expression_id = 15; + break; + default: + return; + } + uint32_t* expression = dsc_replace_add_func(dr, drd); - expression[0] = data[1]; + expression[0] = expression_id; expression[1] = data[2]; expression[2] = data[3]; expression[3] = data[4]; @@ -1817,8 +2003,50 @@ static void dsc_convert_to_ac100_hand_anim(dsc_replace* dr, dsc_replace_data* dr if (data[0]) return; + int32_t hand_anim_id; + switch (data[1]) { + case 0: + hand_anim_id = 0; + break; + case 1: + hand_anim_id = 1; + break; + case 2: + hand_anim_id = 2; + break; + case 3: + hand_anim_id = 3; + break; + case 4: + hand_anim_id = 4; + break; + case 5: + hand_anim_id = 5; + break; + case 6: + hand_anim_id = 6; + break; + case 14: + hand_anim_id = 7; + break; + case 9: + hand_anim_id = 8; + break; + case 10: + hand_anim_id = 9; + break; + case 12: + hand_anim_id = 10; + break; + case 13: + hand_anim_id = 11; + break; + default: + return; + } + uint32_t* hand_anim = dsc_replace_add_func(dr, drd); - hand_anim[0] = data[1]; + hand_anim[0] = hand_anim_id; hand_anim[1] = data[2]; hand_anim[2] = data[3]; hand_anim[3] = data[4]; @@ -1893,8 +2121,44 @@ static void dsc_convert_to_ac100_mouth_anim(dsc_replace* dr, dsc_replace_data* d if (data[0]) return; + int32_t mouth_anim_id; + switch (data[2]) { + case 24: + mouth_anim_id = 0; + break; + case 31: + mouth_anim_id = 1; + break; + case 25: + mouth_anim_id = 2; + break; + case 26: + mouth_anim_id = 3; + break; + case 27: + mouth_anim_id = 4; + break; + case 32: + mouth_anim_id = 5; + break; + case 28: + mouth_anim_id = 6; + break; + case 9: + mouth_anim_id = 7; + break; + case 29: + mouth_anim_id = 8; + break; + case 30: + mouth_anim_id = 9; + break; + default: + return; + } + uint32_t* mouth_anim = dsc_replace_add_func(dr, drd); - mouth_anim[0] = data[2]; + mouth_anim[0] = mouth_anim_id; mouth_anim[1] = data[3]; mouth_anim[2] = data[4]; } @@ -1960,10 +2224,10 @@ static void dsc_convert_note7_to_note11(dsc_replace* dr, dsc_replace_data* drd, note11->type = dn->type; note11->hold_timer = -1; note11->hold_end = -1; - note11->x_pos = dn->x_pos; - note11->y_pos = dn->y_pos; + note11->pos_x = dn->pos_x; + note11->pos_y = dn->pos_y; note11->angle = dn->angle; - note11->wave_count = dn->wave_count; + note11->frequency = dn->frequency; note11->distance = dn->distance; note11->amplitude = dn->amplitude; note11->target_flying_time = dr->target_flying_time; @@ -1976,10 +2240,10 @@ static void dsc_convert_note7_to_note12(dsc_replace* dr, dsc_replace_data* drd, note12->type = dn->type; note12->hold_timer = -1; note12->hold_end = -1; - note12->x_pos = dn->x_pos; - note12->y_pos = dn->y_pos; + note12->pos_x = dn->pos_x; + note12->pos_y = dn->pos_y; note12->angle = dn->angle; - note12->wave_count = dn->wave_count; + note12->frequency = dn->frequency; note12->distance = dn->distance; note12->amplitude = dn->amplitude; note12->target_flying_time = dr->target_flying_time; @@ -2008,12 +2272,12 @@ static void dsc_convert_note11_to_note7(dsc_replace* dr, dsc_replace_data* drd, dsc_note7* note7 = (dsc_note7*)dsc_replace_add_func(dr, drd); note7->type = dn->type; - note7->x_pos = dn->x_pos; - note7->y_pos = dn->y_pos; + note7->pos_x = dn->pos_x; + note7->pos_y = dn->pos_y; note7->angle = dn->angle; note7->distance = dn->distance; note7->amplitude = dn->amplitude; - note7->wave_count = dn->wave_count; + note7->frequency = dn->frequency; } static void dsc_convert_note11_to_note12(dsc_replace* dr, dsc_replace_data* drd, uint32_t* data) { @@ -2022,10 +2286,10 @@ static void dsc_convert_note11_to_note12(dsc_replace* dr, dsc_replace_data* drd, note12->type = dn->type; note12->hold_timer = dn->hold_timer; note12->hold_end = dn->hold_end; - note12->x_pos = dn->x_pos; - note12->y_pos = dn->y_pos; + note12->pos_x = dn->pos_x; + note12->pos_y = dn->pos_y; note12->angle = dn->angle; - note12->wave_count = dn->wave_count; + note12->frequency = dn->frequency; note12->distance = dn->distance; note12->amplitude = dn->amplitude; note12->target_flying_time = dn->target_flying_time; @@ -2054,12 +2318,12 @@ static void dsc_convert_note12_to_note7(dsc_replace* dr, dsc_replace_data* drd, dsc_note7* note7 = (dsc_note7*)dsc_replace_add_func(dr, drd); note7->type = dn->type; - note7->x_pos = dn->x_pos; - note7->y_pos = dn->y_pos; + note7->pos_x = dn->pos_x; + note7->pos_y = dn->pos_y; note7->angle = dn->angle; note7->distance = dn->distance; note7->amplitude = dn->amplitude; - note7->wave_count = dn->wave_count; + note7->frequency = dn->frequency; } static void dsc_convert_note12_to_note11(dsc_replace* dr, dsc_replace_data* drd, uint32_t* data) { @@ -2068,10 +2332,10 @@ static void dsc_convert_note12_to_note11(dsc_replace* dr, dsc_replace_data* drd, note11->type = dn->type; note11->hold_timer = dn->hold_timer; note11->hold_end = dn->hold_end; - note11->x_pos = dn->x_pos; - note11->y_pos = dn->y_pos; + note11->pos_x = dn->pos_x; + note11->pos_y = dn->pos_y; note11->angle = dn->angle; - note11->wave_count = dn->wave_count; + note11->frequency = dn->frequency; note11->distance = dn->distance; note11->amplitude = dn->amplitude; note11->target_flying_time = dn->target_flying_time; @@ -2760,7 +3024,7 @@ bool dsc::parse(const void* data, size_t size, dsc_type type) { default: if (*data_dsc >= 0x10000000) { signature = *data_dsc++; - size--; + size -= 4; } break; case DSC_F: diff --git a/src/KKdLib/dsc.hpp b/src/KKdLib/dsc.hpp index 44f676ac..9b9fdc2e 100644 --- a/src/KKdLib/dsc.hpp +++ b/src/KKdLib/dsc.hpp @@ -53,22 +53,22 @@ enum dsc_type { #pragma region dsc_note struct dsc_note7 { int32_t type; - int32_t x_pos; - int32_t y_pos; + int32_t pos_x; + int32_t pos_y; int32_t angle; int32_t distance; int32_t amplitude; - int32_t wave_count; + int32_t frequency; }; struct dsc_note11 { int32_t type; int32_t hold_timer; int32_t hold_end; - int32_t x_pos; - int32_t y_pos; + int32_t pos_x; + int32_t pos_y; int32_t angle; - int32_t wave_count; + int32_t frequency; int32_t distance; int32_t amplitude; int32_t target_flying_time; @@ -79,10 +79,10 @@ struct dsc_note12 { int32_t type; int32_t hold_timer; int32_t hold_end; - int32_t x_pos; - int32_t y_pos; + int32_t pos_x; + int32_t pos_y; int32_t angle; - int32_t wave_count; + int32_t frequency; int32_t distance; int32_t amplitude; int32_t target_flying_time; @@ -119,6 +119,7 @@ enum dsc_target_ac { DSC_TARGET_AC_RANDOM = 0x08, DSC_TARGET_AC_RANDOM_HOLD = 0x09, DSC_TARGET_AC_PREVIOUS = 0x0A, + DSC_TARGET_AC_MAX = 0x0B, }; enum dsc_target_ft { @@ -133,8 +134,10 @@ enum dsc_target_ac { DSC_TARGET_FT_RANDOM = 0x08, DSC_TARGET_FT_RANDOM_HOLD = 0x09, DSC_TARGET_FT_PREVIOUS = 0x0A, + DSC_TARGET_FT_0B = 0x0B, DSC_TARGET_FT_SLIDE_L = 0x0C, DSC_TARGET_FT_SLIDE_R = 0x0D, + DSC_TARGET_FT_0E = 0x0E, DSC_TARGET_FT_SLIDE_CHAIN_L = 0x0F, DSC_TARGET_FT_SLIDE_CHAIN_R = 0x10, DSC_TARGET_FT_GREEN_SQUARE = 0x11, @@ -142,8 +145,10 @@ enum dsc_target_ac { DSC_TARGET_FT_CIRCLE_CHANCE = 0x13, DSC_TARGET_FT_CROSS_CHANCE = 0x14, DSC_TARGET_FT_SQUARE_CHANCE = 0x15, + DSC_TARGET_FT_16 = 0x16, DSC_TARGET_FT_SLIDE_L_CHANCE = 0x17, DSC_TARGET_FT_SLIDE_R_CHANCE = 0x18, + DSC_TARGET_FT_MAX = 0x19, }; enum dsc_target_dt { @@ -159,6 +164,7 @@ enum dsc_target_dt { DSC_TARGET_DT_CIRCLE_HOLD = 0x09, DSC_TARGET_DT_CROSS_HOLD = 0x0A, DSC_TARGET_DT_SQUARE_HOLD = 0x0B, + DSC_TARGET_DT_MAX = 0x0C, }; enum dsc_target_f { @@ -183,6 +189,7 @@ enum dsc_target_f { DSC_TARGET_F_STAR_RIGHT = 0x13, DSC_TARGET_F_STAR_DOWN = 0x14, DSC_TARGET_F_STAR_LEFT = 0x15, + DSC_TARGET_F_MAX = 0x16, }; enum dsc_target_f2 { @@ -205,6 +212,7 @@ enum dsc_target_f2 { DSC_TARGET_F2_EDIT_CHANCE_STAR = 0x10, DSC_TARGET_F2_LINK_STAR = 0x16, DSC_TARGET_F2_LINK_STAR_END = 0x17, + DSC_TARGET_F2_MAX = 0x18, }; enum dsc_target_mgf { @@ -232,6 +240,7 @@ enum dsc_target_mgf { DSC_TARGET_MGF_CIRCLE_FEVER_HOLD = 0x2A, DSC_TARGET_MGF_CROSS_FEVER_HOLD = 0x2B, DSC_TARGET_MGF_SQUARE_FEVER_HOLD = 0x2C, + DSC_TARGET_MGF_MAX = 0x2D, }; enum dsc_target_id_x { @@ -260,6 +269,7 @@ enum dsc_target_id_x { DSC_TARGET_X_CIRCLE_RUSH = 0x1A, DSC_TARGET_X_CROSS_RUSH = 0x1B, DSC_TARGET_X_SQUARE_RUSH = 0x1C, + DSC_TARGET_X_MAX = 0x1D, }; #pragma endregion diff --git a/src/KKdLib/io/json.cpp b/src/KKdLib/io/json.cpp index a9ad49ed..a5ebd6b3 100644 --- a/src/KKdLib/io/json.cpp +++ b/src/KKdLib/io/json.cpp @@ -17,10 +17,11 @@ static int32_t io_json_read_char(stream& s, io_json_read_buffer* buf); static void io_json_seek(stream& s, io_json_read_buffer* buf, int64_t offset); static void io_json_seek_one(stream& s, io_json_read_buffer* buf); static void io_json_read_inner(stream& s, io_json_read_buffer* buf, msgpack* msg, int32_t* c); -static void io_json_read_digit(stream& s, io_json_read_buffer* buf, int32_t* c, char** dig_buf, char* dig_buf_end); +static void io_json_read_digit(stream& s, io_json_read_buffer* buf, + int32_t* c, char* dig_buf, size_t* dig_buf_pos, size_t dig_buf_end); static void io_json_read_float(stream& s, io_json_read_buffer* buf, msgpack* msg, int32_t* c); static uint8_t io_json_read_string_hex(int32_t c); -static char* io_json_read_string_inner(stream& s, io_json_read_buffer* buf, msgpack* msg, int32_t* c); +static char* io_json_read_string_inner(stream& s, io_json_read_buffer* buf, int32_t* c); static void io_json_read_string(stream& s, io_json_read_buffer* buf, msgpack* msg, int32_t* c); static void io_json_read_map(stream& s, io_json_read_buffer* buf, msgpack* msg, int32_t* c); static void io_json_read_array(stream& s, io_json_read_buffer* buf, msgpack* msg, int32_t* c); @@ -110,84 +111,88 @@ inline static void io_json_seek_one(stream& s, io_json_read_buffer* buf) { static void io_json_read_inner(stream& s, io_json_read_buffer* buf, msgpack* msg, int32_t* c) { *msg = {}; - while (*c != EOF) { - if (CHECK_WHITESPACE(*c)) - *c = io_json_read_char(s, buf); - - if (*c >= '0' && *c <= '9') { - io_json_read_float(s, buf, msg, c); - return; - } - - switch (*c) { - case '\"': - io_json_read_string(s, buf, msg, c); - break; - case '{': - io_json_read_map(s, buf, msg, c); - break; - case '[': - io_json_read_array(s, buf, msg, c); - break; - case '-': - io_json_read_float(s, buf, msg, c); - break; - case 't': - io_json_read_bool(s, buf, msg, c); - break; - case 'f': - io_json_read_bool(s, buf, msg, c); - break; - case 'n': - io_json_read_null(s, buf, msg, c); - break; - } + if (*c == EOF) return; + + if (CHECK_WHITESPACE(*c)) + *c = io_json_read_char(s, buf); + + switch (*c) { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + case '-': + io_json_read_float(s, buf, msg, c); + break; + case '"': + io_json_read_string(s, buf, msg, c); + break; + case '{': + io_json_read_map(s, buf, msg, c); + break; + case '[': + io_json_read_array(s, buf, msg, c); + break; + case 't': + io_json_read_bool(s, buf, msg, c); + break; + case 'f': + io_json_read_bool(s, buf, msg, c); + break; + case 'n': + io_json_read_null(s, buf, msg, c); + break; } } -inline static void io_json_read_digit(stream& s, io_json_read_buffer* buf, int32_t* c, char** dig_buf, char* dig_buf_end) { - char* b = *dig_buf; +inline static void io_json_read_digit(stream& s, io_json_read_buffer* buf, + int32_t* c, char* dig_buf, size_t* dig_buf_pos, size_t dig_buf_end) { + size_t b = *dig_buf_pos; while (*c >= '0' && *c <= '9' && b < dig_buf_end) { - *b++ = *c; + dig_buf[b++] = *c; if ((*c = io_json_read_char(s, buf)) == EOF) break; } - *dig_buf = b; + *dig_buf_pos = b; } static void io_json_read_float(stream& s, io_json_read_buffer* buf, msgpack* msg, int32_t* c) { char dig_buf[0x100]; - char* t_buf = dig_buf; - char* buf_end = dig_buf + 0x100; + size_t buf_pos = 0; + size_t buf_end = 0x100; bool negate = false; bool zero = false; bool fraction = false; memset(dig_buf, 0, 0x100); if (*c == '-') { - *t_buf++ = *c; + dig_buf[buf_pos++] = *c; if ((*c = io_json_read_char(s, buf)) == EOF) return; negate = true; } if (*c == '0') { - *t_buf++ = *c; + dig_buf[buf_pos++] = *c; if ((*c = io_json_read_char(s, buf)) == EOF) return; zero = true; } else - io_json_read_digit(s, buf, c, &t_buf, buf_end); + io_json_read_digit(s, buf, c, dig_buf, &buf_pos, buf_end); - bool f = false; if (*c == '.') { - f = true; - *t_buf++ = *c; + dig_buf[buf_pos++] = *c; if ((*c = io_json_read_char(s, buf)) == EOF) return; - io_json_read_digit(s, buf, c, &t_buf, buf_end); + io_json_read_digit(s, buf, c, dig_buf, &buf_pos, buf_end); fraction = true; } @@ -199,7 +204,7 @@ static void io_json_read_float(stream& s, io_json_read_buffer* buf, msgpack* msg io_json_seek_one(s, buf); return; } - else if (*c != 'e' && *c != 'E' && !f) { + else if (*c != 'e' && *c != 'E' && !fraction) { int64_t val; if (sscanf_s(dig_buf, "%lli", &val) == EOF) return; @@ -222,16 +227,16 @@ static void io_json_read_float(stream& s, io_json_read_buffer* buf, msgpack* msg return; } else if (*c == 'e' || *c == 'E') { - *t_buf++ = *c; + dig_buf[buf_pos++] = *c; if ((*c = io_json_read_char(s, buf)) == EOF) return; if (*c == '+' || *c == '-') { - *t_buf++ = *c; + dig_buf[buf_pos++] = *c; if ((*c = io_json_read_char(s, buf)) == EOF) return; } - io_json_read_digit(s, buf, c, &t_buf, buf_end); + io_json_read_digit(s, buf, c, dig_buf, &buf_pos, buf_end); } double_t val; @@ -239,7 +244,7 @@ static void io_json_read_float(stream& s, io_json_read_buffer* buf, msgpack* msg if (sscanf_s(dig_buf, "%lg", &val) == EOF) return; - if ((float_t)val == val) + if (val == (float_t)val) *msg = (float_t)val; else *msg = val; @@ -257,7 +262,7 @@ inline static uint8_t io_json_read_string_hex(int32_t c) { return 0; } -static char* io_json_read_string_inner(stream& s, io_json_read_buffer* buf, msgpack* msg, int32_t* c) { +static char* io_json_read_string_inner(stream& s, io_json_read_buffer* buf, int32_t* c) { if (*c != '"') return 0; @@ -281,7 +286,7 @@ static char* io_json_read_string_inner(stream& s, io_json_read_buffer* buf, msgp len++; break; case 'u': { - wchar_t uc = 0; + uint32_t uc = 0; if ((*c = io_json_read_char(s, buf)) == EOF) break; uc |= io_json_read_string_hex(*c) << 24; @@ -326,7 +331,7 @@ static char* io_json_read_string_inner(stream& s, io_json_read_buffer* buf, msgp switch (*c) { case '"': - temp[i++] = '\"'; + temp[i++] = '"'; break; case '\\': temp[i++] = '\\'; @@ -350,7 +355,7 @@ static char* io_json_read_string_inner(stream& s, io_json_read_buffer* buf, msgp temp[i++] = '\t'; break; case 'u': { - wchar_t uc = 0; + uint32_t uc = 0; uc |= io_json_read_string_hex(io_json_read_char(s, buf)) << 24; uc |= io_json_read_string_hex(io_json_read_char(s, buf)) << 16; uc |= io_json_read_string_hex(io_json_read_char(s, buf)) << 8; @@ -382,7 +387,7 @@ static char* io_json_read_string_inner(stream& s, io_json_read_buffer* buf, msgp } inline static void io_json_read_string(stream& s, io_json_read_buffer* buf, msgpack* msg, int32_t* c) { - char* temp = io_json_read_string_inner(s, buf, msg, c); + char* temp = io_json_read_string_inner(s, buf, c); *msg = temp; free_def(temp); } @@ -406,7 +411,7 @@ static void io_json_read_map(stream& s, io_json_read_buffer* buf, msgpack* msg, if (*c == '}') break; - char* key = io_json_read_string_inner(s, buf, msg, c); + char* key = io_json_read_string_inner(s, buf, c); if (!key) return; @@ -655,7 +660,7 @@ inline static void io_json_write_double_t(stream& s, double_t val) { } inline static void io_json_write_string(stream& s, std::string& val) { - s.write_char('\"'); + s.write_char('"'); const char* str = val.c_str(); size_t len = val.size(); for (size_t i = len; i; i--, str++) @@ -720,5 +725,5 @@ inline static void io_json_write_string(stream& s, std::string& val) { default: s.write_char(*str); } - s.write_char('\"'); + s.write_char('"'); } diff --git a/src/KKdLib/io/stream.cpp b/src/KKdLib/io/stream.cpp index 54b97002..ca1d51bf 100644 --- a/src/KKdLib/io/stream.cpp +++ b/src/KKdLib/io/stream.cpp @@ -635,7 +635,7 @@ void stream::write_string_null_terminated(std::string& str) { } void stream::write_string_null_terminated(std::string&& str) { - write_string_null_terminated(*(std::string*)&str); + write_string_null_terminated(str); } void stream::write_wstring_null_terminated(std::wstring& str) { diff --git a/src/KKdLib/mat.hpp b/src/KKdLib/mat.hpp index fa8fa77f..67a82b7b 100644 --- a/src/KKdLib/mat.hpp +++ b/src/KKdLib/mat.hpp @@ -170,6 +170,7 @@ extern void mat4_translate_x_add(const mat4* x, float_t y, mat4* z); extern void mat4_translate_y_add(const mat4* x, float_t y, mat4* z); extern void mat4_translate_z_add(const mat4* x, float_t y, mat4* z); extern void mat4_from_quat(const quat* quat, mat4* mat); +extern void mat4_from_two_vectors(const vec3* x, const vec3* y, mat4* mat); extern void mat4_from_axis_angle(const vec3* axis, float_t angle, mat4* mat); extern void mat4_from_axis_angle_sin_cos(const vec3* axis, float_t sin_val, float_t cos_val, mat4* mat); extern void mat4_from_mat3(const mat3* x, mat4* z); diff --git a/src/KKdLib/prj/algorithm.hpp b/src/KKdLib/prj/algorithm.hpp index 945ae6a6..d4fcde2a 100644 --- a/src/KKdLib/prj/algorithm.hpp +++ b/src/KKdLib/prj/algorithm.hpp @@ -12,6 +12,16 @@ #include namespace prj { + template + bool find(std::vector& vec, T& value) { + auto begin = vec.begin(); + auto end = vec.end(); + for (auto i = begin; i != end; i++) + if (*i == value) + return true; + return false; + } + template void sort(std::vector& vec) { std::sort(vec.begin(), vec.end()); diff --git a/src/KKdLib/prj/time.cpp b/src/KKdLib/prj/time.cpp new file mode 100644 index 00000000..f040bb9b --- /dev/null +++ b/src/KKdLib/prj/time.cpp @@ -0,0 +1,39 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#include "time.hpp" +#include + +namespace prj { + prj::time prj::time::get_default() { + static prj::time start_of_2005 = prj::strptime("2005-01-01 00:00:00"); + return start_of_2005; + } + + prj::time strptime(std::string& str) { + int32_t year; + int32_t month; + int32_t day; + int32_t hour; + int32_t min; + int32_t sec; + if (sscanf_s(str.c_str(), "%4d-%2d-%2d %2d:%2d:%2d", &year, &month, &day, &hour, &min, &sec) == 6) { + struct tm time; + time.tm_isdst = -1; + time.tm_year = year - 1900; + time.tm_mon = month - 1; + time.tm_mday = day; + time.tm_hour = hour; + time.tm_min = min; + time.tm_sec = sec; + return prj::time(mktime(&time)); + } + return {}; + } + + prj::time strptime(std::string&& str) { + return strptime(str); + } +} diff --git a/src/KKdLib/prj/time.hpp b/src/KKdLib/prj/time.hpp new file mode 100644 index 00000000..7d719953 --- /dev/null +++ b/src/KKdLib/prj/time.hpp @@ -0,0 +1,27 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#pragma once + +#include "../default.hpp" + +namespace prj { + struct time { + time_t value; + + inline time() { + value = -1; + } + + inline time(time_t value) { + this->value = value; + } + + static prj::time get_default(); + }; + + prj::time strptime(std::string& str); + prj::time strptime(std::string&& str); +} diff --git a/src/KKdLib/pv_exp.cpp b/src/KKdLib/pv_exp.cpp index 68bdbe9c..b8518d62 100644 --- a/src/KKdLib/pv_exp.cpp +++ b/src/KKdLib/pv_exp.cpp @@ -161,7 +161,7 @@ static void pv_exp_classic_read_inner(pv_exp* exp, prj::shared_ptrload_data_wait) { - object_database* obj_db = 0; - data_struct* ds = &data_list[glt_edt->load_data_type]; - switch (ds->type) { - case DATA_AFT: - case DATA_FT: - case DATA_M39: - obj_db = &ds->data_ft.obj_db; - break; - } glt_edt->hash = Glitter::glt_particle_manager->LoadFile(glt_edt->load_glt_type, - &data_list[glt_edt->load_data_type], file, path, -1.0f, false, obj_db); + &data_list[glt_edt->load_data_type], file, path, -1.0f, false); glt_edt->load_data_wait = true; } else if (Glitter::glt_particle_manager->CheckNoFileReaders(glt_edt->hash)) { diff --git a/src/ReDIVA/data_edit.cpp b/src/ReDIVA/data_edit.cpp index 23a35b75..e3201a6c 100644 --- a/src/ReDIVA/data_edit.cpp +++ b/src/ReDIVA/data_edit.cpp @@ -386,7 +386,7 @@ bool DataEdit::Ctrl() { if (chara_id == -1) { rob_chara_pv_data pv_data; pv_data.chara_size_index = chara_init_data_get_chara_size_index(CHARA_MIKU); - chara_id = rob_chara_array_init_chara_index(CHARA_MIKU, &pv_data, 0, true); + chara_id = rob_chara_array_init_chara_index(CHARA_MIKU, pv_data, 0, true); } if (chara_id == -1 || !task_rob_manager_check_chara_loaded(chara_id)) @@ -461,7 +461,7 @@ bool DataEdit::Ctrl() { rob_chara* rob_chr = rob_chara_array_get(chara_id); rob_chr->set_frame((float_t)frame); - rob_chr->data.miku_rot.position = rob_trans; + rob_chr->set_data_miku_rot_position(rob_trans); if (!play && sound_play) { sound_work_release_stream(0); diff --git a/src/ReDIVA/data_initialize.cpp b/src/ReDIVA/data_initialize.cpp index 3204fe5a..4eec3306 100644 --- a/src/ReDIVA/data_initialize.cpp +++ b/src/ReDIVA/data_initialize.cpp @@ -6,9 +6,11 @@ #include "data_initialize.hpp" #include "../CRE/rob/rob.hpp" #include "../CRE/auth_2d.hpp" +#include "../CRE/customize_item_table.hpp" #include "../CRE/data.hpp" #include "../CRE/hand_item.hpp" #include "../CRE/item_table.hpp" +#include "../CRE/module_table.hpp" #include "../CRE/object.hpp" #include "../CRE/sound.hpp" #include "../CRE/sprite.hpp" @@ -98,10 +100,8 @@ bool TaskDataInit::Ctrl() { sound_work_read_farc("rom/sound/pvchange.farc"); sound_work_read_farc("rom/sound/slide_se.farc"); sound_work_read_farc("rom/sound/slide_long.farc"); - //sub_14037EF30(); - //sub_14037F180(); - //sub_140377A10(); - //sub_140377C30(); + module_table_handler_data_read(); + customize_item_table_handler_data_read(); //sub_1403926C0(); //sub_1403928E0(); //sub_1403740D0(); @@ -134,8 +134,8 @@ bool TaskDataInit::Ctrl() { && !sound_work_load_farc("rom/sound/pvchange.farc") && !sound_work_load_farc("rom/sound/slide_se.farc") && !sound_work_load_farc("rom/sound/slide_long.farc") - //&& !sub_14037FE80() - //&& !sub_1403785C0() + && !module_table_handler_data_load() + && !customize_item_table_handler_data_load() //&& !sub_1403933B0() //&& !sub_1403747D0() //&& !sub_140390AE0() @@ -145,12 +145,10 @@ bool TaskDataInit::Ctrl() { //&& !sub_140388A50() && !hand_item_handler_data_load() && !rob_sleeve_handler_data_load()) { - //sub_14037F680(); - //sub_1403F98D0(sub_1403F8C30()); - //sub_140378060(); - //sub_140234DE0(sub_140234860()); + //sub_1403F8C30()->sub_1403F98D0(); + //sub_140234860()->sub_140234DE0(); //sub_140392D10(); - //sub_140226A80(sub_140226760()); + //sub_140226760()->sub_140226A80(); //sub_140374650(); //sub_140390960(); //sub_140375FB0(); diff --git a/src/ReDIVA/data_test/auth_2d_test.cpp b/src/ReDIVA/data_test/auth_2d_test.cpp index 532c7d1c..33a336e6 100644 --- a/src/ReDIVA/data_test/auth_2d_test.cpp +++ b/src/ReDIVA/data_test/auth_2d_test.cpp @@ -187,7 +187,7 @@ bool DtmAet::Ctrl() { if (type) { comp.data.clear(); aet_manager_init_aet_layout(&comp, aet_id, layer_name, - (AetFlags)0, RESOLUTION_MODE_HD, 0, frame, aft_aet_db); + (AetFlags)0, RESOLUTION_MODE_HD, 0, frame, aft_aet_db, aft_spr_db); } else { float_t x = 0.0f; diff --git a/src/ReDIVA/data_test/glitter_test.cpp b/src/ReDIVA/data_test/glitter_test.cpp index 722adeba..759a1f45 100644 --- a/src/ReDIVA/data_test/glitter_test.cpp +++ b/src/ReDIVA/data_test/glitter_test.cpp @@ -267,11 +267,10 @@ void TaskDataTestGlitterParticle::Window() { void TaskDataTestGlitterParticle::LoadFile(const char* file) { data_struct* aft_data = &data_list[DATA_AFT]; - object_database* aft_obj_db = &aft_data->data_ft.obj_db; Glitter::glt_particle_manager->FreeSceneEffect(scene_counter); Glitter::glt_particle_manager->UnloadEffectGroup(hash); - hash = Glitter::glt_particle_manager->LoadFile(Glitter::FT, aft_data, file, 0, -1.0f, true, aft_obj_db); + hash = Glitter::glt_particle_manager->LoadFile(Glitter::FT, aft_data, file, 0, -1.0f, true); rebuild_geff = true; } diff --git a/src/ReDIVA/game_state.cpp b/src/ReDIVA/game_state.cpp index 48a93552..4b73f210 100644 --- a/src/ReDIVA/game_state.cpp +++ b/src/ReDIVA/game_state.cpp @@ -15,9 +15,9 @@ #include "data_test/glitter_test.hpp" #include "data_test/motion_test.hpp" #include "data_test/stage_test.hpp" +#include "pv_game/pv_game.hpp" #include "data_edit.hpp" #include "data_initialize.hpp" -#include "pv_game.hpp" #include "system_startup.hpp" #include "x_pv_game.hpp" diff --git a/src/ReDIVA/pv_game.cpp b/src/ReDIVA/pv_game.cpp deleted file mode 100644 index 7232c427..00000000 --- a/src/ReDIVA/pv_game.cpp +++ /dev/null @@ -1,1664 +0,0 @@ -/* - by korenkonder - GitHub/GitLab: korenkonder -*/ - -#include "pv_game.hpp" -#include "../CRE/Glitter/glitter.hpp" -#include "../CRE/light_param/light.hpp" -#include "../CRE/light_param.hpp" -#include "../CRE/rob/motion.hpp" -#include "../CRE/rob/rob.hpp" -#include "../CRE/rob/skin_param.hpp" -#include "../CRE/data.hpp" -#include "../CRE/object.hpp" -#include "../CRE/pv_expression.hpp" -#include "../CRE/pv_param.hpp" -#include "../CRE/sound.hpp" -#include "../CRE/stage.hpp" -#include "../KKdLib/farc.hpp" -#include "../KKdLib/sort.hpp" -#include "imgui_helper.hpp" -#include "input.hpp" - -enum dsc_ft_func { - DSC_FT_END, - DSC_FT_TIME, - DSC_FT_MIKU_MOVE, - DSC_FT_MIKU_ROT, - DSC_FT_MIKU_DISP, - DSC_FT_MIKU_SHADOW, - DSC_FT_TARGET, - DSC_FT_SET_MOTION, - DSC_FT_SET_PLAYDATA, - DSC_FT_EFFECT, - DSC_FT_FADEIN_FIELD, - DSC_FT_EFFECT_OFF, - DSC_FT_SET_CAMERA, - DSC_FT_DATA_CAMERA, - DSC_FT_CHANGE_FIELD, - DSC_FT_HIDE_FIELD, - DSC_FT_MOVE_FIELD, - DSC_FT_FADEOUT_FIELD, - DSC_FT_EYE_ANIM, - DSC_FT_MOUTH_ANIM, - DSC_FT_HAND_ANIM, - DSC_FT_LOOK_ANIM, - DSC_FT_EXPRESSION, - DSC_FT_LOOK_CAMERA, - DSC_FT_LYRIC, - DSC_FT_MUSIC_PLAY, - DSC_FT_MODE_SELECT, - DSC_FT_EDIT_MOTION, - DSC_FT_BAR_TIME_SET, - DSC_FT_SHADOWHEIGHT, - DSC_FT_EDIT_FACE, - DSC_FT_MOVE_CAMERA, - DSC_FT_PV_END, - DSC_FT_SHADOWPOS, - DSC_FT_EDIT_LYRIC, - DSC_FT_EDIT_TARGET, - DSC_FT_EDIT_MOUTH, - DSC_FT_SET_CHARA, - DSC_FT_EDIT_MOVE, - DSC_FT_EDIT_SHADOW, - DSC_FT_EDIT_EYELID, - DSC_FT_EDIT_EYE, - DSC_FT_EDIT_ITEM, - DSC_FT_EDIT_EFFECT, - DSC_FT_EDIT_DISP, - DSC_FT_EDIT_HAND_ANIM, - DSC_FT_AIM, - DSC_FT_HAND_ITEM, - DSC_FT_EDIT_BLUSH, - DSC_FT_NEAR_CLIP, - DSC_FT_CLOTH_WET, - DSC_FT_LIGHT_ROT, - DSC_FT_SCENE_FADE, - DSC_FT_TONE_TRANS, - DSC_FT_SATURATE, - DSC_FT_FADE_MODE, - DSC_FT_AUTO_BLINK, - DSC_FT_PARTS_DISP, - DSC_FT_TARGET_FLYING_TIME, - DSC_FT_CHARA_SIZE, - DSC_FT_CHARA_HEIGHT_ADJUST, - DSC_FT_ITEM_ANIM, - DSC_FT_CHARA_POS_ADJUST, - DSC_FT_SCENE_ROT, - DSC_FT_EDIT_MOT_SMOOTH_LEN, - DSC_FT_PV_BRANCH_MODE, - DSC_FT_DATA_CAMERA_START, - DSC_FT_MOVIE_PLAY, - DSC_FT_MOVIE_DISP, - DSC_FT_WIND, - DSC_FT_OSAGE_STEP, - DSC_FT_OSAGE_MV_CCL, - DSC_FT_CHARA_COLOR, - DSC_FT_SE_EFFECT, - DSC_FT_EDIT_MOVE_XYZ, - DSC_FT_EDIT_EYELID_ANIM, - DSC_FT_EDIT_INSTRUMENT_ITEM, - DSC_FT_EDIT_MOTION_LOOP, - DSC_FT_EDIT_EXPRESSION, - DSC_FT_EDIT_EYE_ANIM, - DSC_FT_EDIT_MOUTH_ANIM, - DSC_FT_EDIT_CAMERA, - DSC_FT_EDIT_MODE_SELECT, - DSC_FT_PV_END_FADEOUT, - DSC_FT_TARGET_FLAG, - DSC_FT_ITEM_ANIM_ATTACH, - DSC_FT_SHADOW_RANGE, - DSC_FT_HAND_SCALE, - DSC_FT_LIGHT_POS, - DSC_FT_FACE_TYPE, - DSC_FT_SHADOW_CAST, - DSC_FT_EDIT_MOTION_F, - DSC_FT_FOG, - DSC_FT_BLOOM, - DSC_FT_COLOR_COLLE, - DSC_FT_DOF, - DSC_FT_CHARA_ALPHA, - DSC_FT_AOTO_CAP, - DSC_FT_MAN_CAP, - DSC_FT_TOON, - DSC_FT_SHIMMER, - DSC_FT_ITEM_ALPHA, - DSC_FT_MOVIE_CUT_CHG, - DSC_FT_CHARA_LIGHT, - DSC_FT_STAGE_LIGHT, - DSC_FT_AGEAGE_CTRL, - DSC_FT_MAX, -}; - -struct struc_14 { - int32_t field_0; - int32_t difficulty; - int32_t edition; - uint32_t pv; - int8_t field_10; - int8_t field_11; - int8_t field_12; - int8_t field_13; - int32_t field_14; - int32_t field_18; - int32_t field_1C; - float_t field_20; - int8_t field_24; - int8_t field_25; - int8_t field_26; - int8_t field_27; -}; - -pv_game* _pv_game; -TaskPvGame* task_pv_game; -pv_game_music* pv_game_music_data; - -struc_14 stru_140C94438; - -extern render_context* rctx_ptr; - -static pv_game_music* pv_game_music_get(); - -static struc_14* sub_14013C8C0(); - -pv_play_data_motion_data::pv_play_data_motion_data() : rob_chr(), current_time(), -duration(), start_pos(), end_pos(), start_rot(), end_rot() { - mot_smooth_len = 12.0f; -} - -pv_play_data_motion_data::~pv_play_data_motion_data() { - -} - -void pv_play_data_motion_data::clear() { - set_motion.clear(); - set_motion.shrink_to_fit(); - set_item.clear(); - set_item.shrink_to_fit(); -} - -void 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(); -} - -pv_play_data::pv_play_data() : rob_chr(), disp(), field_31(), field_34() { - -} - -pv_play_data::~pv_play_data() { - -} - -void pv_play_data::reset() { - motion.clear(); - motion.shrink_to_fit(); - rob_chr = 0; - set_motion.clear(); - disp = true; - motion_data.reset(); -} - -pv_disp2d::pv_disp2d() : pv_id(), title_start_2d_field(), title_end_2d_field(), -title_start_2d_low_field(), title_end_2d_low_field(), title_start_3d_field(), title_end_3d_field(), -target_shadow_type(), pv_spr_set_id(), pv_aet_set_id(), pv_main_aet_id() { - -} - -pv_disp2d::~pv_disp2d() { - -} - -pv_data_camera::pv_data_camera() : enable(), time() { - id = -1; -} - -pv_game_pv_data::pv_game_pv_data() : field_0(), state(), play(), dsc_buffer(), dsc_buffer_counter(), -field_2BF30(), field_2BF38(), curr_time(), curr_time_float(), prev_time_float(), field_2BF50(), field_2BF58(), -field_2BF60(), field_2BF64(), field_2BF68(), chara_id(), pv_game()/*, field_2BF80()*/, music(), -dsc_file_handler(), target_anim_fps(), anim_frame_speed(), target_flying_time(), time_signature(), dsc_time(), -field_2BFB0(), field_2BFB4(), field_2BFB8(), field_2BFBC(), field_2BFC0(), music_play(), field_2BFC4(), pv_end(), -fov(), min_dist(), field_2BFD4(), field_2BFD5(), data_camera(), change_field_branch_time(), scene_fade_enable(), -scene_fade_frame(), scene_fade_duration(), scene_fade_start_alpha(), scene_fade_end_alpha(), scene_fade_color(), -has_signature(), has_perf_id(), field_2C4E4(), field_2C500(), scene_rot_y(), scene_rot_mat(), field_2C54C(), -field_2C550(), branch_mode(), first_challenge_note(), last_challenge_note(), field_2C560() { - -} - -pv_game_pv_data::~pv_game_pv_data() { - -} - -void pv_game_pv_data::reset() { - pv_game = 0i64; - //field_2BF80 = 0; - music = 0i64; - dsc_file_handler.reset(); - play = false; - field_2BF50 = false; - - //if (sub_1400E7910(sub_14013C8C0()) >= 6) - // field_2BF60 = false; - - for (pv_play_data& i : playdata) { - i.rob_chr = 0; - i.set_motion.clear(); - i.motion_data.clear(); - pv_expression_array_reset_motion(&i - playdata); - } - - data_camera_branch_fail.clear(); - data_camera_branch_fail.shrink_to_fit(); - data_camera_branch_success.clear(); - data_camera_branch_success.shrink_to_fit(); - change_field_branch_fail.clear(); - change_field_branch_fail.shrink_to_fit(); - change_field_branch_success.clear(); - change_field_branch_success.shrink_to_fit(); - change_field_branch_time = -1i64; - scene_fade_enable = false; - scene_fade_frame = 0.0f; - scene_fade_duration = 0.0f; - scene_fade_start_alpha = 0.0f; - scene_fade_end_alpha = 0.0f; - scene_fade_color = 0.0f; - - reset_camera_post_process(); - - field_2C4E8.clear(); - field_2C4E8.shrink_to_fit(); - field_2C500 = 0; - field_0 = 0; -} - -void pv_game_pv_data::reset_camera_post_process() { - camera* cam = rctx_ptr->camera; - //cam->set_ignore_min_dist(false); - cam->set_max_distance(0.05); - //cam->set_ignore_fov(0); - cam->set_fov(32.2673416137695); - - post_process* pp = &rctx_ptr->post_process; - pp->tone_map->set_scene_fade_color(0.0f); - pp->tone_map->set_scene_fade_alpha(0.0f); - pp->tone_map->set_scene_fade_alpha(0); - pp->tone_map->set_tone_trans(0.0f, 1.0f); - pp->tone_map->set_saturate_coeff(1.0f); - - shadow* shad = rctx_ptr->render_manager.shadow_ptr; - if (shad) - for (bool& i : shad->blur_filter_enable) - i = true; - - branch_mode = false; - - for (pv_data_camera& i : data_camera) - i = {}; -} - -pv_game_play_data::pv_game_play_data() : pv_set(), aet_ids(), aet_ids_enable(), field_1C8(), field_1D0(), -field_1D8(), field_1E0(), field_1E8(), field_1F0(), disp(), field_1FC(), field_204(), field_20C(), -frame_state(), field_218(), fade_begin(), fade_end(), fade(), skin_danger_frame(), field_2FC(), -chance_result(), chance_points(), field_310(), slide_points(), max_slide_points(), pv_spr_set_id(), -pv_aet_set_id(), pv_main_aet_id(), stage_index(), field_33C(), field_350(), field_354(), value_text_spr_index(), -not_clear(), spr_set_back_id(), loaded(), state(), field_36C(), score_preview_update(), field_374(), -field_378(), field_37C(), score_preview_speed(), score_preview(), value_text_display(), field_38C(), -value_text_index(), value_text_time_offset(), combo_state(), combo_count(), combo_disp_time(), field_3AC(), -field_3B0(), field_3B4(), field_3B8(), field_3BC(), aix(), ogg(), field_3C4(), field_5E8(), field_5EC(), -option(), field_5F4(), lyric(), lyric_index(), field_64C(), field_650(), field_654(), field_658(), field_65C() { - chance_points_pos = 0; - slide_points_pos = 0; - max_slide_points_pos = 0; - reset(); - state = 0; -} - -pv_game_play_data::~pv_game_play_data() { - -} - -void pv_game_play_data::reset() { - loaded = false; - score_preview_update = false; - field_378 = false; - score_preview_speed = 0.04f; - field_36C = -1; - combo_state = 4; - pv_set = false; - stage_index = 0; - field_354 = false; - not_clear = false; - pv_spr_set_id = -1; - pv_aet_set_id = -1; - pv_main_aet_id = -1; - - sub_1401362C0(); -} - -void pv_game_play_data::sub_1401362C0() { - for (int32_t i = 0; i < PV_GAME_AET_MAX; i++) { - aet_ids[i] = 0; - aet_ids_enable[i] = false; - } - - for (int32_t i = 0; i < 2; i++) { - field_1C8[i] = 0.0f; - field_1D0[i] = 0.0f; - field_1D8[i] = 0.0f; - field_1E0[i] = 0.0f; - field_1E8[i] = 0.0f; - field_1F0[i] = 0.0f; - disp[i] = false; - field_1FC[i] = 0; - } - - field_1C8[0] = 86.0f; - field_1C8[1] = 138.0f; - field_1D8[0] = 58.0f; - field_1D8[1] = 138.0f; - field_1E8[0] = 58.0f; - field_1E8[1] = -1.0f; - field_1F0[0] = 86.0f; - field_1F0[1] = -1.0f; - field_204[0] = 58.0f; - field_204[1] = 138.0f; - field_20C[0] = 86.0f; - field_20C[1] = 138.0f; - - frame_state = 0; - field_218 = false; - fade_begin = false; - fade_end = false; - fade = PV_GAME_AET_WHITE_FADE; - skin_danger_frame = 0; - field_2FC = 0; - chance_result = 0; - chance_points = 0; - chance_points_pos = 0.0f; - field_310 = 0; - slide_points = 0; - slide_points_pos = 0.0f; - max_slide_points = 0; - max_slide_points_pos = 0.0f; - field_33C = 0; - comp.Clear(); - field_350 = 0.0f; - value_text_spr_index = 0; - spr_set_back_id = -1; - field_374 = 0; - field_37C = 0.0f; - score_preview = 0; - value_text_display = 0; - field_38C = 0.0f; - value_text_index = 0; - value_text_time_offset = 0.0f; - combo_count = 0; - combo_disp_time = 0; - draw_pos = 0.0f; -} - -pv_game_chara::pv_game_chara() : chara_index(), cos(), chara_id(), pv_data(), rob_chr() { - -} - -pv_game_chara::~pv_game_chara() { - -} - -pv_game_field::pv_game_field() : stage_index(), light_auth_3d_uid(), light_auth_3d_id(), -light_frame(), spr_set_back_id(), stage_flag(), npr_type(), cam_blur(), sdw_off() { - -} - -pv_game_field::~pv_game_field() { - -} - -struc_269::struc_269() : field_30(), field_34() { - -} - -struc_269::~struc_269() { - -} - -pv_game_chreff::pv_game_chreff() : src_chara_index(), -dst_chara_index(), src_auth_3d_uid(), dst_auth_3d_uid() { - -} - -pv_game_chreff::~pv_game_chreff() { - -} - -pv_effect_resource::pv_effect_resource() : emission() { - -} - -pv_effect_resource::~pv_effect_resource() { - -} - -pv_game_data::pv_game_data() : field_2CE98(), field_2CE9C(), field_2CF1C(), field_2CF20(), field_2CF24(), -field_2CF28(), field_2CF2C(), field_2CF30(), field_2CF34(), field_2CF38(), life_gauge(), score_final(), -challenge_time_total_bonus(), combo(), challenge_time_combo_count(), max_combo(), total_hit_count(), -hit_count(), current_reference_score(), target_count(), field_2CF84(), field_2CF88(), field_2CF8C(), -score_slide_chain_bonus(), slide_chain_length(), field_2CF98(), field_2CF9C(), field_2CFA0(), field_2CFA4(), -pv(), field_2CFB0(), chance_point(), reference_score(), field_2CFBC(), field_2CFC0(), field_2CFC4(), -field_2CFE0(), field_2CFE4(), notes_passed(), field_2CFF0(), song_energy(), song_energy_base(), -song_energy_border(), life_gauge_safety_time(), life_gauge_border(), stage_index(), field_2D00C(), -no_fail(), changed_field(), challenge_time_start(), challenge_time_end(), max_time(), max_time_float(), -current_time_float(), current_time(), current_time_float_dup(), field_2D03C(), score_hold_multi(), -score_hold(), score_slide(), has_slide(), has_success_se(), pv_disp2d(), life_gauge_final(), -hit_border(), field_2D05D(), field_2D05E(), field_2D05F(), title_image_init(), field_2D061(), -field_2D062(), field_2D063(), has_auth_3d_frame(), has_light_frame(), has_aet_frame(), has_aet_list(), -field_index(), edit_effect_index(), slidertouch_counter(), change_field_branch_success_counter(), -field_2D080(), field_2D084(), life_gauge_bonus(), life_gauge_total_bonus(), field_2D090(), field_2D091(), -field_2D092(), field_2D093(), field_2D094(), field_2D095(), field_2D096(), success(), field_2D098(), -field_2D09C(), use_osage_play_data(), pv_end_fadeout(), rival_percentage(), field_2D0A8(), field_2D0AC(), -field_2D0B0(), field_2D0BC(), next_stage(), field_2D0BE(), field_2D0BF(), field_2D0C0(), field_2D0C4(), -field_2D7E8(), field_2D7EC(), field_2D808(), field_2D80C(), edit_effect(), camera_auth_3d_uid(), -field_2D874(), task_effect_init(), field_2D87C(), current_field(), field_2D8A0(), field_2D8A4(), -data_camera_id(), field_2D954(), field_2DAC8(), field_2DACC(), field_2DB28(), field_2DB2C(), field_2DB34() { - field_2D00E = true; -} - -pv_game_data::~pv_game_data() { - -} - -pv_game_item_mask::pv_game_item_mask() { - arr[0] = true; - arr[1] = true; - arr[2] = true; - arr[3] = true; -} - -pv_game::pv_game() : loaded(), field_1(), field_2(), end_pv(), -field_4(), state(), field_C(), pv_id(), field_14(), modules(), items() { - reset(); - - state = 0; - field_C = -1; - pv_id = -1; - - for (int32_t& i : modules) - i = 0; - - data.play_data.field_5EC = 0; - data.play_data.option = 0.0f; - - data.field_2CF98 = 0; - data.song_energy_base = 0.0f; - data.life_gauge_safety_time = 0; - data.life_gauge_border = 0; - data.stage_index = 0; - data.field_2D00C = true; - data.challenge_time_start = -1; - data.challenge_time_end = -1; - data.field_2D061 = false; - data.field_2D062 = false; - data.field_2D063 = false; - data.field_2D0BC = false; - data.next_stage = false; - data.field_2D0BE = false; - data.field_2D0C0 = -1; - data.no_fail = true; - data.task_effect_init = false; - - data.effect_rs_list_hashes.reserve(0x40); - data.effect_rs_list.reserve(0x40); -} - -pv_game::~pv_game() { - -} - -void pv_game::ctrl() { - -} - -void pv_game::disp() { - -} - -std::string pv_game::get_effect_se_file_name() { - pv_db_pv_difficulty* diff = data.pv->get_difficulty( - sub_14013C8C0()->difficulty, sub_14013C8C0()->edition); - if (diff) - return diff->effect_se_file_name; - return {}; -} - -void pv_game::load() { - -} - -void pv_game::reset() { - loaded = false; - field_1 = false; - field_2 = false; - end_pv = false; - field_4 = false; - field_14 = false; - - data.play_data.field_5F4 = 1.0f; - memset(data.play_data.lyric, 0, sizeof(data.play_data.lyric)); - - data.play_data.lyric_index = 0; - data.play_data.lyrics_color = { 0xFF, 0xFF, 0xFF, 0xFF }; - - memset(data.field_2CE9C, 0i64, sizeof(data.field_2CE9C)); - data.field_2CF1C = 0; - data.field_2CF20 = 0; - data.field_2CF8C = 0.0f; - data.field_2CF9C = 0; - data.field_2CFA0 = 0; - data.field_2CFA4 = 0; - - data.play_data.field_3B0 = -1; - data.play_data.field_3B4 = -1; - data.play_data.field_3B8 = -1; - data.play_data.field_3BC = -1; - - pv_id = -1; - - data.field_2CFB0 = 0; - data.chance_point = 0; - - for (auto& i : data.chara) { - i.chara_index = CHARA_MAX; - i.cos = -1; - i.chara_id = -1; - i.pv_data = {}; - i.rob_chr = 0; - i.motion_ids.clear(); - i.motion_face_ids.clear(); - } - - data.motion_set_ids.clear(); - data.motion_set_face_ids.clear(); - - data.obj_set_itmpv.clear(); - data.obj_set_handitem.clear(); - data.chreff_auth_3d_obj_set_ids.clear(); - data.field_2D770.clear(); - data.stgpvhrc_obj_set_ids.clear(); - data.ex_song_ex_auth_obj_set_ids.clear(); - - data.stage_indices.clear(); - data.stage_infos.clear(); - - data.field_2D7E8 = false; - data.spr_set_back_ids.clear(); - - data.field_2D808 = -1; - - data.edit_effect_spr_set_ids.clear(); - data.edit_effect_aet_ids.clear(); - data.edit_effect.field_0 = -1; - data.edit_effect.field_4 = 1.0f; - data.edit_effect.field_8 = 0.0f; - data.edit_effect.field_C = 0.0f; - data.edit_effect.field_10 = 1.0f; - data.edit_effect.field_14 = false; - - data.current_field = 0; - data.field_data.clear(); - - data.field_2D8A0 = true; - - data.camera_auth_3d_uid = -1; - data.campv_string.clear(); - data.campv_auth_3d_uids.clear(); - data.data_camera_id = 0; - data.campv.clear(); - - data.itmpv_string.clear(); - data.itmpv_auth_3d_uids.clear(); - for (auto& i : data.itmpv) - i.clear(); - data.itmpv_uids.clear(); - - for (auto& i : data.field_2DA08) { - i.data.clear(); - i.auth_3d_ids.clear(); - i.field_30 = -1; - } - - data.auth_3d.clear(); - data.field_2DAC8 = false; - data.auth_3d_categories.clear(); - data.loaded_auth_3d_uids.clear(); - - data.auth_3d_time.clear(); - data.light_time.clear(); - - for (auto& i : data.aet_time) - i.clear(); - - data.chreff_auth_3d.clear(); - data.chreff_auth_3d_obj.clear(); - - data.reference_score = 0; - data.field_2CFBC = 0; - data.field_2CFC0 = 0; - data.field_2CFC8.clear(); - data.field_2CFE0 = 0; - data.field_2D092 = data.field_2D00E; - data.notes_passed = 0; - data.field_2CFF0 = 0; - data.song_energy = 0.0f; - data.song_energy_border = 0.0f; - data.max_time_float = 0.0f; - data.current_time_float = 0.0f; - data.max_time = 0; - data.current_time = 0; - data.current_time_float_dup = 0.0f; - data.field_2D03C = 0.0f; - data.score_hold_multi = 0; - data.score_hold = 0; - data.score_slide = 0; - data.has_slide = false; - data.has_success_se = false; - data.pv_disp2d = 0; - data.hit_border = false; - data.field_2D05D = 0; - data.field_2D05F = 1; - data.title_image_init = false; - data.field_index = 0; - data.edit_effect_index = -1; - data.slidertouch_counter = 0; - data.change_field_branch_success_counter = 0; - data.field_2D05E = 0; - data.field_2D080 = 0; - data.field_2D084 = 0; - data.life_gauge_bonus = 0; - data.life_gauge_total_bonus = 0; - data.field_2D090 = 0; - data.field_2D091 = 0; - data.field_2D093 = 0; - data.field_2D094 = 0; - data.field_2D095 = false; - data.field_2D096 = false; - data.use_osage_play_data = false; - data.pv_end_fadeout = false; - data.field_2D098 = 0; - data.field_2D09C = 0; - data.rival_percentage = 0.0f; - data.play_data.se_name.clear(); - data.play_data.pvbranch_success_se_name.clear(); - data.play_data.slide_name.clear(); - data.play_data.chainslide_first_name.clear(); - data.play_data.chainslide_sub_name.clear(); - data.play_data.chainslide_success_name.clear(); - data.play_data.chainslide_failure_name.clear(); - data.play_data.slidertouch_name.clear(); - data.play_data.song_file_name.clear(); - data.play_data.field_5E8 = -1; - data.field_2DB28 = 0; - data.field_2DB2C = 0; - data.play_data.aix = false; - data.play_data.ogg = false; - data.play_data.field_64C = 0; - data.field_2CF30 = 4; - data.field_2CF34 = 0; - data.play_data.field_650 = 43; - data.play_data.field_654 = 0.0f; - data.field_2CF24 = 3; - data.field_2CF28 = 0.0f; - data.field_2CF38 = 0; - data.play_data.field_658 = 0; - data.play_data.field_65C = 0.0f; - data.field_2CF2C = 0.0; - data.target_count = 0; - data.field_2CF84 = 0; - data.current_reference_score = 0; - data.combo = 0; - data.challenge_time_combo_count = 0; - data.life_gauge = 127; - data.score_final = 0; - data.life_gauge_final = 127; - data.max_combo = 0; - data.challenge_time_total_bonus = 0; - data.field_2CF88 = 0; - data.pv = 0i64; - data.score_slide_chain_bonus = 0; - data.slide_chain_length = 0; - data.field_2D0BC = false; - data.next_stage = false; - data.field_2D0BE = false; - data.field_2D0C0 = -1; - - data.field_2CE98 = 0; - - for (int32_t& i : data.total_hit_count) - i = 0; - - for (int32_t& i : data.hit_count) - i = 0; - - data.changed_field = 0; - - data.has_auth_3d_frame = false; - data.has_light_frame = false; - - for (bool& i : data.has_aet_frame) - i = false; - - for (bool& i : data.has_aet_list) - i = false; - - data.success = data.field_2D063; - data.field_2CE98 = 0; - data.field_2D874 = -1; - data.field_2DB34 = 0; - data.field_2D0A8 = 0; - data.field_2D0AC = 0; - data.field_2D0B0[0] = 0; - data.field_2D0B0[1] = 0; - data.field_2D0B0[2] = 0; - - data.effect_rs_list.clear(); - data.effect_rs_list_hashes.clear(); - - data.task_effect_init = false; -} - -bool pv_game::unload() { - data_struct* aft_data = &data_list[DATA_AFT]; - aet_database* aft_aet_db = &aft_data->data_ft.aet_db; - sprite_database* aft_spr_db = &aft_data->data_ft.spr_db; - texture_database* aft_tex_db = &aft_data->data_ft.tex_db; - - switch (data.field_2D09C) { - case 0: { - pv_game_music_get()->stop(); - - /*for (int32_t i = 0; i < 2; i++) - if (app::TaskWork::CheckTaskReady(task_movie_get())) - sub_14041F4E0(task_movie_get());*/ - - std::string effect_se_file_name = get_effect_se_file_name(); - if (effect_se_file_name.size()) - sound_work_unload_farc(effect_se_file_name.data()); - - if (data.play_data.slidertouch_name.size()) { - char buf[0x200]; - sprintf_s(buf, sizeof(buf), "rom/sound/%s.farc", data.play_data.slidertouch_name.c_str()); - sound_work_unload_farc(buf); - } - - wave_audio_storage_clear(); - - if (data.play_data.aix) - pv_game_music_get()->exclude_flags(PV_GAME_MUSIC_AIX); - - pv_game_music_get()->set_channel_pair_volume_map(0, 100); - pv_game_music_get()->set_channel_pair_volume_map(1, 100); - - data.field_2CF30 = 4; - - post_process& pp = rctx_ptr->post_process; - int32_t frame_texture_index = 0; - for (pv_db_pv_frame_texture& i : data.pv->frame_texture) { - if (i.data.size()) { - texture* tex = texture_storage_get_texture(aft_tex_db->get_texture_id(i.data.c_str())); - //if (tex) - // post_process_free_frame_texture(&pp, frame_texture_index, tex); - } - frame_texture_index++; - } - - if (data.field_2D0BE) { - //post_process_reset_frame_textures(&pp); - data.field_2D0BE = false; - } - - data.pv_data.reset(); - - if (data.play_data.ogg) - pv_game_music_get()->exclude_flags(PV_GAME_MUSIC_OGG); - - data.field_2D09C = 1; - } - case 1: - pv_osage_manager_array_set_not_reset_true(); - if (pv_osage_manager_array_get_disp()) - return false; - - data.field_2D09C = 2; - break; - } - - for (auto& i : data.chara) { - if (i.chara_id != -1 && i.rob_chr) { - skin_param_manager_reset(i.chara_id); - rob_chara_array_free_chara_id(i.chara_id); - } - - i.chara_index = CHARA_MAX; - i.cos = -1; - i.chara_id = -1; - i.pv_data = {}; - i.rob_chr = 0; - i.motion_ids.clear(); - i.motion_face_ids.clear(); - } - - //osage_play_data_manager_clear_data(); - - for (uint32_t& i: data.motion_set_ids) { - motion_set_unload_motion(i); - motion_set_unload_mothead(i); - } - data.motion_set_ids.clear(); - - for (uint32_t& i : data.motion_set_face_ids) - motion_set_unload_motion(i); - data.motion_set_face_ids.clear(); - - pv_expression_file_unload(data.pv->pv_expression_file_name.c_str()); - - data.stage_indices.clear(); - data.stage_infos.clear(); - - task_stage_unload_task(); - - if (data.field_2D7E8) - for (int32_t& i : data.spr_set_back_ids) - sprite_manager_unload_set(i, aft_spr_db); - - data.field_2D7E8 = false; - data.spr_set_back_ids.clear(); - - data.current_field = 0; - data.field_data.clear(); - - data.field_2D8A0 = true; - - for (auto& i : data.auth_3d) - i.second.unload_id(rctx_ptr); - - for (auto& i : data.field_2DA08) - for (auto& j : i.auth_3d_ids) - j.unload_id(rctx_ptr); - - if (data.field_2DAC8) - for (std::string& i : data.auth_3d_categories) - auth_3d_data_unload_category(i.c_str()); - - data.camera_auth_3d_uid = -1; - data.campv_string.clear(); - data.campv_auth_3d_uids.clear(); - data.data_camera_id = 0; - data.campv.clear(); - - data.itmpv_string.clear(); - data.itmpv_auth_3d_uids.clear(); - for (auto& i : data.itmpv) - i.clear(); - data.itmpv_uids.clear(); - - for (auto& i : data.field_2DA08) { - i.data.clear(); - i.auth_3d_ids.clear(); - i.field_30 = -1; - } - - data.auth_3d.clear(); - data.field_2DAC8 = false; - data.auth_3d_categories.clear(); - data.loaded_auth_3d_uids.clear(); - - data.auth_3d_time.clear(); - data.light_time.clear(); - - for (auto& i : data.aet_time) - i.clear(); - - data.chreff_auth_3d.clear(); - data.chreff_auth_3d_obj.clear(); - - for (int32_t& i : data.edit_effect_aet_set_ids) - sprite_manager_unload_set(i, aft_spr_db); - data.edit_effect_aet_set_ids.clear(); - - for (int32_t& i : data.edit_effect_spr_set_ids) - aet_manager_unload_set(i, aft_aet_db); - - data.edit_effect_spr_set_ids.clear(); - data.edit_effect_aet_ids.clear(); - data.edit_effect.field_0 = -1; - data.edit_effect.field_4 = 1.0f; - data.edit_effect.field_8 = 0.0f; - data.edit_effect.field_C = 0.0f; - data.edit_effect.field_10 = 1.0f; - data.edit_effect.field_14 = false; - - //pv_param::light_data_clear_data(); - pv_param::post_process_data_clear_data(); - - for (uint32_t& i : data.obj_set_itmpv) - object_storage_unload_set(i); - data.obj_set_itmpv.clear(); - - for (uint32_t& i : data.obj_set_handitem) - object_storage_unload_set(i); - data.obj_set_handitem.clear(); - - skin_param_storage_reset(); - - for (uint32_t& i : data.chreff_auth_3d_obj_set_ids) - object_storage_unload_set(i); - data.chreff_auth_3d_obj_set_ids.clear(); - - for (uint32_t& i : data.field_2D770) - object_storage_unload_set(i); - data.field_2D770.clear(); - - for (uint32_t& i : data.stgpvhrc_obj_set_ids) - object_storage_unload_set(i); - data.stgpvhrc_obj_set_ids.clear(); - - for (uint32_t& i : data.ex_song_ex_auth_obj_set_ids) - object_storage_unload_set(i); - data.ex_song_ex_auth_obj_set_ids.clear(); - - for (uint64_t& i : data.effect_rs_list_hashes) - Glitter::glt_particle_manager->UnloadEffectGroup(i); - data.effect_rs_list.clear(); - data.effect_rs_list_hashes.clear(); - - /*for (int32_t i = 0; i < 2; i++) { - TaskMovie* task_movie = task_movie_get(i16); - if (!app::TaskWork::CheckTaskReady(task_movie)) - continue; - - sub_14041F4E0(task_movie); - app::Task::DelTask(task_movie); - }*/ - - data.field_2D098 = 0; - - //stage_param_data_coli_data_clear(); - - data.play_data.field_3B0 = -1; - data.play_data.field_3B4 = -1; - data.play_data.field_3B8 = -1; - data.play_data.field_3BC = -1; - - //sub_14012BDA0(sub_14013C8F0()); - - //data.play_data->unload(); - - data.play_data.field_64C = 0; - - field_1 = false; - field_2 = false; - end_pv = false; - - //sub_14013C8C0()->field_26 = 0; - - /*struc_14* v85 = sub_14013C8C0(); - v85->field_14 = 0; - v85->field_18 = 0; - v85->field_1C = 0; - v85->field_20 = 1.0;*/ - - //sub_14013C8C0()->field_24 = false; - //sub_14013C8C0()->field_25 = false; - - loaded = false; - - data.field_2CFC8.clear(); - data.notes_passed = 0; - data.field_2CFF0 = 0; - data.field_2CFE0 = 0; - data.field_2D0C0 = -1; - - light_param_data_storage_data_reset(); - - post_process& pp = rctx_ptr->post_process; - pp.tone_map->set_saturate_coeff(1.0f); - pp.dof->set_dof_pv(); - pp.tone_map->set_scene_fade(0.0f); - - /*if (!sub_140192E20()) - post_process_set_taa(&pp, 1);*/ - - //sub_1404A9480(&pp, 0, -1); - - rctx_ptr->disp_manager.object_culling = true; - rctx_ptr->render_manager.shadow_ptr->range = 1.0f; - rctx_ptr->render_manager.set_effect_texture(0); - - sound_work_reset_all_se(); - - pv_param_task::post_process_task_del_task(); - - data.current_time_float = 0.0f; - data.current_time = 0; - return true; -} - -pv_game_init_data::pv_game_init_data() : pv_id(), difficulty(), field_C(), score_percentage_clear(), -life_gauge_safety_time(), life_gauge_border(), field_18(), modules(), items() { - -} - -void pv_game_init_data::reset() { - pv_id = 0; - difficulty = 0; - field_C = 0; - score_percentage_clear = 0; - life_gauge_safety_time = 0; - life_gauge_border = 0; - field_18 = 0; - for (int32_t& i : modules) - i = 0; - for (rob_chara_pv_data_item& i : items) - i = {}; - for (pv_game_item_mask& i : items_mask) - i = {}; -} - -TaskPvGame::Args::Args() : init_data(), field_190(), field_191(), no_fail(), -field_193(), field_194(), field_195(), field_196(), field_197(), test_pv(), option() { - Reset(); -} - -TaskPvGame::Args::~Args() { - -} - -void TaskPvGame::Args::Clear() { - se_name.clear(); - slide_se_name.clear(); - chainslide_first_name.clear(); - chainslide_sub_name.clear(); - chainslide_success_name.clear(); - chainslide_failure_name.clear(); - slidertouch_name.clear(); -} - -void TaskPvGame::Args::Reset() { - init_data.reset(); - Clear(); - field_190 = false; - field_191 = true; - no_fail = false; - field_193 = true; - field_194 = false; - field_195 = false; - field_196 = false; - field_197 = false; - test_pv = false; - option = 0; -} - -TaskPvGame::Data::Data() : field_0(), init_data(), field_190(), field_191(), no_fail(), -field_193(), field_194(), field_195(), field_196(), option() { - Reset(); -} - -TaskPvGame::Data::~Data() { - -} - -void TaskPvGame::Data::Clear() { - se_name.clear(); - slide_se_name.clear(); - chainslide_first_name.clear(); - chainslide_sub_name.clear(); - chainslide_success_name.clear(); - chainslide_failure_name.clear(); - slidertouch_name.clear(); -} - -void TaskPvGame::Data::Reset() { - field_0 = 1; - init_data.reset(); - Clear(); - field_190 = false; - field_191 = true; - no_fail = false; - field_193 = true; - field_194 = false; - field_195 = false; - field_196 = false; - option = 0; -} - -TaskPvGame::TaskPvGame() { - -} - -TaskPvGame::~TaskPvGame() { - -} - -bool TaskPvGame::Init() { - //Load(data); - //touch_util::touch_reaction_set_enable(0); - return true; -} - -bool TaskPvGame::Ctrl() { - return false; -} - -bool TaskPvGame::Dest() { - return true; -} - -void TaskPvGame::Disp() { - -} - -bool task_pv_game_add_task(TaskPvGame::Args& args) { - return true; - if (!task_pv_game) - task_pv_game = new TaskPvGame; - - task_pv_game->data.field_0 = 1; - task_pv_game->data.init_data = args.init_data; - task_pv_game->data.se_name.assign(args.se_name); - task_pv_game->data.slide_se_name.assign(args.slide_se_name); - task_pv_game->data.chainslide_first_name.assign(args.chainslide_first_name); - task_pv_game->data.chainslide_sub_name.assign(args.chainslide_sub_name); - task_pv_game->data.chainslide_success_name.assign(args.chainslide_success_name); - task_pv_game->data.chainslide_failure_name.assign(args.chainslide_failure_name); - task_pv_game->data.slidertouch_name.assign(args.slidertouch_name); - task_pv_game->data.field_190 = args.field_190; - task_pv_game->data.field_191 = !args.field_195; - task_pv_game->data.no_fail = args.no_fail; - if (args.field_191) { - task_pv_game->data.field_0 = 2; - task_pv_game->data.field_193 = args.field_193; - } - else - task_pv_game->data.field_193 = 1; - task_pv_game->data.field_194 = args.field_195; - task_pv_game->data.field_195 = args.field_196; - task_pv_game->data.field_196 = args.field_197; - task_pv_game->data.option = args.option; - - if (args.test_pv) - return app::TaskWork::AddTask(task_pv_game, "PVGAME"); - else - return app::TaskWork::AddTask(task_pv_game, 0, "PVGAME"); -} - -bool task_pv_game_check_task_ready() { - return app::TaskWork::CheckTaskReady(task_pv_game); -} - -bool task_pv_game_del_task() { - return true; - if (!app::TaskWork::CheckTaskReady(task_pv_game)) { - delete task_pv_game; - task_pv_game = 0; - return true; - } - - task_pv_game->DelTask(); - return false; -} - -pv_game_music_args::pv_game_music_args() : type(), start(), field_2C() { - -} - -pv_game_music_args::~pv_game_music_args() { - -} - -pv_game_music_ogg::pv_game_music_ogg() : playback() { - playback = ogg_playback_data_get(0); -} - -pv_game_music_ogg::~pv_game_music_ogg() { - if (playback) { - playback->Reset(); - playback = 0; - } -} - -pv_game_music::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; -} - -pv_game_music::~pv_game_music() { - -} - -bool 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 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 = 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.0f) - 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)((float_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 & 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 pv_game_music::exclude_flags(pv_game_music_flags flags) { - if ((this->flags & PV_GAME_MUSIC_OGG) && (flags & PV_GAME_MUSIC_OGG)) - ogg_free(); - enum_and(this->flags, ~flags); -} - -void 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 PV_GAME_MUSIC_ACTION_STOP: - stop(); - break; - case PV_GAME_MUSIC_ACTION_PAUSE: - set_pause(1); - break; - case PV_GAME_MUSIC_ACTION_PLAY: - play(); - break; - } -} - -void 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 PV_GAME_MUSIC_ACTION_STOP: - stop(); - break; - case PV_GAME_MUSIC_ACTION_PAUSE: - set_pause(1); - break; - case PV_GAME_MUSIC_ACTION_PLAY: - play(); - break; - } -} - -void 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 = 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.0f; - fade_out.action = play_on_end - ? PV_GAME_MUSIC_ACTION_PLAY : 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 - ? PV_GAME_MUSIC_ACTION_PLAY : PV_GAME_MUSIC_ACTION_STOP; - } -} - -int32_t pv_game_music::get_master_volume(int32_t index) { - if (!index) - return master_volume; - return 0; -} - -int32_t pv_game_music::get_volume(int32_t index) { - if (!index) - return volume; - return 0; -} - -int32_t pv_game_music::include_flags(pv_game_music_flags flags) { - if (!(this->flags & PV_GAME_MUSIC_OGG) && (flags & PV_GAME_MUSIC_OGG)) - ogg_init(); - enum_or(this->flags, flags); - return 0; -} - -int32_t 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 pv_game_music::ogg_free() { - if (ogg) { - delete ogg; - ogg = 0; - } -} - -int32_t pv_game_music::ogg_init() { - if (ogg) - return 0; - - ogg = new pv_game_music_ogg; - return ogg->playback ? 0 : -1; -} - -int32_t pv_game_music::ogg_load(std::string&& file_path, float_t start) { - if (!(flags & 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 pv_game_music::ogg_reset() { - sound_stream_array_reset(); - include_flags(PV_GAME_MUSIC_OGG); - return 0; -} - -int32_t pv_game_music::ogg_stop() { - if (!(flags & PV_GAME_MUSIC_OGG)) - return -2; - - ogg->playback->Stop(); - ogg->file_path.clear(); - loaded = false; - return 0; -} - -int32_t 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 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 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 pv_game_music::play_or_stop() { - if (play_on_end) - return play(); - else - return stop(); -} - -void 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 = 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 pv_game_music::reset_args() { - args.type = 0; - args.file_path.clear(); - args.start = 0.0f; - args.field_2C = false; -} - -void 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 pv_game_music::set_channel_pair_volume(int32_t channel_pair, int32_t value) { - if (!(flags & PV_GAME_MUSIC_OGG)) - return -2; - - ogg->playback->SetChannelPairVolume(channel_pair, ratio_to_db((float_t)value * 0.01f)); - return 0; -} - -int32_t 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 pv_game_music::set_fade_out(float_t time, bool stop) { - reset(); - if (time == 0.0f) - 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 ? PV_GAME_MUSIC_ACTION_STOP - : PV_GAME_MUSIC_ACTION_PAUSE; - } - return 0; -} - -int32_t pv_game_music::set_master_volume(int32_t value) { - if (!(flags & 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 pv_game_music::set_ogg_args(std::string&& file_path, float_t start, bool wait_load) { - if (!(flags & 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 pv_game_music::set_ogg_pause_state(uint8_t pause_state) { - if ((flags & PV_GAME_MUSIC_OGG) == 0) - return -2; - - OggPlayback* playback = ogg->playback; - if (playback->GetFileState() == OGG_FILE_HANDLER_FILE_STATE_PLAYING) - playback->SetPauseState((OggFileHandlerPauseState)pause_state); - return 0; -} - -int32_t pv_game_music::set_pause(int32_t pause) { - if ((flags & PV_GAME_MUSIC_OGG) != 0) - set_ogg_pause_state(pause != 0); - pause = pause == 1; - return 0; -} - -void pv_game_music::set_volume_map(int32_t index, int32_t value) { - if (!index) { - if (flags & PV_GAME_MUSIC_OGG) - set_master_volume(value); - volume = value; - } -} - -int32_t pv_game_music::stop() { - if (flags & PV_GAME_MUSIC_OGG) - ogg_stop(); - reset(); - reset_args(); - pause = false; - return 0; -} - -void pv_game_music::stop_reset_flags() { - stop(); - exclude_flags(PV_GAME_MUSIC_ALL); -} - -static pv_game_music* pv_game_music_get() { - return pv_game_music_data; -} - -static struc_14* sub_14013C8C0() { - return &stru_140C94438; -} diff --git a/src/ReDIVA/pv_game.hpp b/src/ReDIVA/pv_game.hpp deleted file mode 100644 index e4bf079e..00000000 --- a/src/ReDIVA/pv_game.hpp +++ /dev/null @@ -1,918 +0,0 @@ -/* - by korenkonder - GitHub/GitLab: korenkonder -*/ - -#pragma once - -#include -#include -#include -#include -#include -#include "../KKdLib/dsc.hpp" -#include "../CRE/rob/rob.hpp" -#include "../CRE/auth_2d.hpp" -#include "../CRE/auth_3d.hpp" -#include "../CRE/ogg_vorbis.hpp" -#include "../CRE/pv_db.hpp" -#include "../CRE/stage.hpp" -#include "../CRE/task.hpp" -#include "task_window.hpp" - -enum pv_game_aet { - PV_GAME_AET_0 = 0, - PV_GAME_AET_1, - PV_GAME_AET_VALUE_TEXT, - PV_GAME_AET_COMBO, - PV_GAME_AET_CHANCE_TXT, - PV_GAME_AET_CHANCE_POINT, - PV_GAME_AET_SLIDE_POINT, - PV_GAME_AET_MAX_SLIDE_POINT, - PV_GAME_AET_MAX_SLIDE_NUM_PLUS, - PV_GAME_AET_MAX_SLIDE_NUM_0, - PV_GAME_AET_MAX_SLIDE_NUM_1, - PV_GAME_AET_MAX_SLIDE_NUM_2, - PV_GAME_AET_MAX_SLIDE_NUM_3, - PV_GAME_AET_MAX_SLIDE_NUM_4, - PV_GAME_AET_MAX_SLIDE_NUM_5, - PV_GAME_AET_MAX_SLIDE_NUM_6, - PV_GAME_AET_FRAME_BOTTOM, - PV_GAME_AET_FRAME_UP, - PV_GAME_AET_CHANCE_FRAME_BOTTOM, - PV_GAME_AET_CHANCE_FRAME_TOP, - PV_GAME_AET_20, - PV_GAME_AET_STAGE_INFO, - PV_GAME_AET_SONG_ENERGY_BASE, - PV_GAME_AET_SONG_ENERGY_BASE_REACH, - PV_GAME_AET_SONG_ENERGY_NORMAL, - PV_GAME_AET_SONG_ENERGY_REACH, - PV_GAME_AET_SONG_ENERGY_FULL, - PV_GAME_AET_SONG_ENERGY_EFF_NORMAL, - PV_GAME_AET_SONG_ENERGY_EFF_REACH, - PV_GAME_AET_SONG_ENERGY_CLEAR_TXT, - PV_GAME_AET_SONG_ENERGY_BORDER_GREAT, - PV_GAME_AET_SONG_ENERGY_BORDER_EXCELLENT, - PV_GAME_AET_SONG_ENERGY_BORDER_RIVAL, - PV_GAME_AET_SONG_ENERGY_EDGE_LINE02, - PV_GAME_AET_SONG_ENERGY_BORDER, - PV_GAME_AET_SONG_ENERGY_NOT_CLEAR, - PV_GAME_AET_SONG_ENERGY_NOT_CLEAR_TXT, - PV_GAME_AET_NEXT_INFO, - PV_GAME_AET_LEVEL_INFO, - PV_GAME_AET_OPTION_INFO_BASE, - PV_GAME_AET_OPTION_INFO_HISPEED, - PV_GAME_AET_OPTION_INFO_HIDDEN, - PV_GAME_AET_OPTION_INFO_SUDDEN, - PV_GAME_AET_SONG_ICON, - PV_GAME_AET_SUCCESS_INFO, - PV_GAME_AET_DEMO_LOGO, - PV_GAME_AET_46, - PV_GAME_AET_DEMO_FONT, - PV_GAME_AET_FRONT_0, - PV_GAME_AET_FRONT_1, - PV_GAME_AET_FRONT_2, - PV_GAME_AET_FRONT_3, - PV_GAME_AET_FRONT_4, - PV_GAME_AET_FRONT_5, - PV_GAME_AET_FRONT_6, - PV_GAME_AET_FRONT_7, - PV_GAME_AET_FRONT_LOW_0, - PV_GAME_AET_FRONT_LOW_1, - PV_GAME_AET_FRONT_LOW_2, - PV_GAME_AET_FRONT_LOW_3, - PV_GAME_AET_FRONT_LOW_4, - PV_GAME_AET_FRONT_LOW_5, - PV_GAME_AET_FRONT_LOW_6, - PV_GAME_AET_FRONT_LOW_7, - PV_GAME_AET_FRONT_3D_SURF_0, - PV_GAME_AET_FRONT_3D_SURF_1, - PV_GAME_AET_FRONT_3D_SURF_2, - PV_GAME_AET_FRONT_3D_SURF_3, - PV_GAME_AET_FRONT_3D_SURF_4, - PV_GAME_AET_FRONT_3D_SURF_5, - PV_GAME_AET_FRONT_3D_SURF_6, - PV_GAME_AET_FRONT_3D_SURF_7, - PV_GAME_AET_BACK_0, - PV_GAME_AET_BACK_1, - PV_GAME_AET_BACK_2, - PV_GAME_AET_BACK_3, - PV_GAME_AET_BACK_4, - PV_GAME_AET_BACK_5, - PV_GAME_AET_BACK_6, - PV_GAME_AET_BACK_7, - PV_GAME_AET_TITLE_IMAGE, - PV_GAME_AET_WHITE_FADE, - PV_GAME_AET_BLACK_FADE, - PV_GAME_AET_83, - PV_GAME_AET_84, - PV_GAME_AET_TOP_FRONT, - PV_GAME_AET_BOTTOM_FRONT, - PV_GAME_AET_TOP_BACK, - PV_GAME_AET_BOTTOM_BACK, - PV_GAME_AET_EDIT_EFFECT, - PV_GAME_AET_MAX, -}; - -enum pv_game_music_action { - PV_GAME_MUSIC_ACTION_NONE = 0, - PV_GAME_MUSIC_ACTION_STOP, - PV_GAME_MUSIC_ACTION_PAUSE, - PV_GAME_MUSIC_ACTION_PLAY, - PV_GAME_MUSIC_ACTION_MAX, -}; - -enum pv_game_music_flags : uint8_t { - PV_GAME_MUSIC_FLAG_1 = 0x01, - PV_GAME_MUSIC_AIX = 0x02, - PV_GAME_MUSIC_OGG = 0x04, - PV_GAME_MUSIC_FLAG_8 = 0x08, - PV_GAME_MUSIC_FLAG_10 = 0x10, - PV_GAME_MUSIC_FLAG_20 = 0x20, - PV_GAME_MUSIC_FLAG_40 = 0x40, - PV_GAME_MUSIC_FLAG_80 = 0x80, - - PV_GAME_MUSIC_ALL = 0xFF, -}; - -struct pv_game_music_fade { - int32_t start; - int32_t value; - float_t time; - float_t remain; - pv_game_music_action action; - bool enable; -}; - -struct pv_game_music_args { - int32_t type; - std::string file_path; - float_t start; - bool field_2C; - - pv_game_music_args(); - ~pv_game_music_args(); -}; - -struct pv_game_music_ogg { - OggPlayback* playback; - std::string file_path; - - pv_game_music_ogg(); - ~pv_game_music_ogg(); -}; - -struct pv_game_music { - pv_game_music_flags flags; - bool pause; - int32_t volume; - int32_t master_volume; - int32_t channel_pair_volume[4]; - pv_game_music_fade fade_in; - pv_game_music_fade fade_out; - bool no_fade; - float_t no_fade_remain; - float_t fade_out_time_req; - pv_game_music_action fade_out_action_req; - int32_t type; - std::string file_path; - float_t start; - float_t end; - bool play_on_end; - float_t fade_in_time; - float_t fade_out_time; - bool field_9C; - pv_game_music_args args; - bool loaded; - pv_game_music_ogg* ogg; - - pv_game_music(); - ~pv_game_music(); - - bool check_args(int32_t type, std::string&& file_path, float_t start); - void ctrl(float_t delta_time); - void exclude_flags(pv_game_music_flags flags); - void fade_in_end(); - void fade_out_end(); - void 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); - int32_t get_master_volume(int32_t index); - int32_t get_volume(int32_t index); - int32_t include_flags(pv_game_music_flags flags); - int32_t load(int32_t type, std::string&& file_path, bool wait_load, float_t time, bool a6); - void ogg_free(); - int32_t ogg_init(); - int32_t ogg_load(std::string&& file_path, float_t start); - int32_t ogg_reset(); - int32_t ogg_stop(); - int32_t play(); - int32_t 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); - void 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); - int32_t play_or_stop(); - void reset(); - void reset_args(); - void set_args(int32_t type, std::string&& file_path, float_t start, bool a5); - int32_t set_channel_pair_volume(int32_t channel_pair, int32_t value); - int32_t set_channel_pair_volume_map(int32_t channel_pair, int32_t value); - int32_t set_fade_out(float_t time, bool stop); - int32_t set_master_volume(int32_t value); - int32_t set_ogg_args(std::string&& file_path, float_t start, bool wait_load); - int32_t set_ogg_pause_state(uint8_t pause_state); - int32_t set_pause(int32_t pause); - void set_volume_map(int32_t index, int32_t value); - int32_t stop(); - void stop_reset_flags(); -}; - -struct pv_play_data_set_motion { - float_t frame_speed; - int32_t motion_id; - float_t frame; - float_t duration; - bool field_10; - MotionBlendType blend_type; - bool disable_eye_motion; - int32_t motion_index; - int64_t dsc_time; - float_t dsc_frame; -}; - -struct pv_play_data_motion { - bool enable; - int32_t motion_index; - int64_t time; -}; - -struct dsc_set_item { - int32_t time; - int32_t item_index; - int32_t pv_branch_mode; -}; - -struct dsc_set_motion { - int32_t time; - int32_t motion_index; - int32_t pv_branch_mode; -}; - -struct pv_play_data_motion_data { - rob_chara* rob_chr; - float_t current_time; - float_t duration; - vec3 start_pos; - vec3 end_pos; - float_t start_rot; - float_t end_rot; - float_t mot_smooth_len; - std::vector set_motion; - std::vector set_item; - - pv_play_data_motion_data(); - ~pv_play_data_motion_data(); - - void clear(); - void reset(); -}; - -struct pv_play_data { - std::vector motion; - rob_chara* rob_chr; - std::list set_motion; - bool disp; - int8_t field_31; - int32_t field_34; - pv_play_data_motion_data motion_data; - - pv_play_data(); - ~pv_play_data(); - - void reset(); -}; - -struct pv_disp2d { - int32_t pv_id; - int32_t title_start_2d_field; - int32_t title_end_2d_field; - int32_t title_start_2d_low_field; - int32_t title_end_2d_low_field; - int32_t title_start_3d_field; - int32_t title_end_3d_field; - bool target_shadow_type; - int32_t pv_spr_set_id; - int32_t pv_aet_set_id; - int32_t pv_main_aet_id; - std::string title_2d_layer; - - pv_disp2d(); - ~pv_disp2d(); -}; - -struct pv_data_camera { - bool enable; - int32_t id; - int64_t time; - - pv_data_camera(); -}; - -struct struc_540 { - int32_t field_0; - vec2 field_4; - vec2 field_C; - int32_t field_14; - int32_t field_18; - int32_t field_1C; - int32_t field_20; -}; - -struct struc_498 { - int32_t field_0; - struc_540 field_4[4]; - int32_t field_94; - int64_t field_98; - int64_t field_A0; - int32_t field_A8; - int32_t field_AC; -}; - -struct struc_563 { - int64_t field_0; - int64_t field_8; - int64_t field_10; - int64_t field_18; - int64_t dsc_time; - int64_t field_28; -}; - -struct struc_676 { - bool field_0[6]; - pv_play_data_set_motion field_8[6]; - int64_t field_128; - int64_t field_130; - int64_t field_138; - int64_t field_140; - bool field_148[6]; - struc_563 field_150[6]; - float_t field_270[6]; - bool field_288[6]; - int32_t field_290[6]; - float_t field_2A8[6]; - int8_t field_2C0; - int32_t field_2C4; - int32_t field_2C8; - float_t field_2CC; - int64_t field_2D0; -}; - -struct pv_game; - -struct pv_game_pv_data { - int8_t field_0; - int32_t state; - bool play; - uint32_t dsc_buffer[45000]; - int32_t dsc_buffer_counter; - int64_t field_2BF30; - int64_t field_2BF38; - int64_t curr_time; - float_t curr_time_float; - float_t prev_time_float; - bool field_2BF50; - int64_t field_2BF58; - bool field_2BF60; - int32_t field_2BF64; - int64_t field_2BF68; - int32_t chara_id; - pv_game* pv_game; - //struc_162* field_2BF80; - pv_game_music* music; - p_file_handler dsc_file_handler; - float_t target_anim_fps; - float_t anim_frame_speed; - float_t target_flying_time; - int32_t time_signature; - ssize_t dsc_time; - int32_t field_2BFB0; - int32_t field_2BFB4; - int32_t field_2BFB8; - int32_t field_2BFBC; - int8_t field_2BFC0; - bool music_play; - int32_t field_2BFC4; - bool pv_end; - float_t fov; - float_t min_dist; - int8_t field_2BFD4; - int8_t field_2BFD5; - pv_play_data playdata[6]; - pv_data_camera data_camera[3]; - std::vector data_camera_branch_fail; - std::vector data_camera_branch_success; - std::vector set_motion[6]; - prj::vector_pair change_field_branch_fail; - prj::vector_pair change_field_branch_success; - int64_t change_field_branch_time; - bool scene_fade_enable; - float_t scene_fade_frame; - float_t scene_fade_duration; - float_t scene_fade_start_alpha; - float_t scene_fade_end_alpha; - vec3 scene_fade_color; - bool has_signature; - bool has_perf_id; - int32_t field_2C4E4; - std::vector field_2C4E8; - size_t field_2C500; - float_t scene_rot_y; - mat4 scene_rot_mat; - float_t field_2C54C; - int32_t field_2C550; - int32_t branch_mode; - int32_t first_challenge_note; - int32_t last_challenge_note; - struc_676 field_2C560; - - pv_game_pv_data(); - ~pv_game_pv_data(); - - void reset(); - void reset_camera_post_process(); -}; - -struct pv_game_play_data { - bool pv_set; - uint32_t aet_ids[PV_GAME_AET_MAX]; - bool aet_ids_enable[PV_GAME_AET_MAX]; - float_t field_1C8[2]; - float_t field_1D0[2]; - float_t field_1D8[2]; - float_t field_1E0[2]; - float_t field_1E8[2]; - float_t field_1F0[2]; - bool disp[2]; - int32_t field_1FC[2]; - float_t field_204[2]; - float_t field_20C[2]; - int32_t frame_state; - bool field_218; - bool fade_begin; - bool fade_end; - pv_game_aet fade; - int32_t skin_danger_frame; - aet_layout_data song_txt[2]; - int32_t field_2FC; - int32_t chance_result; - int32_t chance_points; - vec2 chance_points_pos; - int32_t field_310; - int32_t slide_points; - vec2 slide_points_pos; - int32_t max_slide_points; - vec2 max_slide_points_pos; - int32_t pv_spr_set_id; - int32_t pv_aet_set_id; - int32_t pv_main_aet_id; - int32_t stage_index; - int32_t field_33C; - AetComp comp; - float_t field_350; - bool field_354; - int32_t value_text_spr_index; - bool not_clear; - int32_t spr_set_back_id; - bool loaded; - int32_t state; - int32_t field_36C; - bool score_preview_update; - int32_t field_374; - bool field_378; - float_t field_37C; - float_t score_preview_speed; - uint32_t score_preview; - int32_t value_text_display; - float_t field_38C; - int32_t value_text_index; - float_t value_text_time_offset; - int32_t combo_state; - int32_t combo_count; - float_t combo_disp_time; - vec2 draw_pos; - int32_t field_3AC; - int32_t field_3B0; - int32_t field_3B4; - int32_t field_3B8; - int32_t field_3BC; - bool aix; - bool ogg; - int32_t field_3C4; - std::string field_3C8; - std::string se_name; - std::string pvbranch_success_se_name; - std::string slide_name; - std::string chainslide_first_name; - std::string chainslide_sub_name; - std::string chainslide_success_name; - std::string chainslide_failure_name; - std::string slidertouch_name; - std::string other_se_name; - std::string other_slide_name; - std::string other_chainslide_first_name; - std::string other_chainslide_sub_name; - std::string other_chainslide_success_name; - std::string other_chainslide_failure_name; - std::string other_slidertouch_name; - std::string song_file_name; - int32_t field_5E8; - float_t field_5EC; - int32_t option; - float_t field_5F4; - char lyric[76]; - uint8_t lyric_index; - vec4u8 lyrics_color; - bool field_64C; - int32_t field_650; - float_t field_654; - int32_t field_658; - float_t field_65C; - - pv_game_play_data(); - ~pv_game_play_data(); - - void reset(); - - void sub_1401362C0(); -}; - -struct pv_game_chara { - chara_index chara_index; - int32_t cos; - int32_t chara_id; - rob_chara_pv_data pv_data; - rob_chara* rob_chr; - std::vector motion_ids; - std::vector motion_face_ids; - - pv_game_chara(); - ~pv_game_chara(); -}; - -struct pv_game_edit_effect { - int8_t field_0; - float_t field_4; - float_t field_8; - float_t field_C; - float_t field_10; - bool field_14; -}; - -struct pv_game_field { - int32_t stage_index; - std::vector auth_3d_uids; - std::vector auth_3d_ids; - std::map auth_3d_frame_list; - int32_t light_auth_3d_uid; - int32_t light_auth_3d_id; - int32_t light_frame; - std::vector aet_set_names[4]; - std::vector aet_set_ids[4]; - std::map, int32_t> aet[4]; - int32_t spr_set_back_id; - bool stage_flag; - int32_t npr_type; - int32_t cam_blur; - bool sdw_off; - std::vector play_eff_list; - std::vector stop_eff_list; - std::vector field_1A0; - - pv_game_field(); - ~pv_game_field(); -}; - -struct pv_game_itmpv { - int32_t auth_3d_id; - int32_t field_4; - int64_t time; -}; - -struct struc_269 { - prj::vector_pair data; - std::vector auth_3d_ids; - int32_t field_30; - int32_t field_34; - - struc_269(); - ~struc_269(); -}; - -struct pv_game_chreff { - chara_index src_chara_index; - chara_index dst_chara_index; - std::bitset<128> type; - std::string src_auth_3d; - std::string dst_auth_3d; - std::string src_auth_3d_category; - std::string dst_auth_3d_category; - int32_t src_auth_3d_uid; - int32_t dst_auth_3d_uid; - - pv_game_chreff(); - ~pv_game_chreff(); -}; - -struct pv_effect_resource { - std::string name; - float_t emission; - - pv_effect_resource(); - ~pv_effect_resource(); -}; - -struct pv_game_data { - pv_game_pv_data pv_data; - pv_game_play_data play_data; - int32_t field_2CE98; - int8_t field_2CE9C[128]; - int32_t field_2CF1C; - int8_t field_2CF20; - int32_t field_2CF24; - float_t field_2CF28; - float_t field_2CF2C; - int32_t field_2CF30; - int32_t field_2CF34; - int32_t field_2CF38; - int32_t life_gauge; - int32_t score_final; - int32_t challenge_time_total_bonus; - int32_t combo; - int32_t challenge_time_combo_count; - int32_t max_combo; - int32_t total_hit_count[5]; - int32_t hit_count[5]; - int32_t current_reference_score; - int32_t target_count; - int32_t field_2CF84; - int32_t field_2CF88; - float_t field_2CF8C; - int32_t score_slide_chain_bonus; - int32_t slide_chain_length; - int32_t field_2CF98; - int32_t field_2CF9C; - int16_t field_2CFA0; - int32_t field_2CFA4; - pv_db_pv* pv; - int32_t field_2CFB0; - int32_t chance_point; - int32_t reference_score; - int32_t field_2CFBC; - int32_t field_2CFC0; - int32_t field_2CFC4; - std::vector field_2CFC8; - int32_t field_2CFE0; - int32_t field_2CFE4; - size_t notes_passed; - int32_t field_2CFF0; - float_t song_energy; - float_t song_energy_base; - float_t song_energy_border; - int32_t life_gauge_safety_time; - int32_t life_gauge_border; - int32_t stage_index; - bool field_2D00C; - bool no_fail; - bool field_2D00E; - bool changed_field; - int64_t challenge_time_start; - int64_t challenge_time_end; - int64_t max_time; - float_t max_time_float; - float_t current_time_float; - uint64_t current_time; - float_t current_time_float_dup; - float_t field_2D03C; - int32_t score_hold_multi; - uint32_t score_hold; - int32_t score_slide; - bool has_slide; - bool has_success_se; - pv_disp2d* pv_disp2d; - int32_t life_gauge_final; - bool hit_border; - int8_t field_2D05D; - int8_t field_2D05E; - int8_t field_2D05F; - bool title_image_init; - bool field_2D061; - bool field_2D062; - bool field_2D063; - bool has_auth_3d_frame; - bool has_light_frame; - bool has_aet_frame[4]; - bool has_aet_list[4]; - uint32_t field_index; - int32_t edit_effect_index; - int32_t slidertouch_counter; - int32_t change_field_branch_success_counter; - int32_t field_2D080; - int32_t field_2D084; - int32_t life_gauge_bonus; - int32_t life_gauge_total_bonus; - int8_t field_2D090; - int8_t field_2D091; - int8_t field_2D092; - int8_t field_2D093; - uint8_t field_2D094; - bool field_2D095; - int8_t field_2D096; - bool success; - int32_t field_2D098; - int32_t field_2D09C; - bool use_osage_play_data; - bool pv_end_fadeout; - float_t rival_percentage; - int32_t field_2D0A8; - int32_t field_2D0AC; - int32_t field_2D0B0[3]; - bool field_2D0BC; - bool next_stage; - bool field_2D0BE; - int8_t field_2D0BF; - int32_t field_2D0C0; - int32_t field_2D0C4; - pv_game_chara chara[6]; - std::vector motion_set_ids; - std::vector motion_set_face_ids; - std::vector obj_set_itmpv; - std::vector obj_set_handitem; - std::vector chreff_auth_3d_obj_set_ids; - std::vector field_2D770; - std::vector stgpvhrc_obj_set_ids; - std::vector ex_song_ex_auth_obj_set_ids; - std::vector stage_indices; - std::vector stage_infos; - bool field_2D7E8; - int32_t field_2D7EC; - std::vector spr_set_back_ids; - int32_t field_2D808; - int32_t field_2D80C; - std::vector edit_effect_aet_set_ids; - std::vector edit_effect_spr_set_ids; - std::vector edit_effect_aet_ids; - pv_game_edit_effect edit_effect; - uint32_t camera_auth_3d_uid; - int32_t field_2D874; - bool task_effect_init; - int32_t field_2D87C; - size_t current_field; - std::vector field_data; - bool field_2D8A0; - int32_t field_2D8A4; - std::map auth_3d_time; - std::map light_time; - std::map, int64_t> aet_time[4]; - std::string campv_string; - std::vector campv_auth_3d_uids; - std::map campv; - int32_t data_camera_id; - int32_t field_2D954; - std::string itmpv_string; - std::vector itmpv_auth_3d_uids; - std::map itmpv[6]; - std::vector itmpv_uids; - struc_269 field_2DA08[3]; - std::vector loaded_auth_3d_uids; - bool field_2DAC8; - int32_t field_2DACC; - std::vector auth_3d_categories; - std::map auth_3d; - std::vector chreff_auth_3d; - std::vector chreff_auth_3d_obj; - int8_t field_2DB28; - vec2 field_2DB2C; - int32_t field_2DB34; - time_struct field_2DB38; - std::vector effect_rs_list_hashes; - std::vector effect_rs_list; - - pv_game_data(); - ~pv_game_data(); -}; - -struct pv_game_item_mask { - bool arr[4]; - - pv_game_item_mask(); -}; - -struct pv_game { - bool loaded; - bool field_1; - bool field_2; - bool end_pv; - bool field_4; - int32_t state; - int32_t field_C; - int32_t pv_id; - bool field_14; - int32_t modules[6]; - rob_chara_pv_data_item items[6]; - pv_game_item_mask items_mask[6]; - pv_game_data data; - - pv_game(); - ~pv_game(); - - void ctrl(); - void disp(); - std::string get_effect_se_file_name(); - void load(); - void reset(); - bool unload(); -}; - -struct pv_game_init_data { - int32_t pv_id; - int32_t difficulty; - int32_t field_C; - int32_t score_percentage_clear; - int32_t life_gauge_safety_time; - int32_t life_gauge_border; - int32_t field_18; - int32_t modules[6]; - rob_chara_pv_data_item items[6]; - pv_game_item_mask items_mask[6]; - - pv_game_init_data(); - - void reset(); -}; - -class TaskPvGame : public app::Task { -public: - struct Args { - pv_game_init_data init_data; - std::string se_name; - std::string slide_se_name; - std::string chainslide_first_name; - std::string chainslide_sub_name; - std::string chainslide_success_name; - std::string chainslide_failure_name; - std::string slidertouch_name; - bool field_190; - bool field_191; - bool no_fail; - bool field_193; - bool field_194; - bool field_195; - bool field_196; - bool field_197; - bool test_pv; - int32_t option; - - Args(); - ~Args(); - - void Clear(); - void Reset(); - }; - - struct Data { - int32_t field_0; - pv_game_init_data init_data; - std::string se_name; - std::string slide_se_name; - std::string chainslide_first_name; - std::string chainslide_sub_name; - std::string chainslide_success_name; - std::string chainslide_failure_name; - std::string slidertouch_name; - bool field_190; - bool field_191; - bool no_fail; - bool field_193; - bool field_194; - bool field_195; - bool field_196; - int32_t option; - - Data(); - ~Data(); - - void Clear(); - void Reset(); - } data; - - TaskPvGame(); - virtual ~TaskPvGame() override; - - virtual bool Init() override; - virtual bool Ctrl() override; - virtual bool Dest() override; - virtual void Disp() override; -}; - -bool task_pv_game_add_task(TaskPvGame::Args& args); -bool task_pv_game_check_task_ready(); -bool task_pv_game_del_task(); diff --git a/src/ReDIVA/pv_game/game_2d.cpp b/src/ReDIVA/pv_game/game_2d.cpp new file mode 100644 index 00000000..48cd10a6 --- /dev/null +++ b/src/ReDIVA/pv_game/game_2d.cpp @@ -0,0 +1,522 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#include "game_2d.hpp" +#include "pv_game.hpp" + +const char* spr_life_bonus[] = { + "life_bonus", + "life_bonus_insu", +}; + +const char* spr_p_life_bonus_num[] = { + "p_life_bonus_num1_c", + "p_life_bonus_num2_c", + "p_life_bonus_num3_c", +}; + +const int32_t spr_p_life_bonus_num_spr[] = { + 3120, 3121, 3122, 3123, 3124, 3125, 3126, 3127, 3128, 3129 +}; + +const int32_t spr_p_life_safe_num_spr[] = { + 2867, 2868, 2869, 2870, 2871, 2872, 2873, 2874, 2875, 2876 +}; + +TaskGame2d* task_game_2d; + +Game2dEnergyUnit::Game2dEnergyUnit() : field_1B8(), field_1CC(), field_1D1(), no_fail(), field_1D4(), +max_value(), life_gauge_prev(), life_gauge_stable(), life_gauge_decrease(), life_gauge_increase(), +life_gauge_border(), life_gauge(), life_gauge_delay(), field_218(), life_gauge_safety(), +life_gauge_safety_time(), life_gauge_bonus(), field_224(), field_228(), field_22C() { + +} + +Game2dEnergyUnit::~Game2dEnergyUnit() { + +} + +void Game2dEnergyUnit::Init() { + data_struct* aft_data = &data_list[DATA_AFT]; + aet_database* aft_aet_db = &aft_data->data_ft.aet_db; + sprite_database* aft_spr_db = &aft_data->data_ft.spr_db; + + for (int32_t i = 0; i < 5; i++) { + field_1B8[i] = 0; + field_1CC[i] = false; + } + + field_1D1 = false; + no_fail = false; + field_1D4 = 0; + + AetComp comp; + aet_manager_init_aet_layout(&comp, 3, 0, (AetFlags)0, RESOLUTION_MODE_HD, 0, 0.0f, aft_aet_db, aft_spr_db); + + field_8[0] = *comp.Find("lifegauge_start_l"); + field_8[1] = *comp.Find("lifegauge_end_r"); + field_8[2] = *comp.Find("p_life_safe_num_01_c"); + field_8[3] = *comp.Find("p_life_safe_num_10_c"); + + field_1B8[0] = aet_manager_init_aet_object(3, /*game_skin_get()->check_skin() + ? "life_gauge_skin" : */ "life_gauge", spr::SPR_PRIO_11, AET_PLAY_ONCE, 0, 0, aft_aet_db, aft_spr_db); + field_1CC[0] = true; + + field_1B8[1] = aet_manager_init_aet_object(3, "life_gauge_full", + spr::SPR_PRIO_12, AET_LOOP, 0, 0, aft_aet_db, aft_spr_db); + aet_manager_set_obj_visible(field_1B8[1], false); + field_1CC[1] = false; + + field_1CC[3] = true; + + field_1D8 = sprite_manager_get_spr_rectangle(2569, aft_spr_db).size; + field_1E0.x = field_8[1].position.x - field_8[0].position.x; + field_1E0.y = field_1D8.y; + + max_value = 255.0; + life_gauge_prev = 0.0f; + life_gauge_stable = 0.0f; + life_gauge_decrease = 0.0f; + life_gauge_increase = 0.0f; + life_gauge_border = 0; + life_gauge = 0.0f; + life_gauge_delay = 0; + + pv_game* pv_game = pv_game_get(); + if (pv_game) { + float_t life_gauge = (float_t)pv_game->data.life_gauge; + life_gauge_prev = life_gauge; + life_gauge_stable = life_gauge; + life_gauge_decrease = life_gauge; + life_gauge_increase = life_gauge; + life_gauge_border = (float_t)pv_game->calculate_life_gauge_border(); + this->life_gauge = life_gauge; + life_gauge_delay = 0; + } + + field_218 = false; + + AetArgs args; + args.id.id = 3; + args.prio = spr::SPR_PRIO_13; + args.flags = AET_PLAY_ONCE; + args.layer_name = "life_safe_txt"; + args.mode = RESOLUTION_MODE_HD; + args.pos.x = life_gauge_border * field_1E0.x / max_value * 0.5f + field_8[0].position.x; + args.pos.y = field_1D8.y * 0.5f + field_8[0].position.y; + args.spr_db = aft_spr_db; + + field_1B8[2] = aet_manager_init_aet_object(args, aft_aet_db); + field_1CC[2] = true; + + field_1E8 = *(vec2*)&args.pos; + field_1F0 = *(vec2*)&args.pos; + + field_1B8[4] = aet_manager_init_aet_object(3, "life_gauge_insurance", spr::SPR_PRIO_13, AET_PLAY_ONCE, 0, 0, aft_aet_db, aft_spr_db); + field_1CC[4] = false; + + life_gauge_safety = false; + life_gauge_safety_time = 0.0f; + life_gauge_bonus = 0; +} + +void Game2dEnergyUnit::Ctrl() { + data_struct* aft_data = &data_list[DATA_AFT]; + aet_database* aft_aet_db = &aft_data->data_ft.aet_db; + sprite_database* aft_spr_db = &aft_data->data_ft.spr_db; + + float_t life_gauge = 0.0f; + bool life_gauge_safety = false; + float_t life_gauge_border = 0.0f; + float_t life_gauge_safety_time = 0.0f; + int32_t life_gauge_bonus = 0; + + pv_game* pv_game = pv_game_get(); + if (pv_game) { + life_gauge = (float_t)pv_game->data.life_gauge; + life_gauge_safety = pv_game->check_life_gauge_safety(); + life_gauge_border = (float_t)pv_game->calculate_life_gauge_border(); + life_gauge_safety_time = pv_game->get_life_gauge_safety_time(); + life_gauge_bonus = pv_game->data.life_gauge_bonus; + } + + this->life_gauge_safety_time = life_gauge_safety_time; + this->life_gauge_safety = life_gauge_safety; + + if (life_gauge_safety) + this->life_gauge_border = life_gauge_border; + else + this->life_gauge_border = 0.0f; + + if (life_gauge != this->life_gauge) { + if (life_gauge >= this->life_gauge) { + life_gauge_prev = life_gauge; + life_gauge_stable = this->life_gauge; + life_gauge_increase = life_gauge_prev; + life_gauge_decrease = life_gauge_stable; + } + else { + life_gauge_prev = this->life_gauge; + life_gauge_stable = life_gauge; + life_gauge_decrease = life_gauge_prev; + life_gauge_increase = life_gauge_stable; + } + + life_gauge_delay = 20; + + life_gauge_delay--; + } + else if (life_gauge_delay) + life_gauge_delay--; + else { + if (life_gauge_decrease > life_gauge_stable) + life_gauge_decrease -= 1.0f; + else if (life_gauge_stable < life_gauge_increase) + life_gauge_stable += 1.0f; + + life_gauge_prev = life_gauge_stable; + + if (life_gauge_delay) + life_gauge_delay--; + } + + field_1CC[1] = (int32_t)life_gauge == 255; + + if (life_gauge_bonus > 0) { + aet_manager_free_aet_object_reset(&field_1B8[3]); + field_1B8[3] = aet_manager_init_aet_object(3, spr_life_bonus[no_fail ? 1 : 0], + no_fail ? spr::SPR_PRIO_13 : spr::SPR_PRIO_12, AET_PLAY_ONCE, 0, 0, aft_aet_db, aft_spr_db); + this->life_gauge_bonus = life_gauge_bonus; + } + else if ((int32_t)life_gauge < 255 || field_1B8[3] != 0 && aet_manager_get_obj_end(field_1B8[3])) + aet_manager_free_aet_object_reset(&field_1B8[3]); + + field_1CC[2] = this->life_gauge_safety; + field_1F0.x = field_1E8.x; + field_1F0.y = (float_t)field_1D4 + field_1E8.y; + + field_1CC[4] = no_fail; + + for (int32_t i = 0; i < 5; i++) { + if (!field_1B8[i]) + continue; + + bool disp = field_1CC[i]; + if (!field_1D1) + disp = false; + + aet_manager_set_obj_visible(field_1B8[i], disp); + + vec3 pos; + pos.y = (float_t)field_1D4; + if (i == 2) + *(vec2*)&pos = field_1F0; + aet_manager_set_obj_position(field_1B8[i], pos); + } + + this->life_gauge = life_gauge; +} + +void Game2dEnergyUnit::Dest() { + for (int32_t i = 0; i < 5; i++) { + if (field_1B8[i]) { + aet_manager_free_aet_object(field_1B8[i]); + field_1B8[i] = 0; + } + + field_1CC[i] = false; + } +} + +void Game2dEnergyUnit::Disp() { + DispInner(); +} + +void Game2dEnergyUnit::DispInner() { + data_struct* aft_data = &data_list[DATA_AFT]; + aet_database* aft_aet_db = &aft_data->data_ft.aet_db; + sprite_database* aft_spr_db = &aft_data->data_ft.spr_db; + + if (!field_1D1 || !field_1CC[0]) + return; + + float_t v9 = life_gauge_stable * field_1E0.x * (1.0f / max_value); + + vec2 v11 = field_1D8; + if (v11.x > v9 * 0.5f) + v11.x = v9 * 0.5f; + + spr::SprArgs v49; + v49.SetSpriteSize({ v9, v11.y}); + v49.id.index = 2570; + v49.trans = field_8[0].position; + v49.trans.y = field_8[0].position.y + (float_t)field_1D4; + v49.resolution_mode_screen = field_8[0].mode; + v49.resolution_mode_sprite = field_8[0].mode; + v49.prio = spr::SPR_PRIO_12; + + spr::SprArgs v51; + v51.SetSpriteSize(v11); + v51.id.index = 2569; + v51.trans = field_8[0].position; + v51.trans.y = field_8[0].position.y + (float_t)field_1D4; + v51.resolution_mode_screen = field_8[0].mode; + v51.resolution_mode_sprite = field_8[0].mode; + v51.prio = spr::SPR_PRIO_12; + + spr::SprArgs v43; + v43.SetSpriteSize(v11); + v43.id.index = 2569; + v43.trans.x = field_8[0].position.x + v9; + v43.trans.y = field_8[0].position.y + (float_t)field_1D4; + v43.trans.z = field_8[0].position.z; + v43.scale.x = -1.0f; + v43.resolution_mode_screen = field_8[0].mode; + v43.resolution_mode_sprite = field_8[0].mode; + v43.prio = spr::SPR_PRIO_12; + + float_t v12 = life_gauge_decrease * field_1E0.x * (1.0f / max_value); + + vec2 v14 = field_1D8; + if (v14.x > v12 * 0.5f) + v14.x = v12 * 0.5f; + + spr::SprArgs v54; + v54.SetSpriteSize({ v12, v14.y }); + v54.id.index = 2583; + v54.trans = field_8[0].position; + v54.trans.y = field_8[0].position.y + (float_t)field_1D4; + v54.resolution_mode_screen = field_8[0].mode; + v54.resolution_mode_sprite = field_8[0].mode; + v54.prio = spr::SPR_PRIO_12; + + spr::SprArgs v52; + v52.SetSpriteSize(v14); + v52.id.index = 2581; + v52.trans = field_8[0].position; + v52.trans.y = field_8[0].position.y + (float_t)field_1D4; + v52.resolution_mode_screen = field_8[0].mode; + v52.resolution_mode_sprite = field_8[0].mode; + v52.prio = spr::SPR_PRIO_12; + + spr::SprArgs v46; + v46.SetSpriteSize(v14); + v46.id.index = 2581; + v46.trans.x = field_8[0].position.x + v12; + v46.trans.y = field_8[0].position.y + (float_t)field_1D4; + v46.trans.z = field_8[0].position.z; + v46.scale.x = -1.0f; + v46.resolution_mode_screen = field_8[0].mode; + v46.resolution_mode_sprite = field_8[0].mode; + v46.prio = spr::SPR_PRIO_12; + + float_t v15 = life_gauge_increase * field_1E0.x * (1.0f / max_value); + + vec2 v17 = field_1D8; + if (v17.x > v15 * 0.5f) + v17.x = v15 * 0.5f; + + spr::SprArgs v50; + v50.SetSpriteSize({ v15, v17.y }); + v50.id.index = 2582; + v50.trans = field_8[0].position; + v50.trans.y = field_8[0].position.y + (float_t)field_1D4; + v50.resolution_mode_screen = field_8[0].mode; + v50.resolution_mode_sprite = field_8[0].mode; + v50.prio = spr::SPR_PRIO_12; + + spr::SprArgs v48; + v48.SetSpriteSize(v17); + v48.id.index = 2580; + v48.trans = field_8[0].position; + v48.trans.y = field_8[0].position.y + (float_t)field_1D4; + v48.resolution_mode_screen = field_8[0].mode; + v48.resolution_mode_sprite = field_8[0].mode; + v48.prio = spr::SPR_PRIO_12; + + spr::SprArgs v44; + v44.SetSpriteSize(v17); + v44.id.index = 2580; + v44.trans.x = field_8[0].position.x + v15; + v44.trans.y = field_8[0].position.y + (float_t)field_1D4; + v44.trans.z = field_8[0].position.z; + v44.scale.x = -1.0f; + v44.resolution_mode_screen = field_8[0].mode; + v44.resolution_mode_sprite = field_8[0].mode; + v44.prio = spr::SPR_PRIO_12; + + float_t v18 = life_gauge_border * field_1E0.x * (1.0f / max_value); + + vec2 v19 = field_1D8; + if (v19.x > v15 * 0.5f) + v19.x = v15 * 0.5f; + + spr::SprArgs v53; + v53.SetSpriteSize({ v18, v19.y }); + v53.id.index = 2866; + v53.trans = field_8[0].position; + v53.trans.y = field_8[0].position.y + (float_t)field_1D4; + v53.resolution_mode_screen = field_8[0].mode; + v53.resolution_mode_sprite = field_8[0].mode; + v53.prio = spr::SPR_PRIO_13; + + spr::SprArgs v55; + v55.SetSpriteSize(v19); + v55.id.index = 2865; + v55.trans = field_8[0].position; + v55.trans.y = field_8[0].position.y + (float_t)field_1D4; + v55.resolution_mode_screen = field_8[0].mode; + v55.resolution_mode_sprite = field_8[0].mode; + v55.prio = spr::SPR_PRIO_13; + + spr::SprArgs v45; + v45.SetSpriteSize(v19); + v45.id.index = 2865; + v45.trans.z = field_8[0].position.z; + v45.trans.x = v18 + field_8[0].position.x; + v45.trans.y = field_8[0].position.y + (float_t)field_1D4; + v45.scale.x = -1.0f; + v45.resolution_mode_screen = field_8[0].mode; + v45.resolution_mode_sprite = field_8[0].mode; + v45.prio = spr::SPR_PRIO_13; + + spr::SprArgs v47; + v47.SetSpriteSize({ (life_gauge_prev - life_gauge_stable) * field_1E0.x * (1.0f / max_value), field_1D8.y }); + v47.kind = spr::SPR_KIND_RECT; + v47.trans.z = field_8[0].position.z; + v47.trans.x = field_8[0].position.x + field_1E0.x * life_gauge_stable * (1.0f / max_value); + v47.trans.y = field_8[0].position.y + (float_t)field_1D4; + v47.resolution_mode_screen = field_8[0].mode; + v47.resolution_mode_sprite = field_8[0].mode; + v47.prio = spr::SPR_PRIO_12; + v47.color = { 0xFF, 0xFF, 0xFF, (uint8_t)(int32_t)(life_gauge_delay * 0.05f * 255.0f) }; + + spr::put_sprite(v50, aft_spr_db); + spr::put_sprite(v48, aft_spr_db); + if (life_gauge_stable != life_gauge_increase) + spr::put_sprite(v44, aft_spr_db); + spr::put_sprite(v54, aft_spr_db); + spr::put_sprite(v52, aft_spr_db); + if (life_gauge_stable != life_gauge_decrease) + spr::put_sprite(v46, aft_spr_db); + spr::put_sprite(v49, aft_spr_db); + spr::put_sprite(v51, aft_spr_db); + if (life_gauge_stable == life_gauge_decrease) + spr::put_sprite(v43, aft_spr_db); + spr::put_sprite(v47, aft_spr_db); + + if (life_gauge_safety) { + spr::put_sprite(v53, aft_spr_db); + spr::put_sprite(v55, aft_spr_db); + spr::put_sprite(v45, aft_spr_db); + } + + if (life_gauge_safety) { + int32_t life_gauge_safety_time = (int32_t)this->life_gauge_safety_time; + if (life_gauge_safety_time <= 10) { + int32_t v23 = life_gauge_safety_time / 10; + int32_t v24 = life_gauge_safety_time % 10; + if (v23 > 0) { + aet_layout_data::put_sprite(spr_p_life_safe_num_spr[v23], spr::SPR_ATTR_CTR_CC, + spr::SPR_PRIO_13, &field_1F0, &field_8[3], aft_spr_db); + aet_layout_data::put_sprite(spr_p_life_safe_num_spr[v24], spr::SPR_ATTR_CTR_CC, + spr::SPR_PRIO_13, &field_1F0, &field_8[2], aft_spr_db); + } + else + aet_layout_data::put_sprite(spr_p_life_safe_num_spr[v24], spr::SPR_ATTR_CTR_CC, + spr::SPR_PRIO_13, &field_1F0, &field_8[3], aft_spr_db); + } + } + + if (!field_1B8[3]) + return; + + int32_t life_gauge_bonus = min_def(this->life_gauge_bonus, 999); + if (life_gauge_bonus > 999) + life_gauge_bonus = 999; + + int32_t max_digits = 3; + int32_t v28 = 0; + if (life_gauge_bonus > 0) + if (life_gauge_bonus < 10) { + max_digits = 1; + v28 = 2; + } + else if (life_gauge_bonus < 100) { + max_digits = 2; + v28 = 1; + } + + AetComp comp; + aet_manager_init_aet_layout(&comp, 3, spr_life_bonus[0], (AetFlags)0, RESOLUTION_MODE_HD, 0, + aet_manager_get_obj_frame(field_1B8[3]), aft_aet_db, aft_spr_db); + + vec2 size; + size.x = 0.0f; + size.y = (float_t)field_1D4; + AetComp::put_number_sprite(life_gauge_bonus, max_digits, &comp, &spr_p_life_bonus_num[v28], + spr_p_life_bonus_num_spr, spr::SPR_PRIO_14, &size, 0, aft_spr_db); +} + +TaskGame2d::TaskGame2d() : energy_unit_init() { + +} + +TaskGame2d::~TaskGame2d() { + +} + +bool TaskGame2d::Init() { + energy_unit_init = false; + energy_unit.Init(); + energy_unit_init = true; + return true; +} + +bool TaskGame2d::Ctrl() { + if (energy_unit_init) + energy_unit.Ctrl(); + return false; +} + +bool TaskGame2d::Dest() { + energy_unit_init = false; + energy_unit.Dest(); + return true; +} + +void TaskGame2d::Disp() { + if (energy_unit_init) + energy_unit.Disp(); +} + +bool task_game_2d_add_task() { + if (!task_game_2d) + task_game_2d = new TaskGame2d; + + return app::TaskWork::AddTask(task_game_2d, 0, "GAME_2D", 0); +} + +void task_game_2d_set_energy_unit_no_fail(bool value) { + task_game_2d->energy_unit.no_fail = value; +} + +void task_game_2d_sub_140372670(bool value) { + task_game_2d->energy_unit.field_1D1 = value; +} + +void task_game_2d_sub_1403726D0(int32_t value) { + task_game_2d->energy_unit.field_1D4 = value; +} + +bool task_game_2d_del_task() { + if (!task_game_2d) + return true; + + bool ret = task_game_2d->DelTask(); + delete task_game_2d; + task_game_2d = 0; + return ret; +} diff --git a/src/ReDIVA/pv_game/game_2d.hpp b/src/ReDIVA/pv_game/game_2d.hpp new file mode 100644 index 00000000..79a364c2 --- /dev/null +++ b/src/ReDIVA/pv_game/game_2d.hpp @@ -0,0 +1,69 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#pragma once + +#include "../../KKdLib/default.hpp" +#include "../../KKdLib/vec.hpp" +#include "../../CRE/auth_2d.hpp" +#include "../../CRE/task.hpp" + +class Game2dEnergyUnit { +public: + aet_layout_data field_8[4]; + uint32_t field_1B8[5]; + bool field_1CC[5]; + bool field_1D1; + bool no_fail; + int32_t field_1D4; + vec2 field_1D8; + vec2 field_1E0; + vec2 field_1E8; + vec2 field_1F0; + float_t max_value; + float_t life_gauge_prev; + float_t life_gauge_stable; + float_t life_gauge_decrease; + float_t life_gauge_increase; + float_t life_gauge_border; + float_t life_gauge; + int32_t life_gauge_delay; + bool field_218; + bool life_gauge_safety; + float_t life_gauge_safety_time; + int32_t life_gauge_bonus; + int32_t field_224; + int32_t field_228; + int32_t field_22C; + + Game2dEnergyUnit(); + virtual ~Game2dEnergyUnit(); + + virtual void Init(); + virtual void Ctrl(); + virtual void Dest(); + virtual void Disp(); + virtual void DispInner(); +}; + +class TaskGame2d : public app::Task { +public: + bool energy_unit_init; + Game2dEnergyUnit energy_unit; + + TaskGame2d(); + virtual ~TaskGame2d() override; + + virtual bool Init() override; + virtual bool Ctrl() override; + virtual bool Dest() override; + virtual void Disp() override; +}; + +bool task_game_2d_add_task(); +void task_game_2d_set_energy_unit_no_fail(bool value); +void task_game_2d_sub_140372670(bool value); +void task_game_2d_sub_1403726D0(int32_t value); +bool task_game_2d_del_task(); diff --git a/src/ReDIVA/pv_game/player_data.cpp b/src/ReDIVA/pv_game/player_data.cpp new file mode 100644 index 00000000..894b8f53 --- /dev/null +++ b/src/ReDIVA/pv_game/player_data.cpp @@ -0,0 +1,320 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#include "player_data.hpp" + +PlayerData player_data_array[2]; + +struc_765::struc_765() : field_10(), field_14() { + field_0 = -1; + field_4 = 5; + field_8 = -1; + field_C = -1; +} + +struc_713::struc_713() : field_0(), field_4(), field_8(), +field_C(), field_10(), field_14(), field_18() { + reset(); +} + +void struc_713::reset() { + field_0 = -1; + field_4 = -1; + field_8 = -1; + field_C = 0; + field_10 = 0; + field_14 = 0; + field_18 = 0; + field_1C = {}; + field_34 = {}; + field_4C = {}; + field_64 = {}; + field_7C = {}; + field_94 = {}; + field_AC = {}; + field_C4 = {}; + field_DC = {}; + field_F4 = {}; +} + +struc_761::struc_761() { + field_0 = -1; + field_8 = prj::time::get_default(); +} + +struc_762::struc_762() { + +} + +struc_766::struc_766() { + field_0 = -1; + field_4 = -1; + field_8 = -1; + field_C = -1; +} + +struc_767::struc_767() : field_0() { + for (bool& i : field_0) + i = true; +} + +struc_763::struc_763() { + field_0 = -1; + field_8 = prj::time::get_default(); +} + +struc_764::struc_764() { + +} + +struc_715::struc_715() { + field_0 = -1; + field_8 = -1; + field_10 = prj::time::get_default(); +} + +struc_768::struc_768() : field_0() { + +} + +struc_768::~struc_768() { + +} + +struc_769::struc_769() : field_0() { + +} + +struc_769::~struc_769() { + +} + +struc_770::struc_770() : field_0(), field_4(), field_8(), field_90() { + +} + +struc_770::~struc_770() { + +} + +struc_771::struc_771() : field_0() { + +} + +struc_771::~struc_771() { + +} + +struc_772::struc_772() { + field_0 = -999; + field_4 = -999; + field_8 = -999; + field_C = -999; +} + +PlayerData::Contest::Contest() : enable(), field_1(), field_4(), field_8(), field_C() { + +} + +void PlayerData::Contest::Reset() { + enable = false; + field_1 = false; + field_4 = -1; + field_8 = 0; + field_C = false; + + for (struc_713& i : field_10) + i.reset(); +} + +PlayerData::PlayerData() : field_0(), freeplay(), card_type(), field_A8(), play_data_id(), accept_index(), +start_index(), field_DC(), level(), level_plate_id(), level_plate_effect(), vocaloid_point(), hp_vol(), act_toggle(), +act_vol(), act_slide_vol(), module_equip(), module_equip_cmn(), field_1F0(), use_pv_module_equip(), +ch_pv_module_equip(), module_filter_kind(), field_2B8(), skin_equip(), skin_equip_cmn(), +use_pv_skin_equip(), btn_se_equip(), btn_se_equip_cmn(), use_pv_btn_se_equip(), slide_se_equip(), +slide_se_equip_cmn(), use_pv_slide_se_equip(), chainslide_se_equip(), chainslide_se_equip_cmn(), +use_pv_chainslide_se_equip(), slidertouch_se_equip(), slidertouch_se_equip_cmn(),use_pv_slidertouch_se_equip(), +field_584(), field_668(), field_66C(), field_D08(), field_D10(), field_D18(), field_D90(), clear_border(), +field_D98(), field_DA0(), field_DA8(), field_DB0(), field_DB8(), field_DC0(), field_DC8(), field_DD0(), +field_DD8(), field_DE0(), field_DE8(), field_DEC(), field_DF0(), field_DF4(), field_E00(), field_E28(), +field_E30(), field_E34(), game_opts(), field_E36(), field_E38(), field_E40(), field_EC0(), field_F40() { + field_D08 = -1; + field_D10 = -1; + field_D18 = -1; + + Reset(); + return; +} + +PlayerData::~PlayerData() { + +} + +void PlayerData::Reset() { + field_0 = false; + freeplay = false; + card_type = 0; + field_8.assign("0"); + field_28.assign("0"); + field_48.assign("0"); + field_68.assign("0"); + field_88.assign("0"); + field_A8 = -1; + field_B0.assign("0"); + + play_data_id = -1; + accept_index = -1; + start_index = -1; + + player_name.assign("NO-NAME"); + level_name.assign(""); + + level = 1; + level_plate_id = 0; + level_plate_effect = -1; + vocaloid_point = 0; + hp_vol = 0; + act_toggle = 1; + act_vol = 100; + act_slide_vol = 100; + + field_140.reset(); + + for (int32_t& i : module_equip) + i = 0; + + for (int32_t& i : module_equip_cmn) + i = 0; + + for (int32_t& i : field_1F0) + i = 0; + + field_208 = prj::time::get_default(); + field_210 = {}; + + use_pv_module_equip = false; + ch_pv_module_equip = false; + module_filter_kind = 0; + + for (int32_t& i : module_equip) + i = 0; + + for (int32_t& i : module_equip_cmn) + i = 0; + + for (int32_t& i : field_1F0) + i = -999; + + for (int64_t& i : field_2B8) + i = 0; + + for (struc_766& i : field_338) + i = {}; + + for (struc_766& i : field_398) + i = {}; + + for (struc_772& i : field_3F8) + i = {}; + + for (struc_767& i : field_458) + i = {}; + + for (struc_767& i : field_470) + i = {}; + + for (struc_767& i : field_488) + i = {}; + + field_4A0 = prj::time::get_default(); + field_4A8 = {}; + + for (auto& i : field_5D0) + i.clear(); + + field_630.clear(); + + skin_equip = 0; + skin_equip_cmn = 0; + use_pv_skin_equip = 0; + btn_se_equip = -1; + btn_se_equip_cmn = -1; + use_pv_btn_se_equip = 0; + slide_se_equip = -1; + slide_se_equip_cmn = -1; + use_pv_slide_se_equip = 0; + chainslide_se_equip = -1; + chainslide_se_equip_cmn = -1; + use_pv_chainslide_se_equip = 0; + slidertouch_se_equip = -1; + slidertouch_se_equip_cmn = -1; + use_pv_slidertouch_se_equip = 0; + + field_584 = 2; + + for (auto& i : mylist) + i.clear(); + + field_648.assign("************"); + field_668 = -1; + field_66C = 0; + contest.Reset(); + + for (struc_715& i : field_AB0) + i = {}; + + field_D20 = prj::time::get_default(); + field_D28.clear(); + field_D40.clear(); + field_D58.clear(); + field_D70.clear(); + + static prj::time start_of_2011 = prj::strptime("2011-01-01 00:00:00"); + field_D88 = start_of_2011; + + field_D90 = false; + clear_border = 0; + field_D98 = -1; + field_DA0 = -1; + field_DA8 = -1; + field_DB0 = -1; + field_DB8 = -1; + field_DC0 = -1; + field_DC8 = -1; + field_DD0 = -1; + field_DD8 = -1; + field_DE0 = -1; + field_DE8 = 0; + field_DEC = -1; + field_DF0 = 0; + + for (int32_t& i : field_DF4) + i = -1; + + for (int32_t& i : field_E00) + i = 0; + + field_E10.clear(); + if (field_E10.capacity() < 6) + field_E10.reserve(6); + + field_E28 = 0; + field_E30 = 0; + field_E34 = false; + game_opts = 0; + field_E38 = 0; + field_F40 = 2; + field_E36 = true; + + for (int64_t& i : field_E40) + i = 0; + + for (int64_t& i : field_EC0) + i = 0; +} + +PlayerData* player_data_array_get(uint32_t index) { + return &player_data_array[index]; +} diff --git a/src/ReDIVA/pv_game/player_data.hpp b/src/ReDIVA/pv_game/player_data.hpp new file mode 100644 index 00000000..8b480704 --- /dev/null +++ b/src/ReDIVA/pv_game/player_data.hpp @@ -0,0 +1,302 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#pragma once + +#include "../../KKdLib/default.hpp" +#include "../../KKdLib/prj/time.hpp" +#include +#include +#include + +struct struc_765 { + int32_t field_0; + int32_t field_4; + int32_t field_8; + int32_t field_C; + int32_t field_10; + int32_t field_14; + + struc_765(); +}; + +struct struc_713 { + int32_t field_0; + int32_t field_4; + int32_t field_8; + int32_t field_C; + int32_t field_10; + int32_t field_14; + int32_t field_18; + struc_765 field_1C; + struc_765 field_34; + struc_765 field_4C; + struc_765 field_64; + struc_765 field_7C; + struc_765 field_94; + struc_765 field_AC; + struc_765 field_C4; + struc_765 field_DC; + struc_765 field_F4; + + struc_713(); + + void reset(); +}; + +struct struc_761 { + int32_t field_0; + prj::time field_8; + + struc_761(); +}; + +struct struc_762 { + struc_761 field_0[10]; + + struc_762(); +}; + +struct struc_766 { + int32_t field_0; + int32_t field_4; + int32_t field_8; + int32_t field_C; + + struc_766(); +}; + +struct struc_767 { + bool field_0[4]; + + struc_767(); +}; + +struct struc_763 { + int32_t field_0; + prj::time field_8; + + struc_763(); +}; + +struct struc_764 { + struc_763 field_0[10]; + + struc_764(); +}; + +struct struc_715 { + int64_t field_0; + int32_t field_8; + prj::time field_10; + + struc_715(); +}; + +struct struc_758 { + int32_t pv_id; + int32_t edition; + int32_t field_8[6]; + int32_t field_20[24]; + int8_t field_80[6]; + int32_t field_88; + int32_t field_8C; + int32_t field_90; + int32_t field_94; + int32_t field_98; + int32_t field_9C; + int32_t field_A0; + int32_t field_A4; + int32_t field_A8; + int32_t field_AC; + int32_t field_B0; + int32_t field_B4; + int32_t field_B8; + int8_t field_BC; + int32_t field_C0; + int32_t field_C4; + int8_t field_C8; + int32_t field_CC; + int32_t field_D0; + int32_t rival_percentage; + int32_t field_D8; + int8_t field_DC[4]; + int8_t field_E0[4]; +}; + +struct struc_768 { + int64_t field_0; + std::string field_8; + std::string field_28; + + struc_768(); + ~struc_768(); +}; + +struct struc_769 { + int64_t field_0; + std::string field_8; + + struc_769(); + ~struc_769(); +}; + +struct struc_770 { + int32_t field_0; + int32_t field_4; + int64_t field_8; + std::string field_10; + std::string field_30; + std::string field_50; + std::string field_70; + bool field_90; + + struc_770(); + ~struc_770(); +}; + +struct struc_771 { + int64_t field_0; + std::string field_8; + std::string field_28; + std::string field_48; + + struc_771(); + ~struc_771(); +}; + +struct struc_772 { + int32_t field_0; + int32_t field_4; + int32_t field_8; + int32_t field_C; + + struc_772(); +}; + +struct PlayerData { + struct Contest { + bool enable; + bool field_1; + int32_t field_4; + int32_t field_8; + bool field_C; + struc_713 field_10[4]; + + Contest(); + + void Reset(); + }; + + bool field_0; + bool freeplay; + int32_t card_type; + std::string field_8; + std::string field_28; + std::string field_48; + std::string field_68; + std::string field_88; + int32_t field_A8; + std::string field_B0; + int32_t play_data_id; + int32_t accept_index; + int32_t start_index; + int32_t field_DC; + std::string player_name; + std::string level_name; + int32_t level; + int32_t level_plate_id; + int32_t level_plate_effect; + int32_t vocaloid_point; + int32_t hp_vol; + int8_t act_toggle; + int32_t act_vol; + int32_t act_slide_vol; + std::bitset<1000> field_140; + int32_t module_equip[6]; + int32_t module_equip_cmn[6]; + int32_t field_1F0[6]; + prj::time field_208; + struc_762 field_210; + bool use_pv_module_equip; + bool ch_pv_module_equip; + int32_t module_filter_kind; + int64_t field_2B8[16]; + struc_766 field_338[6]; + struc_766 field_398[6]; + struc_772 field_3F8[6]; + struc_767 field_458[6]; + struc_767 field_470[6]; + struc_767 field_488[6]; + prj::time field_4A0; + struc_764 field_4A8; + uint32_t skin_equip; + int32_t skin_equip_cmn; + int8_t use_pv_skin_equip; + int32_t btn_se_equip; + int32_t btn_se_equip_cmn; + bool use_pv_btn_se_equip; + int32_t slide_se_equip; + int32_t slide_se_equip_cmn; + bool use_pv_slide_se_equip; + int32_t chainslide_se_equip; + int32_t chainslide_se_equip_cmn; + bool use_pv_chainslide_se_equip; + int32_t slidertouch_se_equip; + int32_t slidertouch_se_equip_cmn; + bool use_pv_slidertouch_se_equip; + int32_t field_584; + std::vector mylist[3]; + std::vector field_5D0[4]; + std::vector field_630; + std::string field_648; + int32_t field_668; + int32_t field_66C; + PlayerData::Contest contest; + struc_715 field_AB0[25]; + int64_t field_D08; + int32_t field_D10; + int64_t field_D18; + prj::time field_D20; + std::vector field_D28; + std::vector field_D40; + std::vector field_D58; + std::vector field_D70; + prj::time field_D88; + bool field_D90; + int32_t clear_border; + int64_t field_D98; + int64_t field_DA0; + int64_t field_DA8; + int64_t field_DB0; + int64_t field_DB8; + int64_t field_DC0; + int64_t field_DC8; + int64_t field_DD0; + int64_t field_DD8; + int64_t field_DE0; + int8_t field_DE8; + int32_t field_DEC; + int8_t field_DF0; + int32_t field_DF4[3]; + int32_t field_E00[3]; + std::vector field_E10; + int64_t field_E28; + int32_t field_E30; + bool field_E34; + bool game_opts; + bool field_E36; + int64_t field_E38; + int64_t field_E40[16]; + int64_t field_EC0[16]; + int32_t field_F40; + + PlayerData(); + ~PlayerData(); + + void Reset(); +}; + +extern PlayerData* player_data_array_get(uint32_t index); diff --git a/src/ReDIVA/pv_game/pv_game.cpp b/src/ReDIVA/pv_game/pv_game.cpp new file mode 100644 index 00000000..bd61ae24 --- /dev/null +++ b/src/ReDIVA/pv_game/pv_game.cpp @@ -0,0 +1,5818 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#include "pv_game.hpp" +#include +#include "../../CRE/Glitter/glitter.hpp" +#include "../../CRE/rob/motion.hpp" +#include "../../CRE/rob/skin_param.hpp" +#include "../../CRE/hand_item.hpp" +#include "../../CRE/random.hpp" +#include "../../CRE/pv_expression.hpp" +#include "../../CRE/pv_param.hpp" +#include "../../CRE/task_effect.hpp" +#include "../../CRE/sound.hpp" +#include "../../KKdLib/prj/algorithm.hpp" +#include "../game_state.hpp" +#include "player_data.hpp" +#include "pv_game_camera.hpp" +#include "pv_game_music.hpp" +#include "target_pos.hpp" + +class DivaPvFrameRate : public FrameRateControl { +public: + DivaPvFrameRate(); + virtual ~DivaPvFrameRate() override; + + virtual float_t GetDeltaFrame() override; +}; + +struct pv_game_parent { + int8_t field_0; + int8_t field_1; + uint8_t pv_state; + bool playing; + int8_t field_4; + int8_t field_5; + int8_t field_6; + int8_t field_7; + int64_t curr_time; + float_t delta_time; + int32_t state; + void(*update_func)(pv_game_parent*); + int8_t field_20; + int8_t field_21; + int8_t field_22; + int8_t field_23; + int8_t field_24; + int8_t field_25; + int8_t field_26; + int8_t field_27; + bool field_28; + + pv_game_parent(); + + static void ctrl(pv_game_parent* pvgmp); +}; + +struct pv_game_time { + int64_t curr_time; + time_struct last_stop_time; + bool add_last_stop_time; + int64_t delta_time; + time_struct current_time; + bool add_current_time; + + pv_game_time(); +}; + +struct pv_game_se_data { + std::string se_name; + std::string slide_name; + std::string chainslide_first_name; + std::string chainslide_sub_name; + std::string chainslide_success_name; + std::string chainslide_failure_name; + std::string slidertouch_name; + + pv_game_se_data(); + ~pv_game_se_data(); +}; + +struct struc_674 { + size_t performer; + int32_t module; + rob_chara_pv_data_item item; + bool field_1C; + const pv_db_pv* pv; + + struc_674(); +}; + +struct struc_683 { + int32_t id; + int32_t sort_index; + chara_index chara_index; + int32_t cos; + rob_sleeve_data sleeve_l; + rob_sleeve_data sleeve_r; + int32_t spr_sel_md_id_spr_set_id; + int32_t spr_sel_md_id_cmn_spr_set_id; + int32_t spr_sel_md_id_cmn_md_img_id_spr_id; + int32_t spr_sel_md_id_cmn_md_img_spr_id; + bool field_78; + bool field_79; + std::string name; + int32_t field_A0; + time_t field_A8; + time_t field_B0; + + struc_683(); +}; + +struct struc_773 { + int32_t field_0; + bool field_4; + int32_t field_8; + bool field_C; + int32_t field_10; +}; + +const int32_t life_gauge_table_array[PV_DIFFICULTY_MAX][HIT_MAX] = { + { 3, 2, 1, -10, 0, -1, -3, -15, -20, 3, 2, 1, -10, 3, 2, 1, -10, 3, 2, 1, -10 }, + { 2, 1, 0, -10, 0, -1, -3, -15, -20, 2, 1, 0, -10, 2, 1, 0, -10, 2, 1, 0, -10 }, + { 2, 1, 0, -10, -3, -6, -9, -15, -20, 2, 1, 0, -10, 2, 1, 0, -10, 2, 1, 0, -10 }, + { 2, 1, 0, -15, -6, -8, -10, -20, -25, 2, 1, 0, -15, 2, 1, 0, -15, 2, 1, 0, -15 }, + { 1, 1, 0, -15, -6, -8, -10, -20, -30, 1, 1, 0, -15, 1, 1, 0, -15, 1, 1, 0, -15 }, +}; + +DivaPvFrameRate diva_pv_frame_rate; +SysFrameRate sys_frame_rate_array[3]; +pv_game* pv_game_ptr; +pv_disp2d pv_disp2d_data; +TaskPvGame* task_pv_game; + +struc_14 stru_140C94438; +struc_717 stru_141197E00; + +pv_game_parent pv_game_parent_data; +pv_game_time pv_game_time_data; +int32_t pv_game_parent_state; + +int32_t pv_game_state; + +extern render_context* rctx_ptr; + +static bool pv_game_parent_ctrl(); +static void pv_game_parent_disp(); + +static void pv_game_time_ctrl(); +static void pv_game_time_get(); + +static FrameRateControl* get_diva_pv_frame_rate(); +static SysFrameRate* sys_frame_rate_get(int32_t chara_id); + +static int32_t sub_1400FCFD0(pv_game_chara* arr, const pv_db_pv* pv); +static void sub_140105010(pv_game_chara* arr, size_t max_count, pv_game_item_mask* a3, struc_674& a4); + +pv_game_chara::pv_game_chara() : chara_index(), cos(), chara_id(), pv_data(), rob_chr() { + +} + +pv_game_chara::~pv_game_chara() { + +} + +bool pv_game_chara::check_chara() { + if (chara_id != -1) + return !!rob_chr; + return false; +} + +void pv_game_chara::reset() { + chara_index = CHARA_MAX; + cos = -1; + chara_id = -1; + pv_data.reset(); + rob_chr = 0; + motion_ids.clear(); + motion_face_ids.clear(); +} + +pv_game_edit_effect_data::pv_game_edit_effect_data() { + index = -1; + speed = 1.0f; + time = 0.0f; + end_frame = 0.0f; + delta_time = 1.0f; + loop = false; +} + +void pv_game_edit_effect_data::reset() { + index = -1; + speed = 1.0f; + time = 0.0f; + end_frame = 0.0f; + delta_time = 1.0f; + loop = false; +} + +pv_game_edit_effect::pv_game_edit_effect() { + +} + +pv_game_edit_effect::~pv_game_edit_effect() { + +} + +void pv_game_edit_effect::reset() { + spr_set_ids.clear(); + aet_set_ids.clear(); + aet_ids.clear(); + data.reset(); +} + +void pv_game_edit_effect::unload() { + data_struct* aft_data = &data_list[DATA_AFT]; + aet_database* aft_aet_db = &aft_data->data_ft.aet_db; + sprite_database* aft_spr_db = &aft_data->data_ft.spr_db; + + for (uint32_t& i : spr_set_ids) + sprite_manager_unload_set(i, aft_spr_db); + + for (uint32_t& i : aet_set_ids) + aet_manager_unload_set(i, aft_aet_db); + + reset(); +} + +pv_game_field::pv_game_field() : stage_index(), light_auth_3d_uid(), light_auth_3d_id(), +light_frame(), spr_set_back_id(), stage_flag(), npr_type(), cam_blur(), sdw_off() { + +} + +pv_game_field::~pv_game_field() { + +} + +struc_269::struc_269() : field_30(), field_34() { + +} + +struc_269::~struc_269() { + +} + +pv_game_chreff::pv_game_chreff() : src_chara_index(), +dst_chara_index(), src_auth_3d_uid(), dst_auth_3d_uid() { + +} + +pv_game_chreff::~pv_game_chreff() { + +} + +pv_effect_resource::pv_effect_resource() : emission() { + +} + +pv_effect_resource::~pv_effect_resource() { + +} + +pv_game_data::pv_game_data() : field_2CE98(), field_2CE9C(), field_2CF1C(), field_2CF20(), field_2CF24(), +field_2CF28(), field_2CF2C(), field_2CF30(), field_2CF34(), field_2CF38(), life_gauge(), score_final(), +challenge_time_total_bonus(), combo(), challenge_time_combo_count(), max_combo(), total_hit_count(), hit_count(), +current_reference_score(), target_count(), field_2CF84(), field_2CF88(), field_2CF8C(), score_slide_chain_bonus(), +slide_chain_length(), field_2CF98(), field_2CF9C(), field_2CFA0(), field_2CFA4(), pv(),field_2CFB0(), +chance_point(), reference_score(), reference_score_no_flag(), reference_score_no_flag_life_bonus(), +field_2CFE0(), field_2CFE4(), notes_passed(), field_2CFF0(), song_energy(), song_energy_base(), +song_energy_border(), life_gauge_safety_time(), life_gauge_border(), stage_index(), field_2D00C(), +no_fail(), changed_field(), challenge_time_start(), challenge_time_end(), max_time(), max_time_float(), +current_time_float(), current_time(), field_2D038(), field_2D03C(), score_hold_multi(), +score_hold(), score_slide(), has_slide(), has_success_se(), pv_disp2d(), life_gauge_final(), +hit_border(), field_2D05D(), field_2D05E(), start_fade(), title_image_init(), field_2D061(), +ex_stage(), field_2D063(), has_auth_3d_frame(), has_light_frame(), has_aet_frame(), has_aet_list(), +field_index(), edit_effect_index(), slidertouch_counter(), change_field_branch_success_counter(), +field_2D080(), field_2D084(), life_gauge_bonus(), life_gauge_total_bonus(), field_2D090(), no_clear(), +field_2D092(), field_2D093(), field_2D094(), field_2D095(), field_2D096(), success(), title_image_state(), +field_2D09C(), use_osage_play_data(), pv_end_fadeout(), rival_percentage(), field_2D0A8(), field_2D0AC(), +field_2D0B0(), field_2D0BC(), next_stage(), has_frame_texture(), field_2D0BF(), field_2D0C0(), field_2D0C4(), +field_2D7E8(), field_2D7EC(), field_2D808(), field_2D80C(), edit_effect(), camera_auth_3d_uid(), +se_index(), task_effect_init(), field_2D87C(), current_field(), field_2D8A0(), field_2D8A4(), +campv_index(), field_2D954(), field_2DAC8(), field_2DACC(), height_adjust(), field_2DB2C(), field_2DB34() { + field_2D00E = true; +} + +pv_game_data::~pv_game_data() { + +} + +void pv_game_data::calculate_target_start_pos(vec2& pos, float_t angle, float_t distance, vec2& start_pos) { + angle = ((angle >= 0.0f ? 180.0f : -180.0f) - angle) * DEG_TO_RAD_FLOAT; + start_pos.x = sinf(angle) * distance + pos.x; + start_pos.y = cosf(angle) * distance + pos.y; +} + +int64_t pv_game_data::get_max_time(int64_t* challenge_time_start, int64_t* challenge_time_end) { + if (!challenge_time_start || !challenge_time_end) + return 0; + + *challenge_time_start = -1; + *challenge_time_end = -1; + + int64_t dsc_time = 0; + int64_t max_time = 0; + while (pv_data.dsc_data_ptr != pv_data.dsc_data_ptr_end) { + int32_t func = pv_data.dsc_data_ptr->func; + uint32_t* data = pv_data.dsc.get_func_data(pv_data.dsc_data_ptr); + + if (func < 0 || func >= DSC_FT_MAX) + goto END; + + switch (func) { + case DSC_FT_END: + case DSC_FT_PV_END:{ + max_time = dsc_time; + } goto END; + case DSC_FT_TIME: { + dsc_time = 10000LL * (int32_t)data[0]; + } break; + case DSC_FT_MODE_SELECT: + case DSC_FT_EDIT_MODE_SELECT: { + bool v11 = true; + int32_t mode; + if (func == DSC_FT_MODE_SELECT && pv_data.has_perf_id && sub_14013C8C0()->sub_1400E7910() < 4) { + int32_t diff_bits = (int32_t)data[0]; + mode = (int32_t)data[1]; + v11 = !!(diff_bits & (1 << sub_14013C8C0()->difficulty)); + } + else + mode = (int32_t)data[0]; + + if (v11 && (sub_14013C8C0()->difficulty == PV_DIFFICULTY_EASY + || sub_14013C8C0()->difficulty == PV_DIFFICULTY_NORMAL)) + if (mode == 1) + *challenge_time_start = dsc_time; + else if (mode == 3) + *challenge_time_end = dsc_time; + } break; + } + + pv_data.dsc_data_ptr++; + } + +END: + pv_data.targets.clear(); + pv_data.targets.shrink_to_fit(); + pv_data.target_index = 0; + return max_time; +} + +void pv_game_data::reset() { + 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 (pv_play_data& i : pv_data.playdata) { + rob_chara* rob_chr = i.rob_chr; + if (rob_chr) { + rob_chr->reset_data(&rob_chr->pv_data, aft_bone_data, aft_mot_db); + rob_chr->set_hand_l_mottbl_motion(0, 194, 1.0, 0, 0.0, 0.0, 1.0, -1, 0.0, aft_mot_db); + rob_chr->set_hand_r_mottbl_motion(0, 194, 1.0, 0, 0.0, 0.0, 1.0, -1, 0.0, aft_mot_db); + rob_chr->set_visibility(true); + } + + i.motion_data.start_pos = 0.0f; + i.motion_data.end_pos = 0.0f; + i.motion_data.start_rot = 0.0f; + i.motion_data.end_rot = 0.0f; + + i.motion_data.rob_chr = 0; + i.motion_data.current_time = 0.0f; + i.motion_data.duration = 0.0f; + i.set_motion.clear(); + } + + pv_data.dsc_reset_position(); + + pv_data.curr_time = 0; + pv_data.curr_time_float = 0.0f; + pv_data.prev_time_float = 0.0f; + pv_data.field_2BF30 = -1; + pv_data.field_2BF38 = 0; + pv_data.music_play = false; + pv_data.pv_game->data.play_data.lyrics_color = { 0xFF, 0xFF, 0xFF, 0xFF }; + pv_data.play = true; + pv_data.field_2BF50 = 0; + pv_data.field_2BFD5 = 0; + sub_14013C8C0()->field_26 = 0; + pv_data.field_2BF58 = -1; + pv_data.field_2BFC4 = 2; + + pv_game_camera_reset(); + + pv_data.fov = 32.2673416137695f; + pv_data.min_dist = 0.05f; + pv_data.scene_fade.reset(); + pv_data.pv_game->data_itmpv_disable(); + pv_data.reset_camera_post_process(); + + pv_data.scene_rot_y = 0.0f; + pv_data.scene_rot_mat = mat4_identity; +} + +#pragma warning(push) +#pragma warning(disable: 6011) +#pragma warning(disable: 6385) +#pragma warning(disable: 28182) +bool pv_game_data::sub_140119960(bool* has_target, int64_t* dsc_time, int32_t* target_count, + int64_t* target_flying_time, float_t fade_time, bool* start_fade, dsc_target_ft* target_hist, + int32_t* target_flag, bool* has_chance, bool* has_slide, int32_t* slide_chain_type, + bool* slide_chain_start, int32_t* slide_chain_start_count, int32_t* slide_chain_cont_count, + int32_t* slide_chain_no_end_count, bool* has_slide_chain, int64_t target_flying_time_hist) { + if (!has_target || !dsc_time || !target_count || !target_flying_time || !start_fade || !target_hist + || !target_flag || !has_chance || !has_slide || !slide_chain_type) + return true; + + *has_target = false; + *target_flying_time = -1; + *has_chance = false; + *has_slide = false; + *slide_chain_type = 0; + + bool end = false; + int32_t fade_time_int = (int32_t)(fade_time * 1000000000.0f); + + uint32_t* target_data_offset[4] = {}; + + int32_t _target_count = 0; + while (pv_data.dsc_data_ptr != pv_data.dsc_data_ptr_end) { + int32_t func = pv_data.dsc_data_ptr->func; + uint32_t* data = pv_data.dsc.get_func_data(pv_data.dsc_data_ptr); + + if (func < 0 || func >= DSC_FT_MAX) + goto END; + + switch (func) { + case DSC_FT_END: + case DSC_FT_PV_END: + end = true; + pv_data.dsc_data_ptr++; + goto END; + case DSC_FT_TIME: { + if (_target_count > 0) { + pv_data.dsc_data_ptr++; + goto PROCESS_TARGET; + } + + *dsc_time = 10000LL * (int32_t)data[0]; + } break; + case DSC_FT_TARGET: { + *has_target = true; + target_data_offset[_target_count++] = data; + + int32_t target = (int32_t)data[0]; + + switch (target) { + case DSC_TARGET_FT_0B: + case DSC_TARGET_FT_SLIDE_L: + case DSC_TARGET_FT_SLIDE_R: + case DSC_TARGET_FT_GREEN_SQUARE: + case DSC_TARGET_FT_16: + case DSC_TARGET_FT_SLIDE_L_CHANCE: + case DSC_TARGET_FT_SLIDE_R_CHANCE: + *has_slide = 1; + break; + case DSC_TARGET_FT_0E: + *slide_chain_type = 1; + break; + case DSC_TARGET_FT_SLIDE_CHAIN_L: + *slide_chain_type = 2; + break; + case DSC_TARGET_FT_SLIDE_CHAIN_R: + *slide_chain_type = 3; + break; + } + + switch (target) { + case DSC_TARGET_FT_TRIANGLE_CHANCE: + case DSC_TARGET_FT_CIRCLE_CHANCE: + case DSC_TARGET_FT_CROSS_CHANCE: + case DSC_TARGET_FT_SQUARE_CHANCE: + case DSC_TARGET_FT_SLIDE_L_CHANCE: + case DSC_TARGET_FT_SLIDE_R_CHANCE: + *has_chance = true; + break; + } + + if (*dsc_time + *target_flying_time - 129999995 < fade_time_int) + *start_fade = false; + } break; + case DSC_FT_LYRIC: { + int32_t lyric_index = (int32_t)data[0]; + if (lyric_index > 0 && *dsc_time < fade_time_int) + *start_fade = false; + } break; + case DSC_FT_BAR_TIME_SET: { + int32_t bpm = (int32_t)data[0]; + int32_t time_signature = (int32_t)data[1] + 1; + bar_time_set_to_target_flying_time(bpm, time_signature, target_flying_time); + } break; + case DSC_FT_TARGET_FLYING_TIME: { + int32_t _target_flying_time = (int32_t)data[0]; + if (target_flying_time >= 0) + *target_flying_time = 1000000LL * _target_flying_time; + } break; + case DSC_FT_TARGET_FLAG: { + *target_flag = data[0]; + } break; + } + + pv_data.dsc_data_ptr++; + } + +END: + if (_target_count <= 0) { + *target_count = _target_count; + return end; + } + +PROCESS_TARGET: + int32_t random_mask = 0x0F; + int32_t random_count = 4; + int32_t max_random_count = 0; + for (int32_t i = 0; i < _target_count; i++) { + dsc_target_ft type = (dsc_target_ft)target_data_offset[i][0]; + if (type < DSC_TARGET_FT_RANDOM || type > DSC_TARGET_FT_RANDOM_HOLD) { + if (type >= DSC_TARGET_FT_TRIANGLE_HOLD && type <= DSC_TARGET_FT_SQUARE_HOLD) + type = (dsc_target_ft)(type - 4); + max_random_count--; + random_mask &= ~(1 << type); + } + else + random_count++; + } + + if (random_count > 0) { + int32_t v41 = 0; + int32_t v42 = max_random_count - 1; + for (int32_t i = 0; i < _target_count; i++) { + if (!target_data_offset[i]) + continue; + + dsc_ft_func v44 = (dsc_ft_func)target_data_offset[i][0]; + if ((unsigned int)(v44 - 8) > 1) + continue; + + int32_t v45 = rand_state_array_get_int(0, v42, 0); + int32_t v46 = 1; + int32_t v47 = 0; + int32_t v48 = 0; + for (; random_mask & (1 << v48) && v48 < 4; v46 <<= 1, v48++) { + if (v47 == v45) { + v42--; + random_mask &= ~v46; + } + + v47++; + } + + if (v48 == 4) + v48 = 0; + if (v44 != DSC_TARGET_FT_RANDOM) + v48 += 4; + + target_data_offset[i][0] = v48; + } + } + + for (int32_t i = 0; i < _target_count; i++) + if (target_data_offset[i][0] == DSC_TARGET_FT_PREVIOUS) + target_data_offset[i][0] = *target_hist != DSC_TARGET_FT_MAX ? *target_hist : DSC_TARGET_FT_CIRCLE; + + dsc_target_ft type = (dsc_target_ft)target_data_offset[_target_count - 1][0]; + if (type < DSC_TARGET_FT_RANDOM || type > DSC_TARGET_FT_PREVIOUS) + *target_hist = type; + else + *target_hist = DSC_TARGET_FT_CIRCLE; + + if (*target_flying_time >= 0) + target_flying_time_hist = *target_flying_time; + + pv_dsc_target_group next_target; + next_target.time_begin = *dsc_time; + next_target.time_end = *dsc_time + target_flying_time_hist; + + for (int32_t i = 0; i < _target_count; ) { + uint32_t* data = target_data_offset[i]; + + dsc_target_ft type = (dsc_target_ft)data[0]; + float_t pos_x = (float_t)(int32_t)data[1] * 0.001f; + float_t pos_y = (float_t)(int32_t)data[2] * 0.001f; + float_t angle = (float_t)(int32_t)data[3] * 0.001f; + float_t distance = (float_t)(int32_t)data[4] * 0.001f; + float_t amplitude = (float_t)(int32_t)data[5] * 0.001f; + int32_t frequency = (int32_t)data[6]; + + int32_t high_speed_rate = 1; + if (pv_data.pv_game->data.play_data.option == 1) { + distance *= (float_t)pv_data.pv_game->get_pv_high_speed_rate(); + high_speed_rate = pv_data.pv_game->get_pv_high_speed_rate(); + } + + next_target.targets[i].type = type; + next_target.targets[i].pos.x = pos_x; + next_target.targets[i].pos.y = pos_y; + calculate_target_start_pos(next_target.targets[i].pos, + angle, distance, next_target.targets[i].start_pos); + next_target.targets[i].amplitude = amplitude; + next_target.targets[i].frequency = high_speed_rate * frequency; + next_target.target_count = ++i; + } + + next_target.slide_chain = *slide_chain_type > 0; + + for (int32_t i = 0; i < next_target.target_count; i++) { + pv_dsc_target& target = next_target.targets[i]; + target.slide_chain_start = false; + target.slide_chain_end = false; + target.slide_chain_left = false; + target.slide_chain_right = false; + target.slide_chain = next_target.slide_chain; + } + + if (next_target.target_count > 0) { + bool has_other = false; + bool has_no_slide_chain = true; + for (int32_t i = 0; i < next_target.target_count; i++) { + dsc_target_ft type = next_target.targets[i].type; + if (type >= DSC_TARGET_FT_0E && type <= DSC_TARGET_FT_SLIDE_CHAIN_R) + has_no_slide_chain = false; + else + has_other = true; + } + + if (has_other && has_no_slide_chain) + *has_slide_chain = true; + } + + if ((*has_slide || *slide_chain_type > 0) && next_target.target_count > 1) { + int32_t left_index = 0; + int32_t right_index = 0; + float_t pos_left = next_target.targets[0].pos.x; + float_t pos_right = next_target.targets[0].pos.x; + + for (int32_t i = 1; i < next_target.target_count; i++) { + if (pos_left > next_target.targets[i].pos.x) { + left_index = i; + pos_left = next_target.targets[i].pos.x; + } + + if (pos_right < next_target.targets[i].pos.x) { + right_index = i; + pos_right = next_target.targets[i].pos.x; + } + } + + if (left_index != right_index) { + next_target.targets[left_index].slide_chain_left = true; + next_target.targets[right_index].slide_chain_right = true; + } + } + + size_t pv_target_count = pv_data.targets.size(); + + bool slide_chain_end = false; + if (*slide_chain_type > 0) { + pv_dsc_target_group prev_target_1; + pv_dsc_target_group prev_target_2; + + bool has_prev_target_1 = false; + bool prev_target_1_has_same_slide_chain = false; + + if (pv_target_count > 0) { + has_prev_target_1 = true; + prev_target_1 = pv_data.targets[pv_target_count - 1]; + for (int32_t i = 0; i < next_target.target_count; i++) { + dsc_target_ft type = next_target.targets[i].type; + if (type >= DSC_TARGET_FT_0E && type <= DSC_TARGET_FT_SLIDE_CHAIN_R) + if (type != prev_target_1.targets[i].type) { + prev_target_1_has_same_slide_chain = false; + break; + } + else + prev_target_1_has_same_slide_chain = true; + } + } + + bool has_prev_target_2 = false; + bool prev_target_2_has_same_slide_chain = false; + + if (pv_target_count > 1) { + has_prev_target_2 = true; + prev_target_2 = pv_data.targets[pv_target_count - 2]; + for (int32_t i = 0; i < next_target.target_count; i++) { + dsc_target_ft type = next_target.targets[i].type; + if (type >= DSC_TARGET_FT_0E && type <= DSC_TARGET_FT_SLIDE_CHAIN_R) + if (type != prev_target_2.targets[i].type) { + prev_target_2_has_same_slide_chain = false; + break; + } + else + prev_target_2_has_same_slide_chain = true; + } + } + + int32_t next_target_slide_chain_count = 0; + for (int32_t i = 0; i < next_target.target_count; i++) { + dsc_target_ft type = next_target.targets[i].type; + if (type >= DSC_TARGET_FT_0E && type <= DSC_TARGET_FT_SLIDE_CHAIN_R) + next_target_slide_chain_count++; + } + + bool prev_target_1_has_start = false; + int32_t prev_target_1_slide_chain_count = 0; + if (has_prev_target_1) + for (int32_t i = 0; i < prev_target_1.target_count; i++) { + dsc_target_ft type = prev_target_1.targets[i].type; + if (type >= DSC_TARGET_FT_0E && type <= DSC_TARGET_FT_SLIDE_CHAIN_R) { + if (prev_target_1.targets[i].slide_chain_start) + prev_target_1_has_start = true; + prev_target_1_slide_chain_count++; + } + } + + int32_t prev_target_2_slide_chain_count = 0; + if (has_prev_target_2) + for (int32_t i = 0; i < prev_target_2.target_count; i++) { + dsc_target_ft type = prev_target_2.targets[i].type; + if (type >= DSC_TARGET_FT_0E && type <= DSC_TARGET_FT_SLIDE_CHAIN_R) + prev_target_2_slide_chain_count++; + } + + float_t v139; + float_t v140; + if (has_prev_target_1 + && prev_target_1_has_same_slide_chain + && next_target_slide_chain_count == prev_target_1_slide_chain_count + && (!has_prev_target_2 + || !prev_target_2_has_same_slide_chain + || next_target_slide_chain_count != prev_target_2_slide_chain_count + || prev_target_1_has_start + || (v139 = (float_t)(int32_t)(next_target.time_begin - prev_target_1.time_begin) * 0.000001f, + v140 = (float_t)(int32_t)(prev_target_1.time_begin - prev_target_2.time_begin) * 0.000001f, + (v139 >= (v140 * 0.5f) && v139 <= (v140 * 1.5f))))) + slide_chain_end = false; + else { + slide_chain_end = true; + for (int32_t i = 0; i < next_target.target_count; i++) { + dsc_target_ft type = next_target.targets[i].type; + if (type >= DSC_TARGET_FT_0E && type <= DSC_TARGET_FT_SLIDE_CHAIN_R) + next_target.targets[i].slide_chain_start = true; + } + } + } + else + slide_chain_end = true; + + if (pv_target_count && slide_chain_end) { + pv_dsc_target_group prev_target = pv_data.targets[pv_target_count - 1]; + for (int32_t i = 0; i < prev_target.target_count; i++) { + dsc_target_ft type = prev_target.targets[i].type; + if (type >= DSC_TARGET_FT_0E && type <= DSC_TARGET_FT_SLIDE_CHAIN_R) { + if (!prev_target.targets[i].slide_chain_end) + (*slide_chain_no_end_count)++; + + pv_data.targets[pv_target_count - 1].targets[i].slide_chain_end = true; + } + } + } + + *slide_chain_start = false; + for (int32_t i = 0; i < next_target.target_count; i++) { + dsc_target_ft type = next_target.targets[i].type; + if (type >= DSC_TARGET_FT_0E && type <= DSC_TARGET_FT_SLIDE_CHAIN_R) + if (next_target.targets[i].slide_chain_start) { + *slide_chain_start = true; + (*slide_chain_start_count)++; + } + else + (*slide_chain_cont_count)++; + } + + pv_data.targets.push_back(next_target); + *target_count = _target_count; + return end; +} +#pragma warning(pop) + +pv_game_item_mask::pv_game_item_mask() { + arr[0] = true; + arr[1] = true; + arr[2] = true; + arr[3] = true; +} + +pv_game::pv_game() : loaded(), field_1(), field_2(), end_pv(), +field_4(), state(), field_C(), pv_id(), field_14(), modules(), items() { + reset(); + + state = 0; + field_C = -1; + pv_id = -1; + + for (int32_t& i : modules) + i = 0; + + data.play_data.field_5EC = 0; + data.play_data.option = 0; + + data.field_2CF98 = 0; + data.song_energy_base = 0.0f; + data.life_gauge_safety_time = 0; + data.life_gauge_border = 0; + data.stage_index = 0; + data.field_2D00C = true; + data.challenge_time_start = -1; + data.challenge_time_end = -1; + data.field_2D061 = false; + data.ex_stage = false; + data.field_2D063 = false; + data.field_2D0BC = false; + data.next_stage = false; + data.has_frame_texture = false; + data.field_2D0C0 = -1; + data.no_fail = true; + data.task_effect_init = false; + + data.effect_rs_list_hashes.reserve(0x40); + data.effect_rs_list.reserve(0x40); +} + +pv_game::~pv_game() { + +} + +void pv_game::calculate_life_gauge(hit_state hit_state, bool has_safety, + bool challenge_time, bool slide, bool slide_chain, bool slide_chain_start, bool a8) { + if (sub_14013C8C0()->sub_1400E7910() >= 6 || challenge_time) + return; + + int32_t score = 0; + if (!slide_chain || slide_chain_start || !a8) + score = life_gauge_table_array[sub_14013C8C0()->difficulty][hit_state]; + + if (!data.life_gauge && data.no_fail) + score = 0; + + data.life_gauge += score; + + data.life_gauge = clamp_def(data.life_gauge, 0, 255); + data.life_gauge_final = data.life_gauge; + + if (has_safety) { + int32_t border = calculate_life_gauge_border(); + if (data.life_gauge <= border) { + data.life_gauge = border; + data.hit_border = true; + } + } +} + +int32_t pv_game::calculate_life_gauge_border() { + return 255 * data.life_gauge_border / 100; +} + +int32_t pv_game::calculate_reference_score() { + data.challenge_time_start = -1; + data.challenge_time_end = -1; + + const int32_t life_gauge_cool = life_gauge_table_array[sub_14013C8C0()->difficulty][0]; + + data.max_time = data.get_max_time(&data.challenge_time_start, &data.challenge_time_end); + data.max_time_float = (float_t)(int32_t)data.max_time * 0.000000001f; + + data.pv_data.dsc_reset_position(); + data.target_reference_score.push_back(0); + + data.field_2CFE0 = 0; + data.field_2CFF0 = 0; + + bool has_slide = false; + bool has_success_se = false; + + int32_t reference_score = 0; + int32_t reference_score_no_flag = 0; + int32_t life_bonus = 0; + + int64_t dsc_time = 0; + bool start_fade = true; + dsc_target_ft target_hist = DSC_TARGET_FT_MAX; + bool has_chance = false; + int32_t slide_chain_start_count = 0; + int32_t slide_chain_cont_count = 0; + int32_t slide_chain_no_end_count = 0; + int64_t target_flying_time_hist = -1; + + int32_t target = 0; + int32_t life_gauge = 127; + int32_t target_index = 0; + int32_t target_index_no_flag = 0; + int32_t target_index_chance = 0; + int32_t target_index_chance_no_flag = 0; + bool end; + do + { + int32_t target_count = 0; + int32_t target_flag = 0; + int32_t slide_chain_type = 0; + bool has_target = false; + int64_t target_flying_time = -1; + bool _has_slide = false; + bool slide_chain_start = false; + bool has_slide_chain = false; + end = data.sub_140119960(&has_target, &dsc_time, &target_count, &target_flying_time, 3.0f, + &start_fade, &target_hist, &target_flag, &has_chance, &_has_slide, &slide_chain_type, + &slide_chain_start, &slide_chain_start_count, &slide_chain_cont_count, + &slide_chain_no_end_count, &has_slide_chain, target_flying_time_hist); + if (target_flying_time >= 0) + target_flying_time_hist = target_flying_time; + + if (has_target) { + target_count = max_def(target_count, 1); + bool slide_chain = slide_chain_type > 0 && !slide_chain_start && has_slide_chain; + + calculate_target_reference_score(&reference_score, + &target_index, target_count, slide_chain); + calculate_target_reference_score(&reference_score_no_flag, + &target_index_no_flag, target_count, slide_chain); + + target_flying_time_hist = max_def(target_flying_time_hist, 0); + + if (target_flying_time_hist + dsc_time >= data.challenge_time_start + && target_flying_time_hist + dsc_time <= data.challenge_time_end) { + if (!slide_chain) { + if (!(target_flag & 1)) + calculate_target_reference_combo_bonus( + &reference_score, &target_index_chance); + calculate_target_reference_combo_bonus( + &reference_score_no_flag, &target_index_chance_no_flag); + data.field_2CFF0++; + } + + if (data.pv_data.first_challenge_note < 0) + data.pv_data.first_challenge_note = target; + data.pv_data.last_challenge_note = target; + } + else { + if (life_gauge == 255) + life_bonus += 10; + else { + if (slide_chain_type <= 0 || slide_chain_start) + life_gauge += life_gauge_cool; + life_gauge = min_def(life_gauge, 255); + } + } + + data.target_reference_score.push_back(reference_score); + + if (slide_chain_type > 0 && !slide_chain_start) + data.field_2CFE0++; + target++; + } + + if (_has_slide || slide_chain_type > 0) + has_slide = true; + + if (has_chance) + has_success_se = true; + } while (!end); + + if (has_slide) + data.has_slide = true; + + if (has_success_se) + data.has_success_se = true; + + data.pv_data.dsc_reset_position(); + + data.start_fade = start_fade; + data.notes_passed = 0; + data.reference_score_no_flag = reference_score_no_flag; + data.reference_score_no_flag_life_bonus = reference_score_no_flag + life_bonus; + return reference_score; +} + +void pv_game::calculate_score(int32_t score, bool continue_combo, int64_t& time, + vec2& pos, int32_t multi_count, hit_state hit_state, bool challenge_time, + bool slide, bool slide_chain, bool slide_chain_start, bool slide_chain_end, bool slide_chain_continues) { + data.score_final += score; + + if (multi_count > 1) + data.score_hold_multi += score; + + if (slide || slide_chain) + data.score_slide += score; + + data.life_gauge_bonus = 0; + + if (!challenge_time) { + if (data.life_gauge == 255 && hit_state <= HIT_COOL_QUADRIPLE && (0x22201 & (1 << hit_state))) + data.life_gauge_bonus = 10; + + data.life_gauge_total_bonus += data.life_gauge_bonus; + data.score_final += data.life_gauge_bonus; + } + + bool _slide_chain = false; + if (slide_chain && !slide_chain_start && slide_chain_continues) + _slide_chain = true; + else if (continue_combo) { + data.combo = min_def(data.combo + 1, 9999); + data.max_combo = max_def(data.max_combo, data.combo); + data.score_final += 50 * min_def(data.combo / 10, 5); + } + else + data.combo = 0; + + calculate_target_reference_score(&data.current_reference_score, + &data.target_count, multi_count, _slide_chain); + + if (continue_combo && slide_chain && !slide_chain_start) { + data.slide_chain_length = min_def(data.slide_chain_length + 1, 50); + + int32_t slide_points = 10 * data.slide_chain_length; + if (slide_chain_end) + slide_points += 1000; + + data.score_final += slide_points; + data.score_slide_chain_bonus += slide_points; + data.score_slide += slide_points; + + if (slide_points > 0) + data.play_data.disp_slide_points(slide_points, pos.x, pos.y - -40.0f, slide_chain_end); + } + else + data.slide_chain_length = 0; + + if (challenge_time && (!slide_chain || slide_chain_start || !slide_chain_continues)) { + if (continue_combo) + data.challenge_time_combo_count = min_def(data.challenge_time_combo_count + 1, 50); + else + data.challenge_time_combo_count = 0; + + int32_t chance_point = 10 * data.challenge_time_combo_count; + data.score_final += chance_point; + data.challenge_time_total_bonus += chance_point; + + if (chance_point) { + data.play_data.disp_chance_points(chance_point, pos.x, pos.y); + data.field_2CFB0 = 30; + data.chance_point = chance_point; + } + + calculate_target_reference_combo_bonus(&data.current_reference_score, &data.field_2CF84); + data.field_2CF88++; + } +} + +void pv_game::calculate_song_energy() { + if (data.reference_score <= 0) { + data.song_energy = 0.0f; + return; + } + + static const float_t score_hold_mult[] = { + 400.0f, 200.0f, 50.0f, 20.0f, 0.0f + }; + + int32_t score = data.score_final - data.score_slide_chain_bonus - data.score_hold; + score = max_def(score, 0); + + float_t song_energy; + if (score == data.reference_score) + song_energy = 100.0f; + else + song_energy = ((float_t)score * 100.0f) / (float_t)data.reference_score; + + float_t song_energy_hold = ((float_t)data.score_hold + * score_hold_mult[sub_14013C8C0()->difficulty]) / (float_t)data.reference_score; + data.song_energy = song_energy + min_def(song_energy_hold, 5.0f); +} + +void pv_game::calculate_song_energy_border() { + if (data.reference_score <= 0 || data.notes_passed >= data.target_reference_score.size()) { + data.song_energy_border = 0.0f; + return; + } + + int32_t reference_score = data.target_reference_score[data.notes_passed]; + reference_score = min_def(reference_score, data.reference_score); + + if (reference_score != data.reference_score) { + float_t song_energy_border = (float_t)reference_score + * data.song_energy_base / (float_t)data.reference_score; + if (song_energy_border <= data.song_energy_base) + data.song_energy_border = song_energy_border; + else + data.song_energy_border = data.song_energy_base; + } + else + data.song_energy_border = data.song_energy_base; +} + +void pv_game::calculate_target_reference_score(int32_t* reference_score, + int32_t* target_index, int32_t multi_count, bool slide_chain) { + if (!reference_score || !target_index || multi_count <= 0) + return; + + int32_t score; + switch (multi_count) { + case 1: + default: + score = 500; + break; + case 2: + score = 1000; + break; + case 3: + score = 1500; + break; + case 4: + score = 2000; + break; + } + *reference_score += score; + + if (!slide_chain) { + int32_t tgt_idx = ++(*target_index) / 10; + *reference_score += 50 * min_def(tgt_idx, 5); + } +} + +void pv_game::calculate_target_reference_combo_bonus(int32_t* reference_score, int32_t* target_index) { + if (!reference_score || !target_index) + return; + + int32_t tgt_idx = ++(*target_index); + tgt_idx = min_def(tgt_idx, 5); + *target_index = tgt_idx; + *reference_score += 10 * tgt_idx; +} + +void pv_game::change_field(size_t field, ssize_t dsc_time, ssize_t curr_time) { + if (!field || field >= data.field_data.size()) + return; + + data_struct* aft_data = &data_list[DATA_AFT]; + aet_database* aft_aet_db = &aft_data->data_ft.aet_db; + + if (!data.task_effect_init && (dsc_time > -1 || curr_time > -1)) { + rand_state_array_4_set_seed_1393939(); + task_effect_parent_reset(); + data.task_effect_init = 1; + } + + pv_game_field& curr_field_data = data.field_data[data.current_field]; + pv_game_field& next_field_data = data.field_data[field]; + + task_stage_info stg_info = get_stage_info(next_field_data.stage_index); + stg_info.set_stage(); + if (stg_info.check()) + stg_info.set_stage_display(next_field_data.stage_flag, true); + else + task_stage_current_set_stage_display(false, true); + + light_param_data_storage_data_set_pv_cut((int32_t)field); + rctx_ptr->render_manager.set_npr_param(next_field_data.npr_type); + //rctx_ptr->post_process.set_cam_blur(next_field_data.cam_blur); + + if (next_field_data.sdw_off) + rctx_ptr->render_manager.set_shadow_false(); + else + rctx_ptr->render_manager.set_shadow_true(); + + bool disp_front = true; + bool disp_front_low = true; + + if (sub_14013C8C0()->sub_1400E7910() == 3) { + pv_disp2d* pv_disp2d = data.pv_disp2d; + if (pv_disp2d) { + if (pv_disp2d->title_start_2d_field >= 0 && pv_disp2d->title_end_2d_field >= 0 + && field >= pv_disp2d->title_start_2d_field) + disp_front = field > pv_disp2d->title_end_2d_field; + + if (pv_disp2d->title_start_2d_low_field >= 0 && pv_disp2d->title_end_2d_low_field >= 0 + && field >= pv_disp2d->title_start_2d_low_field) + disp_front_low = field > pv_disp2d->title_end_2d_low_field; + } + } + + bool not_init[4]; + for (int32_t i = 0; i < PV_AET_MAX; i++) { + not_init[i] = false; + + pv_aet aet = (pv_aet)i; + + bool disp_aet = true; + switch (aet) { + case PV_AET_FRONT: + disp_aet = disp_front; + break; + case PV_AET_FRONT_LOW: + disp_aet = disp_front_low; + break; + case PV_AET_FRONT_3D_SURF: + case PV_AET_BACK: + default: + disp_aet = true; + break; + } + + std::vector v109; + + int32_t index = 0; + for (const std::string& j : curr_field_data.aet_names[i]) { + if (data.has_aet_list[i]) { + float_t v26 = data.play_data.get_aet_frame(aet, index); + v109.push_back(max_def(v26, 0.0f)); + data.play_data.free_aet(aet, index); + } + else { + std::pair aet_name_id; + aet_name_id.second.assign(j); + if (index < curr_field_data.aet_ids[i].size()) + aet_name_id.first.assign(curr_field_data.aet_ids[i][index]); + + if (get_field_aet_index_by_name_id(next_field_data, aet, aet_name_id) < 0) + data.play_data.free_aet(aet, index); + } + + index++; + } + + index = 0; + for (const std::string& j : next_field_data.aet_names[i]) { + bool disp = disp_aet; + if (sub_14013C8C0()->sub_1400E7910() == 3) { + pv_disp2d* pv_disp2d = data.pv_disp2d; + if (pv_disp2d && !pv_disp2d->title_2d_layer.compare(j)) + disp = false; + } + + std::pair aet_name_id; + aet_name_id.second.assign(j); + if (index < next_field_data.aet_ids[i].size()) + aet_name_id.first.assign(next_field_data.aet_ids[i][index]); + + if (!aet_name_id.second.size()) { + index++; + continue; + } + + int32_t aet_index = get_field_aet_index_by_name_id(curr_field_data, aet, aet_name_id); + + if (aet_index >= 0) { + float_t end_time = -1.0f; + float_t start_time = -1.0f; + FrameRateControl* frame_rate_control = 0; + + if (data.has_aet_frame[i]) { + int32_t aet_frame = get_field_aet_frame_by_name_id(next_field_data, aet, aet_name_id); + start_time = get_aet_frame_max_frame(get_frame_continue(aet_frame), + aet, aet_name_id, dsc_time, curr_time, &end_time); + frame_rate_control = get_diva_pv_frame_rate(); + } + + if (!data.has_aet_frame[i] && !data.has_aet_list[i] + || (get_aet_frame_max_frame_by_name(start_time, end_time, aet_name_id), !data.has_aet_list[i])) { + if (data.has_aet_frame[i]) { + if (start_time >= 0.0f) + data.play_data.set_aet_frame(aet, index, start_time); + if (end_time < 0.0f) { + uint32_t aet_id = data.pv_disp2d->pv_aet_id; + if (aet_name_id.first.size()) + aet_id = aft_aet_db->get_aet_by_name(aet_name_id.first.c_str())->id; + end_time = aet_manager_get_scene_layer_end_time(aet_id, + aet_name_id.second.c_str(), aft_aet_db); + } + data.play_data.set_aet_end_time(aet, index, end_time); + } + } + else { + float_t v64 = 0.0f; + if (aet_index < v109.size()) + v64 = v109[aet_index]; + + if (start_time < 0.0f) + start_time = v64; + + if (end_time >= 0.0f && start_time >= end_time) + end_time = -1.0f; + + data.play_data.init_aet(aet, index, + std::string(aet_name_id.second), std::string(aet_name_id.first), + ¬_init[aet], start_time, end_time, frame_rate_control); + } + } + else { + float_t end_time = -1.0f; + float_t start_time = -1.0f; + FrameRateControl* frame_rate_control = 0; + + if (data.has_aet_frame[i]) { + int32_t aet_frame = get_field_aet_frame_by_name_id(next_field_data, aet, aet_name_id); + start_time = get_aet_frame_max_frame(get_frame(aet_frame, + dsc_time, curr_time), aet, aet_name_id, dsc_time, curr_time, &end_time); + + if (start_time < 0.0f) + start_time = 0.0f; + + if (end_time >= 0.0f && start_time >= end_time) + end_time = -1.0f; + + get_aet_frame_max_frame_by_name(start_time, end_time, aet_name_id); + frame_rate_control = get_diva_pv_frame_rate(); + } + + data.play_data.init_aet(aet, index, + std::string(aet_name_id.second), std::string(aet_name_id.first), + ¬_init[aet], start_time, end_time, frame_rate_control); + } + + data.play_data.set_aet_visible(aet, index, disp); + index++; + } + } + + data.play_data.set_spr_set_back_id(next_field_data.spr_set_back_id); + + std::vector auth_3d_end; + std::set_difference( + curr_field_data.auth_3d_ids.begin(), curr_field_data.auth_3d_ids.end(), + next_field_data.auth_3d_ids.begin(), next_field_data.auth_3d_ids.end(), std::back_inserter(auth_3d_end)); + std::vector auth_3d_start; + std::set_difference( + next_field_data.auth_3d_ids.begin(), next_field_data.auth_3d_ids.end(), + curr_field_data.auth_3d_ids.begin(), curr_field_data.auth_3d_ids.end(), std::back_inserter(auth_3d_start)); + std::vector auth_3d_cont; + std::set_intersection( + curr_field_data.auth_3d_ids.begin(), curr_field_data.auth_3d_ids.end(), + next_field_data.auth_3d_ids.begin(), next_field_data.auth_3d_ids.end(), std::back_inserter(auth_3d_cont)); + + for (auth_3d_id& i : auth_3d_end) { + i.set_visibility(false); + i.set_enable(false); + } + + bool disp = true; + if (sub_14013C8C0()->sub_1400E7910() == 3) { + pv_disp2d* pv_disp2d = data.pv_disp2d; + if (pv_disp2d && pv_disp2d->title_start_3d_field >= 0 && pv_disp2d->title_end_3d_field >= 0 + && field >= pv_disp2d->title_start_3d_field) + disp = field > pv_disp2d->title_end_3d_field; + } + + for (auth_3d_id& i : auth_3d_start) { + float_t req_frame = 0.0f; + float_t max_frame = -1.0f; + + if (data.has_auth_3d_frame) { + int32_t auth_3d_frame = get_field_auth_3d_frame(next_field_data, i.get_uid(), 0); + req_frame = pv_game::get_auth_3d_frame_max_frame(get_frame(auth_3d_frame, + dsc_time, curr_time), i.get_uid(), dsc_time, curr_time, 0, &max_frame); + req_frame = max_def(req_frame, 0.0f); + } + + i.set_enable(true); + i.set_req_frame(req_frame); + i.set_max_frame(max_frame); + i.set_paused(false); + i.set_visibility(disp); + } + + for (auth_3d_id& i : auth_3d_cont) { + float_t max_frame = -1.0f; + + if (data.has_auth_3d_frame) { + int32_t auth_3d_frame = get_field_auth_3d_frame(next_field_data, i.get_uid(), 0); + float_t req_frame = get_auth_3d_frame_max_frame(get_frame_continue(auth_3d_frame), + i.get_uid(), dsc_time, curr_time, 0, &max_frame); + if (req_frame >= 0.0f) + i.set_req_frame(req_frame); + } + + i.set_max_frame(max_frame); + } + + if (next_field_data.light_auth_3d_id == curr_field_data.light_auth_3d_id) { + auth_3d_id& light_auth = next_field_data.light_auth_3d_id; + if (light_auth.check_not_empty()) { + float_t max_frame = -1.0f; + + if (data.has_light_frame) { + int32_t light_frame = get_field_auth_3d_frame(next_field_data, light_auth.get_uid(), 1); + float_t req_frame = get_auth_3d_frame_max_frame(get_frame_continue(light_frame), + light_auth.get_uid(), dsc_time, curr_time, 1, &max_frame); + if (req_frame >= 0.0f) + light_auth.set_req_frame(req_frame); + } + + light_auth.set_max_frame(max_frame); + } + } + else { + auth_3d_id& prev_light_auth = curr_field_data.light_auth_3d_id; + if (prev_light_auth.check_not_empty()) { + prev_light_auth.set_visibility(false); + prev_light_auth.set_enable(false); + } + + auth_3d_id& next_light_auth = next_field_data.light_auth_3d_id; + if (next_light_auth.check_not_empty()) { + float_t req_frame = 0.0f; + float_t max_frame = -1.0f; + + if (data.has_light_frame) { + int32_t light_frame = get_field_auth_3d_frame(next_field_data, next_light_auth.get_uid(), 1); + req_frame = get_auth_3d_frame_max_frame(get_frame(light_frame, + dsc_time, curr_time), next_light_auth.get_uid(), dsc_time, curr_time, 1, &max_frame); + req_frame = max_def(req_frame, 0.0f); + } + + next_light_auth.set_enable(true); + next_light_auth.set_req_frame(req_frame); + next_light_auth.set_max_frame(req_frame); + next_light_auth.set_paused(false); + next_light_auth.set_visibility(true); + } + } + + for (uint64_t& i : curr_field_data.stop_eff_list) + Glitter::glt_particle_manager->FreeSceneEffect(0, i); + + for (uint64_t& i : next_field_data.play_eff_list) + Glitter::glt_particle_manager->LoadScene(hash_fnv1a64m_empty, i); + + data.current_field = field; + data.changed_field = true; +} + +void pv_game::check_auth_replace_by_module(const char* name, int32_t& uid) { + data_struct* aft_data = &data_list[DATA_AFT]; + auth_3d_database* aft_auth_3d_db = &aft_data->data_ft.auth_3d_db; + + int32_t perf_count = (int32_t)data.pv->get_performer_count(); + for (int32_t i = 0; i < perf_count; i++) + for (const pv_db_pv_auth_replace_by_module& j : data.pv->auth_replace_by_module) + if (j.id == i && j.module_id == modules[i] && !j.org_name.compare(name)) { + uid = aft_auth_3d_db->get_uid(j.name.c_str()); + return; + } +} + +int32_t pv_game::check_chrcam(const char* name, int32_t& uid) { + data_struct* aft_data = &data_list[DATA_AFT]; + auth_3d_database* aft_auth_3d_db = &aft_data->data_ft.auth_3d_db; + + std::string _name; + _name.assign(name); + + std::string campv_base; + campv_base.assign(data.campv_string); + campv_base.append("_BASE"); + + std::string campv_parts; + campv_parts.assign(data.campv_string); + campv_parts.append("_PARTS"); + + int32_t cam_index = 0; + if (!campv_base.compare(_name)) + cam_index = 1; + else if (!_name.find(campv_parts)) + cam_index = atoi(_name.c_str() + campv_parts.size()); + + for (const pv_db_pv_chrcam& i : data.pv->chrcam) + if (!i.org_name.compare(_name) + && !i.chara.compare(chara_index_get_auth_3d_name(data.chara[i.id].chara_index))) { + uid = aft_auth_3d_db->get_uid(i.name.c_str()); + return 1; + } + + return cam_index; +} + +bool pv_game::check_life_gauge_safety() { + return get_life_gauge_safety_time() > 0.0f; +} + +int32_t pv_game::ctrl(float_t delta_time, int64_t curr_time) { + data.hit_border = false; + data.life_gauge_bonus = 0; + if (!loaded) + return 0; + + data.play_data.fade_begin_ctrl(); + + if (pv_osage_manager_array_get_disp()) { + pv_osage_manager_array_set_not_reset_true(); + return 0; + } + + data.changed_field = 0; + if (data.play_data.field_64C) { + if (!data.field_2D093) + data.pv_data.ctrl(delta_time, curr_time, false); + /*else + for (int32_t i = 0; i < 2; i++) + if (app::TaskWork::CheckTaskReady(task_movie_get(i))) + task_movie_get(i)->sub_14041F4E0();*/ + + if (!sub_14013C8C0()->sub_1400E7920()) { + hit_state hit_state = HIT_MAX; + bool v94 = false; + vec2 pos; + pv_game_se_data se_data; + se_data.se_name.assign(data.play_data.se_name); + se_data.slide_name.assign(data.play_data.slide_name); + se_data.chainslide_first_name.assign(data.play_data.chainslide_first_name); + se_data.chainslide_sub_name.assign(data.play_data.chainslide_sub_name); + se_data.chainslide_success_name.assign(data.play_data.chainslide_success_name); + se_data.chainslide_failure_name.assign(data.play_data.chainslide_failure_name); + se_data.slidertouch_name.assign(data.play_data.slidertouch_name); + int32_t a7 = 0; + int32_t multi_count = 0; + bool slide = false; + bool slide_chain = false; + bool slide_chain_start = false; + bool slide_chain_end = false; + bool slide_chain_continue = false; + bool success = false; + float_t time_offset = 0.0f; + int32_t target = -1; + /*sub_14013C8F0()->sub_14012C300(delta_time, hit_state, v94, pos, se_data, a7, multi_count, 1, + slide, slide_chain, slide_chain_start, slide_chain_end, slide_chain_continue, + data.song_energy_base <= data.song_energy, success, 0, 0, data.changed_field, time_offset, target);*/ + } + + if (!data.field_2D096) { + sub_1400FC500(); + data.field_2D096 = true; + } + + data.play_data.fade_end_ctrl(); + data.play_data.sub_140138D60(); + data.play_data.sub_140138F30(); + data.play_data.set_aet_song_energy(); + data.play_data.score_update(data.score_final, true); + + return sub_1400FC780(delta_time); + } + + if (end_pv) { + end_pv = false; + return 1; + } + + hit_state hit_state = HIT_MAX; + bool v94 = true; + vec2 pos; + int32_t a7 = 0; + int32_t multi_count = 0; + bool slide = false; + bool slide_chain = false; + bool slide_chain_start = false; + bool slide_chain_end = false; + bool slide_chain_continue = false; + bool success = false; + float_t time_offset = 0.0f; + int32_t target = -1; + + data.current_time = data.pv_data.ctrl(delta_time, curr_time, true); + data.current_time_float = (float_t)(int32_t)data.current_time * 0.000000001f; + data.field_2D038 = data.current_time_float + data.field_2D03C; + + if (!sub_14013C8C0()->sub_1400E7920()) { + /*TaskLampCtrl* task_lamp_ctrl = task_lamp_ctrl_get(); + task_lamp_ctrl->field_74 = 2; + task_lamp_ctrl->field_78 = { 0xFF, 0xFF, 0xFF, 0xFF }; + task_lamp_ctrl->field_7C = 0; + task_slider_control_get()->sub_140618980(3);*/ + + pv_game_se_data se_data; + se_data.se_name.assign(data.play_data.se_name); + se_data.slide_name.assign(data.play_data.slide_name); + se_data.chainslide_first_name.assign(data.play_data.chainslide_first_name); + se_data.chainslide_sub_name.assign(data.play_data.chainslide_sub_name); + se_data.chainslide_success_name.assign(data.play_data.chainslide_success_name); + se_data.chainslide_failure_name.assign(data.play_data.chainslide_failure_name); + se_data.slidertouch_name.assign(data.play_data.slidertouch_name); + + /*sub_14013C8F0()->sub_14012C300(delta_time, hit_state, v94, pos, se_data, a7, multi_count, 0, + slide, slide_chain, slide_chain_start, slide_chain_end, slide_chain_continue, + data.song_energy_border <= data.song_energy, success, data.pv_data.sub_1400FDA40(), + data.pv_data.target_index, data.changed_field, time_offset, target); */ + data.score_final += a7; + data.score_hold += a7; + data.score_hold_multi += a7; + } + /*else if (sub_14013C8C0()->sub_1400E7910() != 3) + task_slider_control_get()->sub_140618980(1);*/ + + bool challenge_time = hit_state != HIT_MAX + && data.pv_data.first_challenge_note >= 0 && data.pv_data.last_challenge_note >= 0 + && target >= data.pv_data.first_challenge_note && target <= data.pv_data.last_challenge_note; + + if (data.field_2CFB0 > 0) + data.field_2CFB0--; + + if (!data.field_2D0BC && slide_chain_end) + data.field_2D0BC = true; + + if (sub_14013C8C0()->sub_1400E7920()) { + if (sub_14013C8C0()->sub_1400E7910() == 3) { + data.field_2CF8C -= delta_time; + if (data.field_2CF8C <= 0.0f) + end(true, true); + } + else if (sub_14010EF00()) { + data.field_2D0A8 = sub_14010F930(); + end(true, true); + } + } + else { + /*if (v94) + sub_140105690();*/ + + struc_773 v103[HIT_MAX]; + v103[HIT_COOL ] = { 500, true, 0, true, 0 }; + v103[HIT_FINE ] = { 300, true, 1, true, 2 }; + v103[HIT_SAFE ] = { 100, false, 2, true, 4 }; + v103[HIT_BAD ] = { 50, false, 3, true, 6 }; + v103[HIT_WRONG_COOL ] = { 250, false, 0, false, 1 }; + v103[HIT_WRONG_FINE ] = { 150, false, 1, false, 3 }; + v103[HIT_WRONG_SAFE ] = { 50, false, 2, false, 5 }; + v103[HIT_WRONG_BAD ] = { 30, false, 3, false, 7 }; + v103[HIT_WORST ] = { 0, false, 4, true, 8 }; + v103[HIT_COOL_DOUBLE ] = { 1000, true, 0, true, 0 }; + v103[HIT_FINE_DOUBLE ] = { 600, true, 1, true, 2 }; + v103[HIT_SAFE_DOUBLE ] = { 200, false, 2, true, 4 }; + v103[HIT_BAD_DOUBLE ] = { 100, false, 3, true, 6 }; + v103[HIT_COOL_TRIPLE ] = { 1500, true, 0, true, 0 }; + v103[HIT_FINE_TRIPLE ] = { 900, true, 1, true, 2 }; + v103[HIT_SAFE_TRIPLE ] = { 300, false, 2, true, 4 }; + v103[HIT_BAD_TRIPLE ] = { 150, false, 3, true, 6 }; + v103[HIT_COOL_QUADRIPLE] = { 2000, true, 0, true, 0 }; + v103[HIT_FINE_QUADRIPLE] = { 1200, true, 1, true, 2 }; + v103[HIT_SAFE_QUADRIPLE] = { 400, false, 2, true, 4 }; + v103[HIT_BAD_QUADRIPLE ] = { 200, false, 3, true, 6 }; + + if (hit_state != HIT_MAX) { + int64_t time = 0; + calculate_score(v103[hit_state].field_0, v103[hit_state].field_4, time, pos, multi_count, + hit_state, challenge_time, slide, slide_chain, slide_chain_start, slide_chain_end, slide_chain_continue); + calculate_life_gauge(hit_state, check_life_gauge_safety(), challenge_time, + slide, slide_chain, slide_chain_start, slide_chain_continue); + if (!slide_chain || slide_chain_start || !slide_chain_continue) { + data.total_hit_count[v103[hit_state].field_8]++; + if (v103[hit_state].field_C) + data.hit_count[v103[hit_state].field_8]++; + data.play_data.set_value_text(v103[hit_state].field_10, time_offset); + } + } + + if (hit_state == HIT_WORST) { + if (/*!sub_14012F9A0(&sub_14013C8F0()->field_0.field_12B9C) + && */!slide_chain || slide_chain_start || !slide_chain_continue) { + pv_game_music_get()->set_channel_pair_volume_map(1, 0); + data.field_2D090 = true; + } + + if (data.notes_passed < data.target_reference_score.size() - 1) + data.notes_passed++; + } + else if (hit_state != HIT_MAX) { + pv_game_music_get()->set_channel_pair_volume_map(1, 100); + data.field_2D090 = false; + + if (data.notes_passed < data.target_reference_score.size() - 1) + data.notes_passed++; + } + + if (success && !data.success) { + data.success = true; + data.play_data.init_aet_success_info(); + if (/*sub_14013C8F0()->field_0.field_12A8D && */data.play_data.pvbranch_success_se_name.size()) + sound_work_play_se(2, data.play_data.pvbranch_success_se_name.c_str(), 1.0f); + } + + bool end = false; + if (sub_14010EF00()) { + data.field_2D0A8 = sub_14010F930(); + if (data.field_2D0A8 == 2) + end = true; + else { + data.life_gauge = 0; + data.life_gauge_final = 0; + data.no_clear = true; + } + } + + int32_t combo = data.combo; + if (combo < 2 || slide_chain && !slide_chain_start && slide_chain_continue) + combo = 0; + + if (hit_state != HIT_MAX) + data.field_2DB2C = pos; + + data.play_data.sub_140137DD0(data.life_gauge / 16, delta_time, data.field_2DB2C, combo); + + if (end) + pv_game::end(true, true); + + else if (data.life_gauge <= 0) + if (data.no_clear || !data.no_fail) + pv_game::end(false, false); + else + data.play_data.set_not_clear(); + + calculate_song_energy(); + calculate_song_energy_border(); + } + + sub_1400FCAD0(delta_time); + + title_image_ctrl(false); + data.play_data.set_aet_song_energy(); + + if (sub_14013C8C0()->sub_1400E7910() == 3 && data.field_2CF8C <= 5.0f && !data.field_2D05D) { + data.play_data.init_aet_demo_font(); + data.field_2D05D = true; + } + + data.field_2D084 = data.field_2D080; + data.field_2D080++; + return 0; +} + +void pv_game::data_itmpv_disable() { + for (auto& i : data.itmpv) + for (auto& j : i) + j.second.first.set_enable(false); +} + +void pv_game::disp() { + //sub_1400FC6F0(); + //sub_14013C8F0()->sub_14012A4E0(); +} + +void pv_game::edit_effect_ctrl(float_t delta_time) { + if (data.edit_effect.data.index < 0) + return; + + if (!data.play_data.field_64C) + data.edit_effect.data.delta_time = delta_time * data.edit_effect.data.speed; + data.edit_effect.data.time += data.edit_effect.data.delta_time; + + float_t end_frame = data.edit_effect.data.end_frame; + float_t frame = 0.0f; + if (end_frame > 0.0f) { + frame = get_target_anim_fps() * data.edit_effect.data.time; + if (data.edit_effect.data.loop) + frame = fmodf(frame, end_frame + 1.0f); + else if (frame > end_frame) + frame = end_frame; + } + + data.play_data.set_aet_edit_effect_frame(frame); +} + +void pv_game::edit_effect_set(int32_t index, float_t speed, float_t delta_time) { + int32_t aet_id = -1; + bool loop = false; + bool low_field = false; + if (index >= 0 && index < data.edit_effect.aet_ids.size()) { + const pv_db_pv_difficulty* diff = data.pv->get_difficulty( + sub_14013C8C0()->difficulty, sub_14013C8C0()->edition); + if (diff) { + int32_t edit_effect_index = diff->edit_effect[index].index; + if (edit_effect_index >= 0 && edit_effect_index <= 83) { + static const bool edit_effect_loop[] = { + true, true, true, true, true, true, true, true, + true, true, true, true, true, true, true, true, + true, true, false, false, false, false, false, false, + false, false, true, true, true, true, true, true, + true, true, true, true, true, true, true, true, + true, true, true, true, true, true, true, true, + true, true, true, true, true, true, true, false, + true, true, true, true, true, false, true, true, + true, true, true, true, true, true, true, false, + false, false, false, false, false, false, false, false, + false, false, false, false, + }; + + low_field = diff->edit_effect[index].low_field; + aet_id = data.edit_effect.aet_ids[index]; + loop = edit_effect_loop[edit_effect_index]; + } + } + } + + if (index != data.edit_effect.data.index || !loop) { + data.edit_effect.data.time = 0.0f; + data.edit_effect.data.end_frame = data.play_data.init_aet_edit_effect(aet_id, "eff", loop, low_field); + } + + data.edit_effect.data.speed = speed; + data.edit_effect.data.index = index; + data.edit_effect.data.loop = loop; + data.edit_effect.data.delta_time = speed * delta_time; +} + +void pv_game::end(bool a2, bool set_fade) { + data.play_data.field_64C = true; + data.field_2D095 = a2; + + if (set_fade) + pv_game_music_get()->set_fade_out(0.75f, true); + else + pv_game_music_get()->stop(); + + data.play_data.disable_update(); + + if (sub_14013C8C0()->sub_1400E7920() || sub_14013C8C0()->sub_1400E7910() == 6) + data.play_data.field_650 = 41; + else { + data.play_data.field_654 = 0.0f; + data.play_data.field_658 = 0; + data.play_data.field_65C = 0.0f; + data.play_data.field_650 = a2 ? 0 : 27; + + sub_14010F030(); + } +} + +float_t pv_game::get_aet_frame_max_frame(int32_t aet_frame, int32_t aet_index, std::pair& aet_name_id, int64_t dsc_time, int64_t curr_time, float_t* max_frame) { + if (!max_frame) + return -1.0f; + + *max_frame = -1.0f; + if (dsc_time < 0 || curr_time < 0) + return 0.0f; + + if (!((aet_frame + 4) & -5)) { + data.aet_time[aet_index].insert_or_assign(aet_name_id, dsc_time); + + if (!aet_frame) { + *max_frame = get_aet_frame_max_frame_change_field(aet_index, aet_name_id, dsc_time); + if (*max_frame < 0.0f) + *max_frame = get_next_aet_max_frame_change_field(aet_index, aet_name_id, dsc_time, curr_time); + } + return 0.0f; + } + else if (!((aet_frame + 5) & -5)) { + float_t frame = -1.0f; + int64_t aet_time = get_aet_time(aet_index, aet_name_id); + if (aet_time >= 0) { + frame = dsc_time_to_frame(curr_time - aet_time); + float_t dsc_frame = roundf(dsc_time_to_frame(dsc_time - aet_time)); + frame = max_def(frame, dsc_frame); + } + + if (aet_frame == -1) { + *max_frame = get_aet_frame_max_frame_change_field(aet_index, aet_name_id, dsc_time); + if (*max_frame < 0.0f) + *max_frame = get_next_aet_max_frame_change_field(aet_index, aet_name_id, dsc_time, curr_time); + } + return frame; + } + else if (!((aet_frame + 6) & -5) && aet_frame == -2) + *max_frame = get_aet_frame_max_frame_change_field(aet_index, aet_name_id, dsc_time); + return -1.0f; +} + +void pv_game::get_aet_frame_max_frame_by_name(float_t& frame, float_t& max_frame, std::pair& aet_name_id) { + if (frame < 0.0f && max_frame < 0.0f || !data.pv_disp2d) + return; + + data_struct* aft_data = &data_list[DATA_AFT]; + aet_database* aft_aet_db = &aft_data->data_ft.aet_db; + + uint32_t aet_id = data.pv_disp2d->pv_aet_id; + if (aet_name_id.first.size()) + aet_id = data_list[DATA_AFT].data_ft.aet_db.get_aet_by_name(aet_name_id.first.c_str())->id; + + float_t start_frame = aet_manager_get_scene_layer_start_time(aet_id, aet_name_id.second.c_str(), aft_aet_db); + float_t end_frame = aet_manager_get_scene_layer_end_time(aet_id, aet_name_id.second.c_str(), aft_aet_db); + + if (frame >= 0.0f) { + frame += start_frame; + if (end_frame >= 0.0f && frame > end_frame) + frame = end_frame; + } + + if (max_frame >= 0.0f) { + max_frame += start_frame; + if (end_frame >= 0.0f && max_frame > end_frame) + max_frame = end_frame; + } +} + +float_t pv_game::get_aet_frame_max_frame_change_field(int32_t aet_index, + std::pair& aet_name_id, int64_t time) { + if (time < 0) + return -1.0f; + + prj::vector_pair& change_field = data.pv_data.branch_mode != 2 + ? data.pv_data.change_field_branch_fail + : data.pv_data.change_field_branch_success; + if (time == 10000LL * change_field.back().first) + return roundf(dsc_time_to_frame(data.max_time - get_aet_time(aet_index, aet_name_id))) - 1.0f; + return -1.0f; +} + +int64_t pv_game::get_aet_time(int32_t aet_index, std::pair& aet_name_id) { + auto elem = data.aet_time[aet_index].find(aet_name_id); + if (elem != data.aet_time[aet_index].end()) + return elem->second; + return -1; +} + +float_t pv_game::get_auth_3d_frame_max_frame(int32_t auth_3d_frame, int32_t auth_3d_uid, + int64_t dsc_time, int64_t curr_time, uint8_t type, float_t* max_frame) { + if (!max_frame || type != 0 && type != 1) + return -1.0f; + + *max_frame = -1.0f; + if (dsc_time < 0 || curr_time < 0) + return 0.0f; + + if (!((auth_3d_frame + 4) & ~4u)) { + if (type) + data.light_time.insert_or_assign(auth_3d_uid, dsc_time); + else + data.auth_3d_time.insert_or_assign(auth_3d_uid, dsc_time); + + if (!auth_3d_frame) { + *max_frame = get_auth_3d_frame_max_frame_change_field(auth_3d_uid, dsc_time, type); + if (*max_frame < 0.0f) + *max_frame = get_next_auth_3d_max_frame_change_field(auth_3d_uid, dsc_time, curr_time, type); + } + return 0.0f; + } + else if (!((auth_3d_frame + 5) & ~4u)) { + float_t frame = -1.0f; + int64_t auth_3d_time = get_auth_3d_time(auth_3d_uid, type); + if (auth_3d_time >= 0) { + frame = dsc_time_to_frame(curr_time - auth_3d_time); + float_t dsc_frame = roundf(dsc_time_to_frame(dsc_time - auth_3d_time)); + frame = max_def(frame, dsc_frame); + } + + if (auth_3d_frame == -1) { + *max_frame = get_auth_3d_frame_max_frame_change_field(auth_3d_uid, dsc_time, type); + if (*max_frame < 0.0f) + *max_frame = get_next_auth_3d_max_frame_change_field(auth_3d_uid, dsc_time, curr_time, type); + } + return frame; + } + else if (!((auth_3d_frame + 6) & ~4u) && auth_3d_frame == -2) + *max_frame = get_auth_3d_frame_max_frame_change_field(auth_3d_uid, dsc_time, type); + return -1.0f; +} + +float_t pv_game::get_auth_3d_frame_max_frame_change_field(uint32_t auth_3d_uid, int64_t time, uint8_t type) { + if (time < 0) + return -1.0f; + + prj::vector_pair& change_field = data.pv_data.branch_mode != 2 + ? data.pv_data.change_field_branch_fail + : data.pv_data.change_field_branch_success; + if (time == 10000LL * change_field.back().first) + return roundf(dsc_time_to_frame(data.max_time - get_auth_3d_time(auth_3d_uid, type))) - 1.0f; + return -1.0f; +} + +auth_3d_id pv_game::get_auth_3d_id(int32_t uid) { + auto elem = data.auth_3d.find(uid); + if (elem != data.auth_3d.end()) + return elem->second; + return {}; +} + +int64_t pv_game::get_auth_3d_time(int32_t uid, uint8_t type) { + switch (type) { + case 0: { + auto elem = data.auth_3d_time.find(uid); + if (elem != data.auth_3d_time.end()) + return elem->second; + } break; + case 1: { + auto elem = data.light_time.find(uid); + if (elem != data.light_time.end()) + return elem->second; + } break; + } + return -1; +} + +uint32_t pv_game::get_chreff_auth_3d_object_set(int32_t& uid) { + data_struct* aft_data = &data_list[DATA_AFT]; + auth_3d_database* aft_auth_3d_db = &aft_data->data_ft.auth_3d_db; + object_database* aft_obj_db = &aft_data->data_ft.obj_db; + + int32_t obj_set = -1; + for (pv_game_chreff& i : data.chreff_auth_3d) { + if (i.src_auth_3d_uid == uid) { + obj_set = aft_obj_db->get_object_set_id(i.dst_auth_3d_category.c_str()); + if (obj_set != -1) { + uid = i.dst_auth_3d_uid; + break; + } + + obj_set = aft_obj_db->get_object_set_id(i.src_auth_3d_category.c_str()); + if (obj_set != -1) + return obj_set; + } + } + + if (obj_set == -1 && uid >= 0 && uid < aft_auth_3d_db->uid.size()) { + std::string& category = aft_auth_3d_db->uid[uid].category; + if (!category.find("EFFCHRPV")) + return aft_obj_db->get_object_set_id(category.c_str()); + } + return obj_set; +} + +int64_t pv_game::get_data_itmpv_time(int32_t chara_id, int32_t index) { + auto elem = data.itmpv[chara_id].find(index); + if (elem != data.itmpv[chara_id].end()) + return elem->second.second; + return -1; +} + +float_t pv_game::get_data_rival_percentage() { + return data.rival_percentage; +} + +std::string pv_game::get_effect_se_file_name() { + const pv_db_pv_difficulty* diff = data.pv->get_difficulty( + sub_14013C8C0()->difficulty, sub_14013C8C0()->edition); + if (diff) + return diff->effect_se_file_name; + return {}; +} + +int32_t pv_game::get_field_aet_frame_by_name_id(pv_game_field& field, + int32_t aet_index, std::pair& aet_name_id) { + auto elem = field.aet[aet_index].find(aet_name_id); + if (elem != field.aet[aet_index].end()) + return elem->second; + return -1; +} + +int32_t pv_game::get_field_aet_index_by_name_id(pv_game_field& field, + int32_t aet_index, std::pair& aet_name_id) { + int32_t index = 0; + for (std::string& i : field.aet_names[aet_index]) { + std::string* id = 0; + if (index < field.aet_ids[aet_index].size()) + id = &field.aet_ids[aet_index][index]; + if ((!id || !id->compare(aet_name_id.first)) && !i.compare(aet_name_id.second)) + return index; + + index++; + } + return -1; +} + +int32_t pv_game::get_field_auth_3d_frame(pv_game_field& field, int32_t uid, int32_t type) { + switch (type) { + case 0: { + auto elem = field.auth_3d_frame_list.find(uid); + if (elem != field.auth_3d_frame_list.end()) + return elem->second; + } break; + case 1: + return field.light_frame; + } + return -3; +} + +int32_t pv_game::get_frame(int32_t frame, int64_t dsc_time, int64_t curr_time) { + if (frame == -3) + frame = 0; + if (dsc_time >= 0 && curr_time >= 0) { + if (frame == -2) + return 0; + else if (frame == -6) + return -4; + } + return frame; +} + +int32_t pv_game::get_frame_continue(int32_t frame) { + if (frame == -3) + frame = -2; + return frame; +} + +float_t pv_game::get_life_gauge_safety_time() { + float_t time = (float_t)data.life_gauge_safety_time - data.current_time_float; + return max_def(time, 0.0f); +} + +float_t pv_game::get_next_aet_max_frame_change_field(int32_t aet_index, std::pair& aet_name_id, int64_t dsc_time, int64_t curr_time) { + if (dsc_time < 0) + return -1.0f; + + int64_t max_time = -1; + if (dsc_time > data.pv_data.change_field_branch_time) { + prj::vector_pair& change_field = data.pv_data.branch_mode != 2 + ? data.pv_data.change_field_branch_fail + : data.pv_data.change_field_branch_success; + return get_next_aet_max_time_max_frame_change_field(aet_index, + aet_name_id, dsc_time, &max_time, curr_time, change_field); + } + + float_t max_frame_fail = get_next_aet_max_time_max_frame_change_field(aet_index, + aet_name_id, dsc_time, &max_time, curr_time, data.pv_data.change_field_branch_fail); + if (max_frame_fail < 0.0f) + return get_next_aet_max_time_max_frame_change_field(aet_index, + aet_name_id, dsc_time, &max_time, curr_time, data.pv_data.change_field_branch_success); + else if (max_time > data.pv_data.change_field_branch_time) { + float_t max_frame_success = get_next_aet_max_time_max_frame_change_field(aet_index, + aet_name_id, dsc_time, &max_time, curr_time, data.pv_data.change_field_branch_success); + if (max_frame_success >= 0.0f && max_frame_success < max_frame_fail) + return max_frame_success; + } + return max_frame_fail; +} + +float_t pv_game::get_next_aet_max_time_max_frame_change_field(int32_t aet_index, + std::pair& aet_name_id, int64_t dsc_time, int64_t* max_time, + int64_t curr_time, prj::vector_pair& change_field) { + if (!max_time) + return -1.0f; + + for (auto& i : change_field) { + int64_t time = 10000LL * i.first; + if (time > dsc_time && i.second >= 0 && i.second < data.field_data.size() + && ((get_field_aet_frame_by_name_id(data.field_data[i.second], aet_index, aet_name_id) + 5) & ~5u) == 0) { + *max_time = time; + return roundf(dsc_time_to_frame(time - get_aet_time(aet_index, aet_name_id))) - 1.0f; + } + } + return -1.0f; +} + +float_t pv_game::get_next_auth_3d_max_frame_change_field(uint32_t auth_3d_uid, + int64_t dsc_time, int64_t curr_time, int32_t type) { + if (dsc_time < 0) + return -1.0f; + + int64_t max_time = -1; + if (dsc_time > data.pv_data.change_field_branch_time) { + prj::vector_pair& change_field = data.pv_data.branch_mode != 2 + ? data.pv_data.change_field_branch_fail + : data.pv_data.change_field_branch_success; + return get_next_auth_3d_max_time_max_frame_change_field(auth_3d_uid, + dsc_time, &max_time, curr_time, change_field, type); + } + + float_t max_frame_fail = get_next_auth_3d_max_time_max_frame_change_field(auth_3d_uid, + dsc_time, &max_time, curr_time, data.pv_data.change_field_branch_fail, type); + if (max_frame_fail < 0.0f) + return get_next_auth_3d_max_time_max_frame_change_field(auth_3d_uid, + dsc_time, &max_time, curr_time, data.pv_data.change_field_branch_success, type); + else if (max_time > data.pv_data.change_field_branch_time) { + float_t max_frame_success = get_next_auth_3d_max_time_max_frame_change_field(auth_3d_uid, + dsc_time, &max_time, curr_time, data.pv_data.change_field_branch_success, type); + if (max_frame_success >= 0.0f && max_frame_success < max_frame_fail) + return max_frame_success; + } + return max_frame_fail; +} + +float_t pv_game::get_next_auth_3d_max_time_max_frame_change_field(uint32_t auth_3d_uid, int64_t dsc_time, + int64_t* max_time, int64_t curr_time, prj::vector_pair& change_field, int32_t type) { + if (!max_time) + return -1.0f; + + for (auto& i : change_field) { + int64_t time = 10000LL * i.first; + if (time > dsc_time && i.second >= 0 && i.second < data.field_data.size() + && ((get_field_auth_3d_frame(data.field_data[i.second], auth_3d_uid, type) + 5) & -6) == 0) { + *max_time = time; + return roundf(dsc_time_to_frame(time - get_auth_3d_time(auth_3d_uid, type))) - 1.0f; + } + } + return -1.0f; +} + +int32_t pv_game::get_play_data_ex_song_index() { + return data.play_data.ex_song_index; +} + +std::string pv_game::get_play_data_song_file_name() { + return data.play_data.song_file_name; +} + +const pv_db_pv* pv_game::get_pv_db_pv() { + return data.pv; +} + +float_t pv_game::get_pv_hidden_timing() { + const pv_db_pv_difficulty* diff = data.pv->get_difficulty( + sub_14013C8C0()->difficulty, sub_14013C8C0()->edition); + if (diff) + return diff->hidden_timing; + return 0.3f; +} + +int32_t pv_game::get_pv_high_speed_rate() { + const pv_db_pv_difficulty* diff = data.pv->get_difficulty( + sub_14013C8C0()->difficulty, sub_14013C8C0()->edition); + if (diff) + return diff->high_speed_rate; + return 1; +} + +std::string pv_game::get_pv_movie_file_name(int32_t index) { + const pv_db_pv_difficulty* diff = data.pv->get_difficulty( + sub_14013C8C0()->difficulty, sub_14013C8C0()->edition); + if (diff && index >= 0 && index < diff->movie_list.size()) + return diff->movie_list[index].name; + return {}; +} + +float_t pv_game::get_pv_sudden_timing() { + const pv_db_pv_difficulty* diff = data.pv->get_difficulty( + sub_14013C8C0()->difficulty, sub_14013C8C0()->edition); + if (diff) + return diff->sudden_timing; + return 0.6f; +} + +std::string pv_game::get_song_name() { + struc_717* v13 = sub_14038BB30(); + struc_716* v15; + if (v13->field_0.stage_index >= 4) + v15 = &v13->field_28[2]; + else + v15 = &v13->field_28[v13->field_0.stage_index]; + + const pv_db_pv* pv = data.pv; + if (pv->another_song.size() && v15->field_2C.another_song_index < pv->another_song.size()) { + const std::string& another_song_name = pv->another_song[v15->field_2C.another_song_index].name; + if (another_song_name.size()) + return another_song_name; + } + + if (pv->ex_song.data.size()) { + if (data.play_data.ex_song_index <= 0) { + int32_t ex_song_index = sub_1400FCFD0(data.chara, pv); + if (ex_song_index >= 0 && ex_song_index < pv->ex_song.data.size()) + return pv->ex_song.data[ex_song_index].name; + } + else if (data.play_data.ex_song_index <= pv->ex_song.data.size()) + return pv->ex_song.data[data.play_data.ex_song_index - 1LL].name; + } + return pv->song_name; +} + +std::string pv_game::get_song_file_name(int32_t& ex_song_index) { + ex_song_index = -1; + + struc_717* v13 = sub_14038BB30(); + struc_716* v15; + if (v13->field_0.stage_index >= 4) + v15 = &v13->field_28[2]; + else + v15 = &v13->field_28[v13->field_0.stage_index]; + + ex_song_index = -1; + const pv_db_pv* pv = data.pv; + if (pv->another_song.size() && v15->field_2C.another_song_index < pv->another_song.size()) { + const std::string& another_song_name = pv->another_song[v15->field_2C.another_song_index].name; + if (another_song_name.size()) + return another_song_name; + } + + if (pv->ex_song.data.size()) { + if (ex_song_index < 0) { + int32_t _ex_song_index = sub_1400FCFD0(data.chara, pv); + if (_ex_song_index >= 0 && _ex_song_index < pv->ex_song.data.size()) { + ex_song_index = _ex_song_index; + return pv->ex_song.data[_ex_song_index].name; + } + } + else if (ex_song_index > 0 && data.play_data.ex_song_index <= pv->ex_song.data.size()) { + ex_song_index = data.play_data.ex_song_index - 1; + return pv->ex_song.data[data.play_data.ex_song_index - 1LL].name; + } + } + + return data.pv->song_file_name; +} + +task_stage_info pv_game::get_stage_info(int32_t stage_index) { + if (data.stage_infos.size()) + for (const task_stage_info& i : data.stage_infos) + if (i.check() && i.get_stage_index() == stage_index) + return i; + return {}; +} + +bool pv_game::is_play_data_option_3() { + return data.play_data.option == 3; +} + +void pv_game::itmpv_reset() { + for (auto& i : data.itmpv) + for (auto& j : i) { + auth_3d_id& id = j.second.first; + id.set_repeat(0); + id.set_enable(0); + id.set_camera_root_update(0); + id.set_visibility(1); + id.set_frame_rate(get_diva_pv_frame_rate()); + id.set_shadow(true); + id.set_chara_id((int32_t)(&i - data.itmpv)); + j.second.second = -1; + } +} + +bool pv_game::load() { + data_struct* aft_data = &data_list[DATA_AFT]; + aet_database* aft_aet_db = &aft_data->data_ft.aet_db; + auth_3d_database* aft_auth_3d_db = &aft_data->data_ft.auth_3d_db; + bone_database* aft_bone_data = &aft_data->data_ft.bone_data; + motion_database* aft_mot_db = &aft_data->data_ft.mot_db; + object_database* aft_obj_db = &aft_data->data_ft.obj_db; + sprite_database* aft_spr_db = &aft_data->data_ft.spr_db; + texture_database* aft_tex_db = &aft_data->data_ft.tex_db; + stage_database* aft_stage_data = &aft_data->data_ft.stage_data; + + switch (state) { + case 0: { + wave_audio_storage_clear(); + if (sub_14013C8C0()->sub_1400E7920()) { + reset(); + state = 1; + } + else /*if (sub_14013C8F0()->sub_14012AA70())*/ { + reset(); + state = 1; + } + /*else + break;*/ + } + case 1: { + if (sub_14013C8C0()->sub_1400E7910() < 4) { + pv_id = sub_14013C8C0()->pv; + pv_db_pv* pv = task_pv_db_get_pv(pv_id); + if (pv) + data.pv = pv; + + const pv_db_pv_disp2d* pv_disp2d; + int32_t pv_disp2d_pv_id; + if (pv) { + pv_disp2d = &data.pv->disp2d; + pv_disp2d_pv_id = pv->id; + } + else { + pv_disp2d = 0; + pv_disp2d_pv_id = pv_id; + } + + pv_disp2d_data.pv_id = pv_disp2d_pv_id; + pv_disp2d_data.pv_spr_set_id = -1; + pv_disp2d_data.pv_aet_set_id = -1; + pv_disp2d_data.pv_aet_id = -1; + if (pv_disp2d) { + if (pv_disp2d->set_name.size()) { + std::string spr_set_name("SPR_GAM_PV"); + spr_set_name.append(pv_disp2d->set_name); + + std::string aet_set_name("AET_GAM_PV"); + aet_set_name.append(pv_disp2d->set_name); + + std::string aet_name(aet_set_name); + aet_name.append("_MAIN"); + + pv_disp2d_data.pv_spr_set_id = aft_spr_db->get_spr_set_id_by_name(spr_set_name.c_str()); + pv_disp2d_data.pv_aet_set_id = aft_aet_db->get_aet_set_id_by_name(aet_set_name.c_str()); + pv_disp2d_data.pv_aet_id = aft_aet_db->get_aet_id_by_name(aet_set_name.c_str()); + } + + pv_disp2d_data.title_start_2d_field = pv_disp2d->title_start_2d_field; + pv_disp2d_data.title_end_2d_field = pv_disp2d->title_end_2d_field; + pv_disp2d_data.title_start_2d_low_field = pv_disp2d->title_start_2d_low_field; + pv_disp2d_data.title_end_2d_low_field = pv_disp2d->title_end_2d_low_field; + pv_disp2d_data.title_start_3d_field = pv_disp2d->title_start_3d_field; + pv_disp2d_data.title_end_3d_field = pv_disp2d->title_end_3d_field; + pv_disp2d_data.target_shadow_type = pv_disp2d->target_shadow_type == 1; + pv_disp2d_data.title_2d_layer.assign(pv_disp2d->title_2d_layer); + } + + data.pv_disp2d = &pv_disp2d_data; + //sub_14013C8F0()->field_0.target_shadow_type = pv_disp2d_data.target_shadow_type; + } + else + field_C = -1; + + const pv_db_pv_difficulty* diff = get_pv_db_pv()->get_difficulty( + sub_14013C8C0()->difficulty, sub_14013C8C0()->edition); + if (diff) { + data.play_data.se_name.assign(diff->se_name); + data.play_data.pvbranch_success_se_name.assign(diff->pvbranch_success_se_name); + data.play_data.slide_name.assign(diff->slide_name); + data.play_data.chainslide_first_name.assign(diff->chainslide_first_name); + data.play_data.chainslide_sub_name.assign(diff->chainslide_sub_name); + data.play_data.chainslide_success_name.assign(diff->chainslide_success_name); + data.play_data.chainslide_failure_name.assign(diff->chainslide_failure_name); + data.play_data.slidertouch_name.assign(diff->slidertouch_name); + if (diff->attribute.bitset.test(2)) + data.has_slide = true; + if (data.play_data.pvbranch_success_se_name.size()) + data.has_success_se = true; + if (data.play_data.other_se_name.size()) + data.play_data.se_name.assign(data.play_data.other_se_name); + if (data.play_data.se_name.size()) + wave_audio_storage_load_wave_audio(data.play_data.se_name); + if (data.play_data.other_slide_name.size()) + data.play_data.slide_name.assign(data.play_data.other_slide_name); + if (data.play_data.other_chainslide_first_name.size()) + data.play_data.chainslide_first_name.assign(data.play_data.other_chainslide_first_name); + if (data.play_data.other_chainslide_sub_name.size()) + data.play_data.chainslide_sub_name.assign(data.play_data.other_chainslide_sub_name); + if (data.play_data.other_chainslide_success_name.size()) + data.play_data.chainslide_success_name.assign(data.play_data.other_chainslide_success_name); + if (data.play_data.other_chainslide_failure_name.size()) + data.play_data.chainslide_failure_name.assign(data.play_data.other_chainslide_failure_name); + if (data.play_data.other_slidertouch_name.size()) + data.play_data.slidertouch_name.assign(data.play_data.other_slidertouch_name); + if (data.play_data.pvbranch_success_se_name.size()) + wave_audio_storage_load_wave_audio(data.play_data.pvbranch_success_se_name); + if (data.play_data.slide_name.size()) + wave_audio_storage_load_wave_audio(data.play_data.slide_name); + if (data.play_data.chainslide_first_name.size()) + wave_audio_storage_load_wave_audio(data.play_data.chainslide_first_name); + if (data.play_data.chainslide_sub_name.size()) + wave_audio_storage_load_wave_audio(data.play_data.chainslide_sub_name); + if (data.play_data.chainslide_success_name.size()) + wave_audio_storage_load_wave_audio(data.play_data.chainslide_success_name); + if (data.play_data.chainslide_failure_name.size()) + wave_audio_storage_load_wave_audio(data.play_data.chainslide_failure_name); + } + + PlayerData* player_data = player_data_array_get(0); + for (auto& i : player_data->field_5D0[sub_14038BB30()->field_0.field_0]) + if (i.pv_id != pv_id || i.edition != sub_14013C8C0()->edition) { + if (i.field_CC != -1 && i.rival_percentage > 0) + data.rival_percentage = (float_t)i.rival_percentage * 0.01f; + break; + } + + for (int32_t i = 0; i < ROB_CHARA_COUNT; i++) { + pv_game_chara& j = data.chara[i]; + j.reset(); + j.pv_data.field_4 = false; + j.pv_data.field_70 = player_data->field_66C; + + struc_674 v750; + v750.performer = i; + v750.module = modules[i]; + v750.item = items[i]; + v750.field_1C = player_data->field_0; + v750.pv = data.pv; + if (data.pv) + sub_140105010(data.chara, ROB_CHARA_COUNT, items_mask, v750); + + if (data.height_adjust) + j.pv_data.height_adjust = true; + + pv_performer_size size = data.pv ? data.pv->get_performer_size(i) : PV_PERFORMER_NORMAL; + switch (size) { + case PV_PERFORMER_NORMAL: + default: + j.pv_data.chara_size_index = 1; + break; + case PV_PERFORMER_PLAY_CHARA: + j.pv_data.chara_size_index = chara_init_data_get_chara_size_index(j.chara_index); + break; + case PV_PERFORMER_PV_CHARA: + j.pv_data.chara_size_index = chara_init_data_get_chara_size_index(data.pv->get_performer_chara(i)); + break; + case PV_PERFORMER_SHORT: + j.pv_data.chara_size_index = 2; + break; + case PV_PERFORMER_TALL: + j.pv_data.chara_size_index = 0; + break; + } + + set_eyes_adjust(&j); + } + state = 6; + } break; + case 2: { + const pv_db_pv_difficulty* diff = get_pv_db_pv()->get_difficulty( + sub_14013C8C0()->difficulty, sub_14013C8C0()->edition); + /*if (diff && diff->movie_list.size()) { + resolution_struct* res_wind = res_window_get(); + resolution_struct* res_wind_int = res_window_internal_get(); + + struc_15 v750; + v750.field_0.field_0.x = 0.0f; + v750.field_0.field_0.y = (float_t)(res_wind->height - res_wind_int->height) * 0.5f; + v750.field_0.field_8.x = (float_t)res_wind_int->width; + v750.field_0.field_8.y = (float_t)res_wind_int->height; + v750.field_0.field_10 = res_wind->resolution_mode; + v750.field_0.field_14 = -1.0f; + v750.field_0.field_1C = diff->movie_surface == PV_MOVIE_SURFACE_FRONT ? 0 : 2; + v750.field_20 = true; + + for (pv_db_pv_movie& i : diff->movie_list) + if (i.name.size() && aft_data->check_file_exists(i.name.c_str())) { + task_movie_get(v43->index)->sub_14041F260(v750); + task_movie_get(v43->index)->sub_14041F0A0(i.name); + task_movie_get(v43->index)->sub_14041F240(0.0f); + } + }*/ + + if (sub_14013C8C0()->sub_1400E7910() >= 4) { + state = 12; + for (pv_game_chara& i : data.chara) { + if (!i.motion_ids.size()) + continue; + + i.chara_id = rob_chara_array_init_chara_index(i.chara_index, i.pv_data, i.cos, true); + if (i.chara_id != -1) + i.rob_chr = rob_chara_array_get(i.chara_id); + } + + rctx_ptr->render_manager.set_effect_texture(0); + state = 12; + return false; + } + + data.motion_set_ids.clear(); + data.motion_set_face_ids.clear(); + + if (diff) { + for (int32_t i = 0; i < ROB_CHARA_COUNT; i++) { + pv_game_chara& chr = data.chara[i]; + data.motion_set_ids.reserve(diff->motion[i].size()); + data.motion_set_face_ids.reserve(diff->motion[i].size()); + + int32_t motion_face_id_index = 0; + for (const pv_db_pv_motion& j : diff->motion[i]) { + if (j.index < 0) + continue; + + uint32_t motion_id = j.id; + if (data.pv) + motion_id = data.pv->get_chrmot_motion_id(i, chr.chara_index, j); + + uint32_t motion_set_id = aft_mot_db->get_motion_set_id_by_motion_id(motion_id); + if (motion_set_id != -1) { + if (!prj::find(chr.motion_ids, motion_id)) + chr.motion_ids.push_back(motion_id); + if (!prj::find(data.motion_set_ids, motion_set_id)) + data.motion_set_ids.push_back(motion_set_id); + } + + if (j.index <= 0) + continue; + + std::string motion_face_name; + motion_face_name.assign(chara_index_get_face_mot_name(chr.chara_index)); + motion_face_name.append("_FACE_"); + motion_face_name.append(j.name); + + uint32_t motion_face_id = aft_mot_db->get_motion_id(motion_face_name.c_str()); + if (motion_face_id_index < 10) + chr.pv_data.motion_face_ids[motion_face_id_index++] = motion_face_id; + + uint32_t motion_face_set_id = aft_mot_db->get_motion_set_id_by_motion_id(motion_face_id); + if (motion_face_set_id != -1 && motion_face_set_id != 2) { + if (!prj::find(chr.motion_face_ids, motion_face_id)) + chr.motion_face_ids.push_back(motion_face_id); + if (!prj::find(data.motion_set_face_ids, motion_face_set_id)) + data.motion_set_face_ids.push_back(motion_face_set_id); + } + } + } + } + + for (uint32_t& i : data.motion_set_ids) { + motion_set_load_motion(i, std::string(data.pv->mdata.dir), aft_mot_db); + motion_set_load_mothead(i, std::string(data.pv->mdata.dir), aft_mot_db); + } + + for (uint32_t& i : data.motion_set_face_ids) + motion_set_load_motion(i, std::string(data.pv->mdata.dir), aft_mot_db); + + pv_expression_file_load(aft_data, data.pv->pv_expression_file_name.c_str()); + + for (pv_game_chara& i : data.chara) { + if (!i.motion_ids.size()) + continue; + + i.chara_id = rob_chara_array_init_chara_index(i.chara_index, i.pv_data, i.cos, true); + if (i.chara_id != -1) + i.rob_chr = rob_chara_array_get(i.chara_id); + } + + rctx_ptr->render_manager.set_effect_texture(0); + state = 3; + } return false; + case 3: { + const pv_db_pv_difficulty* diff = get_pv_db_pv()->get_difficulty( + sub_14013C8C0()->difficulty, sub_14013C8C0()->edition); + /*for (pv_db_pv_movie& i : diff->movie_list) + if (app::TaskWork::CheckTaskReady(task_movie_get(i.index)) + && !task_movie_get(i.index)->sub_14041F0E0()) + return false;*/ + + for (uint32_t& i : data.motion_set_ids) + if (motion_storage_check_mot_file_not_ready(i) + || mothead_storage_check_mhd_file_not_ready(i)) + return false; + + for (uint32_t& i : data.motion_set_face_ids) + if (motion_storage_check_mot_file_not_ready(i)) + return false; + + if (data.pv->pv_expression_file_name.size() + && pv_expression_file_check_not_ready(data.pv->pv_expression_file_name.c_str())) + return false; + + data.pv_data.dsc_state = 0; + data.field_2D094 = false; + data.use_osage_play_data = false; + if (get_pv_db_pv()->use_osage_play_data) { + bool use_osage_play_data = true; + for (uint32_t& i : data.motion_set_ids) { + bool has_opd = false; + const uint32_t* opd_motion_set_ids = get_opd_motion_set_ids(); + while (*opd_motion_set_ids != -1) { + if (*opd_motion_set_ids == i) + has_opd = true; + opd_motion_set_ids++; + } + + if (i != 2 && !has_opd) + use_osage_play_data = false; + } + + if (use_osage_play_data) + data.use_osage_play_data = true; + } + state = 4; + } return false; + case 4: { + const pv_db_pv_difficulty* diff = get_pv_db_pv()->get_difficulty( + sub_14013C8C0()->difficulty, sub_14013C8C0()->edition); + if (diff && !data.field_2D094) { + if (sub_14013C8C0()->sub_1400E7910() < 4 + && !data.pv_data.read_dsc_file(std::string(diff->script_file_name), this, data.field_2D00C)) + return false; + + data.field_2D094 = true; + + int32_t field_index = 0; + for (pv_game_field& i : data.field_data) { + bool found = false; + for (auto& i : data.pv_data.change_field_branch_fail) + if (i.second == field_index) { + found = true; + break; + } + + if (!found) + for (auto& i : data.pv_data.change_field_branch_success) + if (i.second == field_index) { + found = true; + break; + } + + if (!found) { + field_index++; + continue; + } + + + for (auto& j : i.auth_3d_frame_list) + switch (j.second) { + case -6: + j.second = -2; + break; + case -5: + j.second = -1; + break; + case -4: + j.second = 0; + break; + } + + switch (i.light_frame) { + case -6: + i.light_frame = -2; + break; + case -5: + i.light_frame = -1; + break; + case -4: + i.light_frame = 0; + break; + } + + for (auto& j : i.aet) + for (auto& k : j) + switch (k.second) { + case -6: + k.second = -2; + break; + case -5: + k.second = -1; + break; + case -4: + k.second = 0; + break; + } + + field_index++; + } + } + + bool has_chara = false; + for (pv_game_chara& i : data.chara) + if (i.chara_id != -1 && i.rob_chr) { + has_chara = true; + if (!task_rob_manager_check_chara_loaded(i.rob_chr->chara_id)) + return false; + } + + if (has_chara) { + task_rob_manager_hide_task(); + + for (int32_t i = 0; i < ROB_CHARA_COUNT; i++) { + pv_game_chara& chr = data.chara[i]; + if (chr.chara_id == -1 || !chr.rob_chr) + continue; + + for (int32_t j = 0; j < PV_PERFORMER_ITEM_MAX; j++) { + int32_t item_no = data.pv->get_performer_item(i, (pv_performer_item)j); + if (!item_no || item_no < 0 && !items_mask[i].arr[j]) + chr.rob_chr->load_body_parts_object_info( + pv_performer_item_to_item_id((pv_performer_item)j), + {}, aft_bone_data, aft_data, aft_obj_db); + } + set_osage_init(chr); + } + } + state = 5; + } return false; + case 5: { + if (skin_param_manager_array_check_task_ready()) + return false; + + if (!data.use_osage_play_data) + for (pv_game_chara& i : data.chara) { + if (i.chara_id == -1 || !i.rob_chr) + continue; + + pv_osage_manager_array_reset(i.chara_id); + const std::vector* set_motion = data.pv_data.get_set_motion(i.chara_id); + if (set_motion) + pv_osage_manager_array_set_pv_set_motion(i.chara_id, *set_motion); + pv_osage_manager_array_set_pv_id(i.chara_id, data.pv->id, true); + } + state = 8; + } return false; + case 6: { + rand_state_array_4_set_seed_1393939(); + if (task_stage_load_task("PV_STAGE")) + return false; + + for (const pv_db_pv_chreff& i : data.pv->chreff) { + chara_index src_chara_index = chara_index_get_from_chara_name(i.name.c_str()); + chara_index dst_chara_index = data.chara[i.id].chara_index; + + const std::string& src_name = i.name; + std::string dst_name(chara_index_get_auth_3d_name(data.chara[i.id].chara_index)); + + for (const pv_db_pv_chreff_data& j : i.data) { + pv_game_chreff chreff; + chreff.src_chara_index = src_chara_index; + chreff.dst_chara_index = dst_chara_index; + chreff.type = j.type; + chreff.src_auth_3d.assign(j.name); + chreff.dst_auth_3d.assign(j.name); + + if (j.type && src_chara_index != dst_chara_index) { + size_t pos = chreff.dst_auth_3d.find(src_name); + if (pos != -1) + chreff.dst_auth_3d.replace(pos, 3, dst_name); + else { + size_t pos = chreff.dst_auth_3d.find(dst_name); + if (pos != -1) + chreff.dst_auth_3d.replace(pos, 3, src_name); + } + } + + if (j.type != PV_CHREFF_DATA_AUTH3D && j.type != PV_CHREFF_DATA_AUTH3D_OBJ + && !(j.type && src_chara_index == dst_chara_index)) + continue; + + chreff.src_auth_3d_uid = aft_auth_3d_db->get_uid(chreff.src_auth_3d.c_str()); + chreff.dst_auth_3d_uid = aft_auth_3d_db->get_uid(chreff.dst_auth_3d.c_str()); + + std::string& src_category = aft_auth_3d_db->uid[chreff.src_auth_3d_uid].category; + if (src_category.size()) + chreff.src_auth_3d_category.assign(src_category); + + std::string& dst_category = aft_auth_3d_db->uid[chreff.dst_auth_3d_uid].category; + if (dst_category.size()) + chreff.dst_auth_3d_category.assign(dst_category); + + if (chreff.dst_auth_3d_uid == -1 || !dst_category.size()) { + chreff.dst_chara_index = src_chara_index; + chreff.dst_auth_3d.assign(chreff.src_auth_3d); + chreff.dst_auth_3d_uid = chreff.src_auth_3d_uid; + chreff.dst_auth_3d_category.assign(chreff.src_auth_3d_category); + + if (chreff.dst_auth_3d_uid == -1 || !src_category.size()) + continue; + } + + if (j.type == PV_CHREFF_DATA_AUTH3D_OBJ && src_chara_index != dst_chara_index) { + std::string dst_category(chreff.dst_auth_3d_category); + size_t pos = dst_category.find(src_name); + if (pos != -1) { + dst_category.replace(pos, 3, dst_name); + if (aft_obj_db->get_object_set_id(dst_category.c_str()) != -1) { + chreff.dst_auth_3d_category.assign(dst_category); + data.chreff_auth_3d_obj.push_back(chreff); + } + } + else { + size_t pos = dst_category.find(dst_name); + if (pos != -1) { + dst_category.replace(pos, 3, src_name); + if (aft_obj_db->get_object_set_id(dst_category.c_str()) != -1) { + chreff.src_chara_index = src_chara_index; + chreff.dst_chara_index = dst_chara_index; + chreff.dst_auth_3d_category.assign(dst_category); + data.chreff_auth_3d_obj.push_back(chreff); + } + } + } + } + + data.chreff_auth_3d.push_back(chreff); + } + } + + data.chreff_auth_3d_obj_set_ids.clear(); + + const pv_db_pv_difficulty* diff = get_pv_db_pv()->get_difficulty( + sub_14013C8C0()->difficulty, sub_14013C8C0()->edition); + if (diff) { + data.field_data.reserve(diff->field.data.size()); + light_param_data_storage_data_set_pv_id(sub_14013C8C0()->pv); + + for (const pv_db_pv_field& i : diff->field.data) { + pv_game_field field; + + int32_t stage_index = i.stage_index; + if (data.ex_stage && i.ex_stage_index != -1) + stage_index = i.ex_stage_index; + + if (stage_index != -1) { + field.stage_index = stage_index; + data.stage_indices.push_back(stage_index); + } + + const std::vector* auth_3d_list = &i.auth_3d_list; + if (data.ex_stage && i.ex_auth_3d_list.size()) + auth_3d_list = &i.ex_auth_3d_list; + + size_t auth_3d_list_index = 0; + for (const std::string& j : *auth_3d_list) { + int32_t auth_3d_uid = aft_auth_3d_db->get_uid(j.c_str()); + check_auth_replace_by_module(j.c_str(), auth_3d_uid); + if (auth_3d_uid != -1) { + int32_t frame = -3; + if (auth_3d_list_index < i.auth_3d_frame_list.size()) { + frame = i.auth_3d_frame_list[auth_3d_list_index]; + data.has_auth_3d_frame = true; + } + + int32_t chreff_auth_3d_obj_set_id = get_chreff_auth_3d_object_set(auth_3d_uid); + field.auth_3d_frame_list.insert_or_assign(auth_3d_uid, frame); + field.auth_3d_uids.push_back(auth_3d_uid); + data.loaded_auth_3d_uids.push_back(auth_3d_uid); + + if (aft_auth_3d_db->uid[auth_3d_uid].category.size()) + data.auth_3d_categories.push_back(aft_auth_3d_db->uid[auth_3d_uid].category); + + if (chreff_auth_3d_obj_set_id != -1) + data.chreff_auth_3d_obj_set_ids.push_back(chreff_auth_3d_obj_set_id); + else { + size_t pos = j.find('_'); + if (pos != -1) { + std::string stage_name = j.substr(0, pos); + uint32_t stage_index = aft_stage_data->get_stage_index(stage_name.c_str()); + if (stage_index != -1) + data.stage_indices.push_back(stage_index); + } + } + } + } + + int32_t light_uid = aft_auth_3d_db->get_uid(i.light.c_str()); + check_auth_replace_by_module(i.light.c_str(), light_uid); + + if (light_uid != -1) { + field.light_auth_3d_uid = light_uid; + data.loaded_auth_3d_uids.push_back(light_uid); + + field.light_frame = i.light_frame; + if (i.light_frame_set) + data.has_light_frame = true; + + if (aft_auth_3d_db->uid[light_uid].category.size()) + data.auth_3d_categories.push_back(aft_auth_3d_db->uid[light_uid].category); + + size_t pos = i.light.find('_'); + if (pos != -1) { + std::string stage_name = i.light.substr(0, pos); + uint32_t stage_index = aft_stage_data->get_stage_index(stage_name.c_str()); + if (stage_index != -1) + data.stage_indices.push_back(stage_index); + } + } + + if (i.spr_set_back.size()) { + uint32_t spr_set_id = aft_spr_db->get_spr_set_id_by_name(i.spr_set_back.c_str()); + if (spr_set_id != -1) { + std::string spr_set_back_image(i.spr_set_back); + spr_set_back_image.append("_IMAGE"); + + uint32_t spr_id = aft_spr_db->get_spr_set_id_by_name(spr_set_back_image.c_str()); + if (spr_id != -1) { + data.spr_set_back_ids.push_back(spr_set_id); + field.stage_index = aft_stage_data->get_stage_index("STGAETBACK"); + data.stage_indices.push_back(field.stage_index); + } + } + } + + for (int32_t j = 0; j < PV_AET_MAX; j++) { + const std::vector& aet_name = i.aet.name[j]; + const std::vector& aet_id = i.aet.id[j]; + const std::vector& aet_frame = i.aet.frame[j]; + + size_t aet_count = aet_name.size(); + for (size_t k = 0; k < aet_count; k++) { + const std::string& name = aet_name[k]; + field.aet_names[j].push_back(name); + if (k) + data.has_aet_list[k] = true; + + std::string id; + if (k < aet_id.size()) + id.assign(aet_id[k]); + field.aet_ids[j].push_back(id); + + int32_t frame = -3; + if (k < aet_frame.size()) { + frame = aet_frame[k]; + data.has_aet_frame[j] = true; + } + + field.aet[j].insert_or_assign({ id, name }, frame); + } + } + + if (Glitter::glt_particle_manager) { + int32_t emision_rs_list_index = 0; + for (const std::string& j : i.effect_rs_list) { + float_t emission = -1.0; + if (emision_rs_list_index < i.effect_emision_rs_list.size()) + emission = i.effect_emision_rs_list[emision_rs_list_index++]; + + pv_effect_resource pv_eff; + pv_eff.name.assign(j); + pv_eff.emission = emission; + data.effect_rs_list.push_back(pv_eff); + } + + for (const std::string& j : i.play_eff_list) + field.play_eff_list.push_back(Glitter::glt_particle_manager->CalculateHash(j.c_str())); + + for (const std::string& j : i.stop_eff_list) + field.stop_eff_list.push_back(Glitter::glt_particle_manager->CalculateHash(j.c_str())); + } + + field.stage_flag = i.stage_flag; + field.cam_blur = i.cam_blur; + field.npr_type = i.npr_type; + field.sdw_off = i.sdw_off; + data.field_data.push_back(field); + } + + prj::sort_unique(data.chreff_auth_3d_obj_set_ids); + for (uint32_t& i : data.chreff_auth_3d_obj_set_ids) + object_storage_load_set(aft_data, aft_obj_db, i); + + char campv[0x40]; + sprintf_s(campv, sizeof(campv), "CAMPV%03d", get_pv_db_pv()->id); + data.campv_string.assign(campv); + + aft_auth_3d_db->get_category_uids(data.campv_string.c_str(), data.campv_auth_3d_uids); + if (data.campv_auth_3d_uids.size()) { + data.auth_3d_categories.push_back(data.campv_string); + + data.loaded_auth_3d_uids.insert(data.loaded_auth_3d_uids.end(), + data.campv_auth_3d_uids.begin(), data.campv_auth_3d_uids.end()); + } + + char itmpv[0x40]; + sprintf_s(itmpv, sizeof(itmpv), "ITMPV%03d", get_pv_db_pv()->id); + data.itmpv_string.assign(itmpv); + + aft_auth_3d_db->get_category_uids(data.itmpv_string.c_str(), data.itmpv_auth_3d_uids); + if (data.itmpv_auth_3d_uids.size()) { + data.auth_3d_categories.push_back(data.itmpv_string); + for (int32_t& i : data.itmpv_auth_3d_uids) + check_auth_replace_by_module(auth_3d_data_get_uid_name(i, aft_auth_3d_db), i); + + data.loaded_auth_3d_uids.insert(data.loaded_auth_3d_uids.end(), + data.itmpv_auth_3d_uids.begin(), data.itmpv_auth_3d_uids.end()); + } + + bool v261 = false; + for (int32_t i = 0; i < 3; i++) { + v261 |= !!diff->field_228[i].size(); + for (auto& j : diff->field_228[i]) + data.itmpv_uids.push_back(auth_3d_data_get_uid_name(j.second.second, aft_auth_3d_db)); + } + + if (v261) + for (std::string& i : data.itmpv_uids) + data.auth_3d_categories.push_back(i); + + data.field_2D770.clear(); + for (int32_t i = 0; i < 3; i++) + for (auto& j : diff->field_228[i]) + data.field_2D770.push_back(j.second.first.set_id); + + prj::sort_unique(data.field_2D770); + for (uint32_t& i : data.field_2D770) + object_storage_load_set(aft_data, aft_obj_db, i); + + data.ex_song_ex_auth_obj_set_ids.clear(); + for (const pv_db_pv_ex_song& i : get_pv_db_pv()->ex_song.data) + for (const pv_db_pv_ex_song_ex_auth& j : i.ex_auth) { + uint32_t uid = aft_auth_3d_db->get_uid(j.org_name.c_str()); + data.loaded_auth_3d_uids.push_back(uid); + const char* category_name = aft_auth_3d_db->uid[uid].category.c_str(); + if (category_name) { + uint32_t obj_set_id = aft_obj_db->get_object_set_id(category_name); + if (obj_set_id != -1) + data.ex_song_ex_auth_obj_set_ids.push_back(obj_set_id); + } + } + + prj::sort_unique(data.ex_song_ex_auth_obj_set_ids); + for (uint32_t& i : data.ex_song_ex_auth_obj_set_ids) + object_storage_load_set(aft_data, aft_obj_db, i); + + prj::sort_unique(data.stage_indices); + if (!data.stage_indices.size()) + data.stage_indices.push_back(0); + + //stage_param_data_coli_data_load(data.pv->id); + task_stage_set_stage_indices(data.stage_indices); + task_stage_current_set_stage_display(false, true); + + data.stgpvhrc_obj_set_ids.clear(); + for (int32_t& i : data.stage_indices) { + std::string stage_name(aft_stage_data->get_stage_name(i)); + if (stage_name.find("STGPV")) + continue; + + stage_name.resize(8); + stage_name.append("HRC"); + uint32_t obj_set_id = aft_obj_db->get_object_set_id(stage_name.c_str()); + if (obj_set_id != -1) + data.stgpvhrc_obj_set_ids.push_back(obj_set_id); + } + + prj::sort_unique(data.stgpvhrc_obj_set_ids); + for (uint32_t& i : data.stgpvhrc_obj_set_ids) + object_storage_load_set(aft_data, aft_obj_db, i); + + data.has_frame_texture = false; + for (const pv_db_pv_frame_texture& i : get_pv_db_pv()->frame_texture) + if (i.data.size()) { + data.has_frame_texture = true; + rctx_ptr->post_process.frame_texture_reset(); + break; + } + } + state = 7; + } return false; + case 7: { + if (task_stage_check_not_loaded()) + return false; + + for (uint32_t& i : data.chreff_auth_3d_obj_set_ids) + if (object_storage_load_obj_set_check_not_read(i)) + return false; + + for (uint32_t& i : data.field_2D770) + if (object_storage_load_obj_set_check_not_read(i)) + return false; + + for (uint32_t& i : data.ex_song_ex_auth_obj_set_ids) + if (object_storage_load_obj_set_check_not_read(i)) + return false; + + state = 2; + } break; + case 8: { + prj::sort_unique(data.spr_set_back_ids); + for (uint32_t& i : data.spr_set_back_ids) + sprite_manager_read_file(i, std::string(data.pv->mdata.dir), aft_data, aft_spr_db); + data.field_2D7E8 = true; + + prj::sort_unique(data.auth_3d_categories); + for (std::string& i : data.auth_3d_categories) + auth_3d_data_load_category(i.c_str(), data.pv->mdata.dir.c_str()); + data.field_2DAC8 = true; + + prj::sort_unique(data.loaded_auth_3d_uids); + for (int32_t& i : data.loaded_auth_3d_uids) { + auth_3d_id id = auth_3d_data_load_uid(i, aft_auth_3d_db); + if (!id.check_not_empty()) + continue; + + id.set_enable(false); + id.set_repeat(true); + id.set_paused(false); + + data.auth_3d.insert_or_assign(i, id); + } + + for (pv_game_field& i : data.field_data) { + for (int32_t& j : i.auth_3d_uids) { + auth_3d_id id = get_auth_3d_id(j); + if (!id.check_not_empty()) + continue; + + for (pv_game_chreff& k : data.chreff_auth_3d_obj) + if (k.dst_auth_3d_uid == j) { + id.set_src_dst_chara(k.src_chara_index, k.dst_chara_index); + break; + } + + i.auth_3d_ids.push_back(id); + } + + prj::sort(i.auth_3d_ids); + + auth_3d_id light_auth_3d_id = get_auth_3d_id(i.light_auth_3d_uid); + if (light_auth_3d_id.check_not_empty()) + i.light_auth_3d_id = light_auth_3d_id; + else + i.light_auth_3d_id = {}; + } + + for (int32_t& i : data.campv_auth_3d_uids) { + const char* name = auth_3d_data_get_uid_name(i, aft_auth_3d_db); + if (!name) + continue; + + int32_t cam_index = check_chrcam(name, i); + if (!cam_index) + continue; + + auto elem = data.auth_3d.find(i); + if (elem != data.auth_3d.end()) { + auth_3d_id& id = elem->second; + id.set_camera_root_update(true); + id.set_repeat(false); + id.set_frame_rate(get_diva_pv_frame_rate()); + data.campv.insert_or_assign(cam_index, id); + } + } + data.campv_index = 0; + + for (int32_t& i : data.itmpv_auth_3d_uids) { + const char* name = auth_3d_data_get_uid_name(i, aft_auth_3d_db); + if (!name) + continue; + + std::string uid_name(name); + + char buf[0x200]; + int32_t chara_id = -1; + for (int32_t j = 0; j < ROB_CHARA_COUNT; j++) { + sprintf_s(buf, sizeof(buf), "%s_%dP", data.itmpv_string.c_str(), j + 1); + if (!uid_name.compare(buf)) { + chara_id = j; + break; + } + } + + if (chara_id != -1) + continue; + + int32_t itm_index = 1; + std::string index_str = uid_name.substr(utf8_length(buf)); + if (!index_str.size() && index_str.size() == 4 && index_str[0] == '_' + && isdigit(index_str[1]) && isdigit(index_str[2]) && isdigit(index_str[3])) + itm_index = atoi(index_str.c_str() + 1); + + if (chara_id >= 0 && itm_index >= 0) { + auto elem = data.auth_3d.find(i); + if (elem != data.auth_3d.end()) + data.itmpv[chara_id].insert_or_assign(itm_index, + std::pair(elem->second, -1)); + } + } + + itmpv_reset(); + for (struc_269& i : data.field_2DA08) { + for (auto& j : i.data) { + auth_3d_id id = auth_3d_data_load_uid(j.second, aft_auth_3d_db); + if (!id.check_not_empty()) + continue; + + id.set_enable(false); + id.set_repeat(true); + id.set_paused(false); + id.set_camera_root_update(false); + //id.set_object_info(j.first); + i.auth_3d_ids.push_back(id); + } + } + + data.edit_effect.reset(); + const pv_db_pv_difficulty* diff = get_pv_db_pv()->get_difficulty( + sub_14013C8C0()->difficulty, sub_14013C8C0()->edition); + if (diff) { + data.edit_effect.spr_set_ids.reserve(diff->edit_effect.size()); + data.edit_effect.aet_set_ids.reserve(diff->edit_effect.size()); + data.edit_effect.aet_ids.reserve(diff->edit_effect.size()); + + for (const pv_db_pv_edit_effect& i : diff->edit_effect) { + if (!i.name.size()) + continue; + + std::string aet_set_name("AET_GAM_EFF"); + aet_set_name.append(i.name); + + std::string spr_set_name("SPR_GAM_EFF"); + spr_set_name.append(i.name); + + uint32_t aet_set_id = aft_aet_db->get_aet_set_id_by_name(aet_set_name.c_str()); + uint32_t spr_set_id = aft_spr_db->get_spr_set_id_by_name(spr_set_name.c_str()); + if (aet_set_id != -1 && spr_set_id != -1) { + std::string aet_name(aet_set_name); + aet_name.append("_MAIN"); + + uint32_t aet_id = aft_aet_db->get_aet_id_by_name(aet_name.c_str()); + if (aet_id != -1) { + data.edit_effect.spr_set_ids.push_back(spr_set_id); + data.edit_effect.aet_set_ids.push_back(aet_set_id); + data.edit_effect.aet_ids.push_back(aet_id); + } + } + } + + for (uint32_t& i : data.edit_effect.spr_set_ids) + sprite_manager_read_file(i, "", aft_data, aft_spr_db); + + for (uint32_t& i : data.edit_effect.aet_set_ids) + aet_manager_read_file(i, "", aft_data, aft_aet_db); + } + + data.obj_set_itmpv.clear(); + if (diff) + for (const pv_db_pv_item& i : diff->pv_item) + if (i.index > 0) { + object_info obj_info = aft_obj_db->get_object_info(i.name.c_str()); + if (obj_info.not_null()) + data.obj_set_itmpv.push_back(obj_info.set_id); + } + + object_info itmpv_obj_info = aft_obj_db->get_object_info(data.itmpv_string.c_str()); + if (itmpv_obj_info.not_null()) + data.obj_set_itmpv.push_back(itmpv_obj_info.set_id); + + prj::sort_unique(data.obj_set_itmpv); + for (uint32_t& i : data.obj_set_itmpv) + object_storage_load_set(aft_data, aft_obj_db, i); + + data.obj_set_handitem.clear(); + if (diff) { + std::vector hand_obj_infos; + hand_obj_infos.reserve(diff->hand_item.size() * 2); + data.obj_set_handitem.reserve(diff->hand_item.size()); + for (const pv_db_pv_hand_item& i : diff->hand_item) { + if (i.index < (data.height_adjust ? 0 : 1)) + continue; + + const hand_item* hand_item = hand_item_handler_data_get_hand_item(i.id, (chara_index)-1); + if (hand_item) { + hand_obj_infos.push_back(hand_item->obj_left); + hand_obj_infos.push_back(hand_item->obj_right); + if (hand_item->obj_left.not_null()) + data.obj_set_handitem.push_back(hand_item->obj_left.set_id); + else if (hand_item->obj_right.not_null()) + data.obj_set_handitem.push_back(hand_item->obj_right.set_id); + } + } + + prj::sort_unique(data.obj_set_handitem); + for (uint32_t& i : data.obj_set_handitem) + object_storage_load_set(aft_data, aft_obj_db, i); + + skin_param_storage_load(hand_obj_infos, aft_data, aft_obj_db); + } + + pv_param::post_process_data_load_files(data.pv->id, std::string(data.pv->mdata.dir)); + pv_param::light_data_load_files(data.pv->id, std::string(data.pv->mdata.dir)); + state = 9; + } break; + case 9: { + bool wait_load = task_stage_check_not_loaded(); + + for (uint32_t& i : data.spr_set_back_ids) + if (sprite_manager_load_file(i, aft_spr_db)) + wait_load |= true; + + for (std::string& i : data.auth_3d_categories) + if (!auth_3d_data_check_category_loaded(i.c_str())) + wait_load |= true; + + for (uint32_t& i : data.edit_effect.aet_set_ids) + if (aet_manager_load_file(i, aft_aet_db)) + wait_load |= true; + + for (uint32_t& i : data.edit_effect.spr_set_ids) + if (sprite_manager_load_file(i, aft_spr_db)) + wait_load |= true; + + for (uint32_t& i : data.obj_set_itmpv) + if (object_storage_load_obj_set_check_not_read(i)) { + wait_load |= true; + break; + } + + for (uint32_t& i : data.obj_set_itmpv) + if (object_storage_load_obj_set_check_not_read(i)) { + wait_load |= true; + break; + } + + for (uint32_t& i : data.obj_set_handitem) + if (object_storage_load_obj_set_check_not_read(i)) { + wait_load |= true; + break; + } + + + for (uint32_t& i : data.stgpvhrc_obj_set_ids) + if (object_storage_load_obj_set_check_not_read(i)) { + wait_load |= true; + break; + } + + if (wait_load) + break; + + if (data.use_osage_play_data) { + for (pv_game_chara& i : data.chara) + if (i.check_chara()) + osage_play_data_manager_append_chara_motion_ids(i.rob_chr, i.motion_ids); + osage_play_data_manager_add_task(); + } + + task_stage_get_loaded_stage_infos(data.stage_infos); + state = 10; + } break; + case 10: { + for (auto& i : data.auth_3d) + i.second.read_file(aft_auth_3d_db); + + for (struc_269& i : data.field_2DA08) + for (auth_3d_id& j : i.auth_3d_ids) + j.read_file(aft_auth_3d_db); + + if (Glitter::glt_particle_manager) { + Glitter::glt_particle_manager->counter = 0; + for (pv_effect_resource& i : data.effect_rs_list) { + uint64_t hash = Glitter::glt_particle_manager->LoadFile(Glitter::FT, + aft_data, i.name.c_str(), 0, i.emission, true); + if (hash != hash_fnv1a64m_empty) + data.effect_rs_list_hashes.push_back(hash); + } + } + state = 11; + } + case 11: { + bool wait_load = false; + + for (auto& i : data.auth_3d) + if (!i.second.check_loaded()) + wait_load |= true; + + for (struc_269& i : data.field_2DA08) + for (auth_3d_id& j : i.auth_3d_ids) + if (!j.check_loaded()) + wait_load |= true; + + if (!wait_load) + state = 12; + } break; + case 12: { + post_process& pp = rctx_ptr->post_process; + int32_t frame_texture_slot = 0; + for (const pv_db_pv_frame_texture& i : data.pv->frame_texture) { + texture* tex = texture_storage_get_texture(aft_tex_db->get_texture_id(i.data.c_str())); + if (tex) + pp.frame_texture_load(frame_texture_slot, (post_process_frame_texture_type)i.type, tex); + frame_texture_slot++; + } + + /*if (app::TaskWork::CheckTaskReady(sel_main_get())) + return false; + + if (sub_14013C8C0()->sub_1400E7910() != 3 && get_pv_db_pv()->id != 999) + data.play_data.ex_song_index = sel_vocal_change_get()->sub_140112C30();*/ + + data.play_data.aix = false; + data.play_data.ogg = false; + + data.play_data.song_name.clear(); + data.play_data.song_name.assign(get_song_name()); + + int32_t ex_song_index = -1; + data.play_data.song_file_name.assign(get_song_file_name(ex_song_index)); + + std::string song_file_name = get_play_data_song_file_name(); + if (song_file_name.size() > 3 && aft_data->check_file_exists(song_file_name.c_str()) + && song_file_name.find(".ogg") == song_file_name.size() - 4) + data.play_data.ogg = true; + + for (pv_game_chara& i : data.chara) + if (i.check_chara() && !task_rob_manager_check_chara_loaded(i.chara_id)) + return false; + + pv_game_music_get()->ogg_reset(); + + if (data.play_data.aix) { + pv_game_music_get()->include_flags(PV_GAME_MUSIC_AIX); + pv_game_music_get()->load(2, get_play_data_song_file_name(), 1, sub_1400FCEB0(), false); + } + else { + pv_game_music_get()->include_flags(PV_GAME_MUSIC_OGG); + pv_game_music_get()->load(4, get_play_data_song_file_name(), 1, sub_1400FCEB0(), false); + } + + std::string effect_se_file_name = get_effect_se_file_name(); + if (effect_se_file_name.size()) + sound_work_read_farc(effect_se_file_name.c_str()); + + if (data.play_data.slidertouch_name.size()) { + char buf[0x200]; + sprintf_s(buf, sizeof(buf), "rom/sound/%s.farc", data.play_data.slidertouch_name.c_str()); + sound_work_read_farc(buf); + } + + if (ex_song_index >= 0 && ex_song_index < get_pv_db_pv()->ex_song.data.size()) + for (const pv_db_pv_ex_song_ex_auth& i : get_pv_db_pv()->ex_song.data[ex_song_index].ex_auth) { + int32_t org_uid = aft_auth_3d_db->get_uid(i.org_name.c_str()); + int32_t uid = aft_auth_3d_db->get_uid(i.name.c_str()); + + for (pv_game_field& j : data.field_data) + for (int32_t& k : j.auth_3d_uids) + if (k == org_uid) { + k = uid; + break; + } + + for (pv_game_field& j : data.field_data) + for (auth_3d_id& k : j.auth_3d_ids) + if (k.get_uid() == org_uid) { + auto elem = data.auth_3d.find(uid); + if (elem != data.auth_3d.end()) { + k = elem->second; + break; + } + } + + for (pv_game_field& j : data.field_data) { + auto elem = j.auth_3d_frame_list.find(org_uid); + if (elem != j.auth_3d_frame_list.end()) { + j.auth_3d_frame_list.insert({ uid, elem->second }); + j.auth_3d_frame_list.erase(elem); + } + } + } + state = 13; + } break; + case 13: { + if (pv_osage_manager_array_get_disp() || osage_play_data_manager_check_task_ready()) + return false; + + std::string effect_se_file_name = get_effect_se_file_name(); + if (effect_se_file_name.size()) + if (sound_work_load_farc(effect_se_file_name.c_str())) + return false; + + if (data.play_data.slidertouch_name.size()) { + char buf[0x200]; + sprintf_s(buf, sizeof(buf), "rom/sound/%s.farc", data.play_data.slidertouch_name.c_str()); + if (sound_work_load_farc(buf)) + return false; + } + + set_chara_use_opd(true); + task_rob_manager_run_task(); + + for (pv_game_chara& i : data.chara) + if (i.check_chara()) { + i.rob_chr->set_hand_l_mottbl_motion(0, 194, 1.0f, 0, 0.0f, 0.0f, 1.0f, -1, 0.0f, aft_mot_db); + i.rob_chr->set_hand_r_mottbl_motion(0, 194, 1.0f, 0, 0.0f, 0.0f, 1.0f, -1, 0.0f, aft_mot_db); + } + + const pv_db_pv_difficulty* diff = get_pv_db_pv()->get_difficulty( + sub_14013C8C0()->difficulty, sub_14013C8C0()->edition); + if (diff && !diff->effect_se_file_name.size()) + for (const std::string& i : diff->effect_se_name_list) + wave_audio_storage_load_wave_audio(i); + + if (Glitter::glt_particle_manager) + for (uint64_t& i : data.effect_rs_list_hashes) + if (Glitter::glt_particle_manager->GetEffectsCount(i) + && !Glitter::glt_particle_manager->CheckNoFileReaders(i)) + return false; + state = 14; + } break; + case 14: { + //sub_14013C8F0()->sub_14012BDA0(); + state = sub_14013C8C0()->sub_1400E7910() >= 4 ? 17 :15; + } break; + case 15: { + state = 16; + } break; + case 16: { + state = 17; + } break; + case 17: { + data.life_gauge = 127; + data.life_gauge_final = 127; + data.play_data.state = 0; + state = 18; + } break; + case 18: { + if (!data.play_data.load_auth_2d(data.stage_index, data.pv_disp2d)) + return false; + + state = sub_14013C8C0()->sub_1400E7910() >= 4 ? 21 : 19; + } return false; + case 19: { + state = sub_14013C8C0()->sub_1400E7910() != 3 ? 21 : 20; + } break; + case 20: { + state = 21; + } return false; + case 21: { + if (sub_14013C8C0()->sub_1400E7910() < 4) { + data.reference_score = calculate_reference_score(); + calculate_song_energy(); + /*if (!sub_14013C8C0()->sub_1400E7920()) + sub_14013C8F0()->sub_14012AE60();*/ + } + + rctx_ptr->camera->reset(); + + data.score_final = 0; + data.challenge_time_total_bonus = 0; + data.combo = 0; + data.challenge_time_combo_count = 0; + data.max_combo = 0; + data.current_reference_score = 0; + data.target_count = 0; + data.field_2CF84 = 0; + data.field_2CF88 = 0; + data.score_slide_chain_bonus = 0; + data.slide_chain_length = 0; + data.field_2CF98 = 0; + data.field_2D0BC = false; + + for (int32_t& i : data.total_hit_count) + i = 0; + + for (int32_t& i : data.hit_count) + i = 0; + + data.play_data.field_5F4 = 1.0f; + + memset(data.play_data.lyric, 0, sizeof(data.play_data.lyric)); + data.play_data.lyric_set = false; + data.play_data.field_64C = false; + + memset(data.field_2CE9C, 0, sizeof(data.field_2CE9C)); + data.field_2CF1C = 0; + data.field_2CF20 = false; + data.field_2CF30 = 4; + + field_1 = false; + field_2 = false; + end_pv = false; + + for (pv_game_chara& i : data.chara) + if (i.check_chara()) + i.rob_chr->set_visibility(true); + + field_4 = false; + if (sub_14013C8C0()->sub_1400E7910() == 3) + data.field_2CF8C = 30.0f; + data.field_2CF9C = 0; + data.field_2CFA0 = 0; + data.field_2CFA4 = 0; + sub_14013C8C0()->field_26 = false; + data.title_image_init = false; + data.field_index = 1; + data.edit_effect_index = 0; + data.slidertouch_counter = 0; + data.change_field_branch_success_counter = 10; + if (data.pv_data.field_0) { + if (sub_14013C8C0()->sub_1400E7910() < 4) + data.pv_data.get_target_target_count(0, 0.0f, true); + } + rctx_ptr->disp_manager.object_culling = false; + state = 22; + } break; + case 22: { + if (data.field_index >= data.field_data.size() + && data.edit_effect_index >= data.edit_effect.aet_ids.size() + && data.slidertouch_counter >= 32 + && data.change_field_branch_success_counter <= 0 + && data.title_image_init) { + if (data.pv->pre_play_script) { + data.change_field_branch_success_counter = 0; + state = 23; + } + else + state = 25; + break; + } + + float_t view_point_xz_pos_angle = + (float_t)(36 * get_frame_counter() % 360) * DEG_TO_RAD_FLOAT; + vec3 view_point; + view_point.x = sinf(view_point_xz_pos_angle) * 40.0f; + view_point.y = 0.0f; + view_point.z = cosf(view_point_xz_pos_angle) * 40.0f; + rctx_ptr->camera->set_view_point(view_point); + rctx_ptr->camera->set_interest({ 0.0f, 0.0f, 0.0f }); + + data.change_field_branch_success_counter--; + if (data.field_index < data.field_data.size()) + change_field(data.field_index, -1, -1); + + while (data.field_index < data.field_data.size()) { + int32_t stage_index = data.field_data[data.field_index].stage_index; + if (++data.field_index >= data.field_data.size()) + break; + else if (stage_index != data.field_data[data.field_index].stage_index) + break; + } + + if (data.edit_effect_index < data.edit_effect.aet_ids.size()) { + edit_effect_set(data.edit_effect_index, 1.0f, (float_t)(1.0 / 60.0)); + data.edit_effect_index++; + } + + if (!data.title_image_init) { + data.title_image_init = true; + title_image_ctrl(true); + } + + if (data.slidertouch_counter < 32) { + if (data.play_data.slidertouch_name.size()) { + char buf[0x200]; + std::string name(buf, sprintf_s(buf, sizeof(buf), "%s_%02d", + data.play_data.slidertouch_name.c_str(), data.slidertouch_counter + 1)); + wave_audio_storage_load_wave_audio(name); + } + else { + data.slidertouch_counter += 32; + } + data.slidertouch_counter++; + } + } break; + case 23: { + if (data.change_field_branch_success_counter >= data.pv_data.change_field_branch_success.size()) { + state = 24; + break; + } + + int32_t curr_time = data.pv_data.change_field_branch_success + [data.change_field_branch_success_counter].first; + if (data.change_field_branch_success_counter > 0) { + int32_t prev_time = data.pv_data.change_field_branch_success + [data.change_field_branch_success_counter - 1LL].first; + if (curr_time > prev_time) + for (int64_t i = 60LL * ((int64_t)curr_time - prev_time) / 100000; i; i--) + Glitter::glt_particle_manager->CtrlScenes(); + } + data.pv_data.ctrl((float_t)(1.0 / 60.0), 10000LL * curr_time, false); + data.change_field_branch_success_counter++; + } break; + case 24: { + data.reset(); + data.play_data.sub_140137BE0(); + set_lyric(-1, { 0xFF, 0xFF, 0xFF, 0xFF }); + + for (pv_game_chara& i : data.chara) { + if (!i.check_chara()) + continue; + + rob_chara* rob_chr = i.rob_chr; + 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); + } + rob_chr->set_hand_l_mottbl_motion(0, 194, 1.0f, 0, 0.0f, 0.0f, 1.0f, -1, 0.0f, aft_mot_db); + rob_chr->set_hand_r_mottbl_motion(0, 194, 1.0f, 0, 0.0f, 0.0f, 1.0f, -1, 0.0f, aft_mot_db); + } + + for (int32_t& i : data.campv_auth_3d_uids) { + const char* name = auth_3d_data_get_uid_name(i, aft_auth_3d_db); + if (!name || !check_chrcam(name, i)) + continue; + + auto elem = data.auth_3d.find(i); + if (elem != data.auth_3d.end()) + elem->second.set_enable(false); + } + + itmpv_reset(); + sub_140113730(); + data.current_field = 0; + + for (pv_game_field& i : data.field_data) { + for (int32_t& j : i.auth_3d_uids) { + auth_3d_id id = get_auth_3d_id(j); + id.set_enable(false); + id.set_visibility(false); + id.set_paused(false); + id.set_req_frame(0.0f); + } + + if (i.light_auth_3d_id.check_not_empty()) { + i.light_auth_3d_id.set_enable(false); + i.light_auth_3d_id.set_visibility(false); + i.light_auth_3d_id.set_paused(false); + i.light_auth_3d_id.set_req_frame(0.0f); + } + } + + pv_expression_array_reset(); + state = 25; + } break; + case 25: { + //sub_14013C8F0->sub_14012BDA0(); + rand_state_array_4_set_seed_1393939(); + reset_field(); + data.edit_effect.data.reset(); + data.play_data.init_aet_edit_effect(-1, "eff", false, false); + data.play_data.free_aet_title_image(); + data.title_image_state = 0; + Glitter::glt_particle_manager->counter = 0; + rctx_ptr->disp_manager.object_culling = true; + loaded = true; + state = false; + //sel_vocal_change_get()->DelTask(); + rctx_ptr->render_manager.set_effect_texture(0); + pv_param_task::post_process_task_add_task(); + } return true; + } + return false; +} + +void pv_game::play_se(int32_t index) { + const pv_db_pv_difficulty* diff = data.pv->get_difficulty(sub_14013C8C0()->difficulty, sub_14013C8C0()->edition); + if (diff && diff->effect_se_file_name.size() + && index > 0 && index < diff->effect_se_name_list.size() + && diff->effect_se_name_list[index].size()) { + sound_work_play_se(1, diff->effect_se_name_list[index].c_str(), 1.0f); + data.se_index = index; + } +} + +void pv_game::reset() { + loaded = false; + field_1 = false; + field_2 = false; + end_pv = false; + field_4 = false; + field_14 = false; + + data.play_data.field_5F4 = 1.0f; + + memset(data.play_data.lyric, 0, sizeof(data.play_data.lyric)); + data.play_data.lyric_set = false; + data.play_data.lyrics_color = { 0xFF, 0xFF, 0xFF, 0xFF }; + + memset(data.field_2CE9C, 0, sizeof(data.field_2CE9C)); + data.field_2CF1C = 0; + data.field_2CF20 = false; + data.field_2CF8C = 0.0f; + data.field_2CF9C = 0; + data.field_2CFA0 = 0; + data.field_2CFA4 = 0; + + data.play_data.field_3B0 = -1; + data.play_data.field_3B4 = -1; + data.play_data.field_3B8 = -1; + data.play_data.field_3BC = -1; + + pv_id = -1; + + data.field_2CFB0 = 0; + data.chance_point = 0; + + for (pv_game_chara& i : data.chara) { + i.chara_index = CHARA_MAX; + i.cos = -1; + i.chara_id = -1; + i.pv_data = {}; + i.rob_chr = 0; + i.motion_ids.clear(); + i.motion_face_ids.clear(); + } + + data.motion_set_ids.clear(); + data.motion_set_face_ids.clear(); + + data.obj_set_itmpv.clear(); + data.obj_set_handitem.clear(); + data.chreff_auth_3d_obj_set_ids.clear(); + data.field_2D770.clear(); + data.stgpvhrc_obj_set_ids.clear(); + data.ex_song_ex_auth_obj_set_ids.clear(); + + data.stage_indices.clear(); + data.stage_infos.clear(); + + data.field_2D7E8 = false; + data.spr_set_back_ids.clear(); + + data.field_2D808 = -1; + + data.edit_effect.reset(); + + data.current_field = 0; + data.field_data.clear(); + + data.field_2D8A0 = true; + + data.camera_auth_3d_uid = -1; + data.campv_string.clear(); + data.campv_auth_3d_uids.clear(); + data.campv_index = 0; + data.campv.clear(); + + data.itmpv_string.clear(); + data.itmpv_auth_3d_uids.clear(); + for (auto& i : data.itmpv) + i.clear(); + data.itmpv_uids.clear(); + + for (auto& i : data.field_2DA08) { + i.data.clear(); + i.auth_3d_ids.clear(); + i.field_30 = -1; + } + + data.auth_3d.clear(); + data.field_2DAC8 = false; + data.auth_3d_categories.clear(); + data.loaded_auth_3d_uids.clear(); + + data.auth_3d_time.clear(); + data.light_time.clear(); + + for (auto& i : data.aet_time) + i.clear(); + + data.chreff_auth_3d.clear(); + data.chreff_auth_3d_obj.clear(); + + data.reference_score = 0; + data.reference_score_no_flag = 0; + data.reference_score_no_flag_life_bonus = 0; + data.target_reference_score.clear(); + data.field_2CFE0 = 0; + data.field_2D092 = data.field_2D00E; + data.notes_passed = 0; + data.field_2CFF0 = 0; + data.song_energy = 0.0f; + data.song_energy_border = 0.0f; + data.max_time_float = 0.0f; + data.current_time_float = 0.0f; + data.max_time = 0; + data.current_time = 0; + data.field_2D038 = 0.0f; + data.field_2D03C = 0.0f; + data.score_hold_multi = 0; + data.score_hold = 0; + data.score_slide = 0; + data.has_slide = false; + data.has_success_se = false; + data.pv_disp2d = 0; + data.hit_border = false; + data.field_2D05D = false; + data.start_fade = true; + data.title_image_init = false; + data.field_index = 0; + data.edit_effect_index = -1; + data.slidertouch_counter = 0; + data.change_field_branch_success_counter = 0; + data.field_2D05E = false; + data.field_2D080 = 0; + data.field_2D084 = 0; + data.life_gauge_bonus = 0; + data.life_gauge_total_bonus = 0; + data.field_2D090 = 0; + data.no_clear = true; + data.field_2D093 = false; + data.field_2D094 = false; + data.field_2D095 = false; + data.field_2D096 = false; + data.use_osage_play_data = false; + data.pv_end_fadeout = false; + data.title_image_state = 0; + data.field_2D09C = 0; + data.rival_percentage = 0.0f; + data.play_data.se_name.clear(); + data.play_data.pvbranch_success_se_name.clear(); + data.play_data.slide_name.clear(); + data.play_data.chainslide_first_name.clear(); + data.play_data.chainslide_sub_name.clear(); + data.play_data.chainslide_success_name.clear(); + data.play_data.chainslide_failure_name.clear(); + data.play_data.slidertouch_name.clear(); + data.play_data.song_file_name.clear(); + data.play_data.ex_song_index = -1; + data.height_adjust = false; + data.field_2DB2C = 0; + data.play_data.aix = false; + data.play_data.ogg = false; + data.play_data.field_64C = false; + data.field_2CF30 = 4; + data.field_2CF34 = 0; + data.play_data.field_650 = 43; + data.play_data.field_654 = 0.0f; + data.field_2CF24 = 3; + data.field_2CF28 = 0.0f; + data.field_2CF38 = 0; + data.play_data.field_658 = 0; + data.play_data.field_65C = 0.0f; + data.field_2CF2C = 0.0f; + data.target_count = 0; + data.field_2CF84 = 0; + data.current_reference_score = 0; + data.combo = 0; + data.challenge_time_combo_count = 0; + data.life_gauge = 127; + data.score_final = 0; + data.life_gauge_final = 127; + data.max_combo = 0; + data.challenge_time_total_bonus = 0; + data.field_2CF88 = 0; + data.pv = 0; + data.score_slide_chain_bonus = 0; + data.slide_chain_length = 0; + data.field_2D0BC = false; + data.next_stage = false; + data.has_frame_texture = false; + data.field_2D0C0 = -1; + + data.field_2CE98 = 0; + + for (int32_t& i : data.total_hit_count) + i = 0; + + for (int32_t& i : data.hit_count) + i = 0; + + data.changed_field = 0; + + data.has_auth_3d_frame = false; + data.has_light_frame = false; + + for (bool& i : data.has_aet_frame) + i = false; + + for (bool& i : data.has_aet_list) + i = false; + + data.success = data.field_2D063; + data.field_2CE98 = 0; + data.se_index = -1; + data.field_2DB34 = 0; + data.field_2D0A8 = 0; + data.field_2D0AC = 0; + data.field_2D0B0[0] = 0; + data.field_2D0B0[1] = 0; + data.field_2D0B0[2] = 0; + + data.effect_rs_list.clear(); + data.effect_rs_list_hashes.clear(); + + data.task_effect_init = false; +} + +void pv_game::reset_field() { + task_stage_info().set_stage(); + + if (data.current_field) { + pv_game_field& curr_field_data = data.field_data[data.current_field]; + + for (auth_3d_id& i : curr_field_data.auth_3d_ids) + i.set_enable(false); + + if (curr_field_data.light_auth_3d_id.check_not_empty()) + curr_field_data.light_auth_3d_id.set_enable(false); + + data.current_field = 0; + } + + data.play_data.unload_aet(); + data.play_data.set_spr_set_back_id(-1); + + data.auth_3d_time.clear(); + data.light_time.clear(); + + for (auto& i : data.aet_time) + i.clear(); + + Glitter::glt_particle_manager->FreeScenes(); +} + +void pv_game::set_chara_use_opd(bool value) { + if (!data.use_osage_play_data) + return; + + for (pv_game_chara& i : data.chara) + if (i.chara_id != -1 && i.rob_chr) + i.rob_chr->set_use_opd(value); +} + +void pv_game::set_data_campv(int32_t type, int32_t index, float_t frame) { + auto elem = data.campv.find(index); + if (elem == data.campv.end()) + return; + + int32_t campv_index = data.campv_index; + if (campv_index) { + auto elem = data.campv.find(campv_index); + if (elem != data.campv.end()) + elem->second.set_enable(false); + } + data.campv_index = index; + + auth_3d_id& id = elem->second; + id.set_enable(true); + data.camera_auth_3d_uid = id.get_uid(); + if (type == 0 || type == 1) { + id.set_req_frame(frame); + id.set_paused(false); + } +} + +void pv_game::set_data_itmpv(int32_t chara_id, int32_t index, bool enable, int64_t time) { + auto elem = data.itmpv[chara_id].find(index); + if (elem == data.itmpv[chara_id].end()) + return; + + auth_3d_id& id = elem->second.first; + if (enable) { + id.set_enable(true); + id.set_paused(false); + id.set_req_frame(0.0f); + elem->second.second = time; + } + else { + id.set_enable(false); + elem->second.second = -1; + } +} + +void pv_game::set_data_itmpv_chara_id(int32_t chara_id, int32_t index, bool attach) { + auto elem = data.itmpv[chara_id].find(index); + if (elem != data.itmpv[chara_id].end()) + elem->second.first.set_chara_id(attach ? chara_id : -1); +} + +void pv_game::set_data_itmpv_req_frame(int32_t chara_id, int32_t index, float_t value) { + auto elem = data.itmpv[chara_id].find(index); + if (elem != data.itmpv[chara_id].end()) + elem->second.first.set_req_frame(value); +} + +void pv_game::set_data_itmpv_max_frame(int32_t chara_id, float_t value) { + for (auto& i : data.itmpv[chara_id]) + i.second.first.set_max_frame(value); +} + +void pv_game::set_data_itmpv_max_frame(int32_t chara_id, int32_t index, float_t value) { + auto elem = data.itmpv[chara_id].find(index); + if (elem != data.itmpv[chara_id].end()) + elem->second.first.set_max_frame(value); +} + +void pv_game::set_data_itmpv_visibility(int32_t chara_id, bool value) { + for (auto& i : data.itmpv[chara_id]) + i.second.first.set_visibility(value); +} + +void pv_game::set_data_itmpv_visibility(int32_t chara_id, int32_t index, bool value) { + auto elem = data.itmpv[chara_id].find(index); + if (elem != data.itmpv[chara_id].end()) + elem->second.first.set_visibility(value); +} + +void pv_game::set_eyes_adjust(pv_game_chara* chr) { + chr->pv_data.eyes_adjust.xrot_adjust = data.pv->eyes_xrot_adjust; + if (data.pv->eyes_base_adjust_type != EYES_BASE_ADJUST_NONE) + chr->pv_data.eyes_adjust.base_adjust = data.pv->eyes_base_adjust_type; + + auto elem = data.pv->eyes_rot_rate.find(chr->chara_index); + if (elem != data.pv->eyes_rot_rate.end()) { + chr->pv_data.eyes_adjust.neg = elem->second.xn_rate; + chr->pv_data.eyes_adjust.pos = elem->second.xp_rate; + } +} + +void pv_game::set_item(size_t performer, rob_chara_pv_data_item& value) { + items[performer] = value; +} + +void pv_game::set_item_mask(size_t performer, size_t item, bool value) { + items_mask[performer].arr[item] = value; +} + +void pv_game::set_lyric(int32_t lyric_index, vec4u8 lyric_color) { + memset(data.play_data.lyric, 0, sizeof(data.play_data.lyric)); + data.play_data.lyric_set = false; + + data.play_data.lyrics_color = sub_14013C8C0()->sub_1400E7910() < 4 + ? lyric_color : vec4u8(0xFF, 0xFF, 0xFF, 0xFF); + + if (lyric_index < 0) + return; + + const pv_db_pv_lyric* lyric = 0; + for (const pv_db_pv_lyric& i : data.pv->lyric) + if (i.index == lyric_index) { + lyric = &i; + break; + } + data.play_data.lyric_set = !!lyric; + + if (lyric) + strcpy_s(data.play_data.lyric, sizeof(data.play_data.lyric), lyric->data.c_str()); +} + +void pv_game::set_module(size_t performer, int32_t module) { + modules[performer] = module; +} + +void pv_game::set_osage_init(const pv_game_chara& chr) { + data_struct* aft_data = &data_list[DATA_AFT]; + motion_database* aft_mot_db = &aft_data->data_ft.mot_db; + + const pv_db_pv* pv = data.pv; + + std::vector vec; + vec.push_back(osage_init_data(chr.rob_chr)); + + for (const uint32_t& i : chr.motion_ids) { + osage_init_data osage_init; + osage_init.rob_chr = chr.rob_chr; + osage_init.pv_id = pv->id; + osage_init.motion_id = i; + osage_init.frame = -1; + vec.push_back(osage_init); + } + + const std::vector* set_motion = data.pv_data.get_set_motion(chr.chara_id); + if (set_motion) + for (const pv_data_set_motion& i : *set_motion) { + float_t frame = i.frame_stage_index.first; + if (frame > 0.0f) + frame = (float_t)(int32_t)(frame + 0.5f); + else if (frame < 0.0f) + frame = (float_t)(int32_t)(frame - 0.5f); + + osage_init_data osage_init; + osage_init.rob_chr = chr.rob_chr; + osage_init.pv_id = pv->id; + osage_init.motion_id = i.motion_id; + osage_init.frame = (int32_t)frame; + vec.push_back(osage_init); + } + + for (const pv_db_pv_osage_init& i : pv->osage_init) { + int32_t motion_id = aft_mot_db->get_motion_id(i.motion.c_str()); + if (motion_id == -1) + continue; + + osage_init_data osage_init; + osage_init.rob_chr = chr.rob_chr; + osage_init.pv_id = pv->id; + osage_init.motion_id = motion_id; + osage_init.path.assign(pv->mdata.dir); + osage_init.frame = i.frame; + vec.push_back(osage_init); + } + + skin_param_manager_add_task(chr.chara_id, vec); +} + +bool pv_game::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; +} + +void pv_game::set_pv_param_post_process_chara_alpha_data(int32_t chara_id, + float_t alpha, int32_t type, float_t duration) { + 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); +} + +void pv_game::set_pv_param_post_process_chara_item_alpha_data(int32_t chara_id, + float_t alpha, int32_t type, float_t duration) { + 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, + pv_game::chara_item_alpha_callback, this); +} + +bool pv_game::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 pv_game::set_pv_param_post_process_dof_data(bool set, int32_t id, float_t duration) { + 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); + return true; +} + +void pv_game::title_image_ctrl(bool dont_wait) { + const pv_db_pv* pv = data.pv; + if (!pv) + return; + + const pv_db_pv_difficulty* diff = pv->get_difficulty(sub_14013C8C0()->difficulty, sub_14013C8C0()->edition); + if (!diff) + return; + + int32_t& state = data.title_image_state; + switch (data.title_image_state) { + case 0: + if (sub_14013C8C0()->sub_1400E7910() == 3 || diff->title_image.time == -1.0) { + state = 3; + break; + } + + if (dont_wait) { + if (diff->title_image.aet_name.size()) + data.play_data.init_aet_title_image(diff->title_image.aet_name.c_str()); + state = 3; + break; + } + case 1: + if (data.current_time_float - diff->title_image.time < 0.0f) + break; + + if (diff->title_image.aet_name.size()) { + state = 3; + break; + } + + data.play_data.init_aet_title_image(diff->title_image.aet_name.c_str()); + if (diff->title_image.end_time >= 0.0) + state = 2; + break; + case 2: + if (diff->title_image.end_time <= data.current_time_float) { + data.play_data.free_aet_title_image(); + state = 3; + } + break; + } +} + +bool pv_game::unload() { + data_struct* aft_data = &data_list[DATA_AFT]; + aet_database* aft_aet_db = &aft_data->data_ft.aet_db; + sprite_database* aft_spr_db = &aft_data->data_ft.spr_db; + texture_database* aft_tex_db = &aft_data->data_ft.tex_db; + + switch (data.field_2D09C) { + case 0: { + pv_game_music_get()->stop(); + + /*for (int32_t i = 0; i < 2; i++) + if (app::TaskWork::CheckTaskReady(task_movie_get())) + sub_14041F4E0(task_movie_get());*/ + + std::string effect_se_file_name = get_effect_se_file_name(); + if (effect_se_file_name.size()) + sound_work_unload_farc(effect_se_file_name.data()); + + if (data.play_data.slidertouch_name.size()) { + char buf[0x200]; + sprintf_s(buf, sizeof(buf), "rom/sound/%s.farc", data.play_data.slidertouch_name.c_str()); + sound_work_unload_farc(buf); + } + + wave_audio_storage_clear(); + + if (data.play_data.aix) + pv_game_music_get()->exclude_flags(PV_GAME_MUSIC_AIX); + + pv_game_music_get()->set_channel_pair_volume_map(0, 100); + pv_game_music_get()->set_channel_pair_volume_map(1, 100); + + data.field_2CF30 = 4; + + post_process& pp = rctx_ptr->post_process; + int32_t frame_texture_slot = 0; + for (const pv_db_pv_frame_texture& i : data.pv->frame_texture) { + if (i.data.size()) { + texture* tex = texture_storage_get_texture(aft_tex_db->get_texture_id(i.data.c_str())); + if (tex) + pp.frame_texture_unload(frame_texture_slot, tex); + } + frame_texture_slot++; + } + + if (data.has_frame_texture) { + rctx_ptr->post_process.frame_texture_free(); + data.has_frame_texture = false; + } + + data.pv_data.reset(); + + if (data.play_data.ogg) + pv_game_music_get()->exclude_flags(PV_GAME_MUSIC_OGG); + + data.field_2D09C = 1; + } + case 1: + pv_osage_manager_array_set_not_reset_true(); + if (pv_osage_manager_array_get_disp()) + return false; + + data.field_2D09C = 2; + break; + } + + for (pv_game_chara& i : data.chara) { + if (i.chara_id != -1 && i.rob_chr) { + skin_param_manager_reset(i.chara_id); + rob_chara_array_free_chara_id(i.chara_id); + } + + i.chara_index = CHARA_MAX; + i.cos = -1; + i.chara_id = -1; + i.pv_data = {}; + i.rob_chr = 0; + i.motion_ids.clear(); + i.motion_face_ids.clear(); + } + + osage_play_data_manager_reset(); + + for (uint32_t& i: data.motion_set_ids) { + motion_set_unload_motion(i); + motion_set_unload_mothead(i); + } + data.motion_set_ids.clear(); + + for (uint32_t& i : data.motion_set_face_ids) + motion_set_unload_motion(i); + data.motion_set_face_ids.clear(); + + pv_expression_file_unload(data.pv->pv_expression_file_name.c_str()); + + data.stage_indices.clear(); + data.stage_infos.clear(); + + task_stage_unload_task(); + + if (data.field_2D7E8) + for (uint32_t& i : data.spr_set_back_ids) + sprite_manager_unload_set(i, aft_spr_db); + + data.field_2D7E8 = false; + data.spr_set_back_ids.clear(); + + data.current_field = 0; + data.field_data.clear(); + + data.field_2D8A0 = true; + + for (auto& i : data.auth_3d) + i.second.unload_id(rctx_ptr); + + for (auto& i : data.field_2DA08) + for (auto& j : i.auth_3d_ids) + j.unload_id(rctx_ptr); + + if (data.field_2DAC8) + for (std::string& i : data.auth_3d_categories) + auth_3d_data_unload_category(i.c_str()); + + data.camera_auth_3d_uid = -1; + data.campv_string.clear(); + data.campv_auth_3d_uids.clear(); + data.campv_index = 0; + data.campv.clear(); + + data.itmpv_string.clear(); + data.itmpv_auth_3d_uids.clear(); + for (auto& i : data.itmpv) + i.clear(); + data.itmpv_uids.clear(); + + for (auto& i : data.field_2DA08) { + i.data.clear(); + i.auth_3d_ids.clear(); + i.field_30 = -1; + } + + data.auth_3d.clear(); + data.field_2DAC8 = false; + data.auth_3d_categories.clear(); + data.loaded_auth_3d_uids.clear(); + + data.auth_3d_time.clear(); + data.light_time.clear(); + + for (auto& i : data.aet_time) + i.clear(); + + data.chreff_auth_3d.clear(); + data.chreff_auth_3d_obj.clear(); + + data.edit_effect.unload(); + + pv_param::light_data_clear_data(); + pv_param::post_process_data_clear_data(); + + for (uint32_t& i : data.obj_set_itmpv) + object_storage_unload_set(i); + data.obj_set_itmpv.clear(); + + for (uint32_t& i : data.obj_set_handitem) + object_storage_unload_set(i); + data.obj_set_handitem.clear(); + + skin_param_storage_reset(); + + for (uint32_t& i : data.chreff_auth_3d_obj_set_ids) + object_storage_unload_set(i); + data.chreff_auth_3d_obj_set_ids.clear(); + + for (uint32_t& i : data.field_2D770) + object_storage_unload_set(i); + data.field_2D770.clear(); + + for (uint32_t& i : data.stgpvhrc_obj_set_ids) + object_storage_unload_set(i); + data.stgpvhrc_obj_set_ids.clear(); + + for (uint32_t& i : data.ex_song_ex_auth_obj_set_ids) + object_storage_unload_set(i); + data.ex_song_ex_auth_obj_set_ids.clear(); + + for (uint64_t& i : data.effect_rs_list_hashes) + Glitter::glt_particle_manager->UnloadEffectGroup(i); + data.effect_rs_list.clear(); + data.effect_rs_list_hashes.clear(); + + /*for (int32_t i = 0; i < 2; i++) { + if (!app::TaskWork::CheckTaskReady(task_movie_get(i))) + continue; + + task_movie_get(i)->sub_14041F4E0(); + task_movie->DelTask(); + }*/ + + data.title_image_state = 0; + + //stage_param_data_coli_data_clear(); + + data.play_data.field_3B0 = -1; + data.play_data.field_3B4 = -1; + data.play_data.field_3B8 = -1; + data.play_data.field_3BC = -1; + + //sub_14013C8F0()->sub_14012BDA0(); + + data.play_data.unload(); + + data.play_data.field_64C = false; + + field_1 = false; + field_2 = false; + end_pv = false; + + sub_14013C8C0()->field_26 = false; + + struc_14* v85 = sub_14013C8C0(); + v85->field_14 = 0; + v85->field_18 = 0; + v85->field_1C = 0; + v85->field_20 = 1.0f; + + sub_14013C8C0()->field_24 = false; + sub_14013C8C0()->field_25 = false; + + loaded = false; + + data.target_reference_score.clear(); + data.notes_passed = 0; + data.field_2CFF0 = 0; + data.field_2CFE0 = 0; + data.field_2D0C0 = -1; + + light_param_data_storage_data_reset(); + + post_process& pp = rctx_ptr->post_process; + pp.tone_map->set_saturate_coeff(1.0f); + pp.dof->set_dof_pv(); + pp.tone_map->set_scene_fade(0.0f); + + /*if (!sub_140192E20()) + post_process_set_taa(&pp, 1);*/ + + //sub_1404A9480(&pp, 0, -1); + + rctx_ptr->disp_manager.object_culling = true; + rctx_ptr->render_manager.shadow_ptr->range = 1.0f; + rctx_ptr->render_manager.set_effect_texture(0); + + sound_work_reset_all_se(); + + pv_param_task::post_process_task_del_task(); + + data.current_time_float = 0.0f; + data.current_time = 0; + return true; +} + +void pv_game::sub_1400FCAD0(float_t delta_time) { + bool fade_end = data.play_data.fade_end_ctrl(); + data.play_data.sub_140138D60(); + data.play_data.sub_140138F30(); + + switch (data.field_2CF24) { + case 0: + if (data.start_fade) { + data.field_2CF24 = 1; + break; + } + + if (sub_14013C8C0()->sub_1400E7920()) { + data.field_2CF24 = 4; + data.field_2CF28 = 0.0f; + data.field_2CF2C = 0.0f; + } + else { + data.field_2CF24 = 3; + data.field_2CF28 = 0.0f; + data.field_2CF2C = 0.0f; + + if (!data.pv_data.field_2BFD5) + data.play_data.sub_140137F80(1, 0.0f); + } + break; + case 1: + if (!fade_end) + return; + + if (sub_14013C8C0()->sub_1400E7920()) { + data.field_2CF24 = 4; + data.field_2CF28 = 0.0f; + data.field_2CF2C = 0.0f; + } + else { + data.field_2CF24 = 2; + data.field_2CF28 = 0.0f; + data.field_2CF2C = 2.0f; + + if (!data.pv_data.field_2BFD5) + data.play_data.sub_140137F80(1, 2.0f); + } + break; + case 2: + data.field_2CF28 += delta_time; + if (data.field_2CF28 >= data.field_2CF2C) { + data.field_2CF24 = 3; + data.field_2CF28 = 0.0f; + data.field_2CF2C = 0.0f; + } + break; + case 3: + data.play_data.sub_1401385F0(delta_time); + data.play_data.score_update(data.score_final, false); + break; + } +} + +void pv_game::sub_1400FC500() { + if (data.field_2D095) { + if (data.hit_count[0] + data.hit_count[1] == data.target_count) + data.field_2CE98 = 5; + else if (data.song_energy >= get_percentage_clear_excellent()) + data.field_2CE98 = 4; + else if (data.song_energy >= get_percentage_clear_great()) + data.field_2CE98 = 3; + else if (data.song_energy > 40.0f || data.song_energy_base <= data.song_energy) + data.field_2CE98 = 2; + else + data.field_2CE98 = 1; + + if (!data.life_gauge && data.no_fail) + data.field_2CE98 = 0; + } + data.field_2CE98 = 0; + + /*if (!sub_14013C8C0()->sub_1400E7920() && sub_14013C8C0()->sub_1400E7910() != 6 + && (!data.field_2CE98 || data.song_energy_base > data.song_energy) + && !data.no_fail && sub_14019C750() && sub_14038BB30()->field_0.stage_index < sub_14038AEE0() - 1) + data.next_stage = true;*/ +} + +int32_t pv_game::sub_1400FC780(float_t delta_time) { + data.play_data.field_65C += delta_time; + data.play_data.skin_danger_ctrl(); + + switch (data.play_data.field_650) { + case 0: + /*if (!this->data.pv_end_fadeout) + task_mask_screen_fade_out(0.75f, false);*/ + + data.play_data.field_650 = 1; + data.play_data.field_654 = 1.0f; + data.play_data.field_65C = 0.0; + return 0; + case 1: + if (data.play_data.field_654 * 0.95f > data.play_data.field_65C) + return 0; + + data.field_2D093 = true; + break; + case 6: + if (data.play_data.field_654 > data.play_data.field_65C) + return 0; + + data.play_data.field_650 = 34; + data.play_data.field_654 = 0.0f; + data.play_data.field_65C = 0.0f; + return 0; + case 27: + data.play_data.init_aet_next_info(); + + data.play_data.field_650 = 28; + data.play_data.field_654 = 1.0f; + data.play_data.field_65C = 0.0f; + return 0; + case 28: + case 29: + if (data.pv_data.pv_end && !data.field_2D05E) { + data.field_2D05E = true; + //task_mask_screen_fade_out(0.75f, 0); + } + + rctx_ptr->post_process.tone_map->set_exposure(0.0f); + + if (data.play_data.get_aet_next_info_disp()) + return 0; + + data.field_2D093 = true; + if (data.field_2D05E) + break; + + data.field_2D05E = true; + //task_mask_screen_fade_out(0.0f, 0); + break; + case 31: + if (data.play_data.field_654 > data.play_data.field_65C) + return 0; + + data.play_data.field_650 = 32; + data.play_data.field_654 = 1.0f; + data.play_data.field_65C = 0.0f; + return 0; + case 41: + /*if (!data.pv_end_fadeout) + task_mask_screen_fade_out(1.0, 0);*/ + + data.play_data.field_650 = 42; + data.play_data.field_654 = 1.1f; + data.play_data.field_65C = 0.0f; + return 0; + case 42: + if (data.play_data.field_654 > data.play_data.field_65C) + return 0; + + data.field_2D093 = true; + if (sub_14013C8C0()->sub_1400E7910() == 3 && data.field_2CF8C > 0.0f) + return 3; + break; + } + return 1; +} + +float_t pv_game::sub_1400FCEB0() { + return max_def(data.play_data.field_5EC, 0.0f); +} + +int32_t pv_game::sub_1400FDD80() { + if (data.target_reference_score.size()) + return (int32_t)(data.target_reference_score.size() - data.field_2CFE0 - 1); + return 0; +} + +void pv_game::sub_140104FB0() { + data.se_index = -1; + data.success = data.field_2D063; + data.field_2CE98 = 0; + data.field_2DB34 = 0; + data.field_2D0A8 = 0; + data.field_2D0AC = 0; + + for (int32_t& i : data.field_2D0B0) + i = 0; +} + +void pv_game::sub_140106640() { + pv_game_time_ctrl(); + + pv_game_music_get()->stop(); + pv_game_music_get()->set_volume_map(0, 0); + + if (data.play_data.aix) { + pv_game_music_get()->include_flags(PV_GAME_MUSIC_AIX); + pv_game_music_get()->load(2, get_play_data_song_file_name(), true, sub_1400FCEB0(), false); + } + else { + pv_game_music_get()->include_flags(PV_GAME_MUSIC_OGG); + pv_game_music_get()->load(4, get_play_data_song_file_name(), true, sub_1400FCEB0(), false); + } + + /*for (int32_t i = 0; i < 2; i++) { + if (!app::TaskWork::CheckTaskReady(task_movie_get(i))) + continue; + + task_movie_get(i)->sub_14041F4E0(); + std::string name = get_pv_movie_file_name(i); + if (name.size()) { + task_movie_get(i)->sub_14041F0A0(name); + while (!task_movie_get(i)->sub_14041F0E0(v14)); + } + }*/ + + sub_140104FB0(); + + //sub_14013C8F0()->sub_14012BDA0(); + + data.field_2D092 = data.field_2D00E; + + data.play_data.sub_140137BE0(); + set_lyric(-1, { 0xFF, 0xFF, 0xFF, 0xFF }); + data.reset(); + data.title_image_state = 0; + sub_140108320(); + + data.life_gauge = 127; + data.score_final = 0; + data.challenge_time_total_bonus = 0; + data.combo = 0; + data.challenge_time_combo_count = 0; + data.max_combo = 0; + data.current_reference_score = 0; + data.target_count = 0; + data.field_2CF84 = 0; + data.field_2CF88 = 0; + data.score_slide_chain_bonus = 0; + data.slide_chain_length = 0; + data.field_2CF98 = 0; + data.field_2D0BC = false; + data.next_stage = false; + data.has_frame_texture = false; + data.field_2D0C0 = -1; + + for (int32_t& i : data.total_hit_count) + i = 0; + + for (int32_t& i : data.hit_count) + i = 0; + + data.play_data.field_5F4 = 1.0f; + memset(data.play_data.lyric, 0, sizeof(data.play_data.lyric)); + data.play_data.lyric_set = false; + + data.field_2CF30 = 4; + field_1 = false; + field_2 = false; + end_pv = false; + field_4 = false; + data.field_2D03C = data.field_2D038; + data.field_2DB2C = 0; + + data_struct* aft_data = &data_list[DATA_AFT]; + auth_3d_database* aft_auth_3d_db = &aft_data->data_ft.auth_3d_db; + + for (int32_t& i : data.campv_auth_3d_uids) { + int32_t uid = i; + const char* name = auth_3d_data_get_uid_name(uid, aft_auth_3d_db); + if (!name) + continue; + + if (check_chrcam(name, uid)) { + auto elem = data.auth_3d.find(uid); + if (elem != data.auth_3d.end()) + elem->second.set_enable(false); + } + } + + itmpv_reset(); + sub_140113730(); + + data.edit_effect.data.reset(); + + data.field_2D093 = false; + data.field_2D095 = false; + data.field_2D096 = false; + + pv_expression_array_reset(); + + data.pv_end_fadeout = false; + + pv_game_time_get(); +} + +void pv_game::sub_140108320() { + data.field_2CF24 = 0; + data.field_2CF28 = 0.0f; + data.field_2CF2C = 0.0f; +} + +bool pv_game::sub_14010EF00() { + /*InputState* input_state = input_state_get(0); + if (!sub_1401E8380(ub_1401E8950() + 1)) + return false; + + bool v5 = task_slider_control_get()->sub_140618C20(38) + && input_state->sub_14018D480(10) && input_state->sub_14018D480(7); + switch (data.field_2DB34) { + case 0: + if (v5 && input_state->sub_14018D510(2)) { + data.field_2DB34 = 1; + data.field_2DB38.get_timestamp(); + data.field_2D0AC = sub_14010F930(); + } + break; + case 1: + if (!v5 || !input_state->sub_14018D480(2)) { + sub_14010F030(); + data.field_2DB34 = 0; + data.field_2D0AC = 0; + return false; + } + + if (data.field_2DB38.calc_time() > 0.1f) { + data.field_2D0AC = 0; + return true; + } + break; + }*/ + return false; +} + +void pv_game::sub_14010F030() { + if (data.field_2D0AC) + data.field_2D0B0[data.field_2D0AC]++; +} + +int32_t pv_game::sub_14010F930() { + if (sub_14013C8C0()->sub_1400E7920() || data.life_gauge <= 0 + || data.notes_passed != data.target_reference_score.size() - 1) + return 1; + return 2; +} + +int32_t pv_game::sub_140112C00(int32_t index) { + if (index > 0 && index <= 2) + return data.field_2D0B0[index]; + return 0; +} + +void pv_game::sub_140113730() { + for (struc_269& i : data.field_2DA08) + for (auth_3d_id& j : i.auth_3d_ids) + j.set_enable(false); +} + +void pv_game::sub_140115C10(int32_t chara_id, bool value) { + struc_269& v4 = data.field_2DA08[chara_id]; + int32_t v5 = v4.field_30; + if (v5 >= 0 && v4.auth_3d_ids.size()) { + auth_3d_id& id = v4.auth_3d_ids[v5]; + if (id.check_not_empty()) + id.set_visibility(value); + } +} + +void pv_game::sub_140115C90(int32_t chara_id, bool disp, int32_t index, float_t frame, float_t frame_speed) { + if (chara_id < 0 || chara_id >= 3) + return; + + struc_269& v19 = data.field_2DA08[chara_id]; + int32_t v11 = v19.field_30; + if (v11 >= 0) { + if (v11 >= v19.auth_3d_ids.size()) + return; + + auth_3d_id& id = v19.auth_3d_ids[v11]; + id.set_enable(false); + } + + if (index >= 0) { + if (index >= v19.auth_3d_ids.size()) + return; + + auth_3d_id& id = v19.auth_3d_ids[index]; + if (id.check_not_empty()) { + id.set_enable(true); + id.set_visibility(disp); + id.set_paused(false); + id.set_req_frame(frame); + id.set_chara_id(chara_id); + id.set_last_frame(id.get_play_control_size() - 1.0f); + + FrameRateControl* sys_frame_rate = sys_frame_rate_get(chara_id); + sys_frame_rate->SetFrameSpeed(frame_speed); + id.set_frame_rate(sys_frame_rate); + } + } + v19.field_30 = index; +} + +void pv_game::sub_1401230A0() { + data.challenge_time_total_bonus = 0; + data.challenge_time_combo_count = 0; + data.field_2CF84 = 0; + data.play_data.sub_140134730(); + sub_14013C8C0()->field_26 = true; +} + +void pv_game::chara_item_alpha_callback(void* data, int32_t chara_id, int32_t type, float_t alpha) { + if (!data || chara_id < 0 || chara_id >= ROB_CHARA_COUNT) + 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 (auto& i : ((pv_game*)data)->data.itmpv[chara_id]) + i.second.first.set_alpha_obj_flags(alpha, flags); +} + +void pv_game::get_item_mask(pv_performer_type type, + rob_chara_pv_data_item* src_item, pv_game_item_mask* src_mask, + rob_chara_pv_data_item* dst_item, pv_game_item_mask* dst_mask) { + if (!src_item || !src_mask || !dst_item || !dst_mask) + return; + + if (type == PV_PERFORMER_PSEUDO_SAME) { + *dst_item = *src_item; + *dst_mask = *src_mask; + } + else { + *dst_item = {}; + *dst_mask = {}; + } +} + +pv_game_init_data::pv_game_init_data() : pv_id(), difficulty(), edition(), score_percentage_clear(), +life_gauge_safety_time(), life_gauge_border(), stage_index(), modules(), items() { + +} + +void pv_game_init_data::reset() { + pv_id = 0; + difficulty = PV_DIFFICULTY_EASY; + edition = 0; + score_percentage_clear = 0; + life_gauge_safety_time = 0; + life_gauge_border = 0; + stage_index = 0; + + for (int32_t& i : modules) + i = 0; + + for (rob_chara_pv_data_item& i : items) + i = {}; + + for (pv_game_item_mask& i : items_mask) + i = {}; +} + +struc_14::struc_14() : edition(), pv(), field_10(), field_11(), field_12(), +field_13(), field_14(), field_18(), field_1C(), field_24(), field_25(), field_26() { + field_0 = 8; + difficulty = PV_DIFFICULTY_NORMAL; + field_20 = 1.0f; +} + +int32_t struc_14::sub_1400E7910() { + return field_0; +} + +bool struc_14::sub_1400E7920() { + return field_0 == 2 || field_0 == 3 || field_0 == 5 || field_0 == 7; +} + +void struc_14::sub_1400E79E0(int32_t a2) { + field_0 = a2; +} + +TaskPvGame::Args::Args() : init_data(), field_190(), field_191(), no_fail(), +field_193(), field_194(), field_195(), ex_stage(), field_197(), test_pv(), option() { + Reset(); +} + +TaskPvGame::Args::~Args() { + +} + +void TaskPvGame::Args::Clear() { + se_name.clear(); + slide_se_name.clear(); + chainslide_first_name.clear(); + chainslide_sub_name.clear(); + chainslide_success_name.clear(); + chainslide_failure_name.clear(); + slidertouch_name.clear(); +} + +void TaskPvGame::Args::Reset() { + init_data.reset(); + Clear(); + field_190 = false; + field_191 = true; + no_fail = false; + field_193 = true; + field_194 = false; + field_195 = false; + ex_stage = false; + field_197 = false; + test_pv = false; + option = 0; +} + +TaskPvGame::Data::Data() : field_0(), init_data(), field_190(), field_191(), no_fail(), +field_193(), field_194(), ex_stage(), field_196(), option() { + Reset(); +} + +TaskPvGame::Data::~Data() { + +} + +void TaskPvGame::Data::Clear() { + se_name.clear(); + slide_se_name.clear(); + chainslide_first_name.clear(); + chainslide_sub_name.clear(); + chainslide_success_name.clear(); + chainslide_failure_name.clear(); + slidertouch_name.clear(); +} + +void TaskPvGame::Data::Reset() { + field_0 = 1; + init_data.reset(); + Clear(); + field_190 = false; + field_191 = true; + no_fail = false; + field_193 = true; + field_194 = false; + ex_stage = false; + field_196 = false; + option = 0; +} + +TaskPvGame::TaskPvGame() { + +} + +TaskPvGame::~TaskPvGame() { + +} + +bool TaskPvGame::Init() { + Load(data); + //touch_util::touch_reaction_set_enable(false); + return true; +} + +bool TaskPvGame::Ctrl() { + return !pv_game_parent_ctrl(); +} + +bool TaskPvGame::Dest() { + if (!Unload()) + return false; + + //touch_util::touch_reaction_set_enable(true); + return true; +} + +void TaskPvGame::Disp() { + pv_game_parent_disp(); +} + +void TaskPvGame::Load(TaskPvGame::Data& data) { + pv_game_init(); + + pv_game_parent_data.update_func = pv_game_parent::ctrl; + pv_game_parent_data.state = 0; + pv_game_parent_data.playing = true; + pv_game_parent_data.state = 0; + pv_game_parent_data.field_28 = 0; + pv_game_time_data.curr_time = 0; + pv_game_time_data.last_stop_time.get_timestamp(); + pv_game_time_data.last_stop_time.get_timestamp(); + pv_game_time_data.add_last_stop_time = true; + pv_game_time_data.delta_time = 0; + pv_game_time_data.current_time.get_timestamp(); + pv_game_time_data.current_time.get_timestamp(); + pv_game_time_data.add_current_time = true; + + sub_14013C8C0()->sub_1400E79E0(data.field_0); + sub_14013C8C0()->pv = data.init_data.pv_id;; + sub_14013C8C0()->difficulty = data.init_data.difficulty; + sub_14013C8C0()->edition = data.init_data.edition; + + for (int32_t i = 0; i < ROB_CHARA_COUNT; i++) { + pv_game_ptr->set_module(i, data.init_data.modules[i]); + pv_game_ptr->set_item(i, data.init_data.items[i]); + for (int32_t j = 0; j < 4; j++) + pv_game_ptr->set_item_mask(i, i, data.init_data.items_mask[i].arr[j]); + } + + pv_game_ptr->data.field_2D00C = data.field_191; + pv_game_ptr->data.no_fail = data.no_fail; + pv_game_ptr->data.field_2D00E = data.field_193; + pv_game_ptr->data.song_energy_base = (float_t)data.init_data.score_percentage_clear; + pv_game_ptr->data.life_gauge_safety_time = data.init_data.life_gauge_safety_time; + pv_game_ptr->data.life_gauge_border = data.init_data.life_gauge_border; + pv_game_ptr->data.stage_index = data.init_data.stage_index; + pv_game_ptr->data.play_data.other_se_name.assign(data.se_name); + pv_game_ptr->data.play_data.other_slide_name.assign(data.slide_se_name); + pv_game_ptr->data.play_data.other_chainslide_first_name.assign(data.chainslide_first_name); + pv_game_ptr->data.play_data.other_chainslide_sub_name.assign(data.chainslide_sub_name); + pv_game_ptr->data.play_data.other_chainslide_success_name.assign(data.chainslide_success_name); + pv_game_ptr->data.play_data.other_chainslide_failure_name.assign(data.chainslide_failure_name); + pv_game_ptr->data.play_data.other_slidertouch_name.assign(data.slidertouch_name); + pv_game_ptr->data.field_2D061 = data.field_194; + pv_game_ptr->data.ex_stage = data.ex_stage; + pv_game_ptr->data.field_2D063 = data.field_196; + pv_game_ptr->data.play_data.option = data.option; + + target_pos_scale_offset_get(); + pv_game_parent_state = 0; +} + +bool TaskPvGame::Unload() { + switch (pv_game_parent_state) { + case 0: + pv_game_parent_data.state = 0; + pv_game_music_get()->stop(); + //sub_14013C8F0()->sub_14012B830(); + pv_game_parent_state = 1; + break; + case 1: + break; + default: + return true; + } + + if (!pv_game_ptr->unload()) + return false; + + pv_game_parent_state = 2; + pv_game_music_get()->stop_reset_flags(); + pv_game_free(); + return true; +} + +float_t bar_time_set_to_target_flying_time(int32_t bpm, int32_t time_signature, int64_t* time_int) { + if (time_int) + *time_int = (int64_t)time_signature * (int32_t)(float_t)((60.0 / (float_t)bpm) * 1000000000.0f); + return time_signature * (60.0f / (float_t)bpm); +} + +float_t dsc_time_to_frame(int64_t time) { + return (float_t)((float_t)(int32_t)time / (float_t)1000000000) * 60.0f; +} + +void pv_game_init() { + pv_game_music_init(); + + if (!pv_game_ptr) + pv_game_ptr = new pv_game; +} + +pv_game* pv_game_get() { + return pv_game_ptr; +} + +void pv_game_free() { + if (pv_game_ptr) { + delete pv_game_ptr; + pv_game_ptr = 0; + } + + pv_game_music_free(); +} + +bool task_pv_game_add_task(TaskPvGame::Args& args) { + if (!task_pv_game) + task_pv_game = new TaskPvGame; + + task_pv_game->data.field_0 = 1; + task_pv_game->data.init_data = args.init_data; + task_pv_game->data.se_name.assign(args.se_name); + task_pv_game->data.slide_se_name.assign(args.slide_se_name); + task_pv_game->data.chainslide_first_name.assign(args.chainslide_first_name); + task_pv_game->data.chainslide_sub_name.assign(args.chainslide_sub_name); + task_pv_game->data.chainslide_success_name.assign(args.chainslide_success_name); + task_pv_game->data.chainslide_failure_name.assign(args.chainslide_failure_name); + task_pv_game->data.slidertouch_name.assign(args.slidertouch_name); + task_pv_game->data.field_190 = args.field_190; + task_pv_game->data.field_191 = !args.field_195; + task_pv_game->data.no_fail = args.no_fail; + if (args.field_191) { + task_pv_game->data.field_0 = 2; + task_pv_game->data.field_193 = args.field_193; + } + else + task_pv_game->data.field_193 = true; + task_pv_game->data.field_194 = args.field_195; + task_pv_game->data.ex_stage = args.ex_stage; + task_pv_game->data.field_196 = args.field_197; + task_pv_game->data.option = args.option; + + if (args.test_pv) + return app::TaskWork::AddTask(task_pv_game, "PVGAME", 0); + else + return app::TaskWork::AddTask(task_pv_game, 0, "PVGAME", 0); +} + +bool task_pv_game_check_task_ready() { + return app::TaskWork::CheckTaskReady(task_pv_game); +} + +bool task_pv_game_del_task() { + if (!app::TaskWork::CheckTaskReady(task_pv_game)) { + delete task_pv_game; + task_pv_game = 0; + return true; + } + + task_pv_game->DelTask(); + return false; +} + +void task_pv_game_init_pv() { + PlayerData* player_data = player_data_array_get(0); + + struc_717* v0 = sub_14038BB30(); + struc_716* v2; + if (v0->field_0.stage_index >= 4) + v2 = &v0->field_28[2]; + else + v2 = &v0->field_28[v0->field_0.stage_index]; + + int32_t stage_index = v0->field_0.stage_index; + /*if (stage_index == sub_14038AEE0() - 1) + stage_index = 2;*/ + + TaskPvGame::Args args; + args.init_data.pv_id = max_def(v2->field_2C.pv_id, 0); + args.init_data.difficulty = v2->field_2C.difficulty; + args.init_data.edition = max_def(v2->field_2C.edition, 0); + args.init_data.score_percentage_clear = v2->field_2C.score_percentage_clear / 100; + args.init_data.life_gauge_safety_time = v2->field_2C.life_gauge_safety_time; + args.init_data.life_gauge_border = v2->field_2C.life_gauge_border; + args.init_data.stage_index = stage_index; + args.ex_stage = v2->field_2C.ex_stage; + + for (int32_t i = 0; i < ROB_CHARA_COUNT; i++) { + args.init_data.modules[i] = v2->field_2C.field_4C[i]; + for (int32_t j = 0; j < 4; j++) { + int32_t item_no = 0; + /*if (v2->field_2C.field_64[i] >= 0) + item_no = sub_140234860->sub_140234490( v2->field_2C.field_64[i]);*/ + args.init_data.items[i].arr[j] = item_no; + args.init_data.items_mask[i].arr[j] = v2->field_2C.field_7C[i].arr[j]; + } + } + + args.field_193 = true; + args.field_194 = false; + + /*if (player_data->btn_se_equip >= 0) { + int64_t v21 = sub_140390240(player_data->btn_se_equip); + if (v21) + args.se_name.assign(*(std::string*)(v21 + 40)); + }*/ + + /*if (player_data->slide_se_equip >= 0) { + int64_t v23 = sub_140390240(player_data->slide_se_equip); + if (v23) + args.slide_se_name.assign(*(std::string*)(v23 + 40)); + }*/ + + /*if (player_data->chainslide_se_equip >= 0) { + struc_711* v25 = sub_140374F00(player_data->chainslide_se_equip); + if (v25) { + args.chainslide_first_name.assign(v25->first_name); + args.chainslide_sub_name.assign(v25->sub_name); + args.chainslide_success_name.assign(v25->success_name); + args.chainslide_failure_name.assign(v25->failure_name); + } + }*/ + + /*if (player_data->slidertouch_se_equip >= 0) { + int64_t v28 = sub_14038ED90(player_data->slidertouch_se_equip); + if (v28) + args.slidertouch_name.assign(*(std::string*)(v28 + 40)); + }*/ + + if (sub_14038BB30()->field_0.no_fail) { + args.no_fail = true; + if (!sub_14038BB30()->field_0.field_15) { + args.field_190 = false; + args.field_191 = false; + } + else { + args.field_190 = true; + args.field_191 = true; + if (sub_14038BB30()->field_0.field_16) + args.field_197 = true; + } + } + else { + args.no_fail = false; + args.field_190 = false; + args.field_191 = false; + } + + args.option = sub_14038BB30()->field_0.field_24; + task_pv_game_add_task(args); +} + +void task_pv_game_init_test_pv() { + if (test_mode_get()) + return; + + task_rob_manager_add_task(); + TaskPvGame::Args args; + args.init_data.pv_id = 999; + args.init_data.difficulty = PV_DIFFICULTY_NORMAL; + args.init_data.edition = 0; + args.init_data.score_percentage_clear = 50; + args.init_data.life_gauge_safety_time = 40; + args.init_data.life_gauge_border = 30; + args.field_190 = false; + args.field_191 = false; + args.no_fail = false; + args.field_193 = true; + args.field_194 = true; + args.field_195 = true; + args.test_pv = true; + task_pv_game_add_task(args); +} + +struc_14* sub_14013C8C0() { + return &stru_140C94438; +} + +struc_717* sub_14038BB30() { + return &stru_141197E00; +} + +DivaPvFrameRate::DivaPvFrameRate() { + +} + +DivaPvFrameRate::~DivaPvFrameRate() { + +} + +float_t DivaPvFrameRate::GetDeltaFrame() { + return get_delta_frame() * get_anim_frame_speed() * frame_speed; +} + +pv_game_parent::pv_game_parent() : field_0(), field_1(), pv_state(), playing(), field_4(), +field_5(), field_6(), field_7(), curr_time(), delta_time(), state(), update_func(), field_20(), +field_21(), field_22(), field_23(), field_24(), field_25(), field_26(), field_27(), field_28() { + +} + +void pv_game_parent::ctrl(pv_game_parent* pvgmp) { + switch (pvgmp->pv_state) { + case 0: + default: + switch (pvgmp->state) { + case 0: + case 5: + pvgmp->state = 6; + break; + case 2: + pvgmp->state = 3; + break; + case 3: + pvgmp->state = 4; + break; + case 6: + pv_game_time_ctrl(); + if (sub_14013C8C0()->sub_1400E7920()) { + pv_game_ptr->state = 0; + pvgmp->state = 8; + break; + } + pvgmp->state = 7; + break; + case 7: + pv_game_ptr->state = 0; + pvgmp->state = 8; + break; + case 8: + if (sub_14013C8C0()->sub_1400E7910() < 4 && pv_game_ptr->load()) + pvgmp->state = 9; + break; + case 9: + if (sub_14013C8C0()->sub_1400E7910() == 3 || sub_14013C8C0()->sub_1400E7910() >= 6) { + struc_14* v15 = sub_14013C8C0(); + v15->field_14 = 0; + v15->field_18 = 0; + v15->field_1C = 0; + v15->field_20 = 1.0f; + sub_14013C8C0()->sub_1400E7910(); + //task_wait_screen_set_load_end(); + } + /*else + task_wait_screen_set_load_end();*/ + + pv_game_time_get(); + pvgmp->state = 10; + break; + case 10: + /*if (sub_14013C8C0()->sub_1400E7910() == 3 || (sub_14013C8C0()->sub_1400E7910() >= 6)) { + if (task_wait_screen_get_hide_text()) { + pv_game_ptr->sub_140108320(); + //task_wait_screen_set(0); + if (pv_game_ptr->data.field_2CF9C > 0) { + pv_game_time_ctrl(); + pv_game_time_get(); + } + pvgmp->state = 13; + } + } + else if (task_wait_screen_get_hide_text()) { + task_wait_screen_set_type_0();*/ + pvgmp->state = 11; + //} + break; + case 11: + pvgmp->state = 12; + break; + case 12: + pv_game_ptr->sub_140108320(); + if (pv_game_ptr->data.field_2CF9C > 0) { + pv_game_time_ctrl(); + pv_game_time_get(); + } + pvgmp->state = 13; + break; + default: + if (pvgmp->state >= 13) { + pv_game_state = 0; + pvgmp->field_28 = true; + pvgmp->pv_state = 1; + } + break; + } + break; + case 1: + pv_game_state = pv_game_ptr->ctrl(pvgmp->delta_time, pvgmp->curr_time); + if (pv_game_state) { + sub_14013C8C0()->sub_1400E7910(); + pvgmp->pv_state = 2; + } + break; + case 2: + pvgmp->playing = false; + /*if (pv_game_ptr->data.play_data.field_64C) { + struc_662 v19; + v19.field_0 = pv_game_ptr->data.field_2CE98; + v19.total_hit_count[0] = pv_game_ptr->data.total_hit_count[0]; + v19.hit_count[0] = pv_game_ptr->data.hit_count[0]; + v19.total_hit_count[1] = pv_game_ptr->data.total_hit_count[1]; + v19.hit_count[1] = pv_game_ptr->data.hit_count[1]; + v19.total_hit_count[2] = pv_game_ptr->data.total_hit_count[2]; + v19.hit_count[2] = pv_game_ptr->data.hit_count[2]; + v19.total_hit_count[3] = pv_game_ptr->data.total_hit_count[3]; + v19.hit_count[3] = pv_game_ptr->data.hit_count[3]; + v19.total_hit_count[4] = pv_game_ptr->data.total_hit_count[4]; + v19.hit_count[4] = pv_game_ptr->data.hit_count[4]; + v19.field_2C = pv_game_ptr->sub_1400FDD80(); + v19.max_combo = pv_game_ptr->data.max_combo; + v19.challenge_time_total_bonus = pv_game_ptr->data.challenge_time_total_bonus; + v19.score_final = pv_game_ptr->data.score_final; + v19.score_percentage = (int)(float)(pv_game_ptr->data.song_energy * 100.0); + v19.score_hold_multi = pv_game_ptr->data.score_hold_multi; + v19.score_slide = pv_game_ptr->data.score_slide; + v19.field_70 = pv_game_ptr->data.field_2D0BC; + v19.has_slide = pv_game_ptr->data.has_slide; + v19.field_90 = task_photo_service_sub_1404901F0(); + v6 = 0i64; + v19.pv_game_state = 0; + if (pv_game_ptr->data.has_success_se) + v19.pv_game_state = pv_game_ptr->data.success ? 2 : 1; + v19.field_7C = pv_game_ptr->get_play_data_ex_song_index(); + v19.field_1E0 = pv_game_ptr->data.field_2D0A8; + for (int32_t i = 0; i < 3; i++) + v19.field_1E4[i] = pv_game_ptr->sub_140112C00(i); + v19.next_stage = pv_game_ptr->data.next_stage; + sub_14038BB30()->sub_14038BD60(&v19); + /*if (sub_14038BB30()->field_0.field_15) + task_photo_service_sub_140490050(); + }*/ + + if (pv_game_ptr) { + if (sub_14013C8C0()->sub_1400E7910() >= 4) + pv_game_ptr->sub_140106640(); + else + pv_game_ptr->unload(); + } + + sub_14013C8C0()->sub_1400E7910(); + } +} + +pv_game_time::pv_game_time() : curr_time(), add_last_stop_time(), delta_time(), add_current_time() { + last_stop_time.get_timestamp(); + add_last_stop_time = true; +} + +pv_game_se_data::pv_game_se_data() { + +} + +pv_game_se_data::~pv_game_se_data() { + +} + +struc_674::struc_674() : performer(), module(), item(), field_1C(), pv() { + +} + +struc_683::struc_683() : sort_index(), chara_index(), cos(), sleeve_l(), sleeve_r() { + id = -1; + spr_sel_md_id_spr_set_id = -1; + spr_sel_md_id_cmn_spr_set_id = -1; + spr_sel_md_id_cmn_md_img_id_spr_id = -1; + spr_sel_md_id_cmn_md_img_spr_id = -1; + field_78 = false; + field_79 = false; + name.assign(""); + field_A0 = 0; + field_A8 = -1; + field_B0 = -1; + //field_A8 = *sub_1404911C0(); + //field_B0 = *sub_1404911C0(); +} + +static bool pv_game_parent_ctrl() { + if (pv_game_parent_data.field_28) { + pv_game_parent_data.field_28 = false; + + pv_game_time_data.curr_time = 0; + pv_game_time_data.last_stop_time.get_timestamp(); + pv_game_time_data.last_stop_time.get_timestamp(); + pv_game_time_data.add_last_stop_time = true; + + pv_game_time_data.delta_time = 0; + pv_game_time_data.current_time.get_timestamp(); + pv_game_time_data.current_time.get_timestamp(); + pv_game_time_data.add_current_time = true; + } + + int64_t curr_time = pv_game_time_data.curr_time; + if (pv_game_time_data.add_last_stop_time) + curr_time += (int64_t)(pv_game_time_data.last_stop_time.calc_time() * 100.0); + + int64_t delta_time = pv_game_time_data.delta_time; + if (pv_game_time_data.add_current_time) + delta_time += (int64_t)(pv_game_time_data.current_time.calc_time() * 100.0); + + pv_game_time_data.delta_time = 0; + pv_game_time_data.current_time.get_timestamp(); + + pv_game_parent_data.curr_time = 1000 * curr_time; + pv_game_parent_data.delta_time = (float_t)(1000 * delta_time) * 0.000000001f; + + //sub_14013C8D0()->sub_140132C20(pv_game_parent_data.delta_time); + + if (pv_game_parent_data.playing && pv_game_parent_data.update_func) + pv_game_parent_data.update_func(&pv_game_parent_data); + + pv_game_music_get()->ctrl(pv_game_parent_data.delta_time); + return pv_game_parent_data.playing; +} + +static void pv_game_parent_disp() { + pv_game_ptr->data.play_data.disp(); + pv_game_ptr->disp(); +} + +static void pv_game_time_ctrl() { + if (pv_game_time_data.add_last_stop_time) + pv_game_time_data.curr_time += (int64_t)(pv_game_time_data.last_stop_time.calc_time() * 100.0); + pv_game_time_data.add_last_stop_time = false; + + if (pv_game_time_data.add_current_time) + pv_game_time_data.delta_time += (int64_t)(pv_game_time_data.current_time.calc_time() * 100.0); + pv_game_time_data.add_current_time = false; +} + +static void pv_game_time_get() { + pv_game_time_data.last_stop_time.get_timestamp(); + pv_game_time_data.add_last_stop_time = true; + + pv_game_time_data.current_time.get_timestamp(); + pv_game_time_data.add_current_time = true; +} + +static FrameRateControl* get_diva_pv_frame_rate() { + return &diva_pv_frame_rate; +} + +static SysFrameRate* sys_frame_rate_get(int32_t chara_id) { + if (chara_id < 0 || chara_id >= 3) + chara_id = 0; + return &sys_frame_rate_array[chara_id]; +} + +static int32_t sub_1400FCFD0(pv_game_chara* arr, const pv_db_pv* pv) { + chara_index charas[ROB_CHARA_COUNT]; + for (chara_index& i : charas) + i = CHARA_MAX; + + for (int32_t i = 0; i < ROB_CHARA_COUNT; i++) + if (i < pv->ex_song.chara_count) + charas[i] = arr[i].chara_index; + + for (const pv_db_pv_ex_song& i : pv->ex_song.data) { + int32_t j = 0; + for (; j < ROB_CHARA_COUNT; j++) + if (charas[j] != CHARA_MAX && i.chara[j] != charas[j]) + break; + + if (j == ROB_CHARA_COUNT) + return (int32_t)(&i - pv->ex_song.data.data()); + } + return -1; +} + +static void sub_140105010(pv_game_chara* arr, size_t max_count, pv_game_item_mask* a3, struc_674& a4) { + int32_t performer = (int32_t)a4.performer; + pv_game_chara* chr = &arr[performer]; + + { + /*struc_683 v40; + if (sub_1403F8C30()->sub_1403F8B40(a4.module, v40)) { + chr->chara_index = v40.chara_index; + chr->cos = v40.cos; + chr->pv_data.sleeve_l = v40.sleeve_l; + chr->pv_data.sleeve_r = v40.sleeve_r; + } + else */{ + chr->chara_index = CHARA_MIKU; + chr->cos = 0; + } + } + + chr->pv_data.item = a4.item; + + /*for (int32_t i = 0; i < PV_PERFORMER_ITEM_MAX; i++) + if (sub_140234860()->sub_140234460(chr->pv_data.item.arr[i]) < 0) + chr->pv_data.item.arr[i] = 0;*/ + + const pv_db_pv* pv = a4.pv; + PlayerData* player_data = player_data_array_get(0); + bool v14 = pv->get_performer_pseudo_fixed(chr->chara_index, + performer, a4.field_1C, player_data->field_F40 == 0); + if (sub_14013C8C0()->sub_1400E7910() == 3 && !pv->get_performer_fixed(performer)) + v14 = false; + + ::chara_index chara_index = CHARA_MAX; + int32_t costume; + if (pv->is_performer_type_pseudo(performer)) { + int32_t pseudo_performer = pv->get_performer_pseudo_same_id(performer); + if (pseudo_performer >= 0) { + pv_game_chara* pseudo_chr = &arr[pseudo_performer]; + if (!a4.field_1C && player_data->field_F40 && sub_14013C8C0()->sub_1400E7910() != 3 + || chr->chara_index != pseudo_chr->chara_index || pv->get_performer_fixed(performer)) { + chara_index = pseudo_chr->chara_index; + pv_performer_type type = pv->get_performer_type(performer); + costume = pv_db_pv::get_pseudo_costume(type, pseudo_chr->chara_index, pseudo_chr->cos); + + pv_game::get_item_mask(type, &pseudo_chr->pv_data.item, + &a3[pseudo_performer], &chr->pv_data.item, &a3[performer]); + } + } + } + + if (v14) { + chara_index = pv->get_performer_chara(performer); + costume = pv->get_performer_costume(performer); + int32_t exclude = pv->get_performer_exclude(performer); + if (exclude >= 0 && exclude < max_count && arr[exclude].chara_index == chara_index) { + chara_index = pv->get_performer_chara(exclude); + costume = pv->get_performer_costume(exclude); + } + } + + if (chara_index != CHARA_MAX) { + //struc_683 v40; + //sub_1403F8C30()->sub_1403F8840(chara_index, costume != -1 ? costume : 0, v40); + chr->chara_index = chara_index;//v40.chara_index; + chr->cos = costume;//v40.cos; + } + + pv_performer_item item = PV_PERFORMER_ITEM_ZUJO; + for (int32_t i = 0; i < PV_PERFORMER_ITEM_MAX; i++) { + int32_t item_no = pv->get_performer_item(performer, item); + if (item_no == -2) { + const item_cos_data* cos = + item_table_handler_array_get_item_cos_data_by_module_index(chr->chara_index, chr->cos); + if (!cos) + continue; + + item_sub_id sub_id = pv_performer_item_to_item_sub_id(item); + if (sub_id < 0 || sub_id >= ITEM_SUB_MAX) + continue; + + chr->pv_data.item.arr[i] = cos->arr[sub_id]; + a3[performer].arr[i] = true; + } + else if (item_no > 0) { + const item_table_item* itm = item_table_handler_array_get_item(chr->chara_index, item_no); + if (itm && itm->sub_id == pv_performer_item_to_item_sub_id(item)) + chr->pv_data.item.arr[i] = item_no; + } + } +} diff --git a/src/ReDIVA/pv_game/pv_game.hpp b/src/ReDIVA/pv_game/pv_game.hpp new file mode 100644 index 00000000..28c52b4d --- /dev/null +++ b/src/ReDIVA/pv_game/pv_game.hpp @@ -0,0 +1,815 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#pragma once + +#include "../../CRE/auth_3d.hpp" +#include "../../CRE/stage.hpp" +#include "../../CRE/task.hpp" +#include "../task_window.hpp" +#include "pv_game_pv_data.hpp" +#include "pv_game_play_data.hpp" + +enum hit_state { + HIT_COOL = 0, + HIT_FINE, + HIT_SAFE, + HIT_BAD, + HIT_WRONG_COOL, + HIT_WRONG_FINE, + HIT_WRONG_SAFE, + HIT_WRONG_BAD, + HIT_WORST, + HIT_COOL_DOUBLE, + HIT_FINE_DOUBLE, + HIT_SAFE_DOUBLE, + HIT_BAD_DOUBLE, + HIT_COOL_TRIPLE, + HIT_FINE_TRIPLE, + HIT_SAFE_TRIPLE, + HIT_BAD_TRIPLE, + HIT_COOL_QUADRIPLE, + HIT_FINE_QUADRIPLE, + HIT_SAFE_QUADRIPLE, + HIT_BAD_QUADRIPLE, + HIT_MAX, +}; + +struct pv_game_chara { + chara_index chara_index; + int32_t cos; + int32_t chara_id; + rob_chara_pv_data pv_data; + rob_chara* rob_chr; + std::vector motion_ids; + std::vector motion_face_ids; + + pv_game_chara(); + ~pv_game_chara(); + + bool check_chara(); + void reset(); +}; + +struct pv_game_edit_effect_data { + int32_t index; + float_t speed; + float_t time; + float_t end_frame; + float_t delta_time; + bool loop; + + pv_game_edit_effect_data(); + + void reset(); +}; + +struct pv_game_edit_effect { + std::vector spr_set_ids; + std::vector aet_set_ids; + std::vector aet_ids; + pv_game_edit_effect_data data; + + pv_game_edit_effect(); + ~pv_game_edit_effect(); + + void reset(); + void unload(); +}; + +struct pv_game_field { + int32_t stage_index; + std::vector auth_3d_uids; + std::vector auth_3d_ids; + std::map auth_3d_frame_list; + int32_t light_auth_3d_uid; + auth_3d_id light_auth_3d_id; + int32_t light_frame; + std::vector aet_names[4]; + std::vector aet_ids[4]; + std::map, int32_t> aet[4]; + uint32_t spr_set_back_id; + bool stage_flag; + int32_t npr_type; + int32_t cam_blur; + bool sdw_off; + std::vector play_eff_list; + std::vector stop_eff_list; + std::vector field_1A0; + + pv_game_field(); + ~pv_game_field(); +}; + +struct struc_269 { + prj::vector_pair data; + std::vector auth_3d_ids; + int32_t field_30; + int32_t field_34; + + struc_269(); + ~struc_269(); +}; + +struct pv_game_chreff { + chara_index src_chara_index; + chara_index dst_chara_index; + std::bitset<128> type; + std::string src_auth_3d; + std::string dst_auth_3d; + std::string src_auth_3d_category; + std::string dst_auth_3d_category; + int32_t src_auth_3d_uid; + int32_t dst_auth_3d_uid; + + pv_game_chreff(); + ~pv_game_chreff(); +}; + +struct pv_effect_resource { + std::string name; + float_t emission; + + pv_effect_resource(); + ~pv_effect_resource(); +}; + +struct pv_game_data { + pv_game_pv_data pv_data; + pv_game_play_data play_data; + int32_t field_2CE98; + int8_t field_2CE9C[128]; + int32_t field_2CF1C; + bool field_2CF20; + int32_t field_2CF24; + float_t field_2CF28; + float_t field_2CF2C; + int32_t field_2CF30; + int32_t field_2CF34; + int32_t field_2CF38; + int32_t life_gauge; + int32_t score_final; + int32_t challenge_time_total_bonus; + int32_t combo; + int32_t challenge_time_combo_count; + int32_t max_combo; + int32_t total_hit_count[5]; + int32_t hit_count[5]; + int32_t current_reference_score; + int32_t target_count; + int32_t field_2CF84; + int32_t field_2CF88; + float_t field_2CF8C; + int32_t score_slide_chain_bonus; + int32_t slide_chain_length; + int32_t field_2CF98; + int32_t field_2CF9C; + int16_t field_2CFA0; + int32_t field_2CFA4; + const pv_db_pv* pv; + int32_t field_2CFB0; + int32_t chance_point; + int32_t reference_score; + int32_t reference_score_no_flag; + int32_t reference_score_no_flag_life_bonus; + std::vector target_reference_score; + int32_t field_2CFE0; + int32_t field_2CFE4; + size_t notes_passed; + int32_t field_2CFF0; + float_t song_energy; + float_t song_energy_base; + float_t song_energy_border; + int32_t life_gauge_safety_time; + int32_t life_gauge_border; + int32_t stage_index; + bool field_2D00C; + bool no_fail; + bool field_2D00E; + bool changed_field; + int64_t challenge_time_start; + int64_t challenge_time_end; + int64_t max_time; + float_t max_time_float; + float_t current_time_float; + uint64_t current_time; + float_t field_2D038; + float_t field_2D03C; + int32_t score_hold_multi; + uint32_t score_hold; + int32_t score_slide; + bool has_slide; + bool has_success_se; + pv_disp2d* pv_disp2d; + int32_t life_gauge_final; + bool hit_border; + bool field_2D05D; + bool field_2D05E; + bool start_fade; + bool title_image_init; + bool field_2D061; + bool ex_stage; + bool field_2D063; + bool has_auth_3d_frame; + bool has_light_frame; + bool has_aet_frame[4]; + bool has_aet_list[4]; + uint32_t field_index; + int32_t edit_effect_index; + int32_t slidertouch_counter; + int32_t change_field_branch_success_counter; + int32_t field_2D080; + int32_t field_2D084; + int32_t life_gauge_bonus; + int32_t life_gauge_total_bonus; + bool field_2D090; + bool no_clear; + bool field_2D092; + bool field_2D093; + bool field_2D094; + bool field_2D095; + bool field_2D096; + bool success; + int32_t title_image_state; + int32_t field_2D09C; + bool use_osage_play_data; + bool pv_end_fadeout; + float_t rival_percentage; + int32_t field_2D0A8; + int32_t field_2D0AC; + int32_t field_2D0B0[3]; + bool field_2D0BC; + bool next_stage; + bool has_frame_texture; + int8_t field_2D0BF; + int32_t field_2D0C0; + int32_t field_2D0C4; + pv_game_chara chara[ROB_CHARA_COUNT]; + std::vector motion_set_ids; + std::vector motion_set_face_ids; + std::vector obj_set_itmpv; + std::vector obj_set_handitem; + std::vector chreff_auth_3d_obj_set_ids; + std::vector field_2D770; + std::vector stgpvhrc_obj_set_ids; + std::vector ex_song_ex_auth_obj_set_ids; + std::vector stage_indices; + std::vector stage_infos; + bool field_2D7E8; + int32_t field_2D7EC; + std::vector spr_set_back_ids; + int32_t field_2D808; + int32_t field_2D80C; + pv_game_edit_effect edit_effect; + uint32_t camera_auth_3d_uid; + int32_t se_index; + bool task_effect_init; + int32_t field_2D87C; + size_t current_field; + std::vector field_data; + bool field_2D8A0; + int32_t field_2D8A4; + std::map auth_3d_time; + std::map light_time; + std::map, int64_t> aet_time[4]; + std::string campv_string; + std::vector campv_auth_3d_uids; + std::map campv; + int32_t campv_index; + int32_t field_2D954; + std::string itmpv_string; + std::vector itmpv_auth_3d_uids; + std::map> itmpv[ROB_CHARA_COUNT]; + std::vector itmpv_uids; + struc_269 field_2DA08[3]; + std::vector loaded_auth_3d_uids; + bool field_2DAC8; + int32_t field_2DACC; + std::vector auth_3d_categories; + std::map auth_3d; + std::vector chreff_auth_3d; + std::vector chreff_auth_3d_obj; + bool height_adjust; + vec2 field_2DB2C; + int32_t field_2DB34; + time_struct field_2DB38; + std::vector effect_rs_list_hashes; + std::vector effect_rs_list; + + pv_game_data(); + ~pv_game_data(); + + void calculate_target_start_pos(vec2& pos, float_t angle, float_t distance, vec2& start_pos); + int64_t get_max_time(int64_t* challenge_time_start, int64_t* challenge_time_end); + void reset(); + + bool sub_140119960(bool* has_target, int64_t* dsc_time, int32_t* target_count, + int64_t* target_flying_time, float_t fade_time, bool* fade, dsc_target_ft* target_hist, + int32_t* target_flag, bool* has_chance, bool* has_slide, int32_t* slide_chain_type, + bool* slide_chain_start, int32_t* slide_chain_start_count, int32_t* slide_chain_cont_count, + int32_t* slide_chain_no_end_count, bool* has_slide_chain, int64_t target_flying_time_hist); +}; + +struct pv_game_item_mask { + bool arr[4]; + + pv_game_item_mask(); +}; + +struct pv_game { + bool loaded; + bool field_1; + bool field_2; + bool end_pv; + bool field_4; + int32_t state; + int32_t field_C; + int32_t pv_id; + bool field_14; + int32_t modules[ROB_CHARA_COUNT]; + rob_chara_pv_data_item items[ROB_CHARA_COUNT]; + pv_game_item_mask items_mask[ROB_CHARA_COUNT]; + pv_game_data data; + + pv_game(); + ~pv_game(); + + void calculate_life_gauge(hit_state hit_state, bool has_safety, + bool challenge_time, bool slide, bool slide_chain, bool slide_chain_start, bool a8); + int32_t calculate_life_gauge_border(); + int32_t calculate_reference_score(); + void calculate_score(int32_t score, bool continue_combo, int64_t& time, + vec2& pos, int32_t multi_count, hit_state hit_state, bool challenge_time, bool slide, + bool slide_chain, bool slide_chain_start, bool slide_chain_max, bool slide_chain_continues); + void calculate_song_energy(); + void calculate_song_energy_border(); + void calculate_target_reference_score(int32_t* reference_score, + int32_t* target_index, int32_t multi_count, bool slide_chain); + void calculate_target_reference_combo_bonus(int32_t* reference_score, int32_t* target_index); + void change_field(size_t field, ssize_t dsc_time, ssize_t curr_time); + void check_auth_replace_by_module(const char* name, int32_t& uid); + int32_t check_chrcam(const char* name, int32_t& uid); + bool check_life_gauge_safety(); + int32_t ctrl(float_t delta_time, int64_t curr_time); + void data_itmpv_disable(); + void disp(); + void edit_effect_ctrl(float_t delta_time); + void edit_effect_set(int32_t index, float_t frame_speed, float_t delta_time); + void end(bool a2, bool set_fade); + float_t get_aet_frame_max_frame(int32_t aet_frame, int32_t aet_index, std::pair& aet_name_id, int64_t dsc_time, int64_t curr_time, float_t* max_frame); + void get_aet_frame_max_frame_by_name(float_t& frame, + float_t& max_frame, std::pair& aet_name_id); + float_t get_aet_frame_max_frame_change_field(int32_t aet_index, + std::pair& aet_name_id, int64_t time); + int64_t get_aet_time(int32_t aet_index, std::pair& aet_name_id); + float_t get_auth_3d_frame_max_frame(int32_t auth_3d_frame, int32_t auth_3d_uid, + int64_t dsc_time, int64_t curr_time, uint8_t type, float_t* max_frame); + float_t get_auth_3d_frame_max_frame_change_field(uint32_t auth_3d_uid, int64_t time, uint8_t type); + auth_3d_id get_auth_3d_id(int32_t uid); + int64_t get_auth_3d_time(int32_t uid, uint8_t type); + uint32_t get_chreff_auth_3d_object_set(int32_t& uid); + int64_t get_data_itmpv_time(int32_t chara_id, int32_t index); + float_t get_data_rival_percentage(); + std::string get_effect_se_file_name(); + int32_t get_field_aet_frame_by_name_id(pv_game_field& field, + int32_t aet_index, std::pair& aet_name_id); + int32_t get_field_aet_index_by_name_id(pv_game_field& field, + int32_t aet_index, std::pair& aet_name_id); + int32_t get_field_auth_3d_frame(pv_game_field& field_data, int32_t uid, int32_t type); + int32_t get_frame(int32_t frame, int64_t dsc_time, int64_t curr_time); + int32_t get_frame_continue(int32_t frame); + float_t get_life_gauge_safety_time(); + float_t get_next_aet_max_frame_change_field(int32_t aet_index, + std::pair& aet_name_id, int64_t dsc_time, int64_t curr_time); + float_t get_next_aet_max_time_max_frame_change_field(int32_t aet_index, + std::pair& aet_name_id, int64_t dsc_time, int64_t* max_time, + int64_t curr_time, prj::vector_pair& change_field); + float_t get_next_auth_3d_max_frame_change_field(uint32_t auth_3d_uid, + int64_t dsc_time, int64_t curr_time, int32_t type); + float_t get_next_auth_3d_max_time_max_frame_change_field(uint32_t auth_3d_uid, int64_t dsc_time, + int64_t* max_time, int64_t curr_time, prj::vector_pair& change_field, int32_t type); + int32_t get_play_data_ex_song_index(); + std::string get_play_data_song_file_name(); + const pv_db_pv* get_pv_db_pv(); + float_t get_pv_hidden_timing(); + int32_t get_pv_high_speed_rate(); + std::string get_pv_movie_file_name(int32_t index); + float_t get_pv_sudden_timing(); + std::string get_song_name(); + std::string get_song_file_name(int32_t& ex_song_index); + task_stage_info get_stage_info(int32_t stage_index); + bool is_play_data_option_3(); + void itmpv_reset(); + bool load(); + void play_se(int32_t index); + void reset(); + void reset_field(); + void set_chara_use_opd(bool value); + void set_data_campv(int32_t type, int32_t index, float_t frame); + void set_data_itmpv(int32_t chara_id, int32_t index, bool enable, int64_t time); + void set_data_itmpv_chara_id(int32_t chara_id, int32_t index, bool attach); + void set_data_itmpv_req_frame(int32_t chara_id, int32_t index, float_t value); + void set_data_itmpv_max_frame(int32_t chara_id, float_t value); + void set_data_itmpv_max_frame(int32_t chara_id, int32_t index, float_t value); + void set_data_itmpv_visibility(int32_t chara_id, bool value); + void set_data_itmpv_visibility(int32_t chara_id, int32_t index, bool value); + void set_eyes_adjust(pv_game_chara* chr); + void set_item(size_t performer, rob_chara_pv_data_item& value); + void set_item_mask(size_t performer, size_t item, bool value); + void set_lyric(int32_t lyric_index, vec4u8 lyric_color); + void set_module(size_t performer, int32_t module); + void set_osage_init(const pv_game_chara& chr); + bool set_pv_param_post_process_bloom_data(bool set, int32_t id, float_t duration); + void set_pv_param_post_process_chara_alpha_data(int32_t chara_id, + float_t alpha, int32_t type, float_t duration); + void set_pv_param_post_process_chara_item_alpha_data(int32_t chara_id, + float_t alpha, int32_t type, float_t duration); + bool set_pv_param_post_process_color_correction_data(bool set, int32_t id, float_t duration); + bool set_pv_param_post_process_dof_data(bool set, int32_t id, float_t duration); + void title_image_ctrl(bool dont_wait); + bool unload(); + + void sub_1400FC500(); + int32_t sub_1400FC780(float_t delta_time); + void sub_1400FCAD0(float_t delta_time); + float_t sub_1400FCEB0(); + int32_t sub_1400FDD80(); + void sub_140104FB0(); + void sub_140106640(); + void sub_140108320(); + bool sub_14010EF00(); + void sub_14010F030(); + int32_t sub_14010F930(); + int32_t sub_140112C00(int32_t index); + void sub_140113730(); + void sub_140115C10(int32_t chara_id, bool value); + void sub_140115C90(int32_t chara_id, bool disp, int32_t index, float_t frame, float_t frame_speed); + void sub_1401230A0(); + + static void chara_item_alpha_callback(void* data, int32_t chara_id, int32_t type, float_t alpha); + static void get_item_mask(pv_performer_type type, + rob_chara_pv_data_item* src_item, pv_game_item_mask* src_mask, + rob_chara_pv_data_item* dst_item, pv_game_item_mask* dst_mask); +}; + +struct pv_game_init_data { + int32_t pv_id; + pv_difficulty difficulty; + int32_t edition; + int32_t score_percentage_clear; + int32_t life_gauge_safety_time; + int32_t life_gauge_border; + int32_t stage_index; + int32_t modules[ROB_CHARA_COUNT]; + rob_chara_pv_data_item items[ROB_CHARA_COUNT]; + pv_game_item_mask items_mask[ROB_CHARA_COUNT]; + + pv_game_init_data(); + + void reset(); +}; + +struct struc_14 { + int32_t field_0; + pv_difficulty difficulty; + int32_t edition; + uint32_t pv; + int8_t field_10; + int8_t field_11; + int8_t field_12; + int8_t field_13; + int32_t field_14; + int32_t field_18; + int32_t field_1C; + float_t field_20; + bool field_24; + bool field_25; + bool field_26; + + struc_14(); + + int32_t sub_1400E7910(); + bool sub_1400E7920(); + void sub_1400E79E0(int32_t a2); +}; + +struct struc_677 { + int32_t field_0; + int32_t field_4; + int32_t stage_index; + int8_t field_C; + int32_t field_10; + bool no_fail; + int8_t field_15; + int8_t field_16; + bool field_17; + int32_t field_18; + int32_t field_1C; + int32_t field_20; + int32_t field_24; +}; + +struct struc_775 { + int32_t pv_id; + int32_t field_4; + pv_difficulty difficulty; + int32_t edition; + int32_t field_10; + int32_t field_14; + int32_t field_18; + int8_t field_1C; + int32_t score_percentage_clear; + int32_t life_gauge_safety_time; + int32_t life_gauge_border; + int32_t field_2C; + int8_t field_30; + int32_t field_34; + int32_t field_38; + int8_t field_3C; + bool ex_stage; + int32_t another_song_index; + int32_t field_44; + int8_t field_48; + int8_t field_49; + int32_t field_4C[6]; + int32_t field_64[6]; + rob_chara_pv_data_item field_7C[6]; + bool field_DC[6]; + int32_t field_E4; + int32_t field_E8; + int32_t field_EC; + int32_t field_F0; + int32_t field_F4; +}; + +struct struc_663 { + int32_t field_0; + int32_t field_4; + int32_t field_8; + int32_t field_C; +}; + +struct struc_664 { + int8_t field_0; + int8_t field_1; + int8_t field_2; + int8_t field_3; +}; + + +struct struc_660 { + int32_t field_0; + int32_t field_4; + std::vector field_8; + int32_t field_20; + int32_t field_24; + std::string field_28; + int32_t field_48; + int32_t field_4C; +}; + +struct struc_661 { + struc_660 field_0[2]; +}; + +struct struc_662 { + int32_t field_0; + int32_t total_hit_count[5]; + int32_t hit_count[5]; + int32_t field_2C; + int32_t field_30[5]; + int32_t field_44[5]; + int32_t max_combo; + int32_t challenge_time_total_bonus; + int32_t score_hold_multi; + int32_t score_final; + int32_t score_percentage; + int32_t score_slide; + bool field_70; + int32_t has_slide; + int32_t pv_game_state; + int32_t field_7C; + int32_t field_80; + int32_t field_84; + int32_t field_88; + int32_t field_8C; + int32_t field_90; + int32_t field_94; + int32_t field_98; + int32_t field_9C; + int32_t field_A0; + int32_t field_A4; + int32_t field_A8; + int32_t field_AC[6]; + struc_663 field_C4[6]; + struc_664 field_124[6]; + int32_t field_13C; + struc_661 field_140; + int32_t field_1E0; + int32_t field_1E4[3]; + bool next_stage; +}; + +struct struc_777 { + int8_t field_0; + int32_t field_4; + int32_t field_8; + int32_t field_C; + std::string field_10; + int32_t field_30; + int32_t field_34; + int32_t field_38; + int32_t field_3C; + std::string field_40; + int32_t field_60; + int32_t field_64; +}; + +struct struc_778 { + int32_t field_0; + int32_t field_4; + std::string field_8[2]; +}; + +struct struc_780 { + int32_t field_0; + int32_t field_4; + int8_t field_8; +}; + +struct struc_779 { + int32_t field_0; + int32_t field_4; + int32_t field_8; + struc_780 field_C[5]; +}; + +struct struc_716 { + int32_t field_0; + int32_t field_4; + int32_t field_8; + int32_t field_C; + int8_t field_10; + int8_t field_11; + int32_t field_14; + int32_t field_18; + int32_t field_1C; + int32_t field_20; + int32_t field_24; + int32_t field_28; + struc_775 field_2C; + struc_662 field_128; + struc_777 field_320; + struc_778 field_388; + struc_778 field_3D0[3]; + struc_779 field_4A8[5]; + int64_t field_610; + int64_t field_618; + int64_t field_620; + int64_t field_628; + int64_t field_630; + int64_t field_638; + int64_t field_640; + int8_t field_648; + int8_t field_649; + int64_t field_650; + int64_t field_658; + int64_t field_660; +}; + +struct struc_718 { + int64_t field_0; + int64_t field_8; + int64_t field_10; + int64_t field_18; + int64_t field_20; + int64_t field_28; + int64_t field_30; + int64_t field_38; + int64_t field_40; + int64_t field_48; + int64_t field_50; + int64_t field_58; + int64_t field_60; + int64_t field_68; + int64_t field_70; + int64_t field_78; + int64_t field_80; + int64_t field_88; + int64_t field_90; + int64_t field_98; + int64_t field_A0; + int64_t field_A8; + int64_t field_B0; + int64_t field_B8; + int64_t field_C0; + int64_t field_C8; + int64_t field_D0; + int64_t field_D8; + int64_t field_E0; + int64_t field_E8; + int64_t field_F0; + int64_t field_F8; + int64_t field_100; + int64_t field_108; + int64_t field_110; + int64_t field_118; + int64_t field_120; + int64_t field_128; + int64_t field_130; + int64_t field_138; + int64_t field_140; +}; + +struct struc_717 { + struc_677 field_0; + struc_716 field_28[4]; + struc_718 field_19C8; +}; + +class TaskPvGame : public app::Task { +public: + struct Args { + pv_game_init_data init_data; + std::string se_name; + std::string slide_se_name; + std::string chainslide_first_name; + std::string chainslide_sub_name; + std::string chainslide_success_name; + std::string chainslide_failure_name; + std::string slidertouch_name; + bool field_190; + bool field_191; + bool no_fail; + bool field_193; + bool field_194; + bool field_195; + bool ex_stage; + bool field_197; + bool test_pv; + int32_t option; + + Args(); + ~Args(); + + void Clear(); + void Reset(); + }; + + struct Data { + int32_t field_0; + pv_game_init_data init_data; + std::string se_name; + std::string slide_se_name; + std::string chainslide_first_name; + std::string chainslide_sub_name; + std::string chainslide_success_name; + std::string chainslide_failure_name; + std::string slidertouch_name; + bool field_190; + bool field_191; + bool no_fail; + bool field_193; + bool field_194; + bool ex_stage; + bool field_196; + int32_t option; + + Data(); + ~Data(); + + void Clear(); + void Reset(); + } data; + + TaskPvGame(); + virtual ~TaskPvGame() override; + + virtual bool Init() override; + virtual bool Ctrl() override; + virtual bool Dest() override; + virtual void Disp() override; + + void Load(TaskPvGame::Data& data); + bool Unload(); +}; + +extern float_t bar_time_set_to_target_flying_time(int32_t bpm, int32_t time_signature, int64_t* time_int = 0); +extern float_t dsc_time_to_frame(int64_t time); + +extern void pv_game_init(); +extern pv_game* pv_game_get(); +extern void pv_game_free(); + +extern bool task_pv_game_add_task(TaskPvGame::Args& args); +extern bool task_pv_game_check_task_ready(); +extern bool task_pv_game_del_task(); + +extern void task_pv_game_init_pv(); +extern void task_pv_game_init_test_pv(); + +extern struc_14* sub_14013C8C0(); +extern struc_717* sub_14038BB30(); diff --git a/src/ReDIVA/pv_game/pv_game_camera.cpp b/src/ReDIVA/pv_game/pv_game_camera.cpp new file mode 100644 index 00000000..b0af8c68 --- /dev/null +++ b/src/ReDIVA/pv_game/pv_game_camera.cpp @@ -0,0 +1,297 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#include "pv_game_camera.hpp" +#include "../../CRE/rob/rob.hpp" +#include "../../CRE/render_context.hpp" + +struct pv_game_camera { + bool enable; + bool follow_chara; + bool edit_camera; + float_t duration; + float_t curr_time; + vec3 view_point_start; + vec3 view_point_end; + vec3 interest_start; + vec3 interest_end; + float_t start_distance; + float_t end_distance; + mat4 dir_mat; + mat4 up_mat; + vec3 view_direction; + vec3 up_vec; + float_t fov; + float_t min_dist; + int32_t chara_id; + int32_t chara_follow_point; + float_t acceleration_1; + float_t acceleration_2; + int32_t field_F4; + float_t acceleration; + float_t acceleration_curr_time; + + pv_game_camera(); + + void reset(); +}; + +extern render_context* rctx_ptr; + +pv_game_camera pv_game_camera_data; + +static float_t pv_game_camera_get_acceleration(); +static bool pv_game_camera_get_edit_camera(cam_struct* cam, float_t delta_time); +static bool pv_game_camera_get_move_camera(cam_struct* cam, float_t delta_time); + +pv_game_camera::pv_game_camera() : enable(), follow_chara(), edit_camera(), duration(), curr_time(), +start_distance(), end_distance(), fov(), min_dist(), chara_id(), chara_follow_point(), +acceleration_1(), acceleration_2(), field_F4(), acceleration(), acceleration_curr_time() { + +} + +void pv_game_camera::reset() { + enable = false; + follow_chara = false; + edit_camera = false; + duration = 0.0f; + curr_time = 0.0f; + view_point_end = 0.0f; + view_point_start = 0.0f; + interest_end = 0.0f; + interest_start = 0.0f; + dir_mat = mat4_identity; + up_mat = mat4_identity; + view_direction = { 0.0f, 0.0f, 1.0f }; + up_vec = { 0.0f, 1.0f, 0.0f }; + fov = 32.2673416137695f; + min_dist = 0.05f; + chara_id = 0; + chara_follow_point = 0; + acceleration_1 = 0.0f; + acceleration_2 = 1.0f; + field_F4 = 0; + acceleration = 0.0f; + acceleration_curr_time = 0.0f; +} + +pv_game_camera_dsc_data::pv_game_camera_dsc_data() { + +} + +void pv_game_camera_ctrl(float_t delta_time) { + if (!pv_game_camera_data.enable) + return; + + bool in_transition; + cam_struct cam; + if (pv_game_camera_data.edit_camera) + in_transition = pv_game_camera_get_edit_camera(&cam, delta_time); + else + in_transition = pv_game_camera_get_move_camera(&cam, delta_time); + + cam.fov = pv_game_camera_data.fov * DEG_TO_RAD_FLOAT; + cam.min_distance = pv_game_camera_data.min_dist; + cam.set(rctx_ptr->camera); + + if (!in_transition) + pv_game_camera_data.reset(); +} + +void pv_game_camera_reset() { + pv_game_camera_data.reset(); +} + +void pv_game_camera_set_dsc_data(float_t duration, pv_game_camera_dsc_data& start, + pv_game_camera_dsc_data& end, float_t acceleration_1, float_t acceleration_2, + int32_t follow_chara, int32_t chara_id, int32_t chara_follow_point, bool edit_camera) { + pv_game_camera_data.reset(); + + pv_game_camera_data.edit_camera = edit_camera; + + start.up_vec = vec3::normalize(start.up_vec); + end.up_vec = vec3::normalize(end.up_vec); + + pv_game_camera_data.view_point_start = start.view_point; + pv_game_camera_data.view_point_end = end.view_point; + pv_game_camera_data.interest_start = start.interest; + pv_game_camera_data.interest_end = end.interest; + + if (!edit_camera) { + vec3 start_direction = start.view_point - start.interest; + vec3 end_direction = end.view_point - end.interest; + + pv_game_camera_data.start_distance = vec3::length(start_direction); + pv_game_camera_data.end_distance = vec3::length(end_direction); + + start_direction = vec3::normalize(start_direction); + end_direction = vec3::normalize(end_direction); + + pv_game_camera_data.view_direction = start_direction; + pv_game_camera_data.up_vec = start.up_vec; + + mat4_from_two_vectors(&start_direction, &end_direction, &pv_game_camera_data.dir_mat); + mat4_from_two_vectors(&start.up_vec, &end.up_vec, &pv_game_camera_data.up_mat); + } + + pv_game_camera_data.duration = duration; + pv_game_camera_data.curr_time = 0.0f; + + if (follow_chara) { + pv_game_camera_data.follow_chara = true; + pv_game_camera_data.chara_id = chara_id; + + switch (chara_follow_point) { + case 0: + pv_game_camera_data.chara_follow_point = 4; + break; + case 1: + pv_game_camera_data.chara_follow_point = 1; + break; + default: + pv_game_camera_data.chara_follow_point = 0; + break; + } + } + + pv_game_camera_data.enable = true; + pv_game_camera_data.field_F4 = 0; + pv_game_camera_data.acceleration = 0.0f; + pv_game_camera_data.acceleration_curr_time = 0.0f; + pv_game_camera_data.acceleration_1 = acceleration_1; + pv_game_camera_data.acceleration_2 = acceleration_2; +} + +void pv_game_camera_set_fov_min_dist(float_t fov, float_t min_dist) { + pv_game_camera_data.fov = fov; + pv_game_camera_data.min_dist = min_dist; +} + +static float_t sub_14011B160(float_t acceleration_1, float_t acceleration_2, float_t t) { + if (acceleration_2 == 1.0f) + return 1.0f; + if (acceleration_1 == 0.0) + return cosf(t * (float_t)M_PI) * (acceleration_2 - 1.0f) + 1.0f; + else if (acceleration_1 == 1.0f) + return cosf(t * (float_t)M_PI + (float_t)M_PI) + * fabsf((float_t)(int32_t)(1.0f - acceleration_2)) + 1.0f; + else if (t < acceleration_1) + return 2.0f - (cosf((t / acceleration_1) * (float_t)M_PI) + * (acceleration_2 - 1.0f) + 1.0f); + else + return cosf((t - acceleration_1) / (1.0f - acceleration_1) + * (float_t)M_PI + (float_t)M_PI) * (1.0f - acceleration_2) + 1.0f; +} + +static float_t pv_game_camera_get_acceleration() { + bool v2 = false; + float_t curr_time = pv_game_camera_data.curr_time; + float_t v5 = 1.0f / pv_game_camera_data.duration; + float_t acceleration_1 = pv_game_camera_data.acceleration_1; + float_t acceleration_2 = pv_game_camera_data.acceleration_2; + float_t acceleration = pv_game_camera_data.acceleration; + float_t acceleration_curr_time = pv_game_camera_data.acceleration_curr_time; + while (acceleration_curr_time < curr_time) { + float_t delta_time = 0.005f; + if (v2) + delta_time = 0.0005f; + else if (acceleration_curr_time + 0.005f >= curr_time) { + v2 = true; + delta_time = 0.0005f; + } + acceleration_curr_time += delta_time; + acceleration += sub_14011B160(acceleration_1, acceleration_2, + v5 * acceleration_curr_time) * (v5 * delta_time); + pv_game_camera_data.acceleration_curr_time = acceleration_curr_time; + pv_game_camera_data.acceleration = acceleration; + } + return min_def(acceleration, 1.0f); +} + +static bool pv_game_camera_get_edit_camera(cam_struct* cam, float_t delta_time) { + if (!cam) + return false; + + pv_game_camera_data.curr_time += delta_time; + + vec3 interest; + vec3 view_point; + bool in_transition; + if (pv_game_camera_data.duration == 0.0f + || pv_game_camera_data.duration <= pv_game_camera_data.curr_time) { + view_point = pv_game_camera_data.view_point_start; + interest = pv_game_camera_data.interest_start; + in_transition = false; + } + else { + float_t t = pv_game_camera_get_acceleration(); + interest = vec3::lerp(pv_game_camera_data.interest_start, pv_game_camera_data.interest_end, t); + view_point = vec3::lerp(pv_game_camera_data.view_point_start, pv_game_camera_data.view_point_end, t); + in_transition = true; + } + + if (pv_game_camera_data.follow_chara) { + rob_chara* rob_chr = rob_chara_array_get(pv_game_camera_data.chara_id); + if (rob_chr) + mat4_get_translation(&rob_chr->data.field_1E68.field_78[ + pv_game_camera_data.chara_follow_point], &interest); + } + + cam->interest = interest; + cam->view_point = view_point; + return in_transition; +} + +static bool pv_game_camera_get_move_camera(cam_struct* cam, float_t delta_time) { + if (!cam) + return false; + + mat4 dir_mat; + mat4 up_mat; + vec3 interest; + vec3 view_point; + float_t distance; + bool in_transition; + if (pv_game_camera_data.duration == 0.0f + || pv_game_camera_data.duration <= pv_game_camera_data.curr_time) { + dir_mat = pv_game_camera_data.dir_mat; + up_mat = pv_game_camera_data.up_mat; + view_point = pv_game_camera_data.view_point_end; + interest = pv_game_camera_data.interest_end; + distance = pv_game_camera_data.end_distance; + in_transition = false; + } + else { + float_t t = pv_game_camera_get_acceleration(); + mat4_blend(&mat4_identity, &pv_game_camera_data.dir_mat, &dir_mat, t); + mat4_blend(&mat4_identity, &pv_game_camera_data.up_mat, &up_mat, t); + distance = ((pv_game_camera_data.end_distance - pv_game_camera_data.start_distance) * t) + + pv_game_camera_data.start_distance; + interest = vec3::lerp(pv_game_camera_data.interest_start, pv_game_camera_data.interest_end, t); + view_point = vec3::lerp(pv_game_camera_data.view_point_start, pv_game_camera_data.view_point_end, t); + distance = lerp_def(pv_game_camera_data.start_distance, pv_game_camera_data.end_distance, t); + in_transition = true; + } + + if (pv_game_camera_data.follow_chara) { + rob_chara* rob_chr = rob_chara_array_get(pv_game_camera_data.chara_id); + if (rob_chr) + mat4_get_translation(&rob_chr->data.field_1E68.field_78[ + pv_game_camera_data.chara_follow_point], &interest); + } + + if (!pv_game_camera_data.follow_chara) { + vec3 direction; + mat4_mult_vec3(&dir_mat, &pv_game_camera_data.view_direction, &direction); + view_point = direction * distance + interest; + } + + cam->interest = interest; + cam->view_point = view_point; + + mat4_mult_vec3(&up_mat, &pv_game_camera_data.up_vec, &cam->up); + cam->use_up = true; + return in_transition; +} diff --git a/src/ReDIVA/pv_game/pv_game_camera.hpp b/src/ReDIVA/pv_game/pv_game_camera.hpp new file mode 100644 index 00000000..3c333a06 --- /dev/null +++ b/src/ReDIVA/pv_game/pv_game_camera.hpp @@ -0,0 +1,24 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#pragma once + +#include "../../KKdLib/default.hpp" +#include "../../KKdLib/vec.hpp" + +struct pv_game_camera_dsc_data { + vec3 view_point; + vec3 interest; + vec3 up_vec; + + pv_game_camera_dsc_data(); +}; + +extern void pv_game_camera_ctrl(float_t delta_time); +extern void pv_game_camera_reset(); +extern void pv_game_camera_set_dsc_data(float_t duration, pv_game_camera_dsc_data& start, + pv_game_camera_dsc_data& end, float_t acceleration_1, float_t acceleration_2, + int32_t follow_chara, int32_t chara_id, int32_t chara_follow_point, bool edit_camera); +extern void pv_game_camera_set_fov_min_dist(float_t fov, float_t min_dist); diff --git a/src/ReDIVA/pv_game/pv_game_music.cpp b/src/ReDIVA/pv_game/pv_game_music.cpp new file mode 100644 index 00000000..dc0fe50c --- /dev/null +++ b/src/ReDIVA/pv_game/pv_game_music.cpp @@ -0,0 +1,462 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#include "pv_game_music.hpp" + +pv_game_music* pv_game_music_ptr; + +pv_game_music_args::pv_game_music_args() : type(), start(), field_2C() { + +} + +pv_game_music_args::~pv_game_music_args() { + +} + +pv_game_music_ogg::pv_game_music_ogg() : playback() { + playback = ogg_playback_data_get(0); +} + +pv_game_music_ogg::~pv_game_music_ogg() { + if (playback) { + playback->Reset(); + playback = 0; + } +} + +pv_game_music::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; +} + +pv_game_music::~pv_game_music() { + +} + +bool 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 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 = 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.0f) + 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)((float_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 & 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 pv_game_music::exclude_flags(pv_game_music_flags flags) { + if ((this->flags & PV_GAME_MUSIC_OGG) && (flags & PV_GAME_MUSIC_OGG)) + ogg_free(); + enum_and(this->flags, ~flags); +} + +void 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 PV_GAME_MUSIC_ACTION_STOP: + stop(); + break; + case PV_GAME_MUSIC_ACTION_PAUSE: + set_pause(1); + break; + case PV_GAME_MUSIC_ACTION_PLAY: + play(); + break; + } +} + +void 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 PV_GAME_MUSIC_ACTION_STOP: + stop(); + break; + case PV_GAME_MUSIC_ACTION_PAUSE: + set_pause(1); + break; + case PV_GAME_MUSIC_ACTION_PLAY: + play(); + break; + } +} + +void 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 = 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.0f; + fade_out.action = play_on_end + ? PV_GAME_MUSIC_ACTION_PLAY : 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 + ? PV_GAME_MUSIC_ACTION_PLAY : PV_GAME_MUSIC_ACTION_STOP; + } +} + +int32_t pv_game_music::get_master_volume(int32_t index) { + if (!index) + return master_volume; + return 0; +} + +int32_t pv_game_music::get_volume(int32_t index) { + if (!index) + return volume; + return 0; +} + +int32_t pv_game_music::include_flags(pv_game_music_flags flags) { + if (!(this->flags & PV_GAME_MUSIC_OGG) && (flags & PV_GAME_MUSIC_OGG)) + ogg_init(); + enum_or(this->flags, flags); + return 0; +} + +int32_t 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 pv_game_music::ogg_free() { + if (ogg) { + delete ogg; + ogg = 0; + } +} + +int32_t pv_game_music::ogg_init() { + if (ogg) + return 0; + + ogg = new pv_game_music_ogg; + return ogg->playback ? 0 : -1; +} + +int32_t pv_game_music::ogg_load(std::string&& file_path, float_t start) { + if (!(flags & 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 pv_game_music::ogg_reset() { + sound_stream_array_reset(); + include_flags(PV_GAME_MUSIC_OGG); + return 0; +} + +int32_t pv_game_music::ogg_stop() { + if (!(flags & PV_GAME_MUSIC_OGG)) + return -2; + + ogg->playback->Stop(); + ogg->file_path.clear(); + loaded = false; + return 0; +} + +int32_t 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 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 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 pv_game_music::play_or_stop() { + if (play_on_end) + return play(); + else + return stop(); +} + +void 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 = 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 pv_game_music::reset_args() { + args.type = 0; + args.file_path.clear(); + args.start = 0.0f; + args.field_2C = false; +} + +void 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 pv_game_music::set_channel_pair_volume(int32_t channel_pair, int32_t value) { + if (!(flags & PV_GAME_MUSIC_OGG)) + return -2; + + ogg->playback->SetChannelPairVolume(channel_pair, ratio_to_db((float_t)value * 0.01f)); + return 0; +} + +int32_t 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 pv_game_music::set_fade_out(float_t time, bool stop) { + reset(); + if (time == 0.0f) + 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 ? PV_GAME_MUSIC_ACTION_STOP + : PV_GAME_MUSIC_ACTION_PAUSE; + } + return 0; +} + +int32_t pv_game_music::set_master_volume(int32_t value) { + if (!(flags & 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 pv_game_music::set_ogg_args(std::string&& file_path, float_t start, bool wait_load) { + if (!(flags & 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 pv_game_music::set_ogg_pause_state(uint8_t pause_state) { + if ((flags & PV_GAME_MUSIC_OGG) == 0) + return -2; + + OggPlayback* playback = ogg->playback; + if (playback->GetFileState() == OGG_FILE_HANDLER_FILE_STATE_PLAYING) + playback->SetPauseState((OggFileHandlerPauseState)pause_state); + return 0; +} + +int32_t pv_game_music::set_pause(int32_t pause) { + if ((flags & PV_GAME_MUSIC_OGG) != 0) + set_ogg_pause_state(pause != 0); + pause = pause == 1; + return 0; +} + +void pv_game_music::set_volume_map(int32_t index, int32_t value) { + if (!index) { + if (flags & PV_GAME_MUSIC_OGG) + set_master_volume(value); + volume = value; + } +} + +int32_t pv_game_music::stop() { + if (flags & PV_GAME_MUSIC_OGG) + ogg_stop(); + reset(); + reset_args(); + pause = false; + return 0; +} + +void pv_game_music::stop_reset_flags() { + stop(); + exclude_flags(PV_GAME_MUSIC_ALL); +} + +void pv_game_music_init() { + if (!pv_game_music_ptr) + pv_game_music_ptr = new pv_game_music; +} + +pv_game_music* pv_game_music_get() { + return pv_game_music_ptr; +} + +void pv_game_music_free() { + if (pv_game_music_ptr) { + delete pv_game_music_ptr; + pv_game_music_ptr = 0; + } +} diff --git a/src/ReDIVA/pv_game/pv_game_music.hpp b/src/ReDIVA/pv_game/pv_game_music.hpp new file mode 100644 index 00000000..3fd9c9af --- /dev/null +++ b/src/ReDIVA/pv_game/pv_game_music.hpp @@ -0,0 +1,125 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#pragma once + +#include "../../KKdLib/default.hpp" +#include "../../CRE/ogg_vorbis.hpp" + +enum pv_game_music_action { + PV_GAME_MUSIC_ACTION_NONE = 0, + PV_GAME_MUSIC_ACTION_STOP, + PV_GAME_MUSIC_ACTION_PAUSE, + PV_GAME_MUSIC_ACTION_PLAY, + PV_GAME_MUSIC_ACTION_MAX, +}; + +enum pv_game_music_flags : uint8_t { + PV_GAME_MUSIC_FLAG_1 = 0x01, + PV_GAME_MUSIC_AIX = 0x02, + PV_GAME_MUSIC_OGG = 0x04, + PV_GAME_MUSIC_FLAG_8 = 0x08, + PV_GAME_MUSIC_FLAG_10 = 0x10, + PV_GAME_MUSIC_FLAG_20 = 0x20, + PV_GAME_MUSIC_FLAG_40 = 0x40, + PV_GAME_MUSIC_FLAG_80 = 0x80, + + PV_GAME_MUSIC_ALL = 0xFF, +}; + +struct pv_game_music_fade { + int32_t start; + int32_t value; + float_t time; + float_t remain; + pv_game_music_action action; + bool enable; +}; + +struct pv_game_music_args { + int32_t type; + std::string file_path; + float_t start; + bool field_2C; + + pv_game_music_args(); + ~pv_game_music_args(); +}; + +struct pv_game_music_ogg { + OggPlayback* playback; + std::string file_path; + + pv_game_music_ogg(); + ~pv_game_music_ogg(); +}; + +struct pv_game_music { + pv_game_music_flags flags; + bool pause; + int32_t volume; + int32_t master_volume; + int32_t channel_pair_volume[4]; + pv_game_music_fade fade_in; + pv_game_music_fade fade_out; + bool no_fade; + float_t no_fade_remain; + float_t fade_out_time_req; + pv_game_music_action fade_out_action_req; + int32_t type; + std::string file_path; + float_t start; + float_t end; + bool play_on_end; + float_t fade_in_time; + float_t fade_out_time; + bool field_9C; + pv_game_music_args args; + bool loaded; + pv_game_music_ogg* ogg; + + pv_game_music(); + ~pv_game_music(); + + bool check_args(int32_t type, std::string&& file_path, float_t start); + void ctrl(float_t delta_time); + void exclude_flags(pv_game_music_flags flags); + void fade_in_end(); + void fade_out_end(); + void 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); + int32_t get_master_volume(int32_t index); + int32_t get_volume(int32_t index); + int32_t include_flags(pv_game_music_flags flags); + int32_t load(int32_t type, std::string&& file_path, bool wait_load, float_t time, bool a6); + void ogg_free(); + int32_t ogg_init(); + int32_t ogg_load(std::string&& file_path, float_t start); + int32_t ogg_reset(); + int32_t ogg_stop(); + int32_t play(); + int32_t 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); + void 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); + int32_t play_or_stop(); + void reset(); + void reset_args(); + void set_args(int32_t type, std::string&& file_path, float_t start, bool a5); + int32_t set_channel_pair_volume(int32_t channel_pair, int32_t value); + int32_t set_channel_pair_volume_map(int32_t channel_pair, int32_t value); + int32_t set_fade_out(float_t time, bool stop); + int32_t set_master_volume(int32_t value); + int32_t set_ogg_args(std::string&& file_path, float_t start, bool wait_load); + int32_t set_ogg_pause_state(uint8_t pause_state); + int32_t set_pause(int32_t pause); + void set_volume_map(int32_t index, int32_t value); + int32_t stop(); + void stop_reset_flags(); +}; + +extern void pv_game_music_init(); +extern pv_game_music* pv_game_music_get(); +extern void pv_game_music_free(); diff --git a/src/ReDIVA/pv_game/pv_game_play_data.cpp b/src/ReDIVA/pv_game/pv_game_play_data.cpp new file mode 100644 index 00000000..e8ab4536 --- /dev/null +++ b/src/ReDIVA/pv_game/pv_game_play_data.cpp @@ -0,0 +1,2217 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#include "pv_game_play_data.hpp" +#include "game_2d.hpp" +#include "player_data.hpp" +#include "pv_game.hpp" +#include "target_pos.hpp" + +const float_t percentage_clear_excellent[] = { + 80.0f, 85.0f, 90.0f, 95.0f, 97.0f +}; + +const float_t percentage_clear_great[] = { + 65.0f, 75.0f, 80.0f, 85.0f, 90.0f +}; + +const char* spr_black_fade[] = { + "black_fade", +}; + +const char* spr_chance_frame_bottom[] = { + "chance_frame_bottom", +}; + +const char* spr_chance_frame_top[] = { + "chance_frame_top", +}; + +const char* spr_chance_point[] = { + "chance_point_even", + "chance_point_odd", +}; + +const char* spr_chance_txt[] = { + "chance_start_txt", + "chance_end_txt", +}; + +const char* spr_combo_cool_fine[] = { + "combo_cool001", + "combo_cool010", + "combo_cool100", + "combo_cool100_b", + "combo_cool1000", + "combo_fine001", + "combo_fine010", + "combo_fine100", + "combo_fine100_b", + "combo_fine1000", +}; + +const char* spr_combo_just_cool_fine[] = { + "combo_just_cool001", + "combo_just_cool010", + "combo_just_cool100", + "combo_just_cool100_b", + "combo_just_cool1000", + "combo_fine001", + "combo_fine010", + "combo_fine100", + "combo_fine100_b", + "combo_fine1000", +}; + +const char* spr_combo_tempo_cool_fine[] = { + "combo_tempo_cool001", + "combo_tempo_cool010", + "combo_tempo_cool100", + "combo_tempo_cool100_b", + "combo_tempo_cool1000", + "combo_tempo_fine001", + "combo_tempo_fine010", + "combo_tempo_fine100", + "combo_tempo_fine100_b", + "combo_tempo_fine1000", +}; + +const char* spr_demo_font[] = { + "demo_font", +}; + +const char* spr_demo_logo[] = { + "demo_logo", +}; + +const char* spr_failed_info[] = { + "failed_info", +}; + +const char* spr_frame[] = { + "frame_bottom", + "frame_up", + "frame_bottom_danger", + "frame_up_danger", +}; + +const char* spr_level_info[] = { + "level_info_easy", + "level_info_normal", + "level_info_hard", + "level_info_extreme", + "level_info_encore", +}; + +const char* spr_level_info_ctst[] = { + "level_info_easy_ctst", + "level_info_normal_ctst", + "level_info_hard_ctst", + "level_info_extreme_ctst", + "level_info_extreme_ctst", +}; + +const char* spr_level_info_ctst_extra[] = { + "level_info_easy_ctst", + "level_info_normal_ctst", + "level_info_hard_ctst", + "level_info_extreme_extra_ctst", + "level_info_extreme_ctst", +}; + +const char* spr_level_info_extra[] = { + "level_info_easy", + "level_info_normal", + "level_info_hard", + "level_info_extreme_extra", + "level_info_encore", +}; + +const char* spr_level_info_insu[] = { + "level_info_easy_insu", + "level_info_normal_insu", + "level_info_hard_insu", + "level_info_extreme_insu", + "level_info_extreme_insu", +}; + +const char* spr_level_info_insu_extra[] = { + "level_info_easy_insu", + "level_info_normal_insu", + "level_info_hard_insu", + "level_info_extreme_extra_insu", + "level_info_extreme_insu", +}; + +const char* spr_max_slide_num[] = { + "max_slide_num_00", + "max_slide_num_01", + "max_slide_num_02", + "max_slide_num_03", + "max_slide_num_04", + "max_slide_num_05", + "max_slide_num_06", + "max_slide_num_07", + "max_slide_num_08", + "max_slide_num_09", +}; + +const char* spr_max_slide_num_plus[] = { + "max_slide_num_plus", +}; + +const char* spr_max_slide_point[] = { + "max_slide_point_even", + "max_slide_point_odd", +}; + +const char* spr_next_info[] = { + "next_info", +}; + +const char* spr_option_info_base[] = { + "option_info_base", +}; + +const char* spr_option_info_hidden[] = { + "option_info_hispeed_a", + "option_info_hispeed_b", +}; + +const char* spr_option_info_hispeed[] = { + "option_info_hidden_a", + "option_info_hidden_b", +}; + +const char* spr_option_info_sudden[] = { + "option_info_sudden_a", + "option_info_sudden_b", +}; + +const char* spr_p_chance_point_num[] = { + "p_chance_point_num01_c", + "p_chance_point_num02_c", + "p_chance_point_num03_c", + "p_chance_point_num04_c", + "p_chance_point_num05_c", + "p_chance_point_num06_c", + "p_chance_point_num07_c", +}; + +const int32_t spr_p_chance_point_num_spr[] = { + 391, 399, 400, 401, 402, 403, 404, 405, 406, 407, 392, +}; + +const char* spr_p_chance_rslt_num[] = { + "p_chance_rslt_num01_c", + "p_chance_rslt_num02_c", + "p_chance_rslt_num03_c", + "p_chance_rslt_num04_c", + "p_chance_rslt_num05_c", + "p_chance_rslt_num06_c", +}; + +const int32_t spr_p_chance_rslt_num_spr[] = { + 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, +}; + +const char* spr_p_energy_num[] = { + "p_energy_num01_c", + "p_energy_num02_c", + "p_energy_num03_c", + "p_energy_num04_c", + "p_energy_num05_c", + "p_energy_num06_c", + "p_energy_num07_c", +}; + +const int32_t spr_p_energy_num_spr[] = { + 1535, 1536, 1537, 1538, 1539, 1540, 1541, 1542, 1543, 1544, 1545, 3092, +}; + +const int32_t spr_p_energy_reach_num_spr[] = { + 1546, 1547, 1548, 1549, 1550, 1551, 1552, 1553, 1554, 1555, 1556, 3093, +}; + +const char* spr_p_combo_num[] = { + "p_combo_num001_c", + "p_combo_num010_c", + "p_combo_num100_c", + "p_combo_num1000_c", +}; + +const int32_t spr_p_combo_num_spr[] = { + 3210, 3211, 3212, 3213, 3214, 3215, 3216, 3217, 3218, 3219, +}; + +const char* spr_p_score[] = { + "p_score01_c", + "p_score02_c", + "p_score03_c", + "p_score04_c", + "p_score05_c", + "p_score06_c", + "p_score07_c", +}; + +const int32_t spr_p_score_spr[] = { + 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, +}; + +const int32_t spr_p_slide_point_num_spr[] = { + 34076, 34077, 34078, 34079, 34080, 34081, 34082, 34083, 34084, 34085, 34086, +}; + +const char* spr_p_song_lt[] = { + "p_song_lyric_lt", + "p_song_title_lt", +}; + +const char* spr_song_energy_base[] = { + "song_energy_base", +}; + +const char* spr_song_energy_base_reach[] = { + "song_energy_base_reach", +}; + +const char* spr_song_energy_border[] = { + "song_energy_border", +}; + +const char* spr_song_energy_border_excellent[] = { + "song_energy_border_excellent", +}; + +const char* spr_song_energy_border_great[] = { + "song_energy_border_great", +}; + +const char* spr_song_energy_border_rival[] = { + "song_energy_border_rival", +}; + +const char* spr_song_energy_clear_txt[] = { + "song_energy_clear_txt", +}; + +const char* spr_song_energy_edge_line02[] = { + "song_energy_edge_line02", +}; + +const char* spr_song_energy_eff_normal[] = { + "song_energy_eff_normal", +}; + +const char* spr_song_energy_eff_reach[] = { + "song_energy_eff_reach", +}; + +const char* spr_song_energy_full[] = { + "song_energy_full", +}; + +const char* spr_song_energy_normal[] = { + "song_energy_normal", +}; + +const char* spr_song_energy_not_clear[] = { + "song_energy_not_clear", +}; + +const char* spr_song_energy_not_clear_txt[] = { + "song_energy_not_clear_txt", +}; + +const char* spr_song_energy_reach[] = { + "song_energy_reach", +}; + +const char* spr_song_icon_loop[] = { + "song_icon_loop", +}; + +const char* spr_stage_info[] = { + "stage_info01", + "stage_info02", + "stage_info03", + "stage_info04", +}; + +const char* spr_success_info[] = { + "success_info", +}; + +const char* spr_value_text[] = { + "value_text_cool04", + "value_text_wrong01", + "value_text_fine01", + "value_text_wrong02", + "value_text_safe", + "value_text_wrong03", + "value_text_sad", + "value_text_wrong04", + "value_text_worst", +}; + +const char* spr_value_text_early[] = { + "value_text_cool01", + "value_text_wrong01", + "value_text_fine01", + "value_text_wrong02", + "value_text_safe", + "value_text_wrong03", + "value_text_sad", + "value_text_wrong04", + "value_text_worst", +}; + +const char* spr_value_text_late[] = { + "value_text_cool03", + "value_text_wrong01", + "value_text_fine03", + "value_text_wrong02", + "value_text_safe", + "value_text_wrong03", + "value_text_sad", + "value_text_wrong04", + "value_text_worst", +}; + +const char* spr_white_fade[] = { + "white_fade", +}; + +pv_disp2d::pv_disp2d() : pv_id(), title_start_2d_field(), title_end_2d_field(), +title_start_2d_low_field(), title_end_2d_low_field(), title_start_3d_field(), title_end_3d_field(), +target_shadow_type(), pv_spr_set_id(), pv_aet_set_id(), pv_aet_id() { + +} + +pv_disp2d::~pv_disp2d() { + +} + +pv_game_play_data::pv_game_play_data() : pv_set(), aet_ids(), aet_ids_enable(), field_1C8(), field_1D0(), +field_1D8(), field_1E0(), field_1E8(), field_1F0(), field_1F8(), field_1FC(), field_204(), field_20C(), +frame_state(), field_218(), fade_begin(), fade_end(), fade(), skin_danger_frame(), field_2FC(), +chance_result(), chance_points(), field_310(), slide_points(), max_slide_points(), pv_spr_set_id(), +pv_aet_set_id(), pv_aet_id(), stage_index(), field_33C(), field_350(), field_354(), value_text_spr_index(), +not_clear(), spr_set_back_id(), loaded(), state(), field_36C(), update(), field_374(), field_378(), +field_37C(), score_speed(), score(), value_text_display(), field_38C(), value_text_index(), +value_text_time_offset(), combo_state(), combo_count(), combo_disp_time(), field_3AC(), field_3B0(), +field_3B4(), field_3B8(), field_3BC(), aix(), ogg(), field_3C4(), ex_song_index(), field_5EC(), option(), +field_5F4(), lyric(), lyric_set(), field_64C(), field_650(), field_654(), field_658(), field_65C() { + chance_points_pos = 0; + slide_points_pos = 0; + max_slide_points_pos = 0; + reset(); + state = 0; +} + +pv_game_play_data::~pv_game_play_data() { + +} + +void pv_game_play_data::combo_ctrl(float_t delta_time) { + switch (combo_state) { + case 0: + combo_disp_time = 0.0f; + combo_state = 1; + break; + case 1: + if (combo_disp_time >= 0.05f) { + combo_disp_time = 0.0f; + combo_state = 2; + } + else + combo_disp_time += delta_time; + return; + case 2: + if (combo_disp_time >= 0.04f) { + combo_disp_time = 0.0f; + combo_state = 3; + } + else + combo_disp_time += delta_time; + return; + case 3: + if (combo_disp_time >= 0.2f) { + combo_disp_time = 0.0f; + combo_state = 4; + } + else + combo_disp_time += delta_time; + return; + case 4: + default: + if (aet_manager_get_obj_end(aet_ids[PV_GAME_AET_COMBO])) + aet_manager_free_aet_object_reset(&aet_ids[PV_GAME_AET_COMBO]); + break; + } + +} + +void pv_game_play_data::disable_update() { + if (loaded) + update = false; +} + +void pv_game_play_data::disp() { + if (loaded && !field_354) { + sub_1401349B0(); + field_354 = true; + } + + disp_combo(); + disp_chance_point(); + disp_chance_txt(); + disp_slide_point(); + disp_max_slide_point(); + disp_score(); + disp_song_energy(); + disp_spr_set_back(); +} + +void pv_game_play_data::disp_chance_point() { + if (!aet_ids[PV_GAME_AET_CHANCE_POINT]) + return; + + data_struct* aft_data = &data_list[DATA_AFT]; + aet_database* aft_aet_db = &aft_data->data_ft.aet_db; + sprite_database* aft_spr_db = &aft_data->data_ft.spr_db; + + int32_t digits = get_digit_count(chance_points, 6); + + int32_t chance_point; + int32_t v5; + if ((digits + 1) % 2) { + chance_point = 1; + v5 = 6 - digits; + } + else { + chance_point = 0; + v5 = 5 - digits; + } + + aet_manager_init_aet_layout(&comp, 3, spr_chance_point[chance_point], (AetFlags)0, RESOLUTION_MODE_HD, + 0, aet_manager_get_obj_frame(aet_ids[PV_GAME_AET_CHANCE_POINT]), aft_aet_db, aft_spr_db); + + vec2 pos; + target_pos_scale_offset_apply(&chance_points_pos, &pos); + + aet_layout_data* layout = comp.Find((&spr_p_chance_point_num[v5 / 2])[digits]); + if (layout) + aet_layout_data::put_sprite(392, spr::SPR_ATTR_CTR_CC, spr::SPR_PRIO_16, &pos, layout, aft_spr_db); + + AetComp::put_number_sprite(chance_points, 7, &comp, &spr_p_chance_point_num[v5 / 2], + spr_p_chance_point_num_spr, spr::SPR_PRIO_16, &pos, 0, aft_spr_db); +} + +void pv_game_play_data::disp_chance_points(int32_t chance_points, float_t pos_x, float_t pos_y) { + pos_y = max_def(pos_y, 58.0f); + + chance_points = chance_points; + chance_points_pos.x = pos_x; + chance_points_pos.y = pos_y; + init_aet_chance_point(chance_points, pos_x, pos_y); +} + +void pv_game_play_data::disp_chance_txt() { + if (!aet_ids[PV_GAME_AET_CHANCE_TXT] || !field_378 || field_374 < 4) + return; + + int32_t digits = 6; + while (digits) { + if (digits > 1) { + int32_t div = 10; + int32_t v6 = digits - 2; + while (v6) { + div *= 10; + v6--; + } + + if (chance_result / div % 10) + break; + } + else if (chance_result % 10) + break; + digits--; + }; + + if (!digits) + return; + + data_struct* aft_data = &data_list[DATA_AFT]; + aet_database* aft_aet_db = &aft_data->data_ft.aet_db; + sprite_database* aft_spr_db = &aft_data->data_ft.spr_db; + + vec2 pos = { ((float_t)(6 - digits) * field_350) * -0.5f, 0.0f }; + aet_manager_init_aet_layout(&comp, 3, spr_chance_txt[1], (AetFlags)0, RESOLUTION_MODE_HD, + 0, aet_manager_get_obj_frame(aet_ids[PV_GAME_AET_CHANCE_TXT]), aft_aet_db, aft_spr_db); + AetComp::put_number_sprite(chance_result, 6, &comp, spr_p_chance_rslt_num, + spr_p_chance_rslt_num_spr, spr::SPR_PRIO_06, &pos, 0, aft_spr_db); +} + +void pv_game_play_data::disp_combo() { + if (!aet_ids[PV_GAME_AET_COMBO]) + return; + + data_struct* aft_data = &data_list[DATA_AFT]; + aet_database* aft_aet_db = &aft_data->data_ft.aet_db; + sprite_database* aft_spr_db = &aft_data->data_ft.spr_db; + + const char* name; + if (value_text_time_offset < -(float_t)(1.0 / 120.0)) + name = spr_combo_tempo_cool_fine[value_text_spr_index]; + else if (value_text_time_offset > (float_t)(1.0 / 120.0)) + name = spr_combo_cool_fine[value_text_spr_index]; + else + name = spr_combo_just_cool_fine[value_text_spr_index]; + + AetComp comp; + aet_manager_init_aet_layout(&comp, 3, name, (AetFlags)0, RESOLUTION_MODE_HD, + 0, aet_manager_get_obj_frame(aet_ids[PV_GAME_AET_COMBO]), aft_aet_db, aft_spr_db); + + vec2 pos; + target_pos_scale_offset_apply(&combo_pos, &pos); + AetComp::put_number_sprite(combo_count, 4, &comp, spr_p_combo_num, + spr_p_combo_num_spr, spr::SPR_PRIO_14, &pos, false, aft_spr_db); +} + +void pv_game_play_data::disp_max_slide_point() { + if (!aet_ids[PV_GAME_AET_MAX_SLIDE_POINT]) + return; + + data_struct* aft_data = &data_list[DATA_AFT]; + aet_database* aft_aet_db = &aft_data->data_ft.aet_db; + sprite_database* aft_spr_db = &aft_data->data_ft.spr_db; + + int32_t digits = get_digit_count(max_slide_points, 6); + + int32_t max_slide_point; + int32_t v5; + if ((digits + 1) % 2) { + max_slide_point = 1; + v5 = 6 - digits; + } + else { + max_slide_point = 0; + v5 = 5 - digits; + } + + AetComp comp; + aet_manager_init_aet_layout(&comp, 3, + spr_max_slide_point[max_slide_point], (AetFlags)0, RESOLUTION_MODE_HD, 0, + aet_manager_get_obj_frame(aet_ids[PV_GAME_AET_MAX_SLIDE_POINT]), aft_aet_db, aft_spr_db); + + vec2 pos; + target_pos_scale_offset_apply(&this->max_slide_points_pos, &pos); + + aet_layout_data* layout = comp.Find((&spr_p_chance_point_num[v5 / 2])[digits]); + if (layout) { + vec3 position; + position.x = pos.x + layout->position.x; + position.y = pos.y + layout->position.y; + position.z = 0.0f; + if (aet_ids[PV_GAME_AET_MAX_SLIDE_NUM_PLUS]) + aet_manager_set_obj_position(aet_ids[PV_GAME_AET_MAX_SLIDE_NUM_PLUS], position); + } + + int32_t max_slide_points = this->max_slide_points; + for (int32_t i = 0; i < 7; i++) { + max_slide_points /= 10; + aet_layout_data* layout = comp.Find((&spr_p_chance_point_num[v5 / 2])[i]); + if (layout) { + vec3 position; + position.x = pos.x + layout->position.x; + position.y = pos.y + layout->position.y; + position.z = 0.0f; + if (aet_ids[PV_GAME_AET_MAX_SLIDE_NUM + i]) + aet_manager_set_obj_position(aet_ids[PV_GAME_AET_MAX_SLIDE_NUM + i], position); + } + + if (!max_slide_points) + break; + } +} + +void pv_game_play_data::disp_score() { + if (!(aet_ids[PV_GAME_AET_FRAME_BOTTOM] || aet_ids[PV_GAME_AET_BOTTOM_BACK]) || !field_1F8[0]) + return; + + data_struct* aft_data = &data_list[DATA_AFT]; + sprite_database* aft_spr_db = &aft_data->data_ft.spr_db; + + vec2 pos = { 0.0f, field_1C8[0] }; + AetComp::put_number_sprite(score, 7, &comp, spr_p_score, + spr_p_score_spr, spr::SPR_PRIO_11, &pos, true, aft_spr_db); +} + +void pv_game_play_data::disp_slide_point() { + if (!aet_ids[PV_GAME_AET_SLIDE_POINT]) + return; + + data_struct* aft_data = &data_list[DATA_AFT]; + aet_database* aft_aet_db = &aft_data->data_ft.aet_db; + sprite_database* aft_spr_db = &aft_data->data_ft.spr_db; + + int32_t digits = get_digit_count(slide_points, 6); + + int32_t chance_point; + int32_t v5; + if ((digits + 1) % 2) { + chance_point = 1; + v5 = 6 - digits; + } + else { + chance_point = 0; + v5 = 5 - digits; + } + + aet_manager_init_aet_layout(&comp, 3, spr_chance_point[chance_point], (AetFlags)0, RESOLUTION_MODE_HD, + 0, aet_manager_get_obj_frame(aet_ids[PV_GAME_AET_SLIDE_POINT]), aft_aet_db, aft_spr_db); + + vec2 pos; + target_pos_scale_offset_apply(&slide_points_pos, &pos); + aet_layout_data* layout = comp.Find((&spr_p_chance_point_num[v5 / 2])[digits]); + if (layout) + aet_layout_data::put_sprite(34086, spr::SPR_ATTR_CTR_CC, spr::SPR_PRIO_16, &pos, layout, aft_spr_db); + AetComp::put_number_sprite(slide_points, 7, &comp, &spr_p_chance_point_num[v5 / 2], + spr_p_slide_point_num_spr, spr::SPR_PRIO_16, &pos, 0, aft_spr_db); +} + +void pv_game_play_data::disp_slide_points(int32_t max_slide_point, float_t pos_x, float_t pos_y, bool max_slide) { + pos_y = max_def(pos_y, 48.0f); + + if (max_slide) { + max_slide_points_pos.x = pos_x; + max_slide_points_pos.y = pos_y; + max_slide_points = max_slide_point; + init_aet_slide_max(max_slide_point, pos_x, pos_y); + } + else { + slide_points_pos.x = pos_x; + slide_points_pos.y = pos_y; + slide_points = max_slide_point; + init_aet_slide_point(max_slide_point, pos_x, pos_y); + } +} + +void pv_game_play_data::disp_song_energy() { + if (!(aet_ids[PV_GAME_AET_FRAME_BOTTOM] || aet_ids[PV_GAME_AET_BOTTOM_BACK]) || !field_1F8[0]) + return; + + data_struct* aft_data = &data_list[DATA_AFT]; + sprite_database* aft_spr_db = &aft_data->data_ft.spr_db; + + pv_game* pv_game = pv_game_get(); + const int32_t* spr; + if (pv_game->data.song_energy < pv_game->data.song_energy_base) + spr = spr_p_energy_num_spr; + else + spr = spr_p_energy_reach_num_spr; + + int32_t song_energy = (int32_t)(pv_game->data.song_energy * 100.0f); + vec2 pos = { 0.0f, field_1F0[0] }; + AetComp::put_number_sprite(song_energy / 100, 3, &comp, + &spr_p_energy_num[4], spr, spr::SPR_PRIO_16, &pos, 0, aft_spr_db); + AetComp::put_number_sprite(song_energy % 100, 2, &comp, + &spr_p_energy_num[1], spr, spr::SPR_PRIO_16, &pos, 1, aft_spr_db); + + aet_layout_data* spr_p_energy_num_3_layout = comp.Find(spr_p_energy_num[3]); + if (spr_p_energy_num_3_layout) + aet_layout_data::put_sprite(spr[11], spr::SPR_ATTR_CTR_CC, + spr::SPR_PRIO_16, &pos, spr_p_energy_num_3_layout, aft_spr_db); + + aet_layout_data* spr_p_energy_num_0_layout = comp.Find(spr_p_energy_num[0]); + if (spr_p_energy_num_0_layout) + aet_layout_data::put_sprite(spr[10], spr::SPR_ATTR_CTR_CC, + spr::SPR_PRIO_16, &pos, spr_p_energy_num_0_layout, aft_spr_db); +} + +void pv_game_play_data::disp_spr_set_back() { + if (!loaded || spr_set_back_id == -1) + return; + + data_struct* aft_data = &data_list[DATA_AFT]; + sprite_database* aft_spr_db = &aft_data->data_ft.spr_db; + + spr::SprArgs args; + args.id.id = spr_set_back_id; + args.prio = spr::SPR_PRIO_01; + args.index = 2; + spr::put_sprite(args, aft_spr_db); +} + +void pv_game_play_data::fade_begin_ctrl() { + if (!loaded) + return; + + if (!fade_begin) { + set_aet_id_play(PV_GAME_AET_WHITE_FADE, true); + fade_begin = true; + } +} + +bool pv_game_play_data::fade_end_ctrl() { + if (!loaded) + return false; + + if (!fade_end && aet_ids[PV_GAME_AET_WHITE_FADE] + && aet_manager_get_obj_end(aet_ids[PV_GAME_AET_WHITE_FADE])) { + aet_manager_free_aet_object_reset(&aet_ids[PV_GAME_AET_WHITE_FADE]); + fade_end = true; + } + + return fade_end; +} + +void pv_game_play_data::free_aet(pv_aet aet, int32_t index) { + if (index < 0 || index >= 8) + return; + + switch (aet) { + case PV_AET_FRONT: + aet_manager_free_aet_object_reset(&aet_ids[index + PV_GAME_AET_FRONT]); + break; + case PV_AET_FRONT_LOW: + aet_manager_free_aet_object_reset(&aet_ids[index + PV_GAME_AET_FRONT_LOW]); + break; + case PV_AET_FRONT_3D_SURF: + aet_manager_free_aet_object_reset(&aet_ids[index + PV_GAME_AET_FRONT_3D_SURF]); + break; + case PV_AET_BACK: + aet_manager_free_aet_object_reset(&aet_ids[index + PV_GAME_AET_BACK]); + break; + } +} + +void pv_game_play_data::free_aet_title_image() { + aet_manager_free_aet_object_reset(&aet_ids[PV_GAME_AET_TITLE_IMAGE]); +} + +float_t pv_game_play_data::get_aet_frame(pv_aet aet, int32_t index) { + if (index < 0 || index >= 8) + return -1.0f; + + switch (aet) { + case PV_AET_FRONT: + return get_aet_id_frame((pv_game_aet)(index + PV_GAME_AET_FRONT)); + case PV_AET_FRONT_LOW: + return get_aet_id_frame((pv_game_aet)(index + PV_GAME_AET_FRONT_LOW)); + case PV_AET_FRONT_3D_SURF: + return get_aet_id_frame((pv_game_aet)(index + PV_GAME_AET_FRONT_3D_SURF)); + case PV_AET_BACK: + return get_aet_id_frame((pv_game_aet)(index + PV_GAME_AET_BACK)); + } + return -1.0f; +} + +float_t pv_game_play_data::get_aet_id_frame(pv_game_aet aet_index) { + if (aet_ids[aet_index]) + return aet_manager_get_obj_frame(aet_ids[aet_index]); + return -1.0f; +} + +bool pv_game_play_data::get_aet_next_info_disp() { + return aet_ids[PV_GAME_AET_NEXT_INFO] + && !aet_manager_get_obj_end(aet_ids[PV_GAME_AET_NEXT_INFO]); +} + +int32_t pv_game_play_data::get_digit_count(int32_t score, int32_t digits) { + if (score <= 0) + return 1; + + int32_t _digits = 0; + while (score > 0) { + score /= 10; + _digits++; + } + + if (_digits < 1) + return 1; + + if (_digits > digits) + _digits = digits; + return _digits; +} + +void pv_game_play_data::init_aet(pv_aet aet, int32_t index, std::string&& layer_name, std::string&& aet_name, + bool* not_init, float_t start_time, float_t end_time, FrameRateControl* frame_rate_control) { + if (index < 0 || index >= 8) + return; + + int32_t aet_id = pv_aet_id; + if (aet_name.size()) { + data_struct* aft_data = &data_list[DATA_AFT]; + aet_database* aft_aet_db = &aft_data->data_ft.aet_db; + + aet_id = aft_aet_db->get_aet_by_name(aet_name.c_str())->id; + } + + int32_t spr_index; + pv_game_aet aet_index; + spr::SprPrio prio; + switch (aet) { + case PV_AET_FRONT: + spr_index = 0; + aet_index = (pv_game_aet)(index + PV_GAME_AET_FRONT); + prio = spr::SPR_PRIO_01; + break; + case PV_AET_FRONT_LOW: + spr_index = 0; + aet_index = (pv_game_aet)(index + PV_GAME_AET_FRONT_LOW); + prio = spr::SPR_PRIO_00; + break; + case PV_AET_FRONT_3D_SURF: + spr_index = 1; + aet_index = (pv_game_aet)(index + PV_GAME_AET_FRONT_3D_SURF); + prio = spr::SPR_PRIO_00; + break; + case PV_AET_BACK: + spr_index = 2; + aet_index = (pv_game_aet)(index + PV_GAME_AET_BACK); + prio = spr::SPR_PRIO_01; + break; + default: + return; + } + + init_aet_id(aet_id, layer_name.c_str(), spr_index, aet_index, + prio, not_init, start_time, end_time, frame_rate_control); + +} + +void pv_game_play_data::init_aet_black_fade() { + fade = PV_GAME_AET_BLACK_FADE; + aet_manager_free_aet_object_reset(&aet_ids[PV_GAME_AET_BLACK_FADE]); + aet_ids[PV_GAME_AET_BLACK_FADE] = init_aet_gam_cmn(PV_GAME_AET_BLACK_FADE, + spr::SPR_PRIO_17, AET_PLAY_ONCE, spr_black_fade[0]); + set_aet_id_frame(PV_GAME_AET_BLACK_FADE, 0.0f); + set_aet_id_play(PV_GAME_AET_BLACK_FADE, false); +} + +void pv_game_play_data::init_aet_chance_frame() { + + aet_manager_free_aet_object_reset(&aet_ids[PV_GAME_AET_CHANCE_FRAME_BOTTOM]); + aet_ids[PV_GAME_AET_CHANCE_FRAME_BOTTOM] = init_aet_gam_cmn(PV_GAME_AET_CHANCE_FRAME_BOTTOM, + spr::SPR_PRIO_12, AET_LOOP, spr_chance_frame_bottom[0]); + aet_manager_free_aet_object_reset(&aet_ids[PV_GAME_AET_CHANCE_FRAME_TOP]); + aet_ids[PV_GAME_AET_CHANCE_FRAME_TOP] = init_aet_gam_cmn(PV_GAME_AET_CHANCE_FRAME_TOP, + spr::SPR_PRIO_12, AET_LOOP, spr_chance_frame_top[0]); +} + +void pv_game_play_data::init_aet_chance_point(int32_t chance_points, float_t pos_x, float_t pos_y) { + + vec2 pos = { pos_x, pos_y }; + target_pos_scale_offset_apply(&pos, &pos); + aet_manager_free_aet_object_reset(&aet_ids[PV_GAME_AET_CHANCE_POINT]); + aet_ids[PV_GAME_AET_CHANCE_POINT] = init_aet_gam_cmn(PV_GAME_AET_CHANCE_POINT, spr::SPR_PRIO_15, + AET_PLAY_ONCE, spr_chance_point[(get_digit_count(chance_points, 6) + 1) % 2 ? 1 : 0], &pos); +} + +void pv_game_play_data::init_aet_chance_txt(bool end) { + aet_manager_free_aet_object_reset(&aet_ids[PV_GAME_AET_CHANCE_TXT]); + aet_ids[PV_GAME_AET_CHANCE_TXT] = init_aet_gam_cmn(PV_GAME_AET_CHANCE_TXT, + spr::SPR_PRIO_06, AET_PLAY_ONCE, spr_chance_txt[end ? 0 : 1]); +} + +void pv_game_play_data::init_aet_combo(int32_t target_display_index, + float_t pos_x, float_t pos_y, int32_t combo_count) { + if (target_display_index < 0 || target_display_index >= 9 || combo_count < 0 || combo_count > 9999 + || combo_count > 0 && target_display_index != 0 && target_display_index != 2) + return; + + pos_y = max_def(pos_y, 58.0f); + + combo_pos = { pos_x, pos_y }; + this->combo_count = combo_count; + + vec2 pos = { pos_x, pos_y }; + target_pos_scale_offset_apply(&pos, &pos); + + aet_manager_free_aet_object_reset(&aet_ids[PV_GAME_AET_VALUE_TEXT]); + aet_manager_free_aet_object_reset(&aet_ids[PV_GAME_AET_COMBO]); + + if (combo_count > 0) { + if (combo_count < 10) + value_text_spr_index = 0; + else if (combo_count < 100) + value_text_spr_index = 1; + else if (combo_count < 1000) + value_text_spr_index = combo_count == 50 * (combo_count / 50) ? 3 : 2; + else + value_text_spr_index = 4; + + if (target_display_index == 2) + value_text_spr_index += 5; + + const char* name; + if (value_text_time_offset < -(float_t)(1.0 / 120.0)) + name = spr_combo_tempo_cool_fine[value_text_spr_index]; + else if (value_text_time_offset > (float_t)(1.0 / 120.0)) + name = spr_combo_cool_fine[value_text_spr_index]; + else + name = spr_combo_just_cool_fine[value_text_spr_index]; + aet_ids[PV_GAME_AET_COMBO] = init_aet_gam_cmn(PV_GAME_AET_COMBO, + spr::SPR_PRIO_14, AET_PLAY_ONCE, name, &pos); + } + else { + const char* name; + if (value_text_time_offset < -(float_t)(1.0 / 120.0)) + name = spr_value_text_late[target_display_index]; + else if (value_text_time_offset > (float_t)(1.0 / 120.0)) + name = spr_value_text_early[target_display_index]; + else + name = spr_value_text[target_display_index]; + aet_ids[PV_GAME_AET_VALUE_TEXT] = init_aet_gam_cmn(PV_GAME_AET_VALUE_TEXT, + spr::SPR_PRIO_14, AET_PLAY_ONCE, name, &pos); + } +} + +void pv_game_play_data::init_aet_demo_font() { + data_struct* aft_data = &data_list[DATA_AFT]; + aet_database* aft_aet_db = &aft_data->data_ft.aet_db; + sprite_database* aft_spr_db = &aft_data->data_ft.spr_db; + + aet_manager_free_aet_object_reset(&aet_ids[PV_GAME_AET_DEMO_FONT]); + aet_ids[PV_GAME_AET_DEMO_FONT] = aet_manager_init_aet_object(33, spr::SPR_PRIO_16, + AET_PLAY_ONCE, spr_demo_font[0], 0, 0, 0, 0, -1.0f, -1.0f, 0, 0, aft_aet_db, aft_spr_db); +} + +void pv_game_play_data::init_aet_demo_logo() { + data_struct* aft_data = &data_list[DATA_AFT]; + aet_database* aft_aet_db = &aft_data->data_ft.aet_db; + sprite_database* aft_spr_db = &aft_data->data_ft.spr_db; + + aet_manager_free_aet_object_reset(&aet_ids[PV_GAME_AET_DEMO_LOGO]); + aet_ids[PV_GAME_AET_DEMO_LOGO] = aet_manager_init_aet_object(33, spr::SPR_PRIO_16, + AET_LOOP, spr_demo_logo[0], 0, 0, 0, 0, -1.0f, -1.0f, 0, 0, aft_aet_db, aft_spr_db); +} + +float_t pv_game_play_data::init_aet_edit_effect(int32_t aet_id, const char* name, bool loop, bool low_field) { + aet_manager_free_aet_object_reset(&aet_ids[PV_GAME_AET_EDIT_EFFECT]); + + if (aet_id == -1) + return 0.0f; + + data_struct* aft_data = &data_list[DATA_AFT]; + aet_database* aft_aet_db = &aft_data->data_ft.aet_db; + sprite_database* aft_spr_db = &aft_data->data_ft.spr_db; + + std::vector vec; + aet_manager_get_scene_comp_layer_names(vec, aet_id, aft_aet_db); + for (const std::string& i : vec) + if (!i.compare("eff__f")) { + name = i.c_str(); + break; + } + + aet_ids[PV_GAME_AET_EDIT_EFFECT] = aet_manager_init_aet_object(aet_id, + low_field ? spr::SPR_PRIO_00 : spr::SPR_PRIO_01, loop ? AET_LOOP : AET_PLAY_ONCE, + name, 0, 0, 0, 0, -1.0f, -1.0f, 0, 0, aft_aet_db, aft_spr_db); + set_aet_id_play(PV_GAME_AET_EDIT_EFFECT, false); + + return aet_manager_get_scene_layer_end_time(aet_id, name, aft_aet_db); +} + +void pv_game_play_data::init_aet_frame(bool danger) { + + + if (frame_state != (danger ? 2 : 1)) { + data_struct* aft_data = &data_list[DATA_AFT]; + aet_database* aft_aet_db = &aft_data->data_ft.aet_db; + + /*if (game_skin_get()->check_skin()) { + aet_manager_free_aet_object_reset(&aet_ids[PV_GAME_AET_BOTTOM_FRONT]); + aet_ids[PV_GAME_AET_BOTTOM_FRONT] = aet_manager_init_aet_object(game_skin_get()->get_skin_aet(), + spr::SPR_PRIO_10, AET_LOOP, "bottom_front", 0, 0, 0, 0, -1.0f, -1.0f, 0, 0, aft_aet_db); + aet_manager_free_aet_object_reset(&aet_ids[PV_GAME_AET_BOTTOM_BACK]); + aet_ids[PV_GAME_AET_BOTTOM_BACK] = aet_manager_init_aet_object(game_skin_get()->get_skin_aet(), + spr::SPR_PRIO_03, AET_LOOP, "bottom_back", 0, 0, 0, 0, -1.0f, -1.0f, 0, 0, aft_aet_db); + } + else */{ + aet_manager_free_aet_object_reset(&aet_ids[PV_GAME_AET_FRAME_BOTTOM]); + aet_ids[PV_GAME_AET_FRAME_BOTTOM] = init_aet_gam_cmn(PV_GAME_AET_FRAME_BOTTOM, + spr::SPR_PRIO_10, AET_LOOP, spr_frame[danger ? 2 : 0]); + } + + /*if (game_skin_get()->check_skin()) { + aet_manager_free_aet_object_reset(&aet_ids[PV_GAME_AET_TOP_FRONT]); + aet_ids[PV_GAME_AET_TOP_FRONT] = aet_manager_init_aet_object(game_skin_get()->get_skin_aet(), + spr::SPR_PRIO_10, AET_LOOP, "top_front", 0, 0, 0, 0, -1.0f, -1.0f, 0, 0, aft_aet_db); + aet_manager_free_aet_object_reset(&aet_ids[PV_GAME_AET_TOP_BACK]); + aet_ids[PV_GAME_AET_TOP_BACK] = aet_manager_init_aet_object(game_skin_get()->get_skin_aet(), + spr::SPR_PRIO_03, AET_LOOP, "top_back", 0, 0, 0, 0, -1.0f, -1.0f, 0, 0, aft_aet_db); + } + else */{ + aet_manager_free_aet_object_reset(&aet_ids[PV_GAME_AET_FRAME_UP]); + aet_ids[PV_GAME_AET_FRAME_UP] = init_aet_gam_cmn(PV_GAME_AET_FRAME_UP, + spr::SPR_PRIO_10, AET_LOOP, spr_frame[danger ? 3 : 1]); + } + frame_state = danger ? 2 : 1; + } + + /*if (game_skin_get()->check_skin()) { + set_aet_id_visible_enable(PV_GAME_AET_BOTTOM_FRONT, field_1F8[0]); + set_aet_id_visible_enable(PV_GAME_AET_BOTTOM_BACK , field_1F8[0]); + set_aet_id_visible_enable(PV_GAME_AET_TOP_FRONT , field_1F8[0]); + set_aet_id_visible_enable(PV_GAME_AET_TOP_BACK , field_1F8[0]); + } + else */{ + set_aet_id_visible_enable(PV_GAME_AET_FRAME_BOTTOM, field_1F8[0]); + set_aet_id_visible_enable(PV_GAME_AET_FRAME_UP , field_1F8[0]); + } +} + +uint32_t pv_game_play_data::init_aet_gam_cmn(pv_game_aet aet_index, spr::SprPrio prio, + AetFlags flags, const char* layer_name, const vec2* pos, const vec2* scale) { + data_struct* aft_data = &data_list[DATA_AFT]; + aet_database* aft_aet_db = &aft_data->data_ft.aet_db; + sprite_database* aft_spr_db = &aft_data->data_ft.spr_db; + + uint32_t aet_id = aet_manager_init_aet_object(3, prio, flags, layer_name, pos, + 0, 0, 0, -1.0f, -1.0f, scale, 0, aft_aet_db, aft_spr_db); + aet_ids_enable[aet_index] = 1; + return aet_id; +} + +void pv_game_play_data::init_aet_id(int32_t aet_id, const char* layer_name, + int32_t index, pv_game_aet aet_index, spr::SprPrio prio, bool* not_init, + float_t start_time, float_t end_time, FrameRateControl* frame_rate_control) { + aet_manager_free_aet_object_reset(&aet_ids[aet_index]); + if (!pv_set || !layer_name || !*layer_name) + return; + + data_struct* aft_data = &data_list[DATA_AFT]; + aet_database* aft_aet_db = &aft_data->data_ft.aet_db; + sprite_database* aft_spr_db = &aft_data->data_ft.spr_db; + + aet_ids[aet_index] = aet_manager_init_aet_object(aet_id, prio, AET_PLAY_ONCE, layer_name, 0, + index, 0, 0, start_time, end_time, 0, frame_rate_control, aft_aet_db, aft_spr_db); + if (!aet_ids[aet_index] && not_init) + *not_init = true; +} + +void pv_game_play_data::init_aet_level_info() { + aet_manager_free_aet_object_reset(&aet_ids[PV_GAME_AET_LEVEL_INFO]); + + int32_t difficulty = sub_14013C8C0()->difficulty; + int32_t edition = sub_14013C8C0()->edition; + + const pv_db_pv_difficulty* diff = pv_game_get()->data.pv->get_difficulty(difficulty, edition); + if (!diff) + return; + + bool extra = diff->attribute.type == PV_ATTRIBUTE_EXTRA; + + const char* name; + if (player_data_array_get(0)->contest.enable) + name = (extra ? spr_level_info_ctst_extra : spr_level_info_ctst)[difficulty]; + else if (pv_game_get()->data.no_fail) + name = (extra ? spr_level_info_insu_extra : spr_level_info_insu)[difficulty]; + else + name = (extra ? spr_level_info_extra : spr_level_info)[difficulty]; + + aet_ids[PV_GAME_AET_LEVEL_INFO] = init_aet_gam_cmn(PV_GAME_AET_LEVEL_INFO, spr::SPR_PRIO_13, AET_LOOP, name); + set_aet_id_visible_enable(PV_GAME_AET_LEVEL_INFO, field_1F8[0]); +} + +void pv_game_play_data::init_aet_next_info() { + aet_manager_free_aet_object_reset(&aet_ids[PV_GAME_AET_NEXT_INFO]); + aet_ids[PV_GAME_AET_NEXT_INFO] = init_aet_gam_cmn(PV_GAME_AET_NEXT_INFO, spr::SPR_PRIO_22, + AET_PLAY_ONCE, pv_game_get()->data.next_stage ? spr_next_info[0] : spr_failed_info[0]); +} + +void pv_game_play_data::init_aet_option_info() { + if (!player_data_array_get(0)->field_0 || !player_data_array_get(0)->game_opts) + return; + + int32_t option = pv_game_get()->data.play_data.option; + if (!option) + return; + + aet_manager_free_aet_object_reset(&aet_ids[PV_GAME_AET_OPTION_INFO_BASE]); + aet_manager_free_aet_object_reset(&aet_ids[PV_GAME_AET_OPTION_INFO_HISPEED]); + aet_manager_free_aet_object_reset(&aet_ids[PV_GAME_AET_OPTION_INFO_HIDDEN]); + aet_manager_free_aet_object_reset(&aet_ids[PV_GAME_AET_OPTION_INFO_SUDDEN]); + aet_ids[PV_GAME_AET_OPTION_INFO_BASE] = init_aet_gam_cmn(PV_GAME_AET_OPTION_INFO_BASE, + spr::SPR_PRIO_13, AET_PLAY_ONCE, spr_option_info_base[0]); + aet_ids[PV_GAME_AET_OPTION_INFO_HISPEED] = init_aet_gam_cmn(PV_GAME_AET_OPTION_INFO_HISPEED, + spr::SPR_PRIO_13, AET_PLAY_ONCE, spr_option_info_hispeed[option != 1 ? 1 : 0]); + aet_ids[PV_GAME_AET_OPTION_INFO_HIDDEN] = init_aet_gam_cmn(PV_GAME_AET_OPTION_INFO_HIDDEN, + spr::SPR_PRIO_13, AET_PLAY_ONCE, spr_option_info_hidden[option != 2 ? 1 : 0]); + aet_ids[PV_GAME_AET_OPTION_INFO_SUDDEN] = init_aet_gam_cmn(PV_GAME_AET_OPTION_INFO_SUDDEN, + spr::SPR_PRIO_13, AET_PLAY_ONCE, spr_option_info_sudden[option != 3 ? 1 : 0]); + set_aet_id_visible_enable(PV_GAME_AET_OPTION_INFO_BASE, field_1F8[0]); + set_aet_id_visible_enable(PV_GAME_AET_OPTION_INFO_HISPEED, field_1F8[0]); + set_aet_id_visible_enable(PV_GAME_AET_OPTION_INFO_HIDDEN, field_1F8[0]); + set_aet_id_visible_enable(PV_GAME_AET_OPTION_INFO_SUDDEN, field_1F8[0]); +} + +void pv_game_play_data::init_aet_slide_max(int32_t slide_point, float_t pos_x, float_t pos_y) { + aet_manager_free_aet_object_reset(&aet_ids[PV_GAME_AET_SLIDE_POINT]); + aet_manager_free_aet_object_reset(&aet_ids[PV_GAME_AET_MAX_SLIDE_POINT]); + aet_manager_free_aet_object_reset(&aet_ids[PV_GAME_AET_MAX_SLIDE_NUM_PLUS]); + aet_manager_free_aet_object_reset(&aet_ids[PV_GAME_AET_MAX_SLIDE_NUM_0]); + aet_manager_free_aet_object_reset(&aet_ids[PV_GAME_AET_MAX_SLIDE_NUM_1]); + aet_manager_free_aet_object_reset(&aet_ids[PV_GAME_AET_MAX_SLIDE_NUM_2]); + aet_manager_free_aet_object_reset(&aet_ids[PV_GAME_AET_MAX_SLIDE_NUM_3]); + aet_manager_free_aet_object_reset(&aet_ids[PV_GAME_AET_MAX_SLIDE_NUM_4]); + aet_manager_free_aet_object_reset(&aet_ids[PV_GAME_AET_MAX_SLIDE_NUM_5]); + aet_manager_free_aet_object_reset(&aet_ids[PV_GAME_AET_MAX_SLIDE_NUM_6]); + + vec2 v27 = { pos_x, pos_y }; + target_pos_scale_offset_apply(&v27, &v27); + + aet_ids[PV_GAME_AET_MAX_SLIDE_POINT] = init_aet_gam_cmn(PV_GAME_AET_MAX_SLIDE_POINT, spr::SPR_PRIO_15, + AET_PLAY_ONCE, spr_max_slide_point[(get_digit_count(slide_point, 6) + 1) % 2 ? 1 : 0], &v27); + + int32_t v8 = get_digit_count(max_slide_points, 6); + + int32_t v10; + int32_t v11; + if ((v8 + 1) % 2) { + v10 = 1; + v11 = 6 - v8; + } + else { + v10 = 0; + v11 = 5 - v8; + } + + data_struct* aft_data = &data_list[DATA_AFT]; + aet_database* aft_aet_db = &aft_data->data_ft.aet_db; + sprite_database* aft_spr_db = &aft_data->data_ft.spr_db; + + AetComp comp; + aet_manager_init_aet_layout(&comp, 3, spr_max_slide_point[v10], (AetFlags)0, RESOLUTION_MODE_HD, + 0, aet_manager_get_obj_frame(aet_ids[PV_GAME_AET_MAX_SLIDE_POINT]), aft_aet_db, aft_spr_db); + + vec2 pos ; + target_pos_scale_offset_apply(&max_slide_points_pos, &pos); + + aet_layout_data* layout = comp.Find((&spr_p_chance_point_num[v11 / 2])[v8]); + if (layout) { + vec2 position = pos + *(vec2*)&layout->position; + aet_ids[PV_GAME_AET_MAX_SLIDE_NUM_PLUS] = init_aet_gam_cmn(PV_GAME_AET_MAX_SLIDE_NUM_PLUS, + spr::SPR_PRIO_15, AET_PLAY_ONCE, spr_max_slide_num_plus[0], &position); + } + + for (int32_t i = 0; i < 7; i++) { + int32_t digit = slide_point % 10; + slide_point /= 10; + + aet_layout_data* layout = comp.Find(spr_p_chance_point_num[i]); + if (layout) { + vec2 position = pos + *(vec2*)&layout->position; + aet_ids[PV_GAME_AET_MAX_SLIDE_NUM + i] = init_aet_gam_cmn((pv_game_aet)(PV_GAME_AET_MAX_SLIDE_NUM + i), + spr::SPR_PRIO_15, AET_PLAY_ONCE, spr_max_slide_num[digit], &position); + } + + if (!slide_point) + break; + } +} + +void pv_game_play_data::init_aet_slide_point(int32_t slide_point, float_t pos_x, float_t pos_y) { + vec2 pos = { pos_x, pos_y }; + target_pos_scale_offset_apply(&pos, &pos); + aet_manager_free_aet_object_reset(&aet_ids[PV_GAME_AET_SLIDE_POINT]); + aet_ids[PV_GAME_AET_SLIDE_POINT] = init_aet_gam_cmn(PV_GAME_AET_SLIDE_POINT, spr::SPR_PRIO_15, + AET_PLAY_ONCE, spr_chance_point[(get_digit_count(slide_point, 6) + 1) % 2 ? 1 : 0], &pos); +} + +void pv_game_play_data::init_aet_song_energy() { + aet_manager_free_aet_object_reset(&aet_ids[PV_GAME_AET_SONG_ENERGY_BASE]); + aet_ids[PV_GAME_AET_SONG_ENERGY_BASE] = init_aet_gam_cmn(PV_GAME_AET_SONG_ENERGY_BASE, + spr::SPR_PRIO_15, AET_LOOP, spr_song_energy_base[0]); + aet_manager_free_aet_object_reset(&aet_ids[PV_GAME_AET_SONG_ENERGY_BASE_REACH]); + aet_ids[PV_GAME_AET_SONG_ENERGY_BASE_REACH] = init_aet_gam_cmn(PV_GAME_AET_SONG_ENERGY_BASE_REACH, + spr::SPR_PRIO_15, AET_LOOP, spr_song_energy_base_reach[0]); + aet_manager_free_aet_object_reset(&aet_ids[PV_GAME_AET_SONG_ENERGY_NORMAL]); + aet_ids[PV_GAME_AET_SONG_ENERGY_NORMAL] = init_aet_gam_cmn(PV_GAME_AET_SONG_ENERGY_NORMAL, + spr::SPR_PRIO_15, AET_LOOP, spr_song_energy_normal[0]); + aet_manager_free_aet_object_reset(&aet_ids[PV_GAME_AET_SONG_ENERGY_REACH]); + aet_ids[PV_GAME_AET_SONG_ENERGY_REACH] = init_aet_gam_cmn(PV_GAME_AET_SONG_ENERGY_REACH, + spr::SPR_PRIO_15, AET_LOOP, spr_song_energy_reach[0]); + aet_manager_free_aet_object_reset(&aet_ids[PV_GAME_AET_SONG_ENERGY_FULL]); + aet_ids[PV_GAME_AET_SONG_ENERGY_FULL] = init_aet_gam_cmn(PV_GAME_AET_SONG_ENERGY_FULL, + spr::SPR_PRIO_15, AET_LOOP, spr_song_energy_full[0]); + aet_manager_free_aet_object_reset(&aet_ids[PV_GAME_AET_SONG_ENERGY_EFF_NORMAL]); + aet_ids[PV_GAME_AET_SONG_ENERGY_EFF_NORMAL] = init_aet_gam_cmn(PV_GAME_AET_SONG_ENERGY_EFF_NORMAL, + spr::SPR_PRIO_15, AET_LOOP, spr_song_energy_eff_normal[0]); + aet_manager_free_aet_object_reset(&aet_ids[PV_GAME_AET_SONG_ENERGY_EFF_REACH]); + aet_ids[PV_GAME_AET_SONG_ENERGY_EFF_REACH] = init_aet_gam_cmn(PV_GAME_AET_SONG_ENERGY_EFF_REACH, + spr::SPR_PRIO_15, AET_LOOP, spr_song_energy_eff_reach[0]); + aet_manager_free_aet_object_reset(&aet_ids[PV_GAME_AET_SONG_ENERGY_CLEAR_TXT]); + aet_ids[PV_GAME_AET_SONG_ENERGY_CLEAR_TXT] = init_aet_gam_cmn(PV_GAME_AET_SONG_ENERGY_CLEAR_TXT, + spr::SPR_PRIO_15, AET_LOOP, spr_song_energy_clear_txt[0]); + aet_manager_free_aet_object_reset(&aet_ids[PV_GAME_AET_SONG_ENERGY_BORDER_GREAT]); + aet_ids[PV_GAME_AET_SONG_ENERGY_BORDER_GREAT] = init_aet_gam_cmn(PV_GAME_AET_SONG_ENERGY_BORDER_GREAT, + spr::SPR_PRIO_15, AET_LOOP, spr_song_energy_border_great[0]); + aet_manager_free_aet_object_reset(&aet_ids[PV_GAME_AET_SONG_ENERGY_BORDER_EXCELLENT]); + aet_ids[PV_GAME_AET_SONG_ENERGY_BORDER_EXCELLENT] = init_aet_gam_cmn(PV_GAME_AET_SONG_ENERGY_BORDER_EXCELLENT, + spr::SPR_PRIO_15, AET_LOOP, spr_song_energy_border_excellent[0]); + aet_manager_free_aet_object_reset(&aet_ids[PV_GAME_AET_SONG_ENERGY_BORDER_RIVAL]); + aet_ids[PV_GAME_AET_SONG_ENERGY_BORDER_RIVAL] = init_aet_gam_cmn(PV_GAME_AET_SONG_ENERGY_BORDER_RIVAL, + spr::SPR_PRIO_15, AET_LOOP, spr_song_energy_border_rival[0]); + aet_manager_free_aet_object_reset(&aet_ids[PV_GAME_AET_SONG_ENERGY_EDGE_LINE02]); + aet_ids[PV_GAME_AET_SONG_ENERGY_EDGE_LINE02] = init_aet_gam_cmn(PV_GAME_AET_SONG_ENERGY_EDGE_LINE02, + spr::SPR_PRIO_15, AET_LOOP, spr_song_energy_edge_line02[0]); + aet_manager_free_aet_object_reset(&aet_ids[PV_GAME_AET_SONG_ENERGY_NOT_CLEAR]); + aet_ids[PV_GAME_AET_SONG_ENERGY_NOT_CLEAR] = init_aet_gam_cmn(PV_GAME_AET_SONG_ENERGY_NOT_CLEAR, + spr::SPR_PRIO_16, AET_LOOP, spr_song_energy_not_clear[0]); + aet_manager_free_aet_object_reset(&aet_ids[PV_GAME_AET_SONG_ENERGY_BORDER]); + aet_ids[PV_GAME_AET_SONG_ENERGY_BORDER] = init_aet_gam_cmn(PV_GAME_AET_SONG_ENERGY_BORDER, + spr::SPR_PRIO_16, AET_LOOP, spr_song_energy_border[0]); + aet_manager_free_aet_object_reset(&aet_ids[PV_GAME_AET_SONG_ENERGY_NOT_CLEAR_TXT]); + aet_ids[PV_GAME_AET_SONG_ENERGY_NOT_CLEAR_TXT] = init_aet_gam_cmn(PV_GAME_AET_SONG_ENERGY_NOT_CLEAR_TXT, + spr::SPR_PRIO_16, AET_LOOP, spr_song_energy_not_clear_txt[0]); + + set_aet_id_visible_enable(PV_GAME_AET_SONG_ENERGY_BASE , field_1F8[0]); + set_aet_id_visible_enable(PV_GAME_AET_SONG_ENERGY_BASE_REACH , field_1F8[0]); + set_aet_id_visible_enable(PV_GAME_AET_SONG_ENERGY_CLEAR_TXT , field_1F8[0]); + set_aet_id_visible_enable(PV_GAME_AET_SONG_ENERGY_BORDER_GREAT , field_1F8[0]); + set_aet_id_visible_enable(PV_GAME_AET_SONG_ENERGY_BORDER_EXCELLENT, field_1F8[0]); + set_aet_id_visible_enable(PV_GAME_AET_SONG_ENERGY_EDGE_LINE02 , field_1F8[0]); + + set_song_energy(field_1F8[0]); + + set_aet_id_play(PV_GAME_AET_SONG_ENERGY_BASE , false); + set_aet_id_play(PV_GAME_AET_SONG_ENERGY_CLEAR_TXT , false); + set_aet_id_play(PV_GAME_AET_SONG_ENERGY_BORDER_GREAT , false); + set_aet_id_play(PV_GAME_AET_SONG_ENERGY_BORDER_EXCELLENT, false); + set_aet_id_play(PV_GAME_AET_SONG_ENERGY_EDGE_LINE02 , false); + set_aet_id_play(PV_GAME_AET_SONG_ENERGY_BASE_REACH , false); + set_aet_id_play(PV_GAME_AET_SONG_ENERGY_NORMAL , false); + set_aet_id_play(PV_GAME_AET_SONG_ENERGY_REACH , false); + set_aet_id_play(PV_GAME_AET_SONG_ENERGY_EFF_NORMAL , false); + set_aet_id_play(PV_GAME_AET_SONG_ENERGY_EFF_REACH , false); + set_aet_id_play(PV_GAME_AET_SONG_ENERGY_BORDER , false); +} + +void pv_game_play_data::init_aet_song_icon_loop() { + aet_manager_free_aet_object_reset(&aet_ids[PV_GAME_AET_SONG_ICON]); + aet_ids[PV_GAME_AET_SONG_ICON] = init_aet_gam_cmn(PV_GAME_AET_SONG_ICON, + spr::SPR_PRIO_13, AET_LOOP, spr_song_icon_loop[0]); + set_aet_id_visible_enable(PV_GAME_AET_SONG_ICON, field_1F8[0]); +} + +void pv_game_play_data::init_aet_stage_info() { + if (stage_index >= 0 && stage_index <= 3) { + aet_manager_free_aet_object_reset(&aet_ids[PV_GAME_AET_STAGE_INFO]); + aet_ids[PV_GAME_AET_STAGE_INFO] = init_aet_gam_cmn(PV_GAME_AET_STAGE_INFO, + spr::SPR_PRIO_13, AET_LOOP, spr_stage_info[stage_index]); + set_aet_id_visible_enable(PV_GAME_AET_STAGE_INFO, field_1F8[0]); + } +} + +void pv_game_play_data::init_aet_success_info() { + aet_manager_free_aet_object_reset(&aet_ids[PV_GAME_AET_SUCCESS_INFO]); + aet_ids[PV_GAME_AET_SUCCESS_INFO] = init_aet_gam_cmn(PV_GAME_AET_SUCCESS_INFO, + spr::SPR_PRIO_02, (AetFlags)0, spr_success_info[0]); +} + +void pv_game_play_data::init_aet_title_image(const char* name) { + data_struct* aft_data = &data_list[DATA_AFT]; + aet_database* aft_aet_db = &aft_data->data_ft.aet_db; + sprite_database* aft_spr_db = &aft_data->data_ft.spr_db; + + aet_ids[PV_GAME_AET_TITLE_IMAGE] = aet_manager_init_aet_object(pv_aet_id, spr::SPR_PRIO_02, + (AetFlags)0, name, 0, 0, 0, 0, -1.0f, -1.0f, 0, 0, aft_aet_db, aft_spr_db); +} + +void pv_game_play_data::init_aet_white_fade() { + fade = PV_GAME_AET_WHITE_FADE; + aet_manager_free_aet_object_reset(&aet_ids[PV_GAME_AET_WHITE_FADE]); + aet_ids[PV_GAME_AET_WHITE_FADE] = init_aet_gam_cmn(PV_GAME_AET_WHITE_FADE, + spr::SPR_PRIO_17, AET_PLAY_ONCE, spr_white_fade[0]); + set_aet_id_frame(PV_GAME_AET_WHITE_FADE, 0.0f); + set_aet_id_play(PV_GAME_AET_WHITE_FADE, false); +} + +bool pv_game_play_data::load_auth_2d(int32_t stage_index, pv_disp2d* disp2d) { + if (!state) { + reset(); + set_pv_disp2d(disp2d); + set_stage_index(stage_index); + update = true; + read_auth_2d_data(); + state = 1; + } + else if (state == 1 && !load_auth_2d_data()) { + sub_140135ED0(); + state = 0; + loaded = 1; + return true; + } + return false; +} + +bool pv_game_play_data::load_auth_2d_data() { + data_struct* aft_data = &data_list[DATA_AFT]; + aet_database* aft_aet_db = &aft_data->data_ft.aet_db; + sprite_database* aft_spr_db = &aft_data->data_ft.spr_db; + + if (pv_set) { + if (pv_spr_set_id != -1 && sprite_manager_load_file(pv_spr_set_id, aft_spr_db)) + return true; + if (pv_aet_set_id != -1 && aet_manager_load_file(pv_aet_set_id, aft_aet_db)) + return true; + } + + if (sprite_manager_load_file(9, aft_spr_db) || aet_manager_load_file(3, aft_aet_db)) + return true; + + return false;//game_skin_get()->load_file(); +} + +void pv_game_play_data::read_auth_2d_data() { + data_struct* aft_data = &data_list[DATA_AFT]; + aet_database* aft_aet_db = &aft_data->data_ft.aet_db; + sprite_database* aft_spr_db = &aft_data->data_ft.spr_db; + + sprite_manager_read_file(9, "", aft_data, aft_spr_db); + aet_manager_read_file(3, "", aft_data, aft_aet_db); + + if (pv_set) { + std::string mdata_dir; + if (pv_game_get()) + mdata_dir.assign(pv_game_get()->data.pv->mdata.dir); + + if (pv_spr_set_id != -1) + sprite_manager_read_file(pv_spr_set_id, mdata_dir, aft_data, aft_spr_db); + + if (pv_aet_set_id != -1) + aet_manager_read_file(pv_aet_set_id, mdata_dir, aft_data, aft_aet_db); + } + + //game_skin_get()->load(); +} + +void pv_game_play_data::reset() { + loaded = false; + update = false; + field_378 = false; + score_speed = 0.04f; + field_36C = -1; + combo_state = 4; + pv_set = false; + stage_index = 0; + field_354 = false; + not_clear = false; + pv_spr_set_id = -1; + pv_aet_set_id = -1; + pv_aet_id = -1; + + sub_1401362C0(); +} + +void pv_game_play_data::set_aet_edit_effect_frame(float_t frame) { + set_aet_id_frame(PV_GAME_AET_EDIT_EFFECT, frame); +} + +void pv_game_play_data::set_aet_end_time(pv_aet aet, int32_t index, float_t value) { + if (index < 0 || index >= 8) + return; + + switch (aet) { + case PV_AET_FRONT: + set_aet_id_end_time((pv_game_aet)(index + PV_GAME_AET_FRONT), value); + break; + case PV_AET_FRONT_LOW: + set_aet_id_end_time((pv_game_aet)(index + PV_GAME_AET_FRONT_LOW), value); + break; + case PV_AET_FRONT_3D_SURF: + set_aet_id_end_time((pv_game_aet)(index + PV_GAME_AET_FRONT_3D_SURF), value); + break; + case PV_AET_BACK: + set_aet_id_end_time((pv_game_aet)(index + PV_GAME_AET_BACK), value); + break; + } +} + +void pv_game_play_data::set_aet_frame(pv_aet aet, int32_t index, float_t value) { + if (index < 0 || index >= 8) + return; + + switch (aet) { + case PV_AET_FRONT: + set_aet_id_frame((pv_game_aet)(index + PV_GAME_AET_FRONT), value); + break; + case PV_AET_FRONT_LOW: + set_aet_id_frame((pv_game_aet)(index + PV_GAME_AET_FRONT_LOW), value); + break; + case PV_AET_FRONT_3D_SURF: + set_aet_id_frame((pv_game_aet)(index + PV_GAME_AET_FRONT_3D_SURF), value); + break; + case PV_AET_BACK: + set_aet_id_frame((pv_game_aet)(index + PV_GAME_AET_BACK), value); + break; + } +} + +void pv_game_play_data::set_aet_id_alpha(pv_game_aet aet_index, float_t value) { + if (aet_ids[aet_index]) + aet_manager_set_obj_alpha(aet_ids[aet_index], value); +} + +void pv_game_play_data::set_aet_id_end_time(pv_game_aet aet_index, float_t value) { + if (aet_ids[aet_index]) + aet_manager_set_obj_end_time(aet_ids[aet_index], value); +} + +void pv_game_play_data::set_aet_id_frame(pv_game_aet aet_index, float_t value) { + if (aet_ids[aet_index]) + aet_manager_set_obj_frame(aet_ids[aet_index], value); +} + +void pv_game_play_data::set_aet_id_play(pv_game_aet aet_index, bool value) { + if (aet_ids[aet_index]) + aet_manager_set_obj_play(aet_ids[aet_index], value); +} + +void pv_game_play_data::set_aet_id_position(pv_game_aet aet_index, const vec3& position) { + if (aet_ids[aet_index]) + aet_manager_set_obj_position(aet_ids[aet_index], position); +} + +void pv_game_play_data::set_aet_id_visible(pv_game_aet aet_index, bool value) { + if (aet_ids[aet_index]) + aet_manager_set_obj_visible(aet_ids[aet_index], value); +} + +void pv_game_play_data::set_aet_id_visible_enable(pv_game_aet aet_index, bool value) { + aet_ids_enable[aet_index] = value; + set_aet_id_visible(aet_index, value); +} + +void pv_game_play_data::set_aet_song_energy() { + pv_game* pv_game = pv_game_get(); + if (!loaded) + return; + + set_aet_id_frame(PV_GAME_AET_SONG_ENERGY_BASE , pv_game->data.song_energy_base); + set_aet_id_frame(PV_GAME_AET_SONG_ENERGY_CLEAR_TXT , pv_game->data.song_energy_base); + set_aet_id_frame(PV_GAME_AET_SONG_ENERGY_EDGE_LINE02, pv_game->data.song_energy_base); + set_aet_id_frame(PV_GAME_AET_SONG_ENERGY_BASE_REACH , pv_game->data.song_energy_base); + set_aet_id_frame(PV_GAME_AET_SONG_ENERGY_NORMAL , pv_game->data.song_energy); + set_aet_id_frame(PV_GAME_AET_SONG_ENERGY_REACH , pv_game->data.song_energy); + set_aet_id_frame(PV_GAME_AET_SONG_ENERGY_EFF_NORMAL , pv_game->data.song_energy); + set_aet_id_frame(PV_GAME_AET_SONG_ENERGY_EFF_REACH , pv_game->data.song_energy); + set_aet_id_frame(PV_GAME_AET_SONG_ENERGY_BORDER , pv_game->data.song_energy_border); + + if (pv_game->data.song_energy_base <= 0.0f) + return; + + float_t song_energy_base = pv_game->data.song_energy_base; + float_t song_energy_border = pv_game->data.song_energy_border; + + set_aet_id_frame(PV_GAME_AET_SONG_ENERGY_BORDER_GREAT, + 1.0f / song_energy_base * get_percentage_clear_great() * song_energy_border); + set_aet_id_frame(PV_GAME_AET_SONG_ENERGY_BORDER_EXCELLENT, + 1.0f / song_energy_base * get_percentage_clear_excellent() * song_energy_border); + if (pv_game->get_data_rival_percentage() > 0.0f) { + float_t song_energy_rival + = 1.0f / song_energy_base * pv_game->get_data_rival_percentage() * song_energy_border; + song_energy_rival = min_def(song_energy_rival, 100.0f); + set_aet_id_frame(PV_GAME_AET_SONG_ENERGY_BORDER_RIVAL, song_energy_rival); + } +} + +void pv_game_play_data::set_aet_visible(pv_aet aet, int32_t index, bool value) { + if (index < 0 || index >= 8) + return; + + switch (aet) { + case PV_AET_FRONT: + set_aet_id_visible((pv_game_aet)(index + PV_GAME_AET_FRONT), value); + break; + case PV_AET_FRONT_LOW: + set_aet_id_visible((pv_game_aet)(index + PV_GAME_AET_FRONT_LOW), value); + break; + case PV_AET_FRONT_3D_SURF: + set_aet_id_visible((pv_game_aet)(index + PV_GAME_AET_FRONT_3D_SURF), value); + break; + case PV_AET_BACK: + set_aet_id_visible((pv_game_aet)(index + PV_GAME_AET_BACK), value); + break; + } +} + +void pv_game_play_data::set_not_clear() { + not_clear = true; +} + +void pv_game_play_data::set_pv_disp2d(pv_disp2d* disp2d) { + pv_set = false; + if (!disp2d || disp2d->pv_id < 0 + || disp2d->pv_spr_set_id == -1 + || disp2d->pv_aet_set_id == -1 + || disp2d->pv_aet_id == -1) + return; + + pv_set = true; + pv_spr_set_id = disp2d->pv_spr_set_id; + pv_aet_set_id = disp2d->pv_aet_set_id; + pv_aet_id = disp2d->pv_aet_id; +} + +void pv_game_play_data::set_song_energy(bool disp) { + bool normal = false; + bool reach = false; + bool base_eff_reach = false; + bool full = false; + bool border = false; + bool border_great = false; + bool border_excellent = false; + bool border_rival = false; + bool not_clear = false; + bool clear_txt = false; + + if (disp) { + pv_game* pv_game = pv_game_get(); + if (pv_game->data.song_energy >= 100.0f) + full = true; + else if (pv_game->data.song_energy >= pv_game->data.song_energy_base) { + reach = true; + base_eff_reach = true; + } + else if (pv_game->data.song_energy >= pv_game->data.song_energy_border) + reach = true; + else + normal = true; + + border = true; + int32_t clear_border = player_data_array_get(0)->clear_border; + border_great = !!(clear_border & 0x01); + border_excellent = !!(clear_border & 0x02); + border_rival = (clear_border & 0x04) && pv_game->get_data_rival_percentage() > 0.0f; + not_clear = this->not_clear; + clear_txt = true; + } + + set_aet_id_visible_enable(PV_GAME_AET_SONG_ENERGY_NORMAL , normal); + set_aet_id_visible_enable(PV_GAME_AET_SONG_ENERGY_EFF_NORMAL , normal); + set_aet_id_visible_enable(PV_GAME_AET_SONG_ENERGY_REACH , reach); + set_aet_id_visible_enable(PV_GAME_AET_SONG_ENERGY_BASE_REACH , base_eff_reach); + set_aet_id_visible_enable(PV_GAME_AET_SONG_ENERGY_EFF_REACH , base_eff_reach); + set_aet_id_visible_enable(PV_GAME_AET_SONG_ENERGY_FULL , full); + set_aet_id_visible_enable(PV_GAME_AET_SONG_ENERGY_BORDER , border); + set_aet_id_visible_enable(PV_GAME_AET_SONG_ENERGY_BORDER_GREAT , border_great); + set_aet_id_visible_enable(PV_GAME_AET_SONG_ENERGY_BORDER_EXCELLENT, border_excellent); + set_aet_id_visible_enable(PV_GAME_AET_SONG_ENERGY_BORDER_RIVAL , border_rival); + set_aet_id_visible_enable(PV_GAME_AET_SONG_ENERGY_NOT_CLEAR , not_clear); + set_aet_id_visible_enable(PV_GAME_AET_SONG_ENERGY_NOT_CLEAR_TXT , not_clear); + set_aet_id_visible_enable(PV_GAME_AET_SONG_ENERGY_CLEAR_TXT , clear_txt); +} + +void pv_game_play_data::set_spr_set_back_id(int32_t value) { + spr_set_back_id = value; +} + +void pv_game_play_data::set_stage_index(int32_t value) { + stage_index = value; +} + +void pv_game_play_data::set_value_text(int32_t index, float_t time_offset) { + value_text_time_offset = time_offset; + value_text_index = index; + value_text_display = true; +} + +void pv_game_play_data::skin_danger_ctrl() { + /*if (!game_skin_get()->check_skin()) + return; + + skin_danger_frame--; + + vec4 color = 1.0f; + if (frame_state == 2) { + if (skin_danger_frame < 0) + skin_danger_frame = 30; + else if (skin_danger_frame < 15) + color = { 1.0f, 0.6f, 0.7f, 1.0f }; + } + + aet_manager_set_obj_color(aet_ids[PV_GAME_AET_BOTTOM_BACK], color); + aet_manager_set_obj_color(aet_ids[PV_GAME_AET_BOTTOM_FRONT], color); + aet_manager_set_obj_color(aet_ids[PV_GAME_AET_TOP_BACK], color); + aet_manager_set_obj_color(aet_ids[PV_GAME_AET_TOP_FRONT], color);*/ +} + +void pv_game_play_data::score_update(uint32_t score_final, bool update) { + if (!this->update && !update) + return; + + if (score_final - score > 140) + score += (int32_t)((float_t)(10 * (score_final - score)) * score_speed); + else if (score_final - score <= 20) + score = score_final; + else + score += 20; +} + +void pv_game_play_data::unload() { + if (!loaded) + return; + + task_game_2d_sub_140372670(false); + task_game_2d_del_task(); + + for (uint32_t& i : aet_ids) + aet_manager_free_aet_object_reset(&i); + + unload_auth_2d(); + loaded = false; +} + +void pv_game_play_data::unload_aet() { + for (int32_t i = 0; i < 8; i++) { + aet_manager_free_aet_object_reset(&aet_ids[PV_GAME_AET_FRONT]); + aet_manager_free_aet_object_reset(&aet_ids[PV_GAME_AET_FRONT_LOW]); + aet_manager_free_aet_object_reset(&aet_ids[PV_GAME_AET_BACK]); + } +} + +void pv_game_play_data::unload_auth_2d() { + data_struct* aft_data = &data_list[DATA_AFT]; + aet_database* aft_aet_db = &aft_data->data_ft.aet_db; + sprite_database* aft_spr_db = &aft_data->data_ft.spr_db; + + sub_14013C320(); + + if (pv_set) { + if (pv_spr_set_id != -1) + sprite_manager_unload_set(pv_spr_set_id, aft_spr_db); + if (pv_aet_set_id != -1) + aet_manager_unload_set(pv_aet_set_id, aft_aet_db); + } + + sprite_manager_unload_set(9, aft_spr_db); + aet_manager_unload_set(3, aft_aet_db); + + //game_skin_get()->unload_skin(); +} + +void pv_game_play_data::sub_140134670(int32_t chance_result) { + if (!field_378) + return; + + sub_140137F80(true, 1.0f); + sub_1401378E0(true, 1, 4, 60.0f); + + this->chance_result = chance_result; + field_37C = 0.0f; + field_374 = 4; +} + +void pv_game_play_data::sub_140134730() { + sub_140137F80(false, 1.0f); + sub_1401378E0(true, 1, 3, 60.0f); + update = true; + field_37C = 0.0f; + field_374 = 0; + field_378 = true; +} + +void pv_game_play_data::sub_1401349B0() { + sub_1401349C0(9); +} + +void pv_game_play_data::sub_1401349C0(uint32_t set_id) { + data_struct* aft_data = &data_list[DATA_AFT]; + sprite_database* aft_spr_db = &aft_data->data_ft.spr_db; + + if (!sprite_manager_get_set_ready(aft_spr_db->get_spr_set_by_id(set_id)->index, aft_spr_db)) + return; + + uint32_t count = sprite_manager_get_set_texture_num(set_id, aft_spr_db); + for (uint32_t i = 0; i < count; i++) { + texture* tex = sprite_manager_get_spr_texture( + aft_spr_db->get_tex_by_set_id_index(set_id, i)->id, aft_spr_db); + if (!tex) + continue; + + spr::SprArgs args; + args.id.id = -1; + args.prio = spr::SPR_PRIO_04; + args.texture = tex; + args.SetSpriteSize({ (float_t)tex->width, (float_t)tex->height }); + args.SetTexturePosSize(0.0f, 0.0f, (float_t)tex->width, (float_t)tex->height); + spr::put_sprite(args, aft_spr_db); + } +} + +void pv_game_play_data::sub_140135ED0() { + data_struct* aft_data = &data_list[DATA_AFT]; + aet_database* aft_aet_db = &aft_data->data_ft.aet_db; + sprite_database* aft_spr_db = &aft_data->data_ft.spr_db; + + AetArgs args; + args.id.id = 3; + args.mode = RESOLUTION_MODE_HD; + args.spr_db = aft_spr_db; + + comp.Clear(); + aet_manager_init_aet_layout(&comp, args, aft_aet_db); + + for (int32_t i = 0; i < 2; i++) { + aet_layout_data* p_song_layout = comp.Find(spr_p_song_lt[i]); + if (p_song_layout) + song_txt[i] = *p_song_layout; + } + + aet_layout_data* p_chance_rslt_num_0_layout = comp.Find(spr_p_chance_rslt_num[0]); + aet_layout_data* p_chance_rslt_num_1_layout = comp.Find(spr_p_chance_rslt_num[1]); + if (p_chance_rslt_num_0_layout && p_chance_rslt_num_1_layout) + field_350 = p_chance_rslt_num_0_layout->position.x - p_chance_rslt_num_1_layout->position.x; + + if (sub_14013C8C0()->sub_1400E7910() == 3) + init_aet_demo_logo(); + else { + init_aet_frame(false); + init_aet_chance_frame(); + init_aet_song_icon_loop(); + init_aet_song_energy(); + init_aet_level_info(); + init_aet_option_info(); + init_aet_stage_info(); + sub_1401378E0(false, 0, 0, 0.0f); + sub_1401378E0(false, 1, 0, 0.0f); + } + + if (sub_14013C8C0()->sub_1400E7910() != 2) + sub_14013C8C0()->sub_1400E7910(); + + /*if (game_skin_get()->check_skin()) { + field_204[0] = 105.0f; + field_20C[0] = 200.0f; + }*/ + init_aet_white_fade(); + + task_game_2d_add_task(); + task_game_2d_sub_140372670(false); + task_game_2d_set_energy_unit_no_fail(pv_game_get()->data.no_fail); +} + +void pv_game_play_data::sub_1401362C0() { + for (int32_t i = 0; i < PV_GAME_AET_MAX; i++) { + aet_ids[i] = 0; + aet_ids_enable[i] = false; + } + + for (int32_t i = 0; i < 2; i++) { + field_1C8[i] = 0.0f; + field_1D0[i] = 0.0f; + field_1D8[i] = 0.0f; + field_1E0[i] = 0.0f; + field_1E8[i] = 0.0f; + field_1F0[i] = 0.0f; + field_1F8[i] = false; + field_1FC[i] = 0; + } + + field_1C8[0] = 86.0f; + field_1C8[1] = 138.0f; + + field_1D8[0] = 58.0f; + field_1D8[1] = 138.0f; + + field_1E8[0] = 58.0f; + field_1E8[1] = -1.0f; + + field_1F0[0] = 86.0f; + field_1F0[1] = -1.0f; + + field_204[0] = 58.0f; + field_204[1] = 138.0f; + + field_20C[0] = 86.0f; + field_20C[1] = 138.0f; + + frame_state = 0; + field_218 = false; + fade_begin = false; + fade_end = false; + fade = PV_GAME_AET_WHITE_FADE; + skin_danger_frame = 0; + field_2FC = 0; + chance_result = 0; + chance_points = 0; + chance_points_pos = 0.0f; + field_310 = 0; + slide_points = 0; + slide_points_pos = 0.0f; + max_slide_points = 0; + max_slide_points_pos = 0.0f; + field_33C = 0; + comp.Clear(); + field_350 = 0.0f; + value_text_spr_index = 0; + spr_set_back_id = -1; + field_374 = 0; + field_37C = 0.0f; + score = 0; + value_text_display = 0; + field_38C = 0.0f; + value_text_index = 0; + value_text_time_offset = 0.0f; + combo_count = 0; + combo_disp_time = 0; + combo_pos = 0.0f; +} + +#pragma warning(push) +#pragma warning(disable: 6385) +#pragma warning(disable: 6386) +void pv_game_play_data::sub_1401378E0(bool disp, int32_t index, int32_t a4, float_t a5) { + if (index < 0 || index > 1) + return; + + field_1F8[index] = disp; + field_1FC[index] = a4; + + switch (index) { + case 0: + /*if (game_skin_get()->check_skin()) { + set_aet_id_visible_enable(PV_GAME_AET_TOP_FRONT , disp); + set_aet_id_visible_enable(PV_GAME_AET_BOTTOM_FRONT, disp); + set_aet_id_visible_enable(PV_GAME_AET_TOP_BACK , disp); + set_aet_id_visible_enable(PV_GAME_AET_BOTTOM_BACK , disp); + } + else */{ + set_aet_id_visible_enable(PV_GAME_AET_FRAME_BOTTOM, disp); + set_aet_id_visible_enable(PV_GAME_AET_FRAME_UP , disp); + } + + set_aet_id_visible_enable(PV_GAME_AET_0 , disp); + set_aet_id_visible_enable(PV_GAME_AET_1 , disp); + set_aet_id_visible_enable(PV_GAME_AET_SONG_ICON , disp); + set_aet_id_visible_enable(PV_GAME_AET_LEVEL_INFO , disp); + set_aet_id_visible_enable(PV_GAME_AET_OPTION_INFO_BASE , disp); + set_aet_id_visible_enable(PV_GAME_AET_OPTION_INFO_HISPEED , disp); + set_aet_id_visible_enable(PV_GAME_AET_OPTION_INFO_HIDDEN , disp); + set_aet_id_visible_enable(PV_GAME_AET_OPTION_INFO_SUDDEN , disp); + set_aet_id_visible_enable(PV_GAME_AET_SONG_ENERGY_BASE , disp); + set_aet_id_visible_enable(PV_GAME_AET_SONG_ENERGY_BASE_REACH , disp); + set_aet_id_visible_enable(PV_GAME_AET_SONG_ENERGY_EDGE_LINE02, disp); + set_aet_id_visible_enable(PV_GAME_AET_STAGE_INFO , disp); + + set_song_energy(disp); + break; + case 1: + set_aet_id_visible_enable(PV_GAME_AET_CHANCE_FRAME_BOTTOM, disp); + set_aet_id_visible_enable(PV_GAME_AET_CHANCE_FRAME_TOP , disp); + break; + } + + if (a4 == 3) { + if (a5 <= 0.0f) { + field_1FC[index] = 1; + field_1C8[index] = 0.0f; + field_1D8[index] = 0.0f; + field_218 = true; + + if (!index) { + field_1E8[0] = 0.0f; + field_1F0[0] = 0.0f; + } + } + else { + field_1D0[index] = (1.0f / a5) * field_20C[index]; + field_1E0[index] = (1.0f / a5) * field_204[index]; + + if (!index) { + if (field_1E8[1] < 0.0f) + field_1E8[1] = (1.0f / a5) * field_204[index]; + if (field_1F0[1] < 0.0f) + field_1F0[1] = (1.0f / a5) * field_20C[0]; + } + } + } + else if (a4 == 4) { + if (a5 <= 0.0f) { + field_1FC[index] = 2; + field_1C8[index] = field_20C[index]; + field_1D8[index] = field_204[index]; + } + else { + field_1D0[index] = (1.0f / a5) * field_20C[index]; + field_1E0[index] = (1.0f / a5) * field_204[index]; + } + } + + sub_140138A30(); +} +#pragma warning(pop) + +void pv_game_play_data::sub_140137BE0() { + if (!loaded) + return; + + field_36C = -1; + update = false; + field_378 = false; + score_speed = 0.04f; + combo_state = 4; + + for (uint32_t& i : aet_ids) + aet_manager_free_aet_object_reset(&i); + + sub_1401362C0(); + sub_140135ED0(); +} + +void pv_game_play_data::sub_140137DD0(int32_t a2, float_t delta_time, vec2& pos, int32_t combo_count) { + if (!update) + return; + + if (field_36C != a2) { + if (a2 > 3) + init_aet_frame(false); + else + init_aet_frame(!pv_game_get()->data.no_fail); + field_36C = a2; + } + + switch (value_text_display) { + case 1: + init_aet_combo(value_text_index, pos.x, pos.y, combo_count); + field_38C = 0.025f; + value_text_display = 2; + break; + case 2: + field_38C -= delta_time; + if (field_38C <= 0.0f) { + field_38C = 2.0f; + value_text_display = 3; + } + break; + case 3: + field_38C -= delta_time; + if (field_38C <= 0.0f) + value_text_display = 0; + break; + } + set_song_energy(field_1F8[0]); + + float_t alpha = field_33C % 60 < 30 ? 1.0f : 0.0f; + set_aet_id_alpha(PV_GAME_AET_SONG_ENERGY_EFF_NORMAL, alpha); + set_aet_id_alpha(PV_GAME_AET_SONG_ENERGY_EFF_REACH , alpha); + set_aet_id_alpha(PV_GAME_AET_SONG_ENERGY_BASE_REACH, alpha); + + field_33C++; +} + +void pv_game_play_data::sub_140137F80(bool update, float_t a3) { + if (update) { + sub_1401378E0(true, 0, 3, a3 * 60.0f); + update = true; + } + else { + sub_1401378E0(true, 0, 4, a3 * 60.0f); + update = false; + } +} + +void pv_game_play_data::sub_1401385F0(float_t delta_time){ + if (!update) + return; + + combo_ctrl(delta_time); + skin_danger_ctrl(); + + if (field_378) { + switch (field_374) { + case 0: + init_aet_chance_txt(true); + field_374++; + field_37C = 0.0f; + break; + case 1: + if (field_37C >= 2.0f) + field_374 = 2; + break; + case 2: + if (aet_manager_get_obj_end(aet_ids[PV_GAME_AET_CHANCE_TXT])) { + aet_manager_free_aet_object_reset(&aet_ids[PV_GAME_AET_CHANCE_TXT]); + field_374++; + } + break; + case 4: + init_aet_chance_txt(false); + field_374++; + field_37C = 0.0f; + break; + case 5: + if (field_37C >= 2.0f) + field_374 = 6; + break; + case 6: + if (aet_manager_get_obj_end(aet_ids[PV_GAME_AET_CHANCE_TXT])) { + aet_manager_free_aet_object_reset(&aet_ids[PV_GAME_AET_CHANCE_TXT]); + field_374 = 0; + field_378 = false; + } + break; + } + + field_37C += delta_time; + } + + if (aet_manager_get_obj_end(aet_ids[PV_GAME_AET_CHANCE_POINT])) + aet_manager_free_aet_object_reset(&aet_ids[PV_GAME_AET_CHANCE_POINT]); + if (aet_manager_get_obj_end(aet_ids[PV_GAME_AET_SLIDE_POINT])) + aet_manager_free_aet_object_reset(&aet_ids[PV_GAME_AET_SLIDE_POINT]); + if (aet_manager_get_obj_end(aet_ids[PV_GAME_AET_MAX_SLIDE_POINT])) + aet_manager_free_aet_object_reset(&aet_ids[PV_GAME_AET_MAX_SLIDE_POINT]); + if (aet_manager_get_obj_end(aet_ids[PV_GAME_AET_MAX_SLIDE_NUM_PLUS])) + aet_manager_free_aet_object_reset(&aet_ids[PV_GAME_AET_MAX_SLIDE_NUM_PLUS]); + if (aet_manager_get_obj_end(aet_ids[PV_GAME_AET_MAX_SLIDE_NUM_0])) + aet_manager_free_aet_object_reset(&aet_ids[PV_GAME_AET_MAX_SLIDE_NUM_0]); + if (aet_manager_get_obj_end(aet_ids[PV_GAME_AET_MAX_SLIDE_NUM_1])) + aet_manager_free_aet_object_reset(&aet_ids[PV_GAME_AET_MAX_SLIDE_NUM_1]); + if (aet_manager_get_obj_end(aet_ids[PV_GAME_AET_MAX_SLIDE_NUM_2])) + aet_manager_free_aet_object_reset(&aet_ids[PV_GAME_AET_MAX_SLIDE_NUM_2]); + if (aet_manager_get_obj_end(aet_ids[PV_GAME_AET_MAX_SLIDE_NUM_3])) + aet_manager_free_aet_object_reset(&aet_ids[PV_GAME_AET_MAX_SLIDE_NUM_3]); + if (aet_manager_get_obj_end(aet_ids[PV_GAME_AET_MAX_SLIDE_NUM_4])) + aet_manager_free_aet_object_reset(&aet_ids[PV_GAME_AET_MAX_SLIDE_NUM_4]); + if (aet_manager_get_obj_end(aet_ids[PV_GAME_AET_MAX_SLIDE_NUM_5])) + aet_manager_free_aet_object_reset(&aet_ids[PV_GAME_AET_MAX_SLIDE_NUM_5]); + if (aet_manager_get_obj_end(aet_ids[PV_GAME_AET_MAX_SLIDE_NUM_6])) + aet_manager_free_aet_object_reset(&aet_ids[PV_GAME_AET_MAX_SLIDE_NUM_6]); + + if (aet_ids[PV_GAME_AET_VALUE_TEXT] && (aet_manager_get_obj_end(aet_ids[PV_GAME_AET_VALUE_TEXT]) + || aet_manager_get_obj_frame(aet_ids[PV_GAME_AET_VALUE_TEXT]) > 60.0f)) + aet_manager_free_aet_object_reset(&aet_ids[PV_GAME_AET_VALUE_TEXT]); +} + +void pv_game_play_data::sub_140138A30() { + const vec3 v16 = { 0.0f, field_1C8[0], 0.0f }; + const vec3 v18 = { 0.0f, field_1C8[1], 0.0f }; + const vec3 v17 = { 0.0f, -field_1D8[0], 0.0f }; + const vec3 v19 = { 0.0f, -field_1D8[1], 0.0f }; + const vec3 v15 = { 0.0f, -field_1E8[0], 0.0f }; + const vec3 v14 = { 0.0f, field_1F0[0], 0.0f }; + + /*if (game_skin_get()->check_skin()) { + set_aet_id_position(PV_GAME_AET_BOTTOM_FRONT, v16); + set_aet_id_position(PV_GAME_AET_BOTTOM_BACK , v16); + } + else*/ + set_aet_id_position(PV_GAME_AET_FRAME_BOTTOM, v16); + + set_aet_id_position(PV_GAME_AET_0 , v16); + set_aet_id_position(PV_GAME_AET_1 , v16); + set_aet_id_position(PV_GAME_AET_SONG_ENERGY_BASE , v14); + set_aet_id_position(PV_GAME_AET_SONG_ENERGY_BASE_REACH , v14); + set_aet_id_position(PV_GAME_AET_SONG_ENERGY_NORMAL , v14); + set_aet_id_position(PV_GAME_AET_SONG_ENERGY_REACH , v14); + set_aet_id_position(PV_GAME_AET_SONG_ENERGY_FULL , v14); + set_aet_id_position(PV_GAME_AET_SONG_ENERGY_EFF_NORMAL , v14); + set_aet_id_position(PV_GAME_AET_SONG_ENERGY_EFF_REACH , v14); + set_aet_id_position(PV_GAME_AET_SONG_ENERGY_CLEAR_TXT , v14); + set_aet_id_position(PV_GAME_AET_SONG_ENERGY_NOT_CLEAR , v14); + set_aet_id_position(PV_GAME_AET_SONG_ENERGY_NOT_CLEAR_TXT , v14); + set_aet_id_position(PV_GAME_AET_SONG_ENERGY_BORDER_GREAT , v14); + set_aet_id_position(PV_GAME_AET_SONG_ENERGY_BORDER_EXCELLENT, v14); + set_aet_id_position(PV_GAME_AET_SONG_ENERGY_BORDER_RIVAL , v14); + set_aet_id_position(PV_GAME_AET_SONG_ENERGY_EDGE_LINE02 , v14); + set_aet_id_position(PV_GAME_AET_SONG_ENERGY_BORDER , v14); + set_aet_id_position(PV_GAME_AET_STAGE_INFO , v16); + + /*if (game_skin_get()->check_skin()) { + set_aet_id_position(PV_GAME_AET_TOP_FRONT, v17); + set_aet_id_position(PV_GAME_AET_TOP_BACK , v17); + } + else*/ + set_aet_id_position(PV_GAME_AET_FRAME_UP , v17); + + set_aet_id_position(PV_GAME_AET_CHANCE_FRAME_BOTTOM, v18); + set_aet_id_position(PV_GAME_AET_CHANCE_FRAME_TOP , v19); + set_aet_id_position(PV_GAME_AET_SONG_ICON , v15); + set_aet_id_position(PV_GAME_AET_LEVEL_INFO , v15); + set_aet_id_position(PV_GAME_AET_OPTION_INFO_BASE , v15); + set_aet_id_position(PV_GAME_AET_OPTION_INFO_HISPEED, v15); + set_aet_id_position(PV_GAME_AET_OPTION_INFO_HIDDEN , v15); + set_aet_id_position(PV_GAME_AET_OPTION_INFO_SUDDEN , v15); +} + +void pv_game_play_data::sub_140138D60() { + for (int32_t i = 0; i < 2; i++) { + if (field_1FC[i] == 3) { + field_1C8[i] = field_1C8[i] - field_1D0[i]; + field_1C8[i] = max_def(field_1C8[i], 0.0f); + + field_1D8[i] = field_1D8[i] - field_1E0[i]; + field_1D8[i] = max_def(field_1D8[i], 0.0f); + + if (field_1C8[i] == 0.0f && field_1D8[i] == 0.0f) + field_1FC[i] = 1; + } + else if (field_1FC[i] == 4) { + field_1C8[i] = field_1D0[i] + field_1C8[i]; + field_1C8[i] = min_def(field_1C8[i], field_20C[i]); + + field_1D8[i] = field_1E0[i] + field_1D8[i]; + field_1D8[i] = min_def(field_1D8[i], field_204[i]); + + if (field_1C8[i] == field_20C[i] && field_1D8[i] == field_204[i]) + field_1FC[i] = 2; + } + } + + if (field_1E8[1] > 0.0f) + field_1E8[0] -= field_1E8[1]; + field_1E8[0] = max_def(field_1E8[0], 0.0f); + + if (field_1F0[1] > 0.0f) + field_1F0[0] -= field_1F0[1]; + field_1F0[0] = max_def(field_1F0[0], 0.0f); + + sub_140138A30(); + + if (field_1FC[0] == 1) + field_218 = true; + + int32_t v13 = 0; + bool v15 = false; + if (!sub_14013C8C0()->sub_1400E7920() && field_1F8[0]) { + if (field_1FC[0] == 1 || !field_218) + v15 = true; + v13 = (int32_t)-field_1E8[0]; + } + + task_game_2d_sub_140372670(v15); + task_game_2d_sub_1403726D0(v13); + task_game_2d_set_energy_unit_no_fail(pv_game_get()->data.no_fail); +} + +void pv_game_play_data::sub_140138F30() { + for (int32_t i = PV_GAME_AET_0; i <= PV_GAME_AET_SONG_ICON; i++) + set_aet_id_visible((pv_game_aet)i, aet_ids_enable[i]); +} + +void pv_game_play_data::sub_14013C320() { + data_struct* aft_data = &data_list[DATA_AFT]; + aet_database* aft_aet_db = &aft_data->data_ft.aet_db; + + if (pv_set && pv_aet_set_id != -1) + aet_manager_free_aet_set_objects(pv_aet_set_id, aft_aet_db); + + aet_manager_free_aet_set_objects(3, aft_aet_db); +} + +float_t get_percentage_clear_excellent() { + return percentage_clear_excellent[sub_14013C8C0()->difficulty]; +} + +float_t get_percentage_clear_great() { + return percentage_clear_great[sub_14013C8C0()->difficulty]; +} diff --git a/src/ReDIVA/pv_game/pv_game_play_data.hpp b/src/ReDIVA/pv_game/pv_game_play_data.hpp new file mode 100644 index 00000000..26c5026d --- /dev/null +++ b/src/ReDIVA/pv_game/pv_game_play_data.hpp @@ -0,0 +1,323 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#pragma once + +#include "../../CRE/auth_2d.hpp" +#include "../../CRE/pv_db.hpp" + +enum pv_game_aet { + PV_GAME_AET_0 = 0, + PV_GAME_AET_1, + PV_GAME_AET_VALUE_TEXT, + PV_GAME_AET_COMBO, + PV_GAME_AET_CHANCE_TXT, + PV_GAME_AET_CHANCE_POINT, + PV_GAME_AET_SLIDE_POINT, + PV_GAME_AET_MAX_SLIDE_POINT, + PV_GAME_AET_MAX_SLIDE_NUM_PLUS, + PV_GAME_AET_MAX_SLIDE_NUM_0, + PV_GAME_AET_MAX_SLIDE_NUM_1, + PV_GAME_AET_MAX_SLIDE_NUM_2, + PV_GAME_AET_MAX_SLIDE_NUM_3, + PV_GAME_AET_MAX_SLIDE_NUM_4, + PV_GAME_AET_MAX_SLIDE_NUM_5, + PV_GAME_AET_MAX_SLIDE_NUM_6, + PV_GAME_AET_FRAME_BOTTOM, + PV_GAME_AET_FRAME_UP, + PV_GAME_AET_CHANCE_FRAME_BOTTOM, + PV_GAME_AET_CHANCE_FRAME_TOP, + PV_GAME_AET_20, + PV_GAME_AET_STAGE_INFO, + PV_GAME_AET_SONG_ENERGY_BASE, + PV_GAME_AET_SONG_ENERGY_BASE_REACH, + PV_GAME_AET_SONG_ENERGY_NORMAL, + PV_GAME_AET_SONG_ENERGY_REACH, + PV_GAME_AET_SONG_ENERGY_FULL, + PV_GAME_AET_SONG_ENERGY_EFF_NORMAL, + PV_GAME_AET_SONG_ENERGY_EFF_REACH, + PV_GAME_AET_SONG_ENERGY_CLEAR_TXT, + PV_GAME_AET_SONG_ENERGY_BORDER_GREAT, + PV_GAME_AET_SONG_ENERGY_BORDER_EXCELLENT, + PV_GAME_AET_SONG_ENERGY_BORDER_RIVAL, + PV_GAME_AET_SONG_ENERGY_EDGE_LINE02, + PV_GAME_AET_SONG_ENERGY_BORDER, + PV_GAME_AET_SONG_ENERGY_NOT_CLEAR, + PV_GAME_AET_SONG_ENERGY_NOT_CLEAR_TXT, + PV_GAME_AET_NEXT_INFO, + PV_GAME_AET_LEVEL_INFO, + PV_GAME_AET_OPTION_INFO_BASE, + PV_GAME_AET_OPTION_INFO_HISPEED, + PV_GAME_AET_OPTION_INFO_HIDDEN, + PV_GAME_AET_OPTION_INFO_SUDDEN, + PV_GAME_AET_SONG_ICON, + PV_GAME_AET_SUCCESS_INFO, + PV_GAME_AET_DEMO_LOGO, + PV_GAME_AET_46, + PV_GAME_AET_DEMO_FONT, + PV_GAME_AET_FRONT_0, + PV_GAME_AET_FRONT_1, + PV_GAME_AET_FRONT_2, + PV_GAME_AET_FRONT_3, + PV_GAME_AET_FRONT_4, + PV_GAME_AET_FRONT_5, + PV_GAME_AET_FRONT_6, + PV_GAME_AET_FRONT_7, + PV_GAME_AET_FRONT_LOW_0, + PV_GAME_AET_FRONT_LOW_1, + PV_GAME_AET_FRONT_LOW_2, + PV_GAME_AET_FRONT_LOW_3, + PV_GAME_AET_FRONT_LOW_4, + PV_GAME_AET_FRONT_LOW_5, + PV_GAME_AET_FRONT_LOW_6, + PV_GAME_AET_FRONT_LOW_7, + PV_GAME_AET_FRONT_3D_SURF_0, + PV_GAME_AET_FRONT_3D_SURF_1, + PV_GAME_AET_FRONT_3D_SURF_2, + PV_GAME_AET_FRONT_3D_SURF_3, + PV_GAME_AET_FRONT_3D_SURF_4, + PV_GAME_AET_FRONT_3D_SURF_5, + PV_GAME_AET_FRONT_3D_SURF_6, + PV_GAME_AET_FRONT_3D_SURF_7, + PV_GAME_AET_BACK_0, + PV_GAME_AET_BACK_1, + PV_GAME_AET_BACK_2, + PV_GAME_AET_BACK_3, + PV_GAME_AET_BACK_4, + PV_GAME_AET_BACK_5, + PV_GAME_AET_BACK_6, + PV_GAME_AET_BACK_7, + PV_GAME_AET_TITLE_IMAGE, + PV_GAME_AET_WHITE_FADE, + PV_GAME_AET_BLACK_FADE, + PV_GAME_AET_83, + PV_GAME_AET_84, + PV_GAME_AET_TOP_FRONT, + PV_GAME_AET_BOTTOM_FRONT, + PV_GAME_AET_TOP_BACK, + PV_GAME_AET_BOTTOM_BACK, + PV_GAME_AET_EDIT_EFFECT, + PV_GAME_AET_MAX, + + PV_GAME_AET_MAX_SLIDE_NUM = PV_GAME_AET_MAX_SLIDE_NUM_0, + PV_GAME_AET_FRONT = PV_GAME_AET_FRONT_0, + PV_GAME_AET_FRONT_LOW = PV_GAME_AET_FRONT_LOW_0, + PV_GAME_AET_FRONT_3D_SURF = PV_GAME_AET_FRONT_3D_SURF_0, + PV_GAME_AET_BACK = PV_GAME_AET_BACK_0, +}; + +struct pv_disp2d { + int32_t pv_id; + int32_t title_start_2d_field; + int32_t title_end_2d_field; + int32_t title_start_2d_low_field; + int32_t title_end_2d_low_field; + int32_t title_start_3d_field; + int32_t title_end_3d_field; + bool target_shadow_type; + uint32_t pv_spr_set_id; + uint32_t pv_aet_set_id; + uint32_t pv_aet_id; + std::string title_2d_layer; + + pv_disp2d(); + ~pv_disp2d(); +}; + +struct pv_game_play_data { + bool pv_set; + uint32_t aet_ids[PV_GAME_AET_MAX]; + bool aet_ids_enable[PV_GAME_AET_MAX]; + float_t field_1C8[2]; + float_t field_1D0[2]; + float_t field_1D8[2]; + float_t field_1E0[2]; + float_t field_1E8[2]; + float_t field_1F0[2]; + bool field_1F8[2]; + int32_t field_1FC[2]; + float_t field_204[2]; + float_t field_20C[2]; + int32_t frame_state; + bool field_218; + bool fade_begin; + bool fade_end; + pv_game_aet fade; + int32_t skin_danger_frame; + aet_layout_data song_txt[2]; + int32_t field_2FC; + int32_t chance_result; + int32_t chance_points; + vec2 chance_points_pos; + int32_t field_310; + int32_t slide_points; + vec2 slide_points_pos; + int32_t max_slide_points; + vec2 max_slide_points_pos; + int32_t pv_spr_set_id; + int32_t pv_aet_set_id; + int32_t pv_aet_id; + int32_t stage_index; + int32_t field_33C; + AetComp comp; + float_t field_350; + bool field_354; + int32_t value_text_spr_index; + bool not_clear; + int32_t spr_set_back_id; + bool loaded; + int32_t state; + int32_t field_36C; + bool update; + int32_t field_374; + bool field_378; + float_t field_37C; + float_t score_speed; + uint32_t score; + int32_t value_text_display; + float_t field_38C; + int32_t value_text_index; + float_t value_text_time_offset; + int32_t combo_state; + int32_t combo_count; + float_t combo_disp_time; + vec2 combo_pos; + int32_t field_3AC; + int32_t field_3B0; + int32_t field_3B4; + int32_t field_3B8; + int32_t field_3BC; + bool aix; + bool ogg; + int32_t field_3C4; + std::string song_name; + std::string se_name; + std::string pvbranch_success_se_name; + std::string slide_name; + std::string chainslide_first_name; + std::string chainslide_sub_name; + std::string chainslide_success_name; + std::string chainslide_failure_name; + std::string slidertouch_name; + std::string other_se_name; + std::string other_slide_name; + std::string other_chainslide_first_name; + std::string other_chainslide_sub_name; + std::string other_chainslide_success_name; + std::string other_chainslide_failure_name; + std::string other_slidertouch_name; + std::string song_file_name; + int32_t ex_song_index; + float_t field_5EC; + int32_t option; + float_t field_5F4; + char lyric[76]; + bool lyric_set; + vec4u8 lyrics_color; + bool field_64C; + int32_t field_650; + float_t field_654; + int32_t field_658; + float_t field_65C; + + pv_game_play_data(); + ~pv_game_play_data(); + + void combo_ctrl(float_t delta_time); + void disable_update(); + void disp(); + void disp_chance_point(); + void disp_chance_points(int32_t chance_points, float_t pos_x, float_t pos_y); + void disp_chance_txt(); + void disp_combo(); + void disp_max_slide_point(); + void disp_score(); + void disp_slide_point(); + void disp_slide_points(int32_t max_slide_point, float_t pos_x, float_t pos_y, bool max_slide); + void disp_song_energy(); + void disp_spr_set_back(); + void fade_begin_ctrl(); + bool fade_end_ctrl(); + void free_aet(pv_aet aet, int32_t index); + void free_aet_title_image(); + float_t get_aet_frame(pv_aet aet, int32_t index); + float_t get_aet_id_frame(pv_game_aet aet_index); + bool get_aet_next_info_disp(); + int32_t get_digit_count(int32_t score, int32_t digits); + void init_aet(pv_aet aet, int32_t index, std::string&& layer_name, std::string&& aet_name, + bool* not_init, float_t start_time, float_t end_time, FrameRateControl* frame_rate_control); + void init_aet_black_fade(); + void init_aet_chance_frame(); + void init_aet_chance_point(int32_t chance_points, float_t pos_x, float_t pos_y); + void init_aet_chance_txt(bool end); + void init_aet_combo(int32_t target_display_index, + float_t pos_x, float_t pos_y, int32_t combo_count); + void init_aet_demo_font(); + void init_aet_demo_logo(); + float_t init_aet_edit_effect(int32_t aet_id, const char* name, bool loop, bool low_field); + void init_aet_frame(bool danger); + uint32_t init_aet_gam_cmn(pv_game_aet aet_index, spr::SprPrio prio, + AetFlags flags, const char* layer_name, const vec2* pos = 0, const vec2* scale = 0); + void init_aet_id(int32_t aet_id, const char* layer_name, + int32_t index, pv_game_aet aet_index, spr::SprPrio prio, bool* not_init, + float_t start_time, float_t end_time, FrameRateControl* frame_rate_control); + void init_aet_level_info(); + void init_aet_next_info(); + void init_aet_option_info(); + void init_aet_slide_max(int32_t slide_point, float_t pos_x, float_t pos_y); + void init_aet_slide_point(int32_t slide_point, float_t pos_x, float_t pos_y); + void init_aet_song_energy(); + void init_aet_song_icon_loop(); + void init_aet_stage_info(); + void init_aet_success_info(); + void init_aet_title_image(const char* name); + void init_aet_white_fade(); + bool load_auth_2d(int32_t stage_index, pv_disp2d* disp2d); + bool load_auth_2d_data(); + void read_auth_2d_data(); + void reset(); + void set_aet_edit_effect_frame(float_t frame); + void set_aet_end_time(pv_aet aet, int32_t index, float_t value); + void set_aet_frame(pv_aet aet, int32_t index, float_t value); + void set_aet_id_alpha(pv_game_aet aet_index, float_t value); + void set_aet_id_end_time(pv_game_aet aet_index, float_t value); + void set_aet_id_frame(pv_game_aet aet_index, float_t value); + void set_aet_id_play(pv_game_aet aet_index, bool value); + void set_aet_id_position(pv_game_aet aet_index, const vec3& position); + void set_aet_id_visible(pv_game_aet aet_index, bool value); + void set_aet_id_visible_enable(pv_game_aet aet_index, bool value); + void set_aet_song_energy(); + void set_aet_visible(pv_aet aet, int32_t index, bool value); + void set_not_clear(); + void set_pv_disp2d(pv_disp2d* disp2d); + void set_song_energy(bool disp); + void set_spr_set_back_id(int32_t value); + void set_stage_index(int32_t value); + void set_value_text(int32_t index, float_t time_offset); + void skin_danger_ctrl(); + void score_update(uint32_t score_final, bool update); + void unload(); + void unload_aet(); + void unload_auth_2d(); + + void sub_140134670(int32_t chance_result); + void sub_140134730(); + void sub_1401349B0(); + void sub_1401349C0(uint32_t set_id); + void sub_140135ED0(); + void sub_1401362C0(); + void sub_1401378E0(bool disp, int32_t index, int32_t a4, float_t a5); + void sub_140137BE0(); + void sub_140137DD0(int32_t a2, float_t delta_time, vec2& pos, int32_t combo_count); + void sub_140137F80(bool a2, float_t a3); + void sub_1401385F0(float_t delta_time); + void sub_140138A30(); + void sub_140138D60(); + void sub_140138F30(); + void sub_14013C320(); +}; + +extern float_t get_percentage_clear_excellent(); +extern float_t get_percentage_clear_great(); diff --git a/src/ReDIVA/pv_game/pv_game_pv_data.cpp b/src/ReDIVA/pv_game/pv_game_pv_data.cpp new file mode 100644 index 00000000..4387e287 --- /dev/null +++ b/src/ReDIVA/pv_game/pv_game_pv_data.cpp @@ -0,0 +1,2595 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#include "pv_game_pv_data.hpp" +#include "../../CRE/rob/motion.hpp" +#include "../../CRE/pv_expression.hpp" +#include "../../CRE/pv_param.hpp" +#include "pv_game.hpp" +#include "pv_game_camera.hpp" +#include "pv_game_music.hpp" + +struct struc_595 { + const char* name; + int32_t mottbl_index; + int32_t field_C; + int32_t field_10; +}; + +struct struc_595 stru_1409A0AA0[] = { + { "通常", 0xA7, 0, 0 }, + { "カメラ目線", 0xA7, 1, 0 }, + { "上", 0xA9, 0, 0 }, + { "下", 0xAB, 0, 0 }, + { "左", 0xAD, 0, 0 }, + { "右", 0xAF, 0, 0 }, + { "右上", 0xB3, 0, 0 }, + { "右下", 0xB7, 0, 0 }, + { "左上", 0xB1, 0, 0 }, + { "左下", 0xB5, 0, 0 }, + { "上 → 下", 0xB9, 2, 8 }, + { "下 → 上", 0xB9, 3, 8 }, + { "左 → 右", 0xBB, 2, 8 }, + { "右 → 左", 0xBB, 3, 8 }, + { "左上 → 右下", 0xBD, 2, 8 }, + { "右上 → 左下", 0xBF, 2, 8 }, + { "右下 → 左上", 0xBD, 3, 8 }, + { "左下 → 右上", 0xBF, 3, 8 }, + { "中央 → 上", 0xA9, 2, 8 }, + { "中央 → 下", 0xAB, 2, 8 }, + { "中央 → 左", 0xAD, 2, 8 }, + { "中央 → 右", 0xAF, 2, 8 }, + { "中央 → 右上", 0xB3, 2, 8 }, + { "中央 → 右下", 0xB7, 2, 8 }, + { "中央 → 左上", 0xB1, 2, 8 }, + { "中央 → 左下", 0xB5, 2, 8 }, + { "上 → 中央", 0xA9, 3, 8 }, + { "下 → 中央", 0xAB, 3, 8 }, + { "左 → 中央", 0xAD, 3, 8 }, + { "右 → 中央", 0xAF, 3, 8 }, + { "右上 → 中央", 0xB3, 3, 8 }, + { "右下 → 中央", 0xB7, 3, 8 }, + { "左上 → 中央", 0xB1, 3, 8 }, + { "左下 → 中央", 0xB5, 3, 8 }, + { "上", 0xA8, 0, 0 }, +}; + +struct struc_595 stru_1409A0DD0[] = { + { "下", 0xAA, 0, 0 }, + { "右", 0xAE, 0, 0 }, + { "左", 0xAC, 0, 0 }, + { "右上", 0xB2, 0, 0 }, + { "左上", 0xB0, 0, 0 }, + { "右下", 0xB6, 0, 0 }, + { "左下", 0xB4, 0, 0 }, + { "カメラ目線", 0xA6, 1, 0 }, + { "通常", 0xA6, 0, 0 }, + { "通常", 0xA5, 0, 0 }, +}; + +extern render_context* rctx_ptr; + +extern bool light_chara_ambient; +extern vec4 npr_cloth_spec_color; + +pv_play_data_set_motion::pv_play_data_set_motion() : frame_speed(), motion_id(), +frame(), blend_duration(), blend(), disable_eye_motion(), dsc_frame() { + blend_type = MOTION_BLEND_CROSS; + motion_index = -1; + dsc_time = -1; +} + +void pv_play_data_set_motion::reset() { + frame_speed = 0.0f; + motion_id = 0; + frame = 0.0f; + blend_duration = 0.0f; + blend = false; + blend_type = MOTION_BLEND_CROSS; + disable_eye_motion = false; + motion_index = -1; + dsc_time = -1; + dsc_frame = 0.0f; +} + +pv_play_data_motion_data::pv_play_data_motion_data() : rob_chr(), current_time(), +duration(), start_pos(), end_pos(), start_rot(), end_rot() { + mot_smooth_len = 12.0f; +} + +pv_play_data_motion_data::~pv_play_data_motion_data() { + +} + +void pv_play_data_motion_data::ctrl(float_t delta_time) { + if (!rob_chr || current_time > duration) + return; + + current_time += delta_time; + ctrl_inner(); +} + +void pv_play_data_motion_data::ctrl_inner() { + if (!rob_chr) + return; + + vec3 pos; + float_t rot; + if (current_time >= duration || duration <= 0.0f) { + pos = end_pos; + rot = end_rot; + } + else { + float_t t = current_time / duration; + pos = vec3::lerp(start_pos, end_pos, t); + rot = lerp_def(start_rot, start_rot, t); + } + + rob_chr->set_data_miku_rot_position(pos); + rob_chr->set_data_miku_rot_rot_y_int16((int16_t)((rot * 32768.0f) * (float_t)(1.0 / 180.0))); + rob_chr->set_osage_reset(); + + if (rob_chr->check_for_ageageagain_module()) { + if (fabs(vec3::distance(start_pos, end_pos) <= 0.000001f && fabsf(end_rot - start_rot) <= 0.000001f)) { + rob_chara_age_age_array_set_skip(rob_chr->chara_id, 1); + rob_chara_age_age_array_set_skip(rob_chr->chara_id, 2); + } + rob_chara_age_age_array_set_step_full(rob_chr->chara_id, 1); + rob_chara_age_age_array_set_step_full(rob_chr->chara_id, 2); + } +} + +void pv_play_data_motion_data::clear() { + set_motion.clear(); + set_motion.shrink_to_fit(); + item_anim.clear(); + item_anim.shrink_to_fit(); +} + +void 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(); + item_anim.clear(); + item_anim.shrink_to_fit(); +} + +void pv_play_data_motion_data::set(rob_chara* rob_chr, float_t duration, + vec3 start_pos, vec3 end_pos, float_t start_rot, float_t end_rot) { + this->rob_chr = rob_chr; + this->current_time = 0.0; + this->duration = duration; + this->start_pos = start_pos; + this->end_pos = end_pos; + + while (start_rot < -180.0f) + start_rot += 360.0f; + + while (start_rot > 180.0f) + start_rot += -360.0f; + + while (end_rot < -180.0f) + end_rot += 360.0f; + + while (end_rot > 180.0f) + end_rot += -360.0f; + + if (end_rot < start_rot) + end_rot += 360.0f; + + if (end_rot >= start_rot + 180.0f) + end_rot += -360.0f; + + this->start_rot = start_rot; + this->end_rot = end_rot; +} + +pv_play_data::pv_play_data() : rob_chr(), disp(), shadow() { + +} + +pv_play_data::~pv_play_data() { + +} + +pv_play_data_motion* pv_play_data::get_motion(int32_t motion_index) { + for (::pv_play_data_motion& i : motion) + if (i.motion_index == motion_index) + return &i; + return 0; +} + +void pv_play_data::reset() { + motion.clear(); + motion.shrink_to_fit(); + rob_chr = 0; + set_motion.clear(); + disp = true; + motion_data.reset(); +} + +pv_data_camera::pv_data_camera() : enable(), time() { + index = -1; +} + +pv_scene_fade::pv_scene_fade() : enable(), time(), duration(), start_alpha(), end_alpha() { + +} + +void pv_scene_fade::ctrl(float_t delta_time) { + if (!enable) + return; + + time += delta_time; + + float_t alpha; + bool end; + if (duration <= time || duration <= 0.0f) { + alpha = this->end_alpha; + end = true; + } + else { + alpha = lerp_def(start_alpha, end_alpha, time / duration); + end = false; + } + + rctx_ptr->post_process.tone_map->set_scene_fade_color(color); + rctx_ptr->post_process.tone_map->set_scene_fade_alpha(alpha); + + if (end) + reset(); +} + +void pv_scene_fade::reset() { + enable = false; + time = 0.0f; + duration = 0.0f; + start_alpha = 0.0f; + end_alpha = 0.0f; + color = 0.0f; +} + +pv_dsc_target::pv_dsc_target() : amplitude(), frequency(), slide_chain_start(), +slide_chain_end(), slide_chain_left(), slide_chain_right(), slide_chain() { + type = DSC_TARGET_FT_MAX; +} + +pv_dsc_target_group::pv_dsc_target_group() : target_count(), field_94(), slide_chain() { + time_begin = -1; + time_end = -1; +} + +struc_676::struc_676() : field_0(), field_128(), field_130(), field_148(), field_270(), field_288(), +field_290(), field_2A8(), field_2C0(), field_2C4(), field_2C8(), field_2CC(), field_2D0() { + +} + +void struc_676::reset() { + for (int32_t i = 0; i < ROB_CHARA_COUNT; i++) { + field_0[i] = false; + field_8[i].reset(); + field_128[i] = false; + field_130[i] = 0; + field_148[i] = false; + field_150[i].reset(); + field_270[i] = 0.0f; + field_288[i] = false; + field_290[i] = 0; + field_2A8[i] = 0.0f; + } + + field_2C0 = false; + field_2C4 = 0; + field_2CC = 0.0f; + field_2D0 = 0; +} + +pv_game_pv_data::pv_game_pv_data() : field_0(), dsc_state(), play()/*, dsc_buffer(), dsc_buffer_counter()*/, +dsc_data_ptr(), dsc_data_ptr_end(), field_2BF38(), curr_time(), curr_time_float(), prev_time_float(), +field_2BF50(), field_2BF60(), field_2BF64(), field_2BF68(), chara_id(), pv_game()/*, field_2BF80()*/, +music(), dsc_file_handler(), +dsc_time(), music_play(), field_2BFC4(), +pv_end(), field_2BFD4(), field_2BFD5(), data_camera(), +has_signature(), has_perf_id(), targets_remaining(), target_index(), scene_rot_y(), +field_2C550(), branch_mode(), last_challenge_note(), field_2C560() { + field_2BF30 = -1; + field_2BF58 = -1i64; + field_2BFB0 = -1; + field_2BFB4 = -1; + field_2BFB8 = -1; + field_2BFBC = -1; + field_2BFC0 = true; + fov = 32.2673416137695f; + min_dist = 0.05f; + target_flying_time = -1.0f; + target_anim_fps = 60.0f; + anim_frame_speed = 1.0f; + time_signature = -1; + scene_rot_mat = mat4_identity; + field_2C54C = 1000.0f; + change_field_branch_time = -1; + first_challenge_note = -1; + + for (pv_play_data& i : playdata) + i.reset(); +} + +pv_game_pv_data::~pv_game_pv_data() { + +} + +int64_t pv_game_pv_data::ctrl(float_t delta_time, int64_t curr_time, bool a4) { + if (!field_0) + return 0; + + if (pv_game) + pv_game->edit_effect_ctrl(delta_time); + + if (!play) + return 0; + + for (pv_play_data& i : playdata) + i.motion_data.ctrl(delta_time); + + pv_game_camera_ctrl(delta_time); + + scene_fade_ctrl(delta_time); + + if (field_2BF30 < 0) + field_2BF30 = curr_time; + + this->curr_time = curr_time + field_2BF38 - field_2BF30; + curr_time_float = (float_t)((double_t)this->curr_time * 0.000000001); + + /*for (int32_t i = 0; i < 2; i++) + if (app::TaskWork::CheckTaskReady(task_movie_get(i))) { + if (pv_game_get()->loaded) + sub_14041F1B0(this->curr_time); + break; + }*/ + + + dsc_data* prev_dsc_data_ptr = dsc_data_ptr; + targets_remaining = 0; + + 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, this->curr_time, &dsc_time_offset, &music_play, a4, false); + + //if (prev_dsc_data_ptr != dsc_data_ptr) + // print_dsc_command(&dsc_buffer[dsc_buffer_counter], dsc_time); + + prev_dsc_data_ptr = dsc_data_ptr; + if (music_play) { + music_play = false; + prev_time_float = curr_time_float; + } + + if (!next) + break; + } + + return this->curr_time; +} + +/*void pv_game_pv_data::dsc_buffer_counter_set() { + dsc_get_start_position(&dsc_buffer_counter); +} + +void pv_game_pv_data::dsc_buffer_set(const void* data, uint32_t size) { + if (data) + memmove(this->dsc_buffer, data, size); + has_signature = true; + has_perf_id = true; + dsc_buffer_counter_set(); +}*/ + +bool pv_game_pv_data::dsc_ctrl(float_t delta_time, int64_t curr_time, float_t* dsc_time_offset, bool* music_play, bool a6, bool ignore_targets) { + if (sub_14013C8C0()->sub_1400E7910() >= 4 && field_2BF68 <= curr_time) + pv_game->set_lyric(-1, { 0xFF, 0xFF, 0xFF, 0xFF }); + + int32_t func = dsc_data_ptr->func; + uint32_t* data = dsc.get_func_data(dsc_data_ptr); + + if (branch_mode) { + bool v18; + if (!pv_game->loaded || pv_game->data.success) + v18 = branch_mode == 2; + else + v18 = branch_mode == 1; + + if (!v18) { + if (func < 0 || func >= DSC_FT_MAX) { + //sub_140859DBC("PV Script Command Error\n"); + play = false; + return false; + } + + if (func != DSC_FT_TIME && func != DSC_FT_PV_END && func != DSC_FT_PV_BRANCH_MODE) { + dsc_data_ptr++; + return true; + } + } + } + + dsc_data_ptr++; + + 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; + + pv_play_data* playdata = &this->playdata[chara_id]; + rob_chara* rob_chr = playdata->rob_chr; + + switch (func) { + case DSC_FT_END: { + //play = false; + return false; + } + case DSC_FT_TIME: { + dsc_time = 10000LL * (int32_t)data[0]; + *dsc_time_offset = 0.0f; + if (curr_time < dsc_time) + return false; + + *dsc_time_offset = (float_t)((double_t)(curr_time - dsc_time) * 0.000000001); + } break; + case DSC_FT_MIKU_MOVE: { + chara_id = (int32_t)data[0]; + playdata = &this->playdata[chara_id]; + rob_chr = playdata->rob_chr; + + vec3 pos; + pos = (float_t)(int32_t)data[1] * 0.001f; + pos = (float_t)(int32_t)data[2] * 0.001f; + pos = (float_t)(int32_t)data[3] * 0.001f; + + if (rob_chr) { + pos *= (pv_game->data.pv->edit == 2 ? 1.0f : 0.227f); + mat4_mult_vec3_trans(&scene_rot_mat, &pos, &pos); + rob_chr->set_data_miku_rot_position(pos); + rob_chr->set_osage_reset(); + } + } break; + case DSC_FT_MIKU_ROT: { + chara_id = (int32_t)data[0]; + playdata = &this->playdata[chara_id]; + rob_chr = playdata->rob_chr; + + float_t rot = (float_t)(int32_t)data[1] * 0.001f; + + if (rob_chr) { + rob_chr->set_data_miku_rot_rot_y_int16( + (int16_t)((rot + scene_rot_y) * 32768.0f * (float_t)(1.0 / 180.0))); + rob_chr->set_osage_reset(); + } + } break; + case DSC_FT_MIKU_DISP: { + chara_id = (int32_t)data[0]; + playdata = &this->playdata[chara_id]; + rob_chr = playdata->rob_chr; + + int32_t disp = (int32_t)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); + } + + pv_game->set_data_itmpv_visibility(chara_id, true); + for (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, 0, 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->set_disable_eye_motion(i.disable_eye_motion); + rob_chr->set_motion_step(i.frame_speed); + if (set) + pv_expression_array_set_motion(hash_murmurhash_empty, chara_id, i.motion_id); + + if (!pv_game->data.pv->disable_calc_motfrm_limit) + set_motion_max_frame(chara_id, i.motion_index, i.dsc_time); + } + playdata->set_motion.clear(); + } + else { + rob_chr->set_visibility(false); + pv_game->set_data_itmpv_visibility(chara_id, false); + } + } break; + case DSC_FT_MIKU_SHADOW: { + chara_id = (int32_t)data[0]; + playdata = &this->playdata[chara_id]; + rob_chr = playdata->rob_chr; + } break; + case DSC_FT_TARGET: { + if (sub_14013C8C0()->sub_1400E7920() || !a6 || targets_remaining > 0) + targets_remaining = max_def(--targets_remaining, 0); + else { + targets_remaining = get_target_target_count(target_index, *dsc_time_offset, !ignore_targets); + targets_remaining = max_def(targets_remaining, 0); + target_index++; + } + } break; + case DSC_FT_SET_MOTION: { + chara_id = (int32_t)data[0]; + playdata = &this->playdata[chara_id]; + rob_chr = playdata->rob_chr; + + int32_t motion_index = (int32_t)data[1]; + int32_t blend_duration_int = (int32_t)data[2]; + int32_t frame_speed_int = (int32_t)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; + + if (!rob_chr) + break; + + float_t frame = 0.0f; + float_t dsc_frame = 0.0f; + + bool blend = false; + pv_play_data_motion* motion = playdata->get_motion(motion_index); + if (motion && motion->enable && (!motion->motion_index || motion_index == motion->motion_index)) { + if (dsc_time != motion->time) { + frame = dsc_time_to_frame(curr_time - motion->time); + float_t dsc_frame = 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; + } + + const pv_db_pv_difficulty* diff = pv_game->data.pv->get_difficulty( + sub_14013C8C0()->difficulty, sub_14013C8C0()->edition); + if (!diff) + break; + + int32_t motion_id = diff->get_motion_or_default(chara_id, motion_index).id; + if (pv_game_get()->data.pv) + motion_id = pv_game_get()->data.pv->get_chrmot_motion_id(rob_chr->chara_id, + rob_chr->chara_index, diff->get_motion_or_default(chara_id, motion_index)); + + if (!motion_index) { + 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); + } + } + else + 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; + + frame_speed *= anim_frame_speed; + + pv_play_data_set_motion v518; + v518.frame_speed = frame_speed; + v518.motion_id = motion_id; + v518.frame = frame; + v518.blend_duration = blend_duration; + v518.blend = blend; + v518.blend_type = MOTION_BLEND_CROSS; + v518.disable_eye_motion = true; + v518.motion_index = motion_index; + v518.dsc_time = motion ? motion->time : dsc_time; + v518.dsc_frame = dsc_frame; + + field_2C560.field_0[chara_id] = true; + field_2C560.field_8[chara_id] = v518; + + 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->set_disable_eye_motion(true); + rob_chr->set_motion_step(frame_speed); + if (set) + pv_expression_array_set_motion(hash_murmurhash_empty, chara_id, motion_id); + + if (!pv_game->data.pv->disable_calc_motfrm_limit) + set_motion_max_frame(chara_id, motion_index, motion ? motion->time : 0); + } + else { + set_motion->clear(); + rob_chr->set_motion_step(frame_speed); + } + } break; + case DSC_FT_SET_PLAYDATA: { + chara_id = (int32_t)data[0]; + playdata = &this->playdata[chara_id]; + rob_chr = playdata->rob_chr; + + int32_t motion_index = (int32_t)data[0]; + if (motion_index >= 0) { + 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_FT_EFFECT: { + } break; + case DSC_FT_FADEIN_FIELD: { + } break; + case DSC_FT_EFFECT_OFF: { + } break; + case DSC_FT_SET_CAMERA: { + } break; + case DSC_FT_DATA_CAMERA: { + int32_t id = (int32_t)data[0]; + int32_t index = (int32_t)data[1]; + + switch (id) { + case 0: { + if (field_2BF58 < 0) + field_2BF58 = dsc_time; + + if (data_camera[0].index != index - 1) { + data_camera[0].index = index - 1; + data_camera[0].time = this->dsc_time; + data_camera[0].enable = 1; + } + + if (dsc_time == data_camera[0].time) + curr_time = this->data_camera[0].time; + + float_t frame = dsc_time_to_frame(curr_time - data_camera[0].time); + float_t dsc_frame = roundf(dsc_time_to_frame(dsc_time - data_camera[0].time)); + if (frame < dsc_frame) + frame = dsc_frame; + + pv_game->set_data_campv(0, index, frame); + rctx_ptr->camera->set_fast_change_hist0(true); + set_camera_max_frame((int32_t)data_camera[0].time); + } break; + case 1: { + if (data_camera[1].index != index - 1) { + data_camera[1].index = index - 1; + data_camera[1].time = this->dsc_time; + data_camera[1].enable = 1; + } + + if (dsc_time == data_camera[1].time) + curr_time = data_camera[1].time; + + float_t frame = dsc_time_to_frame(curr_time - data_camera[1].time); + float_t dsc_frame = roundf(dsc_time_to_frame(dsc_time - data_camera[1].time)); + if (frame < dsc_frame) + frame = dsc_frame; + + field_2C560.field_2C0 = true; + field_2C560.field_2C4 = 1; + field_2C560.field_2C8 = index; + field_2C560.field_2CC = frame; + field_2C560.field_2D0 = data_camera[1].time; + + pv_game->set_data_campv(1, index, frame); + rctx_ptr->camera->set_fast_change_hist0(true); + set_camera_max_frame((int32_t)data_camera[1].time); + } break; + case 2: { + pv_game->set_data_campv(2, index, 0.0f); + rctx_ptr->camera->set_fast_change_hist0(true); + } break; + } + } break; + case DSC_FT_CHANGE_FIELD: { + int32_t field_index = (int32_t)data[0]; + + if (field_index > 0) + pv_game->change_field(field_index, dsc_time, curr_time); + else + pv_game->reset_field(); + } break; + case DSC_FT_HIDE_FIELD: { + } break; + case DSC_FT_MOVE_FIELD: { + } break; + case DSC_FT_FADEOUT_FIELD: { + } break; + case DSC_FT_EYE_ANIM: { + chara_id = (int32_t)data[0]; + playdata = &this->playdata[chara_id]; + rob_chr = playdata->rob_chr; + + int32_t v114 = (int32_t)data[0]; + int32_t duration_int = (int32_t)data[1]; + + float_t duration; + if (duration_int == -1) + duration = 6.0f; + else + duration = (float_t)duration_int * 0.001f * 60.0f; + + if (rob_chr) + rob_chr->set_eyelid_mottbl_motion_from_face(v114, duration / anim_frame_speed, + -1.0f, pv_game->data.pv->is_old_pv ? 1.0f : 0.0f, aft_mot_db); + } break; + case DSC_FT_MOUTH_ANIM: { + chara_id = (int32_t)data[0]; + playdata = &this->playdata[chara_id]; + rob_chr = playdata->rob_chr; + + int32_t mouth_anim_id = (int32_t)data[2]; + int32_t blend_duration_int = (int32_t)data[3]; + int32_t value_int = (int32_t)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) { + int32_t mottbl_index = mouth_anim_id_to_mottbl_index(mouth_anim_id); + if (pv_game->data.field_2D090 && mottbl_index != 144) + value = 0.0f; + + rob_chr->set_mouth_mottbl_motion(0, mottbl_index, value, 0, blend_duration / anim_frame_speed, + 0.0f, 1.0f, -1, pv_game->data.pv->is_old_pv ? 1.0f : 0.0f, aft_mot_db); + } + } break; + case DSC_FT_HAND_ANIM: { + chara_id = (int32_t)data[0]; + playdata = &this->playdata[chara_id]; + rob_chr = playdata->rob_chr; + + int32_t hand_index = (int32_t)data[1]; + int32_t hand_anim_id = (int32_t)data[2]; + int32_t blend_duration_int = (int32_t)data[3]; + int32_t value_int = (int32_t)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 * 60.0f; + if (value < 0.0f) + value = 0.0f; + } + else + value = 0.0f; + + if (rob_chr) { + int32_t mottbl_index = hand_anim_id_to_mottbl_index(hand_anim_id); + switch (hand_index) { + case 0: + rob_chr->set_hand_l_mottbl_motion(0, mottbl_index, value, 0, blend_duration / anim_frame_speed, + 0.0f, 1.0f, -1, pv_game->data.pv->is_old_pv ? 1.0f : 0.0f, aft_mot_db); + break; + case 1: + rob_chr->set_hand_r_mottbl_motion(0, mottbl_index, value, 0, blend_duration / anim_frame_speed, + 0.0f, 1.0f, -1, pv_game->data.pv->is_old_pv ? 1.0f : 0.0f, aft_mot_db); + break; + } + } + } break; + case DSC_FT_LOOK_ANIM: { + chara_id = (int32_t)data[0]; + playdata = &this->playdata[chara_id]; + rob_chr = playdata->rob_chr; + + int32_t look_anim_id = (int32_t)data[1]; + int32_t blend_duration_int = (int32_t)data[2]; + int32_t value_int = (int32_t)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) { + int32_t mottbl_index = look_anim_id_to_mottbl_index(look_anim_id); + rob_chr->set_eyes_mottbl_motion(0, mottbl_index, value, mottbl_index == 224, blend_duration + / anim_frame_speed, 0.0f, 1.0f, -1, pv_game->data.pv->is_old_pv ? 1.0f : 0.0f, aft_mot_db); + } + } break; + case DSC_FT_EXPRESSION: { + chara_id = (int32_t)data[0]; + playdata = &this->playdata[chara_id]; + rob_chr = playdata->rob_chr; + + int32_t expression_id = (int32_t)data[1]; + int32_t blend_duration_int = (int32_t)data[2]; + int32_t value_int = (int32_t)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) { + int32_t mottbl_index = expression_id_to_mottbl_index(expression_id); + bool v167 = dsc.signature >= 0x10000000 || pv_game->data.pv->edit != 1 && pv_game->data.pv->edit != 2; + rob_chr->set_face_mottbl_motion(0, mottbl_index, value, mottbl_index >= 214 && mottbl_index <= 223, + blend_duration / anim_frame_speed, 0.0f, 1.0f, -1, pv_game->data.pv->is_old_pv ? 1.0f : 0.0f, v167, aft_mot_db); + } + } break; + case DSC_FT_LOOK_CAMERA: { + chara_id = (int32_t)data[0]; + playdata = &this->playdata[chara_id]; + rob_chr = playdata->rob_chr; + + int32_t v171 = (int32_t)data[1]; + int32_t v172 = (int32_t)data[2]; + int32_t v173 = (int32_t)data[3]; + int32_t v174 = (int32_t)data[4]; + + float_t v175; + if (v172 != -1) { + v175 = (float_t)v172 * 0.001f * 60.0f; + if (v175 < 0.0f) + v175 = 0.0f; + } + else + v175 = 0.0f; + + float_t v176; + if (v173 != -1) { + v176 = (float_t)v173 * 0.001f; + v176 = clamp_def(v176, 0.0f, 1.0f); + } + else + v176 = 1.0f; + + float_t v177; + if (v174 != -1) { + v177 = (float_t)v174 * 0.001f; + v177 = clamp_def(v177, 0.0f, 1.0f); + } + else + v177 = 1.0f; + + if (rob_chr) { + field_2BFD4 = v171 == 1; + if (pv_game->data.pv->is_old_pv) + rob_chr->sub_1405547E0(field_2BFD4, v176, v177, v175 / anim_frame_speed, 0.25f, 2.0f); + else + rob_chr->sub_140554790(field_2BFD4, v176, v177, v175 / anim_frame_speed, 0.25f, 2.0f); + } + } break; + case DSC_FT_LYRIC: { + int32_t lyric_index = (int32_t)data[0]; + vec4u8 color = *(vec4u8*)&data[1]; + color = { color.z, color.y, color.x, color.w }; + pv_game->set_lyric(lyric_index, color); + } break; + case DSC_FT_MUSIC_PLAY: { + if (!pv_game_get()->loaded) + break; + + if (pv_game->data.pv->song_file_name.size()) { + music->play(4, pv_game->get_play_data_song_file_name(), false, 0.0f, 0.0f, 0.0f, 3.0f, false); + + int32_t v189 = 100; + int32_t v192 = 0; + if (sub_14013C8C0()->sub_1400E7910() != 2 || !sub_14013C8C0()->field_25) + v192 = 100; + + if (!field_2BFC0) { + v192 = 0; + v189 = 0; + } + + music->set_channel_pair_volume_map(1, v192); + music->set_channel_pair_volume_map(0, v189); + } + else { + music->play_fade_in(2, pv_game->get_play_data_song_file_name(), 0.0f, -1.0f, false, true, 3.0f, false); + music->set_volume_map(0, 100); + } + + if (pv_game->field_1 || pv_game->field_2) + music->set_pause(true); + + *music_play = true; + this->music_play = true; + } break; + case DSC_FT_MODE_SELECT: + case DSC_FT_EDIT_MODE_SELECT: { + int32_t diff_bits = (int32_t)data[0]; + int32_t mode = (int32_t)data[1]; + + bool v3 = true; + if (func == DSC_FT_MODE_SELECT && has_perf_id && sub_14013C8C0()->sub_1400E7910() < 4) + v3 = !!(diff_bits & (1 << sub_14013C8C0()->difficulty)); + + if (!sub_14013C8C0()->sub_1400E7920() && v3 + && (sub_14013C8C0()->difficulty == PV_DIFFICULTY_EASY + || sub_14013C8C0()->difficulty == PV_DIFFICULTY_NORMAL)) { + if (mode == 1) + pv_game->sub_1401230A0(); + else if (mode == 3) { + pv_game->data.play_data.sub_140134670(pv_game->data.challenge_time_total_bonus); + sub_14013C8C0()->field_26 = false; + } + else + field_2BFD5 = true; + } + } break; + case DSC_FT_EDIT_MOTION: + case DSC_FT_EDIT_MOTION_LOOP: + case DSC_FT_EDIT_MOTION_F: { + int32_t motion_index = (int32_t)data[0]; + float_t frame_speed = (float_t)(int32_t)data[1] * 0.001f; + int32_t _blend_type = (int32_t)data[2]; + float_t value = (float_t)(int32_t)data[3] * 0.001f; + + if (!rob_chr) { + playdata->motion_data.mot_smooth_len = 12.0f; + break; + } + + if (motion_index < 0) + motion_index = 0; + if (frame_speed < 0.0f) + frame_speed = 1.0f; + value = clamp_def(value, 0.0f, 1.0f); + + int32_t motion_id; + const pv_db_pv_difficulty* diff = pv_game->data.pv->get_difficulty( + sub_14013C8C0()->difficulty, sub_14013C8C0()->edition); + if (diff) { + motion_id = diff->get_motion_or_default(chara_id, motion_index).id; + if (pv_game_get()->data.pv) + motion_id = pv_game_get()->data.pv->get_chrmot_motion_id(rob_chr->chara_id, + rob_chr->chara_index, diff->get_motion_or_default(chara_id, motion_index)); + + if (motion_id == -1) + motion_id = rob_chr->get_rob_cmn_mottbl_motion_id(0); + } + else + motion_id = rob_chr->get_rob_cmn_mottbl_motion_id(0); + + frame_speed *= anim_frame_speed; + + float_t frame_count = motion_storage_get_mot_data_frame_count(motion_id, aft_mot_db) - 1.0f; + float_t frame = frame_count * value; + if (pv_game->data.use_osage_play_data && frame_count > 0.0f) + frame = fmodf((dsc_time_to_frame(curr_time - dsc_time) * frame_speed) + + frame_count * value, frame_count); + + float_t blend_duration = playdata->motion_data.mot_smooth_len / this->anim_frame_speed; + MotionBlendType blend_type = MOTION_BLEND_CROSS; + if (_blend_type == 2) + blend_type = MOTION_BLEND_FREEZE; + else if (_blend_type != 1) { + if (func == DSC_FT_EDIT_MOTION_LOOP) + blend_type = MOTION_BLEND_FREEZE; + blend_duration = 0.0f; + } + + bool blend = !(dsc_time / 10000) || (int32_t)(value * 1000.0); + + pv_play_data_set_motion v518; + v518.frame_speed = frame_speed; + v518.motion_id = motion_id; + v518.frame = frame; + v518.blend_duration = blend_duration; + v518.blend = blend; + v518.blend_type = blend_type; + v518.disable_eye_motion = false; + v518.motion_index = -1; + v518.dsc_time = dsc_time; + v518.dsc_frame = frame; + + bool loop = true; + if (func != DSC_FT_EDIT_MOTION_LOOP && func != DSC_FT_EDIT_MOTION_F) + loop = false; + + if (playdata->disp || loop) { + rob_chr->set_motion_id(motion_id, frame, blend_duration, blend, 0, blend_type, aft_bone_data, aft_mot_db); + rob_chr->set_motion_step(frame_speed); + if (loop) + rob_chr->set_motion_loop(0.0f, -1.0f, -1); + + field_2C560.field_148[chara_id] = true; + field_2C560.field_150[chara_id] = v518; + field_2C560.field_270[chara_id] = frame_count * value; + } + else { + playdata->set_motion.push_back(v518); + rob_chr->set_motion_step(frame_speed); + } + + playdata->motion_data.mot_smooth_len = 12.0f; + } break; + case DSC_FT_BAR_TIME_SET: { + int32_t bpm = (int32_t)data[0]; + int32_t time_signature = (int32_t)data[1] + 1; + float_t target_flying_time = bar_time_set_to_target_flying_time(bpm, time_signature); + //field_2BF80->field_0.target_flying_time = target_flying_time; + this->target_flying_time = target_flying_time; + this->time_signature = time_signature; + } break; + case DSC_FT_SHADOWHEIGHT: { + chara_id = (int32_t)data[0]; + playdata = &this->playdata[chara_id]; + rob_chr = playdata->rob_chr; + } break; + case DSC_FT_EDIT_FACE: + case DSC_FT_EDIT_EXPRESSION: { + int32_t expression_id = (int32_t)data[0]; + float_t blend_duration = 0.0f; + if (func == DSC_FT_EDIT_EXPRESSION) + blend_duration = (float_t)(int32_t)data[1] * 0.001f * 60.0f; + + /*int32_t mouth_anim_id = -1; + if (!has_perf_id) + mouth_anim_id = (int32_t)data[1];*/ + + if (rob_chr) { + int32_t mottbl_index = expression_id_to_mottbl_index(expression_id); + bool v236 = true; + //if (has_perf_id) + v236 = pv_game->data.pv->edit != 1 && pv_game->data.pv->edit != 2; + rob_chr->set_face_mottbl_motion(0, mottbl_index, 1.0f, 0, blend_duration / anim_frame_speed, + 0.0f, 1.0f, -1, pv_game->data.pv->is_old_pv ? 1.0f : 0.0f, v236, aft_mot_db); + + /*if (!has_perf_id) { + int32_t mottbl_index = mouth_anim_id_to_mottbl_index(mouth_anim_id); + float_t value = pv_game->data.field_2D090 && mottbl_index != 144 ? 0.0f : 1.0f; + rob_chr->set_mouth_mottbl_motion(0, mottbl_index, value, 0, target_anim_fps * 0.1, + 0.0f, 1.0f, -1, pv_game->data.pv->is_old_pv ? 1.0f : 0.0f, aft_mot_db); + }*/ + } + } break; + case DSC_FT_MOVE_CAMERA: + case DSC_FT_EDIT_CAMERA: { + float_t duration = (float_t)(int32_t)data[0] * 0.001f; + + float_t v12 = pv_game->data.pv->edit == 2 ? 1.0f : 0.227f; + float_t v14 = 1.0f / field_2C54C; + + pv_game_camera_dsc_data start; + pv_game_camera_dsc_data end; + start.view_point.x = (float_t)(int32_t)data[1] * v14 * v12; + start.view_point.y = (float_t)(int32_t)data[2] * v14 * v12; + start.view_point.z = (float_t)(int32_t)data[3] * v14 * v12; + start.interest.x = (float_t)(int32_t)data[4] * v14 * v12; + start.interest.y = (float_t)(int32_t)data[5] * v14 * v12; + start.interest.z = (float_t)(int32_t)data[6] * v14 * v12; + start.up_vec.x = (float_t)(int32_t)data[7] * v14; + start.up_vec.y = (float_t)(int32_t)data[8] * v14; + start.up_vec.z = (float_t)(int32_t)data[9] * v14; + end.view_point.x = (float_t)(int32_t)data[10] * v14 * v12; + end.view_point.y = (float_t)(int32_t)data[11] * v14 * v12; + end.view_point.z = (float_t)(int32_t)data[12] * v14 * v12; + end.interest.x = (float_t)(int32_t)data[13] * v14 * v12; + end.interest.y = (float_t)(int32_t)data[14] * v14 * v12; + end.interest.z = (float_t)(int32_t)data[15] * v14 * v12; + end.up_vec.x = (float_t)(int32_t)data[16] * v14; + end.up_vec.y = (float_t)(int32_t)data[17] * v14; + end.up_vec.z = (float_t)(int32_t)data[18] * v14; + + mat4_mult_vec3_trans(&scene_rot_mat, &start.view_point, &start.view_point); + mat4_mult_vec3_trans(&scene_rot_mat, &start.interest, &start.interest); + mat4_mult_vec3_trans(&scene_rot_mat, &start.up_vec, &start.up_vec); + mat4_mult_vec3_trans(&scene_rot_mat, &end.view_point, &end.view_point); + mat4_mult_vec3_trans(&scene_rot_mat, &end.interest, &end.interest); + mat4_mult_vec3_trans(&scene_rot_mat, &end.up_vec, &end.up_vec); + + float_t acceleration_1 = 0.0f; + if ((int32_t)data[19] != -1) + acceleration_1 = (float_t)(int32_t)data[19] * 0.001f; + + float_t acceleration_2 = 1.0f; + if ((int32_t)data[20] != -1) + acceleration_2 = (float_t)(int32_t)data[20] * 0.001f; + + int32_t follow_chara = 0; + int32_t chara_id = 0; + int32_t chara_follow_point = 0; + if (func == DSC_FT_EDIT_CAMERA) { + follow_chara = (int32_t)data[21]; + chara_id = (int32_t)data[22]; + chara_follow_point = (int32_t)data[23]; + } + + pv_game_camera_set_fov_min_dist(fov, min_dist); + pv_game_camera_set_dsc_data(duration, start, end, acceleration_1, acceleration_2, + follow_chara, chara_id, chara_follow_point, func == DSC_FT_EDIT_CAMERA); + pv_game_camera_ctrl(0.0f); + + rctx_ptr->camera->set_fast_change_hist0(true); + } break; + case DSC_FT_PV_END: { + dsc_data_ptr++; + if (a6) + pv_game->end(true, false); + pv_end = true; + return false; + } + case DSC_FT_SHADOWPOS: { + chara_id = (int32_t)data[0]; + playdata = &this->playdata[chara_id]; + rob_chr = playdata->rob_chr; + } break; + case DSC_FT_EDIT_LYRIC: { + int32_t lyric_index = (int32_t)data[0] - 1; + field_2BF68 = curr_time + 1000000LL * (int32_t)data[1]; + pv_game->set_lyric(lyric_index, { 0xFF, 0xFF, 0xFF, 0xFF }); + } break; + case DSC_FT_EDIT_TARGET: { + } break; + case DSC_FT_EDIT_MOUTH: + case DSC_FT_EDIT_MOUTH_ANIM: { + int32_t mouth_anim_id = (int32_t)data[0]; + + float_t blend_duration = 0.1f; + if (func == DSC_FT_EDIT_MOUTH_ANIM) + blend_duration = (float_t)(int32_t)data[1] * 0.001f; + + if (!rob_chr) + break; + + int32_t mottbl_index = mouth_anim_id_to_mottbl_index(mouth_anim_id); + blend_duration *= target_anim_fps; + + float_t value = pv_game->data.field_2D090 && mottbl_index != 144 ? 0.0f : 1.0f; + rob_chr->set_mouth_mottbl_motion(0, mottbl_index, value, 0, blend_duration, + 0.0f, 1.0f, -1, pv_game->data.pv->is_old_pv ? 1.0f : 0.0f, aft_mot_db); + } break; + case DSC_FT_SET_CHARA: { + chara_id = (int32_t)data[0]; + playdata = &this->playdata[chara_id]; + rob_chr = playdata->rob_chr; + } break; + case DSC_FT_EDIT_MOVE: { + float_t v9 = 1.0f / field_2C54C; + float_t duration = (float_t)(int32_t)(data[0]) * v9; + vec3 start_pos; + start_pos.x = (float_t)(int32_t)data[1] * v9; + start_pos.y = 0.0f; + start_pos.z = (float_t)(int32_t)data[2] * v9; + vec3 end_pos; + end_pos.x = (float_t)(int32_t)data[3] * v9; + end_pos.y = 0.0f; + end_pos.z = (float_t)(int32_t)data[4] * v9; + float_t start_rot = (float_t)(int32_t)data[5] * v9; + float_t end_rot = (float_t)(int32_t)data[6] * v9; + + if (playdata) { + float_t v5 = pv_game->data.pv->edit == 2 ? 1.0f : 0.227f; + start_pos *= v5; + end_pos *= v5; + mat4_mult_vec3_trans(&scene_rot_mat, &start_pos, &start_pos); + mat4_mult_vec3_trans(&scene_rot_mat, &end_pos, &end_pos); + playdata->motion_data.set(playdata->rob_chr, duration, + start_pos, end_pos, start_rot + scene_rot_y, end_rot + scene_rot_y); + playdata->motion_data.ctrl(0.0f); + } + } break; + case DSC_FT_EDIT_MOVE_XYZ: { + float_t v9 = 1.0f / field_2C54C; + float_t duration = (float_t)(int32_t)(data[0]) * v9; + vec3 start_pos; + start_pos.x = (float_t)(int32_t)data[1] * v9; + start_pos.y = (float_t)(int32_t)data[2] * v9; + start_pos.z = (float_t)(int32_t)data[3] * v9; + vec3 end_pos; + end_pos.x = (float_t)(int32_t)data[4] * v9; + end_pos.y = (float_t)(int32_t)data[5] * v9; + end_pos.z = (float_t)(int32_t)data[6] * v9; + float_t start_rot = (float_t)(int32_t)data[7] * v9; + float_t end_rot = (float_t)(int32_t)data[8] * v9; + + if (playdata) { + float_t v5 = pv_game->data.pv->edit == 2 ? 1.0f : 0.227f; + start_pos *= v5; + end_pos *= v5; + mat4_mult_vec3_trans(&scene_rot_mat, &start_pos, &start_pos); + mat4_mult_vec3_trans(&scene_rot_mat, &end_pos, &end_pos); + playdata->motion_data.set(playdata->rob_chr, duration, + start_pos, end_pos, start_rot + scene_rot_y, end_rot + scene_rot_y); + playdata->motion_data.ctrl(0.0f); + } + } break; + case DSC_FT_EDIT_SHADOW: { + int32_t enable = (int32_t)data[0]; + + playdata->shadow = enable == 1; + + shadow* shad = rctx_ptr->render_manager.shadow_ptr; + if (shad) + if (chara_id == 1) + shad->blur_filter_enable[1] = playdata->shadow; + else + shad->blur_filter_enable[0] = playdata->shadow; + } break; + case DSC_FT_EDIT_EYELID: { + int32_t v337 = (int32_t)data[0]; + + if (!rob_chr) + break; + + int32_t v339; + switch (v337) { + case 0: + rob_chr->autoblink_enable(); + v339 = 2; + break; + case 1: + rob_chr->autoblink_disable(); + v339 = 2; + break; + default: + rob_chr->autoblink_disable(); + v339 = 1; + break; + } + + rob_chr->set_eyelid_mottbl_motion_from_face(v339, + 0.0f, -1.0f, pv_game->data.pv->is_old_pv ? 1.0f : 0.0f, aft_mot_db); + } break; + case DSC_FT_EDIT_EYE: + case DSC_FT_EDIT_EYE_ANIM: { + int32_t eye_anim_id = (int32_t)data[0]; + float_t v533 = (float_t)(int32_t)data[1] * 0.001f; + + float_t blend_duration = 0.0f; + if (func == DSC_FT_EDIT_EYE_ANIM) + blend_duration = (float_t)(int32_t)data[2] * 0.001f * 60.0f; + if (eye_anim_id < 0 || eye_anim_id >= 34) + eye_anim_id = 0; + + if (!rob_chr) + break; + + blend_duration /= anim_frame_speed; + + struc_595& v355 = func == DSC_FT_EDIT_EYE_ANIM ? stru_1409A0DD0[eye_anim_id] : stru_1409A0AA0[eye_anim_id]; + + int32_t mottbl_index = v355.mottbl_index; + float_t _blend_duration = blend_duration; + bool v358 = false; + float_t value = 1.0f; + float_t v360 = 1.0f; + int32_t state = 0; + int32_t v13 = -1; + switch (v355.field_C) { + case 1: + v358 = true; + _blend_duration = 0.0f; + break; + case 2: { + state = 2; + value = 0.0f; + v13 = 0; + float_t v363 = motion_storage_get_mot_data_frame_count(rob_chr-> + get_rob_cmn_mottbl_motion_id(mottbl_index), aft_mot_db) - 1.0f; + v360 = v533 > 0.0f ? v363 / target_anim_fps * v533 : 1.0f; + } break; + case 3: { + state = 4; + v13 = 0; + float_t v363 = motion_storage_get_mot_data_frame_count(rob_chr-> + get_rob_cmn_mottbl_motion_id(mottbl_index), aft_mot_db) - 1.0f; + v360 = v533 > 0.0f ? v363 / target_anim_fps * v533 : 1.0f; + } break; + } + + rob_chr->set_eyes_mottbl_motion(0, mottbl_index, value, state, _blend_duration, 0.0f, + v360, v13, pv_game->data.pv->is_old_pv ? 1.0f : 0.0f, aft_mot_db); + + if (pv_game->data.pv->is_old_pv) + rob_chr->sub_1405547E0(v358, 0.0f, 1.0f, blend_duration, 1.0f, 2.0f); + else + rob_chr->sub_140554790(v358, 0.0f, 1.0f, blend_duration, 1.0f, 2.0f); + } break; + case DSC_FT_EDIT_ITEM: { + int32_t index = (int32_t)data[0]; + + /*if (rob_chr) { + pv_db_pv_difficulty* diff = pv_game->data.pv->get_difficulty( + sub_14013C8C0()->difficulty, sub_14013C8C0()->edition); + if (diff) + rob_chr->sub_1405524C0(sub_1404E4B90(&diff->hand_item, index), 0.0f); + }*/ + } break; + case DSC_FT_EDIT_EFFECT: { + int32_t index = (int32_t)data[0]; + float_t speed = (float_t)(int32_t)data[1] * 0.001f; + + pv_game->edit_effect_set(index, speed, delta_time); + } break; + case DSC_FT_EDIT_HAND_ANIM: { + } break; + case DSC_FT_EDIT_DISP: { + int32_t disp = (int32_t)data[0]; + + playdata->disp = disp == 1; + if (rob_chr) + 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 (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->bone_data->set_disable_eye_motion(i.disable_eye_motion); + rob_chr->set_motion_step(i.frame_speed); + if (set) + pv_expression_array_set_motion(hash_murmurhash_empty, chara_id, i.motion_id); + } + playdata->set_motion.clear(); + } + else + rob_chr->set_visibility(false); + + pv_game->sub_140115C10(chara_id, playdata->disp); + } break; + case DSC_FT_AIM: { + chara_id = (int32_t)data[0]; + playdata = &this->playdata[chara_id]; + rob_chr = playdata->rob_chr; + } break; + case DSC_FT_HAND_ITEM: { + chara_id = (int32_t)data[0]; + playdata = &this->playdata[chara_id]; + rob_chr = playdata->rob_chr; + + int32_t hand_index = (int32_t)data[1]; + int32_t index = (int32_t)data[0]; + + /*if (rob_chr) { + pv_db_pv_difficulty* diff = pv_game->data.pv->get_difficulty( + sub_14013C8C0()->difficulty, sub_14013C8C0()->edition); + if (diff) + switch (hand_index) { + case 0: + rob_chr->sub_1405551B0(sub_1404E4B90(&diff->hand_item, index)); + break; + case 1: + rob_chr->sub_1405551F0(sub_1404E4B90(&diff->hand_item, index)); + break; + } + }*/ + } break; + case DSC_FT_EDIT_BLUSH: { + int32_t index = (int32_t)data[0]; + + if (rob_chr) + rob_chr->set_face_object_index(index >= 0 || index < 15 ? index : 0); + } break; + case DSC_FT_NEAR_CLIP: { + float_t _min_dist = (float_t)(int32_t)data[0] * 0.001f; + float_t _fov = (float_t)(int32_t)data[1] * 0.001f; + + camera* cam = rctx_ptr->camera; + + bool ignore_min_dist = true; + if (_min_dist <= 0.0f) { + _min_dist = 0.05f; + ignore_min_dist = false; + } + + bool ignore_fov = true; + if (_fov <= 0.0f) { + _fov = 32.2673416137695f; + ignore_fov = false; + } + + this->min_dist = _min_dist; + cam->set_ignore_min_dist(false); + cam->set_min_distance(_min_dist); + cam->set_ignore_min_dist(ignore_min_dist); + + this->fov = _fov; + cam->set_ignore_fov(false); + cam->set_fov(_fov); + cam->set_ignore_fov(ignore_fov); + + pv_game_camera_set_fov_min_dist(fov, min_dist); + } break; + case DSC_FT_CLOTH_WET: { + chara_id = (int32_t)data[0]; + playdata = &this->playdata[chara_id]; + rob_chr = playdata->rob_chr; + + float_t wet = (float_t)(int32_t)data[0] * 0.001f; + + wet = clamp_def(wet, 0.0f, 1.0f); + + if (rob_chr) + rob_chr->item_equip->wet = wet; + } break; + case DSC_FT_LIGHT_ROT: { + } break; + case DSC_FT_SCENE_FADE: { + scene_fade.duration = (float_t)(int32_t)data[0] * 0.001f; + scene_fade.start_alpha = (float_t)(int32_t)data[1] * 0.001f; + scene_fade.end_alpha = (float_t)(int32_t)data[2] * 0.001f; + scene_fade.color.x = (float_t)(int32_t)data[3] * 0.001f; + scene_fade.color.y = (float_t)(int32_t)data[4] * 0.001f; + scene_fade.color.z = (float_t)(int32_t)data[5] * 0.001f; + + scene_fade.enable = true; + scene_fade.time = 0.0f; + scene_fade_ctrl(0.0f); + } break; + case DSC_FT_TONE_TRANS: { + vec3 start; + start.x = (float_t)(int32_t)data[0] * 0.001f; + start.y = (float_t)(int32_t)data[1] * 0.001f; + start.z = (float_t)(int32_t)data[2] * 0.001f; + + vec3 end; + end.x = (float_t)(int32_t)data[3] * 0.001f; + end.y = (float_t)(int32_t)data[4] * 0.001f; + end.z = (float_t)(int32_t)data[5] * 0.001f; + + rctx_ptr->post_process.tone_map->set_tone_trans(start, end); + } break; + case DSC_FT_SATURATE: { + float_t saturate_coeff = (float_t)(int32_t)data[0] * 0.001f; + + rctx_ptr->post_process.tone_map->set_saturate_coeff(saturate_coeff); + } break; + case DSC_FT_FADE_MODE: { + int32_t blend_func = (int32_t)data[0]; + + rctx_ptr->post_process.tone_map->set_scene_fade_blend_func(blend_func); + } break; + case DSC_FT_AUTO_BLINK: { + chara_id = (int32_t)data[0]; + playdata = &this->playdata[chara_id]; + rob_chr = playdata->rob_chr; + + int32_t enable = (int32_t)data[0]; + + if (rob_chr) + if (enable) + rob_chr->autoblink_enable(); + else + rob_chr->autoblink_disable(); + } break; + case DSC_FT_PARTS_DISP: { + chara_id = (int32_t)data[0]; + playdata = &this->playdata[chara_id]; + rob_chr = playdata->rob_chr; + + int32_t id = (int32_t)data[0]; + int32_t enable = (int32_t)data[1]; + + if (rob_chr) + rob_chr->set_parts_disp((item_id)id, enable == 1); + } break; + case DSC_FT_TARGET_FLYING_TIME: { + /*float_t target_flying_time = (float_t)(int32_t)data[0] * 0.001f; + + if (target_flying_time >= 0.0f) + field_2BF80->field_0.target_flying_time = target_flying_time;*/ + } break; + case DSC_FT_CHARA_SIZE: { + chara_id = (int32_t)data[0]; + playdata = &this->playdata[chara_id]; + rob_chr = playdata->rob_chr; + + int32_t chara_size = (int32_t)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_size_index = chara_init_data_get_chara_size_index(pv_game->data.pv->get_performer_chara(chara_id)); + else if (chara_size == 2) + chara_size_index = 1; + else if (chara_size == 3) { + chara_size_index = rob_chr->pv_data.chara_size_index; + if (chara_size_index < 0 || chara_size_index > 4) + break; + } + else { + rob_chr->set_chara_size((float_t)chara_size / field_2C54C); + 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; + } break; + case DSC_FT_CHARA_HEIGHT_ADJUST: { + chara_id = (int32_t)data[0]; + playdata = &this->playdata[chara_id]; + rob_chr = playdata->rob_chr; + + int32_t height_adjust = (int32_t)data[1]; + + if (rob_chr) + rob_chr->set_chara_height_adjust(height_adjust != 0); + } break; + case DSC_FT_ITEM_ANIM: { + chara_id = (int32_t)data[0]; + playdata = &this->playdata[chara_id]; + rob_chr = playdata->rob_chr; + + int32_t index = (int32_t)data[1]; + int32_t v290 = (int32_t)data[2]; + int32_t disp = (int32_t)data[3]; + + if (index < 0) + break; + + if (v290 == 2) { + int64_t time = pv_game->get_data_itmpv_time(chara_id, index); + if (time >= 0 && time <= dsc_time && time <= curr_time) { + float_t frame = dsc_time_to_frame(curr_time - time); + float_t dsc_frame = roundf(dsc_time_to_frame(dsc_time - time)); + if (frame < dsc_frame) + frame = dsc_frame; + pv_game->set_data_itmpv_req_frame(chara_id, index, frame); + set_item_anim_max_frame(chara_id, index, time); + } + } + else if (v290 >= 0) { + pv_game->set_data_itmpv(chara_id, index, v290 != 0, this->dsc_time); + set_item_anim_max_frame(chara_id, index, dsc_time); + } + + if (disp >= 0) + pv_game->set_data_itmpv_visibility(chara_id, index, disp != 0); + } break; + case DSC_FT_CHARA_POS_ADJUST: { + chara_id = (int32_t)data[0]; + playdata = &this->playdata[chara_id]; + rob_chr = playdata->rob_chr; + + vec3 pos; + pos.x = (float_t)(int32_t)data[1] * 0.001f; + pos.y = (float_t)(int32_t)data[2] * 0.001f; + pos.z = (float_t)(int32_t)data[3] * 0.001f; + if (!rob_chr) + break; + + mat4_mult_vec3_trans(&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_FT_SCENE_ROT: { + float_t scene_rot = (float_t)(int32_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_FT_EDIT_MOT_SMOOTH_LEN: { + chara_id = (int32_t)data[0]; + playdata = &this->playdata[chara_id]; + rob_chr = playdata->rob_chr; + + int32_t value = (int32_t)data[1]; + + if (value >= 0) + playdata->motion_data.mot_smooth_len = (float_t)(value * 60) / field_2C54C; + else + playdata->motion_data.mot_smooth_len = 12.0f; + } break; + case DSC_FT_PV_BRANCH_MODE: { + int32_t branch_mode = (int32_t)data[0]; + + if (branch_mode >= 0 && branch_mode <= 2) + this->branch_mode = branch_mode; + } break; + case DSC_FT_DATA_CAMERA_START: { + int32_t camera_index = (int32_t)data[0]; + int32_t index = (int32_t)data[1]; + + if (camera_index < 3) { + data_camera[camera_index].enable = true; + data_camera[camera_index].index = index; + data_camera[camera_index].time = dsc_time; + } + } break; + case DSC_FT_MOVIE_PLAY: { + int32_t v408 = (int32_t)data[0]; + + /*if (pv_game_get()->loaded && v408 && app::TaskWork::CheckTaskReady(task_movie_get(0))) { + v410 = task_movie_get(0); + task_movie_get(0)->sub_14041EF10(); + pv_game_get()->data.field_2D0C0 = 0; + sub_14041F1D0(curr_time); + }*/ + } break; + case DSC_FT_MOVIE_DISP: { + int32_t v412 = (int32_t)data[0]; + if (!pv_game_get()->loaded) + break; + + /*for (int32_t i = 0; i < 2; i++) { + if (!app::TaskWork::CheckTaskReady(task_movie_get(i))) + continue; + + int32_t v415 = 0; + if (pv_game_get()->data.field_2D0C0 == i) { + if (pv_game->data.field_2D8A0) + switch (v412) { + case 1: + v415 = 1; + break; + case 2: + v415 = 2; + break; + } + } + task_movie_get(l)->field_88 = v415; + break; + }*/ + } break; + case DSC_FT_WIND: { + chara_id = (int32_t)data[0]; + playdata = &this->playdata[chara_id]; + rob_chr = playdata->rob_chr; + + float_t wind_strength_kami = (float_t)(int32_t)data[1] * 0.001f; + float_t wind_strength_outer = (float_t)(int32_t)data[2] * 0.001f; + + if (rob_chr) + rob_chr->set_wind_strength(wind_strength_outer); + } break; + case DSC_FT_OSAGE_STEP: { + chara_id = (int32_t)data[0]; + playdata = &this->playdata[chara_id]; + rob_chr = playdata->rob_chr; + + float_t osage_step_kami = (float_t)(int32_t)data[1] * 0.001f; + float_t osage_step_outer = (float_t)(int32_t)data[2] * 0.001f; + + if (rob_chr) + rob_chr->set_osage_step(osage_step_outer); + } break; + case DSC_FT_OSAGE_MV_CCL: { + chara_id = (int32_t)data[0]; + playdata = &this->playdata[chara_id]; + rob_chr = playdata->rob_chr; + + float_t osage_mv_ccl_kami = (float_t)(int32_t)data[1] * 0.001f; + float_t osage_mv_ccl_outer = (float_t)(int32_t)data[2] * 0.001f; + + if (rob_chr) { + 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_FT_CHARA_COLOR: { + chara_id = (int32_t)data[0]; + playdata = &this->playdata[chara_id]; + rob_chr = playdata->rob_chr; + + int32_t chara_color = (int32_t)data[1]; + + if (rob_chr) + rob_chr->set_chara_color(chara_color != 0); + } break; + case DSC_FT_SE_EFFECT: { + int32_t index = (int32_t)data[0]; + + if (pv_game_get()->loaded) + pv_game->play_se(index); + } break; + case DSC_FT_EDIT_EYELID_ANIM: { + int32_t v342 = (int32_t)data[0]; + float_t blend_duration = (float_t)(int32_t)data[1] * 0.001f * 60.0f; + float_t value = (float_t)(int32_t)data[2] * 0.001f; + + if (!rob_chr) + break; + + int32_t v346; + switch (v342) { + case 0: + v346 = 1; + break; + case 1: + rob_chr->autoblink_disable(); + v346 = 2; + break; + case 2: + v346 = 3; + break; + case 3: + default: + rob_chr->autoblink_enable(); + v346 = 2; + break; + } + + rob_chr->set_eyelid_mottbl_motion_from_face(v346, blend_duration / anim_frame_speed, + value, pv_game->data.pv->is_old_pv ? 1.0f : 0.0f, aft_mot_db); + } break; + case DSC_FT_EDIT_INSTRUMENT_ITEM: { + int32_t index = (int32_t)data[0]; + float_t frame_speed = (float_t)(int32_t)data[1] * 0.001f; + + if (rob_chr) { + field_2C560.field_288[chara_id] = index != -1; + field_2C560.field_290[chara_id] = index; + field_2C560.field_2A8[chara_id] = frame_speed; + pv_game->sub_140115C90(chara_id, playdata->disp, index, rob_chr->get_frame(), frame_speed); + } + } break; + case DSC_FT_PV_END_FADEOUT: { + float_t duration = (float_t)(int32_t)data[0] * 0.001f; + int32_t v437 = (int32_t)data[1]; + + /*if (a6) + task_mask_screen_fade_out(duration, v437 != 1);*/ + pv_game->data.pv_end_fadeout = true; + } break; + case DSC_FT_TARGET_FLAG: { + } break; + case DSC_FT_ITEM_ANIM_ATTACH: { + chara_id = (int32_t)data[0]; + playdata = &this->playdata[chara_id]; + rob_chr = playdata->rob_chr; + + int32_t index = (int32_t)data[1]; + int32_t attach = (int32_t)data[2]; + + if (index >= 0) + pv_game->set_data_itmpv_chara_id(chara_id, index, attach == 1); + } break; + case DSC_FT_SHADOW_RANGE: { + float_t range = (float_t)(int32_t)data[0] * 0.001f; + + rctx_ptr->render_manager.shadow_ptr->range = range; + } break; + case DSC_FT_HAND_SCALE: { + chara_id = (int32_t)data[0]; + playdata = &this->playdata[chara_id]; + rob_chr = playdata->rob_chr; + + int32_t hand = (int32_t)data[1]; + float_t scale = (float_t)(int32_t)data[2] * 0.001f; + + if (rob_chr) + switch (hand) { + case 0: + rob_chr->set_right_hand_scale(scale); + break; + case 1: + rob_chr->set_left_hand_scale(scale); + break; + } + } break; + case DSC_FT_LIGHT_POS: { + vec3 pos; + pos.x = (float_t)(int32_t)data[0] * 0.001f; + pos.y = (float_t)(int32_t)data[1] * 0.001f; + pos.z = (float_t)(int32_t)data[2] * 0.001f; + int32_t index = (int32_t)data[3]; + + if (index >= LIGHT_CHARA && index <= LIGHT_PROJECTION) { + light_set* set_data = &rctx_ptr->light_set[LIGHT_SET_MAIN]; + set_data->lights[index].set_position(pos); + } + } break; + case DSC_FT_FACE_TYPE: { + } break; + case DSC_FT_SHADOW_CAST: { + chara_id = (int32_t)data[0]; + playdata = &this->playdata[chara_id]; + rob_chr = playdata->rob_chr; + + int32_t shadow_cast = (int32_t)data[0]; + + if (rob_chr) + rob_chr->set_shadow_cast(shadow_cast == 1); + } break; + case DSC_FT_FOG: { + } break; + case DSC_FT_BLOOM: { + int32_t id = (int32_t)data[0]; + float_t duration = (float_t)(int32_t)data[1]; + + pv_game->set_pv_param_post_process_bloom_data(true, id, duration); + } break; + case DSC_FT_COLOR_COLLE: { + int32_t set = (int32_t)data[0]; + int32_t id = (int32_t)data[1]; + float_t duration = (float_t)(int32_t)data[2]; + + pv_game->set_pv_param_post_process_color_correction_data(set == 1, id, duration); + } break; + case DSC_FT_DOF: { + int32_t set = (int32_t)data[0]; + int32_t id = (int32_t)data[1]; + float_t duration = (float_t)(int32_t)data[2]; + + pv_game->set_pv_param_post_process_dof_data(set == 1, id, duration); + } break; + case DSC_FT_CHARA_ALPHA: { + chara_id = (int32_t)data[0]; + playdata = &this->playdata[chara_id]; + rob_chr = playdata->rob_chr; + + float_t alpha = (float_t)(int32_t)data[1] * 0.001f; + float_t duration = (float_t)(int32_t)data[2]; + int32_t type = (int32_t)data[3]; + + pv_game->set_pv_param_post_process_chara_alpha_data(chara_id, alpha, type, duration); + } break; + case DSC_FT_AOTO_CAP: { + int32_t enable = (int32_t)data[0]; + + if (pv_game->data.pv) + rctx_ptr->post_process.frame_texture_cont_capture_set(enable == 1); + } break; + case DSC_FT_MAN_CAP: { + int32_t slot = (int32_t)data[0]; + + if (pv_game->data.pv && slot >= 0 && slot <= 4) + rctx_ptr->post_process.frame_texture_slot_capture_set(slot + 1); + } break; + case DSC_FT_TOON: { + int32_t npr_param = (int32_t)data[0]; + int32_t value = (int32_t)data[1]; + + rctx_ptr->render_manager.set_npr_param(npr_param); + if (npr_param == 1) + if (value > 0) + npr_cloth_spec_color.w = (float_t)(value - 1) * 0.1f; + else + npr_cloth_spec_color.w = 1.0f; + } break; + case DSC_FT_SHIMMER: { + } break; + case DSC_FT_ITEM_ALPHA: { + chara_id = (int32_t)data[0]; + playdata = &this->playdata[chara_id]; + rob_chr = playdata->rob_chr; + + float_t alpha = (float_t)(int32_t)data[1] * 0.001f; + float_t duration = (float_t)(int32_t)data[2]; + int32_t type = (int32_t)data[3]; + + pv_game->set_pv_param_post_process_chara_item_alpha_data(chara_id, alpha, type, duration); + } break; + case DSC_FT_MOVIE_CUT_CHG: { + /*int32_t v486 = (int32_t)data[0]; + int32_t v487 = (int32_t)data[1]; + + if (pv_game_get()->loaded) { + for (int32_t m = 0; m < 2; m++) + if (app::TaskWork::CheckTaskReady(task_movie_get(m))) + task_movie_get(m)->field_88 = 0; + + if (v486 != -1 && app::TaskWork::CheckTaskReady(task_movie_get(v486))) { + task_movie_get(v486)->sub_14041EF10((__int64)v492); + pv_game_get()->data.field_2D0C0 = v486; + //sub_14041F210(curr_time); + if (!pv_game->data.field_2D8A0) + v487 = 0; + if (v487) + switch (v487) { + case 1: + v488 = 1; + break; + case 2: + v488 = 2; + break; + } + task_movie_get(v486)->field_88 = v488; + } + }*/ + } break; + case DSC_FT_CHARA_LIGHT: { + int32_t id = (int32_t)data[0]; + float_t transition = (float_t)(int32_t)data[1]; + + light_param_light_data& light_data = pv_param::light_data_get_chara_light_data(id); + + light_set* set_data = &rctx_ptr->light_set[LIGHT_SET_MAIN]; + ::light_data* light_chara = &set_data->lights[LIGHT_CHARA]; + + light_chara->set_ambient(light_data.ambient); + light_chara->set_diffuse(light_data.diffuse); + light_chara->set_specular(light_data.specular); + light_chara->set_position(light_data.position); + } break; + case DSC_FT_STAGE_LIGHT: { + int32_t id = (int32_t)data[0]; + float_t transition = (float_t)(int32_t)data[1]; + + light_param_light_data& light_data = pv_param::light_data_get_chara_light_data(id); + + light_set* set_data = &rctx_ptr->light_set[LIGHT_SET_MAIN]; + ::light_data* light_stage = &set_data->lights[LIGHT_STAGE]; + + light_stage->set_ambient(light_data.ambient); + light_stage->set_diffuse(light_data.diffuse); + light_stage->set_specular(light_data.specular); + light_stage->set_position(light_data.position); + } break; + case DSC_FT_AGEAGE_CTRL: { + int32_t chara_id = (int32_t)data[0]; + int32_t parts = (int32_t)data[0]; + int32_t npr = (int32_t)data[2]; + int32_t rot_speed = (int32_t)data[3]; + int32_t skip = (int32_t)data[4]; + int32_t disp = (int32_t)data[5]; + + switch (parts) { + case 0: + rob_chara_age_age_array_set_params(chara_id, 1, npr, rot_speed, skip, disp); + rob_chara_age_age_array_set_params(chara_id, 2, npr, rot_speed, skip, disp); + break; + case 1: + rob_chara_age_age_array_set_params(chara_id, 1, npr, rot_speed, skip, disp); + break; + case 2: + rob_chara_age_age_array_set_params(chara_id, 2, npr, rot_speed, skip, disp); + break; + } + } break; + default: { + //sub_140859DBC("PV Script Command Error\n"); + play = false; + } return false; + } + return true; +} + +void pv_game_pv_data::dsc_reset_position() { + //dsc_get_start_position(&dsc_buffer_counter); + dsc_data_ptr = dsc.data.data(); + dsc_data_ptr_end = dsc.data.data() + dsc.data.size(); +} + +/*void pv_game_pv_data::dsc_get_start_position(int32_t* value) { + if (value) + *value = has_signature ? 1 : 0; +}*/ + +void pv_game_pv_data::find_change_fields() { + change_field_branch_fail.clear(); + change_field_branch_success.clear(); + + bool branch = false; + 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_func(DSC_FT_CHANGE_FIELD, &time, &pv_branch_mode, i, i_end)) { + if (time < 0) { + time = prev_time; + if (prev_time < 0) + break; + } + + uint32_t* data = dsc.get_func_data(i); + + switch (pv_branch_mode) { + case 0: + change_field_branch_fail.push_back({ time, data[0] }); + change_field_branch_success.push_back({ time, data[0] }); + if (!branch) + change_field_branch_time = 10000LL * time; + break; + case 1: + change_field_branch_fail.push_back({ time, data[0] }); + branch = true; + break; + case 2: + change_field_branch_success.push_back({ time, data[0] }); + branch = true; + break; + } + + prev_time = time; + i++; + } +} + +dsc_data* pv_game_pv_data::find_func(int32_t func_name, int32_t* time, + int32_t* pv_branch_mode, dsc_data* start, dsc_data* end) { + if (!start || !end) + return 0; + + 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_FT_END) + break; + else if (i->func == DSC_FT_TIME) { + uint32_t* data = dsc.get_func_data(i); + _time = (int32_t)data[0]; + } + else if (i->func == DSC_FT_PV_END) + break; + else if (i->func == DSC_FT_PV_BRANCH_MODE) { + if (pv_branch_mode) { + uint32_t* data = dsc.get_func_data(i); + *pv_branch_mode = (int32_t)data[0]; + } + } + return 0; +} + +void pv_game_pv_data::find_data_camera() { + data_camera_branch_fail.clear(); + data_camera_branch_success.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 (i = find_func(DSC_FT_CHANGE_FIELD, &time, &pv_branch_mode, i, i_end)) { + if (time < 0) { + time = prev_time; + if (prev_time < 0) + break; + } + + uint32_t* data = dsc.get_func_data(i); + int32_t stage_effect = (int32_t)data[0]; + + switch (pv_branch_mode) { + case 0: + data_camera_branch_fail.push_back(time); + data_camera_branch_success.push_back(time); + break; + case 1: + data_camera_branch_fail.push_back(time); + break; + case 2: + data_camera_branch_success.push_back(time); + break; + } + + prev_time = time; + i++; + } +} + +void pv_game_pv_data::find_playdata_item_anim(int32_t chara_id) { + if (chara_id < 0 || chara_id >= ROB_CHARA_COUNT) + return; + + std::vector& item_anim = playdata[chara_id].motion_data.item_anim; + item_anim.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 (i = find_func(DSC_FT_ITEM_ANIM, &time, &pv_branch_mode, i, i_end)) { + if (time < 0) { + time = prev_time; + if (prev_time < 0) + break; + } + + uint32_t* data = dsc.get_func_data(i); + if (chara_id == (int32_t)data[0] && (int32_t)data[2] == 2) + item_anim.push_back({ time, (int32_t)data[1], pv_branch_mode }); + + prev_time = time; + i++; + } +} + +void pv_game_pv_data::find_playdata_set_motion(int32_t chara_id) { + if (chara_id < 0 || chara_id >= ROB_CHARA_COUNT) + return; + + std::vector& set_motion = playdata[chara_id].motion_data.set_motion; + 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 (i = find_func(DSC_FT_SET_MOTION, &time, &pv_branch_mode, i, i_end)) { + if (time < 0) { + time = prev_time; + if (prev_time < 0) + break; + } + + uint32_t* data = dsc.get_func_data(i); + if (chara_id == (int32_t)data[0]) + set_motion.push_back({ time, (int32_t)data[1], pv_branch_mode }); + + prev_time = time; + i++; + } +} + +void pv_game_pv_data::find_set_motion(const pv_db_pv_difficulty* diff) { + if (!diff) + return; + + std::vector v94; + std::vector v99[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_func(DSC_FT_SET_PLAYDATA, &time, &pv_branch_mode, i, i_end); + if (!i) + break; + + if (time < 0) + time = prev_time; + + uint32_t* data = dsc.get_func_data(i); + + int32_t chara_id = (int32_t)data[0]; + int32_t motion_index = (int32_t)data[1]; + + v99[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_func(DSC_FT_CHANGE_FIELD, &time, &pv_branch_mode, i, i_end); + if (!i) + break; + + if (time < 0) + time = prev_time; + + uint32_t* data = dsc.get_func_data(i); + + int32_t field = (int32_t)data[0]; + + if (field >= 0 && field < diff->field.data.size()) + v94.push_back({ time, diff->field.data[field].stage_index, pv_branch_mode }); + + prev_time = time; + i++; + } + + for (std::vector& i : set_motion) + i.clear(); + + data_struct* aft_data = &data_list[DATA_AFT]; + motion_database* aft_mot_db = &aft_data->data_ft.mot_db; + + for (int32_t i = 0; i < ROB_CHARA_COUNT; i++) { + std::vector& set_motion = this->set_motion[i]; + pv_play_data& playdata = this->playdata[i]; + + for (pv_play_data_event& j : playdata.motion_data.set_motion) { + int32_t stage_index = 0; + int32_t time = -1; + + pv_play_data_event* k_begin = v94.data() + v94.size(); + pv_play_data_event* k_end = v94.data(); + for (pv_play_data_event* k = k_begin; k != k_end; ) { + k--; + + if (k->time <= j.time && k->pv_branch_mode == j.pv_branch_mode) { + stage_index = k->index; + break; + } + } + + pv_play_data_event* l_begin = v99[i].data() + v99[i].size(); + pv_play_data_event* l_end = v99[i].data(); + for (pv_play_data_event* l = l_begin; l != l_end; ) { + l--; + + if (l->index == j.index && l->time <= j.time) { + time = l->time; + break; + } + } + + if (time < 0) + time = j.time; + + float_t frame = dsc_time_to_frame(((int64_t)j.time - time) * 10000); + + if (frame >= 0.0f) + frame += 0.5f; + else + frame -= 0.5f; + + int32_t frame_int = (int32_t)frame; + if (frame != -0.0f && (float_t)frame_int != frame) + frame = (float_t)(frame < 0.0f ? frame_int - 1 : frame_int); + + int32_t motion_id = diff->get_motion_or_default(i, j.index).id; + if (pv_game_get()->data.pv) { + rob_chara* rob_chr = playdata.rob_chr; + if (rob_chr) + motion_id = pv_game_get()->data.pv->get_chrmot_motion_id(rob_chr->chara_id, + rob_chr->chara_index, diff->get_motion_or_default(i, j.index)); + } + + if (motion_id != -1) + set_motion.push_back({ motion_id, { frame, stage_index } }); + } + } +} + +const std::vector* pv_game_pv_data::get_set_motion(size_t chara_id) { + if (chara_id >= 0 && chara_id < ROB_CHARA_COUNT) + return &set_motion[chara_id]; + return 0; +} + +pv_dsc_target_group* pv_game_pv_data::get_target() { + if (target_index < targets.size()) + return &targets[target_index]; + return 0; +} + +int32_t pv_game_pv_data::get_target_target_count(size_t index, float_t time_offset, bool a4) { + if (index >= targets.size()) + return 0; + + /*if (a4) + sub_14012B9A0(this->field_2BF80, &targets[index], dsc_time, index);*/ + return targets[index].target_count; +} + +void pv_game_pv_data::init(::pv_game* pv_game, bool a3) { + this->pv_game = pv_game; + //field_2BF80 = sub_14013C8F0(); + music = pv_game_music_get(); + 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->data.chara[i].chara_id == -1 || !pv_game->data.chara[i].rob_chr) + continue; + + pv_play_data& playdata = this->playdata[i]; + playdata.reset(); + playdata.set_motion.clear(); + + if (pv_game->data.chara[i].chara_id != -1) + playdata.rob_chr = rob_chara_array_get(pv_game->data.chara[i].chara_id); + + 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_reset_data(i, playdata.rob_chr, anim_frame_speed); + } + + find_playdata_set_motion(i); + find_playdata_item_anim(i); + } + + target_flying_time = -1.0f; + time_signature = -1; + field_2BFB0 = -1; + field_2BFB4 = -1; + field_2BFB8 = -1; + field_2BFBC = -1; + field_2BFC0 = a3; + field_2BFD4 = false; + field_2BFD5 = false; + pv_end = false; + targets_remaining = 0; + target_index = 0; + scene_rot_y = 0.0f; + scene_rot_mat = mat4_identity; + first_challenge_note = -1; + last_challenge_note = -1; + curr_time = 0; + curr_time_float = 0.0f; + prev_time_float = 0.0f; + field_2BF30 = -1; + field_2BF38 = 0; + field_2BF68 = 0; + music_play = false; + + dsc_reset_position(); + + play = true; + field_2BF50 = false; + field_2BF60 = false; + field_2BF58 = -1; + + pv_game_camera_reset(); + + fov = 32.2673416137695f; + min_dist = 0.05f; + + scene_fade.reset(); + + find_data_camera(); + find_change_fields(); + + const pv_db_pv_difficulty* diff = pv_game->data.pv->get_difficulty( + sub_14013C8C0()->difficulty, sub_14013C8C0()->edition); + find_set_motion(diff); + + shadow* shad = rctx_ptr->render_manager.shadow_ptr; + if (shad) { + shad->blur_filter_enable[0] = 0x1; + shad->blur_filter_enable[1] = 0x1; + } + + pv_game->data.play_data.lyrics_color = { 0xFF, 0xFF, 0xFF, 0xFF }; + + field_0 = true; + chara_id = 0; + + field_2C560.reset(); + + reset_camera_post_process(); +} + +bool pv_game_pv_data::read_dsc_file(std::string&& file_path, ::pv_game* pv_game, bool a4) { + switch (dsc_state) { + case 0: + if (dsc_file_handler.read_file(&data_list[DATA_AFT], file_path.c_str())) + dsc_state = 1; + break; + case 1: { + if (dsc_file_handler.check_not_ready()) + break; + + has_signature = false; + has_perf_id = false; + + const void* data = dsc_file_handler.get_data(); + size_t size = dsc_file_handler.get_size(); + if (data && size && !(size % 4)) { + uint32_t signature = *(uint32_t*)data; + has_signature = signature >= 0x10000000; + has_perf_id = has_signature && signature >= 0x10101514; + dsc.parse(data, size, has_perf_id ? DSC_FT : DSC_AC120); + if (!has_perf_id) + dsc.convert(DSC_FT); + } + + dsc_file_handler.reset(); + //dsc_process(pv_game); + dsc_state = 2; + } break; + case 2: + init(pv_game, a4); + dsc_state = 0; + return true; + } + return false; +} + +void pv_game_pv_data::reset() { + pv_game = 0; + //field_2BF80 = 0; + music = 0; + dsc_file_handler.reset(); + play = false; + field_2BF50 = false; + + if (sub_14013C8C0()->sub_1400E7910() >= 6) + field_2BF60 = false; + + for (pv_play_data& i : playdata) { + i.rob_chr = 0; + i.set_motion.clear(); + i.motion_data.clear(); + pv_expression_array_reset_motion(&i - playdata); + } + + data_camera_branch_fail.clear(); + data_camera_branch_fail.shrink_to_fit(); + data_camera_branch_success.clear(); + data_camera_branch_success.shrink_to_fit(); + change_field_branch_fail.clear(); + change_field_branch_fail.shrink_to_fit(); + change_field_branch_success.clear(); + change_field_branch_success.shrink_to_fit(); + change_field_branch_time = -1; + + scene_fade.reset(); + + reset_camera_post_process(); + + targets.clear(); + targets.shrink_to_fit(); + target_index = 0; + field_0 = 0; +} + +void pv_game_pv_data::reset_camera_post_process() { + camera* cam = rctx_ptr->camera; + cam->set_ignore_min_dist(false); + cam->set_max_distance(0.05); + cam->set_ignore_fov(false); + cam->set_fov(32.2673416137695); + + post_process* pp = &rctx_ptr->post_process; + pp->tone_map->set_scene_fade_color(0.0f); + pp->tone_map->set_scene_fade_alpha(0.0f); + pp->tone_map->set_scene_fade_alpha(0); + pp->tone_map->set_tone_trans(0.0f, 1.0f); + pp->tone_map->set_saturate_coeff(1.0f); + + shadow* shad = rctx_ptr->render_manager.shadow_ptr; + if (shad) + for (bool& i : shad->blur_filter_enable) + i = true; + + branch_mode = false; + + for (pv_data_camera& i : data_camera) + i = {}; +} + +void pv_game_pv_data::scene_fade_ctrl(float_t delta_time) { + scene_fade.ctrl(delta_time); +} + +void pv_game_pv_data::set_camera_max_frame(int32_t time) { + std::vector& data_camera = branch_mode != 2 + ? data_camera_branch_fail + : data_camera_branch_success; + for (int32_t& i : data_camera) { + if (10000LL * i <= dsc_time) + continue; + + float_t max_frame = dsc_time_to_frame(10000LL * i - time); + if (max_frame > 0.0f) + max_frame = (float_t)(int32_t)(max_frame + 0.5f); + else if (max_frame < 0.0f) + max_frame = (float_t)(int32_t)(max_frame - 0.5f); + + if (pv_game->data.camera_auth_3d_uid != -1) { + auth_3d_id id = pv_game->get_auth_3d_id(pv_game->data.camera_auth_3d_uid); + if (id.check_not_empty()) + id.set_max_frame(max_frame - 1.0f); + } + break; + } +} + +void pv_game_pv_data::set_item_anim_max_frame(int32_t chara_id, int32_t index, int64_t time) { + if (chara_id < 0 || chara_id >= ROB_CHARA_COUNT || index < 0) + return; + + for (auto& i : playdata[chara_id].motion_data.item_anim) + if (10000LL * i.time > dsc_time && i.index == index && (!branch_mode || branch_mode == i.pv_branch_mode)) { + pv_game->set_data_itmpv_max_frame(chara_id, index, roundf(dsc_time_to_frame(10000LL * i.time - time)) - 1.0f); + break; + } +} + +void 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; + + pv_play_data& playdata = this->playdata[chara_id]; + + std::vector& set_motion = playdata.motion_data.set_motion; + for (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( + roundf(dsc_time_to_frame(10000LL * i.time - time)) - 1.0f); + break; + } +} diff --git a/src/ReDIVA/pv_game/pv_game_pv_data.hpp b/src/ReDIVA/pv_game/pv_game_pv_data.hpp new file mode 100644 index 00000000..8837168e --- /dev/null +++ b/src/ReDIVA/pv_game/pv_game_pv_data.hpp @@ -0,0 +1,349 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#pragma once + +#include "../../CRE/rob/rob.hpp" +#include "../../KKdLib/dsc.hpp" + +enum dsc_ft_func { + DSC_FT_END = 0, + DSC_FT_TIME, + DSC_FT_MIKU_MOVE, + DSC_FT_MIKU_ROT, + DSC_FT_MIKU_DISP, + DSC_FT_MIKU_SHADOW, + DSC_FT_TARGET, + DSC_FT_SET_MOTION, + DSC_FT_SET_PLAYDATA, + DSC_FT_EFFECT, + DSC_FT_FADEIN_FIELD, + DSC_FT_EFFECT_OFF, + DSC_FT_SET_CAMERA, + DSC_FT_DATA_CAMERA, + DSC_FT_CHANGE_FIELD, + DSC_FT_HIDE_FIELD, + DSC_FT_MOVE_FIELD, + DSC_FT_FADEOUT_FIELD, + DSC_FT_EYE_ANIM, + DSC_FT_MOUTH_ANIM, + DSC_FT_HAND_ANIM, + DSC_FT_LOOK_ANIM, + DSC_FT_EXPRESSION, + DSC_FT_LOOK_CAMERA, + DSC_FT_LYRIC, + DSC_FT_MUSIC_PLAY, + DSC_FT_MODE_SELECT, + DSC_FT_EDIT_MOTION, + DSC_FT_BAR_TIME_SET, + DSC_FT_SHADOWHEIGHT, + DSC_FT_EDIT_FACE, + DSC_FT_MOVE_CAMERA, + DSC_FT_PV_END, + DSC_FT_SHADOWPOS, + DSC_FT_EDIT_LYRIC, + DSC_FT_EDIT_TARGET, + DSC_FT_EDIT_MOUTH, + DSC_FT_SET_CHARA, + DSC_FT_EDIT_MOVE, + DSC_FT_EDIT_SHADOW, + DSC_FT_EDIT_EYELID, + DSC_FT_EDIT_EYE, + DSC_FT_EDIT_ITEM, + DSC_FT_EDIT_EFFECT, + DSC_FT_EDIT_DISP, + DSC_FT_EDIT_HAND_ANIM, + DSC_FT_AIM, + DSC_FT_HAND_ITEM, + DSC_FT_EDIT_BLUSH, + DSC_FT_NEAR_CLIP, + DSC_FT_CLOTH_WET, + DSC_FT_LIGHT_ROT, + DSC_FT_SCENE_FADE, + DSC_FT_TONE_TRANS, + DSC_FT_SATURATE, + DSC_FT_FADE_MODE, + DSC_FT_AUTO_BLINK, + DSC_FT_PARTS_DISP, + DSC_FT_TARGET_FLYING_TIME, + DSC_FT_CHARA_SIZE, + DSC_FT_CHARA_HEIGHT_ADJUST, + DSC_FT_ITEM_ANIM, + DSC_FT_CHARA_POS_ADJUST, + DSC_FT_SCENE_ROT, + DSC_FT_EDIT_MOT_SMOOTH_LEN, + DSC_FT_PV_BRANCH_MODE, + DSC_FT_DATA_CAMERA_START, + DSC_FT_MOVIE_PLAY, + DSC_FT_MOVIE_DISP, + DSC_FT_WIND, + DSC_FT_OSAGE_STEP, + DSC_FT_OSAGE_MV_CCL, + DSC_FT_CHARA_COLOR, + DSC_FT_SE_EFFECT, + DSC_FT_EDIT_MOVE_XYZ, + DSC_FT_EDIT_EYELID_ANIM, + DSC_FT_EDIT_INSTRUMENT_ITEM, + DSC_FT_EDIT_MOTION_LOOP, + DSC_FT_EDIT_EXPRESSION, + DSC_FT_EDIT_EYE_ANIM, + DSC_FT_EDIT_MOUTH_ANIM, + DSC_FT_EDIT_CAMERA, + DSC_FT_EDIT_MODE_SELECT, + DSC_FT_PV_END_FADEOUT, + DSC_FT_TARGET_FLAG, + DSC_FT_ITEM_ANIM_ATTACH, + DSC_FT_SHADOW_RANGE, + DSC_FT_HAND_SCALE, + DSC_FT_LIGHT_POS, + DSC_FT_FACE_TYPE, + DSC_FT_SHADOW_CAST, + DSC_FT_EDIT_MOTION_F, + DSC_FT_FOG, + DSC_FT_BLOOM, + DSC_FT_COLOR_COLLE, + DSC_FT_DOF, + DSC_FT_CHARA_ALPHA, + DSC_FT_AOTO_CAP, + DSC_FT_MAN_CAP, + DSC_FT_TOON, + DSC_FT_SHIMMER, + DSC_FT_ITEM_ALPHA, + DSC_FT_MOVIE_CUT_CHG, + DSC_FT_CHARA_LIGHT, + DSC_FT_STAGE_LIGHT, + DSC_FT_AGEAGE_CTRL, + DSC_FT_MAX, +}; + +struct pv_play_data_set_motion { + float_t frame_speed; + int32_t motion_id; + float_t frame; + float_t blend_duration; + bool blend; + MotionBlendType blend_type; + bool disable_eye_motion; + int32_t motion_index; + int64_t dsc_time; + float_t dsc_frame; + + pv_play_data_set_motion(); + + void reset(); +}; + +struct pv_play_data_motion { + bool enable; + int32_t motion_index; + int64_t time; +}; + +struct pv_play_data_event { + int32_t time; + int32_t index; + int32_t pv_branch_mode; +}; + +struct pv_play_data_motion_data { + rob_chara* rob_chr; + float_t current_time; + float_t duration; + vec3 start_pos; + vec3 end_pos; + float_t start_rot; + float_t end_rot; + float_t mot_smooth_len; + std::vector set_motion; + std::vector item_anim; + + pv_play_data_motion_data(); + ~pv_play_data_motion_data(); + + void ctrl(float_t delta_time); + void ctrl_inner(); + void clear(); + void reset(); + void set(rob_chara* rob_chr, float_t duration, + vec3 start_pos, vec3 end_pos, float_t start_rot, float_t end_rot); +}; + +struct pv_play_data { + std::vector motion; + rob_chara* rob_chr; + std::list set_motion; + bool disp; + bool shadow; + pv_play_data_motion_data motion_data; + + pv_play_data(); + ~pv_play_data(); + + pv_play_data_motion* get_motion(int32_t motion_index); + void reset(); +}; + +struct pv_data_camera { + bool enable; + int32_t index; + int64_t time; + + pv_data_camera(); +}; + +struct pv_scene_fade { + bool enable; + float_t time; + float_t duration; + float_t start_alpha; + float_t end_alpha; + vec3 color; + + pv_scene_fade(); + + void ctrl(float_t delta_time); + void reset(); +}; + +struct pv_dsc_target { + dsc_target_ft type; + vec2 pos; + vec2 start_pos; + float_t amplitude; + int32_t frequency; + bool slide_chain_start; + bool slide_chain_end; + bool slide_chain_left; + bool slide_chain_right; + bool slide_chain; + + pv_dsc_target(); +}; + +struct pv_dsc_target_group { + int32_t target_count; + pv_dsc_target targets[4]; + int32_t field_94; + int64_t time_begin; + int64_t time_end; + bool slide_chain; + + pv_dsc_target_group(); +}; + +struct struc_676 { + bool field_0[ROB_CHARA_COUNT]; + pv_play_data_set_motion field_8[ROB_CHARA_COUNT]; + bool field_128[ROB_CHARA_COUNT]; + int32_t field_130[ROB_CHARA_COUNT]; + bool field_148[ROB_CHARA_COUNT]; + pv_play_data_set_motion field_150[ROB_CHARA_COUNT]; + float_t field_270[ROB_CHARA_COUNT]; + bool field_288[ROB_CHARA_COUNT]; + int32_t field_290[ROB_CHARA_COUNT]; + float_t field_2A8[ROB_CHARA_COUNT]; + bool field_2C0; + int32_t field_2C4; + int32_t field_2C8; + float_t field_2CC; + int64_t field_2D0; + + struc_676(); + + void reset(); +}; + +struct pv_game_pv_data { + bool field_0; + int32_t dsc_state; + bool play; + //uint32_t dsc_buffer[45000]; + //int32_t dsc_buffer_counter; + dsc dsc; + dsc_data* dsc_data_ptr; + dsc_data* dsc_data_ptr_end; + int64_t field_2BF30; + int64_t field_2BF38; + int64_t curr_time; + float_t curr_time_float; + float_t prev_time_float; + bool field_2BF50; + int64_t field_2BF58; + bool field_2BF60; + int32_t field_2BF64; + int64_t field_2BF68; + int32_t chara_id; + struct pv_game* pv_game; + //struc_162* field_2BF80; + struct pv_game_music* music; + p_file_handler dsc_file_handler; + float_t target_anim_fps; + float_t anim_frame_speed; + float_t target_flying_time; + int32_t time_signature; + ssize_t dsc_time; + int32_t field_2BFB0; + int32_t field_2BFB4; + int32_t field_2BFB8; + int32_t field_2BFBC; + bool field_2BFC0; + bool music_play; + int32_t field_2BFC4; + bool pv_end; + float_t fov; + float_t min_dist; + bool field_2BFD4; + bool field_2BFD5; + pv_play_data playdata[ROB_CHARA_COUNT]; + pv_data_camera data_camera[3]; + std::vector data_camera_branch_fail; + std::vector data_camera_branch_success; + std::vector set_motion[ROB_CHARA_COUNT]; + prj::vector_pair change_field_branch_fail; + prj::vector_pair change_field_branch_success; + int64_t change_field_branch_time; + pv_scene_fade scene_fade; + bool has_signature; + bool has_perf_id; + int32_t targets_remaining; + std::vector targets; + size_t target_index; + float_t scene_rot_y; + mat4 scene_rot_mat; + float_t field_2C54C; + int32_t field_2C550; + int32_t branch_mode; + int32_t first_challenge_note; + int32_t last_challenge_note; + struc_676 field_2C560; + + pv_game_pv_data(); + ~pv_game_pv_data(); + + int64_t ctrl(float_t delta_time, int64_t curr_time, bool a4); + //void dsc_buffer_counter_set(); + //void dsc_buffer_set(const void* data, uint32_t size); + bool dsc_ctrl(float_t delta_time, int64_t curr_time, float_t* dsc_time_offset, bool* music_play, bool a6, bool ignore_targets); + void dsc_reset_position(); + //void dsc_get_start_position(int32_t* value); + dsc_data* find_func(int32_t func_name, int32_t* time, + int32_t* pv_branch_mode, dsc_data* start, dsc_data* end); + void find_change_fields(); + void find_data_camera(); + void find_playdata_item_anim(int32_t chara_id); + void find_playdata_set_motion(int32_t chara_id); + void find_set_motion(const struct pv_db_pv_difficulty* diff); + const std::vector* get_set_motion(size_t chara_id); + pv_dsc_target_group* get_target(); + int32_t get_target_target_count(size_t index, float_t time_offset, bool a4); + void init(::pv_game * pv_game, bool a3); + bool read_dsc_file(std::string&& file_path, struct pv_game* pv_game, bool a4); + void reset(); + void reset_camera_post_process(); + void scene_fade_ctrl(float_t delta_time); + void set_camera_max_frame(int32_t time); + void set_item_anim_max_frame(int32_t chara_id, int32_t index, int64_t time); + void set_motion_max_frame(int32_t chara_id, int32_t motion_index, int64_t time); +}; diff --git a/src/ReDIVA/pv_game/target_pos.cpp b/src/ReDIVA/pv_game/target_pos.cpp new file mode 100644 index 00000000..acd9f9cc --- /dev/null +++ b/src/ReDIVA/pv_game/target_pos.cpp @@ -0,0 +1,22 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#include "target_pos.hpp" +#include "../../CRE/resolution_mode.hpp" + +vec2 target_pos_scale; +vec2 target_pos_offset; + +void target_pos_scale_offset_apply(const vec2* src, vec2* dst) { + if (src && dst) + *dst = target_pos_scale * *src + target_pos_offset; +} + +void target_pos_scale_offset_get() { + resolution_struct v0(RESOLUTION_MODE_HD); + target_pos_offset = 0.0f; + target_pos_scale.x = (float_t)v0.width * (float_t)(1.0 / 480.0); + target_pos_scale.y = (float_t)v0.height * (float_t)(1.0 / 272.0); +} diff --git a/src/ReDIVA/pv_game/target_pos.hpp b/src/ReDIVA/pv_game/target_pos.hpp new file mode 100644 index 00000000..6bdd01e6 --- /dev/null +++ b/src/ReDIVA/pv_game/target_pos.hpp @@ -0,0 +1,14 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#pragma once + +#include "../../KKdLib/vec.hpp" + +extern vec2 target_pos_scale; +extern vec2 target_pos_offset; + +extern void target_pos_scale_offset_apply(const vec2* src, vec2* dst); +extern void target_pos_scale_offset_get(); diff --git a/src/ReDIVA/render.cpp b/src/ReDIVA/render.cpp index 47a02ce8..a229b59b 100644 --- a/src/ReDIVA/render.cpp +++ b/src/ReDIVA/render.cpp @@ -15,6 +15,7 @@ #include "../CRE/auth_3d.hpp" #include "../CRE/camera.hpp" #include "../CRE/clear_color.hpp" +#include "../CRE/customize_item_table.hpp" #include "../CRE/data.hpp" #include "../CRE/fbo.hpp" #include "../CRE/file_handler.hpp" @@ -23,6 +24,7 @@ #include "../CRE/light_param.hpp" #include "../CRE/lock.hpp" #include "../CRE/mdata_manager.hpp" +#include "../CRE/module_table.hpp" #include "../CRE/object.hpp" #include "../CRE/ogg_vorbis.hpp" #include "../CRE/pv_db.hpp" @@ -48,11 +50,11 @@ #include "data_test/auth_3d_test.hpp" #include "data_test/glitter_test.hpp" #include "data_test/stage_test.hpp" +#include "pv_game/pv_game.hpp" #include "game_state.hpp" #include "imgui_helper.hpp" #include "input.hpp" #include "task_window.hpp" -#include "pv_game.hpp" #include "x_pv_game.hpp" #include #include @@ -853,6 +855,8 @@ static render_context* render_context_load() { dbg_set_id = aft_obj_db->get_object_set_id("DBG"); hand_item_handler_data_init(); + module_table_handler_data_init(); + customize_item_table_handler_data_init(); aet_manager_add_aet_sets(aft_aet_db); sprite_manager_add_spr_sets(aft_spr_db); @@ -1007,7 +1011,7 @@ static void render_context_ctrl(render_context* rctx) { game_state_set_game_state_next(GAME_STATE_GAME); else if (Input::IsKeyTapped(GLFW_KEY_F6)) { game_state_set_game_state_next(GAME_STATE_DATA_TEST); - game_state_set_sub_game_state_next(SUB_GAME_STATE_DATA_TEST_AUTH_3D); + game_state_set_sub_game_state_next(SUB_GAME_STATE_DATA_TEST_AET); } else if (Input::IsKeyTapped(GLFW_KEY_F7)) game_state_set_game_state_next(GAME_STATE_TEST_MODE); @@ -1138,6 +1142,8 @@ static void render_context_dispose(render_context* rctx) { sprite_manager_remove_spr_sets(aft_spr_db); aet_manager_remove_aet_sets(aft_aet_db); + customize_item_table_handler_data_free(); + module_table_handler_data_free(); hand_item_handler_data_free(); //rob_chara_array_free_chara_id(0); diff --git a/src/ReDIVA/system_startup.cpp b/src/ReDIVA/system_startup.cpp index 436b0c9e..567e31e4 100644 --- a/src/ReDIVA/system_startup.cpp +++ b/src/ReDIVA/system_startup.cpp @@ -7,8 +7,8 @@ #include "../CRE/auth_2d.hpp" #include "../CRE/mdata_manager.hpp" #include "../CRE/sprite.hpp" +#include "pv_game/pv_game.hpp" #include "game_state.hpp" -#include "pv_game.hpp" system_startup_detail::TaskSystemStartup* task_system_startup; @@ -26,8 +26,6 @@ int32_t system_startup_ready; static bool system_startup_check_ready(); -static void task_pv_game_init_test_pv(); - namespace system_startup_detail { TaskSystemStartup::TaskSystemStartup() { @@ -61,7 +59,7 @@ namespace system_startup_detail { system_startup.state = 4; break; case 4: - rctx_ptr->render_manager.set_pass_sw(rndr::RND_PASSID_ALL_3D, false); + //rctx_ptr->render_manager.set_pass_sw(rndr::RND_PASSID_ALL_3D, false); task_pv_game_init_test_pv(); system_startup.state = 5; break; @@ -78,7 +76,7 @@ namespace system_startup_detail { system_startup.state = 8; break; case 8: - rctx_ptr->render_manager.set_pass_sw(rndr::RND_PASSID_ALL_3D, true); + //rctx_ptr->render_manager.set_pass_sw(rndr::RND_PASSID_ALL_3D, true); system_startup_ready = 1; break; } @@ -131,29 +129,12 @@ static bool system_startup_check_ready() { return true; task_pv_game_del_task(); - if (!task_pv_game_check_task_ready() && task_rob_manager_del_task()) - system_startup.ready = true; + if (!task_pv_game_check_task_ready()) { + //task_mask_screen_fade_in(0.0f, 0); + if (task_rob_manager_del_task()) { + system_startup.ready = true; + return true; + } + } return system_startup.ready; } - -static void task_pv_game_init_test_pv() { - if (test_mode_get()) - return; - - task_rob_manager_add_task(); - TaskPvGame::Args args; - args.init_data.pv_id = 999; - args.init_data.difficulty = 1; - args.init_data.field_C = 0; - args.init_data.score_percentage_clear = 50; - args.init_data.life_gauge_safety_time = 40; - args.init_data.life_gauge_border = 30; - args.field_190 = false; - args.field_191 = false; - args.no_fail = false; - args.field_193 = true; - args.field_194 = true; - args.field_195 = true; - args.test_pv = true; - task_pv_game_add_task(args); -} diff --git a/src/ReDIVA/x_pv_game.cpp b/src/ReDIVA/x_pv_game.cpp index 6752fa36..abab7804 100644 --- a/src/ReDIVA/x_pv_game.cpp +++ b/src/ReDIVA/x_pv_game.cpp @@ -1040,7 +1040,7 @@ void x_pv_game_effect::load_data(int32_t pv_id) { 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, false, 0); + x_data, buf, 0, -1.0f, false); if (hash != hash_murmurhash_empty) pv_glitter.push_back(std::string(buf, len)); break; @@ -2115,11 +2115,7 @@ void x_pv_game_dsc_data::find_change_fields(std::vector& change_fields) ::dsc_data* i = dsc.data.data(); ::dsc_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; - + while (i = find(DSC_X_CHANGE_FIELD, &time, &pv_branch_mode, i, i_end)) { if (time < 0) { time = prev_time; if (prev_time < 0) @@ -2156,11 +2152,7 @@ void x_pv_game_dsc_data::find_stage_effects(std::vectorstage_info) - if (task_stage_modern_has_stage_info(&i) && task_stage_modern_get_stage_hash(&i) == hash) { - stage_info = i; + 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; } - task_stage_modern_set_stage(&stage_info); - if (task_stage_modern_has_stage_info(&stage_info)) - task_stage_modern_set_stage_display(&stage_info, !!(flags & 0x04), true); + stg_info.set_stage(); + if (stg_info.check()) + stg_info.set_stage_display(!!(flags & 0x04), true); else task_stage_modern_current_set_stage_display(false, true); } @@ -3197,7 +3189,7 @@ void x_pv_game_stage::ctrl(float_t delta_time) { 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, false, 0); + x_data, i.name.c_str(), 0, i.emission, false); if (hash != hash_murmurhash_empty) stage_glitter.push_back(hash); } @@ -4150,7 +4142,7 @@ bool x_pv_game::Ctrl() { 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); + 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; } @@ -4164,7 +4156,7 @@ bool x_pv_game::Ctrl() { 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); + 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); @@ -5128,7 +5120,8 @@ void x_pv_game::Load(int32_t pv_id, int32_t stage_id, chara_index charas[6], int motion_set_load_motion(mot_set, "", aft_mot_db); motion_set_load_mothead(mot_set, "", aft_mot_db); - pv_param::post_process_data_load_files(pv_id); + pv_param::light_data_load_files(pv_id, ""); + pv_param::post_process_data_load_files(pv_id, ""); { dof d; @@ -5629,6 +5622,7 @@ bool x_pv_game::Unload() { 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]; @@ -6115,7 +6109,7 @@ static void x_pv_game_chara_item_alpha_callback(void* data, int32_t chara_id, in continue; for (x_pv_game_song_effect_auth_3d& j : i.auth_3d) - j.id.set_obj_flags_alpha(flags, alpha); + 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, @@ -6171,17 +6165,17 @@ static bool x_pv_game_dsc_process(x_pv_game* a1, int64_t curr_time) { a1->chara_id = (int32_t)data[0]; x_pv_play_data* playdata = &a1->playdata[a1->chara_id]; - vec3 trans; - trans.x = (float_t)(int32_t)data[1] * 0.001f; - trans.y = (float_t)(int32_t)data[2] * 0.001f; - trans.z = (float_t)(int32_t)data[3] * 0.001f; + vec3 pos; + pos.x = (float_t)(int32_t)data[1] * 0.001f; + pos.y = (float_t)(int32_t)data[2] * 0.001f; + pos.z = (float_t)(int32_t)data[3] * 0.001f; rob_chara* rob_chr = playdata->rob_chr; if (!rob_chr) break; - mat4_mult_vec3_trans(&a1->scene_rot_mat, - &trans, &rob_chr->data.miku_rot.position); + mat4_mult_vec3_trans(&a1->scene_rot_mat, &pos, &pos); + rob_chr->set_data_miku_rot_position(pos); rob_chr->set_osage_reset(); } break; case DSC_X_MIKU_ROT: { @@ -6216,29 +6210,25 @@ static bool x_pv_game_dsc_process(x_pv_game* a1, int64_t curr_time) { if (disp == 1) { rob_chr->set_visibility(true); - if (rob_chara_check_for_ageageagain_module(rob_chr->chara_index, rob_chr->module_index)) { + 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); } - //pv_game::set_data_itmpv_visibility(a1->pv_game, a1->chara_id, true); for (x_pv_play_data_set_motion& i : playdata->set_motion) { - bool v45 = rob_chr->set_motion_id(i.motion_id, i.frame, - i.blend_duration, i.field_10, false, i.blend_type, aft_bone_data, aft_mot_db); + 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 (v45) - pv_expression_array_set_motion(pv_data.exp_file.hash_murmurhash, a1->chara_id, i.motion_id); - //if (!a1->pv_game->data.pv->disable_calc_motfrm_limit) - pv_game_dsc_data_set_motion_max_frame(a1, a1->chara_id, i.motion_index, i.dsc_time); + if (set) + pv_expression_array_set_motion(pv_data.exp_file.hash_murmurhash, a1->chara_id, i.motion_id); + pv_game_dsc_data_set_motion_max_frame(a1, a1->chara_id, i.motion_index, i.dsc_time); } playdata->set_motion.clear(); } - else { + else rob_chr->set_visibility(false); - //pv_game::set_data_itmpv_visibility(a1->pv_game, a1->chara_id, false); - } } break; case DSC_X_MIKU_SHADOW: { a1->chara_id = data[0]; @@ -6283,21 +6273,21 @@ static bool x_pv_game_dsc_process(x_pv_game* a1, int64_t curr_time) { float_t frame = 0.0f; float_t dsc_frame = 0.0f; - bool v11 = false; - x_pv_play_data_motion* v56 = 0; + bool blend = false; + x_pv_play_data_motion* motion = 0; for (x_pv_play_data_motion& i : playdata->motion) if (i.motion_index == motion_index) { - v56 = &i; + motion = &i; break; } - if (v56 && v56->enable && (motion_index == v56->motion_index || !v56->motion_index)) { - if (pv_data.dsc_data.time != v56->time) { - frame = dsc_time_to_frame(curr_time - v56->time); - dsc_frame = roundf(dsc_time_to_frame(pv_data.dsc_data.time - v56->time)); + if (motion && motion->enable && (motion_index == motion->motion_index || !motion->motion_index)) { + if (pv_data.dsc_data.time != motion->time) { + frame = dsc_time_to_frame(curr_time - motion->time); + dsc_frame = roundf(dsc_time_to_frame(pv_data.dsc_data.time - motion->time)); if (frame < dsc_frame) frame = dsc_frame; - v11 = curr_time > v56->time; + blend = curr_time > motion->time; } else frame = 0.0f; @@ -6320,27 +6310,6 @@ static bool x_pv_game_dsc_process(x_pv_game* a1, int64_t curr_time) { break; } - /*pv_db_pv_difficulty* v64 = 0i64; - pv_db_pv* v65 = a1->pv_game->data.pv; - pv_db_pv_difficulty* v66 = v65->difficulty[sub_14013C8C0()->difficulty].begin; - pv_db_pv* v67 = a1->pv_game->data.pv; - if (v66 == v67->difficulty[sub_14013C8C0()->difficulty].end) - return 1; - do { - if (v66->edition == sub_14013C8C0()->edition) - v64 = v66; - ++v66; - pv_db_pv* v68 = a1->pv_game->data.pv; - } while (v66 != v68->difficulty[sub_14013C8C0()->difficulty].end); - if (!v64) - return 1; - - int32_t motion_id = vector_pv_db_pv_motion_get_element_by_index_or_null(&v64->motion[a1->chara_id], v52)->id; - if (pv_game_data_get()->data.pv) { - pv_db_pv_motion* v76 = vector_pv_db_pv_motion_get_element_by_index_or_null(&v64->motion[a1->chara_id], v52); - motion_id = pv_game_data_get()->data.pv->get_chrmot_motion_id(rob_chr->chara_id, rob_chr->chara_index, v76); - }*/ - if (motion_index) { if (motion_id == -1) motion_id = rob_chr->get_rob_cmn_mottbl_motion_id(0); @@ -6351,7 +6320,7 @@ static bool x_pv_game_dsc_process(x_pv_game* a1, int64_t curr_time) { motion_id = rob_chr->get_rob_cmn_mottbl_motion_id(0); } - if (v11) + if (blend) blend_duration = 0.0f; else blend_duration /= a1->anim_frame_speed; @@ -6361,26 +6330,23 @@ static bool x_pv_game_dsc_process(x_pv_game* a1, int64_t curr_time) { set_motion.motion_id = motion_id; set_motion.frame = frame; set_motion.blend_duration = blend_duration; - set_motion.field_10 = v11; + 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 = v56 ? v56->time : pv_data.dsc_data.time; + set_motion.dsc_time = motion ? motion->time : pv_data.dsc_data.time; set_motion.dsc_frame = dsc_frame; - //a1->field_2C560[a1->chara_id] = true; - //a1->field_2C568[a1->chara_id] = set_motion; if (playdata->disp) { - bool v84 = rob_chr->set_motion_id(motion_id, frame, blend_duration, - v11, false, MOTION_BLEND_CROSS, aft_bone_data, aft_mot_db); + 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 (v84) + if (set) pv_expression_array_set_motion(pv_data.exp_file.hash_murmurhash, a1->chara_id, motion_id); - //if (!a1->pv_game->data.pv->disable_calc_motfrm_limit) - pv_game_dsc_data_set_motion_max_frame(a1, a1->chara_id, motion_index, v56 ? v56->time : 0); + pv_game_dsc_data_set_motion_max_frame(a1, a1->chara_id, motion_index, motion ? motion->time : 0); } else { playdata->set_motion.clear(); @@ -6474,11 +6440,7 @@ static bool x_pv_game_dsc_process(x_pv_game* a1, int64_t curr_time) { blend_duration /= a1->anim_frame_speed; - float_t blend_offset = 0.0f; - //if (a1->pv_game->data.pv->is_old_pv) - // blend_offset = 1.0f; - - rob_chr->set_eyelid_mottbl_motion_from_face(v115, blend_duration, -1.0f, blend_offset, aft_mot_db); + rob_chr->set_eyelid_mottbl_motion_from_face(v115, blend_duration, -1.0f, 0.0f, aft_mot_db); } break; case DSC_X_MOUTH_ANIM: { data_struct* aft_data = &data_list[DATA_AFT]; @@ -6547,15 +6509,8 @@ static bool x_pv_game_dsc_process(x_pv_game* a1, int64_t curr_time) { int32_t mottbl_index = mouth_anim_id_to_mottbl_index(mouth_anim_id); blend_duration /= a1->anim_frame_speed; - //if (a1->pv_game->data.field_2D090 && mottbl_index != 144) - // value = 0.0f; - - float_t blend_offset = 0.0f; - //if (a1->pv_game->data.pv->is_old_pv) - // blend_offset = 1.0f; - rob_chr->set_mouth_mottbl_motion(0, mottbl_index, value, - 0, blend_duration, 0.0f, 1.0f, -1, blend_offset, aft_mot_db); + 0, blend_duration, 0.0f, 1.0f, -1, 0.0f, aft_mot_db); } break; case DSC_X_HAND_ANIM: { data_struct* aft_data = &data_list[DATA_AFT]; @@ -6594,18 +6549,14 @@ static bool x_pv_game_dsc_process(x_pv_game* a1, int64_t curr_time) { int32_t mottbl_index = hand_anim_id_to_mottbl_index(hand_anim_id); blend_duration /= a1->anim_frame_speed; - float_t blend_offset = 0.0f; - //if (a1->pv_game->data.pv->is_old_pv) - // blend_offset = 1.0f; - switch (hand_index) { case 0: rob_chr->set_hand_l_mottbl_motion(0, mottbl_index, value, - 0, blend_duration, 0.0f, 1.0f, -1, blend_offset, aft_mot_db); + 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, blend_offset, aft_mot_db); + 0, blend_duration, 0.0f, 1.0f, -1, 0.0f, aft_mot_db); break; } } break; @@ -6645,12 +6596,8 @@ static bool x_pv_game_dsc_process(x_pv_game* a1, int64_t curr_time) { int32_t mottbl_index = look_anim_id_to_mottbl_index(look_anim_id); blend_duration /= a1->anim_frame_speed; - float_t blend_offset = 0.0f; - //if (a1->pv_game->data.pv->is_old_pv) - // blend_offset = 1.0f; - rob_chr->set_eyes_mottbl_motion(0, mottbl_index, value, - mottbl_index == 224 ? 1 : 0, blend_duration, 0.0f, 1.0f, -1, blend_offset, aft_mot_db); + mottbl_index == 224 ? 1 : 0, blend_duration, 0.0f, 1.0f, -1, 0.0f, aft_mot_db); return 1; } break; case DSC_X_EXPRESSION: { @@ -6689,16 +6636,8 @@ static bool x_pv_game_dsc_process(x_pv_game* a1, int64_t curr_time) { int32_t mottbl_index = expression_id_to_mottbl_index(expression_id); blend_duration /= a1->anim_frame_speed; - bool v168 = true; - //if (a1->has_perf_id && (a1->pv_game->data.pv->edit - 1) <= 1) - // v168 = false; - - float_t blend_offset = 0.0f; - //if (a1->pv_game->data.pv->is_old_pv) - // blend_offset = 1.0f; - 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, blend_offset, v168, aft_mot_db); + && mottbl_index <= 223 ? 1 : 0, blend_duration, 0.0f, 1.0f, -1, 0.0f, true, aft_mot_db); } break; case DSC_X_LOOK_CAMERA: { @@ -6735,42 +6674,14 @@ static bool x_pv_game_dsc_process(x_pv_game* a1, int64_t curr_time) { int32_t expression_id = (int32_t)data[0]; - float_t blend_duration = 0.0f; - //if (func == DSC_EDIT_EXPRESSION) - // blend_duration = (float_t)(int32_t)data[1] * 0.001f * 60.0f; - - int32_t v234 = -1; - //if (!a1->has_perf_id) - // v234 = data[1]; - rob_chara* rob_chr = playdata->rob_chr; if (!rob_chr) break; int32_t mottbl_index = expression_id_to_mottbl_index(expression_id); - blend_duration /= a1->anim_frame_speed; - - bool v237 = true; - //if (a1->has_perf_id) - // v237 = (a1->pv_game->data.pv->edit - 1) > 1; - - float_t blend_offset = 0.0f; - //if (a1->pv_game->data.pv->is_old_pv) - // blend_offset = 1.0f; rob_chr->set_face_mottbl_motion(0, mottbl_index, 1.0f, mottbl_index >= 214 - && mottbl_index <= 223 ? 1 : 0, blend_duration, 0.0f, 1.0f, -1, blend_offset, v237, aft_mot_db); - - /*if (!a1->has_perf_id) { - int32_t mottbl_index = mouth_anim_id_to_mottbl_index(v234); - - float_t value = 1.0f; - //if (a1->pv_game->data.field_2D090 && mottbl_index != 144) - // value = 0.0f; - - rob_chr->set_mouth_mottbl_motion(0, mottbl_index, value, 0, - a1->target_anim_fps * 0.1f, 0.0f, 1.0f, -1, offset, aft_mot_db); - }*/ + && mottbl_index <= 223 ? 1 : 0, 0.0f, 0.0f, 1.0f, -1, 0.0f, true, aft_mot_db); } break; case DSC_X_DUMMY: { @@ -6796,27 +6707,15 @@ static bool x_pv_game_dsc_process(x_pv_game* a1, int64_t curr_time) { x_pv_play_data* playdata = &a1->playdata[a1->chara_id]; int32_t mouth_anim_id = (int32_t)data[1]; - float_t blend_duration = 0.1f; - //if (func == DSC_EDIT_MOUTH_ANIM) - // blend_duration = (float_t)(int32_t)data[2] * 0.001f; rob_chara* rob_chr = playdata->rob_chr; if (!rob_chr) break; int32_t mottbl_index = mouth_anim_id_to_mottbl_index(mouth_anim_id); - blend_duration *= a1->target_anim_fps; - float_t value = 1.0f; - //if (a1->pv_game->data.field_2D090 && mottbl_index != 144) - // value = 0.0f; - - float_t blend_offset = 0.0f; - //if (a1->pv_game->data.pv->is_old_pv) - // blend_offset = 1.0f; - - rob_chr->set_mouth_mottbl_motion(0, mottbl_index, value, - 0, blend_duration, 0.0f, 1.0f, -1, blend_offset, aft_mot_db); + 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: { a1->chara_id = (int32_t)data[0]; @@ -6940,7 +6839,6 @@ static bool x_pv_game_dsc_process(x_pv_game* a1, int64_t curr_time) { else if (pv_data.pv_id == 826 && false) chara_index = rob_chara_array_get(a1->chara_id)->chara_index; - //chara_index chara_index = pv_db_pv::get_performer_chara(a1->pv_game->data.pv, a1->chara_id); chara_size_index = chara_init_data_get_chara_size_index(chara_index); } else if (chara_size == 2) @@ -6948,7 +6846,7 @@ static bool x_pv_game_dsc_process(x_pv_game* a1, int64_t curr_time) { 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/*a1->field_2C54C*/); + rob_chr->set_chara_size((float_t)chara_size / 1000.0f); break; } @@ -6985,9 +6883,9 @@ static bool x_pv_game_dsc_process(x_pv_game* a1, int64_t curr_time) { break; mat4_mult_vec3_trans(&a1->scene_rot_mat, &pos, &pos); - rob_chr->set_chara_pos_adjust(&pos); + rob_chr->set_chara_pos_adjust(pos); - if (rob_chara_check_for_ageageagain_module(rob_chr->chara_index, rob_chr->module_index)) { + 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); } @@ -7030,7 +6928,7 @@ static bool x_pv_game_dsc_process(x_pv_game* a1, int64_t curr_time) { if (!rob_chr) break; - rob_chr->item_equip->wind_strength = wind_strength_outer; + rob_chr->set_wind_strength(wind_strength_outer); } break; case DSC_X_OSAGE_STEP: { data_struct* aft_data = &data_list[DATA_AFT]; @@ -7046,7 +6944,7 @@ static bool x_pv_game_dsc_process(x_pv_game* a1, int64_t curr_time) { if (!rob_chr) break; - rob_chr->set_step(osage_step_outer); + rob_chr->set_osage_step(osage_step_outer); } break; case DSC_X_OSAGE_MV_CCL: { data_struct* aft_data = &data_list[DATA_AFT]; @@ -7670,8 +7568,7 @@ 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) { - task_stage_modern_info v14; - task_stage_modern_set_stage(&v14); + task_stage_modern_info().set_stage(); Glitter::glt_particle_manager->FreeScenes(); } @@ -8899,7 +8796,7 @@ static void x_pv_game_split_auth_3d_material_list(auth_3d_material_list& ml, play_control_size = max_def(play_control_size, ml.blend_color.a.max_frame); play_control_size = max_def(play_control_size, ml.blend_color.a.keys_vec.back().frame + 1.0f); } - + if (has_data[4]) { play_control_size = max_def(play_control_size, ml.emission.r.max_frame); play_control_size = max_def(play_control_size, ml.emission.r.keys_vec.back().frame + 1.0f); @@ -8919,9 +8816,9 @@ static void x_pv_game_split_auth_3d_material_list(auth_3d_material_list& ml, play_control_size = max_def(play_control_size, ml.emission.a.max_frame); play_control_size = max_def(play_control_size, ml.emission.a.keys_vec.back().frame + 1.0f); } - + size_t count = (size_t)(int32_t)play_control_size; - + if (has_data[0] && (ml.blend_color.r.ep_type_post == AUTH_3D_EP_CYCLE || ml.blend_color.r.ep_type_post == AUTH_3D_EP_CYCLE_OFFSET)) { size_t _count = (size_t)ml.blend_color.r.keys_vec.back().frame; @@ -8931,7 +8828,7 @@ static void x_pv_game_split_auth_3d_material_list(auth_3d_material_list& ml, count = _count + 1; } } - + if (has_data[1] && (ml.blend_color.g.ep_type_post == AUTH_3D_EP_CYCLE || ml.blend_color.g.ep_type_post == AUTH_3D_EP_CYCLE_OFFSET)) { size_t _count = (size_t)ml.blend_color.g.keys_vec.back().frame; @@ -8941,7 +8838,7 @@ static void x_pv_game_split_auth_3d_material_list(auth_3d_material_list& ml, count = _count + 1; } } - + if (has_data[2] && (ml.blend_color.b.ep_type_post == AUTH_3D_EP_CYCLE || ml.blend_color.b.ep_type_post == AUTH_3D_EP_CYCLE_OFFSET)) { size_t _count = (size_t)ml.blend_color.b.keys_vec.back().frame; @@ -8951,7 +8848,7 @@ static void x_pv_game_split_auth_3d_material_list(auth_3d_material_list& ml, count = _count + 1; } } - + if (has_data[3] && (ml.blend_color.a.ep_type_post == AUTH_3D_EP_CYCLE || ml.blend_color.a.ep_type_post == AUTH_3D_EP_CYCLE_OFFSET)) { size_t _count = (size_t)ml.blend_color.a.keys_vec.back().frame; @@ -8961,7 +8858,7 @@ static void x_pv_game_split_auth_3d_material_list(auth_3d_material_list& ml, count = _count + 1; } } - + if (has_data[4] && (ml.emission.r.ep_type_post == AUTH_3D_EP_CYCLE || ml.emission.r.ep_type_post == AUTH_3D_EP_CYCLE_OFFSET)) { size_t _count = (size_t)ml.emission.r.keys_vec.back().frame; @@ -8971,7 +8868,7 @@ static void x_pv_game_split_auth_3d_material_list(auth_3d_material_list& ml, count = _count + 1; } } - + if (has_data[5] && (ml.emission.g.ep_type_post == AUTH_3D_EP_CYCLE || ml.emission.g.ep_type_post == AUTH_3D_EP_CYCLE_OFFSET)) { size_t _count = (size_t)ml.emission.g.keys_vec.back().frame; @@ -8981,7 +8878,7 @@ static void x_pv_game_split_auth_3d_material_list(auth_3d_material_list& ml, count = _count + 1; } } - + if (has_data[6] && (ml.emission.b.ep_type_post == AUTH_3D_EP_CYCLE || ml.emission.b.ep_type_post == AUTH_3D_EP_CYCLE_OFFSET)) { size_t _count = (size_t)ml.emission.b.keys_vec.back().frame; @@ -8991,7 +8888,7 @@ static void x_pv_game_split_auth_3d_material_list(auth_3d_material_list& ml, count = _count + 1; } } - + if (has_data[7] && (ml.emission.a.ep_type_post == AUTH_3D_EP_CYCLE || ml.emission.a.ep_type_post == AUTH_3D_EP_CYCLE_OFFSET)) { size_t _count = (size_t)ml.emission.a.keys_vec.back().frame; diff --git a/src/ReDIVA/x_pv_game.hpp b/src/ReDIVA/x_pv_game.hpp index a51d7d73..d55e8932 100644 --- a/src/ReDIVA/x_pv_game.hpp +++ b/src/ReDIVA/x_pv_game.hpp @@ -111,7 +111,7 @@ struct x_pv_play_data_set_motion { int32_t motion_id; float_t frame; float_t blend_duration; - bool field_10; + bool blend; MotionBlendType blend_type; bool disable_eye_motion; int32_t motion_index;