diff options
| author | Jonathan Bradley <jcb@pikum.xyz> | 2025-10-02 10:56:30 -0400 |
|---|---|---|
| committer | Jonathan Bradley <jcb@pikum.xyz> | 2025-10-02 10:56:30 -0400 |
| commit | cc8653536c499df4b85aae423ad6b27bb74544be (patch) | |
| tree | c1d91873ee5f1672a773615699353ee866d06d36 | |
| parent | 3545969b61ccc5a19653309ab19d1c2c9eb729f1 (diff) | |
pke-at: metronome start+stop buttons
| -rw-r--r-- | src/level-main.cpp | 199 | ||||
| -rw-r--r-- | src/pke-at-common.cpp | 2 | ||||
| -rw-r--r-- | src/pke-at-settings.hpp | 2 |
3 files changed, 189 insertions, 14 deletions
diff --git a/src/level-main.cpp b/src/level-main.cpp index ccfa060..71999ce 100644 --- a/src/level-main.cpp +++ b/src/level-main.cpp @@ -3,12 +3,18 @@ #include "pke-at-common.hpp" #include "pke-at-settings.hpp" -#include "pke/audio-types.hpp" -#include "pke/audio.hpp" -#include "pke/level.hpp" + +#include <pke/pke.hpp> struct pke_level_main_master { - pke_level *level; + pke_level *level = nullptr; + struct pke_level_main_master_ui { + pke_ui_box *ctrls = nullptr; + pke_ui_box *btn_play_pause = nullptr; + pke_ui_box *btn_stop = nullptr; + pke_ui_box *btn_prev_track = nullptr; + pke_ui_box *btn_next_track = nullptr; + } ui; } main_mstr; pke_level *pke_at_level_main_create() { @@ -19,28 +25,197 @@ pke_level *pke_at_level_main_create() { return main_mstr.level; } +void dbg_print_box_states(const pke_ui_box *box) { + fprintf(stdout, "[dbg_print_box_states] x:y | w:h | %f:%f | %f:%f\n", box->internal.px_corner.x, box->internal.px_corner.y, box->internal.px_size.x, box->internal.px_size.y); + fprintf(stdout, "[dbg_print_box_states] pad rblt | %f:%f:%f:%f\n", box->internal.px_padding_r, box->internal.px_padding_b, box->internal.px_padding_l, box->internal.px_padding_t); + fprintf(stdout, "[dbg_print_box_states] bgcolr | %f:%f:%f:%f\n", box->color_background.r, box->color_background.g, box->color_background.b, box->color_background.a); + fprintf(stdout, "[dbg_print_box_states] border | %f:%f:%f:%f\n", box->color_border.r, box->color_border.g, box->color_border.b, box->color_border.a); +} + +void pke_at_level_main_recalc_ui() { + pke_ui_box *box = nullptr; + + box = main_mstr.ui.ctrls; + box->flags |= PKE_UI_BOX_FLAG_POSITION_TYPE_STATIC; + box->color_border = glm::vec4(0,0,0,0); + box->color_background = glm::vec4(0,0,0,0); + box->flags |= PKE_UI_BOX_FLAG_CENTER_HORIZONTAL; + box->min_size.x = Extent.width - 2; + box->min_size.y = 50; + box->max_size.x = Extent.width; + box->max_size.y = 50; + box->pos_top_left.x = 0; + box->pos_top_left.y = Extent.height - (box->min_size.y + 1); + + box = main_mstr.ui.btn_prev_track; + box->color_border = glm::vec4(1,1,1,1); + box->color_background = glm::vec4(1,0,0,1); + box->flags |= PKE_UI_BOX_FLAG_POSITION_TYPE_FLEX; + box->flex_weight = 1; + box->flex_direction = 0; + box->min_size.x = 0; + box->min_size.y = 0; + box->max_size.x = Extent.width; + box->max_size.y = Extent.height; + box->pos_top_left.x = 0; + box->pos_top_left.y = 0; + + box = main_mstr.ui.btn_play_pause; + box->color_border = glm::vec4(1,1,1,1); + box->color_background = glm::vec4(0,1,0,1); + box->flags |= PKE_UI_BOX_FLAG_POSITION_TYPE_FLEX; + box->flex_weight = 2; + box->flex_direction = 0; + box->min_size.x = 0; + box->min_size.y = 0; + box->max_size.x = Extent.width; + box->max_size.y = Extent.height; + box->pos_top_left.x = 0; + box->pos_top_left.y = 0; + + box = main_mstr.ui.btn_stop; + box->color_border = glm::vec4(1,1,1,1); + box->color_background = glm::vec4(0.5,0.5,0,1); + box->flags |= PKE_UI_BOX_FLAG_POSITION_TYPE_FLEX; + box->flex_weight = 1; + box->flex_direction = 0; + box->min_size.x = 0; + box->min_size.y = 0; + box->max_size.x = Extent.width; + box->max_size.y = Extent.height; + box->pos_top_left.x = 0; + box->pos_top_left.y = 0; + + box = main_mstr.ui.btn_next_track; + box->color_border = glm::vec4(1,1,1,1); + box->color_background = glm::vec4(0,0,1,1); + box->flags |= PKE_UI_BOX_FLAG_POSITION_TYPE_FLEX; + box->flex_weight = 1; + box->flex_direction = 0; + box->min_size.x = 0; + box->min_size.y = 0; + box->max_size.x = Extent.width; + box->max_size.y = Extent.height; + box->pos_top_left.x = 0; + box->pos_top_left.y = 0; + + pke_ui_force_recalc(); +} + +void pke_at_level_main_btn_prev_cb(void *ev_data, void *cb_data, void *em_data) { + (void)ev_data; + (void)cb_data; + (void)em_data; + // TODO +} + +void pke_at_level_main_btn_play_pause_cb(void *ev_data, void *cb_data, void *em_data) { + (void)ev_data; + (void)cb_data; + (void)em_data; + if (!PK_HAS_FLAG(g_at.rt.flags, PKE_AT_RUNTIME_FLAG_PLAYING)) { + g_at.rt.flags |= PKE_AT_RUNTIME_FLAG_PLAYING; + FontType_UpdateStringRenderText(main_mstr.ui.btn_play_pause->type_data->button_text.font_render_handle, cstring_to_pk_cstr("Pause")); + return; + } + if (!PK_HAS_FLAG(g_at.rt.flags, PKE_AT_RUNTIME_FLAG_PAUSED)) { + g_at.rt.flags |= PKE_AT_RUNTIME_FLAG_PAUSED; + FontType_UpdateStringRenderText(main_mstr.ui.btn_play_pause->type_data->button_text.font_render_handle, cstring_to_pk_cstr("Resume")); + } else { + g_at.rt.flags &= ~PKE_AT_RUNTIME_FLAG_PAUSED; + FontType_UpdateStringRenderText(main_mstr.ui.btn_play_pause->type_data->button_text.font_render_handle, cstring_to_pk_cstr("Pause")); + } +} + +void pke_at_level_main_btn_stop_cb(void *ev_data, void *cb_data, void *em_data) { + (void)ev_data; + (void)cb_data; + (void)em_data; + g_at.rt.flags &= ~(PKE_AT_RUNTIME_FLAG_PLAYING | PKE_AT_RUNTIME_FLAG_PAUSED); + pke_at_bpm_reset(g_at.bpm.target); + FontType_UpdateStringRenderText(main_mstr.ui.btn_play_pause->type_data->button_text.font_render_handle, cstring_to_pk_cstr("Play")); +} + +void pke_at_level_main_btn_next_cb(void *ev_data, void *cb_data, void *em_data) { + (void)ev_data; + (void)cb_data; + (void)em_data; + // TODO +} + void pke_at_level_main_init() { - pke_ui_box *hello_world = pke_ui_box_new_root(); - hello_world->flags |= PKE_UI_BOX_FLAG_POSITION_TYPE_DYNAMIC; - hello_world->flags |= PKE_UI_BOX_FLAG_CENTER_BOTH; - hello_world->min_size = glm::vec2(0.9); - hello_world->max_size = glm::vec2(0.9); - pke_level_register_root_ui_box(main_mstr.level, hello_world); + FontRenderSettings frs{}; + pke_ui_box *ctrls = pke_ui_box_new_root(); + pke_level_register_root_ui_box(main_mstr.level, ctrls); + main_mstr.ui.ctrls = ctrls; + + pke_ui_box *btn_prev_track = pke_ui_box_new_child(ctrls, PKE_UI_BOX_TYPE_BUTTON_TEXT); + main_mstr.ui.btn_prev_track = btn_prev_track; + frs.char_scale = 12; + frs.color_background = glm::vec4(0,0,0,1); + frs.color_foreground = glm::vec4(1,0,0,1); + frs.surface_area_type_flags = FONT_RENDER_SURFACE_AREA_TYPE_FLAGS_CENTER_BOTH; + FontRenderHandle fr_prev = FontType_AddStringRender(FontTypeIndex{0}, cstring_to_pk_cstr(" < "), &frs); + btn_prev_track->type_data->button_text.font_render_handle = fr_prev; + pke_component_event *prev_ev = ECS_CreateEv(btn_prev_track, pk_uuid_max); + pk_ev_register_cb(prev_ev->ev_mgr_id, prev_ev->ev_id, pke_at_level_main_btn_prev_cb, nullptr); + btn_prev_track->type_data->button_text.pke_event_handle = prev_ev->pke_event_handle; + + pke_ui_box *btn_play_pause = pke_ui_box_new_child(ctrls, PKE_UI_BOX_TYPE_BUTTON_TEXT); + main_mstr.ui.btn_play_pause = btn_play_pause; + frs.char_scale = 12; + frs.color_background = glm::vec4(0,0,0,1); + frs.color_foreground = glm::vec4(0,1,0,1); + frs.surface_area_type_flags = FONT_RENDER_SURFACE_AREA_TYPE_FLAGS_CENTER_BOTH; + FontRenderHandle fr_play = FontType_AddStringRender(FontTypeIndex{0}, cstring_to_pk_cstr(" Play "), &frs); + btn_play_pause->type_data->button_text.font_render_handle = fr_play; + pke_component_event *play_pause_ev = ECS_CreateEv(btn_play_pause, pk_uuid_max); + pk_ev_register_cb(play_pause_ev->ev_mgr_id, play_pause_ev->ev_id, pke_at_level_main_btn_play_pause_cb, nullptr); + btn_play_pause->type_data->button_text.pke_event_handle = play_pause_ev->pke_event_handle; + + pke_ui_box *btn_stop = pke_ui_box_new_child(ctrls, PKE_UI_BOX_TYPE_BUTTON_TEXT); + main_mstr.ui.btn_stop = btn_stop; + frs.char_scale = 12; + frs.color_background = glm::vec4(0,0,0,1); + frs.color_foreground = glm::vec4(0.5,0.5,0,1); + frs.surface_area_type_flags = FONT_RENDER_SURFACE_AREA_TYPE_FLAGS_CENTER_BOTH; + FontRenderHandle fr_stop = FontType_AddStringRender(FontTypeIndex{0}, cstring_to_pk_cstr(" Stop "), &frs); + btn_stop->type_data->button_text.font_render_handle = fr_stop; + pke_component_event *stop_ev = ECS_CreateEv(btn_stop, pk_uuid_max); + pk_ev_register_cb(stop_ev->ev_mgr_id, stop_ev->ev_id, pke_at_level_main_btn_stop_cb, nullptr); + btn_stop->type_data->button_text.pke_event_handle = stop_ev->pke_event_handle; + + pke_ui_box *btn_next_track = pke_ui_box_new_child(ctrls, PKE_UI_BOX_TYPE_BUTTON_TEXT); + main_mstr.ui.btn_next_track = btn_next_track; + frs.char_scale = 12; + frs.color_background = glm::vec4(0,0,0,1); + frs.color_foreground = glm::vec4(0,0,1,1); + frs.surface_area_type_flags = FONT_RENDER_SURFACE_AREA_TYPE_FLAGS_CENTER_BOTH; + FontRenderHandle fr_next = FontType_AddStringRender(FontTypeIndex{0}, cstring_to_pk_cstr(" > "), &frs); + btn_next_track->type_data->button_text.font_render_handle = fr_next; + pke_component_event *next_ev = ECS_CreateEv(btn_next_track, pk_uuid_max); + pk_ev_register_cb(next_ev->ev_mgr_id, next_ev->ev_id, pke_at_level_main_btn_next_cb, nullptr); + btn_next_track->type_data->button_text.pke_event_handle = next_ev->pke_event_handle; + pke_at_bpm_reset(120); g_at.mtrnm.beep = pke_at_audio_get_or_generate_sawtooth(440.f, 0.30); g_at.mtrnm.beep_accent = pke_at_audio_get_or_generate_sawtooth(440.f * (3/2.f), 0.30); pke_audio_set_volume(pke_audio_source_sfx, 0.25); g_at.rt.flags = PKE_AT_RUNTIME_FLAG_NONE; + + pke_at_level_main_recalc_ui(); } void pke_at_level_main_tick(double delta) { + if (pkeSettings.rt.was_framebuffer_resized == true) { + pke_at_level_main_recalc_ui(); + } if (!PK_HAS_FLAG(g_at.rt.flags, PKE_AT_RUNTIME_FLAG_PLAYING)) { return; } if (PK_HAS_FLAG(g_at.rt.flags, PKE_AT_RUNTIME_FLAG_PAUSED)) { return; } - g_at.bpm.delta_since_last_beat += delta; if (g_at.bpm.lerp_delta <= g_at.bpm.lerp_delta_duration) { g_at.bpm.lerp_delta += delta; g_at.bpm.current = std::lerp(g_at.bpm.last, g_at.bpm.target, g_at.bpm.lerp_delta / g_at.bpm.lerp_delta_duration); @@ -52,10 +227,8 @@ void pke_at_level_main_tick(double delta) { if (g_at.bpm.delta_since_last_beat >= g_at.bpm.delta_per_beat) { if (g_at.mtrnm.beat == 0) { pke_audio_play(g_at.mtrnm.beep_accent, pke_audio_source_sfx, pke_audio_flag_none); - fprintf(stdout, "beat accent %f\n", delta); } else { pke_audio_play(g_at.mtrnm.beep, pke_audio_source_sfx, pke_audio_flag_none); - fprintf(stdout, "beat %f\n", delta); } g_at.bpm.delta_since_last_beat = std::fmod(g_at.bpm.delta_since_last_beat, g_at.bpm.delta_per_beat); g_at.mtrnm.beat += 1; diff --git a/src/pke-at-common.cpp b/src/pke-at-common.cpp index a2a290f..8372bcc 100644 --- a/src/pke-at-common.cpp +++ b/src/pke-at-common.cpp @@ -12,7 +12,7 @@ void pke_at_bpm_reset(uint8_t bpm) { g_at.bpm.lerp_delta = 0.f; g_at.bpm.lerp_delta_duration = 0.f; g_at.bpm.delta_per_beat = 60.f / (double)bpm; - g_at.bpm.delta_since_last_beat = 0.f; + g_at.bpm.delta_since_last_beat = BEEP_IMMEDIATELY_VAL; g_at.mtrnm.beat = 0; g_at.mtrnm.beats_per_bar = 4; } diff --git a/src/pke-at-settings.hpp b/src/pke-at-settings.hpp index 2bed25a..fe4ee1c 100644 --- a/src/pke-at-settings.hpp +++ b/src/pke-at-settings.hpp @@ -4,6 +4,8 @@ #include "pke/asset-manager.hpp" #include "pke/pk.h" +#define BEEP_IMMEDIATELY_VAL 99999999.f + enum PKE_AT_RUNTIME_FLAGS : uint32_t { PKE_AT_RUNTIME_FLAG_NONE = 0, PKE_AT_RUNTIME_FLAG_PLAYING = (1u << 0), |
