From fd28f2337da9639e81bc41b30e3f7400092dffdd Mon Sep 17 00:00:00 2001 From: Kris Bahnsen Date: Sat, 24 Jun 2023 18:13:37 -0700 Subject: [PATCH] pokemon: Refactor party trade struct setup/use No longer declared in header, causes problems for multiple inclusions. Added as a pokemon_fap struct member. Trade was updated to use this struct member. For sections of code where the flat array is still expected, the TradeBlock struct is cast as a flat pointer. The struct initialization is also cut down heavily to only specify the bare minimum needed for the first pokemon in the party. --- pokemon_app.cpp | 47 ++++++++++++ pokemon_app.h | 9 +++ pokemon_data.h | 161 +-------------------------------------- views/select_pokemon.cpp | 2 +- views/trade.cpp | 10 ++- 5 files changed, 65 insertions(+), 164 deletions(-) diff --git a/pokemon_app.cpp b/pokemon_app.cpp index defe922ca8f..6939fb7b748 100644 --- a/pokemon_app.cpp +++ b/pokemon_app.cpp @@ -157,6 +157,50 @@ const PokemonTable pokemon_table[] = { {}, }; +TradeBlock OUTPUT_BLOCK = { + .trainer_name = {F_, l_, i_, p_, p_, e_, r_, TERM_, 0x00, 0x00, 0x00}, + .party_cnt = 1, + /* Only the first pokemon is ever used even though there are 7 bytes here. + * If the remaining 6 bytes are _not_ 0xff, then the trade window renders + * garbage for the Flipper's party. + */ + .party_members = {0x15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, + /* Only the first pokemon is set up, even though there are 6 total party members */ + .party = + { + {.species = 0x4a, + .hp = 0x2c01, + .level = 0x4a, + .status_condition = 0x0, + .type = {0x14, 0x08}, + .catch_held = 0x1f, + .move = {0x7e, 0x38, 0x09, 0x19}, + .orig_trainer = 0xd204, + .exp = {0x3, 0xd, 0x40}, + .hp_ev = 0xffff, + .atk_ev = 0xffff, + .def_ev = 0xffff, + .spd_ev = 0xffff, + .special_ev = 0xffff, + .iv = 0xffff, + .move_pp = {0xc0, 0xc0, 0xc0, 0xc0}, + .level_again = 0x4a, + .max_hp = 0x2c01, + .atk = 0x9600, + .def = 0x9700, + .spd = 0x9800, + .special = 0x9900}, + }, + /* Only the first pokemon has an OT name and nickname even though there are 6 members */ + /* NOTE: I think this shouldn't exceed 7 chars */ + .ot_name = + { + {.str = {F_, l_, i_, p_, p_, e_, r_, TERM_, 0x00, 0x00}}, + }, + .nickname = { + {.str = {F_, l_, o_, p_, p_, e_, r_, TERM_, 0x00, 0x00}}, + }}; + uint32_t pokemon_exit_confirm_view(void* context) { UNUSED(context); return AppViewExitConfirm; @@ -181,6 +225,9 @@ PokemonFap* pokemon_alloc() { // Set up pointer to pokemon table pokemon_fap->pokemon_table = pokemon_table; + // Set up trade party struct + pokemon_fap->trade_party = &OUTPUT_BLOCK; + // Select Pokemon View pokemon_fap->select_view = select_pokemon_alloc(pokemon_fap); view_set_previous_callback(select_pokemon_get_view(pokemon_fap), pokemon_exit_confirm_view); diff --git a/pokemon_app.h b/pokemon_app.h index e4ea2546e48..51cef1899f3 100644 --- a/pokemon_app.h +++ b/pokemon_app.h @@ -10,6 +10,8 @@ #include #include +#include "pokemon_data.h" + #define TAG "Pokemon" struct pokemon_data_table { @@ -40,6 +42,13 @@ struct pokemon_fap { /* Table of pokemon data for Gen I */ const PokemonTable* pokemon_table; + /* Struct for holding trade data */ + /* NOTE: There may be some runtime memory savings by adding more intelligence + * to views/trade and slimming down this struct to only contain the single + * pokemon data rather than the full 6 member party data. + */ + TradeBlock* trade_party; + /* The currently selected pokemon */ int curr_pokemon; diff --git a/pokemon_data.h b/pokemon_data.h index 4adaff98b76..8b38c49e25d 100644 --- a/pokemon_data.h +++ b/pokemon_data.h @@ -142,165 +142,6 @@ struct __attribute__((__packed__)) trade_data_block { struct name nickname[6]; }; -struct trade_data_block DATA_BLOCK2 = - {.trainer_name = {F_, l_, i_, p_, p_, e_, r_, TERM_, 0x00, 0x00, 0x00}, - .party_cnt = 1, - .party_members = {0x15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, - .party = - { - {.species = 0x4a, - .hp = 0x2c01, - .level = 0x4a, - .status_condition = 0x0, - .type = {0x14, 0x08}, - .catch_held = 0x1f, - .move = {0x7e, 0x38, 0x09, 0x19}, - .orig_trainer = 0xd204, - .exp = {0x3, 0xd, 0x40}, - .hp_ev = 0xffff, - .atk_ev = 0xffff, - .def_ev = 0xffff, - .spd_ev = 0xffff, - .special_ev = 0xffff, - .iv = 0xffff, - .move_pp = {0xc0, 0xc0, 0xc0, 0xc0}, - .level_again = 0x4a, - .max_hp = 0x2c01, - .atk = 0x9600, - .def = 0x9700, - .spd = 0x9800, - .special = 0x9900}, - {.species = 0x4a, - .hp = 0x2c01, - .level = 0x4a, - .status_condition = 0x0, - .type = {0x14, 0x08}, - .catch_held = 0x1f, - .move = {0x7e, 0x38, 0x09, 0x19}, - .orig_trainer = 0xd204, - .exp = {0x3, 0xd, 0x40}, - .hp_ev = 0xffff, - .atk_ev = 0xffff, - .def_ev = 0xffff, - .spd_ev = 0xffff, - .special_ev = 0xffff, - .iv = 0xffff, - .move_pp = {0xc0, 0xc0, 0xc0, 0xc0}, - .level_again = 0x4a, - .max_hp = 0x2c01, - .atk = 0x9600, - .def = 0x9700, - .spd = 0x9800, - .special = 0x9900}, - {.species = 0x4a, - .hp = 0x2c01, - .level = 0x4a, - .status_condition = 0x0, - .type = {0x14, 0x08}, - .catch_held = 0x1f, - .move = {0x7e, 0x38, 0x09, 0x19}, - .orig_trainer = 0xd204, - .exp = {0x3, 0xd, 0x40}, - .hp_ev = 0xffff, - .atk_ev = 0xffff, - .def_ev = 0xffff, - .spd_ev = 0xffff, - .special_ev = 0xffff, - .iv = 0xffff, - .move_pp = {0xc0, 0xc0, 0xc0, 0xc0}, - .level_again = 0x4a, - .max_hp = 0x2c01, - .atk = 0x9600, - .def = 0x9700, - .spd = 0x9800, - .special = 0x9900}, - {.species = 0x4a, - .hp = 0x2c01, - .level = 0x4a, - .status_condition = 0x0, - .type = {0x14, 0x08}, - .catch_held = 0x1f, - .move = {0x7e, 0x38, 0x09, 0x19}, - .orig_trainer = 0xd204, - .exp = {0x3, 0xd, 0x40}, - .hp_ev = 0xffff, - .atk_ev = 0xffff, - .def_ev = 0xffff, - .spd_ev = 0xffff, - .special_ev = 0xffff, - .iv = 0xffff, - .move_pp = {0xc0, 0xc0, 0xc0, 0xc0}, - .level_again = 0x4a, - .max_hp = 0x2c01, - .atk = 0x9600, - .def = 0x9700, - .spd = 0x9800, - .special = 0x9900}, - {.species = 0x4a, - .hp = 0x2c01, - .level = 0x4a, - .status_condition = 0x0, - .type = {0x14, 0x08}, - .catch_held = 0x1f, - .move = {0x7e, 0x38, 0x09, 0x19}, - .orig_trainer = 0xd204, - .exp = {0x3, 0xd, 0x40}, - .hp_ev = 0xffff, - .atk_ev = 0xffff, - .def_ev = 0xffff, - .spd_ev = 0xffff, - .special_ev = 0xffff, - .iv = 0xffff, - .move_pp = {0xc0, 0xc0, 0xc0, 0xc0}, - .level_again = 0x4a, - .max_hp = 0x2c01, - .atk = 0x9600, - .def = 0x9700, - .spd = 0x9800, - .special = 0x9900}, - {.species = 0x4a, - .hp = 0x2c01, - .level = 0x4a, - .status_condition = 0x0, - .type = {0x14, 0x08}, - .catch_held = 0x1f, - .move = {0x7e, 0x38, 0x09, 0x19}, - .orig_trainer = 0xd204, - .exp = {0x3, 0xd, 0x40}, - .hp_ev = 0xffff, - .atk_ev = 0xffff, - .def_ev = 0xffff, - .spd_ev = 0xffff, - .special_ev = 0xffff, - .iv = 0xffff, - .move_pp = {0xc0, 0xc0, 0xc0, 0xc0}, - .level_again = 0x4a, - .max_hp = 0x2c01, - .atk = 0x9600, - .def = 0x9700, - .spd = 0x9800, - .special = 0x9900}, - }, - /* NOTE: I think this shouldn't exceed 7 chars */ - .ot_name = - { - {.str = {F_, l_, i_, p_, p_, e_, r_, TERM_, 0x00, 0x00}}, - {.str = {F_, l_, i_, p_, p_, e_, r_, TERM_, 0x00, 0x00}}, - {.str = {F_, l_, i_, p_, p_, e_, r_, TERM_, 0x00, 0x00}}, - {.str = {F_, l_, i_, p_, p_, e_, r_, TERM_, 0x00, 0x00}}, - {.str = {F_, l_, i_, p_, p_, e_, r_, TERM_, 0x00, 0x00}}, - {.str = {F_, l_, i_, p_, p_, e_, r_, TERM_, 0x00, 0x00}}, - }, - .nickname = { - {.str = {F_, l_, o_, p_, p_, e_, r_, TERM_, 0x00, 0x00}}, - {.str = {F_, l_, o_, p_, p_, e_, r_, TERM_, 0x00, 0x00}}, - {.str = {F_, l_, o_, p_, p_, e_, r_, TERM_, 0x00, 0x00}}, - {.str = {F_, l_, o_, p_, p_, e_, r_, TERM_, 0x00, 0x00}}, - {.str = {F_, l_, o_, p_, p_, e_, r_, TERM_, 0x00, 0x00}}, - {.str = {F_, l_, o_, p_, p_, e_, r_, TERM_, 0x00, 0x00}}, - }}; - -unsigned char INPUT_BLOCK[405]; -unsigned char* DATA_BLOCK = (unsigned char*)&DATA_BLOCK2; +typedef struct trade_data_block TradeBlock; #endif /* POKEMON_DATA_H */ diff --git a/views/select_pokemon.cpp b/views/select_pokemon.cpp index 7ca7430e086..a9ce4d534ef 100644 --- a/views/select_pokemon.cpp +++ b/views/select_pokemon.cpp @@ -9,7 +9,7 @@ static void select_pokemon_render_callback(Canvas* canvas, void* model) { snprintf(pokedex_num, sizeof(pokedex_num), "#%03d", current_index + 1); canvas_set_font(canvas, FontPrimary); canvas_draw_str_aligned( - canvas, 55, 54 / 2, AlignLeft, AlignTop, pokemon_table[current_index].name); + canvas, 55, 54 / 2, AlignLeft, AlignTop, pokemon_fap->pokemon_table[current_index].name); canvas_set_font(canvas, FontSecondary); canvas_draw_str_aligned(canvas, 55, 38, AlignLeft, AlignTop, pokedex_num); diff --git a/views/trade.cpp b/views/trade.cpp index ea09b27bd82..bea992942ae 100644 --- a/views/trade.cpp +++ b/views/trade.cpp @@ -12,6 +12,7 @@ volatile int counter = 0; volatile bool procesing = true; volatile connection_state_t connection_state = NOT_CONNECTED; volatile trade_centre_state_t trade_centre_state = INIT; +unsigned char INPUT_BLOCK[405]; void screen_gameboy_connect(Canvas* const canvas) { canvas_draw_frame(canvas, 0, 0, 128, 64); @@ -184,6 +185,7 @@ byte getMenuResponse(byte in) { byte getTradeCentreResponse(byte in, void* context) { PokemonFap* pokemon_fap = (PokemonFap*)context; + uint8_t* trade_party_flat = (uint8_t*)pokemon_fap->trade_party; byte send = in; furi_assert(context); @@ -227,7 +229,7 @@ byte getTradeCentreResponse(byte in, void* context) { if((in & 0xF0) != 0xF0) { counter = 0; INPUT_BLOCK[counter] = in; - send = DATA_BLOCK[counter]; + send = trade_party_flat[counter]; counter++; trade_centre_state = SENDING_DATA; } @@ -235,7 +237,7 @@ byte getTradeCentreResponse(byte in, void* context) { case SENDING_DATA: INPUT_BLOCK[counter] = in; - send = DATA_BLOCK[counter]; + send = trade_party_flat[counter]; counter++; if(counter == 405) //TODO: replace with sizeof struct rather than static number trade_centre_state = SENDING_PATCH_DATA; @@ -357,7 +359,9 @@ void trade_enter_callback(void* context) { pokemon_fap->connected = false; pokemon_fap->gameboy_status = GAMEBOY_INITIAL; - DATA_BLOCK[12] = pokemon_fap->pokemon_table[pokemon_fap->curr_pokemon].species; + pokemon_fap->trade_party->party_members[0] = + pokemon_fap->pokemon_table[pokemon_fap->curr_pokemon].species; + // B3 (Pin6) / SO (2) furi_hal_gpio_write(&GAME_BOY_SO, false); furi_hal_gpio_init(&GAME_BOY_SO, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh);