Smth big is coming

This commit is contained in:
korenkonder
2023-05-20 01:33:55 +03:00
parent 53b99ffc78
commit a348230f5c
10 changed files with 696 additions and 52 deletions
+295 -17
View File
@@ -109,6 +109,67 @@ struct OpdMakeWorker : public app::Task {
bool AddTask(bool a2);
};
struct osage_play_data_init_header {
uint32_t signature;
std::pair<uint16_t, uint16_t> 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<uint16_t, uint16_t> 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<object_info, uint32_t> opd_req_data;
std::list<p_file_handler*> file_handlers;
std::map<std::pair<object_info, uint32_t>, 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<uint32_t>& 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<uint32_t> 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_blend_data>& 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<uint32_t>& 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<object_info, int32_t>& 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<rob_chara*>* 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<rob_chara*>::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<rob_chara*>::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;
}