Synced changes for X Pack specific stuff between repos
This commit is contained in:
Binary file not shown.
@@ -166,6 +166,7 @@ del "$(SolutionDir)bin\$(TargetName).lib"</Command>
|
||||
<ClCompile Include="mdl\disp_manager.cpp" />
|
||||
<ClCompile Include="mdl\draw_object.cpp" />
|
||||
<ClCompile Include="pv_game\dsc.cpp" />
|
||||
<ClCompile Include="pv_game\firstread.cpp" />
|
||||
<ClCompile Include="pv_game\pvpp.cpp" />
|
||||
<ClCompile Include="pv_game\pvsr.cpp" />
|
||||
<ClCompile Include="pv_game\pv_game.cpp" />
|
||||
@@ -225,6 +226,7 @@ del "$(SolutionDir)bin\$(TargetName).lib"</Command>
|
||||
<ClInclude Include="mdl\disp_manager.hpp" />
|
||||
<ClInclude Include="mdl\draw_object.hpp" />
|
||||
<ClInclude Include="pv_game\dsc.hpp" />
|
||||
<ClInclude Include="pv_game\firstread.hpp" />
|
||||
<ClInclude Include="pv_game\pvpp.hpp" />
|
||||
<ClInclude Include="pv_game\pvsr.hpp" />
|
||||
<ClInclude Include="pv_game\pv_game.hpp" />
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#include "glitter.hpp"
|
||||
|
||||
namespace Glitter {
|
||||
Counter* counter = (Counter*)0x0000000141199CB0;
|
||||
Counter& counter = *(Counter*)0x0000000141199CB0;
|
||||
|
||||
void Counter::Increment() {
|
||||
value++;
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
*/
|
||||
|
||||
#include "glitter.hpp"
|
||||
#include "../../KKdLib/prj/algorithm.hpp"
|
||||
#include "../object.hpp"
|
||||
#include "../texture.hpp"
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -55,5 +55,4 @@ namespace Glitter {
|
||||
hist_data->translation = temp;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
+79
-11
@@ -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<auth_3d_curve>* 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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
+19
-19
@@ -8,10 +8,10 @@
|
||||
#include "resolution_mode.hpp"
|
||||
#include <Helpers.h>
|
||||
|
||||
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) {
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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] = {};
|
||||
|
||||
+13
-13
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+6
-4
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
+486
-139
File diff suppressed because it is too large
Load Diff
@@ -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<GLuint>* 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<GLuint>* 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<mdl::ObjData*> 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<GLuint>* 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<GLuint>* 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<GLuint>* 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<GLuint>* 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<GLuint>* textures, obj_mesh_vertex_buffer_aft* obj_vert_buf,
|
||||
void entry_obj_by_obj(const mat4& mat,
|
||||
const ::obj* obj, prj::vector<GLuint>* 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_struct>* 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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
+175
-3
@@ -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<prj::stack_allocator>& 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<obj_sub_mesh>(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);
|
||||
}
|
||||
|
||||
|
||||
+12
-5
@@ -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();
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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<prj::stack_allocator>& 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<prj::stack_allocator>*)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;
|
||||
}
|
||||
@@ -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<prj::stack_allocator>& 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);
|
||||
};
|
||||
@@ -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 <Helpers.h>
|
||||
@@ -620,26 +621,30 @@ public:
|
||||
void stop_current_pv();
|
||||
};
|
||||
|
||||
struct x_pv_game_str_array {
|
||||
prj::unordered_map<int32_t, prj::unordered_map<int32_t, const char*>> strings;
|
||||
struct x_pv_game_firstread {
|
||||
prj::unordered_map<int32_t, prj::unordered_map<int32_t, const char*>> 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<int32_t, const char*>& 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<int32_t, const char*>& 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;
|
||||
}
|
||||
|
||||
+13
-13
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
+471
-50
@@ -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 <Helpers.h>
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
|
||||
+13
-9
@@ -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<GLuint>* (FASTCALL * rob_chara_age_age_object__get_obj_set_texture)(rob_chara_age_age_object * rob_age_age_obj)
|
||||
= (prj::vector<GLuint>*(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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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];
|
||||
|
||||
|
||||
+15
-15
@@ -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() {
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
+61
-16
@@ -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 <Helpers.h>
|
||||
@@ -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);
|
||||
|
||||
@@ -116,6 +116,11 @@ namespace prj {
|
||||
|
||||
template<class T>
|
||||
class ptr_base {
|
||||
public:
|
||||
T* get() const {
|
||||
return ptr;
|
||||
}
|
||||
|
||||
private:
|
||||
T* ptr;
|
||||
ref_count<T>* ref;
|
||||
@@ -127,6 +132,61 @@ namespace prj {
|
||||
template<class T>
|
||||
class shared_ptr : public ptr_base<T> {
|
||||
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 <typename T>
|
||||
inline T* allocate() {
|
||||
return new((T*)allocate(sizeof(T))) T;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
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 <typename T>
|
||||
inline T* allocate(const T* src) {
|
||||
if (!src)
|
||||
return 0;
|
||||
|
||||
return new((T*)allocate(sizeof(T))) T(*src);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
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<typename T, typename U>
|
||||
|
||||
Reference in New Issue
Block a user