From ebb9f7c87d83f12cc3fef38b9a59828264474819 Mon Sep 17 00:00:00 2001 From: Zack Buhman Date: Mon, 30 Jun 2025 15:04:24 -0500 Subject: [PATCH] button icons --- font/icons.data | Bin 0 -> 1024 bytes font/icons.data.h | 15 +++ font/icons.pgm | Bin 0 -> 2107 bytes src/graphics.cpp | 6 +- src/graphics_primitive.cpp | 2 +- src/graphics_primitive.hpp | 4 - src/icons.cpp | 68 +++++++++++ src/icons.hpp | 43 +++++++ src/main.cpp | 4 +- src/scene/tracker/channel_status.cpp | 41 +++---- src/scene/tracker/channel_status.hpp | 6 +- src/scene/tracker/notes.cpp | 172 +++++++++++++++++++-------- src/scene/tracker/notes.hpp | 8 +- src/scene/tracker/scene.cpp | 71 ++++------- src/texture.cpp | 5 + src/texture.hpp | 6 +- src/widget/bounding_box.hpp | 4 +- src/widget/button.cpp | 25 +--- src/widget/button.hpp | 39 ++---- src/widget/button_icon.cpp | 36 ++++++ src/widget/button_icon.hpp | 24 ++++ src/widget/button_label.cpp | 31 +++++ src/widget/button_label.hpp | 33 +++++ xm_player.mk | 4 + 24 files changed, 452 insertions(+), 195 deletions(-) create mode 100644 font/icons.data create mode 100644 font/icons.data.h create mode 100644 font/icons.pgm create mode 100644 src/icons.cpp create mode 100644 src/icons.hpp create mode 100644 src/widget/button_icon.cpp create mode 100644 src/widget/button_icon.hpp create mode 100644 src/widget/button_label.cpp create mode 100644 src/widget/button_label.hpp diff --git a/font/icons.data b/font/icons.data new file mode 100644 index 0000000000000000000000000000000000000000..668015f2c5e0999ae8e0d55dbbb067ad695d1d07 GIT binary patch literal 1024 zcmb7?2^Iq(2t)M-a{tRVpQTl%%QUaA$`S}TW@c;YFENJM7`vw;{hX7`0#R6H_d0V% z#O&miUp);O#W(42TReG_t-A=jeaTOU_{tMnKBe4QM4hBza(2)d-={eK1KGCPA2EzK zadxn>JNMl-*}L9uSAFu6O~n^ literal 0 HcmV?d00001 diff --git a/font/icons.data.h b/font/icons.data.h new file mode 100644 index 0000000..1dc5feb --- /dev/null +++ b/font/icons.data.h @@ -0,0 +1,15 @@ +#pragma once + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +extern uint32_t _binary_font_icons_data_start __asm("_binary_font_icons_data_start"); +extern uint32_t _binary_font_icons_data_end __asm("_binary_font_icons_data_end"); +extern uint32_t _binary_font_icons_data_size __asm("_binary_font_icons_data_size"); + +#ifdef __cplusplus +} +#endif diff --git a/font/icons.pgm b/font/icons.pgm new file mode 100644 index 0000000000000000000000000000000000000000..e74f227896fc3a84c51f55ffc4c9421f622f4f96 GIT binary patch literal 2107 zcmeH^!A`?442FB|Q$*s-1RX`(IUo*0eFYE|nuG@00EwqBwH@1kytU=RjY^sS*#GA^ zS=ZKQ>2}{ge)P}j={w!sZ@To=?+@FzU20aB7pwJ6>K-=f{q^(Ze7mc!uhP1yo3^co zp$gx?A16Up>N7wDS;__gfy}(wRiH)sKn5i9wl`6U!Wq1li@B{^kx}g(rg(R%qQ7x?jL;YrA8CB4Wi zKE_DS?txP|>yJf+AV$mVUb%4pk)ey^1u`}hp6w(_h=n$%R%nnRd0(yxPkH@pHcA}v oIbjucD9W+mV}sC7x7eWI)vy$4)KhDTvpQWUFOXLL7k~KzKNJok8vp 0); int number_of_channels = round_up(state.xm.number_of_channels, rows); int channels_per_row = number_of_channels / rows; - int width_per_col = (framebuffer.px_width - 3) / channels_per_row; - int offset = (framebuffer.px_width - (width_per_col * channels_per_row)) / 2; + int width_per_col = (px_width - 3) / channels_per_row; + int offset = (px_width - (width_per_col * channels_per_row)) / 2; int inner_width = width_per_col - 3; - int height_per_row = channel_status_height / rows; + int height_per_row = height / rows; int vert_center = height_per_row / 2 - glyph::vert_advance / 2; int ch = 0; for (int row = 0; row < rows; row++) { int xi = x + offset - 2; - global_polygon_untextured(writer, + global_polygon_untextured(multi.op, para_control::list_type::opaque, tsp_instruction_word::dst_alpha_instr::zero); - transfer_horizontal_border(writer, xi, y, width_per_col * channels_per_row); + transfer_horizontal_border(multi.op, xi, y, width_per_col * channels_per_row); for (int col = 0; col < channels_per_row; col++) { - global_polygon_untextured(writer, + global_polygon_untextured(multi.op, para_control::list_type::opaque, tsp_instruction_word::dst_alpha_instr::zero); - transfer_vertical_border(writer, xi, y, height_per_row); + transfer_vertical_border(multi.op, xi, y, height_per_row); int keyon = 128 * (state.channel[ch].keyon - 224) / 16; if (keyon < 0) keyon = 0; uint32_t base_color = (keyon << 16) | (keyon << 8) | (keyon << 0); - transfer_rectangle(writer, + transfer_rectangle(multi.op, xi, y, 1.0 / 10000.0, width_per_col, height_per_row, base_color); if (ch < state.xm.number_of_channels) { - uint32_t texture_size = tsp_instruction_word::texture_u_size::from_int(128) - | tsp_instruction_word::texture_v_size::from_int(256); - - global_polygon_textured(writer, - para_control::list_type::opaque, - texture::offset::tandy1k, - texture_size, - texture_control_word::pixel_format::_4bpp_palette); + transfer_global_polygon_glyph(multi.pt); int hori_center = inner_width / 2 - (glyph::hori_advance * (ch >= 10)) / 2; - transfer_integer(writer, ch, + transfer_integer(multi.pt, ch, xi + hori_center, y + vert_center, 0.0001f, 0, 0, 0xa7a7a7); @@ -91,19 +84,19 @@ void transfer(ta_parameter_writer& writer, int x, int y) ch += 1; } - global_polygon_untextured(writer, + global_polygon_untextured(multi.op, para_control::list_type::opaque, tsp_instruction_word::dst_alpha_instr::zero); - transfer_vertical_border(writer, xi, y, height_per_row); + transfer_vertical_border(multi.op, xi, y, height_per_row); y += height_per_row; } int xi = x + offset - 2; - transfer_horizontal_border(writer, xi, y, width_per_col * channels_per_row); + transfer_horizontal_border(multi.op, xi, y, width_per_col * channels_per_row); - //borders(writer, x, y); + //borders(multi, x, y); } } diff --git a/src/scene/tracker/channel_status.hpp b/src/scene/tracker/channel_status.hpp index cd6d444..a37c912 100644 --- a/src/scene/tracker/channel_status.hpp +++ b/src/scene/tracker/channel_status.hpp @@ -1,7 +1,9 @@ #pragma once -#include "holly/ta_parameter.hpp" +#include "ta_multiwriter.hpp" namespace scene::tracker::channel_status { - void transfer(ta_parameter_writer& writer, int x, int y); + const int height = 50; + + void draw(ta_multiwriter& multi, int x, int y); } diff --git a/src/scene/tracker/notes.cpp b/src/scene/tracker/notes.cpp index b5f6126..ea3d010 100644 --- a/src/scene/tracker/notes.cpp +++ b/src/scene/tracker/notes.cpp @@ -4,16 +4,54 @@ #include "../../interpreter.hpp" #include "notes.hpp" +#include "framebuffer.hpp" -const int line_column_total_advance = (3 + 2 + 2 + 1 + 2) * glyph::hori_advance; -const int line_column_width = line_column_total_advance + 6 + 3; +union columns { + struct { + int note; + int instrument; + int volume_column_byte; + int effect_type; + int effect_parameter; + }; + int col[5]; + + int count() const + { + int acc = 0; + for (int i = 0; i < 5; i++) { + acc += col[i] != 0; + } + return acc; + } + + int sum() const + { + int acc = 0; + for (int i = 0; i < 5; i++) { + acc += col[i]; + } + return acc; + } +}; + +const columns line_columns = { + .note = 3, + .instrument = 2, + .volume_column_byte = 0, // 2 + .effect_type = 0, // 1 + .effect_parameter = 0, // 1 +}; + +const int line_column_total_advance = line_columns.sum() * glyph::hori_advance; +const int line_column_width = line_column_total_advance + (line_columns.count() + 1) + 3; const int line_rows_half = 15; const int line_rows = line_rows_half * 2 + 1; const int line_column_height = line_rows * glyph::vert_advance + 3 + 1; -const int depth = 0.0001f; +const float depth = 0.0001f; -static inline int transfer_line_index(ta_parameter_writer& writer, int line_index, int x, int y) +static inline int draw_line_index(ta_parameter_writer& writer, int line_index, int x, int y) { const int dark = 0x5d646b; const int light = 0xa7a7a7; @@ -26,7 +64,7 @@ static inline int transfer_line_index(ta_parameter_writer& writer, int line_inde return x; } -static inline int transfer_fill(ta_parameter_writer& writer, int count, int x, int y, +static inline int draw_fill(ta_parameter_writer& writer, int count, int x, int y, int base_color) { for (int i = 0; i < count; i++) { @@ -36,7 +74,7 @@ static inline int transfer_fill(ta_parameter_writer& writer, int count, int x, i return x; } -static inline int transfer_note(ta_parameter_writer& writer, int note, int x, int y) +static inline int draw_note(ta_parameter_writer& writer, int note, int x, int y) { static const char note_names[12][2] = { {'C', '-'}, @@ -75,33 +113,39 @@ static inline int transfer_note(ta_parameter_writer& writer, int note, int x, in transfer_glyph(writer, '0' + octave, x, y, depth, base_color); x += glyph::hori_advance; } else { - x = transfer_fill(writer, 3, x, y, base_color); + x = draw_fill(writer, 3, x, y, base_color); } return x; } -static inline int transfer_instrument(ta_parameter_writer& writer, int instrument, int x, int y) +static inline int draw_instrument(ta_parameter_writer& writer, int instrument, int x, int y) { int base_color = 0x9393ff; if (instrument != 0) { - int len = transfer_hex_integer(writer, instrument, x, y, 2, glyph::interpunct, base_color); + int len = transfer_hex_integer(writer, instrument, + x, y, depth, + 2, glyph::interpunct, + base_color); x += glyph::hori_advance * len; } else { - x = transfer_fill(writer, 2, x, y, base_color); + x = draw_fill(writer, 2, x, y, base_color); } return x; } -static inline int transfer_volume_column_byte(ta_parameter_writer& writer, int volume_column_byte, int x, int y) +static inline int draw_volume_column_byte(ta_parameter_writer& writer, int volume_column_byte, int x, int y) { int base_color = 0xa7c9f1; if (volume_column_byte != 0) { - int len = transfer_hex_integer(writer, volume_column_byte, x, y, 2, glyph::interpunct, base_color); + int len = transfer_hex_integer(writer, volume_column_byte, + x, y, depth, + 2, glyph::interpunct, + base_color); x += glyph::hori_advance * len; } else { - x = transfer_fill(writer, 2, x, y, base_color); + x = draw_fill(writer, 2, x, y, base_color); } return x; } @@ -115,7 +159,7 @@ static inline int effect_type_char(int effect_type) return 128; } -static inline int transfer_effect_type(ta_parameter_writer& writer, int effect_type, int x, int y) +static inline int draw_effect_type(ta_parameter_writer& writer, int effect_type, int x, int y) { int base_color = 0xffffff; @@ -124,32 +168,34 @@ static inline int transfer_effect_type(ta_parameter_writer& writer, int effect_t transfer_glyph(writer, c, x, y, depth, base_color); x += glyph::hori_advance; } else { - x = transfer_fill(writer, 1, x, y, base_color); + x = draw_fill(writer, 1, x, y, base_color); } return x; } -static inline int transfer_effect_parameter(ta_parameter_writer& writer, int effect_parameter, int x, int y) +static inline int draw_effect_parameter(ta_parameter_writer& writer, int effect_parameter, int x, int y) { int base_color = 0x7f7f80; if (effect_parameter != 0) { - int len = transfer_hex_integer(writer, effect_parameter, x, y, 2, glyph::interpunct, + int len = transfer_hex_integer(writer, effect_parameter, + x, y, depth, + 2, glyph::interpunct, base_color); x += glyph::hori_advance * len; } else { - x = transfer_fill(writer, 2, x, y, base_color); + x = draw_fill(writer, 2, x, y, base_color); } return x; } -static void transfer_line(ta_parameter_writer& writer, int line_index, int x, int y) +static void draw_line(ta_parameter_writer& writer, int line_index, int x, int y) { using namespace interpreter; x += 3; x += 1; - x = transfer_line_index(writer, line_index, x, y); + x = draw_line_index(writer, line_index, x, y); x += 1; x += 3; @@ -159,16 +205,26 @@ static void transfer_line(ta_parameter_writer& writer, int line_index, int x, in const xm_pattern_format_t& pf = pattern[line_pattern_index + ch]; x += 1; - x = transfer_note(writer, pf.note, x, y); - x += 1; - x = transfer_instrument(writer, pf.instrument, x, y); - x += 1; - x = transfer_volume_column_byte(writer, pf.volume_column_byte, x, y); - x += 1; - x = transfer_effect_type(writer, pf.effect_type, x, y); - x += 1; - x = transfer_effect_parameter(writer, pf.effect_parameter, x, y); - x += 1; + if (line_columns.note != 0) { + x = draw_note(writer, pf.note, x, y); + x += 1; + } + if (line_columns.instrument != 0) { + x = draw_instrument(writer, pf.instrument, x, y); + x += 1; + } + if (line_columns.volume_column_byte != 0) { + x = draw_volume_column_byte(writer, pf.volume_column_byte, x, y); + x += 1; + } + if (line_columns.effect_type != 0) { + x = draw_effect_type(writer, pf.effect_type, x, y); + x += 1; + } + if (line_columns.effect_parameter != 0) { + x = draw_effect_parameter(writer, pf.effect_parameter, x, y); + x += 1; + } x += 3; } @@ -176,13 +232,13 @@ static void transfer_line(ta_parameter_writer& writer, int line_index, int x, in namespace scene::tracker::notes { -void borders(ta_parameter_writer& writer, int x, int y) +void draw_borders(ta_parameter_writer& writer, int x, int y) { using namespace interpreter; int x0 = x; - transfer_vertical_border(writer, x, y, line_column_height); + //transfer_vertical_border(writer, x, y, line_column_height); x += 3 + glyph::hori_advance * 2 + 2; for (int ch = 0; ch < (state.xm.number_of_channels); ch++) { @@ -191,14 +247,14 @@ void borders(ta_parameter_writer& writer, int x, int y) } transfer_vertical_border(writer, x, y, line_column_height); - transfer_horizontal_border(writer, x0, y, - x - x0); + transfer_horizontal_border(writer, 0, y, + framebuffer.px_width); - transfer_horizontal_border(writer, x0, y + line_column_height, - x - x0); + transfer_horizontal_border(writer, 0, y + line_column_height, + framebuffer.px_width); } -void transfer_lines(ta_parameter_writer& writer, int x, int y) +void draw_lines(ta_parameter_writer& writer, int x, int y) { using namespace interpreter; @@ -208,12 +264,12 @@ void transfer_lines(ta_parameter_writer& writer, int x, int y) for (int i = 0; i < line_rows; i++) { int line_ix = state.line_index - line_rows_half + i; if (line_ix >= 0 && line_ix < pattern_line_count) - transfer_line(writer, line_ix, x, y); + draw_line(writer, line_ix, x, y); y += glyph::vert_advance; } } -void transfer_middle_line(ta_parameter_writer& writer, float x, float y) +void draw_middle_line(ta_parameter_writer& writer, float x, float y) { using namespace interpreter; @@ -225,29 +281,43 @@ void transfer_middle_line(ta_parameter_writer& writer, float x, float y) y += glyph::vert_advance * line_rows_half; quad_type_0(writer, - {x + 0, y + 0, 1.0/15.0}, - {x + 0, y + 1, 1.0/15.0}, - {x + middle_width, y + 1, 1.0/15.0}, - {x + middle_width, y + 0, 1.0/15.0}, + {x + 0, y + 0, depth / 2.0}, + {x + 0, y + 1, depth / 2.0}, + {x + middle_width, y + 1, depth / 2.0}, + {x + middle_width, y + 0, depth / 2.0}, 0x555555); y += 1; quad_type_0(writer, - {x + 0, y + 0, 1.0/15.0}, - {x + 0, y + middle_height, 1.0/15.0}, - {x + middle_width, y + middle_height, 1.0/15.0}, - {x + middle_width, y + 0, 1.0/15.0}, + {x + 0, y + 0, depth / 2.0}, + {x + 0, y + middle_height, depth / 2.0}, + {x + middle_width, y + middle_height, depth / 2.0}, + {x + middle_width, y + 0, depth / 2.0}, 0x404040); y += middle_width; quad_type_0(writer, - {x + 0, y + 0, 1.0/15.0}, - {x + 0, y + 1, 1.0/15.0}, - {x + middle_width, y + 1, 1.0/15.0}, - {x + middle_width, y + 0, 1.0/15.0}, + {x + 0, y + 0, depth / 2.0}, + {x + 0, y + 1, depth / 2.0}, + {x + middle_width, y + 1, depth / 2.0}, + {x + middle_width, y + 0, depth / 2.0}, 0x202020); } +void draw(ta_multiwriter& multi, float x, float y) +{ + transfer_global_polygon_glyph(multi.pt); + + draw_lines(multi.pt, x, y); + + global_polygon_untextured(multi.op, + para_control::list_type::opaque, + tsp_instruction_word::dst_alpha_instr::zero); + draw_borders(multi.op, x, y); + + draw_middle_line(multi.op, x, y); +} + } diff --git a/src/scene/tracker/notes.hpp b/src/scene/tracker/notes.hpp index e9a49de..2a2fce4 100644 --- a/src/scene/tracker/notes.hpp +++ b/src/scene/tracker/notes.hpp @@ -1,11 +1,13 @@ #pragma once #include "holly/ta_parameter.hpp" +#include "ta_multiwriter.hpp" namespace scene::tracker::notes { - void borders(ta_parameter_writer& writer, int x, int y); - void transfer_lines(ta_parameter_writer& writer, int x, int y); - void transfer_middle_line(ta_parameter_writer& writer, float x, float y); + void draw_borders(ta_parameter_writer& writer, int x, int y); + void draw_lines(ta_parameter_writer& writer, int x, int y); + void draw_middle_line(ta_parameter_writer& writer, float x, float y); + void draw(ta_multiwriter& multi, float x, float y); } diff --git a/src/scene/tracker/scene.cpp b/src/scene/tracker/scene.cpp index 2702fb5..e9a27f6 100644 --- a/src/scene/tracker/scene.cpp +++ b/src/scene/tracker/scene.cpp @@ -7,11 +7,13 @@ #include "notes.hpp" #include "channel_status.hpp" #include "texture.hpp" -#include "widget/button.hpp" +#include "widget/button_label.hpp" +#include "widget/button_icon.hpp" #include "widget/left_aligned.hpp" #include "widget/top_aligned.hpp" #include "playlist.hpp" #include "interpreter.hpp" +#include "icons.hpp" #include "cursor.hpp" @@ -29,16 +31,17 @@ void next_click() #define __length(c) ((sizeof (c)) / (sizeof (c[0]))) -widget::button play_button(75, 60, "play"); -widget::button pause_button(75, 33, "pause"); +//widget::button_label play_button(75, 60, "play", nullptr); +widget::button_icon play_button(75, 60, icons::play, nullptr); +widget::button_icon pause_button(75, 33, icons::pause, nullptr); -widget::button prev_button(79, 30, "prev", prev_click); -widget::button next_button(79, 30, "next", next_click); +widget::button_icon prev_button(79, 30, icons::prev, prev_click); +widget::button_icon next_button(79, 30, icons::next, next_click); -widget::button rrr_button(39, 15, "rrr"); -widget::button rr_button(39, 15, "rr"); -widget::button ff_button(39, 15, "ff"); -widget::button fff_button(39, 15, "fff"); +widget::button_icon rrr_button(39, 21, icons::rrr, nullptr); +widget::button_icon rr_button(39, 21, icons::rr, nullptr); +widget::button_icon ff_button(39, 21, icons::ff, nullptr); +widget::button_icon fff_button(39, 21, icons::fff, nullptr); widget::widget * play_pause_children[] = { &play_button, @@ -64,7 +67,7 @@ widget::top_aligned play_pause(0, 0, 1, play_pause_children, play_pause_length); widget::left_aligned prev_next(0, 15, 1, prev_next_children, prev_next_length); -widget::left_aligned ff_rr(0, 70, 1, ff_rr_children, ff_rr_length); +widget::left_aligned ff_rr(0, 67, 1, ff_rr_children, ff_rr_length); widget::widget * prev_next_ff_rr_children[] = { &prev_next, @@ -80,7 +83,7 @@ widget::widget * top_children[] = { }; int top_length = __length(top_children); -widget::left_aligned top(100, 100, 20, top_children, top_length); +widget::left_aligned top(0, 0, 20, top_children, top_length); namespace scene::tracker { @@ -103,7 +106,7 @@ namespace scene::tracker { void init() { - top.freeze(0, 0); + top.freeze(5, 5); playlist::next(); } @@ -124,48 +127,14 @@ namespace scene::tracker { { update(); - const int x = 3; - const int y = 100; + top.draw(multi); - { // punch-through - uint32_t texture_size = tsp_instruction_word::texture_u_size::from_int(128) - | tsp_instruction_word::texture_v_size::from_int(256); + float y = top.y() + top.height + 5; - /* - global_polygon_textured(multi.pt, - para_control::list_type::punch_through, - texture::offset::tandy1k, - texture_size, - texture_control_word::pixel_format::_4bpp_palette); - */ + channel_status::draw(multi, 5, y); - //tracker::notes::transfer_lines(multi.pt, x, y); - } + y += channel_status::height + 5; - /* - { // translucent - global_polygon_untextured(writer, - para_control::list_type::translucent, - tsp_instruction_word::dst_alpha_instr::one); - - tracker::notes::transfer_middle_line(writer, x, y); - - writer.append() = - ta_global_parameter::end_of_list(para_control::para_type::end_of_list); - } - */ - - { // opaque - global_polygon_untextured(multi.op, - para_control::list_type::opaque, - tsp_instruction_word::dst_alpha_instr::zero); - - //tracker::notes::borders(multi.op, x, y); - - //tracker::channel_status::transfer(multi.op, 0, 0); - - //test_container.draw(multi); - top.draw(multi); - } + notes::draw(multi, 5, y); } } diff --git a/src/texture.cpp b/src/texture.cpp index bb33c9b..14e9f2a 100644 --- a/src/texture.cpp +++ b/src/texture.cpp @@ -21,6 +21,11 @@ namespace texture { .start = reinterpret_cast(&_binary_model_32bitlogo_colors_data_start), .size = reinterpret_cast(&_binary_model_32bitlogo_colors_data_size), .offset = offset::logo, + }, + { + .start = reinterpret_cast(&_binary_font_icons_data_start), + .size = reinterpret_cast(&_binary_font_icons_data_size), + .offset = offset::icons, } }; diff --git a/src/texture.hpp b/src/texture.hpp index 82b387e..6a322ba 100644 --- a/src/texture.hpp +++ b/src/texture.hpp @@ -2,6 +2,7 @@ #include "font/tandy1k.data.h" #include "model/32bitlogo/colors.data.h" +#include "font/icons.data.h" namespace texture { struct texture { @@ -11,8 +12,9 @@ namespace texture { }; namespace offset { - constexpr int tandy1k = 0; - constexpr int logo = 16384; + constexpr int tandy1k = 0; // 16384 + constexpr int logo = 16384; // 128 * 3 + constexpr int icons = 16384 + (128 * 3); // 2048 }; extern struct texture textures[]; diff --git a/src/widget/bounding_box.hpp b/src/widget/bounding_box.hpp index 53db160..56c10ae 100644 --- a/src/widget/bounding_box.hpp +++ b/src/widget/bounding_box.hpp @@ -14,12 +14,12 @@ namespace widget { : _x(__x), _y(__y), width(_width), height(_height), dx(0), dy(0) { } - constexpr inline float x() + constexpr inline float x() const { return dx + _x; } - constexpr inline float y() + constexpr inline float y() const { return dy + _y; } diff --git a/src/widget/button.cpp b/src/widget/button.cpp index e186075..34af26a 100644 --- a/src/widget/button.cpp +++ b/src/widget/button.cpp @@ -19,10 +19,7 @@ namespace widget { const static float background_depth = 1.0 / 7.0; const static int background_color = 0x282c2c; - const static float label_depth = 1.0 / 6.0; - const static int label_color = 0xffffff; - - void button::draw_shadow(ta_parameter_writer& writer) + void button::draw_shadow(ta_parameter_writer& writer) const { { float x0 = x() + 1; @@ -50,7 +47,7 @@ namespace widget { } } - void button::draw_lowlight(ta_parameter_writer& writer) + void button::draw_lowlight(ta_parameter_writer& writer) const { float x0 = x() + 1; float x1 = x() + width - 1; @@ -64,7 +61,7 @@ namespace widget { lowlight_color); } - void button::draw_highlight(ta_parameter_writer& writer) + void button::draw_highlight(ta_parameter_writer& writer) const { float x0 = x() + 1; float x1 = x() + width - 2; @@ -80,7 +77,7 @@ namespace widget { color); } - void button::draw_background(ta_parameter_writer& writer) + void button::draw_background(ta_parameter_writer& writer) const { float x0 = x() + 2; float x1 = x() + width - 2; @@ -94,16 +91,6 @@ namespace widget { background_color); } - void button::draw_label(ta_parameter_writer& writer) - { - float y_offset = (float)(click_state != click_type::release); - - float cx = x() + width / 2 - (glyph::hori_advance * label_length) / 2; - float cy = y() + height / 2 - glyph::vert_advance / 2 + y_offset; - - transfer_string(writer, label, cx, cy, label_depth, label_color); - } - void button::draw(ta_multiwriter& multi) { global_polygon_untextured(multi.op, @@ -118,10 +105,6 @@ namespace widget { draw_background(multi.op); - transfer_global_polygon_glyph(multi.pt); - - draw_label(multi.pt); - widget::draw(multi); } diff --git a/src/widget/button.hpp b/src/widget/button.hpp index 78e98cf..4b12b04 100644 --- a/src/widget/button.hpp +++ b/src/widget/button.hpp @@ -5,42 +5,23 @@ #include "widget/widget.hpp" namespace widget { - - constexpr inline int str_length(const char * s) - { - int l = 0; - while (*s++) { - l += 1; - } - return l; - } - struct button : widget { - const char * const label; - const int label_length; + using widget::draw; + void (* const on_click)(); - inline button(float _width, float _height, const char * _label) - : widget(0, 0, _width, _height), label(_label), label_length(str_length(_label)), on_click(nullptr) + inline button(float _width, float _height, void (* const _on_click)()) + : widget(0, 0, _width, _height), on_click(_on_click) { } - inline button(float _width, float _height, const char * _label, void (* const _on_click)()) - : widget(0, 0, _width, _height), label(_label), label_length(str_length(_label)), on_click(_on_click) + inline button(float _x, float _y, float _width, float _height, void (* const _on_click)()) + : widget(_x, _y, _width, _height), on_click(_on_click) { } - inline button(float _x, float _y, float _width, float _height, const char * _label) - : widget(_x, _y, _width, _height), label(_label), label_length(str_length(_label)), on_click(nullptr) - { } - - inline button(float _x, float _y, float _width, float _height, const char * _label, void (* const _on_click)()) - : widget(_x, _y, _width, _height), label(_label), label_length(str_length(_label)), on_click(_on_click) - { } - - void draw_shadow(ta_parameter_writer& writer); - void draw_lowlight(ta_parameter_writer& writer); - void draw_highlight(ta_parameter_writer& writer); - void draw_background(ta_parameter_writer& writer); - void draw_label(ta_parameter_writer& writer); + void draw_shadow(ta_parameter_writer& writer) const; + void draw_lowlight(ta_parameter_writer& writer) const; + void draw_highlight(ta_parameter_writer& writer) const; + void draw_background(ta_parameter_writer& writer) const; void draw(ta_multiwriter& multi) override; void click() override; diff --git a/src/widget/button_icon.cpp b/src/widget/button_icon.cpp new file mode 100644 index 0000000..3d905d4 --- /dev/null +++ b/src/widget/button_icon.cpp @@ -0,0 +1,36 @@ +#include "button_icon.hpp" + +#include "icons.hpp" + +namespace widget { + + const static float icon_depth = 1.0 / 5.0; + const static int icon_color = 0xffffff; + + const static float icon_shadow_depth = 1.0 / 5.5; + const static int icon_shadow_color = 0x100000; + + void button_icon::draw_icon(ta_parameter_writer& writer) const + { + float y_offset = (float)(click_state != click_type::release); + + const icons::icon& icon = icons::icons[icon_type]; + + float cx = x() + width / 2 - (icon.width) / 2; + float cy = y() + height / 2 - (icon.height) / 2 + y_offset; + + icons::global_polygon_icon(writer); + + icons::draw(writer, icon_type, cx, cy, icon_depth, icon_color); + + if (click_state == click_type::release) + icons::draw(writer, icon_type, cx + 1, cy + 1, icon_shadow_depth, icon_shadow_color); + } + + void button_icon::draw(ta_multiwriter& multi) + { + draw_icon(multi.pt); + + button::draw(multi); + } +} diff --git a/src/widget/button_icon.hpp b/src/widget/button_icon.hpp new file mode 100644 index 0000000..881ee68 --- /dev/null +++ b/src/widget/button_icon.hpp @@ -0,0 +1,24 @@ +#pragma once + +#include "holly/ta_parameter.hpp" +#include "ta_multiwriter.hpp" +#include "widget/button.hpp" +#include "icons.hpp" + +namespace widget { + + struct button_icon : button { + const icons::icon_type icon_type; + + inline button_icon(float _width, float _height, icons::icon_type icon_type, void (* const _on_click)()) + : button(0, 0, _width, _height, _on_click), icon_type(icon_type) + { } + + inline button_icon(float _x, float _y, float _width, float _height, icons::icon_type icon_type, void (* const _on_click)()) + : button(_x, _y, _width, _height, _on_click), icon_type(icon_type) + { } + + void draw_icon(ta_parameter_writer& writer) const; + void draw(ta_multiwriter& multi) override; + }; +} diff --git a/src/widget/button_label.cpp b/src/widget/button_label.cpp new file mode 100644 index 0000000..16c59c1 --- /dev/null +++ b/src/widget/button_label.cpp @@ -0,0 +1,31 @@ +#include "button_label.hpp" + +#include "graphics_primitive.hpp" + +namespace widget { + + const static float label_depth = 1.0 / 5.0; + const static int label_color = 0xffffff; + + const static float label_shadow_depth = 1.0 / 6.0; + const static int label_shadow_color = 0x000000; + + void button_label::draw_label(ta_parameter_writer& writer) const + { + float y_offset = (float)(click_state != click_type::release); + + float cx = x() + width / 2 - (glyph::hori_advance * label_length) / 2; + float cy = y() + height / 2 - glyph::vert_advance / 2 + y_offset; + + transfer_string(writer, label, cx, cy, label_depth, label_color); + } + + void button_label::draw(ta_multiwriter& multi) + { + transfer_global_polygon_glyph(multi.pt); + + draw_label(multi.pt); + + button::draw(multi); + } +} diff --git a/src/widget/button_label.hpp b/src/widget/button_label.hpp new file mode 100644 index 0000000..907bf71 --- /dev/null +++ b/src/widget/button_label.hpp @@ -0,0 +1,33 @@ +#pragma once + +#include "holly/ta_parameter.hpp" +#include "ta_multiwriter.hpp" +#include "widget/button.hpp" + +namespace widget { + + constexpr inline int str_length(const char * s) + { + int l = 0; + while (*s++) { + l += 1; + } + return l; + } + + struct button_label : button { + const char * const label; + const int label_length; + + inline button_label(float _width, float _height, const char * label, void (* const _on_click)()) + : button(0, 0, _width, _height, _on_click), label(label), label_length(str_length(label)) + { } + + inline button_label(float _x, float _y, float _width, float _height, const char * label, void (* const _on_click)()) + : button(_x, _y, _width, _height, _on_click), label(label), label_length(str_length(label)) + { } + + void draw_label(ta_parameter_writer& writer) const; + void draw(ta_multiwriter& multi) override; + }; +} diff --git a/xm_player.mk b/xm_player.mk index 15b4142..a543324 100644 --- a/xm_player.mk +++ b/xm_player.mk @@ -5,6 +5,7 @@ XM_OBJ = \ TEXTURE_OBJ = \ font/tandy1k.data.o \ + font/icons.data.o \ model/32bitlogo/colors.data.o PCM_OBJ = \ @@ -22,6 +23,7 @@ XM_PLAYER_OBJ = \ $(LIB)/printf/printf.o \ $(LIB)/printf/unparse.o \ $(LIB)/printf/parse.o \ + src/icons.o \ src/cursor.o \ src/framebuffer.o \ src/graphics.o \ @@ -40,6 +42,8 @@ XM_PLAYER_OBJ = \ src/sound.o \ src/texture.o \ src/widget/button.o \ + src/widget/button_label.o \ + src/widget/button_icon.o \ src/xm.o xm_player.elf: LDSCRIPT = $(LIB)/main.lds