Added more funcs to PrintWork

This commit is contained in:
korenkonder
2024-06-02 16:05:38 +03:00
parent b4fb7c1bf6
commit a2b94b680c
6 changed files with 895 additions and 32 deletions
+16
View File
@@ -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
View File
@@ -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
View File
@@ -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;
}
+92 -6
View File
@@ -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
View File
@@ -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
View File
@@ -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();