diff --git a/controller/hid-test.py b/controller/hid-test.py index d692db4..7a8c338 100755 --- a/controller/hid-test.py +++ b/controller/hid-test.py @@ -22,6 +22,7 @@ def main(): h.pregame(RiotPlayerInfo.dummy(valorant=ValorantPlayerInfo(map='/Game/Maps/Bonsai/Bonsai'))) h.match_found(RiotPlayerInfo.dummy(valorant=ValorantPlayerInfo())) h.pregame(RiotPlayerInfo.dummy(valorant=ValorantPlayerInfo())) + h.game_generic(RiotPlayerInfo.dummy(valorant=ValorantPlayerInfo(queue_type='ggteam'))) h.service() finally: diff --git a/controller/valconomy.py b/controller/valconomy.py index c8042e1..6ff46e7 100644 --- a/controller/valconomy.py +++ b/controller/valconomy.py @@ -319,6 +319,24 @@ class HIDValconomyHandler(ValconomyHandler): def pregame(self, info: RiotPlayerInfo): self._enq(5, 1 if info.valorant.map == '/Game/Maps/Bonsai/Bonsai' else 0, fmt='B') + def game_generic(self, info: RiotPlayerInfo): + match info.valorant.queue_type: + case 'hurm': # tdm + gm = 0 + case 'deathmatch': + gm = 1 + case 'ggteam': # escalation + gm = 2 + case 'spikerush': + gm = 3 + case _: + if info.valorant.max_party_size == 12: # custom + gm = 4 + else: + gm = 5 + + self._enq(6, gm, fmt='B') + class GameState(Enum): NONE = 0 MENU = 1 diff --git a/firmware/main/ui.c b/firmware/main/ui.c index 699bc02..31f89e9 100644 --- a/firmware/main/ui.c +++ b/firmware/main/ui.c @@ -3,6 +3,14 @@ #include "ui.h" static const char* M_VAL_TIME = "VAL TIME?"; +const char *val_ext_gamemodes[] = { + "TDM", + "DEATHMATCH", + "ESCALATION", + "SPIKE RUSH", + "CUSTOM", + "GAME", +}; static const lv_font_t *font_normal = &lv_font_montserrat_24; @@ -441,6 +449,53 @@ void val_ui_pregame(bool is_split) { lv_anim_timeline_start(at_active); } +void val_ui_game_generic(const char *gamemode) { + 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, "HAVE FUN!"); + + 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_fmt(l_subtitle, "ENJOY YOUR %s!", gamemode); + + lv_obj_update_layout(o_active); + lv_obj_set_y( + l_subtitle, + (lv_obj_get_height(l_main) + lv_obj_get_height(l_subtitle)) / 2 + 5); + + // 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_bounce); + 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, + -(lv_obj_get_width(l_main) - lv_obj_get_width(l_subtitle)) / 2); + lv_anim_set_exec_cb(&a_sub, anim_x_cb); + lv_anim_set_path_cb(&a_sub, lv_anim_path_bounce); + 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); + 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); diff --git a/firmware/main/ui.h b/firmware/main/ui.h index d10065e..5293328 100644 --- a/firmware/main/ui.h +++ b/firmware/main/ui.h @@ -2,6 +2,9 @@ #include "lvgl.h" +extern const char *val_ext_gamemodes[]; +#define VAL_EXT_GAMEMODES_SIZE 6 + LV_FONT_DECLARE(lv_font_tungsten_40) LV_FONT_DECLARE(lv_font_tungsten_180) @@ -18,5 +21,6 @@ void val_ui_idle(); void val_ui_queue_start(bool ms_not_comp); void val_ui_match_found(bool is_premier); void val_ui_pregame(bool is_split); +void val_ui_game_generic(const char *gamemode); void val_lvgl_ui(lv_display_t *disp); diff --git a/firmware/main/usb.c b/firmware/main/usb.c index 4e50b1c..10a1b99 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_PREGAME) { + if (buf[0] > ST_GAME_GENERIC) { ESP_LOGW(TAG, "Unknown state %hhu", buf[0]); goto ret; } @@ -144,6 +144,13 @@ void tud_hid_set_report_cb(uint8_t instance, uint8_t report_id, hid_report_type_ } val_ui_pregame((bool)buf[1]); break; + case ST_GAME_GENERIC: + if (bufsize < 2 || buf[1] > VAL_EXT_GAMEMODES_SIZE) { + ESP_LOGE(TAG, "Invalid ST_PREGAME command"); + goto ret; + } + val_ui_game_generic(val_ext_gamemodes[buf[1]]); + break; } ret: diff --git a/firmware/main/usb.h b/firmware/main/usb.h index 90da7a7..26334a2 100644 --- a/firmware/main/usb.h +++ b/firmware/main/usb.h @@ -12,6 +12,7 @@ typedef enum val_state { ST_QUEUE_START, ST_MATCH_FOUND, ST_PREGAME, + ST_GAME_GENERIC, } val_state_t; void val_usb_init(void);