diff --git a/graphics/openingBG.grit b/graphics/openingBG.grit new file mode 100644 index 0000000..96096d1 --- /dev/null +++ b/graphics/openingBG.grit @@ -0,0 +1,6 @@ +# +# Text Box (Background) : 64x64t, 4bpp, SBB-layout, not compressed. +# Pallet bank 2, copy from 32 to 48. +# +-gt -gB4 -mR4 -mLs -mp2 -ps32 -pe48 + diff --git a/graphics/openingBG.png b/graphics/openingBG.png new file mode 100644 index 0000000..fdf95a5 Binary files /dev/null and b/graphics/openingBG.png differ diff --git a/graphics/unused graphics/The_Gears_of_Progress_Official_PFP_Original.png b/graphics/unused graphics/The_Gears_of_Progress_Official_PFP_Original.png new file mode 100644 index 0000000..3ca7d73 Binary files /dev/null and b/graphics/unused graphics/The_Gears_of_Progress_Official_PFP_Original.png differ diff --git a/graphics/unused graphics/gen5.png b/graphics/unused graphics/gen5.png new file mode 100644 index 0000000..092f578 Binary files /dev/null and b/graphics/unused graphics/gen5.png differ diff --git a/graphics/unused graphics/klink.png b/graphics/unused graphics/klink.png new file mode 100644 index 0000000..b872dcd Binary files /dev/null and b/graphics/unused graphics/klink.png differ diff --git a/include/debug_mode.h b/include/debug_mode.h new file mode 100644 index 0000000..3de7365 --- /dev/null +++ b/include/debug_mode.h @@ -0,0 +1,7 @@ +#ifndef DEBUG_MODE_H +#define DEBUG_MODE_H + +static bool DEBUG_MODE = true; +// This is literally it. Yay. + +#endif \ No newline at end of file diff --git a/include/main_menu.h b/include/main_menu.h index 2a5884e..a1f24fa 100644 --- a/include/main_menu.h +++ b/include/main_menu.h @@ -5,11 +5,19 @@ #include "button_handler.h" +#define MAIN_MENU 0 #define TRANSFER 1 #define POKEDEX 2 #define CREDITS 3 +#define NO_ANI 0 +#define ENTERING -1 +#define EXITING -2 +#define DISABLE -3 + void main_menu_init(Button transfer, Button pokedex, Button credits); int main_menu_loop(); +void main_menu_enter(); +void main_menu_exit(); #endif \ No newline at end of file diff --git a/include/script_array.h b/include/script_array.h index 8711c2c..a42fd5c 100644 --- a/include/script_array.h +++ b/include/script_array.h @@ -4,7 +4,7 @@ #include "script_obj.h" #include "pokemon_party.h" -extern script_obj script[16]; +extern script_obj script[17]; void add_script_party_var(Pokemon_Party var); bool run_conditional(int index); diff --git a/include/script_obj.h b/include/script_obj.h index 0eb72af..303597f 100644 --- a/include/script_obj.h +++ b/include/script_obj.h @@ -4,14 +4,14 @@ #include #include "pokemon_party.h" -#define CHECK_GAME 1 -#define START_LINK 2 -#define ERROR_TIMEOUT_ONE 3 -#define ERROR_DISCONNECT 4 -#define ERROR_COM_ENDED 5 -#define ERROR_TIMEOUT_TWO 6 -#define ERROR_COLOSSEUM 7 -#define IMPORT_POKEMON 8 +#define START_LINK 1 +#define ERROR_TIMEOUT_ONE 2 +#define ERROR_DISCONNECT 3 +#define ERROR_COM_ENDED 4 +#define ERROR_TIMEOUT_TWO 5 +#define ERROR_COLOSSEUM 6 +#define IMPORT_POKEMON 7 +#define BACK_TO_MENU 8 class script_obj { diff --git a/include/sprite_data.h b/include/sprite_data.h index 684ce19..4390478 100644 --- a/include/sprite_data.h +++ b/include/sprite_data.h @@ -14,6 +14,7 @@ extern OBJ_ATTR *btn_c_r; void load_background(); void load_textbox_background(); +void load_opening_background(); void load_testroid(); void load_professor(); void load_btn_t_l(); diff --git a/include/text_engine.h b/include/text_engine.h index f65e36b..7315d32 100644 --- a/include/text_engine.h +++ b/include/text_engine.h @@ -7,17 +7,10 @@ #include "script_obj.h" #include "script_array.h" -class text_engine -{ -public: - text_engine(); - void next_frame(); - int get_next_obj_id(script_obj current_line); - -private: - script_obj curr_line; - int frame_count; - void set_next_line(std::string next); -}; + void init_text_engine(); + void text_next_frame(); + int text_next_obj_id(script_obj current_line); + void text_enable(); + void text_disable(); #endif \ No newline at end of file diff --git a/source/main.cpp b/source/main.cpp index a310221..d9786ae 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -18,6 +18,7 @@ #include "sprite_data.h" #include "button_handler.h" #include "main_menu.h" +#include "debug_mode.h" /*TODO: -------- @@ -56,15 +57,15 @@ TESTING: */ Pokemon_Party party = Pokemon_Party(); -text_engine main_text = text_engine(); int main(void) { + int delay_counter = 0; // Initalizations linkGPIO->reset(); - REG_DISPCNT = DCNT_MODE0 | DCNT_BG0 | DCNT_BG2 | DCNT_BG3 | DCNT_OBJ | DCNT_OBJ_1D; + REG_DISPCNT = DCNT_MODE0 | DCNT_BG0 | DCNT_BG1 | DCNT_BG2 | DCNT_BG3 | DCNT_OBJ | DCNT_OBJ_1D; irq_init(NULL); irq_enable(II_VBLANK); @@ -72,6 +73,7 @@ int main(void) flash_init(FLASH_SIZE_128KB); initalize_memory_locations(); rand_set_seed(0x12162001); + init_text_engine(); add_script_party_var(party); @@ -79,6 +81,7 @@ int main(void) load_background(); load_textbox_background(); + load_opening_background(); load_testroid(); load_professor(); load_btn_t_l(); @@ -93,7 +96,61 @@ int main(void) Button credits_btn = Button(btn_c_l, btn_c_r, 256, 288); main_menu_init(transfer_btn, pokedex_btn, credits_btn); - + + text_disable(); + + // Check if the game has been loaded correctly. + u32 game_code = (*(vu32 *)(0x80000AC)) & 0xFFFFFF; + if (!(game_code == 0x565841 || // Ruby + game_code == 0x505841 || // Sapphire + game_code == 0x525042 || // FireRed + game_code == 0x475042 || // LeafGreen + game_code == 0x455042 || // Emerald + DEBUG_MODE // Ignore if in debug mode + )) + { + REG_BG0CNT = (REG_BG0CNT & ~BG_PRIO_MASK) | BG_PRIO(3); + REG_BG1CNT = (REG_BG1CNT & ~BG_PRIO_MASK) | BG_PRIO(2); + REG_BG2CNT = (REG_BG2CNT & ~BG_PRIO_MASK) | BG_PRIO(1); + REG_BG2VOFS = 0; + tte_set_pos(40, 24); + tte_set_margins(40, 24, 206, 104); + tte_write("The Pokemon save\nfile was not loaded successfully. Please\nrestart the console,\nload the Pokemon\ngame normally, and\nthen upload the\nprogram again."); + while (1) + { + }; + } + + // Legal mumbo jumbo + tte_set_pos(8, 0); + tte_write("\n\nPokemon Mirror was created\nout of love and appreciation\nfor the Pokemon franchise\nwith no profit in mind.\nIt will ALWAYS be free.\n\nPlease support the original developers-\nNintendo and GAME FREAK.\n\nAll Pokemon names, sprites, and music are owned by \nNintendo, Creatures Inc, and\nGAME FREAK Inc."); + while (delay_counter < 2500000) + { + delay_counter++; + rand_next_frame(); + key_poll(); + if (key_hit(KEY_A)) + { + delay_counter = 2500000; + } + } + key_poll(); + // Gears of Progress + tte_erase_rect(0, 0, 240, 160); + REG_BG1VOFS = 0; + delay_counter = 0; + while (delay_counter < 2500000) + { + delay_counter++; + rand_next_frame(); + key_poll(); + if (key_hit(KEY_A)) + { + delay_counter = 2500000; + } + } + key_poll(); + REG_BG1CNT = REG_BG1CNT | BG_PRIO(3); // Set up blend to fade to white/black @@ -103,19 +160,26 @@ int main(void) switch (main_menu_loop()) { case (TRANSFER): + text_enable(); break; case (POKEDEX): - + main_menu_exit(); break; case (CREDITS): - + tte_set_pos(0, 0); + tte_write("wow cool credits man"); + if (key_hit(KEY_B)) + { + tte_erase_rect(0, 0, 240, 160); + main_menu_exit(); + } break; } key_poll(); rand_next_frame(); background_frame(); - //main_text.next_frame(); + text_next_frame(); oam_copy(oam_mem, obj_buffer, 8); } } diff --git a/source/main_menu.cpp b/source/main_menu.cpp index d8ddbad..fa47886 100644 --- a/source/main_menu.cpp +++ b/source/main_menu.cpp @@ -2,10 +2,11 @@ #include "main_menu.h" #include "button_handler.h" - - int menu_slot = 1; int old_menu_slot = 0; +int menu_mode = MAIN_MENU; +int ani_mode = 0; +int x_cord = 128; Button button_array[4]; @@ -14,9 +15,9 @@ void main_menu_init(Button nTransfer, Button nPokedex, Button nCredits) button_array[TRANSFER] = nTransfer; button_array[POKEDEX] = nPokedex; button_array[CREDITS] = nCredits; - button_array[TRANSFER].set_location(10, 10); - button_array[POKEDEX].set_location(10, 60); - button_array[CREDITS].set_location(10, 100); + button_array[TRANSFER].set_location(128, 16); + button_array[POKEDEX].set_location(128, 64); + button_array[CREDITS].set_location(128, 112); button_array[TRANSFER].show(); button_array[POKEDEX].show(); button_array[CREDITS].show(); @@ -24,27 +25,79 @@ void main_menu_init(Button nTransfer, Button nPokedex, Button nCredits) int main_menu_loop() { - if(key_hit(KEY_DOWN)){ - if (menu_slot != CREDITS){ - menu_slot++; - } - } - - if (key_hit(KEY_UP)){ - if (menu_slot != TRANSFER){ - menu_slot--; - } - } - - if (key_hit(KEY_A)){ - return (menu_slot); - } - - if (menu_slot != old_menu_slot) + switch (ani_mode) { - button_array[menu_slot].set_highlight(true); - button_array[old_menu_slot].set_highlight(false); - old_menu_slot = menu_slot; + case ENTERING: + { + x_cord = x_cord + 4; + for (int i = 1; i < 4; i++) + { + button_array[i].set_location(x_cord, 16 + (48 * (i - 1))); + } + if (x_cord > 220) + { + ani_mode = DISABLE; + } + break; + } + case EXITING: + { + x_cord = x_cord - 4; + for (int i = 1; i < 4; i++) + { + button_array[i].set_location(x_cord, 16 + (48 * (i - 1))); + } + if (x_cord <= 128) + { + ani_mode = MAIN_MENU; + } + break; + } + case MAIN_MENU: + { + if (key_hit(KEY_DOWN)) + { + if (menu_slot != CREDITS) + { + menu_slot++; + } + } + + if (key_hit(KEY_UP)) + { + if (menu_slot != TRANSFER) + { + menu_slot--; + } + } + + if (key_hit(KEY_A)) + { + ani_mode = ENTERING; + } + + if (menu_slot != old_menu_slot) + { + button_array[menu_slot].set_highlight(true); + button_array[old_menu_slot].set_highlight(false); + old_menu_slot = menu_slot; + } + return 0; + } + }; + if (ani_mode == DISABLE) + { + return menu_slot; } return 0; } + +void main_menu_enter() +{ + ani_mode = ENTERING; +} + +void main_menu_exit() +{ + ani_mode = EXITING; +} \ No newline at end of file diff --git a/source/pokemon_party.cpp b/source/pokemon_party.cpp index 97b3e63..5b89efd 100644 --- a/source/pokemon_party.cpp +++ b/source/pokemon_party.cpp @@ -2,8 +2,7 @@ #include "pokemon_party.h" #include "pokemon.h" #include "flash_mem.h" - -static bool DEBUG = false; +#include "debug_mode.h" byte debug_party_data[444] = { 0x8A, 0x91, 0x88, 0x92, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x06, 0x9B, 0x13, 0xA1, 0xA1, 0xA1, 0xA1, 0xFF, 0x25, 0xDA, @@ -34,7 +33,7 @@ byte debug_party_data[444] = { Pokemon_Party::Pokemon_Party(){}; void Pokemon_Party::start_link() { - if (DEBUG) + if (DEBUG_MODE) { for (int i = 0; i < 444; i++) { diff --git a/source/script_array.cpp b/source/script_array.cpp index 33253dc..21932d8 100644 --- a/source/script_array.cpp +++ b/source/script_array.cpp @@ -1,13 +1,15 @@ #include "script_array.h" +#include "main_menu.h" +#include "text_engine.h" #include int last_error; Pokemon_Party party_data; -script_obj script[16] = +script_obj script[17] = { - script_obj("", 2, CHECK_GAME, 1), // 0 + script_obj("", 2), // 0 script_obj("Game not detected. Please turn off your system and upload the program again.", 2), // 1 script_obj("Welcome to Pokemon Mirror!", 3), // 2 script_obj("Please connect your GBA to a GB in the trading room, and press A", 4, START_LINK), // 3 @@ -22,7 +24,8 @@ script_obj script[16] = script_obj("", 14, ERROR_COLOSSEUM, 13), // 12 script_obj("Error: Went into Colosseum", 3), // 13 script_obj("Connection successful! Transfering in Pokemon now", 15), // 14 - script_obj("", 14, IMPORT_POKEMON), // 15 + script_obj("", 16, IMPORT_POKEMON), // 15 + script_obj("Bye!", 0, BACK_TO_MENU), // 16 }; void add_script_party_var(Pokemon_Party var) @@ -35,16 +38,7 @@ bool run_conditional(int index) // Here is most of the logic that drives what lines show up where. It's probably not the best way to code it, but it works switch (index) { - case CHECK_GAME: - { - u32 game_code = (*(vu32 *)(0x80000AC)) & 0xFFFFFF; - return (game_code == 0x565841 || // Ruby - game_code == 0x505841 || // Sapphire - game_code == 0x525042 || // FireRed - game_code == 0x475042 || // LeafGreen - game_code == 0x455042 // Emerald - ); - } + case START_LINK: party_data.start_link(); return true; @@ -69,6 +63,12 @@ bool run_conditional(int index) party_data.inject_pokemon(); return true; + case BACK_TO_MENU: + text_disable(); + main_menu_exit(); + return true; + + default: tte_set_pos(0, 0); tte_write("ERROR! No conditional found."); diff --git a/source/sprite_data.cpp b/source/sprite_data.cpp index a1c559e..37ad7ca 100644 --- a/source/sprite_data.cpp +++ b/source/sprite_data.cpp @@ -20,11 +20,26 @@ void load_background(){ REG_BG0CNT= BG_CBB(CBB) | BG_SBB(SBB) | BG_4BPP | BG_REG_32x32 | BG_PRIO(2); } -#include "textboxBG.h" -void load_textbox_background(){ +#include "openingBG.h" +void load_opening_background(){ int CBB = 1; int SBB = 9; // Load palette + memcpy(pal_bg_mem + 32, openingBGPal, openingBGPalLen); + // Load tiles into CBB 0 + memcpy(&tile_mem[CBB][0], openingBGTiles, openingBGTilesLen); + // Load map into SBB 0 + memcpy(&se_mem[SBB][0], openingBGMap, openingBGMapLen); + + REG_BG1VOFS = 96; + REG_BG1CNT = BG_CBB(CBB) | BG_SBB(SBB) | BG_4BPP | BG_REG_32x32 | BG_PRIO(1); +} + +#include "textboxBG.h" +void load_textbox_background(){ + int CBB = 2; + int SBB = 17; + // Load palette memcpy(pal_bg_mem + 16, textBoxBGPal, textBoxBGPalLen); // Load tiles into CBB 0 memcpy(&tile_mem[CBB][0], textBoxBGTiles, textBoxBGTilesLen); diff --git a/source/text_engine.cpp b/source/text_engine.cpp index 6d7284b..402f1e9 100644 --- a/source/text_engine.cpp +++ b/source/text_engine.cpp @@ -14,46 +14,54 @@ const int RIGHT = H_MAX - LEFT; const int TOP = 120; const int BOTTOM = V_MAX; -uint char_count = 0; +script_obj curr_line; +int frame_count; +uint char_count; +bool disabled; -text_engine::text_engine() +void init_text_engine() { // Load the TTE - tte_init_se(3, BG_CBB(TEXT_CBB)|BG_SBB(TEXT_SBB)|BG_PRIO(0), 0xF000, CLR_PURPLE, 0, &fwf_default, NULL); + tte_init_se(3, BG_CBB(TEXT_CBB) | BG_SBB(TEXT_SBB) | BG_PRIO(0), 0xF000, CLR_ORANGE, 0, &fwf_default, NULL); tte_set_margins(LEFT, TOP, RIGHT, BOTTOM); tte_set_pos(LEFT, TOP); // Set default variables curr_line = script[0]; frame_count = 0; + char_count = 0; + disabled = false; } -void text_engine::next_frame() +void text_next_frame() { - tte_set_pos(LEFT, TOP); - if (char_count < curr_line.get_text().length()) + if (!disabled) { - if (frame_count % 2 == 0 || key_held(KEY_B)) + tte_set_pos(LEFT, TOP); + if (char_count < curr_line.get_text().length()) { - char_count++; - tte_erase_rect(LEFT, TOP, RIGHT, BOTTOM); - tte_set_ink(CLR_RED); - tte_write(curr_line.get_text().substr(0, char_count).c_str()); + if (frame_count % 2 == 0 || key_held(KEY_B)) + { + char_count++; + tte_erase_rect(LEFT, TOP, RIGHT, BOTTOM); + tte_set_ink(CLR_RED); + tte_write(curr_line.get_text().substr(0, char_count).c_str()); + } } - } - else - { - if (key_hit(KEY_A) || char_count == 0) + else { - curr_line = script[get_next_obj_id(curr_line)]; - char_count = 0; + if (key_hit(KEY_A) || char_count == 0) + { + curr_line = script[text_next_obj_id(curr_line)]; + char_count = 0; + } } - } - frame_count++; + frame_count++; + } } -int text_engine::get_next_obj_id(script_obj current_line) +int text_next_obj_id(script_obj current_line) { if (current_line.get_cond_id() == 0) { @@ -69,3 +77,15 @@ int text_engine::get_next_obj_id(script_obj current_line) } } +void text_enable() +{ + disabled = false; + REG_BG2CNT = (REG_BG2CNT & ~BG_PRIO_MASK) | BG_PRIO(1); +} + +void text_disable() +{ + disabled = true; + tte_erase_screen(); + REG_BG2CNT = (REG_BG2CNT & ~BG_PRIO_MASK) | BG_PRIO(3); +}