274 lines
9.6 KiB
C++
274 lines
9.6 KiB
C++
/*
|
|
by korenkonder
|
|
GitHub/GitLab: korenkonder
|
|
*/
|
|
|
|
#include "sprite.hpp"
|
|
#include "camera.hpp"
|
|
#include "shader.hpp"
|
|
#include <Helpers.h>
|
|
|
|
namespace spr {
|
|
struct SpriteVertexData {
|
|
size_t max_count;
|
|
spr::SpriteVertex* array;
|
|
};
|
|
}
|
|
|
|
vec4& spr_color = *(vec4*)0x00000001411ACC30;
|
|
|
|
void (FASTCALL* sprite_manager_unload_set)(int32_t set_id)
|
|
= (void (FASTCALL*)(int32_t set_id))0x000000014063F8D0;
|
|
size_t(FASTCALL* sprite_manager_get_reqlist_count)(int32_t index)
|
|
= (size_t(FASTCALL*)(int32_t index))0x000000014063FA90;
|
|
void (FASTCALL* sprite_manager_read_file)(int32_t set_id, const prj::string mdata_dir)
|
|
= (void (FASTCALL*)(int32_t set_id, const prj::string mdata_dir))0x0000000140640E10;
|
|
bool (FASTCALL* sprite_manager_load_file)(int32_t set_id)
|
|
= (bool (FASTCALL*)(int32_t set_id))0x0000000140640FB0;
|
|
|
|
spr::SpriteVertexData& sprite_vertex_data = *(spr::SpriteVertexData*)0x000000014CC62480;
|
|
|
|
const size_t sprite_vertex_array_max_count = 0x2000;
|
|
spr::SpriteVertex* sprite_vertex_array = (spr::SpriteVertex*)0x000000014CC62480;
|
|
|
|
size_t& sprite_vertex_array_count = *(size_t*)0x000000014CC611B0;
|
|
|
|
const size_t sprite_manager = 0x000000014CC611C0;
|
|
const size_t sprite_database = 0x000000014CC62290;
|
|
|
|
bool sprite_break_sprite_vertex_limit = false;
|
|
|
|
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;
|
|
|
|
SprArgs::SprArgs() : kind(), attr(), blend(), index(), layer(),
|
|
prio(), resolution_mode_screen(), resolution_mode_sprite(), texture(),
|
|
shader(), vertex_array(), num_vertex(), flags(), field_CC(), next() {
|
|
Reset();
|
|
}
|
|
|
|
SpriteVertex* SprArgs::GetVertexArray() {
|
|
if (sprite_break_sprite_vertex_limit)
|
|
return sprite_vertex_data.array + vertex_array;
|
|
else
|
|
return vertex_array_ptr;
|
|
}
|
|
|
|
void SprArgs::Reset() {
|
|
kind = SPR_KIND_NORMAL;
|
|
id = {};
|
|
color = 0xFFFFFFFF;
|
|
attr = (SprAttr)0;
|
|
blend = 0;
|
|
index = -1;
|
|
layer = 0;
|
|
prio = SPR_PRIO_DEFAULT;
|
|
resolution_mode_screen = RESOLUTION_MODE_HD;
|
|
resolution_mode_sprite = RESOLUTION_MODE_HD;
|
|
center = 0.0f;
|
|
trans = 0.0f;
|
|
scale = 1.0f;
|
|
rot = 0.0f;
|
|
skew_angle = 0.0f;
|
|
mat = mat4_identity;
|
|
texture = 0;
|
|
shader = SHADER_FFP;
|
|
if (sprite_break_sprite_vertex_limit)
|
|
vertex_array = -1;
|
|
else
|
|
vertex_array = 0;
|
|
num_vertex = 0;
|
|
flags = (SprArgs::Flags)0;
|
|
sprite_size = 0.0f;
|
|
field_CC = 0;
|
|
texture_pos = 0.0f;
|
|
texture_size = 1.0f;
|
|
next = 0;
|
|
}
|
|
|
|
void SprArgs::SetSpriteSize(vec2 size) {
|
|
if (flags & SPRITE_SIZE)
|
|
return;
|
|
|
|
enum_or(flags, SPRITE_SIZE);
|
|
sprite_size = size;
|
|
field_CC = 0;
|
|
}
|
|
|
|
void SprArgs::SetTexturePosSize(float_t x, float_t y, float_t width, float_t height) {
|
|
if (flags & TEXTURE_POS_SIZE)
|
|
return;
|
|
|
|
enum_or(flags, TEXTURE_POS_SIZE);
|
|
texture_pos.x = x;
|
|
texture_pos.y = y;
|
|
texture_size.x = width;
|
|
texture_size.y = height;
|
|
}
|
|
|
|
void SprArgs::SetVertexArray(SpriteVertex* vertex_array, size_t num_vertex) {
|
|
void (FASTCALL * spr__SprArgs__SetVertexArray)(spr::SprArgs * This,
|
|
spr::SpriteVertex * vertex_array, size_t num_vertex)
|
|
= (void (FASTCALL*)(spr::SprArgs * This,
|
|
spr::SpriteVertex * vertex_array, size_t num_vertex))0x000000014063F040;
|
|
spr__SprArgs__SetVertexArray(this, vertex_array, num_vertex);
|
|
}
|
|
|
|
void SprArgs::SetNext(SprArgs* args, SprArgs* next) {
|
|
while (args->next)
|
|
args = args->next;
|
|
args->next = next;
|
|
next->kind = SPR_KIND_CHILD;
|
|
}
|
|
|
|
vec2 proj_sprite_3d_line(vec3 vec, bool offset) {
|
|
mat4 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);
|
|
|
|
resolution_struct* res_wind_int = res_window_internal_get();
|
|
sc_vec.x = (float_t)res_wind_int->width * 0.5f - sc_vec.x;
|
|
sc_vec.y = (float_t)res_wind_int->height * 0.5f + sc_vec.y;
|
|
if (offset) {
|
|
resolution_struct* res_wind = res_window_get();
|
|
sc_vec.x = (float_t)res_wind_int->x_offset + sc_vec.x;
|
|
sc_vec.y = (float_t)(res_wind->height
|
|
- res_wind_int->y_offset - res_wind_int->height) + sc_vec.y;
|
|
}
|
|
return sc_vec;
|
|
}
|
|
|
|
void put_sprite_3d_line(vec3 p1, vec3 p2, color4u8 color) {
|
|
vec2 sc_p1 = proj_sprite_3d_line(p1, true);
|
|
vec2 sc_p2 = proj_sprite_3d_line(p2, true);
|
|
spr::put_sprite_line(sc_p1, sc_p2, RESOLUTION_MODE_MAX, SPR_PRIO_DEBUG, color, 0);
|
|
}
|
|
|
|
void put_sprite_line(vec2 p1, vec2 p2, resolution_mode mode, spr::SprPrio prio, color4u8 color, int32_t layer) {
|
|
spr::SprArgs args;
|
|
args.trans.x = p1.x;
|
|
args.trans.y = p1.y;
|
|
args.trans.z = 0.0f;
|
|
args.layer = layer;
|
|
args.kind = SPR_KIND_LINE;
|
|
args.resolution_mode_screen = mode;
|
|
args.resolution_mode_sprite = mode;
|
|
args.prio = prio;
|
|
args.color = color;
|
|
args.SetSpriteSize({ p2.x - p1.x, p2.y - p1.y });
|
|
enum_or(args.attr, SPR_ATTR_MATRIX);
|
|
spr::put_sprite(args);
|
|
}
|
|
|
|
void put_sprite_poly_line(vec2* points, size_t count, resolution_mode mode,
|
|
spr::SprPrio prio, color4u8 color, int32_t layer) {
|
|
spr::SprArgs args;
|
|
args.kind = SPR_KIND_POLY_LINE;
|
|
args.layer = layer;
|
|
args.resolution_mode_screen = mode;
|
|
args.resolution_mode_sprite = mode;
|
|
args.prio = prio;
|
|
args.color = color;
|
|
|
|
std::vector<spr::SpriteVertex> vertex_array;
|
|
vertex_array.reserve(count);
|
|
|
|
for (size_t i = 0; i < count; i++, points++) {
|
|
spr::SpriteVertex vert = {};
|
|
*(vec2*)&vert.pos = *points;
|
|
vertex_array.push_back(vert);
|
|
}
|
|
|
|
args.SetVertexArray(vertex_array.data(), vertex_array.size());
|
|
spr::put_sprite(args);
|
|
}
|
|
|
|
void put_sprite_rect_draw(rectangle rect, resolution_mode mode, spr::SprPrio prio, color4u8 color, int32_t layer) {
|
|
spr::SprArgs args;
|
|
args.trans.x = rect.pos.x;
|
|
args.trans.y = rect.pos.y;
|
|
args.trans.z = 0.0f;
|
|
args.layer = layer;
|
|
args.kind = SPR_KIND_RECT_DRAW;
|
|
args.resolution_mode_screen = mode;
|
|
args.resolution_mode_sprite = mode;
|
|
args.prio = prio;
|
|
args.color = color;
|
|
args.SetSpriteSize(rect.size);
|
|
enum_or(args.attr, SPR_ATTR_MATRIX);
|
|
spr::put_sprite(args);
|
|
}
|
|
|
|
void put_sprite_rect_fill(rectangle rect, resolution_mode mode, spr::SprPrio prio, color4u8 color, int32_t layer) {
|
|
spr::SprArgs args;
|
|
args.trans.x = rect.pos.x;
|
|
args.trans.y = rect.pos.y;
|
|
args.trans.z = 0.0f;
|
|
args.layer = layer;
|
|
args.kind = SPR_KIND_RECT_FILL;
|
|
args.resolution_mode_screen = mode;
|
|
args.resolution_mode_sprite = mode;
|
|
args.prio = prio;
|
|
args.color = color;
|
|
args.SetSpriteSize(rect.size);
|
|
enum_or(args.attr, SPR_ATTR_MATRIX);
|
|
spr::put_sprite(args);
|
|
}
|
|
|
|
void put_sprite_strip(SpriteVertex* vert, size_t num, resolution_mode mode,
|
|
SprPrio prio, int32_t spr_id, int32_t layer) {
|
|
spr::SprArgs args;
|
|
args.layer = layer;
|
|
args.kind = SPR_KIND_STRIP;
|
|
args.resolution_mode_screen = mode;
|
|
args.resolution_mode_sprite = mode;
|
|
args.prio = prio;
|
|
args.color = vert[0].color;
|
|
if (spr_id != -1)
|
|
args.id.info = sprite_database_get_spr_by_id(spr_id)->info;
|
|
enum_or(args.attr, SPR_ATTR_MATRIX);
|
|
args.SetVertexArray(vert, num);
|
|
spr::put_sprite(args);
|
|
}
|
|
}
|
|
|
|
const spr_db_spr* sprite_database_get_spr_by_id(int32_t id) {
|
|
const spr_db_spr* (FASTCALL * sprite_database_struct__get_spr_by_id)(size_t _this, int32_t id)
|
|
= (const spr_db_spr * (FASTCALL*)(size_t _this, int32_t id))0x000000014063C800;
|
|
return sprite_database_struct__get_spr_by_id(sprite_database, id);
|
|
}
|
|
|
|
int32_t sprite_database_get_spr_set_id_by_name(const prj::string& name) {
|
|
int32_t(FASTCALL * sprite_database_struct__get_spr_set_id_by_name)(size_t _this, const prj::string & name)
|
|
= (int32_t(FASTCALL*)(size_t _this, const prj::string & name))0x00000001401121A0;
|
|
return sprite_database_struct__get_spr_set_id_by_name(sprite_database, name);
|
|
}
|
|
|
|
texture* sprite_manager_get_spr_texture(spr_info info) {
|
|
texture* (FASTCALL * spr__SpriteManager__GetSprTexture)(size_t _this, uint32_t info)
|
|
= (texture * (FASTCALL*)(size_t _this, uint32_t info))0x000000014063C990;
|
|
return spr__SpriteManager__GetSprTexture(sprite_manager, *(uint32_t*)&info);
|
|
}
|
|
|
|
void sprite_shared_init() {
|
|
const uint8_t orig_spr__SprArgs__SetVertexArray[] = {
|
|
0x40, 0x53, 0x48, 0x83, 0xEC, 0x20, 0x48, 0x8B,
|
|
0x05, 0x63, 0x21, 0x62, 0x0C, 0x4C, 0x8B, 0xC9,
|
|
};
|
|
|
|
if (memcmp((void*)0x000000014063F040, (void*)orig_spr__SprArgs__SetVertexArray,
|
|
sizeof(orig_spr__SprArgs__SetVertexArray)))
|
|
sprite_break_sprite_vertex_limit = true;
|
|
else
|
|
sprite_break_sprite_vertex_limit = false;
|
|
}
|