diff --git a/controller/hid-test.py b/controller/hid-test.py index 0a84d14..1033c2e 100755 --- a/controller/hid-test.py +++ b/controller/hid-test.py @@ -2,6 +2,7 @@ import logging import valconomy +from valconomy import ValorantPlayerInfo, RiotPlayerInfo def main(): logging.basicConfig( @@ -11,8 +12,12 @@ def main(): try: h.menu(None, False) h.none() + h.queue_start(RiotPlayerInfo.dummy( + valorant=ValorantPlayerInfo())) h.menu(None, True) h.idle(None) + h.queue_start(RiotPlayerInfo.dummy( + valorant=ValorantPlayerInfo(queue_type='unrated', is_party_owner=True))) h.service() finally: diff --git a/controller/valconomy.py b/controller/valconomy.py index 8130204..800f50d 100644 --- a/controller/valconomy.py +++ b/controller/valconomy.py @@ -48,6 +48,10 @@ class RiotPlayerInfo: valorant: ValorantPlayerInfo = None + @classmethod + def dummy(cls, **kwargs): + return cls('00000000-0000-0000-0000-000000000000', 'Player', 'gamer', 'dnd', **kwargs) + def full_name(self) -> str: return f'{self.name}#{self.tag}' @@ -305,6 +309,10 @@ class HIDValconomyHandler(ValconomyHandler): def idle(self, info: RiotPlayerInfo): self._enq(2) + def queue_start(self, info: RiotPlayerInfo): + ms_not_comp = info.valorant.is_party_owner and info.valorant.queue_type == 'unrated' + self._enq(3, 1 if ms_not_comp else 0, fmt='B') + class GameState(Enum): NONE = 0 MENU = 1 diff --git a/firmware/main/ui.c b/firmware/main/ui.c index dc1d7b9..f436732 100644 --- a/firmware/main/ui.c +++ b/firmware/main/ui.c @@ -39,8 +39,8 @@ static const void* imgfont_get_path( static void b_cfg_cb(lv_event_t *e) { lv_obj_t *box = lv_msgbox_create(NULL); - lv_msgbox_add_title(box, "Hello"); - lv_msgbox_add_text(box, "test message"); + lv_msgbox_add_title(box, "Settings"); + lv_msgbox_add_text(box, "Sorry, there aren't any right now."); lv_msgbox_add_close_button(box); } @@ -89,10 +89,10 @@ static void anim_y_cb(void *var, int32_t v) { static void anim_opa_cb(void *var, int32_t v) { lv_obj_set_style_opa(var, v, 0); } + static void anim_val_time_text(lv_anim_t *anim) { lv_label_set_text_static(anim->var, M_VAL_TIME); } - void val_ui_none() { setup_next_state(); @@ -268,12 +268,91 @@ void val_ui_idle() { lv_anim_timeline_start(at_active); } +static void anim_text_color_mix_hero_sub(void *var, int32_t v) { + lv_obj_set_style_text_color( + var, lv_color_mix(color_text_hero, color_text_subtitle, v), 0); +} +void val_ui_queue_start(bool ms_not_comp) { + setup_next_state(); + + // Widgets + lv_obj_t *l_main = lv_label_create(o_active); + lv_obj_add_style(l_main, &s_hero, 0); + lv_obj_center(l_main); + lv_label_set_text_static(l_main, "SEARCHING..."); + + lv_obj_t *l_subtitle = lv_label_create(o_active); + lv_obj_add_style(l_subtitle, &s_subtitle, 0); + lv_obj_center(l_subtitle); + lv_label_set_text_static(l_subtitle, ms_not_comp ? "UHHH SHOULD THAT BE COMP?" : "I HOPE IT'S NOT SPLIT..."); + + lv_obj_t *spinner = lv_spinner_create(o_active); + lv_obj_set_size(spinner, 100, 100); + lv_obj_center(spinner); + lv_obj_set_style_arc_color(spinner, color_text_hero, LV_PART_INDICATOR); + lv_spinner_set_anim_params(spinner, 1500, 200); + + lv_obj_update_layout(o_active); + const int32_t offset = -60; + lv_obj_set_y(l_main, offset); + lv_obj_set_y( + l_subtitle, + offset + (lv_obj_get_height(l_main) + lv_obj_get_height(l_subtitle)) / 2 + 5); + lv_obj_set_y( + spinner, + lv_obj_get_height(o_container) / 4); + // offset + (lv_obj_get_height(l_main)/2) + lv_obj_get_height(l_subtitle) + (lv_obj_get_height(spinner)/2) + 15); + + // Animations + lv_anim_t a_title; + lv_anim_init(&a_title); + lv_anim_set_var(&a_title, l_main); + lv_anim_set_values( + &a_title, + -(lv_obj_get_width(o_container) - lv_obj_get_width(l_main)) / 2, 0); + lv_anim_set_exec_cb(&a_title, anim_x_cb); + lv_anim_set_path_cb(&a_title, lv_anim_path_ease_out); + lv_anim_set_duration(&a_title, 750); + + lv_anim_t a_sub; + lv_anim_init(&a_sub); + lv_anim_set_var(&a_sub, l_subtitle); + lv_anim_set_values( + &a_sub, + (lv_obj_get_width(o_container) - lv_obj_get_width(l_subtitle)) / 2, 0); + lv_anim_set_exec_cb(&a_sub, anim_x_cb); + lv_anim_set_path_cb(&a_sub, lv_anim_path_ease_out); + lv_anim_set_completed_cb(&a_sub, anim_state_ready_cb); + lv_anim_set_duration(&a_sub, 750); + + lv_anim_timeline_add(at_active, 0, &a_title); + lv_anim_timeline_add(at_active, 0, &a_sub); + + if (ms_not_comp) { + lv_anim_t a_warn; + lv_anim_init(&a_warn); + lv_anim_set_early_apply(&a_warn, false); + lv_anim_set_var(&a_warn, l_subtitle); + lv_anim_set_path_cb(&a_warn, lv_anim_path_linear); + lv_anim_set_duration(&a_warn, 1000); + lv_anim_set_exec_cb(&a_warn, anim_text_color_mix_hero_sub); + + lv_anim_set_values(&a_warn, 0, 255); + lv_anim_timeline_add(at_active_rep, 0, &a_warn); + + lv_anim_set_values(&a_warn, 255, 0); + lv_anim_timeline_add(at_active_rep, 1000, &a_warn); + } + + lv_anim_timeline_start(at_active); +} + void val_lvgl_ui(lv_display_t *disp) { color_primary = lv_color_hex(0xff4655); color_secondary = lv_color_hex(0xf7518f); color_text_hero = lv_palette_lighten(LV_PALETTE_GREY, 2); - color_text_subtitle = lv_palette_darken(LV_PALETTE_GREY, 2); + color_text_subtitle = lv_palette_darken(LV_PALETTE_GREY, 1); // init default theme lv_theme_default_init( diff --git a/firmware/main/ui.h b/firmware/main/ui.h index aa95ba8..9ebd4b1 100644 --- a/firmware/main/ui.h +++ b/firmware/main/ui.h @@ -15,5 +15,6 @@ bool val_ui_state_ready(); void val_ui_none(); void val_ui_menu(bool was_idle); void val_ui_idle(); +void val_ui_queue_start(bool ms_not_comp); void val_lvgl_ui(lv_display_t *disp); diff --git a/firmware/main/usb.c b/firmware/main/usb.c index 1a016fe..b92f299 100644 --- a/firmware/main/usb.c +++ b/firmware/main/usb.c @@ -101,7 +101,7 @@ void tud_hid_set_report_cb(uint8_t instance, uint8_t report_id, hid_report_type_ ESP_LOGE(TAG, "Failed to grab LVGL lock"); return; } - if (buf[0] > ST_IDLE) { + if (buf[0] > ST_QUEUE_START) { ESP_LOGW(TAG, "Unknown state %hhu", buf[0]); goto ret; } @@ -123,6 +123,13 @@ void tud_hid_set_report_cb(uint8_t instance, uint8_t report_id, hid_report_type_ case ST_IDLE: val_ui_idle(); break; + case ST_QUEUE_START: + if (bufsize < 2) { + ESP_LOGE(TAG, "Invalid ST_QUEUE_START command"); + goto ret; + } + val_ui_queue_start((bool)buf[1]); + break; } ret: diff --git a/firmware/main/usb.h b/firmware/main/usb.h index 204971b..9b6fc29 100644 --- a/firmware/main/usb.h +++ b/firmware/main/usb.h @@ -8,7 +8,8 @@ typedef enum val_state { ST_NONE = 0, ST_MENU, - ST_IDLE + ST_IDLE, + ST_QUEUE_START, } val_state_t; void val_usb_init(void);