diff --git a/src/DivaGL/DivaGL.vcxproj b/src/DivaGL/DivaGL.vcxproj index f25d01a..d08d388 100644 --- a/src/DivaGL/DivaGL.vcxproj +++ b/src/DivaGL/DivaGL.vcxproj @@ -135,6 +135,7 @@ del "$(SolutionDir)bin\$(TargetName).lib" + @@ -206,6 +207,7 @@ del "$(SolutionDir)bin\$(TargetName).lib" + diff --git a/src/DivaGL/auth_3d.cpp b/src/DivaGL/auth_3d.cpp index 25f9101..8a3b2c0 100644 --- a/src/DivaGL/auth_3d.cpp +++ b/src/DivaGL/auth_3d.cpp @@ -8,6 +8,7 @@ #include "light_param/fog.hpp" #include "mdl/disp_manager.hpp" #include "rob/rob.hpp" +#include "canonical_properties.hpp" #include "file_handler.hpp" #include "frame_rate_control.hpp" #include "render_context.hpp" @@ -510,30 +511,6 @@ struct auth_3d_material_list { uint64_t hash; }; -struct string_range { - char* begin; - char* end; -}; - -struct string_range_capacity { - string_range range; - char* capacity_end; -}; - -struct pair_string_range_string_range { - string_range key; - string_range value; -}; - -static_assert(sizeof(pair_string_range_string_range) == 0x20, "\"CanonicalProperties\" struct should have a size of 0x20"); - -struct CanonicalProperties { - prj::string data; - prj::vector key_value_pair_storage; -}; - -static_assert(sizeof(CanonicalProperties) == 0x38, "\"CanonicalProperties\" struct should have a size of 0x38"); - struct struc_8 { float_t max_frame; void* data; @@ -614,30 +591,22 @@ void (FASTCALL* auth_3d_data_unload_category)(const char* category_name) static auth_3d_data_struct* auth_3d_data = (auth_3d_data_struct*)0x0000000140EDA950; -static string_range* (FASTCALL* CanonicalProperties__GetValueStringRange)( - CanonicalProperties* CanProp, string_range str_rng) - = (string_range * (FASTCALL*)(CanonicalProperties * CanProp, string_range str_rng))0x00000001400AE4F0; -static prj::string* (FASTCALL* CanonicalProperties__GetValueString)( - CanonicalProperties* CanProp, prj::string* str, string_range str_rng) - = (prj::string * (FASTCALL*)(CanonicalProperties * CanProp, prj::string * str, string_range str_rng))0x00000001401AD640; static void(FASTCALL* auth_3d_rgba__free)(auth_3d_rgba* rgba) = (void(FASTCALL*)(auth_3d_rgba * rgba))0x00000001401B8900; static void (FASTCALL* auth_3d_rgba__ctrl)(auth_3d_rgba* rgba, float_t frame) = (void (FASTCALL*)(auth_3d_rgba * rgba, float_t frame))0x00000001401D4070; -static bool (FASTCALL* auth_3d_key__parse)(auth_3d_key* k, struc_8* a2, string_range_capacity str_rng_cap) -= (bool (FASTCALL*)(auth_3d_key * k, struc_8 * a2, string_range_capacity str_rng_cap))0x00000001401DB1A0; -static bool (FASTCALL* auth_3d_rgba__parse)(auth_3d_rgba* rgba, struc_8* a2, string_range_capacity str_rng_cap) - = (bool (FASTCALL*)(auth_3d_rgba * rgba, struc_8 * a2, string_range_capacity str_rng_cap))0x00000001401DB520; +static bool (FASTCALL* auth_3d_key__parse)(auth_3d_key* k, struc_8* a2, prj::string_range_capacity str_rng_cap) += (bool (FASTCALL*)(auth_3d_key * k, struc_8 * a2, prj::string_range_capacity str_rng_cap))0x00000001401DB1A0; +static bool (FASTCALL* auth_3d_rgba__parse)(auth_3d_rgba* rgba, struc_8* a2, prj::string_range_capacity str_rng_cap) + = (bool (FASTCALL*)(auth_3d_rgba * rgba, struc_8 * a2, prj::string_range_capacity str_rng_cap))0x00000001401DB520; static int32_t auth_3d_get_auth_3d_object_index(auth_3d* auth, object_info object_info, int32_t instance); static const mat4* auth_3d_get_auth_3d_object_mat(auth_3d* auth, size_t index); static const mat4* auth_3d_get_auth_3d_object_hrc_bone_mats(auth_3d* auth, size_t index); static int32_t auth_3d_get_auth_3d_object_hrc_index(auth_3d* auth, object_info obj_info, int32_t instance); static void auth_3d_material_list_ctrl(auth_3d_material_list* ml, float_t frame); -static bool auth_3d_material_list_parse(auth_3d_material_list* ml, struc_8* a2, string_range_capacity str_rng_cap); +static bool auth_3d_material_list_parse(auth_3d_material_list* ml, struc_8* a2, prj::string_range_capacity str_rng_cap); static void auth_3d_set_material_list(auth_3d* auth); -static prj::string string_init_CanonicalProperties_string_range(CanonicalProperties& CanProp, string_range str_rng); -static string_range_capacity string_range_capacity_init_char_ptr(string_range_capacity str_rng_cap, const char* str); auth_3d_id::auth_3d_id(int32_t uid) : id() { ((auth_3d_id * (FASTCALL*)(auth_3d_id * _this, int32_t uid))0x00000001401CDC80)(this, uid); @@ -1299,12 +1268,12 @@ HOOK(void, FASTCALL, auth_3d_curve__ctrl, 0x00000001401D4140, auth_3d_curve* c, } HOOK(bool, FASTCALL, auth_3d_curve_parse, 0x00000001401DA230, - auth_3d_curve* c, struc_8* a2, string_range_capacity str_rng_cap) { - string_range_capacity name = string_range_capacity_init_char_ptr(str_rng_cap, ".name"); - c->name.assign(string_init_CanonicalProperties_string_range(a2->CanProp, name.range)); + auth_3d_curve* c, struc_8* a2, prj::string_range_capacity str_rng_cap) { + prj::string_range_capacity name = prj::string_range_capacity(str_rng_cap, ".name"); + c->name.assign(a2->CanProp.GetValueString(name.range)); - string_range_capacity ml_str = string_range_capacity_init_char_ptr(str_rng_cap, ".ml"); - if (CanonicalProperties__GetValueStringRange(&a2->CanProp, ml_str.range)) { + prj::string_range_capacity ml_str = prj::string_range_capacity(str_rng_cap, ".ml"); + if (a2->CanProp.GetValue(ml_str.range)) { auth_3d_material_list* ml = (auth_3d_material_list*)_operator_new(sizeof(auth_3d_material_list)); memset(ml, 0, sizeof(auth_3d_material_list)); auth_3d_material_list_parse(ml, a2, ml_str); @@ -1313,7 +1282,7 @@ HOOK(bool, FASTCALL, auth_3d_curve_parse, 0x00000001401DA230, c->type = 1; } else { - string_range_capacity cv = string_range_capacity_init_char_ptr(str_rng_cap, ".cv"); + prj::string_range_capacity cv = prj::string_range_capacity(str_rng_cap, ".cv"); auth_3d_key__parse(&c->curve, a2, cv); c->type = 0; } @@ -1385,16 +1354,16 @@ static void auth_3d_material_list_ctrl(auth_3d_material_list* ml, float_t frame) auth_3d_rgba__ctrl(&ml->emission, frame); } -static bool auth_3d_material_list_parse(auth_3d_material_list* ml, struc_8* a2, string_range_capacity str_rng_cap) { +static bool auth_3d_material_list_parse(auth_3d_material_list* ml, struc_8* a2, prj::string_range_capacity str_rng_cap) { ml->flags = (auth_3d_material_list_flags)0; - string_range_capacity blend_color = string_range_capacity_init_char_ptr(str_rng_cap, ".blend_color"); - if (CanonicalProperties__GetValueStringRange(&a2->CanProp, blend_color.range)) { + prj::string_range_capacity blend_color = prj::string_range_capacity(str_rng_cap, ".blend_color"); + if (a2->CanProp.GetValue(blend_color.range)) { auth_3d_rgba__parse(&ml->blend_color, a2, blend_color); enum_or(ml->flags, AUTH_3D_MATERIAL_LIST_BLEND_COLOR); } - string_range_capacity emission = string_range_capacity_init_char_ptr(str_rng_cap, ".emission"); - if (CanonicalProperties__GetValueStringRange(&a2->CanProp, emission.range)) { + prj::string_range_capacity emission = prj::string_range_capacity(str_rng_cap, ".emission"); + if (a2->CanProp.GetValue(emission.range)) { auth_3d_rgba__parse(&ml->emission, a2, emission); enum_or(ml->flags, AUTH_3D_MATERIAL_LIST_EMISSION); } @@ -1448,17 +1417,3 @@ static void auth_3d_set_material_list(auth_3d* auth) { disp_manager->set_material_list(mat_list_count, mat_list); } - -static string_range_capacity string_range_capacity_init_char_ptr(string_range_capacity str_rng_cap, const char* str) { - char* end = str_rng_cap.range.end; - while (end != str_rng_cap.capacity_end && *str) - *end++ = *str++; - str_rng_cap.range.end = end; - return str_rng_cap; -} - -static prj::string string_init_CanonicalProperties_string_range(CanonicalProperties& CanProp, string_range str_rng) { - prj::string str; - CanonicalProperties__GetValueString(&CanProp, &str, str_rng); - return str; -} diff --git a/src/DivaGL/canonical_properties.cpp b/src/DivaGL/canonical_properties.cpp new file mode 100644 index 0000000..06eec0c --- /dev/null +++ b/src/DivaGL/canonical_properties.cpp @@ -0,0 +1,90 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#include "canonical_properties.hpp" + +CanonicalProperties::CanonicalProperties() { + +} + +CanonicalProperties::~CanonicalProperties() { + +} + +void CanonicalProperties::Clear() { + key_value_pair_storage.clear(); + key_value_pair_storage.shrink_to_fit(); + data.clear(); + data.shrink_to_fit(); +} + +prj::string_range* CanonicalProperties::GetValue(const prj::string_range& key) { + prj::string_range* (FASTCALL * CanonicalProperties__GetValueStringRange)(CanonicalProperties * _this, const prj::string_range * key) + = (prj::string_range * (FASTCALL*)(CanonicalProperties * _this, const prj::string_range * key))0x00000001400AE4F0; + return CanonicalProperties__GetValueStringRange(this, &key); +} + +int32_t CanonicalProperties::GetValueInt32(const prj::string_range& key) { + prj::string_range* value = GetValue(key); + if (!value) + ThrowError(prj::string(key.begin, key.end - key.begin)); + + prj::string temp(value->begin, value->end - value->begin); + return atoi(temp.c_str()); +} + +int32_t CanonicalProperties::GetValueInt32(const prj::string_range& key, const int32_t& def) { + prj::string_range* value = GetValue(key); + if (!value) + return def; + + prj::string temp(value->begin, value->end - value->begin); + return atoi(temp.c_str()); +} + +float_t CanonicalProperties::GetValueFloat32(const prj::string_range& key) { + prj::string_range* value = GetValue(key); + if (!value) + ThrowError(prj::string(key.begin, key.end - key.begin)); + + prj::string temp(value->begin, value->end - value->begin); + return (float_t)atof(temp.c_str()); +} + +prj::string CanonicalProperties::GetValueString(const prj::string_range& key) { + prj::string_range* value = GetValue(key); + if (!value) + ThrowError(prj::string(key.begin, key.end - key.begin)); + + return prj::string(value->begin, value->end - value->begin); +} + +void CanonicalProperties::Parse(const char* str, size_t size) { + void(FASTCALL * CanonicalProperties__ParseCharPtrLength)( + CanonicalProperties * _this, const char* str, size_t size) + = (void(FASTCALL*)(CanonicalProperties * _this, const char* str, size_t size))0x00000001400B52C0; + CanonicalProperties__ParseCharPtrLength(this, str, size); +} + +void CanonicalProperties::Parse(const prj::string_range& data) { + void(FASTCALL * CanonicalProperties__ParseStringRange)( + CanonicalProperties * _this, const prj::string_range * data) + = (void(FASTCALL*)(CanonicalProperties * _this, const prj::string_range * data))0x000000014008E710; + CanonicalProperties__ParseStringRange(this, &data); +} + +void CanonicalProperties::ParseEscapeSeq(const char* str, size_t size) { + void(FASTCALL * CanonicalProperties__ParseCharPtrLengthEscapeSeq)( + CanonicalProperties * _this, const char* str, size_t size) + = (void(FASTCALL*)(CanonicalProperties * _this, const char* str, size_t size))0x00000001400B5020; + CanonicalProperties__ParseCharPtrLengthEscapeSeq(this, str, size); +} + +void CanonicalProperties::ParseEscapeSeq(const prj::string_range& data) { + void(FASTCALL * CanonicalProperties__ParseStringRangeEscapeSeq)( + CanonicalProperties * _this, const prj::string_range * data) + = (void(FASTCALL*)(CanonicalProperties * _this, const prj::string_range * data))0x000000014008E5A0; + CanonicalProperties__ParseStringRangeEscapeSeq(this, &data); +} diff --git a/src/DivaGL/canonical_properties.hpp b/src/DivaGL/canonical_properties.hpp new file mode 100644 index 0000000..3b5a258 --- /dev/null +++ b/src/DivaGL/canonical_properties.hpp @@ -0,0 +1,34 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#pragma once + +#include "types.hpp" +#include + +struct CanonicalProperties { + prj::string data; + prj::vector_pair_alloc key_value_pair_storage; + + CanonicalProperties(); + ~CanonicalProperties(); + + void Clear(); + prj::string_range* GetValue(const prj::string_range& key); + int32_t GetValueInt32(const prj::string_range& key); + int32_t GetValueInt32(const prj::string_range& key, const int32_t& def); + float_t GetValueFloat32(const prj::string_range& key); + prj::string GetValueString(const prj::string_range& key); + void Parse(const char* str, size_t size); + void Parse(const prj::string_range& data); + void ParseEscapeSeq(const char* str, size_t size); + void ParseEscapeSeq(const prj::string_range& data); + + [[noreturn]] inline void ThrowError(const prj::string& str) { + throw std::out_of_range(("CanonicalProperties::get(\"" + str + "\"").c_str()); + } +}; + +static_assert(sizeof(CanonicalProperties) == 0x38, "\"CanonicalProperties\" struct should have a size of 0x38"); diff --git a/src/DivaGL/types.hpp b/src/DivaGL/types.hpp index e10cdd3..fd00fdd 100644 --- a/src/DivaGL/types.hpp +++ b/src/DivaGL/types.hpp @@ -139,31 +139,81 @@ namespace prj { }; struct string_range { - const char* begin; - const char* end; + char* begin; + char* end; inline string_range() : begin(), end() { } - inline string_range(const char* str) { + inline string_range(char* str) { this->begin = str; this->end = str + utf8_length(str); } - inline string_range(const char* str, size_t length) { + inline string_range(char* str, size_t length) { this->begin = str; this->end = str + length; } - inline string_range(const char* begin, const char* end) { + inline string_range(char* begin, char* end) { this->begin = begin; this->end = end; } - inline string_range(const prj::string& str) { - begin = str.c_str(); - end = str.c_str() + str.size(); + inline string_range(prj::string& str) { + begin = (char*)str.data(); + end = (char*)str.data() + str.size(); + } + }; + + static_assert(sizeof(string_range) == 0x10, "\"string_range\" struct should have a size of 0x10"); + + struct string_range_capacity { + string_range range; + char* capacity_end; + + inline string_range_capacity() : capacity_end() { + + } + + inline string_range_capacity(char* str) { + range = string_range(str); + capacity_end = range.end; + } + + inline string_range_capacity(char* str, size_t length) { + range = string_range(str, length); + capacity_end = range.end; + } + + inline string_range_capacity(char* str, size_t length, size_t capacity) { + range = string_range(str, length); + capacity_end = str + capacity; + } + + inline string_range_capacity(char* begin, char* end) { + range = string_range(begin, end); + capacity_end = range.end; + } + + inline string_range_capacity(char* begin, char* end, char* capacity_end) { + range = string_range(begin, end); + this->capacity_end = capacity_end; + } + + inline string_range_capacity(prj::string& str) { + range = string_range(str); + capacity_end = (char*)str.data() + str.capacity(); + } + + inline string_range_capacity(prj::string_range_capacity str_rng_cap, const char* str) { + *this = str_rng_cap; + + char* end = range.end; + while (end != capacity_end && *str) + *end++ = *str++; + range.end = end; } };