From be0fb6dcca2bc1744d257c0065ef3cf1a1f04ed8 Mon Sep 17 00:00:00 2001 From: GearsProgress Date: Fri, 17 Apr 2026 12:05:00 -0400 Subject: [PATCH] Cleaning up the link handler (aka gameboy_colour) --- include/gameboy_colour.h | 40 -- include/gb_link.h | 4 +- include/link_handler.h | 81 ++++ include/pokemon_trade.h | 77 ---- source/button_menu.cpp | 2 +- .../{gameboy_colour.cpp => link_handler.cpp} | 346 +++++++----------- source/main.cpp | 8 +- source/pokemon_party.cpp | 2 +- source/vertical_menu.cpp | 78 ++-- 9 files changed, 251 insertions(+), 387 deletions(-) delete mode 100644 include/gameboy_colour.h create mode 100644 include/link_handler.h delete mode 100644 include/pokemon_trade.h rename source/{gameboy_colour.cpp => link_handler.cpp} (60%) diff --git a/include/gameboy_colour.h b/include/gameboy_colour.h deleted file mode 100644 index 85ca228..0000000 --- a/include/gameboy_colour.h +++ /dev/null @@ -1,40 +0,0 @@ -//Created by StevenChaulk https://github.com/stevenchaulk/arduino-poke-gen2 - -#ifndef GAMEBOY_COLOUR_H_ -#define GAMEBOY_COLOUR_H_ - -#include -#include "libraries/gba-link-connection/LinkSPI.hpp" -#include "pokemon_party.h" - -/* -#define LINK_SPI_NO_DATA 0xffffffff -#define LINK_SPI_SIOCNT_NORMAL 0 -#define LINK_SPI_BIT_CLOCK 0 -#define LINK_SPI_BIT_CLOCK_SPEED 1 -#define LINK_SPI_BIT_SI 2 -#define LINK_SPI_BIT_SO 3 -#define LINK_SPI_BIT_START 7 -#define LINK_SPI_BIT_LENGTH 12 -#define LINK_SPI_BIT_IRQ 14 -#define LINK_SPI_BIT_GENERAL_PURPOSE_LOW 14 -#define LINK_SPI_BIT_GENERAL_PURPOSE_HIGH 15 -#define LINK_SPI_SET_HIGH(REG, BIT) REG |= 1 << BIT -#define LINK_SPI_SET_LOW(REG, BIT) REG &= ~(1 << BIT) - -#define LINK_SPI_SET(REG, BIT, VALUE) VALUE ? LINK_SPI_SET_HIGH(REG, BIT) : LINK_SPI_SET_LOW(REG, BIT) -*/ - - -// The number of frames(?) between changing the clock signals -#define FAST_SPEED 10 -#define SLOW_SPEED 1000 - -void setup(const u16 *debug_charset); -byte handleIncomingByte(byte in, byte *box_data_storage, byte *curr_payload, GB_ROM *curr_gb_rom, PokeBox* box, const u16 *debug_charset, bool cancel_connection); -int loop(byte *box_data_storage, byte *curr_payload, GB_ROM *curr_rom, PokeBox* box, const u16 *debug_charset, bool cancel_connection); -byte exchange_parties(byte curr_in, byte *curr_payload); -byte exchange_boxes(byte curr_in, byte *party_data, GB_ROM *curr_gb_rom, const u16 *debug_charset); -byte exchange_remove_array(byte curr_in, PokeBox* box, bool cancel_connection); - -#endif /* GAMEBOY_COLOUR_H_ */ diff --git a/include/gb_link.h b/include/gb_link.h index b4dc325..df15cd7 100644 --- a/include/gb_link.h +++ b/include/gb_link.h @@ -14,7 +14,7 @@ typedef enum { FINAL_DESTINATION, SEND_POKEMON_DATA } connection_state; -*/ + typedef enum { @@ -79,5 +79,5 @@ void wait(u32 verticalLines); inline void VBLANK() {} void init(); int start_link(); - +*/ #endif diff --git a/include/link_handler.h b/include/link_handler.h new file mode 100644 index 0000000..3ca82fb --- /dev/null +++ b/include/link_handler.h @@ -0,0 +1,81 @@ +// Loosely based on code created by StevenChaulk +// Source: https://github.com/stevenchaulk/arduino-poke-gen2 + +#ifndef LINK_HANDLER_H_ +#define LINK_HANDLER_H_ + +#include +#include "libraries/gba-link-connection/LinkSPI.hpp" +#include "pokemon_party.h" + +#define DATA_PER_PACKET 8 +#define PACKET_DATA_START 2 +#define PACKET_DATA_AT(i) (PACKET_DATA_START + (i * 2)) +#define PACKET_FLAG_AT(i) (PACKET_DATA_START + (i * 2) + 1) +#define PACKET_CHECKSUM (PACKET_DATA_START + (2 * DATA_PER_PACKET)) +#define PACKET_LOCATION_UPPER (PACKET_CHECKSUM + 1) +#define PACKET_LOCATION_LOWER (PACKET_CHECKSUM + 2) + +// 0xFD, 0x00, data bytes per packet, flag bytes per packet, the checksum, and two location bytes +#define PACKET_SIZE (1 + 1 + (2 * DATA_PER_PACKET) + 1 + 2) // Originally 13 + +#define TIMEOUT 2 +#define TIMEOUT_ONE_LENGTH 1000000 // Maybe keep a 10:1 ratio between ONE and TWO? +#define TIMEOUT_TWO_LENGTH 100000 + +#define SPI_TEXT_OUT_ARRAY_ELEMENT_SIZE 64 + +enum ConnectionState +{ + HS, + ACK, + MENU, + PRETRADE, + TRADE, + PARTY_PREAMBLE, + COLOSSEUM, + CANCEL, + TRADE_DATA, + BOX_PREAMBLE, + BOX_DATA, + END1, + REBOOT, + REMOVE_ARRAY_PREAMBLE, + SEND_REMOVE_ARRAY, + END2, +}; + +struct LinkState +{ + ConnectionState conState = HS; + + uint8_t in_data; + uint8_t out_data; + + int data_counter = 0; // The counter for the number of bytes we have sent + int gen = 0; // The generation we are trading with + + int FF_count = 0; // The number of 0xFF bytes that have been in a row + int zero_count = 0; // The number of 0x00 bytes that have been in a row + + int mosi_delay = 4; // inital delay, speeds up once sending + int received_offset = 0; // The offset contained in the last packet + int next_offset = 0; // The offset we are sending in the next packet + int packet_index = 0; // The index of the current packet + + bool failed_packet = false; // Flags if a packet failed + bool init_packet = true; // Flags if a packet is the inital one + bool end_of_data = false; // Flags if we are at the end of the data + bool test_packet_fail = false; // ??? + + byte data_packet[PACKET_SIZE]; +}; + +void setup(const u16 *debug_charset); +byte handleIncomingByte(byte in, byte *box_data_storage, byte *curr_payload, GB_ROM *curr_gb_rom, PokeBox *box, const u16 *debug_charset, bool cancel_connection); +int loop(byte *box_data_storage, byte *curr_payload, GB_ROM *curr_rom, PokeBox *box, const u16 *debug_charset, bool cancel_connection); +byte exchange_parties(byte curr_in, byte *curr_payload); +byte exchange_boxes(byte curr_in, byte *party_data, GB_ROM *curr_gb_rom, const u16 *debug_charset); +byte exchange_remove_array(byte curr_in, PokeBox *box, bool cancel_connection); + +#endif /* LINK_HANDLER_H_ */ diff --git a/include/pokemon_trade.h b/include/pokemon_trade.h deleted file mode 100644 index 92a061c..0000000 --- a/include/pokemon_trade.h +++ /dev/null @@ -1,77 +0,0 @@ -//Created by StevenChaulk https://github.com/stevenchaulk/arduino-poke-gen2 - -#ifndef POKEMON_TRADE_H_ -#define POKEMON_TRADE_H_ - -typedef enum { - PRE_CONNECT_TWO, - NOT_CONNECTED, - CONNECTED, - TRADE_CENTRE, - COLOSSEUM -} connection_state_t; - -/* typedef enum { - INIT, - READY_TO_GO, - SEEN_FIRST_WAIT, - SENDING_RANDOM_DATA, - WAITING_TO_SEND_DATA, - START_SENDING_DATA, - SENDING_DATA, - SENDING_PATCH_DATA, - TRADE_PENDING, - TRADE_CONFIRMATION, - DONE -} trade_centre_state_t; */ - -typedef enum { - INIT, - READY_TO_GO, - SEEN_FIRST_WAIT, - SENDING_RANDOM_DATA, - WAITING_TO_SEND_DATA, - SENDING_DATA, - SENDING_PATCH_DATA, - MIMIC, - TRADE_PENDING, - TRADE_CONFIRMATION, - DONE -} trade_centre_state_gen_II_t; - -typedef unsigned char byte; - -#define PKMN_BLANK 0x00 - -#define ITEM_1_HIGHLIGHTED 0xD0 -#define ITEM_2_HIGHLIGHTED 0xD1 -#define ITEM_3_HIGHLIGHTED 0xD2 -#define ITEM_1_SELECTED 0xD4 -#define ITEM_2_SELECTED 0xD5 -#define ITEM_2_SELECTED 0xD5 -#define ITEM_3_SELECTED 0xD6 - -#define GEN_I_CABLE_TRADE_CENTER 0xD4 -#define GEN_I_CABLE_CLUB_COLOSSEUM 0xD5 - -#define GEN_II_CABLE_TRADE_CENTER 0xD1 -#define GEN_II_CABLE_CLUB_COLOSSEUM 0xD2 -#define GEN_II_TIME_CAPSULE 0xD2 - -#define PKMN_MASTER 0x01 -#define PKMN_SLAVE 0x02 -#define PKMN_MASTER_GEN_III 0x8FFF //?? -#define PKMN_SLAVE_GEN_III 0xB9A0 //?? -#define PKMN_CONNECTED_I 0x60 -#define PKMN_CONNECTED_II 0x61 -#define PKMN_WAIT 0x7F - -#define PKMN_ACTION 0x60 - -#define PKMN_TRADE_CENTRE ITEM_1_SELECTED -#define PKMN_COLOSSEUM ITEM_2_SELECTED -#define PKMN_BREAK_LINK ITEM_3_SELECTED - -#define TRADE_CENTRE_WAIT 0xFD - -#endif /* POKEMON_H_ */ diff --git a/source/button_menu.cpp b/source/button_menu.cpp index 2b4177a..56478f3 100644 --- a/source/button_menu.cpp +++ b/source/button_menu.cpp @@ -36,7 +36,7 @@ int Button_Menu::button_main() int curr_x = 0; int curr_y = 0; - //key_poll(); // Reset the buttons + VBlankIntrWait(); // Reset the buttons while (true) { diff --git a/source/gameboy_colour.cpp b/source/link_handler.cpp similarity index 60% rename from source/gameboy_colour.cpp rename to source/link_handler.cpp index 1d6644d..9f39c02 100644 --- a/source/gameboy_colour.cpp +++ b/source/link_handler.cpp @@ -6,8 +6,7 @@ #include #include "libraries/nanoprintf/nanoprintf.h" #include "libstd_replacements.h" -#include "gameboy_colour.h" -#include "pokemon_trade.h" +#include "link_handler.h" #include "script_array.h" #include "dbg/debug_mode.h" #include "interrupt.h" @@ -19,74 +18,9 @@ #include "libraries/Pokemon-Gen3-to-Gen-X/include/save.h" #include "flash_mem.h" -#define DATA_PER_PACKET 8 -#define PACKET_DATA_START 2 -#define PACKET_DATA_AT(i) (PACKET_DATA_START + (i * 2)) -#define PACKET_FLAG_AT(i) (PACKET_DATA_START + (i * 2) + 1) -#define PACKET_CHECKSUM (PACKET_DATA_START + (2 * DATA_PER_PACKET)) -#define PACKET_LOCATION_UPPER (PACKET_CHECKSUM + 1) -#define PACKET_LOCATION_LOWER (PACKET_CHECKSUM + 2) - -// 0xFD, 0x00, data bytes per packet, flag bytes per packet, the checksum, and two location bytes -#define PACKET_SIZE (1 + 1 + (2 * DATA_PER_PACKET) + 1 + 2) // Originally 13 - -#define TIMEOUT 2 -#define TIMEOUT_ONE_LENGTH 1000000 // Maybe keep a 10:1 ratio between ONE and TWO? -#define TIMEOUT_TWO_LENGTH 100000 - -#define hs 0 -#define ack 1 -#define menu 2 -#define pretrade 3 -#define trade 4 -#define party_preamble 5 -#define colosseum 6 -#define cancel 7 -#define trade_data 8 -#define box_preamble 9 -#define box_data 10 -#define end1 11 -#define reboot 12 -#define remove_array_preamble 13 -#define send_remove_array 14 -#define end2 15 - -const int MODE = 1; // mode=0 will transfer pokemon data from pokemon.h - // mode=1 will copy pokemon party data being received LinkSPI linkSPIInstance; LinkSPI *linkSPI = &linkSPIInstance; - -uint8_t in_data; -uint8_t out_data; -uint frame; - -connection_state_t connection_state; - -int counter; -int data_counter = 0; -int gen_1_room_counter = 0; -int gen; -int trade_pokemon; - -int FF_count; -int zero_count; - -int state; -int mosi_delay = 4; // inital delay, speeds up once sending PKMN -int received_offset = 0; -int next_offset = 0; -int packet_index = 0; - -bool failed_packet; -bool init_packet; - -bool test_packet_fail = false; - -bool end_of_data; - -byte data_packet[PACKET_SIZE]; - -#define SPI_TEXT_OUT_ARRAY_ELEMENT_SIZE 64 +LinkState *currLinkState; // Here's a compilation check to ensure that the size of these structs match our expectations. // Just update it if you changed the struct members. The data-generator process prints their actual sizes. @@ -136,35 +70,15 @@ void print(const char *format, ...) void setup(const u16 *debug_charset) { - //interrupt_init(); - //interrupt_set_handler(INTR_SERIAL, LINK_SPI_ISR_SERIAL); - //interrupt_enable(INTR_SERIAL); + interrupt_init(); + interrupt_set_handler(INTR_SERIAL, LINK_SPI_ISR_SERIAL); + interrupt_enable(INTR_SERIAL); linkSPI->activate(LinkSPI::Mode::MASTER_256KBPS); linkSPI->setWaitModeActive(false); - state = hs; + currLinkState = new LinkState; - in_data = 0; - out_data = 0; - frame = 0; - - connection_state = NOT_CONNECTED; - counter = 0; - - gen = 0; - - trade_pokemon = -1; - - FF_count = 0; - zero_count = 0; - next_offset = 0; - received_offset = 0; - packet_index = 0; - - failed_packet = false; - init_packet = true; - end_of_data = false; { u8 general_text_table_buffer[2048]; text_data_table general_text(general_text_table_buffer); @@ -177,29 +91,28 @@ void setup(const u16 *debug_charset) byte handleIncomingByte(byte in, byte *box_data_storage, byte *curr_payload, GB_ROM *curr_gb_rom, PokeBox *box, const u16 *debug_charset, bool cancel_connection) { - // TODO: Change to a switch statement - if (state == hs) + switch (currLinkState->conState) { - mosi_delay = 4; + case HS: + currLinkState->mosi_delay = 4; if (curr_gb_rom->generation == 2) { - state = ack; + currLinkState->conState = ACK; return 0x00; } if (in == 0x00) { - state = ack; + currLinkState->conState = ACK; return 0x01; } - } + break; - else if (state == ack) - { + case ACK: if (curr_gb_rom->generation == 2) { if (in == 0x61) { - state = menu; + currLinkState->conState = MENU; return 0x61; } return 0x01; @@ -208,19 +121,18 @@ byte handleIncomingByte(byte in, byte *box_data_storage, byte *curr_payload, GB_ { if (in == 0x00) { - state = menu; + currLinkState->conState = MENU; return 0x00; } else if (in == 0x02) { - state = hs; + currLinkState->conState = HS; return 0x02; } } - } + break; - else if (state == menu) - { + case MENU: if (in == 0x60 || in == 0x61) { { @@ -233,29 +145,28 @@ byte handleIncomingByte(byte in, byte *box_data_storage, byte *curr_payload, GB_ } link_animation_state(STATE_NO_ANIM); - state = pretrade; - data_counter = 0; + currLinkState->conState = PRETRADE; + currLinkState->data_counter = 0; return in; } else if (in == 0x02) { - state = hs; + currLinkState->conState = HS; return 0x02; } else { return in; } - } + break; - else if (state == pretrade) - { - if (data_counter == 16) + case PRETRADE: + if (currLinkState->data_counter == 16) { - data_counter = 0; - state = trade; + currLinkState->data_counter = 0; + currLinkState->conState = TRADE; } - data_counter++; + currLinkState->data_counter++; if (curr_gb_rom->generation == 2) { return 0x61; @@ -268,10 +179,8 @@ byte handleIncomingByte(byte in, byte *box_data_storage, byte *curr_payload, GB_ { return 0xD4; } - } - - else if (state == trade) - { + break; + case TRADE: if (in == 0xfd) { { @@ -284,30 +193,26 @@ byte handleIncomingByte(byte in, byte *box_data_storage, byte *curr_payload, GB_ } link_animation_state(STATE_TRANSFER); - mosi_delay = 1; - state = party_preamble; + currLinkState->mosi_delay = 1; + currLinkState->conState = PARTY_PREAMBLE; } return in; - } - - else if (state == party_preamble) - { + break; + case PARTY_PREAMBLE: if (in != 0xfd) { - state = trade_data; + currLinkState->conState = TRADE_DATA; return exchange_parties(in, curr_payload); } return in; - } - - else if (state == trade_data) - { - if (data_counter >= curr_gb_rom->payload_size) + break; + case TRADE_DATA: + if (currLinkState->data_counter >= curr_gb_rom->payload_size) { if (in == 0xFD) { - state = box_preamble; - init_packet = true; + currLinkState->conState = BOX_PREAMBLE; + currLinkState->init_packet = true; } else { @@ -315,51 +220,48 @@ byte handleIncomingByte(byte in, byte *box_data_storage, byte *curr_payload, GB_ } } return exchange_parties(in, curr_payload); - } - - else if (state == box_preamble) - { + break; + case BOX_PREAMBLE: if (in != 0xFD) { - state = box_data; + currLinkState->conState = BOX_DATA; return exchange_boxes(in, box_data_storage, curr_gb_rom, debug_charset); } return in; - } - - else if (state == box_data) - { + break; + case BOX_DATA: return exchange_boxes(in, box_data_storage, curr_gb_rom, debug_charset); - } - - else if (state == reboot) - { - data_counter = 0; - state = remove_array_preamble; + break; + case REBOOT: + currLinkState->data_counter = 0; + currLinkState->conState = REMOVE_ARRAY_PREAMBLE; return 0xFD; - } + break; - else if (state == remove_array_preamble) - { + case REMOVE_ARRAY_PREAMBLE: if (in != 0xFD) { - state = send_remove_array; + currLinkState->conState = SEND_REMOVE_ARRAY; return exchange_remove_array(in, box, cancel_connection); } return in; - } + break; - else if (state == send_remove_array) - { - if (data_counter >= 29) // This assumes the preamble does not count towards the number of bytes sent over the cable + case SEND_REMOVE_ARRAY: + if (currLinkState->data_counter >= 29) // This assumes the preamble does not count towards the number of bytes sent over the cable { - state = end2; + currLinkState->conState = END2; } - data_counter++; + currLinkState->data_counter++; return exchange_remove_array(in, box, cancel_connection); + break; + + default: + return in; + break; } - return in; + return 0; // This should never hit } int loop(byte *box_data_storage, byte *curr_payload, GB_ROM *curr_gb_rom, PokeBox *box, const u16 *debug_charset, bool cancel_connection) @@ -379,7 +281,7 @@ int loop(byte *box_data_storage, byte *curr_payload, GB_ROM *curr_gb_rom, PokeBo VBlankIntrWait(); } // TODO: Restore Errors - in_data = linkSPI->transfer(out_data); + currLinkState->in_data = linkSPI->transfer(currLinkState->out_data); if (g_debug_options.print_link_data && !key_held(KEY_DOWN)) { @@ -393,13 +295,13 @@ int loop(byte *box_data_storage, byte *curr_payload, GB_ROM *curr_gb_rom, PokeBo } n2hexstr(&stuff[NUM_LINES - 1][0], counter & 0xFFFFFF, 6); stuff[NUM_LINES - 1][6] = ':'; - n2hexstr(&stuff[NUM_LINES - 1][7], data_counter & 0xFFFF, 4); + n2hexstr(&stuff[NUM_LINES - 1][7], currLinkState->data_counter & 0xFFFF, 4); stuff[NUM_LINES - 1][11] = '|'; - n2hexstr(&stuff[NUM_LINES - 1][12], state & 0xFF, 2); + n2hexstr(&stuff[NUM_LINES - 1][12], currLinkState->conState & 0xFF, 2); stuff[NUM_LINES - 1][14] = '|'; - n2hexstr(&stuff[NUM_LINES - 1][15], in_data & 0xFF, 2); + n2hexstr(&stuff[NUM_LINES - 1][15], currLinkState->in_data & 0xFF, 2); stuff[NUM_LINES - 1][17] = '|'; - n2hexstr(&stuff[NUM_LINES - 1][18], out_data & 0xFF, 2); + n2hexstr(&stuff[NUM_LINES - 1][18], currLinkState->out_data & 0xFF, 2); stuff[NUM_LINES - 1][20] = '\0'; create_textbox(0, 0, 125, 128, false); @@ -407,9 +309,9 @@ int loop(byte *box_data_storage, byte *curr_payload, GB_ROM *curr_gb_rom, PokeBo } else if (g_debug_options.write_cable_data_to_save) { - global_memory_buffer[link_cable_array_index] = in_data; + global_memory_buffer[link_cable_array_index] = currLinkState->in_data; link_cable_array_index++; - global_memory_buffer[link_cable_array_index] = out_data; + global_memory_buffer[link_cable_array_index] = currLinkState->out_data; link_cable_array_index++; if (link_cable_array_index >= 0x1000) { @@ -419,24 +321,24 @@ int loop(byte *box_data_storage, byte *curr_payload, GB_ROM *curr_gb_rom, PokeBo } } - out_data = handleIncomingByte(in_data, box_data_storage, curr_payload, curr_gb_rom, box, debug_charset, cancel_connection); + currLinkState->out_data = handleIncomingByte(currLinkState->in_data, box_data_storage, curr_payload, curr_gb_rom, box, debug_charset, cancel_connection); - if (FF_count > (15 * 60)) + if (currLinkState->FF_count > (15 * 60)) { return COND_ERROR_DISCONNECT; } - if (zero_count > (5 * 60)) + if (currLinkState->zero_count > (5 * 60)) { // return COND_ERROR_COM_ENDED; } - if (connection_state == COLOSSEUM) + if (currLinkState->conState == COLOSSEUM) { return COND_ERROR_COLOSSEUM; } - if (state == end1) + if (currLinkState->conState == END1) { - state = reboot; + currLinkState->conState = REBOOT; if (g_debug_options.write_cable_data_to_save) { for (int i = 0; i < 16; i++) @@ -448,7 +350,7 @@ int loop(byte *box_data_storage, byte *curr_payload, GB_ROM *curr_gb_rom, PokeBo return 0; } - if (state == end2) + if (currLinkState->conState == END2) { return 0; } @@ -458,14 +360,14 @@ int loop(byte *box_data_storage, byte *curr_payload, GB_ROM *curr_gb_rom, PokeBo return COND_ERROR_DISCONNECT; } - if (state != box_data) + if (currLinkState->conState != BOX_DATA) { - FF_count = (in_data == 0xFF ? FF_count + mosi_delay : 0); - zero_count = (in_data == 0x00 ? zero_count + mosi_delay : 0); + currLinkState->FF_count = (currLinkState->in_data == 0xFF ? currLinkState->FF_count + currLinkState->mosi_delay : 0); + currLinkState->zero_count = (currLinkState->in_data == 0x00 ? currLinkState->zero_count + currLinkState->mosi_delay : 0); } counter++; - for (int i = 0; i < mosi_delay; i++) + for (int i = 0; i < currLinkState->mosi_delay; i++) { VBlankIntrWait(); } @@ -474,83 +376,83 @@ int loop(byte *box_data_storage, byte *curr_payload, GB_ROM *curr_gb_rom, PokeBo byte exchange_parties(byte curr_in, byte *curr_payload) { - int ret = curr_payload[data_counter]; - data_counter += 1; + int ret = curr_payload[currLinkState->data_counter]; + currLinkState->data_counter += 1; return ret; }; byte exchange_boxes(byte curr_in, byte *box_data_storage, GB_ROM *curr_gb_rom, const u16 *debug_charset) { - data_packet[packet_index] = curr_in; - if (packet_index == PACKET_SIZE - 1) + currLinkState->data_packet[currLinkState->packet_index] = curr_in; + if (currLinkState->packet_index == PACKET_SIZE - 1) { byte checksum = 0; for (int i = 0; i < DATA_PER_PACKET; i++) { - if (data_packet[PACKET_FLAG_AT(i)] == 1) + if (currLinkState->data_packet[PACKET_FLAG_AT(i)] == 1) { - data_packet[PACKET_DATA_AT(i)] = 0xFE; + currLinkState->data_packet[PACKET_DATA_AT(i)] = 0xFE; } - checksum += data_packet[PACKET_DATA_AT(i)]; + checksum += currLinkState->data_packet[PACKET_DATA_AT(i)]; } checksum &= 0b01111111; // Reset the top bit so it matches the recieved range - if (!init_packet) + if (!currLinkState->init_packet) { - received_offset = (data_packet[PACKET_LOCATION_LOWER] | (data_packet[PACKET_LOCATION_UPPER] << 8)) - ((curr_gb_rom->wBoxDataStart & 0xFFFF) + DATA_PER_PACKET); + currLinkState->received_offset = (currLinkState->data_packet[PACKET_LOCATION_LOWER] | (currLinkState->data_packet[PACKET_LOCATION_UPPER] << 8)) - ((curr_gb_rom->wBoxDataStart & 0xFFFF) + DATA_PER_PACKET); } - if (checksum == data_packet[PACKET_CHECKSUM] && !init_packet && !(test_packet_fail && received_offset == 128)) // Verify if the data matches the checksum + if (checksum == currLinkState->data_packet[PACKET_CHECKSUM] && !currLinkState->init_packet && !(currLinkState->test_packet_fail && currLinkState->received_offset == 128)) // Verify if the data matches the checksum { for (int i = 0; i < DATA_PER_PACKET; i++) { - if (received_offset + i <= curr_gb_rom->box_data_size && received_offset + i >= 0) + if (currLinkState->received_offset + i <= curr_gb_rom->box_data_size && currLinkState->received_offset + i >= 0) { - box_data_storage[received_offset + i] = data_packet[PACKET_DATA_AT(i)]; + box_data_storage[currLinkState->received_offset + i] = currLinkState->data_packet[PACKET_DATA_AT(i)]; } } } - else if (!init_packet) + else if (!currLinkState->init_packet) { - failed_packet = true; - if (test_packet_fail) + currLinkState->failed_packet = true; + if (currLinkState->test_packet_fail) { - test_packet_fail = false; + currLinkState->test_packet_fail = false; } } - if (end_of_data) + if (currLinkState->end_of_data) { - state = end1; + currLinkState->conState = END1; } else { - state = box_preamble; + currLinkState->conState = BOX_PREAMBLE; } - if (received_offset > curr_gb_rom->box_data_size + DATA_PER_PACKET) + if (currLinkState->received_offset > curr_gb_rom->box_data_size + DATA_PER_PACKET) { - end_of_data = true; + currLinkState->end_of_data = true; } - if (!init_packet) + if (!currLinkState->init_packet) { - if (failed_packet) + if (currLinkState->failed_packet) { - next_offset -= DATA_PER_PACKET; - if (next_offset < 0) + currLinkState->next_offset -= DATA_PER_PACKET; + if (currLinkState->next_offset < 0) { - next_offset = 0; + currLinkState->next_offset = 0; } - failed_packet = false; + currLinkState->failed_packet = false; } else { - next_offset += DATA_PER_PACKET; + currLinkState->next_offset += DATA_PER_PACKET; } } - if (((next_offset + curr_gb_rom->wBoxDataStart) & 0xFF) == 0xFE) + if (((currLinkState->next_offset + curr_gb_rom->wBoxDataStart) & 0xFF) == 0xFE) { - next_offset -= 1; // Set back the offset if the byte sent would be 0xFE, since that would break the system + currLinkState->next_offset -= 1; // Set back the offset if the byte sent would be 0xFE, since that would break the system } #define ROW_LENGTH 22 @@ -582,7 +484,7 @@ byte exchange_boxes(byte curr_in, byte *box_data_storage, GB_ROM *curr_gb_rom, c outArr[currRow][10] = ' '; n2hexstr(&outArr[currRow][11], checksum, 2); strcpy(&outArr[currRow][13], " = "); - n2hexstr(&outArr[currRow][16], data_packet[PACKET_CHECKSUM], 2); + n2hexstr(&outArr[currRow][16], currLinkState->data_packet[PACKET_CHECKSUM], 2); outArr[currRow][18] = ' '; currRow += 1; @@ -591,24 +493,24 @@ byte exchange_boxes(byte curr_in, byte *box_data_storage, GB_ROM *curr_gb_rom, c outArr[currRow][0] = 'P'; n2hexstr(&outArr[currRow][1], i, 1); strcpy(&outArr[currRow][2], ": "); - n2hexstr(&outArr[currRow][4], data_packet[PACKET_DATA_AT(i)], 2); + n2hexstr(&outArr[currRow][4], currLinkState->data_packet[PACKET_DATA_AT(i)], 2); strcpy(&outArr[currRow][6], " ("); - n2hexstr(&outArr[currRow][8], data_packet[PACKET_FLAG_AT(i)], 2); + n2hexstr(&outArr[currRow][8], currLinkState->data_packet[PACKET_FLAG_AT(i)], 2); outArr[currRow][10] = ')'; currRow += 1; } strcpy(&outArr[currRow][0], "RO: "); - n2hexstr(&outArr[currRow][4], received_offset, 4); + n2hexstr(&outArr[currRow][4], currLinkState->received_offset, 4); strcpy(&outArr[currRow][8], " FP: "); - n2hexstr(&outArr[currRow][14], failed_packet, 2); + n2hexstr(&outArr[currRow][14], currLinkState->failed_packet, 2); outArr[currRow][16] = ' '; currRow += 1; strcpy(&outArr[currRow][0], "NO: "); - n2hexstr(&outArr[currRow][4], next_offset, 4); + n2hexstr(&outArr[currRow][4], currLinkState->next_offset, 4); strcpy(&outArr[currRow][8], " IP: "); - n2hexstr(&outArr[currRow][14], init_packet, 2); + n2hexstr(&outArr[currRow][14], currLinkState->init_packet, 2); outArr[currRow][16] = ' '; // create_textbox(0, 0, 125, 110, false); @@ -621,20 +523,20 @@ byte exchange_boxes(byte curr_in, byte *box_data_storage, GB_ROM *curr_gb_rom, c } VBlankIntrWait(); } - packet_index = 0; - init_packet = false; + currLinkState->packet_index = 0; + currLinkState->init_packet = false; } - packet_index += 1; - switch (packet_index) + currLinkState->packet_index += 1; + switch (currLinkState->packet_index) { case 3: - if (end_of_data) + if (currLinkState->end_of_data) { return 0xFF; } - return (curr_gb_rom->wBoxDataStart + next_offset) >> 8; + return (curr_gb_rom->wBoxDataStart + currLinkState->next_offset) >> 8; case 2: - return (curr_gb_rom->wBoxDataStart + next_offset) >> 0; + return (curr_gb_rom->wBoxDataStart + currLinkState->next_offset) >> 0; default: return 0; } diff --git a/source/main.cpp b/source/main.cpp index 150ed5f..9cf3da4 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -4,7 +4,7 @@ #include "flash_mem.h" #include "interrupt.h" #include "gb_link.h" -#include "gameboy_colour.h" +#include "link_handler.h" #include "random.h" #include "text_engine.h" #include "background_engine.h" @@ -80,14 +80,18 @@ void initialization_script(void) REG_IME = 0; REG_IE = 0; + irq_init(NULL); + // Sound bank init // irq_init(NULL); // irq_enable(II_VBLANK); // This currently crashes when you try to transfer a Pokemon: // sound_init(); + // Link Cable init + //irq_add(II_TIMER0, handleIncomingByte); + // Graphics init - irq_init(NULL); irq_add(II_VBLANK, global_next_frame); irq_enable(II_VBLANK); oam_init(obj_buffer, 128); diff --git a/source/pokemon_party.cpp b/source/pokemon_party.cpp index d54a5b2..278b0a0 100644 --- a/source/pokemon_party.cpp +++ b/source/pokemon_party.cpp @@ -1,4 +1,4 @@ -#include "gameboy_colour.h" +#include "link_handler.h" #include "pokemon_party.h" #include "flash_mem.h" #include "dbg/debug_mode.h" diff --git a/source/vertical_menu.cpp b/source/vertical_menu.cpp index ce8e143..eb1e7b2 100644 --- a/source/vertical_menu.cpp +++ b/source/vertical_menu.cpp @@ -34,13 +34,7 @@ static unsigned get_viewport_end_index(unsigned viewport_start_index, unsigned n } vertical_menu::vertical_menu(const vertical_menu_settings &settings) - : settings_(settings) - , state_changed_handler_(nullptr) - , run_cycle_handler_(nullptr) - , focused_index_(settings.initial_focus_index) - , viewport_start_index_(0) - , items_() - , is_focused_(true) + : settings_(settings), state_changed_handler_(nullptr), run_cycle_handler_(nullptr), focused_index_(settings.initial_focus_index), viewport_start_index_(0), items_(), is_focused_(true) { } @@ -55,7 +49,7 @@ void vertical_menu::show() update_viewport(); - if(state_changed_handler_) + if (state_changed_handler_) { state_changed_handler_->on_show(); } @@ -65,9 +59,9 @@ void vertical_menu::show() handle_selection_change(focused_index_, settings_.x, settings_.y + settings_.margin_top + (render_index * settings_.item_height)); } -i_item_widget* vertical_menu::get_item_widget_at(unsigned index) const +i_item_widget *vertical_menu::get_item_widget_at(unsigned index) const { - if(index >= items_.size()) + if (index >= items_.size()) { return nullptr; } @@ -76,7 +70,7 @@ i_item_widget* vertical_menu::get_item_widget_at(unsigned index) const void vertical_menu::hide() { - if(state_changed_handler_) + if (state_changed_handler_) { state_changed_handler_->on_hide(); } @@ -86,7 +80,7 @@ void vertical_menu::hide() reload_textbox_background(); } -const vertical_menu_settings& vertical_menu::get_settings() const +const vertical_menu_settings &vertical_menu::get_settings() const { return settings_; } @@ -127,9 +121,9 @@ void vertical_menu::clear_item_widgets() void vertical_menu::set_focused(bool is_focused) { is_focused_ = is_focused; - if(state_changed_handler_ && settings_.should_hide_state_changed_handler_on_not_focused) + if (state_changed_handler_ && settings_.should_hide_state_changed_handler_on_not_focused) { - if(is_focused_) + if (is_focused_) { state_changed_handler_->on_show(); } @@ -147,49 +141,49 @@ MenuInputHandleState vertical_menu::handle_input() bool viewport_changed = false; // If no items or not focused, there's nothing to handle. - if(items_.size() <= 1 || !is_focused_) + if (items_.size() <= 1 || !is_focused_) { return MenuInputHandleState::NOT_HANDLED; } - // the focused item widget gets the first chance to handle input, + // the focused item widget gets the first chance to handle input, // since it might have some special behavior for certain keys. result = items_[focused_index_]->handle_input(); - if(result == MenuInputHandleState::HANDLED_UPDATE_VIEWPORT) + if (result == MenuInputHandleState::HANDLED_UPDATE_VIEWPORT) { // the child widget is requesting that we update the viewport. - // so we do that here and then degrade the result to HANDLED, + // so we do that here and then degrade the result to HANDLED, // since we've already done the viewport update that the child widget requested. update_viewport(); result = MenuInputHandleState::HANDLED; // degrade to HANDLED after updating the viewport } - if(result != MenuInputHandleState::NOT_HANDLED) + if (result != MenuInputHandleState::NOT_HANDLED) { return result; } // if the user presses B, and the current settings allow it, // we will return the CANCELLED state, which the caller can use to know that they should exit the menu. - if(settings_.allow_cancel && key_hit(KEY_B)) + if (settings_.allow_cancel && key_hit(KEY_B)) { return MenuInputHandleState::CANCELLED; } - if(key_hit(KEY_DOWN) && focused_index_ < (items_.size() - 1u)) + if (key_hit(KEY_DOWN) && focused_index_ < (items_.size() - 1u)) { const unsigned current_viewport_end_index = get_viewport_end_index(viewport_start_index_, get_num_visible_items(settings_.height, settings_.margin_top, settings_.margin_bottom, settings_.item_height), items_.size()); ++focused_index_; - if(focused_index_ >= current_viewport_end_index) + if (focused_index_ >= current_viewport_end_index) { ++viewport_start_index_; viewport_changed = true; } did_navigate = true; } - else if(key_hit(KEY_UP) && focused_index_ > 0) + else if (key_hit(KEY_UP) && focused_index_ > 0) { --focused_index_; - if(focused_index_ < viewport_start_index_) + if (focused_index_ < viewport_start_index_) { --viewport_start_index_; viewport_changed = true; @@ -198,10 +192,10 @@ MenuInputHandleState vertical_menu::handle_input() } // if we did navigate, we need to update the viewport and state changed handler. - if(did_navigate) + if (did_navigate) { const unsigned render_index = focused_index_ - viewport_start_index_; - if(viewport_changed) + if (viewport_changed) { update_viewport(); } @@ -219,7 +213,7 @@ void vertical_menu::update_viewport() clear_viewport(); - if(settings_.text_table_index != INT32_MAX) + if (settings_.text_table_index != INT32_MAX) { text_table.decompress(get_compressed_text_table(settings_.text_table_index)); } @@ -245,26 +239,26 @@ unsigned vertical_menu::run() { MenuInputHandleState input_result; - while(true) - { - //key_poll(); // Reset the buttons + VBlankIntrWait(); // Reset the buttons + while (true) + { input_result = handle_input(); - switch(input_result) + switch (input_result) { - case MenuInputHandleState::CHOICE_MADE: - return focused_index_; - case MenuInputHandleState::CANCELLED: - return UINT32_MAX; - default: - break; + case MenuInputHandleState::CHOICE_MADE: + return focused_index_; + case MenuInputHandleState::CANCELLED: + return UINT32_MAX; + default: + break; } // if any global elements need to be updated // on every cycle (animations, for example) // the run_cycle_handler can be used for that. - if(run_cycle_handler_) + if (run_cycle_handler_) { run_cycle_handler_->on_run_cycle(); } @@ -287,7 +281,7 @@ void vertical_menu::set_run_cycle_handler(i_run_cycle_handler *handler) void vertical_menu::handle_selection_change(unsigned new_index, unsigned x, unsigned y) { - if(state_changed_handler_) + if (state_changed_handler_) { state_changed_handler_->on_selection_changed(new_index, x, y); } @@ -302,7 +296,7 @@ simple_item_renderer::~simple_item_renderer() { } -const simple_item_widget_data& simple_item_renderer::get_data() const +const simple_item_widget_data &simple_item_renderer::get_data() const { return data_; } @@ -315,12 +309,12 @@ void simple_item_renderer::render_item(text_data_table &text_table, unsigned x, MenuInputHandleState simple_item_renderer::handle_input() { - if(!key_hit(KEY_A)) + if (!key_hit(KEY_A)) { return MenuInputHandleState::NOT_HANDLED; } - if(data_.on_execute_callback) + if (data_.on_execute_callback) { data_.on_execute_callback(this); return MenuInputHandleState::HANDLED;