diff options
author | NobodySociety <43542553+NobodySociety@users.noreply.github.com> | 2020-01-11 21:12:04 -0500 |
---|---|---|
committer | NobodySociety <43542553+NobodySociety@users.noreply.github.com> | 2020-01-11 21:12:04 -0500 |
commit | aca94d69f6e09c7ef07709e19f71168628fe986c (patch) | |
tree | 7248e6f33a3bce1e73a369aa281cc2526f5e3064 | |
parent | 2ea7a88db183d4217776f2581e93ecbcfa74f47c (diff) |
Created Customizable Pokédex Color (markdown)
-rw-r--r-- | Customizable-Pokédex-Color.md | 532 |
1 files changed, 532 insertions, 0 deletions
diff --git a/Customizable-Pokédex-Color.md b/Customizable-Pokédex-Color.md new file mode 100644 index 0000000..65ae4df --- /dev/null +++ b/Customizable-Pokédex-Color.md @@ -0,0 +1,532 @@ +Ever wanted to your Pokédex to be something besides red? This is rather simple to implement in pokecrystal. All that's needed is a WRAM byte, and reworking some already existing code. + +## 1. Create a WRAM Byte + +Edit [wram.asm](../blob/master/wram.asm): + +```diff + +wPokegearFlags:: +; bit 0: map +; bit 1: radio +; bit 2: phone +; bit 3: expn +; bit 7: on/off + db +wRadioTuningKnob:: db +wLastDexMode:: db +- ds 1 ++wCurPokedexColor:: db ; current dex color +wWhichRegisteredItem:: db ; d95b +wRegisteredItem:: db ; d95c +``` + +To start we create a wram byte. `wLastDexMode` has room after it and is also used by [engine\pokedex\pokedex.asm](../blob/master/engine/pokedex/pokedex.asm). + +## 2. Create Constants + +Edit [constants\wram_constants.asm](../blob/master/constants/wram_constants.asm). + +```diff +; wCurDexMode:: ; c7d4 + const_def + const DEXMODE_NEW + const DEXMODE_OLD + const DEXMODE_ABC + const DEXMODE_UNOWN + ++; wPokedexColor ++ const_def ++ const DEXCOLOR_RED ++ const DEXCOLOR_BLUE ++ const DEXCOLOR_PURPLE ++ const DEXCOLOR_BROWN ++ const DEXCOLOR_GREEN ++ const DEXCOLOR_PINK ++ const DEXCOLOR_YELLOW ++ const DEXCOLOR_CYAN + +; wMonType:: ; cf5f + const_def + const PARTYMON ; 0 + const OTPARTYMON ; 1 + const BOXMON ; 2 + const TEMPMON ; 3 + const WILDMON ; 4 +``` + +Now we need some constants that'll be used to figure out which color is seleceted. + +## 3. Add the Color Option + +Edit [engine\pokedex\pokedex.asm](../blob/master/engine/pokedex/pokedex.asm). + +```diff +; Pokedex_RunJumptable.Jumptable indexes + const_def + const DEXSTATE_MAIN_SCR + const DEXSTATE_UPDATE_MAIN_SCR + const DEXSTATE_DEX_ENTRY_SCR + const DEXSTATE_UPDATE_DEX_ENTRY_SCR + const DEXSTATE_REINIT_DEX_ENTRY_SCR + const DEXSTATE_SEARCH_SCR + const DEXSTATE_UPDATE_SEARCH_SCR + const DEXSTATE_OPTION_SCR + const DEXSTATE_UPDATE_OPTION_SCR + const DEXSTATE_SEARCH_RESULTS_SCR + const DEXSTATE_UPDATE_SEARCH_RESULTS_SCR + const DEXSTATE_UNOWN_MODE + const DEXSTATE_UPDATE_UNOWN_MODE ++ const DEXSTATE_COLOR_OPTION ++ const DEXSTATE_UPDATE_COLOR_OPTION + const DEXSTATE_EXIT +``` +First is to create the `const` DEXSTATEs that'll be used to determine the Color options screen. + +```diff +.Jumptable: +; entries correspond to DEXSTATE_* constants + dw Pokedex_InitMainScreen + dw Pokedex_UpdateMainScreen + dw Pokedex_InitDexEntryScreen + dw Pokedex_UpdateDexEntryScreen + dw Pokedex_ReinitDexEntryScreen + dw Pokedex_InitSearchScreen + dw Pokedex_UpdateSearchScreen + dw Pokedex_InitOptionScreen + dw Pokedex_UpdateOptionScreen + dw Pokedex_InitSearchResultsScreen + dw Pokedex_UpdateSearchResultsScreen + dw Pokedex_InitUnownMode + dw Pokedex_UpdateUnownMode ++ dw Pokedex_InitColorOption ++ dw Pokedex_UpdateColorOption + dw Pokedex_Exit +``` +And to create the jumptable data for those screens. + +```diff +Pokedex_InitOptionScreen: + xor a + ldh [hBGMapMode], a + call ClearSprites + call Pokedex_DrawOptionScreenBG + call Pokedex_InitArrowCursor +- ld a, [wCurDexMode] ; Index of the topmost visible item in a scrolling menu ??? + ld [wDexArrowCursorPosIndex], a + call Pokedex_DisplayModeDescription + call WaitBGMap + ld a, SCGB_POKEDEX_SEARCH_OPTION + call Pokedex_GetSGBLayout + call Pokedex_IncrementDexPointer + ret +``` +This is to make sure the options menu starts at the top of the screen whenever the player enters it. Otherwise it'd begin at the second option. + +```diff +Pokedex_UpdateOptionScreen: +... + +.NoUnownModeArrowCursorData: +- db D_UP | D_DOWN, 3 +- dwcoord 2, 4 ; NEW +- dwcoord 2, 6 ; OLD +- dwcoord 2, 8 ; ABC ++ db D_UP | D_DOWN, 4 ++ dwcoord 2, 3 ; NEW ++ dwcoord 2, 4 ; OLD ++ dwcoord 2, 5 ; ABC ++ dwcoord 2, 6 ; COLOR + +.ArrowCursorData: +- db D_UP | D_DOWN, 4 +- dwcoord 2, 4 ; NEW +- dwcoord 2, 6 ; OLD +- dwcoord 2, 8 ; ABC +- dwcoord 2, 10 ; UNOWN ++ db D_UP | D_DOWN, 5 ++ dwcoord 2, 3 ; NEW ++ dwcoord 2, 4 ; OLD ++ dwcoord 2, 5 ; ABC ++ dwcoord 2, 6 ; COLOR ++ dwcoord 2, 7 ; UNOWN +``` + +Here we're adding the color option to the cursor jumptable. You may notice that the `dwcoord` are changed as well. This is because in order to fit an extra option on the screen, along with a description of said option, we need to remove the space between each option. + +```diff +.MenuActionJumptable: + dw .MenuAction_NewMode + dw .MenuAction_OldMode + dw .MenuAction_ABCMode ++ dw .MenuAction_ColorOption + dw .MenuAction_UnownMode +... ++.MenuAction_ColorOption ++ call Pokedex_BlackOutBG ++ ld a, DEXSTATE_COLOR_OPTION ++ ld [wJumptableIndex], a ++ ret + +.MenuAction_UnownMode: + call Pokedex_BlackOutBG + ld a, DEXSTATE_UNOWN_MODE + ld [wJumptableIndex], a + ret +``` +Adding the Color option to the `.MenuActionJumptable`. As you can see, the menu action is a copy of the Unown Dex action, but it takes us to the color option instead. + +``` +Pokedex_InitColorOption: + xor a + ldh [hBGMapMode], a + call ClearSprites + call Pokedex_DrawColorScreenBG + call Pokedex_InitArrowCursor + ld a, [wCurPokedexColor] + ld [wDexArrowCursorPosIndex], a + call WaitBGMap + ld a, SCGB_POKEDEX_SEARCH_OPTION + call Pokedex_GetSGBLayout + call Pokedex_IncrementDexPointer + ret +``` + +Here is the actual color option screen code, that should be placed after `Pokedex_UnownModeUpdateCursorGfx` Its a modified `Pokedex_InitOptionScreen` that will also remember cursor's location on the screen. + +```diff +Pokedex_DrawOptionScreenBG: + call Pokedex_FillBackgroundColor2 + hlcoord 0, 2 + lb bc, 8, 18 + call Pokedex_PlaceBorder + hlcoord 0, 12 + lb bc, 4, 18 + call Pokedex_PlaceBorder + hlcoord 0, 1 + ld de, .Title + call Pokedex_PlaceString +- hlcoord 3, 4 +- ld de, .Modes +- call PlaceString ++ hlcoord 3, 3 ++ ld de, .NewMode ++ call PlaceString ++ hlcoord 3, 4 ++ ld de, .OldMode ++ call PlaceString ++ hlcoord 3, 5 ++ ld de, .AtoZMode ++ call PlaceString ++ hlcoord 3, 6 ++ ld de, .Color ++ call PlaceString + ld a, [wUnlockedUnownMode] + and a + ret z +- hlcoord 3, 10 ++ hlcoord 3, 7 + ld de, .UnownMode + call PlaceString + ret + +.Title: + db $3b, " OPTION ", $3c, -1 + +-.Modes: +- db "NEW #DEX MODE" +- next "OLD #DEX MODE" +- next "A to Z MODE" +- db "@" +- ++.NewMode: ++ db "NEW #DEX MODE@" ++ ++.OldMode: ++ db "OLD #DEX MODE@" ++ ++.AtoZMode: ++ db "A to Z MODE@" ++ ++.Color: ++ db "#DEX COLOR@" ++ +.UnownMode: + db "UNOWN MODE@" +``` + +This is where we add the text displayed by the dex in the options menu. We had to change it from `.Mode` since it would force there to be a space between each line of the options, this way we guarantee that each line will be uniform. + +``` +Pokedex_DrawColorScreenBG: + call Pokedex_FillBackgroundColor2 + hlcoord 0, 2 + lb bc, 8, 18 + call Pokedex_PlaceBorder + hlcoord 0, 1 + ld de, .Title + call Pokedex_PlaceString + hlcoord 3, 3 + ld de, .Red + call Pokedex_PlaceString + hlcoord 3, 4 + ld de, .Blue + call Pokedex_PlaceString + hlcoord 3, 5 + ld de, .Purple + call Pokedex_PlaceString + hlcoord 3, 6 + ld de, .Brown + call Pokedex_PlaceString + hlcoord 3, 7 + ld de, .Green + call Pokedex_PlaceString + hlcoord 3, 8 + ld de, .Pink + call Pokedex_PlaceString + hlcoord 3, 9 + ld de, .Yellow + call Pokedex_PlaceString + hlcoord 3, 10 + ld de, .Cyan + call Pokedex_PlaceString + ret + +.Title: + db $3b, " COLORS ", $3c, -1 + +.Red + db "RED ", $4f, -1 + +.Blue + db "BLUE ", $4f, -1 + +.Purple + db "PURPLE ", $4f, -1 + +.Brown + db "BROWN ", $4f, -1 + +.Green + db "GREEN ", $4f, -1 + +.Pink + db "PINK ", $4f, -1 + +.Yellow + db "YELLOW ", $4f, -1 + +.Cyan + db "CYAN ", $4f, -1 + +Pokedex_UpdateColorOption: + ld de, .ArrowCursorData + call Pokedex_MoveArrowCursor + ld hl, hJoyPressed + ld a, [hl] + and SELECT | B_BUTTON + jr nz, .return_to_main_screen + ld a, [hl] + and A_BUTTON + jr nz, .do_menu_action + ret + +.ArrowCursorData: + db D_UP | D_DOWN, 8 + dwcoord 2, 3 ; Red + dwcoord 2, 4 ; Blue + dwcoord 2, 5 ; Purple + dwcoord 2, 6 ; Brown + dwcoord 2, 7 ; Green + dwcoord 2, 8 ; Pink + dwcoord 2, 9 ; Yellow + dwcoord 2, 10 ; Gray + +.do_menu_action + ld a, [wDexArrowCursorPosIndex] + ld hl, .MenuActionJumptable + call Pokedex_LoadPointer + jp hl + +.return_to_main_screen + call Pokedex_BlackOutBG + ld a, DEXSTATE_MAIN_SCR + ld [wJumptableIndex], a + ret + +.MenuActionJumptable: + dw .MenuAction_Red + dw .MenuAction_Blue + dw .MenuAction_Purple + dw .MenuAction_Brown + dw .MenuAction_Green + dw .MenuAction_Pink + dw .MenuAction_Yellow + dw .MenuAction_Cyan + +.MenuAction_Red + ld b, DEXCOLOR_RED + jr .ChangeColor + +.MenuAction_Blue + ld b, DEXCOLOR_BLUE + jr .ChangeColor + +.MenuAction_Purple + ld b, DEXCOLOR_PURPLE + jr .ChangeColor + +.MenuAction_Brown + ld b, DEXCOLOR_BROWN + jr .ChangeColor + +.MenuAction_Green + ld b, DEXCOLOR_GREEN + jr .ChangeColor + +.MenuAction_Pink + ld b, DEXCOLOR_PINK + jr .ChangeColor + +.MenuAction_Yellow + ld b, DEXCOLOR_YELLOW + jr .ChangeColor + +.MenuAction_Cyan + ld b, DEXCOLOR_CYAN + +.ChangeColor: + ld a, [wCurPokedexColor] + cp b + jr z, .skip_changing_color + + ld a, b + ld [wCurPokedexColor], a + +.skip_changing_color + call Pokedex_BlackOutBG + ld a, DEXSTATE_COLOR_OPTION + ld [wJumptableIndex], a + ret +``` +This should be placed immediately after `.UnownMode`. This is the bread and butter of the color options screen. So let's break it down into its parts: + +`Pokedex_DrawColorScreenBG` Is actually what creates the color option screen. Its a copy of the already used `Pokedex_DrawOptionScreenBG`, just adjusted to what we need. `Pokedex_UpdateColorOption` is similarly a copy of `Pokedex_UpdateOptionScreen`, but modified to remove the extra window at the bottom, since the colors don't really need descriptions. Also it uses the same button actions as that screen. This is optional, but the reason we've added the Pokéball symbol beside each color option is because that is the only use of the lighter color in the palette, and will give the player an additional idea of what the color will look like on a whole, without having to completely leave the menu. + +Now the `.MenuActionJumptable` is a copy of the same one used by the options screen to update the Pokédex mode its in, but modified in a way that it loads `wCurPokedexColor` we created earilier with one of the corresponding palettes and then updates the screen so to apply the color. + +```diff +Pokedex_DisplayModeDescription: + xor a + ldh [hBGMapMode], a + hlcoord 0, 12 + lb bc, 4, 18 + call Pokedex_PlaceBorder + ld a, [wDexArrowCursorPosIndex] + ld hl, .Modes + call Pokedex_LoadPointer + ld e, l + ld d, h + hlcoord 1, 14 + call PlaceString + ld a, $1 + ldh [hBGMapMode], a + ret + +.Modes: + dw .NewMode + dw .OldMode + dw .ABCMode ++ dw .Color + dw .UnownMode + +.NewMode: + db "<PK><MN> are listed by" + next "evolution type.@" + +.OldMode: + db "<PK><MN> are listed by" + next "official type.@" + +.ABCMode: + db "<PK><MN> are listed" + next "alphabetically.@" + ++.Color ++ db "Change the color" ++ next "of the border.@" + +.UnownMode: + db "UNOWN are listed" + next "in catching order.@" +``` + +And finally this adds a desctription. + +## 4. Making the Pokédex load the color + +Now that everything's set up on the Pokédex side, we it to actually load the correct color. Do some digging reveals that what we need is located in: + +[engine\gfx\cgb_layouts.asm](../blob/master/engine/gfx/cgb_layouts.asm). + +Searching the file for the default Pokédex color (`PREDEFPAL_POKEDEX`) will show it in `_CGB_Pokedex`, `_CGB_PokedexSearchOption`, and `_CGB_PokedexUnownMode`. + +```diff +_CGB_Pokedex: + ld de, wBGPals1 +- ld a, PREDEFPAL_POKEDEX ++ ld a, [wCurPokedexColor] ++ cp DEXCOLOR_BLUE ++ jr nz, .Purple ++ ld a, PREDEFPAL_TRADE_TUBE ++ jr .setColor ++.Purple ++ cp DEXCOLOR_PURPLE ++ jr nz, .Brown ++ ld a, PREDEFPAL_RB_PURPLEMON ++ jr .setColor ++.Brown ++ cp DEXCOLOR_BROWN ++ jr nz, .Green ++ ld a, PREDEFPAL_RB_BROWNMON ++ jr .setColor ++.Green ++ cp DEXCOLOR_GREEN ++ jr nz, .Pink ++ ld a, PREDEFPAL_RB_GREENMON ++ jr .setColor ++.Pink ++ cp DEXCOLOR_PINK ++ jr nz, .Yellow ++ ld a, PREDEFPAL_RB_PINKMON ++ jr .setColor ++.Yellow ++ cp DEXCOLOR_YELLOW ++ jr nz, .Cyan ++ ld a, PREDEFPAL_RB_YELLOWMON ++ jr .setColor ++.Cyan ++ cp DEXCOLOR_CYAN ++ jr nz, .Red ++ ld a, PREDEFPAL_RB_CYANMON ++ jr .setColor ++.Red ++ ld a, PREDEFPAL_POKEDEX ++.setColor + call GetPredefPal + call LoadHLPaletteIntoDE ; dex interface palette + ld a, [wCurPartySpecies] + cp $ff + jr nz, .is_pokemon + ld hl, .PokedexQuestionMarkPalette + call LoadHLPaletteIntoDE ; green question mark palette + jr .got_palette +``` + +We replaced the inital load of `PREDEFPAL_POKEDEX` with a chain comparison that finds the correct color and sets it. Do this for the other two mentioned locations and your done. + +## 5. Closing + + + +The palettes I used were the unused palettes of the original Pokémon sprites in Red/Blue, but you can use any palette you like. This also has freed up some space on the options screen to allow for other Pokédex modes in addition to what's already there!
\ No newline at end of file |