#include "level-main.hpp" #include "pke-at-common.hpp" #include "pke-at-settings.hpp" #include struct pke_level_main_master { 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() { main_mstr.level = pke_level_create("main", pk_uuid_zed, pk_uuid_zed); main_mstr.level->pke_cb_spinup.func = pke_at_level_main_init; main_mstr.level->pke_cb_tick.func = (void(*)())pke_at_level_main_tick; main_mstr.level->pke_cb_teardown.func = pke_at_level_main_teardown; 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() { 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; } 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); } else { g_at.bpm.current = g_at.bpm.target; } g_at.bpm.delta_per_beat = 60.f / g_at.bpm.current; g_at.bpm.delta_since_last_beat += 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); } else { pke_audio_play(g_at.mtrnm.beep, pke_audio_source_sfx, pke_audio_flag_none); } 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; g_at.mtrnm.beat %= g_at.mtrnm.beats_per_bar; } } void pke_at_level_main_teardown() { main_mstr.level = nullptr; }