diff --git a/include/link_handler.h b/include/link_handler.h index 10fb381..20130e4 100644 --- a/include/link_handler.h +++ b/include/link_handler.h @@ -52,7 +52,8 @@ struct LinkState uint8_t in_data; uint8_t out_data; - int data_counter = 0; // The counter for the number of bytes we have sent + int section_data_counter = 0; // The counter for the number of bytes we have sent in this section + int global_data_counter = 0; // the counter for the total number of bytes 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 @@ -71,7 +72,6 @@ struct LinkState byte data_packet[PACKET_SIZE]; // This is info that was passed in via handleIncomingByte - byte in; byte *box_data_storage; byte *curr_payload; GB_ROM *curr_gb_rom; @@ -80,7 +80,7 @@ struct LinkState bool cancel_connection; }; -void setup(const u16 *debug_charset); +void setup(byte *box_data_storage, byte *curr_payload, GB_ROM *curr_rom, PokeBox *box, const u16 *debug_charset, bool cancel_connection); byte handleIncomingByte(); 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); diff --git a/include/text_engine.h b/include/text_engine.h index 21e339f..befd74e 100644 --- a/include/text_engine.h +++ b/include/text_engine.h @@ -24,6 +24,6 @@ int ptgb_write_simple(const byte *text, bool instant); int ptgb_write(const byte *text, bool instant, int length, int box_type); int ptgb_write_debug(const u16* charset, const char *text, bool instant); void wait_for_user_to_continue(); -void scroll_text(bool instant, TTC *tc, int left, int top, int right, int bottom); +void scroll_text(bool instant, TTC *tc, bool scrollUp, int left, int top, int right, int bottom); #endif \ No newline at end of file diff --git a/source/dbg/debug_mode.cpp b/source/dbg/debug_mode.cpp index 0ccaf30..a9314eb 100644 --- a/source/dbg/debug_mode.cpp +++ b/source/dbg/debug_mode.cpp @@ -3,7 +3,7 @@ debug_options g_debug_options = { .print_link_data = (false && DEBUG_MODE), - .instant_text_speed = (false && DEBUG_MODE), + .instant_text_speed = (true && DEBUG_MODE), .ignore_game_pak = (true && DEBUG_MODE), .ignore_game_pak_sprites = (false && DEBUG_MODE), .ignore_link_cable = (false && DEBUG_MODE), diff --git a/source/link_handler.cpp b/source/link_handler.cpp index 8ec5791..4fdc191 100644 --- a/source/link_handler.cpp +++ b/source/link_handler.cpp @@ -68,9 +68,9 @@ void print(const char *format, ...) } } -void setup(const u16 *debug_charset) +void setup(byte *box_data_storage, byte *curr_payload, GB_ROM *curr_rom, PokeBox *box, const u16 *debug_charset, bool cancel_connection) { - REG_TM3D = -0x4000; + REG_TM3D = -0x4000 / 60; REG_TM3CNT = TM_FREQ_1024 | TM_ENABLE; irq_enable(II_TIMER3); @@ -78,6 +78,12 @@ void setup(const u16 *debug_charset) linkSPI->setWaitModeActive(false); currLinkState = new LinkState; + currLinkState->box_data_storage = box_data_storage; + currLinkState->curr_payload = curr_payload; + currLinkState->curr_gb_rom = curr_rom; + currLinkState->box = box; + currLinkState->debug_charset = debug_charset; + currLinkState->cancel_connection = cancel_connection; { u8 general_text_table_buffer[2048]; @@ -87,6 +93,8 @@ void setup(const u16 *debug_charset) ptgb_write_textbox(general_text.get_text_entry(GENERAL_connecting), true, false, GENERAL_INDEX, GENERAL_connecting, false); } + + create_textbox(0, 0, 125, 128, false); } byte handleIncomingByte() @@ -100,7 +108,7 @@ byte handleIncomingByte() currLinkState->conState = ACK; return 0x00; } - if (currLinkState->in == 0x00) + if (currLinkState->in_data == 0x00) { currLinkState->conState = ACK; return 0x01; @@ -110,7 +118,7 @@ byte handleIncomingByte() case ACK: if (currLinkState->curr_gb_rom->generation == 2) { - if (currLinkState->in == 0x61) + if (currLinkState->in_data == 0x61) { currLinkState->conState = MENU; return 0x61; @@ -119,12 +127,12 @@ byte handleIncomingByte() } else { - if (currLinkState->in == 0x00) + if (currLinkState->in_data == 0x00) { currLinkState->conState = MENU; return 0x00; } - else if (currLinkState->in == 0x02) + else if (currLinkState->in_data == 0x02) { currLinkState->conState = HS; return 0x02; @@ -133,7 +141,7 @@ byte handleIncomingByte() break; case MENU: - if (currLinkState->in == 0x60 || currLinkState->in == 0x61) + if (currLinkState->in_data == 0x60 || currLinkState->in_data == 0x61) { { u8 general_text_table_buffer[2048]; @@ -146,27 +154,27 @@ byte handleIncomingByte() link_animation_state(STATE_NO_ANIM); currLinkState->conState = PRETRADE; - currLinkState->data_counter = 0; - return currLinkState->in; + currLinkState->section_data_counter = 0; + return currLinkState->in_data; } - else if (currLinkState->in == 0x02) + else if (currLinkState->in_data == 0x02) { currLinkState->conState = HS; return 0x02; } else { - return currLinkState->in; + return currLinkState->in_data; } break; case PRETRADE: - if (currLinkState->data_counter == 16) + if (currLinkState->section_data_counter == 16) { - currLinkState->data_counter = 0; + currLinkState->section_data_counter = 0; currLinkState->conState = TRADE; } - currLinkState->data_counter++; + currLinkState->section_data_counter++; if (currLinkState->curr_gb_rom->generation == 2) { return 0x61; @@ -181,7 +189,7 @@ byte handleIncomingByte() } break; case TRADE: - if (currLinkState->in == 0xfd) + if (currLinkState->in_data == 0xfd) { { u8 general_text_table_buffer[2048]; @@ -193,23 +201,24 @@ byte handleIncomingByte() } link_animation_state(STATE_TRANSFER); - currLinkState->mosi_delay = 1; + //currLinkState->mosi_delay = 1; + REG_TM3D = -0x0040; currLinkState->conState = PARTY_PREAMBLE; } - return currLinkState->in; + return currLinkState->in_data; break; case PARTY_PREAMBLE: - if (currLinkState->in != 0xfd) + if (currLinkState->in_data != 0xfd) { currLinkState->conState = TRADE_DATA; - return exchange_parties(currLinkState->in, currLinkState->curr_payload); + return exchange_parties(currLinkState->in_data, currLinkState->curr_payload); } - return currLinkState->in; + return currLinkState->in_data; break; case TRADE_DATA: - if (currLinkState->data_counter >= currLinkState->curr_gb_rom->payload_size) + if (currLinkState->section_data_counter >= currLinkState->curr_gb_rom->payload_size) { - if (currLinkState->in == 0xFD) + if (currLinkState->in_data == 0xFD) { currLinkState->conState = BOX_PREAMBLE; currLinkState->init_packet = true; @@ -219,55 +228,55 @@ byte handleIncomingByte() return 0x00; } } - return exchange_parties(currLinkState->in, currLinkState->curr_payload); + return exchange_parties(currLinkState->in_data, currLinkState->curr_payload); break; case BOX_PREAMBLE: - if (currLinkState->in != 0xFD) + if (currLinkState->in_data != 0xFD) { currLinkState->conState = BOX_DATA; - return exchange_boxes(currLinkState->in, currLinkState->box_data_storage, currLinkState->curr_gb_rom, currLinkState->debug_charset); + return exchange_boxes(currLinkState->in_data, currLinkState->box_data_storage, currLinkState->curr_gb_rom, currLinkState->debug_charset); } - return currLinkState->in; + return currLinkState->in_data; break; case BOX_DATA: - return exchange_boxes(currLinkState->in, currLinkState->box_data_storage, currLinkState->curr_gb_rom, currLinkState->debug_charset); + return exchange_boxes(currLinkState->in_data, currLinkState->box_data_storage, currLinkState->curr_gb_rom, currLinkState->debug_charset); break; case REBOOT: - currLinkState->data_counter = 0; + currLinkState->section_data_counter = 0; currLinkState->conState = REMOVE_ARRAY_PREAMBLE; return 0xFD; break; case REMOVE_ARRAY_PREAMBLE: - if (currLinkState->in != 0xFD) + if (currLinkState->in_data != 0xFD) { currLinkState->conState = SEND_REMOVE_ARRAY; - return exchange_remove_array(currLinkState->in, currLinkState->box, currLinkState->cancel_connection); + return exchange_remove_array(currLinkState->in_data, currLinkState->box, currLinkState->cancel_connection); } - return currLinkState->in; + return currLinkState->in_data; break; 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 + if (currLinkState->section_data_counter >= 29) // This assumes the preamble does not count towards the number of bytes sent over the cable { currLinkState->conState = END2; } - currLinkState->data_counter++; - return exchange_remove_array(currLinkState->in, currLinkState->box, currLinkState->cancel_connection); + currLinkState->section_data_counter++; + return exchange_remove_array(currLinkState->in_data, currLinkState->box, currLinkState->cancel_connection); break; default: - return currLinkState->in; + return currLinkState->in_data; break; } return 0; // This should never hit but the compiler likes this being here } - +/* int loop(byte *box_data_storage, byte *curr_payload, GB_ROM *curr_gb_rom, PokeBox *box, const u16 *debug_charset, bool cancel_connection) { #define LINE_WIDTH 21 -#define NUM_LINES 8 +#define NUM_LINES 2 int counter = 0; char stuff[NUM_LINES][LINE_WIDTH]; @@ -381,16 +390,56 @@ int loop(byte *box_data_storage, byte *curr_payload, GB_ROM *curr_gb_rom, PokeBo } } }; +*/ + +#define LINE_WIDTH 21 +#define NUM_LINES 8 +char stuff[NUM_LINES][LINE_WIDTH]; +char line[LINE_WIDTH] = "OUT"; +ConnectionState prevConState; void handshake() { + prevConState = currLinkState->conState; // The con state can change in handleIncomingByte - we want to display what it was before running that function + currLinkState->in_data = linkSPI->transfer(currLinkState->out_data); currLinkState->out_data = handleIncomingByte(); + + if (g_debug_options.print_link_data && !key_held(KEY_DOWN)) + { + n2hexstr(&line[0], currLinkState->global_data_counter & 0xFFFFFF, 6); + line[6] = ':'; + n2hexstr(&line[7], currLinkState->section_data_counter & 0xFFFF, 4); + line[11] = '|'; + n2hexstr(&line[12], prevConState & 0xFF, 2); + line[14] = '|'; + n2hexstr(&line[15], currLinkState->in_data & 0xFF, 2); + line[17] = '|'; + n2hexstr(&line[18], currLinkState->out_data & 0xFF, 2); + line[20] = '\0'; + scroll_text(true, tte_get_context(), false, 8, 8, 127, 135); + ptgb_write_debug(currLinkState->debug_charset, line, true); + } + else if (g_debug_options.write_cable_data_to_save) + { + global_memory_buffer[link_cable_array_index] = currLinkState->in_data; + link_cable_array_index++; + global_memory_buffer[link_cable_array_index] = currLinkState->out_data; + link_cable_array_index++; + if (link_cable_array_index >= 0x1000) + { + copy_ram_to_save(&global_memory_buffer[0], 0x1000 * link_cable_memory_section_index, 0x1000); + link_cable_memory_section_index++; + link_cable_array_index = link_cable_array_index % 0x1000; + } + } + + currLinkState->global_data_counter++; } byte exchange_parties(byte curr_in, byte *curr_payload) { - int ret = curr_payload[currLinkState->data_counter]; - currLinkState->data_counter += 1; + int ret = curr_payload[currLinkState->section_data_counter]; + currLinkState->section_data_counter += 1; return ret; }; diff --git a/source/pokemon_party.cpp b/source/pokemon_party.cpp index 11665c7..c9c67ba 100644 --- a/source/pokemon_party.cpp +++ b/source/pokemon_party.cpp @@ -178,7 +178,7 @@ void Pokemon_Party::start_link() load_localized_charset(debug_charset, 3, ENGLISH); init_payload(); - setup(debug_charset); + setup(&box_data_array[0], current_payload, &curr_gb_rom, &box, debug_charset, false); // This used to clear out the box data, probably isn't needed anymore // memset(box_data_array, 0, curr_gb_rom.box_data_size); @@ -212,7 +212,7 @@ void Pokemon_Party::continue_link(bool cancel_connection) load_localized_charset(debug_charset, 3, ENGLISH); - last_error = loop(&box_data_array[0], current_payload, &curr_gb_rom, &box, debug_charset, cancel_connection); + //last_error = loop(&box_data_array[0], current_payload, &curr_gb_rom, &box, debug_charset, cancel_connection); } } diff --git a/source/text_engine.cpp b/source/text_engine.cpp index 213c659..55ef2f0 100644 --- a/source/text_engine.cpp +++ b/source/text_engine.cpp @@ -341,7 +341,7 @@ int ptgb_write(const byte *text, bool instant, int length, int box_type) tc->drawgProc(0x79); } wait_for_user_to_continue(); - scroll_text(instant, tc, left, top, right, bottom); + scroll_text(instant, tc, true, left, top, right, bottom); break; case 0xFB: if (g_debug_options.display_control_char) @@ -427,7 +427,7 @@ int ptgb_write_debug(const u16 *charset, const char *text, bool instant) u16 utf16_char; // we need to use this conversion function in order to convert char values >= 0x80 // correctly to UTF-16 (which is used by the charset) - convert_utf8_to_utf16_char((const u8*)(text + i), utf16_char); + convert_utf8_to_utf16_char((const u8 *)(text + i), utf16_char); // WARNING: the conversion of the text characters from u8 to u16 done here, is incorrect // for every character value >= 0x80. The character set uses UTF-16 to represent characters. // But the input text is in UTF-8. @@ -458,29 +458,42 @@ void wait_for_user_to_continue() } } -void scroll_text(bool instant, TTC *tc, int left, int top, int right, int bottom) +void scroll_text(bool instant, TTC *tc, bool scrollUp, int left, int top, int right, int bottom) { + int direction = scrollUp ? 1 : -1; + for (int i = 1; i <= tc->font->charH; i++) { - REG_BG3VOFS = i; - tte_erase_rect(left, top - tc->font->charH, right, top + i); - if (!instant) + REG_BG3VOFS = i * direction; + tte_erase_rect(left, top - tc->font->charH, right, top + (i * direction)); + if (!instant) // This is somewhat of a silly way to do this - can be optimized { VBlankIntrWait(); } } REG_BG3VOFS = 0; - + // The map starts at tile 0 in the top left, increases by 1 as you go down, and then loops back at the top. - for (int i = 0; i < 30; i++) + if (scrollUp) { - tonccpy(&tile_mem[TEXT_CBB][0 + (i * 20)], &tile_mem[TEXT_CBB][2 + (i * 20)], 20 * 32); + for (int i = 0; i < 30; i++) + { + tonccpy(&tile_mem[TEXT_CBB][0 + (i * 20)], &tile_mem[TEXT_CBB][2 + (i * 20)], 20 * 32); + } + } + else + { + for (int i = 29; i >= 0; i--) + { + // Due to the order of tonccpy, we need to store the data in a temporary buffer + byte buffer[20 * 32]; + tonccpy(&buffer, &tile_mem[TEXT_CBB][0 + (i * 20)], 20 * 32); + tonccpy(&tile_mem[TEXT_CBB][2 + (i * 20)], &buffer, 20 * 32); + } } - // Remove text that went outside of the box and set the position - tte_erase_rect(left, top - tc->font->charH, right, top); - tte_set_pos(left, bottom - (8 + (2 * tc->font->charH))); // The newline will trigger after this and move it down a line + tte_erase_rect(left, scrollUp ? (top - tc->font->charH) : bottom, right, scrollUp ? top : (bottom + tc->font->charH)); - tc->cursorY = bottom - tc->font->charH; + tc->cursorY = (scrollUp ? bottom - tc->font->charH : top); // The newline will trigger after this and move it down a line tc->cursorX = left; } \ No newline at end of file