diff --git a/src/CRE/Glitter/animation.cpp b/src/CRE/Glitter/animation.cpp index 16bb5366..f896b7c1 100644 --- a/src/CRE/Glitter/animation.cpp +++ b/src/CRE/Glitter/animation.cpp @@ -16,9 +16,8 @@ namespace Glitter { #if defined(CRE_DEV) void Animation::AddValue(GLT, float_t val, CurveTypeFlags flags) { - for (int32_t i = CURVE_TRANSLATION_X; - i <= CURVE_V_SCROLL_ALPHA_2ND; i++) { - if (~flags & (1 << (size_t)i)) + for (int32_t i = CURVE_TRANSLATION_X; i <= CURVE_V_SCROLL_ALPHA_2ND; i++) { + if (!(flags & (1 << (size_t)i))) continue; for (Curve*& j : curves) { diff --git a/src/CRE/Glitter/curve.cpp b/src/CRE/Glitter/curve.cpp index 0af3678b..5500cb39 100644 --- a/src/CRE/Glitter/curve.cpp +++ b/src/CRE/Glitter/curve.cpp @@ -63,7 +63,10 @@ namespace Glitter { end_time = (float_t)this->end_time; if (repeat && (start_time > frame || frame >= end_time)) { float_t t = (frame - start_time) / (end_time - start_time); - t = t <= 0.0f ? (float_t)(int32_t)t - 1.0f : (float_t)(int32_t)t; + if (t > 0.0f) + t = (float_t)(int32_t)t; + else if (t < 0.0f) + t = (float_t)(int32_t)t - 1.0f; frame -= t * (end_time - start_time); } @@ -145,7 +148,7 @@ namespace Glitter { float_t Curve::F2Randomize(GLT, float_t value, Random* random) { float_t rand; - if (~flags & CURVE_RANDOM_RANGE) + if (!(flags & CURVE_RANDOM_RANGE)) return value; rand = random->F2GetFloat(GLT_VAL, flags & CURVE_RANDOM_RANGE_NEGATE @@ -160,7 +163,7 @@ namespace Glitter { } float_t Curve::F2RandomizeKey(GLT, Curve::Key* key, Random* random) { - if (~flags & CURVE_KEY_RANDOM_RANGE) + if (!(flags & CURVE_KEY_RANDOM_RANGE)) return key->value; float_t rand = random->F2GetFloat(GLT_VAL, flags & CURVE_RANDOM_RANGE_NEGATE @@ -208,7 +211,7 @@ namespace Glitter { void Curve::FitKeysIntoCurve(GLT) { size_t count = keys.size(); keys_rev = {}; - if (~flags & CURVE_BAKED) { + if (!(flags & CURVE_BAKED)) { keys_rev.insert(keys_rev.end(), keys.begin(), keys.end()); return; } @@ -219,7 +222,7 @@ namespace Glitter { } bool curve_baked_half = false; - if (type == Glitter::F2 || (type == Glitter::X && ~flags & CURVE_BAKED_FULL)) + if (type == Glitter::F2 || (type == Glitter::X && !(flags & CURVE_BAKED_FULL))) curve_baked_half = true; const uint8_t step = curve_baked_half ? 2 : 1; @@ -413,13 +416,13 @@ namespace Glitter { keys.push_back(keys_rev.data()[0]); else if (keys_rev.size() < 1) return; - else if (~flags & CURVE_BAKED) { + else if (!(flags & CURVE_BAKED)) { keys.insert(keys.end(), keys_rev.begin(), keys_rev.end()); return; } bool curve_baked_half = false; - if (GLT_VAL == Glitter::F2 || (GLT_VAL == Glitter::X && ~flags & CURVE_BAKED_FULL)) + if (GLT_VAL == Glitter::F2 || (GLT_VAL == Glitter::X && !(flags & CURVE_BAKED_FULL))) curve_baked_half = true; ssize_t keys_count = keys_rev.size(); @@ -528,7 +531,10 @@ namespace Glitter { end_time = (float_t)this->end_time; if (repeat && (start_time > frame || frame >= end_time)) { float_t t = (frame - start_time) / (end_time - start_time); - t = t <= 0.0f ? (float_t)(int32_t)t - 1.0f : (float_t)(int32_t)t; + if (t > 0.0f) + t = (float_t)(int32_t)t; + else if (t < 0.0f) + t = (float_t)(int32_t)t - 1.0f; frame -= t * (end_time - start_time); } @@ -546,7 +552,7 @@ namespace Glitter { key_index = keys_count - 1; else if (frame > start_time) { key_index = (size_t)frame - this->start_time; - if (~flags & CURVE_BAKED_FULL) + if (!(flags & CURVE_BAKED_FULL)) key_index /= 2; if (key_index >= keys_count) @@ -608,7 +614,7 @@ namespace Glitter { } float_t Curve::XRandomize(float_t value, Random* random) { - if (~flags & CURVE_RANDOM_RANGE) + if (!(flags & CURVE_RANDOM_RANGE)) return value; float_t rand = random->XGetFloat(flags & CURVE_RANDOM_RANGE_NEGATE @@ -620,7 +626,7 @@ namespace Glitter { } float_t Curve::XRandomizeKey(Curve::Key* key, Random* random) { - if (~flags & CURVE_KEY_RANDOM_RANGE) + if (!(flags & CURVE_KEY_RANDOM_RANGE)) return key->value; float_t rand = random->XGetFloat(flags & CURVE_RANDOM_RANGE_NEGATE diff --git a/src/CRE/Glitter/emitter_inst.cpp b/src/CRE/Glitter/emitter_inst.cpp index 979963d3..7ac696de 100644 --- a/src/CRE/Glitter/emitter_inst.cpp +++ b/src/CRE/Glitter/emitter_inst.cpp @@ -176,7 +176,7 @@ namespace Glitter { return; } - if (~flags & EMITTER_INST_ENDED) + if (!(flags & EMITTER_INST_ENDED)) if (this->emission == EMITTER_EMISSION_ON_TIMER) { if (emission_timer >= 0.0f || emission_interval >= 0.0f) { emission_timer -= delta_frame; @@ -289,7 +289,7 @@ namespace Glitter { } bool F2EmitterInst::HasEnded(bool a2) { - if (~flags & EMITTER_INST_ENDED) + if (!(flags & EMITTER_INST_ENDED)) return false; else if (!a2) return true; @@ -542,7 +542,7 @@ namespace Glitter { emission_timer -= vec3::distance(trans, trans_prev); } - if (~flags & EMITTER_INST_HAS_DISTANCE) + if (!(flags & EMITTER_INST_HAS_DISTANCE)) enum_or(flags, EMITTER_INST_HAS_DISTANCE); } @@ -660,7 +660,7 @@ namespace Glitter { return; } - if (~flags & EMITTER_INST_ENDED) + if (!(flags & EMITTER_INST_ENDED)) if (this->emission == EMITTER_EMISSION_ON_TIMER) { if (data.timer == EMITTER_TIMER_BY_DISTANCE) { if (emission_timer <= 0.0f || emission_interval >= 0.0f) @@ -789,7 +789,7 @@ namespace Glitter { } bool XEmitterInst::HasEnded(bool a2) { - if (~flags & EMITTER_INST_ENDED) + if (!(flags & EMITTER_INST_ENDED)) return false; else if (!a2) return true; diff --git a/src/CRE/Glitter/file_writer.cpp b/src/CRE/Glitter/file_writer.cpp index d10a9ce0..a2e0ec5d 100644 --- a/src/CRE/Glitter/file_writer.cpp +++ b/src/CRE/Glitter/file_writer.cpp @@ -426,7 +426,7 @@ namespace Glitter { e.vec.push_back(ee); l += o = 4; - if (~eff->data.flags & EFFECT_LOCAL && ext_anim) + if (!(eff->data.flags & EFFECT_LOCAL && ext_anim)) if (ext_anim->flags & EFFECT_EXT_ANIM_CHARA_ANIM) { ee = { 0, 1, 12, 1 }; ee.append(0, 3, ENRS_DWORD); @@ -1019,7 +1019,7 @@ namespace Glitter { }; for (int32_t i = CURVE_TRANSLATION_X; i <= CURVE_V_SCROLL_ALPHA_2ND; i++) { - if (~flags & (1 << (size_t)order[i])) + if (!(flags & (1 << (size_t)order[i]))) continue; for (Curve*& j : anim->curves) { diff --git a/src/CRE/Glitter/particle_inst.cpp b/src/CRE/Glitter/particle_inst.cpp index 13c2e3ff..81a6ec02 100644 --- a/src/CRE/Glitter/particle_inst.cpp +++ b/src/CRE/Glitter/particle_inst.cpp @@ -410,12 +410,12 @@ namespace Glitter { } bool F2ParticleInst::HasEnded(bool a2) { - if (~data.flags & PARTICLE_INST_ENDED) + if (!(data.flags & PARTICLE_INST_ENDED)) return false; else if (!a2) return true; - if (~data.flags & PARTICLE_INST_NO_CHILD || data.parent) { + if (!(data.flags & PARTICLE_INST_NO_CHILD) || data.parent) { if (data.render_group && data.render_group->ctrl > 0) return false; return true; @@ -925,12 +925,12 @@ namespace Glitter { } bool XParticleInst::HasEnded(bool a2) { - if (~data.flags & PARTICLE_INST_ENDED) + if (!(data.flags & PARTICLE_INST_ENDED)) return false; else if (!a2) return true; - if (~data.flags & PARTICLE_INST_NO_CHILD || data.parent) { + if (!(data.flags & PARTICLE_INST_NO_CHILD) || data.parent) { if (data.render_group && data.render_group->ctrl > 0) return false; return true; diff --git a/src/CRE/Glitter/particle_manager.cpp b/src/CRE/Glitter/particle_manager.cpp index 3973d78b..1d03ddc9 100644 --- a/src/CRE/Glitter/particle_manager.cpp +++ b/src/CRE/Glitter/particle_manager.cpp @@ -49,7 +49,7 @@ namespace Glitter { enum_and(flags, ~PARTICLE_MANAGER_READ_FILES); } - if (~flags & PARTICLE_MANAGER_PAUSE) { + if (!(flags & PARTICLE_MANAGER_PAUSE)) { if (frame_rate) delta_frame = frame_rate->GetDeltaFrame(); else @@ -120,7 +120,7 @@ namespace Glitter { bool local = false; for (std::vector::iterator i = scenes.begin(); i != scenes.end();) { Scene* scene = *i; - if (~scene->flags & SCENE_ENDED) { + if (!(scene->flags & SCENE_ENDED)) { if (!local && scene->CanDisp(DISP_LOCAL, true)) local = true; i++; @@ -244,7 +244,7 @@ namespace Glitter { i = scenes.erase(i); } else if (scene->type == Glitter::X && scene->flags & SCENE_ENDED - || ~scene->flags & SCENE_EDITOR) { + || !(scene->flags & SCENE_EDITOR)) { float_t delta_frame; if (scene->frame_rate) delta_frame = scene->frame_rate->GetDeltaFrame(); @@ -317,7 +317,7 @@ namespace Glitter { if (free) { #if defined(CRE_DEV) - if (~scene->flags & SCENE_ENDED) { + if (!(scene->flags & SCENE_ENDED)) { enum_or(scene->flags, SCENE_ENDED); scene->fade_frame_left = scene->fade_frame; } @@ -454,7 +454,7 @@ namespace Glitter { } SceneCounter GltParticleManager::GetSceneCounter(uint8_t index) { - if (scene_load_counter + 1 < 0xFFFFFF && (~flags & PARTICLE_MANAGER_RESET_SCENE_COUNTER)) { + if (scene_load_counter + 1 < 0xFFFFFF && !(flags & PARTICLE_MANAGER_RESET_SCENE_COUNTER)) { scene_load_counter++; return SceneCounter(index, scene_load_counter); } diff --git a/src/CRE/Glitter/render_element.cpp b/src/CRE/Glitter/render_element.cpp index b8a60f9c..4222351e 100644 --- a/src/CRE/Glitter/render_element.cpp +++ b/src/CRE/Glitter/render_element.cpp @@ -53,7 +53,7 @@ namespace Glitter { vec3 position = 0.0f; emit_inst->InitMesh(GLT_VAL, index, scale, position, direction, random); - if (~ptcl_inst_data->data.flags & PARTICLE_EMITTER_LOCAL) + if (!(ptcl_inst_data->data.flags & PARTICLE_EMITTER_LOCAL)) mat4_mult_vec3(&emit_inst->mat_rot, &position, &position); base_translation += position; @@ -63,7 +63,7 @@ namespace Glitter { direction = vec3::normalize(direction + random->F2GetVec3(GLT_VAL, ptcl_inst_data->data.direction_random)); - if (~ptcl_inst_data->data.flags & PARTICLE_EMITTER_LOCAL) + if (!(ptcl_inst_data->data.flags & PARTICLE_EMITTER_LOCAL)) mat4_mult_vec3(&emit_inst->mat_rot, &direction, &direction); base_direction = direction; this->direction = direction; @@ -96,7 +96,7 @@ namespace Glitter { vec3 position = 0.0f; emit_inst->InitMesh(index, scale, position, direction, random); - if (~ptcl_inst_data->data.flags & PARTICLE_EMITTER_LOCAL) + if (!(ptcl_inst_data->data.flags & PARTICLE_EMITTER_LOCAL)) mat4_mult_vec3(&emit_inst->mat_rot, &position, &position); base_translation += position; @@ -106,7 +106,7 @@ namespace Glitter { direction = vec3::normalize(direction + random->XGetVec3(ptcl_inst_data->data.direction_random)); - if (~ptcl_inst_data->data.flags & PARTICLE_EMITTER_LOCAL) + if (!(ptcl_inst_data->data.flags & PARTICLE_EMITTER_LOCAL)) mat4_mult_vec3(&emit_inst->mat_rot, &direction, &direction); base_direction = direction; this->direction = direction; diff --git a/src/CRE/Glitter/render_group.cpp b/src/CRE/Glitter/render_group.cpp index dd5609ac..d66cc706 100644 --- a/src/CRE/Glitter/render_group.cpp +++ b/src/CRE/Glitter/render_group.cpp @@ -351,7 +351,7 @@ namespace Glitter { vec3 axis; float_t angle; axis_angle_from_vectors(&axis, &angle, &vec1, &vec2); - mat4_mult_axis_angle(&mat, &mat, &axis, angle); + mat4_mult_axis_angle(&mat, &axis, angle, &mat); } else mat4_rotate_z((float_t)M_PI, &mat); @@ -375,7 +375,7 @@ namespace Glitter { vec3 axis; float_t angle; axis_angle_from_vectors(&axis, &angle, &vec1, &vec2); - mat4_mult_axis_angle(&mat, &mat, &axis, angle); + mat4_mult_axis_angle(&mat, &axis, angle, &mat); } return mat; } @@ -740,7 +740,7 @@ namespace Glitter { axis_angle_from_vectors(&axis, &angle, &vec1, &vec2); mat4 mat; - mat4_mult_axis_angle(&mat4_identity, &mat, &axis, angle); + mat4_mult_axis_angle(&mat4_identity, &axis, angle, &mat); return mat; } @@ -760,7 +760,7 @@ namespace Glitter { axis_angle_from_vectors(&axis, &angle, &vec1, &vec2); mat4 mat; - mat4_mult_axis_angle(&mat4_identity, &mat, &axis, angle); + mat4_mult_axis_angle(&mat4_identity, &axis, angle, &mat); return mat; } @@ -782,7 +782,7 @@ namespace Glitter { axis_angle_from_vectors(&axis, &angle, &vec1, &vec2); mat4 mat; - mat4_mult_axis_angle(&mat4_identity, &mat, &axis, angle); + mat4_mult_axis_angle(&mat4_identity, &axis, angle, &mat); return mat; } @@ -802,7 +802,7 @@ namespace Glitter { axis_angle_from_vectors(&axis, &angle, &vec1, &vec2); mat4 mat; - mat4_mult_axis_angle(&mat4_identity, &mat, &axis, angle); + mat4_mult_axis_angle(&mat4_identity, &axis, angle, &mat); return mat; } } diff --git a/src/CRE/Glitter/render_scene.cpp b/src/CRE/Glitter/render_scene.cpp index 511983e7..342e96c1 100644 --- a/src/CRE/Glitter/render_scene.cpp +++ b/src/CRE/Glitter/render_scene.cpp @@ -2181,7 +2181,7 @@ namespace Glitter { else uniform_value[U_ALPHA_BLEND] = rend_group->disp_type ? 2 : 0; - if (~rend_group->flags & PARTICLE_DEPTH_TEST) + if (!(rend_group->flags & PARTICLE_DEPTH_TEST)) gl_state_enable_depth_test(); else gl_state_disable_depth_test(); diff --git a/src/CRE/Glitter/scene.cpp b/src/CRE/Glitter/scene.cpp index 8683e1d2..9000bea2 100644 --- a/src/CRE/Glitter/scene.cpp +++ b/src/CRE/Glitter/scene.cpp @@ -34,7 +34,7 @@ namespace Glitter { } bool Scene::Copy(Glitter::EffectInst* eff_inst, Glitter::Scene* dst) { - if (~flags & SCENE_FLAG_3) + if (!(flags & SCENE_FLAG_3)) return flags; for (SceneEffect& i : effects) diff --git a/src/CRE/auth_3d.cpp b/src/CRE/auth_3d.cpp index 3b6ce5b5..c7e047d4 100644 --- a/src/CRE/auth_3d.cpp +++ b/src/CRE/auth_3d.cpp @@ -166,12 +166,12 @@ static void auth_3d_data_struct_unload_category(auth_3d_data_struct* auth_3d_dat static void auth_3d_data_struct_unload_category( auth_3d_data_struct* auth_3d_data, uint32_t category_hash); -static void auth_3d_farc_free_data(auth_3d_farc* a3da_farc); static void auth_3d_farc_load(auth_3d_farc* a3da_farc, const char* mdata_dir); static void auth_3d_farc_load_modern(auth_3d_farc* a3da_farc, void* data); static void auth_3d_farc_read_file(auth_3d_farc* a3da_farc, const char* mdata_dir); static void auth_3d_farc_read_file_modern(auth_3d_farc* a3da_farc, void* data); static bool auth_3d_farc_read_func(auth_3d_farc* a3da_farc, const void* data, size_t size); +static void auth_3d_farc_reset(auth_3d_farc* a3da_farc); static void auth_3d_farc_unload(auth_3d_farc* a3da_farc); static void auth_3d_uid_file_load(auth_3d_uid_file* uid_file); @@ -1183,12 +1183,12 @@ float_t auth_3d_key::interpolate(float_t frame) { return value_interp; } -inline void auth_3d_key::reset() { - type = (auth_3d_key_type)0; +void auth_3d_key::reset() { + type = AUTH_3D_KEY_NONE; value = 0.0f; max_frame = 0.0f; - ep_type_pre = (auth_3d_ep_type)0; - ep_type_post = (auth_3d_ep_type)0; + ep_type_pre = AUTH_3D_EP_NONE; + ep_type_post = AUTH_3D_EP_NONE; frame_delta = 0.0f; value_delta = 0.0f; keys_vec.clear(); @@ -2304,22 +2304,22 @@ bool Auth3dTestTask::Ctrl() { if (field_1EC == 1 && !object_storage_load_obj_set_check_not_read(effcmn_obj_set)) field_1EC = 4; - if (field_1D4 == 1 && auth_3d_data_check_id_loaded(&auth_3d_id)) + if (field_1D4 == 1 && auth_3d_data_check_id_loaded(auth_3d_id)) field_1D4 = 2; if (field_1D4 == 2) { - auth_3d_data_set_enable(&auth_3d_id, true); - auth_3d_data_set_paused(&auth_3d_id, false); - auth_3d_data_set_repeat(&auth_3d_id, repeat); - auth_3d_data_set_left_right_reverse(&auth_3d_id, left_right_reverse); + auth_3d_data_set_enable(auth_3d_id, true); + auth_3d_data_set_paused(auth_3d_id, false); + auth_3d_data_set_repeat(auth_3d_id, repeat); + auth_3d_data_set_left_right_reverse(auth_3d_id, left_right_reverse); field_1D4 = 4; } - if (auth_3d_data_check_id_not_empty(&auth_3d_id)) { + if (auth_3d_data_check_id_not_empty(auth_3d_id)) { mat4 mat; mat4_translate(&trans_value, &mat); mat4_rotate_y_mult(&mat, rot_y_value * DEG_TO_RAD_FLOAT, &mat); - auth_3d_data_set_mat(&auth_3d_id, &mat); + auth_3d_data_set_mat(auth_3d_id, &mat); } return false; } @@ -2347,10 +2347,10 @@ void auth_3d_data_init() { auth_3d_data = new auth_3d_data_struct; } -bool auth_3d_data_check_id_not_empty(int32_t* id) { - if (*id >= 0 && ((*id & 0x7FFF) < AUTH_3D_DATA_COUNT)) { - auth_3d* auth = &auth_3d_data->data[*id & 0x7FFF]; - if (auth->id == *id) +bool auth_3d_data_check_id_not_empty(const int32_t& id) { + if (id >= 0 && ((id & 0x7FFF) < AUTH_3D_DATA_COUNT)) { + auth_3d* auth = &auth_3d_data->data[id & 0x7FFF]; + if (auth->id == id) return auth->id != -1; } return false; @@ -2364,25 +2364,25 @@ bool auth_3d_data_check_category_loaded(uint32_t category_hash) { return auth_3d_data_struct_check_category_loaded(auth_3d_data, category_hash); } -bool auth_3d_data_check_id_loading(int32_t* id) { - if (*id >= 0 && ((*id & 0x7FFF) < AUTH_3D_DATA_COUNT)) { - auth_3d* auth = &auth_3d_data->data[*id & 0x7FFF]; - if (auth->id == *id) +bool auth_3d_data_check_id_loading(const int32_t& id) { + if (id >= 0 && ((id & 0x7FFF) < AUTH_3D_DATA_COUNT)) { + auth_3d* auth = &auth_3d_data->data[id & 0x7FFF]; + if (auth->id == id) return auth->state == 1; } return false; } -bool auth_3d_data_check_id_loaded(int32_t* id) { - if (*id >= 0 && ((*id & 0x7FFF) < AUTH_3D_DATA_COUNT)) { - auth_3d* auth = &auth_3d_data->data[*id & 0x7FFF]; - if (auth->id == *id) +bool auth_3d_data_check_id_loaded(const int32_t& id) { + if (id >= 0 && ((id & 0x7FFF) < AUTH_3D_DATA_COUNT)) { + auth_3d* auth = &auth_3d_data->data[id & 0x7FFF]; + if (auth->id == id) return auth->state == 2; } return true; } -auth_3d* auth_3d_data_get_auth_3d(int32_t id) { +auth_3d* auth_3d_data_get_auth_3d(const int32_t& id) { int32_t index = 0; while (auth_3d_data->data[index].id != id) if (++index >= AUTH_3D_DATA_COUNT) @@ -2487,14 +2487,14 @@ int32_t auth_3d_data_get_auth_3d_id(uint32_t file_name_hash, uint32_t object_has return -1; } -int32_t auth_3d_data_get_chara_id(int32_t id) { +int32_t auth_3d_data_get_chara_id(const int32_t& id) { auth_3d* auth = auth_3d_data_get_auth_3d(id); if (auth) return auth->chara_id; return -1; } -mat4* auth_3d_data_get_auth_3d_object_mat(int32_t id, size_t index, bool hrc, mat4* mat) { +mat4* auth_3d_data_get_auth_3d_object_mat(const int32_t& id, size_t index, bool hrc, mat4* mat) { if (id < 0 || (id & 0x7FFF) >= AUTH_3D_DATA_COUNT) return 0; @@ -2512,91 +2512,91 @@ mat4* auth_3d_data_get_auth_3d_object_mat(int32_t id, size_t index, bool hrc, ma return mat; } -bool auth_3d_data_get_enable(int32_t* id) { - if (*id >= 0 && ((*id & 0x7FFF) < AUTH_3D_DATA_COUNT)) { - auth_3d* auth = &auth_3d_data->data[*id & 0x7FFF]; - if (auth->id == *id) +bool auth_3d_data_get_enable(const int32_t& id) { + if (id >= 0 && ((id & 0x7FFF) < AUTH_3D_DATA_COUNT)) { + auth_3d* auth = &auth_3d_data->data[id & 0x7FFF]; + if (auth->id == id) return auth->enable; } return false; } -bool auth_3d_data_get_ended(int32_t* id) { - if (*id >= 0 && ((*id & 0x7FFF) < AUTH_3D_DATA_COUNT)) { - auth_3d* auth = &auth_3d_data->data[*id & 0x7FFF]; - if (auth->id == *id) +bool auth_3d_data_get_ended(const int32_t& id) { + if (id >= 0 && ((id & 0x7FFF) < AUTH_3D_DATA_COUNT)) { + auth_3d* auth = &auth_3d_data->data[id & 0x7FFF]; + if (auth->id == id) return auth->ended; } return true; } -float_t auth_3d_data_get_frame(int32_t* id) { - if (*id >= 0 && ((*id & 0x7FFF) < AUTH_3D_DATA_COUNT)) { - auth_3d* auth = &auth_3d_data->data[*id & 0x7FFF]; - if (auth->id == *id) +float_t auth_3d_data_get_frame(const int32_t& id) { + if (id >= 0 && ((id & 0x7FFF) < AUTH_3D_DATA_COUNT)) { + auth_3d* auth = &auth_3d_data->data[id & 0x7FFF]; + if (auth->id == id) return auth->frame; } return 0.0f; } -float_t auth_3d_data_get_frame_offset(int32_t* id) { - if (*id >= 0 && ((*id & 0x7FFF) < AUTH_3D_DATA_COUNT)) { - auth_3d* auth = &auth_3d_data->data[*id & 0x7FFF]; - if (auth->id == *id) +float_t auth_3d_data_get_frame_offset(const int32_t& id) { + if (id >= 0 && ((id & 0x7FFF) < AUTH_3D_DATA_COUNT)) { + auth_3d* auth = &auth_3d_data->data[id & 0x7FFF]; + if (auth->id == id) return auth->frame_offset; } return 0.0f; } -float_t auth_3d_data_get_last_frame(int32_t* id) { - if (*id >= 0 && ((*id & 0x7FFF) < AUTH_3D_DATA_COUNT)) { - auth_3d* auth = &auth_3d_data->data[*id & 0x7FFF]; - if (auth->id == *id) +float_t auth_3d_data_get_last_frame(const int32_t& id) { + if (id >= 0 && ((id & 0x7FFF) < AUTH_3D_DATA_COUNT)) { + auth_3d* auth = &auth_3d_data->data[id & 0x7FFF]; + if (auth->id == id) return auth->last_frame; } return 0.0f; } -bool auth_3d_data_get_left_right_reverse(int32_t* id) { - if (*id >= 0 && ((*id & 0x7FFF) < AUTH_3D_DATA_COUNT)) { - auth_3d* auth = &auth_3d_data->data[*id & 0x7FFF]; - if (auth->id == *id) +bool auth_3d_data_get_left_right_reverse(const int32_t& id) { + if (id >= 0 && ((id & 0x7FFF) < AUTH_3D_DATA_COUNT)) { + auth_3d* auth = &auth_3d_data->data[id & 0x7FFF]; + if (auth->id == id) return auth->left_right_reverse; } return false; } -float_t auth_3d_data_get_play_control_begin(int32_t* id) { - if (*id >= 0 && ((*id & 0x7FFF) < AUTH_3D_DATA_COUNT)) { - auth_3d* auth = &auth_3d_data->data[*id & 0x7FFF]; - if (auth->id == *id) +float_t auth_3d_data_get_play_control_begin(const int32_t& id) { + if (id >= 0 && ((id & 0x7FFF) < AUTH_3D_DATA_COUNT)) { + auth_3d* auth = &auth_3d_data->data[id & 0x7FFF]; + if (auth->id == id) return auth->play_control.begin; } return 0.0f; } -float_t auth_3d_data_get_play_control_size(int32_t* id) { - if (*id >= 0 && ((*id & 0x7FFF) < AUTH_3D_DATA_COUNT)) { - auth_3d* auth = &auth_3d_data->data[*id & 0x7FFF]; - if (auth->id == *id) +float_t auth_3d_data_get_play_control_size(const int32_t& id) { + if (id >= 0 && ((id & 0x7FFF) < AUTH_3D_DATA_COUNT)) { + auth_3d* auth = &auth_3d_data->data[id & 0x7FFF]; + if (auth->id == id) return auth->play_control.size; } return 0.0f; } -bool auth_3d_data_get_paused(int32_t* id) { - if (*id >= 0 && ((*id & 0x7FFF) < AUTH_3D_DATA_COUNT)) { - auth_3d* auth = &auth_3d_data->data[*id & 0x7FFF]; - if (auth->id == *id) +bool auth_3d_data_get_paused(const int32_t& id) { + if (id >= 0 && ((id & 0x7FFF) < AUTH_3D_DATA_COUNT)) { + auth_3d* auth = &auth_3d_data->data[id & 0x7FFF]; + if (auth->id == id) return auth->paused; } return false; } -bool auth_3d_data_get_repeat(int32_t* id) { - if (*id >= 0 && ((*id & 0x7FFF) < AUTH_3D_DATA_COUNT)) { - auth_3d* auth = &auth_3d_data->data[*id & 0x7FFF]; - if (auth->id == *id) +bool auth_3d_data_get_repeat(const int32_t& id) { + if (id >= 0 && ((id & 0x7FFF) < AUTH_3D_DATA_COUNT)) { + auth_3d* auth = &auth_3d_data->data[id & 0x7FFF]; + if (auth->id == id) return auth->repeat; } return false; @@ -2676,10 +2676,10 @@ void auth_3d_data_get_obj_sets_from_category(std::string& name, std::vector= 0 && ((*id & 0x7FFF) < AUTH_3D_DATA_COUNT)) { - auth_3d* auth = &auth_3d_data->data[*id & 0x7FFF]; - if (auth->id == *id) +int32_t auth_3d_data_get_uid(const int32_t& id) { + if (id >= 0 && ((id & 0x7FFF) < AUTH_3D_DATA_COUNT)) { + auth_3d* auth = &auth_3d_data->data[id & 0x7FFF]; + if (auth->id == id) return auth->uid; } return -1; @@ -2777,68 +2777,68 @@ int32_t auth_3d_data_load_uid(int32_t uid, auth_3d_database* auth_3d_db) { return id; } -void auth_3d_data_read_file(int32_t* id, auth_3d_database* auth_3d_db) { - if (*id >= 0 && ((*id & 0x7FFF) < AUTH_3D_DATA_COUNT)) { - auth_3d* auth = &auth_3d_data->data[*id & 0x7FFF]; - if (auth && auth->id == *id) +void auth_3d_data_read_file(const int32_t& id, auth_3d_database* auth_3d_db) { + if (id >= 0 && ((id & 0x7FFF) < AUTH_3D_DATA_COUNT)) { + auth_3d* auth = &auth_3d_data->data[id & 0x7FFF]; + if (auth && auth->id == id) auth_3d_read_file(auth, auth_3d_db); } } -void auth_3d_data_read_file_modern(int32_t* id) { - if (*id >= 0 && ((*id & 0x7FFF) < AUTH_3D_DATA_COUNT)) { - auth_3d* auth = &auth_3d_data->data[*id & 0x7FFF]; - if (auth && auth->id == *id) +void auth_3d_data_read_file_modern(const int32_t& id) { + if (id >= 0 && ((id & 0x7FFF) < AUTH_3D_DATA_COUNT)) { + auth_3d* auth = &auth_3d_data->data[id & 0x7FFF]; + if (auth && auth->id == id) auth_3d_read_file_modern(auth); } } -void auth_3d_data_set_camera_root_update(int32_t* id, bool value) { - if (*id >= 0 && ((*id & 0x7FFF) < AUTH_3D_DATA_COUNT)) { - auth_3d* auth = &auth_3d_data->data[*id & 0x7FFF]; - if (auth->id == *id) +void auth_3d_data_set_camera_root_update(const int32_t& id, bool value) { + if (id >= 0 && ((id & 0x7FFF) < AUTH_3D_DATA_COUNT)) { + auth_3d* auth = &auth_3d_data->data[id & 0x7FFF]; + if (auth->id == id) auth->camera_root_update = value; } } -void auth_3d_data_set_chara_id(int32_t* id, int32_t value) { - if (*id >= 0 && ((*id & 0x7FFF) < AUTH_3D_DATA_COUNT)) { - auth_3d* auth = &auth_3d_data->data[*id & 0x7FFF]; - if (auth->id == *id) +void auth_3d_data_set_chara_id(const int32_t& id, int32_t value) { + if (id >= 0 && ((id & 0x7FFF) < AUTH_3D_DATA_COUNT)) { + auth_3d* auth = &auth_3d_data->data[id & 0x7FFF]; + if (auth->id == id) auth->chara_id = value; } } -void auth_3d_data_set_chara_item(int32_t* id, bool value) { - if (*id >= 0 && ((*id & 0x7FFF) < AUTH_3D_DATA_COUNT)) { - auth_3d* auth = &auth_3d_data->data[*id & 0x7FFF]; - if (auth->id == *id) +void auth_3d_data_set_chara_item(const int32_t& id, bool value) { + if (id >= 0 && ((id & 0x7FFF) < AUTH_3D_DATA_COUNT)) { + auth_3d* auth = &auth_3d_data->data[id & 0x7FFF]; + if (auth->id == id) auth->chara_item = value; } } -void auth_3d_data_set_draw_task_flags_alpha(int32_t* id, draw_task_flags draw_task_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) { +void auth_3d_data_set_draw_task_flags_alpha(const int32_t& id, draw_task_flags draw_task_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->draw_task_flags = draw_task_flags; auth->alpha = alpha; } } } -void auth_3d_data_set_enable(int32_t* id, bool value) { - if (*id >= 0 && ((*id & 0x7FFF) < AUTH_3D_DATA_COUNT)) { - auth_3d* auth = &auth_3d_data->data[*id & 0x7FFF]; - if (auth->id == *id) +void auth_3d_data_set_enable(const int32_t& id, bool value) { + if (id >= 0 && ((id & 0x7FFF) < AUTH_3D_DATA_COUNT)) { + auth_3d* auth = &auth_3d_data->data[id & 0x7FFF]; + if (auth->id == id) auth->enable = value; } } -void auth_3d_data_set_frame_rate(int32_t* id, FrameRateControl* value) { - if (*id >= 0 && ((*id & 0x7FFF) < AUTH_3D_DATA_COUNT)) { - auth_3d* auth = &auth_3d_data->data[*id & 0x7FFF]; - if (auth->id == *id) +void auth_3d_data_set_frame_rate(const int32_t& id, FrameRateControl* value) { + if (id >= 0 && ((id & 0x7FFF) < AUTH_3D_DATA_COUNT)) { + auth_3d* auth = &auth_3d_data->data[id & 0x7FFF]; + if (auth->id == id) if (value) auth->frame_rate = value; else @@ -2846,86 +2846,86 @@ void auth_3d_data_set_frame_rate(int32_t* id, FrameRateControl* value) { } } -void auth_3d_data_set_last_frame(int32_t* id, float_t value) { - if (*id >= 0 && ((*id & 0x7FFF) < AUTH_3D_DATA_COUNT)) { - auth_3d* auth = &auth_3d_data->data[*id & 0x7FFF]; - if (auth->id == *id) +void auth_3d_data_set_last_frame(const int32_t& id, float_t value) { + if (id >= 0 && ((id & 0x7FFF) < AUTH_3D_DATA_COUNT)) { + auth_3d* auth = &auth_3d_data->data[id & 0x7FFF]; + if (auth->id == id) auth->last_frame = value; } } -void auth_3d_data_set_left_right_reverse(int32_t* id, bool value) { - if (*id >= 0 && ((*id & 0x7FFF) < AUTH_3D_DATA_COUNT)) { - auth_3d* auth = &auth_3d_data->data[*id & 0x7FFF]; - if (auth->id == *id) +void auth_3d_data_set_left_right_reverse(const int32_t& id, bool value) { + if (id >= 0 && ((id & 0x7FFF) < AUTH_3D_DATA_COUNT)) { + auth_3d* auth = &auth_3d_data->data[id & 0x7FFF]; + if (auth->id == id) auth->left_right_reverse = value; } } -void auth_3d_data_set_mat(int32_t* id, const mat4* value) { - if (*id >= 0 && ((*id & 0x7FFF) < AUTH_3D_DATA_COUNT)) { - auth_3d* auth = &auth_3d_data->data[*id & 0x7FFF]; - if (auth->id == *id) +void auth_3d_data_set_mat(const int32_t& id, const mat4* value) { + if (id >= 0 && ((id & 0x7FFF) < AUTH_3D_DATA_COUNT)) { + auth_3d* auth = &auth_3d_data->data[id & 0x7FFF]; + if (auth->id == id) auth->mat = *value; } } -void auth_3d_data_set_max_frame(int32_t* id, float_t value) { - if (*id >= 0 && ((*id & 0x7FFF) < AUTH_3D_DATA_COUNT)) { - auth_3d* auth = &auth_3d_data->data[*id & 0x7FFF]; - if (auth->id == *id) +void auth_3d_data_set_max_frame(const int32_t& id, float_t value) { + if (id >= 0 && ((id & 0x7FFF) < AUTH_3D_DATA_COUNT)) { + auth_3d* auth = &auth_3d_data->data[id & 0x7FFF]; + if (auth->id == id) auth->max_frame = value; } } -void auth_3d_data_set_paused(int32_t* id, bool value) { - if (*id >= 0 && ((*id & 0x7FFF) < AUTH_3D_DATA_COUNT)) { - auth_3d* auth = &auth_3d_data->data[*id & 0x7FFF]; - if (auth->id == *id) +void auth_3d_data_set_paused(const int32_t& id, bool value) { + if (id >= 0 && ((id & 0x7FFF) < AUTH_3D_DATA_COUNT)) { + auth_3d* auth = &auth_3d_data->data[id & 0x7FFF]; + if (auth->id == id) auth->paused = value; } } -void auth_3d_data_set_repeat(int32_t* id, bool value) { - if (*id >= 0 && ((*id & 0x7FFF) < AUTH_3D_DATA_COUNT)) { - auth_3d* auth = &auth_3d_data->data[*id & 0x7FFF]; - if (auth->id == *id) +void auth_3d_data_set_repeat(const int32_t& id, bool value) { + if (id >= 0 && ((id & 0x7FFF) < AUTH_3D_DATA_COUNT)) { + auth_3d* auth = &auth_3d_data->data[id & 0x7FFF]; + if (auth->id == id) auth->repeat = value; } } -void auth_3d_data_set_req_frame(int32_t* id, float_t value) { - if (*id >= 0 && ((*id & 0x7FFF) < AUTH_3D_DATA_COUNT)) { - auth_3d* auth = &auth_3d_data->data[*id & 0x7FFF]; - if (auth->id == *id) { +void auth_3d_data_set_req_frame(const int32_t& id, float_t value) { + if (id >= 0 && ((id & 0x7FFF) < AUTH_3D_DATA_COUNT)) { + auth_3d* auth = &auth_3d_data->data[id & 0x7FFF]; + if (auth->id == id) { auth->req_frame = value; auth->frame_changed = true; } } } -void auth_3d_data_set_shadow(int32_t* id, bool value) { - if (*id >= 0 && ((*id & 0x7FFF) < AUTH_3D_DATA_COUNT)) { - auth_3d* auth = &auth_3d_data->data[*id & 0x7FFF]; - if (auth->id == *id) +void auth_3d_data_set_shadow(const int32_t& id, bool value) { + if (id >= 0 && ((id & 0x7FFF) < AUTH_3D_DATA_COUNT)) { + auth_3d* auth = &auth_3d_data->data[id & 0x7FFF]; + if (auth->id == id) auth->shadow = value; } } -void auth_3d_data_set_src_dst_chara(int32_t* id, int32_t src_chara, int32_t dst_chara) { - if (*id >= 0 && ((*id & 0x7FFF) < AUTH_3D_DATA_COUNT)) { - auth_3d* auth = &auth_3d_data->data[*id & 0x7FFF]; - if (auth->id == *id) { +void auth_3d_data_set_src_dst_chara(const int32_t& id, int32_t src_chara, int32_t dst_chara) { + if (id >= 0 && ((id & 0x7FFF) < AUTH_3D_DATA_COUNT)) { + auth_3d* auth = &auth_3d_data->data[id & 0x7FFF]; + if (auth->id == id) { auth->src_chara = src_chara; auth->dst_chara = dst_chara; } } } -void auth_3d_data_set_visibility(int32_t* id, bool value) { - if (*id >= 0 && ((*id & 0x7FFF) < AUTH_3D_DATA_COUNT)) { - auth_3d* auth = &auth_3d_data->data[*id & 0x7FFF]; - if (auth->id == *id) +void auth_3d_data_set_visibility(const int32_t& id, bool value) { + if (id >= 0 && ((id & 0x7FFF) < AUTH_3D_DATA_COUNT)) { + auth_3d* auth = &auth_3d_data->data[id & 0x7FFF]; + if (auth->id == id) auth->visible = value; } } @@ -2938,7 +2938,7 @@ void auth_3d_data_unload_category(uint32_t category_hash) { auth_3d_data_struct_unload_category(auth_3d_data, category_hash); } -void auth_3d_data_unload_id(int32_t id, render_context* rctx) { +void auth_3d_data_unload_id(const int32_t& id, render_context* rctx) { if (id < 0 || (id & 0x7FFF) >= AUTH_3D_DATA_COUNT) return; @@ -3753,7 +3753,7 @@ static void auth_3d_fog_set(auth_3d_fog* f, render_context* rctx) { fog* data = &rctx->fog[id]; if (f->flags & AUTH_3D_FOG_COLOR) { - if (~f->flags_init & AUTH_3D_FOG_COLOR) { + if (!(f->flags_init & AUTH_3D_FOG_COLOR)) { vec4 color_init; data->get_color(color_init); f->color_init = color_init; @@ -3764,7 +3764,7 @@ static void auth_3d_fog_set(auth_3d_fog* f, render_context* rctx) { } if (f->flags & AUTH_3D_FOG_DENSITY) { - if (~f->flags_init & AUTH_3D_FOG_DENSITY) { + if (!(f->flags_init & AUTH_3D_FOG_DENSITY)) { f->density_init = data->get_density(); enum_or(f->flags_init, AUTH_3D_FOG_DENSITY); } @@ -3773,7 +3773,7 @@ static void auth_3d_fog_set(auth_3d_fog* f, render_context* rctx) { } if (f->flags & AUTH_3D_FOG_END) { - if (~f->flags_init & AUTH_3D_FOG_END) { + if (!(f->flags_init & AUTH_3D_FOG_END)) { f->end_init = data->get_end(); enum_or(f->flags_init, AUTH_3D_FOG_END); } @@ -3782,7 +3782,7 @@ static void auth_3d_fog_set(auth_3d_fog* f, render_context* rctx) { } if (f->flags & AUTH_3D_FOG_START) { - if (~f->flags_init & AUTH_3D_FOG_START) { + if (!(f->flags_init & AUTH_3D_FOG_START)) { f->start_init = data->get_start(); enum_or(f->flags_init, AUTH_3D_FOG_START); } @@ -3892,7 +3892,7 @@ static void auth_3d_light_set(auth_3d_light* l, render_context* rctx) { light_data* data = &set_data->lights[id]; if (l->flags & AUTH_3D_LIGHT_AMBIENT) { - if (~l->flags_init & AUTH_3D_LIGHT_AMBIENT) { + if (!(l->flags_init & AUTH_3D_LIGHT_AMBIENT)) { vec4 ambient_init; data->get_ambient(ambient_init); l->ambient_init = ambient_init; @@ -3908,7 +3908,7 @@ static void auth_3d_light_set(auth_3d_light* l, render_context* rctx) { } if (l->flags & AUTH_3D_LIGHT_DIFFUSE) { - if (~l->flags_init & AUTH_3D_LIGHT_DIFFUSE) { + if (!(l->flags_init & AUTH_3D_LIGHT_DIFFUSE)) { vec4 diffuse_init; data->get_diffuse(diffuse_init); l->diffuse_init = diffuse_init; @@ -3927,7 +3927,7 @@ static void auth_3d_light_set(auth_3d_light* l, render_context* rctx) { data->set_position(l->position.translation_value); if (l->flags & AUTH_3D_LIGHT_SPECULAR) { - if (~l->flags_init & AUTH_3D_LIGHT_SPECULAR) { + if (!(l->flags_init & AUTH_3D_LIGHT_SPECULAR)) { vec4 specular_init; data->get_specular(specular_init); l->specular_init = specular_init; @@ -3946,7 +3946,7 @@ static void auth_3d_light_set(auth_3d_light* l, render_context* rctx) { data->set_spot_direction(l->spot_direction.translation_value); if (l->flags & AUTH_3D_LIGHT_TONE_CURVE) { - if (~l->flags_init & AUTH_3D_LIGHT_TONE_CURVE) { + if (!(l->flags_init & AUTH_3D_LIGHT_TONE_CURVE)) { data->get_tone_curve(l->tone_curve_init); enum_or(l->flags_init, AUTH_3D_LIGHT_TONE_CURVE); } @@ -5834,7 +5834,7 @@ static void auth_3d_object_hrc_load(auth_3d* auth, auth_3d_object_hrc* oh, break; } - if (i.bone_id > -1 && ~i.bone_id & 0x8000) + if (i.bone_id > -1 && !(i.bone_id & 0x8000)) i.mat = &mats[i.bone_id]; } } @@ -5901,7 +5901,7 @@ static void auth_3d_object_instance_load(auth_3d* auth, auth_3d_object_instance* for (auth_3d_object_node& j : moh->node) if (hash_string_fnv1a64m(j.name) == name_hash) { int32_t bone_id = skin->bone_array[i].id; - if (~bone_id & 0x8000) + if (!(bone_id & 0x8000)) object_bone_indices[bone_id] = (int32_t)(&j - moh->node.data()); break; } @@ -6119,7 +6119,7 @@ static void auth_3d_post_process_set(auth_3d_post_process* pp, render_context* r post_process_tone_map* tm = rctx->post_process.tone_map; if (pp->flags & AUTH_3D_POST_PROCESS_INTENSITY) { - if (~pp->flags_init & AUTH_3D_POST_PROCESS_INTENSITY) { + if (!(pp->flags_init & AUTH_3D_POST_PROCESS_INTENSITY)) { pp->intensity_init = blur->get_intensity(); enum_or(pp->flags_init, AUTH_3D_POST_PROCESS_INTENSITY); } @@ -6128,7 +6128,7 @@ static void auth_3d_post_process_set(auth_3d_post_process* pp, render_context* r } if (pp->flags & AUTH_3D_POST_PROCESS_LENS_FLARE) { - if (~pp->flags_init & AUTH_3D_POST_PROCESS_LENS_FLARE) { + if (!(pp->flags_init & AUTH_3D_POST_PROCESS_LENS_FLARE)) { pp->lens_flare_init = tm->get_lens_flare(); enum_or(pp->flags_init, AUTH_3D_POST_PROCESS_LENS_FLARE); } @@ -6137,7 +6137,7 @@ static void auth_3d_post_process_set(auth_3d_post_process* pp, render_context* r } if (pp->flags & AUTH_3D_POST_PROCESS_LENS_GHOST) { - if (~pp->flags_init & AUTH_3D_POST_PROCESS_LENS_GHOST) { + if (!(pp->flags_init & AUTH_3D_POST_PROCESS_LENS_GHOST)) { pp->lens_ghost_init = tm->get_lens_ghost(); enum_or(pp->flags_init, AUTH_3D_POST_PROCESS_LENS_GHOST); } @@ -6146,7 +6146,7 @@ static void auth_3d_post_process_set(auth_3d_post_process* pp, render_context* r } if (pp->flags & AUTH_3D_POST_PROCESS_LENS_SHAFT) { - if (~pp->flags_init & AUTH_3D_POST_PROCESS_LENS_SHAFT) { + if (!(pp->flags_init & AUTH_3D_POST_PROCESS_LENS_SHAFT)) { pp->lens_shaft_init = tm->get_lens_shaft(); enum_or(pp->flags_init, AUTH_3D_POST_PROCESS_LENS_SHAFT); } @@ -6155,7 +6155,7 @@ static void auth_3d_post_process_set(auth_3d_post_process* pp, render_context* r } if (pp->flags & AUTH_3D_POST_PROCESS_RADIUS) { - if (~pp->flags_init & AUTH_3D_POST_PROCESS_RADIUS) { + if (!(pp->flags_init & AUTH_3D_POST_PROCESS_RADIUS)) { pp->radius_init = blur->get_radius(); enum_or(pp->flags_init, AUTH_3D_POST_PROCESS_RADIUS); } @@ -6164,7 +6164,7 @@ static void auth_3d_post_process_set(auth_3d_post_process* pp, render_context* r } if (pp->flags & AUTH_3D_POST_PROCESS_SCENE_FADE) { - if (~pp->flags_init & AUTH_3D_POST_PROCESS_SCENE_FADE) { + if (!(pp->flags_init & AUTH_3D_POST_PROCESS_SCENE_FADE)) { pp->scene_fade_init = tm->get_scene_fade(); enum_or(pp->flags_init, AUTH_3D_POST_PROCESS_SCENE_FADE); } @@ -6284,24 +6284,6 @@ static void auth_3d_data_struct_unload_category( auth_3d_data->farcs_modern.erase(elem); } -static void auth_3d_farc_free_data(auth_3d_farc* a3da_farc) { - if (a3da_farc->state == 1) - a3da_farc->file_handler.call_free_callback(); - else if (a3da_farc->state == 2) { - delete a3da_farc->farc; - a3da_farc->farc = 0; - a3da_farc->file_handler.free_data(); - } - - a3da_farc->path.clear(); - a3da_farc->path.shrink_to_fit(); - a3da_farc->file.clear(); - a3da_farc->file.shrink_to_fit(); - a3da_farc->data = 0; - a3da_farc->size = 0; - a3da_farc->state = 0; -} - static void auth_3d_farc_load(auth_3d_farc* a3da_farc, const char* mdata_dir) { if (a3da_farc->load_count) { a3da_farc->load_count++; @@ -6382,11 +6364,29 @@ static bool auth_3d_farc_read_func(auth_3d_farc* a3da_farc, const void* data, si return true; } +static void auth_3d_farc_reset(auth_3d_farc* a3da_farc) { + if (a3da_farc->state == 1) + a3da_farc->file_handler.call_free_callback(); + else if (a3da_farc->state == 2) { + delete a3da_farc->farc; + a3da_farc->farc = 0; + a3da_farc->file_handler.reset(); + } + + a3da_farc->path.clear(); + a3da_farc->path.shrink_to_fit(); + a3da_farc->file.clear(); + a3da_farc->file.shrink_to_fit(); + a3da_farc->data = 0; + a3da_farc->size = 0; + a3da_farc->state = 0; +} + static void auth_3d_farc_unload(auth_3d_farc* a3da_farc) { if (--a3da_farc->load_count < 0) a3da_farc->load_count = 0; else if (!a3da_farc->load_count) - auth_3d_farc_free_data(a3da_farc); + auth_3d_farc_reset(a3da_farc); } static void auth_3d_uid_file_load(auth_3d_uid_file* uid_file) { @@ -6490,7 +6490,7 @@ static size_t auth_3d_time_event_radix_index_func_time(auth_3d_time_event* data, static void Auth3dTestTask__SetAuth3dId(Auth3dTestTask* tt) { if (task_stage_check_not_loaded() || tt->auth_3d_uid == -1 - || !tt->load_category.size() || tt->auth_3d_uid == auth_3d_data_get_uid(&tt->auth_3d_id)) + || !tt->load_category.size() || tt->auth_3d_uid == auth_3d_data_get_uid(tt->auth_3d_id)) return; if (tt->load_category.compare(tt->category)) { @@ -6536,9 +6536,9 @@ static void Auth3dTestTask__SetAuth3dId(Auth3dTestTask* tt) { auth_3d_data_unload_id(tt->auth_3d_id, rctx_ptr); tt->auth_3d_id = auth_3d_data_load_uid(tt->auth_3d_uid, aft_auth_3d_db); - if (auth_3d_data_check_id_not_empty(&tt->auth_3d_id)) { - auth_3d_data_set_enable(&tt->auth_3d_id, false); - auth_3d_data_read_file(&tt->auth_3d_id, aft_auth_3d_db); + if (auth_3d_data_check_id_not_empty(tt->auth_3d_id)) { + auth_3d_data_set_enable(tt->auth_3d_id, false); + auth_3d_data_read_file(tt->auth_3d_id, aft_auth_3d_db); tt->field_1D4 = 1; } tt->auth_3d_uid = -1; diff --git a/src/CRE/auth_3d.hpp b/src/CRE/auth_3d.hpp index 99ac23fc..af34094f 100644 --- a/src/CRE/auth_3d.hpp +++ b/src/CRE/auth_3d.hpp @@ -206,7 +206,7 @@ namespace auth_3d_detail { //std::pair aet_init_data; EventA2d(a3da_event* e); - virtual ~EventA2d(); + virtual ~EventA2d() override; virtual void Begin(auth_3d* auth, int32_t flags, render_context* rctx) override; virtual void End(auth_3d* auth, int32_t flags, render_context* rctx) override; @@ -217,7 +217,7 @@ namespace auth_3d_detail { struct EventFX : public Event { public: EventFX(a3da_event* e); - virtual ~EventFX(); + virtual ~EventFX() override; virtual void Load(auth_3d* auth) override; virtual void Begin(auth_3d* auth, int32_t flags, render_context* rctx) override; @@ -229,7 +229,7 @@ namespace auth_3d_detail { bool cam; EventFXSmoothCut(a3da_event* e); - virtual ~EventFXSmoothCut(); + virtual ~EventFXSmoothCut() override; virtual void Load(auth_3d* auth) override; virtual void Begin(auth_3d* auth, int32_t flags, render_context* rctx) override; @@ -249,7 +249,7 @@ namespace auth_3d_detail { vec3 color; EventFilterFade(a3da_event* e); - virtual ~EventFilterFade(); + virtual ~EventFilterFade() override; virtual void Begin(auth_3d* auth, int32_t flags, render_context* rctx) override; virtual void End(auth_3d* auth, int32_t flags, render_context* rctx) override; @@ -259,7 +259,7 @@ namespace auth_3d_detail { struct EventFilterTimeStop : public Event { public: EventFilterTimeStop(a3da_event* e); - virtual ~EventFilterTimeStop(); + virtual ~EventFilterTimeStop() override; virtual void Begin(auth_3d* auth, int32_t flags, render_context* rctx) override; virtual void End(auth_3d* auth, int32_t flags, render_context* rctx) override; @@ -269,7 +269,7 @@ namespace auth_3d_detail { struct EventMot : public Event { public: EventMot(a3da_event* e); - virtual ~EventMot(); + virtual ~EventMot() override; virtual void Load(auth_3d* auth) override; virtual void Begin(auth_3d* auth, int32_t flags, render_context* rctx) override; @@ -283,7 +283,7 @@ namespace auth_3d_detail { bool field_190; EventSnd(a3da_event* e); - virtual ~EventSnd(); + virtual ~EventSnd() override; virtual void Load(auth_3d* auth) override; virtual void Begin(auth_3d* auth, int32_t flags, render_context* rctx) override; @@ -875,7 +875,7 @@ struct auth_3d_farc { size_t size; auth_3d_farc(); - virtual ~auth_3d_farc(); + ~auth_3d_farc(); }; struct auth_3d_uid_file { @@ -914,7 +914,7 @@ struct auth_3d_data_struct { auth_3d data[AUTH_3D_DATA_COUNT]; auth_3d_data_struct(); - virtual ~auth_3d_data_struct(); + ~auth_3d_data_struct(); }; class Auth3dTestTask : public app::Task { @@ -973,59 +973,59 @@ extern auth_3d_data_struct* auth_3d_data; extern Auth3dTestTask* auth_3d_test_task; extern void auth_3d_data_init(); -extern bool auth_3d_data_check_id_not_empty(int32_t* id); +extern bool auth_3d_data_check_id_not_empty(const int32_t& id); extern bool auth_3d_data_check_category_loaded(const char* category_name); extern bool auth_3d_data_check_category_loaded(uint32_t category_hash); -extern bool auth_3d_data_check_id_loading(int32_t* id); -extern bool auth_3d_data_check_id_loaded(int32_t* id); -extern auth_3d* auth_3d_data_get_auth_3d(int32_t id); +extern bool auth_3d_data_check_id_loading(const int32_t& id); +extern bool auth_3d_data_check_id_loaded(const int32_t& id); +extern auth_3d* auth_3d_data_get_auth_3d(const int32_t& id); extern int32_t auth_3d_data_get_auth_3d_id(const char* object_name); extern int32_t auth_3d_data_get_auth_3d_id(object_info obj_info, int32_t* object_index, bool* hrc, int32_t instance = -1); extern int32_t auth_3d_data_get_auth_3d_id(uint32_t file_name_hash, uint32_t object_hash, int32_t* object_index, bool* hrc, int32_t instance = -1); -extern mat4* auth_3d_data_get_auth_3d_object_mat(int32_t id, size_t index, bool hrc, mat4* mat); -extern int32_t auth_3d_data_get_chara_id(int32_t id); -extern bool auth_3d_data_get_enable(int32_t* id); -extern bool auth_3d_data_get_ended(int32_t* id); -extern float_t auth_3d_data_get_frame(int32_t* id); -extern float_t auth_3d_data_get_frame_offset(int32_t* id); -extern float_t auth_3d_data_get_last_frame(int32_t* id); -extern bool auth_3d_data_get_left_right_reverse(int32_t* id); -extern bool auth_3d_data_get_paused(int32_t* id); -extern float_t auth_3d_data_get_play_control_begin(int32_t* id); -extern float_t auth_3d_data_get_play_control_size(int32_t* id); -extern bool auth_3d_data_get_repeat(int32_t* id); +extern mat4* auth_3d_data_get_auth_3d_object_mat(const int32_t& id, size_t index, bool hrc, mat4* mat); +extern int32_t auth_3d_data_get_chara_id(const int32_t& id); +extern bool auth_3d_data_get_enable(const int32_t& id); +extern bool auth_3d_data_get_ended(const int32_t& id); +extern float_t auth_3d_data_get_frame(const int32_t& id); +extern float_t auth_3d_data_get_frame_offset(const int32_t& id); +extern float_t auth_3d_data_get_last_frame(const int32_t& id); +extern bool auth_3d_data_get_left_right_reverse(const int32_t& id); +extern bool auth_3d_data_get_paused(const int32_t& id); +extern float_t auth_3d_data_get_play_control_begin(const int32_t& id); +extern float_t auth_3d_data_get_play_control_size(const int32_t& id); +extern bool auth_3d_data_get_repeat(const int32_t& id); void auth_3d_data_get_obj_sets_from_category(std::string& name, std::vector& obj_sets, auth_3d_database* auth_3d_db, object_database* obj_db); -extern int32_t auth_3d_data_get_uid(int32_t* id); +extern int32_t auth_3d_data_get_uid(const int32_t& id); extern const char* auth_3d_data_get_uid_name(int32_t uid, auth_3d_database* auth_3d_db); extern void auth_3d_data_load_auth_3d_db(auth_3d_database* auth_3d_db); extern void auth_3d_data_load_category(const char* category_name, const char* mdata_dir = 0); extern void auth_3d_data_load_category(void* data, const char* category_name, uint32_t category_hash); extern int32_t auth_3d_data_load_hash(uint32_t hash, void* data, object_database* obj_db, texture_database* tex_db); extern int32_t auth_3d_data_load_uid(int32_t uid, auth_3d_database* auth_3d_db); -extern void auth_3d_data_read_file(int32_t* id, auth_3d_database* auth_3d_db); -extern void auth_3d_data_read_file_modern(int32_t* id); -extern void auth_3d_data_set_camera_root_update(int32_t* id, bool value); -extern void auth_3d_data_set_chara_id(int32_t* id, int32_t value); -extern void auth_3d_data_set_chara_item(int32_t* id, bool value); -extern void auth_3d_data_set_draw_task_flags_alpha(int32_t* id, draw_task_flags draw_task_flags, float_t alpha); -extern void auth_3d_data_set_enable(int32_t* id, bool value); -extern void auth_3d_data_set_frame_rate(int32_t* id, FrameRateControl* value); -extern void auth_3d_data_set_last_frame(int32_t* id, float_t value); -extern void auth_3d_data_set_left_right_reverse(int32_t* id, bool value); -extern void auth_3d_data_set_mat(int32_t* id, const mat4* value); -extern void auth_3d_data_set_max_frame(int32_t* id, float_t value); -extern void auth_3d_data_set_paused(int32_t* id, bool value); -extern void auth_3d_data_set_repeat(int32_t* id, bool value); -extern void auth_3d_data_set_req_frame(int32_t* id, float_t value); -extern void auth_3d_data_set_shadow(int32_t* id, bool value); -extern void auth_3d_data_set_src_dst_chara(int32_t* id, int32_t src_chara, int32_t dst_chara); -extern void auth_3d_data_set_visibility(int32_t* id, bool value); +extern void auth_3d_data_read_file(const int32_t& id, auth_3d_database* auth_3d_db); +extern void auth_3d_data_read_file_modern(const int32_t& id); +extern void auth_3d_data_set_camera_root_update(const int32_t& id, bool value); +extern void auth_3d_data_set_chara_id(const int32_t& id, int32_t value); +extern void auth_3d_data_set_chara_item(const int32_t& id, bool value); +extern void auth_3d_data_set_draw_task_flags_alpha(const int32_t& id, draw_task_flags draw_task_flags, float_t alpha); +extern void auth_3d_data_set_enable(const int32_t& id, bool value); +extern void auth_3d_data_set_frame_rate(const int32_t& id, FrameRateControl* value); +extern void auth_3d_data_set_last_frame(const int32_t& id, float_t value); +extern void auth_3d_data_set_left_right_reverse(const int32_t& id, bool value); +extern void auth_3d_data_set_mat(const int32_t& id, const mat4* value); +extern void auth_3d_data_set_max_frame(const int32_t& id, float_t value); +extern void auth_3d_data_set_paused(const int32_t& id, bool value); +extern void auth_3d_data_set_repeat(const int32_t& id, bool value); +extern void auth_3d_data_set_req_frame(const int32_t& id, float_t value); +extern void auth_3d_data_set_shadow(const int32_t& id, bool value); +extern void auth_3d_data_set_src_dst_chara(const int32_t& id, int32_t src_chara, int32_t dst_chara); +extern void auth_3d_data_set_visibility(const int32_t& id, bool value); extern void auth_3d_data_unload_category(const char* category_name); extern void auth_3d_data_unload_category(uint32_t category_hash); -extern void auth_3d_data_unload_id(int32_t id, render_context* rctx); +extern void auth_3d_data_unload_id(const int32_t& id, render_context* rctx); extern void auth_3d_data_free(); extern void auth_3d_test_task_init(); diff --git a/src/CRE/camera.hpp b/src/CRE/camera.hpp index 05763aae..1a664d57 100644 --- a/src/CRE/camera.hpp +++ b/src/CRE/camera.hpp @@ -52,7 +52,7 @@ struct camera { bool fast_change_hist1; camera(); - virtual ~camera(); + ~camera(); void initialize(double_t aspect, int32_t render_width, int32_t render_height, int32_t sprite_width, int32_t sprite_height); diff --git a/src/CRE/draw_object.cpp b/src/CRE/draw_object.cpp index 0f0567b3..65780c15 100644 --- a/src/CRE/draw_object.cpp +++ b/src/CRE/draw_object.cpp @@ -249,7 +249,7 @@ void draw_object_draw_translucent(render_context* rctx, draw_object* draw) { obj_material_texture_data* texdata = material->material.texdata; uint32_t texture_id = -1; uint32_t texture_index = -1; - if (~material->material.shader_compo.m.transparency) { + if (!material->material.shader_compo.m.transparency) { for (int32_t i = 0; i < 8; i++, texdata++) if (texdata->shader_info.m.tex_type == OBJ_MATERIAL_TEXTURE_COLOR) { texture_id = texdata->tex_index; diff --git a/src/CRE/draw_pass.cpp b/src/CRE/draw_pass.cpp index 719c9247..31fb1140 100644 --- a/src/CRE/draw_pass.cpp +++ b/src/CRE/draw_pass.cpp @@ -1204,7 +1204,7 @@ static void draw_pass_show_vector(render_context* rctx, draw_pass* a1) { shaders_ft.env_vert_set(20, a1->show_vector_length, a1->show_vector_z_offset, 0.0f, 0.0f); for (int32_t i = 1; i < 4; i++) { - if (~a1->show_vector_flags & (1 << (i - 1))) + if (!(a1->show_vector_flags & (1 << (i - 1)))) continue; if (a1->draw_pass_3d[DRAW_PASS_3D_OPAQUE]) diff --git a/src/CRE/draw_task.cpp b/src/CRE/draw_task.cpp index 79f53c2a..415e1eab 100644 --- a/src/CRE/draw_task.cpp +++ b/src/CRE/draw_task.cpp @@ -480,7 +480,7 @@ bool draw_task_add_draw_object(render_context* rctx, obj* object, obj_material_attrib_member attrib = material->material.attrib.m; if (draw_task_flags & (DRAW_TASK_ALPHA_ORDER_1 | DRAW_TASK_ALPHA_ORDER_2 | DRAW_TASK_ALPHA_ORDER_3) && task->data.object.blend_color.w < 1.0f) { - if (~draw_task_flags & DRAW_TASK_NO_TRANSLUCENCY) { + if (!(draw_task_flags & DRAW_TASK_NO_TRANSLUCENCY)) { if (attrib.flag_28 || (attrib.punch_through || !(attrib.alpha_texture | attrib.alpha_material)) && !sub_mesh->attrib.m.transparent) { diff --git a/src/CRE/file_handler.cpp b/src/CRE/file_handler.cpp index 36a64120..763d64d6 100644 --- a/src/CRE/file_handler.cpp +++ b/src/CRE/file_handler.cpp @@ -112,7 +112,7 @@ void file_handler::set_callback_data(int32_t index, PFNFILEHANDLERCALLBACK* func } } -void file_handler::free_data_lock() { +void file_handler::reset() { bool free_fhndl = false; { @@ -299,7 +299,7 @@ static void file_handler_storage_ctrl_list() { for (std::list::iterator i = list.begin(); i != list.end();) { file_handler* pfhndl = *i; if (pfhndl->count == 1) { - pfhndl->free_data_lock(); + pfhndl->reset(); i = list.erase(i); } else { @@ -331,7 +331,7 @@ static void file_handler_storage_thread_ctrl() { } i->reading = false; } - i->free_data_lock(); + i->reset(); } file_handler_storage_data->deque.clear(); } @@ -347,14 +347,14 @@ p_file_handler::~p_file_handler() { if (check_not_ready()) call_free_callback(); else - free_data(); + reset(); } } void p_file_handler::call_free_callback() { if (ptr) ptr->call_callback(1); - free_data(); + reset(); } bool p_file_handler::check_not_ready() { @@ -366,20 +366,6 @@ bool p_file_handler::check_not_ready() { return !ptr->callback[0].ready; } -void p_file_handler::free_data() { - if (!ptr) - return; - - { - std::unique_lock u_lock(ptr->mtx); - for (int32_t i = 0; i < 2; i++) - ptr->callback[i] = {}; - } - - ptr->free_data_lock(); - ptr = 0; -} - const void* p_file_handler::get_data() { if (!ptr || ptr->not_ready) return 0; @@ -415,7 +401,7 @@ bool p_file_handler::read_file(void* data, const char* dir, if (ptr) { if (ptr->not_ready) return false; - free_data(); + reset(); } if (!((data_struct*)data)->check_file_exists(dir, farc_file ? farc_file : file)) @@ -457,7 +443,7 @@ bool p_file_handler::read_file(void* data, const char* dir, uint32_t hash, const if (ptr) { if (ptr->not_ready) return false; - free_data(); + reset(); } std::string file; @@ -514,6 +500,20 @@ void p_file_handler::read_now() { } } +void p_file_handler::reset() { + if (!ptr) + return; + + { + std::unique_lock u_lock(ptr->mtx); + for (int32_t i = 0; i < 2; i++) + ptr->callback[i] = {}; + } + + ptr->reset(); + ptr = 0; +} + void p_file_handler::set_callback_data(int32_t index, PFNFILEHANDLERCALLBACK* func, void* data) { if (ptr) ptr->set_callback_data(index, func, data); diff --git a/src/CRE/file_handler.hpp b/src/CRE/file_handler.hpp index a8978d66..86f6aa9e 100644 --- a/src/CRE/file_handler.hpp +++ b/src/CRE/file_handler.hpp @@ -36,10 +36,10 @@ struct file_handler { void* ds; file_handler(); - virtual ~file_handler(); + ~file_handler(); void call_callback(int32_t index); - void free_data_lock(); + void reset(); void set_file(const char* file); void set_farc_file(const char* farc_file, bool cache); void set_dir(const char* dir); @@ -50,11 +50,10 @@ struct p_file_handler { file_handler* ptr; p_file_handler(); - virtual ~p_file_handler(); + ~p_file_handler(); void call_free_callback(); bool check_not_ready(); - void free_data(); const void* get_data(); ssize_t get_size(); bool read_file(void* data, const char* path); @@ -62,6 +61,7 @@ struct p_file_handler { bool read_file(void* data, const char* dir, const char* file); bool read_file(void* data, const char* dir, uint32_t hash, const char* ext); void read_now(); + void reset(); void set_callback_data(int32_t index, PFNFILEHANDLERCALLBACK* func, void* data); }; diff --git a/src/CRE/item_table.hpp b/src/CRE/item_table.hpp index e2938872..66cbb393 100644 --- a/src/CRE/item_table.hpp +++ b/src/CRE/item_table.hpp @@ -116,7 +116,7 @@ struct item_table { std::map dbgset; item_table(); - virtual ~item_table(); + ~item_table(); }; extern void item_table_array_init(); diff --git a/src/CRE/light_param.cpp b/src/CRE/light_param.cpp index ead9e9af..4c286e51 100644 --- a/src/CRE/light_param.cpp +++ b/src/CRE/light_param.cpp @@ -155,7 +155,7 @@ static int32_t light_param_storage_load_file(light_param_data_storage* a1, bool int32_t load_error = light_param_data_load_file(&a1->stage_light_param_iterator->second, a1->file_handlers); for (int32_t i = 0; i < 6; i++) - a1->file_handlers[i].free_data(); + a1->file_handlers[i].reset(); a1->stage_light_param_iterator++; @@ -178,7 +178,7 @@ static int32_t light_param_storage_load_file(light_param_data_storage* a1, bool if (a1->farc_file_handler.read_file(&data_list[DATA_AFT], "rom/light_param/", buf)) a1->state = 4; else { - a1->farc_file_handler.free_data(); + a1->farc_file_handler.reset(); a1->state = 0; return 0; } @@ -506,8 +506,8 @@ static void light_param_data_set(light_param_data* a1, light_param_data_storage* static void light_param_storage_free_file_handlers(light_param_data_storage* a1) { for (int32_t i = 0; i < 6; ++i) - a1->file_handlers[i].free_data(); - a1->farc_file_handler.free_data(); + a1->file_handlers[i].reset(); + a1->farc_file_handler.reset(); } static void light_param_storage_load_stages(light_param_data_storage* a1, std::vector& stage_indices) { @@ -578,8 +578,8 @@ static void light_param_storage_reset(light_param_data_storage* a1) { a1->pv_cut.clear(); a1->pv_id = 0; for (p_file_handler& i : a1->file_handlers) - i.free_data(); - a1->farc_file_handler.free_data(); + i.reset(); + a1->farc_file_handler.reset(); } static void light_param_storage_set_default_light_param(light_param_data_storage* a1, int32_t stage_index) { diff --git a/src/CRE/light_param.hpp b/src/CRE/light_param.hpp index 8948c280..8f0d07ab 100644 --- a/src/CRE/light_param.hpp +++ b/src/CRE/light_param.hpp @@ -60,7 +60,7 @@ struct light_param_data_storage { int32_t pv_id; light_param_data_storage(); - virtual ~light_param_data_storage(); + ~light_param_data_storage(); static void load(data_struct* data); static void unload(); diff --git a/src/CRE/light_param/wind.hpp b/src/CRE/light_param/wind.hpp index 404619ec..c7a312e7 100644 --- a/src/CRE/light_param/wind.hpp +++ b/src/CRE/light_param/wind.hpp @@ -29,7 +29,7 @@ struct wind { float_t strength; wind(); - virtual ~wind(); + ~wind(); float_t get_scale(); void set_scale(float_t value); diff --git a/src/CRE/lock.hpp b/src/CRE/lock.hpp index dd4166a4..90cd044c 100644 --- a/src/CRE/lock.hpp +++ b/src/CRE/lock.hpp @@ -7,15 +7,42 @@ #include "../KKdLib/default.hpp" +template struct lock { +private: + volatile uint32_t value; + +public: + inline lock() { + _InterlockedExchange(&value, 0); + } + + inline T get() { + _m_prefetchw(&value); + int32_t v3 = value; + while (true) { + int32_t v4 = v3; + v3 = _InterlockedCompareExchange(&value, v3, v3); + if (v4 == v3) + break; + } + return (T)v3; + } + + inline void set(T value) { + _InterlockedExchange(&this->value, (uint32_t)value); + } +}; + +struct lock_cs { CRITICAL_SECTION cs; bool init; - inline lock() : cs() { + inline lock_cs() : cs() { init = InitializeCriticalSectionAndSpinCount(&cs, 0); } - inline ~lock() { + inline ~lock_cs() { if (init) DeleteCriticalSection(&cs); cs = {}; @@ -29,32 +56,6 @@ struct lock { } }; -struct lock_uint32_t { -private: - volatile uint32_t value; - -public: - inline lock_uint32_t() { - _InterlockedExchange(&value, 0); - } - - inline uint32_t get() { - _m_prefetchw(&value); - int32_t v3 = value; - while (true) { - int32_t v4 = v3; - v3 = _InterlockedCompareExchange(&value, v3, v3); - if (v4 == v3) - break; - } - return v3; - } - - inline void set(uint32_t value) { - _InterlockedExchange(&this->value, value); - } -}; - #define lock_lock(val) \ if ((val) && (val)->init) { \ EnterCriticalSection(&(val)->cs) diff --git a/src/CRE/object.cpp b/src/CRE/object.cpp index 28945fdc..88350d4f 100644 --- a/src/CRE/object.cpp +++ b/src/CRE/object.cpp @@ -381,11 +381,11 @@ obj_set_handler::~obj_set_handler() { obj_set_handler_vertex_buffer_free(this); alloc_handler.reset(); while (tex_file_handler.ptr && tex_file_handler.ptr->count) - tex_file_handler.free_data(); + tex_file_handler.reset(); while (obj_file_handler.ptr && obj_file_handler.ptr->count) - obj_file_handler.free_data(); + obj_file_handler.reset(); while (farc_file_handler.ptr && farc_file_handler.ptr->count) - farc_file_handler.free_data(); + farc_file_handler.reset(); } inline int32_t obj_material_texture_type_get_texcoord_index( @@ -1834,7 +1834,7 @@ bool object_storage_load_obj_set_check_not_read(uint32_t set_id, if (!set->ready) return false; - handler->obj_file_handler.free_data(); + handler->obj_file_handler.reset(); handler->obj_id_data.reserve(set->obj_num); for (uint32_t i = 0; i < set->obj_num; i++) handler->obj_id_data.push_back({ set->obj_data[i].id, i }); @@ -1858,7 +1858,7 @@ bool object_storage_load_obj_set_check_not_read(uint32_t set_id, return false; obj_set_handler_get_shader_index_texture_index(handler); - handler->tex_file_handler.free_data(); + handler->tex_file_handler.reset(); handler->tex_loaded = true; } } @@ -1950,7 +1950,7 @@ bool object_storage_load_obj_set_check_not_read(uint32_t set_id, object_material_msgpack_read("patch\\AFT\\objset", file.c_str(), set, &local_obj_db); - handler->obj_file_handler.free_data(); + handler->obj_file_handler.reset(); handler->obj_id_data.reserve(set->obj_num); for (uint32_t i = 0; i < set->obj_num; i++) handler->obj_id_data.push_back({ set->obj_data[i].id, i }); @@ -1967,7 +1967,7 @@ bool object_storage_load_obj_set_check_not_read(uint32_t set_id, obj_set_handler_get_shader_index_texture_index(handler); handler->tex_loaded = true; - handler->farc_file_handler.free_data(); + handler->farc_file_handler.reset(); } if (handler->obj_loaded && handler->tex_loaded) @@ -2006,9 +2006,9 @@ inline void object_storage_unload_set(object_database* obj_db, const char* name) handler->obj_loaded = false; handler->alloc_handler.reset(); handler->obj_set = 0; - handler->tex_file_handler.free_data(); - handler->obj_file_handler.free_data(); - handler->farc_file_handler.free_data(); + handler->tex_file_handler.reset(); + handler->obj_file_handler.reset(); + handler->farc_file_handler.reset(); } inline void object_storage_unload_set(uint32_t set_id) { @@ -2038,9 +2038,9 @@ inline void object_storage_unload_set(uint32_t set_id) { handler->obj_loaded = false; handler->alloc_handler.reset(); handler->obj_set = 0; - handler->tex_file_handler.free_data(); - handler->obj_file_handler.free_data(); - handler->farc_file_handler.free_data(); + handler->tex_file_handler.reset(); + handler->obj_file_handler.reset(); + handler->farc_file_handler.reset(); if (handler->modern) for (auto i = object_storage_data_modern.begin(); i != object_storage_data_modern.end(); i++) if (i->set_id == set_id) { diff --git a/src/CRE/object.hpp b/src/CRE/object.hpp index 4ff29d34..1fd569c7 100644 --- a/src/CRE/object.hpp +++ b/src/CRE/object.hpp @@ -92,7 +92,7 @@ struct obj_set_handler { bool modern; obj_set_handler(); - virtual ~obj_set_handler(); + ~obj_set_handler(); }; extern int32_t obj_material_texture_type_get_texcoord_index( diff --git a/src/CRE/ogg_vorbis.cpp b/src/CRE/ogg_vorbis.cpp index d1cf07fd..6d71e967 100644 --- a/src/CRE/ogg_vorbis.cpp +++ b/src/CRE/ogg_vorbis.cpp @@ -307,7 +307,7 @@ void OggFile::ThreadMain(OggFile* of) { of->thread_state.set(0); } -OggFileHandler::OggFileHandler(size_t index) : time_seek(), channel_pairs_count(), +OggFileHandler::OggFileHandler(size_t index) : load_time_seek(), channel_pairs_count(), duration(), time(), channel_pairs_count_dup(), duration_dup(), time_dup(), channel_pair_volume_pan(), master_volume(), channel_pair_volume(), req_time(), loop() { this->index = index; @@ -346,7 +346,7 @@ void OggFileHandler::Ctrl() { _playback_state = playback_state.get(); playback_state.set(OGG_FILE_HANDLER_PLAYBACK_STATE_NONE); switch (_playback_state) { - case OGG_FILE_HANDLER_PLAYBACK_STATE_PLAY: + case OGG_FILE_HANDLER_PLAYBACK_STATE_LOAD: Reset(false); file_state.set(OGG_FILE_HANDLER_FILE_STATE_LOADING); OpenFile(); @@ -354,7 +354,7 @@ void OggFileHandler::Ctrl() { req_time = 0.0; ReadBufferProt(0, 0); break; - case OGG_FILE_HANDLER_PLAYBACK_STATE_STOP: + case OGG_FILE_HANDLER_PLAYBACK_STATE_UNLOAD: Reset(true); break; } @@ -367,14 +367,14 @@ void OggFileHandler::Ctrl() { sound::wasapi::StreamingChannel* streaming_channel = mixer->GetStreamingChannel(index); if (streaming_channel) { switch (_playback_state) { - case OGG_FILE_HANDLER_PLAYBACK_STATE_PLAY: + case OGG_FILE_HANDLER_PLAYBACK_STATE_LOAD: if (sound_wasapi_system->pClockAdjustment) sound_wasapi_system->pClockAdjustment->SetSampleRate((float_t)rate); streaming_channel->SetMasterVolume(1.0f); streaming_channel->SetCallback(OggFileHandler::FillBufferStatic, this); break; - case OGG_FILE_HANDLER_PLAYBACK_STATE_STOP: + case OGG_FILE_HANDLER_PLAYBACK_STATE_UNLOAD: streaming_channel->reset_state.set(1); break; } @@ -406,10 +406,10 @@ void OggFileHandler::FillBuffer(sound_buffer_data* buffer, size_t samples_count) file_state.set(OGG_FILE_HANDLER_FILE_STATE_NONE); int32_t _playback_state = playback_state.get(); - playback_state.set(0); + playback_state.set(OGG_FILE_HANDLER_PLAYBACK_STATE_NONE); if (_file_state == OGG_FILE_HANDLER_FILE_STATE_PLAYING - && _playback_state != OGG_FILE_HANDLER_PLAYBACK_STATE_STOP) { + && _playback_state != OGG_FILE_HANDLER_PLAYBACK_STATE_UNLOAD) { std::unique_lock u_lock(mtx); ReadBufferProt(buffer, samples_count); } @@ -426,11 +426,11 @@ float_t OggFileHandler::GetDuration() { } OggFileHandlerFileState OggFileHandler::GetFileState() { - return (OggFileHandlerFileState)file_state.get(); + return file_state.get(); } OggFileHandlerPauseState OggFileHandler::GetPauseState() { - return (OggFileHandlerPauseState)pause_state.get(); + return pause_state.get(); } float_t OggFileHandler::GetTime() { @@ -440,7 +440,7 @@ float_t OggFileHandler::GetTime() { void OggFileHandler::OpenFile() { std::unique_lock u_lock(file_mtx); - if (file.OpenFile(path.c_str(), time_seek)) { + if (file.OpenFile(path.c_str(), load_time_seek)) { channel_pairs_count = file.GetChannelPairsCount(); duration = file.GetDuration(); time = 0.0; @@ -518,7 +518,7 @@ void OggFileHandler::ReadBufferProt(sound_buffer_data* buffer, size_t samples_co if (process || loop) ReadBuffer(buffer, samples_count); else - playback_state.set(OGG_FILE_HANDLER_PLAYBACK_STATE_STOP); + playback_state.set(OGG_FILE_HANDLER_PLAYBACK_STATE_UNLOAD); } void OggFileHandler::Reset(bool reset) { @@ -555,6 +555,11 @@ void OggFileHandler::SetFileState(OggFileHandlerFileState state) { Reset(false); } +void OggFileHandler::SetLoadTimeSeek(float_t value) { + std::unique_lock u_lock(file_mtx); + load_time_seek = value; +} + void OggFileHandler::SetMasterVolume(int32_t value) { value = clamp_def(value, -10000, 0); std::unique_lock u_lock(volume_mtx); @@ -564,7 +569,7 @@ void OggFileHandler::SetMasterVolume(int32_t value) { void OggFileHandler::SetPath(std::string& path) { std::unique_lock u_lock(mtx); file_state.set(OGG_FILE_HANDLER_FILE_STATE_LOADING); - playback_state.set(OGG_FILE_HANDLER_PLAYBACK_STATE_PLAY); + playback_state.set(OGG_FILE_HANDLER_PLAYBACK_STATE_LOAD); { std::unique_lock u_lock(file_mtx); @@ -587,11 +592,6 @@ void OggFileHandler::SetPlaybackState(OggFileHandlerPlaybackState value) { playback_state.set(value); } -void OggFileHandler::SetTimeSeek(float_t value) { - std::unique_lock u_lock(file_mtx); - time_seek = value; -} - void OggFileHandler::FillBufferStatic(sound_buffer_data* buffer, size_t samples_count, void* data) { if (data) ((OggFileHandler*)data)->FillBuffer(buffer, samples_count); @@ -617,7 +617,7 @@ void OggFileHandler::ThreadMain(OggFileHandler* ofh) { ofh->Ctrl(); timer.sleep(8); } - ofh->playback_state.set(OGG_FILE_HANDLER_PLAYBACK_STATE_STOP); + ofh->playback_state.set(OGG_FILE_HANDLER_PLAYBACK_STATE_UNLOAD); ofh->Ctrl(); ofh->thread_state.set(0); } @@ -679,6 +679,11 @@ void p_OggFileHandler::SetChannelPairVolumePan(size_t src_channel_pair, ptr->SetChannelPairVolumePan(src_channel_pair, src_channel, dst_channel, value); } +void p_OggFileHandler::SetLoadTimeSeek(float_t value) { + if (ptr) + ptr->SetLoadTimeSeek(value); +} + void p_OggFileHandler::SetMasterVolume(int32_t value) { if (ptr) ptr->SetMasterVolume(value); @@ -704,12 +709,7 @@ void p_OggFileHandler::SetPlaybackState(OggFileHandlerPlaybackState value) { ptr->SetPlaybackState(value); } -void p_OggFileHandler::SetTimeSeek(float_t value) { - if (ptr) - ptr->SetTimeSeek(value); -} - -OggPlayback::OggPlayback(size_t index) : state(), ogg_file_handler(), time_seek() { +OggPlayback::OggPlayback(size_t index) : state(), ogg_file_handler(), load_time_seek() { this->index = index; } @@ -781,6 +781,10 @@ void OggPlayback::SetChannelPairVolumePan(size_t src_channel_pair, ogg_file_handler->SetChannelPairVolumePan(src_channel_pair, src_channel, dst_channel, value); } +void OggPlayback::SetLoadTimeSeek(float_t value) { + load_time_seek = value; +} + void OggPlayback::SetMasterVolume(int32_t value) { if (state == 1 && ogg_file_handler) ogg_file_handler->SetMasterVolume(value); @@ -804,10 +808,6 @@ void OggPlayback::SetPlaybackState(OggFileHandlerPlaybackState value) { ogg_file_handler->SetPlaybackState(value); } -void OggPlayback::SetTimeSeek(float_t value) { - time_seek = value; -} - bool OggPlayback::LoadFile(void* data, const char* path, const char* file, uint32_t hash) { OggPlayback* op = (OggPlayback*)data; @@ -833,7 +833,7 @@ bool OggPlayback::LoadFile(void* data, const char* path, const char* file, uint3 } if (op->ogg_file_handler) { - op->ogg_file_handler->SetTimeSeek(op->time_seek); + op->ogg_file_handler->SetLoadTimeSeek(op->load_time_seek); op->ogg_file_handler->SetPath(_path); op->state = 1; } diff --git a/src/CRE/ogg_vorbis.hpp b/src/CRE/ogg_vorbis.hpp index 0e53be2c..65030dc3 100644 --- a/src/CRE/ogg_vorbis.hpp +++ b/src/CRE/ogg_vorbis.hpp @@ -41,8 +41,8 @@ enum OggFileHandlerPauseState { enum OggFileHandlerPlaybackState { OGG_FILE_HANDLER_PLAYBACK_STATE_NONE = 0, - OGG_FILE_HANDLER_PLAYBACK_STATE_PLAY, - OGG_FILE_HANDLER_PLAYBACK_STATE_STOP, + OGG_FILE_HANDLER_PLAYBACK_STATE_LOAD, + OGG_FILE_HANDLER_PLAYBACK_STATE_UNLOAD, OGG_FILE_HANDLER_PLAYBACK_STATE_MAX, }; @@ -74,7 +74,7 @@ struct OggFileBuffer { struct OggFile { std::mutex mtx; - lock_uint32_t thread_state; + lock thread_state; std::thread* thread; OggFileBuffer buffer; OggVorbis_File* file; @@ -85,7 +85,7 @@ struct OggFile { std::mutex file_mtx; OggFile(); - virtual ~OggFile(); + ~OggFile(); void Ctrl(size_t samples_count); size_t FillBufferData(OggFileBufferData* buffer_data, size_t samples_count); @@ -103,13 +103,13 @@ struct OggFile { struct OggFileHandler { std::mutex mtx; - lock_uint32_t thread_state; + lock thread_state; std::thread* thread; size_t index; OggFile file; std::mutex file_mtx; std::string path; - float_t time_seek; + float_t load_time_seek; int32_t channel_pairs_count; double_t duration; double_t time; @@ -121,16 +121,16 @@ struct OggFileHandler { int32_t channel_pair_volume_pan[4][2][4]; int32_t master_volume; int32_t channel_pair_volume[4]; - lock_uint32_t file_state; - lock_uint32_t playback_state; - lock_uint32_t pause_state; + lock file_state; + lock playback_state; + lock pause_state; double_t req_time; int32_t rate; bool loop; std::vector buffer_data; OggFileHandler(size_t index = 0); - virtual ~OggFileHandler(); + ~OggFileHandler(); void Ctrl(); int32_t GetChannelPairsCount(); @@ -146,12 +146,12 @@ struct OggFileHandler { void SetChannelPairVolumePan(size_t src_channel_pair, int32_t src_channel, int32_t dst_channel, int32_t value); void SetFileState(OggFileHandlerFileState state); + void SetLoadTimeSeek(float_t value); void SetMasterVolume(int32_t value); void SetPath(std::string& path); void SetPath(std::string&& path); void SetPauseState(OggFileHandlerPauseState value); void SetPlaybackState(OggFileHandlerPlaybackState value); - void SetTimeSeek(float_t value); static void FillBufferStatic(sound_buffer_data* buffer, size_t samples_count, void* data); static bool LoadFile(void* data, const char* path, const char* file, uint32_t hash); @@ -171,19 +171,19 @@ struct p_OggFileHandler { float_t GetTime(); void SetChannelPairVolumePan(size_t src_channel_pair, int32_t src_channel, int32_t dst_channel, int32_t value); + void SetLoadTimeSeek(float_t value); void SetMasterVolume(int32_t value); void SetPath(std::string& path); void SetPath(std::string&& path); void SetPauseState(OggFileHandlerPauseState value); void SetPlaybackState(OggFileHandlerPlaybackState value); - void SetTimeSeek(float_t value); }; struct OggPlayback { size_t index; int32_t state; p_OggFileHandler* ogg_file_handler; - float_t time_seek; + float_t load_time_seek; OggPlayback(size_t index); ~OggPlayback(); @@ -196,12 +196,12 @@ struct OggPlayback { void Reset(); void SetChannelPairVolumePan(size_t src_channel_pair, int32_t src_channel, int32_t dst_channel, int32_t value); + void SetLoadTimeSeek(float_t value); void SetMasterVolume(int32_t value); void SetPath(std::string& path); void SetPath(std::string&& path); void SetPauseState(OggFileHandlerPauseState value); void SetPlaybackState(OggFileHandlerPlaybackState value); - void SetTimeSeek(float_t value); static bool LoadFile(void* data, const char* path, const char* file, uint32_t hash); static void SetChannelPairVolumePan(OggPlayback* op); diff --git a/src/CRE/post_process/aa.hpp b/src/CRE/post_process/aa.hpp index 0c90e819..d9c314b5 100644 --- a/src/CRE/post_process/aa.hpp +++ b/src/CRE/post_process/aa.hpp @@ -17,7 +17,7 @@ struct post_process_aa { GLuint mlaa_area_texture; post_process_aa(); - virtual ~post_process_aa(); + ~post_process_aa(); void apply_mlaa(render_texture* rt, render_texture* buf_rt, GLuint* samplers, int32_t ss_alpha_mask); diff --git a/src/CRE/post_process/blur.hpp b/src/CRE/post_process/blur.hpp index 77b5c08b..835ab0ce 100644 --- a/src/CRE/post_process/blur.hpp +++ b/src/CRE/post_process/blur.hpp @@ -29,7 +29,7 @@ struct post_process_blur { int32_t count_down; post_process_blur(); - virtual ~post_process_blur(); + ~post_process_blur(); void get_blur(render_texture* rt); void init_fbo(int32_t width, int32_t height); diff --git a/src/CRE/post_process/dof.hpp b/src/CRE/post_process/dof.hpp index 6e50c2af..b95c3551 100644 --- a/src/CRE/post_process/dof.hpp +++ b/src/CRE/post_process/dof.hpp @@ -55,7 +55,7 @@ struct post_process_dof { GLuint ubo[2]; post_process_dof(); - virtual ~post_process_dof(); + ~post_process_dof(); void apply(render_texture* rt, render_texture* buf, GLuint* samplers, camera* cam); void init_fbo(int32_t width, int32_t height); diff --git a/src/CRE/post_process/exposure.hpp b/src/CRE/post_process/exposure.hpp index 136962ed..e12c3f3e 100644 --- a/src/CRE/post_process/exposure.hpp +++ b/src/CRE/post_process/exposure.hpp @@ -28,7 +28,7 @@ struct post_process_exposure { int32_t query_index; post_process_exposure(); - virtual ~post_process_exposure(); + ~post_process_exposure(); void get_exposure(camera* cam, int32_t render_width, int32_t render_height, bool reset_exposure, GLuint in_tex_0, GLuint in_tex_1); diff --git a/src/CRE/post_process/tone_map.hpp b/src/CRE/post_process/tone_map.hpp index 5ba04f32..1a07e3a0 100644 --- a/src/CRE/post_process/tone_map.hpp +++ b/src/CRE/post_process/tone_map.hpp @@ -53,7 +53,7 @@ struct post_process_tone_map { GLuint tone_map; post_process_tone_map(); - virtual ~post_process_tone_map(); + ~post_process_tone_map(); void apply(render_texture* in_tex, texture* light_proj_tex, texture* back_2d_tex, render_texture* rt, render_texture* buf_rt,/* render_texture* contour_rt,*/ diff --git a/src/CRE/pv_db.cpp b/src/CRE/pv_db.cpp index f2e4b92b..367995c5 100644 --- a/src/CRE/pv_db.cpp +++ b/src/CRE/pv_db.cpp @@ -714,7 +714,7 @@ namespace pv_db { state = 4; } break; case 4: { - file_handler.free_data(); + file_handler.reset(); paths.pop_front(); state = 1; } break; diff --git a/src/CRE/pv_expression.cpp b/src/CRE/pv_expression.cpp index b8681efe..28000540 100644 --- a/src/CRE/pv_expression.cpp +++ b/src/CRE/pv_expression.cpp @@ -180,7 +180,7 @@ void pv_expression_file_unload(const char* file) { i->data = 0; } - i->file_handler.free_data(); + i->file_handler.reset(); i->alloc_handler.reset(); } delete i; @@ -204,7 +204,7 @@ void pv_expression_file_unload(uint32_t hash) { i->data = 0; } - i->file_handler.free_data(); + i->file_handler.reset(); i->alloc_handler.reset(); } diff --git a/src/CRE/random.hpp b/src/CRE/random.hpp index 2f7fd8b9..43a6d716 100644 --- a/src/CRE/random.hpp +++ b/src/CRE/random.hpp @@ -12,7 +12,7 @@ struct RandState { std::mt19937 mt; RandState(); - virtual ~RandState(); + ~RandState(); }; extern void rand_state_array_init(); diff --git a/src/CRE/render_context.hpp b/src/CRE/render_context.hpp index f945454e..2637b0d5 100644 --- a/src/CRE/render_context.hpp +++ b/src/CRE/render_context.hpp @@ -433,7 +433,7 @@ struct light_proj { uint32_t texture_id; light_proj(int32_t width, int32_t height); - virtual ~light_proj(); + ~light_proj(); void resize(int32_t width, int32_t height); bool set(render_context* rctx); @@ -568,7 +568,7 @@ struct render_context { mat4 matrix_buffer[MATRIX_BUFFER_COUNT]; render_context(); - virtual ~render_context(); + ~render_context(); void ctrl(); void disp(); @@ -619,7 +619,7 @@ struct shadow { bool field_2F5; shadow(); - virtual ~shadow(); + ~shadow(); void ctrl(render_context* rctx); int32_t init_data(); diff --git a/src/CRE/rob/rob.cpp b/src/CRE/rob/rob.cpp index 4c742928..f11c6d75 100644 --- a/src/CRE/rob/rob.cpp +++ b/src/CRE/rob/rob.cpp @@ -21,6 +21,7 @@ struct MotFile { motion_set_info* mot_set_info; + prj::shared_ptr alloc_handler; mot_set* mot_set; p_file_handler file_handler; int32_t load_count; @@ -2180,7 +2181,7 @@ void rob_init() { rob_mot_tbl_file_handler.read_file(&data_list[DATA_AFT], "rom/rob/", "rob_mot_tbl.bin"); rob_mot_tbl_file_handler.set_callback_data(0, (PFNFILEHANDLERCALLBACK*)rob_cmn_mottbl_read, 0); rob_mot_tbl_file_handler.read_now(); - rob_mot_tbl_file_handler.free_data(); + rob_mot_tbl_file_handler.reset(); } if (!rob_thread_handler) @@ -2423,7 +2424,7 @@ float_t rob_chara::get_max_face_depth() { static int16_t sub_14054FE90(rob_chara* rob_chr, bool a3) { int16_t v3 = rob_chr->data.miku_rot.rot_y_int16; - if (!a3 || ~rob_chr->data.field_0 & 0x10) { + if (!a3 || !(rob_chr->data.field_0 & 0x10)) { int16_t v4 = rob_chr->data.field_8.field_B8.field_8; if (v4) return v3 + v4; @@ -2503,7 +2504,7 @@ static float_t sub_14054FDE0(rob_chara* rob_chr) { } else { if (!(rob_chr->data.field_1588.field_0.field_20.field_0 & 0x8000) - || ~rob_chr->data.field_1588.field_0.field_20.field_0 & 0x01) + || !(rob_chr->data.field_1588.field_0.field_20.field_0 & 0x01)) return 7.0f; } return 3.0f; @@ -2593,8 +2594,8 @@ static void sub_140555B00(rob_chara* rob_chr, bool a2) { else if (rob_chr->data.motion.prev_motion_id == -1) v3 = 0; else { - v3 = ~rob_chr->data.field_1588.field_0.field_20.field_0 & 0x400 - || ~rob_chr->data.field_1588.field_0.field_10.field_0 & 0x40 + v3 = !(rob_chr->data.field_1588.field_0.field_20.field_0 & 0x400) + || !(rob_chr->data.field_1588.field_0.field_10.field_0 & 0x40) || rob_chr->data.field_1588.field_0.field_20.field_0 & 0x100000; } @@ -5872,11 +5873,11 @@ static void mothead_mot_msgpack_read(const char* path, const char* set_name, mot if (!mot_id || !arr) continue; - uint32_t motion_id = mot_id->read_uint32_t(); - if ((int32_t)motion_id < mhd->first_mot_id || (int32_t)motion_id > mhd->last_mot_id) + int32_t motion_id = mot_id->read_int32_t(); + if (motion_id < mhd->first_mot_id || motion_id > mhd->last_mot_id) continue; - mothead_mot* mhdm = mhd->mots[(ssize_t)(int32_t)motion_id - mhd->first_mot_id]; + mothead_mot* mhdm = mhd->mots[(ssize_t)motion_id - mhd->first_mot_id]; msgpack_array* ptr = arr->data.arr; for (msgpack& j : *ptr) { @@ -6519,8 +6520,8 @@ void rob_chara_data_adjust_ctrl(rob_chara* rob_chr, rob_chara_data_adjust* adjus && fabsf(adjust->force_duration - adjust->transition_frame) > 0.000001f) { transition_frame_step = true; float_t blend = (adjust->transition_frame + 1.0f) / (adjust->force_duration + 1.0f); - vec3_lerp_scalar(adjust_prev->curr_external_force, - adjust->curr_external_force, adjust->curr_external_force, blend); + adjust->curr_external_force = vec3::lerp(adjust_prev->curr_external_force, + adjust->curr_external_force, blend); adjust->curr_force = lerp_def(adjust_prev->curr_force, adjust->curr_force, blend); } @@ -8145,7 +8146,7 @@ static void sub_140407280(struc_258* a1, std::vector* a2, mat4* mat, vec3_mult_scalar(v71, 0.5f, v71); mat4 v72 = *v7[MOTION_BONE_CL_KAO].node[1].mat; - mat4_mult_axis_angle(&v72, &v72, &v71, v51); + mat4_mult_axis_angle(&v72, &v71, v51, &v72); mat4_mult_vec3_inv_trans(&v72, &a1->field_184, &v67); float_t v52; @@ -8597,10 +8598,8 @@ static void sub_140406A70(vec3* a1, std::vector* bones, mat4* a3, vec mat4_clear_trans(v25->node->mat, &v39); mat4_transpose(&v38, &v38); mat4_mult(&v39, &v38, &v38); - if (rotation_blend < 1.0f) { - mat4 rot_mat = v25->rot_mat[0]; - mat4_lerp_rotation(&rot_mat, &v38, &v38, rotation_blend); - } + if (rotation_blend < 1.0f) + mat4_lerp_rotation(&v25->rot_mat[0], &v38, &v38, rotation_blend); v25->rot_mat[0] = v38; } @@ -8817,12 +8816,10 @@ static bool sub_14053B580(rob_chara* rob_chr, int32_t a2) { int32_t v33 = v0.field_0; vec3 v48 = 0.0f; - if (v33 == 0) { - vec3_lerp_scalar(v45, v13, v48, v31); - } - else if (v33 == 1) { - vec3_lerp_scalar(v13, v45, v48, v31); - } + if (v33 == 0) + v48 = vec3::lerp(v45, v13, v31); + else if (v33 == 1) + v48 = vec3::lerp(v13, v45, v31); switch (v0.field_E) { case 1: @@ -12110,6 +12107,10 @@ bool task_rob_manager_check_chara_loaded(int32_t chara_id) { return task_rob_manager->CheckCharaLoaded(&rob_chara_array[chara_id]); } +bool task_rob_manager_check_task_ready() { + return app::TaskWork::CheckTaskReady(task_rob_manager); +} + bool task_rob_manager_free_task() { if (!app::TaskWork::CheckTaskReady(task_rob_manager)) return true; @@ -12371,7 +12372,7 @@ void MotionBlendCross::Blend(bone_data* a2, bone_data* a3) { switch (a2->type) { case BONE_DATABASE_BONE_TYPE_1: case BONE_DATABASE_BONE_POSITION: - vec3_lerp_scalar(a3->trans, a2->trans, a2->trans, blend); + a2->trans = vec3::lerp(a3->trans, a2->trans, blend); break; case BONE_DATABASE_BONE_POSITION_ROTATION: if (field_21) { @@ -12541,7 +12542,7 @@ void MotionBlendFreeze::Blend(bone_data* a2, bone_data* a3) { switch (a2->type) { case BONE_DATABASE_BONE_TYPE_1: case BONE_DATABASE_BONE_POSITION: - vec3_lerp_scalar(a2->trans_prev[field_24], a2->trans, a2->trans, blend); + a2->trans = vec3::lerp(a2->trans_prev[field_24], a2->trans, blend); break; case BONE_DATABASE_BONE_POSITION_ROTATION: if (field_21) { @@ -12630,15 +12631,15 @@ void PartialMotionBlendFreeze::Blend(bone_data* a2, bone_data* a3) { switch (a2->type) { case BONE_DATABASE_BONE_POSITION: case BONE_DATABASE_BONE_TYPE_1: - vec3_lerp_scalar(a2->trans_prev[0], a2->trans, a2->trans, blend); + a2->trans = vec3::lerp(a2->trans_prev[0], a2->trans, blend); break; case BONE_DATABASE_BONE_POSITION_ROTATION: mat4_lerp_rotation(&a2->rot_mat_prev[0][0], &a2->rot_mat[0], &a2->rot_mat[0], blend); - vec3_lerp_scalar(a2->trans_prev[0], a2->trans, a2->trans, blend); + a2->trans = vec3::lerp(a2->trans_prev[0], a2->trans, blend); break; case BONE_DATABASE_BONE_ARM_IK_ROTATION: case BONE_DATABASE_BONE_LEGS_IK_ROTATION: - mat4_lerp_rotation(&a2->rot_mat[2], &a2->rot_mat_prev[2][0], &a2->rot_mat[2], blend); + mat4_lerp_rotation(&a2->rot_mat_prev[2][0], &a2->rot_mat[2], &a2->rot_mat[2], blend); case BONE_DATABASE_BONE_HEAD_IK_ROTATION: { mat4 v15; mat4 v16; @@ -14692,7 +14693,7 @@ void MotFile::FreeData() { delete mot_set; mot_set = 0; } - file_handler.free_data(); + file_handler.reset(); load_count = 0; } @@ -14767,7 +14768,7 @@ void MhdFile::FreeData() { } set = -1; file_path.clear(); - file_handler.free_data(); + file_handler.reset(); load_count = 0; } @@ -14953,7 +14954,7 @@ bool OpdMaker::Data::IsValidOpdiFile(rob_chara* rob_chr, int32_t motion_id) { void OpdMaker::Data::Reset() { for (auto i : opdi_files) if (i.second) { - i.second->free_data(); + i.second->reset(); delete i.second; i.second = 0; } diff --git a/src/CRE/rob/rob.hpp b/src/CRE/rob/rob.hpp index 8b23078b..ce877fed 100644 --- a/src/CRE/rob/rob.hpp +++ b/src/CRE/rob/rob.hpp @@ -1143,7 +1143,7 @@ struct motion_blend_mot { MotionBlend* blend; motion_blend_mot(); - virtual ~motion_blend_mot(); + ~motion_blend_mot(); MotionBlendType get_type(); void reset(); @@ -1321,7 +1321,7 @@ struct rob_chara_bone_data { rob_chara_bone_data_sleeve_adjust sleeve_adjust; rob_chara_bone_data(); - virtual ~rob_chara_bone_data(); + ~rob_chara_bone_data(); float_t get_frame(); float_t get_frame_count(); @@ -1363,7 +1363,7 @@ struct rob_chara_pv_data { eyes_adjust eyes_adjust; rob_chara_pv_data(); - virtual ~rob_chara_pv_data(); + ~rob_chara_pv_data(); }; struct struc_218 { @@ -2122,7 +2122,7 @@ struct rob_chara_item_equip_object { rob_chara_item_equip* item_equip; rob_chara_item_equip_object(); - virtual ~rob_chara_item_equip_object(); + ~rob_chara_item_equip_object(); void add_motion_reset_data(int32_t motion_id, float_t frame, int32_t osage_iterations); void check_no_opd(std::vector& opd_blend_data); @@ -2211,7 +2211,7 @@ struct rob_chara_item_equip { bool parts_white_one_l; rob_chara_item_equip(); - virtual ~rob_chara_item_equip(); + ~rob_chara_item_equip(); rob_chara_item_equip_object* get_item_equip_object(item_id id); void reset(); @@ -2787,7 +2787,7 @@ struct mothead_mot { bool is_x; mothead_mot(); - virtual ~mothead_mot(); + ~mothead_mot(); }; struct mothead { @@ -2798,7 +2798,7 @@ struct mothead { void* data_x; mothead(); - virtual ~mothead(); + ~mothead(); }; struct mothead_file { @@ -3295,7 +3295,7 @@ struct rob_chara { rob_chara_pv_data pv_data; rob_chara(); - virtual ~rob_chara(); + ~rob_chara(); void autoblink_disable(); void autoblink_enable(); @@ -3400,6 +3400,7 @@ extern void pv_osage_manager_array_set_pv_set_motion( extern bool task_rob_manager_append_task(); extern bool task_rob_manager_check_chara_loaded(int32_t chara_id); +extern bool task_rob_manager_check_task_ready(); extern bool task_rob_manager_free_task(); extern void motion_storage_init(); diff --git a/src/CRE/shader_glsl.hpp b/src/CRE/shader_glsl.hpp index 67dcdcae..cc507275 100644 --- a/src/CRE/shader_glsl.hpp +++ b/src/CRE/shader_glsl.hpp @@ -29,7 +29,7 @@ struct shader_glsl { std::vector> uniform_block; shader_glsl(); - virtual ~shader_glsl(); + ~shader_glsl(); GLint get_uniform_location(const char* name); void load(const char* vert_data, const char* frag_data, diff --git a/src/CRE/sound.cpp b/src/CRE/sound.cpp index 2c534d17..f23eb8de 100644 --- a/src/CRE/sound.cpp +++ b/src/CRE/sound.cpp @@ -37,7 +37,7 @@ struct sound_stream { bool pause; uint32_t file_loading_frames; uint32_t file_ready_frames; - float_t time_seek; + float_t load_time_seek; int32_t volume_trans; float_t target_volume; int32_t state; @@ -873,7 +873,7 @@ bool sound_db_farc::unload() { file_path.clear(); loaded = false; - file_handler.free_data(); + file_handler.reset(); return true; } @@ -1935,7 +1935,7 @@ static size_t ima_decode(int16_t* dst, size_t dst_size, uint8_t* data, size_t sa } sound_stream::sound_stream() : ogg_playback(), duration(), pause(), file_loading_frames(), -file_ready_frames(), time_seek(), volume_trans(), state(), play_state(), time() { +file_ready_frames(), load_time_seek(), volume_trans(), state(), play_state(), time() { current_volume = 1.0f; target_volume = 1.0f; } @@ -2060,7 +2060,7 @@ bool sound_stream::set_path(const char* path, bool pause) { if (!(this->path.compare(path) || !check_state() || !paused)) { if (ogg_playback) ogg_playback->SetPauseState(OGG_FILE_HANDLER_PAUSE_STATE_PLAY); - pause = 0; + pause = false; return true; } } @@ -2069,7 +2069,7 @@ bool sound_stream::set_path(const char* path, bool pause) { state = 1; this->pause = pause; current_volume = sound_stream_volume; - time_seek = 0.0f; + load_time_seek = 0.0f; volume_trans = 0; target_volume = sound_stream_volume; return true; @@ -2078,7 +2078,7 @@ bool sound_stream::set_path(const char* path, bool pause) { bool sound_stream::set_path(const char* path, float_t time, bool pause) { bool res = set_path(path, pause); if (res) - time_seek = time; + load_time_seek = time; return res; } @@ -2088,7 +2088,7 @@ bool sound_stream::set_path_playback() { ogg_playback->SetPauseState(pause ? OGG_FILE_HANDLER_PAUSE_STATE_PAUSE : OGG_FILE_HANDLER_PAUSE_STATE_PLAY); - ogg_playback->SetTimeSeek(time_seek); + ogg_playback->SetLoadTimeSeek(load_time_seek); ogg_playback->SetPath(path); return true; } @@ -2117,7 +2117,7 @@ bool sound_stream::stop_playback() { if (!ogg_playback) return false; - ogg_playback->SetPlaybackState(OGG_FILE_HANDLER_PLAYBACK_STATE_STOP); + ogg_playback->SetPlaybackState(OGG_FILE_HANDLER_PLAYBACK_STATE_UNLOAD); ogg_playback->SetPauseState(OGG_FILE_HANDLER_PAUSE_STATE_PLAY); return true; } diff --git a/src/CRE/sound.hpp b/src/CRE/sound.hpp index f2c4f8f2..3f80c54c 100644 --- a/src/CRE/sound.hpp +++ b/src/CRE/sound.hpp @@ -54,7 +54,7 @@ namespace sound { int32_t bit_depth; Mixer* mixer; std::thread* thread; - lock_uint32_t thread_state; + lock thread_state; AudioFormat format; System(); @@ -94,7 +94,7 @@ namespace sound { struct SEChannel { Mixer* mixer; - lock_uint32_t play_state; + lock play_state; std::mutex mtx; float_t master_volume; float_t channels_volume[4]; @@ -125,8 +125,8 @@ namespace sound { Mixer* mixer; sound_buffer_data* buffer; size_t buffer_size; - lock_uint32_t playing_state; - lock_uint32_t reset_state; + lock playing_state; + lock reset_state; std::mutex mtx; float_t master_volume; float_t channels_volume[4]; @@ -207,8 +207,8 @@ struct SoundCueVolume { }; struct SoundCue { - lock_uint32_t thread_state; - lock_uint32_t data_state; + lock thread_state; + lock data_state; std::thread* thread; std::mutex mtx; std::condition_variable cnd; @@ -219,7 +219,7 @@ struct SoundCue { int32_t counter; float_t release_time; time_struct time; - lock_uint32_t load_state; + lock load_state; sound::wasapi::SEChannel* se_channel; SoundCue(); diff --git a/src/CRE/stage.cpp b/src/CRE/stage.cpp index 5a441965..4b463306 100644 --- a/src/CRE/stage.cpp +++ b/src/CRE/stage.cpp @@ -472,11 +472,11 @@ static bool stage_ctrl(stage* s) { } for (int32_t& i : s->auth_3d_ids) { - auth_3d_data_set_repeat(&i, true); - auth_3d_data_set_paused(&i, false); - auth_3d_data_set_enable(&i, true); - auth_3d_data_set_visibility(&i, s->effect_display); - auth_3d_data_set_frame_rate(&i, 0); + auth_3d_data_set_repeat(i, true); + auth_3d_data_set_paused(i, false); + auth_3d_data_set_enable(i, true); + auth_3d_data_set_visibility(i, s->effect_display); + auth_3d_data_set_frame_rate(i, 0); } return false; } diff --git a/src/CRE/stage_modern.cpp b/src/CRE/stage_modern.cpp index 1c5dc740..46946bad 100644 --- a/src/CRE/stage_modern.cpp +++ b/src/CRE/stage_modern.cpp @@ -452,11 +452,11 @@ static bool stage_modern_ctrl(stage_modern* s, void* data, object_database* obj_ } for (int32_t& i : s->auth_3d_ids) { - auth_3d_data_set_repeat(&i, true); - auth_3d_data_set_paused(&i, false); - auth_3d_data_set_enable(&i, true); - auth_3d_data_set_visibility(&i, s->effect_display); - auth_3d_data_set_frame_rate(&i, 0); + auth_3d_data_set_repeat(i, true); + auth_3d_data_set_paused(i, false); + auth_3d_data_set_enable(i, true); + auth_3d_data_set_visibility(i, s->effect_display); + auth_3d_data_set_frame_rate(i, 0); } return false; } diff --git a/src/CRE/task_effect.cpp b/src/CRE/task_effect.cpp index 5beabd04..89641e4d 100644 --- a/src/CRE/task_effect.cpp +++ b/src/CRE/task_effect.cpp @@ -388,15 +388,15 @@ bool TaskEffectAuth3D::Init() { if (stage.count) { for (int32_t i = 0; i < stage.count; i++) - if (!auth_3d_data_check_id_loaded(&stage.auth_3d_ids_ptr[i])) + if (!auth_3d_data_check_id_loaded(stage.auth_3d_ids_ptr[i])) return false; } for (int32_t i = 0; i < stage.count; i++) { int32_t& id = stage.auth_3d_ids_ptr[i]; - auth_3d_data_set_repeat(&id, true); - auth_3d_data_set_paused(&id, false); - auth_3d_data_set_enable(&id, true); + auth_3d_data_set_repeat(id, true); + auth_3d_data_set_paused(id, false); + auth_3d_data_set_enable(id, true); } //if (field_158) @@ -465,13 +465,13 @@ void TaskEffectAuth3D::SetStageHashes(std::vector& stage_hashes, void* break; id = auth_3d_data_load_hash(j, data, obj_db, tex_db); - if (auth_3d_data_check_id_not_empty(&id)) + if (auth_3d_data_check_id_not_empty(id)) break; } if (id != -1) { - auth_3d_data_read_file_modern(&id); - auth_3d_data_set_visibility(&id, false); + auth_3d_data_read_file_modern(id); + auth_3d_data_set_visibility(id, false); if (stage.count + 1 <= stage.max_count) stage.auth_3d_ids_ptr[stage.count++] = id; v30.auth_3d_ids.push_back(id); @@ -505,13 +505,13 @@ void TaskEffectAuth3D::SetStageIndices(std::vector& stage_indices) { break; id = auth_3d_data_load_uid(j, aft_auth_3d_db); - if (auth_3d_data_check_id_not_empty(&id)) + if (auth_3d_data_check_id_not_empty(id)) break; } if (id != -1) { - auth_3d_data_read_file(&id, aft_auth_3d_db); - auth_3d_data_set_visibility(&id, false); + auth_3d_data_read_file(id, aft_auth_3d_db); + auth_3d_data_set_visibility(id, false); if (stage.count + 1 <= stage.max_count) stage.auth_3d_ids_ptr[stage.count++] = id; v30.auth_3d_ids.push_back(id); @@ -526,13 +526,13 @@ void TaskEffectAuth3D::SetFrame(int32_t value) { double_t frame = (double_t)value; for (int32_t i = 0; i < stage.count; i++) { int32_t& id = stage.auth_3d_ids_ptr[i]; - float_t play_control_size = auth_3d_data_get_play_control_size(&id); + float_t play_control_size = auth_3d_data_get_play_control_size(id); float_t req_frame; if (play_control_size != 0.0f) req_frame = (float_t)fmod(frame, play_control_size); else req_frame = 0.0f; - auth_3d_data_set_req_frame(&id, req_frame); + auth_3d_data_set_req_frame(id, req_frame); } } @@ -557,16 +557,16 @@ void TaskEffectAuth3D::SetCurrentStageIndex(int32_t value) { void TaskEffectAuth3D::SetFrameRateControl(FrameRateControl* value) { for (int32_t i = 0; i < stage.count; i++) { int32_t& id = stage.auth_3d_ids_ptr[i]; - auth_3d_data_set_frame_rate(&id, value); + auth_3d_data_set_frame_rate(id, value); } } void TaskEffectAuth3D::Reset() { for (int32_t i = 0; i < stage.count; i++) { int32_t& id = stage.auth_3d_ids_ptr[i]; - auth_3d_data_set_enable(&id, true); - auth_3d_data_set_paused(&id, false); - auth_3d_data_set_req_frame(&id, 0.0f); + auth_3d_data_set_enable(id, true); + auth_3d_data_set_paused(id, false); + auth_3d_data_set_req_frame(id, 0.0f); } } @@ -595,7 +595,7 @@ void TaskEffectAuth3D::SetVisibility(bool value) { continue; for (int32_t& j : i.auth_3d_ids) - auth_3d_data_set_visibility(&j, value); + auth_3d_data_set_visibility(j, value); break; } else if (current_stage_hash != -1 && current_stage_hash @@ -605,7 +605,7 @@ void TaskEffectAuth3D::SetVisibility(bool value) { continue; for (int32_t& j : i.auth_3d_ids) - auth_3d_data_set_visibility(&j, value); + auth_3d_data_set_visibility(j, value); break; } } diff --git a/src/CRE/timer.hpp b/src/CRE/timer.hpp index 3663f3da..89fe445d 100644 --- a/src/CRE/timer.hpp +++ b/src/CRE/timer.hpp @@ -24,7 +24,7 @@ struct timer { waitable_timer wait_timer; timer(double_t freq); - virtual ~timer(); + ~timer(); void start_of_cycle(); void end_of_cycle(); diff --git a/src/DivaGL/bone_data.cpp b/src/DivaGL/bone_data.cpp index 3599bab5..edcb4969 100644 --- a/src/DivaGL/bone_data.cpp +++ b/src/DivaGL/bone_data.cpp @@ -2529,7 +2529,7 @@ static void mot_key_data_interpolate(mot_key_data* a1, float_t frame, } static bool motion_blend_mot_interpolate_get_reverse(int32_t* a1) { - return *a1 & 0x01 && ~*a1 & 0x08 || ~*a1 & 0x01 && *a1 & 0x08; + return *a1 & 0x01 && !(*a1 & 0x08) || !(*a1 & 0x01) && *a1 & 0x08; } static void sub_140415430(motion_blend_mot* a1) { @@ -2938,7 +2938,7 @@ void rob_chara_bone_data_interpolate(rob_chara_bone_data* rob_bone_data) { static void sub_140412E10(motion_blend_mot* a1, int32_t a2) { for (bone_data* i = a1->bone_data.bones.begin; i != a1->bone_data.bones.end; i++) { motion_bone_index v5 = i->motion_bone_index; - if (~a1->field_0.field_8.bitfield.begin[v5 >> 5] & (1 << (v5 & 0x1F))) + if (!(a1->field_0.field_8.bitfield.begin[v5 >> 5] & (1 << (v5 & 0x1F)))) continue; sub_1401EB1D0(i, a2); diff --git a/src/KKdLib/a3da.cpp b/src/KKdLib/a3da.cpp index a5cf13b4..7ffaa1b7 100644 --- a/src/KKdLib/a3da.cpp +++ b/src/KKdLib/a3da.cpp @@ -2769,7 +2769,7 @@ static void a3dc_read_a3da_key_f16(void* data, size_t size, a3da_key* value, a3d } return; } - else if (~value->flags & A3DA_KEY_BIN_OFFSET) + else if (!(value->flags & A3DA_KEY_BIN_OFFSET)) return; a3dc_key_header* head = (a3dc_key_header*)((size_t)data + value->bin_offset); @@ -2924,7 +2924,7 @@ static void a3dc_write_a3da_key_f16(stream& s, a3da_key& value, a3da_compress_f1 static void a3dc_read_a3da_model_transform(void* data, size_t size, a3da_model_transform* value, a3da_compress_f16 f16) { - if (~value->flags & A3DA_MODEL_TRANSFORM_BIN_OFFSET) + if (!(value->flags & A3DA_MODEL_TRANSFORM_BIN_OFFSET)) return; a3da_model_transform_header* head = (a3da_model_transform_header*)((size_t)data + value->bin_offset); diff --git a/src/KKdLib/a3da.hpp b/src/KKdLib/a3da.hpp index f7d83d87..04e128fe 100644 --- a/src/KKdLib/a3da.hpp +++ b/src/KKdLib/a3da.hpp @@ -508,7 +508,7 @@ struct a3da { a3da_post_process post_process; a3da(); - virtual ~a3da(); + ~a3da(); void read(const char* path); void read(const wchar_t* path); diff --git a/src/KKdLib/aet.hpp b/src/KKdLib/aet.hpp index cb7c3beb..4e6f1b26 100644 --- a/src/KKdLib/aet.hpp +++ b/src/KKdLib/aet.hpp @@ -269,7 +269,7 @@ struct aet_set { std::vector scenes; aet_set(); - virtual ~aet_set(); + ~aet_set(); void pack_file(void** data, size_t* size); void unpack_file(const void* data, size_t size, bool modern); diff --git a/src/KKdLib/alloc_data.hpp b/src/KKdLib/alloc_data.hpp index 17215ec7..068fcede 100644 --- a/src/KKdLib/alloc_data.hpp +++ b/src/KKdLib/alloc_data.hpp @@ -32,6 +32,28 @@ struct alloc_data { template inline T* allocate(size_t size) { + if (!size) + return 0; + return new((T*)allocate(sizeof(T) * size)) T; } + + template + inline T* allocate(const T* src) { + if (!src) + return 0; + + return new((T*)allocate(sizeof(T))) T(*src); + } + + template + inline T* allocate(const T* src, size_t size) { + if (!src || !size) + return 0; + + T* dst = (T*)allocate(sizeof(T) * size); + for (size_t i = 0; i < size; i++) + new(&dst[i]) T(src[i]); + return dst; + } }; diff --git a/src/KKdLib/database/item_table.cpp b/src/KKdLib/database/item_table.cpp index 2d7fd82c..9e08d5b2 100644 --- a/src/KKdLib/database/item_table.cpp +++ b/src/KKdLib/database/item_table.cpp @@ -477,7 +477,7 @@ static void itm_table_read_text(itm_table* itm_tbl, void* data, size_t size) { kv.read("tex", col.tex); kv.read("flag", col.flag); - if (~col.flag & 0x01) { + if (!(col.flag & 0x01)) { vidc.push_back(col); kv.close_scope(); continue; diff --git a/src/KKdLib/dds.cpp b/src/KKdLib/dds.cpp index 39fae724..6fb8f9e0 100644 --- a/src/KKdLib/dds.cpp +++ b/src/KKdLib/dds.cpp @@ -198,7 +198,7 @@ void dds::read(const wchar_t* path) { goto End; else if (!(dds_h.caps & DDS_SURFACE_FLAGS_TEXTURE)) goto End; - else if ((dds_h.caps2 & DDS_CUBE_MAP) && (~dds_h.caps2 & DDS_CUBE_MAP_ALLFACES) || (dds_h.flags & DDS_FLAGS_VOLUME)) + else if ((dds_h.caps2 & DDS_CUBE_MAP) && !(dds_h.caps2 & DDS_CUBE_MAP_ALLFACES) || (dds_h.flags & DDS_FLAGS_VOLUME)) goto End; bool reverse = false; diff --git a/src/KKdLib/default.cpp b/src/KKdLib/default.cpp index 799ae375..d2bff2bd 100644 --- a/src/KKdLib/default.cpp +++ b/src/KKdLib/default.cpp @@ -31,7 +31,7 @@ wchar_t* utf8_to_utf16(const char* s) { size_t l = 0; while (*s) { char t = *s++; - if (~t & 0x80) { + if (!(t & 0x80)) { l = 0; str[j++] = t; c = 0; @@ -139,7 +139,7 @@ std::wstring utf8_to_utf16(const std::string& s) { size_t l = 0; while (*_s) { char t = *_s++; - if (~t & 0x80) { + if (!(t & 0x80)) { l = 0; *_str++ = t; c = 0; diff --git a/src/KKdLib/default.hpp b/src/KKdLib/default.hpp index a25bae7c..a859cff8 100644 --- a/src/KKdLib/default.hpp +++ b/src/KKdLib/default.hpp @@ -339,7 +339,7 @@ inline constexpr size_t utf8_to_utf16_length(const char* s) { while (*s) { char t = *s++; - if (~t & 0x80) { + if (!(t & 0x80)) { l = 0; length++; c = 0; diff --git a/src/KKdLib/farc.hpp b/src/KKdLib/farc.hpp index 52922bed..d107924c 100644 --- a/src/KKdLib/farc.hpp +++ b/src/KKdLib/farc.hpp @@ -63,7 +63,7 @@ struct farc { bool ft; farc(); - virtual ~farc(); + ~farc(); farc_file* add_file(const char* name); farc_file* add_file(const wchar_t* name); diff --git a/src/KKdLib/hash.cpp b/src/KKdLib/hash.cpp index 67afb569..ce5fb25b 100644 --- a/src/KKdLib/hash.cpp +++ b/src/KKdLib/hash.cpp @@ -49,61 +49,6 @@ const uint32_t hash_murmurhash_null = 0x5A009B23; // Empty string const uint32_t hash_crc16_ccitt_empty = 0xFFFF; -string_hash::string_hash() { - hash_fnv1a64m = hash_fnv1a64m_empty; - hash_murmurhash = hash_murmurhash_empty; -} - -string_hash::string_hash(const char* str) { - this->str.assign(str); - this->hash_fnv1a64m = hash_string_fnv1a64m(this->str); - this->hash_murmurhash = hash_string_murmurhash(this->str); -} - -string_hash::string_hash(std::string& str) { - this->str.assign(str); - this->hash_fnv1a64m = hash_string_fnv1a64m(this->str); - this->hash_murmurhash = hash_string_murmurhash(this->str); -} - -string_hash::string_hash(std::string&& str) { - this->str.assign(str); - this->hash_fnv1a64m = hash_string_fnv1a64m(this->str); - this->hash_murmurhash = hash_string_murmurhash(this->str); -} - -string_hash::~string_hash() { - -} - -const char* string_hash::c_str() { - return str.c_str(); -} - -void string_hash::assign(const char* str) { - this->str.assign(str); - this->hash_fnv1a64m = hash_string_fnv1a64m(this->str); - this->hash_murmurhash = hash_string_murmurhash(this->str); -} - -void string_hash::assign(std::string& str) { - this->str.assign(str); - this->hash_fnv1a64m = hash_string_fnv1a64m(this->str); - this->hash_murmurhash = hash_string_murmurhash(this->str); -} - -void string_hash::assign(std::string&& str) { - this->str.assign(str); - this->hash_fnv1a64m = hash_string_fnv1a64m(this->str); - this->hash_murmurhash = hash_string_murmurhash(this->str); -} - -void string_hash::assign(string_hash& str) { - this->str.assign(str.str); - this->hash_fnv1a64m = hash_string_fnv1a64m(this->str); - this->hash_murmurhash = hash_string_murmurhash(this->str); -} - // FNV 1a 64-bit Modified // 0x1403B04D0 in SBZV_7.10 uint64_t hash_fnv1a64m(const void* data, size_t size, bool make_upper) { diff --git a/src/KKdLib/hash.hpp b/src/KKdLib/hash.hpp index 409917d0..4e3071f3 100644 --- a/src/KKdLib/hash.hpp +++ b/src/KKdLib/hash.hpp @@ -17,24 +17,6 @@ extern const uint32_t hash_murmurhash_null; // Empty string extern const uint32_t hash_crc16_ccitt_empty; -struct string_hash { - std::string str; - uint64_t hash_fnv1a64m; - uint32_t hash_murmurhash; - - string_hash(); - string_hash(const char* str); - string_hash(std::string& str); - string_hash(std::string&& str); - ~string_hash(); - - const char* c_str(); - void assign(const char* str); - void assign(std::string& str); - void assign(std::string&& str); - void assign(string_hash& str); -}; - extern uint64_t hash_fnv1a64m(const void* data, size_t size, bool make_upper = false); extern uint32_t hash_murmurhash(const void* data, size_t size, uint32_t seed = 0, bool upper = false, bool big_endian = false); @@ -84,3 +66,113 @@ inline uint16_t hash_utf16_crc16_ccitt(const wchar_t* data, bool make_upper = fa inline uint16_t hash_string_crc16_ccitt(const std::string& data, bool make_upper = false) { return hash_crc16_ccitt(data.c_str(), data.size(), make_upper); } + +struct string_hash { + std::string str; + uint64_t hash_fnv1a64m; + uint32_t hash_murmurhash; + + inline string_hash() { + hash_fnv1a64m = hash_fnv1a64m_empty; + hash_murmurhash = hash_murmurhash_empty; + } + + inline string_hash(const char* str) { + this->str.assign(str); + this->hash_fnv1a64m = hash_string_fnv1a64m(this->str); + this->hash_murmurhash = hash_string_murmurhash(this->str); + } + + inline string_hash(const char* str, size_t length) { + this->str.assign(str, length); + this->hash_fnv1a64m = hash_string_fnv1a64m(this->str); + this->hash_murmurhash = hash_string_murmurhash(this->str); + } + + inline string_hash(std::string& str) { + this->str.assign(str); + this->hash_fnv1a64m = hash_string_fnv1a64m(this->str); + this->hash_murmurhash = hash_string_murmurhash(this->str); + } + + inline string_hash(std::string&& str) { + this->str.assign(str); + this->hash_fnv1a64m = hash_string_fnv1a64m(this->str); + this->hash_murmurhash = hash_string_murmurhash(this->str); + } + + inline ~string_hash() { + + } + + inline const char* c_str() { + return str.c_str(); + } + + inline void append(const char* str) { + this->str.append(str); + this->hash_fnv1a64m = hash_string_fnv1a64m(this->str); + this->hash_murmurhash = hash_string_murmurhash(this->str); + } + + inline void append(const char* str, size_t length) { + this->str.append(str, length); + this->hash_fnv1a64m = hash_string_fnv1a64m(this->str); + this->hash_murmurhash = hash_string_murmurhash(this->str); + } + + inline void append(std::string& str) { + this->str.append(str); + this->hash_fnv1a64m = hash_string_fnv1a64m(this->str); + this->hash_murmurhash = hash_string_murmurhash(this->str); + } + + inline void append(std::string&& str) { + this->str.append(str); + this->hash_fnv1a64m = hash_string_fnv1a64m(this->str); + this->hash_murmurhash = hash_string_murmurhash(this->str); + } + + inline void append(string_hash& str) { + this->str.append(str.str); + this->hash_fnv1a64m = hash_string_fnv1a64m(this->str); + this->hash_murmurhash = hash_string_murmurhash(this->str); + } + + inline void assign(const char* str) { + this->str.assign(str); + this->hash_fnv1a64m = hash_string_fnv1a64m(this->str); + this->hash_murmurhash = hash_string_murmurhash(this->str); + } + + inline void assign(const char* str, size_t length) { + this->str.assign(str, length); + this->hash_fnv1a64m = hash_string_fnv1a64m(this->str); + this->hash_murmurhash = hash_string_murmurhash(this->str); + } + + inline void assign(std::string& str) { + this->str.assign(str); + this->hash_fnv1a64m = hash_string_fnv1a64m(this->str); + this->hash_murmurhash = hash_string_murmurhash(this->str); + } + + inline void assign(std::string&& str) { + this->str.assign(str); + this->hash_fnv1a64m = hash_string_fnv1a64m(this->str); + this->hash_murmurhash = hash_string_murmurhash(this->str); + } + + inline void assign(string_hash& str) { + this->str.assign(str.str); + this->hash_fnv1a64m = hash_string_fnv1a64m(this->str); + this->hash_murmurhash = hash_string_murmurhash(this->str); + } + + inline void clear() { + str.clear(); + str.shrink_to_fit(); + hash_fnv1a64m = hash_fnv1a64m_empty; + hash_murmurhash = hash_murmurhash_empty; + } +}; diff --git a/src/KKdLib/io/path.cpp b/src/KKdLib/io/path.cpp index e3ac82eb..7c9dd396 100644 --- a/src/KKdLib/io/path.cpp +++ b/src/KKdLib/io/path.cpp @@ -141,9 +141,8 @@ std::vector path_get_directories( std::vector directories; do { - if (~fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) - continue; - else if (!str_utils_compare(fdata.cFileName, L".") + if (!(fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + || !str_utils_compare(fdata.cFileName, L".") || !str_utils_compare(fdata.cFileName, L"..")) continue; @@ -192,9 +191,8 @@ std::vector path_get_directories( std::vector directories; do { - if (~fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) - continue; - else if (!str_utils_compare(fdata.cFileName, L".") + if (!(fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + || !str_utils_compare(fdata.cFileName, L".") || !str_utils_compare(fdata.cFileName, L"..")) continue; @@ -243,9 +241,8 @@ std::vector path_get_directories_recursive( std::vector temp_vec; do { - if (~fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) - continue; - else if (!str_utils_compare(fdata.cFileName, L".") + if (!(fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + || !str_utils_compare(fdata.cFileName, L".") || !str_utils_compare(fdata.cFileName, L"..")) continue; @@ -331,9 +328,8 @@ std::vector path_get_directories_recursive( std::vector temp_vec; do { - if (~fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) - continue; - else if (!str_utils_compare(fdata.cFileName, L".") + if (!(fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + || !str_utils_compare(fdata.cFileName, L".") || !str_utils_compare(fdata.cFileName, L"..")) continue; diff --git a/src/KKdLib/key_val.hpp b/src/KKdLib/key_val.hpp index bf53b669..d274149b 100644 --- a/src/KKdLib/key_val.hpp +++ b/src/KKdLib/key_val.hpp @@ -50,7 +50,7 @@ struct key_val { char* buf; key_val(); - virtual ~key_val(); + ~key_val(); void close_scope(); void file_read(const char* path); diff --git a/src/KKdLib/mat.cpp b/src/KKdLib/mat.cpp index 8392aaaf..c88c7415 100644 --- a/src/KKdLib/mat.cpp +++ b/src/KKdLib/mat.cpp @@ -657,15 +657,15 @@ inline float_t mat3_get_max_scale(const mat3* x) { return max; } -inline void mat3_mult_axis_angle(const mat3* src, mat3* dst, const vec3* axis, const float_t angle) { +inline void mat3_mult_axis_angle(const mat3* x, const vec3* axis, const float_t angle, mat3* z) { quat q1; quat q2; quat q3; - quat_from_mat3(src->row0.x, src->row1.x, src->row2.x, src->row0.y, - src->row1.y, src->row2.y, src->row0.z, src->row1.z, src->row2.z, &q1); + quat_from_mat3(x->row0.x, x->row1.x, x->row2.x, x->row0.y, + x->row1.y, x->row2.y, x->row0.z, x->row1.z, x->row2.z, &q1); quat_from_axis_angle(axis, angle, &q2); quat_mult(&q2, &q1, &q3); - mat3_from_quat(&q3, dst); + mat3_from_quat(&q3, z); } inline void mat4_add(const mat4* x, const mat4* y, mat4* z) { @@ -1722,17 +1722,17 @@ inline void mat4_blend_rotation(const mat4* x, const mat4* y, mat4* z, float_t b mat4_from_quat(&q2, z); } -void mat4_lerp_rotation(mat4* dst, const mat4* src0, const mat4* src1, float_t blend) { +void mat4_lerp_rotation(const mat4* x, const mat4* y, mat4* z, float_t blend) { vec3 m0; vec3 m1; - m0 = vec3::lerp(*(vec3*)&src0->row0, *(vec3*)&src1->row0, blend); - m1 = vec3::lerp(*(vec3*)&src0->row1, *(vec3*)&src1->row1, blend); + m0 = vec3::lerp(*(vec3*)&x->row0, *(vec3*)&y->row0, blend); + m1 = vec3::lerp(*(vec3*)&x->row1, *(vec3*)&y->row1, blend); float_t m0_len_sq = vec3::length_squared(m0); float_t m1_len_sq = vec3::length_squared(m1); if (m0_len_sq <= 0.000001f || m1_len_sq <= 0.000001f) { - *dst = *src1; + *z = *y; return; } @@ -1744,7 +1744,7 @@ void mat4_lerp_rotation(mat4* dst, const mat4* src0, const mat4* src1, float_t b m1_len_sq = vec3::length_squared(m1); m2_len_sq = vec3::length_squared(m2); if (m2_len_sq <= 0.000001f || m1_len_sq <= 0.000001) { - *dst = *src1; + *z = *y; return; } @@ -1760,10 +1760,10 @@ void mat4_lerp_rotation(mat4* dst, const mat4* src0, const mat4* src1, float_t b if (m2_len != 0.0f) m2 *= 1.0f / m2_len; - *dst = mat4_identity; - *(vec3*)&dst->row0 = m0; - *(vec3*)&dst->row1 = m1; - *(vec3*)&dst->row2 = m2; + *z = mat4_identity; + *(vec3*)&z->row0 = m0; + *(vec3*)&z->row1 = m1; + *(vec3*)&z->row2 = m2; } inline float_t mat4_get_max_scale(const mat4* x) { @@ -1784,7 +1784,7 @@ inline float_t mat4_get_max_scale(const mat4* x) { return max; } -inline void mat4_mult_axis_angle(const mat4* src, mat4* dst, const vec3* axis, const float_t angle) { +inline void mat4_mult_axis_angle(const mat4* x, const vec3* axis, const float_t angle, mat4* z) { quat q1; quat q2; quat q3; @@ -1793,19 +1793,19 @@ inline void mat4_mult_axis_angle(const mat4* src, mat4* dst, const vec3* axis, c float_t t2; vec4 t3; - t0 = src->row0.w; - t1 = src->row1.w; - t2 = src->row2.w; - t3 = src->row3; - quat_from_mat3(src->row0.x, src->row1.x, src->row2.x, src->row0.y, - src->row1.y, src->row2.y, src->row0.z, src->row1.z, src->row2.z, &q1); + t0 = x->row0.w; + t1 = x->row1.w; + t2 = x->row2.w; + t3 = x->row3; + quat_from_mat3(x->row0.x, x->row1.x, x->row2.x, x->row0.y, + x->row1.y, x->row2.y, x->row0.z, x->row1.z, x->row2.z, &q1); quat_from_axis_angle(axis, angle, &q2); quat_mult(&q2, &q1, &q3); - mat4_from_quat(&q3, dst); - dst->row0.w = t0; - dst->row1.w = t1; - dst->row2.w = t2; - dst->row3 = t3; + mat4_from_quat(&q3, z); + z->row0.w = t0; + z->row1.w = t1; + z->row2.w = t2; + z->row3 = t3; } inline void mat4_frustrum(double_t left, double_t right, diff --git a/src/KKdLib/mat.hpp b/src/KKdLib/mat.hpp index 668fb333..0fdd5ded 100644 --- a/src/KKdLib/mat.hpp +++ b/src/KKdLib/mat.hpp @@ -86,7 +86,7 @@ extern void mat3_from_mat4_inverse(const mat4* x, mat3* z); extern void mat3_get_rotation(const mat3* x, vec3* z); extern void mat3_get_scale(const mat3* x, vec3* z); extern float_t mat3_get_max_scale(const mat3* x); -extern void mat3_mult_axis_angle(const mat3* src, mat3* dst, const vec3* axis, const float_t angle); +extern void mat3_mult_axis_angle(const mat3* x, const vec3* axis, const float_t angle, mat3* z); extern void mat4_add(const mat4* x, const mat4* y, mat4* z); extern void mat4_sub(const mat4* x, const mat4* y, mat4* z); @@ -157,9 +157,9 @@ extern void mat4_get_translation(const mat4* x, vec3* z); extern void mat4_set_translation(mat4* x, vec3* z); extern void mat4_blend(const mat4* x, const mat4* y, mat4* z, float_t blend); extern void mat4_blend_rotation(const mat4* x, const mat4* y, mat4* z, float_t blend); -extern void mat4_lerp_rotation(mat4* dst, const mat4* src0, const mat4* src1, float_t blend); +extern void mat4_lerp_rotation(const mat4* x, const mat4* y, mat4* z, float_t blend); extern float_t mat4_get_max_scale(const mat4* x); -extern void mat4_mult_axis_angle(const mat4* src, mat4* dst, const vec3* axis, const float_t angle); +extern void mat4_mult_axis_angle(const mat4* x, const vec3* axis, const float_t angle, mat4* z); extern void mat4_frustrum(double_t left, double_t right, double_t bottom, double_t top, double_t z_near, double_t z_far, mat4* mat); extern void mat4_ortho(double_t left, double_t right, diff --git a/src/KKdLib/mot.hpp b/src/KKdLib/mot.hpp index b800c011..8fd97634 100644 --- a/src/KKdLib/mot.hpp +++ b/src/KKdLib/mot.hpp @@ -74,7 +74,7 @@ struct mot_set { std::vector vec; mot_set(); - virtual ~mot_set(); + ~mot_set(); void pack_file(void** data, size_t* size); void unpack_file(const void* data, size_t size, bool modern); diff --git a/src/KKdLib/obj.cpp b/src/KKdLib/obj.cpp index c1c020a8..14ac2e67 100644 --- a/src/KKdLib/obj.cpp +++ b/src/KKdLib/obj.cpp @@ -119,8 +119,44 @@ static void obj_vertex_add_bone_weight(vec4& bone_weight, vec4i& bone_index, int static void obj_vertex_generate_tangents(obj_mesh* mesh); static void obj_vertex_validate_bone_data(vec4& bone_weight, vec4i& bone_index); -static void obj_set_classic_read_inner(obj_set* os, prj::shared_ptr& alloc, stream& s); -static void obj_set_classic_write_inner(obj_set* os, stream& s); +static void obj_move_data(obj* obj_dst, const obj* obj_src, + prj::shared_ptr alloc); +static void obj_move_data_mesh(obj_mesh* mesh_dst, const obj_mesh* mesh_src, + prj::shared_ptr alloc); +static void obj_move_data_sub_mesh(obj_sub_mesh* sub_mesh_dst, const obj_sub_mesh* sub_mesh_src, + prj::shared_ptr alloc); +static obj_skin* obj_move_data_skin(const obj_skin* sk_src, + prj::shared_ptr alloc); +static void obj_move_data_skin_bone(obj_skin_bone* bone_dst, const obj_skin_bone* bone_src, + prj::shared_ptr alloc); +static obj_skin_ex_data* obj_move_data_skin_ex_data(const obj_skin_ex_data* ex_src, + prj::shared_ptr alloc); +static obj_skin_block_cloth* obj_move_data_skin_block_cloth(const obj_skin_block_cloth* cls_src, + prj::shared_ptr alloc); +static void obj_move_data_skin_block_cloth_root(obj_skin_block_cloth_root* cloth_root_dst, + const obj_skin_block_cloth_root* cloth_root_src, + prj::shared_ptr alloc); +static void obj_move_data_skin_block_cloth_root_bone_weight(obj_skin_block_cloth_root_bone_weight* bone_weight_dst, + const obj_skin_block_cloth_root_bone_weight* bone_weight_src, + prj::shared_ptr alloc); +static obj_skin_block_constraint* obj_move_data_skin_block_constraint(const obj_skin_block_constraint* cns_src, + prj::shared_ptr alloc); +static void obj_move_data_skin_block_constraint_up_vector(obj_skin_block_constraint_up_vector* up_vector_dst, + const obj_skin_block_constraint_up_vector* up_vector_src, + prj::shared_ptr alloc); +static obj_skin_block_expression* obj_move_data_skin_block_expression(const obj_skin_block_expression* exp_src, + prj::shared_ptr alloc); +static obj_skin_block_motion* obj_move_data_skin_block_motion(const obj_skin_block_motion* mot_src, + prj::shared_ptr alloc); +static void obj_move_data_skin_block_node(obj_skin_block_node* node_dst, const obj_skin_block_node* node_src, + prj::shared_ptr alloc); +static obj_skin_block_osage* obj_move_data_skin_block_osage(const obj_skin_block_osage* osg_src, + prj::shared_ptr alloc); +static obj_skin_skin_param* obj_move_data_skin_param(const obj_skin_skin_param* skp_src, + prj::shared_ptr alloc); + +static void obj_set_classic_read_inner(obj_set* set, prj::shared_ptr& alloc, stream& s); +static void obj_set_classic_write_inner(obj_set* set, stream& s); static void obj_classic_read_index(obj_sub_mesh* sub_mesh, prj::shared_ptr alloc, stream& s); static void obj_classic_write_index(obj_sub_mesh* sub_mesh, stream& s); static void obj_classic_read_model(obj* obj, prj::shared_ptr alloc, stream& s, int64_t base_offset); @@ -189,8 +225,8 @@ static void obj_classic_write_vertex(obj_mesh* mesh, stream& s, int64_t* vertex, int64_t base_offset, uint32_t* num_vertex, obj_vertex_format_file* vertex_format_file, uint32_t* size_vertex); -static void obj_set_modern_read_inner(obj_set* os, prj::shared_ptr& alloc, stream& s); -static void obj_set_modern_write_inner(obj_set* os, stream& s); +static void obj_set_modern_read_inner(obj_set* set, prj::shared_ptr& alloc, stream& s); +static void obj_set_modern_write_inner(obj_set* set, stream& s); static void obj_modern_read_index(obj_sub_mesh* sub_mesh, prj::shared_ptr alloc, stream& s); static void obj_modern_write_index(obj_sub_mesh* sub_mesh, stream& s, bool is_x, f2_struct* ovtx); static void obj_modern_read_model(obj* obj, prj::shared_ptr alloc, stream& s, int64_t base_offset, @@ -215,6 +251,10 @@ static void obj_modern_write_skin_block_cloth(obj_skin_block_cloth* cls, stream& s, std::vector& strings, std::vector& string_offsets, bool is_x, int64_t* mat_array_offset, int64_t* root_array_offset, int64_t* node_array_offset, int64_t* mesh_index_array_offset, int64_t* backface_mesh_index_array_offset); +static void obj_modern_read_skin_block_cloth_root(obj_skin_block_cloth_root* cloth_root, + prj::shared_ptr alloc, stream& s, uint32_t header_length, const char** str, bool is_x); +static void obj_modern_write_skin_block_cloth_root(obj_skin_block_cloth_root* cloth_root, + stream& s, std::vector& strings, std::vector& string_offsets, bool is_x); static void obj_modern_read_skin_block_cloth_root_bone_weight(obj_skin_block_cloth_root_bone_weight* bone_weight, prj::shared_ptr alloc, stream& s, uint32_t header_length, const char** str, bool is_x); static void obj_modern_write_skin_block_cloth_root_bone_weight(obj_skin_block_cloth_root_bone_weight* bone_weight, @@ -255,6 +295,9 @@ static void obj_modern_read_vertex(obj_mesh* mesh, prj::shared_ptr a static void obj_modern_write_vertex(obj_mesh* mesh, stream& s, int64_t* vertex, uint32_t* vertex_format_index, uint32_t* num_vertex, uint32_t* size_vertex, f2_struct* ovtx); +static const char* obj_move_data_string(const char* str, + prj::shared_ptr& alloc); + static const char* obj_read_utf8_string_null_terminated_offset( prj::shared_ptr& alloc, stream& s, int64_t offset); @@ -466,6 +509,37 @@ obj_num(), tex_id_data(), tex_id_num(), reserved() { } +void obj_set::move_data(obj_set* set_src, prj::shared_ptr alloc) { + if (!set_src->ready) { + ready = false; + modern = false; + big_endian = false; + is_x = false; + return; + } + + ready = true; + modern = set_src->modern; + big_endian = set_src->big_endian; + is_x = set_src->is_x; + + uint32_t obj_num = set_src->obj_num; + obj* obj_data_src = set_src->obj_data; + obj* obj_data_dst = alloc->allocate(obj_num); + + for (uint32_t i = 0; i < obj_num; i++) + obj_move_data(&obj_data_dst[i], &obj_data_src[i], alloc); + + this->obj_data = obj_data_dst; + this->obj_num = obj_num; + + uint32_t tex_id_num = set_src->tex_id_num; + this->tex_id_data = alloc->allocate(set_src->tex_id_data, tex_id_num); + this->tex_id_num = tex_id_num; + + memcpy(this->reserved, set_src->reserved, sizeof(uint32_t) * 2); +} + void obj_set::pack_file(void** data, size_t* size) { if (!data || !ready) return; @@ -558,9 +632,9 @@ static void calculate_tangent(obj_vertex_data* vtx, } static void obj_vertex_generate_tangents(obj_mesh* mesh) { - if (~mesh->vertex_format & OBJ_VERTEX_NORMAL + if (!(mesh->vertex_format & OBJ_VERTEX_NORMAL) || mesh->vertex_format & OBJ_VERTEX_TANGENT - || ~mesh->vertex_format & OBJ_VERTEX_TEXCOORD0) + || !(mesh->vertex_format & OBJ_VERTEX_TEXCOORD0)) return; uint32_t num_vertex = mesh->num_vertex; @@ -711,30 +785,433 @@ static void obj_vertex_validate_bone_data(vec4& bone_weight, vec4i& bone_index) bone_index = _bone_index; } -static void obj_set_classic_read_inner(obj_set* os, prj::shared_ptr& alloc, stream& s) { +static void obj_move_data(obj* obj_dst, const obj* obj_src, + prj::shared_ptr alloc) { + obj_dst->bounding_sphere = obj_src->bounding_sphere; + + uint32_t num_mesh = obj_src->num_mesh; + obj_mesh* mesh_array_src = obj_src->mesh_array; + obj_mesh* mesh_array_dst = alloc->allocate(num_mesh); + + for (uint32_t i = 0; i < num_mesh; i++) + obj_move_data_mesh(&mesh_array_dst[i], &mesh_array_src[i], alloc); + + obj_dst->mesh_array = mesh_array_dst; + obj_dst->num_mesh = num_mesh; + + uint32_t num_material = obj_src->num_material; + obj_dst->material_array = alloc->allocate(obj_src->material_array, num_material); + obj_dst->num_material = num_material; + + obj_dst->flags = obj_src->flags; + memcpy(obj_dst->reserved, obj_src->reserved, sizeof(uint32_t) * 10); + + obj_dst->skin = obj_move_data_skin(obj_src->skin, alloc); + + obj_dst->name = obj_move_data_string(obj_src->name, alloc); + obj_dst->id = obj_src->id; + obj_dst->hash = obj_src->hash; +} + +static void obj_move_data_mesh(obj_mesh* mesh_dst, const obj_mesh* mesh_src, + prj::shared_ptr alloc) { + mesh_dst->flags = mesh_src->flags; + mesh_dst->bounding_sphere = mesh_src->bounding_sphere; + + uint32_t num_submesh = mesh_src->num_submesh; + obj_sub_mesh* submesh_array_src = mesh_src->submesh_array; + obj_sub_mesh* submesh_array_dst = alloc->allocate(num_submesh); + + for (uint32_t i = 0; i < num_submesh; i++) + obj_move_data_sub_mesh(&submesh_array_dst[i], &submesh_array_src[i], alloc); + + mesh_dst->submesh_array = submesh_array_dst; + mesh_dst->num_submesh = num_submesh; + + mesh_dst->vertex_format = mesh_src->vertex_format; + mesh_dst->size_vertex = mesh_src->size_vertex; + + uint32_t num_vertex = mesh_src->num_vertex; + mesh_dst->vertex_array = alloc->allocate(mesh_src->vertex_array, num_vertex); + mesh_dst->num_vertex = num_vertex; + + mesh_dst->attrib = mesh_src->attrib; + memcpy(mesh_dst->reserved, mesh_src->reserved, sizeof(uint32_t) * 6); + memcpy(mesh_dst->name, mesh_src->name, 0x40); +} + +static void obj_move_data_sub_mesh(obj_sub_mesh* sub_mesh_dst, const obj_sub_mesh* sub_mesh_src, + prj::shared_ptr alloc) { + sub_mesh_dst->flags = sub_mesh_src->flags; + sub_mesh_dst->bounding_sphere = sub_mesh_src->bounding_sphere; + sub_mesh_dst->material_index = sub_mesh_src->material_index; + memcpy(sub_mesh_dst->uv_index, sub_mesh_src->uv_index, 8); + + uint32_t num_bone_index = sub_mesh_src->num_bone_index; + sub_mesh_dst->bone_index_array = alloc->allocate(sub_mesh_src->bone_index_array, num_bone_index); + sub_mesh_dst->num_bone_index = num_bone_index; + + sub_mesh_dst->bones_per_vertex = sub_mesh_src->bones_per_vertex; + sub_mesh_dst->primitive_type = sub_mesh_src->primitive_type; + sub_mesh_dst->index_format = sub_mesh_src->index_format; + + uint32_t num_index = sub_mesh_src->num_index; + sub_mesh_dst->index_array = alloc->allocate(sub_mesh_src->index_array, num_index); + sub_mesh_dst->num_index = num_index; + + sub_mesh_dst->attrib = sub_mesh_src->attrib; + sub_mesh_dst->bounding_box = sub_mesh_src->bounding_box; + + sub_mesh_dst->first_index = sub_mesh_src->first_index; + sub_mesh_dst->last_index = sub_mesh_src->last_index; + sub_mesh_dst->index_offset = sub_mesh_src->index_offset; +} + +static obj_skin* obj_move_data_skin(const obj_skin* sk_src, + prj::shared_ptr alloc) { + if (!sk_src) + return 0; + + obj_skin* sk_dst = alloc->allocate(); + + uint32_t num_bone = sk_src->num_bone; + obj_skin_bone* bone_array_src = sk_src->bone_array; + obj_skin_bone* bone_array_dst = alloc->allocate(num_bone); + + for (uint32_t i = 0; i < num_bone; i++) + obj_move_data_skin_bone(&bone_array_dst[i], &bone_array_src[i], alloc); + + sk_dst->bone_array = bone_array_dst; + sk_dst->num_bone = num_bone; + + sk_dst->ex_data = obj_move_data_skin_ex_data(sk_src->ex_data, alloc); + return sk_dst; +} + +static void obj_move_data_skin_bone(obj_skin_bone* bone_dst, const obj_skin_bone* bone_src, + prj::shared_ptr alloc) { + bone_dst->id = bone_src->id; + bone_dst->parent = bone_src->parent; + bone_dst->inv_bind_pose_mat = bone_src->inv_bind_pose_mat; + bone_dst->name = obj_move_data_string(bone_src->name, alloc); +} + +static obj_skin_ex_data* obj_move_data_skin_ex_data(const obj_skin_ex_data* ex_src, + prj::shared_ptr alloc) { + obj_skin_ex_data* ex_dst = alloc->allocate(); + + uint32_t num_osage_node = ex_src->num_osage_node; + ex_dst->osage_node_array = alloc->allocate( + ex_src->osage_node_array, num_osage_node); + ex_dst->num_osage_node = num_osage_node; + + uint32_t num_block = ex_src->num_block; + obj_skin_block* block_array_src = ex_src->block_array; + obj_skin_block* block_array_dst = alloc->allocate(num_block); + + for (uint32_t i = 0; i < num_block; i++) { + obj_skin_block* block_src = &block_array_src[i]; + obj_skin_block* block_dst = &block_array_dst[i]; + switch (block_src->type) { + default: + block_dst->type = OBJ_SKIN_BLOCK_NONE; + block_dst->node = 0; + break; + case OBJ_SKIN_BLOCK_CLOTH: + block_dst->type = OBJ_SKIN_BLOCK_CLOTH; + block_dst->cloth = obj_move_data_skin_block_cloth(block_src->cloth, alloc); + break; + case OBJ_SKIN_BLOCK_CONSTRAINT: + block_dst->type = OBJ_SKIN_BLOCK_CONSTRAINT; + block_dst->constraint = obj_move_data_skin_block_constraint(block_src->constraint, alloc); + break; + case OBJ_SKIN_BLOCK_EXPRESSION: + block_dst->type = OBJ_SKIN_BLOCK_EXPRESSION; + block_dst->expression = obj_move_data_skin_block_expression(block_src->expression, alloc); + break; + case OBJ_SKIN_BLOCK_MOTION: + block_dst->type = OBJ_SKIN_BLOCK_MOTION; + block_dst->motion = obj_move_data_skin_block_motion(block_src->motion, alloc); + break; + case OBJ_SKIN_BLOCK_OSAGE: + block_dst->type = OBJ_SKIN_BLOCK_OSAGE; + block_dst->osage = obj_move_data_skin_block_osage(block_src->osage, alloc); + break; + } + } + + ex_dst->block_array = block_array_dst; + ex_dst->num_block = num_block; + + uint32_t num_bone_name = ex_src->num_bone_name; + const char** bone_array_src = ex_src->bone_name_array; + const char** bone_array_dst = alloc->allocate(num_bone_name); + + for (uint32_t i = 0; i < num_bone_name; i++) + bone_array_dst[i] = obj_move_data_string(bone_array_src[i], alloc); + + ex_dst->bone_name_array = bone_array_dst; + ex_dst->num_bone_name = num_bone_name; + + uint32_t num_osage_sibling_info = ex_src->num_osage_sibling_info; + ex_dst->osage_sibling_info_array = alloc->allocate( + ex_src->osage_sibling_info_array, num_osage_sibling_info); + ex_dst->num_osage_sibling_info = num_osage_sibling_info; + + memcpy(ex_dst->reserved, ex_src->reserved, sizeof(int64_t) * 7); + return ex_dst; +} + +static obj_skin_block_cloth* obj_move_data_skin_block_cloth(const obj_skin_block_cloth* cls_src, + prj::shared_ptr alloc) { + obj_skin_block_cloth* cls_dst = alloc->allocate(); + cls_dst->mesh_name = obj_move_data_string(cls_src->mesh_name, alloc); + cls_dst->backface_mesh_name = obj_move_data_string(cls_src->backface_mesh_name, alloc); + cls_dst->field_8 = cls_src->field_8; + + uint32_t num_root = cls_src->num_root; + uint32_t num_node = cls_src->num_node; + cls_dst->num_root = num_root; + cls_dst->num_node = num_node; + cls_dst->field_14 = cls_src->field_14; + + uint32_t num_mat = cls_src->num_mat; + cls_dst->mat_array = alloc->allocate(cls_src->mat_array, num_mat); + cls_dst->num_mat = num_mat; + + obj_skin_block_cloth_root* root_array_src = cls_src->root_array; + obj_skin_block_cloth_root* root_array_dst = alloc->allocate(num_root); + + for (uint32_t i = 0; i < num_root; i++) + obj_move_data_skin_block_cloth_root(&root_array_dst[i], &root_array_src[i], alloc); + + cls_dst->root_array = root_array_dst; + + cls_dst->node_array = alloc->allocate( + cls_src->node_array, num_root * (num_node - 1ULL)); + + uint32_t num_mesh_index = cls_src->num_mesh_index; + cls_dst->mesh_index_array = alloc->allocate( + cls_src->mesh_index_array, num_mesh_index); + cls_dst->num_mesh_index = num_mesh_index; + + uint32_t num_backface_mesh_index = cls_src->num_backface_mesh_index; + cls_dst->backface_mesh_index_array = alloc->allocate( + cls_src->backface_mesh_index_array, num_backface_mesh_index); + cls_dst->num_backface_mesh_index = num_backface_mesh_index; + + cls_dst->skin_param = obj_move_data_skin_param(cls_src->skin_param, alloc); + cls_dst->reserved = cls_src->reserved; + return cls_dst; +} + +static void obj_move_data_skin_block_cloth_root(obj_skin_block_cloth_root* cloth_root_dst, + const obj_skin_block_cloth_root* cloth_root_src, + prj::shared_ptr alloc) { + cloth_root_dst->trans = cloth_root_src->trans; + cloth_root_dst->normal = cloth_root_src->normal; + cloth_root_dst->field_18 = cloth_root_src->field_18; + cloth_root_dst->field_1C = cloth_root_src->field_1C; + cloth_root_dst->field_20 = cloth_root_src->field_20; + cloth_root_dst->field_24 = cloth_root_src->field_24; + + for (uint32_t i = 0; i < 4; i++) + obj_move_data_skin_block_cloth_root_bone_weight(&cloth_root_dst->bone_weights[i], + &cloth_root_src->bone_weights[i], alloc); +} + +static void obj_move_data_skin_block_cloth_root_bone_weight(obj_skin_block_cloth_root_bone_weight* bone_weight_dst, + const obj_skin_block_cloth_root_bone_weight* bone_weight_src, + prj::shared_ptr alloc) { + bone_weight_dst->bone_name = obj_move_data_string(bone_weight_src->bone_name, alloc); + bone_weight_dst->weight = bone_weight_src->weight; + bone_weight_dst->matrix_index = bone_weight_src->matrix_index; + bone_weight_dst->reserved = bone_weight_src->reserved; +} + +static obj_skin_block_constraint* obj_move_data_skin_block_constraint(const obj_skin_block_constraint* cns_src, + prj::shared_ptr alloc) { + obj_skin_block_constraint* cns_dst = alloc->allocate(); + obj_move_data_skin_block_node(&cns_dst->node, &cns_src->node, alloc); + cns_dst->name_index = cns_src->name_index; + cns_dst->source_node_name = obj_move_data_string(cns_src->source_node_name, alloc); + cns_dst->coupling = cns_src->coupling; + + switch (cns_src->type) { + case OBJ_SKIN_BLOCK_CONSTRAINT_ORIENTATION: { + cns_dst->type = OBJ_SKIN_BLOCK_CONSTRAINT_ORIENTATION; + + obj_skin_block_constraint_orientation* orientation_src = cns_src->orientation; + obj_skin_block_constraint_orientation* orientation_dst + = alloc->allocate(); + orientation_dst->offset = orientation_src->offset; + cns_dst->orientation = orientation_dst; + } break; + case OBJ_SKIN_BLOCK_CONSTRAINT_DIRECTION: { + cns_dst->type = OBJ_SKIN_BLOCK_CONSTRAINT_DIRECTION; + + obj_skin_block_constraint_direction* direction_src = cns_src->direction; + obj_skin_block_constraint_direction* direction_dst + = alloc->allocate(); + obj_move_data_skin_block_constraint_up_vector( + &direction_dst->up_vector, &direction_src->up_vector, alloc); + direction_dst->align_axis = direction_src->align_axis; + direction_dst->target_offset = direction_src->target_offset; + cns_dst->direction = direction_dst; + } break; + case OBJ_SKIN_BLOCK_CONSTRAINT_POSITION: { + cns_dst->type = OBJ_SKIN_BLOCK_CONSTRAINT_POSITION; + + obj_skin_block_constraint_position* position_src = cns_src->position; + obj_skin_block_constraint_position* position_dst + = alloc->allocate(); + obj_move_data_skin_block_constraint_up_vector( + &position_dst->up_vector, &position_src->up_vector, alloc); + position_dst->constrained_object = position_src->constrained_object; + position_dst->constraining_object = position_src->constraining_object; + cns_dst->position = position_dst; + } break; + case OBJ_SKIN_BLOCK_CONSTRAINT_DISTANCE: { + cns_dst->type = OBJ_SKIN_BLOCK_CONSTRAINT_DISTANCE; + + obj_skin_block_constraint_distance* distance_src = cns_src->distance; + obj_skin_block_constraint_distance* distance_dst + = alloc->allocate(); + obj_move_data_skin_block_constraint_up_vector( + &distance_dst->up_vector, &distance_src->up_vector, alloc); + distance_dst->distance = distance_src->distance; + distance_dst->constrained_object = distance_src->constrained_object; + distance_dst->constraining_object = distance_src->constraining_object; + cns_dst->distance = distance_dst; + } break; + default: + cns_dst->type = OBJ_SKIN_BLOCK_CONSTRAINT_NONE; + cns_dst->data = 0; + } + return cns_dst; +} + +static void obj_move_data_skin_block_constraint_up_vector(obj_skin_block_constraint_up_vector* up_vector_dst, + const obj_skin_block_constraint_up_vector* up_vector_src, + prj::shared_ptr alloc) { + up_vector_dst->active = up_vector_src->active; + up_vector_dst->roll = up_vector_src->roll; + up_vector_dst->affected_axis = up_vector_src->affected_axis; + up_vector_dst->point_at = up_vector_src->point_at; + up_vector_dst->name = obj_move_data_string(up_vector_src->name, alloc); +} + +static obj_skin_block_expression* obj_move_data_skin_block_expression(const obj_skin_block_expression* exp_src, + prj::shared_ptr alloc) { + obj_skin_block_expression* exp_dst = alloc->allocate(); + obj_move_data_skin_block_node(&exp_dst->node, &exp_src->node, alloc); + exp_dst->name_index = exp_src->name_index; + + uint32_t num_expression = exp_src->num_expression; + num_expression = min_def(num_expression, 9); + exp_dst->num_expression = num_expression; + for (uint32_t i = 0; i < num_expression; i++) + exp_dst->expression_array[i] = obj_move_data_string(exp_src->expression_array[i], alloc); + + for (uint32_t i = num_expression; i < 9; i++) + exp_dst->expression_array[i] = 0; + return exp_dst; +} + +static obj_skin_block_motion* obj_move_data_skin_block_motion(const obj_skin_block_motion* mot_src, + prj::shared_ptr alloc) { + obj_skin_block_motion* mot_dst = alloc->allocate(); + obj_move_data_skin_block_node(&mot_dst->node, &mot_src->node, alloc); + + mot_dst->name = 0; + if ((mot_src->name_index & ~0x7FFF) == 0x8000) + mot_dst->name_index = mot_src->name_index; + else + mot_dst->name = obj_move_data_string(mot_src->name, alloc); + + uint32_t num_node = mot_src->num_node; + mot_dst->node_array = alloc->allocate(mot_src->node_array, num_node); + mot_dst->num_node = num_node; + return mot_dst; +} + +static void obj_move_data_skin_block_node(obj_skin_block_node* node_dst, const obj_skin_block_node* node_src, + prj::shared_ptr alloc) { + node_dst->parent_name = obj_move_data_string(node_src->parent_name, alloc); + node_dst->position = node_src->position; + node_dst->rotation = node_src->rotation; + node_dst->scale = node_src->scale; +} + +static obj_skin_block_osage* obj_move_data_skin_block_osage(const obj_skin_block_osage* osg_src, + prj::shared_ptr alloc) { + obj_skin_block_osage* osg_dst = alloc->allocate(); + obj_move_data_skin_block_node(&osg_dst->node, &osg_src->node, alloc); + osg_dst->start_index = osg_src->start_index; + osg_dst->count = osg_src->count; + + uint32_t num_node = osg_src->num_node; + osg_dst->node_array = alloc->allocate(osg_src->node_array, num_node); + osg_dst->num_node = num_node; + + osg_dst->skin_param = obj_move_data_skin_param(osg_src->skin_param, alloc); + osg_dst->external_name_index = osg_src->external_name_index; + osg_dst->name_index = osg_src->name_index; + osg_dst->motion_node_name = obj_move_data_string(osg_src->motion_node_name, alloc); + return osg_dst; +} + +static obj_skin_skin_param* obj_move_data_skin_param(const obj_skin_skin_param* skp_src, + prj::shared_ptr alloc) { + if (!skp_src) + return 0; + + obj_skin_skin_param* skp_dst = alloc->allocate(); + skp_dst->unk0 = skp_src->unk0; + skp_dst->force = skp_src->force; + skp_dst->force_gain = skp_src->force_gain; + skp_dst->air_res = skp_src->air_res; + skp_dst->rot_y = skp_src->rot_y; + skp_dst->rot_z = skp_src->rot_z; + skp_dst->hinge_y = skp_src->hinge_y; + skp_dst->hinge_z = skp_src->hinge_z; + skp_dst->name = obj_move_data_string(skp_src->name, alloc); + + uint32_t coli_count = skp_src->coli_count; + skp_dst->coli = alloc->allocate(skp_src->coli, coli_count); + skp_dst->coli_count = coli_count; + + skp_dst->coli_r = skp_src->coli_r; + skp_dst->friction = skp_src->friction; + skp_dst->wind_afc = skp_src->wind_afc; + skp_dst->unk44 = skp_src->unk44; + return skp_dst; +} + +static void obj_set_classic_read_inner(obj_set* set, prj::shared_ptr& alloc, stream& s) { uint32_t version = s.read_uint32_t(); if (version != 0x05062500) { - os->ready = false; - os->modern = false; - os->big_endian = false; - os->is_x = false; + set->ready = false; + set->modern = false; + set->big_endian = false; + set->is_x = false; return; } obj_set_header osh = {}; - os->obj_num = s.read_int32_t(); + set->obj_num = s.read_int32_t(); osh.last_obj_id = s.read_int32_t(); osh.obj_data = s.read_int32_t(); osh.obj_skin_data = s.read_int32_t(); osh.obj_name_data = s.read_int32_t(); osh.obj_id_data = s.read_int32_t(); osh.tex_id_data = s.read_int32_t(); - os->tex_id_num = s.read_int32_t(); - os->reserved[0] = s.read_uint32_t(); - os->reserved[1] = s.read_uint32_t(); + set->tex_id_num = s.read_int32_t(); + set->reserved[0] = s.read_uint32_t(); + set->reserved[1] = s.read_uint32_t(); - uint32_t obj_num = os->obj_num; - os->obj_data = alloc->allocate(obj_num); + uint32_t obj_num = set->obj_num; + set->obj_data = alloc->allocate(obj_num); int32_t* data = force_malloc_s(int32_t, obj_num * 3ULL); @@ -764,7 +1241,7 @@ static void obj_set_classic_read_inner(obj_set* os, prj::shared_ptr& if (osh.obj_data) { for (uint32_t i = 0; i < obj_num; i++) { - obj* obj = &os->obj_data[i]; + obj* obj = &set->obj_data[i]; if (obj_data[i]) obj_classic_read_model(obj, alloc, s, obj_data[i]); @@ -780,26 +1257,29 @@ static void obj_set_classic_read_inner(obj_set* os, prj::shared_ptr& } s.set_position(osh.obj_id_data, SEEK_SET); + obj* obj_data = set->obj_data; for (uint32_t i = 0; i < obj_num; i++) - os->obj_data[i].id = s.read_uint32_t(); + obj_data[i].id = s.read_uint32_t(); } if (osh.tex_id_data) { - os->tex_id_data = alloc->allocate(os->tex_id_num); s.set_position(osh.tex_id_data, SEEK_SET); - for (uint32_t i = 0; i < os->tex_id_num; i++) - os->tex_id_data[i] = s.read_uint32_t(); + uint32_t tex_id_num = set->tex_id_num; + uint32_t* tex_id_data = alloc->allocate(tex_id_num); + set->tex_id_data = tex_id_data; + for (uint32_t i = 0; i < tex_id_num; i++) + tex_id_data[i] = s.read_uint32_t(); } free_def(data); - os->ready = true; - os->modern = false; - os->big_endian = false; - os->is_x = false; + set->ready = true; + set->modern = false; + set->big_endian = false; + set->is_x = false; } -static void obj_set_classic_write_inner(obj_set* os, stream& s) { +static void obj_set_classic_write_inner(obj_set* set, stream& s) { s.write_int32_t(0); s.write_int32_t(0); s.write_int32_t(0); @@ -818,7 +1298,7 @@ static void obj_set_classic_write_inner(obj_set* os, stream& s) { obj_set_header osh = {}; osh.last_obj_id = -1; - uint32_t obj_num = os->obj_num; + uint32_t obj_num = set->obj_num; osh.obj_data = s.get_position(); for (uint32_t i = 0; i < obj_num; i++) @@ -830,7 +1310,7 @@ static void obj_set_classic_write_inner(obj_set* os, stream& s) { int32_t* obj_data = data; for (uint32_t i = 0; i < obj_num; i++) { obj_data[i] = (int32_t)s.get_position(); - obj_classic_write_model(&os->obj_data[i], s, obj_data[i]); + obj_classic_write_model(&set->obj_data[i], s, obj_data[i]); } s.align_write(0x10); @@ -841,7 +1321,7 @@ static void obj_set_classic_write_inner(obj_set* os, stream& s) { osh.obj_id_data = s.get_position(); for (uint32_t i = 0; i < obj_num; i++) { - int32_t object_id = os->obj_data[i].id; + int32_t object_id = set->obj_data[i].id; s.write_uint32_t(object_id); if (osh.last_obj_id < object_id) osh.last_obj_id = object_id; @@ -851,7 +1331,7 @@ static void obj_set_classic_write_inner(obj_set* os, stream& s) { int32_t* obj_name_data = data; for (uint32_t i = 0; i < obj_num; i++) { obj_name_data[i] = (int32_t)s.get_position(); - s.write_utf8_string_null_terminated(os->obj_data[i].name); + s.write_utf8_string_null_terminated(set->obj_data[i].name); } s.align_write(0x10); @@ -861,8 +1341,8 @@ static void obj_set_classic_write_inner(obj_set* os, stream& s) { s.align_write(0x10); osh.tex_id_data = s.get_position(); - for (uint32_t i = 0; i < os->tex_id_num; i++) - s.write_uint32_t(os->tex_id_data[i]); + for (uint32_t i = 0; i < set->tex_id_num; i++) + s.write_uint32_t(set->tex_id_data[i]); s.align_write(0x10); osh.obj_skin_data = s.get_position(); @@ -872,7 +1352,7 @@ static void obj_set_classic_write_inner(obj_set* os, stream& s) { int32_t* obj_skin_data = data; for (uint32_t i = 0; i < obj_num; i++) { - obj_skin* sk = os->obj_data[i].skin; + obj_skin* sk = set->obj_data[i].skin; if (!sk) { obj_skin_data[i] = 0; continue; @@ -892,16 +1372,16 @@ static void obj_set_classic_write_inner(obj_set* os, stream& s) { s.position_push(0x00, SEEK_SET); s.write_uint32_t(0x05062500); - s.write_int32_t(os->obj_num); + s.write_int32_t(set->obj_num); s.write_uint32_t(osh.last_obj_id); s.write_uint32_t((uint32_t)osh.obj_data); s.write_uint32_t((uint32_t)osh.obj_skin_data); s.write_uint32_t((uint32_t)osh.obj_name_data); s.write_uint32_t((uint32_t)osh.obj_id_data); s.write_uint32_t((uint32_t)osh.tex_id_data); - s.write_int32_t(os->tex_id_num); - s.write_uint32_t(os->reserved[0]); - s.write_uint32_t(os->reserved[1]); + s.write_int32_t(set->tex_id_num); + s.write_uint32_t(set->reserved[0]); + s.write_uint32_t(set->reserved[1]); s.position_pop(); } @@ -2375,23 +2855,11 @@ static void obj_classic_write_skin_block_cloth(obj_skin_block_cloth* cls, if (cls->root_array) { s.position_push(*root_array_offset, SEEK_SET); - for (uint32_t i = 0; i < cls->num_root; i++) { - obj_skin_block_cloth_root* f = &cls->root_array[i]; - s.write_float_t(f->trans.x); - s.write_float_t(f->trans.y); - s.write_float_t(f->trans.z); - s.write_float_t(f->normal.x); - s.write_float_t(f->normal.y); - s.write_float_t(f->normal.z); - s.write_float_t(f->field_18); - s.write_int32_t(f->field_1C); - s.write_int32_t(f->field_20); - s.write_int32_t(f->field_24); - - for (uint32_t j = 0; j < 4; j++) - obj_classic_write_skin_block_cloth_root_bone_weight(&f->bone_weights[j], - s, strings, string_offsets); - } + uint32_t num_root = cls->num_root; + obj_skin_block_cloth_root* root_array = cls->root_array; + for (uint32_t i = 0; i < num_root; i++) + obj_classic_write_skin_block_cloth_root(&root_array[i], + s, strings, string_offsets); s.position_pop(); *root_array_offset += (sizeof(int32_t) + 4 * (sizeof(int32_t) + 3 * sizeof(int32_t))) * cls->num_root * (cls->num_node - 1ULL); @@ -2399,9 +2867,12 @@ static void obj_classic_write_skin_block_cloth(obj_skin_block_cloth* cls, if (cls->node_array) { s.position_push(*node_array_offset, SEEK_SET); - for (uint32_t i = 0; i < cls->num_node - 1; i++) - for (uint32_t j = 0; j < cls->num_root; j++) { - obj_skin_block_cloth_node* f = &cls->node_array[i * cls->num_root + j]; + uint32_t num_root = cls->num_root; + uint32_t num_node = cls->num_node; + obj_skin_block_cloth_node* node_array = cls->node_array; + for (uint32_t i = 0; i < num_node - 1; i++) + for (uint32_t j = 0; j < num_root; j++) { + obj_skin_block_cloth_node* f = &node_array[i * cls->num_root + j]; s.write_uint32_t(f->flags); s.write_float_t(f->trans.x); s.write_float_t(f->trans.y); @@ -2455,7 +2926,20 @@ static void obj_classic_read_skin_block_cloth_root(obj_skin_block_cloth_root* cl static void obj_classic_write_skin_block_cloth_root(obj_skin_block_cloth_root* cloth_root, stream& s, std::vector& strings, std::vector& string_offsets) { + s.write_float_t(cloth_root->trans.x); + s.write_float_t(cloth_root->trans.y); + s.write_float_t(cloth_root->trans.z); + s.write_float_t(cloth_root->normal.x); + s.write_float_t(cloth_root->normal.y); + s.write_float_t(cloth_root->normal.z); + s.write_float_t(cloth_root->field_18); + s.write_int32_t(cloth_root->field_1C); + s.write_int32_t(cloth_root->field_20); + s.write_int32_t(cloth_root->field_24); + for (uint32_t j = 0; j < 4; j++) + obj_classic_write_skin_block_cloth_root_bone_weight(&cloth_root->bone_weights[j], + s, strings, string_offsets); } static void obj_classic_read_skin_block_cloth_root_bone_weight(obj_skin_block_cloth_root_bone_weight* bone_weight, @@ -2553,8 +3037,10 @@ static obj_skin_block_constraint* obj_classic_read_skin_block_constraint( s, str); cns->distance = distance; } - else + else { cns->type = OBJ_SKIN_BLOCK_CONSTRAINT_NONE; + cns->data = 0; + } free_def(type); return cns; } @@ -2692,16 +3178,17 @@ static obj_skin_block_expression* obj_classic_read_skin_block_expression( } free_def(name); - exp->num_expression = s.read_int32_t(); - exp->num_expression = min_def(exp->num_expression, 9); - for (uint32_t i = 0; i < exp->num_expression; i++) { + uint32_t num_expression = s.read_int32_t(); + num_expression = min_def(num_expression, 9); + exp->num_expression = num_expression; + for (uint32_t i = 0; i < num_expression; i++) { uint32_t expression_offset = s.read_uint32_t(); if (expression_offset) exp->expression_array[i] = obj_read_utf8_string_null_terminated_offset(alloc, s, expression_offset); } - for (uint32_t i = exp->num_expression; i < 9; i++) + for (uint32_t i = num_expression; i < 9; i++) exp->expression_array[i] = 0; return exp; } @@ -2715,14 +3202,16 @@ static void obj_classic_write_skin_block_expression(obj_skin_block_expression* e string_offsets, bone_name_array, exp->name_index); s.write_uint32_t((uint32_t)name_offset); - s.write_int32_t(min_def(exp->num_expression, 9)); - for (uint32_t i = 0; i < exp->num_expression && i < 9; i++) { + uint32_t num_expression = exp->num_expression; + num_expression = min_def(num_expression, 9); + s.write_int32_t(num_expression); + for (uint32_t i = 0; i < num_expression; i++) { int64_t expression_offset = obj_skin_strings_get_string_offset(strings, string_offsets, exp->expression_array[i]); s.write_uint32_t((uint32_t)expression_offset); } - for (uint32_t i = exp->num_expression; i < 9; i++) + for (uint32_t i = num_expression; i < 9; i++) s.write_int32_t(0); } @@ -3379,7 +3868,7 @@ static void obj_classic_write_vertex(obj_mesh* mesh, } } -static void obj_set_modern_read_inner(obj_set* os, prj::shared_ptr& alloc, stream& s) { +static void obj_set_modern_read_inner(obj_set* set, prj::shared_ptr& alloc, stream& s) { f2_struct st; st.read(s); if (st.header.signature != reverse_endianness_uint32_t('MOSD') || !st.data.size()) @@ -3393,10 +3882,10 @@ static void obj_set_modern_read_inner(obj_set* os, prj::shared_ptr& uint32_t version = s_mosd.read_uint32_t_reverse_endianness(); if (version != 0x05062501) { - os->ready = false; - os->modern = false; - os->big_endian = false; - os->is_x = false; + set->ready = false; + set->modern = false; + set->big_endian = false; + set->is_x = false; return; } @@ -3415,32 +3904,32 @@ static void obj_set_modern_read_inner(obj_set* os, prj::shared_ptr& s_mosd.set_position(0x04, SEEK_SET); obj_set_header osh = {}; if (!is_x) { - os->obj_num = s_mosd.read_int32_t_reverse_endianness(); + set->obj_num = s_mosd.read_int32_t_reverse_endianness(); osh.last_obj_id = s_mosd.read_int32_t_reverse_endianness(); osh.obj_data = s_mosd.read_offset_f2(st.header.length); osh.obj_skin_data = s_mosd.read_offset_f2(st.header.length); osh.obj_name_data = s_mosd.read_offset_f2(st.header.length); osh.obj_id_data = s_mosd.read_offset_f2(st.header.length); osh.tex_id_data = s_mosd.read_offset_f2(st.header.length); - os->tex_id_num = s_mosd.read_int32_t_reverse_endianness(); - os->reserved[0] = s_mosd.read_uint32_t_reverse_endianness(); - os->reserved[1] = s_mosd.read_uint32_t_reverse_endianness(); + set->tex_id_num = s_mosd.read_int32_t_reverse_endianness(); + set->reserved[0] = s_mosd.read_uint32_t_reverse_endianness(); + set->reserved[1] = s_mosd.read_uint32_t_reverse_endianness(); } else { - os->obj_num = s_mosd.read_int32_t_reverse_endianness(); + set->obj_num = s_mosd.read_int32_t_reverse_endianness(); osh.last_obj_id = s_mosd.read_int32_t_reverse_endianness(); osh.obj_data = s_mosd.read_offset_x(); osh.obj_skin_data = s_mosd.read_offset_x(); osh.obj_name_data = s_mosd.read_offset_x(); osh.obj_id_data = s_mosd.read_offset_x(); osh.tex_id_data = s_mosd.read_offset_x(); - os->tex_id_num = s_mosd.read_int32_t_reverse_endianness(); - os->reserved[0] = s_mosd.read_uint32_t_reverse_endianness(); - os->reserved[1] = s_mosd.read_uint32_t_reverse_endianness(); + set->tex_id_num = s_mosd.read_int32_t_reverse_endianness(); + set->reserved[0] = s_mosd.read_uint32_t_reverse_endianness(); + set->reserved[1] = s_mosd.read_uint32_t_reverse_endianness(); } - uint32_t obj_num = os->obj_num; - os->obj_data = alloc->allocate(obj_num); + uint32_t obj_num = set->obj_num; + set->obj_data = alloc->allocate(obj_num); int64_t* data = force_malloc_s(int64_t, obj_num * 3ULL); @@ -3482,7 +3971,7 @@ static void obj_set_modern_read_inner(obj_set* os, prj::shared_ptr& if (osh.obj_data) for (uint32_t i = 0; i < obj_num; i++) { - obj* obj = &os->obj_data[i]; + obj* obj = &set->obj_data[i]; if (osh.obj_name_data && obj_name_data[i]) { obj->name = obj_read_utf8_string_null_terminated_offset(alloc, s_mosd, obj_name_data[i]); obj->hash = hash_utf8_murmurhash(obj->name); @@ -3493,17 +3982,20 @@ static void obj_set_modern_read_inner(obj_set* os, prj::shared_ptr& if (osh.obj_id_data) { s_mosd.set_position(osh.obj_id_data, SEEK_SET); + obj* obj_data = set->obj_data; for (uint32_t i = 0; i < obj_num; i++) - os->obj_data[i].id = s_mosd.read_uint32_t_reverse_endianness(); + obj_data[i].id = s_mosd.read_uint32_t_reverse_endianness(); } free_def(data); if (osh.tex_id_data) { s_mosd.set_position(osh.tex_id_data, SEEK_SET); - os->tex_id_data = alloc->allocate(os->tex_id_num); - for (uint32_t i = 0; i < os->tex_id_num; i++) - os->tex_id_data[i] = s_mosd.read_uint32_t_reverse_endianness(); + uint32_t tex_id_num = set->tex_id_num; + uint32_t* tex_id_data = alloc->allocate(tex_id_num); + set->tex_id_data = tex_id_data; + for (uint32_t i = 0; i < tex_id_num; i++) + tex_id_data[i] = s_mosd.read_uint32_t_reverse_endianness(); } int32_t omdl_index = 0; @@ -3546,7 +4038,7 @@ static void obj_set_modern_read_inner(obj_set* os, prj::shared_ptr& s_ovtx_ptr = &s_ovtx; } - obj* obj = &os->obj_data[omdl_index]; + obj* obj = &set->obj_data[omdl_index]; memory_stream s_omdl; s_omdl.open(i.data); s_omdl.big_endian = i.header.use_big_endian; @@ -3560,13 +4052,13 @@ static void obj_set_modern_read_inner(obj_set* os, prj::shared_ptr& omdl_index++; } - os->ready = true; - os->modern = true; - os->big_endian = big_endian; - os->is_x = is_x; + set->ready = true; + set->modern = true; + set->big_endian = big_endian; + set->is_x = is_x; } -static void obj_set_modern_write_inner(obj_set* os, stream& s) { +static void obj_set_modern_write_inner(obj_set* set, stream& s) { bool big_endian = s.big_endian; memory_stream s_mosd; @@ -3578,12 +4070,12 @@ static void obj_set_modern_write_inner(obj_set* os, stream& s) { enrs_entry ee; pof pof; - bool is_x = os->is_x; + bool is_x = set->is_x; obj_set_header osh = {}; osh.last_obj_id = -1; - uint32_t obj_num = os->obj_num; + uint32_t obj_num = set->obj_num; if (!is_x) { ee = { 0, 1, 44, 1 }; @@ -3633,10 +4125,10 @@ static void obj_set_modern_write_inner(obj_set* os, stream& s) { off = (uint32_t)(obj_num * 4ULL); off = align_val(off, 0x10); - ee = { off, 1, 4, (uint32_t)os->tex_id_num }; + ee = { off, 1, 4, (uint32_t)set->tex_id_num }; ee.append(0, 1, ENRS_DWORD); e.vec.push_back(ee); - off = (uint32_t)(os->tex_id_num * 4ULL); + off = (uint32_t)(set->tex_id_num * 4ULL); off = align_val(off, 0x10); if (!is_x) { @@ -3696,18 +4188,18 @@ static void obj_set_modern_write_inner(obj_set* os, stream& s) { osh.obj_id_data = s_mosd.get_position(); for (uint32_t i = 0; i < obj_num; i++) - s_mosd.write_uint32_t_reverse_endianness(os->obj_data[i].id); + s_mosd.write_uint32_t_reverse_endianness(set->obj_data[i].id); s_mosd.align_write(0x10); osh.tex_id_data = s_mosd.get_position(); - for (uint32_t i = 0; i < os->tex_id_num; i++) - s_mosd.write_uint32_t_reverse_endianness(os->tex_id_data[i]); + for (uint32_t i = 0; i < set->tex_id_num; i++) + s_mosd.write_uint32_t_reverse_endianness(set->tex_id_data[i]); s_mosd.align_write(0x10); int64_t* obj_name_data = force_malloc_s(int64_t, obj_num); for (uint32_t i = 0; i < obj_num; i++) { obj_name_data[i] = (int32_t)s_mosd.get_position(); - s_mosd.write_utf8_string_null_terminated(os->obj_data[i].name); + s_mosd.write_utf8_string_null_terminated(set->obj_data[i].name); } s_mosd.align_write(0x10); @@ -3724,35 +4216,35 @@ static void obj_set_modern_write_inner(obj_set* os, stream& s) { s_mosd.position_push(0x00, SEEK_SET); if (!is_x) { s_mosd.write_uint32_t_reverse_endianness(0x05062501); - s_mosd.write_int32_t_reverse_endianness(os->obj_num); + s_mosd.write_int32_t_reverse_endianness(set->obj_num); s_mosd.write_int32_t_reverse_endianness(-1); s_mosd.write_offset_f2(osh.obj_data, 0x20); s_mosd.write_offset_f2(osh.obj_skin_data, 0x20); s_mosd.write_offset_f2(osh.obj_name_data, 0x20); s_mosd.write_offset_f2(osh.obj_id_data, 0x20); s_mosd.write_offset_f2(osh.tex_id_data, 0x20); - s_mosd.write_int32_t_reverse_endianness(os->tex_id_num); - s_mosd.write_uint32_t_reverse_endianness(os->reserved[0]); - s_mosd.write_uint32_t_reverse_endianness(os->reserved[1]); + s_mosd.write_int32_t_reverse_endianness(set->tex_id_num); + s_mosd.write_uint32_t_reverse_endianness(set->reserved[0]); + s_mosd.write_uint32_t_reverse_endianness(set->reserved[1]); } else { s_mosd.write_uint32_t_reverse_endianness(0x05062501); - s_mosd.write_int32_t_reverse_endianness(os->obj_num); + s_mosd.write_int32_t_reverse_endianness(set->obj_num); s_mosd.write_int32_t_reverse_endianness(-1); s_mosd.write_offset_x(osh.obj_data); s_mosd.write_offset_x(osh.obj_skin_data); s_mosd.write_offset_x(osh.obj_name_data); s_mosd.write_offset_x(osh.obj_id_data); s_mosd.write_offset_x(osh.tex_id_data); - s_mosd.write_int32_t_reverse_endianness(os->tex_id_num); - s_mosd.write_uint32_t_reverse_endianness(os->reserved[0]); - s_mosd.write_uint32_t_reverse_endianness(os->reserved[1]); + s_mosd.write_int32_t_reverse_endianness(set->tex_id_num); + s_mosd.write_uint32_t_reverse_endianness(set->reserved[0]); + s_mosd.write_uint32_t_reverse_endianness(set->reserved[1]); } s_mosd.position_pop(); f2_struct st; for (uint32_t i = 0; i < obj_num; i++) { - obj* obj = &os->obj_data[i]; + obj* obj = &set->obj_data[i]; st.sub_structs.push_back({}); f2_struct* omdl = &st.sub_structs.back(); @@ -3805,7 +4297,7 @@ static void obj_set_modern_write_inner(obj_set* os, stream& s) { st.header.use_big_endian = big_endian; st.header.use_section_size = true; - st.write(s, true, os->is_x); + st.write(s, true, set->is_x); } static void obj_modern_read_index(obj_sub_mesh* sub_mesh, prj::shared_ptr alloc, stream& s) { @@ -5120,11 +5612,11 @@ static void obj_modern_write_skin(obj_skin* sk, stream& s, } if (exh.cloth_count) { - int32_t num_mat = 0; - int32_t num_root = 0; - int32_t num_node = 0; - int32_t num_mesh_index = 0; - int32_t num_backface_mesh_index = 0; + uint32_t num_mat = 0; + uint32_t num_root = 0; + uint32_t num_node = 0; + uint32_t num_mesh_index = 0; + uint32_t num_backface_mesh_index = 0; for (uint32_t i = 0; i < ex->num_block; i++) { obj_skin_block* block = &ex->block_array[i]; if (block->type == OBJ_SKIN_BLOCK_CLOTH) { @@ -5140,7 +5632,7 @@ static void obj_modern_write_skin(obj_skin* sk, stream& s, } if (num_mat) { - ee = { off, 1, sizeof(mat4), (uint32_t)num_mat }; + ee = { off, 1, sizeof(mat4), num_mat }; ee.append(0, 16, ENRS_DWORD); e.vec.push_back(ee); off = (uint32_t)(num_mat * sizeof(mat4)); @@ -5149,13 +5641,13 @@ static void obj_modern_write_skin(obj_skin* sk, stream& s, if (num_root) { if (!is_x) { - ee = { off, 1, 104, (uint32_t)num_root }; + ee = { off, 1, 104, num_root }; ee.append(0, 26, ENRS_DWORD); e.vec.push_back(ee); off = (uint32_t)(num_root * 104ULL); } else { - ee = { off, 9, 136, (uint32_t)num_root }; + ee = { off, 9, 136, num_root }; ee.append(0, 10, ENRS_DWORD); ee.append(0, 1, ENRS_QWORD); ee.append(0, 3, ENRS_DWORD); @@ -5172,7 +5664,7 @@ static void obj_modern_write_skin(obj_skin* sk, stream& s, } if (num_node) { - ee = { off, 1, 44, (uint32_t)num_node }; + ee = { off, 1, 44, num_node }; ee.append(0, 11, ENRS_DWORD); e.vec.push_back(ee); off = (uint32_t)(num_node * 44ULL); @@ -5180,7 +5672,7 @@ static void obj_modern_write_skin(obj_skin* sk, stream& s, } if (num_mesh_index) { - ee = { off, 1, 2, (uint32_t)num_mesh_index }; + ee = { off, 1, 2, num_mesh_index }; ee.append(0, 1, ENRS_WORD); e.vec.push_back(ee); off = (uint32_t)(num_mesh_index * 2ULL); @@ -5188,7 +5680,7 @@ static void obj_modern_write_skin(obj_skin* sk, stream& s, } if (num_backface_mesh_index) { - ee = { off, 1, 2, (uint32_t)num_backface_mesh_index }; + ee = { off, 1, 2, num_backface_mesh_index }; ee.append(0, 1, ENRS_WORD); e.vec.push_back(ee); off = (uint32_t)(num_backface_mesh_index * 2ULL); @@ -6299,24 +6791,11 @@ static obj_skin_block_cloth* obj_modern_read_skin_block_cloth( if (root_array_offset) { s.position_push(root_array_offset, SEEK_SET); uint32_t num_root = cls->num_root; - cls->root_array = alloc->allocate(num_root); - for (uint32_t i = 0; i < num_root; i++) { - obj_skin_block_cloth_root* f = &cls->root_array[i]; - f->trans.x = s.read_float_t_reverse_endianness(); - f->trans.y = s.read_float_t_reverse_endianness(); - f->trans.z = s.read_float_t_reverse_endianness(); - f->normal.x = s.read_float_t_reverse_endianness(); - f->normal.y = s.read_float_t_reverse_endianness(); - f->normal.z = s.read_float_t_reverse_endianness(); - f->field_18 = s.read_float_t_reverse_endianness(); - f->field_1C = s.read_int32_t_reverse_endianness(); - f->field_20 = s.read_int32_t_reverse_endianness(); - f->field_24 = s.read_int32_t_reverse_endianness(); - - for (uint32_t j = 0; j < 4; j++) - obj_modern_read_skin_block_cloth_root_bone_weight(&f->bone_weights[j], - alloc, s, header_length, str, is_x); - } + obj_skin_block_cloth_root* root_array = alloc->allocate(num_root); + cls->root_array = root_array; + for (uint32_t i = 0; i < num_root; i++) + obj_modern_read_skin_block_cloth_root(&root_array[i], + alloc, s, header_length, str, is_x); s.position_pop(); } @@ -6324,11 +6803,12 @@ static obj_skin_block_cloth* obj_modern_read_skin_block_cloth( s.position_push(node_array_offset, SEEK_SET); uint32_t num_root = cls->num_root; uint32_t num_node = cls->num_node; - cls->node_array = alloc->allocate( + obj_skin_block_cloth_node* node_array = alloc->allocate( num_root * (cls->num_node - 1ULL)); + cls->node_array = node_array; for (uint32_t i = 0; i < num_node - 1; i++) for (uint32_t j = 0; j < num_root; j++) { - obj_skin_block_cloth_node* f = &cls->node_array[(size_t)i * num_root + j]; + obj_skin_block_cloth_node* f = &node_array[(size_t)i * num_root + j]; f->flags = s.read_uint32_t_reverse_endianness(); f->trans.x = s.read_float_t_reverse_endianness(); f->trans.y = s.read_float_t_reverse_endianness(); @@ -6441,23 +6921,11 @@ static void obj_modern_write_skin_block_cloth(obj_skin_block_cloth* cls, if (cls->root_array) { s.position_push(*root_array_offset, SEEK_SET); uint32_t num_root = cls->num_root; - for (uint32_t i = 0; i < num_root; i++) { - obj_skin_block_cloth_root* f = &cls->root_array[i]; - s.write_float_t_reverse_endianness(f->trans.x); - s.write_float_t_reverse_endianness(f->trans.y); - s.write_float_t_reverse_endianness(f->trans.z); - s.write_float_t_reverse_endianness(f->normal.x); - s.write_float_t_reverse_endianness(f->normal.y); - s.write_float_t_reverse_endianness(f->normal.z); - s.write_float_t_reverse_endianness(f->field_18); - s.write_int32_t_reverse_endianness(f->field_1C); - s.write_int32_t_reverse_endianness(f->field_20); - s.write_int32_t_reverse_endianness(f->field_24); - - for (uint32_t j = 0; j < 4; j++) - obj_modern_write_skin_block_cloth_root_bone_weight(&f->bone_weights[j], - s, strings, string_offsets, is_x); - } + uint32_t num_node = cls->num_node; + obj_skin_block_cloth_root* root_array = cls->root_array; + for (uint32_t i = 0; i < num_root; i++) + obj_modern_write_skin_block_cloth_root(&root_array[i], + s, strings, string_offsets, is_x); s.position_pop(); if (!is_x) *root_array_offset += (sizeof(int32_t) + 4 * (sizeof(int64_t) + 4 * sizeof(int32_t))) @@ -6471,9 +6939,10 @@ static void obj_modern_write_skin_block_cloth(obj_skin_block_cloth* cls, s.position_push(*node_array_offset, SEEK_SET); uint32_t num_root = cls->num_root; uint32_t num_node = cls->num_node; + obj_skin_block_cloth_node* node_array = cls->node_array; for (uint32_t i = 0; i < num_node - 1; i++) for (uint32_t j = 0; j < num_root; j++) { - obj_skin_block_cloth_node* f = &cls->node_array[(size_t)i * num_root + j]; + obj_skin_block_cloth_node* f = &node_array[(size_t)i * num_root + j]; s.write_uint32_t_reverse_endianness(f->flags); s.write_float_t_reverse_endianness(f->trans.x); s.write_float_t_reverse_endianness(f->trans.y); @@ -6494,7 +6963,7 @@ static void obj_modern_write_skin_block_cloth(obj_skin_block_cloth* cls, s.position_push(*mesh_index_array_offset, SEEK_SET); s.write_uint16_t_reverse_endianness((uint16_t)cls->num_mesh_index); uint16_t* mesh_index_array = cls->mesh_index_array; - for (int32_t i = cls->num_mesh_index; i > 0; i--, mesh_index_array++) + for (uint32_t i = cls->num_mesh_index; i > 0; i--, mesh_index_array++) s.write_uint16_t_reverse_endianness(*mesh_index_array); s.position_pop(); *mesh_index_array_offset += sizeof(uint16_t) + cls->num_mesh_index * sizeof(uint16_t); @@ -6504,13 +6973,49 @@ static void obj_modern_write_skin_block_cloth(obj_skin_block_cloth* cls, s.position_push(*backface_mesh_index_array_offset, SEEK_SET); s.write_uint16_t_reverse_endianness((uint16_t)cls->num_backface_mesh_index); uint16_t* backface_mesh_index_array = cls->backface_mesh_index_array; - for (int32_t i = cls->num_backface_mesh_index; i > 0; i--, backface_mesh_index_array++) + for (uint32_t i = cls->num_backface_mesh_index; i > 0; i--, backface_mesh_index_array++) s.write_uint16_t_reverse_endianness(*backface_mesh_index_array); s.position_pop(); *backface_mesh_index_array_offset += sizeof(uint16_t) + cls->num_backface_mesh_index * sizeof(uint16_t); } } +static void obj_modern_read_skin_block_cloth_root(obj_skin_block_cloth_root* cloth_root, + prj::shared_ptr alloc, stream& s, uint32_t header_length, const char** str, bool is_x) { + cloth_root->trans.x = s.read_float_t(); + cloth_root->trans.y = s.read_float_t(); + cloth_root->trans.z = s.read_float_t(); + cloth_root->normal.x = s.read_float_t(); + cloth_root->normal.y = s.read_float_t(); + cloth_root->normal.z = s.read_float_t(); + cloth_root->field_18 = s.read_float_t(); + cloth_root->field_1C = s.read_int32_t(); + cloth_root->field_20 = s.read_int32_t(); + cloth_root->field_24 = s.read_int32_t(); + + for (uint32_t i = 0; i < 4; i++) + obj_modern_read_skin_block_cloth_root_bone_weight(&cloth_root->bone_weights[i], + alloc, s, header_length, str, is_x); +} + +static void obj_modern_write_skin_block_cloth_root(obj_skin_block_cloth_root* cloth_root, + stream& s, std::vector& strings, std::vector& string_offsets, bool is_x) { + s.write_float_t(cloth_root->trans.x); + s.write_float_t(cloth_root->trans.y); + s.write_float_t(cloth_root->trans.z); + s.write_float_t(cloth_root->normal.x); + s.write_float_t(cloth_root->normal.y); + s.write_float_t(cloth_root->normal.z); + s.write_float_t(cloth_root->field_18); + s.write_int32_t(cloth_root->field_1C); + s.write_int32_t(cloth_root->field_20); + s.write_int32_t(cloth_root->field_24); + + for (uint32_t j = 0; j < 4; j++) + obj_modern_write_skin_block_cloth_root_bone_weight(&cloth_root->bone_weights[j], + s, strings, string_offsets, is_x); +} + static void obj_modern_read_skin_block_cloth_root_bone_weight(obj_skin_block_cloth_root_bone_weight* bone_weight, prj::shared_ptr alloc, stream& s, uint32_t header_length, const char** str, bool is_x) { int64_t bone_name_offset = s.read_offset(header_length, is_x); @@ -6610,8 +7115,10 @@ static obj_skin_block_constraint* obj_modern_read_skin_block_constraint( s, header_length, str, is_x); cns->distance = distance; } - else + else { cns->type = OBJ_SKIN_BLOCK_CONSTRAINT_NONE; + cns->data = 0; + } free_def(type); return cns; } @@ -6749,24 +7256,25 @@ static obj_skin_block_expression* obj_modern_read_skin_block_expression( } free_def(name); - exp->num_expression = s.read_int32_t_reverse_endianness(); - exp->num_expression = min_def(exp->num_expression, 9); + uint32_t num_expression = s.read_int32_t_reverse_endianness(); + num_expression = min_def(num_expression, 9); + exp->num_expression = num_expression; if (!is_x) - for (uint32_t i = 0; i < exp->num_expression; i++) { + for (uint32_t i = 0; i < num_expression; i++) { int64_t expression_offset = s.read_offset_f2(header_length); if (expression_offset) exp->expression_array[i] = obj_read_utf8_string_null_terminated_offset(alloc, s, expression_offset); } else - for (uint32_t i = 0; i < exp->num_expression; i++) { + for (uint32_t i = 0; i < num_expression; i++) { int64_t expression_offset = s.read_offset_x(); if (expression_offset) exp->expression_array[i] = obj_read_utf8_string_null_terminated_offset(alloc, s, expression_offset); } - for (uint32_t i = exp->num_expression; i < 9; i++) + for (uint32_t i = num_expression; i < 9; i++) exp->expression_array[i] = 0; return exp; } @@ -6780,25 +7288,27 @@ static void obj_modern_write_skin_block_expression(obj_skin_block_expression* ex string_offsets, bone_name_array, exp->name_index); s.write_offset(name_offset, 0x20, is_x); - s.write_int32_t_reverse_endianness(min_def(exp->num_expression, 9)); + uint32_t num_expression = exp->num_expression; + num_expression = min_def(num_expression, 9); + s.write_int32_t_reverse_endianness(num_expression); if (!is_x) { - for (uint32_t i = 0; i < exp->num_expression && i < 9; i++) { + for (uint32_t i = 0; i < num_expression; i++) { int64_t expression_offset = obj_skin_strings_get_string_offset(strings, string_offsets, exp->expression_array[i]); s.write_offset_f2((int32_t)expression_offset, 0x20); } - for (uint32_t i = exp->num_expression; i < 9; i++) + for (uint32_t i = num_expression; i < 9; i++) s.write_offset_f2(0, 0x20); } else { - for (uint32_t i = 0; i < exp->num_expression && i < 9; i++) { + for (uint32_t i = 0; i < num_expression; i++) { int64_t expression_offset = obj_skin_strings_get_string_offset(strings, string_offsets, exp->expression_array[i]); s.write_offset_x(expression_offset); } - for (uint32_t i = exp->num_expression; i < 9; i++) + for (uint32_t i = num_expression; i < 9; i++) s.write_offset_x(0); } } @@ -7320,6 +7830,13 @@ static void obj_modern_write_vertex(obj_mesh* mesh, stream& s, int64_t* vertex, *size_vertex = _size_vertex; } +inline static const char* obj_move_data_string(const char* str, + prj::shared_ptr& alloc) { + if (str) + return alloc->allocate(str, utf8_length(str) + 1); + return 0; +} + inline static const char* obj_read_utf8_string_null_terminated_offset( prj::shared_ptr& alloc, stream& s, int64_t offset) { size_t len = s.read_utf8_string_null_terminated_offset_length(offset); @@ -7354,7 +7871,7 @@ inline static int64_t obj_skin_strings_get_string_offset(std::vector& vec, std::vector& vec_off, const char** strings, uint32_t index) { - if (~index & 0x8000) + if (!(index & 0x8000)) return 0; const char* str = strings[index & 0x7FFF]; @@ -7380,7 +7897,7 @@ inline static void obj_skin_strings_push_back_check(std::vector& ve inline static void obj_skin_strings_push_back_check_by_index(std::vector& vec, const char** strings, uint32_t index) { - if (~index & 0x8000) + if (!(index & 0x8000)) return; const char* str = strings[index & 0x7FFF]; diff --git a/src/KKdLib/obj.hpp b/src/KKdLib/obj.hpp index 4ec3d9bb..bc6659ca 100644 --- a/src/KKdLib/obj.hpp +++ b/src/KKdLib/obj.hpp @@ -118,7 +118,6 @@ enum obj_skin_block_type : uint32_t { OBJ_SKIN_BLOCK_CLOTH, OBJ_SKIN_BLOCK_CONSTRAINT, OBJ_SKIN_BLOCK_EXPRESSION, - OBJ_SKIN_BLOCK_ITEM, OBJ_SKIN_BLOCK_MOTION, OBJ_SKIN_BLOCK_OSAGE, }; @@ -499,9 +498,9 @@ struct obj_skin_block_cloth { obj_skin_block_cloth_root* root_array; obj_skin_block_cloth_node* node_array; uint16_t* mesh_index_array; - int32_t num_mesh_index; + uint32_t num_mesh_index; uint16_t* backface_mesh_index_array; - int32_t num_backface_mesh_index; + uint32_t num_backface_mesh_index; obj_skin_skin_param* skin_param; uint32_t reserved; @@ -710,6 +709,7 @@ struct obj_set { obj_set(); + void move_data(obj_set* set_src, prj::shared_ptr alloc); void pack_file(void** data, size_t* size); void unpack_file(prj::shared_ptr alloc, const void* data, size_t size, bool modern); }; diff --git a/src/KKdLib/post_process_table/dof.hpp b/src/KKdLib/post_process_table/dof.hpp index 84665896..d8266230 100644 --- a/src/KKdLib/post_process_table/dof.hpp +++ b/src/KKdLib/post_process_table/dof.hpp @@ -36,7 +36,7 @@ struct dof { std::vector data; dof(); - virtual ~dof(); + ~dof(); void read(const char* path); void read(const wchar_t* path); diff --git a/src/KKdLib/pv_exp.cpp b/src/KKdLib/pv_exp.cpp index cc553f5e..5a9f5ca8 100644 --- a/src/KKdLib/pv_exp.cpp +++ b/src/KKdLib/pv_exp.cpp @@ -39,6 +39,51 @@ pv_exp::pv_exp() : ready(), modern(), big_endian(), is_x(), motion_data(), motio } +void pv_exp::move_data(pv_exp* exp_src, prj::shared_ptr alloc) { + if (!exp_src->ready) { + ready = false; + modern = false; + big_endian = false; + is_x = false; + return; + } + + ready = true; + modern = exp_src->modern; + big_endian = exp_src->big_endian; + is_x = exp_src->is_x; + + uint32_t motion_num = exp_src->motion_num; + pv_exp_mot* motion_data_src = exp_src->motion_data; + pv_exp_mot* motion_data_dst = alloc->allocate(motion_num); + this->motion_data = motion_data_dst; + this->motion_num = motion_num; + + for (uint32_t i = 0; i < motion_num; i++) { + pv_exp_mot& mot_src = motion_data_src[i]; + pv_exp_mot& mot_dst = motion_data_dst[i]; + + size_t face_count = 0; + pv_exp_data* face_data_src = mot_src.face_data; + while (face_data_src->type != -1) + face_count++; + face_count++; + + size_t face_cl_count = 0; + pv_exp_data* face_cl_data_src = mot_src.face_cl_data; + while (face_cl_data_src->type != -1) + face_cl_count++; + face_cl_count++; + + mot_dst.face_data = alloc->allocate(mot_src.face_data, face_count); + mot_dst.face_cl_data = alloc->allocate(mot_src.face_cl_data, face_cl_count); + if (mot_src.name) + mot_dst.name = alloc->allocate(mot_src.name, utf8_length(mot_src.name) + 1); + else + mot_src.name = 0; + } +} + void pv_exp::pack_file(void** data, size_t* size) { if (!data || !size || !ready) return; diff --git a/src/KKdLib/pv_exp.hpp b/src/KKdLib/pv_exp.hpp index e6cf7c1c..c858f995 100644 --- a/src/KKdLib/pv_exp.hpp +++ b/src/KKdLib/pv_exp.hpp @@ -39,6 +39,7 @@ struct pv_exp { pv_exp(); + void move_data(pv_exp* exp_src, prj::shared_ptr alloc); void pack_file(void** data, size_t* size); void unpack_file(prj::shared_ptr alloc, const void* data, size_t size, bool modern); }; diff --git a/src/KKdLib/pvpp.hpp b/src/KKdLib/pvpp.hpp index 64ba32e6..f9e4d90e 100644 --- a/src/KKdLib/pvpp.hpp +++ b/src/KKdLib/pvpp.hpp @@ -114,7 +114,7 @@ struct pvpp { std::vector effect; pvpp(); - virtual ~pvpp(); + ~pvpp(); void read(const char* path); void read(const wchar_t* path); diff --git a/src/KKdLib/pvsr.hpp b/src/KKdLib/pvsr.hpp index 34982e52..815c6b94 100644 --- a/src/KKdLib/pvsr.hpp +++ b/src/KKdLib/pvsr.hpp @@ -139,7 +139,7 @@ struct pvsr { std::vector stage_effect_env; pvsr(); - virtual ~pvsr(); + ~pvsr(); void read(const char* path); void read(const wchar_t* path); diff --git a/src/KKdLib/sound/diva.cpp b/src/KKdLib/sound/diva.cpp index 945e92ad..71486fad 100644 --- a/src/KKdLib/sound/diva.cpp +++ b/src/KKdLib/sound/diva.cpp @@ -156,7 +156,7 @@ static bool diva_read_inner(diva* d, stream& s, float_t*& data) { float_t* temp_data = data; for (size_t i = 0; i < samples_count; i++) for (size_t c = 0; c < ch; c++, current_sample++) { - if (~current_sample & 0x01) + if (!(current_sample & 0x01)) value = s.read_uint8_t(); nibble = (current_sample & 1 ? value : value >> 4) & 0x0F; diff --git a/src/KKdLib/sound/diva.hpp b/src/KKdLib/sound/diva.hpp index af4ec496..9ce3b984 100644 --- a/src/KKdLib/sound/diva.hpp +++ b/src/KKdLib/sound/diva.hpp @@ -16,7 +16,7 @@ struct diva { uint32_t channels; diva(); - virtual ~diva(); + ~diva(); void read(const char* path); void read(const wchar_t* path); diff --git a/src/KKdLib/sound/vag.hpp b/src/KKdLib/sound/vag.hpp index b068e4de..1830fc31 100644 --- a/src/KKdLib/sound/vag.hpp +++ b/src/KKdLib/sound/vag.hpp @@ -24,7 +24,7 @@ struct vag { size_t size; vag(); - virtual ~vag(); + ~vag(); void read(const char* path); void read(const wchar_t* path); diff --git a/src/KKdLib/sound/wav.hpp b/src/KKdLib/sound/wav.hpp index e39d0f8d..b52b9031 100644 --- a/src/KKdLib/sound/wav.hpp +++ b/src/KKdLib/sound/wav.hpp @@ -18,7 +18,7 @@ struct wav { uint16_t channels; wav(); - virtual ~wav(); + ~wav(); void read(const char* path, float_t*& data, size_t& samples); void read(const wchar_t* path, float_t*& data, size_t& samples); diff --git a/src/KKdLib/txp.hpp b/src/KKdLib/txp.hpp index 14df612f..cab39721 100644 --- a/src/KKdLib/txp.hpp +++ b/src/KKdLib/txp.hpp @@ -53,7 +53,7 @@ struct txp_set { std::vector textures; txp_set(); - virtual ~txp_set(); + ~txp_set(); bool pack_file(void** data, size_t* size, bool big_endian); bool pack_file(std::vector& data, bool big_endian); diff --git a/src/ReDIVA/classes.cpp b/src/ReDIVA/classes.cpp index bda3dc58..bd0e9b79 100644 --- a/src/ReDIVA/classes.cpp +++ b/src/ReDIVA/classes.cpp @@ -13,7 +13,7 @@ void classes_process_init(classes_data* classes, const size_t classes_count, ren for (size_t i = 0; i < classes_count; i++) { classes_data* c = &classes[i]; - c->data.lock = new lock; + c->data.lock = new lock_cs; if (c->data.lock->check_init() && c->flags & (CLASSES_INIT_AT_STARTUP | CLASSES_SHOW_AT_STARTUP) && c->init) { lock_lock(c->data.lock); @@ -23,7 +23,7 @@ void classes_process_init(classes_data* classes, const size_t classes_count, ren c->data.flags = (class_flags)(CLASS_DISPOSED | CLASS_HIDDEN); c->data.imgui_focus = false; - if (~c->flags & CLASSES_SHOW_AT_STARTUP) + if (!(c->flags & CLASSES_SHOW_AT_STARTUP)) enum_or(c->data.flags, CLASS_HIDDEN); lock_unlock(c->data.lock); } @@ -51,7 +51,7 @@ void classes_process_ctrl(classes_data* classes, const size_t classes_count) { if (c->data.lock->check_init()) { if (c->data.flags & CLASS_HIDE) { lock_lock(c->data.lock); - if (~c->data.flags & CLASS_HIDDEN && ((c->hide && c->hide(&c->data)) || !c->hide)) { + if (!(c->data.flags & CLASS_HIDDEN) && ((c->hide && c->hide(&c->data)) || !c->hide)) { enum_and(c->data.flags, ~CLASS_HIDE); enum_or(c->data.flags, CLASS_HIDDEN); enum_and(c->data.flags, ~CLASS_HAS_PARENT); @@ -62,13 +62,13 @@ void classes_process_ctrl(classes_data* classes, const size_t classes_count) { if ((c->data.flags & CLASS_DISPOSE || (c->data.flags & CLASS_HIDDEN && c->flags & CLASSES_DISPOSE_AT_HIDE))) { lock_lock(c->data.lock); - if (~c->data.flags & CLASS_HIDDEN && ((c->hide && c->hide(&c->data)) || !c->hide)) { + if (!(c->data.flags & CLASS_HIDDEN) && ((c->hide && c->hide(&c->data)) || !c->hide)) { enum_and(c->data.flags, ~CLASS_HIDE); enum_or(c->data.flags, CLASS_HIDDEN); enum_and(c->data.flags, ~CLASS_HAS_PARENT); } - if (~c->data.flags & CLASS_DISPOSED && ((c->dispose && c->dispose(&c->data)) || !c->dispose)) { + if (!(c->data.flags & CLASS_DISPOSED) && ((c->dispose && c->dispose(&c->data)) || !c->dispose)) { enum_and(c->data.flags, ~CLASS_DISPOSE); enum_or(c->data.flags, CLASS_DISPOSED); c->data.imgui_focus = false; @@ -130,7 +130,7 @@ void classes_process_imgui(classes_data* classes, const size_t classes_count) { classes_data* c = &classes[i]; if (c->data.lock->check_init()) { lock_lock(c->data.lock); - if (~c->data.flags & CLASS_HIDDEN) { + if (!(c->data.flags & CLASS_HIDDEN)) { if (c->imgui) c->imgui(&c->data); input_locked |= c->data.imgui_focus; @@ -187,13 +187,13 @@ void classes_process_dispose(classes_data* classes, const size_t classes_count) classes_data* c = &classes[i]; if (c->data.lock->check_init()) { lock_lock(c->data.lock); - if (~c->data.flags & CLASS_HIDDEN && ((c->hide && c->hide(&c->data)) || !c->hide)) { + if (!(c->data.flags & CLASS_HIDDEN) && ((c->hide && c->hide(&c->data)) || !c->hide)) { enum_and(c->data.flags, ~CLASS_HIDE); enum_or(c->data.flags, CLASS_HIDDEN); enum_and(c->data.flags, ~CLASS_HAS_PARENT); } - if (~c->data.flags & CLASS_DISPOSED && ((c->dispose && c->dispose(&c->data)) || !c->dispose)) { + if (!(c->data.flags & CLASS_DISPOSED) && ((c->dispose && c->dispose(&c->data)) || !c->dispose)) { enum_and(c->data.flags, ~CLASS_DISPOSE); enum_or(c->data.flags, CLASS_DISPOSED); c->data.imgui_focus = false; diff --git a/src/ReDIVA/classes.hpp b/src/ReDIVA/classes.hpp index a42b9720..7e25c1f4 100644 --- a/src/ReDIVA/classes.hpp +++ b/src/ReDIVA/classes.hpp @@ -30,7 +30,7 @@ enum classes_enum { }; struct class_data { - lock* lock; + lock_cs* lock; class_flags flags; bool imgui_focus; void* data; diff --git a/src/ReDIVA/classes/glitter_editor.cpp b/src/ReDIVA/classes/glitter_editor.cpp index b5d935f0..8cf6a54a 100644 --- a/src/ReDIVA/classes/glitter_editor.cpp +++ b/src/ReDIVA/classes/glitter_editor.cpp @@ -57,6 +57,7 @@ struct GlitterEditor; struct GlitterEditor { struct CurveEditor { Glitter::CurveType type; + Glitter::CurveTypeFlags type_flags; Glitter::Animation* animation; Glitter::Curve* list[Glitter::CURVE_V_SCROLL_ALPHA_2ND - Glitter::CURVE_TRANSLATION_X + 1]; Glitter::Curve::Key* key; @@ -75,6 +76,7 @@ struct GlitterEditor { float_t timeline_pos; float_t range; + float_t offset; bool add_key; bool del_key; @@ -86,6 +88,7 @@ struct GlitterEditor { void ResetCurves(); void ResetState(Glitter::CurveType type = (Glitter::CurveType)-1); + void SetFlag(const Glitter::CurveTypeFlags type_flag); }; bool test; @@ -256,7 +259,29 @@ static void glitter_editor_curve_editor_key_manager(GlitterEditor* glt_edt, std::vector* keys, bool* add_key, bool* del_key); static void glitter_editor_curve_editor_property_window(GlitterEditor* glt_edt, class_data* data); static void glitter_editor_curve_editor_selector(GlitterEditor* glt_edt, class_data* data); -static void glitter_editor_curve_editor_windows(GlitterEditor* glt_edt); +static void glitter_editor_curve_editor_window(GlitterEditor* glt_edt); +static void glitter_editor_curve_editor_window_draw(GlitterEditor* glt_edt, const Glitter::CurveType type, + const ImU32 line_color, const bool line_front, const float_t min, const float_t max, + const ImVec2 canvas_size, const ImVec2 canvas_pos, const ImVec2 canvas_pos_min, const ImVec2 canvas_pos_max, + const bool fix_rot_z = false); +static void glitter_editor_curve_editor_window_draw(GlitterEditor* glt_edt, const Glitter::Curve* curve, + const ImU32 line_color, const bool line_front, const float_t min, const float_t max, + const ImVec2 canvas_size, const ImVec2 canvas_pos, const ImVec2 canvas_pos_min, const ImVec2 canvas_pos_max, + const bool fix_rot_z = false); +static void glitter_editor_curve_editor_window_draw(GlitterEditor* glt_edt, const Glitter::Curve* curve, + const ImU32 line_color, const bool line_front, const float_t min, const float_t max, + const ImVec2 canvas_size, const ImVec2 canvas_pos, const ImVec2 canvas_pos_min, const ImVec2 canvas_pos_max, + const bool fix_rot_z, const int32_t start_time, const int32_t end_time, + const int32_t base_start_time, const int32_t base_end_time, std::vector& points, bool loop = false); +static void glitter_editor_curve_editor_window_draw_random_range( + GlitterEditor::CurveEditor* crv_edt, const float_t x1, const float_t x2, + const vec3 value, const vec3 random, const float_t min, const float_t max, const bool random_range_negate, + const ImVec2 canvas_size, const ImVec2 canvas_pos, const ImVec2 canvas_pos_min, const ImVec2 canvas_pos_max); +static void glitter_editor_curve_editor_window_draw_random_range( + GlitterEditor::CurveEditor* crv_edt, const float_t x1, const float_t x2, + const vec3 value1, const vec3 value2, const vec3 random1, const vec3 random2, + const float_t min, const float_t max, const bool random_range_negate, + const ImVec2 canvas_size, const ImVec2 canvas_pos, const ImVec2 canvas_pos_min, const ImVec2 canvas_pos_max); static bool glitter_editor_hash_input(GlitterEditor* glt_edt, const char* label, uint64_t* hash); @@ -1164,9 +1189,10 @@ bool glitter_editor_dispose(class_data* data) { return true; } -GlitterEditor::CurveEditor::CurveEditor() : type(), animation(), list(), key(), frame_width(), -zoom_time(), prev_zoom_time(), zoom_value(), key_radius_in(), key_radius_out(), height_offset(), frame(), -draw_list(), io(), timeline_pos(), range(), add_key(), del_key(), add_curve(), del_curve(), key_edit() { +GlitterEditor::CurveEditor::CurveEditor() : type(), type_flags(), animation(), list(), +key(), frame_width(), zoom_time(), prev_zoom_time(), zoom_value(), key_radius_in(), +key_radius_out(), height_offset(), frame(), draw_list(), io(), timeline_pos(), +range(), offset(), add_key(), del_key(), add_curve(), del_curve(), key_edit() { } @@ -1180,6 +1206,11 @@ void GlitterEditor::CurveEditor::ResetState(Glitter::CurveType type) { if (this->type != type) this->type = type; + if (this->type != -1) + type_flags = (Glitter::CurveTypeFlags)(1 << this->type); + else + type_flags = (Glitter::CurveTypeFlags)0; + frame_width = 16; zoom_time = 1.0f; prev_zoom_time = 1.0f; @@ -1241,10 +1272,73 @@ void GlitterEditor::CurveEditor::ResetState(Glitter::CurveType type) { break; } + offset = 0.0f; + add_key = false; del_key = false; } +void GlitterEditor::CurveEditor::SetFlag(const Glitter::CurveTypeFlags type_flag) { + switch (type) { + case Glitter::CURVE_TRANSLATION_X: + case Glitter::CURVE_TRANSLATION_Y: + case Glitter::CURVE_TRANSLATION_Z: + if (type_flag & Glitter::CURVE_TYPE_TRANSLATION_XYZ) + enum_xor(type_flags, type_flag); + break; + case Glitter::CURVE_ROTATION_X: + case Glitter::CURVE_ROTATION_Y: + case Glitter::CURVE_ROTATION_Z: + if (type_flag & Glitter::CURVE_TYPE_ROTATION_XYZ) + enum_xor(type_flags, type_flag); + break; + case Glitter::CURVE_SCALE_X: + case Glitter::CURVE_SCALE_Y: + case Glitter::CURVE_SCALE_Z: + case Glitter::CURVE_SCALE_ALL: + if (type_flag & (Glitter::CURVE_TYPE_SCALE_XYZ | Glitter::CURVE_TYPE_SCALE_ALL)) + enum_xor(type_flags, type_flag); + break; + case Glitter::CURVE_COLOR_R: + case Glitter::CURVE_COLOR_G: + case Glitter::CURVE_COLOR_B: + case Glitter::CURVE_COLOR_A: + case Glitter::CURVE_COLOR_RGB_SCALE: + if (type_flag & (Glitter::CURVE_TYPE_COLOR_RGBA | Glitter::CURVE_TYPE_COLOR_RGB_SCALE)) + enum_xor(type_flags, type_flag); + break; + case Glitter::CURVE_COLOR_R_2ND: + case Glitter::CURVE_COLOR_G_2ND: + case Glitter::CURVE_COLOR_B_2ND: + case Glitter::CURVE_COLOR_A_2ND: + case Glitter::CURVE_COLOR_RGB_SCALE_2ND: + if (type_flag & (Glitter::CURVE_TYPE_COLOR_RGBA_2ND | Glitter::CURVE_TYPE_COLOR_RGB_SCALE_2ND)) + enum_xor(type_flags, type_flag); + break; + case Glitter::CURVE_U_SCROLL: + case Glitter::CURVE_V_SCROLL: + if (type_flag & Glitter::CURVE_TYPE_UV_SCROLL) + enum_xor(type_flags, type_flag); + break; + case Glitter::CURVE_U_SCROLL_ALPHA: + case Glitter::CURVE_V_SCROLL_ALPHA: + if (type_flag & Glitter::CURVE_TYPE_UV_SCROLL_ALPHA) + enum_xor(type_flags, type_flag); + break; + case Glitter::CURVE_U_SCROLL_2ND: + case Glitter::CURVE_V_SCROLL_2ND: + if (type_flag & Glitter::CURVE_TYPE_UV_SCROLL_2ND) + enum_xor(type_flags, type_flag); + break; + case Glitter::CURVE_U_SCROLL_ALPHA_2ND: + case Glitter::CURVE_V_SCROLL_ALPHA_2ND: + if (type_flag & Glitter::CURVE_TYPE_UV_SCROLL_ALPHA_2ND) + enum_xor(type_flags, type_flag); + break; + } + enum_or(type_flags, (1 << type)); +} + GlitterEditor::GlitterEditor() : test(), create_popup(), load(), load_wait(), load_data(), load_data_wait(), load_popup(), load_data_popup(), load_error_list_popup(), save(), save_popup(), save_compress(), close(), input_play(), input_reload(), input_pause(), input_pause_temp(), input_reset(), @@ -1606,6 +1700,8 @@ static void glitter_editor_windows(GlitterEditor* glt_edt, class_data* data) { window_flags = 0; window_flags |= ImGuiWindowFlags_NoResize; window_flags |= ImGuiWindowFlags_NoMove; + window_flags |= ImGuiWindowFlags_NoScrollbar; + window_flags |= ImGuiWindowFlags_NoScrollWithMouse; window_flags |= ImGuiWindowFlags_NoCollapse; window_flags |= ImGuiWindowFlags_NoFocusOnAppearing; window_flags |= ImGuiWindowFlags_NoBringToFrontOnFocus; @@ -1616,7 +1712,7 @@ static void glitter_editor_windows(GlitterEditor* glt_edt, class_data* data) { ImGui::PushID("Glitter Editor Curve Editor Window"); if (ImGui::Begin("Curve Editor", 0, window_flags)) { if (glt_edt->effect_group && selected) - glitter_editor_curve_editor_windows(glt_edt); + glitter_editor_curve_editor_window(glt_edt); data->imgui_focus |= ImGui::IsWindowFocused(); ImGui::End(); } @@ -2979,7 +3075,7 @@ static void glitter_editor_property_effect(GlitterEditor* glt_edt, class_data* d changed = true; } - if (~effect->data.flags & Glitter::EFFECT_LOCAL && effect->data.ext_anim) { + if (!(effect->data.flags & Glitter::EFFECT_LOCAL) && effect->data.ext_anim) { ImGui::Separator(); bool changed = false; @@ -3375,13 +3471,13 @@ static void glitter_editor_property_emitter(GlitterEditor* glt_edt, class_data* bool prev_draw_z_axis = prev_direction == Glitter::EMITTER_DIRECTION_Z_AXIS; if (draw_z_axis && !prev_draw_z_axis) { - if (~flags & Glitter::CURVE_TYPE_ROTATION_Z) + if (!(flags & Glitter::CURVE_TYPE_ROTATION_Z)) emitter->animation.AddValue(eg->type, (float_t)M_PI_2, Glitter::CURVE_TYPE_ROTATION_Z); emitter->rotation.z += (float_t)M_PI_2; } else if (!draw_z_axis && prev_draw_z_axis) { - if (~flags & Glitter::CURVE_TYPE_ROTATION_Z) + if (!(flags & Glitter::CURVE_TYPE_ROTATION_Z)) emitter->animation.AddValue(eg->type, (float_t)-M_PI_2, Glitter::CURVE_TYPE_ROTATION_Z); emitter->rotation.z -= (float_t)M_PI_2; @@ -3692,13 +3788,13 @@ static void glitter_editor_property_particle(GlitterEditor* glt_edt, class_data* else if (!draw_prev_pos && prev_draw_prev_pos) particle->data.rotation.z -= (float_t)M_PI; else if (draw_z_axis && !prev_draw_z_axis) { - if (~flags & Glitter::CURVE_TYPE_ROTATION_Z) + if (!(flags & Glitter::CURVE_TYPE_ROTATION_Z)) particle->animation.AddValue(eg->type, (float_t)M_PI_2, Glitter::CURVE_TYPE_ROTATION_Z); particle->data.rotation.z += (float_t)M_PI_2; } else if (!draw_z_axis && prev_draw_z_axis) { - if (~flags & Glitter::CURVE_TYPE_ROTATION_Z) + if (!(flags & Glitter::CURVE_TYPE_ROTATION_Z)) particle->animation.AddValue(eg->type, (float_t)-M_PI_2, Glitter::CURVE_TYPE_ROTATION_Z); particle->data.rotation.z -= (float_t)M_PI_2; @@ -4929,21 +5025,15 @@ static void glitter_editor_file_save_popup(GlitterEditor* glt_edt, class_data* d ImGui::PopStyleVar(); } -static float_t convert_height_to_value(GlitterEditor* glt_edt, +inline static float_t convert_height_to_value(GlitterEditor::CurveEditor* crv_edt, float_t val, float_t pos, float_t size, float_t min, float_t max) { - GlitterEditor::CurveEditor* crv_edt = &glt_edt->curve_editor; - - float_t t = (val - pos - crv_edt->height_offset) - / (size - crv_edt->height_offset); + float_t t = (val - pos - crv_edt->height_offset) / (size - crv_edt->height_offset); return (1.0f - t) * (max - min) + min; } -static float_t convert_value_to_height(GlitterEditor* glt_edt, +inline static float_t convert_value_to_height(GlitterEditor::CurveEditor* crv_edt, float_t val, float_t pos, float_t size, float_t min, float_t max) { - GlitterEditor::CurveEditor* crv_edt = &glt_edt->curve_editor; - float_t t = 1.0f - (val - min) / (max - min); - return pos + t * (size - crv_edt->height_offset) - + crv_edt->height_offset; + return pos + t * (size - crv_edt->height_offset) + crv_edt->height_offset; } static void glitter_editor_curve_editor_curve_set(GlitterEditor* glt_edt, @@ -4973,15 +5063,15 @@ static Glitter::Curve::Key* glitter_editor_curve_editor_get_closest_key( GlitterEditor* glt_edt, Glitter::Curve* curve) { GlitterEditor::CurveEditor* crv_edt = &glt_edt->curve_editor; - std::vector::iterator key = {}; + Glitter::Curve::Key* key = 0; std::vector* keys = &curve->keys_rev; - for (std::vector::iterator i = keys->begin(); i != keys->end(); i++) { - if (i->frame == crv_edt->frame) - return &i[0]; + for (Glitter::Curve::Key& i : *keys) { + if (i.frame == crv_edt->frame) + return &i; - if (!key._Ptr || (key._Ptr && abs(i->frame - crv_edt->frame) + if (!key || (key && abs(i.frame - crv_edt->frame) <= abs(key->frame - crv_edt->frame))) - key = i; + key = &i; } return &key[0]; } @@ -4991,9 +5081,9 @@ static Glitter::Curve::Key* glitter_editor_curve_editor_get_selected_key( GlitterEditor::CurveEditor* crv_edt = &glt_edt->curve_editor; std::vector* keys = &curve->keys_rev; - for (std::vector::iterator i = keys->begin(); i != keys->end(); i++) - if (i->frame == crv_edt->frame) - return &i[0]; + for (Glitter::Curve::Key& i : *keys) + if (i.frame == crv_edt->frame) + return &i; return 0; } @@ -5119,10 +5209,10 @@ static void glitter_editor_curve_editor_key_manager(GlitterEditor* glt_edt, Glitter::Curve* curve = crv_edt->list[crv_edt->type]; *add_key = true; *del_key = false; - for (std::vector::iterator i = keys->begin(); i != keys->end(); i++) - if (i->frame > curve->end_time) + for (Glitter::Curve::Key& i : *keys) + if (i.frame > curve->end_time) break; - else if (i->frame == crv_edt->frame) { + else if (i.frame == crv_edt->frame) { *add_key = false; *del_key = true; break; @@ -5140,21 +5230,22 @@ static void glitter_editor_curve_editor_property_window(GlitterEditor* glt_edt, || crv_edt->type > Glitter::CURVE_V_SCROLL_ALPHA_2ND) return; - float_t scale; - float_t inv_scale; - float_t min; - Glitter::EffectGroup* eg = glt_edt->effect_group; Glitter::Curve* curve = crv_edt->list[crv_edt->type]; if (!curve) return; - bool fix_rot_z = eg->type != Glitter::X && curve->type == Glitter::CURVE_ROTATION_Z + const bool fix_rot_z = eg->type != Glitter::X && curve->type == Glitter::CURVE_ROTATION_Z && ((glt_edt->selected_type == GLITTER_EDITOR_SELECTED_EMITTER && sel_emit->data.direction == Glitter::DIRECTION_Z_AXIS) || (glt_edt->selected_type == GLITTER_EDITOR_SELECTED_PARTICLE && sel_ptcl->data.draw_type == Glitter::DIRECTION_Z_AXIS)); + float_t scale; + float_t inv_scale; + float_t min; + float_t min_random; + if (curve->type >= Glitter::CURVE_ROTATION_X && curve->type <= Glitter::CURVE_ROTATION_Z) { scale = RAD_TO_DEG_FLOAT; inv_scale = DEG_TO_RAD_FLOAT; @@ -5168,12 +5259,18 @@ static void glitter_editor_curve_editor_property_window(GlitterEditor* glt_edt, inv_scale = 1.0f; } - if (curve->type == Glitter::CURVE_EMISSION_INTERVAL) + if (curve->type == Glitter::CURVE_EMISSION_INTERVAL) { min = -1.0f; - else if (curve->type == Glitter::CURVE_PARTICLES_PER_EMISSION) + min_random = 0.0f; + } + else if (curve->type == Glitter::CURVE_PARTICLES_PER_EMISSION) { min = 0.0f; - else + min_random = 0.0f; + } + else { min = -FLT_MAX; + min_random = -FLT_MAX; + } bool random_range = curve->flags & Glitter::CURVE_RANDOM_RANGE ? true : false; bool key_random_range = curve->flags & Glitter::CURVE_KEY_RANDOM_RANGE ? true : false; @@ -5183,14 +5280,16 @@ static void glitter_editor_curve_editor_property_window(GlitterEditor* glt_edt, float_t value = 0.0f; if (curve->keys_rev.size() > 1) { - std::vector::iterator c = curve->keys_rev.begin(); - std::vector::iterator n = c + 1; - while (n != curve->keys_rev.end() && n->frame < crv_edt->frame) { + Glitter::Curve::Key* i_begin = curve->keys_rev.data(); + Glitter::Curve::Key* i_end = curve->keys_rev.data() + curve->keys_rev.size(); + Glitter::Curve::Key* c = i_begin; + Glitter::Curve::Key* n = c + 1; + while (n != i_end && n->frame < crv_edt->frame) { c++; n++; } - if (c + 1 != curve->keys_rev.end()) + if (c + 1 != i_end) switch (c->type) { case Glitter::KEY_CONSTANT: value = n->frame == crv_edt->frame ? n->value : c->value; @@ -5243,7 +5342,7 @@ static void glitter_editor_curve_editor_property_window(GlitterEditor* glt_edt, ImGui::DisableElementPush(key_random_range); float_t random = c->random_range * scale; if (ImGui::ColumnDragFloat("Random Range", - &random, 0.0001f, 0.0f, FLT_MAX, "%g", + &random, 0.0001f, min_random, FLT_MAX, "%g", ImGuiSliderFlags_NoRoundToFormat)) { random *= inv_scale; if (random != c->random_range) { @@ -5310,7 +5409,7 @@ static void glitter_editor_curve_editor_property_window(GlitterEditor* glt_edt, ImGui::DisableElementPush(random_range); float_t random = curve->random_range * scale; if (ImGui::ColumnDragFloat("Random Range", - &random, 0.0001f, 0.0f, FLT_MAX, "%g", + &random, 0.0001f, min_random, FLT_MAX, "%g", ImGuiSliderFlags_NoRoundToFormat)) { random *= inv_scale; if (random != curve->random_range) { @@ -5390,7 +5489,7 @@ static void glitter_editor_curve_editor_property_window(GlitterEditor* glt_edt, Glitter::CURVE_STEP)) changed = true; - if (ImGui::CheckboxFlagsEnterKeyPressed("Random Negate", + if (ImGui::CheckboxFlagsEnterKeyPressed("Curve Negate", (uint32_t*)&curve->flags, Glitter::CURVE_NEGATE)) changed = true; @@ -5417,6 +5516,46 @@ static void glitter_editor_curve_editor_property_window(GlitterEditor* glt_edt, } } +static void glitter_editor_curve_editor_selector_list_box_selectable(GlitterEditor* glt_edt, + const Glitter::CurveTypeFlags flags, const char* label, const Glitter::CurveType type, bool& reset) { + if (!(flags & type)) + return; + + GlitterEditor::CurveEditor* crv_edt = &glt_edt->curve_editor; + + char buf[0x40]; + sprintf_s(buf, sizeof(buf), crv_edt->list[type] ? "%s [*]" : "%s", label); + if (!ImGui::Selectable(buf, crv_edt->type == type)) + return; + + if (crv_edt->type != type) { + glt_edt->curve_editor.ResetState(type); + reset = true; + } +} + +static void glitter_editor_curve_editor_selector_list_box_multi_selectable(GlitterEditor* glt_edt, + const Glitter::CurveTypeFlags flags, const char* label, const Glitter::CurveType type, bool& reset) { + if (!(flags & (1 << type))) + return; + + GlitterEditor::CurveEditor* crv_edt = &glt_edt->curve_editor; + + char buf[0x40]; + sprintf_s(buf, sizeof(buf), crv_edt->type_flags & (1 << type) + ? (crv_edt->list[type] ? "[V] %s [*]" : "[V] %s") + : (crv_edt->list[type] ? " %s [*]" : " %s"), label); + if (!ImGui::Selectable(buf, crv_edt->type == type)) + return; + + if (Input::IsKeyDown(GLFW_KEY_LEFT_CONTROL) || Input::IsKeyDown(GLFW_KEY_RIGHT_CONTROL)) + glt_edt->curve_editor.SetFlag((Glitter::CurveTypeFlags)(1 << type)); + else if (crv_edt->type != type) { + glt_edt->curve_editor.ResetState(type); + reset = true; + } +} + static void glitter_editor_curve_editor_selector(GlitterEditor* glt_edt, class_data* data) { GlitterEditor::CurveEditor* crv_edt = &glt_edt->curve_editor; int32_t sel_rsrc = glt_edt->selected_resource; @@ -5474,23 +5613,15 @@ static void glitter_editor_curve_editor_selector(GlitterEditor* glt_edt, class_d tree_node_flags |= ImGuiTreeNodeFlags_OpenOnArrow; tree_node_flags |= ImGuiTreeNodeFlags_SpanAvailWidth; -#define LIST_BOX(label, curve_type) \ -if (flags & Glitter::CURVE_TYPE_##curve_type){ \ - const char* _l = crv_edt->list[Glitter::CURVE_##curve_type] ? label" [*]" : label; \ - ImGui::Selectable(_l, crv_edt->type == Glitter::CURVE_##curve_type); \ -\ - if (ImGui::IsItemFocused() && crv_edt->type != Glitter::CURVE_##curve_type) { \ - glt_edt->curve_editor.ResetState(Glitter::CURVE_##curve_type); \ - reset = true; \ - } \ -} - if (flags & Glitter::CURVE_TYPE_TRANSLATION_XYZ && ImGui::TreeNodeEx("Translation", tree_node_flags)) { ImGui::PushID("T"); - LIST_BOX("X", TRANSLATION_X); - LIST_BOX("Y", TRANSLATION_Y); - LIST_BOX("Z", TRANSLATION_Z); + glitter_editor_curve_editor_selector_list_box_multi_selectable(glt_edt, flags, "X", + Glitter::CURVE_TRANSLATION_X, reset); + glitter_editor_curve_editor_selector_list_box_multi_selectable(glt_edt, flags, "Y", + Glitter::CURVE_TRANSLATION_Y, reset); + glitter_editor_curve_editor_selector_list_box_multi_selectable(glt_edt, flags, "Z", + Glitter::CURVE_TRANSLATION_Z, reset); ImGui::PopID(); ImGui::TreePop(); } @@ -5498,9 +5629,12 @@ if (flags & Glitter::CURVE_TYPE_##curve_type){ \ if (flags & Glitter::CURVE_TYPE_ROTATION_XYZ && ImGui::TreeNodeEx("Rotation", tree_node_flags)) { ImGui::PushID("R"); - LIST_BOX("X", ROTATION_X); - LIST_BOX("Y", ROTATION_Y); - LIST_BOX("Z", ROTATION_Z); + glitter_editor_curve_editor_selector_list_box_multi_selectable(glt_edt, flags, "X", + Glitter::CURVE_ROTATION_X, reset); + glitter_editor_curve_editor_selector_list_box_multi_selectable(glt_edt, flags, "Y", + Glitter::CURVE_ROTATION_Y, reset); + glitter_editor_curve_editor_selector_list_box_multi_selectable(glt_edt, flags, "Z", + Glitter::CURVE_ROTATION_Z, reset); ImGui::PopID(); ImGui::TreePop(); } @@ -5508,10 +5642,14 @@ if (flags & Glitter::CURVE_TYPE_##curve_type){ \ if (flags & (Glitter::CURVE_TYPE_SCALE_XYZ | Glitter::CURVE_TYPE_SCALE_ALL) && ImGui::TreeNodeEx("Scale", tree_node_flags)) { ImGui::PushID("S"); - LIST_BOX("X", SCALE_X); - LIST_BOX("Y", SCALE_Y); - LIST_BOX("Z", SCALE_Z); - LIST_BOX("All", SCALE_ALL); + glitter_editor_curve_editor_selector_list_box_multi_selectable(glt_edt, flags, "X", + Glitter::CURVE_SCALE_X, reset); + glitter_editor_curve_editor_selector_list_box_multi_selectable(glt_edt, flags, "Y", + Glitter::CURVE_SCALE_Y, reset); + glitter_editor_curve_editor_selector_list_box_multi_selectable(glt_edt, flags, "Z", + Glitter::CURVE_SCALE_Z, reset); + glitter_editor_curve_editor_selector_list_box_multi_selectable(glt_edt, flags, "All", + Glitter::CURVE_SCALE_ALL, reset); ImGui::PopID(); ImGui::TreePop(); } @@ -5519,11 +5657,16 @@ if (flags & Glitter::CURVE_TYPE_##curve_type){ \ if (flags & (Glitter::CURVE_TYPE_COLOR_RGBA | Glitter::CURVE_TYPE_COLOR_RGB_SCALE) && ImGui::TreeNodeEx("Color", tree_node_flags)) { ImGui::PushID("C"); - LIST_BOX("R", COLOR_R); - LIST_BOX("G", COLOR_G); - LIST_BOX("B", COLOR_B); - LIST_BOX("A", COLOR_A); - LIST_BOX("RGB Scale", COLOR_RGB_SCALE); + glitter_editor_curve_editor_selector_list_box_multi_selectable(glt_edt, flags, "R", + Glitter::CURVE_COLOR_R, reset); + glitter_editor_curve_editor_selector_list_box_multi_selectable(glt_edt, flags, "G", + Glitter::CURVE_COLOR_G, reset); + glitter_editor_curve_editor_selector_list_box_multi_selectable(glt_edt, flags, "B", + Glitter::CURVE_COLOR_B, reset); + glitter_editor_curve_editor_selector_list_box_multi_selectable(glt_edt, flags, "A", + Glitter::CURVE_COLOR_A, reset); + glitter_editor_curve_editor_selector_list_box_multi_selectable(glt_edt, flags, "RGB Scale", + Glitter::CURVE_COLOR_RGB_SCALE, reset); ImGui::PopID(); ImGui::TreePop(); } @@ -5531,25 +5674,36 @@ if (flags & Glitter::CURVE_TYPE_##curve_type){ \ if (flags & (Glitter::CURVE_TYPE_COLOR_RGBA_2ND | Glitter::CURVE_TYPE_COLOR_RGB_SCALE_2ND) && ImGui::TreeNodeEx("Color 2nd", tree_node_flags)) { ImGui::PushID("C2"); - LIST_BOX("R", COLOR_R_2ND); - LIST_BOX("G", COLOR_G_2ND); - LIST_BOX("B", COLOR_B_2ND); - LIST_BOX("A", COLOR_A_2ND); - LIST_BOX("RGB Scale", COLOR_RGB_SCALE_2ND); + glitter_editor_curve_editor_selector_list_box_multi_selectable(glt_edt, flags, "R", + Glitter::CURVE_COLOR_R_2ND, reset); + glitter_editor_curve_editor_selector_list_box_multi_selectable(glt_edt, flags, "G", + Glitter::CURVE_COLOR_G_2ND, reset); + glitter_editor_curve_editor_selector_list_box_multi_selectable(glt_edt, flags, "B", + Glitter::CURVE_COLOR_B_2ND, reset); + glitter_editor_curve_editor_selector_list_box_multi_selectable(glt_edt, flags, "A", + Glitter::CURVE_COLOR_A_2ND, reset); + glitter_editor_curve_editor_selector_list_box_multi_selectable(glt_edt, flags, "RGB Scale", + Glitter::CURVE_COLOR_RGB_SCALE_2ND, reset); ImGui::PopID(); ImGui::TreePop(); } - LIST_BOX("Emit Interval", EMISSION_INTERVAL); - LIST_BOX("PTC Per Emit", PARTICLES_PER_EMISSION); + glitter_editor_curve_editor_selector_list_box_selectable(glt_edt, flags, "Emit Interval", + Glitter::CURVE_EMISSION_INTERVAL, reset); + glitter_editor_curve_editor_selector_list_box_selectable(glt_edt, flags, "PTC Per Emit", + Glitter::CURVE_PARTICLES_PER_EMISSION, reset); if (flags & (Glitter::CURVE_TYPE_UV_SCROLL | Glitter::CURVE_TYPE_UV_SCROLL_ALPHA) && ImGui::TreeNodeEx("UV Scroll", tree_node_flags)) { ImGui::PushID("UV"); - LIST_BOX("U", U_SCROLL); - LIST_BOX("V", V_SCROLL); - LIST_BOX("U Alpha", U_SCROLL_ALPHA); - LIST_BOX("V Alpha", V_SCROLL_ALPHA); + glitter_editor_curve_editor_selector_list_box_multi_selectable(glt_edt, flags, "Y", + Glitter::CURVE_U_SCROLL, reset); + glitter_editor_curve_editor_selector_list_box_multi_selectable(glt_edt, flags, "V", + Glitter::CURVE_V_SCROLL, reset); + glitter_editor_curve_editor_selector_list_box_multi_selectable(glt_edt, flags, "U Alpha", + Glitter::CURVE_U_SCROLL_ALPHA, reset); + glitter_editor_curve_editor_selector_list_box_multi_selectable(glt_edt, flags, "V Alpha", + Glitter::CURVE_V_SCROLL_ALPHA, reset); ImGui::PopID(); ImGui::TreePop(); } @@ -5557,14 +5711,17 @@ if (flags & Glitter::CURVE_TYPE_##curve_type){ \ if (flags & (Glitter::CURVE_TYPE_UV_SCROLL_2ND | Glitter::CURVE_TYPE_UV_SCROLL_ALPHA_2ND) && ImGui::TreeNodeEx("UV Scroll 2nd", tree_node_flags)) { ImGui::PushID("UV2"); - LIST_BOX("U", U_SCROLL_2ND); - LIST_BOX("V", V_SCROLL_2ND); - LIST_BOX("U Alpha", U_SCROLL_ALPHA_2ND); - LIST_BOX("V Alpha", V_SCROLL_ALPHA_2ND); + glitter_editor_curve_editor_selector_list_box_multi_selectable(glt_edt, flags, "U", + Glitter::CURVE_U_SCROLL_2ND, reset); + glitter_editor_curve_editor_selector_list_box_multi_selectable(glt_edt, flags, "V", + Glitter::CURVE_V_SCROLL_2ND, reset); + glitter_editor_curve_editor_selector_list_box_multi_selectable(glt_edt, flags, "U Alpha", + Glitter::CURVE_U_SCROLL_ALPHA_2ND, reset); + glitter_editor_curve_editor_selector_list_box_multi_selectable(glt_edt, flags, "V Alpha", + Glitter::CURVE_V_SCROLL_ALPHA_2ND, reset); ImGui::PopID(); ImGui::TreePop(); } -#undef LIST_BOX data->imgui_focus |= ImGui::IsWindowFocused(); ImGui::EndListBox(); } @@ -5592,6 +5749,8 @@ if (flags & Glitter::CURVE_TYPE_##curve_type){ \ ImGui::ColumnDragFloat("Range", &crv_edt->range, 0.0001f, 0.0f, FLT_MAX, "%g", 0); + ImGui::ColumnDragFloat("Offset", + &crv_edt->offset, 0.0001f, -FLT_MAX, FLT_MAX, "%g", 0); ImGui::SetDefaultColumnSpace(); bool add_key = false; @@ -5624,7 +5783,7 @@ if (flags & Glitter::CURVE_TYPE_##curve_type){ \ ImGui::EndGroup(); } -static void glitter_editor_curve_editor_windows(GlitterEditor* glt_edt) { +static void glitter_editor_curve_editor_window(GlitterEditor* glt_edt) { Glitter::Emitter* sel_emit = glt_edt->selected_emitter; Glitter::Particle* sel_ptcl = glt_edt->selected_particle; GlitterEditor::CurveEditor* crv_edt = &glt_edt->curve_editor; @@ -5667,6 +5826,9 @@ static void glitter_editor_curve_editor_windows(GlitterEditor* glt_edt) { crv_edt->frame++; else if (ImGui::IsKeyPressed(GLFW_KEY_LEFT)) crv_edt->frame--; + + if (curve) + crv_edt->frame = clamp_def(crv_edt->frame, curve->start_time, curve->end_time); } bool exist = true; @@ -5693,23 +5855,25 @@ static void glitter_editor_curve_editor_windows(GlitterEditor* glt_edt) { changed = true; } else { - std::vector::iterator i = keys->begin(); + Glitter::Curve::Key* i_begin = keys->data(); + Glitter::Curve::Key* i_end = keys->data() + keys->size(); + Glitter::Curve::Key* i = i_begin; bool is_before_start = keys->data()[0].frame > crv_edt->frame; bool has_key_after = false; if (!is_before_start) - for (i++; i != keys->end(); i++) + for (i++; i != i_end; i++) if (crv_edt->frame <= i->frame) { - has_key_after = keys->end() - i > 0; + has_key_after = i_end - i > 0; break; } - ssize_t pos = i - keys->begin(); + ssize_t pos = i - i_begin; if (!is_before_start) pos--; if (!is_before_start && has_key_after) { - std::vector::iterator c = i - 1; - std::vector::iterator n = i; + Glitter::Curve::Key* c = i - 1; + Glitter::Curve::Key* n = i; Glitter::Curve::Key key; key.frame = crv_edt->frame; @@ -5737,7 +5901,7 @@ static void glitter_editor_curve_editor_windows(GlitterEditor* glt_edt) { keys->insert(keys->begin() + ++pos, key); } else if (is_before_start) { - std::vector::iterator n = i; + Glitter::Curve::Key* n = i; Glitter::Curve::Key key; key.frame = crv_edt->frame; @@ -5747,7 +5911,7 @@ static void glitter_editor_curve_editor_windows(GlitterEditor* glt_edt) { keys->insert(keys->begin() + pos, key); } else { - std::vector::iterator c = i - 1; + Glitter::Curve::Key* c = i - 1; Glitter::Curve::Key key; key.frame = crv_edt->frame; @@ -5761,13 +5925,15 @@ static void glitter_editor_curve_editor_windows(GlitterEditor* glt_edt) { } } else if (keys && crv_edt->del_key && del_key) { - for (std::vector::iterator i = keys->begin(); i != keys->end(); i++) + Glitter::Curve::Key* i_begin = keys->data(); + Glitter::Curve::Key* i_end = keys->data() + keys->size(); + for (Glitter::Curve::Key* i = i_begin; i != i_end; i++) if (&i[0] == crv_edt->key) { bool has_key_before = keys->front().frame < i->frame; bool has_key_after = keys->back().frame > i->frame; if (has_key_before && i[-1].type == Glitter::KEY_HERMITE && has_key_after) { - std::vector::iterator c = i - 1; - std::vector::iterator n = i + 1; + Glitter::Curve::Key* c = i - 1; + Glitter::Curve::Key* n = i + 1; int32_t df_c = i->frame - c->frame; int32_t df_n = n->frame - i->frame; @@ -5786,7 +5952,7 @@ static void glitter_editor_curve_editor_windows(GlitterEditor* glt_edt) { n->tangent1, 0, (size_t)n->frame - c->frame); delete[] v_arr; } - keys->erase(i); + keys->erase(keys->begin() + (i - i_begin)); changed = true; break; } @@ -5834,7 +6000,8 @@ static void glitter_editor_curve_editor_windows(GlitterEditor* glt_edt) { ImVec2 cont_reg_avail = ImGui::GetContentRegionAvail(); ImVec2 canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max; - crv_edt->draw_list = ImGui::GetWindowDrawList(); + ImDrawList* draw_list = ImGui::GetWindowDrawList(); + crv_edt->draw_list = draw_list; canvas_size = cont_reg_avail; canvas_pos = ImGui::GetCursorScreenPos(); canvas_pos_min.x = canvas_pos.x; @@ -5854,8 +6021,7 @@ static void glitter_editor_curve_editor_windows(GlitterEditor* glt_edt) { } crv_edt->prev_zoom_time = crv_edt->zoom_time; - float_t frame_width = crv_edt->frame_width - * crv_edt->zoom_time; + float_t frame_width = crv_edt->frame_width * crv_edt->zoom_time; canvas_pos.x -= crv_edt->timeline_pos; ImGui::ItemSize(boundaries); @@ -5879,15 +6045,19 @@ static void glitter_editor_curve_editor_windows(GlitterEditor* glt_edt) { float_t timeline_max_offset = (end_time - start_time) * frame_width; timeline_max_offset = max_def(timeline_max_offset, 0.0f) - curve_editor_timeline_base_pos; - crv_edt->draw_list->PushClipRect(boundaries.Min, boundaries.Max, true); + draw_list->PushClipRect(boundaries.Min, boundaries.Max, true); - int32_t start = (int32_t)(crv_edt->timeline_pos / frame_width) + start_time; - int32_t end = (int32_t)((crv_edt->timeline_pos + canvas_size.x) / frame_width) + start_time; + const int32_t graph_start = start_time + (int32_t)((crv_edt->timeline_pos + + frame_width - 1.0f) / frame_width); + const int32_t graph_end = start_time + (int32_t)((crv_edt->timeline_pos + canvas_size.x + + frame_width - 1.0f) / frame_width); - ImU32 line_color_valid_bold = ImGui::GetColorU32({ 0.5f, 0.5f, 0.5f, 0.75f }); - ImU32 line_color_valid = ImGui::GetColorU32({ 0.4f, 0.4f, 0.4f, 0.45f }); - ImU32 line_color_not_valid = ImGui::GetColorU32({ 0.2f, 0.2f, 0.2f, 0.75f }); - for (int32_t frame = start; frame <= end; frame++) { + const ImU32 line_color_valid_bold = ImGui::GetColorU32({ 0.5f, 0.5f, 0.5f, 0.75f }); + const ImU32 line_color_valid = ImGui::GetColorU32({ 0.4f, 0.4f, 0.4f, 0.45f }); + const ImU32 line_color_not_valid_bold = ImGui::GetColorU32({ 0.3f, 0.3f, 0.3f, 0.75f }); + const ImU32 line_color_not_valid = ImGui::GetColorU32({ 0.2f, 0.2f, 0.2f, 0.45f }); + + for (int32_t frame = graph_start; frame <= graph_end; frame++) { if (frame < start_time) continue; @@ -5898,45 +6068,39 @@ static void glitter_editor_curve_editor_windows(GlitterEditor* glt_edt) { bool bold_frame = !(f % 10) || !f || frame == end_time; bool valid_frame = f >= 0 && frame <= end_time; - ImU32 line_color = valid_frame ? (bold_frame ? line_color_valid_bold - : line_color_valid) : line_color_not_valid; - crv_edt->draw_list->AddLine({ x, y - canvas_size.y }, + ImU32 line_color = bold_frame + ? (valid_frame ? line_color_valid_bold : line_color_not_valid_bold) + : (valid_frame ? line_color_valid : line_color_not_valid ); + draw_list->AddLine({ x, y - canvas_size.y }, { x, y }, line_color, 0.80f); if (bold_frame) { char buf[0x20]; snprintf(buf, sizeof(buf), "%d", frame); - crv_edt->draw_list->AddText({ x + 3, canvas_pos.y }, line_color, buf); + draw_list->AddText({ x + 3, canvas_pos.y }, line_color, buf); } } float_t max = crv_edt->range * (1.0f / crv_edt->zoom_value); float_t min; - if (curve->type == Glitter::CURVE_EMISSION_INTERVAL) + if (curve->type == Glitter::CURVE_EMISSION_INTERVAL) { min = -1.0f; - else if (curve->type == Glitter::CURVE_PARTICLES_PER_EMISSION) + if (crv_edt->offset > 0.0f) { + min += crv_edt->offset * (1.0f / crv_edt->zoom_value); + max += crv_edt->offset * (1.0f / crv_edt->zoom_value); + } + } + else if (curve->type == Glitter::CURVE_PARTICLES_PER_EMISSION) { min = 0.0f; - else + if (crv_edt->offset > 0.0f) { + min += crv_edt->offset * (1.0f / crv_edt->zoom_value); + max += crv_edt->offset * (1.0f / crv_edt->zoom_value); + } + } + else { min = -max; - - for (int32_t j = 0; j < 5; j++) { - float_t x_pos = canvas_pos_min.x; - float_t y_pos = canvas_pos.y + j * 0.25f * (canvas_size.y - - crv_edt->height_offset) + crv_edt->height_offset; - - ImU32 line_color = j % 2 == 1 - ? ImGui::GetColorU32({ 0.35f, 0.35f, 0.35f, 0.45f }) - : ImGui::GetColorU32({ 0.45f, 0.45f, 0.45f, 0.75f }); - bool last = j == 4; - if (j && !last) - crv_edt->draw_list->AddLine({ x_pos, y_pos }, - { x_pos + canvas_size.x, y_pos }, line_color, 0.80f); - - float_t val = max - j * 0.25f * (max - min); - char buf[0x20]; - snprintf(buf, sizeof(buf), "%.2f", val); - crv_edt->draw_list->AddText({ x_pos + 2, y_pos + (last ? -16 : -2) }, - ImGui::GetColorU32({ 0.65f, 0.65f, 0.65f, 0.85f }), buf); + min += crv_edt->offset * (1.0f / crv_edt->zoom_value); + max += crv_edt->offset * (1.0f / crv_edt->zoom_value); } if (curve->type >= Glitter::CURVE_ROTATION_X && curve->type <= Glitter::CURVE_ROTATION_Z) { @@ -5948,7 +6112,7 @@ static void glitter_editor_curve_editor_windows(GlitterEditor* glt_edt) { min *= (float_t)(1.0 / 255.0); } - float_t base_line = convert_value_to_height(glt_edt, 0.0f, canvas_pos.y, canvas_size.y, min, max); + float_t base_line = convert_value_to_height(crv_edt, 0.0f, canvas_pos.y, canvas_size.y, min, max); ImVec2 p1, p2, p3; p1.x = canvas_pos_min.x; @@ -5957,337 +6121,327 @@ static void glitter_editor_curve_editor_windows(GlitterEditor* glt_edt) { p2.y = canvas_pos.y + crv_edt->height_offset; p3.x = canvas_pos_min.x; p3.y = canvas_pos.y; - crv_edt->draw_list->AddLine(p1, p2, + draw_list->AddLine(p1, p2, ImGui::GetColorU32({ 0.5f, 0.5f, 0.5f, 0.85f }), 2.0f); - ImU32 random_range_color = ImGui::GetColorU32({ 0.5f, 0.5f, 0.0f, 0.25f }); - ImU32 key_random_range_color = ImGui::GetColorU32({ 0.5f, 0.0f, 0.5f, 0.25f }); - ImU32 default_color = ImGui::GetColorU32({ 1.0f, 1.0f, 1.0f, 0.75f }); - ImU32 selected_color = ImGui::GetColorU32({ 0.0f, 1.0f, 1.0f, 0.75f }); + const ImU32 red_color = ImGui::GetColorU32({ 1.0f, 0.0f, 0.0f, 1.00f }); + const ImU32 green_color = ImGui::GetColorU32({ 0.0f, 1.0f, 0.0f, 1.00f }); + const ImU32 blue_color = ImGui::GetColorU32({ 0.0f, 0.0f, 1.0f, 1.00f }); + const ImU32 white_color = ImGui::GetColorU32({ 1.0f, 1.0f, 1.0f, 1.00f }); + const ImU32 nwhite_color = ImGui::GetColorU32({ 1.0f, 1.0f, 1.0f, 0.75f }); + const ImU32 red_bcolor = ImGui::GetColorU32({ 1.0f, 0.0f, 0.0f, 0.50f }); + const ImU32 green_bcolor = ImGui::GetColorU32({ 0.0f, 1.0f, 0.0f, 0.50f }); + const ImU32 blue_bcolor = ImGui::GetColorU32({ 0.0f, 0.0f, 1.0f, 0.50f }); + const ImU32 white_bcolor = ImGui::GetColorU32({ 1.0f, 1.0f, 1.0f, 0.50f }); + const ImU32 nwhite_bcolor = ImGui::GetColorU32({ 1.0f, 1.0f, 1.0f, 0.25f }); - if (curve->flags & Glitter::CURVE_RANDOM_RANGE - || curve->flags & Glitter::CURVE_KEY_RANDOM_RANGE) { - float_t random_range = curve->random_range; - bool random_range_mult = curve->flags & Glitter::CURVE_RANDOM_RANGE_MULT; - bool random_range_negate = curve->flags & Glitter::CURVE_RANDOM_RANGE_NEGATE; - bool glt_type_ft = eg->type == Glitter::FT; - for (std::vector::iterator i = keys->begin(); i != keys->end(); i++) { - if (i->frame >= end_time || keys->end() - i <= 1) - break; + const ImU32 default_color = ImGui::GetColorU32({ 1.0f, 1.0f, 1.0f, 1.0f }); + const ImU32 selected_color = ImGui::GetColorU32({ 0.0f, 1.0f, 1.0f, 1.0f }); - std::vector::iterator c = i; - std::vector::iterator n = i + 1; - float_t x1 = canvas_pos.x + (float_t)(c->frame - start_time) * frame_width; - float_t x2 = canvas_pos.x + (float_t)(n->frame - start_time) * frame_width; + switch (crv_edt->type) { + case Glitter::CURVE_TRANSLATION_X: + glitter_editor_curve_editor_window_draw(glt_edt, Glitter::CURVE_TRANSLATION_Y, green_bcolor, false, + min, max, canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max); + glitter_editor_curve_editor_window_draw(glt_edt, Glitter::CURVE_TRANSLATION_Z, blue_bcolor, false, + min, max, canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max); + glitter_editor_curve_editor_window_draw(glt_edt, Glitter::CURVE_TRANSLATION_X, red_color , true, + min, max, canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max); + break; + case Glitter::CURVE_TRANSLATION_Y: + glitter_editor_curve_editor_window_draw(glt_edt, Glitter::CURVE_TRANSLATION_X, red_bcolor, false, + min, max, canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max); + glitter_editor_curve_editor_window_draw(glt_edt, Glitter::CURVE_TRANSLATION_Z, blue_bcolor, false, + min, max, canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max); + glitter_editor_curve_editor_window_draw(glt_edt, Glitter::CURVE_TRANSLATION_Y, green_color , true, + min, max, canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max); + break; + case Glitter::CURVE_TRANSLATION_Z: + glitter_editor_curve_editor_window_draw(glt_edt, Glitter::CURVE_TRANSLATION_X, red_bcolor, false, + min, max, canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max); + glitter_editor_curve_editor_window_draw(glt_edt, Glitter::CURVE_TRANSLATION_Y, green_bcolor, false, + min, max, canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max); + glitter_editor_curve_editor_window_draw(glt_edt, Glitter::CURVE_TRANSLATION_Z, blue_color , true, + min, max, canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max); - if (((x1 < canvas_pos_min.x) && (x2 < canvas_pos_min.x)) || - (x1 > canvas_pos_max.x) && (x2 > canvas_pos_max.x)) - continue; + break; + case Glitter::CURVE_ROTATION_X: + glitter_editor_curve_editor_window_draw(glt_edt, Glitter::CURVE_ROTATION_Y, green_bcolor, false, + min, max, canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max); + glitter_editor_curve_editor_window_draw(glt_edt, Glitter::CURVE_ROTATION_Z, blue_bcolor, false, + min, max, canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max); + glitter_editor_curve_editor_window_draw(glt_edt, Glitter::CURVE_ROTATION_X, red_color , true, + min, max, canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max); + break; + case Glitter::CURVE_ROTATION_Y: + glitter_editor_curve_editor_window_draw(glt_edt, Glitter::CURVE_ROTATION_X, red_bcolor, false, + min, max, canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max); + glitter_editor_curve_editor_window_draw(glt_edt, Glitter::CURVE_ROTATION_Z, blue_bcolor, false, + min, max, canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max); + glitter_editor_curve_editor_window_draw(glt_edt, Glitter::CURVE_ROTATION_Y, green_color , true, + min, max, canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max); + break; + case Glitter::CURVE_ROTATION_Z: + glitter_editor_curve_editor_window_draw(glt_edt, Glitter::CURVE_ROTATION_X, red_bcolor, false, + min, max, canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max); + glitter_editor_curve_editor_window_draw(glt_edt, Glitter::CURVE_ROTATION_Y, green_bcolor, false, + min, max, canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max); + glitter_editor_curve_editor_window_draw(glt_edt, Glitter::CURVE_ROTATION_Z, blue_color , true, + min, max, canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max); + break; + case Glitter::CURVE_SCALE_X: + glitter_editor_curve_editor_window_draw(glt_edt, Glitter::CURVE_SCALE_Y , green_bcolor, false, + min, max, canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max); + glitter_editor_curve_editor_window_draw(glt_edt, Glitter::CURVE_SCALE_Z , blue_bcolor, false, + min, max, canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max); + glitter_editor_curve_editor_window_draw(glt_edt, Glitter::CURVE_SCALE_ALL, nwhite_bcolor, false, + min, max, canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max); + glitter_editor_curve_editor_window_draw(glt_edt, Glitter::CURVE_SCALE_X , red_color , true, + min, max, canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max); + break; + case Glitter::CURVE_SCALE_Y: + glitter_editor_curve_editor_window_draw(glt_edt, Glitter::CURVE_SCALE_X , red_bcolor, false, + min, max, canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max); + glitter_editor_curve_editor_window_draw(glt_edt, Glitter::CURVE_SCALE_Z , blue_bcolor, false, + min, max, canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max); + glitter_editor_curve_editor_window_draw(glt_edt, Glitter::CURVE_SCALE_ALL, nwhite_bcolor, false, + min, max, canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max); + glitter_editor_curve_editor_window_draw(glt_edt, Glitter::CURVE_SCALE_Y , green_color , true, + min, max, canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max); + break; + case Glitter::CURVE_SCALE_Z: + glitter_editor_curve_editor_window_draw(glt_edt, Glitter::CURVE_SCALE_X , red_bcolor, false, + min, max, canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max); + glitter_editor_curve_editor_window_draw(glt_edt, Glitter::CURVE_SCALE_Y , green_bcolor, false, + min, max, canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max); + glitter_editor_curve_editor_window_draw(glt_edt, Glitter::CURVE_SCALE_ALL, nwhite_bcolor, false, + min, max, canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max); + glitter_editor_curve_editor_window_draw(glt_edt, Glitter::CURVE_SCALE_Z , blue_color , true, + min, max, canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max); + break; + case Glitter::CURVE_SCALE_ALL: + glitter_editor_curve_editor_window_draw(glt_edt, Glitter::CURVE_SCALE_X , red_bcolor, false, + min, max, canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max); + glitter_editor_curve_editor_window_draw(glt_edt, Glitter::CURVE_SCALE_Y , green_bcolor, false, + min, max, canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max); + glitter_editor_curve_editor_window_draw(glt_edt, Glitter::CURVE_SCALE_Z , blue_bcolor, false, + min, max, canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max); + glitter_editor_curve_editor_window_draw(glt_edt, Glitter::CURVE_SCALE_ALL, nwhite_color , true, + min, max, canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max); + break; + case Glitter::CURVE_COLOR_R: + glitter_editor_curve_editor_window_draw(glt_edt, Glitter::CURVE_COLOR_G , blue_bcolor, false, + min, max, canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max); + glitter_editor_curve_editor_window_draw(glt_edt, Glitter::CURVE_COLOR_B , green_bcolor, false, + min, max, canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max); + glitter_editor_curve_editor_window_draw(glt_edt, Glitter::CURVE_COLOR_A , white_bcolor, false, + min, max, canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max); + glitter_editor_curve_editor_window_draw(glt_edt, Glitter::CURVE_COLOR_RGB_SCALE, nwhite_bcolor, false, + min, max, canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max); + glitter_editor_curve_editor_window_draw(glt_edt, Glitter::CURVE_COLOR_R , red_color , true, + min, max, canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max); + break; + case Glitter::CURVE_COLOR_G: + glitter_editor_curve_editor_window_draw(glt_edt, Glitter::CURVE_COLOR_R , red_bcolor, false, + min, max, canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max); + glitter_editor_curve_editor_window_draw(glt_edt, Glitter::CURVE_COLOR_B , green_bcolor, false, + min, max, canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max); + glitter_editor_curve_editor_window_draw(glt_edt, Glitter::CURVE_COLOR_A , white_bcolor, false, + min, max, canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max); + glitter_editor_curve_editor_window_draw(glt_edt, Glitter::CURVE_COLOR_RGB_SCALE, nwhite_bcolor, false, + min, max, canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max); + glitter_editor_curve_editor_window_draw(glt_edt, Glitter::CURVE_COLOR_G , blue_color , true, + min, max, canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max); + break; + case Glitter::CURVE_COLOR_B: + glitter_editor_curve_editor_window_draw(glt_edt, Glitter::CURVE_COLOR_R , red_bcolor, false, + min, max, canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max); + glitter_editor_curve_editor_window_draw(glt_edt, Glitter::CURVE_COLOR_G , blue_bcolor, false, + min, max, canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max); + glitter_editor_curve_editor_window_draw(glt_edt, Glitter::CURVE_COLOR_A , white_bcolor, false, + min, max, canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max); + glitter_editor_curve_editor_window_draw(glt_edt, Glitter::CURVE_COLOR_RGB_SCALE, nwhite_bcolor, false, + min, max, canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max); + glitter_editor_curve_editor_window_draw(glt_edt, Glitter::CURVE_COLOR_B , green_color , true, + min, max, canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max); + break; + case Glitter::CURVE_COLOR_A: + glitter_editor_curve_editor_window_draw(glt_edt, Glitter::CURVE_COLOR_R , red_bcolor, false, + min, max, canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max); + glitter_editor_curve_editor_window_draw(glt_edt, Glitter::CURVE_COLOR_G , blue_bcolor, false, + min, max, canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max); + glitter_editor_curve_editor_window_draw(glt_edt, Glitter::CURVE_COLOR_B , green_bcolor, false, + min, max, canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max); + glitter_editor_curve_editor_window_draw(glt_edt, Glitter::CURVE_COLOR_RGB_SCALE, nwhite_bcolor, false, + min, max, canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max); + glitter_editor_curve_editor_window_draw(glt_edt, Glitter::CURVE_COLOR_A , white_color , true, + min, max, canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max); + break; + case Glitter::CURVE_COLOR_RGB_SCALE: + glitter_editor_curve_editor_window_draw(glt_edt, Glitter::CURVE_COLOR_R , red_bcolor, false, + min, max, canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max); + glitter_editor_curve_editor_window_draw(glt_edt, Glitter::CURVE_COLOR_G , blue_bcolor, false, + min, max, canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max); + glitter_editor_curve_editor_window_draw(glt_edt, Glitter::CURVE_COLOR_B , green_bcolor, false, + min, max, canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max); + glitter_editor_curve_editor_window_draw(glt_edt, Glitter::CURVE_COLOR_A , white_bcolor, false, + min, max, canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max); + glitter_editor_curve_editor_window_draw(glt_edt, Glitter::CURVE_COLOR_RGB_SCALE, nwhite_color , true, + min, max, canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max); + break; + case Glitter::CURVE_COLOR_R_2ND: + glitter_editor_curve_editor_window_draw(glt_edt, Glitter::CURVE_COLOR_G_2ND , blue_bcolor, false, + min, max, canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max); + glitter_editor_curve_editor_window_draw(glt_edt, Glitter::CURVE_COLOR_B_2ND , green_bcolor, false, + min, max, canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max); + glitter_editor_curve_editor_window_draw(glt_edt, Glitter::CURVE_COLOR_A_2ND , white_bcolor, false, + min, max, canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max); + glitter_editor_curve_editor_window_draw(glt_edt, Glitter::CURVE_COLOR_RGB_SCALE_2ND, nwhite_bcolor, false, + min, max, canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max); + glitter_editor_curve_editor_window_draw(glt_edt, Glitter::CURVE_COLOR_R_2ND , red_color , true, + min, max, canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max); - x1 = max_def(x1, canvas_pos_min.x); - x2 = min_def(x2, canvas_pos_max.x); - - Glitter::KeyType k_type = c->type; - float_t c_frame = (float_t)c->frame; - float_t n_frame = (float_t)n->frame; - float_t c_value = c->value; - float_t n_value = n->value; - if (fix_rot_z) { - c_value -= (float_t)M_PI_2; - n_value -= (float_t)M_PI_2; - } - float_t c_random_range = c->random_range; - float_t n_random_range = n->random_range; - if (random_range_mult && glt_type_ft) { - c_random_range *= c_value; - n_random_range *= n_value; - } - - size_t frame_width_int = (size_t)roundf(frame_width); - if (k_type == Glitter::KEY_CONSTANT) { - vec3 value = { c_value + c_random_range, c_value, c_value - c_random_range }; - vec3 random = { random_range, random_range, random_range }; - if (random_range_mult) { - random *= value; - if (!glt_type_ft) - random *= 0.01f; - } - - if (value.x != value.y) { - float_t y1 = convert_value_to_height(glt_edt, value.x + random.x, - canvas_pos.y, canvas_size.y, min, max); - float_t y2 = convert_value_to_height(glt_edt, value.x, - canvas_pos.y, canvas_size.y, min, max); - float_t y3 = convert_value_to_height(glt_edt, value.x, - canvas_pos.y, canvas_size.y, min, max); - float_t y4 = convert_value_to_height(glt_edt, value.y, - canvas_pos.y, canvas_size.y, min, max); - - y1 = clamp_def(y1, canvas_pos_min.y, canvas_pos_max.y); - y2 = clamp_def(y2, canvas_pos_min.y, canvas_pos_max.y); - if (y1 != y2) - crv_edt->draw_list->AddRectFilled({ x1, y1 }, - { x2, y2 }, random_range_color, 0.0f, 0); - - y3 = clamp_def(y3, canvas_pos_min.y, canvas_pos_max.y); - y4 = clamp_def(y4, canvas_pos_min.y, canvas_pos_max.y); - if (y3 != y4) - crv_edt->draw_list->AddRectFilled({ x1, y3 }, - { x2, y4 }, key_random_range_color, 0.0f, 0); - } - else { - float_t y1 = convert_value_to_height(glt_edt, value.y + random.y, - canvas_pos.y, canvas_size.y, min, max); - float_t y2 = convert_value_to_height(glt_edt, value.y, - canvas_pos.y, canvas_size.y, min, max); - - y1 = clamp_def(y1, canvas_pos_min.y, canvas_pos_max.y); - y2 = clamp_def(y2, canvas_pos_min.y, canvas_pos_max.y); - if (y1 != y2) - crv_edt->draw_list->AddRectFilled({ x1, y1 }, - { x2, y2 }, random_range_color, 0.0f, 0); - } - - if (random_range_negate) - if (value.y != value.z) { - float_t y1 = convert_value_to_height(glt_edt, value.y, - canvas_pos.y, canvas_size.y, min, max); - float_t y2 = convert_value_to_height(glt_edt, value.z, - canvas_pos.y, canvas_size.y, min, max); - float_t y3 = convert_value_to_height(glt_edt, value.z, - canvas_pos.y, canvas_size.y, min, max); - float_t y4 = convert_value_to_height(glt_edt, value.z - random.z, - canvas_pos.y, canvas_size.y, min, max); - - y1 = clamp_def(y1, canvas_pos_min.y, canvas_pos_max.y); - y2 = clamp_def(y2, canvas_pos_min.y, canvas_pos_max.y); - if (y1 != y2) - crv_edt->draw_list->AddRectFilled({ x1, y1 }, - { x2, y2 }, key_random_range_color, 0.0f, 0); - - y3 = clamp_def(y3, canvas_pos_min.y, canvas_pos_max.y); - y4 = clamp_def(y4, canvas_pos_min.y, canvas_pos_max.y); - if (y3 != y4) - crv_edt->draw_list->AddRectFilled({ x1, y3 }, - { x2, y4 }, random_range_color, 0.0f, 0); - } - else { - float_t y1 = convert_value_to_height(glt_edt, value.y, - canvas_pos.y, canvas_size.y, min, max); - float_t y2 = convert_value_to_height(glt_edt, value.y - random.y, - canvas_pos.y, canvas_size.y, min, max); - - y1 = clamp_def(y1, canvas_pos_min.y, canvas_pos_max.y); - y2 = clamp_def(y2, canvas_pos_min.y, canvas_pos_max.y); - if (y1 != y2) - crv_edt->draw_list->AddRectFilled({ x1, y1 }, - { x2, y2 }, random_range_color, 0.0f, 0); - } - } - else { - float_t c_tangent2 = c->tangent2; - float_t n_tangent1 = n->tangent1; - - vec3 c_frame_vec = { c_frame, c_frame, c_frame }; - vec3 n_frame_vec = { n_frame, n_frame, n_frame }; - vec3 c_value_vec = { c_value + c_random_range, c_value, c_value - c_random_range }; - vec3 n_value_vec = { n_value + n_random_range, n_value, n_value - n_random_range }; - vec3 random_vec = { random_range, random_range, random_range }; - vec3 c_tangent2_vec = { c_tangent2, c_tangent2, c_tangent2 }; - vec3 n_tangent1_vec = { n_tangent1, n_tangent1, n_tangent1 }; - for (size_t i = c->frame; i < n->frame; i++) - for (size_t j = 0; j < frame_width_int; j++) { - float_t frame = (float_t)i + (float_t)j / frame_width; - vec3 frame_vec = { frame, frame, frame }; - - vec3 value; - if (k_type != Glitter::KEY_HERMITE) - value = interpolate_linear_value(c_value_vec, n_value_vec, - c_frame_vec, n_frame_vec, frame_vec); - else - value = interpolate_chs_value(c_value_vec, n_value_vec, - c_tangent2_vec, n_tangent1_vec, c_frame_vec, n_frame_vec, frame_vec); - - vec3 random; - if (random_range_mult) { - random_vec *= value; - if (!glt_type_ft) - random *= 0.01f; - } - else - random = random_vec; - - if (random_range_mult) { - vec3 random = { random_range, random_range, random_range }; - random *= value; - if (!glt_type_ft) - random *= 0.01f; - } - - float_t x = canvas_pos.x - + (float_t)(i - start_time) * frame_width + (float_t)j; - if (value.x != value.y) { - float_t y1 = convert_value_to_height(glt_edt, value.x + random.x, - canvas_pos.y, canvas_size.y, min, max); - float_t y2 = convert_value_to_height(glt_edt, value.x, - canvas_pos.y, canvas_size.y, min, max); - float_t y3 = convert_value_to_height(glt_edt, value.x, - canvas_pos.y, canvas_size.y, min, max); - float_t y4 = convert_value_to_height(glt_edt, value.y, - canvas_pos.y, canvas_size.y, min, max); - - y1 = clamp_def(y1, canvas_pos_min.y, canvas_pos_max.y); - y2 = clamp_def(y2, canvas_pos_min.y, canvas_pos_max.y); - if (y1 != y2) - crv_edt->draw_list->AddLine({ x, y1 }, - { x, y2 }, random_range_color, 0.0f); - - y3 = clamp_def(y3, canvas_pos_min.y, canvas_pos_max.y); - y4 = clamp_def(y4, canvas_pos_min.y, canvas_pos_max.y); - if (y3 != y4) - crv_edt->draw_list->AddLine({ x, y3 }, - { x, y4 }, key_random_range_color, 0.0f); - } - else { - float_t y1 = convert_value_to_height(glt_edt, value.y + random.y, - canvas_pos.y, canvas_size.y, min, max); - float_t y2 = convert_value_to_height(glt_edt, value.y, - canvas_pos.y, canvas_size.y, min, max); - - y1 = clamp_def(y1, canvas_pos_min.y, canvas_pos_max.y); - y2 = clamp_def(y2, canvas_pos_min.y, canvas_pos_max.y); - if (y1 != y2) - crv_edt->draw_list->AddLine({ x, y1 }, - { x, y2 }, random_range_color, 0.0f); - } - - if (random_range_negate) - if (value.y != value.z) { - float_t y1 = convert_value_to_height(glt_edt, value.y, - canvas_pos.y, canvas_size.y, min, max); - float_t y2 = convert_value_to_height(glt_edt, value.z, - canvas_pos.y, canvas_size.y, min, max); - float_t y3 = convert_value_to_height(glt_edt, value.z, - canvas_pos.y, canvas_size.y, min, max); - float_t y4 = convert_value_to_height(glt_edt, value.z - random.z, - canvas_pos.y, canvas_size.y, min, max); - - y1 = clamp_def(y1, canvas_pos_min.y, canvas_pos_max.y); - y2 = clamp_def(y2, canvas_pos_min.y, canvas_pos_max.y); - if (y1 != y2) - crv_edt->draw_list->AddLine({ x, y1 }, - { x, y2 }, key_random_range_color, 0.0f); - - y3 = clamp_def(y3, canvas_pos_min.y, canvas_pos_max.y); - y4 = clamp_def(y4, canvas_pos_min.y, canvas_pos_max.y); - if (y3 != y4) - crv_edt->draw_list->AddLine({ x, y3 }, - { x, y4 }, random_range_color, 0.0f); - } - else { - float_t y1 = convert_value_to_height(glt_edt, value.y, - canvas_pos.y, canvas_size.y, min, max); - float_t y2 = convert_value_to_height(glt_edt, value.y - random.y, - canvas_pos.y, canvas_size.y, min, max); - - y1 = clamp_def(y1, canvas_pos_min.y, canvas_pos_max.y); - y2 = clamp_def(y2, canvas_pos_min.y, canvas_pos_max.y); - if (y1 != y2) - crv_edt->draw_list->AddLine({ x, y1 }, - { x, y2 }, random_range_color, 0.0f); - } - } - } - } + break; + case Glitter::CURVE_COLOR_G_2ND: + glitter_editor_curve_editor_window_draw(glt_edt, Glitter::CURVE_COLOR_R_2ND , red_bcolor, false, + min, max, canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max); + glitter_editor_curve_editor_window_draw(glt_edt, Glitter::CURVE_COLOR_B_2ND , green_bcolor, false, + min, max, canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max); + glitter_editor_curve_editor_window_draw(glt_edt, Glitter::CURVE_COLOR_A_2ND , white_bcolor, false, + min, max, canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max); + glitter_editor_curve_editor_window_draw(glt_edt, Glitter::CURVE_COLOR_RGB_SCALE_2ND, nwhite_bcolor, false, + min, max, canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max); + glitter_editor_curve_editor_window_draw(glt_edt, Glitter::CURVE_COLOR_G_2ND , blue_color , true, + min, max, canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max); + break; + case Glitter::CURVE_COLOR_B_2ND: + glitter_editor_curve_editor_window_draw(glt_edt, Glitter::CURVE_COLOR_R_2ND , red_bcolor, false, + min, max, canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max); + glitter_editor_curve_editor_window_draw(glt_edt, Glitter::CURVE_COLOR_G_2ND , blue_bcolor, false, + min, max, canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max); + glitter_editor_curve_editor_window_draw(glt_edt, Glitter::CURVE_COLOR_A_2ND , white_bcolor, false, + min, max, canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max); + glitter_editor_curve_editor_window_draw(glt_edt, Glitter::CURVE_COLOR_RGB_SCALE_2ND, nwhite_bcolor, false, + min, max, canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max); + glitter_editor_curve_editor_window_draw(glt_edt, Glitter::CURVE_COLOR_B_2ND , green_color , true, + min, max, canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max); + break; + case Glitter::CURVE_COLOR_A_2ND: + glitter_editor_curve_editor_window_draw(glt_edt, Glitter::CURVE_COLOR_R_2ND , red_bcolor, false, + min, max, canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max); + glitter_editor_curve_editor_window_draw(glt_edt, Glitter::CURVE_COLOR_G_2ND , blue_bcolor, false, + min, max, canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max); + glitter_editor_curve_editor_window_draw(glt_edt, Glitter::CURVE_COLOR_B_2ND , green_bcolor, false, + min, max, canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max); + glitter_editor_curve_editor_window_draw(glt_edt, Glitter::CURVE_COLOR_RGB_SCALE_2ND, nwhite_bcolor, false, + min, max, canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max); + glitter_editor_curve_editor_window_draw(glt_edt, Glitter::CURVE_COLOR_A_2ND , white_color , true, + min, max, canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max); + break; + case Glitter::CURVE_COLOR_RGB_SCALE_2ND: + glitter_editor_curve_editor_window_draw(glt_edt, Glitter::CURVE_COLOR_R_2ND , red_bcolor, false, + min, max, canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max); + glitter_editor_curve_editor_window_draw(glt_edt, Glitter::CURVE_COLOR_G_2ND , blue_bcolor, false, + min, max, canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max); + glitter_editor_curve_editor_window_draw(glt_edt, Glitter::CURVE_COLOR_B_2ND , green_bcolor, false, + min, max, canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max); + glitter_editor_curve_editor_window_draw(glt_edt, Glitter::CURVE_COLOR_A_2ND , white_bcolor, false, + min, max, canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max); + glitter_editor_curve_editor_window_draw(glt_edt, Glitter::CURVE_COLOR_RGB_SCALE_2ND, nwhite_color , true, + min, max, canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max); + break; + case Glitter::CURVE_U_SCROLL: + glitter_editor_curve_editor_window_draw(glt_edt, Glitter::CURVE_V_SCROLL, green_bcolor, false, + min, max, canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max); + glitter_editor_curve_editor_window_draw(glt_edt, Glitter::CURVE_U_SCROLL, red_color , true, + min, max, canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max); + break; + case Glitter::CURVE_V_SCROLL: + glitter_editor_curve_editor_window_draw(glt_edt, Glitter::CURVE_U_SCROLL, red_bcolor, false, + min, max, canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max); + glitter_editor_curve_editor_window_draw(glt_edt, Glitter::CURVE_V_SCROLL, green_color , true, + min, max, canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max); + break; + case Glitter::CURVE_U_SCROLL_ALPHA: + glitter_editor_curve_editor_window_draw(glt_edt, Glitter::CURVE_V_SCROLL_ALPHA, green_bcolor, false, + min, max, canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max); + glitter_editor_curve_editor_window_draw(glt_edt, Glitter::CURVE_U_SCROLL_ALPHA, red_color , true, + min, max, canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max); + break; + case Glitter::CURVE_V_SCROLL_ALPHA: + glitter_editor_curve_editor_window_draw(glt_edt, Glitter::CURVE_U_SCROLL_ALPHA, red_bcolor, false, + min, max, canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max); + glitter_editor_curve_editor_window_draw(glt_edt, Glitter::CURVE_V_SCROLL_ALPHA, green_color , true, + min, max, canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max); + break; + case Glitter::CURVE_U_SCROLL_2ND: + glitter_editor_curve_editor_window_draw(glt_edt, Glitter::CURVE_V_SCROLL, green_bcolor, false, + min, max, canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max); + glitter_editor_curve_editor_window_draw(glt_edt, Glitter::CURVE_U_SCROLL, red_color , true, + min, max, canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max); + break; + case Glitter::CURVE_V_SCROLL_2ND: + glitter_editor_curve_editor_window_draw(glt_edt, Glitter::CURVE_U_SCROLL_2ND, red_bcolor, false, + min, max, canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max); + glitter_editor_curve_editor_window_draw(glt_edt, Glitter::CURVE_V_SCROLL_2ND, green_color , true, + min, max, canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max); + break; + case Glitter::CURVE_U_SCROLL_ALPHA_2ND: + glitter_editor_curve_editor_window_draw(glt_edt, Glitter::CURVE_V_SCROLL_ALPHA_2ND, green_bcolor, false, + min, max, canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max); + glitter_editor_curve_editor_window_draw(glt_edt, Glitter::CURVE_U_SCROLL_ALPHA_2ND, red_color , true, + min, max, canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max); + break; + case Glitter::CURVE_V_SCROLL_ALPHA_2ND: + glitter_editor_curve_editor_window_draw(glt_edt, Glitter::CURVE_V_SCROLL_ALPHA_2ND, green_bcolor, false, + min, max, canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max); + glitter_editor_curve_editor_window_draw(glt_edt, Glitter::CURVE_U_SCROLL_ALPHA_2ND, red_color , true, + min, max, canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max); + break; + default: + glitter_editor_curve_editor_window_draw(glt_edt, curve, default_color, true, + min, max, canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max); + break; } - for (std::vector::iterator i = keys->begin(); i != keys->end(); i++) { - if (i->frame >= end_time || keys->end() - i <= 1) - break; + for (int32_t j = 0; j < 5; j++) { + float_t x_pos = canvas_pos_min.x; + float_t y_pos = canvas_pos.y + j * 0.25f * (canvas_size.y + - crv_edt->height_offset) + crv_edt->height_offset; - std::vector::iterator c = i; - std::vector::iterator n = i + 1; - float_t x1 = canvas_pos.x + (float_t)(c->frame - start_time) * frame_width; - float_t x2 = canvas_pos.x + (float_t)(n->frame - start_time) * frame_width; + ImU32 line_color = j % 2 == 1 + ? ImGui::GetColorU32({ 0.35f, 0.35f, 0.35f, 0.45f }) + : ImGui::GetColorU32({ 0.45f, 0.45f, 0.45f, 0.75f }); + bool last = j == 4; + if (j && !last) + draw_list->AddLine({ x_pos, y_pos }, + { x_pos + canvas_size.x, y_pos }, line_color, 0.80f); - if (((x1 < canvas_pos_min.x) && (x2 < canvas_pos_min.x)) || - (x1 > canvas_pos_max.x) && (x2 > canvas_pos_max.x)) - continue; - - float_t c_value = c->value; - float_t n_value = n->value; - - if (fix_rot_z) { - c_value -= (float_t)M_PI_2; - n_value -= (float_t)M_PI_2; - } - - if (i->type != Glitter::KEY_HERMITE) { - float_t y1 = convert_value_to_height(glt_edt, c_value, canvas_pos.y, canvas_size.y, min, max); - float_t y2 = convert_value_to_height(glt_edt, n_value, canvas_pos.y, canvas_size.y, min, max); - - if (i->type == Glitter::KEY_CONSTANT) { - int32_t count = 0; - ImVec2 points_temp[3]; - if (x1 != x2) - points_temp[count++] = { x1, y1 }; - points_temp[count++] = { x2, y1 }; - if (y1 != y2) - points_temp[count++] = { x2, y2 }; - - if (count > 1) - crv_edt->draw_list->AddPolyline(points_temp, - count, default_color, 0, 3.0f); - } - else - crv_edt->draw_list->AddLine({ x1, y1 }, { x2, y2 }, default_color, 3.0f); - } - else { - float_t c_frame = (float_t)c->frame; - float_t n_frame = (float_t)n->frame; - float_t c_tangent2 = (float_t)c->tangent2; - float_t n_tangent1 = (float_t)n->tangent1; - size_t frame_width_int = (size_t)roundf(frame_width); - size_t points_count = ((size_t)n_frame - (size_t)c_frame) * frame_width_int; - ImVec2* points = force_malloc_s(ImVec2, points_count); - for (size_t i = c->frame; i < n->frame; i++) - for (size_t j = 0; j < frame_width_int; j++) { - float_t value = interpolate_chs_value(c_value, n_value, c_tangent2, n_tangent1, - c_frame, n_frame, (float_t)i + (float_t)j / frame_width); - - ImVec2 point; - point.x = canvas_pos.x - + (float_t)(i - start_time) * frame_width + (float_t)j; - point.y = convert_value_to_height(glt_edt, value, - canvas_pos.y, canvas_size.y, min, max); - points[(i - c->frame) * frame_width_int + j] = point; - } - crv_edt->draw_list->AddPolyline(points, - (int32_t)points_count, default_color, 0, 3.0f); - free_def(points); - } + float_t val = max - j * 0.25f * (max - min); + char buf[0x20]; + snprintf(buf, sizeof(buf), "%.2f", val); + draw_list->AddText({ x_pos + 2, y_pos + (last ? -16 : -2) }, + ImGui::GetColorU32({ 0.65f, 0.65f, 0.65f, 0.85f }), buf); } - const ImU32 key_constant_color = ImGui::GetColorU32({ 1.0f, 0.0f, 0.0f, 0.75f }); - const ImU32 key_linear_color = ImGui::GetColorU32({ 0.0f, 1.0f, 0.0f, 0.75f }); - const ImU32 key_hermite_color = ImGui::GetColorU32({ 0.0f, 0.0f, 1.0f, 0.75f }); + const ImU32 key_constant_color = ImGui::GetColorU32({ 1.0f, 0.0f, 0.0f, 1.0f }); + const ImU32 key_linear_color = ImGui::GetColorU32({ 0.0f, 1.0f, 0.0f, 1.0f }); + const ImU32 key_hermite_color = ImGui::GetColorU32({ 0.0f, 0.0f, 1.0f, 1.0f }); bool dragged = false; bool holding_tan = false; - for (std::vector::iterator i = keys->begin(); i != keys->end(); i++) { - if (!(i->frame >= start_time || i->frame <= end_time)) + Glitter::Curve::Key* i_begin = keys->data(); + Glitter::Curve::Key* i_end = keys->data() + keys->size(); + for (Glitter::Curve::Key* i = i_begin; i != i_end; i++) { + if (i->frame < graph_start) continue; - else if (i - keys->begin() > 1) - if (i->frame < start_time && i[1].frame < start_time) - continue; - else if (i->frame > end_time && i[-1].frame > end_time) - continue; + else if (i->frame > graph_end) + break; float_t base_value = i->value; if (fix_rot_z) base_value -= (float_t)M_PI_2; float_t x = canvas_pos.x + ((size_t)i->frame - start_time) * frame_width; - float_t y = convert_value_to_height(glt_edt, base_value, canvas_pos.y, canvas_size.y, min, max); + float_t y = convert_value_to_height(crv_edt, base_value, canvas_pos.y, canvas_size.y, min, max); if (!(x >= p3.x - 10.0f && x <= p3.x + canvas_size.x + 10.0f) || !(y >= p3.y - 10.0f && y <= p3.y + canvas_size.y + 10.0f)) @@ -6307,7 +6461,7 @@ static void glitter_editor_curve_editor_windows(GlitterEditor* glt_edt) { break; } - ImGui::PushID(i._Ptr); + ImGui::PushID(i); ImGui::SetCursorScreenPos({ x - 7.5f, y - 7.5f }); ImGui::InvisibleButton("val", { 15.0f, 15.0f }, 0); @@ -6324,8 +6478,8 @@ static void glitter_editor_curve_editor_windows(GlitterEditor* glt_edt) { } if (i->frame >= start_time && i->frame <= end_time) { - int32_t start = i - keys->begin() > 0 ? (i - 1)->frame + 1 : start_time; - int32_t end = keys->end() - i > 1 ? (i + 1)->frame - 1 : end_time; + int32_t start = i - i_begin > 0 ? (i - 1)->frame + 1 : start_time; + int32_t end = i_end - i > 1 ? (i + 1)->frame - 1 : end_time; crv_edt->frame = (int32_t)roundf((io.MousePos.x - canvas_pos.x) / frame_width); crv_edt->frame = clamp_def(crv_edt->frame + start_time, start, end); if (i->frame != crv_edt->frame) { @@ -6349,7 +6503,7 @@ static void glitter_editor_curve_editor_windows(GlitterEditor* glt_edt) { y += io.MouseDelta.y; if (old_y != y) { - float_t value = convert_height_to_value(glt_edt, + float_t value = convert_height_to_value(crv_edt, y, canvas_pos.y, canvas_size.y, min, max); dragged = true; @@ -6363,14 +6517,14 @@ static void glitter_editor_curve_editor_windows(GlitterEditor* glt_edt) { } } - if (i - keys->begin() > 0 && (i - 1)->type == Glitter::KEY_HERMITE) { + if (i - i_begin > 0 && (i - 1)->type == Glitter::KEY_HERMITE) { ImU32 tangent1_color; float_t tangent1; ImVec2 circle_pos; circle_pos.x = x - 25.0f; - circle_pos.y = y - base_line + convert_value_to_height(glt_edt, tangent1 = i->tangent1, + circle_pos.y = y - base_line + convert_value_to_height(crv_edt, tangent1 = i->tangent1, canvas_pos.y, canvas_size.y, min, max); - crv_edt->draw_list->AddLine({ x, y }, circle_pos, default_color, 1.5f); + draw_list->AddLine({ x, y }, circle_pos, default_color, 1.5f); if ((circle_pos.x >= p3.x - 10.0f && circle_pos.x <= p3.x + canvas_size.x + 10.0f) && (circle_pos.y >= p3.y - 10.0f && circle_pos.y <= p3.y + canvas_size.y + 10.0f)) { @@ -6379,7 +6533,7 @@ static void glitter_editor_curve_editor_windows(GlitterEditor* glt_edt) { if (can_drag && ImGui::IsItemActive()) { if (ImGui::IsMouseDragging(ImGuiMouseButton_Left)) { - i->tangent1 = convert_height_to_value(glt_edt, + i->tangent1 = convert_height_to_value(crv_edt, circle_pos.y + io.MouseDelta.y - y + base_line, canvas_pos.y, canvas_size.y, min, max); @@ -6392,19 +6546,19 @@ static void glitter_editor_curve_editor_windows(GlitterEditor* glt_edt) { else tangent1_color = default_color; - crv_edt->draw_list->AddCircleFilled(circle_pos, + draw_list->AddCircleFilled(circle_pos, crv_edt->key_radius_in, tangent1_color, 12); } } - if (keys->end() - i > 1 && i->type == Glitter::KEY_HERMITE) { + if (i_end - i > 1 && i->type == Glitter::KEY_HERMITE) { ImU32 tangent2_color; float_t tangent2; ImVec2 circle_pos; circle_pos.x = x + 25.0f; - circle_pos.y = y - base_line + convert_value_to_height(glt_edt, tangent2 = i->tangent2, + circle_pos.y = y - base_line + convert_value_to_height(crv_edt, tangent2 = i->tangent2, canvas_pos.y, canvas_size.y, min, max); - crv_edt->draw_list->AddLine({ x, y }, circle_pos, default_color, 1.5f); + draw_list->AddLine({ x, y }, circle_pos, default_color, 1.5f); if ((circle_pos.x >= p3.x - 10.0f && circle_pos.x <= p3.x + canvas_size.x + 10.0f) && (circle_pos.y >= p3.y - 10.0f && circle_pos.y <= p3.y + canvas_size.y + 10.0f)) { @@ -6413,7 +6567,7 @@ static void glitter_editor_curve_editor_windows(GlitterEditor* glt_edt) { if (can_drag && ImGui::IsItemActive()) { if (ImGui::IsMouseDragging(ImGuiMouseButton_Left)) { - i->tangent2 = convert_height_to_value(glt_edt, + i->tangent2 = convert_height_to_value(crv_edt, circle_pos.y + io.MouseDelta.y - y + base_line, canvas_pos.y, canvas_size.y, min, max); @@ -6426,14 +6580,14 @@ static void glitter_editor_curve_editor_windows(GlitterEditor* glt_edt) { else tangent2_color = default_color; - crv_edt->draw_list->AddCircleFilled(circle_pos, + draw_list->AddCircleFilled(circle_pos, crv_edt->key_radius_in, tangent2_color, 12); } } - crv_edt->draw_list->AddCircleFilled({ x, y }, + draw_list->AddCircleFilled({ x, y }, crv_edt->key_radius_out, crv_edt->key == &i[0] ? selected_color : default_color, 12); - crv_edt->draw_list->AddCircleFilled({ x, y }, + draw_list->AddCircleFilled({ x, y }, crv_edt->key_radius_in, value_color, 12); ImGui::PopID(); } @@ -6457,15 +6611,15 @@ static void glitter_editor_curve_editor_windows(GlitterEditor* glt_edt) { ImU32 cursor_color = ImGui::GetColorU32({ 0.8f, 0.8f, 0.8f, 0.75f }); p1.x = cursor_pos.x; p1.y = canvas_pos.y + canvas_size.y; - crv_edt->draw_list->AddLine(cursor_pos, p1, cursor_color, 2.5f); + draw_list->AddLine(cursor_pos, p1, cursor_color, 2.5f); p1 = p2 = p3 = cursor_pos; p1.x -= 10.0f; p2.y += 10.0f; p3.x += 10.0f; - crv_edt->draw_list->AddTriangleFilled(p1, p2, p3, cursor_color); + draw_list->AddTriangleFilled(p1, p2, p3, cursor_color); } - crv_edt->draw_list->PopClipRect(); + draw_list->PopClipRect(); if (hovered) if (ImGui::IsKeyDown(GLFW_KEY_LEFT_SHIFT) || ImGui::IsKeyDown(GLFW_KEY_RIGHT_SHIFT)) @@ -6483,6 +6637,757 @@ static void glitter_editor_curve_editor_windows(GlitterEditor* glt_edt) { } } +inline static void glitter_editor_curve_editor_window_draw(GlitterEditor* glt_edt, const Glitter::CurveType type, + const ImU32 line_color, const bool line_front, const float_t min, const float_t max, + const ImVec2 canvas_size, const ImVec2 canvas_pos, const ImVec2 canvas_pos_min, const ImVec2 canvas_pos_max, + const bool fix_rot_z) { + GlitterEditor::CurveEditor* crv_edt = &glt_edt->curve_editor; + if (!(crv_edt->type_flags & (1 << type)) || !crv_edt->list[type]) + return; + + glitter_editor_curve_editor_window_draw(glt_edt, crv_edt->list[type], line_color, line_front, + min, max, canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max, fix_rot_z); +} + +static void glitter_editor_curve_editor_window_draw(GlitterEditor* glt_edt, const Glitter::Curve* curve, + const ImU32 line_color, const bool line_front, const float_t min, const float_t max, + const ImVec2 canvas_size, const ImVec2 canvas_pos, const ImVec2 canvas_pos_min, const ImVec2 canvas_pos_max, + const bool fix_rot_z) { + GlitterEditor::CurveEditor* crv_edt = &glt_edt->curve_editor; + ImDrawList* draw_list = crv_edt->draw_list; + const ImU32 random_range_color = ImGui::GetColorU32({ 0.5f, 0.5f, 0.0f, 0.25f }); + const ImU32 key_random_range_color = ImGui::GetColorU32({ 0.5f, 0.0f, 0.5f, 0.25f }); + + const std::vector* keys = &curve->keys_rev; + if (!keys->size()) + return; + + const float_t frame_width = crv_edt->frame_width * crv_edt->zoom_time; + + const float_t line_thickness = line_front ? 3.0f : 1.0f; + + if (keys->size() == 1) { + if (line_front && (curve->flags + & (Glitter::CURVE_RANDOM_RANGE | Glitter::CURVE_KEY_RANDOM_RANGE))) { + const float_t random_range = curve->random_range; + const bool random_range_mult = curve->flags & Glitter::CURVE_RANDOM_RANGE_MULT; + const bool random_range_negate = curve->flags & Glitter::CURVE_RANDOM_RANGE_NEGATE; + const bool glt_type_ft = glt_edt->effect_group->type == Glitter::FT; + + const Glitter::Curve::Key* c = &keys->data()[0]; + const Glitter::KeyType k_type = c->type; + const float_t c_frame = (float_t)c->frame; + const float_t c_value = fix_rot_z ? c->value - (float_t)M_PI_2 : c->value; + const float_t c_random_range = random_range_mult && glt_type_ft + ? c->random_range * c_value : c->random_range; + + const vec3 value = { c_value + c_random_range, c_value, c_value - c_random_range }; + const vec3 random = !random_range_mult + ? random_range : glt_type_ft + ? (random_range * value) : (random_range * value * 0.01f); + + glitter_editor_curve_editor_window_draw_random_range(crv_edt, + canvas_pos_min.x, canvas_pos_max.x, + value, random, min, max, random_range_negate, + canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max); + } + + const Glitter::Curve::Key* c = &keys->data()[0]; + const float_t c_value = fix_rot_z ? c->value - (float_t)M_PI_2 : c->value; + + float_t y = convert_value_to_height(crv_edt, c_value, + canvas_pos.y, canvas_size.y, min, max); + + draw_list->AddLine({ canvas_pos_min.x, y }, + { canvas_pos_max.x, y }, line_color, line_thickness); + return; + } + + const Glitter::Curve* base_curve = crv_edt->list[crv_edt->type]; + const int32_t start_time = curve->start_time; + const int32_t end_time = curve-> end_time; + const int32_t base_start_time = base_curve->start_time; + const int32_t base_end_time = base_curve-> end_time; + + std::vector points; + if (curve->repeat && end_time - start_time) { + const int32_t graph_start = base_start_time + (int32_t)((crv_edt->timeline_pos + + frame_width - 1.0f) / frame_width); + const int32_t graph_end = base_start_time + (int32_t)((crv_edt->timeline_pos + canvas_size.x + + frame_width - 1.0f) / frame_width); + + const int32_t delta_time = end_time - start_time; + int32_t repeat_count_pre = (start_time - graph_start + delta_time - 1) / delta_time; + int32_t repeat_count_post = (graph_end - end_time + delta_time - 1) / delta_time; + repeat_count_pre = max_def(repeat_count_pre , 0); + repeat_count_post = max_def(repeat_count_post, 0); + + for (int32_t i = repeat_count_pre; i >= 1; i--) + glitter_editor_curve_editor_window_draw(glt_edt, curve, line_color, line_front, + min, max, canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max, + fix_rot_z, start_time, end_time, + base_start_time + delta_time * i, base_end_time + delta_time * i, points, true); + glitter_editor_curve_editor_window_draw(glt_edt, curve, line_color, line_front, + min, max, canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max, + fix_rot_z, start_time, end_time, base_start_time, base_end_time, points, true); + for (int32_t i = 1; i <= repeat_count_post; i++) + glitter_editor_curve_editor_window_draw(glt_edt, curve, line_color, line_front, + min, max, canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max, + fix_rot_z, start_time, end_time, + base_start_time - delta_time * i, base_end_time - delta_time * i, points, true); + } + else { + glitter_editor_curve_editor_window_draw(glt_edt, curve, line_color, line_front, + min, max, canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max, + fix_rot_z, start_time, end_time, base_start_time, base_end_time, points); + } + draw_list->AddPolyline(points.data(), + (int32_t)points.size(), line_color, 0, line_thickness); +} + +static void glitter_editor_curve_editor_window_draw(GlitterEditor* glt_edt, const Glitter::Curve* curve, + const ImU32 line_color, const bool line_front, const float_t min, const float_t max, + const ImVec2 canvas_size, const ImVec2 canvas_pos, const ImVec2 canvas_pos_min, const ImVec2 canvas_pos_max, + const bool fix_rot_z, const int32_t start_time, const int32_t end_time, + const int32_t base_start_time, const int32_t base_end_time, std::vector& points, bool loop) { + GlitterEditor::CurveEditor* crv_edt = &glt_edt->curve_editor; + ImDrawList* draw_list = crv_edt->draw_list; + const ImU32 random_range_color = ImGui::GetColorU32({ 0.5f, 0.5f, 0.0f, 0.25f }); + const ImU32 key_random_range_color = ImGui::GetColorU32({ 0.5f, 0.0f, 0.5f, 0.25f }); + + const std::vector* keys = &curve->keys_rev; + + const float_t frame_width = crv_edt->frame_width * crv_edt->zoom_time; + + const float_t line_thickness = line_front ? 3.0f : 1.0f; + + if (line_front && (curve->flags + & (Glitter::CURVE_RANDOM_RANGE | Glitter::CURVE_KEY_RANDOM_RANGE))) { + const float_t random_range = curve->random_range; + const bool random_range_mult = curve->flags & Glitter::CURVE_RANDOM_RANGE_MULT; + const bool random_range_negate = curve->flags & Glitter::CURVE_RANDOM_RANGE_NEGATE; + const bool glt_type_ft = glt_edt->effect_group->type == Glitter::FT; + + bool first_frame_found = false; + + const Glitter::Curve::Key* i_begin = keys->data(); + const Glitter::Curve::Key* i_end = keys->data() + keys->size(); + for (const Glitter::Curve::Key* i = i_begin; i != i_end; i++) { + if (i->frame <= start_time || i->frame > start_time && !first_frame_found) { + if (i_end - i <= 1) + break; + else if (i[1].frame <= start_time) + continue; + + const Glitter::Curve::Key* c = i; + const Glitter::Curve::Key* n = i + 1; + const float_t c_value = fix_rot_z ? c->value - (float_t)M_PI_2 : c->value; + const float_t n_value = fix_rot_z ? n->value - (float_t)M_PI_2 : n->value; + const float_t c_random_range = random_range_mult && glt_type_ft + ? c->random_range * c_value : c->random_range; + const float_t n_random_range = random_range_mult && glt_type_ft + ? n->random_range * n_value : n->random_range; + + const vec3 c_value_vec = { c_value + c_random_range, c_value, c_value - c_random_range }; + const vec3 n_value_vec = { n_value + n_random_range, n_value, n_value - n_random_range }; + + vec3 value; + if (i->frame < start_time) + switch (c->type) { + case Glitter::KEY_CONSTANT: + value = c_value_vec; + break; + case Glitter::KEY_LINEAR: + default: + value = interpolate_linear_value(c_value_vec, n_value_vec, + (float_t)c->frame, (float_t)n->frame, (float_t)start_time); + break; + case Glitter::KEY_HERMITE: + value = interpolate_chs_value(c_value_vec, n_value_vec, + (float_t)c->tangent2, (float_t)n->tangent1, + (float_t)c->frame, (float_t)n->frame, (float_t)start_time); + break; + } + else + value = c_value_vec; + + const vec3 random = !random_range_mult + ? random_range : glt_type_ft + ? (random_range * value) : (random_range * value * 0.01f); + + const float_t x1 = loop + ? canvas_pos.x + (float_t)(start_time - base_start_time) * frame_width + : canvas_pos_min.x; + const float_t x2 = canvas_pos.x + (float_t)(max_def(i->frame, + start_time) - base_start_time) * frame_width; + glitter_editor_curve_editor_window_draw_random_range(crv_edt, x1, x2, + value, random, min, max, random_range_negate, + canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max); + first_frame_found = true; + } + else if (i->frame > end_time || i->frame == end_time || i_end - i <= 1 && i->frame <= end_time) { + vec3 value; + if (i->frame > end_time) { + const Glitter::Curve::Key* c = i - 1; + const Glitter::Curve::Key* n = i; + const float_t c_value = fix_rot_z ? c->value - (float_t)M_PI_2 : c->value; + const float_t n_value = fix_rot_z ? n->value - (float_t)M_PI_2 : n->value; + const float_t c_random_range = random_range_mult && glt_type_ft + ? c->random_range * c_value : c->random_range; + const float_t n_random_range = random_range_mult && glt_type_ft + ? n->random_range * n_value : n->random_range; + + const vec3 c_value_vec = { c_value + c_random_range, c_value, c_value - c_random_range }; + const vec3 n_value_vec = { n_value + n_random_range, n_value, n_value - n_random_range }; + + switch (c->type) { + case Glitter::KEY_CONSTANT: + value = c_value_vec; + break; + case Glitter::KEY_LINEAR: + default: + value = interpolate_linear_value(c_value_vec, n_value_vec, + (float_t)c->frame, (float_t)n->frame, (float_t)end_time); + break; + case Glitter::KEY_HERMITE: + value = interpolate_chs_value(c_value_vec, n_value_vec, + (float_t)c->tangent2, (float_t)n->tangent1, + (float_t)c->frame, (float_t)n->frame, (float_t)end_time); + break; + } + } + else { + const Glitter::Curve::Key* c = i; + const float_t c_value = fix_rot_z ? c->value - (float_t)M_PI_2 : c->value; + const float_t c_random_range = random_range_mult && glt_type_ft + ? c->random_range * c_value : c->random_range; + value = { c_value + c_random_range, c_value, c_value - c_random_range }; + } + + const vec3 random = !random_range_mult + ? random_range : glt_type_ft + ? (random_range * value) : (random_range * value * 0.01f); + + const float_t x1 = canvas_pos.x + (float_t)(min_def(i->frame, + end_time) - base_start_time) * frame_width; + const float_t x2 = loop + ? canvas_pos.x + (float_t)(end_time - base_start_time) * frame_width + : canvas_pos_max.x; + glitter_editor_curve_editor_window_draw_random_range(crv_edt, x1, x2, + value, random, min, max, random_range_negate, + canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max); + break; + } + else if (i_end - i <= 1) + break; + + const Glitter::Curve::Key* c = i; + const Glitter::Curve::Key* n = i + 1; + const Glitter::KeyType k_type = c->type; + const float_t c_value = fix_rot_z ? c->value - (float_t)M_PI_2 : c->value; + const float_t n_value = fix_rot_z ? n->value - (float_t)M_PI_2 : n->value; + const float_t c_random_range = random_range_mult && glt_type_ft + ? c->random_range * c_value : c->random_range; + const float_t n_random_range = random_range_mult && glt_type_ft + ? n->random_range * n_value : n->random_range; + + switch (k_type) { + case Glitter::KEY_CONSTANT: { + const vec3 value = { c_value + c_random_range, c_value, c_value - c_random_range }; + const vec3 random = !random_range_mult + ? random_range : glt_type_ft + ? (random_range * value) : (random_range * value * 0.01f); + + const int32_t c_frame = max_def(c->frame, start_time); + const int32_t n_frame = min_def(n->frame, end_time); + const float_t x1 = canvas_pos.x + (float_t)(c_frame - base_start_time) * frame_width; + const float_t x2 = canvas_pos.x + (float_t)(n_frame - base_start_time) * frame_width; + glitter_editor_curve_editor_window_draw_random_range(crv_edt, x1, x2, + value, random, min, max, random_range_negate, + canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max); + } break; + case Glitter::KEY_LINEAR: { + const int32_t c_frame = max_def(c->frame, start_time); + const int32_t n_frame = min_def(n->frame, end_time); + const float_t x1 = canvas_pos.x + (float_t)(c_frame - base_start_time) * frame_width; + const float_t x2 = canvas_pos.x + (float_t)(n_frame - base_start_time) * frame_width; + + const float_t _c_value = interpolate_linear_value(c_value, n_value, + (float_t)c->frame, (float_t)n->frame, (float_t)c_frame); + const float_t _n_value = interpolate_linear_value(c_value, n_value, + (float_t)c->frame, (float_t)n->frame, (float_t)n_frame); + + const vec3 c_value_vec = { _c_value + c_random_range, _c_value, _c_value - c_random_range }; + const vec3 n_value_vec = { _n_value + n_random_range, _n_value, _n_value - n_random_range }; + const vec3 c_random = !random_range_mult + ? random_range : glt_type_ft + ? (random_range * c_value_vec) : (random_range * c_value_vec * 0.01f); + const vec3 n_random = !random_range_mult + ? random_range : glt_type_ft + ? (random_range * n_value_vec) : (random_range * n_value_vec * 0.01f); + + glitter_editor_curve_editor_window_draw_random_range(crv_edt, x1, x2, + c_value_vec, n_value_vec, c_random, n_random, min, max, random_range_negate, + canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max); + } break; + case Glitter::KEY_HERMITE: { + const float_t c_frame = (float_t)c->frame; + const float_t n_frame = (float_t)n->frame; + const float_t c_tangent2 = c->tangent2; + const float_t n_tangent1 = n->tangent1; + + const vec3 c_frame_vec = c_frame; + const vec3 n_frame_vec = n_frame; + const vec3 c_value_vec = { c_value + c_random_range, c_value, c_value - c_random_range }; + const vec3 n_value_vec = { n_value + n_random_range, n_value, n_value - n_random_range }; + const vec3 c_tangent2_vec = c_tangent2; + const vec3 n_tangent1_vec = n_tangent1; + const size_t frame_width_int = (size_t)roundf(frame_width); + for (size_t j = c->frame; j < n->frame; j++) { + if (j < start_time) + continue; + else if (j >= end_time) + break; + + for (size_t k = 0; k < frame_width_int; k++) { + const float_t frame = (float_t)(int32_t)j + (float_t)(int32_t)k / frame_width; + const vec3 frame_vec = frame; + + const vec3 value = interpolate_chs_value(c_value_vec, n_value_vec, + c_tangent2_vec, n_tangent1_vec, c_frame_vec, n_frame_vec, frame_vec); + const vec3 random = !random_range_mult + ? random_range : glt_type_ft + ? (random_range * value) : (random_range * value * 0.01f); + + const float_t x1 = canvas_pos.x + + (float_t)(int32_t)(j - base_start_time) * frame_width + (float_t)(int32_t)k; + const float_t x2 = canvas_pos.x + + (float_t)(int32_t)(j - base_start_time) * frame_width + (float_t)(int32_t)(k + 1); + glitter_editor_curve_editor_window_draw_random_range(crv_edt, x1, x2, + value, random, min, max, random_range_negate, + canvas_size, canvas_pos, canvas_pos_min, canvas_pos_max); + } + } + } break; + } + } + } + + bool first_frame_found = false; + + const Glitter::Curve::Key* i_begin = keys->data(); + const Glitter::Curve::Key* i_end = keys->data() + keys->size(); + for (const Glitter::Curve::Key* i = i_begin; i != i_end; i++) { + if (i->frame <= start_time || i->frame > start_time && !first_frame_found) { + if (i_end - i <= 1) + break; + else if (i[1].frame <= start_time) + continue; + + const Glitter::Curve::Key* c = i; + const Glitter::Curve::Key* n = i + 1; + const float_t c_value = fix_rot_z ? c->value - (float_t)M_PI_2 : c->value; + const float_t n_value = fix_rot_z ? n->value - (float_t)M_PI_2 : n->value; + + float_t value; + if (i->frame < start_time) + switch (c->type) { + case Glitter::KEY_CONSTANT: + value = c_value; + break; + case Glitter::KEY_LINEAR: + default: + value = interpolate_linear_value(c_value, n_value, + (float_t)c->frame, (float_t)n->frame, (float_t)start_time); + break; + case Glitter::KEY_HERMITE: + value = interpolate_chs_value(c_value, n_value, + (float_t)c->tangent2, (float_t)n->tangent1, + (float_t)c->frame, (float_t)n->frame, (float_t)start_time); + break; + } + else + value = c_value; + + const float_t x1 = loop + ? canvas_pos.x + (float_t)(start_time - base_start_time) * frame_width + : canvas_pos_min.x; + const float_t x2 = canvas_pos.x + (float_t)(max_def(i->frame, + start_time) - base_start_time) * frame_width; + const float_t y = convert_value_to_height(crv_edt, value, + canvas_pos.y, canvas_size.y, min, max); + + if ((x1 > canvas_pos_min.x || x2 > canvas_pos_min.x) + && (x1 < canvas_pos_max.x || x2 < canvas_pos_max.x)) { + if (!points.size() || points.back().x < x1 || points.back().y != y) + points.push_back({ x1, y }); + if (points.back().x < x2 || points.back().y != y) + points.push_back({ x2, y }); + } + first_frame_found = true; + } + else if (i->frame > end_time || i->frame == end_time || i_end - i <= 1 && i->frame <= end_time) { + float_t value; + if (i->frame > end_time) { + const Glitter::Curve::Key* c = i - 1; + const Glitter::Curve::Key* n = i; + const float_t c_value = fix_rot_z ? c->value - (float_t)M_PI_2 : c->value; + const float_t n_value = fix_rot_z ? n->value - (float_t)M_PI_2 : n->value; + + switch (c->type) { + case Glitter::KEY_CONSTANT: + value = c_value; + break; + case Glitter::KEY_LINEAR: + default: + value = interpolate_linear_value(c_value, n_value, + (float_t)c->frame, (float_t)n->frame, (float_t)end_time); + break; + case Glitter::KEY_HERMITE: + value = interpolate_chs_value(c_value, n_value, + (float_t)c->tangent2, (float_t)n->tangent1, + (float_t)c->frame, (float_t)n->frame, (float_t)end_time); + break; + } + } + else + value = i->value; + + const float_t x1 = canvas_pos.x + (float_t)(min_def(i->frame, + end_time) - base_start_time) * frame_width; + const float_t x2 = loop + ? canvas_pos.x + (float_t)(end_time - base_start_time) * frame_width + : canvas_pos_max.x; + const float_t y = convert_value_to_height(crv_edt, value, + canvas_pos.y, canvas_size.y, min, max); + if ((x1 > canvas_pos_min.x || x2 > canvas_pos_min.x) + && (x1 < canvas_pos_max.x || x2 < canvas_pos_max.x)) { + if (!points.size() || points.back().x < x1 || points.back().y != y) + points.push_back({ x1, y }); + if (points.back().x < x2 || points.back().y != y) + points.push_back({ x2, y }); + } + break; + } + else if (i_end - i <= 1) + break; + + const Glitter::Curve::Key* c = i; + const Glitter::Curve::Key* n = i + 1; + const float_t c_value = fix_rot_z ? c->value - (float_t)M_PI_2 : c->value; + const float_t n_value = fix_rot_z ? n->value - (float_t)M_PI_2 : n->value; + + if (c->type == Glitter::KEY_CONSTANT) { + const int32_t c_frame = max_def(c->frame, start_time); + const int32_t n_frame = min_def(n->frame, end_time); + const float_t x1 = canvas_pos.x + (float_t)(c_frame - base_start_time) * frame_width; + const float_t x2 = canvas_pos.x + (float_t)(n_frame - base_start_time) * frame_width; + + const float_t y1 = convert_value_to_height(crv_edt, c_value, + canvas_pos.y, canvas_size.y, min, max); + const float_t y2 = convert_value_to_height(crv_edt, n_value, + canvas_pos.y, canvas_size.y, min, max); + + if ((x1 > canvas_pos_min.x || x2 > canvas_pos_min.x) + && (x1 < canvas_pos_max.x || x2 < canvas_pos_max.x)) { + if (!points.size() || points.back().x < x1 || points.back().y != y1) + points.push_back({ x1, y1 }); + if (points.back().x < x2 || points.back().y != y1) + points.push_back({ x2, y1 }); + if (points.back().x < x2 || points.back().y != y2) + points.push_back({ x2, y2 }); + } + } + else if (c->type == Glitter::KEY_LINEAR) { + const int32_t c_frame = max_def(c->frame, start_time); + const int32_t n_frame = min_def(n->frame, end_time); + const float_t x1 = canvas_pos.x + (float_t)(c_frame - base_start_time) * frame_width; + const float_t x2 = canvas_pos.x + (float_t)(n_frame - base_start_time) * frame_width; + + const float_t _c_value = interpolate_linear_value(c_value, n_value, + (float_t)c->frame, (float_t)n->frame, (float_t)c_frame); + const float_t _n_value = interpolate_linear_value(c_value, n_value, + (float_t)c->frame, (float_t)n->frame, (float_t)n_frame); + + const float_t y1 = convert_value_to_height(crv_edt, _c_value, + canvas_pos.y, canvas_size.y, min, max); + const float_t y2 = convert_value_to_height(crv_edt, _n_value, + canvas_pos.y, canvas_size.y, min, max); + + if ((x1 > canvas_pos_min.x || x2 > canvas_pos_min.x) + && (x1 < canvas_pos_max.x || x2 < canvas_pos_max.x)) { + if (!points.size() || points.back().x < x1 || points.back().y != y1) + points.push_back({ x1, y1 }); + if (points.back().x < x2 || points.back().y != y2) + points.push_back({ x2, y2 }); + } + } + else if (c->type == Glitter::KEY_HERMITE) { + const float_t c_frame = (float_t)c->frame; + const float_t n_frame = (float_t)n->frame; + const float_t c_tangent2 = (float_t)c->tangent2; + const float_t n_tangent1 = (float_t)n->tangent1; + + float_t value = interpolate_chs_value(c_value, n_value, + c_tangent2, n_tangent1, + c_frame, n_frame, (float_t)max_def(c->frame, start_time)); + float_t x = canvas_pos.x + (float_t)(max_def(c->frame, start_time) + - base_start_time) * frame_width; + float_t y = convert_value_to_height(crv_edt, value, + canvas_pos.y, canvas_size.y, min, max); + if (!points.size() || points.back().x < x || points.back().y != y) + points.push_back({ x, y }); + + const size_t frame_width_int = (size_t)roundf(frame_width); + for (size_t j = c->frame; j < n->frame; j++) { + if (j < start_time) + continue; + else if (j >= end_time) + break; + + for (size_t k = 0; k < frame_width_int; k++) { + const float_t value = interpolate_chs_value(c_value, n_value, c_tangent2, n_tangent1, + c_frame, n_frame, (float_t)(int32_t)j + (float_t)(int32_t)k / frame_width); + + float_t x = canvas_pos.x + + (float_t)(int32_t)(j - base_start_time) * frame_width + (float_t)(int32_t)k; + const float_t y = convert_value_to_height(crv_edt, value, + canvas_pos.y, canvas_size.y, min, max); + + if ((x > canvas_pos_min.x || points.back().x < canvas_pos_max.x + && canvas_pos_max.x < x) && points.back().x < x) + points.push_back({ x, y }); + } + } + } + } +} + +static void glitter_editor_curve_editor_window_draw_random_range( + GlitterEditor::CurveEditor* crv_edt, const float_t x1, const float_t x2, + const vec3 value, const vec3 random, const float_t min, const float_t max, const bool random_range_negate, + const ImVec2 canvas_size, const ImVec2 canvas_pos, const ImVec2 canvas_pos_min, const ImVec2 canvas_pos_max) { + const ImU32 random_range_color = ImGui::GetColorU32({ 0.5f, 0.5f, 0.0f, 0.25f }); + const ImU32 key_random_range_color = ImGui::GetColorU32({ 0.5f, 0.0f, 0.5f, 0.25f }); + + if ((x1 <= canvas_pos_min.x && x2 <= canvas_pos_min.x) || (x1 >= canvas_pos_max.x && x2 >= canvas_pos_max.x)) + return; + + ImDrawList* draw_list = crv_edt->draw_list; + if (value.x < value.y || value.y > value.z) { + float_t y1 = convert_value_to_height(crv_edt, value.x + random.x, + canvas_pos.y, canvas_size.y, min, max); + float_t y2 = convert_value_to_height(crv_edt, value.x, + canvas_pos.y, canvas_size.y, min, max); + float_t y3 = y2; + float_t y4; + float_t y5; + float_t y6; + if (!random_range_negate) + y4 = convert_value_to_height(crv_edt, value.y, + canvas_pos.y, canvas_size.y, min, max); + else { + y4 = convert_value_to_height(crv_edt, value.z, + canvas_pos.y, canvas_size.y, min, max); + y5 = y4; + y6 = convert_value_to_height(crv_edt, value.z - random.z, + canvas_pos.y, canvas_size.y, min, max); + } + + if (y1 > y2) { + float_t t = y2; + y2 = y1; + y1 = t; + } + + if (y3 > y4) { + float_t t = y4; + y4 = y3; + y3 = t; + } + + if (random_range_negate && y5 > y6) { + float_t t = y6; + y6 = y5; + y5 = t; + } + + y1 = clamp_def(y1, canvas_pos_min.y, canvas_pos_max.y); + y2 = clamp_def(y2, canvas_pos_min.y, canvas_pos_max.y); + y3 = clamp_def(y3, canvas_pos_min.y, canvas_pos_max.y); + y4 = clamp_def(y4, canvas_pos_min.y, canvas_pos_max.y); + + if (random_range_negate) { + y5 = clamp_def(y5, canvas_pos_min.y, canvas_pos_max.y); + y6 = clamp_def(y6, canvas_pos_min.y, canvas_pos_max.y); + } + + if (y1 != y2) + draw_list->AddRectFilled({ x1, y1 }, { x2, y2 }, random_range_color); + + if (y3 != y4) + draw_list->AddRectFilled({ x1, y3 }, { x2, y4 }, key_random_range_color); + + if (random_range_negate && y5 != y6) + draw_list->AddRectFilled({ x1, y5 }, { x2, y6 }, random_range_color); + } + else { + float_t y1 = convert_value_to_height(crv_edt, value.y + random.y, + canvas_pos.y, canvas_size.y, min, max); + float_t y2; + if (!random_range_negate) + y2 = convert_value_to_height(crv_edt, value.y, + canvas_pos.y, canvas_size.y, min, max); + else + y2 = convert_value_to_height(crv_edt, value.y - random.y, + canvas_pos.y, canvas_size.y, min, max); + + if (y1 > y2) { + float_t t = y2; + y2 = y1; + y1 = t; + } + + y1 = clamp_def(y1, canvas_pos_min.y, canvas_pos_max.y); + y2 = clamp_def(y2, canvas_pos_min.y, canvas_pos_max.y); + if (y1 != y2) + draw_list->AddRectFilled({ x1, y1 }, { x2, y2 }, random_range_color); + } +} + +static void glitter_editor_curve_editor_window_draw_random_range( + GlitterEditor::CurveEditor* crv_edt, const float_t x1, const float_t x2, + const vec3 value1, const vec3 value2, const vec3 random1, const vec3 random2, + const float_t min, const float_t max, const bool random_range_negate, + const ImVec2 canvas_size, const ImVec2 canvas_pos, const ImVec2 canvas_pos_min, const ImVec2 canvas_pos_max) { + const ImU32 random_range_color = ImGui::GetColorU32({ 0.5f, 0.5f, 0.0f, 0.25f }); + const ImU32 key_random_range_color = ImGui::GetColorU32({ 0.5f, 0.0f, 0.5f, 0.25f }); + + if ((x1 <= canvas_pos_min.x && x2 <= canvas_pos_min.x) || (x1 >= canvas_pos_max.x && x2 >= canvas_pos_max.x)) + return; + + ImDrawList* draw_list = crv_edt->draw_list; + if (value1.x < value1.y || value1.y != value1.z + || value2.x < value2.y || value2.y != value2.z) { + float_t y11 = convert_value_to_height(crv_edt, value1.x + random1.x, + canvas_pos.y, canvas_size.y, min, max); + float_t y21 = convert_value_to_height(crv_edt, value2.x + random2.x, + canvas_pos.y, canvas_size.y, min, max); + float_t y12 = convert_value_to_height(crv_edt, value1.x, + canvas_pos.y, canvas_size.y, min, max); + float_t y22 = convert_value_to_height(crv_edt, value2.x, + canvas_pos.y, canvas_size.y, min, max); + float_t y13 = y12; + float_t y23 = y22; + float_t y14; + float_t y24; + float_t y15; + float_t y25; + float_t y16; + float_t y26; + if (!random_range_negate) { + y14 = convert_value_to_height(crv_edt, value1.y, + canvas_pos.y, canvas_size.y, min, max); + y24 = convert_value_to_height(crv_edt, value2.y, + canvas_pos.y, canvas_size.y, min, max); + } + else { + y14 = convert_value_to_height(crv_edt, value1.z, + canvas_pos.y, canvas_size.y, min, max); + y24 = convert_value_to_height(crv_edt, value2.z, + canvas_pos.y, canvas_size.y, min, max); + y15 = y14; + y25 = y24; + y16 = convert_value_to_height(crv_edt, value1.z - random1.z, + canvas_pos.y, canvas_size.y, min, max); + y26 = convert_value_to_height(crv_edt, value2.z - random2.z, + canvas_pos.y, canvas_size.y, min, max); + } + + if (y11 > y12) { + float_t t = y12; + y12 = y11; + y11 = t; + } + + if (y21 > y22) { + float_t t = y22; + y22 = y21; + y21 = t; + } + + if (y13 > y14) { + float_t t = y14; + y14 = y13; + y13 = t; + } + + if (y23 > y24) { + float_t t = y24; + y24 = y23; + y23 = t; + } + + if (random_range_negate) { + if (y15 > y16) { + float_t t = y16; + y16 = y15; + y15 = t; + } + + if (y25 > y26) { + float_t t = y26; + y26 = y25; + y25 = t; + } + } + + if (y11 != y12 || y21 != y22) + draw_list->AddQuadFilled({ x1, y11 }, { x2, y21 }, { x2, y22 }, { x1, y12 }, random_range_color); + + if (y13 != y14 || y23 != y24) + draw_list->AddQuadFilled({ x1, y13 }, { x2, y23 }, { x2, y24 }, { x1, y14 }, key_random_range_color); + + if (random_range_negate && (y15 != y16 || y25 != y26)) + draw_list->AddQuadFilled({ x1, y15 }, { x2, y25 }, { x2, y26 }, { x1, y16 }, random_range_color); + } + else { + float_t y11 = convert_value_to_height(crv_edt, value1.y + random1.y, + canvas_pos.y, canvas_size.y, min, max); + float_t y21 = convert_value_to_height(crv_edt, value2.y + random2.y, + canvas_pos.y, canvas_size.y, min, max); + float_t y12; + float_t y22; + if (!random_range_negate) { + y12 = convert_value_to_height(crv_edt, value1.y, + canvas_pos.y, canvas_size.y, min, max); + y22 = convert_value_to_height(crv_edt, value2.y, + canvas_pos.y, canvas_size.y, min, max); + } + else { + y12 = convert_value_to_height(crv_edt, value1.y - random1.y, + canvas_pos.y, canvas_size.y, min, max); + y22 = convert_value_to_height(crv_edt, value2.y - random2.y, + canvas_pos.y, canvas_size.y, min, max); + } + + if (y11 > y12) { + float_t t = y12; + y12 = y11; + y11 = t; + } + + if (y21 > y22) { + float_t t = y22; + y22 = y21; + y21 = t; + } + + if (y11 != y12 || y21 != y22) + draw_list->AddQuadFilled({ x1, y11 }, { x1, y21 }, { x2, y22 }, { x2, y12 }, random_range_color); + } +} + static bool glitter_editor_hash_input(GlitterEditor* glt_edt, const char* label, uint64_t* hash) { uint64_t h = *hash; if (glt_edt->effect_group->type == Glitter::FT) { diff --git a/src/ReDIVA/data_test/auth_3d_test.cpp b/src/ReDIVA/data_test/auth_3d_test.cpp index 71a60cc1..d979c9f1 100644 --- a/src/ReDIVA/data_test/auth_3d_test.cpp +++ b/src/ReDIVA/data_test/auth_3d_test.cpp @@ -165,9 +165,9 @@ void Auth3dTestWindow::Window() { if (auth) last_frame = auth->play_control.size; - if (auth_3d_data_check_id_not_empty(&auth_3d_test_task->auth_3d_id)) { - enable = auth_3d_data_get_enable(&auth_3d_test_task->auth_3d_id); - frame = auth_3d_data_get_frame(&auth_3d_test_task->auth_3d_id); + if (auth_3d_data_check_id_not_empty(auth_3d_test_task->auth_3d_id)) { + enable = auth_3d_data_get_enable(auth_3d_test_task->auth_3d_id); + frame = auth_3d_data_get_frame(auth_3d_test_task->auth_3d_id); frame_changed = false; } @@ -365,16 +365,16 @@ void Auth3dTestWindow::Window() { ImGui::Checkbox("Link Stage Change", &auth_3d_test_task->window.stage_link_change); - if (auth_3d_data_check_id_not_empty(&auth_3d_test_task->auth_3d_id)) { - auth_3d_data_set_enable(&auth_3d_test_task->auth_3d_id, enable); - auth_3d_data_set_repeat(&auth_3d_test_task->auth_3d_id, auth_3d_test_task->repeat); - auth_3d_data_set_left_right_reverse(&auth_3d_test_task->auth_3d_id, auth_3d_test_task->left_right_reverse); + if (auth_3d_data_check_id_not_empty(auth_3d_test_task->auth_3d_id)) { + auth_3d_data_set_enable(auth_3d_test_task->auth_3d_id, enable); + auth_3d_data_set_repeat(auth_3d_test_task->auth_3d_id, auth_3d_test_task->repeat); + auth_3d_data_set_left_right_reverse(auth_3d_test_task->auth_3d_id, auth_3d_test_task->left_right_reverse); if (frame_changed) { - auth_3d_data_set_req_frame(&auth_3d_test_task->auth_3d_id, frame); + auth_3d_data_set_req_frame(auth_3d_test_task->auth_3d_id, frame); frame_changed = false; } - auth_3d_data_set_paused(&auth_3d_test_task->auth_3d_id, paused); - auth_3d_data_set_frame_rate(&auth_3d_test_task->auth_3d_id, 0); + auth_3d_data_set_paused(auth_3d_test_task->auth_3d_id, paused); + auth_3d_data_set_frame_rate(auth_3d_test_task->auth_3d_id, 0); } ImGui::End(); } diff --git a/src/ReDIVA/input.cpp b/src/ReDIVA/input.cpp index 4b3d55af..b0e6f31a 100644 --- a/src/ReDIVA/input.cpp +++ b/src/ReDIVA/input.cpp @@ -24,11 +24,11 @@ bool input_reset_mouse_position; bool input_locked; extern bool close; -extern lock render_lock; +extern lock_cs render_lock; extern timer* render_timer; extern HWND window_handle; extern ImGuiContext* imgui_context; -extern lock imgui_context_lock; +extern lock_cs imgui_context_lock; namespace Input { struct Key { diff --git a/src/ReDIVA/pv_game.cpp b/src/ReDIVA/pv_game.cpp index ef8a9c6a..5530a6ff 100644 --- a/src/ReDIVA/pv_game.cpp +++ b/src/ReDIVA/pv_game.cpp @@ -490,9 +490,9 @@ bool pv_game_old::Ctrl() { uint32_t light_auth_3d_uid = auth_3d_db->get_uid(buf); if (light_auth_3d_uid != -1) { light_auth_3d_id = auth_3d_data_load_uid(light_auth_3d_uid, auth_3d_db); - auth_3d_data_read_file(&light_auth_3d_id, auth_3d_db); - auth_3d_data_set_enable(&light_auth_3d_id, false); - auth_3d_data_set_visibility(&light_auth_3d_id, false); + auth_3d_data_read_file(light_auth_3d_id, auth_3d_db); + auth_3d_data_set_enable(light_auth_3d_id, false); + auth_3d_data_set_visibility(light_auth_3d_id, false); break; } } @@ -503,9 +503,9 @@ bool pv_game_old::Ctrl() { sprintf_s(buf, sizeof(buf), "CAMPV%03d_BASE", pv_id); uint32_t camera_auth_3d_uid = auth_3d_db->get_uid(buf); camera_auth_3d_id = auth_3d_data_load_uid(camera_auth_3d_uid, auth_3d_db); - auth_3d_data_read_file_modern(&camera_auth_3d_id); - auth_3d_data_set_enable(&camera_auth_3d_id, false); - auth_3d_data_set_visibility(&camera_auth_3d_id, false); + auth_3d_data_read_file_modern(camera_auth_3d_id); + auth_3d_data_set_enable(camera_auth_3d_id, false); + auth_3d_data_set_visibility(camera_auth_3d_id, false); } state = 7; @@ -514,13 +514,13 @@ bool pv_game_old::Ctrl() { bool wait_load = false; for (auto i : pv_auth_3d_ids) - if (!auth_3d_data_check_id_loaded(&i.second)) + if (!auth_3d_data_check_id_loaded(i.second)) wait_load = true; - if (!auth_3d_data_check_id_loaded(&light_auth_3d_id)) + if (!auth_3d_data_check_id_loaded(light_auth_3d_id)) wait_load = true; - if (!auth_3d_data_check_id_loaded(&camera_auth_3d_id)) + if (!auth_3d_data_check_id_loaded(camera_auth_3d_id)) wait_load = true; if (!wait_load) @@ -621,17 +621,17 @@ bool pv_game_old::Ctrl() { && pv_game_dsc_process(this, this->time)) dsc_data_ptr++; - auth_3d_data_set_enable(&light_auth_3d_id, true); - auth_3d_data_set_camera_root_update(&light_auth_3d_id, false); - auth_3d_data_set_paused(&light_auth_3d_id, false); - auth_3d_data_set_repeat(&camera_auth_3d_id, false); - auth_3d_data_set_visibility(&light_auth_3d_id, true); + auth_3d_data_set_enable(light_auth_3d_id, true); + auth_3d_data_set_camera_root_update(light_auth_3d_id, false); + auth_3d_data_set_paused(light_auth_3d_id, false); + auth_3d_data_set_repeat(light_auth_3d_id, false); + auth_3d_data_set_visibility(light_auth_3d_id, true); - auth_3d_data_set_enable(&camera_auth_3d_id, true); - auth_3d_data_set_camera_root_update(&light_auth_3d_id, true); - auth_3d_data_set_paused(&camera_auth_3d_id, false); - auth_3d_data_set_repeat(&camera_auth_3d_id, false); - auth_3d_data_set_visibility(&camera_auth_3d_id, true); + auth_3d_data_set_enable(camera_auth_3d_id, true); + auth_3d_data_set_camera_root_update(camera_auth_3d_id, true); + auth_3d_data_set_paused(camera_auth_3d_id, false); + auth_3d_data_set_repeat(camera_auth_3d_id, false); + auth_3d_data_set_visibility(camera_auth_3d_id, true); pause = true; } break; diff --git a/src/ReDIVA/pv_game.hpp b/src/ReDIVA/pv_game.hpp index a6db5581..ca4c066d 100644 --- a/src/ReDIVA/pv_game.hpp +++ b/src/ReDIVA/pv_game.hpp @@ -98,7 +98,7 @@ struct pv_disp2d { std::string title_2d_layer; pv_disp2d(); - virtual ~pv_disp2d(); + ~pv_disp2d(); }; struct pv_data_camera { diff --git a/src/ReDIVA/render.cpp b/src/ReDIVA/render.cpp index 6b008b61..26625e22 100644 --- a/src/ReDIVA/render.cpp +++ b/src/ReDIVA/render.cpp @@ -156,11 +156,11 @@ static void APIENTRY render_debug_output(GLenum source, GLenum type, uint32_t id bool close; bool reload_render; -lock* render_lock; +lock_cs* render_lock; HWND window_handle; GLFWwindow* window; ImGuiContext* imgui_context; -lock* imgui_context_lock; +lock_cs* imgui_context_lock; bool global_context_menu; extern size_t frame_counter; render_context* rctx_ptr; @@ -174,7 +174,7 @@ int32_t render_main(render_init_struct* ris) { SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL); timeBeginPeriod(1); - render_lock = new lock; + render_lock = new lock_cs; if (!render_lock) return 0; @@ -1015,7 +1015,7 @@ static render_context* render_load() { cam->set_interest({ 0.0f, 1.375f, 0.0f }); imgui_context = ImGui::CreateContext(); - imgui_context_lock = new lock; + imgui_context_lock = new lock_cs; lock_lock(imgui_context_lock); ImGui::SetCurrentContext(imgui_context); @@ -1770,7 +1770,7 @@ static void render_imgui_context_menu(classes_data* classes, ImGui::MenuItem(c->name, 0, false, false); else if (ImGui::MenuItem(c->name, 0)) { if (~c->data.flags & CLASS_INIT) { - c->data.lock = new lock; + c->data.lock = new lock_cs; if (c->data.lock->check_init() && c->init) { lock_lock(c->data.lock); if (c->init(&c->data, rctx)) diff --git a/src/ReDIVA/x_pv_game.cpp b/src/ReDIVA/x_pv_game.cpp index cae6caae..aa1a129d 100644 --- a/src/ReDIVA/x_pv_game.cpp +++ b/src/ReDIVA/x_pv_game.cpp @@ -7,7 +7,6 @@ #if defined(ReDIVA_DEV) #include "x_pv_game.hpp" -#include #include "../CRE/light_param/light.hpp" #include "../CRE/light_param.hpp" #include "../CRE/data.hpp" @@ -18,6 +17,7 @@ #include "../CRE/random.hpp" #include "../CRE/sound.hpp" #include "../CRE/task_effect.hpp" +#include "../KKdLib/io/file_stream.hpp" #include "../KKdLib/farc.hpp" #include "../KKdLib/interpolation.hpp" #include "../KKdLib/sort.hpp" @@ -228,7 +228,9 @@ static float_t dsc_time_to_frame(int64_t time); static void x_pv_game_chara_item_alpha_callback(void* data, int32_t chara_id, int32_t type, float_t alpha); static void x_pv_game_change_field(x_pv_game* xpvgm, int32_t field, int64_t dsc_time, int64_t curr_time); static bool x_pv_game_dsc_process(x_pv_game* xpvgm, int64_t curr_time); -//static void x_pv_game_map_auth_3d_to_mot(x_pv_game* xpvgm, bool add_keys); +#if BAKE_PV826 +static void x_pv_game_map_auth_3d_to_mot(x_pv_game* xpvgm, bool add_keys); +#endif static void x_pv_game_reset_field(x_pv_game* xpvgm); static void x_pv_game_split_auth_3d_hrc_material_list(x_pv_game* xpvgm, std::set& object_hrc, std::set& material_list); @@ -591,7 +593,8 @@ void x_pv_play_data::reset() { motion_data.reset(); } -/*x_pv_game_a3da_to_mot_keys::x_pv_game_a3da_to_mot_keys() { +#if BAKE_PV826 +x_pv_game_a3da_to_mot_keys::x_pv_game_a3da_to_mot_keys() { } @@ -656,6 +659,7 @@ x_pv_game_a3da_to_mot::x_pv_game_a3da_to_mot(int32_t auth_3d_id) { x_pv_game_a3da_to_mot::~x_pv_game_a3da_to_mot() { } + static int32_t get_bone_index(auth_3d_object_hrc* oh, const char* name) { uint32_t name_hash = hash_utf8_murmurhash(name); for (auth_3d_object_node& i : oh->node) @@ -715,7 +719,8 @@ void x_pv_game_a3da_to_mot::get_bone_indices(auth_3d_object_hrc* oh) { j_momo_r_wj = get_bone_index(oh, "j_momo_r_wj"); j_sune_r_wj = get_bone_index(oh, "j_sune_r_wj"); j_asi_r_wj = get_bone_index(oh, "j_asi_r_wj"); -}*/ +} +#endif x_pv_game_song_effect_auth_3d::x_pv_game_song_effect_auth_3d() { id = -1; @@ -734,10 +739,7 @@ x_pv_game_song_effect_glitter::x_pv_game_song_effect_glitter() : scene_counter() } void x_pv_game_song_effect_glitter::reset() { - name.str.clear(); - name.str.shrink_to_fit(); - name.hash_fnv1a64m = hash_fnv1a64m_empty; - name.hash_murmurhash = hash_murmurhash_empty; + name.clear(); scene_counter = 0; field_8 = false; for (bool& i : field_9) @@ -777,12 +779,12 @@ void x_pv_game_camera::ctrl(float_t curr_time) { break; int32_t id = auth_3d_data_load_hash(file.hash_murmurhash, &data_list[DATA_X], 0, 0); - if (auth_3d_data_check_id_not_empty(&id)) { - auth_3d_data_read_file_modern(&id); - auth_3d_data_set_enable(&id, false); - auth_3d_data_set_repeat(&id, false); - auth_3d_data_set_paused(&id, false); - auth_3d_data_set_frame_rate(&id, frame_rate_control); + if (auth_3d_data_check_id_not_empty(id)) { + auth_3d_data_read_file_modern(id); + auth_3d_data_set_enable(id, false); + auth_3d_data_set_repeat(id, false); + auth_3d_data_set_paused(id, false); + auth_3d_data_set_frame_rate(id, frame_rate_control); } auth_3d_id = id; @@ -790,17 +792,17 @@ void x_pv_game_camera::ctrl(float_t curr_time) { state = 11; } break; case 11: { - if (auth_3d_data_check_id_not_empty(&auth_3d_id) - && auth_3d_data_check_id_loaded(&auth_3d_id)) + if (auth_3d_data_check_id_not_empty(auth_3d_id) + && auth_3d_data_check_id_loaded(auth_3d_id)) state = 20; } break; case 20: { int32_t& id = auth_3d_id; - auth_3d_data_set_enable(&id, 1u); - auth_3d_data_set_repeat(&id, false); - auth_3d_data_set_paused(&id, 0); - auth_3d_data_set_camera_root_update(&id, true); - auth_3d_data_set_req_frame(&id, curr_time * 60.0f); + auth_3d_data_set_enable(id, 1u); + auth_3d_data_set_repeat(id, false); + auth_3d_data_set_paused(id, 0); + auth_3d_data_set_camera_root_update(id, true); + auth_3d_data_set_req_frame(id, curr_time * 60.0f); } break; } } @@ -829,20 +831,14 @@ void x_pv_game_camera::load_data() { void x_pv_game_camera::reset() { state = 0; - category.str.clear(); - category.str.shrink_to_fit(); - category.hash_fnv1a64m = hash_fnv1a64m_empty; - category.hash_murmurhash = hash_murmurhash_empty; - file.str.clear(); - file.str.shrink_to_fit(); - file.hash_fnv1a64m = hash_fnv1a64m_empty; - file.hash_murmurhash = hash_murmurhash_empty; + category.clear(); + file.clear(); auth_3d_id = -1; } void x_pv_game_camera::stop() { - if (auth_3d_data_check_id_not_empty(&auth_3d_id)) - auth_3d_data_set_enable(&auth_3d_id, false); + if (auth_3d_data_check_id_not_empty(auth_3d_id)) + auth_3d_data_set_enable(auth_3d_id, false); } void x_pv_game_camera::unload() { @@ -890,16 +886,16 @@ void x_pv_game_effect::ctrl(object_database* obj_db, texture_database* tex_db) { pvpp_effect& effect = play_param->effect[i]; for (string_hash& j : effect.auth_3d) { int32_t id = auth_3d_data_load_hash(j.hash_murmurhash, x_data, obj_db, tex_db); - if (!auth_3d_data_check_id_not_empty(&id)) { + if (!auth_3d_data_check_id_not_empty(id)) { continue; } - auth_3d_data_read_file_modern(&id); - auth_3d_data_set_enable(&id, false); - auth_3d_data_set_repeat(&id, false); - auth_3d_data_set_paused(&id, false); - auth_3d_data_set_visibility(&id, false); - auth_3d_data_set_frame_rate(&id, frame_rate_control); + auth_3d_data_read_file_modern(id); + auth_3d_data_set_enable(id, false); + auth_3d_data_set_repeat(id, false); + auth_3d_data_set_paused(id, false); + auth_3d_data_set_visibility(id, false); + auth_3d_data_set_frame_rate(id, frame_rate_control); song_effect.auth_3d.push_back(id); } @@ -911,8 +907,8 @@ void x_pv_game_effect::ctrl(object_database* obj_db, texture_database* tex_db) { for (x_pv_game_song_effect& i : song_effect) for (x_pv_game_song_effect_auth_3d& j : i.auth_3d) - if (auth_3d_data_check_id_not_empty(&j.id) - && !auth_3d_data_check_id_loaded(&j.id)) + if (auth_3d_data_check_id_not_empty(j.id) + && !auth_3d_data_check_id_loaded(j.id)) wait_load |= true; for (string_hash& i : pv_glitter) @@ -983,7 +979,7 @@ void x_pv_game_effect::ctrl(object_database* obj_db, texture_database* tex_db) { for (x_pv_game_song_effect& i : song_effect) if (i.enable) for (x_pv_game_song_effect_auth_3d& j : i.auth_3d) - auth_3d_data_set_chara_id(&j.id, i.chara_id); + auth_3d_data_set_chara_id(j.id, i.chara_id); } break; } } @@ -1066,8 +1062,8 @@ void x_pv_game_effect::set_chara_id(int32_t index, int32_t chara_id, bool chara_ x_pv_game_song_effect& song_effect = this->song_effect[index]; for (x_pv_game_song_effect_auth_3d& i : song_effect.auth_3d) { - auth_3d_data_set_chara_id(&i.id, chara_id); - auth_3d_data_set_chara_item(&i.id, chara_item); + auth_3d_data_set_chara_id(i.id, chara_id); + auth_3d_data_set_chara_item(i.id, chara_item); } song_effect.chara_id = chara_id; @@ -1096,10 +1092,10 @@ void x_pv_game_effect::set_song_effect(int32_t index, int64_t time) { song_effect.chara_id = chara_id; for (x_pv_game_song_effect_auth_3d& i : song_effect.auth_3d) { - auth_3d_data_set_enable(&i.id, true); - auth_3d_data_set_repeat(&i.id, false); - auth_3d_data_set_req_frame(&i.id, 0.0f); - auth_3d_data_set_visibility(&i.id, true); + auth_3d_data_set_enable(i.id, true); + auth_3d_data_set_repeat(i.id, false); + auth_3d_data_set_req_frame(i.id, 0.0f); + auth_3d_data_set_visibility(i.id, true); } for (x_pv_game_song_effect_glitter& i : song_effect.glitter) { @@ -1116,7 +1112,7 @@ void x_pv_game_effect::set_song_effect(int32_t index, int64_t time) { set_song_effect_time_inner(index, time, false); for (x_pv_game_song_effect_auth_3d& i : song_effect.auth_3d) - auth_3d_data_set_chara_id(&i.id, chara_id); + auth_3d_data_set_chara_id(i.id, chara_id); } void x_pv_game_effect::set_song_effect_time(int32_t index, int64_t time, bool glitter) { @@ -1150,9 +1146,9 @@ void x_pv_game_effect::set_song_effect_time_inner(int32_t index, int64_t time, b } for (x_pv_game_song_effect_auth_3d& i : song_effect.auth_3d) { - auth_3d_data_set_req_frame(&i.id, req_frame); - auth_3d_data_set_paused(&i.id, false); - auth_3d_data_set_max_frame(&i.id, max_frame); + auth_3d_data_set_req_frame(i.id, req_frame); + auth_3d_data_set_paused(i.id, false); + auth_3d_data_set_max_frame(i.id, max_frame); } if (glitter) @@ -1182,9 +1178,9 @@ void x_pv_game_effect::stop_song_effect(int32_t index, bool free_glitter) { for (x_pv_game_song_effect_auth_3d& i : song_effect.auth_3d) { int32_t& id = i.id; - auth_3d_data_set_enable(&id, false); - auth_3d_data_set_req_frame(&id, 0.0f); - auth_3d_data_set_visibility(&id, false); + auth_3d_data_set_enable(id, false); + auth_3d_data_set_req_frame(id, 0.0f); + auth_3d_data_set_visibility(id, false); } for (x_pv_game_song_effect_glitter& i : song_effect.glitter) @@ -1247,18 +1243,9 @@ void x_pv_game_chara_effect_auth_3d::reset() { field_0 = false; src_chara = CHARA_MAX; dst_chara = CHARA_MAX; - file.str.clear(); - file.str.shrink_to_fit(); - file.hash_fnv1a64m = hash_fnv1a64m_empty; - file.hash_murmurhash = hash_murmurhash_empty; - category.str.clear(); - category.str.shrink_to_fit(); - category.hash_fnv1a64m = hash_fnv1a64m_empty; - category.hash_murmurhash = hash_murmurhash_empty; - object_set.str.clear(); - object_set.str.shrink_to_fit(); - object_set.hash_fnv1a64m = hash_fnv1a64m_empty; - object_set.hash_murmurhash = hash_murmurhash_empty; + file.clear(); + category.clear(); + object_set.clear(); id = -1; time = -1; } @@ -1271,7 +1258,12 @@ x_pv_game_chara_effect::~x_pv_game_chara_effect() { } +#if BAKE_PV826 +void x_pv_game_chara_effect::ctrl(object_database* obj_db, texture_database* tex_db, + int32_t pv_id, std::map* effchrpv_auth_3d_mot_ids) { +#else void x_pv_game_chara_effect::ctrl(object_database* obj_db, texture_database* tex_db) { +#endif switch (state) { case 20: { bool wait_load = false; @@ -1300,22 +1292,27 @@ void x_pv_game_chara_effect::ctrl(object_database* obj_db, texture_database* tex continue; int32_t id = auth_3d_data_load_hash(j.file.hash_murmurhash, x_data, obj_db, tex_db); - if (!auth_3d_data_check_id_not_empty(&id)) { + if (!auth_3d_data_check_id_not_empty(id)) { j.id = -1; continue; } - auth_3d_data_read_file_modern(&id); - auth_3d_data_set_enable(&id, false); - auth_3d_data_set_repeat(&id, false); - auth_3d_data_set_paused(&id, true); - auth_3d_data_set_visibility(&id, false); - auth_3d_data_set_frame_rate(&id, frame_rate_control); + auth_3d_data_read_file_modern(id); + auth_3d_data_set_enable(id, false); + auth_3d_data_set_repeat(id, false); + auth_3d_data_set_paused(id, true); + auth_3d_data_set_visibility(id, false); + auth_3d_data_set_frame_rate(id, frame_rate_control); if (j.field_0) - auth_3d_data_set_src_dst_chara(&id, j.src_chara, j.dst_chara); + auth_3d_data_set_src_dst_chara(id, j.src_chara, j.dst_chara); j.id = id; + +#if BAKE_PV826 + if (pv_id == 826 && effchrpv_auth_3d_mot_ids) + effchrpv_auth_3d_mot_ids->insert({ j.file.hash_murmurhash, id }); +#endif } state = 21; @@ -1328,8 +1325,8 @@ void x_pv_game_chara_effect::ctrl(object_database* obj_db, texture_database* tex if (!j.category.str.size()) continue; - if (auth_3d_data_check_id_not_empty(&j.id) - && !auth_3d_data_check_id_loaded(&j.id)) + if (auth_3d_data_check_id_not_empty(j.id) + && !auth_3d_data_check_id_loaded(j.id)) wait_load |= true; } @@ -1339,8 +1336,14 @@ void x_pv_game_chara_effect::ctrl(object_database* obj_db, texture_database* tex } } +#if BAKE_PV826 +void x_pv_game_chara_effect::load(int32_t pv_id, pvpp* play_param, + FrameRateControl* frame_rate_control, chara_index charas[6], + std::unordered_map* effchrpv_auth_3d_mot_names) { +#else void x_pv_game_chara_effect::load(int32_t pv_id, pvpp* play_param, FrameRateControl* frame_rate_control, chara_index charas[6]) { +#endif if (state) return; @@ -1361,51 +1364,73 @@ void x_pv_game_chara_effect::load(int32_t pv_id, pvpp* play_param, std::string src_chara_str = chara_index_get_auth_3d_name(src_chara); std::string dst_chara_str = chara_index_get_auth_3d_name(dst_chara); +#if BAKE_PV826 + std::string mik_chara_str = chara_index_get_auth_3d_name(CHARA_MIKU); +#endif for (pvpp_chara_effect_auth_3d& j : chara_effect.auth_3d) { + std::string file = j.auth_3d.str; + std::string object_set; +#if BAKE_PV826 + if (pv_id != 826) { +#endif + if (!j.object_set.str.size()) { + size_t pos = file.find("_"); + if (pos != -1) + object_set.assign(file.substr(0, pos)); + else + object_set.assign(file); + } + else + object_set.assign(j.object_set.str); + + if (src_chara != dst_chara) { + size_t pos = object_set.find(dst_chara_str); + if (pos && pos != -1) + object_set.replace(pos, dst_chara_str.size(), src_chara_str); + + if (!j.u00) { + size_t pos = file.find(dst_chara_str); + if (pos != -1) + file.replace(pos, dst_chara_str.size(), src_chara_str); + } + } +#if BAKE_PV826 + } + else { + char buf[0x200]; + sprintf_s(buf, sizeof(buf), "EFFCHRPV%03d", pv_id); + if (j.auth_3d.str.find(buf) == std::string::npos) + continue; + + file.assign(j.auth_3d.str); + file.replace(utf8_length(buf), mik_chara_str.size(), mik_chara_str); + + sprintf_s(buf, sizeof(buf), "EFFCHRPV%03dMIK001", pv_id); + object_set.assign(buf); + } +#endif + + std::string category = "A3D_"; + size_t pos = file.find("_"); + if (pos != -1) + category.append(file.substr(0, pos)); + else + category.append(file); + x_pv_game_chara_effect_auth_3d auth_3d; auth_3d.field_0 = j.u00; auth_3d.src_chara = src_chara; auth_3d.dst_chara = dst_chara; - - std::string file = j.auth_3d.str; - - std::string object_set; - if (!j.object_set.str.size()) { - size_t pos = file.find("_"); - if (pos != -1) - object_set = file.substr(0, pos); - else - object_set = file; - } - else - object_set = j.object_set.str; - - - if (src_chara != dst_chara) { - size_t pos = object_set.find(dst_chara_str); - if (pos && pos != -1) - object_set.replace(pos, dst_chara_str.size(), src_chara_str); - - if (!auth_3d.field_0) { - size_t pos = file.find(dst_chara_str); - if (pos != -1) - file = file.replace(pos, dst_chara_str.size(), src_chara_str); - } - } - - std::string category; - size_t pos = file.find("_"); - if (pos != -1) - category = file.substr(0, pos); - else - category = file; - auth_3d.file = file; - auth_3d.category = "A3D_" + category; + auth_3d.category = category; auth_3d.object_set = object_set; - this->auth_3d[i].push_back(auth_3d); + +#if BAKE_PV826 + if (pv_id == 826 && effchrpv_auth_3d_mot_names) + effchrpv_auth_3d_mot_names->insert({ file, category }); +#endif } } state = 10; @@ -1451,19 +1476,19 @@ void x_pv_game_chara_effect::set_chara_effect(int32_t chara_id, int32_t index, i int32_t& id = auth_3d[index].id; - if (!auth_3d_data_check_id_not_empty(&id)) + if (!auth_3d_data_check_id_not_empty(id)) return; - if (auth_3d_data_get_enable(&id)) { + if (auth_3d_data_get_enable(id)) { float_t req_frame = (float_t)((double_t)(time - auth_3d[index].time) * 0.000000001) * 60.0f; - auth_3d_data_set_req_frame(&id, req_frame); + auth_3d_data_set_req_frame(id, req_frame); } else { - auth_3d_data_set_enable(&id, true); - auth_3d_data_set_paused(&id, false); - auth_3d_data_set_repeat(&id, false); - auth_3d_data_set_req_frame(&id, 0.0f); - auth_3d_data_set_visibility(&id, true); + auth_3d_data_set_enable(id, true); + auth_3d_data_set_paused(id, false); + auth_3d_data_set_repeat(id, false); + auth_3d_data_set_req_frame(id, 0.0f); + auth_3d_data_set_visibility(id, true); auth_3d[index].time = time; } @@ -1484,7 +1509,7 @@ void x_pv_game_chara_effect::set_chara_effect(int32_t chara_id, int32_t index, i max_frame = (float_t)((double_t)(*key - auth_3d[index].time) * 0.000000001) * 60.0f - 1.0f; } - auth_3d_data_set_max_frame(&id, max_frame); + auth_3d_data_set_max_frame(id, max_frame); } void x_pv_game_chara_effect::set_chara_effect_time(int32_t chara_id, int32_t index, int64_t time) { @@ -1492,12 +1517,12 @@ void x_pv_game_chara_effect::set_chara_effect_time(int32_t chara_id, int32_t ind return; for (x_pv_game_chara_effect_auth_3d& i : auth_3d[chara_id]) { - if (!auth_3d_data_check_id_not_empty(&i.id) || !auth_3d_data_get_enable(&i.id)) + if (!auth_3d_data_check_id_not_empty(i.id) || !auth_3d_data_get_enable(i.id)) continue; float_t req_frame = (float_t)((double_t)(time - i.time) * 0.000000001) * 60.0f; - auth_3d_data_set_req_frame(&i.id, req_frame); - auth_3d_data_set_paused(&i.id, 0); + auth_3d_data_set_req_frame(i.id, req_frame); + auth_3d_data_set_paused(i.id, 0); } } @@ -1507,8 +1532,8 @@ void x_pv_game_chara_effect::stop() { for (std::vector& i : auth_3d) for (x_pv_game_chara_effect_auth_3d& j : i) - if (auth_3d_data_check_id_not_empty(&j.id)) - auth_3d_data_set_enable(&j.id, false); + if (auth_3d_data_check_id_not_empty(j.id)) + auth_3d_data_set_enable(j.id, false); } void x_pv_game_chara_effect::stop_chara_effect(int32_t chara_id, int32_t index) { @@ -1516,8 +1541,8 @@ void x_pv_game_chara_effect::stop_chara_effect(int32_t chara_id, int32_t index) return; for (x_pv_game_chara_effect_auth_3d& i : auth_3d[chara_id]) - if (auth_3d_data_check_id_not_empty(&i.id)) - auth_3d_data_set_enable(&i.id, false); + if (auth_3d_data_check_id_not_empty(i.id)) + auth_3d_data_set_enable(i.id, false); } void x_pv_game_chara_effect::unload() { @@ -1725,7 +1750,12 @@ x_pv_game_data::~x_pv_game_data() { } } +#if BAKE_PV826 +void x_pv_game_data::ctrl(float_t curr_time, float_t delta_time, + std::map* effchrpv_auth_3d_mot_ids) { +#else void x_pv_game_data::ctrl(float_t curr_time, float_t delta_time) { +#endif this->curr_time = curr_time; this->delta_time = delta_time; @@ -1798,7 +1828,11 @@ void x_pv_game_data::ctrl(float_t curr_time, float_t delta_time) { camera.ctrl(this->curr_time); effect.ctrl(&obj_db, &tex_db); +#if BAKE_PV826 + chara_effect.ctrl(&obj_db, &tex_db, pv_id, effchrpv_auth_3d_mot_ids); +#else chara_effect.ctrl(&obj_db, &tex_db); +#endif field_1C &= ~0x02; } @@ -1829,14 +1863,23 @@ void x_pv_game_data::ctrl_stage_effect_index() { next_stage_effect_bar = 2 * v14 + 1; } +#if BAKE_PV826 +void x_pv_game_data::load(int32_t pv_id, FrameRateControl* frame_rate_control, chara_index charas[6], + std::unordered_map* effchrpv_auth_3d_mot_names) { +#else void x_pv_game_data::load(int32_t pv_id, FrameRateControl* frame_rate_control, chara_index charas[6]) { +#endif if (state) return; data_struct* x_data = &data_list[DATA_X]; effect.load(pv_id, play_param, frame_rate_control); +#if BAKE_PV826 + chara_effect.load(pv_id, play_param, frame_rate_control, charas, effchrpv_auth_3d_mot_names); +#else chara_effect.load(pv_id, play_param, frame_rate_control, charas); +#endif char buf[0x200]; size_t len = sprintf_s(buf, sizeof(buf), "exp_PV%03d", pv_id); @@ -1849,7 +1892,7 @@ void x_pv_game_data::load(int32_t pv_id, FrameRateControl* frame_rate_control, c void x_pv_game_data::reset() { pv_id = 0; - play_param_file_handler.free_data(); + play_param_file_handler.reset(); if (play_param) { delete play_param; play_param = 0; @@ -1872,10 +1915,7 @@ void x_pv_game_data::reset() { effect.reset(); chara_effect.reset(); dsc_data.reset(); - exp_file.str.clear(); - exp_file.str.shrink_to_fit(); - exp_file.hash_fnv1a64m = hash_fnv1a64m_empty; - exp_file.hash_murmurhash = hash_murmurhash_empty; + exp_file.clear(); //dof = {}; stage = 0; obj_db.object_set.clear(); @@ -1934,10 +1974,7 @@ x_pv_game_stage_effect_glitter::x_pv_game_stage_effect_glitter() : } void x_pv_game_stage_effect_glitter::reset() { - name.str.clear(); - name.str.shrink_to_fit(); - name.hash_fnv1a64m = hash_fnv1a64m_empty; - name.hash_murmurhash = hash_murmurhash_empty; + name.clear(); scene_counter = 0; fade_time = 0.0f; fade_time_left = 0.0f; @@ -2033,7 +2070,7 @@ void x_pv_game_stage_data::load(int32_t stage_id, FrameRateControl* frame_rate_c } void x_pv_game_stage_data::load_objects(object_database* obj_db, texture_database* tex_db) { - if (~flags & 0x02 || file_handler.check_not_ready() || state && state != 2) + if (!(flags & 0x02) || file_handler.check_not_ready() || state && state != 2) return; const void* stg_data = file_handler.get_data(); @@ -2071,7 +2108,7 @@ void x_pv_game_stage_data::load_objects(object_database* obj_db, texture_databas void x_pv_game_stage_data::reset() { flags = 0x04; state = 0; - file_handler.free_data(); + file_handler.reset(); stg_db.stage_data.clear(); stg_db.stage_data.shrink_to_fit(); stg_db.stage_modern.clear(); @@ -2086,14 +2123,14 @@ void x_pv_game_stage_data::reset() { } void x_pv_game_stage_data::set_default_stage() { - if (~flags & 0x02 || state && state != 2) + if (!(flags & 0x02) || state && state != 2) return; set_stage(hash_utf8_murmurhash("STGAETBACK")); } void x_pv_game_stage_data::set_stage(uint32_t hash) { - if (~flags & 0x02 || state && state != 2) + if (!(flags & 0x02) || state && state != 2) return; if (flags & 0x01) { @@ -2123,7 +2160,7 @@ void x_pv_game_stage_data::unload() { flags &= ~0x02; state = 0; - file_handler.free_data(); + file_handler.reset(); frame_rate_control = 0; obj_hash.clear(); obj_hash.shrink_to_fit(); @@ -2270,17 +2307,17 @@ void x_pv_game_stage::ctrl(float_t delta_time) { if (elem == auth_3d_ids.end()) { int32_t id = auth_3d_data_load_hash(stg_eff_auth_3d .name.hash_murmurhash, x_data, &obj_db, &tex_db); - if (!auth_3d_data_check_id_not_empty(&id)) { + if (!auth_3d_data_check_id_not_empty(id)) { eff_auth_3d.id = -1; continue; } - auth_3d_data_read_file_modern(&id); - auth_3d_data_set_enable(&id, false); - auth_3d_data_set_repeat(&id, true); - auth_3d_data_set_paused(&id, false); - auth_3d_data_set_visibility(&id, false); - auth_3d_data_set_frame_rate(&id, &bpm_frame_rate_control); + auth_3d_data_read_file_modern(id); + auth_3d_data_set_enable(id, false); + auth_3d_data_set_repeat(id, true); + auth_3d_data_set_paused(id, false); + auth_3d_data_set_visibility(id, false); + auth_3d_data_set_frame_rate(id, &bpm_frame_rate_control); eff_auth_3d.id = id; auth_3d_ids.insert({ stg_eff_auth_3d.name.hash_murmurhash, id }); @@ -2322,8 +2359,8 @@ void x_pv_game_stage::ctrl(float_t delta_time) { for (int32_t i = 0; i < X_PV_GAME_STAGE_EFFECT_COUNT; i++) { x_pv_game_stage_effect& eff = effect[i]; for (x_pv_game_stage_effect_auth_3d& j : eff.auth_3d) - if (auth_3d_data_check_id_not_empty(&j.id) - && !auth_3d_data_check_id_loaded(&j.id)) + if (auth_3d_data_check_id_not_empty(j.id) + && !auth_3d_data_check_id_loaded(j.id)) wait_load |= true; } @@ -2331,8 +2368,8 @@ void x_pv_game_stage::ctrl(float_t delta_time) { for (int32_t j = 0; j < X_PV_GAME_STAGE_EFFECT_COUNT; j++) { x_pv_game_stage_change_effect& chg_eff = change_effect[i][j]; for (x_pv_game_stage_effect_auth_3d& k : chg_eff.auth_3d) - if (auth_3d_data_check_id_not_empty(&k.id) - && !auth_3d_data_check_id_loaded(&k.id)) + if (auth_3d_data_check_id_not_empty(k.id) + && !auth_3d_data_check_id_loaded(k.id)) wait_load |= true; } @@ -2410,7 +2447,7 @@ void x_pv_game_stage::ctrl_inner() { std::vector& auth_3d = eff.auth_3d; for (x_pv_game_stage_effect_auth_3d& i : auth_3d) { int32_t& id = i.id; - auth_3d_data_set_repeat(&id, false); + auth_3d_data_set_repeat(id, false); } } } break; @@ -2455,7 +2492,7 @@ void x_pv_game_stage::ctrl_inner() { return; for (int32_t i = 8; i <= 9; i++) { - if (~flags & (1 << i)) + if (!(flags & (1 << i))) continue; int32_t stage_effect; @@ -2470,7 +2507,7 @@ void x_pv_game_stage::ctrl_inner() { bool stop = false; if (auth_3d.size()) - stop = auth_3d_data_get_ended(&auth_3d[eff.main_auth_3d_index].id); + stop = auth_3d_data_get_ended(auth_3d[eff.main_auth_3d_index].id); if (!stop) { for (x_pv_game_stage_effect_glitter& j : glitter) @@ -2549,17 +2586,17 @@ void x_pv_game_stage::load_change_effect(int32_t curr_stage_effect, int32_t next if (elem == auth_3d_ids.end()) { int32_t id = auth_3d_data_load_hash(stg_chg_eff_auth_3d .name.hash_murmurhash, x_data, &obj_db, &tex_db); - if (!auth_3d_data_check_id_not_empty(&id)) { + if (!auth_3d_data_check_id_not_empty(id)) { chg_eff_auth_3d.id = -1; continue; } - auth_3d_data_read_file_modern(&id); - auth_3d_data_set_enable(&id, false); - auth_3d_data_set_repeat(&id, false); - auth_3d_data_set_paused(&id, false); - auth_3d_data_set_visibility(&id, false); - auth_3d_data_set_frame_rate(&id, &bpm_frame_rate_control); + auth_3d_data_read_file_modern(id); + auth_3d_data_set_enable(id, false); + auth_3d_data_set_repeat(id, false); + auth_3d_data_set_paused(id, false); + auth_3d_data_set_visibility(id, false); + auth_3d_data_set_frame_rate(id, &bpm_frame_rate_control); chg_eff_auth_3d.id = id; auth_3d_ids.insert({ stg_chg_eff_auth_3d.name.hash_murmurhash, id }); @@ -2586,7 +2623,7 @@ void x_pv_game_stage::reset() { stage_id = 0; field_8 = 0; state = 0; - stage_resource_file_handler.free_data(); + stage_resource_file_handler.reset(); if (stage_resource) { delete stage_resource; stage_resource = 0; @@ -2618,7 +2655,7 @@ void x_pv_game_stage::reset_stage_effect() { stop_stage_effect(true); for (int32_t i = 8; i <= 9; i++) { - if (~flags & (1 << i)) + if (!(flags & (1 << i))) continue; stop_stage_effect_auth_3d(i); @@ -2673,14 +2710,14 @@ void x_pv_game_stage::set_change_effect_frame_part_2(float_t frame) { for (x_pv_game_stage_effect_auth_3d& i : chg_eff.auth_3d) { int32_t& id = i.id; - auth_3d_data_set_camera_root_update(&id, false); - auth_3d_data_set_enable(&id, true); - auth_3d_data_set_repeat(&id, i.repeat); - auth_3d_data_set_req_frame(&id, frame); - auth_3d_data_set_max_frame(&id, auth_3d_data_get_last_frame(&id) - 1.0f); - auth_3d_data_set_paused(&id, false); - auth_3d_data_set_visibility(&id, !!(flags & 0x01)); - auth_3d_data_set_frame_rate(&id, &bpm_frame_rate_control); + auth_3d_data_set_camera_root_update(id, false); + auth_3d_data_set_enable(id, true); + auth_3d_data_set_repeat(id, i.repeat); + auth_3d_data_set_req_frame(id, frame); + auth_3d_data_set_max_frame(id, auth_3d_data_get_last_frame(id) - 1.0f); + auth_3d_data_set_paused(id, false); + auth_3d_data_set_visibility(id, !!(flags & 0x01)); + auth_3d_data_set_frame_rate(id, &bpm_frame_rate_control); } for (x_pv_game_stage_effect_glitter& i : chg_eff.glitter) { @@ -2715,7 +2752,7 @@ void x_pv_game_stage::set_stage_effect(int32_t stage_effect) { if (curr_stage_effect == stage_effect && !next_stage_effect || next_stage_effect) return; else if (curr_stage_effect) { - if (~flags & 0x10) { + if (!(flags & 0x10)) { next_stage_effect = stage_effect; stage_effect_transition_state = 0; return; @@ -2743,21 +2780,21 @@ void x_pv_game_stage::set_stage_effect_auth_3d_frame(int32_t stage_effect, float std::vector& auth_3d = effect[stage_effect - 1ULL].auth_3d; for (x_pv_game_stage_effect_auth_3d& i : auth_3d) { int32_t& id = i.id; - auth_3d_data_set_camera_root_update(&id, false); - auth_3d_data_set_enable(&id, true); - auth_3d_data_set_repeat(&id, true); - if (i.repeat && auth_3d_data_get_last_frame(&id) <= frame) { - int32_t frame_offset = (int32_t)auth_3d_data_get_frame_offset(&id); - int32_t last_frame = (int32_t)auth_3d_data_get_last_frame(&id); + auth_3d_data_set_camera_root_update(id, false); + auth_3d_data_set_enable(id, true); + auth_3d_data_set_repeat(id, true); + if (i.repeat && auth_3d_data_get_last_frame(id) <= frame) { + int32_t frame_offset = (int32_t)auth_3d_data_get_frame_offset(id); + int32_t last_frame = (int32_t)auth_3d_data_get_last_frame(id); int32_t _frame = frame_offset + (int32_t)(frame - (float_t)frame_offset) % last_frame; frame = (float_t)_frame + (frame - (float_t)(int32_t)frame); } - auth_3d_data_set_req_frame(&id, frame); - auth_3d_data_set_max_frame(&id, -1.0f); - auth_3d_data_set_paused(&id, false); - auth_3d_data_set_visibility(&id, true); - auth_3d_data_set_frame_rate(&id, &bpm_frame_rate_control); + auth_3d_data_set_req_frame(id, frame); + auth_3d_data_set_max_frame(id, -1.0f); + auth_3d_data_set_paused(id, false); + auth_3d_data_set_visibility(id, true); + auth_3d_data_set_frame_rate(id, &bpm_frame_rate_control); } } @@ -2816,8 +2853,8 @@ void x_pv_game_stage::stop_stage_change_effect() { for (x_pv_game_stage_effect_auth_3d& i : chg_eff.auth_3d) { int32_t& id = i.id; - auth_3d_data_set_visibility(&id, false); - auth_3d_data_set_enable(&id, false); + auth_3d_data_set_visibility(id, false); + auth_3d_data_set_enable(id, false); } for (x_pv_game_stage_effect_glitter& i : chg_eff.glitter) @@ -2861,8 +2898,8 @@ void x_pv_game_stage::stop_stage_effect_auth_3d(int32_t stage_effect) { std::vector& auth_3d = effect[stage_effect - 1ULL].auth_3d; for (x_pv_game_stage_effect_auth_3d& i : auth_3d) { int32_t& id = i.id; - auth_3d_data_set_visibility(&id, false); - auth_3d_data_set_enable(&id, false); + auth_3d_data_set_visibility(id, false); + auth_3d_data_set_enable(id, false); } } @@ -3037,7 +3074,12 @@ bool x_pv_game::Ctrl() { pv_data.play_param = new pvpp; pv_data.play_param->read(pvpp_data, pvpp_size); +#if BAKE_PV826 + pv_data.load(pv_id, &field_71994, charas, + pv_id == 826 ? &effchrpv_auth_3d_mot_names : 0); +#else pv_data.load(pv_id, &field_71994, charas); +#endif int32_t chara_index = 0; for (pvpp_chara& i : pv_data.play_param->chara) { @@ -3053,6 +3095,50 @@ bool x_pv_game::Ctrl() { if (++chara_index >= ROB_CHARA_COUNT) break; } + +#if BAKE_PV826 + if (pv_id == 826) { + for (int32_t i = (int32_t)pv_data.play_param->chara.size(); i < ROB_CHARA_COUNT; i++) { + rob_chara_pv_data pv_data; + pv_data.chara_size_index = chara_init_data_get_chara_size_index(charas[i]); + int32_t chara_id = rob_chara_array_init_chara_index(charas[i], &pv_data, modules[i], true); + if (chara_id >= 0 && chara_id < ROB_CHARA_COUNT) + rob_chara_ids[i] = chara_id; + effchrpv_rob_mot_ids.push_back(chara_id); + } + + char buf[0x100]; + pv_data.play_param->chara.resize(6); + pvpp_chara* chara = pv_data.play_param->chara.data(); + for (int32_t i = 1; i < 6; i++) { + switch (i) { + case 1: + chara[i].chara_effect.base_chara = PVPP_CHARA_RIN; + chara[i].chara_effect_init = true; + break; + case 2: + chara[i].chara_effect.base_chara = PVPP_CHARA_LEN; + chara[i].chara_effect_init = true; + break; + case 3: + chara[i].chara_effect.base_chara = PVPP_CHARA_LUKA; + chara[i].chara_effect_init = true; + break; + case 4: + chara[i].chara_effect.base_chara = PVPP_CHARA_MEIKO; + chara[i].chara_effect_init = true; + break; + case 5: + chara[i].chara_effect.base_chara = PVPP_CHARA_KAITO; + chara[i].chara_effect_init = true; + break; + } + sprintf_s(buf, sizeof(buf), "PV%03d_%s_P%d_00", 826, "OST", i + 1); + + chara[i].motion.push_back(buf); + } + } +#endif } state_old = 3; @@ -3098,14 +3184,14 @@ bool x_pv_game::Ctrl() { if (hash_string_murmurhash(i.name) == light_auth_3d_hash) { light_auth_3d_id = auth_3d_data_load_uid( (int32_t)(&i - auth_3d_db->uid.data()), auth_3d_db); - if (!auth_3d_data_check_id_not_empty(&light_auth_3d_id)) { + if (!auth_3d_data_check_id_not_empty(light_auth_3d_id)) { light_auth_3d_id = -1; break; } - auth_3d_data_read_file(&light_auth_3d_id, auth_3d_db); - auth_3d_data_set_enable(&light_auth_3d_id, false); - auth_3d_data_set_visibility(&light_auth_3d_id, false); + auth_3d_data_read_file(light_auth_3d_id, auth_3d_db); + auth_3d_data_set_enable(light_auth_3d_id, false); + auth_3d_data_set_visibility(light_auth_3d_id, false); break; } } @@ -3115,8 +3201,8 @@ bool x_pv_game::Ctrl() { case 8: { bool wait_load = false; - if (auth_3d_data_check_id_not_empty(&light_auth_3d_id) - && !auth_3d_data_check_id_loaded(&light_auth_3d_id)) + if (auth_3d_data_check_id_not_empty(light_auth_3d_id) + && !auth_3d_data_check_id_loaded(light_auth_3d_id)) wait_load |= true; if (wait_load) @@ -3160,13 +3246,13 @@ bool x_pv_game::Ctrl() { dsc_easy.type = DSC_X; x_data->load_file(&dsc_easy, path_buf, file_buf, dsc::load_file); - /*if (pv_id == 826) { + if (pv_id == 826) { dsc dsc_hand_keys[5]; char file_buf[0x200]; for (int32_t i = 2; i <= 6; i++) { - stream s; - sprintf_s(file_buf, sizeof(file_buf), "pv_826_hand_%d.txt", i); + file_stream s; + sprintf_s(file_buf, sizeof(file_buf), "pv826\\pv_826_hand_%d.txt", i); s.open(file_buf, "rb"); size_t length = s.length; uint8_t* data = force_malloc_s(uint8_t, length); @@ -3176,17 +3262,13 @@ bool x_pv_game::Ctrl() { dsc& d = dsc_hand_keys[i - 2]; d.parse_text(data, length, DSC_X); d.signature = 0x13120420; - free_def(data); + free(data); { int32_t hand_l_time = -1; int32_t hand_l_id = -1; int32_t hand_l_duration = -1; ::dsc_data* hand_l_data = 0; - int32_t hand_r_time = -1; - int32_t hand_r_id = -1; - int32_t hand_r_duration = -1; - ::dsc_data* hand_r_data = 0; int32_t time = -1; for (::dsc_data& j : d.data) { if (j.func == DSC_X_END) @@ -3207,6 +3289,27 @@ bool x_pv_game::Ctrl() { hand_l_duration = (int32_t)data[3] * 100; hand_l_data = &j; } + } break; + } + } + } + + { + int32_t hand_r_time = -1; + int32_t hand_r_id = -1; + int32_t hand_r_duration = -1; + ::dsc_data* hand_r_data = 0; + int32_t time = -1; + for (::dsc_data& j : d.data) { + if (j.func == DSC_X_END) + break; + + uint32_t* data = d.get_func_data(&j); + switch (j.func) { + case DSC_X_TIME: + time = (int32_t)data[0]; + break; + case DSC_X_HAND_ANIM: { if (data[1] == 1) { if (hand_r_time > -1 && hand_r_duration > time - hand_r_time) data[3] = (time - hand_r_time) / 100; @@ -3226,8 +3329,7 @@ bool x_pv_game::Ctrl() { &dsc_hand_keys[0], &dsc_hand_keys[1], &dsc_hand_keys[2], &dsc_hand_keys[3], dsc_hand_keys[4]); } else - dsc_data.dsc.merge(4, &dsc_mouth, &dsc_scene, &dsc_system, &dsc_easy);*/ - dsc_data.dsc.merge(4, &dsc_mouth, &dsc_scene, &dsc_system, &dsc_easy); + dsc_data.dsc.merge(4, &dsc_mouth, &dsc_scene, &dsc_system, &dsc_easy); struct miku_state { bool disp; @@ -3248,9 +3350,9 @@ bool x_pv_game::Ctrl() { x_pv_bar_beat_data* bar_beat_data = 0; int32_t beat_counter = 0; - /*std::vector> miku_disp; + std::vector> miku_disp; std::vector> set_motion; - std::vector> set_playdata;*/ + std::vector> set_playdata; int32_t time = -1; int32_t frame = -1; @@ -3272,21 +3374,21 @@ bool x_pv_game::Ctrl() { state[chara_id].disp = (int32_t)data[1] == 1; if (state[chara_id].disp) state[chara_id].disp_time = time; - //miku_disp.push_back({ time, i.data_offset }); + miku_disp.push_back({ time, i.data_offset }); } break; case DSC_X_SET_MOTION: { int32_t chara_id = (int32_t)data[0]; state[chara_id].set_motion_time = time; state[chara_id].set_motion_data_offset = i.data_offset; - //set_motion.push_back({ time, i.data_offset }); + set_motion.push_back({ time, i.data_offset }); + } break; + case DSC_X_SET_PLAYDATA: { + set_playdata.push_back({ time, i.data_offset }); } break; - /*case DSC_X_SET_PLAYDATA: { - set_playdata.push_back({ time, i.data_offset }); - } break;*/ } } - if (state_vec.size()/* || miku_disp.size() || set_motion.size() || set_playdata.size()*/) { + if (state_vec.size() || miku_disp.size() || set_motion.size() || set_playdata.size()) { int32_t time = -1; for (miku_state& i : state_vec) { if (i.disp_time != time) { @@ -3302,19 +3404,19 @@ bool x_pv_game::Ctrl() { memcpy(new_data, data, sizeof(uint32_t) * dsc_x_get_func_length(DSC_X_SET_MOTION)); } - /*time = -1; + time = -1; for (std::pair& i : miku_disp) { if (i.first != time) { - uint32_t* data = dsc_m.add_func(dsc_x_get_func_name(DSC_X_TIME), + uint32_t* data = dsc_data.dsc.add_func(dsc_x_get_func_name(DSC_X_TIME), DSC_X_TIME, dsc_x_get_func_length(DSC_X_TIME)); data[0] = i.first; time = i.first; } for (int32_t j = 1; j < 6; j++) { - uint32_t* new_data = dsc_m.add_func(dsc_x_get_func_name(DSC_X_MIKU_DISP), + uint32_t* new_data = dsc_data.dsc.add_func(dsc_x_get_func_name(DSC_X_MIKU_DISP), DSC_X_MIKU_DISP, dsc_x_get_func_length(DSC_X_MIKU_DISP)); - uint32_t* data = dsc_m.data_buffer.data() + i.second; + uint32_t* data = dsc_data.dsc.data_buffer.data() + i.second; memcpy(new_data, data, sizeof(uint32_t) * dsc_x_get_func_length(DSC_X_MIKU_DISP)); new_data[0] = j; } @@ -3323,16 +3425,16 @@ bool x_pv_game::Ctrl() { time = -1; for (std::pair& i : set_motion) { if (i.first != time) { - uint32_t* data = dsc_m.add_func(dsc_x_get_func_name(DSC_X_TIME), + uint32_t* data = dsc_data.dsc.add_func(dsc_x_get_func_name(DSC_X_TIME), DSC_X_TIME, dsc_x_get_func_length(DSC_X_TIME)); data[0] = i.first; time = i.first; } for (int32_t j = 1; j < 6; j++) { - uint32_t* new_data = dsc_m.add_func(dsc_x_get_func_name(DSC_X_SET_MOTION), + uint32_t* new_data = dsc_data.dsc.add_func(dsc_x_get_func_name(DSC_X_SET_MOTION), DSC_X_SET_MOTION, dsc_x_get_func_length(DSC_X_SET_MOTION)); - uint32_t* data = dsc_m.data_buffer.data() + i.second; + uint32_t* data = dsc_data.dsc.data_buffer.data() + i.second; memcpy(new_data, data, sizeof(uint32_t) * dsc_x_get_func_length(DSC_X_SET_MOTION)); new_data[0] = j; } @@ -3341,20 +3443,20 @@ bool x_pv_game::Ctrl() { time = -1; for (std::pair& i : set_playdata) { if (i.first != time) { - uint32_t* data = dsc_m.add_func(dsc_x_get_func_name(DSC_X_TIME), + uint32_t* data = dsc_data.dsc.add_func(dsc_x_get_func_name(DSC_X_TIME), DSC_X_TIME, dsc_x_get_func_length(DSC_X_TIME)); data[0] = i.first; time = i.first; } for (int32_t j = 1; j < 6; j++) { - uint32_t* new_data = dsc_m.add_func(dsc_x_get_func_name(DSC_X_SET_PLAYDATA), + uint32_t* new_data = dsc_data.dsc.add_func(dsc_x_get_func_name(DSC_X_SET_PLAYDATA), DSC_X_SET_PLAYDATA, dsc_x_get_func_length(DSC_X_SET_PLAYDATA)); - uint32_t* data = dsc_m.data_buffer.data() + i.second; + uint32_t* data = dsc_data.dsc.data_buffer.data() + i.second; memcpy(new_data, data, sizeof(uint32_t) * dsc_x_get_func_length(DSC_X_SET_PLAYDATA)); new_data[0] = j; } - }*/ + } dsc_data.dsc.rebuild(); } @@ -3448,8 +3550,8 @@ bool x_pv_game::Ctrl() { for (int32_t i = 0; i < X_PV_GAME_STAGE_EFFECT_COUNT; i++) { x_pv_game_stage_effect& eff = stage_data.effect[i]; for (x_pv_game_stage_effect_auth_3d& j : eff.auth_3d) { - if (!auth_3d_data_check_id_not_empty(&j.id) - || !auth_3d_data_check_id_loaded(&j.id)) + if (!auth_3d_data_check_id_not_empty(j.id) + || !auth_3d_data_check_id_loaded(j.id)) continue; auth_3d* auth = auth_3d_data_get_auth_3d(j.id); @@ -3469,8 +3571,8 @@ bool x_pv_game::Ctrl() { for (int32_t j = 0; j < X_PV_GAME_STAGE_EFFECT_COUNT; j++) { x_pv_game_stage_change_effect& chg_eff = stage_data.change_effect[i][j]; for (x_pv_game_stage_effect_auth_3d& k : chg_eff.auth_3d) { - if (!auth_3d_data_check_id_not_empty(&k.id) - || !auth_3d_data_check_id_loaded(&k.id)) + if (!auth_3d_data_check_id_not_empty(k.id) + || !auth_3d_data_check_id_loaded(k.id)) continue; auth_3d* auth = auth_3d_data_get_auth_3d(k.id); @@ -3508,12 +3610,56 @@ bool x_pv_game::Ctrl() { && x_pv_game_dsc_process(this, this->time)) pv_data[pv_index].dsc_data.dsc_data_ptr++; - auth_3d_data_set_enable(&light_auth_3d_id, true); - auth_3d_data_set_camera_root_update(&light_auth_3d_id, false); - auth_3d_data_set_paused(&light_auth_3d_id, false); - auth_3d_data_set_repeat(&light_auth_3d_id, false); - auth_3d_data_set_visibility(&light_auth_3d_id, true); - auth_3d_data_set_req_frame(&light_auth_3d_id, 0.0f); + auth_3d_data_set_enable(light_auth_3d_id, true); + auth_3d_data_set_camera_root_update(light_auth_3d_id, false); + auth_3d_data_set_paused(light_auth_3d_id, false); + auth_3d_data_set_repeat(light_auth_3d_id, false); + auth_3d_data_set_visibility(light_auth_3d_id, true); + auth_3d_data_set_req_frame(light_auth_3d_id, 0.0f); + +#if BAKE_PV826 + if (pv_id == 826) { + data_struct* aft_data = &data_list[DATA_AFT]; + bone_database* aft_bone_data = &aft_data->data_ft.bone_data; + motion_database* aft_mot_db = &aft_data->data_ft.mot_db; + + for (int32_t& i : effchrpv_rob_mot_ids) { + char buf[0x100]; + sprintf_s(buf, sizeof(buf), "PV826_OST_P%d_00", i + 1); + int32_t motion_id = aft_mot_db->get_motion_id(buf); + rob_chara* rob_chr = rob_chara_array_get(rob_chara_ids[i]); + rob_chr->set_motion_id(motion_id, 0.0f, + 0.0f, false, false, MOTION_BLEND_CROSS, aft_bone_data, aft_mot_db); + rob_chr->set_motion_reset_data(motion_id, 0.0f); + rob_chr->set_motion_skin_param(motion_id, 0.0f); + + sprintf_s(buf, sizeof(buf), "A3D_EFFCHRPV%03dMIK%03d", pv_id, i); + uint32_t hash = hash_utf8_murmurhash(buf); + for (auto j : effchrpv_auth_3d_mot_names) + if (j.second.hash_murmurhash == hash) { + uint32_t hash = hash_string_murmurhash(j.first); + effchrpv_auth_3d_rob_mot_ids.insert({ i, { effchrpv_auth_3d_mot_ids[hash] } }); + break; + } + } + + for (auto& i : effchrpv_auth_3d_rob_mot_ids) { + x_pv_game_a3da_to_mot& a2m = i.second; + auth_3d* auth = auth_3d_data_get_auth_3d(a2m.auth_3d_id); + a2m.get_bone_indices(&auth->object_hrc[0]); + } + + for (auto& i : effchrpv_auth_3d_mot_ids) { + int32_t& id = i.second; + auth_3d_data_set_repeat(id, false); + auth_3d_data_set_camera_root_update(id, false); + auth_3d_data_set_enable(id, true); + auth_3d_data_set_paused(id, false); + auth_3d_data_set_visibility(id, false); + auth_3d_data_set_req_frame(id, 0.0f); + } + } +#endif #if BAKE_VIDEO char buf[0x400]; @@ -3541,7 +3687,10 @@ bool x_pv_game::Ctrl() { sound_work_stream_set_pause(0, pause); - //x_pv_game_map_auth_3d_to_mot(this, delta_frame != 0.0f && frame > 0); +#if BAKE_PV826 + x_pv_game_map_auth_3d_to_mot(this, delta_frame != 0.0f && frame > 0); +#endif + #if BAKE_PNG || BAKE_VIDEO img_write = true; #endif @@ -3730,7 +3879,8 @@ void x_pv_game::Basic() { extern float_t frame_speed; frame_speed = pause ? 0.0f : 1.0f; - /*if (get_delta_frame() != 0.0f && frame > 0) +#if BAKE_PV826 + if (get_delta_frame() != 0.0f && frame > 0) for (auto& i : effchrpv_auth_3d_rob_mot_ids) { rob_chara* rob_chr = rob_chara_array_get(rob_chara_ids[i.first]); x_pv_game_a3da_to_mot& a2m = i.second; @@ -3767,7 +3917,8 @@ void x_pv_game::Basic() { elem->second.z.push_back(data->rotation.z); } } - }*/ + } +#endif #if BAKE_VIDEO if (img_write && frame_prev != frame) { @@ -3917,7 +4068,7 @@ void x_pv_game::Window() { ImGui::TableNextColumn(); w = ImGui::GetContentRegionAvailWidth(); char buf[0x200]; - sprintf_s(buf, sizeof(buf), "%d", frame); + sprintf_s(buf, sizeof(buf), "%d/%d", frame, (int32_t)(time / 10000)); ImGui::PushStyleColor(ImGuiCol_Button, { 0.0f, 0.0f, 0.0f, 0.0f }); ImGui::PushStyleColor(ImGuiCol_ButtonActive, { 0.0f, 0.0f, 0.0f, 0.0f }); ImGui::PushStyleColor(ImGuiCol_ButtonHovered, { 0.0f, 0.0f, 0.0f, 0.0f }); @@ -3999,6 +4150,7 @@ void x_pv_game::Load(int32_t pv_id, int32_t stage_id, ::chara_index charas[6], i //sound_work_play_se(1, "load01_2", 1.0f); } +#if BAKE_PV826 mot_key_set_type mot_fit_keys_into_curve(std::vector& values_src, std::vector& frames, std::vector& values) { std::vector value; @@ -4070,7 +4222,7 @@ mot_key_set_type mot_fit_keys_into_curve(std::vector& values_src, } } -/*static void fix_rotation(std::vector& vec) { +static void fix_rotation(std::vector& vec) { if (vec.size() < 2) return; @@ -4301,20 +4453,22 @@ bool mot_write_motion(void* data, const char* path, const char* file, uint32_t h farc_file* ff = &f.files.back(); mot_set->pack_file(&ff->data, &ff->size); - std::string mot_farc = "mot_" + set_info->name; + std::string mot_farc = "pv826\\mot_" + set_info->name; f.write(mot_farc.c_str(), FARC_COMPRESS_FArC, false); } delete mot_set; return true; -}*/ +} +#endif bool x_pv_game::Unload() { pv_osage_manager_array_set_not_reset_true(); if (pv_osage_manager_array_get_disp()) return false; - /*if (pv_data[pv_index].pv_id == 826) { +#if BAKE_PV826 + if (pv_data[pv_index].pv_id == 826) { for (auto& i : effchrpv_auth_3d_rob_mot_ids) { rob_chara* rob_chr = rob_chara_array_get(rob_chara_ids[i.first]); x_pv_game_a3da_to_mot& a2m = i.second; @@ -4358,7 +4512,8 @@ bool x_pv_game::Unload() { std::string farc_file = "mot_" + set_info->name + ".farc"; aft_data->load_file(this, "rom/rob/", farc_file.c_str(), mot_write_motion); } - }*/ + } +#endif data_struct* aft_data = &data_list[DATA_AFT]; motion_database* aft_mot_db = &aft_data->data_ft.mot_db; @@ -4432,8 +4587,14 @@ bool x_pv_game::Unload() { } void x_pv_game::ctrl(float_t curr_time, float_t delta_time) { +#if BAKE_PV826 + for (int32_t i = 0; i < pv_count; i++) + pv_data[i].ctrl(curr_time, delta_time, + pv_data[i].pv_id == 826 ? &effchrpv_auth_3d_mot_ids : 0); +#else for (int32_t i = 0; i < pv_count; i++) pv_data[i].ctrl(curr_time, delta_time); +#endif switch (state) { case 10: @@ -4536,6 +4697,22 @@ XPVGameSelector::XPVGameSelector() : charas(), modules(), start(), exit() { for (int32_t& i : modules) i = 0; + +#if BAKE_PV826 + charas[0] = CHARA_MIKU; + charas[1] = CHARA_RIN; + charas[2] = CHARA_LEN; + charas[3] = CHARA_LUKA; + charas[4] = CHARA_KAITO; + charas[5] = CHARA_MEIKO; + + modules[0] = 168; + modules[1] = 46; + modules[2] = 39; + modules[3] = 41; + modules[4] = 40; + modules[5] = 31; +#endif } XPVGameSelector::~XPVGameSelector() { @@ -4802,7 +4979,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) - auth_3d_data_set_draw_task_flags_alpha(&j.id, draw_task_flags, alpha); + auth_3d_data_set_draw_task_flags_alpha(j.id, draw_task_flags, alpha); for (x_pv_game_song_effect_glitter& j : i.glitter) Glitter::glt_particle_manager->SetSceneEffectExtColor(j.scene_counter, @@ -5943,7 +6120,7 @@ static bool x_pv_game_dsc_process(x_pv_game* a1, int64_t curr_time) { int32_t index = (int32_t)data[1]; int32_t unk2 = (int32_t)data[2]; - if (unk2 && (~a1->field_1C & 0x10)) + if (unk2 && !(a1->field_1C & 0x10)) break; if (enable) { @@ -6129,7 +6306,8 @@ static bool x_pv_game_dsc_process(x_pv_game* a1, int64_t curr_time) { return true; } -/*static void set_bone_key_set_data(bone_data* bone_data, +#if BAKE_PV826 +static void set_bone_key_set_data(bone_data* bone_data, std::map& bone_keys, std::map& second_bone_keys, bool add_keys, motion_bone_index motion_bone_index, mot_key_set* key_set, vec3* data, int32_t count = 1) { @@ -6392,7 +6570,8 @@ static void x_pv_game_map_auth_3d_to_mot(x_pv_game* xpvgm, bool add_keys) { auth->frame_changed = auth_frame_changed; auth->paused = auth_paused; } -}*/ +} +#endif static void x_pv_game_reset_field(x_pv_game* xpvgm) { task_stage_modern_info v14; @@ -6999,7 +7178,7 @@ static void x_pv_game_split_auth_3d_hrc_material_list(x_pv_game* xpvgm, j.children_object_hrc.clear(); j.children_object_hrc.shrink_to_fit(); } - + for (auth_3d_object_hrc& j : auth->object_hrc) { j.children_object.clear(); j.children_object.shrink_to_fit(); diff --git a/src/ReDIVA/x_pv_game.hpp b/src/ReDIVA/x_pv_game.hpp index 990eefa7..13cfe67d 100644 --- a/src/ReDIVA/x_pv_game.hpp +++ b/src/ReDIVA/x_pv_game.hpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include "../CRE/Glitter/glitter.hpp" @@ -26,6 +27,7 @@ #define BAKE_PNG 0 #define BAKE_VIDEO 0 +#define BAKE_PV826 0 struct x_pv_bar_beat_data { int32_t bar; @@ -148,7 +150,8 @@ struct x_pv_play_data { void reset(); }; -/*struct x_pv_game_a3da_to_mot_keys { +#if BAKE_PV826 +struct x_pv_game_a3da_to_mot_keys { std::vector x; std::vector y; std::vector z; @@ -216,7 +219,8 @@ struct x_pv_game_a3da_to_mot { ~x_pv_game_a3da_to_mot(); void get_bone_indices(auth_3d_object_hrc* oh); -};*/ +}; +#endif struct x_pv_game_song_effect_auth_3d { int32_t id; @@ -322,8 +326,15 @@ struct x_pv_game_chara_effect { x_pv_game_chara_effect(); ~x_pv_game_chara_effect(); +#if BAKE_PV826 + void ctrl(object_database* obj_db, texture_database* tex_db, + int32_t pv_id = -1, std::map* effchrpv_auth_3d_mot_ids = 0); + void load(int32_t pv_id, pvpp* play_param, FrameRateControl* frame_rate_control, chara_index charas[6], + std::unordered_map* effchrpv_auth_3d_mot_names = 0); +#else void ctrl(object_database* obj_db, texture_database* tex_db); void load(int32_t pv_id, pvpp* play_param, FrameRateControl* frame_rate_control, chara_index charas[6]); +#endif void load_data(); void reset(); void set_chara_effect(int32_t chara_id, int32_t index, int64_t time); @@ -385,9 +396,19 @@ struct x_pv_game_data { x_pv_game_data(); ~x_pv_game_data(); +#if BAKE_PV826 + void ctrl(float_t curr_time, float_t delta_time, + std::map* effchrpv_auth_3d_mot_ids = 0); +#else void ctrl(float_t curr_time, float_t delta_time); +#endif void ctrl_stage_effect_index(); +#if BAKE_PV826 + void load(int32_t pv_id, FrameRateControl* frame_rate_control, chara_index charas[6], + std::unordered_map* effchrpv_auth_3d_mot_names = 0); +#else void load(int32_t pv_id, FrameRateControl* frame_rate_control, chara_index charas[6]); +#endif void reset(); void stop(); void unload(); @@ -536,12 +557,18 @@ public: std::string light_category; - //std::unordered_set effchrpv_auth_3d_mot_names; +#if BAKE_PV826 + std::unordered_map effchrpv_auth_3d_mot_names; +#endif int32_t light_auth_3d_id; - //std::map effchrpv_auth_3d_ids; - //std::map effchrpv_auth_3d_hashes; +#if BAKE_PV826 + std::map effchrpv_auth_3d_mot_ids; + + std::vector effchrpv_rob_mot_ids; + std::map effchrpv_auth_3d_rob_mot_ids; +#endif std::vector set_motion[ROB_CHARA_COUNT];