diff --git a/src/CRE/auth_2d.cpp b/src/CRE/auth_2d.cpp index e32a0945..41576ef4 100644 --- a/src/CRE/auth_2d.cpp +++ b/src/CRE/auth_2d.cpp @@ -6,373 +6,13 @@ #include #include #include "auth_2d.hpp" +#include "../KKdLib/aet.hpp" #include "../KKdLib/str_utils.hpp" #include "data.hpp" #include "file_handler.hpp" #include "sound.hpp" #include "task.hpp" -enum aet_blend_mode : uint8_t { - AET_BLEND_MODE_NONE = 0, - AET_BLEND_MODE_COPY, - AET_BLEND_MODE_BEHIND, - AET_BLEND_MODE_NORMAL, - AET_BLEND_MODE_DISSOLVE, - AET_BLEND_MODE_ADD, - AET_BLEND_MODE_MULTIPLY, - AET_BLEND_MODE_SCREEN, - AET_BLEND_MODE_OVERLAY, - AET_BLEND_MODE_SOFT_LIGHT, - AET_BLEND_MODE_HARD_LIGHT, - AET_BLEND_MODE_DARKEN, - AET_BLEND_MODE_LIGHTEN, - AET_BLEND_MODE_CLASSIC_DIFFERENCE, - AET_BLEND_MODE_HUE, - AET_BLEND_MODE_SATURATION, - AET_BLEND_MODE_COLOR, - AET_BLEND_MODE_LUMINOSITY, - AET_BLEND_MODE_STENCIL_ALPHA, - AET_BLEND_MODE_STENCIL_LUMA, - AET_BLEND_MODE_SILHOUETTE_ALPHA, - AET_BLEND_MODE_SILHOUETTE_LUMA, - AET_BLEND_MODE_LUMINESCENT_PREMUL, - AET_BLEND_MODE_ALPHA_ADD, - AET_BLEND_MODE_CLASSIC_COLOR_DODGE, - AET_BLEND_MODE_CLASSIC_COLOR_BURN, - AET_BLEND_MODE_EXCLUSION, - AET_BLEND_MODE_DIFFERENCE, - AET_BLEND_MODE_COLOR_DODGE, - AET_BLEND_MODE_COLOR_BURN, - AET_BLEND_MODE_LINEAR_DODGE, - AET_BLEND_MODE_LINEAR_BURN, - AET_BLEND_MODE_LINEAR_LIGHT, - AET_BLEND_MODE_VIVID_LIGHT, - AET_BLEND_MODE_PIN_LIGHT, - AET_BLEND_MODE_HARD_MIX, - AET_BLEND_MODE_LIGHTER_COLOR, - AET_BLEND_MODE_DARKER_COLOR, - AET_BLEND_MODE_SUBTRACT, - AET_BLEND_MODE_DIVIDE, -}; - -enum aet_layer_quality : uint8_t { - AET_LAYER_QUALITY_NONE = 0, - AET_LAYER_QUALITY_WIREFRAME, - AET_LAYER_QUALITY_DRAFT, - AET_LAYER_QUALITY_BEST, -}; - -enum aet_item_type : uint8_t { - AET_ITEM_TYPE_NONE = 0, - AET_ITEM_TYPE_VIDEO, - AET_ITEM_TYPE_AUDIO, - AET_ITEM_TYPE_COMPOSITION, -}; - -struct aet_layer_flag { - uint16_t video_active : 1; - uint16_t audio_active : 1; - uint16_t effects_active : 1; - uint16_t motion_blur : 1; - uint16_t frame_blending : 1; - uint16_t locked : 1; - uint16_t shy : 1; - uint16_t collapse : 1; - uint16_t auto_orient_rotation : 1; - uint16_t adjustment_layer : 1; - uint16_t time_remapping : 1; - uint16_t layer_is_3d : 1; - uint16_t look_at_camera : 1; - uint16_t look_at_point_of_interest : 1; - uint16_t solo : 1; - uint16_t markers_locked : 1; - //uint16_t null_layer : 1; - //uint16_t hide_locked_masks : 1; - //uint16_t guide_layer : 1; - //uint16_t advanced_frame_blending : 1; - //uint16_t sub_layers_render_separately : 1; - //uint16_t environment_layer : 1; -}; - -struct aet_fcurve { - uint32_t keys_count; - const float_t* keys; - - float_t interpolate(float_t frame) const; -}; - -struct aet_fcurve_file { - uint32_t keys_count; - uint32_t keys_offset; -}; - -struct aet_layer_video_3d { - aet_fcurve anchor_z; - aet_fcurve pos_z; - aet_fcurve dir_x; - aet_fcurve dir_y; - aet_fcurve dir_z; - aet_fcurve rot_x; - aet_fcurve rot_y; - aet_fcurve scale_z; -}; - -struct aet_layer_video_3d_file { - aet_fcurve_file anchor_z; - aet_fcurve_file pos_z; - aet_fcurve_file dir_x; - aet_fcurve_file dir_y; - aet_fcurve_file dir_z; - aet_fcurve_file rot_x; - aet_fcurve_file rot_y; - aet_fcurve_file scale_z; -}; - -struct aet_transfer_mode { - aet_blend_mode mode; - uint8_t flag; - uint8_t matte; -}; - -struct aet_layer_video { - aet_transfer_mode transfer_mode; - aet_fcurve anchor_x; - aet_fcurve anchor_y; - aet_fcurve pos_x; - aet_fcurve pos_y; - aet_fcurve rot_z; - aet_fcurve scale_x; - aet_fcurve scale_y; - aet_fcurve opacity; - const aet_layer_video_3d* _3d; -}; - -struct aet_layer_video_file { - aet_transfer_mode transfer_mode; - aet_fcurve_file anchor_x; - aet_fcurve_file anchor_y; - aet_fcurve_file pos_x; - aet_fcurve_file pos_y; - aet_fcurve_file rot_z; - aet_fcurve_file scale_x; - aet_fcurve_file scale_y; - aet_fcurve_file opacity; - uint32_t _3d_offset; -}; - -struct aet_layer_audio { - aet_fcurve volume_l; - aet_fcurve volume_r; - aet_fcurve pan_l; - aet_fcurve pan_r; -}; - -struct aet_layer_audio_file { - aet_fcurve_file volume_l; - aet_fcurve_file volume_r; - aet_fcurve_file pan_l; - aet_fcurve_file pan_r; -}; - -struct aet_camera { - aet_fcurve eye_x; - aet_fcurve eye_y; - aet_fcurve eye_z; - aet_fcurve pos_x; - aet_fcurve pos_y; - aet_fcurve pos_z; - aet_fcurve dir_x; - aet_fcurve dir_y; - aet_fcurve dir_z; - aet_fcurve rot_x; - aet_fcurve rot_y; - aet_fcurve rot_z; - aet_fcurve zoom; -}; - -struct aet_camera_file { - aet_fcurve_file eye_x; - aet_fcurve_file eye_y; - aet_fcurve_file eye_z; - aet_fcurve_file pos_x; - aet_fcurve_file pos_y; - aet_fcurve_file pos_z; - aet_fcurve_file dir_x; - aet_fcurve_file dir_y; - aet_fcurve_file dir_z; - aet_fcurve_file rot_x; - aet_fcurve_file rot_y; - aet_fcurve_file rot_z; - aet_fcurve_file zoom; -}; - -struct aet_video_src { - const char* sprite_name; - int32_t sprite_index; -}; - -struct aet_video_src_file { - uint32_t sprite_name_offset; - int32_t sprite_index; -}; - -struct aet_video { - uint8_t color[3]; - uint16_t width; - uint16_t height; - float_t fpf; - uint32_t sources_count; - const aet_video_src* sources; -}; - -struct aet_video_file { - uint8_t color[3]; - uint16_t width; - uint16_t height; - float_t fpf; - uint32_t sources_count; - uint32_t sources_offset; -}; - -struct aet_audio { - uint32_t sound_index; -}; - -struct aet_comp; - -union aet_item { - const void* none; - uint32_t offset; - const aet_video* video; - const aet_audio* audio; - const aet_comp* comp; - - inline aet_item() : none() { - - } - - inline aet_item(aet_video* video) { - this->video = video; - } - - inline aet_item(aet_audio* audio) { - this->audio = audio; - } - - inline aet_item(aet_comp* comp) { - this->comp = comp; - } -}; - -struct aet_marker { - float_t time; - const char* name; -}; - -struct aet_marker_file { - float_t time; - uint32_t name_offset; -}; - -#pragma warning(push) -#pragma warning(disable: 26495) -struct aet_layer { - const char* name; - float_t start_time; - float_t end_time; - float_t offset_time; - float_t time_scale; - aet_layer_flag flags; - aet_layer_quality quality; - aet_item_type item_type; - aet_item item; - union { - const aet_layer* parent; - uint32_t parent_offset; - }; - uint32_t markers_count; - const aet_marker* markers; - const aet_layer_video* video; - const aet_layer_audio* audio; -}; -#pragma warning(pop) - -struct aet_layer_file { - uint32_t name_offset; - float_t start_time; - float_t end_time; - float_t offset_time; - float_t time_scale; - aet_layer_flag flags; - aet_layer_quality quality; - aet_item_type item_type; - uint32_t item_offset; - uint32_t parent_offset; - uint32_t markers_count; - uint32_t markers_offset; - uint32_t video_offset; - uint32_t audio_offset; -}; - -struct aet_comp { - uint32_t layers_count; - const aet_layer* layers; -}; - -struct aet_comp_file { - uint32_t layers_count; - uint32_t layers_offset; -}; - -struct aet_scene { - const char* name; - float_t start_time; - float_t end_time; - float_t fps; - uint8_t color[3]; - uint32_t width; - uint32_t height; - const aet_camera* camera; - uint32_t comp_count; - const aet_comp* comp; - uint32_t video_count; - const aet_video* video; - uint32_t audio_count; - const aet_audio* audio; -}; - -struct aet_scene_file { - uint32_t name_offset; - float_t start_time; - float_t end_time; - float_t fps; - uint8_t color[3]; - uint32_t width; - uint32_t height; - uint32_t camera_offset; - uint32_t comp_count; - uint32_t comp_offset; - uint32_t video_count; - uint32_t video_offset; - uint32_t audio_count; - uint32_t audio_offset; -}; - -struct aet_set_file { -#pragma warning(suppress: 4200) - uint32_t scene_offsets[]; -}; - -struct aet_set_load_data { - prj::shared_ptr alloc_handler; - size_t data; - std::map layers; - std::map items; - - aet_set_load_data(prj::shared_ptr alloc_handler, size_t data); - ~aet_set_load_data(); -}; - class AetObj { public: aet_info info; @@ -431,6 +71,7 @@ public: virtual void SetColor(const vec4& value); virtual void SetEndTime(float_t value); virtual void SetFrame(float_t value); + virtual void SetFrameRateControl(FrameRateControl* value); virtual void SetPrio(spr::SprPrio value); virtual aet_info GetInfo(); virtual bool GetPlay(); @@ -467,13 +108,16 @@ public: class AetSet { public: uint32_t index; - const aet_scene** scenes; - uint32_t scenes_count; + ::aet_set* aet_set; int32_t load_count; p_file_handler file_handler; bool ready; prj::shared_ptr alloc_handler; + std::string name; + std::vector aet_ids; + uint32_t hash; + AetSet(uint32_t index); virtual ~AetSet(); @@ -482,6 +126,11 @@ public: virtual void Unload(); virtual bool Load(); + virtual void ReadFileModern(uint32_t set_hash, void* data); + virtual bool LoadFileModern(aet_database* aet_db); + virtual void UnloadModern(aet_database* aet_db); + virtual bool LoadModern(aet_database* aet_db); + const aet_marker* GetLayerMarker(const aet_layer* layer, const char* marker_name); void GetLayerMarkerNames(std::vector& vec, const aet_layer* layer); const aet_scene* GetSceneByInfo(aet_info info); @@ -496,11 +145,13 @@ public: class AetMgr : public app::Task { public: - std::map sets; + std::map sets; std::map objects; std::list::iterator> free_objects; uint32_t load_counter; + uint32_t set_counter; + AetMgr(); virtual ~AetMgr(); @@ -510,6 +161,7 @@ public: virtual void Disp() override; virtual void Basic() override; + uint32_t AddSetModern(); void AddAetSets(const aet_database* aet_db); void FreeAetObject(uint32_t id); void FreeAetObject(std::map::iterator it); @@ -518,8 +170,8 @@ public: bool GetObjDisp(uint32_t id); float_t GetObjFrame(uint32_t id); bool GetObjVisible(uint32_t id); - AetSet* GetSet(int32_t index); - bool GetSetReady(int32_t index); + AetSet* GetSet(uint32_t index); + bool GetSetReady(uint32_t index); void GetSetSceneCompLayerNames(std::vector& vec, aet_info info); float_t GetSetSceneEndTime(aet_info info); float GetSetSceneLayerEndTime(aet_info info, const char* layer_name); @@ -528,17 +180,20 @@ public: float_t GetSetSceneLayerStartTime(aet_info info, const char* layer_name); const char* GetSetSceneName(aet_info info); float_t GetSetSceneStartTime(aet_info info); - uint32_t GetSetScenesCount(int32_t index); + uint32_t GetSetScenesCount(uint32_t index); void InitAetLayout(AetComp* comp, AetArgs& args); bool InitAetObj(AetObj& obj, AetArgs& args); uint32_t InitAetObject(AetArgs& args); - bool LoadFile(int32_t index); - void ReadFile(int32_t index, const char* file, std::string& mdata_dir, void* data); + bool LoadFile(uint32_t index); + bool LoadFileModern(uint32_t index, aet_database* aet_db); + void ReadFile(uint32_t index, const char* file, std::string& mdata_dir, void* data); + void ReadFileModern(uint32_t index, uint32_t set_hash, void* data, aet_database* aet_db); void RemoveAetSets(const aet_database* aet_db); void SetObjAlpha(uint32_t id, float_t value); void SetObjColor(uint32_t id, const vec4& value); void SetObjEndTime(uint32_t id, float_t value); void SetObjFrame(uint32_t id, float_t value); + void SetObjFrameRateControl(uint32_t id, FrameRateControl* value); void SetObjPlay(uint32_t id, bool value); void SetObjPosition(uint32_t id, const vec3& value); void SetObjPrio(uint32_t id, spr::SprPrio value); @@ -548,33 +203,12 @@ public: void SetObjSpriteReplace(uint32_t id, std::map& value); void SetObjSpriteTexture(uint32_t id, std::map& value); void SetObjVisible(uint32_t id, bool value); - void UnloadSet(int32_t index); + void UnloadSet(uint32_t index); + void UnloadSetModern(uint32_t index, aet_database* aet_db); }; AetMgr* aet_manager; -static aet_camera* aet_camera_load(aet_set_load_data& load_data, const aet_camera_file* cam_file); -static void aet_comp_set_item_parent(aet_set_load_data& load_data, const aet_comp* comp); -static aet_comp* aet_comps_load(aet_set_load_data& load_data, - size_t comp_count, const aet_comp_file* comps_file); -static void aet_fcurve_load(aet_set_load_data& load_data, - aet_fcurve& fcurve, const aet_fcurve_file& fcurve_file); -static aet_layer* aet_layer_load(aet_set_load_data& load_data, - aet_layer* layer, const aet_layer_file* layer_file); -static aet_layer_audio* aet_layer_audio_load( - aet_set_load_data& load_data, const aet_layer_audio_file* layer_audio_file); -static aet_layer_video* aet_layer_video_load( - aet_set_load_data& load_data, const aet_layer_video_file* layer_video_file); -static aet_layer_video_3d* aet_layer_video_3d_load( - aet_set_load_data& load_data, const aet_layer_video_3d_file* layer_video_3d_file); -static aet_marker* aet_markers_load(aet_set_load_data& load_data, - size_t markers_count, const aet_marker_file* markers_file); -static const aet_comp* aet_scene_get_root_comp(const aet_scene* scene); -static aet_scene* aet_scene_load(aet_set_load_data& load_data, - aet_scene* scene, const aet_scene_file* scene_file); -static aet_video* aet_video_load(aet_set_load_data& load_data, - aet_video* video, const aet_video_file* video_file); - AetArgs::AetArgs() : layer_name(), start_marker(), end_marker(), flags(), index(), layer(), frame_rate_control(), sound_voice(), spr_db() { start_time = -1.0f; @@ -787,6 +421,10 @@ bool aet_manager_load_file(uint32_t set_id, const aet_database* aet_db) { return aet_manager->LoadFile(aet_db->get_aet_set_by_id(set_id)->index); } +bool aet_manager_load_file_modern(uint32_t set_hash, aet_database* aet_db) { + return aet_manager->LoadFileModern(aet_db->get_aet_set_by_id(set_hash)->index, aet_db); +} + void aet_manager_read_file(uint32_t set_id, std::string& mdata_dir, void* data, const aet_database* aet_db) { const aet_db_aet_set* set = aet_db->get_aet_set_by_id(set_id); @@ -799,6 +437,11 @@ void aet_manager_read_file(uint32_t set_id, aet_manager->ReadFile(set->index, set->file_name.c_str(), mdata_dir, data); } +void aet_manager_read_file_modern(uint32_t set_hash, void* data, aet_database* aet_db) { + const aet_db_aet_set* aet_set = aet_db->get_aet_set_by_id(set_hash); + aet_manager->ReadFileModern(aet_set->index, set_hash, data, aet_db); +} + void aet_manager_remove_aet_sets(const aet_database* aet_db) { aet_manager->RemoveAetSets(aet_db); } @@ -819,6 +462,10 @@ void aet_manager_set_obj_frame(uint32_t id, float_t value) { aet_manager->SetObjFrame(id, value); } +void aet_manager_set_obj_frame_rate_control(uint32_t id, FrameRateControl* value) { + aet_manager->SetObjFrameRateControl(id, value); +} + void aet_manager_set_obj_play(uint32_t id, bool value) { aet_manager->SetObjPlay(id, value); } @@ -859,6 +506,10 @@ void aet_manager_unload_set(uint32_t set_id, const aet_database* aet_db) { aet_manager->UnloadSet(aet_db->get_aet_set_by_id(set_id)->index); } +void aet_manager_unload_set_modern(uint32_t set_hash, aet_database* aet_db) { + aet_manager->UnloadSetModern(aet_db->get_aet_set_by_id(set_hash)->index, aet_db); +} + void aet_manager_free() { if (aet_manager) { delete aet_manager; @@ -866,45 +517,6 @@ void aet_manager_free() { } } -float_t aet_fcurve::interpolate(float_t frame) const { - if (!keys_count) - return 0.0f; - else if (keys_count == 1) - return keys[0]; - - size_t keys_count = this->keys_count; - const float_t* keys = this->keys; - const float_t* values = &keys[keys_count]; - if (frame <= keys[0]) - return values[0]; - - const float_t* v6 = keys; - const float_t* v7 = &keys[keys_count]; - if (frame >= keys[keys_count - 1]) - return values[(keys_count - 1) * 2]; - - const float_t* v8 = &keys[keys_count / 2]; - while (v6 < v8) { - if (frame >= *v8) - v6 = v8; - else - v7 = v8; - v8 = &v6[(v7 - v6) / 2]; - } - - if (values - 1 <= v8) - return values[(keys_count - 1) * 2]; - - size_t v9 = (v8 - keys) * 2; - - float_t df = v8[1] - v8[0]; - float_t t = (frame - v8[0]) / df; - float_t t_1 = t - 1.0f; - return (t_1 * values[v9 + 1] + t * values[v9 + 3]) * t * t_1 * df - + t * t * (3.0f - 2.0f * t) * values[v9 + 2] - + (1.0f + 2.0f * t) * ((1.0f - t) * (1.0f - t)) * values[v9]; -} - AetObj::AetObj() : scene(), comp(), layer(), start_time(), end_time(), flags(), layer_index(), frame_speed(), frame(), matte(), opacity(), frame_rate_control(), sound_voice(), use_float(), spr_db() { @@ -921,16 +533,6 @@ AetObj::~AetObj() { } -aet_set_load_data::aet_set_load_data( - prj::shared_ptr alloc_handler, size_t data) { - this->alloc_handler = alloc_handler; - this->data = data; -} - -aet_set_load_data::~aet_set_load_data() { - -} - void AetObj::Init(AetArgs& args, const aet_scene* scene, const aet_comp* comp, const aet_layer* layer, const aet_marker* start_marker, const aet_marker* end_marker, resolution_mode mode) { start_time = scene->start_time; @@ -1159,6 +761,10 @@ void AetObj::SetFrame(float_t value) { frame = value; } +void AetObj::SetFrameRateControl(FrameRateControl* value) { + frame_rate_control = value; +} + void AetObj::SetPrio(spr::SprPrio value) { prio = value; } @@ -1567,8 +1173,9 @@ void AetLyo::DispLayer(const mat4& mat, const aet_layer* layer, DispComp(m, layer->item.comp, frame, opacity, spr_db); } -AetSet::AetSet(uint32_t index) : scenes(), scenes_count(), load_count(), ready() { +AetSet::AetSet(uint32_t index) : aet_set(), load_count(), ready() { this->index = index; + hash = hash_murmurhash_empty; } AetSet::~AetSet() { @@ -1584,6 +1191,7 @@ void AetSet::ReadFile(const char* dir, const char* file, void* data) { load_count = 1; file_handler.read_file(data, dir, file); ready = false; + aet_set = 0; } bool AetSet::LoadFile() { @@ -1598,39 +1206,6 @@ bool AetSet::LoadFile() { return true; } -bool AetSet::Load() { - size_t data = (size_t)file_handler.get_data(); - if (!data) { - scenes = 0; - return false; - } - - prj::shared_ptr& alloc = alloc_handler; - alloc = prj::shared_ptr(new prj::stack_allocator); - - uint32_t scenes_count = 0; - const aet_set_file* set_file = (const aet_set_file*)data; - while (set_file->scene_offsets[scenes_count]) - scenes_count++; - this->scenes_count = scenes_count; - - aet_set_load_data load_data(alloc, data); - aet_scene** scenes = alloc->allocate(scenes_count); - this->scenes = (const aet_scene**)scenes; - - for (uint32_t i = scenes_count, j = 0; i; i--, j++) - scenes[j] = aet_scene_load(load_data, alloc->allocate(), - (aet_scene_file*)(data + set_file->scene_offsets[j])); - - for (uint32_t i = scenes_count, j = 0; i; i--, j++) { - aet_scene* scene = scenes[j]; - const aet_comp* comp = scene->comp; - for (uint32_t k = scene->comp_count; k; k--, comp++) - aet_comp_set_item_parent(load_data, comp); - } - return true; -} - void AetSet::Unload() { if (load_count > 1) { load_count--; @@ -1639,12 +1214,151 @@ void AetSet::Unload() { alloc_handler.reset(); file_handler.reset(); + aet_set = 0; - scenes = 0; ready = false; load_count = 0; } +bool AetSet::Load() { + const void* data = file_handler.get_data(); + size_t size = file_handler.get_size(); + if (!data || !size) + return false; + + prj::shared_ptr& alloc = alloc_handler; + alloc = prj::shared_ptr(new prj::stack_allocator); + + ::aet_set* set = alloc->allocate<::aet_set>(); + this->aet_set = set; + set->unpack_file(alloc_handler, data, size, false); + if (!set->ready) + return false; + + file_handler.reset(); + return true; +} + +void AetSet::ReadFileModern(uint32_t set_hash, void* data) { + if (load_count > 1) { + load_count++; + return; + } + + std::string file; + if (((data_struct*)data)->get_file("root+/2d/", set_hash, ".farc", file)) + file_handler.read_file(data, "root+/2d/", file.c_str()); + this->hash = set_hash; + ready = false; + aet_set = 0; +} + +bool AetSet::LoadFileModern(aet_database* aet_db) { + if (ready) + return false; + else if (file_handler.check_not_ready()) + return true; + else if (!LoadModern(aet_db)) + return false; + + ready = true; + return true; +} + +void AetSet::UnloadModern(aet_database* aet_db) { + if (load_count > 1) { + load_count--; + return; + } + + aet_db->remove_aet_set(hash, index, name.c_str(), aet_ids); + + if (load_count > 1) { + load_count--; + return; + } + + alloc_handler.reset(); + file_handler.reset(); + aet_set = 0; + + ready = false; + load_count = 0; + + hash = hash_murmurhash_empty; + name.clear(); + aet_ids.clear(); +} + +bool AetSet::LoadModern(aet_database* aet_db) { + if (ready) + return false; + else if (file_handler.check_not_ready()) + return true; + + const void* data = file_handler.get_data(); + size_t size = file_handler.get_size(); + if (!data || !size) + return false; + + farc f; + f.read(data, size, true); + + std::string& file = file_handler.ptr->file; + + size_t file_len = file.size(); + if (file_len >= 0x100 - 4) + return false; + + const char* t = strrchr(file.c_str(), '.'); + if (t) + file_len = t - file.c_str(); + + char buf[0x100]; + memcpy(buf, file.c_str(), file_len); + char* ext = buf + file_len; + size_t ext_len = sizeof(buf) - file_len; + + memcpy_s(ext, ext_len, ".aec", 5); + farc_file* aec = f.read_file(buf); + if (!aec) + return false; + + memcpy_s(ext, ext_len, ".aei", 5); + farc_file* aei = f.read_file(buf); + if (!aei) + return false; + + aet_database_file aet_db_file; + aet_db_file.read(aei->data, aei->size, true); + + aet_db_aet_set_file* aet_set_file = 0; + if (aet_db_file.ready) + for (aet_db_aet_set_file& m : aet_db_file.aet_set) + if (m.id == hash) { + aet_set_file = &m; + break; + } + + if (!aet_set_file) + return false; + + if (aet_db_file.ready) + aet_db->parse(aet_set_file, name, aet_ids); + + prj::shared_ptr& alloc = alloc_handler; + alloc = prj::shared_ptr(new prj::stack_allocator); + + ::aet_set* set = alloc->allocate<::aet_set>(); + this->aet_set = set; + set->unpack_file(alloc_handler, aec->data, aec->size, true); + if (!set->ready) + return false; + + file_handler.reset(); + return true; +} + const aet_marker* AetSet::GetLayerMarker(const aet_layer* layer, const char* marker_name) { if (!layer->markers_count) return 0; @@ -1664,8 +1378,8 @@ void AetSet::GetLayerMarkerNames(std::vector& vec, const aet_layer* } const aet_scene* AetSet::GetSceneByInfo(aet_info info) { - if (index == info.set_index && ready && info.index < scenes_count) - return scenes[info.index]; + if (index == info.set_index && ready && info.index < aet_set->scenes_count) + return aet_set->scenes[info.index]; return 0; } @@ -1680,7 +1394,7 @@ void AetSet::GetSceneCompLayerNames(std::vector& vec, const aet_sce } float_t AetSet::GetSceneEndTime(uint16_t index) { - return scenes[index]->end_time; + return aet_set->scenes[index]->end_time; } const aet_layer* AetSet::GetSceneLayer(const aet_scene* scene, const char* layer_name) { @@ -1698,7 +1412,7 @@ const aet_layer* AetSet::GetSceneLayer(const aet_scene* scene, const char* layer } const char* AetSet::GetSceneName(uint16_t index) { - return scenes[index]->name; + return aet_set->scenes[index]->name; } resolution_mode AetSet::GetSceneResolutionMode(const aet_scene* scene) { @@ -1711,14 +1425,14 @@ resolution_mode AetSet::GetSceneResolutionMode(const aet_scene* scene) { } float_t AetSet::GetSceneStartTime(uint16_t index) { - return scenes[index]->start_time; + return aet_set->scenes[index]->start_time; } uint32_t AetSet::GetScenesCount() { - return scenes_count; + return aet_set->scenes_count; } -AetMgr::AetMgr() : load_counter() { +AetMgr::AetMgr() : load_counter(), set_counter() { } @@ -1763,6 +1477,32 @@ void AetMgr::Basic() { } } +uint32_t AetMgr::AddSetModern() { + uint32_t index = this->set_counter; + for (; index <= 0x0FFF; index++) { + auto elem = sets.find(0x8000 | index); + if (elem == sets.end()) + break; + } + + if (!index || index > 0x0FFF) { + for (index = 1; index <= 0x0FFF; index++) { + auto elem = sets.find(0x8000 | index); + if (elem == sets.end()) + break; + } + + if (!index || index > 0x0FFF) + return 0x8000; + } + + sets.insert({ 0x8000 | index, AetSet(0x8000 | index) }); + set_counter = index + 1; + if (index + 1 > 0x0FFF) + set_counter = 1; + return 0x8000 | index; +} + void AetMgr::AddAetSets(const aet_database* aet_db) { for (auto& i : aet_db->aet_set_indices) sets.insert({ i.first, AetSet(i.first) }); @@ -1832,14 +1572,14 @@ bool AetMgr::GetObjVisible(uint32_t id) { return false; } -AetSet* AetMgr::GetSet(int32_t index) { +AetSet* AetMgr::GetSet(uint32_t index) { auto elem = sets.find(index); if (elem != sets.end()) return &elem->second; return 0; } -bool AetMgr::GetSetReady(int32_t index) { +bool AetMgr::GetSetReady(uint32_t index) { return GetSet(index)->ready; } @@ -1848,7 +1588,7 @@ void AetMgr::GetSetSceneCompLayerNames(std::vector& vec, aet_info i set->GetSceneCompLayerNames(vec, set->GetSceneByInfo(info)); } -uint32_t AetMgr::GetSetScenesCount(int32_t index) { +uint32_t AetMgr::GetSetScenesCount(uint32_t index) { return GetSet(index)->GetScenesCount(); } @@ -1899,7 +1639,7 @@ bool AetMgr::InitAetObj(AetObj& obj, AetArgs& args) { if (!scene) return false; - const aet_comp* comp = aet_scene_get_root_comp(scene); + const aet_comp* comp = aet_scene::get_root_comp(scene); if (!comp) return false; @@ -1937,14 +1677,21 @@ uint32_t AetMgr::InitAetObject(AetArgs& args) { return load_counter; } -bool AetMgr::LoadFile(int32_t index) { +bool AetMgr::LoadFile(uint32_t index) { AetSet* set = GetSet(index); if (set) return set->LoadFile(); return false; } -void AetMgr::ReadFile(int32_t index, const char* file, std::string& mdata_dir, void* data) { +bool AetMgr::LoadFileModern(uint32_t index, aet_database* aet_db) { + AetSet* set = GetSet(index); + if (set) + return set->LoadFileModern(aet_db); + return false; +} + +void AetMgr::ReadFile(uint32_t index, const char* file, std::string& mdata_dir, void* data) { const char* dir = "./rom/2d/"; if (mdata_dir.size() && ((data_struct*)data)->check_directory_exists(mdata_dir.c_str())) dir = mdata_dir.c_str(); @@ -1954,6 +1701,18 @@ void AetMgr::ReadFile(int32_t index, const char* file, std::string& mdata_dir, v set->ReadFile(dir, file, data); } +void AetMgr::ReadFileModern(uint32_t index, + uint32_t set_hash, void* data, aet_database* aet_db) { + if (index == -1) { + index = AddSetModern(); + aet_db->add_aet_set(set_hash, index); + } + + AetSet* set = GetSet(index); + if (set) + set->ReadFileModern(set_hash, data); +} + void AetMgr::RemoveAetSets(const aet_database* aet_db) { for (auto& i : aet_db->aet_set_indices) sets.erase(i.first); @@ -1983,6 +1742,12 @@ void AetMgr::SetObjFrame(uint32_t id, float_t value) { obj->SetFrame(value); } +void AetMgr::SetObjFrameRateControl(uint32_t id, FrameRateControl* value) { + AetObj* obj = GetObj(id); + if (obj) + obj->SetFrameRateControl(value); +} + void AetMgr::SetObjPlay(uint32_t id, bool value) { AetObj* obj = GetObj(id); if (obj) @@ -2037,279 +1802,20 @@ void AetMgr::SetObjVisible(uint32_t id, bool value) { obj->SetVisible(value); } -void AetMgr::UnloadSet(int32_t index) { +void AetMgr::UnloadSet(uint32_t index) { AetSet* set = GetSet(index); if (set) set->Unload(); } -static aet_camera* aet_camera_load(aet_set_load_data& load_data, const aet_camera_file* cam_file) { - aet_camera* cam = load_data.alloc_handler->allocate(); - aet_fcurve_load(load_data, cam->eye_x, cam_file->eye_x); - aet_fcurve_load(load_data, cam->eye_y, cam_file->eye_y); - aet_fcurve_load(load_data, cam->eye_z, cam_file->eye_z); - aet_fcurve_load(load_data, cam->pos_x, cam_file->pos_x); - aet_fcurve_load(load_data, cam->pos_y, cam_file->pos_y); - aet_fcurve_load(load_data, cam->pos_z, cam_file->pos_z); - aet_fcurve_load(load_data, cam->dir_x, cam_file->dir_x); - aet_fcurve_load(load_data, cam->dir_y, cam_file->dir_y); - aet_fcurve_load(load_data, cam->dir_z, cam_file->dir_z); - aet_fcurve_load(load_data, cam->rot_x, cam_file->rot_x); - aet_fcurve_load(load_data, cam->rot_y, cam_file->rot_y); - aet_fcurve_load(load_data, cam->rot_z, cam_file->rot_z); - aet_fcurve_load(load_data, cam->zoom, cam_file->zoom); - return cam; -} - -static void aet_comp_set_item_parent(aet_set_load_data& load_data, const aet_comp* comp) { - aet_layer* layer = (aet_layer*)comp->layers; - for (uint32_t i = comp->layers_count; i; i--, layer++) { - if (layer->item_type == AET_ITEM_TYPE_VIDEO - || layer->item_type == AET_ITEM_TYPE_COMPOSITION) { - uint32_t item_offset = layer->item.offset; - layer->item.none = 0; - - if (item_offset) { - auto elem = load_data.items.find(item_offset); - if (elem != load_data.items.end()) - layer->item = elem->second; - } - } - - uint32_t parent_offset = layer->parent_offset; - layer->parent = 0; - - if (parent_offset) { - auto elem = load_data.layers.find(parent_offset); - if (elem != load_data.layers.end()) - layer->parent = elem->second; +void AetMgr::UnloadSetModern(uint32_t index, aet_database* aet_db) { + AetSet* set = GetSet(index); + if (set) { + set->UnloadModern(aet_db); + if (set->load_count <= 0) { + auto elem = sets.find(index); + if (elem != sets.end()) + sets.erase(elem); } } } - -static aet_comp* aet_comps_load(aet_set_load_data& load_data, - size_t comp_count, const aet_comp_file* comps_file) { - aet_comp* comps = load_data.alloc_handler->allocate(comp_count); - - aet_comp* comp = comps; - const aet_comp_file* comp_file = comps_file; - - for (size_t i = comp_count; i; i--, comp++, comp_file++) { - load_data.items.insert_or_assign((uint32_t)((size_t)comp_file - load_data.data), comp); - - comp->layers_count = comp_file->layers_count; - if (comp_file->layers_offset) { - const aet_layer_file* layer_file = (const aet_layer_file*)(load_data.data + comp_file->layers_offset); - - aet_layer* layer = load_data.alloc_handler->allocate(comp_file->layers_count); - comp->layers = layer; - - for (uint32_t i = comp_file->layers_count; i; i--, layer++, layer_file++) - aet_layer_load(load_data, layer, layer_file); - } - else - comp->layers = 0; - } - return comps; -} - -inline static void aet_fcurve_load(aet_set_load_data& load_data, - aet_fcurve& fcurve, const aet_fcurve_file& fcurve_file) { - fcurve.keys_count = fcurve_file.keys_count; - if (fcurve_file.keys_offset) - fcurve.keys = (const float_t*)(load_data.data + fcurve_file.keys_offset); - else - fcurve.keys = 0; -} - -static aet_layer* aet_layer_load(aet_set_load_data& load_data, - aet_layer* layer, const aet_layer_file* layer_file) { - load_data.layers.insert_or_assign((uint32_t)((size_t)layer_file - load_data.data), layer); - - if (layer_file->name_offset) - layer->name = (const char*)(load_data.data + layer_file->name_offset); - else - layer->name = 0; - - layer->start_time = layer_file->start_time; - layer->end_time = layer_file->end_time; - layer->offset_time = layer_file->offset_time; - layer->time_scale = layer_file->time_scale; - layer->flags = layer_file->flags; - layer->quality = layer_file->quality; - layer->item.none = 0; - layer->item_type = layer_file->item_type; - if ((layer_file->item_type == AET_ITEM_TYPE_VIDEO - || layer_file->item_type == AET_ITEM_TYPE_COMPOSITION) - && layer_file->item_offset) - layer->item.offset = layer_file->item_offset; - - layer->parent = 0; - if (layer_file->parent_offset) - layer->parent_offset = layer_file->parent_offset; - - layer->markers_count = layer_file->markers_count; - if (layer_file->markers_offset) - layer->markers = aet_markers_load(load_data, layer_file->markers_count, - (const aet_marker_file*)(load_data.data + layer_file->markers_offset)); - else - layer->markers = 0; - - if (layer_file->video_offset) - layer->video = aet_layer_video_load(load_data, - (const aet_layer_video_file*)(load_data.data + layer_file->video_offset)); - else - layer->video = 0; - - if (layer_file->audio_offset) - layer->audio = aet_layer_audio_load(load_data, - (const aet_layer_audio_file*)(load_data.data + layer_file->audio_offset)); - else - layer->audio = 0; - return layer; -} - -static aet_layer_audio* aet_layer_audio_load( - aet_set_load_data& load_data, const aet_layer_audio_file* layer_audio_file) { - aet_layer_audio* layer_audio = load_data.alloc_handler->allocate(); - aet_fcurve_load(load_data, layer_audio->volume_l, layer_audio_file->volume_l); - aet_fcurve_load(load_data, layer_audio->volume_r, layer_audio_file->volume_r); - aet_fcurve_load(load_data, layer_audio->pan_l, layer_audio_file->pan_l); - aet_fcurve_load(load_data, layer_audio->pan_r, layer_audio_file->pan_r); - return layer_audio; -} - -static aet_layer_video* aet_layer_video_load( - aet_set_load_data& load_data, const aet_layer_video_file* layer_video_file) { - aet_layer_video* layer_video = load_data.alloc_handler->allocate(); - layer_video->transfer_mode = layer_video_file->transfer_mode; - aet_fcurve_load(load_data, layer_video->anchor_x, layer_video_file->anchor_x); - aet_fcurve_load(load_data, layer_video->anchor_y, layer_video_file->anchor_y); - aet_fcurve_load(load_data, layer_video->pos_x, layer_video_file->pos_x); - aet_fcurve_load(load_data, layer_video->pos_y, layer_video_file->pos_y); - aet_fcurve_load(load_data, layer_video->rot_z, layer_video_file->rot_z); - aet_fcurve_load(load_data, layer_video->scale_x, layer_video_file->scale_x); - aet_fcurve_load(load_data, layer_video->scale_y, layer_video_file->scale_y); - aet_fcurve_load(load_data, layer_video->opacity, layer_video_file->opacity); - if (layer_video_file->_3d_offset) - layer_video->_3d = aet_layer_video_3d_load(load_data, - (const aet_layer_video_3d_file*)(load_data.data + layer_video_file->_3d_offset)); - return layer_video; -} - -static aet_layer_video_3d* aet_layer_video_3d_load( - aet_set_load_data& load_data, const aet_layer_video_3d_file* layer_video_3d_file) { - aet_layer_video_3d* layer_video_3d = load_data.alloc_handler->allocate(); - aet_fcurve_load(load_data, layer_video_3d->anchor_z, layer_video_3d_file->anchor_z); - aet_fcurve_load(load_data, layer_video_3d->pos_z, layer_video_3d_file->pos_z); - aet_fcurve_load(load_data, layer_video_3d->dir_x, layer_video_3d_file->dir_x); - aet_fcurve_load(load_data, layer_video_3d->dir_y, layer_video_3d_file->dir_y); - aet_fcurve_load(load_data, layer_video_3d->dir_z, layer_video_3d_file->dir_z); - aet_fcurve_load(load_data, layer_video_3d->rot_x, layer_video_3d_file->rot_x); - aet_fcurve_load(load_data, layer_video_3d->rot_y, layer_video_3d_file->rot_y); - aet_fcurve_load(load_data, layer_video_3d->scale_z, layer_video_3d_file->scale_z); - return layer_video_3d; -} - -static aet_marker* aet_markers_load(aet_set_load_data& load_data, - size_t markers_count, const aet_marker_file* markers_file) { - aet_marker* markers = load_data.alloc_handler->allocate(markers_count); - - aet_marker* marker = markers; - const aet_marker_file* marker_file = markers_file; - - for (size_t i = markers_count; i; i--, marker++, marker_file++) { - marker->time = marker_file->time; - if (marker_file->name_offset) - marker->name = (const char*)(load_data.data + marker_file->name_offset); - else - marker->name = 0; - } - return markers; -} - -static const aet_comp* aet_scene_get_root_comp(const aet_scene* scene) { - if (scene && scene->comp_count) - return &scene->comp[scene->comp_count - 1]; - return 0; -} - -static aet_scene* aet_scene_load(aet_set_load_data& load_data, - aet_scene* scene, const aet_scene_file* scene_file) { - if (scene_file->name_offset) - scene->name = (const char*)(load_data.data + scene_file->name_offset); - else - scene->name = 0; - - scene->start_time = scene_file->start_time; - scene->end_time = scene_file->end_time; - scene->fps = scene_file->fps; - scene->color[0] = scene_file->color[0]; - scene->color[1] = scene_file->color[1]; - scene->color[2] = scene_file->color[2]; - scene->width = scene_file->width; - scene->height = scene_file->height; - - if (scene_file->camera_offset) - scene->camera = aet_camera_load(load_data, - (const aet_camera_file*)(load_data.data + scene_file->camera_offset)); - else - scene->camera = 0; - - scene->comp_count = scene_file->comp_count; - if (scene_file->comp_offset) - scene->comp = aet_comps_load(load_data, scene_file->comp_count, - (const aet_comp_file*)(load_data.data + scene_file->comp_offset)); - else - scene->comp = 0; - - scene->video_count = scene_file->video_count; - const aet_video_file* video_file; - if (scene_file->video_offset) - video_file = (const aet_video_file*)(load_data.data + scene_file->video_offset); - else - video_file = 0; - - aet_video* video = load_data.alloc_handler->allocate(scene_file->video_count); - scene->video = video; - for (uint32_t i = scene_file->video_count; i; i--, video++, video_file++) - aet_video_load(load_data, video, video_file); - - scene->audio_count = scene_file->audio_count; - if (scene_file->audio_offset) - scene->audio = (aet_audio*)(load_data.data + scene_file->audio_offset); - else - scene->audio = 0; - return scene; -} - -static aet_video* aet_video_load(aet_set_load_data& load_data, - aet_video* video, const aet_video_file* video_file) { - load_data.items.insert_or_assign((uint32_t)((size_t)video_file - load_data.data), video); - video->color[0] = video_file->color[0]; - video->color[1] = video_file->color[1]; - video->color[2] = video_file->color[2]; - video->width = video_file->width; - video->height = video_file->height; - video->fpf = video_file->fpf; - video->sources_count = video_file->sources_count; - - if (video_file->sources_offset) { - const aet_video_src_file* source_file - = (const aet_video_src_file*)(load_data.data + video_file->sources_offset); - - aet_video_src* source = load_data.alloc_handler->allocate(video_file->sources_count); - video->sources = source; - - for (uint32_t i = video_file->sources_count; i; i--, source++, source_file++) { - if (source_file->sprite_name_offset) - source->sprite_name = (const char*)(load_data.data + source_file->sprite_name_offset); - else - source->sprite_name = 0; - source->sprite_index = source_file->sprite_index; - } - } - else - video->sources = 0; - return video; -} \ No newline at end of file diff --git a/src/CRE/auth_2d.hpp b/src/CRE/auth_2d.hpp index e13eac6d..b6cd714b 100644 --- a/src/CRE/auth_2d.hpp +++ b/src/CRE/auth_2d.hpp @@ -131,15 +131,18 @@ extern uint32_t aet_manager_init_aet_object(uint32_t aet_id, spr::SprPrio prio, const char* start_marker, const char* end_marker, float_t start_time, float_t end_time, const vec2* scale, FrameRateControl* frame_rate_control, const aet_database* aet_db); extern bool aet_manager_load_file(uint32_t set_id, const aet_database* aet_db); +extern bool aet_manager_load_file_modern(uint32_t set_hash, aet_database* aet_db); extern void aet_manager_read_file(uint32_t set_id, std::string& mdata_dir, void* data, const aet_database* aet_db); extern void aet_manager_read_file(uint32_t set_id, std::string&& mdata_dir, void* data, const aet_database* aet_db); +extern void aet_manager_read_file_modern(uint32_t set_hash, void* data, aet_database* aet_db); extern void aet_manager_remove_aet_sets(const aet_database* aet_db); extern void aet_manager_set_obj_alpha(uint32_t id, float_t value); extern void aet_manager_set_obj_color(uint32_t id, const vec4& value); extern void aet_manager_set_obj_end_time(uint32_t id, float_t value); extern void aet_manager_set_obj_frame(uint32_t id, float_t value); +extern void aet_manager_set_obj_frame_rate_control(uint32_t id, FrameRateControl* value); extern void aet_manager_set_obj_play(uint32_t id, bool value); extern void aet_manager_set_obj_position(uint32_t id, const vec3& value); extern void aet_manager_set_obj_prio(uint32_t id, spr::SprPrio value); @@ -150,4 +153,5 @@ extern void aet_manager_set_obj_sprite_replace(uint32_t id, std::map& value); extern void aet_manager_set_obj_visible(uint32_t id, bool value); extern void aet_manager_unload_set(uint32_t set_id, const aet_database* aet_db); +extern void aet_manager_unload_set_modern(uint32_t set_hash, aet_database* aet_db); extern void aet_manager_free(); diff --git a/src/CRE/object.cpp b/src/CRE/object.cpp index 5f70a9f6..dd9f282e 100644 --- a/src/CRE/object.cpp +++ b/src/CRE/object.cpp @@ -873,7 +873,7 @@ void object_material_msgpack_read(const char* path, const char* set_name, tex_db->texture.push_back({}); texture_info* info = &tex_db->texture.back(); - info->name = name; + info->name.assign(name); info->name_hash = hash_string_murmurhash(info->name); info->id = id; @@ -1302,7 +1302,7 @@ inline void object_storage_init(object_database* obj_db) { object_storage_data.resize(count); for (size_t i = 0; i < count; i++) { object_storage_data[i].set_id = obj_set[i].id; - object_storage_data[i].name = obj_set[i].name; + object_storage_data[i].name.assign(obj_set[i].name); } object_storage_data_modern.clear(); } @@ -1908,14 +1908,17 @@ bool object_storage_load_obj_set_check_not_read(uint32_t set_id, texture_database_file tex_db_file; tex_db_file.read(txi->data, txi->size, true); - std::string name; + object_set_info_file* set_info_file = 0; if (obj_db_file.ready) for (object_set_info_file& m : obj_db_file.object_set) if (m.id == handler->set_id) { - name = m.name; + set_info_file = &m; break; } + if (!set_info_file) + return false; + object_database local_obj_db; if (obj_db_file.ready) { if (obj_db) @@ -1930,10 +1933,7 @@ bool object_storage_load_obj_set_check_not_read(uint32_t set_id, local_tex_db.add(&tex_db_file); } - if (!name.size()) - return false; - - handler->name = name; + handler->name.assign(set_info_file->name); prj::shared_ptr& alloc = handler->alloc_handler; alloc = prj::shared_ptr(new prj::stack_allocator); @@ -2179,7 +2179,7 @@ static bool obj_set_handler_load_textures_modern(obj_set_handler* handler, { txp_set txp; - txp.unpack_file_modern(data, size); + txp.unpack_file_modern(data, size, 'MTXD'); handler->tex_num = (int32_t)txp.textures.size(); object_material_msgpack_read("patch\\AFT\\objset", file, &txp, tex_db, handler); texture_txp_set_load(&txp, &handler->tex_data, set->tex_id_data); diff --git a/src/CRE/post_process.cpp b/src/CRE/post_process.cpp index 1c7e3a51..bc8daa4a 100644 --- a/src/CRE/post_process.cpp +++ b/src/CRE/post_process.cpp @@ -624,7 +624,7 @@ void post_process::init_fbo(int32_t render_width, int32_t render_height, } if (this->sprite_width != sprite_width || this->sprite_height != sprite_height) { - screen_texture.init(screen_width, sprite_height, 0, GL_RGBA16F, 0); // Was GL_R11F_G11F_B10F + screen_texture.init(sprite_width, sprite_height, 0, GL_RGBA16F, 0); // Was GL_R11F_G11F_B10F this->sprite_width = sprite_width; this->sprite_height = sprite_height; } diff --git a/src/CRE/resolution_mode.hpp b/src/CRE/resolution_mode.hpp index e2f66af4..850c5ea5 100644 --- a/src/CRE/resolution_mode.hpp +++ b/src/CRE/resolution_mode.hpp @@ -6,66 +6,9 @@ #pragma once #include "../KKdLib/default.hpp" +#include "../KKdLib/spr.hpp" #include "../KKdLib/vec.hpp" -enum resolution_mode { - 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_QHD = 0x0F, - RESOLUTION_MODE_WQVGA = 0x10, - RESOLUTION_MODE_qHD = 0x11, - 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 { int32_t width_full; int32_t height_full; diff --git a/src/CRE/sprite.cpp b/src/CRE/sprite.cpp index 4f7fd977..6ac6ce14 100644 --- a/src/CRE/sprite.cpp +++ b/src/CRE/sprite.cpp @@ -13,39 +13,11 @@ #include "texture.hpp" #include -struct SpriteHeaderFile { - uint32_t flag; - uint32_t texofs; - int32_t num_of_texture; - int32_t num_of_sprite; - uint32_t sprinfo_offset; - uint32_t texname_offset; - uint32_t sprname_offset; - uint32_t sprdata_offset; -}; - -struct SpriteData { - uint32_t attr; - resolution_mode resolution_mode; -}; - -struct SpriteHeader { - uint32_t flag; - uint32_t texofs; - int32_t num_of_texture; - int32_t num_of_sprite; - spr::SprInfo* sprinfo; - const char** texname; - const char** sprname; - SpriteData* sprdata; -}; - class SprSet { public: int32_t flag; uint32_t index; - const SpriteHeaderFile* header_file; - const SpriteHeader* header; + ::spr_set* spr_set; texture** textures; int32_t load_count; p_file_handler file_handler; @@ -53,6 +25,10 @@ public: prj::shared_ptr alloc_handler; std::string file; + std::string name; + std::vector sprite_ids; + uint32_t hash; + SprSet(uint32_t index); virtual ~SprSet(); @@ -61,10 +37,15 @@ public: resolution_mode GetResolutionMode(spr_info info); texture* GetTexture(spr_info info); bool LoadData(); + bool LoadDataModern(const void* data, size_t size); bool LoadFile(); + bool LoadFileModern(sprite_database* spr_db); bool LoadTexture(); + bool LoadTextureModern(const void* data, size_t size); void ReadFile(const char* file, std::string& mdata_dir, void* data); + void ReadFileModern(uint32_t set_hash, void* data); void Unload(); + void UnloadModern(sprite_database* spr_db); bool UnloadTexture(); }; @@ -102,7 +83,7 @@ struct sprite_draw_param { namespace spr { struct SpriteManager { - std::map sets; + std::map sets; std::list reqlist[4][2][SPR_PRIO_MAX]; float_t aspect[2]; std::pair field_1018[2]; @@ -111,6 +92,8 @@ namespace spr { mat4 mat; resolution_mode resolution_mode; + uint32_t set_counter; + std::vector draw_param_buffer; std::vector vertex_buffer; GLuint vao; @@ -120,26 +103,29 @@ namespace spr { SpriteManager(); ~SpriteManager(); + uint32_t AddSetModern(); void AddSprSets(const sprite_database* spr_db); void Clear(); void Draw(render_context* rctx, int32_t index, bool font, texture* tex, const mat4& proj); - SprSet* GetSet(int32_t index); - bool GetSetReady(int32_t index); - uint32_t GetSetSpriteNum(int32_t index); - uint32_t GetSetTextureNum(int32_t index); + SprSet* GetSet(uint32_t index); + bool GetSetReady(uint32_t index); + uint32_t GetSetSpriteNum(uint32_t index); + uint32_t GetSetTextureNum(uint32_t index); const char* GetSprName(spr_info info); rectangle GetSprRectangle(spr_info info); texture* GetSprTexture(spr_info info); - bool LoadFile(int32_t index); + bool LoadFile(uint32_t index); + bool LoadFileModern(uint32_t index, sprite_database* spr_db); SprArgs* PutSprite(const SprArgs& args, const sprite_database* spr_db); - void ReadFile(int32_t index, const char* file, std::string& mdata_dir, void* data); - void ReadFile(int32_t index, const char* file, std::string&& mdata_dir, void* data); + void ReadFile(uint32_t index, const char* file, std::string& mdata_dir, void* data); + void ReadFileModern(uint32_t index, uint32_t set_hash, void* data, sprite_database* spr_db); void RemoveSprSets(const sprite_database* spr_db); void ResetIndex(); void ResetReqList(); void ResetResData(); - void UnloadSet(int32_t index); + void UnloadSet(uint32_t index); + void UnloadSetModern(uint32_t index, sprite_database* spr_db); }; static void calc_sprite_vertex(spr::SprArgs* args, vec3* vtx, mat4* mat, bool font); @@ -349,7 +335,7 @@ namespace spr { sprite_manager->PutSprite(args, 0); } - void put_sprite_triangles(SpriteVertex* vert, size_t size, resolution_mode mode, + void put_sprite_triangles(SpriteVertex* vert, size_t num, resolution_mode mode, SprPrio prio, int32_t spr_id, int32_t layer, const sprite_database* spr_db) { spr::SprArgs args; args.layer = layer; @@ -361,7 +347,7 @@ namespace spr { if (spr_id != -1) args.id.info = spr_db->get_spr_by_id(spr_id)->info; enum_or(args.attr, SPR_ATTR_MATRIX); - args.SetVertexArray(vert, size); + args.SetVertexArray(vert, num); sprite_manager->PutSprite(args, spr_db); } } @@ -396,6 +382,13 @@ size_t sprite_manager_get_reqlist_count(int32_t index) { return count; } +::spr_set* sprite_manager_get_set(uint32_t spr_id, const sprite_database* spr_db) { + SprSet* set = sprite_manager->GetSet(spr_db->get_spr_set_by_id(spr_id)->index); + if (set) + return set->spr_set; + return 0; +} + bool sprite_manager_get_set_ready(uint32_t set_id, const sprite_database* spr_db) { return sprite_manager->GetSetReady(spr_db->get_spr_set_by_id(set_id)->index); } @@ -424,6 +417,10 @@ bool sprite_manager_load_file(uint32_t set_id, const sprite_database* spr_db) { return sprite_manager->LoadFile(spr_db->get_spr_set_by_id(set_id)->index); } +bool sprite_manager_load_file_modern(uint32_t set_hash, sprite_database* spr_db) { + return sprite_manager->LoadFileModern(spr_db->get_spr_set_by_id(set_hash)->index, spr_db); +} + void sprite_manager_read_file(uint32_t set_id, std::string& mdata_dir, void* data, const sprite_database* spr_db) { const spr_db_spr_set* spr_set = spr_db->get_spr_set_by_id(set_id); @@ -436,6 +433,11 @@ void sprite_manager_read_file(uint32_t set_id, sprite_manager->ReadFile(spr_set->index, spr_set->file_name.c_str(), mdata_dir, data); } +void sprite_manager_read_file_modern(uint32_t set_hash, void* data, sprite_database* spr_db) { + const spr_db_spr_set* spr_set = spr_db->get_spr_set_by_id(set_hash); + sprite_manager->ReadFileModern(spr_set->index, set_hash, data, spr_db); +} + void sprite_manager_remove_spr_sets(const sprite_database* spr_db) { sprite_manager->RemoveSprSets(spr_db); } @@ -466,6 +468,10 @@ void sprite_manager_unload_set(uint32_t set_id, const sprite_database* spr_db) { sprite_manager->UnloadSet(spr_db->get_spr_set_by_id(set_id)->index); } +void sprite_manager_unload_set_modern(uint32_t set_hash, sprite_database* spr_db) { + sprite_manager->UnloadSetModern(spr_db->get_spr_set_by_id(set_hash)->index, spr_db); +} + void sprite_manager_free() { if (sprite_manager) { delete sprite_manager; @@ -474,7 +480,7 @@ void sprite_manager_free() { } namespace spr { - SpriteManager::SpriteManager() : aspect(), index() { + SpriteManager::SpriteManager() : aspect(), index(), set_counter() { ResetIndex(); resolution_mode = RESOLUTION_MODE_MAX; @@ -539,6 +545,32 @@ namespace spr { } } + uint32_t SpriteManager::AddSetModern() { + uint32_t index = this->set_counter; + for (; index <= 0x0FFF; index++) { + auto elem = sets.find(0x8000 | index); + if (elem == sets.end()) + break; + } + + if (!index || index > 0x0FFF) { + for (index = 1; index <= 0x0FFF; index++) { + auto elem = sets.find(0x8000 | index); + if (elem == sets.end()) + break; + } + + if (!index || index > 0x0FFF) + return 0x8000; + } + + sets.insert({ 0x8000 | index, SprSet(0x8000 | index) }); + set_counter = index + 1; + if (index + 1 > 0x0FFF) + set_counter = 1; + return 0x8000 | index; + } + void SpriteManager::AddSprSets(const sprite_database* spr_db) { for (auto& i : spr_db->spr_set_indices) sets.insert({ i.first, SprSet(i.first) }); @@ -747,62 +779,69 @@ namespace spr { draw_sprite_end(); } - SprSet* SpriteManager::GetSet(int32_t index) { + SprSet* SpriteManager::GetSet(uint32_t index) { auto elem = sets.find(index); if (elem != sets.end()) return &elem->second; return 0; } - bool SpriteManager::GetSetReady(int32_t index) { + bool SpriteManager::GetSetReady(uint32_t index) { SprSet* set = GetSet(index); if (set) return set->ready; return false; } - uint32_t SpriteManager::GetSetSpriteNum(int32_t index) { + uint32_t SpriteManager::GetSetSpriteNum(uint32_t index) { SprSet* set = GetSet(index); if (set) - return set->header->num_of_sprite; + return set->spr_set->num_of_sprite; return 0; } - uint32_t SpriteManager::GetSetTextureNum(int32_t index) { + uint32_t SpriteManager::GetSetTextureNum(uint32_t index) { SprSet* set = GetSet(index); if (set) - return set->header->num_of_texture; + return set->spr_set->num_of_texture; return 0; } const char* SpriteManager::GetSprName(spr_info info) { - SprSet* set = GetSet(info.set_index & 0x0FFF); + SprSet* set = GetSet(info.set_index & 0x8FFF); if (set) return set->GetName(info); return "(null)"; } rectangle SpriteManager::GetSprRectangle(spr_info info) { - SprSet* set = GetSet(info.set_index & 0x0FFF); + SprSet* set = GetSet(info.set_index & 0x8FFF); if (set) return set->GetRectangle(info); return {}; } texture* SpriteManager::GetSprTexture(spr_info info) { - SprSet* set = GetSet(info.set_index & 0x0FFF); + SprSet* set = GetSet(info.set_index & 0x8FFF); if (set) return set->GetTexture(info); return 0; } - bool SpriteManager::LoadFile(int32_t index) { + bool SpriteManager::LoadFile(uint32_t index) { SprSet* set = GetSet(index); if (set) return set->LoadFile(); return false; } + bool SpriteManager::LoadFileModern(uint32_t index, sprite_database* spr_db) { + SprSet* set = GetSet(index); + if (set) + return set->LoadFileModern(spr_db); + return false; + } + SprArgs* SpriteManager::PutSprite(const SprArgs& args, const sprite_database* spr_db) { int32_t index = args.index; if (index == -1) @@ -814,7 +853,7 @@ namespace spr { info = spr_db->get_spr_by_id(args.id.id)->info; if (info.not_null()) { - SprSet* set = GetSet(info.set_index & 0x0FFF); + SprSet* set = GetSet(info.set_index & 0x8FFF); if (!set || !set->ready) return 0; @@ -846,18 +885,23 @@ namespace spr { } } - void SpriteManager::ReadFile(int32_t index, + void SpriteManager::ReadFile(uint32_t index, const char* file, std::string& mdata_dir, void* data) { SprSet* set = GetSet(index); if (set) set->ReadFile(file, mdata_dir, data); } - void SpriteManager::ReadFile(int32_t index, - const char* file, std::string&& mdata_dir, void* data) { + void SpriteManager::ReadFileModern(uint32_t index, + uint32_t set_hash, void* data, sprite_database* spr_db) { + if (index == -1) { + index = AddSetModern(); + spr_db->add_spr_set(set_hash, index); + } + SprSet* set = GetSet(index); if (set) - set->ReadFile(file, mdata_dir, data); + set->ReadFileModern(set_hash, data); } void SpriteManager::ResetIndex() { @@ -895,12 +939,24 @@ namespace spr { mat = mat4_identity; } - void SpriteManager::UnloadSet(int32_t index) { + void SpriteManager::UnloadSet(uint32_t index) { SprSet* set = GetSet(index); if (set) set->Unload(); } + void SpriteManager::UnloadSetModern(uint32_t index, sprite_database* spr_db) { + SprSet* set = GetSet(index); + if (set) { + set->UnloadModern(spr_db); + if (set->load_count <= 0) { + auto elem = sets.find(index); + if (elem != sets.end()) + sets.erase(elem); + } + } + } + static void calc_sprite_vertex(spr::SprArgs* args, vec3* vtx, mat4* mat, bool font) { vtx[0].x = 0.0f; vtx[0].y = 0.0f; @@ -1606,9 +1662,10 @@ namespace spr { } } -SprSet::SprSet(uint32_t index) : flag(), header_file(), -header(), textures(), load_count(), ready() { +SprSet::SprSet(uint32_t index) : flag(), spr_set(), +textures(), load_count(), ready() { this->index = index; + hash = hash_murmurhash_empty; } SprSet::~SprSet() { @@ -1616,74 +1673,63 @@ SprSet::~SprSet() { } const char* SprSet::GetName(spr_info info) { - if ((info.set_index & 0xF000) == 0x1000) - return header->texname[info.index]; + if (info.set_index & 0x1000) + return spr_set->texname[info.index]; else - return header->sprname[info.index]; + return spr_set->sprname[info.index]; } rectangle SprSet::GetRectangle(spr_info info) { - if ((info.set_index & 0xF000) == 0x1000) { + if (info.set_index & 0x1000) { texture* tex = textures[info.index]; return { 0.0f, 0.0f, (float_t)tex->width, (float_t)tex->height }; } - spr::SprInfo* sprinfo = &header->sprinfo[info.index]; + spr::SprInfo* sprinfo = &spr_set->sprinfo[info.index]; return { (float_t)(int32_t)sprinfo->px, (float_t)(int32_t)sprinfo->py, (float_t)(int32_t)sprinfo->width, (float_t)(int32_t)sprinfo->height }; } resolution_mode SprSet::GetResolutionMode(spr_info info) { - if ((info.set_index & 0xF000) == 0x1000) + if (info.set_index & 0x1000) return RESOLUTION_MODE_HD; else - return header->sprdata[info.index].resolution_mode; + return spr_set->sprdata[info.index].resolution_mode; } texture* SprSet::GetTexture(spr_info info) { - if ((info.set_index & 0xF000) == 0x1000) + if (info.set_index & 0x1000) return textures[info.index]; else - return textures[header->sprinfo[info.index].texid]; + return textures[spr_set->sprinfo[info.index].texid]; } bool SprSet::LoadData() { const void* data = file_handler.get_data(); - if (!data) { - header_file = 0; - header = 0; + size_t size = file_handler.get_size(); + if (!data || !size) return false; - } prj::shared_ptr& alloc = alloc_handler; alloc = prj::shared_ptr(new prj::stack_allocator); - header_file = (SpriteHeaderFile*)alloc->allocate( - (uint8_t*)data, ((const SpriteHeaderFile*)data)->texofs); + ::spr_set* set = alloc->allocate<::spr_set>(); + this->spr_set = set; + set->unpack_file(alloc, data, size, false); + return true; +} - SpriteHeader* header = alloc->allocate(); - header->flag = header_file->flag; - header->texofs = header_file->texofs; - header->num_of_texture = header_file->num_of_texture; - header->num_of_sprite = header_file->num_of_sprite; - header->sprinfo = (spr::SprInfo*)((char*)header_file + header_file->sprinfo_offset); +bool SprSet::LoadDataModern(const void* data, size_t size) { + if (!data || !size) + return false; - const char** texname = alloc->allocate(header->num_of_texture); - header->texname = texname; + prj::shared_ptr& alloc = alloc_handler; + alloc = prj::shared_ptr(new prj::stack_allocator); - uint32_t* texname_offset = (uint32_t*)((size_t)header_file + header_file->texname_offset); - for (uint32_t i = header->num_of_texture; i; i--, texname++, texname_offset++) - *texname = (const char*)((size_t)header_file + *texname_offset); - - const char** sprname = alloc->allocate(header->num_of_sprite); - header->sprname = sprname; - - uint32_t* sprname_offset = (uint32_t*)((size_t)header_file + header_file->sprname_offset); - for (uint32_t i = header->num_of_sprite; i; i--, sprname++, sprname_offset++) - *sprname = (const char*)((size_t)header_file + *sprname_offset); - - header->sprdata = (SpriteData*)((size_t)header_file + header_file->sprdata_offset); - this->header = header; + ::spr_set* set = alloc->allocate<::spr_set>(); + this->spr_set = set; + set->unpack_file(alloc, data, size, true); + file_handler.reset(); return true; } @@ -1700,21 +1746,98 @@ bool SprSet::LoadFile() { return true; } +bool SprSet::LoadFileModern(sprite_database* spr_db) { + if (ready) + return false; + else if (file_handler.check_not_ready()) + return true; + + const void* data = file_handler.get_data(); + size_t size = file_handler.get_size(); + if (!data || !size) + return false; + + farc f; + f.read(data, size, true); + + std::string& file = file_handler.ptr->file; + + size_t file_len = file.size(); + if (file_len >= 0x100 - 4) + return false; + + const char* t = strrchr(file.c_str(), '.'); + if (t) + file_len = t - file.c_str(); + + char buf[0x100]; + memcpy(buf, file.c_str(), file_len); + char* ext = buf + file_len; + size_t ext_len = sizeof(buf) - file_len; + + memcpy_s(ext, ext_len, ".spr", 5); + farc_file* spr = f.read_file(buf); + if (!spr) + return false; + + memcpy_s(ext, ext_len, ".spi", 5); + farc_file* spi = f.read_file(buf); + if (!spi) + return false; + + sprite_database_file spr_db_file; + spr_db_file.read(spi->data, spi->size, true); + + spr_db_spr_set_file* spr_set_file = 0; + if (spr_db_file.ready) + for (spr_db_spr_set_file& m : spr_db_file.sprite_set) + if (m.id == hash) { + spr_set_file = &m; + break; + } + + if (!spr_set_file) + return false; + + if (spr_db_file.ready) + spr_db->parse(spr_set_file, name, sprite_ids); + + if (!LoadDataModern(spr->data, spr->size) || !LoadTextureModern(spr->data, spr->size)) + return false; + + file_handler.reset(); + ready = true; + return true; +} + bool SprSet::LoadTexture() { size_t data = (size_t)file_handler.get_data(); if (!data) return false; - const SpriteHeaderFile* header_file = (const SpriteHeaderFile*)data; - - std::vector ids(header_file->num_of_texture); + std::vector ids(spr_set->num_of_texture); uint32_t set_index = (uint32_t)(0x1000 | index & 0x0FFF); uint32_t index = 0; for (uint32_t& i : ids) i = (set_index << 16) | index++; - txp_set txp; - txp.unpack_file((const void*)(data + header_file->texofs), false); - texture_txp_set_load(&txp, &textures, ids.data()); + texture_txp_set_load(spr_set->txp, &textures, ids.data()); + delete spr_set->txp; + spr_set->txp = 0; + return !!textures; +} + +bool SprSet::LoadTextureModern(const void* data, size_t size) { + if (!data || !size) + return false; + + std::vector ids(spr_set->num_of_texture); + uint32_t set_index = (uint32_t)(0x8000 | 0x1000 | index & 0x0FFF); + uint32_t index = 0; + for (uint32_t& i : ids) + i = (set_index << 16) | index++; + texture_txp_set_load(spr_set->txp, &textures, ids.data()); + delete spr_set->txp; + spr_set->txp = 0; return !!textures; } @@ -1741,6 +1864,19 @@ void SprSet::ReadFile(const char* file, std::string& mdata_dir, void* data) { ready = false; } +void SprSet::ReadFileModern(uint32_t set_hash, void* data) { + if (load_count > 1) { + load_count++; + return; + } + + std::string file; + if (((data_struct*)data)->get_file("root+/2d/", set_hash, ".farc", file)) + file_handler.read_file(data, "root+/2d/", file.c_str()); + this->hash = set_hash; + ready = false; +} + void SprSet::Unload() { if (load_count > 1) { load_count--; @@ -1751,13 +1887,34 @@ void SprSet::Unload() { UnloadTexture(); alloc_handler.reset(); - header_file = 0; - header = 0; + spr_set = 0; file.clear(); ready = false; load_count = 0; } +void SprSet::UnloadModern(sprite_database* spr_db) { + if (load_count > 1) { + load_count--; + return; + } + + spr_db->remove_spr_set(hash, index, name.c_str(), sprite_ids); + + file_handler.reset(); + UnloadTexture(); + alloc_handler.reset(); + + spr_set = 0; + file.clear(); + ready = false; + load_count = 0; + + hash = hash_murmurhash_empty; + name.clear(); + sprite_ids.clear(); +} + bool SprSet::UnloadTexture() { if (textures) { texture_array_free(textures); diff --git a/src/CRE/sprite.hpp b/src/CRE/sprite.hpp index b9b79524..98c03890 100644 --- a/src/CRE/sprite.hpp +++ b/src/CRE/sprite.hpp @@ -202,19 +202,6 @@ namespace spr { static void SetNext(SprArgs* args, 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 TexCoord { struct UV { float_t u; @@ -251,7 +238,7 @@ namespace spr { void put_sprite_line(vec2 p1, vec2 p2, resolution_mode mode, spr::SprPrio prio, vec4u8 color, int32_t layer); void put_sprite_multi(rectangle rect, resolution_mode mode, spr::SprPrio prio, vec4u8 color, int32_t layer); void put_sprite_rect(rectangle rect, resolution_mode mode, spr::SprPrio prio, vec4u8 color, int32_t layer); - void put_sprite_triangles(SpriteVertex* vert, size_t size, resolution_mode mode, + void put_sprite_triangles(SpriteVertex* vert, size_t num, resolution_mode mode, SprPrio prio, int32_t spr_id, int32_t layer, const sprite_database* spr_db); } @@ -262,6 +249,7 @@ extern void sprite_manager_draw(render_context* rctx, int32_t index, bool font, texture* tex, const mat4& proj); extern int32_t sprite_manager_get_index(); extern size_t sprite_manager_get_reqlist_count(int32_t index); +extern ::spr_set* sprite_manager_get_set(uint32_t set_id, const sprite_database* spr_db); extern bool sprite_manager_get_set_ready(uint32_t set_id, const sprite_database* spr_db); extern uint32_t sprite_manager_get_set_sprite_num(uint32_t set_id, const sprite_database* spr_db); extern uint32_t sprite_manager_get_set_texture_num(uint32_t set_id, const sprite_database* spr_db); @@ -269,14 +257,17 @@ extern const char* sprite_manager_get_spr_name(uint32_t spr_id, const sprite_dat extern rectangle sprite_manager_get_spr_rectangle(uint32_t spr_id, const sprite_database* spr_db); extern texture* sprite_manager_get_spr_texture(uint32_t spr_id, const sprite_database* spr_db); extern bool sprite_manager_load_file(uint32_t set_id, const sprite_database* spr_db); +extern bool sprite_manager_load_file_modern(uint32_t set_hash, sprite_database* spr_db); extern void sprite_manager_read_file(uint32_t set_id, std::string& mdata_dir, void* data, const sprite_database* spr_db); extern void sprite_manager_read_file(uint32_t set_id, std::string&& mdata_dir, void* data, const sprite_database* spr_db); +extern void sprite_manager_read_file_modern(uint32_t set_hash, void* data, sprite_database* spr_db); extern void sprite_manager_remove_spr_sets(const sprite_database* spr_db); extern void sprite_manager_reset_req_list(); extern void sprite_manager_reset_res_data(); extern void sprite_manager_set_index(int32_t value); extern void sprite_manager_set_res(double_t aspect, int32_t width, int32_t height); extern void sprite_manager_unload_set(uint32_t set_id, const sprite_database* spr_db); +extern void sprite_manager_unload_set_modern(uint32_t set_hash, sprite_database* spr_db); extern void sprite_manager_free(); diff --git a/src/CRE/task.cpp b/src/CRE/task.cpp index d77aa13a..0d4748b8 100644 --- a/src/CRE/task.cpp +++ b/src/CRE/task.cpp @@ -191,11 +191,11 @@ namespace app { } bool TaskWork::CheckTaskCtrl(Task* t) { - return app::TaskWork::HasTask(t) && t->state == Task::State::Running && t->op == Task::Op::Ctrl; + return t && app::TaskWork::HasTask(t) && t->state == Task::State::Running && t->op == Task::Op::Ctrl; } bool TaskWork::CheckTaskReady(Task* t) { - return TaskWork::HasTask(t) && (t->op == Task::Op::None || t->state != Task::State::None); + return t && TaskWork::HasTask(t) && (t->op == Task::Op::None || t->state != Task::State::None); } void TaskWork::Ctrl() { @@ -278,21 +278,21 @@ namespace app { } bool TaskWork::HasTaskInit(Task* t) { - if (TaskWork::HasTask(t)) + if (t && TaskWork::HasTask(t)) return t->op == Task::Op::Init; else return false; } bool TaskWork::HasTaskCtrl(Task* t) { - if (TaskWork::HasTask(t)) + if (t && TaskWork::HasTask(t)) return t->op == Task::Op::Ctrl; else return false; } bool TaskWork::HasTaskDest(Task* t) { - if (TaskWork::HasTask(t)) + if (t && TaskWork::HasTask(t)) return t->op == Task::Op::Dest; else return false; diff --git a/src/KKdLib/aet.cpp b/src/KKdLib/aet.cpp index e7e599a5..46cb9a7f 100644 --- a/src/KKdLib/aet.cpp +++ b/src/KKdLib/aet.cpp @@ -3,41 +3,155 @@ GitHub/GitLab: korenkonder */ +#include #include "aet.hpp" #include "f2/struct.hpp" #include "io/path.hpp" #include "io/memory_stream.hpp" -static void aet_set_classic_read_inner(aet_set* as, stream& s); +struct aet_layer_header { + int64_t markers_offset; + int64_t video_offset; + int64_t audio_offset; +}; + +struct aet_scene_header { + int64_t camera_offset; + int64_t comp_offset; + int64_t video_offset; + int64_t audio_offset; +}; + +static void aet_set_classic_read_inner(aet_set* as, prj::shared_ptr& alloc, stream& s); static void aet_set_classic_write_inner(aet_set* as, stream& s); -static void aet_set_modern_read_inner(aet_set* as, stream& s); +static void aet_set_modern_read_inner(aet_set* as, prj::shared_ptr& alloc, stream& s); static void aet_set_modern_write_inner(aet_set* as, stream& s); -aet_marker::aet_marker() : time() { +static void aet_classic_read_audio(aet_audio* audio, + prj::shared_ptr alloc, stream& s); +static aet_camera* aet_classic_read_camera(prj::shared_ptr alloc, + stream& s, int64_t offset); +static void aet_classic_read_comp(aet_comp* comp, + prj::shared_ptr alloc, stream& s, + std::map& layers, + std::map& items); +static void aet_classic_read_fcurve(aet_fcurve* fcurve, + prj::shared_ptr alloc, stream& s); +static void aet_classic_read_layer(aet_layer* layer, + prj::shared_ptr alloc, stream& s); +static aet_layer_audio* aet_classic_read_layer_audio(prj::shared_ptr alloc, + stream& s, int64_t offset); +static aet_layer_video* aet_classic_read_layer_video(prj::shared_ptr alloc, + stream& s, int64_t offset); +static aet_layer_video_3d* aet_classic_read_layer_video_3d(prj::shared_ptr alloc, + stream& s, int64_t offset); +static void aet_classic_read_marker(aet_marker* marker, + prj::shared_ptr alloc, stream& s); +static aet_scene* aet_classic_read_scene(prj::shared_ptr alloc, + stream& s, int64_t offset, std::map& layers, + std::map& items); +static void aet_classic_read_video(aet_video* video, + prj::shared_ptr alloc, stream& s, + std::map& items); + +static void aet_modern_read_audio(aet_audio* audio, + prj::shared_ptr alloc, stream& s, + uint32_t header_length, bool is_x); +static aet_camera* aet_modern_read_camera(prj::shared_ptr alloc, + stream& s, int64_t offset, + uint32_t header_length, bool is_x); +static void aet_modern_read_comp(aet_comp* comp, + prj::shared_ptr alloc, stream& s, + uint32_t header_length, bool is_x, + std::map& layers, std::map& items); +static void aet_modern_read_fcurve(aet_fcurve* fcurve, + prj::shared_ptr alloc, stream& s, + uint32_t header_length, bool is_x); +static void aet_modern_read_layer(aet_layer* layer, + prj::shared_ptr alloc, stream& s, + uint32_t header_length, bool is_x); +static aet_layer_audio* aet_modern_read_layer_audio(prj::shared_ptr alloc, + stream& s, int64_t offset, + uint32_t header_length, bool is_x); +static aet_layer_video* aet_modern_read_layer_video(prj::shared_ptr alloc, + stream& s, int64_t offset, + uint32_t header_length, bool is_x); +static aet_layer_video_3d* aet_modern_read_layer_video_3d(prj::shared_ptr alloc, + stream& s, int64_t offset, + uint32_t header_length, bool is_x); +static void aet_modern_read_marker(aet_marker* marker, + prj::shared_ptr alloc, stream& s, + uint32_t header_length, bool is_x); +static aet_scene* aet_modern_read_scene(prj::shared_ptr alloc, + stream& s, int64_t offset, + uint32_t header_length, bool is_x, + std::map& layers, std::map& items); +static void aet_modern_read_video(aet_video* video, + prj::shared_ptr alloc, stream& s, + uint32_t header_length, bool is_x, + std::map& items); + +static void aet_comp_set_item_parent(const aet_comp* comp, + std::map& layers, std::map& items); + +static const char* aet_move_data_string(const char* str, + prj::shared_ptr& alloc); + +static const char* aet_read_utf8_string_null_terminated_offset( + prj::shared_ptr& alloc, stream& s, int64_t offset); + +aet_fcurve::aet_fcurve() : keys_count(), keys() { } -aet_marker::~aet_marker() { +float_t aet_fcurve::interpolate(float_t frame) const { + if (!keys_count) + return 0.0f; + else if (keys_count == 1) + return keys[0]; + size_t keys_count = this->keys_count; + const float_t* keys = this->keys; + const float_t* values = &keys[keys_count]; + if (frame <= keys[0]) + return values[0]; + + const float_t* v6 = keys; + const float_t* v7 = &keys[keys_count]; + if (frame >= keys[keys_count - 1]) + return values[(keys_count - 1) * 2]; + + const float_t* v8 = &keys[keys_count / 2]; + while (v6 < v8) { + if (frame >= *v8) + v6 = v8; + else + v7 = v8; + v8 = &v6[(v7 - v6) / 2]; + } + + if (values - 1 <= v8) + return values[(keys_count - 1) * 2]; + + size_t v9 = (v8 - keys) * 2; + + float_t df = v8[1] - v8[0]; + float_t t = (frame - v8[0]) / df; + float_t t_1 = t - 1.0f; + return (t_1 * values[v9 + 1] + t * values[v9 + 3]) * t * t_1 * df + + t * t * (3.0f - 2.0f * t) * values[v9 + 2] + + (1.0f + 2.0f * t) * (t_1 * t_1) * values[v9]; } aet_layer_video_3d::aet_layer_video_3d() { } -aet_layer_video_3d::~aet_layer_video_3d() { - -} - aet_transfer_mode::aet_transfer_mode() : mode(), flag(), matte() { } -aet_layer_video::aet_layer_video() : _3d_init() { - -} - -aet_layer_video::~aet_layer_video() { +aet_layer_video::aet_layer_video() : _3d() { } @@ -45,27 +159,15 @@ aet_layer_audio::aet_layer_audio() { } -aet_layer_audio::~aet_layer_audio() { +aet_camera::aet_camera() { } -aet_color::aet_color() : r(), g(), b() { - +aet_video_src::aet_video_src() : sprite_name() { + sprite_index = -1; } -aet_video_src::aet_video_src() : sprite_index() { - -} - -aet_video_src::~aet_video_src() { - -} - -aet_video::aet_video() : width(), height(), fpf() { - -} - -aet_video::~aet_video() { +aet_video::aet_video() : color(), width(), height(), fpf(), sources_count(), sources() { } @@ -73,36 +175,35 @@ aet_audio::aet_audio() : sound_index() { } -aet_layer::aet_layer() : start_time(), end_time(), offset_time(), time_scale(), flags(), -quality(), item_type(), item(), parent(), video(), video_init(), audio(), audio_init() { +aet_marker::aet_marker() : time(), name() { } -aet_layer::~aet_layer() { +aet_layer::aet_layer() : name(), start_time(), end_time(), offset_time(), time_scale(), +flags(), quality(), item_type(), parent(), markers_count(), markers(), video(), audio() { } -aet_camera::aet_camera() { +aet_comp::aet_comp() : layers_count(), layers() { } -aet_camera::~aet_camera() { +aet_scene::aet_scene() : name(), start_time(), end_time(), fps(), color(), width(), +height(), camera(), comp_count(), comp(), video_count(), video(), audio_count(), audio() { } -aet_scene::aet_scene() : start_time(), end_time(), fps(), width(), height(), camera_init() { +const aet_comp* aet_scene::get_root_comp(const aet_scene* scene) { + if (scene && scene->comp_count) + return &scene->comp[scene->comp_count - 1]; + return 0; +} + +aet_set::aet_set() : ready(), modern(), big_endian(), is_x(), scenes_count(), scenes() { } -aet_scene::~aet_scene() { - -} - -aet_set::aet_set() : ready(), modern(), big_endian(), is_x() { - -} - -aet_set::~aet_set() { +void aet_set::move_data(aet_set* set_src, prj::shared_ptr alloc) { } @@ -120,19 +221,47 @@ void aet_set::pack_file(void** data, size_t* size) { s.copy(data, size); } -void aet_set::unpack_file(const void* data, size_t size, bool modern) { +void aet_set::unpack_file(prj::shared_ptr alloc, const void* data, size_t size, bool modern) { if (!data || !size) return; memory_stream s; s.open(data, size); if (!modern) - aet_set_classic_read_inner(this, s); + aet_set_classic_read_inner(this, alloc, s); else - aet_set_modern_read_inner(this, s); + aet_set_modern_read_inner(this, alloc, s); } -static void aet_set_classic_read_inner(aet_set* as, stream& s) { +static void aet_set_classic_read_inner(aet_set* as, prj::shared_ptr& alloc, stream& s) { + uint32_t scenes_count = 0; + while (s.read_uint32_t()) + scenes_count++; + as->scenes_count = scenes_count; + + aet_scene** scenes = alloc->allocate(scenes_count); + as->scenes = (const aet_scene**)scenes; + + uint32_t* data = force_malloc_s(uint32_t, scenes_count); + s.set_position(0, SEEK_SET); + for (uint32_t i = 0; i < scenes_count; i++) + data[i] = s.read_uint32_t(); + + std::map layers; + std::map items; + + for (uint32_t i = 0; i < scenes_count; i++) + scenes[i] = aet_classic_read_scene(alloc, s, data[i], layers, items); + + for (uint32_t i = 0; i < scenes_count; i++) { + aet_scene* scene = scenes[i]; + const aet_comp* comp = scene->comp; + for (uint32_t j = scene->comp_count; j; j--, comp++) + aet_comp_set_item_parent(comp, layers, items); + } + + free_def(data); + as->ready = true; as->modern = false; as->big_endian = false; @@ -143,19 +272,56 @@ static void aet_set_classic_write_inner(aet_set* as, stream& s) { } -static void aet_set_modern_read_inner(aet_set* as, stream& s) { +static void aet_set_modern_read_inner(aet_set* as, prj::shared_ptr& alloc, stream& s) { f2_struct st; st.read(s); if (st.header.signature != reverse_endianness_uint32_t('AETC') || !st.data.size()) return; + uint32_t header_length = st.header.length; bool big_endian = st.header.use_big_endian; + bool is_x = st.pof.shift_x; memory_stream s_aetc; s_aetc.open(st.data); s_aetc.big_endian = big_endian; - bool is_x = false; + uint32_t scenes_count = 0; + if (!is_x) + while (s_aetc.read_uint32_t_reverse_endianness()) + scenes_count++; + else + while (s_aetc.read_int64_t_reverse_endianness()) + scenes_count++; + as->scenes_count = scenes_count; + + aet_scene** scenes = alloc->allocate(scenes_count); + as->scenes = (const aet_scene**)scenes; + + int64_t* data = force_malloc_s(int64_t, scenes_count); + s_aetc.set_position(0, SEEK_SET); + if (!is_x) + for (uint32_t i = 0; i < scenes_count; i++) + data[i] = s_aetc.read_uint32_t_reverse_endianness(); + else + for (uint32_t i = 0; i < scenes_count; i++) + data[i] = s_aetc.read_int64_t_reverse_endianness(); + + std::map layers; + std::map items; + + for (uint32_t i = 0; i < scenes_count; i++) + scenes[i] = aet_modern_read_scene(alloc, s_aetc, data[i], + header_length, is_x, layers, items); + + for (uint32_t i = 0; i < scenes_count; i++) { + aet_scene* scene = scenes[i]; + const aet_comp* comp = scene->comp; + for (uint32_t j = scene->comp_count; j; j--, comp++) + aet_comp_set_item_parent(comp, layers, items); + } + + free_def(data); as->ready = true; as->modern = true; @@ -193,3 +359,680 @@ static void aet_set_modern_write_inner(aet_set* as, stream& s) { st.write(s, true, is_x); } + +static void aet_classic_read_audio(aet_audio* audio, + prj::shared_ptr alloc, stream& s) { + audio->sound_index = s.read_int32_t(); +} + +static aet_camera* aet_classic_read_camera(prj::shared_ptr alloc, + stream& s, int64_t offset) { + if (!offset) + return 0; + + aet_camera* cam = alloc->allocate(); + s.position_push(offset, SEEK_SET); + aet_classic_read_fcurve(&cam->eye_x, alloc, s); + aet_classic_read_fcurve(&cam->eye_y, alloc, s); + aet_classic_read_fcurve(&cam->eye_z, alloc, s); + aet_classic_read_fcurve(&cam->pos_x, alloc, s); + aet_classic_read_fcurve(&cam->pos_y, alloc, s); + aet_classic_read_fcurve(&cam->pos_z, alloc, s); + aet_classic_read_fcurve(&cam->dir_x, alloc, s); + aet_classic_read_fcurve(&cam->dir_y, alloc, s); + aet_classic_read_fcurve(&cam->dir_z, alloc, s); + aet_classic_read_fcurve(&cam->rot_x, alloc, s); + aet_classic_read_fcurve(&cam->rot_y, alloc, s); + aet_classic_read_fcurve(&cam->rot_z, alloc, s); + aet_classic_read_fcurve(&cam->zoom, alloc, s); + s.position_pop(); + return cam; +} + +static void aet_classic_read_comp(aet_comp* comp, + prj::shared_ptr alloc, stream& s, + std::map& layers, + std::map& items) { + items.insert_or_assign(s.get_position(), comp); + + comp->layers_count = s.read_uint32_t(); + uint32_t layers_offset = s.read_uint32_t(); + + if (layers_offset) { + aet_layer* layer = alloc->allocate(comp->layers_count); + comp->layers = layer; + + s.position_push(layers_offset, SEEK_SET); + for (uint32_t i = comp->layers_count; i; i--, layer++) { + layers.insert_or_assign(s.get_position(), layer); + aet_classic_read_layer(layer, alloc, s); + } + s.position_pop(); + } + else + comp->layers = 0; +} + +static void aet_classic_read_fcurve(aet_fcurve* fcurve, + prj::shared_ptr alloc, stream& s) { + fcurve->keys_count = s.read_uint32_t(); + uint32_t keys_offset = s.read_uint32_t(); + + s.position_push(keys_offset, SEEK_SET); + if (fcurve->keys_count > 1) { + float_t* key = alloc->allocate(fcurve->keys_count * 3ULL); + fcurve->keys = key; + + s.read(key, fcurve->keys_count * 3ULL * sizeof(float_t)); + } + else if (fcurve->keys_count) { + float_t* key = alloc->allocate(); + fcurve->keys = key; + + *key = s.read_float_t(); + } + else + fcurve->keys = 0; + s.position_pop(); +} + +static void aet_classic_read_layer(aet_layer* layer, + prj::shared_ptr alloc, stream& s) { + aet_layer_header alh = {}; + + layer->name = aet_read_utf8_string_null_terminated_offset( + alloc, s, s.read_uint32_t()); + layer->start_time = s.read_float_t(); + layer->end_time = s.read_float_t(); + layer->offset_time = s.read_float_t(); + layer->time_scale = s.read_float_t(); + *(uint16_t*)&layer->flags = s.read_uint16_t(); + layer->quality = (aet_layer_quality)s.read_uint8_t(); + layer->item_type = (aet_item_type)s.read_uint8_t(); + if (layer->item_type == AET_ITEM_TYPE_VIDEO + || layer->item_type == AET_ITEM_TYPE_COMPOSITION) + layer->item.none = (void*)(size_t)s.read_uint32_t(); + else + s.read_uint32_t(); + + layer->parent = (const aet_layer*)(size_t)s.read_uint32_t(); + layer->markers_count = s.read_uint32_t(); + alh.markers_offset = s.read_uint32_t(); + alh.video_offset = s.read_uint32_t(); + alh.audio_offset = s.read_uint32_t(); + + if (alh.markers_offset) { + aet_marker* marker = alloc->allocate(layer->markers_count); + layer->markers = marker; + + s.position_push(alh.markers_offset, SEEK_SET); + for (uint32_t i = layer->markers_count; i; i--, marker++) + aet_classic_read_marker(marker, alloc, s); + s.position_pop(); + } + else + layer->audio = 0; + + layer->video = aet_classic_read_layer_video(alloc, s, alh.video_offset); + layer->audio = aet_classic_read_layer_audio(alloc, s, alh.audio_offset); +} + +static aet_layer_audio* aet_classic_read_layer_audio(prj::shared_ptr alloc, + stream& s, int64_t offset) { + if (!offset) + return 0; + + aet_layer_audio* layer_audio = alloc->allocate(); + s.position_push(offset, SEEK_SET); + aet_classic_read_fcurve(&layer_audio->volume_l, alloc, s); + aet_classic_read_fcurve(&layer_audio->volume_r, alloc, s); + aet_classic_read_fcurve(&layer_audio->pan_l, alloc, s); + aet_classic_read_fcurve(&layer_audio->pan_r, alloc, s); + s.position_pop(); + return layer_audio; +} + +static aet_layer_video* aet_classic_read_layer_video(prj::shared_ptr alloc, + stream& s, int64_t offset) { + if (!offset) + return 0; + + aet_layer_video* layer_video = alloc->allocate(); + s.position_push(offset, SEEK_SET); + layer_video->transfer_mode.mode = (aet_blend_mode)s.read_uint8_t(); + layer_video->transfer_mode.flag = s.read_uint8_t(); + layer_video->transfer_mode.matte = s.read_uint8_t(); + s.read_uint8_t(); + aet_classic_read_fcurve(&layer_video->anchor_x, alloc, s); + aet_classic_read_fcurve(&layer_video->anchor_y, alloc, s); + aet_classic_read_fcurve(&layer_video->pos_x, alloc, s); + aet_classic_read_fcurve(&layer_video->pos_y, alloc, s); + aet_classic_read_fcurve(&layer_video->rot_z, alloc, s); + aet_classic_read_fcurve(&layer_video->scale_x, alloc, s); + aet_classic_read_fcurve(&layer_video->scale_y, alloc, s); + aet_classic_read_fcurve(&layer_video->opacity, alloc, s); + layer_video->_3d = aet_classic_read_layer_video_3d(alloc, s, s.read_uint32_t()); + s.position_pop(); + return layer_video; +} + +static aet_layer_video_3d* aet_classic_read_layer_video_3d(prj::shared_ptr alloc, + stream& s, int64_t offset) { + if (!offset) + return 0; + + aet_layer_video_3d* layer_video_3d = alloc->allocate(); + s.position_push(offset, SEEK_SET); + aet_classic_read_fcurve(&layer_video_3d->anchor_z, alloc, s); + aet_classic_read_fcurve(&layer_video_3d->pos_z, alloc, s); + aet_classic_read_fcurve(&layer_video_3d->dir_x, alloc, s); + aet_classic_read_fcurve(&layer_video_3d->dir_y, alloc, s); + aet_classic_read_fcurve(&layer_video_3d->dir_z, alloc, s); + aet_classic_read_fcurve(&layer_video_3d->rot_x, alloc, s); + aet_classic_read_fcurve(&layer_video_3d->rot_y, alloc, s); + aet_classic_read_fcurve(&layer_video_3d->scale_z, alloc, s); + s.position_pop(); + return layer_video_3d; +} + +static void aet_classic_read_marker(aet_marker* marker, + prj::shared_ptr alloc, stream& s) { + marker->time = s.read_float_t(); + marker->name = aet_read_utf8_string_null_terminated_offset( + alloc, s, s.read_uint32_t()); +} + +static aet_scene* aet_classic_read_scene(prj::shared_ptr alloc, + stream& s, int64_t offset, std::map& layers, + std::map& items) { + if (!offset) + return 0; + + aet_scene_header ash = {}; + + aet_scene* scene = alloc->allocate(); + s.position_push(offset, SEEK_SET); + scene->name = aet_read_utf8_string_null_terminated_offset( + alloc, s, s.read_uint32_t()); + scene->start_time = s.read_float_t(); + scene->end_time = s.read_float_t(); + scene->fps = s.read_float_t(); + scene->color[0] = s.read_uint8_t(); + scene->color[1] = s.read_uint8_t(); + scene->color[2] = s.read_uint8_t(); + s.read_uint8_t(); + scene->width = s.read_uint32_t(); + scene->height = s.read_uint32_t(); + ash.camera_offset = s.read_uint32_t(); + scene->comp_count = s.read_uint32_t(); + ash.comp_offset = s.read_uint32_t(); + scene->video_count = s.read_uint32_t(); + ash.video_offset = s.read_uint32_t(); + scene->audio_count = s.read_uint32_t(); + ash.audio_offset = s.read_uint32_t(); + s.position_pop(); + + scene->camera = aet_classic_read_camera(alloc, s, ash.camera_offset); + + if (ash.comp_offset) { + aet_comp* comp = alloc->allocate(scene->comp_count); + scene->comp = comp; + + s.position_push(ash.comp_offset, SEEK_SET); + for (uint32_t i = scene->comp_count; i; i--, comp++) + aet_classic_read_comp(comp, alloc, s, layers, items); + s.position_pop(); + } + else + scene->comp = 0; + + if (ash.video_offset) { + aet_video* video = alloc->allocate(scene->video_count); + scene->video = video; + + s.position_push(ash.video_offset, SEEK_SET); + for (uint32_t i = scene->video_count; i; i--, video++) + aet_classic_read_video(video, alloc, s, items); + s.position_pop(); + } + else + scene->video = 0; + + if (ash.audio_offset) { + aet_audio* audio = alloc->allocate(scene->audio_count); + scene->audio = audio; + + s.position_push(ash.audio_offset, SEEK_SET); + for (uint32_t i = scene->audio_count; i; i--, audio++) + aet_classic_read_audio(audio, alloc, s); + s.position_pop(); + } + else + scene->audio = 0; + return scene; +} + +static void aet_classic_read_video(aet_video* video, + prj::shared_ptr alloc, stream& s, + std::map& items) { + items.insert_or_assign(s.get_position(), video); + + video->color[0] = s.read_uint8_t(); + video->color[1] = s.read_uint8_t(); + video->color[2] = s.read_uint8_t(); + s.read_uint8_t(); + video->width = s.read_uint16_t(); + video->height = s.read_uint16_t(); + video->fpf = s.read_float_t(); + video->sources_count = s.read_uint32_t(); + uint32_t sources_offset = s.read_uint32_t(); + + if (sources_offset) { + aet_video_src* source = alloc->allocate(video->sources_count); + video->sources = source; + + s.position_push(sources_offset, SEEK_SET); + for (uint32_t i = video->sources_count; i; i--, source++) { + source->sprite_name = aet_read_utf8_string_null_terminated_offset( + alloc, s, s.read_uint32_t()); + source->sprite_index = s.read_int32_t(); + } + s.position_pop(); + } + else + video->sources = 0; +} + +static void aet_modern_read_audio(aet_audio* audio, + prj::shared_ptr alloc, stream& s, + uint32_t header_length, bool is_x) { + audio->sound_index = s.read_int32_t(); +} + +static aet_camera* aet_modern_read_camera(prj::shared_ptr alloc, + stream& s, int64_t offset, + uint32_t header_length, bool is_x) { + if (!offset) + return 0; + + aet_camera* cam = alloc->allocate(); + s.position_push(offset, SEEK_SET); + aet_modern_read_fcurve(&cam->eye_x, alloc, s, header_length, is_x); + aet_modern_read_fcurve(&cam->eye_y, alloc, s, header_length, is_x); + aet_modern_read_fcurve(&cam->eye_z, alloc, s, header_length, is_x); + aet_modern_read_fcurve(&cam->pos_x, alloc, s, header_length, is_x); + aet_modern_read_fcurve(&cam->pos_y, alloc, s, header_length, is_x); + aet_modern_read_fcurve(&cam->pos_z, alloc, s, header_length, is_x); + aet_modern_read_fcurve(&cam->dir_x, alloc, s, header_length, is_x); + aet_modern_read_fcurve(&cam->dir_y, alloc, s, header_length, is_x); + aet_modern_read_fcurve(&cam->dir_z, alloc, s, header_length, is_x); + aet_modern_read_fcurve(&cam->rot_x, alloc, s, header_length, is_x); + aet_modern_read_fcurve(&cam->rot_y, alloc, s, header_length, is_x); + aet_modern_read_fcurve(&cam->rot_z, alloc, s, header_length, is_x); + aet_modern_read_fcurve(&cam->zoom, alloc, s, header_length, is_x); + s.position_pop(); + return cam; +} + +static void aet_modern_read_comp(aet_comp* comp, + prj::shared_ptr alloc, stream& s, + uint32_t header_length, bool is_x, + std::map& layers, std::map& items) { + items.insert_or_assign(s.get_position(), comp); + + comp->layers_count = s.read_uint32_t(); + int64_t layers_offset = s.read_offset(header_length, is_x); + + if (layers_offset) { + aet_layer* layer = alloc->allocate(comp->layers_count); + comp->layers = layer; + + s.position_push(layers_offset, SEEK_SET); + for (uint32_t i = comp->layers_count; i; i--, layer++) { + layers.insert_or_assign(s.get_position(), layer); + aet_modern_read_layer(layer, alloc, s, header_length, is_x); + } + s.position_pop(); + } + else + comp->layers = 0; +} + +static void aet_modern_read_fcurve(aet_fcurve* fcurve, + prj::shared_ptr alloc, stream& s, + uint32_t header_length, bool is_x) { + fcurve->keys_count = s.read_uint32_t(); + int64_t keys_offset = s.read_offset(header_length, is_x); + + s.position_push(keys_offset, SEEK_SET); + if (fcurve->keys_count > 1) { + float_t* key = alloc->allocate(fcurve->keys_count * 3ULL); + fcurve->keys = key; + + s.read(key, fcurve->keys_count * 3ULL * sizeof(float_t)); + } + else if (fcurve->keys_count) { + float_t* key = alloc->allocate(); + fcurve->keys = key; + + *key = s.read_float_t_reverse_endianness(); + } + else + fcurve->keys = 0; + s.position_pop(); +} + +static void aet_modern_read_layer(aet_layer* layer, + prj::shared_ptr alloc, stream& s, + uint32_t header_length, bool is_x) { + aet_layer_header alh = {}; + + if (!is_x) { + layer->name = aet_read_utf8_string_null_terminated_offset( + alloc, s, s.read_offset_f2(header_length)); + layer->start_time = s.read_float_t_reverse_endianness(); + layer->end_time = s.read_float_t_reverse_endianness(); + layer->offset_time = s.read_float_t_reverse_endianness(); + layer->time_scale = s.read_float_t_reverse_endianness(); + *(uint16_t*)&layer->flags = s.read_uint16_t_reverse_endianness(); + layer->quality = (aet_layer_quality)s.read_uint8_t(); + layer->item_type = (aet_item_type)s.read_uint8_t(); + if (layer->item_type == AET_ITEM_TYPE_VIDEO + || layer->item_type == AET_ITEM_TYPE_COMPOSITION) + layer->item.none = (void*)(size_t)s.read_offset_f2(header_length); + else + s.read_offset_f2(header_length); + + layer->parent = (const aet_layer*)(size_t)s.read_offset_f2(header_length); + layer->markers_count = s.read_uint32_t_reverse_endianness(); + alh.markers_offset = s.read_offset_f2(header_length); + alh.video_offset = s.read_offset_f2(header_length); + alh.audio_offset = s.read_offset_f2(header_length); + } + else { + layer->name = aet_read_utf8_string_null_terminated_offset( + alloc, s, s.read_offset_x()); + layer->start_time = s.read_float_t_reverse_endianness(); + layer->end_time = s.read_float_t_reverse_endianness(); + layer->offset_time = s.read_float_t_reverse_endianness(); + layer->time_scale = s.read_float_t_reverse_endianness(); + *(uint16_t*)&layer->flags = s.read_uint16_t_reverse_endianness(); + layer->quality = (aet_layer_quality)s.read_uint8_t(); + layer->item_type = (aet_item_type)s.read_uint8_t(); + if (layer->item_type == AET_ITEM_TYPE_VIDEO + || layer->item_type == AET_ITEM_TYPE_COMPOSITION) + layer->item.none = (void*)s.read_offset_x(); + else + s.read_offset_x(); + + layer->parent = (const aet_layer*)s.read_offset_x(); + layer->markers_count = s.read_uint32_t_reverse_endianness(); + alh.markers_offset = s.read_offset_x(); + alh.video_offset = s.read_offset_x(); + alh.audio_offset = s.read_offset_x(); + } + + if (alh.markers_offset) { + aet_marker* marker = alloc->allocate(layer->markers_count); + layer->markers = marker; + + s.position_push(alh.markers_offset, SEEK_SET); + for (uint32_t i = layer->markers_count; i; i--, marker++) + aet_modern_read_marker(marker, alloc, s, header_length, is_x); + s.position_pop(); + } + else + layer->audio = 0; + + layer->video = aet_modern_read_layer_video(alloc, s, alh.video_offset, header_length, is_x); + layer->audio = aet_modern_read_layer_audio(alloc, s, alh.audio_offset, header_length, is_x); +} + +static aet_layer_audio* aet_modern_read_layer_audio(prj::shared_ptr alloc, + stream& s, int64_t offset, + uint32_t header_length, bool is_x) { + if (!offset) + return 0; + + aet_layer_audio* layer_audio = alloc->allocate(); + s.position_push(offset, SEEK_SET); + aet_modern_read_fcurve(&layer_audio->volume_l, alloc, s, header_length, is_x); + aet_modern_read_fcurve(&layer_audio->volume_r, alloc, s, header_length, is_x); + aet_modern_read_fcurve(&layer_audio->pan_l, alloc, s, header_length, is_x); + aet_modern_read_fcurve(&layer_audio->pan_r, alloc, s, header_length, is_x); + s.position_pop(); + return layer_audio; +} + +static aet_layer_video* aet_modern_read_layer_video(prj::shared_ptr alloc, + stream& s, int64_t offset, + uint32_t header_length, bool is_x) { + if (!offset) + return 0; + + aet_layer_video* layer_video = alloc->allocate(); + s.position_push(offset, SEEK_SET); + layer_video->transfer_mode.mode = (aet_blend_mode)s.read_uint8_t(); + layer_video->transfer_mode.flag = s.read_uint8_t(); + layer_video->transfer_mode.matte = s.read_uint8_t(); + s.read_uint8_t(); + if (is_x) + s.read_uint32_t(); + aet_modern_read_fcurve(&layer_video->anchor_x, alloc, s, header_length, is_x); + aet_modern_read_fcurve(&layer_video->anchor_y, alloc, s, header_length, is_x); + aet_modern_read_fcurve(&layer_video->pos_x, alloc, s, header_length, is_x); + aet_modern_read_fcurve(&layer_video->pos_y, alloc, s, header_length, is_x); + aet_modern_read_fcurve(&layer_video->rot_z, alloc, s, header_length, is_x); + aet_modern_read_fcurve(&layer_video->scale_x, alloc, s, header_length, is_x); + aet_modern_read_fcurve(&layer_video->scale_y, alloc, s, header_length, is_x); + aet_modern_read_fcurve(&layer_video->opacity, alloc, s, header_length, is_x); + layer_video->_3d = aet_modern_read_layer_video_3d(alloc, + s, s.read_offset(header_length, is_x), header_length, is_x); + s.position_pop(); + return layer_video; +} + +static aet_layer_video_3d* aet_modern_read_layer_video_3d(prj::shared_ptr alloc, + stream& s, int64_t offset, + uint32_t header_length, bool is_x) { + if (!offset) + return 0; + + aet_layer_video_3d* layer_video_3d = alloc->allocate(); + s.position_push(offset, SEEK_SET); + aet_modern_read_fcurve(&layer_video_3d->anchor_z, alloc, s, header_length, is_x); + aet_modern_read_fcurve(&layer_video_3d->pos_z, alloc, s, header_length, is_x); + aet_modern_read_fcurve(&layer_video_3d->dir_x, alloc, s, header_length, is_x); + aet_modern_read_fcurve(&layer_video_3d->dir_y, alloc, s, header_length, is_x); + aet_modern_read_fcurve(&layer_video_3d->dir_z, alloc, s, header_length, is_x); + aet_modern_read_fcurve(&layer_video_3d->rot_x, alloc, s, header_length, is_x); + aet_modern_read_fcurve(&layer_video_3d->rot_y, alloc, s, header_length, is_x); + aet_modern_read_fcurve(&layer_video_3d->scale_z, alloc, s, header_length, is_x); + s.position_pop(); + return layer_video_3d; +} + +static void aet_modern_read_marker(aet_marker* marker, + prj::shared_ptr alloc, stream& s, + uint32_t header_length, bool is_x) { + marker->time = s.read_float_t_reverse_endianness(); + marker->name = aet_read_utf8_string_null_terminated_offset( + alloc, s, s.read_offset(header_length, is_x)); +} + +static aet_scene* aet_modern_read_scene(prj::shared_ptr alloc, + stream& s, int64_t offset, + uint32_t header_length, bool is_x, + std::map& layers, std::map& items) { + if (!offset) + return 0; + + aet_scene_header ash = {}; + + aet_scene* scene = alloc->allocate(); + s.position_push(offset, SEEK_SET); + if (!is_x) { + scene->name = aet_read_utf8_string_null_terminated_offset( + alloc, s, s.read_offset_f2(header_length)); + scene->start_time = s.read_float_t_reverse_endianness(); + scene->end_time = s.read_float_t_reverse_endianness(); + scene->fps = s.read_float_t_reverse_endianness(); + scene->color[0] = s.read_uint8_t(); + scene->color[1] = s.read_uint8_t(); + scene->color[2] = s.read_uint8_t(); + s.read_uint8_t(); + scene->width = s.read_uint32_t_reverse_endianness(); + scene->height = s.read_uint32_t_reverse_endianness(); + ash.camera_offset = s.read_offset_f2(header_length); + scene->comp_count = s.read_uint32_t_reverse_endianness(); + ash.comp_offset = s.read_offset_f2(header_length); + scene->video_count = s.read_uint32_t_reverse_endianness(); + ash.video_offset = s.read_offset_f2(header_length); + scene->audio_count = s.read_uint32_t_reverse_endianness(); + ash.audio_offset = s.read_offset_f2(header_length); + } + else { + scene->name = aet_read_utf8_string_null_terminated_offset( + alloc, s, s.read_offset_x()); + scene->start_time = s.read_float_t_reverse_endianness(); + scene->end_time = s.read_float_t_reverse_endianness(); + scene->fps = s.read_float_t_reverse_endianness(); + scene->color[0] = s.read_uint8_t(); + scene->color[1] = s.read_uint8_t(); + scene->color[2] = s.read_uint8_t(); + s.read_uint8_t(); + scene->width = s.read_uint32_t_reverse_endianness(); + scene->height = s.read_uint32_t_reverse_endianness(); + ash.camera_offset = s.read_offset_x(); + scene->comp_count = s.read_uint32_t_reverse_endianness(); + ash.comp_offset = s.read_offset_x(); + scene->video_count = s.read_uint32_t_reverse_endianness(); + ash.video_offset = s.read_offset_x(); + scene->audio_count = s.read_uint32_t_reverse_endianness(); + ash.audio_offset = s.read_offset_x(); + } + s.position_pop(); + + scene->camera = aet_modern_read_camera(alloc, s, ash.camera_offset, header_length, is_x); + + if (ash.comp_offset) { + aet_comp* comp = alloc->allocate(scene->comp_count); + scene->comp = comp; + + s.position_push(ash.comp_offset, SEEK_SET); + for (uint32_t i = scene->comp_count; i; i--, comp++) + aet_modern_read_comp(comp, alloc, s, header_length, is_x, layers, items); + s.position_pop(); + } + else + scene->comp = 0; + + if (ash.video_offset) { + aet_video* video = alloc->allocate(scene->video_count); + scene->video = video; + + s.position_push(ash.video_offset, SEEK_SET); + for (uint32_t i = scene->video_count; i; i--, video++) + aet_modern_read_video(video, alloc, s, header_length, is_x, items); + s.position_pop(); + } + else + scene->video = 0; + + if (ash.audio_offset) { + aet_audio* audio = alloc->allocate(scene->audio_count); + scene->audio = audio; + + s.position_push(ash.audio_offset, SEEK_SET); + for (uint32_t i = scene->audio_count; i; i--, audio++) + aet_modern_read_audio(audio, alloc, s, header_length, is_x); + s.position_pop(); + } + else + scene->audio = 0; + return scene; +} + +static void aet_modern_read_video(aet_video* video, + prj::shared_ptr alloc, stream& s, + uint32_t header_length, bool is_x, + std::map& items) { + items.insert_or_assign(s.get_position(), video); + + video->color[0] = s.read_uint8_t(); + video->color[1] = s.read_uint8_t(); + video->color[2] = s.read_uint8_t(); + s.read_uint8_t(); + video->width = s.read_uint16_t_reverse_endianness(); + video->height = s.read_uint16_t_reverse_endianness(); + video->fpf = s.read_float_t_reverse_endianness(); + video->sources_count = s.read_uint32_t_reverse_endianness(); + int64_t sources_offset = s.read_offset(header_length, is_x); + + if (sources_offset) { + aet_video_src* source = alloc->allocate(video->sources_count); + video->sources = source; + + s.position_push(sources_offset, SEEK_SET); + if (!is_x) + for (uint32_t i = video->sources_count; i; i--, source++) { + source->sprite_name = aet_read_utf8_string_null_terminated_offset( + alloc, s, s.read_offset_f2(header_length)); + source->sprite_index = s.read_int32_t(); + } + else + for (uint32_t i = video->sources_count; i; i--, source++) { + source->sprite_name = aet_read_utf8_string_null_terminated_offset( + alloc, s, s.read_offset_x()); + source->sprite_index = s.read_int32_t(); + } + s.position_pop(); + } + else + video->sources = 0; +} + +static void aet_comp_set_item_parent(const aet_comp* comp, + std::map& layers, std::map& items) { + aet_layer* layer = (aet_layer*)comp->layers; + for (uint32_t i = comp->layers_count; i; i--, layer++) { + if (layer->item_type == AET_ITEM_TYPE_VIDEO + || layer->item_type == AET_ITEM_TYPE_COMPOSITION) { + int64_t item_offset = (int64_t)layer->item.none; + layer->item.none = 0; + + if (item_offset) { + auto elem = items.find(item_offset); + if (elem != items.end()) + layer->item = elem->second; + } + } + + int64_t parent_offset = (int64_t)layer->parent; + layer->parent = 0; + + if (parent_offset) { + auto elem = layers.find(parent_offset); + if (elem != layers.end()) + layer->parent = elem->second; + } + } +} + +inline static const char* aet_move_data_string(const char* str, + prj::shared_ptr& alloc) { + if (str) + return alloc->allocate(str, utf8_length(str) + 1); + return 0; +} + +inline static const char* aet_read_utf8_string_null_terminated_offset( + prj::shared_ptr& alloc, stream& s, int64_t offset) { + size_t len = s.read_utf8_string_null_terminated_offset_length(offset); + char* str = alloc->allocate(len + 1); + s.position_push(offset, SEEK_SET); + s.read(str, len); + s.position_pop(); + str[len] = 0; + return str; +} diff --git a/src/KKdLib/aet.hpp b/src/KKdLib/aet.hpp index 4e6f1b26..f063b1b2 100644 --- a/src/KKdLib/aet.hpp +++ b/src/KKdLib/aet.hpp @@ -7,117 +7,102 @@ #pragma once -#include -#include #include "default.hpp" -#include "kf.hpp" +#include "prj/shared_ptr.hpp" +#include "prj/stack_allocator.hpp" enum aet_blend_mode : uint8_t { - AET_BLEND_MODE_NONE = 0, // Unsupported - AET_BLEND_MODE_COPY = 1, // Unsupported - AET_BLEND_MODE_BEHIND = 2, // Unsupported - AET_BLEND_MODE_NORMAL = 3, - AET_BLEND_MODE_DISSOLVE = 4, // Unsupported - AET_BLEND_MODE_ADD = 5, - AET_BLEND_MODE_MULTIPLY = 6, - AET_BLEND_MODE_SCREEN = 7, - AET_BLEND_MODE_OVERLAY = 8, // Unsupported - AET_BLEND_MODE_SOFT_LIGHT = 9, // Unsupported - AET_BLEND_MODE_HARD_LIGHT = 10, // Unsupported - AET_BLEND_MODE_DARKER = 11, // Unsupported - AET_BLEND_MODE_LIGHTEN = 12, // Unsupported - AET_BLEND_MODE_CLASSIC_DIFFERENCE = 13, // Unsupported - AET_BLEND_MODE_HUE = 14, // Unsupported - AET_BLEND_MODE_SATURATION = 15, // Unsupported - AET_BLEND_MODE_COLOR = 16, // Unsupported - AET_BLEND_MODE_LUMINOSITY = 17, // Unsupported - AET_BLEND_MODE_STENCIL_ALPHA = 18, // Unsupported - AET_BLEND_MODE_STENCIL_LUMA = 19, // Unsupported - AET_BLEND_MODE_SILHOUETTE_ALPHA = 20, // Unsupported - AET_BLEND_MODE_SILHOUETTE_LUMA = 21, // Unsupported - AET_BLEND_MODE_LUMINESCENT_PREMULTYPLY = 22, // Unsupported - AET_BLEND_MODE_ALPHA_ADD = 23, // Unsupported - AET_BLEND_MODE_CLASSIC_COLOR_DODGE = 24, // Unsupported - AET_BLEND_MODE_CLASSIC_COLOR_BURN = 25, // Unsupported - AET_BLEND_MODE_EXCLUSION = 26, // Unsupported - AET_BLEND_MODE_DIFFERENCE = 27, // Unsupported - AET_BLEND_MODE_COLOR_DODGE = 28, // Unsupported - AET_BLEND_MODE_COLOR_BURN = 29, // Unsupported - AET_BLEND_MODE_LINEAR_DODGE = 30, // Unsupported - AET_BLEND_MODE_LINEAR_BURN = 31, // Unsupported - AET_BLEND_MODE_LINEAR_LIGHT = 32, // Unsupported - AET_BLEND_MODE_VIVID_LIGHT = 33, // Unsupported - AET_BLEND_MODE_PIN_LIGHT = 34, // Unsupported - AET_BLEND_MODE_HARD_MIX = 35, // Unsupported - AET_BLEND_MODE_LIGHTER_COLOR = 36, // Unsupported - AET_BLEND_MODE_DARKER_COLOR = 37, // Unsupported - AET_BLEND_MODE_SUBTRACT = 38, // Unsupported - AET_BLEND_MODE_DIVIDE = 39, // Unsupported -}; - -enum aet_item_type : uint8_t { - AET_ITEM_TYPE_NONE = 0, - AET_ITEM_TYPE_VIDEO = 1, - AET_ITEM_TYPE_AUDIO = 2, - AET_ITEM_TYPE_COMPOSITION = 3, -}; - -enum aet_layer_flags : uint16_t { - AET_LAYER_FLAGS_VIDEO_ACTIVE = 0x000001, - AET_LAYER_FLAGS_AUDIO_ACTIVE = 0x000002, - AET_LAYER_FLAGS_EFFECTS_ACTIVE = 0x000004, - AET_LAYER_FLAGS_MOTION_BLUR = 0x000008, - AET_LAYER_FLAGS_FRAME_BLENDING = 0x000010, - AET_LAYER_FLAGS_LOCKED = 0x000020, - AET_LAYER_FLAGS_SHY = 0x000040, - AET_LAYER_FLAGS_COLLAPSE = 0x000080, - AET_LAYER_FLAGS_AUTO_ORIENT_ROTATION = 0x000100, - AET_LAYER_FLAGS_ADJUSTMENT_LAYER = 0x000200, - AET_LAYER_FLAGS_TIME_REMAPPING = 0x000400, - AET_LAYER_FLAGS_LAYER_IS_3D = 0x000800, - AET_LAYER_FLAGS_LOOK_AT_CAMERA = 0x001000, - AET_LAYER_FLAGS_LOOK_AT_POINT_OF_INTEREST = 0x002000, - AET_LAYER_FLAGS_SOLO = 0x004000, - AET_LAYER_FLAGS_MARKERS_LOCKED = 0x008000, - // Should be there but they don't fit in 16 bits - //AET_LAYER_FLAGS_NULL_LAYER = 0x010000, - //AET_LAYER_FLAGS_HIDE_LOCKED_MASKS = 0x020000, - //AET_LAYER_FLAGS_GUIDE_LAYER = 0x040000, - //AET_LAYER_FLAGS_ADVANCED_FRAME_BLENDING = 0x080000, - //AET_LAYER_FLAGS_SUB_LAYERS_RENDER_SEPARATELY = 0x100000, - //AET_LAYER_FLAGS_ENVIRONMENT_LAYER = 0x200000, + AET_BLEND_MODE_NONE = 0, + AET_BLEND_MODE_COPY, + AET_BLEND_MODE_BEHIND, + AET_BLEND_MODE_NORMAL, + AET_BLEND_MODE_DISSOLVE, + AET_BLEND_MODE_ADD, + AET_BLEND_MODE_MULTIPLY, + AET_BLEND_MODE_SCREEN, + AET_BLEND_MODE_OVERLAY, + AET_BLEND_MODE_SOFT_LIGHT, + AET_BLEND_MODE_HARD_LIGHT, + AET_BLEND_MODE_DARKEN, + AET_BLEND_MODE_LIGHTEN, + AET_BLEND_MODE_CLASSIC_DIFFERENCE, + AET_BLEND_MODE_HUE, + AET_BLEND_MODE_SATURATION, + AET_BLEND_MODE_COLOR, + AET_BLEND_MODE_LUMINOSITY, + AET_BLEND_MODE_STENCIL_ALPHA, + AET_BLEND_MODE_STENCIL_LUMA, + AET_BLEND_MODE_SILHOUETTE_ALPHA, + AET_BLEND_MODE_SILHOUETTE_LUMA, + AET_BLEND_MODE_LUMINESCENT_PREMUL, + AET_BLEND_MODE_ALPHA_ADD, + AET_BLEND_MODE_CLASSIC_COLOR_DODGE, + AET_BLEND_MODE_CLASSIC_COLOR_BURN, + AET_BLEND_MODE_EXCLUSION, + AET_BLEND_MODE_DIFFERENCE, + AET_BLEND_MODE_COLOR_DODGE, + AET_BLEND_MODE_COLOR_BURN, + AET_BLEND_MODE_LINEAR_DODGE, + AET_BLEND_MODE_LINEAR_BURN, + AET_BLEND_MODE_LINEAR_LIGHT, + AET_BLEND_MODE_VIVID_LIGHT, + AET_BLEND_MODE_PIN_LIGHT, + AET_BLEND_MODE_HARD_MIX, + AET_BLEND_MODE_LIGHTER_COLOR, + AET_BLEND_MODE_DARKER_COLOR, + AET_BLEND_MODE_SUBTRACT, + AET_BLEND_MODE_DIVIDE, }; enum aet_layer_quality : uint8_t { - AET_LAYER_QUALITY_NONE = 0, - AET_LAYER_QUALITY_WIREFRAME = 1, - AET_LAYER_QUALITY_DRAFT = 2, - AET_LAYER_QUALITY_BEST = 3, + AET_LAYER_QUALITY_NONE = 0, + AET_LAYER_QUALITY_WIREFRAME, + AET_LAYER_QUALITY_DRAFT, + AET_LAYER_QUALITY_BEST, }; -enum aet_track_matte : uint8_t { - AET_TRACK_MATTE_NONE = 0, - AET_TRACK_MATTE_ALPHA = 1, - AET_TRACK_MATTE_NOT_ALPHA = 2, - AET_TRACK_MATTE_LUMA = 3, - AET_TRACK_MATTE_NOT_LUMA = 4, +enum aet_item_type : uint8_t { + AET_ITEM_TYPE_NONE = 0, + AET_ITEM_TYPE_VIDEO, + AET_ITEM_TYPE_AUDIO, + AET_ITEM_TYPE_COMPOSITION, }; -enum aet_transfer_flags : uint8_t { - AET_TRANSFRER_FLAGS_PRESERVE_ALPHA = 0x01, - AET_TRANSFRER_FLAGS_RANDOMIZE_DISSOLVE = 0x02, +struct aet_layer_flag { + uint16_t video_active : 1; + uint16_t audio_active : 1; + uint16_t effects_active : 1; + uint16_t motion_blur : 1; + uint16_t frame_blending : 1; + uint16_t locked : 1; + uint16_t shy : 1; + uint16_t collapse : 1; + uint16_t auto_orient_rotation : 1; + uint16_t adjustment_layer : 1; + uint16_t time_remapping : 1; + uint16_t layer_is_3d : 1; + uint16_t look_at_camera : 1; + uint16_t look_at_point_of_interest : 1; + uint16_t solo : 1; + uint16_t markers_locked : 1; + // Should be there but they don't fit in 16 bits + //uint16_t null_layer : 1; + //uint16_t hide_locked_masks : 1; + //uint16_t guide_layer : 1; + //uint16_t advanced_frame_blending : 1; + //uint16_t sub_layers_render_separately : 1; + //uint16_t environment_layer : 1; }; -struct aet_marker { - float_t time; - std::string name; +struct aet_fcurve { + uint32_t keys_count; + const float_t* keys; - aet_marker(); - ~aet_marker(); + aet_fcurve(); + + float_t interpolate(float_t frame) const; }; -typedef std::vector aet_fcurve; - struct aet_layer_video_3d { aet_fcurve anchor_z; aet_fcurve pos_z; @@ -129,13 +114,12 @@ struct aet_layer_video_3d { aet_fcurve scale_z; aet_layer_video_3d(); - ~aet_layer_video_3d(); }; struct aet_transfer_mode { aet_blend_mode mode; - aet_transfer_flags flag; - aet_track_matte matte; + uint8_t flag; + uint8_t matte; aet_transfer_mode(); }; @@ -150,11 +134,9 @@ struct aet_layer_video { aet_fcurve scale_x; aet_fcurve scale_y; aet_fcurve opacity; - aet_layer_video_3d _3d; - bool _3d_init; + const aet_layer_video_3d* _3d; aet_layer_video(); - ~aet_layer_video(); }; struct aet_layer_audio { @@ -164,65 +146,8 @@ struct aet_layer_audio { aet_fcurve pan_r; aet_layer_audio(); - ~aet_layer_audio(); }; -struct aet_color { - uint8_t r; - uint8_t g; - uint8_t b; - - aet_color(); -}; - -struct aet_video_src { - std::string sprite_name; - int32_t sprite_index; - - aet_video_src(); - ~aet_video_src(); -}; - -struct aet_video { - aet_color color; - uint16_t width; - uint16_t height; - float_t fpf; - std::vector sources; - - aet_video(); - ~aet_video(); -}; - -struct aet_audio { - uint32_t sound_index; - - aet_audio(); -}; - -struct aet_layer { - std::string name; - float_t start_time; - float_t end_time; - float_t offset_time; - float_t time_scale; - aet_layer_flags flags; - aet_layer_quality quality; - aet_item_type item_type; - void* item; - aet_layer* parent; - std::vector markers; - aet_layer_video video; - bool video_init; - aet_layer_audio audio; - bool audio_init; - - aet_layer(); - ~aet_layer(); -}; - -typedef std::vector aet_comp; - struct aet_camera { aet_fcurve eye_x; aet_fcurve eye_y; @@ -239,25 +164,112 @@ struct aet_camera { aet_fcurve zoom; aet_camera(); - ~aet_camera(); +}; + +struct aet_video_src { + const char* sprite_name; + int32_t sprite_index; + + aet_video_src(); +}; + +struct aet_video { + uint8_t color[3]; + uint16_t width; + uint16_t height; + float_t fpf; + uint32_t sources_count; + const aet_video_src* sources; + + aet_video(); +}; + +struct aet_audio { + uint32_t sound_index; + + aet_audio(); +}; + +struct aet_comp; + +union aet_item { + const void* none; + const aet_video* video; + const aet_audio* audio; + const aet_comp* comp; + + inline aet_item() : none() { + + } + + inline aet_item(aet_video* video) { + this->video = video; + } + + inline aet_item(aet_audio* audio) { + this->audio = audio; + } + + inline aet_item(aet_comp* comp) { + this->comp = comp; + } +}; + +struct aet_marker { + float_t time; + const char* name; + + aet_marker(); +}; + +#pragma warning(push) +#pragma warning(disable: 26495) +struct aet_layer { + const char* name; + float_t start_time; + float_t end_time; + float_t offset_time; + float_t time_scale; + aet_layer_flag flags; + aet_layer_quality quality; + aet_item_type item_type; + aet_item item; + const aet_layer* parent; + uint32_t markers_count; + const aet_marker* markers; + const aet_layer_video* video; + const aet_layer_audio* audio; + + aet_layer(); +}; +#pragma warning(pop) + +struct aet_comp { + uint32_t layers_count; + const aet_layer* layers; + + aet_comp(); }; struct aet_scene { - std::string name; + const char* name; float_t start_time; float_t end_time; float_t fps; - aet_color color; + uint8_t color[3]; uint32_t width; uint32_t height; - aet_camera camera; - bool camera_init; - std::vector comp; - std::vector video; - std::vector audio; + const aet_camera* camera; + uint32_t comp_count; + const aet_comp* comp; + uint32_t video_count; + const aet_video* video; + uint32_t audio_count; + const aet_audio* audio; aet_scene(); - ~aet_scene(); + + static const aet_comp* get_root_comp(const aet_scene* scene); }; struct aet_set { @@ -266,11 +278,12 @@ struct aet_set { bool big_endian; bool is_x; - std::vector scenes; + uint32_t scenes_count; + const aet_scene** scenes; aet_set(); - ~aet_set(); + void move_data(aet_set* set_src, prj::shared_ptr alloc); void pack_file(void** data, size_t* size); - void unpack_file(const void* data, size_t size, bool modern); + void unpack_file(prj::shared_ptr alloc, const void* data, size_t size, bool modern); }; diff --git a/src/KKdLib/database/aet.cpp b/src/KKdLib/database/aet.cpp index 82590816..0bffa7d1 100644 --- a/src/KKdLib/database/aet.cpp +++ b/src/KKdLib/database/aet.cpp @@ -23,15 +23,17 @@ static bool aet_database_file_strings_push_back_check(std::vector& const aet_db_aet_set aet_db_aet_set_null; const aet_db_aet aet_db_aet_null; -aet_db_aet_file::aet_db_aet_file() : id(), index() { - +aet_db_aet_file::aet_db_aet_file() { + id = -1; + index = -1; } aet_db_aet_file::~aet_db_aet_file() { } -aet_db_aet::aet_db_aet() : id() { +aet_db_aet::aet_db_aet() : load_count() { + id = -1; name_hash = hash_murmurhash_empty; } @@ -39,17 +41,22 @@ aet_db_aet::~aet_db_aet() { } -aet_db_aet_set_file::aet_db_aet_set_file() : id(), index(), sprite_set_id() { - +aet_db_aet_set_file::aet_db_aet_set_file() { + id = -1; + index = -1; + sprite_set_id = -1; } aet_db_aet_set_file::~aet_db_aet_set_file() { } -aet_db_aet_set::aet_db_aet_set() : id(), index(), sprite_set_id() { +aet_db_aet_set::aet_db_aet_set() { + id = -1; name_hash = hash_murmurhash_empty; file_name_hash = hash_murmurhash_empty; + index = -1; + sprite_set_id = -1; } aet_db_aet_set::~aet_db_aet_set() { @@ -85,18 +92,18 @@ void aet_database_file::read(const char* path, bool modern) { free_def(path_bin); } else { - char* path_spi = str_utils_add(path, ".aei"); - if (path_check_file_exists(path_spi)) { + char* path_aei = str_utils_add(path, ".aei"); + if (path_check_file_exists(path_aei)) { f2_struct st; - st.read(path_spi); + st.read(path_aei); if (st.header.signature == reverse_endianness_uint32_t('AEDB')) { - memory_stream s_spdb; - s_spdb.open(st.data); - s_spdb.big_endian = st.header.use_big_endian; - aet_database_file_modern_read_inner(this, s_spdb, st.header.length); + memory_stream s_aedb; + s_aedb.open(st.data); + s_aedb.big_endian = st.header.use_big_endian; + aet_database_file_modern_read_inner(this, s_aedb, st.header.length); } } - free_def(path_spi); + free_def(path_aei); } } @@ -121,18 +128,18 @@ void aet_database_file::read(const wchar_t* path, bool modern) { free_def(path_bin); } else { - wchar_t* path_spi = str_utils_add(path, L".aei"); - if (path_check_file_exists(path_spi)) { + wchar_t* path_aei = str_utils_add(path, L".aei"); + if (path_check_file_exists(path_aei)) { f2_struct st; - st.read(path_spi); + st.read(path_aei); if (st.header.signature == reverse_endianness_uint32_t('AEDB')) { - memory_stream s_spdb; - s_spdb.open(st.data); - s_spdb.big_endian = st.header.use_big_endian; - aet_database_file_modern_read_inner(this, s_spdb, st.header.length); + memory_stream s_aedb; + s_aedb.open(st.data); + s_aedb.big_endian = st.header.use_big_endian; + aet_database_file_modern_read_inner(this, s_aedb, st.header.length); } } - free_def(path_spi); + free_def(path_aei); } } @@ -148,11 +155,11 @@ void aet_database_file::read(const void* data, size_t size, bool modern) { else { f2_struct st; st.read(data, size); - if (st.header.signature == reverse_endianness_uint32_t('SPDB')) { - memory_stream s_spdb; - s_spdb.open(st.data); - s_spdb.big_endian = st.header.use_big_endian; - aet_database_file_modern_read_inner(this, s_spdb, st.header.length); + if (st.header.signature == reverse_endianness_uint32_t('AEDB')) { + memory_stream s_aedb; + s_aedb.open(st.data); + s_aedb.big_endian = st.header.use_big_endian; + aet_database_file_modern_read_inner(this, s_aedb, st.header.length); } } } @@ -170,12 +177,12 @@ void aet_database_file::write(const char* path) { free_def(path_bin); } else { - char* path_spi = str_utils_add(path, ".spi"); + char* path_aei = str_utils_add(path, ".aei"); file_stream s; - s.open(path_spi, "wb"); + s.open(path_aei, "wb"); if (s.check_not_null()) aet_database_file_modern_write_inner(this, s); - free_def(path_spi); + free_def(path_aei); } } @@ -192,12 +199,12 @@ void aet_database_file::write(const wchar_t* path) { free_def(path_bin); } else { - wchar_t* path_spi = str_utils_add(path, L".spi"); + wchar_t* path_aei = str_utils_add(path, L".aei"); file_stream s; - s.open(path_spi, L"wb"); + s.open(path_aei, L"wb"); if (s.check_not_null()) aet_database_file_modern_write_inner(this, s); - free_def(path_spi); + free_def(path_aei); } } @@ -251,33 +258,36 @@ void aet_database::add(aet_database_file* aet_db_file) { aet_set_names.reserve(aet_db_file->aet_set.size()); for (aet_db_aet_set_file& i : aet_db_file->aet_set) { - aet_db_aet_set aet_set; + aet_sets.push_back({}); + aet_db_aet_set& aet_set = aet_sets.back(); aet_set.id = i.id; aet_set.name.assign(i.name); aet_set.name_hash = hash_string_murmurhash(aet_set.name); aet_set.file_name.assign(i.file_name); aet_set.file_name_hash = hash_string_murmurhash(aet_set.file_name); - aet_set.index = (uint16_t)(aet_sets_count + i.index); + aet_set.index = (uint32_t)(aet_sets_count + i.index); aet_set.sprite_set_id = i.sprite_set_id; - aet_set_ids.push_back({ aet_set.id, aet_set }); - aet_set_indices.push_back({ aet_set.index, aet_set }); - aet_set_names.push_back({ aet_set.name, aet_set }); + aet_set_ids.push_back({ aet_set.id, &aet_set }); + aet_set_indices.push_back({ aet_set.index, &aet_set }); + aet_set_names.push_back({ aet_set.name, &aet_set }); aet_ids.reserve(i.aet.size()); aet_names.reserve(i.aet.size()); aet_indices.reserve(i.aet.size()); for (aet_db_aet_file& j : i.aet) { - aet_db_aet aet; + aets.push_back({}); + aet_db_aet& aet = aets.back(); aet.id = j.id; aet.name.assign(j.name); aet.name_hash = hash_string_murmurhash(aet.name); - aet.info = { j.index, aet_set.index }; + aet.info = { j.index, (uint16_t)aet_set.index }; + aet.load_count = 1; - aet_ids.push_back({ aet.id, aet }); - aet_names.push_back({ aet.name, aet }); - aet_indices.push_back({ aet.info, aet }); + aet_ids.push_back({ aet.id, &aet }); + aet_names.push_back({ aet.name, &aet }); + aet_indices.push_back({ aet.info, &aet }); } } @@ -289,52 +299,178 @@ void aet_database::add(aet_database_file* aet_db_file) { aet_indices.combine(); } +void aet_database::clear() { + aet_sets.clear(); + aet_set_ids.clear(); + aet_set_indices.clear(); + aet_set_names.clear(); + aets.clear(); + aet_ids.clear(); + aet_names.clear(); + aet_indices.clear(); +} + +void aet_database::add_aet_set(uint32_t set_id, uint32_t index) { + if (set_id == -1 || set_id == hash_murmurhash_empty) + return; + + aet_sets.push_back({}); + aet_db_aet_set& set = aet_sets.back(); + set.id = set_id; + set.index = index; + + aet_set_indices.push_back({ set.index, &set }); + aet_set_ids.push_back({ set.id, &set }); + + aet_set_indices.combine(); + aet_set_ids.combine(); +} + +void aet_database::parse(const aet_db_aet_set_file* set_file, + std::string& set_name, std::vector& aet_ids) { + if (!set_file) + return; + + auto elem = aet_set_ids.find(set_file->id); + if (elem == aet_set_ids.end()) + return; + + uint16_t set_index = (uint16_t)elem->second->index; + + aet_set_names.push_back({ set_file->name, elem->second }); + + aet_ids.reserve(set_file->aet.size()); + for (const aet_db_aet_file& i : set_file->aet) { + uint32_t id = i.id; + aet_ids.push_back(id); + + auto j_begin = aets.begin(); + auto j_end = aets.end(); + auto j = j_begin; + while (j != j_end) + if (j->id == id) + break; + + aet_db_aet* aet; + if (j == j_end) { + aets.push_back({}); + aet = &aets.back(); + } + else + aet = &*j; + + aet->id = id; + aet->name.assign(i.name); + aet->name_hash = hash_string_murmurhash(aet->name); + aet->info = { i.index, set_index }; + aet->load_count++; + + this->aet_ids.push_back({ aet->id, aet }); + aet_names.push_back({ aet->name, aet }); + aet_indices.push_back({ aet->info, aet }); + } + + aet_set_names.combine(); + this->aet_ids.combine(); + aet_names.combine(); + aet_indices.combine(); +} + +void aet_database::remove_aet_set(uint32_t set_id, uint32_t index, + const char* set_name, std::vector& aet_ids) { + if (set_name && *set_name) { + auto elem = aet_set_names.find(set_name); + if (elem != aet_set_names.end()) + aet_set_names.erase(elem); + } + + if (index != -1) { + auto elem = aet_set_indices.find(index); + if (elem != aet_set_indices.end()) + aet_set_indices.erase(elem); + } + + if (set_id != -1 && set_id != hash_murmurhash_empty) { + auto elem = aet_set_ids.find(set_id); + if (elem != aet_set_ids.end()) + aet_set_ids.erase(elem); + + auto i_begin = aet_sets.begin(); + auto i_end = aet_sets.end(); + auto i = i_begin; + while (i != i_end) + if (i->id == set_id) + i = aet_sets.erase(i); + else + i++; + } + + for (auto& i : aet_ids) { + auto j_begin = aets.begin(); + auto j_end = aets.end(); + auto j = j_begin; + while (j != j_end) { + if (j->id != i || --j->load_count > 0) { + j++; + continue; + } + + auto elem_id = this->aet_ids.find(j->id); + if (elem_id != this->aet_ids.end()) + this->aet_ids.erase(elem_id); + + auto elem_index = aet_indices.find(j->info); + if (elem_index != aet_indices.end()) + aet_indices.erase(elem_index); + + auto elem_name = aet_names.find(j->name); + if (elem_name != aet_names.end()) + aet_names.erase(elem_name); + + j = aets.erase(j); + } + } +} + const aet_db_aet_set* aet_database::get_aet_set_by_name(const char* name) const { auto elem = aet_set_names.find(std::string(name)); if (elem != aet_set_names.end()) - return &elem->second; + return elem->second; return &aet_db_aet_set_null; } const aet_db_aet_set* aet_database::get_aet_set_by_id(uint32_t set_id) const { auto elem = aet_set_ids.find(set_id); if (elem != aet_set_ids.end()) - return &elem->second; + return elem->second; return &aet_db_aet_set_null; } const aet_db_aet_set* aet_database::get_aet_set_by_index(uint32_t index) const { auto elem = aet_set_indices.find(index); if (elem != aet_set_indices.end()) - return &elem->second; + return elem->second; return &aet_db_aet_set_null; } const aet_db_aet* aet_database::get_aet_by_name(const char* name) const { auto elem = aet_names.find(std::string(name)); if (elem != aet_names.end()) - return &elem->second; + return elem->second; return &aet_db_aet_null; } const aet_db_aet* aet_database::get_aet_by_id(uint32_t id) const { auto elem = aet_ids.find(id); if (elem != aet_ids.end()) - return &elem->second; + return elem->second; return &aet_db_aet_null; } const aet_db_aet* aet_database::get_aet_by_set_id_index(uint32_t set_id, uint32_t index) const { - auto elem = aet_indices.find({ (uint16_t)index, get_aet_set_by_id(set_id)->index }); + auto elem = aet_indices.find({ (uint16_t)index, (uint16_t)get_aet_set_by_id(set_id)->index }); if (elem != aet_indices.end()) - return &elem->second; - return &aet_db_aet_null; -} - -const aet_db_aet* aet_database::get_tex_by_set_id_index(uint32_t set_id, uint32_t index) const { - auto elem = aet_indices.find({ (uint16_t)index, (uint16_t)(0x1000 | get_aet_set_by_id(set_id)->index) }); - if (elem != aet_indices.end()) - return &elem->second; + return elem->second; return &aet_db_aet_null; } @@ -347,7 +483,7 @@ uint32_t aet_database::get_aet_set_id_by_name(const char* name) const { } uint32_t aet_database::get_aet_set_id_by_name_index(uint32_t index) const { - return aet_set_names[index].second.id; + return aet_set_names[index].second->id; } const char* aet_database::get_aet_set_name(uint32_t set_id) const { @@ -370,7 +506,7 @@ static void aet_database_file_classic_read_inner(aet_database_file* aet_db, stre aet_set.id = s.read_uint32_t(); aet_set.name = s.read_string_null_terminated_offset(s.read_uint32_t()); aet_set.file_name = s.read_string_null_terminated_offset(s.read_uint32_t()); - aet_set.index = (uint16_t)s.read_uint32_t(); + aet_set.index = s.read_uint32_t(); aet_set.sprite_set_id = s.read_uint32_t(); } s.position_pop(); @@ -453,7 +589,7 @@ static void aet_database_file_classic_write_inner(aet_database_file* aet_db, str s.position_push(aets_offset, SEEK_SET); for (aet_db_aet_set_file& i : aet_db->aet_set) { - uint16_t aet_set_index = i.index; + uint16_t aet_set_index = (uint16_t)i.index; for (aet_db_aet_file& j : i.aet) { s.write_uint32_t(j.id); @@ -509,7 +645,7 @@ static void aet_database_file_modern_read_inner(aet_database_file* aet_db, strea aet_set.id = s.read_uint32_t_reverse_endianness(); aet_set.name = s.read_string_null_terminated_offset(s.read_offset_f2(header_length)); aet_set.file_name = s.read_string_null_terminated_offset(s.read_offset_f2(header_length)); - aet_set.index = (uint16_t)s.read_uint32_t_reverse_endianness(); + aet_set.index = s.read_uint32_t_reverse_endianness(); aet_set.sprite_set_id = s.read_uint32_t_reverse_endianness(); } else @@ -518,7 +654,7 @@ static void aet_database_file_modern_read_inner(aet_database_file* aet_db, strea aet_set.id = s.read_uint32_t_reverse_endianness(); aet_set.name = s.read_string_null_terminated_offset(s.read_offset_x()); aet_set.file_name = s.read_string_null_terminated_offset(s.read_offset_x()); - aet_set.index = (uint16_t)s.read_uint32_t_reverse_endianness(); + aet_set.index = s.read_uint32_t_reverse_endianness(); aet_set.sprite_set_id = s.read_uint32_t_reverse_endianness(); s.align_read(0x08); } @@ -572,9 +708,9 @@ static void aet_database_file_modern_write_inner(aet_database_file* aet_db, stre bool big_endian = aet_db->big_endian; bool is_x = aet_db->is_x; - memory_stream s_spdb; - s_spdb.open(); - s_spdb.big_endian = big_endian; + memory_stream s_aedb; + s_aedb.open(); + s_aedb.big_endian = big_endian; uint32_t off; enrs e; @@ -633,16 +769,16 @@ static void aet_database_file_modern_write_inner(aet_database_file* aet_db, stre off = align_val(off, 0x10); } - s_spdb.write(is_x ? 0x20 : 0x10); - s_spdb.align_write(0x10); + s_aedb.write(is_x ? 0x20 : 0x10); + s_aedb.align_write(0x10); - int64_t aet_sets_offset = s_spdb.get_position(); - s_spdb.write(aet_sets_count * (is_x ? 0x20ULL : 0x10ULL)); - s_spdb.align_write(0x10); + int64_t aet_sets_offset = s_aedb.get_position(); + s_aedb.write(aet_sets_count * (is_x ? 0x20ULL : 0x10ULL)); + s_aedb.align_write(0x10); - int64_t aets_offset = s_spdb.get_position(); - s_spdb.write(aets_count * (is_x ? 0x18ULL : 0x0CULL)); - s_spdb.align_write(0x10); + int64_t aets_offset = s_aedb.get_position(); + s_aedb.write(aets_count * (is_x ? 0x18ULL : 0x0CULL)); + s_aedb.align_write(0x10); std::vector strings; std::vector string_offsets; @@ -651,85 +787,85 @@ static void aet_database_file_modern_write_inner(aet_database_file* aet_db, stre for (aet_db_aet_set_file& i : aet_db->aet_set) { if (aet_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); + string_offsets.push_back(s_aedb.get_position()); + s_aedb.write_string_null_terminated(i.name); } if (aet_database_file_strings_push_back_check(strings, i.file_name)) { - string_offsets.push_back(s_spdb.get_position()); - s_spdb.write_string_null_terminated(i.file_name); + string_offsets.push_back(s_aedb.get_position()); + s_aedb.write_string_null_terminated(i.file_name); } } for (aet_db_aet_set_file& i : aet_db->aet_set) for (aet_db_aet_file& j : i.aet) if (aet_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); + string_offsets.push_back(s_aedb.get_position()); + s_aedb.write_string_null_terminated(j.name); } - s_spdb.align_write(0x10); + s_aedb.align_write(0x10); - s_spdb.position_push(0x00, SEEK_SET); - s_spdb.write_uint32_t_reverse_endianness((uint32_t)aet_sets_count); - io_write_offset_pof_add(s_spdb, aet_sets_offset, 0x20, is_x, &pof); - s_spdb.write_uint32_t_reverse_endianness((uint32_t)aets_count); - io_write_offset_pof_add(s_spdb, aets_offset, 0x20, is_x, &pof); - s_spdb.position_pop(); + s_aedb.position_push(0x00, SEEK_SET); + s_aedb.write_uint32_t_reverse_endianness((uint32_t)aet_sets_count); + io_write_offset_pof_add(s_aedb, aet_sets_offset, 0x20, is_x, &pof); + s_aedb.write_uint32_t_reverse_endianness((uint32_t)aets_count); + io_write_offset_pof_add(s_aedb, aets_offset, 0x20, is_x, &pof); + s_aedb.position_pop(); - s_spdb.position_push(aet_sets_offset, SEEK_SET); + s_aedb.position_push(aet_sets_offset, SEEK_SET); if (!is_x) for (aet_db_aet_set_file& i : aet_db->aet_set) { - s_spdb.write_uint32_t_reverse_endianness(i.id); - io_write_offset_f2_pof_add(s_spdb, aet_database_file_strings_get_string_offset(strings, + s_aedb.write_uint32_t_reverse_endianness(i.id); + io_write_offset_f2_pof_add(s_aedb, aet_database_file_strings_get_string_offset(strings, string_offsets, i.name), 0x20, &pof); - io_write_offset_f2_pof_add(s_spdb, aet_database_file_strings_get_string_offset(strings, + io_write_offset_f2_pof_add(s_aedb, aet_database_file_strings_get_string_offset(strings, string_offsets, i.file_name), 0x20, &pof); - s_spdb.write_uint32_t_reverse_endianness(i.index); - s_spdb.write_uint32_t_reverse_endianness(i.sprite_set_id); + s_aedb.write_uint32_t_reverse_endianness(i.index); + s_aedb.write_uint32_t_reverse_endianness(i.sprite_set_id); } else for (aet_db_aet_set_file& i : aet_db->aet_set) { - s_spdb.write_uint32_t_reverse_endianness(i.id); - io_write_offset_x_pof_add(s_spdb, aet_database_file_strings_get_string_offset(strings, + s_aedb.write_uint32_t_reverse_endianness(i.id); + io_write_offset_x_pof_add(s_aedb, aet_database_file_strings_get_string_offset(strings, string_offsets, i.name), &pof); - io_write_offset_x_pof_add(s_spdb, aet_database_file_strings_get_string_offset(strings, + io_write_offset_x_pof_add(s_aedb, aet_database_file_strings_get_string_offset(strings, string_offsets, i.file_name), &pof); - s_spdb.write_uint32_t_reverse_endianness(i.index); - s_spdb.write_uint32_t_reverse_endianness(i.sprite_set_id); + s_aedb.write_uint32_t_reverse_endianness(i.index); + s_aedb.write_uint32_t_reverse_endianness(i.sprite_set_id); } - s_spdb.position_pop(); + s_aedb.position_pop(); - s_spdb.position_push(aets_offset, SEEK_SET); + s_aedb.position_push(aets_offset, SEEK_SET); for (aet_db_aet_set_file& i : aet_db->aet_set) { - uint16_t aet_set_index = i.index; + uint16_t aet_set_index = (uint16_t)i.index; if (!is_x) for (aet_db_aet_file& j : i.aet) { - s_spdb.write_uint32_t_reverse_endianness(j.id); - io_write_offset_f2_pof_add(s_spdb, aet_database_file_strings_get_string_offset(strings, + s_aedb.write_uint32_t_reverse_endianness(j.id); + io_write_offset_f2_pof_add(s_aedb, aet_database_file_strings_get_string_offset(strings, string_offsets, j.name), 0x20, &pof); - s_spdb.write_uint32_t_reverse_endianness((aet_set_index << 16) | j.index); + s_aedb.write_uint32_t_reverse_endianness((aet_set_index << 16) | j.index); } else for (aet_db_aet_file& j : i.aet) { - s_spdb.write_uint32_t_reverse_endianness(j.id); - io_write_offset_x_pof_add(s_spdb, aet_database_file_strings_get_string_offset(strings, + s_aedb.write_uint32_t_reverse_endianness(j.id); + io_write_offset_x_pof_add(s_aedb, aet_database_file_strings_get_string_offset(strings, string_offsets, j.name), &pof); - s_spdb.write_uint32_t_reverse_endianness((aet_set_index << 16) | j.index); - s_spdb.align_write(0x08); + s_aedb.write_uint32_t_reverse_endianness((aet_set_index << 16) | j.index); + s_aedb.align_write(0x08); } } - s_spdb.position_pop(); + s_aedb.position_pop(); f2_struct st; - s_spdb.align_write(0x10); - s_spdb.copy(st.data); - s_spdb.close(); + s_aedb.align_write(0x10); + s_aedb.copy(st.data); + s_aedb.close(); st.enrs = e; st.pof = pof; - st.header.signature = reverse_endianness_uint32_t('SPDB'); + st.header.signature = reverse_endianness_uint32_t('AEDB'); st.header.length = 0x20; st.header.use_big_endian = big_endian; st.header.use_section_size = true; diff --git a/src/KKdLib/database/aet.hpp b/src/KKdLib/database/aet.hpp index b0157863..0289abbe 100644 --- a/src/KKdLib/database/aet.hpp +++ b/src/KKdLib/database/aet.hpp @@ -5,11 +5,11 @@ #pragma once +#include #include #include #include "../default.hpp" #include "../prj/vector_pair_combine.hpp" -#include "../hash.hpp" struct aet_info { uint16_t index; @@ -72,6 +72,7 @@ struct aet_db_aet { std::string name; uint32_t name_hash; aet_info info; + int32_t load_count; aet_db_aet(); ~aet_db_aet(); @@ -82,7 +83,7 @@ struct aet_db_aet_set_file { std::string name; std::string file_name; std::vector aet; - uint16_t index; + uint32_t index; uint32_t sprite_set_id; aet_db_aet_set_file(); @@ -95,7 +96,7 @@ struct aet_db_aet_set { uint32_t name_hash; std::string file_name; uint32_t file_name_hash; - uint16_t index; + uint32_t index; uint32_t sprite_set_id; aet_db_aet_set(); @@ -124,17 +125,26 @@ struct aet_database_file { }; struct aet_database { - prj::vector_pair_combine aet_set_ids; - prj::vector_pair_combine aet_set_indices; - prj::vector_pair_combine aet_set_names; - prj::vector_pair_combine aet_ids; - prj::vector_pair_combine aet_names; - prj::vector_pair_combine aet_indices; + std::list aet_sets; + prj::vector_pair_combine aet_set_ids; + prj::vector_pair_combine aet_set_indices; + prj::vector_pair_combine aet_set_names; + std::list aets; + prj::vector_pair_combine aet_ids; + prj::vector_pair_combine aet_names; + prj::vector_pair_combine aet_indices; aet_database(); ~aet_database(); void add(aet_database_file* aet_db_file); + void clear(); + + void add_aet_set(uint32_t set_id, uint32_t index); + void parse(const aet_db_aet_set_file* set_file, + std::string& set_name, std::vector& aet_ids); + void remove_aet_set(uint32_t set_id, uint32_t index, + const char* set_name, std::vector& aet_ids); const aet_db_aet_set* get_aet_set_by_name(const char* name) const; const aet_db_aet_set* get_aet_set_by_id(uint32_t set_id) const; @@ -142,7 +152,6 @@ struct aet_database { const aet_db_aet* get_aet_by_name(const char* name) const; const aet_db_aet* get_aet_by_id(uint32_t id) const; const aet_db_aet* get_aet_by_set_id_index(uint32_t set_id, uint32_t index) const; - const aet_db_aet* get_tex_by_set_id_index(uint32_t set_id, uint32_t index) const; const char* get_aet_set_file_name(uint32_t set_id) const; uint32_t get_aet_set_id_by_name(const char* name) const; uint32_t get_aet_set_id_by_name_index(uint32_t index) const; diff --git a/src/KKdLib/database/object.cpp b/src/KKdLib/database/object.cpp index 13177b84..16f97b2c 100644 --- a/src/KKdLib/database/object.cpp +++ b/src/KKdLib/database/object.cpp @@ -241,7 +241,7 @@ void object_database::add(object_database_file* obj_db_file) { if (!obj_db_file || !obj_db_file->ready) return; - object_set.reserve(obj_db_file->object_set.size()); + object_set.reserve(obj_db_file->object_set.size());; for (object_set_info_file& i : obj_db_file->object_set) { uint32_t name_hash = hash_string_murmurhash(i.name); @@ -278,60 +278,116 @@ void object_database::add(object_database_file* obj_db_file) { info.name_hash_murmurhash = hash_string_murmurhash(info.name); } } + + update(); +} + +void object_database::clear() { + object_set.clear(); + object_set.shrink_to_fit(); + obj_set_ids.clear(); + obj_set_ids.shrink_to_fit(); + obj_set_murmurhashes.clear(); + obj_set_murmurhashes.shrink_to_fit(); + obj_infos.clear(); + obj_infos.shrink_to_fit(); + obj_fnv1a64m_hashes.clear(); + obj_fnv1a64m_hashes.shrink_to_fit(); + obj_fnv1a64m_hashes_upper.clear(); + obj_fnv1a64m_hashes_upper.shrink_to_fit(); + obj_murmurhashes.clear(); + obj_murmurhashes.shrink_to_fit(); + obj_info_murmurhashes.clear(); + obj_info_murmurhashes.shrink_to_fit(); +} + +void object_database::update() { + obj_set_ids.clear(); + obj_set_murmurhashes.clear(); + obj_infos.clear(); + obj_fnv1a64m_hashes.clear(); + obj_fnv1a64m_hashes_upper.clear(); + obj_murmurhashes.clear(); + obj_info_murmurhashes.clear(); + + obj_set_ids.reserve(object_set.size()); + obj_set_murmurhashes.reserve(object_set.size()); + + for (object_set_info& i : object_set) { + obj_set_ids.push_back({ i.id, &i }); + obj_set_murmurhashes.push_back({ i.name_hash, &i }); + + obj_infos.reserve(i.object.size()); + obj_fnv1a64m_hashes.reserve(i.object.size()); + obj_fnv1a64m_hashes_upper.reserve(i.object.size()); + obj_murmurhashes.reserve(i.object.size()); + obj_info_murmurhashes.reserve(i.object.size()); + + for (object_info_data& j : i.object) { + obj_infos.push_back({ { j.id, i.id }, &j }); + obj_fnv1a64m_hashes.push_back({ j.name_hash_fnv1a64m, &j }); + obj_fnv1a64m_hashes_upper.push_back({ j.name_hash_fnv1a64m_upper, &j }); + obj_murmurhashes.push_back({ j.name_hash_murmurhash, &j }); + obj_info_murmurhashes.push_back({ j.name_hash_murmurhash, { j.id, i.id } }); + } + } + + obj_set_ids.sort_unique(); + obj_set_murmurhashes.sort_unique(); + obj_infos.sort_unique(); + obj_fnv1a64m_hashes.sort_unique(); + obj_fnv1a64m_hashes_upper.sort_unique(); + obj_murmurhashes.sort_unique(); + obj_info_murmurhashes.sort_unique(); } const object_set_info* object_database::get_object_set_info(const char* name) const { - if (!name) + if (!name || !*name) return 0; - uint32_t name_hash = hash_utf8_murmurhash(name); - for (const object_set_info& i : object_set) - if (name_hash == i.name_hash) - return &i; + auto elem = obj_set_murmurhashes.find(hash_utf8_murmurhash(name)); + if (elem != obj_set_murmurhashes.end()) + return elem->second; return 0; } const object_set_info* object_database::get_object_set_info(uint32_t set_id) const { - if (set_id == -1) + if (set_id == -1 || set_id == hash_murmurhash_empty || set_id == hash_murmurhash_null) return 0; - for (const object_set_info& i : object_set) - if (set_id == i.id) - return &i; + auto elem = obj_set_ids.find(set_id); + if (elem != obj_set_ids.end()) + return elem->second; return 0; } const object_info_data* object_database::get_object_info_data(const char* name) const { - if (!name) + if (!name || !*name) 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) - return &j; + auto elem = obj_murmurhashes.find(hash_utf8_murmurhash(name)); + if (elem != obj_murmurhashes.end()) + return elem->second; return 0; } const object_info_data* object_database::get_object_info_data_by_fnv1a64m_hash(uint64_t hash) const { - if (hash == hash_fnv1a64m_empty) + if (hash == -1 || hash == hash_fnv1a64m_empty) return 0; - for (const object_set_info& i : object_set) - for (const object_info_data& j : i.object) - if (hash == j.name_hash_fnv1a64m) - return &j; + auto elem = obj_fnv1a64m_hashes.find(hash); + if (elem != obj_fnv1a64m_hashes.end()) + return elem->second; return 0; } const object_info_data* object_database::get_object_info_data_by_fnv1a64m_hash_upper(uint64_t hash) const { - if (hash == hash_fnv1a64m_empty) + if (hash == -1 || hash == hash_fnv1a64m_empty) 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) - return &j; + auto elem = obj_fnv1a64m_hashes_upper.find(hash); + if (elem != obj_fnv1a64m_hashes_upper.end()) + return elem->second; return 0; } @@ -339,25 +395,23 @@ const object_info_data* object_database::get_object_info_data_by_murmurhash(uint 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) - return &j; + auto elem = obj_murmurhashes.find(hash); + if (elem != obj_murmurhashes.end()) + return elem->second; return 0; } uint32_t object_database::get_object_set_id(const char* name) const { - if (!name) + if (!name || !*name) return (uint32_t)-1; size_t name_len = utf8_length(name); if (!str_utils_compare_length(name, name_len, "NULL", 5)) return (uint32_t)-1; - uint32_t name_hash = hash_utf8_murmurhash(name); - for (const object_set_info& i : object_set) - if (name_hash == i.name_hash) - return i.id; + auto elem = obj_set_murmurhashes.find(hash_utf8_murmurhash(name)); + if (elem != obj_set_murmurhashes.end()) + return elem->second->id; return (uint32_t)-1; } @@ -365,9 +419,9 @@ const char* object_database::get_object_set_name(uint32_t set_id) const { if (set_id == -1) return 0; - for (const object_set_info& i : object_set) - if (set_id == i.id) - return i.name.c_str(); + auto elem = obj_set_ids.find(set_id); + if (elem != obj_set_ids.end()) + return elem->second->name.c_str(); return 0; } @@ -379,11 +433,9 @@ object_info object_database::get_object_info(const char* name) const { if (!str_utils_compare_length(name, name_len, "NULL", 5)) return object_info(); - 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) - return { j.id, i.id }; + auto elem = obj_info_murmurhashes.find(hash_utf8_murmurhash(name)); + if (elem != obj_info_murmurhashes.end()) + return elem->second; return object_info(); } @@ -391,11 +443,9 @@ const char* object_database::get_object_name(object_info obj_info) const { if (obj_info.is_null()) return 0; - for (const object_set_info& i : object_set) - if (obj_info.set_id == i.id) - for (const object_info_data& j : i.object) - if (obj_info.id == j.id) - return j.name.c_str(); + auto elem = obj_infos.find(obj_info); + if (elem != obj_infos.end()) + return elem->second->name.c_str(); return 0; } diff --git a/src/KKdLib/database/object.hpp b/src/KKdLib/database/object.hpp index 99b83466..17cde527 100644 --- a/src/KKdLib/database/object.hpp +++ b/src/KKdLib/database/object.hpp @@ -8,6 +8,7 @@ #include #include #include "../default.hpp" +#include "../prj/vector_pair.hpp" #include "../hash.hpp" struct object_info { @@ -136,11 +137,20 @@ struct object_database_file { struct object_database { std::vector object_set; + prj::vector_pair obj_set_ids; + prj::vector_pair obj_set_murmurhashes; + prj::vector_pair obj_infos; + prj::vector_pair obj_fnv1a64m_hashes; + prj::vector_pair obj_fnv1a64m_hashes_upper; + prj::vector_pair obj_murmurhashes; + prj::vector_pair obj_info_murmurhashes; object_database(); ~object_database(); void add(object_database_file* obj_db_file); + void clear(); + void update(); 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; diff --git a/src/KKdLib/database/sprite.cpp b/src/KKdLib/database/sprite.cpp index 9f2291b4..4196a554 100644 --- a/src/KKdLib/database/sprite.cpp +++ b/src/KKdLib/database/sprite.cpp @@ -23,15 +23,16 @@ static bool sprite_database_file_strings_push_back_check(std::vectorsprite_set.size()); for (spr_db_spr_set_file& i : spr_db_file->sprite_set) { - spr_db_spr_set spr_set; + spr_sets.push_back({}); + spr_db_spr_set& spr_set = spr_sets.back(); 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); + spr_set.index = (uint32_t)(sprite_sets_count + i.index); - 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 }); + 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 }); spr_ids.reserve(i.sprite.size()); spr_names.reserve(i.sprite.size()); spr_indices.reserve(i.sprite.size()); for (spr_db_spr_file& j : i.sprite) { - spr_db_spr spr; + sprs.push_back({}); + spr_db_spr& spr = sprs.back(); 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.load_count = 1; - spr_ids.push_back({ spr.id, spr }); - spr_names.push_back({ spr.name, spr }); - spr_indices.push_back({ spr.info, spr }); + spr_ids.push_back({ spr.id, &spr }); + spr_names.push_back({ spr.name, &spr }); + spr_indices.push_back({ spr.info, &spr }); } } @@ -288,52 +295,187 @@ void sprite_database::add(sprite_database_file* spr_db_file) { spr_indices.combine(); } +void sprite_database::clear() { + spr_sets.clear(); + spr_set_ids.clear(); + spr_set_indices.clear(); + spr_set_names.clear(); + sprs.clear(); + spr_ids.clear(); + spr_names.clear(); + spr_indices.clear(); +} + +void sprite_database::add_spr_set(uint32_t set_id, uint32_t index) { + if (set_id == -1 || set_id == hash_murmurhash_empty) + return; + + spr_sets.push_back({}); + spr_db_spr_set& set = spr_sets.back(); + set.id = set_id; + set.index = index; + + spr_set_indices.push_back({ set.index, &set }); + spr_set_ids.push_back({ set.id, &set }); + + spr_set_indices.combine(); + spr_set_ids.combine(); +} + +void sprite_database::parse(const spr_db_spr_set_file* set_file, + std::string& set_name, std::vector& sprite_ids) { + if (!set_file) + return; + + auto elem = spr_set_ids.find(set_file->id); + if (elem == spr_set_ids.end()) + return; + + uint16_t set_index = (uint16_t)elem->second->index; + + spr_set_names.push_back({ set_file->name, elem->second }); + + sprite_ids.reserve(set_file->sprite.size()); + for (const spr_db_spr_file& i : set_file->sprite) { + uint32_t id = i.id; + sprite_ids.push_back(id); + + auto j_begin = sprs.begin(); + auto j_end = sprs.end(); + auto j = j_begin; + while (j != j_end) + if (j->id == id) + break; + else + j++; + + spr_db_spr* spr; + if (j == j_end) { + sprs.push_back({}); + spr = &sprs.back(); + } + else + spr = &*j; + + spr->id = id; + spr->name.assign(i.name); + spr->name_hash = hash_string_murmurhash(spr->name); + spr->info = { i.index, (uint16_t)((i.texture ? 0x1000 : 0x0000) | set_index) }; + spr->load_count++; + + spr_ids.push_back({ spr->id, spr }); + spr_names.push_back({ spr->name, spr }); + spr_indices.push_back({ spr->info, spr }); + } + + spr_set_names.combine(); + spr_ids.combine(); + spr_names.combine(); + spr_indices.combine(); +} + +void sprite_database::remove_spr_set(uint32_t set_id, uint32_t index, + const char* set_name, std::vector& sprite_ids) { + if (set_name && *set_name) { + auto elem = spr_set_names.find(set_name); + if (elem != spr_set_names.end()) + spr_set_names.erase(elem); + } + + if (index != -1) { + auto elem = spr_set_indices.find(index); + if (elem != spr_set_indices.end()) + spr_set_indices.erase(elem); + } + + if (set_id != -1 && set_id != hash_murmurhash_empty) { + auto elem = spr_set_ids.find(set_id); + if (elem != spr_set_ids.end()) + spr_set_ids.erase(elem); + + auto i_begin = spr_sets.begin(); + auto i_end = spr_sets.end(); + auto i = i_begin; + while (i != i_end) + if (i->id == set_id) + i = spr_sets.erase(i); + else + i++; + } + + for (auto& i : sprite_ids) { + auto j_begin = sprs.begin(); + auto j_end = sprs.end(); + auto j = j_begin; + while (j != j_end) { + if (j->id != i || --j->load_count > 0) { + j++; + continue; + } + + auto elem_id = spr_ids.find(j->id); + if (elem_id != spr_ids.end()) + spr_ids.erase(elem_id); + + auto elem_index = spr_indices.find(j->info); + if (elem_index != spr_indices.end()) + spr_indices.erase(elem_index); + + auto elem_name = spr_names.find(j->name); + if (elem_name != spr_names.end()) + spr_names.erase(elem_name); + + j = sprs.erase(j); + } + } +} + 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 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 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 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 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 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 }); + auto elem = spr_indices.find({ (uint16_t)index, (uint16_t)get_spr_set_by_id(set_id)->index }); if (elem != spr_indices.end()) - return &elem->second; + 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 elem->second; return &spr_db_spr_null; } @@ -346,7 +488,7 @@ uint32_t sprite_database::get_spr_set_id_by_name(const char* name) const { } uint32_t sprite_database::get_spr_set_id_by_name_index(uint32_t index) const { - return spr_set_names[index].second.id; + return spr_set_names[index].second->id; } const char* sprite_database::get_spr_set_name(uint32_t set_id) const { @@ -369,7 +511,7 @@ static void sprite_database_file_classic_read_inner(sprite_database_file* spr_db 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 = (uint16_t)s.read_uint32_t(); + spr_set.index = s.read_uint32_t(); } s.position_pop(); @@ -528,7 +670,7 @@ static void sprite_database_file_modern_read_inner(sprite_database_file* spr_db, 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 = (uint16_t)s.read_uint32_t_reverse_endianness(); + spr_set.index = s.read_uint32_t_reverse_endianness(); } else for (uint32_t i = 0; i < sprite_sets_count; i++) { @@ -536,7 +678,7 @@ static void sprite_database_file_modern_read_inner(sprite_database_file* spr_db, 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 = (uint16_t)s.read_uint32_t_reverse_endianness(); + spr_set.index = s.read_uint32_t_reverse_endianness(); s.align_read(0x08); } s.position_pop(); diff --git a/src/KKdLib/database/sprite.hpp b/src/KKdLib/database/sprite.hpp index 078696bd..d8c84be4 100644 --- a/src/KKdLib/database/sprite.hpp +++ b/src/KKdLib/database/sprite.hpp @@ -5,11 +5,11 @@ #pragma once +#include #include #include #include "../default.hpp" #include "../prj/vector_pair_combine.hpp" -#include "../hash.hpp" struct spr_info { uint16_t index; @@ -73,6 +73,7 @@ struct spr_db_spr { std::string name; uint32_t name_hash; spr_info info; + int32_t load_count; spr_db_spr(); ~spr_db_spr(); @@ -83,7 +84,7 @@ struct spr_db_spr_set_file { std::string name; std::string file_name; std::vector sprite; - uint16_t index; + uint32_t index; spr_db_spr_set_file(); ~spr_db_spr_set_file(); @@ -95,7 +96,7 @@ struct spr_db_spr_set { uint32_t name_hash; std::string file_name; uint32_t file_name_hash; - uint16_t index; + uint32_t index; spr_db_spr_set(); ~spr_db_spr_set(); @@ -123,17 +124,26 @@ struct sprite_database_file { }; struct sprite_database { - prj::vector_pair_combine spr_set_ids; - prj::vector_pair_combine spr_set_indices; - prj::vector_pair_combine spr_set_names; - prj::vector_pair_combine spr_ids; - prj::vector_pair_combine spr_names; - prj::vector_pair_combine spr_indices; + std::list spr_sets; + prj::vector_pair_combine spr_set_ids; + prj::vector_pair_combine spr_set_indices; + prj::vector_pair_combine spr_set_names; + std::list sprs; + prj::vector_pair_combine spr_ids; + prj::vector_pair_combine spr_names; + prj::vector_pair_combine spr_indices; sprite_database(); ~sprite_database(); void add(sprite_database_file* spr_db_file); + void clear(); + + void add_spr_set(uint32_t set_id, uint32_t index); + void parse(const spr_db_spr_set_file* set_file, + std::string& set_name, std::vector& sprite_ids); + void remove_spr_set(uint32_t set_id, uint32_t index, + const char* set_name, std::vector& sprite_ids); 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; diff --git a/src/KKdLib/database/stage.cpp b/src/KKdLib/database/stage.cpp index 212ba746..7641264d 100644 --- a/src/KKdLib/database/stage.cpp +++ b/src/KKdLib/database/stage.cpp @@ -388,6 +388,13 @@ void stage_database::add(stage_database_file* stage_data_file) { } } +void stage_database::clear() { + stage_data.clear(); + stage_data.shrink_to_fit(); + stage_modern.clear(); + stage_modern.shrink_to_fit(); +} + const ::stage_data* stage_database::get_stage_data(int32_t stage_index) const { if (stage_index >= 0 && stage_index < stage_data.size()) return &stage_data[stage_index]; diff --git a/src/KKdLib/database/stage.hpp b/src/KKdLib/database/stage.hpp index d8259d76..53471e3f 100644 --- a/src/KKdLib/database/stage.hpp +++ b/src/KKdLib/database/stage.hpp @@ -272,6 +272,7 @@ struct stage_database { ~stage_database(); void add(stage_database_file* stage_data_file); + void clear(); const ::stage_data* get_stage_data(int32_t stage_index) const; const ::stage_data_modern* get_stage_data_modern(uint32_t stage_hash) const; diff --git a/src/KKdLib/database/texture.cpp b/src/KKdLib/database/texture.cpp index 311a09ac..0382f485 100644 --- a/src/KKdLib/database/texture.cpp +++ b/src/KKdLib/database/texture.cpp @@ -277,6 +277,11 @@ static size_t texture_info_radix_index_func_id(texture_info* data, size_t index) return data[index].id; } +void texture_database::clear() { + texture.clear(); + texture.shrink_to_fit(); +} + void texture_database::sort() { radix_sort_custom(texture.data(), texture.size(), sizeof(texture_info), sizeof(uint32_t), (radix_index_func)texture_info_radix_index_func_id); diff --git a/src/KKdLib/database/texture.hpp b/src/KKdLib/database/texture.hpp index baf2acd5..96386f12 100644 --- a/src/KKdLib/database/texture.hpp +++ b/src/KKdLib/database/texture.hpp @@ -54,6 +54,7 @@ struct texture_database { ~texture_database(); void add(texture_database_file* tex_db_file); + void clear(); void sort(); uint32_t get_texture_id(const char* name) const; diff --git a/src/KKdLib/f2/pof.cpp b/src/KKdLib/f2/pof.cpp index 16e1a271..700e11c8 100644 --- a/src/KKdLib/f2/pof.cpp +++ b/src/KKdLib/f2/pof.cpp @@ -16,7 +16,7 @@ inline static bool pof_length_get_size(uint32_t* length, size_t val); static size_t pof_read_offsets_count(stream& s); inline static bool pof_write_packed_value(stream& s, size_t val); -pof::pof() { +pof::pof() : shift_x() { } @@ -28,7 +28,7 @@ void pof::add(stream& s, int64_t offset) { vec.push_back(s.get_position() + offset); } -void pof::read(stream& s, bool shift_x) { +void pof::read(stream& s) { vec.clear(); size_t length = pof_read_offsets_count(s); @@ -64,12 +64,12 @@ void pof::read(stream& s, bool shift_x) { } } -void pof::write(stream& s, bool shift_x) { +void pof::write(stream& s) { size_t j = 0; size_t o = 0; uint8_t bit_shift = (uint8_t)(shift_x ? 3 : 2); size_t v = ((size_t)1 << bit_shift) - 1; - size_t l = length(shift_x); + size_t l = length(); if (shift_x) s.write_uint32_t((uint32_t)l); else @@ -96,7 +96,7 @@ void pof::write(stream& s, bool shift_x) { s.write_uint8_t(0); } -uint32_t pof::length(bool shift_x) { +uint32_t pof::length() { uint32_t l = 4; size_t j = 0; uint8_t bit_shift = (uint8_t)(shift_x ? 3 : 2); diff --git a/src/KKdLib/f2/pof.hpp b/src/KKdLib/f2/pof.hpp index d30e123f..2985ce5d 100644 --- a/src/KKdLib/f2/pof.hpp +++ b/src/KKdLib/f2/pof.hpp @@ -11,14 +11,15 @@ struct pof { std::vector vec; + bool shift_x; pof(); ~pof(); void add(stream& s, int64_t offset); - void read(stream& s, bool shift_x = false); - void write(stream& s, bool shift_x = false); - uint32_t length(bool shift_x = false); + void read(stream& s); + void write(stream& s); + uint32_t length(); }; extern void io_write_offset_pof_add(stream& s, int64_t val, diff --git a/src/KKdLib/f2/struct.cpp b/src/KKdLib/f2/struct.cpp index e3e5428c..0c1b4be5 100644 --- a/src/KKdLib/f2/struct.cpp +++ b/src/KKdLib/f2/struct.cpp @@ -143,7 +143,8 @@ static void f2_struct_get_length(f2_struct* s, bool shift_x) { } if (has_pof) { - uint32_t len = s->pof.length(shift_x); + s->pof.shift_x = shift_x; + uint32_t len = s->pof.length(); l += 0x20 + align_val(len, 0x10); } @@ -186,7 +187,8 @@ static void f2_struct_read_data(stream& s, f2_struct* st, f2_header* h) { } else if ((sig & 0xFFFFFFF0) == 'POF0') { size_t pos = s.get_position(); - st->pof.read(s, sig == 'POF1'); + st->pof.shift_x = sig == 'POF1'; + st->pof.read(s); s.set_position(pos + l, SEEK_SET); } else { @@ -219,7 +221,8 @@ static void f2_struct_write_inner(stream& s, f2_struct* st, uint32_t depth, bool } static void f2_struct_write_pof(stream& s, pof* pof, uint32_t depth, bool shift_x) { - size_t len = pof->length(shift_x); + pof->shift_x = shift_x; + size_t len = pof->length(); f2_header h = {}; h.signature = shift_x ? reverse_endianness_uint32_t('POF1') : reverse_endianness_uint32_t('POF0'); h.length = 0x20; @@ -227,7 +230,7 @@ static void f2_struct_write_pof(stream& s, pof* pof, uint32_t depth, bool shift_ h.use_section_size = true; h.data_size = h.section_size = (uint32_t)align_val(len, 0x10); f2_header_write(s, &h, false); - pof->write(s, shift_x); + pof->write(s); } static void f2_struct_write_enrs(stream& s, enrs* enrs, uint32_t depth) { diff --git a/src/KKdLib/interpolation.cpp b/src/KKdLib/interpolation.cpp index d88818e4..621a5040 100644 --- a/src/KKdLib/interpolation.cpp +++ b/src/KKdLib/interpolation.cpp @@ -20,8 +20,10 @@ void interpolate_chs_reverse_value(float_t* arr, size_t length, float_t t1_1 = _t1 - 1.0f; float_t t2_1 = _t2 - 1.0f; - float_t t1_t2_1 = arr[f] - arr[f1] - _t1 * _t1 * (3.0f - 2.0f * _t1) * (arr[f2] - arr[f1]); - float_t t1_t2_2 = arr[f + 1] - arr[f1] - _t2 * _t2 * (3.0f - 2.0f * _t2) * (arr[f2] - arr[f1]); + float_t t1_t2_1 = arr[f] - (1.0f + 2.0f * _t1) * (t1_1 * t1_1) * arr[f1] + - _t1 * _t1 * (3.0f - 2.0f * _t1) * arr[f2]; + float_t t1_t2_2 = arr[f + 1] - (1.0f + 2.0f * _t2) * (t2_1 * t2_1) * arr[f1] + - _t2 * _t2 * (3.0f - 2.0f * _t2) * arr[f2]; t1_t2_1 /= df_1 * t1_1; t1_t2_2 /= df_2 * t2_1; @@ -65,8 +67,10 @@ void interpolate_chs_reverse_step_value(float_t* arr, size_t length, float_t t1_1 = _t1 - 1.0f; float_t t2_1 = _t2 - 1.0f; - float_t t1_t2_1 = arr[f] - arr[f1] - _t1 * _t1 * (3.0f - 2.0f * _t1) * (arr[f2] - arr[f1]); - float_t t1_t2_2 = arr[f + 1] - arr[f1] - _t2 * _t2 * (3.0f - 2.0f * _t2) * (arr[f2] - arr[f1]); + float_t t1_t2_1 = arr[f] - (1.0f + 2.0f * _t1) * (t1_1 * t1_1) * arr[f1] + - _t1 * _t1 * (3.0f - 2.0f * _t1) * arr[f2]; + float_t t1_t2_2 = arr[f + 1] - (1.0f + 2.0f * _t2) * (t2_1 * t2_1) * arr[f1] + - _t2 * _t2 * (3.0f - 2.0f * _t2) * arr[f2]; t1_t2_1 /= df_1 * t1_1; t1_t2_2 /= df_2 * t2_1; diff --git a/src/KKdLib/interpolation.hpp b/src/KKdLib/interpolation.hpp index 2b11c2a6..04fe16be 100644 --- a/src/KKdLib/interpolation.hpp +++ b/src/KKdLib/interpolation.hpp @@ -91,7 +91,9 @@ inline float_t interpolate_chs_value(const float_t p1, const float_t p2, float_t df = f - f1; float_t t = df / (f2 - f1); float_t t_1 = t - 1.0f; - return (t_1 * t1 + t * t2) * df * t_1 + t * t * (3.0f - 2.0f * t) * (p2 - p1) + p1; + return (t_1 * t1 + t * t2) * df * t_1 + + t * t * (3.0f - 2.0f * t) * p2 + + (1.0f + 2.0f * t) * (t_1 * t_1) * p1; } inline vec2 interpolate_chs_value(const vec2 p1, const vec2 p2, @@ -119,9 +121,10 @@ inline vec2 interpolate_chs_value(const vec2 p1, const vec2 p2, __m128 t = _mm_div_ps(df, _mm_sub_ps(_f2, _f1)); __m128 t_1 = _mm_sub_ps(t, _1); - __m128 delta = _mm_mul_ps(_mm_mul_ps(_mm_mul_ps(t, t), _mm_sub_ps(_3, _mm_mul_ps(_2, t))), _mm_sub_ps(_p2, _p1)); + _p1 = _mm_mul_ps(_mm_mul_ps(_mm_add_ps(_1, _mm_mul_ps(_2, t)), _mm_mul_ps(t_1, t_1)), _p1); + _p2 = _mm_mul_ps(_mm_mul_ps(_mm_mul_ps(t, t), _mm_sub_ps(_3, _mm_mul_ps(_2, t))), _p2); __m128 tangent = _mm_mul_ps(_mm_add_ps(_mm_mul_ps(t_1, _t1), _mm_mul_ps(t, _t2)), _mm_mul_ps(df, t_1)); - return vec2::store_xmm(_mm_add_ps(_mm_add_ps(tangent, delta), _p1)); + return vec2::store_xmm(_mm_add_ps(_mm_add_ps(tangent, _p2), _p1)); } inline vec3 interpolate_chs_value(const vec3 p1, const vec3 p2, @@ -149,9 +152,10 @@ inline vec3 interpolate_chs_value(const vec3 p1, const vec3 p2, __m128 t = _mm_div_ps(df, _mm_sub_ps(_f2, _f1)); __m128 t_1 = _mm_sub_ps(t, _1); - __m128 delta = _mm_mul_ps(_mm_mul_ps(_mm_mul_ps(t, t), _mm_sub_ps(_3, _mm_mul_ps(_2, t))), _mm_sub_ps(_p2, _p1)); + _p1 = _mm_mul_ps(_mm_mul_ps(_mm_add_ps(_1, _mm_mul_ps(_2, t)), _mm_mul_ps(t_1, t_1)), _p1); + _p2 = _mm_mul_ps(_mm_mul_ps(_mm_mul_ps(t, t), _mm_sub_ps(_3, _mm_mul_ps(_2, t))), _p2); __m128 tangent = _mm_mul_ps(_mm_add_ps(_mm_mul_ps(t_1, _t1), _mm_mul_ps(t, _t2)), _mm_mul_ps(df, t_1)); - return vec3::store_xmm(_mm_add_ps(_mm_add_ps(tangent, delta), _p1)); + return vec3::store_xmm(_mm_add_ps(_mm_add_ps(tangent, _p2), _p1)); } inline vec4 interpolate_chs_value(const vec4 p1, const vec4 p2, @@ -179,9 +183,10 @@ inline vec4 interpolate_chs_value(const vec4 p1, const vec4 p2, __m128 t = _mm_div_ps(df, _mm_sub_ps(_f2, _f1)); __m128 t_1 = _mm_sub_ps(t, _1); - __m128 delta = _mm_mul_ps(_mm_mul_ps(_mm_mul_ps(t, t), _mm_sub_ps(_3, _mm_mul_ps(_2, t))), _mm_sub_ps(_p2, _p1)); + _p1 = _mm_mul_ps(_mm_mul_ps(_mm_add_ps(_1, _mm_mul_ps(_2, t)), _mm_mul_ps(t_1, t_1)), _p1); + _p2 = _mm_mul_ps(_mm_mul_ps(_mm_mul_ps(t, t), _mm_sub_ps(_3, _mm_mul_ps(_2, t))), _p2); __m128 tangent = _mm_mul_ps(_mm_add_ps(_mm_mul_ps(t_1, _t1), _mm_mul_ps(t, _t2)), _mm_mul_ps(df, t_1)); - return vec4::store_xmm(_mm_add_ps(_mm_add_ps(tangent, delta), _p1)); + return vec4::store_xmm(_mm_add_ps(_mm_add_ps(tangent, _p2), _p1)); } inline std::vector interpolate_chs(const float_t p1, const float_t p2, diff --git a/src/KKdLib/mot.cpp b/src/KKdLib/mot.cpp index 4e965c9e..4cae6210 100644 --- a/src/KKdLib/mot.cpp +++ b/src/KKdLib/mot.cpp @@ -34,6 +34,12 @@ static void mot_classic_read_inner(mot_set* ms, prj::shared_ptr& alloc, stream& s); static void mot_modern_write_inner(mot_set* ms, stream& s); + +static const char* mot_move_data_string(const char* str, + prj::shared_ptr& alloc); +static void mot_data_move_data(mot_data* mot_dst, const mot_data* mot_src, + prj::shared_ptr alloc); + static const char* mot_read_utf8_string_null_terminated_offset( prj::shared_ptr& alloc, stream& s, int64_t offset); @@ -54,6 +60,33 @@ mot_set::mot_set() : ready(), modern(), big_endian(), is_x(), name(), mot_data() } +void mot_set::move_data(mot_set* set_src, prj::shared_ptr alloc) { + if (!set_src->ready) { + ready = false; + modern = false; + big_endian = false; + is_x = false; + return; + } + + ready = true; + modern = set_src->modern; + big_endian = set_src->big_endian; + is_x = set_src->is_x; + + name = mot_move_data_string(set_src->name, alloc); + + uint32_t mot_num = set_src->mot_num; + ::mot_data* mot_data_src = set_src->mot_data; + ::mot_data* mot_data_dst = alloc->allocate<::mot_data>(mot_num); + + for (uint32_t i = 0; i < mot_num; i++) + mot_data_move_data(&mot_data_dst[i], &mot_data_src[i], alloc); + + this->mot_data = mot_data_dst; + this->mot_num = mot_num; +} + void mot_set::pack_file(void** data, size_t* size) { if (!data || !size || !ready) return; @@ -101,8 +134,10 @@ inline static void interpolate_mot_reverse_value(float_t* arr, size_t length, float_t t1_1 = _t1 - 1.0f; float_t t2_1 = _t2 - 1.0f; - float_t t1_t2_1 = arr[f] - arr[f1] - (_t1 * 2.0f - 3.0f) * (_t1 * _t1) * (arr[f1] - arr[f2]); - float_t t1_t2_2 = arr[f + 1] - arr[f1] - (_t2 * 2.0f - 3.0f) * (_t2 * _t2) * (arr[f1] - arr[f2]); + float_t t1_t2_1 = arr[f] - (1.0f + 2.0f * _t1) * (t1_1 * t1_1) * arr[f1] + - _t1 * _t1 * (3.0f - 2.0f * _t1) * arr[f2]; + float_t t1_t2_2 = arr[f + 1] - (1.0f + 2.0f * _t2) * (t2_1 * t2_1) * arr[f1] + - _t2 * _t2 * (3.0f - 2.0f * _t2) * arr[f2]; t1_t2_1 /= df_1 * t1_1; t1_t2_2 /= df_2 * t2_1; @@ -530,15 +565,14 @@ static void mot_modern_read_inner(mot_set* ms, prj::shared_ptrallocate<::mot_data>(); ms->mot_data = mot_data; ms->mot_num = 1; @@ -547,12 +581,12 @@ static void mot_modern_read_inner(mot_set* ms, prj::shared_ptr& alloc) { + if (str) + return alloc->allocate(str, utf8_length(str) + 1); + return 0; +} + +static void mot_data_move_data(mot_data* mot_dst, const mot_data* mot_src, + prj::shared_ptr alloc) { + mot_dst->info = mot_src->info; + mot_dst->frame_count = mot_src->frame_count; + mot_dst->bone_info_count = mot_src->bone_info_count; + + mot_dst->murmurhash = mot_src->murmurhash; + mot_dst->div_frames = mot_src->div_frames; + mot_dst->div_count = mot_src->div_count; + + mot_dst->name = mot_move_data_string(mot_src->name, alloc); + + uint32_t bone_info_count = mot_src->bone_info_count; + mot_bone_info* bone_info_array_src = mot_src->bone_info_array; + mot_bone_info* bone_info_array_dst = alloc->allocate(bone_info_count); + + for (uint32_t i = 0; i < bone_info_count; i++) { + mot_bone_info* bone_info_src = &bone_info_array_src[i]; + mot_bone_info* bone_info_dst = &bone_info_array_dst[i]; + bone_info_dst->name = mot_move_data_string(bone_info_src->name, alloc); + bone_info_dst->index = bone_info_src->index; + } + + mot_dst->bone_info_array = bone_info_array_dst; + + uint32_t key_set_count = mot_src->key_set_count; + mot_key_set_data* key_set_array_src = mot_src->key_set_array; + mot_key_set_data* key_set_array_dst = alloc->allocate(key_set_count); + + for (uint32_t i = 0; i < key_set_count; i++) { + mot_key_set_data* key_set_src = &key_set_array_src[i]; + mot_key_set_data* key_set_dst = &key_set_array_dst[i]; + + mot_key_set_type type = key_set_src->type; + uint16_t keys_count = key_set_src->keys_count; + + switch (type) { + case MOT_KEY_SET_NONE: + key_set_dst->frames = 0; + key_set_dst->values = 0; + break; + case MOT_KEY_SET_STATIC: + key_set_dst->frames = 0; + key_set_dst->values = alloc->allocate(key_set_src->values, 1); + break; + case MOT_KEY_SET_HERMITE: + key_set_dst->frames = alloc->allocate(key_set_src->frames, keys_count); + key_set_dst->values = alloc->allocate(key_set_src->values, keys_count); + break; + case MOT_KEY_SET_HERMITE_TANGENT: + key_set_dst->frames = alloc->allocate(key_set_src->frames, keys_count); + key_set_dst->values = alloc->allocate(key_set_src->values, keys_count * 2ULL); + break; + } + + key_set_dst->type = type; + key_set_dst->keys_count = keys_count; + key_set_dst->data_type = key_set_src->data_type; + } + + mot_dst->key_set_array = key_set_array_dst; +} + inline static const char* mot_read_utf8_string_null_terminated_offset( prj::shared_ptr& alloc, stream& s, int64_t offset) { size_t len = s.read_utf8_string_null_terminated_offset_length(offset); diff --git a/src/KKdLib/mot.hpp b/src/KKdLib/mot.hpp index 088d8836..9e64e5b4 100644 --- a/src/KKdLib/mot.hpp +++ b/src/KKdLib/mot.hpp @@ -75,6 +75,7 @@ struct mot_set { mot_set(); + void move_data(mot_set* set_src, prj::shared_ptr alloc); void pack_file(void** data, size_t* size); void unpack_file(prj::shared_ptr alloc, const void* data, size_t size, bool modern); diff --git a/src/KKdLib/obj.cpp b/src/KKdLib/obj.cpp index ace31171..9a7cfef2 100644 --- a/src/KKdLib/obj.cpp +++ b/src/KKdLib/obj.cpp @@ -73,7 +73,7 @@ struct obj_header { }; struct obj_set_header { - int32_t last_obj_id; + uint32_t last_obj_id; int64_t obj_data; int64_t obj_skin_data; int64_t obj_name_data; @@ -1206,44 +1206,44 @@ static void obj_set_classic_read_inner(obj_set* set, prj::shared_ptrobj_num = s.read_int32_t(); - osh.last_obj_id = s.read_int32_t(); - osh.obj_data = s.read_int32_t(); - osh.obj_skin_data = s.read_int32_t(); - osh.obj_name_data = s.read_int32_t(); - osh.obj_id_data = s.read_int32_t(); - osh.tex_id_data = s.read_int32_t(); - set->tex_id_num = s.read_int32_t(); + set->obj_num = s.read_uint32_t(); + osh.last_obj_id = s.read_uint32_t(); + osh.obj_data = s.read_uint32_t(); + osh.obj_skin_data = s.read_uint32_t(); + osh.obj_name_data = s.read_uint32_t(); + osh.obj_id_data = s.read_uint32_t(); + osh.tex_id_data = s.read_uint32_t(); + set->tex_id_num = s.read_uint32_t(); set->reserved[0] = s.read_uint32_t(); set->reserved[1] = s.read_uint32_t(); uint32_t obj_num = set->obj_num; set->obj_data = alloc->allocate(obj_num); - int32_t* data = force_malloc_s(int32_t, obj_num * 3ULL); + uint32_t* data = force_malloc_s(uint32_t, obj_num * 3ULL); - int32_t* obj_data = 0; + uint32_t* obj_data = 0; if (osh.obj_data) { obj_data = data; s.set_position(osh.obj_data, SEEK_SET); for (uint32_t i = 0; i < obj_num; i++) - obj_data[i] = s.read_int32_t(); + obj_data[i] = s.read_uint32_t(); } - int32_t* obj_skin_data = 0; + uint32_t* obj_skin_data = 0; if (osh.obj_skin_data) { obj_skin_data = data + obj_num; s.set_position(osh.obj_skin_data, SEEK_SET); for (uint32_t i = 0; i < obj_num; i++) - obj_skin_data[i] = s.read_int32_t(); + obj_skin_data[i] = s.read_uint32_t(); } - int32_t* obj_name_data = 0; + uint32_t* obj_name_data = 0; if (osh.obj_name_data) { obj_name_data = data + obj_num * 2ULL; s.set_position(osh.obj_name_data, SEEK_SET); for (uint32_t i = 0; i < obj_num; i++) - obj_name_data[i] = s.read_int32_t(); + obj_name_data[i] = s.read_uint32_t(); } if (osh.obj_data) { @@ -1328,7 +1328,7 @@ static void obj_set_classic_write_inner(obj_set* set, stream& s) { osh.obj_id_data = s.get_position(); for (uint32_t i = 0; i < obj_num; i++) { - int32_t object_id = set->obj_data[i].id; + uint32_t object_id = set->obj_data[i].id; s.write_uint32_t(object_id); if (osh.last_obj_id < object_id) osh.last_obj_id = object_id; @@ -1450,10 +1450,10 @@ static void obj_classic_read_model(obj* obj, prj::shared_ptrbounding_sphere.center.y = s.read_float_t(); obj->bounding_sphere.center.z = s.read_float_t(); obj->bounding_sphere.radius = s.read_float_t(); - obj->num_mesh = s.read_int32_t(); - oh.mesh_array = s.read_int32_t(); - obj->num_material = s.read_int32_t(); - oh.material_array = s.read_int32_t(); + obj->num_mesh = s.read_uint32_t(); + oh.mesh_array = s.read_uint32_t(); + obj->num_material = s.read_uint32_t(); + oh.material_array = s.read_uint32_t(); obj->reserved[0] = s.read_uint32_t(); obj->reserved[1] = s.read_uint32_t(); obj->reserved[2] = s.read_uint32_t(); @@ -1690,14 +1690,14 @@ static void obj_classic_read_model_mesh(obj_mesh* mesh, mesh->bounding_sphere.center.y = s.read_float_t(); mesh->bounding_sphere.center.z = s.read_float_t(); mesh->bounding_sphere.radius = s.read_float_t(); - mesh->num_submesh = s.read_int32_t(); - mh.submesh_array = s.read_int32_t(); + mesh->num_submesh = s.read_uint32_t(); + mh.submesh_array = s.read_uint32_t(); mh.format = (obj_vertex_format_file)s.read_uint32_t(); - mh.size_vertex = s.read_int32_t(); - mh.num_vertex = s.read_int32_t(); + mh.size_vertex = s.read_uint32_t(); + mh.num_vertex = s.read_uint32_t(); for (int64_t& i : mh.vertex) - i = s.read_int32_t(); + i = s.read_uint32_t(); mesh->attrib.w = s.read_uint32_t(); mh.vertex_format_index = s.read_uint32_t(); @@ -1735,12 +1735,12 @@ static void obj_classic_read_model_sub_mesh(obj_sub_mesh* sub_mesh, sub_mesh->bounding_sphere.radius = s.read_float_t(); sub_mesh->material_index = s.read_uint32_t(); s.read(&sub_mesh->uv_index, 0x08); - sub_mesh->num_bone_index = s.read_int32_t(); + sub_mesh->num_bone_index = s.read_uint32_t(); smh.bone_index_array_offset = s.read_uint32_t(); sub_mesh->bones_per_vertex = s.read_uint32_t(); sub_mesh->primitive_type = (obj_primitive_type)s.read_uint32_t(); sub_mesh->index_format = (obj_index_format)s.read_uint32_t(); - sub_mesh->num_index = s.read_int32_t(); + sub_mesh->num_index = s.read_uint32_t(); smh.index_array_offset = s.read_uint32_t(); sub_mesh->attrib.w = s.read_uint32_t(); sub_mesh->bounding_box.center = sub_mesh->bounding_sphere.center; @@ -1769,7 +1769,7 @@ static obj_skin* obj_classic_read_skin(prj::shared_ptr all sh.bone_matrix_array_offset = s.read_uint32_t(); sh.bone_name_array_offset = s.read_uint32_t(); sh.ex_data_offset = s.read_uint32_t(); - sk->num_bone = s.read_int32_t(); + sk->num_bone = s.read_uint32_t(); sh.bone_parent_id_array_offset = s.read_uint32_t(); s.read(0, 0x0C); @@ -1813,7 +1813,7 @@ static obj_skin* obj_classic_read_skin(prj::shared_ptr all s.set_position(sh.bone_name_array_offset, SEEK_SET); for (uint32_t i = 0; i < sk->num_bone; i++) sk->bone_array[i].name = obj_read_utf8_string_null_terminated_offset( - alloc, s, s.read_int32_t()); + alloc, s, s.read_uint32_t()); } } @@ -2536,13 +2536,13 @@ static obj_skin_ex_data* obj_classic_read_skin_ex_data(prj::shared_ptrnum_osage_node = s.read_int32_t(); + exh.num_osage = s.read_uint32_t(); + ex->num_osage_node = s.read_uint32_t(); s.read(0, 0x04); exh.osage_node_array_offset = s.read_uint32_t(); exh.osage_name_array_offset = s.read_uint32_t(); exh.block_array_offset = s.read_uint32_t(); - exh.num_bone_name = s.read_int32_t(); + exh.num_bone_name = s.read_uint32_t(); exh.bone_name_array_offset = s.read_uint32_t(); exh.osage_sibling_info_array_offset = s.read_uint32_t(); exh.cloth_count = s.read_uint32_t(); @@ -2569,7 +2569,7 @@ static obj_skin_ex_data* obj_classic_read_skin_ex_data(prj::shared_ptrnum_block = 0; s.set_position(exh.block_array_offset, SEEK_SET); - while (s.read_int32_t()) { + while (s.read_uint32_t()) { s.read(0, 0x04); ex->num_block++; } @@ -2697,10 +2697,10 @@ static obj_skin_block_cloth* obj_classic_read_skin_block_cloth( obj_skin_block_cloth* cls = alloc->allocate(); uint32_t mesh_name_offset = s.read_uint32_t(); uint32_t backface_mesh_name_offset = s.read_uint32_t(); - cls->field_8 = s.read_int32_t(); - cls->num_root = s.read_int32_t(); - cls->num_node = s.read_int32_t(); - cls->field_14 = s.read_int32_t(); + cls->field_8 = s.read_uint32_t(); + cls->num_root = s.read_uint32_t(); + cls->num_node = s.read_uint32_t(); + cls->field_14 = s.read_uint32_t(); uint32_t mat_array_offset = s.read_uint32_t(); uint32_t root_array_offset = s.read_uint32_t(); uint32_t node_array_offset = s.read_uint32_t(); @@ -2986,7 +2986,7 @@ static obj_skin_block_constraint* obj_classic_read_skin_block_constraint( } free_def(name); - cns->coupling = (obj_skin_block_constraint_coupling)s.read_int32_t(); + cns->coupling = (obj_skin_block_constraint_coupling)s.read_uint32_t(); uint32_t source_node_name_offset = s.read_uint32_t(); cns->source_node_name = obj_read_utf8_string_null_terminated_offset(alloc, s, source_node_name_offset); @@ -3121,8 +3121,8 @@ static void obj_classic_write_skin_block_constraint(obj_skin_block_constraint* c static void obj_classic_read_skin_block_constraint_attach_point(obj_skin_block_constraint_attach_point* attach_point, stream& s, const char** str) { - attach_point->affected_by_orientation = s.read_int32_t() != 0; - attach_point->affected_by_scaling = s.read_int32_t() != 0; + attach_point->affected_by_orientation = s.read_uint32_t() != 0; + attach_point->affected_by_scaling = s.read_uint32_t() != 0; attach_point->offset.x = s.read_float_t(); attach_point->offset.y = s.read_float_t(); attach_point->offset.z = s.read_float_t(); @@ -3139,7 +3139,7 @@ static void obj_classic_write_skin_block_constraint_attach_point(obj_skin_block_ static void obj_classic_read_skin_block_constraint_up_vector(obj_skin_block_constraint_up_vector* up_vector, prj::shared_ptr alloc, stream& s, const char** str) { - up_vector->active = !!s.read_int32_t(); + up_vector->active = !!s.read_uint32_t(); up_vector->roll = s.read_float_t(); up_vector->affected_axis.x = s.read_float_t(); up_vector->affected_axis.y = s.read_float_t(); @@ -3184,7 +3184,7 @@ static obj_skin_block_expression* obj_classic_read_skin_block_expression( } free_def(name); - uint32_t num_expression = s.read_int32_t(); + uint32_t num_expression = s.read_uint32_t(); num_expression = min_def(num_expression, 9); exp->num_expression = num_expression; for (uint32_t i = 0; i < num_expression; i++) { @@ -3227,7 +3227,7 @@ static obj_skin_block_motion* obj_classic_read_skin_block_motion( obj_classic_read_skin_block_node(&mot->node, alloc, s, str); uint32_t name_offset = s.read_uint32_t(); - mot->num_node = s.read_int32_t(); + mot->num_node = s.read_uint32_t(); uint32_t bone_name_array_offset = s.read_uint32_t(); uint32_t bone_matrix_array_offset = s.read_uint32_t(); @@ -3363,12 +3363,12 @@ static obj_skin_block_osage* obj_classic_read_skin_block_osage( obj_skin_block_osage* osg = alloc->allocate(); obj_classic_read_skin_block_node(&osg->node, alloc, s, str); - osg->start_index = s.read_int32_t(); - osg->count = s.read_int32_t(); + osg->start_index = s.read_uint32_t(); + osg->count = s.read_uint32_t(); osg->external_name_index = s.read_uint32_t(); osg->name_index = s.read_uint32_t(); - int32_t offset = s.read_int32_t(); + uint32_t offset = s.read_uint32_t(); s.read(0, 0x14); osg->node_array = 0; @@ -3884,7 +3884,9 @@ static void obj_set_modern_read_inner(obj_set* set, prj::shared_ptrobj_num = s_mosd.read_int32_t_reverse_endianness(); - osh.last_obj_id = s_mosd.read_int32_t_reverse_endianness(); - osh.obj_data = s_mosd.read_offset_f2(st.header.length); - osh.obj_skin_data = s_mosd.read_offset_f2(st.header.length); - osh.obj_name_data = s_mosd.read_offset_f2(st.header.length); - osh.obj_id_data = s_mosd.read_offset_f2(st.header.length); - osh.tex_id_data = s_mosd.read_offset_f2(st.header.length); - set->tex_id_num = s_mosd.read_int32_t_reverse_endianness(); + set->obj_num = s_mosd.read_uint32_t_reverse_endianness(); + osh.last_obj_id = s_mosd.read_uint32_t_reverse_endianness(); + osh.obj_data = s_mosd.read_offset_f2(header_length); + osh.obj_skin_data = s_mosd.read_offset_f2(header_length); + osh.obj_name_data = s_mosd.read_offset_f2(header_length); + osh.obj_id_data = s_mosd.read_offset_f2(header_length); + osh.tex_id_data = s_mosd.read_offset_f2(header_length); + set->tex_id_num = s_mosd.read_uint32_t_reverse_endianness(); set->reserved[0] = s_mosd.read_uint32_t_reverse_endianness(); set->reserved[1] = s_mosd.read_uint32_t_reverse_endianness(); } else { - set->obj_num = s_mosd.read_int32_t_reverse_endianness(); - osh.last_obj_id = s_mosd.read_int32_t_reverse_endianness(); + set->obj_num = s_mosd.read_uint32_t_reverse_endianness(); + osh.last_obj_id = s_mosd.read_uint32_t_reverse_endianness(); osh.obj_data = s_mosd.read_offset_x(); osh.obj_skin_data = s_mosd.read_offset_x(); osh.obj_name_data = s_mosd.read_offset_x(); osh.obj_id_data = s_mosd.read_offset_x(); osh.tex_id_data = s_mosd.read_offset_x(); - set->tex_id_num = s_mosd.read_int32_t_reverse_endianness(); + set->tex_id_num = s_mosd.read_uint32_t_reverse_endianness(); set->reserved[0] = s_mosd.read_uint32_t_reverse_endianness(); set->reserved[1] = s_mosd.read_uint32_t_reverse_endianness(); } @@ -3949,7 +3939,7 @@ static void obj_set_modern_read_inner(obj_set* set, prj::shared_ptrbounding_sphere.center.y = s.read_float_t_reverse_endianness(); obj->bounding_sphere.center.z = s.read_float_t_reverse_endianness(); obj->bounding_sphere.radius = s.read_float_t_reverse_endianness(); - obj->num_mesh = s.read_int32_t_reverse_endianness(); + obj->num_mesh = s.read_uint32_t_reverse_endianness(); oh.mesh_array = s.read_offset_f2(header_length); - obj->num_material = s.read_int32_t_reverse_endianness(); + obj->num_material = s.read_uint32_t_reverse_endianness(); oh.material_array = s.read_offset_f2(header_length); obj->reserved[0] = s.read_uint32_t_reverse_endianness(); obj->reserved[1] = s.read_uint32_t_reverse_endianness(); @@ -4425,8 +4415,8 @@ static void obj_modern_read_model(obj* obj, prj::shared_ptrnum_mesh = s.read_int32_t_reverse_endianness(); - obj->num_material = s.read_int32_t_reverse_endianness(); + obj->num_mesh = s.read_uint32_t_reverse_endianness(); + obj->num_material = s.read_uint32_t_reverse_endianness(); obj->bounding_sphere.center.x = s.read_float_t_reverse_endianness(); obj->bounding_sphere.center.y = s.read_float_t_reverse_endianness(); obj->bounding_sphere.center.z = s.read_float_t_reverse_endianness(); @@ -4963,11 +4953,11 @@ static void obj_modern_read_model_mesh(obj_mesh* mesh, mesh->bounding_sphere.center.y = s.read_float_t_reverse_endianness(); mesh->bounding_sphere.center.z = s.read_float_t_reverse_endianness(); mesh->bounding_sphere.radius = s.read_float_t_reverse_endianness(); - mesh->num_submesh = s.read_int32_t_reverse_endianness(); + mesh->num_submesh = s.read_uint32_t_reverse_endianness(); mh.submesh_array = s.read_offset(header_length, is_x); mh.format = (obj_vertex_format_file)s.read_uint32_t_reverse_endianness(); - mh.size_vertex = s.read_int32_t_reverse_endianness(); - mh.num_vertex = s.read_int32_t_reverse_endianness(); + mh.size_vertex = s.read_uint32_t_reverse_endianness(); + mh.num_vertex = s.read_uint32_t_reverse_endianness(); if (!is_x) for (int64_t& i : mh.vertex) @@ -5013,12 +5003,12 @@ static void obj_modern_read_model_sub_mesh(obj_sub_mesh* sub_mesh, sub_mesh->bounding_sphere.radius = s.read_float_t_reverse_endianness(); sub_mesh->material_index = s.read_uint32_t_reverse_endianness(); s.read(&sub_mesh->uv_index, 0x08); - sub_mesh->num_bone_index = s.read_int32_t_reverse_endianness(); + sub_mesh->num_bone_index = s.read_uint32_t_reverse_endianness(); smh.bone_index_array_offset = s.read_offset(header_length, is_x); sub_mesh->bones_per_vertex = s.read_uint32_t_reverse_endianness(); sub_mesh->primitive_type = (obj_primitive_type)s.read_uint32_t_reverse_endianness(); sub_mesh->index_format = (obj_index_format)s.read_uint32_t_reverse_endianness(); - sub_mesh->num_index = s.read_int32_t_reverse_endianness(); + sub_mesh->num_index = s.read_uint32_t_reverse_endianness(); smh.index_array_offset = s.read_offset(0, is_x); sub_mesh->attrib.w = s.read_uint32_t_reverse_endianness(); s.read(0, 0x10); @@ -5060,7 +5050,7 @@ static obj_skin* obj_modern_read_skin(prj::shared_ptr allo sh.bone_matrix_array_offset = s.read_offset_f2(header_length); sh.bone_name_array_offset = s.read_offset_f2(header_length); sh.ex_data_offset = s.read_offset_f2(header_length); - sk->num_bone = s.read_int32_t_reverse_endianness(); + sk->num_bone = s.read_uint32_t_reverse_endianness(); sh.bone_parent_id_array_offset = s.read_offset_f2(header_length); s.read(0, 0x0C); } @@ -5069,7 +5059,7 @@ static obj_skin* obj_modern_read_skin(prj::shared_ptr allo sh.bone_matrix_array_offset = s.read_offset_x(); sh.bone_name_array_offset = s.read_offset_x(); sh.ex_data_offset = s.read_offset_x(); - sk->num_bone = s.read_int32_t_reverse_endianness(); + sk->num_bone = s.read_uint32_t_reverse_endianness(); sh.bone_parent_id_array_offset = s.read_offset_x(); s.read(0, 0x18); } @@ -6558,16 +6548,16 @@ static obj_skin_ex_data* obj_modern_read_skin_ex_data(prj::shared_ptrnum_osage_node = s.read_int32_t_reverse_endianness(); + exh.num_osage = s.read_uint32_t_reverse_endianness(); + ex->num_osage_node = s.read_uint32_t_reverse_endianness(); s.read(0, 0x04); exh.osage_node_array_offset = s.read_offset_f2(header_length); exh.osage_name_array_offset = s.read_offset_f2(header_length); exh.block_array_offset = s.read_offset_f2(header_length); - exh.num_bone_name = s.read_int32_t_reverse_endianness(); + exh.num_bone_name = s.read_uint32_t_reverse_endianness(); exh.bone_name_array_offset = s.read_offset_f2(header_length); exh.osage_sibling_info_array_offset = s.read_offset_f2(header_length); - exh.cloth_count = s.read_int32_t_reverse_endianness(); + exh.cloth_count = s.read_uint32_t_reverse_endianness(); ex->reserved[0] = s.read_offset_f2(header_length); ex->reserved[1] = s.read_offset_f2(header_length); ex->reserved[2] = s.read_offset_f2(header_length); @@ -6577,16 +6567,16 @@ static obj_skin_ex_data* obj_modern_read_skin_ex_data(prj::shared_ptrreserved[6] = s.read_offset_f2(header_length); } else { - exh.num_osage = s.read_int32_t_reverse_endianness(); - ex->num_osage_node = s.read_int32_t_reverse_endianness(); + exh.num_osage = s.read_uint32_t_reverse_endianness(); + ex->num_osage_node = s.read_uint32_t_reverse_endianness(); s.read(0, 0x08); exh.osage_node_array_offset = s.read_offset_x(); exh.osage_name_array_offset = s.read_offset_x(); exh.block_array_offset = s.read_offset_x(); - exh.num_bone_name = s.read_int32_t_reverse_endianness(); + exh.num_bone_name = s.read_uint32_t_reverse_endianness(); exh.bone_name_array_offset = s.read_offset_x(); exh.osage_sibling_info_array_offset = s.read_offset_x(); - exh.cloth_count = s.read_int32_t_reverse_endianness(); + exh.cloth_count = s.read_uint32_t_reverse_endianness(); ex->reserved[0] = s.read_offset_x(); ex->reserved[1] = s.read_offset_x(); ex->reserved[2] = s.read_offset_x(); @@ -6643,7 +6633,7 @@ static obj_skin_ex_data* obj_modern_read_skin_ex_data(prj::shared_ptrnum_block = 0; s.set_position(exh.block_array_offset, SEEK_SET); if (!is_x) - while (s.read_int32_t()) { + while (s.read_uint32_t()) { s.read(0, 0x04); ex->num_block++; } @@ -6740,10 +6730,10 @@ static obj_skin_block_cloth* obj_modern_read_skin_block_cloth( obj_skin_block_cloth* cls = alloc->allocate(); int64_t mesh_name_offset = s.read_offset(header_length, is_x); int64_t backface_mesh_name_offset = s.read_offset(header_length, is_x); - cls->field_8 = s.read_int32_t_reverse_endianness(); - cls->num_root = s.read_int32_t_reverse_endianness(); - cls->num_node = s.read_int32_t_reverse_endianness(); - cls->field_14 = s.read_int32_t_reverse_endianness(); + cls->field_8 = s.read_uint32_t_reverse_endianness(); + cls->num_root = s.read_uint32_t_reverse_endianness(); + cls->num_node = s.read_uint32_t_reverse_endianness(); + cls->field_14 = s.read_uint32_t_reverse_endianness(); int64_t mat_array_offset = s.read_offset(header_length, is_x); int64_t root_array_offset = s.read_offset(header_length, is_x); int64_t node_array_offset = s.read_offset(header_length, is_x); @@ -6763,8 +6753,8 @@ static obj_skin_block_cloth* obj_modern_read_skin_block_cloth( for (uint32_t i = 0; i < num_root; i++) { s.read(0x28); for (uint32_t j = 0; j < 4; j++) { - uint32_t name_offset = s.read_uint32_t(); - int32_t matrix_index = s.read_int32_t(); + uint32_t name_offset = s.read_uint32_t_reverse_endianness(); + int32_t matrix_index = s.read_int32_t_reverse_endianness(); if (name_offset&& max_matrix_index < matrix_index) max_matrix_index = matrix_index; } @@ -7067,7 +7057,7 @@ static obj_skin_block_constraint* obj_modern_read_skin_block_constraint( } free_def(name); - cns->coupling = (obj_skin_block_constraint_coupling)s.read_int32_t_reverse_endianness(); + cns->coupling = (obj_skin_block_constraint_coupling)s.read_uint32_t_reverse_endianness(); int64_t source_node_name_offset = s.read_offset(header_length, is_x); cns->source_node_name = obj_read_utf8_string_null_terminated_offset(alloc, s, source_node_name_offset); @@ -7202,8 +7192,8 @@ static void obj_modern_write_skin_block_constraint(obj_skin_block_constraint* cn static void obj_modern_read_skin_block_constraint_attach_point(obj_skin_block_constraint_attach_point* attach_point, stream& s, uint32_t header_length, const char** str, bool is_x) { - attach_point->affected_by_orientation = s.read_int32_t_reverse_endianness() != 0; - attach_point->affected_by_scaling = s.read_int32_t_reverse_endianness() != 0; + attach_point->affected_by_orientation = s.read_uint32_t_reverse_endianness() != 0; + attach_point->affected_by_scaling = s.read_uint32_t_reverse_endianness() != 0; attach_point->offset.x = s.read_float_t_reverse_endianness(); attach_point->offset.y = s.read_float_t_reverse_endianness(); attach_point->offset.z = s.read_float_t_reverse_endianness(); @@ -7220,7 +7210,7 @@ static void obj_modern_write_skin_block_constraint_attach_point(obj_skin_block_c static void obj_modern_read_skin_block_constraint_up_vector(obj_skin_block_constraint_up_vector* up_vector, prj::shared_ptr alloc, stream& s, uint32_t header_length, const char** str, bool is_x) { - up_vector->active = !!s.read_int32_t_reverse_endianness(); + up_vector->active = !!s.read_uint32_t_reverse_endianness(); up_vector->roll = s.read_float_t_reverse_endianness(); up_vector->affected_axis.x = s.read_float_t_reverse_endianness(); up_vector->affected_axis.y = s.read_float_t_reverse_endianness(); @@ -7265,7 +7255,7 @@ static obj_skin_block_expression* obj_modern_read_skin_block_expression( } free_def(name); - uint32_t num_expression = s.read_int32_t_reverse_endianness(); + uint32_t num_expression = s.read_uint32_t_reverse_endianness(); num_expression = min_def(num_expression, 9); exp->num_expression = num_expression; if (!is_x) @@ -7328,7 +7318,7 @@ static obj_skin_block_motion* obj_modern_read_skin_block_motion( obj_modern_read_skin_block_node(&mot->node, alloc, s, header_length, str, is_x); int64_t name_offset = s.read_offset(header_length, is_x); - mot->num_node = s.read_int32_t_reverse_endianness(); + mot->num_node = s.read_uint32_t_reverse_endianness(); int64_t bone_name_array_offset = s.read_offset(header_length, is_x); int64_t bone_matrix_array_offset = s.read_offset(header_length, is_x); @@ -7476,8 +7466,8 @@ static obj_skin_block_osage* obj_modern_read_skin_block_osage( obj_skin_block_osage* osg = alloc->allocate(); obj_modern_read_skin_block_node(&osg->node, alloc, s, header_length, str, is_x); - osg->start_index = s.read_int32_t_reverse_endianness(); - osg->count = s.read_int32_t_reverse_endianness(); + osg->start_index = s.read_uint32_t_reverse_endianness(); + osg->count = s.read_uint32_t_reverse_endianness(); osg->external_name_index = s.read_uint32_t_reverse_endianness(); osg->name_index = s.read_uint32_t_reverse_endianness(); diff --git a/src/KKdLib/prj/vector_pair.hpp b/src/KKdLib/prj/vector_pair.hpp index c666e55d..cb7e01fc 100644 --- a/src/KKdLib/prj/vector_pair.hpp +++ b/src/KKdLib/prj/vector_pair.hpp @@ -47,7 +47,24 @@ namespace prj { unique(); } - inline typename auto find(T key) { + 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; @@ -64,7 +81,24 @@ namespace prj { return k; } - inline typename auto find(T key) const { + 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; diff --git a/src/KKdLib/prj/vector_pair_combine.hpp b/src/KKdLib/prj/vector_pair_combine.hpp index 75811dc8..804774b7 100644 --- a/src/KKdLib/prj/vector_pair_combine.hpp +++ b/src/KKdLib/prj/vector_pair_combine.hpp @@ -16,10 +16,12 @@ namespace prj { class vector_pair_combine { public: using value_pair = std::pair; + using iterator = typename std::vector::iterator; + using const_iterator = typename std::vector::const_iterator; std::vector data; std::vector new_data; - inline typename auto find(T key) { + inline auto find(T& key) { auto k = data.begin(); size_t l = data.size(); size_t temp; @@ -36,7 +38,7 @@ namespace prj { return k; } - inline typename auto find(T key) const { + inline auto find(const T& key) const { auto k = data.begin(); size_t l = data.size(); size_t temp; @@ -53,14 +55,46 @@ namespace prj { return k; } + inline auto find(T&& key) { + auto k = data.begin(); + size_t l = data.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 == data.end() || key < k->first) + return data.end(); + return k; + } + + inline auto find(T&& key) const { + auto k = data.begin(); + size_t l = data.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 == data.end() || key < k->first) + return data.end(); + return k; + } + inline void combine() { - if (new_data.size() <= 1) - return; - - std::sort(data.begin(), data.end(), - [](const value_pair& a, const value_pair& b) { - return a.first < b.first; - }); + if (data.size() > 1) + std::sort(data.begin(), data.end(), + [](const value_pair& a, const value_pair& b) { + return a.first < b.first; + }); for (auto& i : new_data) { auto elem = find(i.first); @@ -72,75 +106,74 @@ namespace prj { new_data.clear(); - if (data.size() <= 1) - return; + if (data.size() > 1) { + std::sort(data.begin(), data.end(), + [](const value_pair& a, const value_pair& b) { + return a.first < b.first; + }); - std::sort(data.begin(), data.end(), - [](const value_pair& a, const value_pair& b) { - return a.first < b.first; - }); + auto begin = data.begin(); + auto end = data.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++; + } - auto begin = data.begin(); - auto end = data.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 (data.size() != end - begin) - data.resize(end - begin); + if (data.size() != end - begin) + data.resize(end - begin); + } } - inline typename auto begin() { + inline auto begin() { return data.begin(); } - inline typename auto begin() const { + inline auto begin() const { return data.begin(); } - inline typename auto cbegin() const { + inline auto cbegin() const { return data.cbegin(); } - inline typename auto end() { + inline auto end() { return data.end(); } - inline typename auto end() const { + inline auto end() const { return data.end(); } - inline typename auto cend() const { + inline auto cend() const { return data.cend(); } - inline typename auto rbegin() { + inline auto rbegin() { return data.rbegin(); } - inline typename auto rbegin() const { + inline auto rbegin() const { return data.rbegin(); } - inline typename auto crbegin() const { + inline auto crbegin() const { return data.crbegin(); } - inline typename auto rend() { + inline auto rend() { return data.rend(); } - inline typename auto rend() const { + inline auto rend() const { return data.rend(); } - inline typename auto crend() const { + inline auto crend() const { return data.crend(); } @@ -152,6 +185,24 @@ namespace prj { new_data.push_back(value); } + inline auto erase(const_iterator where) noexcept { + return data.erase(where); + } + + inline auto erase(const_iterator first, const_iterator last) noexcept { + return data.erase(first, last); + } + + inline void clear() noexcept { + data.clear(); + new_data.clear(); + } + + inline void shrink_to_fit() noexcept { + data.shrink_to_fit(); + new_data.shrink_to_fit(); + } + inline void reserve(size_t new_capacity) { new_data.reserve(new_capacity); } @@ -160,12 +211,36 @@ namespace prj { return data.size(); } - value_pair& operator[](const size_t pos) noexcept { + inline value_pair& operator[](const size_t pos) noexcept { return data[pos]; } - const value_pair& operator[](const size_t pos) const noexcept { + inline const value_pair& operator[](const size_t pos) const noexcept { return data[pos]; } + + inline value_pair& at(const size_t pos) { + return data.at(pos); + } + + inline const value_pair& at(const size_t pos) const { + return data.at(pos); + } + + inline value_pair& front() noexcept { + return data.front(); + } + + inline const value_pair& front() const noexcept { + return data.front(); + } + + inline value_pair& back() noexcept { + return data.back(); + } + + inline const value_pair& back() const noexcept { + return data.back(); + } }; } diff --git a/src/KKdLib/spr.cpp b/src/KKdLib/spr.cpp new file mode 100644 index 00000000..6fd1f6dd --- /dev/null +++ b/src/KKdLib/spr.cpp @@ -0,0 +1,270 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#include +#include "spr.hpp" +#include "f2/struct.hpp" +#include "io/path.hpp" +#include "io/memory_stream.hpp" + +struct spr_layer_header { + int64_t markers_offset; + int64_t video_offset; + int64_t audio_offset; +}; + +struct spr_scene_header { + int64_t camera_offset; + int64_t comp_offset; + int64_t video_offset; + int64_t audio_offset; +}; + +static void spr_set_classic_read_inner(spr_set* ss, + prj::shared_ptr& alloc, const void* data, size_t size); +static void spr_set_classic_write_inner(spr_set* ss, void** data, size_t* size); +static void spr_set_modern_read_inner(spr_set* ss, + prj::shared_ptr& alloc, const void* data, size_t size); +static void spr_set_modern_write_inner(spr_set* ss, void** data, size_t* size); + +static const char* spr_move_data_string(const char* str, + prj::shared_ptr& alloc); + +static const char* spr_read_utf8_string_null_terminated_offset( + prj::shared_ptr& alloc, stream& s, int64_t offset); + +spr_set::spr_set() : ready(), modern(), big_endian(), is_x(), flag(), texofs(), +num_of_texture(), num_of_sprite(), sprinfo(), texname(), sprname(), sprdata(), txp() { + +} + +void spr_set::move_data(spr_set* set_src, prj::shared_ptr alloc) { + +} + +void spr_set::pack_file(void** data, size_t* size) { + if (!data || !ready) + return; + + if (!modern) + spr_set_classic_write_inner(this, data, size); + else + spr_set_modern_write_inner(this, data, size); +} + +void spr_set::unpack_file(prj::shared_ptr alloc, const void* data, size_t size, bool modern) { + if (!data || !size) + return; + + if (!modern) + spr_set_classic_read_inner(this, alloc, data, size); + else + spr_set_modern_read_inner(this, alloc, data, size); +} + +static void spr_set_classic_read_inner(spr_set* ss, + prj::shared_ptr& alloc, const void* data, size_t size) { + memory_stream s; + s.open(data, size); + + ss->flag = s.read_uint32_t(); + uint32_t texofs = s.read_uint32_t(); + ss->num_of_texture = s.read_uint32_t(); + ss->num_of_sprite = s.read_uint32_t(); + uint32_t sprinfo_offset = s.read_uint32_t(); + uint32_t texname_offset = s.read_uint32_t(); + uint32_t sprname_offset = s.read_uint32_t(); + uint32_t sprdata_offset = s.read_uint32_t(); + + spr::SprInfo* sprinfo = alloc->allocate(ss->num_of_sprite); + ss->sprinfo = sprinfo; + + s.set_position(sprinfo_offset, SEEK_SET); + for (uint32_t i = ss->num_of_sprite; i; i--, sprinfo++) { + sprinfo->texid = s.read_uint32_t(); + sprinfo->rotate = s.read_int32_t(); + sprinfo->su = s.read_float_t(); + sprinfo->sv = s.read_float_t(); + sprinfo->eu = s.read_float_t(); + sprinfo->ev = s.read_float_t(); + sprinfo->px = s.read_float_t(); + sprinfo->py = s.read_float_t(); + sprinfo->width = s.read_float_t(); + sprinfo->height = s.read_float_t(); + } + + const char** texname = alloc->allocate(ss->num_of_texture); + ss->texname = texname; + + s.set_position(texname_offset, SEEK_SET); + for (uint32_t i = ss->num_of_texture; i; i--, texname++) + *texname = spr_read_utf8_string_null_terminated_offset(alloc, s, s.read_uint32_t()); + + const char** sprname = alloc->allocate(ss->num_of_sprite); + ss->sprname = sprname; + + s.set_position(sprname_offset, SEEK_SET); + for (uint32_t i = ss->num_of_sprite; i; i--, sprname++) + *sprname = spr_read_utf8_string_null_terminated_offset(alloc, s, s.read_uint32_t()); + + SpriteData* sprdata = alloc->allocate(ss->num_of_sprite); + ss->sprdata = sprdata; + + s.set_position(sprdata_offset, SEEK_SET); + for (uint32_t i = ss->num_of_sprite; i; i--, sprdata++) { + sprdata->attr = s.read_uint32_t(); + sprdata->resolution_mode = (resolution_mode)s.read_uint32_t(); + } + s.close(); + + ss->txp = new txp_set; + ss->txp->unpack_file((const void*)((size_t)data + texofs), false); + + ss->ready = true; + ss->modern = false; + ss->big_endian = false; + ss->is_x = false; +} + +static void spr_set_classic_write_inner(spr_set* ss, void** data, size_t* size) { + +} + +static void spr_set_modern_read_inner(spr_set* ss, + prj::shared_ptr& alloc, const void* data, size_t size) { + f2_struct st; + st.read(data, size); + if (st.header.signature != reverse_endianness_uint32_t('SPRC') || !st.data.size()) + return; + + uint32_t header_length = st.header.length; + bool big_endian = st.header.use_big_endian; + bool is_x = st.pof.shift_x; + + memory_stream s_sprc; + s_sprc.open(st.data); + s_sprc.big_endian = big_endian; + + ss->flag = s_sprc.read_uint32_t_reverse_endianness(); + uint32_t texofs = s_sprc.read_uint32_t_reverse_endianness(); + ss->num_of_texture = s_sprc.read_uint32_t_reverse_endianness(); + ss->num_of_sprite = s_sprc.read_uint32_t_reverse_endianness(); + int64_t sprinfo_offset = s_sprc.read_offset(header_length, is_x); + int64_t texname_offset = s_sprc.read_offset(header_length, is_x); + int64_t sprname_offset = s_sprc.read_offset(header_length, is_x); + int64_t sprdata_offset = s_sprc.read_offset(header_length, is_x); + + spr::SprInfo* sprinfo = alloc->allocate(ss->num_of_sprite); + ss->sprinfo = sprinfo; + + s_sprc.set_position(sprinfo_offset, SEEK_SET); + for (uint32_t i = ss->num_of_sprite; i; i--, sprinfo++) { + sprinfo->texid = s_sprc.read_uint32_t_reverse_endianness(); + sprinfo->rotate = s_sprc.read_int32_t_reverse_endianness(); + sprinfo->su = s_sprc.read_float_t_reverse_endianness(); + sprinfo->sv = s_sprc.read_float_t_reverse_endianness(); + sprinfo->eu = s_sprc.read_float_t_reverse_endianness(); + sprinfo->ev = s_sprc.read_float_t_reverse_endianness(); + sprinfo->px = s_sprc.read_float_t_reverse_endianness(); + sprinfo->py = s_sprc.read_float_t_reverse_endianness(); + sprinfo->width = s_sprc.read_float_t_reverse_endianness(); + sprinfo->height = s_sprc.read_float_t_reverse_endianness(); + } + + const char** texname = alloc->allocate(ss->num_of_texture); + ss->texname = texname; + + s_sprc.set_position(texname_offset, SEEK_SET); + if (!is_x) + for (uint32_t i = ss->num_of_texture; i; i--, texname++) + *texname = spr_read_utf8_string_null_terminated_offset( + alloc, s_sprc, s_sprc.read_offset_f2(header_length)); + else + for (uint32_t i = ss->num_of_texture; i; i--, texname++) + *texname = spr_read_utf8_string_null_terminated_offset( + alloc, s_sprc, s_sprc.read_offset_x()); + + const char** sprname = alloc->allocate(ss->num_of_sprite); + ss->sprname = sprname; + + s_sprc.set_position(sprname_offset, SEEK_SET); + if (!is_x) + for (uint32_t i = ss->num_of_sprite; i; i--, sprname++) + *sprname = spr_read_utf8_string_null_terminated_offset( + alloc, s_sprc, s_sprc.read_offset_f2(header_length)); + else + for (uint32_t i = ss->num_of_sprite; i; i--, sprname++) + *sprname = spr_read_utf8_string_null_terminated_offset( + alloc, s_sprc, s_sprc.read_offset_x()); + + SpriteData* sprdata = alloc->allocate(ss->num_of_sprite); + ss->sprdata = sprdata; + + s_sprc.set_position(sprdata_offset, SEEK_SET); + for (uint32_t i = ss->num_of_sprite; i; i--, sprdata++) { + sprdata->attr = s_sprc.read_uint32_t_reverse_endianness(); + sprdata->resolution_mode = (resolution_mode)s_sprc.read_uint32_t_reverse_endianness(); + } + s_sprc.close(); + + texofs = st.header.data_size + 0x20; + + ss->txp = new txp_set; + ss->txp->unpack_file_modern((const void*)((size_t)data + texofs), size - texofs, 'TXPC'); + + ss->ready = true; + ss->modern = true; + ss->big_endian = big_endian; + ss->is_x = is_x; +} + +static void spr_set_modern_write_inner(spr_set* ss, void** data, size_t* size) { + bool big_endian = ss->big_endian; + bool is_x = ss->is_x; + + memory_stream s_sprc; + s_sprc.open(); + s_sprc.big_endian = big_endian; + + uint32_t off; + enrs e; + enrs_entry ee; + pof pof; + + off = align_val(0, 0x10); + + f2_struct st; + s_sprc.align_write(0x10); + s_sprc.copy(st.data); + s_sprc.close(); + + st.enrs = e; + st.pof = pof; + + st.header.signature = reverse_endianness_uint32_t('SPRC'); + st.header.length = 0x20; + st.header.use_big_endian = big_endian; + st.header.use_section_size = true; + + st.write(data, size, true, is_x); +} + +inline static const char* spr_move_data_string(const char* str, + prj::shared_ptr& alloc) { + if (str) + return alloc->allocate(str, utf8_length(str) + 1); + return 0; +} + +inline static const char* spr_read_utf8_string_null_terminated_offset( + prj::shared_ptr& alloc, stream& s, int64_t offset) { + size_t len = s.read_utf8_string_null_terminated_offset_length(offset); + char* str = alloc->allocate(len + 1); + s.position_push(offset, SEEK_SET); + s.read(str, len); + s.position_pop(); + str[len] = 0; + return str; +} diff --git a/src/KKdLib/spr.hpp b/src/KKdLib/spr.hpp new file mode 100644 index 00000000..a233c123 --- /dev/null +++ b/src/KKdLib/spr.hpp @@ -0,0 +1,113 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#pragma once + +#include "default.hpp" +#include "prj/shared_ptr.hpp" +#include "prj/stack_allocator.hpp" +#include "txp.hpp" + +enum resolution_mode { + 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_QHD = 0x0F, + RESOLUTION_MODE_WQVGA = 0x10, + RESOLUTION_MODE_qHD = 0x11, + 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,*/ +}; + +namespace spr { + 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 SpriteData { + uint32_t attr; + resolution_mode resolution_mode; +}; + +struct spr_set { + bool ready; + bool modern; + bool big_endian; + bool is_x; + + uint32_t flag; + uint32_t texofs; + int32_t num_of_texture; + int32_t num_of_sprite; + spr::SprInfo* sprinfo; + const char** texname; + const char** sprname; + SpriteData* sprdata; + + txp_set* txp; + + spr_set(); + + void move_data(spr_set* set_src, prj::shared_ptr alloc); + void pack_file(void** data, size_t* size); + void unpack_file(prj::shared_ptr alloc, const void* data, size_t size, bool modern); +}; diff --git a/src/KKdLib/txp.cpp b/src/KKdLib/txp.cpp index 96f52635..da4e81e6 100644 --- a/src/KKdLib/txp.cpp +++ b/src/KKdLib/txp.cpp @@ -245,7 +245,7 @@ bool txp_set::pack_file(std::vector& data, bool big_endian) { return true; } -bool txp_set::pack_file_modern(void** data, size_t* size, bool big_endian) { +bool txp_set::pack_file_modern(void** data, size_t* size, bool big_endian, uint32_t signature) { f2_struct st; if (!pack_file(st.data, big_endian)) { *data = 0; @@ -255,7 +255,7 @@ bool txp_set::pack_file_modern(void** data, size_t* size, bool big_endian) { produce_enrs(&st.enrs); - st.header.signature = reverse_endianness_uint32_t('MTXD'); + st.header.signature = reverse_endianness_uint32_t(signature); st.header.length = 0x20; st.header.use_big_endian = big_endian; st.header.use_section_size = true; @@ -415,11 +415,11 @@ bool txp_set::unpack_file(const void* data, bool big_endian) { return true; } -bool txp_set::unpack_file_modern(const void* data, size_t size) { +bool txp_set::unpack_file_modern(const void* data, size_t size, uint32_t signature) { bool ret = false; f2_struct st; st.read(data, size); - if (st.header.signature == reverse_endianness_uint32_t('MTXD')) + if (st.header.signature == reverse_endianness_uint32_t(signature)) ret = unpack_file(st.data.data(), st.header.use_big_endian); return ret; } diff --git a/src/KKdLib/txp.hpp b/src/KKdLib/txp.hpp index 410294b8..68e6a5fc 100644 --- a/src/KKdLib/txp.hpp +++ b/src/KKdLib/txp.hpp @@ -57,8 +57,8 @@ struct txp_set { bool pack_file(void** data, size_t* size, bool big_endian); bool pack_file(std::vector& data, bool big_endian); - bool pack_file_modern(void** data, size_t* size, bool big_endian); + bool pack_file_modern(void** data, size_t* size, bool big_endian, uint32_t signature); bool produce_enrs(enrs* enrs); bool unpack_file(const void* data, bool big_endian); - bool unpack_file_modern(const void* data, size_t size); + bool unpack_file_modern(const void* data, size_t size, uint32_t signature); }; diff --git a/src/ReDIVA/classes/glitter_editor.cpp b/src/ReDIVA/classes/glitter_editor.cpp index 9f2ed8a3..8bb95dea 100644 --- a/src/ReDIVA/classes/glitter_editor.cpp +++ b/src/ReDIVA/classes/glitter_editor.cpp @@ -6084,6 +6084,14 @@ static void glitter_editor_curve_editor_window(GlitterEditor* glt_edt) { } } + float_t scale; + if (curve->type >= Glitter::CURVE_ROTATION_X && curve->type <= Glitter::CURVE_ROTATION_Z) + scale = RAD_TO_DEG_FLOAT; + else if (curve->type >= Glitter::CURVE_COLOR_R && curve->type <= Glitter::CURVE_COLOR_RGB_SCALE_2ND) + scale = 255.0f; + else + scale = 1.0f; + float_t max = crv_edt->range * (1.0f / crv_edt->zoom_value); float_t min; if (curve->type == Glitter::CURVE_EMISSION_INTERVAL) { @@ -6419,7 +6427,7 @@ static void glitter_editor_curve_editor_window(GlitterEditor* glt_edt) { draw_list->AddLine({ x_pos, y_pos }, { x_pos + canvas_size.x, y_pos }, line_color, 0.80f); - float_t val = max - j * 0.25f * (max - min); + float_t val = (max - j * 0.25f * (max - min)) * scale; char buf[0x20]; snprintf(buf, sizeof(buf), "%.2f", val); draw_list->AddText({ x_pos + 2, y_pos + (last ? -16 : -2) }, diff --git a/src/ReDIVA/data_edit.cpp b/src/ReDIVA/data_edit.cpp index 741bb631..23a35b75 100644 --- a/src/ReDIVA/data_edit.cpp +++ b/src/ReDIVA/data_edit.cpp @@ -348,10 +348,8 @@ void DataEdit::Auth3D::Reset() { object_set.clear(); id = -1; - obj_db.object_set.clear(); - obj_db.object_set.shrink_to_fit(); - tex_db.texture.clear(); - tex_db.texture.shrink_to_fit(); + obj_db.clear(); + tex_db.clear(); } DataEdit::DataEdit() : state(), play(), sound_play(), frame(), frame_count() { diff --git a/src/ReDIVA/data_initialize.cpp b/src/ReDIVA/data_initialize.cpp index 49ec5657..685f2364 100644 --- a/src/ReDIVA/data_initialize.cpp +++ b/src/ReDIVA/data_initialize.cpp @@ -47,9 +47,9 @@ bool TaskDataInit::Ctrl() { state = 1; } break; case 1: - if (sprite_manager_load_file(4, aft_spr_db) - || sprite_manager_load_file(472, aft_spr_db) - || sprite_manager_load_file(43, aft_spr_db) + if (!sprite_manager_load_file(4, aft_spr_db) + && !sprite_manager_load_file(472, aft_spr_db) + && !sprite_manager_load_file(43, aft_spr_db) /* || fontmap_data_parse_file()*/) state = field_6C ? 2 : 4; break; diff --git a/src/ReDIVA/data_test/auth_2d_test.cpp b/src/ReDIVA/data_test/auth_2d_test.cpp index 708165b0..532c7d1c 100644 --- a/src/ReDIVA/data_test/auth_2d_test.cpp +++ b/src/ReDIVA/data_test/auth_2d_test.cpp @@ -341,7 +341,7 @@ DtwAet::DtwAet() : Shell(0) { set = new dw::ListBox(this); - for (size_t i = aft_aet_db->aet_set_ids.size(), j = 0; i; i--, j++) { + for (size_t i = aft_aet_db->aet_set_names.size(), j = 0; i; i--, j++) { uint32_t set_id = aft_aet_db->get_aet_set_id_by_name_index((uint32_t)j); const aet_db_aet_set* set = aft_aet_db->get_aet_set_by_id(set_id); this->set->list->AddItem(set->name); diff --git a/src/ReDIVA/game_state.cpp b/src/ReDIVA/game_state.cpp index 450d22b4..090ec798 100644 --- a/src/ReDIVA/game_state.cpp +++ b/src/ReDIVA/game_state.cpp @@ -992,10 +992,11 @@ bool SubGameState::DataInitialize::Dest() { } bool SubGameState::SystemStartup::Init() { - task_system_startup_init(); - task_system_startup_add_task(); - task_pv_db_add_task(); - return true; + if (task_system_startup_add_task()) { + task_pv_db_add_task(); + return true; + } + return false; } bool SubGameState::SystemStartup::Ctrl() { @@ -1003,10 +1004,11 @@ bool SubGameState::SystemStartup::Ctrl() { } bool SubGameState::SystemStartup::Dest() { - task_system_startup_del_task(); - task_system_startup_free(); - game_state_set_sub_game_state_next(SUB_GAME_STATE_WARNING); - return true; + if (task_system_startup_del_task()) { + game_state_set_sub_game_state_next(SUB_GAME_STATE_WARNING); + return true; + } + return false; } bool SubGameState::SystemStartupError::Init() { diff --git a/src/ReDIVA/pv_game.cpp b/src/ReDIVA/pv_game.cpp index 0dc1bcbd..db566be6 100644 --- a/src/ReDIVA/pv_game.cpp +++ b/src/ReDIVA/pv_game.cpp @@ -511,7 +511,9 @@ void TaskPvGame::Disp() { } bool task_pv_game_add_task(TaskPvGame::Args& args) { - task_pv_game->data.Reset(); + return true; + if (!task_pv_game) + task_pv_game = new TaskPvGame; task_pv_game->data.field_0 = 1; task_pv_game->data.init_data = args.init_data; @@ -547,8 +549,12 @@ bool task_pv_game_check_task_ready() { } bool task_pv_game_del_task() { - if (!app::TaskWork::CheckTaskReady(task_pv_game)) + return true; + if (!app::TaskWork::CheckTaskReady(task_pv_game)) { + delete task_pv_game; + task_pv_game = 0; return true; + } task_pv_game->DelTask(); return false; diff --git a/src/ReDIVA/render.cpp b/src/ReDIVA/render.cpp index 14d8ef7c..8be6159a 100644 --- a/src/ReDIVA/render.cpp +++ b/src/ReDIVA/render.cpp @@ -721,7 +721,7 @@ static render_context* render_context_load() { continue; txp_set txp_set; - if (!txp_set.unpack_file_modern(txd->data, txd->size)) + if (!txp_set.unpack_file_modern(txd->data, txd->size, 'MTXD')) continue; object_database_file obj_db_file; @@ -814,7 +814,7 @@ static render_context* render_context_load() { continue; txp_set txp_set; - if (!txp_set.unpack_file_modern(txd->data, txd->size)) + if (!txp_set.unpack_file_modern(txd->data, txd->size, 'MTXD')) continue; object_database_file obj_db_file; @@ -1018,7 +1018,7 @@ static void render_context_ctrl(render_context* rctx) { game_state_set_game_state_next(GAME_STATE_GAME); else if (Input::IsKeyTapped(GLFW_KEY_F6)) { game_state_set_game_state_next(GAME_STATE_DATA_TEST); - game_state_set_sub_game_state_next(SUB_GAME_STATE_DATA_TEST_STG); + game_state_set_sub_game_state_next(SUB_GAME_STATE_DATA_TEST_AUTH_3D); } else if (Input::IsKeyTapped(GLFW_KEY_F7)) game_state_set_game_state_next(GAME_STATE_TEST_MODE); diff --git a/src/ReDIVA/system_startup.cpp b/src/ReDIVA/system_startup.cpp index dde8c28a..436b0c9e 100644 --- a/src/ReDIVA/system_startup.cpp +++ b/src/ReDIVA/system_startup.cpp @@ -101,17 +101,22 @@ namespace system_startup_detail { } } -void task_system_startup_init() { +bool task_system_startup_add_task() { if (!task_system_startup) task_system_startup = new system_startup_detail::TaskSystemStartup; -} -bool task_system_startup_add_task() { return app::TaskWork::AddTask(task_system_startup, "SYSTEM_STARTUP"); } bool task_system_startup_del_task() { - return task_system_startup->DelTask(); + if (!app::TaskWork::CheckTaskReady(task_system_startup)) { + delete task_system_startup; + task_system_startup = 0; + return true; + } + + task_system_startup->DelTask(); + return false; } void task_system_startup_free() { diff --git a/src/ReDIVA/system_startup.hpp b/src/ReDIVA/system_startup.hpp index bdcf31f9..fb9d1d98 100644 --- a/src/ReDIVA/system_startup.hpp +++ b/src/ReDIVA/system_startup.hpp @@ -25,7 +25,5 @@ namespace system_startup_detail { extern int32_t system_startup_ready; -extern void task_system_startup_init(); extern bool task_system_startup_add_task(); extern bool task_system_startup_del_task(); -extern void task_system_startup_free(); diff --git a/src/ReDIVA/x_pv_game.cpp b/src/ReDIVA/x_pv_game.cpp index 9eb61197..0925e78f 100644 --- a/src/ReDIVA/x_pv_game.cpp +++ b/src/ReDIVA/x_pv_game.cpp @@ -17,8 +17,10 @@ #include "../CRE/pv_param.hpp" #include "../CRE/random.hpp" #include "../CRE/sound.hpp" +#include "../CRE/sprite.hpp" #include "../CRE/task_effect.hpp" #include "../KKdLib/io/file_stream.hpp" +#include "../KKdLib/prj/algorithm.hpp" #include "../KKdLib/farc.hpp" #include "../KKdLib/interpolation.hpp" #include "../KKdLib/sort.hpp" @@ -217,6 +219,8 @@ struct dof_cam { }; #endif +static int32_t aet_index_table[] = { 0, 1, 2, 6, 5 }; + #if DOF_BAKE dof_cam dof_cam_data; #endif @@ -225,6 +229,8 @@ XPVGameSelector x_pv_game_selector; extern render_context* rctx_ptr; +static vec4 bright_scale_get(int32_t index, float_t value); + static float_t dsc_time_to_frame(int64_t time); static void x_pv_game_chara_item_alpha_callback(void* data, int32_t chara_id, int32_t type, float_t alpha); static void x_pv_game_change_field(x_pv_game* xpvgm, int32_t field, int64_t dsc_time, int64_t curr_time); @@ -1912,10 +1918,8 @@ void x_pv_game_data::reset() { exp_file.clear(); //dof = {}; stage = 0; - obj_db.object_set.clear(); - obj_db.object_set.shrink_to_fit(); - tex_db.texture.clear(); - tex_db.texture.shrink_to_fit(); + obj_db.clear(); + tex_db.clear(); sound_work_release_stream(0); } @@ -1923,6 +1927,7 @@ void x_pv_game_data::reset() { void x_pv_game_data::stop() { camera.stop(); stage->reset_stage_effect(); + stage->reset_stage_env(); effect.stop(); chara_effect.stop(); dsc_data.reset(); @@ -1940,10 +1945,8 @@ void x_pv_game_data::unload() { //dof = {}; dsc_data.unload(); pv_expression_file_unload(exp_file.hash_murmurhash); - obj_db.object_set.clear(); - obj_db.object_set.shrink_to_fit(); - tex_db.texture.clear(); - tex_db.texture.shrink_to_fit(); + obj_db.clear(); + tex_db.clear(); state = 40; } @@ -1952,6 +1955,497 @@ void x_pv_game_data::unload_if_state_is_0() { unload(); } +PVStageFrameRateControl::PVStageFrameRateControl() { + delta_frame = 1.0f; +} + +PVStageFrameRateControl::~PVStageFrameRateControl() { + +} + +float_t PVStageFrameRateControl::GetDeltaFrame() { + return delta_frame; +} + +aet_obj_data::aet_obj_data() : field_20(), loop(), hidden(), field_2A(), frame_rate_control() { + hash = hash_murmurhash_empty; + + reset(); +} + +aet_obj_data::~aet_obj_data() { + reset(); +} + +bool aet_obj_data::check_disp() { + return aet_manager_get_obj_disp(id); +} + +uint32_t aet_obj_data::init(AetArgs& args, const aet_database* aet_db) { + reset(); + + hash = args.id.id; + layer_name.assign(args.layer_name); + id = aet_manager_init_aet_object(args, aet_db); + if (!id) + return 0; + + aet_manager_set_obj_frame_rate_control(id, frame_rate_control); + aet_manager_set_obj_visible(id, !hidden); + field_2A = true; + loop = !!(args.flags & AET_LOOP); + return id; +} + +void aet_obj_data::reset() { + field_2A = false; + + if (id) { + aet_manager_free_aet_object(id); + id = 0; + } + + hash = hash_murmurhash_empty; + layer_name.clear(); + layer_name.shrink_to_fit(); + + if (field_20) { + delete field_20; + field_20 = 0; + } +} + +x_pv_game_stage_env_data::x_pv_game_stage_env_data() { + +} + +x_pv_game_stage_env_aet::x_pv_game_stage_env_aet() : state(), prev(), next() { + duration = 1.0f; +} + +x_pv_game_stage_env::x_pv_game_stage_env() : flags(), +state(), stage_resource(), trans_duration(), trans_remain() { + env_index = -1; + aet_gam_stgpv_id_hash = hash_murmurhash_empty; + spr_gam_stgpv_id_hash = hash_murmurhash_empty; + aet_gam_stgpv_id_main_hash = hash_murmurhash_empty; + + for (auto& i : data) + for (auto& j : i.data) + for (auto& k : j) + k.frame_rate_control = &frame_rate_control; +} + +x_pv_game_stage_env::~x_pv_game_stage_env() { + +} + +void x_pv_game_stage_env::ctrl(float_t delta_time) { + frame_rate_control.delta_frame = delta_time * 60.0f; + + switch (state) { + case 10: + state = 11; + case 11: + if ((aet_gam_stgpv_id_hash == hash_murmurhash_empty + || !aet_manager_load_file_modern(aet_gam_stgpv_id_hash, &aet_db)) + && (spr_gam_stgpv_id_hash == hash_murmurhash_empty + || !sprite_manager_load_file_modern(spr_gam_stgpv_id_hash, &spr_db))) { + spr_set* set = sprite_manager_get_set(spr_gam_stgpv_id_hash, &spr_db); + if (set) { + SpriteData* sprdata = set->sprdata; + for (uint32_t i = set->num_of_sprite; i; i--, sprdata++) + sprdata->resolution_mode = RESOLUTION_MODE_HD; + } + state = 20; + } + break; + case 20: + if (env_index != -1 && !sub_810EE198(delta_time)) + sub_810EE03E(); + break; + } +} + +pvsr_auth_2d* x_pv_game_stage_env::get_aet(int32_t env_index, int32_t type, int32_t index) { + if (env_index < 0 || env_index >= stage_resource->stage_effect_env.size()) + return 0; + + pvsr_stage_effect_env* env = &stage_resource->stage_effect_env[env_index]; + + switch (type) { + case 0: + default: + if (index < env->aet_front.size()) + return &env->aet_front[index]; + break; + case 1: + if (index < env->aet_front_low.size()) + return &env->aet_front_low[index]; + break; + case 2: + if (index < env->aet_back.size()) + return &env->aet_back[index]; + break; + case 3: + if (index < env->unk03.size()) + return &env->unk03[index]; + break; + case 4: + if (index < env->unk04.size()) + return &env->unk04[index]; + break; + } + return 0; +} + +void x_pv_game_stage_env::load(int32_t stage_id, pvsr* stage_resource) { + if (this->stage_resource || !stage_resource || stage_resource->stage_effect_env.size() > 64) + return; + + this->stage_resource = stage_resource; + + bool aet = false; + for (pvsr_stage_effect_env& i : stage_resource->stage_effect_env) + if (i.aet_front.size() || i.aet_front_low.size() + || i.aet_back.size() || i.unk03.size() || i.unk04.size()) { + aet = true; + break; + } + + if (aet) { + char buf[0x40]; + sprintf_s(buf, sizeof(buf), "AET_GAM_STGPV%03d", stage_id); + aet_gam_stgpv_id_hash = hash_utf8_murmurhash(buf); + + sprintf_s(buf, sizeof(buf), "SPR_GAM_STGPV%03d", stage_id); + spr_gam_stgpv_id_hash = hash_utf8_murmurhash(buf); + + aet_manager_read_file_modern(aet_gam_stgpv_id_hash, &data_list[DATA_X], &aet_db); + sprite_manager_read_file_modern(spr_gam_stgpv_id_hash, &data_list[DATA_X], &spr_db); + + sprintf_s(buf, sizeof(buf), "AET_GAM_STGPV%03d_MAIN", stage_id); + aet_gam_stgpv_id_main_hash = hash_utf8_murmurhash(buf); + } + + state = 10; +} + +void x_pv_game_stage_env::reset() { + flags = 0; + state = 0; + stage_resource = 0; + env_index = -1; + aet_gam_stgpv_id_hash = hash_murmurhash_empty; + spr_gam_stgpv_id_hash = hash_murmurhash_empty; + aet_gam_stgpv_id_main_hash = hash_murmurhash_empty; + frame_rate_control.delta_frame = 1.0f; + + aet_db.clear(); + spr_db.clear(); +} + +void x_pv_game_stage_env::reset_env() { + if (env_index == -1) + return; + + for (auto& i : data[env_index].data) + for (auto& j : i) + j.reset(); + + trans_duration = 0.0f; + trans_remain = 0.0f; + aet = {}; + env_index = -1; +} + +static const float env_aet_opacity = 0.65f; + +#pragma warning(push) +#pragma warning(disable: 6385) +void x_pv_game_stage_env::set(int32_t env_index, float_t end_time, float_t start_time) { + if (!stage_resource || env_index < 0 || env_index >= 64 + || env_index >= stage_resource->stage_effect_env.size() || this->env_index == env_index) + return; + + float_t duration = max_def(end_time - start_time, 0.0f); + if (trans_duration > 0.0f) { + if (fabsf(end_time) > 0.000001f) + return; + + trans_duration = 0.0f; + trans_remain = 0.0f; + aet = {}; + } + + if (this->env_index == -1 || fabsf(duration) <= 0.000001f) { + float_t frame = start_time * 60.0f; + if (this->env_index != -1) + for (auto& i : data[this->env_index].data) + for (auto& j : i) + j.reset(); + + if (!(flags & 0x04)) + for (int32_t type = 0; type < 5; type++) + for (int32_t index = 0; index < 8; index++) { + pvsr_auth_2d* aet = get_aet(env_index, type, index); + if (!aet) + break; + + aet_obj_data& aet_obj = data[env_index].data[type][index]; + + AetArgs args; + args.id.id = aet_gam_stgpv_id_main_hash; + args.layer_name = aet->name.c_str(); + args.mode = RESOLUTION_MODE_HD; + args.flags = AET_PLAY_ONCE; + switch (type) { + case 0: + args.index = 0; + args.prio = spr::SPR_PRIO_01; + break; + case 1: + args.index = 0; + args.prio = spr::SPR_PRIO_00; + break; + case 2: + args.index = 2; + args.prio = spr::SPR_PRIO_00; + break; + case 3: + args.index = 1; + args.prio = spr::SPR_PRIO_00; + break; + case 4: + args.index = 1; + args.prio = spr::SPR_PRIO_01; + break; + } + args.start_marker = 0; + args.end_marker = 0; + //args.color = bright_scale_get(aet_index_table[type], aet->bright_scale); + args.color = vec4(1.0f, 1.0f, 1.0f, env_aet_opacity); + args.spr_db = &spr_db; + aet_obj.init(args, &aet_db); + + if (aet_obj.id) + aet_manager_set_obj_frame(aet_obj.id, frame); + } + } + else { + trans_duration = duration; + trans_remain = duration; + + bool has_prev = false; + for (int32_t type = 0; type < 5; type++) + for (int32_t index = 0; index < 8; index++) + if (data[this->env_index].data[type][index].id) { + aet.prev[type][index] = &data[this->env_index].data[type][index]; + has_prev = true; + } + else + break; + + for (int32_t type = 0; type < 5; type++) + for (int32_t index = 0; index < 8; index++) + if (get_aet(env_index, type, index)) + aet.next[type][index] = &data[env_index].data[type][index]; + else + break; + + if (has_prev) { + aet.state = 1; + aet.duration = duration * 0.5f; + } + else { + aet.state = 2; + aet.duration = duration; + } + } + + this->env_index = env_index; +} + +void x_pv_game_stage_env::unload() { + if (!state) + return; + + if (aet_gam_stgpv_id_hash != hash_murmurhash_empty) { + aet_manager_unload_set_modern(aet_gam_stgpv_id_hash, &aet_db); + aet_gam_stgpv_id_hash = hash_murmurhash_empty; + } + + if (spr_gam_stgpv_id_hash != hash_murmurhash_empty) { + sprite_manager_unload_set_modern(spr_gam_stgpv_id_hash, &spr_db); + spr_gam_stgpv_id_hash = hash_murmurhash_empty; + } + + aet_gam_stgpv_id_main_hash = hash_murmurhash_empty; + + state = 0; + stage_resource = 0; + + aet_db.clear(); + spr_db.clear(); +} + +void x_pv_game_stage_env::sub_810EE03E() { + if (env_index < 0 || env_index >= 64) + return; + + for (int32_t type = 0; type < 5; type++) + for (int32_t index = 0; index < 8; index++) { + aet_obj_data& aet_obj = data[env_index].data[type][index]; + if (!aet_obj.id || !aet_obj.check_disp()) + continue; + + AetArgs args; + if (stage_resource && env_index >= 0 && env_index < 64) { + pvsr_auth_2d* aet = get_aet(env_index, type, index); + if (aet) { + args.id.id = aet_gam_stgpv_id_main_hash; + args.layer_name = aet->name.c_str(); + args.mode = RESOLUTION_MODE_HD; + args.flags = AET_PLAY_ONCE; + switch (type) { + case 0: + args.index = 0; + args.prio = spr::SPR_PRIO_01; + break; + case 1: + args.index = 0; + args.prio = spr::SPR_PRIO_00; + break; + case 2: + args.index = 2; + args.prio = spr::SPR_PRIO_00; + break; + case 3: + args.index = 1; + args.prio = spr::SPR_PRIO_00; + break; + case 4: + args.index = 1; + args.prio = spr::SPR_PRIO_01; + break; + } + args.start_marker = 0; + args.end_marker = 0; + //args.color = bright_scale_get(aet_index_table[type], aet->bright_scale); + args.color = vec4(1.0f, 1.0f, 1.0f, env_aet_opacity); + } + } + args.spr_db = &spr_db; + aet_obj.init(args, &aet_db); + } +} + +bool x_pv_game_stage_env::sub_810EE198(float_t delta_time) { + if (trans_remain <= 0.0f) + return false; + + trans_remain = max_def(trans_remain - delta_time, 0.0f); + + float_t t = 1.0f - trans_remain / trans_duration; + switch (aet.state) { + case 1: { + float_t alpha = 1.0f - t * 2.0f; + if (alpha > 0.0f) { + for (int32_t type = 0; type < 5; type++) + for (int32_t index = 0; index < 8; index++) { + aet_obj_data* aet_obj = aet.prev[type][index]; + if (!aet_obj) + break; + + aet_manager_set_obj_alpha(aet_obj->id, alpha * env_aet_opacity); + } + break; + } + + for (int32_t type = 0; type < 5; type++) + for (int32_t index = 0; index < 8; index++) { + aet_obj_data* aet_obj = aet.prev[type][index]; + if (!aet_obj) + break; + + aet_obj->reset(); + } + + aet.state = 2; + } + case 2: { + for (int32_t type = 0; type < 5; type++) + for (int32_t index = 0; index < 8; index++) { + aet_obj_data* aet_obj = aet.next[type][index]; + if (!aet_obj) + break; + + AetArgs args; + if (stage_resource && env_index >= 0 && env_index < 64) { + pvsr_auth_2d* aet = get_aet(env_index, type, index); + if (aet) { + args.id.id = aet_gam_stgpv_id_main_hash; + args.layer_name = aet->name.c_str(); + args.mode = RESOLUTION_MODE_HD; + args.flags = AET_PLAY_ONCE; + switch (type) { + case 0: + args.index = 0; + args.prio = spr::SPR_PRIO_01; + break; + case 1: + args.index = 0; + args.prio = spr::SPR_PRIO_00; + break; + case 2: + args.index = 2; + args.prio = spr::SPR_PRIO_00; + break; + case 3: + args.index = 1; + args.prio = spr::SPR_PRIO_00; + break; + case 4: + args.index = 1; + args.prio = spr::SPR_PRIO_01; + break; + } + args.start_marker = 0; + args.end_marker = 0; + //args.color = bright_scale_get(aet_index_table[type], aet->bright_scale); + args.color = vec4(1.0f, 1.0f, 1.0f, env_aet_opacity); + } + } + args.spr_db = &spr_db; + aet_obj->init(args, &aet_db); + + aet_manager_set_obj_alpha(aet_obj->id, 0.0f); + } + + aet.state = 3; + } break; + case 3: { + float_t alpha = 1.0f - trans_remain / aet.duration; + for (int32_t type = 0; type < 5; type++) + for (int32_t index = 0; index < 8; index++) { + aet_obj_data* aet_obj = aet.next[type][index]; + if (!aet_obj) + break; + + aet_manager_set_obj_alpha(aet_obj->id, alpha * env_aet_opacity); + } + } break; + } + + if (trans_remain <= 0.0f) { + trans_duration = 0.0f; + trans_remain = 0.0f; + aet = {}; + } + return false; +} +#pragma warning(pop) + x_pv_game_stage_effect_auth_3d::x_pv_game_stage_effect_auth_3d() : repeat(), field_1(), id() { reset(); } @@ -2103,10 +2597,7 @@ void x_pv_game_stage_data::reset() { flags = 0x04; state = 0; file_handler.reset(); - stg_db.stage_data.clear(); - stg_db.stage_data.shrink_to_fit(); - stg_db.stage_modern.clear(); - stg_db.stage_modern.shrink_to_fit(); + stg_db.clear(); frame_rate_control = 0; obj_hash.clear(); obj_hash.shrink_to_fit(); @@ -2164,13 +2655,6 @@ void x_pv_game_stage_data::unload() { objhrc_hash.shrink_to_fit(); } -void x_pv_game_stage_data::unload_stage_database() { - stg_db.stage_data.clear(); - stg_db.stage_data.shrink_to_fit(); - stg_db.stage_modern.clear(); - stg_db.stage_modern.shrink_to_fit(); -} - x_pv_game_stage::x_pv_game_stage() : flags(), stage_id(), field_8(), state(), stage_resource(), curr_stage_effect(), next_stage_effect(), stage_effect_transition_state() { reset(); @@ -2248,6 +2732,7 @@ void x_pv_game_stage::ctrl(float_t delta_time) { for (string_hash& i : stage_auth_3d) auth_3d_data_load_category(x_data, i.c_str(), i.hash_murmurhash); + env.load(stage_id, stage_resource); state = 11; } break; case 11: { @@ -2349,6 +2834,9 @@ void x_pv_game_stage::ctrl(float_t delta_time) { state = 12; } case 12: { + if (env.state && env.state != 20) + break; + bool wait_load = false; for (int32_t i = 0; i < X_PV_GAME_STAGE_EFFECT_COUNT; i++) { x_pv_game_stage_effect& eff = effect[i]; @@ -2381,13 +2869,14 @@ void x_pv_game_stage::ctrl(float_t delta_time) { break; case 30: if (!task_stage_modern_check_task_ready()) { - stage_data.unload_stage_database(); + stage_data.stg_db.clear(); state = 0; } break; } stage_data.ctrl(&obj_db, &tex_db); + env.ctrl(delta_time); } void x_pv_game_stage::ctrl_inner() { @@ -2636,10 +3125,8 @@ void x_pv_game_stage::reset() { for (int32_t j = 0; j < X_PV_GAME_STAGE_EFFECT_COUNT; j++) change_effect[i][j].reset(); - obj_db.object_set.clear(); - obj_db.object_set.shrink_to_fit(); - tex_db.texture.clear(); - tex_db.texture.shrink_to_fit(); + obj_db.clear(); + tex_db.clear(); auth_3d_ids.clear(); } @@ -2658,6 +3145,10 @@ void x_pv_game_stage::reset_stage_effect() { Glitter::glt_particle_manager->FreeScene(i); } +void x_pv_game_stage::reset_stage_env() { + env.reset_env(); +} + bool x_pv_game_stage::set_change_effect_frame_part_1() { if (!curr_stage_effect || !next_stage_effect) return false; @@ -2726,6 +3217,10 @@ void x_pv_game_stage::set_change_effect_frame_part_2(float_t frame) { } } +void x_pv_game_stage::set_env(int32_t env_index, float_t end_time, float_t start_time) { + env.set(env_index, end_time, start_time); +} + void x_pv_game_stage::set_stage_effect(int32_t stage_effect) { if (stage_effect < 1 || stage_effect > 12) return; @@ -2954,9 +3449,15 @@ void x_pv_game_stage::unload() { Glitter::glt_particle_manager->UnloadEffectGroup(i); } + stage_glitter.clear(); + for (string_hash& i : stage_auth_3d) auth_3d_data_unload_category(i.hash_murmurhash); + stage_auth_3d.clear(); + + env.unload(); + delete stage_resource; stage_resource = 0; @@ -4575,9 +5076,8 @@ void x_pv_game::ctrl(float_t curr_time, float_t delta_time) { break; case 30: { bool v38 = true; - x_pv_game_data* pv_data = this->pv_data; - for (int32_t i = 0; i < pv_count; i++, pv_data++) - if (pv_data->state == 10 || pv_data->state == 20) { + for (int32_t i = 0; i < pv_count; i++) + if (pv_data[i].state == 10 || pv_data[i].state == 20) { v38 = false; break; } @@ -4593,9 +5093,8 @@ void x_pv_game::ctrl(float_t curr_time, float_t delta_time) { } break; case 40: { bool v19 = true; - x_pv_game_data* pv_data = this->pv_data; - for (int32_t i = 0; i < pv_count; i++, pv_data++) - if (pv_data->state == 10 || pv_data->state == 20) { + for (int32_t i = 0; i < pv_count; i++) + if (pv_data[i].state == 10 || pv_data[i].state == 20) { v19 = false; break; } @@ -4605,7 +5104,7 @@ void x_pv_game::ctrl(float_t curr_time, float_t delta_time) { stop_current_pv(); - pv_data = this->pv_data; + x_pv_game_data* pv_data = this->pv_data; for (int32_t i = 0; i < pv_count; i++, pv_data++) { if (!pv_data->state) { rctx_ptr->camera->reset(); @@ -4920,6 +5419,16 @@ void dof_cam::reset() { } #endif +static vec4 bright_scale_get(int32_t index, float_t value) { + static const float_t bright_scale_table[] = { + 1.0f, 1.176f, 0.85f, 1.0f, + 1.0f, 1.176f, 1.176f, 1.176f + }; + + value = bright_scale_table[index] * value; + return { value, value, value, 1.0f }; +} + static float_t dsc_time_to_frame(int64_t time) { return (float_t)time / 1000000000.0f * 60.0f; } @@ -6122,7 +6631,11 @@ static bool x_pv_game_dsc_process(x_pv_game* a1, int64_t curr_time) { } break; case DSC_X_SET_STAGE_EFFECT_ENV: { - printf_debug("Env: % 3d; Trans: %3d\n", (int32_t)data[0], (int32_t)data[1]); + int32_t env_index = (int32_t)data[0]; + int32_t trans = (int32_t)data[1]; + a1->stage_data.set_env(env_index, (float_t)trans * (float_t)(1.0f / 60.0f), 0.0f); + printf_debug("Time: %8d; Env: %2d; Trans: %3d\n", + (int32_t)(curr_time / 10000), env_index, trans); } break; case DSC_X_RESERVE2: { @@ -6603,7 +7116,7 @@ static int x_pv_game_split_auth_3d_hrc_obj_bone_compare_func(void const* src1, v } static std::string x_pv_game_split_auth_3d_get_object_name( - std::string& str1, const char* str2, object_database& obj_db, bool uid_name = false) { + const std::string& str1, const char* str2, const object_database& obj_db, bool uid_name = false) { if (!str1.size()) return {}; @@ -6979,6 +7492,8 @@ static void x_pv_game_split_auth_3d_hrc_material_list(x_pv_game* xpvgm, } } + obj_db.update(); + handler->obj_id_data.reserve(set->obj_num); for (uint32_t j = 0; j < obj_num_new; j++) handler->obj_id_data.push_back({ obj_data_new[j].id, obj_num + j }); @@ -7012,7 +7527,7 @@ static void x_pv_game_split_auth_3d_hrc_material_list(x_pv_game* xpvgm, if (!skin) continue; - std::map hrc_nodes; + std::set hrc_nodes; obj_skin_bone* bone_array = skin->bone_array; uint32_t num_bone = skin->num_bone; @@ -7050,7 +7565,7 @@ static void x_pv_game_split_auth_3d_hrc_material_list(x_pv_game* xpvgm, if (!node->name.compare("BONE")) continue; - hrc_nodes.insert({ _node_index, node->name }); + hrc_nodes.insert(node->name); } } } @@ -7072,10 +7587,10 @@ static void x_pv_game_split_auth_3d_hrc_material_list(x_pv_game* xpvgm, size_t object_base = (size_t)auth->object.data(); - for (std::pair l : hrc_nodes) { + for (const std::string& l : hrc_nodes) { auth->object.push_back({}); auth_3d_object& object = auth->object.back(); - object.name.assign(l.second); + object.name.assign(l); } size_t object_new_base = (size_t)auth->object.data(); @@ -7099,21 +7614,29 @@ static void x_pv_game_split_auth_3d_hrc_material_list(x_pv_game* xpvgm, if (!obj_hrc) continue; - for (std::pair m : hrc_nodes) + for (const std::string& m : hrc_nodes) for (auth_3d_object& n : auth->object) { - if (n.name.compare(m.second) || m.first < 0) + if (n.name.compare(m)) continue; - auth_3d_object_node* node = &obj_hrc->node[m.first]; + auth_3d_object_node* node = 0; + for (auth_3d_object_node& o : obj_hrc->node) + if (!o.name.compare(m)) { + node = &o; + break; + } - if (!str_utils_compare_length(m.second.c_str(), m.second.size(), "OBJHRC_", 7)) + if (!node) + continue; + + if (!str_utils_compare_length(m.c_str(), m.size(), "OBJHRC_", 7)) auth->object_list.push_back(&n); std::string name = x_pv_game_split_auth_3d_get_object_name( - m.second, obj->name, obj_db); + m, obj->name, obj_db); std::string parent_name; std::string uid_name = x_pv_game_split_auth_3d_get_object_name( - m.second, obj->name, obj_db, true); + m, obj->name, obj_db, true); auth_3d_object_node* _node = node; int32_t parent = _node->parent; diff --git a/src/ReDIVA/x_pv_game.hpp b/src/ReDIVA/x_pv_game.hpp index f64e1f33..4281b133 100644 --- a/src/ReDIVA/x_pv_game.hpp +++ b/src/ReDIVA/x_pv_game.hpp @@ -16,6 +16,7 @@ #include "config.hpp" #include "../CRE/Glitter/glitter.hpp" #include "../CRE/rob/rob.hpp" +#include "../CRE/auth_2d.hpp" #include "../CRE/auth_3d.hpp" #include "../CRE/frame_rate_control.hpp" #include "../CRE/stage_modern.hpp" @@ -412,6 +413,82 @@ struct x_pv_game_data { void unload_if_state_is_0(); }; +class PVStageFrameRateControl : public FrameRateControl { +public: + float_t delta_frame; + + PVStageFrameRateControl(); + virtual ~PVStageFrameRateControl() override; + + virtual float_t GetDeltaFrame() override; +}; + +struct aet_obj_data { + uint32_t hash; + std::string layer_name; + void* field_20; + uint32_t id; + bool loop; + bool hidden; + bool field_2A; + FrameRateControl* frame_rate_control; + + aet_obj_data(); + ~aet_obj_data(); + + bool check_disp(); + uint32_t init(AetArgs& args, const aet_database* aet_db); + void reset(); +}; + +struct x_pv_game_stage_env_data { + auth_3d_id light_auth_3d_id; + aet_obj_data data[5][8]; + + x_pv_game_stage_env_data(); +}; + +struct x_pv_game_stage_env_aet { + int32_t state; + float_t duration; + aet_obj_data* prev[5][8]; + aet_obj_data* next[5][8]; + + x_pv_game_stage_env_aet(); +}; + +struct x_pv_game_stage_env { + int32_t flags; + int32_t state; + pvsr* stage_resource; + int32_t env_index; + x_pv_game_stage_env_data data[64]; + uint32_t aet_gam_stgpv_id_hash; + uint32_t spr_gam_stgpv_id_hash; + uint32_t aet_gam_stgpv_id_main_hash; + PVStageFrameRateControl frame_rate_control; + float_t trans_duration; + float_t trans_remain; + x_pv_game_stage_env_aet aet; + + aet_database aet_db; + sprite_database spr_db; + + x_pv_game_stage_env(); + ~x_pv_game_stage_env(); + + void ctrl(float_t delta_time); + pvsr_auth_2d* get_aet(int32_t env_index, int32_t type, int32_t index); + void load(int32_t stage_id, pvsr* stage_resource); + void reset(); + void reset_env(); + void set(int32_t env_index, float_t trans_time, float_t a4); + void unload(); + + void sub_810EE03E(); + bool sub_810EE198(float_t delta_time); +}; + struct x_pv_game_stage_effect_auth_3d { bool repeat; bool field_1; @@ -483,7 +560,6 @@ struct x_pv_game_stage_data { void set_default_stage(); void set_stage(uint32_t hash); void unload(); - void unload_stage_database(); }; struct x_pv_game_stage { @@ -494,7 +570,7 @@ struct x_pv_game_stage { //int32_t field_10; p_file_handler stage_resource_file_handler; pvsr* stage_resource; - //pv_game_stage_env env; + x_pv_game_stage_env env; BPMFrameRateControl bpm_frame_rate_control; x_pv_game_stage_data stage_data; std::vector stage_auth_3d; @@ -524,8 +600,10 @@ struct x_pv_game_stage { void load_change_effect(int32_t curr_stage_effect, int32_t next_stage_effect); void reset(); void reset_stage_effect(); + void reset_stage_env(); bool set_change_effect_frame_part_1(); void set_change_effect_frame_part_2(float_t frame); + void set_env(int32_t env_index, float_t end_time, float_t start_time); void set_stage_effect(int32_t stage_effect); void set_stage_effect_auth_3d_frame(int32_t stage_effect, float_t frame); void set_stage_effect_glitter_frame(int32_t stage_effect, float_t frame);