Added more funcs to PrintWork
This commit is contained in:
@@ -4,3 +4,19 @@
|
||||
*/
|
||||
|
||||
#include "color.hpp"
|
||||
|
||||
const color4u8 color_black = 0xFF000000;
|
||||
const color4u8 color_grey = 0xFF7F7F7F;
|
||||
const color4u8 color_white = 0xFFFFFFFF;
|
||||
const color4u8 color_red = 0xFF0000FF;
|
||||
const color4u8 color_green = 0xFF00FF00;
|
||||
const color4u8 color_blue = 0xFFFF0000;
|
||||
const color4u8 color_cyan = 0xFFFFFF00;
|
||||
const color4u8 color_magenta = 0xFFFF00FF;
|
||||
const color4u8 color_yellow = 0xFF00FFFF;
|
||||
const color4u8 color_dark_red = 0xFF00007F;
|
||||
const color4u8 color_dark_green = 0xFF007F00;
|
||||
const color4u8 color_dark_blue = 0xFF7F0000;
|
||||
const color4u8 color_dark_cyan = 0xFF7F7F00;
|
||||
const color4u8 color_dark_magenta = 0xFF7F007F;
|
||||
const color4u8 color_dark_yellow = 0xFF007F7F;
|
||||
|
||||
+36
-2
@@ -29,7 +29,7 @@ struct color4u8 {
|
||||
a = (uint8_t)((value >> 24) & 0xFF);
|
||||
}
|
||||
|
||||
inline color4u8(vec4 value) {
|
||||
inline color4u8(const vec4& value) {
|
||||
vec4i _value = vec4i::store_xmm(_mm_cvtps_epi32(vec4::load_xmm(vec4::clamp(value, 0.0f, 1.0f) * 255.0f)));
|
||||
r = (uint8_t)_value.x;
|
||||
g = (uint8_t)_value.y;
|
||||
@@ -40,6 +40,8 @@ struct color4u8 {
|
||||
inline operator vec4() const {
|
||||
return vec4::store_xmm(_mm_cvtepi32_ps(vec4i::load_xmm(vec4i(r, g, b, a)))) * (1.0f / 255.0f);
|
||||
}
|
||||
|
||||
inline color4u8(const struct color4u8_bgra& value);
|
||||
};
|
||||
|
||||
struct color4u8_bgra {
|
||||
@@ -63,7 +65,7 @@ struct color4u8_bgra {
|
||||
a = (uint8_t)((value >> 24) & 0xFF);
|
||||
}
|
||||
|
||||
inline color4u8_bgra(vec4 value) {
|
||||
inline color4u8_bgra(const vec4& value) {
|
||||
vec4i _value = vec4i::store_xmm(_mm_cvtps_epi32(vec4::load_xmm(vec4::clamp(value, 0.0f, 1.0f) * 255.0f)));
|
||||
r = (uint8_t)_value.x;
|
||||
g = (uint8_t)_value.y;
|
||||
@@ -74,4 +76,36 @@ struct color4u8_bgra {
|
||||
inline operator vec4() const {
|
||||
return vec4::store_xmm(_mm_cvtepi32_ps(vec4i::load_xmm(vec4i(r, g, b, a)))) * (1.0f / 255.0f);
|
||||
}
|
||||
|
||||
color4u8_bgra(const struct color4u8& value);
|
||||
};
|
||||
|
||||
inline color4u8::color4u8(const color4u8_bgra& value) {
|
||||
r = value.r;
|
||||
g = value.g;
|
||||
b = value.b;
|
||||
a = value.a;
|
||||
}
|
||||
|
||||
inline color4u8_bgra::color4u8_bgra(const color4u8& value) {
|
||||
r = value.r;
|
||||
g = value.g;
|
||||
b = value.b;
|
||||
a = value.a;
|
||||
}
|
||||
|
||||
extern const color4u8 color_black;
|
||||
extern const color4u8 color_grey;
|
||||
extern const color4u8 color_white;
|
||||
extern const color4u8 color_red;
|
||||
extern const color4u8 color_green;
|
||||
extern const color4u8 color_blue;
|
||||
extern const color4u8 color_cyan;
|
||||
extern const color4u8 color_magenta;
|
||||
extern const color4u8 color_yellow;
|
||||
extern const color4u8 color_dark_red;
|
||||
extern const color4u8 color_dark_green;
|
||||
extern const color4u8 color_dark_blue;
|
||||
extern const color4u8 color_dark_cyan;
|
||||
extern const color4u8 color_dark_magenta;
|
||||
extern const color4u8 color_dark_yellow;
|
||||
|
||||
+444
-22
@@ -4,6 +4,19 @@
|
||||
*/
|
||||
|
||||
#include "print_work.hpp"
|
||||
#include "shader_ft.hpp"
|
||||
|
||||
static const font_character font_character_null = {};
|
||||
|
||||
const font_character* font::get_character(wchar_t c) const {
|
||||
if (c >= 0 && c < characters.size())
|
||||
return &characters[c];
|
||||
return &font_character_null;
|
||||
}
|
||||
|
||||
font_char::font_char() : glyph_offset(), glyph_width(), field_18() {
|
||||
|
||||
}
|
||||
|
||||
font_info::font_info() : font_ptr(), type() {
|
||||
font_handler_index = -1;
|
||||
@@ -19,6 +32,30 @@ font_info::font_info(int32_t font_handler_index) : font_ptr(), type() {
|
||||
font_info__font_info(this, font_handler_index);
|
||||
}
|
||||
|
||||
font_char* font_info::get_char_data(wchar_t c, font_char* font_c) const {
|
||||
const font_character* fc = font_ptr->get_character(c);
|
||||
if (!fc->init)
|
||||
return 0;
|
||||
|
||||
vec2 glyph_size = font_glyph;
|
||||
if (fc->halfwidth)
|
||||
glyph_size.x *= 0.5f;
|
||||
|
||||
float_t glyph_offset = 0.0f;
|
||||
float_t glyph_width = glyph_size.x;
|
||||
if (type == 2) {
|
||||
glyph_offset = (float_t)fc->glyph_offset;
|
||||
glyph_width = (float_t)fc->glyph_width;
|
||||
}
|
||||
|
||||
font_c->tex.pos = vec2((float_t)fc->tex_column, (float_t)fc->tex_row) * font_glyph_box;
|
||||
font_c->tex.size = glyph_size;
|
||||
font_c->glyph_offset = glyph_offset;
|
||||
font_c->glyph_width = glyph_width;
|
||||
font_c->field_18 = 0;
|
||||
return font_c;
|
||||
}
|
||||
|
||||
void font_info::set_glyph_size(float_t glyph_width, float_t glyph_height) {
|
||||
glyph.x = glyph_width;
|
||||
glyph.y = glyph_height;
|
||||
@@ -26,6 +63,70 @@ void font_info::set_glyph_size(float_t glyph_width, float_t glyph_height) {
|
||||
glyph_ratio.y = glyph_height / font_glyph.y;
|
||||
}
|
||||
|
||||
bool font_info::sub_140199170() const {
|
||||
return font_glyph != glyph && font_glyph == font_glyph_box;
|
||||
}
|
||||
|
||||
sprite_text_mesh::sprite_text_mesh() {
|
||||
sprite_id = -1;
|
||||
}
|
||||
|
||||
sprite_text_mesh::~sprite_text_mesh() {
|
||||
|
||||
}
|
||||
|
||||
spr::SpriteVertex* sprite_text_mesh::add_char() {
|
||||
size_t size = vertices.size();
|
||||
vertices.resize(size + 4);
|
||||
return &vertices.data()[size];
|
||||
}
|
||||
|
||||
void sprite_text_mesh::add_set_char(app::text_flags flags, rectangle pos, rectangle uv, color4u8 color) {
|
||||
sprite_text_mesh::set_char(add_char(), flags, pos, uv, color);
|
||||
}
|
||||
|
||||
void sprite_text_mesh::apply_scale_offset(vec2 scale, vec2 offset) {
|
||||
for (spr::SpriteVertex& i : vertices)
|
||||
*(vec2*)&i.pos.x = *(vec2*)&i.pos.x * scale + offset;
|
||||
}
|
||||
|
||||
void sprite_text_mesh::set_char(spr::SpriteVertex* vtx, app::text_flags flags, rectangle pos, rectangle uv, color4u8 color) {
|
||||
vec2 uv_size = uv.size;
|
||||
vec2 uv_pos = uv.pos;
|
||||
if (flags & app::TEXT_FLAG_11) {
|
||||
uv_pos += 0.5f;
|
||||
uv_size += -1.0f;
|
||||
}
|
||||
|
||||
vtx[0].pos.x = pos.pos.x;
|
||||
vtx[0].pos.y = pos.pos.y;
|
||||
vtx[0].pos.z = 0.0f;
|
||||
vtx[0].uv.x = uv_pos.x;
|
||||
vtx[0].uv.y = uv_pos.y;
|
||||
vtx[0].color = color;
|
||||
|
||||
vtx[1].pos.x = pos.pos.x + pos.size.x;
|
||||
vtx[1].pos.y = pos.pos.y;
|
||||
vtx[1].pos.z = 0.0;
|
||||
vtx[1].uv.x = uv_pos.x + uv_size.x;
|
||||
vtx[1].uv.y = uv_pos.y;
|
||||
vtx[1].color = color;
|
||||
|
||||
vtx[2].pos.x = pos.pos.x + pos.size.x;
|
||||
vtx[2].pos.y = pos.pos.y + pos.size.y;
|
||||
vtx[2].pos.z = 0.0f;
|
||||
vtx[2].uv.x = uv_pos.x + uv_size.x;
|
||||
vtx[2].uv.y = uv_pos.y + uv_size.y;
|
||||
vtx[2].color = color;
|
||||
|
||||
vtx[3].pos.x = pos.pos.x;
|
||||
vtx[3].pos.y = pos.pos.y + pos.size.y;
|
||||
vtx[3].pos.z = 0.0f;
|
||||
vtx[3].uv.x = uv_pos.x;
|
||||
vtx[3].uv.y = uv_pos.y + uv_size.y;
|
||||
vtx[3].color = color;
|
||||
}
|
||||
|
||||
PrintWork::PrintWork() : clip(), layer(), field_28(), line_length() {
|
||||
color = 0xFFFFFFFF;
|
||||
fill_color = 0xFF808080;
|
||||
@@ -35,56 +136,377 @@ PrintWork::PrintWork() : clip(), layer(), field_28(), line_length() {
|
||||
empty_char = L'\x25A1';
|
||||
}
|
||||
|
||||
void PrintWork::DrawLine(vec2 pos[2]) {
|
||||
spr::put_sprite_line(pos[0], pos[1], resolution_mode, prio, color, layer);
|
||||
}
|
||||
|
||||
void PrintWork::DrawPolyLine(vec2* points, size_t count) {
|
||||
spr::put_sprite_line_list(points, count, resolution_mode, prio, color, layer);
|
||||
}
|
||||
|
||||
void PrintWork::DrawRectangle(rectangle rect) {
|
||||
spr::put_sprite_multi(rect, resolution_mode, prio, color, layer);
|
||||
}
|
||||
|
||||
void PrintWork::DrawTextMesh(app::text_flags flags, sprite_text_mesh& mesh) {
|
||||
if (!mesh.vertices.size())
|
||||
return;
|
||||
|
||||
spr::SprArgs args;
|
||||
args.blend = (field_28 >> 3) & 0x02;
|
||||
args.resolution_mode_screen = resolution_mode;
|
||||
args.resolution_mode_sprite = args.resolution_mode_screen;
|
||||
args.prio = prio;
|
||||
args.color = color;
|
||||
args.layer = layer;
|
||||
|
||||
if (field_28 & 0x02) {
|
||||
for (spr::SpriteVertex& i : mesh.vertices) {
|
||||
i.color.r = 0x40;
|
||||
i.color.g = 0x40;
|
||||
i.color.b = 0x40;
|
||||
i.pos += 2.0f;
|
||||
}
|
||||
args.SetVertexArray(mesh.vertices.data(), mesh.vertices.size());
|
||||
args.id.index = mesh.sprite_id;
|
||||
spr::put_sprite(&args);
|
||||
|
||||
for (spr::SpriteVertex& i : mesh.vertices) {
|
||||
i.color.r = color.r;
|
||||
i.color.g = color.g;
|
||||
i.color.b = color.b;
|
||||
i.pos.x -= 2.0f;
|
||||
i.pos.y -= 2.0f;
|
||||
}
|
||||
}
|
||||
|
||||
args.SetVertexArray(mesh.vertices.data(), mesh.vertices.size());
|
||||
if (flags & app::TEXT_FLAG_FONT)
|
||||
args.shader = SHADER_FT_FONT;
|
||||
args.id.index = mesh.sprite_id;
|
||||
spr::put_sprite(&args);
|
||||
}
|
||||
|
||||
void PrintWork::FillRectangle(rectangle rect) {
|
||||
if (clip) {
|
||||
float_t clip_max_pos_x;
|
||||
PrintWork::ClampPosToClipBox(rect.pos.x, rect.pos.x + rect.size.x,
|
||||
clip_data.pos.x, clip_data.pos.x + clip_data.size.x, rect.pos.x, clip_max_pos_x);
|
||||
rect.size.x = clip_max_pos_x - rect.pos.x;
|
||||
|
||||
float_t clip_max_pos_y;
|
||||
PrintWork::ClampPosToClipBox(rect.pos.y, rect.pos.y + rect.size.y,
|
||||
clip_data.pos.y, clip_data.pos.y + clip_data.size.y, rect.pos.y, clip_max_pos_y);
|
||||
rect.size.y = clip_max_pos_y - rect.pos.y;
|
||||
}
|
||||
|
||||
spr::put_sprite_rect(rect, resolution_mode, prio, fill_color, layer);
|
||||
}
|
||||
|
||||
font_char PrintWork::GetCharData(wchar_t c) {
|
||||
font_char font_c = {};
|
||||
if (!font->get_char_data(c, &font_c))
|
||||
font->get_char_data(empty_char, &font_c);
|
||||
return font_c;
|
||||
}
|
||||
|
||||
rectangle PrintWork::GetClipBox(app::text_flags flags, vec2 glyph_size, vec2 glyph_ratio) {
|
||||
glyph_ratio = 1.0f / glyph_ratio;
|
||||
rectangle clip_box;
|
||||
clip_box.pos = (clip_data.pos - text_current_loc) * glyph_ratio;
|
||||
clip_box.size = clip_data.size * glyph_ratio;
|
||||
|
||||
if (flags & app::TEXT_FLAG_ALIGN_FLAG_RIGHT)
|
||||
clip_box.pos.x += glyph_size.x;
|
||||
else if (flags & app::TEXT_FLAG_ALIGN_FLAG_H_CENTER)
|
||||
clip_box.pos.x = (glyph_size.x - clip_data.size.x) * 0.5f * glyph_ratio.x;
|
||||
else if (flags & app::TEXT_FLAG_ALIGN_FLAG_LOCATE_H_CENTER)
|
||||
clip_box.pos.x += glyph_size.x * 0.5f;
|
||||
|
||||
if (flags & app::TEXT_FLAG_ALIGN_FLAG_V_CENTER)
|
||||
clip_box.pos.y = (glyph_size.y - clip_data.size.y) * 0.5f * glyph_ratio.y;
|
||||
else if (flags & app::TEXT_FLAG_ALIGN_FLAG_LOCATE_V_CENTER)
|
||||
clip_box.pos.y += glyph_size.y * 0.5f;
|
||||
return clip_box;
|
||||
}
|
||||
|
||||
std::vector<font_char> PrintWork::GetStringData(const wchar_t* str_begin, const wchar_t* str_end) {
|
||||
std::vector<font_char> vec(str_end - str_begin);
|
||||
font_char* fc = vec.data();
|
||||
for (const wchar_t* i = str_begin; i != str_end; i++)
|
||||
*fc++ = PrintWork::GetCharData(*i);
|
||||
return vec;
|
||||
}
|
||||
|
||||
vec2 PrintWork::GetStringSize(const wchar_t* str_begin, const wchar_t* str_end) {
|
||||
std::vector<font_char> vec = GetStringData(str_begin, str_end);
|
||||
float_t spacing = font->spacing.x / font->glyph_ratio.x;
|
||||
vec2 size;
|
||||
for (font_char& i : vec) {
|
||||
if (&i - vec.data())
|
||||
size.x += spacing;
|
||||
size.x += i.glyph_width;
|
||||
}
|
||||
|
||||
size.x *= font->glyph_ratio.x;
|
||||
size.y = font->glyph.y;
|
||||
return size;
|
||||
}
|
||||
|
||||
vec2 PrintWork::GetTextSize(const wchar_t* str, size_t length) {
|
||||
vec2* (FASTCALL * PrintWork__GetTextSize)(PrintWork * _this, vec2 * size, const prj::wstring_range& str)
|
||||
= (vec2 * (FASTCALL*)(PrintWork * _this, vec2 * size, const prj::wstring_range & str))0x000000014019A0A0;
|
||||
|
||||
vec2 size;
|
||||
return *PrintWork__GetTextSize(this, &size, prj::wstring_range(str, length));
|
||||
}
|
||||
|
||||
vec2 PrintWork::GetTextSize(const wchar_t* str_begin, const wchar_t* str_end) {
|
||||
return GetTextSize(str_begin, str_end - str_begin);
|
||||
}
|
||||
|
||||
vec2 PrintWork::GetTextSize(const char* str, size_t length) {
|
||||
return GetTextSize(str, str + length);
|
||||
}
|
||||
|
||||
vec2 PrintWork::GetTextSize(const char* str_begin, const char* str_end) {
|
||||
wchar_t* wstr = utf8_to_utf16(str_begin, str_end - str_begin);
|
||||
vec2 size = GetTextSize(wstr, wstr + utf16_length(wstr));
|
||||
free_def(wstr);
|
||||
return size;
|
||||
}
|
||||
|
||||
vec2 PrintWork::GetTextSize(const std::wstring& str) {
|
||||
return GetTextSize(str.c_str(), str.c_str() + str.size());
|
||||
}
|
||||
|
||||
void PrintWork::NewLine() {
|
||||
text_current_loc.x = line_origin_loc.x;
|
||||
float_t loc_y = text_current_loc.y + font->spacing.y + font->glyph.y;
|
||||
text_current_loc.y = loc_y;
|
||||
line_origin_loc.y = loc_y;
|
||||
}
|
||||
|
||||
void PrintWork::PrintText(app::text_flags flags, const char* str) {
|
||||
wchar_t* wstr = utf8_to_utf16(str);
|
||||
PrintText(flags, wstr, wstr + utf16_length(wstr));
|
||||
free_def(wstr);
|
||||
}
|
||||
|
||||
void PrintWork::PrintText(app::text_flags flags, const char* str, size_t length) {
|
||||
wchar_t* wstr = utf8_to_utf16(str, length);
|
||||
PrintText(flags, wstr, wstr + utf16_length(wstr));
|
||||
free_def(wstr);
|
||||
}
|
||||
|
||||
void PrintWork::PrintText(app::text_flags flags, const wchar_t* str_begin, const wchar_t* str_end) {
|
||||
void (FASTCALL * PrintWork__PrintText)(PrintWork * _this,
|
||||
app::text_flags flags, const prj::wstring_range& str)
|
||||
= (void (FASTCALL*)(PrintWork * _this,
|
||||
app::text_flags flags, const prj::wstring_range & str))0x0000000140198380;
|
||||
PrintWork__PrintText(this, flags, prj::wstring_range(str_begin, str_end));
|
||||
}
|
||||
|
||||
// It was intended to be DrawText but there's WinAPI macro for that
|
||||
void PrintWork::PutText(app::text_flags flags, const wchar_t* str_begin, const wchar_t* str_end) {
|
||||
if (str_begin == str_end)
|
||||
return;
|
||||
|
||||
app::text_flags v5 = (app::text_flags)(flags
|
||||
& (app::TEXT_FLAG_ALIGN_FLAG_LOCATE_V_CENTER | app::TEXT_FLAG_ALIGN_FLAG_V_CENTER
|
||||
| app::TEXT_FLAG_ALIGN_FLAG_LOCATE_H_CENTER | app::TEXT_FLAG_ALIGN_FLAG_H_CENTER
|
||||
| app::TEXT_FLAG_ALIGN_FLAG_RIGHT | app::TEXT_FLAG_ALIGN_FLAG_LEFT));
|
||||
app::text_flags v6 = (app::text_flags)(flags & (app::TEXT_FLAG_11 | app::TEXT_FLAG_CLIP));
|
||||
bool clip = !!(flags & app::TEXT_FLAG_CLIP);
|
||||
if (clip && font->glyph.y + text_current_loc.y <= clip_data.pos.y
|
||||
&& clip_data.pos.y + clip_data.size.y < text_current_loc.y)
|
||||
return;
|
||||
|
||||
std::vector<font_char> v43 = PrintWork::GetStringData(str_begin, str_end);
|
||||
float_t spacing = font->spacing.x / font->glyph_ratio.x;
|
||||
|
||||
vec2 glyph_ratio = font->glyph_ratio;
|
||||
rectangle clip_box;
|
||||
if (clip) {
|
||||
float_t glyph_size_x = 0.0f;
|
||||
for (font_char& i : v43)
|
||||
glyph_size_x += i.glyph_width + spacing;
|
||||
|
||||
vec2 glyph_size;
|
||||
glyph_size.x = glyph_size_x - spacing;
|
||||
glyph_size.y = font->glyph.y;
|
||||
clip_box = GetClipBox(v5, glyph_size, glyph_ratio);
|
||||
}
|
||||
else
|
||||
clip_box = {};
|
||||
|
||||
std::vector<sprite_text_mesh> v44;
|
||||
sprite_text_mesh v45;
|
||||
v45.sprite_id = font->font_ptr->sprite_id;
|
||||
v44.push_back(v45);
|
||||
v44.back().vertices.reserve(str_end - str_begin);
|
||||
|
||||
float_t glyph_x = 0.0f;
|
||||
if (str_end - str_begin) {
|
||||
for (size_t i = 0; i != str_end - str_begin; i++) {
|
||||
font_char* fc = &v43.data()[i];
|
||||
rectangle v37;
|
||||
v37.pos.x = glyph_x;
|
||||
v37.pos.y = 0.0f;
|
||||
v37.size.x = fc->glyph_width;
|
||||
v37.size.y = fc->tex.size.y;
|
||||
rectangle v42;
|
||||
v42.pos.x = fc->tex.pos.x + fc->glyph_offset;
|
||||
v42.pos.y = fc->tex.pos.y;
|
||||
v42.size.x = fc->glyph_width;
|
||||
v42.size.y = fc->tex.size.y;
|
||||
if (!clip || PrintWork::sub_140197D60(clip_box, v37, v42))
|
||||
v44.data()[fc->field_18].add_set_char(v6, v37, v42, color);
|
||||
glyph_x += fc->glyph_width + spacing;
|
||||
}
|
||||
}
|
||||
else
|
||||
glyph_x -= spacing;
|
||||
|
||||
vec2 v35;
|
||||
v35.x = glyph_x * glyph_ratio.x;
|
||||
v35.y = font->glyph.y;
|
||||
|
||||
vec2 v41 = PrintWork::sub_140197B80((app::text_flags)(v5 | v6), v35);
|
||||
if (v5 & app::TEXT_FLAG_ALIGN_FLAG_LEFT)
|
||||
text_current_loc.x += font->spacing.x + v35.x;
|
||||
|
||||
for (sprite_text_mesh& i : v44) {
|
||||
i.apply_scale_offset(glyph_ratio, v41);
|
||||
DrawTextMesh(flags, i);
|
||||
}
|
||||
}
|
||||
|
||||
void PrintWork::SetFont(const font_info* value) {
|
||||
font = value;
|
||||
}
|
||||
|
||||
void PrintWork::printf(app::text_flags flags, const char* fmt, ...) {
|
||||
void PrintWork::SetResolutionMode(::resolution_mode value) {
|
||||
resolution_mode = value;
|
||||
}
|
||||
|
||||
void PrintWork::set_text_position(float_t column, float_t line) {
|
||||
line_origin_loc.x = (font->spacing.x + font->glyph.x * font->font_ptr->column_scale) * column;
|
||||
line_origin_loc.y = (font->spacing.y + font->glyph.y) * line;
|
||||
text_current_loc = line_origin_loc;
|
||||
}
|
||||
|
||||
void PrintWork::printf(app::text_flags flags,
|
||||
_In_z_ _Printf_format_string_ const char* const fmt, ...) {
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
vprintf(flags, fmt, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
void PrintWork::printf_align_left(const char* fmt, ...) {
|
||||
void PrintWork::printf_align_left(_In_z_ _Printf_format_string_ const char* const fmt, ...) {
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
vprintf(app::TEXT_FLAG_ALIGN_FLAG_LEFT, fmt, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
void PrintWork::wprintf(app::text_flags flags, const wchar_t* fmt, ...) {
|
||||
void PrintWork::wprintf(app::text_flags flags,
|
||||
_In_z_ _Printf_format_string_ const wchar_t* const fmt, ...) {
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
vwprintf(flags, fmt, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
void PrintWork::wprintf_align_left(const wchar_t* fmt, ...) {
|
||||
void PrintWork::wprintf_align_left(_In_z_ _Printf_format_string_ const wchar_t* const fmt, ...) {
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
vwprintf(app::TEXT_FLAG_ALIGN_FLAG_LEFT, fmt, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
void PrintWork::vprintf(app::text_flags flags, const char* fmt, va_list args) {
|
||||
static void(FASTCALL * sub_1400CA8E0)(prj::string * buf, const char* fmt, va_list args)
|
||||
= (void (FASTCALL*)(prj::string * buf, const char* fmt, va_list args))0x00000001400CA8E0;
|
||||
static void(FASTCALL * PrintWork__PrintText)(PrintWork * _this, app::text_flags flags, const char* str, size_t length)
|
||||
= (void (FASTCALL*)(PrintWork * _this, app::text_flags flags, const char* str, size_t length))0x0000000140198500;
|
||||
|
||||
prj::string buf;
|
||||
sub_1400CA8E0(&buf, fmt, args);
|
||||
PrintWork__PrintText(this, flags, buf.c_str(), buf.size());
|
||||
void PrintWork::vprintf(app::text_flags flags,
|
||||
_In_z_ _Printf_format_string_ const char* const fmt, va_list args) {
|
||||
std::string buf = vsprintf_s_string(fmt, args);
|
||||
PrintText(flags, buf.data(), buf.size());
|
||||
}
|
||||
|
||||
void PrintWork::vwprintf(app::text_flags flags, const wchar_t* fmt, va_list args) {
|
||||
static void(FASTCALL * sub_1400DDC30)(prj::wstring * buf, const wchar_t* fmt, va_list args)
|
||||
= (void (FASTCALL*)(prj::wstring * buf, const wchar_t* fmt, va_list args))0x00000001400DDC30;
|
||||
static void(FASTCALL * PrintWork__PrintText)(PrintWork * _this, app::text_flags flags, const wchar_t* str, size_t length)
|
||||
= (void (FASTCALL*)(PrintWork * _this, app::text_flags flags, const wchar_t* str, size_t length))0x0000000140198380;
|
||||
|
||||
prj::wstring buf;
|
||||
sub_1400DDC30(&buf, fmt, args);
|
||||
PrintWork__PrintText(this, flags, buf.c_str(), buf.size());
|
||||
void PrintWork::vwprintf(app::text_flags flags,
|
||||
_In_z_ _Printf_format_string_ const wchar_t* const fmt, va_list args) {
|
||||
std::wstring buf = vswprintf_s_string(fmt, args);
|
||||
PrintText(flags, buf.data(), buf.data() + buf.size());
|
||||
}
|
||||
|
||||
void PrintWork::ClampPosToClipBox(float_t pos_min, float_t pos_max,
|
||||
float_t clip_box_min, float_t clip_box_max, float_t& clip_pos_min, float_t& clip_pos_max) {
|
||||
float_t v8 = max_def(pos_min, clip_box_min);
|
||||
float_t v10 = min_def(pos_max, clip_box_max);
|
||||
|
||||
if (v8 < v10) {
|
||||
clip_pos_min = v8;
|
||||
clip_pos_max = v10;
|
||||
}
|
||||
else {
|
||||
clip_pos_min = pos_min;
|
||||
clip_pos_max = pos_min;
|
||||
}
|
||||
}
|
||||
|
||||
vec2 PrintWork::sub_140197B80(app::text_flags flags, vec2 size) {
|
||||
vec2 pos = text_current_loc;
|
||||
if (flags & app::TEXT_FLAG_ALIGN_FLAG_RIGHT)
|
||||
pos.x -= size.x;
|
||||
else if (flags & app::TEXT_FLAG_ALIGN_FLAG_H_CENTER) {
|
||||
if (flags & app::TEXT_FLAG_CLIP)
|
||||
pos.x = clip_data.pos.x + clip_data.size.x * 0.5f;
|
||||
else {
|
||||
resolution_struct v10(resolution_mode);
|
||||
pos.x = (float_t)v10.width * 0.5f;
|
||||
}
|
||||
pos.x -= size.x * 0.5f;
|
||||
}
|
||||
else if (flags & app::TEXT_FLAG_ALIGN_FLAG_LOCATE_H_CENTER)
|
||||
pos.x -= size.x * 0.5f;
|
||||
|
||||
if (flags & app::TEXT_FLAG_ALIGN_FLAG_V_CENTER) {
|
||||
if (flags & app::TEXT_FLAG_CLIP)
|
||||
pos.y = clip_data.pos.y + clip_data.size.y * 0.5f;
|
||||
else {
|
||||
resolution_struct v10(resolution_mode);
|
||||
pos.y = (float_t)v10.height * 0.5f;
|
||||
}
|
||||
pos.y -= size.y * 0.5f;
|
||||
}
|
||||
else if (flags & app::TEXT_FLAG_ALIGN_FLAG_LOCATE_V_CENTER)
|
||||
pos.y -= size.y * 0.5f;
|
||||
return pos;
|
||||
}
|
||||
|
||||
int32_t PrintWork::sub_140197D60(rectangle clip_box, rectangle& pos, rectangle& uv) {
|
||||
vec2 pos_pos = pos.pos;
|
||||
vec2 pos_size = pos.size;
|
||||
vec2 uv_pos = uv.pos;
|
||||
vec2 uv_size = uv.size;
|
||||
|
||||
vec2 clip_max_pos;
|
||||
vec2 clip_min_pos;
|
||||
PrintWork::ClampPosToClipBox(pos_pos.x, pos_pos.x + pos_size.x,
|
||||
clip_box.pos.x, clip_box.pos.x + clip_box.size.x, clip_min_pos.x, clip_max_pos.x);
|
||||
PrintWork::ClampPosToClipBox(pos_pos.y, pos_pos.y + pos_size.y,
|
||||
clip_box.pos.y, clip_box.pos.y + clip_box.size.y, clip_min_pos.y, clip_max_pos.y);
|
||||
|
||||
vec2 clip_size = clip_max_pos - clip_min_pos;
|
||||
|
||||
if (clip_size.x == pos_size.x && clip_size.y == pos_size.y)
|
||||
return 2;
|
||||
else if (clip_size.x <= 0.0f || clip_size.y <= 0.0f)
|
||||
return 0;
|
||||
|
||||
vec2 uv_scale = uv_size / pos_size;
|
||||
pos.pos = clip_min_pos;
|
||||
pos.size = clip_size;
|
||||
uv.pos = (clip_min_pos - pos_pos) * uv_scale + uv_pos;
|
||||
uv.size = clip_size * uv_scale;
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -31,6 +31,41 @@ namespace app {
|
||||
};
|
||||
}
|
||||
|
||||
struct font_char {
|
||||
rectangle tex;
|
||||
float_t glyph_offset;
|
||||
float_t glyph_width;
|
||||
uint8_t field_18;
|
||||
|
||||
font_char();
|
||||
};
|
||||
|
||||
struct font_character {
|
||||
bool init;
|
||||
bool halfwidth;
|
||||
uint8_t tex_column;
|
||||
uint8_t tex_row;
|
||||
uint8_t glyph_offset;
|
||||
uint8_t glyph_width;
|
||||
};
|
||||
|
||||
struct font {
|
||||
int32_t sprite_id;
|
||||
uint8_t glyph_width;
|
||||
uint8_t glyph_height;
|
||||
uint8_t glyph_box_width;
|
||||
uint8_t glyph_box_height;
|
||||
uint8_t column_scale_num;
|
||||
uint8_t column_scale_denom;
|
||||
int32_t map_id;
|
||||
float_t column_scale;
|
||||
size_t characters_count_per_row;
|
||||
prj::vector<font_character> characters;
|
||||
bool disable_glyph_spacing;
|
||||
|
||||
const font_character* get_character(wchar_t c) const;
|
||||
};
|
||||
|
||||
struct font_info {
|
||||
int32_t font_handler_index;
|
||||
const struct font* font_ptr;
|
||||
@@ -44,11 +79,30 @@ struct font_info {
|
||||
font_info();
|
||||
font_info(int32_t font_handler_index);
|
||||
|
||||
font_char* get_char_data(wchar_t c, font_char* font_c) const;
|
||||
void set_glyph_size(float_t glyph_width, float_t glyph_height);
|
||||
|
||||
bool sub_140199170() const;
|
||||
};
|
||||
|
||||
static_assert(sizeof(font_info) == 0x40, "\"font_info\" struct should have a size of 0x40");
|
||||
|
||||
struct sprite_text_mesh {
|
||||
int32_t sprite_id;
|
||||
std::vector<spr::SpriteVertex> vertices;
|
||||
|
||||
sprite_text_mesh();
|
||||
~sprite_text_mesh();
|
||||
|
||||
spr::SpriteVertex* add_char();
|
||||
void add_set_char(app::text_flags flags,
|
||||
rectangle pos, rectangle uv, color4u8 color);
|
||||
void apply_scale_offset(vec2 scale, vec2 offset);
|
||||
|
||||
static void set_char(spr::SpriteVertex* vtx, app::text_flags flags,
|
||||
rectangle pos, rectangle uv, color4u8 color);
|
||||
};
|
||||
|
||||
struct PrintWork {
|
||||
color4u8 color;
|
||||
color4u8 fill_color;
|
||||
@@ -66,14 +120,46 @@ struct PrintWork {
|
||||
|
||||
PrintWork();
|
||||
|
||||
void DrawLine(vec2 pos[2]);
|
||||
void DrawPolyLine(vec2* points, size_t count);
|
||||
void DrawRectangle(rectangle rect);
|
||||
void DrawTextMesh(app::text_flags flags, sprite_text_mesh& mesh);
|
||||
void FillRectangle(rectangle rect);
|
||||
font_char GetCharData(wchar_t c);
|
||||
rectangle GetClipBox(app::text_flags flags, vec2 glyph_size, vec2 glyph_ratio);
|
||||
std::vector<font_char> GetStringData(const wchar_t* str_begin, const wchar_t* str_end);
|
||||
vec2 GetStringSize(const wchar_t* str_begin, const wchar_t* str_end);
|
||||
vec2 GetTextSize(const wchar_t* str, size_t length);
|
||||
vec2 GetTextSize(const wchar_t* str_begin, const wchar_t* str_end);
|
||||
vec2 GetTextSize(const char* str, size_t length);
|
||||
vec2 GetTextSize(const char* str_begin, const char* str_end);
|
||||
vec2 GetTextSize(const std::wstring& str);
|
||||
void NewLine();
|
||||
void PrintText(app::text_flags flags, const char* str);
|
||||
void PrintText(app::text_flags flags, const char* str, size_t length);
|
||||
void PrintText(app::text_flags flags, const wchar_t* str_begin, const wchar_t* str_end);
|
||||
void PutText(app::text_flags flags, const wchar_t* str_begin, const wchar_t* str_end);
|
||||
void SetFont(const font_info* value);
|
||||
void SetResolutionMode(::resolution_mode value);
|
||||
void set_text_position(float_t column, float_t line);
|
||||
|
||||
void printf(app::text_flags flags, const char* fmt, ...);
|
||||
void printf_align_left(const char* fmt, ...);
|
||||
void wprintf(app::text_flags flags, const wchar_t* fmt, ...);
|
||||
void wprintf_align_left(const wchar_t* fmt, ...);
|
||||
void vprintf(app::text_flags flags, const char* fmt, va_list args);
|
||||
void vwprintf(app::text_flags flags, const wchar_t* fmt, va_list args);
|
||||
void printf(app::text_flags flags,
|
||||
_In_z_ _Printf_format_string_ const char* const fmt, ...);
|
||||
void printf_align_left(_In_z_ _Printf_format_string_ const char* const fmt, ...);
|
||||
void wprintf(app::text_flags flags,
|
||||
_In_z_ _Printf_format_string_ const wchar_t* const fmt, ...);
|
||||
void wprintf_align_left(_In_z_ _Printf_format_string_ const wchar_t* const fmt, ...);
|
||||
void vprintf(app::text_flags flags,
|
||||
_In_z_ _Printf_format_string_ const char* const fmt, va_list args);
|
||||
void vwprintf(app::text_flags flags,
|
||||
_In_z_ _Printf_format_string_ const wchar_t* const fmt, va_list args);
|
||||
|
||||
static void ClampPosToClipBox(float_t pos_min, float_t pos_max,
|
||||
float_t clip_box_min, float_t clip_box_max, float_t& clip_pos_min, float_t& clip_pos_max);
|
||||
|
||||
vec2 sub_140197B80(app::text_flags flags, vec2 size);
|
||||
|
||||
static int32_t sub_140197D60(rectangle clip_box, rectangle& pos, rectangle& uv);
|
||||
};
|
||||
|
||||
static_assert(sizeof(PrintWork) == 0x58, "\"PrintWork\" struct should have a size of 0x58");
|
||||
|
||||
+229
-1
@@ -120,6 +120,17 @@ bool (FASTCALL* sprite_manager_load_file)(int32_t set_id)
|
||||
|
||||
spr::SpriteManager* sprite_manager = (spr::SpriteManager*)0x000000014CC611C0;
|
||||
|
||||
#if BREAK_SPRITE_VERTEX_LIMIT
|
||||
size_t sprite_vertex_array_max_count = 0x2000;
|
||||
|
||||
spr::SpriteVertex* sprite_vertex_array;
|
||||
#else
|
||||
const size_t sprite_vertex_array_max_count = 0x2000;
|
||||
|
||||
spr::SpriteVertex* sprite_vertex_array = (spr::SpriteVertex*)0x000000014CC62480;
|
||||
#endif
|
||||
size_t& sprite_vertex_array_count = *(size_t*)0x000000014CC611B0;
|
||||
|
||||
static mat4 view_projection_aet;
|
||||
|
||||
static spr::SpriteManager::RenderData* sprite_manager_render_data;
|
||||
@@ -134,10 +145,220 @@ static const GLenum spr_blend_param[6][4] = {
|
||||
};
|
||||
|
||||
namespace spr {
|
||||
void(FASTCALL* put_rgb_cross)(mat4* mat) = (void(FASTCALL*)(mat4 * mat))0x00000001404BC8F0;
|
||||
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();
|
||||
}
|
||||
|
||||
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_FT_FFP;
|
||||
#if BREAK_SPRITE_VERTEX_LIMIT
|
||||
vertex_array = -1;
|
||||
#else
|
||||
vertex_array = 0;
|
||||
#endif
|
||||
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) {
|
||||
#if BREAK_SPRITE_VERTEX_LIMIT
|
||||
if (sprite_vertex_array_count + num_vertex >= sprite_vertex_array_max_count) {
|
||||
while (sprite_vertex_array_count + num_vertex >= sprite_vertex_array_max_count)
|
||||
sprite_vertex_array_max_count *= 2;
|
||||
|
||||
spr::SpriteVertex* _sprite_vertex_array = new spr::SpriteVertex[sprite_vertex_array_max_count * 2];
|
||||
memmove(_sprite_vertex_array, sprite_vertex_array, sizeof(SpriteVertex) * sprite_vertex_array_count);
|
||||
delete[] sprite_vertex_array;
|
||||
sprite_vertex_array = _sprite_vertex_array;
|
||||
}
|
||||
#else
|
||||
if (sprite_vertex_array_count + num_vertex >= sprite_vertex_array_max_count)
|
||||
return;
|
||||
#endif
|
||||
|
||||
this->num_vertex = num_vertex;
|
||||
#if BREAK_SPRITE_VERTEX_LIMIT
|
||||
this->vertex_array = sprite_vertex_array_count;
|
||||
memmove(sprite_vertex_array + this->vertex_array, vertex_array, sizeof(SpriteVertex) * num_vertex);
|
||||
#else
|
||||
this->vertex_array = &sprite_vertex_array[sprite_vertex_array_count];
|
||||
memmove(this->vertex_array, vertex_array, sizeof(SpriteVertex) * num_vertex);
|
||||
#endif
|
||||
sprite_vertex_array_count += num_vertex;
|
||||
}
|
||||
|
||||
void SprArgs::SetNext(SprArgs* args, SprArgs* next) {
|
||||
while (args->next)
|
||||
args = args->next;
|
||||
args->next = next;
|
||||
next->kind = SPR_KIND_LINE;
|
||||
}
|
||||
|
||||
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_LINES;
|
||||
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_line_list(vec2* points, size_t count, resolution_mode mode,
|
||||
spr::SprPrio prio, color4u8 color, int32_t layer) {
|
||||
spr::SprArgs args;
|
||||
args.kind = SPR_KIND_ARROW_AB;
|
||||
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_multi(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_MULTI;
|
||||
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(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;
|
||||
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_triangles(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_TRIANGLE;
|
||||
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);
|
||||
}
|
||||
|
||||
SpriteManager::RenderData::RenderData() {
|
||||
glGenVertexArrays(1, &vao);
|
||||
gl_state_bind_vertex_array(vao, true);
|
||||
@@ -1195,6 +1416,13 @@ namespace spr {
|
||||
}
|
||||
}
|
||||
|
||||
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(0x000000014CC62290, 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)
|
||||
|
||||
+78
-1
@@ -7,6 +7,7 @@
|
||||
|
||||
#include "../KKdLib/default.hpp"
|
||||
#include "../KKdLib/mat.hpp"
|
||||
#include "../KKdLib/rectangle.hpp"
|
||||
#include "../KKdLib/vec.hpp"
|
||||
#include "gl_state.hpp"
|
||||
#include "render_context.hpp"
|
||||
@@ -14,10 +15,59 @@
|
||||
#include "texture.hpp"
|
||||
#include "types.hpp"
|
||||
|
||||
#define BREAK_SPRITE_VERTEX_LIMIT (0)
|
||||
|
||||
struct spr_info {
|
||||
uint16_t index;
|
||||
uint16_t set_index;
|
||||
|
||||
inline spr_info() {
|
||||
this->index = (uint16_t)-1;
|
||||
this->set_index = (uint16_t)-1;
|
||||
}
|
||||
|
||||
inline spr_info(uint16_t index, uint16_t set_index) {
|
||||
this->index = index;
|
||||
this->set_index = set_index;
|
||||
}
|
||||
|
||||
inline bool is_null() const {
|
||||
return index == (uint16_t)-1 && set_index == (uint16_t)-1;
|
||||
}
|
||||
|
||||
inline bool not_null() const {
|
||||
return index != (uint16_t)-1 || set_index != (uint16_t)-1;
|
||||
}
|
||||
};
|
||||
|
||||
constexpr bool operator==(const spr_info& left, const spr_info& right) {
|
||||
return *(uint32_t*)&left == *(uint32_t*)&right;
|
||||
}
|
||||
|
||||
constexpr bool operator!=(const spr_info& left, const spr_info& right) {
|
||||
return !(left == right);
|
||||
}
|
||||
|
||||
constexpr bool operator<(const spr_info& left, const spr_info& right) {
|
||||
return *(uint32_t*)&left < *(uint32_t*)&right;
|
||||
}
|
||||
|
||||
constexpr bool operator>(const spr_info& left, const spr_info& right) {
|
||||
return right < left;
|
||||
}
|
||||
|
||||
constexpr bool operator<=(const spr_info& left, const spr_info& right) {
|
||||
return !(right < left);
|
||||
}
|
||||
|
||||
constexpr bool operator>=(const spr_info& left, const spr_info& right) {
|
||||
return !(left < right);
|
||||
}
|
||||
|
||||
struct spr_db_spr {
|
||||
uint32_t id;
|
||||
prj::string name;
|
||||
spr_info info;
|
||||
};
|
||||
|
||||
struct SpriteHeaderFile {
|
||||
@@ -191,7 +241,11 @@ namespace spr {
|
||||
mat4 mat;
|
||||
texture* texture;
|
||||
int32_t shader;
|
||||
#if BREAK_SPRITE_VERTEX_LIMIT
|
||||
size_t vertex_array;
|
||||
#else
|
||||
SpriteVertex* vertex_array;
|
||||
#endif
|
||||
size_t num_vertex;
|
||||
Flags flags;
|
||||
vec2 sprite_size;
|
||||
@@ -199,11 +253,33 @@ namespace spr {
|
||||
vec2 texture_pos;
|
||||
vec2 texture_size;
|
||||
spr::SprArgs* next;
|
||||
|
||||
SprArgs();
|
||||
|
||||
void Reset();
|
||||
void SetSpriteSize(vec2 size);
|
||||
void SetTexturePosSize(float_t x, float_t y, float_t width, float_t height);
|
||||
void SetVertexArray(SpriteVertex* vertex_array, size_t num_vertex);
|
||||
|
||||
static void SetNext(SprArgs* args, SprArgs* next);
|
||||
};
|
||||
|
||||
static_assert(sizeof(spr::SprArgs) == 0xE8, "\"spr::SprArgs\" struct should have a size of 0xE8");
|
||||
|
||||
extern void(FASTCALL* put_rgb_cross)(mat4* mat);
|
||||
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);
|
||||
|
||||
void put_sprite_3d_line(vec3 p1, vec3 p2, color4u8 color);
|
||||
void put_sprite_line(vec2 p1, vec2 p2, resolution_mode mode, spr::SprPrio prio, color4u8 color, int32_t layer);
|
||||
void put_sprite_line_list(vec2* points, size_t count, resolution_mode mode,
|
||||
spr::SprPrio prio, color4u8 color, int32_t layer);
|
||||
void put_sprite_multi(rectangle rect, resolution_mode mode, spr::SprPrio prio, color4u8 color, int32_t layer);
|
||||
void put_sprite_rect(rectangle rect, resolution_mode mode, spr::SprPrio prio, color4u8 color, int32_t layer);
|
||||
void put_sprite_triangles(SpriteVertex* vert, size_t num, resolution_mode mode,
|
||||
SprPrio prio, int32_t spr_id, int32_t layer);
|
||||
}
|
||||
|
||||
extern vec4& spr_color;
|
||||
@@ -213,6 +289,7 @@ extern size_t(FASTCALL* sprite_manager_get_reqlist_count)(int32_t index);
|
||||
extern void (FASTCALL* sprite_manager_read_file)(int32_t set_id, const prj::string mdata_dir);
|
||||
extern bool (FASTCALL* sprite_manager_load_file)(int32_t set_id);
|
||||
|
||||
extern const spr_db_spr* sprite_database_get_spr_by_id(int32_t id);
|
||||
extern int32_t sprite_database_get_spr_set_id_by_name(const prj::string& name);
|
||||
|
||||
extern void sprite_manager_init();
|
||||
|
||||
Reference in New Issue
Block a user