From 935d7ffeb6c066ae1c197385fd02ddf56fc46f92 Mon Sep 17 00:00:00 2001 From: korenkonder Date: Wed, 6 Jul 2022 14:13:11 +0300 Subject: [PATCH] Temp commit --- extern/lib/libdeflatestatic.lib | Bin 73752 -> 77554 bytes extern/src/libdeflate.h | 6 +- src/CLOUD/classes/data_test/glitter_test.cpp | 4 +- src/CLOUD/classes/data_view/draw_task.cpp | 8 +- src/CLOUD/classes/glitter_editor.cpp | 49 +- .../classes/graphics/render_settings.cpp | 11 +- src/CLOUD/input.cpp | 82 +- src/CLOUD/main.cpp | 9 +- src/CLOUD/pv_game.cpp | 111 +- src/CLOUD/pv_game.hpp | 9 +- src/CLOUD/render.cpp | 85 +- src/CLOUD/render.hpp | 24 +- src/CLOUD/x_pv_game.cpp | 809 ++++++---- src/CLOUD/x_pv_game.hpp | 58 +- src/CRE/Glitter/curve.cpp | 2 +- src/CRE/Glitter/effect_group.cpp | 2 +- src/CRE/Glitter/effect_inst.cpp | 189 ++- src/CRE/Glitter/emitter.cpp | 31 +- src/CRE/Glitter/emitter_inst.cpp | 196 +-- src/CRE/Glitter/file_reader.cpp | 7 +- src/CRE/Glitter/glitter.cpp | 36 - src/CRE/Glitter/glitter.hpp | 100 +- src/CRE/Glitter/particle.cpp | 2 +- src/CRE/Glitter/particle_inst.cpp | 28 +- src/CRE/Glitter/particle_manager.cpp | 31 +- src/CRE/Glitter/random.cpp | 12 +- src/CRE/Glitter/render_element.cpp | 18 +- src/CRE/Glitter/render_group.cpp | 23 +- src/CRE/Glitter/render_scene.cpp | 209 ++- src/CRE/Glitter/scene.cpp | 8 +- src/CRE/auth_3d.cpp | 137 +- src/CRE/auth_3d.hpp | 26 +- src/CRE/camera.cpp | 28 +- src/CRE/camera.hpp | 6 +- src/CRE/data.cpp | 101 +- src/CRE/data.hpp | 6 - src/CRE/draw_object.cpp | 52 +- src/CRE/draw_pass.cpp | 7 +- src/CRE/draw_task.cpp | 80 +- src/CRE/fbo.cpp | 21 +- src/CRE/fbo.hpp | 6 +- src/CRE/frame_rate_control.cpp | 26 - src/CRE/frame_rate_control.hpp | 16 +- src/CRE/light_param/light.hpp | 22 +- src/CRE/object.cpp | 44 +- src/CRE/object.hpp | 4 +- src/CRE/post_process/dof.cpp | 10 +- src/CRE/post_process/exposure.cpp | 6 +- src/CRE/pv_expression.cpp | 428 +++++ src/CRE/pv_expression.hpp | 19 + src/CRE/render_context.cpp | 68 +- src/CRE/render_context.hpp | 64 +- src/CRE/rob/ex_block.cpp | 102 +- src/CRE/rob/rob.cpp | 1438 +++++++++++++---- src/CRE/rob/rob.hpp | 148 +- src/CRE/shader.cpp | 94 +- src/CRE/shader.hpp | 44 +- src/CRE/shader_ft.cpp | 38 +- src/CRE/shader_glsl.cpp | 48 - src/CRE/shader_glsl.hpp | 6 - src/CRE/stage.cpp | 8 +- src/CRE/stage.hpp | 5 +- src/CRE/stage_modern.cpp | 8 +- src/CRE/stage_modern.hpp | 5 +- src/CRE/task_effect.cpp | 2 +- src/CRE/texture.cpp | 1 + src/DivaGL/DivaGL.vcxproj | 4 +- src/DivaGL/bone_data.cpp | 38 +- src/DivaGL/bone_data.hpp | 70 +- src/DivaGL/inject.cpp | 27 +- src/DivaGL/shader_table.cpp | 84 +- src/DivaGL/shader_table.hpp | 68 +- src/KKdLib/a3da.cpp | 2 +- src/KKdLib/a3da.hpp | 2 +- src/KKdLib/database/auth_3d.cpp | 47 +- src/KKdLib/database/auth_3d.hpp | 14 +- src/KKdLib/database/bone.cpp | 26 +- src/KKdLib/database/bone.hpp | 2 +- src/KKdLib/database/item_table.hpp | 24 +- src/KKdLib/database/motion.cpp | 201 ++- src/KKdLib/database/motion.hpp | 40 +- src/KKdLib/database/object.cpp | 249 +-- src/KKdLib/database/object.hpp | 42 +- src/KKdLib/database/stage.cpp | 244 ++- src/KKdLib/database/stage.hpp | 109 +- src/KKdLib/database/texture.cpp | 189 +-- src/KKdLib/database/texture.hpp | 32 +- src/KKdLib/enbaya.hpp | 2 +- src/KKdLib/farc.cpp | 191 ++- src/KKdLib/farc.hpp | 5 +- src/KKdLib/half_t.cpp | 15 + src/KKdLib/hash.cpp | 17 +- src/KKdLib/hash.hpp | 11 +- .../{interpolation.c => interpolation.cpp} | 30 +- .../{interpolation.h => interpolation.hpp} | 0 src/KKdLib/key_val.cpp | 2 +- src/KKdLib/key_val.hpp | 2 +- src/KKdLib/light_param/face.cpp | 8 +- src/KKdLib/light_param/face.hpp | 3 +- src/KKdLib/light_param/fog.cpp | 14 +- src/KKdLib/light_param/fog.hpp | 4 +- src/KKdLib/light_param/glow.cpp | 72 +- src/KKdLib/light_param/glow.hpp | 4 +- src/KKdLib/light_param/ibl.cpp | 14 +- src/KKdLib/light_param/ibl.hpp | 8 +- src/KKdLib/light_param/light.cpp | 90 +- src/KKdLib/light_param/light.hpp | 8 +- src/KKdLib/light_param/wind.hpp | 2 +- src/KKdLib/mat.cpp | 914 +++++------ src/KKdLib/mat.hpp | 43 +- src/KKdLib/mot.cpp | 9 +- src/KKdLib/obj.cpp | 160 +- src/KKdLib/obj.hpp | 29 +- src/KKdLib/pv_exp.cpp | 339 ++++ src/KKdLib/pv_exp.hpp | 2 +- src/KKdLib/pvpp.cpp | 349 ++-- src/KKdLib/pvpp.hpp | 67 +- src/KKdLib/pvsr.cpp | 409 +++-- src/KKdLib/pvsr.hpp | 61 +- src/KKdLib/quat.cpp | 2 +- src/KKdLib/{quat_trans.c => quat_trans.cpp} | 3 +- src/KKdLib/{quat_trans.h => quat_trans.hpp} | 0 src/KKdLib/sound/diva.cpp | 61 +- src/KKdLib/vec.cpp | 62 - src/KKdLib/vec.hpp | 499 ++---- src/MMPlusDec/MMPlusDec.cpp | 12 +- 126 files changed, 6163 insertions(+), 4157 deletions(-) create mode 100644 src/CRE/pv_expression.cpp create mode 100644 src/CRE/pv_expression.hpp rename src/KKdLib/{interpolation.c => interpolation.cpp} (93%) rename src/KKdLib/{interpolation.h => interpolation.hpp} (100%) rename src/KKdLib/{quat_trans.c => quat_trans.cpp} (90%) rename src/KKdLib/{quat_trans.h => quat_trans.hpp} (100%) diff --git a/extern/lib/libdeflatestatic.lib b/extern/lib/libdeflatestatic.lib index 37d8176302cbe49c594d994addcc6a49880719e6..0cc709c5dd23a5ef94d0dd8fa6016e0364aec26d 100644 GIT binary patch literal 77554 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

R1Q^jtVAmvGYCEnZ!geWn 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 diff --git a/extern/src/libdeflate.h b/extern/src/libdeflate.h index 0bb1f22a..a13ac71e 100644 --- a/extern/src/libdeflate.h +++ b/extern/src/libdeflate.h @@ -10,8 +10,8 @@ extern "C" { #endif #define LIBDEFLATE_VERSION_MAJOR 1 -#define LIBDEFLATE_VERSION_MINOR 10 -#define LIBDEFLATE_VERSION_STRING "1.10" +#define LIBDEFLATE_VERSION_MINOR 12 +#define LIBDEFLATE_VERSION_STRING "1.12" #include #include @@ -31,7 +31,7 @@ extern "C" { # define LIBDEFLATEEXPORT #endif -#if defined(_WIN32) && !defined(_WIN64) +#if defined(_WIN32) && !defined(_WIN64) && defined(LIBDEFLATE_DLL) # define LIBDEFLATEAPI_ABI __stdcall #else # define LIBDEFLATEAPI_ABI diff --git a/src/CLOUD/classes/data_test/glitter_test.cpp b/src/CLOUD/classes/data_test/glitter_test.cpp index f5c4b474..859d3e84 100644 --- a/src/CLOUD/classes/data_test/glitter_test.cpp +++ b/src/CLOUD/classes/data_test/glitter_test.cpp @@ -126,8 +126,6 @@ bool TaskDataTestGlitterParticle::Init() { } bool TaskDataTestGlitterParticle::Ctrl() { - Glitter::glt_particle_manager.rctx = rctx_ptr; - if (load_file && file_index < files.size()) LoadFile(files[file_index].name.c_str()); load_file = false; @@ -152,7 +150,7 @@ bool TaskDataTestGlitterParticle::Ctrl() { } if (Glitter::glt_particle_manager.SceneHasNotEnded(scene_counter) && !Glitter::glt_particle_manager.GetPause()) - frame += sys_frame_rate.frame_speed; + frame += sys_frame_rate.GetDeltaFrame(); if (reload || auto_and_repeat && !Glitter::glt_particle_manager.SceneHasNotEnded(scene_counter)) { Glitter::glt_particle_manager.FreeSceneEffect(scene_counter, hash_fnv1a64m_empty, true); diff --git a/src/CLOUD/classes/data_view/draw_task.cpp b/src/CLOUD/classes/data_view/draw_task.cpp index fdd99ea0..412c61cc 100644 --- a/src/CLOUD/classes/data_view/draw_task.cpp +++ b/src/CLOUD/classes/data_view/draw_task.cpp @@ -155,17 +155,15 @@ void data_view_draw_task_imgui(class_data* data) { continue; } - mat4 mat = task->mat; - vec3 trans; - mat4_get_translation(&mat, &trans); + mat4_get_translation(&task->mat, &trans); vec3 rot; - mat4_get_rotation(&mat, &rot); + mat4_get_rotation(&task->mat, &rot); vec3_mult_scalar(rot, RAD_TO_DEG_FLOAT, rot); vec3 scale; - mat4_get_scale(&mat, &scale); + mat4_get_scale(&task->mat, &scale); ImGui::Text("Trans: %9.4f %9.4f %9.4f", trans.x, trans.y, trans.z); ImGui::Text(" Rot: %9.4f %9.4f %9.4f", rot.x, rot.y, rot.z); diff --git a/src/CLOUD/classes/glitter_editor.cpp b/src/CLOUD/classes/glitter_editor.cpp index d2545200..7ea3c6fe 100644 --- a/src/CLOUD/classes/glitter_editor.cpp +++ b/src/CLOUD/classes/glitter_editor.cpp @@ -10,7 +10,7 @@ #include "../../KKdLib/io/path.hpp" #include "../../KKdLib/io/stream.hpp" #include "../../KKdLib/dds.hpp" -#include "../../KKdLib/interpolation.h" +#include "../../KKdLib/interpolation.hpp" #include "../../KKdLib/str_utils.hpp" #include "../../KKdLib/txp.hpp" #include "../../KKdLib/vec.hpp" @@ -196,6 +196,8 @@ extern bool global_context_menu; extern float_t rob_frame; +extern render_context* rctx_ptr; + static const char* glitter_editor_window_title = "Glitter Editor"; static void glitter_editor_windows(glitter_editor_struct* glt_edt, class_data* data); @@ -1276,7 +1278,6 @@ static void glitter_editor_windows(glitter_editor_struct* glt_edt, class_data* d enum_or(data->flags, CLASS_DISPOSE); if (ImGui::MenuItem("Quit", "Ctrl+Q")) close = true; - ImGui::EndMenu(); } if (ImGui::BeginMenu("Edit", false)) { @@ -1499,9 +1500,9 @@ static void glitter_editor_reload(glitter_editor_struct* glt_edt) { Glitter::Effect* effect = i; if (eg->type != Glitter::FT) - effect->data.name_hash = hash_string_murmurhash(&effect->name); + effect->data.name_hash = hash_string_murmurhash(effect->name); else - effect->data.name_hash = hash_string_fnv1a64m(&effect->name); + effect->data.name_hash = hash_string_fnv1a64m(effect->name); for (Glitter::Curve*& c : effect->animation.curves) if (c) @@ -1664,7 +1665,7 @@ static void glitter_editor_load_file(glitter_editor_struct* glt_edt, const char* continue; Glitter::Effect* e = i; - if (e->data.name_hash != hash_string_fnv1a64m(&e->name)) { + if (e->data.name_hash != hash_string_fnv1a64m(e->name)) { lst_not_valid = true; break; } @@ -1985,7 +1986,7 @@ static void glitter_editor_test_window(glitter_editor_struct* glt_edt, class_dat float_t y; float_t w = 280.0f; - float_t h = 326.0f; + float_t h = 352.0f; ImGui::SetNextWindowPos({ 0, 0 }, ImGuiCond_FirstUseEver); ImGui::SetNextWindowSize({ w, h }, ImGuiCond_Always); @@ -2058,6 +2059,16 @@ static void glitter_editor_test_window(glitter_editor_struct* glt_edt, class_dat ImGui::CheckboxFlagsEnterKeyPressed("No Draw", (uint32_t*)&glt_edt->draw_flags, GLITTER_EDITOR_DRAW_NO_DRAW); + ImGui::Separator(); + + camera* cam = rctx_ptr->camera; + + static const double_t fov_min = 0.0; + static const double_t fov_max = 180.0; + double_t fov = cam->get_fov(); + if (ImGui::SliderScalar("Camera FOV", ImGuiDataType_Double, &fov, &fov_min, &fov_max, "%g")) + cam->set_fov(fov); + data->imgui_focus |= ImGui::IsWindowFocused(); ImGui::End(); @@ -2725,6 +2736,17 @@ static void glitter_editor_play_manager(glitter_editor_struct* glt_edt) { ImGui::DisableElementPush(Glitter::glt_particle_manager.draw_all && eg && eg->type == Glitter::X); ImGui::CheckboxEnterKeyPressed("Draw All Mesh", &Glitter::glt_particle_manager.draw_all_mesh); ImGui::DisableElementPop(Glitter::glt_particle_manager.draw_all && eg && eg->type == Glitter::X); + + ImGui::Separator(); + + camera* cam = rctx_ptr->camera; + + static const double_t fov_min = 0.0; + static const double_t fov_max = 180.0; + double_t fov = cam->get_fov(); + if (ImGui::SliderScalar("Camera FOV", ImGuiDataType_Double, &fov, &fov_min, &fov_max, "%g")) + cam->set_fov(fov); + } static void glitter_editor_property(glitter_editor_struct* glt_edt, class_data* data) { @@ -2761,7 +2783,7 @@ static void glitter_editor_property_effect(glitter_editor_struct* glt_edt, class name.assign(effect->name.c_str()); if (ImGui::ColumnInputText("Name", (char*)name.c_str(), name.capacity(), 0, 0, 0)) { effect->data.name_hash = eg->type != Glitter::FT - ? hash_string_murmurhash(&name) : hash_string_fnv1a64m(&name); + ? hash_string_murmurhash(name) : hash_string_fnv1a64m(name); effect->name.assign(name.c_str()); changed = true; } @@ -6868,8 +6890,7 @@ static void glitter_editor_gl_draw_wireframe_draw_mesh(glitter_editor_struct* gl if (!elem->disp) continue; - render_context* rctx = (render_context*)Glitter::glt_particle_manager.rctx; - object_data* object_data = &rctx->object_data; + object_data* object_data = &rctx_ptr->object_data; Glitter::Particle* particle = rg->particle->data.particle; object_info object_info; @@ -6881,10 +6902,10 @@ static void glitter_editor_gl_draw_wireframe_draw_mesh(glitter_editor_struct* gl obj_mesh_index_buffer* obj_index_buffer = object_storage_get_obj_mesh_index_buffer(object_info); - mat4 mat = elem->mat_draw; + mat4& mat = elem->mat_draw; if (!obj || !obj_vertex_buffer || !obj_index_buffer || (object_data->object_culling && !object_bounding_sphere_check_visibility(&obj->bounding_sphere, - object_data, rctx->camera, &mat))) + object_data, rctx_ptr->camera, &mat))) continue; glt_edt->gl_data->wireframe.shader.set("model", false, mat); @@ -6895,7 +6916,7 @@ static void glitter_editor_gl_draw_wireframe_draw_mesh(glitter_editor_struct* gl obj_mesh* mesh = &obj->mesh_array[i]; if (object_data->object_culling && !object_bounding_sphere_check_visibility( - &mesh->bounding_sphere, object_data, rctx->camera, &mat)) + &mesh->bounding_sphere, object_data, rctx_ptr->camera, &mat)) continue; for (uint32_t j = 0; j < mesh->num_submesh; j++) { @@ -6906,14 +6927,14 @@ static void glitter_editor_gl_draw_wireframe_draw_mesh(glitter_editor_struct* gl if (object_data->object_culling) { int32_t v32 = object_bounding_sphere_check_visibility( - &sub_mesh->bounding_sphere, object_data, rctx->camera, &mat); + &sub_mesh->bounding_sphere, object_data, rctx_ptr->camera, &mat); if (v32 != 2 || (!mesh->attrib.m.billboard && !mesh->attrib.m.billboard_y_axis)) { if (v32 == 2) { if (object_data->object_bounding_sphere_check_func) v32 = 1; else v32 = obj_axis_aligned_bounding_box_check_visibility( - &sub_mesh->axis_aligned_bounding_box, rctx->camera, &mat); + &sub_mesh->axis_aligned_bounding_box, rctx_ptr->camera, &mat); } if (!v32) diff --git a/src/CLOUD/classes/graphics/render_settings.cpp b/src/CLOUD/classes/graphics/render_settings.cpp index 4613b6ef..74cbd92f 100644 --- a/src/CLOUD/classes/graphics/render_settings.cpp +++ b/src/CLOUD/classes/graphics/render_settings.cpp @@ -7,6 +7,7 @@ #include "../../../CRE/lock.hpp" #include "../../../CRE/static_var.hpp" #include "../../../CRE/timer.hpp" +#include "../../render.hpp" #include "../imgui_helper.hpp" extern int32_t width; @@ -15,12 +16,6 @@ extern int32_t height; extern timer* render_timer; extern timer* sound_timer; -extern size_t render_scale_table_count; -extern double_t render_get_scale(); -extern void render_set_scale(double_t value); -extern int32_t render_get_scale_index(); -extern void render_set_scale_index(int32_t index); - const char* graphics_render_settings_window_title = "Render Settings##Graphics"; inline static void render_settings_freq_to_string(double_t freq, @@ -75,7 +70,7 @@ void graphics_render_settings_imgui(class_data* data) { char buf[0x80]; sprintf_s(buf, sizeof(buf), "%g%%%%", scale); if (ImGui::ColumnSliderInt("Scale", &scale_index, 0, - (int32_t)render_scale_table_count, buf, ImGuiSliderFlags_NoInput, true)) + RENDER_SCALE_MAX - 1, buf, ImGuiSliderFlags_NoInput, true)) render_set_scale_index(scale_index); #if defined(CLOUD_DEV) @@ -118,7 +113,7 @@ void graphics_render_settings_imgui(class_data* data) { ImGui::Separator(); if (ImGui::ButtonEnterKeyPressed("Reset Render Settings")) - render_set_scale(1.0); + render_set_scale_index(6); data->imgui_focus |= ImGui::IsWindowFocused(); ImGui::End(); diff --git a/src/CLOUD/input.cpp b/src/CLOUD/input.cpp index d0c50f0d..90b7c424 100644 --- a/src/CLOUD/input.cpp +++ b/src/CLOUD/input.cpp @@ -14,8 +14,10 @@ double_t input_movement_speed = 0.1; double_t input_rotation_sensitivity = 0.5; -vec2d input_move; -vec2d input_rotate; +double_t input_move_x; +double_t input_move_y; +double_t input_rotate_x; +double_t input_rotate_y; double_t input_roll; bool input_reset; bool input_reset_mouse_position; @@ -189,10 +191,10 @@ namespace Input { ScreenToClient(window_handle, &pos); } - input_move.x = 0.0; - input_move.y = 0.0; - input_rotate.x = 0.0; - input_rotate.y = 0.0; + input_move_x = 0.0; + input_move_y = 0.0; + input_rotate_x = 0.0; + input_rotate_y = 0.0; input_roll = 0.0; if (!window_handle || window_handle != GetForegroundWindow()) @@ -218,40 +220,40 @@ namespace Input { speed_slow *= frame_speed; if (IsKeyDown(GLFW_KEY_W) || IsKeyDown(GLFW_KEY_W, GLFW_MOD_CONTROL | GLFW_MOD_SHIFT)) - input_move.x += speed; + input_move_x += speed; else if (IsKeyDown(GLFW_KEY_W, GLFW_MOD_SHIFT)) - input_move.x += speed_fast; + input_move_x += speed_fast; else if (IsKeyDown(GLFW_KEY_W, GLFW_MOD_CONTROL)) - input_move.x += speed_slow; + input_move_x += speed_slow; else if (IsKeyDown(GLFW_KEY_W, -1)) - input_move.x += speed; + input_move_x += speed; if (IsKeyDown(GLFW_KEY_S) || IsKeyDown(GLFW_KEY_S, GLFW_MOD_CONTROL | GLFW_MOD_SHIFT)) - input_move.x -= speed; + input_move_x -= speed; else if (IsKeyDown(GLFW_KEY_S, GLFW_MOD_SHIFT)) - input_move.x -= speed_fast; + input_move_x -= speed_fast; else if (IsKeyDown(GLFW_KEY_S, GLFW_MOD_CONTROL)) - input_move.x -= speed_slow; + input_move_x -= speed_slow; else if (IsKeyDown(GLFW_KEY_S, -1)) - input_move.x -= speed; + input_move_x -= speed; if (IsKeyDown(GLFW_KEY_A) || IsKeyDown(GLFW_KEY_A, GLFW_MOD_CONTROL | GLFW_MOD_SHIFT)) - input_move.y -= speed; + input_move_y -= speed; else if (IsKeyDown(GLFW_KEY_A, GLFW_MOD_SHIFT)) - input_move.y -= speed_fast; + input_move_y -= speed_fast; else if (IsKeyDown(GLFW_KEY_A, GLFW_MOD_CONTROL)) - input_move.y -= speed_slow; + input_move_y -= speed_slow; else if (IsKeyDown(GLFW_KEY_A, -1)) - input_move.y -= speed; + input_move_y -= speed; if (IsKeyDown(GLFW_KEY_D) || IsKeyDown(GLFW_KEY_D, GLFW_MOD_CONTROL | GLFW_MOD_SHIFT)) - input_move.y += speed; + input_move_y += speed; else if (IsKeyDown(GLFW_KEY_D, GLFW_MOD_SHIFT)) - input_move.y += speed_fast; + input_move_y += speed_fast; else if (IsKeyDown(GLFW_KEY_D, GLFW_MOD_CONTROL)) - input_move.y += speed_slow; + input_move_y += speed_slow; else if (IsKeyDown(GLFW_KEY_D, -1)) - input_move.y += speed; + input_move_y += speed; speed = input_movement_speed; speed_fast = input_movement_speed * 2.0; @@ -267,40 +269,40 @@ namespace Input { speed_slow *= 10.0; if (IsKeyDown(GLFW_KEY_UP) || IsKeyDown(GLFW_KEY_UP, GLFW_MOD_CONTROL | GLFW_MOD_SHIFT)) - input_rotate.y += speed; + input_rotate_y += speed; else if (IsKeyDown(GLFW_KEY_UP, GLFW_MOD_SHIFT)) - input_rotate.y += speed_fast; + input_rotate_y += speed_fast; else if (IsKeyDown(GLFW_KEY_UP, GLFW_MOD_CONTROL)) - input_rotate.y += speed_slow; + input_rotate_y += speed_slow; else if (IsKeyDown(GLFW_KEY_UP, -1)) - input_rotate.y += speed; + input_rotate_y += speed; if (IsKeyDown(GLFW_KEY_DOWN) || IsKeyDown(GLFW_KEY_DOWN, GLFW_MOD_CONTROL | GLFW_MOD_SHIFT)) - input_rotate.y -= speed; + input_rotate_y -= speed; else if (IsKeyDown(GLFW_KEY_DOWN, GLFW_MOD_SHIFT)) - input_rotate.y -= speed_fast; + input_rotate_y -= speed_fast; else if (IsKeyDown(GLFW_KEY_DOWN, GLFW_MOD_CONTROL)) - input_rotate.y -= speed_slow; + input_rotate_y -= speed_slow; else if (IsKeyDown(GLFW_KEY_DOWN, -1)) - input_rotate.y -= speed; + input_rotate_y -= speed; if (IsKeyDown(GLFW_KEY_LEFT) || IsKeyDown(GLFW_KEY_LEFT, GLFW_MOD_CONTROL | GLFW_MOD_SHIFT)) - input_rotate.x -= speed; + input_rotate_x -= speed; else if (IsKeyDown(GLFW_KEY_LEFT, GLFW_MOD_SHIFT)) - input_rotate.x -= speed_fast; + input_rotate_x -= speed_fast; else if (IsKeyDown(GLFW_KEY_LEFT, GLFW_MOD_CONTROL)) - input_rotate.x -= speed_slow; + input_rotate_x -= speed_slow; else if (IsKeyDown(GLFW_KEY_LEFT, -1)) - input_rotate.x -= speed; + input_rotate_x -= speed; if (IsKeyDown(GLFW_KEY_RIGHT) || IsKeyDown(GLFW_KEY_RIGHT, GLFW_MOD_CONTROL | GLFW_MOD_SHIFT)) - input_rotate.x += speed; + input_rotate_x += speed; else if (IsKeyDown(GLFW_KEY_RIGHT, GLFW_MOD_SHIFT)) - input_rotate.x += speed_fast; + input_rotate_x += speed_fast; else if (IsKeyDown(GLFW_KEY_RIGHT, GLFW_MOD_CONTROL)) - input_rotate.x += speed_slow; + input_rotate_x += speed_slow; else if (IsKeyDown(GLFW_KEY_RIGHT, -1)) - input_rotate.x += speed; + input_rotate_x += speed; if (IsKeyDown(GLFW_KEY_Q) || IsKeyDown(GLFW_KEY_Q, GLFW_MOD_CONTROL | GLFW_MOD_SHIFT)) input_roll += speed; @@ -325,8 +327,8 @@ namespace Input { if (IsMouseButtonDown(GLFW_MOUSE_BUTTON_MIDDLE, -1)) { if (!input_reset_mouse_position) { - input_rotate.y += ((double_t)pos_prev.y - (double_t)pos.y) * input_rotation_sensitivity; - input_rotate.x += ((double_t)pos.x - (double_t)pos_prev.x) * input_rotation_sensitivity; + input_rotate_y += ((double_t)pos_prev.y - (double_t)pos.y) * input_rotation_sensitivity; + input_rotate_x += ((double_t)pos.x - (double_t)pos_prev.x) * input_rotation_sensitivity; } input_reset_mouse_position = false; } diff --git a/src/CLOUD/main.cpp b/src/CLOUD/main.cpp index e5ed9169..79c67b15 100644 --- a/src/CLOUD/main.cpp +++ b/src/CLOUD/main.cpp @@ -14,6 +14,7 @@ #include bool aes_ni; +bool f16c; inline static void next_rand_uint8_t_pointer(uint8_t* arr, size_t length, uint32_t* state) { if (!arr || length < 1) @@ -312,16 +313,14 @@ int32_t wmain(int32_t argc, wchar_t** argv) { timeBeginPeriod(1); SetProcessDPIAware(); - int32_t cpuid_data[4]; + int32_t cpuid_data[4] = {}; __cpuid(cpuid_data, 1); - aes_ni = cpuid_data[2] & 0x2000000 ? true : false; + aes_ni = (cpuid_data[2] & (1 << 25)) ? true : false; + f16c = (cpuid_data[2] & (1 << 29)) ? true : false; //a3da_to_dft_dsc(269); render_init_struct ris; - ris.res.x = 0; - ris.res.y = 0; - ris.scale = 0.0f; thread render, sound; HANDLE h[2]; diff --git a/src/CLOUD/pv_game.cpp b/src/CLOUD/pv_game.cpp index 9741cb71..6403248e 100644 --- a/src/CLOUD/pv_game.cpp +++ b/src/CLOUD/pv_game.cpp @@ -171,7 +171,7 @@ void pv_play_data_motion_data::reset() { set_item.shrink_to_fit(); } -pv_play_data::pv_play_data() : rob_chr(), disp() { +pv_play_data::pv_play_data() : rob_chr(), disp(), field_31(), field_34() { } @@ -198,7 +198,15 @@ pv_disp2d::~pv_disp2d() { } -pv_game_dsc_data::pv_game_dsc_data() { +pv_game_dsc_data::pv_game_dsc_data() : field_0(), state(), play(), dsc_buffer(), dsc_buffer_counter(), +field_2BF30(), field_2BF38(), curr_time(), curr_time_float(), prev_time_float(), field_2BF50(), field_2BF58(), +field_2BF60(), field_2BF64(), field_2BF68(), chara_id(), pv_game()/*, field_2BF80(), field_2BF88()*/, +dsc_file_handler(), target_anim_fps(), anim_frame_speed(), target_flying_time(), time_signature(), dsc_time(), +field_2BFB0(), field_2BFB4(), field_2BFB8(), field_2BFBC(), field_2BFC0(), music_play(), field_2BFC4(), pv_end(), +fov(), min_dist(), field_2BFD4(), field_2BFD5(), data_camera(), scene_fade_enable(), scene_fade_frame(), +scene_fade_duration(), scene_fade_start_alpha(), scene_fade_end_alpha(), scene_fade_color(), has_signature(), +has_perf_id(), field_2C4E4(), field_2C500(), scene_rot_y(), scene_rot_mat(), field_2C54C(), +field_2C550(), branch_mode(), first_challenge_note(), last_challenge_note(), field_2C560() { } @@ -206,7 +214,7 @@ pv_game_dsc_data::~pv_game_dsc_data() { } -pv_game_data_chara::pv_game_data_chara() { +pv_game_data_chara::pv_game_data_chara() : chara_index(), cos(), chara_id(), pv_data(), rob_chr() { } @@ -214,7 +222,8 @@ pv_game_data_chara::~pv_game_data_chara() { } -pv_game_data_field::pv_game_data_field() { +pv_game_data_field::pv_game_data_field() : stage_index(), light_auth_3d_uid(), light_auth_3d_id(), +light_frame(), spr_set_back_id(), stage_flag(), npr_type(), cam_blur(), sdw_off() { } @@ -222,7 +231,7 @@ pv_game_data_field::~pv_game_data_field() { } -struc_78::struc_78() { +struc_78::struc_78() : field_30(), field_34() { } @@ -230,7 +239,8 @@ struc_78::~struc_78() { } -pv_game_data_chreff::pv_game_data_chreff() { +pv_game_data_chreff::pv_game_data_chreff() : src_chara_index(), +dst_chara_index(), src_auth_3d_uid(), dst_auth_3d_uid() { } @@ -238,7 +248,7 @@ pv_game_data_chreff::~pv_game_data_chreff() { } -pv_effect_resource::pv_effect_resource() { +pv_effect_resource::pv_effect_resource() : emission() { } @@ -246,7 +256,26 @@ pv_effect_resource::~pv_effect_resource() { } -pv_game_data::pv_game_data() { +pv_game_data::pv_game_data() : field_2CE98(), field_2CE9C(), field_2CF1C(), field_2CF20(), field_2CF24(), +field_2CF28(), field_2CF2C(), field_2CF30(), field_2CF34(), field_2CF38(), life_gauge(), score_final(), +challenge_time_total_bonus(), combo(), challenge_time_combo_count(), max_combo(), total_hit_count(), hit_count(), +current_reference_score(), target_count(), field_2CF84(), field_2CF88(), field_2CF8C(), score_slide_chain_bonus(), +slide_chain_length(), field_2CF98(), field_2CF9C(), field_2CFA0(), field_2CFA4(), pv(), field_2CFB0(), field_2CFB4(), +reference_score(), field_2CFBC(), field_2CFC0(), field_2CFC4(), field_2CFE0(), field_2CFE4(), notes_passed(), +field_2CFF0(), score_percentage(), score_percentage_clear(), score_percentage_border(), life_gauge_safety_time(), +life_gauge_border(), field_2D008(), field_2D00C(), no_fail(), field_2D00E(), field_2D00F(), challenge_time_start(), +challenge_time_end(), max_time(), max_time_float(), current_time_float(), current_time(), current_time_float_dup(), +field_2D03C(), score_hold_multi(), score_hold(), score_slide(), field_2D04C(), chance_time_ended(), pv_disp2d(), +life_gauge_final(), hit_border(), field_2D05D(), field_2D05E(), field_2D05F(), title_image_init(), field_2D061(), +field_2D062(), field_2D063(), has_auth_3d_frame(), has_light_frame(), field_2D066(), field_2D068(), field_2D069(), +field_2D06A(), field_2D06C(), field_index(), edit_effect_index(), slidertouch_counter(), +change_field_branch_success_counter(), field_2D080(), field_2D084(), life_gauge_bonus(), life_gauge_total_bonus(), +field_2D090(), field_2D091(), field_2D092(), field_2D093(), field_2D094(), field_2D095(), field_2D096(), success(), +field_2D098(), field_2D09C(), field_2D0A0(), pv_end_fadeout(), rival_percentage(), field_2D0A8(), field_2D0AC(), +field_2D0B0(), field_2D0BC(), field_2D0BD(), field_2D0BE(), field_2D0BF(), field_2D0C0(), field_2D0C4(), +field_2D7E8(), field_2D7EC(), field_2D808(), field_2D80C(), field_2D858(), camera_auth_3d_uid(), field_2D874(), +field_2D878(), field_2D87C(), current_field(), field_2D8A0(), field_2D8A4(), data_camera_id(), +field_2D954(), field_2DAC8(), field_2DACC(), field_2DB28(), field_2DB2C(), field_2DB34() { } @@ -254,7 +283,8 @@ pv_game_data::~pv_game_data() { } -pv_game::pv_game() { +pv_game::pv_game() : loaded(), field_1(), field_2(), end_pv(), field_4(), +state(), field_C(), pv_id(), field_14(), modules(), items(), field_90() { } @@ -262,7 +292,9 @@ pv_game::~pv_game() { } -TaskPvGame::Data::Data() { +TaskPvGame::Data::Data() : field_0(), field_4(), field_8(), score_percentage_clear(), life_gauge_safety_time(), +life_gauge_border(), field_1C(), modules(), items(), field_98(), field_A0(), field_A8(), field_190(), +field_191(), no_fail(), field_193(), field_194(), field_195(), field_196(), field_198() { } @@ -315,7 +347,7 @@ pv_end(), playdata(), scene_rot_y(), branch_mode(), pause(), step_frame() { camera_auth_3d_id = -1; target_anim_fps = 60.0f; anim_frame_speed = 1.0f; - scene_rot_mat = mat4u_identity; + scene_rot_mat = mat4_identity; } pv_game_old::~pv_game_old() { @@ -543,18 +575,6 @@ bool pv_game_old::Ctrl() { pause = true; } break; case 10: { - if (step_frame) - if (pause) - pause = false; - else { - pause = true; - step_frame = false; - } - - Glitter::glt_particle_manager.SetPause(pause); - extern float_t frame_speed; - frame_speed = pause ? 0.0f : 1.0f; - float_t delta_frame = get_delta_frame(); frame_float += delta_frame; frame = (int32_t)frame_float; @@ -575,12 +595,6 @@ bool pv_game_old::Ctrl() { return false; } -void pv_game_old::Disp() { - if (state != 10) - return; - -} - bool pv_game_old::Dest() { Unload(); task_stage_unload(); @@ -599,6 +613,29 @@ bool pv_game_old::Dest() { return true; } +void pv_game_old::Disp() { + if (state != 10) + return; + +} + +void pv_game_old::Basic() { + if (state != 10) + return; + + if (step_frame) + if (pause) + pause = false; + else { + pause = true; + step_frame = false; + } + + Glitter::glt_particle_manager.SetPause(pause); + extern float_t frame_speed; + frame_speed = pause ? 0.0f : 1.0f; +} + void pv_game_old::Window() { if (state != 10) return; @@ -706,7 +743,7 @@ void pv_game_old::Load(int32_t pv_id, chara_index charas[6], int32_t modules[6]) for (pv_play_data& i : playdata) i.reset(); scene_rot_y = 0.0f; - scene_rot_mat = mat4u_identity; + scene_rot_mat = mat4_identity; branch_mode = 0; pause = false; @@ -815,7 +852,7 @@ void pv_game_old::Unload() { for (pv_play_data& i : playdata) i.reset(); scene_rot_y = 0.0f; - scene_rot_mat = mat4u_identity; + scene_rot_mat = mat4_identity; branch_mode = 0; Glitter::glt_particle_manager.draw_all = true; @@ -955,9 +992,8 @@ static bool pv_game_dsc_process(pv_game_old* a1, int64_t curr_time) { if (!rob_chr) break; - mat4 scene_rot_mat = a1->scene_rot_mat; - mat4_mult_vec3_trans(&scene_rot_mat, &trans, &trans); - rob_chr->data.miku_rot.position = trans; + mat4_mult_vec3_trans(&a1->scene_rot_mat, + &trans, &rob_chr->data.miku_rot.position); rob_chr->set_osage_reset(); } break; case DSC_FT_MIKU_ROT: { @@ -1733,8 +1769,7 @@ static bool pv_game_dsc_process(pv_game_old* a1, int64_t curr_time) { if (!rob_chr) break; - mat4 scene_rot_mat = a1->scene_rot_mat; - mat4_mult_vec3_trans(&scene_rot_mat, &pos, &pos); + mat4_mult_vec3_trans(&a1->scene_rot_mat, &pos, &pos); rob_chr->set_chara_pos_adjust(&pos); /*if (rob_chara_check_for_ageageagain_module(rob_chr->chara_index, rob_chr->module_index)) { @@ -1746,9 +1781,7 @@ static bool pv_game_dsc_process(pv_game_old* a1, int64_t curr_time) { float_t scene_rot_y = (float_t)(int32_t)data[0] * 0.001f; a1->scene_rot_y = scene_rot_y; - mat4 scene_rot_mat = a1->scene_rot_mat; - mat4_rotate_y(scene_rot_y * DEG_TO_RAD_FLOAT, &scene_rot_mat); - a1->scene_rot_mat = scene_rot_mat; + mat4_rotate_y(scene_rot_y * DEG_TO_RAD_FLOAT, &a1->scene_rot_mat); } break; case DSC_FT_EDIT_MOT_SMOOTH_LEN: { diff --git a/src/CLOUD/pv_game.hpp b/src/CLOUD/pv_game.hpp index 875dd95a..d20e46fb 100644 --- a/src/CLOUD/pv_game.hpp +++ b/src/CLOUD/pv_game.hpp @@ -241,7 +241,7 @@ struct pv_game_dsc_data { struct pv_game_data_chara { chara_index chara_index; - int32_t module_index; + int32_t cos; int32_t chara_id; rob_chara_pv_data pv_data; rob_chara* rob_chr; @@ -304,7 +304,7 @@ struct struc_78 { struct pv_game_data_chreff { chara_index src_chara_index; chara_index dst_chara_index; - std::bitset<128>* type; + std::bitset<128> type; std::string src_auth_3d; std::string dst_auth_3d; std::string src_auth_3d_category; @@ -390,7 +390,7 @@ struct pv_game_data { uint32_t score_hold; int32_t score_slide; uint8_t field_2D04C; - uint8_t chance_time_endede; + uint8_t chance_time_ended; pv_disp2d* pv_disp2d; int32_t life_gauge_final; bool hit_border; @@ -603,7 +603,7 @@ public: bool pv_end; pv_play_data playdata[ROB_CHARA_COUNT]; float_t scene_rot_y; - mat4u scene_rot_mat; + mat4 scene_rot_mat; int32_t branch_mode; bool pause; @@ -616,6 +616,7 @@ public: virtual bool Ctrl() override; virtual bool Dest() override; virtual void Disp() override; + virtual void Basic() override; virtual void Window() override; void Load(int32_t pv_id, chara_index charas[6], int32_t modules[6]); diff --git a/src/CLOUD/render.cpp b/src/CLOUD/render.cpp index 2197fe3a..41aa228f 100644 --- a/src/CLOUD/render.cpp +++ b/src/CLOUD/render.cpp @@ -92,9 +92,8 @@ const double_t render_scale_table[] = { 8.0 / 4.0, // 200% }; -size_t render_scale_table_count = sizeof(render_scale_table) / sizeof(double_t); - -static float_t old_scale, scale; +static int32_t old_scale_index; +static int32_t scale_index; static vec2i old_internal_2d_res; static vec2i old_internal_3d_res; @@ -147,6 +146,10 @@ extern size_t frame_counter; render_context* rctx_ptr; bool task_stage_is_modern; +render_init_struct::render_init_struct() : scale_index() { + +} + int32_t render_main(void* arg) { SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL); timeBeginPeriod(1); @@ -234,7 +237,9 @@ int32_t render_main(void* arg) { width = window_rect.right; height = window_rect.bottom; - old_scale = scale = ris->scale > 0 ? ris->scale : 1.0f; + scale_index = ris->scale_index > 0 && ris->scale_index < RENDER_SCALE_MAX + ? ris->scale_index : RENDER_SCALE_100; + old_scale_index = scale_index; #pragma endregion #if defined(DEBUG) && OPENGL_DEBUG @@ -333,47 +338,15 @@ int32_t render_main(void* arg) { } double_t render_get_scale() { - return scale; -} - -void render_set_scale(double_t value) { - size_t i; - for (i = 0; i < render_scale_table_count; i++) - if (value <= render_scale_table[i]) break; - - if (i < render_scale_table_count) - value = render_scale_table[i]; - else if (render_scale_table_count - 1 > -1) - value = render_scale_table[render_scale_table_count - 1]; - else - value = 1.0; - - scale = (float_t)value; + return render_scale_table[scale_index]; } int32_t render_get_scale_index() { - size_t i; - for (i = 0; i < render_scale_table_count; i++) - if (scale <= render_scale_table[i]) break; - - int32_t index; - if (i < render_scale_table_count) - index = (int32_t)i; - else - index = (int32_t)(render_scale_table_count - 1); - return index; + return scale_index; } void render_set_scale_index(int32_t index) { - double_t value; - if (index < 0) - value = render_scale_table[0]; - else if (index < render_scale_table_count) - value = render_scale_table[index]; - else - value = render_scale_table[render_scale_table_count - 1]; - - scale = (float_t)value; + scale_index = index >= 0 && index < RENDER_SCALE_MAX ? index : RENDER_SCALE_100; } float_t rob_frame = 0.0f; @@ -393,11 +366,11 @@ static render_context* render_load() { mothead_storage_init(); osage_setting_data_init(); - Glitter::glt_particle_manager.rctx = rctx; - data_struct_init(); data_struct_load("CLOUD_data.txt"); + render_shaders_load(); + data_struct* aft_data = &data_list[DATA_AFT]; auth_3d_database* aft_auth_3d_db = &aft_data->data_ft.auth_3d_db; bone_database* aft_bone_data = &aft_data->data_ft.bone_data; @@ -430,8 +403,6 @@ static render_context* render_load() { uniform_value[U16] = 1; - render_shaders_load(); - const char* cube_line_vert_shader = "#version 430 core\n" "layout(location = 0) in vec4 a_position;\n" @@ -764,9 +735,9 @@ static render_context* render_load() { modules[5] = 0;//31; //pv_game_data.Load(739, charas, modules); - charas[0] = CHARA_LUKA; - charas[1] = CHARA_LUKA;//CHARA_RIN; - charas[2] = CHARA_LUKA;//CHARA_LEN; + charas[0] = CHARA_KAITO; + charas[1] = CHARA_MIKU;//CHARA_RIN; + charas[2] = CHARA_MEIKO;//CHARA_LEN; charas[3] = CHARA_LUKA;//CHARA_LUKA; charas[4] = CHARA_LUKA;//CHARA_KAITO; charas[5] = CHARA_LUKA;//CHARA_MEIKO; @@ -785,8 +756,10 @@ static render_context* render_load() { return rctx; } -extern vec2d input_move; -extern vec2d input_rotate; +extern double_t input_move_x; +extern double_t input_move_y; +extern double_t input_rotate_x; +extern double_t input_rotate_y; extern double_t input_roll; extern bool input_reset; @@ -811,13 +784,13 @@ static void render_ctrl(render_context* rctx) { classes_process_imgui(classes, classes_count); lock_unlock(&imgui_context_lock); - if (old_width != width || old_height != height || old_scale != scale) { + if (old_width != width || old_height != height || old_scale_index != scale_index) { render_resize_fb(rctx, true); cam->set_res(internal_3d_res.x, internal_3d_res.y); } old_width = width; old_height = height; - old_scale = scale; + old_scale_index = scale_index; lock_lock(&imgui_context_lock); ImGui::SetCurrentContext(imgui_context); @@ -845,8 +818,8 @@ static void render_ctrl(render_context* rctx) { cam->set_fast_change_hist0(true); } else { - cam->rotate(input_rotate); - cam->move(input_move); + cam->rotate(input_rotate_x, input_rotate_y); + cam->move(input_move_x, input_move_y); if (input_roll != 0.0) cam->set_roll(cam->get_roll() + input_roll); } @@ -1145,8 +1118,6 @@ static void render_dispose(render_context* rctx) { object_storage_free(); data_struct_free(); - render_shaders_free(); - glDeleteBuffers(1, &common_data_ubo); glDeleteBuffers(1, &grid_vbo); glDeleteBuffers(1, &cube_line_point_instance_vbo); @@ -1164,6 +1135,8 @@ static void render_dispose(render_context* rctx) { file_handler_storage_free(); texture_storage_free(); + + render_shaders_free(); } static void render_imgui(render_context* rctx) { @@ -1222,8 +1195,8 @@ static void render_resize_fb(render_context* rctx, bool change_fb) { internal_2d_res.x = clamp(internal_res.x, 1, sv_max_texture_size); internal_2d_res.y = clamp(internal_res.y, 1, sv_max_texture_size); - internal_3d_res.x = (int32_t)roundf((float_t)internal_res.x * scale); - internal_3d_res.y = (int32_t)roundf((float_t)internal_res.y * scale); + internal_3d_res.x = (int32_t)roundf((float_t)(internal_res.x * render_scale_table[scale_index])); + internal_3d_res.y = (int32_t)roundf((float_t)(internal_res.y * render_scale_table[scale_index])); internal_3d_res.x = clamp(internal_3d_res.x, 1, sv_max_texture_size); internal_3d_res.y = clamp(internal_3d_res.y, 1, sv_max_texture_size); diff --git a/src/CLOUD/render.hpp b/src/CLOUD/render.hpp index 74ab19ce..3952c0d1 100644 --- a/src/CLOUD/render.hpp +++ b/src/CLOUD/render.hpp @@ -8,15 +8,35 @@ #include "shared.hpp" #include "../KKdLib/vec.hpp" +enum render_scale { + RENDER_SCALE_25 = 0, + RENDER_SCALE_33, + RENDER_SCALE_50, + RENDER_SCALE_67, + RENDER_SCALE_75, + RENDER_SCALE_83, + RENDER_SCALE_100, + RENDER_SCALE_117, + RENDER_SCALE_125, + RENDER_SCALE_133, + RENDER_SCALE_150, + RENDER_SCALE_167, + RENDER_SCALE_175, + RENDER_SCALE_183, + RENDER_SCALE_200, + RENDER_SCALE_MAX, +}; + struct render_init_struct { vec2i res; - float_t scale; + int32_t scale_index; + + render_init_struct(); }; extern const double_t render_scale_table[]; extern int32_t render_main(void* arg); extern double_t render_get_scale(); -extern void render_set_scale(double_t value); extern int32_t render_get_scale_index(); extern void render_set_scale_index(int32_t index); diff --git a/src/CLOUD/x_pv_game.cpp b/src/CLOUD/x_pv_game.cpp index fe8c4e70..6722f2b4 100644 --- a/src/CLOUD/x_pv_game.cpp +++ b/src/CLOUD/x_pv_game.cpp @@ -13,6 +13,7 @@ #include "../CRE/light_param.hpp" #include "../CRE/data.hpp" #include "../CRE/object.hpp" +#include "../CRE/pv_expression.hpp" #include "../CRE/pv_param.hpp" #include "../CRE/stage_modern.hpp" #include "../KKdLib/farc.hpp" @@ -191,16 +192,15 @@ x_pv_game x_pv_game_data; extern render_context* rctx_ptr; static float_t dsc_time_to_frame(int64_t time); -static int32_t expression_id_to_mottbl_index(int32_t expression_id); -static int32_t hand_anim_id_to_mottbl_index(int32_t hand_anim_id); -static int32_t look_anim_id_to_mottbl_index(int32_t look_anim_id); -static int32_t mouth_anim_id_to_mottbl_index(int32_t mouth_anim_id); 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); static void x_pv_game_reset_field(x_pv_game* xpvgm); static void x_pv_game_stage_effect_ctrl(x_pv_game* xpvgm); +static void x_pv_game_stage_effect_start(x_pv_game* xpvgm, pvsr_stage_change_effect* stage_change_effect); static void x_pv_game_stage_effect_start(x_pv_game* xpvgm, pvsr_stage_effect* stage_effect); +static void x_pv_game_stage_effect_stop(x_pv_game* xpvgm, + pvsr_stage_change_effect* stage_change_effect, bool stop_a3da = true, bool stop_glitter = true); static void x_pv_game_stage_effect_stop(x_pv_game* xpvgm, pvsr_stage_effect* stage_effect, bool stop_a3da = true, bool stop_glitter = true); static bool x_pv_game_stage_effects_process(x_pv_game* xpvgm, int32_t frame); @@ -210,6 +210,295 @@ static dsc_data* sub_1401216D0(x_pv_game* a1, dsc_x_func func_name, static void sub_140121A80(x_pv_game* a1, int32_t chara_id); static void sub_140122770(x_pv_game* a1, int32_t chara_id); +bool x_pv_bar_beat_data::compare_bar_time_less(float_t time) { + return (time + 0.0001f) < bar_time; +} + +x_pv_bar_beat::x_pv_bar_beat() : curr_time(), delta_time(), next_bar_time(), +curr_bar_time(), next_beat_time(), curr_beat_time(), bar(), field_20() { + divisor = 2.0f; +} + +x_pv_bar_beat::~x_pv_bar_beat() { + +} + +float_t x_pv_bar_beat::get_bar_current_frame() { + return (curr_time - curr_bar_time) / (next_bar_time - curr_bar_time) * 120.0f; +} + +float_t x_pv_bar_beat::get_delta_frame() { + return delta_time / (next_bar_time - curr_bar_time) * 120.0f; +} + +float_t x_pv_bar_beat::get_next_beat_time(float_t time) { + x_pv_bar_beat_data* d = data.data(); + const size_t size = data.size(); + + size_t length = size; + size_t temp; + while (length > 0) + if (d[temp = length / 2].compare_bar_time_less(time)) + length = temp; + else { + d += temp + 1; + length -= temp + 1; + } + + if (d == data.data() + size) { + float_t v12 = 0.0f; + float_t v13 = divisor * 0.25f; + if (size) { + v12 = data[size - 1].bar_time; + v13 = v12 - data[size - 2].beat_time[data[size - 2].beat_count - 1]; + } + + float_t beat_time = (float_t)((int32_t)((time - v12) / v13) + 1) * v13 + v12; + if (beat_time < time + 0.00001f) + beat_time += v13; + return beat_time; + } + else if (d != data.data()) { + int32_t v9 = d[-1].beat_count - 1; + if (v9 >= 0) { + float_t* v10 = &d[-1].beat_time[v9]; + for (; time >= *v10; v10--) + if (--v9 < 0) + return d->bar_time; + return *v10; + } + } + return d->bar_time; +} + +int32_t x_pv_bar_beat::get_time_bar_beat(int32_t* beat, float_t time) { + if (!data.size()) { + int32_t bar = (int32_t)(float_t)(time / divisor); + if (beat) + *beat = (int32_t)(4.0f * (time - (float_t)(int32_t)(time / divisor) * divisor) / divisor) + 1; + return bar + 1; + } + + x_pv_bar_beat_data* d = data.data(); + const size_t size = data.size(); + + size_t length = size; + size_t temp; + while (length > 0) + if (d[temp = length / 2].compare_bar_time_less(time)) + length = temp; + else { + d += temp + 1; + length -= temp + 1; + } + + if (d == data.data() + size) { + float_t divisor = this->divisor; + float_t diff_time = time - data.back().bar_time; + + if (size > 1) + divisor = data[size - 1].bar_time - data[size - 2].bar_time; + + if (beat) + *beat = (int32_t)((float_t)data.back().beat_count * (diff_time + - (float_t)(int32_t)(diff_time / divisor) * divisor) / divisor) + 1; + return (int32_t)(diff_time / divisor) + data.back().bar; + } + + int32_t bar = d->bar - 1; + if (beat) { + *beat = 1; + if (d == data.data()) + *beat = (int32_t)((float_t)d->beat_count * time / d->bar_time) + 1; + else { + int32_t v18 = d[-1].beat_count - 1; + if (v18 >= 0) { + float_t* v19 = &d[-1].beat_time[v18]; + for (; *v19 > time; v19--) + if (--v18 < 0) + return bar; + *beat = v18 + 1; + } + } + } + return bar; +} + +void x_pv_bar_beat::reset() { + curr_time = 0.0f; + delta_time = 0.0f; + next_bar_time = 0.0f; + curr_bar_time = 0.0f; + next_beat_time = 0.0f; + curr_beat_time = 0.0f; + divisor = 2.0f; + bar = 0; + data.clear(); + data.shrink_to_fit(); +} + +void x_pv_bar_beat::reset_time() { + curr_time = 0.0f; + delta_time = 0.0f; + + x_pv_bar_beat_data* d = data.data(); + const size_t size = data.size(); + + size_t length = size; + size_t temp; + while (length > 0) + if (d[temp = length / 2].compare_bar_time_less(next_bar_time)) + length = temp; + else { + d += temp + 1; + length -= temp + 1; + } + + float_t next_bar_time; + if (d == data.data() + data.size()) { + float_t v9 = 0.0f; + float_t v10 = divisor; + if (data.size()) + v9 = data.back().bar_time; + + next_bar_time = (float_t)((int32_t)((-v9) / v10) + 1) * v10 + v9; + if (next_bar_time < 0.00001f) + next_bar_time += v10; + } + else + next_bar_time = d->bar_time; + + curr_bar_time = 0.0f; + this->next_bar_time = next_bar_time; + curr_beat_time = 0.0f; + next_beat_time = get_next_beat_time(0.0f); + bar = 1; + field_20 = 0; +} + +void x_pv_bar_beat::set_frame(float_t curr_frame, float_t delta_frame) { + set_time(curr_frame * (float_t)(1.0 / 60.0), delta_frame * (float_t)(1.0 / 60.0)); +} + +void x_pv_bar_beat::set_time(float_t curr_time, float_t delta_time) { + if (next_bar_time <= 0.0f) + return; + + this->curr_time = curr_time; + this->delta_time = delta_time; + field_20 = 0; + + float_t next_bar_time = this->next_bar_time; + while (curr_time >= next_bar_time) { + curr_bar_time = next_bar_time; + bar++; + field_20++; + + x_pv_bar_beat_data* d = data.data(); + const size_t size = data.size(); + + size_t length = size; + size_t temp; + while (length > 0) + if (d[temp = length / 2].compare_bar_time_less(next_bar_time)) + length = temp; + else { + d += temp + 1; + length -= temp + 1; + } + + if (d == data.data() + data.size()) { + float_t v11 = 0.0f; + float_t v12 = divisor; + if (data.size()) + v11 = data.back().bar_time; + + float_t _next_bar_time = (float_t)((int32_t)((next_bar_time - v11) / v12) + 1) * v12 + v11; + if (_next_bar_time < next_bar_time + 0.00001f) + _next_bar_time += v12; + next_bar_time = _next_bar_time; + } + else + next_bar_time = d->bar_time; + this->next_bar_time = next_bar_time; + } + + while (curr_time >= next_beat_time) { + curr_beat_time = next_beat_time; + next_beat_time = get_next_beat_time(next_beat_time); + } +} + +BPMFrameRateControl::BPMFrameRateControl() : bar_beat() { + +} + +BPMFrameRateControl::~BPMFrameRateControl() { + +} + +float_t BPMFrameRateControl::GetDeltaFrame() { + if (bar_beat) + return bar_beat->get_delta_frame(); + return 0.0f; +} + +void BPMFrameRateControl::Reset() { + bar_beat = 0; + SetFrameSpeed(1.0f); +} + +x_pv_game_glitter::x_pv_game_glitter(const char* name) { + this->name = name; + hash = (uint32_t)Glitter::glt_particle_manager + .LoadFile(Glitter::X, &data_list[DATA_X], name, 0, -1.0f, false, 0); +} + +x_pv_game_glitter::~x_pv_game_glitter() { + Glitter::glt_particle_manager.UnloadEffectGroup(hash); +} + +x_struc_104::x_struc_104() : rob_chr(), current_time(), +duration(), start_pos(), end_pos(), start_rot(), end_rot() { + mot_smooth_len = 12.0f; +} + +x_struc_104::~x_struc_104() { + +} + +void x_struc_104::reset() { + rob_chr = 0; + current_time = 0.0f; + duration = 0.0f; + start_pos = vec3_null; + end_pos = vec3_null; + start_rot = 0.0f; + end_rot = 0.0f; + mot_smooth_len = 12.0f; + set_motion.clear(); + set_motion.shrink_to_fit(); + set_item.clear(); + set_item.shrink_to_fit(); +} + +x_pv_play_data::x_pv_play_data() : rob_chr(), disp() { + +} + +x_pv_play_data::~x_pv_play_data() { + +} + +void x_pv_play_data::reset() { + motion.clear(); + motion.shrink_to_fit(); + rob_chr = 0; + set_motion.clear(); + disp = true; + field_38.reset(); +} + x_pv_game_a3da_to_mot_keys::x_pv_game_a3da_to_mot_keys() { } @@ -278,7 +567,7 @@ x_pv_game_a3da_to_mot::~x_pv_game_a3da_to_mot() { static int32_t get_bone_index(auth_3d_object_hrc* oh, const char* name) { uint32_t name_hash = hash_utf8_murmurhash(name); for (auth_3d_object_node& i : oh->node) - if (hash_string_murmurhash(&i.name) == name_hash) + if (hash_string_murmurhash(i.name) == name_hash) return (int32_t)(&i - oh->node.data()); return -1; } @@ -352,9 +641,7 @@ pv_end(), playdata(), scene_rot_y(), branch_mode(), pause(), step_frame(), stage camera_auth_3d_id = -1; target_anim_fps = 60.0f; anim_frame_speed = 1.0f; - scene_rot_mat = mat4u_identity; - prev_bar_point_time = -1; - prev_bpm = -1; + scene_rot_mat = mat4_identity; } x_pv_game::~x_pv_game() { @@ -376,6 +663,8 @@ bool x_pv_game::Ctrl() { if (rob_chara_ids[i] != -1) wait_load |= !task_rob_manager_check_chara_loaded(rob_chara_ids[i]); + wait_load |= pv_expression_file_check_not_ready(); + if (!wait_load) state = 2; } break; @@ -471,7 +760,7 @@ bool x_pv_game::Ctrl() { } for (std::string i : pv_auth_3d_names) { - uint32_t hash = hash_string_murmurhash(&i); + uint32_t hash = hash_string_murmurhash(i); int32_t id = auth_3d_data_load_hash(hash, pv_category_hash, pv_category.c_str(), x_data, &obj_db, &tex_db); auth_3d_data_read_file_modern(&id); @@ -481,7 +770,7 @@ bool x_pv_game::Ctrl() { } for (std::string i : stage_auth_3d_names) { - uint32_t hash = hash_string_murmurhash(&i); + uint32_t hash = hash_string_murmurhash(i); int32_t id = auth_3d_data_load_hash(hash, stage_category_hash, stage_category.c_str(), x_data, &obj_db, &tex_db); auth_3d_data_read_file_modern(&id); @@ -499,7 +788,7 @@ bool x_pv_game::Ctrl() { sprintf_s(buf, sizeof(buf), "STGPV%03d_EFF_LT_000", pv_id); uint32_t light_auth_3d_hash = hash_utf8_murmurhash(buf); for (auth_3d_database_uid& i : auth_3d_db->uid) - if (hash_string_murmurhash(&i.name) == light_auth_3d_hash) { + 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); auth_3d_data_read_file(&light_auth_3d_id, auth_3d_db); @@ -525,7 +814,7 @@ bool x_pv_game::Ctrl() { } for (auto i : effchrpv_auth_3d_names) { - uint32_t hash = hash_string_murmurhash(&i.first); + uint32_t hash = hash_string_murmurhash(i.first); int32_t id = auth_3d_data_load_hash(hash, i.second.first, i.second.second.c_str(), x_data, &obj_db, &tex_db); auth_3d_data_read_file_modern(&id); @@ -535,7 +824,7 @@ bool x_pv_game::Ctrl() { } for (auto i : effchrpv_auth_3d_mot_names) { - uint32_t hash = hash_string_murmurhash(&i.first); + uint32_t hash = hash_string_murmurhash(i.first); int32_t id = auth_3d_data_load_hash(hash, i.second.first, i.second.second.c_str(), x_data, &obj_db, &tex_db); auth_3d_data_read_file_modern(&id); @@ -638,6 +927,9 @@ bool x_pv_game::Ctrl() { std::vector> bar_frames; std::vector state_vec; + x_pv_bar_beat_data* bar_beat_data = 0; + int32_t beat_counter = 0; + int32_t time = -1; int32_t frame = -1; int32_t prev_stage_effect = -1; @@ -652,7 +944,7 @@ bool x_pv_game::Ctrl() { if (state[chara_id].disp && i.disp_time == time && i.set_motion_time != time) state_vec.push_back(i); time = (int32_t)data[0]; - frame = (int32_t)roundf((float_t)time * (float_t)(60.0f / 100000.0f)); + frame = (int32_t)roundf((float_t)time * (float_t)(60.0 / 100000.0)); } break; case DSC_X_MIKU_DISP: { int32_t chara_id = (int32_t)data[0]; @@ -666,10 +958,24 @@ bool x_pv_game::Ctrl() { state[chara_id].set_motion_data_offset = i.data_offset; } break; case DSC_X_BAR_POINT: { + bar_beat.data.push_back({}); + bar_beat_data = &bar_beat.data.back(); + *bar_beat_data = {}; + bar_beat_data->bar = (int32_t)data[0]; + bar_beat_data->bar_time = (float_t)time * (float_t)(1.0 / 100000.0); + bar_beat_data->beat_counter = beat_counter; + int32_t bar = data[0]; if (bar % 2) bar_frames.push_back({ frame, bar }); } break; + case DSC_X_BEAT_POINT: { + if (!bar_beat_data) + break; + + bar_beat_data->beat_counter = ++beat_counter; + bar_beat_data->beat_time[bar_beat_data->beat_count++] = (float_t)time * (float_t)(1.0 / 100000.0); + } break; case DSC_X_STAGE_EFFECT: { int32_t stage_effect = (int32_t)data[0]; stage_effect--; @@ -678,35 +984,24 @@ bool x_pv_game::Ctrl() { break; int32_t bar_count = 2; - pvsr_stage_effect& effect = sr->stage_effect[stage_effect]; - if (effect.bar_count && effect.bar_count != 0xFF) - bar_count = effect.bar_count; - - int32_t bar_count_change = 2; if (prev_stage_effect != -1) { - if (sr->stage_change_effect_init[prev_stage_effect][stage_effect]) { - pvsr_stage_effect& effect = sr->stage_change_effect[prev_stage_effect][stage_effect]; - if (effect.bar_count && effect.bar_count != 0xFF) - bar_count_change = effect.bar_count; - } - else { - pvsr_stage_effect& effect = sr->stage_effect[prev_stage_effect]; - if (effect.bar_count && effect.bar_count != 0xFF) - bar_count_change = effect.bar_count; + if (sr->stage_change_effect[prev_stage_effect][stage_effect].enable) { + pvsr_stage_change_effect& change_effect = sr->stage_change_effect[prev_stage_effect][stage_effect]; + if (change_effect.bar_count > 0) + bar_count = change_effect.bar_count / 2; } } - bar_count_change /= 2; int32_t stage_effect_frame = frame; int32_t bar = 1; for (std::pair& i : bar_frames) - if (&i - bar_frames.data() >= bar_count_change && frame >= i.first) { - stage_effect_frame = (&i)[-bar_count_change].first; - bar = (&i)[-bar_count_change].second; + if (&i - bar_frames.data() >= (bar_count / 2) && frame >= i.first) { + stage_effect_frame = (&i)[-(bar_count / 2)].first; + bar = (&i)[-(bar_count / 2)].second; } stage_effects.push_back({ stage_effect_frame, - stage_effect, bar_count + bar_count_change, bar }); + stage_effect, bar_count, bar }); prev_stage_effect = stage_effect; } break; case DSC_X_SONG_EFFECT_ATTACH: { @@ -773,6 +1068,8 @@ bool x_pv_game::Ctrl() { free(data);*/ } + pv_expression_array_reset(); + for (int32_t i = 0; i < ROB_CHARA_COUNT; i++) { playdata[i].reset(); if (rob_chara_ids[i] == -1) @@ -783,7 +1080,7 @@ bool x_pv_game::Ctrl() { playdata[i].rob_chr = rob_chr; rob_chr->frame_speed = anim_frame_speed; rob_chr->data.motion.step_data.step = anim_frame_speed; - //sub_1404F3000(i, rob_chr, anim_frame_speed); + pv_expression_array_reset_data(i, rob_chr, anim_frame_speed); } sub_140122770(this, i); sub_140121A80(this, i); @@ -803,9 +1100,6 @@ bool x_pv_game::Ctrl() { extern float_t frame_speed; frame_speed = 1.0f; - prev_bar_point_time = -1; - prev_bpm = -1; - pause = false; step_frame = false; @@ -814,10 +1108,15 @@ bool x_pv_game::Ctrl() { stage_effect.prev_stage_effect = -1; stage_effect.stage_effect = -1; stage_effect.next_stage_effect = -1; + stage_effect.bar_count = 1; + + frame_float = 0.0f; + this->frame = (int32_t)frame_float; + this->time = (int64_t)round(frame_float * (100000.0 / 60.0) * 10000.0); + + bar_beat.reset_time(); + frame_rate_control.bar_beat = &bar_beat; - frame_float = -1.0f; - this->frame = -1; - this->time = (int64_t)round(-(100000.0 / 60.0) * 10000.0); while (dsc_data_ptr != dsc_data_ptr_end && x_pv_game_dsc_process(this, this->time)) dsc_data_ptr++; @@ -831,19 +1130,35 @@ bool x_pv_game::Ctrl() { 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_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_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); + 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) { + rob_chara* rob_chr = rob_chara_array_get(rob_chara_ids[i]); + if (!rob_chr) + continue; + + rob_chr->reset_data(&rob_chr->pv_data, aft_bone_data, aft_mot_db); + rob_chr->set_hand_l_mottbl_motion(0, 194, 1.0f, 0, 0.0f, 0.0f, 1.0f, -1, 0.0f, aft_mot_db); + rob_chr->set_hand_r_mottbl_motion(0, 194, 1.0f, 0, 0.0f, 0.0f, 1.0f, -1, 0.0f, aft_mot_db); + rob_chr->set_visibility(true); + } + 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); @@ -859,7 +1174,7 @@ bool x_pv_game::Ctrl() { bool found = false; for (auto j : effchrpv_auth_3d_names) if (j.second.first == hash) { - uint32_t hash = hash_string_murmurhash(&j.first); + uint32_t hash = hash_string_murmurhash(j.first); effchrpv_auth_3d_rob_mot_ids.insert({ i, { effchrpv_auth_3d_ids[hash] } }); found = true; break; @@ -870,7 +1185,7 @@ bool x_pv_game::Ctrl() { for (auto j : effchrpv_auth_3d_mot_names) if (j.second.first == hash) { - uint32_t hash = hash_string_murmurhash(&j.first); + uint32_t hash = hash_string_murmurhash(j.first); effchrpv_auth_3d_rob_mot_ids.insert({ i, { effchrpv_auth_3d_mot_ids[hash] } }); break; } @@ -889,13 +1204,12 @@ bool x_pv_game::Ctrl() { auth_3d_data_set_paused(&id, false); auth_3d_data_set_visibility(&id, true); auth_3d_data_set_req_frame(&id, -2.0f); - auth_3d_data_set_frame_rate(&id, &diva_pv_frame_rate); } } if (pv_id == 826) { extern int32_t global_ctrl_frames; - global_ctrl_frames = 5111; + global_ctrl_frames = 5110; } else if (pv_id == 822) { extern int32_t global_ctrl_frames; @@ -905,23 +1219,13 @@ bool x_pv_game::Ctrl() { pause = true; } break; case 10: { - if (step_frame) - if (pause) - pause = false; - else { - pause = true; - step_frame = false; - } - - Glitter::glt_particle_manager.SetPause(pause); - extern float_t frame_speed; - frame_speed = pause ? 0.0f : 1.0f; - float_t delta_frame = get_delta_frame(); frame_float += delta_frame; frame = (int32_t)frame_float; time = (int64_t)round(frame_float * (100000.0 / 60.0) * 10000.0); + bar_beat.set_frame((float_t)frame_float, delta_frame); + if (pv_id == 826 && frame == 5110) pause = true; else if (pv_id == 822 && frame == 3600) @@ -935,7 +1239,7 @@ bool x_pv_game::Ctrl() { && x_pv_game_stage_effects_process(this, this->frame)) stage_effects_ptr++; - stage_effect.frame += diva_stage_frame_rate.GetDeltaFrame(); + stage_effect.frame += frame_rate_control.GetDeltaFrame(); x_pv_game_stage_effect_ctrl(this); if (pv_id == 826) @@ -952,12 +1256,6 @@ bool x_pv_game::Ctrl() { return false; } -void x_pv_game::Disp() { - if (state != 10) - return; - -} - bool x_pv_game::Dest() { Unload(); task_stage_modern_unload(); @@ -976,6 +1274,29 @@ bool x_pv_game::Dest() { return true; } +void x_pv_game::Disp() { + if (state != 10) + return; + +} + +void x_pv_game::Basic() { + if (state != 10) + return; + + if (step_frame) + if (pause) + pause = false; + else { + pause = true; + step_frame = false; + } + + Glitter::glt_particle_manager.SetPause(pause); + extern float_t frame_speed; + frame_speed = pause ? 0.0f : 1.0f; +} + void x_pv_game::Window() { if (state != 10) return; @@ -990,8 +1311,10 @@ void x_pv_game::Window() { step_frame = true; } - if (!pause) + if (!pause) { + Basic(); return; + } ImGuiIO& io = ImGui::GetIO(); ImGuiStyle& style = ImGui::GetStyle(); @@ -1050,9 +1373,11 @@ void x_pv_game::Window() { extern bool input_locked; input_locked |= ImGui::IsWindowFocused(); ImGui::End(); + + Basic(); } -void x_pv_game::Load(int32_t pv_id, int32_t stage_id, chara_index charas[6], int32_t modules[6]) { +void x_pv_game::Load(int32_t pv_id, int32_t stage_id, ::chara_index charas[6], int32_t modules[6]) { data_struct* aft_data = &data_list[DATA_AFT]; motion_database* aft_mot_db = &aft_data->data_ft.mot_db; @@ -1076,7 +1401,22 @@ void x_pv_game::Load(int32_t pv_id, int32_t stage_id, chara_index charas[6], int motion_set_load_motion(mot_set, 0, aft_mot_db); motion_set_load_mothead(mot_set, 0, aft_mot_db); + sprintf_s(buf, sizeof(buf), "exp_PV%03d", pv_id); + pv_expression_file_load(x_data, "root+/pv_expression/", hash_utf8_murmurhash(buf)); + char file_buf[0x200]; + for (int32_t i = 1; i <= 32; i++) { + sprintf_s(file_buf, sizeof(file_buf), "pv%03d.pvpp", 800 + i); + pvpp* pp = new pvpp; + x_data->load_file(pp, "root+/pv/", file_buf, pvpp::load_file); + delete pp; + + sprintf_s(file_buf, sizeof(file_buf), "stgpv%03d_param.pvsr", i); + pvsr* sr = new pvsr; + x_data->load_file(sr, "root+/pv_stage_rsrc/", file_buf, pvsr::load_file); + delete sr; + } + sprintf_s(file_buf, sizeof(file_buf), "pv%03d.pvpp", pv_id); pp = new pvpp; x_data->load_file(pp, "root+/pv/", file_buf, pvpp::load_file); @@ -1085,9 +1425,13 @@ void x_pv_game::Load(int32_t pv_id, int32_t stage_id, chara_index charas[6], int sr = new pvsr; x_data->load_file(sr, "root+/pv_stage_rsrc/", file_buf, pvsr::load_file); - sprintf_s(file_buf, sizeof(file_buf), "pv_stgpv%03d.stg", stage_id); - stage_data.modern = true; - x_data->load_file(&stage_data, "root+/stage/", file_buf, stage_database::load_file); + { + sprintf_s(file_buf, sizeof(file_buf), "pv_stgpv%03d.stg", stage_id); + stage_database_file stage_data_file; + stage_data_file.modern = true; + x_data->load_file(&stage_data_file, "root+/stage/", file_buf, stage_database_file::load_file); + stage_data.add(&stage_data_file); + } sprintf_s(file_buf, sizeof(file_buf), "eff_pv%03d_main", pv_id); pv_glitter = new x_pv_game_glitter(file_buf); @@ -1097,34 +1441,34 @@ void x_pv_game::Load(int32_t pv_id, int32_t stage_id, chara_index charas[6], int sprintf_s(buf, sizeof(buf), "A3D_EFFPV%03d", pv_id); pv_category = buf; - pv_category_hash = hash_string_murmurhash(&pv_category); + pv_category_hash = hash_string_murmurhash(pv_category); category_load.push_back({ pv_category, pv_category_hash }); pv_auth_3d_names.clear(); for (pvpp_effect i : pp->effect) - for (pvpp_a3da j : i.a3da) { + for (pvpp_auth_3d j : i.auth_3d) { if (pv_auth_3d_names.find(j.name) == pv_auth_3d_names.end()) pv_auth_3d_names.insert(j.name); } sprintf_s(buf, sizeof(buf), "EFFSTGPV%03d", stage_id); stage_category = buf; - stage_category_hash = hash_string_murmurhash(&stage_category); + stage_category_hash = hash_string_murmurhash(stage_category); category_load.push_back({ stage_category, stage_category_hash }); stage_auth_3d_names.clear(); for (pvsr_stage_effect i : sr->stage_effect) - for (pvsr_a3da j : i.a3da) + for (pvsr_auth_3d j : i.auth_3d) if (stage_auth_3d_names.find(j.name) == stage_auth_3d_names.end()) stage_auth_3d_names.insert(j.name); for (int32_t i = 0; i < PVSR_STAGE_CHANGE_EFFECT_COUNT; i++) for (int32_t j = 0; j < PVSR_STAGE_CHANGE_EFFECT_COUNT; j++) { - if (!sr->stage_change_effect_init[i][j]) + if (!sr->stage_change_effect[i][j].enable) continue; - pvsr_stage_effect& stage_effect = sr->stage_change_effect[i][j]; - for (pvsr_a3da k : stage_effect.a3da) + pvsr_stage_change_effect& stage_change_effect = sr->stage_change_effect[i][j]; + for (pvsr_auth_3d k : stage_change_effect.auth_3d) if (stage_auth_3d_names.find(k.name) == stage_auth_3d_names.end()) stage_auth_3d_names.insert(k.name); } @@ -1134,7 +1478,7 @@ void x_pv_game::Load(int32_t pv_id, int32_t stage_id, chara_index charas[6], int sprintf_s(buf, sizeof(buf), "CAMPV%03d", pv_id); camera_category = buf; - camera_category_hash = hash_string_murmurhash(&camera_category); + camera_category_hash = hash_string_murmurhash(camera_category); category_load.push_back({ camera_category, camera_category_hash }); int32_t chara_index = 0; @@ -1152,8 +1496,8 @@ void x_pv_game::Load(int32_t pv_id, int32_t stage_id, chara_index charas[6], int const char* dst_name = chara_index_get_auth_3d_name(charas[chara_index++]); const char* mik_name = chara_index_get_auth_3d_name(CHARA_MIKU); - for (pvpp_chara_effect_a3da& j : i.chara_effect.effect_a3da) { - std::string name = j.a3da.name; + for (pvpp_chara_effect_auth_3d& j : i.chara_effect.effect_auth_3d) { + std::string name = j.auth_3d.name; if (name.find(src_name) == std::string::npos) { size_t pos = name.find(dst_name); if (pos != std::string::npos) @@ -1162,24 +1506,24 @@ void x_pv_game::Load(int32_t pv_id, int32_t stage_id, chara_index charas[6], int if (pv_id != 826) { std::string category = "A3D_" + name; - uint32_t category_hash = hash_string_murmurhash(&category); + uint32_t category_hash = hash_string_murmurhash(category); category_load.push_back({ category, category_hash }); if (effchrpv_auth_3d_names.find(name) == effchrpv_auth_3d_names.end()) effchrpv_auth_3d_names.insert({ name, { category_hash, category } }); - effchrpv_auth_3d_hashes.insert({ j.a3da.hash, hash_string_murmurhash(&name) }); + effchrpv_auth_3d_hashes.insert({ j.auth_3d.hash, hash_string_murmurhash(name) }); } else { sprintf_s(buf, sizeof(buf), "EFFCHRPV%03d", pv_id); - if (j.a3da.name.find(buf) == std::string::npos) + if (j.auth_3d.name.find(buf) == std::string::npos) continue; - name = j.a3da.name; + name = j.auth_3d.name; name.replace(utf8_length(buf), utf8_length(mik_name), mik_name, utf8_length(mik_name)); std::string category = "A3D_" + name; - uint32_t category_hash = hash_string_murmurhash(&category); + uint32_t category_hash = hash_string_murmurhash(category); effchrpv_category_load.push_back({ category, category_hash }); effchrpv_auth_3d_mot_names.insert({ name, { category_hash, category } }); @@ -1203,12 +1547,9 @@ void x_pv_game::Load(int32_t pv_id, int32_t stage_id, chara_index charas[6], int for (x_pv_play_data& i : playdata) i.reset(); scene_rot_y = 0.0f; - scene_rot_mat = mat4u_identity; + scene_rot_mat = mat4_identity; branch_mode = 0; - prev_bar_point_time = -1; - prev_bpm = -1; - pause = false; step_frame = false; @@ -1254,20 +1595,20 @@ void x_pv_game::Load(int32_t pv_id, int32_t stage_id, chara_index charas[6], int const char* src_name = chara_index_get_auth_3d_name((::chara_index)i.chara_effect.base_chara); const char* dst_name = chara_index_get_auth_3d_name(charas[chara_index++]); - for (pvpp_chara_effect_a3da& j : i.chara_effect.effect_a3da) { - std::string name = j.has_object_set ? j.object_set.name : j.a3da.name; + for (pvpp_chara_effect_auth_3d& j : i.chara_effect.effect_auth_3d) { + std::string name = j.has_object_set ? j.object_set.name : j.auth_3d.name; if (name.find(src_name) == std::string::npos) { size_t pos = name.find(dst_name); if (pos != std::string::npos) name.replace(pos, utf8_length(dst_name), src_name, utf8_length(src_name)); } - objset_load.push_back(hash_string_murmurhash(&name)); + objset_load.push_back(hash_string_murmurhash(name)); - std::string nam = j.has_object_set ? j.object_set.name : j.a3da.name; + std::string nam = j.has_object_set ? j.object_set.name : j.auth_3d.name; nam.replace(utf8_length(buf), utf8_length(dst_name), dst_name, utf8_length(dst_name)); if (nam != name) - objset_load.push_back(hash_string_murmurhash(&nam)); + objset_load.push_back(hash_string_murmurhash(nam)); } } @@ -1278,16 +1619,9 @@ void x_pv_game::Load(int32_t pv_id, int32_t stage_id, chara_index charas[6], int this->frame = 0; frame_float = 0.0; time = 0; - diva_stage_frame_rate.SetFrameSpeed(1.0f); - obj_db.ready = true; - obj_db.modern = true; - obj_db.is_x = true; obj_db.object_set.clear(); obj_db.object_set.shrink_to_fit(); - tex_db.ready = true; - tex_db.modern = true; - tex_db.is_x = true; tex_db.texture.clear(); tex_db.texture.shrink_to_fit(); @@ -1301,6 +1635,9 @@ void x_pv_game::Load(int32_t pv_id, int32_t stage_id, chara_index charas[6], int dsc_data_ptr = 0; dsc_data_ptr_end = 0; + bar_beat.reset(); + frame_rate_control.Reset(); + stage_effects.clear(); stage_effects.shrink_to_fit(); stage_effects_ptr = 0; @@ -1533,6 +1870,11 @@ void x_pv_game::Unload() { data_struct* aft_data = &data_list[DATA_AFT]; motion_database* aft_mot_db = &aft_data->data_ft.mot_db; + for (int32_t i = 0; i < ROB_CHARA_COUNT; i++) + pv_expression_array_reset_motion(i); + + pv_expression_file_unload(); + char buf[0x200]; sprintf_s(buf, sizeof(buf), "PV%03d", pv_id); uint32_t mot_set = aft_mot_db->get_motion_set_id(buf); @@ -1558,20 +1900,10 @@ void x_pv_game::Unload() { pv_glitter = 0; stage_glitter = 0; - obj_db.ready = false; - obj_db.modern = false; - obj_db.is_x = false; obj_db.object_set.clear(); obj_db.object_set.shrink_to_fit(); - tex_db.ready = false; - tex_db.modern = false; - tex_db.is_x = false; tex_db.texture.clear(); tex_db.texture.shrink_to_fit(); - stage_data.ready = false; - stage_data.modern = false; - stage_data.is_x = false; - stage_data.format = STAGE_DATA_UNK; stage_data.stage_data.clear(); stage_data.stage_data.shrink_to_fit(); stage_data.stage_modern.clear(); @@ -1668,6 +2000,8 @@ void x_pv_game::Unload() { dsc_data_ptr = 0; dsc_data_ptr_end = 0; + bar_beat.reset(); + stage_effects.clear(); stage_effects.shrink_to_fit(); stage_effects_ptr = 0; @@ -1688,129 +2022,17 @@ void x_pv_game::Unload() { for (x_pv_play_data& i : playdata) i.reset(); scene_rot_y = 0.0f; - scene_rot_mat = mat4u_identity; + scene_rot_mat = mat4_identity; branch_mode = 0; Glitter::glt_particle_manager.draw_all = true; pv_param_task::post_process_task.SetDest(); } -x_pv_game_glitter::x_pv_game_glitter(const char* name) { - this->name = name; - hash = (uint32_t)Glitter::glt_particle_manager - .LoadFile(Glitter::X, &data_list[DATA_X], name, 0, -1.0f, false, 0); -} - -x_pv_game_glitter::~x_pv_game_glitter() { - Glitter::glt_particle_manager.UnloadEffectGroup(hash); -} - -x_struc_104::x_struc_104() : rob_chr(), current_time(), -duration(), start_pos(), end_pos(), start_rot(), end_rot() { - mot_smooth_len = 12.0f; -} - -x_struc_104::~x_struc_104() { - -} - -void x_struc_104::reset() { - rob_chr = 0; - current_time = 0.0f; - duration = 0.0f; - start_pos = vec3_null; - end_pos = vec3_null; - start_rot = 0.0f; - end_rot = 0.0f; - mot_smooth_len = 12.0f; - set_motion.clear(); - set_motion.shrink_to_fit(); - set_item.clear(); - set_item.shrink_to_fit(); -} - -x_pv_play_data::x_pv_play_data() : rob_chr(), disp() { - -} - -x_pv_play_data::~x_pv_play_data() { - -} - -void x_pv_play_data::reset() { - motion.clear(); - motion.shrink_to_fit(); - rob_chr = 0; - set_motion.clear(); - disp = true; - field_38.reset(); -} - static float_t dsc_time_to_frame(int64_t time) { return (float_t)time / 1000000000.0f * 60.0f; } -static int32_t expression_id_to_mottbl_index(int32_t expression_id) { - static const int32_t expression_id_to_mottbl_index_table[] = { - 11, 15, 57, 19, 23, 25, 29, 33, - 37, 41, 45, 49, 53, 65, 7, 69, - 73, 77, 81, 85, 89, 7, 61, 6, - 214, 215, 216, 217, 218, 219, 220, 221, - 222, 223, 93, 95, 97, 99, 101, 103, - 105, 107, 109, 111, 113, 115, 117, 119, - 121, 123, 125, 127, 13, 21, 31, 39, - 43, 47, 51, 55, 67, 71, 79, 83, - 129, 59, 17, 91, 27, 87, 35, 75, - 9, 63, 236, 238, 240, 242, - }; - - if (expression_id >= 0 && expression_id - < sizeof(expression_id_to_mottbl_index_table) / sizeof(int32_t)) - return expression_id_to_mottbl_index_table[expression_id]; - return 6; -} - -static int32_t hand_anim_id_to_mottbl_index(int32_t hand_anim_id) { - static const int32_t hand_anim_id_to_mottbl_index_table[] = { - 195, 196, 194, 197, 201, 198, 199, 202, - 203, 192, 200, 204, 204, 204, 193, - }; - - if (hand_anim_id >= 0 && hand_anim_id - < sizeof(hand_anim_id_to_mottbl_index_table) / sizeof(int32_t)) - return hand_anim_id_to_mottbl_index_table[hand_anim_id]; - return 192; -} - -static int32_t look_anim_id_to_mottbl_index(int32_t look_anim_id) { - static const int32_t look_anim_id_to_mottbl_index_table[] = { - 168, 170, 174, 172, 178, 176, 182, 180, - 166, 165, 224, 169, 171, 175, 173, 179, - 177, 183, 181, 167, - }; - - if (look_anim_id >= 0 && look_anim_id - < sizeof(look_anim_id_to_mottbl_index_table) / sizeof(int32_t)) - return look_anim_id_to_mottbl_index_table[look_anim_id]; - return 165; -} - -static int32_t mouth_anim_id_to_mottbl_index(int32_t mouth_anim_id) { - static const int32_t mouth_anim_id_to_mottbl_index_table[] = { - 134, 140, 142, 146, 144, 148, 150, 152, - 132, 131, 136, 138, 154, 155, 156, 157, - 158, 159, 160, 161, 162, 163, 164, 151, - 135, 143, 147, 145, 133, 137, 139, 141, - 149, 153, 244, 245, 246, 247, 248, 249, - 250, 251, 252, - }; - - if (mouth_anim_id >= 0 && mouth_anim_id - < sizeof(mouth_anim_id_to_mottbl_index_table) / sizeof(int32_t)) - return mouth_anim_id_to_mottbl_index_table[mouth_anim_id]; - return 131; -} - static void sub_140122B60(x_pv_game* a1, int32_t chara_id, int32_t motion_index, int64_t disp_time) { if (chara_id < 0 || chara_id > ROB_CHARA_COUNT || motion_index < 0) return; @@ -1877,9 +2099,8 @@ static bool x_pv_game_dsc_process(x_pv_game* a1, int64_t curr_time) { if (!rob_chr) break; - mat4 scene_rot_mat = a1->scene_rot_mat; - mat4_mult_vec3_trans(&scene_rot_mat, &trans, &trans); - rob_chr->data.miku_rot.position = trans; + mat4_mult_vec3_trans(&a1->scene_rot_mat, + &trans, &rob_chr->data.miku_rot.position); rob_chr->set_osage_reset(); } break; case DSC_X_MIKU_ROT: { @@ -1926,8 +2147,8 @@ static bool x_pv_game_dsc_process(x_pv_game* a1, int64_t curr_time) { rob_chr->set_motion_reset_data(i.motion_id, i.dsc_frame); rob_chr->bone_data->disable_eye_motion = i.disable_eye_motion; rob_chr->data.motion.step_data.step = i.frame_speed; - //if (v45) - // pv_expression_array_set_motion(a1->chara_id, i.motion_id); + if (v45) + pv_expression_array_set_motion(a1->chara_id, i.motion_id); //if (!a1->pv_game->data.pv->disable_calc_motfrm_limit) sub_140122B60(a1, a1->chara_id, i.motion_index, i.dsc_time); } @@ -2074,8 +2295,8 @@ static bool x_pv_game_dsc_process(x_pv_game* a1, int64_t curr_time) { rob_chr->set_motion_skin_param(motion_id, dsc_frame); rob_chr->bone_data->disable_eye_motion = true; rob_chr->data.motion.step_data.step = v519.frame_speed; - //if (v84) - // pv_expression_array_set_motion(a1->chara_id, motion_id); + if (v84) + pv_expression_array_set_motion(a1->chara_id, motion_id); //if (!a1->pv_game->data.pv->disable_calc_motfrm_limit) sub_140122B60(a1, a1->chara_id, motion_index, v56 ? v56->time : 0); } @@ -2412,11 +2633,7 @@ static bool x_pv_game_dsc_process(x_pv_game* a1, int64_t curr_time) { } break; case DSC_X_BAR_TIME_SET: { - int32_t bpm = (int32_t)data[0]; - if (bpm != a1->prev_bpm) - diva_stage_frame_rate.SetFrameSpeed((float_t)bpm / 120.0f); - a1->prev_bpm = bpm; - a1->prev_bar_point_time = a1->dsc_time; + } break; case DSC_X_SHADOWHEIGHT: { a1->chara_id = data[0]; @@ -2677,8 +2894,7 @@ static bool x_pv_game_dsc_process(x_pv_game* a1, int64_t curr_time) { if (!rob_chr) break; - mat4 scene_rot_mat = a1->scene_rot_mat; - mat4_mult_vec3_trans(&scene_rot_mat, &pos, &pos); + mat4_mult_vec3_trans(&a1->scene_rot_mat, &pos, &pos); rob_chr->set_chara_pos_adjust(&pos); /*if (rob_chara_check_for_ageageagain_module(rob_chr->chara_index, rob_chr->module_index)) { @@ -2690,9 +2906,7 @@ static bool x_pv_game_dsc_process(x_pv_game* a1, int64_t curr_time) { float_t scene_rot_y = (float_t)(int32_t)data[0] * 0.001f; a1->scene_rot_y = scene_rot_y; - mat4 scene_rot_mat = a1->scene_rot_mat; - mat4_rotate_y(scene_rot_y * DEG_TO_RAD_FLOAT, &scene_rot_mat); - a1->scene_rot_mat = scene_rot_mat; + mat4_rotate_y(scene_rot_y * DEG_TO_RAD_FLOAT, &a1->scene_rot_mat); } break; case DSC_X_EDIT_MOT_SMOOTH_LEN: { @@ -2801,14 +3015,7 @@ static bool x_pv_game_dsc_process(x_pv_game* a1, int64_t curr_time) { } break; case DSC_X_BAR_POINT: { - if (a1->prev_bar_point_time != -1) { - float_t frame_speed = 200000.0f / ((float_t)(a1->dsc_time - a1->prev_bar_point_time) / 10000.0f); - int32_t bpm = (int32_t)roundf(frame_speed * 120.0f); - if (bpm != a1->prev_bpm) - diva_stage_frame_rate.SetFrameSpeed((float_t)bpm / 120.0f); - a1->prev_bpm = bpm; - } - a1->prev_bar_point_time = a1->dsc_time; + } break; case DSC_X_BEAT_POINT: { @@ -2922,7 +3129,7 @@ static bool x_pv_game_dsc_process(x_pv_game* a1, int64_t curr_time) { if (effect_id >= 7 && effect_id <= 8) { pvsr_stage_effect& effect = a1->sr->stage_effect[effect_id]; - for (pvsr_a3da& i : effect.a3da) { + for (pvsr_auth_3d& i : effect.auth_3d) { int32_t& id = a1->stage_auth_3d_ids[i.hash]; auth_3d_data_set_camera_root_update(&id, false); auth_3d_data_set_enable(&id, true); @@ -2930,16 +3137,15 @@ static bool x_pv_game_dsc_process(x_pv_game* a1, int64_t curr_time) { 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, &diva_stage_frame_rate); } for (pvsr_glitter& i : effect.glitter) { - uint32_t effect_hash = hash_string_murmurhash(&i.name); + uint32_t effect_hash = hash_string_murmurhash(i.name); Glitter::glt_particle_manager.LoadScene(hash_murmurhash_empty, effect_hash); Glitter::glt_particle_manager.SetSceneName(hash, a1->stage_glitter->name.c_str()); Glitter::glt_particle_manager.SetSceneEffectName( hash_murmurhash_empty, effect_hash, i.name.c_str()); - Glitter::glt_particle_manager.SetSceneFrameRate(hash, &diva_stage_frame_rate); + Glitter::glt_particle_manager.SetSceneFrameRate(hash, &a1->frame_rate_control); } } } break; @@ -2954,7 +3160,7 @@ static bool x_pv_game_dsc_process(x_pv_game* a1, int64_t curr_time) { pvpp_effect& effect = a1->pp->effect[effect_id]; if (enable) { - for (pvpp_a3da& i : effect.a3da) { + for (pvpp_auth_3d& i : effect.auth_3d) { int32_t& id = a1->pv_auth_3d_ids[i.hash]; auth_3d_data_set_repeat(&id, false); auth_3d_data_set_camera_root_update(&id, false); @@ -2963,22 +3169,20 @@ static bool x_pv_game_dsc_process(x_pv_game* a1, int64_t curr_time) { 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, &diva_pv_frame_rate); - if (effect.chara_index != PVPP_CHARA_STAGE) - auth_3d_data_set_chara_id(&id, effect.chara_index); + if (effect.chara_id != PVPP_CHARA_PNONE) + auth_3d_data_set_chara_id(&id, effect.chara_id); } for (pvpp_glitter& i : effect.glitter) { - uint32_t effect_hash = hash_string_murmurhash(&i.name); + uint32_t effect_hash = hash_string_murmurhash(i.name); Glitter::glt_particle_manager.LoadScene(hash_murmurhash_empty, effect_hash); Glitter::glt_particle_manager.SetSceneName(hash, a1->pv_glitter->name.c_str()); Glitter::glt_particle_manager.SetSceneEffectName( hash_murmurhash_empty, effect_hash, i.name.c_str()); - Glitter::glt_particle_manager.SetSceneFrameRate(hash, &diva_pv_frame_rate); } } else { - for (pvpp_a3da& i : effect.a3da) { + for (pvpp_auth_3d& i : effect.auth_3d) { int32_t& id = a1->pv_auth_3d_ids[i.hash]; auth_3d_data_set_visibility(&id, false); auth_3d_data_set_enable(&id, false); @@ -2986,7 +3190,7 @@ static bool x_pv_game_dsc_process(x_pv_game* a1, int64_t curr_time) { for (pvpp_glitter& i : effect.glitter) Glitter::glt_particle_manager.FreeSceneEffect( - 0, hash_string_murmurhash(&i.name), false); + 0, hash_string_murmurhash(i.name), false); } } break; case DSC_X_SONG_EFFECT_ATTACH: { @@ -3001,7 +3205,7 @@ static bool x_pv_game_dsc_process(x_pv_game* a1, int64_t curr_time) { chara_id = -1; pvpp_effect& effect = a1->pp->effect[effect_id]; - for (pvpp_a3da& i : effect.a3da) { + for (pvpp_auth_3d& i : effect.auth_3d) { int32_t& id = a1->pv_auth_3d_ids[i.hash]; auth_3d_data_set_chara_id(&id, chara_id); } @@ -3050,10 +3254,10 @@ static bool x_pv_game_dsc_process(x_pv_game* a1, int64_t curr_time) { pvpp_chara& chara = a1->pp->chara[a1->chara_id]; if (!chara.chara_effect_init) break; - else if (chara_effect_id < 0 || chara_effect_id >= chara.chara_effect.effect_a3da.size()) + else if (chara_effect_id < 0 || chara_effect_id >= chara.chara_effect.effect_auth_3d.size()) break; - uint32_t hash = chara.chara_effect.effect_a3da[chara_effect_id].a3da.hash; + uint32_t hash = chara.chara_effect.effect_auth_3d[chara_effect_id].auth_3d.hash; hash = a1->effchrpv_auth_3d_hashes[hash]; if (enable) { int32_t& id = a1->effchrpv_auth_3d_ids[hash]; @@ -3064,7 +3268,6 @@ static bool x_pv_game_dsc_process(x_pv_game* a1, int64_t curr_time) { 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, &diva_pv_frame_rate); auth_3d_data_set_chara_id(&id, a1->chara_id); } else { @@ -3457,8 +3660,8 @@ static void x_pv_game_stage_effect_ctrl(x_pv_game* xpvgm) { x_pv_game_stage_effect_start(xpvgm, &effect); stage_effect.frame = 0.0f; - if (effect.bar_count && effect.bar_count != 0xFF) - stage_effect.last_frame = (float_t)(effect.bar_count * 120); + if (stage_effect.bar_count > 0) + stage_effect.last_frame = (float_t)(stage_effect.bar_count * 120); else stage_effect.last_frame = 240.0f; stage_effect.stage_effect = stage_effect.next_stage_effect; @@ -3466,15 +3669,15 @@ static void x_pv_game_stage_effect_ctrl(x_pv_game* xpvgm) { } else if (stage_effect.frame >= stage_effect.last_frame) { pvsr_stage_effect& effect = xpvgm->sr->stage_effect[stage_effect.stage_effect]; - pvsr_stage_effect& change_effect = xpvgm->sr->stage_change_effect + pvsr_stage_change_effect& change_effect = xpvgm->sr->stage_change_effect [stage_effect.stage_effect][stage_effect.next_stage_effect]; x_pv_game_stage_effect_stop(xpvgm, &effect, - !!change_effect.a3da.size(), !!change_effect.glitter.size()); + !!change_effect.auth_3d.size(), !!change_effect.glitter.size()); x_pv_game_stage_effect_start(xpvgm, &change_effect); stage_effect.frame = 0.0f; - if (change_effect.bar_count && change_effect.bar_count != 0xFF) + if (change_effect.bar_count > 0) stage_effect.last_frame = (float_t)(change_effect.bar_count * 120); else stage_effect.last_frame = 240.0f; @@ -3485,14 +3688,14 @@ static void x_pv_game_stage_effect_ctrl(x_pv_game* xpvgm) { } else if (stage_effect.prev_stage_effect != -1) { if (stage_effect.stage_effect != -1 && stage_effect.frame >= stage_effect.last_frame) { - if (xpvgm->sr->stage_change_effect_init[stage_effect.prev_stage_effect][stage_effect.stage_effect]) { + if (xpvgm->sr->stage_change_effect[stage_effect.prev_stage_effect][stage_effect.stage_effect].enable) { pvsr_stage_effect& effect = xpvgm->sr->stage_effect[stage_effect.prev_stage_effect]; - pvsr_stage_effect& change_effect = xpvgm->sr->stage_change_effect + pvsr_stage_change_effect& change_effect = xpvgm->sr->stage_change_effect [stage_effect.prev_stage_effect][stage_effect.stage_effect]; x_pv_game_stage_effect_stop(xpvgm, &change_effect); x_pv_game_stage_effect_stop(xpvgm, &effect, - !change_effect.a3da.size(), !change_effect.glitter.size()); + !change_effect.auth_3d.size(), !change_effect.glitter.size()); } else x_pv_game_stage_effect_stop(xpvgm, @@ -3502,8 +3705,8 @@ static void x_pv_game_stage_effect_ctrl(x_pv_game* xpvgm) { x_pv_game_stage_effect_start(xpvgm, &effect); stage_effect.frame = 0.0f; - if (effect.bar_count && effect.bar_count != 0xFF) - stage_effect.last_frame = (float_t)(effect.bar_count * 120); + if (stage_effect.bar_count > 0 ) + stage_effect.last_frame = (float_t)(stage_effect.bar_count * 120); else stage_effect.last_frame = 240.0f; stage_effect.prev_stage_effect = -1; @@ -3515,9 +3718,9 @@ static void x_pv_game_stage_effect_ctrl(x_pv_game* xpvgm) { stage_effect.frame -= stage_effect.last_frame; } -static void x_pv_game_stage_effect_start(x_pv_game* xpvgm, pvsr_stage_effect* stage_effect) { +static void x_pv_game_stage_effect_start(x_pv_game* xpvgm, pvsr_stage_change_effect* stage_change_effect) { uint32_t hash = xpvgm->stage_glitter->hash; - for (pvsr_a3da& i : stage_effect->a3da) { + for (pvsr_auth_3d& i : stage_change_effect->auth_3d) { int32_t& id = xpvgm->stage_auth_3d_ids[i.hash]; auth_3d_data_set_camera_root_update(&id, false); auth_3d_data_set_enable(&id, true); @@ -3526,23 +3729,62 @@ static void x_pv_game_stage_effect_start(x_pv_game* xpvgm, pvsr_stage_effect* st 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, &diva_stage_frame_rate); + auth_3d_data_set_frame_rate(&id, &xpvgm->frame_rate_control); } - for (pvsr_glitter& i : stage_effect->glitter) { - uint32_t effect_hash = hash_string_murmurhash(&i.name); + for (pvsr_glitter& i : stage_change_effect->glitter) { + uint32_t effect_hash = hash_string_murmurhash(i.name); Glitter::glt_particle_manager.LoadScene(hash_murmurhash_empty, effect_hash); Glitter::glt_particle_manager.SetSceneName(hash, xpvgm->stage_glitter->name.c_str()); Glitter::glt_particle_manager.SetSceneEffectName( hash_murmurhash_empty, effect_hash, i.name.c_str()); - Glitter::glt_particle_manager.SetSceneFrameRate(hash, &diva_stage_frame_rate); + Glitter::glt_particle_manager.SetSceneFrameRate(hash, &xpvgm->frame_rate_control); } } +static void x_pv_game_stage_effect_start(x_pv_game* xpvgm, pvsr_stage_effect* stage_effect) { + uint32_t hash = xpvgm->stage_glitter->hash; + for (pvsr_auth_3d& i : stage_effect->auth_3d) { + int32_t& id = xpvgm->stage_auth_3d_ids[i.hash]; + auth_3d_data_set_camera_root_update(&id, false); + auth_3d_data_set_enable(&id, true); + auth_3d_data_set_repeat(&id, true); + auth_3d_data_set_req_frame(&id, 0.0f); + 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, &xpvgm->frame_rate_control); + } + + for (pvsr_glitter& i : stage_effect->glitter) { + uint32_t effect_hash = hash_string_murmurhash(i.name); + Glitter::glt_particle_manager.LoadScene(hash_murmurhash_empty, effect_hash); + Glitter::glt_particle_manager.SetSceneName(hash, xpvgm->stage_glitter->name.c_str()); + Glitter::glt_particle_manager.SetSceneEffectName( + hash_murmurhash_empty, effect_hash, i.name.c_str()); + Glitter::glt_particle_manager.SetSceneFrameRate(hash, &xpvgm->frame_rate_control); + } +} + +static void x_pv_game_stage_effect_stop(x_pv_game* xpvgm, + pvsr_stage_change_effect* stage_change_effect, bool stop_a3da, bool stop_glitter) { + if (stop_a3da) + for (pvsr_auth_3d& i : stage_change_effect->auth_3d) { + int32_t& id = xpvgm->stage_auth_3d_ids[i.hash]; + auth_3d_data_set_visibility(&id, false); + auth_3d_data_set_enable(&id, false); + } + + if (stop_glitter) + for (pvsr_glitter& i : stage_change_effect->glitter) + Glitter::glt_particle_manager.FreeSceneEffect( + 0, hash_string_murmurhash(i.name), false); +} + static void x_pv_game_stage_effect_stop(x_pv_game* xpvgm, pvsr_stage_effect* stage_effect, bool stop_a3da, bool stop_glitter) { if (stop_a3da) - for (pvsr_a3da& i : stage_effect->a3da) { + for (pvsr_auth_3d& i : stage_effect->auth_3d) { int32_t& id = xpvgm->stage_auth_3d_ids[i.hash]; auth_3d_data_set_visibility(&id, false); auth_3d_data_set_enable(&id, false); @@ -3551,7 +3793,7 @@ static void x_pv_game_stage_effect_stop(x_pv_game* xpvgm, if (stop_glitter) for (pvsr_glitter& i : stage_effect->glitter) Glitter::glt_particle_manager.FreeSceneEffect( - 0, hash_string_murmurhash(&i.name), false); + 0, hash_string_murmurhash(i.name), false); } static bool x_pv_game_stage_effects_process(x_pv_game* xpvgm, int32_t frame) { @@ -3561,6 +3803,7 @@ static bool x_pv_game_stage_effects_process(x_pv_game* xpvgm, int32_t frame) { return true; xpvgm->stage_effect.next_stage_effect = xpvgm->stage_effects_ptr->effect_id; + xpvgm->stage_effect.bar_count = xpvgm->stage_effects_ptr->bar_count; return true; } diff --git a/src/CLOUD/x_pv_game.hpp b/src/CLOUD/x_pv_game.hpp index 9809f117..b688a160 100644 --- a/src/CLOUD/x_pv_game.hpp +++ b/src/CLOUD/x_pv_game.hpp @@ -17,9 +17,57 @@ #include "../KKdLib/pvsr.hpp" #include "../CRE/rob/rob.hpp" #include "../CRE/auth_3d.hpp" +#include "../CRE/frame_rate_control.hpp" #include "../CRE/task.hpp" #include "classes.hpp" +struct x_pv_bar_beat_data { + int32_t bar; + float_t bar_time; + int32_t beat_count; + int32_t beat_counter; + float_t beat_time[16]; + + bool compare_bar_time_less(float_t time); +}; + +struct x_pv_bar_beat { + float_t curr_time; + float_t delta_time; + float_t next_bar_time; + float_t curr_bar_time; + float_t next_beat_time; + float_t curr_beat_time; + float_t divisor; + int32_t bar; + int32_t field_20; + std::vector data; + + x_pv_bar_beat(); + ~x_pv_bar_beat(); + + float_t get_bar_current_frame(); + float_t get_delta_frame(); + float_t get_next_beat_time(float_t time); + int32_t get_time_bar_beat(int32_t* beat, float_t time); + void reset(); + void reset_time(); + void set_frame(float_t curr_frame, float_t delta_frame); + void set_time(float_t curr_time, float_t delta_time); +}; + +class BPMFrameRateControl : public FrameRateControl { +public: + x_pv_bar_beat* bar_beat; + + BPMFrameRateControl(); + virtual ~BPMFrameRateControl() override; + + virtual float_t GetDeltaFrame() override; + + void Reset(); +}; + struct x_pv_game_glitter { std::string name; uint32_t hash; @@ -96,6 +144,7 @@ struct x_pv_game_stage_effect { int32_t prev_stage_effect; int32_t stage_effect; int32_t next_stage_effect; + int32_t bar_count; }; struct x_pv_game_stage_effect_init { @@ -237,6 +286,9 @@ public: dsc_data* dsc_data_ptr; dsc_data* dsc_data_ptr_end; + x_pv_bar_beat bar_beat; + BPMFrameRateControl frame_rate_control; + std::vector stage_effects; x_pv_game_stage_effect_init* stage_effects_ptr; x_pv_game_stage_effect_init* stage_effects_ptr_end; @@ -252,12 +304,9 @@ public: bool pv_end; x_pv_play_data playdata[ROB_CHARA_COUNT]; float_t scene_rot_y; - mat4u scene_rot_mat; + mat4 scene_rot_mat; int32_t branch_mode; - int64_t prev_bar_point_time; - int32_t prev_bpm; - bool pause; bool step_frame; @@ -270,6 +319,7 @@ public: virtual bool Ctrl() override; virtual bool Dest() override; virtual void Disp() override; + virtual void Basic() override; virtual void Window() override; void Load(int32_t pv_id, int32_t stage_id, chara_index charas[6], int32_t modules[6]); diff --git a/src/CRE/Glitter/curve.cpp b/src/CRE/Glitter/curve.cpp index 6b607960..8cca30c3 100644 --- a/src/CRE/Glitter/curve.cpp +++ b/src/CRE/Glitter/curve.cpp @@ -4,7 +4,7 @@ */ #include "glitter.hpp" -#include "../../KKdLib/interpolation.h" +#include "../../KKdLib/interpolation.hpp" namespace Glitter { #if defined(CRE_DEV) diff --git a/src/CRE/Glitter/effect_group.cpp b/src/CRE/Glitter/effect_group.cpp index c644579a..ec507ace 100644 --- a/src/CRE/Glitter/effect_group.cpp +++ b/src/CRE/Glitter/effect_group.cpp @@ -61,7 +61,7 @@ namespace Glitter { obj_material* mat = &obj->material_array[j].material; if (!memcmp(&mat->color.emission, &vec3_null, sizeof(vec3)) && mat->color.emission.w == 1.0f) - mat->color.emission = vec4u_identity; + mat->color.emission = vec4_identity; } } } diff --git a/src/CRE/Glitter/effect_inst.cpp b/src/CRE/Glitter/effect_inst.cpp index 99db9aa1..91898c60 100644 --- a/src/CRE/Glitter/effect_inst.cpp +++ b/src/CRE/Glitter/effect_inst.cpp @@ -13,7 +13,7 @@ namespace Glitter { size_t id, float_t emission, bool appear_now) : data(GLT_VAL) { effect = eff; data = eff->data; - color = vec4u_identity; + color = vec4_identity; scale_all = 1.0f; this->id = id; translation = eff->translation; @@ -24,7 +24,7 @@ namespace Glitter { mat = mat4_identity; flags = (EffectInstFlag)0; random = 0; - min_color = vec4u_null; + min_color = vec4_null; ext_anim_scale = vec3_null; some_scale = -1.0f; @@ -38,19 +38,6 @@ namespace Glitter { } - draw_pass_3d_type EffectInst::GetAlpha() { - return data.flags & EFFECT_ALPHA ? DRAW_PASS_3D_TRANSPARENT : DRAW_PASS_3D_TRANSLUCENT; - } - - fog_id EffectInst::GetFog() { - if (data.flags & EFFECT_FOG) - return FOG_DEPTH; - else if (data.flags & EFFECT_FOG_HEIGHT) - return FOG_HEIGHT; - else - return (fog_id)-1; - } - F2EffectInst::ExtAnim::ExtAnim() { object_index = -1; mesh_index = -1; @@ -146,10 +133,9 @@ namespace Glitter { GetValue(GLT_VAL); mat4 mat; - if (flags & EFFECT_INST_HAS_EXT_ANIM_TRANS && ext_anim) { - vec3 trans; - vec3_add(translation, ext_anim->translation, trans); - mat4_translate_mult(&ext_anim->mat, trans.x, trans.y, trans.z, &mat); + if (GetExtAnimMat(&mat)) { + vec3 trans = translation; + mat4_translate_mult(&mat, trans.x, trans.y, trans.z, &mat); } else { vec3 trans = translation; @@ -175,19 +161,15 @@ namespace Glitter { } else if (data.flags & EFFECT_LOOP) frame0 -= (float_t)data.life_time; - else { - enum_or(flags, EFFECT_INST_FREE); - for (F2EmitterInst*& i : emitters) - if (i) - i->Free(GPM_VAL, GLT_VAL, emission, false); - } + else + Free(GPM_VAL, GLT_VAL, emission, false); render_scene.Ctrl(GLT_VAL, delta_frame); frame0 += delta_frame; } - void F2EffectInst::Disp(GPM, draw_pass_3d_type alpha) { - render_scene.Disp(GPM_VAL, alpha); + void F2EffectInst::Disp(GPM, DispType disp_type) { + render_scene.Disp(GPM_VAL, disp_type); } void F2EffectInst::Free(GPM, GLT, float_t emission, bool free) { @@ -219,6 +201,7 @@ namespace Glitter { void F2EffectInst::Reset(GPM, GLT, float_t emission) { frame0 = -(float_t)data.appear_time; + frame1 = 0.0; flags = (EffectInstFlag)0; if (~data.flags & EFFECT_LOCAL && data.ext_anim) { @@ -258,15 +241,8 @@ namespace Glitter { GetValue(GLT_VAL); mat4 mat; - if (flags & EFFECT_INST_HAS_EXT_ANIM_TRANS && ext_anim) { - vec3 trans; - vec3_add(translation, ext_anim->translation, trans); - mat4_translate_mult(&ext_anim->mat, trans.x, trans.y, trans.z, &mat); - } - else { - vec3 trans = translation; - mat4_translate(trans.x, trans.y, trans.z, &mat); - } + vec3 trans = translation; + mat4_translate(trans.x, trans.y, trans.z, &mat); vec3 rot = rotation; vec3 scale; @@ -285,12 +261,8 @@ namespace Glitter { } else if (data.flags & EFFECT_LOOP) frame0 -= (float_t)data.life_time; - else { - enum_or(flags, EFFECT_INST_FREE); - for (F2EmitterInst*& i : emitters) - if (i) - i->Free(GPM_VAL, GLT_VAL, emission, false); - } + else + Free(GPM_VAL, GLT_VAL, emission, false); render_scene.Ctrl(GLT_VAL, delta_frame); } @@ -299,7 +271,36 @@ namespace Glitter { frame1 += delta_frame; start_time -= delta_frame; } - frame1 += delta_frame; + + CtrlMat(GPM_VAL, GLT_VAL); + } + + void F2EffectInst::CtrlMat(GPM, GLT) { + if (~flags & EFFECT_INST_JUST_INIT) + return; + + vec3 trans = translation; + vec3 rot = rotation; + vec3 scale; + vec3_mult_scalar(this->scale, scale_all, scale); + + mat4 mat; + mat4_translate(trans.x, trans.y, trans.z, &mat); + mat4_rot(&mat, rot.x, rot.y, rot.z, &mat); + mat4_scale_rot(&mat, scale.x, scale.y, scale.z, &mat); + this->mat = mat; + + for (F2EmitterInst*& i : emitters) + if (i) + i->CtrlMat(GPM_VAL, GLT_VAL, this); + + enum_and(flags, ~EFFECT_INST_JUST_INIT); + } + + DispType F2EffectInst::GetDispType() { + if (data.flags & EFFECT_ALPHA) + return DISP_ALPHA; + return DISP_NORMAL; } void F2EffectInst::GetExtAnim() { @@ -320,7 +321,7 @@ namespace Glitter { if (!rob_chr) return; - mat4 mat = rob_chr->data.adjust_data.mat; + mat4& mat = rob_chr->data.adjust_data.mat; vec3 scale; mat4_get_scale(&mat, &scale); @@ -433,6 +434,23 @@ namespace Glitter { } } + bool F2EffectInst::GetExtAnimMat(mat4* mat) { + if (~flags & EFFECT_INST_HAS_EXT_ANIM_TRANS || !ext_anim) + return false; + + vec3 trans = ext_anim->translation; + mat4_translate_mult(&ext_anim->mat, trans.x, trans.y, trans.z, mat); + return true; + } + + FogType F2EffectInst::GetFog() { + if (data.flags & EFFECT_FOG) + return Glitter::FOG_DEPTH; + else if (data.flags & EFFECT_FOG_HEIGHT) + return Glitter::FOG_HEIGHT; + return Glitter::FOG_NONE; + } + void F2EffectInst::GetValue(GLT) { Animation* anim = &effect->animation; size_t length = anim->curves.size(); @@ -555,7 +573,7 @@ namespace Glitter { uint64_t bone_name_hash = hash_utf8_fnv1a64m(bone_names[node]); for (std::string& i : *motion_bone_names) - if (bone_name_hash == hash_string_fnv1a64m(&i)) + if (bone_name_hash == hash_string_fnv1a64m(i)) return (int32_t)(&i - motion_bone_names->data()); return -1; } @@ -641,7 +659,7 @@ namespace Glitter { emitters.push_back(emitter); } - CtrlInit(emission); + CtrlInit(GPM_VAL, emission); } XEffectInst::~XEffectInst() { @@ -682,22 +700,19 @@ namespace Glitter { vec3 rot = rotation; mat4 mat; - if (flags & EFFECT_INST_HAS_EXT_ANIM_TRANS && ext_anim) { - mat4_normalize_rotation(&ext_anim->mat, &mat_rot); + if (GetExtAnimMat(&mat)) { + mat4_normalize_rotation(&mat, &mat_rot); mat4_clear_trans(&mat_rot, &mat_rot); mat4_rotate_mult(&mat_rot, rot.x, rot.y, rot.z, &mat_rot_eff_rot); - vec3 ext_trans = ext_anim->translation; - mat4_translate_mult(&ext_anim->mat, ext_trans.x, ext_trans.y, ext_trans.z, &mat); - - vec3& trans = translation; + vec3 trans = translation; mat4_translate_mult(&mat, trans.x, trans.y, trans.z, &mat); } else { mat_rot = mat4_identity; mat4_rotate(rot.x, rot.y, rot.z, &mat_rot_eff_rot); - vec3& trans = translation; + vec3 trans = translation; mat4_translate(trans.x, trans.y, trans.z, &mat); } @@ -719,19 +734,15 @@ namespace Glitter { } else if (data.flags & EFFECT_LOOP) frame0 -= (float_t)data.life_time; - else { - enum_or(flags, EFFECT_INST_FREE); - for (XEmitterInst*& i : emitters) - if (i) - i->Free(emission, false); - } + else + Free(GPM_VAL, GLT_VAL, emission, false); render_scene.Ctrl(delta_frame, true); frame0 += delta_frame; } - void XEffectInst::Disp(GPM, draw_pass_3d_type alpha) { - render_scene.Disp(GPM_VAL, alpha); + void XEffectInst::Disp(GPM, DispType disp_type) { + render_scene.Disp(GPM_VAL, disp_type); } void XEffectInst::Free(GPM, GLT, float_t emission, bool free) { @@ -763,6 +774,7 @@ namespace Glitter { void XEffectInst::Reset(GPM, GLT, float_t emission) { frame0 = -(float_t)data.appear_time; + frame1 = 0.0; flags = (EffectInstFlag)0; if (~data.flags & EFFECT_LOCAL && data.ext_anim_x) { @@ -792,14 +804,14 @@ namespace Glitter { if (i) i->Reset(); - CtrlInit(emission); + CtrlInit(GPM_VAL, emission); } void XEffectInst::CalcDisp(GPM) { render_scene.CalcDisp(GPM_VAL); } - void XEffectInst::CtrlInit(float_t emission) { + void XEffectInst::CtrlInit(GPM, float_t emission) { if (data.start_time < 1) return; @@ -847,6 +859,36 @@ namespace Glitter { frame1 += delta_frame; start_time -= delta_frame; } + + CtrlMat(GPM_VAL); + } + + void XEffectInst::CtrlMat(GPM) { + if (~flags & EFFECT_INST_JUST_INIT) + return; + + vec3 trans = translation; + vec3 rot = rotation; + vec3 scale; + vec3_mult_scalar(this->scale, scale_all, scale); + + mat4 mat; + mat4_translate(trans.x, trans.y, trans.z, &mat); + mat4_rot(&mat, rot.x, rot.y, rot.z, &mat); + mat4_scale_rot(&mat, scale.x, scale.y, scale.z, &mat); + this->mat = mat; + + for (XEmitterInst*& i : emitters) + if (i) + i->CtrlMat(GPM_VAL, this); + + enum_and(flags, ~EFFECT_INST_JUST_INIT); + } + + DispType XEffectInst::GetDispType() { + if (data.flags & EFFECT_ALPHA) + return DISP_ALPHA; + return DISP_NORMAL; } void XEffectInst::GetExtAnim() { @@ -867,7 +909,7 @@ namespace Glitter { if (!rob_chr) return; - mat4 mat = rob_chr->data.adjust_data.mat; + mat4& mat = rob_chr->data.adjust_data.mat; vec3 scale; mat4_get_scale(&rob_chr->data.adjust_data.mat, &scale); @@ -916,7 +958,7 @@ namespace Glitter { rob_chara* rob_chr = rob_chara_array_get(chara_id); if (rob_chr) { vec3 trans = rob_chr->data.adjust_data.trans; - mat4_translate(trans.x, trans.y + rob_chr->data.adjust_data.pos_adjust_y, trans.z, &m); + mat4_translate(trans.x, trans.y, trans.z, &m); vec3 scale; mat4_get_scale(&rob_chr->data.adjust_data.mat, &scale); @@ -964,6 +1006,23 @@ namespace Glitter { } } + bool XEffectInst::GetExtAnimMat(mat4* mat) { + if (~flags & EFFECT_INST_HAS_EXT_ANIM_TRANS || !ext_anim) + return false; + + vec3 trans = ext_anim->translation; + mat4_translate_mult(&ext_anim->mat, trans.x, trans.y, trans.z, mat); + return true; + } + + FogType XEffectInst::GetFog() { + if (data.flags & EFFECT_FOG) + return Glitter::FOG_DEPTH; + else if (data.flags & EFFECT_FOG_HEIGHT) + return Glitter::FOG_HEIGHT; + return Glitter::FOG_NONE; + } + void XEffectInst::GetValue() { Animation* anim = &effect->animation; size_t length = anim->curves.size(); diff --git a/src/CRE/Glitter/emitter.cpp b/src/CRE/Glitter/emitter.cpp index 6cbf5042..b85b09c3 100644 --- a/src/CRE/Glitter/emitter.cpp +++ b/src/CRE/Glitter/emitter.cpp @@ -6,12 +6,33 @@ #include "glitter.hpp" namespace Glitter { - Emitter::Emitter(GLT) : data() { + Emitter::Box::Box() { + + } + + Emitter::Cylinder::Cylinder() : radius(), height(), + start_angle(), end_angle(), on_edge(), direction() { + + } + + Emitter::Polygon::Polygon() : size(), count(), direction() { + + } + + Emitter::Sphere::Sphere() : radius(), latitude(), longitude(), on_edge(), direction() { + + } + + Emitter::Data::Data() : start_time(), life_time(), + flags(), timer(), emission_interval(), type(), seed() { + loop_start_time = 0; + loop_end_time = -1; + particles_per_emission = 1.0f; + direction = DIRECTION_EFFECT_ROTATION; + } + + Emitter::Emitter(GLT) { version = GLT_VAL == Glitter::X ? 0x04 : 0x02; - data.loop_start_time = 0; - data.loop_end_time = -1; - data.particles_per_emission = 1; - data.direction = DIRECTION_EFFECT_ROTATION; } Emitter::~Emitter() { diff --git a/src/CRE/Glitter/emitter_inst.cpp b/src/CRE/Glitter/emitter_inst.cpp index bbf5ec83..e45f5947 100644 --- a/src/CRE/Glitter/emitter_inst.cpp +++ b/src/CRE/Glitter/emitter_inst.cpp @@ -143,7 +143,7 @@ namespace Glitter { mat4 dir_mat; switch (data.direction) { case DIRECTION_BILLBOARD: - mat4_from_mat3(&((render_context*)GPM_VAL->rctx)->camera->inv_view_mat3, &dir_mat); + mat4_from_mat3(&GPM_VAL->cam.inv_view_mat3, &dir_mat); mat4_mult(&eff_inst->mat, &dir_mat, &dir_mat); mat4_clear_trans(&dir_mat, &dir_mat); break; @@ -157,7 +157,7 @@ namespace Glitter { mat4_rotate_z((float_t)-M_PI_2, &dir_mat); break; case DIRECTION_BILLBOARD_Y_AXIS: - mat4_rotate_y(((render_context*)GPM_VAL->rctx)->camera->rotation.y, &dir_mat); + mat4_rotate_y(GPM_VAL->cam.rotation_y, &dir_mat); break; default: mult = false; @@ -304,17 +304,17 @@ namespace Glitter { return true; } - void F2EmitterInst::InitMesh(GLT, int32_t index, vec3* scale, - vec3* position, vec3* direction, Random* random) { + void F2EmitterInst::InitMesh(GLT, int32_t index, vec3& scale, + vec3& position, vec3& direction, Random* random) { switch (data.type) { case EMITTER_BOX: { vec3 dir; - vec3_mult(data.box.size, *scale, dir); + vec3_mult(data.box.size, scale, dir); vec3_mult_scalar(dir, 0.5f, dir); - random->F2GetVec3(GLT_VAL, &dir, position); + random->F2GetVec3(GLT_VAL, dir, position); } break; case EMITTER_CYLINDER: { - float_t radius = data.cylinder.radius * scale->x; + float_t radius = data.cylinder.radius * scale.x; if (!data.cylinder.on_edge) radius = random->F2GetFloat(GLT_VAL, 0.0f, radius); @@ -325,19 +325,19 @@ namespace Glitter { dir.y = 0.0f; dir.z = sinf(angle); - position->x = dir.x * radius; - position->y = random->F2GetFloat(GLT_VAL, data.cylinder.height * scale->y * 0.5f); - position->z = dir.z * radius; + position.x = dir.x * radius; + position.y = random->F2GetFloat(GLT_VAL, data.cylinder.height * scale.y * 0.5f); + position.z = dir.z * radius; if (data.cylinder.direction == EMITTER_EMISSION_DIRECTION_OUTWARD) - *direction = dir; + direction = dir; else if (data.cylinder.direction == EMITTER_EMISSION_DIRECTION_INWARD) { const vec3 reverse_xz_dir = { -0.0f, 0.0f, -0.0f }; - vec3_xor(dir, reverse_xz_dir, *direction); + vec3_xor(dir, reverse_xz_dir, direction); } } break; case EMITTER_SPHERE: { - float_t radius = data.sphere.radius * scale->x; + float_t radius = data.sphere.radius * scale.x; if (!data.sphere.on_edge) radius = random->F2GetFloat(GLT_VAL, 0.0f, radius); @@ -349,19 +349,19 @@ namespace Glitter { dir.y = sinf(latitude); dir.z = cosf(longitude) * cosf(latitude); - vec3_mult_scalar(dir, radius, *position); + vec3_mult_scalar(dir, radius, position); if (data.sphere.direction == EMITTER_EMISSION_DIRECTION_OUTWARD) - *direction = dir; + direction = dir; else if (data.sphere.direction == EMITTER_EMISSION_DIRECTION_INWARD) - vec3_negate(dir, *direction); + vec3_negate(dir, direction); } break; case EMITTER_POLYGON: { - float_t radius = data.polygon.size * scale->x; + float_t radius = data.polygon.size * scale.x; float_t angle = (float_t)index * 360.0f / (float_t)data.polygon.count * DEG_TO_RAD_FLOAT + (float_t)M_PI_2; - position->x = sinf(angle) * radius; - position->y = 0.0f; + position.x = sinf(angle) * radius; + position.y = 0.0f; } break; } } @@ -381,17 +381,17 @@ namespace Glitter { i->Reset(); } - void XEmitterInst::InitMesh(int32_t index, vec3* scale, - vec3* position, vec3* direction, Random* random) { + void XEmitterInst::InitMesh(int32_t index, vec3& scale, + vec3& position, vec3& direction, Random* random) { switch (emitter->data.type) { case EMITTER_BOX: { vec3 dir; - vec3_mult(data.box.size, *scale, dir); + vec3_mult(data.box.size, scale, dir); vec3_mult_scalar(dir, 0.5f, dir); - random->XGetVec3(&dir, position); + random->XGetVec3(dir, position); } break; case EMITTER_CYLINDER: { - float_t radius = data.cylinder.radius * scale->x; + float_t radius = data.cylinder.radius * scale.x; if (!data.cylinder.on_edge) radius = random->XGetFloat(0.0f, radius); @@ -402,19 +402,19 @@ namespace Glitter { dir.y = 0.0f; dir.z = sinf(angle); - position->x = dir.x * radius; - position->y = random->XGetFloat(data.cylinder.height * scale->y * 0.5f); - position->z = dir.z * radius; + position.x = dir.x * radius; + position.y = random->XGetFloat(data.cylinder.height * scale.y * 0.5f); + position.z = dir.z * radius; if (data.cylinder.direction == EMITTER_EMISSION_DIRECTION_OUTWARD) - *direction = dir; + direction = dir; else if (data.cylinder.direction == EMITTER_EMISSION_DIRECTION_INWARD) { const vec3 reverse_xz_dir = { -0.0f, 0.0f, -0.0f }; - vec3_xor(dir, reverse_xz_dir, *direction); + vec3_xor(dir, reverse_xz_dir, direction); } } break; case EMITTER_SPHERE: { - float_t radius = data.sphere.radius * scale->x; + float_t radius = data.sphere.radius * scale.x; if (!data.sphere.on_edge) radius = random->XGetFloat(0.0f, radius); @@ -426,14 +426,14 @@ namespace Glitter { dir.y = sinf(latitude); dir.z = cosf(longitude) * cosf(latitude); - vec3_mult_scalar(dir, radius, *position); + vec3_mult_scalar(dir, radius, position); if (data.sphere.direction == EMITTER_EMISSION_DIRECTION_OUTWARD) - *direction = dir; + direction = dir; else if (data.sphere.direction == EMITTER_EMISSION_DIRECTION_INWARD) - vec3_negate(dir, *direction); + vec3_negate(dir, direction); } break; case EMITTER_POLYGON: { - float_t radius = data.polygon.size * scale->x; + float_t radius = data.polygon.size * scale.x; float_t angle = ((float_t)index * 360.0f / (float_t)data.polygon.count + 90.0f) * DEG_TO_RAD_FLOAT; @@ -442,11 +442,11 @@ namespace Glitter { dir.y = 0.0f; dir.z = sinf(angle); - vec3_mult_scalar(dir, radius, *position); + vec3_mult_scalar(dir, radius, position); if (data.sphere.direction == EMITTER_EMISSION_DIRECTION_OUTWARD) - *direction = dir; + direction = dir; else if (data.sphere.direction == EMITTER_EMISSION_DIRECTION_INWARD) - vec3_negate(dir, *direction); + vec3_negate(dir, direction); } break; } } @@ -547,11 +547,6 @@ namespace Glitter { vec3_mult_scalar(data.rotation_add, delta_frame, rotation_add); vec3_add(rotation, rotation_add, rotation); - vec3 trans = translation; - vec3 rot = rotation; - vec3 scale; - vec3_mult_scalar(this->scale, scale_all, scale); - vec3 trans_prev = vec3_null; bool has_dist = false; if (data.timer == EMITTER_TIMER_BY_DISTANCE && flags & EMITTER_INST_HAS_DISTANCE) { @@ -559,61 +554,10 @@ namespace Glitter { has_dist = true; } - mat4 mat = eff_inst->mat; - mat4_translate_mult(&mat, trans.x, trans.y, trans.z, &mat); - mat4_normalize_rotation(&mat, &mat); - - mat4 mat_rot; - if (data.direction == DIRECTION_EFFECT_ROTATION) - mat_rot = eff_inst->mat_rot_eff_rot; - else { - mat4_clear_rot(&mat, &mat); - mat_rot = eff_inst->mat_rot; - } - - bool mult = true; - mat4 dir_mat; - switch (data.direction) { - case DIRECTION_BILLBOARD: { - if (eff_inst->data.flags & EFFECT_LOCAL) { - dir_mat = ((render_context*)GPM_VAL->rctx)->camera->view; - mat4_clear_trans(&dir_mat, &dir_mat); - mat4_mult(&dir_mat, &mat, &dir_mat); - } - else - dir_mat = mat; - - mat4 inv_view_mat; - mat4_from_mat3(&((render_context*)GPM_VAL->rctx)->camera->inv_view_mat3, &inv_view_mat); - mat4_mult(&dir_mat, &inv_view_mat, &dir_mat); - mat4_clear_trans(&dir_mat, &dir_mat); - } break; - case DIRECTION_Y_AXIS: - mat4_rotate_y((float_t)M_PI_2, &dir_mat); - break; - case DIRECTION_X_AXIS: - mat4_rotate_x((float_t)-M_PI_2, &dir_mat); - break; - case DIRECTION_BILLBOARD_Y_AXIS: - mat4_rotate_y(((render_context*)GPM_VAL->rctx)->camera->rotation.y, &dir_mat); - break; - default: - mult = false; - break; - } - - if (mult) { - mat4_mult(&dir_mat, &mat, &mat); - mat4_mult(&dir_mat, &mat_rot, &mat_rot); - } - - mat4_rot(&mat, rot.x, rot.y, rot.z, &mat); - mat4_rot(&mat_rot, rot.x, rot.y, rot.z, &mat_rot); - mat4_scale_rot(&mat, scale.x, scale.y, scale.z, &mat); - this->mat = mat; - this->mat_rot = mat_rot; + CtrlMat(GPM_VAL, eff_inst); if (has_dist) { + vec3 trans; mat4_get_translation(&mat, &trans); float_t trans_dist; @@ -682,6 +626,68 @@ namespace Glitter { enum_or(flags, EMITTER_INST_HAS_DISTANCE); } + void XEmitterInst::CtrlMat(GPM, XEffectInst* eff_inst) { + vec3 trans = translation; + vec3 rot = rotation; + vec3 scale; + vec3_mult_scalar(this->scale, scale_all, scale); + + mat4 mat = eff_inst->mat; + mat4_translate_mult(&mat, trans.x, trans.y, trans.z, &mat); + + mat4 mat_rot; + if (data.direction == DIRECTION_EFFECT_ROTATION) { + mat4_normalize_rotation(&mat, &mat); + mat_rot = eff_inst->mat_rot_eff_rot; + } + else { + mat4_clear_rot(&mat, &mat); + mat_rot = eff_inst->mat_rot; + } + + bool mult = true; + mat4 dir_mat; + switch (data.direction) { + case DIRECTION_BILLBOARD: { + if (eff_inst->data.flags & EFFECT_LOCAL) { + dir_mat = GPM_VAL->cam.view; + mat4_clear_trans(&dir_mat, &dir_mat); + mat4_mult(&dir_mat, &mat, &dir_mat); + } + else + dir_mat = mat; + + mat4 inv_view_mat; + mat4_from_mat3(&GPM_VAL->cam.inv_view_mat3, &inv_view_mat); + mat4_mult(&dir_mat, &inv_view_mat, &dir_mat); + mat4_clear_trans(&dir_mat, &dir_mat); + } break; + case DIRECTION_Y_AXIS: + mat4_rotate_y((float_t)M_PI_2, &dir_mat); + break; + case DIRECTION_X_AXIS: + mat4_rotate_x((float_t)-M_PI_2, &dir_mat); + break; + case DIRECTION_BILLBOARD_Y_AXIS: + mat4_rotate_y(GPM_VAL->cam.rotation_y, &dir_mat); + break; + default: + mult = false; + break; + } + + if (mult) { + mat4_mult(&dir_mat, &mat, &mat); + mat4_mult(&dir_mat, &mat_rot, &mat_rot); + } + + mat4_rot(&mat, rot.x, rot.y, rot.z, &mat); + mat4_rot(&mat_rot, rot.x, rot.y, rot.z, &mat_rot); + mat4_scale_rot(&mat, scale.x, scale.y, scale.z, &mat); + this->mat = mat; + this->mat_rot = mat_rot; + } + void XEmitterInst::Emit(float_t delta_frame, float_t emission) { if (frame < 0.0f) { frame += delta_frame; diff --git a/src/CRE/Glitter/file_reader.cpp b/src/CRE/Glitter/file_reader.cpp index b9d29225..d8a0fc1a 100644 --- a/src/CRE/Glitter/file_reader.cpp +++ b/src/CRE/Glitter/file_reader.cpp @@ -5,7 +5,7 @@ #include "glitter.hpp" #include "../../KKdLib/io/path.hpp" -#include "../../KKdLib/interpolation.h" +#include "../../KKdLib/interpolation.hpp" #include "../../KKdLib/farc.hpp" #include "../../KKdLib/str_utils.hpp" #include "../data.hpp" @@ -2365,10 +2365,7 @@ namespace Glitter { ptcl->data.unk1 = unk1; vec2_rcp(ptcl->data.split_uv, ptcl->data.split_uv); - - vec4 color = ptcl->data.color; - vec4_mult_scalar(color, (float_t)(1.0 / 255.0), color); - ptcl->data.color = color; + vec4_mult_scalar(ptcl->data.color, (float_t)(1.0 / 255.0), ptcl->data.color); int32_t uv_max_count = (int32_t)(split_u * split_v); if (uv_max_count) diff --git a/src/CRE/Glitter/glitter.cpp b/src/CRE/Glitter/glitter.cpp index 6093dd98..cdcb9bbf 100644 --- a/src/CRE/Glitter/glitter.cpp +++ b/src/CRE/Glitter/glitter.cpp @@ -286,40 +286,4 @@ namespace Glitter { if (t < 0.0f) *angle = (float_t)M_PI - *angle; } - - void mat3_mult_axis_angle(const mat3* src, mat3* dst, const vec3* axis, const float_t angle) { - 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_axis_angle(axis, angle, &q2); - quat_mult(&q2, &q1, &q3); - mat3_from_quat(&q3, dst); - } - - void mat4_mult_axis_angle(const mat4* src, mat4* dst, const vec3* axis, const float_t angle) { - quat q1; - quat q2; - quat q3; - float_t t0; - float_t t1; - 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); - 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; - } } diff --git a/src/CRE/Glitter/glitter.hpp b/src/CRE/Glitter/glitter.hpp index b1cbc0bf..8b4cc262 100644 --- a/src/CRE/Glitter/glitter.hpp +++ b/src/CRE/Glitter/glitter.hpp @@ -126,6 +126,12 @@ namespace Glitter { DIRECTION_PARTICLE_ROTATION = 11, }; + enum DispType { + DISP_OPAQUE = 0, + DISP_NORMAL, + DISP_ALPHA, + }; + enum EffectExtAnimFlag { EFFECT_EXT_ANIM_SET_ONCE = 0x00001, EFFECT_EXT_ANIM_TRANS_ONLY = 0x00002, @@ -248,6 +254,12 @@ namespace Glitter { EMITTER_POLYGON = 4, }; + enum FogType { + FOG_NONE = 0, + FOG_DEPTH, + FOG_HEIGHT, + }; + enum KeyType { KEY_CONSTANT = 0, KEY_LINEAR = 1, @@ -351,7 +363,7 @@ namespace Glitter { SCENE_NONE = 0x00, SCENE_FLAG_1 = 0x01, SCENE_NOT_DISP = 0x02, - SCENE_FLAG_4 = 0x04, + SCENE_FLAG_3 = 0x04, #if defined(CRE_DEV) || defined(CLOUD_DEV) SCENE_EDITOR = 0x80, #endif @@ -376,6 +388,7 @@ namespace Glitter { struct Animation; struct Buffer; + struct Camera; struct Curve; class Effect; class Emitter; @@ -460,7 +473,18 @@ namespace Glitter { struct Buffer { vec3 position; vec2 uv; - vec4u color; + vec4 color; + }; + + struct Camera { + mat4 projection; + mat4 view; + mat4 inv_view; + mat3 inv_view_mat3; + vec3 view_point; + float_t rotation_y; + + Camera(); }; struct Curve { @@ -635,7 +659,7 @@ namespace Glitter { float_t F2GetFloat(GLT, float_t min, float_t max); int32_t F2GetInt(GLT, int32_t value); int32_t F2GetInt(GLT, int32_t min, int32_t max); - void F2GetVec3(GLT, vec3* src, vec3* dst); + void F2GetVec3(GLT, vec3& src, vec3& dst); void F2StepValue(); int32_t GetValue(); void SetValue(int32_t value); @@ -643,7 +667,7 @@ namespace Glitter { float_t XGetFloat(float_t min, float_t max); int32_t XGetInt(int32_t value); int32_t XGetInt(int32_t min, int32_t max); - void XGetVec3(vec3* src, vec3* dst); + void XGetVec3(vec3& src, vec3& dst); void XReset(); void XSetStep(uint8_t step); void XStepValue(); @@ -676,8 +700,8 @@ namespace Glitter { RenderElement* elements; size_t max_count; Random* random_ptr; - draw_pass_3d_type alpha; - fog_id fog; + DispType disp_type; + FogType fog_type; GLuint vbo; GLuint ebo; float_t emission; @@ -728,7 +752,7 @@ namespace Glitter { void CalcDispQuadNormal(GPM, F2RenderGroup* rend_group, mat4* model_mat, mat4* dir_mat); void Ctrl(GLT, float_t delta_frame); - void Disp(GPM, draw_pass_3d_type alpha); + void Disp(GPM, DispType disp_type); void Disp(GPM, F2RenderGroup* rend_group); }; @@ -751,7 +775,7 @@ namespace Glitter { void CalcDispQuadNormal(GPM, XRenderGroup* rend_group, mat4* model_mat, mat4* dir_mat); void Ctrl(float_t delta_frame, bool copy_mats); - void Disp(GPM, draw_pass_3d_type alpha); + void Disp(GPM, DispType disp_type); void Disp(GPM, XRenderGroup* rend_group); }; @@ -764,7 +788,7 @@ namespace Glitter { Effect::Data data; float_t frame0; float_t frame1; - vec4u color; + vec4 color; vec3 translation; vec3 rotation; vec3 scale; @@ -773,7 +797,7 @@ namespace Glitter { EffectInstFlag flags; size_t id; uint32_t random; - vec4u min_color; + vec4 min_color; vec3 ext_anim_scale; float_t some_scale; @@ -783,16 +807,13 @@ namespace Glitter { virtual void Copy(EffectInst* dst, float_t emission) = 0; virtual void Ctrl(GPM, GLT, float_t delta_frame, float_t emission) = 0; - virtual void Disp(GPM, draw_pass_3d_type alpha) = 0; + virtual void Disp(GPM, DispType disp_type) = 0; virtual void Free(GPM, GLT, float_t emission, bool free) = 0; virtual size_t GetCtrlCount(ParticleType type) = 0; virtual size_t GetDispCount(ParticleType type) = 0; virtual bool HasEnded(bool a2) = 0; virtual void Reset(GPM, GLT, float_t emission) = 0; - draw_pass_3d_type GetAlpha(); - fog_id GetFog(); - static int32_t GetExtAnimBoneIndex(EffectExtAnimCharaNode node); }; @@ -830,7 +851,7 @@ namespace Glitter { virtual void Copy(EffectInst* dst, float_t emission) override; virtual void Ctrl(GPM, GLT, float_t delta_frame, float_t emission) override; - virtual void Disp(GPM, draw_pass_3d_type alpha) override; + virtual void Disp(GPM, DispType disp_type) override; virtual void Free(GPM, GLT, float_t emission, bool free) override; virtual size_t GetCtrlCount(ParticleType type) override; virtual size_t GetDispCount(ParticleType type) override; @@ -838,7 +859,11 @@ namespace Glitter { virtual void Reset(GPM, GLT, float_t emission) override; void CtrlInit(GPM, GLT, float_t emission); + void CtrlMat(GPM, GLT); + DispType GetDispType(); void GetExtAnim(); + bool GetExtAnimMat(mat4* mat); + FogType GetFog(); void GetValue(GLT); void SetMinColor(float_t& r, float_t& g, float_t& b, float_t& a); }; @@ -881,7 +906,7 @@ namespace Glitter { virtual void Copy(EffectInst* dst, float_t emission) override; virtual void Ctrl(GPM, GLT, float_t delta_frame, float_t emission) override; - virtual void Disp(GPM, draw_pass_3d_type alpha) override; + virtual void Disp(GPM, DispType disp_type) override; virtual void Free(GPM, GLT, float_t emission, bool free) override; virtual size_t GetCtrlCount(ParticleType type) override; virtual size_t GetDispCount(ParticleType type) override; @@ -889,8 +914,12 @@ namespace Glitter { virtual void Reset(GPM, GLT, float_t emission) override; void CalcDisp(GPM); - void CtrlInit(float_t emission); + void CtrlInit(GPM, float_t emission); + void CtrlMat(GPM); + DispType GetDispType(); void GetExtAnim(); + bool GetExtAnimMat(mat4* mat); + FogType GetFog(); void GetValue(); void SetExtAnim(mat4* a2, mat4* a3, vec3* trans, bool set_flags); void SetMinColor(float_t& r, float_t& g, float_t& b, float_t& a); @@ -900,6 +929,8 @@ namespace Glitter { public: struct Box { vec3 size; + + Box(); }; struct Cylinder { @@ -909,12 +940,16 @@ namespace Glitter { float_t end_angle; bool on_edge; EmitterEmissionDirection direction; + + Cylinder(); }; struct Polygon { float_t size; int32_t count; EmitterEmissionDirection direction; + + Polygon(); }; struct Sphere { @@ -923,6 +958,8 @@ namespace Glitter { float_t longitude; bool on_edge; EmitterEmissionDirection direction; + + Sphere(); }; struct Data { @@ -943,6 +980,8 @@ namespace Glitter { Emitter::Sphere sphere; Emitter::Polygon polygon; int32_t seed; + + Data(); }; Emitter::Data data; @@ -993,8 +1032,8 @@ namespace Glitter { void Free(GPM, GLT, float_t emission, bool free); void GetValue(GLT); bool HasEnded(bool a2); - void InitMesh(GLT, int32_t index, vec3* scale, - vec3* position, vec3* direction, Random* random); + void InitMesh(GLT, int32_t index, vec3& scale, + vec3& position, vec3& direction, Random* random); void Reset(); }; @@ -1010,13 +1049,14 @@ namespace Glitter { void Copy(XEmitterInst* dst, float_t emission); void Ctrl(GPM, XEffectInst* eff_inst, float_t delta_frame); void CtrlInit(XEffectInst* eff_inst, float_t delta_frame); + void CtrlMat(GPM, XEffectInst* eff_inst); void Emit(float_t delta_frame, float_t emission); void EmitParticle(float_t emission); void Free(float_t emission, bool free); void GetValue(); bool HasEnded(bool a2); - void InitMesh(int32_t index, vec3* scale, - vec3* position, vec3* direction, Random* random); + void InitMesh(int32_t index, vec3& scale, + vec3& position, vec3& direction, Random* random); uint8_t RandomGetStep(); void RandomStepValue(); void Reset(); @@ -1068,7 +1108,7 @@ namespace Glitter { struct LocusHistory { struct Data { - vec4u color; + vec4 color; vec3 translation; float_t scale; }; @@ -1121,7 +1161,7 @@ namespace Glitter { float_t reflection_coeff; float_t reflection_coeff_random; float_t rebound_plane_y; - vec4u color; + vec4 color; UVIndexType uv_index_type; int32_t uv_index; int32_t frame_step_uv; @@ -1283,7 +1323,7 @@ namespace Glitter { XEmitterInst* emit_inst, int32_t dup_count, int32_t count); void Free(); void FreeData(); - bool GetEmitterScale(vec3* emitter_scale); + bool GetEmitterScale(vec3& emitter_scale); bool GetExtAnimScale(vec3* ext_anim_scale, float_t* some_scale); static mat4 RotateMeshToEmitPosition(XRenderGroup* rend_group, @@ -1308,7 +1348,7 @@ namespace Glitter { float_t speed; float_t deceleration; vec2 uv; - vec4u color; + vec4 color; vec3 base_translation; vec3 base_direction; vec3 translation; @@ -1330,6 +1370,8 @@ namespace Glitter { uint32_t random; uint8_t step; + RenderElement(); + void InitLocusHistory(GLT, F2ParticleInst* ptcl_inst, Random* random); void InitLocusHistory(XParticleInst* ptcl_inst, Random* random); void InitMesh(GLT, F2EmitterInst* emit_inst, @@ -1378,7 +1420,7 @@ namespace Glitter { #endif bool Copy(Glitter::EffectInst* eff_inst, Glitter::Scene* dst); void Ctrl(GPM, float_t delta_frame); - void Disp(GPM, draw_pass_3d_type alpha); + void Disp(GPM, DispType disp_type); size_t GetCtrlCount(ParticleType ptcl_type); size_t GetDispCount(ParticleType ptcl_type); void GetFrame(float_t* frame, int32_t* life_time); @@ -1401,9 +1443,9 @@ namespace Glitter { EffectInst* effect; EmitterInst* emitter; ParticleInst* particle; - void* rctx; void* bone_data; FrameRateControl* frame_rate; + Camera cam; ParticleManagerFlag flags; int32_t scene_load_counter; float_t emission; @@ -1433,7 +1475,7 @@ namespace Glitter { int32_t CounterGet(); void CounterIncrement(); void CtrlScenes(); - void Disp(draw_pass_3d_type draw_pass_type); + void DispScenes(DispType disp_type); void FreeEffects(); void FreeSceneEffect(SceneCounter scene_counter, uint64_t hash, bool force_kill); void FreeScenes(); @@ -1471,8 +1513,6 @@ namespace Glitter { }; extern void axis_angle_from_vectors(vec3* axis, float_t* angle, const vec3* vec0, const vec3* vec1); - extern void mat3_mult_axis_angle(const mat3* src, mat3* dst, const vec3* axis, const float_t angle); - extern void mat4_mult_axis_angle(const mat4* src, mat4* dst, const vec3* axis, const float_t angle); extern GltParticleManager glt_particle_manager; } diff --git a/src/CRE/Glitter/particle.cpp b/src/CRE/Glitter/particle.cpp index 9cfb46cd..72a0a810 100644 --- a/src/CRE/Glitter/particle.cpp +++ b/src/CRE/Glitter/particle.cpp @@ -11,7 +11,7 @@ namespace Glitter { data.pivot = PIVOT_MIDDLE_CENTER; data.scale = vec3_identity; data.reflection_coeff = 1.0f; - data.color = vec4u_identity; + data.color = vec4_identity; data.uv_index = 0; data.uv_index_start = 0; data.uv_index_end = 1; diff --git a/src/CRE/Glitter/particle_inst.cpp b/src/CRE/Glitter/particle_inst.cpp index 3cb7aca7..f3cd08a0 100644 --- a/src/CRE/Glitter/particle_inst.cpp +++ b/src/CRE/Glitter/particle_inst.cpp @@ -34,11 +34,12 @@ namespace Glitter { if (data.data.type != PARTICLE_LOCUS) { F2RenderGroup* rend_group = new F2RenderGroup(this); if (rend_group) { - rend_group->alpha = eff_inst->GetAlpha(); - rend_group->fog = eff_inst->GetFog(); + rend_group->disp_type = eff_inst->GetDispType(); + rend_group->fog_type = eff_inst->GetFog(); + if (data.data.type == PARTICLE_QUAD && data.data.blend_mode == PARTICLE_BLEND_PUNCH_THROUGH) - rend_group->alpha = DRAW_PASS_3D_OPAQUE; + rend_group->disp_type = DISP_OPAQUE; if (data.data.emission >= min_emission) rend_group->emission = data.data.emission; @@ -46,6 +47,7 @@ namespace Glitter { rend_group->emission = eff_inst->data.emission; else rend_group->emission = emission; + data.render_group = rend_group; eff_inst->render_scene.Append(rend_group); } @@ -68,15 +70,18 @@ namespace Glitter { F2RenderGroup* rend_group = new F2RenderGroup(this); if (rend_group) { F2EffectInst* effect = parent->data.effect; - rend_group->alpha = effect->GetAlpha(); - rend_group->fog = effect->GetFog(); + rend_group->disp_type = effect->GetDispType(); + rend_group->fog_type = effect->GetFog(); + if (data.data.blend_mode == PARTICLE_BLEND_PUNCH_THROUGH && data.data.type == PARTICLE_QUAD) - rend_group->alpha = DRAW_PASS_3D_OPAQUE; + rend_group->disp_type = DISP_OPAQUE; + if (effect->data.emission >= min_emission) rend_group->emission = effect->data.emission; else rend_group->emission = emission; + data.render_group = rend_group; effect->render_scene.Append(rend_group); } @@ -485,8 +490,8 @@ namespace Glitter { if (data.data.type == PARTICLE_QUAD || data.data.type == PARTICLE_MESH) { XRenderGroup* rend_group = new XRenderGroup(this); if (rend_group) { - rend_group->alpha = eff_inst->GetAlpha(); - rend_group->fog = eff_inst->GetFog(); + rend_group->disp_type = eff_inst->GetDispType(); + rend_group->fog_type = eff_inst->GetFog(); if (data.data.draw_flags & PARTICLE_DRAW_NO_BILLBOARD_CULL) rend_group->use_culling = false; @@ -499,6 +504,7 @@ namespace Glitter { rend_group->emission = eff_inst->data.emission; else rend_group->emission = emission; + data.render_group = rend_group; eff_inst->render_scene.Append(rend_group); } @@ -521,12 +527,14 @@ namespace Glitter { XRenderGroup* rend_group = new XRenderGroup(this); if (rend_group) { XEffectInst* effect = (XEffectInst*)parent->data.effect; - rend_group->alpha = effect->GetAlpha(); - rend_group->fog = effect->GetFog(); + rend_group->disp_type = effect->GetDispType(); + rend_group->fog_type = effect->GetFog(); + if (effect->data.emission >= min_emission) rend_group->emission = effect->data.emission; else rend_group->emission = emission; + data.render_group = rend_group; effect->render_scene.Append(rend_group); } diff --git a/src/CRE/Glitter/particle_manager.cpp b/src/CRE/Glitter/particle_manager.cpp index d1218793..18cc8aad 100644 --- a/src/CRE/Glitter/particle_manager.cpp +++ b/src/CRE/Glitter/particle_manager.cpp @@ -4,13 +4,24 @@ */ #include "glitter.hpp" +#include "../render_context.hpp" + +extern render_context* rctx_ptr; namespace Glitter { GltParticleManager glt_particle_manager; - GltParticleManager::GltParticleManager() :scene(), effect(), emitter(), particle(), rctx(), - bone_data(), frame_rate(), flags(), scene_load_counter(), emission(1.5f), delta_frame(2.0f), - texture_counter(), random(), counter(), draw_all(true), draw_all_mesh(true), draw_selected() { + Camera::Camera() : rotation_y() { + + } + + GltParticleManager::GltParticleManager() :scene(), effect(), emitter(), particle(), + bone_data(), frame_rate(), cam(), flags(), scene_load_counter(), + texture_counter(), random(), counter(), draw_selected() { + emission = 1.5f; + delta_frame = 2.0f; + draw_all = true; + draw_all_mesh = true; scenes.reserve(0x100); file_readers.reserve(0x100); } @@ -43,6 +54,16 @@ namespace Glitter { delta_frame = frame_rate->GetDeltaFrame(); else delta_frame = get_delta_frame(); + + camera* c = rctx_ptr->camera; + c->update(); + cam.projection = c->projection; + cam.view = c->view; + cam.inv_view = c->inv_view; + cam.inv_view_mat3 = c->inv_view_mat3; + cam.view_point = c->view_point; + cam.rotation_y = c->rotation.y; + CtrlScenes(); } return false; @@ -157,7 +178,7 @@ namespace Glitter { } } - void GltParticleManager::Disp(draw_pass_3d_type draw_pass_type) { + void GltParticleManager::DispScenes(DispType disp_type) { if (flags & PARTICLE_MANAGER_NOT_DISP) return; @@ -169,7 +190,7 @@ namespace Glitter { if (draw_selected && scene && scene != i) continue; #endif - i->Disp(this, draw_pass_type); + i->Disp(this, disp_type); } } diff --git a/src/CRE/Glitter/random.cpp b/src/CRE/Glitter/random.cpp index 49bfd924..3d01923c 100644 --- a/src/CRE/Glitter/random.cpp +++ b/src/CRE/Glitter/random.cpp @@ -1298,7 +1298,7 @@ namespace Glitter { return val % (max - min) + min; } - void Random::F2GetVec3(GLT, vec3* src, vec3* dst) { + void Random::F2GetVec3(GLT, vec3& src, vec3& dst) { vec3 val; switch (GLT_VAL) { default: @@ -1315,9 +1315,9 @@ namespace Glitter { } vec3 t; - vec3_add(*src, *src, t); + vec3_add(src, src, t); vec3_mult(val, t, val); - vec3_sub(val, *src, *dst); + vec3_sub(val, src, dst); } void Random::F2StepValue() { @@ -1358,7 +1358,7 @@ namespace Glitter { return val % (max - min) + min; } - void Random::XGetVec3(vec3* src, vec3* dst) { + void Random::XGetVec3(vec3& src, vec3& dst) { vec3 val; val.x = *(float_t*)&x_float_table[value % 0x169]; value += step; @@ -1368,9 +1368,9 @@ namespace Glitter { value += step; vec3 t; - vec3_add(*src, *src, t); + vec3_add(src, src, t); vec3_mult(val, t, val); - vec3_sub(val, *src, *dst); + vec3_sub(val, src, dst); } void Random::XReset() { diff --git a/src/CRE/Glitter/render_element.cpp b/src/CRE/Glitter/render_element.cpp index 7ca52a5f..72944046 100644 --- a/src/CRE/Glitter/render_element.cpp +++ b/src/CRE/Glitter/render_element.cpp @@ -6,6 +6,12 @@ #include "glitter.hpp" namespace Glitter { + RenderElement::RenderElement() : alive(), uv_index(), disp(), frame(), life_time(), + rebound_time(), frame_step_uv(), base_speed(), speed(), deceleration(), + scale_all(), fade_out_frames(), fade_in_frames(), locus_history(), random(), step() { + + } + void RenderElement::InitLocusHistory(GLT, F2ParticleInst* ptcl_inst, Random* random) { if (ptcl_inst->data.data.type == PARTICLE_LOCUS) { uint32_t locus_history_size = random->F2GetInt(GLT_VAL, @@ -45,7 +51,7 @@ namespace Glitter { vec3_mult_scalar(emit_inst->scale, emit_inst->scale_all, scale); vec3 position = vec3_null; - emit_inst->InitMesh(GLT_VAL, index, &scale, &position, &direction, random); + emit_inst->InitMesh(GLT_VAL, index, scale, position, direction, random); if (~ptcl_inst_data->data.flags & PARTICLE_EMITTER_LOCAL) mat4_mult_vec3(&emit_inst->mat_rot, &position, &position); @@ -55,7 +61,7 @@ namespace Glitter { translation_prev = base_translation; vec3 direction_random; - random->F2GetVec3(GLT_VAL, &ptcl_inst_data->data.direction_random, &direction_random); + random->F2GetVec3(GLT_VAL, ptcl_inst_data->data.direction_random, direction_random); vec3_add(direction, direction_random, direction); vec3_normalize(direction, direction); @@ -72,7 +78,7 @@ namespace Glitter { this->deceleration = max(deceleration * 60.0f, 0.0f); vec3 acceleration; - random->F2GetVec3(GLT_VAL, &ptcl_inst_data->data.acceleration_random, &acceleration); + random->F2GetVec3(GLT_VAL, ptcl_inst_data->data.acceleration_random, acceleration); vec3_add(acceleration, ptcl_inst_data->data.acceleration, acceleration); vec3_add(acceleration, ptcl_inst_data->data.gravity, this->acceleration); } @@ -92,7 +98,7 @@ namespace Glitter { vec3_mult_scalar(emit_inst->scale, emit_inst->scale_all, scale); vec3 position = vec3_null; - emit_inst->InitMesh(index, &scale, &position, &direction, random); + emit_inst->InitMesh(index, scale, position, direction, random); if (~ptcl_inst_data->data.flags & PARTICLE_EMITTER_LOCAL) mat4_mult_vec3(&emit_inst->mat_rot, &position, &position); @@ -102,7 +108,7 @@ namespace Glitter { translation_prev = base_translation; vec3 direction_random; - random->XGetVec3(&ptcl_inst_data->data.direction_random, &direction_random); + random->XGetVec3(ptcl_inst_data->data.direction_random, direction_random); vec3_add(direction, direction_random, direction); vec3_normalize(direction, direction); @@ -120,7 +126,7 @@ namespace Glitter { this->deceleration = max(deceleration, 0.0f); vec3 acceleration; - random->XGetVec3(&ptcl_inst_data->data.acceleration_random, &acceleration); + random->XGetVec3(ptcl_inst_data->data.acceleration_random, acceleration); vec3_add(acceleration, ptcl_inst_data->data.acceleration, acceleration); vec3_add(acceleration, ptcl_inst_data->data.gravity, this->acceleration); } diff --git a/src/CRE/Glitter/render_group.cpp b/src/CRE/Glitter/render_group.cpp index 60d40d88..2f2d77bd 100644 --- a/src/CRE/Glitter/render_group.cpp +++ b/src/CRE/Glitter/render_group.cpp @@ -9,14 +9,14 @@ namespace Glitter { RenderGroup::RenderGroup() : flags(), type(), draw_type(), pivot(), z_offset(), count(), ctrl(), disp(), texture(), mask_texture(), frame(), - elements(), max_count(), random_ptr(), alpha(), fog(), vbo(), ebo() { + elements(), max_count(), random_ptr(), disp_type(), fog_type(), vbo(), ebo() { split_u = 1; split_v = 1; split_uv = vec2_identity; mat = mat4_identity; mat_rot = mat4_identity; mat_draw = mat4_identity; - alpha = DRAW_PASS_3D_TRANSLUCENT; + disp_type = DISP_NORMAL; emission = 1.0f; blend_mode = PARTICLE_BLEND_TYPICAL; mask_blend_mode = PARTICLE_BLEND_TYPICAL; @@ -611,20 +611,17 @@ namespace Glitter { DeleteBuffers(true); } - bool XRenderGroup::GetEmitterScale(vec3* emitter_scale) { - *emitter_scale = vec3_identity; - + bool XRenderGroup::GetEmitterScale(vec3& emitter_scale) { if (particle) { - XEmitterInst* emitter = particle->data.emitter; - if (emitter) { - vec3_mult_scalar(emitter->scale, emitter->scale_all, *emitter_scale); - - float_t length; - vec3_length(*emitter_scale, length); - return length > 0.000001f; + Glitter::EmitterInst* emit_inst = particle->data.emitter; + if (emit_inst) { + vec3_mult_scalar(emit_inst->scale, emit_inst->scale_all, emitter_scale); + return emitter_scale.x > 0.000001f || emitter_scale.y > 0.000001f || emitter_scale.z > 0.000001f; } } - return true; + + emitter_scale = vec3_identity; + return false; } bool XRenderGroup::GetExtAnimScale(vec3* ext_anim_scale, float_t* some_scale) { diff --git a/src/CRE/Glitter/render_scene.cpp b/src/CRE/Glitter/render_scene.cpp index aa79b449..2f51efec 100644 --- a/src/CRE/Glitter/render_scene.cpp +++ b/src/CRE/Glitter/render_scene.cpp @@ -11,6 +11,8 @@ #include "../shader_ft.hpp" #include "../static_var.hpp" +extern render_context* rctx_ptr; + namespace Glitter { RenderScene::RenderScene() : ctrl_quad(), ctrl_line(), ctrl_locus(), ctrl_mesh(), disp_quad(), disp_line(), disp_locus(), disp_mesh() { @@ -281,9 +283,9 @@ namespace Glitter { vec3 x_vec = { 1.0f, 0.0f, 0.0f }; if (rend_group->flags & PARTICLE_LOCAL) { mat4 mat; - mat4_mult(&((render_context*)GPM_VAL->rctx)->camera->inv_view, &rend_group->mat, &mat); - mat4_mult(&((render_context*)GPM_VAL->rctx)->camera->view, &mat, &mat); - mat4_mult(&mat, &((render_context*)GPM_VAL->rctx)->camera->inv_view, &rend_group->mat_draw); + mat4_mult(&GPM_VAL->cam.inv_view, &rend_group->mat, &mat); + mat4_mult(&GPM_VAL->cam.view, &mat, &mat); + mat4_mult(&mat, &GPM_VAL->cam.inv_view, &rend_group->mat_draw); } else rend_group->mat_draw = mat4_identity; @@ -311,7 +313,7 @@ namespace Glitter { else model_mat = mat3_identity; - mat3_mult_vec(&((render_context*)GPM_VAL->rctx)->camera->inv_view_mat3, &x_vec, &x_vec); + mat3_mult_vec(&GPM_VAL->cam.inv_view_mat3, &x_vec, &x_vec); gl_state_bind_array_buffer(rend_group->vbo); Buffer* buf = (Buffer*)glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY); @@ -411,13 +413,13 @@ namespace Glitter { if (rend_group->flags & PARTICLE_EMITTER_LOCAL) { model_mat = rend_group->mat; mat4_normalize_rotation(&model_mat, &view_mat); - mat4_mult(&view_mat, &((render_context*)GPM_VAL->rctx)->camera->view, &view_mat); + mat4_mult(&view_mat, &GPM_VAL->cam.view, &view_mat); mat4_inverse(&view_mat, &inv_view_mat); } else { model_mat = mat4_identity; - view_mat = ((render_context*)GPM_VAL->rctx)->camera->view; - inv_view_mat = ((render_context*)GPM_VAL->rctx)->camera->inv_view; + view_mat = GPM_VAL->cam.view; + inv_view_mat = GPM_VAL->cam.inv_view; } if (rend_group->flags & PARTICLE_LOCAL) { @@ -426,7 +428,7 @@ namespace Glitter { mat4_inverse(&view_mat, &inv_view_mat); } - mat4_mult(&view_mat, &((render_context*)GPM_VAL->rctx)->camera->inv_view, &rend_group->mat_draw); + mat4_mult(&view_mat, &GPM_VAL->cam.inv_view, &rend_group->mat_draw); mat4 dir_mat; switch (rend_group->draw_type) { @@ -456,7 +458,7 @@ namespace Glitter { mat4_rotate_z((float_t)-M_PI_2, &dir_mat); break; case DIRECTION_BILLBOARD_Y_AXIS: - mat4_rotate_y(((render_context*)GPM_VAL->rctx)->camera->rotation.y, &dir_mat); + mat4_rotate_y(GPM_VAL->cam.rotation_y, &dir_mat); break; default: dir_mat = mat4_identity; @@ -607,7 +609,7 @@ namespace Glitter { if (fabsf(rend_group->z_offset) > 0.000001f) { use_z_offset = true; mat4_get_translation(model_mat, &dist_to_cam); - vec3_sub(((render_context*)GPM_VAL->rctx)->camera->view_point, dist_to_cam, dist_to_cam); + vec3_sub(GPM_VAL->cam.view_point, dist_to_cam, dist_to_cam); if (rend_group->flags & PARTICLE_EMITTER_LOCAL) { mat4_normalize_rotation(model_mat, &z_offset_inv_mat); mat4_inverse(&z_offset_inv_mat, &z_offset_inv_mat); @@ -830,7 +832,7 @@ namespace Glitter { gl_state_bind_array_buffer(0); } - void F2RenderScene::Disp(GPM, draw_pass_3d_type alpha) { + void F2RenderScene::Disp(GPM, DispType disp_type) { disp_quad = 0; disp_line = 0; disp_locus = 0; @@ -844,7 +846,7 @@ namespace Glitter { continue; F2RenderGroup* rend_group = i; - if ((rend_group)->alpha != alpha + if ((rend_group)->disp_type != disp_type || (rend_group->CannotDisp() && !GPM_VAL->draw_all)) continue; @@ -951,14 +953,14 @@ namespace Glitter { switch (rend_group->type) { case PARTICLE_QUAD: - switch (rend_group->fog) { + switch (rend_group->fog_type) { default: uniform_value[U_FOG_HEIGHT] = 0; break; - case FOG_DEPTH: + case Glitter::FOG_DEPTH: uniform_value[U_FOG_HEIGHT] = 1; break; - case FOG_HEIGHT: + case Glitter::FOG_HEIGHT: uniform_value[U_FOG_HEIGHT] = 2; break; } @@ -970,7 +972,7 @@ namespace Glitter { gl_state_set_depth_mask(GL_TRUE); } else { - uniform_value[U_ALPHA_BLEND] = rend_group->alpha != DRAW_PASS_3D_OPAQUE ? 2 : 0; + uniform_value[U_ALPHA_BLEND] = rend_group->disp_type ? 2 : 0; gl_state_enable_depth_test(); gl_state_set_depth_func(GL_LESS); gl_state_set_depth_mask(GL_FALSE); @@ -1010,9 +1012,7 @@ namespace Glitter { emission = rend_group->emission; shaders_ft.state_material_set_emission(false, emission, emission, emission, 1.0f); - shaders_ft.state_matrix_set_mvp(rend_group->mat_draw, - ((render_context*)GPM_VAL->rctx)->camera->view, - ((render_context*)GPM_VAL->rctx)->camera->projection); + shaders_ft.state_matrix_set_mvp(rend_group->mat_draw, GPM_VAL->cam.view, GPM_VAL->cam.projection); shaders_ft.state_matrix_set_texture(0, mat4_identity); shaders_ft.state_matrix_set_texture(1, mat4_identity); shaders_ft.env_vert_set(3, vec4_identity); @@ -1176,7 +1176,7 @@ namespace Glitter { bool has_scale = false; vec3 scale = vec3_null; if (rend_group->flags & PARTICLE_EMITTER_LOCAL) { - rend_group->GetEmitterScale(&scale); + rend_group->GetEmitterScale(scale); if (!(has_scale |= fabsf(scale.x) > 0.000001f ? true : false)) scale.x = 0.0f; if (!(has_scale |= fabsf(scale.y) > 0.000001f ? true : false)) @@ -1258,9 +1258,9 @@ namespace Glitter { vec3 x_vec = { 1.0f, 0.0f, 0.0f }; if (rend_group->flags & PARTICLE_LOCAL) { mat4 mat; - mat4_mult(&((render_context*)GPM_VAL->rctx)->camera->inv_view, &rend_group->mat, &mat); - mat4_mult(&((render_context*)GPM_VAL->rctx)->camera->view, &mat, &mat); - mat4_mult(&mat, &((render_context*)GPM_VAL->rctx)->camera->inv_view, &rend_group->mat_draw); + mat4_mult(&GPM_VAL->cam.inv_view, &rend_group->mat, &mat); + mat4_mult(&GPM_VAL->cam.view, &mat, &mat); + mat4_mult(&mat, &GPM_VAL->cam.inv_view, &rend_group->mat_draw); } else rend_group->mat_draw = mat4_identity; @@ -1286,7 +1286,7 @@ namespace Glitter { else model_mat = mat3_identity; - mat3_mult_vec(&((render_context*)GPM_VAL->rctx)->camera->inv_view_mat3, &x_vec, &x_vec); + mat3_mult_vec(&GPM_VAL->cam.inv_view_mat3, &x_vec, &x_vec); gl_state_bind_array_buffer(rend_group->vbo); Buffer* buf = (Buffer*)glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY); @@ -1389,31 +1389,29 @@ namespace Glitter { if (rend_group->flags & PARTICLE_EMITTER_LOCAL) { model_mat = rend_group->mat; mat4_normalize_rotation(&model_mat, &view_mat); - mat4_mult(&view_mat, &((render_context*)GPM_VAL->rctx)->camera->view, &view_mat); + mat4_mult(&view_mat, &GPM_VAL->cam.view, &view_mat); mat4_inverse(&view_mat, &inv_view_mat); emitter_local = true; if (rend_group->flags & PARTICLE_SCALE) { - rend_group->GetEmitterScale(&emit_scale); - if (fabsf(emit_scale.x) > 0.000001f - || fabsf(emit_scale.y) > 0.000001f || fabsf(emit_scale.z) > 0.000001f) + if (rend_group->GetEmitterScale(emit_scale)) has_scale = true; } } else { model_mat = mat4_identity; - view_mat = ((render_context*)GPM_VAL->rctx)->camera->view; - inv_view_mat = ((render_context*)GPM_VAL->rctx)->camera->inv_view; + view_mat = GPM_VAL->cam.view; + inv_view_mat = GPM_VAL->cam.inv_view; } - bool draw_local = false; + bool local = false; if (rend_group->flags & PARTICLE_LOCAL) { mat4_mult(&inv_view_mat, &rend_group->mat, &inv_view_mat); mat4_mult(&view_mat, &inv_view_mat, &view_mat); mat4_inverse(&view_mat, &inv_view_mat); - draw_local = true; + local = true; } - mat4_mult(&view_mat, &((render_context*)GPM_VAL->rctx)->camera->inv_view, &rend_group->mat_draw); + mat4_mult(&view_mat, &GPM_VAL->cam.inv_view, &rend_group->mat_draw); mat4 dir_mat = mat4_identity; vec3 up_vec = { 0.0f, 0.0f, 1.0f }; @@ -1444,13 +1442,43 @@ namespace Glitter { mat4_rotate_x((float_t)-M_PI_2, &dir_mat); break; case DIRECTION_BILLBOARD_Y_AXIS: - mat4_rotate_y(((render_context*)GPM_VAL->rctx)->camera->rotation.y, &dir_mat); + mat4_rotate_y(GPM_VAL->cam.rotation_y, &dir_mat); break; case DIRECTION_EMITTER_ROTATION: emitter_rotation = true; break; } + Particle* particle = rend_group->particle->data.particle; + object_info object_info; + object_info.set_id = (uint32_t)particle->data.mesh.object_set_name_hash; + object_info.id = (uint32_t)particle->data.mesh.object_name_hash; + obj* obj = object_storage_get_obj(object_info); + if (!obj) + return; + + texture_transform_struct tex_trans[2]; + int32_t tex_trans_count = 0; + + for (texture_transform_struct& i : tex_trans) { + tex_trans->id = hash_murmurhash_empty; + tex_trans->mat = mat4_identity; + } + + obj_material& material = obj->material_array[0].material; + + for (obj_material_texture_data& i : material.texdata) { + if (i.tex_index == hash_murmurhash_empty || i.tex_index == hash_murmurhash_null) + continue; + + tex_trans[tex_trans_count].id = i.tex_index; + tex_trans[tex_trans_count].mat = mat4_identity; + tex_trans_count++; + + if (++tex_trans_count == 2) + break; + } + vec3 ext_anim_scale; float_t some_scale = 0.0f; if (rend_group->GetExtAnimScale(&ext_anim_scale, &some_scale)) { @@ -1467,8 +1495,8 @@ namespace Glitter { vec3_add(emit_scale, ext_anim_scale, emit_scale); } - render_context* rctx = (render_context*)GPM_VAL->rctx; - object_data* object_data = &rctx->object_data; + object_data* object_data = &rctx_ptr->object_data; + object_data->set_texture_pattern(0, 0); RenderElement* elem = rend_group->elements; size_t disp = 0; @@ -1494,80 +1522,51 @@ namespace Glitter { mat4 mat; if (billboard) { - if (draw_local) + if (local) mat = mat4_identity; else mat = dir_mat; } - else if (rotate_func) + else if (rotate_func) { mat = rotate_func(rend_group, elem, &up_vec, &trans); + } else if (emitter_rotation) mat = elem->mat; else - mat = dir_mat; + mat = mat4_identity; - mat4_rotate(rot.x, rot.y, rot.z, &mat); - mat4_scale_rot(&mat, scale.x, scale.y, scale.z, &mat); mat4_set_translation(&mat, &trans); + mat4_rot(&mat, rot.x, rot.y, rot.z, &mat); + mat4_scale_rot(&mat, scale.x, scale.y, scale.z, &mat); - mat4 uv_mat[2]; - mat4_translate(elem->uv_scroll.x, -elem->uv_scroll.y, 0.0f, &uv_mat[0]); - mat4_translate(elem->uv_scroll_2nd.x, -elem->uv_scroll_2nd.y, 0.0f, &uv_mat[1]); - Particle* particle = rend_group->particle->data.particle; - object_info object_info; - object_info.set_id = (uint32_t)particle->data.mesh.object_set_name_hash; - object_info.id = (uint32_t)particle->data.mesh.object_name_hash; - obj* obj = object_storage_get_obj(object_info); - if (!obj) - continue; + vec3 uv_scroll; + vec3 uv_scroll_2nd; + uv_scroll.x = elem->uv_scroll.x; + uv_scroll.y = -elem->uv_scroll.y; + uv_scroll.z = 0.0f; + uv_scroll_2nd.x = elem->uv_scroll_2nd.x; + uv_scroll_2nd.y = -elem->uv_scroll_2nd.y; + uv_scroll_2nd.z = 0.0f; - object_data->texture_pattern_count = 0; - int32_t ttc = 0; - texture_transform_struct* tt = object_data->texture_transform_array; - for (uint32_t i = 0; i < obj->num_mesh; i++) { - obj_mesh* mesh = &obj->mesh_array[i]; - for (uint32_t j = 0; j < mesh->num_submesh; j++) { - obj_sub_mesh* sub_mesh = &mesh->submesh_array[j]; - obj_material* material = &obj->material_array[sub_mesh->material_index].material; + mat4_set_translation(&tex_trans[0].mat, &uv_scroll); + mat4_set_translation(&tex_trans[1].mat, &uv_scroll_2nd); - int32_t l = 0; - for (obj_material_texture_data& k : material->texdata) { - obj_material_texture_data* texture = &k; - if (texture->shader_info.m.tex_type != OBJ_MATERIAL_TEXTURE_COLOR) - continue; + object_data->set_texture_transform(tex_trans_count, tex_trans); - tt->id = texture->tex_index; - tt->mat = uv_mat[l]; - ttc++; - tt++; + if (local) + mat4_mult(&mat, &GPM_VAL->cam.inv_view, &mat); - if (++l == 2 || ttc == 24) - break; - } - - if (ttc == 24) - break; - } - - if (ttc == 24) - break; - } - object_data->texture_transform_count = ttc; - - if (rend_group->flags & PARTICLE_LOCAL) - mat4_mult(&mat, &((render_context*)GPM_VAL->rctx)->camera->inv_view, &mat); - - vec4u color = elem->color; - if (draw_task_add_draw_object_by_object_info_color(rctx, &mat, + vec4& color = elem->color; + if (draw_task_add_draw_object_by_object_info_color(rctx_ptr, &mat, object_info, color.x, color.y, color.z, color.w)) disp++; elem->mat_draw = mat; - object_data->texture_pattern_count = 0; - object_data->texture_transform_count = 0; + object_data->set_texture_transform(0, 0); } } + object_data->set_texture_pattern(0, 0); rend_group->disp = disp; } @@ -1587,13 +1586,13 @@ namespace Glitter { mat4_clear_rot(&rend_group->mat, &view_mat); else mat4_normalize_rotation(&rend_group->mat, &view_mat); - mat4_mult(&view_mat, &((render_context*)GPM_VAL->rctx)->camera->view, &view_mat); + mat4_mult(&view_mat, &GPM_VAL->cam.view, &view_mat); mat4_inverse(&view_mat, &inv_view_mat); } else { model_mat = mat4_identity; - view_mat = ((render_context*)GPM_VAL->rctx)->camera->view; - inv_view_mat = ((render_context*)GPM_VAL->rctx)->camera->inv_view; + view_mat = GPM_VAL->cam.view; + inv_view_mat = GPM_VAL->cam.inv_view; } if (rend_group->flags & PARTICLE_LOCAL) { @@ -1601,7 +1600,7 @@ namespace Glitter { mat4_mult(&view_mat, &inv_view_mat, &view_mat); mat4_inverse(&view_mat, &inv_view_mat); } - mat4_mult(&view_mat, &((render_context*)GPM_VAL->rctx)->camera->inv_view, &rend_group->mat_draw); + mat4_mult(&view_mat, &GPM_VAL->cam.inv_view, &rend_group->mat_draw); switch (rend_group->draw_type) { case DIRECTION_BILLBOARD: @@ -1619,7 +1618,7 @@ namespace Glitter { mat4_rotate_x((float_t)-M_PI_2, &dir_mat); break; case DIRECTION_BILLBOARD_Y_AXIS: - mat4_rotate_y(((render_context*)GPM_VAL->rctx)->camera->rotation.y, &dir_mat); + mat4_rotate_y(GPM_VAL->cam.rotation_y, &dir_mat); break; default: dir_mat = mat4_identity; @@ -1664,7 +1663,7 @@ namespace Glitter { bool use_scale = false; vec3 scale = vec3_identity; if (rend_group->flags & PARTICLE_EMITTER_LOCAL - && rend_group->GetEmitterScale(&scale)) + && rend_group->GetEmitterScale(scale)) use_scale = rend_group->flags & PARTICLE_SCALE ? true : false; gl_state_bind_array_buffer(rend_group->vbo); @@ -1771,7 +1770,7 @@ namespace Glitter { if (fabsf(rend_group->z_offset) > 0.000001f) { use_z_offset = true; mat4_get_translation(model_mat, &dist_to_cam); - vec3_sub(((render_context*)GPM_VAL->rctx)->camera->view_point, dist_to_cam, dist_to_cam); + vec3_sub(GPM_VAL->cam.view_point, dist_to_cam, dist_to_cam); if (rend_group->flags & PARTICLE_EMITTER_LOCAL) { mat4_normalize_rotation(model_mat, &z_offset_inv_mat); mat4_inverse(&z_offset_inv_mat, &z_offset_inv_mat); @@ -1782,7 +1781,7 @@ namespace Glitter { bool emitter_local = false; vec3 scale = vec3_null; if (rend_group->flags & PARTICLE_EMITTER_LOCAL) { - rend_group->GetEmitterScale(&scale); + rend_group->GetEmitterScale(scale); if (rend_group->flags & PARTICLE_SCALE) { x_vec.x = scale.x; y_vec.y = scale.y; @@ -2009,7 +2008,7 @@ namespace Glitter { } } - void XRenderScene::Disp(GPM, draw_pass_3d_type alpha) { + void XRenderScene::Disp(GPM, DispType disp_type) { disp_quad = 0; disp_line = 0; disp_locus = 0; @@ -2022,7 +2021,7 @@ namespace Glitter { continue; XRenderGroup* rend_group = i; - if ((rend_group)->alpha != alpha || rend_group->CannotDisp() && !GPM_VAL->draw_all) + if ((rend_group)->disp_type != disp_type || rend_group->CannotDisp() && !GPM_VAL->draw_all) continue; #if !defined(CRE_DEV) @@ -2126,22 +2125,22 @@ namespace Glitter { uniform_value[U_TEXTURE_BLEND] = 0; } - switch (rend_group->fog) { + switch (rend_group->fog_type) { default: uniform_value[U_FOG_HEIGHT] = 0; break; - case FOG_DEPTH: + case Glitter::FOG_DEPTH: uniform_value[U_FOG_HEIGHT] = 1; break; - case FOG_HEIGHT: + case Glitter::FOG_HEIGHT: uniform_value[U_FOG_HEIGHT] = 2; break; } if (rend_group->blend_mode == PARTICLE_BLEND_PUNCH_THROUGH) - uniform_value[U_ALPHA_BLEND] = rend_group->alpha != DRAW_PASS_3D_OPAQUE ? 3 : 1; + uniform_value[U_ALPHA_BLEND] = rend_group->disp_type ? 3 : 1; else - uniform_value[U_ALPHA_BLEND] = rend_group->alpha != DRAW_PASS_3D_OPAQUE ? 2 : 0; + uniform_value[U_ALPHA_BLEND] = rend_group->disp_type ? 2 : 0; if (~rend_group->particle->data.flags & PARTICLE_DEPTH_TEST) { gl_state_enable_depth_test(); @@ -2167,9 +2166,7 @@ namespace Glitter { emission = rend_group->emission; shaders_ft.state_material_set_emission(false, emission, emission, emission, 1.0f); - shaders_ft.state_matrix_set_mvp(rend_group->mat_draw, - ((render_context*)GPM_VAL->rctx)->camera->view, - ((render_context*)GPM_VAL->rctx)->camera->projection); + shaders_ft.state_matrix_set_mvp(rend_group->mat_draw, GPM_VAL->cam.view, GPM_VAL->cam.projection); shaders_ft.state_matrix_set_texture(0, mat4_identity); shaders_ft.state_matrix_set_texture(1, mat4_identity); shaders_ft.env_vert_set(3, vec4_identity); diff --git a/src/CRE/Glitter/scene.cpp b/src/CRE/Glitter/scene.cpp index 5c21ac48..f4a16475 100644 --- a/src/CRE/Glitter/scene.cpp +++ b/src/CRE/Glitter/scene.cpp @@ -22,7 +22,7 @@ namespace Glitter { effects.reserve(eff_group->effects.size()); emission = eff_group->emission; if (a5) - enum_or(flags, SCENE_FLAG_4); + enum_or(flags, SCENE_FLAG_3); } } @@ -32,7 +32,7 @@ namespace Glitter { } bool Scene::Copy(Glitter::EffectInst* eff_inst, Glitter::Scene* dst) { - if (~flags & SCENE_FLAG_4) + if (~flags & SCENE_FLAG_3) return flags; for (SceneEffect& i : effects) @@ -63,7 +63,7 @@ namespace Glitter { i.ptr->Ctrl(GPM_VAL, type, delta_frame, emission); } - void Scene::Disp(GPM, draw_pass_3d_type alpha) { + void Scene::Disp(GPM, DispType disp_type) { if (flags & SCENE_NOT_DISP) return; @@ -73,7 +73,7 @@ namespace Glitter { if (GPM_VAL->draw_selected && GPM_VAL->effect && GPM_VAL->effect != i.ptr) continue; #endif - i.ptr->Disp(GPM_VAL, alpha); + i.ptr->Disp(GPM_VAL, disp_type); } } diff --git a/src/CRE/auth_3d.cpp b/src/CRE/auth_3d.cpp index 3c6b06c9..aa423d79 100644 --- a/src/CRE/auth_3d.cpp +++ b/src/CRE/auth_3d.cpp @@ -5,7 +5,7 @@ #include "auth_3d.hpp" #include "../KKdLib/hash.hpp" -#include "../KKdLib/interpolation.h" +#include "../KKdLib/interpolation.hpp" #include "../KKdLib/sort.hpp" #include "../KKdLib/str_utils.hpp" #include "rob/rob.hpp" @@ -262,8 +262,6 @@ void auth_3d::ctrl(render_context* rctx) { if (state != 2 || !enable) return; - mat4 mat = this->mat; - bool set = false; while (true) { if (frame_changed) { @@ -380,8 +378,6 @@ void auth_3d::disp(render_context* rctx) { if (state != 2 || !enable) return; - mat4 mat = this->mat; - auth_3d_set_material_list(this, rctx); for (auth_3d_point& i : point) @@ -646,7 +642,7 @@ void auth_3d::load_from_farc(farc* f, const char* file, void auth_3d::reset() { uid = -1; id = -1; - mat = mat4u_identity; + mat = mat4_identity; enable = false; camera_root_update = true; visible = true; @@ -854,7 +850,7 @@ void auth_3d_rgba::reset() { g.reset(); b.reset(); a.reset(); - value = vec4u_null; + value = vec4_null; } auth_3d_vec3::auth_3d_vec3() { @@ -898,7 +894,7 @@ void auth_3d_model_transform::interpolate(float_t frame) { } void auth_3d_model_transform::reset() { - mat = mat4u_identity; + mat = mat4_identity; scale.reset(); rotation.reset(); translation.reset(); @@ -1078,7 +1074,7 @@ void auth_3d_fog::reset() { end_value = 0.0f; start_value = 0.0f; - color_init = vec4u_null; + color_init = vec4_null; density_init = 0.0f; end_init = 0.0f; start_init = 0.0f; @@ -1121,16 +1117,16 @@ void auth_3d_light::reset() { intensity_value = 0.0f; linear_value = 0.0f; quadratic_value = 0.0f; - ambient_init = vec4u_null; + ambient_init = vec4_null; cone_angle_init = 0.0f; constant_init = 0.0f; - diffuse_init = vec4u_null; + diffuse_init = vec4_null; drop_off_init = 0.0f; far_init = 0.0f; intensity_init = 0.0f; linear_init = 0.0f; quadratic_init = 0.0f; - specular_init = vec4u_null; + specular_init = vec4_null; tone_curve_init = vec3_null; } @@ -1309,9 +1305,9 @@ auth_3d_object_model_transform::~auth_3d_object_model_transform() { } void auth_3d_object_model_transform::reset() { - mat = mat4u_identity; - mat_inner = mat4u_identity; - mat_rot = mat4u_identity; + mat = mat4_identity; + mat_inner = mat4_identity; + mat_rot = mat4_identity; translation.reset(); rotation.reset(); scale.reset(); @@ -1340,7 +1336,7 @@ void auth_3d_object_node::reset() { flags = (auth_3d_object_node_flags)0; bone_id = -1; joint_orient = vec3_null; - joint_orient_mat = mat4u_identity; + joint_orient_mat = mat4_identity; mat = 0; model_transform.reset(); name.clear(); @@ -1375,7 +1371,7 @@ void auth_3d_object_texture_transform::reset() { flags = (auth_3d_object_texture_transform_flags)0; coverage_u.reset(); coverage_v.reset(); - mat = mat4u_identity; + mat = mat4_identity; name.clear(); name.shrink_to_fit(); offset_u.reset(); @@ -1448,7 +1444,7 @@ void auth_3d_post_process::reset() { lens_ghost_init = 1.0f; lens_shaft_init = 1.0f; radius_init = vec3_null; - scene_fade_init = vec4u_null; + scene_fade_init = vec4_null; } auth_3d_farc::auth_3d_farc() : load_count(), name(), state(), farc(), data(), size() { @@ -2519,7 +2515,7 @@ static void auth_3d_set_material_list(auth_3d* auth, render_context* rctx) { material_list_struct mat_list[TEXTURE_PATTERN_COUNT]; for (auth_3d_material_list& i : auth->material_list) { if (i.blend_color.flags) { - vec4u& blend_color = mat_list[mat_list_count].blend_color; + vec4& blend_color = mat_list[mat_list_count].blend_color; vec4u8& has_blend_color = mat_list[mat_list_count].has_blend_color; blend_color = i.blend_color.value; @@ -2534,7 +2530,7 @@ static void auth_3d_set_material_list(auth_3d* auth, render_context* rctx) { } if (i.incandescence.flags) { - vec4u& emission = mat_list[mat_list_count].emission; + vec4& emission = mat_list[mat_list_count].emission; vec4u8& has_emission = mat_list[mat_list_count].has_emission; emission = i.incandescence.value; @@ -2692,7 +2688,7 @@ static void auth_3d_camera_root_ctrl(auth_3d_camera_root* cr, cr->model_transform.interpolate(frame); auth_3d_model_transform_set_mat(&cr->model_transform, &mat4_identity); - mat4 cr_mat = cr->model_transform.mat; + mat4& cr_mat = cr->model_transform.mat; vec3 view_point = cr->view_point.model_transform.translation.interpolate(frame); mat4_mult_vec3_trans(&cr_mat, &view_point, &cr->view_point_value); @@ -3183,10 +3179,10 @@ static void auth_3d_m_object_hrc_disp(auth_3d_m_object_hrc* moh, auth_3d* auth, if (shad && flags & DRAW_TASK_SHADOW) { object_data->set_shadow_type(SHADOW_STAGE); - mat4u* m = &moh->model_transform.mat; + mat4* m = &moh->model_transform.mat; for (auth_3d_object_node& j : moh->node) if (j.mat) { - m = (mat4u*)j.mat; + m = j.mat; break; } @@ -3199,11 +3195,9 @@ static void auth_3d_m_object_hrc_disp(auth_3d_m_object_hrc* moh, auth_3d* auth, shad->field_1D0[shadow_type].push_back(pos); } - if (i.mats.size() > 0) { - mat4 mat = i.model_transform.mat; + if (i.mats.size() > 0) draw_task_add_draw_object_by_object_info_object_skin(rctx, - i.object_info, 0, 0, auth->alpha, i.mats.data(), 0, 0, &mat); - } + i.object_info, 0, 0, auth->alpha, i.mats.data(), 0, 0, &i.model_transform.mat); } object_data->set_draw_task_flags(); @@ -3221,7 +3215,7 @@ static void auth_3d_m_object_hrc_list_ctrl(auth_3d_m_object_hrc* moh, mat4* pare auth_3d_object_model_transform_mat_mult(&moh->model_transform, parent_mat); - mat4 mat = moh->model_transform.mat; + mat4& mat = moh->model_transform.mat; for (auth_3d_object_instance& i : moh->instance) { //if (!i.model_transform.visible) @@ -3240,10 +3234,9 @@ static void auth_3d_m_object_hrc_nodes_mat_mult(auth_3d_m_object_hrc* moh) { auth_3d_object_node* node = moh->node.data(); for (auth_3d_object_node& i : moh->node) - if (i.parent >= 0) { - mat4 mat = node[i.parent].model_transform.mat; - auth_3d_object_model_transform_mat_mult(&i.model_transform, &mat); - } + if (i.parent >= 0) + auth_3d_object_model_transform_mat_mult( + &i.model_transform, &node[i.parent].model_transform.mat); else i.model_transform.mat = i.model_transform.mat_inner; } @@ -3274,7 +3267,7 @@ static void auth_3d_material_list_load(auth_3d* auth, auth_3d_material_list* ml, } ml->name = mlf->name; - ml->hash = hash_string_murmurhash(&ml->name); + ml->hash = hash_string_murmurhash(ml->name); } static void auth_3d_material_list_set(auth_3d_material_list* ml) { @@ -3344,7 +3337,7 @@ static void auth_3d_object_load(auth_3d* auth, auth_3d_object* o, o->refract = strstr(o->uid_name.c_str(), "_REFRACT") ? true : false; o->object_info = obj_db->get_object_info(o->uid_name.c_str()); - o->object_hash = hash_string_murmurhash(&o->uid_name); + o->object_hash = hash_string_murmurhash(o->uid_name); } static void auth_3d_object_curve_ctrl(auth_3d_object_curve* oc, float_t frame) { @@ -3398,7 +3391,7 @@ static void auth_3d_object_disp(auth_3d_object* o, auth_3d* auth, render_context rob_chara* rob_chr = rob_chara_array_get(auth->chara_id); mat4 m; mat4_mult(&rob_chr->data.miku_rot.field_6C, - &rob_chr->data.adjust_data.mat, (mat4u*)&m); + &rob_chr->data.adjust_data.mat, &m); mat4_mult(&m, &mat, &mat); object_data->set_shadow_type(auth->chara_id ? SHADOW_STAGE : SHADOW_CHARA); } @@ -3517,7 +3510,7 @@ static void auth_3d_object_list_ctrl(auth_3d_object* o, mat4* parent_mat) { auth_3d_model_transform_set_mat(&o->model_transform, parent_mat); - mat4 mat = o->model_transform.mat; + mat4& mat = o->model_transform.mat; for (auth_3d_object*& i : o->children_object) auth_3d_object_list_ctrl(i, &mat); @@ -3549,7 +3542,7 @@ static void auth_3d_object_hrc_load(auth_3d* auth, auth_3d_object_hrc* oh, oh->refract = strstr(oh->uid_name.c_str(), "_REFRACT") ? true : false; oh->object_info = obj_db->get_object_info(oh->uid_name.c_str()); - oh->object_hash = hash_string_murmurhash(&oh->uid_name); + oh->object_hash = hash_string_murmurhash(oh->uid_name); obj_skin* skin = object_storage_get_obj_skin(oh->object_info); if (!skin) @@ -3560,7 +3553,7 @@ static void auth_3d_object_hrc_load(auth_3d* auth, auth_3d_object_hrc* oh, for (auth_3d_object_node& i : oh->node) { i.bone_id = -1; - uint64_t name_hash = hash_string_fnv1a64m(&i.name); + uint64_t name_hash = hash_string_fnv1a64m(i.name); for (uint32_t j = 0; j < skin->bones_count; j++) if (hash_utf8_fnv1a64m(skin->bones[j].name) == name_hash) { i.bone_id = skin->bones[j].id; @@ -3598,7 +3591,7 @@ static void auth_3d_object_hrc_disp(auth_3d_object_hrc* oh, auth_3d* auth, rende if (rob_chara_pv_data_array_check_chara_id(auth->chara_id)) { rob_chara* rob_chr = rob_chara_array_get(auth->chara_id); mat4_mult(&rob_chr->data.miku_rot.field_6C, - &rob_chr->data.adjust_data.mat, (mat4u*)&mat); + &rob_chr->data.adjust_data.mat, &mat); if (auth->chara_id) object_data->set_shadow_type(SHADOW_STAGE); } @@ -3606,10 +3599,10 @@ static void auth_3d_object_hrc_disp(auth_3d_object_hrc* oh, auth_3d* auth, rende else if (flags & DRAW_TASK_SHADOW) { object_data->set_shadow_type(SHADOW_STAGE); - mat4u* m = &oh->node[0].model_transform.mat; + mat4* m = &oh->node[0].model_transform.mat; for (auth_3d_object_node& i : oh->node) if (i.mat) { - m = (mat4u*)i.mat; + m = i.mat; break; } @@ -3643,17 +3636,15 @@ static void auth_3d_object_hrc_list_ctrl(auth_3d_object_hrc* oh, mat4* mat) { int32_t* childer_object_parent_node = oh->childer_object_parent_node.data(); size_t children_object_count = oh->children_object.size(); - for (size_t i = 0; i < children_object_count; i++) { - mat4 mat = oh->node[childer_object_parent_node[i]].model_transform.mat; - auth_3d_object_list_ctrl(oh->children_object[i], &mat); - } + for (size_t i = 0; i < children_object_count; i++) + auth_3d_object_list_ctrl(oh->children_object[i], + &oh->node[childer_object_parent_node[i]].model_transform.mat); int32_t* childer_object_hrc_parent_node = oh->childer_object_hrc_parent_node.data(); size_t children_object_hrc_count = oh->children_object_hrc.size(); - for (size_t i = 0; i < children_object_hrc_count; i++) { - mat4 mat = oh->node[childer_object_hrc_parent_node[i]].model_transform.mat; - auth_3d_object_hrc_list_ctrl(oh->children_object_hrc[i], &mat); - } + for (size_t i = 0; i < children_object_hrc_count; i++) + auth_3d_object_hrc_list_ctrl(oh->children_object_hrc[i], + &oh->node[childer_object_hrc_parent_node[i]].model_transform.mat); } static void auth_3d_object_hrc_nodes_mat_mult(auth_3d_object_hrc* oh, mat4* mat) { @@ -3666,8 +3657,7 @@ static void auth_3d_object_hrc_nodes_mat_mult(auth_3d_object_hrc* oh, mat4* mat) else m = *mat; - mat4 joint_orient = i.joint_orient_mat; - mat4_mult(&joint_orient, &m, &m); + mat4_mult(&i.joint_orient_mat, &m, &m); auth_3d_object_model_transform_mat_mult(&i.model_transform, &m); if (i.mat) @@ -3683,7 +3673,7 @@ static void auth_3d_object_instance_load(auth_3d* auth, auth_3d_object_instance* oi->uid_name = oif->uid_name; oi->object_info = obj_db->get_object_info(oi->uid_name.c_str()); - oi->object_hash = hash_string_murmurhash(&oi->uid_name); + oi->object_hash = hash_string_murmurhash(oi->uid_name); obj_skin* skin = object_storage_get_obj_skin(oi->object_info); if (!skin) @@ -3698,7 +3688,7 @@ static void auth_3d_object_instance_load(auth_3d* auth, auth_3d_object_instance* for (uint32_t i = 0; i < skin->bones_count; i++) { uint64_t name_hash = hash_utf8_fnv1a64m(skin->bones[i].name); for (auth_3d_object_node& j : moh->node) - if (hash_string_fnv1a64m(&j.name) == name_hash) { + if (hash_string_fnv1a64m(j.name) == name_hash) { int32_t bone_id = skin->bones[i].id; if (~bone_id & 0x8000) object_bone_indices[bone_id] = (int32_t)(&j - moh->node.data()); @@ -3720,10 +3710,8 @@ static void auth_3d_object_model_transform_ctrl(auth_3d_object_model_transform* if (obj_mt->has_visibility) obj_mt->visible = obj_mt->visibility.interpolate(frame) >= 0.99900001f; - mat4 mat_rot; - vec3 rotation = obj_mt->rotation_value; - mat4_rotate(rotation.x, rotation.y, rotation.z, &mat_rot); - obj_mt->mat_rot = mat_rot; + vec3& rotation = obj_mt->rotation_value; + mat4_rotate(rotation.x, rotation.y, rotation.z, &obj_mt->mat_rot); obj_mt->frame = frame; obj_mt->has_rotation = false; obj_mt->has_translation = false; @@ -3731,9 +3719,9 @@ static void auth_3d_object_model_transform_ctrl(auth_3d_object_model_transform* static void auth_3d_object_model_transform_load(auth_3d* auth, auth_3d_object_model_transform* omt, auth_3d_model_transform_file* mtf) { - omt->mat = mat4u_identity; - omt->mat_inner = mat4u_identity; - omt->mat_rot = mat4u_identity; + omt->mat = mat4_identity; + omt->mat_inner = mat4_identity; + omt->mat_rot = mat4_identity; omt->translation_value = vec3_null; omt->rotation_value = vec3_null; omt->scale_value = vec3_identity; @@ -3767,9 +3755,7 @@ static void auth_3d_object_model_transform_load(auth_3d* auth, } static void auth_3d_object_model_transform_mat_mult(auth_3d_object_model_transform* obj_mt, mat4* mat) { - mat4 obj_mt_mat = obj_mt->mat_inner; - mat4_mult(&obj_mt_mat, mat, &obj_mt_mat); - obj_mt->mat = obj_mt_mat; + mat4_mult(&obj_mt->mat_inner, mat, &obj_mt->mat); } static void auth_3d_object_model_transform_set_mat_inner(auth_3d_object_model_transform* obj_mt) { @@ -3777,11 +3763,10 @@ static void auth_3d_object_model_transform_set_mat_inner(auth_3d_object_model_tr return; mat4 mat; - vec3 translation = obj_mt->translation_value; + vec3& translation = obj_mt->translation_value; mat4_translate(translation.x, translation.y, translation.z, &mat); - mat4 mat_rot = obj_mt->mat_rot; - mat4_mult(&mat_rot, &mat, &mat); + mat4_mult(&obj_mt->mat_rot, &mat, &mat); if (obj_mt->has_scale) { vec3 scale = obj_mt->scale_value; mat4_scale_rot(&mat, scale.x, scale.y, scale.z, &mat); @@ -3793,16 +3778,15 @@ static void auth_3d_object_model_transform_set_mat_inner(auth_3d_object_model_tr static void auth_3d_object_node_load(auth_3d* auth, auth_3d_object_node* on, auth_3d_object_node_file* onf) { if (onf->flags & A3DA_OBJECT_NODE_JOINT_ORIENT) { - vec3 rot = onf->joint_orient; - mat4 mat; - mat4_rotate(rot.x, rot.y, rot.z, &mat); + vec3& rot = onf->joint_orient; on->joint_orient = rot; - on->joint_orient_mat = mat; + mat4 mat; + mat4_rotate(rot.x, rot.y, rot.z, &on->joint_orient_mat); enum_or(on->flags, AUTH_3D_OBJECT_NODE_JOINT_ORIENT); } else { on->joint_orient = vec3_null; - on->joint_orient_mat = mat4u_identity; + on->joint_orient_mat = mat4_identity; } auth_3d_object_model_transform_load(auth, &on->model_transform, &onf->model_transform); @@ -4059,10 +4043,8 @@ static void auth_3d_post_process_restore_prev_value(auth_3d_post_process* pp, re if (pp->flags_init & AUTH_3D_POST_PROCESS_RADIUS) blur->set_radius(pp->radius_init); - if (pp->flags_init & AUTH_3D_POST_PROCESS_SCENE_FADE) { - vec4 scene_fade_init = pp->scene_fade_init; - tm->set_scene_fade(scene_fade_init); - } + if (pp->flags_init & AUTH_3D_POST_PROCESS_SCENE_FADE) + tm->set_scene_fade(pp->scene_fade_init); } static void auth_3d_post_process_set(auth_3d_post_process* pp, render_context* rctx) { @@ -4120,8 +4102,7 @@ static void auth_3d_post_process_set(auth_3d_post_process* pp, render_context* r enum_or(pp->flags_init, AUTH_3D_POST_PROCESS_SCENE_FADE); } - vec4 scene_fade = pp->scene_fade.value; - tm->set_scene_fade(scene_fade); + tm->set_scene_fade(pp->scene_fade.value); } } @@ -4180,7 +4161,7 @@ static auth_3d_farc* auth_3d_data_struct_get_farc( uint64_t name_hash = hash_utf8_fnv1a64m(category_name); for (auth_3d_farc& i : auth_3d_data->farcs) - if (hash_string_fnv1a64m(&i.name) == name_hash) + if (hash_string_fnv1a64m(i.name) == name_hash) return &i; return 0; } diff --git a/src/CRE/auth_3d.hpp b/src/CRE/auth_3d.hpp index b9c21ee7..20114981 100644 --- a/src/CRE/auth_3d.hpp +++ b/src/CRE/auth_3d.hpp @@ -214,7 +214,7 @@ struct auth_3d_rgba { auth_3d_key b; auth_3d_key a; - vec4u value; + vec4 value; auth_3d_rgba(); ~auth_3d_rgba(); @@ -236,7 +236,7 @@ struct auth_3d_vec3 { }; struct auth_3d_model_transform { - mat4u mat; + mat4 mat; auth_3d_vec3 scale; auth_3d_vec3 rotation; auth_3d_vec3 translation; @@ -382,7 +382,7 @@ struct auth_3d_fog { float_t end_value; float_t start_value; - vec4u color_init; + vec4 color_init; float_t density_init; float_t end_init; float_t start_init; @@ -420,16 +420,16 @@ struct auth_3d_light { float_t linear_value; float_t quadratic_value; - vec4u ambient_init; + vec4 ambient_init; float_t cone_angle_init; float_t constant_init; - vec4u diffuse_init; + vec4 diffuse_init; float_t drop_off_init; float_t far_init; float_t intensity_init; float_t linear_init; float_t quadratic_init; - vec4u specular_init; + vec4 specular_init; vec3 tone_curve_init; auth_3d_light(); @@ -439,9 +439,9 @@ struct auth_3d_light { }; struct auth_3d_object_model_transform { - mat4u mat; - mat4u mat_inner; - mat4u mat_rot; + mat4 mat; + mat4 mat_inner; + mat4 mat_rot; auth_3d_vec3 translation; auth_3d_vec3 rotation; auth_3d_vec3 scale; @@ -569,7 +569,7 @@ struct auth_3d_object_node { auth_3d_object_node_flags flags; int32_t bone_id; vec3 joint_orient; - mat4u joint_orient_mat; + mat4 joint_orient_mat; mat4* mat; auth_3d_object_model_transform model_transform; std::string name; @@ -596,7 +596,7 @@ struct auth_3d_object_texture_transform { auth_3d_object_texture_transform_flags flags; auth_3d_key coverage_u; auth_3d_key coverage_v; - mat4u mat; + mat4 mat; std::string name; auth_3d_key offset_u; auth_3d_key offset_v; @@ -657,7 +657,7 @@ struct auth_3d_post_process { float_t lens_ghost_init; float_t lens_shaft_init; vec3 radius_init; - vec4u scene_fade_init; + vec4 scene_fade_init; auth_3d_post_process(); ~auth_3d_post_process(); @@ -675,7 +675,7 @@ struct auth_3d { bool ended; bool left_right_reverse; bool once; - mat4u mat; + mat4 mat; float_t alpha; draw_task_flags draw_task_flags; int32_t chara_id; diff --git a/src/CRE/camera.cpp b/src/CRE/camera.cpp index 8094730b..49eb4f31 100644 --- a/src/CRE/camera.cpp +++ b/src/CRE/camera.cpp @@ -205,17 +205,17 @@ void camera::reset() { update(); } -void camera::move(vec2d& move) { - if (memcmp(&move, &vec2d_null, sizeof(vec2d))) { +void camera::move(double_t move_x, double_t move_y) { + if (move_x != 0.0 || move_y != 0.0) { vec3 temp; vec3 view_point; vec3 interest; vec3 up = { 0.0f, 1.0f, 0.0f }; vec3_cross(forward, up, temp); vec3_normalize(temp, temp); - vec3_mult_scalar(temp, (float_t)move.y, temp); + vec3_mult_scalar(temp, (float_t)move_y, temp); vec3_add(this->view_point, temp, view_point); - vec3_mult_scalar(forward, (float_t)move.x, temp); + vec3_mult_scalar(forward, (float_t)move_x, temp); vec3_add(view_point, temp, view_point); vec3_add(view_point, forward, interest); @@ -224,18 +224,14 @@ void camera::move(vec2d& move) { } } -void camera::move(vec2d&& move) { - this->move(*(vec2d*)&move); -} +void camera::rotate(double_t rotate_x, double_t rotate_y) { + if (rotate_x != 0.0) + set_yaw(get_yaw() + rotate_x); -void camera::rotate(vec2d& rotate) { - if (rotate.x != 0.0) - set_yaw(get_yaw() + rotate.x); + if (rotate_y != 0.0) + set_pitch(get_pitch() + rotate_y); - if (rotate.y != 0.0) - set_pitch(get_pitch() + rotate.y); - - if (memcmp(&rotate, &vec2d_null, sizeof(vec2d))) { + if (rotate_x != 0.0 || rotate_y != 0.0) { camera_calculate_forward(this); vec3 interest; @@ -244,10 +240,6 @@ void camera::rotate(vec2d& rotate) { } } -void camera::rotate(vec2d&& rotate) { - this->rotate(*(vec2d*)&rotate); -} - void camera::set(const vec3& view_point, const vec3& interest, const vec3& trans, const vec3& rot, const vec3& scale, double_t roll, double_t fov) { vec3 _vp; diff --git a/src/CRE/camera.hpp b/src/CRE/camera.hpp index 55f85810..3a29941e 100644 --- a/src/CRE/camera.hpp +++ b/src/CRE/camera.hpp @@ -76,10 +76,8 @@ struct camera { void set_fast_change_hist0(bool value); void set_fast_change_hist1(bool value); void reset(); - void move(vec2d& move); - void move(vec2d&& move); - void rotate(vec2d& rotate); - void rotate(vec2d&& rotate); + void move(double_t move_x, double_t move_y); + void rotate(double_t rotate_x, double_t rotate_y); void set(const vec3& view_point, const vec3& interest, const vec3& trans, const vec3& rot, const vec3& scale, double_t roll, double_t fov); void set(const vec3&& view_point, const vec3&& interest, diff --git a/src/CRE/data.cpp b/src/CRE/data.cpp index fa45819b..528ecc74 100644 --- a/src/CRE/data.cpp +++ b/src/CRE/data.cpp @@ -664,7 +664,7 @@ data_f2::~data_f2() { } #endif -data_ft::data_ft() : obj_db(), stage_data(), base_obj_db(), base_stage_data() { +data_ft::data_ft() { } @@ -935,17 +935,18 @@ static void data_load_inner(stream& s) { data_struct* ds = &data_list[DATA_AFT]; data_ft* d = &ds->data_ft; - { - auth_3d_database_file* base_auth_3d_db = &d->base_auth_3d_db; - *base_auth_3d_db = auth_3d_database_file(); - ds->load_file(base_auth_3d_db, "rom/auth_3d/", - "auth_3d_db.bin", auth_3d_database_file::load_file); + static const char* prefixes[] = { + "", + "mdata_", + }; - auth_3d_database_file mdata_auth_3d_db; - ds->load_file(&mdata_auth_3d_db, "rom/auth_3d/", - "mdata_auth_3d_db.bin", auth_3d_database_file::load_file); + for (const char* i : prefixes) { + std::string file = std::string(i) + "auth_3d_db.bin"; - d->auth_3d_db.merge_mdata(base_auth_3d_db, &mdata_auth_3d_db); + auth_3d_database_file auth_3d_db_file; + ds->load_file(&auth_3d_db_file, "rom/auth_3d/", file.c_str(), + auth_3d_database_file::load_file); + d->auth_3d_db.add(&auth_3d_db_file); } { @@ -956,65 +957,43 @@ static void data_load_inner(stream& s) { "bone_data.bin", bone_database::load_file); } - { - motion_database* base_mot_db = &d->base_mot_db; - ds->load_file(base_mot_db, "rom/rob/", - "mot_db.farc", motion_database::load_file); + for (const char* i : prefixes) { + std::string file = std::string(i) + "mot_db.farc"; - motion_database mdata_mot_db; - ds->load_file(&mdata_mot_db, "rom/rob/", - "mdata_mot_db.farc", motion_database::load_file); - - d->mot_db.merge_mdata(base_mot_db, &mdata_mot_db); + motion_database_file mot_db_file; + ds->load_file(&mot_db_file, "rom/rob/", file.c_str(), + motion_database_file::load_file); + d->mot_db.add(&mot_db_file); } - { - object_database* base_obj_db = &d->base_obj_db; - *base_obj_db = object_database(); - base_obj_db->modern = false; - ds->load_file(base_obj_db, "rom/objset/", - "obj_db.bin", object_database::load_file); + for (const char* i : prefixes) { + std::string file = std::string(i) + "obj_db.bin"; - object_database mdata_obj_db; - mdata_obj_db.modern = false; - ds->load_file(&mdata_obj_db, "rom/objset/", - "mdata_obj_db.bin", object_database::load_file); - - object_database* obj_db = &d->obj_db; - *obj_db = object_database(); - obj_db->merge_mdata(base_obj_db, &mdata_obj_db); + object_database_file obj_db_file; + obj_db_file.modern = false; + ds->load_file(&obj_db_file, "rom/objset/", file.c_str(), + object_database_file::load_file); + d->obj_db.add(&obj_db_file); } - { - stage_database* base_stage_data = &d->base_stage_data; - *base_stage_data = stage_database(); - base_stage_data->modern = false; - ds->load_file(base_stage_data, "rom/", - "stage_data.bin", stage_database::load_file); + for (const char* i : prefixes) { + std::string file = std::string(i) + "stage_data.bin"; - stage_database mdata_stage_data; - mdata_stage_data.modern = false; - ds->load_file(&mdata_stage_data, "rom/", - "mdata_stage_data.bin", stage_database::load_file); - - stage_database* stage_data = &d->stage_data; - *stage_data = stage_database(); - stage_data->merge_mdata(base_stage_data, &mdata_stage_data); + stage_database_file stage_data_file; + stage_data_file.modern = false; + ds->load_file(&stage_data_file, "rom/", file.c_str(), + stage_database_file::load_file); + d->stage_data.add(&stage_data_file); } - { - texture_database* base_tex_db = &d->base_tex_db; - *base_tex_db = texture_database(); - base_tex_db->modern = false; - ds->load_file(base_tex_db, "rom/objset/", - "tex_db.bin", texture_database::load_file); + for (const char* i : prefixes) { + std::string file = std::string(i) + "tex_db.bin"; - texture_database mdata_tex_db; - mdata_tex_db.modern = false; - ds->load_file(&mdata_tex_db, "rom/objset/", - "mdata_tex_db.bin", texture_database::load_file); - - d->tex_db.merge_mdata(base_tex_db, &mdata_tex_db); + texture_database_file tex_db_file; + tex_db_file.modern = false; + ds->load_file(&tex_db_file, "rom/objset/", file.c_str(), + texture_database_file::load_file); + d->tex_db.add(&tex_db_file); } } @@ -1111,7 +1090,7 @@ static void data_load_glitter_list(data_struct* ds, const char* path) { case DATA_XHD: ds->glitter_list_murmurhash.reserve(count); for (size_t i = 0; i < count; i++) { - uint32_t hash = hash_string_murmurhash(&ds->glitter_list_names[i]); + uint32_t hash = hash_string_murmurhash(ds->glitter_list_names[i]); ds->glitter_list_murmurhash.push_back(hash); } break; @@ -1120,7 +1099,7 @@ static void data_load_glitter_list(data_struct* ds, const char* path) { case DATA_M39: ds->glitter_list_fnv1a64m.reserve(count); for (size_t i = 0; i < count; i++) { - uint64_t hash = hash_string_fnv1a64m(&ds->glitter_list_names[i]); + uint64_t hash = hash_string_fnv1a64m(ds->glitter_list_names[i]); ds->glitter_list_fnv1a64m.push_back(hash); } break; diff --git a/src/CRE/data.hpp b/src/CRE/data.hpp index 99ba07d1..3df7acc3 100644 --- a/src/CRE/data.hpp +++ b/src/CRE/data.hpp @@ -71,12 +71,6 @@ struct data_ft { stage_database stage_data; texture_database tex_db; - auth_3d_database_file base_auth_3d_db; - motion_database base_mot_db; - object_database base_obj_db; - stage_database base_stage_data; - texture_database base_tex_db; - data_ft(); ~data_ft(); }; diff --git a/src/CRE/draw_object.cpp b/src/CRE/draw_object.cpp index a86cf072..12147474 100644 --- a/src/CRE/draw_object.cpp +++ b/src/CRE/draw_object.cpp @@ -38,11 +38,9 @@ static void draw_object_vertex_attrib_set_reflect_compressed(draw_object* draw); void draw_object_draw(render_context* rctx, draw_object* draw, mat4* model, void(*draw_object_func)(render_context* rctx, draw_object* draw), int32_t show_vector) { if (draw->mats) { - mat4u* mats = draw->mats; - if (draw->mat_count == 2) { - mat4 mat = *mats; - shaders_ft.state_matrix_set_program(7, mat); - } + mat4* mats = draw->mats; + if (draw->mat_count == 2) + shaders_ft.state_matrix_set_program(7, *mats); mat4 mat; for (int32_t i = 0; i < draw->mat_count; i++, mats++) { @@ -74,8 +72,7 @@ void draw_object_draw(render_context* rctx, draw_object* draw, mat4* model, void draw_object_draw_default(render_context* rctx, draw_object* draw) { if (draw->set_blend_color) { - vec4 blend_color = draw->blend_color; - shaders_ft.env_vert_set(3, blend_color); + shaders_ft.env_vert_set(3, draw->blend_color); shaders_ft.env_vert_set(4, vec4_null); } @@ -91,9 +88,9 @@ void draw_object_draw_default(render_context* rctx, draw_object* draw) { draw->sub_mesh->last_index, draw->sub_mesh->index_format, draw->sub_mesh->indices_offset); - else + else { + mat4 mat; for (int32_t i = 0; i < draw->instances_count; i++) { - mat4 mat; mat4_transpose(&draw->instances_mat[i], &mat); glVertexAttrib4fv(12, (const GLfloat*)&mat.row0); glVertexAttrib4fv(13, (const GLfloat*)&mat.row1); @@ -107,6 +104,7 @@ void draw_object_draw_default(render_context* rctx, draw_object* draw) { draw->sub_mesh->index_format, draw->sub_mesh->indices_offset); } + } draw_object_material_reset_default(draw->material); if (!draw->draw_object_func) @@ -154,7 +152,7 @@ void draw_object_draw_sss(render_context* rctx, draw_object* draw) { uniform_value[U37] = 1; } else { - vec4 sss_param = rctx->draw_pass.sss_data.param; + vec4& sss_param = rctx->draw_pass.sss_data.param; shaders_ft.env_frag_set(25, sss_param.x, sss_param.y, sss_param.z, 0.5f); uniform_value[U37] = 0; } @@ -226,8 +224,7 @@ void draw_object_draw_translucent(render_context* rctx, draw_object* draw) { obj_material_data* material = draw->material; std::vector* textures = draw->textures; if (rctx->draw_state.shader_index != -1) { - vec4 emission = draw->emission; - shaders_ft.state_material_set_emission(false, emission); + shaders_ft.state_material_set_emission(false, draw->emission); draw_object_material_set_uniform(rctx, material, 0); if (material->material.attrib.m.alpha_texture) uniform_value[U_TEXTURE_COUNT] = 0; @@ -1038,13 +1035,13 @@ static void draw_object_vertex_attrib_set_default(draw_object* draw) { int32_t texture_id = material->material.texdata[i].tex_index; - mat4 mat = material->material.texdata[i].tex_coord_mat; - shaders_ft.state_matrix_set_texture(texcoord_index, mat); + shaders_ft.state_matrix_set_texture(texcoord_index, + material->material.texdata[i].tex_coord_mat); if (material->material.texdata[i].shader_info.m.tex_type == OBJ_MATERIAL_TEXTURE_COLOR) for (int32_t k = 0; k < draw->texture_transform_count; k++) if (draw->texture_transform_array[k].id == texture_id) { - mat4 mat = draw->texture_transform_array[k].mat; - shaders_ft.state_matrix_set_texture(texcoord_index, mat); + shaders_ft.state_matrix_set_texture(texcoord_index, + draw->texture_transform_array[k].mat); texcoord_mat_set[texcoord_index] = true; break; } @@ -1240,13 +1237,12 @@ inline static void draw_object_vertex_attrib_set_default_compressed(draw_object* int32_t tex_index = material->material.texdata[i].tex_index; - mat4 mat = material->material.texdata[i].tex_coord_mat; - shaders_ft.state_matrix_set_texture(texcoord_index, mat); + shaders_ft.state_matrix_set_texture(texcoord_index, + material->material.texdata[i].tex_coord_mat); if (material->material.texdata[i].shader_info.m.tex_type == OBJ_MATERIAL_TEXTURE_COLOR) for (int32_t k = 0; k < draw->texture_transform_count; k++) if (draw->texture_transform_array[k].id == tex_index) { - mat4 mat = draw->texture_transform_array[k].mat; - shaders_ft.state_matrix_set_texture(texcoord_index, mat); + shaders_ft.state_matrix_set_texture(texcoord_index, draw->texture_transform_array[k].mat); texcoord_mat_set[texcoord_index] = true; break; } @@ -1411,13 +1407,13 @@ static void draw_object_vertex_attrib_set_reflect(draw_object* draw) { int32_t tex_index = material->material.texdata[0].tex_index; - mat4 mat = material->material.texdata[0].tex_coord_mat; - shaders_ft.state_matrix_set_texture(0, mat); + shaders_ft.state_matrix_set_texture(0, + material->material.texdata[0].tex_coord_mat); if (material->material.texdata[0].shader_info.m.tex_type == OBJ_MATERIAL_TEXTURE_COLOR) for (int32_t j = 0; j < draw->texture_transform_count; j++) if (draw->texture_transform_array[j].id == tex_index) { - mat4 mat = draw->texture_transform_array[j].mat; - shaders_ft.state_matrix_set_texture(0, mat); + shaders_ft.state_matrix_set_texture(0, + draw->texture_transform_array[j].mat); break; } } @@ -1584,13 +1580,13 @@ inline static void draw_object_vertex_attrib_set_reflect_compressed(draw_object* int32_t tex_index = material->material.texdata[0].tex_index; - mat4 mat = material->material.texdata[0].tex_coord_mat; - shaders_ft.state_matrix_set_texture(0, mat); + shaders_ft.state_matrix_set_texture(0, + material->material.texdata[0].tex_coord_mat); if (material->material.texdata[0].shader_info.m.tex_type == OBJ_MATERIAL_TEXTURE_COLOR) for (int32_t j = 0; j < draw->texture_transform_count; j++) if (draw->texture_transform_array[j].id == tex_index) { - mat4 mat = draw->texture_transform_array[j].mat; - shaders_ft.state_matrix_set_texture(0, mat); + shaders_ft.state_matrix_set_texture(0, + draw->texture_transform_array[j].mat); break; } } diff --git a/src/CRE/draw_pass.cpp b/src/CRE/draw_pass.cpp index 3eab67ec..87a8126f 100644 --- a/src/CRE/draw_pass.cpp +++ b/src/CRE/draw_pass.cpp @@ -80,6 +80,7 @@ void draw_pass_main(render_context* rctx) { gl_state_set_color_mask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); gl_state_enable_depth_test(); + gl_state_set_depth_func(GL_LEQUAL); gl_state_set_depth_mask(GL_TRUE); for (int32_t i = DRAW_PASS_SHADOW; i < DRAW_PASS_MAX; i++) { rctx->draw_pass.cpu_time[i] = 0.0; @@ -863,7 +864,7 @@ static void draw_pass_3d(render_context* rctx, draw_pass* a1) { gl_state_disable_depth_test(); } - Glitter::glt_particle_manager.Disp(DRAW_PASS_3D_OPAQUE); + Glitter::glt_particle_manager.DispScenes(Glitter::DISP_OPAQUE); if (draw_grid_3d) draw_pass_3d_grid(rctx); @@ -897,7 +898,7 @@ static void draw_pass_3d(render_context* rctx, draw_pass* a1) { gl_state_disable_depth_test(); gl_state_set_color_mask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE); - Glitter::glt_particle_manager.Disp(DRAW_PASS_3D_TRANSPARENT); + Glitter::glt_particle_manager.DispScenes(Glitter::DISP_ALPHA); gl_state_set_color_mask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); if (a1->npr_param == 1) { @@ -930,7 +931,7 @@ static void draw_pass_3d(render_context* rctx, draw_pass* a1) { gl_state_disable_depth_test(); gl_state_set_color_mask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE); - Glitter::glt_particle_manager.Disp(DRAW_PASS_3D_TRANSLUCENT); + Glitter::glt_particle_manager.DispScenes(Glitter::DISP_NORMAL); gl_state_set_color_mask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); gl_state_enable_depth_test(); diff --git a/src/CRE/draw_task.cpp b/src/CRE/draw_task.cpp index 41aa7cd0..7b8f6bf4 100644 --- a/src/CRE/draw_task.cpp +++ b/src/CRE/draw_task.cpp @@ -14,7 +14,7 @@ static void draw_task_add(render_context* rctx, draw_object_type type, draw_task* task); static void draw_task_object_init(draw_task* task, object_data* object_data, mat4* mat, float_t bounding_radius, obj_sub_mesh* sub_mesh, obj_mesh* mesh, obj_material_data* material, - std::vector* textures, int32_t mat_count, mat4u* mats, GLuint array_buffer, + std::vector* textures, int32_t mat_count, mat4* mats, GLuint array_buffer, GLuint element_array_buffer, vec4* blend_color, vec4* emission, int32_t morph_array_buffer, int32_t instances_count, mat4* instances_mat, void(*draw_object_func)(draw_object*)); static void draw_task_object_translucent_init(draw_task* task, mat4* mat, @@ -142,25 +142,21 @@ void draw_task_draw_objects_by_type(render_context* rctx, draw_object_type type, draw_task* task = i; switch (task->type) { case DRAW_TASK_TYPE_OBJECT: { - mat4 mat = task->mat; draw_object_draw(rctx, &task->data.object, - &mat, draw_object_func, show_vector); + &task->mat, draw_object_func, show_vector); } break; case DRAW_TASK_TYPE_PRIMITIVE: { - mat4 mat = task->mat; - draw_object_model_mat_load(rctx, &mat); + draw_object_model_mat_load(rctx, &task->mat); //draw_primitive_draw(&task->data.primitive); } break; case DRAW_TASK_TYPE_PREPROCESS: { - mat4 mat = task->mat; - draw_object_model_mat_load(rctx, &mat); + draw_object_model_mat_load(rctx, &task->mat); task->data.preprocess.func(rctx, task->data.preprocess.data); } break; case DRAW_TASK_TYPE_OBJECT_TRANSLUCENT: { - mat4 mat = task->mat; for (int32_t j = 0; j < task->data.object_translucent.count; j++) draw_object_draw(rctx, task->data.object_translucent.objects[j], - &mat, draw_object_func, show_vector); + &task->mat, draw_object_func, show_vector); } break; } } @@ -172,20 +168,18 @@ void draw_task_draw_objects_by_type(render_context* rctx, draw_object_type type, int32_t a = (int32_t)(task->data.object.blend_color.w * 255.0f); a = clamp(a, 0, 255); if (a == alpha) { - mat4 mat = task->mat; draw_object_draw(rctx, &task->data.object, - &mat, draw_object_func, show_vector); + &task->mat, draw_object_func, show_vector); } } break; case DRAW_TASK_TYPE_OBJECT_TRANSLUCENT: { - mat4 mat = task->mat; for (int32_t j = 0; j < task->data.object_translucent.count; j++) { draw_object* object = task->data.object_translucent.objects[j]; int32_t a = (int32_t)(object->blend_color.w * 255.0f); a = clamp(a, 0, 255); if (a == alpha) draw_object_draw(rctx, object, - &mat, draw_object_func, show_vector); + &task->mat, draw_object_func, show_vector); } } break; } @@ -361,7 +355,7 @@ bool draw_task_add_draw_object(render_context* rctx, obj* object, int32_t bone_indices_count = sub_mesh->bone_indices_count; uint16_t* bone_indices = sub_mesh->bone_indices; - mat4u* mats; + mat4* mats; if (bone_indices_count && enable_bone_mat) { mats = object_data->buffer.add_mat4(bone_indices_count); if (bone_mat) @@ -703,25 +697,25 @@ void draw_task_add_draw_object_by_object_info_object_skin(render_context* rctx, object_data* object_data = &rctx->object_data; if (texture_data && !texture_data->field_0) { vec4 value; - object_data->get_texture_color_coeff(&texture_color_coeff); + object_data->get_texture_color_coeff(texture_color_coeff); vec3_mult(texture_data->texture_color_coeff, *(vec3*)&texture_color_coeff, *(vec3*)&value); value.w = 0.0f; - object_data->set_texture_color_coeff(&value); + object_data->set_texture_color_coeff(value); - object_data->get_texture_color_offset(&texture_color_offset); + object_data->get_texture_color_offset(texture_color_offset); *(vec3*)&value = texture_data->texture_color_offset; value.w = 0.0f; - object_data->set_texture_color_offset(&value); + object_data->set_texture_color_offset(value); - object_data->get_texture_specular_coeff(&texture_specular_coeff); + object_data->get_texture_specular_coeff(texture_specular_coeff); vec3_mult(texture_data->texture_specular_coeff, *(vec3*)&texture_specular_coeff, *(vec3*)&value); value.w = 0.0f; - object_data->set_texture_specular_coeff(&value); + object_data->set_texture_specular_coeff(value); - object_data->get_texture_specular_offset(&texture_specular_offset); + object_data->get_texture_specular_offset(texture_specular_offset); *(vec3*)&value = texture_data->texture_specular_offset; value.w = 0.0f; - object_data->set_texture_specular_offset(&value); + object_data->set_texture_specular_offset(value); } size_t texture_pattern_count = texture_pattern ? texture_pattern->size() : 0; @@ -739,10 +733,10 @@ void draw_task_add_draw_object_by_object_info_object_skin(render_context* rctx, object_data->set_texture_pattern(); if (texture_data && !texture_data->field_0) { - object_data->set_texture_color_coeff(&texture_color_coeff); - object_data->set_texture_color_offset(&texture_color_offset); - object_data->set_texture_specular_coeff(&texture_specular_coeff); - object_data->set_texture_specular_offset(&texture_specular_offset); + object_data->set_texture_color_coeff(texture_color_coeff); + object_data->set_texture_color_offset(texture_color_offset); + object_data->set_texture_specular_coeff(texture_specular_coeff); + object_data->set_texture_specular_offset(texture_specular_offset); } } @@ -754,28 +748,26 @@ void draw_task_sort(render_context* rctx, draw_object_type type, int32_t compare object_data* object_data = &rctx->object_data; for (draw_task*& i : vec) { draw_task* task = i; - mat4 mat = task->mat; vec3 center; - mat4_get_translation(&mat, ¢er); + mat4_get_translation(&task->mat, ¢er); if (task->type == DRAW_TASK_TYPE_OBJECT) { - if (task->data.object.mesh->attrib.m.billboard) { - model_mat_face_camera_view(&rctx->camera->view, &mat, &mat);} + mat4 mat = task->mat; + if (task->data.object.mesh->attrib.m.billboard) + model_mat_face_camera_view(&rctx->camera->view, &mat, &mat); else if (task->data.object.mesh->attrib.m.billboard_y_axis) model_mat_face_camera_position(&rctx->camera->view, &mat, &mat); + + obj_sub_mesh* sub_mesh = task->data.object.sub_mesh; + if (task->data.object.mat_count < 1 || !sub_mesh->bone_indices_count) + mat4_mult_vec3_trans(&mat, &sub_mesh->bounding_sphere.center, ¢er); else { - obj_sub_mesh* sub_mesh = task->data.object.sub_mesh; - if (task->data.object.mat_count < 1 || !sub_mesh->bone_indices_count) - mat4_mult_vec3_trans(&mat, &sub_mesh->bounding_sphere.center, ¢er); - else { - vec3 center_sum = vec3_null; - for (uint32_t j = 0; j < sub_mesh->bone_indices_count; j++) { - center = sub_mesh->bounding_sphere.center; - mat = task->data.object.mats[j]; - mat4_mult_vec3_trans(&mat, ¢er, ¢er); - vec3_add(center_sum, center, center_sum); - } - vec3_mult_scalar(center_sum, 1.0f / (float_t)sub_mesh->bone_indices_count, center); + vec3 center_sum = vec3_null; + for (uint32_t j = 0; j < sub_mesh->bone_indices_count; j++) { + center = sub_mesh->bounding_sphere.center; + mat4_mult_vec3_trans(&task->data.object.mats[j], ¢er, ¢er); + vec3_add(center_sum, center, center_sum); } + vec3_mult_scalar(center_sum, 1.0f / (float_t)sub_mesh->bone_indices_count, center); } task->bounding_radius = task->data.object.mesh->bounding_sphere.radius; } @@ -910,7 +902,7 @@ inline static void draw_task_add(render_context* rctx, draw_object_type type, dr inline static void draw_task_object_init(draw_task* task, object_data* object_data, mat4* mat, float_t bounding_radius, obj_sub_mesh* sub_mesh, obj_mesh* mesh, obj_material_data* material, - std::vector* textures, int32_t mat_count, mat4u* mats, GLuint array_buffer, + std::vector* textures, int32_t mat_count, mat4* mats, GLuint array_buffer, GLuint element_array_buffer, vec4* blend_color, vec4* emission, int32_t morph_array_buffer, int32_t instances_count, mat4* instances_mat, void(*draw_object_func)(draw_object*)) { task->type = DRAW_TASK_TYPE_OBJECT; @@ -942,7 +934,7 @@ inline static void draw_task_object_init(draw_task* task, object_data* object_da } else { draw->set_blend_color = false; - draw->blend_color = vec4u_identity; + draw->blend_color = vec4_identity; } draw->emission = *emission; diff --git a/src/CRE/fbo.cpp b/src/CRE/fbo.cpp index ab43f1ed..e88cd457 100644 --- a/src/CRE/fbo.cpp +++ b/src/CRE/fbo.cpp @@ -10,14 +10,21 @@ fbo::fbo() : flags(), width(), height(), buffer(), count(), textures() { } -fbo::fbo(int32_t width, int32_t height, - GLuint* color_textures, int32_t count, GLuint depth_texture) : flags(), - width(), height(), buffer(), count(), textures() { +fbo::~fbo() { + free_data(); +} + +void fbo::init_data(int32_t width, int32_t height, + GLuint* color_textures, int32_t count, GLuint depth_texture) { if (buffer) { glDeleteFramebuffers(1, &buffer); buffer = 0; } - free(textures); + + if (textures) { + delete[] textures; + textures = 0; + } count = min(count, 8); @@ -30,7 +37,7 @@ fbo::fbo(int32_t width, int32_t height, this->count++; } - textures = force_malloc_s(GLuint, this->count); + textures = new GLuint[this->count]; for (int32_t i = 0; i < count; i++) textures[i] = color_textures[i]; @@ -52,14 +59,14 @@ fbo::fbo(int32_t width, int32_t height, glCheckFramebufferStatus(GL_FRAMEBUFFER); } -fbo::~fbo() { +void fbo::free_data() { if (buffer) { glDeleteFramebuffers(1, &buffer); buffer = 0; } if (textures) { - free(textures); + delete[] textures; textures = 0; } } diff --git a/src/CRE/fbo.hpp b/src/CRE/fbo.hpp index e5a420ae..d7de43d7 100644 --- a/src/CRE/fbo.hpp +++ b/src/CRE/fbo.hpp @@ -20,10 +20,12 @@ struct fbo { GLuint* textures; fbo(); - fbo(int32_t width, int32_t height, - GLuint* color_textures, int32_t count, GLuint depth_texture); ~fbo(); + void init_data(int32_t width, int32_t height, + GLuint* color_textures, int32_t count, GLuint depth_texture); + void free_data(); + static void blit(GLuint src_fbo, GLuint dst_fbo, GLint src_x0, GLint src_y0, GLint src_x1, GLint src_y1, GLint dst_x0, GLint dst_y0, GLint dst_x1, GLint dst_y1, GLbitfield mask, GLenum filter); diff --git a/src/CRE/frame_rate_control.cpp b/src/CRE/frame_rate_control.cpp index ed80aa9b..852473a2 100644 --- a/src/CRE/frame_rate_control.cpp +++ b/src/CRE/frame_rate_control.cpp @@ -7,8 +7,6 @@ #include "static_var.hpp" SysFrameRate sys_frame_rate; -DivaPvFrameRate diva_pv_frame_rate; -DivaStageFrameRate diva_stage_frame_rate; FrameRateControl::FrameRateControl() { frame_speed = 1.0f; @@ -33,27 +31,3 @@ SysFrameRate::~SysFrameRate() { float_t SysFrameRate::GetDeltaFrame() { return get_delta_frame() * get_anim_frame_speed() * frame_speed; } - -DivaPvFrameRate::DivaPvFrameRate() { - frame_speed = 1.0f; -} - -DivaPvFrameRate::~DivaPvFrameRate() { - -} - -float_t DivaPvFrameRate::GetDeltaFrame() { - return get_delta_frame() * get_anim_frame_speed() * frame_speed; -} - -DivaStageFrameRate::DivaStageFrameRate() { - frame_speed = 1.0f; -} - -DivaStageFrameRate::~DivaStageFrameRate() { - -} - -float_t DivaStageFrameRate::GetDeltaFrame() { - return get_delta_frame() * get_anim_frame_speed() * frame_speed; -} diff --git a/src/CRE/frame_rate_control.hpp b/src/CRE/frame_rate_control.hpp index 12f6192d..57e7a8b0 100644 --- a/src/CRE/frame_rate_control.hpp +++ b/src/CRE/frame_rate_control.hpp @@ -13,6 +13,7 @@ public: FrameRateControl(); virtual ~FrameRateControl(); + virtual float_t GetDeltaFrame() = 0; virtual void SetFrameSpeed(float_t frame_speed); }; @@ -21,23 +22,8 @@ class SysFrameRate : public FrameRateControl { public: SysFrameRate(); virtual ~SysFrameRate() override; - virtual float_t GetDeltaFrame() override; -}; -class DivaPvFrameRate : public FrameRateControl { -public: - DivaPvFrameRate(); - virtual ~DivaPvFrameRate() override; - virtual float_t GetDeltaFrame() override; -}; - -class DivaStageFrameRate : public FrameRateControl { -public: - DivaStageFrameRate(); - virtual ~DivaStageFrameRate() override; virtual float_t GetDeltaFrame() override; }; extern SysFrameRate sys_frame_rate; -extern DivaPvFrameRate diva_pv_frame_rate; -extern DivaStageFrameRate diva_stage_frame_rate; diff --git a/src/CRE/light_param/light.hpp b/src/CRE/light_param/light.hpp index 5c74cf20..c9c8d429 100644 --- a/src/CRE/light_param/light.hpp +++ b/src/CRE/light_param/light.hpp @@ -13,19 +13,19 @@ struct light_data { light_type type; - vec4u ambient; - vec4u diffuse; - vec4u specular; - vec4u position; + vec4 ambient; + vec4 diffuse; + vec4 specular; + vec4 position; vec3 spot_direction; float_t spot_exponent; float_t spot_cutoff; float_t constant; float_t linear; float_t quadratic; - vec4u ibl_specular; - vec4u ibl_back; - vec4u ibl_direction; + vec4 ibl_specular; + vec4 ibl_back; + vec4 ibl_direction; vec3 tone_curve; bool clip_plane[4]; @@ -82,10 +82,10 @@ struct light_data { struct light_set { light_data lights[LIGHT_MAX]; - vec4u ambient_intensity; - mat4u irradiance_r; - mat4u irradiance_g; - mat4u irradiance_b; + vec4 ambient_intensity; + mat4 irradiance_r; + mat4 irradiance_g; + mat4 irradiance_b; light_set(); diff --git a/src/CRE/object.cpp b/src/CRE/object.cpp index ccd77392..8cd33fdc 100644 --- a/src/CRE/object.cpp +++ b/src/CRE/object.cpp @@ -142,7 +142,7 @@ bool obj_mesh_vertex_buffer::load(obj_mesh& mesh) { return false; { - const vec4u attib_default = { 0.0f, 0.0f, 0.0f, 1.0f }; + const vec4 attib_default = { 0.0f, 0.0f, 0.0f, 1.0f }; obj_vertex_format vertex_format = mesh.vertex_format; obj_vertex_data* vertex_file = mesh.vertex; @@ -168,20 +168,20 @@ bool obj_mesh_vertex_buffer::load(obj_mesh& mesh) { enum_or(_vertex_format, OBJ_VERTEX_TEXCOORD3); if (~_vertex_format & OBJ_VERTEX_COLOR0 && vertex_format & OBJ_VERTEX_COLOR0 - && memcmp(&vertex_file[i].normal, &vec4u_identity, sizeof(vec4u))) + && memcmp(&vertex_file[i].normal, &vec4_identity, sizeof(vec4))) enum_or(_vertex_format, OBJ_VERTEX_COLOR0); if (~_vertex_format & OBJ_VERTEX_COLOR1 && vertex_format & OBJ_VERTEX_COLOR1 - && memcmp(&vertex_file[i].normal, &vec4u_identity, sizeof(vec4u))) + && memcmp(&vertex_file[i].normal, &vec4_identity, sizeof(vec4))) enum_or(_vertex_format, OBJ_VERTEX_COLOR1); if (~_vertex_format & OBJ_VERTEX_BONE_DATA && vertex_format & OBJ_VERTEX_BONE_DATA - && memcmp(&vertex_file[i].bone_index, &vec4iu_null, sizeof(vec4iu)) - && memcmp(&vertex_file[i].bone_weight, &vec4u_null, sizeof(vec4u))) + && memcmp(&vertex_file[i].bone_index, &vec4i_null, sizeof(vec4i)) + && memcmp(&vertex_file[i].bone_weight, &vec4_null, sizeof(vec4))) enum_or(_vertex_format, OBJ_VERTEX_BONE_DATA); if (~_vertex_format & OBJ_VERTEX_UNKNOWN && vertex_format & OBJ_VERTEX_UNKNOWN - && memcmp(&vertex_file[i].unknown, &attib_default, sizeof(vec4u))) + && memcmp(&vertex_file[i].unknown, &attib_default, sizeof(vec4))) enum_or(_vertex_format, OBJ_VERTEX_UNKNOWN); } @@ -214,7 +214,7 @@ bool obj_mesh_vertex_buffer::load(obj_mesh& mesh) { } if (vertex_format & OBJ_VERTEX_TANGENT) { - *(vec4u*)d = vertex_file[i].tangent; + *(vec4*)d = vertex_file[i].tangent; d += 16; } @@ -244,24 +244,24 @@ bool obj_mesh_vertex_buffer::load(obj_mesh& mesh) { } if (vertex_format & OBJ_VERTEX_COLOR0) { - *(vec4u*)d = vertex_file[i].color0; + *(vec4*)d = vertex_file[i].color0; d += 16; } if (vertex_format & OBJ_VERTEX_COLOR1) { - *(vec4u*)d = vertex_file[i].color1; + *(vec4*)d = vertex_file[i].color1; d += 16; } if (vertex_format & OBJ_VERTEX_BONE_DATA) { - *(vec4u*)d = vertex_file[i].bone_weight; + *(vec4*)d = vertex_file[i].bone_weight; d += 16; - *(vec4iu*)d = vertex_file[i].bone_index; + *(vec4i*)d = vertex_file[i].bone_index; d += 16; } if (vertex_format & OBJ_VERTEX_UNKNOWN) { - *(vec4u*)d = vertex_file[i].unknown; + *(vec4*)d = vertex_file[i].unknown; d += 16; } } @@ -488,10 +488,7 @@ void obj_skin_set_matrix_buffer(obj_skin* s, mat4* matrices, mat4_mult(mat, &matrices[bone_id], &temp); mat4_mult(&temp, global_mat, &temp); - - mat4 inv_bind_pose_mat = s->bones[i].inv_bind_pose_mat; - mat4_mult(&inv_bind_pose_mat, &temp, &temp); - matrix_buffer[i] = temp; + mat4_mult(&s->bones[i].inv_bind_pose_mat, &temp, &matrix_buffer[i]); } else for (uint32_t i = 0; i < s->bones_count; i++) { @@ -503,10 +500,7 @@ void obj_skin_set_matrix_buffer(obj_skin* s, mat4* matrices, temp = matrices[bone_id]; mat4_mult(&temp, global_mat, &temp); - - mat4 inv_bind_pose_mat = s->bones[i].inv_bind_pose_mat; - mat4_mult(&inv_bind_pose_mat, &temp, &temp); - matrix_buffer[i] = temp; + mat4_mult(&s->bones[i].inv_bind_pose_mat, &temp, &matrix_buffer[i]); } } @@ -1122,25 +1116,25 @@ bool object_storage_load_obj_set_check_not_read(uint32_t set_id, if (!txi) return false; - object_database local_obj_db; + object_database_file local_obj_db; local_obj_db.read(osi->data, osi->size, true); - texture_database local_tex_db; + texture_database_file local_tex_db; local_tex_db.read(txi->data, txi->size, true); std::string name; if (local_obj_db.ready) - for (object_set_info& m : local_obj_db.object_set) + for (object_set_info_file& m : local_obj_db.object_set) if (m.id == handler->set_id) { name = m.name; break; } if (obj_db) - obj_db->merge_mdata(obj_db, &local_obj_db); + obj_db->add(&local_obj_db); if (tex_db) - tex_db->merge_mdata(tex_db, &local_tex_db); + tex_db->add(&local_tex_db); if (!name.size()) return false; diff --git a/src/CRE/object.hpp b/src/CRE/object.hpp index 925a5cf4..a06f9e8b 100644 --- a/src/CRE/object.hpp +++ b/src/CRE/object.hpp @@ -17,9 +17,9 @@ #include "texture.hpp" struct material_change { - vec4u blend_color; + vec4 blend_color; float_t glow_intensity; - vec4u incandescence; + vec4 incandescence; }; struct obj_mesh_index_buffer { diff --git a/src/CRE/post_process/dof.cpp b/src/CRE/post_process/dof.cpp index c116678a..fae07c29 100644 --- a/src/CRE/post_process/dof.cpp +++ b/src/CRE/post_process/dof.cpp @@ -705,7 +705,7 @@ void post_process_dof::apply(render_texture* rt, GLuint* samplers, camera* cam) } void post_process_dof::init_fbo(int32_t width, int32_t height) { - if (!this || (width == width && height == height)) + if (!this || (this->width == width && this->height == height)) return; if (textures[0]) { @@ -732,20 +732,20 @@ void post_process_dof::init_fbo(int32_t width, int32_t height) { glGenTextures(6, textures); gl_state_bind_texture_2d(textures[0]); glTexStorage2D(GL_TEXTURE_2D, 1, GL_RG16F, w20, h20); - fbo[0] = ::fbo(w20, h20, &textures[0], 1, 0); + fbo[0].init_data(w20, h20, &textures[0], 1, 0); gl_state_bind_texture_2d(textures[1]); glTexStorage2D(GL_TEXTURE_2D, 1, GL_RG16F, w20, h20); - fbo[1] = ::fbo(w20, h20, &textures[1], 1, 0); + fbo[1].init_data(w20, h20, &textures[1], 1, 0); gl_state_bind_texture_2d(textures[2]); glTexStorage2D(GL_TEXTURE_2D, 1, GL_R11F_G11F_B10F, w2, h2); gl_state_bind_texture_2d(textures[3]); glTexStorage2D(GL_TEXTURE_2D, 1, GL_R11F_G11F_B10F, w2, h2); - fbo[2] = ::fbo(w2, h2, &textures[2], 2, 0); + fbo[2].init_data(w2, h2, &textures[2], 2, 0); gl_state_bind_texture_2d(textures[4]); glTexStorage2D(GL_TEXTURE_2D, 1, GL_R11F_G11F_B10F, w2, h2); gl_state_bind_texture_2d(textures[5]); glTexStorage2D(GL_TEXTURE_2D, 1, GL_R8, w2, h2); - fbo[3] = ::fbo(w2, h2, &textures[4], 2, 0); + fbo[3].init_data(w2, h2, &textures[4], 2, 0); glGenBuffers(2, ubo); gl_state_bind_uniform_buffer(ubo[0]); diff --git a/src/CRE/post_process/exposure.cpp b/src/CRE/post_process/exposure.cpp index b379aae8..d32cfc48 100644 --- a/src/CRE/post_process/exposure.cpp +++ b/src/CRE/post_process/exposure.cpp @@ -37,8 +37,10 @@ void post_process_exposure::get_exposure(camera* cam, int32_t render_width, int32_t render_height, bool reset_exposure, GLuint in_tex_0, GLuint in_tex_1) { bool v2 = false; if (!reset_exposure) { - for (int32_t i = 0; i < ROB_CHARA_COUNT; i++) - memset(&chara_data[i], 0, sizeof(post_process_exposure_chara_data)); + for (int32_t i = 0; i < ROB_CHARA_COUNT; i++) { + memset(&chara_data[i].field_0, 0, sizeof(chara_data[i].field_0)); + chara_data[i].field_80 = 0.0f; + } post_process_exposure_chara_data* v6 = chara_data; float_t v18 = (float_t)render_height / (float_t)render_width; diff --git a/src/CRE/pv_expression.cpp b/src/CRE/pv_expression.cpp new file mode 100644 index 00000000..b1afb418 --- /dev/null +++ b/src/CRE/pv_expression.cpp @@ -0,0 +1,428 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#include +#include +#include "pv_expression.hpp" +#include "../KKdLib/pv_exp.hpp" +#include "rob/rob.hpp" +#include "file_handler.hpp" +#include "render_context.hpp" + +struct pv_expression { + rob_chara* rob_chr; + int32_t motion_id; + pv_exp_data* face_data; + pv_exp_data* face_data_curr; + pv_exp_data* face_data_prev; + pv_exp_data* face_cl_data; + pv_exp_data* face_cl_data_curr; + pv_exp_data* face_cl_data_prev; + float_t frame_speed; + bool face_data_update; + bool face_cl_data_update; + + pv_expression(); + ~pv_expression(); + + bool ctrl(); + void face_cl_set_data(float_t frame); + void face_cl_set_frame(float_t frame); + void face_set_data(float_t frame); + void face_set_frame(float_t frame); + void reset(); + void reset_data(); + bool set_motion(int32_t motion_id); +}; + +struct pv_expression_file_handler { + p_file_handler file_handler; + pv_exp* data; + int32_t load_count; + + pv_expression_file_handler(); + ~pv_expression_file_handler(); + + static void load_file(pv_expression_file_handler* handler, const void* data, size_t size); +}; + +pv_expression_file_handler pv_expression_file_handler_data; +pv_expression pv_expression_array[6]; + +extern render_context* rctx_ptr; + +void pv_expression_array_ctrl(void* rob_chr) { + for (pv_expression& i : pv_expression_array) + if (i.rob_chr == rob_chr) { + i.ctrl(); + break; + } +} + +void pv_expression_array_reset() { + for (pv_expression& i : pv_expression_array) + i.reset(); +} + +bool pv_expression_array_reset_data(size_t chara_id, void* rob_chr, float_t frame_speed) { + if (chara_id < 0 || chara_id >= ROB_CHARA_COUNT) + return false; + + pv_expression& exp = pv_expression_array[chara_id]; + exp.rob_chr = (rob_chara*)rob_chr; + exp.frame_speed = frame_speed; + exp.reset_data(); + return true; +} + +void pv_expression_array_reset_motion(size_t chara_id) { + if (chara_id < 0 || chara_id >= ROB_CHARA_COUNT) + return; + + pv_expression& exp = pv_expression_array[chara_id]; + if (exp.rob_chr) + exp.rob_chr->autoblink_enable(); + exp.reset(); +} + +bool pv_expression_array_set_motion(size_t chara_id, int32_t motion_id) { + if (chara_id >= 0 && chara_id < ROB_CHARA_COUNT) + return pv_expression_array[chara_id].set_motion(motion_id); + return false; +} + +bool pv_expression_file_check_not_ready() { + return pv_expression_file_handler_data.file_handler.check_not_ready(); +} + +void pv_expression_file_load(void* data, const char* path, const char* file) { + if (pv_expression_file_handler_data.load_count > 0) + pv_expression_file_handler_data.load_count++; + else if (pv_expression_file_handler_data.file_handler.read_file(data, path, file)) { + if (pv_expression_file_handler_data.data) + delete pv_expression_file_handler_data.data; + + pv_expression_file_handler_data.data = new pv_exp; + pv_expression_file_handler_data.data->modern = false; + + pv_expression_file_handler_data.file_handler.set_callback_data(0, + (void(*)(void*, const void*, size_t))pv_expression_file_handler::load_file, + &pv_expression_file_handler_data); + pv_expression_file_handler_data.load_count = 1; + } + else + pv_expression_file_handler_data.load_count = 0; +} + +void pv_expression_file_load(void* data, const char* path, uint32_t hash) { + if (pv_expression_file_handler_data.load_count > 0) + pv_expression_file_handler_data.load_count++; + else if (pv_expression_file_handler_data.file_handler.read_file(data, path, hash, ".dex")) { + if (pv_expression_file_handler_data.data) + delete pv_expression_file_handler_data.data; + + pv_expression_file_handler_data.data = new pv_exp; + pv_expression_file_handler_data.data->modern = true; + + pv_expression_file_handler_data.file_handler.set_callback_data(0, + (void(*)(void*, const void*, size_t))pv_expression_file_handler::load_file, + &pv_expression_file_handler_data); + pv_expression_file_handler_data.load_count = 1; + } + else + pv_expression_file_handler_data.load_count = 0; +} + +void pv_expression_file_unload() { + if (--pv_expression_file_handler_data.load_count < 0) + pv_expression_file_handler_data.load_count = 0; + else if (!pv_expression_file_handler_data.load_count) { + if (pv_expression_file_handler_data.data) { + delete pv_expression_file_handler_data.data; + pv_expression_file_handler_data.data = 0; + } + + pv_expression_file_handler_data.file_handler.free_data(); + } +} + +pv_expression::pv_expression() : rob_chr(), face_data(), face_data_curr(), face_data_prev(), +face_cl_data(), face_cl_data_curr(), face_cl_data_prev(), face_data_update(), face_cl_data_update() { + motion_id = -1; + frame_speed = 1.0f; +} + +pv_expression::~pv_expression() { + +} + +bool pv_expression::ctrl() { + if (!rob_chr || rob_chr->data.motion.motion_id != motion_id) + return false; + + float_t frame = rob_chr->get_frame(); + if (face_data_curr) { + face_set_frame(frame); + face_set_data(frame); + } + + if (face_cl_data_curr) { + face_cl_set_frame(frame); + face_cl_set_data(frame); + } + return true; +} + +void pv_expression::face_cl_set_data(float_t frame) { + pv_exp_data* v2 = face_cl_data_curr; + pv_exp_data* v3 = face_cl_data_prev; + + int32_t id = 4; + float_t duration = 0.0f; + float_t value = 0.0f; + float_t offset = 0.0f; + + if (face_cl_data_update) { + face_cl_data_update = false; + + if (v2->type == 1) { + value = v2->value; + id = v2->id; + } + + if (v2->type == 1 && frame - v2->frame >= v2->trans) + v3 = v2++; + else if (v3->type == 1) { + id = v3->id; + duration = 0.0f; + value = v3->value; + offset = 0.0f; + } + } + else { + float_t v9 = 1.0f; + if (v3->trans + v3->frame + 1.0f < v2->frame || v2->trans <= 0.0f) + v9 = 0.0f; + + if (v2->frame + v9 > frame || v2->type != 1) { + face_cl_data_curr = v2; + face_cl_data_prev = v3; + return; + } + + value = v2->value; + id = v2->id; + + float_t v10 = frame - v2->frame; + float_t v11 = v2->trans - v10; + if (v11 < 0.0f) { + v11 = 0.0f; + v10 = 0.0f; + } + + duration = (1.0f / frame_speed) * v11; + if (duration > 0.0f) + offset = (1.0f / frame_speed) * v10; + v3 = v2++; + } + + if (id != 4 && rob_chr) + rob_chr->set_eyelid_mottbl_motion_from_face(id, duration, value, offset, &rctx_ptr->data->data_ft.mot_db); + + face_cl_data_curr = v2; + face_cl_data_prev = v3; +} + +void pv_expression::face_cl_set_frame(float_t frame) { + pv_exp_data* v2 = face_cl_data_prev; + pv_exp_data* v3 = face_cl_data_curr; + + if (frame < v2->frame) { + v2 = face_cl_data; + v3 = face_cl_data; + } + + bool update = false; + if (frame > v3->frame && v3->type != -1) { + pv_exp_data* v5 = v3 + 1; + while (v5->type != -1 && frame > v5->frame) { + v2 = v3; + v3 = v5++; + update = true; + } + } + + face_cl_data_curr = v3; + face_cl_data_prev = v2; + face_cl_data_update = update; +} + +void pv_expression::face_set_data(float_t frame) { + pv_exp_data* v2 = face_data_curr; + pv_exp_data* v3 = face_data_prev; + + int32_t expression_id = 78; + float_t value = 0.0f; + float_t duration = 0.0f; + float_t offset = 0.0f; + + if (face_data_update) { + face_data_update = false; + if (!v2->type) { + expression_id = v2->id; + value = v2->value; + } + + if (!v2->type && frame - v2->frame >= v2->trans || v3->type) + v3 = v2++; + else { + expression_id = v3->id; + value = v3->value; + duration = 0.0f; + offset = 0.0f; + } + } + else { + float_t v10 = 1.0f; + if (v3->trans + v3->frame + 1.0f < v2->frame || v2->trans <= 0.0f) + v10 = 0.0f; + + if (v2->frame + v10 > frame || v2->type) { + face_data_prev = v3; + face_data_curr = v2; + return; + } + + expression_id = v2->id; + value = v2->value; + + float_t v11 = frame - v2->frame; + float_t v12 = v2->trans - v11; + if (v12 < 0.0f) { + v12 = 0.0f; + v11 = 0.0f; + } + + duration = (1.0f / frame_speed) * v12; + if (duration > 0.0f) + offset = (1.0f / frame_speed) * v11; + v3 = v2++; + } + + if (expression_id != 78 && rob_chr) { + int32_t mottbl_index = expression_id_to_mottbl_index(expression_id); + rob_chr->set_face_mottbl_motion(0, mottbl_index, value, mottbl_index >= 214 && mottbl_index <= 223 ? 1 : 0, + duration, 0.0f, 1.0f, -1, offset, false, &rctx_ptr->data->data_ft.mot_db); + } + + face_data_prev = v3; + face_data_curr = v2; +} + +void pv_expression::face_set_frame(float_t frame) { + pv_exp_data* v2 = face_data_prev; + pv_exp_data* v3 = face_data_curr; + + if (frame < v2->frame) { + v2 = face_data; + v3 = face_data; + } + + bool update = false; + if (frame > v3->frame && v3->type != -1) { + pv_exp_data* v5 = v3 + 1; + while (v5->type != -1 && frame > v5->frame) { + v2 = v3; + v3 = v5++; + update = true; + } + } + + face_data_curr = v3; + face_data_prev = v2; + face_data_update = update; +} + +void pv_expression::reset() { + rob_chr = 0; + motion_id = -1; + face_data = 0; + face_data_curr = 0; + face_data_prev = 0; + face_cl_data = 0; + face_cl_data_curr = 0; + face_cl_data_prev = 0; + frame_speed = 1.0f; + face_data_update = false; + face_cl_data_update = false; +} + +void pv_expression::reset_data() { + motion_id = -1; + face_data = 0; + face_data_curr = 0; + face_data_prev = 0; + face_cl_data = 0; + face_cl_data_curr = 0; + face_cl_data_prev = 0; + face_data_update = false; + face_cl_data_update = false; +} + +bool pv_expression::set_motion(int32_t motion_id) { + if (!pv_expression_file_handler_data.data) + return false; + + pv_exp* exp = pv_expression_file_handler_data.data; + if (!exp->motion_data.size()) { + reset_data(); + return false; + } + + const char* motion_name = rctx_ptr->data->data_ft.mot_db.get_motion_name(motion_id); + + size_t motion_index = -1; + for (pv_exp_mot& i : exp->motion_data) + if (!i.name.compare(motion_name)) { + motion_index = (&i - exp->motion_data.data()); + break; + } + + if (motion_index == -1) { + reset_data(); + return false; + } + + this->motion_id = motion_id; + + pv_exp_data* face_data = exp->motion_data[motion_index].face_data; + if (this->face_data != face_data) { + this->face_data = face_data; + this->face_data_prev = face_data; + this->face_data_curr = face_data; + } + + pv_exp_data* face_cl_data = exp->motion_data[motion_index].face_cl_data; + if (this->face_cl_data != face_cl_data) { + this->face_cl_data = face_cl_data; + this->face_cl_data_prev = face_cl_data; + this->face_cl_data_curr = face_cl_data; + if (rob_chr) + rob_chr->autoblink_disable(); + } + return true; +} + +pv_expression_file_handler::pv_expression_file_handler() : data(), load_count() { + +} + +pv_expression_file_handler::~pv_expression_file_handler() { + +} + +void pv_expression_file_handler::load_file(pv_expression_file_handler* handler, const void* data, size_t size) { + handler->data->read(data, size, handler->data->modern); +} diff --git a/src/CRE/pv_expression.hpp b/src/CRE/pv_expression.hpp new file mode 100644 index 00000000..069bea3d --- /dev/null +++ b/src/CRE/pv_expression.hpp @@ -0,0 +1,19 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#pragma once + +#include "../KKdLib/default.hpp" + +extern void pv_expression_array_ctrl(void* rob_chr); +extern void pv_expression_array_reset(); +extern bool pv_expression_array_reset_data(size_t chara_id, void* rob_chr, float_t frame_speed); +extern void pv_expression_array_reset_motion(size_t chara_id); +extern bool pv_expression_array_set_motion(size_t chara_id, int32_t motion_id); + +extern bool pv_expression_file_check_not_ready(); +extern void pv_expression_file_load(void* data, const char* path, const char* file); +extern void pv_expression_file_load(void* data, const char* path, uint32_t hash); +extern void pv_expression_file_unload(); diff --git a/src/CRE/render_context.cpp b/src/CRE/render_context.cpp index fc9b6ced..17c12aa9 100644 --- a/src/CRE/render_context.cpp +++ b/src/CRE/render_context.cpp @@ -65,8 +65,8 @@ has_blend_color(), emission(), has_emission() { hash = (uint32_t)-1; } -material_list_struct::material_list_struct(uint32_t hash, vec4u& blend_color, - vec4u8& has_blend_color, vec4u& emission, vec4u8& has_emission) : hash(hash), blend_color(blend_color), +material_list_struct::material_list_struct(uint32_t hash, vec4& blend_color, + vec4u8& has_blend_color, vec4& emission, vec4u8& has_emission) : hash(hash), blend_color(blend_color), has_blend_color(has_blend_color), emission(emission), has_emission(has_emission) { } @@ -81,10 +81,10 @@ texture_pattern_struct::texture_pattern_struct(texture_id src, texture_id dst) : texture_transform_struct::texture_transform_struct() { id = (uint32_t)-1; - mat = mat4u_identity; + mat = mat4_identity; } -texture_transform_struct::texture_transform_struct(uint32_t id, mat4u& mat) : id(id), mat(mat) { +texture_transform_struct::texture_transform_struct(uint32_t id, mat4& mat) : id(id), mat(mat) { } @@ -212,7 +212,7 @@ draw_task* object_data_buffer::add_draw_task(draw_task_type type) { if (!data) return 0; - int32_t size = align_val(sizeof(draw_task_type) + sizeof(mat4u) + sizeof(float_t) * 2, 0x08); + int32_t size = align_val(sizeof(draw_task_type) + sizeof(mat4) + sizeof(float_t) * 2, 0x08); switch (type) { case DRAW_TASK_TYPE_OBJECT: size += sizeof(draw_object); @@ -240,15 +240,15 @@ draw_task* object_data_buffer::add_draw_task(draw_task_type type) { return task; } -mat4u* object_data_buffer::add_mat4(int32_t count) { +mat4* object_data_buffer::add_mat4(int32_t count) { if (!data) return 0; - int32_t size = sizeof(mat4u) * count; + int32_t size = sizeof(mat4) * count; if (offset + size > this->size) return 0; - mat4u* mats = (mat4u*)((size_t)data + offset); + mat4* mats = (mat4*)((size_t)data + offset); offset += size; if (max_offset < offset) max_offset = offset; @@ -285,10 +285,10 @@ bool object_data::get_chara_color() { return draw_task_flags; } -void object_data::get_material_list(int32_t* count, material_list_struct* value) { - *count = material_list_count; +void object_data::get_material_list(int32_t& count, material_list_struct*& value) { + count = material_list_count; - for (int32_t i = 0; i < *count; i++) + for (int32_t i = 0; i < count; i++) value[i] = material_list_array[i]; } @@ -301,33 +301,33 @@ shadow_type_enum object_data::get_shadow_type() { return shadow_type; } -void object_data::get_texture_color_coeff(vec4* value) { - *value = texture_color_coeff; +void object_data::get_texture_color_coeff(vec4& value) { + value = texture_color_coeff; } -void object_data::get_texture_color_offset(vec4* value) { - *value = texture_color_offset; +void object_data::get_texture_color_offset(vec4& value) { + value = texture_color_offset; } -void object_data::get_texture_pattern(int32_t* count, texture_pattern_struct* value) { - *count = texture_pattern_count; +void object_data::get_texture_pattern(int32_t& count, texture_pattern_struct*& value) { + count = texture_pattern_count; - for (int32_t i = 0; i < *count; i++) + for (int32_t i = 0; i < count; i++) value[i] = texture_pattern_array[i]; } -void object_data::get_texture_specular_coeff(vec4* value) { - *value = texture_specular_coeff; +void object_data::get_texture_specular_coeff(vec4& value) { + value = texture_specular_coeff; } -void object_data::get_texture_specular_offset(vec4* value) { - *value = texture_specular_offset; +void object_data::get_texture_specular_offset(vec4& value) { + value = texture_specular_offset; } -void object_data::get_texture_transform(int32_t* count, texture_transform_struct* value) { - *count = texture_transform_count; +void object_data::get_texture_transform(int32_t& count, texture_transform_struct*& value) { + count = texture_transform_count; - for (int32_t i = 0; i < *count; i++) + for (int32_t i = 0; i < count; i++) value[i] = texture_transform_array[i]; } @@ -395,12 +395,12 @@ void object_data::set_shadow_type(shadow_type_enum type) { shadow_type = type; } -void object_data::set_texture_color_coeff(vec4* value) { - texture_color_coeff = *value; +void object_data::set_texture_color_coeff(vec4& value) { + texture_color_coeff = value; } -void object_data::set_texture_color_offset(vec4* value) { - texture_color_offset = *value; +void object_data::set_texture_color_offset(vec4& value) { + texture_color_offset = value; } void object_data::set_texture_pattern(int32_t count, texture_pattern_struct* value) { @@ -417,12 +417,12 @@ void object_data::set_texture_pattern(int32_t count, texture_pattern_struct* val texture_pattern_array[i] = {}; } -void object_data::set_texture_specular_coeff(vec4* value) { - texture_specular_coeff = *value; +void object_data::set_texture_specular_coeff(vec4& value) { + texture_specular_coeff = value; } -void object_data::set_texture_specular_offset(vec4* value) { - texture_specular_offset = *value; +void object_data::set_texture_specular_offset(vec4& value) { + texture_specular_offset = value; } void object_data::set_texture_transform(int32_t count, texture_transform_struct* value) { @@ -496,8 +496,6 @@ void render_context::ctrl() { rob_chara_array[i].item_equip->shadow_type = SHADOW_CHARA; }*/ - Glitter::glt_particle_manager.rctx = this; - rctx_ptr = this; app::TaskWork::Ctrl(); diff --git a/src/CRE/render_context.hpp b/src/CRE/render_context.hpp index bf7bef70..7afb9649 100644 --- a/src/CRE/render_context.hpp +++ b/src/CRE/render_context.hpp @@ -159,7 +159,7 @@ struct sss_data { bool enable; bool npr_contour; render_texture textures[4]; - vec4u param; + vec4 param; sss_data(); ~sss_data(); @@ -227,14 +227,14 @@ struct draw_state { struct material_list_struct { uint32_t hash; - vec4u blend_color; + vec4 blend_color; vec4u8 has_blend_color; - vec4u emission; + vec4 emission; vec4u8 has_emission; material_list_struct(); - material_list_struct(uint32_t hash, vec4u& blend_color, - vec4u8& has_blend_color, vec4u& emission, vec4u8& has_emission); + material_list_struct(uint32_t hash, vec4& blend_color, + vec4u8& has_blend_color, vec4& emission, vec4u8& has_emission); }; struct texture_pattern_struct { @@ -247,10 +247,10 @@ struct texture_pattern_struct { struct texture_transform_struct { uint32_t id; - mat4u mat; + mat4 mat; texture_transform_struct(); - texture_transform_struct(uint32_t id, mat4u& mat); + texture_transform_struct(uint32_t id, mat4& mat); }; struct draw_object; @@ -261,23 +261,23 @@ struct draw_object { obj_material_data* material; std::vector* textures; int32_t mat_count; - mat4u* mats; + mat4* mats; GLuint array_buffer; GLuint element_array_buffer; bool set_blend_color; bool chara_color; - vec4u blend_color; - vec4u emission; + vec4 blend_color; + vec4 emission; bool self_shadow; shadow_type_enum shadow; GLuint morph_array_buffer; float_t morph_value; int32_t texture_pattern_count; texture_pattern_struct texture_pattern_array[TEXTURE_PATTERN_COUNT]; - vec4u texture_color_coeff; - vec4u texture_color_offset; - vec4u texture_specular_coeff; - vec4u texture_specular_offset; + vec4 texture_color_coeff; + vec4 texture_color_offset; + vec4 texture_specular_coeff; + vec4 texture_specular_offset; int32_t texture_transform_count; texture_transform_struct texture_transform_array[TEXTURE_TRANSFORM_COUNT]; int32_t instances_count; @@ -356,7 +356,7 @@ union draw_primitive_union { struct draw_primitive { draw_primitive_type type; bool fog; - vec4u color; + vec4 color; draw_primitive_union data; }; @@ -379,7 +379,7 @@ union draw_task_union { struct draw_task { draw_task_type type; - mat4u mat; + mat4 mat; float_t depth; float_t bounding_radius; draw_task_union data; @@ -418,7 +418,7 @@ struct object_data_buffer { ~object_data_buffer(); draw_task* add_draw_task(draw_task_type type); - mat4u* add_mat4(int32_t count); + mat4* add_mat4(int32_t count); void reset(); }; @@ -448,10 +448,10 @@ struct object_data { morph_struct morph; int32_t texture_pattern_count; texture_pattern_struct texture_pattern_array[TEXTURE_PATTERN_COUNT]; - vec4u texture_color_coeff; - vec4u texture_color_offset; - vec4u texture_specular_coeff; - vec4u texture_specular_offset; + vec4 texture_color_coeff; + vec4 texture_color_offset; + vec4 texture_specular_coeff; + vec4 texture_specular_offset; float_t wet_param; int32_t texture_transform_count; texture_transform_struct texture_transform_array[TEXTURE_TRANSFORM_COUNT]; @@ -464,15 +464,15 @@ struct object_data { bool get_chara_color(); ::draw_task_flags get_draw_task_flags(); - void get_material_list(int32_t* count, material_list_struct* value); + void get_material_list(int32_t& count, material_list_struct*& value); void get_morph(object_info* object, float_t* value); shadow_type_enum get_shadow_type(); - void get_texture_color_coeff(vec4* value); - void get_texture_color_offset(vec4* value); - void get_texture_pattern(int32_t* count, texture_pattern_struct* value); - void get_texture_specular_coeff(vec4* value); - void get_texture_specular_offset(vec4* value); - void get_texture_transform(int32_t* count, texture_transform_struct* value); + void get_texture_color_coeff(vec4& value); + void get_texture_color_offset(vec4& value); + void get_texture_pattern(int32_t& count, texture_pattern_struct*& value); + void get_texture_specular_coeff(vec4& value); + void get_texture_specular_offset(vec4& value); + void get_texture_transform(int32_t& count, texture_transform_struct*& value); float_t get_wet_param(); void reset(); void set_chara_color(bool value = false); @@ -481,11 +481,11 @@ struct object_data { void set_morph(object_info object = {}, float_t value = 0.0f); void set_object_bounding_sphere_check_func(bool(*func)(obj_bounding_sphere*, camera*) = 0); void set_shadow_type(shadow_type_enum type = SHADOW_CHARA); - void set_texture_color_coeff(vec4* value); - void set_texture_color_offset(vec4* value); + void set_texture_color_coeff(vec4& value); + void set_texture_color_offset(vec4& value); void set_texture_pattern(int32_t count = 0, texture_pattern_struct* value = 0); - void set_texture_specular_coeff(vec4* value); - void set_texture_specular_offset(vec4* value); + void set_texture_specular_coeff(vec4& value); + void set_texture_specular_offset(vec4& value); void set_texture_transform(int32_t count = 0, texture_transform_struct* value = 0); void set_wet_param(float_t value = 0.0f); }; diff --git a/src/CRE/rob/ex_block.cpp b/src/CRE/rob/ex_block.cpp index 18980c2a..332d7e76 100644 --- a/src/CRE/rob/ex_block.cpp +++ b/src/CRE/rob/ex_block.cpp @@ -299,7 +299,7 @@ void RobOsageNodeDataNormalRef::GetMat() { vec3 v22; vec3 v23; if (sub_14053D1B0(&l_trans, &r_trans, &u_trans, &d_trans, &v22, &v21, &v23)) { - mat4u mat; + mat4 mat; mat.row0.x = v23.x; mat.row0.y = v21.x; mat.row0.z = v22.x; @@ -364,7 +364,7 @@ void RobOsageNodeData::Reset() { normal_ref.d = 0; normal_ref.l = 0; normal_ref.r = 0; - normal_ref.mat = mat4u_identity; + normal_ref.mat = mat4_identity; skp_osg_node.weight = 1.0f; skp_osg_node.inertial_cancel = 0.0f; skp_osg_node.coli_r = 0.0f; @@ -407,7 +407,7 @@ void RobOsageNode::Reset() { data_ptr = &data; opd_data.clear(); opd_data.resize(3); - mat = mat4u_null; + mat = mat4_null; } skin_param_osage_root_coli::skin_param_osage_root_coli() : type(), @@ -489,12 +489,12 @@ void osage_coli::set(osage_coli* coli, skin_param_osage_root_coli* skp_root_coli for (; skp_root_coli->type; coli++, skp_root_coli++) { coli->type = skp_root_coli->type; coli->radius = skp_root_coli->radius; - mat4 mat = mats[skp_root_coli->bone0_index]; - mat4_mult_vec3_trans(&mat, &skp_root_coli->bone0_pos, &coli->bone0_pos); + mat4_mult_vec3_trans(&mats[skp_root_coli->bone0_index], + &skp_root_coli->bone0_pos, &coli->bone0_pos); if (skp_root_coli->type == SKIN_PARAM_OSAGE_ROOT_COLI_TYPE_CYLINDER || skp_root_coli->type == SKIN_PARAM_OSAGE_ROOT_COLI_TYPE_ELLIPSE) { - mat = mats[skp_root_coli->bone1_index]; - mat4_mult_vec3_trans(&mat, &skp_root_coli->bone1_pos, &coli->bone1_pos); + mat4_mult_vec3_trans(&mats[skp_root_coli->bone1_index], + &skp_root_coli->bone1_pos, &coli->bone1_pos); vec3_sub(coli->bone1_pos, coli->bone0_pos, coli->bone_pos_diff); vec3_length_squared(coli->bone_pos_diff, coli->bone_pos_diff_length_squared); coli->bone_pos_diff_length = sqrtf(coli->bone_pos_diff_length_squared); @@ -502,7 +502,8 @@ void osage_coli::set(osage_coli* coli, skin_param_osage_root_coli* skp_root_coli coli->type = SKIN_PARAM_OSAGE_ROOT_COLI_TYPE_BALL; } else if (skp_root_coli->type == SKIN_PARAM_OSAGE_ROOT_COLI_TYPE_PLANE) - mat4_mult_vec3(&mat, &skp_root_coli->bone1_pos, &coli->bone1_pos); + mat4_mult_vec3(&mats[skp_root_coli->bone0_index], + &skp_root_coli->bone1_pos, &coli->bone1_pos); } coli->type = (skin_param_osage_root_coli_type)0; } @@ -721,7 +722,7 @@ void RobCloth::Disp(mat4* mat, render_context* rctx) { } void RobCloth::InitData(size_t root_count, size_t nodes_count, obj_skin_block_cloth_root* root, - obj_skin_block_cloth_node* nodes, mat4u* mats, int32_t a7, + obj_skin_block_cloth_node* nodes, mat4* mats, int32_t a7, rob_chara_item_equip_object* itm_eq_obj, bone_database* bone_data) { this->itm_eq_obj = itm_eq_obj; obj* obj = object_storage_get_obj(itm_eq_obj->obj_info); @@ -1403,9 +1404,7 @@ void RobOsage::InitData(obj_skin_block_osage* osg_data, obj_skin_osage_node* osg obj_skin_bone* v36 = skin->bones; for (uint32_t j = 0; j < skin->bones_count; j++, v36++) if (v36->id == osg_nodes->name_index) { - mat4 mat = skin->bones[j].inv_bind_pose_mat; - mat4_inverse_normalized(&mat, &mat); - v26[i].mat = mat; + mat4_inverse_normalized(&skin->bones[j].inv_bind_pose_mat, &v26[i].mat); break; } @@ -1414,11 +1413,8 @@ void RobOsage::InitData(obj_skin_block_osage* osg_data, obj_skin_osage_node* osg } RobOsageNode* v38 = &nodes.back(); - if (memcmp(&v38->mat, &mat4_null, sizeof(mat4))) { - mat4 mat = v38->mat; - mat4_translate_mult(&mat, node.length, 0.0f, 0.0f, &mat); - node.mat = mat; - } + if (memcmp(&v38->mat, &mat4_null, sizeof(mat4))) + mat4_translate_mult(&v38->mat, node.length, 0.0f, 0.0f, &node.mat); } float_t* RobOsage::LoadOpdData(size_t node_index, float_t* opd_data, size_t opd_count) { @@ -1482,7 +1478,7 @@ void RobOsage::Reset() { set_external_force = false; external_force = vec3_null; parent_mat_ptr = 0; - parent_mat = mat4u_null; + parent_mat = mat4_null; } void RobOsage::SetAirRes(float_t air_res) { @@ -2356,7 +2352,7 @@ void ExExpressionBlock::InitData(rob_chara_item_equip_object* itm_eq_obj, for (int32_t i = 0; i < 9; i++) { const char* expression = exp_data->expressions[i]; - if (!expression || str_utils_compare(expression, "= ")) + if (!expression || str_utils_compare_length(expression, utf8_length(expression), "= ", 2)) break; expression += 2; @@ -2718,6 +2714,67 @@ void skin_param_osage_root_parse(void* kv, const char* name, _kv->close_scope(); } +int32_t expression_id_to_mottbl_index(int32_t expression_id) { + static const int32_t expression_id_to_mottbl_index_table[] = { + 11, 15, 57, 19, 23, 25, 29, 33, + 37, 41, 45, 49, 53, 65, 7, 69, + 73, 77, 81, 85, 89, 7, 61, 6, + 214, 215, 216, 217, 218, 219, 220, 221, + 222, 223, 93, 95, 97, 99, 101, 103, + 105, 107, 109, 111, 113, 115, 117, 119, + 121, 123, 125, 127, 13, 21, 31, 39, + 43, 47, 51, 55, 67, 71, 79, 83, + 129, 59, 17, 91, 27, 87, 35, 75, + 9, 63, 236, 238, 240, 242, + }; + + if (expression_id >= 0 && expression_id + < sizeof(expression_id_to_mottbl_index_table) / sizeof(int32_t)) + return expression_id_to_mottbl_index_table[expression_id]; + return 6; +} + +int32_t hand_anim_id_to_mottbl_index(int32_t hand_anim_id) { + static const int32_t hand_anim_id_to_mottbl_index_table[] = { + 195, 196, 194, 197, 201, 198, 199, 202, + 203, 192, 200, 204, 204, 204, 193, + }; + + if (hand_anim_id >= 0 && hand_anim_id + < sizeof(hand_anim_id_to_mottbl_index_table) / sizeof(int32_t)) + return hand_anim_id_to_mottbl_index_table[hand_anim_id]; + return 192; +} + +int32_t look_anim_id_to_mottbl_index(int32_t look_anim_id) { + static const int32_t look_anim_id_to_mottbl_index_table[] = { + 168, 170, 174, 172, 178, 176, 182, 180, + 166, 165, 224, 169, 171, 175, 173, 179, + 177, 183, 181, 167, + }; + + if (look_anim_id >= 0 && look_anim_id + < sizeof(look_anim_id_to_mottbl_index_table) / sizeof(int32_t)) + return look_anim_id_to_mottbl_index_table[look_anim_id]; + return 165; +} + +int32_t mouth_anim_id_to_mottbl_index(int32_t mouth_anim_id) { + static const int32_t mouth_anim_id_to_mottbl_index_table[] = { + 134, 140, 142, 146, 144, 148, 150, 152, + 132, 131, 136, 138, 154, 155, 156, 157, + 158, 159, 160, 161, 162, 163, 164, 151, + 135, 143, 147, 145, 133, 137, 139, 141, + 149, 153, 244, 245, 246, 247, 248, 249, + 250, 251, 252, + }; + + if (mouth_anim_id >= 0 && mouth_anim_id + < sizeof(mouth_anim_id_to_mottbl_index_table) / sizeof(int32_t)) + return mouth_anim_id_to_mottbl_index_table[mouth_anim_id]; + return 131; +} + osage_setting::osage_setting() { } @@ -3120,9 +3177,8 @@ static void sub_1402196D0(RobCloth* rob_cls) { for (size_t i = 0; i < root_count; i++, root++) { CLOTHNode* node = &rob_cls->nodes.data()[i + root_count]; for (size_t j = 1; j < nodes_count; j++, node += root_count) { - mat4 mat = root->field_D8; - mat4_mult_vec3_trans(&mat, &node->reset_data.trans, &node->trans); - mat4_mult_vec3(&mat, &node->reset_data.trans_diff, &node->trans_diff); + mat4_mult_vec3_trans(&root->field_D8, &node->reset_data.trans, &node->trans); + mat4_mult_vec3(&root->field_D8, &node->reset_data.trans_diff, &node->trans_diff); } } } @@ -3391,7 +3447,7 @@ void sub_14021AA60(RobCloth* rob_cls, float_t step, bool a3) { vec3_mult_scalar(v44, v10, node->trans_diff); if (!a3) { - mat4 v49 = rob_cls->root.data()[j].field_118; + mat4& v49 = rob_cls->root.data()[j].field_118; mat4_mult_vec3_trans(&v49, &node->trans, &node->reset_data.trans); mat4_mult_vec3(&v49, &node->trans_diff, &node->reset_data.trans_diff); } diff --git a/src/CRE/rob/rob.cpp b/src/CRE/rob/rob.cpp index 28862b7f..677cb504 100644 --- a/src/CRE/rob/rob.cpp +++ b/src/CRE/rob/rob.cpp @@ -8,7 +8,9 @@ #include "../../KKdLib/str_utils.hpp" #include "../data.hpp" #include "../draw_task.hpp" +#include "../pv_db.hpp" #include "../random.hpp" +#include "../pv_expression.hpp" #include "../stage.hpp" struct MotFile { @@ -50,6 +52,42 @@ struct MhdFile { static void ParseFileParent(void* data, const void* file_data, size_t size); }; +/*struct OpdMaker { + struct Data { + bool field_0; + std::map, p_file_handler*> field_8; + + Data(); + ~Data(); + }; + + rob_chara* rob_chr; + std::vector* motion_ids; + bool waiting; + uint32_t index; + char field_18; + OpdMaker::Data* data; + std::thread* thread; + std::mutex* waiting_mtx; + std::mutex* field_38; + std::mutex* field_40; +}; + +struct OpdMakeWorker : public app::Task { + int32_t state; + int32_t chara_id; + int32_t field_70[25]; + bool field_D4; + + OpdMakeWorker(); + virtual ~OpdMakeWorker() override; + + bool Init() override; + bool Ctrl() override; + bool Dest() override; + void Disp() override; +};*/ + struct struc_380 { rob_chara* rob_chara; rob_chara_data* rob_chara_data; @@ -129,7 +167,7 @@ public: uint32_t motion_index; std::vector pv_set_motion; std::vector osage_set_motion; - void* pv;//pv_db_pv* pv; + pv_db_pv* pv; std::map reset_frames_list; std::thread* thread; std::condition_variable cnd; @@ -626,7 +664,7 @@ static void mothead_func_65_motion_skin_param(mothead_func_data* func_data, void* data, const mothead_data* mhd_data, int32_t frame, motion_database* mot_db); static void mothead_func_66_osage_step(mothead_func_data* func_data, void* data, const mothead_data* mhd_data, int32_t frame, motion_database* mot_db); -static void mothead_func_67(mothead_func_data* func_data, +static void mothead_func_67_sleeve(mothead_func_data* func_data, void* data, const mothead_data* mhd_data, int32_t frame, motion_database* mot_db); static void mothead_func_68(mothead_func_data* func_data, void* data, const mothead_data* mhd_data, int32_t frame, motion_database* mot_db); @@ -657,7 +695,7 @@ static void mothead_func_80_adjust_get_global_trans(mothead_func_data* func_data static void motion_blend_mot_interpolate(motion_blend_mot* a1); static void motion_blend_mot_load_bone_data(motion_blend_mot* a1, - rob_chara_bone_data* a2, bool(*bone_check_func)(motion_bone_index), bone_database* bone_data); + rob_chara_bone_data* a2, PFNMOTIONBONECHECKFUNC bone_check_func, bone_database* bone_data); static bool motion_blend_mot_interpolate_get_reverse(int32_t* a1); static void motion_blend_mot_load_file(motion_blend_mot* a1, int32_t motion_id, MotionBlendType blend_type, float_t blend, bone_database* bone_data, motion_database* mot_db); @@ -764,11 +802,11 @@ static void rob_chara_bone_data_set_parent_mats(rob_chara_bone_data* rob_bone_da static void rob_chara_bone_data_set_rot_y(rob_chara_bone_data* rob_bone_data, float_t rot_y); static void rob_chara_bone_data_update(rob_chara_bone_data* rob_bone_data, mat4* mat); -static bool rob_chara_item_cos_data_check_for_npr_flag(rob_chara_item_cos_data* itm_cos_data); +static bool rob_chara_item_cos_data_check_for_npr_flag(rob_chara_item_cos_data* item_cos_data); static object_info rob_chara_item_cos_data_get_head_object_replace( rob_chara_item_cos_data* item_cos_data, int32_t head_object_id); static float_t rob_chara_item_cos_data_get_max_face_depth(rob_chara_item_cos_data* item_cos_data); -static void rob_chara_item_cos_data_reload_items(rob_chara_item_cos_data* itm_cos_data, +static void rob_chara_item_cos_data_reload_items(rob_chara_item_cos_data* item_cos_data, int32_t chara_id, bone_database* bone_data, void* data, object_database* obj_db); static void rob_chara_item_cos_data_set_chara_index( rob_chara_item_cos_data* item_cos_data, chara_index chara_index); @@ -781,10 +819,11 @@ static void rob_chara_item_cos_data_set_item_no( rob_chara_item_cos_data* item_cos_data, item_sub_id sub_id, int32_t item_no); static void rob_chara_item_cos_data_set_item_nos( rob_chara_item_cos_data* item_cos_data, int32_t* item_nos); +static void rob_chara_item_cos_data_set_item_zero(rob_chara_item_cos_data* item_cos_data, int32_t item_no); static void rob_chara_item_cos_data_texture_change_clear(rob_chara_item_cos_data* item_cos_data); static void rob_chara_item_cos_data_texture_pattern_clear(rob_chara_item_cos_data* item_cos_data); -static void rob_chara_item_equip_add_motion_reset_data(rob_chara_item_equip* rob_item_equip, +static void rob_chara_item_equip_add_motion_reset_data(rob_chara_item_equip* rob_itm_equip, int32_t motion_id, float_t frame, int32_t iterations); static void rob_chara_item_equip_disp( rob_chara_item_equip* rob_itm_equip, int32_t chara_id, render_context* rctx); @@ -925,7 +964,7 @@ static const mothead_func_struct mothead_func_array[] = { { mothead_func_64_osage_reset, 0 }, { mothead_func_65_motion_skin_param, 0 }, { mothead_func_66_osage_step, 0 }, - { mothead_func_67, 0 }, + { mothead_func_67_sleeve, 0 }, { mothead_func_68, 0 }, { mothead_func_69, 0 }, { mothead_func_70, 0 }, @@ -1063,9 +1102,8 @@ static const struc_218 stru_140A25340[] = { static const chara_init_data chara_init_data_array[] = { { - 0x0000, BONE_DATABASE_SKELETON_MIKU, + 0x0000, BONE_DATABASE_SKELETON_MIKU, object_info(0x0000, 0x0000), { - object_info(0x0000, 0x0000), object_info(0x00F7, 0x0000), object_info(), object_info(), @@ -1113,9 +1151,8 @@ static const chara_init_data chara_init_data_array[] = { }, }, { - 0x0107, BONE_DATABASE_SKELETON_RIN, + 0x0107, BONE_DATABASE_SKELETON_RIN, object_info(0x0000, 0x0000), { - object_info(0x0000, 0x0000), object_info(0x004A, 0x0107), object_info(), object_info(), @@ -1163,9 +1200,8 @@ static const chara_init_data chara_init_data_array[] = { }, }, { - 0x0105, BONE_DATABASE_SKELETON_LEN, + 0x0105, BONE_DATABASE_SKELETON_LEN, object_info(0x0000, 0x0000), { - object_info(0x0000, 0x0000), object_info(0x0040, 0x0105), object_info(), object_info(), @@ -1213,9 +1249,8 @@ static const chara_init_data chara_init_data_array[] = { }, }, { - 0x0106, BONE_DATABASE_SKELETON_LUKA, + 0x0106, BONE_DATABASE_SKELETON_LUKA, object_info(0x0000, 0x0000), { - object_info(0x0000, 0x0000), object_info(0x004C, 0x0106), object_info(), object_info(), @@ -1263,9 +1298,8 @@ static const chara_init_data chara_init_data_array[] = { }, }, { - 0x0108, BONE_DATABASE_SKELETON_NERU, + 0x0108, BONE_DATABASE_SKELETON_NERU, object_info(0x0000, 0x0000), { - object_info(0x0000, 0x0000), object_info(0x0019, 0x0108), object_info(), object_info(), @@ -1313,9 +1347,8 @@ static const chara_init_data chara_init_data_array[] = { }, }, { - 0x0109, BONE_DATABASE_SKELETON_HAKU, + 0x0109, BONE_DATABASE_SKELETON_HAKU, object_info(0x0000, 0x0000), { - object_info(0x0000, 0x0000), object_info(0x001F, 0x0109), object_info(), object_info(), @@ -1363,9 +1396,8 @@ static const chara_init_data chara_init_data_array[] = { }, }, { - 0x010D, BONE_DATABASE_SKELETON_KAITO, + 0x010D, BONE_DATABASE_SKELETON_KAITO, object_info(0x0000, 0x0000), { - object_info(0x0000, 0x0000), object_info(0x003C, 0x010D), object_info(), object_info(), @@ -1413,9 +1445,8 @@ static const chara_init_data chara_init_data_array[] = { }, }, { - 0x010E, BONE_DATABASE_SKELETON_MEIKO, + 0x010E, BONE_DATABASE_SKELETON_MEIKO, object_info(0x0000, 0x0000), { - object_info(0x0000, 0x0000), object_info(0x0040, 0x010E), object_info(), object_info(), @@ -1463,9 +1494,8 @@ static const chara_init_data chara_init_data_array[] = { }, }, { - 0x010F, BONE_DATABASE_SKELETON_SAKINE, + 0x010F, BONE_DATABASE_SKELETON_SAKINE, object_info(0x0000, 0x0000), { - object_info(0x0000, 0x0000), object_info(0x001A, 0x010F), object_info(), object_info(), @@ -1513,9 +1543,8 @@ static const chara_init_data chara_init_data_array[] = { }, }, { - 0x063D, BONE_DATABASE_SKELETON_TETO, + 0x063D, BONE_DATABASE_SKELETON_TETO, object_info(0x0000, 0x0000), { - object_info(0x0000, 0x0000), object_info(0x0000, 0x063D), object_info(), object_info(), @@ -1643,72 +1672,63 @@ static const struc_241 chara_some_data_array[] = { { -0.0610865242779255f, 0.104719758033752f, -0.0802851468324661f, 0.113446399569511f, -0.0436332300305367f, 0.0610865242779255f, -0.0802851468324661f, 0.113446399569511f, - 0.0148999998345971f, -0.0212999992072582f, 0.0f, 1.0f, - 1.0f, -3.8f, 6.0f, -3.8f, - 6.0f, + { 0.0148999998345971f, -0.0212999992072582f, 0.0f, }, + 1.0f, 1.0f, -3.8f, 6.0f, -3.8f, 6.0f, }, { -0.0610865242779255f, 0.104719758033752f, -0.0802851468324661f, 0.113446399569511f, -0.0750491619110107f, 0.104719758033752f, -0.0733038261532783f, 0.125663697719574f, - 0.033500000834465f, -0.0111999996006489f, 0.0f, 1.0f, - 1.0f, -5.5f, 10.0f, -5.5f, - 6.5f, + { 0.033500000834465f, -0.0111999996006489f, 0.0f, }, + 1.0f, 1.0f, -5.5f, 10.0f, -5.5f, 6.5f, }, { -0.0610865242779255f, 0.104719758033752f, -0.0802851468324661f, 0.113446399569511f, -0.0837758034467697f, 0.0855211317539215f, -0.104719758033752f, 0.120427720248699f, - 0.0166999995708466f, -0.00540000014007092f, 0.0f, 1.0f, - 1.0f, -6.5f, 6.0f, -6.0f, - 2.0f, + { 0.0166999995708466f, -0.00540000014007092f, 0.0f, }, + 1.0f, 1.0f, -6.5f, 6.0f, -6.0f, 2.0f, }, { -0.0610865242779255f, 0.104719758033752f, -0.0802851468324661f, 0.113446399569511f, -0.0349065847694874f, 0.0698131695389748f, -0.0872664600610733f, 0.113446399569511f, - 0.011400000192225f, 0.00810000021010637f, 0.0f, 1.0f, - 1.0f, -3.5f, 6.0f, -3.5f, - 6.0f, + { 0.011400000192225f, 0.00810000021010637f, 0.0f, }, + 1.0f, 1.0f, -3.5f, 6.0f, -3.5f, 6.0f, }, { -0.0610865242779255f, 0.104719758033752f, -0.0802851468324661f, 0.113446399569511f, -0.0349065847694874f, 0.0733038261532783f, -0.0907571166753769f, 0.13962633907795f, - 0.0151000004261732f, -0.0439999997615814f, 0.0f, 1.0f, - 1.0f, -2.6f, 6.0f, -2.6f, - 6.0f, + { 0.0151000004261732f, -0.0439999997615814f, 0.0f, }, + 1.0f, 1.0f, -2.6f, 6.0f, -2.6f, 6.0f, }, { -0.0610865242779255f, 0.104719758033752f, -0.0802851468324661f, 0.113446399569511f, -0.0523598790168762f, 0.122173048555851f, -0.0872664600610733f, 0.130899697542191f, - 0.0221999995410442f, -0.000199999994947575f, 0.0f, 1.0f, + { 0.0221999995410442f, -0.000199999994947575f, 0.0f, }, 1.0f, 1.0f, -4.0f, 7.5f, -3.5f, 6.0f, }, { -0.0610865242779255f, 0.104719758033752f, -0.0802851468324661f, 0.113446399569511f, -0.0733038261532783f, 0.101229101419449f, -0.0785398185253143f, 0.113446399569511f, - 0.025000000372529f, -0.0230999998748302f, 0.0f, 1.0f, - 1.0f, -4.0f, 6.0f, -3.8f, - 3.5f, + { 0.025000000372529f, -0.0230999998748302f, 0.0f, }, + 1.0f, 1.0f, -4.0f, 6.0f, -3.8f, 3.5f, }, { -0.0610865242779255f, 0.104719758033752f, -0.0802851468324661f, 0.113446399569511f, -0.0663225129246712f, 0.0593411959707737f, -0.0785398185253143f, 0.113446399569511f, - 0.0118000004440546f, -0.00510000018402934f, 0.0f, 1.0f, - 1.0f, -5.6f, 6.0f, -5.6f, - 5.5f, + { 0.0118000004440546f, -0.00510000018402934f, 0.0f, }, + 1.0f, 1.0f, -5.6f, 6.0f, -5.6f, 5.5f, }, { -0.0610865242779255f, 0.104719758033752f, -0.0802851468324661f, 0.113446399569511f, -0.0645771846175194f, 0.0663225129246712f, -0.0698131695389748f, 0.113446399569511f, - 0.0229000002145767f, -0.0148999998345971f, 0.0f, 1.0f, - 1.0f, -5.0f, 4.0f, -5.0f, - 2.5f, + { 0.0229000002145767f, -0.0148999998345971f, 0.0f, }, + 1.0f, 1.0f, -5.0f, 4.0f, -5.0f, 2.5f, }, { -0.0610865242779255f, 0.104719758033752f, -0.0802851468324661f, 0.113446399569511f, -0.0698131695389748f, 0.0698131695389748f, -0.113446399569511f, 0.122173048555851f, - 0.0137000000104308f, -0.00800000037997961f, 0.0f, 1.0f, - 1.0f, -5.5f, 6.0f, -5.0f, - 4.0f, + { 0.0137000000104308f, -0.00800000037997961f, 0.0f, }, + 1.0f, 1.0f, -5.5f, 6.0f, -5.0f, 4.0f, }, }; @@ -2139,8 +2159,8 @@ static void sub_140509D30(rob_chara* rob_chr) { struc_195* v39 = rob_chr->data.field_1E68.field_DF8; struc_195* v40 = rob_chr->data.field_1E68.field_1230; struc_195* v41 = rob_chr->data.field_1E68.field_1668; - mat4u* v42 = rob_chr->data.field_1E68.field_78; - mat4u* v43 = rob_chr->data.field_1E68.field_738; + mat4* v42 = rob_chr->data.field_1E68.field_78; + mat4* v43 = rob_chr->data.field_1E68.field_738; const struc_218* v3 = rob_chr->chara_init_data->field_828; const struc_218* v6 = rob_chr->chara_init_data->field_830; @@ -2194,6 +2214,14 @@ static void sub_140509D30(rob_chara* rob_chr) { } } +void rob_chara::autoblink_disable() { + data.motion.field_2A |= 0x02; +} + +void rob_chara::autoblink_enable() { + data.motion.field_2A &= ~0x02; +} + mat4* rob_chara::get_bone_data_mat(size_t index) { return rob_chara_bone_data_get_mat(bone_data, index); } @@ -2291,16 +2319,16 @@ static void sub_14041C990(rob_chara_bone_data* rob_bone_data, float_t a2, int32_ } static void sub_14041B9D0(rob_chara_bone_data* rob_bone_data) { - struc_312* v1 = &rob_bone_data->field_958; - v1->field_58 = false; - v1->field_59 = false; - v1->field_5C = vec3_null; - v1->field_68 = vec3_null; - v1->field_74 = vec3_null; - v1->field_80 = vec3_null; - v1->field_8C = 1.0f; - v1->bones = 0; - v1->step = 1.0f; + rob_chara_bone_data_sleeve_adjust& sleeve_adjust = rob_bone_data->sleeve_adjust; + sleeve_adjust.enable1 = false; + sleeve_adjust.enable2 = false; + sleeve_adjust.field_5C = vec3_null; + sleeve_adjust.field_68 = vec3_null; + sleeve_adjust.field_74 = vec3_null; + sleeve_adjust.field_80 = vec3_null; + sleeve_adjust.radius = 1.0f; + sleeve_adjust.bones = 0; + sleeve_adjust.step = 1.0f; } static void sub_14041D6F0(rob_chara_bone_data* rob_bone_data, bool a2) { @@ -2741,7 +2769,7 @@ void rob_chara::load_motion(int32_t motion_id, bool a3, float_t frame, data.motion.field_30 = 0; rob_chara_data_adjust* parts_adjust = data.motion.parts_adjust; - for (int32_t i = 0; i < 13; i++, parts_adjust++) + for (int32_t i = 0; i < ROB_OSAGE_PARTS_MAX; i++, parts_adjust++) parts_adjust->reset(); data.motion.adjust_global.reset(); @@ -2913,7 +2941,7 @@ static void rob_chara_set_eyelid_motion(rob_chara* rob_chr, RobEyelidMotion* motion, int32_t type, motion_database* mot_db) { if (type == 1 || type == 2) { rob_chr->data.motion.field_3B0.eyelid.data = motion->data; - if (rob_chr->data.motion.field_29 & 0x80) + if (~rob_chr->data.motion.field_29 & 0x80) return; } else { @@ -3175,8 +3203,8 @@ void rob_chara::set_eyelid_mottbl_motion_from_face(int32_t a2, } else { v13.data.state = 0; - v13.data.frame = (v13.data.frame_count - 1.0f) * value; v13.data.frame_count = motion_storage_get_mot_data_frame_count(motion_id, mot_db); + v13.data.frame = (v13.data.frame_count - 1.0f) * value; } } break; } @@ -3314,7 +3342,7 @@ void rob_chara::set_face_mottbl_motion(int32_t type, duration = 0.0f; } - if (type == 1 || type == 2) { + if (type != 1 || type != 2) { if (a11) set_eyelid_mottbl_motion_from_face(2, duration, -1.0f, offset, mot_db); else if (data.motion.field_29 & 0x02) { @@ -3417,7 +3445,7 @@ bool rob_chara::set_motion_id(int32_t motion_id, set_motion_skin_param(motion_id, (float_t)(int32_t)frame); if (duration == 0.0f) { if (set_motion_reset_data) - this->set_motion_reset_data(motion_id, frame); + rob_chara::set_motion_reset_data(motion_id, frame); item_equip->item_equip_object[ITEM_TE_L].osage_iterations = 60; item_equip->item_equip_object[ITEM_TE_R].osage_iterations = 60; @@ -3538,12 +3566,12 @@ static void bone_data_mult_0(bone_data* a1, int32_t skeleton_select) { if (a1->type == BONE_DATABASE_BONE_POSITION) { mat4_translate_mult(&mat, a1->trans.x, a1->trans.y, a1->trans.z, &mat); - a1->rot_mat[0] = mat4u_identity; + a1->rot_mat[0] = mat4_identity; } else if (a1->type == BONE_DATABASE_BONE_TYPE_1) { mat4_mult_vec3_inv_trans(&mat, &a1->trans, &a1->trans); mat4_translate_mult(&mat, a1->trans.x, a1->trans.y, a1->trans.z, &mat); - a1->rot_mat[0] = mat4u_identity; + a1->rot_mat[0] = mat4_identity; } else { mat4 rot_mat; @@ -3611,12 +3639,11 @@ static void bone_data_mult_1(bone_data* a1, mat4* parent_mat, bone_data* a3, boo a1->rot_mat[0] = rot_mat; } else - a1->rot_mat[0] = mat4u_identity; + a1->rot_mat[0] = mat4_identity; } } - mat4 rot_mat = a1->rot_mat[0]; - mat4_mult(&rot_mat, &mat, &mat); + mat4_mult(&a1->rot_mat[0], &mat, &mat); } else { mat4_translate_mult(&mat, a1->trans.x, a1->trans.y, a1->trans.z, &mat); @@ -3633,8 +3660,7 @@ static void bone_data_mult_1(bone_data* a1, mat4* parent_mat, bone_data* a3, boo if (a1->type < BONE_DATABASE_BONE_HEAD_IK_ROTATION) return; - mat4 rot_mat = a1->rot_mat[1]; - mat4_mult(&rot_mat, &mat, &mat); + mat4_mult(&a1->rot_mat[1], &mat, &mat); *a1->node[1].mat = mat; if (a1->type == BONE_DATABASE_BONE_HEAD_IK_ROTATION) { @@ -3651,8 +3677,7 @@ static void bone_data_mult_1(bone_data* a1, mat4* parent_mat, bone_data* a3, boo } else { mat4_translate_mult(&mat, a1->ik_segment_length[1], 0.0f, 0.0f, &mat); - mat4 rot_mat = a1->rot_mat[2]; - mat4_mult(&rot_mat, &mat, &mat); + mat4_mult(&a1->rot_mat[2], &mat, &mat); *a1->node[2].mat = mat; mat4_translate_mult(&mat, a1->ik_2nd_segment_length[1], 0.0f, 0.0f, &mat); @@ -5388,7 +5413,7 @@ static void mothead_func_66_osage_step(mothead_func_data* func_data, func_data->rob_chr->set_osage_step(((float_t*)data)[0]); } -static void mothead_func_67(mothead_func_data* func_data, +static void mothead_func_67_sleeve(mothead_func_data* func_data, void* data, const mothead_data* mhd_data, int32_t frame, motion_database* mot_db) { bool v5 = false; bool v6 = false; @@ -5406,9 +5431,9 @@ static void mothead_func_67(mothead_func_data* func_data, } rob_chara_bone_data* rob_bone_data = func_data->rob_chr->bone_data; - rob_bone_data->field_958.field_58 = v6; - rob_bone_data->field_958.field_59 = v5; - rob_bone_data->field_958.field_8C = ((float_t*)data)[1]; + rob_bone_data->sleeve_adjust.enable1 = v6; + rob_bone_data->sleeve_adjust.enable2 = v5; + rob_bone_data->sleeve_adjust.radius = ((float_t*)data)[1]; } static void mothead_func_68(mothead_func_data* func_data, @@ -5844,7 +5869,7 @@ static void sub_140414550(struc_313* a1, size_t a2, bool a3) { } } -static void sub_140413350(struc_240* a1, bool(*bone_check_func)(motion_bone_index), size_t motion_bone_count) { +static void sub_140413350(struc_240* a1, PFNMOTIONBONECHECKFUNC bone_check_func, size_t motion_bone_count) { a1->bone_check_func = bone_check_func; a1->motion_bone_count = motion_bone_count; sub_1404119A0(&a1->field_8); @@ -5853,7 +5878,7 @@ static void sub_140413350(struc_240* a1, bool(*bone_check_func)(motion_bone_inde } static void motion_blend_mot_load_bone_data(motion_blend_mot* a1, - rob_chara_bone_data* a2, bool(*bone_check_func)(motion_bone_index), bone_database* bone_data) { + rob_chara_bone_data* a2, PFNMOTIONBONECHECKFUNC bone_check_func, bone_database* bone_data) { bone_data_parent_data_init(&a1->bone_data, a2, bone_data); mot_key_data_init_key_sets( &a1->mot_key_data, @@ -5933,7 +5958,7 @@ static void motion_blend_mot_load_file(motion_blend_mot* a1, int32_t motion_id, a1->field_4F8.field_8C = false; a1->field_4F8.field_4C = a1->field_4F8.mat; - a1->field_4F8.mat = mat4u_identity; + a1->field_4F8.mat = mat4_identity; } static void motion_blend_mot_mult_mat(motion_blend_mot* a1, mat4* mat) { @@ -5942,11 +5967,11 @@ static void motion_blend_mot_mult_mat(motion_blend_mot* a1, mat4* mat) { a1->field_4F8.field_8C = true; } else { - a1->field_4F8.mat = mat4u_identity; + a1->field_4F8.mat = mat4_identity; a1->field_4F8.field_8C = false; } - mat4 m = a1->field_4F8.mat; + mat4& m = a1->field_4F8.mat; bone_data* v3 = a1->bone_data.bones.data(); for (bone_data& v4 : a1->bone_data.bones) bone_data_mult_1(&v4, &m, v3, true); @@ -6035,11 +6060,11 @@ static void sub_140414900(struc_308* a1, mat4* a2) { } else { a1->field_8C = false; - a1->mat = mat4u_identity; + a1->mat = mat4_identity; } } -static mat4u* sub_140504E80(rob_chara* rob_chr) { +static mat4* sub_140504E80(rob_chara* rob_chr) { mat4 mat; mat4_rotate_y((float_t)((double_t)rob_chr->data.miku_rot.rot_y_int16 * M_PI * (1.0 / 32768.0)), &mat); mat4_set_translation(&mat, &rob_chr->data.miku_rot.position); @@ -6054,8 +6079,7 @@ static void sub_14041DA50(rob_chara_bone_data* rob_bone_data, mat4* mat) { } static void sub_140507F60(rob_chara* rob_chr) { - mat4 v2 = *sub_140504E80(rob_chr); - sub_14041DA50(rob_chr->bone_data, &v2); + sub_14041DA50(rob_chr->bone_data, sub_140504E80(rob_chr)); rob_chr->data.miku_rot.field_48 = rob_chr->data.miku_rot.field_24; mat4* v3 = rob_chara_bone_data_get_mats_mat(rob_chr->bone_data, ROB_BONE_N_HARA); @@ -6226,7 +6250,7 @@ static void rob_chara_item_equip_set_external_force( static void rob_chara_adjust_ctrl(rob_chara* rob_chr) { rob_chara_item_equip* rob_itm_equip = rob_chr->item_equip; - for (int32_t i = 0; i < 13; i++) { + for (int32_t i = 0; i < ROB_OSAGE_PARTS_MAX; i++) { rob_chara_data_adjust* parts_adjust = &rob_chr->data.motion.parts_adjust[i]; if (parts_adjust->enable) { rob_chara_data_adjust_ctrl(rob_chr, parts_adjust, &rob_chr->data.motion.parts_adjust_prev[i]); @@ -6355,7 +6379,7 @@ static void sub_1405145F0(rob_chara* rob_chr, bone_database* bone_data, motion_d static void sub_1405144C0(rob_chara* rob_chr, bone_database* bone_data, motion_database* mot_db) { if (rob_chr->data.field_8.field_4.field_0 == 1) { - //sub_14036D130(6, &rob_chr); + pv_expression_array_ctrl(rob_chr); sub_1405145F0(rob_chr, bone_data, mot_db); } } @@ -7354,7 +7378,7 @@ static void rob_disp_rob_chara_init(rob_chara* rob_chr, rob_chara_item_equip_load_object_info(rob_chr->item_equip, object_info(), ITEM_BODY, false, bone_data, data, obj_db); rob_chara_item_equip_load_object_info(rob_chr->item_equip, - rob_chr->chara_init_data->field_7E0[ITEM_ATAMA], ITEM_ATAMA, false, bone_data, data, obj_db); + rob_chr->chara_init_data->field_7E4[0], ITEM_ATAMA, false, bone_data, data, obj_db); rob_chara_item_equip_set_shadow_type(rob_chr->item_equip, rob_chr->chara_id); rob_chr->item_equip->field_A0 = 5; rob_chara_item_cos_data_reload_items(&rob_chr->item_cos_data, @@ -7431,7 +7455,7 @@ static void rob_disp_rob_chara_ctrl_thread_main(rob_chara* rob_chr) { } static void rob_disp_rob_chara_disp(rob_chara* rob_chr) { - rob_chr->item_equip->texture_color_coeff = vec4u_identity; + rob_chr->item_equip->texture_color_coeff = vec4_identity; rob_chr->item_equip->mat = rob_chr->data.adjust_data.mat; rob_chara_item_equip_disp(rob_chr->item_equip, rob_chr->chara_id, rctx_ptr); } @@ -7463,7 +7487,7 @@ static bool sub_140419F00(rob_chara_bone_data* rob_bone_data) { return false; } -static void sub_140409B70(struc_258* a1, vec3* a2, mat4u* a3, bool a4) { +static void sub_140409B70(struc_258* a1, vec3* a2, mat4* a3, bool a4) { if (a2) { a1->field_190 = true; a1->field_191 = a4; @@ -7489,28 +7513,28 @@ static void sub_140409B70(struc_258* a1, vec3* a2, mat4u* a3, bool a4) { mat4_mult_vec3_trans(&mat, a2, &v24); float_t v12 = v24.x - 0.05f; - if (a1->field_184 >= v12) { + if (a1->field_184.x >= v12) { v12 = v24.x + 0.05f; - if (a1->field_184 <= v12) - v12 = a1->field_184; + if (a1->field_184.x <= v12) + v12 = a1->field_184.x; } - a1->field_184 = v12; + a1->field_184.x = v12; float_t v15 = v24.y - 0.05f; - if (a1->field_188 >= v15) { + if (a1->field_184.y >= v15) { v15 = v24.y + 0.05f; - if (a1->field_188 <= v15) - v15 = a1->field_188; + if (a1->field_184.y <= v15) + v15 = a1->field_184.y; } - a1->field_188 = v15; + a1->field_184.y = v15; float_t v18 = v24.z - 0.05f; - if (a1->field_18C >= v18) { + if (a1->field_184.z >= v18) { v18 = v24.z + 0.05f; - if (a1->field_18C <= v18) - v18 = a1->field_18C; + if (a1->field_184.z <= v18) + v18 = a1->field_184.z; } - a1->field_18C = v18; + a1->field_184.z = v18; } else { if (!a1->field_190 && !a1->field_191) { @@ -7536,29 +7560,503 @@ static void sub_140409B70(struc_258* a1, vec3* a2, mat4u* a3, bool a4) { } } -static void sub_14041C620(rob_chara_bone_data* rob_bone_data, vec3* a2, mat4u* a3, char a4) { +static void sub_14041C620(rob_chara_bone_data* rob_bone_data, vec3* a2, mat4* a3, bool a4) { sub_140409B70(&rob_bone_data->field_788, a2, a3, a4); } -static void sub_1404189A0(rob_chara_bone_data* rob_bone_data) { - //motion_blend_mot* v2 = rob_bone_data->motion_loaded.front(); - //sub_140407280(&rob_bone_data->field_788, &v2->bone_data.bones, - // &v2->field_4F8.mat, v2->mot_play_data.frame_data.step); +static float_t sub_14040ADE0(float_t a1, float_t a2) { + float_t v1 = a1 - a2; + if (v1 > (float_t)M_PI) + return v1 - (float_t)(M_PI * 2.0); + else if (v1 < (float_t)-M_PI) + return v1 + (float_t)(M_PI * 2.0); + return v1; } -static void sub_14041A160(rob_chara_bone_data* rob_bone_data, mat4u* a2) { - //motion_blend_mot* v2 = rob_bone_data->motion_loaded.front(); - //sub_140409170(&rob_bone_data->field_788, a2, &v2->bone_data.bones, - // &v2->field_4F8.mat, v2->mot_play_data.frame_data.step); +static void sub_140407280(struc_258* a1, std::vector* a2, mat4* mat, float_t step) { + bone_data* v7 = a2->data(); + + vec3 v69; + mat4_get_translation(v7[MOTION_BONE_CL_KAO].node[2].mat, &v69); + if (!a1->field_190 && !a1->field_191) + return; + + float_t v14 = step * 0.25f; + float_t v15 = a1->field_15C.field_8; + float_t v18 = -v15; + float_t v16 = a1->field_15C.field_C; + mat4* v19 = v7[MOTION_BONE_C_KATA_R].node->mat; + mat4* v20 = v7[MOTION_BONE_C_KATA_L].node->mat; + float_t v21 = v19->row3.x - v20->row3.x; + float_t v22 = v19->row3.z - v20->row3.z; + mat4* v73 = v7[MOTION_BONE_N_KAO].node->mat; + float_t v23 = atan2f(v73->row0.x, v73->row0.z); + float_t v24 = atan2f(v21, v22); + float_t v25 = sub_14040ADE0(v24, v23); + if (v25 < 0.0f) + v15 = v25 + v15; + else if (v25 > 0.0f) + v18 = v25 - v15; + + vec3 v67; + mat4_mult_vec3_inv_trans(v73, &a1->field_184, &v67); + + float_t v26; + vec3_length(v67, v26); + if (v26 < 0.000001f) + return; + + vec3 v68; + mat4_mult_vec3_inv_trans(v73, &v69, &v68); + + float_t v28; + vec3_length(v68, v28); + if (v28 < 0.000001f) + return; + + vec3_normalize(v67, v67); + vec3_mult_scalar(v67, v28, v68); + + float_t v39; + vec2_length(*(vec2*)&v67, v39); + + float_t v38; + if (a1->field_1C8 == 3) + v38 = (float_t)(75.0 * DEG_TO_RAD) - (float_t)(30.0 * DEG_TO_RAD); + else + v38 = (float_t)(75.0 * DEG_TO_RAD); + + float_t v31; + vec3_length(v67, v31); + + bool v36; + float_t v40; + if (v39 >= v31 * cosf(v38)) { + v40 = atan2f(-v67.x, v67.y); + v36 = false; + } + else { + v40 = a1->field_19C; + v36 = true; + } + + float_t v42 = v40; + if (a1->field_190) { + if (a1->field_1C8 == 3) + v16 -= (float_t)(100.0 * DEG_TO_RAD); + + if (v36 || v40 > v16 || v40 < -v16) { + v40 = 0.0f; + v14 *= 0.5f; + a1->field_1C8 = 3; + } + else if (v40 > v15) { + v40 = v15; + a1->field_1C8 = 2; + v14 *= 0.5f; + } + else if (v40 < v18) { + v40 = v18; + v14 *= 0.5f; + a1->field_1C8 = 1; + } + else + return; + } + else + a1->field_1C8 = 0; + + int32_t v43 = a1->field_1C8; + float_t v44 = a1->field_94; + if (v43 != 3 && a1->field_14C) { + if (!v43) + v14 *= 0.5f; + + float_t v45 = a1->field_154; + if (fabsf(a1->field_154) <= 0.000001f) { + if (v40 >= 0.0f) { + v40 = v40 + -(float_t)(50.0 * DEG_TO_RAD); + if (v40 < v18) + v40 = v18; + } + else { + v40 = v40 + (float_t)(50.0 * DEG_TO_RAD); + if (v40 > v15) + v40 = v15; + } + } + else if (v45 >= 0.0f) { + float_t v46 = v40 + (float_t)(50.0 * DEG_TO_RAD); + if (v46 > v15) + v46 = v15; + + float_t v47 = v40 - (float_t)(50.0 * DEG_TO_RAD); + if (v47 < v18) + v47 = v18; + + if (v40 + (float_t)(50.0 * DEG_TO_RAD) < v45) { + if (v42 < (float_t)(-700.0 * DEG_TO_RAD)) { + a1->field_1C8 = 3; + v46 = 0.0f; + } + else + v46 = a1->field_154; + + v40 = v46; + } + else if (v46 - (float_t)(30.0 * DEG_TO_RAD) >= v40) + v40 = v46; + else + v40 = v47; + } + else { + float_t v46 = v40 - (float_t)(50.0 * DEG_TO_RAD); + if (v40 - (float_t)(50.0 * DEG_TO_RAD) < v18) + v46 = v18; + + float_t v47 = v40 + (float_t)(50.0 * DEG_TO_RAD); + if (v40 + (float_t)(50.0 * DEG_TO_RAD) > v15) + v47 = v15; + + if (v40 - (float_t)(50.0 * DEG_TO_RAD) > v45) { + if (v42 > (float_t)(70.0 * DEG_TO_RAD)) { + a1->field_1C8 = 3; + v46 = 0.0f; + } + else + v46 = a1->field_154; + v40 = v46; + } + else if (v46 + (float_t)(30.0 * DEG_TO_RAD) <= v40) + v40 = v46; + else + v40 = v47; + } + + v44 = a1->field_150; + a1->field_154 = v40; + } + else + a1->field_154 = 0.0f; + + float_t v48 = v40 * v44; + float_t v49 = v48; + if (a1->field_191) { + a1->field_19C = v48; + if (!a1->field_190) + v48 = a1->field_1AC; + else + a1->field_1AC = v48; + } + else { + if (a1->field_192) + v48 = sub_14040ADE0(v48, a1->field_19C) * v14 + a1->field_19C; + a1->field_19C = v48; + a1->field_1AC = v48; + } + + float_t v51 = (v48 - atan2f(-v68.x, v68.y)) * a1->field_198; + vec3 v71 = *(vec3*&)v73->row2; + v71.y += 1.0f; + 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_vec3_inv_trans(&v72, &a1->field_184, &v67); + + float_t v52; + if (v36) + v52 = a1->field_1A0; + else + vec2_length(*(vec2*)&v67, v52); + + if (a1->field_190) { + float_t v55 = fabsf(v49); + float_t v56; + if (v52 >= 0.0f) + v56 = v55 * a1->field_15C.field_24; + else + v56 = v55 * a1->field_15C.field_20; + v52 = v52 * (float)((float)(a1->field_15C.field_8 - v56) / a1->field_15C.field_8); + float_t v57 = a1->field_15C.field_0; + if (v52 < v57 || (v57 = a1->field_15C.field_4, v52 > v57)) + v52 = v57; + } + + if (a1->field_1C8 == 3 || a1->field_14C) + v52 = 0.0f; + + float_t v58 = v52 * a1->field_94; + a1->field_158 = 0.0f; + + if (!a1->field_191) { + if (a1->field_193) + v58 = sub_14040ADE0(v58, a1->field_1A0) * v14 + a1->field_1A0; + a1->field_1A0 = v58; + a1->field_1B0 = v58; + } + else { + a1->field_1A0 = v58; + if (a1->field_190) + a1->field_1B0 = v58; + else + v58 = a1->field_1B0; + + } + + mat4_rotate_y_mult(&v72, v58 * a1->field_198, &v72); + + mat4 v60 = v7[MOTION_BONE_CL_KAO].rot_mat[1]; + + mat4 v74; + mat4_inverse(v7[MOTION_BONE_CL_KAO].node->mat, &v74); + mat4_clear_trans(&v74, &v74); + mat4_mult(&v7[MOTION_BONE_CL_KAO].rot_mat[1], &v74, &v72); + + for (int32_t i = MOTION_BONE_CL_KAO; i <= MOTION_BONE_N_KUBI_WJ_EX; i++) + bone_data_mult_1(&v7[i], mat, v7, true); + + v7[MOTION_BONE_CL_KAO].rot_mat[1] = v60; +} + +static void sub_1404189A0(rob_chara_bone_data* rob_bone_data) { + motion_blend_mot* v2 = rob_bone_data->motion_loaded.front(); + sub_140407280(&rob_bone_data->field_788, &v2->bone_data.bones, + &v2->field_4F8.mat, v2->mot_play_data.frame_data.step); +} + +static void sub_140406FC0(struc_258* a1, bone_data* a2, mat4* a3, + vec3* a4, vec3* a5, vec3* a6, bool a7, float_t a8, float_t a9) { + float_t v14; + float_t v17; + + a4->z = fabsf(a4->z); + + float_t v15 = sqrt(a4->x * a4->x + a4->z * a4->z); + if (fabsf(v15) <= 0.000001f) { + v14 = 0.0; + if (a4->y <= 0.0f) + v17 = a6->x; + else + v17 = a5->x; + } + else { + v14 = atan2f(a4->x, a4->z); + v17 = atanf(-a4->y / v15); + + if (v17 > 0.0f) + v17 *= a1->field_1BC.y; + else if (v17 < 0.0f) + v17 *= a1->field_1BC.x; + + if (v17 < a5->x) + v17 = a5->x; + else if (v17 > a6->x) + v17 = a6->x; + + if (v14 < a5->y) + v14 = a5->y; + else if (v14 > a6->y) + v14 = a6->y; + } + + if (!a1->field_14C || fabsf(a1->field_150) <= 0.000001f) { + if (fabsf(a1->field_158) > 0.000001f) { + if (a1->field_158 < 0.0f) + v17 = a5->x; + else + v17 = a6->x; + } + else { + if (v17 < 0.0f) + v17 = a6->x; + else + v17 = a5->x; + } + + if (fabsf(a1->field_154) > 0.000001f) { + if (a1->field_154 < 0.0f) + v14 = a5->y; + else + v14 = a6->y; + } + else { + if (v14 < 0.0f) + v14 = a6->y; + else + v14 = a5->y; + } + } + + mat4 mat = mat4_identity; + mat4_rotate_y_mult(&mat, v14, &mat); + mat4_rotate_x_mult(&mat, v17, &mat); + + mat4 v25; + mat4_lerp_rotation(&v25, &mat, &mat, a1->field_98); + + mat4* v22; + if (a7) + v22 = a2->rot_mat; + else { + a8 = a9; + v22 = a3; + } + + mat4_lerp_rotation(v22, &mat, &mat, a8); + + *a3 = mat; + a2->rot_mat[0] = mat; +} + +static void sub_140409170(struc_258* a1, mat4* a2, std::vector* a3, mat4* a4, float_t step) { + if (a1->field_91) + return; + + a1->field_0 = a3; + a1->field_8 = *a4; + + bool a7 = false; + float_t v11 = 0.0f; + if (a1->field_A0 > 0.0f && a1->field_A0 > a1->field_A4 && fabsf(a1->field_A0 - a1->field_A4) > 0.000001f) { + a7 = true; + v11 = (a1->field_A4 + 1.0f) / (a1->field_A0 + 1.0f); + if (!a1->field_90) + v11 = 1.0f - v11; + a1->field_A4 += step; + } + + float_t v15 = a1->field_9C * step; + if (fabsf(a1->field_9C - 1.0f) <= 0.000001f || v15 > 1.0f || a1->field_8F && !a7 + || rctx_ptr->camera->fast_change_hist0 && rctx_ptr->camera->fast_change_hist1) + v15 = 1.0f; + + a1->field_8D = false; + a1->field_8F = false; + if (!(a1->field_90 || a1->field_14C && fabsf(a1->field_150) > 0.000001f || a7) + || !(a1->field_94 <= 0.0f || a1->field_1C8 != 3)) + return; + + a1->field_C0 = a1->field_B4; + + mat4 mat; + mat4_inverse(a2, &mat); + mat4_mult_vec3_trans(&mat, &a1->field_C0, &a1->field_C0); + + float_t v29 = a1->field_48.field_8; + float_t v31 = a1->field_48.field_C; + float_t v32 = -a1->field_48.field_8; + if (a1->field_1C4 != 0) { + v29 = a1->field_48.field_18; + v31 = a1->field_48.field_1C; + v32 = -a1->field_48.field_18; + } + + std::vector* v19 = a1->field_0; + if (a1->field_B0 > 0.0f) { + mat4* mat = v19->data()[MOTION_BONE_KL_EYE_L].parent_mat; + + vec3 v52; + vec3 v54; + mat4_get_translation(v19->data()[MOTION_BONE_KL_EYE_L].parent_mat, &v52); + mat4_get_translation(v19->data()[MOTION_BONE_KL_EYE_R].parent_mat, &v54); + + vec3_add(v52, v54, v52); + vec3_mult_scalar(v52, 0.5f, v54); + mat4_set_translation(mat, &v54); + + vec3 v53; + mat4_mult_vec3_inv_trans(mat, &a1->field_C0, &v53); + + float_t v37; + vec3_length(v53, v37); + if (fabsf(v37) <= 0.000001f || v53.x * v53.x + v53.z * v53.z <= 0.01f) { + v29 = 0.0f; + v32 = 0.0f; + } + else if (v37 < a1->field_B0) { + v53.z = fabsf(v53.z); + + vec3_mult_scalar(v53, a1->field_B0 / v37, v53); + mat4_mult_vec3_trans(mat, &v53, &v53); + + vec3 v56; + mat4_mult_vec3_inv_trans(v19->data()[MOTION_BONE_KL_EYE_L].parent_mat, &v53, &v56); + float_t v40 = atan2f(v56.x - a1->field_48.field_20.x, v56.z); + if (v29 < v40) + if (v31 > v40) + v29 = v40; + else + v29 = v31; + + vec3 v57; + mat4_mult_vec3_inv_trans(v19->data()[MOTION_BONE_KL_EYE_R].parent_mat, &v53, &v57); + float_t v41 = atan2f(v57.x + a1->field_48.field_20.x, v57.z); + if (v32 > v41) + if (-v31 < v41) + v32 = v41; + else + v32 = -v31; + } + } + + float_t v42; + float_t v43; + if (a1->field_1C4) { + v42 = a1->field_48.field_10 * -3.8f / a1->field_48.field_34 * a1->field_1BC.x; + v43 = a1->field_48.field_14 * 6.0f / a1->field_48.field_38 * a1->field_1BC.y; + } + else { + v42 = a1->field_1BC.x * a1->field_48.field_0; + v43 = a1->field_1BC.y * a1->field_48.field_4; + } + + vec3 v58; + mat4_mult_vec3_inv_trans(v19->data()[MOTION_BONE_KL_EYE_L].parent_mat, &a1->field_C0, &v58); + vec3_sub(v58, a1->field_48.field_20, v58); + + vec3 v56; + v56.x = v43; + v56.y = v31; + v56.z = 0.0f; + + vec3 v55; + v55.x = v42; + v55.y = v29; + v55.z = 0.0f; + + sub_140406FC0(a1, &v19->data()[MOTION_BONE_KL_EYE_L], &a1->field_CC, &v58, &v55, &v56, a7, v11, v15); + + v55.y = -v31; + v56.y = v32; + + vec3 v59; + mat4_mult_vec3_inv_trans(v19->data()[MOTION_BONE_KL_EYE_R].parent_mat, &a1->field_C0, &v59); + vec3 v60 = a1->field_48.field_20; + v60.x = -v60.x; + vec3_sub(v59, v60, v59); + + sub_140406FC0(a1, &v19->data()[MOTION_BONE_KL_EYE_R], &a1->field_10C, &v59, &v55, &v56, a7, v11, v15); + + bone_data* v47 = a3->data(); + for (int32_t i = MOTION_BONE_KL_EYE_L; i <= MOTION_BONE_KL_HIGHLIGHT_L_WJ; i++) + bone_data_mult_1(&v47[i], a4, v47, true); + + for (int32_t i = MOTION_BONE_KL_EYE_R; i <= MOTION_BONE_KL_HIGHLIGHT_R_WJ; i++) + bone_data_mult_1(&v47[i], a4, v47, true); +} + +static void sub_14041A160(rob_chara_bone_data* rob_bone_data, mat4* a2) { + motion_blend_mot* v2 = rob_bone_data->motion_loaded.front(); + sub_140409170(&rob_bone_data->field_788, a2, &v2->bone_data.bones, + &v2->field_4F8.mat, v2->mot_play_data.frame_data.step); } static void sub_14053BEE0(rob_chara* rob_chr) { if (rob_chr->type != ROB_CHARA_TYPE_2) return; - bool v4 = true; - if (rob_chr->data.field_2 & 0x80) - v4 = false; + bool v4 = !(rob_chr->data.field_2 & 0x80); rob_chr->data.field_2 &= ~0x80; rob_chara_bone_data* rob_bone_data = rob_chr->bone_data; @@ -8010,8 +8508,8 @@ static bool sub_14040AC40(vec3* a1, vec3* a2, float_t a3, vec3* a4) { return true; } -static void sub_1403FA040(vec3* a1, float_t a2, mat4* a3, float_t a4, - float_t a5, float_t a6, float_t a7, vec3* a8, float_t a9) { +static void sub_1403FA040(vec3* a1, float_t a2, mat4* a3, float_t ymin, + float_t ymax, float_t zmin, float_t zmax, vec3* a8, float_t step) { vec3 v16; vec3 v52; vec3 v53; @@ -8026,37 +8524,37 @@ static void sub_1403FA040(vec3* a1, float_t a2, mat4* a3, float_t a4, vec3_normalize(v16, v16); float_t v23; - if (a7 - a6 >= a5 - a4) { - v23 = (a5 - a4) * 0.5f; + if (zmax - zmin >= ymax - ymin) { + v23 = (ymax - ymin) * 0.5f; v53.x = 0.0f; - v53.y = a5 - v23; - v53.z = a6 + v23; + v53.y = ymax - v23; + v53.z = zmin + v23; v52.x = 0.0f; - v52.y = a5 - v23; - v52.z = a7 - v23; + v52.y = ymax - v23; + v52.z = zmax - v23; if (fabsf(v16.y) <= 0.000001f) { - if (fabsf(a4) <= 0.000001f || fabsf(a5) <= 0.000001f) { + if (fabsf(ymin) <= 0.000001f || fabsf(ymax) <= 0.000001f) { vec3_mult_scalar(v16, a2, v16); - if (v16.z < a6 + v23) { - v16.z = a6 + v23; + if (v16.z < zmin + v23) { + v16.z = zmin + v23; goto LABEL_66; } - else if (v16.z > a7 - v23) { - v16.z = a7 - v23; + else if (v16.z > zmax - v23) { + v16.z = zmax - v23; goto LABEL_66; } goto LABEL_60; } } - else if ((fabsf(a4) > 0.000001f || v16.y >= 0.0f) && (fabsf(a5) > 0.000001f || v16.y <= 0.0f)) { - float_t v22 = a5; - if (v16.y * a5 <= 0.0f) - v22 = a4; + else if ((fabsf(ymin) > 0.000001f || v16.y >= 0.0f) && (fabsf(ymax) > 0.000001f || v16.y <= 0.0f)) { + float_t v22 = ymax; + if (v16.y * ymax <= 0.0f) + v22 = ymin; float_t v31 = v22 * v16.z / v16.y; - if (v31 >= a6 + v23 && v31 <= a7 - v23) { + if (v31 >= zmin + v23 && v31 <= zmax - v23) { float_t v32 = sqrtf(v31 * v31 + v22 * v22); bool v17 = true; if (a2 < v32) { @@ -8073,42 +8571,42 @@ static void sub_1403FA040(vec3* a1, float_t a2, mat4* a3, float_t a4, if (fabsf(v16.z) > 0.000001f) { vec3_normalize(v16, v16); vec3_mult_scalar(v16, a2, v16); - v16.z = clamp(v16.z, a6, a7); + v16.z = clamp(v16.z, zmin, zmax); } goto LABEL_66; } } else { - v23 = (a7 - a6) * 0.5f; + v23 = (zmax - zmin) * 0.5f; v53.x = 0.0f; - v53.y = a5 - v23; - v53.z = a7 - v23; + v53.y = ymax - v23; + v53.z = zmax - v23; v52.x = 0.0f; v52.y = 0.0f; - v52.z = a7 - v23; + v52.z = zmax - v23; if (fabsf(v16.z) <= 0.000001f) { - if (fabsf(a6) <= 0.000001f || fabsf(a7) <= 0.000001f) { + if (fabsf(zmin) <= 0.000001f || fabsf(zmax) <= 0.000001f) { vec3_mult_scalar(v16, a2, v16); - if (v16.y < a4 + v23) { - v16.y = a4 + v23; + if (v16.y < ymin + v23) { + v16.y = ymin + v23; goto LABEL_66; } - else if (v16.y > a5 - v23) { - v16.y = a5 - v23; + else if (v16.y > ymax - v23) { + v16.y = ymax - v23; goto LABEL_66; } goto LABEL_60; } } - else if ((fabsf(a6) > 0.000001f || v16.z >= 0.0f) && (fabsf(a7) > 0.000001f || v16.z <= 0.0f)) { - float_t v22 = a7; - if (v16.z * a7 <= 0.0f) - v22 = a6; + else if ((fabsf(zmin) > 0.000001f || v16.z >= 0.0f) && (fabsf(zmax) > 0.000001f || v16.z <= 0.0f)) { + float_t v22 = zmax; + if (v16.z * zmax <= 0.0f) + v22 = zmin; float_t v31 = v22 * v16.y / v16.z; - if (v31 >= a4 + v23 && v31 <= a5 - v23) { + if (v31 >= ymin + v23 && v31 <= ymax - v23) { float_t v32 = sqrtf(v31 * v31 + v22 * v22); bool v17 = true; if (a2 < v32) { @@ -8125,7 +8623,7 @@ static void sub_1403FA040(vec3* a1, float_t a2, mat4* a3, float_t a4, if (fabsf(v16.y) > 0.000001f) { vec3_normalize(v16, v16); vec3_mult_scalar(v16, a2, v16); - v16.y = clamp(v16.y, a4, a5); + v16.y = clamp(v16.y, ymin, ymax); } goto LABEL_66; } @@ -8157,7 +8655,7 @@ LABEL_60: if (v20 != 0.0f) { float_t v43; vec3_length(*a8, v43); - float_t v44 = v43 + (v43 * 0.97f - v43) * a9; + float_t v44 = v43 + (v43 * 0.97f - v43) * step; float_t v45; vec3_length(v16, v45); @@ -8174,7 +8672,7 @@ LABEL_66: *a8 = v16; } -static void sub_1403FA770(struc_312* a1) { +static void sub_1403FA770(rob_chara_bone_data_sleeve_adjust* a1) { mat4* v4 = a1->bones->data()[MOTION_BONE_C_KATA_L].node[3].mat; mat4* v5 = a1->bones->data()[MOTION_BONE_C_KATA_R].node[3].mat; @@ -8184,9 +8682,9 @@ static void sub_1403FA770(struc_312* a1) { mat4_get_translation(v5, &v43); vec3 v41; - sub_1403F9A40(&v41, &v42, v4, a1->field_0.field_4, a1->field_0.field_8); + sub_1403F9A40(&v41, &v42, v4, a1->sleeve_l.cyofs, a1->sleeve_l.czofs); vec3 v40; - sub_1403F9A40(&v40, &v43, v5, a1->field_2C.field_4, a1->field_2C.field_8); + sub_1403F9A40(&v40, &v43, v5, a1->sleeve_r.cyofs, a1->sleeve_r.czofs); vec3 v45; vec3_sub(v41, v40, v45); @@ -8197,8 +8695,8 @@ static void sub_1403FA770(struc_312* a1) { float_t v20; vec3_distance(v41, v40, v20); - float_t v21 = (a1->field_0.field_0 * a1->field_8C + a1->field_2C.field_0 - v20) * 0.5f; - float_t v22 = (a1->field_2C.field_0 * a1->field_8C + a1->field_0.field_0 - v20) * 0.5f; + float_t v21 = (a1->sleeve_l.radius * a1->radius + a1->sleeve_r.radius - v20) * 0.5f; + float_t v22 = (a1->sleeve_r.radius * a1->radius + a1->sleeve_l.radius - v20) * 0.5f; bool v16 = true; bool v17 = false; @@ -8235,12 +8733,12 @@ static void sub_1403FA770(struc_312* a1) { } if (v16) - sub_1403FA040(&v45, v21, v4, a1->field_0.field_C, a1->field_0.field_10, - a1->field_0.field_14, a1->field_0.field_18, &a1->field_5C, a1->step); + sub_1403FA040(&v45, v21, v4, a1->sleeve_l.ymin, a1->sleeve_l.ymax, + a1->sleeve_l.zmin, a1->sleeve_l.zmax, &a1->field_5C, a1->step); if (v19) - sub_1403FA040(&v44, v22, v5, a1->field_2C.field_C, a1->field_2C.field_10, - a1->field_2C.field_14, a1->field_2C.field_18, &a1->field_68, a1->step); + sub_1403FA040(&v44, v22, v5, a1->sleeve_r.ymin, a1->sleeve_r.ymax, + a1->sleeve_r.zmin, a1->sleeve_r.zmax, &a1->field_68, a1->step); if (v16 || v17) { vec3_add(v42, v45, v42); @@ -8253,39 +8751,43 @@ static void sub_1403FA770(struc_312* a1) { } } -static void sub_1403F9B20(struc_312* a1, motion_bone_index motion_bone_index) { - float_t v3; - float_t v4; - float_t a5; +static void sub_1403F9B20(rob_chara_bone_data_sleeve_adjust* a1, motion_bone_index motion_bone_index) { + float_t sleeve_radius; + float_t sleeve_cyofs; + float_t sleeve_czofs; vec3* v6; - float_t v7; - float_t v8; - float_t v9; - float_t v10; - vec3 v11; - float_t v14; + float_t sleeve_ymin; + float_t sleeve_ymax; + float_t sleeve_zmin; + float_t sleeve_zmax; + vec3 sleeve_mune_ofs; + float_t sleeve_mune_rad; if (motion_bone_index == MOTION_BONE_C_KATA_L) { - v3 = a1->field_0.field_0; - v4 = a1->field_0.field_4; - a5 = a1->field_0.field_8; - v7 = a1->field_0.field_C; - v8 = a1->field_0.field_10; - v9 = a1->field_0.field_14; - v10 = a1->field_0.field_18; - v11 = a1->field_0.field_1C; - v14 = a1->field_0.field_28; + sleeve_radius = a1->sleeve_l.radius; + sleeve_cyofs = a1->sleeve_l.cyofs; + sleeve_czofs = a1->sleeve_l.czofs; + sleeve_ymin = a1->sleeve_l.ymin; + sleeve_ymax = a1->sleeve_l.ymax; + sleeve_zmin = a1->sleeve_l.zmin; + sleeve_zmax = a1->sleeve_l.zmax; + sleeve_mune_ofs.x = a1->sleeve_l.mune_xofs; + sleeve_mune_ofs.x = a1->sleeve_l.mune_yofs; + sleeve_mune_ofs.x = a1->sleeve_l.mune_zofs; + sleeve_mune_rad = a1->sleeve_l.mune_rad; v6 = &a1->field_74; } else if (motion_bone_index == MOTION_BONE_C_KATA_R) { - v3 = a1->field_2C.field_0; - v4 = a1->field_2C.field_4; - a5 = a1->field_2C.field_8; - v7 = a1->field_2C.field_C; - v8 = a1->field_2C.field_10; - v9 = a1->field_2C.field_14; - v10 = a1->field_2C.field_18; - v11 = a1->field_2C.field_1C; - v14 = a1->field_2C.field_28; + sleeve_radius = a1->sleeve_r.radius; + sleeve_cyofs = a1->sleeve_r.cyofs; + sleeve_czofs = a1->sleeve_r.czofs; + sleeve_ymin = a1->sleeve_r.ymin; + sleeve_ymax = a1->sleeve_r.ymax; + sleeve_zmin = a1->sleeve_r.zmin; + sleeve_zmax = a1->sleeve_r.zmax; + sleeve_mune_ofs.x = a1->sleeve_r.mune_xofs; + sleeve_mune_ofs.z = a1->sleeve_r.mune_yofs; + sleeve_mune_ofs.z = a1->sleeve_r.mune_zofs; + sleeve_mune_rad = a1->sleeve_r.mune_rad; v6 = &a1->field_80; } else @@ -8299,20 +8801,20 @@ static void sub_1403F9B20(struc_312* a1, motion_bone_index motion_bone_index) { mat4_get_translation(v19, &v39); vec3 v37; - sub_1403F9A40(&v37, &v39, v19, v4, a5); + sub_1403F9A40(&v37, &v39, v19, sleeve_cyofs, sleeve_czofs); vec3 v40; mat4* v23 = v15[MOTION_BONE_KL_MUNE_B_WJ].node->mat; - mat4_mult_vec3_trans(v23, &v11, &v40); + mat4_mult_vec3_trans(v23, &sleeve_mune_ofs, &v40); vec3 v41; vec3_sub(v37, v40, v41); float_t v24; vec3_length(v41, v24); - float_t v26 = v3 * a1->field_8C + v14 - v24; + float_t v26 = sleeve_radius * a1->radius + sleeve_mune_rad - v24; if (v26 > 0.0f) - sub_1403FA040(&v41, v26, v19, v7, v8, v9, v10, v6, a1->step); + sub_1403FA040(&v41, v26, v19, sleeve_ymin, sleeve_ymax, sleeve_zmin, sleeve_zmax, v6, a1->step); else { float_t v31; vec3_length(*v6, v31); @@ -8330,13 +8832,13 @@ static void sub_1403F9B20(struc_312* a1, motion_bone_index motion_bone_index) { sub_14040AE10(v42, &v39); } -static void sub_1403FAF30(struc_312* a1, std::vector* bones, float_t step) { +static void sub_1403FAF30(rob_chara_bone_data_sleeve_adjust* a1, std::vector* bones, float_t step) { a1->step = step; a1->bones = bones; - if (a1->field_58) + if (a1->enable1) sub_1403FA770(a1); - if (a1->field_59) { + if (a1->enable2) { sub_1403F9B20(a1, MOTION_BONE_C_KATA_L); sub_1403F9B20(a1, MOTION_BONE_C_KATA_R); } @@ -8344,7 +8846,7 @@ static void sub_1403FAF30(struc_312* a1, std::vector* bones, float_t static void sub_14041AB50(rob_chara_bone_data* rob_bone_data) { motion_blend_mot* v2 = rob_bone_data->motion_loaded.front(); - sub_1403FAF30(&rob_bone_data->field_958, &v2->bone_data.bones, v2->mot_play_data.frame_data.step); + sub_1403FAF30(&rob_bone_data->sleeve_adjust, &v2->bone_data.bones, v2->mot_play_data.frame_data.step); } static bool rob_chara_hands_adjust(rob_chara* rob_chr) { @@ -8370,7 +8872,7 @@ static float_t sub_140406E90(bone_data* a1, bone_data* a2, float_t a3, vec3* a4) vec3 v17; v17.x = 0.01f; v17.y = -0.05f; - v17.z = 0.0; + v17.z = 0.0f; mat4_mult_vec3_trans(a2->node[0].mat, &v18, &v17); if (v18.y - a3 <= v17.y) @@ -8700,13 +9202,13 @@ static void mot_key_data_reserve_key_sets_by_skeleton_type(mot_key_data* a1, } static void mot_blend_reserve_key_sets(mot_blend* blend, bone_database_skeleton_type type, - bool(*bone_check_func)(motion_bone_index), size_t motion_bone_count, bone_database* bone_data) { + PFNMOTIONBONECHECKFUNC bone_check_func, size_t motion_bone_count, bone_database* bone_data) { mot_key_data_reserve_key_sets_by_skeleton_type(&blend->mot_key_data, type, bone_data); sub_140413350(&blend->field_0, bone_check_func, motion_bone_count); } static bool motion_blend_mot_check(motion_bone_index bone_index) { - return 1; + return true; } static bool mot_blend_face_check(motion_bone_index bone_index) { @@ -9201,7 +9703,7 @@ static void rob_chara_bone_data_motion_load(rob_chara_bone_data* rob_bone_data, static void sub_1404198D0(struc_258* a1) { a1->field_0 = 0; - a1->field_8 = mat4u_identity; + a1->field_8 = mat4_identity; a1->field_48.field_0 = 0.0f; a1->field_48.field_4 = 0.0f; a1->field_48.field_8 = 0.0f; @@ -9210,9 +9712,7 @@ static void sub_1404198D0(struc_258* a1) { a1->field_48.field_14 = 0.0f; a1->field_48.field_18 = 0.0f; a1->field_48.field_1C = 0.0f; - a1->field_48.field_20 = 0.0f; - a1->field_48.field_24 = 0.0f; - a1->field_48.field_28 = 0.0f; + a1->field_48.field_20 = vec3_null; a1->field_48.field_2C = 1.0f; a1->field_48.field_30 = 1.0f; a1->field_48.field_34 = -3.8f; @@ -9235,8 +9735,8 @@ static void sub_1404198D0(struc_258* a1) { a1->field_B0 = 0.0f; a1->field_B4 = vec3_null; a1->field_C0 = vec3_null; - a1->field_CC = mat4u_identity; - a1->field_10C = mat4u_identity; + a1->field_CC = mat4_identity; + a1->field_10C = mat4_identity; a1->field_14C = 0; a1->field_150 = 0.0f; a1->field_154 = 0.0f; @@ -9251,9 +9751,7 @@ static void sub_1404198D0(struc_258* a1) { a1->field_15C.field_1C = 0; a1->field_15C.field_20 = 0.0f; a1->field_15C.field_24 = 0.0f; - a1->field_184 = 0.0f; - a1->field_188 = 0.0f; - a1->field_18C = 0.0f; + a1->field_184 = vec3_null; a1->field_190 = false; a1->field_191 = false; a1->field_192 = false; @@ -9274,36 +9772,6 @@ static void sub_1404198D0(struc_258* a1) { a1->field_1C8 = 0; } -static void sub_1403FAEF0(struc_312* a1) { - a1->field_0.field_0 = 0.0f; - a1->field_0.field_4 = 0.0f; - a1->field_0.field_8 = 0.0f; - a1->field_0.field_C = 0.0f; - a1->field_0.field_10 = 0.0f; - a1->field_0.field_14 = 0.0f; - a1->field_0.field_18 = 0.0f; - a1->field_0.field_1C = vec3_null; - a1->field_0.field_28 = 0.0f; - a1->field_2C.field_0 = 0.0f; - a1->field_2C.field_4 = 0.0f; - a1->field_2C.field_8 = 0.0f; - a1->field_2C.field_C = 0.0f; - a1->field_2C.field_10 = 0.0f; - a1->field_2C.field_14 = 0.0f; - a1->field_2C.field_18 = 0.0f; - a1->field_2C.field_1C = vec3_null; - a1->field_2C.field_28 = 0.0f; - a1->field_58 = false; - a1->field_59 = false; - a1->field_8C = 1.0f; - a1->bones = 0; - a1->step = 1.0f; - a1->field_5C = vec3_null; - a1->field_68 = vec3_null; - a1->field_74 = vec3_null; - a1->field_80 = vec3_null; -} - static void rob_chara_bone_data_set_eyelid_anim_duration(rob_chara_bone_data* rob_bone_data, float_t duration, float_t step, float_t offset) { mot_blend_set_duration(&rob_bone_data->eyelid, duration, step, offset); @@ -9506,7 +9974,7 @@ static void rob_chara_bone_data_set_rot_y(rob_chara_bone_data* rob_bone_data, fl static void sub_140413EB0(struc_308* a1) { a1->field_8C = false; a1->field_4C = a1->mat; - a1->mat = mat4u_identity; + a1->mat = mat4_identity; } static void sub_1404117F0(motion_blend_mot* a1) { @@ -9531,9 +9999,9 @@ static void sub_14040FBF0(motion_blend_mot* a1, float_t a2) { mat = b_kl_hara_etc->rot_mat[0]; mat4_mult(&mat, &rot_mat, &rot_mat); b_n_hara_cp->rot_mat[0] = rot_mat; - b_kg_hara_y->rot_mat[0] = mat4u_identity; - b_kl_hara_xz->rot_mat[0] = mat4u_identity; - b_kl_hara_etc->rot_mat[0] = mat4u_identity; + b_kg_hara_y->rot_mat[0] = mat4_identity; + b_kl_hara_xz->rot_mat[0] = mat4_identity; + b_kl_hara_etc->rot_mat[0] = mat4_identity; float_t v8 = a1->field_4F8.field_C0; float_t v9 = a1->field_4F8.field_C4; @@ -9974,11 +10442,11 @@ static void sub_140505FB0(struc_209* a1) { a1->field_70 = 0; a1->field_74 = 0; - for (mat4u& i : a1->field_78) - i = mat4u_identity; + for (mat4& i : a1->field_78) + i = mat4_identity; - for (mat4u& i : a1->field_738) - i = mat4u_identity; + for (mat4& i : a1->field_738) + i = mat4_identity; for (struc_195& i : a1->field_DF8) i = {}; @@ -10098,10 +10566,10 @@ static void sub_140505FB0(struc_209* a1) { a1->field_1F26 = 0; } -static bool rob_chara_item_cos_data_check_for_npr_flag(rob_chara_item_cos_data* itm_cos_data) { - int32_t* arr = itm_cos_data->cos.arr; +static bool rob_chara_item_cos_data_check_for_npr_flag(rob_chara_item_cos_data* item_cos_data) { + int32_t* arr = item_cos_data->cos.arr; for (int32_t i = ITEM_SUB_ZUJO; i < ITEM_SUB_MAX; i++) { - item_table_item* item = item_table_array_get_item(itm_cos_data->chara_index, *arr++); + item_table_item* item = item_table_array_get_item(item_cos_data->chara_index, *arr++); if (item && item->npr_flag) return true; } @@ -10274,7 +10742,7 @@ static void sub_140522A30(rob_chara_item_cos_data* item_cos_data, rob_chara_item bone_database* bone_data, void* data, object_database* obj_db) { const chara_init_data* chr_init_data = chara_init_data_get(item_cos_data->chara_index); for (int32_t i = ITEM_ATAMA; i < ITEM_KAMI; i++) { - sub_140513950(rob_itm_equip, (item_id)i, chr_init_data->field_7E0[i], false, bone_data, data, obj_db); + sub_140513950(rob_itm_equip, (item_id)i, chr_init_data->field_7E4[i - 1], false, bone_data, data, obj_db); auto elem = item_cos_data->item_change.find(i); if (elem == item_cos_data->item_change.end()) sub_14052B4C0(item_cos_data, rob_itm_equip, (item_id)i, false); @@ -10657,17 +11125,17 @@ static void sub_1405234E0(rob_chara_item_cos_data* item_cos_data) { item_cos_data->field_100.clear(); } -static void rob_chara_item_cos_data_reload_items(rob_chara_item_cos_data* itm_cos_data, +static void rob_chara_item_cos_data_reload_items(rob_chara_item_cos_data* item_cos_data, int32_t chara_id, bone_database* bone_data, void* data, object_database* obj_db) { rob_chara_item_equip* rob_itm_equip = rob_chara_array_get_item_equip(chara_id); - sub_140522990(itm_cos_data); - sub_140522A30(itm_cos_data, rob_itm_equip, bone_data, data, obj_db); - sub_140522C60(itm_cos_data, rob_itm_equip, bone_data, data, obj_db); - sub_140522D00(itm_cos_data, rob_itm_equip, bone_data, data, obj_db); - sub_140522D90(itm_cos_data, rob_itm_equip, bone_data, data, obj_db); - sub_140522F90(itm_cos_data, rob_itm_equip); - sub_1405231D0(itm_cos_data, rob_itm_equip); - sub_1405234E0(itm_cos_data); + sub_140522990(item_cos_data); + sub_140522A30(item_cos_data, rob_itm_equip, bone_data, data, obj_db); + sub_140522C60(item_cos_data, rob_itm_equip, bone_data, data, obj_db); + sub_140522D00(item_cos_data, rob_itm_equip, bone_data, data, obj_db); + sub_140522D90(item_cos_data, rob_itm_equip, bone_data, data, obj_db); + sub_140522F90(item_cos_data, rob_itm_equip); + sub_1405231D0(item_cos_data, rob_itm_equip); + sub_1405234E0(item_cos_data); } static void rob_chara_item_cos_data_set_chara_index( @@ -10707,6 +11175,12 @@ static void rob_chara_item_cos_data_set_item_nos( rob_chara_item_cos_data_set_item_no(item_cos_data, (item_sub_id)i, item_nos[i]); } +static void rob_chara_item_cos_data_set_item_zero(rob_chara_item_cos_data* item_cos_data, int32_t item_no) { + item_table_item* item = item_table_array_get_item(item_cos_data->chara_index, item_no); + if (item) + item_cos_data->cos.arr[item->sub_id] = 0; +} + static void rob_chara_item_cos_data_texture_change_clear(rob_chara_item_cos_data* item_cos_data) { for (auto i : item_cos_data->texture_change) for (item_cos_texture_change_tex& j : i.second) @@ -10819,10 +11293,10 @@ static void sub_140512C20(rob_chara_item_equip* rob_itm_equip, render_context* r glPopMatrix(); } -static void rob_chara_item_equip_add_motion_reset_data(rob_chara_item_equip* rob_item_equip, +static void rob_chara_item_equip_add_motion_reset_data(rob_chara_item_equip* rob_itm_equip, int32_t motion_id, float_t frame, int32_t iterations) { - for (int32_t i = rob_item_equip->first_item_equip_object; i < rob_item_equip->max_item_equip_object; i++) - rob_item_equip->item_equip_object[i].add_motion_reset_data(motion_id, frame, iterations); + for (int32_t i = rob_itm_equip->first_item_equip_object; i < rob_itm_equip->max_item_equip_object; i++) + rob_itm_equip->item_equip_object[i].add_motion_reset_data(motion_id, frame, iterations); } static void rob_chara_item_equip_disp( @@ -10859,10 +11333,10 @@ static void rob_chara_item_equip_disp( object_data->set_chara_color(rob_itm_equip->chara_color); vec4 v23; - object_data->get_texture_color_coeff(&v23); + object_data->get_texture_color_coeff(v23); - vec4 texture_color_coeff = rob_itm_equip->texture_color_coeff; - object_data->set_texture_color_coeff(&texture_color_coeff); + vec4& texture_color_coeff = rob_itm_equip->texture_color_coeff; + object_data->set_texture_color_coeff(texture_color_coeff); object_data->set_wet_param(rob_itm_equip->wet); //rctx->draw_pass.field_31C |= rob_itm_equip->field_F9; sub_140512C20(rob_itm_equip, rctx); @@ -10894,7 +11368,7 @@ static void rob_chara_item_equip_disp( rob_itm_equip->item_equip_object[i].disp(&mat, rctx); } } - object_data->set_texture_color_coeff(&v23); + object_data->set_texture_color_coeff(v23); object_data->set_wet_param(); object_data->set_chara_color(); object_data->set_draw_task_flags(); @@ -10933,16 +11407,16 @@ static bool sub_14053E690(RobOsageNodeDataNormalRef* normal_ref) { if (normal_ref->n == 0) return normal_ref->field_0; - if (normal_ref->u && !memcmp(&normal_ref->u->mat, &mat4u_null, sizeof(mat4u))) + if (normal_ref->u && !memcmp(&normal_ref->u->mat, &mat4_null, sizeof(mat4))) normal_ref->u = 0; - if (normal_ref->d && !memcmp(&normal_ref->d->mat, &mat4u_null, sizeof(mat4u))) + if (normal_ref->d && !memcmp(&normal_ref->d->mat, &mat4_null, sizeof(mat4))) normal_ref->d = 0; - if (normal_ref->l && !memcmp(&normal_ref->l->mat, &mat4u_null, sizeof(mat4u))) + if (normal_ref->l && !memcmp(&normal_ref->l->mat, &mat4_null, sizeof(mat4))) normal_ref->l = 0; - if (normal_ref->r && !memcmp(&normal_ref->r->mat, &mat4u_null, sizeof(mat4u))) + if (normal_ref->r && !memcmp(&normal_ref->r->mat, &mat4_null, sizeof(mat4))) normal_ref->r = 0; if ((normal_ref->u || normal_ref->d) && (normal_ref->l || normal_ref->r)) { @@ -10965,12 +11439,12 @@ static void rob_chara_item_equip_reset_init_data(rob_chara_item_equip* rob_itm_e rob_itm_equip->bone_nodes = bone_nodes; rob_itm_equip->matrices = bone_nodes->mat; - mat4u* v7 = rob_itm_equip->field_13C; + mat4* v7 = rob_itm_equip->field_13C; int32_t* v8 = rob_itm_equip->field_18; for (int32_t v6 = ITEM_BODY; v6 < ITEM_MAX; v6++) { rob_itm_equip->item_equip_object[v6].init_members(v6); *v8++ = 0; - *v7++ = mat4u_identity; + *v7++ = mat4_identity; } rob_itm_equip->step = 1.0f; @@ -10978,7 +11452,7 @@ static void rob_chara_item_equip_reset_init_data(rob_chara_item_equip* rob_itm_e rob_itm_equip->wind_strength = 1.0f; rob_itm_equip->chara_color = true; rob_itm_equip->npr_flag = false; - rob_itm_equip->mat = mat4u_identity; + rob_itm_equip->mat = mat4_identity; } static void rob_chara_item_equip_set_alpha_draw_task_flags( @@ -11575,8 +12049,8 @@ void MotionBlend::SetDuration(float_t duration, float_t step, float_t offset) { } MotionBlendCross::MotionBlendCross() : field_20(), field_21(), -rot_y_mat(mat4u_identity), field_64(mat4u_identity), -field_A4(mat4u_identity), field_E4(mat4u_identity) { +rot_y_mat(mat4_identity), field_64(mat4_identity), +field_A4(mat4_identity), field_E4(mat4_identity) { } @@ -11588,10 +12062,10 @@ void MotionBlendCross::Reset() { MotionBlend::Reset(); field_20 = false; field_21 = false; - rot_y_mat = mat4u_identity; - field_64 = mat4u_identity; - field_A4 = mat4u_identity; - field_E4 = mat4u_identity; + rot_y_mat = mat4_identity; + field_64 = mat4_identity; + field_A4 = mat4_identity; + field_E4 = mat4_identity; } void MotionBlendCross::Field_10(float_t a2, float_t a3, int32_t a4) { @@ -11617,7 +12091,7 @@ void MotionBlendCross::Step(struc_400* a2) { rot_y_mat = mat; } else - rot_y_mat = mat4u_identity; + rot_y_mat = mat4_identity; } void MotionBlendCross::Field_20(std::vector* a2, std::vector* a3) { @@ -11640,8 +12114,8 @@ void MotionBlendCross::Blend(bone_data* a2, bone_data* a3) { if (!a2 || !a3 || a2->disable_mot_anim) return; - mat4u v15; - mat4u v16; + mat4 v15; + mat4 v16; switch (a2->type) { case BONE_DATABASE_BONE_TYPE_1: @@ -11712,7 +12186,7 @@ void MotionBlendCombine::Step(struc_400* a2) { rot_y_mat = mat; } else - rot_y_mat = mat4u_identity; + rot_y_mat = mat4_identity; } bool MotionBlendCombine::Field_30() { @@ -11720,8 +12194,8 @@ bool MotionBlendCombine::Field_30() { } MotionBlendFreeze::MotionBlendFreeze() : field_20(),field_21(), field_24(), field_28(), field_2C(), field_30(), -rot_y_mat(mat4u_identity), field_74(mat4u_identity), -field_B4(mat4u_identity), field_F4(mat4u_identity) { +rot_y_mat(mat4_identity), field_74(mat4_identity), +field_B4(mat4_identity), field_F4(mat4_identity) { } @@ -11737,10 +12211,10 @@ void MotionBlendFreeze::Reset() { field_28 = 0.0f; field_2C = 0.0f; field_30 = 2; - rot_y_mat = mat4u_identity; - field_74 = mat4u_identity; - field_B4 = mat4u_identity; - field_F4 = mat4u_identity; + rot_y_mat = mat4_identity; + field_74 = mat4_identity; + field_B4 = mat4_identity; + field_F4 = mat4_identity; } void MotionBlendFreeze::Field_10(float_t a2, float_t a3, int32_t a4) { @@ -11790,7 +12264,7 @@ void MotionBlendFreeze::Step(struc_400* a2) { rot_y_mat = mat; } else - rot_y_mat = mat4u_identity; + rot_y_mat = mat4_identity; } void MotionBlendFreeze::Field_20(std::vector* a2, std::vector* a3) { @@ -11811,8 +12285,8 @@ void MotionBlendFreeze::Blend(bone_data* a2, bone_data* a3) { if (!a2 || a2->disable_mot_anim) return; - mat4u v15; - mat4u v16; + mat4 v15; + mat4 v16; switch (a2->type) { case BONE_DATABASE_BONE_TYPE_1: case BONE_DATABASE_BONE_POSITION: @@ -11915,9 +12389,9 @@ void PartialMotionBlendFreeze::Blend(bone_data* a2, bone_data* a3) { 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); case BONE_DATABASE_BONE_HEAD_IK_ROTATION: { - mat4u v15; - mat4u v16; - mat4u v17; + mat4 v15; + mat4 v16; + mat4 v17; mat4_mult(&a2->rot_mat_prev[1][0], &a2->rot_mat_prev[0][0], &v16); mat4_mult(&a2->rot_mat[1], &a2->rot_mat[0], &v15); mat4_lerp_rotation(&v16, &v15, &v15, blend); @@ -11961,8 +12435,8 @@ void motion_blend_mot::reset() { mot_play_data.reset(); field_4F8.field_0 = 0; field_4F8.field_8 = 0; - field_4F8.mat = mat4u_identity; - field_4F8.field_4C = mat4u_identity; + field_4F8.mat = mat4_identity; + field_4F8.field_4C = mat4_identity; field_4F8.field_8C = false; field_4F8.rot_y = 0.0f; field_4F8.prev_rot_y = 0.0f; @@ -12000,9 +12474,50 @@ void mot_blend::reset() { field_30 = 0; } +struc_241::struc_241() : field_0(), field_4(), field_8(), field_C(), field_10(), field_14(), +field_18(), field_1C(), field_2C(), field_30(), field_34(), field_38(), field_3C(), field_40() { + +} + +struc_241::struc_241(float_t field_0, float_t field_4, float_t field_8, float_t field_C, float_t field_10, + float_t field_14, float_t field_18, float_t field_1C, vec3 field_20, float_t field_2C, + float_t field_30, float_t field_34, float_t field_38, float_t field_3C, float_t field_40) : field_0(field_0), + field_4(field_4), field_8(field_8), field_C(field_C), field_10(field_10), field_14(field_14), + field_18(field_18), field_1C(field_1C), field_2C(field_2C), field_30(field_30), + field_34(field_34), field_38(field_38), field_3C(field_3C), field_40(field_40) { + +} + +struc_258::struc_258() : field_0(), field_8C(), field_8D(), field_8E(), field_8F(), field_90(), +field_91(), field_94(), field_98(), field_9C(), field_A0(), field_A4(), field_A8(), field_AC(), +field_B0(), field_14C(), field_150(), field_154(), field_158(), field_15C(), field_190(), field_191(), +field_192(), field_193(), field_194(), field_195(), field_198(), field_19C(), field_1A0(), field_1A4(), +field_1A8(), field_1AC(), field_1B0(), field_1B4(), field_1B8(), field_1C4(), field_1C8(), field_1CC() { + +} + +rob_chara_bone_data_sleeve_adjust::rob_chara_bone_data_sleeve_adjust() : sleeve_l(), sleeve_r(), +enable1(), enable2(), field_5C(), field_68(), field_74(), field_80(), radius(), bones(), step() { + +} + +void rob_chara_bone_data_sleeve_adjust::reset() { + sleeve_l = {}; + sleeve_r = {}; + enable1 = false; + enable2 = false; + radius = 1.0f; + bones = 0; + step = 1.0f; + field_5C = vec3_null; + field_68 = vec3_null; + field_74 = vec3_null; + field_80 = vec3_null; +} + rob_chara_bone_data::rob_chara_bone_data() : field_0(), field_1(), object_bone_count(), total_bone_count(), motion_bone_count(), ik_bone_count(), chain_pos(), -disable_eye_motion(), field_76C(), field_784(), field_788(), field_958() { +disable_eye_motion(), field_76C(), field_784(), field_788() { base_skeleton_type = BONE_DATABASE_SKELETON_NONE; skeleton_type = BONE_DATABASE_SKELETON_NONE; } @@ -12048,7 +12563,7 @@ void rob_chara_bone_data::reset() { field_76C[0] = vec3_null; field_76C[0] = vec3_null; sub_1404198D0(&field_788); - sub_1403FAEF0(&field_958); + sleeve_adjust.reset(); } rob_chara_pv_data::rob_chara_pv_data() { @@ -12059,8 +12574,8 @@ rob_chara_pv_data::rob_chara_pv_data() { field_8 = vec3_null; rot_y_int16 = 0x00; field_16 = 0xC9; - field_18 = {}; - field_44 = {}; + sleeve_l = {}; + sleeve_r = {}; field_70 = 0; motion_face_ids[0] = -1; motion_face_ids[1] = -1; @@ -12087,7 +12602,7 @@ rob_chara_pv_data::~rob_chara_pv_data() { rob_chara_item_equip_object::rob_chara_item_equip_object() : index(), mats(), obj_info(), field_14(), texture_data(), null_blocks_data_set(), alpha(), draw_task_flags(), can_disp(), field_A4(), mat(), osage_iterations(), bone_nodes(), -field_138(), field_1B8(), field_1C0(), use_opd(), skin_ex_data(), skin(), item_equip() { +field_138(), field_1B8(), osage_nodes_count(), use_opd(), skin_ex_data(), skin(), item_equip() { init_members(0x12345678); } @@ -12289,7 +12804,7 @@ void rob_chara_item_equip_object::init_members(size_t index) { ex_bones.clear(); field_1B8 = 0; use_opd = false; - field_1C0 = 0; + osage_nodes_count = 0; } void rob_chara_item_equip_object::load_ex_data(obj_skin_ex_data* ex_data, @@ -12456,12 +12971,12 @@ void rob_chara_item_equip_object::load_ex_data(obj_skin_ex_data* ex_data, if (osage_count || cloth_count) skp_load_file(data, bone_data, obj_db); - size_t v103 = 0; + size_t osage_nodes_count = 0; for (ExOsageBlock*& i : osage_blocks) - v103 += i->rob.nodes.size() - 1; + osage_nodes_count += i->rob.nodes.size() - 1; for (ExClothBlock*& i : cloth_blocks) - v103 += i->rob.nodes.size() - i->rob.root_count; - field_1C0 = v103; + osage_nodes_count += i->rob.nodes.size() - i->rob.root_count; + this->osage_nodes_count = osage_nodes_count; } void rob_chara_item_equip_object::load_object_info_ex_data(object_info object_info, bone_node* bone_nodes, @@ -12691,6 +13206,12 @@ rob_chara_item_equip::~rob_chara_item_equip() { } } +rob_chara_item_equip_object* rob_chara_item_equip::get_item_equip_object(item_id id) { + if (id >= ITEM_BODY && id <= ITEM_ITEM16) + return &item_equip_object[id]; + return 0; +} + void rob_chara_item_equip::reset() { bone_nodes = 0; matrices = 0; @@ -13367,7 +13888,7 @@ void rob_chara_data_miku_rot::reset() { field_60 = 0; field_64 = 0; field_68 = 0; - field_6C = mat4u_identity; + field_6C = mat4_identity; } void rob_chara_adjust_data::reset() { @@ -13770,6 +14291,293 @@ void MhdFile::ParseFileParent(void* data, const void* file_data, size_t size) { ((MhdFile*)data)->ParseFile(file_data); } +/*OpdMaker::Data::Data() : field_0() { + +} + +OpdMaker::Data::~Data() { + +} + +OpdMakeWorker::OpdMakeWorker() : state(), chara_id(), field_70(), field_D4() { + +} + +OpdMakeWorker::~OpdMakeWorker() { + +} + +bool OpdMakeWorker::Init() { + return true; +} + +bool OpdMakeWorker::Ctrl() { + char* v2; // rax + * v3; // r15 + chara_index chara_index; // er12 + rob_chara_item_cos_data* v5; // r13 + int64_t v6; // rdi + OpdMakeManager* v8; // rax + __int64 v9; // rbx + item_cos_data* v10; // rax + rob_chara_item_equip* v11; // r12 + unsigned __int64 v12; // rsi + rob_chara_item_equip_object* v13; // r15 + object_info v14; // ebx + __int64 v15; // rcx + object_info* j; // rax + OpdMakeManager* v17; // rax + int v18; // ecx + OpdMakeManager* v19; // rax + int32_t* i; // rbx + int32_t v22; // eax + struc_462* v23; // rcx + struc_462* v24; // r14 + struc_462* v25; // rbx + OpdMakeManager* v26; // rax + vector_int32_t* v27; // r12 + OpdMakeWorker::Data* v28; // rbx + string* v29; // rax + struc_658* v30; // rax + struc_658* v31; // rax + const char* v32; // r8 + string* v33; // rbx + int v34; // eax + string* v35; // rbx + __int64 v36; // rax + string* v37; // r15 + const char* v38; // r9 + const char* v39; // r8 + const char* v40; // r9 + const char* v41; // r8 + string* v42; // r15 + struc_462* v43; // r15 + item_cos_data* v44; // rax + int32_t* v45; // rsi + __int64 v46; // rbx + OpdMakeManager* v47; // rax + chara_init_data* v49; // [rsp+20h] [rbp-E0h] + string dst; // [rsp+28h] [rbp-D8h] BYREF + string v51; // [rsp+48h] [rbp-B8h] BYREF + string v52; // [rsp+68h] [rbp-98h] BYREF + string v53; // [rsp+88h] [rbp-78h] BYREF + string Memory; // [rsp+A8h] [rbp-58h] BYREF + __int64 v55; // [rsp+C8h] [rbp-38h] + string v57; // [rsp+E8h] [rbp-18h] BYREF + string v58; // [rsp+108h] [rbp+8h] BYREF + string v59; // [rsp+128h] [rbp+28h] BYREF + + v55 = -2i64; + *(&v6 + 1) = (int64_t)get_rob_chara_smth(); + v2 = get_rob_chara_smth(); + rob_chara* rob_chr = rob_chara_array_get(v2, chara_id); + chara_index = rob_chr->chara_index; + v5 = ; + v49 = chara_init_data_get(chara_index); + v6 = 0i64; + switch (state) { + case 1: { + int32_t* v7 = field_70; + OpdMakeManager* v8 = opd_make_manager_get(); + sub_140479950(&v8->field_88, chara_index, field_70); + v9 = 25i64; + do + { + rob_chara_item_cos_data_set_chara_index(&rob_chr->item_cos_data, chara_index); + rob_chara_item_cos_data_set_item(&rob_chr->item_cos_data, *v7++); + --v9; + } while (v9); + + bone_node* v4 = rob_chara_bone_data_get_node(rob_chara_array[chara_id].bone_data, 0i64); + rob_chara_item_equip_reset_init_data(rob_chr->item_equip, v4); + rob_chara_item_equip_set_shadow_type(rob_chr->item_equip, chara_id); + rob_chr->item_equip->field_A0 = 5; + state = 2; + } + case 2: { + if (!task_rob_load_check_load_req_data()) { + task_rob_load.AppendLoadReqDataObj(chara_index, &rob_chr->item_cos_data.cos); + state = 3; + } + } return false; + case 3: { + if (task_rob_load_check_load_req_data()) + return false; + + rob_chara_item_cos_data_reload_items(&rob_chr->item_cos_data, chara_id); + for (int32_t i = ITEM_KAMI; i < ITEM_MAX; i++) { + v13 = rob_chr->item_equip->get_item_equip_object((item_id)i); + v14 = v13->obj_info; + if (obj_database_get_object_name(v14) && v13->osage_nodes_count) { + int32_t j = ITEM_ATAMA; + object_info* k = v49->field_7E4; + for (; *k != v14; j++, k++) { + if (j < ITEM_KAMI) + continue; + v18 = 6; + if (opd_make_manager_get()->field_1889) + state = 4; + else + state = 6; + return false; + } + } + } + state = 10; + } break; + case 4: { + OpdMakeManager* v19 = opd_make_manager_get(); + sub_140479AA0(&data, rob_chr, &v19->field_1810); + state = 5; + } break; + case 5: { + if (sub_14047A370(&data)) + return false; + state = 6; + } + case 6: { + std::vector v56; + OpdMakeManager* v20 = opd_make_manager_get(); + for (i = v20->field_1810.begin; i != v20->field_1810.end; i++) { + struc_462 v60; + v60.rob_chr = rob_chr; + v60.pv_id = -1; + v60.motion_id = *i; + v60.name = {}; + v60.frame = -1; + v56.push_back(v60); + } + sub_140610780(chara_id, &v56); + + state = 7; + } break; + case 7: { + if (sub_140611690(chara_id)) + return false; + state = 8; + } + case 8: { + v26 = opd_make_manager_get(); + v27 = &v26->field_1810; + v28 = 0; + if (v26->field_1889) + v28 = &data; + v29 = sub_140489250(&Memory); + sub_1400AB860(v29); + if (Memory.capacity >= 0x10) + operator delete(Memory.data.ptr); + Memory.capacity = 15i64; + Memory.length = 0i64; + Memory.data.data[0] = 0; + v30 = sub_140478FF0(chara_id); + sub_14047A110(v30, rob_chr, v27, v28); + state = 9; + } break; + case 9: { + v31 = sub_140478FF0(chara_id); + if (sub_140478D10(v31)) + return false; + sub_140478220(&data); + sub_140489250(&v58); + v32 = (const char*)&v58; + if (v58.capacity >= 0x10) + v32 = v58.data.ptr; + v33 = sprintf_s_string(&v53, "%s/%d", v32, chara_id); + *(&v6 + 1) = 15i64; + if (&v58 != v33) + { + if (v58.capacity >= 0x10) + operator delete(v58.data.ptr); + v58.capacity = 15i64; + v58.length = 0i64; + v58.data.data[0] = 0; + string_move(&v58, v33); + } + if (v53.capacity >= 0x10) + operator delete(v53.data.ptr); + v53.capacity = 15i64; + v53.length = 0i64; + v53.data.data[0] = 0; + + std::vector v56; + if (!sub_1400AC0B0(&v58, &v56) && v56.size()) + for (std::string& i : v56) { + size_t v36 = i.find('/'); + if (v36 == -1) + continue; + + std::string v57 = i.substr(v36 + 1); + v39 = (const char*)&v58; + if (v58.capacity >= 0x10) + v39 = v58.data.ptr; + sprintf_s_string((string*)&v60, "%s/%s", v39, v57.c_str()); + sub_140489030(&v59); + v41 = (const char*)&v59; + if (v59.capacity >= 0x10) + v41 = v59.data.ptr; + v42 = sprintf_s_string(&v51, "%s/%s", v41, v57.c_str()); + if (&v59 != v42) + { + if (v59.capacity >= 0x10) + operator delete(v59.data.ptr); + v59.capacity = 15i64; + v59.length = 0i64; + v59.data.data[0] = 0; + string_move(&v59, v42); + } + if (v51.capacity >= 0x10) + operator delete(v51.data.ptr); + v51.capacity = 15i64; + v51.length = 0i64; + v51.data.data[0] = 0; + sub_1400AB540((string*)&v60, &v59); + sub_1400ACBE0((string*)&v60); + if (v59.capacity >= 0x10) + operator delete(v59.data.ptr); + v59.capacity = 15i64; + v59.length = 0i64; + v59.data.data[0] = 0; + if (*(_QWORD*)&v60.name.data.data[8] >= 0x10ui64) + operator delete(v60.rob_chr); + v60.name.data = *(string_union*)&v6; + LOBYTE(v60.rob_chr) = 0; + if (v57.capacity >= 0x10) + operator delete(v57.data.ptr); + } + + if (field_D4) + return true; + state = 10; + } + case 10: { + task_rob_load.AppendFreeReqDataObj(chara_index, &rob_chr->item_cos_data.cos); + v45 = field_70; + v46 = 25i64; + do + { + rob_chara_item_cos_data_set_chara_index(&rob_chr->item_cos_data, chara_index); + rob_chara_item_cos_data_set_item_zero(&rob_chr->item_cos_data, *v45); + *v45++ = 0; + --v46; + } while (v46); + rob_chara_item_cos_data_reload_items(v5, chara_id); + skin_param_manager_reset(chara_id); + if (sub_140479090(&opd_make_manager_get()->field_88, chara_index)) + return true; + state = 1; + } break; + } + return false; +} + +bool OpdMakeWorker::Dest() { + return true; +} + +void OpdMakeWorker::Disp() { + +}*/ + ReqData::ReqData() : chara_index(), count() { } diff --git a/src/CRE/rob/rob.hpp b/src/CRE/rob/rob.hpp index 5b0d0f27..3c3cc857 100644 --- a/src/CRE/rob/rob.hpp +++ b/src/CRE/rob/rob.hpp @@ -909,9 +909,9 @@ struct bone_data { vec3 rotation; vec3 ik_target; vec3 trans; - mat4u rot_mat[3]; + mat4 rot_mat[3]; vec3 trans_prev[2]; - mat4u rot_mat_prev[3][2]; + mat4 rot_mat_prev[3][2]; mat4* pole_target_mat; mat4* parent_mat; bone_node* node; @@ -973,8 +973,8 @@ struct struc_308 { int32_t field_0; int32_t field_4; uint8_t field_8; - mat4u mat; - mat4u field_4C; + mat4 mat; + mat4 field_4C; bool field_8C; vec3 field_90; vec3 field_9C; @@ -1025,10 +1025,10 @@ class MotionBlendCross : public MotionBlend { public: bool field_20; bool field_21; - mat4u rot_y_mat; - mat4u field_64; - mat4u field_A4; - mat4u field_E4; + mat4 rot_y_mat; + mat4 field_64; + mat4 field_A4; + mat4 field_E4; MotionBlendCross(); virtual ~MotionBlendCross() override; @@ -1055,10 +1055,10 @@ public: float_t field_28; float_t field_2C; int32_t field_30; - mat4u rot_y_mat; - mat4u field_74; - mat4u field_B4; - mat4u field_F4; + mat4 rot_y_mat; + mat4 field_74; + mat4 field_B4; + mat4 field_F4; MotionBlendFreeze(); virtual ~MotionBlendFreeze() override; @@ -1088,8 +1088,10 @@ struct struc_313 { ~struc_313(); }; +typedef bool(* PFNMOTIONBONECHECKFUNC)(motion_bone_index bone_index); + struct struc_240 { - bool(*bone_check_func)(motion_bone_index bone_index); + PFNMOTIONBONECHECKFUNC bone_check_func; struc_313 field_8; size_t motion_bone_count; @@ -1146,15 +1148,18 @@ struct struc_241 { float_t field_14; float_t field_18; float_t field_1C; - float_t field_20; - float_t field_24; - float_t field_28; + vec3 field_20; float_t field_2C; float_t field_30; float_t field_34; float_t field_38; float_t field_3C; float_t field_40; + + struc_241(); + struc_241(float_t field_0, float_t field_4, float_t field_8, float_t field_C, float_t field_10, + float_t field_14, float_t field_18, float_t field_1C, vec3 field_20, float_t field_2C, + float_t field_30, float_t field_34, float_t field_38, float_t field_3C, float_t field_40); }; struct struc_243 { @@ -1172,7 +1177,7 @@ struct struc_243 { struct struc_258 { std::vector* field_0; - mat4u field_8; + mat4 field_8; struc_241 field_48; bool field_8C; bool field_8D; @@ -1190,16 +1195,14 @@ struct struc_258 { float_t field_B0; vec3 field_B4; vec3 field_C0; - mat4u field_CC; - mat4u field_10C; + mat4 field_CC; + mat4 field_10C; bool field_14C; float_t field_150; float_t field_154; float_t field_158; struc_243 field_15C; - float_t field_184; - float_t field_188; - float_t field_18C; + vec3 field_184; bool field_190; bool field_191; bool field_192; @@ -1219,32 +1222,40 @@ struct struc_258 { bool field_1C4; int32_t field_1C8; int32_t field_1CC; + + struc_258(); }; -struct struc_242 { - float_t field_0; - float_t field_4; - float_t field_8; - float_t field_C; - float_t field_10; - float_t field_14; - float_t field_18; - vec3 field_1C; - float_t field_28; +struct sleeve_data { + float_t radius; + float_t cyofs; + float_t czofs; + float_t ymin; + float_t ymax; + float_t zmin; + float_t zmax; + float_t mune_xofs; + float_t mune_yofs; + float_t mune_zofs; + float_t mune_rad; }; -struct struc_312 { - struc_242 field_0; - struc_242 field_2C; - bool field_58; - bool field_59; +struct rob_chara_bone_data_sleeve_adjust { + sleeve_data sleeve_l; + sleeve_data sleeve_r; + bool enable1; + bool enable2; vec3 field_5C; vec3 field_68; vec3 field_74; vec3 field_80; - float_t field_8C; + float_t radius; std::vector* bones; float_t step; + + rob_chara_bone_data_sleeve_adjust(); + + void reset(); }; struct rob_chara_bone_data { @@ -1275,7 +1286,7 @@ struct rob_chara_bone_data { vec3 field_76C[2]; int32_t field_784; struc_258 field_788; - struc_312 field_958; + rob_chara_bone_data_sleeve_adjust sleeve_adjust; rob_chara_bone_data(); virtual ~rob_chara_bone_data(); @@ -1301,8 +1312,8 @@ struct rob_chara_pv_data { vec3 field_8; int16_t rot_y_int16; int16_t field_16; - struc_242 field_18; - struc_242 field_44; + sleeve_data sleeve_l; + sleeve_data sleeve_r; int32_t field_70; int32_t motion_face_ids[10]; int32_t chara_size_index; @@ -1324,14 +1335,15 @@ struct struc_218 { struct struc_344 { int32_t chara_size_index; int32_t field_4; - int32_t field_8; - int32_t field_C; + int32_t swim_costume; + int32_t swim_s_costume; }; struct chara_init_data { int32_t object_set; bone_database_skeleton_type skeleton_type; - object_info field_7E0[15]; + object_info field_7E0; + object_info field_7E4[14]; uint32_t motion_set; const struc_218* field_828; const struc_218* field_830; @@ -1404,7 +1416,7 @@ struct RobOsageNodeDataNormalRef { RobOsageNode* d; RobOsageNode* l; RobOsageNode* r; - mat4u mat; + mat4 mat; void GetMat(); }; @@ -1475,7 +1487,7 @@ struct RobOsageNode { float_t child_length; bone_node* bone_node_ptr; mat4* bone_node_mat; - mat4u mat; + mat4 mat; RobOsageNode* sibling_node; float_t max_distance; vec3 field_94; @@ -1660,7 +1672,7 @@ struct CLOTH { osage_coli coli[64]; osage_coli coli_ring[64]; osage_ring_data ring; - mat4u* mats; + mat4* mats; CLOTH(); virtual ~CLOTH(); @@ -1680,14 +1692,14 @@ struct CLOTH { struct RobClothRoot { vec3 trans; vec3 normal; - vec4u tangent; + vec4 tangent; bone_node* node[4]; mat4* node_mat[4]; - mat4u* mat[4]; + mat4* mat[4]; float_t weight[4]; - mat4u field_98; - mat4u field_D8; - mat4u field_118; + mat4 field_98; + mat4 field_D8; + mat4 field_118; }; struct RobClothSubMeshArray { @@ -1728,7 +1740,7 @@ struct RobCloth : public CLOTH { void ColiSet(mat4* mats); void Disp(mat4* mat, render_context* rctx); void InitData(size_t root_count, size_t nodes_count, obj_skin_block_cloth_root* root, - obj_skin_block_cloth_node* nodes, mat4u* mats, int32_t a7, + obj_skin_block_cloth_node* nodes, mat4* mats, int32_t a7, rob_chara_item_equip_object* itm_eq_obj, bone_database* bone_data); void InitDataParent(obj_skin_block_cloth* cls_data, rob_chara_item_equip_object* itm_eq_obj, bone_database* bone_data); @@ -1809,7 +1821,7 @@ struct RobOsage { int32_t yz_order; int32_t field_1EBC; mat4* parent_mat_ptr; - mat4u parent_mat; + mat4 parent_mat; float_t move_cancel; bool field_1F0C; bool osage_reset; @@ -2024,7 +2036,7 @@ struct rob_chara_item_equip_object { std::vector expression_blocks; std::vector cloth_blocks; bool field_1B8; - int64_t field_1C0; + size_t osage_nodes_count; bool use_opd; obj_skin_ex_data* skin_ex_data; obj_skin* skin; @@ -2079,13 +2091,13 @@ struct rob_chara_item_equip { int32_t field_D4; bool disable_update; int32_t field_DC; - vec4u texture_color_coeff; + vec4 texture_color_coeff; float_t wet; float_t wind_strength; bool chara_color; bool npr_flag; - mat4u mat; - mat4u field_13C[30]; + mat4 mat; + mat4 field_13C[30]; int32_t field_8BC; int32_t field_8C0; int32_t field_8C4; @@ -2120,6 +2132,7 @@ struct rob_chara_item_equip { rob_chara_item_equip(); virtual ~rob_chara_item_equip(); + rob_chara_item_equip_object* get_item_equip_object(item_id id); void reset(); }; @@ -2602,8 +2615,8 @@ struct rob_chara_motion { object_info hand_l_object; object_info hand_r_object; struc_405 field_3B0; - rob_chara_data_adjust parts_adjust[13]; - rob_chara_data_adjust parts_adjust_prev[13]; + rob_chara_data_adjust parts_adjust[ROB_OSAGE_PARTS_MAX]; + rob_chara_data_adjust parts_adjust_prev[ROB_OSAGE_PARTS_MAX]; rob_chara_data_adjust adjust_global; rob_chara_data_adjust adjust_global_prev; rob_chara_data_hand_adjust hand_adjust[2]; @@ -2882,7 +2895,7 @@ struct rob_chara_data_miku_rot { int32_t field_60; int32_t field_64; int32_t field_68; - mat4u field_6C; + mat4 field_6C; void reset(); }; @@ -2898,7 +2911,7 @@ struct rob_chara_adjust_data { bool offset_z; bool get_global_trans; vec3 trans; - mat4u mat; + mat4 mat; float_t left_hand_scale; float_t right_hand_scale; float_t left_hand_scale_default; @@ -2960,8 +2973,8 @@ struct struc_209 { int32_t field_6C; int32_t field_70; int32_t field_74; - mat4u field_78[27]; - mat4u field_738[27]; + mat4 field_78[27]; + mat4 field_738[27]; struc_195 field_DF8[27]; struc_195 field_1230[27]; struc_195 field_1668[27]; @@ -3128,6 +3141,8 @@ struct rob_chara { rob_chara(); virtual ~rob_chara(); + void autoblink_disable(); + void autoblink_enable(); mat4* get_bone_data_mat(size_t index); float_t get_frame(); float_t get_frame_count(); @@ -3244,3 +3259,8 @@ extern void skin_param_osage_node_parse(void* kv, const char* name, extern void skin_param_osage_root_parse(void* kv, const char* name, skin_param_osage_root& skp_root, bone_database* bone_data); + +extern int32_t expression_id_to_mottbl_index(int32_t expression_id); +extern int32_t hand_anim_id_to_mottbl_index(int32_t hand_anim_id); +extern int32_t look_anim_id_to_mottbl_index(int32_t look_anim_id); +extern int32_t mouth_anim_id_to_mottbl_index(int32_t mouth_anim_id); diff --git a/src/CRE/shader.cpp b/src/CRE/shader.cpp index fbe90255..0706c96a 100644 --- a/src/CRE/shader.cpp +++ b/src/CRE/shader.cpp @@ -67,6 +67,14 @@ shader_state_point::shader_state_point() { } +shader_state_texgen::eye::eye() { + +} + +shader_state_texgen::object::object() { + +} + shader_state_texgen::shader_state_texgen() { } @@ -166,7 +174,7 @@ void shader_set_data::draw_range_elements(GLenum mode, int32_t shader_set_data::get_index_by_name(const char* name) { for (size_t i = 0; i < size; i++) if (!str_utils_compare(shaders[i].name, name)) - return (int32_t)shaders[i].index; + return (int32_t)shaders[i].name_index; return -1; } @@ -206,7 +214,7 @@ void shader_set_data::load(farc* f, bool ignore_cache, bool not_load_cache, for (size_t i = 0; i < size; i++) { shader* shader = &shaders[i]; shader->name = shaders_table[i].name; - shader->index = shaders_table[i].index; + shader->name_index = shaders_table[i].name_index; shader->num_sub = shaders_table[i].num_sub; shader->sub = force_malloc_s(shader_sub, shader->num_sub); shader->num_uniform = shaders_table[i].num_uniform; @@ -465,7 +473,7 @@ void shader_set_data::load(farc* f, bool ignore_cache, bool not_load_cache, vec_frag.clear(); for (size_t j = 0; j < bind_func_table_size; j++) - if (shader->index == bind_func_table[j].index) { + if (shader->name_index == bind_func_table[j].index) { shader->bind_func = bind_func_table[j].bind_func; break; } @@ -879,56 +887,56 @@ void shader_set_data::state_texgen_get_eye_s(size_t index, vec4& data) { if (!this || index >= SHADER_MAX_TEXTURE_UNITS) return; - data = this->data.state.texgen[index].eye_s; + data = this->data.state.texgen[index].eye.s; } void shader_set_data::state_texgen_get_eye_t(size_t index, vec4& data) { if (!this || index >= SHADER_MAX_TEXTURE_UNITS) return; - data = this->data.state.texgen[index].eye_t; + data = this->data.state.texgen[index].eye.t; } void shader_set_data::state_texgen_get_eye_r(size_t index, vec4& data) { if (!this || index >= SHADER_MAX_TEXTURE_UNITS) return; - data = this->data.state.texgen[index].eye_r; + data = this->data.state.texgen[index].eye.r; } void shader_set_data::state_texgen_get_eye_q(size_t index, vec4& data) { if (!this || index >= SHADER_MAX_TEXTURE_UNITS) return; - data = this->data.state.texgen[index].eye_q; + data = this->data.state.texgen[index].eye.q; } void shader_set_data::state_texgen_get_object_s(size_t index, vec4& data) { if (!this || index >= SHADER_MAX_TEXTURE_UNITS) return; - data = this->data.state.texgen[index].object_s; + data = this->data.state.texgen[index].object.s; } void shader_set_data::state_texgen_get_object_t(size_t index, vec4& data) { if (!this || index >= SHADER_MAX_TEXTURE_UNITS) return; - data = this->data.state.texgen[index].object_t; + data = this->data.state.texgen[index].object.t; } void shader_set_data::state_texgen_get_object_r(size_t index, vec4& data) { if (!this || index >= SHADER_MAX_TEXTURE_UNITS) return; - data = this->data.state.texgen[index].object_r; + data = this->data.state.texgen[index].object.r; } void shader_set_data::state_texgen_get_object_q(size_t index, vec4& data) { if (!this || index >= SHADER_MAX_TEXTURE_UNITS) return; - data = this->data.state.texgen[index].object_q; + data = this->data.state.texgen[index].object.q; } void shader_set_data::state_texenv_get_color(size_t index, vec4& data) { @@ -1891,10 +1899,10 @@ void shader_set_data::state_texgen_set_eye_s(size_t index, float_t x, float_t y, return; vec4 data = { x, y, z, w }; - if (!memcmp(&this->data.state.texgen[index].eye_s, &data, sizeof(vec4))) + if (!memcmp(&this->data.state.texgen[index].eye.s, &data, sizeof(vec4))) return; - this->data.state.texgen[index].eye_s = data; + this->data.state.texgen[index].eye.s = data; this->data.state_update_data = true; } @@ -1902,10 +1910,10 @@ void shader_set_data::state_texgen_set_eye_s(size_t index, const vec4& data) { if (!this || index >= SHADER_MAX_TEXTURE_UNITS) return; - if (!memcmp(&this->data.state.texgen[index].eye_s, &data, sizeof(vec4))) + if (!memcmp(&this->data.state.texgen[index].eye.s, &data, sizeof(vec4))) return; - this->data.state.texgen[index].eye_s = data; + this->data.state.texgen[index].eye.s = data; this->data.state_update_data = true; } @@ -1914,10 +1922,10 @@ void shader_set_data::state_texgen_set_eye_t(size_t index, float_t x, float_t y, return; vec4 data = { x, y, z, w }; - if (!memcmp(&this->data.state.texgen[index].eye_t, &data, sizeof(vec4))) + if (!memcmp(&this->data.state.texgen[index].eye.t, &data, sizeof(vec4))) return; - this->data.state.texgen[index].eye_t = data; + this->data.state.texgen[index].eye.t = data; this->data.state_update_data = true; } @@ -1925,10 +1933,10 @@ void shader_set_data::state_texgen_set_eye_t(size_t index, const vec4& data) { if (!this || index >= SHADER_MAX_TEXTURE_UNITS) return; - if (!memcmp(&this->data.state.texgen[index].eye_t, &data, sizeof(vec4))) + if (!memcmp(&this->data.state.texgen[index].eye.t, &data, sizeof(vec4))) return; - this->data.state.texgen[index].eye_t = data; + this->data.state.texgen[index].eye.t = data; this->data.state_update_data = true; } @@ -1937,10 +1945,10 @@ void shader_set_data::state_texgen_set_eye_r(size_t index, float_t x, float_t y, return; vec4 data = { x, y, z, w }; - if (!memcmp(&this->data.state.texgen[index].eye_r, &data, sizeof(vec4))) + if (!memcmp(&this->data.state.texgen[index].eye.r, &data, sizeof(vec4))) return; - this->data.state.texgen[index].eye_r = data; + this->data.state.texgen[index].eye.r = data; this->data.state_update_data = true; } @@ -1948,10 +1956,10 @@ void shader_set_data::state_texgen_set_eye_r(size_t index, const vec4& data) { if (!this || index >= SHADER_MAX_TEXTURE_UNITS) return; - if (!memcmp(&this->data.state.texgen[index].eye_r, &data, sizeof(vec4))) + if (!memcmp(&this->data.state.texgen[index].eye.r, &data, sizeof(vec4))) return; - this->data.state.texgen[index].eye_r = data; + this->data.state.texgen[index].eye.r = data; this->data.state_update_data = true; } @@ -1960,10 +1968,10 @@ void shader_set_data::state_texgen_set_eye_q(size_t index, float_t x, float_t y, return; vec4 data = { x, y, z, w }; - if (!memcmp(&this->data.state.texgen[index].eye_q, &data, sizeof(vec4))) + if (!memcmp(&this->data.state.texgen[index].eye.q, &data, sizeof(vec4))) return; - this->data.state.texgen[index].eye_q = data; + this->data.state.texgen[index].eye.q = data; this->data.state_update_data = true; } @@ -1971,10 +1979,10 @@ void shader_set_data::state_texgen_set_eye_q(size_t index, const vec4& data) { if (!this || index >= SHADER_MAX_TEXTURE_UNITS) return; - if (!memcmp(&this->data.state.texgen[index].eye_q, &data, sizeof(vec4))) + if (!memcmp(&this->data.state.texgen[index].eye.q, &data, sizeof(vec4))) return; - this->data.state.texgen[index].eye_q = data; + this->data.state.texgen[index].eye.q = data; this->data.state_update_data = true; } @@ -1983,10 +1991,10 @@ void shader_set_data::state_texgen_set_object_s(size_t index, float_t x, float_t return; vec4 data = { x, y, z, w }; - if (!memcmp(&this->data.state.texgen[index].object_s, &data, sizeof(vec4))) + if (!memcmp(&this->data.state.texgen[index].object.s, &data, sizeof(vec4))) return; - this->data.state.texgen[index].object_s = data; + this->data.state.texgen[index].object.s = data; this->data.state_update_data = true; } @@ -1994,10 +2002,10 @@ void shader_set_data::state_texgen_set_object_s(size_t index, const vec4& data) if (!this || index >= SHADER_MAX_TEXTURE_UNITS) return; - if (!memcmp(&this->data.state.texgen[index].object_s, &data, sizeof(vec4))) + if (!memcmp(&this->data.state.texgen[index].object.s, &data, sizeof(vec4))) return; - this->data.state.texgen[index].object_s = data; + this->data.state.texgen[index].object.s = data; this->data.state_update_data = true; } @@ -2006,10 +2014,10 @@ void shader_set_data::state_texgen_set_object_t(size_t index, float_t x, float_t return; vec4 data = { x, y, z, w }; - if (!memcmp(&this->data.state.texgen[index].object_t, &data, sizeof(vec4))) + if (!memcmp(&this->data.state.texgen[index].object.t, &data, sizeof(vec4))) return; - this->data.state.texgen[index].object_t = data; + this->data.state.texgen[index].object.t = data; this->data.state_update_data = true; } @@ -2017,10 +2025,10 @@ void shader_set_data::state_texgen_set_object_t(size_t index, const vec4& data) if (!this || index >= SHADER_MAX_TEXTURE_UNITS) return; - if (!memcmp(&this->data.state.texgen[index].object_t, &data, sizeof(vec4))) + if (!memcmp(&this->data.state.texgen[index].object.t, &data, sizeof(vec4))) return; - this->data.state.texgen[index].object_t = data; + this->data.state.texgen[index].object.t = data; this->data.state_update_data = true; } @@ -2029,10 +2037,10 @@ void shader_set_data::state_texgen_set_object_r(size_t index, float_t x, float_t return; vec4 data = { x, y, z, w }; - if (!memcmp(&this->data.state.texgen[index].object_r, &data, sizeof(vec4))) + if (!memcmp(&this->data.state.texgen[index].object.r, &data, sizeof(vec4))) return; - this->data.state.texgen[index].object_r = data; + this->data.state.texgen[index].object.r = data; this->data.state_update_data = true; } @@ -2040,10 +2048,10 @@ void shader_set_data::state_texgen_set_object_r(size_t index, const vec4& data) if (!this || index >= SHADER_MAX_TEXTURE_UNITS) return; - if (!memcmp(&this->data.state.texgen[index].object_r, &data, sizeof(vec4))) + if (!memcmp(&this->data.state.texgen[index].object.r, &data, sizeof(vec4))) return; - this->data.state.texgen[index].object_r = data; + this->data.state.texgen[index].object.r = data; this->data.state_update_data = true; } @@ -2052,10 +2060,10 @@ void shader_set_data::state_texgen_set_object_q(size_t index, float_t x, float_t return; vec4 data = { x, y, z, w }; - if (!memcmp(&this->data.state.texgen[index].object_q, &data, sizeof(vec4))) + if (!memcmp(&this->data.state.texgen[index].object.q, &data, sizeof(vec4))) return; - this->data.state.texgen[index].object_q = data; + this->data.state.texgen[index].object.q = data; this->data.state_update_data = true; } @@ -2063,10 +2071,10 @@ void shader_set_data::state_texgen_set_object_q(size_t index, const vec4& data) if (!this || index >= SHADER_MAX_TEXTURE_UNITS) return; - if (!memcmp(&this->data.state.texgen[index].object_q, &data, sizeof(vec4))) + if (!memcmp(&this->data.state.texgen[index].object.q, &data, sizeof(vec4))) return; - this->data.state.texgen[index].object_q = data; + this->data.state.texgen[index].object.q = data; this->data.state_update_data = true; } diff --git a/src/CRE/shader.hpp b/src/CRE/shader.hpp index 2e71c727..e0d632f9 100644 --- a/src/CRE/shader.hpp +++ b/src/CRE/shader.hpp @@ -111,25 +111,23 @@ struct shader_state_point { }; struct shader_state_texgen { - union { - vec4 eye[4]; - struct { - vec4 eye_s; - vec4 eye_t; - vec4 eye_r; - vec4 eye_q; - }; - }; + struct eye { + vec4 s; + vec4 t; + vec4 r; + vec4 q; - union { - vec4 object[4]; - struct { - vec4 object_s; - vec4 object_t; - vec4 object_r; - vec4 object_q; - }; - }; + eye(); + } eye; + + struct object { + vec4 s; + vec4 t; + vec4 r; + vec4 q; + + object(); + } object; shader_state_texgen(); }; @@ -189,11 +187,11 @@ struct shader_data { struct shader; struct shader_set_data; -typedef void (*PFNSHADERPERMUTBINDFUNCPROC)(shader_set_data* set, shader* shad); +typedef void (*PFNSHADERBINDFUNCPROC)(shader_set_data* set, shader* shad); struct shader_bind_func { uint32_t index; - PFNSHADERPERMUTBINDFUNCPROC bind_func; + PFNSHADERBINDFUNCPROC bind_func; }; struct shader_sub { @@ -213,7 +211,7 @@ struct shader_sub_table { struct shader_table { const char* name; - uint32_t index; + uint32_t name_index; int32_t num_sub; const shader_sub_table* sub; int32_t num_uniform; @@ -223,13 +221,13 @@ struct shader_table { struct shader { const char* name; - uint32_t index; + uint32_t name_index; int32_t num_sub; shader_sub* sub; int32_t num_uniform; const uniform_name* use_uniform; const bool* use_permut; - PFNSHADERPERMUTBINDFUNCPROC bind_func; + PFNSHADERBINDFUNCPROC bind_func; int32_t bind(uint32_t sub_index); static void unbind(); diff --git a/src/CRE/shader_ft.cpp b/src/CRE/shader_ft.cpp index 337cfef2..fbfe9b2a 100644 --- a/src/CRE/shader_ft.cpp +++ b/src/CRE/shader_ft.cpp @@ -37,8 +37,8 @@ enum shader_ft_sub_enum { SHADER_FT_SUB_LAMBERT = 0x1B, SHADER_FT_SUB_CONSTANT = 0x1C, SHADER_FT_SUB_PEEL = 0x1D, - SHADER_FT_SUB_TONE_MAP = 0x1E, - SHADER_FT_SUB_TONE_MAP_NPR1 = 0x1F, + SHADER_FT_SUB_TONEMAP = 0x1E, + SHADER_FT_SUB_TONEMAP_NPR1 = 0x1F, SHADER_FT_SUB_REDUCE_TEX = 0x20, SHADER_FT_SUB_MAGNIFY = 0x21, SHADER_FT_SUB_MLAA = 0x22, @@ -310,19 +310,19 @@ static const int32_t peel_fpt_unival_max[] = { 1, 0, }; -static const int32_t tone_map_vpt_unival_max[] = { +static const int32_t tonemap_vpt_unival_max[] = { 0, 0, 0, 0, 1, 0, 0, 0, }; -static const int32_t tone_map_fpt_unival_max[] = { +static const int32_t tonemap_fpt_unival_max[] = { 0, 2, 2, 1, 1, 1, 0, 0, }; -static const int32_t tone_map_npr1_vpt_unival_max[] = { +static const int32_t tonemap_npr1_vpt_unival_max[] = { 0, 0, 0, 0, 1, 0, 0, 0, }; -static const int32_t tone_map_npr1_fpt_unival_max[] = { +static const int32_t tonemap_npr1_fpt_unival_max[] = { 1, 0, 0, 1, 1, 0, 0, 1, }; @@ -891,16 +891,16 @@ static const shader_sub_table PEEL_table[] = { static const shader_sub_table TONEMAP_table[] = { { - SHADER_FT_SUB_TONE_MAP, - tone_map_vpt_unival_max, - tone_map_fpt_unival_max, + SHADER_FT_SUB_TONEMAP, + tonemap_vpt_unival_max, + tonemap_fpt_unival_max, "tone_map", "tone_map", }, { - SHADER_FT_SUB_TONE_MAP_NPR1, - tone_map_npr1_vpt_unival_max, - tone_map_npr1_fpt_unival_max, + SHADER_FT_SUB_TONEMAP_NPR1, + tonemap_npr1_vpt_unival_max, + tonemap_npr1_fpt_unival_max, "tone_map", "tone_map_npr1", }, @@ -2160,8 +2160,8 @@ static const bool SPRITE_permut[] = { }; struct glass_eye_struct { - vec4u field_0; - vec4u field_10; + vec4 field_0; + vec4 field_10; float_t field_20; float_t field_24; float_t field_28; @@ -2178,7 +2178,7 @@ struct glass_eye_struct { float_t field_8C; vec3 field_90; uint32_t frame; - vec4u field_A0; + vec4 field_A0; bool field_B0; bool field_B1; bool field_B2; @@ -2328,7 +2328,7 @@ glass_eye_struct glass_eye = { { 1.0f, 1.2f, 0.45f }, { 1.0f, 1.2f, 0.25f }, { 0.5f, 0.6f, 0.4f }, - 0.2f, + -0.2f, { 1.0f, 1.0f, 1.0f }, 0.0f, { 0.0f, 0.0f, 0.0f }, @@ -2361,7 +2361,7 @@ static void glass_eye_calc(glass_eye_struct* glass_eye) { vec3_mult_scalar(glass_eye->field_48, v2, glass_eye->field_80); glass_eye->field_8C = glass_eye->field_54 * v2; if (glass_eye->field_B0 == 0) { - glass_eye->field_A0 = vec4u_null; + glass_eye->field_A0 = vec4_null; return; } @@ -2423,7 +2423,7 @@ static void glass_eye_set(glass_eye_struct* glass_eye, shader_set_data* set) { set->local_frag_set(0x0D, v3, 1.0f - v3, glass_eye->field_20 / glass_eye->field_24, 0.0f); float_t v4 = (glass_eye->field_24 * glass_eye->field_24) / (glass_eye->field_20 * glass_eye->field_20); - set->local_frag_set(0x0E, 1.0f - v4, v4, glass_eye->field_24 / glass_eye->field_20, 0.0f); + set->local_frag_set(0x0E, v4, 1.0f - v4, glass_eye->field_24 / glass_eye->field_20, 0.0f); vec3_mult(glass_eye->field_74, glass_eye->field_74, *(vec3*)&temp); temp.w = -1.0f; @@ -2489,5 +2489,5 @@ static void shader_bind_eye_ball(shader_set_data* set, shader* shad) { static void shader_bind_tone_map(shader_set_data* set, shader* shad) { shad->bind(uniform_value[U_NPR] == 1 - ? SHADER_FT_SUB_TONE_MAP_NPR1 : SHADER_FT_SUB_TONE_MAP); + ? SHADER_FT_SUB_TONEMAP_NPR1 : SHADER_FT_SUB_TONEMAP); } diff --git a/src/CRE/shader_glsl.cpp b/src/CRE/shader_glsl.cpp index 7ee5355b..b7e913f5 100644 --- a/src/CRE/shader_glsl.cpp +++ b/src/CRE/shader_glsl.cpp @@ -295,14 +295,6 @@ void shader_glsl::set(const char* name, vec4i& value) { } } -void shader_glsl::set(const char* name, vec4iu& value) { - int32_t location = get_uniform_location(name); - if (location != GL_INVALID_INDEX) { - use(); - glUniform4i(location, value.x, value.y, value.z, value.w); - } -} - void shader_glsl::set(const char* name, int32_t x, int32_t y, int32_t z, int32_t w) { int32_t location = get_uniform_location(name); if (location != GL_INVALID_INDEX) { @@ -319,14 +311,6 @@ void shader_glsl::set(const char* name, vec4& value) { } } -void shader_glsl::set(const char* name, vec4u& value) { - int32_t location = get_uniform_location(name); - if (location != GL_INVALID_INDEX) { - use(); - glUniform4f(location, value.x, value.y, value.z, value.w); - } -} - void shader_glsl::set(const char* name, float_t x, float_t y, float_t z, float_t w) { int32_t location = get_uniform_location(name); if (location != GL_INVALID_INDEX) { @@ -351,14 +335,6 @@ void shader_glsl::set(const char* name, bool transpose, mat4& value) { } } -void shader_glsl::set(const char* name, bool transpose, mat4u& value) { - int32_t location = get_uniform_location(name); - if (location != GL_INVALID_INDEX) { - use(); - glUniformMatrix4fv(location, 1, transpose, (GLfloat*)&value); - } -} - void shader_glsl::set(const char* name, size_t count, int32_t* value) { int32_t location = get_uniform_location(name); if (location != GL_INVALID_INDEX) { @@ -415,14 +391,6 @@ void shader_glsl::set(const char* name, size_t count, vec4i* value) { } } -void shader_glsl::set(const char* name, size_t count, vec4iu* value) { - int32_t location = get_uniform_location(name); - if (location != GL_INVALID_INDEX) { - use(); - glUniform4iv(location, (GLsizei)count, (GLint*)value); - } -} - void shader_glsl::set(const char* name, size_t count, vec4* value) { int32_t location = get_uniform_location(name); if (location != GL_INVALID_INDEX) { @@ -431,14 +399,6 @@ void shader_glsl::set(const char* name, size_t count, vec4* value) { } } -void shader_glsl::set(const char* name, size_t count, vec4u* value) { - int32_t location = get_uniform_location(name); - if (location != GL_INVALID_INDEX) { - use(); - glUniform4fv(location, (GLsizei)count, (GLfloat*)value); - } -} - void shader_glsl::set(const char* name, size_t count, bool transpose, mat3* value) { int32_t location = get_uniform_location(name); if (location != GL_INVALID_INDEX) { @@ -455,14 +415,6 @@ void shader_glsl::set(const char* name, size_t count, bool transpose, mat4* valu } } -void shader_glsl::set(const char* name, size_t count, bool transpose, mat4u* value) { - int32_t location = get_uniform_location(name); - if (location != GL_INVALID_INDEX) { - use(); - glUniformMatrix4fv(location, (GLsizei)count, transpose, (GLfloat*)value); - } -} - void shader_glsl::set_uniform_block_binding(GLchar* name, GLint binding) { GLint index = shader_get_uniform_block_index(program, name, &uniform_block); if (index != GL_INVALID_INDEX) diff --git a/src/CRE/shader_glsl.hpp b/src/CRE/shader_glsl.hpp index bd12d3a8..67dcdcae 100644 --- a/src/CRE/shader_glsl.hpp +++ b/src/CRE/shader_glsl.hpp @@ -50,14 +50,11 @@ struct shader_glsl { void set(const char* name, vec3& value); void set(const char* name, float_t x, float_t y, float_t z); void set(const char* name, vec4i& value); - void set(const char* name, vec4iu& value); void set(const char* name, int32_t x, int32_t y, int32_t z, int32_t w); void set(const char* name, vec4& value); - void set(const char* name, vec4u& value); void set(const char* name, float_t x, float_t y, float_t z, float_t w); void set(const char* name, bool transpose, mat3& value); void set(const char* name, bool transpose, mat4& value); - void set(const char* name, bool transpose, mat4u& value); void set(const char* name, size_t count, int32_t* value); void set(const char* name, size_t count, float_t* value); void set(const char* name, size_t count, vec2i* value); @@ -65,12 +62,9 @@ struct shader_glsl { void set(const char* name, size_t count, vec3i* value); void set(const char* name, size_t count, vec3* value); void set(const char* name, size_t count, vec4i* value); - void set(const char* name, size_t count, vec4iu* value); void set(const char* name, size_t count, vec4* value); - void set(const char* name, size_t count, vec4u* value); void set(const char* name, size_t count, bool transpose, mat3* value); void set(const char* name, size_t count, bool transpose, mat4* value); - void set(const char* name, size_t count, bool transpose, mat4u* value); void set_uniform_block_binding(GLchar* name, GLint binding); void unload(); void use(); diff --git a/src/CRE/stage.cpp b/src/CRE/stage.cpp index 1b534ef7..639f0809 100644 --- a/src/CRE/stage.cpp +++ b/src/CRE/stage.cpp @@ -175,10 +175,6 @@ void task_stage_set_mat(mat4* mat) { task_stage->mat = *mat; } -void task_stage_set_mat(mat4u* mat) { - task_stage->mat = *mat; -} - void task_stage_set_stage(task_stage_info* stg_info) { stage_detail::TaskStage_SetStage(task_stage, *stg_info); } @@ -343,7 +339,7 @@ static void stage_detail::TaskStage_Reset(stage_detail::TaskStage* a1) { a1->field_FB2 = true; a1->field_FB3 = true; a1->field_FB4 = true; - a1->mat = mat4u_identity; + a1->mat = mat4_identity; a1->field_FF8 = 0.0f; } @@ -630,7 +626,7 @@ static void stage_reset(stage* s) { s->ring = true; s->sky = true; s->auth_3d_loaded = 0; - s->mat = mat4u_identity; + s->mat = mat4_identity; s->rot_y = 0.0; s->obj_set = -1; diff --git a/src/CRE/stage.hpp b/src/CRE/stage.hpp index b3635e0b..0cec7c5d 100644 --- a/src/CRE/stage.hpp +++ b/src/CRE/stage.hpp @@ -22,7 +22,7 @@ struct stage { bool ring; bool sky; bool auth_3d_loaded; - mat4u mat; + mat4 mat; float_t rot_y; uint32_t obj_set; @@ -49,7 +49,7 @@ namespace stage_detail { bool field_FB2; bool field_FB3; bool field_FB4; - mat4u mat; + mat4 mat; float_t field_FF8; TaskStage(); @@ -106,7 +106,6 @@ int32_t task_stage_get_stage_index(task_stage_info* stg_info); extern bool task_stage_has_stage_info(task_stage_info* stg_info); extern bool task_stage_load(const char* name); extern void task_stage_set_mat(mat4* mat); -extern void task_stage_set_mat(mat4u* mat); extern void task_stage_set_stage(task_stage_info* stg_info); extern void task_stage_set_stage_index(int32_t stage_index); extern void task_stage_set_stage_indices(std::vector* stage_indices); diff --git a/src/CRE/stage_modern.cpp b/src/CRE/stage_modern.cpp index a06bf4a9..e9db9e56 100644 --- a/src/CRE/stage_modern.cpp +++ b/src/CRE/stage_modern.cpp @@ -152,10 +152,6 @@ void task_stage_modern_set_mat(mat4* mat) { task_stage_modern->mat = *mat; } -void task_stage_modern_set_mat(mat4u* mat) { - task_stage_modern->mat = *mat; -} - void task_stage_modern_set_stage(task_stage_modern_info* stg_info) { stage_detail::TaskStageModern_SetStage(task_stage_modern, *stg_info); } @@ -329,7 +325,7 @@ static void stage_detail::TaskStageModern_Reset(stage_detail::TaskStageModern* a a1->field_FB2 = true; a1->field_FB3 = true; a1->field_FB4 = true; - a1->mat = mat4u_identity; + a1->mat = mat4_identity; a1->field_FF8 = 0.0f; } @@ -590,7 +586,7 @@ static void stage_modern_reset(stage_modern* s) { s->ground = true; s->sky = true; s->auth_3d_loaded = 0; - s->mat = mat4u_identity; + s->mat = mat4_identity; s->rot_y = 0.0; s->obj_set_hash = hash_murmurhash_empty; diff --git a/src/CRE/stage_modern.hpp b/src/CRE/stage_modern.hpp index d6b862ef..ac3dabf5 100644 --- a/src/CRE/stage_modern.hpp +++ b/src/CRE/stage_modern.hpp @@ -20,7 +20,7 @@ struct stage_modern { bool ground; bool sky; bool auth_3d_loaded; - mat4u mat; + mat4 mat; float_t rot_y; uint32_t obj_set_hash; @@ -48,7 +48,7 @@ namespace stage_detail { bool field_FB2; bool field_FB3; bool field_FB4; - mat4u mat; + mat4 mat; float_t field_FF8; void* data; @@ -91,7 +91,6 @@ extern bool task_stage_modern_load(const char* name); extern void task_stage_modern_set_data(void* data, object_database* obj_db, texture_database* tex_db, stage_database* stage_data); extern void task_stage_modern_set_mat(mat4* mat); -extern void task_stage_modern_set_mat(mat4u* mat); extern void task_stage_modern_set_stage(task_stage_modern_info* stg_info); extern void task_stage_modern_set_stage_hash(uint32_t stage_hash, stage_data_modern* stg_data); extern void task_stage_modern_set_stage_hashes(std::vector* stage_hashes, diff --git a/src/CRE/task_effect.cpp b/src/CRE/task_effect.cpp index 24eb93c5..2fc6ff7a 100644 --- a/src/CRE/task_effect.cpp +++ b/src/CRE/task_effect.cpp @@ -345,7 +345,7 @@ void TaskEffectFogAnim::Data::Reset() { field_28 = 0; field_2C = 0; field_30 = 0; - field_34 = vec4u_identity; + field_34 = vec4_identity; } TaskEffectFogAnim::TaskEffectFogAnim() { diff --git a/src/CRE/texture.cpp b/src/CRE/texture.cpp index 4f955189..09e0aac7 100644 --- a/src/CRE/texture.cpp +++ b/src/CRE/texture.cpp @@ -36,6 +36,7 @@ texture_id::texture_id(uint8_t id, uint32_t index) : id(id), index(index) { texture::texture() : init_count(), flags(), width(), height(), tex(), target(), internal_format(), max_mipmap_level(), size() { + } texture* texture_init(texture_id id) { diff --git a/src/DivaGL/DivaGL.vcxproj b/src/DivaGL/DivaGL.vcxproj index 88c70149..f2c6038f 100644 --- a/src/DivaGL/DivaGL.vcxproj +++ b/src/DivaGL/DivaGL.vcxproj @@ -259,7 +259,7 @@ del "$(SolutionDir)bin\$(TargetName).lib" true FastCall CompileAsCpp - MultiThreadedDebug + MultiThreaded /Gw %(AdditionalOptions) $(IntDir)/%(RelativeDir) Speed @@ -297,7 +297,7 @@ del "$(SolutionDir)bin\$(TargetName).lib" true FastCall CompileAsCpp - MultiThreadedDebug + MultiThreaded /Gw %(AdditionalOptions) $(IntDir)/%(RelativeDir) Speed diff --git a/src/DivaGL/bone_data.cpp b/src/DivaGL/bone_data.cpp index 162beda3..2e58bea3 100644 --- a/src/DivaGL/bone_data.cpp +++ b/src/DivaGL/bone_data.cpp @@ -93,14 +93,14 @@ static bone_data* bone_data_init(bone_data* bone) { bone->ik_target = vec3_null; bone->trans = vec3_null; for (int32_t i = 0; i < 2; i++) - bone->rot_mat[i] = mat4u_null; + bone->rot_mat[i] = mat4_null; for (int32_t i = 0; i < 2; i++) bone->trans_prev[i] = vec3_null; for (int32_t i = 0; i < 2; i++) for (int32_t j = 0; j < 3; j++) - bone->rot_mat_prev[i][j] = mat4u_null; + bone->rot_mat_prev[i][j] = mat4_null; bone->pole_target_mat = 0; bone->parent_mat = 0; @@ -816,7 +816,7 @@ static void sub_140414900(struc_308* a1, mat4* mat) { a1->field_8C = true; } else { - a1->mat = mat4u_identity; + a1->mat = mat4_identity; a1->field_8C = false; } } @@ -1234,12 +1234,12 @@ static void bone_data_mult_0(bone_data* a1, int32_t skeleton_select) { if (a1->type == BONE_DATABASE_BONE_POSITION) { mat4_translate_mult(&mat, a1->trans.x, a1->trans.y, a1->trans.z, &mat); - a1->rot_mat[0] = mat4u_identity; + a1->rot_mat[0] = mat4_identity; } else if (a1->type == BONE_DATABASE_BONE_TYPE_1) { mat4_mult_vec3_inv_trans(&mat, &a1->trans, &a1->trans); mat4_translate_mult(&mat, a1->trans.x, a1->trans.y, a1->trans.z, &mat); - a1->rot_mat[0] = mat4u_identity; + a1->rot_mat[0] = mat4_identity; } else { mat4 rot_mat; @@ -1310,7 +1310,7 @@ void bone_data_mult_1(bone_data* a1, mat4* parent_mat, bone_data* a3, bool a4) { mat4_transpose(&rot_mat, &a1->rot_mat[0]); } else - a1->rot_mat[0] = mat4u_identity; + a1->rot_mat[0] = mat4_identity; } } @@ -1382,7 +1382,7 @@ void bone_data_mult_2(rob_chara_bone_data* rob_bone_data, mat4* mat) { static void sub_140413EB0(struc_308* a1) { a1->field_8C = false; a1->field_4C = a1->mat; - a1->mat = mat4u_identity; + a1->mat = mat4_identity; } static void sub_1404117F0(motion_blend_mot* a1) { @@ -1409,9 +1409,9 @@ static void sub_14040FBF0(motion_blend_mot* a1, float_t a2) { mat4_transpose(&b_kl_hara_etc->rot_mat[0], &mat); mat4_mult(&mat, &rot_mat, &rot_mat); mat4_transpose(&rot_mat, &b_n_hara_cp->rot_mat[0]); - b_kg_hara_y->rot_mat[0] = mat4u_identity; - b_kl_hara_xz->rot_mat[0] = mat4u_identity; - b_kl_hara_etc->rot_mat[0] = mat4u_identity; + b_kg_hara_y->rot_mat[0] = mat4_identity; + b_kl_hara_xz->rot_mat[0] = mat4_identity; + b_kl_hara_etc->rot_mat[0] = mat4_identity; float_t v8 = a1->field_4F8.field_C0; float_t v9 = a1->field_4F8.field_C4; @@ -2128,8 +2128,8 @@ static void bone_data_parent_reset(bone_data_parent* a1) { static void sub_140413470(struc_308* a1) { a1->field_0 = 0; a1->field_8 = 0; - a1->mat = mat4u_identity; - a1->field_4C = mat4u_identity; + a1->mat = mat4_identity; + a1->field_4C = mat4_identity; a1->field_8C = false; a1->rot_y = 0.0f; a1->prev_rot_y = 0.0f; @@ -2221,7 +2221,7 @@ static void mot_blend_reset(mot_blend* a1) { static void sub_1404198D0(struc_258* a1) { a1->field_0 = 0; - a1->field_8 = mat4u_identity; + a1->field_8 = mat4_identity; a1->field_48.field_0 = 0.0f; a1->field_48.field_4 = 0.0f; a1->field_48.field_8 = 0.0f; @@ -2255,8 +2255,8 @@ static void sub_1404198D0(struc_258* a1) { a1->field_B0 = 0.0f; a1->field_B4 = vec3_null; a1->field_C0 = vec3_null; - a1->field_CC = mat4u_identity; - a1->field_10C = mat4u_identity; + a1->field_CC = mat4_identity; + a1->field_10C = mat4_identity; a1->field_14C = 0; a1->field_150 = 0; a1->field_158 = 0.0f; @@ -3083,7 +3083,7 @@ static void bone_data_parent_load_bone_indices_from_mot(bone_data_parent* a1, mo static void sub_140413C30(struc_308* a1) { a1->field_8C = false; a1->field_4C = a1->mat; - a1->mat = mat4u_identity; + a1->mat = mat4_identity; } static void motion_blend_mot_load_file(motion_blend_mot* a1, @@ -3709,7 +3709,7 @@ static void rob_osage_node_data_init(rob_osage_node_data *node_data) { node_data->normal_ref.d = 0; node_data->normal_ref.l = 0; node_data->normal_ref.r = 0; - node_data->normal_ref.mat = mat4u_identity; + node_data->normal_ref.mat = mat4_identity; } static void rob_osage_node_init(rob_osage_node* node) { @@ -3738,7 +3738,7 @@ static void rob_osage_node_init(rob_osage_node* node) { node->data_ptr = &node->data; node->opd_data.end = node->opd_data.begin; sub_14021DCC0(&node->opd_data, 3); - node->mat = mat4u_null; + node->mat = mat4_null; } static void skin_param_init(skin_param* skp) { @@ -3788,7 +3788,7 @@ static void rob_osage_init(rob_osage* rob_osg) { rob_osg->set_external_force = false; rob_osg->external_force = vec3_null; rob_osg->parent_mat_ptr = 0; - rob_osg->parent_mat = mat4u_null; + rob_osg->parent_mat = mat4_null; } static void rob_osage_node_free(rob_osage_node* node) { diff --git a/src/DivaGL/bone_data.hpp b/src/DivaGL/bone_data.hpp index 2124abdf..3f74853c 100644 --- a/src/DivaGL/bone_data.hpp +++ b/src/DivaGL/bone_data.hpp @@ -1745,7 +1745,7 @@ struct rob_chara_data_miku_rot { vec3 field_48; vec3 field_54; vec3 field_60; - mat4u field_6C; + mat4 field_6C; }; struct rob_chara_adjust_data { @@ -1759,7 +1759,7 @@ struct rob_chara_adjust_data { bool offset_z; bool get_global_trans; vec3 trans; - mat4u mat; + mat4 mat; float_t left_hand_scale; float_t right_hand_scale; float_t left_hand_scale_default; @@ -1827,8 +1827,8 @@ struct struc_209 { int32_t field_6C; int32_t field_70; int32_t field_74; - mat4u field_78[27]; - mat4u field_738[27]; + mat4 field_78[27]; + mat4 field_738[27]; struc_195 field_DF8[27]; struc_195 field_1230[27]; struc_195 field_1668[27]; @@ -2701,9 +2701,9 @@ struct bone_data { vec3 rotation; vec3 ik_target; vec3 trans; - mat4u rot_mat[3]; + mat4 rot_mat[3]; vec3 trans_prev[2]; - mat4u rot_mat_prev[3][2]; + mat4 rot_mat_prev[3][2]; mat4* pole_target_mat; mat4* parent_mat; bone_node* node; @@ -2758,10 +2758,10 @@ struct MotionBlendCross { MotionBlend base; bool field_20; bool field_21; - mat4u field_24; - mat4u field_64; - mat4u field_A4; - mat4u field_E4; + mat4 field_24; + mat4 field_64; + mat4 field_A4; + mat4 field_E4; }; struct MotionBlendFreeze { @@ -2772,10 +2772,10 @@ struct MotionBlendFreeze { float_t field_28; float_t field_2C; int32_t field_30; - mat4u field_34; - mat4u field_74; - mat4u rot_y; - mat4u field_F4; + mat4 field_34; + mat4 field_74; + mat4 rot_y; + mat4 field_F4; }; struct MotionBlendCombine { @@ -2855,7 +2855,7 @@ struct struc_243 { struct struc_258 { vector_old_bone_data* field_0; - mat4u field_8; + mat4 field_8; struc_241 field_48; uint8_t field_8C; uint8_t field_8D; @@ -2873,8 +2873,8 @@ struct struc_258 { float_t field_B0; vec3 field_B4; vec3 field_C0; - mat4u field_CC; - mat4u field_10C; + mat4 field_CC; + mat4 field_10C; bool field_14C; float_t field_150; float_t field_154; @@ -2939,8 +2939,8 @@ struct struc_308 { int32_t field_0; int32_t field_4; uint8_t field_8; - mat4u mat; - mat4u field_4C; + mat4 mat; + mat4 field_4C; bool field_8C; vec3 field_90; vec3 field_9C; @@ -3148,7 +3148,7 @@ struct obj_skin_block_cloth { uint32_t count; uint32_t field_10; int32_t field_14; - mat4u* field_18; + mat4* field_18; struc_230* field_1C; struc_251* field_20; uint16_t* field_24; @@ -3269,7 +3269,7 @@ struct rob_osage_node_data_normal_ref { rob_osage_node* d; rob_osage_node* l; rob_osage_node* r; - mat4u mat; + mat4 mat; }; struct skin_param_hinge { @@ -3329,7 +3329,7 @@ struct rob_osage_node { float_t child_length; bone_node* bone_node_ptr; mat4* bone_node_mat; - mat4u mat; + mat4 mat; rob_osage_node* sibling_node; float_t distance; vec3 field_94; @@ -3426,7 +3426,7 @@ struct rob_osage { int32_t yz_order; int32_t field_1EBC; mat4* parent_mat_ptr; - mat4u parent_mat; + mat4 parent_mat; float_t move_cancel; bool field_1F0C; bool osage_reset; @@ -3726,7 +3726,7 @@ struct obj_mesh { union obj_material_shader { char name[8]; - aft_shader_enum index; + shader_enum index; }; struct obj_material_shader_flags { @@ -3751,7 +3751,7 @@ struct obj_material_texture { int32_t texture_flags; char shader_name[8]; float_t weight; - mat4u tex_coord_mat; + mat4 tex_coord_mat; float_t unk[8]; }; @@ -3764,10 +3764,10 @@ struct obj_material { }; obj_material_texture textures[8]; int32_t blend_flags; - vec4u diffuse; - vec4u ambient; - vec4u specular; - vec4u emission; + vec4 diffuse; + vec4 ambient; + vec4 specular; + vec4 emission; float_t shininess; float_t intensity; obj_bounding_sphere reserved_sphere; @@ -3781,7 +3781,7 @@ struct obj_material_data { obj_material material; }; -struct aft_obj { +struct obj { uint32_t field_0; uint32_t field_4; obj_bounding_sphere bounding_sphere; @@ -3848,7 +3848,7 @@ struct obj_skin_ex_data { struct obj_skin { uint32_t* bone_ids; - mat4u* bone_matrices; + mat4* bone_matrices; const char** bone_names; obj_skin_ex_data* ex_data; uint32_t bone_count; @@ -3884,7 +3884,7 @@ struct obj_set { uint32_t signature; uint32_t objects_count; uint32_t max_object_id; - aft_obj** objects; + obj** objects; obj_skin** object_skins; const char** object_names; uint32_t* object_ids; @@ -4082,13 +4082,13 @@ struct rob_chara_item_equip { item_id field_D4; bool disable_update; int32_t field_DC; - vec4u texture_color_coeff; + vec4 texture_color_coeff; float_t wet; float_t wind_strength; bool chara_color; bool npr_flag; - mat4u mat; - mat4u field_13C[30]; + mat4 mat; + mat4 field_13C[30]; int32_t field_8BC; int32_t field_8C0; int32_t field_8C4; diff --git a/src/DivaGL/inject.cpp b/src/DivaGL/inject.cpp index 6416be1d..84171713 100644 --- a/src/DivaGL/inject.cpp +++ b/src/DivaGL/inject.cpp @@ -63,9 +63,9 @@ uint64_t inject_uint64_t(void* address, uint64_t data) { } static patch_struct patch_data[] = { - { (void*)0x00000001405E4CE0, (uint64_t)&aft_shader_set, }, - { (void*)0x00000001405E4FC0, (uint64_t)&aft_shader_load_all_shaders, }, - { (void*)0x00000001405E4B50, (uint64_t)&aft_shader_bind, }, + { (void*)0x00000001405E4CE0, (uint64_t)&shader_set, }, + { (void*)0x00000001405E4FC0, (uint64_t)&shader_load_all_shaders, }, + { (void*)0x00000001405E4B50, (uint64_t)&shader_bind, }, { (void*)0x00000001401D3860, (uint64_t)&printf_proxy, }, { (void*)0x00000001400DE640, (uint64_t)&printf_proxy, }, //{ (void*)0x0000000140507210, (uint64_t)&rob_chara_reset_data, }, @@ -91,9 +91,6 @@ static patch_struct patch_data[] = { static uint64_t shader_bind_func_orig_data[6]; -extern bool toggle1[10]; -extern bool toggle2[10]; - void inject_patches() { uint8_t buf[12]; buf[0] = 0x48; @@ -111,17 +108,17 @@ void inject_patches() { glutMainLoop = (void (*)())inject_uint64_t((void*)0x0000000140966008, (uint64_t)&gl_get_func_pointers); shader_bind_func_orig_data[0] = inject_uint64_t( - (void*)&shader_name_bind_func_table[0].bind_func, (uint64_t)&aft_shader_bind_blinn); + (void*)&shader_name_bind_func_table[0].bind_func, (uint64_t)&shader_bind_blinn); shader_bind_func_orig_data[1] = inject_uint64_t( - (void*)&shader_name_bind_func_table[1].bind_func, (uint64_t)&aft_shader_bind_cloth); + (void*)&shader_name_bind_func_table[1].bind_func, (uint64_t)&shader_bind_cloth); shader_bind_func_orig_data[2] = inject_uint64_t( - (void*)&shader_name_bind_func_table[2].bind_func, (uint64_t)&aft_shader_bind_hair); + (void*)&shader_name_bind_func_table[2].bind_func, (uint64_t)&shader_bind_hair); shader_bind_func_orig_data[3] = inject_uint64_t( - (void*)&shader_name_bind_func_table[3].bind_func, (uint64_t)&aft_shader_bind_membrane); + (void*)&shader_name_bind_func_table[3].bind_func, (uint64_t)&shader_bind_membrane); shader_bind_func_orig_data[4] = inject_uint64_t( - (void*)&shader_name_bind_func_table[4].bind_func, (uint64_t)&aft_shader_bind_eye_ball); + (void*)&shader_name_bind_func_table[4].bind_func, (uint64_t)&shader_bind_eye_ball); shader_bind_func_orig_data[5] = inject_uint64_t( - (void*)&shader_name_bind_func_table[5].bind_func, (uint64_t)&aft_shader_bind_tone_map); + (void*)&shader_name_bind_func_table[5].bind_func, (uint64_t)&shader_bind_tone_map); } void inject_restore() { @@ -131,8 +128,8 @@ void inject_restore() { free(data); } - inject_uint64_t((void*)0x0000000140966008, (uint64_t)glutMainLoop); + inject_uint64_t((void*)0x0000000140966008, (uint64_t)glutMainLoop); - for (int32_t i = 0; i < 6; i++) - inject_uint64_t(shader_name_bind_func_table[i].bind_func, shader_bind_func_orig_data[i]); + for (int32_t i = 0; i < 6; i++) + inject_uint64_t(shader_name_bind_func_table[i].bind_func, shader_bind_func_orig_data[i]); } diff --git a/src/DivaGL/shader_table.cpp b/src/DivaGL/shader_table.cpp index 316093e9..b6fc8908 100644 --- a/src/DivaGL/shader_table.cpp +++ b/src/DivaGL/shader_table.cpp @@ -4,8 +4,8 @@ */ #include "shader_table.hpp" -#include "gl.hpp" #include "../KKdLib/mat.hpp" +#include "gl.hpp" enum uniform_name { U_NONE = 0x00, @@ -82,15 +82,15 @@ enum uniform_name { U_INVALID = 0xFFFFFFFF, }; -typedef struct uniform_array { +struct uniform_array { int32_t array[70]; -} uniform_array; +}; extern uniform_array* uniform; -aft_shader* shaders = (aft_shader*)0x000000014CC57C10; -aft_shader_table_struct* aft_shader_table = (aft_shader_table_struct*)0x0000000140A41D20; -aft_shader_bind_func* shader_name_bind_func_table = (aft_shader_bind_func*)0x0000000140A40F50; +shader* shaders = (shader*)0x000000014CC57C10; +shader_table_struct* shader_table = (shader_table_struct*)0x0000000140A41D20; +shader_bind_func* shader_name_bind_func_table = (shader_bind_func*)0x0000000140A40F50; uniform_array* uniform = (uniform_array*)0x000000014CC57AF0; int32_t* current_vp = (int32_t*)0x000000014CC587B0; int32_t* current_fp = (int32_t*)0x000000014CC587B4; @@ -102,9 +102,9 @@ typedef void (GLAPIENTRY* PFNGLPROGRAMLOCALPARAMETER4FARBPROC) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); typedef void (GLAPIENTRY* PFNGLGENPROGRAMSARBPROC) (GLsizei n, GLuint* programs); -void FASTCALL aft_shader_set(aft_shader_enum name) { - if (name == aft_shader_enum::SHADER_FFP) { - aft_shader_unbind(); +void FASTCALL shader_set(shader_enum name) { + if (name == shader_enum::SHADER_FFP) { + shader_unbind(); return; } @@ -113,32 +113,32 @@ void FASTCALL aft_shader_set(aft_shader_enum name) { _glProgramEnvParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 24, (float_t)uniform->array[U_TEXTURE_BLEND], 0.0f, 0.0f, 0.0f); - aft_shader* shad = &shaders[(size_t)name]; - void (FASTCALL * bind_func)(aft_shader*) = (void (*)(aft_shader*))shad->bind_func; + shader* shad = &shaders[(size_t)name]; + void (FASTCALL * bind_func)(shader*) = (void (*)(shader*))shad->bind_func; if (bind_func) bind_func(shad); else - aft_shader_bind(shad, shad->subs->sub_name); + shader_bind(shad, shad->subs->sub_name); } -void FASTCALL aft_shader_bind_blinn(aft_shader* shad) { - aft_shader_bind(shad, uniform->array[U_NORMAL] - ? aft_shader_sub_enum::BLINN_FRAG : aft_shader_sub_enum::BLINN_VERT); +void FASTCALL shader_bind_blinn(shader* shad) { + shader_bind(shad, uniform->array[U_NORMAL] + ? shader_sub_enum::BLINN_FRAG : shader_sub_enum::BLINN_VERT); } -void FASTCALL aft_shader_bind_cloth(aft_shader* shad) { - aft_shader_bind(shad, uniform->array[U_NPR] ? aft_shader_sub_enum::CLOTH_NPR1 - : (uniform->array[U_ANISO] ? aft_shader_sub_enum::CLOTH_ANISO : aft_shader_sub_enum::CLOTH_DEFAULT)); +void FASTCALL shader_bind_cloth(shader* shad) { + shader_bind(shad, uniform->array[U_NPR] ? shader_sub_enum::CLOTH_NPR1 + : (uniform->array[U_ANISO] ? shader_sub_enum::CLOTH_ANISO : shader_sub_enum::CLOTH_DEFAULT)); } -void FASTCALL aft_shader_bind_hair(aft_shader* shad) { - aft_shader_bind(shad, uniform->array[U_NPR] ? aft_shader_sub_enum::HAIR_NPR1 - : (uniform->array[U_ANISO] ? aft_shader_sub_enum::HAIR_ANISO : aft_shader_sub_enum::HAIR_DEFAULT)); +void FASTCALL shader_bind_hair(shader* shad) { + shader_bind(shad, uniform->array[U_NPR] ? shader_sub_enum::HAIR_NPR1 + : (uniform->array[U_ANISO] ? shader_sub_enum::HAIR_ANISO : shader_sub_enum::HAIR_DEFAULT)); } -void FASTCALL aft_shader_bind_membrane(aft_shader* shad) { +void FASTCALL shader_bind_membrane(shader* shad) { uniform->array[U_MEMBRANE] = 3; - if (aft_shader_bind(shad, aft_shader_sub_enum::MEMBRANE) < 0) + if (shader_bind(shad, shader_sub_enum::MEMBRANE) < 0) return; uint32_t(FASTCALL * sub_140192E00)() = (uint32_t(*)())0x0000000140192E00; @@ -155,9 +155,9 @@ void FASTCALL aft_shader_bind_membrane(aft_shader* shad) { _glProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 10, vec.x, vec.y, vec.z, 0.0); } -void FASTCALL aft_shader_bind_eye_ball(aft_shader* shader) { +void FASTCALL shader_bind_eye_ball(shader* shader) { uniform->array[U18] = 0; - if (aft_shader_bind(&shaders[(size_t)aft_shader_enum::_GLASEYE], aft_shader_sub_enum::GLASS_EYE) >= 0) { + if (shader_bind(&shaders[(size_t)shader_enum::_GLASEYE], shader_sub_enum::GLASS_EYE) >= 0) { float_t* glass_eye = (float_t*)0x0000000140CA2D70; void (FASTCALL * glass_eye_calc)(float_t * glass_eye) = (void (*)(float_t*))0x00000001405E53D0; void (FASTCALL * glass_eye_set)(float_t * glass_eye) = (void (*)(float_t*))0x00000001405E4750; @@ -166,24 +166,24 @@ void FASTCALL aft_shader_bind_eye_ball(aft_shader* shader) { } } -void FASTCALL aft_shader_bind_tone_map(aft_shader* shader) { - aft_shader_bind(shader, uniform->array[U_NPR] == 1 - ? aft_shader_sub_enum::TONEMAP_NPR1 : aft_shader_sub_enum::TONEMAP); +void FASTCALL shader_bind_tone_map(shader* shader) { + shader_bind(shader, uniform->array[U_NPR] == 1 + ? shader_sub_enum::TONEMAP_NPR1 : shader_sub_enum::TONEMAP); } -int32_t FASTCALL aft_shader_bind(aft_shader* shader, aft_shader_sub_enum name) { +int32_t FASTCALL shader_bind(shader* shader, shader_sub_enum name) { int32_t num_sub = shader->num_sub; int32_t subshader_index = 0; if (num_sub < 1) return -1; - for (aft_shader_sub* i = shader->subs; i->sub_name != name; i++) { + for (shader_sub* i = shader->subs; i->sub_name != name; i++) { subshader_index++; if (subshader_index >= num_sub) return -1; } - aft_shader_sub* subshader = &shader->subs[subshader_index]; + shader_sub* subshader = &shader->subs[subshader_index]; if (!subshader) return -1; @@ -223,7 +223,7 @@ int32_t FASTCALL aft_shader_bind(aft_shader* shader, aft_shader_sub_enum name) { return 0; } -void FASTCALL aft_shader_unbind() { +void FASTCALL shader_unbind() { if (current_vp) _glDisable(GL_VERTEX_PROGRAM_ARB); if (current_fp) @@ -232,24 +232,24 @@ void FASTCALL aft_shader_unbind() { current_vp = 0; } -void FASTCALL aft_shader_load_all_shaders() { +void FASTCALL shader_load_all_shaders() { PFNGLGENPROGRAMSARBPROC _glGenProgramsARB = *(PFNGLGENPROGRAMSARBPROC*)0x00000001411A4A70; void (FASTCALL * shader_load_program_file)(GLuint program, const char* file_name, bool vertex_program) = (void (*)(GLuint, const char*, bool))0x00000001405E52D0; - aft_shader_table_struct* shaders_table = &aft_shader_table[(int32_t)aft_shader_enum::_BLINN]; - aft_shader* shader = &shaders[(int32_t)aft_shader_enum::_BLINN]; - int32_t curr_shader = (int32_t)aft_shader_enum::SHADER_END - 1; + shader_table_struct* shaders_table = &shader_table[(int32_t)shader_enum::_BLINN]; + shader* shader = &shaders[(int32_t)shader_enum::_BLINN]; + int32_t curr_shader = (int32_t)shader_enum::SHADER_END - 1; do { shader->name = shaders_table->name; shader->name_enum = shaders_table->name_enum; shader->num_sub = shaders_table->num_sub; int32_t num_sub = shaders_table->num_sub; - void* v9 = force_malloc(sizeof(aft_shader_sub) * num_sub + 8); + void* v9 = force_malloc(sizeof(shader_sub) * num_sub + 8); *(int64_t*)v9 = num_sub; - const aft_shader_sub_table_struct* sub = shaders_table->sub; - aft_shader_sub* subs = (aft_shader_sub*)((char*)v9 + 8); + const shader_sub_table_struct* sub = shaders_table->sub; + shader_sub* subs = (shader_sub*)((char*)v9 + 8); for (int32_t i = 0; i < num_sub; i++) subs[i] = { }; @@ -277,11 +277,11 @@ void FASTCALL aft_shader_load_all_shaders() { } shader->bind_func = 0; - aft_shader_bind_func* bind_func_table = shader_name_bind_func_table; - aft_shader_enum bind_func_name = aft_shader_enum::_BLINN; + shader_bind_func* bind_func_table = shader_name_bind_func_table; + shader_enum bind_func_name = shader_enum::_BLINN; while (shader->name_enum != bind_func_name) { bind_func_name = (++bind_func_table)->name; - if (bind_func_table->name == aft_shader_enum::SHADER_END) + if (bind_func_table->name == shader_enum::SHADER_END) break; } shader->bind_func = bind_func_table->bind_func; diff --git a/src/DivaGL/shader_table.hpp b/src/DivaGL/shader_table.hpp index 93322eb8..36335c50 100644 --- a/src/DivaGL/shader_table.hpp +++ b/src/DivaGL/shader_table.hpp @@ -7,7 +7,7 @@ #include "../KKdLib/default.hpp" -typedef enum aft_shader_sub_enum { +typedef enum shader_sub_enum { SHADER_SUB_FFP = 0, BLINN_VERT = 1, BLINN_FRAG = 2, @@ -76,9 +76,9 @@ typedef enum aft_shader_sub_enum { MOVIE = 65, IMGFILTER = 66, SPRITE = 67, -} aft_shader_sub_enum; +} shader_sub_enum; -typedef enum aft_shader_enum { +typedef enum shader_enum { SHADER_FFP = 0, _BLINN = 1, _ITEM = 2, @@ -142,10 +142,10 @@ typedef enum aft_shader_enum { _IMGFILT = 60, _SPRITE = 61, SHADER_END = 62, -} aft_shader_enum; +} shader_enum; -typedef struct aft_shader_sub_table_struct { - aft_shader_sub_enum sub_name; +typedef struct shader_sub_table_struct { + shader_sub_enum sub_name; int32_t padding; const int32_t* vp_unival_max; const int32_t* fp_unival_max; @@ -153,20 +153,20 @@ typedef struct aft_shader_sub_table_struct { int32_t num_fp; const char** vp; const char** fp; -} aft_shader_sub_table_struct; +} shader_sub_table_struct; -typedef struct aft_shader_table_struct { +typedef struct shader_table_struct { const char* name; - aft_shader_enum name_enum; + shader_enum name_enum; int32_t num_sub; - const aft_shader_sub_table_struct* sub; + const shader_sub_table_struct* sub; int32_t num_uniform; int32_t padding; int32_t* use_uniform; -} aft_shader_table_struct; +} shader_table_struct; -typedef struct aft_shader_sub { - aft_shader_sub_enum sub_name; +typedef struct shader_sub { + shader_sub_enum sub_name; int32_t padding; int32_t* vp_unival_max; int32_t* fp_unival_max; @@ -174,38 +174,38 @@ typedef struct aft_shader_sub { int32_t num_fp; int32_t* vp; int32_t* fp; -} aft_shader_sub; +} shader_sub; -typedef struct aft_shader { +typedef struct shader { const char* name; - aft_shader_enum name_enum; + shader_enum name_enum; int32_t num_sub; - aft_shader_sub* subs; + shader_sub* subs; int32_t num_uniform; int32_t padding; int32_t* use_uniform; void* bind_func; -} aft_shader; +} shader; -typedef struct aft_shader_bind_func { - aft_shader_enum name; +typedef struct shader_bind_func { + shader_enum name; int32_t padding; void* bind_func; -} aft_shader_bind_func; +} shader_bind_func; -extern aft_shader* shaders; -extern aft_shader_table_struct* aft_shader_table; -extern aft_shader_bind_func* shader_name_bind_func_table; +extern shader* shaders; +extern shader_table_struct* shader_table; +extern shader_bind_func* shader_name_bind_func_table; extern int32_t* current_vp; extern int32_t* current_fp; -extern void FASTCALL aft_shader_set(aft_shader_enum name); // 0x00000001405E4CE0 -extern void FASTCALL aft_shader_bind_blinn(aft_shader* shader); // 0x00000001405E4320 -extern void FASTCALL aft_shader_bind_cloth(aft_shader* shader); // 0x00000001405E4340 -extern void FASTCALL aft_shader_bind_hair(aft_shader* shader); // 0x00000001405E4370 -extern void FASTCALL aft_shader_bind_membrane(aft_shader* shader); // 0x00000001405E43A0 -extern void FASTCALL aft_shader_bind_eye_ball(aft_shader* shader); // 0x00000001405E4530 -extern void FASTCALL aft_shader_bind_tone_map(aft_shader* shader); // 0x00000001405E4580 -extern int32_t FASTCALL aft_shader_bind(aft_shader* shader, aft_shader_sub_enum name); // 0x00000001405E4B50 -extern void FASTCALL aft_shader_unbind(); // 0x00000001405E5660 -extern void FASTCALL aft_shader_load_all_shaders(); // 0x00000001405E4FC0 +extern void FASTCALL shader_set(shader_enum name); // 0x00000001405E4CE0 +extern void FASTCALL shader_bind_blinn(shader* shader); // 0x00000001405E4320 +extern void FASTCALL shader_bind_cloth(shader* shader); // 0x00000001405E4340 +extern void FASTCALL shader_bind_hair(shader* shader); // 0x00000001405E4370 +extern void FASTCALL shader_bind_membrane(shader* shader); // 0x00000001405E43A0 +extern void FASTCALL shader_bind_eye_ball(shader* shader); // 0x00000001405E4530 +extern void FASTCALL shader_bind_tone_map(shader* shader); // 0x00000001405E4580 +extern int32_t FASTCALL shader_bind(shader* shader, shader_sub_enum name); // 0x00000001405E4B50 +extern void FASTCALL shader_unbind(); // 0x00000001405E5660 +extern void FASTCALL shader_load_all_shaders(); // 0x00000001405E4FC0 diff --git a/src/KKdLib/a3da.cpp b/src/KKdLib/a3da.cpp index 45885675..2d664837 100644 --- a/src/KKdLib/a3da.cpp +++ b/src/KKdLib/a3da.cpp @@ -1535,7 +1535,7 @@ static void a3da_write_text(a3da* a, void** data, size_t* size, bool a3dc) { key_val_out_write(&kv, s, "blend_color", ml->blend_color); if (ml->flags & A3DA_MATERIAL_LIST_BLEND_COLOR) key_val_out_write(&kv, s, "glow_intensity", ml->glow_intensity); - kv.write(s, "hash_name", hash_string_murmurhash(&ml->name)); + kv.write(s, "hash_name", hash_string_murmurhash(ml->name)); if (ml->flags & A3DA_MATERIAL_LIST_BLEND_COLOR) key_val_out_write(&kv, s, "incandescence", ml->incandescence); kv.write(s, "name", ml->name); diff --git a/src/KKdLib/a3da.hpp b/src/KKdLib/a3da.hpp index 45c6d8a6..69e75a21 100644 --- a/src/KKdLib/a3da.hpp +++ b/src/KKdLib/a3da.hpp @@ -508,7 +508,7 @@ struct a3da { a3da_post_process post_process; a3da(); - ~a3da(); + virtual ~a3da(); void read(const char* path); void read(const wchar_t* path); diff --git a/src/KKdLib/database/auth_3d.cpp b/src/KKdLib/database/auth_3d.cpp index 40b67889..4ce0f7b7 100644 --- a/src/KKdLib/database/auth_3d.cpp +++ b/src/KKdLib/database/auth_3d.cpp @@ -115,7 +115,7 @@ bool auth_3d_database_file::load_file(void* data, const char* path, const char* return auth_3d_db->ready; } -auth_3d_database::auth_3d_database() : ready() { +auth_3d_database::auth_3d_database() { } @@ -123,10 +123,18 @@ auth_3d_database::~auth_3d_database() { } +void auth_3d_database::add(auth_3d_database_file* auth_3d_db_file) { + if (!auth_3d_db_file || !auth_3d_db_file->ready ) + return; + + auth_3d_database_load_categories(this, auth_3d_db_file, false); + auth_3d_database_load_uids(this, auth_3d_db_file, false); +} + int32_t auth_3d_database::get_category_index(const char* name) { uint32_t name_hash = hash_utf8_murmurhash(name); for (auth_3d_database_category i : category) - if (hash_string_murmurhash(&i.name) == name_hash) + if (i.name_hash == name_hash) return (int32_t)(&i - category.data()); return -1; } @@ -136,7 +144,7 @@ void auth_3d_database::get_category_uids(const char* name, std::vector& uint32_t name_hash = hash_utf8_murmurhash(name); for (auth_3d_database_category& i : category) - if (hash_string_murmurhash(&i.name) == name_hash) { + if (i.name_hash == name_hash) { uid = i.uid; return; } @@ -145,36 +153,14 @@ void auth_3d_database::get_category_uids(const char* name, std::vector& int32_t auth_3d_database::get_uid(const char* name) { uint32_t name_hash = hash_utf8_murmurhash(name); for (auth_3d_database_uid& i : uid) - if (hash_string_murmurhash(&i.name) == name_hash) + if (i.name_hash == name_hash) return (int32_t)(&i - uid.data()); return -1; } -void auth_3d_database::merge_mdata(auth_3d_database_file* base_auth_3d_db, - auth_3d_database_file* mdata_auth_3d_db) { - if (!base_auth_3d_db || !mdata_auth_3d_db - || !base_auth_3d_db->ready || !mdata_auth_3d_db->ready) - return; - - auth_3d_database_load_categories(this, base_auth_3d_db, false); - auth_3d_database_load_uids(this, base_auth_3d_db, false); - - auth_3d_database_load_categories(this, mdata_auth_3d_db, true); - auth_3d_database_load_uids(this, mdata_auth_3d_db, true); - - ready = true; -} - -void auth_3d_database::split_mdata(auth_3d_database_file* base_auth_3d_db, - auth_3d_database_file* mdata_auth_3d_db) { - if (!base_auth_3d_db || !mdata_auth_3d_db - || !ready || !base_auth_3d_db->ready) - return; - -} - auth_3d_database_uid::auth_3d_database_uid() : enabled(), org_uid(), size() { - + category_hash = hash_murmurhash_empty; + name_hash = hash_murmurhash_empty; } auth_3d_database_uid::~auth_3d_database_uid() { @@ -190,7 +176,7 @@ auth_3d_database_uid_file::~auth_3d_database_uid_file() { } auth_3d_database_category::auth_3d_database_category() { - + name_hash = hash_murmurhash_empty; } auth_3d_database_category::~auth_3d_database_category() { @@ -219,6 +205,7 @@ static void auth_3d_database_load_categories(auth_3d_database* auth_3d_db, auth_3d_database_category cat; cat.name = category_file[i]; + cat.name_hash = hash_string_murmurhash(cat.name); category.push_back(cat); } } @@ -263,7 +250,9 @@ static void auth_3d_database_load_uids(auth_3d_database* auth_3d_db, uid->enabled = true; uid->name = uid_file->value.substr(2, uid_file->value.size() - 2); + uid->name_hash = hash_string_murmurhash(uid->name); uid->category = uid_file->category; + uid->category_hash = hash_string_murmurhash(uid->category); } if (uid->enabled) { diff --git a/src/KKdLib/database/auth_3d.hpp b/src/KKdLib/database/auth_3d.hpp index 138d5c04..2d30df97 100644 --- a/src/KKdLib/database/auth_3d.hpp +++ b/src/KKdLib/database/auth_3d.hpp @@ -17,7 +17,9 @@ enum auth_3d_database_uid_flags { struct auth_3d_database_uid { bool enabled; std::string category; + uint32_t category_hash; std::string name; + uint32_t name_hash; int32_t org_uid; float_t size; @@ -38,6 +40,7 @@ struct auth_3d_database_uid_file { struct auth_3d_database_category { std::string name; + uint32_t name_hash; std::vector uid; auth_3d_database_category(); @@ -52,7 +55,7 @@ struct auth_3d_database_file { int32_t uid_max; auth_3d_database_file(); - ~auth_3d_database_file(); + virtual ~auth_3d_database_file(); void read(const char* path); void read(const wchar_t* path); @@ -65,19 +68,14 @@ struct auth_3d_database_file { }; struct auth_3d_database { - bool ready; - std::vector category; std::vector uid; auth_3d_database(); - ~auth_3d_database(); + virtual ~auth_3d_database(); + void add(auth_3d_database_file* auth_3d_db_file); int32_t get_category_index(const char* name); void get_category_uids(const char* name, std::vector& uid); int32_t get_uid(const char* name); - void merge_mdata(auth_3d_database_file* base_auth_3d_db, - auth_3d_database_file* mdata_auth_3d_db); - void split_mdata(auth_3d_database_file* base_auth_3d_db, - auth_3d_database_file* mdata_auth_3d_db); }; diff --git a/src/KKdLib/database/bone.cpp b/src/KKdLib/database/bone.cpp index ed3e3a77..d31127b5 100644 --- a/src/KKdLib/database/bone.cpp +++ b/src/KKdLib/database/bone.cpp @@ -197,7 +197,7 @@ bool bone_database::get_skeleton(const char* name, bone_database_skeleton** skel uint32_t name_hash = hash_utf8_murmurhash(name); for (bone_database_skeleton& i : this->skeleton) - if (hash_string_murmurhash(&i.name) == name_hash) { + if (hash_string_murmurhash(i.name) == name_hash) { *skeleton = &i; return true; } @@ -211,9 +211,9 @@ int32_t bone_database::get_skeleton_bone_index(const char* name, const char* bon uint32_t name_hash = hash_utf8_murmurhash(name); uint32_t bone_name_hash = hash_utf8_murmurhash(bone_name); for (bone_database_skeleton& i : skeleton) - if (hash_string_murmurhash(&i.name) == name_hash) { + if (hash_string_murmurhash(i.name) == name_hash) { for (bone_database_bone& j : i.bone) - if (hash_string_murmurhash(&j.name) == bone_name_hash) + if (hash_string_murmurhash(j.name) == bone_name_hash) return (int32_t)(&j - i.bone.data()); return -1; } @@ -230,7 +230,7 @@ bool bone_database::get_skeleton_bones(const char* name, std::vector** uint32_t name_hash = hash_utf8_murmurhash(name); for (bone_database_skeleton& i : skeleton) - if (hash_string_murmurhash(&i.name) == name_hash) { + if (hash_string_murmurhash(i.name) == name_hash) { *positions = &i.position; return true; } @@ -261,9 +261,9 @@ int32_t bone_database::get_skeleton_object_bone_index(const char* name, const ch uint32_t name_hash = hash_utf8_murmurhash(name); uint32_t bone_name_hash = hash_utf8_murmurhash(bone_name); for (bone_database_skeleton& i : skeleton) - if (hash_string_murmurhash(&i.name) == name_hash) { + if (hash_string_murmurhash(i.name) == name_hash) { for (std::string& j : i.object_bone) - if (hash_string_murmurhash(&j) == bone_name_hash) + if (hash_string_murmurhash(j) == bone_name_hash) return (int32_t)(&j - i.object_bone.data()); return -1; } @@ -280,7 +280,7 @@ bool bone_database::get_skeleton_object_bones(const char* name, std::vector skeleton; bone_database(); - ~bone_database(); + virtual ~bone_database(); void read(const char* path, bool modern); void read(const wchar_t* path, bool modern); diff --git a/src/KKdLib/database/item_table.hpp b/src/KKdLib/database/item_table.hpp index 887f0435..4a33a3c0 100644 --- a/src/KKdLib/database/item_table.hpp +++ b/src/KKdLib/database/item_table.hpp @@ -15,17 +15,17 @@ enum chara_index { CHARA_NONE = -1, - CHARA_MIKU = 0, - CHARA_RIN = 1, - CHARA_LEN = 2, - CHARA_LUKA = 3, - CHARA_NERU = 4, - CHARA_HAKU = 5, - CHARA_KAITO = 6, - CHARA_MEIKO = 7, - CHARA_SAKINE = 8, - CHARA_TETO = 9, - CHARA_MAX = 10, + CHARA_MIKU = 0x00, + CHARA_RIN = 0x01, + CHARA_LEN = 0x02, + CHARA_LUKA = 0x03, + CHARA_NERU = 0x04, + CHARA_HAKU = 0x05, + CHARA_KAITO = 0x06, + CHARA_MEIKO = 0x07, + CHARA_SAKINE = 0x08, + CHARA_TETO = 0x09, + CHARA_MAX = 0x0A, }; enum item_id { @@ -181,7 +181,7 @@ struct itm_table { std::vector dbgset; itm_table(); - ~itm_table(); + virtual ~itm_table(); void read(const char* path); void read(const wchar_t* path); diff --git a/src/KKdLib/database/motion.cpp b/src/KKdLib/database/motion.cpp index ea9e9628..e76b917c 100644 --- a/src/KKdLib/database/motion.cpp +++ b/src/KKdLib/database/motion.cpp @@ -10,18 +10,18 @@ #include "../hash.hpp" #include "../str_utils.hpp" -static void motion_database_read_inner(motion_database* mot_db, stream& s); -static void motion_database_write_inner(motion_database* mot_db, stream& s); +static void motion_database_file_read_inner(motion_database_file* mot_db, stream& s); +static void motion_database_file_write_inner(motion_database_file* mot_db, stream& s); -motion_database::motion_database() : ready() { +motion_database_file::motion_database_file() : ready() { } -motion_database::~motion_database() { +motion_database_file::~motion_database_file() { } -void motion_database::read(const char* path) { +void motion_database_file::read(const char* path) { if (!path) return; @@ -34,13 +34,13 @@ void motion_database::read(const char* path) { if (ff) { stream s; s.open(ff->data, ff->size); - motion_database_read_inner(this, s); + motion_database_file_read_inner(this, s); } } free(path_farc); } -void motion_database::read(const wchar_t* path) { +void motion_database_file::read(const wchar_t* path) { if (!path) return; @@ -53,22 +53,22 @@ void motion_database::read(const wchar_t* path) { if (ff) { stream s; s.open(ff->data, ff->size); - motion_database_read_inner(this, s); + motion_database_file_read_inner(this, s); } } free(path_farc); } -void motion_database::read(const void* data, size_t size) { +void motion_database_file::read(const void* data, size_t size) { if (!data || !size) return; stream s; s.open(data, size); - motion_database_read_inner(this, s); + motion_database_file_read_inner(this, s); } -void motion_database::write(const char* path) { +void motion_database_file::write(const char* path) { if (!path || !ready) return; @@ -79,13 +79,13 @@ void motion_database::write(const char* path) { stream s; s.open(); - motion_database_write_inner(this, s); + motion_database_file_write_inner(this, s); s.copy(&ff->data, &ff->size); f.write(path, FARC_COMPRESS_FArC, false); } -void motion_database::write(const wchar_t* path) { +void motion_database_file::write(const wchar_t* path) { if (!path || !ready) return; @@ -96,91 +96,82 @@ void motion_database::write(const wchar_t* path) { stream s; s.open(); - motion_database_write_inner(this, s); + motion_database_file_write_inner(this, s); s.copy(&ff->data, &ff->size); f.write(path, FARC_COMPRESS_FArC, false); } -void motion_database::write(void** data, size_t* size) { +void motion_database_file::write(void** data, size_t* size) { if (!data || !size || !ready) return; stream s; s.open(); - motion_database_write_inner(this, s); + motion_database_file_write_inner(this, s); s.copy(data, size); } -void motion_database::merge_mdata(motion_database* base_mot_db, - motion_database* mdata_mot_db) { - if (!base_mot_db || !mdata_mot_db - || !base_mot_db->ready || !mdata_mot_db->ready) +bool motion_database_file::load_file(void* data, const char* path, const char* file, uint32_t hash) { + size_t file_len = utf8_length(file); + + const char* t = strrchr(file, '.'); + if (t) + file_len = t - file; + + std::string s = path + std::string(file, file_len); + + motion_database_file* mot_db = (motion_database_file*)data; + mot_db->read(s.c_str()); + + return mot_db->ready; +} + +motion_database::motion_database() { + +} + +motion_database::~motion_database() { + +} + +void motion_database::add(motion_database_file* mot_db_file) { + if (!mot_db_file || !mot_db_file->ready) return; - bone_name = base_mot_db->bone_name; + bone_name = mot_db_file->bone_name; - motion_set.reserve(base_mot_db->motion_set.size()); + motion_set.reserve(mot_db_file->motion_set.size()); - for (motion_set_info& i : base_mot_db->motion_set) { - motion_set_info set_info; - set_info.id = i.id; - set_info.name = i.name; - set_info.name_hash = hash_string_murmurhash(&i.name); + for (motion_set_info_file& i : mot_db_file->motion_set) { + uint32_t name_hash = hash_string_murmurhash(i.name); - set_info.motion.reserve(i.motion.size()); - - for (motion_info& j : i.motion) { - motion_info info; - info.id = j.id; - info.name = j.name; - info.name_hash = hash_string_murmurhash(&j.name); - set_info.motion.push_back(info); - } - motion_set.push_back(set_info); - } - - for (motion_set_info& i : mdata_mot_db->motion_set) { - const char* name_str = i.name.c_str(); - size_t name_len = i.name.size(); - - motion_set_info* set_info_ptr = 0; + motion_set_info* set_info = 0; for (motion_set_info& j : motion_set) - if (!memcmp(name_str, j.name.c_str(), min(name_len, j.name.size()) + 1)) { - set_info_ptr = &j; + if (name_hash == j.name_hash) { + set_info = &j; break; } - motion_set_info set_info; - set_info.id = i.id; - set_info.name = i.name; - set_info.name_hash = hash_string_murmurhash(&i.name); + if (!set_info) { + motion_set.push_back({}); + set_info = &motion_set.back(); + } - set_info.motion.reserve(i.motion.size()); + set_info->id = i.id; + set_info->name = i.name; + set_info->name_hash = hash_string_murmurhash(set_info->name); - for (motion_info& j : i.motion) { + set_info->motion.reserve(i.motion.size()); + + for (motion_info_file& j : i.motion) { motion_info info; info.id = j.id; info.name = j.name; - info.name_hash = hash_string_murmurhash(&j.name); - set_info.motion.push_back(info); + info.name_hash = hash_string_murmurhash(info.name); + set_info->motion.push_back(info); } - - if (set_info_ptr) - *set_info_ptr = set_info; - else - motion_set.push_back(set_info); } - - ready = true; -} - -void motion_database::split_mdata(motion_database* base_mot_db, - motion_database* mdata_mot_db) { - if (!base_mot_db || !mdata_mot_db - || !ready || !base_mot_db->ready) - return; - } motion_set_info* motion_database::get_motion_set_by_id(uint32_t id) { @@ -323,38 +314,41 @@ const char* motion_database::get_motion_name(uint32_t id) { return 0; } -bool motion_database::load_file(void* data, const char* path, const char* file, uint32_t hash) { - size_t file_len = utf8_length(file); - - const char* t = strrchr(file, '.'); - if (t) - file_len = t - file; - - std::string s = path + std::string(file, file_len); - - motion_database* mot_db = (motion_database*)data; - mot_db->read(s.c_str()); - - return mot_db->ready; +motion_info_file::motion_info_file() { + id = (uint32_t)-1; } -motion_info::motion_info() : name_hash(hash_murmurhash_empty), id((uint32_t)-1) { +motion_info_file::~motion_info_file() { } +motion_set_info_file::motion_set_info_file() { + id = (uint32_t)-1; +} + +motion_set_info_file::~motion_set_info_file() { + +} + +motion_info::motion_info() { + name_hash = hash_murmurhash_empty; + id = (uint32_t)-1; +} + motion_info::~motion_info() { } -motion_set_info::motion_set_info() : name_hash(hash_murmurhash_empty), id((uint32_t)-1) { - +motion_set_info::motion_set_info() { + name_hash = hash_murmurhash_empty; + id = (uint32_t)-1; } motion_set_info::~motion_set_info() { } -static void motion_database_read_inner(motion_database* mot_db, stream& s) { +static void motion_database_file_read_inner(motion_database_file* mot_db, stream& s) { if (s.read_uint32_t() != 0x01) return; @@ -368,7 +362,7 @@ static void motion_database_read_inner(motion_database* mot_db, stream& s) { s.position_push(motion_sets_offset, SEEK_SET); for (uint32_t i = 0; i < motion_set_count; i++) { - motion_set_info& set_info = mot_db->motion_set[i]; + motion_set_info_file& set_info = mot_db->motion_set[i]; uint32_t name_offset = s.read_uint32_t(); uint32_t motion_name_offsets_offset = s.read_uint32_t(); @@ -376,15 +370,12 @@ static void motion_database_read_inner(motion_database* mot_db, stream& s) { uint32_t motion_ids_offset = s.read_uint32_t(); set_info.name = s.read_string_null_terminated_offset(name_offset); - set_info.name_hash = hash_string_murmurhash(&set_info.name); set_info.motion.resize(motion_count); s.position_push(motion_name_offsets_offset, SEEK_SET); - for (uint32_t j = 0; j < motion_count; j++) { + for (uint32_t j = 0; j < motion_count; j++) set_info.motion[j].name = s.read_string_null_terminated_offset(s.read_uint32_t()); - set_info.motion[j].name_hash = hash_string_murmurhash(&set_info.motion[j].name); - } s.position_pop(); s.position_push(motion_ids_offset, SEEK_SET); @@ -409,7 +400,7 @@ static void motion_database_read_inner(motion_database* mot_db, stream& s) { mot_db->ready = true; } -static void motion_database_write_inner(motion_database* mot_db, stream& s) { +static void motion_database_file_write_inner(motion_database_file* mot_db, stream& s) { s.write_int32_t(0); s.write_int32_t(0); s.write_int32_t(0); @@ -426,15 +417,15 @@ static void motion_database_write_inner(motion_database* mot_db, stream& s) { s.align_write(0x20); size_t size = 0; - for (motion_set_info& i : mot_db->motion_set) + for (motion_set_info_file& i : mot_db->motion_set) size += i.name.size() + 1; int64_t motion_set_name_offset = s.get_position(); s.write(size); size = 0; - for (motion_set_info& i : mot_db->motion_set) - for (motion_info& j : i.motion) + for (motion_set_info_file& i : mot_db->motion_set) + for (motion_info_file& j : i.motion) size += j.name.size() + 1; int64_t motion_name_offset = s.get_position(); @@ -443,19 +434,19 @@ static void motion_database_write_inner(motion_database* mot_db, stream& s) { int64_t motion_names_offset = s.get_position(); size = 0; - for (motion_set_info& i : mot_db->motion_set) + for (motion_set_info_file& i : mot_db->motion_set) size += 0x04 * i.motion.size(); s.write(size); s.align_write(0x20); int64_t motion_ids_offset = s.get_position(); - for (motion_set_info& i : mot_db->motion_set) - for (motion_info& j : i.motion) + for (motion_set_info_file& i : mot_db->motion_set) + for (motion_info_file& j : i.motion) s.write_uint32_t(j.id); s.align_write(0x20); int64_t motion_set_ids_offset = s.get_position(); - for (motion_set_info& i : mot_db->motion_set) + for (motion_set_info_file& i : mot_db->motion_set) s.write_uint32_t(i.id); int64_t bone_name_offset = s.get_position(); @@ -466,13 +457,13 @@ static void motion_database_write_inner(motion_database* mot_db, stream& s) { s.align_write(0x20); s.position_push(motion_set_name_offset, SEEK_SET); - for (motion_set_info& i : mot_db->motion_set) + for (motion_set_info_file& i : mot_db->motion_set) s.write_string_null_terminated(i.name); s.position_pop(); s.position_push(motion_name_offset, SEEK_SET); - for (motion_set_info& i : mot_db->motion_set) - for (motion_info& j : i.motion) + for (motion_set_info_file& i : mot_db->motion_set) + for (motion_info_file& j : i.motion) s.write_string_null_terminated(j.name); s.position_pop(); @@ -486,15 +477,15 @@ static void motion_database_write_inner(motion_database* mot_db, stream& s) { s.align_write(0x20); s.position_push(motion_names_offset, SEEK_SET); - for (motion_set_info& i : mot_db->motion_set) - for (motion_info& j : i.motion) { + for (motion_set_info_file& i : mot_db->motion_set) + for (motion_info_file& j : i.motion) { s.write_uint32_t((uint32_t)motion_name_offset); motion_name_offset += j.name.size() + 1; } s.position_pop(); s.position_push(motion_sets_offset, SEEK_SET); - for (motion_set_info& i : mot_db->motion_set) { + for (motion_set_info_file& i : mot_db->motion_set) { s.write_uint32_t((uint32_t)motion_set_name_offset); s.write_uint32_t((uint32_t)motion_names_offset); s.write_uint32_t((uint32_t)i.motion.size()); diff --git a/src/KKdLib/database/motion.hpp b/src/KKdLib/database/motion.hpp index 472ebbdf..db631648 100644 --- a/src/KKdLib/database/motion.hpp +++ b/src/KKdLib/database/motion.hpp @@ -9,6 +9,23 @@ #include #include "../default.hpp" +struct motion_info_file { + std::string name; + uint32_t id; + + motion_info_file(); + ~motion_info_file(); +}; + +struct motion_set_info_file { + std::string name; + uint32_t id; + std::vector motion; + + motion_set_info_file(); + ~motion_set_info_file(); +}; + struct motion_info { std::string name; uint32_t name_hash; @@ -28,14 +45,14 @@ struct motion_set_info { ~motion_set_info(); }; -struct motion_database { +struct motion_database_file { bool ready; std::vector bone_name; - std::vector motion_set; + std::vector motion_set; - motion_database(); - ~motion_database(); + motion_database_file(); + virtual ~motion_database_file(); void read(const char* path); void read(const wchar_t* path); @@ -44,8 +61,17 @@ struct motion_database { void write(const wchar_t* path); void write(void** data, size_t* size); - void merge_mdata(motion_database* base_mot_db, motion_database* mdata_mot_db); - void split_mdata(motion_database* base_mot_db, motion_database* mdata_mot_db); + static bool load_file(void* data, const char* path, const char* file, uint32_t hash); +}; + +struct motion_database { + std::vector bone_name; + std::vector motion_set; + + motion_database(); + virtual ~motion_database(); + + void add(motion_database_file* mot_db_file); motion_set_info* get_motion_set_by_id(uint32_t id); motion_set_info* get_motion_set_by_name(const char* name); @@ -59,6 +85,4 @@ struct motion_database { motion_info* get_motion_by_name(const char* name); uint32_t get_motion_id(const char* name); const char* get_motion_name(uint32_t id); - - static bool load_file(void* data, const char* path, const char* file, uint32_t hash); }; diff --git a/src/KKdLib/database/object.cpp b/src/KKdLib/database/object.cpp index b8c233e3..87ebc3ea 100644 --- a/src/KKdLib/database/object.cpp +++ b/src/KKdLib/database/object.cpp @@ -11,10 +11,10 @@ #include "../sort.hpp" #include "../str_utils.hpp" -static void object_database_classic_read_inner(object_database* obj_db, stream& s); -static void object_database_classic_write_inner(object_database* obj_db, stream& s); -static void object_database_modern_read_inner(object_database* obj_db, stream& s, uint32_t header_length); -static void object_database_modern_write_inner(object_database* obj_db, stream& s); +static void object_database_file_classic_read_inner(object_database_file* obj_db, stream& s); +static void object_database_file_classic_write_inner(object_database_file* obj_db, stream& s); +static void object_database_file_modern_read_inner(object_database_file* obj_db, stream& s, uint32_t header_length); +static void object_database_file_modern_write_inner(object_database_file* obj_db, stream& s); static int64_t object_database_strings_get_string_offset(std::vector& vec, std::vector& vec_off, std::string& str); static void object_database_strings_push_back_check(std::vector& vec, std::string& str); @@ -29,15 +29,48 @@ object_info::object_info(uint32_t id, uint32_t set_id) { this->set_id = set_id; } -object_database::object_database() : ready(), modern(), is_x() { +object_set_info_file::object_set_info_file() : id() { } -object_database::~object_database() { +object_set_info_file::~object_set_info_file() { } -void object_database::read(const char* path, bool modern) { +object_info_data_file::object_info_data_file() : id() { +} + +object_info_data_file::~object_info_data_file() { + +} + +object_set_info::object_set_info() : name_hash(), id() { + name_hash = hash_murmurhash_empty; +} + +object_set_info::~object_set_info() { + +} + +object_info_data::object_info_data() : id() { + name_hash_fnv1a64m = hash_fnv1a64m_empty; + name_hash_fnv1a64m_upper = hash_fnv1a64m_empty; + name_hash_murmurhash = hash_murmurhash_empty; +} + +object_info_data::~object_info_data() { + +} + +object_database_file::object_database_file() : ready(), modern(), is_x() { + +} + +object_database_file::~object_database_file() { + +} + +void object_database_file::read(const char* path, bool modern) { if (!path) return; @@ -51,7 +84,7 @@ void object_database::read(const char* path, bool modern) { s.read(data, s.length); stream s_bin; s_bin.open(data, s.length); - object_database_classic_read_inner(this, s_bin); + object_database_file_classic_read_inner(this, s_bin); free(data); } } @@ -66,14 +99,14 @@ void object_database::read(const char* path, bool modern) { stream s_mosi; s_mosi.open(st.data); s_mosi.is_big_endian = st.header.use_big_endian; - object_database_modern_read_inner(this, s_mosi, st.header.length); + object_database_file_modern_read_inner(this, s_mosi, st.header.length); } } free(path_osi); } } -void object_database::read(const wchar_t* path, bool modern) { +void object_database_file::read(const wchar_t* path, bool modern) { if (!path) return; @@ -87,7 +120,7 @@ void object_database::read(const wchar_t* path, bool modern) { s.read(data, s.length); stream s_bin; s_bin.open(data, s.length); - object_database_classic_read_inner(this, s_bin); + object_database_file_classic_read_inner(this, s_bin); free(data); } } @@ -102,21 +135,21 @@ void object_database::read(const wchar_t* path, bool modern) { stream s_mosi; s_mosi.open(st.data); s_mosi.is_big_endian = st.header.use_big_endian; - object_database_modern_read_inner(this, s_mosi, st.header.length); + object_database_file_modern_read_inner(this, s_mosi, st.header.length); } } free(path_osi); } } -void object_database::read(const void* data, size_t size, bool modern) { +void object_database_file::read(const void* data, size_t size, bool modern) { if (!data || !size) return; if (!modern) { stream s; s.open(data, size); - object_database_classic_read_inner(this, s); + object_database_file_classic_read_inner(this, s); } else { f2_struct st; @@ -125,12 +158,12 @@ void object_database::read(const void* data, size_t size, bool modern) { stream s_mosi; s_mosi.open(st.data); s_mosi.is_big_endian = st.header.use_big_endian; - object_database_modern_read_inner(this, s_mosi, st.header.length); + object_database_file_modern_read_inner(this, s_mosi, st.header.length); } } } -void object_database::write(const char* path) { +void object_database_file::write(const char* path) { if (!path || !ready) return; @@ -139,7 +172,7 @@ void object_database::write(const char* path) { stream s; s.open(path_bin, "wb"); if (s.io.stream) - object_database_classic_write_inner(this, s); + object_database_file_classic_write_inner(this, s); free(path_bin); } else { @@ -147,12 +180,12 @@ void object_database::write(const char* path) { stream s; s.open(path_osi, "wb"); if (s.io.stream) - object_database_modern_write_inner(this, s); + object_database_file_modern_write_inner(this, s); free(path_osi); } } -void object_database::write(const wchar_t* path) { +void object_database_file::write(const wchar_t* path) { if (!path || !ready) return; @@ -161,7 +194,7 @@ void object_database::write(const wchar_t* path) { stream s; s.open(path_bin, L"wb"); if (s.io.stream) - object_database_classic_write_inner(this, s); + object_database_file_classic_write_inner(this, s); free(path_bin); } else { @@ -169,58 +202,89 @@ void object_database::write(const wchar_t* path) { stream s; s.open(path_osi, L"wb"); if (s.io.stream) - object_database_modern_write_inner(this, s); + object_database_file_modern_write_inner(this, s); free(path_osi); } } -void object_database::write(void** data, size_t* size) { +void object_database_file::write(void** data, size_t* size) { if (!data || !size || !ready) return; stream s; s.open(); if (!modern) - object_database_classic_write_inner(this, s); + object_database_file_classic_write_inner(this, s); else - object_database_modern_write_inner(this, s); + object_database_file_modern_write_inner(this, s); s.align_write(0x10); s.copy(data, size); } -void object_database::merge_mdata(object_database* base_obj_db, object_database* mdata_obj_db) { - if (!base_obj_db || !mdata_obj_db || !base_obj_db->ready || !mdata_obj_db->ready) +bool object_database_file::load_file(void* data, const char* path, const char* file, uint32_t hash) { + size_t file_len = utf8_length(file); + + const char* t = strrchr(file, '.'); + if (t) + file_len = t - file; + + std::string s = path + std::string(file, file_len); + + object_database_file* obj_db = (object_database_file*)data; + obj_db->read(s.c_str(), obj_db->modern); + + return obj_db->ready; +} + +object_database::object_database() { + +} + +object_database::~object_database() { + +} + +void object_database::add(object_database_file* obj_db_file) { + if (!obj_db_file || !obj_db_file->ready) return; - if (this != base_obj_db) - object_set = base_obj_db->object_set; + object_set.reserve(obj_db_file->object_set.size()); - for (object_set_info& i : mdata_obj_db->object_set) { - uint32_t name_hash = i.name_hash; + for (object_set_info_file& i : obj_db_file->object_set) { + uint32_t name_hash = hash_string_murmurhash(i.name); - object_set_info* info = 0; + object_set_info* set_info = 0; for (object_set_info& j : object_set) if (name_hash == j.name_hash) { - info = &j; + set_info = &j; break; } - if (info) - *info = i; - else - object_set.push_back(i); - } + if (!set_info) { + object_set.push_back({}); + set_info = &object_set.back(); + } - if (this != base_obj_db) { - ready = true; - modern = base_obj_db->modern; - is_x = base_obj_db->is_x; - } -} + set_info->id = i.id; + set_info->name = i.name; + set_info->name_hash = hash_string_murmurhash(i.name); + set_info->object_file_name = i.object_file_name; + set_info->texture_file_name = i.texture_file_name; + set_info->archive_file_name = i.archive_file_name; -void object_database::split_mdata(object_database* base_obj_db, object_database* mdata_obj_db) { - if (!base_obj_db || !mdata_obj_db || !ready || !base_obj_db->ready) - return; + set_info->object.clear(); + set_info->object.reserve(i.object.size()); + + for (object_info_data_file& j : i.object) { + object_info_data info; + info.id = j.id; + info.name = j.name; + info.name_hash_fnv1a64m = hash_string_fnv1a64m(info.name); + info.name_hash_fnv1a64m_upper = hash_string_fnv1a64m(info.name, true); + info.name_hash_murmurhash = hash_string_murmurhash(info.name); + set_info->object.push_back(info); + } + } } bool object_database::get_object_set_info(const char* name, object_set_info** set_info) { @@ -379,38 +443,7 @@ const char* object_database::get_object_name(object_info obj_info) { return 0; } -bool object_database::load_file(void* data, const char* path, const char* file, uint32_t hash) { - size_t file_len = utf8_length(file); - - const char* t = strrchr(file, '.'); - if (t) - file_len = t - file; - - std::string s = path + std::string(file, file_len); - - object_database* obj_db = (object_database*)data; - obj_db->read(s.c_str(), obj_db->modern); - - return obj_db->ready; -} - -object_set_info::object_set_info() : name_hash(), id() { - -} - -object_set_info::~object_set_info() { - -} - -object_info_data::object_info_data() : id(), name_hash_fnv1a64m(), -name_hash_fnv1a64m_upper(), name_hash_murmurhash() { -} - -object_info_data::~object_info_data() { - -} - -static void object_database_classic_read_inner(object_database* obj_db, stream& s) { +static void object_database_file_classic_read_inner(object_database_file* obj_db, stream& s) { uint32_t object_set_count = s.read_uint32_t(); uint32_t max_object_set_id = s.read_uint32_t(); uint32_t object_sets_offset = s.read_uint32_t(); @@ -421,9 +454,8 @@ static void object_database_classic_read_inner(object_database* obj_db, stream& s.position_push(object_sets_offset, SEEK_SET); for (uint32_t i = 0; i < object_set_count; i++) { - object_set_info* set_info = &obj_db->object_set[i]; + object_set_info_file* set_info = &obj_db->object_set[i]; set_info->name = s.read_string_null_terminated_offset(s.read_uint32_t()); - set_info->name_hash = hash_string_murmurhash(&set_info->name); set_info->id = s.read_uint32_t(); set_info->object_file_name = s.read_string_null_terminated_offset(s.read_uint32_t()); set_info->texture_file_name = s.read_string_null_terminated_offset(s.read_uint32_t()); @@ -434,13 +466,10 @@ static void object_database_classic_read_inner(object_database* obj_db, stream& s.position_push(objects_offset, SEEK_SET); for (uint32_t i = 0; i < object_count; i++) { - object_info_data info; + object_info_data_file info; info.id = s.read_uint16_t(); uint32_t set_id = s.read_uint16_t(); info.name = s.read_string_null_terminated_offset(s.read_uint32_t()); - info.name_hash_fnv1a64m = hash_string_fnv1a64m(&info.name); - info.name_hash_fnv1a64m_upper = hash_string_fnv1a64m(&info.name, true); - info.name_hash_murmurhash = hash_string_murmurhash(&info.name); if (info.id == 0xFFFF) info.id = -1; @@ -460,7 +489,7 @@ static void object_database_classic_read_inner(object_database* obj_db, stream& obj_db->ready = true; } -static void object_database_classic_write_inner(object_database* obj_db, stream& s) { +static void object_database_file_classic_write_inner(object_database_file* obj_db, stream& s) { s.write_uint32_t(0x90669066); s.write_uint32_t(0x90669066); s.write_uint32_t(0x90669066); @@ -482,7 +511,7 @@ static void object_database_classic_write_inner(object_database* obj_db, stream& size_t off_idx = 0; int64_t objects_offset = 0; if (string_offsets.size()) { - for (object_set_info& i : obj_db->object_set) { + for (object_set_info_file& i : obj_db->object_set) { string_offsets.push_back(s.get_position()); s.write_string_null_terminated(i.name); string_offsets.push_back(s.get_position()); @@ -495,7 +524,7 @@ static void object_database_classic_write_inner(object_database* obj_db, stream& s.align_write(0x20); object_sets_offset = s.get_position(); - for (object_set_info& i : obj_db->object_set) { + for (object_set_info_file& i : obj_db->object_set) { s.write_uint32_t((uint32_t)string_offsets[off_idx++]); s.write_uint32_t(i.id); s.write_uint32_t((uint32_t)string_offsets[off_idx++]); @@ -510,8 +539,8 @@ static void object_database_classic_write_inner(object_database* obj_db, stream& string_offsets.clear(); string_offsets.reserve(object_count); - for (object_set_info& i : obj_db->object_set) - for (object_info_data& j : i.object) { + for (object_set_info_file& i : obj_db->object_set) + for (object_info_data_file& j : i.object) { string_offsets.push_back(s.get_position()); s.write_string_null_terminated(j.name); } @@ -519,9 +548,9 @@ static void object_database_classic_write_inner(object_database* obj_db, stream& objects_offset = s.get_position(); off_idx = 0; - for (object_set_info& i : obj_db->object_set) { + for (object_set_info_file& i : obj_db->object_set) { uint16_t set_id = (uint16_t)i.id; - for (object_info_data& j : i.object) { + for (object_info_data_file& j : i.object) { s.write_uint16_t((uint16_t)j.id); s.write_uint16_t(set_id); s.write_uint32_t((uint32_t)string_offsets[off_idx++]); @@ -540,7 +569,7 @@ static void object_database_classic_write_inner(object_database* obj_db, stream& s.position_pop(); } -static void object_database_modern_read_inner(object_database* obj_db, stream& s, uint32_t header_length) { +static void object_database_file_modern_read_inner(object_database_file* obj_db, stream& s, uint32_t header_length) { bool is_x = true; s.set_position(0x0C, SEEK_SET); @@ -562,9 +591,8 @@ static void object_database_modern_read_inner(object_database* obj_db, stream& s s.position_push(object_sets_offset, SEEK_SET); if (!is_x) for (uint32_t i = 0; i < object_set_count; i++) { - object_set_info* set_info = &obj_db->object_set[i]; + object_set_info_file* set_info = &obj_db->object_set[i]; set_info->name = s.read_string_null_terminated_offset(s.read_offset_f2(header_length)); - set_info->name_hash = hash_string_murmurhash(&set_info->name); set_info->id = s.read_uint32_t_reverse_endianness(); set_info->object_file_name = s.read_string_null_terminated_offset(s.read_offset_f2(header_length)); set_info->texture_file_name = s.read_string_null_terminated_offset(s.read_offset_f2(header_length)); @@ -573,9 +601,8 @@ static void object_database_modern_read_inner(object_database* obj_db, stream& s } else for (uint32_t i = 0; i < object_set_count; i++) { - object_set_info* set_info = &obj_db->object_set[i]; + object_set_info_file* set_info = &obj_db->object_set[i]; set_info->name = s.read_string_null_terminated_offset(s.read_offset_x()); - set_info->name_hash = hash_string_murmurhash(&set_info->name); set_info->id = s.read_uint32_t_reverse_endianness(); set_info->object_file_name = s.read_string_null_terminated_offset(s.read_offset_x()); set_info->texture_file_name = s.read_string_null_terminated_offset(s.read_offset_x()); @@ -587,13 +614,10 @@ static void object_database_modern_read_inner(object_database* obj_db, stream& s s.position_push(objects_offset, SEEK_SET); if (!is_x) for (uint32_t i = 0; i < object_count; i++) { - object_info_data info; + object_info_data_file info; info.id = s.read_uint32_t_reverse_endianness(); uint32_t set_id = s.read_uint32_t_reverse_endianness(); info.name = s.read_string_null_terminated_offset(s.read_offset_f2(header_length)); - info.name_hash_fnv1a64m = hash_string_fnv1a64m(&info.name); - info.name_hash_fnv1a64m_upper = hash_string_fnv1a64m(&info.name, true); - info.name_hash_murmurhash = hash_string_murmurhash(&info.name); for (uint32_t i = 0; i < object_set_count; i++) if (set_id == obj_db->object_set[i].id) { @@ -603,13 +627,10 @@ static void object_database_modern_read_inner(object_database* obj_db, stream& s } else for (uint32_t i = 0; i < object_count; i++) { - object_info_data info; + object_info_data_file info; info.id = s.read_uint32_t_reverse_endianness(); uint32_t set_id = s.read_uint32_t_reverse_endianness(); info.name = s.read_string_null_terminated_offset(s.read_offset_x()); - info.name_hash_fnv1a64m = hash_string_fnv1a64m(&info.name); - info.name_hash_fnv1a64m_upper = hash_string_fnv1a64m(&info.name, true); - info.name_hash_murmurhash = hash_string_murmurhash(&info.name); for (uint32_t i = 0; i < object_set_count; i++) if (set_id == obj_db->object_set[i].id) { @@ -624,7 +645,7 @@ static void object_database_modern_read_inner(object_database* obj_db, stream& s obj_db->ready = true; } -static void object_database_modern_write_inner(object_database* obj_db, stream& s) { +static void object_database_file_modern_write_inner(object_database_file* obj_db, stream& s) { stream s_mosi; s_mosi.open(); uint32_t off; @@ -637,7 +658,7 @@ static void object_database_modern_write_inner(object_database* obj_db, stream& uint32_t object_set_count = (uint32_t)obj_db->object_set.size(); uint32_t object_count = 0; - for (object_set_info& i : obj_db->object_set) + for (object_set_info_file& i : obj_db->object_set) object_count += (uint32_t)i.object.size(); if (!is_x) { @@ -704,12 +725,12 @@ static void object_database_modern_write_inner(object_database* obj_db, stream& strings.reserve((int64_t)object_set_count + object_count); - for (object_set_info& i : obj_db->object_set) { + for (object_set_info_file& i : obj_db->object_set) { object_database_strings_push_back_check(strings, i.name); object_database_strings_push_back_check(strings, i.object_file_name); object_database_strings_push_back_check(strings, i.texture_file_name); object_database_strings_push_back_check(strings, i.archive_file_name); - for (object_info_data& j : i.object) + for (object_info_data_file& j : i.object) object_database_strings_push_back_check(strings, j.name); } @@ -732,7 +753,7 @@ static void object_database_modern_write_inner(object_database* obj_db, stream& s_mosi.align_write(0x10); if (!is_x) - for (object_set_info& i : obj_db->object_set) { + for (object_set_info_file& i : obj_db->object_set) { io_write_offset_f2_pof_add(s_mosi, object_database_strings_get_string_offset(strings, string_offsets, i.name), 0x20, &pof); s_mosi.write_uint32_t(i.id); @@ -745,7 +766,7 @@ static void object_database_modern_write_inner(object_database* obj_db, stream& s_mosi.write(0x10); } else - for (object_set_info& i : obj_db->object_set) { + for (object_set_info_file& i : obj_db->object_set) { io_write_offset_x_pof_add(s_mosi, object_database_strings_get_string_offset(strings, string_offsets, i.name), &pof); s_mosi.write_uint32_t(i.id); @@ -760,9 +781,9 @@ static void object_database_modern_write_inner(object_database* obj_db, stream& s_mosi.align_write(0x10); if (!is_x) - for (object_set_info& i : obj_db->object_set) { + for (object_set_info_file& i : obj_db->object_set) { uint32_t set_id = i.id; - for (object_info_data& j : i.object) { + for (object_info_data_file& j : i.object) { s_mosi.write_uint32_t(j.id); s_mosi.write_uint32_t(set_id); io_write_offset_f2_pof_add(s_mosi, object_database_strings_get_string_offset(strings, @@ -770,9 +791,9 @@ static void object_database_modern_write_inner(object_database* obj_db, stream& } } else - for (object_set_info& i : obj_db->object_set) { + for (object_set_info_file& i : obj_db->object_set) { uint32_t set_id = i.id; - for (object_info_data& j : i.object) { + for (object_info_data_file& j : i.object) { s_mosi.write_uint32_t(j.id); s_mosi.write_uint32_t(set_id); io_write_offset_x_pof_add(s_mosi, object_database_strings_get_string_offset(strings, diff --git a/src/KKdLib/database/object.hpp b/src/KKdLib/database/object.hpp index 920dc268..35bf6da3 100644 --- a/src/KKdLib/database/object.hpp +++ b/src/KKdLib/database/object.hpp @@ -51,6 +51,26 @@ inline bool operator !=(const object_info& left, const object_info& right) { return left.set_id != right.set_id || left.id != right.id; } +struct object_info_data_file { + uint32_t id; + std::string name; + + object_info_data_file(); + ~object_info_data_file(); +}; + +struct object_set_info_file { + std::string name; + uint32_t id; + std::string object_file_name; + std::string texture_file_name; + std::string archive_file_name; + std::vector object; + + object_set_info_file(); + ~object_set_info_file(); +}; + struct object_info_data { uint32_t id; std::string name; @@ -75,15 +95,15 @@ struct object_set_info { ~object_set_info(); }; -struct object_database { +struct object_database_file { bool ready; bool modern; bool is_x; - std::vector object_set; + std::vector object_set; - object_database(); - ~object_database(); + object_database_file(); + virtual ~object_database_file(); void read(const char* path, bool modern); void read(const wchar_t* path, bool modern); @@ -92,8 +112,16 @@ struct object_database { void write(const wchar_t* path); void write(void** data, size_t* size); - void merge_mdata(object_database* base_obj_db, object_database* mdata_obj_db); - void split_mdata(object_database* base_obj_db, object_database* mdata_obj_db); + static bool load_file(void* data, const char* path, const char* file, uint32_t hash); +}; + +struct object_database { + std::vector object_set; + + object_database(); + virtual ~object_database(); + + void add(object_database_file* obj_db_file); bool get_object_set_info(const char* name, object_set_info** set_info); bool get_object_set_info(uint32_t set_id, object_set_info** set_info); @@ -104,6 +132,4 @@ struct object_database { uint32_t get_object_set_id(const char* name); object_info get_object_info(const char* name); const char* get_object_name(object_info obj_info); - - static bool load_file(void* data, const char* path, const char* file, uint32_t hash); }; diff --git a/src/KKdLib/database/stage.cpp b/src/KKdLib/database/stage.cpp index 5c275e88..cdb40601 100644 --- a/src/KKdLib/database/stage.cpp +++ b/src/KKdLib/database/stage.cpp @@ -10,10 +10,34 @@ #include "../hash.hpp" #include "../str_utils.hpp" -static void stage_database_classic_read_inner(stage_database* stage_data, stream& s); -static void stage_database_classic_write_inner(stage_database* stage_data, stream& s); -static void stage_database_modern_read_inner(stage_database* stage_data, stream& s, uint32_t header_length); -static void stage_database_modern_write_inner(stage_database* stage_data, stream& s); +static void stage_database_file_classic_read_inner(stage_database_file* stage_data, stream& s); +static void stage_database_file_classic_write_inner(stage_database_file* stage_data, stream& s); +static void stage_database_file_modern_read_inner(stage_database_file* stage_data, stream& s, uint32_t header_length); +static void stage_database_file_modern_write_inner(stage_database_file* stage_data, stream& s); + +stage_data_file::stage_data_file() : id(), object_set_id(), lens_flare_texture(), lens_shaft_texture(), +lens_ghost_texture(), unknown(), render_texture(), movie_texture(), reflect_type(), refract_enable(), +reflect(), reflect_data(), refract(), refract_data(), flags(), ring_rectangle_x(), ring_rectangle_y(), +ring_rectangle_width(), ring_rectangle_height(), ring_height(), ring_out_height(), effects() { + lens_shaft_inv_scale = 1.0f; +} + +stage_data_file::~stage_data_file() { + +} + +stage_data_modern_file::stage_data_modern_file() : unknown(), render_texture(), +render_texture_flag(), movie_texture(), movie_texture_flag(), field_04(), field_04_flag(), field_05(), +field_05_flag(), field_06(), field_06_flag(), field_07(), field_07_flag(), field_08(), field_09(), +field_10(), field_11(), field_12(), ring_rectangle_x(), ring_rectangle_y(), ring_rectangle_width(), +ring_rectangle_height(), ring_height(), ring_out_height(), field_13(), effects() { + hash = hash_murmurhash_empty; + lens_shaft_inv_scale = 1.0f; +} + +stage_data_modern_file::~stage_data_modern_file() { + +} stage_data::stage_data() : id(), object_set_id(), lens_flare_texture(), lens_shaft_texture(), lens_ghost_texture(), unknown(), render_texture(), movie_texture(), reflect_type(), refract_enable(), @@ -41,15 +65,15 @@ stage_data_modern::~stage_data_modern() { } -stage_database::stage_database() : ready(), modern(), is_x(), format() { +stage_database_file::stage_database_file() : ready(), modern(), is_x(), format() { } -stage_database::~stage_database() { +stage_database_file::~stage_database_file() { } -void stage_database::read(const char* path, bool modern) { +void stage_database_file::read(const char* path, bool modern) { if (!path) return; @@ -63,7 +87,7 @@ void stage_database::read(const char* path, bool modern) { s.read(data, s.length); stream s_bin; s_bin.open(data, s.length); - stage_database_classic_read_inner(this, s_bin); + stage_database_file_classic_read_inner(this, s_bin); free(data); } } @@ -78,14 +102,14 @@ void stage_database::read(const char* path, bool modern) { stream s_stgc; s_stgc.open(st.data); s_stgc.is_big_endian = st.header.use_big_endian; - stage_database_modern_read_inner(this, s_stgc, st.header.length); + stage_database_file_modern_read_inner(this, s_stgc, st.header.length); } } free(path_stg); } } -void stage_database::read(const wchar_t* path, bool modern) { +void stage_database_file::read(const wchar_t* path, bool modern) { if (!path) return; @@ -99,7 +123,7 @@ void stage_database::read(const wchar_t* path, bool modern) { s.read(data, s.length); stream s_bin; s_bin.open(data, s.length); - stage_database_classic_read_inner(this, s_bin); + stage_database_file_classic_read_inner(this, s_bin); free(data); } } @@ -114,21 +138,21 @@ void stage_database::read(const wchar_t* path, bool modern) { stream s_stgc; s_stgc.open(st.data); s_stgc.is_big_endian = st.header.use_big_endian; - stage_database_modern_read_inner(this, s_stgc, st.header.length); + stage_database_file_modern_read_inner(this, s_stgc, st.header.length); } } free(path_stg); } } -void stage_database::read(const void* data, size_t size, bool modern) { +void stage_database_file::read(const void* data, size_t size, bool modern) { if (!data || !size) return; if (!modern) { stream s; s.open(data, size); - stage_database_classic_read_inner(this, s); + stage_database_file_classic_read_inner(this, s); } else { f2_struct st; @@ -137,12 +161,12 @@ void stage_database::read(const void* data, size_t size, bool modern) { stream s_stgc; s_stgc.open(st.data); s_stgc.is_big_endian = st.header.use_big_endian; - stage_database_modern_read_inner(this, s_stgc, st.header.length); + stage_database_file_modern_read_inner(this, s_stgc, st.header.length); } } } -void stage_database::write(const char* path) { +void stage_database_file::write(const char* path) { if (!path || !ready) return; @@ -151,7 +175,7 @@ void stage_database::write(const char* path) { stream s; s.open(path_bin, "wb"); if (s.io.stream) - stage_database_classic_write_inner(this, s); + stage_database_file_classic_write_inner(this, s); free(path_bin); } else { @@ -159,12 +183,12 @@ void stage_database::write(const char* path) { stream s; s.open(path_stg, "wb"); if (s.io.stream) - stage_database_modern_write_inner(this, s); + stage_database_file_modern_write_inner(this, s); free(path_stg); } } -void stage_database::write(const wchar_t* path) { +void stage_database_file::write(const wchar_t* path) { if (!path || !ready) return; @@ -173,7 +197,7 @@ void stage_database::write(const wchar_t* path) { stream s; s.open(path_bin, L"wb"); if (s.io.stream) - stage_database_classic_write_inner(this, s); + stage_database_file_classic_write_inner(this, s); free(path_bin); } else { @@ -181,26 +205,26 @@ void stage_database::write(const wchar_t* path) { stream s; s.open(path_stg, L"wb"); if (s.io.stream) - stage_database_modern_write_inner(this, s); + stage_database_file_modern_write_inner(this, s); free(path_stg); } } -void stage_database::write(void** data, size_t* size) { +void stage_database_file::write(void** data, size_t* size) { if (!data || !size || !ready) return; stream s; s.open(); if (!modern) - stage_database_classic_write_inner(this, s); + stage_database_file_classic_write_inner(this, s); else - stage_database_modern_write_inner(this, s); + stage_database_file_modern_write_inner(this, s); s.align_write(0x10); s.copy(data, size); } -bool stage_database::load_file(void* data, const char* path, const char* file, uint32_t hash) { +bool stage_database_file::load_file(void* data, const char* path, const char* file, uint32_t hash) { size_t file_len = utf8_length(file); const char* t = strrchr(file, '.'); @@ -209,12 +233,20 @@ bool stage_database::load_file(void* data, const char* path, const char* file, u std::string s = path + std::string(file, file_len); - stage_database* stage_data = (stage_database*)data; + stage_database_file* stage_data = (stage_database_file*)data; stage_data->read(s.c_str(), stage_data->modern); return stage_data->ready; } +stage_database::stage_database() { + +} + +stage_database::~stage_database() { + +} + ::stage_data* stage_database::get_stage_data(int32_t stage_index) { if (stage_index >= 0 && stage_index < stage_data.size()) return &stage_data[stage_index]; @@ -236,60 +268,132 @@ int32_t stage_database::get_stage_index(const char* name) { return -1; } -void stage_database::merge_mdata(stage_database* base_stage_data, stage_database* mdata_stage_data) { - if (!base_stage_data || !mdata_stage_data || !base_stage_data->ready || !mdata_stage_data->ready) +void stage_database::add(stage_database_file* stage_data_file) { + if (!stage_data_file || !stage_data_file->ready) return; - if (this != base_stage_data) { - stage_data = base_stage_data->stage_data; - stage_modern = base_stage_data->stage_modern; - } + if (stage_data.capacity() - stage_data.size() < stage_data_file->stage_data.size()) + stage_data.reserve(stage_data_file->stage_data.size()); - for (::stage_data i : mdata_stage_data->stage_data) { - uint32_t name_hash = i.name_hash; + for (::stage_data_file i : stage_data_file->stage_data) { + uint32_t name_hash = hash_string_murmurhash(i.name); - ::stage_data* info = 0; + ::stage_data* data = 0; for (::stage_data& j : stage_data) if (name_hash == j.name_hash) { - info = &j; + data = &j; break; } - if (info) - *info = i; - else - stage_data.push_back(i); + if (!data) { + stage_data.push_back({}); + data = &stage_data.back(); + } + + data->id = i.id; + data->name = i.name; + data->name_hash = hash_string_murmurhash(data->name); + data->auth_3d_name = i.auth_3d_name; + data->object_set_id = i.object_set_id; + data->object_ground = i.object_ground; + data->object_ring = i.object_ring; + data->object_sky = i.object_sky; + data->object_shadow = i.object_shadow; + data->object_reflect = i.object_reflect; + data->object_refract = i.object_refract; + data->lens_flare_texture = i.lens_flare_texture; + data->lens_shaft_texture = i.lens_shaft_texture; + data->lens_ghost_texture = i.lens_ghost_texture; + data->lens_shaft_inv_scale = i.lens_shaft_inv_scale; + data->unknown = i.unknown; + data->render_texture = i.render_texture; + data->movie_texture = i.movie_texture; + data->collision_file_path = i.collision_file_path; + data->reflect_type = i.reflect_type; + data->refract_enable = i.refract_enable; + data->reflect = i.reflect; + data->reflect_data = i.reflect_data; + data->refract = i.refract; + data->refract_data = i.refract_data; + data->flags = i.flags; + data->ring_rectangle_x = i.ring_rectangle_x; + data->ring_rectangle_y = i.ring_rectangle_y; + data->ring_rectangle_width = i.ring_rectangle_width; + data->ring_rectangle_height = i.ring_rectangle_height; + data->ring_height = i.ring_height; + data->ring_out_height = i.ring_out_height; + data->effects = i.effects; + data->auth_3d_ids = i.auth_3d_ids; } - for (stage_data_modern& i : mdata_stage_data->stage_modern) { - uint32_t name_hash = hash_string_murmurhash(&i.name); + for (stage_data_modern_file& i : stage_data_file->stage_modern) { + uint32_t hash = i.hash; - stage_data_modern* info = 0; + stage_data_modern* data = 0; for (stage_data_modern& j : stage_modern) - if (name_hash == hash_string_murmurhash(&j.name)) { - info = &j; + if (hash == j.hash) { + data = &j; break; } - if (info) - *info = i; - else - stage_modern.push_back(i); + if (!data) { + stage_modern.push_back({}); + data = &stage_modern.back(); + } + + data->hash = i.hash; + data->name = i.name; + data->auth_3d_name = i.auth_3d_name; + data->auth_3d_name_hash = hash_string_murmurhash(data->auth_3d_name); + data->object_ground = i.object_ground; + data->object_sky = i.object_sky; + data->object_shadow = i.object_shadow; + data->object_reflect = i.object_reflect; + data->object_refract = i.object_refract; + data->lens_shaft_inv_scale = i.lens_shaft_inv_scale; + data->unknown = i.unknown; + data->render_texture = i.render_texture; + data->render_texture_flag = i.render_texture_flag; + data->movie_texture = i.movie_texture; + data->movie_texture_flag = i.movie_texture_flag; + data->field_04 = i.field_04; + data->field_04_flag = i.field_04_flag; + data->field_05 = i.field_05; + data->field_05_flag = i.field_05_flag; + data->field_06 = i.field_06; + data->field_06_flag = i.field_06_flag; + data->field_07 = i.field_07; + data->field_07_flag = i.field_07_flag; + data->field_08 = i.field_08; + data->field_09 = i.field_09; + data->field_10 = i.field_10; + data->field_11 = i.field_11; + data->field_12 = i.field_12; + data->ring_rectangle_x = i.ring_rectangle_x; + data->ring_rectangle_y = i.ring_rectangle_y; + data->ring_rectangle_width = i.ring_rectangle_width; + data->ring_rectangle_height = i.ring_rectangle_height; + data->ring_height = i.ring_height; + data->ring_out_height = i.ring_out_height; + data->effects = i.effects; + data->auth_3d_ids = i.auth_3d_ids; + data->render_texture = i.render_texture; + data->render_texture_flag = i.render_texture_flag; + data->movie_texture = i.movie_texture; + data->movie_texture_flag = i.movie_texture_flag; + data->ring_rectangle_x = i.ring_rectangle_x; + data->ring_rectangle_y = i.ring_rectangle_y; + data->ring_rectangle_width = i.ring_rectangle_width; + data->ring_rectangle_height = i.ring_rectangle_height; + data->ring_height = i.ring_height; + data->ring_out_height = i.ring_out_height; + data->field_13 = i.field_13; + data->effects = i.effects; + data->auth_3d_ids = i.auth_3d_ids; } - - ready = true; - modern = base_stage_data->modern; - is_x = base_stage_data->is_x; - format = base_stage_data->format; } -void stage_database::split_mdata(stage_database* base_stage_data, stage_database* mdata_stage_data) { - if (!base_stage_data || !mdata_stage_data || !ready || !base_stage_data->ready) - return; - -} - -static void stage_database_classic_read_inner(stage_database* stage_data, stream& s) { +static void stage_database_file_classic_read_inner(stage_database_file* stage_data, stream& s) { int32_t count = s.read_int32_t(); int32_t stages_offset = s.read_int32_t(); int32_t stage_effects_offset = s.read_int32_t(); @@ -312,11 +416,10 @@ static void stage_database_classic_read_inner(stage_database* stage_data, stream s.position_push(stages_offset, SEEK_SET); for (int32_t i = 0; i < count; i++) { - ::stage_data* stage = &stage_data->stage_data[i]; + stage_data_file* stage = &stage_data->stage_data[i]; stage->id = i; stage->name = s.read_string_null_terminated_offset(s.read_uint32_t()); - stage->name_hash = hash_string_murmurhash(&stage->name); stage->auth_3d_name = s.read_string_null_terminated_offset(s.read_uint32_t()); stage->object_set_id = (uint16_t)s.read_uint32_t(); // Crutch to remove higher bits stage->object_ground.id = s.read_uint16_t(); @@ -413,7 +516,7 @@ static void stage_database_classic_read_inner(stage_database* stage_data, stream s.position_push(stage_effects_offset, SEEK_SET); for (int32_t i = 0; i < count; i++) { - ::stage_data* stage = &stage_data->stage_data[i]; + stage_data_file* stage = &stage_data->stage_data[i]; stage_effects* effects = &stage->effects; for (int32_t j = 0; j < 8; j++) @@ -426,7 +529,7 @@ static void stage_database_classic_read_inner(stage_database* stage_data, stream s.position_push(auth3d_id_counts_offset, SEEK_SET); for (int32_t i = 0; i < count; i++) { - ::stage_data* stage = &stage_data->stage_data[i]; + stage_data_file* stage = &stage_data->stage_data[i]; stage->auth_3d_ids.resize(s.read_int32_t()); } @@ -434,7 +537,7 @@ static void stage_database_classic_read_inner(stage_database* stage_data, stream s.position_push(auth3d_ids_offsets_offset, SEEK_SET); for (int32_t i = 0; i < count; i++) { - ::stage_data* stage = &stage_data->stage_data[i]; + stage_data_file* stage = &stage_data->stage_data[i]; uint32_t id = s.read_uint32_t(); uint32_t offset = s.read_uint32_t(); @@ -469,11 +572,11 @@ static void stage_database_classic_read_inner(stage_database* stage_data, stream stage_data->is_x = false; } -static void stage_database_classic_write_inner(stage_database* stage_data, stream& s) { +static void stage_database_file_classic_write_inner(stage_database_file* stage_data, stream& s) { } -static void stage_database_modern_read_inner(stage_database* stage_data, stream& s, uint32_t header_length) { +static void stage_database_file_modern_read_inner(stage_database_file* stage_data, stream& s, uint32_t header_length) { bool is_x = true; s.set_position(0x04, SEEK_SET); @@ -488,11 +591,10 @@ static void stage_database_modern_read_inner(stage_database* stage_data, stream& s.position_push(stages_offset, SEEK_SET); for (int32_t i = 0; i < count; i++) { - stage_data_modern* stage = &stage_data->stage_modern[i]; + stage_data_modern_file* stage = &stage_data->stage_modern[i]; stage->hash = (uint32_t)s.read_uint64_t_reverse_endianness(); stage->name = s.read_string_null_terminated_offset(s.read_offset(header_length, is_x)); stage->auth_3d_name = s.read_string_null_terminated_offset(s.read_offset(header_length, is_x)); - stage->auth_3d_name_hash = hash_string_murmurhash(&stage->auth_3d_name); stage->object_ground.set_id = s.read_uint32_t_reverse_endianness(); stage->object_ground.id = s.read_uint32_t_reverse_endianness(); stage->object_sky.id = s.read_uint32_t_reverse_endianness(); @@ -584,7 +686,7 @@ static void stage_database_modern_read_inner(stage_database* stage_data, stream& stage_data->format = STAGE_DATA_UNK; } -static void stage_database_modern_write_inner(stage_database* stage_data, stream& s) { +static void stage_database_file_modern_write_inner(stage_database_file* stage_data, stream& s) { } diff --git a/src/KKdLib/database/stage.hpp b/src/KKdLib/database/stage.hpp index f0a918f8..6376c5e8 100644 --- a/src/KKdLib/database/stage.hpp +++ b/src/KKdLib/database/stage.hpp @@ -64,6 +64,87 @@ struct stage_effects { int32_t field_20[16]; }; +struct stage_data_file { + int32_t id; + std::string name; + std::string auth_3d_name; + uint32_t object_set_id; + object_info object_ground; + object_info object_ring; + object_info object_sky; + object_info object_shadow; + object_info object_reflect; + object_info object_refract; + uint32_t lens_flare_texture; + uint32_t lens_shaft_texture; + uint32_t lens_ghost_texture; + float_t lens_shaft_inv_scale; + uint32_t unknown; + uint32_t render_texture; + uint32_t movie_texture; + std::string collision_file_path; + stage_data_reflect_type reflect_type; + bool refract_enable; + bool reflect; + stage_data_reflect reflect_data; + bool refract; + stage_data_refract refract_data; + stage_data_flags flags; + float_t ring_rectangle_x; + float_t ring_rectangle_y; + float_t ring_rectangle_width; + float_t ring_rectangle_height; + float_t ring_height; + float_t ring_out_height; + stage_effects effects; + std::vector auth_3d_ids; + + stage_data_file(); + ~stage_data_file(); +}; + +struct stage_data_modern_file { + uint32_t hash; + std::string name; + std::string auth_3d_name; + object_info object_ground; + object_info object_sky; + object_info object_shadow; + object_info object_reflect; + object_info object_refract; + float_t lens_shaft_inv_scale; + uint32_t unknown; + uint32_t render_texture; + uint32_t render_texture_flag; + uint32_t movie_texture; + uint32_t movie_texture_flag; + uint32_t field_04; + uint32_t field_04_flag; + uint32_t field_05; + uint32_t field_05_flag; + uint32_t field_06; + uint32_t field_06_flag; + uint32_t field_07; + uint32_t field_07_flag; + uint32_t field_08; + uint32_t field_09; + uint32_t field_10; + size_t field_11; + size_t field_12; + float_t ring_rectangle_x; + float_t ring_rectangle_y; + float_t ring_rectangle_width; + float_t ring_rectangle_height; + float_t ring_height; + float_t ring_out_height; + uint32_t field_13; + stage_effects effects; + std::vector auth_3d_ids; + + stage_data_modern_file(); + ~stage_data_modern_file(); +}; + struct stage_data { int32_t id; std::string name; @@ -147,17 +228,17 @@ struct stage_data_modern { ~stage_data_modern(); }; -struct stage_database { +struct stage_database_file { bool ready; bool modern; bool is_x; stage_data_format format; - std::vector<::stage_data> stage_data; - std::vector stage_modern; + std::vector<::stage_data_file> stage_data; + std::vector stage_modern; - stage_database(); - ~stage_database(); + stage_database_file(); + virtual ~stage_database_file(); void read(const char* path, bool modern); void read(const wchar_t* path, bool modern); @@ -166,12 +247,18 @@ struct stage_database { void write(const wchar_t* path); void write(void** data, size_t* size); - ::stage_data* get_stage_data(int32_t stage_index); - ::stage_data_modern* get_stage_data_modern(uint32_t stage_hash); - int32_t get_stage_index(const char* name); - void merge_mdata(stage_database* base_stage_data, stage_database* mdata_stage_data); - void split_mdata(stage_database* base_stage_data, stage_database* mdata_stage_data); - static bool load_file(void* data, const char* path, const char* file, uint32_t hash); }; +struct stage_database { + std::vector<::stage_data> stage_data; + std::vector stage_modern; + + stage_database(); + virtual ~stage_database(); + + ::stage_data* get_stage_data(int32_t stage_index); + ::stage_data_modern* get_stage_data_modern(uint32_t stage_hash); + int32_t get_stage_index(const char* name); + void add(stage_database_file* stage_data_file); +}; diff --git a/src/KKdLib/database/texture.cpp b/src/KKdLib/database/texture.cpp index 759ece44..e3b0a6fa 100644 --- a/src/KKdLib/database/texture.cpp +++ b/src/KKdLib/database/texture.cpp @@ -11,23 +11,40 @@ #include "../sort.hpp" #include "../str_utils.hpp" -static void texture_database_classic_read_inner(texture_database* tex_db, stream& s); -static void texture_database_classic_write_inner(texture_database* tex_db, stream& s); -static void texture_database_modern_read_inner(texture_database* tex_db, stream& s, uint32_t header_length); -static void texture_database_modern_write_inner(texture_database* tex_db, stream& s); -static int64_t texture_database_strings_get_string_offset(std::vector& vec, +static void texture_database_file_classic_read_inner(texture_database_file* tex_db, stream& s); +static void texture_database_file_classic_write_inner(texture_database_file* tex_db, stream& s); +static void texture_database_file_modern_read_inner(texture_database_file* tex_db, stream& s, uint32_t header_length); +static void texture_database_file_modern_write_inner(texture_database_file* tex_db, stream& s); +static int64_t texture_database_file_strings_get_string_offset(std::vector& vec, std::vector& vec_off, std::string& str); -static void texture_database_strings_push_back_check(std::vector& vec, std::string& str); +static void texture_database_file_strings_push_back_check(std::vector& vec, std::string& str); -texture_database::texture_database() : ready(), modern(), is_x() { +texture_info_file::texture_info_file() { + id = (uint32_t)-1; +} + +texture_info_file::~texture_info_file() { } -texture_database::~texture_database() { +texture_info::texture_info() { + name_hash = hash_murmurhash_empty; + id = (uint32_t)-1; +} + +texture_info::~texture_info() { } -void texture_database::read(const char* path, bool modern) { +texture_database_file::texture_database_file() : ready(), modern(), is_x() { + +} + +texture_database_file::~texture_database_file() { + +} + +void texture_database_file::read(const char* path, bool modern) { if (!path) return; @@ -41,7 +58,7 @@ void texture_database::read(const char* path, bool modern) { s.read(data, s.length); stream s_bin; s_bin.open(data, s.length); - texture_database_classic_read_inner(this, s_bin); + texture_database_file_classic_read_inner(this, s_bin); free(data); } } @@ -56,14 +73,14 @@ void texture_database::read(const char* path, bool modern) { stream s_mtxi; s_mtxi.open(st.data); s_mtxi.is_big_endian = st.header.use_big_endian; - texture_database_modern_read_inner(this, s_mtxi, st.header.length); + texture_database_file_modern_read_inner(this, s_mtxi, st.header.length); } } free(path_txi); } } -void texture_database::read(const wchar_t* path, bool modern) { +void texture_database_file::read(const wchar_t* path, bool modern) { if (!path) return; @@ -77,7 +94,7 @@ void texture_database::read(const wchar_t* path, bool modern) { s.read(data, s.length); stream s_bin; s_bin.open(data, s.length); - texture_database_classic_read_inner(this, s_bin); + texture_database_file_classic_read_inner(this, s_bin); free(data); } } @@ -92,21 +109,21 @@ void texture_database::read(const wchar_t* path, bool modern) { stream s_mtxi; s_mtxi.open(st.data); s_mtxi.is_big_endian = st.header.use_big_endian; - texture_database_modern_read_inner(this, s_mtxi, st.header.length); + texture_database_file_modern_read_inner(this, s_mtxi, st.header.length); } } free(path_txi); } } -void texture_database::read(const void* data, size_t size, bool modern) { +void texture_database_file::read(const void* data, size_t size, bool modern) { if (!data || !size) return; if (!modern) { stream s; s.open(data, size); - texture_database_classic_read_inner(this, s); + texture_database_file_classic_read_inner(this, s); } else { f2_struct st; @@ -115,12 +132,12 @@ void texture_database::read(const void* data, size_t size, bool modern) { stream s_mtxi; s_mtxi.open(st.data); s_mtxi.is_big_endian = st.header.use_big_endian; - texture_database_modern_read_inner(this, s_mtxi, st.header.length); + texture_database_file_modern_read_inner(this, s_mtxi, st.header.length); } } } -void texture_database::write(const char* path) { +void texture_database_file::write(const char* path) { if (!path || !ready) return; @@ -129,7 +146,7 @@ void texture_database::write(const char* path) { stream s; s.open(path_bin, "wb"); if (s.io.stream) - texture_database_classic_write_inner(this, s); + texture_database_file_classic_write_inner(this, s); free(path_bin); } else { @@ -137,12 +154,12 @@ void texture_database::write(const char* path) { stream s; s.open(path_txi, "wb"); if (s.io.stream) - texture_database_modern_write_inner(this, s); + texture_database_file_modern_write_inner(this, s); free(path_txi); } } -void texture_database::write(const wchar_t* path) { +void texture_database_file::write(const wchar_t* path) { if (!path || !ready) return; @@ -151,7 +168,7 @@ void texture_database::write(const wchar_t* path) { stream s; s.open(path_bin, L"wb"); if (s.io.stream) - texture_database_classic_write_inner(this, s); + texture_database_file_classic_write_inner(this, s); free(path_bin); } else { @@ -159,35 +176,55 @@ void texture_database::write(const wchar_t* path) { stream s; s.open(path_txi, L"wb"); if (s.io.stream) - texture_database_modern_write_inner(this, s); + texture_database_file_modern_write_inner(this, s); free(path_txi); } } -void texture_database::write(void** data, size_t* size) { +void texture_database_file::write(void** data, size_t* size) { if (!data || !size || !ready) return; stream s; s.open(); if (!modern) - texture_database_classic_write_inner(this, s); + texture_database_file_classic_write_inner(this, s); else - texture_database_modern_write_inner(this, s); + texture_database_file_modern_write_inner(this, s); s.align_write(0x10); s.copy(data, size); } -void texture_database::merge_mdata(texture_database* base_tex_db, - texture_database* mdata_tex_db) { - if (!base_tex_db || !mdata_tex_db - || !base_tex_db->ready || !mdata_tex_db->ready) +bool texture_database_file::load_file(void* data, const char* path, const char* file, uint32_t hash) { + size_t file_len = utf8_length(file); + + const char* t = strrchr(file, '.'); + if (t) + file_len = t - file; + + std::string s = path + std::string(file, file_len); + + texture_database_file* tex_db = (texture_database_file*)data; + tex_db->read(s.c_str(), tex_db->modern); + + return tex_db->ready; +} + +texture_database::texture_database() { + +} + +texture_database::~texture_database() { + +} + +void texture_database::add(texture_database_file* tex_db_file) { + if (!tex_db_file || !tex_db_file->ready) return; - if (this != base_tex_db) - texture = base_tex_db->texture; + texture.reserve(tex_db_file->texture.size()); - for (texture_info& i : mdata_tex_db->texture) { + for (texture_info_file& i : tex_db_file->texture) { uint32_t id = i.id; texture_info* info = 0; @@ -197,25 +234,15 @@ void texture_database::merge_mdata(texture_database* base_tex_db, break; } - if (info) - *info = i; - else - texture.push_back(i); + if (!info) { + texture.push_back({}); + info = &texture.back(); + } + + info->id = i.id; + info->name = i.name; + info->name_hash = hash_string_murmurhash(info->name); } - - if (this != base_tex_db) { - ready = true; - modern = base_tex_db->modern; - is_x = base_tex_db->is_x; - } -} - -void texture_database::split_mdata(texture_database* base_tex_db, - texture_database* mdata_tex_db) { - if (!base_tex_db || !mdata_tex_db - || !ready || !mdata_tex_db->ready) - return; - } uint32_t texture_database::get_texture_id(const char* name) { @@ -240,30 +267,7 @@ const char* texture_database::get_texture_name(uint32_t id) { return 0; } -bool texture_database::load_file(void* data, const char* path, const char* file, uint32_t hash) { - size_t file_len = utf8_length(file); - - const char* t = strrchr(file, '.'); - if (t) - file_len = t - file; - - std::string s = path + std::string(file, file_len); - - texture_database* tex_db = (texture_database*)data; - tex_db->read(s.c_str(), tex_db->modern); - - return tex_db->ready; -} - -texture_info::texture_info() : name_hash(hash_murmurhash_empty), id((uint32_t)-1) { - -} - -texture_info::~texture_info() { - -} - -static void texture_database_classic_read_inner(texture_database* tex_db, stream& s) { +static void texture_database_file_classic_read_inner(texture_database_file* tex_db, stream& s) { uint32_t textures_count = s.read_uint32_t(); uint32_t textures_offset = s.read_uint32_t(); @@ -271,10 +275,9 @@ static void texture_database_classic_read_inner(texture_database* tex_db, stream s.position_push(textures_offset, SEEK_SET); for (uint32_t i = 0; i < textures_count; i++) { - texture_info& info = tex_db->texture[i]; + texture_info_file& info = tex_db->texture[i]; info.id = s.read_uint32_t(); info.name = s.read_string_null_terminated_offset(s.read_uint32_t()); - info.name_hash = hash_string_murmurhash(&info.name); } s.position_pop(); @@ -283,7 +286,7 @@ static void texture_database_classic_read_inner(texture_database* tex_db, stream tex_db->ready = true; } -static void texture_database_classic_write_inner(texture_database* tex_db, stream& s) { +static void texture_database_file_classic_write_inner(texture_database_file* tex_db, stream& s) { s.write_uint32_t(0x90669066); s.write_uint32_t(0x90669066); s.write_uint32_t(0x90669066); @@ -299,7 +302,7 @@ static void texture_database_classic_write_inner(texture_database* tex_db, strea std::vector string_offsets; string_offsets.reserve(textures_count); - for (texture_info& i : tex_db->texture) { + for (texture_info_file& i : tex_db->texture) { string_offsets.push_back(s.get_position()); s.write_string_null_terminated(i.name); } @@ -308,7 +311,7 @@ static void texture_database_classic_write_inner(texture_database* tex_db, strea int64_t textures_offset = s.get_position(); if (string_offsets.size()) { size_t off_idx = 0; - for (texture_info& i : tex_db->texture) { + for (texture_info_file& i : tex_db->texture) { s.write_uint32_t(i.id); s.write_uint32_t((uint32_t)string_offsets[off_idx++]); } @@ -321,7 +324,7 @@ static void texture_database_classic_write_inner(texture_database* tex_db, strea s.position_pop(); } -static void texture_database_modern_read_inner(texture_database* tex_db, stream& s, uint32_t header_length) { +static void texture_database_file_modern_read_inner(texture_database_file* tex_db, stream& s, uint32_t header_length) { bool is_x = true; s.set_position(0x04, SEEK_SET); @@ -337,17 +340,15 @@ static void texture_database_modern_read_inner(texture_database* tex_db, stream& s.position_push(textures_offset, SEEK_SET); if (!is_x) for (uint32_t i = 0; i < textures_count; i++) { - texture_info& info = tex_db->texture[i]; + texture_info_file& info = tex_db->texture[i]; info.id = s.read_uint32_t_reverse_endianness(); info.name = s.read_string_null_terminated_offset(s.read_offset_f2(header_length)); - info.name_hash = hash_string_murmurhash(&info.name); } else for (uint32_t i = 0; i < textures_count; i++) { - texture_info& info = tex_db->texture[i]; + texture_info_file& info = tex_db->texture[i]; info.id = s.read_uint32_t_reverse_endianness(); info.name = s.read_string_null_terminated_offset(s.read_offset_x()); - info.name_hash = hash_string_murmurhash(&info.name); } s.position_pop(); @@ -356,7 +357,7 @@ static void texture_database_modern_read_inner(texture_database* tex_db, stream& tex_db->ready = true; } -static void texture_database_modern_write_inner(texture_database* tex_db, stream& s) { +static void texture_database_file_modern_write_inner(texture_database_file* tex_db, stream& s) { stream s_mtxi; s_mtxi.open(); uint32_t off; @@ -403,8 +404,8 @@ static void texture_database_modern_write_inner(texture_database* tex_db, stream strings.reserve(textures_count); - for (texture_info& i : tex_db->texture) - texture_database_strings_push_back_check(strings, i.name); + for (texture_info_file& i : tex_db->texture) + texture_database_file_strings_push_back_check(strings, i.name); quicksort_string(strings.data(), strings.size()); string_offsets.reserve(strings.size()); @@ -420,16 +421,16 @@ static void texture_database_modern_write_inner(texture_database* tex_db, stream s_mtxi.align_write(0x10); if (!is_x) - for (texture_info& i : tex_db->texture) { + for (texture_info_file& i : tex_db->texture) { s_mtxi.write_uint32_t(i.id); - int64_t offset = texture_database_strings_get_string_offset(strings, + int64_t offset = texture_database_file_strings_get_string_offset(strings, string_offsets, i.name); io_write_offset_f2_pof_add(s_mtxi, offset, 0x20, &pof); } else - for (texture_info& i : tex_db->texture) { + for (texture_info_file& i : tex_db->texture) { s_mtxi.write_uint32_t(i.id); - int64_t offset = texture_database_strings_get_string_offset(strings, + int64_t offset = texture_database_file_strings_get_string_offset(strings, string_offsets, i.name); io_write_offset_x_pof_add(s_mtxi, offset, &pof); } @@ -451,7 +452,7 @@ static void texture_database_modern_write_inner(texture_database* tex_db, stream st.write(s, true, tex_db->is_x); } -inline static int64_t texture_database_strings_get_string_offset(std::vector& vec, +inline static int64_t texture_database_file_strings_get_string_offset(std::vector& vec, std::vector& vec_off, std::string& str) { for (std::string& i : vec) if (str == i) @@ -459,7 +460,7 @@ inline static int64_t texture_database_strings_get_string_offset(std::vector& vec, std::string& str) { +inline static void texture_database_file_strings_push_back_check(std::vector& vec, std::string& str) { for (std::string& i : vec) if (str == i) return; diff --git a/src/KKdLib/database/texture.hpp b/src/KKdLib/database/texture.hpp index 6c9ca6a0..6df6cabe 100644 --- a/src/KKdLib/database/texture.hpp +++ b/src/KKdLib/database/texture.hpp @@ -9,6 +9,14 @@ #include #include "../default.hpp" +struct texture_info_file { + std::string name; + uint32_t id; + + texture_info_file(); + ~texture_info_file(); +}; + struct texture_info { std::string name; uint32_t name_hash; @@ -18,15 +26,15 @@ struct texture_info { ~texture_info(); }; -struct texture_database { +struct texture_database_file { bool ready; bool modern; bool is_x; - std::vector texture; + std::vector texture; - texture_database(); - ~texture_database(); + texture_database_file(); + virtual ~texture_database_file(); void read(const char* path, bool modern); void read(const wchar_t* path, bool modern); @@ -35,13 +43,17 @@ struct texture_database { void write(const wchar_t* path); void write(void** data, size_t* size); - void merge_mdata(texture_database* base_tex_db, - texture_database* mdata_tex_db); - void split_mdata(texture_database* base_tex_db, - texture_database* mdata_tex_db); + static bool load_file(void* data, const char* path, const char* file, uint32_t hash); +}; + +struct texture_database { + std::vector texture; + + texture_database(); + virtual ~texture_database(); + + void add(texture_database_file* tex_db_file); uint32_t get_texture_id(const char* name); const char* get_texture_name(uint32_t id); - - static bool load_file(void* data, const char* path, const char* file, uint32_t hash); }; diff --git a/src/KKdLib/enbaya.hpp b/src/KKdLib/enbaya.hpp index 460bc8d1..009c16be 100644 --- a/src/KKdLib/enbaya.hpp +++ b/src/KKdLib/enbaya.hpp @@ -7,7 +7,7 @@ #include "default.hpp" #include "quat.hpp" -#include "quat_trans.h" +#include "quat_trans.hpp" #include "vec.hpp" struct enb_track { diff --git a/src/KKdLib/farc.cpp b/src/KKdLib/farc.cpp index 746f74d0..51b2846a 100644 --- a/src/KKdLib/farc.cpp +++ b/src/KKdLib/farc.cpp @@ -24,7 +24,8 @@ static errno_t farc_get_files(farc* f); static void farc_pack_files(farc* f, stream& s, farc_compress_mode mode, bool get_files); static errno_t farc_read_header(farc* f, stream& s); static void farc_unpack_files(farc* f, stream& s, bool save); -static void farc_unpack_file(farc* f, stream& s, farc_file* ff); +static void farc_unpack_file(farc* f, stream& s, farc_file* ff, + bool save = false, char* temp_path = 0, size_t dir_len = 0); farc::farc() : flags(), ft() { signature = FARC_FArC; @@ -36,7 +37,7 @@ farc::~farc() { } farc_file::farc_file() : offset(), size(), size_compressed(), -data(), data_compressed(), flags(), data_changed() { +data(), data_compressed(), compressed(), encrypted(), data_changed() { } @@ -180,7 +181,7 @@ farc_file* farc::read_file(const char* name) { uint32_t name_hash = hash_utf8_murmurhash(name); for (farc_file& i : files) { - if (hash_string_murmurhash(&i.name) != name_hash) + if (hash_string_murmurhash(i.name) != name_hash) continue; if (!i.data && i.data_compressed) @@ -203,7 +204,7 @@ farc_file* farc::read_file(const wchar_t* name) { uint32_t name_hash = hash_utf16_murmurhash(name); for (farc_file& i : files) { - if (hash_string_murmurhash(&i.name) != name_hash) + if (hash_string_murmurhash(i.name) != name_hash) continue; if (!i.data && i.data_compressed) @@ -566,6 +567,20 @@ static void farc_pack_files(farc* f, stream& s, farc_compress_mode mode, bool ge break; } + bool compressed = false; + switch (mode) { + case FARC_COMPRESS_FArc: + case FARC_COMPRESS_FARC: + case FARC_COMPRESS_FARC_AES: + compressed = false; + break; + case FARC_COMPRESS_FArC: + case FARC_COMPRESS_FARC_GZIP: + case FARC_COMPRESS_FARC_GZIP_AES: + compressed = true; + break; + } + if (mode == FARC_COMPRESS_FArc) for (farc_file& i : f->files) { s.write_string_null_terminated(i.name); @@ -576,8 +591,8 @@ static void farc_pack_files(farc* f, stream& s, farc_compress_mode mode, bool ge for (farc_file& i : f->files) { s.write_string_null_terminated(i.name); s.write_int32_t_reverse_endianness((int32_t)i.offset, true); - s.write_int32_t_reverse_endianness((int32_t)i.size_compressed, true); - s.write_int32_t_reverse_endianness((int32_t)i.size, true); + s.write_int32_t_reverse_endianness((int32_t)(compressed ? i.size : i.size_compressed), true); + s.write_int32_t_reverse_endianness((int32_t)(compressed ? i.size : 0), true); } align = align_val(align, 0x10) - align; @@ -612,9 +627,9 @@ static errno_t farc_read_header(farc* f, stream& s) { if (f->signature == FARC_FARC) { f->flags = (farc_flags)s.read_int32_t_reverse_endianness(true); s.read_int32_t(); - int32_t farc_mode = s.read_int32_t_reverse_endianness(true); + int32_t alignment = s.read_int32_t_reverse_endianness(true); - f->ft = (f->flags & FARC_AES) && (farc_mode & (farc_mode - 1)); + f->ft = (f->flags & FARC_AES) && (alignment & (alignment - 1)); if (f->ft) { header_length -= 0x08; s.set_position(-0x04, SEEK_CUR); @@ -633,10 +648,14 @@ static errno_t farc_read_header(farc* f, stream& s) { dt = d_t = force_malloc_s(uint8_t, header_length); s.read(d_t, header_length); if (f->ft) { + header_length -= 0x10; + aes128_ctx ctx; aes128_init_ctx_iv(&ctx, key_ft, dt); dt += 0x10; - aes128_cbc_decrypt_buffer(&ctx, dt, (size_t)header_length - 0x10); + aes128_cbc_decrypt_buffer(&ctx, dt, header_length); + + header_length -= ((uint8_t*)dt)[header_length - 1]; // PKCS7 Padding dt += sizeof(int32_t); } @@ -679,7 +698,10 @@ static errno_t farc_read_header(farc* f, stream& s) { i.offset = (size_t)load_reverse_endianness_int32_t((void*)dt); i.size_compressed = (size_t)load_reverse_endianness_int32_t((void*)(dt + 4)); i.size = (size_t)load_reverse_endianness_int32_t((void*)(dt + 8)); - i.flags = (farc_flags)load_reverse_endianness_int32_t((void*)(dt + 12)); + farc_flags flags = (farc_flags)load_reverse_endianness_int32_t((void*)(dt + 12)); + + i.compressed = i.size || flags & FARC_GZIP ? true : false; + i.encrypted = (f->flags | flags) & FARC_AES ? true : false; dt += sizeof(int32_t) * 4; } else if (f->signature != FARC_FArc) @@ -689,6 +711,9 @@ static errno_t farc_read_header(farc* f, stream& s) { i.offset = (size_t)load_reverse_endianness_int32_t((void*)dt); i.size_compressed = (size_t)load_reverse_endianness_int32_t((void*)(dt + 4)); i.size = (size_t)load_reverse_endianness_int32_t((void*)(dt + 8)); + + i.compressed = i.size ? true : false; + i.encrypted = f->flags & FARC_AES ? true : false; dt += sizeof(int32_t) * 3; } else @@ -697,6 +722,10 @@ static errno_t farc_read_header(farc* f, stream& s) { dt += i.name.size() + 1; i.offset = (size_t)load_reverse_endianness_int32_t((void*)dt); i.size = (size_t)load_reverse_endianness_int32_t((void*)(dt + 4)); + + i.size_compressed = 0; + i.compressed = false; + i.encrypted = false; dt += sizeof(int32_t) * 2; } free(d_t); @@ -707,12 +736,6 @@ static void farc_unpack_files(farc* f, stream& s, bool save) { if (!f || s.io.check_null()) return; - for (farc_file& i : f->files) - farc_unpack_file(f, s, &i); - - if (!save) - return; - size_t max_path_len = 0; size_t dir_len = f->directory_path.size(); for (farc_file& i : f->files) { @@ -729,24 +752,13 @@ static void farc_unpack_files(farc* f, stream& s, bool save) { memcpy(temp_path, f->directory_path.c_str(), sizeof(char) * dir_len); temp_path[dir_len] = '\\'; - for (farc_file& i : f->files) { - if (i.name.c_str()) { - memcpy(temp_path + dir_len + 1, i.name.c_str(), sizeof(wchar_t) * i.name.size()); - temp_path[dir_len + 1 + i.name.size()] = '\0'; - } + for (farc_file& i : f->files) + farc_unpack_file(f, s, &i, save, temp_path, dir_len); - if (i.data) { - stream temp_s; - temp_s.open(temp_path, "wb"); - if (temp_s.io.stream) - temp_s.write(i.data, i.size); - free(i.data); - } - } free(temp_path); } -static void farc_unpack_file(farc* f, stream& s, farc_file* ff) { +static void farc_unpack_file(farc* f, stream& s, farc_file* ff, bool save, char* temp_path, size_t dir_len ) { if (!f || s.io.check_null()) return; @@ -755,68 +767,79 @@ static void farc_unpack_file(farc* f, stream& s, farc_file* ff) { s.set_position(ff->offset, SEEK_SET); - if (f->signature != FARC_FARC) { - if (f->signature != FARC_FArC) { - ff->data_compressed = 0; - ff->data = force_malloc(ff->size); - s.read(ff->data, ff->size); - } - else if (ff->data_compressed) - deflate::decompress(ff->data_compressed, ff->size_compressed, - &ff->data, &ff->size, deflate::MODE_GZIP); - else { - ff->data_compressed = force_malloc(ff->size_compressed); - s.read(ff->data_compressed, ff->size_compressed); - deflate::decompress(ff->data_compressed, ff->size_compressed, - &ff->data, &ff->size, deflate::MODE_GZIP); - } + if (f->signature == FARC_FArc) { + ff->data_compressed = 0; + ff->data = force_malloc(ff->size); + s.read(ff->data, ff->size); } - else { - bool aes = (f->flags | ff->flags) & FARC_AES; - bool gzip = (f->flags | ff->flags) & FARC_GZIP; - if (!aes && !gzip) { - ff->data_compressed = 0; - ff->data = force_malloc(ff->size); - s.read(ff->data, ff->size); - } - else if (ff->data_compressed) - deflate::decompress(ff->data_compressed, ff->size_compressed, - &ff->data, &ff->size, deflate::MODE_GZIP); - else { - size_t temp_s = aes ? align_val(ff->size_compressed, 0x10) : ff->size_compressed; - void* temp = force_malloc(temp_s); - s.read(temp, temp_s); + else if (f->signature == FARC_FArC) { + ff->data_compressed = force_malloc(ff->size_compressed); + s.read(ff->data_compressed, ff->size_compressed); + deflate::decompress(ff->data_compressed, ff->size_compressed, + &ff->data, &ff->size, deflate::MODE_GZIP); + } + else if (ff->encrypted || ff->compressed) { + size_t temp_s = ff->encrypted ? align_val(ff->size_compressed, 0x10) : ff->size_compressed; + void* temp = force_malloc(temp_s); + s.read(temp, temp_s); - void* t = temp; - if (aes) - if (f->ft) { - ff->size_compressed -= 0x10; - temp_s -= 0x10; - t = (void*)((uint64_t)t + 0x10); + void* t = temp; + if (ff->encrypted) + if (f->ft) { + temp_s -= 0x10; + t = (void*)((uint64_t)t + 0x10); - aes128_ctx ctx; - aes128_init_ctx_iv(&ctx, key_ft, (uint8_t*)temp); - aes128_cbc_decrypt_buffer(&ctx, (uint8_t*)t, temp_s); - } - else { - aes128_ctx ctx; - aes128_init_ctx(&ctx, key); - aes128_ecb_decrypt_buffer(&ctx, (uint8_t*)t, temp_s); - } + aes128_ctx ctx; + aes128_init_ctx_iv(&ctx, key_ft, (uint8_t*)temp); + aes128_cbc_decrypt_buffer(&ctx, (uint8_t*)t, temp_s); - if (!gzip) { - ff->data_compressed = 0; - ff->data = force_malloc(ff->size); - memcpy(ff->data, t, ff->size); + ff->size_compressed = temp_s - ((uint8_t*)t)[temp_s - 1]; // PKCS7 Padding } else { - ff->data_compressed = force_malloc(ff->size_compressed); - memcpy(ff->data_compressed, t, ff->size_compressed); - deflate::decompress(ff->data_compressed, ff->size_compressed, - &ff->data, &ff->size, deflate::MODE_GZIP); + aes128_ctx ctx; + aes128_init_ctx(&ctx, key); + aes128_ecb_decrypt_buffer(&ctx, (uint8_t*)t, temp_s); } - free(temp); + + if (!ff->compressed) { + ff->data_compressed = 0; + ff->data = force_malloc(ff->size); + memcpy(ff->data, t, ff->size); } + else { + ff->data_compressed = force_malloc(ff->size_compressed); + memcpy(ff->data_compressed, t, ff->size_compressed); + deflate::decompress(ff->data_compressed, ff->size_compressed, + &ff->data, &ff->size, deflate::MODE_GZIP); + } + free(temp); + } + else { + ff->data_compressed = 0; + ff->data = force_malloc(ff->size); + s.read(ff->data, ff->size); } ff->data_changed = false; + + if (!save) + return; + + if (ff->data) { + if (ff->name.size()) { + memcpy(temp_path + dir_len + 1, ff->name.c_str(), ff->name.size()); + temp_path[dir_len + 1 + ff->name.size()] = '\0'; + + stream temp_s; + temp_s.open(temp_path, "wb"); + if (temp_s.io.stream) + temp_s.write(ff->data, ff->size); + } + free(ff->data); + ff->data = 0; + } + + if (ff->data_compressed) { + free(ff->data_compressed); + ff->data_compressed = 0; + } } diff --git a/src/KKdLib/farc.hpp b/src/KKdLib/farc.hpp index 614634fb..e6764894 100644 --- a/src/KKdLib/farc.hpp +++ b/src/KKdLib/farc.hpp @@ -31,13 +31,14 @@ enum farc_compress_mode { }; struct farc_file { + std::string name; size_t offset; size_t size; size_t size_compressed; - std::string name; void* data; void* data_compressed; - farc_flags flags; + bool compressed; + bool encrypted; bool data_changed; farc_file(); diff --git a/src/KKdLib/half_t.cpp b/src/KKdLib/half_t.cpp index 30b44768..8483d5a5 100644 --- a/src/KKdLib/half_t.cpp +++ b/src/KKdLib/half_t.cpp @@ -4,6 +4,9 @@ */ #include "half_t.hpp" +#include + +extern bool f16c; inline half_t load_reverse_endianness_half_t(void* ptr) { return (half_t)_byteswap_ushort(*(uint16_t*)ptr); @@ -18,6 +21,9 @@ inline half_t reverse_endianness_half_t(half_t value) { } float_t half_to_float(half_t h) { + if (f16c) + return _mm_cvtss_f32( _mm_cvtph_ps(_mm_cvtsi32_si128((uint16_t)h))); + int32_t si32; uint16_t sign = (h >> 15) & 0x001; uint16_t exponent = (h >> 10) & 0x01F; @@ -33,6 +39,9 @@ float_t half_to_float(half_t h) { } half_t float_to_half(float_t val) { + if (f16c) + return (half_t)_mm_cvtsi128_si32(_mm_cvtps_ph(_mm_set_ss(val), _MM_FROUND_CUR_DIRECTION)); + int32_t si32 = *(int32_t*)&val; if (si32 == 0x00000000) return FLOAT16_POSITIVE_ZERO; @@ -56,6 +65,9 @@ half_t float_to_half(float_t val) { } double_t half_to_double(half_t h) { + if (f16c) + return _mm_cvtss_f32(_mm_cvtph_ps(_mm_cvtsi32_si128((uint16_t)h))); + int64_t si64; uint16_t sign = (h >> 15) & 0x001; uint16_t exponent = (h >> 10) & 0x01F; @@ -71,6 +83,9 @@ double_t half_to_double(half_t h) { } half_t double_to_half(double_t val) { + if (f16c) + return (half_t)_mm_cvtsi128_si32(_mm_cvtps_ph(_mm_cvtpd_ps(_mm_set_sd(val)), _MM_FROUND_CUR_DIRECTION)); + int64_t si64 = *(int64_t*)&val; if (si64 == 0x0000000000000000) return FLOAT16_POSITIVE_ZERO; diff --git a/src/KKdLib/hash.cpp b/src/KKdLib/hash.cpp index b16d0f13..26e46bee 100644 --- a/src/KKdLib/hash.cpp +++ b/src/KKdLib/hash.cpp @@ -40,8 +40,13 @@ static const uint16_t hash_crc16_ccitt_table[] = { 0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0, }; +// Empty string const uint64_t hash_fnv1a64m_empty = 0xCBF29CE44FD0BFC1; +// Empty string const uint32_t hash_murmurhash_empty = 0x0CAD3078; +// "NULL" string +const uint32_t hash_murmurhash_null = 0x5A009B23; +// Empty string const uint32_t hash_crc16_ccitt_empty = 0xFFFF; // FNV 1a 64-bit Modified @@ -78,8 +83,8 @@ inline uint64_t hash_utf16_fnv1a64m(const wchar_t* data, bool make_upper) { return hash; } -inline uint64_t hash_string_fnv1a64m(const std::string* data, bool make_upper) { - return hash_fnv1a64m(data->c_str(), data->size(), make_upper); +inline uint64_t hash_string_fnv1a64m(const std::string& data, bool make_upper) { + return hash_fnv1a64m(data.c_str(), data.size(), make_upper); } // MurmurHash @@ -226,8 +231,8 @@ inline uint32_t hash_utf16_murmurhash(const wchar_t* data, uint32_t seed, bool u return hash; } -inline uint32_t hash_string_murmurhash(const std::string* data, uint32_t seed, bool upper) { - return hash_murmurhash(data->c_str(), data->size(), seed, upper); +inline uint32_t hash_string_murmurhash(const std::string& data, uint32_t seed, bool upper) { + return hash_murmurhash(data.c_str(), data.size(), seed, upper); } // CRC16-CCITT @@ -260,6 +265,6 @@ inline uint16_t hash_utf16_crc16_ccitt(const wchar_t* data, bool make_upper) { return hash; } -inline uint16_t hash_string_crc16_ccitt(const std::string* data, bool make_upper) { - return hash_crc16_ccitt(data->c_str(), data->size(), make_upper); +inline uint16_t hash_string_crc16_ccitt(const std::string& data, bool make_upper) { + return hash_crc16_ccitt(data.c_str(), data.size(), make_upper); } diff --git a/src/KKdLib/hash.hpp b/src/KKdLib/hash.hpp index d61c5e14..b4fd63f7 100644 --- a/src/KKdLib/hash.hpp +++ b/src/KKdLib/hash.hpp @@ -8,19 +8,24 @@ #include #include "default.hpp" +// Empty string extern const uint64_t hash_fnv1a64m_empty; +// Empty string extern const uint32_t hash_murmurhash_empty; +// "NULL" string +extern const uint32_t hash_murmurhash_null; +// Empty string extern const uint32_t hash_crc16_ccitt_empty; extern uint64_t hash_fnv1a64m(const void* data, size_t size, bool make_upper = false); extern uint64_t hash_utf8_fnv1a64m(const char* data, bool make_upper = false); extern uint64_t hash_utf16_fnv1a64m(const wchar_t* data, bool make_upper = false); -extern uint64_t hash_string_fnv1a64m(const std::string* data, bool make_upper = false); +extern uint64_t hash_string_fnv1a64m(const std::string& data, 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); extern uint32_t hash_utf8_murmurhash(const char* data, uint32_t seed = 0, bool upper = false); extern uint32_t hash_utf16_murmurhash(const wchar_t* data, uint32_t seed = 0, bool upper = false); -extern uint32_t hash_string_murmurhash(const std::string* data, uint32_t seed = 0, bool upper = false); +extern uint32_t hash_string_murmurhash(const std::string& data, uint32_t seed = 0, bool upper = false); extern uint16_t hash_crc16_ccitt(const void* data, size_t size, bool make_upper = false); extern uint16_t hash_utf8_crc16_ccitt(const char* data, bool make_upper = false); extern uint16_t hash_utf16_crc16_ccitt(const wchar_t* data, bool make_upper = false); -extern uint16_t hash_string_crc16_ccitt(const std::string* data, bool make_upper = false); +extern uint16_t hash_string_crc16_ccitt(const std::string& data, bool make_upper = false); diff --git a/src/KKdLib/interpolation.c b/src/KKdLib/interpolation.cpp similarity index 93% rename from src/KKdLib/interpolation.c rename to src/KKdLib/interpolation.cpp index 2c6a948a..53a32652 100644 --- a/src/KKdLib/interpolation.c +++ b/src/KKdLib/interpolation.cpp @@ -3,7 +3,7 @@ GitHub/GitLab: korenkonder */ -#include "interpolation.h" +#include "interpolation.hpp" inline float_t interpolate_linear_value(float_t p1, float_t p2, float_t f1, float_t f2, float_t f) { float_t t = (f - f1) / (f2 - f1); @@ -58,18 +58,18 @@ inline void interpolate_linear_value_vec4(vec4* p1, vec4* p2, vec4* f1, vec4* f2 __m128 _f1; __m128 _f2; __m128 _f; - _p1 = p1->data; - _p2 = p2->data; - _f1 = f1->data; - _f2 = f2->data; - _f = f->data; + _p1 = _mm_loadu_ps((float*)p1); + _p2 = _mm_loadu_ps((float*)p2); + _f1 = _mm_loadu_ps((float*)f1); + _f2 = _mm_loadu_ps((float*)f2); + _f = _mm_loadu_ps((float*)f); const __m128 _1 = _mm_set_ps1(1.0f); __m128 df = _mm_sub_ps(_f2, _f1); __m128 t = _mm_div_ps(_mm_sub_ps(_f, _f1), df); __m128 t1 = _mm_sub_ps(_1, t); - value->data = _mm_add_ps(_mm_mul_ps(_p1, t1), _mm_mul_ps(_p2, t)); + _mm_storeu_ps((float*)value, _mm_add_ps(_mm_mul_ps(_p1, t1), _mm_mul_ps(_p2, t))); } inline void interpolate_linear(float_t p1, float_t p2, @@ -163,13 +163,13 @@ inline void interpolate_chs_value_vec4(vec4* p1, vec4* p2, __m128 _f1; __m128 _f2; __m128 _f; - _p1 = p1->data; - _p2 = p2->data; - _t1 = t1->data; - _t2 = t2->data; - _f1 = f1->data; - _f2 = f2->data; - _f = f->data; + _p1 = _mm_loadu_ps((float*)p1); + _p2 = _mm_loadu_ps((float*)p2); + _t1 = _mm_loadu_ps((float*)t1); + _t2 = _mm_loadu_ps((float*)t2); + _f1 = _mm_loadu_ps((float*)f1); + _f2 = _mm_loadu_ps((float*)f2); + _f = _mm_loadu_ps((float*)f); const __m128 _1 = _mm_set_ps1(1.0f); const __m128 _2 = _mm_set_ps1(2.0f); @@ -181,7 +181,7 @@ inline void interpolate_chs_value_vec4(vec4* p1, vec4* p2, __m128 delta = _mm_mul_ps(_mm_mul_ps(_mm_mul_ps(t, t), _mm_sub_ps(_3, _mm_mul_ps(_2, t))), _mm_sub_ps(_p2, _p1)); __m128 tangent = _mm_mul_ps(_mm_add_ps(_mm_mul_ps(t_1, _t1), _mm_mul_ps(t, _t2)), _mm_mul_ps(df, t_1)); - value->data = _mm_add_ps(_mm_add_ps(_p1, delta), tangent); + _mm_storeu_ps((float*)value, _mm_add_ps(_mm_add_ps(_p1, delta), tangent)); } inline void interpolate_chs(float_t p1, float_t p2, diff --git a/src/KKdLib/interpolation.h b/src/KKdLib/interpolation.hpp similarity index 100% rename from src/KKdLib/interpolation.h rename to src/KKdLib/interpolation.hpp diff --git a/src/KKdLib/key_val.cpp b/src/KKdLib/key_val.cpp index 5a19ae5e..424764a6 100644 --- a/src/KKdLib/key_val.cpp +++ b/src/KKdLib/key_val.cpp @@ -808,7 +808,7 @@ static int64_t key_val_get_key_index(key_val* kv, std::string& str) { if (curr_scope->key_hash_index.size() < 1) return -1; - uint64_t hash = hash_string_fnv1a64m(&str); + uint64_t hash = hash_string_fnv1a64m(str); std::vector::iterator key = curr_scope->key_hash_index.begin(); size_t len = curr_scope->count; diff --git a/src/KKdLib/key_val.hpp b/src/KKdLib/key_val.hpp index 2a13274e..57559bdf 100644 --- a/src/KKdLib/key_val.hpp +++ b/src/KKdLib/key_val.hpp @@ -48,7 +48,7 @@ struct key_val { char* buf; key_val(); - ~key_val(); + virtual ~key_val(); void close_scope(); void file_read(const char* path); diff --git a/src/KKdLib/light_param/face.cpp b/src/KKdLib/light_param/face.cpp index ad6c8132..1d8cc3b8 100644 --- a/src/KKdLib/light_param/face.cpp +++ b/src/KKdLib/light_param/face.cpp @@ -18,6 +18,10 @@ light_param_face::light_param_face() : ready(), offset(), scale(), position(), d } +light_param_face::~light_param_face() { + +} + void light_param_face::read(const char* path) { char* path_txt = str_utils_add(path, ".txt"); if (path_check_file_exists(path_txt)) { @@ -80,10 +84,6 @@ void light_param_face::write(void** data, size_t* size) { s.copy(data, size); } -light_param_face::~light_param_face() { - -} - bool light_param_face::load_file(void* data, const char* path, const char* file, uint32_t hash) { size_t file_len = utf8_length(file); diff --git a/src/KKdLib/light_param/face.hpp b/src/KKdLib/light_param/face.hpp index 3d992dea..b807d74a 100644 --- a/src/KKdLib/light_param/face.hpp +++ b/src/KKdLib/light_param/face.hpp @@ -17,13 +17,14 @@ struct light_param_face { vec3 direction; light_param_face(); + virtual ~light_param_face(); + void read(const char* path); void read(const wchar_t* path); void read(const void* data, size_t size); void write(const char* path); void write(const wchar_t* path); void write(void** data, size_t* size); - ~light_param_face(); static bool load_file(void* data, const char* path, const char* file, uint32_t hash); }; diff --git a/src/KKdLib/light_param/fog.cpp b/src/KKdLib/light_param/fog.cpp index 90d0bd80..8b156196 100644 --- a/src/KKdLib/light_param/fog.cpp +++ b/src/KKdLib/light_param/fog.cpp @@ -168,9 +168,9 @@ static void light_param_fog_read_inner(light_param_fog* fog, stream& s) { group->has_linear = true; } else if (!str_utils_compare_length(buf, sizeof(buf), "color", 5)) { - vec4u* color = &group->color; + vec4& color = group->color; if (buf[5] != ' ' || sscanf_s(buf + 6, "%f %f %f %f", - &color->x, &color->y, &color->z, &color->w) != 4) + &color.x, &color.y, &color.z, &color.w) != 4) goto End; group->has_color = true; @@ -214,12 +214,12 @@ static void light_param_fog_write_inner(light_param_fog* fog, stream& s) { } if (group->has_color) { - vec4u* color = &group->color; + vec4& color = group->color; s.write("color", 5); - light_param_fog_write_float_t(s, buf, sizeof(buf), color->x); - light_param_fog_write_float_t(s, buf, sizeof(buf), color->y); - light_param_fog_write_float_t(s, buf, sizeof(buf), color->z); - light_param_fog_write_float_t(s, buf, sizeof(buf), color->w); + light_param_fog_write_float_t(s, buf, sizeof(buf), color.x); + light_param_fog_write_float_t(s, buf, sizeof(buf), color.y); + light_param_fog_write_float_t(s, buf, sizeof(buf), color.z); + light_param_fog_write_float_t(s, buf, sizeof(buf), color.w); s.write_char('\n'); } diff --git a/src/KKdLib/light_param/fog.hpp b/src/KKdLib/light_param/fog.hpp index 1ba5a5ec..b1208744 100644 --- a/src/KKdLib/light_param/fog.hpp +++ b/src/KKdLib/light_param/fog.hpp @@ -31,7 +31,7 @@ struct light_param_fog_group { float_t linear_start; float_t linear_end; bool has_color; - vec4u color; + vec4 color; light_param_fog_group(); ~light_param_fog_group(); @@ -43,7 +43,7 @@ struct light_param_fog { light_param_fog_group group[FOG_MAX]; light_param_fog(); - ~light_param_fog(); + virtual ~light_param_fog(); void read(const char* path); void read(const wchar_t* path); diff --git a/src/KKdLib/light_param/glow.cpp b/src/KKdLib/light_param/glow.cpp index 5a076fdd..7948adf4 100644 --- a/src/KKdLib/light_param/glow.cpp +++ b/src/KKdLib/light_param/glow.cpp @@ -137,25 +137,25 @@ static void light_param_glow_read_inner(light_param_glow* glow, stream& s) { glow->has_saturate_coef = true; } else if (!str_utils_compare_length(buf, sizeof(buf), "flare", 5)) { - vec3* flare = &glow->flare; + vec3& flare = glow->flare; if (buf[5] != ' ' || sscanf_s(buf + 6, "%f %f %f", - &flare->x, &flare->y, &flare->z) != 3) + &flare.x, &flare.y, &flare.z) != 3) goto End; glow->has_flare = true; } else if (!str_utils_compare_length(buf, sizeof(buf), "sigma", 5)) { - vec3* sigma = &glow->sigma; + vec3& sigma = glow->sigma; if (buf[5] != ' ' || sscanf_s(buf + 6, "%f %f %f", - &sigma->x, &sigma->y, &sigma->z) != 3) + &sigma.x, &sigma.y, &sigma.z) != 3) goto End; glow->has_sigma = true; } else if (!str_utils_compare_length(buf, sizeof(buf), "intensity", 9)) { - vec3* intensity = &glow->intensity; + vec3& intensity = glow->intensity; if (buf[9] != ' ' || sscanf_s(buf + 10, "%f %f %f", - &intensity->x, &intensity->y, &intensity->z) != 3) + &intensity.x, &intensity.y, &intensity.z) != 3) goto End; glow->has_intensity = true; @@ -175,19 +175,19 @@ static void light_param_glow_read_inner(light_param_glow* glow, stream& s) { glow->has_tone_map_method = true; } else if (!str_utils_compare_length(buf, sizeof(buf), "fade_color", 10)) { - vec4u* fade_color = &glow->fade_color; + vec4& fade_color = glow->fade_color; int32_t* blend_func = &glow->fade_color_blend_func; if (buf[10] != ' ' || sscanf_s(buf + 11, "%f %f %f %f %d", - &fade_color->x, &fade_color->y, &fade_color->z, &fade_color->w, blend_func) != 5) + &fade_color.x, &fade_color.y, &fade_color.z, &fade_color.w, blend_func) != 5) goto End; glow->has_fade_color = true; } else if (!str_utils_compare_length(buf, sizeof(buf), "tone_transform", 14)) { - vec3* start = &glow->tone_transform_start; - vec3* end = &glow->tone_transform_end; + vec3& start = glow->tone_transform_start; + vec3& end = glow->tone_transform_end; if (buf[14] != ' ' || sscanf_s(buf + 15, "%f %f %f %f %f %f", - &start->x, &start->y, &start->z, &end->x, &end->y, &end->z) != 6) + &start.x, &start.y, &start.z, &end.x, &end.y, &end.z) != 6) goto End; glow->has_tone_transform = true; @@ -230,29 +230,29 @@ static void light_param_glow_write_inner(light_param_glow* glow, stream& s) { } if (glow->has_flare) { - vec3* flare = &glow->flare; + vec3& flare = glow->flare; s.write("flare", 5); - light_param_glow_write_float_t(s, buf, sizeof(buf), flare->x); - light_param_glow_write_float_t(s, buf, sizeof(buf), flare->y); - light_param_glow_write_float_t(s, buf, sizeof(buf), flare->z); + light_param_glow_write_float_t(s, buf, sizeof(buf), flare.x); + light_param_glow_write_float_t(s, buf, sizeof(buf), flare.y); + light_param_glow_write_float_t(s, buf, sizeof(buf), flare.z); s.write_char('\n'); } if (glow->has_sigma) { - vec3* sigma = &glow->sigma; + vec3& sigma = glow->sigma; s.write("sigma", 5); - light_param_glow_write_float_t(s, buf, sizeof(buf), sigma->x); - light_param_glow_write_float_t(s, buf, sizeof(buf), sigma->y); - light_param_glow_write_float_t(s, buf, sizeof(buf), sigma->z); + light_param_glow_write_float_t(s, buf, sizeof(buf), sigma.x); + light_param_glow_write_float_t(s, buf, sizeof(buf), sigma.y); + light_param_glow_write_float_t(s, buf, sizeof(buf), sigma.z); s.write_char('\n'); } if (glow->has_intensity) { - vec3* intensity = &glow->intensity; + vec3& intensity = glow->intensity; s.write("intensity", 9); - light_param_glow_write_float_t(s, buf, sizeof(buf), intensity->x); - light_param_glow_write_float_t(s, buf, sizeof(buf), intensity->y); - light_param_glow_write_float_t(s, buf, sizeof(buf), intensity->z); + light_param_glow_write_float_t(s, buf, sizeof(buf), intensity.x); + light_param_glow_write_float_t(s, buf, sizeof(buf), intensity.y); + light_param_glow_write_float_t(s, buf, sizeof(buf), intensity.z); s.write_char('\n'); } @@ -269,27 +269,27 @@ static void light_param_glow_write_inner(light_param_glow* glow, stream& s) { } if (glow->has_fade_color) { - vec4u* fade_color = &glow->fade_color; + vec4& fade_color = glow->fade_color; int32_t blend_func = glow->fade_color_blend_func; s.write("fade_color", 10); - light_param_glow_write_float_t(s, buf, sizeof(buf), fade_color->x); - light_param_glow_write_float_t(s, buf, sizeof(buf), fade_color->y); - light_param_glow_write_float_t(s, buf, sizeof(buf), fade_color->z); - light_param_glow_write_float_t(s, buf, sizeof(buf), fade_color->w); + light_param_glow_write_float_t(s, buf, sizeof(buf), fade_color.x); + light_param_glow_write_float_t(s, buf, sizeof(buf), fade_color.y); + light_param_glow_write_float_t(s, buf, sizeof(buf), fade_color.z); + light_param_glow_write_float_t(s, buf, sizeof(buf), fade_color.w); light_param_glow_write_int32_t(s, buf, sizeof(buf), blend_func); s.write_char('\n'); } if (glow->has_tone_transform) { - vec3* start = &glow->tone_transform_start; - vec3* end = &glow->tone_transform_end; + vec3& start = glow->tone_transform_start; + vec3& end = glow->tone_transform_end; s.write("tone_transform", 14); - light_param_glow_write_float_t(s, buf, sizeof(buf), start->x); - light_param_glow_write_float_t(s, buf, sizeof(buf), start->y); - light_param_glow_write_float_t(s, buf, sizeof(buf), start->z); - light_param_glow_write_float_t(s, buf, sizeof(buf), end->x); - light_param_glow_write_float_t(s, buf, sizeof(buf), end->y); - light_param_glow_write_float_t(s, buf, sizeof(buf), end->z); + light_param_glow_write_float_t(s, buf, sizeof(buf), start.x); + light_param_glow_write_float_t(s, buf, sizeof(buf), start.y); + light_param_glow_write_float_t(s, buf, sizeof(buf), start.z); + light_param_glow_write_float_t(s, buf, sizeof(buf), end.x); + light_param_glow_write_float_t(s, buf, sizeof(buf), end.y); + light_param_glow_write_float_t(s, buf, sizeof(buf), end.z); s.write_char('\n'); } diff --git a/src/KKdLib/light_param/glow.hpp b/src/KKdLib/light_param/glow.hpp index 66d15277..7a4ad265 100644 --- a/src/KKdLib/light_param/glow.hpp +++ b/src/KKdLib/light_param/glow.hpp @@ -36,14 +36,14 @@ struct light_param_glow { bool has_tone_map_method; tone_map_method tone_map_method; bool has_fade_color; - vec4u fade_color; + vec4 fade_color; int32_t fade_color_blend_func; bool has_tone_transform; vec3 tone_transform_start; vec3 tone_transform_end; light_param_glow(); - ~light_param_glow(); + virtual ~light_param_glow(); void read(const char* path); void read(const wchar_t* path); diff --git a/src/KKdLib/light_param/ibl.cpp b/src/KKdLib/light_param/ibl.cpp index a0f09310..d63a68c6 100644 --- a/src/KKdLib/light_param/ibl.cpp +++ b/src/KKdLib/light_param/ibl.cpp @@ -108,7 +108,7 @@ static void light_param_ibl_read_inner(light_param_ibl* ibl, stream& s) { d = light_param_ibl_read_line(buf, sizeof(buf), d); - vec4u dir; + vec4 dir; if (sscanf_s(buf, "%f %f %f", &dir.x, &dir.y, &dir.z) != 3) goto End; @@ -124,7 +124,7 @@ static void light_param_ibl_read_inner(light_param_ibl* ibl, stream& s) { d = light_param_ibl_read_line(buf, sizeof(buf), d); - vec4u col; + vec4 col; if (sscanf_s(buf, "%f %f %f", &col.x, &col.y, &col.z) != 3) goto End; @@ -141,23 +141,23 @@ static void light_param_ibl_read_inner(light_param_ibl* ibl, stream& s) { for (int32_t i = 0; i < 3; i++) { d = light_param_ibl_read_line(buf, sizeof(buf), d); - mat4u* mat = &ibl->diff_coef[index][i]; - if (sscanf_s(buf, "%f %f %f %f", &mat->row0.x, &mat->row1.x, &mat->row2.x, &mat->row3.x) != 4) + mat4& mat = ibl->diff_coef[index][i]; + if (sscanf_s(buf, "%f %f %f %f", &mat.row0.x, &mat.row1.x, &mat.row2.x, &mat.row3.x) != 4) goto End; d = light_param_ibl_read_line(buf, sizeof(buf), d); - if (sscanf_s(buf, "%f %f %f %f", &mat->row0.y, &mat->row1.y, &mat->row2.y, &mat->row3.y) != 4) + if (sscanf_s(buf, "%f %f %f %f", &mat.row0.y, &mat.row1.y, &mat.row2.y, &mat.row3.y) != 4) goto End; d = light_param_ibl_read_line(buf, sizeof(buf), d); - if (sscanf_s(buf, "%f %f %f %f", &mat->row0.z, &mat->row1.z, &mat->row2.z, &mat->row3.z) != 4) + if (sscanf_s(buf, "%f %f %f %f", &mat.row0.z, &mat.row1.z, &mat.row2.z, &mat.row3.z) != 4) goto End; d = light_param_ibl_read_line(buf, sizeof(buf), d); - if (sscanf_s(buf, "%f %f %f %f", &mat->row0.w, &mat->row1.w, &mat->row2.w, &mat->row3.w) != 4) + if (sscanf_s(buf, "%f %f %f %f", &mat.row0.w, &mat.row1.w, &mat.row2.w, &mat.row3.w) != 4) goto End; } } diff --git a/src/KKdLib/light_param/ibl.hpp b/src/KKdLib/light_param/ibl.hpp index a473dd95..01d60039 100644 --- a/src/KKdLib/light_param/ibl.hpp +++ b/src/KKdLib/light_param/ibl.hpp @@ -31,14 +31,14 @@ struct light_param_ibl_specular { struct light_param_ibl { bool ready; - vec4u lit_col[4]; - vec4u lit_dir[4]; - mat4u diff_coef[4][3]; + vec4 lit_col[4]; + vec4 lit_dir[4]; + mat4 diff_coef[4][3]; light_param_ibl_diffuse diffuse[2]; light_param_ibl_specular specular[4]; light_param_ibl(); - ~light_param_ibl(); + virtual ~light_param_ibl(); void read(const char* path); void read(const wchar_t* path); diff --git a/src/KKdLib/light_param/light.cpp b/src/KKdLib/light_param/light.cpp index 368d23a4..63bed58c 100644 --- a/src/KKdLib/light_param/light.cpp +++ b/src/KKdLib/light_param/light.cpp @@ -192,42 +192,42 @@ static void light_param_light_read_inner(light_param_light* light, stream& s) { light->has_type = true; } else if (!str_utils_compare_length(buf, sizeof(buf), "ambient", 7)) { - vec4u* ambient = &light->ambient; + vec4& ambient = light->ambient; if (buf[7] != ' ' || sscanf_s(buf + 8, "%f %f %f %f", - &ambient->x, &ambient->y, &ambient->z, &ambient->w) != 4) + &ambient.x, &ambient.y, &ambient.z, &ambient.w) != 4) goto End; light->has_ambient = true; } else if (!str_utils_compare_length(buf, sizeof(buf), "diffuse", 7)) { - vec4u* diffuse = &light->diffuse; + vec4& diffuse = light->diffuse; if (buf[7] != ' ' || sscanf_s(buf + 8, "%f %f %f %f", - &diffuse->x, &diffuse->y, &diffuse->z, &diffuse->w) != 4) + &diffuse.x, &diffuse.y, &diffuse.z, &diffuse.w) != 4) goto End; light->has_diffuse = true; } else if (!str_utils_compare_length(buf, sizeof(buf), "specular", 8)) { - vec4u* specular = &light->specular; + vec4& specular = light->specular; if (buf[8] != ' ' || sscanf_s(buf + 9, "%f %f %f %f", - &specular->x, &specular->y, &specular->z, &specular->w) != 4) + &specular.x, &specular.y, &specular.z, &specular.w) != 4) goto End; light->has_specular = true; } else if (!str_utils_compare_length(buf, sizeof(buf), "position", 8)) { - vec3* position = &light->position; + vec3& position = light->position; float_t position_w = 0.0f; if (buf[8] != ' ' || sscanf_s(buf + 9, "%f %f %f %f", - &position->x, &position->y, &position->z, &position_w) != 4) + &position.x, &position.y, &position.z, &position_w) != 4) goto End; light->has_position = true; } else if (!str_utils_compare_length(buf, sizeof(buf), "spot_direction", 14)) { - vec3* spot_direction = &light->spot_direction; + vec3& spot_direction = light->spot_direction; if (buf[14] != ' ' || sscanf_s(buf + 15, "%f %f %f", - &spot_direction->x, &spot_direction->y, &spot_direction->z) != 3) + &spot_direction.x, &spot_direction.y, &spot_direction.z) != 3) goto End; light->has_spot_direction = true; @@ -245,9 +245,9 @@ static void light_param_light_read_inner(light_param_light* light, stream& s) { light->has_spot_cutoff = true; } else if (!str_utils_compare_length(buf, sizeof(buf), "attenuation", 11)) { - vec3* attenuation = &light->attenuation; + vec3& attenuation = light->attenuation; if (buf[11] != ' ' || sscanf_s(buf + 12, "%f %f %f", - &attenuation->x, &attenuation->y, &attenuation->z) != 3) + &attenuation.x, &attenuation.y, &attenuation.z) != 3) goto End; light->has_attenuation = true; @@ -265,9 +265,9 @@ static void light_param_light_read_inner(light_param_light* light, stream& s) { light->has_clip_plane = true; } else if (!str_utils_compare_length(buf, sizeof(buf), "tonecurve", 9)) { - vec3* tone_curve = &light->tone_curve; + vec3& tone_curve = light->tone_curve; if (buf[9] != ' ' || sscanf_s(buf + 10, "%f %f %f", - &tone_curve->x, &tone_curve->y, &tone_curve->z) != 3) + &tone_curve.x, &tone_curve.y, &tone_curve.z) != 3) goto End; light->has_tone_curve = true; @@ -304,51 +304,51 @@ static void light_param_light_write_inner(light_param_light* light, stream& s) { } if (light->has_ambient) { - vec4u* ambient = &light->ambient; + vec4& ambient = light->ambient; s.write("ambient", 7); - light_param_light_write_float_t(s, buf, sizeof(buf), ambient->x); - light_param_light_write_float_t(s, buf, sizeof(buf), ambient->y); - light_param_light_write_float_t(s, buf, sizeof(buf), ambient->z); - light_param_light_write_float_t(s, buf, sizeof(buf), ambient->w); + light_param_light_write_float_t(s, buf, sizeof(buf), ambient.x); + light_param_light_write_float_t(s, buf, sizeof(buf), ambient.y); + light_param_light_write_float_t(s, buf, sizeof(buf), ambient.z); + light_param_light_write_float_t(s, buf, sizeof(buf), ambient.w); s.write_char('\n'); } if (light->has_diffuse) { - vec4u* diffuse = &light->diffuse; + vec4& diffuse = light->diffuse; s.write("diffuse", 7); - light_param_light_write_float_t(s, buf, sizeof(buf), diffuse->x); - light_param_light_write_float_t(s, buf, sizeof(buf), diffuse->y); - light_param_light_write_float_t(s, buf, sizeof(buf), diffuse->z); - light_param_light_write_float_t(s, buf, sizeof(buf), diffuse->w); + light_param_light_write_float_t(s, buf, sizeof(buf), diffuse.x); + light_param_light_write_float_t(s, buf, sizeof(buf), diffuse.y); + light_param_light_write_float_t(s, buf, sizeof(buf), diffuse.z); + light_param_light_write_float_t(s, buf, sizeof(buf), diffuse.w); s.write_char('\n'); } if (light->has_specular) { - vec4u* specular = &light->specular; + vec4& specular = light->specular; s.write("specular", 8); - light_param_light_write_float_t(s, buf, sizeof(buf), specular->x); - light_param_light_write_float_t(s, buf, sizeof(buf), specular->y); - light_param_light_write_float_t(s, buf, sizeof(buf), specular->z); - light_param_light_write_float_t(s, buf, sizeof(buf), specular->w); + light_param_light_write_float_t(s, buf, sizeof(buf), specular.x); + light_param_light_write_float_t(s, buf, sizeof(buf), specular.y); + light_param_light_write_float_t(s, buf, sizeof(buf), specular.z); + light_param_light_write_float_t(s, buf, sizeof(buf), specular.w); s.write_char('\n'); } if (light->has_position) { - vec3* position = &light->position; + vec3& position = light->position; s.write("position", 8); - light_param_light_write_float_t(s, buf, sizeof(buf), position->x); - light_param_light_write_float_t(s, buf, sizeof(buf), position->y); - light_param_light_write_float_t(s, buf, sizeof(buf), position->z); + light_param_light_write_float_t(s, buf, sizeof(buf), position.x); + light_param_light_write_float_t(s, buf, sizeof(buf), position.y); + light_param_light_write_float_t(s, buf, sizeof(buf), position.z); light_param_light_write_float_t(s, buf, sizeof(buf), 0.0f); s.write_char('\n'); } if (light->has_spot_direction) { - vec3* spot_direction = &light->spot_direction; + vec3& spot_direction = light->spot_direction; s.write("spot_direction", 14); - light_param_light_write_float_t(s, buf, sizeof(buf), spot_direction->x); - light_param_light_write_float_t(s, buf, sizeof(buf), spot_direction->y); - light_param_light_write_float_t(s, buf, sizeof(buf), spot_direction->z); + light_param_light_write_float_t(s, buf, sizeof(buf), spot_direction.x); + light_param_light_write_float_t(s, buf, sizeof(buf), spot_direction.y); + light_param_light_write_float_t(s, buf, sizeof(buf), spot_direction.z); s.write_char('\n'); } @@ -367,11 +367,11 @@ static void light_param_light_write_inner(light_param_light* light, stream& s) { } if (light->has_attenuation) { - vec3* attenuation = &light->attenuation; + vec3& attenuation = light->attenuation; s.write("attenuation", 11); - light_param_light_write_float_t(s, buf, sizeof(buf), attenuation->x); - light_param_light_write_float_t(s, buf, sizeof(buf), attenuation->y); - light_param_light_write_float_t(s, buf, sizeof(buf), attenuation->z); + light_param_light_write_float_t(s, buf, sizeof(buf), attenuation.x); + light_param_light_write_float_t(s, buf, sizeof(buf), attenuation.y); + light_param_light_write_float_t(s, buf, sizeof(buf), attenuation.z); s.write_char('\n'); } @@ -386,11 +386,11 @@ static void light_param_light_write_inner(light_param_light* light, stream& s) { } if (light->has_tone_curve) { - vec3* tone_curve = &light->tone_curve; + vec3& tone_curve = light->tone_curve; s.write("tonecurve", 10); - light_param_light_write_float_t(s, buf, sizeof(buf), tone_curve->x); - light_param_light_write_float_t(s, buf, sizeof(buf), tone_curve->y); - light_param_light_write_float_t(s, buf, sizeof(buf), tone_curve->z); + light_param_light_write_float_t(s, buf, sizeof(buf), tone_curve.x); + light_param_light_write_float_t(s, buf, sizeof(buf), tone_curve.y); + light_param_light_write_float_t(s, buf, sizeof(buf), tone_curve.z); s.write_char('\n'); } diff --git a/src/KKdLib/light_param/light.hpp b/src/KKdLib/light_param/light.hpp index 128ebfbb..2676ecb1 100644 --- a/src/KKdLib/light_param/light.hpp +++ b/src/KKdLib/light_param/light.hpp @@ -36,11 +36,11 @@ struct light_param_light_data { bool has_type; light_type type; bool has_ambient; - vec4u ambient; + vec4 ambient; bool has_diffuse; - vec4u diffuse; + vec4 diffuse; bool has_specular; - vec4u specular; + vec4 specular; bool has_position; vec3 position; bool has_spot_direction; @@ -73,7 +73,7 @@ struct light_param_light { light_param_light_group group[LIGHT_SET_MAX]; light_param_light(); - ~light_param_light(); + virtual ~light_param_light(); void read(const char* path); void read(const wchar_t* path); diff --git a/src/KKdLib/light_param/wind.hpp b/src/KKdLib/light_param/wind.hpp index 37f25714..7dfd567d 100644 --- a/src/KKdLib/light_param/wind.hpp +++ b/src/KKdLib/light_param/wind.hpp @@ -32,7 +32,7 @@ struct light_param_wind { light_param_wind_spc spc[16]; light_param_wind(); - ~light_param_wind(); + virtual ~light_param_wind(); void read(const char* path); void read(const wchar_t* path); diff --git a/src/KKdLib/mat.cpp b/src/KKdLib/mat.cpp index 0f6e9357..043263c9 100644 --- a/src/KKdLib/mat.cpp +++ b/src/KKdLib/mat.cpp @@ -32,21 +32,6 @@ const mat4 mat4_null = { { 0.0f, 0.0f, 0.0f, 0.0f }, }; -const mat4u mat4u_identity = { - { 1.0f, 0.0f, 0.0f, 0.0f }, - { 0.0f, 1.0f, 0.0f, 0.0f }, - { 0.0f, 0.0f, 1.0f, 0.0f }, - { 0.0f, 0.0f, 0.0f, 1.0f }, -}; - -const mat4u mat4u_null = { - { 0.0f, 0.0f, 0.0f, 0.0f }, - { 0.0f, 0.0f, 0.0f, 0.0f }, - { 0.0f, 0.0f, 0.0f, 0.0f }, - { 0.0f, 0.0f, 0.0f, 0.0f }, -}; - - mat3::mat3() : row0(), row1(), row2() { } @@ -65,15 +50,6 @@ mat4::mat4(vec4 row0, vec4 row1, vec4 row2, vec4 row3) : } -mat4u::mat4u() : row0(), row1(), row2(), row3() { - -} - -mat4u::mat4u(vec4u row0, vec4u row1, vec4u row2, vec4u row3) : - row0(row0), row1(row1), row2(row2), row3(row3) { - -} - inline void mat3_add(const mat3* x, const mat3* y, mat3* z) { __m128 xt; __m128 yt; @@ -192,10 +168,10 @@ inline void mat3_transpose(const mat3* x, mat3* z) { *(vec3*)&xt0 = x->row0; *(vec3*)&xt1 = x->row1; *(vec3*)&xt2 = x->row2; - xt0 = _mm_and_ps(xt0, vec4_mask_vec3.data); - xt1 = _mm_and_ps(xt1, vec4_mask_vec3.data); - xt2 = _mm_and_ps(xt2, vec4_mask_vec3.data); - xt3 = vec4_null.data; + xt0 = _mm_and_ps(xt0, _mm_loadu_ps((float*)&(vec4_mask_vec3))); + xt1 = _mm_and_ps(xt1, _mm_loadu_ps((float*)&(vec4_mask_vec3))); + xt2 = _mm_and_ps(xt2, _mm_loadu_ps((float*)&(vec4_mask_vec3))); + xt3 = _mm_loadu_ps((float*)&(vec4_null)); yt0 = _mm_unpacklo_ps(xt0, xt1); yt1 = _mm_unpackhi_ps(xt0, xt1); yt2 = _mm_unpacklo_ps(xt2, xt3); @@ -253,7 +229,7 @@ void mat3_inverse(const mat3* x, mat3* z) { wt = _mm_movelh_ps(_mm_unpacklo_ps(zt0, zt1), zt2); *(vec3*)&yt = xt0; - yt = _mm_and_ps(yt, vec4_mask_vec3.data); + yt = _mm_and_ps(yt, _mm_loadu_ps((float*)&(vec4_mask_vec3))); wt = _mm_mul_ps(yt, wt); wt = _mm_hadd_ps(wt, wt); wt = _mm_hadd_ps(wt, wt); @@ -303,7 +279,7 @@ inline void mat3_normalize_rotation(const mat3* x, mat3* z) { __m128 xt; __m128 yt; *(vec3*)&xt = x->row0; - xt = _mm_and_ps(xt, vec4_mask_vec3.data); + xt = _mm_and_ps(xt, _mm_loadu_ps((float*)&(vec4_mask_vec3))); yt = _mm_mul_ps(xt, xt); yt = _mm_hadd_ps(yt, yt); yt = _mm_sqrt_ss(_mm_hadd_ps(yt, yt)); @@ -312,7 +288,7 @@ inline void mat3_normalize_rotation(const mat3* x, mat3* z) { xt = _mm_mul_ps(xt, _mm_shuffle_ps(yt, yt, 0)); z->row0 = *(vec3*)&xt; *(vec3*)&xt = x->row1; - xt = _mm_and_ps(xt, vec4_mask_vec3.data); + xt = _mm_and_ps(xt, _mm_loadu_ps((float*)&(vec4_mask_vec3))); yt = _mm_mul_ps(xt, xt); yt = _mm_hadd_ps(yt, yt); yt = _mm_sqrt_ss(_mm_hadd_ps(yt, yt)); @@ -321,7 +297,7 @@ inline void mat3_normalize_rotation(const mat3* x, mat3* z) { xt = _mm_mul_ps(xt, _mm_shuffle_ps(yt, yt, 0)); z->row1 = *(vec3*)&xt; *(vec3*)&xt = x->row2; - xt = _mm_and_ps(xt, vec4_mask_vec3.data); + xt = _mm_and_ps(xt, _mm_loadu_ps((float*)&(vec4_mask_vec3))); yt = _mm_mul_ps(xt, xt); yt = _mm_hadd_ps(yt, yt); yt = _mm_sqrt_ss(_mm_hadd_ps(yt, yt)); @@ -367,6 +343,114 @@ inline void mat3_rotate(float_t x, float_t y, float_t z, mat3* d) { *d = dt; } +inline void mat3_rotate_x_sin_cos(float_t sin_val, float_t cos_val, mat3* y) { + mat3 yt; + yt = mat3_identity; + yt.row1.y = cos_val; + yt.row1.z = sin_val; + yt.row2.y = -sin_val; + yt.row2.z = cos_val; + *y = yt; +} + +inline void mat3_rotate_y_sin_cos(float_t sin_val, float_t cos_val, mat3* y) { + mat3 yt; + yt = mat3_identity; + yt.row0.x = cos_val; + yt.row0.z = -sin_val; + yt.row2.x = sin_val; + yt.row2.z = cos_val; + *y = yt; +} + +inline void mat3_rotate_z_sin_cos(float_t sin_val, float_t cos_val, mat3* y) { + mat3 yt; + yt = mat3_identity; + yt.row0.x = cos_val; + yt.row0.y = sin_val; + yt.row1.x = -sin_val; + yt.row1.y = cos_val; + *y = yt; +} + +inline void mat3_rotate_x_mult_sin_cos(const mat3* x, float_t sin_val, float_t cos_val, mat3* z) { + __m128 t1; + __m128 t2; + __m128 xt; + __m128 y0; + __m128 y1; + __m128 y2; + __m128 zt; + *(vec3*)&y0 = x->row0; + *(vec3*)&y1 = x->row1; + *(vec3*)&y2 = x->row2; + z->row0 = *(vec3*)&y0; + xt = _mm_set_ss(cos_val); + t1 = _mm_mul_ps(y1, _mm_shuffle_ps(xt, xt, 0x00)); + xt = _mm_set_ss(sin_val); + t2 = _mm_mul_ps(y2, _mm_shuffle_ps(xt, xt, 0x00)); + zt = _mm_add_ps(t1, t2); + z->row1 = *(vec3*)&zt; + xt = _mm_set_ss(-sin_val); + t1 = _mm_mul_ps(y1, _mm_shuffle_ps(xt, xt, 0x00)); + xt = _mm_set_ss(cos_val); + t2 = _mm_mul_ps(y2, _mm_shuffle_ps(xt, xt, 0x00)); + zt = _mm_add_ps(t1, t2); + z->row2 = *(vec3*)&zt; +} + +inline void mat3_rotate_y_mult_sin_cos(const mat3* x, float_t sin_val, float_t cos_val, mat3* z) { + __m128 t0; + __m128 t2; + __m128 xt; + __m128 y0; + __m128 y1; + __m128 y2; + __m128 zt; + *(vec3*)&y0 = x->row0; + *(vec3*)&y1 = x->row1; + *(vec3*)&y2 = x->row2; + xt = _mm_set_ss(cos_val); + t0 = _mm_mul_ps(y0, _mm_shuffle_ps(xt, xt, 0x00)); + xt = _mm_set_ss(-sin_val); + t2 = _mm_mul_ps(y2, _mm_shuffle_ps(xt, xt, 0x00)); + zt = _mm_add_ps(t0, t2); + z->row0 = *(vec3*)&zt; + z->row1 = *(vec3*)&y1; + xt = _mm_set_ss(sin_val); + t0 = _mm_mul_ps(y0, _mm_shuffle_ps(xt, xt, 0x00)); + xt = _mm_set_ss(cos_val); + t2 = _mm_mul_ps(y2, _mm_shuffle_ps(xt, xt, 0x00)); + zt = _mm_add_ps(t0, t2); + z->row2 = *(vec3*)&zt; +} + +inline void mat3_rotate_z_mult_sin_cos(const mat3* x, float_t sin_val, float_t cos_val, mat3* z) { + __m128 t0; + __m128 t1; + __m128 xt; + __m128 y0; + __m128 y1; + __m128 y2; + __m128 zt; + *(vec3*)&y0 = x->row0; + *(vec3*)&y1 = x->row1; + *(vec3*)&y2 = x->row2; + xt = _mm_set_ss(cos_val); + t0 = _mm_mul_ps(y0, _mm_shuffle_ps(xt, xt, 0x00)); + xt = _mm_set_ss(sin_val); + t1 = _mm_mul_ps(y1, _mm_shuffle_ps(xt, xt, 0x00)); + zt = _mm_add_ps(t0, t1); + z->row0 = *(vec3*)&zt; + xt = _mm_set_ss(-sin_val); + t0 = _mm_mul_ps(y0, _mm_shuffle_ps(xt, xt, 0x00)); + xt = _mm_set_ss(cos_val); + t1 = _mm_mul_ps(y1, _mm_shuffle_ps(xt, xt, 0x00)); + zt = _mm_add_ps(t0, t1); + z->row1 = *(vec3*)&zt; + z->row2 = *(vec3*)&y2; +} + inline void mat3_rotate_x(float_t x, mat3* y) { mat3 yt; float_t x_sin = sinf(x); @@ -416,39 +500,87 @@ inline void mat3_rotate_mult(const mat3* s, float_t x, float_t y, float_t z, mat } inline void mat3_rotate_x_mult(const mat3* x, float_t y, mat3* z) { - mat3 yt; + __m128 t1; + __m128 t2; + __m128 xt; + __m128 y0; + __m128 y1; + __m128 y2; + __m128 zt; float_t y_sin = sinf(y); float_t y_cos = cosf(y); - yt = mat3_identity; - yt.row1.y = y_cos; - yt.row1.z = y_sin; - yt.row2.y = -y_sin; - yt.row2.z = y_cos; - mat3_mult(&yt, x, z); + *(vec3*)&y0 = x->row0; + *(vec3*)&y1 = x->row1; + *(vec3*)&y2 = x->row2; + z->row0 = *(vec3*)&y0; + xt = _mm_set_ss(y_cos); + t1 = _mm_mul_ps(y1, _mm_shuffle_ps(xt, xt, 0x00)); + xt = _mm_set_ss(y_sin); + t2 = _mm_mul_ps(y2, _mm_shuffle_ps(xt, xt, 0x00)); + zt = _mm_add_ps(t1, t2); + z->row1 = *(vec3*)&zt; + xt = _mm_set_ss(-y_sin); + t1 = _mm_mul_ps(y1, _mm_shuffle_ps(xt, xt, 0x00)); + xt = _mm_set_ss(y_cos); + t2 = _mm_mul_ps(y2, _mm_shuffle_ps(xt, xt, 0x00)); + zt = _mm_add_ps(t1, t2); + z->row2 = *(vec3*)&zt; } inline void mat3_rotate_y_mult(const mat3* x, float_t y, mat3* z) { - mat3 yt; + __m128 t0; + __m128 t2; + __m128 xt; + __m128 y0; + __m128 y1; + __m128 y2; + __m128 zt; float_t y_sin = sinf(y); float_t y_cos = cosf(y); - yt = mat3_identity; - yt.row0.x = y_cos; - yt.row0.z = -y_sin; - yt.row2.x = y_sin; - yt.row2.z = y_cos; - mat3_mult(&yt, x, z); + *(vec3*)&y0 = x->row0; + *(vec3*)&y1 = x->row1; + *(vec3*)&y2 = x->row2; + xt = _mm_set_ss(y_cos); + t0 = _mm_mul_ps(y0, _mm_shuffle_ps(xt, xt, 0x00)); + xt = _mm_set_ss(-y_sin); + t2 = _mm_mul_ps(y2, _mm_shuffle_ps(xt, xt, 0x00)); + zt = _mm_add_ps(t0, t2); + z->row0 = *(vec3*)&zt; + z->row1 = *(vec3*)&y1; + xt = _mm_set_ss(y_sin); + t0 = _mm_mul_ps(y0, _mm_shuffle_ps(xt, xt, 0x00)); + xt = _mm_set_ss(y_cos); + t2 = _mm_mul_ps(y2, _mm_shuffle_ps(xt, xt, 0x00)); + zt = _mm_add_ps(t0, t2); + z->row2 = *(vec3*)&zt; } inline void mat3_rotate_z_mult(const mat3* x, float_t y, mat3* z) { - mat3 yt; + __m128 t0; + __m128 t1; + __m128 xt; + __m128 y0; + __m128 y1; + __m128 y2; + __m128 zt; float_t y_sin = sinf(y); float_t y_cos = cosf(y); - yt = mat3_identity; - yt.row0.x = y_cos; - yt.row0.y = y_sin; - yt.row1.x = -y_sin; - yt.row1.y = y_cos; - mat3_mult(&yt, x, z); + *(vec3*)&y0 = x->row0; + *(vec3*)&y1 = x->row1; + *(vec3*)&y2 = x->row2; + xt = _mm_set_ss(y_cos); + t0 = _mm_mul_ps(y0, _mm_shuffle_ps(xt, xt, 0x00)); + xt = _mm_set_ss(y_sin); + t1 = _mm_mul_ps(y1, _mm_shuffle_ps(xt, xt, 0x00)); + zt = _mm_add_ps(t0, t1); + z->row0 = *(vec3*)&zt; + xt = _mm_set_ss(-y_sin); + t0 = _mm_mul_ps(y0, _mm_shuffle_ps(xt, xt, 0x00)); + xt = _mm_set_ss(y_cos); + t1 = _mm_mul_ps(y1, _mm_shuffle_ps(xt, xt, 0x00)); + zt = _mm_add_ps(t0, t1); + z->row1 = *(vec3*)&zt; + z->row2 = *(vec3*)&y2; } inline void mat3_scale(float_t x, float_t y, float_t z, mat3* d) { @@ -576,12 +708,6 @@ inline void mat3_from_mat4(const mat4* x, mat3* z) { z->row2 = *(vec3*)&x->row2; } -inline void mat3_from_mat4(const mat4u* x, mat3* z) { - z->row0 = *(vec3*)&x->row0; - z->row1 = *(vec3*)&x->row1; - z->row2 = *(vec3*)&x->row2; -} - inline void mat3_from_mat4_inverse(const mat4* x, mat3* z) { mat4 yt; @@ -591,16 +717,6 @@ inline void mat3_from_mat4_inverse(const mat4* x, mat3* z) { z->row2 = *(vec3*)&yt.row2; } -inline void mat3_from_mat4_inverse(const mat4u* x, mat3* z) { - mat4 yt; - - yt = *x; - mat4_inverse(&yt, &yt); - z->row0 = *(vec3*)&yt.row0; - z->row1 = *(vec3*)&yt.row1; - z->row2 = *(vec3*)&yt.row2; -} - inline void mat3_get_rotation(const mat3* x, vec3* z) { if (-x->row0.z >= 1.0f) z->y = (float_t)M_PI_2; @@ -644,18 +760,38 @@ 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) { + 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_axis_angle(axis, angle, &q2); + quat_mult(&q2, &q1, &q3); + mat3_from_quat(&q3, dst); +} + inline void mat4_add(const mat4* x, const mat4* y, mat4* z) { - z->row0.data = _mm_add_ps(x->row0.data, y->row0.data); - z->row1.data = _mm_add_ps(x->row1.data, y->row1.data); - z->row2.data = _mm_add_ps(x->row2.data, y->row2.data); - z->row3.data = _mm_add_ps(x->row3.data, y->row3.data); + _mm_storeu_ps((float*)&(z->row0), _mm_add_ps( + _mm_loadu_ps((float*)&(x->row0)), _mm_loadu_ps((float*)&(y->row0)))); + _mm_storeu_ps((float*)&(z->row1), _mm_add_ps( + _mm_loadu_ps((float*)&(x->row1)), _mm_loadu_ps((float*)&(y->row1)))); + _mm_storeu_ps((float*)&(z->row2), _mm_add_ps( + _mm_loadu_ps((float*)&(x->row2)), _mm_loadu_ps((float*)&(y->row2)))); + _mm_storeu_ps((float*)&(z->row3), _mm_add_ps( + _mm_loadu_ps((float*)&(x->row3)), _mm_loadu_ps((float*)&(y->row3)))); } inline void mat4_sub(const mat4* x, const mat4* y, mat4* z) { - z->row0.data = _mm_sub_ps(x->row0.data, y->row0.data); - z->row1.data = _mm_sub_ps(x->row1.data, y->row1.data); - z->row2.data = _mm_sub_ps(x->row2.data, y->row2.data); - z->row3.data = _mm_sub_ps(x->row3.data, y->row3.data); + _mm_storeu_ps((float*)&(z->row0), _mm_sub_ps( + _mm_loadu_ps((float*)&(x->row0)), _mm_loadu_ps((float*)&(y->row0)))); + _mm_storeu_ps((float*)&(z->row1), _mm_sub_ps( + _mm_loadu_ps((float*)&(x->row1)), _mm_loadu_ps((float*)&(y->row1)))); + _mm_storeu_ps((float*)&(z->row2), _mm_sub_ps( + _mm_loadu_ps((float*)&(x->row2)), _mm_loadu_ps((float*)&(y->row2)))); + _mm_storeu_ps((float*)&(z->row3), _mm_sub_ps( + _mm_loadu_ps((float*)&(x->row3)), _mm_loadu_ps((float*)&(y->row3)))); } inline void mat4_mult(const mat4* x, const mat4* y, mat4* z) { @@ -668,74 +804,34 @@ inline void mat4_mult(const mat4* x, const mat4* y, mat4* z) { __m128 y1; __m128 y2; __m128 y3; - y0 = y->row0.data; - y1 = y->row1.data; - y2 = y->row2.data; - y3 = y->row3.data; - xt = x->row0.data; + y0 = _mm_loadu_ps((float*)&(y->row0)); + y1 = _mm_loadu_ps((float*)&(y->row1)); + y2 = _mm_loadu_ps((float*)&(y->row2)); + y3 = _mm_loadu_ps((float*)&(y->row3)); + xt = _mm_loadu_ps((float*)&(x->row0)); t0 = _mm_mul_ps(y0, _mm_shuffle_ps(xt, xt, 0x00)); t1 = _mm_mul_ps(y1, _mm_shuffle_ps(xt, xt, 0x55)); t2 = _mm_mul_ps(y2, _mm_shuffle_ps(xt, xt, 0xAA)); t3 = _mm_mul_ps(y3, _mm_shuffle_ps(xt, xt, 0xFF)); - z->row0.data = _mm_add_ps(_mm_add_ps(t0, t1), _mm_add_ps(t2, t3)); - xt = x->row1.data; + _mm_storeu_ps((float*)&(z->row0), _mm_add_ps(_mm_add_ps(t0, t1), _mm_add_ps(t2, t3))); + xt = _mm_loadu_ps((float*)&(x->row1)); t0 = _mm_mul_ps(y0, _mm_shuffle_ps(xt, xt, 0x00)); t1 = _mm_mul_ps(y1, _mm_shuffle_ps(xt, xt, 0x55)); t2 = _mm_mul_ps(y2, _mm_shuffle_ps(xt, xt, 0xAA)); t3 = _mm_mul_ps(y3, _mm_shuffle_ps(xt, xt, 0xFF)); - z->row1.data = _mm_add_ps(_mm_add_ps(t0, t1), _mm_add_ps(t2, t3)); - xt = x->row2.data; + _mm_storeu_ps((float*)&(z->row1), _mm_add_ps(_mm_add_ps(t0, t1), _mm_add_ps(t2, t3))); + xt = _mm_loadu_ps((float*)&(x->row2)); t0 = _mm_mul_ps(y0, _mm_shuffle_ps(xt, xt, 0x00)); t1 = _mm_mul_ps(y1, _mm_shuffle_ps(xt, xt, 0x55)); t2 = _mm_mul_ps(y2, _mm_shuffle_ps(xt, xt, 0xAA)); t3 = _mm_mul_ps(y3, _mm_shuffle_ps(xt, xt, 0xFF)); - z->row2.data = _mm_add_ps(_mm_add_ps(t0, t1), _mm_add_ps(t2, t3)); - xt = x->row3.data; + _mm_storeu_ps((float*)&(z->row2), _mm_add_ps(_mm_add_ps(t0, t1), _mm_add_ps(t2, t3))); + xt = _mm_loadu_ps((float*)&(x->row3)); t0 = _mm_mul_ps(y0, _mm_shuffle_ps(xt, xt, 0x00)); t1 = _mm_mul_ps(y1, _mm_shuffle_ps(xt, xt, 0x55)); t2 = _mm_mul_ps(y2, _mm_shuffle_ps(xt, xt, 0xAA)); t3 = _mm_mul_ps(y3, _mm_shuffle_ps(xt, xt, 0xFF)); - z->row3.data = _mm_add_ps(_mm_add_ps(t0, t1), _mm_add_ps(t2, t3)); -} - -inline void mat4_mult(const mat4u* x, const mat4u* y, mat4u* z) { - __m128 t0; - __m128 t1; - __m128 t2; - __m128 t3; - __m128 xt; - __m128 y0; - __m128 y1; - __m128 y2; - __m128 y3; - y0 = _mm_loadu_ps((float_t*)&y->row0); - y1 = _mm_loadu_ps((float_t*)&y->row1); - y2 = _mm_loadu_ps((float_t*)&y->row2); - y3 = _mm_loadu_ps((float_t*)&y->row3); - xt = _mm_loadu_ps((float_t*)&x->row0); - t0 = _mm_mul_ps(y0, _mm_shuffle_ps(xt, xt, 0x00)); - t1 = _mm_mul_ps(y1, _mm_shuffle_ps(xt, xt, 0x55)); - t2 = _mm_mul_ps(y2, _mm_shuffle_ps(xt, xt, 0xAA)); - t3 = _mm_mul_ps(y3, _mm_shuffle_ps(xt, xt, 0xFF)); - _mm_storeu_ps((float_t*)&z->row0, _mm_add_ps(_mm_add_ps(t0, t1), _mm_add_ps(t2, t3))); - xt = _mm_loadu_ps((float_t*)&x->row1); - t0 = _mm_mul_ps(y0, _mm_shuffle_ps(xt, xt, 0x00)); - t1 = _mm_mul_ps(y1, _mm_shuffle_ps(xt, xt, 0x55)); - t2 = _mm_mul_ps(y2, _mm_shuffle_ps(xt, xt, 0xAA)); - t3 = _mm_mul_ps(y3, _mm_shuffle_ps(xt, xt, 0xFF)); - _mm_storeu_ps((float_t*)&z->row1, _mm_add_ps(_mm_add_ps(t0, t1), _mm_add_ps(t2, t3))); - xt = _mm_loadu_ps((float_t*)&x->row2); - t0 = _mm_mul_ps(y0, _mm_shuffle_ps(xt, xt, 0x00)); - t1 = _mm_mul_ps(y1, _mm_shuffle_ps(xt, xt, 0x55)); - t2 = _mm_mul_ps(y2, _mm_shuffle_ps(xt, xt, 0xAA)); - t3 = _mm_mul_ps(y3, _mm_shuffle_ps(xt, xt, 0xFF)); - _mm_storeu_ps((float_t*)&z->row2, _mm_add_ps(_mm_add_ps(t0, t1), _mm_add_ps(t2, t3))); - xt = _mm_loadu_ps((float_t*)&x->row3); - t0 = _mm_mul_ps(y0, _mm_shuffle_ps(xt, xt, 0x00)); - t1 = _mm_mul_ps(y1, _mm_shuffle_ps(xt, xt, 0x55)); - t2 = _mm_mul_ps(y2, _mm_shuffle_ps(xt, xt, 0xAA)); - t3 = _mm_mul_ps(y3, _mm_shuffle_ps(xt, xt, 0xFF)); - _mm_storeu_ps((float_t*)&z->row3, _mm_add_ps(_mm_add_ps(t0, t1), _mm_add_ps(t2, t3))); + _mm_storeu_ps((float*)&(z->row3), _mm_add_ps(_mm_add_ps(t0, t1), _mm_add_ps(t2, t3))); } inline void mat4_mult_vec3(const mat4* x, const vec3* y, vec3* z) { @@ -745,9 +841,9 @@ inline void mat4_mult_vec3(const mat4* x, const vec3* y, vec3* z) { __m128 zt1; __m128 zt2; *(vec3*)&yt = *y; - zt0 = _mm_mul_ps(x->row0.data, _mm_shuffle_ps(yt, yt, 0x00)); - zt1 = _mm_mul_ps(x->row1.data, _mm_shuffle_ps(yt, yt, 0x55)); - zt2 = _mm_mul_ps(x->row2.data, _mm_shuffle_ps(yt, yt, 0xAA)); + zt0 = _mm_mul_ps(_mm_loadu_ps((float*)&(x->row0)), _mm_shuffle_ps(yt, yt, 0x00)); + zt1 = _mm_mul_ps(_mm_loadu_ps((float*)&(x->row1)), _mm_shuffle_ps(yt, yt, 0x55)); + zt2 = _mm_mul_ps(_mm_loadu_ps((float*)&(x->row2)), _mm_shuffle_ps(yt, yt, 0xAA)); zt = _mm_add_ps(_mm_add_ps(zt0, zt1), zt2); *z = *(vec3*)&zt; } @@ -757,14 +853,14 @@ inline void mat4_mult_vec3_inv(const mat4* x, const vec3* y, vec3* z) { __m128 zt; *(vec3*)&yt = *y; - yt = _mm_and_ps(yt, vec4_mask_vec3.data); - zt = _mm_mul_ps(yt, x->row0.data); + yt = _mm_and_ps(yt, _mm_loadu_ps((float*)&(vec4_mask_vec3))); + zt = _mm_mul_ps(yt, _mm_loadu_ps((float*)&(x->row0))); zt = _mm_hadd_ps(zt, zt); z->x = _mm_cvtss_f32(_mm_hadd_ps(zt, zt)); - zt = _mm_mul_ps(yt, x->row1.data); + zt = _mm_mul_ps(yt, _mm_loadu_ps((float*)&(x->row1))); zt = _mm_hadd_ps(zt, zt); z->y = _mm_cvtss_f32(_mm_hadd_ps(zt, zt)); - zt = _mm_mul_ps(yt, x->row2.data); + zt = _mm_mul_ps(yt, _mm_loadu_ps((float*)&(x->row2))); zt = _mm_hadd_ps(zt, zt); z->z = _mm_cvtss_f32(_mm_hadd_ps(zt, zt)); } @@ -777,10 +873,10 @@ inline void mat4_mult_vec3_trans(const mat4* x, const vec3* y, vec3* z) { __m128 zt2; __m128 zt3; *(vec3*)&yt = *y; - zt0 = _mm_mul_ps(x->row0.data, _mm_shuffle_ps(yt, yt, 0x00)); - zt1 = _mm_mul_ps(x->row1.data, _mm_shuffle_ps(yt, yt, 0x55)); - zt2 = _mm_mul_ps(x->row2.data, _mm_shuffle_ps(yt, yt, 0xAA)); - zt3 = x->row3.data; + zt0 = _mm_mul_ps(_mm_loadu_ps((float*)&(x->row0)), _mm_shuffle_ps(yt, yt, 0x00)); + zt1 = _mm_mul_ps(_mm_loadu_ps((float*)&(x->row1)), _mm_shuffle_ps(yt, yt, 0x55)); + zt2 = _mm_mul_ps(_mm_loadu_ps((float*)&(x->row2)), _mm_shuffle_ps(yt, yt, 0xAA)); + zt3 = _mm_loadu_ps((float*)&(x->row3)); zt = _mm_add_ps(_mm_add_ps(zt0, zt1), _mm_add_ps(zt2, zt3)); *z = *(vec3*)&zt; } @@ -790,15 +886,15 @@ inline void mat4_mult_vec3_inv_trans(const mat4* x, const vec3* y, vec3* z) { __m128 zt; *(vec3*)&yt = *y; - yt = _mm_and_ps(yt, vec4_mask_vec3.data); - yt = _mm_sub_ps(yt, x->row3.data); - zt = _mm_mul_ps(yt, x->row0.data); + yt = _mm_and_ps(yt, _mm_loadu_ps((float*)&(vec4_mask_vec3))); + yt = _mm_sub_ps(yt, _mm_loadu_ps((float*)&(x->row3))); + zt = _mm_mul_ps(yt, _mm_loadu_ps((float*)&(x->row0))); zt = _mm_hadd_ps(zt, zt); z->x = _mm_cvtss_f32(_mm_hadd_ps(zt, zt)); - zt = _mm_mul_ps(yt, x->row1.data); + zt = _mm_mul_ps(yt, _mm_loadu_ps((float*)&(x->row1))); zt = _mm_hadd_ps(zt, zt); z->y = _mm_cvtss_f32(_mm_hadd_ps(zt, zt)); - zt = _mm_mul_ps(yt, x->row2.data); + zt = _mm_mul_ps(yt, _mm_loadu_ps((float*)&(x->row2))); zt = _mm_hadd_ps(zt, zt); z->z = _mm_cvtss_f32(_mm_hadd_ps(zt, zt)); } @@ -809,22 +905,22 @@ inline void mat4_mult_vec(const mat4* x, vec4* y, vec4* z) { __m128 zt1; __m128 zt2; __m128 zt3; - yt = y->data; - zt0 = _mm_mul_ps(x->row0.data, _mm_shuffle_ps(yt, yt, 0x00)); - zt1 = _mm_mul_ps(x->row1.data, _mm_shuffle_ps(yt, yt, 0x55)); - zt2 = _mm_mul_ps(x->row2.data, _mm_shuffle_ps(yt, yt, 0xAA)); - zt3 = _mm_mul_ps(x->row3.data, _mm_shuffle_ps(yt, yt, 0xFF)); - z->data = _mm_add_ps(_mm_add_ps(zt0, zt1), _mm_add_ps(zt2, zt3)); + yt = _mm_loadu_ps((float*)y); + zt0 = _mm_mul_ps(_mm_loadu_ps((float*)&(x->row0)), _mm_shuffle_ps(yt, yt, 0x00)); + zt1 = _mm_mul_ps(_mm_loadu_ps((float*)&(x->row1)), _mm_shuffle_ps(yt, yt, 0x55)); + zt2 = _mm_mul_ps(_mm_loadu_ps((float*)&(x->row2)), _mm_shuffle_ps(yt, yt, 0xAA)); + zt3 = _mm_mul_ps(_mm_loadu_ps((float*)&(x->row3)), _mm_shuffle_ps(yt, yt, 0xFF)); + _mm_storeu_ps((float*)z, _mm_add_ps(_mm_add_ps(zt0, zt1), _mm_add_ps(zt2, zt3))); } inline void mat4_mult_scalar(const mat4* x, float_t y, mat4* z) { __m128 yt; yt = _mm_set_ss(y); yt = _mm_shuffle_ps(yt, yt, 0); - z->row0.data = _mm_mul_ps(x->row0.data, yt); - z->row1.data = _mm_mul_ps(x->row1.data, yt); - z->row2.data = _mm_mul_ps(x->row2.data, yt); - z->row3.data = _mm_mul_ps(x->row3.data, yt); + _mm_storeu_ps((float*)&(z->row0), _mm_mul_ps(_mm_loadu_ps((float*)&(x->row0)), yt)); + _mm_storeu_ps((float*)&(z->row1), _mm_mul_ps(_mm_loadu_ps((float*)&(x->row1)), yt)); + _mm_storeu_ps((float*)&(z->row2), _mm_mul_ps(_mm_loadu_ps((float*)&(x->row2)), yt)); + _mm_storeu_ps((float*)&(z->row3), _mm_mul_ps(_mm_loadu_ps((float*)&(x->row3)), yt)); } inline void mat4_transpose(const mat4* x, mat4* z) { @@ -832,31 +928,14 @@ inline void mat4_transpose(const mat4* x, mat4* z) { __m128 yt1; __m128 yt2; __m128 yt3; - yt0 = _mm_unpacklo_ps(x->row0.data, x->row1.data); - yt1 = _mm_unpackhi_ps(x->row0.data, x->row1.data); - yt2 = _mm_unpacklo_ps(x->row2.data, x->row3.data); - yt3 = _mm_unpackhi_ps(x->row2.data, x->row3.data); - z->row0.data = _mm_movelh_ps(yt0, yt2); - z->row1.data = _mm_movehl_ps(yt2, yt0); - z->row2.data = _mm_movelh_ps(yt1, yt3); - z->row3.data = _mm_movehl_ps(yt3, yt1); -} - -inline void mat4_transpose(const mat4* x, mat4u* z) { - mat4 y; - mat4_transpose(x, &y); - *z = y; -} - -inline void mat4_transpose(const mat4u* x, mat4* z) { - mat4 y = *x; - mat4_transpose(&y, z); -} - -inline void mat4_transpose(const mat4u* x, mat4u* z) { - mat4 y = *x; - mat4_transpose(&y, &y); - *z = y; + yt0 = _mm_unpacklo_ps(_mm_loadu_ps((float*)&(x->row0)), _mm_loadu_ps((float*)&(x->row1))); + yt1 = _mm_unpackhi_ps(_mm_loadu_ps((float*)&(x->row0)), _mm_loadu_ps((float*)&(x->row1))); + yt2 = _mm_unpacklo_ps(_mm_loadu_ps((float*)&(x->row2)), _mm_loadu_ps((float*)&(x->row3))); + yt3 = _mm_unpackhi_ps(_mm_loadu_ps((float*)&(x->row2)), _mm_loadu_ps((float*)&(x->row3))); + _mm_storeu_ps((float*)&(z->row0), _mm_movelh_ps(yt0, yt2)); + _mm_storeu_ps((float*)&(z->row1), _mm_movehl_ps(yt2, yt0)); + _mm_storeu_ps((float*)&(z->row2), _mm_movelh_ps(yt1, yt3)); + _mm_storeu_ps((float*)&(z->row3), _mm_movehl_ps(yt3, yt1)); } void mat4_inverse(const mat4* x, mat4* z) { @@ -873,10 +952,10 @@ void mat4_inverse(const mat4* x, mat4* z) { __m128 wt; __m128 wt0, wt1, wt2; __m128 t0, t1, t2, t3, t4, t5; - xt0 = x->row0.data; - xt1 = x->row1.data; - xt2 = x->row2.data; - xt3 = x->row3.data; + xt0 = _mm_loadu_ps((float*)&(x->row0)); + xt1 = _mm_loadu_ps((float*)&(x->row1)); + xt2 = _mm_loadu_ps((float*)&(x->row2)); + xt3 = _mm_loadu_ps((float*)&(x->row3)); xt0x = _mm_shuffle_ps(xt0, xt0, 0x00); xt0y = _mm_shuffle_ps(xt0, xt0, 0x55); xt0z = _mm_shuffle_ps(xt0, xt0, 0xAA); @@ -941,10 +1020,10 @@ void mat4_inverse(const mat4* x, mat4* z) { if (wt.m128_f32[0] != 0.0f) wt.m128_f32[0] = 1.0f / wt.m128_f32[0]; wt = _mm_shuffle_ps(wt, wt, 0); - z->row0.data = _mm_mul_ps(zt0, wt); - z->row1.data = _mm_mul_ps(zt1, wt); - z->row2.data = _mm_mul_ps(zt2, wt); - z->row3.data = _mm_mul_ps(zt3, wt); + _mm_storeu_ps((float*)&(z->row0), _mm_mul_ps(zt0, wt)); + _mm_storeu_ps((float*)&(z->row1), _mm_mul_ps(zt1, wt)); + _mm_storeu_ps((float*)&(z->row2), _mm_mul_ps(zt2, wt)); + _mm_storeu_ps((float*)&(z->row3), _mm_mul_ps(zt3, wt)); } inline void mat4_invtrans(const mat4* x, mat4* z) { @@ -998,16 +1077,16 @@ inline void mat4_normalize(const mat4* x, mat4* z) { if (det.m128_f32[0] != 0.0f) det.m128_f32[0] = 1.0f / det.m128_f32[0]; det = _mm_shuffle_ps(det, det, 0); - z->row0.data = _mm_mul_ps(x->row0.data, det); - z->row1.data = _mm_mul_ps(x->row1.data, det); - z->row2.data = _mm_mul_ps(x->row2.data, det); - z->row3.data = _mm_mul_ps(x->row3.data, det); + _mm_storeu_ps((float*)&(z->row0), _mm_mul_ps(_mm_loadu_ps((float*)&(x->row0)), det)); + _mm_storeu_ps((float*)&(z->row1), _mm_mul_ps(_mm_loadu_ps((float*)&(x->row1)), det)); + _mm_storeu_ps((float*)&(z->row2), _mm_mul_ps(_mm_loadu_ps((float*)&(x->row2)), det)); + _mm_storeu_ps((float*)&(z->row3), _mm_mul_ps(_mm_loadu_ps((float*)&(x->row3)), det)); } inline void mat4_normalize_rotation(const mat4* x, mat4* z) { __m128 xt; __m128 yt; - xt = _mm_and_ps(x->row0.data, vec4_mask_vec3.data); + xt = _mm_and_ps(_mm_loadu_ps((float*)&(x->row0)), _mm_loadu_ps((float*)&(vec4_mask_vec3))); yt = _mm_mul_ps(xt, xt); yt = _mm_hadd_ps(yt, yt); yt = _mm_sqrt_ss(_mm_hadd_ps(yt, yt)); @@ -1015,7 +1094,7 @@ inline void mat4_normalize_rotation(const mat4* x, mat4* z) { yt.m128_f32[0] = 1.0f / yt.m128_f32[0]; xt = _mm_mul_ps(xt, _mm_shuffle_ps(yt, yt, 0)); *(vec3*)&z->row0 = *(vec3*)&xt; - xt = _mm_and_ps(x->row1.data, vec4_mask_vec3.data); + xt = _mm_and_ps(_mm_loadu_ps((float*)&(x->row1)), _mm_loadu_ps((float*)&(vec4_mask_vec3))); yt = _mm_mul_ps(xt, xt); yt = _mm_hadd_ps(yt, yt); yt = _mm_sqrt_ss(_mm_hadd_ps(yt, yt)); @@ -1023,7 +1102,7 @@ inline void mat4_normalize_rotation(const mat4* x, mat4* z) { yt.m128_f32[0] = 1.0f / yt.m128_f32[0]; xt = _mm_mul_ps(xt, _mm_shuffle_ps(yt, yt, 0)); *(vec3*)&z->row1 = *(vec3*)&xt; - xt = _mm_and_ps(x->row2.data, vec4_mask_vec3.data); + xt = _mm_and_ps(_mm_loadu_ps((float*)&(x->row2)), _mm_loadu_ps((float*)&(vec4_mask_vec3))); yt = _mm_mul_ps(xt, xt); yt = _mm_hadd_ps(yt, yt); yt = _mm_sqrt_ss(_mm_hadd_ps(yt, yt)); @@ -1139,22 +1218,22 @@ inline void mat4_rotate_x_mult(const mat4* x, float_t y, mat4* z) { __m128 y3; float_t y_sin = sinf(y); float_t y_cos = cosf(y); - y0 = x->row0.data; - y1 = x->row1.data; - y2 = x->row2.data; - y3 = x->row3.data; - z->row0.data = y0; + y0 = _mm_loadu_ps((float*)&(x->row0)); + y1 = _mm_loadu_ps((float*)&(x->row1)); + y2 = _mm_loadu_ps((float*)&(x->row2)); + y3 = _mm_loadu_ps((float*)&(x->row3)); + _mm_storeu_ps((float*)&(z->row0), y0); xt = _mm_set_ss(y_cos); t1 = _mm_mul_ps(y1, _mm_shuffle_ps(xt, xt, 0x00)); xt = _mm_set_ss(y_sin); t2 = _mm_mul_ps(y2, _mm_shuffle_ps(xt, xt, 0x00)); - z->row1.data = _mm_add_ps(t1, t2); + _mm_storeu_ps((float*)&(z->row1), _mm_add_ps(t1, t2)); xt = _mm_set_ss(-y_sin); t1 = _mm_mul_ps(y1, _mm_shuffle_ps(xt, xt, 0x00)); xt = _mm_set_ss(y_cos); t2 = _mm_mul_ps(y2, _mm_shuffle_ps(xt, xt, 0x00)); - z->row2.data = _mm_add_ps(t1, t2); - z->row3.data = y3; + _mm_storeu_ps((float*)&(z->row2), _mm_add_ps(t1, t2)); + _mm_storeu_ps((float*)&(z->row3), y3); } inline void mat4_rotate_y_mult(const mat4* x, float_t y, mat4* z) { @@ -1167,22 +1246,22 @@ inline void mat4_rotate_y_mult(const mat4* x, float_t y, mat4* z) { __m128 y3; float_t y_sin = sinf(y); float_t y_cos = cosf(y); - y0 = x->row0.data; - y1 = x->row1.data; - y2 = x->row2.data; - y3 = x->row3.data; + y0 = _mm_loadu_ps((float*)&(x->row0)); + y1 = _mm_loadu_ps((float*)&(x->row1)); + y2 = _mm_loadu_ps((float*)&(x->row2)); + y3 = _mm_loadu_ps((float*)&(x->row3)); xt = _mm_set_ss(y_cos); t0 = _mm_mul_ps(y0, _mm_shuffle_ps(xt, xt, 0x00)); xt = _mm_set_ss(-y_sin); t2 = _mm_mul_ps(y2, _mm_shuffle_ps(xt, xt, 0x00)); - z->row0.data = _mm_add_ps(t0, t2); - z->row1.data = y1; + _mm_storeu_ps((float*)&(z->row0), _mm_add_ps(t0, t2)); + _mm_storeu_ps((float*)&(z->row1), y1); xt = _mm_set_ss(y_sin); t0 = _mm_mul_ps(y0, _mm_shuffle_ps(xt, xt, 0x00)); xt = _mm_set_ss(y_cos); t2 = _mm_mul_ps(y2, _mm_shuffle_ps(xt, xt, 0x00)); - z->row2.data = _mm_add_ps(t0, t2); - z->row3.data = y3; + _mm_storeu_ps((float*)&(z->row2), _mm_add_ps(t0, t2)); + _mm_storeu_ps((float*)&(z->row3), y3); } inline void mat4_rotate_z_mult(const mat4* x, float_t y, mat4* z) { @@ -1195,22 +1274,22 @@ inline void mat4_rotate_z_mult(const mat4* x, float_t y, mat4* z) { __m128 y3; float_t y_sin = sinf(y); float_t y_cos = cosf(y); - y0 = x->row0.data; - y1 = x->row1.data; - y2 = x->row2.data; - y3 = x->row3.data; + y0 = _mm_loadu_ps((float*)&(x->row0)); + y1 = _mm_loadu_ps((float*)&(x->row1)); + y2 = _mm_loadu_ps((float*)&(x->row2)); + y3 = _mm_loadu_ps((float*)&(x->row3)); xt = _mm_set_ss(y_cos); t0 = _mm_mul_ps(y0, _mm_shuffle_ps(xt, xt, 0x00)); xt = _mm_set_ss(y_sin); t1 = _mm_mul_ps(y1, _mm_shuffle_ps(xt, xt, 0x00)); - z->row0.data = _mm_add_ps(t0, t1); + _mm_storeu_ps((float*)&(z->row0), _mm_add_ps(t0, t1)); xt = _mm_set_ss(-y_sin); t0 = _mm_mul_ps(y0, _mm_shuffle_ps(xt, xt, 0x00)); xt = _mm_set_ss(y_cos); t1 = _mm_mul_ps(y1, _mm_shuffle_ps(xt, xt, 0x00)); - z->row1.data = _mm_add_ps(t0, t1); - z->row2.data = y2; - z->row3.data = y3; + _mm_storeu_ps((float*)&(z->row1), _mm_add_ps(t0, t1)); + _mm_storeu_ps((float*)&(z->row2), y2); + _mm_storeu_ps((float*)&(z->row3), y3); } inline void mat4_rotate_x_sin_cos(float_t sin_val, float_t cos_val, mat4* y) { @@ -1251,22 +1330,22 @@ inline void mat4_rotate_x_mult_sin_cos(const mat4* x, float_t sin_val, float_t c __m128 y1; __m128 y2; __m128 y3; - y0 = x->row0.data; - y1 = x->row1.data; - y2 = x->row2.data; - y3 = x->row3.data; - z->row0.data = y0; + y0 = _mm_loadu_ps((float*)&(x->row0)); + y1 = _mm_loadu_ps((float*)&(x->row1)); + y2 = _mm_loadu_ps((float*)&(x->row2)); + y3 = _mm_loadu_ps((float*)&(x->row3)); + _mm_storeu_ps((float*)&(z->row0), y0); xt = _mm_set_ss(cos_val); t1 = _mm_mul_ps(y1, _mm_shuffle_ps(xt, xt, 0x00)); xt = _mm_set_ss(sin_val); t2 = _mm_mul_ps(y2, _mm_shuffle_ps(xt, xt, 0x00)); - z->row1.data = _mm_add_ps(t1, t2); + _mm_storeu_ps((float*)&(z->row1), _mm_add_ps(t1, t2)); xt = _mm_set_ss(-sin_val); t1 = _mm_mul_ps(y1, _mm_shuffle_ps(xt, xt, 0x00)); xt = _mm_set_ss(cos_val); t2 = _mm_mul_ps(y2, _mm_shuffle_ps(xt, xt, 0x00)); - z->row2.data = _mm_add_ps(t1, t2); - z->row3.data = y3; + _mm_storeu_ps((float*)&(z->row2), _mm_add_ps(t1, t2)); + _mm_storeu_ps((float*)&(z->row3), y3); } inline void mat4_rotate_y_mult_sin_cos(const mat4* x, float_t sin_val, float_t cos_val, mat4* z) { @@ -1277,22 +1356,22 @@ inline void mat4_rotate_y_mult_sin_cos(const mat4* x, float_t sin_val, float_t c __m128 y1; __m128 y2; __m128 y3; - y0 = x->row0.data; - y1 = x->row1.data; - y2 = x->row2.data; - y3 = x->row3.data; + y0 = _mm_loadu_ps((float*)&(x->row0)); + y1 = _mm_loadu_ps((float*)&(x->row1)); + y2 = _mm_loadu_ps((float*)&(x->row2)); + y3 = _mm_loadu_ps((float*)&(x->row3)); xt = _mm_set_ss(cos_val); t0 = _mm_mul_ps(y0, _mm_shuffle_ps(xt, xt, 0x00)); xt = _mm_set_ss(-sin_val); t2 = _mm_mul_ps(y2, _mm_shuffle_ps(xt, xt, 0x00)); - z->row0.data = _mm_add_ps(t0, t2); - z->row1.data = y1; + _mm_storeu_ps((float*)&(z->row0), _mm_add_ps(t0, t2)); + _mm_storeu_ps((float*)&(z->row1), y1); xt = _mm_set_ss(sin_val); t0 = _mm_mul_ps(y0, _mm_shuffle_ps(xt, xt, 0x00)); xt = _mm_set_ss(cos_val); t2 = _mm_mul_ps(y2, _mm_shuffle_ps(xt, xt, 0x00)); - z->row2.data = _mm_add_ps(t0, t2); - z->row3.data = y3; + _mm_storeu_ps((float*)&(z->row2), _mm_add_ps(t0, t2)); + _mm_storeu_ps((float*)&(z->row3), y3); } inline void mat4_rotate_z_mult_sin_cos(const mat4* x, float_t sin_val, float_t cos_val, mat4* z) { @@ -1303,22 +1382,22 @@ inline void mat4_rotate_z_mult_sin_cos(const mat4* x, float_t sin_val, float_t c __m128 y1; __m128 y2; __m128 y3; - y0 = x->row0.data; - y1 = x->row1.data; - y2 = x->row2.data; - y3 = x->row3.data; + y0 = _mm_loadu_ps((float*)&(x->row0)); + y1 = _mm_loadu_ps((float*)&(x->row1)); + y2 = _mm_loadu_ps((float*)&(x->row2)); + y3 = _mm_loadu_ps((float*)&(x->row3)); xt = _mm_set_ss(cos_val); t0 = _mm_mul_ps(y0, _mm_shuffle_ps(xt, xt, 0x00)); xt = _mm_set_ss(sin_val); t1 = _mm_mul_ps(y1, _mm_shuffle_ps(xt, xt, 0x00)); - z->row0.data = _mm_add_ps(t0, t1); + _mm_storeu_ps((float*)&(z->row0), _mm_add_ps(t0, t1)); xt = _mm_set_ss(-sin_val); t0 = _mm_mul_ps(y0, _mm_shuffle_ps(xt, xt, 0x00)); xt = _mm_set_ss(cos_val); t1 = _mm_mul_ps(y1, _mm_shuffle_ps(xt, xt, 0x00)); - z->row1.data = _mm_add_ps(t0, t1); - z->row2.data = y2; - z->row3.data = y3; + _mm_storeu_ps((float*)&(z->row1), _mm_add_ps(t0, t1)); + _mm_storeu_ps((float*)&(z->row2), y2); + _mm_storeu_ps((float*)&(z->row3), y3); } inline void mat4_rot(const mat4* s, float_t x, float_t y, float_t z, mat4* d) { @@ -1334,23 +1413,14 @@ inline void mat4_rot(const mat4* s, float_t x, float_t y, float_t z, mat4* d) { } inline void mat4_rot_x(const mat4* x, float_t y, mat4* z) { - mat3 xt; mat3 yt; - mat3 zt; - xt.row0 = *(vec3*)&x->row0; - xt.row1 = *(vec3*)&x->row1; - xt.row2 = *(vec3*)&x->row2; - float_t y_sin = sinf(y); - float_t y_cos = cosf(y); - yt = mat3_identity; - yt.row1.y = y_cos; - yt.row1.z = y_sin; - yt.row2.y = -y_sin; - yt.row2.z = y_cos; - mat3_mult(&xt, &yt, &zt); - *(vec3*)&z->row0 = zt.row0; - *(vec3*)&z->row1 = zt.row1; - *(vec3*)&z->row2 = zt.row2; + yt.row0 = *(vec3*)&x->row0; + yt.row1 = *(vec3*)&x->row1; + yt.row2 = *(vec3*)&x->row2; + mat3_rotate_x_mult(&yt, y, &yt); + *(vec3*)&z->row0 = yt.row0; + *(vec3*)&z->row1 = yt.row1; + *(vec3*)&z->row2 = yt.row2; z->row0.w = x->row0.w; z->row1.w = x->row1.w; z->row2.w = x->row2.w; @@ -1358,23 +1428,14 @@ inline void mat4_rot_x(const mat4* x, float_t y, mat4* z) { } inline void mat4_rot_y(const mat4* x, float_t y, mat4* z) { - mat3 xt; mat3 yt; - mat3 zt; - xt.row0 = *(vec3*)&x->row0; - xt.row1 = *(vec3*)&x->row1; - xt.row2 = *(vec3*)&x->row2; - float_t y_sin = sinf(y); - float_t y_cos = cosf(y); - yt = mat3_identity; - yt.row0.x = y_cos; - yt.row0.z = -y_sin; - yt.row2.x = y_sin; - yt.row2.z = y_cos; - mat3_mult(&xt, &yt, &zt); - *(vec3*)&z->row0 = zt.row0; - *(vec3*)&z->row1 = zt.row1; - *(vec3*)&z->row2 = zt.row2; + yt.row0 = *(vec3*)&x->row0; + yt.row1 = *(vec3*)&x->row1; + yt.row2 = *(vec3*)&x->row2; + mat3_rotate_y_mult(&yt, y, &yt); + *(vec3*)&z->row0 = yt.row0; + *(vec3*)&z->row1 = yt.row1; + *(vec3*)&z->row2 = yt.row2; z->row0.w = x->row0.w; z->row1.w = x->row1.w; z->row2.w = x->row2.w; @@ -1382,23 +1443,14 @@ inline void mat4_rot_y(const mat4* x, float_t y, mat4* z) { } inline void mat4_rot_z(const mat4* x, float_t y, mat4* z) { - mat3 xt; mat3 yt; - mat3 zt; - xt.row0 = *(vec3*)&x->row0; - xt.row1 = *(vec3*)&x->row1; - xt.row2 = *(vec3*)&x->row2; - float_t y_sin = sinf(y); - float_t y_cos = cosf(y); - yt = mat3_identity; - yt.row0.x = y_cos; - yt.row0.y = y_sin; - yt.row1.x = -y_sin; - yt.row1.y = y_cos; - mat3_mult(&xt, &yt, &zt); - *(vec3*)&z->row0 = zt.row0; - *(vec3*)&z->row1 = zt.row1; - *(vec3*)&z->row2 = zt.row2; + yt.row0 = *(vec3*)&x->row0; + yt.row1 = *(vec3*)&x->row1; + yt.row2 = *(vec3*)&x->row2; + mat3_rotate_z_mult(&yt, y, &yt); + *(vec3*)&z->row0 = yt.row0; + *(vec3*)&z->row1 = yt.row1; + *(vec3*)&z->row2 = yt.row2; z->row0.w = x->row0.w; z->row1.w = x->row1.w; z->row2.w = x->row2.w; @@ -1406,21 +1458,14 @@ inline void mat4_rot_z(const mat4* x, float_t y, mat4* z) { } inline void mat4_rot_x_sin_cos(const mat4* x, float_t sin_val, float_t cos_val, mat4* z) { - mat3 xt; mat3 yt; - mat3 zt; - xt.row0 = *(vec3*)&x->row0; - xt.row1 = *(vec3*)&x->row1; - xt.row2 = *(vec3*)&x->row2; - yt = mat3_identity; - yt.row1.y = cos_val; - yt.row1.z = sin_val; - yt.row2.y = -sin_val; - yt.row2.z = cos_val; - mat3_mult(&xt, &yt, &zt); - *(vec3*)&z->row0 = zt.row0; - *(vec3*)&z->row1 = zt.row1; - *(vec3*)&z->row2 = zt.row2; + yt.row0 = *(vec3*)&x->row0; + yt.row1 = *(vec3*)&x->row1; + yt.row2 = *(vec3*)&x->row2; + mat3_rotate_x_mult_sin_cos(&yt, sin_val, cos_val, &yt); + *(vec3*)&z->row0 = yt.row0; + *(vec3*)&z->row1 = yt.row1; + *(vec3*)&z->row2 = yt.row2; z->row0.w = x->row0.w; z->row1.w = x->row1.w; z->row2.w = x->row2.w; @@ -1428,21 +1473,14 @@ inline void mat4_rot_x_sin_cos(const mat4* x, float_t sin_val, float_t cos_val, } inline void mat4_rot_y_sin_cos(const mat4* x, float_t sin_val, float_t cos_val, mat4* z) { - mat3 xt; mat3 yt; - mat3 zt; - xt.row0 = *(vec3*)&x->row0; - xt.row1 = *(vec3*)&x->row1; - xt.row2 = *(vec3*)&x->row2; - yt = mat3_identity; - yt.row0.x = cos_val; - yt.row0.z = -sin_val; - yt.row2.x = sin_val; - yt.row2.z = cos_val; - mat3_mult(&xt, &yt, &zt); - *(vec3*)&z->row0 = zt.row0; - *(vec3*)&z->row1 = zt.row1; - *(vec3*)&z->row2 = zt.row2; + yt.row0 = *(vec3*)&x->row0; + yt.row1 = *(vec3*)&x->row1; + yt.row2 = *(vec3*)&x->row2; + mat3_rotate_y_mult_sin_cos(&yt, sin_val, cos_val, &yt); + *(vec3*)&z->row0 = yt.row0; + *(vec3*)&z->row1 = yt.row1; + *(vec3*)&z->row2 = yt.row2; z->row0.w = x->row0.w; z->row1.w = x->row1.w; z->row2.w = x->row2.w; @@ -1450,21 +1488,14 @@ inline void mat4_rot_y_sin_cos(const mat4* x, float_t sin_val, float_t cos_val, } inline void mat4_rot_z_sin_cos(const mat4* x, float_t sin_val, float_t cos_val, mat4* z) { - mat3 xt; mat3 yt; - mat3 zt; - xt.row0 = *(vec3*)&x->row0; - xt.row1 = *(vec3*)&x->row1; - xt.row2 = *(vec3*)&x->row2; - yt = mat3_identity; - yt.row0.x = cos_val; - yt.row0.y = sin_val; - yt.row1.x = -sin_val; - yt.row1.y = cos_val; - mat3_mult(&xt, &yt, &zt); - *(vec3*)&z->row0 = zt.row0; - *(vec3*)&z->row1 = zt.row1; - *(vec3*)&z->row2 = zt.row2; + yt.row0 = *(vec3*)&x->row0; + yt.row1 = *(vec3*)&x->row1; + yt.row2 = *(vec3*)&x->row2; + mat3_rotate_z_mult_sin_cos(&yt, sin_val, cos_val, &yt); + *(vec3*)&z->row0 = yt.row0; + *(vec3*)&z->row1 = yt.row1; + *(vec3*)&z->row2 = yt.row2; z->row0.w = x->row0.w; z->row1.w = x->row1.w; z->row2.w = x->row2.w; @@ -1666,10 +1697,10 @@ inline void mat4_translate_mult(const mat4* s, float_t x, float_t y, float_t z, if (s != d) *d = *s; if (x != 0.0f || y != 0.0f || z != 0.0f) { - yt0 = s->row0.data; - yt1 = s->row1.data; - yt2 = s->row2.data; - yt3 = s->row3.data; + yt0 = _mm_loadu_ps((float*)&(s->row0)); + yt1 = _mm_loadu_ps((float*)&(s->row1)); + yt2 = _mm_loadu_ps((float*)&(s->row2)); + yt3 = _mm_loadu_ps((float*)&(s->row3)); yt4 = _mm_set_ss(x); yt0 = _mm_mul_ps(yt0, _mm_shuffle_ps(yt4, yt4, 0)); yt4 = _mm_set_ss(y); @@ -1688,8 +1719,8 @@ inline void mat4_translate_x_mult(const mat4* x, float_t y, mat4* z) { if (x != z) *z = *x; if (y != 0.0f) { - yt0 = x->row0.data; - yt1 = x->row3.data; + yt0 = _mm_loadu_ps((float*)&(x->row0)); + yt1 = _mm_loadu_ps((float*)&(x->row3)); yt2 = _mm_set_ss(y); yt0 = _mm_add_ps(_mm_mul_ps(yt0, _mm_shuffle_ps(yt2, yt2, 0)), yt1); *(vec3*)&z->row3 = *(vec3*)&yt0; @@ -1703,8 +1734,8 @@ inline void mat4_translate_y_mult(const mat4* x, float_t y, mat4* z) { if (x != z) *z = *x; if (y != 0.0f) { - yt0 = x->row1.data; - yt1 = x->row3.data; + yt0 = _mm_loadu_ps((float*)&(x->row1)); + yt1 = _mm_loadu_ps((float*)&(x->row3)); yt2 = _mm_set_ss(y); yt0 = _mm_add_ps(_mm_mul_ps(yt0, _mm_shuffle_ps(yt2, yt2, 0)), yt1); *(vec3*)&z->row3 = *(vec3*)&yt0; @@ -1718,8 +1749,8 @@ inline void mat4_translate_z_mult(const mat4* x, float_t y, mat4* z) { if (x != z) *z = *x; if (y != 0.0f) { - yt0 = x->row2.data; - yt1 = x->row3.data; + yt0 = _mm_loadu_ps((float*)&(x->row2)); + yt1 = _mm_loadu_ps((float*)&(x->row3)); yt2 = _mm_set_ss(y); yt0 = _mm_add_ps(_mm_mul_ps(yt0, _mm_shuffle_ps(yt2, yt2, 0)), yt1); *(vec3*)&z->row3 = *(vec3*)&yt0; @@ -1730,7 +1761,8 @@ inline void mat4_translate_add(const mat4* s, float_t x, float_t y, float_t z, m if (s != d) *d = *s; if (x != 0.0f || y != 0.0f || z != 0.0f) - d->row3.data = _mm_add_ps(s->row3.data, _mm_set_ps(x, y, z, 0.0f)); + _mm_storeu_ps((float*)&(d->row3), _mm_add_ps( + _mm_loadu_ps((float*)&(s->row3)), _mm_set_ps(x, y, z, 0.0f))); } inline void mat4_translate_x_add(const mat4* x, float_t y, mat4* z) { @@ -1755,10 +1787,6 @@ inline void mat4_translate_z_add(const mat4* x, float_t y, mat4* z) { } inline void mat4_from_quat(const quat* quat, mat4* mat) { - mat4_from_quat(quat, (mat4u*)mat); -} - -inline void mat4_from_quat(const quat* quat, mat4u* mat) { float_t y; float_t x; float_t z; @@ -1926,61 +1954,20 @@ inline void mat4_get_rotation(const mat4* x, vec3* z) { } } -inline void mat4_get_rotation(const mat4u* x, vec3* z) { - if (-x->row0.z >= 1.0f) - z->y = (float_t)M_PI_2; - else if (-x->row0.z <= -1.0f) - z->y = (float_t)-M_PI_2; - else - z->y = asinf(-x->row0.z); - - if (fabs(x->row0.z) < 0.99999899f) { - z->x = atan2f(x->row1.z, x->row2.z); - z->z = atan2f(x->row0.y, x->row0.x); - } - else { - z->x = 0.0f; - z->z = atan2f(x->row2.y, x->row1.y); - if (x->row0.z > 0.0f) - z->z = -z->z; - } -} - inline void mat4_get_scale(const mat4* x, vec3* z) { vec4_length(x->row0, z->x); vec4_length(x->row1, z->y); vec4_length(x->row2, z->z); } -inline void mat4_get_scale(const mat4u* x, vec3* z) { - vec4 yt0; - vec4 yt1; - vec4 yt2; - - yt0 = x->row0; - yt1 = x->row1; - yt2 = x->row2; - vec4_length(yt0, z->x); - vec4_length(yt1, z->y); - vec4_length(yt2, z->z); -} - inline void mat4_get_translation(const mat4* x, vec3* z) { *z = *(vec3*)&x->row3; } -inline void mat4_get_translation(const mat4u* x, vec3* z) { - *z = *(vec3*)&x->row3; -} - inline void mat4_set_translation(mat4* x, vec3* z) { *(vec3*)&x->row3 = *z; } -inline void mat4_set_translation(mat4u* x, vec3* z) { - *(vec3*)&x->row3 = *z; -} - inline void mat4_blend(const mat4* x, const mat4* y, mat4* z, float_t blend) { quat q1; quat q2; @@ -2004,29 +1991,6 @@ inline void mat4_blend(const mat4* x, const mat4* y, mat4* z, float_t blend) { mat4_set_translation(z, &t3); } -inline void mat4_blend(const mat4u* x, const mat4u* y, mat4u* z, float_t blend) { - quat q1; - quat q2; - quat q3; - - 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_mat3(y->row0.x, y->row1.x, y->row2.x, y->row0.y, - y->row1.y, y->row2.y, y->row0.z, y->row1.z, y->row2.z, &q1); - - vec3 t1; - vec3 t2; - vec3 t3; - mat4_get_translation(x, &t1); - mat4_get_translation(y, &t2); - - quat_slerp(&q3, &q1, &q2, blend); - vec3_lerp_scalar(t1, t2, t3, blend); - - mat4_from_quat(&q3, z); - mat4_set_translation(z, &t3); -} - inline void mat4_blend_rotation(const mat4* x, const mat4* y, mat4* z, float_t blend) { quat q0; quat q1; @@ -2040,19 +2004,6 @@ inline void mat4_blend_rotation(const mat4* x, const mat4* y, mat4* z, float_t b mat4_from_quat(&q2, z); } -inline void mat4_blend_rotation(const mat4u* x, const mat4u* y, mat4u* z, float_t blend) { - quat q0; - quat q1; - quat q2; - - 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_mat3(y->row0.x, y->row1.x, y->row2.x, y->row0.y, - y->row1.y, y->row2.y, y->row0.z, y->row1.z, y->row2.z, &q1); - quat_slerp(&q0, &q1, &q2, blend); - mat4_from_quat(&q2, z); -} - void mat4_lerp_rotation(mat4* dst, const mat4* src0, const mat4* src1, float_t blend) { vec3 m0; vec3 m1; @@ -2099,52 +2050,6 @@ void mat4_lerp_rotation(mat4* dst, const mat4* src0, const mat4* src1, float_t b *(vec3*)&dst->row2 = m2; } -void mat4_lerp_rotation(mat4u* dst, const mat4u* src0, const mat4u* src1, float_t blend) { - vec3 m0; - vec3 m1; - vec3_lerp_scalar(*(vec3*)&src0->row0, *(vec3*)&src1->row0, m0, blend); - vec3_lerp_scalar(*(vec3*)&src0->row1, *(vec3*)&src1->row1, m1, blend); - - float_t m0_len_sq; - float_t m1_len_sq; - vec3_length_squared(m0, m0_len_sq); - vec3_length_squared(m1, m1_len_sq); - - if (m0_len_sq <= 0.000001f || m1_len_sq <= 0.000001f) { - *dst = *src1; - return; - } - - vec3 m2; - vec3_cross(m0, m1, m2); - vec3_cross(m2, m0, m1); - - float_t m2_len_sq; - vec3_length_squared(m1, m1_len_sq); - vec3_length_squared(m2, m2_len_sq); - if (m2_len_sq <= 0.000001f || m1_len_sq <= 0.000001) { - *dst = *src1; - return; - } - - float_t m0_len = sqrtf(m0_len_sq); - if (m0_len != 0.0f) - vec3_div_scalar(m0, 1.0f / m0_len, m0); - - float_t m1_len = sqrtf(m1_len_sq); - if (m1_len != 0.0f) - vec3_div_scalar(m1, 1.0f / m1_len, m1); - - float_t m2_len = sqrtf(m2_len_sq); - if (m2_len != 0.0f) - vec3_div_scalar(m2, 1.0f / m2_len, m2); - - *dst = mat4_identity; - *(vec3*)&dst->row0 = m0; - *(vec3*)&dst->row1 = m1; - *(vec3*)&dst->row2 = m2; -} - inline float_t mat4_get_max_scale(const mat4* x) { mat4 mat; mat4_transpose(x, &mat); @@ -2163,6 +2068,42 @@ 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) { + quat q1; + quat q2; + quat q3; + float_t t0; + float_t t1; + 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); + 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; +} + +inline 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) { + *mat = mat4_null; + mat->row0.x = (float_t)((2.0 * z_near) / (right - left)); + mat->row1.y = (float_t)((2.0 * z_near) / (top - bottom)); + mat->row2.x = (float_t)((right + left) / (right - left)); + mat->row2.y = (float_t)((top + bottom) / (top - bottom)); + mat->row2.z = -(float_t)((z_far + z_near) / (z_far - z_near)); + mat->row2.w = -1.0f; + mat->row3.z = -(float_t)((2.0 * z_far * z_near) / (z_far - z_near)); +} + inline void mat4_ortho(double_t left, double_t right, double_t bottom, double_t top, double_t z_near, double_t z_far, mat4* mat) { *mat = mat4_identity; @@ -2177,17 +2118,12 @@ inline void mat4_ortho(double_t left, double_t right, inline void mat4_persp(double_t fov_y, double_t aspect, double_t z_near, double_t z_far, mat4* mat) { double_t tan_fov = tan(fov_y * 0.5); - double_t x = 1.0 / (aspect * tan_fov); - double_t y = 1.0 / tan_fov; - double_t d = -(2.0 * z_far * z_near) / (z_far - z_near); - double_t e = -(z_far + z_near) / (z_far - z_near); - *mat = mat4_null; - mat->row0.x = (float_t)x; - mat->row1.y = (float_t)y; - mat->row2.z = (float_t)e; + mat->row0.x = (float_t)(1.0 / (aspect * tan_fov)); + mat->row1.y = (float_t)(1.0 / tan_fov); + mat->row2.z = -(float_t)((z_far + z_near) / (z_far - z_near)); mat->row2.w = -1.0f; - mat->row3.z = (float_t)d; + mat->row3.z = -(float_t)((2.0 * z_far * z_near) / (z_far - z_near)); } inline void mat4_look_at(const vec3* eye, const vec3* target, const vec3* up, mat4* mat) { @@ -2235,21 +2171,3 @@ inline void mat4_look_at(const vec3* eye, const vec3* target, mat4* mat) { mat4_look_at(eye, target, &up, mat); } - -mat4::operator mat4u() const { - mat4u m; - m.row0 = row0; - m.row1 = row1; - m.row2 = row2; - m.row3 = row3; - return m; -} - -mat4u::operator mat4() const { - mat4 m; - m.row0 = row0; - m.row1 = row1; - m.row2 = row2; - m.row3 = row3; - return m; -} diff --git a/src/KKdLib/mat.hpp b/src/KKdLib/mat.hpp index f91a9c27..820dc8c2 100644 --- a/src/KKdLib/mat.hpp +++ b/src/KKdLib/mat.hpp @@ -18,9 +18,6 @@ struct mat3 { mat3(vec3 row0, vec3 row1, vec3 row2); }; -struct mat4; -struct mat4u; - struct mat4 { vec4 row0; vec4 row1; @@ -29,28 +26,12 @@ struct mat4 { mat4(); mat4(vec4 row0, vec4 row1, vec4 row2, vec4 row3); - - operator mat4u() const; -}; - -struct mat4u { - vec4u row0; - vec4u row1; - vec4u row2; - vec4u row3; - - mat4u(); - mat4u(vec4u row0, vec4u row1, vec4u row2, vec4u row3); - - operator mat4() const; }; extern const mat3 mat3_identity; extern const mat3 mat3_null; extern const mat4 mat4_identity; extern const mat4 mat4_null; -extern const mat4u mat4u_identity; -extern const mat4u mat4u_null; extern void mat3_add(const mat3* x, const mat3* y, mat3* z); extern void mat3_sub(const mat3* x, const mat3* y, mat3* z); @@ -73,6 +54,12 @@ extern void mat3_rotate_x_mult(const mat3* x, float_t y, mat3* z); extern void mat3_rotate_y_mult(const mat3* x, float_t y, mat3* z); extern void mat3_rotate_z_mult(const mat3* x, float_t y, mat3* z); extern void mat3_rotate(float_t x, float_t y, float_t z, mat3* w); +extern void mat3_rotate_x_sin_cos(float_t sin_val, float_t cos_val, mat3* y); +extern void mat3_rotate_y_sin_cos(float_t sin_val, float_t cos_val, mat3* y); +extern void mat3_rotate_z_sin_cos(float_t sin_val, float_t cos_val, mat3* y); +extern void mat3_rotate_x_mult_sin_cos(const mat3* x, float_t sin_val, float_t cos_val, mat3* z); +extern void mat3_rotate_y_mult_sin_cos(const mat3* x, float_t sin_val, float_t cos_val, mat3* z); +extern void mat3_rotate_z_mult_sin_cos(const mat3* x, float_t sin_val, float_t cos_val, mat3* z); extern void mat3_scale_x(float_t x, mat3* y); extern void mat3_scale_y(float_t x, mat3* y); extern void mat3_scale_z(float_t x, mat3* y); @@ -83,17 +70,15 @@ extern void mat3_scale_z_mult(const mat3* x, float_t y, mat3* z); extern void mat3_from_quat(const quat* quat, mat3* mat); extern void mat3_from_axis_angle(const vec3* axis, float_t angle, mat3* mat); extern void mat3_from_mat4(const mat4* x, mat3* z); -extern void mat3_from_mat4(const mat4u* x, mat3* z); extern void mat3_from_mat4_inverse(const mat4* x, mat3* z); -extern void mat3_from_mat4_inverse(const mat4u* 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 mat4_add(const mat4* x, const mat4* y, mat4* z); extern void mat4_sub(const mat4* x, const mat4* y, mat4* z); extern void mat4_mult(const mat4* x, const mat4* y, mat4* z); -extern void mat4_mult(const mat4u* x, const mat4u* y, mat4u* z); extern void mat4_mult_vec3(const mat4* x, const vec3* y, vec3* z); extern void mat4_mult_vec3_inv(const mat4* x, const vec3* y, vec3* z); extern void mat4_mult_vec3_trans(const mat4* x, const vec3* y, vec3* z); @@ -101,9 +86,6 @@ extern void mat4_mult_vec3_inv_trans(const mat4* x, const vec3* y, vec3* z); extern void mat4_mult_vec(const mat4* x, vec4* y, vec4* z); extern void mat4_mult_scalar(const mat4* x, float_t y, mat4* z); extern void mat4_transpose(const mat4* x, mat4* z); -extern void mat4_transpose(const mat4* x, mat4u* z); -extern void mat4_transpose(const mat4u* x, mat4* z); -extern void mat4_transpose(const mat4u* x, mat4u* z); extern void mat4_inverse(const mat4* x, mat4* z); extern void mat4_invtrans(const mat4* x, mat4* z); extern void mat4_invrot(const mat4* x, mat4* z); @@ -159,27 +141,22 @@ extern void mat4_translate_x_add(const mat4* x, float_t y, mat4* z); extern void mat4_translate_y_add(const mat4* x, float_t y, mat4* z); extern void mat4_translate_z_add(const mat4* x, float_t y, mat4* z); extern void mat4_from_quat(const quat* quat, mat4* mat); -extern void mat4_from_quat(const quat* quat, mat4u* mat); extern void mat4_from_axis_angle(const vec3* axis, float_t angle, mat4* mat); extern void mat4_from_mat3(const mat3* x, mat4* z); extern void mat4_from_mat3_inverse(const mat3* x, mat4* z); extern void mat4_clear_rot(mat4* x, mat4* z); extern void mat4_clear_trans(mat4* x, mat4* z); extern void mat4_get_scale(const mat4* x, vec3* z); -extern void mat4_get_scale(const mat4u* x, vec3* z); extern void mat4_get_rotation(const mat4* x, vec3* z); -extern void mat4_get_rotation(const mat4u* x, vec3* z); extern void mat4_get_translation(const mat4* x, vec3* z); -extern void mat4_get_translation(const mat4u* x, vec3* z); extern void mat4_set_translation(mat4* x, vec3* z); -extern void mat4_set_translation(mat4u* x, vec3* z); extern void mat4_blend(const mat4* x, const mat4* y, mat4* z, float_t blend); -extern void mat4_blend(const mat4u* x, const mat4u* y, mat4u* z, float_t blend); extern void mat4_blend_rotation(const mat4* x, const mat4* y, mat4* z, float_t blend); -extern void mat4_blend_rotation(const mat4u* x, const mat4u* y, mat4u* 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(mat4u* dst, const mat4u* src0, const mat4u* src1, 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_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, double_t bottom, double_t top, double_t z_near, double_t z_far, mat4* mat); extern void mat4_persp(double_t fov_y, double_t aspect, double_t z_near, double_t z_far, mat4* mat); diff --git a/src/KKdLib/mot.cpp b/src/KKdLib/mot.cpp index 95d36351..1b360a59 100644 --- a/src/KKdLib/mot.cpp +++ b/src/KKdLib/mot.cpp @@ -7,7 +7,7 @@ #include "f2/struct.hpp" #include "io/path.hpp" #include "io/stream.hpp" -#include "interpolation.h" +#include "interpolation.hpp" #include "half_t.hpp" #include "hash.hpp" #include "str_utils.hpp" @@ -485,13 +485,13 @@ static void mot_classic_write_inner(mot_set* ms, stream& s) { } static void mot_modern_read_inner(mot_set* ms, stream& s) { - bool ret = false; f2_struct st; st.read(s); if (st.header.signature != reverse_endianness_uint32_t('MOTC') || !st.data.size()) { ms->ready = false; ms->modern = false; ms->is_x = false; + return; } stream s_motc; @@ -619,6 +619,7 @@ static void mot_modern_read_inner(mot_set* ms, stream& s) { static void mot_modern_write_inner(mot_set* ms, stream& s) { stream s_motc; s_motc.open(); + uint32_t o; enrs e; enrs_entry ee; @@ -748,7 +749,7 @@ static void mot_modern_write_inner(mot_set* ms, stream& s) { s_motc.write_uint8_t(0); s_motc.align_write(0x10); - mh.hash = hash_string_murmurhash(&m->name); + mh.hash = hash_string_murmurhash(m->name); mh.key_set_count_offset = s_motc.get_position(); s_motc.write_uint16_t(m->info); @@ -823,7 +824,7 @@ static void mot_modern_write_inner(mot_set* ms, stream& s) { mh.bone_hash_offset = s_motc.get_position(); for (int32_t j = 0; j < m->bone_info_count; j++) - s_motc.write_uint64_t(hash_string_murmurhash(&m->bone_info[j].name)); + s_motc.write_uint64_t(hash_string_murmurhash(m->bone_info[j].name)); s_motc.align_write(0x10); mh.name_offset = s_motc.get_position(); diff --git a/src/KKdLib/obj.cpp b/src/KKdLib/obj.cpp index 72618a4d..179d8500 100644 --- a/src/KKdLib/obj.cpp +++ b/src/KKdLib/obj.cpp @@ -136,7 +136,8 @@ static void obj_classic_write_skin_block_cloth_root_bone_weight(obj_skin_block_c static void obj_classic_read_skin_block_constraint(obj_skin_block_constraint* b, stream& s, char** str); static void obj_classic_write_skin_block_constraint(obj_skin_block_constraint* b, - stream& s, std::vector& strings, std::vector& string_offsets, char** bone_names, int64_t* offsets); + stream& s, std::vector& strings, std::vector& string_offsets, + char** bone_names, int64_t* offsets); static void obj_classic_read_skin_block_constraint_attach_point(obj_skin_block_constraint_attach_point* ap, stream& s, char** str); static void obj_classic_write_skin_block_constraint_attach_point(obj_skin_block_constraint_attach_point* ap, @@ -759,7 +760,14 @@ static void obj_classic_read_model(obj* obj, stream& s, int64_t base_offset) { if (oh.material_array > 0) { s.set_position(base_offset + oh.material_array, SEEK_SET); obj->material_array = force_malloc_s(obj_material_data, obj->num_material); - s.read(obj->material_array, obj->num_material * sizeof(obj_material_data)); + for (uint32_t i = 0; i < obj->num_material; i++) { + obj_material_data mat_data; + s.read(&mat_data, sizeof(obj_material_data)); + + for (obj_material_texture_data& j : mat_data.material.texdata) + mat4_transpose(&j.tex_coord_mat, &j.tex_coord_mat); + obj->material_array[i] = mat_data; + } } } @@ -918,7 +926,12 @@ static void obj_classic_write_model(obj* obj, stream& s, int64_t base_offset) { if (obj->num_material) { oh.material_array = s.get_position() - base_offset; - s.write(obj->material_array, obj->num_material * sizeof(obj_material_data)); + for (uint32_t i = 0; i < obj->num_material; i++) { + obj_material_data mat_data = obj->material_array[i]; + for (obj_material_texture_data& j : mat_data.material.texdata) + mat4_transpose(&j.tex_coord_mat, &j.tex_coord_mat); + s.write(&mat_data, sizeof(obj_material_data)); + } } s.align_write(0x10); @@ -979,7 +992,7 @@ static void obj_classic_read_skin(obj* obj, stream& s, int64_t base_offset) { if (sh.bone_matrices_offset) { s.set_position(sh.bone_matrices_offset, SEEK_SET); for (uint32_t i = 0; i < sk->bones_count; i++) { - mat4u& mat = sk->bones[i].inv_bind_pose_mat; + mat4& mat = sk->bones[i].inv_bind_pose_mat; mat.row0.x = s.read_float_t(); mat.row1.x = s.read_float_t(); mat.row2.x = s.read_float_t(); @@ -1237,7 +1250,7 @@ static void obj_classic_write_skin(obj* obj, stream& s, int64_t base_offset) { sh.bone_matrices_offset = s.get_position(); for (uint32_t i = 0; i < sk->bones_count; i++) { - mat4u& mat = sk->bones[i].inv_bind_pose_mat; + mat4& mat = sk->bones[i].inv_bind_pose_mat; s.write_float_t(mat.row0.x); s.write_float_t(mat.row1.x); s.write_float_t(mat.row2.x); @@ -1633,8 +1646,8 @@ static void obj_classic_write_skin(obj* obj, stream& s, int64_t base_offset) { continue; obj_skin_block_cloth* cloth = &block->cloth; - for (uint32_t j = 0; j < 3; j++) - s.write(sizeof(mat4)); + if (cloth->mats) + s.write(cloth->mats_count * sizeof(mat4)); } s.align_write(0x10); @@ -1931,27 +1944,43 @@ static void obj_classic_read_skin_block_cloth(obj_skin_block_cloth* b, b->backface_mesh_name = s.read_utf8_string_null_terminated_offset(backface_mesh_name_offset); if (mats_offset) { + int32_t max_matrix_index = -1; + + s.position_push(root_offset, SEEK_SET); + for (uint32_t i = 0; i < b->root_count; i++) { + s.read(0x28); + for (uint32_t j = 0; j < 4; j++) { + uint32_t name_offset = s.read_uint32_t(); + s.read(0x04); + int32_t matrix_index = s.read_int32_t(); + s.read(0x04); + if (name_offset && max_matrix_index < matrix_index) + max_matrix_index = matrix_index; + } + } + s.position_pop(); + + b->mats_count = max_matrix_index > -1 ? max_matrix_index + 1 : 0; + b->mats = force_malloc_s(mat4, b->mats_count); s.position_push(mats_offset, SEEK_SET); - for (uint32_t i = 0; i < 3; i++) { - mat4 mat; + for (uint32_t i = 0; i < b->mats_count; i++) { + mat4& mat = b->mats[i]; mat.row0.x = s.read_float_t(); - mat.row0.y = s.read_float_t(); - mat.row0.z = s.read_float_t(); - mat.row0.w = s.read_float_t(); mat.row1.x = s.read_float_t(); - mat.row1.y = s.read_float_t(); - mat.row1.z = s.read_float_t(); - mat.row1.w = s.read_float_t(); mat.row2.x = s.read_float_t(); - mat.row2.y = s.read_float_t(); - mat.row2.z = s.read_float_t(); - mat.row2.w = s.read_float_t(); mat.row3.x = s.read_float_t(); + mat.row0.y = s.read_float_t(); + mat.row1.y = s.read_float_t(); + mat.row2.y = s.read_float_t(); mat.row3.y = s.read_float_t(); + mat.row0.z = s.read_float_t(); + mat.row1.z = s.read_float_t(); + mat.row2.z = s.read_float_t(); mat.row3.z = s.read_float_t(); + mat.row0.w = s.read_float_t(); + mat.row1.w = s.read_float_t(); + mat.row2.w = s.read_float_t(); mat.row3.w = s.read_float_t(); - mat4_transpose(&mat, &mat); - b->mats[i] = mat; } s.position_pop(); } @@ -2053,10 +2082,10 @@ static void obj_classic_write_skin_block_cloth(obj_skin_block_cloth* b, s.write_uint32_t((uint32_t)skin_param_offset); s.write_uint32_t(b->reserved); - if (b->nodes_count) { + if (b->mats) { s.position_push(*mats_offset, SEEK_SET); - for (uint32_t i = 0; i < 3; i++) { - mat4u& mat = b->mats[i]; + for (uint32_t i = 0; i < b->mats_count; i++) { + mat4& mat = b->mats[i]; s.write_float_t(mat.row0.x); s.write_float_t(mat.row1.x); s.write_float_t(mat.row2.x); @@ -2224,7 +2253,8 @@ static void obj_classic_read_skin_block_constraint(obj_skin_block_constraint* b, } static void obj_classic_write_skin_block_constraint(obj_skin_block_constraint* b, - stream& s, std::vector& strings, std::vector& string_offsets, char** bone_names, int64_t* offsets) { + stream& s, std::vector& strings, std::vector& string_offsets, + char** bone_names, int64_t* offsets) { obj_classic_write_skin_block_node(&b->base, s, strings, string_offsets); int64_t type_offset = 0; @@ -2421,7 +2451,7 @@ static void obj_classic_read_skin_block_motion(obj_skin_block_motion* b, if (bone_matrices_offset) { s.position_push(bone_matrices_offset, SEEK_SET); for (uint32_t i = 0; i < b->nodes_count; i++) { - mat4u& mat = b->nodes[i].transformation; + mat4& mat = b->nodes[i].inv_bind_pose_mat; mat.row0.x = s.read_float_t(); mat.row1.x = s.read_float_t(); mat.row2.x = s.read_float_t(); @@ -2464,7 +2494,7 @@ static void obj_classic_write_skin_block_motion(obj_skin_block_motion* b, s.position_push(*bone_matrices_offset, SEEK_SET); for (uint32_t i = 0; i < b->nodes_count; i++) { - mat4u& mat = b->nodes[i].transformation; + mat4& mat = b->nodes[i].inv_bind_pose_mat; s.write_float_t(mat.row0.x); s.write_float_t(mat.row1.x); s.write_float_t(mat.row2.x); @@ -3680,10 +3710,17 @@ static void obj_modern_read_model(obj* obj, stream& s, int64_t base_offset, s.set_position(base_offset + oh.material_array, SEEK_SET); obj->material_array = force_malloc_s(obj_material_data, obj->num_material); - s.read(obj->material_array, obj->num_material * sizeof(obj_material_data)); - if (s.is_big_endian) - for (uint32_t i = 0; i < obj->num_material; i++) - obj_material_texture_enrs_table.apply(&obj->material_array[i]); + for (uint32_t i = 0; i < obj->num_material; i++) { + obj_material_data mat_data; + s.read(&mat_data, sizeof(obj_material_data)); + + if (s.is_big_endian) + obj_material_texture_enrs_table.apply(&mat_data); + + for (obj_material_texture_data& j : mat_data.material.texdata) + mat4_transpose(&j.tex_coord_mat, &j.tex_coord_mat); + obj->material_array[i] = mat_data; + } } } @@ -4068,8 +4105,12 @@ static void obj_modern_write_model(obj* obj, stream& s, if (obj->material_array) { oh.material_array = s.get_position() - base_offset; - for (uint32_t i = 0; i < obj->num_material; i++) - s.write(&obj->material_array[i], sizeof(obj_material_data)); + for (uint32_t i = 0; i < obj->num_material; i++) { + obj_material_data mat_data = obj->material_array[i]; + for (obj_material_texture_data& j : mat_data.material.texdata) + mat4_transpose(&j.tex_coord_mat, &j.tex_coord_mat); + s.write(&mat_data, sizeof(obj_material_data)); + } } s.align_write(0x10); @@ -4194,7 +4235,7 @@ static void obj_modern_read_skin(obj* obj, stream& s, int64_t base_offset, if (sh.bone_matrices_offset) { s.set_position(sh.bone_matrices_offset, SEEK_SET); for (uint32_t i = 0; i < sk->bones_count; i++) { - mat4u& mat = sk->bones[i].inv_bind_pose_mat; + mat4& mat = sk->bones[i].inv_bind_pose_mat; mat.row0.x = s.read_float_t_reverse_endianness(); mat.row1.x = s.read_float_t_reverse_endianness(); mat.row2.x = s.read_float_t_reverse_endianness(); @@ -4934,21 +4975,22 @@ static void obj_modern_write_skin(obj* obj, stream& s, for (uint32_t i = 0; i < ex->blocks_count; i++) { obj_skin_block* block = &ex->blocks[i]; if (block->type == OBJ_SKIN_BLOCK_CLOTH) { - for (uint32_t j = 0; j < 3; j++) - mats_count++; - + mats_count += block->cloth.mats ? block->cloth.mats_count : 0; root_count += block->cloth.root ? block->cloth.root_count : 0; - nodes_count += block->cloth.nodes ? block->cloth.root_count * (block->cloth.nodes_count - 1) : 0; - mesh_indices_count += block->cloth.mesh_indices ? block->cloth.mesh_indices_count + 1 : 0; - backface_mesh_indices_count += block->cloth.backface_mesh_indices ? block->cloth.backface_mesh_indices_count + 1 : 0; + nodes_count += block->cloth.nodes + ? block->cloth.root_count * (block->cloth.nodes_count - 1) : 0; + mesh_indices_count += block->cloth.mesh_indices + ? block->cloth.mesh_indices_count + 1 : 0; + backface_mesh_indices_count += block->cloth.backface_mesh_indices + ? block->cloth.backface_mesh_indices_count + 1 : 0; } } if (mats_count) { - ee = { off, 1, 64, (uint32_t)mats_count }; + ee = { off, 1, sizeof(mat4), (uint32_t)mats_count }; ee.append(0, 16, ENRS_DWORD); e.vec.push_back(ee); - off = (uint32_t)(mats_count * 64ULL); + off = (uint32_t)(mats_count * sizeof(mat4)); off = align_val(off, 0x10); } @@ -5049,7 +5091,7 @@ static void obj_modern_write_skin(obj* obj, stream& s, sh.bone_matrices_offset = s.get_position(); for (uint32_t i = 0; i < sk->bones_count; i++) { - mat4u& mat = sk->bones[i].inv_bind_pose_mat; + mat4& mat = sk->bones[i].inv_bind_pose_mat; s.write_float_t(mat.row0.x); s.write_float_t(mat.row1.x); s.write_float_t(mat.row2.x); @@ -5473,8 +5515,8 @@ static void obj_modern_write_skin(obj* obj, stream& s, continue; obj_skin_block_cloth* cloth = &block->cloth; - for (uint32_t j = 0; j < 3; j++) - s.write(sizeof(mat4)); + if (cloth->mats) + s.write(cloth->mats_count * sizeof(mat4)); } s.align_write(0x10); @@ -5879,9 +5921,25 @@ static void obj_modern_read_skin_block_cloth(obj_skin_block_cloth* b, b->reserved = s.read_uint32_t_reverse_endianness(); if (mats_offset) { + int32_t max_matrix_index = -1; + + s.position_push(root_offset, SEEK_SET); + for (uint32_t i = 0; i < b->root_count; i++) { + s.read(0x28); + for (uint32_t j = 0; j < 4; j++) { + uint32_t name_offset = s.read_uint32_t(); + int32_t matrix_index = s.read_int32_t(); + if (name_offset&& max_matrix_index < matrix_index) + max_matrix_index = matrix_index; + } + } + s.position_pop(); + + b->mats_count = max_matrix_index > -1 ? max_matrix_index + 1 : 0; + b->mats = force_malloc_s(mat4, b->mats_count); s.position_push(mats_offset, SEEK_SET); - for (uint32_t i = 0; i < 3; i++) { - mat4u& mat = b->mats[i]; + for (uint32_t i = 0; i < b->mats_count; i++) { + mat4& mat = b->mats[i]; mat.row0.x = s.read_float_t_reverse_endianness(); mat.row1.x = s.read_float_t_reverse_endianness(); mat.row2.x = s.read_float_t_reverse_endianness(); @@ -6015,10 +6073,10 @@ static void obj_modern_write_skin_block_cloth(obj_skin_block_cloth* b, s.write_uint32_t(b->reserved); } - if (b->nodes_count) { + if (b->mats) { s.position_push(*mats_offset, SEEK_SET); - for (uint32_t i = 0; i < 3; i++) { - mat4u& mat = b->mats[i]; + for (uint32_t i = 0; i < b->mats_count; i++) { + mat4& mat = b->mats[i]; s.write_float_t(mat.row0.x); s.write_float_t(mat.row1.x); s.write_float_t(mat.row2.x); @@ -6414,7 +6472,7 @@ static void obj_modern_read_skin_block_motion(obj_skin_block_motion* b, if (bone_matrices_offset) { s.position_push(bone_matrices_offset, SEEK_SET); for (uint32_t i = 0; i < b->nodes_count; i++) { - mat4u& mat = b->nodes[i].transformation; + mat4& mat = b->nodes[i].inv_bind_pose_mat; mat.row0.x = s.read_float_t_reverse_endianness(); mat.row1.x = s.read_float_t_reverse_endianness(); mat.row2.x = s.read_float_t_reverse_endianness(); @@ -6462,7 +6520,7 @@ static void obj_modern_write_skin_block_motion(obj_skin_block_motion* b, s.position_push(*bone_matrices_offset, SEEK_SET); for (uint32_t i = 0; i < b->nodes_count; i++) { - mat4u& mat = b->nodes[i].transformation; + mat4& mat = b->nodes[i].inv_bind_pose_mat; s.write_float_t(mat.row0.x); s.write_float_t(mat.row1.x); s.write_float_t(mat.row2.x); diff --git a/src/KKdLib/obj.hpp b/src/KKdLib/obj.hpp index 9c7cf6ed..80dc9e20 100644 --- a/src/KKdLib/obj.hpp +++ b/src/KKdLib/obj.hpp @@ -253,7 +253,7 @@ struct obj_material_texture_data { obj_texture_shader_attrib shader_info; char ex_shader[8]; float_t weight; - mat4u tex_coord_mat; + mat4 tex_coord_mat; union { uint32_t reserved[8]; int32_t texture_index; @@ -285,10 +285,10 @@ union obj_material_attrib { }; struct obj_material_color { - vec4u diffuse; - vec4u ambient; - vec4u specular; - vec4u emission; + vec4 diffuse; + vec4 ambient; + vec4 specular; + vec4 emission; float_t shininess; float_t intensity; }; @@ -355,17 +355,17 @@ struct obj_sub_mesh { struct obj_vertex_data { vec3 position; vec3 normal; - vec4u tangent; + vec4 tangent; vec3 binormal; vec2 texcoord0; vec2 texcoord1; vec2 texcoord2; vec2 texcoord3; - vec4u color0; - vec4u color1; - vec4u bone_weight; - vec4iu bone_index; - vec4u unknown; + vec4 color0; + vec4 color1; + vec4 bone_weight; + vec4i bone_index; + vec4 unknown; }; struct obj_mesh_attrib_member { @@ -463,7 +463,8 @@ struct obj_skin_block_cloth { uint32_t root_count; uint32_t nodes_count; uint32_t field_14; - mat4u mats[3]; + mat4* mats; + uint32_t mats_count; obj_skin_block_cloth_root* root; obj_skin_block_cloth_node* nodes; uint16_t* mesh_indices; @@ -535,7 +536,7 @@ struct obj_skin_block_expression { struct obj_skin_motion_node { uint32_t name_index; - mat4u transformation; + mat4 inv_bind_pose_mat; }; struct obj_skin_block_motion { @@ -601,7 +602,7 @@ struct obj_skin_ex_data { struct obj_skin_bone { uint32_t id; uint32_t parent; - mat4u inv_bind_pose_mat; + mat4 inv_bind_pose_mat; char* name; }; diff --git a/src/KKdLib/pv_exp.cpp b/src/KKdLib/pv_exp.cpp index 25697881..6e4761a9 100644 --- a/src/KKdLib/pv_exp.cpp +++ b/src/KKdLib/pv_exp.cpp @@ -205,17 +205,356 @@ bool pv_exp::load_file(void* data, const char* path, const char* file, uint32_t } static void pv_exp_classic_read_inner(pv_exp* exp, stream& s) { + if (s.read_uint32_t() != 0x64) { + exp->ready = false; + exp->modern = false; + exp->is_x = false; + return; + } + exp->motion_data.resize(0); + exp->motion_data.resize(s.read_int32_t()); + + int64_t motion_offsets_offset = s.read_int32_t(); + int64_t name_offsets_offset = s.read_uint32_t(); + + int64_t* face_offset = force_malloc_s(int64_t, exp->motion_data.size()); + int64_t* face_cl_offset = force_malloc_s(int64_t, exp->motion_data.size()); + int64_t* name_offset = force_malloc_s(int64_t, exp->motion_data.size()); + + s.position_push(motion_offsets_offset, SEEK_SET); + for (pv_exp_mot& i : exp->motion_data) { + face_offset[&i - exp->motion_data.data()] = s.read_uint32_t(); + face_cl_offset[&i - exp->motion_data.data()] = s.read_uint32_t(); + } + s.position_pop(); + + s.position_push(name_offsets_offset, SEEK_SET); + for (pv_exp_mot& i : exp->motion_data) + name_offset[&i - exp->motion_data.data()] = s.read_uint32_t(); + s.position_pop(); + + for (pv_exp_mot& i : exp->motion_data) { + if (face_offset[&i - exp->motion_data.data()]) { + size_t face_count = 0; + s.position_push(face_offset[&i - exp->motion_data.data()], SEEK_SET); + s.read(0x04); + while (s.read_int16_t() != -1) { + s.read(0x0C); + face_count++; + } + face_count++; + s.position_pop(); + + i.face_data = new pv_exp_data[face_count]; + s.position_push(face_offset[&i - exp->motion_data.data()], SEEK_SET); + s.read(i.face_data, sizeof(pv_exp_data) * face_count); + s.position_pop(); + } + + if (face_cl_offset[&i - exp->motion_data.data()]) { + size_t face_cl_count = 0; + s.position_push(face_cl_offset[&i - exp->motion_data.data()], SEEK_SET); + s.read(0x04); + while (s.read_int16_t() != -1) { + s.read(0x0C); + face_cl_count++; + } + face_cl_count++; + s.position_pop(); + + i.face_cl_data = new pv_exp_data[face_cl_count]; + s.position_push(face_cl_offset[&i - exp->motion_data.data()], SEEK_SET); + s.read(i.face_cl_data, sizeof(pv_exp_data) * face_cl_count); + s.position_pop(); + } + + if (name_offset[&i - exp->motion_data.data()]) + i.name = s.read_string_null_terminated_offset(name_offset[&i - exp->motion_data.data()]); + } + + free(face_offset); + free(face_cl_offset); + free(name_offset); + + exp->ready = true; + exp->modern = false; + exp->is_x = false; } static void pv_exp_classic_write_inner(pv_exp* exp, stream& s) { + s.write_uint32_t(0x64); + s.write_uint32_t((uint32_t)exp->motion_data.size()); + s.write_uint32_t(0x20); + s.position_push(s.get_position(), SEEK_SET); + s.write_uint32_t(0x00); + + s.write_uint32_t(0x00); + s.write_uint32_t(0x00); + + for (pv_exp_mot& i : exp->motion_data) { + s.write_uint32_t(0x00); + s.write_uint32_t(0x00); + s.write_uint32_t(0x00); + } + s.align_write(0x20); + + int64_t* face_offset = force_malloc_s(int64_t, exp->motion_data.size()); + int64_t* face_cl_offset = force_malloc_s(int64_t, exp->motion_data.size()); + int64_t* name_offset = force_malloc_s(int64_t, exp->motion_data.size()); + + for (pv_exp_mot& i : exp->motion_data) { + face_offset[&i - exp->motion_data.data()] = s.get_position(); + + pv_exp_data* face_data = i.face_data; + while (face_data->type != -1) { + s.write_float_t(face_data->frame); + s.write_int16_t(face_data->type); + s.write_int16_t(face_data->id); + s.write_float_t(face_data->value); + s.write_float_t(face_data->trans); + face_data++; + } + s.align_write(0x20); + + face_cl_offset[&i - exp->motion_data.data()] = s.get_position(); + + pv_exp_data* face_cl_data = i.face_cl_data; + while (face_cl_data->type != -1) { + s.write_float_t(face_cl_data->frame); + s.write_int16_t(face_cl_data->type); + s.write_int16_t(face_cl_data->id); + s.write_float_t(face_cl_data->value); + s.write_float_t(face_cl_data->trans); + face_cl_data++; + } + s.align_write(0x20); + } + + for (pv_exp_mot& i : exp->motion_data) { + name_offset[&i - exp->motion_data.data()] = s.get_position(); + s.write_string_null_terminated(i.name); + } + s.align_write(0x10); + + s.set_position(exp->is_x ? 0x28 : 0x20, SEEK_SET); + for (pv_exp_mot& i : exp->motion_data) { + s.write_uint32_t((uint32_t)face_offset[&i - exp->motion_data.data()]); + s.write_uint32_t((uint32_t)face_cl_offset[&i - exp->motion_data.data()]); + } + + int64_t name_offsets_offset = s.get_position(); + for (pv_exp_mot& i : exp->motion_data) + s.write_uint32_t((uint32_t)name_offset[&i - exp->motion_data.data()]); + + free(face_offset); + free(face_cl_offset); + free(name_offset); + s.position_pop(); + + s.write_uint32_t((uint32_t)name_offsets_offset); } static void pv_exp_modern_read_inner(pv_exp* exp, stream& s, uint32_t header_length) { + if (s.read_uint32_t() != 0x64) { + exp->ready = false; + exp->modern = false; + exp->is_x = false; + return; + } + bool is_x = false; + + exp->motion_data.resize(0); + exp->motion_data.resize(s.read_int32_t()); + + int64_t motion_offsets_offset = s.read_int32_t(); + int64_t name_offsets_offset = s.read_offset_f2(header_length); + if (name_offsets_offset == 0x00) { + is_x = true; + name_offsets_offset = (int)s.read_offset_x(); + } + + int64_t* face_offset = force_malloc_s(int64_t, exp->motion_data.size()); + int64_t* face_cl_offset = force_malloc_s(int64_t, exp->motion_data.size()); + int64_t* name_offset = force_malloc_s(int64_t, exp->motion_data.size()); + + s.position_push(motion_offsets_offset, SEEK_SET); + if (!is_x) + for (pv_exp_mot& i : exp->motion_data) { + face_offset[&i - exp->motion_data.data()] = s.read_offset_f2(header_length); + face_cl_offset[&i - exp->motion_data.data()] = s.read_offset_f2(header_length); + } + else + for (pv_exp_mot& i : exp->motion_data) { + face_offset[&i - exp->motion_data.data()] = s.read_offset_x(); + face_cl_offset[&i - exp->motion_data.data()] = s.read_offset_x(); + } + s.position_pop(); + + s.position_push(name_offsets_offset, SEEK_SET); + if (!is_x) + for (pv_exp_mot& i : exp->motion_data) + name_offset[&i - exp->motion_data.data()] = s.read_offset_f2(header_length); + else + for (pv_exp_mot& i : exp->motion_data) + name_offset[&i - exp->motion_data.data()] = s.read_offset_x(); + s.position_pop(); + + for (pv_exp_mot& i : exp->motion_data) { + if (face_offset[&i - exp->motion_data.data()]) { + size_t face_count = 0; + s.position_push(face_offset[&i - exp->motion_data.data()], SEEK_SET); + s.read(0x04); + while (s.read_int16_t() != -1) { + s.read(0x0E); + face_count++; + } + face_count++; + s.position_pop(); + + i.face_data = new pv_exp_data[face_count]; + s.position_push(face_offset[&i - exp->motion_data.data()], SEEK_SET); + s.read(i.face_data, sizeof(pv_exp_data) * face_count); + s.position_pop(); + } + + if (face_cl_offset[&i - exp->motion_data.data()]) { + size_t face_cl_count = 0; + s.position_push(face_cl_offset[&i - exp->motion_data.data()], SEEK_SET); + s.read(0x04); + while (s.read_int16_t() != -1) { + s.read(0x0E); + face_cl_count++; + } + face_cl_count++; + s.position_pop(); + + i.face_cl_data = new pv_exp_data[face_cl_count]; + s.position_push(face_cl_offset[&i - exp->motion_data.data()], SEEK_SET); + s.read(i.face_cl_data, sizeof(pv_exp_data) * face_cl_count); + s.position_pop(); + } + + if (name_offset[&i - exp->motion_data.data()]) + i.name = s.read_string_null_terminated_offset(name_offset[&i - exp->motion_data.data()]); + } + + free(face_offset); + free(face_cl_offset); + free(name_offset); + + exp->ready = true; + exp->modern = true; + exp->is_x = is_x; } static void pv_exp_modern_write_inner(pv_exp* exp, stream& s) { + stream s_expc; + s_expc.open(); + bool is_x = exp->is_x; + + s_expc.write_uint32_t(0x64); + s_expc.write_int32_t((int32_t)exp->motion_data.size()); + s_expc.write_offset(is_x ? 0x28 : 0x20, 0x20, is_x); + + s_expc.position_push(s_expc.get_position(), SEEK_SET); + s_expc.write_offset(0x00, 0x20, is_x); + + s_expc.write_offset(0x00, 0x20, is_x); + s_expc.write_offset(0x00, 0x20, is_x); + + if (!is_x) + for (pv_exp_mot& i : exp->motion_data) { + s_expc.write_offset_f2(0x00, 0x20); + s_expc.write_offset_f2(0x00, 0x20); + s_expc.write_offset_f2(0x00, 0x20); + } + else + for (pv_exp_mot& i : exp->motion_data) { + s_expc.write_offset_x(0x00); + s_expc.write_offset_x(0x00); + s_expc.write_offset_x(0x00); + } + s_expc.align_write(0x20); + + int64_t* face_offset = force_malloc_s(int64_t, exp->motion_data.size()); + int64_t* face_cl_offset = force_malloc_s(int64_t, exp->motion_data.size()); + int64_t* name_offset = force_malloc_s(int64_t, exp->motion_data.size()); + + for (pv_exp_mot& i : exp->motion_data) { + face_offset[&i - exp->motion_data.data()] = s_expc.get_position(); + + pv_exp_data* face_data = i.face_data; + while (face_data->type != -1) { + s_expc.write_float_t(face_data->frame); + s_expc.write_int16_t(face_data->type); + s_expc.write_int16_t(face_data->id); + s_expc.write_float_t(face_data->value); + s_expc.write_float_t(face_data->trans); + face_data++; + } + s_expc.align_write(0x20); + + face_cl_offset[&i - exp->motion_data.data()] = s_expc.get_position(); + + pv_exp_data* face_cl_data = i.face_cl_data; + while (face_cl_data->type != -1) { + s_expc.write_float_t(face_cl_data->frame); + s_expc.write_int16_t(face_cl_data->type); + s_expc.write_int16_t(face_cl_data->id); + s_expc.write_float_t(face_cl_data->value); + s_expc.write_float_t(face_cl_data->trans); + face_cl_data++; + } + s_expc.align_write(0x20); + } + + for (pv_exp_mot& i : exp->motion_data) { + name_offset[&i - exp->motion_data.data()] = s_expc.get_position(); + s_expc.write_string_null_terminated(i.name); + } + s_expc.align_write(0x10); + + s_expc.set_position(is_x ? 0x28 : 0x20, SEEK_SET); + if (!is_x) + for (pv_exp_mot& i : exp->motion_data) { + s_expc.write_offset_f2(face_offset[&i - exp->motion_data.data()], 0x20); + s_expc.write_offset_f2(face_cl_offset[&i - exp->motion_data.data()], 0x20); + } + else + for (pv_exp_mot& i : exp->motion_data) { + s_expc.write_offset_x(face_offset[&i - exp->motion_data.data()]); + s_expc.write_offset_x(face_cl_offset[&i - exp->motion_data.data()]); + } + + int64_t name_offsets_offset = s_expc.get_position(); + if (!is_x) + for (pv_exp_mot& i : exp->motion_data) + s_expc.write_offset_f2(name_offset[&i - exp->motion_data.data()], 0x20); + else + for (pv_exp_mot& i : exp->motion_data) + s_expc.write_offset_x(name_offset[&i - exp->motion_data.data()]); + + free(face_offset); + free(face_cl_offset); + free(name_offset); + + s_expc.position_pop(); + + s_expc.write_offset(name_offsets_offset, 0x20, is_x); + + f2_struct st; + s_expc.align_write(0x10); + s_expc.copy(st.data); + s_expc.close(); + + st.header.signature = reverse_endianness_uint32_t('EXPC'); + st.header.length = 0x20; + st.header.use_big_endian = false; + st.header.use_section_size = true; + + st.write(s, true, exp->is_x); } diff --git a/src/KKdLib/pv_exp.hpp b/src/KKdLib/pv_exp.hpp index a2e3fcae..efed5152 100644 --- a/src/KKdLib/pv_exp.hpp +++ b/src/KKdLib/pv_exp.hpp @@ -34,7 +34,7 @@ struct pv_exp { std::vector motion_data; pv_exp(); - ~pv_exp(); + virtual ~pv_exp(); void read(const char* path, bool modern); void read(const wchar_t* path, bool modern); diff --git a/src/KKdLib/pvpp.cpp b/src/KKdLib/pvpp.cpp index 2814b904..f523a18e 100644 --- a/src/KKdLib/pvpp.cpp +++ b/src/KKdLib/pvpp.cpp @@ -10,10 +10,10 @@ #include "hash.hpp" #include "str_utils.hpp" -static void pvpp_a3da_read(pvpp_a3da* a3d, stream& s); +static void pvpp_auth_3d_read(pvpp_auth_3d* a3d, stream& s); static void pvpp_chara_read(pvpp_chara* chr, stream& s); static void pvpp_chara_effect_read(pvpp_chara_effect* chr_eff, stream& s); -static void pvpp_chara_effect_a3da_read(pvpp_chara_effect_a3da* chr_pv_eff, stream& s); +static void pvpp_chara_effect_auth_3d_read(pvpp_chara_effect_auth_3d* chr_pv_eff, stream& s); static void pvpp_chara_item_read(pvpp_chara_item* chr_itm, stream& s); static void pvpp_effect_read(pvpp_effect* eff, stream& s); static void pvpp_glitter_read(pvpp_glitter* glt, stream& s); @@ -21,6 +21,79 @@ static void pvpp_motion_read(pvpp_motion* mot, stream& s); static void pvpp_object_set_read(pvpp_object_set* objset, stream& s); static void pvpp_read_inner(pvpp* pp, stream& s); +pvpp_auth_3d::pvpp_auth_3d() { + hash = hash_murmurhash_empty; +} + +pvpp_auth_3d::~pvpp_auth_3d() { + +} + +pvpp_chara::pvpp_chara() : chara_effect_init() { + +} + +pvpp_chara::~pvpp_chara() { + +} + +pvpp_chara_effect::pvpp_chara_effect() : base_chara(), chara_id() { + +} + +pvpp_chara_effect::~pvpp_chara_effect() { + +} + +pvpp_chara_effect_auth_3d::pvpp_chara_effect_auth_3d() : has_object_set(), +u00(), u01(), u02(), u03(), u04(), u05(), u06(), u07() { + +} + +pvpp_chara_effect_auth_3d::~pvpp_chara_effect_auth_3d() { + +} + +pvpp_chara_item::pvpp_chara_item() : u18() { + +} + +pvpp_chara_item::~pvpp_chara_item() { + +} + +pvpp_effect::pvpp_effect() : chara_id() { + +} + +pvpp_effect::~pvpp_effect() { + +} + +pvpp_glitter::pvpp_glitter() : unk2() { + +} + +pvpp_glitter::~pvpp_glitter() { + +} + +pvpp_motion::pvpp_motion() { + hash = hash_murmurhash_empty; +} + +pvpp_motion::~pvpp_motion() { + +} + +pvpp_object_set::pvpp_object_set() { + hash = hash_murmurhash_empty; +} + +pvpp_object_set::~pvpp_object_set() { + +} + pvpp::pvpp() : ready() { } @@ -81,80 +154,7 @@ bool pvpp::load_file(void* data, const char* path, const char* file, uint32_t ha return pp->ready; } -pvpp_a3da::pvpp_a3da() : hash(hash_murmurhash_empty) { - -} - -pvpp_a3da::~pvpp_a3da() { - -} - -pvpp_chara::pvpp_chara() : chara_effect_init() { - -} - -pvpp_chara::~pvpp_chara() { - -} - -pvpp_chara_effect::pvpp_chara_effect() : base_chara(), chara_index() { - -} - -pvpp_chara_effect::~pvpp_chara_effect() { - -} - -pvpp_chara_effect_a3da::pvpp_chara_effect_a3da() : has_object_set(), -u00(), u01(), u02(), u03(), u04(), u05(), u06(), u07() { - -} - -pvpp_chara_effect_a3da::~pvpp_chara_effect_a3da() { - -} - -pvpp_chara_item::pvpp_chara_item() : u18() { - -} - -pvpp_chara_item::~pvpp_chara_item() { - -} - -pvpp_effect::pvpp_effect() : chara_index() { - -} - -pvpp_effect::~pvpp_effect() { - -} - -pvpp_glitter::pvpp_glitter() : unk2() { - -} - -pvpp_glitter::~pvpp_glitter() { - -} - -pvpp_motion::pvpp_motion() : hash(hash_murmurhash_empty) { - -} - -pvpp_motion::~pvpp_motion() { - -} - -pvpp_object_set::pvpp_object_set() : hash(hash_murmurhash_empty) { - -} - -pvpp_object_set::~pvpp_object_set() { - -} - -static void pvpp_a3da_read(pvpp_a3da* a3d, stream& s) { +static void pvpp_auth_3d_read(pvpp_auth_3d* a3d, stream& s) { a3d->name = s.read_string_null_terminated_offset(s.read_offset_x()); a3d->hash = s.read_uint32_t_reverse_endianness(); s.align_read(0x08); @@ -164,136 +164,155 @@ static void pvpp_chara_read(pvpp_chara* chr, stream& s) { int8_t u00 = s.read_int8_t(); int8_t u01 = s.read_int8_t(); int8_t motion_count = s.read_int8_t(); - int8_t a3da_count = s.read_int8_t(); + int8_t auth_3d_count = s.read_int8_t(); int8_t item_count = s.read_int8_t(); int8_t u05 = s.read_int8_t(); int8_t glitter_count = s.read_int8_t(); int8_t u07 = s.read_int8_t(); size_t chr_eff_offset = s.read_offset_x(); size_t motion_offset = s.read_offset_x(); - size_t a3da_offset = s.read_offset_x(); + size_t auth_3d_offset = s.read_offset_x(); size_t item_offset = s.read_offset_x(); size_t glitter_offset = s.read_offset_x(); size_t o30 = s.read_offset_x(); chr->chara_effect_init = false; - if (chr_eff_offset) { + if (chr_eff_offset > 0) { s.position_push(chr_eff_offset, SEEK_SET); pvpp_chara_effect_read(&chr->chara_effect, s); chr->chara_effect_init = true; s.position_pop(); } - chr->motion.resize(motion_count); + if (motion_offset > 0) { + chr->motion.resize(motion_count); - s.position_push(motion_offset, SEEK_SET); - for (pvpp_motion& i : chr->motion) { - s.position_push(s.read_offset_x(), SEEK_SET); - pvpp_motion_read(&i, s); + s.position_push(motion_offset, SEEK_SET); + for (pvpp_motion& i : chr->motion) { + s.position_push(s.read_offset_x(), SEEK_SET); + pvpp_motion_read(&i, s); + s.position_pop(); + } s.position_pop(); } - s.position_pop(); - chr->a3da.resize(a3da_count); + if (auth_3d_offset > 0) { + chr->auth_3d.resize(auth_3d_count); - s.position_push(a3da_offset, SEEK_SET); - for (pvpp_a3da& i : chr->a3da) - pvpp_a3da_read(&i, s); - s.position_pop(); + s.position_push(auth_3d_offset, SEEK_SET); + for (pvpp_auth_3d& i : chr->auth_3d) + pvpp_auth_3d_read(&i, s); + s.position_pop(); + } - chr->item.resize(item_count); + if (item_offset > 0) { + chr->item.resize(item_count); - s.position_push(item_offset, SEEK_SET); - for (pvpp_chara_item& i : chr->item) - pvpp_chara_item_read(&i, s); - s.position_pop(); + s.position_push(item_offset, SEEK_SET); + for (pvpp_chara_item& i : chr->item) + pvpp_chara_item_read(&i, s); + s.position_pop(); + } - chr->glitter.resize(glitter_count); + if (glitter_offset > 0) { + chr->glitter.resize(glitter_count); - s.position_push(glitter_offset, SEEK_SET); - for (pvpp_glitter& i : chr->glitter) - pvpp_glitter_read(&i, s); - s.position_pop(); + s.position_push(glitter_offset, SEEK_SET); + for (pvpp_glitter& i : chr->glitter) + pvpp_glitter_read(&i, s); + s.position_pop(); + } } static void pvpp_chara_effect_read(pvpp_chara_effect* chr_eff, stream& s) { - chr_eff->base_chara = (pvpp_chara_type)s.read_uint8_t(); + chr_eff->base_chara = (pvpp_chara_index)s.read_uint8_t(); int8_t pv_effects_count = s.read_int8_t(); - chr_eff->chara_index = (pvpp_chara_index)s.read_uint8_t(); + chr_eff->chara_id = (pvpp_chara_id)s.read_uint8_t(); size_t pv_effects_offstet = s.read_offset_x(); - chr_eff->effect_a3da.resize(pv_effects_count); + if (pv_effects_offstet > 0) { + chr_eff->effect_auth_3d.resize(pv_effects_count); - s.position_push(pv_effects_offstet, SEEK_SET); - for (pvpp_chara_effect_a3da& i : chr_eff->effect_a3da) - pvpp_chara_effect_a3da_read(&i, s); - s.position_pop(); + s.position_push(pv_effects_offstet, SEEK_SET); + for (pvpp_chara_effect_auth_3d& i : chr_eff->effect_auth_3d) + pvpp_chara_effect_auth_3d_read(&i, s); + s.position_pop(); + } } -static void pvpp_chara_effect_a3da_read(pvpp_chara_effect_a3da* chr_eff_a3da, stream& s) { - chr_eff_a3da->u00 = s.read_uint8_t(); - chr_eff_a3da->u01 = s.read_uint8_t(); - chr_eff_a3da->u02 = s.read_uint8_t(); - chr_eff_a3da->u03 = s.read_uint8_t(); - chr_eff_a3da->u04 = s.read_uint8_t(); - chr_eff_a3da->u05 = s.read_uint8_t(); - chr_eff_a3da->u06 = s.read_uint8_t(); - chr_eff_a3da->u07 = s.read_uint8_t(); - size_t a3da_offset = s.read_offset_x(); - size_t source_a3da_offset = s.read_offset_x(); +static void pvpp_chara_effect_auth_3d_read(pvpp_chara_effect_auth_3d* chr_eff_auth_3d, stream& s) { + chr_eff_auth_3d->u00 = s.read_uint8_t(); + chr_eff_auth_3d->u01 = s.read_uint8_t(); + chr_eff_auth_3d->u02 = s.read_uint8_t(); + chr_eff_auth_3d->u03 = s.read_uint8_t(); + chr_eff_auth_3d->u04 = s.read_uint8_t(); + chr_eff_auth_3d->u05 = s.read_uint8_t(); + chr_eff_auth_3d->u06 = s.read_uint8_t(); + chr_eff_auth_3d->u07 = s.read_uint8_t(); + size_t auth_3d_offset = s.read_offset_x(); + size_t source_auth_3d_offset = s.read_offset_x(); - s.position_push(a3da_offset, SEEK_SET); - pvpp_a3da_read(&chr_eff_a3da->a3da, s); - s.position_pop(); + if (auth_3d_offset > 0) { + s.position_push(auth_3d_offset, SEEK_SET); + pvpp_auth_3d_read(&chr_eff_auth_3d->auth_3d, s); + s.position_pop(); + } - chr_eff_a3da->has_object_set = false; - if (source_a3da_offset) { - s.position_push(source_a3da_offset, SEEK_SET); - pvpp_object_set_read(&chr_eff_a3da->object_set, s); - chr_eff_a3da->has_object_set = true; + chr_eff_auth_3d->has_object_set = false; + if (source_auth_3d_offset > 0) { + s.position_push(source_auth_3d_offset, SEEK_SET); + pvpp_object_set_read(&chr_eff_auth_3d->object_set, s); + chr_eff_auth_3d->has_object_set = true; s.position_pop(); } } static void pvpp_chara_item_read(pvpp_chara_item* chr_itm, stream& s) { - int8_t a3das_count = s.read_int8_t(); - size_t a3das_offset = s.read_offset_x(); + int8_t auth_3ds_count = s.read_int8_t(); + size_t auth_3ds_offset = s.read_offset_x(); size_t bone_offset = s.read_offset_x(); chr_itm->u18.x = s.read_float_t_reverse_endianness(); chr_itm->u18.y = s.read_float_t_reverse_endianness(); chr_itm->u18.z = s.read_float_t_reverse_endianness(); chr_itm->u18.w = s.read_float_t_reverse_endianness(); - chr_itm->a3da.resize(a3das_count); + if (auth_3ds_offset > 0) { + chr_itm->auth_3d.resize(auth_3ds_count); - s.position_push(a3das_offset, SEEK_SET); - for (pvpp_a3da& i : chr_itm->a3da) - pvpp_a3da_read(&i, s); - s.position_pop(); + s.position_push(auth_3ds_offset, SEEK_SET); + for (pvpp_auth_3d& i : chr_itm->auth_3d) + pvpp_auth_3d_read(&i, s); + s.position_pop(); + } - chr_itm->bone = s.read_string_null_terminated_offset(bone_offset); + if (bone_offset > 0) + chr_itm->bone = s.read_string_null_terminated_offset(bone_offset); } static void pvpp_effect_read(pvpp_effect* eff, stream& s) { - int8_t a3das_count = s.read_int8_t(); + int8_t auth_3ds_count = s.read_int8_t(); int8_t glitters_count = s.read_int8_t(); - eff->chara_index = (pvpp_chara_type)s.read_uint8_t(); - int64_t a3das_offset = s.read_offset_x(); + eff->chara_id = (pvpp_chara_id)s.read_uint8_t(); + int64_t auth_3ds_offset = s.read_offset_x(); int64_t glitters_offset = s.read_offset_x(); - eff->a3da.resize(a3das_count); + if (auth_3ds_offset) { + eff->auth_3d.resize(auth_3ds_count); - s.position_push(a3das_offset, SEEK_SET); - for (pvpp_a3da& i : eff->a3da) - pvpp_a3da_read(&i, s); - s.position_pop(); + s.position_push(auth_3ds_offset, SEEK_SET); + for (pvpp_auth_3d& i : eff->auth_3d) + pvpp_auth_3d_read(&i, s); + s.position_pop(); + } - eff->glitter.resize(glitters_count); + if (glitters_offset) { + eff->glitter.resize(glitters_count); - s.position_push(glitters_offset, SEEK_SET); - for (pvpp_glitter& i : eff->glitter) - pvpp_glitter_read(&i, s); - s.position_pop(); + s.position_push(glitters_offset, SEEK_SET); + for (pvpp_glitter& i : eff->glitter) + pvpp_glitter_read(&i, s); + s.position_pop(); + } } static void pvpp_glitter_read(pvpp_glitter* glt, stream& s) { @@ -331,25 +350,31 @@ static void pvpp_read_inner(pvpp* pp, stream& s) { int64_t chara_offset = s_pvpp.read_offset_x(); s_pvpp.read_offset_x(); - pp->chara.resize(chara_count); + if (chara_offset) { + pp->chara.resize(chara_count); - s_pvpp.position_push(chara_offset, SEEK_SET); - for (pvpp_chara& i : pp->chara) - pvpp_chara_read(&i, s_pvpp); - s_pvpp.position_pop(); + s_pvpp.position_push(chara_offset, SEEK_SET); + for (pvpp_chara& i : pp->chara) + pvpp_chara_read(&i, s_pvpp); + s_pvpp.position_pop(); + } - s_pvpp.position_push( effect_offset, SEEK_SET); - s_pvpp.read_uint8_t(); - int8_t efffect_count = s_pvpp.read_int8_t(); - effect_offset = s_pvpp.read_offset_x(); - s_pvpp.position_pop(); + if (effect_offset) { + s_pvpp.position_push(effect_offset, SEEK_SET); + s_pvpp.read_uint8_t(); + int8_t efffect_count = s_pvpp.read_int8_t(); + int64_t effect_offset = s_pvpp.read_offset_x(); + s_pvpp.position_pop(); - pp->effect.resize(efffect_count); + if (effect_offset) { + pp->effect.resize(efffect_count); - s_pvpp.position_push(effect_offset, SEEK_SET); - for (pvpp_effect& i : pp->effect) - pvpp_effect_read(&i, s_pvpp); - s_pvpp.position_pop(); + s_pvpp.position_push(effect_offset, SEEK_SET); + for (pvpp_effect& i : pp->effect) + pvpp_effect_read(&i, s_pvpp); + s_pvpp.position_pop(); + } + } pp->ready = true; } diff --git a/src/KKdLib/pvpp.hpp b/src/KKdLib/pvpp.hpp index 17789e5c..259ebe5e 100644 --- a/src/KKdLib/pvpp.hpp +++ b/src/KKdLib/pvpp.hpp @@ -10,34 +10,35 @@ #include "default.hpp" #include "vec.hpp" -enum pvpp_chara_index { - PVPP_CHARA_1P = 0, - PVPP_CHARA_2P = 1, - PVPP_CHARA_3P = 2, - PVPP_CHARA_4P = 3, +enum pvpp_chara_id : uint8_t { + PVPP_CHARA_1P = 0x00, + PVPP_CHARA_2P = 0x01, + PVPP_CHARA_3P = 0x02, + PVPP_CHARA_4P = 0x03, + PVPP_CHARA_PNONE = 0xFF, }; -enum pvpp_chara_type { - PVPP_CHARA_MIKU = 0, - PVPP_CHARA_RIN = 1, - PVPP_CHARA_LEN = 2, - PVPP_CHARA_LUKA = 3, - PVPP_CHARA_NERU = 4, - PVPP_CHARA_HAKU = 5, - PVPP_CHARA_KAITO = 6, - PVPP_CHARA_MEIKO = 7, - PVPP_CHARA_SAKINE = 8, - PVPP_CHARA_TETO = 9, - PVPP_CHARA_EXTRA = 10, - PVPP_CHARA_STAGE = 255, +enum pvpp_chara_index : uint8_t { + PVPP_CHARA_MIKU = 0x00, + PVPP_CHARA_RIN = 0x01, + PVPP_CHARA_LEN = 0x02, + PVPP_CHARA_LUKA = 0x03, + PVPP_CHARA_NERU = 0x04, + PVPP_CHARA_HAKU = 0x05, + PVPP_CHARA_KAITO = 0x06, + PVPP_CHARA_MEIKO = 0x07, + PVPP_CHARA_SAKINE = 0x08, + PVPP_CHARA_TETO = 0x09, + PVPP_CHARA_EXTRA = 0x0A, + PVPP_CHARA_NONE = 0xFF, }; -struct pvpp_a3da { +struct pvpp_auth_3d { uint32_t hash; std::string name; - pvpp_a3da(); - ~pvpp_a3da(); + pvpp_auth_3d(); + ~pvpp_auth_3d(); }; struct pvpp_object_set { @@ -48,8 +49,8 @@ struct pvpp_object_set { ~pvpp_object_set(); }; -struct pvpp_chara_effect_a3da { - pvpp_a3da a3da; +struct pvpp_chara_effect_auth_3d { + pvpp_auth_3d auth_3d; pvpp_object_set object_set; bool has_object_set; uint8_t u00; @@ -61,23 +62,23 @@ struct pvpp_chara_effect_a3da { uint8_t u06; uint8_t u07; - pvpp_chara_effect_a3da(); - ~pvpp_chara_effect_a3da(); + pvpp_chara_effect_auth_3d(); + ~pvpp_chara_effect_auth_3d(); }; struct pvpp_chara_effect { - pvpp_chara_type base_chara; - pvpp_chara_index chara_index; - std::vector effect_a3da; + pvpp_chara_index base_chara; + pvpp_chara_id chara_id; + std::vector effect_auth_3d; pvpp_chara_effect(); ~pvpp_chara_effect(); }; struct pvpp_chara_item { - std::vector a3da; + std::vector auth_3d; std::string bone; - vec4u u18; + vec4 u18; pvpp_chara_item(); ~pvpp_chara_item(); @@ -101,8 +102,8 @@ struct pvpp_motion { }; struct pvpp_effect { - std::vector a3da; - pvpp_chara_type chara_index; + std::vector auth_3d; + pvpp_chara_id chara_id; std::vector glitter; pvpp_effect(); @@ -110,7 +111,7 @@ struct pvpp_effect { }; struct pvpp_chara { - std::vector a3da; + std::vector auth_3d; std::vector item; pvpp_chara_effect chara_effect; bool chara_effect_init; diff --git a/src/KKdLib/pvsr.cpp b/src/KKdLib/pvsr.cpp index c0da8313..be072db5 100644 --- a/src/KKdLib/pvsr.cpp +++ b/src/KKdLib/pvsr.cpp @@ -10,17 +10,85 @@ #include "hash.hpp" #include "str_utils.hpp" -static void pvsr_a3da_read(pvsr_a3da* a3d, stream& s); -static void pvsr_aet_read(pvsr_aet* aet_entry, stream& s); +static void pvsr_auth_3d_read(pvsr_auth_3d* a3d, stream& s); +static void pvsr_auth_2d_read(pvsr_auth_2d* aet_entry, stream& s); static void pvsr_effect_read(pvsr_effect* eff, stream& s); static void pvsr_glitter_read(pvsr_glitter* glt, stream& s); static void pvsr_read_inner(pvsr* sr, stream& s); +static void pvsr_stage_change_effect_read(pvsr_stage_change_effect* stg_chg_eff, stream& s); static void pvsr_stage_effect_read(pvsr_stage_effect* stg_eff, stream& s); static void pvsr_stage_effect_env_read(pvsr_stage_effect_env* aet, stream& s, int32_t x00); static bool pvsr_stage_effect_env_sub1_read(pvsr_stage_effect_env_sub1* aet_sub1, stream& s, int64_t offset); static bool pvsr_stage_effect_env_sub2_read(pvsr_stage_effect_env_sub2* aet_sub2, stream& s, int64_t offset); -pvsr::pvsr() : ready(), stage_change_effect_init() { +pvsr_auth_2d::pvsr_auth_2d() { + bright_scale = 1.0f; + hash = hash_murmurhash_empty; +} + +pvsr_auth_2d::~pvsr_auth_2d() { + +} + +pvsr_auth_3d::pvsr_auth_3d() : hash(hash_murmurhash_empty), flags() { + +} + +pvsr_auth_3d::~pvsr_auth_3d() { + +} + +pvsr_effect::pvsr_effect() { + emission = 1.0f; +} + +pvsr_effect::~pvsr_effect() { + +} + +pvsr_glitter::pvsr_glitter() : unk1(), flags() { + +} + +pvsr_glitter::~pvsr_glitter() { + +} + +pvsr_stage_change_effect::pvsr_stage_change_effect() : enable(), bar_count() { + +} + +pvsr_stage_change_effect::~pvsr_stage_change_effect() { + +} + +pvsr_stage_effect::pvsr_stage_effect() { + +} + +pvsr_stage_effect::~pvsr_stage_effect() { + +} + +pvsr_stage_effect_env_sub1::pvsr_stage_effect_env_sub1() : stage_light() { + hash = hash_murmurhash_empty; +} + +pvsr_stage_effect_env_sub1::~pvsr_stage_effect_env_sub1() { + +} + +pvsr_stage_effect_env::pvsr_stage_effect_env() : u48(), u4a(), u4c(), u4e(), u50(), u52(), u54(), u56(), u58(), u5a(), +u5c(), u5e(), u60(), sub1_data(), sub1_data_init(), sub2a_data(), sub2a_data_init(), +sub2b_data(), sub2b_data_init(), sub2c_data(), sub2c_data_init(), sub2d_data(), sub2d_data_init() { + +} + +pvsr_stage_effect_env::~pvsr_stage_effect_env() { + +} + +pvsr::pvsr() : ready() { } @@ -71,76 +139,19 @@ bool pvsr::load_file(void* data, const char* path, const char* file, uint32_t ha return sr->ready; } -pvsr_a3da::pvsr_a3da() : hash(hash_murmurhash_empty) { - -} - -pvsr_a3da::~pvsr_a3da() { - -} - -pvsr_aet::pvsr_aet() : bright_scale(1.0f), hash(hash_murmurhash_empty) { - -} - -pvsr_aet::~pvsr_aet() { - -} - -pvsr_effect::pvsr_effect() : emission(1.0f) { - -} - -pvsr_effect::~pvsr_effect() { - -} - -pvsr_glitter::pvsr_glitter() : unk1() { - -} - -pvsr_glitter::~pvsr_glitter() { - -} - -pvsr_stage_effect::pvsr_stage_effect() : bar_count() { - -} - -pvsr_stage_effect::~pvsr_stage_effect() { - -} - -pvsr_stage_effect_env_sub1::pvsr_stage_effect_env_sub1() : hash(hash_murmurhash_empty), unk2() { - -} - -pvsr_stage_effect_env_sub1::~pvsr_stage_effect_env_sub1() { - -} - -pvsr_stage_effect_env::pvsr_stage_effect_env() : u48(), u4a(), u4c(), u4e(), u50(), u52(), u54(), u56(), u58(), u5a(), -u5c(), u5e(), u60(), sub1_data(), sub1_data_init(), sub2a_data(), sub2a_data_init(), -sub2b_data(), sub2b_data_init(), sub2c_data(), sub2c_data_init(), sub2d_data(), sub2d_data_init() { - -} - -pvsr_stage_effect_env::~pvsr_stage_effect_env() { - -} - -static void pvsr_a3da_read(pvsr_a3da* a3d, stream& s) { - a3d->name = s.read_string_null_terminated_offset(s.read_offset_x()); - a3d->hash = s.read_uint32_t_reverse_endianness(); - s.align_read(0x08); -} - -static void pvsr_aet_read(pvsr_aet* aet_entry, stream& s) { +static void pvsr_auth_2d_read(pvsr_auth_2d* aet_entry, stream& s) { aet_entry->name = s.read_string_null_terminated_offset(s.read_offset_x()); aet_entry->hash = s.read_uint32_t_reverse_endianness(); aet_entry->bright_scale = s.read_float_t_reverse_endianness(); } +static void pvsr_auth_3d_read(pvsr_auth_3d* a3d, stream& s) { + a3d->name = s.read_string_null_terminated_offset(s.read_offset_x()); + a3d->hash = s.read_uint32_t_reverse_endianness(); + a3d->flags = (pvsr_auth_3d_flags)s.read_uint8_t(); + s.align_read(0x08); +} + static void pvsr_effect_read(pvsr_effect* eff, stream& s) { eff->name = s.read_string_null_terminated_offset(s.read_offset_x()); eff->emission = s.read_float_t_reverse_endianness(); @@ -149,7 +160,8 @@ static void pvsr_effect_read(pvsr_effect* eff, stream& s) { static void pvsr_glitter_read(pvsr_glitter* glt, stream& s) { glt->name = s.read_string_null_terminated_offset(s.read_offset_x()); - glt->unk1 = s.read_uint8_t(); + glt->unk1 = s.read_int8_t(); + glt->flags = (pvsr_glitter_flags)s.read_uint8_t(); s.align_read(0x08); } @@ -181,105 +193,156 @@ static void pvsr_read_inner(pvsr* sr, stream& s) { int64_t stage_change_effect_offset = s_pvsr.read_offset_x(); int64_t stage_effect_env_offset = s_pvsr.read_offset_x(); - s_pvsr.position_push(x10, SEEK_SET); - int8_t unknown_count = s_pvsr.read_int8_t(); - int8_t effect_count = s_pvsr.read_int8_t(); - int8_t emcs_count = s_pvsr.read_int8_t(); - int64_t unknown_offset = s_pvsr.read_offset_x(); - int64_t effect_offset = s_pvsr.read_offset_x(); - int64_t emcs_offset = s_pvsr.read_offset_x(); - s_pvsr.position_pop(); + int8_t unknown_count = 0; + int8_t effect_count = 0; + int8_t emcs_count = 0; + int64_t unknown_offset = 0; + int64_t effect_offset = 0; + int64_t emcs_offset = 0; + if (x10) { + s_pvsr.position_push(x10, SEEK_SET); + unknown_count = s_pvsr.read_int8_t(); + effect_count = s_pvsr.read_int8_t(); + emcs_count = s_pvsr.read_int8_t(); + unknown_offset = s_pvsr.read_offset_x(); + effect_offset = s_pvsr.read_offset_x(); + emcs_offset = s_pvsr.read_offset_x(); + s_pvsr.position_pop(); + } - sr->effect.resize(effect_count); + if (effect_offset > 0) { + sr->effect.resize(effect_count); - s_pvsr.position_push(effect_offset, SEEK_SET); - for (pvsr_effect& i : sr->effect) - pvsr_effect_read(&i, s_pvsr); - s_pvsr.position_pop(); + s_pvsr.position_push(effect_offset, SEEK_SET); + for (pvsr_effect& i : sr->effect) + pvsr_effect_read(&i, s_pvsr); + s_pvsr.position_pop(); + } - sr->emcs.resize(emcs_count); + if (emcs_offset > 0) { + sr->emcs.resize(emcs_count); - s_pvsr.position_push(emcs_offset, SEEK_SET); - for (std::string& i : sr->emcs) - i = s_pvsr.read_string_null_terminated_offset(s_pvsr.read_offset_x()); - s_pvsr.position_pop(); + s_pvsr.position_push(emcs_offset, SEEK_SET); + for (std::string& i : sr->emcs) + i = s_pvsr.read_string_null_terminated_offset(s_pvsr.read_offset_x()); + s_pvsr.position_pop(); + } - sr->stage_effect.resize(stage_effect_count); + if (stage_effect_offset > 0) { + sr->stage_effect.resize(stage_effect_count); - s_pvsr.position_push(stage_effect_offset, SEEK_SET); - for (pvsr_stage_effect& i : sr->stage_effect) - pvsr_stage_effect_read(&i, s_pvsr); - s_pvsr.position_pop(); + s_pvsr.position_push(stage_effect_offset, SEEK_SET); + for (pvsr_stage_effect& i : sr->stage_effect) + pvsr_stage_effect_read(&i, s_pvsr); + s_pvsr.position_pop(); + } for (int32_t i = 0; i < PVSR_STAGE_CHANGE_EFFECT_COUNT; i++) for (int32_t j = 0; j < PVSR_STAGE_CHANGE_EFFECT_COUNT; j++) - sr->stage_change_effect_init[i][j] = false; + sr->stage_change_effect[i][j].enable = false; - s_pvsr.position_push(stage_change_effect_offset, SEEK_SET); - for (int32_t i = 0; i < PVSR_STAGE_CHANGE_EFFECT_COUNT; i++) - for (int32_t j = 0; j < PVSR_STAGE_CHANGE_EFFECT_COUNT; j++) { - int64_t offset = s_pvsr.read_offset_x(); - if (offset <= 0) - continue; + if (stage_change_effect_offset > 0) { + s_pvsr.position_push(stage_change_effect_offset, SEEK_SET); + for (int32_t i = 0; i < PVSR_STAGE_CHANGE_EFFECT_COUNT; i++) + for (int32_t j = 0; j < PVSR_STAGE_CHANGE_EFFECT_COUNT; j++) { + int64_t offset = s_pvsr.read_offset_x(); + if (offset <= 0) + continue; - s_pvsr.position_push(offset, SEEK_SET); - pvsr_stage_effect_read(&sr->stage_change_effect[i][j], s_pvsr); - sr->stage_change_effect_init[i][j] = true; - s_pvsr.position_pop(); - } - s_pvsr.position_pop(); + s_pvsr.position_push(offset, SEEK_SET); + pvsr_stage_change_effect_read(&sr->stage_change_effect[i][j], s_pvsr); + s_pvsr.position_pop(); + } + s_pvsr.position_pop(); + } - sr->stage_effect_env.resize(stage_effect_envs_count); + if (stage_effect_env_offset > 0) { + sr->stage_effect_env.resize(stage_effect_envs_count); - s_pvsr.position_push(stage_effect_env_offset, SEEK_SET); - for (pvsr_stage_effect_env& i : sr->stage_effect_env) - pvsr_stage_effect_env_read(&i, s_pvsr, x00); - s_pvsr.position_pop(); + s_pvsr.position_push(stage_effect_env_offset, SEEK_SET); + for (pvsr_stage_effect_env& i : sr->stage_effect_env) + pvsr_stage_effect_env_read(&i, s_pvsr, x00); + s_pvsr.position_pop(); + } sr->ready = true; } -static void pvsr_stage_effect_read(pvsr_stage_effect* stg_eff, stream& s) { - uint8_t u00 = s.read_uint8_t(); - uint8_t u01 = s.read_uint8_t(); - uint8_t u02 = s.read_uint8_t(); - uint8_t u03 = s.read_uint8_t(); - stg_eff->bar_count = s.read_uint8_t(); - int64_t a3da_offset = s.read_offset_x(); +static void pvsr_stage_change_effect_read(pvsr_stage_change_effect* stg_chg_eff, stream& s) { + int8_t enable = s.read_int8_t(); + int8_t auth_3d_count = s.read_int8_t(); + int8_t glitter_count = s.read_int8_t(); + int8_t u03 = s.read_int8_t(); + int8_t bar_count = s.read_int8_t(); + int64_t auth_3d_offset = s.read_offset_x(); int64_t glitter_offset = s.read_offset_x(); s.read_offset_x(); - uint8_t a3da_count; - uint8_t glitter_count; - if (stg_eff->bar_count != 0xFF) { - a3da_count = u00; - glitter_count = u01; - } - else { - a3da_count = u01; - glitter_count = u02; + if (!enable) { + stg_chg_eff->enable = false; + return; } - stg_eff->a3da.resize(a3da_count); + stg_chg_eff->enable = true; - s.position_push(a3da_offset, SEEK_SET); - for (pvsr_a3da& i : stg_eff->a3da) - pvsr_a3da_read(&i, s); - s.position_pop(); + if (bar_count > 0) + stg_chg_eff->bar_count = bar_count; + else + stg_chg_eff->bar_count = 0; - stg_eff->glitter.resize(glitter_count); + if (auth_3d_offset > 0) { + stg_chg_eff->auth_3d.resize(auth_3d_count); - s.position_push(glitter_offset, SEEK_SET); - for (pvsr_glitter& i : stg_eff->glitter) - pvsr_glitter_read(&i, s); - s.position_pop(); + s.position_push(auth_3d_offset, SEEK_SET); + for (pvsr_auth_3d& i : stg_chg_eff->auth_3d) + pvsr_auth_3d_read(&i, s); + s.position_pop(); + } + + if (glitter_offset > 0) { + stg_chg_eff->glitter.resize(glitter_count); + + s.position_push(glitter_offset, SEEK_SET); + for (pvsr_glitter& i : stg_chg_eff->glitter) + pvsr_glitter_read(&i, s); + s.position_pop(); + } +} + +static void pvsr_stage_effect_read(pvsr_stage_effect* stg_eff, stream& s) { + int8_t auth_3d_count = s.read_int8_t(); + int8_t glitter_count = s.read_int8_t(); + int8_t u02 = s.read_int8_t(); + int8_t u03 = s.read_int8_t(); + int8_t u04 = s.read_int8_t(); + int64_t auth_3d_offset = s.read_offset_x(); + int64_t glitter_offset = s.read_offset_x(); + s.read_offset_x(); + + if (auth_3d_offset > 0) { + stg_eff->auth_3d.resize(auth_3d_count); + + s.position_push(auth_3d_offset, SEEK_SET); + for (pvsr_auth_3d& i : stg_eff->auth_3d) + pvsr_auth_3d_read(&i, s); + s.position_pop(); + } + + if (glitter_offset > 0) { + stg_eff->glitter.resize(glitter_count); + + s.position_push(glitter_offset, SEEK_SET); + for (pvsr_glitter& i : stg_eff->glitter) + pvsr_glitter_read(&i, s); + s.position_pop(); + } } static void pvsr_stage_effect_env_read(pvsr_stage_effect_env* aet, stream& s, int32_t x00) { int64_t set_name_offset = s.read_offset_x(); - int64_t front_offset = s.read_offset_x(); - int64_t front_low_offset = s.read_offset_x(); - int64_t back_offset = s.read_offset_x(); + int64_t aet_front_offset = s.read_offset_x(); + int64_t aet_front_low_offset = s.read_offset_x(); + int64_t aet_back_offset = s.read_offset_x(); int64_t sub1_offset = s.read_offset_x(); int64_t sub2a_offset = s.read_offset_x(); int64_t sub2b_offset = s.read_offset_x(); @@ -298,9 +361,9 @@ static void pvsr_stage_effect_env_read(pvsr_stage_effect_env* aet, stream& s, in aet->u5c = s.read_uint16_t_reverse_endianness(); aet->u5e = s.read_uint16_t_reverse_endianness(); aet->u60 = s.read_uint16_t_reverse_endianness(); - int8_t front_count = s.read_int8_t(); - int8_t front_low_count = s.read_int8_t(); - int8_t back_count = s.read_int8_t(); + int8_t aet_front_count = s.read_int8_t(); + int8_t aet_front_low_count = s.read_int8_t(); + int8_t aet_back_count = s.read_int8_t(); s.align_read(0x08); int64_t o68 = 0; int64_t o70 = 0; @@ -316,26 +379,32 @@ static void pvsr_stage_effect_env_read(pvsr_stage_effect_env* aet, stream& s, in aet->set_name = s.read_string_null_terminated_offset(set_name_offset); - aet->aet_front.resize(front_count); + if (aet_front_offset > 0) { + aet->aet_front.resize(aet_front_count); - s.position_push(front_offset, SEEK_SET); - for (pvsr_aet& i : aet->aet_front) - pvsr_aet_read(&i, s); - s.position_pop(); + s.position_push(aet_front_offset, SEEK_SET); + for (pvsr_auth_2d& i : aet->aet_front) + pvsr_auth_2d_read(&i, s); + s.position_pop(); + } - aet->aet_front_low.resize(front_low_count); + if (aet_front_low_offset > 0) { + aet->aet_front_low.resize(aet_front_low_count); - s.position_push(front_low_offset, SEEK_SET); - for (pvsr_aet& i : aet->aet_front_low) - pvsr_aet_read(&i, s); - s.position_pop(); + s.position_push(aet_front_low_offset, SEEK_SET); + for (pvsr_auth_2d& i : aet->aet_front_low) + pvsr_auth_2d_read(&i, s); + s.position_pop(); + } - aet->aet_back.resize(back_count); + if (aet_back_offset > 0) { + aet->aet_back.resize(aet_back_count); - s.position_push(back_offset, SEEK_SET); - for (pvsr_aet& i : aet->aet_back) - pvsr_aet_read(&i, s); - s.position_pop(); + s.position_push(aet_back_offset, SEEK_SET); + for (pvsr_auth_2d& i : aet->aet_back) + pvsr_auth_2d_read(&i, s); + s.position_pop(); + } aet->sub1_data_init = pvsr_stage_effect_env_sub1_read(&aet->sub1_data, s, sub1_offset); aet->sub2a_data_init = pvsr_stage_effect_env_sub2_read(&aet->sub2a_data, s, sub2a_offset); @@ -344,19 +413,23 @@ static void pvsr_stage_effect_env_read(pvsr_stage_effect_env* aet, stream& s, in aet->sub2d_data_init = pvsr_stage_effect_env_sub2_read(&aet->sub2d_data, s, sub2d_offset); if (x00 & 0x100) { - aet->unk03.resize(u78); + if (aet_back_offset > 0) { + aet->unk03.resize(u78); - s.position_push(o68, SEEK_SET); - for (pvsr_aet& i : aet->unk03) - pvsr_aet_read(&i, s); - s.position_pop(); + s.position_push(o68, SEEK_SET); + for (pvsr_auth_2d& i : aet->unk03) + pvsr_auth_2d_read(&i, s); + s.position_pop(); + } - aet->unk04.resize(u79); + if (o70 > 0) { + aet->unk04.resize(u79); - s.position_push(o70, SEEK_SET); - for (pvsr_aet& i : aet->unk04) - pvsr_aet_read(&i, s); - s.position_pop(); + s.position_push(o70, SEEK_SET); + for (pvsr_auth_2d& i : aet->unk04) + pvsr_auth_2d_read(&i, s); + s.position_pop(); + } } } @@ -367,7 +440,7 @@ static bool pvsr_stage_effect_env_sub1_read(pvsr_stage_effect_env_sub1* aet_sub1 s.position_push(offset, SEEK_SET); aet_sub1->name = s.read_string_null_terminated_offset(s.read_offset_x()); aet_sub1->hash = s.read_uint32_t_reverse_endianness(); - aet_sub1->unk2 = s.read_uint16_t_reverse_endianness(); + aet_sub1->stage_light = s.read_uint16_t_reverse_endianness(); s.align_read(0x08); s.position_pop(); return true; diff --git a/src/KKdLib/pvsr.hpp b/src/KKdLib/pvsr.hpp index 0114c2df..6bc30940 100644 --- a/src/KKdLib/pvsr.hpp +++ b/src/KKdLib/pvsr.hpp @@ -9,21 +9,33 @@ #include #include "default.hpp" -struct pvsr_a3da { - std::string name; - uint32_t hash; - - pvsr_a3da(); - ~pvsr_a3da(); +enum pvsr_auth_3d_flags : uint8_t { + PVSR_AUTH_3D_FINAL = 0x01, + PVSR_AUTH_3D_MOVIE_TEXTURE = 0x02, + PVSR_AUTH_3D_RENDER_TEXTURE = 0x04, + PVSR_AUTH_3D_MAIN = 0x08, }; -struct pvsr_aet { +enum pvsr_glitter_flags : uint8_t { + PVSR_GLITTER_FORCE_DISP = 0x01, +}; + +struct pvsr_auth_2d { std::string name; std::uint32_t hash; float_t bright_scale; - pvsr_aet(); - ~pvsr_aet(); + pvsr_auth_2d(); + ~pvsr_auth_2d(); +}; + +struct pvsr_auth_3d { + std::string name; + uint32_t hash; + pvsr_auth_3d_flags flags; + + pvsr_auth_3d(); + ~pvsr_auth_3d(); }; struct pvsr_effect { @@ -36,15 +48,25 @@ struct pvsr_effect { struct pvsr_glitter { std::string name; - uint8_t unk1; + int8_t unk1; + pvsr_glitter_flags flags; pvsr_glitter(); ~pvsr_glitter(); }; +struct pvsr_stage_change_effect { + bool enable; + int8_t bar_count; + std::vector auth_3d; + std::vector glitter; + + pvsr_stage_change_effect(); + ~pvsr_stage_change_effect(); +}; + struct pvsr_stage_effect { - uint8_t bar_count; - std::vector a3da; + std::vector auth_3d; std::vector glitter; pvsr_stage_effect(); @@ -54,7 +76,7 @@ struct pvsr_stage_effect { struct pvsr_stage_effect_env_sub1 { std::string name; uint32_t hash; - uint16_t unk2; + uint16_t stage_light; pvsr_stage_effect_env_sub1(); ~pvsr_stage_effect_env_sub1(); @@ -86,9 +108,9 @@ struct pvsr_stage_effect_env { uint16_t u60; std::string set_name; - std::vector aet_front; - std::vector aet_front_low; - std::vector aet_back; + std::vector aet_front; + std::vector aet_front_low; + std::vector aet_back; pvsr_stage_effect_env_sub1 sub1_data; bool sub1_data_init; pvsr_stage_effect_env_sub2 sub2a_data; @@ -99,8 +121,8 @@ struct pvsr_stage_effect_env { bool sub2c_data_init; pvsr_stage_effect_env_sub2 sub2d_data; bool sub2d_data_init; - std::vector unk03; - std::vector unk04; + std::vector unk03; + std::vector unk04; pvsr_stage_effect_env(); ~pvsr_stage_effect_env(); @@ -113,8 +135,7 @@ struct pvsr { std::vector effect; std::vector emcs; - pvsr_stage_effect stage_change_effect[PVSR_STAGE_CHANGE_EFFECT_COUNT][PVSR_STAGE_CHANGE_EFFECT_COUNT]; - bool stage_change_effect_init[PVSR_STAGE_CHANGE_EFFECT_COUNT][PVSR_STAGE_CHANGE_EFFECT_COUNT]; + pvsr_stage_change_effect stage_change_effect[PVSR_STAGE_CHANGE_EFFECT_COUNT][PVSR_STAGE_CHANGE_EFFECT_COUNT]; std::vector stage_effect; std::vector stage_effect_env; diff --git a/src/KKdLib/quat.cpp b/src/KKdLib/quat.cpp index 3e51cc4e..8b1c532f 100644 --- a/src/KKdLib/quat.cpp +++ b/src/KKdLib/quat.cpp @@ -114,7 +114,7 @@ void quat_from_mat3(float_t m00, float_t m01, float_t m02, float_t m10, } } -void quat_from_axis_angle(const vec3* axis, const float_t angle, quat* quat) { +inline void quat_from_axis_angle(const vec3* axis, const float_t angle, quat* quat) { float_t angle_sin; float_t angle_cos; vec3 _axis; diff --git a/src/KKdLib/quat_trans.c b/src/KKdLib/quat_trans.cpp similarity index 90% rename from src/KKdLib/quat_trans.c rename to src/KKdLib/quat_trans.cpp index e4d46d0c..80227df4 100644 --- a/src/KKdLib/quat_trans.c +++ b/src/KKdLib/quat_trans.cpp @@ -3,8 +3,7 @@ GitHub/GitLab: korenkonder */ -#include "math.h" -#include "quat_trans.h" +#include "quat_trans.hpp" void lerp_quat_trans(quat_trans* x, quat_trans* y, quat_trans* z, float_t blend) { if (blend > 1.0f) diff --git a/src/KKdLib/quat_trans.h b/src/KKdLib/quat_trans.hpp similarity index 100% rename from src/KKdLib/quat_trans.h rename to src/KKdLib/quat_trans.hpp diff --git a/src/KKdLib/sound/diva.cpp b/src/KKdLib/sound/diva.cpp index 13402ae5..4d600a6b 100644 --- a/src/KKdLib/sound/diva.cpp +++ b/src/KKdLib/sound/diva.cpp @@ -8,6 +8,12 @@ #include "../io/stream.hpp" #include "../str_utils.hpp" +struct ima_storage { + int32_t step_index; + int32_t current; + int32_t current_clamp; +}; + static const int8_t ima_index_table[] = { -1, -1, -1, -1, 2, 4, 6, 8, }; @@ -29,8 +35,8 @@ static const int16_t ima_step_table[] = { static void diva_read_wav(diva* d, const wchar_t* path, float_t** data); static void diva_write_wav(diva* d, const wchar_t* path, float_t* data); -static void ima_decode(uint8_t value, int32_t* current, int32_t* current_clamp, int8_t* step_index); -static uint8_t ima_encode(int32_t sample, int32_t* current, int32_t* current_clamp, int8_t* step_index); +static void ima_decode(uint8_t value, ima_storage* storage); +static uint8_t ima_encode(int32_t sample, ima_storage* storage); diva* diva_init() { diva* d = force_malloc_s(diva, 1); @@ -68,9 +74,7 @@ void diva_read(diva* d, const wchar_t* path) { size_t samples_count = d->samples_count; float_t* data = force_malloc_s(float_t, samples_count * ch); - int32_t* current = force_malloc_s(int32_t, ch); - int32_t* current_clamp = force_malloc_s(int32_t, ch); - int8_t* step_index = force_malloc_s(int8_t, ch); + ima_storage* storage = force_malloc_s(ima_storage, ch); float_t* temp_data = data; for (size_t i = 0; i < samples_count; i++) @@ -79,12 +83,10 @@ void diva_read(diva* d, const wchar_t* path) { value = s.read_uint8_t(); nibble = (current_sample & 1 ? value : value >> 4) & 0x0F; - ima_decode(nibble, current + c, current_clamp + c, step_index + c); - *temp_data++ = (float_t)(current[c] / 32768.0); + ima_decode(nibble, &storage[c]); + *temp_data++ = (float_t)(storage[c].current / 32768.0); } - free(step_index); - free(current_clamp); - free(current); + free(storage); diva_write_wav(d, path, data); free(data); @@ -129,15 +131,12 @@ void diva_write(diva* d, const wchar_t* path) { size_t ch = d->channels; size_t samples_count = d->samples_count; - int32_t* current = force_malloc_s(int32_t, ch); - int32_t* current_clamp = force_malloc_s(int32_t, ch); - int8_t* step_index = force_malloc_s(int8_t, ch); + ima_storage* storage = force_malloc_s(ima_storage, ch); float_t* temp_data = data; for (size_t i = 0; i < samples_count; i++) for (size_t c = 0; c < ch; c++, current_sample++) { - nibble = ima_encode((int32_t)round(*temp_data++ * 32768.0), - current + c, current_clamp + c, step_index + c); + nibble = ima_encode((int32_t)round(*temp_data++ * 32768.0), &storage[c]); value |= current_sample & 1 ? nibble : nibble << 4; if (current_sample & 1) { s.write_uint8_t(value); @@ -147,9 +146,7 @@ void diva_write(diva* d, const wchar_t* path) { if (current_sample & 1) s.write_uint8_t(value); - free(step_index); - free(current_clamp); - free(current); + free(storage); } free(path_diva); free(data); @@ -184,10 +181,10 @@ static void diva_write_wav(diva* d, const wchar_t* path, float_t* data) { free(path_av); } -static void ima_decode(uint8_t value, int32_t* current, int32_t* current_clamp, int8_t* step_index) { - int32_t c = *current; - int32_t cc = *current_clamp; - int32_t si = *step_index; +static void ima_decode(uint8_t value, ima_storage* storage) { + int32_t c = storage->current; + int32_t cc = storage->current_clamp; + int32_t si = storage->step_index; int16_t step = ima_step_table[si]; int32_t diff = step >> 3; @@ -213,15 +210,15 @@ static void ima_decode(uint8_t value, int32_t* current, int32_t* current_clamp, si = 0; if (si > 88) si = 88; - *current = c; - *current_clamp = cc; - *step_index = si; + storage->current = c; + storage->current_clamp = cc; + storage->step_index = si; } -static uint8_t ima_encode(int32_t sample, int32_t* current, int32_t* current_clamp, int8_t* step_index) { - int32_t c = *current; - int32_t cc = *current_clamp; - int32_t si = *step_index; +static uint8_t ima_encode(int32_t sample, ima_storage* storage) { + int32_t c = storage->current; + int32_t cc = storage->current_clamp; + int32_t si = storage->step_index; uint8_t value = 0; int16_t step = ima_step_table[si]; @@ -270,8 +267,8 @@ static uint8_t ima_encode(int32_t sample, int32_t* current, int32_t* current_cla si = 0; if (si > 88) si = 88; - *current = c; - *current_clamp = cc; - *step_index = si; + storage->current = c; + storage->current_clamp = cc; + storage->step_index = si; return value; } diff --git a/src/KKdLib/vec.cpp b/src/KKdLib/vec.cpp index c69f0bb5..f79c05ec 100644 --- a/src/KKdLib/vec.cpp +++ b/src/KKdLib/vec.cpp @@ -26,16 +26,6 @@ const vec2i vec2i_null = { 0, 0 }; const vec3i vec3i_null = { 0, 0, 0 }; const vec4i vec4i_null = { 0, 0, 0, 0 }; -const vec2d vec2d_identity = { 1.0f, 1.0f }; - -const vec2d vec2d_null = { 0.0f, 0.0f }; - -const vec4u vec4u_identity = { 1.0f, 1.0f, 1.0f, 1.0f }; - -const vec4u vec4u_null = { 0.0f, 0.0f, 0.0f, 0.0f }; - -const vec4iu vec4iu_null = { 0, 0, 0, 0 }; - vec2i8::vec2i8() : x(), y() { } @@ -287,55 +277,3 @@ vec4i::vec4i(int32_t value) : x(value), y(value), z(value), w(value) { vec4i::vec4i(int32_t x, int32_t y, int32_t z, int32_t w) : x(x), y(y), z(z), w(w) { } - -vec2d::vec2d() : x(), y() { - -} - -vec2d::vec2d(double_t value) : x(value), y(value) { - -} - -vec2d::vec2d(double_t x, double_t y) : x(x), y(y) { - -} - -vec4u::vec4u() : x(), y(), z(), w() { - -} - -vec4u::vec4u(float_t value) : x(value), y(value), z(value), w(value) { - -} - -vec4u::vec4u(float_t x, float_t y, float_t z, float_t w) : x(x), y(y), z(z), w(w) { - -} - -vec4iu::vec4iu() : x(), y(), z(), w() { - -} - -vec4iu::vec4iu(int32_t value) : x(value), y(value), z(value), w(value) { - -} - -vec4iu::vec4iu(int32_t x, int32_t y, int32_t z, int32_t w) : x(x), y(y), z(z), w(w) { - -} - -vec4::operator vec4u() const { - return { x, y, z, w }; -} - -vec4u::operator vec4() const { - return { x, y, z, w }; -} - -vec4i::operator vec4iu() const { - return { x, y, z, w }; -} - -vec4iu::operator vec4i() const { - return { x, y, z, w }; -} diff --git a/src/KKdLib/vec.hpp b/src/KKdLib/vec.hpp index 53a1eded..49a91476 100644 --- a/src/KKdLib/vec.hpp +++ b/src/KKdLib/vec.hpp @@ -179,25 +179,15 @@ struct vec3 { vec3(float_t x, float_t y, float_t z); }; -union vec4; -union vec4i; -struct vec4u; -struct vec4iu; - -union vec4 { - struct { - float_t x; - float_t y; - float_t z; - float_t w; - }; - __m128 data; +struct vec4 { + float_t x; + float_t y; + float_t z; + float_t w; vec4(); vec4(float_t value); vec4(float_t x, float_t y, float_t z, float_t w); - - operator vec4u() const; }; struct vec2i { @@ -219,58 +209,15 @@ struct vec3i { vec3i(int32_t x, int32_t y, int32_t z); }; -union vec4i { - struct { - int32_t x; - int32_t y; - int32_t z; - int32_t w; - }; - __m128 data; - - vec4i(); - vec4i(int32_t value); - vec4i(int32_t x, int32_t y, int32_t z, int32_t w); - - operator vec4iu() const; -}; - -union vec2d { - struct { - double_t x; - double_t y; - }; - __m128d data; - - vec2d(); - vec2d(double_t value); - vec2d(double_t x, double_t y); -}; - -struct vec4u { - float_t x; - float_t y; - float_t z; - float_t w; - - vec4u(); - vec4u(float_t value); - vec4u(float_t x, float_t y, float_t z, float_t w); - - operator vec4() const; -}; - -struct vec4iu { +struct vec4i { int32_t x; int32_t y; int32_t z; int32_t w; - vec4iu(); - vec4iu(int32_t value); - vec4iu(int32_t x, int32_t y, int32_t z, int32_t w); - - operator vec4i() const; + vec4i(); + vec4i(int32_t value); + vec4i(int32_t x, int32_t y, int32_t z, int32_t w); }; extern const __m128 vec2_negate; @@ -293,17 +240,6 @@ extern const vec4 vec4_null; extern const vec2i vec2i_null; extern const vec3i vec3i_null; extern const vec4i vec4i_null; - -extern const vec2d vec2d_identity; - -extern const vec2d vec2d_null; - -extern const vec4u vec4u_identity; - -extern const vec4u vec4u_null; - -extern const vec4iu vec4iu_null; - #define vec2i8_to_vec2(src, dst) \ (dst).x = (float_t)(src).x; \ (dst).y = (float_t)(src).y; @@ -883,8 +819,8 @@ extern const vec4iu vec4iu_null; *(vec2*)&yt = (y); \ *(vec2*)&zt = (z); \ yt = _mm_xor_ps(yt, vec2_negate); \ - wt = _mm_or_ps(_mm_and_ps(yt, _mm_cmplt_ps(xt, vec4_null.data)), \ - _mm_and_ps(zt, _mm_cmpge_ps(xt, vec4_null.data))); \ + wt = _mm_or_ps(_mm_and_ps(yt, _mm_cmplt_ps(xt, _mm_loadu_ps((float*)&(vec4_null)))), \ + _mm_and_ps(zt, _mm_cmpge_ps(xt, _mm_loadu_ps((float*)&(vec4_null))))); \ wt = _mm_mul_ps(xt, wt); \ (w) = *(vec2*)&wt; \ } @@ -901,8 +837,8 @@ extern const vec4iu vec4iu_null; zt = _mm_set_ss(z); \ zt = _mm_shuffle_ps(zt, zt, 0); \ yt = _mm_xor_ps(yt, vec2_negate); \ - wt = _mm_or_ps(_mm_and_ps(yt, _mm_cmplt_ps(xt, vec4_null.data)), \ - _mm_and_ps(zt, _mm_cmpge_ps(xt, vec4_null.data))); \ + wt = _mm_or_ps(_mm_and_ps(yt, _mm_cmplt_ps(xt, _mm_loadu_ps((float*)&(vec4_null)))), \ + _mm_and_ps(zt, _mm_cmpge_ps(xt, _mm_loadu_ps((float*)&(vec4_null))))); \ wt = _mm_mul_ps(xt, wt); \ (w) = *(vec2*)&wt; \ } @@ -917,8 +853,8 @@ extern const vec4iu vec4iu_null; *(vec2*)&yt = (y); \ *(vec2*)&zt = (z); \ yt = _mm_xor_ps(yt, vec2_negate); \ - wt = _mm_or_ps(_mm_and_ps(yt, _mm_cmplt_ps(xt, vec4_null.data)), \ - _mm_and_ps(zt, _mm_cmpge_ps(xt, vec4_null.data))); \ + wt = _mm_or_ps(_mm_and_ps(yt, _mm_cmplt_ps(xt, _mm_loadu_ps((float*)&(vec4_null)))), \ + _mm_and_ps(zt, _mm_cmpge_ps(xt, _mm_loadu_ps((float*)&(vec4_null))))); \ wt = _mm_div_ps(xt, wt); \ (w) = *(vec2*)&wt; \ } @@ -935,8 +871,8 @@ extern const vec4iu vec4iu_null; zt = _mm_set_ss(z); \ zt = _mm_shuffle_ps(zt, zt, 0); \ yt = _mm_xor_ps(yt, vec2_negate); \ - wt = _mm_or_ps(_mm_and_ps(yt, _mm_cmplt_ps(xt, vec4_null.data)), \ - _mm_and_ps(zt, _mm_cmpge_ps(xt, vec4_null.data))); \ + wt = _mm_or_ps(_mm_and_ps(yt, _mm_cmplt_ps(xt, _mm_loadu_ps((float*)&(vec4_null)))), \ + _mm_and_ps(zt, _mm_cmpge_ps(xt, _mm_loadu_ps((float*)&(vec4_null))))); \ wt = _mm_div_ps(xt, wt); \ (w) = *(vec2*)&wt; \ } @@ -1088,9 +1024,9 @@ extern const vec4iu vec4iu_null; __m128 yt; \ __m128 zt; \ *(vec3*)&xt = (x); \ - xt = _mm_and_ps(xt, vec4_mask_vec3.data); \ + xt = _mm_and_ps(xt, _mm_loadu_ps((float*)&(vec4_mask_vec3))); \ *(vec3*)&yt = (y); \ - yt = _mm_and_ps(yt, vec4_mask_vec3.data); \ + yt = _mm_and_ps(yt, _mm_loadu_ps((float*)&(vec4_mask_vec3))); \ zt = _mm_mul_ps(xt, yt); \ zt = _mm_hadd_ps(zt, zt); \ (z) = _mm_cvtss_f32(_mm_hadd_ps(zt, zt)); \ @@ -1101,7 +1037,7 @@ extern const vec4iu vec4iu_null; __m128 xt; \ __m128 zt; \ *(vec3*)&xt = (x); \ - xt = _mm_and_ps(xt, vec4_mask_vec3.data); \ + xt = _mm_and_ps(xt, _mm_loadu_ps((float*)&(vec4_mask_vec3))); \ zt = _mm_mul_ps(xt, xt); \ zt = _mm_hadd_ps(zt, zt); \ (z) = _mm_cvtss_f32(_mm_sqrt_ss(_mm_hadd_ps(zt, zt))); \ @@ -1112,7 +1048,7 @@ extern const vec4iu vec4iu_null; __m128 xt; \ __m128 zt; \ *(vec3*)&xt = (x); \ - xt = _mm_and_ps(xt, vec4_mask_vec3.data); \ + xt = _mm_and_ps(xt, _mm_loadu_ps((float*)&(vec4_mask_vec3))); \ zt = _mm_mul_ps(xt, xt); \ zt = _mm_hadd_ps(zt, zt); \ (z) = _mm_cvtss_f32(_mm_hadd_ps(zt, zt)); \ @@ -1124,9 +1060,9 @@ extern const vec4iu vec4iu_null; __m128 yt; \ __m128 zt; \ *(vec3*)&xt = (x); \ - xt = _mm_and_ps(xt, vec4_mask_vec3.data); \ + xt = _mm_and_ps(xt, _mm_loadu_ps((float*)&(vec4_mask_vec3))); \ *(vec3*)&yt = (y); \ - yt = _mm_and_ps(yt, vec4_mask_vec3.data); \ + yt = _mm_and_ps(yt, _mm_loadu_ps((float*)&(vec4_mask_vec3))); \ zt = _mm_sub_ps(xt, yt); \ zt = _mm_mul_ps(zt, zt); \ zt = _mm_hadd_ps(zt, zt); \ @@ -1139,9 +1075,9 @@ extern const vec4iu vec4iu_null; __m128 yt; \ __m128 zt; \ *(vec3*)&xt = (x); \ - xt = _mm_and_ps(xt, vec4_mask_vec3.data); \ + xt = _mm_and_ps(xt, _mm_loadu_ps((float*)&(vec4_mask_vec3))); \ *(vec3*)&yt = (y); \ - yt = _mm_and_ps(yt, vec4_mask_vec3.data); \ + yt = _mm_and_ps(yt, _mm_loadu_ps((float*)&(vec4_mask_vec3))); \ zt = _mm_sub_ps(xt, yt); \ zt = _mm_mul_ps(zt, zt); \ zt = _mm_hadd_ps(zt, zt); \ @@ -1186,7 +1122,7 @@ extern const vec4iu vec4iu_null; __m128 xt; \ __m128 zt; \ *(vec3*)&xt = (x); \ - xt = _mm_and_ps(xt, vec4_mask_vec3.data); \ + xt = _mm_and_ps(xt, _mm_loadu_ps((float*)&(vec4_mask_vec3))); \ zt = _mm_mul_ps(xt, xt); \ zt = _mm_hadd_ps(zt, zt); \ zt = _mm_sqrt_ss(_mm_hadd_ps(zt, zt)); \ @@ -1265,8 +1201,8 @@ extern const vec4iu vec4iu_null; *(vec3*)&yt = (y); \ *(vec3*)&zt = (z); \ yt = _mm_xor_ps(yt, vec3_negate); \ - wt = _mm_or_ps(_mm_and_ps(yt, _mm_cmplt_ps(xt, vec4_null.data)), \ - _mm_and_ps(zt, _mm_cmpge_ps(xt, vec4_null.data))); \ + wt = _mm_or_ps(_mm_and_ps(yt, _mm_cmplt_ps(xt, _mm_loadu_ps((float*)&(vec4_null)))), \ + _mm_and_ps(zt, _mm_cmpge_ps(xt, _mm_loadu_ps((float*)&(vec4_null))))); \ wt = _mm_mul_ps(xt, wt); \ (w) = *(vec3*)&wt; \ } @@ -1283,8 +1219,8 @@ extern const vec4iu vec4iu_null; zt = _mm_set_ss(z); \ zt = _mm_shuffle_ps(zt, zt, 0); \ yt = _mm_xor_ps(yt, vec3_negate); \ - wt = _mm_or_ps(_mm_and_ps(yt, _mm_cmplt_ps(xt, vec4_null.data)), \ - _mm_and_ps(zt, _mm_cmpge_ps(xt, vec4_null.data))); \ + wt = _mm_or_ps(_mm_and_ps(yt, _mm_cmplt_ps(xt, _mm_loadu_ps((float*)&(vec4_null)))), \ + _mm_and_ps(zt, _mm_cmpge_ps(xt, _mm_loadu_ps((float*)&(vec4_null))))); \ wt = _mm_mul_ps(xt, wt); \ (w) = *(vec3*)&wt; \ } @@ -1299,8 +1235,8 @@ extern const vec4iu vec4iu_null; *(vec3*)&yt = (y); \ *(vec3*)&zt = (z); \ yt = _mm_xor_ps(yt, vec3_negate); \ - wt = _mm_or_ps(_mm_and_ps(yt, _mm_cmplt_ps(xt, vec4_null.data)), \ - _mm_and_ps(zt, _mm_cmpge_ps(xt, vec4_null.data))); \ + wt = _mm_or_ps(_mm_and_ps(yt, _mm_cmplt_ps(xt, _mm_loadu_ps((float*)&(vec4_null)))), \ + _mm_and_ps(zt, _mm_cmpge_ps(xt, _mm_loadu_ps((float*)&(vec4_null))))); \ wt = _mm_div_ps(xt, wt); \ (w) = *(vec3*)&wt; \ } @@ -1317,8 +1253,8 @@ extern const vec4iu vec4iu_null; zt = _mm_set_ss(z); \ zt = _mm_shuffle_ps(zt, zt, 0); \ yt = _mm_xor_ps(yt, vec3_negate); \ - wt = _mm_or_ps(_mm_and_ps(yt, _mm_cmplt_ps(xt, vec4_null.data)), \ - _mm_and_ps(zt, _mm_cmpge_ps(xt, vec4_null.data))); \ + wt = _mm_or_ps(_mm_and_ps(yt, _mm_cmplt_ps(xt, _mm_loadu_ps((float*)&(vec4_null)))), \ + _mm_and_ps(zt, _mm_cmpge_ps(xt, _mm_loadu_ps((float*)&(vec4_null))))); \ wt = _mm_div_ps(xt, wt); \ (w) = *(vec3*)&wt; \ } @@ -1340,85 +1276,85 @@ extern const vec4iu vec4iu_null; #define vec4_add(x, y, z) \ { \ - (z).data = _mm_add_ps((x).data, (y).data); \ + _mm_storeu_ps((float*)&(z), _mm_add_ps(_mm_loadu_ps((float*)&(x)), _mm_loadu_ps((float*)&(y)))); \ } #define vec4_add_scalar(x, y, z) \ { \ __m128 yt; \ yt = _mm_set_ss(y); \ - (z).data = _mm_add_ps((x).data, _mm_shuffle_ps(yt, yt, 0)); \ + _mm_storeu_ps((float*)&(z), _mm_add_ps(_mm_loadu_ps((float*)&(x)), _mm_shuffle_ps(yt, yt, 0))); \ } #define vec4_sub(x, y, z) \ { \ - (z).data = _mm_sub_ps((x).data, (y).data); \ + _mm_storeu_ps((float*)&(z), _mm_sub_ps(_mm_loadu_ps((float*)&(x)), _mm_loadu_ps((float*)&(y)))); \ } #define vec4_sub_scalar(x, y, z) \ { \ __m128 yt; \ yt = _mm_set_ss(y); \ - (z).data = _mm_sub_ps((x).data, _mm_shuffle_ps(yt, yt, 0)); \ + _mm_storeu_ps((float*)&(z), _mm_sub_ps(_mm_loadu_ps((float*)&(x)), _mm_shuffle_ps(yt, yt, 0))); \ } #define vec4_mult(x, y, z) \ { \ - (z).data = _mm_mul_ps((x).data, (y).data); \ + _mm_storeu_ps((float*)&(z), _mm_mul_ps(_mm_loadu_ps((float*)&(x)), _mm_loadu_ps((float*)&(y)))); \ } #define vec4_mult_scalar(x, y, z) \ { \ __m128 yt; \ yt = _mm_set_ss(y); \ - (z).data = _mm_mul_ps((x).data, _mm_shuffle_ps(yt, yt, 0)); \ + _mm_storeu_ps((float*)&(z), _mm_mul_ps(_mm_loadu_ps((float*)&(x)), _mm_shuffle_ps(yt, yt, 0))); \ } #define vec4_div(x, y, z) \ { \ - (z).data = _mm_div_ps((x).data, (y).data); \ + _mm_storeu_ps((float*)&(z), _mm_div_ps(_mm_loadu_ps((float*)&(x)), _mm_loadu_ps((float*)&(y)))); \ } #define vec4_div_scalar(x, y, z) \ { \ __m128 yt; \ yt = _mm_set_ss(y); \ - (z).data = _mm_div_ps((x).data, _mm_shuffle_ps(yt, yt, 0)); \ + _mm_storeu_ps((float*)&(z), _mm_div_ps(_mm_loadu_ps((float*)&(x)), _mm_shuffle_ps(yt, yt, 0))); \ } #define vec4_and(x, y, z) \ { \ - (z).data = _mm_and_ps((x).data, (y).data); \ + _mm_storeu_ps((float*)&(z), _mm_and_ps(_mm_loadu_ps((float*)&(x)), _mm_loadu_ps((float*)&(y)))); \ } #define vec4_and_scalar(x, y, z) \ { \ __m128 yt; \ yt = _mm_set_ss(y); \ - (z).data = _mm_and_ps((x).data, _mm_shuffle_ps(yt, yt, 0)); \ + _mm_storeu_ps((float*)&(z), _mm_and_ps(_mm_loadu_ps((float*)&(x)), _mm_shuffle_ps(yt, yt, 0))); \ } #define vec4_xor(x, y, z) \ { \ - (z).data = _mm_xor_ps((x).data, (y).data); \ + _mm_storeu_ps((float*)&(z), _mm_xor_ps(_mm_loadu_ps((float*)&(x)), _mm_loadu_ps((float*)&(y)))); \ } #define vec4_xor_scalar(x, y, z) \ { \ __m128 yt; \ yt = _mm_set_ss(y); \ - (z).data = _mm_xor_ps((x).data, _mm_shuffle_ps(yt, yt, 0)); \ + _mm_storeu_ps((float*)&(z), _mm_xor_ps(_mm_loadu_ps((float*)&(x)), _mm_shuffle_ps(yt, yt, 0))); \ } #define vec4_negate(x, z) \ { \ - (z).data = _mm_xor_ps((x).data, vec4_negate); \ + _mm_storeu_ps((float*)&(z), _mm_xor_ps(_mm_loadu_ps((float*)&(x)), vec4_negate)); \ } #define vec4_dot(x, y, z) \ { \ __m128 zt; \ - zt = _mm_mul_ps((x).data, (y).data); \ + zt = _mm_mul_ps(_mm_loadu_ps((float*)&(x)), _mm_loadu_ps((float*)&(y))); \ zt = _mm_hadd_ps(zt, zt); \ (z) = _mm_cvtss_f32(_mm_hadd_ps(zt, zt)); \ } @@ -1427,7 +1363,7 @@ extern const vec4iu vec4iu_null; { \ __m128 xt; \ __m128 zt; \ - xt = (x).data; \ + xt = _mm_loadu_ps((float*)&(x)); \ zt = _mm_mul_ps(xt, xt); \ zt = _mm_hadd_ps(zt, zt); \ (z) = _mm_cvtss_f32(_mm_sqrt_ss(_mm_hadd_ps(zt, zt))); \ @@ -1437,7 +1373,7 @@ extern const vec4iu vec4iu_null; { \ __m128 xt; \ __m128 zt; \ - xt = (x).data; \ + xt = _mm_loadu_ps((float*)&(x)); \ zt = _mm_mul_ps(xt, xt); \ zt = _mm_hadd_ps(zt, zt); \ (z) = _mm_cvtss_f32(_mm_hadd_ps(zt, zt)); \ @@ -1446,7 +1382,7 @@ extern const vec4iu vec4iu_null; #define vec4_distance(x, y, z) \ { \ __m128 zt; \ - zt = _mm_sub_ps((x).data, (y).data); \ + zt = _mm_sub_ps(_mm_loadu_ps((float*)&(x)), _mm_loadu_ps((float*)&(y))); \ zt = _mm_mul_ps(zt, zt); \ zt = _mm_hadd_ps(zt, zt); \ (z) = _mm_cvtss_f32(_mm_sqrt_ss(_mm_hadd_ps(zt, zt))); \ @@ -1455,7 +1391,7 @@ extern const vec4iu vec4iu_null; #define vec4_distance_squared(x, y, z) \ { \ __m128 zt; \ - zt = _mm_sub_ps((x).data, (y).data); \ + zt = _mm_sub_ps(_mm_loadu_ps((float*)&(x)), _mm_loadu_ps((float*)&(y))); \ zt = _mm_mul_ps(zt, zt); \ zt = _mm_hadd_ps(zt, zt); \ (z) = _mm_cvtss_f32(_mm_hadd_ps(zt, zt)); \ @@ -1465,9 +1401,10 @@ extern const vec4iu vec4iu_null; { \ __m128 b1; \ __m128 b2; \ - b1 = (blend).data; \ - b2 = _mm_sub_ps(vec4_identity.data, b1); \ - (z).data = _mm_add_ps(_mm_mul_ps((x).data, b2), _mm_mul_ps((y).data, b1)); \ + b1 = _mm_loadu_ps((float*)&(blend)); \ + b2 = _mm_sub_ps(_mm_loadu_ps((float*)&(vec4_identity)), b1); \ + _mm_storeu_ps((float*)&(z), _mm_add_ps(_mm_mul_ps(_mm_loadu_ps((float*)&(x)), b2), \ + _mm_mul_ps(_mm_loadu_ps((float*)&(y)), b1))); \ } #define vec4_lerp_scalar(x, y, z, blend) \ @@ -1476,41 +1413,42 @@ extern const vec4iu vec4iu_null; __m128 b2; \ b1 = _mm_set_ss(blend); \ b1 = _mm_shuffle_ps(b1, b1, 0); \ - b2 = _mm_sub_ps(vec4_identity.data, b1); \ - (z).data = _mm_add_ps(_mm_mul_ps((x).data, b2), _mm_mul_ps((y).data, b1)); \ + b2 = _mm_sub_ps(_mm_loadu_ps((float*)&(vec4_identity)), b1); \ + _mm_storeu_ps((float*)&(z), _mm_add_ps(_mm_mul_ps(_mm_loadu_ps((float*)&(x)), b2), \ + _mm_mul_ps(_mm_loadu_ps((float*)&(y)), b1))); \ } #define vec4_normalize(x, z) \ { \ __m128 xt; \ __m128 zt; \ - xt = (x).data; \ + xt = _mm_loadu_ps((float*)&(x)); \ zt = _mm_mul_ps(xt, xt); \ zt = _mm_hadd_ps(zt, zt); \ zt = _mm_sqrt_ss(_mm_hadd_ps(zt, zt)); \ if (zt.m128_f32[0] != 0.0f) \ zt.m128_f32[0] = 1.0f / zt.m128_f32[0]; \ - (z).data = _mm_mul_ps(xt, _mm_shuffle_ps(zt, zt, 0)); \ + _mm_storeu_ps((float*)&(z), _mm_mul_ps(xt, _mm_shuffle_ps(zt, zt, 0))); \ } #define vec4_rcp(x, z) \ { \ - (z).data = _mm_div_ps(vec4_identity.data, (x).data); \ + _mm_storeu_ps((float*)&(z), _mm_div_ps(_mm_loadu_ps((float*)&(vec4_identity)), _mm_loadu_ps((float*)&(x)))); \ } #define vec4_min(x, y, z) \ { \ - (z).data = _mm_min_ps((x).data, (y).data); \ + _mm_storeu_ps((float*)&(z), _mm_min_ps(_mm_loadu_ps((float*)&(x)), yt)); \ } #define vec4_max(x, y, z) \ { \ - (z).data = _mm_max_ps((x).data, (y).data); \ + _mm_storeu_ps((float*)&(z), _mm_max_ps(_mm_loadu_ps((float*)&(x)), yt)); \ } #define vec4_clamp(x, y, z, w) \ { \ - (w).data = _mm_min_ps(_mm_max_ps((x).data, (y).data), (z).data); \ + _mm_storeu_ps((float*)&(w), _mm_min_ps(_mm_max_ps(_mm_loadu_ps((float*)&(x)), yt), zt)); \ } #define vec4_clamp_scalar(x, y, z, w) \ @@ -1519,59 +1457,66 @@ extern const vec4iu vec4iu_null; __m128 zt; \ yt = _mm_set_ss(y); \ zt = _mm_set_ss(z); \ - (w).data = _mm_min_ps(_mm_max_ps((x).data, _mm_shuffle_ps(yt, yt, 0)), _mm_shuffle_ps(zt, zt, 0)); \ + _mm_storeu_ps((float*)&(w), _mm_min_ps(_mm_max_ps(_mm_loadu_ps((float*)&(x)), \ + _mm_shuffle_ps(yt, yt, 0)), _mm_shuffle_ps(zt, zt, 0))); \ } #define vec4_mult_min_max(x, y, z, w) \ { \ + __m128 xt; \ __m128 yt; \ - __m128 zt; \ __m128 wt; \ - yt = _mm_xor_ps((y).data, vec4_negate); \ - wt = _mm_or_ps(_mm_and_ps(yt, _mm_cmplt_ps((x).data, vec4_null.data)), \ - _mm_and_ps((z).data, _mm_cmpge_ps((x).data, vec4_null.data))); \ - (w).data = _mm_mul_ps((x).data, wt); \ + xt = _mm_loadu_ps((float*)&(x)); \ + yt = _mm_xor_ps(_mm_loadu_ps((float*)&(y)), vec4_negate); \ + wt = _mm_or_ps(_mm_and_ps(yt, _mm_cmplt_ps(xt, _mm_loadu_ps((float*)&(vec4_null)))), \ + _mm_and_ps(_mm_loadu_ps((float*)&(z)), _mm_cmpge_ps(xt, _mm_loadu_ps((float*)&(vec4_null))))); \ + _mm_storeu_ps((float*)&(w), _mm_mul_ps(xt, wt)); \ } #define vec4_mult_min_max_scalar(x, y, z, w) \ { \ + __m128 xt; \ __m128 yt; \ __m128 zt; \ __m128 wt; \ + xt = _mm_loadu_ps((float*)&(xt)); \ yt = _mm_set_ss(y); \ yt = _mm_shuffle_ps(yt, yt, 0); \ zt = _mm_set_ss(z); \ zt = _mm_shuffle_ps(zt, zt, 0); \ yt = _mm_xor_ps(yt, vec4_negate); \ - wt = _mm_or_ps(_mm_and_ps(yt, _mm_cmplt_ps((x).data, vec4_null.data)), \ - _mm_and_ps(zt, _mm_cmpge_ps((x).data, vec4_null.data))); \ - (w).data = _mm_mul_ps((x).data, wt); \ + wt = _mm_or_ps(_mm_and_ps(yt, _mm_cmplt_ps(xt, _mm_loadu_ps((float*)&(vec4_null)))), \ + _mm_and_ps(zt, _mm_cmpge_ps(xt, _mm_loadu_ps((float*)&(vec4_null))))); \ + _mm_storeu_ps((float*)&(w), _mm_mul_ps(xt, wt)); \ } #define vec4_div_min_max(x, y, z, w) \ { \ + __m128 xt; \ __m128 yt; \ - __m128 zt; \ __m128 wt; \ - yt = _mm_xor_ps((y).data, vec4_negate); \ - wt = _mm_or_ps(_mm_and_ps(yt, _mm_cmplt_ps((x).data, vec4_null.data)), \ - _mm_and_ps((z).data, _mm_cmpge_ps((x).data, vec4_null.data))); \ - (w).data = _mm_div_ps((x).data, wt); \ + xt = _mm_loadu_ps((float*)&(x)); \ + yt = _mm_xor_ps(_mm_loadu_ps((float*)&(y)), vec4_negate); \ + wt = _mm_or_ps(_mm_and_ps(yt, _mm_cmplt_ps(xt, _mm_loadu_ps((float*)&(vec4_null)))), \ + _mm_and_ps(_mm_loadu_ps((float*)&(z)), _mm_cmpge_ps(xt, _mm_loadu_ps((float*)&(vec4_null))))); \ + _mm_storeu_ps((float*)&(w), _mm_div_ps(xt, wt)); \ } #define vec4_div_min_max_scalar(x, y, z, w) \ { \ + __m128 xt; \ __m128 yt; \ __m128 zt; \ __m128 wt; \ + xt = _mm_loadu_ps((float*)&(x)); \ yt = _mm_set_ss(y); \ yt = _mm_shuffle_ps(yt, yt, 0); \ zt = _mm_set_ss(z); \ zt = _mm_shuffle_ps(zt, zt, 0); \ yt = _mm_xor_ps(yt, vec4_negate); \ - wt = _mm_or_ps(_mm_and_ps(yt, _mm_cmplt_ps((x).data, vec4_null.data)), \ - _mm_and_ps(zt, _mm_cmpge_ps((x).data, vec4_null.data))); \ - (w).data = _mm_div_ps((x).data, wt); \ + wt = _mm_or_ps(_mm_and_ps(yt, _mm_cmplt_ps(xt, _mm_loadu_ps((float*)&(vec4_null)))), \ + _mm_and_ps(zt, _mm_cmpge_ps(xt, _mm_loadu_ps((float*)&(vec4_null))))); \ + _mm_storeu_ps((float*)&(w), _mm_div_ps(xt, wt)); \ } #define vec2i_add(x, y, z) \ @@ -1700,264 +1645,58 @@ extern const vec4iu vec4iu_null; #define vec4i_add(x, y, z) \ { \ - (z).data = _mm_add_epi32((x).data, (y).data); \ + __m128i xt; \ + __m128i yt; \ + __m128i zt; \ + *(vec4i*)&xt = (x); \ + *(vec4i*)&yt = (y); \ + zt = _mm_add_epi32(xt, yt); \ + (z) = *(vec4i*)&zt; \ } #define vec4i_add_scalar(x, y, z) \ { \ + __m128i xt; \ __m128i yt; \ + __m128i zt; \ + *(vec4i*)&xt = (x); \ yt = _mm_set1_epi32(y); \ - (z).data = _mm_add_epi32((x).data, _mm_shuffle_epi32(yt, yt, 0)); \ + zt = _mm_add_epi32(xt, _mm_shuffle_epi32(yt, yt, 0)); \ + (z) = *(vec4i*)&zt; \ } #define vec4i_sub(x, y, z) \ { \ - (z).data = _mm_sub_epi32((x).data, (y).data); \ + __m128i xt; \ + __m128i yt; \ + __m128i zt; \ + *(vec4i*)&xt = (x); \ + *(vec4i*)&yt = (y); \ + zt = _mm_sub_epi32(xt, yt); \ + (z) = *(vec4i*)&zt; \ } #define vec4i_sub_scalar(x, y, z) \ { \ + __m128i xt; \ __m128i yt; \ + __m128i zt; \ + *(vec4i*)&xt = (x); \ yt = _mm_set1_epi32(y); \ - (z).data = _mm_sub_epi32((x).data, _mm_shuffle_epi32(yt, yt, 0)); \ + zt = _mm_sub_epi32(xt, _mm_shuffle_epi32(yt, yt, 0)); \ + (z) = *(vec4i*)&zt; \ } #define vec4_to_vec4i(x, z) \ { \ - (z).data = _mm_cvtps_epi32((x).data); \ + __m128i zt; \ + zt = _mm_cvtps_epi32(_mm_loadu_ps((float*)&(x))); \ + (z) = *(vec4i*)&zt; \ } #define vec4i_to_vec4(x, z) \ { \ - (z).data = _mm_cvtepi32_ps((x).data); \ -} - -#define vec2d_add(x, y, z) \ -{ \ - (z).data = _mm_add_pd((x).data, (y).data); \ -} - -#define vec2d_add_scalar(x, y, z) \ -{ \ - __m128d yt; \ - yt = _mm_set_sd(y); \ - (z).data = _mm_add_pd((x).data, _mm_shuffle_pd(yt, yt, 0)); \ -} - -#define vec2d_sub(x, y, z) \ -{ \ - (z).data = _mm_sub_pd((x).data, (y).data); \ -} - -#define vec2d_sub_scalar(x, y, z) \ -{ \ - __m128d yt; \ - yt = _mm_set_sd(y); \ - (z).data = _mm_sub_pd((x).data, _mm_shuffle_pd(yt, yt, 0)); \ -} - -#define vec2d_mult(x, y, z) \ -{ \ - (z).data = _mm_mul_pd((x).data, (y).data); \ -} - -#define vec2d_mult_scalar(x, y, z) \ -{ \ - __m128d yt; \ - yt = _mm_set_sd(y); \ - (z).data = _mm_mul_pd((x).data, _mm_shuffle_pd(yt, yt, 0)); \ -} - -#define vec2d_div(x, y, z) \ -{ \ - (z).data = _mm_div_pd((x).data, (y).data); \ -} - -#define vec2d_div_scalar(x, y, z) \ -{ \ - __m128d yt; \ - yt = _mm_set_sd(y); \ - (z).data = _mm_div_pd((x).data, _mm_shuffle_pd(yt, yt, 0)); \ -} - -#define vec2d_and(x, y, z) \ -{ \ - (z).data = _mm_and_pd((x).data, (y).data); \ -} - -#define vec2d_and_scalar(x, y, z) \ -{ \ - __m128d yt; \ - yt = _mm_set_sd(y); \ - (z).data = _mm_and_pd((x).data, _mm_shuffle_pd(yt, yt, 0)); \ -} - -#define vec2d_xor(x, y, z) \ -{ \ - (z).data = _mm_xor_pd((x).data, (y).data); \ -} - -#define vec2d_xor_scalar(x, y, z) \ -{ \ - __m128d yt; \ - yt = _mm_set_sd(y); \ - (z).data = _mm_xor_pd((x).data, _mm_shuffle_pd(yt, yt, 0)); \ -} - -#define vec2d_negate(x, z) \ -{ \ - (z).data = _mm_xor_pd((x).data, vec2d_negate); \ -} - -#define vec2d_dot(x, y, z) \ -{ \ - __m128d zt; \ - zt = _mm_mul_pd((x).data, (y).data); \ - (z) = _mm_cvtsd_f64(_mm_hadd_pd(zt, zt)); \ -} - -#define vec2d_length(x, z) \ -{ \ - __m128d zt; \ - zt = _mm_mul_pd((x).data, (x).data); \ - (z) = _mm_cvtsd_f64(_mm_sqrt_sd(_mm_hadd_pd(zt, zt))); \ -} - -#define vec2d_length_squared(x, z) \ -{ \ - __m128d zt; \ - zt = _mm_mul_pd((x).data, (x).data); \ - (z) = _mm_cvtsd_f64(_mm_hadd_pd(zt, zt)); \ -} - -#define vec2d_distance(x, y, z) \ -{ \ - __m128d zt; \ - zt = _mm_sub_pd((x).data, (y).data); \ - zt = _mm_mul_pd(zt, zt); \ - (z) = _mm_cvtsd_f64(_mm_sqrt_sd(_mm_hadd_pd(zt, zt))); \ -} - -#define vec2d_distance_squared(x, y, z) \ -{ \ - __m128d zt; \ - zt = _mm_sub_pd((x).data, (y).data); \ - zt = _mm_mul_pd(zt, zt); \ - (z) = _mm_cvtsd_f64(_mm_hadd_pd(zt, zt)); \ -} - -#define vec2d_lerp(x, y, z, blend) \ -{ \ - __m128d b1; \ - __m128d b2; \ - b1 = (blend).data; \ - b2 = _mm_sub_pd(vec2d_identity.data, b1); \ - (z).data = _mm_add_pd(_mm_mul_pd((x).data, b2), _mm_mul_pd((y).data, b1)); \ -} - -#define vec2d_lerp_scalar(x, y, z, blend) \ -{ \ - __m128d b1; \ - __m128d b2; \ - b1 = _mm_set_sd(blend); \ - b1 = _mm_shuffle_pd(b1, b1, 0); \ - b2 = _mm_sub_pd(vec2d_identity.data, b1); \ - (z).data = _mm_add_pd(_mm_mul_pd((x).data, b2), _mm_mul_pd((y).data, b1)); \ -} - -#define vec2d_normalize(x, z) \ -{ \ - __m128d zt; \ - zt = _mm_mul_pd((x).data, (x).data); \ - zt = _mm_sqrt_sd(_mm_hadd_pd(zt, zt)); \ - if (zt.m128d_f64[0] != 0.0) \ - zt.m128d_f64[0] = 1.0 / zt.m128d_f64[0]; \ - (z).data = _mm_mul_pd((x).data, _mm_shuffle_pd(zt, zt, 0)); \ -} - -#define vec2d_rcp(x, z) \ -{ \ - (z).data = _mm_div_pd(vec2d_identity.data, (x).data); \ -} - -#define vec2d_min(x, y, z) \ -{ \ - (z).data = _mm_min_pd((x).data, (y).data); \ -} - -#define vec2d_max(x, y, z) \ -{ \ - (z).data = _mm_max_pd((x).data, (y).data); \ -} - -#define vec2d_clamp(x, y, z, w) \ -{ \ - (w).data = _mm_min_pd(_mm_max_pd((x).data, (y).data), (z).data); \ -} - -#define vec2d_clamp_scalar(x, y, z, w) \ -{ \ - __m128d yt; \ - __m128d zt; \ - __m128d wt; \ - yt = _mm_set_sd(y); \ - zt = _mm_set_sd(z); \ - wt = _mm_min_pd(_mm_max_pd((x).data, _mm_shuffle_pd(yt, yt, 0)), _mm_shuffle_pd(zt, zt, 0)); \ - (w) = *(vec2d*)&wt; \ -} - -#define vec2d_mult_min_max(x, y, z, w) \ -{ \ - __m128d yt; \ - __m128d zt; \ - __m128d wt; \ - yt = (y).data; \ - zt = (z).data; \ - yt = _mm_xor_pd(yt, vec2d_negate); \ - wt = _mm_or_pd(_mm_and_pd(yt, _mm_cmplt_pd((x).data, vec2d_null.data)), \ - _mm_and_pd(zt, _mm_cmpgt_pd((x).data, vec2d_null.data))); \ - (w).data = _mm_mul_pd((x).data, wt); \ -} - -#define vec2d_mult_min_max_scalar(x, y, z, w) \ -{ \ - __m128d yt; \ - __m128d zt; \ - __m128d wt; \ - yt = _mm_set_sd(y); \ - yt = _mm_shuffle_pd(yt, yt, 0); \ - zt = _mm_set_sd(z); \ - zt = _mm_shuffle_pd(zt, zt, 0); \ - yt = _mm_xor_pd(yt, vec2d_negate); \ - wt = _mm_or_pd(_mm_and_pd(yt, _mm_cmplt_pd((x).data, vec2d_null.data)), \ - _mm_and_pd(zt, _mm_cmpgt_pd((x).data, vec2d_null.data))); \ - (w).data = _mm_mul_pd((x).data, wt); \ -} - -#define vec2d_div_min_max(x, y, z, w) \ -{ \ - __m128d yt; \ - __m128d zt; \ - __m128d wt; \ - yt = (y).data; \ - zt = (z).data; \ - yt = _mm_xor_pd(yt, vec2d_negate); \ - wt = _mm_or_pd(_mm_and_pd(yt, _mm_cmplt_pd((x).data, vec2d_null.data)), \ - _mm_and_pd(zt, _mm_cmpgt_pd((x).data, vec2d_null.data))); \ - (w).data = _mm_div_pd((x).data, wt); \ -} - -#define vec2d_div_min_max_scalar(x, y, z, w) \ -{ \ - __m128d yt; \ - __m128d zt; \ - __m128d wt; \ - yt = _mm_set_sd(y); \ - yt = _mm_shuffle_pd(yt, yt, 0); \ - zt = _mm_set_sd(z); \ - zt = _mm_shuffle_pd(zt, zt, 0); \ - yt = _mm_xor_pd(yt, vec2d_negate); \ - wt = _mm_or_pd(_mm_and_pd(yt, _mm_cmplt_pd((x).data, vec2d_null.data)), \ - _mm_and_pd(zt, _mm_cmpgt_pd((x).data, vec2d_null.data))); \ - (w).data = _mm_div_pd((x).data, wt); \ + __m128i xt; \ + *(vec4i*)&xt = (x); \ + _mm_storeu_ps((float*)&(z), _mm_cvtepi32_ps(xt)); \ } diff --git a/src/MMPlusDec/MMPlusDec.cpp b/src/MMPlusDec/MMPlusDec.cpp index b479fec3..22ef33d1 100644 --- a/src/MMPlusDec/MMPlusDec.cpp +++ b/src/MMPlusDec/MMPlusDec.cpp @@ -27,6 +27,7 @@ static const uint8_t mmplus_iv[] = { }; bool aes_ni; +bool f16c; int32_t wmain(int32_t argc, wchar_t** argv) { if (argc < 2) { @@ -63,7 +64,8 @@ int32_t wmain(int32_t argc, wchar_t** argv) { int32_t cpuid_data[4]; __cpuid(cpuid_data, 1); - aes_ni = cpuid_data[2] & 0x2000000 ? true : false; + aes_ni = (cpuid_data[2] & (1 << 25)) ? true : false; + f16c = (cpuid_data[2] & (1 << 29)) ? true : false; aes256_ctx ctx; aes256_init_ctx(&ctx, mmplus_key); @@ -93,7 +95,7 @@ int32_t wmain(int32_t argc, wchar_t** argv) { size_t size; if (encrypt) { while (length && (size = in_file.read(buf, sizeof(buf)))) { - if (length == size) { + if (length == size) { // PKCS7 Padding uint8_t align = (uint8_t)(0x10 - size % 0x10); for (uint8_t i = 0; i < align; i++) buf[size + i] = align; @@ -110,7 +112,7 @@ int32_t wmain(int32_t argc, wchar_t** argv) { while (length && (size = in_file.read(buf, sizeof(buf)))) { aes256_cbc_decrypt_buffer(&ctx, buf, size); - if (length == size) + if (length == size) // PKCS7 Padding size -= buf[size - 1]; out_file.write(buf, size); @@ -155,7 +157,7 @@ int32_t wmain(int32_t argc, wchar_t** argv) { size_t size; if (encrypt) { while (length && (size = in_file.read(buf, sizeof(buf)))) { - if (length == size) { + if (length == size) { // PKCS7 Padding uint8_t align = (uint8_t)(0x10 - size % 0x10); for (uint8_t i = 0; i < align; i++) buf[size + i] = align; @@ -172,7 +174,7 @@ int32_t wmain(int32_t argc, wchar_t** argv) { while (length && (size = in_file.read(buf, sizeof(buf)))) { aes256_cbc_decrypt_buffer(&ctx, buf, size); - if (length == size) + if (length == size) // PKCS7 Padding size -= buf[size - 1]; out_file.write(buf, size);