diff --git a/pokemon_app.cpp b/pokemon_app.cpp index ffad2a5410f..58a8c24709c 100644 --- a/pokemon_app.cpp +++ b/pokemon_app.cpp @@ -1,6 +1,8 @@ #include "pokemon_app.h" +#include "views/trade.hpp" +#include "views/select_pokemon.hpp" -struct pokemon_lut pokemon_table[] = { +const PokemonTable pokemon_table[] = { {"Bulbasaur", &I_bulbasaur, 0x99}, {"Ivysaur", &I_ivysaur, 0x09}, {"Venusaur", &I_venusaur, 0x9A}, @@ -159,66 +161,77 @@ uint32_t pokemon_exit_confirm_view(void* context) { UNUSED(context); return AppViewExitConfirm; } -App* pokemon_alloc() { - App* app = (App*)malloc(sizeof(App)); + +PokemonFap* pokemon_alloc() { + PokemonFap* pokemon_fap = (PokemonFap*)malloc(sizeof(PokemonFap)); // Gui - app->gui = (Gui*)furi_record_open(RECORD_GUI); + /* XXX: what is furi_record open for? It doesn't return a Gui handle. */ + pokemon_fap->gui = (Gui*)furi_record_open(RECORD_GUI); + // View dispatcher - app->view_dispatcher = view_dispatcher_alloc(); + pokemon_fap->view_dispatcher = view_dispatcher_alloc(); - view_dispatcher_enable_queue(app->view_dispatcher); - view_dispatcher_set_event_callback_context(app->view_dispatcher, app); - view_dispatcher_attach_to_gui(app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen); + view_dispatcher_enable_queue(pokemon_fap->view_dispatcher); + view_dispatcher_set_event_callback_context(pokemon_fap->view_dispatcher, pokemon_fap); + view_dispatcher_attach_to_gui( + pokemon_fap->view_dispatcher, pokemon_fap->gui, ViewDispatcherTypeFullscreen); // Start Index first pokemon - app->current_pokemon = 0; + pokemon_fap->curr_pokemon = 0; + + // Set up pointer to pokemon table + pokemon_fap->pokemon_table = pokemon_table; + // Select Pokemon View - app->select_pokemon = select_pokemon_alloc(app); - view_set_previous_callback(select_pokemon_get_view(app), pokemon_exit_confirm_view); + pokemon_fap->select_view = select_pokemon_alloc(pokemon_fap); + view_set_previous_callback(select_pokemon_get_view(pokemon_fap), pokemon_exit_confirm_view); view_dispatcher_add_view( - app->view_dispatcher, AppViewSelectPokemon, select_pokemon_get_view(app)); + pokemon_fap->view_dispatcher, AppViewSelectPokemon, select_pokemon_get_view(pokemon_fap)); // Trade View - app->trade = trade_alloc(app); - view_set_previous_callback(trade_get_view(app), pokemon_exit_confirm_view); - view_dispatcher_add_view(app->view_dispatcher, AppViewTrade, trade_get_view(app)); + pokemon_fap->trade_view = trade_alloc(pokemon_fap); + view_set_previous_callback(pokemon_fap->trade_view, pokemon_exit_confirm_view); + view_dispatcher_add_view(pokemon_fap->view_dispatcher, AppViewTrade, pokemon_fap->trade_view); - view_dispatcher_switch_to_view(app->view_dispatcher, AppViewSelectPokemon); + view_dispatcher_switch_to_view(pokemon_fap->view_dispatcher, AppViewSelectPokemon); - return app; + return pokemon_fap; } -void free_app(App* app) { - furi_assert(app); +void free_app(PokemonFap* pokemon_fap) { + furi_assert(pokemon_fap); // Free views - view_dispatcher_remove_view(app->view_dispatcher, AppViewSelectPokemon); - select_pokemon_free(app); - view_dispatcher_remove_view(app->view_dispatcher, AppViewTrade); - trade_free(app); + view_dispatcher_remove_view(pokemon_fap->view_dispatcher, AppViewSelectPokemon); + /* XXX: Still need to deal with select_pokemon code */ + select_pokemon_free(pokemon_fap); + view_dispatcher_remove_view(pokemon_fap->view_dispatcher, AppViewTrade); + trade_free(pokemon_fap); // Close records furi_record_close(RECORD_GUI); - app->gui = NULL; + /* XXX: Since furi_record doesn't appear to be a Gui function, it wouldn't clear the pointer */ + pokemon_fap->gui = NULL; // Free rest - free(app); + free(pokemon_fap); + pokemon_fap = NULL; } extern "C" int32_t pokemon_app(void* p) { UNUSED(p); //FURI_LOG_D(TAG, "init scene"); - App* app = (App*)pokemon_alloc(); + //App* app = (App*)pokemon_alloc(); + PokemonFap* pokemon_fap = pokemon_alloc(); furi_hal_light_set(LightRed, 0x00); furi_hal_light_set(LightGreen, 0x00); furi_hal_light_set(LightBlue, 0x00); //switch view and run dispatcher - view_dispatcher_run(app->view_dispatcher); + view_dispatcher_run(pokemon_fap->view_dispatcher); // Free resources - free_app(app); - furi_record_close(RECORD_GUI); + free_app(pokemon_fap); return 0; } diff --git a/pokemon_app.h b/pokemon_app.h index 574a89f9f47..43b957d995d 100644 --- a/pokemon_app.h +++ b/pokemon_app.h @@ -10,18 +10,16 @@ #include #include -#include "views/select_pokemon.hpp" -#include "views/trade.hpp" - #define TAG "Pokemon" -struct pokemon_lut { +struct pokemon_data_table { const char* name; const Icon* icon; const uint8_t hex; }; -typedef struct App App; +typedef struct pokemon_data_table PokemonTable; + typedef enum { GAMEBOY_INITIAL, GAMEBOY_READY, @@ -32,6 +30,7 @@ typedef enum { GAMEBOY_TRADING } render_gameboy_state_t; +#if 0 struct App { Gui* gui; ViewDispatcher* view_dispatcher; @@ -42,6 +41,37 @@ struct App { int current_pokemon = 0; char pokemon_hex_code = ' '; }; +#endif + +struct pokemon_fap { + Gui* gui; + ViewDispatcher* view_dispatcher; + + /* View ports for each of the application's steps */ + View* select_view; + View* trade_view; + + /* Table of pokemon data for Gen I */ + const PokemonTable* pokemon_table; + + /* The currently selected pokemon */ + int curr_pokemon; + + /* Some state tracking */ + /* This, combined with some globals in trade.cpp, can probably be better + * consolidated at some point. + */ + bool trading; + bool connected; + render_gameboy_state_t gameboy_status; + + /* TODO: Other variables will end up here, like selected level, EV/IV, + * moveset, etc. Likely will want to be another sub struct similar to + * the actual pokemon data structure. + */ +}; + +typedef struct pokemon_fap PokemonFap; typedef enum { AppViewSelectPokemon, @@ -49,17 +79,4 @@ typedef enum { AppViewExitConfirm, } AppView; -typedef void (*SelectPokemonCallback)(void* context, uint32_t index); -typedef struct SelectPokemonModel { - int current_pokemon = 0; - char pokemon_hex_code = ' '; - bool trading = false; - bool connected = false; - render_gameboy_state_t gameboy_status = GAMEBOY_INITIAL; - SelectPokemonCallback callback; - void* callback_context; -} SelectPokemonModel; - -extern struct pokemon_lut pokemon_table[]; - #endif /* POKEMON_APP_H */ diff --git a/views/select_pokemon.cpp b/views/select_pokemon.cpp index 08c7daa8899..7ca7430e086 100644 --- a/views/select_pokemon.cpp +++ b/views/select_pokemon.cpp @@ -1,11 +1,9 @@ #include "../pokemon_app.h" #include "select_pokemon.hpp" -static void select_pokemon_render_callback(Canvas* canvas, void* context) { - canvas_clear(canvas); - - SelectPokemonModel* model = (SelectPokemonModel*)context; - const uint8_t current_index = model->current_pokemon; +static void select_pokemon_render_callback(Canvas* canvas, void* model) { + PokemonFap* pokemon_fap = *(PokemonFap**)model; + const uint8_t current_index = pokemon_fap->curr_pokemon; char pokedex_num[5]; snprintf(pokedex_num, sizeof(pokedex_num), "#%03d", current_index + 1); @@ -15,7 +13,7 @@ static void select_pokemon_render_callback(Canvas* canvas, void* context) { canvas_set_font(canvas, FontSecondary); canvas_draw_str_aligned(canvas, 55, 38, AlignLeft, AlignTop, pokedex_num); - canvas_draw_icon(canvas, 0, 0, pokemon_table[current_index].icon); + canvas_draw_icon(canvas, 0, 0, pokemon_fap->pokemon_table[current_index].icon); canvas_draw_icon(canvas, 128 - 80, 0, &I_Space_80x18); canvas_draw_str_aligned(canvas, (128 - 40), 5, AlignCenter, AlignTop, "Select Pokemon"); @@ -24,104 +22,64 @@ static void select_pokemon_render_callback(Canvas* canvas, void* context) { } static bool select_pokemon_input_callback(InputEvent* event, void* context) { - furi_assert(context); - SelectPokemon* select_pokemon = (SelectPokemon*)context; + PokemonFap* pokemon_fap = (PokemonFap*)context; bool consumed = false; + furi_assert(context); + /* We only handle InputTypePress at the moment */ if(event->type != InputTypePress) return consumed; switch(event->key) { /* Advance to next view with the selected pokemon */ case InputKeyOk: - with_view_model_cpp( - select_pokemon->view, - SelectPokemonModel*, - model, - { - select_pokemon->app->current_pokemon = model->current_pokemon; - select_pokemon->app->pokemon_hex_code = pokemon_table[model->current_pokemon].hex; - }, - false); - view_dispatcher_switch_to_view(select_pokemon->app->view_dispatcher, AppViewTrade); + view_dispatcher_switch_to_view(pokemon_fap->view_dispatcher, AppViewTrade); consumed = true; break; /* Return to the previous view */ case InputKeyBack: - view_dispatcher_switch_to_view(select_pokemon->app->view_dispatcher, VIEW_NONE); + view_dispatcher_switch_to_view(pokemon_fap->view_dispatcher, VIEW_NONE); consumed = true; break; /* Move back one through the pokedex listing */ case InputKeyLeft: - with_view_model_cpp( - select_pokemon->view, - SelectPokemonModel*, - model, - { - if(model->current_pokemon == 0) { - model->current_pokemon = 150; - } else { - model->current_pokemon--; - } - }, - true); + if(pokemon_fap->curr_pokemon == 0) + pokemon_fap->curr_pokemon = 150; + else + pokemon_fap->curr_pokemon--; consumed = true; break; - /* Move back ten through the pokemon listing, wrap to max pokemon on + /* Move back ten through the pokemon listing, wrap to max pokemon on * underflow. */ case InputKeyDown: - with_view_model_cpp( - select_pokemon->view, - SelectPokemonModel*, - model, - { - if(model->current_pokemon >= 10) { - model->current_pokemon -= 10; - } else { - model->current_pokemon = 150; - } - }, - true); + if(pokemon_fap->curr_pokemon >= 10) + pokemon_fap->curr_pokemon -= 10; + else + pokemon_fap->curr_pokemon = 150; consumed = true; break; /* Move forward one through the pokedex listing */ case InputKeyRight: - with_view_model_cpp( - select_pokemon->view, - SelectPokemonModel*, - model, - { - if(model->current_pokemon == 150) { - model->current_pokemon = 0; - } else { - model->current_pokemon++; - } - }, - true); + if(pokemon_fap->curr_pokemon == 150) + pokemon_fap->curr_pokemon = 0; + else + pokemon_fap->curr_pokemon++; consumed = true; break; - /* Move forward ten through the pokemon listing, wrap to min pokemon on + /* Move forward ten through the pokemon listing, wrap to min pokemon on * overflow. */ case InputKeyUp: - with_view_model_cpp( - select_pokemon->view, - SelectPokemonModel*, - model, - { - if(model->current_pokemon <= 140) { - model->current_pokemon += 10; - } else { - model->current_pokemon = 0; - } - }, - true); + if(pokemon_fap->curr_pokemon <= 140) + pokemon_fap->curr_pokemon += 10; + else + pokemon_fap->curr_pokemon = 0; consumed = true; break; @@ -139,10 +97,10 @@ void select_pokemon_enter_callback(void* context) { } bool select_pokemon_custom_callback(uint32_t event, void* context) { + PokemonFap* pokemon_fap = (PokemonFap*)context; UNUSED(event); furi_assert(context); - SelectPokemon* select_pokemon = (SelectPokemon*)context; - view_dispatcher_send_custom_event(select_pokemon->app->view_dispatcher, 0); + view_dispatcher_send_custom_event(pokemon_fap->view_dispatcher, 0); return true; } @@ -151,38 +109,31 @@ void select_pokemon_exit_callback(void* context) { UNUSED(context); } -SelectPokemon* select_pokemon_alloc(App* app) { - SelectPokemon* select_pokemon = (SelectPokemon*)malloc(sizeof(SelectPokemon)); - select_pokemon->app = app; - select_pokemon->view = view_alloc(); - view_set_context(select_pokemon->view, select_pokemon); - view_allocate_model(select_pokemon->view, ViewModelTypeLockFree, sizeof(SelectPokemonModel)); +View* select_pokemon_alloc(PokemonFap* pokemon_fap) { + View* view; + + view = view_alloc(); + + view_set_context(view, pokemon_fap); + view_allocate_model(view, ViewModelTypeLockFree, sizeof(PokemonFap**)); with_view_model_cpp( - select_pokemon->view, - SelectPokemonModel*, - model, - { - model->current_pokemon = app->current_pokemon; - model->pokemon_hex_code = app->pokemon_hex_code; - }, - true); - - view_set_draw_callback(select_pokemon->view, select_pokemon_render_callback); - view_set_input_callback(select_pokemon->view, select_pokemon_input_callback); - view_set_enter_callback(select_pokemon->view, select_pokemon_enter_callback); - view_set_custom_callback(select_pokemon->view, select_pokemon_custom_callback); - - view_set_exit_callback(select_pokemon->view, select_pokemon_exit_callback); - return select_pokemon; + view, PokemonFap**, model_fap, { *model_fap = pokemon_fap; }, false); + + view_set_draw_callback(view, select_pokemon_render_callback); + view_set_input_callback(view, select_pokemon_input_callback); + view_set_enter_callback(view, select_pokemon_enter_callback); + view_set_custom_callback(view, select_pokemon_custom_callback); + + view_set_exit_callback(view, select_pokemon_exit_callback); + return view; } -void select_pokemon_free(App* app) { - furi_assert(app->select_pokemon); - view_free(app->select_pokemon->view); - free(app->select_pokemon); +void select_pokemon_free(PokemonFap* pokemon_fap) { + furi_assert(pokemon_fap); + view_free(pokemon_fap->select_view); } -View* select_pokemon_get_view(App* app) { - furi_assert(app->select_pokemon); - return app->select_pokemon->view; +View* select_pokemon_get_view(PokemonFap* pokemon_fap) { + furi_assert(pokemon_fap); + return pokemon_fap->select_view; } diff --git a/views/select_pokemon.hpp b/views/select_pokemon.hpp index 169e43805e8..a5f7fa0baa8 100644 --- a/views/select_pokemon.hpp +++ b/views/select_pokemon.hpp @@ -9,17 +9,12 @@ #include #include -typedef struct App App; +#include "../pokemon_app.h" -typedef struct { - View* view; - App* app; -} SelectPokemon; +View* select_pokemon_alloc(PokemonFap* pokemon_fap); -SelectPokemon* select_pokemon_alloc(App* app); +void select_pokemon_free(PokemonFap* pokemon_fap); -void select_pokemon_free(App* app); +View* select_pokemon_get_view(PokemonFap* pokemon_fap); -View* select_pokemon_get_view(App* app); - -#endif /* SELECCT_POKEMON_HPP */ \ No newline at end of file +#endif /* SELECCT_POKEMON_HPP */ diff --git a/views/trade.cpp b/views/trade.cpp index 91f7e6f5b8e..75c574f687c 100644 --- a/views/trade.cpp +++ b/views/trade.cpp @@ -3,6 +3,7 @@ #include "../pokemon_data.h" +/* XXX: Convert all of these to be maintained in a struct in the Trade context */ uint8_t out_data = 0; uint8_t in_data = 0; uint8_t shift = 0; @@ -31,13 +32,13 @@ void screen_gameboy_connected(Canvas* const canvas) { int time_in_seconds = 0; -static void trade_draw_callback(Canvas* canvas, void* context) { +static void trade_draw_callback(Canvas* canvas, void* model) { const char* gameboy_status_text = NULL; + PokemonFap* pokemon_fap = *(PokemonFap**)model; canvas_clear(canvas); - SelectPokemonModel* model = (SelectPokemonModel*)context; - if(!model->trading) { - if(!model->connected) { + if(!pokemon_fap->trading) { + if(!pokemon_fap->connected) { furi_hal_light_set(LightGreen, 0x00); furi_hal_light_set(LightBlue, 0x00); furi_hal_light_set(LightRed, 0xff); @@ -49,7 +50,7 @@ static void trade_draw_callback(Canvas* canvas, void* context) { screen_gameboy_connected(canvas); } } else { - switch(model->gameboy_status) { + switch(pokemon_fap->gameboy_status) { case GAMEBOY_TRADING: furi_hal_light_set(LightGreen, 0x00); furi_hal_light_set(LightRed, 0x00); @@ -64,7 +65,8 @@ static void trade_draw_callback(Canvas* canvas, void* context) { case GAMEBOY_READY: case GAMEBOY_WAITING: case GAMEBOY_SEND: - canvas_draw_icon(canvas, 38, 11, pokemon_table[model->current_pokemon].icon); + canvas_draw_icon( + canvas, 38, 11, pokemon_fap->pokemon_table[pokemon_fap->curr_pokemon].icon); break; default: // Default state added to eliminated enum warning @@ -75,7 +77,7 @@ static void trade_draw_callback(Canvas* canvas, void* context) { canvas_draw_frame(canvas, 0, 0, 128, 64); canvas_draw_icon(canvas, 24, 0, &I_Space_80x18); - switch(model->gameboy_status) { + switch(pokemon_fap->gameboy_status) { case GAMEBOY_READY: gameboy_status_text = "READY"; break; @@ -108,12 +110,13 @@ static void trade_draw_callback(Canvas* canvas, void* context) { } static bool trade_input_callback(InputEvent* event, void* context) { - furi_assert(context); - Trade* trade = (Trade*)context; bool consumed = false; + PokemonFap* pokemon_fap = (PokemonFap*)context; + + furi_assert(context); if(event->type == InputTypePress && event->key == InputKeyBack) { - view_dispatcher_switch_to_view(trade->app->view_dispatcher, AppViewSelectPokemon); + view_dispatcher_switch_to_view(pokemon_fap->view_dispatcher, AppViewSelectPokemon); consumed = true; } @@ -180,10 +183,11 @@ byte getMenuResponse(byte in) { } byte getTradeCentreResponse(byte in, void* context) { - UNUSED(context); - Trade* trade = (Trade*)context; + PokemonFap* pokemon_fap = (PokemonFap*)context; byte send = in; + furi_assert(context); + switch(trade_centre_state) { case INIT: // TODO: What does this value of in mean? @@ -192,12 +196,7 @@ byte getTradeCentreResponse(byte in, void* context) { if(counter == 5) { trade_centre_state = READY_TO_GO; // CLICK EN LA MESA - with_view_model_cpp( - trade->view, - SelectPokemonModel*, - model, - { model->gameboy_status = GAMEBOY_READY; }, - false); + pokemon_fap->gameboy_status = GAMEBOY_READY; } counter++; } @@ -218,12 +217,7 @@ byte getTradeCentreResponse(byte in, void* context) { if((in & 0xF0) == 0xF0) { if(counter == 5) { trade_centre_state = WAITING_TO_SEND_DATA; - with_view_model_cpp( - trade->view, - SelectPokemonModel*, - model, - { model->gameboy_status = GAMEBOY_WAITING; }, - false); + pokemon_fap->gameboy_status = GAMEBOY_WAITING; } counter++; } @@ -263,20 +257,10 @@ byte getTradeCentreResponse(byte in, void* context) { if(in == 0x6F) { trade_centre_state = READY_TO_GO; send = 0x6F; - with_view_model_cpp( - trade->view, - SelectPokemonModel*, - model, - { model->gameboy_status = GAMEBOY_TRADE_READY; }, - false); + pokemon_fap->gameboy_status = GAMEBOY_TRADE_READY; } else if((in & 0x60) == 0x60) { send = 0x60; // first pokemon - with_view_model_cpp( - trade->view, - SelectPokemonModel*, - model, - { model->gameboy_status = GAMEBOY_SEND; }, - false); + pokemon_fap->gameboy_status = GAMEBOY_SEND; } else if(in == 0x00) { send = 0; trade_centre_state = TRADE_CONFIRMATION; @@ -286,12 +270,7 @@ byte getTradeCentreResponse(byte in, void* context) { case TRADE_CONFIRMATION: if(in == 0x61) { trade_centre_state = TRADE_PENDING; - with_view_model_cpp( - trade->view, - SelectPokemonModel*, - model, - { model->gameboy_status = GAMEBOY_PENDING; }, - false); + pokemon_fap->gameboy_status = GAMEBOY_PENDING; } else if((in & 0x60) == 0x60) { trade_centre_state = DONE; } @@ -301,12 +280,7 @@ byte getTradeCentreResponse(byte in, void* context) { if(in == 0x00) { send = 0; trade_centre_state = INIT; - with_view_model_cpp( - trade->view, - SelectPokemonModel*, - model, - { model->gameboy_status = GAMEBOY_TRADING; }, - false); + pokemon_fap->gameboy_status = GAMEBOY_TRADING; } break; @@ -319,7 +293,8 @@ byte getTradeCentreResponse(byte in, void* context) { } void transferBit(void* context) { - Trade* trade = (Trade*)context; + PokemonFap* pokemon_fap = (PokemonFap*)context; + furi_assert(context); byte raw_data = furi_hal_gpio_read(&GAME_BOY_SI); in_data |= raw_data << (7 - shift); @@ -327,17 +302,15 @@ void transferBit(void* context) { shift = 0; switch(connection_state) { case NOT_CONNECTED: - with_view_model_cpp( - trade->view, SelectPokemonModel*, model, { model->connected = false; }, true); + pokemon_fap->connected = false; out_data = getConnectResponse(in_data); break; case CONNECTED: - with_view_model_cpp( - trade->view, SelectPokemonModel*, model, { model->connected = true; }, true); + pokemon_fap->connected = true; out_data = getMenuResponse(in_data); break; case TRADE_CENTRE: - out_data = getTradeCentreResponse(in_data, trade); + out_data = getTradeCentreResponse(in_data, pokemon_fap); break; default: out_data = in_data; @@ -355,15 +328,14 @@ void transferBit(void* context) { DELAY_MICROSECONDS); // Wait 20-60us ... 120us max (in slave mode is not necessary) // TODO: The above comment doesn't make sense as DELAY_MICROSECONDS is defined as 15 - if(trade_centre_state == READY_TO_GO) { - with_view_model_cpp( - trade->view, SelectPokemonModel*, model, { model->trading = true; }, true); - } + if(trade_centre_state == READY_TO_GO) pokemon_fap->trading = true; + out_data = out_data << 1; } void input_clk_gameboy(void* context) { furi_assert(context); + if(time > 0) { // if there is no response from the master in 120 microseconds, the counters are reset if(micros() - time > 120) { @@ -378,22 +350,15 @@ void input_clk_gameboy(void* context) { } void trade_enter_callback(void* context) { + PokemonFap* pokemon_fap = (PokemonFap*)context; furi_assert(context); - Trade* trade = (Trade*)context; - with_view_model_cpp( - trade->view, - SelectPokemonModel*, - model, - { - model->current_pokemon = trade->app->current_pokemon; - model->pokemon_hex_code = trade->app->pokemon_hex_code; - model->trading = false; - model->connected = false; - model->gameboy_status = GAMEBOY_INITIAL; - }, - true); - - DATA_BLOCK[12] = trade->app->pokemon_hex_code; + + pokemon_fap->trading = false; + pokemon_fap->connected = false; + pokemon_fap->gameboy_status = GAMEBOY_INITIAL; + + /* XXX: Change hex to species to match pokemon nomenclature */ + DATA_BLOCK[12] = pokemon_fap->pokemon_table[pokemon_fap->curr_pokemon].hex; // B3 (Pin6) / SO (2) furi_hal_gpio_write(&GAME_BOY_SO, false); furi_hal_gpio_init(&GAME_BOY_SO, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh); @@ -407,7 +372,7 @@ void trade_enter_callback(void* context) { GpioPullNo, GpioSpeedVeryHigh); // <-- This line causes the "OK" to stop functioning when exiting the application, so a reboot of the Flipper Zero is required. furi_hal_gpio_remove_int_callback(&GAME_BOY_CLK); - furi_hal_gpio_add_int_callback(&GAME_BOY_CLK, input_clk_gameboy, trade); + furi_hal_gpio_add_int_callback(&GAME_BOY_CLK, input_clk_gameboy, pokemon_fap); // furi_hal_gpio_disable_int_callback(&GAME_BOY_CLK); // furi_hal_gpio_remove_int_callback(&GAME_BOY_CLK); @@ -417,9 +382,9 @@ void trade_enter_callback(void* context) { bool trade_custom_callback(uint32_t event, void* context) { UNUSED(event); + PokemonFap* pokemon_fap = (PokemonFap*)context; furi_assert(context); - Trade* trade = (Trade*)context; - view_dispatcher_send_custom_event(trade->app->view_dispatcher, 0); + view_dispatcher_send_custom_event(pokemon_fap->view_dispatcher, 0); return true; } @@ -436,35 +401,32 @@ void trade_exit_callback(void* context) { furi_hal_light_set(LightRed, 0x00); } -Trade* trade_alloc(App* app) { - Trade* trade = (Trade*)malloc(sizeof(Trade)); - trade->app = app; - trade->view = view_alloc(); +View* trade_alloc(PokemonFap* pokemon_fap) { + View* view; + + view = view_alloc(); procesing = true; - view_set_context(trade->view, trade); - view_allocate_model(trade->view, ViewModelTypeLockFree, sizeof(SelectPokemonModel)); - view_set_draw_callback(trade->view, trade_draw_callback); - view_set_input_callback(trade->view, trade_input_callback); - view_set_enter_callback(trade->view, trade_enter_callback); - view_set_custom_callback(trade->view, trade_custom_callback); - view_set_exit_callback(trade->view, trade_exit_callback); + view_set_context(view, pokemon_fap); + view_allocate_model(view, ViewModelTypeLockFree, sizeof(PokemonFap**)); + with_view_model_cpp( + view, PokemonFap**, model_fap, { *model_fap = pokemon_fap; }, false); + + view_set_draw_callback(view, trade_draw_callback); + view_set_input_callback(view, trade_input_callback); + view_set_enter_callback(view, trade_enter_callback); + view_set_custom_callback(view, trade_custom_callback); + view_set_exit_callback(view, trade_exit_callback); - return trade; + return view; } -void trade_free(App* app) { - furi_assert(app); +void trade_free(PokemonFap* pokemon_fap) { + furi_assert(pokemon_fap); // Free resources procesing = false; furi_hal_gpio_remove_int_callback(&GAME_BOY_CLK); disconnect_pin(&GAME_BOY_CLK); - view_free(app->trade->view); - free(app->trade); -} - -View* trade_get_view(App* app) { - furi_assert(app); - return app->trade->view; + view_free(pokemon_fap->trade_view); } diff --git a/views/trade.hpp b/views/trade.hpp index 885c2c126fb..aa21f454d86 100644 --- a/views/trade.hpp +++ b/views/trade.hpp @@ -9,6 +9,8 @@ #include #include +#include "../pokemon_app.h" + #define GAME_BOY_CLK gpio_ext_pb2 #define GAME_BOY_SI gpio_ext_pc3 #define GAME_BOY_SO gpio_ext_pb3 @@ -53,18 +55,9 @@ typedef enum { DONE } trade_centre_state_t; -typedef struct App App; - -typedef struct { - View* view; - App* app; -} Trade; - -Trade* trade_alloc(App* app); - -void trade_free(App* app); +View* trade_alloc(PokemonFap* pokemon_fap); -View* trade_get_view(App* app); +void trade_free(PokemonFap* pokemon_fap); extern unsigned char INPUT_BLOCK[405]; extern unsigned char* DATA_BLOCK;