#include #include #include "../pokemon_app.h" #include "pokemon_menu.h" struct named_pins { const char* text; const GpioPin* pin; }; static const struct named_pins named_pins[] = { {"PA7", &gpio_ext_pa7}, {"PA6", &gpio_ext_pa6}, {"PA4", &gpio_ext_pa4}, {"PB3", &gpio_ext_pb3}, {"PB2", &gpio_ext_pb2}, {"PC3", &gpio_ext_pc3}, {"PC1", &gpio_ext_pc1}, {"PC0", &gpio_ext_pc0}, {}, }; #define NUM_PINS 8 /* This must match gblink's enum order */ static const char* named_groups[] = { "Original", "Malveke", "Custom", "", }; struct itemlist_builder { VariableItem* named; VariableItem* serin; VariableItem* serout; VariableItem* clk; uint8_t named_index; uint8_t serin_index; uint8_t serout_index; uint8_t clk_index; }; /* Just make it a global, whatever */ static struct itemlist_builder builder = {0}; static void select_pins_rebuild_list(PokemonFap* pokemon_fap); static void select_pins_set(PokemonFap* pokemon_fap) { pokemon_fap->pins.serin = named_pins[builder.serin_index].pin; pokemon_fap->pins.serout = named_pins[builder.serout_index].pin; pokemon_fap->pins.clk = named_pins[builder.clk_index].pin; } static void select_named_group_callback(VariableItem* item) { uint8_t index = variable_item_get_current_value_index(item); PokemonFap* pokemon_fap = variable_item_get_context(item); variable_item_set_current_value_text(item, named_groups[index]); builder.named_index = index; select_pins_rebuild_list(pokemon_fap); variable_item_list_set_selected_item(pokemon_fap->variable_item_list, 0); } static void select_pins_serin_callback(VariableItem* item) { uint8_t index = variable_item_get_current_value_index(item); PokemonFap* pokemon_fap = variable_item_get_context(item); variable_item_set_current_value_text(item, named_pins[index].text); builder.serin_index = index; select_pins_rebuild_list(pokemon_fap); variable_item_list_set_selected_item(pokemon_fap->variable_item_list, 1); } static void select_pins_serout_callback(VariableItem* item) { uint8_t index = variable_item_get_current_value_index(item); PokemonFap* pokemon_fap = variable_item_get_context(item); variable_item_set_current_value_text(item, named_pins[index].text); builder.serout_index = index; select_pins_rebuild_list(pokemon_fap); variable_item_list_set_selected_item(pokemon_fap->variable_item_list, 2); } static void select_pins_clk_callback(VariableItem* item) { uint8_t index = variable_item_get_current_value_index(item); PokemonFap* pokemon_fap = variable_item_get_context(item); variable_item_set_current_value_text(item, named_pins[index].text); builder.clk_index = index; select_pins_rebuild_list(pokemon_fap); variable_item_list_set_selected_item(pokemon_fap->variable_item_list, 3); } static void select_pins_rebuild_list(PokemonFap* pokemon_fap) { int num; /* HACK: TODO: It would be better to do this programmatically, but, I'm kind * of done working on this feature so its going to be hardcoded for now. */ switch(builder.named_index) { case 0: // Original num = 1; builder.serin_index = 5; builder.serout_index = 3; builder.clk_index = 4; break; case 1: // MALVEKE num = 1; builder.serin_index = 1; builder.serout_index = 0; builder.clk_index = 3; break; default: num = NUM_PINS; break; } /* HACK: */ pokemon_fap->malveke_detected = builder.named_index; select_pins_set(pokemon_fap); variable_item_list_reset(pokemon_fap->variable_item_list); builder.named = variable_item_list_add( pokemon_fap->variable_item_list, "Mode", 3, select_named_group_callback, pokemon_fap); builder.serin = variable_item_list_add( pokemon_fap->variable_item_list, "SI:", num, select_pins_serin_callback, pokemon_fap); builder.serout = variable_item_list_add( pokemon_fap->variable_item_list, "SO:", num, select_pins_serout_callback, pokemon_fap); builder.clk = variable_item_list_add( pokemon_fap->variable_item_list, "CLK:", num, select_pins_clk_callback, pokemon_fap); variable_item_set_current_value_index(builder.named, builder.named_index); variable_item_set_current_value_text(builder.named, named_groups[builder.named_index]); variable_item_set_current_value_index(builder.serin, (num == 1 ? 0 : builder.serin_index)); variable_item_set_current_value_text(builder.serin, named_pins[builder.serin_index].text); variable_item_set_current_value_index(builder.serout, (num == 1 ? 0 : builder.serout_index)); variable_item_set_current_value_text(builder.serout, named_pins[builder.serout_index].text); variable_item_set_current_value_index(builder.clk, (num == 1 ? 0 : builder.clk_index)); variable_item_set_current_value_text(builder.clk, named_pins[builder.clk_index].text); } void select_pins_scene_on_exit(void* context) { PokemonFap* pokemon_fap = (PokemonFap*)context; view_dispatcher_switch_to_view(pokemon_fap->view_dispatcher, AppViewMainMenu); view_dispatcher_remove_view(pokemon_fap->view_dispatcher, AppViewOpts); } void select_pins_scene_on_enter(void* context) { PokemonFap* pokemon_fap = (PokemonFap*)context; /* TODO: Figure out what defaults we should use for pins based on attached board! */ /* HACK: */ if(builder.named_index < 2) builder.named_index = pokemon_fap->malveke_detected; select_pins_rebuild_list(pokemon_fap); view_dispatcher_add_view( pokemon_fap->view_dispatcher, AppViewOpts, variable_item_list_get_view(pokemon_fap->variable_item_list)); view_dispatcher_switch_to_view(pokemon_fap->view_dispatcher, AppViewOpts); }