diff --git a/src/CRE/Glitter/effect_group.cpp b/src/CRE/Glitter/effect_group.cpp index cae6ed5d..fdb9e155 100644 --- a/src/CRE/Glitter/effect_group.cpp +++ b/src/CRE/Glitter/effect_group.cpp @@ -22,9 +22,7 @@ namespace Glitter { #endif if (resources) { - for (texture** i = resources; *i; i++) - texture_free(*i); - free_def(resources); + texture_array_free(resources); resources = 0; } @@ -94,9 +92,7 @@ namespace Glitter { } } - prj::sort(object_set_ids); - prj::unique(object_set_ids); - + prj::sort_unique(object_set_ids); return has_model; } diff --git a/src/CRE/draw_object.cpp b/src/CRE/draw_object.cpp index eb82945d..19ed230a 100644 --- a/src/CRE/draw_object.cpp +++ b/src/CRE/draw_object.cpp @@ -63,6 +63,10 @@ namespace mdl { rctx->draw_state.stats.draw_triangle_count += count - 2; } + void draw_etc_obj(render_context* rctx, mdl::EtcObj* etc) { + + } + void draw_sub_mesh(render_context* rctx, const ObjSubMeshArgs* args, const mat4* model, void(*func)(render_context* rctx, const ObjSubMeshArgs* args)) { GLuint vao = rctx->disp_manager.get_vertex_array(args); diff --git a/src/CRE/draw_object.hpp b/src/CRE/draw_object.hpp index e18c16c6..5e5598a6 100644 --- a/src/CRE/draw_object.hpp +++ b/src/CRE/draw_object.hpp @@ -14,6 +14,7 @@ namespace mdl { extern void draw(render_context* rctx, obj_primitive_type primitive_type, uint32_t count, uint16_t start, uint16_t end, obj_index_format index_format, size_t indices); + extern void draw_etc_obj(render_context* rctx, mdl::EtcObj* etc); extern void draw_sub_mesh(render_context* rctx, const ObjSubMeshArgs* args, const mat4* model, void(*func)(render_context* rctx, const ObjSubMeshArgs* args)); /*extern void draw_sub_mesh_show_vector(render_context* rctx, diff --git a/src/CRE/draw_primitive.cpp b/src/CRE/draw_primitive.cpp deleted file mode 100644 index c6639ad9..00000000 --- a/src/CRE/draw_primitive.cpp +++ /dev/null @@ -1,6 +0,0 @@ -/* - by korenkonder - GitHub/GitLab: korenkonder -*/ - -#include "draw_object.hpp" diff --git a/src/CRE/draw_primitive.hpp b/src/CRE/draw_primitive.hpp deleted file mode 100644 index b1c0e686..00000000 --- a/src/CRE/draw_primitive.hpp +++ /dev/null @@ -1,11 +0,0 @@ -/* - by korenkonder - GitHub/GitLab: korenkonder -*/ - -#pragma once - -#include "../KKdLib/default.hpp" -#include "../KKdLib/mat.hpp" -#include "../KKdLib/vec.hpp" -#include "gl_state.hpp" diff --git a/src/CRE/gl_state.cpp b/src/CRE/gl_state.cpp index d139ddd4..6e75caa5 100644 --- a/src/CRE/gl_state.cpp +++ b/src/CRE/gl_state.cpp @@ -350,6 +350,13 @@ void gl_state_get_all_gl_errors() { printf_debug("GL Error: 0x%04X\n", error); } +GLenum gl_state_get_error() { + GLenum error = glGetError(); + if (error) + printf_debug("GL Error: 0x%04X\n", error); + return error; +} + GLuint gl_state_get_program() { return gl_state.program; } diff --git a/src/CRE/gl_state.hpp b/src/CRE/gl_state.hpp index ff10f648..fa13ab62 100644 --- a/src/CRE/gl_state.hpp +++ b/src/CRE/gl_state.hpp @@ -96,6 +96,7 @@ extern void gl_state_enable_scissor_test(); extern void gl_state_enable_stencil_test(); extern void gl_state_get(); extern void gl_state_get_all_gl_errors(); +extern GLenum gl_state_get_error(); extern GLuint gl_state_get_program(); extern void gl_state_set_blend_func(GLenum src, GLenum dst); extern void gl_state_set_blend_func_separate(GLenum src_rgb, GLenum dst_rgb, diff --git a/src/CRE/hand_item.cpp b/src/CRE/hand_item.cpp index 50eb0633..08c8e356 100644 --- a/src/CRE/hand_item.cpp +++ b/src/CRE/hand_item.cpp @@ -47,10 +47,6 @@ void hand_item_handler_data_init() { hand_item_handler_data = {}; } -void hand_item_handler_data_clear() { - hand_item_handler_data.clear(); -} - const hand_item* hand_item_handler_data_get_hand_item(int32_t uid, chara_index chara_index) { if (uid >= 0) return hand_item_handler_data.get_hand_item(uid, chara_index); diff --git a/src/CRE/hand_item.hpp b/src/CRE/hand_item.hpp index 02ad6c3c..a6a49797 100644 --- a/src/CRE/hand_item.hpp +++ b/src/CRE/hand_item.hpp @@ -27,7 +27,6 @@ struct hand_item { }; extern void hand_item_handler_data_init(); -extern void hand_item_handler_data_clear(); extern const hand_item* hand_item_handler_data_get_hand_item(int32_t uid, chara_index chara_index); extern const std::map, hand_item>& hand_item_handler_data_get_hand_items(); extern int32_t hand_item_handler_data_get_hand_item_uid(const char* str); diff --git a/src/CRE/item_table.cpp b/src/CRE/item_table.cpp index cb1a1dca..cd5ee650 100644 --- a/src/CRE/item_table.cpp +++ b/src/CRE/item_table.cpp @@ -269,9 +269,12 @@ static void item_table_load(data_struct* data, item_table& itm_tbl, itm_table& i itm.sub_id = (item_sub_id)i.sub_id; for (itm_table_item_data_obj& j : i.data.obj) { - object_info obj_info = aft_obj_db->get_object_info(j.uid.c_str()); - if (obj_info.is_null()) - continue; + object_info obj_info; + if (j.uid.compare("NULL")) { + obj_info = aft_obj_db->get_object_info(j.uid.c_str()); + if (obj_info.is_null()) + continue; + } item_table_item_data_obj obj; obj.obj_info = obj_info; diff --git a/src/CRE/object.cpp b/src/CRE/object.cpp index f1bd0292..52caf643 100644 --- a/src/CRE/object.cpp +++ b/src/CRE/object.cpp @@ -17,7 +17,6 @@ #include "../KKdLib/dds.hpp" #include "../KKdLib/hash.hpp" #include "../KKdLib/msgpack.hpp" -#include "../KKdLib/sort.hpp" #include "../KKdLib/str_utils.hpp" static void obj_set_handler_calc_axis_aligned_bounding_box(obj_set_handler* handler); @@ -373,9 +372,10 @@ index_buffer_num(), index_buffer_data(), load_count(), modern() { } obj_set_handler::~obj_set_handler() { - for (uint32_t i = 0; i < tex_num; i++) - texture_free(tex_data[i]); - free_def(tex_data); + if (tex_data) { + texture_array_free(tex_data); + tex_data = 0; + } obj_set_handler_index_buffer_free(this); obj_set_handler_vertex_buffer_free(this); @@ -1713,8 +1713,8 @@ inline std::vector* object_storage_get_obj_set_textures(int32_t set) { } int32_t object_storage_load_set(void* data, object_database* obj_db, const char* name) { - const object_set_info* set_info = 0; - if (!obj_db->get_object_set_info(name, &set_info)) + const object_set_info* set_info = obj_db->get_object_set_info(name); + if (!set_info) return 1; obj_set_handler* handler = object_storage_get_obj_set_handler(set_info->id); @@ -1750,8 +1750,8 @@ int32_t object_storage_load_set(void* data, object_database* obj_db, const char* } int32_t object_storage_load_set(void* data, object_database* obj_db, uint32_t set_id) { - const object_set_info* set_info = 0; - if (!obj_db->get_object_set_info(set_id, &set_info)) + const object_set_info* set_info = obj_db->get_object_set_info(set_id); + if (!set_info) return 1; obj_set_handler* handler = object_storage_get_obj_set_handler(set_id); @@ -1818,12 +1818,6 @@ int32_t object_storage_load_set_hash(void* data, uint32_t hash) { return 0; } -static int32_t obj_set_obj_id_data_sort(void const* src1, void const* src2) { - std::pair* p1 = (std::pair*)src1; - std::pair* p2 = (std::pair*)src2; - return (int32_t)(p1->first - p2->first); -} - bool object_storage_load_obj_set_check_not_read(uint32_t set_id, object_database* obj_db, texture_database* tex_db) { obj_set_handler* handler = object_storage_get_obj_set_handler(set_id); @@ -1850,9 +1844,7 @@ bool object_storage_load_obj_set_check_not_read(uint32_t set_id, handler->obj_id_data.reserve(set->obj_num); for (uint32_t i = 0; i < set->obj_num; i++) handler->obj_id_data.push_back({ set->obj_data[i].id, i }); - - quicksort_custom(handler->obj_id_data.data(), handler->obj_id_data.size(), - sizeof(std::pair), obj_set_obj_id_data_sort); + handler->obj_id_data.sort(); if (!obj_set_handler_vertex_buffer_load(handler) || !obj_set_handler_index_buffer_load(handler)) @@ -1991,8 +1983,8 @@ bool object_storage_load_obj_set_check_not_read(uint32_t set_id, } inline void object_storage_unload_set(object_database* obj_db, const char* name) { - const object_set_info* set_info = 0; - if (!obj_db->get_object_set_info(name, &set_info)) + const object_set_info* set_info = obj_db->get_object_set_info(name); + if (!set_info) return; obj_set_handler* handler = object_storage_get_obj_set_handler(set_info->id); @@ -2006,11 +1998,7 @@ inline void object_storage_unload_set(object_database* obj_db, const char* name) handler->tex_id_data.clear(); handler->gentex.clear(); - texture** tex_data = handler->tex_data; - int32_t tex_num = handler->tex_num; - for (int32_t i = 0; i < tex_num; i++) - texture_free(tex_data[i]); - free_def(tex_data); + texture_array_free(handler->tex_data); handler->tex_data = 0; handler->tex_num = 0; @@ -2038,11 +2026,7 @@ inline void object_storage_unload_set(uint32_t set_id) { handler->tex_id_data.clear(); handler->gentex.clear(); - texture** tex_data = handler->tex_data; - int32_t tex_num = handler->tex_num; - for (int32_t i = 0; i < tex_num; i++) - texture_free(tex_data[i]); - free_def(tex_data); + texture_array_free(handler->tex_data); handler->tex_data = 0; handler->tex_num = 0; @@ -2169,10 +2153,6 @@ static void obj_set_handler_index_buffer_free(obj_set_handler* handler) { handler->index_buffer_num = 0; } -static size_t obj_set_tex_id_radix_index_func_id(std::pair* data, size_t index) { - return *(uint32_t*)&data[index].first; -} - static bool obj_set_handler_load_textures(obj_set_handler* handler, const void* data, bool big_endian) { obj_set* set = handler->obj_set; if (!set || !data) @@ -2190,16 +2170,13 @@ static bool obj_set_handler_load_textures(obj_set_handler* handler, const void* handler->tex_id_data.reserve(handler->tex_num); handler->gentex.reserve(handler->tex_num); uint32_t* tex_id_data = set->tex_id_data; - int32_t tex_num = handler->tex_num; + uint32_t tex_num = handler->tex_num; texture** tex_data = handler->tex_data; - for (int32_t i = 0; i < tex_num; i++) { + for (uint32_t i = 0; i < tex_num; i++) { handler->tex_id_data.push_back({ tex_id_data[i], i }); handler->gentex.push_back(tex_data[i]); } - - radix_sort_custom(handler->tex_id_data.data(), handler->tex_id_data.size(), - sizeof(std::pair), sizeof(uint32_t), - (radix_index_func)obj_set_tex_id_radix_index_func_id); + handler->tex_id_data.sort(); return false; } @@ -2228,10 +2205,7 @@ static bool obj_set_handler_load_textures_modern(obj_set_handler* handler, handler->tex_id_data.push_back({ tex_id_data[i], i }); handler->gentex.push_back(tex_data[i]); } - - radix_sort_custom(handler->tex_id_data.data(), handler->tex_id_data.size(), - sizeof(std::pair), sizeof(uint32_t), - (radix_index_func)obj_set_tex_id_radix_index_func_id); + handler->tex_id_data.sort(); return false; } diff --git a/src/CRE/object.hpp b/src/CRE/object.hpp index aea79186..bce8af63 100644 --- a/src/CRE/object.hpp +++ b/src/CRE/object.hpp @@ -8,6 +8,7 @@ #include "../KKdLib/default.hpp" #include "../KKdLib/database/object.hpp" #include "../KKdLib/database/texture.hpp" +#include "../KKdLib/prj/vector_pair.hpp" #include "../KKdLib/mat.hpp" #include "../KKdLib/obj.hpp" #include "../KKdLib/txp.hpp" @@ -76,10 +77,10 @@ struct obj_set_handler { bool tex_loaded; prj::shared_ptr alloc_handler; obj_set* obj_set; - std::vector> obj_id_data; + prj::vector_pair obj_id_data; uint32_t tex_num; std::vector gentex; - std::vector> tex_id_data; + prj::vector_pair tex_id_data; texture** tex_data; int32_t set_id; uint32_t vertex_buffer_num; diff --git a/src/CRE/render_context.cpp b/src/CRE/render_context.cpp index e3f8d10b..122bcefe 100644 --- a/src/CRE/render_context.cpp +++ b/src/CRE/render_context.cpp @@ -7,8 +7,8 @@ #include "../KKdLib/sort.hpp" #include "Glitter/glitter.hpp" #include "rob/rob.hpp" -#include "render_manager.hpp" #include "file_handler.hpp" +#include "render_manager.hpp" #include "shader_ft.hpp" #include "sound.hpp" #include "stage.hpp" @@ -98,7 +98,7 @@ sss_data::sss_data() : init(), enable(), npr_contour(), param() { enable = true; param = { 0.0f, 0.0f, 0.0f, 1.0f }; - textures[0].init(640, 360, 0, GL_RGBA16F, GL_DEPTH_COMPONENT32F); + textures[0].init(640, 360, 0, GL_RGBA16F, GL_ZERO /*GL_DEPTH_COMPONENT32F*/); textures[1].init(320, 180, 0, GL_RGBA16F, GL_ZERO); textures[2].init(320, 180, 0, GL_RGBA16F, GL_ZERO); textures[3].init(320, 180, 0, GL_RGBA16F, GL_ZERO); @@ -154,6 +154,63 @@ texture_transform_struct::texture_transform_struct(uint32_t id, mat4& mat) : id( } namespace mdl { + void EtcObj::init(EtcObjType type) { + this->type = type; + color = 1.0f; + fog = false; + switch (type) { + case ETC_OBJ_TEAPOT: + data.teapot.size = 1.0f; + break; + case ETC_OBJ_GRID: + data.grid.w = 10; + data.grid.h = 10; + data.grid.ws = 20; + data.grid.hs = 20; + break; + case ETC_OBJ_CUBE: + data.cube.size_x = 0.0f; + data.cube.size_y = 0.0f; + data.cube.size_z = 0.0f; + data.cube.wire = 0; + break; + case ETC_OBJ_SPHERE: + data.sphere.radius = 1.0f; + data.sphere.slices = 8; + data.sphere.stacks = 8; + data.sphere.wire = 0; + break; + case ETC_OBJ_PLANE: + data.plane.w = 10; + data.plane.h = 10; + break; + case ETC_OBJ_CONE: + data.cone.base = 1.0f; + data.cone.height = 1.0f; + data.cone.slices = 8; + data.cone.stacks = 8; + data.cone.wire = 0; + break; + case ETC_OBJ_LINE: + data.line.x0 = 0.0f; + data.line.y0 = 0.0f; + data.line.y1 = 0.0f; + data.line.z1 = 1.0f; + break; + case ETC_OBJ_CROSS: + data.cross.size = 0.1f; + break; + default: + return; + } + } + + void ObjData::init_etc(const mat4* mat, mdl::EtcObj* etc) { + kind = mdl::OBJ_KIND_ETC; + this->mat = *mat; + args.etc = *etc; + } + void ObjData::init_sub_mesh(DispManager* disp_manager, const mat4* mat, float_t radius, obj_sub_mesh* sub_mesh, obj_mesh* mesh, obj_material_data* material, std::vector* textures, int32_t mat_count, mat4* mats, GLuint vertex_buffer, @@ -1011,7 +1068,7 @@ namespace mdl { } break; case OBJ_KIND_ETC: { draw_object_model_mat_load(rctx_ptr, i->mat); - //draw_primitive_draw(&i->data.primitive); + draw_etc_obj(rctx_ptr, &i->args.etc); } break; case OBJ_KIND_USER: { draw_object_model_mat_load(rctx_ptr, i->mat); @@ -1726,6 +1783,21 @@ namespace mdl { } } + void DispManager::entry_obj_etc(const mat4* mat, EtcObj* etc) { + ObjData* data = alloc_data(mdl::OBJ_KIND_ETC); + if (!data) + return; + + data->init_etc(mat, etc); + if (etc->color.w == 1.0f) { + if ((obj_flags & OBJ_SHADOW) != 0) + mdl::DispManager::entry_list((mdl::ObjType)(OBJ_TYPE_SHADOW_CHARA + shadow_type), data); + mdl::DispManager::entry_list(OBJ_TYPE_OPAQUE, data); + } + else + mdl::DispManager::entry_list(OBJ_TYPE_TRANSLUCENT, data); + } + void DispManager::entry_obj_user(const mat4* mat, UserArgsFunc func, void* data, ObjType type) { ObjData* _data = alloc_data(OBJ_KIND_USER); if (_data) { @@ -2063,6 +2135,7 @@ namespace rndr { glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, i % 2 ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR); glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glSamplerParameterf(sampler, GL_TEXTURE_MAX_ANISOTROPY_EXT, 16.0f); GLuint wrap_s; switch (i / 2 % 3) { @@ -2977,7 +3050,7 @@ int32_t shadow::init_data() { glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, (GLfloat*)&border_color); } gl_state_bind_texture_2d(0); - glGetError(); + gl_state_get_error(); return 0; } diff --git a/src/CRE/render_context.hpp b/src/CRE/render_context.hpp index 44bb10d2..1019f3bf 100644 --- a/src/CRE/render_context.hpp +++ b/src/CRE/render_context.hpp @@ -357,6 +357,8 @@ namespace mdl { vec4 color; bool fog; Data data; + + void init(EtcObjType type); }; typedef void(*UserArgsFunc)(render_context* rctx, void* data); @@ -374,7 +376,7 @@ namespace mdl { struct ObjData { union Args { ObjSubMeshArgs sub_mesh; - EtcObj::Data etc; + EtcObj etc; UserArgs user; ObjTranslucentArgs translucent; }; @@ -385,6 +387,7 @@ namespace mdl { float_t radius; Args args; + void init_etc(const mat4* mat, mdl::EtcObj* etc); void init_sub_mesh(DispManager* disp_manager, const mat4* mat, float_t radius, obj_sub_mesh* sub_mesh, obj_mesh* mesh, obj_material_data* material, std::vector* textures, int32_t mat_count, mat4* mats, GLuint vertex_buffer, @@ -521,6 +524,7 @@ namespace mdl { void entry_obj_by_object_info_object_skin(object_info obj_info, std::vector* texture_pattern, texture_data_struct* texture_data, float_t alpha, mat4* matrices, mat4* ex_data_matrices, const mat4* mat, const mat4* global_mat); + void entry_obj_etc(const mat4* mat, EtcObj* etc); void entry_obj_user(const mat4* mat, UserArgsFunc func, void* data, ObjType type); GLuint get_vertex_array(const ObjSubMeshArgs* args); bool get_chara_color(); diff --git a/src/CRE/render_manager.cpp b/src/CRE/render_manager.cpp index 45a95b86..b3936afa 100644 --- a/src/CRE/render_manager.cpp +++ b/src/CRE/render_manager.cpp @@ -97,7 +97,7 @@ namespace rndr { cpu_time[id] = 0.0; gpu_time[id] = 0.0; if (!pass_sw[id]) { - glGetError(); + gl_state_get_error(); return; } @@ -138,7 +138,7 @@ namespace rndr { break; } render_pass_end(id); - glGetError(); + gl_state_get_error(); } void RenderManager::render_pass_begin() { @@ -253,14 +253,14 @@ namespace rndr { //if (pp->render_width > 1280.0) // sss->npr_contour = false; - if (sss->npr_contour) { + //if (sss->npr_contour) { pp->rend_texture.bind(); glViewport(0, 0, pp->render_width, pp->render_height); - } - else { - sss->textures[0].bind(); - glViewport(0, 0, 640, 360); - } + //} + //else { + // sss->textures[0].bind(); + // glViewport(0, 0, 640, 360); + //} glClearColor(sss->param.x, sss->param.y, sss->param.z, 0.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); @@ -308,6 +308,30 @@ namespace rndr { draw_pass_sss_contour(rctx, pp); } } + + if (!sss->npr_contour) { + sss->textures[0].bind(); + glViewport(0, 0, 640, 360); + + filter_scene_shader_data filter_scene = {}; + filter_scene.g_transform = { 1.0f, 1.0f, 0.0f, 0.0f }; + filter_scene.g_texcoord = { 1.0f, 1.0f, 0.0f, 0.0f }; + rctx->filter_scene_ubo.WriteMapMemory(filter_scene); + + imgfilter_batch_shader_data imgfilter_batch = {}; + imgfilter_batch.g_color_scale = 1.0f; + imgfilter_batch.g_color_offset = 0.0f; + imgfilter_batch.g_texture_lod = 0.0f; + rctx->imgfilter_batch_ubo.WriteMapMemory(imgfilter_batch); + + uniform_value[U_IMAGE_FILTER] = 5; + shaders_ft.set(SHADER_FT_IMGFILT); + rctx->filter_scene_ubo.Bind(0); + rctx->imgfilter_batch_ubo.Bind(1); + gl_state_active_bind_texture_2d(0, pp->rend_texture.color_texture->tex); + render_texture::draw_custom(); + } + draw_pass_sss_filter(rctx, sss); gl_state_bind_framebuffer(0); } @@ -488,7 +512,7 @@ namespace rndr { gl_state_bind_framebuffer(0); } } - glGetError(); + gl_state_get_error(); } void RenderManager::pass_sprite_bg(render_context* rctx) { @@ -510,7 +534,7 @@ namespace rndr { gl_state_enable_depth_test(); gl_state_set_depth_mask(GL_TRUE); gl_state_bind_framebuffer(0); - glGetError(); + gl_state_get_error(); } void RenderManager::pass_all_3d(render_context* rctx) { @@ -777,7 +801,7 @@ namespace rndr { 0, 0, pp->sprite_width, pp->sprite_height, GL_COLOR_BUFFER_BIT, GL_NEAREST); gl_state_bind_read_framebuffer(0); } - glGetError(); + gl_state_get_error(); } void RenderManager::pass_3d_contour(render_context* rctx) { diff --git a/src/CRE/render_texture.cpp b/src/CRE/render_texture.cpp index 3b4cc499..f7940406 100644 --- a/src/CRE/render_texture.cpp +++ b/src/CRE/render_texture.cpp @@ -34,7 +34,7 @@ int32_t render_texture::bind(int32_t index) { if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) return -1; - glGetError(); + gl_state_get_error(); return 0; } @@ -193,7 +193,7 @@ void render_texture_data_free() { static int32_t render_texture_framebuffer_init(render_texture* rt, int32_t max_level) { glGenFramebuffers(max_level + 1, rt->fbos); - return -(glGetError() != GL_ZERO); + return -(gl_state_get_error() != GL_ZERO); } static int32_t render_texture_framebuffer_set_texture(render_texture* rt, @@ -202,21 +202,21 @@ static int32_t render_texture_framebuffer_set_texture(render_texture* rt, return -1; gl_state_bind_framebuffer(rt->fbos[level]); - glGetError(); + gl_state_get_error(); if (color_texture) { glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, color_texture, level); - glGetError(); + gl_state_get_error(); glDrawBuffer(GL_COLOR_ATTACHMENT0); glReadBuffer(GL_COLOR_ATTACHMENT0); } else { glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, 0, 0); - glGetError(); + gl_state_get_error(); glDrawBuffer(GL_ZERO); glReadBuffer(GL_ZERO); } - glGetError(); + gl_state_get_error(); if (level == 0) { if (stencil) { @@ -245,13 +245,13 @@ static int32_t render_texture_framebuffer_set_texture(render_texture* rt, glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, 0, 0); } - glGetError(); + gl_state_get_error(); } int32_t ret = 0; if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) ret = -1; gl_state_bind_framebuffer(0); - glGetError(); + gl_state_get_error(); return ret; } diff --git a/src/CRE/resolution_mode.cpp b/src/CRE/resolution_mode.cpp index aee855c3..2875dfd4 100644 --- a/src/CRE/resolution_mode.cpp +++ b/src/CRE/resolution_mode.cpp @@ -5,34 +5,124 @@ #include "resolution_mode.hpp" -const resolution_table_struct resolution_table[] = { - { 320, 240, 0, 0, 0, 320, 225 }, - { 640, 480, 0, 0, 60, 640, 360 }, - { 800, 600, 0, 0, 75, 800, 450 }, - { 1024, 768, 0, 0, 96, 1024, 576 }, - { 1280, 1024, 1, 0, 152, 1280, 720 }, - { 1400, 1050, 0, 0, 131, 1400, 788 }, - { 1600, 1200, 0, 0, 150, 1600, 900 }, - { 800, 480, 2, 0, 15, 800, 450 }, - { 1024, 600, 2, 0, 12, 1024, 576 }, - { 1280, 768, 2, 0, 24, 1280, 720 }, - { 1360, 768, 3, 0, 2, 1360, 765 }, - { 1920, 1200, 2, 0, 60, 1920, 1200 }, - { 2560, 1536, 2, 0, 48, 2560, 1440 }, - { 1280, 720, 3, 0, 0, 1280, 720 }, - { 1920, 1080, 3, 0, 0, 1920, 1080 }, - { 2560, 1440, 3, 0, 0, 2560, 1440 }, - { 480, 272, 3, 0, 0, 480, 272 }, - { 960, 544, 3, 0, 0, 960, 544 }, +struct resolution_mode_scale_data { + vec2 scale; + vec2 src_res; + vec2 dst_res; + resolution_mode src_mode; + resolution_mode dst_mode; }; +const resolution_table_struct resolution_table[] = { + { 320, 240, 0, 0, 0, 320, 225 }, // QVGA + { 640, 480, 0, 0, 60, 640, 360 }, // VGA + { 800, 600, 0, 0, 75, 800, 450 }, // SVGA + { 1024, 768, 0, 0, 96, 1024, 576 }, // XGA + { 1280, 1024, 1, 0, 152, 1280, 720 }, // SXGA + { 1400, 1050, 0, 0, 131, 1400, 788 }, // SXGA+ + { 1600, 1200, 0, 0, 150, 1600, 900 }, // UXGA + { 800, 480, 2, 0, 15, 800, 450 }, // WVGA + { 1024, 600, 2, 0, 12, 1024, 576 }, // WSVGA + { 1280, 768, 2, 0, 24, 1280, 720 }, // WXGA + { 1360, 768, 3, 0, 2, 1360, 765 }, // FWXGA + { 1920, 1200, 2, 0, 60, 1920, 1200 }, // WUXGA + { 2560, 1536, 2, 0, 48, 2560, 1440 }, // WQXGA + { 1280, 720, 3, 0, 0, 1280, 720 }, // HD + { 1920, 1080, 3, 0, 0, 1920, 1080 }, // FHD + { 2560, 1440, 3, 0, 0, 2560, 1440 }, // QHD + { 480, 272, 3, 0, 0, 480, 272 }, // WQVGA + { 960, 544, 3, 0, 0, 960, 544 }, // qHD + + // MM+ + /*{ 320, 240, 0, 0, 0, 320, 225 }, // QVGA + { 640, 480, 0, 0, 60, 640, 360 }, // VGA + { 800, 600, 0, 0, 75, 800, 450 }, // SVGA + { 1024, 768, 0, 0, 96, 1024, 576 }, // XGA + { 1280, 1024, 1, 0, 152, 1280, 720 }, // SXGA + { 1400, 1050, 0, 0, 131, 1400, 788 }, // SXGA+ + { 1600, 1200, 0, 0, 150, 1600, 900 }, // UXGA + { 800, 480, 2, 0, 15, 800, 450 }, // WVGA + { 1024, 600, 2, 0, 12, 1024, 576 }, // WSVGA + { 1280, 768, 2, 0, 24, 1280, 720 }, // WXGA + { 1360, 768, 3, 0, 2, 1360, 765 }, // FWXGA + { 1920, 1200, 2, 0, 60, 1920, 1200 }, // WUXGA + { 2560, 1536, 2, 0, 48, 2560, 1440 }, // WQXGA + { 1280, 720, 3, 0, 0, 1280, 720 }, // HD + { 1920, 1080, 3, 0, 0, 1920, 1080 }, // FHD + { 3840, 2160, 3, 0, 0, 3840, 2160 }, // UHD + { 3840, 2160, 3, 0, 0, 2880, 1620 }, // 3K at UHD + { 2880, 1620, 3, 0, 0, 2880, 1620 }, // 3K + { 2560, 1440, 3, 0, 0, 2560, 1440 }, // QHD + { 480, 272, 3, 0, 0, 480, 272 }, // WQVGA + { 960, 544, 3, 0, 0, 960, 544 }, // qHD + { 1152, 864, 0, 0, 0, 1152, 864 }, // XGA+ + { 1176, 664, 3, 0, 0, 1176, 664 }, // 1176x664 + { 1200, 960, 1, 0, 0, 1200, 960 }, // 1200x960 + { 1280, 800, 2, 0, 0, 1280, 800 }, // WXGA1280x900 + { 1280, 960, 0, 0, 0, 1280, 960 }, // SXGA- + { 1366, 768, 3, 0, 0, 1366, 768 }, // FWXGA1366x766 + { 1440, 900, 2, 0, 0, 1440, 900 }, // WXGA+ + { 1600, 900, 0, 0, 0, 1600, 900 }, // HD+ + { 1600, 1024, 2, 0, 0, 1600, 1024 }, // WSXGA + { 1680, 1050, 2, 0, 0, 1680, 1050 }, // WSXGA+ + { 1920, 1440, 0, 0, 0, 1920, 1440 }, // 1920x1440 + { 2048, 1152, 0, 0, 0, 2048, 1152 }, // QWXGA*/ +}; + +resolution_struct res_window; +resolution_struct res_window_internal; + +resolution_struct::resolution_struct(::resolution_mode mode) { + resolution_mode = mode; + x_offset = 0; + y_offset = 0; + if (mode == RESOLUTION_MODE_MAX) { + width = res_window.width; + height = res_window.height; + aspect = res_window.aspect; + field_20 = res_window.field_20; + } + else { + width = resolution_table[mode].width_full; + height = resolution_table[mode].height_full; + aspect = (double_t)width / (double_t)height; + field_20 = resolution_table[mode].field_8; + } +} + +resolution_struct* res_window_get() { + return &res_window; +} + +resolution_struct* res_window_internal_get() { + return &res_window_internal; +} + +void res_window_set(resolution_mode mode) { + res_window = resolution_struct(mode); + + int32_t width = resolution_table[mode].width; + int32_t height = resolution_table[mode].height; + + res_window_internal.resolution_mode = RESOLUTION_MODE_MAX; + res_window_internal.x_offset = resolution_table[mode].x_offset; + res_window_internal.y_offset = resolution_table[mode].y_offset; + res_window_internal.width = width; + res_window_internal.height = height; + res_window_internal.aspect = (double_t)width / (double_t)height; + res_window_internal.field_20 = 4; + + for (int32_t i = 0; i < RESOLUTION_MODE_MAX; i++) + if (resolution_table[i].width_full == width && resolution_table[i].height_full == height) { + res_window_internal.resolution_mode = (resolution_mode)i; + res_window_internal.field_20 = resolution_table[i].field_8; + } +} + vec2 resolution_mode_get_scale(const resolution_mode dst_mode, const resolution_mode src_mode) { - if (dst_mode == RESOLUTION_MODE_END - || src_mode == RESOLUTION_MODE_END - || dst_mode < RESOLUTION_MODE_QVGA - || src_mode < RESOLUTION_MODE_QVGA - || dst_mode >= RESOLUTION_MODE_END - || src_mode >= RESOLUTION_MODE_END) + if (dst_mode == RESOLUTION_MODE_MAX || src_mode == RESOLUTION_MODE_MAX + || dst_mode < RESOLUTION_MODE_QVGA || src_mode < RESOLUTION_MODE_QVGA + || dst_mode >= RESOLUTION_MODE_MAX || src_mode >= RESOLUTION_MODE_MAX) return 1.0f; float_t scale_x = (float_t)resolution_table[dst_mode].width_full / (float_t)resolution_table[src_mode].width_full; @@ -60,12 +150,9 @@ vec2 resolution_mode_get_scale(const resolution_mode dst_mode, const resolution_ void resolution_mode_scale_pos(vec2& dst_pos, const resolution_mode dst_mode, const vec2& src_pos, const resolution_mode src_mode) { - if (dst_mode == RESOLUTION_MODE_END - || src_mode == RESOLUTION_MODE_END - || dst_mode < RESOLUTION_MODE_QVGA - || src_mode < RESOLUTION_MODE_QVGA - || dst_mode >= RESOLUTION_MODE_END - || src_mode >= RESOLUTION_MODE_END) { + if (dst_mode == RESOLUTION_MODE_MAX || src_mode == RESOLUTION_MODE_MAX + || dst_mode < RESOLUTION_MODE_QVGA || src_mode < RESOLUTION_MODE_QVGA + || dst_mode >= RESOLUTION_MODE_MAX || src_mode >= RESOLUTION_MODE_MAX) { dst_pos = src_pos; return; } diff --git a/src/CRE/resolution_mode.hpp b/src/CRE/resolution_mode.hpp index 0ecba4ed..5d7fc331 100644 --- a/src/CRE/resolution_mode.hpp +++ b/src/CRE/resolution_mode.hpp @@ -27,8 +27,43 @@ enum resolution_mode { RESOLUTION_MODE_QHD = 0x0F, RESOLUTION_MODE_WQVGA = 0x10, RESOLUTION_MODE_qHD = 0x11, - RESOLUTION_MODE_END = 0x12, - RESOLUTION_MODE_13 = 0x13, + RESOLUTION_MODE_MAX = 0x12, + + // MM+ + /*RESOLUTION_MODE_QVGA = 0x00, + RESOLUTION_MODE_VGA = 0x01, + RESOLUTION_MODE_SVGA = 0x02, + RESOLUTION_MODE_XGA = 0x03, + RESOLUTION_MODE_SXGA = 0x04, + RESOLUTION_MODE_SXGAPlus = 0x05, + RESOLUTION_MODE_UXGA = 0x06, + RESOLUTION_MODE_WVGA = 0x07, + RESOLUTION_MODE_WSVGA = 0x08, + RESOLUTION_MODE_WXGA = 0x09, + RESOLUTION_MODE_FWXGA = 0x0A, + RESOLUTION_MODE_WUXGA = 0x0B, + RESOLUTION_MODE_WQXGA = 0x0C, + RESOLUTION_MODE_HD = 0x0D, + RESOLUTION_MODE_FHD = 0x0E, + RESOLUTION_MODE_UHD = 0x0F, + RESOLUTION_MODE_3KatUHD = 0x10, + RESOLUTION_MODE_3K = 0x11, + RESOLUTION_MODE_QHD = 0x12, + RESOLUTION_MODE_WQVGA = 0x13, + RESOLUTION_MODE_qHD = 0x14, + RESOLUTION_MODE_XGAPlus = 0x15, + RESOLUTION_MODE_1176x664 = 0x16, + RESOLUTION_MODE_1200x960 = 0x17, + RESOLUTION_MODE_WXGA1280x900 = 0x18, + RESOLUTION_MODE_SXGAMinus = 0x19, + RESOLUTION_MODE_FWXGA1366x768 = 0x1A, + RESOLUTION_MODE_WXGAPlus = 0x1B, + RESOLUTION_MODE_HDPlus = 0x1C, + RESOLUTION_MODE_WSXGA = 0x1D, + RESOLUTION_MODE_WSXGAPlus = 0x1E, + RESOLUTION_MODE_1920x1440 = 0x1F, + RESOLUTION_MODE_QWXGA = 0x20, + RESOLUTION_MODE_MAX = 0x21,*/ }; struct resolution_table_struct { @@ -49,10 +84,19 @@ struct resolution_struct { int32_t height; double_t aspect; int32_t field_20; + + inline resolution_struct() : resolution_struct(RESOLUTION_MODE_MAX) { + + } + + resolution_struct(::resolution_mode mode); }; extern const resolution_table_struct resolution_table[]; +extern resolution_struct* res_window_get(); +extern resolution_struct* res_window_internal_get(); +extern void res_window_set(resolution_mode mode); extern vec2 resolution_mode_get_scale(const resolution_mode dst_mode, const resolution_mode src_mode); extern void resolution_mode_scale_pos(vec2& dst_pos, const resolution_mode dst_mode, const vec2& src_pos, const resolution_mode src_mode); diff --git a/src/CRE/rob/rob.cpp b/src/CRE/rob/rob.cpp index d6165335..7ad618ff 100644 --- a/src/CRE/rob/rob.cpp +++ b/src/CRE/rob/rob.cpp @@ -221,17 +221,6 @@ struct mothead_func_struct { int32_t flags; }; -struct rob_cmn_mottbl_sub_header { - int32_t data_offset; - int32_t field_4; -}; - -struct rob_cmn_mottbl_header { - int32_t chara_count; - int32_t mottbl_indices_count; - int32_t subheaders_offset; -}; - class ReqData { public: chara_index chara_index; @@ -255,6 +244,131 @@ public: virtual void Reset() override; }; +struct rob_cmn_mottbl_sub_header { + int32_t data_offset; + int32_t field_4; +}; + +struct rob_cmn_mottbl_header { + int32_t chara_count; + int32_t mottbl_indices_count; + int32_t subheaders_offset; +}; + +struct rob_chara_age_age_init_data { + vec3 trans; + float_t rot_x; + float_t offset; + float_t gravity; + float_t scale; + float_t rot_speed; + float_t rot_y; + float_t appear; + float_t life_time; +}; + +struct rob_chara_age_age_data { + int32_t index; + int32_t part_id; + vec3 trans; + float_t field_14; + float_t rot_z; + int32_t field_1C; + float_t rot_speed; + float_t gravity; + float_t scale; + float_t alpha; + mat4 mat_scale; + mat4 mat; + mat4 prev_parent_mat; + float_t remaining; + bool alive; + + rob_chara_age_age_data(); + + void reset(); +}; + +struct rob_chara_age_age_object_vertex { + vec3 position; + vec3 normal; + vec4 tangent; + vec2 texcoord; +}; + +struct rob_chara_age_age_object { + obj_set_handler* obj_set_handler; + int32_t obj_index; + int32_t field_C; + int32_t num_vertex; + int32_t num_index; + ::obj obj; + obj_mesh mesh; + obj_sub_mesh sub_mesh; + obj_material_data material[2]; + obj_axis_aligned_bounding_box axis_aligned_bounding_box; + rob_chara_age_age_object_vertex* vertex_data; + int32_t vertex_data_size; + int32_t vertex_array_size; + obj_mesh_vertex_buffer obj_vert_buf; + obj_mesh_index_buffer obj_index_buf; + vec3 trans[10]; + int32_t disp_count; + int32_t count; + bool field_C3C; + + rob_chara_age_age_object(); + + void calc_vertex(rob_chara_age_age_object_vertex*& vtx_data, + obj_mesh* mesh, const mat4& mat, float_t alpha); + void disp(render_context* rctx, size_t chara_index, + bool npr, bool reflect, const vec3& a5, bool chara_color); + bool get_obj_set_handler_object_index(object_info obj_info); + ::obj* get_obj_set_obj(); + std::vector* get_obj_set_texture(); + void load(object_info obj_info, int32_t count); + void reset(); + void update(rob_chara_age_age_data* data, int32_t count, float_t alpha); + + static obj_bounding_sphere combine_bounding_spheres( + obj_bounding_sphere* src0, obj_bounding_sphere* src1); +}; + +struct rob_chara_age_age { + rob_chara_age_age_data data[10]; + float_t frame; + float_t field_9B4; + mat4 mat; + float_t step; + bool visible; + bool skip; + float_t move_cancel; + float_t alpha; + rob_chara_age_age_object object; + bool npr; + float_t rot_speed; + bool step_full; + + rob_chara_age_age(); + ~rob_chara_age_age(); + + void ctrl(mat4& mat); + void ctrl_data(rob_chara_age_age_data* data, mat4& mat); + void ctrl_skip(); + void disp(render_context* rctx, size_t chara_id, + bool npr, bool reflect, const vec3& a5, bool chara_color); + void load(object_info obj_info, rob_chara_age_age_data* data, int32_t count); + void reset(); + void set_alpha(float_t value); + void set_disp(bool value); + void set_skip(); + void set_move_cancel(float_t value); + void set_npr(bool value); + void set_rot_speed(float_t value); + void set_step(float_t value); + void set_step_full(); +}; + struct osage_set_motion { int32_t motion_id; std::vector> frames; @@ -809,6 +923,30 @@ static void rob_disp_rob_chara_free(rob_chara* rob_chr); static void rob_motion_modifier_rob_chara_ctrl(rob_chara* rob_chr); +static void rob_chara_age_age_ctrl(rob_chara_age_age* arr, + int32_t chara_id, int32_t part_id, mat4& mat); +static void rob_chara_age_age_disp(rob_chara_age_age* arr, + render_context* rctx, int32_t chara_id, bool reflect, bool chara_color); +static void rob_chara_age_age_load(rob_chara_age_age* arr, + int32_t chara_id, int32_t part_id); +static void rob_chara_age_age_reset(rob_chara_age_age* arr, int32_t chara_id); +static void rob_chara_age_age_set_alpha(rob_chara_age_age* arr, + int32_t chara_id, int32_t part_id, float_t value); +static void rob_chara_age_age_set_disp(rob_chara_age_age* arr, + int32_t chara_id, int32_t part_id, bool value); +static void rob_chara_age_age_set_move_cancel(rob_chara_age_age* arr, + int32_t chara_id, int32_t part_id, float_t value); +static void rob_chara_age_age_set_npr(rob_chara_age_age* arr, + int32_t chara_id, int32_t part_id, bool value); +static void rob_chara_age_age_set_rot_speed(rob_chara_age_age* arr, + int32_t chara_id, int32_t part_id, float_t value); +static void rob_chara_age_age_set_skip(rob_chara_age_age* arr, + int32_t chara_id, int32_t part_id); +static void rob_chara_age_age_set_step(rob_chara_age_age* arr, + int32_t chara_id, int32_t part_id, float_t value); +static void rob_chara_age_age_set_step_full(rob_chara_age_age* arr, + int32_t chara_id, int32_t part_id); + static void rob_chara_bone_data_calculate_bones(rob_chara_bone_data* rob_bone_data, const std::vector* bones); static void rob_chara_bone_data_eyes_xrot_adjust(rob_chara_bone_data* rob_bone_data, @@ -882,7 +1020,7 @@ static void rob_chara_bone_data_set_rot_y(rob_chara_bone_data* rob_bone_data, fl static void rob_chara_bone_data_set_step(rob_chara_bone_data* rob_bone_data, float_t step); static void rob_chara_bone_data_update(rob_chara_bone_data* rob_bone_data, mat4* mat); -static bool rob_chara_check_for_ageageagain_module(chara_index chara_index, int32_t module_index); +static void rob_chara_age_age_ctrl(rob_chara* rob_chr, int32_t part_id, const char* name); static object_info rob_chara_get_head_object(rob_chara* rob_chr, int32_t head_object_id); static object_info rob_chara_get_object_info(rob_chara* rob_chr, item_id id); static void rob_chara_load_default_motion(rob_chara* rob_chr, @@ -914,6 +1052,7 @@ OpdMakeManager* opd_make_manager; OpdMaker* opd_maker_array; PvOsageManager* pv_osage_manager_array; rob_cmn_mottbl_header* rob_cmn_mottbl_data; +rob_chara_age_age* rob_chara_age_age_array; RobThreadHandler* rob_thread_handler; TaskRobLoad* task_rob_load; TaskRobManager* task_rob_manager; @@ -1948,6 +2087,32 @@ static const skeleton_rotation_offset skeleton_rotation_offset_array[] = { { 0, 1, 1, { 0.0f, 0.0f, 0.0f }, }, }; +const rob_chara_age_age_init_data rob_chara_age_age_init_data_left[] = { + { { 0.277f, 0.04f, 0.028f }, 4.65f, 0.115f, 0.0027f, 1.30f, 0.01f, 0.0f, 0.0f, 90.0f }, + { { 0.265f, 0.04f, -0.080f }, 4.25f, 0.070f, 0.0025f, 1.40f, -0.01f, 0.0f, 20.0f, 90.0f }, + { { 0.220f, 0.04f, 0.065f }, 4.60f, 0.119f, 0.0028f, 1.10f, 0.01f, 0.0f, 40.0f, 90.0f }, + { { 0.175f, 0.04f, -0.105f }, 4.20f, 0.049f, 0.0025f, 0.80f, 0.02f, 0.0f, 60.0f, 90.0f }, + { { 0.275f, 0.04f, -0.013f }, 4.30f, 0.112f, 0.0025f, 0.75f, 0.01f, 0.0f, 80.0f, 90.0f }, + { { 0.277f, 0.04f, 0.028f }, 4.65f, 0.115f, 0.0027f, 1.30f, 0.01f, 0.0f, 100.0f, 90.0f }, + { { 0.265f, 0.04f, -0.080f }, 4.25f, 0.070f, 0.0025f, 1.40f, -0.01f, 0.0f, 120.0f, 90.0f }, + { { 0.220f, 0.04f, 0.065f }, 4.60f, 0.119f, 0.0028f, 1.10f, -0.02f, 0.0f, 140.0f, 90.0f }, + { { 0.175f, 0.04f, -0.105f }, 4.20f, 0.049f, 0.0025f, 0.80f, 0.02f, 0.0f, 160.0f, 90.0f }, + { { 0.275f, 0.04f, -0.013f }, 4.30f, 0.112f, 0.0025f, 0.75f, -0.01f, 0.0f, 180.0f, 90.0f }, +}; + +const rob_chara_age_age_init_data rob_chara_age_age_init_data_right[] = { + { { 0.220f, 0.00f, 0.070f }, 1.70f, 0.160f, 0.0028f, 1.10f, -0.02f, 0.0f, 0.0f, 90.0f }, + { { 0.175f, 0.00f, -0.067f }, 2.23f, 0.095f, 0.0025f, 0.80f, 0.02f, 0.0f, 20.0f, 90.0f }, + { { 0.277f, 0.00f, -0.035f }, 1.80f, 0.147f, 0.0025f, 0.75f, 0.01f, 0.0f, 40.0f, 90.0f }, + { { 0.278f, 0.01f, 0.055f }, 1.78f, 0.170f, 0.0027f, 1.30f, -0.01f, 0.0f, 60.0f, 90.0f }, + { { 0.264f, 0.00f, -0.040f }, 2.20f, 0.124f, 0.0025f, 1.40f, 0.01f, 0.0f, 80.0f, 90.0f }, + { { 0.220f, 0.00f, 0.070f }, 1.70f, 0.160f, 0.0028f, 1.10f, 0.01f, 0.0f, 100.0f, 90.0f }, + { { 0.175f, 0.00f, -0.067f }, 2.23f, 0.095f, 0.0025f, 0.80f, -0.02f, 0.0f, 120.0f, 90.0f }, + { { 0.277f, 0.00f, -0.035f }, 1.80f, 0.147f, 0.0025f, 0.75f, -0.01f, 0.0f, 140.0f, 90.0f }, + { { 0.278f, 0.01f, 0.055f }, 1.78f, 0.170f, 0.0027f, 1.30f, -0.01f, 0.0f, 160.0f, 90.0f }, + { { 0.264f, 0.00f, -0.040f }, 2.20f, 0.124f, 0.0025f, 1.40f, 0.01f, 0.0f, 180.0f, 90.0f }, +}; + extern render_context* rctx_ptr; extern uint32_t cmn_set_id; @@ -2039,6 +2204,9 @@ void rob_init() { if (!pv_osage_manager_array) pv_osage_manager_array = new PvOsageManager[ROB_CHARA_COUNT]; + if (!rob_chara_age_age_array) + rob_chara_age_age_array = new rob_chara_age_age[18]; + if (!rob_chara_array) rob_chara_array = new rob_chara[ROB_CHARA_COUNT]; @@ -2091,6 +2259,11 @@ void rob_free() { rob_chara_array = 0; } + if (rob_chara_age_age_array) { + delete[] rob_chara_age_age_array; + rob_chara_age_age_array = 0; + } + if (pv_osage_manager_array) { delete[] pv_osage_manager_array; pv_osage_manager_array = 0; @@ -3495,10 +3668,10 @@ bool rob_chara::set_motion_id(int32_t motion_id, item_equip->item_equip_object[ITEM_TE_L].osage_iterations = 60; item_equip->item_equip_object[ITEM_TE_R].osage_iterations = 60; - /*if (rob_chara_check_for_ageageagain_module(chara_index, module_index)) { - sub_1405430F0(rob_chr->chara_id, 1); - sub_1405430F0(rob_chr->chara_id, 2); - }*/ + if (rob_chara_check_for_ageageagain_module(chara_index, module_index)) { + rob_chara_age_age_array_set_skip(chara_id, 1); + rob_chara_age_age_array_set_skip(chara_id, 2); + } } return true; } @@ -3536,10 +3709,10 @@ void rob_chara::set_mouth_mottbl_motion(int32_t type, void rob_chara::set_osage_move_cancel(uint8_t id, float_t value) { item_equip->set_osage_move_cancel(id, value); - /*if (id <= 1) { - sub_1405436A0(chara_id, 1, value); - sub_1405436A0(chara_id, 2, value); - }*/ + if (id < 2) { + rob_chara_age_age_array_set_move_cancel(chara_id, 1, value); + rob_chara_age_age_array_set_move_cancel(chara_id, 2, value); + } } void rob_chara::set_osage_reset() { @@ -3554,13 +3727,13 @@ void rob_chara::set_parts_disp(item_id id, bool disp) { else if (id == ITEM_MAX) for (int32_t i = ITEM_ATAMA; i <= ITEM_ITEM16; i++) { item_equip->item_equip_object[i].can_disp = disp; - /*if (index == ITEM_ATAMA + if (i == ITEM_ATAMA && rob_chara_check_for_ageageagain_module(chara_index, module_index)) { - sub_140543780(chara_id, 1, disp); - sub_140543780(chara_id, 2, disp); - sub_1405430F0(chara_id, 1); - sub_1405430F0(chara_id, 2); - }*/ + rob_chara_age_age_array_set_disp(chara_id, 1, disp); + rob_chara_age_age_array_set_disp(chara_id, 2, disp); + rob_chara_age_age_array_set_skip(chara_id, 1); + rob_chara_age_age_array_set_skip(chara_id, 2); + } } } @@ -3595,10 +3768,11 @@ void rob_chara::set_visibility(bool value) { data.field_0 &= ~0x01; data.field_3 &= ~0x01; } - /*if (rob_chara_check_for_ageageagain_module(chara_index, module_index)) { - sub_140543780(chara_id, 1, value); - sub_140543780(chara_id, 2, value); - }*/ + + if (rob_chara_check_for_ageageagain_module(chara_index, module_index)) { + rob_chara_age_age_array_set_disp(chara_id, 1, value); + rob_chara_age_age_array_set_disp(chara_id, 2, value); + } } osage_init_data::osage_init_data() : rob_chr() { @@ -4179,12 +4353,10 @@ static void bone_data_parent_data_init(bone_data_parent* bone, rob_chara_bone_data* rob_bone_data, bone_database* bone_data) { const char* base_name = bone_database_skeleton_type_to_string(rob_bone_data->base_skeleton_type); const char* name = bone_database_skeleton_type_to_string(rob_bone_data->skeleton_type); - const std::vector* common_bones = 0; - const std::vector* common_translation = 0; - const std::vector* translation = 0; - if (!bone_data->get_skeleton_bones(base_name, &common_bones) - || !bone_data->get_skeleton_positions(base_name, &common_translation) - || !bone_data->get_skeleton_positions(name, &translation)) + const std::vector* common_bones = bone_data->get_skeleton_bones(base_name); + const std::vector* common_translation = bone_data->get_skeleton_positions(base_name); + const std::vector* translation = bone_data->get_skeleton_positions(name); + if (!common_bones || !common_translation || !translation) return; bone->rob_bone_data = rob_bone_data; @@ -7672,10 +7844,10 @@ static void rob_disp_rob_chara_init(rob_chara* rob_chr, if (rob_chr->item_cos_data.check_for_npr_flag()) rob_chr->item_equip->npr_flag = true; - /*if (rob_chara_check_for_ageageagain_module(rob_chrchara_index, rob_chr->module_index)) { - sub_140542E30(rob_chr->chara_id, 1); - sub_140542E30(rob_chr->chara_id, 2); - }*/ + if (rob_chara_check_for_ageageagain_module(rob_chr->chara_index, rob_chr->module_index)) { + rob_chara_age_age_array_load(rob_chr->chara_id, 1); + rob_chara_age_age_array_load(rob_chr->chara_id, 2); + } } static void rob_disp_rob_chara_ctrl(rob_chara* rob_chr) { @@ -7720,12 +7892,12 @@ static void rob_disp_rob_chara_ctrl_thread_main(rob_chara* rob_chr) { rob_chara_get_trans_scale(rob_chr, 0, &trans); rob_chr->item_equip->position = trans; rob_chara_item_equip_ctrl(rob_chr->item_equip); - /*if (rob_chara_check_for_ageageagain_module(rob_chr->chara_index, rob_chr->module_index)) { - sub_140543520(rob_chr->chara_id, 1, rob_chr->item_equip->step); - sub_14054FC90(rob_chr, 1, "j_tail_l_006_wj"); - sub_140543520(rob_chr->chara_id, 2, rob_chr->item_equip->step); - sub_14054FC90(rob_chr, 2, "j_tail_r_006_wj"); - }*/ + if (rob_chara_check_for_ageageagain_module(rob_chr->chara_index, rob_chr->module_index)) { + rob_chara_age_age_array_set_step(rob_chr->chara_id, 1, rob_chr->item_equip->step); + rob_chara_age_age_ctrl(rob_chr, 1, "j_tail_l_006_wj"); + rob_chara_age_age_array_set_step(rob_chr->chara_id, 2, rob_chr->item_equip->step); + rob_chara_age_age_ctrl(rob_chr, 2, "j_tail_r_006_wj"); + } } static void rob_disp_rob_chara_disp(rob_chara* rob_chr) { @@ -9208,8 +9380,8 @@ static void sub_1404065B0(vec3* a1, std::vector* a2, mat4* a3, float_ bone_database* aft_bone_data = &aft_data->data_ft.bone_data; const char* name = bone_database_skeleton_type_to_string(skeleton_type); - const float_t* heel_height = 0; - if (!aft_bone_data->get_skeleton_heel_height(name, &heel_height)) + const float_t* heel_height = aft_bone_data->get_skeleton_heel_height(name); + if (!heel_height) return; sub_140406920(a1, &a2->data()[a6[0]], &a2->data()[MOTION_BONE_KL_TOE_L_WJ], *heel_height, &a1[0], a4); @@ -9341,6 +9513,82 @@ static void rob_motion_modifier_rob_chara_ctrl(rob_chara* rob_chr) { rob_chara_bone_data_set_right_hand_scale(rob_chr->bone_data, right_hand_scale); } +static void rob_chara_age_age_ctrl(rob_chara_age_age* arr, + int32_t chara_id, int32_t part_id, mat4& mat) { + arr[chara_id * 3 + part_id].ctrl(mat); +} + +static void rob_chara_age_age_disp(rob_chara_age_age* arr, + render_context* rctx, int32_t chara_id, bool reflect, bool chara_color) { + bool npr = !!rctx->render_manager.npr_param; + mat4& view = rctx->camera->view; + vec3 v11 = { view.row0.z, view.row1.z, view.row2.z }; + arr[chara_id * 3 + 0].disp(rctx, chara_id, npr, reflect, v11, chara_color); + arr[chara_id * 3 + 1].disp(rctx, chara_id, npr, reflect, v11, chara_color); + arr[chara_id * 3 + 2].disp(rctx, chara_id, npr, reflect, v11, chara_color); +} + +static void rob_chara_age_age_load(rob_chara_age_age* arr, + int32_t chara_id, int32_t part_id) { + if (part_id != 1 && part_id != 2) + return; + + rob_chara_age_age_data data[10]; + for (rob_chara_age_age_data& i : data) { + i.index = (int32_t)(&i - data); + i.remaining = -1.0; + i.part_id = part_id; + } + + arr[chara_id * 3 + part_id].load({ 0, 3291 }, data, 10); +} + +static void rob_chara_age_age_reset(rob_chara_age_age* arr, int32_t chara_id) { + arr[chara_id * 3 + 0].reset(); + arr[chara_id * 3 + 1].reset(); + arr[chara_id * 3 + 2].reset(); +} + +static void rob_chara_age_age_set_alpha(rob_chara_age_age* arr, + int32_t chara_id, int32_t part_id, float_t value) { + arr[chara_id * 3 + part_id].set_alpha(value); +} + +static void rob_chara_age_age_set_disp(rob_chara_age_age* arr, + int32_t chara_id, int32_t part_id, bool value) { + arr[chara_id * 3 + part_id].set_disp(value); +} + +static void rob_chara_age_age_set_move_cancel(rob_chara_age_age* arr, + int32_t chara_id, int32_t part_id, float_t value) { + arr[chara_id * 3 + part_id].set_move_cancel(value); +} + +static void rob_chara_age_age_set_npr(rob_chara_age_age* arr, + int32_t chara_id, int32_t part_id, bool value) { + arr[chara_id * 3 + part_id].set_npr(value); +} + +static void rob_chara_age_age_set_rot_speed(rob_chara_age_age* arr, + int32_t chara_id, int32_t part_id, float_t value) { + arr[chara_id * 3 + part_id].set_rot_speed(value); +} + +static void rob_chara_age_age_set_skip(rob_chara_age_age* arr, + int32_t chara_id, int32_t part_id) { + arr[chara_id * 3 + part_id].set_skip(); +} + +static void rob_chara_age_age_set_step(rob_chara_age_age* arr, + int32_t chara_id, int32_t part_id, float_t value) { + arr[chara_id * 3 + part_id].set_step(value); +} + +static void rob_chara_age_age_set_step_full(rob_chara_age_age* arr, + int32_t chara_id, int32_t part_id) { + arr[chara_id * 3 + part_id].set_step_full(); +} + static void rob_chara_bone_data_calculate_bones(rob_chara_bone_data* rob_bone_data, const std::vector* bones) { bone_database_bones_calculate_count(bones, &rob_bone_data->object_bone_count, @@ -9424,10 +9672,9 @@ static void rob_chara_bone_data_ik_scale_calculate( bone_database_skeleton_type skeleton_type, bone_database* bone_data) { const char* base_name = bone_database_skeleton_type_to_string(base_skeleton_type); const char* name = bone_database_skeleton_type_to_string(skeleton_type); - const float_t* base_heel_height = 0; - const float_t* heel_height = 0; - if (!bone_data->get_skeleton_heel_height(base_name, &base_heel_height) - || !bone_data->get_skeleton_heel_height(name, &heel_height)) + const float_t* base_heel_height = bone_data->get_skeleton_heel_height(base_name); + const float_t* heel_height = bone_data->get_skeleton_heel_height(name); + if (!base_heel_height || !heel_height) return; ::bone_data* b_cl_mune = &bones->data()[MOTION_BONE_CL_MUNE]; @@ -9451,8 +9698,8 @@ static void rob_chara_bone_data_ik_scale_calculate( static void mot_key_data_reserve_key_sets_by_skeleton_type(mot_key_data* a1, bone_database_skeleton_type type, bone_database* bone_data) { const char* name = bone_database_skeleton_type_to_string(type); - const std::vector* bones = 0; - if (!bone_data->get_skeleton_bones(name, &bones)) + const std::vector* bones = bone_data->get_skeleton_bones(name); + if (!bones) return; mot_key_data_get_key_set_count_by_bone_database_bones(a1, bones); @@ -9530,12 +9777,10 @@ static void rob_chara_bone_data_init_skeleton(rob_chara_bone_data* rob_bone_data return; const char* name = bone_database_skeleton_type_to_string(base_skeleton_type); - const std::vector* bones = 0; - const std::vector* parent_indices = 0; - const std::vector* motion_bones = 0; - if (!bone_data->get_skeleton_bones(name, &bones) - || !bone_data->get_skeleton_parent_indices(name, &parent_indices) - || !bone_data->get_skeleton_motion_bones(name, &motion_bones)) + const std::vector* bones = bone_data->get_skeleton_bones(name); + const std::vector* parent_indices = bone_data->get_skeleton_parent_indices(name); + const std::vector* motion_bones = bone_data->get_skeleton_motion_bones(name); + if (!bones || !parent_indices || !motion_bones) return; rob_chara_bone_data_calculate_bones(rob_bone_data, bones); @@ -10737,8 +10982,14 @@ static void rob_chara_add_motion_reset_data(rob_chara* rob_chr, rob_chr->item_equip->add_motion_reset_data(motion_id, frame, iterations); } -static bool rob_chara_check_for_ageageagain_module(chara_index chara_index, int32_t module_index) { - return chara_index == CHARA_MIKU && module_index == 148; +static void rob_chara_age_age_ctrl(rob_chara* rob_chr, int32_t part_id, const char* name) { + mat4 mat = *rob_chr->item_equip->get_ex_data_bone_node_mat(ITEM_KAMI, name); + if (vec3::length(rob_chr->data.adjust_data.pos_adjust) > 0.000001f) { + mat4 temp; + mat4_translate(&rob_chr->data.adjust_data.pos_adjust, &temp); + mat4_mult(&mat, &temp, &mat); + } + rob_chara_age_age_array_ctrl(rob_chr->chara_id, part_id, mat); } static object_info rob_chara_get_head_object(rob_chara* rob_chr, int32_t head_object_id) { @@ -10919,6 +11170,69 @@ static rob_manager_rob_impl* rob_manager_rob_impls2_get(TaskRobManager* rob_mgr) return rob_manager_rob_impls2; } +void rob_chara_age_age_array_ctrl(int32_t chara_id, int32_t part_id, mat4& mat) { + rob_chara_age_age_ctrl(rob_chara_age_age_array, chara_id, part_id, mat); +} + +void rob_chara_age_age_array_disp(render_context* rctx, + int32_t chara_id, bool reflect, bool chara_color) { + mdl::ObjFlags obj_flags = rctx->disp_manager.get_obj_flags(); + rob_chara_age_age_disp(rob_chara_age_age_array, rctx, chara_id, reflect, chara_color); + rctx->disp_manager.set_obj_flags(obj_flags); +} + +void rob_chara_age_age_array_load(int32_t chara_id, int32_t part_id) { + rob_chara_age_age_load(rob_chara_age_age_array, chara_id, part_id); +} + +void rob_chara_age_age_array_reset(int32_t chara_id) { + rob_chara_age_age_reset(rob_chara_age_age_array, chara_id); +} + +void rob_chara_age_age_array_set_alpha(int32_t chara_id, int32_t part_id, float_t alpha) { + rob_chara_age_age_set_alpha(rob_chara_age_age_array, chara_id, part_id, alpha); +} + +void rob_chara_age_age_array_set_disp(int32_t chara_id, int32_t part_id, bool value) { + rob_chara_age_age_set_disp(rob_chara_age_age_array, chara_id, part_id, value); +} + +void rob_chara_age_age_array_set_move_cancel(int32_t chara_id, int32_t part_id, float_t value) { + rob_chara_age_age_set_move_cancel(rob_chara_age_age_array, chara_id, part_id, value); +} + +void rob_chara_age_age_array_set_npr(int32_t chara_id, int32_t part_id, bool value) { + rob_chara_age_age_set_npr(rob_chara_age_age_array, chara_id, part_id, value); +} + +void rob_chara_age_age_array_set_params(int32_t chara_id, int32_t part_id, + int32_t npr, int32_t rot_speed, int32_t skip, int32_t disp) { + if (!npr || npr == 1) + rob_chara_age_age_array_set_npr(chara_id, part_id, npr); + if (rot_speed != -1) + rob_chara_age_age_array_set_rot_speed(chara_id, part_id, (float_t)rot_speed * 0.001f); + if (skip != -1) + rob_chara_age_age_array_set_skip(chara_id, part_id); + if (!disp || disp == 1) + rob_chara_age_age_array_set_disp(chara_id, part_id, !!disp); +} + +void rob_chara_age_age_array_set_rot_speed(int32_t chara_id, int32_t part_id, float_t value) { + rob_chara_age_age_set_rot_speed(rob_chara_age_age_array, chara_id, part_id, value); +} + +void rob_chara_age_age_array_set_skip(int32_t chara_id, int32_t part_id) { + rob_chara_age_age_set_skip(rob_chara_age_age_array, chara_id, part_id); +} + +void rob_chara_age_age_array_set_step(int32_t chara_id, int32_t part_id, float_t step) { + rob_chara_age_age_set_step(rob_chara_age_age_array, chara_id, part_id, step); +} + +void rob_chara_age_age_array_set_step_full(int32_t chara_id, int32_t part_id) { + rob_chara_age_age_set_step_full(rob_chara_age_age_array, chara_id, part_id); +} + bool rob_chara_array_check_visibility(int32_t chara_id) { if (rob_chara_pv_data_array_check_chara_id(chara_id)) return rob_chara_array[chara_id].is_visible(); @@ -10995,10 +11309,10 @@ void rob_chara_array_set_alpha_obj_flags(int32_t chara_id, float_t alpha, mdl::O rob_chr->item_equip->set_alpha_obj_flags(alpha, flags); - /*if (rob_chara_check_for_ageageagain_module(rob_chr->chara_index, rob_chr->module_index)) { - sub_140543120(chara_id, 1, alpha); - sub_140543120(chara_id, 2, alpha); - }*/ + if (rob_chara_check_for_ageageagain_module(rob_chr->chara_index, rob_chr->module_index)) { + rob_chara_age_age_array_set_alpha(chara_id, 1, alpha); + rob_chara_age_age_array_set_alpha(chara_id, 2, alpha); + } } bool pv_osage_manager_array_get_disp() { @@ -11027,6 +11341,10 @@ int32_t rob_chara_array_reset_pv_data(int32_t chara_id) { return chara_id; } +bool rob_chara_check_for_ageageagain_module(chara_index chara_index, int32_t module_index) { + return chara_index == CHARA_MIKU && module_index == 148; +} + bool rob_chara_pv_data_array_check_chara_id(int32_t chara_id) { return rob_chara_pv_data_array[chara_id].type != ROB_CHARA_TYPE_NONE; } @@ -12043,6 +12361,17 @@ bone_node* rob_chara_item_equip_object::get_bone_node(const char* name, bone_dat return get_bone_node(get_bone_index(name, bone_data)); } +const mat4* rob_chara_item_equip_object::get_ex_data_bone_node_mat(const char* name) { + if (!name || !ex_data_bone_nodes.size()) + return &mat4_identity; + + for (bone_node& i : ex_data_bone_nodes) + if (!str_utils_compare(i.name, name)) + return i.mat; + + return &mat4_identity; +} + RobOsageNode* rob_chara_item_equip_object::get_normal_ref_osage_node(std::string& name, size_t* index) { if (!name.size()) return 0; @@ -12673,9 +13002,9 @@ void rob_chara_item_equip::disp(int32_t chara_id, render_context* rctx) { disp_manager.set_texture_color_coefficients(texture_color_coefficients); disp_manager.set_wet_param(wet); - //rctx->render_manager.field_31C |= field_F9; + rctx->render_manager.field_31C |= npr_flag; sub_140512C20(this, rctx); - //sub_1405421D0(chara_id, rctx->chara_reflect, chara_color); + rob_chara_age_age_array_disp(rctx, chara_id, rctx->chara_reflect, chara_color); if (item_equip_range) for (int32_t i = first_item_equip_object; i < max_item_equip_object; i++) @@ -12727,6 +13056,10 @@ void rob_chara_item_equip::get_parent_bone_nodes(bone_node* bone_nodes, bone_dat item_equip_object[i].get_parent_bone_nodes(bone_nodes, bone_data); } +const mat4* rob_chara_item_equip::get_ex_data_bone_node_mat(item_id id, const char* name) { + return item_equip_object[id].get_ex_data_bone_node_mat(name); +} + void rob_chara_item_equip::load_object_info(object_info obj_info, item_id id, bool osage_reset, bone_database* bone_data, void* data, object_database* obj_db) { if (id < ITEM_BODY || id > ITEM_ITEM16 || !bone_nodes) @@ -16066,8 +16399,7 @@ bool OpdMakeManager::Ctrl() { motion_set_ids.push_back(set_id); } - prj::sort(motion_set_ids); - prj::unique(motion_set_ids); + prj::sort_unique(motion_set_ids); for (uint32_t& i : motion_set_ids) { motion_set_load_motion(i, 0, aft_mot_db); @@ -16237,6 +16569,605 @@ void ReqDataObj::Reset() { cos = {}; } +rob_chara_age_age_data::rob_chara_age_age_data() : part_id(), field_14(), +rot_z(), field_1C(), rot_speed(), gravity(), alpha(), alive() { + index = -1; + scale = 1.0f; + remaining = -1.0f; +} + +void rob_chara_age_age_data::reset() { + index = -1; + part_id = 0; + trans = 0.0f; + field_14 = 0.0f; + rot_z = 0.0f; + field_1C = 0; + rot_speed = 0.0f; + gravity = 0.0f; + scale = 1.0f; + alpha = 0.0f; + mat_scale = mat4_null; + mat = mat4_null; + prev_parent_mat; + remaining = -1.0f; + alive = false; +} + +rob_chara_age_age_object::rob_chara_age_age_object() : obj_set_handler(), +obj_index(), field_C(), num_vertex(), num_index(), vertex_data(), +vertex_data_size(), vertex_array_size(), disp_count(), count(), field_C3C() { + +} + +void rob_chara_age_age_object::calc_vertex(rob_chara_age_age_object_vertex*& vtx_data, + obj_mesh* mesh, const mat4& mat, float_t alpha) { + const float_t alpha_1 = 1.0f - alpha; + + obj_vertex_data* vertex_array = mesh->vertex_array; + uint32_t num_vertex = mesh->num_vertex; + obj_vertex_data* obj_vtx = vertex_array; + rob_chara_age_age_object_vertex* vtx = vtx_data; + for (uint32_t i = num_vertex; i; i--, obj_vtx++, vtx++) { + mat4_mult_vec3_trans(&mat, &obj_vtx->position, &vtx->position); + mat4_mult_vec3(&mat, &obj_vtx->normal, &vtx->normal); + mat4_mult_vec3(&mat, (vec3*)&obj_vtx->tangent, (vec3*)&vtx->tangent); + vtx->tangent.w = obj_vtx->tangent.w; + vtx->texcoord.x = obj_vtx->texcoord0.x + alpha_1; + vtx->texcoord.y = obj_vtx->texcoord0.y; + } + vtx_data = vtx; +} + +void rob_chara_age_age_object::disp(render_context* rctx, size_t chara_index, + bool npr, bool reflect, const vec3& a5, bool chara_color) { + int32_t disp_count = this->disp_count; + if (!obj_set_handler || !disp_count) + return; + + disp_count = min_def(disp_count, 10); + + std::pair v44[10]; + for (int32_t i = 0; i < disp_count; i++) { + v44[i].first = vec3::dot(trans[i], a5); + v44[i].second = i; + } + + if (disp_count >= 2) + std::sort(v44, v44 + disp_count, + [](const std::pair& a, const std::pair& b) { + return a.first < b.first; + }); + + obj_vert_buf.cycle_index(); + + GLuint buffer = obj_vert_buf.get_buffer(); + size_t vtx_data; + if (GLAD_GL_VERSION_4_5) { + vtx_data = (size_t)glMapNamedBuffer(buffer, GL_WRITE_ONLY); + if (!vtx_data) { + glUnmapNamedBuffer(buffer); + return; + } + } + else { + gl_state_bind_array_buffer(buffer); + vtx_data = (size_t)glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY); + if (!vtx_data) { + glUnmapBuffer(GL_ARRAY_BUFFER); + gl_state_bind_array_buffer(0); + return; + } + } + + size_t vertex_array_size = this->vertex_array_size; + for (int32_t i = 0; i < disp_count; i++) + memmove((void*)(vtx_data + vertex_array_size * i), + (void*)((size_t)vertex_data + vertex_array_size * v44[i].second), vertex_array_size); + + if (GLAD_GL_VERSION_4_5) + glUnmapNamedBuffer(buffer); + else { + glUnmapBuffer(GL_ARRAY_BUFFER); + gl_state_bind_array_buffer(0); + } + + mesh.num_vertex = disp_count * num_vertex; + sub_mesh.num_index = disp_count * num_index; + sub_mesh.material_index = npr ? 1 : 0; + + mdl::ObjFlags flags = (mdl::ObjFlags)(mdl::OBJ_SSS | mdl::OBJ_4 | mdl::OBJ_SHADOW); + if (reflect) + enum_or(flags, mdl::OBJ_CHARA_REFLECT); + rctx->disp_manager.set_obj_flags(flags); + rctx->disp_manager.set_chara_color(chara_color); + rctx->disp_manager.set_shadow_type(chara_index ? SHADOW_STAGE : SHADOW_CHARA); + rctx->disp_manager.entry_obj_by_obj(&mat4_identity, &obj, + get_obj_set_texture(), &obj_vert_buf, &obj_index_buf, 0, 1.0f); +} + +bool rob_chara_age_age_object::get_obj_set_handler_object_index(object_info obj_info) { + obj_set_handler = object_storage_get_obj_set_handler(obj_info.set_id); + if (!obj_set_handler) + return false; + + auto elem = obj_set_handler->obj_id_data.find(obj_info.id); + if (elem == obj_set_handler->obj_id_data.end()) +return false; + +obj_index = elem->second; +return true; +} + +::obj* rob_chara_age_age_object::get_obj_set_obj() { + return &obj_set_handler->obj_set->obj_data[obj_index]; +} + +std::vector* rob_chara_age_age_object::get_obj_set_texture() { + return &obj_set_handler->gentex; +} + +void rob_chara_age_age_object::load(object_info obj_info, int32_t count) { + reset(); + + this->count = count; + num_vertex = 0; + num_index = 0; + disp_count = 0; + + if (!get_obj_set_handler_object_index(obj_info)) { + obj_index = -1; + obj_set_handler = 0; + return; + } + else { + ::obj* o = get_obj_set_obj(); + if (o->num_mesh != 1 || o->mesh_array[0].num_submesh != 1 + || o->mesh_array[0].submesh_array[0].index_format != OBJ_INDEX_U16) { + obj_index = -1; + obj_set_handler = 0; + return; + } + } + + if (!obj_set_handler) + return; + + ::obj* o = get_obj_set_obj(); + obj_mesh* m = &o->mesh_array[0]; + obj_sub_mesh* sm = &m->submesh_array[0]; + + uint32_t num_vertex = m->num_vertex; + this->num_vertex = num_vertex; + + uint32_t num_index = sm->num_index; + this->num_index = num_index; + + size_t vertex_array_size = sizeof(rob_chara_age_age_object_vertex) * num_vertex; + this->vertex_array_size = (uint32_t)vertex_array_size; + + size_t vertex_data_size = vertex_array_size * count; + this->vertex_data_size = (uint32_t)vertex_data_size; + + rob_chara_age_age_object_vertex* vtx_data = force_malloc_s( + rob_chara_age_age_object_vertex, vertex_data_size); + vertex_data = vtx_data; + + obj_vertex_data* vertex_array = m->vertex_array; + for (int32_t i = count; i > 0; i--) + for (uint32_t j = num_vertex, k = 0; j; j--, k++, vtx_data++) { + vtx_data->position = vertex_array[k].position; + vtx_data->normal = vertex_array[k].normal; + vtx_data->tangent = vertex_array[k].tangent; + vtx_data->texcoord = vertex_array[k].texcoord0; + } + + obj_vert_buf.load_data(vertex_data_size, vertex_data, 2, true); + + this->num_index = num_index + 1; + uint32_t num_idx_data = (uint32_t)(count * (num_index + 1)); + + uint16_t* idx_data = force_malloc_s(uint16_t, num_idx_data); + uint32_t* index_array = sm->index_array; + uint32_t index_offset = 0; + uint32_t l = 0; + for (int32_t i = count; i > 0; i--) { + for (uint32_t j = num_index, k = 0; j; j--, k++) + if (index_array[k] == 0xFFFFFFFF) + idx_data[l++] = 0xFFFF; + else + idx_data[l++] = (uint16_t)(index_offset + index_array[k]); + idx_data[l++] = 0xFFFF; + index_offset += num_vertex; + } + obj_index_buf.load_data(sizeof(uint16_t) * num_idx_data, idx_data); + free_def(idx_data); + + material[0] = o->material_array[0]; + material[1] = o->material_array[0]; + material[1].material.attrib.m.alpha_texture = 0; + material[1].material.attrib.m.alpha_material = 0; + + obj.bounding_sphere = o->bounding_sphere; + obj.mesh_array = &mesh; + obj.num_mesh = 1; + obj.material_array = material; + obj.num_material = 2; + obj.flags = o->flags; + memmove(obj.reserved, o->reserved, sizeof(uint32_t) * 10); + obj.skin = 0; + obj.name = o->name; + obj.id = o->id; + obj.hash = o->hash; + + mesh.flags = m->flags; + mesh.bounding_sphere = m->bounding_sphere; + mesh.num_submesh = 1; + mesh.submesh_array = &sub_mesh; + mesh.vertex_format = (obj_vertex_format)(OBJ_VERTEX_POSITION | OBJ_VERTEX_NORMAL + | OBJ_VERTEX_TANGENT | OBJ_VERTEX_TEXCOORD0 | OBJ_VERTEX_TEXCOORD1); + mesh.size_vertex = sizeof(rob_chara_age_age_object_vertex); + mesh.num_vertex = m->num_vertex; + mesh.vertex_array = 0; + mesh.attrib = m->attrib; + memmove(mesh.reserved, m->reserved, sizeof(uint32_t) * 6); + memmove(mesh.name, m->name, 0x40); + + sub_mesh.flags = sm->flags; + sub_mesh.material_index = 0; + sub_mesh.bounding_sphere = sm->bounding_sphere; + memmove(sub_mesh.uv_index, sm->uv_index, sizeof(uint8_t) * 8); + sub_mesh.bone_index_array = 0; + sub_mesh.num_bone_index = 0; + sub_mesh.bones_per_vertex = 0; + sub_mesh.primitive_type = sm->primitive_type; + sub_mesh.index_format = OBJ_INDEX_U16; + sub_mesh.index_array = sm->index_array; + sub_mesh.num_index = num_idx_data; + sub_mesh.attrib = sm->attrib; + sub_mesh.axis_aligned_bounding_box = sm->axis_aligned_bounding_box; + sub_mesh.first_index = 0; + sub_mesh.last_index = (uint16_t)((size_t)num_vertex * count); + sub_mesh.index_offset = 0; + + axis_aligned_bounding_box = sm->axis_aligned_bounding_box; +} + +void rob_chara_age_age_object::reset() { + obj_index_buf.unload(); + obj_vert_buf.unload(); + + if (vertex_data) { + free(vertex_data); + vertex_data = 0; + } + + vertex_data_size = 0; + num_vertex = 0; + num_index = 0; + obj_set_handler = 0; + obj_index = -1; +} + +void rob_chara_age_age_object::update(rob_chara_age_age_data* data, int32_t count, float_t alpha) { + if (!obj_set_handler) + return; + + ::obj* o = get_obj_set_obj(); + obj_mesh* m = &o->mesh_array[0]; + obj_sub_mesh* sm = &m->submesh_array[0]; + + rob_chara_age_age_object_vertex* vtx_data = vertex_data; + + int32_t disp_count = 0; + float_t scale = 0.0f; + for (int32_t i = count; i > 0; i--, data++) + if (data->remaining >= 0.0f && data->alive) { + calc_vertex(vtx_data, m, data->mat_scale, alpha * data->alpha); + mat4_get_translation(&data->mat_scale, &trans[disp_count]); + scale = max_def(scale, data->scale); + disp_count++; + } + this->disp_count = disp_count; + + if (disp_count < 1) + return; + + float_t radius = scale * sm->bounding_sphere.radius; + + obj_bounding_sphere v75; + v75.center = trans[0]; + v75.radius = radius; + + for (int32_t i = 1; i < disp_count; i++) { + obj_bounding_sphere v74; + v74.center = trans[i]; + v74.radius = radius; + v75 = combine_bounding_spheres(&v75, &v74); + } + + sub_mesh.bounding_sphere = v75; + mesh.bounding_sphere = v75; + obj.bounding_sphere = v75; + + vec3 min = trans[0] - radius; + vec3 max = trans[0] + radius; + for (int32_t i = 1; i < disp_count; i++) { + min = vec3::min(min, trans[i] - radius); + max = vec3::max(max, trans[i] + radius); + } + sub_mesh.axis_aligned_bounding_box.center = (max + min) * 0.5f; + sub_mesh.axis_aligned_bounding_box.size = (max - min) * 0.5f; +} + +obj_bounding_sphere rob_chara_age_age_object::combine_bounding_spheres( + obj_bounding_sphere* src0, obj_bounding_sphere* src1) { + float_t radius_diff = src1->radius - src0->radius; + float_t dist = vec3::distance_squared(src0->center, src1->center); + if (dist >= radius_diff * radius_diff) { + if (dist > 0.0f) { + dist = sqrtf(dist); + + return { + (src1->center - src0->center) * ((src1->radius - src0->radius + + dist) * 0.5f / dist) + src0->center, + (src1->radius + src0->radius + dist) * 0.5f + }; + } + else + return { src0->center, max_def(src1->radius, src0->radius) }; + } + else { + if (src0->radius >= src1->radius) + return *src0; + else + return *src1; + } +} + +rob_chara_age_age::rob_chara_age_age() { + frame = 0.0f; + field_9B4 = 0.1f; + step = 1.0f; + visible = true; + skip = false; + move_cancel = 0.0f; + alpha = 1.0f; + npr = false; + rot_speed = 1.0f; + step_full = false; +} + +rob_chara_age_age::~rob_chara_age_age() { + object.reset(); +} + +void rob_chara_age_age::ctrl(mat4& mat) { + bool found = false; + for (rob_chara_age_age_data& i : data) + if (i.index != -1) { + found = true; + break; + } + + if (!found) + return; + + float_t step = this->step; + float_t move_cancel = this->move_cancel; + frame += step; + + vec3 trans[2]; + mat4_get_translation(&mat, &trans[0]); + mat4_get_translation(&this->mat, &trans[1]); + this->mat = mat; + + if (vec3::distance(trans[0], trans[1]) > 0.2f) + frame += step * 2.0f; + + if (step_full) { + this->step = 1.0f; + this->move_cancel = 1.0f; + } + + for (rob_chara_age_age_data& j : data) + if (j.part_id == 1 || j.part_id == 2) { + if (frame >= 200.0f) + frame = 0.0f; + + ctrl_data(&j, mat); + } + + if (step_full) { + this->step = step; + this->move_cancel = move_cancel; + step_full = false; + } + + if (skip) { + ctrl_skip(); + skip = false; + } + + object.update(data, 10, alpha); +} + +void rob_chara_age_age::ctrl_data(rob_chara_age_age_data* data, mat4& mat) { + const rob_chara_age_age_init_data* init_data; + if (data->part_id == 1) + init_data = &rob_chara_age_age_init_data_left[data->index]; + else if (data->part_id == 2) + init_data = &rob_chara_age_age_init_data_right[data->index]; + else + return; + + float_t step = skip ? 1.0f : this->step; + if (data->remaining < 0.0f) { + if (frame >= init_data->appear && frame < init_data->appear + 90.0f) { + data->alpha = 0.0f; + data->mat = mat; + data->remaining = init_data->life_time; + + vec3 trans[2]; + mat4_get_translation(&mat, &trans[0]); + mat4_get_translation(&data->prev_parent_mat, &trans[1]); + + vec3 v15 = (trans[0] - trans[1]) * (move_cancel - 1.0f); + if (vec3::length(v15) <= 1.0f) { + data->trans = v15; + data->field_14 = 0.0f; + data->rot_z = data->part_id == 1 ? -0.1f : 0.1f; + data->field_1C = 0; + data->rot_speed = init_data->rot_speed; + mat4_translate_mult(&data->mat, &init_data->trans, &data->mat); + mat4_rotate_x_mult(&data->mat, init_data->rot_x, &data->mat); + mat4_translate_mult(&data->mat, 0.0f, 0.0f, init_data->offset, &data->mat); + data->scale = init_data->scale; + mat4_scale_rot(&data->mat, data->scale, &data->mat_scale); + data->alive = true; + data->gravity = init_data->gravity; + } + else + data->alive = false; + } + } + else if (data->alive) { + if (data->remaining < 70.0f) + data->rot_z += step * data->rot_speed * rot_speed; + data->trans.x += (90.0f - data->remaining) * (float_t)(1.0 / 90.0) + * data->gravity * 2.5f * step * rot_speed; + data->trans.z -= (90.0f - data->remaining) * 0.000011f * step * rot_speed; + + mat4 m; + mat4_translate_mult(&mat, &init_data->trans, &m); + mat4_rotate_x_mult(&m, init_data->rot_x, &m); + mat4_translate_mult(&m, 0.0f, 0.0f, init_data->offset, &m); + mat4_rotate_y_mult(&m, init_data->rot_y, &m); + mat4_translate_mult(&m, &data->trans, &m); + mat4_rotate_z_mult(&m, data->rot_z, &m); + mat4_scale_rot(&m, data->scale, &m); + + vec3 v43; + mat4_get_translation(&m, &v43); + + vec3 v46; + mat4_get_translation(&data->mat_scale, &v46); + + v43 = (v43 - v46) * min_def(step, 1.0f); + + float_t v28 = vec3::length(v43) * (1.0f - move_cancel); + float_t v30 = 1.0f - (90.0f - data->remaining) * 0.000124f; + + vec2 v33 = vec2(v43.x, v43.z) * v30 * max_def(move_cancel, 0.18f); + + if (v28 > 1.0f) + data->alive = false; + else if (v28 > 0.2f) + data->remaining -= step * 2.0f; + + vec3 v44; + v44.x = v46.x + v33.x; + v44.y = v46.y + v43.y; + v44.z = v46.z + v33.y; + + mat4_set_translation(&m, &v44); + + data->mat_scale = m; + + if (data->remaining < 40.0f) + data->scale = (1.0f - step * 0.02f) * data->scale; + + if (data->remaining < 10.0f) + data->alpha = (1.0f - step * 0.9f) * data->remaining; + else if (data->alpha < 1.0) { + float_t alpha = step * 0.15f + data->alpha; + data->alpha = min_def(alpha, 1.0f); + } + } + data->remaining -= step; + data->prev_parent_mat = mat; +} + +void rob_chara_age_age::ctrl_skip() { + frame = 0.0f; + for (int32_t i = 0; i < 200; i++, frame += 1.0f) + for (rob_chara_age_age_data& j : data) + if (j.part_id == 1 || j.part_id == 2) { + if (frame >= 200.0f) + frame = 0.0f; + + ctrl_data(&j, mat); + } +} + +void rob_chara_age_age::disp(render_context* rctx, size_t chara_id, + bool npr, bool reflect, const vec3& a5, bool chara_color) { + if (alpha >= 0.1f && this->visible) + object.disp(rctx, chara_id, npr || this->npr, reflect, a5, chara_color); +} + +void rob_chara_age_age::load(object_info obj_info, rob_chara_age_age_data* data, int32_t count) { + reset(); + + frame = 0.0f; + field_9B4 = 1.0f; + mat = mat4_identity; + step = 1.0f; + visible = true; + skip = false; + move_cancel = 0.0f; + alpha = 1.0f; + npr = false; + rot_speed = 1.0f; + step_full = false; + + count = min_def(count, 10); + if (count < 1) + return; + + memmove(this->data, data, sizeof(rob_chara_age_age_data) * count); + object.load(obj_info, count); +} + +void rob_chara_age_age::reset() { + object.reset(); + + for (rob_chara_age_age_data& i : data) + i.reset(); +} + +void rob_chara_age_age::set_alpha(float_t value) { + alpha = value; +} + +void rob_chara_age_age::set_disp(bool value) { + visible = value; +} + +void rob_chara_age_age::set_move_cancel(float_t value) { + move_cancel = value; +} + +void rob_chara_age_age::set_npr(bool value) { + npr = value; +} + +void rob_chara_age_age::set_rot_speed(float_t value) { + rot_speed = value; +} + +void rob_chara_age_age::set_skip() { + skip = true; +} + +void rob_chara_age_age::set_step(float_t value) { + step = max_def(value, 0.0f); +} + +void rob_chara_age_age::set_step_full() { + step_full = true; +} + osage_set_motion::osage_set_motion() { motion_id = -1; } diff --git a/src/CRE/rob/rob.hpp b/src/CRE/rob/rob.hpp index bb4d5f0a..60c1b2f4 100644 --- a/src/CRE/rob/rob.hpp +++ b/src/CRE/rob/rob.hpp @@ -2166,6 +2166,7 @@ struct rob_chara_item_equip_object { int32_t get_bone_index(const char* name, bone_database* bone_data); bone_node* get_bone_node(int32_t bone_index); bone_node* get_bone_node(const char* name, bone_database* bone_data); + const mat4* get_ex_data_bone_node_mat(const char* name); RobOsageNode* get_normal_ref_osage_node(std::string& name, size_t* index); void get_parent_bone_nodes(bone_node* bone_nodes, bone_database* bone_data); void init_ex_data_bone_nodes(obj_skin_ex_data* ex_data); @@ -2256,6 +2257,7 @@ struct rob_chara_item_equip { rob_chara_item_equip_object* get_item_equip_object(item_id id); object_info get_object_info(item_id id); void get_parent_bone_nodes(bone_node* bone_nodes, bone_database* bone_data); + const mat4* get_ex_data_bone_node_mat(item_id id, const char* name); void load_object_info(object_info obj_info, item_id id, bool osage_reset, bone_database* bone_data, void* data, object_database* obj_db); void load_outfit_object_info(item_id id, object_info obj_info, @@ -3500,6 +3502,22 @@ extern void rob_free(); extern mat4* rob_chara_bone_data_get_mats_mat(rob_chara_bone_data* rob_bone_data, size_t index); +extern void rob_chara_age_age_array_ctrl(int32_t chara_id, int32_t part_id, mat4& mat); +extern void rob_chara_age_age_array_disp(render_context* rctx, + int32_t chara_id, bool reflect, bool chara_color); +extern void rob_chara_age_age_array_load(int32_t chara_id, int32_t part_id); +extern void rob_chara_age_age_array_reset(int32_t chara_id); +extern void rob_chara_age_age_array_set_alpha(int32_t chara_id, int32_t part_id, float_t alpha); +extern void rob_chara_age_age_array_set_disp(int32_t chara_id, int32_t part_id, bool value); +extern void rob_chara_age_age_array_set_move_cancel(int32_t chara_id, int32_t part_id, float_t value); +extern void rob_chara_age_age_array_set_npr(int32_t chara_id, int32_t part_id, bool value); +extern void rob_chara_age_age_array_set_params(int32_t chara_id, int32_t part_id, + int32_t npr, int32_t rot_speed, int32_t skip, int32_t disp); +extern void rob_chara_age_age_array_set_rot_speed(int32_t chara_id, int32_t part_id, float_t value); +extern void rob_chara_age_age_array_set_skip(int32_t chara_id, int32_t part_id); +extern void rob_chara_age_age_array_set_step(int32_t chara_id, int32_t part_id, float_t step); +extern void rob_chara_age_age_array_set_step_full(int32_t chara_id, int32_t part_id); + extern bool rob_chara_array_check_visibility(int32_t chara_id); extern rob_chara* rob_chara_array_get(int32_t chara_id); extern rob_chara_bone_data* rob_chara_array_get_bone_data(int32_t chara_id); @@ -3512,6 +3530,8 @@ extern void rob_chara_array_free_chara_id(int32_t chara_id); extern void rob_chara_array_reset_bone_data_item_equip(int32_t chara_id); extern void rob_chara_array_set_alpha_obj_flags(int32_t chara_id, float_t alpha, mdl::ObjFlags flags); +extern bool rob_chara_check_for_ageageagain_module(chara_index chara_index, int32_t module_index); + extern bool rob_chara_pv_data_array_check_chara_id(int32_t chara_id); extern bool pv_osage_manager_array_get_disp(); diff --git a/src/CRE/shader.cpp b/src/CRE/shader.cpp index a1ecdb7e..99c85444 100644 --- a/src/CRE/shader.cpp +++ b/src/CRE/shader.cpp @@ -717,6 +717,9 @@ void shader_set_data::unload() { shader* shaders = this->shaders; for (size_t i = 0; i < size; i++) { shader* shader = &shaders[i]; + if (!shader->sub) + continue; + int32_t num_sub = shader->num_sub; shader_sub* sub = shader->sub; for (size_t j = 0; j < num_sub; j++, sub++) { @@ -742,7 +745,8 @@ void shader_set_data::unload() { sub->shaders = 0; } } - free_def(shader->sub); + free(shader->sub); + shader->sub = 0; } free_def(shaders); this->shaders = 0; @@ -935,7 +939,7 @@ static GLuint shader_compile_binary(const char* vert, const char* frag, const ch GLsizei length = 0; while (*buffer_size < 0x7FFFFFF) { glGetProgramBinary(program, *buffer_size, &length, &binary_format, *binary); - if (!glGetError()) + if (!gl_state_get_error()) break; free_def(*binary); diff --git a/src/CRE/shader_ft.cpp b/src/CRE/shader_ft.cpp index 7a20e1f4..bb8bf656 100644 --- a/src/CRE/shader_ft.cpp +++ b/src/CRE/shader_ft.cpp @@ -2774,9 +2774,10 @@ static const bool CONSTANT_permut[] = { //true, // 0th removed true, false, - true, - true, false, + true, + true, + false, // 6th added }; /*static const bool PEEL_permut[] = { diff --git a/src/CRE/sprite.cpp b/src/CRE/sprite.cpp new file mode 100644 index 00000000..626ad925 --- /dev/null +++ b/src/CRE/sprite.cpp @@ -0,0 +1,296 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#include "sprite.hpp" +#include "../KKdLib/prj/shared_ptr.hpp" +#include "../KKdLib/prj/stack_allocator.hpp" +#include "data.hpp" +#include "file_handler.hpp" +#include "resolution_mode.hpp" + +struct SpriteHeader { + +}; + +struct SpriteHeaderFile { + +}; + +struct SprSet { + int32_t flag; + int32_t index; + SpriteHeaderFile* header_file; + SpriteHeader* header; + texture** textures; + int32_t load_count; + p_file_handler file_handler; + bool ready; + prj::shared_ptr alloc_handler; + std::string file; + + SprSet(int32_t index); + ~SprSet(); + + void Unload(); + bool UnloadTexture(); +}; + +namespace spr { + struct SpriteManager { + std::map sets; + std::list reqlist[4][64]; + float_t aspect[2]; + std::pair> field_1018; + std::pair> field_102C; + int32_t index; + mat4 projection; + mat4 mat; + resolution_mode resolution_mode; + + SpriteManager(); + ~SpriteManager(); + + void Clear(); + SprSet* GetSet(int32_t index); + void ResetIndex(); + void ResetResData(); + }; + + SprSet* spr::SpriteManager::GetSet(int32_t index) { + auto elem = sets.find(index); + if (elem != sets.end()) + return &elem->second; + return 0; + } +} + +spr::SpriteManager sprite_manager; + +namespace spr { + void calc_sprite_vertex(spr::SprArgs* args, vec3* vtx, mat4* mat, bool font) { + vtx[0] = 0.0f; + vtx[1].x = 0.0f; + vtx[1].y = args->sprite_size.y; + vtx[1].z = 0.0f; + vtx[2].x = args->sprite_size.x; + vtx[2].y = args->sprite_size.y; + vtx[2].z = 0.0f; + vtx[3].x = args->sprite_size.x; + vtx[3].y = 0.0f; + vtx[3].z = 0.0f; + + mat4 m; + SprAttr attr = args->attr; + if (!(attr & SPR_ATTR_MATRIX)) { + if (attr & SPR_ATTR_CTR) { + if (attr & SPR_ATTR_CTR_LT) + args->center = 0.0f; + else if (attr & SPR_ATTR_CTR_LC) { + args->center.x = 0.0f; + args->center.y = args->sprite_size.y * 0.5f; + args->center.z = 0.0f; + } + else if (attr & SPR_ATTR_CTR_LB) { + args->center.x = 0.0f; + args->center.y = args->sprite_size.y; + args->center.z = 0.0f; + } + else if (attr & SPR_ATTR_CTR_CT) { + args->center.x = args->sprite_size.x * 0.5f; + args->center.y = 0.0f; + args->center.z = 0.0f; + } + else if (attr & SPR_ATTR_CTR_CC) { + args->center.x = args->sprite_size.x * 0.5f; + args->center.y = args->sprite_size.y * 0.5f; + args->center.z = 0.0f; + } + else if (attr & SPR_ATTR_CTR_CB) { + args->center.x = args->sprite_size.x * 0.5f; + args->center.y = args->sprite_size.y; + args->center.z = 0.0f; + } + else if (attr & SPR_ATTR_CTR_RT) { + args->center.x = args->sprite_size.x; + args->center.y = 0.0f; + args->center.z = 0.0f; + } + else if (attr & SPR_ATTR_CTR_RC) { + args->center.x = args->sprite_size.x; + args->center.y = args->sprite_size.y * 0.5f; + args->center.z = 0.0f; + } + else if (attr & SPR_ATTR_CTR_RB) { + args->center.x = args->sprite_size.x; + args->center.y = args->sprite_size.y; + args->center.z = 0.0f; + } + } + + if (font) { + if (attr & SPR_ATTR_FLIP_H) { + args->scale.x = -args->scale.x; + args->rot.z = -args->rot.z; + } + if (attr & SPR_ATTR_FLIP_V) { + args->scale.y = -args->scale.y; + args->rot.z = -args->rot.z; + } + } + + if (fabsf(args->skew_angle.x) > 0.000001f) { + float_t skew_width = tanf(args->skew_angle.x) * args->sprite_size.y * 0.5f; + vtx[0].x = vtx[0].x + skew_width; + vtx[1].x = vtx[1].x - skew_width; + vtx[2].x = vtx[2].x - skew_width; + vtx[3].x = vtx[3].x + skew_width; + } + + if (fabsf(args->skew_angle.y) > 0.000001f) { + float_t skew_height = tanf(args->skew_angle.y) * args->sprite_size.x * 0.5f; + vtx[0].y = vtx[0].y - skew_height; + vtx[1].y = vtx[1].y - skew_height; + vtx[2].y = vtx[2].y + skew_height; + vtx[3].y = vtx[3].y + skew_height; + } + + mat4_set_translation(&m, &args->trans); + if (fabsf(args->rot.x) > 0.000001f) + mat4_rotate_x_mult(&m, args->rot.x, &m); + if (fabsf(args->rot.y) > 0.000001f) + mat4_rotate_y_mult(&m, args->rot.y, &m); + if (fabsf(args->rot.z) > 0.000001f) + mat4_rotate_z_mult(&m, args->rot.z, &m); + mat4_scale_rot(&m, &args->scale, &m); + const vec3 center = -args->center; + mat4_translate_mult(&m, ¢er, &m); + } + else { + mat4_set_translation(&m, &args->trans); + mat4_scale_rot(&m, &args->scale, &m); + } + + mat4_mult(&args->mat, &m, &m); + + mat4_mult_vec3_trans(&m, &vtx[0], &vtx[0]); + mat4_mult_vec3_trans(&m, &vtx[1], &vtx[1]); + mat4_mult_vec3_trans(&m, &vtx[2], &vtx[2]); + mat4_mult_vec3_trans(&m, &vtx[3], &vtx[3]); + + if (mat) + *mat = m; + } +} + +void sprite_manager_init() { + sprite_manager = {}; +} + +void sprite_manager_load_set(int32_t set_id, std::string* mdata_dir) { + data_struct* aft_data = &data_list[DATA_AFT]; + sprite_database* aft_spr_db = &aft_data->data_ft.spr_db; + + const spr_db_spr_set* spr_set = aft_spr_db->get_spr_set_by_id(set_id); + //sprite_manager.ReadFile(spr_set->index, spr_set->file_name.c_str(), mdata_dir); +} + +void sprite_manager_reset_res_data() { + sprite_manager.ResetResData(); +} + +void sprite_manager_free() { + sprite_manager.Clear(); +} + +namespace spr { + SpriteManager::SpriteManager() : aspect(), index() { + ResetIndex(); + resolution_mode = RESOLUTION_MODE_MAX; + + resolution_struct res = resolution_struct(RESOLUTION_MODE_HD); + + aspect[0] = (float_t)res.aspect; + field_1018.first = res.resolution_mode; + field_1018.second = { 0.0f, { (float_t)res.width, (float_t)res.height } }; + + aspect[1] = (float_t)res.aspect; + field_102C.first = res.resolution_mode; + field_102C.second = { 0.0f, { (float_t)res.width, (float_t)res.height } }; + + mat = mat4_identity; + } + + SpriteManager::~SpriteManager() { + for (int32_t i = 0; i < 4; i++) + for (int32_t j = 0; j < 64; j++) + reqlist[i][j].clear(); + sets.clear(); + } + + void SpriteManager::Clear() { + for (int32_t i = 0; i < 4; i++) + for (int32_t j = 0; j < 64; j++) + reqlist[i][j].clear(); + + for (auto i : sets) + i.second.Unload(); + sets.clear(); + } + + void SpriteManager::ResetIndex() { + index = 0; + } + + void SpriteManager::ResetResData() { + ResetIndex(); + resolution_mode = RESOLUTION_MODE_MAX; + + resolution_struct* res = res_window_get(); + + aspect[0] = (float_t)res->aspect; + field_1018.first = res->resolution_mode; + field_1018.second = { 0.0f, { (float_t)res->width, (float_t)res->height } }; + + aspect[1] = (float_t)res->aspect; + field_102C.first = res->resolution_mode; + field_102C.second = { 0.0f, { (float_t)res->width, (float_t)res->height } }; + + mat = mat4_identity; + } +} + +SprSet::SprSet(int32_t index) : flag(), header_file(), header(), textures(), load_count(), ready() { + this->index = index; +} + +SprSet::~SprSet() { + +} + +void SprSet::Unload() { + if (load_count > 1) { + load_count--; + return; + } + + file_handler.reset(); + UnloadTexture(); + alloc_handler.reset(); + + free_def(header_file); + this->header = 0; + file.clear(); + ready = false; + load_count = 0; +} + +bool SprSet::UnloadTexture() { + if (textures) { + texture_array_free(textures); + textures = 0; + return true; + } + return false; +} diff --git a/src/CRE/sprite.hpp b/src/CRE/sprite.hpp new file mode 100644 index 00000000..2434a475 --- /dev/null +++ b/src/CRE/sprite.hpp @@ -0,0 +1,158 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#pragma once + +#include +#include +#include "../KKdLib/default.hpp" +#include "../KKdLib/mat.hpp" +#include "../KKdLib/vec.hpp" +#include "resolution_mode.hpp" +#include "texture.hpp" +#include "gl_state.hpp" + +namespace spr { + enum SprKind { + SPR_KIND_NORMAL = 0, + SPR_KIND_LINE, + SPR_KIND_LINES, + SPR_KIND_RECT, + SPR_KIND_MULTI, + SPR_KIND_ARROW_A, + SPR_KIND_ARROW_B, + SPR_KIND_ARROW_AB, + SPR_KIND_TRIANGLE, + SPR_KIND_CIRCLE, + }; + + enum SprAttr : uint32_t { + /*M_SPR_ATTR_SCALESIZE_X = 0x800, + M_SPR_ATTR_SCALESIZE_Y = 0x1000, + M_SPR_ATTR_RATIOCROP = 0x2000, + M_SPR_ATTR_IGNR_FMTRC = 0x4000, + M_SPR_ATTR_NOTCORRECT_P = 0x8000, + M_SPR_ATTR_NOTCORRECT_S = 0x10000, + M_SPR_ATTR_MULTI = 0x40000, + M_SPR_ATTR_BACKGROUND = 0x80000, + M_SPR_ATTR_POLY = 0x1000000, + M_SPR_ATTR_MESH = 0x2000000, + M_SPR_ATTR_LINEAR = 0x4000000, + M_SPR_ATTR_TEXTURE = 0x8000000, + M_SPR_ATTR_EDGELINE = 0x10000000, + M_SPR_ATTR_CROPPED = 0x20000000, + M_SPR_ATTR_REQUESTED = 0x40000000, + M_SPR_ATTR_ALLOCATED = 0x80000000, + M_SPR_ATTR_SCALESIZE = 0x1800, + M_SPR_ATTR_NOTCORRECT = 0x18000,*/ + + SPR_ATTR_FLIP_H = 0x00010000, + SPR_ATTR_FLIP_V = 0x00020000, + SPR_ATTR_CTR_LT = 0x00040000, + SPR_ATTR_CTR_CT = 0x00080000, + SPR_ATTR_CTR_RT = 0x00100000, + SPR_ATTR_CTR_LC = 0x00200000, + SPR_ATTR_CTR_CC = 0x00400000, + SPR_ATTR_CTR_RC = 0x00800000, + SPR_ATTR_CTR_LB = 0x01000000, + SPR_ATTR_CTR_CB = 0x02000000, + SPR_ATTR_CTR_RB = 0x04000000, + SPR_ATTR_MATRIX = 0x08000000, + SPR_ATTR_NOBLEND = 0x20000000, + + SPR_ATTR_CTR = 0x07FC0000, + }; + + struct SprArgs { + enum Flags : uint32_t { + SPRITE_SIZE = 0x01, + TEXTURE_POS_SIZE = 0x02, + }; + + spr::SprKind kind; + union { + int32_t index; + //spr_info info; + } id; + vec4 color; + SprAttr attr; + int32_t blend; + int32_t index; + int32_t layer; + int32_t prio; + resolution_mode resolution_mode_screen; + resolution_mode resolution_mode_sprite; + vec3 center; + vec3 trans; + vec3 scale; + vec3 rot; + vec2 skew_angle; + mat4 mat; + texture* texture; + int32_t shader; + int32_t field_AC; + //sprite_vertex* vertex_array; + size_t num_vertex; + Flags flags; + vec2 sprite_size; + int32_t field_CC; + vec2 texture_pos; + vec2 texture_size; + spr::SprArgs* next; + }; + + struct SprInfo { + uint32_t texid; + int32_t rotate; + float_t su; + float_t sv; + float_t eu; + float_t ev; + float_t px; + float_t py; + float_t width; + float_t height; + }; + + struct SpriteVertex { + vec3 pos; + vec2 uv; + vec4u8 color; + }; + + struct TexCoord { + struct UV { + float_t u; + float_t v; + + inline UV() : u(), v() { + + } + }; + + UV uv[4]; + + inline TexCoord() { + + } + }; + + struct TexParam { + texture* texture; + TexCoord texcoord; + //int32_t pad[2]; + + inline TexParam() : texture()/*, pad()*/ { + + } + }; + + void calc_sprite_vertex(spr::SprArgs* args, vec3* vtx, mat4* mat, bool font); +} + +extern void sprite_manager_init(); +extern void sprite_manager_load_set(int32_t set_id, std::string* mdata_dir); +extern void sprite_manager_reset_res_data(); +extern void sprite_manager_free(); diff --git a/src/CRE/static_var.hpp b/src/CRE/static_var.hpp index cf797b79..23b1cb52 100644 --- a/src/CRE/static_var.hpp +++ b/src/CRE/static_var.hpp @@ -10,7 +10,6 @@ #include "../KKdLib/light_param/light.hpp" #include "../KKdLib/mat.hpp" #include "../KKdLib/vec.hpp" -#include "../KKdLib/vec.hpp" #include enum draw_pass_3d_type { diff --git a/src/CRE/task_effect.cpp b/src/CRE/task_effect.cpp index 348d6d27..0e947d59 100644 --- a/src/CRE/task_effect.cpp +++ b/src/CRE/task_effect.cpp @@ -941,7 +941,7 @@ void TaskEffectFogRing::Data::Draw() { rctx->disp_manager.draw(mdl::OBJ_TYPE_USER); gl_state_bind_framebuffer(0); rctx->render_manager.set_effect_texture(rt.color_texture); - glGetError(); + gl_state_get_error(); } void TaskEffectFogRing::Data::InitParticleData() { @@ -2454,8 +2454,7 @@ void TaskEffectParent::SetStageHashes(std::vector& stage_hashes) { obj_set_ids.push_back(j); } - prj::sort(obj_set_ids); - prj::unique(obj_set_ids); + prj::sort_unique(obj_set_ids); for (uint32_t i : obj_set_ids) object_storage_load_set_hash(data, i); @@ -2489,8 +2488,7 @@ void TaskEffectParent::SetStageIndices(std::vector& stage_indices) { obj_set_ids.push_back(j); } - prj::sort(obj_set_ids); - prj::unique(obj_set_ids); + prj::sort_unique(obj_set_ids); for (uint32_t i : obj_set_ids) object_storage_load_set(aft_data, aft_obj_db, i); diff --git a/src/CRE/texture.cpp b/src/CRE/texture.cpp index 283ad198..2e5bd8c2 100644 --- a/src/CRE/texture.cpp +++ b/src/CRE/texture.cpp @@ -95,7 +95,7 @@ void texture_apply_color_tone(texture* chg_tex, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, data); } glBindTexture(org_tex->target, 0); - glGetError(); + gl_state_get_error(); free_def(data); } } @@ -121,7 +121,7 @@ texture* texture_copy(texture_id id, texture* org_tex) { glGetTexImage(org_tex->target, i, format, type, data); } glBindTexture(org_tex->target, 0); - glGetError(); + gl_state_get_error(); vec_data.push_back(data); } @@ -174,6 +174,15 @@ void texture_free(texture* tex) { texture_storage_delete_texture(tex->id); } +void texture_array_free(texture** arr) { + if (!arr) + return; + + for (texture** i = arr; *i; i++) + texture_free(*i); + free_def(arr); +} + bool texture_txp_set_load(txp_set* t, texture*** texs, uint32_t* ids) { if (!t || !texs || !ids) return false; @@ -477,7 +486,7 @@ static int32_t texture_load(GLenum target, GLenum internal_format, glTexImage2D(target, level, internal_format, width, height, 0, format, type, data); } break; } - return -(glGetError() != GL_ZERO); + return -(gl_state_get_error() != GL_ZERO); } static texture* texture_load_tex(texture_id id, GLenum target, diff --git a/src/CRE/texture.hpp b/src/CRE/texture.hpp index f02d09d2..9859f418 100644 --- a/src/CRE/texture.hpp +++ b/src/CRE/texture.hpp @@ -83,6 +83,8 @@ extern texture* texture_load_tex_cube_map(texture_id id, GLenum internal_format, extern texture* texture_txp_load(txp* t, texture_id id); extern void texture_free(texture* tex); +extern void texture_array_free(texture** arr); + extern bool texture_txp_set_load(txp_set* t, texture*** texs, uint32_t* ids); extern bool texture_txp_set_load(txp_set* t, texture*** texs, texture_id* ids); diff --git a/src/KKdLib/database/auth_3d.cpp b/src/KKdLib/database/auth_3d.cpp index 9b606bc1..30993936 100644 --- a/src/KKdLib/database/auth_3d.cpp +++ b/src/KKdLib/database/auth_3d.cpp @@ -280,10 +280,8 @@ static void auth_3d_database_load_uids(auth_3d_database* auth_3d_db, uid->size = -1.0f; } - for (auth_3d_database_category& i : category) { - prj::sort(i.uid); - prj::unique(i.uid); - } + for (auth_3d_database_category& i : category) + prj::sort_unique(i.uid); } static void auth_3d_database_file_read_inner(auth_3d_database_file* auth_3d_db_file, stream& s) { diff --git a/src/KKdLib/database/bone.cpp b/src/KKdLib/database/bone.cpp index c44a98ae..4b447445 100644 --- a/src/KKdLib/database/bone.cpp +++ b/src/KKdLib/database/bone.cpp @@ -205,22 +205,15 @@ void bone_database::write(void** data, size_t* size) { s.copy(data, size); } -bool bone_database::get_skeleton(const char* name, - const bone_database_skeleton** skeleton) const { - if (!skeleton) - return false; - - *skeleton = 0; - if ( !name) - return false; +const bone_database_skeleton* bone_database::get_skeleton(const char* name) const { + if (!name) + return 0; uint32_t name_hash = hash_utf8_murmurhash(name); for (const bone_database_skeleton& i : this->skeleton) - if (hash_string_murmurhash(i.name) == name_hash) { - *skeleton = &i; - return true; - } - return false; + if (hash_string_murmurhash(i.name) == name_hash) + return &i; + return 0; } int32_t bone_database::get_skeleton_bone_index(const char* name, const char* bone_name) const { @@ -239,39 +232,26 @@ int32_t bone_database::get_skeleton_bone_index(const char* name, const char* bon return -1; } -bool bone_database::get_skeleton_bones(const char* name, - const std::vector** bone) const { - if (!bone) - return false; - - *bone = 0; +const std::vector* bone_database::get_skeleton_bones(const char* name) const { if (!name) - return false; + return 0; uint32_t name_hash = hash_utf8_murmurhash(name); for (const bone_database_skeleton& i : skeleton) - if (hash_string_murmurhash(i.name) == name_hash) { - *bone = &i.bone; - return true; - } - return false; + if (hash_string_murmurhash(i.name) == name_hash) + return &i.bone; + return 0; } -bool bone_database::get_skeleton_positions(const char* name, const std::vector** positions)const { - if (!positions) - return false; - - *positions = 0; +const std::vector* bone_database::get_skeleton_positions(const char* name) const { if (!name) - return false; + return 0; uint32_t name_hash = hash_utf8_murmurhash(name); for (const bone_database_skeleton& i : skeleton) - if (hash_string_murmurhash(i.name) == name_hash) { - *positions = &i.position; - return true; - } - return false; + if (hash_string_murmurhash(i.name) == name_hash) + return &i.position; + return 0; } int32_t bone_database::get_skeleton_object_bone_index(const char* name, const char* bone_name) const { @@ -290,22 +270,15 @@ int32_t bone_database::get_skeleton_object_bone_index(const char* name, const ch return -1; } -bool bone_database::get_skeleton_object_bones(const char* name, - const std::vector** object_bones) const { - if (!object_bones) - return false; - - *object_bones = 0; +const std::vector* bone_database::get_skeleton_object_bones(const char* name) const { if (!name) - return false; + return 0; uint32_t name_hash = hash_utf8_murmurhash(name); for (const bone_database_skeleton& i : skeleton) - if (hash_string_murmurhash(i.name) == name_hash) { - *object_bones = &i.object_bone; - return true; - } - return false; + if (hash_string_murmurhash(i.name) == name_hash) + return &i.object_bone; + return 0; } int32_t bone_database::get_skeleton_motion_bone_index(const char* name, const char* bone_name) const { @@ -324,57 +297,37 @@ int32_t bone_database::get_skeleton_motion_bone_index(const char* name, const ch return -1; } -bool bone_database::get_skeleton_motion_bones(const char* name, - const std::vector** motion_bones) const { - if (!motion_bones) - return false; - - *motion_bones = 0; +const std::vector* bone_database::get_skeleton_motion_bones(const char* name) const { if (!name) - return false; + return 0; uint32_t name_hash = hash_utf8_murmurhash(name); for (const bone_database_skeleton& i : skeleton) - if (hash_string_murmurhash(i.name) == name_hash) { - *motion_bones = &i.motion_bone; - return true; - } - return false; + if (hash_string_murmurhash(i.name) == name_hash) + return &i.motion_bone; + return 0; } -bool bone_database::get_skeleton_parent_indices(const char* name, - const std::vector** parent_indices) const { - if (!parent_indices) - return false; - - *parent_indices = 0; +const std::vector* bone_database::get_skeleton_parent_indices(const char* name) const { if (!name) - return false; + return 0; uint32_t name_hash = hash_utf8_murmurhash(name); for (const bone_database_skeleton& i : skeleton) - if (hash_string_murmurhash(i.name) == name_hash) { - *parent_indices = &i.parent_index; - return true; - } - return false; + if (hash_string_murmurhash(i.name) == name_hash) + return &i.parent_index; + return 0; } -bool bone_database::get_skeleton_heel_height(const char* name, const float_t** unknown_value) const { - if (!unknown_value) - return false; - - *unknown_value = 0; +const float_t* bone_database::get_skeleton_heel_height(const char* name) const { if (!name) - return false; + return 0; uint32_t name_hash = hash_utf8_murmurhash(name); for (const bone_database_skeleton& i : skeleton) - if (hash_string_murmurhash(i.name) == name_hash) { - *unknown_value = &i.heel_height; - return true; - } - return false; + if (hash_string_murmurhash(i.name) == name_hash) + return &i.heel_height; + return 0; } bool bone_database::load_file(void* data, const char* path, const char* file, uint32_t hash) { diff --git a/src/KKdLib/database/bone.hpp b/src/KKdLib/database/bone.hpp index 58721254..86404dfa 100644 --- a/src/KKdLib/database/bone.hpp +++ b/src/KKdLib/database/bone.hpp @@ -79,22 +79,16 @@ struct bone_database { void write(const wchar_t* path); void write(void** data, size_t* size); - bool get_skeleton(const char* name, - const bone_database_skeleton** skeleton) const; + const bone_database_skeleton* get_skeleton(const char* name) const; int32_t get_skeleton_bone_index(const char* name, const char* bone_name) const; - bool get_skeleton_bones(const char* name, - const std::vector** bone) const; - bool get_skeleton_positions(const char* name, - const std::vector** positions) const; + const std::vector* get_skeleton_bones(const char* name) const; + const std::vector* get_skeleton_positions(const char* name) const; int32_t get_skeleton_object_bone_index(const char* name, const char* bone_name) const; - bool get_skeleton_object_bones(const char* name, - const std::vector** object_bones) const; + const std::vector* get_skeleton_object_bones(const char* name) const; int32_t get_skeleton_motion_bone_index(const char* name, const char* bone_name) const; - bool get_skeleton_motion_bones(const char* name, - const std::vector** motion_bones) const; - bool get_skeleton_parent_indices(const char* name, - const std::vector** parent_indices) const; - bool get_skeleton_heel_height(const char* name, const float_t** unknown_value) const; + const std::vector* get_skeleton_motion_bones(const char* name) const; + const std::vector* get_skeleton_parent_indices(const char* name) const; + const float_t* get_skeleton_heel_height(const char* name) const; 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 18852b2a..13177b84 100644 --- a/src/KKdLib/database/object.cpp +++ b/src/KKdLib/database/object.cpp @@ -280,111 +280,70 @@ void object_database::add(object_database_file* obj_db_file) { } } -bool object_database::get_object_set_info(const char* name, const object_set_info** set_info) const { - if (!set_info) - return false; - *set_info = 0; - +const object_set_info* object_database::get_object_set_info(const char* name) const { if (!name) - return false; + return 0; uint32_t name_hash = hash_utf8_murmurhash(name); - for (const object_set_info& i : object_set) - if (name_hash == i.name_hash) { - *set_info = &i; - return true; - } - return false; + if (name_hash == i.name_hash) + return &i; + return 0; } -bool object_database::get_object_set_info(uint32_t set_id, const object_set_info** set_info) const { - if (!set_info) - return false; - *set_info = 0; - +const object_set_info* object_database::get_object_set_info(uint32_t set_id) const { if (set_id == -1) - return false; + return 0; for (const object_set_info& i : object_set) - if (set_id == i.id) { - *set_info = &i; - return true; - } - return false; + if (set_id == i.id) + return &i; + return 0; } -bool object_database::get_object_info_data(const char* name, const object_info_data** info) const { - if (!info) - return false; - *info = 0; - +const object_info_data* object_database::get_object_info_data(const char* name) const { if (!name) - return false; + return 0; uint32_t name_hash = hash_utf8_murmurhash(name); - for (const object_set_info& i : object_set) for (const object_info_data& j : i.object) - if (name_hash == j.name_hash_murmurhash) { - *info = &j; - return true; - } - return false; + if (name_hash == j.name_hash_murmurhash) + return &j; + return 0; } -bool object_database::get_object_info_data_by_fnv1a64m_hash( - uint64_t hash, const object_info_data** info) const { - if (!info) - return false; - *info = 0; - +const object_info_data* object_database::get_object_info_data_by_fnv1a64m_hash(uint64_t hash) const { if (hash == hash_fnv1a64m_empty) - return false; + return 0; for (const object_set_info& i : object_set) for (const object_info_data& j : i.object) - if (hash == j.name_hash_fnv1a64m) { - *info = &j; - return true; - } - return false; + if (hash == j.name_hash_fnv1a64m) + return &j; + return 0; } -bool object_database::get_object_info_data_by_fnv1a64m_hash_upper( - uint64_t hash, const object_info_data** info) const { - if (!info) - return false; - *info = 0; - +const object_info_data* object_database::get_object_info_data_by_fnv1a64m_hash_upper(uint64_t hash) const { if (hash == hash_fnv1a64m_empty) - return false; + return 0; for (const object_set_info& i : object_set) for (const object_info_data& j : i.object) - if (hash == j.name_hash_fnv1a64m_upper) { - *info = &j; - return true; - } - return false; + if (hash == j.name_hash_fnv1a64m_upper) + return &j; + return 0; } -bool object_database::get_object_info_data_by_murmurhash( - uint32_t hash, const object_info_data** info) const { - if (!info) - return false; - *info = 0; - - if (hash == hash_murmurhash_empty) - return false; +const object_info_data* object_database::get_object_info_data_by_murmurhash(uint32_t hash) const { + if (hash == -1 || hash == hash_murmurhash_empty || hash == hash_murmurhash_null) + return 0; for (const object_set_info& i : object_set) for (const object_info_data& j : i.object) - if (hash == j.name_hash_murmurhash) { - *info = &j; - return true; - } - return false; + if (hash == j.name_hash_murmurhash) + return &j; + return 0; } uint32_t object_database::get_object_set_id(const char* name) const { @@ -396,13 +355,9 @@ uint32_t object_database::get_object_set_id(const char* name) const { return (uint32_t)-1; uint32_t name_hash = hash_utf8_murmurhash(name); - if (name_hash == hash_murmurhash_empty) - return (uint32_t)-1; - for (const object_set_info& i : object_set) if (name_hash == i.name_hash) return i.id; - return (uint32_t)-1; } @@ -413,7 +368,6 @@ const char* object_database::get_object_set_name(uint32_t set_id) const { for (const object_set_info& i : object_set) if (set_id == i.id) return i.name.c_str(); - return 0; } @@ -426,14 +380,10 @@ object_info object_database::get_object_info(const char* name) const { return object_info(); uint32_t name_hash = hash_utf8_murmurhash(name); - if (name_hash == hash_murmurhash_empty) - return object_info(); - for (const object_set_info& i : object_set) for (const object_info_data& j : i.object) if (name_hash == j.name_hash_murmurhash) return { j.id, i.id }; - return object_info(); } @@ -446,7 +396,6 @@ const char* object_database::get_object_name(object_info obj_info) const { for (const object_info_data& j : i.object) if (obj_info.id == j.id) return j.name.c_str(); - return 0; } diff --git a/src/KKdLib/database/object.hpp b/src/KKdLib/database/object.hpp index 8734034f..4c521830 100644 --- a/src/KKdLib/database/object.hpp +++ b/src/KKdLib/database/object.hpp @@ -142,15 +142,12 @@ struct object_database { void add(object_database_file* obj_db_file); - bool get_object_set_info(const char* name, const object_set_info** set_info) const; - bool get_object_set_info(uint32_t set_id, const object_set_info** set_info) const; - bool get_object_info_data(const char* name, const object_info_data** info) const; - bool get_object_info_data_by_fnv1a64m_hash( - uint64_t hash, const object_info_data** info) const; - bool get_object_info_data_by_fnv1a64m_hash_upper( - uint64_t hash, const object_info_data** info) const; - bool get_object_info_data_by_murmurhash( - uint32_t hash, const object_info_data** info) const; + const object_set_info* get_object_set_info(const char* name) const; + const object_set_info* get_object_set_info(uint32_t set_id) const; + const object_info_data* get_object_info_data(const char* name) const; + const object_info_data* get_object_info_data_by_fnv1a64m_hash(uint64_t hash) const; + const object_info_data* get_object_info_data_by_fnv1a64m_hash_upper(uint64_t hash) const; + const object_info_data* get_object_info_data_by_murmurhash(uint32_t hash) const; uint32_t get_object_set_id(const char* name) const; const char* get_object_set_name(uint32_t set_id) const; object_info get_object_info(const char* name) const; diff --git a/src/KKdLib/database/sprite.cpp b/src/KKdLib/database/sprite.cpp index 87df1c38..fd1602ad 100644 --- a/src/KKdLib/database/sprite.cpp +++ b/src/KKdLib/database/sprite.cpp @@ -20,52 +20,39 @@ static int64_t sprite_database_file_strings_get_string_offset(std::vector& vec_off, std::string& str); static bool sprite_database_file_strings_push_back_check(std::vector& vec, std::string& str); -sprite_info_file::sprite_info_file() : id(), index() { +const spr_db_spr_set spr_db_spr_set_null; +const spr_db_spr spr_db_spr_null; + +spr_db_spr_file::spr_db_spr_file() : id(), index(), texture() { } -sprite_info_file::~sprite_info_file() { +spr_db_spr_file::~spr_db_spr_file() { } -sprite_info::sprite_info() : id(), index() { +spr_db_spr::spr_db_spr() : id() { name_hash = hash_murmurhash_empty; } -sprite_info::~sprite_info() { +spr_db_spr::~spr_db_spr() { } -sprite_texture_info_file::sprite_texture_info_file() : id(), index() { +spr_db_spr_set_file::spr_db_spr_set_file() : id(), index(){ } -sprite_texture_info_file::~sprite_texture_info_file() { +spr_db_spr_set_file::~spr_db_spr_set_file() { } -sprite_texture_info::sprite_texture_info() : id(), index() { - name_hash = hash_murmurhash_empty; -} - -sprite_texture_info::~sprite_texture_info() { - -} - -sprite_set_file::sprite_set_file() : id(), index(){ - -} - -sprite_set_file::~sprite_set_file() { - -} - -sprite_set::sprite_set() : id(), index() { +spr_db_spr_set::spr_db_spr_set() : id(), index() { name_hash = hash_murmurhash_empty; file_name_hash = hash_murmurhash_empty; } -sprite_set::~sprite_set() { +spr_db_spr_set::~spr_db_spr_set() { } @@ -256,58 +243,115 @@ sprite_database::~sprite_database() { void sprite_database::add(sprite_database_file* spr_db_file) { if (!spr_db_file || !spr_db_file->ready) return; + return; - sprite_set_file* sprite_set = spr_db_file->sprite_set.data(); + size_t sprite_sets_count = this->spr_ids.size(); - size_t sprite_sets_count = this->sprite_set.size(); + spr_set_ids.reserve(spr_db_file->sprite_set.size()); + spr_set_indices.reserve(spr_db_file->sprite_set.size()); + spr_set_names.reserve(spr_db_file->sprite_set.size()); - this->sprite_set.reserve(spr_db_file->sprite_set.size()); + for (spr_db_spr_set_file& i : spr_db_file->sprite_set) { + spr_db_spr_set spr_set; + spr_set.id = i.id; + spr_set.name.assign(i.name); + spr_set.name_hash = hash_string_murmurhash(spr_set.name); + spr_set.file_name.assign(i.file_name); + spr_set.file_name_hash = hash_string_murmurhash(spr_set.file_name); + spr_set.index = (uint16_t)(sprite_sets_count + i.index); - for (sprite_set_file& i : spr_db_file->sprite_set) { - uint32_t id = i.id; + spr_set_ids.push_back({ spr_set.id, spr_set }); + spr_set_indices.push_back({ spr_set.index, spr_set }); + spr_set_names.push_back({ spr_set.name, spr_set }); - ::sprite_set* set_info = 0; - for (::sprite_set& j : this->sprite_set) - if (id == j.id) { - set_info = &j; - break; - } + spr_ids.reserve(i.sprite.size()); + spr_names.reserve(i.sprite.size()); + spr_indices.reserve(i.sprite.size()); - if (!set_info) { - this->sprite_set.push_back({}); - set_info = &this->sprite_set.back(); + for (spr_db_spr_file& j : i.sprite) { + spr_db_spr spr; + spr.id = j.id; + spr.name.assign(j.name); + spr.name_hash = hash_string_murmurhash(spr.name); + spr.info = { j.index, (uint16_t)((j.texture ? 0x1000 : 0x0000) | spr_set.index) }; + + spr_ids.push_back({ spr.id, spr }); + spr_names.push_back({ spr.name, spr }); + spr_indices.push_back({ spr.info, spr }); } - - set_info->id = i.id; - set_info->name.assign(i.name); - set_info->name_hash = hash_string_murmurhash(set_info->name); - set_info->file_name.assign(i.file_name); - set_info->file_name_hash = hash_string_murmurhash(set_info->file_name); - - set_info->sprite.clear(); - set_info->sprite.reserve(i.sprite.size()); - - for (sprite_info_file& j : i.sprite) { - set_info->sprite.push_back({}); - sprite_info& info = set_info->sprite.back(); - info.id = j.id; - info.name.assign(j.name); - info.name_hash = hash_string_murmurhash(info.name); - } - - set_info->texture.clear(); - set_info->texture.reserve(i.texture.size()); - - for (sprite_texture_info_file& j : i.texture) { - set_info->texture.push_back({}); - sprite_texture_info& info = set_info->texture.back(); - info.id = j.id; - info.name.assign(j.name); - info.name_hash = hash_string_murmurhash(info.name); - } - - set_info->index = (uint32_t)(sprite_sets_count + i.index); } + + spr_set_ids.sort_unique(); + spr_set_indices.sort_unique(); + spr_set_names.sort_unique(); + spr_ids.sort_unique(); + spr_names.sort_unique(); + spr_indices.sort_unique(); +} + +const spr_db_spr_set* sprite_database::get_spr_set_by_name(const char* name) const { + auto elem = spr_set_names.find(std::string(name)); + if (elem != spr_set_names.end()) + return &elem->second; + return &spr_db_spr_set_null; +} + +const spr_db_spr_set* sprite_database::get_spr_set_by_id(uint32_t set_id) const { + auto elem = spr_set_ids.find(set_id); + if (elem != spr_set_ids.end()) + return &elem->second; + return &spr_db_spr_set_null; +} + +const spr_db_spr_set* sprite_database::get_spr_set_by_index(uint32_t index) const { + auto elem = spr_set_indices.find(index); + if (elem != spr_set_indices.end()) + return &elem->second; + return &spr_db_spr_set_null; +} + +const spr_db_spr* sprite_database::get_spr_by_name(const char* name) const { + auto elem = spr_names.find(std::string(name)); + if (elem != spr_names.end()) + return &elem->second; + return &spr_db_spr_null; +} + +const spr_db_spr* sprite_database::get_spr_by_id(uint32_t id) const { + auto elem = spr_ids.find(id); + if (elem != spr_ids.end()) + return &elem->second; + return &spr_db_spr_null; +} + +const spr_db_spr* sprite_database::get_spr_by_set_id_index(uint32_t set_id, uint32_t index) const { + auto elem = spr_indices.find({ (uint16_t)index, get_spr_set_by_id(set_id)->index }); + if (elem != spr_indices.end()) + return &elem->second; + return &spr_db_spr_null; +} + +const spr_db_spr* sprite_database::get_tex_by_set_id_index(uint32_t set_id, uint32_t index) const { + auto elem = spr_indices.find({ (uint16_t)index, (uint16_t)(0x1000 | get_spr_set_by_id(set_id)->index) }); + if (elem != spr_indices.end()) + return &elem->second; + return &spr_db_spr_null; +} + +const char* sprite_database::get_spr_set_file_name(uint32_t set_id) const { + return get_spr_set_by_id(set_id)->file_name.c_str(); +} + +uint32_t sprite_database::get_spr_set_id_by_name(const char* name) const { + return get_spr_set_by_name(name)->id; +} + +uint32_t sprite_database::get_spr_set_id_by_index(uint32_t index) const { + return spr_ids[index].first; +} + +const char* sprite_database::get_spr_set_name(uint32_t set_id) const { + return get_spr_set_by_id(set_id)->name.c_str(); } static void sprite_database_file_classic_read_inner(sprite_database_file* spr_db, stream& s) { @@ -318,15 +362,15 @@ static void sprite_database_file_classic_read_inner(sprite_database_file* spr_db spr_db->sprite_set.resize(sprite_sets_count); - sprite_set_file* sprite_set = spr_db->sprite_set.data(); + spr_db_spr_set_file* spr_db_spr_set = spr_db->sprite_set.data(); s.position_push(sprite_sets_offset, SEEK_SET); for (uint32_t i = 0; i < sprite_sets_count; i++) { - sprite_set_file& set_info = sprite_set[i]; - set_info.id = s.read_uint32_t(); - set_info.name = s.read_string_null_terminated_offset(s.read_uint32_t()); - set_info.file_name = s.read_string_null_terminated_offset(s.read_uint32_t()); - set_info.index = s.read_uint32_t(); + spr_db_spr_set_file& spr_set = spr_db_spr_set[i]; + spr_set.id = s.read_uint32_t(); + spr_set.name = s.read_string_null_terminated_offset(s.read_uint32_t()); + spr_set.file_name = s.read_string_null_terminated_offset(s.read_uint32_t()); + spr_set.index = s.read_uint32_t(); } s.position_pop(); @@ -338,23 +382,16 @@ static void sprite_database_file_classic_read_inner(sprite_database_file* spr_db uint16_t index = (uint16_t)(info & 0xFFFF); uint16_t set_index = (uint16_t)((info >> 16) & 0x0FFF); + bool texture = !!((info >> 16) & 0x1000); - sprite_set_file& set_info = sprite_set[set_index]; + spr_db_spr_set_file& spr_set = spr_db_spr_set[set_index]; - if ((info >> 16) & 0x1000) { - set_info.texture.push_back({}); - sprite_texture_info_file& info = set_info.texture.back(); - info.id = id; - info.name.assign(s.read_string_null_terminated_offset(name_offset)); - info.index = index; - } - else { - set_info.sprite.push_back({}); - sprite_info_file& info = set_info.sprite.back(); - info.id = id; - info.name.assign(s.read_string_null_terminated_offset(name_offset)); - info.index = index; - } + spr_set.sprite.push_back({}); + spr_db_spr_file& spr = spr_set.sprite.back(); + spr.id = id; + spr.name.assign(s.read_string_null_terminated_offset(name_offset)); + spr.index = index; + spr.texture = texture; } s.position_pop(); @@ -378,8 +415,8 @@ static void sprite_database_file_classic_write_inner(sprite_database_file* spr_d size_t sprite_sets_count = spr_db->sprite_set.size(); size_t sprites_count = 0; - for (sprite_set_file& i : spr_db->sprite_set) - sprites_count += i.sprite.size() + i.texture.size(); + for (spr_db_spr_set_file& i : spr_db->sprite_set) + sprites_count += i.sprite.size(); int64_t sprites_offset = s.get_position(); s.write(0x0C * sprites_count); @@ -394,22 +431,22 @@ static void sprite_database_file_classic_write_inner(sprite_database_file* spr_d strings.reserve(sprite_sets_count + sprites_count); - for (sprite_set_file& i : spr_db->sprite_set) { - for (sprite_texture_info_file& j : i.texture) - if (sprite_database_file_strings_push_back_check(strings, j.name)) { + for (spr_db_spr_set_file& i : spr_db->sprite_set) { + for (spr_db_spr_file& j : i.sprite) + if (j.texture && sprite_database_file_strings_push_back_check(strings, j.name)) { string_offsets.push_back(s.get_position()); s.write_string_null_terminated(j.name); } - for (sprite_info_file& j : i.sprite) - if (sprite_database_file_strings_push_back_check(strings, j.name)) { + for (spr_db_spr_file& j : i.sprite) + if (!j.texture && sprite_database_file_strings_push_back_check(strings, j.name)) { string_offsets.push_back(s.get_position()); s.write_string_null_terminated(j.name); } } s.align_write(0x04); - for (sprite_set_file& i : spr_db->sprite_set) { + for (spr_db_spr_set_file& i : spr_db->sprite_set) { if (sprite_database_file_strings_push_back_check(strings, i.name)) { string_offsets.push_back(s.get_position()); s.write_string_null_terminated(i.name); @@ -423,17 +460,23 @@ static void sprite_database_file_classic_write_inner(sprite_database_file* spr_d s.align_write(0x04); s.position_push(sprites_offset, SEEK_SET); - for (sprite_set_file& i : spr_db->sprite_set) { + for (spr_db_spr_set_file& i : spr_db->sprite_set) { uint16_t sprite_set_index = (uint16_t)(i.index & 0x0FFF); - for (sprite_texture_info_file& j : i.texture) { + for (spr_db_spr_file& j : i.sprite) { + if (j.texture) + continue; + s.write_uint32_t(j.id); s.write_uint32_t((uint32_t)sprite_database_file_strings_get_string_offset(strings, string_offsets, j.name)); s.write_uint32_t(((0x1000 | sprite_set_index) << 16) | j.index); } - for (sprite_info_file& j : i.sprite) { + for (spr_db_spr_file& j : i.sprite) { + if (!j.texture) + continue; + s.write_uint32_t(j.id); s.write_uint32_t((uint32_t)sprite_database_file_strings_get_string_offset(strings, string_offsets, j.name)); @@ -443,7 +486,7 @@ static void sprite_database_file_classic_write_inner(sprite_database_file* spr_d s.position_pop(); s.position_push(sprite_sets_offset, SEEK_SET); - for (sprite_set_file& i : spr_db->sprite_set) { + for (spr_db_spr_set_file& i : spr_db->sprite_set) { s.write_uint32_t(i.id); s.write_uint32_t((uint32_t)sprite_database_file_strings_get_string_offset(strings, string_offsets, i.name)); @@ -477,24 +520,24 @@ static void sprite_database_file_modern_read_inner(sprite_database_file* spr_db, spr_db->sprite_set.resize(sprite_sets_count); - sprite_set_file* sprite_set = spr_db->sprite_set.data(); + spr_db_spr_set_file* spr_db_spr_set = spr_db->sprite_set.data(); s.position_push(sprite_sets_offset, SEEK_SET); if (!is_x) for (uint32_t i = 0; i < sprite_sets_count; i++) { - sprite_set_file& set_info = sprite_set[i]; - set_info.id = s.read_uint32_t_reverse_endianness(); - set_info.name = s.read_string_null_terminated_offset(s.read_offset_f2(header_length)); - set_info.file_name = s.read_string_null_terminated_offset(s.read_offset_f2(header_length)); - set_info.index = s.read_uint32_t_reverse_endianness(); + spr_db_spr_set_file& spr_set = spr_db_spr_set[i]; + spr_set.id = s.read_uint32_t_reverse_endianness(); + spr_set.name = s.read_string_null_terminated_offset(s.read_offset_f2(header_length)); + spr_set.file_name = s.read_string_null_terminated_offset(s.read_offset_f2(header_length)); + spr_set.index = s.read_uint32_t_reverse_endianness(); } else for (uint32_t i = 0; i < sprite_sets_count; i++) { - sprite_set_file& set_info = sprite_set[i]; - set_info.id = s.read_uint32_t_reverse_endianness(); - set_info.name = s.read_string_null_terminated_offset(s.read_offset_x()); - set_info.file_name = s.read_string_null_terminated_offset(s.read_offset_x()); - set_info.index = s.read_uint32_t_reverse_endianness(); + spr_db_spr_set_file& spr_set = spr_db_spr_set[i]; + spr_set.id = s.read_uint32_t_reverse_endianness(); + spr_set.name = s.read_string_null_terminated_offset(s.read_offset_x()); + spr_set.file_name = s.read_string_null_terminated_offset(s.read_offset_x()); + spr_set.index = s.read_uint32_t_reverse_endianness(); s.align_read(0x08); } s.position_pop(); @@ -508,23 +551,16 @@ static void sprite_database_file_modern_read_inner(sprite_database_file* spr_db, uint16_t index = (uint16_t)(info & 0xFFFF); uint16_t set_index = (uint16_t)((info >> 16) & 0x0FFF); + bool texture = !!((info >> 16) & 0x1000); - sprite_set_file& set_info = sprite_set[set_index]; + spr_db_spr_set_file& spr_set = spr_db_spr_set[set_index]; - if ((info >> 16) & 0x1000) { - set_info.texture.push_back({}); - sprite_texture_info_file& info = set_info.texture.back(); - info.id = id; - info.name.assign(s.read_string_null_terminated_offset(name_offset)); - info.index = index; - } - else { - set_info.sprite.push_back({}); - sprite_info_file& info = set_info.sprite.back(); - info.id = id; - info.name.assign(s.read_string_null_terminated_offset(name_offset)); - info.index = index; - } + spr_set.sprite.push_back({}); + spr_db_spr_file& spr = spr_set.sprite.back(); + spr.id = id; + spr.name.assign(s.read_string_null_terminated_offset(name_offset)); + spr.index = index; + spr.texture = texture; } else for (uint32_t i = 0; i < sprites_count; i++) { @@ -535,23 +571,16 @@ static void sprite_database_file_modern_read_inner(sprite_database_file* spr_db, uint16_t index = (uint16_t)(info & 0xFFFF); uint16_t set_index = (uint16_t)((info >> 16) & 0x0FFF); + bool texture = !!((info >> 16) & 0x1000); - sprite_set_file& set_info = sprite_set[set_index]; + spr_db_spr_set_file& spr_set = spr_db_spr_set[set_index]; - if ((info >> 16) & 0x1000) { - set_info.texture.push_back({}); - sprite_texture_info_file& info = set_info.texture.back(); - info.id = id; - info.name.assign(s.read_string_null_terminated_offset(name_offset)); - info.index = index; - } - else { - set_info.sprite.push_back({}); - sprite_info_file& info = set_info.sprite.back(); - info.id = id; - info.name.assign(s.read_string_null_terminated_offset(name_offset)); - info.index = index; - } + spr_set.sprite.push_back({}); + spr_db_spr_file& spr = spr_set.sprite.back(); + spr.id = id; + spr.name.assign(s.read_string_null_terminated_offset(name_offset)); + spr.index = index; + spr.texture = texture; } s.position_pop(); @@ -577,8 +606,8 @@ static void sprite_database_file_modern_write_inner(sprite_database_file* spr_db size_t sprite_sets_count = spr_db->sprite_set.size(); size_t sprites_count = 0; - for (sprite_set_file& i : spr_db->sprite_set) - sprites_count += i.sprite.size() + i.texture.size(); + for (spr_db_spr_set_file& i : spr_db->sprite_set) + sprites_count += i.sprite.size(); if (!is_x) { ee = { 0, 1, 16, 1 }; @@ -642,7 +671,7 @@ static void sprite_database_file_modern_write_inner(sprite_database_file* spr_db strings.reserve(sprite_sets_count + sprites_count); - for (sprite_set_file& i : spr_db->sprite_set) { + for (spr_db_spr_set_file& i : spr_db->sprite_set) { if (sprite_database_file_strings_push_back_check(strings, i.name)) { string_offsets.push_back(s_spdb.get_position()); s_spdb.write_string_null_terminated(i.name); @@ -654,15 +683,15 @@ static void sprite_database_file_modern_write_inner(sprite_database_file* spr_db } } - for (sprite_set_file& i : spr_db->sprite_set) { - for (sprite_texture_info_file& j : i.texture) - if (sprite_database_file_strings_push_back_check(strings, j.name)) { + for (spr_db_spr_set_file& i : spr_db->sprite_set) { + for (spr_db_spr_file& j : i.sprite) + if (j.texture && sprite_database_file_strings_push_back_check(strings, j.name)) { string_offsets.push_back(s_spdb.get_position()); s_spdb.write_string_null_terminated(j.name); } - for (sprite_info_file& j : i.sprite) - if (sprite_database_file_strings_push_back_check(strings, j.name)) { + for (spr_db_spr_file& j : i.sprite) + if (!j.texture && sprite_database_file_strings_push_back_check(strings, j.name)) { string_offsets.push_back(s_spdb.get_position()); s_spdb.write_string_null_terminated(j.name); } @@ -678,7 +707,7 @@ static void sprite_database_file_modern_write_inner(sprite_database_file* spr_db s_spdb.position_push(sprite_sets_offset, SEEK_SET); if (!is_x) - for (sprite_set_file& i : spr_db->sprite_set) { + for (spr_db_spr_set_file& i : spr_db->sprite_set) { s_spdb.write_uint32_t_reverse_endianness(i.id); io_write_offset_f2_pof_add(s_spdb, sprite_database_file_strings_get_string_offset(strings, string_offsets, i.name), 0x20, &pof); @@ -687,7 +716,7 @@ static void sprite_database_file_modern_write_inner(sprite_database_file* spr_db s_spdb.write_uint32_t_reverse_endianness(i.index); } else - for (sprite_set_file& i : spr_db->sprite_set) { + for (spr_db_spr_set_file& i : spr_db->sprite_set) { s_spdb.write_uint32_t_reverse_endianness(i.id); io_write_offset_x_pof_add(s_spdb, sprite_database_file_strings_get_string_offset(strings, string_offsets, i.name), &pof); @@ -698,18 +727,35 @@ static void sprite_database_file_modern_write_inner(sprite_database_file* spr_db s_spdb.position_pop(); s_spdb.position_push(sprites_offset, SEEK_SET); - for (sprite_set_file& i : spr_db->sprite_set) { + for (spr_db_spr_set_file& i : spr_db->sprite_set) { uint16_t sprite_set_index = (uint16_t)(i.index & 0x0FFF); - if (!is_x) - for (sprite_texture_info_file& j : i.texture) { + if (!is_x) { + for (spr_db_spr_file& j : i.sprite) { + if (!j.texture) + continue; + s_spdb.write_uint32_t_reverse_endianness(j.id); io_write_offset_f2_pof_add(s_spdb, sprite_database_file_strings_get_string_offset(strings, string_offsets, j.name), 0x20, &pof); s_spdb.write_uint32_t_reverse_endianness(((0x1000 | sprite_set_index) << 16) | j.index); } - else - for (sprite_texture_info_file& j : i.texture) { + + for (spr_db_spr_file& j : i.sprite) { + if (j.texture) + continue; + + s_spdb.write_uint32_t_reverse_endianness(j.id); + io_write_offset_f2_pof_add(s_spdb, sprite_database_file_strings_get_string_offset(strings, + string_offsets, j.name), 0x20, &pof); + s_spdb.write_uint32_t_reverse_endianness((sprite_set_index << 16) | j.index); + } + } + else { + for (spr_db_spr_file& j : i.sprite) { + if (!j.texture) + continue; + s_spdb.write_uint32_t_reverse_endianness(j.id); io_write_offset_x_pof_add(s_spdb, sprite_database_file_strings_get_string_offset(strings, string_offsets, j.name), &pof); @@ -717,21 +763,17 @@ static void sprite_database_file_modern_write_inner(sprite_database_file* spr_db s_spdb.align_write(0x08); } - if (!is_x) - for (sprite_info_file& j : i.sprite) { - s_spdb.write_uint32_t_reverse_endianness(j.id); - io_write_offset_f2_pof_add(s_spdb, sprite_database_file_strings_get_string_offset(strings, - string_offsets, j.name), 0x20, &pof); - s_spdb.write_uint32_t_reverse_endianness((sprite_set_index << 16) | j.index); - } - else - for (sprite_info_file& j : i.sprite) { + for (spr_db_spr_file& j : i.sprite) { + if (j.texture) + continue; + s_spdb.write_uint32_t_reverse_endianness(j.id); io_write_offset_x_pof_add(s_spdb, sprite_database_file_strings_get_string_offset(strings, string_offsets, j.name), &pof); s_spdb.write_uint32_t_reverse_endianness((sprite_set_index << 16) | j.index); s_spdb.align_write(0x08); } + } } s_spdb.position_pop(); diff --git a/src/KKdLib/database/sprite.hpp b/src/KKdLib/database/sprite.hpp index 82b7be35..d2b787b3 100644 --- a/src/KKdLib/database/sprite.hpp +++ b/src/KKdLib/database/sprite.hpp @@ -5,72 +5,108 @@ #pragma once -#include "../default.hpp" #include #include +#include "../default.hpp" +#include "../prj/vector_pair.hpp" +#include "../hash.hpp" -struct sprite_info_file { +struct spr_info { + uint16_t index; + uint16_t set_index; + + inline spr_info() { + this->index = (uint16_t)-1; + this->set_index = (uint16_t)-1; + } + + inline spr_info(uint16_t index, uint16_t set_index) { + this->index = index; + this->set_index = set_index; + } + + inline bool is_null() const { + return index == (uint16_t)-1 && set_index == (uint16_t)-1; + } + + inline bool not_null() const { + return index != (uint16_t)-1 || set_index != (uint16_t)-1; + } + + inline bool is_null_modern() const { + return index == (uint16_t)-1 && set_index == (uint16_t)-1; + } + + inline bool not_null_modern() const { + return index != (uint16_t)-1 || set_index != (uint16_t)-1; + } +}; + +inline bool operator >(const spr_info& left, const spr_info& right) { + return left.set_index > right.set_index && left.index > right.index; +} + +inline bool operator <(const spr_info& left, const spr_info& right) { + return left.set_index < right.set_index&& left.index < right.index; +} + +inline bool operator >=(const spr_info& left, const spr_info& right) { + return left.set_index >= right.set_index && left.index >= right.index; +} + +inline bool operator <=(const spr_info& left, const spr_info& right) { + return left.set_index <= right.set_index && left.index <= right.index; +} + +inline bool operator ==(const spr_info& left, const spr_info& right) { + return left.set_index == right.set_index && left.index == right.index; +} + +inline bool operator !=(const spr_info& left, const spr_info& right) { + return left.set_index != right.set_index || left.index != right.index; +} + +struct spr_db_spr_file { uint32_t id; std::string name; uint16_t index; + bool texture; - sprite_info_file(); - ~sprite_info_file(); + spr_db_spr_file(); + ~spr_db_spr_file(); }; -struct sprite_info { +struct spr_db_spr { uint32_t id; std::string name; uint32_t name_hash; - uint16_t index; + spr_info info; - sprite_info(); - ~sprite_info(); + spr_db_spr(); + ~spr_db_spr(); }; -struct sprite_texture_info_file { - uint32_t id; - std::string name; - uint16_t index; - - sprite_texture_info_file(); - ~sprite_texture_info_file(); -}; - -struct sprite_texture_info { - uint32_t id; - std::string name; - uint32_t name_hash; - uint16_t index; - - sprite_texture_info(); - ~sprite_texture_info(); -}; - -struct sprite_set_file { +struct spr_db_spr_set_file { uint32_t id; std::string name; std::string file_name; - std::vector sprite; - std::vector texture; - uint32_t index; + std::vector sprite; + uint16_t index; - sprite_set_file(); - ~sprite_set_file(); + spr_db_spr_set_file(); + ~spr_db_spr_set_file(); }; -struct sprite_set { +struct spr_db_spr_set { uint32_t id; std::string name; uint32_t name_hash; std::string file_name; uint32_t file_name_hash; - std::vector sprite; - std::vector texture; - uint32_t index; + uint16_t index; - sprite_set(); - ~sprite_set(); + spr_db_spr_set(); + ~spr_db_spr_set(); }; struct sprite_database_file { @@ -79,7 +115,7 @@ struct sprite_database_file { bool big_endian; bool is_x; - std::vector sprite_set; + std::vector sprite_set; sprite_database_file(); ~sprite_database_file(); @@ -95,10 +131,27 @@ struct sprite_database_file { }; struct sprite_database { - std::vector sprite_set; + prj::vector_pair spr_set_ids; + prj::vector_pair spr_set_indices; + prj::vector_pair spr_set_names; + prj::vector_pair spr_ids; + prj::vector_pair spr_names; + prj::vector_pair spr_indices; sprite_database(); ~sprite_database(); void add(sprite_database_file* spr_db_file); + + const spr_db_spr_set* get_spr_set_by_name(const char* name) const; + const spr_db_spr_set* get_spr_set_by_id(uint32_t set_id) const; + const spr_db_spr_set* get_spr_set_by_index(uint32_t index) const; + const spr_db_spr* get_spr_by_name(const char* name) const; + const spr_db_spr* get_spr_by_id(uint32_t id) const; + const spr_db_spr* get_spr_by_set_id_index(uint32_t set_id, uint32_t index) const; + const spr_db_spr* get_tex_by_set_id_index(uint32_t set_id, uint32_t index) const; + const char* get_spr_set_file_name(uint32_t set_id) const; + uint32_t get_spr_set_id_by_name(const char* name) const; + uint32_t get_spr_set_id_by_index(uint32_t index) const; + const char* get_spr_set_name(uint32_t set_id) const; }; diff --git a/src/KKdLib/farc.cpp b/src/KKdLib/farc.cpp index cbd3be7a..b9884356 100644 --- a/src/KKdLib/farc.cpp +++ b/src/KKdLib/farc.cpp @@ -818,7 +818,7 @@ static errno_t farc_read_header(farc* f, stream& s) { } static void farc_unpack_files(farc* f, stream& s, bool save) { - if (!f || s.check_null()) + if (!f || s.check_null() || !f->files.size()) return; size_t max_path_len = 0; diff --git a/src/KKdLib/obj.cpp b/src/KKdLib/obj.cpp index ddac53fa..756073b2 100644 --- a/src/KKdLib/obj.cpp +++ b/src/KKdLib/obj.cpp @@ -324,6 +324,11 @@ obj_bounding_sphere::obj_bounding_sphere() : radius() { } +obj_bounding_sphere::obj_bounding_sphere(vec3 center, float_t radius) { + this->center = center; + this->radius = radius; +} + obj_material_shader_lighting_type obj_material_shader_attrib::get_lighting_type() const { if (!m.is_lgt_diffuse && !m.is_lgt_specular) return OBJ_MATERIAL_SHADER_LIGHTING_CONSTANT; diff --git a/src/KKdLib/obj.hpp b/src/KKdLib/obj.hpp index 1ba2964e..09982b26 100644 --- a/src/KKdLib/obj.hpp +++ b/src/KKdLib/obj.hpp @@ -165,6 +165,7 @@ struct obj_bounding_sphere { float_t radius; obj_bounding_sphere(); + obj_bounding_sphere(vec3 center, float_t radius); }; struct obj_shader_compo_member { diff --git a/src/KKdLib/prj/algorithm.hpp b/src/KKdLib/prj/algorithm.hpp index ec2ff2b0..945ae6a6 100644 --- a/src/KKdLib/prj/algorithm.hpp +++ b/src/KKdLib/prj/algorithm.hpp @@ -37,4 +37,10 @@ namespace prj { if (vec.size() != end - begin) vec.resize(end - begin); } + + template + void sort_unique(std::vector& vec) { + sort(vec); + unique(vec); + } } diff --git a/src/KKdLib/prj/vector_pair.hpp b/src/KKdLib/prj/vector_pair.hpp new file mode 100644 index 00000000..e9e06ce7 --- /dev/null +++ b/src/KKdLib/prj/vector_pair.hpp @@ -0,0 +1,84 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder + + Taken from MSVC's VC/include/memory +*/ + +#pragma once + +#include "../default.hpp" +#include +#include + +namespace prj { + template + class vector_pair : public std::vector> { + public: + inline void sort() { + std::sort(this->begin(), this->end(), + [](const std::pair& a, const std::pair& b) { + return a.first < b.first; + }); + } + + inline void unique() { + if (this->size() <= 1) + return; + + auto begin = this->begin(); + auto end = this->end(); + for (auto i = begin, j = begin + 1; i != end && j != end; ) + if (i->first == j->first) { + std::move(j + 1, end, j); + end--; + } + else { + i++; + j++; + } + + if (this->size() != end - begin) + this->resize(end - begin); + } + + inline void sort_unique() { + sort(); + unique(); + } + + inline typename auto find(T key) { + auto k = this->begin(); + size_t l = this->size(); + size_t temp; + while (l > 0) { + if (k[temp = l / 2].first >= key) + l /= 2; + else { + k += temp + 1; + l -= temp + 1; + } + } + if (k == this->end() || key < k->first) + return this->end(); + return k; + } + + inline typename auto find(T key) const { + auto k = this->begin(); + size_t l = this->size(); + size_t temp; + while (l > 0) { + if (k[temp = l / 2].first >= key) + l /= 2; + else { + k += temp + 1; + l -= temp + 1; + } + } + if (k == this->end() || key < k->first) + return this->end(); + return k; + } + }; +} diff --git a/src/ReDIVA/data_initialize.cpp b/src/ReDIVA/data_initialize.cpp index df391eff..83234814 100644 --- a/src/ReDIVA/data_initialize.cpp +++ b/src/ReDIVA/data_initialize.cpp @@ -9,6 +9,7 @@ #include "../CRE/item_table.hpp" #include "../CRE/object.hpp" #include "../CRE/sound.hpp" +#include "../CRE/sprite.hpp" #include "game_state.hpp" extern uint32_t dbg_set_id; @@ -35,21 +36,16 @@ bool TaskDataInit::Ctrl() { switch (state) { case 0: { - //sub_14063FB20(); - - std::string v10 = {}; - //sub_140640E10(4, &v10); - - std::string v14 = {}; - //sub_140640E10(472, &v14); - - std::string v12 = {}; - //sub_140640E10(43, &v12); + sprite_manager_reset_res_data(); + //sprite_manager_load_set(4, ""); + //sprite_manager_load_set(472, ""); + //sprite_manager_load_set(43, ""); //fontmap_data_read_file(); state = 1; } break; case 1: - //if (!SprLoadSetFile(4) && !SprLoadSetFile(472) && !SprLoadSetFile(43) && !fontmap_data_parse_file()) + //if (!sprite_manager_load_file(4) && !sprite_manager_load_file(472) + // && !sprite_manager_load_file(43) && !fontmap_data_parse_file()) state = field_6C ? 2 : 4; break; case 2: @@ -61,21 +57,15 @@ bool TaskDataInit::Ctrl() { state = 4; break; case 4: { - std::string v9 = {}; - //sub_140640E10(32, &v9); - - std::string v11 = {}; - //sub_14019D650(26, &v11); - - std::string v13 = {}; - //sub_140640E10(34, &v13); - - std::string v15 = {}; - //sub_14019D650(35, &v15); + //sprite_manager_load_set(32, ""); + //aet_manager_load_set(26, ""); + //sprite_manager_load_set(34, ""); + //aet_manager_load_set(35, ""); state = 5; } break; case 5: - //if (SprLoadSetFile(32) || AetLoadSetFile(26) || SprLoadSetFile(34) || AetLoadSetFile(35)) + //if (!sprite_manager_load_file(32) && !aet_manager_load_file(26) + // && !sprite_manager_load_file(34) && !aet_manager_load_file(35)) // break; state = 6; diff --git a/src/ReDIVA/data_test/glitter_test.cpp b/src/ReDIVA/data_test/glitter_test.cpp index 47ac4384..4e25e7b3 100644 --- a/src/ReDIVA/data_test/glitter_test.cpp +++ b/src/ReDIVA/data_test/glitter_test.cpp @@ -133,6 +133,19 @@ bool TaskDataTestGlitterParticle::Dest() { return true; } +void TaskDataTestGlitterParticle::Disp() { + if (show_grid) { + mdl::EtcObj etc = {}; + etc.init(mdl::ETC_OBJ_GRID); + etc.color = { 0.0f, 0.0f, 0.0f, 1.0f }; + etc.data.grid.w = 50; + etc.data.grid.h = 50; + etc.data.grid.ws = 50; + etc.data.grid.hs = 50; + rctx_ptr->disp_manager.entry_obj_etc(&mat4_identity, &etc); + } +} + void TaskDataTestGlitterParticle::Window() { ImGuiIO& io = ImGui::GetIO(); ImGuiStyle& style = ImGui::GetStyle(); diff --git a/src/ReDIVA/data_test/glitter_test.hpp b/src/ReDIVA/data_test/glitter_test.hpp index 17a4e3c6..1bfc1405 100644 --- a/src/ReDIVA/data_test/glitter_test.hpp +++ b/src/ReDIVA/data_test/glitter_test.hpp @@ -42,6 +42,7 @@ public: virtual bool Init() override; virtual bool Ctrl() override; virtual bool Dest() override; + virtual void Disp() override; virtual void Window() override; void LoadFile(const char* file); diff --git a/src/ReDIVA/data_test/motion_test.cpp b/src/ReDIVA/data_test/motion_test.cpp index b5e9556b..9c5dc79d 100644 --- a/src/ReDIVA/data_test/motion_test.cpp +++ b/src/ReDIVA/data_test/motion_test.cpp @@ -766,8 +766,7 @@ static void motion_test_objset_load() { motion_test_objset.push_back(hnd_itm.obj_right.set_id); } - prj::sort(motion_test_objset); - prj::unique(motion_test_objset); + prj::sort_unique(motion_test_objset); data_struct* aft_data = &data_list[DATA_AFT]; object_database* aft_obj_db = &aft_data->data_ft.obj_db; diff --git a/src/ReDIVA/render.cpp b/src/ReDIVA/render.cpp index 6a19893d..c4c2b17d 100644 --- a/src/ReDIVA/render.cpp +++ b/src/ReDIVA/render.cpp @@ -17,6 +17,7 @@ #include "../CRE/fbo.hpp" #include "../CRE/file_handler.hpp" #include "../CRE/gl_state.hpp" +#include "../CRE/hand_item.hpp" #include "../CRE/light_param.hpp" #include "../CRE/lock.hpp" #include "../CRE/mdata_manager.hpp" @@ -28,6 +29,7 @@ #include "../CRE/shader.hpp" #include "../CRE/shader_dev.hpp" #include "../CRE/shader_ft.hpp" +#include "../CRE/sprite.hpp" #include "../CRE/stage.hpp" #include "../CRE/stage_modern.hpp" #include "../CRE/stage_param.hpp" @@ -334,7 +336,7 @@ bool render_data::load() { if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) return false; - glGetError(); + gl_state_get_error(); glViewport(0, 0, width, height); return true; } @@ -584,31 +586,31 @@ static render_context* render_context_load() { for (int32_t i = 800; i <= 831; i++) { sprintf_s(buf, sizeof(buf), i == 815 ? "EFFPV%03d" : "ITMPV%03d", i); - const object_set_info* effpv_set_info; - if (aft_obj_db->get_object_set_info(buf, &effpv_set_info)) { + const object_set_info* effpv_set_info = aft_obj_db->get_object_set_info(buf); + if (effpv_set_info) { obj_set_ids.push_back(effpv_set_info->id); obj_set_id_name.insert({ effpv_set_info->id, buf }); } sprintf_s(buf, sizeof(buf), "STGPV%03d", i); - const object_set_info* stgpv_set_info; - if (aft_obj_db->get_object_set_info(buf, &stgpv_set_info)) { + const object_set_info* stgpv_set_info = aft_obj_db->get_object_set_info(buf); + if (stgpv_set_info) { obj_set_ids.push_back(stgpv_set_info->id); obj_set_id_name.insert({ stgpv_set_info->id, buf }); } sprintf_s(buf, sizeof(buf), "STGPV%03dHRC", i); - const object_set_info* stgpvhrc_set_info; - if (aft_obj_db->get_object_set_info(buf, &stgpvhrc_set_info)) { + const object_set_info* stgpvhrc_set_info = aft_obj_db->get_object_set_info(buf); + if (stgpvhrc_set_info) { obj_set_ids.push_back(stgpvhrc_set_info->id); obj_set_id_name.insert({ stgpvhrc_set_info->id, buf }); } for (uint32_t& i : obj_set_ids) { - const object_set_info* set_info; - if (!aft_obj_db->get_object_set_info(i, &set_info)) + const object_set_info* set_info = aft_obj_db->get_object_set_info(i); + if (!set_info) continue; farc f; @@ -848,6 +850,10 @@ static render_context* render_context_load() { cmn_set_id = aft_mot_db->get_motion_set_id("CMN"); dbg_set_id = aft_obj_db->get_object_set_id("DBG"); + hand_item_handler_data_init(); + //rob_sleeve_data_init(); + sprite_manager_init(); + render_timer->reset(); for (int32_t i = 0; i < 30; i++) { render_timer->start_of_cycle(); @@ -1119,6 +1125,16 @@ static void render_context_dispose(render_context* rctx) { sound_work_unload_farc("rom/sound/slide_long.farc"); object_storage_unload_set(dbg_set_id); + //AetUnloadSet(26); + //SprUnloadSet(32); + //AetUnloadSet(35); + //SprUnloadSet(34); + //SprUnloadSet(4); + //SprUnloadSet(472); + //SprUnloadSet(43); + hand_item_handler_data_free(); + //rob_sleeve_data_free(); + sprite_manager_free(); //rob_chara_array_free_chara_id(0); render_timer->reset(); diff --git a/src/ReDIVA/x_pv_game.cpp b/src/ReDIVA/x_pv_game.cpp index 58b05cda..f8bda7d1 100644 --- a/src/ReDIVA/x_pv_game.cpp +++ b/src/ReDIVA/x_pv_game.cpp @@ -5055,10 +5055,10 @@ static bool x_pv_game_dsc_process(x_pv_game* a1, int64_t curr_time) { if (disp == 1) { rob_chr->set_visibility(true); - /*if (rob_chara::check_for_ageageagain_module(chara_index, module_index)) { - sub_1405430F0(chara_id, 1); - sub_1405430F0(chara_id, 2); - }*/ + if (rob_chara_check_for_ageageagain_module(rob_chr->chara_index, rob_chr->module_index)) { + rob_chara_age_age_array_set_skip(rob_chr->chara_id, 1); + rob_chara_age_age_array_set_skip(rob_chr->chara_id, 2); + } //pv_game::set_data_itmpv_visibility(a1->pv_game, a1->chara_id, true); for (x_pv_play_data_set_motion& i : playdata->set_motion) { @@ -5821,10 +5821,10 @@ static bool x_pv_game_dsc_process(x_pv_game* a1, int64_t curr_time) { 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)) { - sub_1405430F0(rob_chr->chara_id, 1); - sub_1405430F0(rob_chr->chara_id, 2); - }*/ + if (rob_chara_check_for_ageageagain_module(rob_chr->chara_index, rob_chr->module_index)) { + rob_chara_age_age_array_set_skip(rob_chr->chara_id, 1); + rob_chara_age_age_array_set_skip(rob_chr->chara_id, 2); + } } break; case DSC_X_SCENE_ROT: { float_t scene_rot_y = (float_t)(int32_t)data[0] * 0.001f; @@ -6964,10 +6964,10 @@ static void x_pv_game_split_auth_3d_hrc_material_list(x_pv_game* xpvgm, dst_obj->id = hash; dst_obj->hash = hash; - object_set_info* set_info; - if (obj_db.get_object_set_info(i.first.set_id, (const object_set_info**)&set_info)) { - object_info_data* info; - if (!obj_db.get_object_info_data_by_murmurhash(hash, (const object_info_data**)&info)) { + object_set_info* set_info = (object_set_info*)obj_db.get_object_set_info(i.first.set_id); + if (set_info) { + object_info_data* info = (object_info_data*)obj_db.get_object_info_data_by_murmurhash(hash); + if (!info) { set_info->object.push_back({}); info = &set_info->object.back(); info->id = hash;