diff --git a/include/debug_mode.h b/include/debug_mode.h index 848d335..b1f5745 100644 --- a/include/debug_mode.h +++ b/include/debug_mode.h @@ -2,18 +2,19 @@ #define DEBUG_MODE_H #define DEBUG_MODE false -#define IGNORE_GAME_PAK true -#define IGNORE_LINK_CABLE true -#define IGNORE_MG_E4_FLAGS true -#define IGNORE_UNRECEIVED_PKMN true +#define IGNORE_GAME_PAK false +#define IGNORE_LINK_CABLE false +#define IGNORE_MG_E4_FLAGS false +#define IGNORE_UNRECEIVED_PKMN false #define FORCE_TUTORIAL false #define DONT_REMOVE_PKMN false #define SHOW_INVALID_PKMN false -#define DEBUG_GAME EMERALD_ID -#define DEBUG_VERS VERS_1_0 +#define DEBUG_GAME RUBY_ID +#define DEBUG_VERS VERS_1_1 #define DEBUG_LANG LANG_ENG #define ENABLE_MATCH_PID true +#define ENABLE_OLD_EVENT true #endif \ No newline at end of file diff --git a/include/gba_rom_values/base_gba_rom_struct.h b/include/gba_rom_values/base_gba_rom_struct.h index 55ac5a4..4af0b62 100644 --- a/include/gba_rom_values/base_gba_rom_struct.h +++ b/include/gba_rom_values/base_gba_rom_struct.h @@ -71,9 +71,11 @@ struct ROM_DATA u8 def_map_id; u8 def_npc_id; - u8 test_map_bank; - u8 test_map_id; - u8 test_npc_id; + u8 old_map_bank; + u8 old_map_id; + u8 old_npc_id; + + int loc_gSaveBlock1PTR; // TODO: Only used for old script, can be removed later }; #endif \ No newline at end of file diff --git a/include/gba_rom_values/eng_gba_rom_values.h b/include/gba_rom_values/eng_gba_rom_values.h index 9123bc9..d9a4e62 100644 --- a/include/gba_rom_values/eng_gba_rom_values.h +++ b/include/gba_rom_values/eng_gba_rom_values.h @@ -50,9 +50,9 @@ const struct ROM_DATA ENG_RUBY_v0 = { .def_map_id = 1, .def_npc_id = 1, - .test_map_bank = 2, - .test_map_id = 2, - .test_npc_id = 3, + .old_map_bank = 20, + .old_map_id = 2, + .old_npc_id = 1, }; const struct ROM_DATA ENG_SAPPHIRE_v0 = { .is_valid = true, @@ -99,9 +99,9 @@ const struct ROM_DATA ENG_SAPPHIRE_v0 = { .def_map_id = 1, .def_npc_id = 1, - .test_map_bank = 2, - .test_map_id = 2, - .test_npc_id = 3, + .old_map_bank = 20, + .old_map_id = 2, + .old_npc_id = 1, }; const struct ROM_DATA ENG_RUBY_v1 = { .is_valid = true, @@ -148,9 +148,9 @@ const struct ROM_DATA ENG_RUBY_v1 = { .def_map_id = 1, .def_npc_id = 1, - .test_map_bank = 2, - .test_map_id = 2, - .test_npc_id = 3, + .old_map_bank = 20, + .old_map_id = 2, + .old_npc_id = 1, }; const struct ROM_DATA ENG_SAPPHIRE_v1 = { .is_valid = true, @@ -197,9 +197,9 @@ const struct ROM_DATA ENG_SAPPHIRE_v1 = { .def_map_id = 1, .def_npc_id = 1, - .test_map_bank = 2, - .test_map_id = 2, - .test_npc_id = 3, + .old_map_bank = 20, + .old_map_id = 2, + .old_npc_id = 1, }; const struct ROM_DATA ENG_RUBY_v2 = { .is_valid = true, @@ -246,9 +246,9 @@ const struct ROM_DATA ENG_RUBY_v2 = { .def_map_id = 1, .def_npc_id = 1, - .test_map_bank = 2, - .test_map_id = 2, - .test_npc_id = 3, + .old_map_bank = 20, + .old_map_id = 2, + .old_npc_id = 1, }; const struct ROM_DATA ENG_SAPPHIRE_v2 = { .is_valid = true, @@ -295,9 +295,9 @@ const struct ROM_DATA ENG_SAPPHIRE_v2 = { .def_map_id = 1, .def_npc_id = 1, - .test_map_bank = 2, - .test_map_id = 2, - .test_npc_id = 3, + .old_map_bank = 20, + .old_map_id = 2, + .old_npc_id = 1, }; const struct ROM_DATA ENG_FIRERED_v0 = { .is_valid = true, @@ -345,9 +345,11 @@ const struct ROM_DATA ENG_FIRERED_v0 = { .def_map_id = 0xFF, .def_npc_id = 0xFF, - .test_map_bank = 7, - .test_map_id = 3, - .test_npc_id = 2, + .old_map_bank = 30, + .old_map_id = 0, + .old_npc_id = 1, + + .loc_gSaveBlock1PTR = 0x03005008, // TODO: Only used for old script, can be removed later }; const struct ROM_DATA ENG_LEAFGREEN_v0 = { .is_valid = true, @@ -395,9 +397,11 @@ const struct ROM_DATA ENG_LEAFGREEN_v0 = { .def_map_id = 0xFF, .def_npc_id = 0xFF, - .test_map_bank = 7, - .test_map_id = 3, - .test_npc_id = 2, + .old_map_bank = 30, + .old_map_id = 0, + .old_npc_id = 1, + + .loc_gSaveBlock1PTR = 0x03005008, // TODO: Only used for old script, can be removed later }; const struct ROM_DATA ENG_FIRERED_v1 = { .is_valid = true, @@ -445,9 +449,11 @@ const struct ROM_DATA ENG_FIRERED_v1 = { .def_map_id = 0xFF, .def_npc_id = 0xFF, - .test_map_bank = 7, - .test_map_id = 3, - .test_npc_id = 2, + .old_map_bank = 30, + .old_map_id = 0, + .old_npc_id = 1, + + .loc_gSaveBlock1PTR = 0x03005008, // TODO: Only used for old script, can be removed later }; const struct ROM_DATA ENG_LEAFGREEN_v1 = { .is_valid = true, @@ -495,9 +501,11 @@ const struct ROM_DATA ENG_LEAFGREEN_v1 = { .def_map_id = 0xFF, .def_npc_id = 0xFF, - .test_map_bank = 7, - .test_map_id = 3, - .test_npc_id = 2, + .old_map_bank = 30, + .old_map_id = 0, + .old_npc_id = 1, + + .loc_gSaveBlock1PTR = 0x03005008, // TODO: Only used for old script, can be removed later }; const struct ROM_DATA ENG_EMERALD_v0 = { .is_valid = true, @@ -545,9 +553,11 @@ const struct ROM_DATA ENG_EMERALD_v0 = { .def_map_id = 0xFF, .def_npc_id = 0xFF, - .test_map_bank = 5, - .test_map_id = 4, - .test_npc_id = 2, + .old_map_bank = 20, + .old_map_id = 2, + .old_npc_id = 1, + + .loc_gSaveBlock1PTR = 0x03005D8C, // TODO: Only used for old script, can be removed later }; #endif \ No newline at end of file diff --git a/include/mystery_gift_builder.h b/include/mystery_gift_builder.h index 9d564b5..a6d4869 100644 --- a/include/mystery_gift_builder.h +++ b/include/mystery_gift_builder.h @@ -266,6 +266,7 @@ class mystery_gift_script public: mystery_gift_script(); void build_script(Pokemon_Party &incoming_box_data); + void build_script_old(Pokemon_Party &incoming_box_data); u8 get_script_value_at(int index); u8 get_section30_value_at(int index); u32 calc_checksum32(); diff --git a/include/rom_data.h b/include/rom_data.h index e09262d..38181e0 100644 --- a/include/rom_data.h +++ b/include/rom_data.h @@ -39,7 +39,7 @@ public: int loc_sendMonToPC; int loc_gSpecialVar_0x8000; - int loc_gSaveBlock1; // Only used in R/S + int loc_gSaveBlock1; // Only used in R/S int loc_setPokedexFlag; int loc_gSaveDataBuffer; // The location of the saveDataBuffer int loc_readFlashSector; @@ -77,6 +77,8 @@ public: u8 def_map_id; u8 def_npc_id; + int loc_gSaveBlock1PTR; // TODO: Only used for old script, can be removed later + private: void fill_values(const ROM_DATA *rom_values); }; diff --git a/source/main.cpp b/source/main.cpp index 9f4c27b..f763800 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -102,7 +102,7 @@ void load_graphics() main_menu.clear_vector(); main_menu.add_button(Button(btn_t_l, btn_t_r, 48), BTN_TRANSFER); main_menu.add_button(Button(btn_p_l, btn_p_r, 48), BTN_POKEDEX); - main_menu.add_button(Button(btn_d_l, btn_d_r, 48), BTN_EVENTS); + //main_menu.add_button(Button(btn_d_l, btn_d_r, 48), BTN_EVENTS); main_menu.add_button(Button(btn_c_l, btn_c_r, 48), BTN_CREDITS); main_menu.set_xy_min_max(0, H_MAX, 48, V_MAX); @@ -183,7 +183,7 @@ void first_load_message(void) int credits() { -#define CREDITS_ARRAY_SIZE 15 +#define CREDITS_ARRAY_SIZE 16 int curr_credits_num = 0; std::string credits_array[CREDITS_ARRAY_SIZE] = { "Lead developer:\n\nThe Gears of\nProgress\n\nLead graphic design:\n\nJome", @@ -197,6 +197,7 @@ int credits() "Pok@mon data\nobtained from:\n\n-Bulbapedia\n-Serebii\n-PokeAPI.com", "Discord community\nassistance:\n\n-Hex Maniac Advance\n Development\n-gbadev\n-pret", "Writing assistance:\n\n\n-Mad", + "Remote and Arbitrary\nCode Execution\nassistance:\n\n\n-TimoVM", "An immense thanks to\nLorenzooone for\ntheir assistance in\nreading/writing save\ndata. Without them,\nthis project would\nnot have been\npossible.", "Special thanks to\nEnn, roku, Sleepy,\nEza, sarahtonin,\nBasabi, Mad, and\neveryone who has\nlistened to me talk\nabout this for\nmonths!", "All Pok@mon names,\nsprites, and names\nof related resources\nare copyright\nNintendo,\nCreatures Inc.,\nand GAME FREAK Inc.", diff --git a/source/mystery_gift_builder.cpp b/source/mystery_gift_builder.cpp index 945c758..128744f 100644 --- a/source/mystery_gift_builder.cpp +++ b/source/mystery_gift_builder.cpp @@ -27,6 +27,18 @@ int ptr_dex_seen_caught; int ptr_index; int ptr_pkmn_offset; +// TODO: For old script, can be removed later +int ptr_callASM; +int ptr_script_ptr_low; +int ptr_script_ptr_high; +int ptr_call_return_1; +int ptr_block_ptr_low; +int ptr_block_ptr_high; +int var_callASM = (VAR_ID_START + 0x00); +int var_script_ptr_low = (VAR_ID_START + 0x01); +int var_script_ptr_high = (VAR_ID_START + 0x02); +int var_call_return_1 = (VAR_ID_START + 0x03); + mystery_gift_script::mystery_gift_script() { curr_mg_index = NPC_LOCATION_OFFSET; @@ -38,6 +50,14 @@ mystery_gift_script::mystery_gift_script() ptr_dex_seen_caught = (curr_rom.loc_gSpecialVar_0x8000 + 0x0E); ptr_index = (curr_rom.loc_gSpecialVar_0x8000 + 0x12); ptr_pkmn_offset = (curr_rom.loc_gSpecialVar_0x8000 + 0x14); + + // TODO: For old script, can be removed later + ptr_callASM = (curr_rom.loc_gSpecialVar_0x8000 + 0x00); + ptr_script_ptr_low = (curr_rom.loc_gSpecialVar_0x8000 + 0x02); + ptr_script_ptr_high = (curr_rom.loc_gSpecialVar_0x8000 + 0x04); + ptr_call_return_1 = (curr_rom.loc_gSpecialVar_0x8000 + 0x06); + ptr_block_ptr_low = (curr_rom.loc_gSaveBlock1PTR + 0x00); + ptr_block_ptr_high = (curr_rom.loc_gSaveBlock1PTR + 0x02); } void mystery_gift_script::build_script(Pokemon_Party &incoming_box_data) @@ -754,6 +774,221 @@ void mystery_gift_script::build_script(Pokemon_Party &incoming_box_data) } }; +void mystery_gift_script::build_script_old(Pokemon_Party &incoming_box_data) +{ + std::vector asm_variable_list; + asm_var sendMonToPC_ptr(curr_rom.loc_sendMonToPC + READ_AS_THUMB, asm_variable_list, &curr_mg_index); + asm_var returned_box_success_ptr(ptr_box_return, asm_variable_list, &curr_mg_index); + asm_var curr_pkmn_index_ptr(ptr_pkmn_offset, asm_variable_list, &curr_mg_index); + asm_var setPokedexFlag_ptr(curr_rom.loc_setPokedexFlag + READ_AS_THUMB, asm_variable_list, &curr_mg_index); + asm_var dexSeenCaught_ptr(ptr_dex_seen_caught, asm_variable_list, &curr_mg_index); + asm_var currPkmnIndex_ptr(ptr_index, asm_variable_list, &curr_mg_index); + asm_var pkmnStruct(curr_rom.loc_gSaveDataBuffer, asm_variable_list, &curr_mg_index); + asm_var dexStruct(curr_rom.loc_gSaveDataBuffer + (MAX_PKMN_IN_BOX * POKEMON_SIZE), asm_variable_list, &curr_mg_index); + asm_var flashBuffer_ptr(curr_rom.loc_gSaveDataBuffer, asm_variable_list, &curr_mg_index); + asm_var readFlashSector_ptr(curr_rom.loc_readFlashSector + READ_AS_THUMB, asm_variable_list, &curr_mg_index); + xse_var mainAsmStart(asm_variable_list, &curr_mg_index); + xse_var dexAsmStart(asm_variable_list, &curr_mg_index); + xse_var readFlashStart(asm_variable_list, &curr_mg_index); + + xse_var jumpLoop(asm_variable_list, &curr_mg_index); + xse_var jumpBoxFull(asm_variable_list, &curr_mg_index); + xse_var jumpPkmnCollected(asm_variable_list, &curr_mg_index); + xse_var jumpAllCollected(asm_variable_list, &curr_mg_index); + + textbox_var textGreet(asm_variable_list, &curr_mg_index); + textbox_var textReceived(asm_variable_list, &curr_mg_index); + textbox_var textPCFull(asm_variable_list, &curr_mg_index); + textbox_var textThank(asm_variable_list, &curr_mg_index); + textbox_var textTest(asm_variable_list, &curr_mg_index); + + // Ş = Wait for button and scroll text + // ȼ = Wait for button and clear text + // Ȇ = Escape character + // Ʋ = Variable escape sequence + // À = Player name + // Ň = New line + // ƞ = string terminator + textGreet.set_text((curr_rom.text_region == TEXT_HOENN) + ? u"LANETTE: Hey ƲÀ!ȼPROFESSOR FENNEL told me that you’dŇbe coming by for these POKÉMON!" + : u"BILL: Hey ƲÀ!ȼPROFESSOR FENNEL told me that you’dŇbe coming by for these POKÉMON!"); + textThank.set_text(u"Thanks for helping out FENNEL!"); + textPCFull.set_text(u"The PC is full…ȼGo make some more room!"); + textReceived.set_text(u"ȆÀÁƲÀ’S POKÉMON were sent to theŇPC!"); + textTest.set_text(u"Testing..."); + + // Located at 0x?8A8 in the .sav + init_npc_location(curr_rom.map_bank, curr_rom.map_id, curr_rom.npc_id); // Set the location of the NPC + setvirtualaddress(VIRTUAL_ADDRESS); // Set virtual address + lock(); // Lock the player + faceplayer(); // Have the NPC face the player + checkflag(curr_rom.all_collected_flag); // Check if the "all collected" flag has been set + virtualgotoif(COND_FLAGTRUE, jumpAllCollected.add_reference(2)); // If "all collected" is true, then jump to the "thank you" text + virtualmsgbox(textGreet.add_reference(1)); // Otherwise, greet the player + waitmsg(); // Wait for the message to finish + waitkeypress(); // Wait for the player to press A/B + setvar(var_index, 0); // set the index to 0 + setvar(var_callASM, rev_endian(0x0023)); // set the call_asm variable to 0x23: 0x23 = CALL ASM + setvar(var_pkmn_offset, 0); // Set the Pokemon struct offset to 0 + if (curr_rom.is_ruby_sapphire()) // Ruby and Sapphire don't shift their save blocks around, so we can hardcode it + { // FOR RUBY AND SAPPHIRE: + setvar(var_script_ptr_low, curr_rom.loc_gSaveBlock1 & 0xFFFF); // Copy the first two bytes of the saveblock1 location to a variable + setvar(var_script_ptr_high, curr_rom.loc_gSaveBlock1 >> 16); // Copy the second two bytes of the saveblock1 location to a variable + } // + else // + { // FOR FIRERED, LEAFGREEN, AND EMERALD + copybyte(ptr_script_ptr_low, ptr_block_ptr_low); // Copy the first byte of the saveblock1ptr to a variable + copybyte(ptr_script_ptr_low + 1, ptr_block_ptr_low + 1); // Copy the second byte of the saveblock1ptr to a variable + copybyte(ptr_script_ptr_high, ptr_block_ptr_high); // Copy the third byte of the saveblock1ptr to a variable + copybyte(ptr_script_ptr_high + 1, ptr_block_ptr_high + 1); // Copy the fourth byte of the saveblock1ptr to a variable + } // + addvar(var_script_ptr_low, curr_rom.offset_ramscript + 8 + READ_AS_THUMB); // add the offset for ramscript, plus 8. 8 is for the 8 bytes of Checksum, padding and NPC info + addvar(var_script_ptr_low, readFlashStart.add_reference(3)); // Add the offset for the start of ASM + setvar(var_call_return_1, rev_endian(0x0300)); // Set the vairable to 0x03. 0x03 = RETURN + setvar(var_call_check_flag, rev_endian(0x2B00)); // Set the variable to 0x2B. 0x2B = CHECK FLAG + addvar(var_call_check_flag, rev_endian(curr_rom.pkmn_collected_flag_start)); // Add the starting flag ID (plus one to ignore the is collected flag) to the check flag ASM variable + setvar(var_call_return_2, rev_endian(0x0003)); // Set the variable to 0x03. 0x03 = RETURN + jumpLoop.set_start(); // Set the jump destination for the JUMP_LOOP + call(ptr_call_check_flag); // Call the check flag ASM + virtualgotoif(COND_FLAGFALSE, jumpPkmnCollected.add_reference(2)); // If the "pokemon collected" flag is false, jump to the end of the loop + call(ptr_callASM); // Call readFlash ASM + addvar(var_script_ptr_low, mainAsmStart.add_reference(3, &readFlashStart)); // add to the CallASM offset so that it points to MAIN_ASM_START instead + call(ptr_callASM); // Call SendMonToPC ASM + compare(var_box_return, 2); // Compare the resulting return to #2 + virtualgotoif(COND_EQUALS, jumpBoxFull.add_reference(2)); // If the return value was #2, jump to the box full message + addvar(var_script_ptr_low, dexAsmStart.add_reference(3, &mainAsmStart)); // add to the CallASM offset so that it points to PTR_DEX_START instead + setvar(var_dex_seen_caught, 2); // set the seen caught variable to 2, so that the Pokemon is set to "seen" + call(ptr_callASM); // call "PTR_DEX_START" + addvar(var_dex_seen_caught, 1); // add 1 to the seen caught variable so that the Pokemon will be "Caught" + call(ptr_callASM); // Call "PTR_DEX_START" again + subvar(var_script_ptr_low, dexAsmStart.add_reference(3, &mainAsmStart)); // subtract from the CallASM offset so that it points to CALL_ASM again + subvar(var_script_ptr_low, mainAsmStart.add_reference(3, &readFlashStart)); // subtract from the CallASM offset so that it points to READ_FLASH + jumpPkmnCollected.set_start(); // Set the jump destination for if the Pokemon has already been collected + addvar(var_pkmn_offset, POKEMON_SIZE); // Add the size of one Pokmeon to the Pokemon offset + addvar(var_index, 1); // Add one to the index + addvar(var_call_check_flag, rev_endian(1)); // Add one to the flag index + compare(var_index, MAX_PKMN_IN_BOX); // Compare the index to 30 + virtualgotoif(COND_LESSTHAN, jumpLoop.add_reference(2)); // if index is less than six, jump to the start of the loop + setflag(curr_rom.all_collected_flag); // Set the "all collected" flag + fanfare(0xA4); // Play the received fanfare + virtualmsgbox(textReceived.add_reference(1)); // Display the recieved text + waitfanfare(); // Wait for the fanfare + waitmsg(); // Wait for the text to finish + waitkeypress(); // Wait for the player to press A/B + jumpAllCollected.set_start(); // Set the destination for if all the Pokemon have already been collected + virtualmsgbox(textThank.add_reference(1)); // Display the thank test + waitmsg(); // Wait for the message + waitkeypress(); // Wait for the player to press A/B + release(); // Release the player + killscript(); // Erase RAMscript + jumpBoxFull.set_start(); // Set the destination for if the box is full + virtualmsgbox(textPCFull.add_reference(1)); // Display the full box message + waitmsg(); // Wait for the message + waitkeypress(); // Wait for the player to presse A/B + release(); // Release the player + end(); // End the script + + textGreet.insert_text(mg_script); + textThank.insert_text(mg_script); + textPCFull.insert_text(mg_script); + textReceived.insert_text(mg_script); + textTest.insert_text(mg_script); + + while (curr_mg_index % 4 != 0) + { + curr_mg_index++; // Align the code so that it is byte aligned + } + + readFlashStart.set_start(); + push(rlist_lr); // save the load register to the stack + mov1(r0, 30); // set r0 to 30 (the sector ID for eReader data) + ldr3(r1, flashBuffer_ptr.add_reference()); // set r1 to the location of "flashBuffer" plus one, since it is thumb code + ldr3(r2, readFlashSector_ptr.add_reference()); // set r2 to the location of "readFlashSector" plus one, since it is thumb code + mov3(r3, r15); // move r15 (the program counter) to r3 + add2(r3, 5); // add 5 to r3 to compensate for the four following bytes, plus to tell the system to read as thumb code + mov3(r14, r3); // move r3 into r14 (the load register) + bx(r2); // jump to the pointer stored in r2 (readFlashSector) + pop(rlist_r0); // remove r0 from the stack and put it into r0 + bx(r0); // go to r0 + // + mainAsmStart.set_start(); // Set the memory pointer location for ASM start + push(rlist_lr); // save the load register to the stack + ldr3(r3, curr_pkmn_index_ptr.add_reference()); // set r3 to the pointer to the pokemon index variable + ldr1(r3, r3, 0); // set r3 to the value in memory r3 points to + add5(r0, pkmnStruct.add_reference()); // set r0 to a pointer to the start of the Pokemon struct. + ldr1(r0, r0, 0); // set r0 to the value in memory r0 points to + add3(r0, r0, r3); // add r3 to r0, giving it the correct offset for the current index + ldr3(r1, sendMonToPC_ptr.add_reference()); // set r1 to the location of "SendMonToPC" plus one, since it is thumb code + mov3(r2, r15); // move r15 (the program counter) to r2 + add2(r2, 5); // add 5 to r2 to compensate for the four following bytes, plus to tell the system to read as thumb code + mov3(r14, r2); // move r2 into r14 (the load register) + bx(r1); // jump to the pointer stored in r1 (SendMonToPC) + ldr3(r2, returned_box_success_ptr.add_reference()); // load variable 0x8006's pointer into r2 + str1(r0, r2, 0); // put the value of r0 into the memory location pointed at by r2, plus 0 + pop(rlist_r0); // remove r0 from the stack and put it into r0 + bx(r0); // jump to r0 (return to where the function was called) + // + dexAsmStart.set_start(); // Note the location where the Dex ASM starts + push(rlist_lr); // save the load register to the stack + ldr3(r0, currPkmnIndex_ptr.add_reference()); // load the pointer to the index variable into r0 + ldr1(r0, r0, 0); // load the value at r0's pointer + mov1(r3, 0xFF); // load 0xFF into r3 + and1(r0, r3); // AND r0 and r3, which will give us just the least significant byte + // + add5(r1, dexStruct.add_reference()); // set r1 to the value stored X bytes ahead + ldr1(r1, r1, 0); // loda the value at the memory location stored in r1 + add3(r0, r0, r1); // add r0 and r1, which is the current index and dex_struct respectivly + ldr1(r0, r0, 0); // load the value at the memory location stored in r0 + and1(r0, r3); // truncate to just the least significant byte, which is the current dex number + ldr3(r1, dexSeenCaught_ptr.add_reference()); // load the dex_seen_caught variable's pointer into r1 + ldr1(r1, r1, 0); // load the value of memory pointed at by r1 + and1(r1, r3); // AND r1 and r3, which will keep only the least significant byte + ldr3(r2, setPokedexFlag_ptr.add_reference()); // load the GetSetPokedexFlag function location into r2 + mov3(r3, r15); // move r15 (the program counter) to r3 + add2(r3, 5); // add 5 to r3 to compensate for the four following bytes, as well as to tell it to read as THUMB code + mov3(r14, r3); // move r3 into r14 (the load register) + bx(r2); // jump to the pointer stored in r2 (GetSetPokedexFlag) + pop(rlist_r0); // remove r0 from the stack and put it into r0 + bx(r0); // jump to r0 (return to where the function was called) + // + // + while (curr_mg_index % 4 != 0) + { + curr_mg_index++; // Align the code so that it is byte aligned + } + add_word(sendMonToPC_ptr.place_word()); // the location of "SendMonToPC", plus one (so it is interpreted as thumb code) + add_word(returned_box_success_ptr.place_word()); // the location of variable "0x8006" (the return value) + add_word(curr_pkmn_index_ptr.place_word()); // the location of variable "0x8008" (the pokemon offset) + add_word(setPokedexFlag_ptr.place_word()); // the location of GetSetPokedexFlag, plus one (so it is interpreted as thumb code) + add_word(dexSeenCaught_ptr.place_word()); // the location of the DEX_SEEN_CAUGHT variable + add_word(currPkmnIndex_ptr.place_word()); // the location of the INDEX variable + add_word(flashBuffer_ptr.place_word()); // the location of the FLASH_BUFFER variable + add_word(readFlashSector_ptr.place_word()); // the location of "readFlashSector", plus one (so it is interpreted as thumb code) + add_word(pkmnStruct.place_word()); // the location of the Pokemon Struct + add_word(dexStruct.place_word()); // the location of the dex struct + // + while (curr_mg_index % 4 != 0) + { + curr_mg_index++; // Align the code so that it is byte aligned + } + for (unsigned int i = 0; i < asm_variable_list.size(); i++) // Fill all the refrences for script variables + { + asm_variable_list[i]->fill_refrences(mg_script); + } + + if (curr_mg_index > MG_SCRIPT_SIZE) // Throw an error if the script is too large + { + tte_erase_screen(); + int val = (curr_mg_index - MG_SCRIPT_SIZE) - four_align_value; + tte_write("Script exceeded by "); + tte_write(std::to_string(val).c_str()); + tte_write(" bytes"); + while (true) + { + } + } +}; + u8 mystery_gift_script::get_script_value_at(int i) { return mg_script[i]; diff --git a/source/mystery_gift_injector.cpp b/source/mystery_gift_injector.cpp index 56c647f..2f7a5e0 100644 --- a/source/mystery_gift_injector.cpp +++ b/source/mystery_gift_injector.cpp @@ -15,7 +15,14 @@ static u8 lanette_wonder_card[0x14E] = { bool inject_mystery(Pokemon_Party &incoming_box_data) { mystery_gift_script script; - script.build_script(incoming_box_data); + if (ENABLE_OLD_EVENT) + { + script.build_script_old(incoming_box_data); + } + else + { + script.build_script(incoming_box_data); + } u32 checksum = 0; if (curr_rom.is_ruby_sapphire()) { @@ -62,12 +69,44 @@ bool inject_mystery(Pokemon_Party &incoming_box_data) copy_save_to_ram(0x1E000, &global_memory_buffer[0], 0x1000); int curr_index = 0; - for (int i = 0; i < 0x1000; i++) // Copy over the save data section + int dex_nums[MAX_PKMN_IN_BOX] = {}; + + if (ENABLE_OLD_EVENT) { - global_memory_buffer[curr_index] = script.get_section30_value_at(i); - curr_index++; + for (int i = 0; i < MAX_PKMN_IN_BOX; i++) // Add in the Pokemon data + { + Pokemon curr_pkmn = incoming_box_data.get_converted_pkmn(i); + if (curr_pkmn.get_validity()) + { + + for (int curr_byte = 0; curr_byte < POKEMON_SIZE; curr_byte++) + { + global_memory_buffer[curr_index] = curr_pkmn.get_gen_3_data(curr_byte); + curr_index++; + } + dex_nums[i] = curr_pkmn.get_dex_number(); + } + else + { + curr_index += POKEMON_SIZE; + } + } + + for (int i = 0; i < MAX_PKMN_IN_BOX; i++) // Add in the dex numbers + { + global_memory_buffer[curr_index] = dex_nums[i]; + curr_index++; + } } - + else + { + for (int i = 0; i < 0x1000; i++) // Copy over the save data section + { + global_memory_buffer[curr_index] = script.get_section30_value_at(i); + curr_index++; + } + } + update_memory_buffer_checksum(false); erase_sector(0x1E000); copy_ram_to_save(&global_memory_buffer[0], 0x1E000, 0x1000); diff --git a/source/rom_data.cpp b/source/rom_data.cpp index 1ba8356..0aeedd0 100644 --- a/source/rom_data.cpp +++ b/source/rom_data.cpp @@ -85,14 +85,17 @@ void rom_data::fill_values(const ROM_DATA *rom_values) all_collected_flag = rom_values->unused_flag_start; // The flag for if everything has been collected pkmn_collected_flag_start = rom_values->unused_flag_start + 1; // The beginning of the flags for each of the Pokemon - map_bank = (DEBUG_MODE ? rom_values->test_map_bank : rom_values->map_bank); - map_id = (DEBUG_MODE ? rom_values->test_map_id : rom_values->map_id); - npc_id = (DEBUG_MODE ? rom_values->test_npc_id : rom_values->npc_id); + map_bank = (ENABLE_OLD_EVENT ? rom_values->old_map_bank : rom_values->map_bank); + map_id = (ENABLE_OLD_EVENT ? rom_values->old_map_id : rom_values->map_id); + npc_id = (ENABLE_OLD_EVENT ? rom_values->old_npc_id : rom_values->npc_id); npc_palette = rom_values->npc_palette; def_map_bank = rom_values->def_map_bank; def_map_id = rom_values->def_map_id; def_npc_id = rom_values->def_npc_id; + + loc_gSaveBlock1PTR = rom_values->loc_gSaveBlock1PTR; // TODO: Only used for old script, can be removed later + } bool rom_data::is_hoenn() diff --git a/source/script_var.cpp b/source/script_var.cpp index edf7cd6..208e859 100644 --- a/source/script_var.cpp +++ b/source/script_var.cpp @@ -2,6 +2,7 @@ #include #include "script_var.h" #include "pokemon_data.h" +#include "debug_mode.h" extern rom_data curr_rom; @@ -142,7 +143,7 @@ void textbox_var::set_text(std::u16string_view nText) void textbox_var::set_start() { - start_location_in_script = *curr_loc_ptr; + start_location_in_script = *curr_loc_ptr - (ENABLE_OLD_EVENT * 4); } void textbox_var::set_virtual_start()