diff --git a/src/DivaGL/dllmain.cpp b/src/DivaGL/dllmain.cpp index 06744d7..cb8be0a 100644 --- a/src/DivaGL/dllmain.cpp +++ b/src/DivaGL/dllmain.cpp @@ -90,11 +90,11 @@ void FASTCALL divagl_main() { LoadLibraryW(L"plugins\\DivaSound.dva"); LoadLibraryW(L"plugins\\TLAC.dva"); #endif - extern void FASTCALL wrap_addresses(); - wrap_addresses(); //Sleep(5000); //return; + wrap_addresses(); + printf_divagl("Patching memory"); hook_funcs(); wrap_patch(); diff --git a/src/DivaGL/hook.cpp b/src/DivaGL/hook.cpp index 0f04929..48a1a34 100644 --- a/src/DivaGL/hook.cpp +++ b/src/DivaGL/hook.cpp @@ -16,7 +16,6 @@ #include HOOK(int32_t, FASTCALL, data_init, 0x0000000140192FF0) { - extern void FASTCALL wrap_addresses(); wrap_addresses(); auth_3d_patch(); @@ -49,9 +48,6 @@ HOOK(int32_t, FASTCALL, data_free, 0x000000140192490) { } HOOK(void, FASTCALL, sub_140194CD0, 0x000000140194CD0) { - extern void FASTCALL wrap_addresses(); - wrap_addresses(); - rctx->ctrl(); originalsub_140194CD0(); } @@ -60,6 +56,10 @@ HOOK(void, FASTCALL, _gl_state_get, 0x0000000140442DF0) { gl_state_get(); } +HOOK(bool, FASTCALL, obj_mesh_vertex_buffer__load, 0x0000000140458280, obj_mesh_vertex_buffer* obj_vb, obj_mesh* mesh) { + return obj_vb->load(mesh); +} + HOOK(void, FASTCALL, rndr__Render__update_res, 0x00000001404A9480, rndr::Render* rend, bool set, int32_t base_downsample) { rend->update_res(set, base_downsample); } @@ -105,6 +105,8 @@ void hook_funcs() { INSTALL_HOOK(_gl_state_get); + INSTALL_HOOK(obj_mesh_vertex_buffer__load); + INSTALL_HOOK(rndr__Render__update_res); INSTALL_HOOK(rndr__Render__init_tone_map_buffers); INSTALL_HOOK(rndr__Render__init_render_buffers); diff --git a/src/DivaGL/inject.cpp b/src/DivaGL/inject.cpp index fc73d07..8779d7f 100644 --- a/src/DivaGL/inject.cpp +++ b/src/DivaGL/inject.cpp @@ -101,6 +101,8 @@ void inject_patches() { static HGLRC FASTCALL glut_create_context(int64_t a1, int64_t a2, int64_t a3, int64_t a4, int32_t a5) { HDC& hDc = *(HDC*)(glut_handle + 0x55F20); + wrap_addresses(); + if (true/*a5*/) { const int32_t attrib_list[] = { WGL_CONTEXT_MAJOR_VERSION_ARB, 4, diff --git a/src/DivaGL/mdl/disp_manager.cpp b/src/DivaGL/mdl/disp_manager.cpp index 1138fe2..8f87d76 100644 --- a/src/DivaGL/mdl/disp_manager.cpp +++ b/src/DivaGL/mdl/disp_manager.cpp @@ -75,7 +75,7 @@ namespace mdl { void ObjData::init_etc(const mat4* mat, mdl::EtcObj* etc) { kind = mdl::OBJ_KIND_ETC; - this->mat = *mat; + mat4_transpose(mat, &this->mat); args.etc = *etc; disp_manager->add_vertex_array(&args.etc, this->mat); @@ -88,7 +88,7 @@ namespace mdl { int32_t instances_count, mat4* instances_mat, void(FASTCALL* func)(const ObjSubMeshArgs*), const ObjSubMeshArgs* func_data) { kind = mdl::OBJ_KIND_NORMAL; - this->mat = *mat; + mat4_transpose(mat, &this->mat); this->radius = radius; mdl::ObjSubMeshArgs* args = &this->args.sub_mesh; @@ -138,13 +138,13 @@ namespace mdl { void ObjData::init_translucent(const mat4* mat, ObjTranslucentArgs* translucent) { kind = mdl::OBJ_KIND_TRANSLUCENT; - this->mat = *mat; + mat4_transpose(mat, &this->mat); args.translucent = *translucent; } void ObjData::init_user(const mat4* mat, UserArgsFunc func, void* data) { kind = OBJ_KIND_USER; - this->mat = *mat; + mat4_transpose(mat, &this->mat); args.user.func = func; args.user.data = data; } diff --git a/src/DivaGL/object.cpp b/src/DivaGL/object.cpp index 20abfed..ffe319b 100644 --- a/src/DivaGL/object.cpp +++ b/src/DivaGL/object.cpp @@ -23,6 +23,10 @@ GLuint(FASTCALL* obj_database_get_obj_set_texture)(int32_t set, int32_t tex_id) prj::vector* (FASTCALL* obj_database_get_obj_set_textures)(int32_t set) = (prj::vector * (FASTCALL*)(int32_t set))0x000000014045A9E0; +static void obj_vertex_add_bone_weight(vec4& bone_weight, vec4i16& bone_index, int16_t index, float_t weight); +static void obj_vertex_validate_bone_data(vec4& bone_weight, vec4i16& bone_index); +static uint32_t obj_vertex_format_get_vertex_size(obj_vertex_format format); + void obj_mesh_vertex_buffer::cycle_index() { if (++index >= count) index = 0; @@ -47,6 +51,172 @@ GLsizeiptr obj_mesh_vertex_buffer::get_size() { return 0; } +bool obj_mesh_vertex_buffer::load(obj_mesh* mesh) { + if (!mesh->num_vertex) + return false; + + uint32_t size_vertex = obj_vertex_format_get_vertex_size(mesh->vertex_format); + mesh->size_vertex = size_vertex; + void* vertex = force_malloc((size_t)size_vertex * mesh->num_vertex); + obj_mesh_vertex_buffer::fill_data(vertex, mesh); + + int32_t(FASTCALL * obj_mesh_vertex_buffer__load_data)(obj_mesh_vertex_buffer * mesh_vb, + uint32_t data_size, const void* data, uint32_t count) + = (int32_t(FASTCALL*)(obj_mesh_vertex_buffer * mesh_vb, + uint32_t data_size, const void* data, uint32_t count))0x0000000140461650; + + bool ret = obj_mesh_vertex_buffer__load_data(this, + (size_t)size_vertex * mesh->num_vertex, vertex, mesh->attrib.m.double_buffer ? 2 : 1) >= 0; + free_def(vertex); + return ret; +} + +void* obj_mesh_vertex_buffer::fill_data(void* data, obj_mesh* mesh) { + obj_vertex_format vertex_format = mesh->vertex_format; + obj_mesh_vertex_array vtx = mesh->vertex_array; + uint32_t size_vertex = mesh->size_vertex; + uint32_t num_vertex = mesh->num_vertex; + size_t d = (size_t)data; + if (vertex_format & OBJ_VERTEX_POSITION) { + vec3* position = vtx.position; + for (uint32_t i = num_vertex; i; i--) { + *(vec3*)d = *position++; + d += size_vertex; + } + d -= (size_t)size_vertex * num_vertex; + d += 12; + } + + if (vertex_format & OBJ_VERTEX_NORMAL) { + vec3* normal = vtx.normal; + for (uint32_t i = num_vertex; i; i--) { + *(vec3*)d = *normal++; + d += size_vertex; + } + d -= (size_t)size_vertex * num_vertex; + d += 12; + } + + if (vertex_format & OBJ_VERTEX_TANGENT) { + vec4* tangent = vtx.tangent; + for (uint32_t i = num_vertex; i; i--) { + *(vec4*)d = *tangent++; + d += size_vertex; + } + d -= (size_t)size_vertex * num_vertex; + d += 16; + } + + if (vertex_format & OBJ_VERTEX_BINORMAL) { + vec3* binormal = vtx.binormal; + for (uint32_t i = num_vertex; i; i--) { + *(vec3*)d = *binormal++; + d += size_vertex; + } + d -= (size_t)size_vertex * num_vertex; + d += 12; + } + + if (vertex_format & OBJ_VERTEX_TEXCOORD0) { + vec2* texcoord0 = vtx.texcoord0; + for (uint32_t i = num_vertex; i; i--) { + *(vec2*)d = *texcoord0++; + d += size_vertex; + } + d -= (size_t)size_vertex * num_vertex; + d += 8; + } + + if (vertex_format & OBJ_VERTEX_TEXCOORD1) { + vec2* texcoord1 = vtx.texcoord1; + for (uint32_t i = num_vertex; i; i--) { + *(vec2*)d = *texcoord1++; + d += size_vertex; + } + d -= (size_t)size_vertex * num_vertex; + d += 8; + } + + if (vertex_format & OBJ_VERTEX_TEXCOORD2) { + vec2* texcoord2 = vtx.texcoord2; + for (uint32_t i = num_vertex; i; i--) { + *(vec2*)d = *texcoord2++; + d += size_vertex; + } + d -= (size_t)size_vertex * num_vertex; + d += 8; + } + + if (vertex_format & OBJ_VERTEX_TEXCOORD3) { + vec2* texcoord3 = vtx.texcoord3; + for (uint32_t i = num_vertex; i; i--) { + *(vec2*)d = *texcoord3++; + d += size_vertex; + } + d -= (size_t)size_vertex * num_vertex; + d += 8; + } + + if (vertex_format & OBJ_VERTEX_COLOR0) { + vec4* color0 = vtx.color0; + for (uint32_t i = num_vertex; i; i--) { + *(vec4*)d = *color0++; + d += size_vertex; + } + d -= (size_t)size_vertex * num_vertex; + d += 16; + } + + if (vertex_format & OBJ_VERTEX_COLOR1) { + vec4* color1 = vtx.color1; + for (uint32_t i = num_vertex; i; i--) { + *(vec4*)d = *color1++; + d += size_vertex; + } + d -= (size_t)size_vertex * num_vertex; + d += 16; + } + + if ((vertex_format & OBJ_VERTEX_BONE_DATA) == OBJ_VERTEX_BONE_DATA) { + vec4* bone_weight = vtx.bone_weight; + vec4* bone_index = vtx.bone_index; + for (uint32_t i = num_vertex; i; i--) { + vec4 _bone_weight = *bone_weight++; + + int32_t bone_index_x = (int32_t)bone_index->x; + int32_t bone_index_y = (int32_t)bone_index->y; + int32_t bone_index_z = (int32_t)bone_index->z; + int32_t bone_index_w = (int32_t)bone_index->w; + bone_index++; + + vec4i16 _bone_index; + _bone_index.x = (int16_t)(bone_index_x >= 0 ? bone_index_x / 3 : -1); + _bone_index.y = (int16_t)(bone_index_y >= 0 ? bone_index_y / 3 : -1); + _bone_index.z = (int16_t)(bone_index_z >= 0 ? bone_index_z / 3 : -1); + _bone_index.w = (int16_t)(bone_index_w >= 0 ? bone_index_w / 3 : -1); + obj_vertex_validate_bone_data(_bone_weight, _bone_index); + + *(vec4*)d = _bone_weight; + *(vec4i16*)(d + 16) = _bone_index; + d += size_vertex; + } + d -= (size_t)size_vertex * num_vertex; + d += 24; + } + + if (vertex_format & OBJ_VERTEX_UNKNOWN) { + vec4* unknown = vtx.unknown; + for (uint32_t i = num_vertex; i; i--) { + *(vec4*)d = *unknown++; + d += size_vertex; + } + d -= (size_t)size_vertex * num_vertex; + d += 16; + } + + return (void*)d; +} + inline int32_t obj_material_texture_type_get_texcoord_index( obj_material_texture_type type, int32_t index) { switch (type) { @@ -100,6 +270,7 @@ void obj_skin_set_matrix_buffer(obj_skin* s, mat4* matrices, mat4_mul(global_mat, &temp, &temp); mat4_mul(&temp, &s->bone_matrix_array[i], &matrix_buffer[i]); + mat4_transpose(&matrix_buffer[i], &matrix_buffer[i]); } else for (uint32_t i = 0; i < s->num_bone; i++) { @@ -112,5 +283,78 @@ void obj_skin_set_matrix_buffer(obj_skin* s, mat4* matrices, mat4_mul(global_mat, &temp, &temp); mat4_mul(&temp, &s->bone_matrix_array[i], &matrix_buffer[i]); + mat4_transpose(&matrix_buffer[i], &matrix_buffer[i]); } } + +static void obj_vertex_add_bone_weight(vec4& bone_weight, vec4i16& bone_index, int16_t index, float_t weight) { + if (bone_index.x < 0) { + bone_index.x = index; + bone_weight.x = weight; + } + else if (bone_index.y < 0) { + bone_index.y = index; + bone_weight.y = weight; + } + else if (bone_index.z < 0) { + bone_index.z = index; + bone_weight.z = weight; + } + else if (bone_index.w < 0) { + bone_index.w = index; + bone_weight.w = weight; + } +} + +static void obj_vertex_validate_bone_data(vec4& bone_weight, vec4i16& bone_index) { + vec4 _bone_weight = { 0.0f, 0.0f, 0.0f, 0.0f }; + vec4i16 _bone_index = { -1, -1, -1, -1 }; + + if (bone_index.x >= 0 && bone_weight.x > 0.0f) + obj_vertex_add_bone_weight(_bone_weight, _bone_index, bone_index.x, bone_weight.x); + + if (bone_index.y >= 0 && bone_weight.y > 0.0f) + obj_vertex_add_bone_weight(_bone_weight, _bone_index, bone_index.y, bone_weight.y); + + if (bone_index.z >= 0 && bone_weight.z > 0.0f) + obj_vertex_add_bone_weight(_bone_weight, _bone_index, bone_index.z, bone_weight.z); + + if (bone_index.w >= 0 && bone_weight.w > 0.0f) + obj_vertex_add_bone_weight(_bone_weight, _bone_index, bone_index.w, bone_weight.w); + + float_t sum = _bone_weight.x + _bone_weight.y + _bone_weight.z + _bone_weight.w; + if (sum > 0.0f && fabsf(sum - 1.0f) > 0.000001f) + _bone_weight *= 1.0f / sum; + + bone_weight = _bone_weight; + bone_index = _bone_index; +} + +inline static uint32_t obj_vertex_format_get_vertex_size(obj_vertex_format format) { + uint32_t size = 0; + if (format & OBJ_VERTEX_POSITION) + size += 12; + if (format & OBJ_VERTEX_NORMAL) + size += 12; + if (format & OBJ_VERTEX_TANGENT) + size += 16; + if (format & OBJ_VERTEX_BINORMAL) + size += 12; + if (format & OBJ_VERTEX_TEXCOORD0) + size += 8; + if (format & OBJ_VERTEX_TEXCOORD1) + size += 8; + if (format & OBJ_VERTEX_TEXCOORD2) + size += 8; + if (format & OBJ_VERTEX_TEXCOORD3) + size += 8; + if (format & OBJ_VERTEX_COLOR0) + size += 16; + if (format & OBJ_VERTEX_COLOR1) + size += 16; + if ((format & OBJ_VERTEX_BONE_DATA) == OBJ_VERTEX_BONE_DATA) + size += 24; + if (format & OBJ_VERTEX_UNKNOWN) + size += 16; + return size; +} diff --git a/src/DivaGL/object.hpp b/src/DivaGL/object.hpp index 9642347..0040ce7 100644 --- a/src/DivaGL/object.hpp +++ b/src/DivaGL/object.hpp @@ -318,22 +318,6 @@ struct obj_sub_mesh { static_assert(sizeof(obj_sub_mesh) == 0x70, "\"obj_sub_mesh\" struct should have a size of 0x70"); -struct obj_vertex_data { - vec3 position; - vec3 normal; - vec4 tangent; - vec3 binormal; - vec2 texcoord0; - vec2 texcoord1; - vec2 texcoord2; - vec2 texcoord3; - vec4 color0; - vec4 color1; - vec4 bone_weight; - vec4i16 bone_index; - vec4 unknown; -}; - struct obj_mesh_attrib_member { uint32_t double_buffer : 1; uint32_t billboard_y_axis : 1; @@ -360,7 +344,7 @@ struct obj_mesh_vertex_array { vec4* color1; vec4* bone_weight; vec4* bone_index; - void* field_60; + vec4* unknown; void* field_68; void* field_70; void* field_78; @@ -494,6 +478,9 @@ struct obj_mesh_vertex_buffer { void cycle_index(); GLuint get_buffer(); GLsizeiptr get_size(); + bool load(obj_mesh* mesh); + + static void* fill_data(void* data, obj_mesh* mesh); }; static_assert(sizeof(obj_mesh_vertex_buffer) == 0x18, "\"obj_mesh_vertex_buffer\" struct should have a size of 0x18"); diff --git a/src/DivaGL/wrap.cpp b/src/DivaGL/wrap.cpp index 52a0ee1..ddd49da 100644 --- a/src/DivaGL/wrap.cpp +++ b/src/DivaGL/wrap.cpp @@ -1616,7 +1616,7 @@ static void print_debug_error(const char* c, const char* e) { } #endif -void FASTCALL wrap_addresses() { +void wrap_addresses() { #ifdef DEBUG print_debug_error("Patching tables", 0); #endif @@ -1682,10 +1682,6 @@ HOOK(void, FASTCALL, wglGetProcAddresses, 0x0000000140461B50) { wrap_addresses(); } -HOOK(GLenum, FASTCALL, gl_check_framebuffer_status, 0x0000000140503240) { - return glCheckFramebufferStatus(GL_FRAMEBUFFER); -} - void wrap_patch() { // glShadeModel(GL_SMOOTH); WRITE_NOP_11(0x00000001401948CA); @@ -1695,11 +1691,7 @@ void wrap_patch() { // glClampColorARB(GL_CLAMP_READ_COLOR_ARB, GL_FIXED_ONLY_ARB); WRITE_JUMP(0x0000000140194932, 0x000000014019495B); - // glCheckFramebufferStatusEXT -> glCheckFramebufferStatus - //WRITE_NULL(0x0000000140A0C3E0, 0x03); - INSTALL_HOOK(wglGetProcAddresses); - //INSTALL_HOOK(gl_check_framebuffer_status); } void GLAPIENTRY glAlphaFuncDLL(GLenum func, GLfloat ref) { diff --git a/src/DivaGL/wrap.hpp b/src/DivaGL/wrap.hpp index f7d00b4..e192b2f 100644 --- a/src/DivaGL/wrap.hpp +++ b/src/DivaGL/wrap.hpp @@ -3254,6 +3254,7 @@ extern bool GL_VERSION_4_4; extern bool GL_VERSION_4_5; extern bool GL_VERSION_4_6; +extern void wrap_addresses(); extern void wrap_patch(); extern void GLAPIENTRY glAlphaFuncDLL(GLenum func, GLfloat ref);