diff --git a/src/CRE/auth_2d.cpp b/src/CRE/auth_2d.cpp index 91d48bf4..bdb435d2 100644 --- a/src/CRE/auth_2d.cpp +++ b/src/CRE/auth_2d.cpp @@ -237,6 +237,10 @@ void AetComp::Add(const char* name, aet_layout_data& data) { this->data.insert({ name, data }); } +void AetComp::Clear() { + data.clear(); +} + aet_layout_data* AetComp::Find(const char* name) { auto elem = data.find(name); if (elem != data.end()) diff --git a/src/CRE/auth_2d.hpp b/src/CRE/auth_2d.hpp index fe46dc63..4f4f780a 100644 --- a/src/CRE/auth_2d.hpp +++ b/src/CRE/auth_2d.hpp @@ -93,6 +93,7 @@ struct AetComp { ~AetComp(); void Add(const char* name, aet_layout_data& data); + void Clear(); aet_layout_data* Find(const char* name); static void put_number_sprite(int32_t value, int32_t max_digits, diff --git a/src/CRE/draw_object.cpp b/src/CRE/draw_object.cpp index d176430a..3470f59f 100644 --- a/src/CRE/draw_object.cpp +++ b/src/CRE/draw_object.cpp @@ -74,6 +74,7 @@ namespace mdl { case mdl::ETC_OBJ_LINE: case mdl::ETC_OBJ_CROSS: case mdl::ETC_OBJ_CAPSULE: // Added + case mdl::ETC_OBJ_ELLIPSE: // Added break; default: return; @@ -153,6 +154,12 @@ namespace mdl { else shaders_ft.draw_elements(GL_TRIANGLES, etc->count, GL_UNSIGNED_INT, (void*)etc->offset); break; + case mdl::ETC_OBJ_ELLIPSE: // Added + if (etc->data.ellipse.wire) + shaders_ft.draw_elements(GL_LINES, etc->count, GL_UNSIGNED_INT, (void*)etc->offset); + else + shaders_ft.draw_elements(GL_TRIANGLES, etc->count, GL_UNSIGNED_INT, (void*)etc->offset); + break; } shader::unbind(); uniform_value_reset(); diff --git a/src/CRE/post_process.cpp b/src/CRE/post_process.cpp index d56b968c..c2a257b8 100644 --- a/src/CRE/post_process.cpp +++ b/src/CRE/post_process.cpp @@ -700,14 +700,9 @@ void post_process::reset() { mlaa = true; mag_filter = POST_PROCESS_MAG_FILTER_BILINEAR; dof->initialize_data(0, 0); - const vec3 radius = { 2.0f, 2.0f, 2.0f }; - const vec3 intensity = { 1.0f, 1.0f, 1.0f }; - blur->initialize_data(radius, intensity); - const vec3 scene_fade_color = { 1.0f, 1.0f, 1.0f }; - const vec3 tone_trans_start = { 0.0f, 0.0f, 0.0f }; - const vec3 tone_trans_end = { 1.0f, 1.0f, 1.0f }; - tone_map->initialize_data(2.0f, true, 1.0f, 1, 1.0f, scene_fade_color, 0.0f, - 0, tone_trans_start, tone_trans_end, TONE_MAP_YCC_EXPONENT); + blur->initialize_data(2.0f, 1.0f); + tone_map->initialize_data(2.0f, true, 1.0f, 1, 1.0f, + 1.0f, 0.0f, 0, 0.0f, 1.0f, TONE_MAP_YCC_EXPONENT); reset_exposure = true; } diff --git a/src/CRE/render_context.cpp b/src/CRE/render_context.cpp index dabffc5c..0dcb63dd 100644 --- a/src/CRE/render_context.cpp +++ b/src/CRE/render_context.cpp @@ -207,6 +207,14 @@ namespace mdl { pos[0] = { 0.0f, 0.0f, 0.0f }; pos[1] = { 0.0f, 0.0f, 1.0f }; } + + EtcObjEllipse::EtcObjEllipse() : wire() { + radius = 1.0f; + slices = 8; + stacks = 8; + pos[0] = { 0.0f, 0.0f, 0.0f }; + pos[1] = { 0.0f, 0.0f, 1.0f }; + } EtcObj::Data::Data() : capsule() { @@ -249,6 +257,9 @@ namespace mdl { case ETC_OBJ_CAPSULE: // Added data.capsule = {}; break; + case ETC_OBJ_ELLIPSE: // Added + data.ellipse = {}; + break; } } @@ -1153,17 +1164,18 @@ namespace mdl { int32_t slices, int32_t stacks, float_t length, float_t radius) { if (slices < 2 || stacks < 2) return; - else if (length < 0.00001f) { + + stacks = ((stacks + 1) >> 1) << 1; + + if (length < 0.00001f) { gen_sphere_vertices(data, slices, stacks, radius); return; } - stacks = ((stacks + 1) >> 1) << 1; + length *= 0.5f; data.reserve(sizeof(vec3) * 2); - length *= 0.5f; - data.push_back(0.0f); data.push_back(radius + length); data.push_back(0.0f); @@ -1236,11 +1248,12 @@ namespace mdl { int32_t slices, int32_t stacks, float_t length) { if (slices < 2 || stacks < 2) return 0; - else if (length < 0.00001f) - return gen_sphere_indices(indices, slices, stacks); stacks = ((stacks + 1) >> 1) << 1; + if (length < 0.00001f) + return gen_sphere_indices(indices, slices, stacks); + { int32_t m1 = 0; int32_t m2 = 1; @@ -1348,6 +1361,76 @@ namespace mdl { return wire_offset; } + static void gen_ellipse_vertices(std::vector& data, + int32_t slices, int32_t stacks, float_t length, float_t radius) { + if (slices < 2 || stacks < 2) + return; + + stacks = ((stacks + 1) >> 1) << 1; + + if (length < 0.00001f) { + gen_sphere_vertices(data, slices, stacks, radius); + return; + } + + length *= 0.5f; + + data.reserve(sizeof(vec3) * 2); + + data.push_back(0.0f); + data.push_back(radius + length); + data.push_back(0.0f); + + data.push_back(0.0f); + data.push_back(1.0f); + data.push_back(0.0f); + + double_t sector_step = (M_PI * 2.0) / (double_t)slices; + double_t stack_step = M_PI / (double_t)stacks; + + for (int32_t i = 1; i < stacks; i++) { + float_t stack_angle = (float_t)((M_PI / 2.0) - (double_t)i * stack_step); + float_t xz = cosf(stack_angle) * radius; + float_t y = sinf(stack_angle); + float_t y_n = y * radius; + y *= radius + length; + + data.reserve(sizeof(vec3) * 2 * slices); + + for (int32_t j = 0; j < slices; j++) { + float_t sector_angle = (float_t)((double_t)j * sector_step); + + float_t x = xz * cosf(sector_angle); + float_t z = xz * sinf(sector_angle); + + data.push_back(x); + data.push_back(y); + data.push_back(z); + + data.push_back(x); + data.push_back(y_n); + data.push_back(z); + } + } + + data.reserve(sizeof(vec3) * 2); + + data.push_back(0.0f); + data.push_back(-radius - length); + data.push_back(0.0f); + + data.push_back(0.0f); + data.push_back(-1.0f); + data.push_back(0.0f); + } + + static size_t gen_ellipse_indices(std::vector& indices, + int32_t slices, int32_t stacks, float_t length) { + stacks = ((stacks + 1) >> 1) << 1; + + return gen_sphere_indices(indices, slices, stacks); + } + void DispManager::add_vertex_array(EtcObj* etc, mat4& mat) { EtcObjType type = etc->type; switch (type) { @@ -1360,6 +1443,7 @@ namespace mdl { case mdl::ETC_OBJ_LINE: case mdl::ETC_OBJ_CROSS: case mdl::ETC_OBJ_CAPSULE: // Added + case mdl::ETC_OBJ_ELLIPSE: // Added break; default: return; @@ -1430,6 +1514,25 @@ namespace mdl { wire = capsule.wire; length = vec3::distance(capsule.pos[0], capsule.pos[1]); } break; + case mdl::ETC_OBJ_ELLIPSE: { // Added + EtcObjEllipse& ellipse = etc->data.ellipse; + + vec3 origin = (ellipse.pos[0] + ellipse.pos[1]) * 0.5f; + mat4_translate_add(&mat, &origin, &mat); + + vec3 dir = vec3::normalize(ellipse.pos[1] - ellipse.pos[0]); + vec3 up = { 0.0f, 1.0f, 0.0f }; + vec3 axis; + float_t angle; + Glitter::axis_angle_from_vectors(&axis, &angle, &up, &dir); + mat4 m; + mat4_mult_axis_angle(&mat4_identity, &axis, angle, &m); + mat4_mult(&m, &mat, &mat); + + indexed = true; + wire = ellipse.wire; + length = vec3::distance(ellipse.pos[0], ellipse.pos[1]); + } break; } DispManager::etc_vertex_array* etc_vertex_array = 0; @@ -1457,7 +1560,12 @@ namespace mdl { && i.data.capsule.slices == etc->data.capsule.slices && ((i.data.capsule.stacks + 1)) >> 1 == ((etc->data.capsule.stacks + 1) >> 1) && fabsf(i.data.capsule.radius - etc->data.capsule.radius) < 0.00001f - && fabsf(vec3::distance(i.data.capsule.pos[0], i.data.capsule.pos[1]) - length) < 0.00001f) + && fabsf(vec3::distance(i.data.capsule.pos[0], i.data.capsule.pos[1]) - length) < 0.00001f + || type == mdl::ETC_OBJ_ELLIPSE // Added + && i.data.ellipse.slices == etc->data.ellipse.slices + && ((i.data.ellipse.stacks + 1)) >> 1 == ((etc->data.ellipse.stacks + 1) >> 1) + && fabsf(i.data.ellipse.radius - etc->data.ellipse.radius) < 0.00001f + && fabsf(vec3::distance(i.data.ellipse.pos[0], i.data.ellipse.pos[1]) - length) < 0.00001f) if (i.vertex_array) { i.alive_time = 2; if (!wire) { @@ -1574,6 +1682,17 @@ namespace mdl { etc_vertex_array->wire_offset = wire_offset * sizeof(uint32_t); etc_vertex_array->wire_count = (GLsizei)(vtx_indices.size() - wire_offset); } break; + case mdl::ETC_OBJ_ELLIPSE: { // Added + EtcObjEllipse& ellipse = etc->data.ellipse; + + gen_ellipse_vertices(vtx_data, ellipse.slices, ellipse.stacks, length, ellipse.radius); + size_t wire_offset = gen_ellipse_indices(vtx_indices, ellipse.slices, ellipse.stacks, length); + + etc_vertex_array->offset = 0; + etc_vertex_array->count = (GLsizei)wire_offset; + etc_vertex_array->wire_offset = wire_offset * sizeof(uint32_t); + etc_vertex_array->wire_count = (GLsizei)(vtx_indices.size() - wire_offset); + } break; } if (!wire) { @@ -2667,6 +2786,9 @@ namespace mdl { case mdl::ETC_OBJ_CAPSULE: // Added length = vec3::distance(etc->data.capsule.pos[0], etc->data.capsule.pos[1]); break; + case mdl::ETC_OBJ_ELLIPSE: // Added + length = vec3::distance(etc->data.ellipse.pos[0], etc->data.ellipse.pos[1]); + break; default: return 0; } @@ -2710,6 +2832,13 @@ namespace mdl { && fabsf(vec3::distance(i.data.capsule.pos[0], i.data.capsule.pos[1]) - length) < 0.00001f) return i.vertex_array; break; + case mdl::ETC_OBJ_ELLIPSE: // Added + if (i.data.ellipse.slices == etc->data.ellipse.slices + && ((i.data.ellipse.stacks + 1)) >> 1 == ((etc->data.ellipse.stacks + 1) >> 1) + && fabsf(i.data.ellipse.radius - etc->data.ellipse.radius) < 0.00001f + && fabsf(vec3::distance(i.data.ellipse.pos[0], i.data.ellipse.pos[1]) - length) < 0.00001f) + return i.vertex_array; + break; } } return 0; diff --git a/src/CRE/render_context.hpp b/src/CRE/render_context.hpp index b89865ed..69248cdd 100644 --- a/src/CRE/render_context.hpp +++ b/src/CRE/render_context.hpp @@ -60,6 +60,7 @@ namespace mdl { ETC_OBJ_LINE, ETC_OBJ_CROSS, ETC_OBJ_CAPSULE, // Added + ETC_OBJ_ELLIPSE, // Added ETC_OBJ_MAX, }; @@ -364,6 +365,16 @@ namespace mdl { EtcObjCapsule(); }; + + struct EtcObjEllipse { // Added + float_t radius; + int32_t slices; + int32_t stacks; + bool wire; + vec3 pos[2]; + + EtcObjEllipse(); + }; struct EtcObj { union Data { @@ -376,6 +387,7 @@ namespace mdl { EtcObjLine line; EtcObjCross cross; EtcObjCapsule capsule; // Added + EtcObjEllipse ellipse; // Added Data(); }; diff --git a/src/CRE/rob/rob.cpp b/src/CRE/rob/rob.cpp index 6ce3f0ad..75e17948 100644 --- a/src/CRE/rob/rob.cpp +++ b/src/CRE/rob/rob.cpp @@ -109,6 +109,67 @@ struct OpdMakeWorker : public app::Task { bool AddTask(bool a2); }; +struct osage_play_data_init_header { + uint32_t signature; + std::pair obj_info; + uint32_t motion_id; + uint16_t nodes_count; +}; + +struct osage_play_data_init_node { + vec3 trans; + vec3 trans_diff; +}; + +struct osage_play_data_header { + uint32_t signature; + std::pair obj_info; + uint32_t motion_id; + uint32_t frame_count; + uint16_t nodes_count; + + osage_play_data_header(); +}; + +struct osage_play_data_node_header { + uint16_t count; + int16_t shift; + int16_t data[]; +}; + +struct opd_file_data { + osage_play_data_header head; + float_t* data; + int32_t load_count; + + void unload(); +}; + +class OsagePlayDataManager : public app::Task { +public: + int32_t state; + prj::vector_pair opd_req_data; + std::list file_handlers; + std::map, opd_file_data> opd_file_data; + + OsagePlayDataManager(); + virtual ~OsagePlayDataManager() override; + + virtual bool Init() override; + virtual bool Ctrl() override; + virtual bool Dest() override; + virtual void Disp() override; + + bool AddTask(); + void AppendCharaMotionId(rob_chara* rob_chr, std::vector& motion_ids); + bool CheckTaskReady(); + void GetOpdFileData(object_info obj_info, + uint32_t motion_id, float_t*& data, uint32_t& count); + void LoadOpdFile(p_file_handler* pfhndl); + void LoadOpdFileList(); + void Reset(); +}; + struct struc_528 { bool field_0; mothead_data_type type; @@ -936,9 +997,6 @@ static void motion_blend_mot_set_blend(motion_blend_mot* a1, static void motion_blend_mot_set_duration(motion_blend_mot* mot, float_t duration, float_t step, float_t offset); -static void osage_play_data_manager_get_opd_file_data(object_info obj_info, - int32_t motion_id, float_t** data, uint32_t* count); - static bool pv_osage_manager_array_get_disp(int32_t* chara_id); static PvOsageManager* pv_osage_manager_array_get(int32_t chara_id); @@ -1085,6 +1143,7 @@ bool rob_manager_rob_impls2_init = false; OpdMakeManager* opd_make_manager; OpdMaker* opd_maker_array; +OsagePlayDataManager* osage_play_data_manager; PvOsageManager* pv_osage_manager_array; rob_cmn_mottbl_header* rob_cmn_mottbl_data; rob_chara_age_age* rob_chara_age_age_array; @@ -2228,6 +2287,29 @@ bool opd_make_manager_del_task() { return opd_make_manager->DelTask(); } +bool osage_play_data_manager_add_task() { + return osage_play_data_manager->AddTask(); +} + +void osage_play_data_manager_append_chara_motion_id(rob_chara* rob_chr, int32_t motion_id) { + std::vector motion_ids; + motion_ids.push_back(motion_id); + osage_play_data_manager->AppendCharaMotionId(rob_chr, motion_ids); +} + +bool osage_play_data_manager_check_task_ready() { + return osage_play_data_manager->CheckTaskReady(); +} + +void osage_play_data_manager_get_opd_file_data(object_info obj_info, + int32_t motion_id, float_t*& data, uint32_t& count) { + osage_play_data_manager->GetOpdFileData(obj_info, motion_id, data, count); +} + +void osage_play_data_manager_reset() { + osage_play_data_manager->Reset(); +} + void pv_osage_manager_array_reset(int32_t chara_id) { pv_osage_manager_array_get(chara_id)->Reset(); } @@ -2239,6 +2321,9 @@ void rob_init() { if (!opd_maker_array) opd_maker_array = new OpdMaker[4]; + if (!osage_play_data_manager) + osage_play_data_manager = new OsagePlayDataManager; + if (!pv_osage_manager_array) pv_osage_manager_array = new PvOsageManager[ROB_CHARA_COUNT]; @@ -2315,6 +2400,11 @@ void rob_free() { pv_osage_manager_array = 0; } + if (osage_play_data_manager) { + delete osage_play_data_manager; + osage_play_data_manager = 0; + } + if (opd_maker_array) { delete[] opd_maker_array; opd_maker_array = 0; @@ -2354,7 +2444,7 @@ static void rob_chara_item_equip_object_load_opd_data(rob_chara_item_equip_objec for (opd_blend_data& i : rob_itm_equip->opd_blend_data) { float_t* opd_data = 0; uint32_t opd_count = 0; - osage_play_data_manager_get_opd_file_data(itm_eq_obj->obj_info, i.motion_id, &opd_data, &opd_count); + osage_play_data_manager_get_opd_file_data(itm_eq_obj->obj_info, i.motion_id, opd_data, opd_count); if (!opd_data) break; @@ -6490,13 +6580,26 @@ static void motion_blend_mot_set_duration(motion_blend_mot* mot, mot->blend->SetDuration(duration, step, offset); } -static void opd_data_decode(int16_t* src_data, size_t count, uint8_t shift, float_t* dst_data) { - float_t div = (float_t)(1 << shift); +static int16_t opd_data_encode_shift(float_t value, uint8_t shift) { + int32_t val = (int)(float)((float)(1 << shift) * value); + if (val & 0x01) + if (val & 0x8000) + val++; + else + val--; + return val; +} + +static float_t opd_data_decode_shift(int16_t value, uint8_t shift) { + return (float_t)value / (float_t)(1 << shift); +} + +static void opd_data_decode(const int16_t* src_data, size_t count, uint8_t shift, float_t* dst_data) { size_t index = 0; for (size_t i = 0; i < count; i++, index++) { - if (src_data[i] & 1) { + if (src_data[i] & 0x01) { float_t first_val = dst_data[index - 1]; - float_t last_val = src_data[i + 1] / div; + float_t last_val = opd_data_decode_shift(src_data[i + 1], shift); float_t diff_val = last_val - first_val; int32_t lerp_count = (int32_t)((src_data[i] >> 1) - (index - 1)); @@ -6507,13 +6610,34 @@ static void opd_data_decode(int16_t* src_data, size_t count, uint8_t shift, floa i++; } else - dst_data[index] = src_data[i] / div; + dst_data[index] = opd_data_decode_shift(src_data[i], shift); } } -static void osage_play_data_manager_get_opd_file_data(object_info obj_info, - int32_t motion_id, float_t** data, uint32_t* count) { - //osage_play_data_manager_get()->GetOpdFileData(v8, obj_info, motion_id, data, count); +static bool opd_decode(const osage_play_data_header* file_head, float_t** opd_decod_buf, osage_play_data_header* head) { + const osage_play_data_node_header* node = (osage_play_data_node_header*)&file_head[1]; + float_t* buf = force_malloc_s(float_t, 3ULL * file_head->frame_count * file_head->nodes_count); + *opd_decod_buf = buf; + if (!buf) + return false; + + for (size_t i = 0; i < file_head->nodes_count; i++) + for (uint32_t i = 3; i; i--) { + opd_data_decode(node->data, node->count, node->shift, buf); + buf += file_head->frame_count; + node = (const osage_play_data_node_header*)((size_t)node + + sizeof(const osage_play_data_node_header) + node->count * sizeof(uint16_t)); + } + + *head = *file_head; + return true; +} + +static bool opd_decode_data(const void* data, float_t** opd_decod_buf, osage_play_data_header* head) { + if (!*opd_decod_buf) + return false; + + return opd_decode((const osage_play_data_header*)data, opd_decod_buf, head); } static bool pv_osage_manager_array_get_disp(int32_t* chara_id) { @@ -12279,8 +12403,7 @@ void rob_chara_item_equip_object::check_no_opd(std::vector& opd_ for (::opd_blend_data& i : opd_blend_data) { float_t* opd_data = 0; uint32_t opd_count = 0; - osage_play_data_manager_get_opd_file_data(obj_info, - i.motion_id, &opd_data, &opd_count); + osage_play_data_manager_get_opd_file_data(obj_info, i.motion_id, opd_data, opd_count); if (!opd_data) { use_opd = false; break; @@ -16275,6 +16398,59 @@ void OpdMakeWorker::Disp() { } +osage_play_data_header::osage_play_data_header() : frame_count(), nodes_count() { + signature = 0x11033115; + obj_info = { -1, -1 }; + motion_id = -1; +} + +void opd_file_data::unload() { + if (--load_count > 0) + return; + + head = {}; + free_def(data); +} + +OsagePlayDataManager::OsagePlayDataManager() : state() { + Reset(); + state = 0; +} + +OsagePlayDataManager::~OsagePlayDataManager() { + +} + +bool OsagePlayDataManager::Init() { + LoadOpdFileList(); + state = 0; + return true; +} + +bool OsagePlayDataManager::Ctrl() { + if (state) + return false; + + for (auto i = file_handlers.begin(); i != file_handlers.end();) { + if (!(*i)->check_not_ready()) { + LoadOpdFile(*i); + i = file_handlers.erase(i); + } + else + i++; + } + + return !file_handlers.size(); +} + +bool OsagePlayDataManager::Dest() { + return true; +} + +void OsagePlayDataManager::Disp() { + +} + bool OpdMakeWorker::AddTask(bool a2) { if (!task_rob_manager_check_chara_loaded(chara_id)) return false; @@ -16283,6 +16459,108 @@ bool OpdMakeWorker::AddTask(bool a2) { return app::TaskWork::AddTask(this, "OPD_MAKE_WORKER"); } +bool OsagePlayDataManager::AddTask() { + return app::TaskWork::AddTask(this, "OSAGE_PLAY_DATA_MANAGER"); +} + +void OsagePlayDataManager::AppendCharaMotionId(rob_chara* rob_chr, std::vector& motion_ids) { + if (CheckTaskReady() || !rob_chr) + return; + + rob_chara_item_equip* rob_itm_equip = rob_chr->item_equip; + for (int32_t i = ITEM_KAMI; i < ITEM_ITEM16; i++) { + rob_chara_item_equip_object* itm_eq_obj = rob_itm_equip->get_item_equip_object((item_id)i); + if (!itm_eq_obj || itm_eq_obj->obj_info.is_null() + || (!itm_eq_obj->osage_blocks.size() && !itm_eq_obj->cloth_blocks.size())) + continue; + + for (uint32_t j : motion_ids) + opd_req_data.push_back({ itm_eq_obj->obj_info, j }); + } +} + +bool OsagePlayDataManager::CheckTaskReady() { + return app::TaskWork::CheckTaskReady(this); +} + +void OsagePlayDataManager::GetOpdFileData(object_info obj_info, + uint32_t motion_id, float_t*& data, uint32_t& count) { + data = 0; + count = 0; + + auto elem = opd_file_data.find({ obj_info, motion_id }); + if (elem != opd_file_data.end()) { + data = elem->second.data; + count = elem->second.head.frame_count; + } +} + +void OsagePlayDataManager::LoadOpdFile(p_file_handler* pfhndl) { + ::opd_file_data data = {}; + if (opd_decode_data(pfhndl->get_data(), &data.data, &data.head)) + opd_file_data.insert({ { object_info(data.head.obj_info.first, + data.head.obj_info.second), data.head.motion_id }, data }); +} + +void OsagePlayDataManager::LoadOpdFileList() { + data_struct* aft_data = &data_list[DATA_AFT]; + motion_database* aft_mot_db = &aft_data->data_ft.mot_db; + object_database* aft_obj_db = &aft_data->data_ft.obj_db; + + prj::sort_unique(opd_req_data); + for (const std::pair& i : opd_req_data) { + auto elem = opd_file_data.find(i); + if (elem == opd_file_data.end()) + continue; + + const char* object_name = aft_obj_db->get_object_name(i.first); + if (!object_name) + continue; + + const char* motion_name = aft_mot_db->get_motion_name(i.second); + if (!motion_name) + continue; + + char obj_name_buf[0x200]; + strcpy_s(obj_name_buf, sizeof(obj_name_buf), object_name); + + for (int32_t i = 0; obj_name_buf[i]; i++) { + char c = obj_name_buf[i]; + if (c >= 'A' && c <= 'Z') + c += 0x20; + obj_name_buf[i] = c; + } + + char mot_name_buf[0x200]; + strcpy_s(mot_name_buf, sizeof(mot_name_buf), motion_name); + + for (int32_t i = 0; mot_name_buf[i]; i++) { + char c = mot_name_buf[i]; + if (c >= 'A' && c <= 'Z') + c += 0x20; + mot_name_buf[i] = c; + } + + char file_buf[0x200]; + sprintf_s(file_buf, sizeof(file_buf), "%s_%s.%s", obj_name_buf, mot_name_buf, "opd"); + + char farc_buf[0x200]; + sprintf_s(farc_buf, sizeof(farc_buf), "%s.farc", obj_name_buf); + + if (aft_data->check_file_exists("rom/osage_play_data/", farc_buf)) { + file_handlers.push_back(new p_file_handler); + file_handlers.back()->read_file(aft_data, "rom/osage_play_data/", farc_buf, file_buf, true); + } + } + opd_req_data.clear(); +} + +void OsagePlayDataManager::Reset() { + file_handlers.clear(); + opd_req_data.clear(); + opd_file_data.clear(); +} + struc_527::struc_527(rob_chara* rob_chr, int32_t stage_index, uint32_t motion_id, float_t frame, const bone_database* bone_data, const motion_database* mot_db) : rob_chr(), motion_id(), frame(), last_frame(), type_62(), type_62_data(), type_75(), type_75_data(), @@ -17970,7 +18248,7 @@ void RobImplTask::FreeList(int8_t* chara_id, std::list* list) { return; for (auto i = list->begin(); i != list->end();) { - rob_chara* rob_chr = i._Ptr->_Myval; + rob_chara* rob_chr = *i; if (rob_chr->chara_id == *chara_id) i = list->erase(i); else @@ -18757,7 +19035,7 @@ void TaskRobManager::AppendFreeCharaList(rob_chara* rob_chr) { int32_t chara_id = rob_chr->chara_id; for (std::list::iterator i = init_chara.begin(); i != init_chara.end();) - if (i._Ptr->_Myval->chara_id == chara_id) { + if ((*i)->chara_id == chara_id) { i = init_chara.erase(i); return; } @@ -18893,7 +19171,7 @@ void TaskRobManager::FreeLoadedCharaList(int8_t* chara_id) { return; for (std::list::iterator i = loaded_chara.begin(); i != loaded_chara.end();) - if (i._Ptr->_Myval->chara_id == *chara_id) { + if ((*i)->chara_id == *chara_id) { i = loaded_chara.erase(i); return; } diff --git a/src/CRE/rob/rob.hpp b/src/CRE/rob/rob.hpp index d0e7d790..70e5da42 100644 --- a/src/CRE/rob/rob.hpp +++ b/src/CRE/rob/rob.hpp @@ -3500,6 +3500,13 @@ extern void motion_set_unload_mothead(uint32_t set); extern bool opd_make_manager_del_task(); +extern bool osage_play_data_manager_add_task(); +extern void osage_play_data_manager_append_chara_motion_id(rob_chara* rob_chr, int32_t motion_id); +extern bool osage_play_data_manager_check_task_ready(); +extern void osage_play_data_manager_get_opd_file_data(object_info obj_info, + int32_t motion_id, float_t*& data, uint32_t& count); +extern void osage_play_data_manager_reset(); + extern void pv_osage_manager_array_reset(int32_t chara_id); extern void rob_init(); diff --git a/src/ReDIVA/pv_game.cpp b/src/ReDIVA/pv_game.cpp index 0fa6b22a..7232c427 100644 --- a/src/ReDIVA/pv_game.cpp +++ b/src/ReDIVA/pv_game.cpp @@ -171,6 +171,13 @@ pv_play_data_motion_data::~pv_play_data_motion_data() { } +void pv_play_data_motion_data::clear() { + set_motion.clear(); + set_motion.shrink_to_fit(); + set_item.clear(); + set_item.shrink_to_fit(); +} + void pv_play_data_motion_data::reset() { rob_chr = 0; current_time = 0.0f; @@ -213,6 +220,10 @@ pv_disp2d::~pv_disp2d() { } +pv_data_camera::pv_data_camera() : enable(), time() { + id = -1; +} + pv_game_pv_data::pv_game_pv_data() : field_0(), state(), play(), dsc_buffer(), dsc_buffer_counter(), field_2BF30(), field_2BF38(), curr_time(), curr_time_float(), prev_time_float(), field_2BF50(), field_2BF58(), field_2BF60(), field_2BF64(), field_2BF68(), chara_id(), pv_game()/*, field_2BF80()*/, music(), @@ -229,14 +240,174 @@ pv_game_pv_data::~pv_game_pv_data() { } -pv_game_play_data::pv_game_play_data() { +void pv_game_pv_data::reset() { + pv_game = 0i64; + //field_2BF80 = 0; + music = 0i64; + dsc_file_handler.reset(); + play = false; + field_2BF50 = false; + //if (sub_1400E7910(sub_14013C8C0()) >= 6) + // field_2BF60 = false; + + for (pv_play_data& i : playdata) { + i.rob_chr = 0; + i.set_motion.clear(); + i.motion_data.clear(); + pv_expression_array_reset_motion(&i - playdata); + } + + data_camera_branch_fail.clear(); + data_camera_branch_fail.shrink_to_fit(); + data_camera_branch_success.clear(); + data_camera_branch_success.shrink_to_fit(); + change_field_branch_fail.clear(); + change_field_branch_fail.shrink_to_fit(); + change_field_branch_success.clear(); + change_field_branch_success.shrink_to_fit(); + change_field_branch_time = -1i64; + scene_fade_enable = false; + scene_fade_frame = 0.0f; + scene_fade_duration = 0.0f; + scene_fade_start_alpha = 0.0f; + scene_fade_end_alpha = 0.0f; + scene_fade_color = 0.0f; + + reset_camera_post_process(); + + field_2C4E8.clear(); + field_2C4E8.shrink_to_fit(); + field_2C500 = 0; + field_0 = 0; +} + +void pv_game_pv_data::reset_camera_post_process() { + camera* cam = rctx_ptr->camera; + //cam->set_ignore_min_dist(false); + cam->set_max_distance(0.05); + //cam->set_ignore_fov(0); + cam->set_fov(32.2673416137695); + + post_process* pp = &rctx_ptr->post_process; + pp->tone_map->set_scene_fade_color(0.0f); + pp->tone_map->set_scene_fade_alpha(0.0f); + pp->tone_map->set_scene_fade_alpha(0); + pp->tone_map->set_tone_trans(0.0f, 1.0f); + pp->tone_map->set_saturate_coeff(1.0f); + + shadow* shad = rctx_ptr->render_manager.shadow_ptr; + if (shad) + for (bool& i : shad->blur_filter_enable) + i = true; + + branch_mode = false; + + for (pv_data_camera& i : data_camera) + i = {}; +} + +pv_game_play_data::pv_game_play_data() : pv_set(), aet_ids(), aet_ids_enable(), field_1C8(), field_1D0(), +field_1D8(), field_1E0(), field_1E8(), field_1F0(), disp(), field_1FC(), field_204(), field_20C(), +frame_state(), field_218(), fade_begin(), fade_end(), fade(), skin_danger_frame(), field_2FC(), +chance_result(), chance_points(), field_310(), slide_points(), max_slide_points(), pv_spr_set_id(), +pv_aet_set_id(), pv_main_aet_id(), stage_index(), field_33C(), field_350(), field_354(), value_text_spr_index(), +not_clear(), spr_set_back_id(), loaded(), state(), field_36C(), score_preview_update(), field_374(), +field_378(), field_37C(), score_preview_speed(), score_preview(), value_text_display(), field_38C(), +value_text_index(), value_text_time_offset(), combo_state(), combo_count(), combo_disp_time(), field_3AC(), +field_3B0(), field_3B4(), field_3B8(), field_3BC(), aix(), ogg(), field_3C4(), field_5E8(), field_5EC(), +option(), field_5F4(), lyric(), lyric_index(), field_64C(), field_650(), field_654(), field_658(), field_65C() { + chance_points_pos = 0; + slide_points_pos = 0; + max_slide_points_pos = 0; + reset(); + state = 0; } pv_game_play_data::~pv_game_play_data() { } +void pv_game_play_data::reset() { + loaded = false; + score_preview_update = false; + field_378 = false; + score_preview_speed = 0.04f; + field_36C = -1; + combo_state = 4; + pv_set = false; + stage_index = 0; + field_354 = false; + not_clear = false; + pv_spr_set_id = -1; + pv_aet_set_id = -1; + pv_main_aet_id = -1; + + sub_1401362C0(); +} + +void pv_game_play_data::sub_1401362C0() { + for (int32_t i = 0; i < PV_GAME_AET_MAX; i++) { + aet_ids[i] = 0; + aet_ids_enable[i] = false; + } + + for (int32_t i = 0; i < 2; i++) { + field_1C8[i] = 0.0f; + field_1D0[i] = 0.0f; + field_1D8[i] = 0.0f; + field_1E0[i] = 0.0f; + field_1E8[i] = 0.0f; + field_1F0[i] = 0.0f; + disp[i] = false; + field_1FC[i] = 0; + } + + field_1C8[0] = 86.0f; + field_1C8[1] = 138.0f; + field_1D8[0] = 58.0f; + field_1D8[1] = 138.0f; + field_1E8[0] = 58.0f; + field_1E8[1] = -1.0f; + field_1F0[0] = 86.0f; + field_1F0[1] = -1.0f; + field_204[0] = 58.0f; + field_204[1] = 138.0f; + field_20C[0] = 86.0f; + field_20C[1] = 138.0f; + + frame_state = 0; + field_218 = false; + fade_begin = false; + fade_end = false; + fade = PV_GAME_AET_WHITE_FADE; + skin_danger_frame = 0; + field_2FC = 0; + chance_result = 0; + chance_points = 0; + chance_points_pos = 0.0f; + field_310 = 0; + slide_points = 0; + slide_points_pos = 0.0f; + max_slide_points = 0; + max_slide_points_pos = 0.0f; + field_33C = 0; + comp.Clear(); + field_350 = 0.0f; + value_text_spr_index = 0; + spr_set_back_id = -1; + field_374 = 0; + field_37C = 0.0f; + score_preview = 0; + value_text_display = 0; + field_38C = 0.0f; + value_text_index = 0; + value_text_time_offset = 0.0f; + combo_count = 0; + combo_disp_time = 0; + draw_pos = 0.0f; +} + pv_game_chara::pv_game_chara() : chara_index(), cos(), chara_id(), pv_data(), rob_chr() { } @@ -287,12 +458,12 @@ score_slide_chain_bonus(), slide_chain_length(), field_2CF98(), field_2CF9C(), f pv(), field_2CFB0(), chance_point(), reference_score(), field_2CFBC(), field_2CFC0(), field_2CFC4(), field_2CFE0(), field_2CFE4(), notes_passed(), field_2CFF0(), song_energy(), song_energy_base(), song_energy_border(), life_gauge_safety_time(), life_gauge_border(), stage_index(), field_2D00C(), -no_fail(), field_2D00E(), changed_field(), challenge_time_start(), challenge_time_end(), max_time(), -max_time_float(), current_time_float(), current_time(), current_time_float_dup(), field_2D03C(), -score_hold_multi(), score_hold(), score_slide(), has_slide(), has_success_se(), pv_disp2d(), -life_gauge_final(), hit_border(), field_2D05D(), field_2D05E(), field_2D05F(), title_image_init(), -field_2D061(), field_2D062(), field_2D063(), has_auth_3d_frame(), has_light_frame(), has_aet_frame(), -has_aet_list(), field_index(), edit_effect_index(), slidertouch_counter(), change_field_branch_success_counter(), +no_fail(), changed_field(), challenge_time_start(), challenge_time_end(), max_time(), max_time_float(), +current_time_float(), current_time(), current_time_float_dup(), field_2D03C(), score_hold_multi(), +score_hold(), score_slide(), has_slide(), has_success_se(), pv_disp2d(), life_gauge_final(), +hit_border(), field_2D05D(), field_2D05E(), field_2D05F(), title_image_init(), field_2D061(), +field_2D062(), field_2D063(), has_auth_3d_frame(), has_light_frame(), has_aet_frame(), has_aet_list(), +field_index(), edit_effect_index(), slidertouch_counter(), change_field_branch_success_counter(), field_2D080(), field_2D084(), life_gauge_bonus(), life_gauge_total_bonus(), field_2D090(), field_2D091(), field_2D092(), field_2D093(), field_2D094(), field_2D095(), field_2D096(), success(), field_2D098(), field_2D09C(), use_osage_play_data(), pv_end_fadeout(), rival_percentage(), field_2D0A8(), field_2D0AC(), @@ -300,7 +471,7 @@ field_2D0B0(), field_2D0BC(), next_stage(), field_2D0BE(), field_2D0BF(), field_ field_2D7E8(), field_2D7EC(), field_2D808(), field_2D80C(), edit_effect(), camera_auth_3d_uid(), field_2D874(), task_effect_init(), field_2D87C(), current_field(), field_2D8A0(), field_2D8A4(), data_camera_id(), field_2D954(), field_2DAC8(), field_2DACC(), field_2DB28(), field_2DB2C(), field_2DB34() { - + field_2D00E = true; } pv_game_data::~pv_game_data() { @@ -316,7 +487,38 @@ pv_game_item_mask::pv_game_item_mask() { pv_game::pv_game() : loaded(), field_1(), field_2(), end_pv(), field_4(), state(), field_C(), pv_id(), field_14(), modules(), items() { + reset(); + state = 0; + field_C = -1; + pv_id = -1; + + for (int32_t& i : modules) + i = 0; + + data.play_data.field_5EC = 0; + data.play_data.option = 0.0f; + + data.field_2CF98 = 0; + data.song_energy_base = 0.0f; + data.life_gauge_safety_time = 0; + data.life_gauge_border = 0; + data.stage_index = 0; + data.field_2D00C = true; + data.challenge_time_start = -1; + data.challenge_time_end = -1; + data.field_2D061 = false; + data.field_2D062 = false; + data.field_2D063 = false; + data.field_2D0BC = false; + data.next_stage = false; + data.field_2D0BE = false; + data.field_2D0C0 = -1; + data.no_fail = true; + data.task_effect_init = false; + + data.effect_rs_list_hashes.reserve(0x40); + data.effect_rs_list.reserve(0x40); } pv_game::~pv_game() { @@ -624,7 +826,7 @@ bool pv_game::unload() { data.field_2D0BE = false; } - //data.pv_data->reset(); + data.pv_data.reset(); if (data.play_data.ogg) pv_game_music_get()->exclude_flags(PV_GAME_MUSIC_OGG); diff --git a/src/ReDIVA/pv_game.hpp b/src/ReDIVA/pv_game.hpp index 1d9ff94e..e4bf079e 100644 --- a/src/ReDIVA/pv_game.hpp +++ b/src/ReDIVA/pv_game.hpp @@ -272,6 +272,7 @@ struct pv_play_data_motion_data { pv_play_data_motion_data(); ~pv_play_data_motion_data(); + void clear(); void reset(); }; @@ -312,6 +313,8 @@ struct pv_data_camera { bool enable; int32_t id; int64_t time; + + pv_data_camera(); }; struct struc_540 { @@ -376,9 +379,9 @@ struct pv_game_pv_data { int64_t curr_time; float_t curr_time_float; float_t prev_time_float; - int8_t field_2BF50; + bool field_2BF50; int64_t field_2BF58; - int8_t field_2BF60; + bool field_2BF60; int32_t field_2BF64; int64_t field_2BF68; int32_t chara_id; @@ -433,6 +436,9 @@ struct pv_game_pv_data { pv_game_pv_data(); ~pv_game_pv_data(); + + void reset(); + void reset_camera_post_process(); }; struct pv_game_play_data { @@ -450,7 +456,7 @@ struct pv_game_play_data { float_t field_204[2]; float_t field_20C[2]; int32_t frame_state; - int8_t field_218; + bool field_218; bool fade_begin; bool fade_end; pv_game_aet fade; @@ -474,14 +480,14 @@ struct pv_game_play_data { float_t field_350; bool field_354; int32_t value_text_spr_index; - int8_t not_clear; + bool not_clear; int32_t spr_set_back_id; bool loaded; int32_t state; int32_t field_36C; bool score_preview_update; int32_t field_374; - int8_t field_378; + bool field_378; float_t field_37C; float_t score_preview_speed; uint32_t score_preview; @@ -492,8 +498,7 @@ struct pv_game_play_data { int32_t combo_state; int32_t combo_count; float_t combo_disp_time; - float_t draw_x; - float_t draw_y; + vec2 draw_pos; int32_t field_3AC; int32_t field_3B0; int32_t field_3B4; @@ -523,7 +528,7 @@ struct pv_game_play_data { float_t field_5EC; int32_t option; float_t field_5F4; - int8_t lyric[76]; + char lyric[76]; uint8_t lyric_index; vec4u8 lyrics_color; bool field_64C; @@ -534,6 +539,10 @@ struct pv_game_play_data { pv_game_play_data(); ~pv_game_play_data(); + + void reset(); + + void sub_1401362C0(); }; struct pv_game_chara { @@ -673,7 +682,7 @@ struct pv_game_data { int32_t stage_index; bool field_2D00C; bool no_fail; - int8_t field_2D00E; + bool field_2D00E; bool changed_field; int64_t challenge_time_start; int64_t challenge_time_end; @@ -695,8 +704,8 @@ struct pv_game_data { int8_t field_2D05E; int8_t field_2D05F; bool title_image_init; - int8_t field_2D061; - int8_t field_2D062; + bool field_2D061; + bool field_2D062; bool field_2D063; bool has_auth_3d_frame; bool has_light_frame;