mirror of
https://github.com/GearsProgress/Poke_Transporter_GB.git
synced 2026-05-09 12:36:05 -05:00
373 lines
10 KiB
C++
373 lines
10 KiB
C++
#include "dbg/debug_menu_functions.h"
|
|
#include "dbg/debug_menu.h"
|
|
#include "libraries/nanoprintf/nanoprintf.h"
|
|
#include "text_engine.h"
|
|
#include "pokemon_data.h"
|
|
#include "sprite_data.h"
|
|
#include "global_frame_controller.h"
|
|
#include "flash_mem.h"
|
|
#include "ptgb_save_data_manager.h"
|
|
#include "background_engine.h"
|
|
#include "libstd_replacements.h"
|
|
#include "sound.h"
|
|
#include "rom_data.h"
|
|
#include "Gen3CartridgeSaveReader.h"
|
|
#include "Gen3SaveManager.h"
|
|
#include "Gen3Pokemon.h"
|
|
#include "pokemon_data.h"
|
|
#include "translated_text.h"
|
|
|
|
#define LEFT 8
|
|
#define RIGHT (H_MAX - LEFT)
|
|
#define TOP 120
|
|
#define BOTTOM V_MAX
|
|
|
|
extern rom_data curr_GBA_rom;
|
|
extern u32 global_tile_id_end;
|
|
|
|
static const byte RSEFL_10_ANIV_Celebi_0BF5_ENG_[] = {
|
|
0xbe, 0x2b, 0x28, 0x78, 0x0a, 0x00, 0x00, 0x00, 0xbd, 0xbf, 0xc6, 0xbf, 0xbc, 0xc3, 0xff, 0x34,
|
|
0x01, 0x31, 0x02, 0x02, 0xa2, 0xa1, 0x00, 0xbb, 0xc8, 0xc3, 0xd0, 0x00, 0x17, 0x35, 0x00, 0x00,
|
|
0xfb, 0x00, 0x00, 0x00, 0x80, 0x43, 0x05, 0x00, 0x00, 0x64, 0x00, 0x00, 0xf6, 0x00, 0xf8, 0x00,
|
|
0xe2, 0x00, 0xc3, 0x00, 0x05, 0x0f, 0x28, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x46, 0x21, 0xe2, 0x31, 0xaf, 0x22, 0x00, 0x00, 0x00, 0x00
|
|
};
|
|
|
|
static Game convert_rom_game_id_to_ptgb_game(int game_id)
|
|
{
|
|
switch (game_id)
|
|
{
|
|
case RUBY_ID:
|
|
return RUBY;
|
|
case SAPPHIRE_ID:
|
|
return SAPPHIRE;
|
|
case FIRERED_ID:
|
|
return FIRERED;
|
|
case LEAFGREEN_ID:
|
|
return LEAFGREEN;
|
|
case EMERALD_ID:
|
|
return EMERALD;
|
|
default:
|
|
return GAME_UNKNOWN; // Default to unknown if the game ID is unrecognized
|
|
}
|
|
}
|
|
|
|
static Language convert_rom_lang_to_ptgb_lang(int rom_lang)
|
|
{
|
|
switch (rom_lang)
|
|
{
|
|
case LANG_JPN:
|
|
return JAPANESE;
|
|
case LANG_ENG:
|
|
return ENGLISH;
|
|
case LANG_FRE:
|
|
return FRENCH;
|
|
case LANG_ITA:
|
|
return ITALIAN;
|
|
case LANG_GER:
|
|
return GERMAN;
|
|
case LANG_SPA:
|
|
return SPANISH;
|
|
default:
|
|
return LANGUAGE_UNKNOWN; // Default to unknown if the language is unrecognized
|
|
}
|
|
}
|
|
|
|
/**
|
|
* The trainer OT is encoded in the gen3 proprietary charset.
|
|
* But if we want to print it with npf_snprintf, we need to convert it to UTF-8 first.
|
|
*/
|
|
static void convert_OT_to_utf8(const u8 *encoded_OT, u8 *output_buffer, const u16 *gen3_charset)
|
|
{
|
|
u16 current_char;
|
|
u32 num_bytes;
|
|
u8 utf8_codepoint_buffer[4];
|
|
u8 *cur_out = output_buffer;
|
|
|
|
for (u32 i = 0; i < 7 && encoded_OT[i] != 0xFF; ++i)
|
|
{
|
|
// the charset maps each gen 3 character (represented as a byte) to a UTF-16 codepoint.
|
|
// So we first convert the encoded OT character to UTF-16, and then convert that UTF-16 codepoint to UTF-8.
|
|
current_char = convert_gen_3_char_to_utf16(gen3_charset, encoded_OT[i]);
|
|
num_bytes = convert_utf16_to_utf8_char(current_char, utf8_codepoint_buffer);
|
|
|
|
memcpy(cur_out, utf8_codepoint_buffer, num_bytes);
|
|
cur_out += num_bytes;
|
|
}
|
|
*cur_out = '\0';
|
|
}
|
|
|
|
void show_debug_menu_section(void *context, unsigned user_param)
|
|
{
|
|
(void)context; // unused
|
|
const DebugMenuSection section_to_show = static_cast<DebugMenuSection>(user_param);
|
|
push_debug_menu_section(section_to_show);
|
|
}
|
|
|
|
void show_text_debug_screen(void *context, unsigned user_param)
|
|
{
|
|
(void)context;
|
|
(void)user_param;
|
|
|
|
tte_set_ink(INK_DARK_GREY);
|
|
BG_FLEX = (BG_FLEX & ~BG_PRIO_MASK) | BG_PRIO(3);
|
|
text_loop(SCRIPT_DEBUG);
|
|
}
|
|
|
|
void show_debug_info_screen(void *context, unsigned user_param)
|
|
{
|
|
(void)context;
|
|
(void)user_param;
|
|
|
|
char flags_hex_str[16];
|
|
char def_lang_hex_str[16];
|
|
char text_buffer[256];
|
|
uint16_t charset[256];
|
|
const char *game_code;
|
|
u32 pkmn_flags = 0;
|
|
|
|
load_localized_charset(charset, 3, ENGLISH);
|
|
if (key_held(KEY_UP) && key_held(KEY_L) && key_held(KEY_R))
|
|
{
|
|
set_treecko(true);
|
|
}
|
|
|
|
bool e4_flag = read_flag(curr_GBA_rom.e4_flag);
|
|
bool mg_flag = read_flag(curr_GBA_rom.mg_flag);
|
|
bool all_collected_flag = read_flag(curr_GBA_rom.all_collected_flag);
|
|
for (int i = 0; i < 30; i++)
|
|
{
|
|
pkmn_flags |= (read_flag(curr_GBA_rom.pkmn_collected_flag_start + i) << i);
|
|
}
|
|
|
|
bool tutorial = get_tutorial_flag();
|
|
int def_lang = get_def_lang_num();
|
|
|
|
switch (curr_GBA_rom.gamecode)
|
|
{
|
|
case RUBY_ID:
|
|
game_code = "-R-";
|
|
break;
|
|
case SAPPHIRE_ID:
|
|
game_code = "-S-";
|
|
break;
|
|
case FIRERED_ID:
|
|
game_code = "-F-";
|
|
break;
|
|
case LEAFGREEN_ID:
|
|
game_code = "-L-";
|
|
break;
|
|
case EMERALD_ID:
|
|
game_code = "-E-";
|
|
break;
|
|
default:
|
|
game_code = "-UNK-";
|
|
break;
|
|
}
|
|
|
|
n2hexstr(flags_hex_str, pkmn_flags);
|
|
n2hexstr(def_lang_hex_str, def_lang);
|
|
|
|
//create_textbox(4, 1, 160, 80, true);
|
|
show_textbox();
|
|
|
|
npf_snprintf(text_buffer, sizeof(text_buffer),
|
|
"Debug info:\n\nG: %d%s%d\nF: %d%d%d-%s\nS: %d-%s\n%s%s",
|
|
curr_GBA_rom.language,
|
|
game_code,
|
|
curr_GBA_rom.version,
|
|
e4_flag,
|
|
mg_flag,
|
|
all_collected_flag,
|
|
flags_hex_str,
|
|
tutorial,
|
|
def_lang_hex_str,
|
|
BUILD_INFO,
|
|
get_treecko_enabled() ? ".T" : ""
|
|
);
|
|
|
|
ptgb_write_debug(charset, text_buffer, true);
|
|
|
|
while (true)
|
|
{
|
|
if (key_hit(KEY_B))
|
|
{
|
|
hide_textbox();
|
|
reload_textbox_background();
|
|
return;
|
|
}
|
|
global_next_frame();
|
|
}
|
|
}
|
|
|
|
void dbg_set_boolean_flag(void *context, unsigned user_param)
|
|
{
|
|
bool *flag_ptr = (bool*)context;
|
|
*flag_ptr = (user_param != 0);
|
|
}
|
|
|
|
void dbg_play_song(void *context, unsigned user_param)
|
|
{
|
|
if(user_param == UINT32_MAX)
|
|
{
|
|
stop_song();
|
|
return;
|
|
}
|
|
play_song(user_param, true);
|
|
}
|
|
|
|
void dbg_inject_pkmn(void *context, unsigned user_param)
|
|
{
|
|
const Game game_type = convert_rom_game_id_to_ptgb_game(curr_GBA_rom.gamecode);
|
|
const Language game_lang = convert_rom_lang_to_ptgb_lang(curr_GBA_rom.language);
|
|
u32 ret;
|
|
char text_buffer[256];
|
|
u8 encoded_OT[8];
|
|
u8 decoded_OT_utf8[32];
|
|
int boxIndex = 0;
|
|
|
|
Gen3CartridgeSaveReader reader(global_memory_buffer);
|
|
Gen3SaveManager save_manager(game_type, game_lang, reader);
|
|
|
|
PokemonTables tables;
|
|
tables.load_gen3_charset(game_lang);
|
|
|
|
Gen3Pokemon celebi(&tables);
|
|
celebi.loadData(RSEFL_10_ANIV_Celebi_0BF5_ENG_, false);
|
|
|
|
// front_sprite_tile_id is reserved behind the box sprites
|
|
if(!g_debug_options.ignore_game_pak && !g_debug_options.ignore_game_pak_sprites)
|
|
{
|
|
u32 front_sprite_tile_id = global_tile_id_end + (30 * 16);
|
|
load_sprite_compressed(grabbed_front_sprite, (const unsigned int *)*(u32 *)(curr_GBA_rom.loc_gMonFrontPicTable + (0 * 8)), front_sprite_tile_id, PULLED_SPRITE_PAL, ATTR0_SQUARE, ATTR1_SIZE_64x64, 1);
|
|
update_front_box_sprite(&celebi, false);
|
|
obj_set_pos(grabbed_front_sprite, 88, 16);
|
|
obj_unhide(grabbed_front_sprite, 0);
|
|
}
|
|
|
|
save_manager.setNationalDexUnlocked(true);
|
|
|
|
do
|
|
{
|
|
ret = save_manager.addPokemonToBox(boxIndex, celebi);
|
|
if(ret != UINT32_MAX)
|
|
{
|
|
break;
|
|
}
|
|
++boxIndex;
|
|
|
|
} while (boxIndex < 14);
|
|
|
|
if(ret == UINT32_MAX)
|
|
{
|
|
// Failed to inject the Pokémon, all boxes are full. You can handle this case as needed (e.g., show an error message).
|
|
return;
|
|
}
|
|
|
|
save_manager.finishSave();
|
|
reader.flush();
|
|
save_manager.readTrainerName(encoded_OT, ret);
|
|
|
|
create_textbox(BOX_TYPE_DIALOUGEBOX, true);
|
|
show_textbox();
|
|
|
|
tte_set_pos(LEFT, TOP);
|
|
tte_erase_rect(LEFT, TOP, RIGHT, BOTTOM);
|
|
|
|
convert_OT_to_utf8(encoded_OT, decoded_OT_utf8, tables.gen3_charset);
|
|
npf_snprintf(text_buffer, sizeof(text_buffer), "%s received a Celebi!\n Celebi was sent to box %d!", decoded_OT_utf8, boxIndex);
|
|
ptgb_write_debug(tables.gen3_charset, text_buffer, false);
|
|
|
|
wait_for_user_to_continue(H_MAX, V_MAX);
|
|
|
|
if(!g_debug_options.ignore_game_pak && !g_debug_options.ignore_game_pak_sprites)
|
|
{
|
|
obj_hide(grabbed_front_sprite);
|
|
}
|
|
|
|
hide_textbox();
|
|
tte_erase_rect(LEFT, TOP, RIGHT, BOTTOM);
|
|
}
|
|
|
|
void dbg_unlock_mystery(void *context, unsigned user_param)
|
|
{
|
|
const Game game_type = convert_rom_game_id_to_ptgb_game(curr_GBA_rom.gamecode);
|
|
const Language game_lang = convert_rom_lang_to_ptgb_lang(curr_GBA_rom.language);
|
|
Gen3CartridgeSaveReader reader(global_memory_buffer);
|
|
Gen3SaveManager save_manager(game_type, game_lang, reader);
|
|
|
|
if(user_param == 0)
|
|
{
|
|
// mystery event not supported by fire red or leaf green
|
|
if(game_type == FIRERED || game_type == LEAFGREEN)
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// mystery gift not supported by ruby or sapphire
|
|
if(game_type == RUBY || game_type == SAPPHIRE)
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
|
|
save_manager.setMysteryEventUnlocked(user_param == 0);
|
|
save_manager.setMysteryGiftUnlocked(user_param != 0);
|
|
|
|
save_manager.finishSave();
|
|
reader.flush();
|
|
}
|
|
|
|
void dbg_inject_wc3(void *context, unsigned user_param)
|
|
{
|
|
const u8* wc3_data_ptr = reinterpret_cast<const u8*>(context);
|
|
size_t wc3_data_size = user_param;
|
|
if(wc3_data_ptr == nullptr)
|
|
{
|
|
return;
|
|
}
|
|
|
|
const Game game_type = convert_rom_game_id_to_ptgb_game(curr_GBA_rom.gamecode);
|
|
if(game_type != EMERALD)
|
|
{
|
|
return;
|
|
}
|
|
|
|
const Language game_lang = convert_rom_lang_to_ptgb_lang(curr_GBA_rom.language);
|
|
Gen3CartridgeSaveReader reader(global_memory_buffer);
|
|
Gen3SaveManager save_manager(game_type, game_lang, reader);
|
|
|
|
save_manager.setMysteryGiftUnlocked(user_param != 0);
|
|
save_manager.injectMysteryGift(wc3_data_ptr, wc3_data_size);
|
|
|
|
save_manager.finishSave();
|
|
reader.flush();
|
|
}
|
|
|
|
void dbg_inject_me3(void *context, unsigned user_param)
|
|
{
|
|
const u8* me3_data_ptr = reinterpret_cast<const u8*>(context);
|
|
size_t me3_data_size = user_param;
|
|
if(me3_data_ptr == nullptr)
|
|
{
|
|
return;
|
|
}
|
|
|
|
const Game game_type = convert_rom_game_id_to_ptgb_game(curr_GBA_rom.gamecode);
|
|
if(game_type != RUBY && game_type != SAPPHIRE)
|
|
{
|
|
return;
|
|
}
|
|
|
|
const Language game_lang = convert_rom_lang_to_ptgb_lang(curr_GBA_rom.language);
|
|
Gen3CartridgeSaveReader reader(global_memory_buffer);
|
|
Gen3SaveManager save_manager(game_type, game_lang, reader);
|
|
|
|
save_manager.setMysteryEventUnlocked(true);
|
|
save_manager.injectMysteryEvent(me3_data_ptr, me3_data_size);
|
|
|
|
save_manager.finishSave();
|
|
reader.flush();
|
|
} |