diff --git a/src/CRE/auth_2d.cpp b/src/CRE/auth_2d.cpp index a89554f1..a9d35c36 100644 --- a/src/CRE/auth_2d.cpp +++ b/src/CRE/auth_2d.cpp @@ -1223,7 +1223,7 @@ void AetLyo::DispLayer(const mat4& mat, const aet_layer* layer, data.height = (float_t)video->height; data.color.r = video->color[0]; data.color.g = video->color[1]; - data.color.b = video->color[2];; + data.color.b = video->color[2]; data.opacity = opacity; data.mode = dst_mode; comp->Add(layer->name, data); diff --git a/src/CRE/rob/rob.cpp b/src/CRE/rob/rob.cpp index 7154df63..e852d9c6 100644 --- a/src/CRE/rob/rob.cpp +++ b/src/CRE/rob/rob.cpp @@ -11523,7 +11523,7 @@ bool pv_osage_manager_array_get_disp(int32_t chara_id) { void pv_osage_manager_array_set_motion_ids( int32_t chara_id, const std::vector& motion_ids) { - std::vector set_motion; + std::vector set_motion; for (const uint32_t& i : motion_ids) set_motion.push_back({ i }); pv_osage_manager_array_get(chara_id)->SetPvSetMotion(set_motion); @@ -19557,15 +19557,15 @@ bool TaskRobManager::GetWait(rob_chara* rob_chr) { for (auto& i : init_chara) if (i->chara_id == chara_id) return true; - + for (auto& i : load_chara) if (i->chara_id == chara_id) return true; - + for (auto& i : loaded_chara) if (i->chara_id == chara_id) return true; - + for (auto& i : free_chara) if (i->chara_id == chara_id) return true; diff --git a/src/CRE/rob/rob.hpp b/src/CRE/rob/rob.hpp index 1475b85e..7fbb9a20 100644 --- a/src/CRE/rob/rob.hpp +++ b/src/CRE/rob/rob.hpp @@ -3537,7 +3537,7 @@ extern float_t chara_size_table_get_value(uint32_t index); extern bool check_module_index_is_501(int32_t module_index); -extern const uint32_t* get_opd_motion_set_ids();; +extern const uint32_t* get_opd_motion_set_ids(); extern const float_t get_osage_gravity_const(); diff --git a/src/CRE/sprite.cpp b/src/CRE/sprite.cpp index 192ac1f7..e16227f1 100644 --- a/src/CRE/sprite.cpp +++ b/src/CRE/sprite.cpp @@ -340,6 +340,29 @@ namespace spr { sprite_manager->PutSprite(args, 0); } + 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 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()); + sprite_manager->PutSprite(args, 0); + } + 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; diff --git a/src/CRE/sprite.hpp b/src/CRE/sprite.hpp index f387bb54..1ab91179 100644 --- a/src/CRE/sprite.hpp +++ b/src/CRE/sprite.hpp @@ -210,6 +210,8 @@ namespace spr { spr::SprArgs* put_sprite(const spr::SprArgs& args, const sprite_database* spr_db); 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, diff --git a/src/KKdLib/database/object.cpp b/src/KKdLib/database/object.cpp index a599bfbd..2d2597fb 100644 --- a/src/KKdLib/database/object.cpp +++ b/src/KKdLib/database/object.cpp @@ -241,7 +241,7 @@ void object_database::add(object_database_file* obj_db_file) { if (!obj_db_file || !obj_db_file->ready) return; - object_set.reserve(obj_db_file->object_set.size());; + object_set.reserve(obj_db_file->object_set.size()); for (object_set_info_file& i : obj_db_file->object_set) { uint32_t name_hash = hash_string_murmurhash(i.name); diff --git a/src/KKdLib/msgpack.cpp b/src/KKdLib/msgpack.cpp index dfafcf1a..2ccc21f2 100644 --- a/src/KKdLib/msgpack.cpp +++ b/src/KKdLib/msgpack.cpp @@ -367,7 +367,7 @@ float_t msgpack::read_float_t(const char* name) { case MSGPACK_FLOAT32: return m->data.f32; case MSGPACK_FLOAT64: - return (float_t)m->data.f64;; + return (float_t)m->data.f64; } return 0; } @@ -400,7 +400,7 @@ double_t msgpack::read_double_t(const char* name) { case MSGPACK_FLOAT32: return m->data.f32; case MSGPACK_FLOAT64: - return m->data.f64;; + return m->data.f64; } return 0; } diff --git a/src/KKdLib/prj/vector_pair_combine.hpp b/src/KKdLib/prj/vector_pair_combine.hpp index 7919c4b9..cbdcb2a2 100644 --- a/src/KKdLib/prj/vector_pair_combine.hpp +++ b/src/KKdLib/prj/vector_pair_combine.hpp @@ -184,11 +184,11 @@ namespace prj { inline void push_back(const T& first, U&& second) { new_data.push_back({ first, second }); } - + inline void push_back(T&& first, const U& second) { new_data.push_back({ first, second }); } - + inline void push_back(T&& first, U&& second) { new_data.push_back({ first, second }); } diff --git a/src/ReDIVA/data_test/motion_test.cpp b/src/ReDIVA/data_test/motion_test.cpp index 60eb21de..a2c9970d 100644 --- a/src/ReDIVA/data_test/motion_test.cpp +++ b/src/ReDIVA/data_test/motion_test.cpp @@ -516,7 +516,7 @@ void DataTestMotA3d::Reset() { i.unload(rctx_ptr); auth_3d_ids.clear(); - + for (uint32_t& i : obj_sets) object_storage_unload_set(i); @@ -1378,7 +1378,7 @@ DataTestFaceMotDw::Data DataTestFaceMotDw::GetData() { if (elem_eyelid != motion_id_mottbl_map.end()) data.eyelid.mottbl_index = elem_eyelid->second; data.eyelid.frame = face_cl_frame->scroll_bar->value; - + auto elem_eyes = motion_id_mottbl_map.find(aft_mot_db->get_motion_id(eyes->GetSelectedItem().c_str())); if (elem_eyes != motion_id_mottbl_map.end()) data.eyes.mottbl_index = elem_eyes->second; diff --git a/src/ReDIVA/data_test/motion_test.hpp b/src/ReDIVA/data_test/motion_test.hpp index be841810..eb59a45d 100644 --- a/src/ReDIVA/data_test/motion_test.hpp +++ b/src/ReDIVA/data_test/motion_test.hpp @@ -85,7 +85,7 @@ public: std::vector auth_3d_ids; std::vector obj_sets; bool camera; - + DataTestMotA3d(); virtual ~DataTestMotA3d() override; @@ -441,7 +441,7 @@ public: virtual void Callback(dw::Widget* data) override; }; - + class A3dListBoxProc : public dw::SelectionAdapter { public: A3dListBoxProc(); diff --git a/src/ReDIVA/dw.cpp b/src/ReDIVA/dw.cpp index 217b06c5..3d3fd930 100644 --- a/src/ReDIVA/dw.cpp +++ b/src/ReDIVA/dw.cpp @@ -1195,7 +1195,7 @@ namespace dw { Scrollable::SetSize(size); SetScrollBarParams(); } - + vec2 List::GetSize() { //print->SetFont(); @@ -1285,7 +1285,7 @@ namespace dw { size_t List::sub_1402EF620() { if (!v_bar) - return items.size(); + return items.size(); /*else if (field_140 >= this->items.size()) return items.size(); return field_140;*/ diff --git a/src/ReDIVA/dw.hpp b/src/ReDIVA/dw.hpp index c627a9ea..72ea9632 100644 --- a/src/ReDIVA/dw.hpp +++ b/src/ReDIVA/dw.hpp @@ -111,7 +111,7 @@ namespace dw { virtual void Callback(Widget* data) override; }; - + class ScrollBarTestSelectionListener : public SelectionAdapter { public: ScrollBarTestSelectionListener(); @@ -424,7 +424,7 @@ namespace dw { inline std::string GetHoveredItem() { return GetItem(hovered_item); } - + inline std::string GetSelectedItem() { return GetItem(selected_item); } diff --git a/src/ReDIVA/font_info.cpp b/src/ReDIVA/font_info.cpp index d43dc2ff..33527326 100644 --- a/src/ReDIVA/font_info.cpp +++ b/src/ReDIVA/font_info.cpp @@ -7,6 +7,10 @@ font_info* font_info_default; +font_char::font_char() : glyph_offset(), glyph_width(), field_18() { + +} + font_info::font_info() : font_ptr(), type() { font_handler_index = -1; init_font_data(0); @@ -60,7 +64,7 @@ font_char* font_info::get_char_data(wchar_t c, font_char* font_c) const { font_c->tex.size = glyph_size; font_c->glyph_offset = glyph_offset; font_c->glyph_width = glyph_width; - font_c->field_18 = false; + font_c->field_18 = 0; return font_c; } diff --git a/src/ReDIVA/font_info.hpp b/src/ReDIVA/font_info.hpp index 2489809b..e9e39924 100644 --- a/src/ReDIVA/font_info.hpp +++ b/src/ReDIVA/font_info.hpp @@ -14,7 +14,9 @@ struct font_char { rectangle tex; float_t glyph_offset; float_t glyph_width; - bool field_18; + uint8_t field_18; + + font_char(); }; struct font_info { diff --git a/src/ReDIVA/print_work.cpp b/src/ReDIVA/print_work.cpp index 599f7a33..e58b2019 100644 --- a/src/ReDIVA/print_work.cpp +++ b/src/ReDIVA/print_work.cpp @@ -5,6 +5,148 @@ #include "print_work.hpp" #include "../KKdLib/str_utils.hpp" +#include "../CRE/shader_ft.hpp" + +namespace app { + namespace sap { + class ContentHandler { + public: + ContentHandler(); + virtual ~ContentHandler(); + + virtual void Print(const wchar_t* str_begin, const wchar_t* str_end) = 0; + virtual void Field_10() = 0; + virtual void NewLine() = 0; + }; + + class DefaultContentHandler : public ContentHandler { + public: + DefaultContentHandler(); + virtual ~DefaultContentHandler() override; + + virtual void Print(const wchar_t* str_begin, const wchar_t* str_end) override; + virtual void Field_10() override; + virtual void NewLine() override; + }; + + class SimpleContentHandler : public DefaultContentHandler { + public: + PrintWork* print_work; + app::text_flags flags; + + SimpleContentHandler(PrintWork* print_work, app::text_flags flags); + virtual ~SimpleContentHandler() override; + + virtual void Print(const wchar_t* str_begin, const wchar_t* str_end) override; + virtual void NewLine() override; + }; + + class SimpleExtentContentHandler : public DefaultContentHandler { + public: + PrintWork* print_work; + vec2 space_size; + vec2 size; + bool new_line; + + SimpleExtentContentHandler(PrintWork* print_work); + virtual ~SimpleExtentContentHandler() override; + + virtual void Print(const wchar_t* str_begin, const wchar_t* str_end) override; + virtual void NewLine() override; + }; + + class Reader { + public: + Reader(); + virtual ~Reader(); + + virtual void Print(const wchar_t* str_begin, const wchar_t* str_end) = 0; + virtual void SetContentHandler(ContentHandler* content_handler) = 0; + virtual ContentHandler* GetContentHandler() = 0; + }; + + class SimpleReader : public Reader { + public: + PrintWork* print_work; + ContentHandler* content_handler; + + SimpleReader(PrintWork* print_work, ContentHandler* content_handler); + virtual ~SimpleReader() override; + + virtual void Print(const wchar_t* str_begin, const wchar_t* str_end) override; + virtual void SetContentHandler(ContentHandler* content_handler) override; + virtual ContentHandler* GetContentHandler() override; + }; + + class SimpleAutoLineFeedReader : public SimpleReader { + public: + SimpleAutoLineFeedReader(PrintWork* print_work, ContentHandler* content_handler); + virtual ~SimpleAutoLineFeedReader() override; + + virtual void Print(const wchar_t* str_begin, const wchar_t* str_end) override; + }; + } +} + +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; @@ -19,6 +161,72 @@ 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; + + data_struct* aft_data = &data_list[DATA_AFT]; + sprite_database* aft_spr_db = &aft_data->data_ft.spr_db; + + 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, aft_spr_db); + + 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, aft_spr_db); +} + +void PrintWork::FillRectangle(rectangle rect) { + if (clip) { + float_t v8a; + PrintWork::sub_140196110(rect.pos.x, rect.pos.x + rect.size.y, + clip_data.pos.x, clip_data.pos.x + clip_data.size.x, rect.pos.x, v8a); + rect.size.x = v8a - rect.pos.x; + + float_t v8b; + PrintWork::sub_140196110(rect.pos.y, rect.pos.y + rect.size.y, + clip_data.pos.y, clip_data.pos.y + clip_data.size.y, rect.pos.y, v8b); + rect.size.y = v8b - 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)) @@ -26,21 +234,61 @@ font_char PrintWork::GetCharData(wchar_t 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 PrintWork::GetStringData(const wchar_t* str_begin, const wchar_t* str_end) { + std::vector 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 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) { return GetTextSize(str, str + length); } vec2 PrintWork::GetTextSize(const wchar_t* str_begin, const wchar_t* str_end) { - /*app::sap::SimpleExtentContentHandler v10; - v10.print_work = this; - - app::sap::SimpleAutoLineFeedReader v8; - v8.print_work = this; - v8.SimpleAutoLineFeedReader::Print(str_begin, str_end);*/ + app::sap::SimpleExtentContentHandler content_handler(this); + app::sap::SimpleAutoLineFeedReader reader(this, &content_handler); + reader.Print(str_begin, str_end); vec2 size; - /*size.x = max_def(v10.size.x, v10.space_size.x); - size.y = v10.space_size.y + v10.size.y;*/ + size.x = max_def(content_handler.size.x, content_handler.space_size.x); + size.y = content_handler.space_size.y + content_handler.size.y; return size; } @@ -59,6 +307,13 @@ 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)); @@ -78,14 +333,84 @@ void PrintWork::PrintText(app::text_flags flags, const wchar_t* str_begin, const if (font->sub_140199170()) enum_or(flags, app::TEXT_FLAG_11); - /*app::sap::SimpleContentHandler v8; - v8.data = this; - v8.flags = flags; + app::sap::SimpleContentHandler content_handler(this, flags); + app::sap::SimpleAutoLineFeedReader reader(this, &content_handler); + reader.Print(str_begin, str_end); +} - app::sap::SimpleAutoLineFeedReader v6; - v6.print_work = this; - v6.content_handler = &v8; - v6.Print(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 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 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) { @@ -133,3 +458,325 @@ void PrintWork::vwprintf(app::text_flags flags, const wchar_t* fmt, va_list args wchar_t buf[0x100]; PrintText(flags, buf, buf + vswprintf_s(buf, sizeof(buf) / sizeof(wchar_t), fmt, args)); } + +void PrintWork::sub_140196110(float_t a1, float_t a2, float_t a3, float_t a4, float_t& a5, float_t& a6) { + float_t v8 = max_def(a1, a3); + float_t v10 = max_def(a2, a4); + + if (v8 >= v10) { + a5 = a1; + a6 = a1; + } + else { + a5 = v8; + a6 = v10; + } +} + +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 v29; + vec2 v25; + PrintWork::sub_140196110(pos_pos.x, pos_pos.x + pos_size.x, + clip_box.pos.x, clip_box.pos.x + clip_box.size.x, v25.x, v29.x); + PrintWork::sub_140196110(pos_pos.y, pos_pos.y + pos_size.y, + clip_box.pos.y, clip_box.pos.y + clip_box.size.y, v25.y, v29.y); + + vec2 v27 = v29 - v25; + + if (v27.x == pos_size.x && v27.y == pos_size.y) + return 2; + else if (v27.x <= 0.0f || v27.y <= 0.0f) + return 0; + + vec2 uv_scale = uv_size / pos_size; + pos.pos = v25; + pos.size = v27; + uv.pos = (v25 - pos_pos) * uv_scale + uv_pos; + uv.size = v27 * uv_scale; + return 1; +} + +namespace app { + namespace sap { + ContentHandler::ContentHandler() { + + } + + ContentHandler:: ~ContentHandler() { + + } + + DefaultContentHandler::DefaultContentHandler() { + + } + + DefaultContentHandler::~DefaultContentHandler() { + + } + + void DefaultContentHandler::Print(const wchar_t* str_begin, const wchar_t* str_end) { + + } + + void DefaultContentHandler::Field_10() { + + } + + void DefaultContentHandler::NewLine() { + + } + + SimpleContentHandler::SimpleContentHandler(PrintWork* print_work, app::text_flags flags) { + this->print_work = print_work; + this->flags = flags; + } + + SimpleContentHandler::~SimpleContentHandler() { + + } + + void SimpleContentHandler::Print(const wchar_t* str_begin, const wchar_t* str_end) { + print_work->PutText(flags, str_begin, str_end); + } + + void SimpleContentHandler::NewLine() { + print_work->NewLine(); + } + + SimpleExtentContentHandler::SimpleExtentContentHandler(PrintWork* print_work) : new_line() { + this->print_work = print_work; + } + + SimpleExtentContentHandler::~SimpleExtentContentHandler() { + + } + + void SimpleExtentContentHandler::Print(const wchar_t* str_begin, const wchar_t* str_end) { + if (new_line) { + new_line = false; + space_size.y = print_work->font->spacing.y + space_size.y; + } + + vec2 str_size = print_work->GetStringSize(str_begin, str_end); + size.x = str_size.x + size.x; + size.y = max_def(str_size.y, size.y); + } + + void SimpleExtentContentHandler::NewLine() { + space_size.x = max_def(size.x, space_size.x); + space_size.y += size.y; + + size = 0.0f; + new_line = true; + } + + Reader::Reader() { + + } + + Reader::~Reader() { + + } + + SimpleReader::SimpleReader(PrintWork* print_work, ContentHandler* content_handler) { + this->print_work = print_work; + this->content_handler = content_handler; + } + + SimpleReader::~SimpleReader() { + + } + + void SimpleReader::Print(const wchar_t* str_begin, const wchar_t* str_end) { + for (const wchar_t* i = str_begin, *j = str_begin; i != str_end; j = i) { + size_t length = str_end - i; + const wchar_t* new_line_ptr; + if (length) { + new_line_ptr = i; + size_t len = length; + while (*new_line_ptr != '\n') { + new_line_ptr++; + + if (!--len) { + new_line_ptr = 0; + break; + } + } + } + else + new_line_ptr = 0; + + const wchar_t* _str_begin; + const wchar_t* _str_end; + bool new_line = !!new_line_ptr; + + if (new_line) { + size_t _length = new_line_ptr - i; + + _str_begin = i; + _str_end = i + _length; + if (i != i + _length) { + if (i[_length - 1] == '\r') { + if (_length <= 1) + _str_end = i; + else + _str_end = i + _length - 1; + } + } + + if (_length + 1 < length) + i += _length + 1; + else + i = str_end; + } + else { + _str_begin = j; + _str_end = str_end; + + // dafuq??? + size_t v15 = -(int64_t)i >> 1; + if (v15 < length) + i += v15; + else + i = str_end; + } + + content_handler->Print(_str_begin, _str_end); + if (new_line) + content_handler->NewLine(); + } + } + + void SimpleReader::SetContentHandler(ContentHandler* content_handler) { + this->content_handler = content_handler; + } + + ContentHandler* SimpleReader::GetContentHandler() { + return content_handler; + } + + SimpleAutoLineFeedReader::SimpleAutoLineFeedReader(PrintWork* print_work, + ContentHandler* content_handler) : SimpleReader(print_work, content_handler) { + + } + + SimpleAutoLineFeedReader::~SimpleAutoLineFeedReader() { + + } + + void SimpleAutoLineFeedReader::Print(const wchar_t* str_begin, const wchar_t* str_end) { + if (!str_begin || !str_end || !(str_end - str_begin)) + return; + + size_t line_length = print_work->line_length; + for (const wchar_t* i = str_begin; i != str_end; ) { + size_t length = str_end - i; + if (line_length) + length = min_def(length, line_length); + + const wchar_t* new_line_ptr; + if (length) { + new_line_ptr = i; + size_t len = length; + while (*new_line_ptr != '\n') { + new_line_ptr++; + + if (!--len) { + new_line_ptr = 0; + break; + } + } + } + else + new_line_ptr = 0; + + const wchar_t* _str_begin; + const wchar_t* _str_end; + bool new_line = !!new_line_ptr; + + if (new_line) { + size_t _length = new_line_ptr - i; + + _str_begin = i; + _str_end = i + _length; + if (i != i + _length) { + if (i[_length - 1] == '\r') { + if (_length > 1) + _str_end = &i[_length - 1]; + else + _str_end = i; + } + } + + if (_length + 1 < line_length) + i += _length + 1; + else + i = str_end; + } + else { + _str_begin = i; + _str_end = i + length; + + if (length < line_length) + i += length; + else + i = str_end; + + if (line_length && line_length <= length) { + new_line = true; + if (i != i + length && i[length - 1] == '\r' && i != str_end && *i == '\n') { + if (length > 1) + _str_end = &i[length - 1]; + else + _str_end = i; + + if (str_end - i > 1) + i++; + else + i = str_end; + } + } + } + + content_handler->Print(_str_begin, _str_end); + if (new_line) + content_handler->NewLine(); + } + } + } +} diff --git a/src/ReDIVA/print_work.hpp b/src/ReDIVA/print_work.hpp index b5f1f175..cb89d0e0 100644 --- a/src/ReDIVA/print_work.hpp +++ b/src/ReDIVA/print_work.hpp @@ -16,8 +16,8 @@ namespace app { TEXT_FLAG_ALIGN_FLAG_RIGHT = 0x00002, TEXT_FLAG_ALIGN_FLAG_H_CENTER = 0x00004, TEXT_FLAG_ALIGN_FLAG_LOCATE_H_CENTER = 0x00008, - TEXT_FLAG_5 = 0x00010, - TEXT_FLAG_6 = 0x00020, + TEXT_FLAG_ALIGN_FLAG_V_CENTER = 0x00010, + TEXT_FLAG_ALIGN_FLAG_LOCATE_V_CENTER = 0x00020, TEXT_FLAG_7 = 0x00040, TEXT_FLAG_8 = 0x00080, TEXT_FLAG_9 = 0x00100, @@ -32,6 +32,21 @@ namespace app { }; } +struct sprite_text_mesh { + int32_t sprite_id; + std::vector 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; @@ -51,15 +66,24 @@ 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 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); @@ -69,4 +93,8 @@ struct PrintWork { 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); + + static void sub_140196110(float_t a1, float_t a2, float_t a3, float_t a4, float_t& a5, float_t& a6); + vec2 sub_140197B80(app::text_flags flags, vec2 size); + static int32_t sub_140197D60(rectangle clip_box, rectangle& pos, rectangle& uv); }; diff --git a/src/ReDIVA/pv_game/pv_game.cpp b/src/ReDIVA/pv_game/pv_game.cpp index 9db5347e..b165e0f8 100644 --- a/src/ReDIVA/pv_game/pv_game.cpp +++ b/src/ReDIVA/pv_game/pv_game.cpp @@ -5372,7 +5372,7 @@ void TaskPvGame::Load(TaskPvGame::Data& data) { pv_game_time_data.add_current_time = true; sub_14013C8C0()->sub_1400E79E0(data.type); - sub_14013C8C0()->pv = data.init_data.pv_id;; + sub_14013C8C0()->pv = data.init_data.pv_id; sub_14013C8C0()->difficulty = data.init_data.difficulty; sub_14013C8C0()->edition = data.init_data.edition;