From cd53da270a7b63cd227b7b7c2f7ccd686114ae51 Mon Sep 17 00:00:00 2001 From: korenkonder Date: Sat, 4 Mar 2023 03:46:44 +0300 Subject: [PATCH] Auth 2D stuff --- src/CRE/auth_2d.cpp | 2307 ++++++++++++++++++++++++ src/CRE/auth_2d.hpp | 143 ++ src/CRE/auth_3d.cpp | 56 +- src/CRE/auth_3d.hpp | 3 +- src/CRE/camera.cpp | 16 +- src/CRE/camera.hpp | 2 + src/CRE/data.cpp | 14 +- src/CRE/data.hpp | 2 + src/CRE/object.cpp | 17 +- src/CRE/post_process.cpp | 4 +- src/CRE/pv_param.cpp | 18 +- src/CRE/render_context.cpp | 42 +- src/CRE/render_context.hpp | 7 + src/CRE/render_manager.cpp | 40 +- src/CRE/resolution_mode.cpp | 26 +- src/CRE/resolution_mode.hpp | 10 + src/CRE/rob/ex_block.cpp | 2 +- src/CRE/rob/rob.cpp | 4 + src/CRE/rob/rob.hpp | 1 + src/CRE/sprite.cpp | 1751 +++++++++++++++++- src/CRE/sprite.hpp | 211 ++- src/KKdLib/database/aet.cpp | 753 ++++++++ src/KKdLib/database/aet.hpp | 142 ++ src/KKdLib/database/object.hpp | 12 +- src/KKdLib/database/sprite.cpp | 25 +- src/KKdLib/database/sprite.hpp | 36 +- src/KKdLib/prj/vector_pair_combine.hpp | 171 ++ src/KKdLib/vec.hpp | 108 +- src/ReDIVA/classes/glitter_editor.cpp | 2 +- src/ReDIVA/data_initialize.cpp | 33 +- src/ReDIVA/data_test/auth_2d_test.cpp | 509 ++++++ src/ReDIVA/data_test/auth_2d_test.hpp | 89 + src/ReDIVA/data_test/auth_3d_test.cpp | 8 +- src/ReDIVA/data_test/auth_3d_test.hpp | 1 + src/ReDIVA/data_test/stage_test.cpp | 23 +- src/ReDIVA/data_test/stage_test.hpp | 1 - src/ReDIVA/dw.cpp | 556 +++++- src/ReDIVA/dw.hpp | 156 +- src/ReDIVA/game_state.cpp | 11 +- src/ReDIVA/render.cpp | 72 +- src/ReDIVA/system_startup.cpp | 8 + src/ReDIVA/system_startup.hpp | 1 + 42 files changed, 7007 insertions(+), 386 deletions(-) create mode 100644 src/CRE/auth_2d.cpp create mode 100644 src/CRE/auth_2d.hpp create mode 100644 src/KKdLib/prj/vector_pair_combine.hpp create mode 100644 src/ReDIVA/data_test/auth_2d_test.cpp create mode 100644 src/ReDIVA/data_test/auth_2d_test.hpp diff --git a/src/CRE/auth_2d.cpp b/src/CRE/auth_2d.cpp new file mode 100644 index 00000000..5f6a46f5 --- /dev/null +++ b/src/CRE/auth_2d.cpp @@ -0,0 +1,2307 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#include +#include +#include "auth_2d.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; + const aet_scene* scene; + const aet_comp* comp; + const aet_layer* layer; + float_t start_time; + float_t end_time; + AetFlags flags; + int32_t index; + int32_t layer_index; + spr::SprPrio prio; + resolution_mode src_mode; + vec3 pos; + vec3 rot; + vec3 scale; + vec3 anchor; + float_t frame_speed; + vec4 color; + float_t frame; + resolution_mode dst_mode; + vec2 scale_size; + bool matte; + spr::SprArgs spr_args; + float_t opacity; + std::map layer_sprite; + std::string sound_path; + std::map sound_replace; + int32_t sound_queue_index; + std::map sprite_replace; + std::map sprite_texture; + std::map sprite_discard; + FrameRateControl* frame_rate_control; + bool sound_voice; + bool use_float; + + const sprite_database* spr_db; + + AetObj(); + virtual ~AetObj(); + + virtual void 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); + virtual void Ctrl(); + virtual void Disp(); + virtual bool StepFrame(); + virtual void SetPlay(bool value); + virtual void SetVisible(bool value); + virtual void SetPosition(const vec3& value); + virtual void SetScale(const vec3& value); + virtual void SetRotation(const vec3& value); + virtual void SetAlpha(float_t value); + virtual void SetSpriteReplace(std::map& value); + virtual void SetSpriteTexture(std::map& value); + virtual void SetSpriteDiscard(std::map& value); + virtual void SetColor(const vec4& value); + virtual void SetEndTime(float_t value); + virtual void SetFrame(float_t value); + virtual void SetPrio(spr::SprPrio value); + virtual aet_info GetInfo(); + virtual bool GetPlay(); + virtual bool GetVisible(); + virtual float_t GetFrame(); + virtual bool GetDisp(); + virtual void CtrlComp(const aet_comp* comp, float_t frame); + virtual void DispComp(const mat4& mat, const aet_comp* comp, + float_t frame, float_t opacity, const sprite_database* spr_db); + virtual void CtrlLayer(const aet_layer* layer, float_t frame); + virtual void DispLayer(const mat4& mat, const aet_layer* layer, + float_t frame, float_t opacity, const sprite_database* spr_db); + virtual void DispVideo(const mat4& mat, const aet_layer* layer, + float_t frame, float_t opacity, const sprite_database* spr_db); + virtual void DispSprite(const mat4& mat, const aet_layer* layer, + float_t opacity, const sprite_database* spr_db); + virtual void DispSpriteSource(const mat4& mat, const aet_layer* layer, + uint32_t source_index, float_t opacity, const sprite_database* spr_db); + virtual void CalcMat(mat4& mat, const aet_layer* layer, float_t frame); +}; + +class AetLyo : public AetObj { +public: + std::map* data; + + AetLyo(std::map* data); + virtual ~AetLyo() override; + + virtual void CtrlLayer(const aet_layer* layer, float_t frame) override; + virtual void DispLayer(const mat4& mat, const aet_layer* layer, + float_t frame, float_t opacity, const sprite_database* spr_db) override; +}; + +class AetSet { +public: + uint32_t index; + const aet_scene** scenes; + uint32_t scenes_count; + int32_t load_count; + p_file_handler file_handler; + bool ready; + prj::shared_ptr alloc_handler; + + AetSet(uint32_t index); + virtual ~AetSet(); + + virtual void ReadFile(const char* dir, const char* file, void* data); + virtual bool LoadFile(); + virtual void Unload(); + virtual bool Load(); + + const aet_marker* GetLayerMarker(const aet_layer* layer, const char* name); + void GetLayerMarkerNames(std::vector& vec, const aet_layer* layer); + const aet_scene* GetSceneByInfo(aet_info info); + void GetSceneCompLayerNames(std::vector& vec, const aet_scene* scene); + float_t GetSceneEndTime(uint16_t index); + const aet_layer* GetSceneLayer(const aet_scene* scene, const char* layer_name); + const char* GetSceneName(uint16_t index); + resolution_mode GetSceneResolutionMode(const aet_scene* scene); + float_t GetSceneStartTime(uint16_t index); + uint32_t GetScenesCount(); +}; + +class AetMgr : public app::Task { +public: + std::map sets; + std::map sets_modern; + std::map objects; + std::list::iterator> free_objects; + uint32_t load_counter; + + AetMgr(); + virtual ~AetMgr(); + + virtual bool Init() override; + virtual bool Ctrl() override; + virtual bool Dest() override; + virtual void Disp() override; + virtual void Basic() override; + + void AddAetSets(const aet_database* aet_db, bool modern); + void FreeAetObject(uint32_t id); + void FreeAetObject(std::map::iterator it); + void FreeAetSetObjects(uint32_t set_index); + AetObj* GetObj(uint32_t id); + 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); + void GetSetSceneCompLayerNames(std::vector& vec, aet_info info); + float_t GetSetSceneEndTime(aet_info info); + float GetSetSceneLayerEndTime(aet_info info, const char* layer_name); + void GetSetSceneLayerMarkerNames(std::vector& vec, aet_info info, const char* layer_name); + float_t GetSetSceneLayerMarkerTime(aet_info info, const char* scene_name, const char* marker_name); + 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); + void InitAetLayout(std::map* data, 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); + void RemoveAetSets(const aet_database* aet_db, bool modern); + 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 SetObjPlay(uint32_t id, bool value); + void SetObjPosition(uint32_t id, const vec3& value); + void SetObjPrio(uint32_t id, spr::SprPrio value); + void SetObjRotation(uint32_t id, const vec3& value); + void SetObjScale(uint32_t id, const vec3& value); + void SetObjSpriteDiscard(uint32_t id, std::map& value); + 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); +}; + +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; + end_time = -1.0f; + prio = spr::SPR_PRIO_DEFAULT; + mode = RESOLUTION_MODE_HD; + scale = 1.0f; + frame_speed = 1.0f; + color = 1.0f; + sound_queue_index = 1; +} + +AetArgs::~AetArgs() { + +} + +aet_layer_object_data::aet_layer_object_data() : width(), height() { + mat = mat4_identity; + opacity = 1.0f; + color = { 0xFF, 0xFF, 0xFF, 0xFF }; + mode = RESOLUTION_MODE_HD; +} + +void aet_manager_init() { + if (!aet_manager) + aet_manager = new AetMgr; +} + +void aet_manager_add_aet_sets(const aet_database* aet_db, bool modern) { + aet_manager->AddAetSets(aet_db, modern); +} + +bool aet_manager_add_task() { + return app::TaskWork::AddTask(aet_manager, "2DAUTH_TASK", 2); +} + +bool aet_manager_check_task_ready() { + return app::TaskWork::CheckTaskReady(aet_manager); +} + +bool aet_manager_del_task() { + return aet_manager->DelTask(); +} + +void aet_manager_free_aet_object(uint32_t id) { + aet_manager->FreeAetObject(id); +} + +void aet_manager_free_aet_object_reset(uint32_t* id) { + if (id && *id) { + aet_manager_free_aet_object(*id); + *id = 0; + } +} + +void aet_manager_free_aet_set_objects(uint32_t set_id, const aet_database* aet_db) { + aet_manager->FreeAetSetObjects(aet_db->get_aet_set_by_id(set_id)->index); +} + +bool aet_manager_get_obj_disp(uint32_t id) { + return aet_manager->GetObjDisp(id); +} + +float_t aet_manager_get_obj_frame(uint32_t id) { + return aet_manager->GetObjFrame(id); +} + +bool aet_manager_get_obj_visible(uint32_t id) { + return aet_manager->GetObjVisible(id); +} + +void aet_manager_get_scene_comp_layer_names(std::vector& vec, + uint32_t aet_id, const aet_database* aet_db) { + return aet_manager->GetSetSceneCompLayerNames(vec, aet_db->get_aet_by_id(aet_id)->info); +} + +float_t aet_manager_get_scene_end_time(uint32_t aet_id, const aet_database* aet_db) { + return aet_manager->GetSetSceneEndTime(aet_db->get_aet_by_id(aet_id)->info); +} + +float_t aet_manager_get_scene_layer_end_time(uint32_t aet_id, + const char* layer_name, const aet_database* aet_db) { + return aet_manager->GetSetSceneLayerEndTime(aet_db->get_aet_by_id(aet_id)->info, layer_name); +} + +void aet_manager_get_scene_layer_marker_names(std::vector& vec, + uint32_t aet_id, const char* layer_name, const aet_database* aet_db) { + aet_manager->GetSetSceneLayerMarkerNames(vec, aet_db->get_aet_by_id(aet_id)->info, layer_name); +} + +float_t aet_manager_get_scene_layer_marker_time(uint32_t aet_id, + const char* scene_name, const char* marker_name, const aet_database* aet_db) { + return aet_manager->GetSetSceneLayerMarkerTime( + aet_db->get_aet_by_id(aet_id)->info, scene_name, marker_name); +} + +float_t aet_manager_get_scene_layer_start_time(uint32_t aet_id, + const char* layer_name, const aet_database* aet_db) { + return aet_manager->GetSetSceneLayerStartTime(aet_db->get_aet_by_id(aet_id)->info, layer_name); +} + +const char* aet_manager_get_scene_name(uint32_t aet_id, const aet_database* aet_db) { + return aet_manager->GetSetSceneName(aet_db->get_aet_by_id(aet_id)->info); +} + +float_t aet_manager_get_scene_start_time(uint32_t aet_id, const aet_database* aet_db) { + return aet_manager->GetSetSceneStartTime(aet_db->get_aet_by_id(aet_id)->info); +} + +uint32_t aet_manager_get_scenes_count(uint32_t set_id, const aet_database* aet_db) { + return aet_manager->GetSetScenesCount(aet_db->get_aet_set_by_id(set_id)->index); +} + +bool aet_manager_get_set_ready(uint32_t set_id, const aet_database* aet_db) { + return aet_manager->GetSetReady(aet_db->get_aet_set_by_id(set_id)->index); +}; + +void aet_manager_init_aet_layout(std::map* data, + AetArgs args, const aet_database* aet_db) { + args.id.info = aet_db->get_aet_by_id(args.id.id)->info; + aet_manager->InitAetLayout(data, args); +} + +void aet_manager_init_aet_layout(std::map* data, + uint32_t aet_id, const char* layer_name, AetFlags flags, resolution_mode mode, + const char* start_marker, float_t start_time, const aet_database* aet_db) { + AetArgs args; + args.id.info = aet_db->get_aet_by_id(aet_id)->info; + args.layer_name = layer_name; + args.flags = flags; + args.mode = mode; + args.start_marker = start_marker; + args.start_time = start_time; + aet_manager->InitAetLayout(data, args); +} + +uint32_t aet_manager_init_aet_object(AetArgs args, const aet_database* aet_db) { + args.id.info = aet_db->get_aet_by_id(args.id.id)->info; + return aet_manager->InitAetObject(args); +} + +uint32_t aet_manager_init_aet_object(uint32_t id, const char* layer_name, spr::SprPrio prio, + AetFlags flags, const char* start_marker, const char* end_marker, const aet_database* aet_db) { + AetArgs args; + args.id.info = aet_db->get_aet_by_id(id)->info; + args.layer_name = layer_name; + args.prio = prio; + args.flags = flags; + args.start_marker = start_marker; + args.end_marker = end_marker; + return aet_manager->InitAetObject(args); +} + +uint32_t aet_manager_init_aet_object(uint32_t aet_id, spr::SprPrio prio, + AetFlags flags, const char* layer_name, const vec2* pos, int32_t index, + 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) { + AetArgs args; + args.id.id = aet_id; + args.prio = prio; + enum_or(args.flags, flags); + args.layer_name = layer_name; + args.mode = RESOLUTION_MODE_HD; + args.layer = 0; + args.index = index; + args.start_marker = start_marker; + args.end_marker = end_marker; + + if (pos) { + args.pos.x = pos->x; + args.pos.y = pos->y; + } + + if (scale) { + args.scale.x = scale->x; + args.scale.y = scale->y; + } + + if (start_time >= 0.0f) + args.start_time = start_time; + + if (end_time >= 0.0f) + args.end_time = end_time; + + if (frame_rate_control) + args.frame_rate_control = frame_rate_control; + return aet_manager_init_aet_object(args, aet_db); +} + +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); +} + +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); + aet_manager->ReadFile(set->index, set->file_name.c_str(), mdata_dir, data); +} + +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); + aet_manager->ReadFile(set->index, set->file_name.c_str(), mdata_dir, data); +} + +void aet_manager_remove_aet_sets(const aet_database* aet_db, bool modern) { + aet_manager->RemoveAetSets(aet_db, modern); +} + +void aet_manager_set_obj_alpha(uint32_t id, float_t value) { + aet_manager->SetObjAlpha(id, value); +} + +void aet_manager_set_obj_color(uint32_t id, const vec4& value) { + aet_manager->SetObjColor(id, value); +} + +void aet_manager_set_obj_end_time(uint32_t id, float_t value) { + aet_manager->SetObjEndTime(id, value); +} + +void aet_manager_set_obj_frame(uint32_t id, float_t frame) { + aet_manager->SetObjFrame(id, frame); +} + +void aet_manager_set_obj_play(uint32_t id, bool value) { + aet_manager->SetObjPlay(id, value); +} + +void aet_manager_set_obj_position(uint32_t id, const vec3& value) { + aet_manager->SetObjPosition(id, value); +} + +void aet_manager_set_obj_prio(uint32_t id, spr::SprPrio prio) { + aet_manager->SetObjPrio(id, prio); +} + +void aet_manager_set_obj_rotation(uint32_t id, const vec3& value) { + aet_manager->SetObjRotation(id, value); +} + +void aet_manager_set_obj_scale(uint32_t id, const vec3& value) { + aet_manager->SetObjScale(id, value); +} + +void aet_manager_set_obj_sprite_discard(uint32_t id, std::map& value) { + aet_manager->SetObjSpriteDiscard(id, value); +} + +void aet_manager_set_obj_sprite_replace(uint32_t id, std::map& value) { + aet_manager->SetObjSpriteReplace(id, value); +} + +void aet_manager_set_obj_sprite_texture(uint32_t id, std::map& value) { + aet_manager->SetObjSpriteTexture(id, value); +} + +void aet_manager_set_obj_visible(uint32_t id, bool value) { + aet_manager->SetObjVisible(id, value); +} + +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_free() { + if (aet_manager) { + delete aet_manager; + aet_manager = 0; + } +} + +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() { + index = -1; + layer_index = 0; + prio = spr::SPR_PRIO_03; + src_mode = RESOLUTION_MODE_HD; + scale = 1.0f; + dst_mode = RESOLUTION_MODE_HD; + sound_queue_index = 2; +} + +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; + end_time = scene->end_time - 1.0f; + + if (layer) { + start_time = layer->start_time; + end_time = layer->end_time - 1.0f; + } + + if (start_marker) + start_time = start_marker->time; + + if (end_marker) + end_time = end_marker->time; + + if (args.start_time >= 0.0f) { + if (args.start_time < scene->start_time) + start_time = scene->start_time; + else if (scene->end_time >= args.start_time) + start_time = args.start_time; + else + start_time = scene->end_time; + } + + if (args.end_time >= 0.0f) { + if (args.end_time < scene->start_time) + end_time = scene->start_time; + else if (scene->end_time >= args.end_time) + end_time = args.end_time; + else + end_time = scene->end_time; + } + + flags = args.flags; + enum_and(flags, 0xFFFF0000); + if (start_time > end_time) { + float_t start_time = this->start_time; + float_t end_time = this->end_time; + this->start_time = end_time; + this->end_time = start_time; + enum_or(flags, AET_REVERSE); + } + + if (flags & AET_REVERSE) + frame = end_time; + else + frame = start_time; + + info = args.id.info; + this->scene = scene; + this->comp = comp; + this->layer = layer; + index = args.index; + layer_index = args.layer; + prio = args.prio; + src_mode = args.mode; + pos = args.pos; + rot = args.rot; + scale = args.scale; + anchor = args.anchor; + frame_speed = args.frame_speed; + color = args.color; + dst_mode = mode; + scale_size.x = flags & AET_FLIP_H ? -1.0f : 1.0f; + scale_size.y = flags & AET_FLIP_V ? -1.0f : 1.0f; + matte = false; + opacity = 0.0f; + layer_sprite.clear(); + layer_sprite.insert(args.layer_sprite.begin(), args.layer_sprite.end()); + sound_path.assign(args.sound_path); + sound_replace.clear(); + sound_replace.insert(args.sound_replace.begin(), args.sound_replace.end()); + sound_queue_index = args.sound_queue_index; + sprite_replace.clear(); + sprite_replace.insert(args.sprite_replace.begin(), args.sprite_replace.end()); + sprite_texture.clear(); + sprite_texture.insert(args.sprite_texture.begin(), args.sprite_texture.end()); + sprite_discard.clear(); + sprite_discard.insert(args.sprite_discard.begin(), args.sprite_discard.end()); + frame_rate_control = args.frame_rate_control; + sound_voice = args.sound_voice; + spr_db = args.spr_db; + + if (args.layer_name) { + const char* name = args.layer_name; + size_t name_len = utf8_length(name); + if (name_len >= 3 && !memcmp(name + name_len - 3, "__f", 3)) + use_float = true; + } +} + +void AetObj::Ctrl() { + if (layer) + CtrlLayer(layer, frame); + else + CtrlComp(comp, frame); +} + +void AetObj::Disp() { + if (flags & AET_HIDDEN || !scene) + return; + + vec3 pos = this->pos; + resolution_mode_scale_pos(*(vec2*)&pos, dst_mode, *(vec2*)&pos, src_mode); + + vec3 anchor = this->anchor; + if (flags & AET_100000) { + anchor.x = (float_t)(int32_t)scene->width * 0.5f; + anchor.y = (float_t)(int32_t)scene->height * 0.5f; + anchor.z = 0.0f; + } + + mat4 mat; + mat4_translate(&pos, &mat); + mat4_rotate_x_mult(&mat, rot.x, &mat); + mat4_rotate_y_mult(&mat, rot.y, &mat); + mat4_rotate_z_mult(&mat, rot.z * scale_size.x * scale_size.y, &mat); + mat4_scale_rot(&mat, scale.x * scale_size.x, scale.y * scale_size.y, scale.z, &mat); + mat4_translate_mult(&mat, -anchor.x, -anchor.y, -anchor.z, &mat); + + const aet_camera* camera = scene->camera; + if (camera) { + float_t eye_x = camera->eye_x.interpolate(frame) - (float_t)(int32_t)scene->width * 0.5f; + float_t eye_y = camera->eye_y.interpolate(frame) - (float_t)(int32_t)scene->height * 0.5f; + float_t eye_z = camera->eye_z.interpolate(frame); + mat4_translate_mult(&mat, -eye_x, -eye_y, -eye_z, &mat); + } + + if (layer) + DispLayer(mat, layer, frame, 1.0f, spr_db); + else + DispComp(mat, comp, frame, 1.0f, spr_db); +} + +bool AetObj::StepFrame() { + if (flags & AET_PAUSE) + return false; + + float_t delta_frame = 1.0f; + if (frame_rate_control) + delta_frame = frame_rate_control->GetDeltaFrame(); + + delta_frame = delta_frame * frame_speed * scene->fps * (float_t)(1.0 / 60.0); + if (flags & AET_REVERSE) + delta_frame = -delta_frame; + frame += delta_frame; + + if (!(flags & AET_REVERSE)) { + if (frame > end_time) { + if (flags & AET_LOOP) + frame = start_time; + else if (flags & AET_PLAY_ONCE) { + frame = end_time; + enum_or(flags, AET_DISP); + } + else + return true; + } + return false; + } + else { + if (start_time > frame) { + if (flags & AET_LOOP) + frame = end_time; + else if (flags & AET_PLAY_ONCE) { + frame = start_time; + enum_or(flags, AET_DISP); + } + else + return true; + } + return false; + } +} + +void AetObj::SetPlay(bool value) { + if (value) + enum_and(flags, ~AET_PAUSE); + else + enum_or(flags, AET_PAUSE); +} + +void AetObj::SetVisible(bool value) { + if (value) + enum_and(flags, ~AET_HIDDEN); + else + enum_or(flags, AET_HIDDEN); +} + +void AetObj::SetPosition(const vec3& value) { + pos = value; +} + +void AetObj::SetScale(const vec3& value) { + scale = value; +} + +void AetObj::SetRotation(const vec3& value) { + rot = value; +} + +void AetObj::SetAlpha(float_t value) { + color.w = value; +} + +void AetObj::SetSpriteReplace(std::map& value) { + sprite_replace.insert(value.begin(), value.end()); +} + +void AetObj::SetSpriteTexture(std::map& value) { + sprite_texture.insert(value.begin(), value.end()); +} + +void AetObj::SetSpriteDiscard(std::map& value) { + sprite_discard.insert(value.begin(), value.end()); +} + +void AetObj::SetColor(const vec4& value) { + color = value; +} + +void AetObj::SetEndTime(float_t value) { + end_time = value; +} + +void AetObj::SetFrame(float_t value) { + frame = value; +} + +void AetObj::SetPrio(spr::SprPrio value) { + prio = value; +} + +aet_info AetObj::GetInfo() { + return info; +} + +bool AetObj::GetPlay() { + return !(flags & AET_PAUSE); +} + +bool AetObj::GetVisible() { + return !(flags & AET_HIDDEN); +} + +float_t AetObj::GetFrame() { + return frame; +} + +bool AetObj::GetDisp() { + return !!(flags & AET_DISP); +} + +void AetObj::CtrlComp(const aet_comp* comp, float_t frame) { + if (!comp->layers_count) + return; + + const aet_layer* layers = comp->layers; + for (int64_t i = comp->layers_count - 1; i >= 0; i--) + CtrlLayer(&layers[i], frame); +} + +void AetObj::DispComp(const mat4& mat, const aet_comp* comp, + float_t frame, float_t opacity, const sprite_database* spr_db) { + if (!comp->layers_count) + return; + + const aet_layer* layers = comp->layers; + for (int64_t i = comp->layers_count - 1; i >= 0; i--) + DispLayer(mat, &layers[i], frame, opacity, spr_db); +} + +void AetObj::CtrlLayer(const aet_layer* layer, float_t frame) { + if (frame < layer->start_time || frame >= layer->end_time || !layer->flags.audio_active) + return; + + frame = (frame - layer->start_time) * layer->time_scale + layer->offset_time; + if (layer->item_type != AET_ITEM_TYPE_AUDIO) { + if (layer->item_type == AET_ITEM_TYPE_COMPOSITION) + CtrlComp(layer->item.comp, frame); + return; + } + + if (frame != 0.0f) + return; + + std::string file(layer->name); + auto elem = sound_replace.find(file); + if (elem != sound_replace.end()) + file.assign(elem->second); + + size_t aif_off = file.rfind(".aif"); + if (aif_off != -1 && aif_off == file.size() - 4) { + file.assign(file.substr(0, aif_off)); + sound_work_play_se(sound_queue_index, file.c_str(), 1.0f); + return; + } + + size_t mp3_off = file.rfind(".mp3"); + if (mp3_off != -1 && mp3_off == file.size() - 4) { + file.assign(file.substr(0, mp3_off)); + file.append(".adx"); + } + + data_struct* aft_data = &data_list[DATA_AFT]; + + std::string path; + if (sound_path.size()) { + path.assign(sound_path); + path.append(file); + } + else if (sound_voice) { + const char* rom_sound_voice_array[] = { + "rom/tv/sound/voice/", + "rom/sound/voice/", + }; + + int32_t path_count = 0; + for (size_t i = 0; i < sizeof(rom_sound_voice_array) / sizeof(const char*); i++) + if (aft_data->check_file_exists(rom_sound_voice_array[i], file.c_str())) { + path.assign(rom_sound_voice_array[i]); + path.append(file); + path_count++; + } + + if (path_count != -1) + path.clear(); + } + else + return; + + if (path.size() && aft_data->check_file_exists(path.c_str())) + sound_work_play_stream(1, path.c_str(), false); +} + +void AetObj::DispLayer(const mat4& mat, const aet_layer* layer, + float_t frame, float_t opacity, const sprite_database* spr_db) { + if (frame < layer->start_time + || frame >= layer->end_time + || layer->item_type == AET_ITEM_TYPE_AUDIO + || (!layer->flags.video_active && !matte)) + return; + + mat4 m = mat; + CalcMat(m, layer, frame); + + float_t _opacity = layer->video->opacity.interpolate(frame); + opacity *= clamp_def(_opacity, 0.0f, 1.0f); + + frame = (frame - layer->start_time) * layer->time_scale + layer->offset_time; + + if (layer->item_type == AET_ITEM_TYPE_VIDEO) + DispVideo(m, layer, frame, opacity, spr_db); + else if (layer->item_type == AET_ITEM_TYPE_COMPOSITION) + DispComp(m, layer->item.comp, frame, opacity, spr_db); +} + +void AetObj::DispVideo(const mat4& mat, const aet_layer* layer, + float_t frame, float_t opacity, const sprite_database* spr_db) { + const aet_video* video = layer->item.video; + if (video->sources_count <= 1) { + if (video->sources_count == 1) + DispSpriteSource(mat, layer, 0, opacity, spr_db); + else if (layer_sprite.size()) + DispSprite(mat, layer, opacity, spr_db); + return; + } + +#pragma warning(suppress: 26451) + double_t v11 = video->fpf * frame + 0.0001; + if (layer->flags.motion_blur) { + double_t v12; + if (video->fpf >= 1.0f) { + v12 = 1.0 - 1.0 / video->fpf; + if (v11 - 1.0 >= 0.0) { + DispSpriteSource(mat, layer, (uint32_t)((int32_t)v11 - 1), + (float_t)(sin(v12) * opacity), spr_db); + } + } + else + v12 = v11 - (double_t)(int32_t)v11; + + DispSpriteSource(mat, layer, (uint32_t)(int32_t)v11, (float_t)(cos(v12) * opacity), spr_db); + if (v11 + 1.0 < (double_t)(int32_t)video->sources_count) { + DispSpriteSource(mat, layer, (uint32_t)((int32_t)v11 + 1), + (float_t)(sin(v12) * opacity), spr_db); + } + } + else + DispSpriteSource(mat, layer, (uint32_t)(int32_t)v11, opacity, spr_db); +} + +void AetObj::DispSprite(const mat4& mat, const aet_layer* layer, + float_t opacity, const sprite_database* spr_db) { + auto elem = layer_sprite.find(layer->name); + if (elem == layer_sprite.end()) + return; + + vec4 color = this->color; + color.w *= opacity; + + spr::SprArgs args; + args.id.index = elem->second; + args.mat = mat; + args.index = index; + args.layer = layer_index; + args.prio = prio; + vec4_to_vec4u8(color * 255.0f, args.color); + args.resolution_mode_screen = dst_mode; + args.resolution_mode_sprite = dst_mode; + if (flags & AET_FLIP_H) + enum_or(args.attr, spr::SPR_ATTR_FLIP_H); + if (flags & AET_FLIP_V) + enum_or(args.attr, spr::SPR_ATTR_FLIP_V); + if (flags & AET_100000) + enum_or(args.attr, spr::SPR_ATTR_10000000); + spr::put_sprite(args, spr_db); +} + +void AetObj::DispSpriteSource(const mat4& mat, const aet_layer* layer, + uint32_t source_index, float_t opacity, const sprite_database* spr_db) { + int32_t sprite_index = layer->item.video->sources[source_index].sprite_index; + + auto elem_discard = sprite_discard.find(sprite_index); + if (elem_discard != sprite_discard.end()) + return; + + spr::SprArgs args; + args.id.index = sprite_index; + + auto elem_texture = sprite_texture.find(sprite_index); + if (elem_texture != sprite_texture.end()) { + args.texture = elem_texture->second; + args.id.index = -1; + } + else if (sprite_index != -1) { + auto elem_replace = sprite_replace.find(sprite_index); + if (elem_replace != sprite_replace.end() && elem_replace->second != -1) { + const spr_db_spr* spr = spr_db->get_spr_by_id(elem_replace->second); + const spr_db_spr_set* spr_set = spr_db->get_spr_set_by_index(spr->info.set_index & 0xFFF); + if (sprite_manager_get_set_ready(spr_set->id, spr_db)) + args.id.index = elem_replace->second; + } + } + + vec4 color = this->color; + color.w *= opacity; + + args.mat = mat; + args.index = index; + args.layer = layer_index; + args.prio = prio; + vec4_to_vec4u8(color * 255.0f, args.color); + args.resolution_mode_screen = dst_mode; + args.resolution_mode_sprite = dst_mode; + if (flags & AET_FLIP_H) + enum_or(args.attr, spr::SPR_ATTR_FLIP_H); + if (flags & AET_FLIP_V) + enum_or(args.attr, spr::SPR_ATTR_FLIP_V); + if (flags & AET_100000) + enum_or(args.attr, spr::SPR_ATTR_10000000); + + switch (layer->video->transfer_mode.mode) { + case AET_BLEND_MODE_SCREEN: + args.blend = 1; + break; + case AET_BLEND_MODE_ADD: + args.blend = 2; + break; + case AET_BLEND_MODE_MULTIPLY: + args.blend = 3; + break; + case AET_BLEND_MODE_OVERLAY: + args.blend = 5; + break; + } + + if (!matte) { + if (layer->video->transfer_mode.matte) { + this->opacity = opacity; + matte = true; + spr_args.Reset(); + spr_args = args; + } + else if (fabsf(mat4_determinant(&args.mat)) > 0.000001f) + spr::put_sprite(args, spr_db); + } + else { + matte = false; + if (fabsf(mat4_determinant(&args.mat)) > 0.000001f) { + vec4 _color = this->color; + _color.w = opacity * _color.w * this->opacity; + + vec4_to_vec4u8(_color * 255.0f, spr_args.color); + + spr::SprArgs* v52 = spr::put_sprite(spr_args, spr_db); + spr::SprArgs* v53 = spr::put_sprite(args, spr_db); + if (v53 && v52) + spr::SprArgs::SetNext(v53, v52); + } + } +} + +void AetObj::CalcMat(mat4& mat, const aet_layer* layer, float_t frame) { + if (layer->parent) + CalcMat(mat, layer->parent, frame); + + float_t pos_x; + float_t pos_y; + float_t pos_z = 0.0f; + float_t scale_x; + float_t scale_y; + float_t scale_z = 1.0f; + float_t dir_x = 0.0f; + float_t dir_y = 0.0f; + float_t dir_z = 0.0f; + float_t rot_x = 0.0f; + float_t rot_y = 0.0f; + float_t rot_z; + float_t anchor_x; + float_t anchor_y; + float_t anchor_z = 0.0f; + + if (use_float) { + const aet_layer_video* video = layer->video; + pos_x = video->pos_x.interpolate(frame); + pos_y = video->pos_y.interpolate(frame); + rot_z = video->rot_z.interpolate(frame) * DEG_TO_RAD_FLOAT; + scale_x = video->scale_x.interpolate(frame); + scale_y = video->scale_y.interpolate(frame); + anchor_x = video->anchor_x.interpolate(frame); + anchor_y = video->anchor_y.interpolate(frame); + + const aet_layer_video_3d* _3d = video->_3d; + if (_3d) { + pos_z = _3d->pos_z.interpolate(frame); + dir_x = _3d->dir_x.interpolate(frame) * DEG_TO_RAD_FLOAT; + dir_y = _3d->dir_y.interpolate(frame) * DEG_TO_RAD_FLOAT; + dir_z = _3d->dir_z.interpolate(frame) * DEG_TO_RAD_FLOAT; + rot_x = _3d->rot_x.interpolate(frame) * DEG_TO_RAD_FLOAT; + rot_y = _3d->rot_y.interpolate(frame) * DEG_TO_RAD_FLOAT; + scale_z = _3d->scale_z.interpolate(frame); + anchor_z = _3d->anchor_z.interpolate(frame); + } + } + else { + const aet_layer_video* video = layer->video; + pos_x = roundf(video->pos_x.interpolate(frame)); + pos_y = roundf(video->pos_y.interpolate(frame)); + rot_z = video->rot_z.interpolate(frame) * DEG_TO_RAD_FLOAT; + scale_x = video->scale_x.interpolate(frame); + scale_y = video->scale_y.interpolate(frame); + anchor_x = roundf(video->anchor_x.interpolate(frame)); + anchor_y = roundf(video->anchor_y.interpolate(frame)); + + const aet_layer_video_3d* _3d = video->_3d; + if (_3d) { + pos_z = roundf(_3d->pos_z.interpolate(frame)); + dir_x = _3d->dir_x.interpolate(frame) * DEG_TO_RAD_FLOAT; + dir_y = _3d->dir_y.interpolate(frame) * DEG_TO_RAD_FLOAT; + dir_z = _3d->dir_z.interpolate(frame) * DEG_TO_RAD_FLOAT; + rot_x = _3d->rot_x.interpolate(frame) * DEG_TO_RAD_FLOAT; + rot_y = _3d->rot_y.interpolate(frame) * DEG_TO_RAD_FLOAT; + scale_z = _3d->scale_z.interpolate(frame); + anchor_z = roundf(_3d->anchor_z.interpolate(frame)); + } + } + + mat4_translate_mult(&mat, pos_x, pos_y, -pos_z, &mat); + if (fabs(dir_x) > 0.000001f) + mat4_rotate_x_mult(&mat, -dir_x, &mat); + if (fabs(dir_y) > 0.000001f) + mat4_rotate_y_mult(&mat, -dir_y, &mat); + if (fabs(dir_z) > 0.000001f) + mat4_rotate_z_mult(&mat, dir_z * scale_size.x * scale_size.y, &mat); + if (fabs(rot_x) > 0.000001f) + mat4_rotate_x_mult(&mat, -rot_x, &mat); + if (fabs(rot_y) > 0.000001f) + mat4_rotate_y_mult(&mat, -rot_y, &mat); + if (fabs(rot_z) > 0.000001f) + mat4_rotate_z_mult(&mat, rot_z * scale_size.x * scale_size.y, &mat); + mat4_scale_rot(&mat, scale_x, scale_y, scale_z, &mat); + mat4_translate_mult(&mat, -anchor_x, -anchor_y, -anchor_z, &mat); +} + +AetLyo::AetLyo(std::map* data) { + this->data = data; +} + +AetLyo::~AetLyo() { + +} + +void AetLyo::CtrlLayer(const aet_layer* layer, float_t frame) { + +} + +void AetLyo::DispLayer(const mat4& mat, const aet_layer* layer, + float_t frame, float_t opacity, const sprite_database* spr_db) { + if (frame < layer->start_time + || frame >= layer->end_time + || layer->item_type == AET_ITEM_TYPE_AUDIO) + return; + + mat4 m = mat; + CalcMat(m, layer, frame); + + float_t _opacity = layer->video->opacity.interpolate(frame); + opacity *= clamp_def(_opacity, 0.0f, 1.0f); + + frame = (frame - layer->start_time) * layer->time_scale + layer->offset_time; + + if (layer->item_type == AET_ITEM_TYPE_VIDEO) { + aet_layer_object_data obj_data; + const aet_layer_video* layer_video = layer->video; + obj_data.anchor.x = layer_video->anchor_x.interpolate(frame); + obj_data.anchor.y = layer_video->anchor_y.interpolate(frame); + const aet_layer_video_3d* layer_video_3d = layer_video->_3d; + if (layer_video_3d) + obj_data.anchor.z = layer_video_3d->anchor_z.interpolate(frame); + obj_data.mat = m; + mat4_mult_vec3_trans(&m, &obj_data.anchor, &obj_data.position); + + const aet_video* video = layer->item.video; + obj_data.width = (float_t)video->width; + obj_data.height = (float_t)video->height; + obj_data.color.x = video->color[0]; + obj_data.color.y = video->color[1]; + obj_data.color.z = video->color[2];; + obj_data.opacity = opacity; + obj_data.mode = dst_mode; + data->insert({ layer->name, obj_data }); + } + else if (layer->item_type == AET_ITEM_TYPE_COMPOSITION) + DispComp(m, layer->item.comp, frame, opacity, spr_db); +} + +AetSet::AetSet(uint32_t index) : scenes(), scenes_count(), load_count(), ready() { + this->index = index; +} + +AetSet::~AetSet() { + +} + +void AetSet::ReadFile(const char* dir, const char* file, void* data) { + if (load_count > 1) { + load_count++; + return; + } + + load_count = 1; + file_handler.read_file(data, dir, file); + ready = false; +} + +bool AetSet::LoadFile() { + if (ready) + return false; + else if (file_handler.check_not_ready()) + return true; + else if (!Load()) + return false; + + ready = true; + 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--; + return; + } + + alloc_handler.reset(); + file_handler.reset(); + + scenes = 0; + ready = false; + load_count = 0; +} + +const aet_marker* AetSet::GetLayerMarker(const aet_layer* layer, const char* name) { + if (!layer->markers_count) + return 0; + + const aet_marker* marker = layer->markers; + for (uint32_t i = layer->markers_count; i; i--, marker++) + if (!str_utils_compare(marker->name, name)) + return marker; + return 0; +} + +void AetSet::GetLayerMarkerNames(std::vector& vec, const aet_layer* layer) { + vec.reserve(layer->markers_count); + const aet_marker* marker = layer->markers; + for (uint32_t i = layer->markers_count; i; i--, marker++) + vec.push_back(marker->name); +} + +const aet_scene* AetSet::GetSceneByInfo(aet_info info) { + if (index == info.set_index && ready && info.index < scenes_count) + return scenes[info.index]; + return 0; +} + +void AetSet::GetSceneCompLayerNames(std::vector& vec, const aet_scene* scene) { + const aet_comp* comp = scene->comp; + for (uint32_t i = scene->comp_count; i; i--, comp++) { + vec.reserve(comp->layers_count); + const aet_layer* layer = comp->layers; + for (uint32_t j = comp->layers_count; j; j--, layer++) + vec.push_back(layer->name); + } +} + +float_t AetSet::GetSceneEndTime(uint16_t index) { + return scenes[index]->end_time; +} + +const aet_layer* AetSet::GetSceneLayer(const aet_scene* scene, const char* layer_name) { + const aet_layer* ret = 0; + const aet_comp* comp = scene->comp; + for (uint32_t i = scene->comp_count; i; i--, comp++) { + const aet_layer* layer = comp->layers; + for (uint32_t j = comp->layers_count; j; j--, layer++) + if (!str_utils_compare(layer->name, layer_name)) { + ret = layer; + break; + } + } + return ret; +} + +const char* AetSet::GetSceneName(uint16_t index) { + return scenes[index]->name; +} + +resolution_mode AetSet::GetSceneResolutionMode(const aet_scene* scene) { + for (int32_t i = RESOLUTION_MODE_QVGA; i < RESOLUTION_MODE_MAX; i++) { + resolution_struct v5((resolution_mode)i); + if (scene->width == v5.width && scene->height == v5.height) + return (resolution_mode)i; + } + return RESOLUTION_MODE_HD; +} + +float_t AetSet::GetSceneStartTime(uint16_t index) { + return scenes[index]->start_time; +} + +uint32_t AetSet::GetScenesCount() { + return scenes_count; +} + +AetMgr::AetMgr() : load_counter() { + +} + +AetMgr::~AetMgr() { + +} + +bool AetMgr::Init() { + objects.clear(); + load_counter = 0; + return true; +} + +bool AetMgr::Ctrl() { + for (auto& i : free_objects) + objects.erase(i); + free_objects.clear(); + + for (auto& i : objects) + i.second.Ctrl(); + return false; +} + +bool AetMgr::Dest() { + objects.clear(); + load_counter = 0; + return true; +} + +void AetMgr::Disp() { + for (auto& i : objects) + i.second.Disp(); +} + +void AetMgr::Basic() { + auto i = objects.begin(); + auto i_end = objects.end(); + while (i != i_end) { + if (i->second.StepFrame()) + FreeAetObject(i); + i++; + } +} + +void AetMgr::AddAetSets(const aet_database* aet_db, bool modern) { + if (modern) + for (auto& i : aet_db->aet_set_ids) + sets_modern.insert({ i.first, AetSet(i.first) }); + else + for (auto& i : aet_db->aet_set_indices) + sets.insert({ i.first, AetSet(i.first) }); +} + +void AetMgr::FreeAetObject(uint32_t id) { + auto elem = objects.find(id); + if (elem != objects.end()) + FreeAetObject(elem); +} + +void AetMgr::FreeAetObject(std::map::iterator it) { + auto i = free_objects.begin(); + auto i_end = free_objects.end(); + while (i != i_end) { + if (it == *i) { + free_objects.erase(i); + break; + } + i++; + } + + free_objects.push_back(it); +} + +void AetMgr::FreeAetSetObjects(uint32_t set_index) { + auto i = objects.begin(); + auto i_end = objects.end(); + while (i != i_end) { + if (i->second.GetInfo().set_index == set_index) + FreeAetObject(i); + i++; + } +} + +AetObj* AetMgr::GetObj(uint32_t id) { + auto elem = objects.find(id); + if (elem != objects.end()) + return &elem->second; + return 0; +} + +bool AetMgr::GetObjDisp(uint32_t id) { + if (app::TaskWork::CheckTaskReady(this)) { + AetObj* obj = AetMgr::GetObj(id); + if (obj) + return obj->GetDisp(); + } + return true; +} + +float_t AetMgr::GetObjFrame(uint32_t id) { + if (app::TaskWork::CheckTaskReady(this)) { + AetObj* obj = AetMgr::GetObj(id); + if (obj) + return obj->GetFrame(); + } + return 0.0f; +} + +bool AetMgr::GetObjVisible(uint32_t id) { + if (app::TaskWork::CheckTaskReady(this)) { + AetObj* obj = AetMgr::GetObj(id); + if (obj) + return obj->GetVisible(); + } + return false; +} + +AetSet* AetMgr::GetSet(int32_t index) { + auto elem = sets.find(index); + if (elem != sets.end()) + return &elem->second; + return 0; +} + +bool AetMgr::GetSetReady(int32_t index) { + return GetSet(index)->ready; +} + +void AetMgr::GetSetSceneCompLayerNames(std::vector& vec, aet_info info) { + AetSet* set = GetSet(info.set_index); + set->GetSceneCompLayerNames(vec, set->GetSceneByInfo(info)); +} + +uint32_t AetMgr::GetSetScenesCount(int32_t index) { + return GetSet(index)->GetScenesCount(); +} + +float_t AetMgr::GetSetSceneEndTime(aet_info info) { + return GetSet(info.set_index)->GetSceneEndTime(info.index) - 1.0f; +} + +float AetMgr::GetSetSceneLayerEndTime(aet_info info, const char* layer_name) { + AetSet* set = GetSet(info.set_index); + return set->GetSceneLayer(set->GetSceneByInfo(info), layer_name)->end_time - 1.0f; +} + +void AetMgr::GetSetSceneLayerMarkerNames(std::vector& vec, aet_info info, const char* layer_name) { + AetSet* set = GetSet(info.set_index); + set->GetLayerMarkerNames(vec, set->GetSceneLayer(set->GetSceneByInfo(info), layer_name)); +} + +float_t AetMgr::GetSetSceneLayerMarkerTime(aet_info info, const char* scene_name, const char* marker_name) { + AetSet* set = GetSet(info.set_index); + return set->GetLayerMarker(set->GetSceneLayer(set->GetSceneByInfo(info), scene_name), marker_name)->time; +} + +float_t AetMgr::GetSetSceneLayerStartTime(aet_info info, const char* layer_name) { + AetSet* set = GetSet(info.set_index); + return set->GetSceneLayer(set->GetSceneByInfo(info), layer_name)->start_time; +} + +const char* AetMgr::GetSetSceneName(aet_info info) { + return GetSet(info.set_index)->GetSceneName(info.index); +} + +float_t AetMgr::GetSetSceneStartTime(aet_info info) { + return GetSet(info.set_index)->GetSceneStartTime(info.index); +} + +void AetMgr::InitAetLayout(std::map* data, AetArgs& args) { + AetLyo layout(data); + InitAetObj(layout, args); + layout.Disp(); +} + +bool AetMgr::InitAetObj(AetObj& obj, AetArgs& args) { + AetSet* set = GetSet(args.id.info.set_index); + if (!set) + return false; + + const aet_scene* scene = set->GetSceneByInfo(args.id.info); + if (!scene) + return false; + + const aet_comp* comp = aet_scene_get_root_comp(scene); + if (!comp) + return false; + + const aet_layer* layer = 0; + if (args.layer_name) { + layer = set->GetSceneLayer(scene, args.layer_name); + if (!layer) + return false; + } + + const aet_marker* start_marker = 0; + const aet_marker* end_marker = 0; + if ((!args.start_marker || (start_marker = set->GetLayerMarker(layer, args.start_marker))) + && (!args.end_marker || (end_marker = set->GetLayerMarker(layer, args.end_marker)))) { + resolution_mode mode = set->GetSceneResolutionMode(scene); + obj.Init(args, scene, comp, layer, start_marker, end_marker, mode); + return true; + } + + return false; +} + +uint32_t AetMgr::InitAetObject(AetArgs& args) { + AetObj obj; + if (!InitAetObj(obj, args)) + return 0; + + while (true) { + auto elem = objects.find(++load_counter); + if (elem == objects.end() && load_counter) + break; + } + + objects.insert({ load_counter, obj }); + return load_counter; +} + +bool AetMgr::LoadFile(int32_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) { + const char* dir = "./rom/2d/"; + if (mdata_dir.size() && ((data_struct*)data)->check_directory_exists(mdata_dir.c_str())) + dir = mdata_dir.c_str(); + + AetSet* set = GetSet(index); + if (set && ((data_struct*)data)->check_file_exists(dir, file)) + set->ReadFile(dir, file, data); +} + +void AetMgr::RemoveAetSets(const aet_database* aet_db, bool modern) { + if (modern) + for (auto& i : aet_db->aet_set_ids) + sets_modern.erase(i.first); + else + for (auto& i : aet_db->aet_set_indices) + sets.erase(i.first); +} + +void AetMgr::SetObjAlpha(uint32_t id, float_t value) { + AetObj* obj = GetObj(id); + if (obj) + obj->SetAlpha(value); +} + +void AetMgr::SetObjColor(uint32_t id, const vec4& value) { + AetObj* obj = GetObj(id); + if (obj) + obj->SetColor(value); +} + +void AetMgr::SetObjEndTime(uint32_t id, float_t value) { + AetObj* obj = GetObj(id); + if (obj) + obj->SetEndTime(value); +} + +void AetMgr::SetObjFrame(uint32_t id, float_t value) { + AetObj* obj = GetObj(id); + if (obj) + obj->SetFrame(value); +} + +void AetMgr::SetObjPlay(uint32_t id, bool value) { + AetObj* obj = GetObj(id); + if (obj) + obj->SetPlay(value); +} + +void AetMgr::SetObjPosition(uint32_t id, const vec3& value) { + AetObj* obj = GetObj(id); + if (obj) + obj->SetPosition(value); +} + +void AetMgr::SetObjPrio(uint32_t id, spr::SprPrio value) { + AetObj* obj = GetObj(id); + if (obj) + obj->SetPrio(value); +} + +void AetMgr::SetObjRotation(uint32_t id, const vec3& value) { + AetObj* obj = GetObj(id); + if (obj) + obj->SetRotation(value); +} + +void AetMgr::SetObjScale(uint32_t id, const vec3& value) { + AetObj* obj = GetObj(id); + if (obj) + obj->SetScale(value); +} + +void AetMgr::SetObjSpriteDiscard(uint32_t id, std::map& value) { + AetObj* obj = GetObj(id); + if (obj) + obj->SetSpriteDiscard(value); +} + +void AetMgr::SetObjSpriteReplace(uint32_t id, std::map& value) { + AetObj* obj = GetObj(id); + if (obj) + obj->SetSpriteReplace(value); +} + +void AetMgr::SetObjSpriteTexture(uint32_t id, std::map& value) { + AetObj* obj = GetObj(id); + if (obj) + obj->SetSpriteTexture(value); +} + +void AetMgr::SetObjVisible(uint32_t id, bool value) { + AetObj* obj = GetObj(id); + if (obj) + obj->SetVisible(value); +} + +void AetMgr::UnloadSet(int32_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; + } + } +} + +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 new file mode 100644 index 00000000..3670614b --- /dev/null +++ b/src/CRE/auth_2d.hpp @@ -0,0 +1,143 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#pragma once + +#include "../KKdLib/default.hpp" +#include "../KKdLib/database/aet.hpp" +#include "../KKdLib/vec.hpp" +#include "frame_rate_control.hpp" +#include "sprite.hpp" + +enum AetFlags { + AET_DISP = 0x000001, + AET_REVERSE = 0x000002, + AET_PAUSE = 0x000004, + AET_HIDDEN = 0x000008, + AET_LOOP = 0x010000, + AET_PLAY_ONCE = 0x020000, + AET_FLIP_H = 0x040000, + AET_FLIP_V = 0x080000, + AET_100000 = 0x100000, +}; + +struct AetArgs { + union IDUnion { + int32_t index; + uint32_t id; + aet_info info; + + IDUnion() { + index = -1; + id = -1; + info = {}; + } + }; + + IDUnion id; + const char* layer_name; + const char* start_marker; + const char* end_marker; + float_t start_time; + float_t end_time; + AetFlags flags; + int32_t index; + int32_t layer; + spr::SprPrio prio; + resolution_mode mode; + vec3 pos; + vec3 rot; + vec3 scale; + vec3 anchor; + float_t frame_speed; + vec4 color; + std::map layer_sprite; + std::string sound_path; + std::map sound_replace; + int32_t sound_queue_index; + std::map sprite_replace; + std::map sprite_texture; + std::map sprite_discard; + FrameRateControl* frame_rate_control; + bool sound_voice; + + const sprite_database* spr_db; + + AetArgs(); + ~AetArgs(); +}; + +struct aet_layer_object_data { + mat4 mat; + vec3 position; + vec3 anchor; + float_t width; + float_t height; + float_t opacity; + vec4u8 color; + resolution_mode mode; + + aet_layer_object_data(); +}; + +extern void aet_manager_init(); +extern void aet_manager_add_aet_sets(const aet_database* aet_db, bool modern); +extern bool aet_manager_add_task(); +extern bool aet_manager_check_task_ready(); +extern bool aet_manager_del_task(); +extern void aet_manager_free_aet_object(uint32_t id); +extern void aet_manager_free_aet_object_reset(uint32_t* id); +extern void aet_manager_free_aet_set_objects(uint32_t set_id, const aet_database* aet_db); +extern bool aet_manager_get_obj_disp(uint32_t id); +extern float_t aet_manager_get_obj_frame(uint32_t id); +extern bool aet_manager_get_obj_visible(uint32_t id); +extern void aet_manager_get_scene_comp_layer_names(std::vector& vec, + uint32_t aet_id, const aet_database* aet_db); +extern float_t aet_manager_get_scene_end_time(uint32_t aet_id, const aet_database* aet_db); +extern float_t aet_manager_get_scene_layer_end_time(uint32_t aet_id, + const char* layer_name, const aet_database* aet_db); +extern void aet_manager_get_scene_layer_marker_names(std::vector& vec, + uint32_t aet_id, const char* layer_name, const aet_database* aet_db); +extern float_t aet_manager_get_scene_layer_marker_time(uint32_t aet_id, + const char* scene_name, const char* marker_name, const aet_database* aet_db); +extern float_t aet_manager_get_scene_layer_start_time(uint32_t aet_id, + const char* layer_name, const aet_database* aet_db); +extern const char* aet_manager_get_scene_name(uint32_t aet_id, const aet_database* aet_db); +extern float_t aet_manager_get_scene_start_time(uint32_t aet_id, const aet_database* aet_db); +extern uint32_t aet_manager_get_scenes_count(uint32_t set_id, const aet_database* aet_db); +extern bool aet_manager_get_set_ready(uint32_t set_id, const aet_database* aet_db); +extern void aet_manager_init_aet_layout(std::map* data, + AetArgs args, const aet_database* aet_db); +extern void aet_manager_init_aet_layout(std::map* data, + uint32_t aet_id, const char* layer_name, AetFlags flags, resolution_mode mode, + const char* start_marker, float_t start_time, const aet_database* aet_db); +extern uint32_t aet_manager_init_aet_object(AetArgs args, const aet_database* aet_db); +extern uint32_t aet_manager_init_aet_object(uint32_t id, const char* layer_name, spr::SprPrio prio, + AetFlags flags, const char* start_marker, const char* end_marker, const aet_database* aet_db); +extern uint32_t aet_manager_init_aet_object(uint32_t aet_id, spr::SprPrio prio, + AetFlags flags, const char* layer_name, const vec2* pos, int32_t index, + 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 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_remove_aet_sets(const aet_database* aet_db, bool modern); +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 frame); +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 prio); +extern void aet_manager_set_obj_rotation(uint32_t id, const vec3& value); +extern void aet_manager_set_obj_scale(uint32_t id, const vec3& value); +extern void aet_manager_set_obj_sprite_discard(uint32_t id, std::map& value); +extern void aet_manager_set_obj_sprite_replace(uint32_t id, std::map& value); +extern void aet_manager_set_obj_sprite_texture(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_free(); diff --git a/src/CRE/auth_3d.cpp b/src/CRE/auth_3d.cpp index 389a4c2a..4354ab08 100644 --- a/src/CRE/auth_3d.cpp +++ b/src/CRE/auth_3d.cpp @@ -16,8 +16,10 @@ #include "clear_color.hpp" #include "object.hpp" #include "pv_db.hpp" +#include "task.hpp" #include "task_effect.hpp" #include "sound.hpp" +#include "sprite.hpp" #include "stage.hpp" namespace auth_3d_detail { @@ -100,7 +102,7 @@ static float_t auth_3d_camera_root_calc_frame(auth_3d_camera_root* cr, float_t f static void auth_3d_camera_root_load(auth_3d* auth, auth_3d_camera_root* cr, auth_3d_camera_root_file* crf); static void auth_3d_camera_root_view_point_load(auth_3d* auth, auth_3d_camera_root_view_point* crvp, auth_3d_camera_root_view_point_file* crvpf); -static void auth_3d_chara_disp(auth_3d_chara* c, mat4* parent_mat, render_context* rctx); +static void auth_3d_chara_disp(auth_3d_chara* c, auth_3d* auth, render_context* rctx); static void auth_3d_chara_load(auth_3d* auth, auth_3d_chara* c, auth_3d_chara_file* cf); static void auth_3d_curve_load(auth_3d* auth, auth_3d_curve* c, auth_3d_curve_file* cf); static void auth_3d_dof_load(auth_3d* auth, auth_3d_dof* d, auth_3d_dof_file* df); @@ -142,7 +144,7 @@ static void auth_3d_object_texture_pattern_load(auth_3d* auth, auth_3d_object_te static void auth_3d_object_texture_transform_load(auth_3d* auth, auth_3d_object_texture_transform* ott, auth_3d_object_texture_transform_file* ottf, texture_database* tex_db); static void auth_3d_play_control_load(auth_3d* auth, auth_3d_play_control_file* pcf); -static void auth_3d_point_disp(auth_3d_point* p, mat4* parent_mat, render_context* rctx); +static void auth_3d_point_disp(auth_3d_point* p, auth_3d* auth, render_context* rctx); static void auth_3d_point_load(auth_3d* auth, auth_3d_point* p, auth_3d_point_file* pf); static void auth_3d_post_process_load(auth_3d* auth, auth_3d_post_process* pp, auth_3d_post_process_file* ppf); static void auth_3d_post_process_restore_prev_value(auth_3d_post_process* pp, render_context* rctx); @@ -193,7 +195,7 @@ static auth_3d_detail::FrameRateTimeStop frame_rate_time_stop; extern render_context* rctx_ptr; auth_3d::auth_3d() : uid(), id(), mat(), enable(), camera_root_update(), visible(), repeat(), ended(), -left_right_reverse(), once(), alpha(), chara_id(), chara_item(), shadow(), frame_rate(), frame(), +left_right_reverse(), once(), alpha(), chara_id(), chara_item(), shadow(), pos(), frame_rate(), frame(), req_frame(), max_frame(), frame_changed(), frame_offset(), last_frame(), paused(), event_time_next() { hash = hash_murmurhash_empty; src_chara = CHARA_MAX; @@ -412,13 +414,16 @@ void auth_3d::disp(render_context* rctx) { if (state != 2 || !enable) return; + if (pos) + spr::put_rgb_cross(mat); + auth_3d_set_material_list(this, rctx); for (auth_3d_point& i : point) - auth_3d_point_disp(&i, &mat, rctx); + auth_3d_point_disp(&i, this, rctx); for (auth_3d_chara& i : chara) - auth_3d_chara_disp(&i, &mat, rctx); + auth_3d_chara_disp(&i, this, rctx); for (auth_3d_object*& i : object_list) auth_3d_object_disp(i, this, rctx); @@ -712,6 +717,7 @@ void auth_3d::reset() { shadow = false; src_chara = CHARA_MAX; dst_chara = CHARA_MAX; + pos = 0; frame_rate = &sys_frame_rate; frame = 0.0f; req_frame = 0.0f; @@ -2472,6 +2478,14 @@ void auth_3d_id::set_paused(bool value) { } } +void auth_3d_id::set_pos(int32_t value) { + if (id >= 0 && ((id & 0x7FFF) < AUTH_3D_DATA_COUNT)) { + auth_3d* auth = &auth_3d_data->data[id & 0x7FFF]; + if (auth->id == id) + auth->pos = value; + } +} + void auth_3d_id::set_repeat(bool value) { if (id >= 0 && ((id & 0x7FFF) < AUTH_3D_DATA_COUNT)) { auth_3d* auth = &auth_3d_data->data[id & 0x7FFF]; @@ -2545,7 +2559,8 @@ auth_3d_data_struct::~auth_3d_data_struct() { } void auth_3d_data_init() { - auth_3d_data = new auth_3d_data_struct; + if (!auth_3d_data) + auth_3d_data = new auth_3d_data_struct; } bool auth_3d_data_check_category_loaded(const char* category_name) { @@ -2827,11 +2842,15 @@ void auth_3d_data_unload_category(uint32_t category_hash) { } void auth_3d_data_free() { - delete auth_3d_data; + if (auth_3d_data) { + delete auth_3d_data; + auth_3d_data = 0; + } } void task_auth_3d_init() { - task_auth_3d = new auth_3d_detail::TaskAuth3d; + if (!task_auth_3d) + task_auth_3d = new auth_3d_detail::TaskAuth3d; } bool task_auth_3d_add_task() { @@ -3459,8 +3478,14 @@ static void auth_3d_camera_root_view_point_load(auth_3d* auth, auth_3d_camera_ro } } -static void auth_3d_chara_disp(auth_3d_chara* c, mat4* parent_mat, render_context* rctx) { +static void auth_3d_chara_disp(auth_3d_chara* c, auth_3d* auth, render_context* rctx) { + if (c->index <= ROB_CHARA_COUNT) + rob_chara_array_set_visibility(c->index, c->model_transform.visible); + if (auth->pos) { + c->model_transform.set_mat(&auth->mat); + spr::put_rgb_cross(c->model_transform.mat); + } } static void auth_3d_chara_load(auth_3d* auth, auth_3d_chara* c, auth_3d_chara_file* cf) { @@ -5411,6 +5436,9 @@ static void auth_3d_object_disp(auth_3d_object* o, auth_3d* auth, render_context return; if (!auth->visible) { + if (auth->pos) + spr::put_rgb_cross(o->model_transform.mat); + for (auth_3d_object*& i : o->children_object) auth_3d_object_disp(i, auth, rctx); for (auth_3d_object_hrc*& i : o->children_object_hrc) @@ -5538,6 +5566,9 @@ static void auth_3d_object_disp(auth_3d_object* o, auth_3d* auth, render_context disp_manager.set_texture_pattern(); disp_manager.set_obj_flags(); + if (auth->pos) + spr::put_rgb_cross(o->model_transform.mat); + for (auth_3d_object*& i : o->children_object) auth_3d_object_disp(i, auth, rctx); for (auth_3d_object_hrc*& i : o->children_object_hrc) @@ -5907,8 +5938,11 @@ static void auth_3d_play_control_load(auth_3d* auth, auth_3d_play_control_file* pc->size = pcf->size; } -static void auth_3d_point_disp(auth_3d_point* p, mat4* parent_mat, render_context* rctx) { - +static void auth_3d_point_disp(auth_3d_point* p, auth_3d* auth, render_context* rctx) { + if (auth->pos) { + p->model_transform.set_mat(&auth->mat); + spr::put_rgb_cross(p->model_transform.mat); + } } static void auth_3d_point_load(auth_3d* auth, auth_3d_point* p, auth_3d_point_file* pf) { diff --git a/src/CRE/auth_3d.hpp b/src/CRE/auth_3d.hpp index 8a63d94a..5873db88 100644 --- a/src/CRE/auth_3d.hpp +++ b/src/CRE/auth_3d.hpp @@ -14,7 +14,6 @@ #include "../KKdLib/kf.hpp" #include "frame_rate_control.hpp" #include "render_context.hpp" -#include "task.hpp" enum auth_3d_ambient_flags { AUTH_3D_AMBIENT_LIGHT_DIFFUSE = 0x01, @@ -840,6 +839,7 @@ struct auth_3d_id { void set_mat(const mat4& value); void set_max_frame(float_t value); void set_paused(bool value); + void set_pos(int32_t value); void set_repeat(bool value); void set_req_frame(float_t value); void set_shadow(bool value); @@ -866,6 +866,7 @@ struct auth_3d { bool shadow; int32_t src_chara; int32_t dst_chara; + int32_t pos; FrameRateControl* frame_rate; float_t frame; float_t req_frame; diff --git a/src/CRE/camera.cpp b/src/CRE/camera.cpp index 639839c2..a74033eb 100644 --- a/src/CRE/camera.cpp +++ b/src/CRE/camera.cpp @@ -10,10 +10,11 @@ static void camera_calculate_projection_aet(camera* c); static void camera_calculate_view(camera* c); static void camera_calculate_forward(camera* c); -camera::camera() : forward(), rotation(), view_point(), interest(), render_width(), render_height(), -sprite_width(), sprite_height(), field_1E4(), field_1F0(), field_1FC(), field_208(), yaw(), -pitch(), roll(), aspect(), fov(), fov_rad(), max_distance(), min_distance(), changed_view(), -changed_proj(), changed_proj_aet(), fast_change(), fast_change_hist0(), fast_change_hist1() { +camera::camera() : forward(), rotation(), view_point(), interest(), fov_correct_height(), +aet_depth(), render_width(), render_height(), sprite_width(), sprite_height(), +field_1E4(), field_1F0(), field_1FC(), field_208(), yaw(), pitch(), roll(), aspect(), +fov(), fov_rad(), max_distance(), min_distance(), changed_view(), changed_proj(), +changed_proj_aet(), fast_change(), fast_change_hist0(), fast_change_hist1() { } @@ -25,6 +26,8 @@ void camera::initialize(double_t aspect, int32_t render_width, int32_t render_height, int32_t sprite_width, int32_t sprite_height) { this->aspect = aspect; fov = 0.0; + fov_correct_height = 0.0f; + aet_depth = 0.0f; forward = { 0.0f, 0.0f, -1.0f }; rotation = { 0.0f, 0.0f, 0.0f }; view_point = { 0.0, 0.0f, 0.0f }; @@ -335,6 +338,7 @@ static void camera_calculate_projection(camera* c) { mat4_inverse(&c->projection, &c->inv_projection); float_t fov_correct_height = (float_t)(((double_t)c->render_height * 0.5) / tan(c->fov_rad * 0.5)); + float_t height = (float_t)c->render_height * 0.5f; float_t width = (float_t)c->render_height * (float_t)c->aspect * 0.5f; @@ -363,6 +367,10 @@ static void camera_calculate_projection_aet(camera* c) { float_t render_half_height = (float_t)c->render_height * 0.5f; float_t aet_depth = sprite_half_height / (tanf(0.34557518363f) * 0.75f); + c->aet_depth = aet_depth; + + float_t fov_correct_height = (float_t)(sprite_half_height / tan(c->fov_rad * 0.5)); + c->fov_correct_height = fov_correct_height; float_t v8a = (float_t)c->min_distance / aet_depth * sprite_half_width; float_t v8b = (float_t)c->min_distance / aet_depth * sprite_half_height; diff --git a/src/CRE/camera.hpp b/src/CRE/camera.hpp index 83fe986d..30630428 100644 --- a/src/CRE/camera.hpp +++ b/src/CRE/camera.hpp @@ -24,6 +24,8 @@ struct camera { mat4 inv_view_rot; mat4 projection_aet_2d; mat4 projection_aet_3d; + float_t fov_correct_height; + float_t aet_depth; vec3 forward; vec3 rotation; vec3 view_point; diff --git a/src/CRE/data.cpp b/src/CRE/data.cpp index 649a96ac..d8395574 100644 --- a/src/CRE/data.cpp +++ b/src/CRE/data.cpp @@ -60,6 +60,18 @@ void data_struct_load_db() { data_struct* ds = &data_list[DATA_AFT]; data_ft* d = &ds->data_ft; + for (const std::string& i : mdata_manager_get()->GetPrefixes()) { + std::string file; + file.assign(i); + file.append("aet_db.bin"); + + aet_database_file aet_db_file; + aet_db_file.modern = false; + ds->load_file(&aet_db_file, "rom/2d/", file.c_str(), + aet_database_file::load_file); + d->aet_db.add(&aet_db_file); + } + for (const std::string& i : mdata_manager_get()->GetPrefixes()) { std::string file; file.assign(i); @@ -563,7 +575,7 @@ bool data_struct::get_file(const char* dir, uint32_t hash, const char* ext, std: } bool data_struct::load_file(void* data, const char* path, - bool (*load_func)(void* data, const char* path, const char* file, uint32_t hash)) { + bool (*load_func)(void* data, const char* path, const char* file, uint32_t hash)) { const char* t = strrchr(path, '/'); if (t) { std::string dir = std::string(path, t - path + 1); diff --git a/src/CRE/data.hpp b/src/CRE/data.hpp index 8eee9c11..71e744fd 100644 --- a/src/CRE/data.hpp +++ b/src/CRE/data.hpp @@ -8,6 +8,7 @@ #include #include #include "../KKdLib/default.hpp" +#include "../KKdLib/database/aet.hpp" #include "../KKdLib/database/auth_3d.hpp" #include "../KKdLib/database/bone.hpp" #include "../KKdLib/database/motion.hpp" @@ -65,6 +66,7 @@ struct data_f2 { #endif struct data_ft { + aet_database aet_db; auth_3d_database auth_3d_db; bone_database bone_data; motion_database mot_db; diff --git a/src/CRE/object.cpp b/src/CRE/object.cpp index 52caf643..5f70a9f6 100644 --- a/src/CRE/object.cpp +++ b/src/CRE/object.cpp @@ -1688,20 +1688,9 @@ texture* obj_database_get_obj_set_texture(int32_t set, uint32_t tex_id) { if (!handler) return 0; - std::pair* texture = handler->tex_id_data.data(); - size_t length = handler->tex_id_data.size(); - size_t temp; - while (length > 0) - if (tex_id <= texture[temp = length / 2].first) - length /= 2; - else { - texture += temp + 1; - length -= temp + 1; - } - - if (texture != handler->tex_id_data.data() + handler->tex_id_data.size() - && tex_id == texture->first) - return (*textures)[texture->second]; + auto elem = handler->tex_id_data.find(tex_id); + if (elem != handler->tex_id_data.end()) + return (*textures)[elem->second]; return 0; } diff --git a/src/CRE/post_process.cpp b/src/CRE/post_process.cpp index 9512be43..84113828 100644 --- a/src/CRE/post_process.cpp +++ b/src/CRE/post_process.cpp @@ -258,8 +258,8 @@ void post_process::apply(camera* cam, texture* light_proj_tex, int32_t npr_param gl_state_bind_sampler(i, 0); fbo::blit(screen_texture.fbos[0], fbo_texture.fbos[0], - screen_x_offset, screen_y_offset, sprite_width, sprite_height, - 0, 0, render_width, render_height, GL_COLOR_BUFFER_BIT, GL_LINEAR); + 0, 0, screen_width, screen_height, + 0, 0, screen_width, screen_height, GL_COLOR_BUFFER_BIT, GL_LINEAR); } void post_process::ctrl(camera* cam) { diff --git a/src/CRE/pv_param.cpp b/src/CRE/pv_param.cpp index b6d5c363..7a58eafc 100644 --- a/src/CRE/pv_param.cpp +++ b/src/CRE/pv_param.cpp @@ -375,12 +375,12 @@ namespace pv_param { } bool post_process_data_load_files(int32_t pv_id) { - std::string path = "rom/pv_param/"; - char buf[0x100]; sprintf_s(buf, sizeof(buf), "pv%03d/", pv_id); - path += buf; + std::string path; + path.assign("rom/pv_param/"); + path.append(buf); if (data_list[DATA_AFT].check_directory_exists(path.c_str())) return post_process_data.load_files(path); @@ -388,17 +388,19 @@ namespace pv_param { } bool post_process_data_load_files(int32_t pv_id, std::string& mdata_dir) { - std::string path = "rom/pv_param/"; - char buf[0x100]; sprintf_s(buf, sizeof(buf), "pv%03d/", pv_id); - path += buf; + std::string path; + path.assign("rom/pv_param/"); + path.append(buf); if (mdata_dir.size()) { - std::string temp_path = mdata_dir + path; + std::string temp_path; + temp_path.assign(mdata_dir); + temp_path.append(path); if (data_list[DATA_AFT].check_directory_exists(temp_path.c_str())) - path = temp_path; + path.assign(temp_path); } if (data_list[DATA_AFT].check_directory_exists(path.c_str())) diff --git a/src/CRE/render_context.cpp b/src/CRE/render_context.cpp index 122bcefe..d6195079 100644 --- a/src/CRE/render_context.cpp +++ b/src/CRE/render_context.cpp @@ -10,6 +10,7 @@ #include "file_handler.hpp" #include "render_manager.hpp" #include "shader_ft.hpp" +#include "sprite.hpp" #include "sound.hpp" #include "stage.hpp" @@ -18,6 +19,8 @@ int32_t delta_frame_history_int = 0; extern render_context* rctx_ptr; +//extern void dw_gui_ctrl_disp(); + static void object_data_get_vertex_attrib_buffer_bindings(const mdl::ObjSubMeshArgs* args, int32_t texcoord_array[2], GLuint vertex_attrib_buffer_binding[16]); @@ -2098,7 +2101,7 @@ namespace rndr { cpu_time(), gpu_time(), time(), draw_pass_3d(), reflect_type(), tex_index(), multisample_framebuffer(), multisample_renderbuffer(), multisample(), show_vector_flags(), show_vector_length(), show_vector_z_offset(), field_2F8(), effect_texture(), npr_param(), - field_31C(), field_31D(), field_31E(), field_31F(), field_320(), npr(), samplers() { + field_31C(), field_31D(), field_31E(), field_31F(), field_320(), npr(), samplers(), sprite_samplers() { for (bool& i : pass_sw) i = true; reflect = true; @@ -2126,11 +2129,12 @@ namespace rndr { } gl_state_bind_framebuffer(0); + static const vec4 border_color = 0.0f; + glCreateSamplers(18, samplers); for (int32_t i = 0; i < 18; i++) { GLuint sampler = samplers[i]; - static const vec4 border_color = 0.0f; glSamplerParameterfv(sampler, GL_TEXTURE_BORDER_COLOR, (GLfloat*)&border_color); glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, i % 2 ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR); @@ -2165,9 +2169,36 @@ namespace rndr { } glSamplerParameteri(sampler, GL_TEXTURE_WRAP_T, wrap_t); } + + GLuint sampler; + glCreateSamplers(3, sprite_samplers); + sampler = sprite_samplers[0]; + glSamplerParameterfv(sampler, GL_TEXTURE_BORDER_COLOR, (GLfloat*)&border_color); + glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); + glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_NEAREST); + glSamplerParameteri(sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glSamplerParameteri(sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glSamplerParameterf(sampler, GL_TEXTURE_MAX_ANISOTROPY_EXT, 16.0f); + + sampler = sprite_samplers[1]; + glSamplerParameterfv(sampler, GL_TEXTURE_BORDER_COLOR, (GLfloat*)&border_color); + glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); + glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_NEAREST); + glSamplerParameteri(sampler, GL_TEXTURE_WRAP_S, GL_REPEAT); + glSamplerParameteri(sampler, GL_TEXTURE_WRAP_T, GL_REPEAT); + glSamplerParameterf(sampler, GL_TEXTURE_MAX_ANISOTROPY_EXT, 16.0f); + + sampler = sprite_samplers[2]; + glSamplerParameterfv(sampler, GL_TEXTURE_BORDER_COLOR, (GLfloat*)&border_color); + glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); + glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_NEAREST); + glSamplerParameteri(sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); + glSamplerParameteri(sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); + glSamplerParameterf(sampler, GL_TEXTURE_MAX_ANISOTROPY_EXT, 16.0f); } RenderManager::~RenderManager() { + glDeleteSamplers(3, sprite_samplers); glDeleteSamplers(18, samplers); if (multisample_framebuffer) { @@ -2468,6 +2499,7 @@ chara_refract(), view_mat(), matrix_buffer(), box_vao(), box_vbo() { imgfilter_batch_ubo.Create(sizeof(imgfilter_batch_shader_data)); glass_eye_batch_ubo.Create(sizeof(glass_eye_batch_shader_data)); quad_ubo.Create(sizeof(quad_shader_data)); + sprite_scene_ubo.Create(sizeof(sprite_scene_shader_data)); sss_filter_gaussian_coef_ubo.Create(sizeof(sss_filter_gaussian_coef_shader_data)); transparency_batch_ubo.Create(sizeof(transparency_batch_shader_data)); @@ -2486,6 +2518,7 @@ render_context::~render_context() { transparency_batch_ubo.Destroy(); sss_filter_gaussian_coef_ubo.Destroy(); + sprite_scene_ubo.Destroy(); quad_ubo.Destroy(); glass_eye_batch_ubo.Destroy(); imgfilter_batch_ubo.Destroy(); @@ -2522,10 +2555,15 @@ void render_context::ctrl() { void render_context::disp() { rctx_ptr = this; disp_manager.refresh(); + sprite_manager_reset_req_list(); draw_state.stats_prev = draw_state.stats; draw_state.stats.reset(); app::TaskWork::Disp(); render_manager.shadow_ptr->ctrl(this); + int32_t sprite_index = sprite_manager_get_index(); + sprite_manager_set_index(3); + //dw_gui_ctrl_disp(); + sprite_manager_set_index(sprite_index); post_process.ctrl(camera); render_manager.render_all(this); app::TaskWork::Basic(); diff --git a/src/CRE/render_context.hpp b/src/CRE/render_context.hpp index 1019f3bf..d2a2425a 100644 --- a/src/CRE/render_context.hpp +++ b/src/CRE/render_context.hpp @@ -595,6 +595,7 @@ namespace rndr { bool npr; sss_data sss_data; GLuint samplers[18]; + GLuint sprite_samplers[3]; RenderManager(); ~RenderManager(); @@ -791,6 +792,11 @@ struct quad_shader_data { vec4 g_texture_lod; }; +struct sprite_scene_shader_data { + mat4 g_transform; + vec4 g_framebuffer_size; +}; + struct sss_filter_gaussian_coef_shader_data { vec4 g_param; vec4 g_coef[64]; @@ -828,6 +834,7 @@ struct render_context { GL::UniformBuffer imgfilter_batch_ubo; GL::UniformBuffer glass_eye_batch_ubo; GL::UniformBuffer quad_ubo; + GL::UniformBuffer sprite_scene_ubo; GL::UniformBuffer sss_filter_gaussian_coef_ubo; GL::UniformBuffer transparency_batch_ubo; diff --git a/src/CRE/render_manager.cpp b/src/CRE/render_manager.cpp index b3936afa..e3ebd738 100644 --- a/src/CRE/render_manager.cpp +++ b/src/CRE/render_manager.cpp @@ -14,6 +14,7 @@ #include "post_process.hpp" #include "render_texture.hpp" #include "shader_ft.hpp" +#include "sprite.hpp" #include "static_var.hpp" #include "task_effect.hpp" #include "texture.hpp" @@ -478,7 +479,7 @@ namespace rndr { if (!sss_data.enable || !sss_data.npr_contour) { pp->set_render_texture(); - if (false/*sprite_manager_get_reqlist_count(2)*/) { + if (sprite_manager_get_reqlist_count(2)) { glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glClearDepth(1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); @@ -495,7 +496,7 @@ namespace rndr { gl_state_bind_framebuffer(0); } else { - if (false/*sprite_manager_get_reqlist_count(2)*/) { + if (sprite_manager_get_reqlist_count(2)) { pp->set_render_texture(); vec4 clear_color = 0.0f; @@ -516,19 +517,19 @@ namespace rndr { } void RenderManager::pass_sprite_bg(render_context* rctx) { - if (!(false/*sprite_manager_get_reqlist_count(2)*/)) + if (!sprite_manager_get_reqlist_count(2)) return; post_process* pp = &rctx->post_process; pp->set_render_texture(true); glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glClear(GL_COLOR_BUFFER_BIT); - //rctx->camera->projection_aet_3d; gl_state_set_depth_mask(GL_FALSE); gl_state_disable_depth_test(); gl_state_enable_blend(); gl_state_disable_cull_face(); - //sprite_manager_draw(2, 1, pp->aa->mlaa_buffer[1].color_texture->tex); + sprite_manager_draw(rctx, 2, true, + pp->aa->temp_buffer.color_texture, rctx->camera->projection_aet_3d); gl_state_enable_cull_face(); gl_state_disable_blend(); gl_state_enable_depth_test(); @@ -774,7 +775,11 @@ namespace rndr { } void RenderManager::pass_sprite_fg(render_context* rctx) { + if (!sprite_manager_get_reqlist_count(0)) + return; + post_process* pp = &rctx->post_process; + glViewport(0, 0, pp->screen_width, pp->screen_height); if (multisample && multisample_framebuffer) { glBindFramebuffer(GL_FRAMEBUFFER, multisample_framebuffer); @@ -782,13 +787,14 @@ namespace rndr { glClearColor(0.0, 0.0, 0.0, 0.0); glClear(GL_COLOR_BUFFER_BIT); } - - //rctx->camera->projection_aet_2d; + else + rctx->post_process.fbo_texture.bind(); gl_state_disable_depth_test(); gl_state_enable_blend(); gl_state_disable_cull_face(); - //sprite_manager_draw(0, 1, pp->aa->mlaa_buffer[1].color_texture->tex); + sprite_manager_draw(rctx, 0, true, + pp->aa->temp_buffer.color_texture, rctx->camera->projection_aet_2d); gl_state_enable_cull_face(); gl_state_disable_blend(); gl_state_enable_depth_test(); @@ -837,16 +843,18 @@ namespace rndr { } void RenderManager::pass_sprite_fg_surf(render_context* rctx) { - if (!(false/*sprite_manager_get_reqlist_count(1)*/)) + if (!sprite_manager_get_reqlist_count(1)) return; - //rctx->camera->projection_aet_2d; + post_process* pp = &rctx->post_process; + gl_state_set_depth_mask(GL_FALSE); gl_state_disable_depth_test(); gl_state_disable_depth_test(); gl_state_enable_blend(); gl_state_disable_cull_face(); - //sprite_manager_draw(1, 1, rctx->post_process.aa->temp_buffer.color_texture); + sprite_manager_draw(rctx, 1, true, + pp->aa->temp_buffer.color_texture, rctx->camera->projection_aet_2d); } } @@ -1287,16 +1295,6 @@ static void draw_pass_sss_filter(render_context* rctx, sss_data* a1) { gl_state_bind_texture_2d(0); } -void sub_1404A9350(post_process* a1, bool a2) { - if (a2) { - a1->aet_back_texture.bind(); - a1->aet_back = 1; - } - else - a1->rend_texture.bind(); - glViewport(0, 0, a1->render_width, a1->render_height); -} - static int32_t draw_pass_3d_get_translucent_count(render_context* rctx) { int32_t count = 0; count += rctx->disp_manager.get_obj_count(mdl::OBJ_TYPE_OPAQUE_ALPHA_ORDER_1); diff --git a/src/CRE/resolution_mode.cpp b/src/CRE/resolution_mode.cpp index 2875dfd4..c6b78ef0 100644 --- a/src/CRE/resolution_mode.cpp +++ b/src/CRE/resolution_mode.cpp @@ -5,14 +5,6 @@ #include "resolution_mode.hpp" -struct resolution_mode_scale_data { - vec2 scale; - vec2 src_res; - vec2 dst_res; - resolution_mode src_mode; - resolution_mode dst_mode; -}; - const resolution_table_struct resolution_table[] = { { 320, 240, 0, 0, 0, 320, 225 }, // QVGA { 640, 480, 0, 0, 60, 640, 360 }, // VGA @@ -90,6 +82,24 @@ resolution_struct::resolution_struct(::resolution_mode mode) { } } +resolution_mode_scale_data::resolution_mode_scale_data( + resolution_mode src_mode, resolution_mode dst_mode) { + scale = 1.0f; + src_res = 0.0f; + dst_res = 0.0f; + this->src_mode = src_mode; + this->dst_mode = dst_mode; + scale = resolution_mode_get_scale(dst_mode, src_mode); + if (dst_mode != RESOLUTION_MODE_MAX && src_mode != RESOLUTION_MODE_MAX + && dst_mode >= RESOLUTION_MODE_QVGA && src_mode >= RESOLUTION_MODE_MAX + && dst_mode < RESOLUTION_MODE_MAX && src_mode < RESOLUTION_MODE_MAX) { + src_res.x = (float_t)resolution_table[src_mode].width_full * 0.5f; + src_res.y = (float_t)resolution_table[src_mode].height_full * 0.5f; + dst_res.x = (float_t)resolution_table[dst_mode].width_full * 0.5f; + dst_res.y = (float_t)resolution_table[dst_mode].height_full * 0.5f; + } +} + resolution_struct* res_window_get() { return &res_window; } diff --git a/src/CRE/resolution_mode.hpp b/src/CRE/resolution_mode.hpp index 5d7fc331..e2f66af4 100644 --- a/src/CRE/resolution_mode.hpp +++ b/src/CRE/resolution_mode.hpp @@ -92,6 +92,16 @@ struct resolution_struct { resolution_struct(::resolution_mode mode); }; +struct resolution_mode_scale_data { + vec2 scale; + vec2 src_res; + vec2 dst_res; + resolution_mode src_mode; + resolution_mode dst_mode; + + resolution_mode_scale_data(resolution_mode src_mode, resolution_mode dst_mode); +}; + extern const resolution_table_struct resolution_table[]; extern resolution_struct* res_window_get(); diff --git a/src/CRE/rob/ex_block.cpp b/src/CRE/rob/ex_block.cpp index 69e03af5..32d9d504 100644 --- a/src/CRE/rob/ex_block.cpp +++ b/src/CRE/rob/ex_block.cpp @@ -541,7 +541,7 @@ int32_t OsageCollision::cls_ball_oidashi(vec3& vec, const vec3& p, const vec3& c } // 0x140484540 -int32_t OsageCollision::cls_capsule_oidashi(vec3& vec, const vec3& p, const OsageCollision::Work* cls, const float_t r) { +int32_t OsageCollision::cls_capsule_oidashi(vec3& vec, const vec3& p, const OsageCollision::Work* cls, const float_t r) { vec3 v11 = p - cls->pos[0]; float_t v17 = vec3::dot(v11, cls->vec_center); diff --git a/src/CRE/rob/rob.cpp b/src/CRE/rob/rob.cpp index 7ad618ff..d888b281 100644 --- a/src/CRE/rob/rob.cpp +++ b/src/CRE/rob/rob.cpp @@ -11315,6 +11315,10 @@ void rob_chara_array_set_alpha_obj_flags(int32_t chara_id, float_t alpha, mdl::O } } +void rob_chara_array_set_visibility(int32_t chara_id, bool value) { + rob_chara_array[chara_id].set_visibility(value); +} + bool pv_osage_manager_array_get_disp() { bool disp = false; for (int32_t i = 0; i < ROB_CHARA_COUNT; i++) diff --git a/src/CRE/rob/rob.hpp b/src/CRE/rob/rob.hpp index 60c1b2f4..460efdaf 100644 --- a/src/CRE/rob/rob.hpp +++ b/src/CRE/rob/rob.hpp @@ -3529,6 +3529,7 @@ extern int32_t rob_chara_array_init_chara_index(chara_index chara_index, extern void rob_chara_array_free_chara_id(int32_t chara_id); extern void rob_chara_array_reset_bone_data_item_equip(int32_t chara_id); extern void rob_chara_array_set_alpha_obj_flags(int32_t chara_id, float_t alpha, mdl::ObjFlags flags); +extern void rob_chara_array_set_visibility(int32_t chara_id, bool value); extern bool rob_chara_check_for_ageageagain_module(chara_index chara_index, int32_t module_index); diff --git a/src/CRE/sprite.cpp b/src/CRE/sprite.cpp index 626ad925..8fd170a8 100644 --- a/src/CRE/sprite.cpp +++ b/src/CRE/sprite.cpp @@ -6,23 +6,46 @@ #include "sprite.hpp" #include "../KKdLib/prj/shared_ptr.hpp" #include "../KKdLib/prj/stack_allocator.hpp" +#include "../KKdLib/txp.hpp" #include "data.hpp" #include "file_handler.hpp" -#include "resolution_mode.hpp" - -struct SpriteHeader { - -}; +#include "shader_ft.hpp" +#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 SprSet { +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; - int32_t index; - SpriteHeaderFile* header_file; - SpriteHeader* header; + uint32_t index; + const SpriteHeaderFile* header_file; + const SpriteHeader* header; texture** textures; int32_t load_count; p_file_handler file_handler; @@ -30,47 +53,969 @@ struct SprSet { prj::shared_ptr alloc_handler; std::string file; - SprSet(int32_t index); - ~SprSet(); + SprSet(uint32_t index); + virtual ~SprSet(); + const char* GetName(spr_info info); + rectangle GetRectangle(spr_info info); + resolution_mode GetResolutionMode(spr_info info); + texture* GetTexture(spr_info info); + bool LoadData(); + bool LoadFile(); + bool LoadTexture(); + void ReadFile(const char* file, std::string& mdata_dir, void* data); void Unload(); bool UnloadTexture(); }; +struct sprite_draw_vertex { + vec3 pos; + vec2 uv[2]; + vec4u8 color; +}; + +struct sprite_draw_param { + bool blend; + GLenum blend_src_rgb; + GLenum blend_src_alpha; + GLenum blend_dst_rgb; + GLenum blend_dst_alpha; + + bool copy_texture; + GLint copy_texture_x; + GLint copy_texture_y; + GLint copy_texture_width; + GLint copy_texture_height; + + int32_t shader; + int32_t tex_0_type; + int32_t tex_1_type; + int32_t combiner; + + GLuint texture[2]; + GLuint sampler; + + GLenum mode; + GLint first; + GLsizei count; +}; + namespace spr { struct SpriteManager { std::map sets; - std::list reqlist[4][64]; + std::map sets_modern; + std::list reqlist[4][SPR_PRIO_MAX * 2]; float_t aspect[2]; - std::pair> field_1018; - std::pair> field_102C; + std::pair field_1018[2]; int32_t index; mat4 projection; mat4 mat; resolution_mode resolution_mode; + std::vector draw_param_buffer; + std::vector vertex_buffer; + GLuint vao; + GLuint vbo; + size_t vbo_vertex_count; + SpriteManager(); ~SpriteManager(); + void AddSprSets(const sprite_database* spr_db, bool modern); void Clear(); + void Draw(render_context* rctx, + int32_t index, bool font, texture* tex, const mat4& proj); SprSet* GetSet(int32_t index); + SprSet* GetSetModern(uint32_t set_id); + bool GetSetReady(int32_t index); + bool GetSetReadyModern(uint32_t set_id); + uint32_t GetSetSpriteNum(int32_t index); + uint32_t GetSetSpriteNumModern(uint32_t set_id); + uint32_t GetSetTextureNum(int32_t index); + uint32_t GetSetTextureNumModern(uint32_t set_id); + const char* GetSprName(spr_info info); + const char* GetSprNameModern(uint32_t set_id, spr_info info); + rectangle GetSprRectangle(spr_info info); + rectangle GetSprRectangleModern(uint32_t set_id, spr_info info); + texture* GetSprTexture(spr_info info); + texture* GetSprTextureModern(uint32_t set_id, spr_info info); + bool LoadFile(int32_t index); + bool LoadFileModern(uint32_t id); + 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 ReadFileModern(uint32_t id, const char* file, std::string& mdata_dir, void* data); + void ReadFileModern(uint32_t id, const char* file, std::string&& mdata_dir, void* data); + void RemoveSprSets(const sprite_database* spr_db, bool modern); void ResetIndex(); + void ResetReqList(); void ResetResData(); + void UnloadSet(int32_t index); + void UnloadSetModern(uint32_t set_id); }; - - SprSet* spr::SpriteManager::GetSet(int32_t index) { + + static void calc_sprite_vertex(spr::SprArgs* args, vec3* vtx, mat4* mat, bool font); + static int32_t calc_sprite_texture_param(SprArgs* args, spr::TexParam* param, vec3* vtx, bool font); + + static void draw_sprite(render_context* rctx, SprArgs& args, bool font, + const mat4& mat, int32_t x_min, int32_t y_min, int32_t x_max, int32_t y_max, + std::vector& draw_param_buffer, std::vector& vertex_buffer); + static void draw_sprite_begin(); + static void draw_sprite_end(); + static void draw_sprite_scale(spr::SprArgs* args); +} + +spr::SpriteManager* sprite_manager; + +const size_t sprite_vertex_array_max_count = 0x2000; + +spr::SpriteVertex sprite_vertex_array[sprite_vertex_array_max_count]; +size_t sprite_vertex_array_count; + +extern render_context* rctx_ptr; + +const GLenum spr_blend_param[6][4] = { + { GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ZERO, GL_ONE }, + { GL_SRC_ALPHA, GL_ONE_MINUS_SRC_COLOR, GL_ZERO, GL_ONE }, + { GL_SRC_ALPHA, GL_ONE, GL_ZERO, GL_ONE }, + { GL_DST_COLOR, GL_ZERO, GL_ZERO, GL_ONE }, + { GL_ONE, GL_ZERO, GL_ONE, GL_ZERO }, + { GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ZERO, GL_ONE }, +}; + +namespace spr { + SprArgs::SprArgs() : kind(), modern(), attr(), blend(), index(), layer(), + prio(), resolution_mode_screen(), resolution_mode_sprite(), texture(), + shader(), vertex_array(), num_vertex(), flags(), field_CC(), next() { + Reset(); + } + + void SprArgs::Reset() { + kind = SPR_KIND_NORMAL; + id = {}; + color = { 0xFF, 0xFF, 0xFF, 0xFF }; + attr = (SprAttr)0; + blend = 0; + index = -1; + layer = 0; + prio = SPR_PRIO_DEFAULT; + resolution_mode_screen = RESOLUTION_MODE_HD; + resolution_mode_sprite = RESOLUTION_MODE_HD; + center = 0.0f; + trans = 0.0f; + scale = 1.0f; + rot = 0.0f; + skew_angle = 0.0f; + mat = mat4_identity; + texture = 0; + shader = SHADER_FT_FFP; + vertex_array = 0; + num_vertex = 0; + flags = (SprArgs::Flags)0; + sprite_size = 0.0f; + field_CC = 0; + texture_pos = 0.0f; + texture_size = 0.0f; + next = 0; + } + + void SprArgs::SetSpriteSize(vec2 size) { + if (flags & SPRITE_SIZE) + return; + + enum_or(flags, SPRITE_SIZE); + sprite_size = size; + field_CC = 0; + } + + void SprArgs::SetTexturePosSize(float_t x, float_t y, float_t width, float_t height) { + if (flags & TEXTURE_POS_SIZE) + return; + + enum_or(flags, TEXTURE_POS_SIZE); + texture_pos.x = x; + texture_pos.y = y; + texture_size.x = width; + texture_size.y = height; + } + + void SprArgs::SetVertexArray(SpriteVertex* vertex_array, size_t num_vertex) { + if (sprite_vertex_array_count + num_vertex >= sprite_vertex_array_max_count) + return; + + this->num_vertex = num_vertex; + this->vertex_array = &sprite_vertex_array[sprite_vertex_array_count]; + memmove(this->vertex_array, vertex_array, sizeof(SpriteVertex) * num_vertex); + sprite_vertex_array_count += num_vertex; + } + + void SprArgs::SetNext(SprArgs* args, SprArgs* next) { + while (args->next) + args = args->next; + args->next = next; + next->kind = SPR_KIND_LINE; + } + + vec2 proj_sprite_3d_line(vec3 vec, bool offset) { + camera* cam = rctx_ptr->camera; + + mat4_mult_vec3_trans(&cam->view, &vec, &vec); + if (fabsf(vec.z) < 1.0e-10f) + return 0.0f; + + vec2 sc_vec; + sc_vec.x = cam->fov_correct_height * vec.x * (1.0f / vec.z); + sc_vec.y = cam->fov_correct_height * vec.y * (1.0f / vec.z); + + resolution_struct* res_wind_int = res_window_internal_get(); + sc_vec.x = (float_t)res_wind_int->width * 0.5f - sc_vec.x; + sc_vec.y = (float_t)res_wind_int->height * 0.5f + sc_vec.y; + if (offset) { + resolution_struct* res_wind = res_window_get(); + sc_vec.x = (float_t)res_wind_int->x_offset + sc_vec.x; + sc_vec.y = (float_t)(res_wind->height + - res_wind_int->y_offset - res_wind_int->height) + sc_vec.y; + } + return sc_vec; + } + + void put_cross(const mat4& mat, vec4u8 color_x, vec4u8 color_y, vec4u8 color_z) { + vec3 v5 = { 0.0f, 0.0f, 0.0f }; + vec3 v6; + mat4_mult_vec3_trans(&mat, &v5, &v6); + + vec3 v7 = v6; + + v5 = { 1.0f, 0.0f, 0.0f }; + mat4_mult_vec3_trans(&mat, &v5, &v6); + put_sprite_3d_line(v7, v6, color_x); + + v5 = { 0.0f, 1.0f, 0.0f }; + mat4_mult_vec3_trans(&mat, &v5, &v6); + put_sprite_3d_line(v7, v6, color_y); + + v5 = { 0.0f, 0.0f, 1.0f }; + mat4_mult_vec3_trans(&mat, &v5, &v6); + put_sprite_3d_line(v7, v6, color_z); + } + + void put_rgb_cross(const mat4& mat) { + spr::put_cross(mat, + { 0xFF, 0x00, 0x00, 0xFF }, + { 0x00, 0xFF, 0x00, 0xFF }, + { 0x00, 0x00, 0xFF, 0xFF }); + } + + spr::SprArgs* put_sprite(const spr::SprArgs& args, const sprite_database* spr_db) { + return sprite_manager->PutSprite(args, spr_db); + } + + void put_sprite_3d_line(vec3 p1, vec3 p2, vec4u8 color) { + vec2 sc_p1 = proj_sprite_3d_line(p1, true); + vec2 sc_p2 = proj_sprite_3d_line(p2, true); + spr::put_sprite_line(sc_p1, sc_p2, RESOLUTION_MODE_MAX, SPR_PRIO_DEBUG, color, 0); + } + + void put_sprite_line(vec2 p1, vec2 p2, resolution_mode mode, spr::SprPrio prio, vec4u8 color, int32_t layer) { + spr::SprArgs args; + args.trans.x = p1.x; + args.trans.y = p1.y; + args.trans.z = 0.0f; + args.layer = layer; + args.kind = SPR_KIND_LINES; + args.resolution_mode_screen = mode; + args.resolution_mode_sprite = mode; + args.prio = prio; + args.color = color; + args.SetSpriteSize({ p2.x - p1.x, p2.y - p1.y }); + enum_or(args.attr, SPR_ATTR_MATRIX); + sprite_manager->PutSprite(args, 0); + } + + void put_sprite_multi(rectangle rect, resolution_mode mode, spr::SprPrio prio, vec4u8 color, int32_t layer) { + spr::SprArgs args; + args.trans.x = rect.pos.x; + args.trans.y = rect.pos.y; + args.trans.z = 0.0f; + args.layer = layer; + args.kind = SPR_KIND_MULTI; + args.resolution_mode_screen = mode; + args.resolution_mode_sprite = mode; + args.prio = prio; + args.color = color; + args.SetSpriteSize(rect.size); + enum_or(args.attr, SPR_ATTR_MATRIX); + sprite_manager->PutSprite(args, 0); + } + + void put_sprite_rect(rectangle rect, resolution_mode mode, spr::SprPrio prio, vec4u8 color, int32_t layer) { + spr::SprArgs args; + args.trans.x = rect.pos.x; + args.trans.y = rect.pos.y; + args.trans.z = 0.0f; + args.layer = layer; + args.kind = SPR_KIND_RECT; + args.resolution_mode_screen = mode; + args.resolution_mode_sprite = mode; + args.prio = prio; + args.color = color; + args.SetSpriteSize(rect.size); + enum_or(args.attr, SPR_ATTR_MATRIX); + sprite_manager->PutSprite(args, 0); + } + + void put_sprite_triangles(SpriteVertex* vert, size_t size, resolution_mode mode, + SprPrio prio, int32_t spr_id, int32_t layer, const sprite_database* spr_db) { + spr::SprArgs args; + args.layer = layer; + args.kind = SPR_KIND_TRIANGLE; + args.resolution_mode_screen = mode; + args.resolution_mode_sprite = mode; + args.prio = prio; + args.color = vert[0].color; + 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); + sprite_manager->PutSprite(args, spr_db); + } +} + +void sprite_manager_init() { + if (!sprite_manager) + sprite_manager = new spr::SpriteManager; +} + +void sprite_manager_add_spr_sets(const sprite_database* spr_db, bool modern) { + sprite_manager->AddSprSets(spr_db, modern); +} + +void sprite_manager_clear() { + sprite_manager->Clear(); +} + +void sprite_manager_draw(render_context* rctx, + int32_t index, bool font, texture* tex, const mat4& proj) { + sprite_manager->Draw(rctx, index, font, tex, proj); +} + +int32_t sprite_manager_get_index() { + return sprite_manager->index; +} + +size_t sprite_manager_get_reqlist_count(int32_t index) { + size_t count = 0; + for (const auto& i : sprite_manager->reqlist[index]) + count += i.size(); + return count; +} + +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); +} + +uint32_t sprite_manager_get_set_sprite_num(uint32_t set_id, const sprite_database* spr_db) { + return sprite_manager->GetSetSpriteNum(spr_db->get_spr_set_by_id(set_id)->index); +} + +uint32_t sprite_manager_get_set_texture_num(uint32_t set_id, const sprite_database* spr_db) { + return sprite_manager->GetSetTextureNum(spr_db->get_spr_set_by_id(set_id)->index); +} + +const char* sprite_manager_get_spr_name(uint32_t spr_id, const sprite_database* spr_db) { + return sprite_manager->GetSprName(spr_db->get_spr_by_id(spr_id)->info); +} + +rectangle sprite_manager_get_spr_rectangle(uint32_t spr_id, const sprite_database* spr_db) { + return sprite_manager->GetSprRectangle(spr_db->get_spr_by_id(spr_id)->info); +} + +texture* sprite_manager_get_spr_texture(uint32_t spr_id, const sprite_database* spr_db) { + return sprite_manager->GetSprTexture(spr_db->get_spr_by_id(spr_id)->info); +} + +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); +} + +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); + sprite_manager->ReadFile(spr_set->index, spr_set->file_name.c_str(), mdata_dir, data); +} + +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); + sprite_manager->ReadFile(spr_set->index, spr_set->file_name.c_str(), mdata_dir, data); +} + +void sprite_manager_remove_spr_sets(const sprite_database* spr_db, bool modern) { + sprite_manager->RemoveSprSets(spr_db, modern); +} + +void sprite_manager_reset_req_list() { + sprite_manager->ResetReqList(); +} + +void sprite_manager_reset_res_data() { + sprite_manager->ResetResData(); +} + +void sprite_manager_set_index(int32_t value) { + sprite_manager->index = value; +} + +void sprite_manager_set_res(double_t aspect, int32_t width, int32_t height) { + if (!sprite_manager) + return; + + sprite_manager->aspect[0] = (float_t)aspect; + sprite_manager->field_1018[0].second = { 0.0f, 0.0f, (float_t)width, (float_t)height }; + sprite_manager->aspect[1] = (float_t)aspect; + sprite_manager->field_1018[1].second = { 0.0f, 0.0f, (float_t)width, (float_t)height }; +} + +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_free() { + if (sprite_manager) { + delete sprite_manager; + sprite_manager = 0; + } +} + +namespace spr { + SpriteManager::SpriteManager() : aspect(), index() { + ResetIndex(); + resolution_mode = RESOLUTION_MODE_MAX; + + resolution_struct res = resolution_struct(RESOLUTION_MODE_HD); + + aspect[0] = (float_t)res.aspect; + field_1018[0].first = res.resolution_mode; + field_1018[0].second = { 0.0f, 0.0f, (float_t)res.width, (float_t)res.height }; + + aspect[1] = (float_t)res.aspect; + field_1018[1].first = res.resolution_mode; + field_1018[1].second = { 0.0f, 0.0f, (float_t)res.width, (float_t)res.height }; + + mat = mat4_identity; + + glGenVertexArrays(1, &vao); + gl_state_bind_vertex_array(vao, true); + + glGenBuffers(1, &vbo); + gl_state_bind_array_buffer(vbo, true); + + vbo_vertex_count = 1024; + + static const GLsizei buffer_size = sizeof(sprite_draw_vertex); + + if (GLAD_GL_VERSION_4_4) + glBufferStorage(GL_ARRAY_BUFFER, + (GLsizeiptr)(buffer_size * vbo_vertex_count), 0, GL_DYNAMIC_STORAGE_BIT); + else + glBufferData(GL_ARRAY_BUFFER, + (GLsizeiptr)(buffer_size * vbo_vertex_count), 0, GL_DYNAMIC_DRAW); + + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, buffer_size, + (void*)offsetof(sprite_draw_vertex, pos)); + glEnableVertexAttribArray(1); + glVertexAttribPointer(1, 4, GL_UNSIGNED_BYTE, GL_TRUE, buffer_size, + (void*)offsetof(sprite_draw_vertex, color)); + glEnableVertexAttribArray(2); + glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, buffer_size, + (void*)offsetof(sprite_draw_vertex, uv[0])); + glEnableVertexAttribArray(3); + glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, buffer_size, + (void*)offsetof(sprite_draw_vertex, uv[1])); + + gl_state_bind_array_buffer(0); + gl_state_bind_vertex_array(0); + + } + + SpriteManager::~SpriteManager() { + Clear(); + + if (vbo) { + glDeleteBuffers(1, &vbo); + vbo = 0; + } + + if (vao) { + glDeleteVertexArrays(1, &vao); + vao = 0; + } + } + + void SpriteManager::AddSprSets(const sprite_database* spr_db, bool modern) { + if (modern) + for (auto& i : spr_db->spr_set_ids) + sets_modern.insert({ i.first, SprSet(i.first) }); + else + for (auto& i : spr_db->spr_set_indices) + sets.insert({ i.first, SprSet(i.first) }); + } + + void SpriteManager::Clear() { + for (int32_t i = 0; i < 4; i++) + for (int32_t j = 0; j < 64; j++) + reqlist[i][j].clear(); + + for (auto i : sets) + i.second.Unload(); + sets.clear(); + + draw_param_buffer.clear(); + vertex_buffer.clear(); + } + + void SpriteManager::Draw(render_context* rctx, + int32_t index, bool font, texture* tex, const mat4& proj) { + draw_sprite_begin(); + + ::resolution_mode mode = res_window_get()->resolution_mode; + if (index == 2 && resolution_mode != RESOLUTION_MODE_MAX) + res_window_get()->resolution_mode = resolution_mode; + + GLint v43[4]; + glGetIntegerv(GL_VIEWPORT, v43); + + auto reqlist = this->reqlist[index]; + for (int32_t i = 0; i < 2; i++) { + int32_t x_min; + int32_t y_min; + int32_t x_max; + int32_t y_max; + if (index == 0 || index == 3) { + camera* cam = rctx->camera; + float_t sprite_half_width = (float_t)cam->sprite_width * 0.5f; + float_t sprite_half_height = (float_t)cam->sprite_height * 0.5f; + + float_t aet_depth = cam->aet_depth; + float_t aet_depth_1 = 1.0f / cam->aet_depth; + + float_t v15a = sprite_half_height * aspect[i] * 0.2f * aet_depth_1; + float_t v15b = sprite_half_height * 0.2f * aet_depth_1; + + mat4 proj; + mat4_frustrum(-v15a, v15a, v15b, -v15b, 0.2, 3000.0, &proj); + + vec3 eye = { sprite_half_width, sprite_half_height, aet_depth }; + vec3 target = { sprite_half_width, sprite_half_height, 0.0f }; + vec3 up = { 0.0f, 1.0f, 0.0f }; + + mat4 view; + mat4_look_at(&eye, &target, &up, &view); + mat4_mult(&view, &proj, &projection); + + vec2 min; + vec2 max; + resolution_mode_scale_pos(min, mode, field_1018[i].second.pos, field_1018[i].first); + resolution_mode_scale_pos(max, mode, + field_1018[i].second.pos + field_1018[i].second.size, field_1018[i].first); + x_min = (int32_t)min.x; + y_min = (int32_t)min.y; + x_max = (int32_t)(max.x - min.x); + y_max = (int32_t)(max.y - min.y); + glViewport(x_min, y_min, x_max, y_max); + } + else { + projection = proj; + + x_min = v43[0]; + y_min = v43[1]; + x_max = v43[2]; + y_max = v43[3]; + } + + float_t v23 = (float_t)x_max * 0.5f; + float_t v24 = (float_t)x_min + v23; + float_t v25 = (float_t)y_max * 0.5f; + float_t v26 = (float_t)y_min + v25; + + mat = projection; + mat.row0.x = v23 * projection.row0.x + v24 * projection.row0.w; + mat.row1.x = v23 * projection.row1.x + v24 * projection.row1.w; + mat.row2.x = v23 * projection.row2.x + v24 * projection.row2.w; + mat.row3.x = v23 * projection.row3.x + v24 * projection.row3.w; + mat.row0.y = v25 * projection.row0.y + v26 * projection.row0.w; + mat.row1.y = v25 * projection.row1.y + v26 * projection.row1.w; + mat.row2.y = v25 * projection.row2.y + v26 * projection.row2.w; + mat.row3.y = v25 * projection.row3.y + v26 * projection.row3.w; + + sprite_scene_shader_data shader_data = {}; + shader_data.g_framebuffer_size = { + 1.0f / (float_t)tex->width, + 1.0f / (float_t)tex->height, 0.0f, 0.0f + }; + mat4_transpose(&projection, &shader_data.g_transform); + rctx->sprite_scene_ubo.WriteMapMemory(shader_data); + + draw_param_buffer.clear(); + vertex_buffer.clear(); + + for (uint32_t j = SPR_PRIO_MAX; j; j--, reqlist++) + for (auto& k : *reqlist) + draw_sprite(rctx, k, font, mat, x_min, y_min, x_max, y_max, + draw_param_buffer, vertex_buffer); + + static const GLsizei buffer_size = sizeof(sprite_draw_vertex); + + if (vbo_vertex_count < vertex_buffer.size()) { + while (vbo_vertex_count < vertex_buffer.size()) + vbo_vertex_count *= 2; + + glDeleteBuffers(1, &vbo); + glGenBuffers(1, &vbo); + + gl_state_bind_vertex_array(vao, true); + gl_state_bind_array_buffer(vbo, true); + + if (GLAD_GL_VERSION_4_4) + glBufferStorage(GL_ARRAY_BUFFER, + (GLsizeiptr)(buffer_size * vbo_vertex_count), 0, GL_DYNAMIC_STORAGE_BIT); + else + glBufferData(GL_ARRAY_BUFFER, + (GLsizeiptr)(buffer_size * vbo_vertex_count), 0, GL_DYNAMIC_DRAW); + glBufferSubData(GL_ARRAY_BUFFER, 0, (GLsizeiptr)(buffer_size + * vertex_buffer.size()), vertex_buffer.data()); + + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, buffer_size, + (void*)offsetof(sprite_draw_vertex, pos)); + glEnableVertexAttribArray(1); + glVertexAttribPointer(1, 4, GL_UNSIGNED_BYTE, GL_TRUE, buffer_size, + (void*)offsetof(sprite_draw_vertex, color)); + glEnableVertexAttribArray(2); + glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, buffer_size, + (void*)offsetof(sprite_draw_vertex, uv[0])); + glEnableVertexAttribArray(3); + glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, buffer_size, + (void*)offsetof(sprite_draw_vertex, uv[1])); + + gl_state_bind_array_buffer(0); + gl_state_bind_vertex_array(0); + } + else { + if (GLAD_GL_VERSION_4_5) + glNamedBufferSubData(vbo, 0, (GLsizeiptr)(buffer_size + * vertex_buffer.size()), vertex_buffer.data()); + else { + gl_state_bind_array_buffer(vbo); + glBufferSubData(GL_ARRAY_BUFFER, 0, (GLsizeiptr)(buffer_size + * vertex_buffer.size()), vertex_buffer.data()); + gl_state_bind_array_buffer(0); + } + } + + rctx->sprite_scene_ubo.Bind(0); + + gl_state_active_bind_texture_2d(7, tex->tex); + + gl_state_bind_vertex_array(vao); + gl_state_bind_array_buffer(vbo); + + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, buffer_size, + (void*)offsetof(sprite_draw_vertex, pos)); + glEnableVertexAttribArray(1); + glVertexAttribPointer(1, 4, GL_UNSIGNED_BYTE, GL_TRUE, buffer_size, + (void*)offsetof(sprite_draw_vertex, color)); + glEnableVertexAttribArray(2); + glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, buffer_size, + (void*)offsetof(sprite_draw_vertex, uv[0])); + glEnableVertexAttribArray(3); + glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, buffer_size, + (void*)offsetof(sprite_draw_vertex, uv[1])); + + for (sprite_draw_param& j : draw_param_buffer) { + if (j.blend) { + gl_state_enable_blend(); + gl_state_set_blend_func_separate( + j.blend_src_rgb, j.blend_dst_rgb, + j.blend_src_alpha, j.blend_dst_alpha); + + if (j.copy_texture) { + gl_state_active_texture(7); + glCopyTexSubImage2D(GL_TEXTURE_2D, 0, j.copy_texture_x, j.copy_texture_y, + j.copy_texture_x, j.copy_texture_y, j.copy_texture_width, j.copy_texture_height); + } + } + else + gl_state_disable_blend(); + + + if (j.shader == SHADER_FT_SPRITE) { + uniform_value[U_TEX_0_TYPE] = j.tex_0_type; + uniform_value[U_TEX_1_TYPE] = j.tex_1_type; + uniform_value[U_COMBINER] = j.combiner; + } + + if (j.texture[0]) { + gl_state_active_bind_texture_2d(0, j.texture[0]); + gl_state_bind_sampler(0, j.sampler); + + if (j.texture[1]) { + gl_state_active_bind_texture_2d(1, j.texture[1]); + gl_state_bind_sampler(1, j.sampler); + } + } + + shaders_ft.set(j.shader); + shaders_ft.draw_arrays(j.mode, j.first, j.count); + } + gl_state_bind_vertex_array(0); + gl_state_bind_array_buffer(0); + } + + if (index == 2 && resolution_mode != RESOLUTION_MODE_MAX) + res_window_get()->resolution_mode = mode; + + draw_sprite_end(); + } + + SprSet* SpriteManager::GetSet(int32_t index) { auto elem = sets.find(index); if (elem != sets.end()) return &elem->second; return 0; } -} -spr::SpriteManager sprite_manager; + SprSet* SpriteManager::GetSetModern(uint32_t set_id) { + auto elem = sets_modern.find(set_id); + if (elem != sets_modern.end()) + return &elem->second; + return 0; + } -namespace spr { - void calc_sprite_vertex(spr::SprArgs* args, vec3* vtx, mat4* mat, bool font) { - vtx[0] = 0.0f; + bool SpriteManager::GetSetReady(int32_t index) { + SprSet* set = GetSet(index); + if (set) + return set->ready; + return false; + } + + bool SpriteManager::GetSetReadyModern(uint32_t set_id) { + SprSet* set = GetSetModern(set_id); + if (set) + return set->ready; + return false; + } + + uint32_t SpriteManager::GetSetSpriteNum(int32_t index) { + SprSet* set = GetSet(index); + if (set) + return set->header->num_of_sprite; + return 0; + } + + uint32_t SpriteManager::GetSetSpriteNumModern(uint32_t set_id) { + SprSet* set = GetSetModern(set_id); + if (set) + return set->header->num_of_sprite; + return 0; + } + + uint32_t SpriteManager::GetSetTextureNum(int32_t index) { + SprSet* set = GetSet(index); + if (set) + return set->header->num_of_texture; + return 0; + } + + uint32_t SpriteManager::GetSetTextureNumModern(uint32_t set_id) { + SprSet* set = GetSetModern(set_id); + if (set) + return set->header->num_of_texture; + return 0; + } + + const char* SpriteManager::GetSprName(spr_info info) { + SprSet* set = GetSet(info.set_index & 0x0FFF); + if (set) + return set->GetName(info); + return "(null)"; + } + + const char* SpriteManager::GetSprNameModern(uint32_t set_id, spr_info info) { + SprSet* set = GetSetModern(set_id); + if (set) + return set->GetName(info); + return "(null)"; + } + + rectangle SpriteManager::GetSprRectangle(spr_info info) { + SprSet* set = GetSet(info.set_index & 0x0FFF); + if (set) + return set->GetRectangle(info); + return {}; + } + + rectangle SpriteManager::GetSprRectangleModern(uint32_t set_id, spr_info info) { + SprSet* set = GetSetModern(set_id); + if (set) + return set->GetRectangle(info); + return {}; + } + + texture* SpriteManager::GetSprTexture(spr_info info) { + SprSet* set = GetSet(info.set_index & 0x0FFF); + if (set) + return set->GetTexture(info); + return 0; + } + + texture* SpriteManager::GetSprTextureModern(uint32_t set_id, spr_info info) { + SprSet* set = GetSetModern(set_id); + if (set) + return set->GetTexture(info); + return 0; + } + + bool SpriteManager::LoadFile(int32_t index) { + SprSet* set = GetSet(index); + if (set) + return set->LoadFile(); + return false; + } + + bool SpriteManager::LoadFileModern(uint32_t set_id) { + SprSet* set = GetSetModern(set_id); + if (set) + return set->LoadFile(); + return false; + } + + SprArgs* SpriteManager::PutSprite(const SprArgs& args, const sprite_database* spr_db) { + int32_t index = args.index; + if (index == -1) + index = this->index; + + auto reqlist = &this->reqlist[index][args.layer * SPR_PRIO_MAX + args.prio]; + spr_info info = args.id.info; + if (args.kind == SPR_KIND_NORMAL) + info = spr_db->get_spr_by_id(args.id.index)->info; + + if (info.not_null()) { + SprSet* set = GetSet(info.set_index & 0x0FFF); + if (!set || !set->ready) + return 0; + + reqlist->push_back(args); + SprArgs& v13 = reqlist->back(); + v13.id.info = info; + v13.texture = set->GetTexture(info); + rectangle rect = set->GetRectangle(info); + v13.SetSpriteSize({ rect.size.x, rect.size.y }); + v13.SetTexturePosSize(rect.pos.x, rect.pos.y, rect.size.x, rect.size.y); + if (v13.resolution_mode_sprite != RESOLUTION_MODE_MAX) + v13.resolution_mode_sprite = set->GetResolutionMode(v13.id.info); + return &v13; + } + + if (args.texture) { + reqlist->push_back(args); + SprArgs& v16 = reqlist->back(); + v16.id.index = -1; + v16.SetSpriteSize({ (float_t)v16.texture->width, (float_t)v16.texture->height }); + v16.SetTexturePosSize(0.0, 0.0, (float_t)v16.texture->width, (float_t)v16.texture->height); + return &v16; + } + else { + reqlist->push_back(args); + SprArgs& v18 = reqlist->back(); + v18.id.index = -1; + return &v18; + } + } + + void SpriteManager::ReadFile(int32_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) { + SprSet* set = GetSet(index); + if (set) + set->ReadFile(file, mdata_dir, data); + } + + void SpriteManager::ReadFileModern(uint32_t set_id, + const char* file, std::string& mdata_dir, void* data) { + SprSet* set = GetSetModern(index); + if (set) + set->ReadFile(file, mdata_dir, data); + } + + void SpriteManager::ReadFileModern(uint32_t set_id, + const char* file, std::string&& mdata_dir, void* data) { + SprSet* set = GetSetModern(index); + if (set) + set->ReadFile(file, mdata_dir, data); + } + + void SpriteManager::ResetIndex() { + index = 0; + } + + void SpriteManager::RemoveSprSets(const sprite_database* spr_db, bool modern) { + if (modern) + for (auto& i : spr_db->spr_set_ids) + sets_modern.erase(i.first); + else + for (auto& i : spr_db->spr_set_indices) + sets.erase(i.first); + } + + void SpriteManager::ResetReqList() { + for (auto& i : reqlist) + for (auto& j : i) + j.clear(); + ResetIndex(); + sprite_vertex_array_count = 0; + } + + void SpriteManager::ResetResData() { + ResetIndex(); + resolution_mode = RESOLUTION_MODE_MAX; + + resolution_struct* res = res_window_get(); + + aspect[0] = (float_t)res->aspect; + field_1018[0].first = res->resolution_mode; + field_1018[0].second = { 0.0f, 0.0f, (float_t)res->width, (float_t)res->height }; + + aspect[1] = (float_t)res->aspect; + field_1018[1].first = res->resolution_mode; + field_1018[1].second = { 0.0f, 0.0f, (float_t)res->width, (float_t)res->height }; + + mat = mat4_identity; + } + + void SpriteManager::UnloadSet(int32_t index) { + SprSet* set = GetSet(index); + if (set) + set->Unload(); + } + + void SpriteManager::UnloadSetModern(uint32_t set_id) { + SprSet* set = GetSetModern(set_id); + if (set) + set->Unload(); + } + + static void calc_sprite_vertex(spr::SprArgs* args, vec3* vtx, mat4* mat, bool font) { + vtx[0].x = 0.0f; + vtx[0].y = 0.0f; vtx[1].x = 0.0f; vtx[1].y = args->sprite_size.y; vtx[1].z = 0.0f; @@ -156,7 +1101,7 @@ namespace spr { vtx[3].y = vtx[3].y + skew_height; } - mat4_set_translation(&m, &args->trans); + mat4_translate(&args->trans, &m); if (fabsf(args->rot.x) > 0.000001f) mat4_rotate_x_mult(&m, args->rot.x, &m); if (fabsf(args->rot.y) > 0.000001f) @@ -168,7 +1113,7 @@ namespace spr { mat4_translate_mult(&m, ¢er, &m); } else { - mat4_set_translation(&m, &args->trans); + mat4_translate(&args->trans, &m); mat4_scale_rot(&m, &args->scale, &m); } @@ -182,86 +1127,592 @@ namespace spr { if (mat) *mat = m; } -} -void sprite_manager_init() { - sprite_manager = {}; -} + static int32_t calc_sprite_texture_param(SprArgs* args, spr::TexParam* param, vec3* vtx, bool font) { + int32_t tex_param_count = 0; + texture* tex = args->texture; + while (args) { + param->texture = args->texture; -void sprite_manager_load_set(int32_t set_id, std::string* mdata_dir) { - data_struct* aft_data = &data_list[DATA_AFT]; - sprite_database* aft_spr_db = &aft_data->data_ft.spr_db; + float_t width = (float_t)args->texture->width; + float_t height = (float_t)args->texture->height; - const spr_db_spr_set* spr_set = aft_spr_db->get_spr_set_by_id(set_id); - //sprite_manager.ReadFile(spr_set->index, spr_set->file_name.c_str(), mdata_dir); -} + float_t u_scale = 1.0f / width; + float_t v_scale = 1.0f / height; -void sprite_manager_reset_res_data() { - sprite_manager.ResetResData(); -} + if (!args->num_vertex) { + vec2 uv00; + vec2 uv01; + vec2 uv10; + vec2 uv11; + if (args->kind == SPR_KIND_LINE) { + vec3 v42[4]; + mat4 mat; + calc_sprite_vertex(args, v42, &mat, font); + mat4_inverse(&mat, &mat); + mat4_mult_vec3_trans(&mat, &vtx[0], &v42[0]); + mat4_mult_vec3_trans(&mat, &vtx[1], &v42[1]); + mat4_mult_vec3_trans(&mat, &vtx[2], &v42[2]); + mat4_mult_vec3_trans(&mat, &vtx[3], &v42[3]); + uv00 = *(vec2*)&v42[0].x; + uv01 = *(vec2*)&v42[1].x; + uv10 = *(vec2*)&v42[2].x; + uv11 = *(vec2*)&v42[3].x; + } + else { + uv00.x = 0.0f; + uv00.y = 0.0f; + uv01.x = 0.0f; + uv01.y = args->texture_size.y; + uv10.x = args->texture_size.x; + uv10.y = args->texture_size.y; + uv11.x = args->texture_size.x; + uv11.y = 0.0f; + } -void sprite_manager_free() { - sprite_manager.Clear(); -} + vec2 texture_pos = args->texture_pos; + param->texcoord.uv[0].u = (uv00.x + texture_pos.x) * u_scale; + param->texcoord.uv[0].v = (height - (uv00.y + texture_pos.y)) * v_scale; + param->texcoord.uv[1].u = (uv01.x + texture_pos.x) * u_scale; + param->texcoord.uv[1].v = (height - (uv01.y + texture_pos.y)) * v_scale; + param->texcoord.uv[2].u = (uv10.x + texture_pos.x) * u_scale; + param->texcoord.uv[2].v = (height - (uv10.y + texture_pos.y)) * v_scale; + param->texcoord.uv[3].u = (uv11.x + texture_pos.x) * u_scale; + param->texcoord.uv[3].v = (height - (uv11.y + texture_pos.y)) * v_scale; + } + else if (font) { + SpriteVertex* vtx = args->vertex_array; + for (size_t i = args->num_vertex; i; i--, vtx++) { + vtx->uv.x = vtx->uv.x * u_scale; + vtx->uv.y = (height - vtx->uv.y) * v_scale; + } + } -namespace spr { - SpriteManager::SpriteManager() : aspect(), index() { - ResetIndex(); - resolution_mode = RESOLUTION_MODE_MAX; - - resolution_struct res = resolution_struct(RESOLUTION_MODE_HD); - - aspect[0] = (float_t)res.aspect; - field_1018.first = res.resolution_mode; - field_1018.second = { 0.0f, { (float_t)res.width, (float_t)res.height } }; - - aspect[1] = (float_t)res.aspect; - field_102C.first = res.resolution_mode; - field_102C.second = { 0.0f, { (float_t)res.width, (float_t)res.height } }; - - mat = mat4_identity; + args = args->next; + param++; + tex_param_count++; + } + return tex_param_count; } - SpriteManager::~SpriteManager() { - for (int32_t i = 0; i < 4; i++) - for (int32_t j = 0; j < 64; j++) - reqlist[i][j].clear(); - sets.clear(); + static void draw_sprite(render_context* rctx, SprArgs& args, bool font, + const mat4& mat, int32_t x_min, int32_t y_min, int32_t x_max, int32_t y_max, + std::vector& draw_param_buffer, std::vector& vertex_buffer) { + if (args.kind == SPR_KIND_LINE) + return; + + const vec4u8 color = args.color; + + if (font) + draw_sprite_scale(&args); + + vec3 vtx[4] = {}; + spr::TexParam tex_param[4] = {}; + + if (args.flags & SprArgs::SPRITE_SIZE) + calc_sprite_vertex(&args, vtx, 0, font); + + int32_t tex_param_count = 0; + if ((args.flags & SprArgs::TEXTURE_POS_SIZE) && args.texture) { + tex_param_count = calc_sprite_texture_param(&args, tex_param, vtx, font); + tex_param_count = min_def(tex_param_count, 2); + } + + mat4 mat_t; + mat4_transpose(&mat, &mat_t); + + draw_param_buffer.push_back({}); + sprite_draw_param& draw_param = draw_param_buffer.back(); + + if (!(args.attr & SPR_ATTR_NOBLEND)) { + const GLenum* blend = spr_blend_param[args.blend]; + draw_param.blend = true; + draw_param.blend_src_rgb = blend[0]; + draw_param.blend_dst_rgb = blend[1]; + draw_param.blend_src_alpha = blend[2]; + draw_param.blend_dst_alpha = blend[3]; + + if (args.blend == 5 && !args.num_vertex && args.kind == SPR_KIND_NORMAL) { + float_t v25 = 0.0f; + float_t v26 = 0.0f; + float_t v27 = 0.0f; + float_t v28 = 0.0f; + for (int32_t i = 0, j = 0; i < 4; i++) { + vec4 v; + *(vec3*)&v = vtx[i]; + v.w = 1.0f; + + float_t v31 = vec4::dot(mat_t.row3, v); + if (v31 * v31 <= 0.0001f) + continue; + + float_t v33 = vec4::dot(mat_t.row0, v) * (1.0f / v31); + float_t v34 = vec4::dot(mat_t.row1, v) * (1.0f / v31); + if (j) { + if (v25 > v33) + v25 = v33; + else if (v27 < v33) + v27 = v33; + + if (v26 > v34) + v26 = v34; + else if (v28 < v34) + v28 = v34; + } + else { + v25 = v33; + v27 = v33; + v26 = v34; + v28 = v34; + } + j++; + } + + int32_t v36 = (int32_t)v27 + 1; + int32_t v37 = (int32_t)v28 + 1; + int32_t v38 = (int32_t)v25 - 1; + int32_t v39 = (int32_t)v26 - 1; + + v36 = clamp_def(v36, x_min, x_min + x_max - 1); + v37 = clamp_def(v37, y_min, y_min + y_max - 1); + v38 = clamp_def(v38, x_min, x_min + x_max - 1); + v39 = clamp_def(v39, y_min, y_min + y_max - 1); + + int32_t v42 = v36 - v38 + 1; + int32_t v43 = v37 - v39 + 1; + if (v42 * v43 > 0) { + draw_param.copy_texture = true; + draw_param.copy_texture_x = v38; + draw_param.copy_texture_y = v39; + draw_param.copy_texture_width = v42; + draw_param.copy_texture_height = v43; + } + } + } + + draw_param.shader = args.shader; + if (draw_param.shader == SHADER_FT_FFP) { + draw_param.shader = SHADER_FT_SPRITE; + draw_param.tex_0_type = 0; + draw_param.tex_1_type = 0; + + if (tex_param_count == 1 || tex_param_count == 2) { + if (tex_param[0].texture->internal_format == GL_COMPRESSED_RED_RGTC1_EXT) + draw_param.tex_0_type = 3; + else if (tex_param[0].texture->internal_format == GL_COMPRESSED_RED_GREEN_RGTC2_EXT) + draw_param.tex_0_type = 2; + else + draw_param.tex_0_type = 1; + + if (tex_param_count == 2) { + if (tex_param[1].texture->internal_format == GL_COMPRESSED_RED_RGTC1_EXT) + draw_param.tex_1_type = 3; + else if (tex_param[1].texture->internal_format == GL_COMPRESSED_RED_GREEN_RGTC2_EXT) + draw_param.tex_1_type = 2; + else + draw_param.tex_1_type = 1; + } + } + + if (args.attr & SPR_ATTR_NOBLEND) + draw_param.combiner = 0; + else if (args.blend != 5) + draw_param.combiner = args.blend == 3 ? 1 : 0; + else + draw_param.combiner = 2; + + } + + switch (tex_param_count) { + case 0: + switch (args.kind) { + case SPR_KIND_LINES: { + if (vtx[0] == 0.0f && vtx[2] == 0.0f) { + draw_param_buffer.pop_back(); + return; + } + + sprite_draw_vertex spr_vtx[4] = {}; + spr_vtx[0].pos = vtx[0]; + spr_vtx[0].color = color; + + spr_vtx[1].pos = vtx[2]; + spr_vtx[1].color = color; + + draw_param.mode = GL_LINES; + draw_param.first = (GLint)vertex_buffer.size(); + draw_param.count = 2; + + vertex_buffer.reserve(2); + vertex_buffer.push_back(spr_vtx[0]); + vertex_buffer.push_back(spr_vtx[1]); + } break; + case SPR_KIND_RECT: { + if (vtx[0] == 0.0f && vtx[1] == 0.0f && vtx[2] == 0.0f && vtx[3] == 0.0f) { + draw_param_buffer.pop_back(); + return; + } + + sprite_draw_vertex spr_vtx[4] = {}; + spr_vtx[0].pos = vtx[0]; + spr_vtx[0].color = color; + + spr_vtx[1].pos = vtx[1]; + spr_vtx[1].color = color; + + spr_vtx[2].pos = vtx[2]; + spr_vtx[2].color = color; + + spr_vtx[3].pos = vtx[3]; + spr_vtx[3].color = color; + + draw_param.mode = GL_TRIANGLES; + draw_param.first = (GLint)vertex_buffer.size(); + draw_param.count = 6; + + vertex_buffer.reserve(6); + vertex_buffer.push_back(spr_vtx[1]); // LT + vertex_buffer.push_back(spr_vtx[0]); // LB + vertex_buffer.push_back(spr_vtx[2]); // RT + vertex_buffer.push_back(spr_vtx[3]); // RB + vertex_buffer.push_back(spr_vtx[2]); // RT + vertex_buffer.push_back(spr_vtx[0]); // LB + } break; + case SPR_KIND_MULTI: { + if (vtx[0] == 0.0f && vtx[1] == 0.0f && vtx[2] == 0.0f && vtx[3] == 0.0f) { + draw_param_buffer.pop_back(); + return; + } + + sprite_draw_vertex spr_vtx[4] = {}; + spr_vtx[0].pos = vtx[0]; + spr_vtx[0].color = color; + + spr_vtx[1].pos = vtx[1]; + spr_vtx[1].color = color; + + spr_vtx[2].pos = vtx[2]; + spr_vtx[2].color = color; + + spr_vtx[3].pos = vtx[3]; + spr_vtx[3].color = color; + + draw_param.mode = GL_LINE_LOOP; + draw_param.first = (GLint)vertex_buffer.size(); + draw_param.count = 4; + + vertex_buffer.reserve(4); + vertex_buffer.push_back(spr_vtx[0]); + vertex_buffer.push_back(spr_vtx[1]); + vertex_buffer.push_back(spr_vtx[2]); + vertex_buffer.push_back(spr_vtx[3]); + } break; + case SPR_KIND_ARROW_B: { + sprite_draw_vertex spr_vtx[2] = {}; + spr_vtx[0].color = color; + spr_vtx[1].color = color; + + if (args.num_vertex) { + size_t vertex_buffer_size = vertex_buffer.size(); + vertex_buffer.reserve(args.num_vertex / 2 * 2); + SpriteVertex* vtx = args.vertex_array; + for (size_t i = args.num_vertex / 2; i; i--, vtx += 2) { + if (vtx[0].pos == 0.0f && vtx[1].pos == 0.0f) + continue; + + spr_vtx[0].pos = vtx[0].pos; + spr_vtx[1].pos = vtx[1].pos; + vertex_buffer.push_back(spr_vtx[0]); + vertex_buffer.push_back(spr_vtx[1]); + } + + if (vertex_buffer_size == vertex_buffer.size()) { + draw_param_buffer.pop_back(); + return; + } + } + else { + if (vtx[0] == 0.0f && vtx[2] == 0.0f) { + draw_param_buffer.pop_back(); + return; + } + + spr_vtx[0].pos = vtx[0]; + spr_vtx[1].pos = vtx[2]; + + vertex_buffer.reserve(2); + vertex_buffer.push_back(spr_vtx[0]); + vertex_buffer.push_back(spr_vtx[1]); + } + } break; + case SPR_KIND_ARROW_AB: { + draw_param.mode = GL_LINE_STRIP; + draw_param.first = (GLint)vertex_buffer.size(); + draw_param.count = (GLsizei)args.num_vertex; + + vertex_buffer.reserve(args.num_vertex); + + sprite_draw_vertex spr_vtx = {}; + spr_vtx.color = color; + + SpriteVertex* vtx = args.vertex_array; + for (size_t i = args.num_vertex; i; i--, vtx++) { + spr_vtx.pos = vtx->pos; + vertex_buffer.push_back(spr_vtx); + } + } break; + case SPR_KIND_TRIANGLE: { + draw_param.mode = GL_TRIANGLE_STRIP; + draw_param.first = (GLint)vertex_buffer.size(); + draw_param.count = (GLsizei)args.num_vertex; + + vertex_buffer.reserve(args.num_vertex); + + sprite_draw_vertex spr_vtx = {}; + spr_vtx.color = color; + + SpriteVertex* vtx = args.vertex_array; + for (size_t i = args.num_vertex; i; i--, vtx++) { + spr_vtx.pos = vtx->pos; + vertex_buffer.push_back(spr_vtx); + } + } break; + } + break; + case 1: + draw_param.texture[0] = tex_param[0].texture->tex; + draw_param.sampler = rctx->render_manager.sprite_samplers[0]; + + if (args.num_vertex) { + if (args.kind == SPR_KIND_TRIANGLE) + draw_param.sampler = rctx->render_manager.sprite_samplers[1]; + + if (args.kind == SPR_KIND_TRIANGLE) { + draw_param.mode = GL_TRIANGLE_STRIP; + draw_param.first = (GLint)vertex_buffer.size(); + draw_param.count = (GLsizei)args.num_vertex; + + vertex_buffer.reserve(args.num_vertex); + + sprite_draw_vertex spr_vtx = {}; + SpriteVertex* vtx = args.vertex_array; + for (size_t i = args.num_vertex; i; i--, vtx++) { + spr_vtx.pos = vtx->pos; + spr_vtx.uv[0] = vtx->uv; + spr_vtx.color = vtx->color; + vertex_buffer.push_back(spr_vtx); + } + } + else { + size_t num_vertex = args.num_vertex / 4 * 6; + + draw_param.mode = GL_TRIANGLES; + draw_param.first = (GLint)vertex_buffer.size(); + draw_param.count = (GLsizei)num_vertex; + + size_t vertex_buffer_size = vertex_buffer.size(); + vertex_buffer.reserve(num_vertex); + + sprite_draw_vertex spr_vtx[4] = {}; + SpriteVertex* vtx = args.vertex_array; + for (size_t i = num_vertex / 6; i; i--, vtx += 4) { + if (vtx[0].pos == 0.0f && vtx[1].pos == 0.0f + && vtx[2].pos == 0.0f && vtx[3].pos == 0.0f) + continue; + + spr_vtx[0].pos = vtx[0].pos; + spr_vtx[0].uv[0] = vtx[0].uv; + spr_vtx[0].color = vtx[0].color; + spr_vtx[1].pos = vtx[1].pos; + spr_vtx[1].uv[0] = vtx[1].uv; + spr_vtx[1].color = vtx[1].color; + spr_vtx[2].pos = vtx[2].pos; + spr_vtx[2].uv[0] = vtx[2].uv; + spr_vtx[2].color = vtx[2].color; + spr_vtx[3].pos = vtx[3].pos; + spr_vtx[3].uv[0] = vtx[3].uv; + spr_vtx[3].color = vtx[3].color; + vertex_buffer.push_back(spr_vtx[1]); // LT + vertex_buffer.push_back(spr_vtx[0]); // LB + vertex_buffer.push_back(spr_vtx[2]); // RT + vertex_buffer.push_back(spr_vtx[3]); // RB + vertex_buffer.push_back(spr_vtx[2]); // RT + vertex_buffer.push_back(spr_vtx[0]); // LB + } + + if (vertex_buffer_size == vertex_buffer.size()) { + draw_param_buffer.pop_back(); + return; + } + } + } + else { + if (vtx[0] == 0.0f && vtx[1] == 0.0f && vtx[2] == 0.0f && vtx[3] == 0.0f) { + draw_param_buffer.pop_back(); + return; + } + + sprite_draw_vertex spr_vtx[4] = {}; + spr_vtx[0].pos = vtx[0]; + spr_vtx[0].uv[0].x = tex_param[0].texcoord.uv[0].u; + spr_vtx[0].uv[0].y = tex_param[0].texcoord.uv[0].v; + spr_vtx[0].color = color; + + spr_vtx[1].pos = vtx[1]; + spr_vtx[1].uv[0].x = tex_param[0].texcoord.uv[1].u; + spr_vtx[1].uv[0].y = tex_param[0].texcoord.uv[1].v; + spr_vtx[1].color = color; + + spr_vtx[2].pos = vtx[2]; + spr_vtx[2].uv[0].x = tex_param[0].texcoord.uv[2].u; + spr_vtx[2].uv[0].y = tex_param[0].texcoord.uv[2].v; + spr_vtx[2].color = color; + + spr_vtx[3].pos = vtx[3]; + spr_vtx[3].uv[0].x = tex_param[0].texcoord.uv[3].u; + spr_vtx[3].uv[0].y = tex_param[0].texcoord.uv[3].v; + spr_vtx[3].color = color; + + draw_param.mode = GL_TRIANGLES; + draw_param.first = (GLint)vertex_buffer.size(); + draw_param.count = 6; + + vertex_buffer.reserve(6); + vertex_buffer.push_back(spr_vtx[1]); // LT + vertex_buffer.push_back(spr_vtx[0]); // LB + vertex_buffer.push_back(spr_vtx[2]); // RT + vertex_buffer.push_back(spr_vtx[3]); // RB + vertex_buffer.push_back(spr_vtx[2]); // RT + vertex_buffer.push_back(spr_vtx[0]); // LB + } + break; + case 2: { + if (vtx[0] == 0.0f && vtx[1] == 0.0f && vtx[2] == 0.0f && vtx[3] == 0.0f) { + draw_param_buffer.pop_back(); + return; + } + + draw_param.texture[0] = tex_param[0].texture->tex; + draw_param.texture[1] = tex_param[1].texture->tex; + draw_param.sampler = rctx->render_manager.sprite_samplers[2]; + + sprite_draw_vertex spr_vtx[4] = {}; + spr_vtx[0].pos = vtx[0]; + spr_vtx[0].uv[0].x = tex_param[0].texcoord.uv[0].u; + spr_vtx[0].uv[0].y = tex_param[0].texcoord.uv[0].v; + spr_vtx[0].uv[1].x = tex_param[1].texcoord.uv[0].u; + spr_vtx[0].uv[1].y = tex_param[1].texcoord.uv[0].v; + spr_vtx[0].color = color; + + spr_vtx[1].pos = vtx[1]; + spr_vtx[1].uv[0].x = tex_param[0].texcoord.uv[1].u; + spr_vtx[1].uv[0].y = tex_param[0].texcoord.uv[1].v; + spr_vtx[1].uv[1].x = tex_param[1].texcoord.uv[1].u; + spr_vtx[1].uv[1].y = tex_param[1].texcoord.uv[1].v; + spr_vtx[1].color = color; + + spr_vtx[2].pos = vtx[2]; + spr_vtx[2].uv[0].x = tex_param[0].texcoord.uv[2].u; + spr_vtx[2].uv[0].y = tex_param[0].texcoord.uv[2].v; + spr_vtx[2].uv[1].x = tex_param[1].texcoord.uv[2].u; + spr_vtx[2].uv[1].y = tex_param[1].texcoord.uv[2].v; + spr_vtx[2].color = color; + + spr_vtx[3].pos = vtx[3]; + spr_vtx[3].uv[0].x = tex_param[0].texcoord.uv[3].u; + spr_vtx[3].uv[0].y = tex_param[0].texcoord.uv[3].v; + spr_vtx[3].uv[1].x = tex_param[1].texcoord.uv[3].u; + spr_vtx[3].uv[1].y = tex_param[1].texcoord.uv[3].v; + spr_vtx[3].color = color; + + draw_param.mode = GL_TRIANGLES; + draw_param.first = (GLint)vertex_buffer.size(); + draw_param.count = 6; + + vertex_buffer.reserve(6); + vertex_buffer.push_back(spr_vtx[1]); // LT + vertex_buffer.push_back(spr_vtx[0]); // LB + vertex_buffer.push_back(spr_vtx[2]); // RT + vertex_buffer.push_back(spr_vtx[3]); // RB + vertex_buffer.push_back(spr_vtx[2]); // RT + vertex_buffer.push_back(spr_vtx[0]); // LB + } break; + } + + if (draw_param_buffer.size() >= 2) { + sprite_draw_param& draw_param_2 = draw_param_buffer.data()[draw_param_buffer.size() - 2]; + sprite_draw_param& draw_param_1 = draw_param_buffer.data()[draw_param_buffer.size() - 1]; + + if ((args.index == 0 || args.index == 3) + && (draw_param_2.mode == GL_LINES || draw_param_2.mode == GL_TRIANGLES) + && draw_param_2.blend == draw_param_1.blend + && draw_param_2.blend_src_rgb == draw_param_1.blend_src_rgb + && draw_param_2.blend_src_alpha == draw_param_1.blend_src_alpha + && draw_param_2.blend_dst_rgb == draw_param_1.blend_dst_rgb + && draw_param_2.blend_dst_alpha == draw_param_1.blend_dst_alpha + && !draw_param_2.copy_texture && !draw_param_1.copy_texture + && draw_param_2.shader == draw_param_1.shader + && draw_param_2.tex_0_type == draw_param_1.tex_0_type + && draw_param_2.tex_1_type == draw_param_1.tex_1_type + && draw_param_2.combiner == draw_param_1.combiner + && draw_param_2.texture[0] == draw_param_1.texture[0] + && draw_param_2.texture[1] == draw_param_1.texture[1] + && draw_param_2.sampler == draw_param_1.sampler + && (draw_param_2.first + draw_param_2.count) == draw_param_1.first) { + draw_param_2.count += draw_param_1.count; + draw_param_buffer.pop_back(); + } + } } - void SpriteManager::Clear() { - for (int32_t i = 0; i < 4; i++) - for (int32_t j = 0; j < 64; j++) - reqlist[i][j].clear(); - - for (auto i : sets) - i.second.Unload(); - sets.clear(); + static void draw_sprite_begin() { + gl_state_disable_blend(); + gl_state_active_bind_texture_2d(0, 0); + gl_state_set_blend_func_separate(GL_ONE, GL_ZERO, GL_ONE, GL_ZERO); } - void SpriteManager::ResetIndex() { - index = 0; + static void draw_sprite_end() { + gl_state_active_bind_texture_2d(0, 0); + gl_state_set_blend_func_separate(GL_ONE, GL_ZERO, GL_ONE, GL_ZERO); + shader::unbind(); } - void SpriteManager::ResetResData() { - ResetIndex(); - resolution_mode = RESOLUTION_MODE_MAX; + static void draw_sprite_scale(spr::SprArgs* args) { + int32_t index = args->index; + resolution_mode mode = res_window_get()->resolution_mode; + while (args) { + resolution_mode_scale_data data(args->resolution_mode_screen, mode); + if (args->resolution_mode_screen != RESOLUTION_MODE_MAX + && args->resolution_mode_screen != mode && (index == 0 || index == 3)) { + float_t scale_x = data.scale.x; + float_t scale_y = data.scale.y; + float_t src_res_x = data.src_res.x; + float_t src_res_y = data.src_res.y; + float_t dst_res_x = data.dst_res.x; + float_t dst_res_y = data.dst_res.y; + args->trans.x = (args->trans.x - src_res_x) * scale_x + src_res_x; + args->trans.y = (args->trans.y - src_res_y) * scale_y + src_res_y; + args->trans.z = args->trans.z * scale_y; - resolution_struct* res = res_window_get(); + SpriteVertex* vtx = args->vertex_array; + for (size_t i = args->num_vertex; i; i--, vtx++) { + vtx->pos.x = (vtx->pos.x - src_res_x) * scale_x + dst_res_x; + vtx->pos.y = (vtx->pos.y - src_res_y) * scale_y + dst_res_y; + } + } - aspect[0] = (float_t)res->aspect; - field_1018.first = res->resolution_mode; - field_1018.second = { 0.0f, { (float_t)res->width, (float_t)res->height } }; - - aspect[1] = (float_t)res->aspect; - field_102C.first = res->resolution_mode; - field_102C.second = { 0.0f, { (float_t)res->width, (float_t)res->height } }; - - mat = mat4_identity; + if (args->resolution_mode_sprite != RESOLUTION_MODE_MAX) { + vec2 scale = resolution_mode_get_scale(mode, args->resolution_mode_sprite); + args->scale.x = scale.x * args->scale.x; + args->scale.y = scale.y * args->scale.y; + } + args = args->next; + } } } -SprSet::SprSet(int32_t index) : flag(), header_file(), header(), textures(), load_count(), ready() { +SprSet::SprSet(uint32_t index) : flag(), header_file(), +header(), textures(), load_count(), ready() { this->index = index; } @@ -269,6 +1720,132 @@ SprSet::~SprSet() { } +const char* SprSet::GetName(spr_info info) { + if ((info.set_index & 0xF000) == 0x1000) + return header->texname[info.index]; + else + return header->sprname[info.index]; +} + +rectangle SprSet::GetRectangle(spr_info info) { + if ((info.set_index & 0xF000) == 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]; + 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) + return RESOLUTION_MODE_HD; + else + return header->sprdata[info.index].resolution_mode; +} + +texture* SprSet::GetTexture(spr_info info) { + if ((info.set_index & 0xF000) == 0x1000) + return textures[info.index]; + else + return textures[header->sprinfo[info.index].texid]; +} + +bool SprSet::LoadData() { + const void* data = file_handler.get_data(); + if (!data) { + header_file = 0; + header = 0; + 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); + + 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); + + const char** texname = alloc->allocate(header->num_of_texture); + header->texname = texname; + + 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; + return true; +} + +bool SprSet::LoadFile() { + if (ready) + return false; + else if (file_handler.check_not_ready()) + return true; + else if (!LoadData() || !LoadTexture()) + 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); + 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()); + return !!textures; +} + +void SprSet::ReadFile(const char* file, std::string& mdata_dir, void* data) { + if (load_count > 1) { + load_count++; + return; + } + + load_count = 1; + this->file.assign(file); + + std::string farc_file(file); + size_t off = farc_file.rfind(".bin"); + if (off != -1 && off == farc_file.size() - 4) + farc_file.replace(off, 4, ".farc"); + + const char* dir = "./rom/2d/"; + if (mdata_dir.size() && ((data_struct*)data)->check_directory_exists(mdata_dir.c_str())) + dir = mdata_dir.c_str(); + + if (((data_struct*)data)->check_file_exists(dir, farc_file.c_str())) + file_handler.read_file(data, dir, farc_file.c_str(), file, false); + ready = false; +} + void SprSet::Unload() { if (load_count > 1) { load_count--; @@ -279,8 +1856,8 @@ void SprSet::Unload() { UnloadTexture(); alloc_handler.reset(); - free_def(header_file); - this->header = 0; + header_file = 0; + header = 0; file.clear(); ready = false; load_count = 0; diff --git a/src/CRE/sprite.hpp b/src/CRE/sprite.hpp index 2434a475..c1ae17fb 100644 --- a/src/CRE/sprite.hpp +++ b/src/CRE/sprite.hpp @@ -8,26 +8,34 @@ #include #include #include "../KKdLib/default.hpp" +#include "../KKdLib/database/sprite.hpp" #include "../KKdLib/mat.hpp" #include "../KKdLib/vec.hpp" +#include "render_context.hpp" #include "resolution_mode.hpp" #include "texture.hpp" #include "gl_state.hpp" +struct rectangle { + vec2 pos; + vec2 size; + + inline rectangle() : pos(), size() { + + } + + inline rectangle(vec2 pos, vec2 size) { + this->pos = pos; + this->size = size; + } + + inline rectangle(float_t pos_x, float_t pos_y, float_t size_x, float_t size_y) { + this->pos = { pos_x, pos_y }; + this->size = { size_x, size_y }; + } +}; + namespace spr { - enum SprKind { - SPR_KIND_NORMAL = 0, - SPR_KIND_LINE, - SPR_KIND_LINES, - SPR_KIND_RECT, - SPR_KIND_MULTI, - SPR_KIND_ARROW_A, - SPR_KIND_ARROW_B, - SPR_KIND_ARROW_AB, - SPR_KIND_TRIANGLE, - SPR_KIND_CIRCLE, - }; - enum SprAttr : uint32_t { /*M_SPR_ATTR_SCALESIZE_X = 0x800, M_SPR_ATTR_SCALESIZE_Y = 0x1000, @@ -48,21 +56,95 @@ namespace spr { M_SPR_ATTR_SCALESIZE = 0x1800, M_SPR_ATTR_NOTCORRECT = 0x18000,*/ - SPR_ATTR_FLIP_H = 0x00010000, - SPR_ATTR_FLIP_V = 0x00020000, - SPR_ATTR_CTR_LT = 0x00040000, - SPR_ATTR_CTR_CT = 0x00080000, - SPR_ATTR_CTR_RT = 0x00100000, - SPR_ATTR_CTR_LC = 0x00200000, - SPR_ATTR_CTR_CC = 0x00400000, - SPR_ATTR_CTR_RC = 0x00800000, - SPR_ATTR_CTR_LB = 0x01000000, - SPR_ATTR_CTR_CB = 0x02000000, - SPR_ATTR_CTR_RB = 0x04000000, - SPR_ATTR_MATRIX = 0x08000000, - SPR_ATTR_NOBLEND = 0x20000000, + SPR_ATTR_FLIP_H = 0x00010000, + SPR_ATTR_FLIP_V = 0x00020000, + SPR_ATTR_CTR_LT = 0x00040000, + SPR_ATTR_CTR_CT = 0x00080000, + SPR_ATTR_CTR_RT = 0x00100000, + SPR_ATTR_CTR_LC = 0x00200000, + SPR_ATTR_CTR_CC = 0x00400000, + SPR_ATTR_CTR_RC = 0x00800000, + SPR_ATTR_CTR_LB = 0x01000000, + SPR_ATTR_CTR_CB = 0x02000000, + SPR_ATTR_CTR_RB = 0x04000000, + SPR_ATTR_MATRIX = 0x08000000, + SPR_ATTR_10000000 = 0x10000000, + SPR_ATTR_NOBLEND = 0x20000000, - SPR_ATTR_CTR = 0x07FC0000, + SPR_ATTR_CTR = 0x07FC0000, + }; + + enum SprKind { + SPR_KIND_NORMAL = 0, + SPR_KIND_LINE, + SPR_KIND_LINES, + SPR_KIND_RECT, + SPR_KIND_MULTI, + SPR_KIND_ARROW_A, + SPR_KIND_ARROW_B, + SPR_KIND_ARROW_AB, + SPR_KIND_TRIANGLE, + SPR_KIND_CIRCLE, + }; + + enum SprPrio { + /*SPR_PRIO_INFORMATION = SPR_PRIO_11, + SPR_PRIO_FRONTSIDE = SPR_PRIO_20, + SPR_PRIO_FOREGROUND = SPR_PRIO_24, + SPR_PRIO_SCREENSAVER = SPR_PRIO_30, + SPR_PRIO_VISTAFRAME = SPR_PRIO_23, + SPR_PRIO_PHASE_BACKGROUND_STA = SPR_PRIO_00, + SPR_PRIO_PHASE_BACKGROUND_END = SPR_PRIO_04, + SPR_PRIO_PHASE_DEFAULT_STA = SPR_PRIO_05, + SPR_PRIO_PHASE_DEFAULT_END = SPR_PRIO_20, + SPR_PRIO_PHASE_FOREGROUND_STA = SPR_PRIO_21, + SPR_PRIO_PHASE_FOREGROUND_END = SPR_PRIO_26, + SPR_PRIO_PHASE_DEBUG_STA = SPR_PRIO_27, + SPR_PRIO_PHASE_DEBUG_END = SPR_PRIO_31,*/ + + SPR_PRIO_00 = 0, + SPR_PRIO_01, + SPR_PRIO_02, + SPR_PRIO_03, + SPR_PRIO_04, + SPR_PRIO_05, + SPR_PRIO_06, + SPR_PRIO_07, + SPR_PRIO_08, + SPR_PRIO_09, + SPR_PRIO_10, + SPR_PRIO_11, + SPR_PRIO_12, + SPR_PRIO_13, + SPR_PRIO_14, + SPR_PRIO_15, + SPR_PRIO_16, + SPR_PRIO_17, + SPR_PRIO_18, + SPR_PRIO_19, + SPR_PRIO_20, + SPR_PRIO_21, + SPR_PRIO_22, + SPR_PRIO_23, + SPR_PRIO_24, + SPR_PRIO_25, + SPR_PRIO_26, + SPR_PRIO_27, + SPR_PRIO_28, + SPR_PRIO_29, + SPR_PRIO_30, + SPR_PRIO_31, + SPR_PRIO_MAX, + + SPR_PRIO_BACKGROUND = SPR_PRIO_03, + SPR_PRIO_DEFAULT = SPR_PRIO_07, + SPR_PRIO_DEBUG = SPR_PRIO_29, + }; + + struct SpriteVertex { + vec3 pos; + vec2 uv; + vec4u8 color; }; struct SprArgs { @@ -71,17 +153,27 @@ namespace spr { TEXTURE_POS_SIZE = 0x02, }; - spr::SprKind kind; - union { + union IDUnion { int32_t index; - //spr_info info; - } id; - vec4 color; + uint32_t id; + spr_info info; + + IDUnion() { + index = -1; + id = -1; + info = {}; + } + }; + + SprKind kind; + IDUnion id; + bool modern; + vec4u8 color; SprAttr attr; int32_t blend; int32_t index; int32_t layer; - int32_t prio; + SprPrio prio; resolution_mode resolution_mode_screen; resolution_mode resolution_mode_sprite; vec3 center; @@ -92,8 +184,7 @@ namespace spr { mat4 mat; texture* texture; int32_t shader; - int32_t field_AC; - //sprite_vertex* vertex_array; + SpriteVertex* vertex_array; size_t num_vertex; Flags flags; vec2 sprite_size; @@ -101,6 +192,15 @@ namespace spr { vec2 texture_pos; vec2 texture_size; spr::SprArgs* next; + + SprArgs(); + + void Reset(); + void SetSpriteSize(vec2 size); + void SetTexturePosSize(float_t x, float_t y, float_t width, float_t height); + void SetVertexArray(SpriteVertex* vertex_array, size_t num_vertex); + + static void SetNext(SprArgs* args, SprArgs* next); }; struct SprInfo { @@ -116,12 +216,6 @@ namespace spr { float_t height; }; - struct SpriteVertex { - vec3 pos; - vec2 uv; - vec4u8 color; - }; - struct TexCoord { struct UV { float_t u; @@ -149,10 +243,41 @@ namespace spr { } }; - void calc_sprite_vertex(spr::SprArgs* args, vec3* vtx, mat4* mat, bool font); + vec2 proj_sprite_3d_line(vec3 vec, bool offset); + + void put_cross(const mat4& mat, vec4u8 color_x, vec4u8 color_y, vec4u8 color_z); + void put_rgb_cross(const mat4& mat); + spr::SprArgs* put_sprite(const spr::SprArgs& args, const sprite_database* spr_db); + void put_sprite_3d_line(vec3 p1, vec3 p2, vec4u8 color); + 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, + SprPrio prio, int32_t spr_id, int32_t layer, const sprite_database* spr_db); } extern void sprite_manager_init(); -extern void sprite_manager_load_set(int32_t set_id, std::string* mdata_dir); +extern void sprite_manager_add_spr_sets(const sprite_database* spr_db, bool modern); +extern void sprite_manager_clear(); +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 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); +extern const char* sprite_manager_get_spr_name(uint32_t spr_id, const sprite_database* spr_db); +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 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_remove_spr_sets(const sprite_database* spr_db, bool modern); +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_free(); diff --git a/src/KKdLib/database/aet.cpp b/src/KKdLib/database/aet.cpp index 0ea03f9f..82590816 100644 --- a/src/KKdLib/database/aet.cpp +++ b/src/KKdLib/database/aet.cpp @@ -4,3 +4,756 @@ */ #include "aet.hpp" +#include "../f2/struct.hpp" +#include "../io/file_stream.hpp" +#include "../io/memory_stream.hpp" +#include "../io/path.hpp" +#include "../hash.hpp" +#include "../sort.hpp" +#include "../str_utils.hpp" + +static void aet_database_file_classic_read_inner(aet_database_file* aet_db, stream& s); +static void aet_database_file_classic_write_inner(aet_database_file* aet_db, stream& s); +static void aet_database_file_modern_read_inner(aet_database_file* aet_db, stream& s, uint32_t header_length); +static void aet_database_file_modern_write_inner(aet_database_file* aet_db, stream& s); +static int64_t aet_database_file_strings_get_string_offset(std::vector& vec, + std::vector& vec_off, std::string& str); +static bool aet_database_file_strings_push_back_check(std::vector& vec, std::string& str); + +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() { + +} + +aet_db_aet::aet_db_aet() : id() { + name_hash = hash_murmurhash_empty; +} + +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() { + +} + +aet_db_aet_set::aet_db_aet_set() : id(), index(), sprite_set_id() { + name_hash = hash_murmurhash_empty; + file_name_hash = hash_murmurhash_empty; +} + +aet_db_aet_set::~aet_db_aet_set() { + +} + +aet_database_file::aet_database_file() : ready(), modern(), big_endian(), is_x() { + +} + +aet_database_file::~aet_database_file() { + +} + +void aet_database_file::read(const char* path, bool modern) { + if (!path) + return; + + if (!modern) { + char* path_bin = str_utils_add(path, ".bin"); + if (path_check_file_exists(path_bin)) { + file_stream s; + s.open(path_bin, "rb"); + if (s.check_not_null()) { + uint8_t* data = force_malloc_s(uint8_t, s.length); + s.read(data, s.length); + memory_stream s_bin; + s_bin.open(data, s.length); + aet_database_file_classic_read_inner(this, s_bin); + free_def(data); + } + } + free_def(path_bin); + } + else { + char* path_spi = str_utils_add(path, ".aei"); + if (path_check_file_exists(path_spi)) { + f2_struct st; + st.read(path_spi); + 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); + } + } + free_def(path_spi); + } +} + +void aet_database_file::read(const wchar_t* path, bool modern) { + if (!path) + return; + + if (!modern) { + wchar_t* path_bin = str_utils_add(path, L".bin"); + if (path_check_file_exists(path_bin)) { + file_stream s; + s.open(path_bin, L"rb"); + if (s.check_not_null()) { + uint8_t* data = force_malloc_s(uint8_t, s.length); + s.read(data, s.length); + memory_stream s_bin; + s_bin.open(data, s.length); + aet_database_file_classic_read_inner(this, s_bin); + free_def(data); + } + } + free_def(path_bin); + } + else { + wchar_t* path_spi = str_utils_add(path, L".aei"); + if (path_check_file_exists(path_spi)) { + f2_struct st; + st.read(path_spi); + 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); + } + } + free_def(path_spi); + } +} + +void aet_database_file::read(const void* data, size_t size, bool modern) { + if (!data || !size) + return; + + if (!modern) { + memory_stream s; + s.open(data, size); + aet_database_file_classic_read_inner(this, s); + } + 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); + } + } +} + +void aet_database_file::write(const char* path) { + if (!path || !ready) + return; + + if (!modern) { + char* path_bin = str_utils_add(path, ".bin"); + file_stream s; + s.open(path_bin, "wb"); + if (s.check_not_null()) + aet_database_file_classic_write_inner(this, s); + free_def(path_bin); + } + else { + char* path_spi = str_utils_add(path, ".spi"); + file_stream s; + s.open(path_spi, "wb"); + if (s.check_not_null()) + aet_database_file_modern_write_inner(this, s); + free_def(path_spi); + } +} + +void aet_database_file::write(const wchar_t* path) { + if (!path || !ready) + return; + + if (!modern) { + wchar_t* path_bin = str_utils_add(path, L".bin"); + file_stream s; + s.open(path_bin, L"wb"); + if (s.check_not_null()) + aet_database_file_classic_write_inner(this, s); + free_def(path_bin); + } + else { + wchar_t* path_spi = str_utils_add(path, L".spi"); + file_stream s; + s.open(path_spi, L"wb"); + if (s.check_not_null()) + aet_database_file_modern_write_inner(this, s); + free_def(path_spi); + } +} + +void aet_database_file::write(void** data, size_t* size) { + if (!data || !size || !ready) + return; + + memory_stream s; + s.open(); + if (!modern) + aet_database_file_classic_write_inner(this, s); + else + aet_database_file_modern_write_inner(this, s); + s.align_write(0x10); + s.copy(data, size); +} + +bool aet_database_file::load_file(void* data, const char* path, const char* file, uint32_t hash) { + size_t file_len = utf8_length(file); + + const char* t = strrchr(file, '.'); + if (t) + file_len = t - file; + + std::string s; + s.assign(path); + s.append(file, file_len); + + aet_database_file* aet_db = (aet_database_file*)data; + aet_db->read(s.c_str(), aet_db->modern); + + return aet_db->ready; +} + +aet_database::aet_database() { + +} + +aet_database::~aet_database() { + +} + +void aet_database::add(aet_database_file* aet_db_file) { + if (!aet_db_file || !aet_db_file->ready) + return; + + size_t aet_sets_count = this->aet_set_ids.size(); + + aet_set_ids.reserve(aet_db_file->aet_set.size()); + aet_set_indices.reserve(aet_db_file->aet_set.size()); + 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_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.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_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; + 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_ids.push_back({ aet.id, aet }); + aet_names.push_back({ aet.name, aet }); + aet_indices.push_back({ aet.info, aet }); + } + } + + aet_set_ids.combine(); + aet_set_indices.combine(); + aet_set_names.combine(); + aet_ids.combine(); + aet_names.combine(); + aet_indices.combine(); +} + +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 &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 &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 &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 &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 &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 }); + 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 &aet_db_aet_null; +} + +const char* aet_database::get_aet_set_file_name(uint32_t set_id) const { + return get_aet_set_by_id(set_id)->file_name.c_str(); +} + +uint32_t aet_database::get_aet_set_id_by_name(const char* name) const { + return get_aet_set_by_name(name)->id; +} + +uint32_t aet_database::get_aet_set_id_by_name_index(uint32_t index) const { + return aet_set_names[index].second.id; +} + +const char* aet_database::get_aet_set_name(uint32_t set_id) const { + return get_aet_set_by_id(set_id)->name.c_str(); +} + +static void aet_database_file_classic_read_inner(aet_database_file* aet_db, stream& s) { + uint32_t aet_sets_count = s.read_uint32_t(); + uint32_t aet_sets_offset = s.read_uint32_t(); + uint32_t aets_count = s.read_uint32_t(); + uint32_t aets_offset = s.read_uint32_t(); + + aet_db->aet_set.resize(aet_sets_count); + + aet_db_aet_set_file* aet_db_aet_set = aet_db->aet_set.data(); + + s.position_push(aet_sets_offset, SEEK_SET); + for (uint32_t i = 0; i < aet_sets_count; i++) { + aet_db_aet_set_file& aet_set = aet_db_aet_set[i]; + 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.sprite_set_id = s.read_uint32_t(); + } + s.position_pop(); + + s.position_push(aets_offset, SEEK_SET); + for (uint32_t i = 0; i < aets_count; i++) { + uint32_t id = s.read_uint32_t(); + uint32_t name_offset = s.read_uint32_t(); + uint32_t info = s.read_uint32_t(); + + uint16_t index = (uint16_t)(info & 0xFFFF); + uint16_t set_index = (uint16_t)(info >> 16); + + aet_db_aet_set_file& aet_set = aet_db_aet_set[set_index]; + + aet_set.aet.push_back({}); + aet_db_aet_file& aet = aet_set.aet.back(); + aet.id = id; + aet.name.assign(s.read_string_null_terminated_offset(name_offset)); + aet.index = index; + } + s.position_pop(); + + aet_db->ready = true; + aet_db->modern = false; + aet_db->big_endian = false; + aet_db->is_x = false; +} + +static void aet_database_file_classic_write_inner(aet_database_file* aet_db, stream& s) { + s.write_uint32_t(0x90669066); + s.write_uint32_t(0x90669066); + s.write_uint32_t(0x90669066); + s.write_uint32_t(0x90669066); + s.write_uint32_t(0x90669066); + s.write_uint32_t(0x90669066); + s.write_uint32_t(0x90669066); + s.write_uint32_t(0x90669066); + s.align_write(0x20); + + size_t aet_sets_count = aet_db->aet_set.size(); + + size_t aets_count = 0; + for (aet_db_aet_set_file& i : aet_db->aet_set) + aets_count += i.aet.size(); + + int64_t aets_offset = s.get_position(); + s.write(0x0C * aets_count); + s.align_write(0x20); + + int64_t aet_sets_offset = s.get_position(); + s.write(0x10 * aet_db->aet_set.size()); + s.align_write(0x20); + + std::vector strings; + std::vector string_offsets; + + strings.reserve(aet_sets_count + aets_count); + + 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.get_position()); + s.write_string_null_terminated(j.name); + } + s.align_write(0x04); + + 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.get_position()); + s.write_string_null_terminated(i.name); + } + + if (aet_database_file_strings_push_back_check(strings, i.file_name)) { + string_offsets.push_back(s.get_position()); + s.write_string_null_terminated(i.file_name); + } + } + s.align_write(0x04); + + 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; + + for (aet_db_aet_file& j : i.aet) { + s.write_uint32_t(j.id); + s.write_uint32_t((uint32_t)aet_database_file_strings_get_string_offset(strings, + string_offsets, j.name)); + s.write_uint32_t((aet_set_index << 16) | j.index); + } + } + s.position_pop(); + + s.position_push(aet_sets_offset, SEEK_SET); + for (aet_db_aet_set_file& i : aet_db->aet_set) { + s.write_uint32_t(i.id); + s.write_uint32_t((uint32_t)aet_database_file_strings_get_string_offset(strings, + string_offsets, i.name)); + s.write_uint32_t((uint32_t)aet_database_file_strings_get_string_offset(strings, + string_offsets, i.file_name)); + s.write_uint32_t(i.index); + s.write_uint32_t(i.sprite_set_id); + } + s.position_pop(); + + s.position_push(0x00, SEEK_SET); + s.write_uint32_t((uint32_t)aet_sets_count); + s.write_uint32_t((uint32_t)aet_sets_offset); + s.write_uint32_t((uint32_t)aets_count); + s.write_uint32_t((uint32_t)aets_offset); + s.position_pop(); +} + +static void aet_database_file_modern_read_inner(aet_database_file* aet_db, stream& s, uint32_t header_length) { + bool big_endian = s.big_endian; + bool is_x = true; + + s.set_position(0x04, SEEK_SET); + is_x &= s.read_uint32_t_reverse_endianness() == 0; + + s.set_position(0x00, SEEK_SET); + + uint32_t aet_sets_count = s.read_uint32_t_reverse_endianness(); + int64_t aet_sets_offset = s.read_offset(header_length, is_x); + uint32_t aets_count = s.read_uint32_t_reverse_endianness(); + int64_t aets_offset = s.read_offset(header_length, is_x); + + aet_db->aet_set.resize(aet_sets_count); + + aet_db_aet_set_file* aet_db_aet_set = aet_db->aet_set.data(); + + s.position_push(aet_sets_offset, SEEK_SET); + if (!is_x) + for (uint32_t i = 0; i < aet_sets_count; i++) { + aet_db_aet_set_file& aet_set = aet_db_aet_set[i]; + 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.sprite_set_id = s.read_uint32_t_reverse_endianness(); + } + else + for (uint32_t i = 0; i < aet_sets_count; i++) { + aet_db_aet_set_file& aet_set = aet_db_aet_set[i]; + 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.sprite_set_id = s.read_uint32_t_reverse_endianness(); + s.align_read(0x08); + } + s.position_pop(); + + s.position_push(aets_offset, SEEK_SET); + if (!is_x) + for (uint32_t i = 0; i < aets_count; i++) { + uint32_t id = s.read_uint32_t_reverse_endianness(); + int64_t name_offset = s.read_offset_f2(header_length); + uint32_t info = s.read_uint32_t_reverse_endianness(); + + uint16_t index = (uint16_t)(info & 0xFFFF); + uint16_t set_index = (uint16_t)((info >> 16) & 0xFFFF); + + aet_db_aet_set_file& aet_set = aet_db_aet_set[set_index]; + + aet_set.aet.push_back({}); + aet_db_aet_file& aet = aet_set.aet.back(); + aet.id = id; + aet.name.assign(s.read_string_null_terminated_offset(name_offset)); + aet.index = index; + } + else + for (uint32_t i = 0; i < aets_count; i++) { + uint32_t id = s.read_uint32_t_reverse_endianness(); + int64_t name_offset = s.read_offset_x(); + uint32_t info = s.read_uint32_t_reverse_endianness(); + s.align_read(0x08); + + uint16_t index = (uint16_t)(info & 0xFFFF); + uint16_t set_index = (uint16_t)((info >> 16) & 0xFFFF); + + aet_db_aet_set_file& aet_set = aet_db_aet_set[set_index]; + + aet_set.aet.push_back({}); + aet_db_aet_file& aet = aet_set.aet.back(); + aet.id = id; + aet.name.assign(s.read_string_null_terminated_offset(name_offset)); + aet.index = index; + } + s.position_pop(); + + aet_db->ready = true; + aet_db->modern = true; + aet_db->big_endian = big_endian; + aet_db->is_x = is_x; +} + +static void aet_database_file_modern_write_inner(aet_database_file* aet_db, stream& s) { + 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; + + uint32_t off; + enrs e; + enrs_entry ee; + pof pof; + + size_t aet_sets_count = aet_db->aet_set.size(); + + size_t aets_count = 0; + for (aet_db_aet_set_file& i : aet_db->aet_set) + aets_count += i.aet.size(); + + if (!is_x) { + ee = { 0, 1, 16, 1 }; + ee.append(0, 4, ENRS_DWORD); + e.vec.push_back(ee); + off = 16; + off = align_val(off, 0x10); + + ee = { off, 1, 16, (uint32_t)aet_sets_count }; + ee.append(0, 4, ENRS_DWORD); + e.vec.push_back(ee); + off = (uint32_t)(aet_sets_count * 16ULL); + off = align_val(off, 0x10); + + ee = { off, 1, 12, (uint32_t)aets_count }; + ee.append(0, 3, ENRS_DWORD); + e.vec.push_back(ee); + off = (uint32_t)(aets_count * 12ULL); + off = align_val(off, 0x10); + } + else { + ee = { 0, 4, 32, 1 }; + ee.append(0, 1, ENRS_DWORD); + ee.append(4, 1, ENRS_QWORD); + ee.append(0, 1, ENRS_DWORD); + ee.append(4, 1, ENRS_QWORD); + e.vec.push_back(ee); + off = 32; + off = align_val(off, 0x10); + + ee = { off, 3, 32, (uint32_t)aet_sets_count }; + ee.append(0, 1, ENRS_DWORD); + ee.append(4, 2, ENRS_QWORD); + ee.append(0, 1, ENRS_DWORD); + e.vec.push_back(ee); + off = (uint32_t)(aet_sets_count * 32ULL); + off = align_val(off, 0x10); + + ee = { off, 3, 24, (uint32_t)aets_count }; + ee.append(0, 1, ENRS_DWORD); + ee.append(4, 1, ENRS_QWORD); + ee.append(0, 1, ENRS_DWORD); + e.vec.push_back(ee); + off = (uint32_t)(aets_count * 24ULL); + off = align_val(off, 0x10); + } + + s_spdb.write(is_x ? 0x20 : 0x10); + s_spdb.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 aets_offset = s_spdb.get_position(); + s_spdb.write(aets_count * (is_x ? 0x18ULL : 0x0CULL)); + s_spdb.align_write(0x10); + + std::vector strings; + std::vector string_offsets; + + strings.reserve(aet_sets_count + aets_count); + + 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); + } + + 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); + } + } + + 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); + } + s_spdb.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_spdb.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, + string_offsets, i.name), 0x20, &pof); + io_write_offset_f2_pof_add(s_spdb, 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); + } + 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, + string_offsets, i.name), &pof); + io_write_offset_x_pof_add(s_spdb, 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_spdb.position_pop(); + + s_spdb.position_push(aets_offset, SEEK_SET); + for (aet_db_aet_set_file& i : aet_db->aet_set) { + uint16_t aet_set_index = 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, + string_offsets, j.name), 0x20, &pof); + s_spdb.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, + string_offsets, j.name), &pof); + s_spdb.write_uint32_t_reverse_endianness((aet_set_index << 16) | j.index); + s_spdb.align_write(0x08); + } + } + s_spdb.position_pop(); + + f2_struct st; + s_spdb.align_write(0x10); + s_spdb.copy(st.data); + s_spdb.close(); + + st.enrs = e; + st.pof = pof; + + st.header.signature = reverse_endianness_uint32_t('SPDB'); + st.header.length = 0x20; + st.header.use_big_endian = big_endian; + st.header.use_section_size = true; + + st.write(s, true, aet_db->is_x); +} + +inline static int64_t aet_database_file_strings_get_string_offset(std::vector& vec, + std::vector& vec_off, std::string& str) { + uint64_t hash_fnv1a64m = hash_string_fnv1a64m(str); + uint64_t hash_murmurhash = hash_string_murmurhash(str); + for (string_hash& i : vec) + if (hash_fnv1a64m == i.hash_fnv1a64m && hash_murmurhash == i.hash_murmurhash) + return vec_off[&i - vec.data()]; + return 0; +} + +inline static bool aet_database_file_strings_push_back_check(std::vector& vec, std::string& str) { + uint64_t hash_fnv1a64m = hash_string_fnv1a64m(str); + uint64_t hash_murmurhash = hash_string_murmurhash(str); + for (string_hash& i : vec) + if (hash_fnv1a64m == i.hash_fnv1a64m && hash_murmurhash == i.hash_murmurhash) + return false; + + vec.push_back(str); + return true; +} diff --git a/src/KKdLib/database/aet.hpp b/src/KKdLib/database/aet.hpp index 3b25d82b..b0157863 100644 --- a/src/KKdLib/database/aet.hpp +++ b/src/KKdLib/database/aet.hpp @@ -5,4 +5,146 @@ #pragma once +#include +#include #include "../default.hpp" +#include "../prj/vector_pair_combine.hpp" +#include "../hash.hpp" + +struct aet_info { + uint16_t index; + uint16_t set_index; + + inline aet_info() { + this->index = (uint16_t)-1; + this->set_index = (uint16_t)-1; + } + + inline aet_info(uint16_t index, uint16_t set_index) { + this->index = index; + this->set_index = set_index; + } + + inline bool is_null() const { + return index == (uint16_t)-1 && set_index == (uint16_t)-1; + } + + inline bool not_null() const { + return index != (uint16_t)-1 || set_index != (uint16_t)-1; + } +}; + +inline bool operator >(const aet_info& left, const aet_info& right) { + return *(uint32_t*)&left > *(uint32_t*)&right; +} + +inline bool operator <(const aet_info& left, const aet_info& right) { + return *(uint32_t*)&left < *(uint32_t*)&right; +} + +inline bool operator >=(const aet_info& left, const aet_info& right) { + return *(uint32_t*)&left >= *(uint32_t*)&right; +} + +inline bool operator <=(const aet_info& left, const aet_info& right) { + return *(uint32_t*)&left <= *(uint32_t*)&right; +} + +inline bool operator ==(const aet_info& left, const aet_info& right) { + return *(uint32_t*)&left == *(uint32_t*)&right; +} + +inline bool operator !=(const aet_info& left, const aet_info& right) { + return *(uint32_t*)&left != *(uint32_t*)&right; +} + +struct aet_db_aet_file { + uint32_t id; + std::string name; + uint16_t index; + + aet_db_aet_file(); + ~aet_db_aet_file(); +}; + +struct aet_db_aet { + uint32_t id; + std::string name; + uint32_t name_hash; + aet_info info; + + aet_db_aet(); + ~aet_db_aet(); +}; + +struct aet_db_aet_set_file { + uint32_t id; + std::string name; + std::string file_name; + std::vector aet; + uint16_t index; + uint32_t sprite_set_id; + + aet_db_aet_set_file(); + ~aet_db_aet_set_file(); +}; + +struct aet_db_aet_set { + uint32_t id; + std::string name; + uint32_t name_hash; + std::string file_name; + uint32_t file_name_hash; + uint16_t index; + uint32_t sprite_set_id; + + aet_db_aet_set(); + ~aet_db_aet_set(); +}; + +struct aet_database_file { + bool ready; + bool modern; + bool big_endian; + bool is_x; + + std::vector aet_set; + + aet_database_file(); + ~aet_database_file(); + + void read(const char* path, bool modern); + void read(const wchar_t* path, bool modern); + void read(const void* data, size_t size, bool modern); + void write(const char* path); + void write(const wchar_t* path); + void write(void** data, size_t* size); + + static bool load_file(void* data, const char* path, const char* file, uint32_t hash); +}; + +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; + + aet_database(); + ~aet_database(); + + void add(aet_database_file* aet_db_file); + + 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; + const aet_db_aet_set* get_aet_set_by_index(uint32_t index) const; + 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; + const char* get_aet_set_name(uint32_t set_id) const; +}; diff --git a/src/KKdLib/database/object.hpp b/src/KKdLib/database/object.hpp index 4c521830..99b83466 100644 --- a/src/KKdLib/database/object.hpp +++ b/src/KKdLib/database/object.hpp @@ -46,27 +46,27 @@ struct object_info { }; inline bool operator >(const object_info& left, const object_info& right) { - return left.set_id > right.set_id && left.id > right.id; + return *(uint64_t*)&left > *(uint64_t*)&right; } inline bool operator <(const object_info& left, const object_info& right) { - return left.set_id < right.set_id&& left.id < right.id; + return *(uint64_t*)&left < *(uint64_t*)&right; } inline bool operator >=(const object_info& left, const object_info& right) { - return left.set_id >= right.set_id && left.id >= right.id; + return *(uint64_t*)&left >= *(uint64_t*)&right; } inline bool operator <=(const object_info& left, const object_info& right) { - return left.set_id <= right.set_id && left.id <= right.id; + return *(uint64_t*)&left <= *(uint64_t*)&right; } inline bool operator ==(const object_info& left, const object_info& right) { - return left.set_id == right.set_id && left.id == right.id; + return *(uint64_t*)&left == *(uint64_t*)&right; } inline bool operator !=(const object_info& left, const object_info& right) { - return left.set_id != right.set_id || left.id != right.id; + return *(uint64_t*)&left != *(uint64_t*)&right; } struct object_info_data_file { diff --git a/src/KKdLib/database/sprite.cpp b/src/KKdLib/database/sprite.cpp index fd1602ad..9f2291b4 100644 --- a/src/KKdLib/database/sprite.cpp +++ b/src/KKdLib/database/sprite.cpp @@ -243,9 +243,8 @@ sprite_database::~sprite_database() { void sprite_database::add(sprite_database_file* spr_db_file) { if (!spr_db_file || !spr_db_file->ready) return; - return; - size_t sprite_sets_count = this->spr_ids.size(); + size_t sprite_sets_count = this->spr_set_ids.size(); spr_set_ids.reserve(spr_db_file->sprite_set.size()); spr_set_indices.reserve(spr_db_file->sprite_set.size()); @@ -281,12 +280,12 @@ void sprite_database::add(sprite_database_file* spr_db_file) { } } - spr_set_ids.sort_unique(); - spr_set_indices.sort_unique(); - spr_set_names.sort_unique(); - spr_ids.sort_unique(); - spr_names.sort_unique(); - spr_indices.sort_unique(); + spr_set_ids.combine(); + spr_set_indices.combine(); + spr_set_names.combine(); + spr_ids.combine(); + spr_names.combine(); + spr_indices.combine(); } const spr_db_spr_set* sprite_database::get_spr_set_by_name(const char* name) const { @@ -346,8 +345,8 @@ uint32_t sprite_database::get_spr_set_id_by_name(const char* name) const { return get_spr_set_by_name(name)->id; } -uint32_t sprite_database::get_spr_set_id_by_index(uint32_t index) const { - return spr_ids[index].first; +uint32_t sprite_database::get_spr_set_id_by_name_index(uint32_t index) const { + return spr_set_names[index].second.id; } const char* sprite_database::get_spr_set_name(uint32_t set_id) const { @@ -370,7 +369,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 = s.read_uint32_t(); + spr_set.index = (uint16_t)s.read_uint32_t(); } s.position_pop(); @@ -529,7 +528,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 = s.read_uint32_t_reverse_endianness(); + spr_set.index = (uint16_t)s.read_uint32_t_reverse_endianness(); } else for (uint32_t i = 0; i < sprite_sets_count; i++) { @@ -537,7 +536,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 = s.read_uint32_t_reverse_endianness(); + spr_set.index = (uint16_t)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 d2b787b3..078696bd 100644 --- a/src/KKdLib/database/sprite.hpp +++ b/src/KKdLib/database/sprite.hpp @@ -8,7 +8,7 @@ #include #include #include "../default.hpp" -#include "../prj/vector_pair.hpp" +#include "../prj/vector_pair_combine.hpp" #include "../hash.hpp" struct spr_info { @@ -32,38 +32,30 @@ struct spr_info { inline bool not_null() const { return index != (uint16_t)-1 || set_index != (uint16_t)-1; } - - inline bool is_null_modern() const { - return index == (uint16_t)-1 && set_index == (uint16_t)-1; - } - - inline bool not_null_modern() const { - return index != (uint16_t)-1 || set_index != (uint16_t)-1; - } }; inline bool operator >(const spr_info& left, const spr_info& right) { - return left.set_index > right.set_index && left.index > right.index; + return *(uint32_t*)&left > *(uint32_t*)&right; } inline bool operator <(const spr_info& left, const spr_info& right) { - return left.set_index < right.set_index&& left.index < right.index; + return *(uint32_t*)&left < *(uint32_t*)&right; } inline bool operator >=(const spr_info& left, const spr_info& right) { - return left.set_index >= right.set_index && left.index >= right.index; + return *(uint32_t*)&left >= *(uint32_t*)&right; } inline bool operator <=(const spr_info& left, const spr_info& right) { - return left.set_index <= right.set_index && left.index <= right.index; + return *(uint32_t*)&left <= *(uint32_t*)&right; } inline bool operator ==(const spr_info& left, const spr_info& right) { - return left.set_index == right.set_index && left.index == right.index; + return *(uint32_t*)&left == *(uint32_t*)&right; } inline bool operator !=(const spr_info& left, const spr_info& right) { - return left.set_index != right.set_index || left.index != right.index; + return *(uint32_t*)&left != *(uint32_t*)&right; } struct spr_db_spr_file { @@ -131,12 +123,12 @@ struct sprite_database_file { }; struct sprite_database { - prj::vector_pair spr_set_ids; - prj::vector_pair spr_set_indices; - prj::vector_pair spr_set_names; - prj::vector_pair spr_ids; - prj::vector_pair spr_names; - prj::vector_pair spr_indices; + 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; sprite_database(); ~sprite_database(); @@ -152,6 +144,6 @@ struct sprite_database { const spr_db_spr* get_tex_by_set_id_index(uint32_t set_id, uint32_t index) const; const char* get_spr_set_file_name(uint32_t set_id) const; uint32_t get_spr_set_id_by_name(const char* name) const; - uint32_t get_spr_set_id_by_index(uint32_t index) const; + uint32_t get_spr_set_id_by_name_index(uint32_t index) const; const char* get_spr_set_name(uint32_t set_id) const; }; diff --git a/src/KKdLib/prj/vector_pair_combine.hpp b/src/KKdLib/prj/vector_pair_combine.hpp new file mode 100644 index 00000000..43880faf --- /dev/null +++ b/src/KKdLib/prj/vector_pair_combine.hpp @@ -0,0 +1,171 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder + + Taken from MSVC's VC/include/memory +*/ + +#pragma once + +#include "../default.hpp" +#include +#include + +namespace prj { + template + class vector_pair_combine { + public: + using value_pair = std::pair; + std::vector data; + std::vector new_data; + + inline typename 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 typename 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; + }); + + for (auto& i : new_data) { + auto elem = find(i.first); + if (elem != data.end()) + elem->second = i.second; + else + data.push_back(i); + } + + new_data.clear(); + + if (data.size() <= 1) + return; + + 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++; + } + + if (data.size() != end - begin) + data.resize(end - begin); + } + + inline typename auto begin() { + return data.begin(); + } + + inline typename auto begin() const { + return data.begin(); + } + + inline typename auto cbegin() const { + return data.cbegin(); + } + + inline typename auto end() { + return data.end(); + } + + inline typename auto end() const { + return data.end(); + } + + inline typename auto cend() const { + return data.cend(); + } + + inline typename auto rbegin() { + return data.rbegin(); + } + + inline typename auto rbegin() const { + return data.rbegin(); + } + + inline typename auto crbegin() const { + return data.crbegin(); + } + + inline typename auto rend() { + return data.rend(); + } + + inline typename auto rend() const { + return data.rend(); + } + + inline typename auto crend() const { + return data.crend(); + } + + inline void push_back(const value_pair& value) { + new_data.push_back(value); + } + + inline void push_back(value_pair&& value) { + new_data.push_back(value); + } + + inline void reserve(size_t new_capacity) { + new_data.reserve(new_capacity); + } + + inline size_t size() const { + return data.size(); + } + + value_pair& operator[](const size_t pos) noexcept { + return data[pos]; + } + + const value_pair& operator[](const size_t pos) const noexcept { + return data[pos]; + } + }; +} diff --git a/src/KKdLib/vec.hpp b/src/KKdLib/vec.hpp index 2b214b09..daebc234 100644 --- a/src/KKdLib/vec.hpp +++ b/src/KKdLib/vec.hpp @@ -1642,324 +1642,324 @@ inline vec4i vec4i::clamp(const vec4i& left, const int32_t min, const int32_t ma vec4i::load_xmm(min)), vec4i::load_xmm(max))); } -inline void vec2i8_to_vec2(vec2i8& src, vec2& dst) { +inline void vec2i8_to_vec2(const vec2i8& src, vec2& dst) { dst.x = (float_t)src.x; dst.y = (float_t)src.y; } -inline void vec3i8_to_vec3(vec3i8& src, vec3& dst) { +inline void vec3i8_to_vec3(const vec3i8& src, vec3& dst) { dst.x = (float_t)src.x; dst.y = (float_t)src.y; dst.z = (float_t)src.z; } -inline void vec4i8_to_vec4(vec4i8& src, vec4& dst) { +inline void vec4i8_to_vec4(const vec4i8& src, vec4& dst) { dst.x = (float_t)src.x; dst.y = (float_t)src.y; dst.z = (float_t)src.z; dst.w = (float_t)src.w; } -inline void vec2_to_vec2i8(vec2& src, vec2i8& dst) { +inline void vec2_to_vec2i8(const vec2& src, vec2i8& dst) { dst.x = (int8_t)src.x; dst.y = (int8_t)src.y; } -inline void vec3_to_vec3i8(vec3& src, vec3i8& dst) { +inline void vec3_to_vec3i8(const vec3& src, vec3i8& dst) { dst.x = (int8_t)src.x; dst.y = (int8_t)src.y; dst.z = (int8_t)src.z; } -inline void vec4_to_vec4i8(vec4& src, vec4i8& dst) { +inline void vec4_to_vec4i8(const vec4& src, vec4i8& dst) { dst.x = (int8_t)src.x; dst.y = (int8_t)src.y; dst.z = (int8_t)src.z; dst.w = (int8_t)src.w; } -inline void vec2u8_to_vec2(vec2u8& src, vec2& dst) { +inline void vec2u8_to_vec2(const vec2u8& src, vec2& dst) { dst.x = (float_t)src.x; dst.y = (float_t)src.y; } -inline void vec3u8_to_vec3(vec3u8& src, vec3& dst) { +inline void vec3u8_to_vec3(const vec3u8& src, vec3& dst) { dst.x = (float_t)src.x; dst.y = (float_t)src.y; dst.z = (float_t)src.z; } -inline void vec4u8_to_vec4(vec4u8& src, vec4& dst) { +inline void vec4u8_to_vec4(const vec4u8& src, vec4& dst) { dst.x = (float_t)src.x; dst.y = (float_t)src.y; dst.z = (float_t)src.z; dst.w = (float_t)src.w; } -inline void vec2_to_vec2u8(vec2& src, vec2u8& dst) { +inline void vec2_to_vec2u8(const vec2& src, vec2u8& dst) { dst.x = (uint8_t)src.x; dst.y = (uint8_t)src.y; } -inline void vec3_to_vec3u8(vec3& src, vec3u8& dst) { +inline void vec3_to_vec3u8(const vec3& src, vec3u8& dst) { dst.x = (uint8_t)src.x; dst.y = (uint8_t)src.y; dst.z = (uint8_t)src.z; } -inline void vec4_to_vec4u8(vec4& src, vec4u8& dst) { +inline void vec4_to_vec4u8(const vec4& src, vec4u8& dst) { dst.x = (uint8_t)src.x; dst.y = (uint8_t)src.y; dst.z = (uint8_t)src.z; dst.w = (uint8_t)src.w; } -inline void vec2i16_to_vec2(vec2i16& src, vec2& dst) { +inline void vec2i16_to_vec2(const vec2i16& src, vec2& dst) { dst.x = (float_t)src.x; dst.y = (float_t)src.y; } -inline void vec3i16_to_vec3(vec3i16& src, vec3& dst) { +inline void vec3i16_to_vec3(const vec3i16& src, vec3& dst) { dst.x = (float_t)src.x; dst.y = (float_t)src.y; dst.z = (float_t)src.z; } -inline void vec4i16_to_vec4(vec4i16& src, vec4& dst) { +inline void vec4i16_to_vec4(const vec4i16& src, vec4& dst) { dst.x = (float_t)src.x; dst.y = (float_t)src.y; dst.z = (float_t)src.z; dst.w = (float_t)src.w; } -inline void vec2_to_vec2i16(vec2& src, vec2i16& dst) { +inline void vec2_to_vec2i16(const vec2& src, vec2i16& dst) { dst.x = (int16_t)src.x; dst.y = (int16_t)src.y; } -inline void vec3_to_vec3i16(vec3& src, vec3i16& dst) { +inline void vec3_to_vec3i16(const vec3& src, vec3i16& dst) { dst.x = (int16_t)src.x; dst.y = (int16_t)src.y; dst.z = (int16_t)src.z; } -inline void vec4_to_vec4i16(vec4& src, vec4i16& dst) { +inline void vec4_to_vec4i16(const vec4& src, vec4i16& dst) { dst.x = (int16_t)src.x; dst.y = (int16_t)src.y; dst.z = (int16_t)src.z; dst.w = (int16_t)src.w; } -inline void vec2u16_to_vec2(vec2u16& src, vec2& dst) { +inline void vec2u16_to_vec2(const vec2u16& src, vec2& dst) { dst.x = (float_t)src.x; dst.y = (float_t)src.y; } -inline void vec3u16_to_vec3(vec3u16& src, vec3& dst) { +inline void vec3u16_to_vec3(const vec3u16& src, vec3& dst) { dst.x = (float_t)src.x; dst.y = (float_t)src.y; dst.z = (float_t)src.z; } -inline void vec4u16_to_vec4(vec4u16& src, vec4& dst) { +inline void vec4u16_to_vec4(const vec4u16& src, vec4& dst) { dst.x = (float_t)src.x; dst.y = (float_t)src.y; dst.z = (float_t)src.z; dst.w = (float_t)src.w; } -inline void vec2_to_vec2u16(vec2& src, vec2u16& dst) { +inline void vec2_to_vec2u16(const vec2& src, vec2u16& dst) { dst.x = (uint16_t)src.x; dst.y = (uint16_t)src.y; } -inline void vec3_to_vec3u16(vec3& src, vec3u16& dst) { +inline void vec3_to_vec3u16(const vec3& src, vec3u16& dst) { dst.x = (uint16_t)src.x; dst.y = (uint16_t)src.y; dst.z = (uint16_t)src.z; } -inline void vec4_to_vec4u16(vec4& src, vec4u16& dst) { +inline void vec4_to_vec4u16(const vec4& src, vec4u16& dst) { dst.x = (uint16_t)src.x; dst.y = (uint16_t)src.y; dst.z = (uint16_t)src.z; dst.w = (uint16_t)src.w; } -inline void vec2h_to_vec2(vec2h& src, vec2& dst) { +inline void vec2h_to_vec2(const vec2h& src, vec2& dst) { dst.x = half_to_float(src.x); dst.y = half_to_float(src.y); } -inline void vec3h_to_vec3(vec3h& src, vec3& dst) { +inline void vec3h_to_vec3(const vec3h& src, vec3& dst) { dst.x = half_to_float(src.x); dst.y = half_to_float(src.y); dst.z = half_to_float(src.z); } -inline void vec4h_to_vec4(vec4h& src, vec4& dst) { +inline void vec4h_to_vec4(const vec4h& src, vec4& dst) { dst.x = half_to_float(src.x); dst.y = half_to_float(src.y); dst.z = half_to_float(src.z); dst.w = half_to_float(src.w); } -inline void vec2_to_vec2h(vec2& src, vec2h& dst) { +inline void vec2_to_vec2h(const vec2& src, vec2h& dst) { dst.x = float_to_half(src.x); dst.y = float_to_half(src.y); } -inline void vec3_to_vec3h(vec3& src, vec3h& dst) { +inline void vec3_to_vec3h(const vec3& src, vec3h& dst) { dst.x = float_to_half(src.x); dst.y = float_to_half(src.y); dst.z = float_to_half(src.z); } -inline void vec4_to_vec4h(vec4& src, vec4h& dst) { +inline void vec4_to_vec4h(const vec4& src, vec4h& dst) { dst.x = float_to_half(src.x); dst.y = float_to_half(src.y); dst.z = float_to_half(src.z); dst.w = float_to_half(src.w); } -inline void vec2i8_to_vec2i(vec2i8& src, vec2i& dst) { +inline void vec2i8_to_vec2i(const vec2i8& src, vec2i& dst) { dst.x = src.x; dst.y = src.y; } -inline void vec3i8_to_vec3i(vec3i8& src, vec3i& dst) { +inline void vec3i8_to_vec3i(const vec3i8& src, vec3i& dst) { dst.x = src.x; dst.y = src.y; dst.z = src.z; } -inline void vec4i8_to_vec4i(vec4i8& src, vec4i& dst) { +inline void vec4i8_to_vec4i(const vec4i8& src, vec4i& dst) { dst.x = src.x; dst.y = src.y; dst.z = src.z; dst.w = src.w; } -inline void vec2i_to_vec2i8(vec2i& src, vec2i8& dst) { +inline void vec2i_to_vec2i8(const vec2i& src, vec2i8& dst) { dst.x = (int8_t)src.x; dst.y = (int8_t)src.y; } -inline void vec3i_to_vec3i8(vec3i& src, vec3i8& dst) { +inline void vec3i_to_vec3i8(const vec3i& src, vec3i8& dst) { dst.x = (int8_t)src.x; dst.y = (int8_t)src.y; dst.z = (int8_t)src.z; } -inline void vec4i_to_vec4i8(vec4i& src, vec4i8& dst) { +inline void vec4i_to_vec4i8(const vec4i& src, vec4i8& dst) { dst.x = (int8_t)src.x; dst.y = (int8_t)src.y; dst.z = (int8_t)src.z; dst.w = (int8_t)src.w; } -inline void vec2u8_to_vec2i(vec2u8& src, vec2i& dst) { +inline void vec2u8_to_vec2i(const vec2u8& src, vec2i& dst) { dst.x = src.x; dst.y = src.y; } -inline void vec3u8_to_vec4i(vec3u8& src, vec3i& dst) { +inline void vec3u8_to_vec4i(const vec3u8& src, vec3i& dst) { dst.x = src.x; dst.y = src.y; dst.z = src.z; } -inline void vec4u8_to_vec4i(vec4u8& src, vec4i& dst) { +inline void vec4u8_to_vec4i(const vec4u8& src, vec4i& dst) { dst.x = src.x; dst.y = src.y; dst.z = src.z; dst.w = src.w; } -inline void vec2i_to_vec2u8(vec2i& src, vec2u8& dst) { +inline void vec2i_to_vec2u8(const vec2i& src, vec2u8& dst) { dst.x = (uint8_t)src.x; dst.y = (uint8_t)src.y; } -inline void vec3i_to_vec3u8(vec3i& src, vec3u8& dst) { +inline void vec3i_to_vec3u8(const vec3i& src, vec3u8& dst) { dst.x = (uint8_t)src.x; dst.y = (uint8_t)src.y; dst.z = (uint8_t)src.z; } -inline void vec4i_to_vec4u8(vec4i& src, vec4u8& dst) { +inline void vec4i_to_vec4u8(const vec4i& src, vec4u8& dst) { dst.x = (uint8_t)src.x; dst.y = (uint8_t)src.y; dst.z = (uint8_t)src.z; dst.w = (uint8_t)src.w; } -inline void vec2i16_to_vec2i(vec2i16& src, vec2i& dst) { +inline void vec2i16_to_vec2i(const vec2i16& src, vec2i& dst) { dst.x = src.x; dst.y = src.y; } -inline void vec3i16_to_vec4i(vec3i16& src, vec3i& dst) { +inline void vec3i16_to_vec4i(const vec3i16& src, vec3i& dst) { dst.x = src.x; dst.y = src.y; dst.z = src.z; } -inline void vec4i16_to_vec4i(vec4i16& src, vec4i& dst) { +inline void vec4i16_to_vec4i(const vec4i16& src, vec4i& dst) { dst.x = src.x; dst.y = src.y; dst.z = src.z; dst.w = src.w; } -inline void vec2i_to_vec2i16(vec2i& src, vec2i16& dst) { +inline void vec2i_to_vec2i16(const vec2i& src, vec2i16& dst) { dst.x = (int16_t)src.x; dst.y = (int16_t)src.y; } -inline void vec3i_to_vec3i16(vec3i& src, vec3i16& dst) { +inline void vec3i_to_vec3i16(const vec3i& src, vec3i16& dst) { dst.x = (int16_t)src.x; dst.y = (int16_t)src.y; dst.z = (int16_t)src.z; } -inline void vec4i_to_vec4i16(vec4i& src, vec4i16& dst) { +inline void vec4i_to_vec4i16(const vec4i& src, vec4i16& dst) { dst.x = (int16_t)src.x; dst.y = (int16_t)src.y; dst.z = (int16_t)src.z; dst.w = (int16_t)src.w; } -inline void vec2u16_to_vec2i(vec2u16& src, vec2i& dst) { +inline void vec2u16_to_vec2i(const vec2u16& src, vec2i& dst) { dst.x = src.x; dst.y = src.y; } -inline void vec3u16_to_vec4i(vec3u16& src, vec3i& dst) { +inline void vec3u16_to_vec4i(const vec3u16& src, vec3i& dst) { dst.x = src.x; dst.y = src.y; dst.z = src.z; } -inline void vec4u16_to_vec4i(vec4u16& src, vec4i& dst) { +inline void vec4u16_to_vec4i(const vec4u16& src, vec4i& dst) { dst.x = src.x; dst.y = src.y; dst.z = src.z; dst.w = src.w; } -inline void vec2i_to_vec2u16(vec2i& src, vec2u16& dst) { +inline void vec2i_to_vec2u16(const vec2i& src, vec2u16& dst) { dst.x = (uint16_t)src.x; dst.y = (uint16_t)src.y; } -inline void vec3i_to_vec3u16(vec3i& src, vec3u16& dst) { +inline void vec3i_to_vec3u16(const vec3i& src, vec3u16& dst) { dst.x = (uint16_t)src.x; dst.y = (uint16_t)src.y; dst.z = (uint16_t)src.z; } -inline void vec4i_to_vec4u16(vec4i& src, vec4u16& dst) { +inline void vec4i_to_vec4u16(const vec4i& src, vec4u16& dst) { dst.x = (uint16_t)src.x; dst.y = (uint16_t)src.y; dst.z = (uint16_t)src.z; diff --git a/src/ReDIVA/classes/glitter_editor.cpp b/src/ReDIVA/classes/glitter_editor.cpp index 38d6d7c1..0ab5f7e4 100644 --- a/src/ReDIVA/classes/glitter_editor.cpp +++ b/src/ReDIVA/classes/glitter_editor.cpp @@ -6657,7 +6657,7 @@ static void glitter_editor_curve_editor_window_draw(GlitterEditor* glt_edt, cons const ImU32 random_range_color = ImGui::GetColorU32({ 0.5f, 0.5f, 0.0f, 0.25f }); const ImU32 key_random_range_color = ImGui::GetColorU32({ 0.5f, 0.0f, 0.5f, 0.25f }); - const std::vector* keys = &curve->keys_rev; + const std::vector* keys = &curve->keys_rev; if (!keys->size()) return; diff --git a/src/ReDIVA/data_initialize.cpp b/src/ReDIVA/data_initialize.cpp index 83234814..49ec5657 100644 --- a/src/ReDIVA/data_initialize.cpp +++ b/src/ReDIVA/data_initialize.cpp @@ -4,6 +4,7 @@ */ #include "data_initialize.hpp" +#include "../CRE/auth_2d.hpp" #include "../CRE/data.hpp" #include "../CRE/hand_item.hpp" #include "../CRE/item_table.hpp" @@ -32,20 +33,24 @@ bool TaskDataInit::Init() { bool TaskDataInit::Ctrl() { data_struct* aft_data = &data_list[DATA_AFT]; + aet_database* aft_aet_db = &aft_data->data_ft.aet_db; object_database* aft_obj_db = &aft_data->data_ft.obj_db; + sprite_database* aft_spr_db = &aft_data->data_ft.spr_db; switch (state) { case 0: { sprite_manager_reset_res_data(); - //sprite_manager_load_set(4, ""); - //sprite_manager_load_set(472, ""); - //sprite_manager_load_set(43, ""); + sprite_manager_read_file(4, "", aft_data, aft_spr_db); + sprite_manager_read_file(472, "", aft_data, aft_spr_db); + sprite_manager_read_file(43, "", aft_data, aft_spr_db); //fontmap_data_read_file(); state = 1; } break; case 1: - //if (!sprite_manager_load_file(4) && !sprite_manager_load_file(472) - // && !sprite_manager_load_file(43) && !fontmap_data_parse_file()) + 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; case 2: @@ -57,23 +62,25 @@ bool TaskDataInit::Ctrl() { state = 4; break; case 4: { - //sprite_manager_load_set(32, ""); - //aet_manager_load_set(26, ""); - //sprite_manager_load_set(34, ""); - //aet_manager_load_set(35, ""); + sprite_manager_read_file(32, "", aft_data, aft_spr_db); + aet_manager_read_file(26, "", aft_data, aft_aet_db); + sprite_manager_read_file(34, "", aft_data, aft_spr_db); + aet_manager_read_file(35, "", aft_data, aft_aet_db); state = 5; } break; case 5: - //if (!sprite_manager_load_file(32) && !aet_manager_load_file(26) - // && !sprite_manager_load_file(34) && !aet_manager_load_file(35)) - // break; + if (sprite_manager_load_file(32, aft_spr_db) + || aet_manager_load_file(26, aft_aet_db) + || sprite_manager_load_file(34, aft_spr_db) + || aet_manager_load_file(35, aft_aet_db)) + break; state = 6; case 6: //auth_3d_database_read_file(); //stage_database_read_file(); state = 7; - break; + //break; case 7: //if (auth_3d_database_load_file() || stage_database_load_file()) // break; diff --git a/src/ReDIVA/data_test/auth_2d_test.cpp b/src/ReDIVA/data_test/auth_2d_test.cpp new file mode 100644 index 00000000..de67b1cb --- /dev/null +++ b/src/ReDIVA/data_test/auth_2d_test.cpp @@ -0,0 +1,509 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#include "auth_2d_test.hpp" +#include "../../KKdLib/io/path.hpp" +#include "../../KKdLib/prj/algorithm.hpp" +#include "../../KKdLib/sort.hpp" +#include "../../KKdLib/str_utils.hpp" +#include "../../CRE/auth_2d.hpp" +#include "../../CRE/data.hpp" +#include "../../CRE/render_context.hpp" +#include "../../CRE/sound.hpp" +#include "../../CRE/sprite.hpp" +#include "../../CRE/stage.hpp" +#include "../../CRE/task_effect.hpp" +#include "../imgui_helper.hpp" +#include "../input.hpp" +#include "../task_window.hpp" + +extern int32_t width; +extern int32_t height; + +DtmAet* dtm_aet; +DtwAet* dtw_aet; + +DtmAet::DtmAet() : curr_set_index(), set_index(), id_index(), layer_index(), marker_index(), +type(), frame(), start_time(), end_time(), lock(), loop(), centering(), state() { + +} + +DtmAet::~DtmAet() { + +} + +bool DtmAet::Init() { + data_struct* aft_data = &data_list[DATA_AFT]; + aet_database* aft_aet_db = &aft_data->data_ft.aet_db; + sprite_database* aft_spr_db = &aft_data->data_ft.spr_db; + + uint32_t set_id = aft_aet_db->get_aet_set_id_by_name_index(this->curr_set_index); + std::string mdata_dir = "";//GetMdataDir(set_id); + sprite_manager_read_file(aft_aet_db->get_aet_set_by_id(set_id)->sprite_set_id, + mdata_dir, aft_data, aft_spr_db); + aet_manager_read_file(set_id, mdata_dir, aft_data, aft_aet_db); + GetSoundFarcs(); + state = 1; + return true; +} + +bool DtmAet::Ctrl() { + data_struct* aft_data = &data_list[DATA_AFT]; + aet_database* aft_aet_db = &aft_data->data_ft.aet_db; + sprite_database* aft_spr_db = &aft_data->data_ft.spr_db; + + switch (state) { + case 1: { + bool wait_load = false; + + for (std::string& i : sound_farcs) + wait_load |= sound_work_load_farc(i.c_str()); + + if (!wait_load) + state = 2; + } break; + case 2: { + uint32_t prev_set_id = aft_aet_db->get_aet_set_id_by_name_index(curr_set_index); + sprite_manager_unload_set(aft_aet_db->get_aet_set_by_id(prev_set_id)->sprite_set_id, aft_spr_db); + aet_manager_unload_set(prev_set_id, aft_aet_db); + + curr_set_index = set_index; + uint32_t set_id = aft_aet_db->get_aet_set_id_by_name_index(set_index); + + std::string mdata_dir = "";//GetMdataDir(set_id); + sprite_manager_read_file(aft_aet_db->get_aet_set_by_id(set_id)->sprite_set_id, + mdata_dir, aft_data, aft_spr_db); + aet_manager_read_file(set_id, mdata_dir, aft_data, aft_aet_db); + state = 3; + } break; + case 3: { + uint32_t set_id = aft_aet_db->get_aet_set_id_by_name_index(curr_set_index); + if (sprite_manager_load_file(aft_aet_db->get_aet_set_by_id(set_id)->sprite_set_id, aft_spr_db) + || aet_manager_load_file(set_id, aft_aet_db)) + break; + + dw::List* id_list = dtw_aet->id->list; + id_list->ClearItems(); + + uint32_t scenes_count = aet_manager_get_scenes_count(set_id, aft_aet_db); + for (uint32_t i = scenes_count, j = 0; i; i--, j++) + id_list->AddItem(aet_manager_get_scene_name( + aft_aet_db->get_aet_by_set_id_index(set_id, j)->id, aft_aet_db)); + + id_list->hovered_item = id_index; + id_list->ResetSetSelectedItem(id_index); + state = 4; + } break; + case 4: { + uint32_t set_id = aft_aet_db->get_aet_set_id_by_name_index(curr_set_index); + uint32_t aet_id = aft_aet_db->get_aet_by_set_id_index(set_id, id_index)->id; + + comp_layers.clear(); + aet_manager_get_scene_comp_layer_names(comp_layers, aet_id, aft_aet_db); + prj::sort_unique(comp_layers); + + auto i = comp_layers.begin(); + auto i_end = comp_layers.end(); + while (i != i_end) + if (i->find(".pic") != -1) + i = comp_layers.erase(i); + else + i++; + + dw::List* layer_list = dtw_aet->layer->list; + layer_list->ClearItems(); + layer_list->AddItem("ROOT"); + for (std::string& i : comp_layers) + layer_list->AddItem(i); + + layer_list->hovered_item = layer_index; + layer_list->ResetSetSelectedItem(layer_index); + state = 5; + } break; + case 5: { + uint32_t set_id = aft_aet_db->get_aet_set_id_by_name_index(curr_set_index); + uint32_t aet_id = aft_aet_db->get_aet_by_set_id_index(set_id, id_index)->id; + + markers.clear(); + + if (layer_index) + aet_manager_get_scene_layer_marker_names(markers, aet_id, + comp_layers[layer_index - 1].c_str(), aft_aet_db); + + if (layer_index) + start_time = aet_manager_get_scene_layer_start_time(aet_id, + comp_layers[layer_index - 1].c_str(), aft_aet_db); + else + start_time = aet_manager_get_scene_start_time(aet_id, aft_aet_db); + + if (layer_index) + end_time = aet_manager_get_scene_layer_end_time(aet_id, + comp_layers[layer_index - 1].c_str(), aft_aet_db); + else + end_time = aet_manager_get_scene_end_time(aet_id, aft_aet_db); + + dw::ListBox* marker = dtw_aet->marker; + if (marker->list) + marker->ClearItems(); + + marker->AddItem("NOMARKER"); + + for (std::string& i : markers) + marker->AddItem(i); + + if (marker->list) { + marker->list->hovered_item = marker_index; + marker->list->ResetSetSelectedItem(marker_index); + } + state = 6; + } break; + case 6: { + uint32_t set_id = aft_aet_db->get_aet_set_id_by_name_index(curr_set_index); + uint32_t aet_id = aft_aet_db->get_aet_by_set_id_index(set_id, id_index)->id; + + float_t frame; + if (layer_index && marker_index) + frame = aet_manager_get_scene_layer_marker_time(aet_id, + comp_layers[layer_index - 1].c_str(), markers[marker_index - 1].c_str(), aft_aet_db); + else + frame = start_time; + + char buf[0x20]; + sprintf_s(buf, sizeof(buf), "%f frame", frame); + dtw_aet->marker_frame->SetName(buf); + this->frame = frame; + state = 7; + } break; + case 7: { + uint32_t set_id = aft_aet_db->get_aet_set_id_by_name_index(curr_set_index); + uint32_t aet_id = aft_aet_db->get_aet_by_set_id_index(set_id, id_index)->id; + + const char* layer_name = 0; + if (layer_index) + layer_name = comp_layers[layer_index - 1].c_str(); + + if (type) { + data.clear(); + aet_manager_init_aet_layout(&data, aet_id, layer_name, + (AetFlags)0, RESOLUTION_MODE_HD, 0, frame, aft_aet_db); + } + else { + float_t x = 0.0f; + float_t y = 0.0f; + + if (centering) { + x = res_window_get()->width * 0.5f; + y = res_window_get()->height * 0.5f; + } + + AetArgs args; + args.id.id = aet_id; + args.layer_name = layer_name; + args.start_time = frame; + args.end_time = frame; + args.pos.x = x; + args.pos.y = y; + args.pos.z = 0.0f; + args.sound_voice = true; + args.spr_db = aft_spr_db; + aet_manager_init_aet_object(args, aft_aet_db); + } + + dtw_aet->frame->scroll_bar->SetParams(frame, + start_time, end_time, (end_time - start_time) * 0.1f, 1.0f, 10.0f); + } break; + } + return false; +} + +bool DtmAet::Dest() { + data_struct* aft_data = &data_list[DATA_AFT]; + aet_database* aft_aet_db = &aft_data->data_ft.aet_db; + sprite_database* aft_spr_db = &aft_data->data_ft.spr_db; + + uint32_t set_id = aft_aet_db->get_aet_set_id_by_name_index(curr_set_index); + sprite_manager_unload_set(aft_aet_db->get_aet_set_by_id(set_id)->sprite_set_id, aft_spr_db); + aet_manager_unload_set(set_id, aft_aet_db); + + for (std::string& i : sound_farcs) + sound_work_unload_farc(i.c_str()); + sound_farcs.clear(); + state = 0; + return true; +} + +void DtmAet::Disp() { + if (state != 7) + return; +} + +void DtmAet::Basic() { + if (state != 7) + return; + + if (!lock) + frame += 1.0f; + + if (frame > end_time) + if (loop) + frame = start_time; + else + frame = end_time; +} + +void DtmAet::GetSoundFarcs() { + static const char* dtm_aet_sound_farcs[] = { + "rom/sound/se_sel.farc", + "rom/sound/se_result.farc", + "rom/sound/se_adv.farc", + "rom/sound/se_over.farc", + }; + + sound_farcs.clear(); + for (const char* i : dtm_aet_sound_farcs) + if (sound_work_read_farc(i)) + sound_farcs.push_back(i); +} + +void DtmAet::SetSetIndex(int32_t value) { + if (curr_set_index != value) { + set_index = value; + id_index = 0; + layer_index = 0; + marker_index = 0; + state = 2; + } +} + +void DtmAet::SetIdIndex(int32_t value) { + if (id_index != value) { + id_index = value; + layer_index = 0; + marker_index = 0; + state = 4; + } +} + +void DtmAet::SetLayerIndex(int32_t value) { + if (layer_index != value) { + layer_index = value; + marker_index = 0; + state = 5; + } +} + +void DtmAet::SetMarkerIndex(int32_t value) { + if (marker_index != value) { + marker_index = value; + state = 6; + } +} + +void DtmAet::SetType(uint8_t value) { + if (type != value) { + type = value; + state = 7; + } +} + +void DtmAet::SetFrame(float_t value) { + if (frame != value) + frame = value; +} + +void DtmAet::SetLock(bool value) { + if (lock != value) + lock = value; +} + +void DtmAet::SetLoop(bool value) { + if (loop != value) + loop = value; +} + +void DtmAet::SetCentering(bool value) { + if (centering != value) + centering = value; +} + +DtwAet::DtwAet() : Shell(0) { + data_struct* aft_data = &data_list[DATA_AFT]; + aet_database* aft_aet_db = &aft_data->data_ft.aet_db; + + dw::Widget::SetName("2DAUTH TEST"); + + (new dw::Label(this))->SetName("SET"); + + set = new dw::ListBox(this, (dw::Widget::Flags)(WIDGET_SCROLL_V | WIDGET_4)); + + for (size_t i = aft_aet_db->aet_set_ids.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); + } + + //set->list->sub_1402F9930(20); + set->list->hovered_item = dtm_aet->curr_set_index; + set->list->ResetSetSelectedItem(dtm_aet->curr_set_index); + + set->list->AddSelectionListener(new dw::SelectionListenerOnHook(DtwAet::SetCallback)); + + (new dw::Label(this))->SetName("ID"); + + id = new dw::ListBox(this, (dw::Widget::Flags)(WIDGET_SCROLL_V | WIDGET_4)); + //id->list->sub_1402F9930(20); + + id->list->AddSelectionListener(new dw::SelectionListenerOnHook(DtwAet::IdCallback)); + + (new dw::Label(this))->SetName("LAYER"); + + layer = new dw::ListBox(this, (dw::Widget::Flags)(WIDGET_SCROLL_V | WIDGET_4)); + layer->AddItem("ROOT"); + //layer->list->sub_1402F9930(20); + + layer->list->AddSelectionListener(new dw::SelectionListenerOnHook(DtwAet::LayerCallback)); + + (new dw::Label(this))->SetName("MARKER"); + + marker = new dw::ListBox(this, (dw::Widget::Flags)(WIDGET_SCROLL_V | WIDGET_4)); + marker->AddItem("NOMARKER"); + //marker->list->sub_1402F9930(20); + + marker->list->AddSelectionListener(new dw::SelectionListenerOnHook(DtwAet::MarkerCallback)); + + marker_frame = new dw::Label(this); + marker_frame->SetName("0"); + + (new dw::Label(this))->SetName("TYPE"); + + type = new dw::ListBox(this, (dw::Widget::Flags)(WIDGET_SCROLL_V | WIDGET_4)); + type->AddItem("DRAW"); + type->AddItem("LAYOUT"); + + type->list->hovered_item = dtm_aet->type; + type->list->ResetSetSelectedItem(dtm_aet->type); + + type->list->AddSelectionListener(new dw::SelectionListenerOnHook(DtwAet::TypeCallback)); + + (new dw::Label(this))->SetName("FRAME"); + + frame = dw::Slider::make(this, (dw::Widget::Flags)(WIDGET_800 | WIDGET_SCROLL_H), + 0.0f, 0.0f, 128.0f, 20.0f, "slider"); + frame->SetName("FRAME"); + frame->format = "%4.0f"; + + frame->scroll_bar->SetParams(0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 10.0f); + + frame->AddSelectionListener(new dw::SelectionListenerOnHook(DtwAet::FrameCallback)); + + (new dw::Label(this))->SetName("SWITCH"); + + dw::Button* lock = new dw::Button(this, WIDGET_CHECKBOX); + lock->SetName("LOCK"); + lock->callback = DtwAet::LockCallback; + + dw::Button* loop = new dw::Button(this, WIDGET_CHECKBOX); + loop->SetName("LOOP"); + loop->callback = DtwAet::LoopCallback; + + dw::Button* centering = new dw::Button(this, WIDGET_CHECKBOX); + centering->SetName("CENTERING"); + centering->callback = DtwAet::CenteringCallback; + + //GetSetSize(); +} + +DtwAet::~DtwAet() { + +} + +void DtwAet::Hide() { + SetDisp(false); +} + +void DtwAet::CenteringCallback(dw::Widget* data) { + dw::Button* button = dynamic_cast(data); + if (button) + dtm_aet->SetCentering(button->value); +} + +void DtwAet::FrameCallback(dw::Widget* data) { + dw::Slider* slider = dynamic_cast(data); + if (slider) + dtm_aet->SetFrame(slider->scroll_bar->value); +} + +void DtwAet::IdCallback(dw::Widget* data) { + dw::ListBox* list_box = dynamic_cast(data); + if (list_box) + dtm_aet->SetIdIndex((int32_t)list_box->list->selected_item); +} + +void DtwAet::LayerCallback(dw::Widget* data) { + dw::ListBox* list_box = dynamic_cast(data); + if (list_box) + dtm_aet->SetLayerIndex((int32_t)list_box->list->selected_item); +} + +void DtwAet::LockCallback(dw::Widget* data) { + dw::Button* button = dynamic_cast(data); + if (button) + dtm_aet->SetLock(button->value); +} + +void DtwAet::LoopCallback(dw::Widget* data) { + dw::Button* button = dynamic_cast(data); + if (button) + dtm_aet->SetLoop(button->value); +} + +void DtwAet::MarkerCallback(dw::Widget* data) { + dw::ListBox* list_box = dynamic_cast(data); + if (list_box) + dtm_aet->SetMarkerIndex((int32_t)list_box->list->selected_item); +} + +void DtwAet::SetCallback(dw::Widget* data) { + dw::ListBox* list_box = dynamic_cast(data); + if (list_box) + dtm_aet->SetSetIndex((int32_t)list_box->list->selected_item); +} + +void DtwAet::TypeCallback(dw::Widget* data) { + dw::ListBox* list_box = dynamic_cast(data); + if (list_box) + dtm_aet->SetType(list_box->list->selected_item ? 1 : 0); +} + +void dtm_aet_init() { + dtm_aet = new DtmAet; +} + +void dtm_aet_load() { + if (app::TaskWork::CheckTaskReady(dtm_aet)) + return; + + app::TaskWork::AddTask(dtm_aet, "DATA_TEST_AET_MANAGER"); + if (!dtw_aet) + dtw_aet = new DtwAet(); + dtw_aet->Disp(); +} + +void dtm_aet_unload() { + dtm_aet->DelTask(); + dtw_aet->Hide(); +} + +void dtm_aet_free() { + if (dtw_aet) { + delete dtw_aet; + dtw_aet = 0; + } + + if (dtm_aet) { + delete dtm_aet; + dtm_aet = 0; + } +} diff --git a/src/ReDIVA/data_test/auth_2d_test.hpp b/src/ReDIVA/data_test/auth_2d_test.hpp new file mode 100644 index 00000000..8b7b124c --- /dev/null +++ b/src/ReDIVA/data_test/auth_2d_test.hpp @@ -0,0 +1,89 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#pragma once + +#include "../../KKdLib/default.hpp" +#include "../../CRE/auth_2d.hpp" +#include "../dw.hpp" +#include "../task_window.hpp" + +class DtmAet : public app::Task { +public: + std::vector sound_farcs; + //draw_params draw_params; + //font_info font; + uint32_t curr_set_index; + uint32_t set_index; + uint32_t id_index; + uint32_t layer_index; + uint32_t marker_index; + uint8_t type; + std::vector comp_layers; + std::map data; + std::vector markers; + float_t frame; + float_t start_time; + float_t end_time; + bool lock; + bool loop; + bool centering; + int32_t state; + + DtmAet(); + virtual ~DtmAet() override; + + virtual bool Init() override; + virtual bool Ctrl() override; + virtual bool Dest() override; + virtual void Disp() override; + virtual void Basic() override; + + virtual void GetSoundFarcs(); + virtual void SetSetIndex(int32_t value); + virtual void SetIdIndex(int32_t value); + virtual void SetLayerIndex(int32_t value); + virtual void SetMarkerIndex(int32_t value); + virtual void SetType(uint8_t value); + virtual void SetFrame(float_t value); + virtual void SetLock(bool value); + virtual void SetLoop(bool value); + virtual void SetCentering(bool value); +}; + +class DtwAet : public dw::Shell { +public: + dw::ListBox* set; + dw::ListBox* id; + dw::ListBox* layer; + dw::ListBox* marker; + dw::Label* marker_frame; + dw::ListBox* type; + dw::Slider* frame; + + DtwAet(); + virtual ~DtwAet() override; + + virtual void Hide() override; + + static void CenteringCallback(dw::Widget* data); + static void FrameCallback(dw::Widget* data); + static void IdCallback(dw::Widget* data); + static void LayerCallback(dw::Widget* data); + static void LockCallback(dw::Widget* data); + static void LoopCallback(dw::Widget* data); + static void MarkerCallback(dw::Widget* data); + static void SetCallback(dw::Widget* data); + static void TypeCallback(dw::Widget* data); +}; + +extern DtmAet* dtm_aet; + +extern DtwAet* dtw_aet; + +extern void dtm_aet_init(); +extern void dtm_aet_load(); +extern void dtm_aet_unload(); +extern void dtm_aet_free(); diff --git a/src/ReDIVA/data_test/auth_3d_test.cpp b/src/ReDIVA/data_test/auth_3d_test.cpp index b4d5e715..078fd1ca 100644 --- a/src/ReDIVA/data_test/auth_3d_test.cpp +++ b/src/ReDIVA/data_test/auth_3d_test.cpp @@ -42,6 +42,7 @@ Auth3dTestTask::Auth3dTestTask() { auth_3d_uid = -1; repeat = true; left_right_reverse = false; + pos = false; field_1E3 = false; field_1E4 = 0; field_1E8 = false; @@ -78,6 +79,7 @@ bool Auth3dTestTask::Init() { auth_3d_uid = -1; repeat = true; left_right_reverse = false; + pos = false; field_1E3 = false; field_1E4 = 0; field_1E8 = false; @@ -124,6 +126,7 @@ bool Auth3dTestTask::Ctrl() { auth_3d_id.set_paused(false); auth_3d_id.set_repeat(repeat); auth_3d_id.set_left_right_reverse(left_right_reverse); + auth_3d_id.set_pos(pos ? 1 : 0); field_1D4 = 4; } @@ -409,7 +412,7 @@ void Auth3dTestWindow::Window() { ImFont* font = ImGui::GetFont(); float_t w = min_def((float_t)width, 280.0f); - float_t h = min_def((float_t)height, 324.0f); + float_t h = min_def((float_t)height, 344.0f); ImGui::SetNextWindowPos({ 0, 0 }, ImGuiCond_Appearing); ImGui::SetNextWindowSize({ w, h }, ImGuiCond_Always); @@ -552,6 +555,8 @@ void Auth3dTestWindow::Window() { if (ImGui::Checkbox("Left Right Reverse", &auth_3d_test_task->left_right_reverse)) _frame = 0.0f; + + ImGui::Checkbox("pos", &auth_3d_test_task->pos); if (_frame != frame) { frame_changed = true; @@ -631,6 +636,7 @@ void Auth3dTestWindow::Window() { auth_3d_test_task->auth_3d_id.set_enable(enable); auth_3d_test_task->auth_3d_id.set_repeat(auth_3d_test_task->repeat); auth_3d_test_task->auth_3d_id.set_left_right_reverse(auth_3d_test_task->left_right_reverse); + auth_3d_test_task->auth_3d_id.set_pos(auth_3d_test_task->pos ? 1 : 0); if (frame_changed) { auth_3d_test_task->auth_3d_id.set_req_frame(frame); frame_changed = false; diff --git a/src/ReDIVA/data_test/auth_3d_test.hpp b/src/ReDIVA/data_test/auth_3d_test.hpp index 27c22c74..9a436e3c 100644 --- a/src/ReDIVA/data_test/auth_3d_test.hpp +++ b/src/ReDIVA/data_test/auth_3d_test.hpp @@ -22,6 +22,7 @@ public: int32_t auth_3d_uid; bool repeat; bool left_right_reverse; + bool pos; bool field_1E3; int32_t field_1E4; bool field_1E8; diff --git a/src/ReDIVA/data_test/stage_test.cpp b/src/ReDIVA/data_test/stage_test.cpp index 4450cc36..fde9a2bf 100644 --- a/src/ReDIVA/data_test/stage_test.cpp +++ b/src/ReDIVA/data_test/stage_test.cpp @@ -133,12 +133,12 @@ DtwStg::DtwStg() : Shell(0) { //dw::List::sub_1402F9930(this->ns->list, 30); ns->list->hovered_item = 0; - ns->list->selected_item = 0; + ns->list->ResetSetSelectedItem(0); ns->AddSelectionListener(new dw::SelectionListenerOnHook(DtwStg::StageCallback)); //dw::List::sub_1402F9930(this->stage->list, 30); stage->list->hovered_item = 0; - stage->list->selected_item = 0; + stage->list->ResetSetSelectedItem(0); stage->AddSelectionListener(new dw::SelectionListenerOnHook(DtwStg::StageCallback)); stage_display = new dw::Button(this, WIDGET_CHECKBOX); @@ -444,6 +444,11 @@ bool dtm_stg_unload() { } void dtm_stg_free() { + if (dtw_stg) { + delete dtw_stg; + dtw_stg = 0; + } + if (dtm_stg) { delete dtm_stg; dtm_stg = 0; @@ -451,25 +456,21 @@ void dtm_stg_free() { } void dtw_stg_init() { - dtw_stg = new DtwStg; + if (!dtw_stg) + dtw_stg = new DtwStg; dtw_stg->Disp(); } void dtw_stg_load(bool hide) { - dtw_stg->SetDisp(!hide); + dtw_stg_init(); + if (hide) + dtw_stg->SetDisp(false); } void dtw_stg_unload() { dtw_stg->Hide(); } -void dtw_stg_free() { - if (dtw_stg) { - delete dtw_stg; - dtw_stg = 0; - } -} - static int stage_test_stage_pv_quicksort_compare_func(void const* src1, void const* src2) { int32_t pv1 = ((stage_test_stage_pv*)src1)->pv_id; int32_t pv2 = ((stage_test_stage_pv*)src2)->pv_id; diff --git a/src/ReDIVA/data_test/stage_test.hpp b/src/ReDIVA/data_test/stage_test.hpp index da201169..0bd98a53 100644 --- a/src/ReDIVA/data_test/stage_test.hpp +++ b/src/ReDIVA/data_test/stage_test.hpp @@ -65,4 +65,3 @@ extern void dtm_stg_free(); extern void dtw_stg_init(); extern void dtw_stg_load(bool hide); extern void dtw_stg_unload(); -extern void dtw_stg_free(); diff --git a/src/ReDIVA/dw.cpp b/src/ReDIVA/dw.cpp index d57951da..c8f88681 100644 --- a/src/ReDIVA/dw.cpp +++ b/src/ReDIVA/dw.cpp @@ -6,6 +6,122 @@ #include "dw.hpp" #include "imgui_helper.hpp" +namespace dw_gui_detail { + struct Display { + /*dw::Shell* field_8; + dw::Menu* field_10; + dw::Widget* field_18; + dw::Widget* field_20; + dw::Widget* field_28; + dw::Widget* field_30; + dw::Shell* field_38; + char field_40; + char field_41;*/ + std::vector shells; + /*std::vector menus; + struc_748 field_78; + struc_748 field_90;*/ + std::vector free_widgets; + /*struc_751 field_C0; + int field_F4; + int field_F8; + int field_FC; + int field_100; + int field_104; + int field_108; + int field_10C; + int field_110; + int field_114; + __int64 field_118; + vec2 field_120; + float_t field_128; + dw::DragBoundsControl* field_130; + std::string name; + dw_gui_detail::Display::RootKeySelection root_key_selection;*/ + + Display(); + ~Display(); + + void AddShell(dw::Shell* value); + void CheckShells(); + void Ctrl(); + void Draw(); + void FreeWidgets(); + void RemoveShell(dw::Shell* value); + }; +} + +struct dw_gui_colors { + vec4u8 background; + vec4u8 foreground; + vec4u8 selection_background; + vec4u8 selection_foreground; + vec4u8 selection_inactive_background; + vec4u8 selection_inactive_foreground; + vec4u8 disable_background; + vec4u8 disable_foreground; + vec4u8 title_background; + vec4u8 title_foreground; + vec4u8 title_inactive_background; + vec4u8 title_inactive_foreground; + vec4u8 active_border_color; + vec4u8 inactive_border_color; + vec4u8 focus_border_color; + vec4u8 border_color; + vec4u8 border_light_color; + vec4u8 border_dark_color; + vec4u8 popup_background; + vec4u8 popup_foreground; + vec4u8 popup_selection_background; + vec4u8 popup_selection_foreground; + vec4u8 menu_background; + vec4u8 menu_foreground; + vec4u8 menu_selection_background; + vec4u8 menu_selection_foreground; + vec4u8 button_background; + vec4u8 button_foreground; + vec4u8 button_disable_background; + vec4u8 button_disable_foreground; +}; + +static dw_gui_colors dw_gui_colors_default = { + { 0xFF, 0xFF, 0xFF, 0xFF }, + { 0x00, 0x00, 0x00, 0xFF }, + { 0x00, 0x00, 0x80, 0xFF }, + { 0xFF, 0xFF, 0xFF, 0xFF }, + { 0xC0, 0xC0, 0xC0, 0xFF }, + { 0xFF, 0xFF, 0xFF, 0xFF }, + { 0xC0, 0xC0, 0xC0, 0xFF }, + { 0x80, 0x80, 0x80, 0xFF }, + { 0x00, 0x00, 0x80, 0xFF }, + { 0xFF, 0xFF, 0xFF, 0xFF }, + { 0xC0, 0xC0, 0xC0, 0xFF }, + { 0x80, 0x80, 0x80, 0xFF }, + { 0xC0, 0xC0, 0xC0, 0xFF }, + { 0xC0, 0xC0, 0xC0, 0xFF }, + { 0xFF, 0x00, 0x00, 0xFF }, + { 0xC0, 0xC0, 0xC0, 0xFF }, + { 0xE0, 0xE0, 0xE0, 0xFF }, + { 0x80, 0x80, 0x80, 0xFF }, + { 0xFF, 0xFF, 0xFF, 0xFF }, + { 0x00, 0x00, 0x00, 0xFF }, + { 0x00, 0x00, 0x80, 0xFF }, + { 0xFF, 0xFF, 0xFF, 0xFF }, + { 0xC0, 0xC0, 0xC0, 0xFF }, + { 0x00, 0x00, 0x00, 0xFF }, + { 0x00, 0x00, 0x80, 0xFF }, + { 0xFF, 0xFF, 0xFF, 0xFF }, + { 0xC0, 0xC0, 0xC0, 0xFF }, + { 0x00, 0x00, 0x00, 0xFF }, + { 0xF0, 0xF0, 0xF0, 0xFF }, + { 0x80, 0x80, 0x80, 0xFF }, +}; + +dw_gui_detail::Display* dw_gui_detail_display; + +static bool dw_gui_get_ctrl(); +static bool dw_gui_get_disp(); + namespace dw { SelectionListener::SelectionListener() { @@ -22,7 +138,15 @@ namespace dw { SelectionAdapter::~SelectionAdapter() { } - + + void SelectionAdapter::Field_8(Widget* data) { + + } + + void SelectionAdapter::Field_10(Widget* data) { + + } + SelectionListenerOnHook::SelectionListenerOnHook() : callback() { } @@ -35,7 +159,12 @@ namespace dw { } - Widget::Widget(Widget* parent, Flags flags) : callback_data(), parent() { + void SelectionListenerOnHook::Field_8(Widget* data) { + callback(data); + } + + Widget::Widget(Widget* parent, Flags flags) : free(), + callback_data(), free_callback(), parent() { this->flags = flags; } @@ -67,10 +196,28 @@ namespace dw { return position; } + void Widget::Free() { + if (free) + return; + + Reset(); + if (free_callback) + free_callback(this); + free = 1; + + if (dw_gui_detail_display) + dw_gui_detail_display->free_widgets.push_back(this); + } + void Widget::SetName(std::string&& str) { SetName(str); } + void Widget::UpdateDraw() { + //sub_140302800(qword_1411900C8); + Draw(); + } + Control::Control(Composite* parent, Flags flags) : Widget(parent, flags), parent_comp(), parent_shell()/*, parent_menu()*/{ parent_comp = parent; @@ -105,8 +252,49 @@ namespace dw { ImGui::Text(name.c_str()); } - Scrollable::Scrollable(Composite* parent, Flags flags) : Control(parent, flags) { + ScrollBar::ScrollBar(Control* parent, Widget::Flags flags) : Widget(parent, flags), + value(), min(), field_A0(), field_A5(), field_A6() { + field_68 = parent; + max = 100.0f; + field_94 = 10.0f; + step = 1.0f; + step_fast = 10.0f; + round = true; + SetSize({ 8.0f, 8.0f }); + } + ScrollBar::~ScrollBar() { + + } + + void ScrollBar::Draw() { + + } + + void ScrollBar::SetSize(vec2 value) { + size = value; + } + + void ScrollBar::SetParams(float_t value, float_t min, + float_t max, float_t a5, float_t step, float_t step_fast) { + this->value = value; + this->field_94 = a5; + this->min = min; + this->step_fast = step_fast; + this->max = max; + this->step = step; + } + + Scrollable::Scrollable(Composite* parent, Flags flags) : Control(parent, flags), h_bar(), v_bar() { + if (flags & WIDGET_SCROLL_H) { + h_bar = new ScrollBar(parent, WIDGET_SCROLL_H); + h_bar->SetName("h_bar"); + } + + if (flags & WIDGET_SCROLL_V) { + v_bar = new ScrollBar(parent, WIDGET_SCROLL_V); + v_bar->SetName("v_bar"); + } } Scrollable::~Scrollable() { @@ -114,7 +302,8 @@ namespace dw { } void Scrollable::Draw() { - + if (v_bar) + v_bar->UpdateDraw(); } void Scrollable::Reset() { @@ -137,11 +326,11 @@ namespace dw { } - vec2 FillLayout::GetSize(dw::Composite* comp) { + vec2 FillLayout::GetSize(Composite* comp) { return comp->size; } - void FillLayout::SetSize(dw::Composite* comp) { + void FillLayout::SetSize(Composite* comp) { const vec2 position = comp->position; const vec2 size = comp->size; for (Control* i : comp->controls) { @@ -158,11 +347,11 @@ namespace dw { } - vec2 GraphLayout::GetSize(dw::Composite* comp) { + vec2 GraphLayout::GetSize(Composite* comp) { return comp->size; } - void GraphLayout::SetSize(dw::Composite* comp) { + void GraphLayout::SetSize(Composite* comp) { const vec2 position = comp->position; const vec2 size = comp->size; for (Control* i : comp->controls) { @@ -182,11 +371,11 @@ namespace dw { } - vec2 GridLayout::GetSize(dw::Composite* comp) { + vec2 GridLayout::GetSize(Composite* comp) { return comp->size; } - void GridLayout::SetSize(dw::Composite* comp) { + void GridLayout::SetSize(Composite* comp) { const vec2 position = comp->position; const vec2 size = comp->size; for (Control* i : comp->controls) { @@ -204,11 +393,11 @@ namespace dw { } - vec2 RowLayout::GetSize(dw::Composite* comp) { + vec2 RowLayout::GetSize(Composite* comp) { return comp->size; } - void RowLayout::SetSize(dw::Composite* comp) { + void RowLayout::SetSize(Composite* comp) { const vec2 position = comp->position; const vec2 size = comp->size; for (Control* i : comp->controls) { @@ -232,13 +421,13 @@ namespace dw { void Composite::Reset() { //for (Control* i : controls) - //dw::Widget::sub_1402ECDE0(i); + //Widget::sub_1402ECDE0(i); controls.clear(); Scrollable::Reset(); } - void Composite::SetLayout(dw::Layout* value) { + void Composite::SetLayout(Layout* value) { layout = value; } @@ -251,8 +440,10 @@ namespace dw { } void Button::Draw() { - if (flags & WIDGET_CHECKBOX) - ImGui::Checkbox(name.c_str(), &value); + if (flags & WIDGET_CHECKBOX) { + if (ImGui::Checkbox(name.c_str(), &value) && callback) + callback(this); + } else if (flags & WIDGET_RADIOBUTTON) { if (ImGui::RadioButton(name.c_str(), value)) { if (callback) @@ -261,7 +452,8 @@ namespace dw { } } else - ImGui::Button(name.c_str()); + if (ImGui::Button(name.c_str()) && callback) + callback(this); } void Button::SetValue(bool value) { @@ -276,8 +468,44 @@ namespace dw { } } - Shell::Shell(Composite* parent, Flags flags) : Composite(parent, flags), disp() { + ShellCloseButton::ShellCloseButton(Shell* parent) : Button(parent) { + SetSize({ 14.0f, 14.0f }); + SetName("Close Box"); + callback = Callback; + //field_100 = 0; + //field_104 = 4; + } + ShellCloseButton::~ShellCloseButton() { + + } + + void ShellCloseButton::Draw() { + + } + + void ShellCloseButton::Callback(Widget* data) { + ShellCloseButton* close_button = dynamic_cast(data); + if (close_button) + close_button->parent_shell->Hide(); + } + + Shell::Shell(Shell* parent, Flags flags) : Composite(parent, flags), + disp(), disp_callback(), hide_callback(), destroy(), close_button() { + parent_shell = this; + + if (flags & WIDGET_CLOSE_BUTTON) { + close_button = new ShellCloseButton(this); + if (controls.size()) + controls.pop_back(); + } + + if (parent) { + parent_comp = parent; + parent->children.push_back(this); + } + + dw_gui_detail_display->shells.push_back(this); } Shell::~Shell() { @@ -288,7 +516,45 @@ namespace dw { if (!GetDisp()) return; - Composite::Draw(); + if (ImGui::Begin(name.c_str())) { + Composite::Draw(); + ImGui::End(); + } + } + + void Shell::Reset() { + std::vector vec; + vec.assign(children.begin(), children.end()); + children.clear(); + + for (Widget* i : vec) + i->Free(); + + /*for (Menu* i : menus) + i->Free(); + menus.clear();*/ + + if (close_button) { + close_button->Free(); + close_button = 0; + } + + if (parent_comp) { + Shell* parent_shell = dynamic_cast(parent_comp); + if (parent_shell) { + auto i = parent_shell->children.begin(); + auto i_end = parent_shell->children.end(); + while (i != i_end) + if (*i == this) { + parent_shell->children.erase(i); + break; + } + } + } + + dw_gui_detail_display->RemoveShell(this); + + Composite::Reset(); } void Shell::Hide() { @@ -297,6 +563,9 @@ namespace dw { void Shell::Disp() { SetDisp(true); + dw_gui_detail_display->AddShell(this); + //dw_gui_detail_display->field_38 = this; + //dw_gui_detail_display->field_40 = true; } bool Shell::GetDisp() { @@ -308,6 +577,18 @@ namespace dw { return; disp = value; + if (disp) { + dw_gui_detail_display->AddShell(this); + //dw_gui_detail_display->field_38 = this; + //dw_gui_detail_display->field_40 = true; + if (disp_callback) + disp_callback(this); + } + else { + //dw_gui_detail_display->field_41 = true; + if (hide_callback) + hide_callback(this); + } } List::List(Composite* parent, Flags flags) : Scrollable(parent, flags) { @@ -348,6 +629,27 @@ namespace dw { return items[index]; } + void List::ResetSelectedItem() { + if (flags & WIDGET_4) + selected_item = -1; + else + for (int32_t& i : selections) + i = 0; + } + + void List::ResetSetSelectedItem(size_t index) { + ResetSelectedItem(); + SetSelectedItem(index); + } + + void List::SetSelectedItem(size_t index) { + if (index < items.size()) + if (flags & WIDGET_4) + selected_item = index; + else + selections[index] = 1; + } + ListBox::ListBox(Composite* parent, Flags flags) : Composite(parent, flags), list() { list = new List(parent, flags); } @@ -357,7 +659,46 @@ namespace dw { } void ListBox::Draw() { + bool window_focus = false; + std::vector& items = list->items; + size_t hovered_item = list->selected_item; + size_t selected_item = list->selected_item; + ImGui::GetContentRegionAvailSetNextItemWidth(); + ImGui::PushID(this); + if (ImGui::BeginCombo("##", selected_item != -1 + && items.size() ? items[selected_item].c_str() : "", 0)) { + for (std::string& i : items) { + size_t item = &i - items.data(); + + ImGui::PushID(&i); + if (ImGui::Selectable(i.c_str(), selected_item == item) + || ImGui::ItemKeyPressed(ImGuiKey_Enter) + || (ImGui::IsItemFocused() && selected_item != item)) { + selected_item = item; + } + + if (ImGui::IsItemHovered()) + hovered_item = item; + ImGui::PopID(); + + if (selected_item == item) + ImGui::SetItemDefaultFocus(); + } + + window_focus |= true; + ImGui::EndCombo(); + } + + if (list->hovered_item != hovered_item) + list->hovered_item = hovered_item; + + if (list->selected_item != selected_item) { + list->selected_item = selected_item; + for (SelectionListener*& i : list->selection_listeners) + i->Field_8(this); + } + ImGui::PopID(); } void ListBox::Reset() { @@ -383,4 +724,181 @@ namespace dw { std::string ListBox::GetItem(size_t index) const { return list->GetItem(index); } + + Slider::Slider(Composite* parent, Widget::Flags flags) : Control(parent, flags) { + format = "%f"; + scroll_bar = new ScrollBar(this, (Widget::Flags)(flags & (WIDGET_SCROLL_H | WIDGET_SCROLL_V))); + scroll_bar->parent = this; + } + + Slider::~Slider() { + delete scroll_bar; + } + + void Slider::Draw() { + ScrollBar* scroll_bar = this->scroll_bar; + if (ImGui::ColumnSliderFloatButton(name.c_str(), &scroll_bar->value, + scroll_bar->step, scroll_bar->min, scroll_bar->max, scroll_bar->step_fast, format, 0)) + for (SelectionListener*& i : selection_listeners) + i->Field_8(this); + } + + void Slider::Reset() { + if (scroll_bar) { + scroll_bar->Free(); + scroll_bar = 0; + } + + Control::Reset(); + } + + void Slider::SetSize(vec2 value) { + Widget::SetSize(value); + scroll_bar->position.x = value.x - scroll_bar->size.x; + scroll_bar->position.y = 0.0f; + } + + void Slider::AddSelectionListener(SelectionListener* value) { + selection_listeners.push_back(value); + } + + Slider* Slider::make(Composite* parent, Widget::Flags flags, + float_t x, float_t y, float_t width, float_t height, const char* name) { + Slider* slider = new Slider(parent, flags); + ScrollBar* scroll_bar = slider->scroll_bar; + slider->SetName(name); + scroll_bar->SetName("slider's bar"); + scroll_bar->SetSize({ width, height }); + /*sub_140302810(qword_1411900C8, &slider->font); + std::string v13 = slider->GetName(); + float_t v15; + float_t v17; + if (flags & WIDGET_100) { + vec2 v21; + vec2 v22; + sub_140302A70(qword_1411900C8, &v22, v13); + sub_140302A70(qword_1411900C8, &v21, "0000"); + scroll_bar->position.x = v21.x + v22.x; + scroll_bar->position.y = 0.0f; + v17 = v21.x + v22.x + scroll_bar->size.x ; + v15 = p_dw__Font::GetFontGlyphHeight(&slider->font); + } + else { + vec2 v21; + vec2 v22; + sub_140302A70(qword_1411900C8, &v21, v13); + sub_140302A70(qword_1411900C8, &v22, "0000"); + v17 = p_dw__Font::GetFontGlyphWidth(&slider->font); + v15 = v21.x + v22.x + scroll_bar->size.y; + }*/ + slider->position.x = x; + slider->position.y = y; + //slider->SetSize({ v17, v15 }); + return slider; + } +} + +void dw_gui_detail_display_init() { + if (!dw_gui_detail_display) + dw_gui_detail_display = new dw_gui_detail::Display; +} + +void dw_gui_detail_display_free() { + if (dw_gui_detail_display) { + delete dw_gui_detail_display; + dw_gui_detail_display = 0; + } +} + +void dw_gui_ctrl_disp() { + if (dw_gui_get_ctrl()) + dw_gui_detail_display->Ctrl(); + if (dw_gui_get_disp()) + dw_gui_detail_display->Draw(); +}; + +dw_gui_detail::Display::Display() { + +} + +dw_gui_detail::Display::~Display() { + +} + +void dw_gui_detail::Display::AddShell(dw::Shell* value) { + if (!value) + return; + + for (dw::Shell* i : shells) + if (i == value) + return; + + shells.push_back(value); +} + +void dw_gui_detail::Display::CheckShells() { + std::vector vec; + + for (dw::Shell* i : shells) + if (i->destroy) + vec.push_back(i); + + if (vec.size()) { + for (dw::Shell* i : vec) + i->Free(); + //field_41 = true; + } +} + +void dw_gui_detail::Display::Ctrl() { + CheckShells(); + FreeWidgets(); +} + +void dw_gui_detail::Display::Draw() { + for (dw::Shell* i : shells) + if (i->GetDisp()) + i->UpdateDraw(); +} + +void dw_gui_detail::Display::FreeWidgets() { + for (auto& i : free_widgets) { + delete i; + /*if (field_28 == i) + field_28 = 0; + if (field_30 == i) + field_30 = 0;*/ + } + free_widgets.clear(); +} + +void dw_gui_detail::Display::RemoveShell(dw::Shell* value) { + auto i = shells.begin(); + auto i_end = shells.end(); + while (i != i_end) + if (*i == value) { + shells.erase(i); + break; + } + + /*if (field_8 == value) { + field_8 = 0; + field_41 = true; + } + + if (field_18 == value) + field_18 = 0; + + if (field_20 == value) + field_20 = 0;*/ +} + +static bool dw_gui_get_ctrl() { + //return false; + return true; +} + +static bool dw_gui_get_disp() { + //return false; + return true; } diff --git a/src/ReDIVA/dw.hpp b/src/ReDIVA/dw.hpp index de9901c4..9e88c9a9 100644 --- a/src/ReDIVA/dw.hpp +++ b/src/ReDIVA/dw.hpp @@ -15,11 +15,17 @@ namespace dw { typedef void(*Callback)(Widget* data); enum Flags { - WIDGET_RADIOBUTTON = 0x10, - WIDGET_CHECKBOX = 0x20, - WIDGET_CLOSE_BUTTON = 0x40, + WIDGET_4 = 0x004, + WIDGET_RADIOBUTTON = 0x010, + WIDGET_CHECKBOX = 0x020, + WIDGET_CLOSE_BUTTON = 0x040, + WIDGET_SCROLL_H = 0x100, + WIDGET_SCROLL_V = 0x200, + WIDGET_800 = 0x800, }; + bool free; + union { int8_t i8; uint8_t u8; @@ -32,6 +38,7 @@ namespace dw { void* v64; } callback_data; + Callback free_callback; std::string name; vec2 position; vec2 size; @@ -48,19 +55,27 @@ namespace dw { virtual void SetSize(vec2 value); virtual vec2 GetPos(); + void Free(); void SetName(std::string&& str); + void UpdateDraw(); }; class SelectionListener { public: SelectionListener(); virtual ~SelectionListener(); + + virtual void Field_8(Widget* data) = 0; + virtual void Field_10(Widget* data) = 0; }; class SelectionAdapter : public SelectionListener { public: SelectionAdapter(); virtual ~SelectionAdapter() override; + + virtual void Field_8(Widget* data) override; + virtual void Field_10(Widget* data) override; }; class SelectionListenerOnHook : public SelectionAdapter { @@ -70,6 +85,8 @@ namespace dw { SelectionListenerOnHook(); SelectionListenerOnHook(Widget::Callback callback); virtual ~SelectionListenerOnHook() override; + + virtual void Field_8(Widget* data) override; }; class Composite; @@ -96,8 +113,60 @@ namespace dw { virtual void Draw() override; }; + class ScrollBar : public Widget { + public: + Control* field_68; + std::vector selection_listeners; + float_t value; + float_t min; + float_t max; + float_t field_94; + float_t step; + float_t step_fast; + int field_A0; + bool round; + char field_A5; + char field_A6; + __int64 field_A8; + __int64 field_B0; + __int64 field_B8; + __int64 field_C0; + __int64 field_C8; + __int64 field_D0; + __int64 field_D8; + __int64 field_E0; + __int64 field_E8; + __int64 field_F0; + __int64 field_F8; + __int64 field_100; + __int64 field_108; + __int64 field_110; + __int64 field_118; + __int64 field_120; + __int64 field_128; + __int64 field_130; + __int64 field_138; + __int64 field_140; + __int64 field_148; + __int64 field_150; + __int64 field_158; + __int64 field_160; + + ScrollBar(Control* parent, Widget::Flags flags); + virtual ~ScrollBar() override; + + virtual void Draw() override; + virtual void SetSize(vec2 value) override; + + void SetParams(float_t value, float_t min, float_t max, + float_t a5, float_t step, float_t step_fast); + }; + class Scrollable : public Control { public: + ScrollBar* h_bar; + ScrollBar* v_bar; + Scrollable(Composite* parent = 0, Flags flags = (Flags)0); virtual ~Scrollable() override; @@ -110,8 +179,8 @@ namespace dw { Layout(); virtual ~Layout(); - virtual vec2 GetSize(dw::Composite* comp) = 0; - virtual void SetSize(dw::Composite* comp) = 0; + virtual vec2 GetSize(Composite* comp) = 0; + virtual void SetSize(Composite* comp) = 0; }; class FillLayout : public Layout { @@ -121,8 +190,8 @@ namespace dw { FillLayout(int32_t a2 = 512); virtual ~FillLayout() override; - virtual vec2 GetSize(dw::Composite* comp) override; - virtual void SetSize(dw::Composite* comp) override; + virtual vec2 GetSize(Composite* comp) override; + virtual void SetSize(Composite* comp) override; }; class GraphLayout : public Layout { @@ -132,8 +201,8 @@ namespace dw { GraphLayout(int32_t a2 = 512); virtual ~GraphLayout() override; - virtual vec2 GetSize(dw::Composite* comp) override; - virtual void SetSize(dw::Composite* comp) override; + virtual vec2 GetSize(Composite* comp) override; + virtual void SetSize(Composite* comp) override; }; class GridLayout : public Layout { @@ -152,8 +221,8 @@ namespace dw { GridLayout(size_t a2 = 2); virtual ~GridLayout() override; - virtual vec2 GetSize(dw::Composite* comp) override; - virtual void SetSize(dw::Composite* comp) override; + virtual vec2 GetSize(Composite* comp) override; + virtual void SetSize(Composite* comp) override; }; class RowLayout : public Layout { @@ -164,14 +233,14 @@ namespace dw { RowLayout(int32_t a2 = 256); virtual ~RowLayout() override; - virtual vec2 GetSize(dw::Composite* comp) override; - virtual void SetSize(dw::Composite* comp) override; + virtual vec2 GetSize(Composite* comp) override; + virtual void SetSize(Composite* comp) override; }; class Composite : public Scrollable { public: - dw::Layout* layout; - std::vector controls; + Layout* layout; + std::vector controls; Composite(Composite* parent = 0, Flags flags = (Flags)0); virtual ~Composite() override; @@ -179,7 +248,7 @@ namespace dw { virtual void Draw() override; virtual void Reset() override; - void SetLayout(dw::Layout* value); + void SetLayout(Layout* value); }; class Button : public Control { @@ -196,15 +265,34 @@ namespace dw { void SetValue(bool value); }; + class ShellCloseButton : public Button { + public: + ShellCloseButton(dw::Shell* parent); + virtual ~ShellCloseButton() override; + + virtual void Draw() override; + + static void Callback(dw::Widget* data); + }; + class Shell : public Composite { public: - bool disp; + typedef void(*Callback)(Shell* data); - Shell(Composite* parent = 0, Flags flags - = (dw::Widget::Flags)(0x480 | WIDGET_CLOSE_BUTTON | WIDGET_CHECKBOX | WIDGET_RADIOBUTTON)); + bool disp; + Callback disp_callback; + Callback hide_callback; + bool destroy; + ShellCloseButton* close_button; + std::vector children; + //std::vector menus; + + Shell(Shell* parent = 0, Flags flags + = (Widget::Flags)(0x480 | WIDGET_CLOSE_BUTTON | WIDGET_CHECKBOX | WIDGET_RADIOBUTTON)); virtual ~Shell() override; virtual void Draw() override; + virtual void Reset() override; virtual void Hide(); @@ -216,6 +304,7 @@ namespace dw { class List : public Scrollable { public: std::vector items; + std::vector selections; size_t hovered_item; size_t selected_item; std::vector selection_listeners; @@ -231,11 +320,14 @@ namespace dw { void AddSelectionListener(SelectionListener* value); void ClearItems(); std::string GetItem(size_t index) const; + void ResetSelectedItem(); + void ResetSetSelectedItem(size_t index); + void SetSelectedItem(size_t index); }; class ListBox : public Composite { public: - dw::List* list; + List* list; ListBox(Composite* parent = 0, Flags flags = (Flags)0x204); virtual ~ListBox() override; @@ -249,4 +341,28 @@ namespace dw { void ClearItems(); std::string GetItem(size_t index) const; }; + + class Slider : public Control { + public: + const char* format; + std::vector selection_listeners; + ScrollBar* scroll_bar; + + Slider(Composite* parent, Widget::Flags flags); + virtual ~Slider(); + + virtual void Draw() override; + virtual void Reset() override; + virtual void SetSize(vec2 value) override; + + void AddSelectionListener(SelectionListener* value); + + static Slider* make(Composite* parent, Widget::Flags flags, + float_t x, float_t y, float_t width, float_t height, const char* name); + }; } + +extern void dw_gui_detail_display_init(); +extern void dw_gui_detail_display_free(); + +extern void dw_gui_ctrl_disp(); diff --git a/src/ReDIVA/game_state.cpp b/src/ReDIVA/game_state.cpp index 7b02ecc1..0a0faa70 100644 --- a/src/ReDIVA/game_state.cpp +++ b/src/ReDIVA/game_state.cpp @@ -5,9 +5,12 @@ #include "game_state.hpp" #include "../CRE/rob/rob.hpp" +#include "../CRE/auth_2d.hpp" +#include "../CRE/auth_3d.hpp" #include "../CRE/clear_color.hpp" #include "../CRE/pv_db.hpp" #include "../CRE/task.hpp" +#include "data_test/auth_2d_test.hpp" #include "data_test/auth_3d_test.hpp" #include "data_test/glitter_test.hpp" #include "data_test/motion_test.hpp" @@ -974,7 +977,7 @@ bool GameState::AppError::Dest() { bool SubGameState::DataInitialize::Init() { task_data_init_add_task(); task_auth_3d_add_task(); - //task_auth_2d_add_task(); + aet_manager_add_task(); //no_good_add_task(); return true; } @@ -1293,7 +1296,7 @@ bool SubGameState::DataTestStg::Ctrl() { bool SubGameState::DataTestStg::Dest() { clear_color = { 0x00, 0x00, 0x00, 0xFF }; - dtw_stg_free(); + dtw_stg->Hide(); dtm_stg->DelTask(); return true; } @@ -1341,6 +1344,8 @@ bool SubGameState::DataTestSpr::Dest() { } bool SubGameState::DataTestAet::Init() { + clear_color = { 0x60, 0x60, 0x60, 0xFF }; + dtm_aet_load(); return true; } @@ -1349,6 +1354,8 @@ bool SubGameState::DataTestAet::Ctrl() { } bool SubGameState::DataTestAet::Dest() { + clear_color = { 0x00, 0x00, 0x00, 0xFF }; + dtm_aet_unload(); return true; } diff --git a/src/ReDIVA/render.cpp b/src/ReDIVA/render.cpp index c4c2b17d..b9f24236 100644 --- a/src/ReDIVA/render.cpp +++ b/src/ReDIVA/render.cpp @@ -11,6 +11,8 @@ #include "../CRE/rob/rob.hpp" #include "../CRE/rob/motion.hpp" #include "../CRE/rob/skin_param.hpp" +#include "../CRE/auth_2d.hpp" +#include "../CRE/auth_3d.hpp" #include "../CRE/camera.hpp" #include "../CRE/clear_color.hpp" #include "../CRE/data.hpp" @@ -42,6 +44,7 @@ #include "../KKdLib/timer.hpp" #include "../KKdLib/sort.hpp" #include "../KKdLib/str_utils.hpp" +#include "data_test/auth_2d_test.hpp" #include "data_test/auth_3d_test.hpp" #include "data_test/glitter_test.hpp" #include "data_test/stage_test.hpp" @@ -435,6 +438,8 @@ static bool render_init(render_init_struct* ris) { width = (int32_t)(width / 2.0f); height = (int32_t)(height / 2.0f); + res_window_set(RESOLUTION_MODE_HD); + #if BAKE_PNG || BAKE_VIDEO width = 1920; height = 1080; @@ -531,10 +536,12 @@ static render_context* render_context_load() { render_texture_data_init(); data_struct* aft_data = &data_list[DATA_AFT]; + aet_database* aft_aet_db = &aft_data->data_ft.aet_db; auth_3d_database* aft_auth_3d_db = &aft_data->data_ft.auth_3d_db; bone_database* aft_bone_data = &aft_data->data_ft.bone_data; motion_database* aft_mot_db = &aft_data->data_ft.mot_db; object_database* aft_obj_db = &aft_data->data_ft.obj_db; + sprite_database* aft_spr_db = &aft_data->data_ft.spr_db; texture_database* aft_tex_db = &aft_data->data_ft.tex_db; stage_database* aft_stage_data = &aft_data->data_ft.stage_data; @@ -559,19 +566,23 @@ static render_context* render_context_load() { rob_init(); task_wind_init(); + aet_manager_init(); + sprite_manager_init(); auth_3d_data_init(); auth_3d_test_task_init(); task_auth_3d_init(); task_stage_init(); - dtm_stg_init(); task_stage_modern_init(); light_param_data_storage_data_init(); task_effect_init(); task_pv_db_init(); Glitter::glt_particle_manager_init(); + dw_gui_detail_display_init(); + auth_3d_test_window_init(); - dtw_stg_init(); + dtm_aet_init(); + dtm_stg_init(); task_data_test_glitter_particle_init(); Glitter::glt_particle_manager->bone_data = aft_bone_data; @@ -835,7 +846,8 @@ static render_context* render_context_load() { rctx->post_process.init_fbo(internal_3d_res.x, internal_3d_res.y, internal_2d_res.x, internal_2d_res.y, width, height); - rctx->render_manager.resize(internal_2d_res.x, internal_2d_res.y); + rctx->render_manager.resize(width, height); + rctx->litproj->resize(internal_3d_res.x, internal_3d_res.y); render_resize_fb(rctx, true); @@ -852,7 +864,11 @@ static render_context* render_context_load() { hand_item_handler_data_init(); //rob_sleeve_data_init(); - sprite_manager_init(); + + aet_manager_add_aet_sets(aft_aet_db, false); + sprite_manager_add_spr_sets(aft_spr_db, false); + + sprite_manager_set_res((double_t)width / (double_t)height, width, height); render_timer->reset(); for (int32_t i = 0; i < 30; i++) { @@ -869,8 +885,9 @@ static render_context* render_context_load() { camera* cam = rctx->camera; + resolution_struct* res_wind = res_window_get(); cam->initialize(aspect, internal_3d_res.x, internal_3d_res.y, - internal_2d_res.x, internal_2d_res.y); + res_wind->width, res_wind->height); //cam->set_position({ 1.35542f, 1.41634f, 1.27852f }); //cam->rotate({ -45.0, -32.5 }); //cam->set_position({ -6.67555f, 4.68882f, -3.67537f }); @@ -947,14 +964,16 @@ static void render_context_ctrl(render_context* rctx) { global_context_menu = true; lock_lock(imgui_context_lock); ImGui::SetCurrentContext(imgui_context); + dw_gui_ctrl_disp(); app::TaskWork_Window(); classes_process_imgui(classes, classes_count); lock_unlock(imgui_context_lock); if (old_width != width || old_height != height || old_scale_index != scale_index) { render_resize_fb(rctx, true); + resolution_struct* res_wind = res_window_get(); cam->set_res(internal_3d_res.x, internal_3d_res.y, - internal_2d_res.x, internal_2d_res.y); + res_wind->width, res_wind->height); } old_width = width; old_height = height; @@ -1001,7 +1020,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_AUTH_3D); + game_state_set_sub_game_state_next(SUB_GAME_STATE_DATA_TEST_AET); } else if (Input::IsKeyTapped(GLFW_KEY_F7)) game_state_set_game_state_next(GAME_STATE_TEST_MODE); @@ -1075,12 +1094,12 @@ static void render_context_disp(render_context* rctx) { int32_t screen_x_offset = (width - internal_2d_res.x) / 2 + (width - internal_2d_res.x) % 2; int32_t screen_y_offset = (height - internal_2d_res.y) / 2 + (width - internal_2d_res.x) % 2; glViewport(screen_x_offset, screen_y_offset, internal_2d_res.x, internal_2d_res.y); - rctx->post_process.screen_texture.bind(); + rctx->post_process.fbo_texture.bind(); classes_process_disp(classes, classes_count); gl_state_bind_framebuffer(0); if (rctx->render_manager.pass_sw[rndr::RND_PASSID_POSTPROCESS]) - fbo::blit(rctx->post_process.screen_texture.fbos[0], 0, + fbo::blit(rctx->post_process.fbo_texture.fbos[0], 0, 0, 0, width, height, 0, 0, width, height, GL_COLOR_BUFFER_BIT, GL_LINEAR); @@ -1111,6 +1130,7 @@ static void render_context_dispose(render_context* rctx) { //pv_game_data.DelTask(); Glitter::glt_particle_manager_del_task(); task_auth_3d_del_task(); + aet_manager_del_task(); task_pv_db_del_task(); app::TaskWork::Dest(); @@ -1124,17 +1144,24 @@ static void render_context_dispose(render_context* rctx) { sound_work_unload_farc("rom/sound/slide_se.farc"); sound_work_unload_farc("rom/sound/slide_long.farc"); + data_struct* aft_data = &data_list[DATA_AFT]; + aet_database* aft_aet_db = &aft_data->data_ft.aet_db; + sprite_database* aft_spr_db = &aft_data->data_ft.spr_db; + object_storage_unload_set(dbg_set_id); - //AetUnloadSet(26); - //SprUnloadSet(32); - //AetUnloadSet(35); - //SprUnloadSet(34); - //SprUnloadSet(4); - //SprUnloadSet(472); - //SprUnloadSet(43); + aet_manager_unload_set(26, aft_aet_db); + sprite_manager_unload_set(32, aft_spr_db); + aet_manager_unload_set(35, aft_aet_db); + sprite_manager_unload_set(34, aft_spr_db); + sprite_manager_unload_set(4, aft_spr_db); + sprite_manager_unload_set(472, aft_spr_db); + sprite_manager_unload_set(43, aft_spr_db); + + sprite_manager_remove_spr_sets(aft_spr_db, false); + aet_manager_remove_aet_sets(aft_aet_db, false); + hand_item_handler_data_free(); //rob_sleeve_data_free(); - sprite_manager_free(); //rob_chara_array_free_chara_id(0); render_timer->reset(); @@ -1153,19 +1180,23 @@ static void render_context_dispose(render_context* rctx) { light_param_data_storage::unload(); task_data_test_glitter_particle_free(); - dtw_stg_free(); + dtm_stg_free(); + dtm_aet_free(); auth_3d_test_window_free(); + dw_gui_detail_display_free(); + Glitter::glt_particle_manager_free(); task_pv_db_free(); task_effect_free(); light_param_data_storage_data_free(); task_stage_modern_free(); - dtm_stg_free(); task_stage_free(); task_auth_3d_free(); auth_3d_test_task_free(); auth_3d_data_free(); + sprite_manager_free(); + aet_manager_free(); task_wind_free(); rob_free(); @@ -1295,8 +1326,9 @@ static void render_resize_fb(render_context* rctx, bool change_fb) { if (fb_changed && change_fb) { rctx->post_process.init_fbo(internal_3d_res.x, internal_3d_res.y, internal_2d_res.x, internal_2d_res.y, width, height); - rctx->render_manager.resize(internal_2d_res.x, internal_2d_res.y); + rctx->render_manager.resize(width, height); rctx->litproj->resize(internal_3d_res.x, internal_3d_res.y); + sprite_manager_set_res((double_t)width / (double_t)height, width, height); } } diff --git a/src/ReDIVA/system_startup.cpp b/src/ReDIVA/system_startup.cpp index e5763fdc..f14afc6c 100644 --- a/src/ReDIVA/system_startup.cpp +++ b/src/ReDIVA/system_startup.cpp @@ -4,7 +4,9 @@ */ #include "system_startup.hpp" +#include "../CRE/auth_2d.hpp" #include "../CRE/mdata_manager.hpp" +#include "../CRE/sprite.hpp" #include "game_state.hpp" #include "pv_game.hpp" @@ -91,6 +93,12 @@ namespace system_startup_detail { mdata_manager_del_task(); return true; } + + void TaskSystemStartup::Disp() { + resolution_struct* res_wind = res_window_get(); + spr::put_sprite_rect({ 0.0f, 0.0f, (float_t)res_wind->width, (float_t)res_wind->height }, + res_wind->resolution_mode, spr::SPR_PRIO_25, { 0x00, 0x00, 0x00, 0xFF }, 0); + } } bool task_system_startup_add_task() { diff --git a/src/ReDIVA/system_startup.hpp b/src/ReDIVA/system_startup.hpp index 48ef3a44..fb9d1d98 100644 --- a/src/ReDIVA/system_startup.hpp +++ b/src/ReDIVA/system_startup.hpp @@ -19,6 +19,7 @@ namespace system_startup_detail { virtual bool Init() override; virtual bool Ctrl() override; virtual bool Dest() override; + virtual void Disp() override; }; }