From f782842d7a6afb6728c8d235cdd7d54f33061537 Mon Sep 17 00:00:00 2001 From: korenkonder Date: Sun, 18 Jun 2023 02:30:44 +0300 Subject: [PATCH] Some updates. Broke dwgui/ImGui render --- src/CRE/Glitter/curve.cpp | 4 +- src/CRE/auth_2d.cpp | 8 +- src/CRE/font.cpp | 282 ++++++++++ src/CRE/font.hpp | 63 +++ src/CRE/render_context.cpp | 11 +- src/CRE/rob/rob.cpp | 10 +- src/KKdLib/dds.cpp | 2 +- src/KKdLib/default.cpp | 129 ++++- src/KKdLib/default.hpp | 91 ++++ src/KKdLib/interpolation.cpp | 14 +- src/KKdLib/io/json.cpp | 8 +- src/KKdLib/mot.cpp | 6 +- src/ReDIVA/classes/data_view/auth_3d.cpp | 4 +- src/ReDIVA/data_initialize.cpp | 5 +- src/ReDIVA/data_test/auth_2d_test.cpp | 76 ++- src/ReDIVA/data_test/auth_2d_test.hpp | 5 +- src/ReDIVA/data_test/motion_test.cpp | 148 +++--- src/ReDIVA/data_test/stage_test.cpp | 35 +- src/ReDIVA/dw.cpp | 638 ++++++++++++++++++----- src/ReDIVA/dw.hpp | 94 ++-- src/ReDIVA/font_info.cpp | 92 ++++ src/ReDIVA/font_info.hpp | 42 ++ src/ReDIVA/imgui_helper.cpp | 12 +- src/ReDIVA/imgui_helper.hpp | 10 + src/ReDIVA/print_work.cpp | 135 +++++ src/ReDIVA/print_work.hpp | 71 +++ src/ReDIVA/pv_game/pv_game_camera.cpp | 2 +- src/ReDIVA/render.cpp | 6 + 28 files changed, 1656 insertions(+), 347 deletions(-) create mode 100644 src/CRE/font.cpp create mode 100644 src/CRE/font.hpp create mode 100644 src/ReDIVA/font_info.cpp create mode 100644 src/ReDIVA/font_info.hpp create mode 100644 src/ReDIVA/print_work.cpp create mode 100644 src/ReDIVA/print_work.hpp diff --git a/src/CRE/Glitter/curve.cpp b/src/CRE/Glitter/curve.cpp index 3d88eae0..75b0f280 100644 --- a/src/CRE/Glitter/curve.cpp +++ b/src/CRE/Glitter/curve.cpp @@ -306,8 +306,8 @@ namespace Glitter { double_t t1_accum = 0.0; double_t t2_accum = 0.0; for (size_t j = 1; j < i - 1; j++) { - float_t _t1 = (float_t)(int32_t)((j + 0) * step) / (float_t)(int32_t)(i * step); - float_t _t2 = (float_t)(int32_t)((j + 1) * step) / (float_t)(int32_t)(i * step); + float_t _t1 = (float_t)(int64_t)((j + 0) * step) / (float_t)(int64_t)(i * step); + float_t _t2 = (float_t)(int64_t)((j + 1) * step) / (float_t)(int64_t)(i * step); float_t t1_1 = _t1 - 1.0f; float_t t2_1 = _t2 - 1.0f; diff --git a/src/CRE/auth_2d.cpp b/src/CRE/auth_2d.cpp index dd378445..cf8af2fe 100644 --- a/src/CRE/auth_2d.cpp +++ b/src/CRE/auth_2d.cpp @@ -699,8 +699,8 @@ void AetObj::Disp() { vec3 anchor = this->anchor; if (flags & AET_100000) { - anchor.x = (float_t)(int32_t)scene->width * 0.5f; - anchor.y = (float_t)(int32_t)scene->height * 0.5f; + anchor.x = (float_t)scene->width * 0.5f; + anchor.y = (float_t)scene->height * 0.5f; anchor.z = 0.0f; } @@ -712,8 +712,8 @@ void AetObj::Disp() { const aet_camera* camera = scene->camera; if (camera) { - float_t eye_x = camera->eye_x.interpolate(frame) - (float_t)(int32_t)scene->width * 0.5f; - float_t eye_y = camera->eye_y.interpolate(frame) - (float_t)(int32_t)scene->height * 0.5f; + float_t eye_x = camera->eye_x.interpolate(frame) - (float_t)scene->width * 0.5f; + float_t eye_y = camera->eye_y.interpolate(frame) - (float_t)scene->height * 0.5f; float_t eye_z = camera->eye_z.interpolate(frame); mat4_translate_mult(&mat, -eye_x, -eye_y, -eye_z, &mat); } diff --git a/src/CRE/font.cpp b/src/CRE/font.cpp new file mode 100644 index 00000000..6eca229e --- /dev/null +++ b/src/CRE/font.cpp @@ -0,0 +1,282 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#include "font.hpp" +#include "data.hpp" +#include + +struct fontmap { + p_file_handler file_handler; + bool read; + prj::shared_ptr alloc_handler; + font_handler handler[FONT_COUNT]; + font font[FONT_COUNT]; + + fontmap(); + ~fontmap(); + + const font_handler* get_font_handler(int32_t index); + bool load_file(); + void parse_file(); + void read_file(); + void set_font_handler(int32_t handler_index, int32_t font_index, bool disable_glyph_spacing = false); +}; + +struct font_character_file { + uint16_t id; + uint8_t halfwidth; + uint8_t pad; + uint8_t tex_column; + uint8_t tex_row; + uint8_t glyph_offset; + uint8_t glypth_width; +}; + +struct font_file { + int32_t map_id; + uint8_t character_advance_width; + uint8_t character_line_height; + uint8_t glyph_box_width; + uint8_t glyph_box_height; + uint8_t flags; + uint8_t column_scale_num; + uint8_t column_scale_denom; + uint8_t field_B; + uint32_t field_C; + uint32_t characters_count_per_row; + uint32_t characters_count; + uint32_t characters_offset; +}; + +struct fontmap_header { + uint32_t signature; + uint32_t pad; + uint32_t font_count; + uint32_t font_offsets_offset; +}; + +fontmap* fontmap_data; + +static const font_character font_character_null = {}; + +font::font() : glyph_width(), glyph_height(), glyph_box_width(), glyph_box_height(), +column_scale_num(), column_scale_denom(), column_scale(), characters_count_per_row(), disable_glyph_spacing() { + sprite_id = -1; + map_id = -1; +} + +font::~font() { + +} + +const font_character* font::get_character(wchar_t c) const { + if (c >= 0 && c < characters.size()) + return &characters[c]; + return &font_character_null; +} + +void font::init(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) { + this->sprite_id = sprite_id; + this->glyph_width = glyph_width; + this->glyph_height = glyph_height; + this->glyph_box_width = glyph_box_width; + this->glyph_box_height = glyph_box_height; + this->map_id = map_id; + + set_column_scale(column_scale_num, column_scale_denom); + + characters_count_per_row = 16; + + if (characters.capacity() < 0x100) + characters.reserve(0x100); + + font_character font_char = {}; + font_char.init = true; + font_char.glyph_offset = 0; + for (int32_t i = 0; i < 0x100; i++) { + font_char.halfwidth = column_scale_denom != 1; + font_char.tex_row = (uint8_t)(i / characters_count_per_row); + font_char.tex_column = (uint8_t)(i % characters_count_per_row); + font_char.glyph_width = glyph_width; + characters.push_back(font_char); + } +} + +void font::set_column_scale(uint8_t num, uint8_t denom) { + column_scale_num = num; + column_scale_denom = denom; + column_scale = (float_t)num / (float_t)denom; +} + +void font_handler::set_font(const font* f, bool disable_glyph_spacing) { + font_ptr = f; + glyph_width = f->glyph_width; + glyph_height = f->glyph_height; + glyph_horizontal_spacing = 0; + glyph_vertical_spacing = 0; + disable_glyph_spacing = disable_glyph_spacing; +} + +void fontmap_data_init() { + if (!fontmap_data) + fontmap_data = new fontmap; +} + +const font_handler* fontmap_data_get_font_handler(int32_t index) { + return fontmap_data->get_font_handler(index); +} + +bool fontmap_data_load_file() { + return fontmap_data->load_file(); +} + +void fontmap_data_read_file() { + fontmap_data->read_file(); +} + +void fontmap_data_free() { + if (fontmap_data) { + delete fontmap_data; + fontmap_data = 0; + } +} + +fontmap::fontmap() : read(), handler() { + font[0].init(3348, 10, 16, 10, 16, 1, 1, -1); + font[1].init(2281, 12, 18, 14, 20, 1, 1, 12); + font[2].init(211, 24, 24, 26, 26, 1, 2, 0); + font[3].init(7365, 24, 24, 26, 26, 1, 2, 0); + font[4].init(1625, 12, 16, 14, 18, 1, 1, 5); + font[5].init(1390, 14, 20, 16, 22, 1, 1, 1); + font[6].init(1670, 14, 18, 16, 20, 1, 1, 9); + font[7].init(1602, 20, 26, 22, 28, 1, 1, 6); + font[8].init(38527, 20, 22, 22, 24, 1, 1, 14); + font[9].init(1695, 22, 22, 24, 24, 1, 1, 10); + font[10].init(1665, 22, 24, 24, 26, 1, 1, 11); + font[11].init(1391, 24, 30, 26, 32, 1, 1, 2); + font[12].init(1282, 26, 24, 28, 26, 1, 1, 3); + font[13].init(2853, 28, 40, 30, 42, 1, 1, 13); + font[14].init(8827, 28, 40, 30, 42, 1, 1, 13); + font[15].init(1283, 34, 32, 36, 34, 1, 1, 4); + font[16].init(1603, 40, 52, 42, 54, 1, 1, 7); + font[17].init(1604, 56, 46, 58, 48, 1, 1, 8); + + set_font_handler(0, 0); + set_font_handler(15, 1); + set_font_handler(16, 2); + set_font_handler(17, 3); + set_font_handler(1, 4); + set_font_handler(2, 5); + set_font_handler(3, 6); + set_font_handler(4, 7); + set_font_handler(5, 8); + set_font_handler(6, 9); + set_font_handler(7, 10); + set_font_handler(8, 11); + set_font_handler(9, 12); + set_font_handler(10, 13); + set_font_handler(11, 14); + set_font_handler(12, 15); + set_font_handler(13, 16); + set_font_handler(14, 17); +} + +fontmap::~fontmap() { + +} + +const font_handler* fontmap::get_font_handler(int32_t index) { + if (index < 0 || index >= FONT_COUNT) + index = 0; + return &handler[index]; +} + +bool fontmap::load_file() { + if (read) + return false; + + if (file_handler.check_not_ready()) + return true; + + parse_file(); + + file_handler.reset(); + read = true; + return false; +} + +void fontmap::parse_file() { + size_t data = (size_t)file_handler.get_data(); + fontmap_header* fmh = (fontmap_header*)data; + if (fmh->signature != reverse_endianness_uint32_t('FMH3')) + return; + + std::map font_map; + + uint32_t* font_offsets = (uint32_t*)(data + fmh->font_offsets_offset); + for (uint32_t i = 0; i < fmh->font_count; i++) { + font_file* ff = (font_file*)(data + font_offsets[i]); + auto elem = font_map.find(ff->map_id); + if (elem != font_map.end()) + elem->second = ff; + else + font_map.insert({ ff->map_id, ff }); + } + + for (::font& i : font) { + if (i.map_id == -1) + continue; + + auto elem = font_map.find(i.map_id); + if (elem == font_map.end()) + continue; + + font_file* ff = elem->second; + i.set_column_scale(ff->column_scale_num, ff->column_scale_denom); + i.characters_count_per_row = ff->characters_count_per_row; + i.disable_glyph_spacing = (ff->flags & 2) != 0; + if (!ff->characters_count) + continue; + + font_character_file* first_char = (font_character_file*)(data + ff->characters_offset); + font_character_file* last_char = &first_char[ff->characters_count]; + + font_character_file* max_char = first_char; + if (first_char != last_char) + for (font_character_file* j = first_char + 1; j != last_char; j++) + if (max_char->id < j->id) + max_char = j; + + i.characters.clear(); + i.characters.resize(max_char->id + 1ULL); + + for (size_t k = 0; k < ff->characters_count; k++) { + font_character_file* c_f = &((font_character_file*)(data + ff->characters_offset))[k]; + if (c_f->id < i.characters.size()) { + font_character* c = &i.characters.data()[c_f->id]; + c->init = true; + c->halfwidth = !!c_f->halfwidth; + c->tex_column = c_f->tex_column; + c->tex_row = c_f->tex_row; + c->glyph_offset = c_f->glyph_offset; + c->glyph_width = c_f->glypth_width; + } + } + } +} + +void fontmap::read_file() { + if (read) + return; + + file_handler.read_file(&data_list[DATA_AFT], "rom/", "fontmap.farc", "fontmap.bin", false); + read = false; +} + +void fontmap::set_font_handler(int32_t handler_index, int32_t font_index, bool disable_glyph_spacing) { + handler[handler_index].set_font(&font[font_index], disable_glyph_spacing); +} diff --git a/src/CRE/font.hpp b/src/CRE/font.hpp new file mode 100644 index 00000000..b7672635 --- /dev/null +++ b/src/CRE/font.hpp @@ -0,0 +1,63 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#pragma once + +#include "../KKdLib/default.hpp" +#include "../KKdLib/prj/shared_ptr.hpp" +#include "../KKdLib/prj/stack_allocator.hpp" +#include "file_handler.hpp" + +#define FONT_COUNT 18 + +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; + std::vector characters; + bool disable_glyph_spacing; + + font(); + ~font(); + + const font_character* get_character(wchar_t c) const; + void init(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); + void set_column_scale(uint8_t num, uint8_t denom); +}; + +struct font_handler { + const font* font_ptr; + int16_t glyph_width; + int16_t glyph_height; + int16_t glyph_horizontal_spacing; + int16_t glyph_vertical_spacing; + bool disable_glyph_spacing; + + void set_font(const font* f, bool disable_glyph_spacing); +}; + +extern void fontmap_data_init(); +extern const font_handler* fontmap_data_get_font_handler(int32_t index); +extern bool fontmap_data_load_file(); +extern void fontmap_data_read_file(); +extern void fontmap_data_free(); diff --git a/src/CRE/render_context.cpp b/src/CRE/render_context.cpp index 25e9b2d3..8a0dbfb5 100644 --- a/src/CRE/render_context.cpp +++ b/src/CRE/render_context.cpp @@ -3877,9 +3877,9 @@ void shadow::ctrl(render_context* rctx) { for (vec3& j : field_1D0[i]) v7 += j; - float_t v14 = (float_t)(int32_t)field_1D0[i].size(); + float_t v14 = (float_t)(int64_t)field_1D0[i].size(); if (v14 < 0.0f) - v14 += 1.8446744e19f; + v14 += (float_t)UINT64_MAX; v7 *= 1.0f / v14; float_t v15 = 0.0f; @@ -3971,10 +3971,9 @@ void shadow::ctrl(render_context* rctx) { for (vec3& j : field_1D0[i]) v22 += j; - int32_t v27 = (int32_t)field_1D0[i].size(); - float_t v29 = (float_t)v27; - if (v27 < 0) - v29 += 1.8446744e19f; + float_t v29 = (float_t)(int64_t)field_1D0[i].size(); + if (v29 < 0.0f) + v29 += (float_t)UINT64_MAX; float_t v30 = 0.0f; vec3 v31 = v22 * (1.0f / v29); diff --git a/src/CRE/rob/rob.cpp b/src/CRE/rob/rob.cpp index fadd67c6..f12e2015 100644 --- a/src/CRE/rob/rob.cpp +++ b/src/CRE/rob/rob.cpp @@ -2519,22 +2519,22 @@ mat4* rob_chara_bone_data_get_mats_mat(rob_chara_bone_data* rob_bone_data, size_ static void rob_chara_data_adjust_ctrl(rob_chara* rob_chr, rob_chara_data_adjust* adjust, rob_chara_data_adjust* adjust_prev) { float_t cycle = adjust->cycle; - float_t v7 = 0.0f; adjust->frame += rob_chr->data.motion.step_data.frame; if (rob_chr->data.field_1588.field_0.field_58 == 1) cycle *= (60.0f / rob_chr->data.field_1588.field_0.frame); cycle *= adjust->frame * 2.0f * (float_t)M_PI * (float_t)(1.0 / 60.0f); + float_t cycle_val = 0.0f; switch (adjust->cycle_type) { case 1: - v7 = cosf(adjust->phase * (float_t)M_PI + cycle); + cycle_val = cosf(adjust->phase * (float_t)M_PI + cycle); break; case 2: - v7 = sinf(adjust->phase * (float_t)M_PI + cycle); + cycle_val = sinf(adjust->phase * (float_t)M_PI + cycle); break; } - adjust->curr_external_force = (adjust->external_force_cycle + v7) + adjust->curr_external_force = (adjust->external_force_cycle + cycle_val) * (adjust->external_force * adjust->external_force_cycle_strength) + adjust->external_force; if (adjust->type == 1) { @@ -19478,7 +19478,7 @@ bool TaskRobManager::CheckCharaLoaded(rob_chara* rob_chr) { || rob_chr->chara_id < 0 || rob_chr->chara_id >= ROB_CHARA_COUNT) return false; - int8_t chara_id = rob_chr->chara_id; + int8_t chara_id = rob_chr->chara_id; for (rob_chara*& i : free_chara) if (i->chara_id == chara_id) return false; diff --git a/src/KKdLib/dds.cpp b/src/KKdLib/dds.cpp index cd7116ce..597bdb51 100644 --- a/src/KKdLib/dds.cpp +++ b/src/KKdLib/dds.cpp @@ -159,7 +159,7 @@ dds::~dds() { } } -void dds::read( const char* path) { +void dds::read(const char* path) { if (!this || !path) return; diff --git a/src/KKdLib/default.cpp b/src/KKdLib/default.cpp index d2bff2bd..38d8a888 100644 --- a/src/KKdLib/default.cpp +++ b/src/KKdLib/default.cpp @@ -71,6 +71,62 @@ wchar_t* utf8_to_utf16(const char* s) { return str; } +wchar_t* utf8_to_utf16(const char* s, size_t length) { + if (!s || !length) + return 0; + + uint32_t c = 0; + size_t _length = utf8_to_utf16_length(s); + + wchar_t* str = force_malloc_s(wchar_t, _length + 1); + if (!str) + return 0; + + size_t j = 0; + size_t l = 0; + while (*s && length) { + char t = *s++; + length--; + if (!(t & 0x80)) { + l = 0; + str[j++] = t; + c = 0; + continue; + } + else if ((t & 0xFC) == 0xF8) + continue; + else if ((t & 0xF8) == 0xF0) { + c = t & 0x07; + l = 3; + } + else if ((t & 0xF0) == 0xE0) { + c = t & 0x0F; + l = 2; + } + else if ((t & 0xE0) == 0xC0) { + c = t & 0x1F; + l = 1; + } + else if ((t & 0xC0) == 0x80) { + c = (c << 6) | (t & 0x3F); + l--; + } + + if (!l) { + if (c <= 0xD7FF || (c >= 0xE000 && c <= 0xFFFF)) + str[j++] = c; + else if (c >= 0x10000 && c <= 0x10FFFF) { + c -= 0x10000; + str[j++] = 0xD800 | ((c >> 10) & 0x3FF); + str[j++] = 0xDC00 | (c & 0x3FF); + } + c = 0; + } + } + str[_length] = 0; + return str; +} + char* utf16_to_utf8(const wchar_t* s) { if (!s) return 0; @@ -123,22 +179,77 @@ char* utf16_to_utf8(const wchar_t* s) { return str; } +char* utf16_to_utf8(const wchar_t* s, size_t length) { + if (!s || !length) + return 0; + + uint32_t c = 0; + size_t _length = utf16_to_utf8_length(s); + + char* str = force_malloc_s(char, _length + 1); + if (!str) + return 0; + + size_t j = 0; + while (*s && length) { + c = *s++; + length--; + if ((c & 0xFC00) == 0xD800) { + if (!*s) + break; + + wchar_t _c = *s++; + if ((_c & 0xFC00) != 0xDC00) + continue; + + c &= 0x3FF; + c <<= 10; + c |= _c & 0x3FF; + c += 0x10000; + } + else if ((c & 0xFC00) == 0xDC00) + continue; + + if (c <= 0x7F) + str[j++] = (uint8_t)c; + else if (c <= 0x7FF) { + str[j++] = (uint8_t)(0xC0 | ((c >> 6) & 0x1F)); + str[j++] = (uint8_t)(0x80 | (c & 0x3F)); + } + else if ((c >= 0x800 && c <= 0xD7FF) || (c >= 0xE000 && c <= 0xFFFF)) { + str[j++] = (uint8_t)(0xE0 | ((c >> 12) & 0xF)); + str[j++] = (uint8_t)(0x80 | ((c >> 6) & 0x3F)); + str[j++] = (uint8_t)(0x80 | (c & 0x3F)); + } + else if (c >= 0x10000 && c <= 0x10FFFF) { + str[j++] = (uint8_t)(0xF0 | ((c >> 18) & 0x7)); + str[j++] = (uint8_t)(0x80 | ((c >> 12) & 0x3F)); + str[j++] = (uint8_t)(0x80 | ((c >> 6) & 0x3F)); + str[j++] = (uint8_t)(0x80 | (c & 0x3F)); + } + } + str[_length] = 0; + return str; +} + std::wstring utf8_to_utf16(const std::string& s) { - if (!s.size()) + size_t length = s.size(); + if (!length) return {}; uint32_t c = 0; - size_t length = utf8_to_utf16_length(s.c_str()); + size_t _length = utf8_to_utf16_length(s.c_str()); std::wstring str; - str.resize(length); + str.resize(_length); char* _s = (char*)s.data(); wchar_t* _str = (wchar_t*)str.data(); size_t l = 0; - while (*_s) { + while (*_s && length) { char t = *_s++; + length--; if (!(t & 0x80)) { l = 0; *_str++ = t; @@ -179,20 +290,22 @@ std::wstring utf8_to_utf16(const std::string& s) { } std::string utf16_to_utf8(const std::wstring& s) { - if (!s.size()) + size_t length = s.size(); + if (!length) return {}; uint32_t c = 0; - size_t length = utf16_to_utf8_length(s.c_str()); + size_t _length = utf16_to_utf8_length(s.c_str()); std::string str; - str.resize(length); + str.resize(_length); wchar_t* _s = (wchar_t*)s.data(); char* _str = (char*)str.data(); - while (*_s) { + while (*_s && length) { c = *_s++; + length--; if ((c & 0xFC00) == 0xD800) { if (!*_s) break; diff --git a/src/KKdLib/default.hpp b/src/KKdLib/default.hpp index a859cff8..9d0cf2af 100644 --- a/src/KKdLib/default.hpp +++ b/src/KKdLib/default.hpp @@ -377,7 +377,59 @@ inline constexpr size_t utf8_to_utf16_length(const char* s) { return length; } +inline constexpr size_t utf8_to_utf16_length(const char* s, size_t length) { + if (!s || !length) + return 0; + + uint32_t c = 0; + size_t _length = 0; + size_t l = 0; + + while (*s && length) { + char t = *s++; + length--; + if (!(t & 0x80)) { + l = 0; + _length++; + c = 0; + continue; + } + else if ((t & 0xFC) == 0xF8) + continue; + else if ((t & 0xF8) == 0xF0) { + c = t & 0x07; + l = 3; + } + else if ((t & 0xF0) == 0xE0) { + c = t & 0x0F; + l = 2; + } + else if ((t & 0xE0) == 0xC0) { + c = t & 0x1F; + l = 1; + } + else if ((t & 0xC0) == 0x80) { + c = (c << 6) | (t & 0x3F); + l--; + } + + if (!l) { + if (c <= 0xD7FF || (c >= 0xE000 && c <= 0xFFFF)) + _length++; + else if (c >= 0x10000 && c <= 0x10FFFF) { + _length++; + _length++; + } + c = 0; + } + } + return _length; +} + inline constexpr size_t utf16_to_utf8_length(const wchar_t* s) { + if (!s) + return 0; + uint32_t c = 0; size_t length = 0; while (*s) { @@ -410,7 +462,46 @@ inline constexpr size_t utf16_to_utf8_length(const wchar_t* s) { return length; } +inline constexpr size_t utf16_to_utf8_length(const wchar_t* s, size_t length) { + if (!s || !length) + return 0; + + uint32_t c = 0; + size_t _length = 0; + while (*s && length) { + c = *s++; + length--; + if ((c & 0xFC00) == 0xD800) { + if (!*s) + break; + + wchar_t _c = *s++; + if ((_c & 0xFC00) != 0xDC00) + continue; + + c &= 0x3FF; + c <<= 10; + c |= _c & 0x3FF; + c += 0x10000; + } + else if ((c & 0xFC00) == 0xDC00) + continue; + + if (c <= 0x7F) + _length++; + else if (c <= 0x7FF) + _length += 2; + else if ((c >= 0x800 && c <= 0xD7FF) || (c >= 0xE000 && c <= 0xFFFF)) + _length += 3; + else if (c >= 0x10000 && c <= 0x10FFFF) + _length += 4; + } + return _length; +} + extern wchar_t* utf8_to_utf16(const char* s); +extern wchar_t* utf8_to_utf16(const char* s, size_t length); extern char* utf16_to_utf8(const wchar_t* s); +extern char* utf16_to_utf8(const wchar_t* s, size_t length); extern std::wstring utf8_to_utf16(const std::string& s); extern std::string utf16_to_utf8(const std::wstring& s); diff --git a/src/KKdLib/interpolation.cpp b/src/KKdLib/interpolation.cpp index b9a2f5b0..ae4276ae 100644 --- a/src/KKdLib/interpolation.cpp +++ b/src/KKdLib/interpolation.cpp @@ -8,9 +8,9 @@ void interpolate_chs_reverse_value(float_t* arr, size_t length, float_t& t1, float_t& t2, size_t f1, size_t f2, size_t f) { vec2 t = vec2( - (float_t)(int32_t)(f - f1 + 0), - (float_t)(int32_t)(f - f1 + 1) - ) / (float_t)(int32_t)(f2 - f1); + (float_t)(int64_t)(f - f1 + 0), + (float_t)(int64_t)(f - f1 + 1) + ) / (float_t)(int64_t)(f2 - f1); vec2 t_2 = t * t; vec2 t_3 = t_2 * t; vec2 t_23 = 3.0f * t_2; @@ -93,7 +93,7 @@ int32_t interpolate_chs_reverse_sequence( if (left_count > 1) { values.push_back({ (float_t)frame, a[0], t2_old, 0.0f }); for (size_t j = 1; j < left_count - 1; j++) - values.push_back({ (float_t)(int32_t)(frame + j), a[j] }); + values.push_back({ (float_t)(int64_t)(frame + j), a[j] }); t2_old = 0.0f; } break; @@ -187,7 +187,7 @@ int32_t interpolate_chs_reverse_sequence( if (has_error) { values.push_back({ (float_t)frame, a[0], t2_old, 0.0f }); for (size_t j = 1; j < c; j++) - values.push_back({ (float_t)(int32_t)(frame + j), a[j] }); + values.push_back({ (float_t)(int64_t)(frame + j), a[j] }); t2_old = 0.0f; } else { @@ -208,12 +208,12 @@ int32_t interpolate_chs_reverse_sequence( left_count -= c; } - values.push_back({ (float_t)(int32_t)(count - 1), arr[count - 1], t2_old, 0.0f }); + values.push_back({ (float_t)(int64_t)(count - 1), arr[count - 1], t2_old, 0.0f }); kft3* keys = values.data(); size_t length = values.size(); for (size_t i = 0; i < count; i++) { - float_t frame = (float_t)(int32_t)i; + float_t frame = (float_t)(int64_t)i; kft3* first_key = keys; kft3* key = keys; diff --git a/src/KKdLib/io/json.cpp b/src/KKdLib/io/json.cpp index e96f0fdf..1d19cbf6 100644 --- a/src/KKdLib/io/json.cpp +++ b/src/KKdLib/io/json.cpp @@ -180,7 +180,7 @@ static void io_json_read_float(stream& s, io_json_read_buffer* buf, msgpack* msg } if (*c == '0') { - dig_buf[buf_pos++] = *c; + dig_buf[buf_pos++] = *c; if ((*c = io_json_read_char(s, buf)) == EOF) return; zero = true; @@ -189,7 +189,7 @@ static void io_json_read_float(stream& s, io_json_read_buffer* buf, msgpack* msg io_json_read_digit(s, buf, c, dig_buf, &buf_pos, buf_end); if (*c == '.') { - dig_buf[buf_pos++] = *c; + dig_buf[buf_pos++] = *c; if ((*c = io_json_read_char(s, buf)) == EOF) return; io_json_read_digit(s, buf, c, dig_buf, &buf_pos, buf_end); @@ -227,12 +227,12 @@ static void io_json_read_float(stream& s, io_json_read_buffer* buf, msgpack* msg return; } else if (*c == 'e' || *c == 'E') { - dig_buf[buf_pos++] = *c; + dig_buf[buf_pos++] = *c; if ((*c = io_json_read_char(s, buf)) == EOF) return; if (*c == '+' || *c == '-') { - dig_buf[buf_pos++] = *c; + dig_buf[buf_pos++] = *c; if ((*c = io_json_read_char(s, buf)) == EOF) return; } diff --git a/src/KKdLib/mot.cpp b/src/KKdLib/mot.cpp index ca5c9a27..8294cd0c 100644 --- a/src/KKdLib/mot.cpp +++ b/src/KKdLib/mot.cpp @@ -123,9 +123,9 @@ static float_t interpolate_mot_value(float_t p1, float_t p2, static void interpolate_mot_reverse_value(float_t* arr, size_t length, float_t& t1, float_t& t2, size_t f1, size_t f2, size_t f) { vec2 t = vec2( - (float_t)(int32_t)(f - f1 + 0), - (float_t)(int32_t)(f - f1 + 1) - ) / (float_t)(int32_t)(f2 - f1); + (float_t)(int64_t)(f - f1 + 0), + (float_t)(int64_t)(f - f1 + 1) + ) / (float_t)(int64_t)(f2 - f1); vec2 t_1 = t - 1.0f; vec2 t1_t2 = *(vec2*)&arr[f] - arr[f1] - (t * 2.0f - 3.0f) * (t * t) * (arr[f1] - arr[f2]); diff --git a/src/ReDIVA/classes/data_view/auth_3d.cpp b/src/ReDIVA/classes/data_view/auth_3d.cpp index 417a943b..7055ce4b 100644 --- a/src/ReDIVA/classes/data_view/auth_3d.cpp +++ b/src/ReDIVA/classes/data_view/auth_3d.cpp @@ -143,7 +143,7 @@ void data_view_auth_3d_imgui(class_data* data) { if (auth->auth_2d.size() > 0 && ImGui::TreeNodeEx("Auth 2D", tree_node_flags)) { for (std::string& l : auth->auth_2d) - ImGui::Text(l.c_str()); + ImGui::Text("%s", l.c_str()); ImGui::TreePop(); } @@ -198,7 +198,7 @@ void data_view_auth_3d_imgui(class_data* data) { if (auth->motion.size() > 0 && ImGui::TreeNodeEx("Motion", tree_node_flags)) { for (std::string& l : auth->motion) - ImGui::Text(l.c_str()); + ImGui::Text("%s", l.c_str()); ImGui::TreePop(); } diff --git a/src/ReDIVA/data_initialize.cpp b/src/ReDIVA/data_initialize.cpp index d36d307a..cfbbb09d 100644 --- a/src/ReDIVA/data_initialize.cpp +++ b/src/ReDIVA/data_initialize.cpp @@ -8,6 +8,7 @@ #include "../CRE/auth_2d.hpp" #include "../CRE/customize_item_table.hpp" #include "../CRE/data.hpp" +#include "../CRE/font.hpp" #include "../CRE/hand_item.hpp" #include "../CRE/item_table.hpp" #include "../CRE/module_table.hpp" @@ -46,14 +47,14 @@ bool TaskDataInit::Ctrl() { sprite_manager_read_file(4, "", aft_data, aft_spr_db); sprite_manager_read_file(472, "", aft_data, aft_spr_db); sprite_manager_read_file(43, "", aft_data, aft_spr_db); - //fontmap_data_read_file(); + fontmap_data_read_file(); state = 1; } break; case 1: if (!sprite_manager_load_file(4, aft_spr_db) && !sprite_manager_load_file(472, aft_spr_db) && !sprite_manager_load_file(43, aft_spr_db) - /* || fontmap_data_parse_file()*/) + && !fontmap_data_load_file()) state = field_6C ? 2 : 4; break; case 2: diff --git a/src/ReDIVA/data_test/auth_2d_test.cpp b/src/ReDIVA/data_test/auth_2d_test.cpp index 4c47d80c..da85fee2 100644 --- a/src/ReDIVA/data_test/auth_2d_test.cpp +++ b/src/ReDIVA/data_test/auth_2d_test.cpp @@ -168,7 +168,7 @@ bool DtmAet::Ctrl() { char buf[0x20]; sprintf_s(buf, sizeof(buf), "%f frame", frame); - dtw_aet->marker_frame->SetName(buf); + dtw_aet->marker_frame->SetText(buf); this->frame = frame; state = 7; } break; @@ -231,8 +231,49 @@ bool DtmAet::Dest() { } void DtmAet::Disp() { - if (state != 7) + if (state != 7 || !type) return; + + data_struct* aft_data = &data_list[DATA_AFT]; + sprite_database* aft_spr_db = &aft_data->data_ft.spr_db; + + for (const auto& i : comp.data) { + vec2 v7 = 0.0f; + if (centering) + v7 = vec2((float_t)res_window_get()->width, (float_t)res_window_get()->height) * 0.5f; + + vec3 pos; + *(vec2*)&pos = *(vec2*)&i.second.position + v7; + pos.z = i.second.position.z; + + spr::SprArgs v34; + v34.SetSpriteSize({ 10.0f, 10.0f}); + v34.trans = pos; + v34.center = { 5.0f, 5.0f, 0.0f }; + v34.kind = spr::SPR_KIND_LINES; + v34.resolution_mode_screen = i.second.mode; + + spr::SprArgs v35 = v34; + v35.rot.z = v34.rot.z + (float_t)(M_PI / 2.0f); + spr::put_sprite(v34, aft_spr_db); + spr::put_sprite(v35, aft_spr_db); + + font.init_font_data(0); + + print_work.SetFont(&font); + print_work.prio = spr::SPR_PRIO_29; + print_work.line_origin_loc = *(vec2*)&pos; + print_work.text_current_loc = print_work.line_origin_loc; + print_work.SetResolutionMode(i.second.mode); + print_work.color = color_red; + print_work.printf_align_left("%s\n", i.first.c_str()); + + /*if (input_state_get(0)->sub_14018D480(64)) { + print_work.color = color_white; + print_work.printf_align_left("p(%.2f,%.2f)\n", pos.x, pos.y); + print_work.printf_align_left("o(%f)\n", i.second.opacity); + }*/ + } } void DtmAet::Basic() { @@ -324,16 +365,15 @@ void DtmAet::SetCentering(bool value) { centering = value; } -DtwAet::DtwAet() : Shell(0) { +DtwAet::DtwAet() { data_struct* aft_data = &data_list[DATA_AFT]; aet_database* aft_aet_db = &aft_data->data_ft.aet_db; - position = { 0.0f, 0.0f }; - size = { 220.0f, 380.0f }; + rect = { 0.0f, 0.0f, 220.0f, 380.0f }; - dw::Widget::SetName("2DAUTH TEST"); + dw::Widget::SetText("2DAUTH TEST"); - (new dw::Label(this))->SetName("SET"); + (new dw::Label(this))->SetText("SET"); set = new dw::ListBox(this); @@ -348,14 +388,14 @@ DtwAet::DtwAet() : Shell(0) { set->list->AddSelectionListener(new dw::SelectionListenerOnHook(DtwAet::SetCallback)); - (new dw::Label(this))->SetName("ID"); + (new dw::Label(this))->SetText("ID"); id = new dw::ListBox(this); //id->list->sub_1402F9930(20); id->list->AddSelectionListener(new dw::SelectionListenerOnHook(DtwAet::IdCallback)); - (new dw::Label(this))->SetName("LAYER"); + (new dw::Label(this))->SetText("LAYER"); layer = new dw::ListBox(this); layer->AddItem("ROOT"); @@ -363,7 +403,7 @@ DtwAet::DtwAet() : Shell(0) { layer->list->AddSelectionListener(new dw::SelectionListenerOnHook(DtwAet::LayerCallback)); - (new dw::Label(this))->SetName("MARKER"); + (new dw::Label(this))->SetText("MARKER"); marker = new dw::ListBox(this); marker->AddItem("NOMARKER"); @@ -372,9 +412,9 @@ DtwAet::DtwAet() : Shell(0) { marker->list->AddSelectionListener(new dw::SelectionListenerOnHook(DtwAet::MarkerCallback)); marker_frame = new dw::Label(this); - marker_frame->SetName("0"); + marker_frame->SetText("0"); - (new dw::Label(this))->SetName("TYPE"); + (new dw::Label(this))->SetText("TYPE"); type = new dw::ListBox(this); type->AddItem("DRAW"); @@ -384,29 +424,29 @@ DtwAet::DtwAet() : Shell(0) { type->list->AddSelectionListener(new dw::SelectionListenerOnHook(DtwAet::TypeCallback)); - (new dw::Label(this))->SetName("FRAME"); + (new dw::Label(this))->SetText("FRAME"); frame = dw::Slider::make(this, (dw::Flags)(dw::FLAG_800 | dw::HORIZONTAL), 0.0f, 0.0f, 128.0f, 20.0f, "slider"); - frame->SetName("FRAME"); + frame->SetText("FRAME"); frame->format = "%4.0f"; frame->SetParams(0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 10.0f); frame->AddSelectionListener(new dw::SelectionListenerOnHook(DtwAet::FrameCallback)); - (new dw::Label(this))->SetName("SWITCH"); + (new dw::Label(this))->SetText("SWITCH"); dw::Button* lock = new dw::Button(this, dw::CHECKBOX); - lock->SetName("LOCK"); + lock->SetText("LOCK"); lock->callback = DtwAet::LockCallback; dw::Button* loop = new dw::Button(this, dw::CHECKBOX); - loop->SetName("LOOP"); + loop->SetText("LOOP"); loop->callback = DtwAet::LoopCallback; dw::Button* centering = new dw::Button(this, dw::CHECKBOX); - centering->SetName("CENTERING"); + centering->SetText("CENTERING"); centering->callback = DtwAet::CenteringCallback; //GetSetSize(); diff --git a/src/ReDIVA/data_test/auth_2d_test.hpp b/src/ReDIVA/data_test/auth_2d_test.hpp index aa75520e..a6115aca 100644 --- a/src/ReDIVA/data_test/auth_2d_test.hpp +++ b/src/ReDIVA/data_test/auth_2d_test.hpp @@ -8,13 +8,14 @@ #include "../../KKdLib/default.hpp" #include "../../CRE/auth_2d.hpp" #include "../dw.hpp" +#include "../print_work.hpp" #include "../task_window.hpp" class DtmAet : public app::Task { public: std::vector sound_farcs; - //draw_params draw_params; - //font_info font; + PrintWork print_work; + font_info font; uint32_t curr_set_index; uint32_t set_index; uint32_t id_index; diff --git a/src/ReDIVA/data_test/motion_test.cpp b/src/ReDIVA/data_test/motion_test.cpp index c636e455..b1d43cf7 100644 --- a/src/ReDIVA/data_test/motion_test.cpp +++ b/src/ReDIVA/data_test/motion_test.cpp @@ -1231,54 +1231,54 @@ int32_t DtmMot::ConvertMotionSetNameToPVID(const char* set_name) { DataTestFaceMotDw::DataTestFaceMotDw(int32_t chara_id) { this->chara_id = chara_id; - SetName("Face motion"); + SetText("Face motion"); enable = new dw::Button(this, dw::CHECKBOX); - enable->SetName("Enable"); + enable->SetText("Enable"); enable->SetValue(false); dw::Group* motion_group = new dw::Group(this); motion_group->SetLayout(new dw::GridLayout(3)); - motion_group->SetName("Motion"); + motion_group->SetText("Motion"); - (new dw::Label(motion_group))->SetName("FACE "); + (new dw::Label(motion_group))->SetText("FACE "); face = InitAddMottblMapMotions(motion_group, 0); face_frame = dw::Slider::make(motion_group); - face_frame->SetName("Frame "); + face_frame->SetText("Frame "); face_frame->format = "%4.0f"; face_frame->SetParams(0.0f, 0.0f, 100.0f, 10.0f, 1.0f, 10.0f); - (new dw::Label(motion_group))->SetName("FACE_CL "); + (new dw::Label(motion_group))->SetText("FACE_CL "); face_cl = new dw::Label(motion_group); - face_cl->SetName(""); + face_cl->SetText(""); face_cl_frame = dw::Slider::make(motion_group); - face_cl_frame->SetName("Frame"); + face_cl_frame->SetText("Frame"); face_cl_frame->format = "%4.0f"; face_cl_frame->SetParams(0.0f, 0.0f, 100.0f, 10.0f, 1.0f, 10.0f); - (new dw::Label(motion_group))->SetName("EYES "); + (new dw::Label(motion_group))->SetText("EYES "); eyes = InitAddMottblMapMotions(motion_group, 1); eyes_frame = dw::Slider::make(motion_group); - eyes_frame->SetName("Frame"); + eyes_frame->SetText("Frame"); eyes_frame->format = "%4.0f"; eyes_frame->SetParams(0.0f, 0.0f, 100.0f, 10.0f, 1.0f, 10.0f); - (new dw::Label(motion_group))->SetName("MOUTH "); + (new dw::Label(motion_group))->SetText("MOUTH "); mouth = InitAddMottblMapMotions(motion_group, 2); mouth_frame = dw::Slider::make(motion_group); - mouth_frame->SetName("Frame"); + mouth_frame->SetText("Frame"); mouth_frame->format = "%4.0f"; mouth_frame->SetParams(0.0f, 0.0f, 100.0f, 10.0f, 1.0f, 10.0f); - //GetSetSize(); + GetSetSize(); } DataTestFaceMotDw::~DataTestFaceMotDw() { @@ -1370,9 +1370,9 @@ DataTestFaceMotDw::Data DataTestFaceMotDw::GetData() { uint32_t face_cl_mot_id = aft_mot_db->get_motion_id(face_cl_mot.c_str()); if (face_cl_mot_id != -1) - face_cl->SetName(face_cl_mot); + face_cl->SetText(face_cl_mot); else - face_cl->SetName("CLモーションなし"); + face_cl->SetText("CLモーションなし"); auto elem_eyelid = motion_id_mottbl_map.find(face_cl_mot_id); if (elem_eyelid != motion_id_mottbl_map.end()) @@ -1656,13 +1656,13 @@ DataTestMotDw::DataTestMotDw(int32_t chara_id, DtmMot* dtm_mot) { char buf[0x20]; sprintf_s(buf, sizeof(buf), "MOTION TEST %dP", chara_id + 1); - SetName(buf); + SetText(buf); dw::Composite* chara_comp = new dw::Composite(this); chara_comp->SetLayout(new dw::RowLayout(dw::HORIZONTAL)); dw::Label* chara_label = new dw::Label(chara_comp); - chara_label->SetName("CHARA "); + chara_label->SetText("CHARA "); //chara_label->SetFont(&p_dw__font_type_6x12); dw::ListBox* chara = new dw::ListBox(chara_comp); @@ -1691,7 +1691,7 @@ DataTestMotDw::DataTestMotDw(int32_t chara_id, DtmMot* dtm_mot) { set_comp->SetLayout( new dw::RowLayout(dw::HORIZONTAL)); dw::Label* set_label = new dw::Label(set_comp); - set_label->SetName("SET "); + set_label->SetText("SET "); //set_label->SetFont(&p_dw__font_type_6x12); data_struct* aft_data = &data_list[DATA_AFT]; @@ -1711,7 +1711,7 @@ DataTestMotDw::DataTestMotDw(int32_t chara_id, DtmMot* dtm_mot) { id_comp->SetLayout(new dw::RowLayout(dw::HORIZONTAL)); dw::Label* id_label = new dw::Label(id_comp); - id_label->SetName("ID "); + id_label->SetText("ID "); //id_label->SetFont(&p_dw__font_type_6x12); set_list_box_proc.list_box = new dw::ListBox(id_comp); @@ -1721,28 +1721,28 @@ DataTestMotDw::DataTestMotDw(int32_t chara_id, DtmMot* dtm_mot) { //set_list_box_proc.list_box->SetFont(&p_dw__font_type_6x12); id_list_box_proc.slider = dw::Slider::make(this); - id_list_box_proc.slider->SetName("Y ROT"); + id_list_box_proc.slider->SetText("Y ROT"); id_list_box_proc.slider->format = "%3.0f"; id_list_box_proc.slider->SetParams(test_mot_data->rot_y[chara_id], -180.0f, 180.0f, 36.0f, 1.0f, 10.0f); id_list_box_proc.slider->callback_data.i32 = chara_id; id_list_box_proc.slider->AddSelectionListener(&rotate_slider_proc); rotate_slider_proc.slider = dw::Slider::make(this); - rotate_slider_proc.slider->dw::Widget::SetName("X POS"); + rotate_slider_proc.slider->dw::Widget::SetText("X POS"); rotate_slider_proc.slider->format = "%3.2f"; rotate_slider_proc.slider->SetParams(test_mot_data->trans_x[chara_id], -2.0f, 2.0f, 0.4f, 0.01f, 0.1f); rotate_slider_proc.slider->callback_data.i32 = chara_id; rotate_slider_proc.slider->AddSelectionListener(&position_slider_proc); dw::Group* frame_group = new dw::Group(this); - frame_group->SetName("FRAME"); + frame_group->SetText("FRAME"); //frame_group->SetFont(&p_dw__font_type_6x12); for (int32_t i = 3; i < 4; i++) { step_slider = dw::Slider::make(frame_group); char buf[0x10]; sprintf_s(buf, sizeof(buf), "STEP %02d", i); - step_slider->SetName(buf); + step_slider->SetText(buf); step_slider->format = "%4.4f"; step_slider->SetParams(test_mot_data->step[chara_id].array[i], -3.0f, 3.0f, 0.4f, 0.01f, 0.1f); step_slider->callback_data.i32 = chara_id; @@ -1753,26 +1753,26 @@ DataTestMotDw::DataTestMotDw(int32_t chara_id, DtmMot* dtm_mot) { dw::Composite* frame_comp = new dw::Composite(frame_group); frame_comp->SetLayout(new dw::RowLayout(dw::HORIZONTAL)); - (new dw::Label(frame_comp))->SetName("FRAME "); + (new dw::Label(frame_comp))->SetText("FRAME "); frame = new dw::Label(frame_comp, dw::FLAG_4000); - frame->SetName("00000.0000"); + frame->SetText("00000.0000"); dw::Label* frame_separator = new dw::Label(frame_comp); - frame_separator->SetName(" / "); + frame_separator->SetText(" / "); frame_count = new dw::Label(frame_comp, dw::FLAG_4000); - frame_count->SetName("00000.0000"); + frame_count->SetText("00000.0000"); current = dw::Slider::make(frame_group); - current->SetName("Current"); + current->SetText("Current"); current->format = "%4.0f"; current->SetParams(0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f); current->callback_data.i32 = chara_id; current->AddSelectionListener(&frame_slider_proc); frame_slider_proc.slider = dw::Slider::make(frame_group); - frame_slider_proc.slider->SetName("Start "); + frame_slider_proc.slider->SetText("Start "); frame_slider_proc.slider->format = "%4.0f"; frame_slider_proc.slider->SetParams(0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f); frame_slider_proc.slider->callback_data.i32 = chara_id; @@ -1781,41 +1781,41 @@ DataTestMotDw::DataTestMotDw(int32_t chara_id, DtmMot* dtm_mot) { dw::Composite* start_ctrl_comp = new dw::Composite(frame_group); start_ctrl_comp->SetLayout(new dw::RowLayout(dw::HORIZONTAL)); - (new dw::Label(start_ctrl_comp))->SetName("Start Ctrl : "); + (new dw::Label(start_ctrl_comp))->SetText("Start Ctrl : "); dw::Button* start_ctrl_left = new dw::Button(start_ctrl_comp, dw::FLAG_8); - start_ctrl_left->SetName(" < "); + start_ctrl_left->SetText(" < "); start_ctrl_left->callback_data.v64 = this; start_ctrl_left->callback = DataTestMotDw::StartCtrlLeftRightCallback; dw::Button* start_ctrl_reset = new dw::Button(start_ctrl_comp, dw::FLAG_8); - start_ctrl_reset->SetName(" RESET "); + start_ctrl_reset->SetText(" RESET "); start_ctrl_reset->callback = DataTestMotDw::StartCtrlResetCallback; dw::Button* start_ctrl_right = new dw::Button(start_ctrl_comp, dw::FLAG_8); - start_ctrl_right->SetName(" > "); + start_ctrl_right->SetText(" > "); start_ctrl_right->callback_data.v64 = this; start_ctrl_right->callback = DataTestMotDw::StartCtrlLeftRightCallback; dw::Group* ab_loop_group = new dw::Group(this); ab_loop_group->SetLayout(new dw::RowLayout(dw::HORIZONTAL)); - ab_loop_group->SetName("AB LOOP"); + ab_loop_group->SetText("AB LOOP"); //ab_loop_group->SetFont(&p_dw__font_type_6x12); dw::Button* a_label = new dw::Button(ab_loop_group, dw::FLAG_8); - a_label->SetName(" A "); + a_label->SetText(" A "); a_label->callback_data.i64 = (int64_t)this; a_label->callback = DataTestMotDw::ACallback; //a_label->SetFont(&p_dw__font_type_6x12); dw::Button* b_label = new dw::Button(ab_loop_group, dw::FLAG_8); - b_label->SetName(" B "); + b_label->SetText(" B "); b_label->callback_data.i64 = (int64_t)this; b_label->callback = DataTestMotDw::BCallback; //b_label->SetFont(&p_dw__font_type_6x12); dw::Button* ab_toggle_button = new dw::Button(ab_loop_group, dw::CHECKBOX); - ab_toggle_button->SetName(""); + ab_toggle_button->SetText(""); ab_toggle_button->callback_data.v64 = this; ab_toggle_button->callback = DataTestMotDw::ABToggleCallback; //ab_toggle->SetFont(&p_dw__font_type_6x12); @@ -1823,20 +1823,20 @@ DataTestMotDw::DataTestMotDw(int32_t chara_id, DtmMot* dtm_mot) { ab_loop = new dw::Label(ab_loop_group, dw::FLAG_8); //ab_loop->SetFont(&p_dw__font_type_6x12); - ab_loop->SetName(" 00000:00000"); + ab_loop->SetText(" 00000:00000"); dw::Composite* rob_comp = new dw::Composite(this); rob_comp->SetLayout(new dw::RowLayout(dw::HORIZONTAL)); dw::Button* disp_button = new dw::Button(rob_comp, dw::CHECKBOX); - disp_button->SetName("DISP "); + disp_button->SetText("DISP "); disp_button->SetValue(true); disp_button->AddSelectionListener(&disp_button_proc); disp_button->callback_data.i32 = chara_id; //disp_button->SetFont(&p_dw__font_type_6x12); disp_button_proc.button = new dw::Button(rob_comp, dw::CHECKBOX); - disp_button_proc.button->SetName("SET CHANGE "); + disp_button_proc.button->SetText("SET CHANGE "); disp_button_proc.button->SetValue(false); //disp_button_proc.button->SetFont(&p_dw__font_type_6x12); @@ -1844,23 +1844,23 @@ DataTestMotDw::DataTestMotDw(int32_t chara_id, DtmMot* dtm_mot) { var_comp->Composite::SetLayout(new dw::RowLayout(dw::HORIZONTAL)); dw::Button* reate_face_mot_dw = new dw::Button(var_comp, dw::FLAG_8); - reate_face_mot_dw->SetName(" FACE MOT "); + reate_face_mot_dw->SetText(" FACE MOT "); reate_face_mot_dw->AddSelectionListener(&create_face_mot_dw_proc); reate_face_mot_dw->callback_data.i32 = chara_id; //reate_face_mot_dw->SetFont(&p_dw__font_type_6x12); dw::Button* create_eq_dw = new dw::Button(var_comp, dw::FLAG_8); - create_eq_dw->SetName(" EQUIP "); + create_eq_dw->SetText(" EQUIP "); create_eq_dw->AddSelectionListener(&create_eq_dw_proc); //create_eq_dw->SetFont(&p_dw__font_type_6x12); dw::Button* create_debug_cam = new dw::Button(var_comp, dw::FLAG_8); - create_debug_cam->SetName(" LOCK CAM "); + create_debug_cam->SetText(" LOCK CAM "); create_debug_cam->AddSelectionListener(&create_debug_cam_proc); //create_debug_cam->SetFont(&p_dw__font_type_6x12); dw::Button* use_opd_button = new dw::Button(this, dw::CHECKBOX); - use_opd_button->SetName("USE OSAGE PLAY DATA"); + use_opd_button->SetText("USE OSAGE PLAY DATA"); use_opd_button->SetValue(false); use_opd_button->AddSelectionListener(&use_opd_button_proc); use_opd_button->callback_data.i32 = chara_id; @@ -1869,13 +1869,13 @@ DataTestMotDw::DataTestMotDw(int32_t chara_id, DtmMot* dtm_mot) { dtm_mot->SetPartialMot(false); dw::Button* save_only_start_frame_button = new dw::Button(this, dw::CHECKBOX); - save_only_start_frame_button->SetName("Initialize only Start Frame Osage"); + save_only_start_frame_button->SetText("Initialize only Start Frame Osage"); save_only_start_frame_button->SetValue(false); save_only_start_frame_button->AddSelectionListener(&save_only_start_frame_button_proc); save_only_start_frame_button->callback_data.i32 = chara_id; //save_only_start_frame_button->SetFont(&p_dw__font_type_6x12); - //GetSetSize(); + GetSetSize(); } DataTestMotDw::~DataTestMotDw() { @@ -1891,7 +1891,7 @@ void DataTestMotDw::Draw() { char buf[0x20]; sprintf_s(buf, sizeof(buf), " %5d:%5d", (int32_t)roundf(a_frame), (int32_t)roundf(b_frame)); - this->ab_loop->SetName(buf); + this->ab_loop->SetText(buf); dw::Shell::Draw(); } @@ -1925,10 +1925,10 @@ void DataTestMotDw::SetFrameSlider(float_t frame, float_t frame_count) { void DataTestMotDw::SetFrameLabel(float_t frame, float_t frame_count) { char buf[0x40]; sprintf_s(buf, sizeof(buf), "%10.4f", frame); - this->frame->SetName(buf); + this->frame->SetText(buf); sprintf_s(buf, sizeof(buf), "%7.1f", frame_count); - this->frame_count->SetName(buf); + this->frame_count->SetText(buf); } void DataTestMotDw::AddModules(int32_t chara_id, dw::ListBox* list_box) { @@ -1975,7 +1975,7 @@ void DataTestMotDw::ResetFrame() { } void DataTestMotDw::ResetIDListBoxIndex() { - //GetSetSize(); + GetSetSize(); set_list_box_proc.list_box->SetItemIndex(0); } @@ -2046,7 +2046,7 @@ void DataTestMotDw::StartCtrlLeftRightCallback(dw::Widget* data) { if (frame > set_motion.back().frame_stage_index.first) last = set_motion.back().frame_stage_index.first; - if (button->GetName().compare(" < ")) + if (button->GetText().compare(" < ")) test_mot_dw->frame_slider_proc.slider->SetValue(last); else if (first > 0.0f) test_mot_dw->frame_slider_proc.slider->SetValue(first); @@ -2069,7 +2069,7 @@ void DataTestMotA3dDw::PvListBoxProc::Callback(dw::Widget* data) { if (list_box) data_test_mot_a3d_dw->SetPvId(atoi(list_box->GetSelectedItem().c_str())); - //data_test_mot_a3d_dw->GetSetSize(); + data_test_mot_a3d_dw->GetSetSize(); } DataTestMotA3dDw::A3dListBoxProc::A3dListBoxProc() { @@ -2132,13 +2132,13 @@ void DataTestMotCtrlDw::GameCameraButtonProc::Callback(dw::Widget* data) { } DataTestMotA3dDw::DataTestMotA3dDw() { - SetName("MOTION TEST"); + SetText("MOTION TEST"); dw::Composite* pv_comp = new dw::Composite(this); pv_comp->SetLayout(new dw::RowLayout(dw::HORIZONTAL)); dw::Label* pv_label = new dw::Label(pv_comp); - pv_label->SetName("PV"); + pv_label->SetText("PV"); //pv_label->SetFont(&p_dw__font_type_6x12); pv = new dw::ListBox(pv_comp); @@ -2160,7 +2160,7 @@ DataTestMotA3dDw::DataTestMotA3dDw() { a3d_comp->SetLayout(new dw::RowLayout(dw::HORIZONTAL)); dw::Label* a3d_label = new dw::Label(a3d_comp); - a3d_label->SetName("A3d"); + a3d_label->SetText("A3d"); //a3d_label->SetFont(&p_dw__font_type_6x12); a3d = new dw::ListBox(a3d_comp); @@ -2175,23 +2175,23 @@ DataTestMotA3dDw::DataTestMotA3dDw() { button_comp->SetLayout(new dw::RowLayout(dw::HORIZONTAL)); play_a3d = new dw::Button(button_comp, dw::FLAG_8); - play_a3d->SetName(" PLAY A3D "); + play_a3d->SetText(" PLAY A3D "); play_a3d->callback_data.v64 = this; play_a3d->callback = DataTestMotA3dDw::PlayA3dCallback; //play_a3d->SetFont(&p_dw__font_type_6x12); sync_1p_frame = new dw::Button(button_comp, dw::CHECKBOX); - sync_1p_frame->SetName("SYNC 1P FRAME"); + sync_1p_frame->SetText("SYNC 1P FRAME"); sync_1p_frame->callback_data.v64 = this; sync_1p_frame->callback = DataTestMotA3dDw::Sync1pFrameCallback; //sync_1p_frame->SetFont(&p_dw__font_type_6x12); - /*GetSetSize(); + GetSetSize(); - position.x = (float_t)res_window_get()->width * 0.3f - size.x * 0.3f; + rect.pos.x = (float_t)res_window_get()->width * 0.3f - rect.size.x * 0.3f; - SetSize(size);*/ + SetSize(rect.size); } DataTestMotA3dDw::~DataTestMotA3dDw() { @@ -2199,7 +2199,7 @@ DataTestMotA3dDw::~DataTestMotA3dDw() { } void DataTestMotA3dDw::Draw() { - SetName(data_test_mot_a3d_get_state_text()); + SetText(data_test_mot_a3d_get_state_text()); } void DataTestMotA3dDw::Hide() { @@ -2253,7 +2253,7 @@ void DataTestMotA3dDw::Sync1pFrameCallback(dw::Widget* data) { DataTestMotCtrlDw::DataTestMotCtrlDw() { DataTestMot::Data* test_mot_data = data_test_mot_data_get(); - SetName("MOTION TEST"); + SetText("MOTION TEST"); type_list = new dw::ListBox(this); type_list->AddItem("ONCE"); @@ -2263,40 +2263,40 @@ DataTestMotCtrlDw::DataTestMotCtrlDw() { type_list->AddSelectionListener(&type_list_box_proc); reset_mot = new dw::Button(this, dw::FLAG_8); - reset_mot->SetName("RESET MOT"); + reset_mot->SetText("RESET MOT"); reset_mot->callback_data.v64 = this; reset_mot->callback = DataTestMotCtrlDw::ResetMotCallback; reset_cam = new dw::Button(this, dw::FLAG_8); - reset_cam->SetName("RESET CAM"); + reset_cam->SetText("RESET CAM"); reset_cam->callback_data.v64 = this; reset_cam->callback = DataTestMotCtrlDw::ResetCamCallback; reload_data = new dw::Button(this, dw::FLAG_8); - reload_data->SetName("RELOAD DATA"); + reload_data->SetText("RELOAD DATA"); reload_data->callback_data.v64 = this; reload_data->callback = DataTestMotCtrlDw::ReloadDataCallback; dw::Button* sync_frame_button = new dw::Button(this, dw::CHECKBOX); - sync_frame_button->SetName("SYNC FRAME"); + sync_frame_button->SetText("SYNC FRAME"); sync_frame_button->AddSelectionListener(&sync_frame_button_proc); //sync_frame_button->SetFont(&p_dw__font_type_6x12); running = new dw::Button(this, dw::CHECKBOX); - running->SetName("RUNNING"); + running->SetText("RUNNING"); running->SetValue(false); running->callback = DataTestMotCtrlDw::RunningCallback; //running->SetFont(&p_dw__font_type_6x12); stage = new dw::Button(this, dw::FLAG_8); - stage->SetName("STAGE"); + stage->SetText("STAGE"); stage->callback = DataTestMotCtrlDw::StageCallback; - /*GetSetSize(); + GetSetSize(); - position.x = (float_t)res_window_get()->width - size.x; + rect.pos.x = (float_t)res_window_get()->width - rect.size.x; - SetSize(size);*/ + SetSize(rect.size); } DataTestMotCtrlDw::~DataTestMotCtrlDw() { @@ -2431,12 +2431,12 @@ static void data_test_mot_dw_array_init(int32_t chara_id, DtmMot* dtm_mot) { switch (chara_id) { case 0: { - test_mot_dw->position.y += 14.0f; + test_mot_dw->rect.pos.y += 14.0f; } break; case 1: { resolution_struct* res_wind = res_window_get(); - test_mot_dw->position.x = (float_t)res_wind->width - test_mot_dw->size.x; - test_mot_dw->position.y = (float_t)res_wind->height - 24.0f; + test_mot_dw->rect.pos.x = (float_t)res_wind->width - test_mot_dw->rect.size.x; + test_mot_dw->rect.pos.y = (float_t)res_wind->height - 24.0f; } break; } } diff --git a/src/ReDIVA/data_test/stage_test.cpp b/src/ReDIVA/data_test/stage_test.cpp index d2e71164..f309a115 100644 --- a/src/ReDIVA/data_test/stage_test.cpp +++ b/src/ReDIVA/data_test/stage_test.cpp @@ -74,37 +74,30 @@ DtwStg::DtwStg() : Shell(0) { std::vector& stg_data = aft_stage_data->stage_data; - position = { 0.0f, 0.0f }; - size = { 250.0f, 240.0f }; - - dw::Widget::SetName("STAGE TEST"); + dw::Widget::SetText("STAGE TEST"); dw::Composite* pv_comp = new dw::Composite(this); pv_comp->SetLayout(new dw::RowLayout(dw::HORIZONTAL)); - (new dw::Label(pv_comp, dw::LABEL_SIZE))->SetName("PV:"); + (new dw::Label(pv_comp, dw::LABEL_SIZE))->SetText("PV:"); pv_id = new dw::ListBox(pv_comp); - pv_id->SetSize({ 48.0f, 0.0f }); pv = new dw::ListBox(pv_comp); - pv->SetSize({ 160.0f, 0.0f }); dw::Composite* ns_comp = new dw::Composite(this); ns_comp->SetLayout(new dw::RowLayout(dw::HORIZONTAL)); - (new dw::Label(ns_comp, dw::LABEL_SIZE))->SetName("NS:"); + (new dw::Label(ns_comp, dw::LABEL_SIZE))->SetText("NS:"); ns = new dw::ListBox(ns_comp); - ns->SetSize({ 160.0f, 0.0f }); dw::Composite* other_comp = new dw::Composite(this); other_comp->SetLayout(new dw::RowLayout(dw::HORIZONTAL)); - (new dw::Label(other_comp, dw::LABEL_SIZE))->SetName("Other:"); + (new dw::Label(other_comp, dw::LABEL_SIZE))->SetText("Other:"); other = new dw::ListBox(other_comp); - other->SetSize({ 160.0f, 0.0f }); stage = new dw::ListBox(this); @@ -140,34 +133,34 @@ DtwStg::DtwStg() : Shell(0) { pv->AddSelectionListener(new dw::SelectionListenerOnHook(DtwStg::StageCallback)); //dw::List::sub_1402F9930(this->ns->list, 30); - ns->list->SetItemIndex(0); + ns->SetItemIndex(0); ns->AddSelectionListener(new dw::SelectionListenerOnHook(DtwStg::StageCallback)); //dw::List::sub_1402F9930(this->stage->list, 30); - stage->list->SetItemIndex(0); + stage->SetItemIndex(0); stage->AddSelectionListener(new dw::SelectionListenerOnHook(DtwStg::StageCallback)); stage_display = new dw::Button(this, dw::CHECKBOX); - stage_display->SetName("Stage display"); + stage_display->SetText("Stage display"); stage_display->SetValue(true); ring = new dw::Button(this, dw::CHECKBOX); - ring->SetName("[Ring]"); + ring->SetText("[Ring]"); ring->SetValue(true); ground = new dw::Button(this, dw::CHECKBOX); - ground->SetName("[Ground]"); + ground->SetText("[Ground]"); ground->SetValue(true); sky = new dw::Button(this, dw::CHECKBOX); - sky->SetName("[Sky]"); + sky->SetText("[Sky]"); sky->SetValue(true); effect_display = new dw::Button(this, dw::CHECKBOX); - effect_display->SetName("Effects display"); + effect_display->SetText("Effects display"); effect_display->SetValue(true); - //GetSetSize(); + GetSetSize(); } DtwStg::~DtwStg() { @@ -189,9 +182,11 @@ void DtwStg::PvIdCallback(dw::Widget* data) { dw::ListBox* pv_list_box = dtw_stg->pv; pv_list_box->ClearItems(); auto elem = dtw_stg->pv_stage.find(name); - if (elem != dtw_stg->pv_stage.end()) + if (elem != dtw_stg->pv_stage.end()) { for (std::string& i : elem->second) pv_list_box->AddItem(i); + dtw_stg->GetSetSize(); + } } } diff --git a/src/ReDIVA/dw.cpp b/src/ReDIVA/dw.cpp index ce8ccc2c..08ad3829 100644 --- a/src/ReDIVA/dw.cpp +++ b/src/ReDIVA/dw.cpp @@ -170,7 +170,7 @@ namespace dw { DropDownListScrollBarSelectionListener::DropDownListScrollBarSelectionListener() { } - + DropDownListScrollBarSelectionListener::~DropDownListScrollBarSelectionListener() { } @@ -178,11 +178,11 @@ namespace dw { void DropDownListScrollBarSelectionListener::Callback(Widget* data) { } - + ScrollBarTestSelectionListener::ScrollBarTestSelectionListener() { } - + ScrollBarTestSelectionListener::~ScrollBarTestSelectionListener() { } @@ -197,7 +197,7 @@ namespace dw { } Widget::~Widget() { - + Free(); } void Widget::Draw() { @@ -205,27 +205,27 @@ namespace dw { } void Widget::Reset() { - name.clear(); + text.clear(); } - std::string Widget::GetName() { - return name; + std::string Widget::GetText() { + return text; } - void Widget::SetName(std::string& str) { - name.assign(str); + void Widget::SetText(std::string& str) { + text.assign(str); if (flags & LABEL_SIZE) { - ImVec2 size = ImGui::CalcTextSize(name.c_str(), 0, true); - this->size = { size.x, size.y }; + ImVec2 size = ImGui::CalcTextSize(text.c_str(), 0, true); + rect.size = { size.x, size.y }; } } void Widget::SetSize(vec2 value) { - size = value; + rect.size = value; } vec2 Widget::GetPos() { - return position; + return rect.pos; } void Widget::Free() { @@ -233,25 +233,31 @@ namespace dw { return; Reset(); + if (free_callback) free_callback(this); - free = 1; + + free = true; if (dw_gui_detail_display) dw_gui_detail_display->free_widgets.push_back(this); } - void Widget::SetName(std::string&& str) { - SetName(str); + rectangle Widget::GetRectangle() { + return { GetPos(), rect.size }; + } + + void Widget::SetText(std::string&& str) { + SetText(str); } void Widget::UpdateDraw() { - //sub_140302800(qword_1411900C8); + //print->sub_140302800(); Draw(); } Control::Control(Composite* parent, Flags flags) : Widget(parent, flags), - parent_comp(), parent_shell()/*, parent_menu()*/{ + parent_comp(), parent_shell()/*, parent_menu()*/ { parent_comp = parent; if (parent) { parent->controls.push_back(this); @@ -272,12 +278,11 @@ namespace dw { Widget::Reset(); } - vec2 dw::Control::GetPos() { - vec2 pos = position; + vec2 Control::GetPos() { + vec2 pos = rect.pos; if (parent_comp) { - rectangle parent_rect = parent_comp->GetBoundingBox(); - vec2 parent_pos = parent_comp->GetPos(); - pos += parent_pos + parent_rect.pos; + rectangle parent_comp_bb = parent_comp->GetBoundingBox(); + pos += parent_comp->GetPos() + parent_comp_bb.pos; if (parent_comp->v_bar) pos.y -= parent_comp->v_bar->value; } @@ -289,7 +294,7 @@ namespace dw { } vec2 Control::GetSize() { - return size; + return rect.size; } Label::Label(Composite* parent, Flags flags) : Control(parent, flags) { @@ -301,14 +306,44 @@ namespace dw { } void Label::Draw() { - ImGui::PushID(this); - if (size != 0.0f) - ImGui::Text(name.c_str()); + rectangle rect = GetRectangle(); + //print->SetFont(font); + //vec2 text_size = print->GetTextSize(name); + ImVec2 _text_size = ImGui::CalcTextSize(text.c_str()); + vec2 text_size(_text_size.x, _text_size.y); + + vec2 pos; + if (flags & FLAG_4000) + pos.x = rect.pos.x; + else if (flags & FLAG_20000) + pos.x = rect.pos.x + rect.size.x - text_size.x; else - ImGui::TextCentered(name.c_str()); + pos.x = rect.pos.x + (rect.size.x - text_size.x) * 0.5f; + pos.y = rect.pos.y + (rect.size.y - text_size.y) * 0.5f; + + /*print->SetColor(Field_A0() + ? dw_gui_colors_current.foreground + : &dw_gui_colors_current.disable_foreground); + print->sub_1403027C0(rect); + print->SetFont(font); + print->PrintText(name, pos.x, pos.y);*/ + + mat4_mult_vec2(&mat4_identity, &pos, &pos); + + ImGui::PushID(this); + ImGui::SetCursorPosX(ImGui::GetCursorPosX() + (pos.x - rect.pos.x)); + ImGui::Text(text.c_str()); ImGui::PopID(); } + vec2 Label::GetSize() { + //sub_140302810(qword_1411900C8, &font); + //vec2 size = sub_140302A70(qword_1411900C8, text); + ImVec2 _size = ImGui::CalcTextSize(text.c_str(), 0, true); + vec2 size(_size.x, _size.y); + return size + 2.0f * 2.0f; + } + ScrollBar::ScrollBar(Control* parent, Flags flags) : Widget(parent, flags), value(), min(), field_A0(), field_A5(), field_A6() { field_68 = parent; @@ -328,8 +363,17 @@ namespace dw { } - void ScrollBar::SetSize(vec2 value) { - size = value; + void ScrollBar::SetSize(vec2 size) { + if (flags & HORIZONTAL) { + rect.size.x = size.x; + //rect.size.y = font->GetFontGlyphHeight(); + rect.size.y = ImGui::CalcEmptyGlyphHeight(); + } + else { + //rect.size.x = font->GetFontGlyphWidth(); + rect.size.x = ImGui::CalcEmptyGlyphHeight(); + rect.size.y = size.y; + } } void ScrollBar::SetParams(float_t value, float_t min, @@ -342,6 +386,46 @@ namespace dw { this->step = step; } + void ScrollBar::SetParams(float_t size, float_t step, size_t items_count) { + if (!items_count) + return; + + float_t v5 = (float_t)(int64_t)items_count; + if (v5 < 0.0f) + v5 += (float_t)UINT64_MAX; + + float_t v6 = v5 * step; + if (v6 > size) { + min = 0.0f; + max = v6 - size; + field_94 = (size / v6) * (v6 - size); + dw::ScrollBar::SetValue(value); + this->step = step; + + int64_t v8 = 0; + float_t v9 = size / step; + if (v9 >= INT64_MAX) { + v9 -= INT64_MAX; + if (v9 < INT64_MAX) + v8 = INT64_MIN; + } + + int64_t v10 = (int64_t)v9; + float_t v11 = (float_t)(v8 + v10); + if (v11 < 0.0f) + v11 += UINT64_MAX; + step_fast = v11 * step; + } + else { + min = 0.0f; + max = 0.0f; + field_94 = v6; + SetValue(value); + this->step = step; + step_fast = v6; + } + } + void ScrollBar::SetValue(float_t value) { value = clamp_def(value, min, max); if (round) @@ -353,12 +437,12 @@ namespace dw { void ScrollBar::SetWidth(float_t value) { vec2 glyph_size = value;//font->GetFontGlyphSize(); if (flags & HORIZONTAL) { - size.x = value; - size.y = glyph_size.y; + rect.size.x = value; + rect.size.y = glyph_size.y; } else { - size.x = glyph_size.x; - size.y = value; + rect.size.x = glyph_size.x; + rect.size.y = value; } } @@ -369,12 +453,12 @@ namespace dw { Scrollable::Scrollable(Composite* parent, Flags flags) : Control(parent, flags), h_bar(), v_bar() { if (flags & HORIZONTAL) { h_bar = new ScrollBar(parent, HORIZONTAL); - h_bar->SetName("h_bar"); + h_bar->SetText("h_bar"); } if (flags & VERTICAL) { v_bar = new ScrollBar(parent, VERTICAL); - v_bar->SetName("v_bar"); + v_bar->SetText("v_bar"); } } @@ -388,6 +472,16 @@ namespace dw { } void Scrollable::Reset() { + if (h_bar) { + h_bar->Free(); + h_bar = 0; + } + + if (v_bar) { + v_bar->Free(); + v_bar = 0; + } + Control::Reset(); } @@ -400,26 +494,23 @@ namespace dw { } if (v_bar) { - v_bar->position.x = value.x - v_bar->size.x; - v_bar->position.y = 0.0f; + v_bar->rect.pos.x = value.x - v_bar->rect.size.x; + v_bar->rect.pos.y = 0.0f; v_bar->SetWidth(value.y); } } rectangle Scrollable::GetBoundingBox() { rectangle rect; - rect.size.x = size.x; - rect.size.y = size.y; + rect.size = this->rect.size; if (flags & FLAG_800) { - rect.pos.x = 2.0f; - rect.pos.y = 2.0f; - rect.size.x = size.x - 2.0f * 2.0f; - rect.size.y = size.y - 2.0f * 2.0f; + rect.pos = 2.0f; + rect.size -= 2.0f * 2.0f; } if (v_bar) - rect.size.x -= v_bar->size.x; + rect.size.x -= v_bar->rect.size.x; return rect; } @@ -431,8 +522,8 @@ namespace dw { } - FillLayout::FillLayout(int32_t a2) { - field_8 = a2; + FillLayout::FillLayout(Flags flags) { + this->flags = flags; } FillLayout::~FillLayout() { @@ -440,15 +531,58 @@ namespace dw { } vec2 FillLayout::GetSize(Composite* comp) { - return comp->size; + if (!comp->controls.size()) + { + vec2 size = comp->rect.size; + if (comp->v_bar) + size.x += comp->v_bar->rect.size.x; + return size; + } + + vec2 size = 0.0f; + if (flags == VERTICAL) + for (Control* i : comp->controls) { + vec2 _size = i->GetSize(); + size.x = max_def(_size.x, size.x); + } + else + for (Control* i : comp->controls) { + vec2 _size = i->GetSize(); + size.y = max_def(_size.y, size.y); + } + + if (comp->v_bar) + size.x += comp->v_bar->rect.size.x; + return size; } void FillLayout::SetSize(Composite* comp) { - const vec2 position = comp->position; - const vec2 size = comp->size; - for (Control* i : comp->controls) { - i->position = position; - i->SetSize(size); + rectangle comp_bb = comp->GetBoundingBox(); + vec2 comp_bb_size = comp_bb.size; + if (!comp->controls.size()) + return; + + float_t size = (float_t)(int64_t)comp->controls.size(); + if (size < 0.0f) + size += (float_t)UINT64_MAX; + + if (flags == VERTICAL) { + float_t pos = 0.0f; + size = comp_bb_size.y / size; + for (Control* i : comp->controls) { + i->rect.pos = { 0.0f, pos }; + i->SetSize({ comp_bb_size.x, size }); + pos += size; + } + } + else { + float_t pos = 0.0f; + size = comp_bb_size.x / size; + for (Control* i : comp->controls) { + i->rect.pos = { pos, 0.0f }; + i->SetSize({ size, comp_bb_size.y }); + pos += size; + } } } @@ -464,8 +598,8 @@ namespace dw { } - GraphLayout::GraphLayout(int32_t a2) { - field_8 = a2; + GraphLayout::GraphLayout(Flags flags) { + this->flags = flags; } GraphLayout::~GraphLayout() { @@ -473,15 +607,14 @@ namespace dw { } vec2 GraphLayout::GetSize(Composite* comp) { - return comp->size; + return comp->rect.size; } void GraphLayout::SetSize(Composite* comp) { - const vec2 position = comp->position; - const vec2 size = comp->size; + const rectangle rect = comp->rect; for (Control* i : comp->controls) { - i->position = position; - i->SetSize(size); + i->rect.pos = rect.pos; + i->SetSize(rect.size); } } @@ -497,11 +630,9 @@ namespace dw { } - GridLayout::GridLayout(size_t a2) : field_8(), field_10(), - field_18(), field_20(), field_28(), field_30(), field_38() { - field_40 = a2; - field_48 = 2.0f; - field_4C = 2.0f; + GridLayout::GridLayout(size_t columns) : rows() { + this->columns = columns; + spacing = 2.0f; } GridLayout::~GridLayout() { @@ -509,15 +640,83 @@ namespace dw { } vec2 GridLayout::GetSize(Composite* comp) { - return comp->size; + std::vector& controls = comp->controls; + size_t controls_count = controls.size(); + if (!controls_count) { + vec2 size = comp->rect.size; + if (comp->v_bar) + size.x += comp->v_bar->rect.size.x; + return size; + } + + rows = (controls_count + columns - 1) / columns; + rows = rows ? rows : 1; + + column_size.resize(columns); + row_size.resize(rows); + + size_t control = 0; + for (size_t row = 0; row < rows && control < controls_count; row++) + for (size_t column = 0; column < columns && control < controls_count; column++, control++) { + vec2 size = controls.data()[control]->GetSize(); + column_size.data()[column] = max_def(size.x, column_size.data()[column]); + row_size.data()[row] = max_def(size.y, row_size.data()[row]); + } + + vec2 size; + size.x = (float_t)(int64_t)(columns - 1); + if (size.x < 0.0f) + size.x += (float_t)UINT64_MAX; + + size.y = (float_t)(int64_t)(rows - 1); + if (size.y < 0.0f) + size.y += (float_t)UINT64_MAX; + + size *= spacing; + + float_t size_x = size.x; + for (float_t i : column_size) + size_x += i; + size.x = size_x; + + float_t size_y = size.y; + for (float_t i : row_size) + size_y += i; + size.y = size_y; + + if (comp->v_bar) + size.x += comp->v_bar->rect.size.x; + return size; } void GridLayout::SetSize(Composite* comp) { - const vec2 position = comp->position; - const vec2 size = comp->size; - for (Control* i : comp->controls) { - i->position = position; - i->SetSize(size); + std::vector& controls = comp->controls; + size_t controls_count = controls.size(); + + rectangle comp_bb = comp->GetBoundingBox(); + vec2 comp_bb_size = comp_bb.size; + if (!controls_count) + return; + + if (controls_count == 1) { + Scrollable* scrollable = dynamic_cast(comp->controls.front()); + if (scrollable) { + scrollable->rect.pos = 0.0f; + scrollable->SetSize(comp_bb.size); + return; + } + } + + size_t control = 0; + vec2 pos = 0.0f; + for (size_t row = 0; row < rows && control < controls_count; row++) { + vec2 _pos = pos; + for (size_t column = 0; column < columns && control < controls_count; column++, control++) { + comp->controls.data()[control]->rect.pos = _pos; + comp->controls.data()[control]->SetSize({ column_size.data()[column], row_size.data()[row] }); + _pos.x += column_size.data()[column] + spacing.x; + } + pos.y += row_size.data()[row] + spacing.y; } } @@ -544,16 +743,66 @@ namespace dw { } vec2 RowLayout::GetSize(Composite* comp) { - return comp->size; + if (!comp->controls.size()) { + vec2 size = comp->rect.size; + if (comp->v_bar) + size.x += comp->v_bar->rect.size.x; + return size; + } + + vec2 size = 0.0f; + if (flags == VERTICAL) { + for (Control* i : comp->controls) { + vec2 _size = i->GetSize(); + size.x = max_def(_size.x, size.x); + size.y += _size.y + spacing; + } + size.y -= spacing; + } + else { + for (Control* i : comp->controls) { + vec2 _size = i->GetSize(); + size.x += _size.x + spacing; + size.y = max_def(_size.y, size.y); + } + size.x -= spacing; + } + + if (comp->v_bar) + size.x += comp->v_bar->rect.size.x; + return size; } void RowLayout::SetSize(Composite* comp) { - const vec2 position = comp->position; - const vec2 size = comp->size; - for (Control* i : comp->controls) { - i->position = position; - i->SetSize(size); + rectangle comp_bb = comp->GetBoundingBox(); + vec2 comp_bb_size = comp_bb.size; + if (!comp->controls.size()) + return; + + if (comp->controls.size() == 1) { + Scrollable* scrollable = dynamic_cast(comp->controls.front()); + if (scrollable) { + scrollable->rect.pos = 0.0f; + scrollable->SetSize(comp_bb.size); + return; + } } + + float_t pos = 0.0f; + if (flags == VERTICAL) + for (Control*& i : comp->controls) { + i->rect.pos = { 0.0f, pos }; + float_t size_y = i->GetSize().y; + i->SetSize({ comp_bb_size.x, size_y }); + pos += size_y + spacing; + } + else + for (Control*& i : comp->controls) { + i->rect.pos = { pos, 0.0f }; + float_t size_x = i->GetSize().x; + i->SetSize({ size_x, comp_bb_size.y }); + pos += size_x + spacing; + } } void RowLayout::Begin() { @@ -603,9 +852,9 @@ namespace dw { layout->Begin(); for (Control*& i : controls) { - if (i->size != 0.0f) - ImGui::SetNextItemWidth(i->size.x); - i->Draw(); + if (i->rect.size != 0.0f) + ImGui::SetNextItemWidth(i->rect.size.x); + i->UpdateDraw(); if (layout) layout->Next(); } @@ -616,10 +865,10 @@ namespace dw { } void Composite::Reset() { - //for (Control* i : controls) - //Widget::sub_1402ECDE0(i); - + for (Control*& i : controls) + i->Free(); controls.clear(); + Scrollable::Reset(); } @@ -653,7 +902,7 @@ namespace dw { } Button::Button(Composite* parent, Flags flags) : Control(parent, flags), value(), callback() { - + GetSetSize(); } Button::~Button() { @@ -663,22 +912,65 @@ namespace dw { void Button::Draw() { ImGui::PushID(this); if (flags & CHECKBOX) { - if (ImGui::Checkbox(name.c_str(), &value) && callback) - callback(this); + bool value = this->value; + if (ImGui::Checkbox(text.c_str(), &value)) { + SetValue(value); + if (callback) + callback(this); + } } else if (flags & RADIOBUTTON) { - if (ImGui::RadioButton(name.c_str(), value)) { + if (ImGui::RadioButton(text.c_str(), value)) { + SetValue(value); + if (callback) + callback(this); + } + } + else { + if (ImGui::Button(text.c_str())) { if (callback) callback(this); - value = true; } } - else - if (ImGui::Button(name.c_str()) && callback) - callback(this); ImGui::PopID(); } + vec2 Button::GetSize() { + //print->SetFont(font); + //vec2 size = print->GetTextSize(text); + ImVec2 _size = ImGui::CalcTextSize(text.c_str(), 0, true); + vec2 size = vec2(_size.x, _size.y); + + if (flags & FLAG_8) { + size.x += 2.0f; + size.x += 2.0f * 2.0f; + size.y += 2.0f * 2.0f; + } + else if (flags & RADIOBUTTON) { + /*print->SetFont(font); + std::string text("(X)"); + vec2 size = print->GetTextSize(text); + ImVec2 _size = ImGui::CalcTextSize(text.c_str(), 0, true); + vec2 radiobutton_size = vec2(_size.x, _size.y); + size.x += radiobutton_size.x*/ + + ImGuiStyle& style = ImGui::GetCurrentContext()->Style; + size.x += ImGui::GetFrameHeight() + style.ItemInnerSpacing.x; + } + else if (flags & CHECKBOX) { + /*print->SetFont(font); + std::string text("[X]"); + vec2 size = print->GetTextSize(text); + ImVec2 _size = ImGui::CalcTextSize(text.c_str(), 0, true); + vec2 checkbox_size = vec2(_size.x, _size.y); + size.x += checkbox_size.x*/ + + ImGuiStyle& style = ImGui::GetCurrentContext()->Style; + size.x += ImGui::GetFrameHeight() + style.ItemInnerSpacing.x; + } + return size; + } + void Button::AddSelectionListener(SelectionListener* value) { selection_listeners.push_back(value); } @@ -697,7 +989,7 @@ namespace dw { ShellCloseButton::ShellCloseButton(Shell* parent) : Button(parent) { SetSize({ 14.0f, 14.0f }); - SetName("Close Box"); + SetText("Close Box"); callback = Callback; //field_100 = 0; //field_104 = 4; @@ -743,13 +1035,13 @@ namespace dw { if (!GetDisp()) return; - ImGui::SetNextWindowPos({ position.x, position.y }, ImGuiCond_Appearing); - if (size != 0.0f) - ImGui::SetNextWindowSize({ size.x, size.y }, ImGuiCond_Appearing); + ImGui::SetNextWindowPos({ rect.pos.x, rect.pos.y }, ImGuiCond_Appearing); + if (rect.size != 0.0f) + ImGui::SetNextWindowSize({ rect.size.x, rect.size.y }, ImGuiCond_Appearing); bool open = true; ImGui::PushID(this); - if (ImGui::Begin(name.c_str(), close_button ? &open : 0)) + if (ImGui::Begin(text.c_str(), close_button ? &open : 0)) Composite::Draw(); input_locked |= ImGui::IsWindowFocused(); ImGui::End(); @@ -798,20 +1090,20 @@ namespace dw { destroy = true; } - void dw::Shell::SetSize(vec2 size) { - dw::Widget::SetSize(size); + void Shell::SetSize(vec2 size) { + Widget::SetSize(size); if (flags & CHECKBOX) { if (close_button) { vec2 size = close_button->GetSize(); - close_button->position.x = this->size.x - size.x + 2.0f; - close_button->position.y = 2.0f; + close_button->rect.pos.x = rect.size.x - size.x + 2.0f; + close_button->rect.pos.y = 2.0f; } } rectangle bounding_box = GetBoundingBox(); if (v_bar) { - v_bar->position.x = bounding_box.pos.x + bounding_box.size.x - v_bar->size.x; - v_bar->position.y = bounding_box.pos.y; + v_bar->rect.pos.x = bounding_box.pos.x + bounding_box.size.x - v_bar->rect.size.x; + v_bar->rect.pos.y = bounding_box.pos.y; v_bar->SetWidth(bounding_box.size.y); } @@ -819,11 +1111,11 @@ namespace dw { } vec2 Shell::GetPos() { - return position; + return rect.pos; } vec2 Shell::GetSize() { - vec2 size = dw::Composite::GetSize(); + vec2 size = Composite::GetSize(); size.x += 2.0f * 2.0f; size.y += 2.0f * 2.0f; /*if (flags & CHECKBOX) @@ -831,12 +1123,10 @@ namespace dw { return size; } - rectangle dw::Shell::GetBoundingBox() { + rectangle Shell::GetBoundingBox() { rectangle rect; - rect.pos.x = 2.0; - rect.pos.y = 2.0; - rect.size.x = size.x - 2.0f * 2.0f; - rect.size.y = size.y - 2.0f * 2.0f; + rect.pos = 2.0f; + rect.size = this->rect.size - 2.0f * 2.0f; /*if (flags & CHECKBOX) { rect.size.y -= p_dw__font_type_8x16_0_get_font_glyph_height() + 2.0f; @@ -844,7 +1134,7 @@ namespace dw { }*/ if (v_bar) - rect.size.x -= v_bar->size.x; + rect.size.x -= v_bar->rect.size.x; return rect; } @@ -901,6 +1191,39 @@ namespace dw { Scrollable::Reset(); } + void List::SetSize(vec2 size) { + Scrollable::SetSize(size); + SetScrollBarParams(); + } + + vec2 List::GetSize() { + //print->SetFont(); + + float_t max_text_size = 0.0f; + for (std::string& i : items) { + //vec2 text_size = print->GetTextSize(i); + ImVec2 _text_size = ImGui::CalcTextSize(i.c_str()); + vec2 text_size(_text_size.x, _text_size.y); + max_text_size = max_def(text_size.x, max_text_size); + } + + size_t v7 = sub_1402EF620(); + size_t v8 = items.size(); + //float_t v12 = font->GetFontGlyphHeight(); + float_t v12 = ImGui::CalcEmptyGlyphHeight(); + float_t v14 = (float_t)(int64_t)min_def(v7, v8); + if (v14 < 0.0f) + v14 += (float_t)UINT64_MAX; + + vec2 size = { max_text_size, v12 * v14 }; + if (v_bar) + size.x += v_bar->rect.size.x; + + if (flags & FLAG_800) + size += 2.0f * 2.0f; + return size; + } + void List::AddItem(const std::string& str) { items.push_back(str); } @@ -915,6 +1238,8 @@ namespace dw { void List::ClearItems() { items.clear(); + hovered_item = -1; + selected_item = -1; } std::string List::GetItem(size_t index) const { @@ -943,6 +1268,13 @@ namespace dw { ResetSetSelectedItem(index); } + void List::SetScrollBarParams() { + rectangle bb = GetBoundingBox(); + if (v_bar) + //v_bar->SetParams(bb.size.y, font->GetFontGlyphHeight(), items.size()); + v_bar->SetParams(bb.size.y, ImGui::CalcEmptyGlyphHeight(), items.size()); + } + void List::SetSelectedItem(size_t index) { if (index < items.size()) if (flags & MULTISELECT) @@ -951,9 +1283,18 @@ namespace dw { selections[index] = 1; } + size_t List::sub_1402EF620() { + if (!v_bar) + return items.size(); + /*else if (field_140 >= this->items.size()) + return items.size(); + return field_140;*/ + return 0; + } + ListBox::ListBox(Composite* parent, Flags flags) : Composite(parent, flags), list() { list = new List(parent, flags); - list->SetName("ddl"); + list->SetText("ddl"); list->parent = this; if (list->v_bar) { @@ -972,8 +1313,7 @@ namespace dw { std::vector& items = list->items; size_t hovered_item = list->selected_item; size_t selected_item = list->selected_item; - if (size == 0.0f) - ImGui::GetContentRegionAvailSetNextItemWidth(); + ImGui::SetNextItemWidth(rect.size.x); ImGui::PushID(this); if (ImGui::BeginCombo("##", selected_item != -1 && items.size() ? items[selected_item].c_str() : "", 0)) { @@ -985,6 +1325,7 @@ namespace dw { || ImGui::ItemKeyPressed(ImGuiKey_Enter) || (ImGui::IsItemFocused() && selected_item != item)) { selected_item = item; + list->selected_item = -1; } if (ImGui::IsItemHovered()) @@ -998,6 +1339,7 @@ namespace dw { window_focus |= true; ImGui::EndCombo(); } + ImGui::PopID(); if (list->hovered_item != hovered_item) list->hovered_item = hovered_item; @@ -1007,7 +1349,6 @@ namespace dw { for (SelectionListener*& i : list->selection_listeners) i->Callback(this); } - ImGui::PopID(); input_locked |= window_focus; } @@ -1016,6 +1357,16 @@ namespace dw { Composite::Reset(); } + vec2 ListBox::GetSize() { + vec2 size = list->GetSize(); + //size.x += font->GetFontGlyphWidth(); + //size.y = font->GetFontGlyphHeight(); + ImVec2 _size = ImGui::CalcEmptyGlyphSize(); + size.x += _size.x; + size.y = _size.y; + return size + 2.0f * 2.0f; + } + Slider::Slider(Composite* parent, Flags flags) : Control(parent, flags) { format = "%f"; scroll_bar = new ScrollBar(this, (Flags)(flags & (HORIZONTAL | VERTICAL))); @@ -1029,7 +1380,7 @@ namespace dw { void Slider::Draw() { ScrollBar* scroll_bar = this->scroll_bar; ImGui::PushID(this); - bool ret = ImGui::ColumnSliderFloatButton(name.c_str(), &scroll_bar->value, + bool ret = ImGui::ColumnSliderFloatButton(text.c_str(), &scroll_bar->value, scroll_bar->step, scroll_bar->min, scroll_bar->max, scroll_bar->step_fast, format, 0); ImGui::PopID(); if (ret) @@ -1048,8 +1399,8 @@ namespace dw { void Slider::SetSize(vec2 value) { Widget::SetSize(value); - scroll_bar->position.x = value.x - scroll_bar->size.x; - scroll_bar->position.y = 0.0f; + scroll_bar->rect.pos.x = value.x - scroll_bar->rect.size.x; + scroll_bar->rect.pos.y = 0.0f; } void Slider::AddSelectionListener(SelectionListener* value) { @@ -1057,37 +1408,40 @@ namespace dw { } Slider* Slider::make(Composite* parent, Flags flags, - float_t x, float_t y, float_t width, float_t height, const char* name) { + float_t pos_x, float_t pos_y, float_t width, float_t height, const char* text) { Slider* slider = new Slider(parent, flags); ScrollBar* scroll_bar = slider->scroll_bar; - slider->SetName(name); - scroll_bar->SetName("slider's bar"); + slider->SetText(text); + scroll_bar->SetText("slider's bar"); scroll_bar->SetSize({ width, height }); - /*sub_140302810(qword_1411900C8, &slider->font); - std::string v13 = slider->GetName(); - float_t v15; - float_t v17; + //print->SetFont(font); + vec2 size; if (flags & HORIZONTAL) { - vec2 v21; - vec2 v22; - sub_140302A70(qword_1411900C8, &v22, v13); - sub_140302A70(qword_1411900C8, &v21, "0000"); - scroll_bar->position.x = v21.x + v22.x; - scroll_bar->position.y = 0.0f; - v17 = v21.x + v22.x + scroll_bar->size.x ; - v15 = p_dw__Font::GetFontGlyphHeight(&slider->font); + //vec2 v21 = print->GetTextSize(slider->text); + //vec2 v22 = print->GetTextSize("0000"); + ImVec2 _v21 = ImGui::CalcTextSize(slider->text.c_str()); + ImVec2 _v22 = ImGui::CalcTextSize("0000"); + vec2 v21 = { _v21.x, _v21.y }; + vec2 v22 = { _v22.x, _v22.y }; + scroll_bar->rect.pos.x = v21.x + v22.x; + scroll_bar->rect.pos.y = 0.0f; + size.x = v21.x + v22.x + scroll_bar->rect.size.x; + //size.y = p_dw__Font::GetFontGlyphHeight(&slider->font); + size.y = ImGui::CalcEmptyGlyphHeight(); } else { - vec2 v21; - vec2 v22; - sub_140302A70(qword_1411900C8, &v21, v13); - sub_140302A70(qword_1411900C8, &v22, "0000"); - v17 = p_dw__Font::GetFontGlyphWidth(&slider->font); - v15 = v21.x + v22.x + scroll_bar->size.y; - }*/ - slider->position.x = x; - slider->position.y = y; - //slider->SetSize({ v17, v15 }); + //vec2 v21 = print->GetTextSize(slider->text); + //vec2 v22 = print->GetTextSize("0000"); + ImVec2 _v21 = ImGui::CalcTextSize(slider->text.c_str()); + ImVec2 _v22 = ImGui::CalcTextSize("0000"); + vec2 v21 = { _v21.x, _v21.y }; + vec2 v22 = { _v22.x, _v22.y }; + //size.x = p_dw__Font::GetFontGlyphWidth(&slider->font); + size.x = ImGui::CalcEmptyGlyphHeight(); + size.y = v21.x + v22.x + scroll_bar->rect.size.y; + } + slider->rect.pos = { pos_x, pos_y }; + slider->SetSize(size); return slider; } } diff --git a/src/ReDIVA/dw.hpp b/src/ReDIVA/dw.hpp index c9f39904..c627a9ea 100644 --- a/src/ReDIVA/dw.hpp +++ b/src/ReDIVA/dw.hpp @@ -12,24 +12,27 @@ namespace dw { enum Flags { - FLAG_1 = 0x0001, - FLAG_2 = 0x0002, - MULTISELECT = 0x0004, - FLAG_8 = 0x0008, - RADIOBUTTON = 0x0010, - CHECKBOX = 0x0020, - CLOSE_BUTTON = 0x0040, - FLAG_80 = 0x0080, - HORIZONTAL = 0x0100, - VERTICAL = 0x0200, - FLAG_400 = 0x0400, - FLAG_800 = 0x0800, - FLAG_1000 = 0x1000, - FLAG_2000 = 0x2000, - FLAG_4000 = 0x4000, + FLAG_1 = 0x00001, + FLAG_2 = 0x00002, + MULTISELECT = 0x00004, + FLAG_8 = 0x00008, + RADIOBUTTON = 0x00010, + CHECKBOX = 0x00020, + CLOSE_BUTTON = 0x00040, + FLAG_80 = 0x00080, + HORIZONTAL = 0x00100, + VERTICAL = 0x00200, + FLAG_400 = 0x00400, + FLAG_800 = 0x00800, + FLAG_1000 = 0x01000, + FLAG_2000 = 0x02000, + FLAG_4000 = 0x04000, + FLAG_8000 = 0x08000, + FLAG_10000 = 0x10000, + FLAG_20000 = 0x20000, // Added - LABEL_SIZE = 0x8000, + LABEL_SIZE = 0x80000, }; class Widget { @@ -51,9 +54,8 @@ namespace dw { } callback_data; Callback free_callback; - std::string name; - vec2 position; - vec2 size; + std::string text; + rectangle rect; Widget* parent; Flags flags; @@ -62,13 +64,14 @@ namespace dw { virtual void Draw(); virtual void Reset(); - virtual std::string GetName(); - virtual void SetName(std::string& str); + virtual std::string GetText(); + virtual void SetText(std::string& str); virtual void SetSize(vec2 value); virtual vec2 GetPos(); void Free(); - void SetName(std::string&& str); + rectangle GetRectangle(); + void SetText(std::string&& str); void UpdateDraw(); }; @@ -143,6 +146,7 @@ namespace dw { virtual ~Label() override; virtual void Draw() override; + virtual vec2 GetSize() override; }; class ScrollBar : public Widget { @@ -155,7 +159,7 @@ namespace dw { float_t field_94; float_t step; float_t step_fast; - int field_A0; + float_t field_A0; bool round; char field_A5; char field_A6; @@ -192,6 +196,7 @@ namespace dw { void SetParams(float_t value, float_t min, float_t max, float_t a5, float_t step, float_t step_fast); + void SetParams(float_t size, float_t step, size_t items_count); void SetValue(float_t value); void SetWidth(float_t value); @@ -229,9 +234,9 @@ namespace dw { class FillLayout : public Layout { public: - int32_t field_8; + Flags flags; - FillLayout(int32_t a2 = 512); + FillLayout(Flags flags = VERTICAL); virtual ~FillLayout() override; virtual vec2 GetSize(Composite* comp) override; @@ -245,9 +250,9 @@ namespace dw { class GraphLayout : public Layout { public: - int32_t field_8; + Flags flags; - GraphLayout(int32_t a2 = 512); + GraphLayout(Flags flags = VERTICAL); virtual ~GraphLayout() override; virtual vec2 GetSize(Composite* comp) override; @@ -261,18 +266,13 @@ namespace dw { class GridLayout : public Layout { public: - __int64 field_8; - __int64 field_10; - __int64 field_18; - __int64 field_20; - __int64 field_28; - __int64 field_30; - __int64 field_38; - size_t field_40; - float_t field_48; - float_t field_4C; + size_t rows; + std::vector column_size; + std::vector row_size; + size_t columns; + vec2 spacing; - GridLayout(size_t a2 = 2); + GridLayout(size_t columns = 2); virtual ~GridLayout() override; virtual vec2 GetSize(Composite* comp) override; @@ -319,7 +319,7 @@ namespace dw { virtual void SetSize(vec2 size) override; virtual void GetSetSize() override; - virtual vec2 GetSize() override; + virtual vec2 GetSize() override; void SetLayout(Layout* value); }; @@ -342,6 +342,7 @@ namespace dw { virtual ~Button() override; virtual void Draw() override; + virtual vec2 GetSize() override; void AddSelectionListener(SelectionListener* value); void SetValue(bool value); @@ -404,6 +405,9 @@ namespace dw { virtual void Draw() override; virtual void Reset() override; + virtual void SetSize(vec2 size) override; + + virtual vec2 GetSize() override; void AddItem(const std::string& str); void AddItem(const std::string&& str); @@ -414,6 +418,7 @@ namespace dw { void ResetSelectedItem(); void ResetSetSelectedItem(size_t index); void SetItemIndex(size_t index); + void SetScrollBarParams(); void SetSelectedItem(size_t index); inline std::string GetHoveredItem() { @@ -423,6 +428,8 @@ namespace dw { inline std::string GetSelectedItem() { return GetItem(selected_item); } + + size_t sub_1402EF620(); }; class ListBox : public Composite { @@ -435,6 +442,8 @@ namespace dw { virtual void Draw() override; virtual void Reset() override; + virtual vec2 GetSize() override; + inline void AddItem(const std::string& str) { if (list) list->AddItem(str); @@ -475,7 +484,7 @@ namespace dw { inline std::string GetSelectedItem() { if (list) - return list->GetHoveredItem(); + return list->GetSelectedItem(); return {}; } @@ -501,8 +510,9 @@ namespace dw { void AddSelectionListener(SelectionListener* value); static Slider* make(Composite* parent = 0, - Flags flags = (dw::Flags)(dw::FLAG_800 | dw::HORIZONTAL), float_t x = 0.0f, float_t y = 0.0f, - float_t width = 128.0f, float_t height = 20.0f, const char* name = "slider"); + Flags flags = (dw::Flags)(dw::FLAG_800 | dw::HORIZONTAL), + float_t pos_x = 0.0f, float_t pos_y = 0.0f, + float_t width = 128.0f, float_t height = 20.0f, const char* text = "slider"); inline void SetParams(float_t value, float_t min, float_t max, float_t a5, float_t step, float_t step_fast) { diff --git a/src/ReDIVA/font_info.cpp b/src/ReDIVA/font_info.cpp new file mode 100644 index 00000000..d43dc2ff --- /dev/null +++ b/src/ReDIVA/font_info.cpp @@ -0,0 +1,92 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#include "font_info.hpp" + +font_info* font_info_default; + +font_info::font_info() : font_ptr(), type() { + font_handler_index = -1; + init_font_data(0); +} + +font_info::font_info(int32_t font_handler_index) : font_ptr(), type() { + this->font_handler_index = -1; + init_font_data(font_handler_index); +} + +void font_info::init_font_data(int32_t font_handler_index) { + this->font_handler_index = font_handler_index; + + const font_handler* fh = fontmap_data_get_font_handler(font_handler_index); + const font* f = fh->font_ptr; + font_ptr = f; + font_glyph.x = (float_t)f->glyph_width; + font_glyph.y = (float_t)f->glyph_height; + font_glyph_box.x = (float_t)f->glyph_box_width; + font_glyph_box.y = (float_t)f->glyph_box_height; + + set_glyph_size((float_t)fh->glyph_width, (float_t)fh->glyph_height); + + spacing.x = (float_t)fh->glyph_horizontal_spacing; + spacing.y = (float_t)fh->glyph_vertical_spacing; + + type = 0; + if (f->column_scale_num != f->column_scale_denom) + type = 1; + if (fh->disable_glyph_spacing && f->disable_glyph_spacing) + type = 2; +} + +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 = false; + 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; + glyph_ratio.x = glyph_width / font_glyph.x; + glyph_ratio.y = glyph_height / font_glyph.y; +} + +bool font_info::sub_140199170() const { + return font_glyph != glyph && font_glyph == font_glyph_box; +} + +void font_info_default_init() { + if (!font_info_default) + font_info_default = new font_info; +} + +const font_info* font_info_default_get() { + return font_info_default; +} + +void font_info_default_free() { + if (font_info_default) { + delete font_info_default; + font_info_default = 0; + } +} diff --git a/src/ReDIVA/font_info.hpp b/src/ReDIVA/font_info.hpp new file mode 100644 index 00000000..2489809b --- /dev/null +++ b/src/ReDIVA/font_info.hpp @@ -0,0 +1,42 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#pragma once + +#include "../KKdLib/default.hpp" +#include "../KKdLib/vec.hpp" +#include "../CRE/font.hpp" +#include "../CRE/sprite.hpp" + +struct font_char { + rectangle tex; + float_t glyph_offset; + float_t glyph_width; + bool field_18; +}; + +struct font_info { + int32_t font_handler_index; + const font* font_ptr; + int32_t type; + vec2 font_glyph; + vec2 font_glyph_box; + vec2 glyph; + vec2 glyph_ratio; + vec2 spacing; + + font_info(); + font_info(int32_t font_handler_index); + + void init_font_data(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; +}; + +extern void font_info_default_init(); +extern const font_info* font_info_default_get(); +extern void font_info_default_free(); diff --git a/src/ReDIVA/imgui_helper.cpp b/src/ReDIVA/imgui_helper.cpp index 03dc196b..5da96b07 100644 --- a/src/ReDIVA/imgui_helper.cpp +++ b/src/ReDIVA/imgui_helper.cpp @@ -48,9 +48,13 @@ namespace ImGui { IsItemToggledOpenAccum |= IsItemToggledOpen(); } - bool SliderScalarStep(const char* label, ImGuiDataType data_type, void* p_data, + static bool SliderScalarStep(const char* label, ImGuiDataType data_type, void* p_data, const void* p_min, const void* p_max, const void* p_step, const char* format, ImGuiSliderFlags flags); + ImVec2 CalcEmptyGlyphSize() { + return ImGui::CalcTextSize(" "); + } + void StartPropertyColumn(const char* label) { PushID(label); @@ -1907,7 +1911,7 @@ namespace ImGui { std::string tex_buf(g.TempBuffer.Data, g.TempBuffer.Size); ImGui::SetCursorPosX((ImGui::GetWindowWidth() - ImGui::CalcTextSize(tex_buf.c_str()).x) * 0.5f); - ImGui::Text(tex_buf.c_str()); + ImGui::Text("%s", tex_buf.c_str()); } void TextRight(const char* fmt, ...) { @@ -1920,7 +1924,7 @@ namespace ImGui { std::string tex_buf(g.TempBuffer.Data, g.TempBuffer.Size); ImGui::SetCursorPosX(ImGui::GetWindowWidth() - ImGui::CalcTextSize(tex_buf.c_str()).x); - ImGui::Text(tex_buf.c_str()); + ImGui::Text("%s", tex_buf.c_str()); } // Taken from ImGui src @@ -2239,7 +2243,7 @@ namespace ImGui { return false; } - bool SliderScalarStep(const char* label, ImGuiDataType data_type, void* p_data, + static bool SliderScalarStep(const char* label, ImGuiDataType data_type, void* p_data, const void* p_min, const void* p_max, const void* p_step, const char* format, ImGuiSliderFlags flags) { ImGuiWindow* window = GetCurrentWindow(); if (window->SkipItems) diff --git a/src/ReDIVA/imgui_helper.hpp b/src/ReDIVA/imgui_helper.hpp index 11e7921a..77334ac7 100644 --- a/src/ReDIVA/imgui_helper.hpp +++ b/src/ReDIVA/imgui_helper.hpp @@ -78,6 +78,16 @@ namespace ImGui { SetNextItemWidth(GetContentRegionAvail().x); } + extern ImVec2 CalcEmptyGlyphSize(); + + inline float_t CalcEmptyGlyphWidth() { + return CalcEmptyGlyphSize().x; + } + + inline float_t CalcEmptyGlyphHeight() { + return CalcEmptyGlyphSize().y; + } + extern void StartPropertyColumn(const char* label); extern void EndPropertyColumn(); diff --git a/src/ReDIVA/print_work.cpp b/src/ReDIVA/print_work.cpp new file mode 100644 index 00000000..c43a42b8 --- /dev/null +++ b/src/ReDIVA/print_work.cpp @@ -0,0 +1,135 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#include "print_work.hpp" +#include "../KKdLib/str_utils.hpp" + +PrintWork::PrintWork() : clip(), layer(), field_28(), line_length() { + color = { 0xFF, 0xFF, 0xFF, 0xFF }; + fill_color = { 0x80, 0x80, 0x80, 0xFF }; + this->clip_data.size = 0i64; + prio = spr::SPR_PRIO_DEFAULT; + layer = 0; + resolution_mode = RESOLUTION_MODE_HD; + field_28 = 0; + line_length = 0i64; + font = font_info_default_get(); + empty_char = '\x25\xA1'; +} + +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; +} + +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);*/ + + vec2 size; + /*size.x = max_def(v10.size.x, v10.space_size.x); + size.y = v10.space_size.y + v10.size.y;*/ + return size; +} + +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::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) { + if (clip) + enum_or(flags, app::TEXT_FLAG_CLIP); + + if (font->sub_140199170()) + enum_or(flags, app::TEXT_FLAG_11); + + /*app::sap::SimpleContentHandler v8; + v8.data = this; + v8.flags = flags; + + app::sap::SimpleAutoLineFeedReader v6; + v6.print_work = this; + v6.content_handler = &v8; + v6.Print(str_begin, str_end);*/ +} + +void PrintWork::SetFont(const font_info* value) { + font = value; +} + +void PrintWork::SetResolutionMode(::resolution_mode value) { + resolution_mode = value; +} + +void PrintWork::printf(app::text_flags flags, const char* fmt, ...) { + va_list args; + va_start(args, fmt); + vprintf(flags, fmt, args); + va_end(args); +} + +void PrintWork::printf_align_left(const char* 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, ...) { + va_list args; + va_start(args, fmt); + vwprintf(flags, fmt, args); + va_end(args); +} + +void PrintWork::wprintf_align_left(const wchar_t* 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) { + char buf[0x100]; + PrintText(flags, buf, vsprintf_s(buf, sizeof(buf) / sizeof(wchar_t), fmt, args)); +} + +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)); +} diff --git a/src/ReDIVA/print_work.hpp b/src/ReDIVA/print_work.hpp new file mode 100644 index 00000000..00295f20 --- /dev/null +++ b/src/ReDIVA/print_work.hpp @@ -0,0 +1,71 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#pragma once + +#include "../KKdLib/default.hpp" +#include "../KKdLib/vec.hpp" +#include "../CRE/auth_2d.hpp" +#include "font_info.hpp" + +namespace app { + enum text_flags { + TEXT_FLAG_ALIGN_FLAG_LEFT = 0x00001, + 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_7 = 0x00040, + TEXT_FLAG_8 = 0x00080, + TEXT_FLAG_9 = 0x00100, + TEXT_FLAG_CLIP = 0x00200, + TEXT_FLAG_11 = 0x00400, + TEXT_FLAG_12 = 0x00800, + TEXT_FLAG_13 = 0x01000, + TEXT_FLAG_14 = 0x02000, + TEXT_FLAG_15 = 0x04000, + TEXT_FLAG_16 = 0x08000, + TEXT_FLAG_FONT = 0x10000, + }; +} + + +struct PrintWork { + vec4u8 color; + vec4u8 fill_color; + bool clip; + rectangle clip_data; + spr::SprPrio prio; + uint32_t layer; + resolution_mode resolution_mode; + uint32_t field_28; + vec2 text_current_loc; + vec2 line_origin_loc; + size_t line_length; + const font_info* font; + wchar_t empty_char; + + PrintWork(); + + font_char GetCharData(wchar_t c); + 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 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 SetFont(const font_info* value); + void SetResolutionMode(::resolution_mode value); + + 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); +}; diff --git a/src/ReDIVA/pv_game/pv_game_camera.cpp b/src/ReDIVA/pv_game/pv_game_camera.cpp index b0af8c68..42fe5454 100644 --- a/src/ReDIVA/pv_game/pv_game_camera.cpp +++ b/src/ReDIVA/pv_game/pv_game_camera.cpp @@ -176,7 +176,7 @@ static float_t sub_14011B160(float_t acceleration_1, float_t acceleration_2, flo return cosf(t * (float_t)M_PI) * (acceleration_2 - 1.0f) + 1.0f; else if (acceleration_1 == 1.0f) return cosf(t * (float_t)M_PI + (float_t)M_PI) - * fabsf((float_t)(int32_t)(1.0f - acceleration_2)) + 1.0f; + * fabsf((float_t)(int32_t)(1.0f - acceleration_2)) + 1.0f; else if (t < acceleration_1) return 2.0f - (cosf((t / acceleration_1) * (float_t)M_PI) * (acceleration_2 - 1.0f) + 1.0f); diff --git a/src/ReDIVA/render.cpp b/src/ReDIVA/render.cpp index fde30d31..bf5c2805 100644 --- a/src/ReDIVA/render.cpp +++ b/src/ReDIVA/render.cpp @@ -19,6 +19,7 @@ #include "../CRE/data.hpp" #include "../CRE/fbo.hpp" #include "../CRE/file_handler.hpp" +#include "../CRE/font.hpp" #include "../CRE/gl_state.hpp" #include "../CRE/hand_item.hpp" #include "../CRE/light_param.hpp" @@ -53,6 +54,7 @@ #include "data_test/stage_test.hpp" #include "pv_game/pv_game.hpp" #include "game_state.hpp" +#include "font_info.hpp" #include "imgui_helper.hpp" #include "input.hpp" #include "task_window.hpp" @@ -551,6 +553,8 @@ static render_context* render_context_load() { skin_param_data_load(); + fontmap_data_init(); + font_info_default_init(); sound_init(); wave_audio_storage_init(); ogg_file_handler_storage_init(); @@ -1240,6 +1244,8 @@ static void render_context_dispose(render_context* rctx) { ogg_file_handler_storage_free(); wave_audio_storage_free(); sound_free(); + font_info_default_free(); + fontmap_data_free(); skin_param_data_free(); mothead_storage_free();