diff --git a/res/ft_shaders.farc b/res/ft_shaders.farc
index c97a9a1..43dd6f9 100644
Binary files a/res/ft_shaders.farc and b/res/ft_shaders.farc differ
diff --git a/src/DivaGL/DivaGL.vcxproj b/src/DivaGL/DivaGL.vcxproj
index 1864e27..2151428 100644
--- a/src/DivaGL/DivaGL.vcxproj
+++ b/src/DivaGL/DivaGL.vcxproj
@@ -166,6 +166,7 @@ del "$(SolutionDir)bin\$(TargetName).lib"
+
@@ -225,6 +226,7 @@ del "$(SolutionDir)bin\$(TargetName).lib"
+
diff --git a/src/DivaGL/Glitter/counter.cpp b/src/DivaGL/Glitter/counter.cpp
index 4911611..2138a14 100644
--- a/src/DivaGL/Glitter/counter.cpp
+++ b/src/DivaGL/Glitter/counter.cpp
@@ -6,7 +6,7 @@
#include "glitter.hpp"
namespace Glitter {
- Counter* counter = (Counter*)0x0000000141199CB0;
+ Counter& counter = *(Counter*)0x0000000141199CB0;
void Counter::Increment() {
value++;
diff --git a/src/DivaGL/Glitter/effect_group.cpp b/src/DivaGL/Glitter/effect_group.cpp
index 28f0ffc..7674db5 100644
--- a/src/DivaGL/Glitter/effect_group.cpp
+++ b/src/DivaGL/Glitter/effect_group.cpp
@@ -4,7 +4,6 @@
*/
#include "glitter.hpp"
-#include "../../KKdLib/prj/algorithm.hpp"
#include "../object.hpp"
#include "../texture.hpp"
diff --git a/src/DivaGL/Glitter/effect_inst.cpp b/src/DivaGL/Glitter/effect_inst.cpp
index 50eb068..a41f055 100644
--- a/src/DivaGL/Glitter/effect_inst.cpp
+++ b/src/DivaGL/Glitter/effect_inst.cpp
@@ -63,7 +63,7 @@ namespace Glitter {
ext_anim = 0;
render_scene = {};
- Glitter::counter->Increment();
+ Glitter::counter.Increment();
if (load_flags & 0x01)
enum_or(flags, EFFECT_INST_FLAG_23);
@@ -71,7 +71,7 @@ namespace Glitter {
if (data.flags & EFFECT_USE_SEED)
random = data.seed;
else
- random = Glitter::counter->GetValue();
+ random = Glitter::counter.GetValue();
random_shared.value = random;
if (!(eff->data.flags & EFFECT_LOCAL) && data.ext_anim) {
diff --git a/src/DivaGL/Glitter/emitter_inst.cpp b/src/DivaGL/Glitter/emitter_inst.cpp
index 2d40af5..58b54bd 100644
--- a/src/DivaGL/Glitter/emitter_inst.cpp
+++ b/src/DivaGL/Glitter/emitter_inst.cpp
@@ -168,7 +168,7 @@ namespace Glitter {
switch (data.direction) {
case DIRECTION_BILLBOARD: {
if (eff_inst->data.flags & EFFECT_LOCAL) {
- mat4_transpose(&camera_data->view, &dir_mat);
+ mat4_transpose(&camera_data.view, &dir_mat);
mat4_clear_trans(&dir_mat, &dir_mat);
mat4_mul(&dir_mat, &mat, &dir_mat);
}
@@ -177,7 +177,7 @@ namespace Glitter {
mat4 inv_view_mat;
mat3 inv_view_mat3;
- mat4_transpose(&camera_data->view, &inv_view_mat);
+ mat4_transpose(&camera_data.view, &inv_view_mat);
mat4_to_mat3(&inv_view_mat, &inv_view_mat3);
mat3_invert(&inv_view_mat3, &inv_view_mat3);
mat4_from_mat3(&inv_view_mat3, &inv_view_mat);
@@ -191,7 +191,7 @@ namespace Glitter {
mat4_rotate_x((float_t)-M_PI_2, &dir_mat);
break;
case DIRECTION_BILLBOARD_Y_AXIS:
- mat4_rotate_y(camera_data->rotation.y, &dir_mat);
+ mat4_rotate_y(camera_data.rotation.y, &dir_mat);
break;
default:
mult = false;
@@ -287,7 +287,7 @@ namespace Glitter {
switch (data.direction) {
case DIRECTION_BILLBOARD: {
mat3 inv_view_mat3;
- mat4_transpose(&camera_data->view, &dir_mat);
+ mat4_transpose(&camera_data.view, &dir_mat);
mat4_to_mat3(&dir_mat, &inv_view_mat3);
mat3_invert(&inv_view_mat3, &inv_view_mat3);
mat4_from_mat3(&inv_view_mat3, &dir_mat);
@@ -301,7 +301,7 @@ namespace Glitter {
mat4_rotate_x((float_t)-M_PI_2, &dir_mat);
break;
case DIRECTION_BILLBOARD_Y_AXIS:
- mat4_rotate_y(camera_data->rotation.y, &dir_mat);
+ mat4_rotate_y(camera_data.rotation.y, &dir_mat);
break;
default:
mult = false;
diff --git a/src/DivaGL/Glitter/file_reader.cpp b/src/DivaGL/Glitter/file_reader.cpp
index bce33ba..ef7bcec 100644
--- a/src/DivaGL/Glitter/file_reader.cpp
+++ b/src/DivaGL/Glitter/file_reader.cpp
@@ -662,7 +662,7 @@ namespace Glitter {
ids[i] = texture_id(0x2A, GPM_VAL->texture_counter++);
txp_set_load(st->data.data(), &eff_group->resources, (uint32_t*)ids);
- free_def(ids);
+ _operator_delete(ids);
uint32_t* resource_hashes = this->resource_hashes;
diff --git a/src/DivaGL/Glitter/glitter.cpp b/src/DivaGL/Glitter/glitter.cpp
index 25f87c9..42fed6e 100644
--- a/src/DivaGL/Glitter/glitter.cpp
+++ b/src/DivaGL/Glitter/glitter.cpp
@@ -11,21 +11,21 @@
namespace Glitter {
const float_t min_emission = 0.01f;
- void axis_angle_from_vectors(vec3* axis, float_t* angle, const vec3* vec1, const vec3* vec2) {
- *axis = vec3::cross(*vec1, *vec2);
- *angle = vec3::length(*axis);
+ void axis_angle_from_vectors(vec3& axis, float_t& angle, const vec3& vec1, const vec3& vec2) {
+ axis = vec3::cross(vec1, vec2);
+ angle = vec3::length(axis);
- if (*angle >= 0.000001f)
- *angle = asinf(clamp_def(*angle, -1.0f, 1.0f));
+ if (angle >= 0.000001f)
+ angle = asinf(clamp_def(angle, -1.0f, 1.0f));
else {
- *angle = 0.0f;
- *axis = vec3::cross(vec3(0.0f, 1.0f, 0.0f), *vec1);
- if (vec3::length(*axis) < 0.000001f)
- *axis = vec3::cross(vec3(0.0f, 0.0f, 1.0f), *vec1);
+ angle = 0.0f;
+ axis = vec3::cross(vec3(0.0f, 1.0f, 0.0f), vec1);
+ if (vec3::length(axis) < 0.000001f)
+ axis = vec3::cross(vec3(0.0f, 0.0f, 1.0f), vec1);
}
- if (vec3::dot(*vec1, *vec2) < 0.0f)
- *angle = (float_t)M_PI - *angle;
+ if (vec3::dot(vec1, vec2) < 0.0f)
+ angle = (float_t)M_PI - angle;
}
void CreateBuffer(size_t max_count, bool is_quad,
diff --git a/src/DivaGL/Glitter/glitter.hpp b/src/DivaGL/Glitter/glitter.hpp
index 1ef5a50..695ea95 100644
--- a/src/DivaGL/Glitter/glitter.hpp
+++ b/src/DivaGL/Glitter/glitter.hpp
@@ -1499,9 +1499,9 @@ namespace Glitter {
extern GltParticleManager* glt_particle_manager;
extern GltParticleManagerX* glt_particle_manager_x;
extern RandomX random_x;
- extern Counter* counter;
+ extern Counter& counter;
- extern void axis_angle_from_vectors(vec3* axis, float_t* angle, const vec3* vec0, const vec3* vec1);
+ extern void axis_angle_from_vectors(vec3& axis, float_t& angle, const vec3& vec0, const vec3& vec1);
extern void CreateBuffer(size_t max_count, bool is_quad,
Buffer*& buffer, GLuint& vao, GL::ArrayBuffer& vbo, GL::ElementArrayBuffer& ebo);
diff --git a/src/DivaGL/Glitter/locus_history.cpp b/src/DivaGL/Glitter/locus_history.cpp
index f962b23..6c58c80 100644
--- a/src/DivaGL/Glitter/locus_history.cpp
+++ b/src/DivaGL/Glitter/locus_history.cpp
@@ -55,5 +55,4 @@ namespace Glitter {
hist_data->translation = temp;
}
}
-
}
diff --git a/src/DivaGL/Glitter/render_group.cpp b/src/DivaGL/Glitter/render_group.cpp
index 443bbc8..c9546b2 100644
--- a/src/DivaGL/Glitter/render_group.cpp
+++ b/src/DivaGL/Glitter/render_group.cpp
@@ -24,7 +24,7 @@ namespace Glitter {
vec3 axis;
float_t angle;
- axis_angle_from_vectors(&axis, &angle, &vec1, &vec2);
+ axis_angle_from_vectors(axis, angle, vec1, vec2);
mat4_mul_rotation(&mat, &axis, angle, &mat);
}
else
@@ -47,7 +47,7 @@ namespace Glitter {
vec3 axis;
float_t angle;
- axis_angle_from_vectors(&axis, &angle, &vec1, &vec2);
+ axis_angle_from_vectors(axis, angle, vec1, vec2);
mat4_mul_rotation(&mat, &axis, angle, &mat);
}
return mat;
@@ -467,7 +467,7 @@ namespace Glitter {
vec3 axis;
float_t angle;
- axis_angle_from_vectors(&axis, &angle, &vec1, &vec2);
+ axis_angle_from_vectors(axis, angle, vec1, vec2);
mat4 mat = mat4_identity;
mat4_mul_rotation(&mat, &axis, angle, &mat);
@@ -487,7 +487,7 @@ namespace Glitter {
vec3 axis;
float_t angle;
- axis_angle_from_vectors(&axis, &angle, &vec1, &vec2);
+ axis_angle_from_vectors(axis, angle, vec1, vec2);
mat4 mat = mat4_identity;
mat4_mul_rotation(&mat, &axis, angle, &mat);
@@ -509,7 +509,7 @@ namespace Glitter {
vec3 axis;
float_t angle;
- axis_angle_from_vectors(&axis, &angle, &vec1, &vec2);
+ axis_angle_from_vectors(axis, angle, vec1, vec2);
mat4 mat = mat4_identity;
mat4_mul_rotation(&mat, &axis, angle, &mat);
@@ -529,7 +529,7 @@ namespace Glitter {
vec3 axis;
float_t angle;
- axis_angle_from_vectors(&axis, &angle, &vec1, &vec2);
+ axis_angle_from_vectors(axis, angle, vec1, vec2);
mat4 mat = mat4_identity;
mat4_mul_rotation(&mat, &axis, angle, &mat);
diff --git a/src/DivaGL/Glitter/render_scene.cpp b/src/DivaGL/Glitter/render_scene.cpp
index f69d9c3..5bae7f6 100644
--- a/src/DivaGL/Glitter/render_scene.cpp
+++ b/src/DivaGL/Glitter/render_scene.cpp
@@ -9,6 +9,9 @@
#include "../shader_ft.hpp"
#include "../wrap.hpp"
+extern bool reflect_draw;
+extern mat4 reflect_mat;
+
namespace Glitter {
void RenderScene::CalcDisp() {
disp_quad = 0;
@@ -88,8 +91,8 @@ namespace Glitter {
mat4 cam_view;
mat4 cam_projection;
- mat4_transpose(&camera_data->view, &cam_view);
- mat4_transpose(&camera_data->projection, &cam_projection);
+ mat4_transpose(&camera_data.view, &cam_view);
+ mat4_transpose(&camera_data.projection, &cam_projection);
mat4 mat;
mat4_transpose(&rend_group->mat_draw, &mat);
@@ -368,8 +371,8 @@ namespace Glitter {
mat4 cam_view;
mat4 cam_inv_view;
- mat4_transpose(&camera_data->view, &cam_view);
- mat4_transpose(&camera_data->inv_view, &cam_inv_view);
+ mat4_transpose(&camera_data.view, &cam_view);
+ mat4_transpose(&camera_data.inv_view, &cam_inv_view);
vec3 x_vec = { 1.0f, 0.0f, 0.0f };
if (rend_group->flags & PARTICLE_LOCAL) {
@@ -511,8 +514,8 @@ namespace Glitter {
mat4 cam_view;
mat4 cam_inv_view;
- mat4_transpose(&camera_data->view, &cam_view);
- mat4_transpose(&camera_data->inv_view, &cam_inv_view);
+ mat4_transpose(&camera_data.view, &cam_view);
+ mat4_transpose(&camera_data.inv_view, &cam_inv_view);
mat4 model_mat;
mat4 view_mat;
@@ -571,7 +574,7 @@ namespace Glitter {
mat4_rotate_z((float_t)-M_PI_2, &dir_mat);
break;
case DIRECTION_BILLBOARD_Y_AXIS:
- mat4_rotate_y(camera_data->rotation.y, &dir_mat);
+ mat4_rotate_y(camera_data.rotation.y, &dir_mat);
break;
default:
dir_mat = mat4_identity;
@@ -717,7 +720,7 @@ namespace Glitter {
if (fabsf(rend_group->z_offset) > 0.000001f) {
use_z_offset = true;
mat4_get_translation(model_mat, &dist_to_cam);
- dist_to_cam = camera_data->view_point - dist_to_cam;
+ dist_to_cam = camera_data.view_point - dist_to_cam;
if (rend_group->flags & PARTICLE_EMITTER_LOCAL) {
mat4_normalize_rotation(model_mat, &z_offset_inv_mat);
mat4_invert(&z_offset_inv_mat, &z_offset_inv_mat);
@@ -1197,8 +1200,8 @@ namespace Glitter {
mat4 cam_view;
mat4 cam_inv_view;
- mat4_transpose(&camera_data->view, &cam_view);
- mat4_transpose(&camera_data->inv_view, &cam_inv_view);
+ mat4_transpose(&camera_data.view, &cam_view);
+ mat4_transpose(&camera_data.inv_view, &cam_inv_view);
vec3 x_vec = { 1.0f, 0.0f, 0.0f };
if (rend_group->flags & PARTICLE_LOCAL) {
@@ -1338,8 +1341,8 @@ namespace Glitter {
mat4 cam_view;
mat4 cam_inv_view;
- mat4_transpose(&camera_data->view, &cam_view);
- mat4_transpose(&camera_data->inv_view, &cam_inv_view);
+ mat4_transpose(&camera_data.view, &cam_view);
+ mat4_transpose(&camera_data.inv_view, &cam_inv_view);
mat4 model_mat;
mat4 view_mat;
@@ -1387,7 +1390,7 @@ namespace Glitter {
mat4_rotate_x((float_t)-M_PI_2, &dir_mat);
break;
case DIRECTION_BILLBOARD_Y_AXIS:
- mat4_rotate_y(camera_data->rotation.y, &dir_mat);
+ mat4_rotate_y(camera_data.rotation.y, &dir_mat);
break;
default:
dir_mat = mat4_identity;
@@ -1532,7 +1535,7 @@ namespace Glitter {
if (fabsf(rend_group->z_offset) > 0.000001f) {
use_z_offset = true;
mat4_get_translation(model_mat, &dist_to_cam);
- dist_to_cam = camera_data->view_point - dist_to_cam;
+ dist_to_cam = camera_data.view_point - dist_to_cam;
if (rend_group->flags & PARTICLE_EMITTER_LOCAL) {
mat4_normalize_rotation(model_mat, &z_offset_inv_mat);
mat4_invert(&z_offset_inv_mat, &z_offset_inv_mat);
@@ -1804,8 +1807,10 @@ namespace Glitter {
mat4 cam_view;
mat4 cam_projection;
- mat4_transpose(&camera_data->view, &cam_view);
- mat4_transpose(&camera_data->projection, &cam_projection);
+ mat4_transpose(&camera_data.view, &cam_view);
+ if (reflect_draw)
+ mat4_mul(&reflect_mat, &cam_view, &cam_view);
+ mat4_transpose(&camera_data.projection, &cam_projection);
mat4 mat;
mat4_mul(&rend_group->mat_draw, &cam_view, &mat);
@@ -1979,8 +1984,8 @@ namespace Glitter {
mat4 cam_view;
mat4 cam_inv_view;
- mat4_transpose(&camera_data->view, &cam_view);
- mat4_transpose(&camera_data->inv_view, &cam_inv_view);
+ mat4_transpose(&camera_data.view, &cam_view);
+ mat4_transpose(&camera_data.inv_view, &cam_inv_view);
bool has_scale = false;
bool emitter_local = false;
@@ -2044,7 +2049,7 @@ namespace Glitter {
mat4_rotate_x((float_t)-M_PI_2, &dir_mat);
break;
case DIRECTION_BILLBOARD_Y_AXIS:
- mat4_rotate_y(camera_data->rotation.y, &dir_mat);
+ mat4_rotate_y(camera_data.rotation.y, &dir_mat);
break;
case DIRECTION_EMITTER_ROTATION:
emitter_rotation = true;
@@ -2096,6 +2101,8 @@ namespace Glitter {
const bool object_culling = disp_manager.object_culling;
if (local)
disp_manager.object_culling = false;
+ extern bool reflect_full;
+ mdl::obj_reflect_enable = !local && reflect_full;
disp_manager.set_texture_pattern(0, 0);
RenderElementX* elem = rend_group->elements;
@@ -2159,7 +2166,7 @@ namespace Glitter {
elem->mat_draw = mat;
mat4_transpose(&mat, &mat);
- if (disp_manager.entry_obj_by_object_info(&mat,
+ if (disp_manager.entry_obj_by_object_info(mat,
rend_group->object, &elem->color, 0, local))
disp++;
@@ -2170,6 +2177,7 @@ namespace Glitter {
rend_group->disp = disp;
if (local)
disp_manager.object_culling = object_culling;
+ mdl::obj_reflect_enable = false;
}
size_t RenderSceneX::GetCtrlCount(ParticleType type) {
diff --git a/src/DivaGL/auth_2d.cpp b/src/DivaGL/auth_2d.cpp
index f9ffa9b..352c85c 100644
--- a/src/DivaGL/auth_2d.cpp
+++ b/src/DivaGL/auth_2d.cpp
@@ -217,7 +217,7 @@ void aet_layout_data::put_sprite(int32_t spr_id, spr::SprAttr attr,
args.prio = prio;
if (pos)
*(vec2*)&args.trans.x += *pos;
- spr::put_sprite(&args);
+ spr::put_sprite(args);
}
void aet_layout_data::set_args(const aet_layout_data* layout, spr::SprArgs* args) {
diff --git a/src/DivaGL/auth_3d.cpp b/src/DivaGL/auth_3d.cpp
index 046a7df..393b327 100644
--- a/src/DivaGL/auth_3d.cpp
+++ b/src/DivaGL/auth_3d.cpp
@@ -6,7 +6,9 @@
#include "auth_3d.hpp"
#include "../KKdLib/hash.hpp"
#include "light_param/fog.hpp"
+#include "light_param/light.hpp"
#include "mdl/disp_manager.hpp"
+#include "pv_game/firstread.hpp"
#include "rob/rob.hpp"
#include "canonical_properties.hpp"
#include "file_handler.hpp"
@@ -451,6 +453,7 @@ struct auth_3d {
mat4* bone_mats;
bool shadow;
bool chara_item;
+ bool reflect;
chara_index src_chara;
chara_index dst_chara;
int32_t pos;
@@ -877,6 +880,14 @@ void auth_3d_id::set_pos(int32_t value) {
}
}
+void auth_3d_id::set_reflect(bool value) {
+ if (id >= 0 && ((id & 0x7FFF) < AUTH_3D_DATA_COUNT)) {
+ auth_3d* auth = &auth_3d_data->data[id & 0x7FFF];
+ if (auth->id == id)
+ auth->reflect = 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];
@@ -966,6 +977,59 @@ int32_t auth_3d_data_get_auth_3d_id(uint32_t uid, object_info obj_info,
return -1;
}
+HOOK(void, FASTCALL, auth_3d_parse, 0x00000001401C15B0, auth_3d* auth) {
+ originalauth_3d_parse(auth);
+
+ extern bool reflect_full;
+ extern const firstread* firstread_ptr;
+ if (!reflect_full || !firstread_ptr || !firstread_ptr->auth_3d_array)
+ return;
+
+ const firstread_auth_3d_array* auth_3d_array = firstread_ptr->auth_3d_array;
+
+ for (uint32_t i = 0; i < auth_3d_array->num_auth_3d; i++) {
+ if (auth_3d_array->auth_3d_array[i].uid != auth->uid)
+ continue;
+
+ const firstread_auth_3d* frg_auth_3d = &auth_3d_array->auth_3d_array[i];
+
+ auto obj_begin = auth->object.begin();
+ auto obj_end = auth->object.end();
+ const uint32_t num_object = frg_auth_3d->num_object;
+ for (uint32_t j = 0; j < num_object; j++) {
+ const uint64_t name_hash = hash_utf8_xxh3_64bits(frg_auth_3d->object_array[j].name);
+ for (auth_3d_object& k : auth->object) {
+ if (name_hash != hash_utf8_xxh3_64bits(k.name.c_str()))
+ continue;
+
+ const firstread_auth_3d_object* frg_a3d_obj = &frg_auth_3d->object_array[j];
+ k.uid_name.assign(frg_a3d_obj->uid_name);
+ k.object_info = object_database_get_object_info(frg_a3d_obj->uid_name);
+
+ k.reflect = k.uid_name.find("_REFLECT") != -1;
+ k.refract = k.uid_name.find("_REFRACT") != -1;
+ break;
+ }
+ }
+
+ auto obj_list_begin = auth->object_list.begin();
+ auto obj_list_end = auth->object_list.end();
+ const uint32_t num_object_list = frg_auth_3d->num_object_list;
+ for (uint32_t j = 0; j < num_object_list; j++) {
+ const uint64_t name_hash = hash_utf8_xxh3_64bits(frg_auth_3d->object_list_array[j].name);
+ for (auto obj_list = obj_list_begin; obj_list != obj_list_end; )
+ if (name_hash == hash_utf8_xxh3_64bits((*obj_list)->name.c_str())) {
+ auth->object_list.erase(obj_list);
+ obj_list_end = auth->object_list.end();
+ break;
+ }
+ else
+ obj_list++;
+ }
+ break;
+ }
+}
+
HOOK(void, FASTCALL, auth_3d_curve_array_free, 0x00000001401C2E30,
prj::vector* vec, auth_3d_curve* begin, auth_3d_curve* end) {
while (begin != end) {
@@ -1037,7 +1101,7 @@ HOOK(void, FASTCALL, auth_3d_m_object_hrc_disp, 0x00000001401D0760, auth_3d_m_ob
if (i.mats.size())
disp_manager.entry_obj_by_object_info_object_skin(
- i.object_info, 0, 0, auth->alpha, i.mats.data(), 0, 0, &i.model_transform.mat);
+ i.object_info, 0, 0, auth->alpha, i.mats.data(), 0, 0, i.model_transform.mat);
}
disp_manager.set_obj_flags();
@@ -1098,7 +1162,7 @@ HOOK(void, FASTCALL, auth_3d_object_hrc_disp, 0x00000001401D04A0, auth_3d_object
if (oh->node_bone_mats.size())
disp_manager.entry_obj_by_object_info_object_skin(
- oh->object_info, 0, 0, auth->alpha, oh->node_bone_mats.data(), 0, 0, &mat);
+ oh->object_info, 0, 0, auth->alpha, oh->node_bone_mats.data(), 0, 0, mat);
disp_manager.set_obj_flags();
disp_manager.set_shadow_type(SHADOW_CHARA);
@@ -1118,7 +1182,7 @@ HOOK(void, FASTCALL, auth_3d_object_disp, 0x00000001401D0970, auth_3d_object* o,
if (!auth->visible) {
if (auth->pos)
- spr::put_rgb_cross(&o->model_transform.mat);
+ spr::put_rgb_cross(o->model_transform.mat);
for (auth_3d_object*& i : o->children_object)
implOfauth_3d_object_disp(i, auth);
@@ -1196,7 +1260,7 @@ HOOK(void, FASTCALL, auth_3d_object_disp, 0x00000001401D0970, auth_3d_object* o,
int32_t uid_name_length = (int32_t)o->uid_name.size();
if (uid_name_length <= 3)
- disp_manager.entry_obj_by_object_info(&mat, o->object_info);
+ disp_manager.entry_obj_by_object_info(mat, o->object_info);
else if (o->morph.curve) {
float_t morph = o->morph.value;
int32_t morph_int = (int32_t)morph;
@@ -1211,9 +1275,9 @@ HOOK(void, FASTCALL, auth_3d_object_disp, 0x00000001401D0970, auth_3d_object* o,
sprintf_s(buf, sizeof(buf), "%.*s%03d", uid_name_length - 3, uid_name, morph_int);
object_info obj_info = object_database_get_object_info(buf);
if (auth->alpha < 0.999f)
- disp_manager.entry_obj_by_object_info(&mat, obj_info, auth->alpha);
+ disp_manager.entry_obj_by_object_info(mat, obj_info, auth->alpha);
else
- disp_manager.entry_obj_by_object_info(&mat, obj_info);
+ disp_manager.entry_obj_by_object_info(mat, obj_info);
disp_manager.set_morph({}, 0.0f);
}
else {
@@ -1224,24 +1288,24 @@ HOOK(void, FASTCALL, auth_3d_object_disp, 0x00000001401D0970, auth_3d_object* o,
object_info obj_info = object_database_get_object_info(buf);
if (obj_info.is_null())
obj_info = o->object_info;
- disp_manager.entry_obj_by_object_info(&mat, obj_info);
+ disp_manager.entry_obj_by_object_info(mat, obj_info);
}
}
else if (o->pattern.curve) {
sprintf_s(buf, sizeof(buf), "%.*s%03d",
uid_name_length - 3, uid_name, (int32_t)prj::roundf(o->pattern.value));
object_info obj_info = object_database_get_object_info(buf);
- disp_manager.entry_obj_by_object_info(&mat, obj_info);
+ disp_manager.entry_obj_by_object_info(mat, obj_info);
}
else
- disp_manager.entry_obj_by_object_info(&mat, o->object_info);
+ disp_manager.entry_obj_by_object_info(mat, o->object_info);
disp_manager.set_texture_transform();
disp_manager.set_texture_pattern();
disp_manager.set_obj_flags();
if (auth->pos)
- spr::put_rgb_cross(&o->model_transform.mat);
+ spr::put_rgb_cross(o->model_transform.mat);
for (auth_3d_object*& i : o->children_object)
implOfauth_3d_object_disp(i, auth);
@@ -1254,7 +1318,10 @@ HOOK(void, FASTCALL, auth_3d__disp, 0x00000001401D1230, auth_3d* auth) {
return;
auth_3d_set_material_list(auth);
+ extern bool reflect_full;
+ mdl::obj_reflect_enable = reflect_full && auth->reflect;
originalauth_3d__disp(auth);
+ mdl::obj_reflect_enable = false;
disp_manager->set_material_list();
}
@@ -1298,9 +1365,10 @@ void auth_3d_patch() {
// Move both auth_3d_curve's value and type
WRITE_MEMORY_STRING(0x00000001401B316A, "\x48\x8B\x43\x68\x48\x89"
"\x47\x68\x48\x8B\xC7\x48\x8B\x5C\x24\x48\x48\x83\xC4\x30\x5F\xC3", 0x16);
- // Null both auth_3d's shadow and chara_item
+ // Null auth_3d's shadow, chara_item and reflect
WRITE_MEMORY_STRING(0x00000001401D7A78, "\x44\x89\xBF\x98\x00\x00\x00", 0x07);
+ INSTALL_HOOK(auth_3d_parse);
INSTALL_HOOK(auth_3d_curve_array_free);
INSTALL_HOOK(auth_3d_m_object_hrc_disp);
INSTALL_HOOK(auth_3d_object_hrc_disp);
diff --git a/src/DivaGL/auth_3d.hpp b/src/DivaGL/auth_3d.hpp
index 975abd8..481f47a 100644
--- a/src/DivaGL/auth_3d.hpp
+++ b/src/DivaGL/auth_3d.hpp
@@ -59,6 +59,7 @@ struct auth_3d_id {
void set_max_frame(float_t value);
void set_paused(bool value);
void set_pos(int32_t value);
+ void set_reflect(bool value);
void set_repeat(bool value);
void set_req_frame(float_t value);
void set_shadow(bool value);
diff --git a/src/DivaGL/camera.cpp b/src/DivaGL/camera.cpp
index de69254..c5e6f9e 100644
--- a/src/DivaGL/camera.cpp
+++ b/src/DivaGL/camera.cpp
@@ -8,10 +8,10 @@
#include "resolution_mode.hpp"
#include
-camera_struct* camera_data = (camera_struct*)0x0000000140FBC2C0;
+camera_struct& camera_data = *(camera_struct*)0x0000000140FBC2C0;
-static void (FASTCALL* camera_struct__update_view)(camera_struct* cam)
- = (void (FASTCALL*)(camera_struct * cam))0x00000001401F7690;
+static void (FASTCALL* camera_struct__update_view)(camera_struct& cam)
+ = (void (FASTCALL*)(camera_struct & cam))0x00000001401F7690;
HOOK(void, FASTCALL, camera_data_update_projection, 0x00000001401F8E90) {
resolution_struct* res_wind = res_window_get();
@@ -22,15 +22,15 @@ HOOK(void, FASTCALL, camera_data_update_projection, 0x00000001401F8E90) {
float_t render_half_width = (float_t)res_wind_int->width * 0.5f;
float_t render_half_height = (float_t)res_wind_int->height * 0.5f;
- float_t aet_depth = camera_data->aet_depth;
+ float_t aet_depth = camera_data.aet_depth;
- float_t spr_2d_range = camera_data->min_distance / aet_depth;
+ float_t spr_2d_range = camera_data.min_distance / aet_depth;
float_t spr_2d_range_x = spr_2d_range * sprite_half_width;
float_t spr_2d_range_y = spr_2d_range * sprite_half_height;
mat4 spr_2d_proj;
mat4_frustrum(-spr_2d_range_x, spr_2d_range_x, spr_2d_range_y, -spr_2d_range_y,
- camera_data->min_distance, 3000.0f, &spr_2d_proj);
+ camera_data.min_distance, 3000.0f, &spr_2d_proj);
vec3 spr_2d_viewpoint = { sprite_half_width, sprite_half_height, aet_depth };
vec3 spr_2d_interest = { sprite_half_width, sprite_half_height, 0.0f };
@@ -39,17 +39,17 @@ HOOK(void, FASTCALL, camera_data_update_projection, 0x00000001401F8E90) {
mat4_look_at(&spr_2d_viewpoint, &spr_2d_interest, &spr_2d_up, &spr_2d_view);
mat4_mul(&spr_2d_view, &spr_2d_proj, &spr_2d_proj);
- mat4_transpose(&spr_2d_proj, &camera_data->view_projection_aet_2d);
+ mat4_transpose(&spr_2d_proj, &camera_data.view_projection_aet_2d);
- float_t aet_3d_depth = render_half_height / tanf(camera_data->aet_fov * 0.5f * DEG_TO_RAD_FLOAT);
+ float_t aet_3d_depth = render_half_height / tanf(camera_data.aet_fov * 0.5f * DEG_TO_RAD_FLOAT);
- float_t spr_3d_range = camera_data->min_distance / aet_3d_depth;
+ float_t spr_3d_range = camera_data.min_distance / aet_3d_depth;
float_t spr_3d_range_x = spr_3d_range * render_half_width;
float_t spr_3d_range_y = spr_3d_range * render_half_height;
mat4 spr_3d_proj;
mat4_frustrum(-spr_3d_range_x, spr_3d_range_x, spr_3d_range_y, -spr_3d_range_y,
- camera_data->min_distance, 3000.0f, &spr_3d_proj);
+ camera_data.min_distance, 3000.0f, &spr_3d_proj);
vec3 spr_3d_viewpoint = { render_half_width, render_half_height, aet_3d_depth };
vec3 spr_3d_interest = { render_half_width, render_half_height, 0.0f };
@@ -58,21 +58,21 @@ HOOK(void, FASTCALL, camera_data_update_projection, 0x00000001401F8E90) {
mat4_look_at(&spr_3d_viewpoint, &spr_3d_interest, &spr_3d_up, &spr_3d_view);
mat4_mul(&spr_3d_view, &spr_3d_proj, &spr_3d_proj);
- mat4_transpose(&spr_3d_proj, &camera_data->view_projection_aet_3d);
+ mat4_transpose(&spr_3d_proj, &camera_data.view_projection_aet_3d);
- render_get()->calc_projection_matrix(&camera_data->projection, camera_data->fov,
- (float_t)camera_data->aspect, camera_data->min_distance, camera_data->max_distance,
- camera_data->proj_left_offset, camera_data->proj_right_offset,
- camera_data->proj_bottom_offset, camera_data->proj_top_offset);
- camera_data->fov_horizontal_rad = tanf(camera_data->fov * 0.5f * DEG_TO_RAD_FLOAT);
+ render_get()->calc_projection_matrix(&camera_data.projection, camera_data.fov,
+ (float_t)camera_data.aspect, camera_data.min_distance, camera_data.max_distance,
+ camera_data.proj_left_offset, camera_data.proj_right_offset,
+ camera_data.proj_bottom_offset, camera_data.proj_top_offset);
+ camera_data.fov_horizontal_rad = tanf(camera_data.fov * 0.5f * DEG_TO_RAD_FLOAT);
}
HOOK(void, FASTCALL, camera_update, 0x00000001401F8970) {
implOfcamera_data_update_projection();
camera_struct__update_view(camera_data);
- camera_data->fast_change_hist1 = camera_data->fast_change_hist0;
- camera_data->fast_change_hist0 = camera_data->fast_change;
- camera_data->fast_change = false;
+ camera_data.fast_change_hist1 = camera_data.fast_change_hist0;
+ camera_data.fast_change_hist0 = camera_data.fast_change;
+ camera_data.fast_change = false;
}
void camera_struct::get_view_point(vec3& value) {
diff --git a/src/DivaGL/camera.hpp b/src/DivaGL/camera.hpp
index fa8ca7e..75428b6 100644
--- a/src/DivaGL/camera.hpp
+++ b/src/DivaGL/camera.hpp
@@ -59,6 +59,6 @@ struct camera_struct {
static void update_data();
};
-extern camera_struct* camera_data;
+extern camera_struct& camera_data;
extern void camera_patch();
diff --git a/src/DivaGL/data_test/rob_osage_test.cpp b/src/DivaGL/data_test/rob_osage_test.cpp
index 5edc2ce..ac28ae1 100644
--- a/src/DivaGL/data_test/rob_osage_test.cpp
+++ b/src/DivaGL/data_test/rob_osage_test.cpp
@@ -998,7 +998,7 @@ void RobOsageTest::disp_coli() {
etc.data.capsule.wire = false;
etc.data.capsule.pos[0] = j[-1].pos;
etc.data.capsule.pos[1] = j[ 0].pos;
- disp_manager->entry_obj_etc(&mat4_identity, &etc);
+ disp_manager->entry_obj_etc(mat4_identity, etc);
}
}
else if (cls && cls->rob.nodes.size() >= cls->rob.root_count) {
@@ -1022,7 +1022,7 @@ void RobOsageTest::disp_coli() {
mat4_translate(&pos, &mat);
mat4_transpose(&mat, &mat);
- disp_manager->entry_obj_etc(&mat, &etc);
+ disp_manager->entry_obj_etc(mat, etc);
}
}
}
@@ -1068,7 +1068,7 @@ void RobOsageTest::disp_coli_cls_list(ExNodeBlock* ex_node, SkinParam::Collision
mat4_translate(&pos, &mat);
mat4_transpose(&mat, &mat);
- disp_manager->entry_obj_etc(&mat, &etc);
+ disp_manager->entry_obj_etc(mat, etc);
} break;
case SkinParam::CollisionTypeCapsule: {
mdl::EtcObj etc(mdl::ETC_OBJ_CAPSULE);
@@ -1086,7 +1086,7 @@ void RobOsageTest::disp_coli_cls_list(ExNodeBlock* ex_node, SkinParam::Collision
mat4_transpose(&transform[i.node_idx[1]], &mat);
mat4_transform_point(&mat, &i.pos[1], &etc.data.capsule.pos[1]);
mat4_transpose(&mat, &mat);
- disp_manager->entry_obj_etc(&mat4_identity, &etc);
+ disp_manager->entry_obj_etc(mat4_identity, etc);
} break;
case SkinParam::CollisionTypePlane: {
mdl::EtcObj etc(mdl::ETC_OBJ_PLANE);
@@ -1105,7 +1105,7 @@ void RobOsageTest::disp_coli_cls_list(ExNodeBlock* ex_node, SkinParam::Collision
const vec3 up = { 0.0f, 1.0f, 0.0f };
vec3 axis;
float_t angle;
- Glitter::axis_angle_from_vectors(&axis, &angle, &up, &dir);
+ Glitter::axis_angle_from_vectors(axis, angle, up, dir);
mat4 mat_rot = mat4_identity;
mat4_mul_rotation(&mat_rot, &axis, angle, &mat_rot);
@@ -1114,7 +1114,7 @@ void RobOsageTest::disp_coli_cls_list(ExNodeBlock* ex_node, SkinParam::Collision
mat4_mul(&mat_rot, &mat, &mat);
mat4_scale_rot(&mat, i.radius, &mat);
mat4_transpose(&mat, &mat);
- disp_manager->entry_obj_etc(&mat, &etc);
+ disp_manager->entry_obj_etc(mat, etc);
} break;
case SkinParam::CollisionTypeEllipse: {
mdl::EtcObj etc(mdl::ETC_OBJ_SPHERE);
@@ -1140,7 +1140,7 @@ void RobOsageTest::disp_coli_cls_list(ExNodeBlock* ex_node, SkinParam::Collision
const vec3 up = { 0.0f, 1.0f, 0.0f };
vec3 axis;
float_t angle;
- Glitter::axis_angle_from_vectors(&axis, &angle, &up, &dir);
+ Glitter::axis_angle_from_vectors(axis, angle, up, dir);
mat4 m = mat4_identity;
mat4_mul_rotation(&m, &axis, angle, &m);
@@ -1151,7 +1151,7 @@ void RobOsageTest::disp_coli_cls_list(ExNodeBlock* ex_node, SkinParam::Collision
mat4_scale_rot(&mat, i.radius, scale_y, i.radius, &mat);
mat4_transpose(&mat, &mat);
- disp_manager->entry_obj_etc(&mat, &etc);
+ disp_manager->entry_obj_etc(mat, etc);
} break;
case SkinParam::CollisionTypeAABB: {
mdl::EtcObj etc(mdl::ETC_OBJ_CUBE);
@@ -1168,7 +1168,7 @@ void RobOsageTest::disp_coli_cls_list(ExNodeBlock* ex_node, SkinParam::Collision
mat4_translate(&pos, &mat);
mat4_transpose(&mat, &mat);
- disp_manager->entry_obj_etc(&mat, &etc);
+ disp_manager->entry_obj_etc(mat, etc);
} break;
}
}
@@ -1193,9 +1193,9 @@ void RobOsageTest::disp_line() {
mat4_scale_rot(&mat, 0.05f, &mat);
mat4_transpose(&mat, &mat);
if (i == ex_node)
- spr::put_cross(&mat, color_red, color_green, color_blue);
+ spr::put_cross(mat, color_red, color_green, color_blue);
else
- spr::put_cross(&mat, color_dark_red, color_dark_green, color_dark_blue);
+ spr::put_cross(mat, color_dark_red, color_dark_green, color_dark_blue);
const color4u8 line_color = i == ex_node ? color_white : color_dark_cyan;
const color4u8 rect_color = i == ex_node ? color_red : color_dark_red;
@@ -1212,7 +1212,7 @@ void RobOsageTest::disp_line() {
mat4_transpose(i->rob.end_node.bone_node_mat, &mat);
mat4_scale_rot(&mat, 0.05f, &mat);
mat4_transpose(&mat, &mat);
- spr::put_cross(&mat, color_dark_red, color_dark_green, color_dark_blue);
+ spr::put_cross(mat, color_dark_red, color_dark_green, color_dark_blue);
}
for (ExClothBlock*& i : itm_eq_obj->cloth_blocks) {
@@ -1285,7 +1285,7 @@ void RobOsageTest::disp_line_cls_param(const mat4& transform, const vec3& pos) {
mat4_transpose(&transform, &mat);
mat4_scale_rot(&mat, 0.1f, &mat);
mat4_transpose(&mat, &mat);
- spr::put_cross(&mat, color_red, color_green, color_blue);
+ spr::put_cross(mat, color_red, color_green, color_blue);
vec3 p;
mat4_transform_point(&transform, &pos, &p);
diff --git a/src/DivaGL/dllmain.cpp b/src/DivaGL/dllmain.cpp
index 42cf64e..9c8a19f 100644
--- a/src/DivaGL/dllmain.cpp
+++ b/src/DivaGL/dllmain.cpp
@@ -18,6 +18,7 @@ size_t opengl32_handle;
size_t dll_handle;
bool cpu_caps_aes_ni;
bool cpu_caps_f16c;
+bool config_reflect_full = true;
void FASTCALL divagl_main() {
int32_t cpuid_data[4] = {};
diff --git a/src/DivaGL/effect.cpp b/src/DivaGL/effect.cpp
index 6f36f30..688c6b9 100644
--- a/src/DivaGL/effect.cpp
+++ b/src/DivaGL/effect.cpp
@@ -554,7 +554,7 @@ void leaf_particle_draw() {
shader_data.g_transform[1] = temp.row1;
shader_data.g_transform[2] = temp.row2;
shader_data.g_transform[3] = temp.row3;
- camera_data->get_view_point(shader_data.g_view_pos);
+ camera_data.get_view_point(shader_data.g_view_pos);
shader_data.g_color = stage_param_data_leaf_current->color;
rctx->get_scene_light(&shader_data.g_light_env_stage_diffuse,
&shader_data.g_light_env_stage_specular,
@@ -662,7 +662,7 @@ void particle_draw() {
shader_data.g_transform[1] = temp.row1;
shader_data.g_transform[2] = temp.row2;
shader_data.g_transform[3] = temp.row3;
- camera_data->get_view_point(shader_data.g_view_pos);
+ camera_data.get_view_point(shader_data.g_view_pos);
light_chara.get_diffuse(shader_data.g_light_env_chara_diffuse);
light_chara.get_specular(shader_data.g_light_env_chara_specular);
particle_scene_ubo.WriteMemory(shader_data);
@@ -690,7 +690,7 @@ void snow_particle_draw() {
gl_state_enable_depth_test();
gl_state_set_depth_mask(GL_FALSE);
- float_t point_attenuation = powf(tanf((float_t)camera_data->fov
+ float_t point_attenuation = powf(tanf((float_t)camera_data.fov
* 0.5f * DEG_TO_RAD_FLOAT) * 3.4f, 2.0f) * 0.1f;
snow_particle_scene_shader_data snow_scene = {};
@@ -741,7 +741,7 @@ void snow_particle_draw() {
snow_particle_scene_ubo.Bind(0);
snow_particle_batch_ubo.Bind(1);
- point_attenuation = powf(tanf((float_t)camera_data->fov
+ point_attenuation = powf(tanf((float_t)camera_data.fov
* 0.5f * DEG_TO_RAD_FLOAT) * 3.4f, 2.0f) * 0.06f;
snow_scene.g_state_point_attenuation = { 0.0f, 0.0f, point_attenuation, 0.0f };
@@ -794,7 +794,7 @@ HOOK(void, FASTCALL, EffectFogRing__dest, 0x0000000140348090, EffectFogRing* fog
HOOK(void, FASTCALL, EffectFogRing__disp, 0x0000000140348120, EffectFogRing* fog_ring) {
if (fog_ring->enable && fog_ring->display)
- disp_manager->entry_obj_user(&mat4_identity,
+ disp_manager->entry_obj_user(mat4_identity,
(mdl::UserArgsFunc)draw_fog_particle, fog_ring, mdl::OBJ_TYPE_USER);
}
@@ -1074,7 +1074,7 @@ HOOK(void, FASTCALL, EffectRipple__draw_static, 0x000000014035AA50, void* data)
HOOK(void, FASTCALL, EffectRipple__disp_particles, 0x000000014035AD80,
EffectRipple* effect_ripple, ripple_struct* data) {
if (data->count > 0)
- disp_manager->entry_obj_user(&mat4_identity,
+ disp_manager->entry_obj_user(mat4_identity,
(mdl::UserArgsFunc)draw_ripple_particles, data, mdl::OBJ_TYPE_USER);
}
@@ -1329,7 +1329,7 @@ HOOK(void, FASTCALL, water_particle__disp, 0x0000000140364090, water_particle* w
if (!water_ptcl->splash)
return;
- disp_manager->entry_obj_user(&mat4_identity,
+ disp_manager->entry_obj_user(mat4_identity,
(mdl::UserArgsFunc)draw_water_particle, water_ptcl, mdl::OBJ_TYPE_TRANSLUCENT);
EffectRipple* effect_ripple = effect_ripple_data_get();
@@ -1406,7 +1406,7 @@ void EffectFogRing::draw() {
return;
draw_state.set_fog_height(true);
- RenderTexture& rt = render_manager->get_render_texture(8);
+ RenderTexture& rt = render_manager.get_render_texture(8);
rt.Bind();
gl_state_set_viewport(0, 0,
rt.color_texture->get_width_align_mip_level(),
@@ -1416,7 +1416,7 @@ void EffectFogRing::draw() {
if (disp_manager->get_obj_count(mdl::OBJ_TYPE_USER))
disp_manager->draw(mdl::OBJ_TYPE_USER);
gl_state_bind_framebuffer(0);
- render_manager->set_effect_texture(rt.color_texture);
+ render_manager.set_effect_texture(rt.color_texture);
gl_state_get_error();
}
@@ -1475,7 +1475,7 @@ void EffectRipple::draw() {
RenderTexture* rt[3];
for (int32_t i = 0, j = 2; i < 3; i++, j++)
- rt[i] = &render_manager->get_render_texture(
+ rt[i] = &render_manager.get_render_texture(
use_float_ripplemap ? j : (j + 3));
if (update) {
@@ -1522,8 +1522,8 @@ void EffectRipple::draw() {
if (!use_float_ripplemap)
v11 += 3;
- render_manager->set_effect_texture(
- render_manager->get_render_texture(v11).color_texture);
+ render_manager.set_effect_texture(
+ render_manager.get_render_texture(v11).color_texture);
update = false;
@@ -2016,7 +2016,7 @@ static void draw_ripple_particles(ripple_struct* data, mat4* mat) {
int32_t size = (int32_t)(data->size + 0.5f);
- RenderTexture& rt = render_manager->get_render_texture(
+ RenderTexture& rt = render_manager.get_render_texture(
effect_ripple_data_get()->use_float_ripplemap ? 2 : 5);
int32_t width = rt.GetWidth();
int32_t height = rt.GetHeight();
diff --git a/src/DivaGL/graphics/color_change_dw.cpp b/src/DivaGL/graphics/color_change_dw.cpp
index e70cb41..e6651e5 100644
--- a/src/DivaGL/graphics/color_change_dw.cpp
+++ b/src/DivaGL/graphics/color_change_dw.cpp
@@ -145,7 +145,7 @@ HOOK(void, FASTCALL, ColorChangeDw__Draw, 0x00000001402C2170, ColorChangeDw* Thi
args.texture = org_tex;
if (This->auto_resize)
args.SetSpriteSize({ 256.0f, 256.0f });
- spr::put_sprite(&args);
+ spr::put_sprite(args);
}
if (chg_tex) {
@@ -156,7 +156,7 @@ HOOK(void, FASTCALL, ColorChangeDw__Draw, 0x00000001402C2170, ColorChangeDw* Thi
args.SetSpriteSize({ 256.0f, 256.0f });
args.trans.x = 266.0f;
}
- spr::put_sprite(&args);
+ spr::put_sprite(args);
}
}
diff --git a/src/DivaGL/hook.cpp b/src/DivaGL/hook.cpp
index aed5f39..40f5d35 100644
--- a/src/DivaGL/hook.cpp
+++ b/src/DivaGL/hook.cpp
@@ -75,6 +75,7 @@ HOOK(int32_t, FASTCALL, data_init, 0x0000000140192FF0) {
Glitter::Patch();
rctx = new render_context;
+ reflect_full_init();
int32_t ret = originaldata_init();
extern size_t diva_handle;
@@ -98,6 +99,7 @@ HOOK(int32_t, FASTCALL, data_free, 0x000000140192490) {
rctx->free();
int32_t ret = originaldata_free();
+ reflect_full_free();
delete rctx;
rctx = 0;
return ret;
@@ -156,20 +158,20 @@ HOOK(void, FASTCALL, rndr__Render__movie_texture_free, 0x00000001404B18F0,
HOOK(void, FASTCALL, rndr__RenderManager__rndpass_pre_proc, 0x0000000140502C90) {
gl_state_begin_event("rndpass_pre_proc");
- render_manager->render->pre_proc();
+ render_manager.render->pre_proc();
Glitter::glt_particle_manager->CalcDisp();
Glitter::glt_particle_manager_x->CalcDisp();
gl_state_end_event();
}
HOOK(void, FASTCALL, rndr__RenderManager__render_all, 0x0000000140502CA0) {
- render_manager->render_all();
+ render_manager.render_all();
}
HOOK(void, FASTCALL, rndr__RenderManager__rndpass_post_proc, 0x0000000140502C70) {
gl_state_begin_event("rndpass_post_proc");
- render_manager->render->post_proc();
- render_manager->field_31C = false;
+ render_manager.render->post_proc();
+ render_manager.field_31C = false;
gl_state_end_event();
}
diff --git a/src/DivaGL/mdl/disp_manager.cpp b/src/DivaGL/mdl/disp_manager.cpp
index 96bb126..f69ad0d 100644
--- a/src/DivaGL/mdl/disp_manager.cpp
+++ b/src/DivaGL/mdl/disp_manager.cpp
@@ -45,6 +45,9 @@ static void object_data_get_vertex_attrib_buffer_bindings(const mdl::ObjSubMeshA
static void sub_140436760(mat4* view);
+extern bool reflect_draw;
+extern mat4 reflect_mat;
+
material_list_struct::material_list_struct() : blend_color(), has_blend_color(), emission(), has_emission() {
hash = (uint64_t)-1;
}
@@ -79,6 +82,9 @@ namespace mdl {
int32_t material_list_count;
material_list_struct material_list_array[MATERIAL_LIST_COUNT];
+
+ bool obj_reflect_enable;
+
ObjSubMeshArgs::ObjSubMeshArgs() : sub_mesh(), mesh(), material(), textures(), mat_count(), mats(),
vertex_buffer(), vertex_buffer_offset(), index_buffer(), set_blend_color(), chara_color(), self_shadow(),
shadow(), morph_vertex_buffer(), morph_vertex_buffer_offset(), morph_weight(), texture_pattern_count(),
@@ -213,23 +219,22 @@ namespace mdl {
}
- void ObjData::init_etc(const mat4* mat, mdl::EtcObj* etc) {
+ void ObjData::init_etc(const mat4& mat, const mdl::EtcObj& etc) {
kind = mdl::OBJ_KIND_ETC;
- mat4_transpose(mat, &this->mat);
- args.etc = *etc;
+ mat4_transpose(&mat, &this->mat);
+ args.etc = etc;
disp_manager->add_vertex_array(&args.etc, this->mat);
}
- void ObjData::init_sub_mesh(const mat4* mat, float_t radius,
- const obj_sub_mesh* sub_mesh, const obj_mesh* mesh, const obj_material_data* material,
- const prj::vector* textures, int32_t mat_count, const mat4* mats,
- GLuint vertex_buffer, size_t vertex_buffer_offset, GLuint index_buffer,
- const vec4& blend_color, const vec4& emission, GLuint morph_vertex_buffer,
- size_t morph_vertex_buffer_offset, int32_t instances_count, mat4* instances_mat,
- void(FASTCALL* func)(const ObjSubMeshArgs*), const ObjSubMeshArgs* func_data) {
+ void ObjData::init_sub_mesh(const mat4& mat, float_t radius, const obj_sub_mesh* sub_mesh,
+ const obj_mesh* mesh, const obj_material_data* material, const prj::vector* textures,
+ int32_t mat_count, const mat4* mats, GLuint vertex_buffer, size_t vertex_buffer_offset,
+ GLuint index_buffer, const vec4& blend_color, const vec4& emission, GLuint morph_vertex_buffer,
+ size_t morph_vertex_buffer_offset,
+ int32_t instances_count, const mat4* instances_mat, draw_func func, const ObjSubMeshArgs* func_data) {
kind = mdl::OBJ_KIND_NORMAL;
- mat4_transpose(mat, &this->mat);
+ mat4_transpose(&mat, &this->mat);
this->radius = radius;
mdl::ObjSubMeshArgs* args = &this->args.sub_mesh;
@@ -284,15 +289,15 @@ namespace mdl {
disp_manager->add_vertex_array(args);
}
- void ObjData::init_translucent(const mat4* mat, ObjTranslucentArgs* translucent) {
+ void ObjData::init_translucent(const mat4& mat, const ObjTranslucentArgs& translucent) {
kind = mdl::OBJ_KIND_TRANSLUCENT;
- mat4_transpose(mat, &this->mat);
- args.translucent = *translucent;
+ mat4_transpose(&mat, &this->mat);
+ args.translucent = translucent;
}
- void ObjData::init_user(const mat4* mat, UserArgsFunc func, void* data) {
+ void ObjData::init_user(const mat4& mat, UserArgsFunc func, void* data) {
kind = OBJ_KIND_USER;
- mat4_transpose(mat, &this->mat);
+ mat4_transpose(&mat, &this->mat);
args.user.func = func;
args.user.data = data;
}
@@ -1549,7 +1554,7 @@ namespace mdl {
const vec3 up = { 0.0f, 1.0f, 0.0f };
vec3 axis;
float_t angle;
- Glitter::axis_angle_from_vectors(&axis, &angle, &up, &dir);
+ Glitter::axis_angle_from_vectors(axis, angle, up, dir);
mat4 m = mat4_identity;
mat4_mul_rotation(&m, &axis, angle, &m);
@@ -1570,7 +1575,7 @@ namespace mdl {
const vec3 up = { 0.0f, 1.0f, 0.0f };
vec3 axis;
float_t angle;
- Glitter::axis_angle_from_vectors(&axis, &angle, &up, &dir);
+ Glitter::axis_angle_from_vectors(axis, angle, up, dir);
mat4 m = mat4_identity;
mat4_mul_rotation(&m, &axis, angle, &m);
@@ -1923,7 +1928,7 @@ namespace mdl {
mat4 mat;
mat4_translate(&i, &mat);
mat4_transpose(&mat, &mat);
- entry_obj_etc(&mat, &etc);
+ entry_obj_etc(mat, etc);
}
if (show_mat_center && type == OBJ_TYPE_TRANSLUCENT)
@@ -1938,7 +1943,7 @@ namespace mdl {
mat4 mat;
mat4_translate(&i, &mat);
mat4_transpose(&mat, &mat);
- entry_obj_etc(&mat, &etc);
+ entry_obj_etc(mat, etc);
}
}
@@ -1972,7 +1977,7 @@ namespace mdl {
}
void DispManager::draw(ObjType type, int32_t depth_mask, bool reflect_texture_mask, int32_t alpha) {
- if (type < 0 || type >= mdl::OBJ_TYPE_LOCAL_MAX || get_obj_count(type) < 1)
+ if (type < 0 || type >= OBJ_TYPE_REFLECT_MAX || get_obj_count(type) < 1)
return;
int32_t alpha_test = 0;
@@ -1997,6 +2002,7 @@ namespace mdl {
func = draw_sub_mesh_translucent;
else
gl_state_set_depth_mask(GL_FALSE);
+
alpha_test = 1;
min_alpha = 0.0f;
alpha_threshold = 0.0f;
@@ -2022,48 +2028,79 @@ namespace mdl {
func = draw_sub_mesh_translucent;
gl_state_set_color_mask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
draw_state.shader_index = SHADER_FT_SIL;
+
alpha_test = 1;
min_alpha = 0.0f;
alpha_threshold = 0.99999994f;
break;
case OBJ_TYPE_REFLECT_CHARA_OPAQUE:
gl_state_set_cull_face_mode(GL_FRONT);
- if (reflect)
- func = draw_sub_mesh_reflect;
- else if (render_manager->reflect_type == STAGE_DATA_REFLECT_REFLECT_MAP)
- func = draw_sub_mesh_reflect_reflect_map;
+
+ if (!reflect_draw) {
+ if (reflect)
+ func = draw_sub_mesh_reflect;
+ else if (render_manager.reflect_type == STAGE_DATA_REFLECT_REFLECT_MAP)
+ func = draw_sub_mesh_reflect_reflect_map;
+ }
break;
case OBJ_TYPE_REFLECT_CHARA_TRANSLUCENT:
gl_state_set_cull_face_mode(GL_FRONT);
- if (reflect)
- func = draw_sub_mesh_reflect;
- else if (render_manager->reflect_type == STAGE_DATA_REFLECT_REFLECT_MAP)
- func = draw_sub_mesh_reflect_reflect_map;
+
min_alpha = 0.0f;
+
+ if (!reflect_draw) {
+ if (reflect)
+ func = draw_sub_mesh_reflect;
+ else if (render_manager.reflect_type == STAGE_DATA_REFLECT_REFLECT_MAP)
+ func = draw_sub_mesh_reflect_reflect_map;
+ }
break;
case OBJ_TYPE_REFLECT_CHARA_TRANSPARENT:
gl_state_set_cull_face_mode(GL_FRONT);
- if (reflect)
- func = draw_sub_mesh_reflect;
- else if (render_manager->reflect_type == STAGE_DATA_REFLECT_REFLECT_MAP)
- func = draw_sub_mesh_reflect_reflect_map;
+
alpha_test = 1;
min_alpha = 0.1f;
alpha_threshold = 0.5f;
+
+ if (!reflect_draw) {
+ if (reflect)
+ func = draw_sub_mesh_reflect;
+ else if (render_manager.reflect_type == STAGE_DATA_REFLECT_REFLECT_MAP)
+ func = draw_sub_mesh_reflect_reflect_map;
+ }
break;
case OBJ_TYPE_REFLECT_OPAQUE:
alpha_test = 1;
alpha_threshold = 0.5f;
- if (!reflect_texture_mask)
+
+ if (reflect_draw)
+ gl_state_set_cull_face_mode(GL_FRONT);
+ else if (!reflect_texture_mask)
func = draw_sub_mesh_reflect_reflect_map;
break;
case OBJ_TYPE_REFLECT_TRANSLUCENT:
+ gl_state_set_depth_mask(GL_FALSE);
+
+ min_alpha = 0.0f;
+ alpha_threshold = 0.0f;
+
+ if (reflect_draw)
+ gl_state_set_cull_face_mode(GL_FRONT);
+ break;
+ case OBJ_TYPE_REFLECT_TRANSPARENT:
+ alpha_test = 1;
+ min_alpha = 0.1f;
+ alpha_threshold = 0.5f;
+
+ if (reflect_draw)
+ gl_state_set_cull_face_mode(GL_FRONT);
+ break;
case OBJ_TYPE_REFRACT_TRANSLUCENT:
gl_state_set_depth_mask(GL_FALSE);
+
min_alpha = 0.0f;
alpha_threshold = 0.0f;
break;
- case OBJ_TYPE_REFLECT_TRANSPARENT:
case OBJ_TYPE_REFRACT_TRANSPARENT:
alpha_test = 1;
min_alpha = 0.1f;
@@ -2071,9 +2108,9 @@ namespace mdl {
break;
case OBJ_TYPE_SSS:
func = draw_sub_mesh_sss;
- break;
- case OBJ_TYPE_USER:
- func = draw_sub_mesh_translucent;
+
+ if (reflect_draw)
+ gl_state_set_cull_face_mode(GL_FRONT);
break;
case OBJ_TYPE_TRANSPARENT_ALPHA_ORDER_1:
case OBJ_TYPE_TRANSPARENT_ALPHA_ORDER_2:
@@ -2088,11 +2125,25 @@ namespace mdl {
case OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_3:
case OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_2_LOCAL:
gl_state_set_depth_mask(GL_FALSE);
+
alpha_test = 1;
min_alpha = 0.0f;
alpha_threshold = 0.0f;
break;
- default:
+ case OBJ_TYPE_USER:
+ func = draw_sub_mesh_translucent;
+ break;
+ case OBJ_TYPE_REFLECT_TRANSLUCENT_SORT_BY_RADIUS:
+ if (depth_mask)
+ func = draw_sub_mesh_translucent;
+ else
+ gl_state_set_depth_mask(GL_FALSE);
+
+ alpha_test = 1;
+ min_alpha = 0.0f;
+ alpha_threshold = 0.0f;
+
+ gl_state_set_cull_face_mode(GL_FRONT);
break;
}
rctx->set_batch_alpha_threshold(alpha_threshold);
@@ -2141,8 +2192,6 @@ namespace mdl {
switch (type) {
case OBJ_TYPE_TRANSLUCENT:
case OBJ_TYPE_TRANSLUCENT_SORT_BY_RADIUS:
- case OBJ_TYPE_REFLECT_TRANSLUCENT:
- case OBJ_TYPE_REFRACT_TRANSLUCENT:
if (!depth_mask)
gl_state_set_depth_mask(GL_TRUE);
break;
@@ -2156,16 +2205,36 @@ namespace mdl {
case OBJ_TYPE_REFLECT_CHARA_TRANSPARENT:
gl_state_set_cull_face_mode(GL_BACK);
break;
- case OBJ_TYPE_TRANSPARENT_ALPHA_ORDER_1:
- case OBJ_TYPE_TRANSPARENT_ALPHA_ORDER_2:
- case OBJ_TYPE_TRANSPARENT_ALPHA_ORDER_3:
- gl_state_set_cull_face_mode(GL_BACK);
+ case OBJ_TYPE_REFLECT_OPAQUE:
+ if (reflect_draw)
+ gl_state_set_cull_face_mode(GL_FRONT);
+ break;
+ case OBJ_TYPE_REFLECT_TRANSLUCENT:
+ if (reflect_draw)
+ gl_state_set_cull_face_mode(GL_FRONT);
+ gl_state_set_depth_mask(GL_TRUE);
+ break;
+ case OBJ_TYPE_REFLECT_TRANSPARENT:
+ if (reflect_draw)
+ gl_state_set_cull_face_mode(GL_FRONT);
+ break;
+ case OBJ_TYPE_REFRACT_TRANSLUCENT:
+ if (reflect_draw)
+ gl_state_set_cull_face_mode(GL_FRONT);
+ gl_state_set_depth_mask(GL_TRUE);
+ break;
+ case OBJ_TYPE_SSS:
+ if (reflect_draw)
+ gl_state_set_cull_face_mode(GL_BACK);
break;
case OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_1:
case OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_2:
case OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_3:
gl_state_set_depth_mask(GL_TRUE);
break;
+ case OBJ_TYPE_REFLECT_TRANSLUCENT_SORT_BY_RADIUS:
+ gl_state_set_cull_face_mode(GL_BACK);
+ break;
}
uniform_value_reset();
@@ -2211,7 +2280,7 @@ namespace mdl {
}
static int32_t obj_axis_aligned_bounding_box_check_visibility(
- obj_axis_aligned_bounding_box* aabb, const mat4* mat) {
+ obj_axis_aligned_bounding_box* aabb, const mat4& mat) {
vec3 points[8];
points[0] = aabb->center + (aabb->size ^ vec3( 0.0f, 0.0f, 0.0f));
points[1] = aabb->center + (aabb->size ^ vec3(-0.0f, -0.0f, -0.0f));
@@ -2223,7 +2292,7 @@ namespace mdl {
points[7] = aabb->center + (aabb->size ^ vec3(-0.0f, -0.0f, 0.0f));
mat4 view_mat;
- mat4_mul(&camera_data->view, mat, &view_mat);
+ mat4_mul(&camera_data.view, &mat, &view_mat);
mat4_transpose(&view_mat, &view_mat);
for (int32_t i = 0; i < 8; i++)
@@ -2231,17 +2300,17 @@ namespace mdl {
vec4 v2[6];
*(vec3*)&v2[0] = { 0.0f, 0.0f, -1.0f };
- v2[0].w = -camera_data->min_distance;
- *(vec3*)&v2[1] = camera_data->field_1E4;
+ v2[0].w = -camera_data.min_distance;
+ *(vec3*)&v2[1] = camera_data.field_1E4;
v2[1].w = 0.0f;
- *(vec3*)&v2[2] = camera_data->field_1F0;
+ *(vec3*)&v2[2] = camera_data.field_1F0;
v2[2].w = 0.0f;
- *(vec3*)&v2[3] = camera_data->field_1FC;
+ *(vec3*)&v2[3] = camera_data.field_1FC;
v2[3].w = 0.0f;
- *(vec3*)&v2[4] = camera_data->field_208;
+ *(vec3*)&v2[4] = camera_data.field_208;
v2[4].w = 0.0f;
*(vec3*)&v2[5] = { 0.0f, 0.0f, 1.0f };
- v2[5].w = camera_data->max_distance;
+ v2[5].w = camera_data.max_distance;
for (int32_t i = 0; i < 6; i++)
for (int32_t j = 0; j < 8; j++) {
@@ -2255,82 +2324,90 @@ namespace mdl {
return 1;
}
- static int32_t obj_bounding_sphere_check_visibility(obj_bounding_sphere* sphere,
- CullingCheck* culling, const mat4* mat) {
+ static int32_t obj_bounding_sphere_check_visibility(const obj_bounding_sphere& sphere,
+ CullingCheck* culling, const mat4& mat) {
if (disp_manager->culling_func)
- return disp_manager->culling_func(sphere);
+ return disp_manager->culling_func(&sphere);
vec3 center;
mat4 _mat;
- mat4_transpose(mat, &_mat);
- mat4_transform_point(&_mat, &sphere->center, ¢er);
- float_t radius = mat4_get_max_scale(&_mat) * sphere->radius;
+ mat4_transpose(&mat, &_mat);
+ mat4_transform_point(&_mat, &sphere.center, ¢er);
+ float_t radius = mat4_get_max_scale(&_mat) * sphere.radius;
- mat4_transpose(&camera_data->view, &_mat);
+ mat4_transpose(&camera_data.view, &_mat);
mat4_transform_point(&_mat, ¢er, ¢er);
double_t min_depth = (double_t)center.z - (double_t)radius;
double_t max_depth = (double_t)center.z + (double_t)radius;
- if (-camera_data->min_distance < min_depth || -camera_data->max_distance > max_depth)
+ if (-camera_data.min_distance < min_depth || -camera_data.max_distance > max_depth)
return 0;
- float_t v5 = vec3::dot(camera_data->field_1E4, center);
+ float_t v5 = vec3::dot(camera_data.field_1E4, center);
if (v5 < -radius)
return 0;
- float_t v6 = vec3::dot(camera_data->field_1F0, center);
+ float_t v6 = vec3::dot(camera_data.field_1F0, center);
if (v6 < -radius)
return 0;
- float_t v7 = vec3::dot(camera_data->field_1FC, center);
+ float_t v7 = vec3::dot(camera_data.field_1FC, center);
if (v7 < -radius)
return 0;
- float_t v8 = vec3::dot(camera_data->field_208, center);
+ float_t v8 = vec3::dot(camera_data.field_208, center);
if (v8 < -radius)
return 0;
- if (-camera_data->min_distance >= max_depth && -camera_data->max_distance <= min_depth
+ if (-camera_data.min_distance >= max_depth && -camera_data.max_distance <= min_depth
&& v5 >= radius && v6 >= radius && v7 >= radius && v8 >= radius)
return 1;
return 2;
}
- bool DispManager::entry_obj(::obj* obj, obj_mesh_vertex_buffer* obj_vertex_buf,
- obj_mesh_index_buffer* obj_index_buf, const mat4* mat,
- prj::vector* textures, vec4* blend_color, mat4* bone_mat, ::obj* object_morph,
- obj_mesh_vertex_buffer* obj_morph_vertex_buf, int32_t instances_count, mat4* instances_mat,
- void(*func)(const mdl::ObjSubMeshArgs*), const ObjSubMeshArgs* func_data,
- bool enable_bone_mat, bool local) {
- if (!obj_vertex_buf || !obj_index_buf)
+ bool DispManager::entry_obj(const ::obj* obj, const mat4& mat, obj_mesh_vertex_buffer* obj_vert_buf,
+ obj_mesh_index_buffer* obj_index_buf, const prj::vector* textures, const vec4* blend_color,
+ const mat4* bone_mat, const ::obj* obj_morph, obj_mesh_vertex_buffer* obj_morph_vert_buf,
+ int32_t instances_count, const mat4* instances_mat,
+ draw_func func, const ObjSubMeshArgs* func_data, bool enable_bone_mat, bool local) {
+ if (!obj_vert_buf || !obj_index_buf)
return false;
camera_struct::update_data();
+ mat4 _mat;
+ if (mdl::obj_reflect_enable) {
+ mat4_transpose(&mat, &_mat);
+ mat4_mul(&_mat, &reflect_mat, &_mat);
+ mat4_transpose(&_mat, &_mat);
+ }
+
if (!local && object_culling && !instances_count && !bone_mat && (!obj
|| !obj_bounding_sphere_check_visibility(
- &obj->bounding_sphere, &culling, mat))) {
+ obj->bounding_sphere, &culling, mat) && !(mdl::obj_reflect_enable
+ && obj_bounding_sphere_check_visibility(
+ obj->bounding_sphere, &culling, _mat)))) {
culling.culled.objects++;
return false;
}
culling.passed.objects++;
for (int32_t i = 0; i < obj->num_mesh; i++) {
- obj_mesh* mesh = &obj->mesh_array[i];
- obj_mesh* mesh_morph = 0;
- if (obj_vertex_buf && obj_morph_vertex_buf) {
- if (obj_vertex_buf[i].get_size() != obj_morph_vertex_buf[i].get_size())
+ const obj_mesh* mesh = &obj->mesh_array[i];
+ const obj_mesh* mesh_morph = 0;
+ if (obj_vert_buf && obj_morph_vert_buf) {
+ if (obj_vert_buf[i].get_size() != obj_morph_vert_buf[i].get_size())
continue;
- if (object_morph && i < object_morph->num_mesh)
- mesh_morph = &object_morph->mesh_array[i];
+ if (obj_morph && i < obj_morph->num_mesh)
+ mesh_morph = &obj_morph->mesh_array[i];
}
if (!local && object_culling && !instances_count && !bone_mat
&& !obj_bounding_sphere_check_visibility(
- &mesh->bounding_sphere, &culling, mat)
+ mesh->bounding_sphere, &culling, mat)
&& (!mesh_morph || !obj_bounding_sphere_check_visibility(
- &mesh_morph->bounding_sphere, &culling, mat))) {
+ mesh_morph->bounding_sphere, &culling, mat))) {
culling.culled.meshes++;
continue;
}
@@ -2340,15 +2417,16 @@ namespace mdl {
int32_t translucent_priority_count = 0;
for (int32_t j = 0; j < mesh->num_submesh; j++) {
- obj_sub_mesh* sub_mesh = &mesh->submesh_array[j];
- obj_sub_mesh* sub_mesh_morph = 0;
+ const obj_sub_mesh* sub_mesh = &mesh->submesh_array[j];
+ const obj_sub_mesh* sub_mesh_morph = 0;
if (sub_mesh->attrib.m.cloth)
continue;
if (!local && object_culling && !instances_count && !bone_mat) {
int32_t v32 = obj_bounding_sphere_check_visibility(
- &sub_mesh->bounding_sphere, &culling, mat);
- if (v32 != 2 || (!mesh->attrib.m.billboard && !mesh->attrib.m.billboard_y_axis)) {
+ sub_mesh->bounding_sphere, &culling, mat);
+ if (v32 != 2 || (!mesh->attrib.m.billboard && !mesh->attrib.m.billboard_y_axis
+ && !mesh->attrib.m.disable_aabb_culling)) {
if (v32 == 2) {
if (disp_manager->culling_func)
v32 = 1;
@@ -2359,18 +2437,18 @@ namespace mdl {
if (!v32) {
if (!mesh_morph || j >= mesh_morph->num_submesh) {
- culling.culled.submesh_array++;
+ culling.culled.sub_meshes++;
continue;
}
sub_mesh_morph = &mesh_morph->submesh_array[j];
if (!sub_mesh_morph) {
- culling.culled.submesh_array++;
+ culling.culled.sub_meshes++;
continue;
}
v32 = obj_bounding_sphere_check_visibility(
- &sub_mesh_morph->bounding_sphere, &culling, mat);
+ sub_mesh_morph->bounding_sphere, &culling, mat);
if (v32 == 2) {
if (disp_manager->culling_func)
v32 = 1;
@@ -2380,16 +2458,16 @@ namespace mdl {
}
if (!v32) {
- culling.culled.submesh_array++;
+ culling.culled.sub_meshes++;
continue;
}
}
}
}
- culling.passed.submesh_array++;
+ culling.passed.sub_meshes++;
int32_t num_bone_index = sub_mesh->num_bone_index;
- uint16_t* bone_index = sub_mesh->bone_index_array;
+ const uint16_t* bone_index = sub_mesh->bone_index_array;
mat4* mats;
if (num_bone_index && enable_bone_mat) {
@@ -2413,9 +2491,9 @@ namespace mdl {
GLuint morph_vertex_buffer = 0;
size_t morph_vertex_buffer_offset = 0;
- if (obj_morph_vertex_buf) {
- morph_vertex_buffer = obj_morph_vertex_buf[i].get_buffer();
- morph_vertex_buffer_offset = obj_morph_vertex_buf[i].get_offset();
+ if (obj_morph_vert_buf) {
+ morph_vertex_buffer = obj_morph_vert_buf[i].get_buffer();
+ morph_vertex_buffer_offset = obj_morph_vert_buf[i].get_offset();
}
GLuint index_buffer = 0;
@@ -2424,15 +2502,15 @@ namespace mdl {
GLuint vertex_buffer = 0;
size_t vertex_buffer_offset = 0;
- if (obj_vertex_buf) {
- vertex_buffer = obj_vertex_buf[i].get_buffer();
- vertex_buffer_offset = obj_vertex_buf[i].get_offset();
+ if (obj_vert_buf) {
+ vertex_buffer = obj_vert_buf[i].get_buffer();
+ vertex_buffer_offset = obj_vert_buf[i].get_offset();
}
- if (!vertex_buffer || !index_buffer || obj_morph_vertex_buf && !morph_vertex_buffer)
+ if (!vertex_buffer || !index_buffer || obj_morph_vert_buf && !morph_vertex_buffer)
continue;
- uint64_t material_hash = hash_utf8_fnv1a64m(material->material.name);
+ const uint64_t material_hash = hash_utf8_fnv1a64m(material->material.name);
material_list_struct* mat_list = 0;
for (int32_t k = 0; k < material_list_count; k++)
@@ -2515,13 +2593,13 @@ namespace mdl {
continue;
}
- obj_material_attrib_member attrib = material->material.attrib.m;
+ const obj_material_attrib_member attrib = material->material.attrib.m;
if (obj_flags & (mdl::OBJ_ALPHA_ORDER_1 | mdl::OBJ_ALPHA_ORDER_2 | mdl::OBJ_ALPHA_ORDER_3)
&& data->args.sub_mesh.blend_color.w < 1.0f) {
if (!(obj_flags & mdl::OBJ_NO_TRANSLUCENCY)) {
if (attrib.flag_28 || (attrib.punch_through
|| !(attrib.alpha_texture | attrib.alpha_material))
- && !sub_mesh->attrib.m.transparent) {
+ && !sub_mesh->attrib.m.translucent) {
if (!attrib.punch_through) {
if (obj_flags & mdl::OBJ_ALPHA_ORDER_1)
entry_list(OBJ_TYPE_OPAQUE_ALPHA_ORDER_1, data);
@@ -2557,7 +2635,7 @@ namespace mdl {
else {
if (attrib.flag_28 || data->args.sub_mesh.blend_color.w >= 1.0f
&& (attrib.punch_through || !(attrib.alpha_texture | attrib.alpha_material))
- && !sub_mesh->attrib.m.transparent) {
+ && !sub_mesh->attrib.m.translucent) {
if (obj_flags & mdl::OBJ_SHADOW)
entry_list((ObjType)(OBJ_TYPE_SHADOW_CHARA + shadow_type), data);
@@ -2623,7 +2701,7 @@ namespace mdl {
if (obj_flags & mdl::OBJ_CHARA_REFLECT)
entry_list(OBJ_TYPE_REFLECT_CHARA_OPAQUE, data);
if (obj_flags & mdl::OBJ_REFLECT) {
- if (render_manager->reflect_type != STAGE_DATA_REFLECT_REFLECT_MAP)
+ if (render_manager.reflect_type != STAGE_DATA_REFLECT_REFLECT_MAP)
entry_list(OBJ_TYPE_REFLECT_OPAQUE, data);
else
entry_list(OBJ_TYPE_REFLECT_TRANSLUCENT, data);
@@ -2653,7 +2731,7 @@ namespace mdl {
if (!data)
continue;
- data->init_translucent(mat, &translucent_args);
+ data->init_translucent(mat, translucent_args);
if (obj_flags & mdl::OBJ_ALPHA_ORDER_1)
entry_list(OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_1, data);
else if (obj_flags & mdl::OBJ_ALPHA_ORDER_2)
@@ -2665,27 +2743,289 @@ namespace mdl {
entry_list(local ? OBJ_TYPE_TRANSLUCENT_LOCAL
: OBJ_TYPE_TRANSLUCENT, data);
}
+
+ if (local || (obj_flags & mdl::OBJ_SHADOW_OBJECT)
+ || (obj_flags & (mdl::OBJ_ALPHA_ORDER_1 | mdl::OBJ_ALPHA_ORDER_2 | mdl::OBJ_ALPHA_ORDER_3)
+ && blend_color && blend_color->w < 1.0f))
+ return true;
+
+ mat4_transpose(&mat, &_mat);
+ mat4_mul(&_mat, &reflect_mat, &_mat);
+ mat4_transpose(&_mat, &_mat);
+
+ bool camera_front = vec3::normalize(camera_data.view_point - camera_data.interest).z >= 0.0f;
+
+ for (int32_t i = 0; i < obj->num_mesh; i++) {
+ const obj_mesh* mesh = &obj->mesh_array[i];
+ const obj_mesh* mesh_morph = 0;
+ if (!mdl::obj_reflect_enable && !mesh->attrib.m.reflect || mesh->attrib.m.no_reflect
+ || camera_front && mesh->attrib.m.reflect_cam_back)
+ continue;
+
+ if (obj_vert_buf && obj_morph_vert_buf) {
+ if (obj_vert_buf[i].get_size() != obj_morph_vert_buf[i].get_size())
+ continue;
+
+ if (obj_morph && i < obj_morph->num_mesh)
+ mesh_morph = &obj_morph->mesh_array[i];
+ }
+
+ if (object_culling && !instances_count && !bone_mat
+ && !obj_bounding_sphere_check_visibility(
+ mesh->bounding_sphere, &culling, _mat)
+ && (!mesh_morph || !obj_bounding_sphere_check_visibility(
+ mesh_morph->bounding_sphere, &culling, _mat))) {
+ culling.culled.meshes++;
+ continue;
+ }
+ culling.passed.meshes++;
+
+ ObjSubMeshArgs* translucent_priority[40];
+ int32_t translucent_priority_count = 0;
+
+ for (int32_t j = 0; j < mesh->num_submesh; j++) {
+ const obj_sub_mesh* sub_mesh = &mesh->submesh_array[j];
+ const obj_sub_mesh* sub_mesh_morph = 0;
+ if (sub_mesh->attrib.m.cloth || sub_mesh->attrib.m.no_reflect
+ || !mdl::obj_reflect_enable && !sub_mesh->attrib.m.reflect
+ || camera_front && sub_mesh->attrib.m.reflect_cam_back)
+ continue;
+
+ if (object_culling && !instances_count && !bone_mat) {
+ int32_t v32 = obj_bounding_sphere_check_visibility(
+ sub_mesh->bounding_sphere, &culling, _mat);
+ if (v32 != 2 || (!mesh->attrib.m.billboard && !mesh->attrib.m.billboard_y_axis
+ && !mesh->attrib.m.disable_aabb_culling)) {
+ if (v32 == 2) {
+ if (culling_func)
+ v32 = 1;
+ else {
+ obj_axis_aligned_bounding_box aabb = *sub_mesh->axis_aligned_bounding_box;
+ mat4_transform_point(&reflect_mat, &aabb.center, &aabb.center);
+ mat4_transform_vector(&reflect_mat, &aabb.size, &aabb.size);
+ v32 = obj_axis_aligned_bounding_box_check_visibility(&aabb, mat);
+ }
+ }
+
+ if (!v32) {
+ if (!mesh_morph || j >= mesh_morph->num_submesh) {
+ culling.culled.sub_meshes++;
+ continue;
+ }
+
+ sub_mesh_morph = &mesh_morph->submesh_array[j];
+ if (!sub_mesh_morph) {
+ culling.culled.sub_meshes++;
+ continue;
+ }
+
+ int32_t v32 = obj_bounding_sphere_check_visibility(
+ sub_mesh_morph->bounding_sphere, &culling, _mat);
+ if (v32 == 2) {
+ if (culling_func)
+ v32 = 1;
+ else {
+ obj_axis_aligned_bounding_box aabb = *sub_mesh_morph->axis_aligned_bounding_box;
+ mat4_transform_point(&reflect_mat, &aabb.center, &aabb.center);
+ mat4_transform_vector(&reflect_mat, &aabb.size, &aabb.size);
+ v32 = obj_axis_aligned_bounding_box_check_visibility(&aabb, mat);
+ }
+ }
+
+ if (!v32) {
+ culling.culled.sub_meshes++;
+ continue;
+ }
+ }
+ }
+ }
+ culling.passed.sub_meshes++;
+
+ int32_t num_bone_index = sub_mesh->num_bone_index;
+ const uint16_t* bone_index = sub_mesh->bone_index_array;
+
+ mat4* mats;
+ if (num_bone_index && enable_bone_mat) {
+ mats = alloc_mat4_array(num_bone_index);
+ if (bone_mat)
+ for (int32_t k = 0; k < num_bone_index; k++, bone_index++)
+ mat4_transpose(&bone_mat[*bone_index], &mats[k]);
+ else
+ for (int32_t k = 0; k < num_bone_index; k++)
+ mats[k] = mat4_identity;
+ }
+ else {
+ mats = 0;
+ num_bone_index = 0;
+ }
+
+ obj_material_data* material = &obj->material_array[sub_mesh->material_index];
+ ObjData* data = alloc_obj_data(OBJ_KIND_NORMAL);
+ if (!data)
+ continue;
+
+ GLuint morph_vertex_buffer = 0;
+ size_t morph_vertex_buffer_offset = 0;
+ if (obj_morph_vert_buf) {
+ morph_vertex_buffer = obj_morph_vert_buf[i].get_buffer();
+ morph_vertex_buffer_offset = obj_morph_vert_buf[i].get_offset();
+ }
+
+ GLuint index_buffer = 0;
+ if (obj_index_buf)
+ index_buffer = obj_index_buf[i].buffer;
+
+ GLuint vertex_buffer = 0;
+ size_t vertex_buffer_offset = 0;
+ if (obj_vert_buf) {
+ vertex_buffer = obj_vert_buf[i].get_buffer();
+ vertex_buffer_offset = obj_vert_buf[i].get_offset();
+ }
+
+ if (!vertex_buffer || !index_buffer || obj_morph_vert_buf && !morph_vertex_buffer)
+ continue;
+
+ const uint64_t material_hash = hash_utf8_fnv1a64m(material->material.name);
+
+ const material_list_struct* mat_list = 0;
+ for (int32_t k = 0; k < material_list_count; k++)
+ if (material_list_array[k].hash == material_hash) {
+ mat_list = &material_list_array[k];
+ break;
+ }
+
+ vec4 _blend_color = 1.0f;
+ vec4 _emission = { 0.0f, 0.0f, 0.0f, 1.0f };
+
+ if (mat_list) {
+ bool has_blend_color = false;
+ if (mat_list->has_blend_color.x) {
+ _blend_color.x = mat_list->blend_color.x;
+ has_blend_color = true;
+ }
+
+ if (mat_list->has_blend_color.y) {
+ _blend_color.y = mat_list->blend_color.y;
+ has_blend_color = true;
+ }
+
+ if (mat_list->has_blend_color.z) {
+ _blend_color.z = mat_list->blend_color.z;
+ has_blend_color = true;
+ }
+
+ if (mat_list->has_blend_color.w) {
+ _blend_color.w = mat_list->blend_color.w;
+ has_blend_color = true;
+ }
+
+ if (blend_color) {
+ if (!has_blend_color)
+ _blend_color = *blend_color;
+ else
+ _blend_color *= *blend_color;
+ }
+
+ bool has_emission = false;
+ if (mat_list->has_emission.x) {
+ _emission.x = mat_list->emission.x;
+ has_emission = true;
+ }
+
+ if (mat_list->has_emission.y) {
+ _emission.y = mat_list->emission.y;
+ has_emission = true;
+ }
+
+ if (mat_list->has_emission.z) {
+ _emission.z = mat_list->emission.z;
+ has_emission = true;
+ }
+
+ if (mat_list->has_emission.w) {
+ _emission.w = mat_list->emission.w;
+ has_emission = true;
+ }
+
+ if (!has_emission)
+ _emission = material->material.color.emission;
+ }
+ else {
+ if (blend_color)
+ _blend_color = *blend_color;
+ _emission = material->material.color.emission;
+ }
+
+ data->init_sub_mesh(mat, obj->bounding_sphere.radius, sub_mesh, mesh, material, textures,
+ num_bone_index, mats, vertex_buffer, vertex_buffer_offset, index_buffer, _blend_color, _emission,
+ morph_vertex_buffer, morph_vertex_buffer_offset, instances_count, instances_mat, func, func_data);
+
+ const obj_material_attrib_member attrib = material->material.attrib.m;
+ if (!attrib.flag_28 && (data->args.sub_mesh.blend_color.w < 1.0f
+ || !attrib.punch_through && attrib.alpha_texture | attrib.alpha_material
+ || sub_mesh->attrib.m.translucent)) {
+ if (!attrib.translucent_priority)
+ if (mesh->attrib.m.translucent_sort_by_radius
+ || obj_flags & mdl::OBJ_TRANSLUCENT_SORT_BY_RADIUS) {
+ DispManager::entry_list(OBJ_TYPE_REFLECT_TRANSLUCENT_SORT_BY_RADIUS, data);
+ }
+ else
+ DispManager::entry_list(OBJ_TYPE_REFLECT_TRANSLUCENT, data);
+ else if (translucent_priority_count < 40)
+ translucent_priority[translucent_priority_count++] = &data->args.sub_mesh;
+ }
+ else {
+ if (!(obj_flags & mdl::OBJ_NO_TRANSLUCENCY))
+ if (attrib.punch_through)
+ DispManager::entry_list(OBJ_TYPE_REFLECT_TRANSPARENT, data);
+ else
+ DispManager::entry_list(OBJ_TYPE_REFLECT_OPAQUE, data);
+ continue;
+ }
+ }
+
+ if (translucent_priority_count <= 0)
+ continue;
+
+ ObjTranslucentArgs translucent_args;
+ translucent_args.count = 0;
+ for (int32_t j = 62; j; j--)
+ for (int32_t k = 0; k < translucent_priority_count; k++) {
+ ObjSubMeshArgs* sub_mesh = translucent_priority[k];
+ if (sub_mesh->material->material.attrib.m.translucent_priority != j)
+ continue;
+
+ translucent_args.sub_mesh[translucent_args.count] = sub_mesh;
+ translucent_args.count++;
+ }
+
+ ObjData* data = DispManager::alloc_obj_data(mdl::OBJ_KIND_TRANSLUCENT);
+ if (data) {
+ data->init_translucent(mat, translucent_args);
+ DispManager::entry_list(OBJ_TYPE_TRANSLUCENT, data);
+ }
+ }
+
return true;
}
- void DispManager::entry_obj_by_obj(const mat4* mat,
- ::obj* obj, prj::vector* textures, obj_mesh_vertex_buffer* obj_vert_buf,
+ void DispManager::entry_obj_by_obj(const mat4& mat,
+ const ::obj* obj, prj::vector* textures, obj_mesh_vertex_buffer* obj_vert_buf,
obj_mesh_index_buffer* obj_index_buf, mat4* bone_mat, float_t alpha) {
if (!obj)
return;
- vec4 blend_color = { 1.0f, 1.0f, 1.0f, alpha };
- vec4* blend_color_ptr = alpha < 1.0f ? &blend_color : 0;
+ const vec4 blend_color(1.0f, 1.0f, 1.0f, alpha);
- entry_obj(obj, obj_vert_buf, obj_index_buf, mat, textures, blend_color_ptr,
- bone_mat, 0, 0, 0, 0, 0, 0, !!bone_mat);
+ entry_obj(obj, mat, obj_vert_buf, obj_index_buf, textures,
+ alpha < 1.0f ? &blend_color : 0, bone_mat, 0, 0, 0, 0, 0, 0, !!bone_mat);
}
#if SHARED_OBJECT_BUFFER
#pragma warning(push)
#pragma warning(disable: 6386)
- void DispManager::entry_obj_by_obj(const mat4* mat,
- ::obj* obj, prj::vector* textures, obj_mesh_vertex_buffer_aft* obj_vert_buf,
+ void DispManager::entry_obj_by_obj(const mat4& mat,
+ const ::obj* obj, prj::vector* textures, obj_mesh_vertex_buffer_aft* obj_vert_buf,
obj_mesh_index_buffer* obj_index_buf, mat4* bone_mat, float_t alpha) {
if (!obj)
return;
@@ -2709,23 +3049,23 @@ namespace mdl {
blend_color.w = alpha;
vec4* blend_color_ptr = alpha < 1.0f ? &blend_color : 0;
- disp_manager->entry_obj(obj, _obj_vert_buf, obj_index_buf, mat,
+ entry_obj(obj, mat, _obj_vert_buf, obj_index_buf,
textures, blend_color_ptr, bone_mat, 0, 0, 0, 0, 0, 0, 0, !!bone_mat);
_operator_delete(_obj_vert_buf);
}
#pragma warning(pop)
#endif
- bool DispManager::entry_obj_by_object_info(const mat4* mat, object_info obj_info) {
+ bool DispManager::entry_obj_by_object_info(const mat4& mat, object_info obj_info) {
return entry_obj_by_object_info(mat, obj_info, 0, 0, 0, 0, 0, 0, false);
}
- bool DispManager::entry_obj_by_object_info(const mat4* mat, object_info obj_info, mat4* bone_mat) {
+ bool DispManager::entry_obj_by_object_info(const mat4& mat, object_info obj_info, mat4* bone_mat) {
vec4 blend_color = 1.0f;
return entry_obj_by_object_info(mat, obj_info, &blend_color, bone_mat, 0, 0, 0, 0, true);
}
- bool DispManager::entry_obj_by_object_info(const mat4* mat, object_info obj_info,
+ bool DispManager::entry_obj_by_object_info(const mat4& mat, object_info obj_info,
vec4* blend_color, mat4* bone_mat, int32_t instances_count, mat4* instances_mat,
void(*func)(const ObjSubMeshArgs*), const ObjSubMeshArgs* func_data,
bool enable_bone_mat, bool local) {
@@ -2737,42 +3077,42 @@ namespace mdl {
return false;
prj::vector* textures = objset_info_storage_get_set_gentex(obj_info.set_id);
- obj_mesh_vertex_buffer* obj_vertex_buffer = objset_info_storage_get_obj_mesh_vertex_buffer(obj_info, 0);
+ obj_mesh_vertex_buffer* obj_vert_buffer = objset_info_storage_get_obj_mesh_vertex_buffer(obj_info, 0);
obj_mesh_index_buffer* obj_index_buffer = objset_info_storage_get_obj_mesh_index_buffer(obj_info, 0);
::obj* obj_morph = 0;
- obj_mesh_vertex_buffer* obj_morph_vertex_buffer = 0;
+ obj_mesh_vertex_buffer* obj_morph_vert_buffer = 0;
if (morph.object.set_id != (uint16_t)-1) {
obj_morph = objset_info_storage_get_obj(morph.object);
- obj_morph_vertex_buffer = objset_info_storage_get_obj_mesh_vertex_buffer(morph.object, 0);
+ obj_morph_vert_buffer = objset_info_storage_get_obj_mesh_vertex_buffer(morph.object, 0);
}
- return entry_obj(obj, obj_vertex_buffer, obj_index_buffer,
- mat, textures, blend_color, bone_mat, obj_morph, obj_morph_vertex_buffer,
+ return entry_obj(obj, mat, obj_vert_buffer, obj_index_buffer,
+ textures, blend_color, bone_mat, obj_morph, obj_morph_vert_buffer,
instances_count, instances_mat, func, func_data, enable_bone_mat, local);
}
- bool DispManager::entry_obj_by_object_info(const mat4* mat,
+ bool DispManager::entry_obj_by_object_info(const mat4& mat,
object_info obj_info, float_t alpha, mat4* bone_mat) {
vec4 blend_color = 1.0f;
blend_color.w = alpha;
return entry_obj_by_object_info(mat, obj_info, &blend_color, bone_mat, 0, 0, 0, 0, true);
}
- bool DispManager::entry_obj_by_object_info(const mat4* mat, object_info obj_info,
+ bool DispManager::entry_obj_by_object_info(const mat4& mat, object_info obj_info,
float_t r, float_t g, float_t b, float_t a, mat4* bone_mat, bool local) {
vec4 blend_color = { r, g, b, a };
return entry_obj_by_object_info(mat, obj_info, &blend_color, bone_mat, 0, 0, 0, 0, true, local);
}
- bool DispManager::entry_obj_by_object_info(const mat4* mat, object_info obj_info,
+ bool DispManager::entry_obj_by_object_info(const mat4& mat, object_info obj_info,
vec4* blend_color, mat4* bone_mat, bool local) {
return entry_obj_by_object_info(mat, obj_info, blend_color, 0, 0, 0, 0, 0, false, local);
}
void DispManager::entry_obj_by_object_info_object_skin(object_info obj_info,
prj::vector* texture_pattern, texture_data_struct* texture_data, float_t alpha,
- mat4* matrices, mat4* ex_data_matrices, const mat4* mat, const mat4* global_mat) {
+ mat4* matrices, mat4* ex_data_matrices, const mat4* mat, const mat4& global_mat) {
obj_skin* skin = objset_info_storage_get_obj_skin(obj_info);
if (!skin)
return;
@@ -2833,13 +3173,13 @@ namespace mdl {
}
}
- void DispManager::entry_obj_etc(const mat4* mat, EtcObj* etc, bool local) {
+ void DispManager::entry_obj_etc(const mat4& mat, const EtcObj& etc, bool local) {
ObjData* data = alloc_obj_data(mdl::OBJ_KIND_ETC);
if (!data)
return;
data->init_etc(mat, etc);
- if (etc->color.a == 0xFF) {
+ if (etc.color.a == 0xFF) {
if (!local && (obj_flags & OBJ_SHADOW))
entry_list((mdl::ObjType)(OBJ_TYPE_SHADOW_CHARA + shadow_type), data);
entry_list(local ? OBJ_TYPE_OPAQUE_LOCAL : OBJ_TYPE_OPAQUE, data);
@@ -2848,7 +3188,7 @@ namespace mdl {
entry_list(local ? OBJ_TYPE_TRANSLUCENT_LOCAL : OBJ_TYPE_TRANSLUCENT, data);
}
- void DispManager::entry_obj_user(const mat4* mat, UserArgsFunc func, void* data, ObjType type) {
+ void DispManager::entry_obj_user(const mat4& mat, UserArgsFunc func, void* data, ObjType type) {
ObjData* _data = alloc_obj_data(OBJ_KIND_USER);
if (_data) {
_data->init_user(mat, func, data);
@@ -2992,7 +3332,11 @@ namespace mdl {
}
mdl::ObjList& DispManager::get_obj_list(mdl::ObjType type) {
- if (type >= OBJ_TYPE_MAX)
+ if (type >= OBJ_TYPE_LOCAL_MAX)
+#pragma warning(suppress: 33010)
+#pragma warning(suppress: 33011)
+ return rctx->obj_reflect[type - OBJ_TYPE_LOCAL_MAX];
+ else if (type >= OBJ_TYPE_MAX)
#pragma warning(suppress: 33010)
#pragma warning(suppress: 33011)
return rctx->obj_local[type - OBJ_TYPE_MAX];
@@ -3121,6 +3465,9 @@ namespace mdl {
for (prj::list& i : rctx->obj_local)
i.clear();
+ for (prj::list& i : rctx->obj_reflect)
+ i.clear();
+
buffer_reset();
}
@@ -3128,7 +3475,7 @@ namespace mdl {
chara_color = value;
}
- void DispManager::set_culling_finc(bool(FASTCALL* func)(obj_bounding_sphere*)) {
+ void DispManager::set_culling_func(bool(FASTCALL* func)(const obj_bounding_sphere*)) {
culling_func = func;
}
@@ -3224,7 +3571,7 @@ namespace mdl {
vec3 pos = 0.0f;
sub_1405E8A20(shadow_ptr_get(), 0, &pos);
disp_manager->set_shadow_type(SHADOW_CHARA);
- disp_manager->entry_obj_by_object_info(&mat, object_info((uint16_t)id, (uint16_t)set_id));
+ disp_manager->entry_obj_by_object_info(mat, object_info((uint16_t)id, (uint16_t)set_id));
disp_manager->set_obj_flags((mdl::ObjFlags)0);
}
@@ -3237,7 +3584,7 @@ namespace mdl {
mat4 mat;
mat4_translate(&aabb->center, &mat);
mat4_transpose(&mat, &mat);
- disp_manager->entry_obj_etc(&mat, &etc);
+ disp_manager->entry_obj_etc(mat, etc);
}
HOOK(void, FASTCALL, MeshDw__DrawObjBoundingSphere, 0x000000014031AFE0, obj_bounding_sphere* bounding_sphere, color4u8_bgra color) {
@@ -3252,7 +3599,7 @@ namespace mdl {
mat4 mat;
mat4_translate(&bounding_sphere->center, &mat);
mat4_transpose(&mat, &mat);
- disp_manager->entry_obj_etc(&mat, &etc);
+ disp_manager->entry_obj_etc(mat, etc);
}
HOOK(void, FASTCALL, DispManager__entry_obj, 0x00000001404379E0,
@@ -3264,20 +3611,20 @@ namespace mdl {
abort();
}
- HOOK(void, FASTCALL, DispManager__entry_obj_etc, 0x00000001404395C0, mdl::EtcObj* etc) {
- disp_manager->entry_obj_etc(&mat4_identity, etc);
+ HOOK(void, FASTCALL, DispManager__entry_obj_etc, 0x00000001404395C0, const mdl::EtcObj& etc) {
+ disp_manager->entry_obj_etc(mat4_identity, etc);
}
#if SHARED_OBJECT_BUFFER
HOOK(void, FASTCALL, DispManager__entry_obj_by_obj, 0x0000000140439A20, obj* obj_data, prj::vector* textures,
obj_mesh_vertex_buffer_aft* obj_vert_buf, obj_mesh_index_buffer* obj_index_buf, mat4* bone_mat, float_t alpha) {
- disp_manager->entry_obj_by_obj(rob_chara_item_equip_mat, obj_data, textures, obj_vert_buf, obj_index_buf, bone_mat, alpha);
+ disp_manager->entry_obj_by_obj(*rob_chara_item_equip_mat, obj_data, textures, obj_vert_buf, obj_index_buf, bone_mat, alpha);
}
#else
HOOK(void, FASTCALL, DispManager__entry_obj_by_obj, 0x0000000140439A20, obj* obj_data, prj::vector* textures,
obj_mesh_vertex_buffer* obj_vert_buf, obj_mesh_index_buffer* obj_index_buf, mat4* bone_mat, float_t alpha) {
- disp_manager->entry_obj_by_obj(rob_chara_item_equip_mat, obj_data, textures, obj_vert_buf, obj_index_buf, bone_mat, alpha);
+ disp_manager->entry_obj_by_obj(*rob_chara_item_equip_mat, obj_data, textures, obj_vert_buf, obj_index_buf, bone_mat, alpha);
}
#endif
@@ -3294,7 +3641,7 @@ namespace mdl {
mat4 mat;
mat4_translate(pos, &mat);
mat4_transpose(&mat, &mat);
- disp_manager->entry_obj_etc(&mat, &etc);
+ disp_manager->entry_obj_etc(mat, etc);
}
void disp_manager_patch() {
diff --git a/src/DivaGL/mdl/disp_manager.hpp b/src/DivaGL/mdl/disp_manager.hpp
index d8c3e78..9f7acfb 100644
--- a/src/DivaGL/mdl/disp_manager.hpp
+++ b/src/DivaGL/mdl/disp_manager.hpp
@@ -115,6 +115,8 @@ namespace mdl {
OBJ_TYPE_TRANSPARENT_ALPHA_ORDER_2_LOCAL,
OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_2_LOCAL,
OBJ_TYPE_LOCAL_MAX,
+ OBJ_TYPE_REFLECT_TRANSLUCENT_SORT_BY_RADIUS = OBJ_TYPE_LOCAL_MAX,
+ OBJ_TYPE_REFLECT_MAX,
};
}
@@ -168,6 +170,10 @@ struct texture_data_struct {
static_assert(sizeof(texture_data_struct) == 0x34, "\"texture_pattern_struct\" struct should have a size of 0x34");
namespace mdl {
+ struct ObjSubMeshArgs;
+
+ typedef void(FASTCALL* draw_func)(const ObjSubMeshArgs* args);
+
struct ObjSubMeshArgs {
const obj_sub_mesh* sub_mesh;
const obj_mesh* mesh;
@@ -199,7 +205,7 @@ namespace mdl {
int32_t field_7C8;
int32_t instances_count;
const mat4* instances_mat;
- void(FASTCALL* func)(const ObjSubMeshArgs*);
+ draw_func func;
const ObjSubMeshArgs* func_data;
ObjSubMeshArgs();
@@ -349,16 +355,15 @@ namespace mdl {
ObjData();
~ObjData();
- void init_etc(const mat4* mat, mdl::EtcObj* etc);
- void init_sub_mesh(const mat4* mat, float_t radius,
- const obj_sub_mesh* sub_mesh, const obj_mesh* mesh, const obj_material_data* material,
- const prj::vector* textures, int32_t mat_count, const mat4* mats,
- GLuint vertex_buffer, size_t vertex_buffer_offset, GLuint index_buffer,
- const vec4& blend_color, const vec4& emission, GLuint morph_vertex_buffer,
- size_t morph_vertex_buffer_offset, int32_t instances_count, mat4* instances_mat,
- void(FASTCALL* func)(const ObjSubMeshArgs*), const ObjSubMeshArgs* func_data);
- void init_translucent(const mat4* mat, ObjTranslucentArgs* translucent);
- void init_user(const mat4* mat, UserArgsFunc func, void* data);
+ void init_etc(const mat4& mat, const mdl::EtcObj& etc);
+ void init_sub_mesh(const mat4& mat, float_t radius, const obj_sub_mesh* sub_mesh,
+ const obj_mesh* mesh, const obj_material_data* material, const prj::vector* textures,
+ int32_t mat_count, const mat4* mats, GLuint vertex_buffer, size_t vertex_buffer_offset,
+ GLuint index_buffer, const vec4& blend_color, const vec4& emission, GLuint morph_vertex_buffer,
+ size_t morph_vertex_buffer_offset,
+ int32_t instances_count, const mat4* instances_mat, draw_func func, const ObjSubMeshArgs* func_data);
+ void init_translucent(const mat4& mat, const ObjTranslucentArgs& translucent);
+ void init_user(const mat4& mat, UserArgsFunc func, void* data);
};
typedef prj::list ObjList;
@@ -367,7 +372,7 @@ namespace mdl {
struct Info {
int32_t objects;
int32_t meshes;
- int32_t submesh_array;
+ int32_t sub_meshes;
int pad;
};
@@ -439,7 +444,7 @@ namespace mdl {
float_t wet_param;
int32_t texture_transform_count;
texture_transform_struct texture_transform_array[TEXTURE_TRANSFORM_COUNT];
- bool(FASTCALL* culling_func)(obj_bounding_sphere*);
+ bool(FASTCALL* culling_func)(const obj_bounding_sphere*);
void add_vertex_array(ObjSubMeshArgs* args);
void add_vertex_array(EtcObj* etc, mat4& mat);
@@ -454,35 +459,34 @@ namespace mdl {
void draw(mdl::ObjType type, int32_t depth_mask = 0, bool reflect_texture_mask = true, int32_t alpha = -1);
/*void draw_show_vector(mdl::ObjType type, int32_t show_vector);*/
void entry_list(ObjType type, ObjData* data);
- bool entry_obj(::obj* object, obj_mesh_vertex_buffer* obj_vertex_buf,
- obj_mesh_index_buffer* obj_index_buf, const mat4* mat,
- prj::vector* textures, vec4* blend_color, mat4* bone_mat, ::obj* object_morph,
- obj_mesh_vertex_buffer* obj_morph_vertex_buf, int32_t instances_count, mat4* instances_mat,
- void(*func)(const mdl::ObjSubMeshArgs*), const ObjSubMeshArgs* func_data,
- bool enable_bone_mat, bool local = false);
- void entry_obj_by_obj(const mat4* mat,
- ::obj* obj, prj::vector* textures, obj_mesh_vertex_buffer* obj_vert_buf,
+ bool entry_obj(const ::obj* obj, const mat4& mat, obj_mesh_vertex_buffer* obj_vert_buf,
+ obj_mesh_index_buffer* obj_index_buf, const prj::vector* textures, const vec4* blend_color,
+ const mat4* bone_mat, const ::obj* obj_morph, obj_mesh_vertex_buffer* obj_morph_vert_buf,
+ int32_t instances_count, const mat4* instances_mat,
+ draw_func func, const ObjSubMeshArgs* func_data, bool enable_bone_mat, bool local = false);
+ void entry_obj_by_obj(const mat4& mat,
+ const ::obj* obj, prj::vector* textures, obj_mesh_vertex_buffer* obj_vert_buf,
obj_mesh_index_buffer* obj_index_buf, mat4* bone_mat, float_t alpha);
#if SHARED_OBJECT_BUFFER
- void entry_obj_by_obj(const mat4* mat,
- ::obj* obj, prj::vector* textures, obj_mesh_vertex_buffer_aft* obj_vert_buf,
+ void entry_obj_by_obj(const mat4& mat,
+ const ::obj* obj, prj::vector* textures, obj_mesh_vertex_buffer_aft* obj_vert_buf,
obj_mesh_index_buffer* obj_index_buf, mat4* bone_mat, float_t alpha);
#endif
- bool entry_obj_by_object_info(const mat4* mat, object_info obj_info);
- bool entry_obj_by_object_info(const mat4* mat, object_info obj_info, mat4* bone_mat);
- bool entry_obj_by_object_info(const mat4* mat, object_info obj_info,
+ bool entry_obj_by_object_info(const mat4& mat, object_info obj_info);
+ bool entry_obj_by_object_info(const mat4& mat, object_info obj_info, mat4* bone_mat);
+ bool entry_obj_by_object_info(const mat4& mat, object_info obj_info,
vec4* blend_color, mat4* bone_mat, int32_t instances_count, mat4* instances_mat,
void(*func)(const ObjSubMeshArgs*), const ObjSubMeshArgs* func_data, bool enable_bone_mat, bool local = false);
- bool entry_obj_by_object_info(const mat4* mat, object_info obj_info, float_t alpha, mat4* bone_mat = 0);
- bool entry_obj_by_object_info(const mat4* mat, object_info obj_info,
+ bool entry_obj_by_object_info(const mat4& mat, object_info obj_info, float_t alpha, mat4* bone_mat = 0);
+ bool entry_obj_by_object_info(const mat4& mat, object_info obj_info,
float_t r, float_t g, float_t b, float_t a, mat4* bone_mat = 0, bool local = false);
- bool entry_obj_by_object_info(const mat4* mat, object_info obj_info,
+ bool entry_obj_by_object_info(const mat4& mat, object_info obj_info,
vec4* blend_color, mat4* bone_mat = 0, bool local = false);
void entry_obj_by_object_info_object_skin(object_info obj_info,
prj::vector* texture_pattern, texture_data_struct* texture_data, float_t alpha,
- mat4* matrices, mat4* ex_data_matrices, const mat4* mat, const mat4* global_mat);
- void entry_obj_etc(const mat4* mat, EtcObj* etc, bool local = false);
- void entry_obj_user(const mat4* mat, UserArgsFunc func, void* data, ObjType type);
+ mat4* matrices, mat4* ex_data_matrices, const mat4* mat, const mat4& global_mat);
+ void entry_obj_etc(const mat4& mat, const EtcObj& etc, bool local = false);
+ void entry_obj_user(const mat4& mat, UserArgsFunc func, void* data, ObjType type);
GLuint get_vertex_array(const ObjSubMeshArgs* args);
GLuint get_vertex_array(const mdl::EtcObj* etc);
bool get_chara_color();
@@ -502,7 +506,7 @@ namespace mdl {
void obj_sort(mat4* view, ObjType type, int32_t compare_func, bool a3 = false);
void refresh();
void set_chara_color(bool value = false);
- void set_culling_finc(bool(FASTCALL* func)(obj_bounding_sphere*) = 0);
+ void set_culling_func(bool(FASTCALL* func)(const obj_bounding_sphere*) = 0);
void set_obj_flags(ObjFlags flags = (ObjFlags)0);
void set_material_list(int32_t count = 0, const material_list_struct* value = 0);
void set_morph(object_info object = {}, float_t weight = 0.0f);
@@ -518,6 +522,8 @@ namespace mdl {
static_assert(sizeof(mdl::DispManager) == 0x9D0, "\"mdl::DispManager\" struct should have a size of 0x9D0");
+ extern bool obj_reflect_enable;
+
extern void disp_manager_patch();
}
diff --git a/src/DivaGL/mdl/draw_object.cpp b/src/DivaGL/mdl/draw_object.cpp
index 5159ae2..03c8656 100644
--- a/src/DivaGL/mdl/draw_object.cpp
+++ b/src/DivaGL/mdl/draw_object.cpp
@@ -295,7 +295,7 @@ namespace mdl {
obj_material_attrib_member attrib = args->material->material.attrib.m;
uniform->arr[U_ALPHA_TEST] = (!attrib.flag_28 && (args->blend_color.w < 1.0f
|| (attrib.alpha_texture || attrib.alpha_material) && !attrib.punch_through
- || args->sub_mesh->attrib.m.transparent)
+ || args->sub_mesh->attrib.m.translucent)
|| attrib.punch_through) ? 1 : 0;
uniform->arr[U_NPR_NORMAL] = 1;
@@ -303,12 +303,12 @@ namespace mdl {
const obj_material_data* material = args->material;
switch (material->material.shader.index) {
case SHADER_FT_CLOTH:
- if (!render_manager->npr_param && material->material.color.ambient.w < 1.0f
+ if (!render_manager.npr_param && material->material.color.ambient.w < 1.0f
&& material->material.shader_info.m.aniso_direction == OBJ_MATERIAL_ANISO_DIRECTION_NORMAL)
chara = true;
break;
case SHADER_FT_TIGHTS:
- if (!render_manager->npr_param)
+ if (!render_manager.npr_param)
chara = true;
break;
case SHADER_FT_GLASEYE:
@@ -382,7 +382,7 @@ namespace mdl {
obj_material_attrib_member attrib = args->material->material.attrib.m;
if (!attrib.flag_28 && (args->blend_color.w < 1.0f
|| (attrib.alpha_texture || attrib.alpha_material) && !attrib.punch_through
- || args->sub_mesh->attrib.m.transparent)
+ || args->sub_mesh->attrib.m.translucent)
|| attrib.punch_through) {
uniform->arr[U_ALPHA_TEST] = 1;
rctx->set_batch_alpha_threshold(0.5f);
diff --git a/src/DivaGL/object.cpp b/src/DivaGL/object.cpp
index 0be64e7..87f68bf 100644
--- a/src/DivaGL/object.cpp
+++ b/src/DivaGL/object.cpp
@@ -4,7 +4,9 @@
*/
#include "object.hpp"
+#include "../KKdLib/hash.hpp"
#include "mdl/disp_manager.hpp"
+#include "pv_game/firstread.hpp"
#include "file_handler.hpp"
#include "gl_state.hpp"
#include "wrap.hpp"
@@ -88,6 +90,8 @@ bool (FASTCALL* objset_info_storage_load_obj_set_check_not_read)(int32_t set)
static BufObjMgr& bufobj_mgr = *(BufObjMgr*)0x00000001411A34D0;
+static int32_t load_set_id;
+
static GLuint create_index_buffer(size_t size, const void* data);
static GLuint create_vertex_buffer(size_t size, const void* data, bool dynamic = false);
static void free_index_buffer(GLuint buffer);
@@ -939,7 +943,7 @@ inline int32_t obj_material_texture_type_get_texture_index(
}
void obj_skin_set_matrix_buffer(obj_skin* s, mat4* matrices,
- mat4* ex_data_matrices, mat4* matrix_buffer, const mat4* mat, const mat4* global_mat) {
+ mat4* ex_data_matrices, mat4* matrix_buffer, const mat4* mat, const mat4& global_mat) {
if (!s->num_bone)
return;
@@ -953,7 +957,7 @@ void obj_skin_set_matrix_buffer(obj_skin* s, mat4* matrices,
else
mat4_mul(&matrices[*bone_id], mat, &temp);
- mat4_mul(global_mat, &temp, &temp);
+ mat4_mul(&global_mat, &temp, &temp);
mat4_mul(&temp, bone_matrix, matrix_buffer);
}
else
@@ -964,7 +968,7 @@ void obj_skin_set_matrix_buffer(obj_skin* s, mat4* matrices,
else
temp = matrices[*bone_id];
- mat4_mul(global_mat, &temp, &temp);
+ mat4_mul(&global_mat, &temp, &temp);
mat4_mul(&temp, bone_matrix, matrix_buffer);
}
}
@@ -1041,6 +1045,172 @@ HOOK(obj_mesh_vertex_buffer*, FASTCALL, objset_info_storage_get_obj_mesh_vertex_
return 0;
}
+HOOK(obj_set*, FASTCALL, obj_set_parse_file, 0x000000014045CBC0,
+ prj::shared_ptr& alloc, __int64 set_file, int32_t& result) {
+ obj_set* set = originalobj_set_parse_file(alloc, set_file, result);
+
+ extern bool reflect_full;
+ extern const firstread* firstread_ptr;
+ if (reflect_full && firstread_ptr && firstread_ptr->objset_array && load_set_id != -1) {
+ const firstread_objset_array* objset_array = firstread_ptr->objset_array;
+ if (objset_array->objset_id_array && objset_array->objset_array) {
+ const uint32_t num_objset = objset_array->num_objset;
+ for (uint32_t i = 0; i < num_objset; i++) {
+ if (objset_array->objset_id_array[i] != load_set_id || !objset_array->objset_array[i].data)
+ continue;
+
+ const firstread_objset* frb_set = firstread_objset::read(alloc,
+ objset_array->objset_array[i].data, objset_array->objset_array[i].size);
+ if (!frb_set || !set->obj_data || !frb_set->obj_data)
+ break;
+
+ const int32_t frb_obj_num = frb_set->obj_num;
+ for (int32_t j = 0; j < frb_obj_num; j++) {
+ const int32_t obj_num = set->obj_num;
+ for (int32_t k = 0; k < obj_num; k++) {
+ if (frb_set->obj_data[j].id != set->obj_id_data[k])
+ continue;
+
+ obj* obj = set->obj_data[k];
+ const firstread_obj* frb_obj = &frb_set->obj_data[j];
+ if (obj->mesh_array && frb_obj->mesh_array) {
+ const int32_t frb_num_mesh = frb_obj->num_mesh;
+ int32_t index_match = -1;
+ for (int32_t l = 0; l < frb_num_mesh; l++) {
+ const uint64_t name_hash = hash_utf8_xxh3_64bits(frb_obj->mesh_array[l].name);
+ const int32_t num_mesh = obj->num_mesh;
+ for (int32_t m = 0; m < num_mesh; m++) {
+ if (name_hash != hash_utf8_xxh3_64bits(obj->mesh_array[m].name))
+ continue;
+ else if (frb_obj->mesh_array[l].index != (uint8_t)-1) {
+ if (++index_match != frb_obj->mesh_array[l].index)
+ continue;
+ }
+
+ obj_mesh* mesh = &obj->mesh_array[m];
+ const firstread_obj_mesh* frb_mesh = &frb_obj->mesh_array[l];
+ if (frb_mesh->remove) {
+ mesh->flags = 0;
+ mesh->bounding_sphere = {};
+ mesh->num_submesh = 0;
+ mesh->submesh_array = 0;
+ mesh->vertex_format = (obj_vertex_format)0;
+ mesh->size_vertex = 0;
+ mesh->num_vertex = 0;
+ for (int32_t n = 0; n < 20; n++)
+ mesh->vertex_array_ptr[n] = 0;
+ mesh->attrib = {};
+ mesh->vertex_flags = 0;
+ break;
+ }
+
+ if (mesh->submesh_array && mesh->num_submesh) {
+ const int32_t num_submesh = mesh->num_submesh;
+ for (int32_t n = 0; n < num_submesh; n++) {
+ obj_sub_mesh* submesh = &mesh->submesh_array[n];
+ submesh->attrib.m.no_reflect = frb_mesh->attrib.m.no_reflect;
+ submesh->attrib.m.reflect = frb_mesh->attrib.m.reflect;
+ submesh->attrib.m.reflect_cam_back = frb_mesh->attrib.m.reflect_cam_back;
+ }
+ }
+
+ if (mesh->submesh_array && frb_mesh->submesh_array
+ && mesh->num_submesh && mesh->num_submesh == frb_mesh->num_submesh) {
+ const int32_t num_submesh = mesh->num_submesh;
+ int32_t num_submesh_split = num_submesh;
+ for (int32_t n = 0; n < num_submesh; n++) {
+ const firstread_obj_sub_mesh* frb_submesh = &frb_mesh->submesh_array[n];
+ if (frb_submesh->split)
+ num_submesh_split++;
+ }
+
+ if (num_submesh < num_submesh_split) {
+ obj_sub_mesh* submesh_array = mesh->submesh_array;
+ mesh->num_submesh = num_submesh_split;
+ mesh->submesh_array = alloc->allocate(num_submesh_split);
+ for (int32_t n = 0, o = 0; n < num_submesh; n++, o++) {
+ const firstread_obj_sub_mesh* frb_submesh = &frb_mesh->submesh_array[n];
+ mesh->submesh_array[o] = submesh_array[n];
+ if (frb_submesh->split)
+ mesh->submesh_array[++o] = submesh_array[n];
+ }
+ }
+
+ for (int32_t n = 0, o = 0; n < num_submesh; n++, o++) {
+ obj_sub_mesh* submesh = &mesh->submesh_array[o];
+ const firstread_obj_sub_mesh* frb_submesh = &frb_mesh->submesh_array[n];
+
+ if (frb_submesh->split) {
+ firstread_obj_sub_mesh_split* split = frb_submesh->split;
+ if (split->material_index[0] != -1)
+ submesh->material_index = split->material_index[0];
+ if (split->num_index[0] && split->index_array[0]) {
+ submesh->bounding_sphere = split->bounding_sphere[0];
+ submesh->index_format = split->index_format;
+ submesh->num_index = split->num_index[0];
+ submesh->index_array = (void*)split->index_array[0];
+ }
+ submesh->attrib = split->attrib[0];
+
+ obj_sub_mesh* submesh_before = &mesh->submesh_array[++o];
+ if (split->material_index[1] != -1)
+ submesh_before->material_index = split->material_index[1];
+ if (split->num_index[1] && split->index_array[1]) {
+ submesh_before->bounding_sphere = split->bounding_sphere[1];
+ submesh_before->index_format = split->index_format;
+ submesh_before->num_index = split->num_index[1];
+ submesh_before->index_array = (void*)split->index_array[1];
+ }
+ submesh_before->attrib = split->attrib[1];
+ continue;
+ }
+ else if (frb_submesh->num_index && frb_submesh->index_array) {
+ submesh->bounding_sphere = frb_submesh->bounding_sphere;
+ submesh->index_format = frb_submesh->index_format;
+ submesh->num_index = frb_submesh->num_index;
+ submesh->index_array = (void*)frb_submesh->index_array;
+ }
+
+ submesh->attrib = frb_submesh->attrib;
+ }
+ }
+
+ if (frb_mesh->vertex_format && frb_mesh->num_vertex) {
+ mesh->vertex_format = frb_mesh->vertex_format;
+ mesh->size_vertex = frb_mesh->size_vertex;
+ mesh->num_vertex = frb_mesh->num_vertex;
+ for (int32_t n = 0; n < 20; n++)
+ mesh->vertex_array_ptr[n] = frb_mesh->vertex_array_ptr[n];
+ }
+
+ mesh->attrib = frb_mesh->attrib;
+ break;
+ }
+ }
+ }
+
+ if (frb_obj->num_material && frb_obj->material_array) {
+ obj->num_material = frb_obj->num_material;
+ obj->material_array = (obj_material_data*)frb_obj->material_array;
+ }
+ break;
+ }
+ }
+ break;
+ }
+ }
+ }
+
+ return set;
+}
+
+HOOK(bool, FASTCALL, _objset_info_storage_load_obj_set_check_not_read, 0x000000014045DA60, int32_t set) {
+ load_set_id = set;
+ bool ret = original_objset_info_storage_load_obj_set_check_not_read(set);
+ load_set_id = -1;
+ return ret;
+}
+
HOOK(void, FASTCALL, obj_mesh_vertex_buffer__unload, 0x0000000140461870, obj_mesh_vertex_buffer* objvb) {
objvb->unload();
}
@@ -1057,6 +1227,8 @@ void object_patch() {
INSTALL_HOOK(ObjsetInfo__vertex_buffer_free);
INSTALL_HOOK(objset_info_storage_get_obj_mesh_index_buffer);
INSTALL_HOOK(objset_info_storage_get_obj_mesh_vertex_buffer);
+ INSTALL_HOOK(obj_set_parse_file);
+ INSTALL_HOOK(_objset_info_storage_load_obj_set_check_not_read);
INSTALL_HOOK(obj_mesh_vertex_buffer__unload);
}
diff --git a/src/DivaGL/object.hpp b/src/DivaGL/object.hpp
index 82f7695..c987651 100644
--- a/src/DivaGL/object.hpp
+++ b/src/DivaGL/object.hpp
@@ -288,9 +288,12 @@ struct obj_material_data {
struct obj_sub_mesh_attrib_member {
uint32_t recieve_shadow : 1;
uint32_t cast_shadow : 1;
- uint32_t transparent : 1;
+ uint32_t translucent : 1;
uint32_t cloth : 1;
- uint32_t dummy : 28;
+ uint32_t no_reflect : 1; // Own stuff
+ uint32_t reflect : 1; // Own stuff
+ uint32_t reflect_cam_back : 1; // Own stuff
+ uint32_t dummy : 25; // 28
};
union obj_sub_mesh_attrib {
@@ -309,7 +312,7 @@ struct obj_sub_mesh {
obj_primitive_type primitive_type;
obj_index_format index_format;
int32_t num_index;
- uint16_t* index_array;
+ void* index_array;
obj_sub_mesh_attrib attrib;
uint32_t reserved[4];
obj_axis_aligned_bounding_box* axis_aligned_bounding_box;
@@ -325,7 +328,11 @@ struct obj_mesh_attrib_member {
uint32_t billboard_y_axis : 1;
uint32_t translucent_sort_by_radius : 1;
uint32_t billboard : 1;
- uint32_t dummy : 26; // 28
+ uint32_t no_reflect : 1; // Own stuff
+ uint32_t reflect : 1; // Own stuff
+ uint32_t reflect_cam_back : 1; // Own stuff
+ uint32_t disable_aabb_culling : 1; // Own stuff
+ uint32_t dummy : 22; // 28
uint32_t compression : 2; // Own stuff
};
@@ -611,6 +618,6 @@ extern int32_t obj_material_texture_type_get_texture_index(
obj_material_texture_type type, int32_t base_index);
extern void obj_skin_set_matrix_buffer(obj_skin* s, mat4* matrices,
- mat4* ex_data_matrices, mat4* matrix_buffer, const mat4* mat, const mat4* global_mat);
+ mat4* ex_data_matrices, mat4* matrix_buffer, const mat4* mat, const mat4& global_mat);
extern void object_patch();
diff --git a/src/DivaGL/print_work.cpp b/src/DivaGL/print_work.cpp
index d947b9e..fc281d1 100644
--- a/src/DivaGL/print_work.cpp
+++ b/src/DivaGL/print_work.cpp
@@ -169,7 +169,7 @@ void PrintWork::DrawTextMesh(app::text_flags flags, sprite_text_mesh& mesh) {
}
args.SetVertexArray(mesh.vertices.data(), mesh.vertices.size());
args.id.index = mesh.sprite_id;
- spr::put_sprite(&args);
+ spr::put_sprite(args);
for (spr::SpriteVertex& i : mesh.vertices) {
i.color.r = color.r;
@@ -184,7 +184,7 @@ void PrintWork::DrawTextMesh(app::text_flags flags, sprite_text_mesh& mesh) {
if (flags & app::TEXT_FLAG_FONT)
args.shader = SHADER_FT_FONT;
args.id.index = mesh.sprite_id;
- spr::put_sprite(&args);
+ spr::put_sprite(args);
}
void PrintWork::FillRectangle(rectangle rect) {
diff --git a/src/DivaGL/pv_game/firstread.cpp b/src/DivaGL/pv_game/firstread.cpp
new file mode 100644
index 0000000..4b48d45
--- /dev/null
+++ b/src/DivaGL/pv_game/firstread.cpp
@@ -0,0 +1,313 @@
+/*
+ by korenkonder
+ GitHub/GitLab: korenkonder
+*/
+
+#include "../../KKdLib/f2/header.hpp"
+#include "../../KKdLib/aes.hpp"
+#include "../../KKdLib/deflate.hpp"
+#include "firstread.hpp"
+
+enum {
+ FIRSTREAD_STR_ARRAY = 0,
+ FIRSTREAD_AUTH_3D,
+ FIRSTREAD_OBJSET,
+ FIRSTREAD_STAGE_DATA,
+ FIRSTREAD_MAX,
+};
+
+const firstread_str_array* firstread_str_array::read(const void* data, size_t size) {
+ if (!data || !size)
+ return 0;
+
+ size_t d = (size_t)data;
+ firstread_str_array* str_array = (firstread_str_array*)data;
+ if (str_array->signature != reverse_endianness_uint32_t('strx'))
+ return 0;
+
+ if (str_array->lang_array) {
+ str_array->lang_array = (firstread_str_array_lang*)(d + (size_t)str_array->lang_array);
+
+ const uint32_t num_lang = str_array->num_lang;
+ for (uint32_t i = 0; i < num_lang; i++) {
+ firstread_str_array_lang* lang = (firstread_str_array_lang*)&str_array->lang_array[i];
+
+ if (lang->string_array) {
+ lang->string_array = (firstread_str_array_string*)(d + (size_t)lang->string_array);
+
+ const uint32_t num_string = lang->num_string;
+ for (uint32_t j = 0; j < num_string; j++) {
+ firstread_str_array_string* string = (firstread_str_array_string*)&lang->string_array[j];
+
+ if (string->str)
+ string->str = (const char*)(d + (size_t)string->str);
+ }
+ }
+ }
+ }
+ return str_array;
+}
+
+const firstread_auth_3d_array* firstread_auth_3d_array::read(const void* data, size_t size) {
+ if (!data || !size)
+ return 0;
+
+ size_t d = (size_t)data;
+ firstread_auth_3d_array* auth_3d_array = (firstread_auth_3d_array*)data;
+ if (auth_3d_array->signature != reverse_endianness_uint32_t('a3dx'))
+ return 0;
+
+ if (auth_3d_array->auth_3d_array) {
+ auth_3d_array->auth_3d_array = (firstread_auth_3d*)(d + (size_t)auth_3d_array->auth_3d_array);
+
+ const uint32_t num_auth_3d = auth_3d_array->num_auth_3d;
+ for (uint32_t i = 0; i < num_auth_3d; i++) {
+ firstread_auth_3d* a3d = (firstread_auth_3d*)&auth_3d_array->auth_3d_array[i];
+
+ if (a3d->object_array) {
+ a3d->object_array = (firstread_auth_3d_object*)(d + (size_t)a3d->object_array);
+
+ const uint32_t num_object = a3d->num_object;
+ for (uint32_t j = 0; j < num_object; j++) {
+ firstread_auth_3d_object* obj = (firstread_auth_3d_object*)&a3d->object_array[j];
+
+ if (obj->name)
+ obj->name = (const char*)(d + (size_t)obj->name);
+
+ if (obj->uid_name)
+ obj->uid_name = (const char*)(d + (size_t)obj->uid_name);
+ }
+ }
+
+ if (a3d->object_list_array) {
+ a3d->object_list_array = (firstread_auth_3d_object_list*)(d + (size_t)a3d->object_list_array);
+
+ const uint32_t num_object_list = a3d->num_object_list;
+ for (uint32_t j = 0; j < num_object_list; j++) {
+ firstread_auth_3d_object_list* obj_list = (firstread_auth_3d_object_list*)&a3d->object_list_array[j];
+
+ if (obj_list->name)
+ obj_list->name = (const char*)(d + (size_t)obj_list->name);
+ }
+ }
+ }
+ }
+ return auth_3d_array;
+}
+
+const firstread_objset* firstread_objset::read(
+ prj::shared_ptr& alloc, const void* data, size_t size) {
+ if (!data || !size)
+ return 0;
+
+ f2_header* head = (f2_header*)alloc->allocate(size);
+ if (!head)
+ return 0;
+
+ memcpy(head, data, size);
+
+ bool reset_flags = head->attrib.get_gzip() || head->attrib.get_xor_data();
+
+ if (head->attrib.get_crc()) {
+ if (!head->validate_crc())
+ return 0;
+
+ if (reset_flags)
+ head->reset_crc();
+ }
+
+ if (head->attrib.get_xor_data())
+ head->remove_xor();
+
+ const deflate::allocator allocator = {
+ (void*)&alloc,
+ [](void* data, size_t size) {
+ return (*(prj::shared_ptr*)data)->allocate(size);
+ },
+ [](void* data, void* ptr) {
+
+ }
+ };
+
+ if (head->attrib.get_aes()) {
+ uint8_t* section_data = head->get_section_data();
+ uint32_t section_size = head->get_section_size();
+ if (section_data) {
+ static const uint32_t key_iv_size = 0x30;
+ if (section_size < key_iv_size)
+ return 0;
+
+ section_size -= key_iv_size;
+
+ if (section_size == align_val(section_size, 0x20)) {
+ const uint32_t data_size = head->get_data_size();
+ uint8_t* key = section_data + data_size - key_iv_size;
+ uint8_t* iv = section_data + data_size + 0x20 - key_iv_size;
+
+ aes256_ctx aes;
+ aes256_init_ctx_iv(&aes, key, iv);
+ aes256_cbc_decrypt_buffer(&aes, section_data, section_size);
+ head->attrib.set_aes(false);
+ }
+ }
+ }
+
+ void* dec = 0;
+ if (head->attrib.get_gzip()) {
+ uint8_t* section_data = head->get_section_data();
+ uint32_t section_size = head->get_section_size();
+ if (!head->custom || !section_data || !section_size)
+ return 0;
+
+ dec = 0;
+ size_t dec_len = head->custom;
+ if (deflate::decompress(section_data, section_size, dec, dec_len, deflate::MODE_GZIP, allocator) < 0
+ || !dec_len || dec_len < head->custom)
+ return 0;
+
+ if (reset_flags)
+ head->attrib.set_gzip(false);
+ }
+ else {
+ dec = alloc->allocate(head->custom);
+ if (dec) {
+ memset(dec, 0, head->custom);
+ memcpy(dec, head->get_section_data(), min_def(head->custom, head->get_section_size()));
+ }
+ }
+
+ if (!dec)
+ return 0;
+
+ size_t d = (size_t)dec;
+ firstread_objset* objset = (firstread_objset*)dec;
+ if (objset->signature != reverse_endianness_uint32_t('objx'))
+ return 0;
+
+ if (objset->obj_data) {
+ objset->obj_data = (firstread_obj*)(d + (size_t)objset->obj_data);
+
+ const uint32_t obj_num = objset->obj_num;
+ for (uint32_t i = 0; i < obj_num; i++) {
+ firstread_obj* obj = (firstread_obj*)&objset->obj_data[i];
+
+ if (obj->mesh_array) {
+ obj->mesh_array = (firstread_obj_mesh*)(d + (size_t)obj->mesh_array);
+
+ const uint32_t num_mesh = obj->num_mesh;
+ for (uint32_t j = 0; j < num_mesh; j++) {
+ firstread_obj_mesh* mesh = (firstread_obj_mesh*)&obj->mesh_array[j];
+
+ if (mesh->submesh_array) {
+ mesh->submesh_array = (firstread_obj_sub_mesh*)(d + (size_t)mesh->submesh_array);
+
+ const uint32_t num_submesh = mesh->num_submesh;
+ for (uint32_t j = 0; j < num_submesh; j++) {
+ firstread_obj_sub_mesh* sub_mesh = (firstread_obj_sub_mesh*)&mesh->submesh_array[j];
+
+ if (sub_mesh->index_array)
+ sub_mesh->index_array = (void*)(d + (size_t)sub_mesh->index_array);
+
+ if (sub_mesh->split) {
+ sub_mesh->split = (firstread_obj_sub_mesh_split*)(d + (size_t)sub_mesh->split);
+
+ firstread_obj_sub_mesh_split* split = sub_mesh->split;
+ if (split->index_array[0])
+ split->index_array[0] = (void*)(d + (size_t)split->index_array[0]);
+ if (split->index_array[1])
+ split->index_array[1] = (void*)(d + (size_t)split->index_array[1]);
+ }
+ }
+ }
+
+ for (void*& k : mesh->vertex_array_ptr)
+ if (k)
+ k = (void*)(d + (size_t)k);
+ }
+ }
+
+ if (obj->material_array)
+ obj->material_array = (obj_material_data*)(d + (size_t)obj->material_array);
+ }
+ }
+ return objset;
+}
+
+const firstread_objset_array* firstread_objset_array::read(const void* data, size_t size) {
+ if (!data || !size)
+ return 0;
+
+ size_t d = (size_t)data;
+ firstread_objset_array* objset_array = (firstread_objset_array*)data;
+ if (objset_array->signature != reverse_endianness_uint32_t('osdx'))
+ return 0;
+
+ if (objset_array->objset_id_array)
+ objset_array->objset_id_array = (int32_t*)(d + (size_t)objset_array->objset_id_array);
+
+ if (objset_array->objset_array) {
+ objset_array->objset_array = (firstread_objset_data*)(d + (size_t)objset_array->objset_array);
+
+ const uint32_t num_objset = objset_array->num_objset;
+ for (uint32_t i = 0; i < num_objset; i++) {
+ firstread_objset_data* objset = (firstread_objset_data*)&objset_array->objset_array[i];
+
+ if (objset->data)
+ objset->data = (void*)(d + (size_t)objset->data);
+ }
+ }
+ return objset_array;
+}
+
+const firstread_stage_data_array* firstread_stage_data_array::read(const void* data, size_t size) {
+ if (!data || !size)
+ return 0;
+
+ size_t d = (size_t)data;
+ firstread_stage_data_array* stage_data_array = (firstread_stage_data_array*)data;
+ if (stage_data_array->signature != reverse_endianness_uint32_t('stgx'))
+ return 0;
+
+ if (stage_data_array->stage_data_array) {
+ stage_data_array->stage_data_array = (firstread_stage_data*)(d + (size_t)stage_data_array->stage_data_array);
+
+ const uint32_t num_stage_data = stage_data_array->num_stage_data;
+ for (uint32_t i = 0; i < num_stage_data; i++) {
+ firstread_stage_data* stage_data = (firstread_stage_data*)&stage_data_array->stage_data_array[i];
+
+ if (stage_data->name)
+ stage_data->name = (const char*)(d + (size_t)stage_data->name);
+
+ if (stage_data->reflect)
+ stage_data->reflect = (stage_data_reflect*)(d + (size_t)stage_data->reflect);
+ }
+ }
+ return stage_data_array;
+}
+
+const firstread* firstread::read(const void* data, size_t size) {
+ if (!data || !size)
+ return 0;
+
+ size_t d = (size_t)data;
+ firstread* fr = (firstread*)data;
+ if (fr->signature != reverse_endianness_uint32_t('frbx'))
+ return 0;
+
+ if (fr->str_array)
+ fr->str_array = firstread_str_array::read(
+ (void*)(d + (size_t)fr->str_array), fr->str_array_size);
+
+ if (fr->auth_3d_array)
+ fr->auth_3d_array = firstread_auth_3d_array::read(
+ (void*)(d + (size_t)fr->auth_3d_array), fr->auth_3d_array_size);
+
+ if (fr->objset_array)
+ fr->objset_array = firstread_objset_array::read(
+ (void*)(d + (size_t)fr->objset_array), fr->objset_array_size);
+
+ if (fr->stage_data_array)
+ fr->stage_data_array = firstread_stage_data_array::read(
+ (void*)(d + (size_t)fr->stage_data_array), fr->stage_data_array_size);
+ return fr;
+}
diff --git a/src/DivaGL/pv_game/firstread.hpp b/src/DivaGL/pv_game/firstread.hpp
new file mode 100644
index 0000000..da5f4a1
--- /dev/null
+++ b/src/DivaGL/pv_game/firstread.hpp
@@ -0,0 +1,153 @@
+/*
+ by korenkonder
+ GitHub/GitLab: korenkonder
+*/
+
+#pragma once
+
+#include "../../KKdLib/vec.hpp"
+#include "../object.hpp"
+#include "../stage.hpp"
+#include "../types.hpp"
+
+struct firstread_str_array_string {
+ int32_t id;
+ const char* str;
+};
+
+struct firstread_str_array_lang {
+ int32_t lang_id;
+ uint32_t num_string;
+ const firstread_str_array_string* string_array;
+};
+
+struct firstread_str_array {
+ uint32_t signature;
+ uint32_t num_lang;
+ const firstread_str_array_lang* lang_array;
+
+ static const firstread_str_array* read(const void* data, size_t size);
+};
+
+struct firstread_auth_3d_object {
+ const char* name;
+ const char* uid_name;
+};
+
+struct firstread_auth_3d_object_list {
+ const char* name;
+ bool remove;
+};
+
+struct firstread_auth_3d {
+ int32_t uid;
+ uint32_t num_object;
+ uint32_t num_object_list;
+ const firstread_auth_3d_object* object_array;
+ const firstread_auth_3d_object_list* object_list_array;
+};
+
+struct firstread_auth_3d_array {
+ uint32_t signature;
+ uint32_t num_auth_3d;
+ const firstread_auth_3d* auth_3d_array;
+
+ static const firstread_auth_3d_array* read(const void* data, size_t size);
+};
+
+struct firstread_obj_sub_mesh_split {
+ obj_bounding_sphere bounding_sphere[2];
+ int32_t material_index[2];
+ obj_index_format index_format;
+ int32_t num_index[2];
+ const void* index_array[2];
+ obj_sub_mesh_attrib attrib[2];
+};
+
+struct firstread_obj_sub_mesh {
+ obj_bounding_sphere bounding_sphere;
+ obj_index_format index_format;
+ int32_t num_index;
+ const void* index_array;
+ obj_sub_mesh_attrib attrib;
+ firstread_obj_sub_mesh_split* split;
+};
+
+struct firstread_obj_mesh {
+ firstread_obj_sub_mesh* submesh_array;
+ int32_t num_submesh;
+ obj_vertex_format vertex_format;
+ uint32_t size_vertex;
+ int32_t num_vertex;
+ union {
+ obj_mesh_vertex_array vertex_array;
+ void* vertex_array_ptr[20];
+ };
+ obj_mesh_attrib attrib;
+ bool remove;
+ uint8_t index;
+ uint8_t pad[2];
+ char name[0x40];
+};
+
+struct firstread_obj {
+ int32_t id;
+ uint16_t num_mesh;
+ uint16_t num_material;
+ firstread_obj_mesh* mesh_array;
+ const obj_material_data* material_array;
+};
+
+struct firstread_objset {
+ uint32_t signature;
+ int32_t obj_num;
+ const firstread_obj* obj_data;
+
+ static const firstread_objset* read(
+ prj::shared_ptr& alloc, const void* data, size_t size);
+};
+
+struct firstread_objset_data {
+ const void* data;
+ size_t size;
+};
+
+struct firstread_objset_array {
+ uint32_t signature;
+ uint32_t num_objset;
+ const int32_t* objset_id_array;
+ const firstread_objset_data* objset_array;
+
+ static const firstread_objset_array* read(const void* data, size_t size);
+};
+
+struct firstread_stage_data {
+ const char* name;
+ uint32_t pv_id;
+ uint8_t reflect_type;
+ uint8_t reflect_full;
+ const stage_data_reflect* reflect;
+};
+
+struct firstread_stage_data_array {
+ uint32_t signature;
+ uint32_t num_stage_data;
+ const firstread_stage_data* stage_data_array;
+
+ static const firstread_stage_data_array* read(const void* data, size_t size);
+};
+
+struct firstread {
+ uint32_t signature;
+ uint32_t pad[0x03];
+ const firstread_str_array* str_array;
+ size_t str_array_size;
+ const firstread_auth_3d_array* auth_3d_array;
+ size_t auth_3d_array_size;
+ const firstread_objset_array* objset_array;
+ size_t objset_array_size;
+ const firstread_stage_data_array* stage_data_array;
+ size_t stage_data_array_size;
+
+ static const firstread* read(const void* data, size_t size);
+};
diff --git a/src/DivaGL/pv_game/pv_game.cpp b/src/DivaGL/pv_game/pv_game.cpp
index 2b76fbc..ccb40c5 100644
--- a/src/DivaGL/pv_game/pv_game.cpp
+++ b/src/DivaGL/pv_game/pv_game.cpp
@@ -11,6 +11,7 @@
#include "../auth_3d.hpp"
#include "../print_work.hpp"
#include "dsc.hpp"
+#include "firstread.hpp"
#include "pvpp.hpp"
#include "pvsr.hpp"
#include
@@ -620,26 +621,30 @@ public:
void stop_current_pv();
};
-struct x_pv_game_str_array {
- prj::unordered_map> strings;
+struct x_pv_game_firstread {
+ prj::unordered_map> str_array_strings;
p_file_handler file_handler;
+ const firstread* firstread;
int32_t lang_sel;
bool init;
- x_pv_game_str_array();
- ~x_pv_game_str_array();
+ x_pv_game_firstread();
+ ~x_pv_game_firstread();
- const char* get_string(int32_t id);
+ const char* get_str_array_string(int32_t id);
void read();
};
TaskPvGame& task_pv_game = *(TaskPvGame*)0x000000014CC95270;
TaskPvGameX* task_pv_game_x;
-x_pv_game_str_array* x_pv_game_str_array_ptr;
+const firstread* firstread_ptr;
+x_pv_game_firstread* x_pv_game_firstread_ptr;
pv_disp2d& pv_disp2d_data = *(pv_disp2d*)0x0000000140C938E0;
size_t pv_game_ptr = 0x0000000140CDD8D0;
pv_game_parent& pv_game_parent_data = *(pv_game_parent*)0x0000000140D0B510;
+bool reflect_full = false;
+
bool pv_game_load_state_4_tail_impl() {
if (task_pv_game_x->use) {
bool wait_load = false;
@@ -827,15 +832,15 @@ HOOK(bool, FASTCALL, pv_game_pv_data__load, 0x000000014011B7E0, size_t _this,
void pv_game_init() {
if (!task_pv_game_x)
task_pv_game_x = new (_operator_new(sizeof(TaskPvGameX))) TaskPvGameX;
- if (!x_pv_game_str_array_ptr)
- x_pv_game_str_array_ptr = new (_operator_new(sizeof(x_pv_game_str_array))) x_pv_game_str_array;
+ if (!x_pv_game_firstread_ptr)
+ x_pv_game_firstread_ptr = new (_operator_new(sizeof(x_pv_game_firstread))) x_pv_game_firstread;
}
void pv_game_free() {
- if (x_pv_game_str_array_ptr) {
- x_pv_game_str_array_ptr->~x_pv_game_str_array();
- _operator_delete(x_pv_game_str_array_ptr);
- x_pv_game_str_array_ptr = 0;
+ if (x_pv_game_firstread_ptr) {
+ x_pv_game_firstread_ptr->~x_pv_game_firstread();
+ _operator_delete(x_pv_game_firstread_ptr);
+ x_pv_game_firstread_ptr = 0;
}
if (task_pv_game_x) {
@@ -1715,6 +1720,7 @@ void x_pv_game_effect::set_song_effect(int32_t index, int64_t time) {
i.id.set_repeat(false);
i.id.set_req_frame(0.0f);
i.id.set_visibility(true);
+ i.id.set_reflect(reflect_full);
}
for (x_pv_game_song_effect_glitter& i : song_effect.glitter) {
@@ -1979,7 +1985,7 @@ void x_pv_aet_disp_string::ctrl(const char* name, aet_obj_data* aet) {
}
static const char* sub_8133DDF8(int32_t id) {
- return x_pv_game_str_array_ptr->get_string(id);
+ return x_pv_game_firstread_ptr->get_str_array_string(id);
}
const char* x_pv_str_array_pv::get_song_name(int32_t index) {
@@ -3166,6 +3172,7 @@ void x_pv_game_stage::ctrl(float_t delta_time) {
id.set_paused(false);
id.set_visibility(false);
id.set_frame_rate(&bpm_frame_rate_control);
+ id.set_reflect(reflect_full);
eff_auth_3d.id = id;
eff_auth_3d.name = stg_eff_auth_3d.name;
@@ -3438,6 +3445,7 @@ void x_pv_game_stage::load_change_effect(int32_t curr_stage_effect, int32_t next
id.set_paused(false);
id.set_visibility(false);
id.set_frame_rate(&bpm_frame_rate_control);
+ id.set_reflect(reflect_full);
chg_eff_auth_3d.id = id;
chg_eff_auth_3d.name = stg_chg_eff_auth_3d.name;
@@ -3560,6 +3568,7 @@ void x_pv_game_stage::set_change_effect_frame_part_2(float_t frame) {
id.set_paused(false);
id.set_visibility(!!(flags & 0x01));
id.set_frame_rate(&bpm_frame_rate_control);
+ id.set_reflect(reflect_full);
}
for (x_pv_game_stage_effect_glitter& i : chg_eff.glitter) {
@@ -3649,6 +3658,7 @@ void x_pv_game_stage::set_stage_effect_auth_3d_frame(int32_t stage_effect, float
id.set_paused(false);
id.set_visibility(true);
id.set_frame_rate(&bpm_frame_rate_control);
+ id.set_reflect(reflect_full);
}
}
@@ -3830,7 +3840,22 @@ TaskPvGameX::~TaskPvGameX() {
bool TaskPvGameX::init() {
use = true;
- x_pv_game_str_array_ptr->read();
+ x_pv_game_firstread_ptr->read();
+ reflect_full = false;
+ extern bool config_reflect_full;
+ if (firstread_ptr && firstread_ptr->stage_data_array && config_reflect_full) {
+ const firstread_stage_data_array* stage_data_array = firstread_ptr->stage_data_array;
+ const uint32_t num_stage_data = stage_data_array->num_stage_data;
+ for (uint32_t i = 0; i < num_stage_data; i++) {
+ const firstread_stage_data* stage_data = &stage_data_array->stage_data_array[i];
+ if (stage_data->pv_id == pv_id) {
+ if (stage_data->reflect_type == STAGE_DATA_REFLECT_REFLECT_MAP
+ && stage_data->reflect && stage_data->reflect_full)
+ reflect_full = true;
+ break;
+ }
+ }
+ }
return true;
}
@@ -3909,12 +3934,45 @@ bool TaskPvGameX::ctrl() {
bool TaskPvGameX::dest() {
unload();
+ reflect_full = false;
use = false;
return true;
}
void TaskPvGameX::disp() {
data.disp();
+
+ static bool reflect_show;
+ if (reflect_full && reflect_show) {
+ extern RenderTexture* reflect_tex;
+ if (reflect_tex) {
+ const float_t width = 1280.0f;
+ const float_t height = 720.0f;
+
+ const float_t reflection_quality = 1.0f;
+
+ spr::put_sprite_rect({ 0.0f, 0.0f, width, height }, RESOLUTION_MODE_HD,
+ spr::SPR_PRIO_DEFAULT, { 0x00, 0x00, 0x00, 0xFF }, 0);
+
+ spr::SprArgs args;
+ args.resolution_mode_screen = RESOLUTION_MODE_HD;
+ args.resolution_mode_sprite = RESOLUTION_MODE_HD;
+ args.SetSpriteSize({ width, height });
+ args.SetTexturePosSize(0.0f,
+ (float_t)reflect_tex->GetHeight() - (float_t)reflect_tex->GetHeight() * reflection_quality,
+ (float_t)reflect_tex->GetWidth() * reflection_quality,
+ (float_t)reflect_tex->GetHeight() * reflection_quality);
+ args.texture = reflect_tex->color_texture;
+ args.color = color4u8_bgra(0xFF, 0xFF, 0xFF, 0x3F);
+ args.scale.x = 1.0f;
+ args.scale.y = -1.0f;
+ args.center.x = width * 0.5f;
+ args.center.y = height * 0.5f;
+ args.trans.x = width * 0.5f;
+ args.trans.y = height * 0.5f;
+ spr::put_sprite(args);
+ }
+ }
}
void TaskPvGameX::load(int32_t pv_id, int32_t modules[6]) {
@@ -4076,17 +4134,19 @@ void TaskPvGameX::stop_current_pv() {
data.stop();
}
-x_pv_game_str_array::x_pv_game_str_array() : init() {
+x_pv_game_firstread::x_pv_game_firstread() : init(), firstread() {
lang_sel = 0;
}
-x_pv_game_str_array::~x_pv_game_str_array() {
-
+x_pv_game_firstread::~x_pv_game_firstread() {
+ firstread = 0;
+ firstread_ptr = 0;
+ file_handler.reset();
}
-const char* x_pv_game_str_array::get_string(int32_t id) {
- auto lang_elem = strings.find(lang_sel);
- if (lang_elem != strings.end()) {
+const char* x_pv_game_firstread::get_str_array_string(int32_t id) {
+ auto lang_elem = str_array_strings.find(lang_sel);
+ if (lang_elem != str_array_strings.end()) {
auto elem = lang_elem->second.find(id);
if (elem != lang_elem->second.end())
return elem->second;
@@ -4094,11 +4154,11 @@ const char* x_pv_game_str_array::get_string(int32_t id) {
return 0;
}
-void x_pv_game_str_array::read() {
+void x_pv_game_firstread::read() {
if (init)
return;
- file_handler.read_file_path("rom/str_array_x.bin", prj::HeapCMallocSystem);
+ file_handler.read_file_path("rom/firstread_x.bin", prj::HeapCMallocSystem);
file_handler.read_now();
if (!file_handler.get_data() || !file_handler.get_size()) {
@@ -4106,24 +4166,22 @@ void x_pv_game_str_array::read() {
return;
}
- size_t data = (size_t)file_handler.get_data();
- if (*(uint32_t*)data != reverse_endianness_uint32_t('strx')) {
- init = true;
- return;
+ firstread = firstread::read(file_handler.get_data(), file_handler.get_size());
+ firstread_ptr = firstread;
+
+ if (firstread->str_array) {
+ const firstread_str_array* str_array = firstread->str_array;
+ const uint32_t lang_count = str_array->num_lang;
+ for (uint32_t i = 0; i < lang_count; i++) {
+ const firstread_str_array_lang* lang_data = &str_array->lang_array[i];
+
+ prj::unordered_map& strings = str_array_strings[lang_data->lang_id];
+ const uint32_t num_string = lang_data->num_string;
+ for (uint32_t j = 0; j < num_string; j++) {
+ const firstread_str_array_string* string_data = &lang_data->string_array[j];
+ strings[string_data->id] = string_data->str;
+ }
+ }
}
-
- uint32_t lang_count = *(uint32_t*)(data + 0x04);
- size_t lang_data = data + *(uint32_t*)(data + 0x08);
- for (uint32_t i = lang_count; i; i--, lang_data += 0x0C) {
- int32_t lang_id = *(int32_t*)lang_data;
- uint32_t strings_count = *(uint32_t*)(lang_data + 0x04);
- uint32_t strings_offset = *(uint32_t*)(lang_data + 0x08);
-
- prj::unordered_map& strings = this->strings[lang_id];
- size_t strings_data = data + strings_offset;
- for (uint32_t j = strings_count; j; j--, strings_data += 0x08)
- strings[*(int32_t*)strings_data] = (const char*)(data + *(uint32_t*)(strings_data + 0x04));
- }
-
init = true;
}
diff --git a/src/DivaGL/render.cpp b/src/DivaGL/render.cpp
index 857803e..cdced59 100644
--- a/src/DivaGL/render.cpp
+++ b/src/DivaGL/render.cpp
@@ -227,9 +227,9 @@ namespace rndr {
rctx->sun_quad_ubo.Bind(0);
mat4 view;
- mat4_transpose(&camera_data->view, &view);
+ mat4_transpose(&camera_data.view, &view);
mat4 projection;
- mat4_transpose(&camera_data->projection, &projection);
+ mat4_transpose(&camera_data.projection, &projection);
ExposureCharaData* chara_data = exposure_chara_data;
int32_t query_index = (this->exposure_query_index + 1) % 3;
@@ -339,16 +339,16 @@ namespace rndr {
return;
mat4 view;
- mat4_transpose(&camera_data->view, &view);
+ mat4_transpose(&camera_data.view, &view);
mat4 projection;
- mat4_transpose(&camera_data->projection, &projection);
+ mat4_transpose(&camera_data.projection, &projection);
mat4 view_projection;
mat4 inverse_view_projection_matrix;
- mat4_transpose(&camera_data->view_projection, &view_projection);
+ mat4_transpose(&camera_data.view_projection, &view_projection);
mat4_invert(&view_projection, &inverse_view_projection_matrix);
- float_t v5 = tanf(camera_data->fov * 0.5f * DEG_TO_RAD_FLOAT);
+ float_t v5 = tanf(camera_data.fov * 0.5f * DEG_TO_RAD_FLOAT);
light_set* set = &light_set_data[LIGHT_SET_MAIN];
light_data* data = &set->lights[LIGHT_SUN];
@@ -820,16 +820,16 @@ namespace rndr {
view_point_prev = view_point;
interest_prev = interest;
- view_point = camera_data->view_point;
- interest = camera_data->interest;
+ view_point = camera_data.view_point;
+ interest = camera_data.interest;
stage_index_prev = stage_index;
stage_index = task_stage_get_current_stage_index();
cam_view_projection_prev = cam_view_projection;
- cam_view_projection = camera_data->view_projection;
+ cam_view_projection = camera_data.view_projection;
- reset_exposure = camera_data->fast_change_hist1 && !camera_data->fast_change_hist0;
+ reset_exposure = camera_data.fast_change_hist1 && !camera_data.fast_change_hist0;
if (reset_exposure) {
float_t view_point_dist = vec3::distance(view_point, view_point_prev);
@@ -1354,8 +1354,8 @@ namespace rndr {
mat4 v42;
mat4 v43;
- mat4_mul(&camera_data->view, &v44, &v42);
- mat4_mul(&camera_data->projection, &v42, &v43);
+ mat4_mul(&camera_data.view, &v44, &v42);
+ mat4_mul(&camera_data.projection, &v42, &v43);
mat4_transpose(&v42, &v42);
mat4_transpose(&v43, &v43);
@@ -1385,7 +1385,7 @@ namespace rndr {
v17 = 0.0f;
float_t v18 = (float_t)height / (float_t)width;
- float_t v20 = tanf(camera_data->fov * 0.5f * DEG_TO_RAD_FLOAT);
+ float_t v20 = tanf(camera_data.fov * 0.5f * DEG_TO_RAD_FLOAT);
float_t v21 = 0.25f / sqrtf(powf(v20 * 3.4f, 2.0f) * (v41.z * v41.z));
float_t v22;
if (v21 < 0.055f)
diff --git a/src/DivaGL/render_context.cpp b/src/DivaGL/render_context.cpp
index d43584d..7d1c95f 100644
--- a/src/DivaGL/render_context.cpp
+++ b/src/DivaGL/render_context.cpp
@@ -613,7 +613,7 @@ void render_context::ctrl(bool change_res) {
return;
if (screen_res_change)
- render_manager->resize(screen_width, screen_height);
+ render_manager.resize(screen_width, screen_height);
/*if (render_res_change)
litproj_texture->Init(render_width, render_height, 0, GL_RGBA8, GL_DEPTH_COMPONENT32F);*/
@@ -629,7 +629,7 @@ void render_context::ctrl(bool change_res) {
};
RenderTexture& render_buffer = render->rend_texture[0];
- RenderTexture& reflect_buffer = render_manager->get_render_texture(0);
+ RenderTexture& reflect_buffer = render_manager.get_render_texture(0);
RenderTexture& shadow_buffer = shadow_ptr_get()->render_textures[1];
init_copy_buffer(reflect_buffer, this->reflect_buffer);
init_copy_buffer(render_buffer, this->render_buffer);
@@ -683,7 +683,7 @@ void render_context::init() {
};
RenderTexture& render_buffer = render_get()->rend_texture[0];
- RenderTexture& reflect_buffer = render_manager->get_render_texture(0);
+ RenderTexture& reflect_buffer = render_manager.get_render_texture(0);
RenderTexture& shadow_buffer = shadow_ptr_get()->render_textures[1];
init_copy_buffer(reflect_buffer, this->reflect_buffer);
init_copy_buffer(render_buffer, this->render_buffer);
diff --git a/src/DivaGL/render_context.hpp b/src/DivaGL/render_context.hpp
index 5aa9930..c4237f8 100644
--- a/src/DivaGL/render_context.hpp
+++ b/src/DivaGL/render_context.hpp
@@ -451,6 +451,7 @@ struct render_context {
int32_t screen_height;
mdl::ObjList obj_local[mdl::OBJ_TYPE_LOCAL_MAX - mdl::OBJ_TYPE_MAX];
+ mdl::ObjList obj_reflect[mdl::OBJ_TYPE_REFLECT_MAX - mdl::OBJ_TYPE_LOCAL_MAX];
render_context();
~render_context();
diff --git a/src/DivaGL/render_manager.cpp b/src/DivaGL/render_manager.cpp
index 71cb8d7..d4e8dcc 100644
--- a/src/DivaGL/render_manager.cpp
+++ b/src/DivaGL/render_manager.cpp
@@ -9,6 +9,7 @@
#include "light_param/fog.hpp"
#include "light_param/light.hpp"
#include "mdl/disp_manager.hpp"
+#include "mdl/draw_object.hpp"
#include "rob/rob.hpp"
#include "clear_color.hpp"
#include "effect.hpp"
@@ -23,6 +24,29 @@
#include "texture.hpp"
#include
+struct reflect_full_struct {
+ RenderTexture reflect_texture;
+ RenderTexture reflect_buffer_texture;
+ RenderTexture reflect_contour_texture;
+
+ reflect_full_struct();
+ ~reflect_full_struct();
+
+ void free();
+ void init();
+};
+
+extern render_context* rctx;
+
+vec4 reflect_clip_plane;
+bool reflect_draw = false;
+mat4 reflect_mat;
+reflect_full_struct* reflect_full_ptr;
+
+RenderTexture* litproj_shadow = (RenderTexture*)0x0000000141194DA0;
+RenderTexture* litproj_texture = (RenderTexture*)0x0000000141194E00;
+rndr::RenderManager& render_manager = *(rndr::RenderManager*)0x00000001411AD320;
+
static void draw_pass_shadow_begin_make_shadowmap(Shadow* shad, int32_t index, int32_t a3);
static void draw_pass_shadow_end_make_shadowmap(Shadow* shad, int32_t index, int32_t a3);
static void draw_pass_shadow_filter(RenderTexture* a1, RenderTexture* a2,
@@ -36,22 +60,21 @@ static void draw_pass_sss_filter(sss_data* sss);
static int32_t draw_pass_3d_get_translucent_count();
static void draw_pass_3d_shadow_reset();
static void draw_pass_3d_shadow_set(Shadow* shad);
-extern void draw_pass_3d_translucent(mdl::ObjType opaque, mdl::ObjType transparent, mdl::ObjType translucent);
+extern void draw_pass_3d_translucent(mdl::ObjType opaque,
+ mdl::ObjType transparent, mdl::ObjType translucent);
static int32_t draw_pass_3d_translucent_count_layers(int32_t* alpha_array,
mdl::ObjType opaque, mdl::ObjType transparent, mdl::ObjType translucent);
static void draw_pass_3d_translucent_has_objects(bool* arr, mdl::ObjType type);
+static void draw_pass_reflect_full(rndr::RenderManager& render_manager);
+
static void blur_filter_apply(RenderTexture* dst, RenderTexture* src,
blur_filter_mode filter, const vec2 res_scale, const vec4 scale, const vec4 offset);
static void render_manager_free_render_textures();
static void render_manager_init_render_textures(int32_t multisample);
-extern render_context* rctx;
-
-RenderTexture* litproj_shadow = (RenderTexture*)0x0000000141194DA0;
-RenderTexture* litproj_texture = (RenderTexture*)0x0000000141194E00;
-rndr::RenderManager* render_manager = (rndr::RenderManager*)0x00000001411AD320;
+static void set_reflect_mat(render_context* rctx);
namespace rndr {
struct RenderTextureData {
@@ -420,6 +443,101 @@ namespace rndr {
gl_state_begin_event("pass_ss_sss");
rndr::Render* rend = render;
+ extern bool reflect_full;
+ if (reflect_full && pass_sw[rndr::RND_PASSID_REFLECT]
+ && disp_manager->get_obj_count(mdl::OBJ_TYPE_SSS)) {
+ gl_state_begin_event("reflect");
+ reflect_draw = true;
+
+ rndr::Render* rend = render;
+ RenderTexture& refl_tex = reflect_full_ptr->reflect_texture;
+ //if (refl_tex.GetWidth() > 1280.0)
+ // sss->npr_contour = false;
+
+ //if (sss->npr_contour) {
+ refl_tex.Bind();
+ refl_tex.SetViewport();
+ //}
+ //else {
+ // sss->textures[0].Bind();
+ // gl_state_set_viewport(0, 0, 640, 360);
+ //}
+
+ glClearColorDLL(sss->param.x, sss->param.y, sss->param.z, 0.0f);
+ glClearDLL(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ draw_pass_set_camera();
+ for (int32_t i = LIGHT_SET_MAIN; i < LIGHT_SET_MAX; i++)
+ light_set_data[i].data_set((light_set_id)i);
+
+ if (shadow)
+ draw_pass_3d_shadow_set(shadow_ptr);
+ else
+ draw_pass_3d_shadow_reset();
+
+ set_reflect_mat(rctx);
+
+ draw_state.shader_index = SHADER_FT_SSS_SKIN;
+ gl_state_enable_depth_test();
+ gl_state_set_depth_func(GL_LEQUAL);
+ gl_state_set_depth_mask(GL_TRUE);
+ disp_manager->draw(mdl::OBJ_TYPE_SSS);
+ gl_state_disable_depth_test();
+ draw_state.shader_index = -1;
+ draw_pass_3d_shadow_reset();
+ uniform->arr[U_NPR] = 0;
+
+ if (npr_param == 1) {
+ if (sss->enable && sss->npr_contour) {
+ uniform->arr[U_NPR] = 1;
+ draw_pass_sss_contour(rend);
+ }
+ else if (npr) {
+ refl_tex.Bind();
+ refl_tex.SetViewport();
+ glClearDLL(GL_DEPTH_BUFFER_BIT);
+ draw_state.shader_index = SHADER_FT_SSS_SKIN;
+ gl_state_enable_depth_test();
+ gl_state_set_depth_mask(GL_TRUE);
+ disp_manager->draw(mdl::OBJ_TYPE_SSS);
+ gl_state_disable_depth_test();
+ draw_state.shader_index = -1;
+ gl_state_bind_framebuffer(0);
+ uniform->arr[U_NPR] = 1;
+ draw_pass_sss_contour(rend);
+ }
+ }
+
+ if (!sss->npr_contour) {
+ sss->textures[0].Bind();
+ gl_state_set_viewport(0, 0, 640, 360);
+
+ filter_scene_shader_data filter_scene = {};
+ filter_scene.g_transform = { 1.0f, 1.0f, 0.0f, 0.0f };
+ filter_scene.g_texcoord = { 1.0f, 1.0f, 0.0f, 0.0f };
+ rctx->filter_scene_ubo.WriteMemory(filter_scene);
+
+ imgfilter_batch_shader_data imgfilter_batch = {};
+ imgfilter_batch.g_color_scale = 1.0f;
+ imgfilter_batch.g_color_offset = 0.0f;
+ imgfilter_batch.g_texture_lod = 0.0f;
+ rctx->imgfilter_batch_ubo.WriteMemory(imgfilter_batch);
+
+ uniform->arr[U_IMAGE_FILTER] = 5;
+ shaders_ft.set(SHADER_FT_IMGFILT);
+ rctx->filter_scene_ubo.Bind(0);
+ rctx->imgfilter_batch_ubo.Bind(1);
+ gl_state_active_bind_texture_2d(0, refl_tex.GetColorTex());
+ gl_state_bind_sampler(0, rctx->render_samplers[0]);
+ gl_state_bind_vertex_array(rctx->common_vao);
+ shaders_ft.draw_arrays(GL_TRIANGLE_STRIP, 0, 4);
+ }
+
+ draw_pass_sss_filter(sss);
+ reflect_draw = false;
+ gl_state_end_event();
+ }
+
//if (rend->render_width > 1280.0)
// sss->npr_contour = false;
@@ -507,8 +625,17 @@ namespace rndr {
}
void RenderManager::pass_reflect() {
+ extern bool reflect_full;
+ if (reflect_full) {
+ draw_pass_reflect_full(*this);
+ return;
+ }
+
+ extern RenderTexture* reflect_tex;
+ reflect_tex = 0;
+
gl_state_begin_event("pass_reflect");
- RenderTexture& refl_tex = render_manager->get_render_texture(0);
+ RenderTexture& refl_tex = render_manager.get_render_texture(0);
RenderTexture& refl_buf_tex = rctx->reflect_buffer;
refl_tex.Bind();
if (disp_manager->get_obj_count(mdl::OBJ_TYPE_REFLECT_OPAQUE)
@@ -578,7 +705,7 @@ namespace rndr {
void RenderManager::pass_refract() {
gl_state_begin_event("pass_refract");
- RenderTexture& refract_texture = render_manager->get_render_texture(1);
+ RenderTexture& refract_texture = render_manager.get_render_texture(1);
refract_texture.Bind();
if (disp_manager->get_obj_count(mdl::OBJ_TYPE_REFRACT_OPAQUE)
|| disp_manager->get_obj_count(mdl::OBJ_TYPE_REFRACT_TRANSPARENT)
@@ -730,7 +857,9 @@ namespace rndr {
gl_state_active_bind_texture_2d(14, rctx->empty_texture_2d->glid);
if (pass_sw[RND_PASSID_REFLECT] && reflect) {
- RenderTexture& refl_tex = get_render_texture(0);
+ extern bool reflect_full;
+ RenderTexture& refl_tex = reflect_full && reflect_full_ptr
+ ? reflect_full_ptr->reflect_texture : get_render_texture(0);
gl_state_active_bind_texture_2d(15, refl_tex.GetColorTex());
uniform->arr[U_WATER_REFLECT] = 1;
}
@@ -773,7 +902,7 @@ namespace rndr {
gl_state_set_depth_mask(GL_TRUE);
if (draw_pass_3d[DRAW_PASS_3D_TRANSPARENT])
disp_manager->draw(mdl::OBJ_TYPE_TRANSPARENT);
- if (render_manager->field_120)
+ if (render_manager.field_120)
disp_manager->draw(mdl::OBJ_TYPE_TYPE_7);
render->calc_exposure_chara_data();
@@ -844,8 +973,8 @@ namespace rndr {
if (Glitter::glt_particle_manager_x->CheckHasLocalEffect()) { // X
gl_state_begin_event("local");
- float_t fov = camera_data->fov;
- camera_data->fov = 32.2673416137695f;
+ float_t fov = camera_data.fov;
+ camera_data.fov = 32.2673416137695f;
draw_pass_set_camera();
disp_manager->draw(mdl::OBJ_TYPE_OPAQUE_LOCAL);
@@ -862,7 +991,7 @@ namespace rndr {
gl_state_set_color_mask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE);
Glitter::glt_particle_manager_x->DispScenes(Glitter::DISP_LOCAL);
gl_state_set_color_mask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
- camera_data->fov = fov;
+ camera_data.fov = fov;
gl_state_end_event();
@@ -968,8 +1097,16 @@ namespace rndr {
}
void RenderManager::pass_3d_contour() {
- RenderTexture* rt = &render->rend_texture[0];
- RenderTexture* contour_rt = render->sss_contour_texture;
+ RenderTexture* rt;
+ RenderTexture* contour_rt;
+ if (reflect_draw) {
+ rt = &reflect_full_ptr->reflect_texture;
+ contour_rt = &reflect_full_ptr->reflect_buffer_texture;
+ }
+ else {
+ rt = &render->rend_texture[0];
+ contour_rt = render->sss_contour_texture;
+ }
gl_state_begin_event("`anonymous-namespace'::draw_npr_frame");
gl_state_enable_blend();
@@ -1059,15 +1196,15 @@ void image_filter_scale(RenderTexture* dst, texture* src, const vec4& scale) {
void draw_pass_set_camera() {
camera_struct::update_data();
- mat4_transpose(&camera_data->view, &rctx->view_mat);
- mat4_transpose(&camera_data->projection, &rctx->proj_mat);
- mat4_transpose(&camera_data->view_projection, &rctx->vp_mat);
+ mat4_transpose(&camera_data.view, &rctx->view_mat);
+ mat4_transpose(&camera_data.projection, &rctx->proj_mat);
+ mat4_transpose(&camera_data.view_projection, &rctx->vp_mat);
vec3 view_point;
- camera_data->get_view_point(view_point);
+ camera_data.get_view_point(view_point);
rctx->set_scene_projection_view(rctx->view_mat, rctx->proj_mat, view_point);
- float_t max_distance = camera_data->max_distance;
- float_t min_distance = camera_data->min_distance;
+ float_t max_distance = camera_data.max_distance;
+ float_t min_distance = camera_data.min_distance;
rctx->g_near_far = {
(float_t)(max_distance / (max_distance - min_distance)),
(float_t)(-(max_distance * min_distance) / (max_distance - min_distance)),
@@ -1080,8 +1217,10 @@ HOOK(void, FASTCALL, render_manager_init_render_textures, 0x0000000140502560, in
}
HOOK(void, FASTCALL, render_manager_free_data, 0x0000000140502770) {
+ if (reflect_full_ptr)
+ reflect_full_ptr->free();
render_manager_free_render_textures();
- render_manager->render->free();
+ render_manager.render->free();
shadow_ptr_free();
@@ -1093,8 +1232,6 @@ HOOK(void, FASTCALL, render_manager_free_render_textures, 0x00000001405027A0) {
}
HOOK(void, FASTCALL, render_manager_init_data, 0x0000000140502A2A, int32_t ssaa, int32_t hd_res, int32_t ss_alpha_mask, bool npr) {
- rndr::RenderManager& render_manager = *::render_manager;
-
render_manager.reset();
render_manager.npr = npr;
render_texture_counter_reset();
@@ -1119,9 +1256,25 @@ HOOK(void, FASTCALL, render_manager_init_data, 0x0000000140502A2A, int32_t ssaa,
void(FASTCALL * sub_1403B6CC0)() = (void(FASTCALL*)())0x00000001403B6CC0;
sub_1403B6CC0();
+ extern bool config_reflect_full;
+ if (reflect_full_ptr && config_reflect_full)
+ reflect_full_ptr->init();
+
glGetErrorDLL();
}
+void reflect_full_init() {
+ if (!reflect_full_ptr)
+ reflect_full_ptr = new reflect_full_struct;
+}
+
+void reflect_full_free() {
+ if (reflect_full_ptr) {
+ delete reflect_full_ptr;
+ reflect_full_ptr = 0;
+ }
+}
+
void render_manager_patch() {
WRITE_NOP_6(0x0000000140502A24);
WRITE_MEMORY(0x0000000140502A3C, uint8_t, 0xC3);
@@ -1132,6 +1285,66 @@ void render_manager_patch() {
INSTALL_HOOK(render_manager_init_data);
}
+reflect_full_struct::reflect_full_struct() {
+
+}
+
+reflect_full_struct::~reflect_full_struct() {
+ free();
+}
+
+void reflect_full_struct::free() {
+ reflect_contour_texture.Free();
+
+ reflect_buffer_texture.Free();
+ reflect_texture.Free();
+}
+
+void reflect_full_struct::init() {
+ rndr::Render* render = render_manager.render;
+
+ reflect_texture.Init(render->render_width[0], render->render_height[0],
+ 0, GL_RGBA16F, GL_DEPTH_COMPONENT24);
+ reflect_buffer_texture.Init(render->render_width[0], render->render_height[0],
+ 0, GL_RGBA16F, GL_DEPTH_COMPONENT24);
+
+ reflect_contour_texture.SetColorDepthTextures(reflect_texture.GetColorTex());
+}
+
+void get_reflect_mat() {
+ vec4 reflect_clip_plane;
+ const light_set* set = &light_set_data[LIGHT_SET_MAIN];
+ const light_data* light_reflect = &set->lights[LIGHT_REFLECT];
+ if (light_reflect->type == LIGHT_SPOT) {
+ const vec3 spot_direction = -light_reflect->spot_direction;
+ const vec3 position = *(vec3*)&light_reflect->position;
+
+ float_t length = vec3::length(spot_direction);
+ if (length > 0.000001f)
+ *(vec3*)&reflect_clip_plane = spot_direction * (1.0f / length);
+ else
+ *(vec3*)&reflect_clip_plane = { 0.0f, 1.0f, 0.0f };
+
+ reflect_clip_plane.w = -vec3::dot(position, *(vec3*)&reflect_clip_plane);
+ }
+ else if (light_reflect->type == LIGHT_POINT)
+ reflect_clip_plane = { 0.0f, -1.0f, 0.0f, 9999.0f };
+ else
+ reflect_clip_plane = { 0.0f, -1.0f, 0.0f, 0.0f };
+
+ const vec4 temp = 2.0f * reflect_clip_plane;
+
+ reflect_mat = mat4_identity;
+ *(vec3*)&reflect_mat.row0 -= temp.x * *(vec3*)&reflect_clip_plane;
+ *(vec3*)&reflect_mat.row1 -= temp.y * *(vec3*)&reflect_clip_plane;
+ *(vec3*)&reflect_mat.row2 -= temp.z * *(vec3*)&reflect_clip_plane;
+ *(vec3*)&reflect_mat.row3 -= temp.w * *(vec3*)&reflect_clip_plane;
+ reflect_mat.row0.w = 0.0f;
+ reflect_mat.row1.w = 0.0f;
+ reflect_mat.row2.w = 0.0f;
+ reflect_mat.row3.w = 1.0f;
+}
+
static void draw_pass_shadow_begin_make_shadowmap(Shadow* shad, int32_t index, int32_t a3) {
shad->curr_render_textures[0]->Bind();
shad->curr_render_textures[0]->SetViewport();
@@ -1434,21 +1647,34 @@ static bool draw_pass_shadow_litproj_set_mat(bool set_mat) {
}
static void draw_pass_sss_contour(rndr::Render* rend) {
- rend->sss_contour_texture->Bind();
- rend->sss_contour_texture->SetViewport();
+ if (reflect_draw)
+ reflect_full_ptr->reflect_buffer_texture.Bind();
+ else
+ rend->sss_contour_texture->Bind();
+
gl_state_enable_depth_test();
gl_state_set_depth_func(GL_ALWAYS);
gl_state_set_depth_mask(GL_TRUE);
- gl_state_set_viewport(0, 0, rend->render_width[0], rend->render_height[0]);
- gl_state_active_bind_texture_2d(0, rend->rend_texture[0].GetColorTex());
- gl_state_bind_sampler(0, rctx->render_samplers[1]);
- gl_state_active_bind_texture_2d(1, rend->rend_texture[0].GetDepthTex());
- gl_state_bind_sampler(1, rctx->render_samplers[1]);
+ if (reflect_draw) {
+ RenderTexture& refl_tex = reflect_full_ptr->reflect_texture;
+ gl_state_set_viewport(0, 0, refl_tex.GetWidth(), refl_tex.GetHeight());
+ gl_state_active_bind_texture_2d(0, refl_tex.GetColorTex());
+ gl_state_bind_sampler(0, rctx->render_samplers[1]);
+ gl_state_active_bind_texture_2d(1, refl_tex.GetDepthTex());
+ gl_state_bind_sampler(1, rctx->render_samplers[1]);
+ }
+ else {
+ gl_state_set_viewport(0, 0, rend->render_width[0], rend->render_height[0]);
+ gl_state_active_bind_texture_2d(0, rend->rend_texture[0].GetColorTex());
+ gl_state_bind_sampler(0, rctx->render_samplers[1]);
+ gl_state_active_bind_texture_2d(1, rend->rend_texture[0].GetDepthTex());
+ gl_state_bind_sampler(1, rctx->render_samplers[1]);
+ }
gl_state_active_texture(0);
- float_t v3 = 1.0f / tanf(camera_data->fov * 0.5f * DEG_TO_RAD_FLOAT);
+ float_t v3 = 1.0f / tanf(camera_data.fov * 0.5f * DEG_TO_RAD_FLOAT);
- vec3 direction = camera_data->interest - camera_data->view_point;
+ vec3 direction = camera_data.interest - camera_data.view_point;
float_t length = vec3::length(direction);
float_t v7 = direction.y;
if (length != 0.0f)
@@ -1465,10 +1691,17 @@ static void draw_pass_sss_contour(rndr::Render* rend) {
shaders_ft.set(SHADER_FT_CONTOUR);
rctx->contour_coef_ubo.Bind(2);
- render_get()->draw_quad(
- rend->render_post_width[0], rend->render_post_height[0],
- rend->render_post_width_scale, rend->render_post_height_scale,
- 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f);
+
+ if (reflect_draw) {
+ RenderTexture& refl_tex = reflect_full_ptr->reflect_texture;
+ render_get()->draw_quad(refl_tex.GetWidth(), refl_tex.GetHeight(), 1.0f, 1.0f,
+ 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f);
+ }
+ else
+ render_get()->draw_quad(
+ rend->render_post_width[0], rend->render_post_height[0],
+ rend->render_post_width_scale, rend->render_post_height_scale,
+ 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f);
}
static void draw_pass_sss_filter_calc_coef(double_t step, int32_t size, double_t a3, int32_t iterations,
@@ -1511,8 +1744,8 @@ static void draw_pass_sss_filter_calc_coef(double_t step, int32_t size, double_t
static void draw_pass_sss_filter(sss_data* sss) {
const int32_t sss_count = 6;
- vec3 interest = camera_data->interest;
- vec3 view_point = camera_data->view_point;
+ vec3 interest = camera_data.interest;
+ vec3 view_point = camera_data.view_point;
vec3 chara_position[2];
chara_position[0] = 0.0f;
@@ -1543,7 +1776,7 @@ static void draw_pass_sss_filter(sss_data* sss) {
interest = chara_position[0];
float_t v29 = max_def(vec3::distance(view_point, interest), 0.25f);
- float_t v31 = max_def(tanf(camera_data->fov * 0.5f * DEG_TO_RAD_FLOAT) * 5.0f, 0.25f);
+ float_t v31 = max_def(tanf(camera_data.fov * 0.5f * DEG_TO_RAD_FLOAT) * 5.0f, 0.25f);
float_t v33 = 0.6f;
float_t v34 = (float_t)(1.0 / clamp_def(v31 * v29, 0.25f, 100.0f));
if (v34 < 0.145f)
@@ -1557,7 +1790,9 @@ static void draw_pass_sss_filter(sss_data* sss) {
rndr::Render* rend = render_get();
uniform->arr[U_REDUCE] = 0;
shaders_ft.set(SHADER_FT_REDUCE);
- RenderTexture& rt = rend->rend_texture[0];
+ RenderTexture& rt = reflect_draw
+ ? reflect_full_ptr->reflect_texture
+ : rend->rend_texture[0];
gl_state_bind_texture_2d(rt.GetColorTex());
gl_state_bind_sampler(0, rctx->render_samplers[0]);
render_get()->draw_quad(rt.GetWidth(), rt.GetHeight(), 1.0f, 1.0f,
@@ -1582,7 +1817,7 @@ static void draw_pass_sss_filter(sss_data* sss) {
draw_pass_sss_filter_calc_coef(1.0, sss_count, v34, 3, a5, a6, a7, a8, shader_data.g_coef);
rctx->sss_filter_gaussian_coef_ubo.WriteMemory(shader_data);
- sss->textures[1].Bind();
+ sss->textures[reflect_draw ? 3 : 1].Bind();
gl_state_set_viewport(0, 0, 320, 180);
uniform->arr[U_SSS_FILTER] = 3;
shaders_ft.set(SHADER_FT_SSS_FILT);
@@ -1717,7 +1952,8 @@ static void draw_pass_3d_shadow_set(Shadow* shad) {
gl_state_bind_sampler(7, 0);
}
-static void draw_pass_3d_translucent(mdl::ObjType opaque, mdl::ObjType transparent, mdl::ObjType translucent) {
+static void draw_pass_3d_translucent(mdl::ObjType opaque,
+ mdl::ObjType transparent, mdl::ObjType translucent) {
if (disp_manager->get_obj_count(opaque) < 1
&& disp_manager->get_obj_count(transparent) < 1
&& disp_manager->get_obj_count(translucent) < 1)
@@ -1731,11 +1967,11 @@ static void draw_pass_3d_translucent(mdl::ObjType opaque, mdl::ObjType transpare
for (int32_t i = 0; i < count; i++) {
int32_t alpha = alpha_array[i];
rend->transparency_copy();
- if (render_manager->draw_pass_3d[DRAW_PASS_3D_OPAQUE] && disp_manager->get_obj_count(opaque))
+ if (render_manager.draw_pass_3d[DRAW_PASS_3D_OPAQUE] && disp_manager->get_obj_count(opaque))
disp_manager->draw(opaque, 0, true, alpha);
- if (render_manager->draw_pass_3d[DRAW_PASS_3D_TRANSPARENT] && disp_manager->get_obj_count(transparent))
+ if (render_manager.draw_pass_3d[DRAW_PASS_3D_TRANSPARENT] && disp_manager->get_obj_count(transparent))
disp_manager->draw(transparent, 0, true, alpha);
- if (render_manager->draw_pass_3d[DRAW_PASS_3D_TRANSLUCENT] && disp_manager->get_obj_count(translucent)) {
+ if (render_manager.draw_pass_3d[DRAW_PASS_3D_TRANSLUCENT] && disp_manager->get_obj_count(translucent)) {
gl_state_enable_blend();
disp_manager->draw(translucent, 0, true, alpha);
gl_state_disable_blend();
@@ -1780,6 +2016,167 @@ static void draw_pass_3d_translucent_has_objects(bool* arr, mdl::ObjType type) {
}
}
+RenderTexture* reflect_tex;
+
+static void draw_pass_reflect_full(rndr::RenderManager& render_manager) {
+ gl_state_begin_event("pass_reflect");
+ RenderTexture& refl_tex = reflect_full_ptr->reflect_texture;
+ RenderTexture& refl_buf_tex = reflect_full_ptr->reflect_buffer_texture;
+ refl_tex.Bind();
+ extern bool reflect_full;
+ if (disp_manager->get_obj_count(mdl::OBJ_TYPE_REFLECT_OPAQUE)
+ || disp_manager->get_obj_count(mdl::OBJ_TYPE_REFLECT_TRANSPARENT)
+ || disp_manager->get_obj_count(mdl::OBJ_TYPE_REFLECT_TRANSLUCENT_SORT_BY_RADIUS)
+ || disp_manager->get_obj_count(mdl::OBJ_TYPE_REFLECT_TRANSLUCENT)) {
+ reflect_tex = &refl_tex;
+
+ refl_tex.SetViewport();
+
+ draw_pass_set_camera();
+ if (!sss_data_get()->enable || !sss_data_get()->npr_contour)
+ glClearDLL(GL_DEPTH_BUFFER_BIT);
+
+ gl_state_set_depth_func(GL_LEQUAL);
+
+ for (int32_t i = LIGHT_SET_MAIN; i < LIGHT_SET_MAX; i++)
+ light_set_data[i].data_set((light_set_id)i);
+ for (int32_t i = FOG_DEPTH; i < FOG_MAX; i++)
+ fog_data[i].data_set((fog_id)i);
+
+ glClearColorDLL(0.0f, 0.0f, 0.0f, 0.0f);
+ if (disp_manager->get_obj_count(mdl::OBJ_TYPE_SSS))
+ glClearDLL(GL_COLOR_BUFFER_BIT);
+ else
+ glClearDLL(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ gl_state_enable_depth_test();
+ gl_state_set_depth_func(GL_LEQUAL);
+ gl_state_set_depth_mask(GL_TRUE);
+ gl_state_set_cull_face_mode(GL_FRONT);
+
+ reflect_draw = true;
+ draw_state.shader_index = -1;
+
+ int32_t render_width = refl_tex.GetWidth();
+ int32_t render_height = refl_tex.GetHeight();
+ rctx->set_scene_framebuffer_size(render_width, render_height, render_width, render_height);
+
+ if (render_manager.shadow)
+ draw_pass_3d_shadow_set(render_manager.shadow_ptr);
+ else
+ draw_pass_3d_shadow_reset();
+
+ if (render_manager.effect_texture)
+ gl_state_active_bind_texture_2d(14, render_manager.effect_texture->glid);
+ else
+ gl_state_active_bind_texture_2d(14, rctx->empty_texture_2d->glid);
+
+ uniform->arr[U_WATER_REFLECT] = 0;
+
+ sss_data_get()->set_texture(3);
+
+ gl_state_bind_sampler(14, rctx->render_samplers[0]);
+ gl_state_bind_sampler(15, rctx->render_samplers[0]);
+ gl_state_bind_sampler(16, rctx->render_samplers[0]);
+
+ uniform->arr[U_STAGE_AMBIENT] = render_manager.light_stage_ambient ? 1 : 0;
+
+ set_reflect_mat(rctx);
+
+ if (render_manager.alpha_z_sort) {
+ disp_manager->obj_sort(&rctx->view_mat,
+ mdl::OBJ_TYPE_REFLECT_TRANSLUCENT, 1, render_manager.field_31F);
+ disp_manager->obj_sort(&rctx->view_mat,
+ mdl::OBJ_TYPE_REFLECT_TRANSLUCENT_SORT_BY_RADIUS, 2);
+ }
+
+ if (render_manager.opaque_z_sort)
+ disp_manager->obj_sort(&rctx->view_mat, mdl::OBJ_TYPE_REFLECT_OPAQUE, 0);
+
+ uniform->arr[U_REFLECT] = 1;
+ if (render_manager.draw_pass_3d[DRAW_PASS_3D_OPAQUE]) {
+ gl_state_enable_depth_test();
+ gl_state_set_depth_mask(GL_TRUE);
+ disp_manager->draw(mdl::OBJ_TYPE_REFLECT_OPAQUE);
+ gl_state_disable_depth_test();
+ }
+
+ Glitter::glt_particle_manager_x->DispScenes(Glitter::DISP_OPAQUE);
+
+ gl_state_enable_depth_test();
+ gl_state_set_depth_mask(GL_TRUE);
+ if (render_manager.draw_pass_3d[DRAW_PASS_3D_TRANSPARENT])
+ disp_manager->draw(mdl::OBJ_TYPE_REFLECT_TRANSPARENT);
+
+ if (render_manager.npr_param == 1)
+ render_manager.pass_3d_contour();
+
+ gl_state_disable_depth_test();
+
+ gl_state_set_color_mask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE);
+ Glitter::glt_particle_manager_x->DispScenes(Glitter::DISP_ALPHA);
+ gl_state_set_color_mask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
+
+ /*if (npr_param == 1) {
+ gl_state_set_color_mask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE);
+ glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+ glClear(GL_COLOR_BUFFER_BIT);
+ gl_state_set_color_mask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
+ }*/
+
+ gl_state_enable_depth_test();
+
+ if (render_manager.draw_pass_3d[DRAW_PASS_3D_TRANSLUCENT]) {
+ gl_state_enable_blend();
+ gl_state_set_blend_func(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ gl_state_set_depth_mask(GL_FALSE);
+ disp_manager->draw(mdl::OBJ_TYPE_REFLECT_TRANSLUCENT_SORT_BY_RADIUS);
+ disp_manager->draw(mdl::OBJ_TYPE_REFLECT_TRANSLUCENT);
+ gl_state_disable_blend();
+ }
+
+ gl_state_set_color_mask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE); // X
+ Glitter::glt_particle_manager_x->DispScenes(Glitter::DISP_TYPE_2);
+ gl_state_set_color_mask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
+ gl_state_disable_depth_test();
+
+ gl_state_set_color_mask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE);
+ Glitter::glt_particle_manager_x->DispScenes(Glitter::DISP_NORMAL);
+ gl_state_set_color_mask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
+
+ gl_state_active_bind_texture_2d(14, 0);
+ gl_state_active_bind_texture_2d(15, 0);
+
+ if (render_manager.shadow)
+ draw_pass_3d_shadow_reset();
+
+ rndr::Render* render = render_manager.render;
+ rctx->set_scene_framebuffer_size(render->render_width[0],
+ render->render_height[0], render->render_width[0], render->render_height[0]);
+ reflect_draw = false;
+
+ gl_state_set_cull_face_mode(GL_BACK);
+ gl_state_disable_depth_test();
+ uniform->arr[U_REFLECT] = 0;
+
+ for (int32_t i = render_manager.reflect_blur_num, j = 0; i > 0; i--, j++) {
+ blur_filter_apply(&refl_buf_tex, &refl_tex,
+ render_manager.reflect_blur_filter, 1.0f, 1.0f, 0.0f);
+ image_filter_scale(&refl_tex, refl_buf_tex.color_texture);
+ }
+ }
+ else {
+ vec4 clear_color;
+ glGetFloatvDLL(GL_COLOR_CLEAR_VALUE, (GLfloat*)&clear_color);
+ glClearColorDLL(0.0f, 0.0f, 0.0f, 0.0f);
+ glClearDLL(GL_COLOR_BUFFER_BIT);
+ glClearColorDLL(clear_color.x, clear_color.y, clear_color.z, clear_color.w);
+ }
+ shader::unbind();
+ gl_state_bind_framebuffer(0);
+ gl_state_end_event();
+}
+
static void blur_filter_apply(RenderTexture* dst, RenderTexture* src,
blur_filter_mode filter, const vec2 res_scale, const vec4 scale, const vec4 offset) {
if (!dst || !src)
@@ -1818,8 +2215,6 @@ static void blur_filter_apply(RenderTexture* dst, RenderTexture* src,
}
static void render_manager_free_render_textures() {
- rndr::RenderManager& render_manager = *::render_manager;
-
if (render_manager.multisample_renderbuffer) {
glDeleteRenderbuffers(1, &render_manager.multisample_renderbuffer);
render_manager.multisample_renderbuffer = 0;
@@ -1835,8 +2230,6 @@ static void render_manager_free_render_textures() {
}
static void render_manager_init_render_textures(int32_t multisample) {
- rndr::RenderManager& render_manager = *::render_manager;
-
if (multisample) {
glGenFramebuffers(1, &render_manager.multisample_framebuffer);
glGenRenderbuffers(1, &render_manager.multisample_renderbuffer);
@@ -1874,3 +2267,31 @@ static void render_manager_init_render_textures(int32_t multisample) {
}
gl_state_bind_framebuffer(0);
}
+
+static void set_reflect_mat(render_context* rctx) {
+ const vec3 clip_plane = *(vec3*)&rctx->data.buffer_scene_data.g_clip_plane;
+ const vec4 temp = 2.0f * rctx->data.buffer_scene_data.g_clip_plane;
+
+ reflect_mat = mat4_identity;
+ *(vec3*)&reflect_mat.row0 -= temp.x * clip_plane;
+ *(vec3*)&reflect_mat.row1 -= temp.y * clip_plane;
+ *(vec3*)&reflect_mat.row2 -= temp.z * clip_plane;
+ *(vec3*)&reflect_mat.row3 -= temp.w * clip_plane;
+ reflect_mat.row0.w = 0.0f;
+ reflect_mat.row1.w = 0.0f;
+ reflect_mat.row2.w = 0.0f;
+ reflect_mat.row3.w = 1.0f;
+
+ mat4 cam_view;
+ mat4 cam_projection;
+ mat4_transpose(&camera_data.view, &cam_view);
+ mat4_transpose(&camera_data.projection, &cam_projection);
+
+ mat4_mul(&reflect_mat, &cam_view, &rctx->view_mat);
+ rctx->proj_mat = cam_projection;
+ mat4_mul(&rctx->view_mat, &rctx->proj_mat, &rctx->vp_mat);
+
+ vec3 view_point = camera_data.view_point;
+ mat4_transform_point(&reflect_mat, &view_point, &view_point);
+ rctx->set_scene_projection_view(rctx->view_mat, rctx->proj_mat, view_point);
+}
diff --git a/src/DivaGL/render_manager.hpp b/src/DivaGL/render_manager.hpp
index 10443ad..6097c18 100644
--- a/src/DivaGL/render_manager.hpp
+++ b/src/DivaGL/render_manager.hpp
@@ -135,10 +135,13 @@ namespace rndr {
extern RenderTexture* litproj_shadow;
extern RenderTexture* litproj_texture;
-extern rndr::RenderManager* render_manager;
+extern rndr::RenderManager& render_manager;
extern void image_filter_scale(RenderTexture* dst, texture* src, const vec4& scale = 1.0f);
extern void draw_pass_set_camera();
+extern void reflect_full_init();
+extern void reflect_full_free();
+
extern void render_manager_patch();
diff --git a/src/DivaGL/renderer/dof.cpp b/src/DivaGL/renderer/dof.cpp
index 01b359c..57bf332 100644
--- a/src/DivaGL/renderer/dof.cpp
+++ b/src/DivaGL/renderer/dof.cpp
@@ -45,7 +45,6 @@ namespace renderer {
if (dof_debug_data->flags & DOF_DEBUG_AUTO_FOCUS) {
size_t rob_chara_smth = get_rob_chara_smth();
- size_t rob_chr = 0;
for (int32_t i = 0; i < ROB_CHARA_COUNT; i++) {
rob_chara* rob_chr = rob_chara_array_get(rob_chara_smth, i);
if (!rob_chr || !rob_chr->is_visible())
@@ -59,24 +58,24 @@ namespace renderer {
mat4_get_translation(&mat, &chara_trans);
mat4 view;
- mat4_transpose(&camera_data->view, &view);
+ mat4_transpose(&camera_data.view, &view);
focus = -vec3::dot(*(vec3*)&view.row2, chara_trans) - view.row2.w - 0.1f;
break;
}
}
- focus = max_def(focus, camera_data->min_distance);
+ focus = max_def(focus, camera_data.min_distance);
apply_physical(rt, rt->GetColorTex(), rt->GetDepthTex(),
- camera_data->min_distance, camera_data->max_distance,
+ camera_data.min_distance, camera_data.max_distance,
focus, dof_debug_data->focal_length,
- camera_data->fov * DEG_TO_RAD_FLOAT,
+ camera_data.fov * DEG_TO_RAD_FLOAT,
dof_debug_data->f_number);
}
else {
float_t fuzzing_range = max_def(dof_debug_data->f2.fuzzing_range, 0.01f);
apply_f2(rt, rt->GetColorTex(), rt->GetDepthTex(),
- camera_data->min_distance, camera_data->max_distance,
- camera_data->fov * DEG_TO_RAD_FLOAT,
+ camera_data.min_distance, camera_data.max_distance,
+ camera_data.fov * DEG_TO_RAD_FLOAT,
dof_debug_data->f2.focus, dof_debug_data->f2.focus_range,
fuzzing_range, dof_debug_data->f2.ratio);
}
@@ -86,8 +85,8 @@ namespace renderer {
float_t fuzzing_range = max_def(dof_pv_data->f2.fuzzing_range, 0.01f);
if (dof_pv_data->f2.fuzzing_range >= 0.0099999998)
apply_f2(rt, rt->GetColorTex(), rt->GetDepthTex(),
- camera_data->min_distance, camera_data->max_distance,
- camera_data->fov * DEG_TO_RAD_FLOAT,
+ camera_data.min_distance, camera_data.max_distance,
+ camera_data.fov * DEG_TO_RAD_FLOAT,
dof_pv_data->f2.focus, dof_pv_data->f2.focus_range,
fuzzing_range, dof_pv_data->f2.ratio);
enum_or(dof_debug_data->flags, DOF_DEBUG_ENABLE_DOF);
diff --git a/src/DivaGL/rob/rob.cpp b/src/DivaGL/rob/rob.cpp
index 33c7946..248d216 100644
--- a/src/DivaGL/rob/rob.cpp
+++ b/src/DivaGL/rob/rob.cpp
@@ -262,7 +262,7 @@ void RobOsage::SetRot(float_t rot_y, float_t rot_z) {
skin_param_ptr->rot.z = rot_z * DEG_TO_RAD_FLOAT;
}
-void rob_chara_item_equip_object::disp(const mat4* mat) {
+void rob_chara_item_equip_object::disp(const mat4& mat) {
if (obj_info.is_null())
return;
@@ -277,7 +277,7 @@ void rob_chara_item_equip_object::disp(const mat4* mat) {
disp_manager->entry_obj_by_object_info_object_skin(obj_info,
&texture_pattern, &texture_data, alpha, mats, ex_data_bone_mats.data(), 0, mat);
- rob_chara_item_equip_mat = mat;
+ rob_chara_item_equip_mat = &mat;
for (ExNodeBlock*& i : node_blocks)
i->__vftable->Disp(i);
@@ -615,7 +615,7 @@ static void sub_140512C20(rob_chara_item_equip* rob_itm_equip) {
int32_t tex_pat_count = (int32_t)rob_itm_equip->texture_pattern.size();
if (tex_pat_count)
disp_manager->set_texture_pattern(tex_pat_count, rob_itm_equip->texture_pattern.data());
- disp_manager->entry_obj_by_object_info(&mat, rob_itm_equip->field_D0);
+ disp_manager->entry_obj_by_object_info(mat, rob_itm_equip->field_D0);
if (tex_pat_count)
disp_manager->set_texture_pattern();
}
@@ -633,6 +633,8 @@ static float_t sub_140512F60(rob_chara_item_equip* rob_itm_equip) {
HOOK(void, FASTCALL, rob_chara_item_equip_disp, 0x0000000140512950,
rob_chara_item_equip* rob_item_equip, int32_t chara_id) {
+ extern bool reflect_full;
+ mdl::obj_reflect_enable = reflect_full;
mdl::ObjFlags flags = (mdl::ObjFlags)0;
if (chara_reflect)
@@ -668,13 +670,13 @@ HOOK(void, FASTCALL, rob_chara_item_equip_disp, 0x0000000140512950,
disp_manager.set_texture_color_coefficients(rob_item_equip->texture_color_coefficients);
disp_manager.set_wet_param(rob_item_equip->wet);
- render_manager->field_31C |= rob_item_equip->npr_flag;
+ render_manager.field_31C |= rob_item_equip->npr_flag;
sub_140512C20(rob_item_equip);
rob_chara_age_age_array_disp(chara_id, chara_reflect, rob_item_equip->chara_color);
if (rob_item_equip->item_equip_range)
for (int32_t i = rob_item_equip->first_item_equip_object; i < rob_item_equip->max_item_equip_object; i++)
- rob_item_equip->item_equip_object[i].disp(&rob_item_equip->mat);
+ rob_item_equip->item_equip_object[i].disp(rob_item_equip->mat);
else {
for (int32_t i = ITEM_ATAMA; i < ITEM_MAX; i++) {
mdl::ObjFlags chara_flags = (mdl::ObjFlags)0;
@@ -693,7 +695,7 @@ HOOK(void, FASTCALL, rob_chara_item_equip_disp, 0x0000000140512950,
enum_and(flags, ~mdl::OBJ_SHADOW);
disp_manager.set_obj_flags((mdl::ObjFlags)(chara_flags | flags | mdl::OBJ_SSS));
- rob_item_equip->item_equip_object[i].disp(&rob_item_equip->mat);
+ rob_item_equip->item_equip_object[i].disp(rob_item_equip->mat);
}
}
disp_manager.set_texture_color_coefficients(temp_texture_color_coeff);
@@ -701,6 +703,8 @@ HOOK(void, FASTCALL, rob_chara_item_equip_disp, 0x0000000140512950,
disp_manager.set_chara_color();
disp_manager.set_obj_flags();
disp_manager.set_shadow_type();
+
+ mdl::obj_reflect_enable = false;
}
HOOK(void, FASTCALL, rob_chara_set_chara_size, 0x0000000140516810, rob_chara* rob_chr, float_t value) {
@@ -956,7 +960,7 @@ void rob_chara_age_age_object::disp(size_t chara_index,
static prj::vector* (FASTCALL * rob_chara_age_age_object__get_obj_set_texture)(rob_chara_age_age_object * rob_age_age_obj)
= (prj::vector*(FASTCALL*)(rob_chara_age_age_object * rob_age_age_obj))0x000000014045A8E0;
- disp_manager->entry_obj_by_obj(&mat4_identity, &obj,
+ disp_manager->entry_obj_by_obj(mat4_identity, &obj,
rob_chara_age_age_object__get_obj_set_texture(this),
&obj_vert_buf, &obj_index_buf, 0, 1.0f);
}
@@ -992,8 +996,8 @@ void rob_chara_arm_adjust_x::reset() {
static void rob_chara_age_age_disp(rob_chara_age_age* arr,
int32_t chara_id, bool reflect, bool chara_color) {
- bool npr = !!render_manager->npr_param;
- mat4& view = camera_data->view;
+ bool npr = !!render_manager.npr_param;
+ mat4& view = camera_data.view;
vec3 v11 = *(vec3*)&view.row2;
arr[chara_id * 3 + 0].disp(chara_id, npr, reflect, v11, chara_color);
arr[chara_id * 3 + 1].disp(chara_id, npr, reflect, v11, chara_color);
diff --git a/src/DivaGL/rob/rob.hpp b/src/DivaGL/rob/rob.hpp
index d1a3ac7..eff2c1d 100644
--- a/src/DivaGL/rob/rob.hpp
+++ b/src/DivaGL/rob/rob.hpp
@@ -1368,7 +1368,7 @@ struct rob_chara_item_equip_object {
obj_skin* skin;
rob_chara_item_equip* item_equip;
- void disp(const mat4* mat);
+ void disp(const mat4& mat);
int32_t get_bone_index(const char* name);
bone_node* get_bone_node(int32_t bone_index);
bone_node* get_bone_node(const char* name);
diff --git a/src/DivaGL/shadow.cpp b/src/DivaGL/shadow.cpp
index ba1af5b..04435af 100644
--- a/src/DivaGL/shadow.cpp
+++ b/src/DivaGL/shadow.cpp
@@ -19,9 +19,9 @@ void Shadow::ctrl() {
for (int32_t i = 0; i < 2; i++)
shadow_enable[i] = false;
- if (render_manager->shadow) {
- view_mat[0] = camera_data->view;
- view_mat[1] = camera_data->inv_view;
+ if (render_manager.shadow) {
+ view_mat[0] = camera_data.view;
+ view_mat[1] = camera_data.inv_view;
light_data& light_chara = light_set_data[LIGHT_SET_MAIN].lights[LIGHT_CHARA];
diff --git a/src/DivaGL/sprite.cpp b/src/DivaGL/sprite.cpp
index e6454e1..cd68dbb 100644
--- a/src/DivaGL/sprite.cpp
+++ b/src/DivaGL/sprite.cpp
@@ -147,11 +147,11 @@ static const GLenum spr_blend_param[6][4] = {
};
namespace spr {
- void(FASTCALL* put_cross)(const mat4* mat, color4u8 color_x, color4u8 color_y, color4u8 color_z)
- = (void(FASTCALL*)(const mat4 * mat, color4u8 color_x, color4u8 color_y, color4u8 color_z))0x00000001404BC920;
- void(FASTCALL* put_rgb_cross)(const mat4* mat) = (void(FASTCALL*)(const mat4 * mat))0x00000001404BC8F0;
- spr::SprArgs* (FASTCALL* put_sprite)(const spr::SprArgs* args)
- = (spr::SprArgs * (FASTCALL*)(const spr::SprArgs * args))0x0000000140640740;
+ void(FASTCALL* put_cross)(const mat4& mat, color4u8 color_x, color4u8 color_y, color4u8 color_z)
+ = (void(FASTCALL*)(const mat4 & mat, color4u8 color_x, color4u8 color_y, color4u8 color_z))0x00000001404BC920;
+ void(FASTCALL* put_rgb_cross)(const mat4& mat) = (void(FASTCALL*)(const mat4 & mat))0x00000001404BC8F0;
+ spr::SprArgs* (FASTCALL* put_sprite)(const spr::SprArgs& args)
+ = (spr::SprArgs * (FASTCALL*)(const spr::SprArgs & args))0x0000000140640740;
SprArgs::SprArgs() : kind(), attr(), blend(), index(), layer(),
prio(), resolution_mode_screen(), resolution_mode_sprite(), texture(),
@@ -235,13 +235,13 @@ namespace spr {
vec2 proj_sprite_3d_line(vec3 vec, bool offset) {
mat4 view;
- mat4_transpose(&camera_data->view, &view);
+ mat4_transpose(&camera_data.view, &view);
mat4_transform_point(&view, &vec, &vec);
if (fabsf(vec.z) < 1.0e-10f)
return 0.0f;
- vec2 sc_vec = camera_data->depth * *(vec2*)&vec.x * (1.0f / vec.z);
+ vec2 sc_vec = camera_data.depth * *(vec2*)&vec.x * (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;
@@ -274,7 +274,7 @@ namespace spr {
args.color = color;
args.SetSpriteSize({ p2.x - p1.x, p2.y - p1.y });
enum_or(args.attr, SPR_ATTR_MATRIX);
- spr::put_sprite(&args);
+ spr::put_sprite(args);
}
void put_sprite_line_list(vec2* points, size_t count, resolution_mode mode,
@@ -297,7 +297,7 @@ namespace spr {
}
args.SetVertexArray(vertex_array.data(), vertex_array.size());
- spr::put_sprite(&args);
+ spr::put_sprite(args);
}
void put_sprite_multi(rectangle rect, resolution_mode mode, spr::SprPrio prio, color4u8 color, int32_t layer) {
@@ -313,7 +313,7 @@ namespace spr {
args.color = color;
args.SetSpriteSize(rect.size);
enum_or(args.attr, SPR_ATTR_MATRIX);
- spr::put_sprite(&args);
+ spr::put_sprite(args);
}
void put_sprite_rect(rectangle rect, resolution_mode mode, spr::SprPrio prio, color4u8 color, int32_t layer) {
@@ -329,7 +329,7 @@ namespace spr {
args.color = color;
args.SetSpriteSize(rect.size);
enum_or(args.attr, SPR_ATTR_MATRIX);
- spr::put_sprite(&args);
+ spr::put_sprite(args);
}
void put_sprite_triangles(SpriteVertex* vert, size_t num, resolution_mode mode,
@@ -345,7 +345,7 @@ namespace spr {
args.id.info = sprite_database_get_spr_by_id(spr_id)->info;
enum_or(args.attr, SPR_ATTR_MATRIX);
args.SetVertexArray(vert, num);
- spr::put_sprite(&args);
+ spr::put_sprite(args);
}
SpriteManager::RenderData::RenderData() {
@@ -481,7 +481,7 @@ namespace spr {
float_t sprite_half_width = (float_t)res_window_get()->width * 0.5f;
float_t sprite_half_height = (float_t)res_window_get()->height * 0.5f;
- float_t aet_depth = camera_data->aet_depth;
+ float_t aet_depth = camera_data.aet_depth;
float_t aet_depth_1 = 1.0f / aet_depth;
float_t v15a = sprite_half_height * aspect[i] * 0.2f * aet_depth_1;
@@ -1441,8 +1441,8 @@ void sprite_manager_set_res(double_t aspect, int32_t width, int32_t height) {
void sprite_manager_set_view_projection(bool aet_3d) {
view_projection_aet = aet_3d
- ? camera_data->view_projection_aet_3d
- : camera_data->view_projection_aet_2d;
+ ? camera_data.view_projection_aet_3d
+ : camera_data.view_projection_aet_2d;
}
void sprite_manager_free() {
diff --git a/src/DivaGL/sprite.hpp b/src/DivaGL/sprite.hpp
index b11efaf..4996738 100644
--- a/src/DivaGL/sprite.hpp
+++ b/src/DivaGL/sprite.hpp
@@ -263,9 +263,9 @@ namespace spr {
static_assert(sizeof(spr::SprArgs) == 0xE8, "\"spr::SprArgs\" struct should have a size of 0xE8");
- extern void(FASTCALL* put_cross)(const mat4* mat, color4u8 color_x, color4u8 color_y, color4u8 color_z);
- extern void(FASTCALL* put_rgb_cross)(const mat4* mat);
- extern spr::SprArgs* (FASTCALL* put_sprite)(const spr::SprArgs* args);
+ extern void(FASTCALL* put_cross)(const mat4& mat, color4u8 color_x, color4u8 color_y, color4u8 color_z);
+ extern void(FASTCALL* put_rgb_cross)(const mat4& mat);
+ extern spr::SprArgs* (FASTCALL* put_sprite)(const spr::SprArgs& args);
vec2 proj_sprite_3d_line(vec3 vec, bool offset);
diff --git a/src/DivaGL/stage.cpp b/src/DivaGL/stage.cpp
index 49f381a..fb0564e 100644
--- a/src/DivaGL/stage.cpp
+++ b/src/DivaGL/stage.cpp
@@ -4,8 +4,9 @@
*/
#include "stage.hpp"
+#include "../KKdLib/hash.hpp"
#include "../KKdLib/mat.hpp"
-#include "../KKdLib/vec.hpp"
+#include "pv_game/firstread.hpp"
#include "object.hpp"
#include "render_context.hpp"
#include
@@ -80,13 +81,54 @@ static_assert(sizeof(stage) == 0x68, "\"stage\" struct should have a size of 0x6
extern size_t(FASTCALL* stage_data_handler_get_stage_data_count)() = (size_t(FASTCALL*)())0x000000014064AFC0;
static bool object_bounding_sphere_check_visibility_shadow(obj_bounding_sphere* sphere, mat4* mat);
-static bool object_bounding_sphere_check_visibility_shadow_chara(obj_bounding_sphere* sphere);
-static bool object_bounding_sphere_check_visibility_shadow_stage(obj_bounding_sphere* sphere);
+static bool object_bounding_sphere_check_visibility_shadow_chara(const obj_bounding_sphere* sphere);
+static bool object_bounding_sphere_check_visibility_shadow_stage(const obj_bounding_sphere* sphere);
+
+bool& chara_reflect = *(bool*)0x00000001411ADAFC;
+
+HOOK(void, FASTCALL, stage__set, 0x0000000140647710, stage* prev, stage* curr) {
+ originalstage__set(prev, curr);
+
+ extern bool reflect_full;
+ extern const firstread* firstread_ptr;
+ if (reflect_full && firstread_ptr && firstread_ptr->stage_data_array && (!curr || prev != curr) && curr) {
+ const firstread_stage_data_array* stage_data_array = firstread_ptr->stage_data_array;
+
+ ::stage_data* stage_data = curr->stage_data;
+ const uint64_t name_hash = hash_utf8_xxh3_64bits(stage_data->name);
+ const uint32_t num_stage_data = stage_data_array->num_stage_data;
+ for (uint32_t i = 0; i < num_stage_data; i++) {
+ if (hash_utf8_xxh3_64bits(stage_data_array->stage_data_array[i].name) != name_hash)
+ continue;
+
+ const firstread_stage_data* frg_stage_data = &stage_data_array->stage_data_array[i];
+
+ chara_reflect = false;
+ render_manager.reflect_type = (stage_data_reflect_type)frg_stage_data->reflect_type;
+
+ if (frg_stage_data->reflect) {
+ const stage_data_reflect* reflect = frg_stage_data->reflect;
+ render_manager.pass_sw[rndr::RND_PASSID_REFLECT] = true;
+ render_manager.reflect_blur_num = reflect->blur_num;
+ render_manager.reflect_blur_filter = (blur_filter_mode)reflect->blur_filter;
+ render_manager.reflect = true;
+ reflect_refract_resolution_mode mode = REFLECT_REFRACT_RESOLUTION_512x512;
+ if (frg_stage_data->reflect_type != STAGE_DATA_REFLECT_REFLECT_MAP)
+ mode = reflect->mode;
+ render_manager.tex_index[0] = mode;
+ }
+ break;
+ }
+ }
+}
HOOK(void, FASTCALL, stage__disp, 0x0000000140649560, stage* s) {
if (s->state != 6 || !s->stage_display)
return;
+ extern bool reflect_full;
+ mdl::obj_reflect_enable = reflect_full;
+
mdl::DispManager& disp_manager = *::disp_manager;
mat4 mat;
@@ -94,27 +136,27 @@ HOOK(void, FASTCALL, stage__disp, 0x0000000140649560, stage* s) {
mat4_transpose(&mat, &mat);
if (s->stage_data->object_ground.not_null() && s->ground)
- disp_manager.entry_obj_by_object_info(&mat, s->stage_data->object_ground);
+ disp_manager.entry_obj_by_object_info(mat, s->stage_data->object_ground);
if (s->stage_data->object_ring.not_null() && s->ring)
- disp_manager.entry_obj_by_object_info(&mat, s->stage_data->object_ring);
+ disp_manager.entry_obj_by_object_info(mat, s->stage_data->object_ring);
if (s->stage_data->object_reflect.not_null()) {
disp_manager.set_obj_flags((mdl::ObjFlags)(mdl::OBJ_NO_TRANSLUCENCY | mdl::OBJ_REFLECT));
- disp_manager.entry_obj_by_object_info(&mat, s->stage_data->object_reflect);
+ disp_manager.entry_obj_by_object_info(mat, s->stage_data->object_reflect);
disp_manager.set_obj_flags();
}
if (s->stage_data->object_refract.not_null()) {
disp_manager.set_obj_flags((mdl::ObjFlags)(mdl::OBJ_NO_TRANSLUCENCY | mdl::OBJ_REFRACT));
- disp_manager.entry_obj_by_object_info(&mat, s->stage_data->object_refract);
+ disp_manager.entry_obj_by_object_info(mat, s->stage_data->object_refract);
disp_manager.set_obj_flags();
}
if (s->stage_data->object_sky.not_null() && s->sky) {
mat4 t = s->mat;
mat4_mul(&mat, &t, &t);
- disp_manager.entry_obj_by_object_info(&t, s->stage_data->object_sky);
+ disp_manager.entry_obj_by_object_info(t, s->stage_data->object_sky);
}
if (s->stage_data->lens_flare_texture != -1 && s->lens_flare) {
@@ -131,14 +173,16 @@ HOOK(void, FASTCALL, stage__disp, 0x0000000140649560, stage* s) {
rend->lens_shaft_inv_scale = s->stage_data->lens_shaft_inv_scale;
}
}
+
+ mdl::obj_reflect_enable = false;
}
-static void stage__disp_shadow_object(object_info object, mat4* mat) {
+static void stage__disp_shadow_object(object_info object, const mat4& mat) {
mdl::DispManager& disp_manager = *::disp_manager;
for (int32_t i = SHADOW_CHARA; i < SHADOW_MAX; i++) {
disp_manager.set_shadow_type((shadow_type_enum)i);
- disp_manager.set_culling_finc(i == SHADOW_CHARA
+ disp_manager.set_culling_func(i == SHADOW_CHARA
? object_bounding_sphere_check_visibility_shadow_chara
: object_bounding_sphere_check_visibility_shadow_stage);
disp_manager.set_obj_flags((mdl::ObjFlags)(mdl::OBJ_NO_TRANSLUCENCY | mdl::OBJ_SHADOW_OBJECT));
@@ -146,7 +190,7 @@ static void stage__disp_shadow_object(object_info object, mat4* mat) {
}
disp_manager.set_obj_flags();
- disp_manager.set_culling_finc();
+ disp_manager.set_culling_func();
disp_manager.set_shadow_type();
}
@@ -159,17 +203,18 @@ HOOK(void, FASTCALL, stage__disp_shadow, 0x00000001406497C0, stage* s) {
mat4_rotate_y(s->rot_y, &mat);
mat4_transpose(&mat, &mat);
if (s->stage_data->object_shadow.not_null())
- stage__disp_shadow_object(s->stage_data->object_shadow, &mat);
+ stage__disp_shadow_object(s->stage_data->object_shadow, mat);
}
void stage_patch() {
+ INSTALL_HOOK(stage__set);
INSTALL_HOOK(stage__disp);
INSTALL_HOOK(stage__disp_shadow);
}
-static bool object_bounding_sphere_check_visibility_shadow(obj_bounding_sphere* sphere, mat4* mat) {
+static bool object_bounding_sphere_check_visibility_shadow(const obj_bounding_sphere* sphere, mat4* mat) {
mat4 view;
- mat4_transpose(&camera_data->view, &view);
+ mat4_transpose(&camera_data.view, &view);
vec3 center;
mat4_transform_point(mat, &sphere->center, ¢er);
@@ -188,14 +233,14 @@ static bool object_bounding_sphere_check_visibility_shadow(obj_bounding_sphere*
return true;
}
-static bool object_bounding_sphere_check_visibility_shadow_chara(obj_bounding_sphere* sphere) {
+static bool object_bounding_sphere_check_visibility_shadow_chara(const obj_bounding_sphere* sphere) {
mat4 mat;
Shadow* shad = shadow_ptr_get();
mat4_look_at(&shad->view_point[0], &shad->interest[0], &mat);
return object_bounding_sphere_check_visibility_shadow(sphere, &mat);
}
-static bool object_bounding_sphere_check_visibility_shadow_stage(obj_bounding_sphere* sphere) {
+static bool object_bounding_sphere_check_visibility_shadow_stage(const obj_bounding_sphere* sphere) {
mat4 mat;
Shadow* shad = shadow_ptr_get();
mat4_look_at(&shad->view_point[1], &shad->interest[1], &mat);
diff --git a/src/DivaGL/types.hpp b/src/DivaGL/types.hpp
index 2b08417..f9a704c 100644
--- a/src/DivaGL/types.hpp
+++ b/src/DivaGL/types.hpp
@@ -116,6 +116,11 @@ namespace prj {
template
class ptr_base {
+ public:
+ T* get() const {
+ return ptr;
+ }
+
private:
T* ptr;
ref_count* ref;
@@ -127,6 +132,61 @@ namespace prj {
template
class shared_ptr : public ptr_base {
public:
+ T* operator->() const {
+ return this->get();
+ }
+
+ operator bool() const {
+ return !!this->get();
+ }
+ };
+
+ struct stack_allocator {
+ size_t size;
+ uint8_t* begin;
+ uint8_t* end;
+ uint8_t* capacity_end;
+
+ inline void* allocate(size_t size) {
+ static void* (*prj__stack_allocator__allocate)(prj::stack_allocator * This, size_t size)
+ = (void* (*)(prj::stack_allocator * This, size_t size))0x000000014009B110;
+ return prj__stack_allocator__allocate(this, size);
+ }
+
+ template
+ inline T* allocate() {
+ return new((T*)allocate(sizeof(T))) T;
+ }
+
+ template
+ inline T* allocate(size_t size) {
+ if (!size)
+ return 0;
+
+ T* arr = (T*)allocate(sizeof(T) * size);
+ for (size_t i = 0; i < size; i++)
+ new(&arr[i]) T();
+ return arr;
+ }
+
+ template
+ inline T* allocate(const T* src) {
+ if (!src)
+ return 0;
+
+ return new((T*)allocate(sizeof(T))) T(*src);
+ }
+
+ template
+ inline T* allocate(const T* src, size_t size) {
+ if (!src || !size)
+ return 0;
+
+ T* dst = (T*)allocate(sizeof(T) * size);
+ for (size_t i = 0; i < size; i++)
+ new(&dst[i]) T(src[i]);
+ return dst;
+ }
};
template