summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Bradley <jcb@pikum.xyz>2025-10-02 10:56:30 -0400
committerJonathan Bradley <jcb@pikum.xyz>2025-10-02 10:56:30 -0400
commitcc8653536c499df4b85aae423ad6b27bb74544be (patch)
treec1d91873ee5f1672a773615699353ee866d06d36
parent3545969b61ccc5a19653309ab19d1c2c9eb729f1 (diff)
pke-at: metronome start+stop buttons
-rw-r--r--src/level-main.cpp199
-rw-r--r--src/pke-at-common.cpp2
-rw-r--r--src/pke-at-settings.hpp2
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),