From 5950e53e885ee5e7d35ef32a92242379aadd76b7 Mon Sep 17 00:00:00 2001 From: The Gears of Progress Date: Sat, 22 Jun 2024 11:24:43 -0400 Subject: [PATCH] Continuing work on updated event --- graphics/mario.grit | 4 + graphics/mario.png | Bin 0 -> 319 bytes include/debug_mode.h | 8 +- include/gba_rom_values/base_gba_rom_struct.h | 1 + include/gba_rom_values/eng_gba_rom_values.h | 13 +- include/mystery_gift_builder.h | 219 +++++- include/rom_data.h | 1 + include/script_var.h | 29 +- include/sprite_data.h | 2 + source/mystery_gift_builder.cpp | 730 +++++++++++++------ source/mystery_gift_injector.cpp | 16 +- source/pokemon_party.cpp | 12 +- source/rom_data.cpp | 3 + source/script_var.cpp | 83 ++- 14 files changed, 869 insertions(+), 252 deletions(-) create mode 100644 graphics/mario.grit create mode 100644 graphics/mario.png diff --git a/graphics/mario.grit b/graphics/mario.grit new file mode 100644 index 0000000..6793a81 --- /dev/null +++ b/graphics/mario.grit @@ -0,0 +1,4 @@ +# +# Metroid : 4bpp, not compressed. Only use the first 64 columns. +# +-gB4 -ps0 -pe16 \ No newline at end of file diff --git a/graphics/mario.png b/graphics/mario.png new file mode 100644 index 0000000000000000000000000000000000000000..e6514380cee3019ebe36a875d76ffb7ed16a6a7a GIT binary patch literal 319 zcmeAS@N?(olHy`uVBq!ia0vp^0zj<5!VDx|E`RzTNErn9gt#)4lypQ$0C^2JPW*5v z_;KNYfEaktF(*0U0Q;%a+y_i{pB5}P=-&Ieq}#e<;gTgwE;5NE1u<>Bvyf*g-+~F3&de@8 z$kXQOSggM?E+Ii+u87IkNvm`w2v(Vgc#5Bxu(vwU^u;^Yj&-}IiyUBUyBErom9(e& z`#V?G39?O(MBggRDtvaNOngG+B;)k19b23w<=zUcoYrTg&@8;fg7-v1bWTj%Hl9NU zajZ!ODXP(Hy%>x)g*i&(WM*b2^lNHyaW!Qub7p64J-{=ed4dxI!_r{O{!-o0)ga$_ My85}Sb4q9e0C})^WB>pF literal 0 HcmV?d00001 diff --git a/include/debug_mode.h b/include/debug_mode.h index ca1f1a3..f11d487 100644 --- a/include/debug_mode.h +++ b/include/debug_mode.h @@ -2,10 +2,10 @@ #define DEBUG_MODE_H #define DEBUG_MODE false -#define IGNORE_GAME_PAK false -#define IGNORE_LINK_CABLE false -#define IGNORE_MG_E4_FLAGS false -#define IGNORE_UNRECEIVED_PKMN false +#define IGNORE_GAME_PAK true +#define IGNORE_LINK_CABLE true +#define IGNORE_MG_E4_FLAGS true +#define IGNORE_UNRECEIVED_PKMN true #define FORCE_TUTORIAL false #define DONT_REMOVE_PKMN false #define SHOW_INVALID_PKMN false diff --git a/include/gba_rom_values/base_gba_rom_struct.h b/include/gba_rom_values/base_gba_rom_struct.h index 6a96321..f178fdd 100644 --- a/include/gba_rom_values/base_gba_rom_struct.h +++ b/include/gba_rom_values/base_gba_rom_struct.h @@ -40,6 +40,7 @@ struct ROM_DATA int loc_getSetPokedexFlag; int loc_gSaveDataBuffer; // The location of the saveDataBuffer int loc_readFlashSector; + int loc_loadSaveSection30; // The location of the function that loads save section 30: CEReaderTool_LoadTrainerTower_r in FRLG, TryReadTrainerHill_Internal in Emerald int offset_ramscript; // Ramscript offset as found within the SaveBlock1 struct in global.h int offset_flags; // Flag offset as found within the SaveBlock1 struct in global.h int offset_wondercard; diff --git a/include/gba_rom_values/eng_gba_rom_values.h b/include/gba_rom_values/eng_gba_rom_values.h index 3427593..5ea87d1 100644 --- a/include/gba_rom_values/eng_gba_rom_values.h +++ b/include/gba_rom_values/eng_gba_rom_values.h @@ -3,6 +3,8 @@ #include "gba_rom_values/base_gba_rom_struct.h" +const struct ROM_DATA test = {.is_valid = true}; + const struct ROM_DATA ENG_RUBY_v0 = { .is_valid = true, @@ -238,6 +240,7 @@ const struct ROM_DATA ENG_FIRERED_v0 = { .loc_getSetPokedexFlag = 0x08088E8C, .loc_gSaveDataBuffer = 0x02039A38, // The location of the saveDataBuffer .loc_readFlashSector = 0x080DA190, + .loc_loadSaveSection30 = 0x0815D7BC,// The location of the function that loads save section 30: CEReaderTool_LoadTrainerTower_r in FRLG, TryReadTrainerHill_Internal in Emerald // The following should be consistant across languages and revisions. .offset_ramscript = 0x361C, // Ramscript offset as found within the SaveBlock1 struct in global.h @@ -276,6 +279,7 @@ const struct ROM_DATA ENG_LEAFGREEN_v0 = { .loc_getSetPokedexFlag = 0x08088E48, .loc_gSaveDataBuffer = 0x02039A38, // The location of the saveDataBuffer .loc_readFlashSector = 0x080DA164, + .loc_loadSaveSection30 = 0x0815D798,// The location of the function that loads save section 30: CEReaderTool_LoadTrainerTower_r in FRLG, TryReadTrainerHill_Internal in Emerald // The following should be consistant across languages and revisions. .offset_ramscript = 0x361C, // Ramscript offset as found within the SaveBlock1 struct in global.h @@ -314,6 +318,7 @@ const struct ROM_DATA ENG_FIRERED_v1 = { .loc_getSetPokedexFlag = 0x08088E88, .loc_gSaveDataBuffer = 0x02039A38, // The location of the saveDataBuffer .loc_readFlashSector = 0x080DA1A4, + .loc_loadSaveSection30 = 0x0815D834,// The location of the function that loads save section 30: CEReaderTool_LoadTrainerTower_r in FRLG, TryReadTrainerHill_Internal in Emerald // The following should be consistant across languages and revisions. .offset_ramscript = 0x361C, // Ramscript offset as found within the SaveBlock1 struct in global.h @@ -349,10 +354,11 @@ const struct ROM_DATA ENG_LEAFGREEN_v1 = { .loc_copyMonToPC = 0x08040BA4, .loc_gSpecialVar_0x8000 = 0x020370B8, .loc_gSaveBlock1PTR = 0x03005008, - .loc_getSetPokedexFlag = 0x08088E74, + .loc_getSetPokedexFlag = 0x08088E5C, .loc_gSaveDataBuffer = 0x02039A38, // The location of the saveDataBuffer .loc_readFlashSector = 0x080DA178, - + .loc_loadSaveSection30 = 0x0815D810,// The location of the function that loads save section 30: CEReaderTool_LoadTrainerTower_r in FRLG, TryReadTrainerHill_Internal in Emerald + // The following should be consistant across languages and revisions. .offset_ramscript = 0x361C, // Ramscript offset as found within the SaveBlock1 struct in global.h .offset_flags = 0x0EE0, // Flag offset as found within the SaveBlock1 struct in global.h @@ -365,7 +371,7 @@ const struct ROM_DATA ENG_LEAFGREEN_v1 = { .mg_flag = 0x860 + 0x7B, // The flag that is set when you enable Mystery Gift. Known as "EXDATA_ENABLE" in RS .unused_flag_start = 0x20, // The start of the unused flags and must have 31 open flags in a row - .map_bank = 30, + .map_bank = 31, .map_id = 0, .npc_id = 1, @@ -390,6 +396,7 @@ const struct ROM_DATA ENG_EMERALD_v0 = { .loc_getSetPokedexFlag = 0x080C0664, .loc_gSaveDataBuffer = 0x0203ABBC, // The location of the saveDataBuffer .loc_readFlashSector = 0x0815314C, + .loc_loadSaveSection30 = 0x081D3AD8,// The location of the function that loads save section 30: CEReaderTool_LoadTrainerTower_r in FRLG, TryReadTrainerHill_Internal in Emerald // The following should be consistant across languages and revisions. .offset_ramscript = 0x3728, // Ramscript offset as found within the SaveBlock1 struct in global.h diff --git a/include/mystery_gift_builder.h b/include/mystery_gift_builder.h index 2248ebb..29bd9ba 100644 --- a/include/mystery_gift_builder.h +++ b/include/mystery_gift_builder.h @@ -16,7 +16,7 @@ #define NPC_LOCATION_OFFSET 0x4 #define READ_AS_THUMB 0x1 -#define VAR_ID_START 0x8000 // This one should also stay consistant +#define VAR_ID_START 0x8000 // This one should also stay consistant #define VIRTUAL_ADDRESS 0x08000000 // This will also stay constant #define TEXT_KANTO 0 @@ -58,12 +58,206 @@ #define rlist_r7 0b010000001 #define rlist_lr 0b100000000 -// Text conversion definitions +#define MOVEMENT_ACTION_FACE_DOWN curr_rom.is_hoenn() ? 0x0 : 0x0 +#define MOVEMENT_ACTION_FACE_UP curr_rom.is_hoenn() ? 0x1 : 0x1 +#define MOVEMENT_ACTION_FACE_LEFT curr_rom.is_hoenn() ? 0x2 : 0x2 +#define MOVEMENT_ACTION_FACE_RIGHT curr_rom.is_hoenn() ? 0x3 : 0x3 +#define MOVEMENT_ACTION_WALK_SLOW_DOWN curr_rom.is_hoenn() ? 0x4 : 0xC +#define MOVEMENT_ACTION_WALK_SLOW_UP curr_rom.is_hoenn() ? 0x5 : 0xD +#define MOVEMENT_ACTION_WALK_SLOW_LEFT curr_rom.is_hoenn() ? 0x6 : 0xE +#define MOVEMENT_ACTION_WALK_SLOW_RIGHT curr_rom.is_hoenn() ? 0x7 : 0xF +#define MOVEMENT_ACTION_WALK_NORMAL_DOWN curr_rom.is_hoenn() ? 0x8 : 0x10 +#define MOVEMENT_ACTION_WALK_NORMAL_UP curr_rom.is_hoenn() ? 0x9 : 0x11 +#define MOVEMENT_ACTION_WALK_NORMAL_LEFT curr_rom.is_hoenn() ? 0xA : 0x12 +#define MOVEMENT_ACTION_WALK_NORMAL_RIGHT curr_rom.is_hoenn() ? 0xB : 0x13 +#define MOVEMENT_ACTION_JUMP_2_DOWN curr_rom.is_hoenn() ? 0xC : 0x14 +#define MOVEMENT_ACTION_JUMP_2_UP curr_rom.is_hoenn() ? 0xD : 0x15 +#define MOVEMENT_ACTION_JUMP_2_LEFT curr_rom.is_hoenn() ? 0xE : 0x16 +#define MOVEMENT_ACTION_JUMP_2_RIGHT curr_rom.is_hoenn() ? 0xF : 0x17 +#define MOVEMENT_ACTION_DELAY_1 curr_rom.is_hoenn() ? 0x10 : 0x18 +#define MOVEMENT_ACTION_DELAY_2 curr_rom.is_hoenn() ? 0x11 : 0x19 +#define MOVEMENT_ACTION_DELAY_4 curr_rom.is_hoenn() ? 0x12 : 0x1A +#define MOVEMENT_ACTION_DELAY_8 curr_rom.is_hoenn() ? 0x13 : 0x1B +#define MOVEMENT_ACTION_DELAY_16 curr_rom.is_hoenn() ? 0x14 : 0x1C +#define MOVEMENT_ACTION_WALK_FAST_DOWN curr_rom.is_hoenn() ? 0x15 : 0x1D +#define MOVEMENT_ACTION_WALK_FAST_UP curr_rom.is_hoenn() ? 0x16 : 0x1E +#define MOVEMENT_ACTION_WALK_FAST_LEFT curr_rom.is_hoenn() ? 0x17 : 0x1F +#define MOVEMENT_ACTION_WALK_FAST_RIGHT curr_rom.is_hoenn() ? 0x18 : 0x20 +#define MOVEMENT_ACTION_WALK_IN_PLACE_SLOW_DOWN curr_rom.is_hoenn() ? 0x19 : 0x21 +#define MOVEMENT_ACTION_WALK_IN_PLACE_SLOW_UP curr_rom.is_hoenn() ? 0x1A : 0x22 +#define MOVEMENT_ACTION_WALK_IN_PLACE_SLOW_LEFT curr_rom.is_hoenn() ? 0x1B : 0x23 +#define MOVEMENT_ACTION_WALK_IN_PLACE_SLOW_RIGHT curr_rom.is_hoenn() ? 0x1C : 0x24 +#define MOVEMENT_ACTION_WALK_IN_PLACE_NORMAL_DOWN curr_rom.is_hoenn() ? 0x1D : 0x25 +#define MOVEMENT_ACTION_WALK_IN_PLACE_NORMAL_UP curr_rom.is_hoenn() ? 0x1E : 0x26 +#define MOVEMENT_ACTION_WALK_IN_PLACE_NORMAL_LEFT curr_rom.is_hoenn() ? 0x1F : 0x27 +#define MOVEMENT_ACTION_WALK_IN_PLACE_NORMAL_RIGHT curr_rom.is_hoenn() ? 0x20 : 0x28 +#define MOVEMENT_ACTION_WALK_IN_PLACE_FAST_DOWN curr_rom.is_hoenn() ? 0x21 : 0x29 +#define MOVEMENT_ACTION_WALK_IN_PLACE_FAST_UP curr_rom.is_hoenn() ? 0x22 : 0x2A +#define MOVEMENT_ACTION_WALK_IN_PLACE_FAST_LEFT curr_rom.is_hoenn() ? 0x23 : 0x2B +#define MOVEMENT_ACTION_WALK_IN_PLACE_FAST_RIGHT curr_rom.is_hoenn() ? 0x24 : 0x2C +#define MOVEMENT_ACTION_WALK_IN_PLACE_FASTER_DOWN curr_rom.is_hoenn() ? 0x25 : 0x2D +#define MOVEMENT_ACTION_WALK_IN_PLACE_FASTER_UP curr_rom.is_hoenn() ? 0x26 : 0x2E +#define MOVEMENT_ACTION_WALK_IN_PLACE_FASTER_LEFT curr_rom.is_hoenn() ? 0x27 : 0x2F +#define MOVEMENT_ACTION_WALK_IN_PLACE_FASTER_RIGHT curr_rom.is_hoenn() ? 0x28 : 0x30 +#define MOVEMENT_ACTION_RIDE_WATER_CURRENT_DOWN curr_rom.is_hoenn() ? 0x29 : 0x31 +#define MOVEMENT_ACTION_RIDE_WATER_CURRENT_UP curr_rom.is_hoenn() ? 0x2A : 0x32 +#define MOVEMENT_ACTION_RIDE_WATER_CURRENT_LEFT curr_rom.is_hoenn() ? 0x2B : 0x33 +#define MOVEMENT_ACTION_RIDE_WATER_CURRENT_RIGHT curr_rom.is_hoenn() ? 0x2C : 0x34 +#define MOVEMENT_ACTION_WALK_FASTER_DOWN curr_rom.is_hoenn() ? 0x2D : 0x35 +#define MOVEMENT_ACTION_WALK_FASTER_UP curr_rom.is_hoenn() ? 0x2E : 0x36 +#define MOVEMENT_ACTION_WALK_FASTER_LEFT curr_rom.is_hoenn() ? 0x2F : 0x37 +#define MOVEMENT_ACTION_WALK_FASTER_RIGHT curr_rom.is_hoenn() ? 0x30 : 0x38 +#define MOVEMENT_ACTION_SLIDE_DOWN curr_rom.is_hoenn() ? 0x31 : 0x39 +#define MOVEMENT_ACTION_SLIDE_UP curr_rom.is_hoenn() ? 0x32 : 0x3A +#define MOVEMENT_ACTION_SLIDE_LEFT curr_rom.is_hoenn() ? 0x33 : 0x3B +#define MOVEMENT_ACTION_SLIDE_RIGHT curr_rom.is_hoenn() ? 0x34 : 0x3C +#define MOVEMENT_ACTION_PLAYER_RUN_DOWN curr_rom.is_hoenn() ? 0x35 : 0x3D +#define MOVEMENT_ACTION_PLAYER_RUN_UP curr_rom.is_hoenn() ? 0x36 : 0x3E +#define MOVEMENT_ACTION_PLAYER_RUN_LEFT curr_rom.is_hoenn() ? 0x37 : 0x3F +#define MOVEMENT_ACTION_PLAYER_RUN_RIGHT curr_rom.is_hoenn() ? 0x38 : 0x40 +#define MOVEMENT_ACTION_START_ANIM_IN_DIRECTION curr_rom.is_hoenn() ? 0x39 : 0x45 +#define MOVEMENT_ACTION_JUMP_SPECIAL_DOWN curr_rom.is_hoenn() ? 0x3A : 0x46 +#define MOVEMENT_ACTION_JUMP_SPECIAL_UP curr_rom.is_hoenn() ? 0x3B : 0x47 +#define MOVEMENT_ACTION_JUMP_SPECIAL_LEFT curr_rom.is_hoenn() ? 0x3C : 0x48 +#define MOVEMENT_ACTION_JUMP_SPECIAL_RIGHT curr_rom.is_hoenn() ? 0x3D : 0x49 +#define MOVEMENT_ACTION_FACE_PLAYER curr_rom.is_hoenn() ? 0x3E : 0x4A +#define MOVEMENT_ACTION_FACE_AWAY_PLAYER curr_rom.is_hoenn() ? 0x3F : 0x4B +#define MOVEMENT_ACTION_LOCK_FACING_DIRECTION curr_rom.is_hoenn() ? 0x40 : 0x4C +#define MOVEMENT_ACTION_UNLOCK_FACING_DIRECTION curr_rom.is_hoenn() ? 0x41 : 0x4D +#define MOVEMENT_ACTION_JUMP_DOWN curr_rom.is_hoenn() ? 0x42 : 0x4E +#define MOVEMENT_ACTION_JUMP_UP curr_rom.is_hoenn() ? 0x43 : 0x4F +#define MOVEMENT_ACTION_JUMP_LEFT curr_rom.is_hoenn() ? 0x44 : 0x50 +#define MOVEMENT_ACTION_JUMP_RIGHT curr_rom.is_hoenn() ? 0x45 : 0x51 +#define MOVEMENT_ACTION_JUMP_IN_PLACE_DOWN curr_rom.is_hoenn() ? 0x46 : 0x52 +#define MOVEMENT_ACTION_JUMP_IN_PLACE_UP curr_rom.is_hoenn() ? 0x47 : 0x53 +#define MOVEMENT_ACTION_JUMP_IN_PLACE_LEFT curr_rom.is_hoenn() ? 0x48 : 0x54 +#define MOVEMENT_ACTION_JUMP_IN_PLACE_RIGHT curr_rom.is_hoenn() ? 0x49 : 0x55 +#define MOVEMENT_ACTION_JUMP_IN_PLACE_DOWN_UP curr_rom.is_hoenn() ? 0x4A : 0x56 +#define MOVEMENT_ACTION_JUMP_IN_PLACE_UP_DOWN curr_rom.is_hoenn() ? 0x4B : 0x57 +#define MOVEMENT_ACTION_JUMP_IN_PLACE_LEFT_RIGHT curr_rom.is_hoenn() ? 0x4C : 0x58 +#define MOVEMENT_ACTION_JUMP_IN_PLACE_RIGHT_LEFT curr_rom.is_hoenn() ? 0x4D : 0x59 +#define MOVEMENT_ACTION_FACE_ORIGINAL_DIRECTION curr_rom.is_hoenn() ? 0x4E : 0x5A +#define MOVEMENT_ACTION_NURSE_JOY_BOW_DOWN curr_rom.is_hoenn() ? 0x4F : 0x5B +#define MOVEMENT_ACTION_ENABLE_JUMP_LANDING_GROUND_EFFECT curr_rom.is_hoenn() ? 0x50 : 0x5C +#define MOVEMENT_ACTION_DISABLE_JUMP_LANDING_GROUND_EFFECT curr_rom.is_hoenn() ? 0x51 : 0x5D +#define MOVEMENT_ACTION_DISABLE_ANIMATION curr_rom.is_hoenn() ? 0x52 : 0x5E +#define MOVEMENT_ACTION_RESTORE_ANIMATION curr_rom.is_hoenn() ? 0x53 : 0x5F +#define MOVEMENT_ACTION_SET_INVISIBLE curr_rom.is_hoenn() ? 0x54 : 0x60 +#define MOVEMENT_ACTION_SET_VISIBLE curr_rom.is_hoenn() ? 0x55 : 0x61 +#define MOVEMENT_ACTION_EMOTE_EXCLAMATION_MARK curr_rom.is_hoenn() ? 0x56 : 0x62 +#define MOVEMENT_ACTION_EMOTE_QUESTION_MARK curr_rom.is_hoenn() ? 0x57 : 0x63 +#define MOVEMENT_ACTION_EMOTE_HEART curr_rom.is_hoenn() ? 0x58 : 0xFF +#define MOVEMENT_ACTION_REVEAL_TRAINER curr_rom.is_hoenn() ? 0x59 : 0x67 +#define MOVEMENT_ACTION_ROCK_SMASH_BREAK curr_rom.is_hoenn() ? 0x5A : 0x68 +#define MOVEMENT_ACTION_CUT_TREE curr_rom.is_hoenn() ? 0x5B : 0x69 +#define MOVEMENT_ACTION_SET_FIXED_PRIORITY curr_rom.is_hoenn() ? 0x5C : 0x6A +#define MOVEMENT_ACTION_CLEAR_FIXED_PRIORITY curr_rom.is_hoenn() ? 0x5D : 0x6B +#define MOVEMENT_ACTION_INIT_AFFINE_ANIM curr_rom.is_hoenn() ? 0x5E : 0x6C +#define MOVEMENT_ACTION_CLEAR_AFFINE_ANIM curr_rom.is_hoenn() ? 0x5F : 0x6D +#define MOVEMENT_ACTION_HIDE_REFLECTION curr_rom.is_hoenn() ? 0x60 : 0xFF +#define MOVEMENT_ACTION_SHOW_REFLECTION curr_rom.is_hoenn() ? 0x61 : 0xFF +#define MOVEMENT_ACTION_WALK_DOWN_START_AFFINE curr_rom.is_hoenn() ? 0x62 : 0x6E +#define MOVEMENT_ACTION_WALK_DOWN_AFFINE curr_rom.is_hoenn() ? 0x63 : 0x6F +#define MOVEMENT_ACTION_ACRO_WHEELIE_FACE_DOWN curr_rom.is_hoenn() ? 0x64 : 0x70 +#define MOVEMENT_ACTION_ACRO_WHEELIE_FACE_UP curr_rom.is_hoenn() ? 0x65 : 0x71 +#define MOVEMENT_ACTION_ACRO_WHEELIE_FACE_LEFT curr_rom.is_hoenn() ? 0x66 : 0x72 +#define MOVEMENT_ACTION_ACRO_WHEELIE_FACE_RIGHT curr_rom.is_hoenn() ? 0x67 : 0x73 +#define MOVEMENT_ACTION_ACRO_POP_WHEELIE_DOWN curr_rom.is_hoenn() ? 0x68 : 0x74 +#define MOVEMENT_ACTION_ACRO_POP_WHEELIE_UP curr_rom.is_hoenn() ? 0x69 : 0x75 +#define MOVEMENT_ACTION_ACRO_POP_WHEELIE_LEFT curr_rom.is_hoenn() ? 0x6A : 0x76 +#define MOVEMENT_ACTION_ACRO_POP_WHEELIE_RIGHT curr_rom.is_hoenn() ? 0x6B : 0x77 +#define MOVEMENT_ACTION_ACRO_END_WHEELIE_FACE_DOWN curr_rom.is_hoenn() ? 0x6C : 0x78 +#define MOVEMENT_ACTION_ACRO_END_WHEELIE_FACE_UP curr_rom.is_hoenn() ? 0x6D : 0x79 +#define MOVEMENT_ACTION_ACRO_END_WHEELIE_FACE_LEFT curr_rom.is_hoenn() ? 0x6E : 0x7A +#define MOVEMENT_ACTION_ACRO_END_WHEELIE_FACE_RIGHT curr_rom.is_hoenn() ? 0x6F : 0x7B +#define MOVEMENT_ACTION_ACRO_WHEELIE_HOP_FACE_DOWN curr_rom.is_hoenn() ? 0x70 : 0x7C +#define MOVEMENT_ACTION_ACRO_WHEELIE_HOP_FACE_UP curr_rom.is_hoenn() ? 0x71 : 0x7D +#define MOVEMENT_ACTION_ACRO_WHEELIE_HOP_FACE_LEFT curr_rom.is_hoenn() ? 0x72 : 0x7E +#define MOVEMENT_ACTION_ACRO_WHEELIE_HOP_FACE_RIGHT curr_rom.is_hoenn() ? 0x73 : 0x7F +#define MOVEMENT_ACTION_ACRO_WHEELIE_HOP_DOWN curr_rom.is_hoenn() ? 0x74 : 0x80 +#define MOVEMENT_ACTION_ACRO_WHEELIE_HOP_UP curr_rom.is_hoenn() ? 0x75 : 0x81 +#define MOVEMENT_ACTION_ACRO_WHEELIE_HOP_LEFT curr_rom.is_hoenn() ? 0x76 : 0x82 +#define MOVEMENT_ACTION_ACRO_WHEELIE_HOP_RIGHT curr_rom.is_hoenn() ? 0x77 : 0x83 +#define MOVEMENT_ACTION_ACRO_WHEELIE_JUMP_DOWN curr_rom.is_hoenn() ? 0x78 : 0x84 +#define MOVEMENT_ACTION_ACRO_WHEELIE_JUMP_UP curr_rom.is_hoenn() ? 0x79 : 0x85 +#define MOVEMENT_ACTION_ACRO_WHEELIE_JUMP_LEFT curr_rom.is_hoenn() ? 0x7A : 0x86 +#define MOVEMENT_ACTION_ACRO_WHEELIE_JUMP_RIGHT curr_rom.is_hoenn() ? 0x7B : 0x87 +#define MOVEMENT_ACTION_ACRO_WHEELIE_IN_PLACE_DOWN curr_rom.is_hoenn() ? 0x7C : 0x88 +#define MOVEMENT_ACTION_ACRO_WHEELIE_IN_PLACE_UP curr_rom.is_hoenn() ? 0x7D : 0x89 +#define MOVEMENT_ACTION_ACRO_WHEELIE_IN_PLACE_LEFT curr_rom.is_hoenn() ? 0x7E : 0x8A +#define MOVEMENT_ACTION_ACRO_WHEELIE_IN_PLACE_RIGHT curr_rom.is_hoenn() ? 0x7F : 0x8B +#define MOVEMENT_ACTION_ACRO_POP_WHEELIE_MOVE_DOWN curr_rom.is_hoenn() ? 0x80 : 0x8C +#define MOVEMENT_ACTION_ACRO_POP_WHEELIE_MOVE_UP curr_rom.is_hoenn() ? 0x81 : 0x8D +#define MOVEMENT_ACTION_ACRO_POP_WHEELIE_MOVE_LEFT curr_rom.is_hoenn() ? 0x82 : 0x8E +#define MOVEMENT_ACTION_ACRO_POP_WHEELIE_MOVE_RIGHT curr_rom.is_hoenn() ? 0x83 : 0x8F +#define MOVEMENT_ACTION_ACRO_WHEELIE_MOVE_DOWN curr_rom.is_hoenn() ? 0x84 : 0x90 +#define MOVEMENT_ACTION_ACRO_WHEELIE_MOVE_UP curr_rom.is_hoenn() ? 0x85 : 0x91 +#define MOVEMENT_ACTION_ACRO_WHEELIE_MOVE_LEFT curr_rom.is_hoenn() ? 0x86 : 0x92 +#define MOVEMENT_ACTION_ACRO_WHEELIE_MOVE_RIGHT curr_rom.is_hoenn() ? 0x87 : 0x93 +#define MOVEMENT_ACTION_ACRO_END_WHEELIE_MOVE_DOWN curr_rom.is_hoenn() ? 0x88 : 0xFF +#define MOVEMENT_ACTION_ACRO_END_WHEELIE_MOVE_UP curr_rom.is_hoenn() ? 0x89 : 0xFF +#define MOVEMENT_ACTION_ACRO_END_WHEELIE_MOVE_LEFT curr_rom.is_hoenn() ? 0x8A : 0xFF +#define MOVEMENT_ACTION_ACRO_END_WHEELIE_MOVE_RIGHT curr_rom.is_hoenn() ? 0x8B : 0xFF +#define MOVEMENT_ACTION_WALK_NORMAL_DIAGONAL_UP_LEFT curr_rom.is_hoenn() ? 0x8C : 0xFF +#define MOVEMENT_ACTION_WALK_NORMAL_DIAGONAL_UP_RIGHT curr_rom.is_hoenn() ? 0x8D : 0xFF +#define MOVEMENT_ACTION_WALK_NORMAL_DIAGONAL_DOWN_LEFT curr_rom.is_hoenn() ? 0x8E : 0xFF +#define MOVEMENT_ACTION_WALK_NORMAL_DIAGONAL_DOWN_RIGHT curr_rom.is_hoenn() ? 0x8F : 0xFF +#define MOVEMENT_ACTION_WALK_SLOW_DIAGONAL_UP_LEFT curr_rom.is_hoenn() ? 0x90 : 0xFF +#define MOVEMENT_ACTION_WALK_SLOW_DIAGONAL_UP_RIGHT curr_rom.is_hoenn() ? 0x91 : 0xFF +#define MOVEMENT_ACTION_WALK_SLOW_DIAGONAL_DOWN_LEFT curr_rom.is_hoenn() ? 0x92 : 0xFF +#define MOVEMENT_ACTION_WALK_SLOW_DIAGONAL_DOWN_RIGHT curr_rom.is_hoenn() ? 0x93 : 0xFF +#define MOVEMENT_ACTION_LOCK_ANIM curr_rom.is_hoenn() ? 0x94 : 0xFF +#define MOVEMENT_ACTION_UNLOCK_ANIM curr_rom.is_hoenn() ? 0x95 : 0xFF +#define MOVEMENT_ACTION_WALK_LEFT_AFFINE curr_rom.is_hoenn() ? 0x96 : 0xFF +#define MOVEMENT_ACTION_WALK_RIGHT_AFFINE curr_rom.is_hoenn() ? 0x97 : 0xFF +#define MOVEMENT_ACTION_LEVITATE curr_rom.is_hoenn() ? 0x98 : 0xFF +#define MOVEMENT_ACTION_STOP_LEVITATE curr_rom.is_hoenn() ? 0x99 : 0xFF +#define MOVEMENT_ACTION_STOP_LEVITATE_AT_TOP curr_rom.is_hoenn() ? 0x9A : 0xFF +#define MOVEMENT_ACTION_FIGURE_8 curr_rom.is_hoenn() ? 0x9B : 0xFF +#define MOVEMENT_ACTION_FLY_UP curr_rom.is_hoenn() ? 0x9C : 0xA4 +#define MOVEMENT_ACTION_FLY_DOWN curr_rom.is_hoenn() ? 0x9D : 0xA5 +#define MOVEMENT_ACTION_FACE_DOWN_FAST curr_rom.is_hoenn() ? 0xFF : 0x4 +#define MOVEMENT_ACTION_FACE_UP_FAST curr_rom.is_hoenn() ? 0xFF : 0x5 +#define MOVEMENT_ACTION_FACE_LEFT_FAST curr_rom.is_hoenn() ? 0xFF : 0x6 +#define MOVEMENT_ACTION_FACE_RIGHT_FAST curr_rom.is_hoenn() ? 0xFF : 0x7 +#define MOVEMENT_ACTION_WALK_SLOWER_DOWN curr_rom.is_hoenn() ? 0xFF : 0x8 +#define MOVEMENT_ACTION_WALK_SLOWER_UP curr_rom.is_hoenn() ? 0xFF : 0x9 +#define MOVEMENT_ACTION_WALK_SLOWER_LEFT curr_rom.is_hoenn() ? 0xFF : 0xA +#define MOVEMENT_ACTION_WALK_SLOWER_RIGHT curr_rom.is_hoenn() ? 0xFF : 0xB +#define MOVEMENT_ACTION_PLAYER_RUN_DOWN_SLOW curr_rom.is_hoenn() ? 0xFF : 0x41 +#define MOVEMENT_ACTION_PLAYER_RUN_UP_SLOW curr_rom.is_hoenn() ? 0xFF : 0x42 +#define MOVEMENT_ACTION_PLAYER_RUN_LEFT_SLOW curr_rom.is_hoenn() ? 0xFF : 0x43 +#define MOVEMENT_ACTION_PLAYER_RUN_RIGHT_SLOW curr_rom.is_hoenn() ? 0xFF : 0x44 +#define MOVEMENT_ACTION_EMOTE_X curr_rom.is_hoenn() ? 0xFF : 0x64 +#define MOVEMENT_ACTION_EMOTE_DOUBLE_EXCL_MARK curr_rom.is_hoenn() ? 0xFF : 0x65 +#define MOVEMENT_ACTION_EMOTE_SMILE curr_rom.is_hoenn() ? 0xFF : 0x66 +#define MOVEMENT_ACTION_SPIN_DOWN curr_rom.is_hoenn() ? 0xFF : 0x94 +#define MOVEMENT_ACTION_SPIN_UP curr_rom.is_hoenn() ? 0xFF : 0x95 +#define MOVEMENT_ACTION_SPIN_LEFT curr_rom.is_hoenn() ? 0xFF : 0x96 +#define MOVEMENT_ACTION_SPIN_RIGHT curr_rom.is_hoenn() ? 0xFF : 0x97 +#define MOVEMENT_ACTION_RAISE_HAND_AND_STOP curr_rom.is_hoenn() ? 0xFF : 0x98 +#define MOVEMENT_ACTION_RAISE_HAND_AND_JUMP curr_rom.is_hoenn() ? 0xFF : 0x99 +#define MOVEMENT_ACTION_RAISE_HAND_AND_SWIM curr_rom.is_hoenn() ? 0xFF : 0x9A +#define MOVEMENT_ACTION_WALK_SLOWEST_DOWN curr_rom.is_hoenn() ? 0xFF : 0x9B +#define MOVEMENT_ACTION_WALK_SLOWEST_UP curr_rom.is_hoenn() ? 0xFF : 0x9C +#define MOVEMENT_ACTION_WALK_SLOWEST_LEFT curr_rom.is_hoenn() ? 0xFF : 0x9D +#define MOVEMENT_ACTION_WALK_SLOWEST_RIGHT curr_rom.is_hoenn() ? 0xFF : 0x9E +#define MOVEMENT_ACTION_SHAKE_HEAD_OR_WALK_IN_PLACE curr_rom.is_hoenn() ? 0xFF : 0x9F +#define MOVEMENT_ACTION_GLIDE_DOWN curr_rom.is_hoenn() ? 0xFF : 0xA0 +#define MOVEMENT_ACTION_GLIDE_UP curr_rom.is_hoenn() ? 0xFF : 0xA1 +#define MOVEMENT_ACTION_GLIDE_LEFT curr_rom.is_hoenn() ? 0xFF : 0xA2 +#define MOVEMENT_ACTION_GLIDE_RIGHT curr_rom.is_hoenn() ? 0xFF : 0xA3 +#define MOVEMENT_ACTION_JUMP_SPECIAL_WITH_EFFECT_DOWN curr_rom.is_hoenn() ? 0xFF : 0xA6 +#define MOVEMENT_ACTION_JUMP_SPECIAL_WITH_EFFECT_UP curr_rom.is_hoenn() ? 0xFF : 0xA7 +#define MOVEMENT_ACTION_JUMP_SPECIAL_WITH_EFFECT_LEFT curr_rom.is_hoenn() ? 0xFF : 0xA8 +#define MOVEMENT_ACTION_JUMP_SPECIAL_WITH_EFFECT_RIGHT curr_rom.is_hoenn() ? 0xFF : 0xA9 class mystery_gift_script { - int curr_index; + int curr_mg_index; + int curr_section30_index; u8 mg_script[MG_SCRIPT_SIZE] = {}; + u8 save_section_30[0x1000] = {}; u8 value_buffer[9]; u8 four_align_value = 0; @@ -71,6 +265,7 @@ public: mystery_gift_script(); void build_script(Pokemon_Party &incoming_box_data); u8 get_script_value_at(int index); + u8 get_section30_value_at(int index); u32 calc_checksum32(); u16 calc_crc16(); @@ -106,6 +301,24 @@ private: void release(); void end(); void killscript(); + void spritebehave(u16 objectID, u8 behaviorType); + void spriteface(u16 npc, u8 direction); + void waitmovement(u16 npc); + void doanimation(u16 animation); + void applymovement(u16 npc, u32 movements); + void callASM(u32 script_ptr); + void loadpointer(u8 destinationBank, u32 value); + void setMapLayoutIndex(u16 footer); + void fadeScreen(u8 effect); + void setMetaTile(u16 x, u16 y, u16 metaTileId, u16 impassible); + void playse(u16 soundId); + void writebytetooffset(u8 byte, u32 offset); + void waitse(); + + void msgboxMacro(u32 location); + void changeSpriteMacro(u8 npcId, u32 spriteTablePtr); + void copyPaletteMacro(u8 palNum, const unsigned short palette_array[]); + void changePaletteMacro(u8 npcId, u8 palNum); // ASM commands void push(u16 register_list); diff --git a/include/rom_data.h b/include/rom_data.h index e2ed24d..61fccbb 100644 --- a/include/rom_data.h +++ b/include/rom_data.h @@ -44,6 +44,7 @@ public: int loc_setPokedexFlag; int loc_gSaveDataBuffer; // The location of the saveDataBuffer int loc_readFlashSector; + int loc_loadSaveSection30;// The location of the function that loads save section 30: CEReaderTool_LoadTrainerTower_r in FRLG, TryReadTrainerHill_Internal in Emerald int offset_ramscript; // Ramscript offset as found within the SaveBlock1 struct in global.h int offset_flags; // Flag offset as found within the SaveBlock1 struct in global.h int offset_wondercard; diff --git a/include/script_var.h b/include/script_var.h index eb42e77..138c754 100644 --- a/include/script_var.h +++ b/include/script_var.h @@ -1,6 +1,7 @@ #include #include #include +#include "rom_data.h" class script_var { @@ -23,6 +24,7 @@ public: void set_start(); // Add a pointer to where the start is u8 add_reference(); // Add a location for the variable to be refrenced in the script void fill_refrences(u8 mg_array_ptr[]); // goes through all the script locations and updates them to point to the start + u32 get_loc_in_sec30(); }; class xse_var : public script_var @@ -36,13 +38,34 @@ public: u8 add_reference(int nCommand_offset); // Add a location for the variable to be refrenced in the script u8 add_reference(int nCommand_offset, xse_var *offset_from); void fill_refrences(u8 mg_array_ptr[]); // goes through all the script locations and updates them to point to the start + u32 get_loc_in_sec30(); }; class textbox_var : public xse_var { public: -using xse_var::xse_var; - void set_text(std::u16string_view text); + using xse_var::xse_var; + void set_text(std::u16string_view nText); void insert_text(u8 mg_array[]); + void set_start(); std::u16string_view text; -}; \ No newline at end of file +}; + +class movement_var : public xse_var +{ +public: + using xse_var::xse_var; + void set_movement(const int movement[], unsigned int nSize); + void insert_movement(u8 mg_array[]); + void set_start(); + const int *movement; + unsigned int size; +}; + +class sprite_var : public xse_var +{ +public: + using xse_var::xse_var; + void insert_sprite_data(u8 mg_array[], const unsigned int sprite_array[], unsigned int size); + void set_start(); + }; \ No newline at end of file diff --git a/include/sprite_data.h b/include/sprite_data.h index fb16378..a54511f 100644 --- a/include/sprite_data.h +++ b/include/sprite_data.h @@ -102,6 +102,8 @@ extern OBJ_ATTR *ptgb_logo_l; #include "ptgb_logo_r.h" extern OBJ_ATTR *ptgb_logo_r; +#include "mario.h" + #define BG2VOF_SMALL_TEXTBOX 96 #define BG2VOF_LARGE_TEXTBOX 0 diff --git a/source/mystery_gift_builder.cpp b/source/mystery_gift_builder.cpp index 040ec2f..f5f7c5e 100644 --- a/source/mystery_gift_builder.cpp +++ b/source/mystery_gift_builder.cpp @@ -8,48 +8,14 @@ extern rom_data curr_rom; // These are static variables -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); int var_call_check_flag = (VAR_ID_START + 0x04); int var_call_return_2 = (VAR_ID_START + 0x05); int var_box_return = (VAR_ID_START + 0x06); int var_dex_seen_caught = (VAR_ID_START + 0x07); -int var_dex_num = (VAR_ID_START + 0x08); int var_index = (VAR_ID_START + 0x09); int var_pkmn_offset = (VAR_ID_START + 0x0A); -// int flag_pkmn_1 = (FLAG_ID_START + 0x0); -// int flag_pkmn_2 = (FLAG_ID_START + 0x1); -// int flag_pkmn_3 = (FLAG_ID_START + 0x2); -// int flag_pkmn_4 = (FLAG_ID_START + 0x3); -// int flag_pkmn_5 = (FLAG_ID_START + 0x4); -// int flag_pkmn_6 = (FLAG_ID_START + 0x5); - -// These will all be set based on the ROM pointers -/* -int loc_sendMonToPC; -int loc_gSpecialVar_0x8000; -int loc_gSaveBlock1; // Only used in R/S -int loc_gSaveBlock1PTR; // Only used in FR/LG/E -int loc_setPokedexFlag; -int offset_ramscript; // Source: https://github.com/pret/pokeemerald/blob/master/include/global.h#L1012 -int offset_flags; // Flag offset as found within the SaveBlock1 struct in global.h -int offset_wondercard; -int offset_script; -int text_region; - -u8 map_bank; -u8 map_id; -u8 npc_id; -*/ - // These values will be defined once we recieve the ROM pointers -int ptr_callASM; -int ptr_script_ptr_low; -int ptr_script_ptr_high; -int ptr_call_return_1; int ptr_call_check_flag; int ptr_call_return_2; int ptr_box_return; @@ -57,165 +23,208 @@ int ptr_dex_seen_caught; int ptr_index; int ptr_pkmn_offset; -int ptr_block_ptr_low; -int ptr_block_ptr_high; - mystery_gift_script::mystery_gift_script() { -#define NUM_RELATIVE_PTR 1 // THIS STAYS AS 1, THERE IS NO RELATIVE POINTER TO DEX AT THE MOMENT, IT IS A STATIC 28!!! -#define REL_PTR_ASM_START 0 -#define REL_PTR_DEX_START 1 + curr_mg_index = NPC_LOCATION_OFFSET; + curr_section30_index = 0; - curr_index = NPC_LOCATION_OFFSET; - - 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_call_check_flag = (curr_rom.loc_gSpecialVar_0x8000 + 0x08); ptr_call_return_2 = (curr_rom.loc_gSpecialVar_0x8000 + 0x0A); ptr_box_return = (curr_rom.loc_gSpecialVar_0x8000 + 0x0C); 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); - - 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) { - std::vector asm_variable_list; - asm_var sendMonToPC_ptr(curr_rom.loc_sendMonToPC + READ_AS_THUMB, asm_variable_list, &curr_index); - asm_var returned_box_success_ptr(ptr_box_return, asm_variable_list, &curr_index); - asm_var curr_pkmn_index_ptr(ptr_pkmn_offset, asm_variable_list, &curr_index); - asm_var setPokedexFlag_ptr(curr_rom.loc_setPokedexFlag + READ_AS_THUMB, asm_variable_list, &curr_index); - asm_var dexSeenCaught_ptr(ptr_dex_seen_caught, asm_variable_list, &curr_index); - asm_var currPkmnIndex_ptr(ptr_index, asm_variable_list, &curr_index); - asm_var pkmnStruct(curr_rom.loc_gSaveDataBuffer, asm_variable_list, &curr_index); - asm_var dexStruct(curr_rom.loc_gSaveDataBuffer + (MAX_PKMN_IN_BOX * POKEMON_SIZE), asm_variable_list, &curr_index); - asm_var flashBuffer_ptr(curr_rom.loc_gSaveDataBuffer, asm_variable_list, &curr_index); - asm_var readFlashSector_ptr(curr_rom.loc_readFlashSector + READ_AS_THUMB, asm_variable_list, &curr_index); - xse_var mainAsmStart(asm_variable_list, &curr_index); - xse_var dexAsmStart(asm_variable_list, &curr_index); - xse_var readFlashStart(asm_variable_list, &curr_index); + std::vector mg_variable_list; + std::vector sec30_variable_list; - xse_var jumpLoop(asm_variable_list, &curr_index); - xse_var jumpBoxFull(asm_variable_list, &curr_index); - xse_var jumpPkmnCollected(asm_variable_list, &curr_index); - xse_var jumpAllCollected(asm_variable_list, &curr_index); + asm_var sendMonToPC_ptr(curr_rom.loc_sendMonToPC + READ_AS_THUMB, sec30_variable_list, &curr_section30_index); + asm_var returned_box_success_ptr(ptr_box_return, sec30_variable_list, &curr_section30_index); + asm_var curr_pkmn_index_ptr(ptr_pkmn_offset, sec30_variable_list, &curr_section30_index); + asm_var setPokedexFlag_ptr(curr_rom.loc_setPokedexFlag + READ_AS_THUMB, sec30_variable_list, &curr_section30_index); + asm_var dexSeenCaught_ptr(ptr_dex_seen_caught, sec30_variable_list, &curr_section30_index); + asm_var currPkmnIndex_ptr(ptr_index, sec30_variable_list, &curr_section30_index); + asm_var pkmnStruct(curr_rom.loc_gSaveDataBuffer, sec30_variable_list, &curr_section30_index); + asm_var dexStruct(curr_rom.loc_gSaveDataBuffer + (MAX_PKMN_IN_BOX * POKEMON_SIZE), sec30_variable_list, &curr_section30_index); + asm_var flashBuffer_ptr(curr_rom.loc_gSaveDataBuffer, sec30_variable_list, &curr_section30_index); + asm_var readFlashSector_ptr(curr_rom.loc_readFlashSector + READ_AS_THUMB, sec30_variable_list, &curr_section30_index); - textbox_var textGreet(asm_variable_list, &curr_index); - textbox_var textReceived(asm_variable_list, &curr_index); - textbox_var textPCFull(asm_variable_list, &curr_index); - textbox_var textThank(asm_variable_list, &curr_index); - textbox_var textTest(asm_variable_list, &curr_index); + asm_var mainAsmStart(sec30_variable_list, &curr_section30_index); + asm_var dexAsmStart(sec30_variable_list, &curr_section30_index); + + xse_var jumpLoop(mg_variable_list, &curr_mg_index); + xse_var jumpBoxFull(mg_variable_list, &curr_mg_index); + xse_var jumpPkmnCollected(mg_variable_list, &curr_mg_index); + xse_var jumpAllCollected(mg_variable_list, &curr_mg_index); + + textbox_var textGreet(sec30_variable_list, &curr_section30_index); + textbox_var textReceived(sec30_variable_list, &curr_section30_index); + textbox_var textPCFull(sec30_variable_list, &curr_section30_index); + textbox_var textThank(sec30_variable_list, &curr_section30_index); + textbox_var textTest(sec30_variable_list, &curr_section30_index); + textbox_var textYouMustBe(sec30_variable_list, &curr_section30_index); + textbox_var textIAm(sec30_variable_list, &curr_section30_index); + textbox_var textWeHere(sec30_variable_list, &curr_section30_index); + textbox_var textMoveBox(sec30_variable_list, &curr_section30_index); + textbox_var textPCConvo(sec30_variable_list, &curr_section30_index); + textbox_var textPCThanks(sec30_variable_list, &curr_section30_index); + textbox_var textLookerFull(sec30_variable_list, &curr_section30_index); + + movement_var movementSlowSpin(sec30_variable_list, &curr_section30_index); + movement_var movementFastSpin(sec30_variable_list, &curr_section30_index); + movement_var movementExclaim(sec30_variable_list, &curr_section30_index); + movement_var movementToBoxes(sec30_variable_list, &curr_section30_index); + movement_var movementWalkBack(sec30_variable_list, &curr_section30_index); + movement_var movementLookDown(sec30_variable_list, &curr_section30_index); + + sprite_var spriteLooker(sec30_variable_list, &curr_section30_index); // Ş = Wait for button and scroll text // ȼ = Wait for button and clear text // Ȇ = Escape character + // À = Change text color + // Ç = Red + // É = Green + // Ë = Blue // Ʋ = 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!"); + textGreet.set_text(u"I may not look like much now,Ňbut when I was younger…"); textReceived.set_text(u"ȆÀÁƲÀ’S POKÉMON were sent to theŇPC!"); - textTest.set_text(u"Testing..."); + textYouMustBe.set_text(u"Ah! You must be ƲÀ!ŇI was told you’d be coming.ȼOh! I still wear my disguise! Pardon!ŇOr, rather, let me introduce myself."); + textIAm.set_text(u"ȆÀËI am a globe-trotting elite of theŇInternational Police.ȼMy name…ŞAh, no, I shall inform you of myŇcode name only.ȼMy code name, it is LOOKER.ŇIt is how I am called!"); + textWeHere.set_text(u"ȆÀËLOOKER: I am here in Kanto to findŇthe leader Giovanni.ȼHowever, in the meantime, I amŇhelping my friend Professor Jazmine.ȼThis is why you are here, no?ȼI shall contact her and tell herŇyou are ready.ŞCome! Allons y!"); + textMoveBox.set_text(u"ȆÀËOh, of course, I have to moveŇthe boxes. Silly me!"); + textPCConvo.set_text(u"ȆÀÉJAZ: Ah, LOOKER! Good to hear fromŇyou! I take it ƲÀ has arrived?ȼȆÀËLOOKER: Indeed! They’re here andŇready to receive their POKÉMON!ȼȆÀÉJAZ: Excellent! I’ll be sending themŇover momentarily… stand by!ȼDon’t worry ƲÀ,Ňyou won’t have to do a thing!"); + textPCThanks.set_text(u"ȆÀÉJAZ: It looks like everything wasŇsent to your PC successfully!ȼThanks again for your help ƲÀ!ŇSee you around, LOOKER!"); + textThank.set_text(u"ȆÀËThanks for stopping by, ƲÀ!ȼIf you’ll excuse me, I need toŇreturn to my disguise.ŞUntil our paths cross again!"); + textPCFull.set_text(u"ȆÀÉJAZ: Hm, it seems like the PC is full!ȼGo make some room, and I can sendŇover the rest of your POKÉMON."); + textLookerFull.set_text(u"ȆÀËLOOKER: Speak to me again afterŇyou’ve made room, ƲÀ!ȼIn the meantime, I will return toŇmy disguise."); - // 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 + const int movementSlowSpinArray[16] = { + MOVEMENT_ACTION_FACE_LEFT, + MOVEMENT_ACTION_DELAY_8, + MOVEMENT_ACTION_FACE_UP, + MOVEMENT_ACTION_DELAY_8, + MOVEMENT_ACTION_FACE_RIGHT, + MOVEMENT_ACTION_DELAY_8, + MOVEMENT_ACTION_FACE_DOWN, + MOVEMENT_ACTION_DELAY_8, + MOVEMENT_ACTION_FACE_LEFT, + MOVEMENT_ACTION_DELAY_8, + MOVEMENT_ACTION_FACE_UP, + MOVEMENT_ACTION_DELAY_8, + MOVEMENT_ACTION_FACE_RIGHT, + MOVEMENT_ACTION_DELAY_8, + MOVEMENT_ACTION_FACE_DOWN, + MOVEMENT_ACTION_DELAY_8, + }; + movementSlowSpin.set_movement(movementSlowSpinArray, 16); - 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); - four_align(); // Align the code so that it is byte aligned + const int movementFastSpinArray[30] = { + MOVEMENT_ACTION_FACE_LEFT, + MOVEMENT_ACTION_DELAY_4, + MOVEMENT_ACTION_FACE_UP, + MOVEMENT_ACTION_DELAY_4, + MOVEMENT_ACTION_FACE_RIGHT, + MOVEMENT_ACTION_DELAY_4, + MOVEMENT_ACTION_FACE_DOWN, + MOVEMENT_ACTION_DELAY_4, + MOVEMENT_ACTION_FACE_LEFT, + MOVEMENT_ACTION_DELAY_4, + MOVEMENT_ACTION_FACE_UP, + MOVEMENT_ACTION_DELAY_4, + MOVEMENT_ACTION_FACE_RIGHT, + MOVEMENT_ACTION_DELAY_4, + MOVEMENT_ACTION_FACE_DOWN, + MOVEMENT_ACTION_DELAY_4, + MOVEMENT_ACTION_FACE_LEFT, + MOVEMENT_ACTION_DELAY_4, + MOVEMENT_ACTION_FACE_UP, + MOVEMENT_ACTION_DELAY_4, + MOVEMENT_ACTION_FACE_RIGHT, + MOVEMENT_ACTION_DELAY_4, + MOVEMENT_ACTION_FACE_DOWN, + MOVEMENT_ACTION_DELAY_4, + MOVEMENT_ACTION_FACE_LEFT, + MOVEMENT_ACTION_DELAY_4, + MOVEMENT_ACTION_FACE_UP, + MOVEMENT_ACTION_DELAY_4, + MOVEMENT_ACTION_FACE_RIGHT, + MOVEMENT_ACTION_DELAY_4, + }; + movementFastSpin.set_movement(movementFastSpinArray, 30); + + const int movementExclaimArray[1] = {MOVEMENT_ACTION_EMOTE_EXCLAMATION_MARK}; + movementExclaim.set_movement(movementExclaimArray, 1); + + const int movementToBoxesArray[3] = {MOVEMENT_ACTION_WALK_FAST_UP, MOVEMENT_ACTION_WALK_FAST_UP, MOVEMENT_ACTION_EMOTE_EXCLAMATION_MARK}; + movementToBoxes.set_movement(movementToBoxesArray, 3); + + const int movementWalkBackArray[2] = {MOVEMENT_ACTION_WALK_FAST_DOWN, MOVEMENT_ACTION_WALK_FAST_DOWN}; + movementWalkBack.set_movement(movementWalkBackArray, 2); + + const int movementLookDownArray[1] = {MOVEMENT_ACTION_FACE_DOWN}; + movementLookDown.set_movement(movementLookDownArray, 1); + + int dex_nums[MAX_PKMN_IN_BOX] = {}; + + 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++) + { + save_section_30[curr_section30_index] = curr_pkmn.get_gen_3_data(curr_byte); + curr_section30_index++; + } + dex_nums[i] = curr_pkmn.get_dex_number(); + } + else + { + curr_section30_index += POKEMON_SIZE; + } + } + + for (int i = 0; i < MAX_PKMN_IN_BOX; i++) // Add in the dex numbers + { + save_section_30[curr_section30_index] = dex_nums[i]; + curr_section30_index++; + } + + // insert text + textThank.insert_text(save_section_30); + textYouMustBe.insert_text(save_section_30); + // textPCFull.insert_text(save_section_30); + textReceived.insert_text(save_section_30); + textGreet.insert_text(save_section_30); + textIAm.insert_text(save_section_30); + textWeHere.insert_text(save_section_30); + textMoveBox.insert_text(save_section_30); + textPCConvo.insert_text(save_section_30); + textPCThanks.insert_text(save_section_30); + // textLookerFull.insert_text(save_section_30); + + movementSlowSpin.insert_movement(save_section_30); + movementFastSpin.insert_movement(save_section_30); + movementExclaim.insert_movement(save_section_30); + movementToBoxes.insert_movement(save_section_30); + movementWalkBack.insert_movement(save_section_30); + movementLookDown.insert_movement(save_section_30); + + while (curr_section30_index % 4 != 0) + { + curr_section30_index++; // Align the code so that it is byte aligned + } + +#include "mario.h" + spriteLooker.insert_sprite_data(save_section_30, marioTiles, 256); - 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 @@ -232,54 +241,187 @@ void mystery_gift_script::build_script(Pokemon_Party &incoming_box_data) 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) - // - // - add_padding(); // add padding so that we are byte aligned again - 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 - // - four_align(); // make the offset a multiple of 4 - - for (unsigned int i = 0; i < asm_variable_list.size(); i++) // Fill all the refrences for script variables + while (curr_section30_index % 4 != 0) { - asm_variable_list[i]->fill_refrences(mg_script); + curr_section30_index++; // Align the code so that it is byte aligned } - if (curr_index > MG_SCRIPT_SIZE) // Throw an error if the script is too large + add_word(curr_pkmn_index_ptr.place_word()); // the location of variable "0x8008" (the pokemon offset) + add_word(pkmnStruct.place_word()); // the location of the Pokemon Struct + 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) + + 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_section30_index % 4 != 0) + { + curr_section30_index++; // Align the code so that it is byte aligned + } + add_word(currPkmnIndex_ptr.place_word()); // the location of the INDEX variable + add_word(dexStruct.place_word()); // the location of the dex struct + add_word(dexSeenCaught_ptr.place_word()); // the location of the DEX_SEEN_CAUGHT variable + add_word(setPokedexFlag_ptr.place_word()); // the location of GetSetPokedexFlag, plus one (so it is interpreted as thumb code) + + // The start of the Mystery Gift Script + + // 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 + callASM(curr_rom.loc_loadSaveSection30 + READ_AS_THUMB); // Load save section 30 into saveDataBuffer + lock(); // Lock the player + faceplayer(); // Have the NPC face the player + msgboxMacro(textGreet.get_loc_in_sec30()); // Start the dialouge + applymovement(curr_rom.npc_id, movementExclaim.get_loc_in_sec30()); + playse(0x15); + waitse(); + waitmovement(curr_rom.npc_id); + msgboxMacro(textYouMustBe.get_loc_in_sec30()); + applymovement(curr_rom.npc_id, movementSlowSpin.get_loc_in_sec30()); + waitmovement(curr_rom.npc_id); + applymovement(curr_rom.npc_id, movementFastSpin.get_loc_in_sec30()); + waitmovement(curr_rom.npc_id); + changeSpriteMacro(1, spriteLooker.get_loc_in_sec30()); + copyPaletteMacro(0xA, marioPal); + changePaletteMacro(curr_rom.npc_id, 0xA); + applymovement(curr_rom.npc_id, movementLookDown.get_loc_in_sec30()); + msgboxMacro(textIAm.get_loc_in_sec30()); + changeSpriteMacro(1, 0x083a0b08); + changePaletteMacro(curr_rom.npc_id, 0x3); + applymovement(curr_rom.npc_id, movementFastSpin.get_loc_in_sec30()); + waitmovement(curr_rom.npc_id); + applymovement(curr_rom.npc_id, movementSlowSpin.get_loc_in_sec30()); + waitmovement(curr_rom.npc_id); + faceplayer(); + msgboxMacro(textWeHere.get_loc_in_sec30()); + applymovement(curr_rom.npc_id, movementToBoxes.get_loc_in_sec30()); + waitmovement(curr_rom.npc_id); + playse(0x15); + waitse(); + msgboxMacro(textMoveBox.get_loc_in_sec30()); + fadeScreen(1); + // Place the PC + setMetaTile(4, 1, 98, 0); + // Place the boxes + setMetaTile(2, 1, 385, 1); + setMetaTile(2, 2, 386, 0); + special(0x8E); + playse(0xC); + waitse(); + fadeScreen(0); + setMetaTile(4, 1, 99, 0); + special(0x8E); + playse(0x2); + waitse(); + msgboxMacro(textPCConvo.get_loc_in_sec30()); + + // -- POKEMON INJECTION START-- + setvar(var_index, 0); // set the index to 0 + setvar(var_pkmn_offset, 0); // Set the Pokemon struct offset to 0 + 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 + callASM(mainAsmStart.get_loc_in_sec30()); // 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 + setvar(var_dex_seen_caught, 2); // set the seen caught variable to 2, so that the Pokemon is set to "seen" + callASM(dexAsmStart.get_loc_in_sec30()); // call "PTR_DEX_START" + addvar(var_dex_seen_caught, 1); // add 1 to the seen caught variable so that the Pokemon will be "Caught" + callASM(dexAsmStart.get_loc_in_sec30()); // Call "PTR_DEX_START" again + 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 + msgboxMacro(textReceived.get_loc_in_sec30()); // Display the recieved text + waitfanfare(); // Wait for the fanfare + + // -- POKEMON INJECTION END -- + jumpAllCollected.set_start(); // Set the destination for if all the Pokemon have already been collected + msgboxMacro(textPCThanks.get_loc_in_sec30()); // Display the thank text + setMetaTile(4, 1, 98, 0); + special(0x8E); + playse(0x3); + waitse(); + fadeScreen(1); + // Place the PC + setMetaTile(4, 1, 385, 1); + // Place the boxes + setMetaTile(2, 1, 272, 1); + setMetaTile(2, 2, 273, 0); + special(0x8E); + playse(0xC); + waitse(); + fadeScreen(0); + applymovement(curr_rom.npc_id, movementWalkBack.get_loc_in_sec30()); + waitmovement(curr_rom.npc_id); + faceplayer(); + msgboxMacro(textThank.get_loc_in_sec30()); + release(); // Release the player + killscript(); // Erase RAMscript + + // -- BOX IS FULL TEXT -- + jumpBoxFull.set_start(); // Set the destination for if the box is full + msgboxMacro(textPCFull.get_loc_in_sec30()); // Display the thank text + setMetaTile(4, 1, 98, 0); + special(0x8E); + playse(0x3); + waitse(); + fadeScreen(1); + // Place the PC + setMetaTile(4, 1, 385, 1); + // Place the boxes + setMetaTile(2, 1, 272, 1); + setMetaTile(2, 2, 273, 0); + special(0x8E); + playse(0xC); + waitse(); + fadeScreen(0); + applymovement(curr_rom.npc_id, movementWalkBack.get_loc_in_sec30()); + waitmovement(curr_rom.npc_id); + faceplayer(); + msgboxMacro(textLookerFull.get_loc_in_sec30()); + release(); // Release the player + end(); // End the script + + for (unsigned int i = 0; i < mg_variable_list.size(); i++) // Fill all the refrences for script variables in the mg + { + mg_variable_list[i]->fill_refrences(mg_script); + } + + for (unsigned int i = 0; i < sec30_variable_list.size(); i++) // Fill all the refrences for script variables in save section 30 + { + sec30_variable_list[i]->fill_refrences(save_section_30); + } + + if (curr_mg_index > MG_SCRIPT_SIZE) // Throw an error if the script is too large { tte_erase_screen(); - int val = (curr_index - MG_SCRIPT_SIZE) - four_align_value; + 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"); @@ -294,6 +436,11 @@ u8 mystery_gift_script::get_script_value_at(int i) return mg_script[i]; } +u8 mystery_gift_script::get_section30_value_at(int i) +{ + return save_section_30[i]; +} + u16 mystery_gift_script::rev_endian(u16 num) { return ((num & 0xFF) << 8) | (num >> 8); @@ -303,8 +450,8 @@ void mystery_gift_script::add_command(int len) { for (int i = 0; i < len; i++) { - mg_script[curr_index] = value_buffer[i]; - curr_index++; + mg_script[curr_mg_index] = value_buffer[i]; + curr_mg_index++; } } @@ -342,9 +489,9 @@ u16 mystery_gift_script::calc_crc16() // Implementation taken from PokeEmerald D void mystery_gift_script::add_asm(u16 command) { - mg_script[curr_index] = command >> 0; - mg_script[curr_index + 1] = command >> 8; - curr_index += 2; + save_section_30[curr_section30_index] = command >> 0; + save_section_30[curr_section30_index + 1] = command >> 8; + curr_section30_index += 2; } // Scripting commands: @@ -400,6 +547,17 @@ void mystery_gift_script::virtualmsgbox(u32 location) add_command(5); } +void mystery_gift_script::loadpointer(u8 destinationBank, u32 value) +{ + value_buffer[0] = 0x0F; + value_buffer[1] = destinationBank; + value_buffer[2] = value >> 0; + value_buffer[3] = value >> 8; + value_buffer[4] = value >> 16; + value_buffer[5] = value >> 24; + add_command(6); +} + void mystery_gift_script::waitmsg() { value_buffer[0] = 0x66; @@ -531,6 +689,116 @@ void mystery_gift_script::killscript() add_command(1); } +void mystery_gift_script::spritebehave(u16 objectID, u8 behaviorType) +{ + value_buffer[0] = 0x65; + value_buffer[1] = objectID >> 0; + value_buffer[2] = objectID >> 8; + value_buffer[3] = behaviorType; + add_command(4); +} + +void mystery_gift_script::spriteface(u16 npc, u8 direction) +{ + value_buffer[0] = 0x5B; + value_buffer[1] = npc >> 0; + value_buffer[2] = npc >> 8; + value_buffer[3] = direction; + add_command(4); +} + +void mystery_gift_script::waitmovement(u16 npc) +{ + value_buffer[0] = 0x51; + value_buffer[1] = npc >> 0; + value_buffer[2] = npc >> 8; + add_command(3); +} + +void mystery_gift_script::doanimation(u16 animation) +{ + value_buffer[0] = 0x9C; + value_buffer[1] = animation >> 0; + value_buffer[2] = animation >> 8; + add_command(3); +} + +void mystery_gift_script::applymovement(u16 npc, u32 movements) +{ + value_buffer[0] = 0x4F; + value_buffer[1] = npc >> 0; + value_buffer[2] = npc >> 8; + value_buffer[3] = movements >> 0; + value_buffer[4] = movements >> 8; + value_buffer[5] = movements >> 16; + value_buffer[6] = movements >> 24; + add_command(7); +} + +void mystery_gift_script::callASM(u32 script_ptr) +{ + value_buffer[0] = 0x23; + value_buffer[1] = script_ptr >> 0; + value_buffer[2] = script_ptr >> 8; + value_buffer[3] = script_ptr >> 16; + value_buffer[4] = script_ptr >> 24; + add_command(5); +} + +void mystery_gift_script::setMapLayoutIndex(u16 footer) +{ + value_buffer[0] = 0xA7; + value_buffer[1] = footer >> 0; + value_buffer[2] = footer >> 8; + add_command(3); +} + +void mystery_gift_script::fadeScreen(u8 effect) +{ + value_buffer[0] = 0x97; + value_buffer[1] = effect >> 0; + add_command(2); +} + +void mystery_gift_script::setMetaTile(u16 x, u16 y, u16 metaTileId, u16 impassible) +{ + value_buffer[0] = 0xA2; + value_buffer[1] = x >> 0; + value_buffer[2] = x >> 8; + value_buffer[3] = y >> 0; + value_buffer[4] = y >> 8; + value_buffer[5] = metaTileId >> 0; + value_buffer[6] = metaTileId >> 8; + value_buffer[7] = impassible >> 0; + value_buffer[8] = impassible >> 8; + add_command(9); +} + +void mystery_gift_script::playse(u16 soundId) +{ + value_buffer[0] = 0x2F; + value_buffer[1] = soundId >> 0; + value_buffer[2] = soundId >> 8; + add_command(3); +} + +void mystery_gift_script::waitse() +{ + value_buffer[0] = 0x30; + add_command(1); +} + +void mystery_gift_script::writebytetooffset(u8 byte, u32 offset) +{ + value_buffer[0] = 0x11; + value_buffer[1] = byte; + value_buffer[2] = offset >> 0; + value_buffer[3] = offset >> 8; + value_buffer[4] = offset >> 16; + value_buffer[5] = offset >> 24; + add_command(6); +} + void mystery_gift_script::init_npc_location(u8 bank, u8 map, u8 npc) { mg_script[0] = 0x33; // File ID? @@ -539,6 +807,32 @@ void mystery_gift_script::init_npc_location(u8 bank, u8 map, u8 npc) mg_script[3] = npc; } +void mystery_gift_script::msgboxMacro(u32 location) +{ + loadpointer(0, location); + callstd(4); +} + +void mystery_gift_script::changeSpriteMacro(u8 npcId, u32 spriteTablePtr) +{ + writebytetooffset(spriteTablePtr >> 0, 0x0202063c + (0x44 * npcId) + 0xC + 0); + writebytetooffset(spriteTablePtr >> 8, 0x0202063c + (0x44 * npcId) + 0xC + 1); + writebytetooffset(spriteTablePtr >> 16, 0x0202063c + (0x44 * npcId) + 0xC + 2); + writebytetooffset(spriteTablePtr >> 24, 0x0202063c + (0x44 * npcId) + 0xC + 3); +} + +void mystery_gift_script::copyPaletteMacro(u8 palNum, const unsigned short palette_array[]) +{ + for (int i = 0; i < 32; i++){ + writebytetooffset(palette_array[i / 2] >> (8 * (i % 2)), 0x020375f8 + 0x200 + (32 * palNum) + i); + } +} + +void mystery_gift_script::changePaletteMacro(u8 npcId, u8 palNum) +{ + writebytetooffset((palNum << 4) | 0x08, 0x0202063c + (0x44 * npcId) + 0x5); +} + // ASM Commands // Documentation found here: // https://github.com/LunarLambda/arm-docs @@ -693,17 +987,17 @@ void mystery_gift_script::add_word(u32 word) void mystery_gift_script::four_align() { // while(curr_index % 4 != 0) - for (int i = 0; i < curr_index % 4; i++) + for (int i = 0; i < curr_mg_index % 4; i++) { - mg_script[curr_index] = 0xAA; - curr_index++; + mg_script[curr_mg_index] = 0xAA; + curr_mg_index++; four_align_value++; } } void mystery_gift_script::add_padding() { - if (curr_index % 4 != 0) + if (curr_mg_index % 4 != 0) { add_asm(0x0000); } diff --git a/source/mystery_gift_injector.cpp b/source/mystery_gift_injector.cpp index 41466b1..56c647f 100644 --- a/source/mystery_gift_injector.cpp +++ b/source/mystery_gift_injector.cpp @@ -62,22 +62,12 @@ 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 < MAX_PKMN_IN_BOX; i++) // Add in the Pokemon data + for (int i = 0; i < 0x1000; i++) // Copy over the save data section { - Pokemon curr_pkmn = incoming_box_data.get_converted_pkmn(i); - 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++; - } - } - - for (int i = 0; i < MAX_PKMN_IN_BOX; i++) // Add in the dex numbers - { - global_memory_buffer[curr_index] = incoming_box_data.get_simple_pkmn(curr_index).dex_number; + 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/pokemon_party.cpp b/source/pokemon_party.cpp index 7c50fbf..fb64ac6 100644 --- a/source/pokemon_party.cpp +++ b/source/pokemon_party.cpp @@ -163,9 +163,17 @@ void Pokemon_Party::start_link() { if (IGNORE_LINK_CABLE) { - for (int i = 0; i < 0x44E; i++) + if (curr_gb_rom.generation == 1) { - box_data_array[i] = gen2_debug_box_data[i]; + for (int i = 0; i < 0x44E; i++) + { + box_data_array[i] = gen1_debug_box_data[i]; + } + } else { + for (int i = 0; i < 0x44E; i++) + { + box_data_array[i] = gen2_debug_box_data[i]; + } } } else diff --git a/source/rom_data.cpp b/source/rom_data.cpp index 8b79de7..4d37c9b 100644 --- a/source/rom_data.cpp +++ b/source/rom_data.cpp @@ -4,6 +4,8 @@ #include "pokemon_data.h" #include "gba_rom_values/eng_gba_rom_values.h" +extern rom_data curr_rom; + rom_data::rom_data() {} bool rom_data::load_rom() { @@ -59,6 +61,7 @@ void rom_data::fill_values(const ROM_DATA *rom_values) loc_setPokedexFlag = rom_values->loc_getSetPokedexFlag; loc_gSaveDataBuffer = rom_values->loc_gSaveDataBuffer; loc_readFlashSector = rom_values->loc_readFlashSector; + loc_loadSaveSection30 = rom_values->loc_loadSaveSection30; offset_ramscript = rom_values->offset_ramscript; offset_flags = rom_values->offset_flags; offset_wondercard = rom_values->offset_wondercard; diff --git a/source/script_var.cpp b/source/script_var.cpp index 7731550..d8f4e1c 100644 --- a/source/script_var.cpp +++ b/source/script_var.cpp @@ -3,6 +3,8 @@ #include "script_var.h" #include "pokemon_data.h" +extern rom_data curr_rom; + script_var::script_var(u32 nValue, std::vector &var_list_ref, int *nCurr_loc_ptr) { var_list_ref.push_back(this); // Place the new object in the var_list @@ -61,6 +63,11 @@ void asm_var::fill_refrences(u8 mg_array[]) } } +u32 asm_var::get_loc_in_sec30() +{ + return start_location_in_script + curr_rom.loc_gSaveDataBuffer + 3; // plus 3 to offset the -2 in set_start, and one for reading as thumb +} + // XSE VAR ---------------- void xse_var::set_start() @@ -99,6 +106,11 @@ void xse_var::fill_refrences(u8 mg_array[]) } } +u32 xse_var::get_loc_in_sec30() +{ + return start_location_in_script + curr_rom.loc_gSaveDataBuffer; +} + // TEXTBOX VAR void textbox_var::set_text(std::u16string_view nText) @@ -106,13 +118,72 @@ void textbox_var::set_text(std::u16string_view nText) text = nText; } -void textbox_var::insert_text(u8 mg_array[]){ +void textbox_var::set_start() +{ + start_location_in_script = *curr_loc_ptr; +} + +void textbox_var::insert_text(u8 mg_array[]) +{ set_start(); for (unsigned int parser = 0; parser < text.length(); parser++) - { - mg_array[*curr_loc_ptr] = get_gen_3_char((char16_t)(text.at(parser)), false); - (*curr_loc_ptr)++; - } - mg_array[*curr_loc_ptr] = 0xFF; // End string + { + mg_array[*curr_loc_ptr] = get_gen_3_char((char16_t)(text.at(parser)), false); (*curr_loc_ptr)++; + } + mg_array[*curr_loc_ptr] = 0xFF; // End string + (*curr_loc_ptr)++; +} + +// MOVEMENT VAR + +void movement_var::set_movement(const int nMovement[], unsigned int nSize) +{ + movement = nMovement; + size = nSize; +} + +void movement_var::set_start() +{ + start_location_in_script = *curr_loc_ptr; +} + +void movement_var::insert_movement(u8 mg_array[]) +{ + set_start(); + for (unsigned int parser = 0; parser < size; parser++) + { + mg_array[*curr_loc_ptr] = movement[parser]; + (*curr_loc_ptr)++; + } + mg_array[*curr_loc_ptr] = 0xFE; // End list + (*curr_loc_ptr)++; +} + +// SPRITE VAR + +void sprite_var::set_start() +{ + start_location_in_script = *curr_loc_ptr; +} + +void sprite_var::insert_sprite_data(u8 mg_array[], const unsigned int sprite_array[], unsigned int size) +{ + set_start(); + u32 pointer = curr_rom.loc_gSaveDataBuffer + *curr_loc_ptr + 8; + for (int i = 0; i < 4; i++) + { + mg_array[*curr_loc_ptr] = pointer >> (8 * i); + (*curr_loc_ptr)++; + } + for (int i = 0; i < 4; i++) + { + mg_array[*curr_loc_ptr] = size >> (8 * i); + (*curr_loc_ptr)++; + } + for (unsigned int parser = 0; parser < size; parser++) + { + mg_array[*curr_loc_ptr] = sprite_array[parser / 4] >> (8 * (parser % 4)); + (*curr_loc_ptr)++; + } } \ No newline at end of file