Sign Up
Romhack.me connects you to ROM Hackers around the world.
Search all tutorials.
Adding Gender Selection to Gen 1

Adding Gender Selection to Gen 1

Category:
Posted By: On July 19, 2015
Comments: 0
Views: 1174
3 Ratings

WARNING: This is a really long tutorial, and while it may not be as complicated for you as it was for me to make it up, it is still a lot more complicated than, say, editing the text or which item is in the PC at the start of the game or any of that jazz. But if you follow the tutorial properly (and assuming I haven't accidentally skipped something, since there was a lot to explain) you should be able to get this working in your game.

To see the finished results of this tutorial, you can check out this youtube video:
http://www.youtube.com/watch?v=9CPbmE9FQC8


Step 1: Get the graphics for the girl player.

For the girl player, you will need the following graphics:

-Front sprite
-Back sprite
-Walking sprite
-Cycling sprite
-Fishing tiles

To get the right dimensions for these, you can just copy+paste the ones for Red and edit them. Please note that in my example, I have Danny-E33's larger backsprite routine installed. You can do this without that routine of course, but your backsprite will have to be the normal Red Version size instead of the larger Gold Version size I am using.

Once you have your graphics drawn/found etc. make sure that they use ONLY the colours that other graphics in the project folder use (otherwise they won't convert properly) and save them as .png files with names you can remember. In my example, I kept the same naming scheme as the original files, but I substituted the word "Leaf" everywhere the original file name said "Red" and placed them in the same subfolders as the originals. This was just to make it easier for me to remember the file names later, and to make sure they are converted properly at compile.

So I ended up with files named:

/pic/trainer/leaf.png
/pic/trainer/leafb.png

/gfx/sprites/leaf.png
/gfx/sprites/leafcycling.png

/gfx/leaf_fishing_tile_back.png
/gfx/leaf_fishing_tile_front.png
/gfx/leaf_fishing_tile_side.png


Step 2: Inserting the sprites.

Now that you have the new .png files in the proper subfolders, we have to actually reference them somewhere to get them included. So we will open main.asm in notepad++ and find the references to the player's sprites. Doing a search for RedPicFront will eventually get you to this:

RedPicFront::  INCBIN "pic/trainer/red.pic"
ShrinkPic1::   INCBIN "pic/trainer/shrink1.pic"
ShrinkPic2::   INCBIN "pic/trainer/shrink2.pic"

Well, let's just add a new line really quick to include our new front sprite for the girl, so we can reference it later. You should have something that looks like this:

RedPicFront::  INCBIN "pic/trainer/red.pic"
LeafPicFront:: INCBIN "pic/trainer/leaf.pic"
ShrinkPic1::   INCBIN "pic/trainer/shrink1.pic"
ShrinkPic2::   INCBIN "pic/trainer/shrink2.pic"

Now if you scroll down a little from that, you should see the lines that include the overworld sprites. So we will just go to the line that says:

RedCyclingSprite:     INCBIN "gfx/sprites/cycling.2bpp"
RedSprite:            INCBIN "gfx/sprites/red.2bpp"

and add a couple of lines under it, so it looks like this:

RedCyclingSprite:     INCBIN "gfx/sprites/cycling.2bpp"
RedSprite:            INCBIN "gfx/sprites/red.2bpp"
LeafSprite:           INCBIN "gfx/sprites/leaf.2bpp"
LeafCyclingSprite:    INCBIN "gfx/sprites/leafcycling.2bpp"

Now, at least in my case, adding thew overworlds to this bank caused errors at compile, because we were trying to add too many sprites in this bank. To make life simpler later, we can just take 2 unrelated sprites and move them to another bank. I decided to cut and paste the lines that said:

GiovanniSprite:       INCBIN "gfx/sprites/giovanni.2bpp"
RocketSprite:         INCBIN "gfx/sprites/rocket.2bpp"

to the top of the other bank of overworld sprites. You can find that other bank by searching "SECTION "NPC Sprites 1"" or by scrolling up a bit from the banks we were just editing.

Now, the next thing we should come to is the fishing tiles. We won't have room to include these in the same bank as Red's fishing tiles, so we will have to find another bank to include them in. Which bank they are in is not important, since the routine that calls them can find them in any bank. So I added them in the same bank as the player backsprites.

So to finish inserting the graphics, do a search in main.asm for RedPicBack. You will eventually find something that looks like this:

RedPicBack::  INCBIN "pic/trainer/redb.pic"
OldManPic::  INCBIN "pic/trainer/oldman.pic"

So I just went ahead and added some lines to make it look like this:

RedPicBack::  INCBIN "pic/trainer/redb.pic"
LeafPicBack::  INCBIN "pic/trainer/leafb.pic"
OldManPic::  INCBIN "pic/trainer/oldman.pic"
LeafFishingTilesFront: INCBIN "gfx/leaf_fishing_tile_front.2bpp"
LeafFishingTilesBack:  INCBIN "gfx/leaf_fishing_tile_back.2bpp"
LeafFishingTilesSide:  INCBIN "gfx/leaf_fishing_tile_side.2bpp"

Now that we have all of the entries for the graphics added, now is a good time to save main.asm and attempt to compile the rom. If all goes well, the rom will compile normally with these extra graphics included (but nothing will call them yet). If you get errors saying that a bank is full, you will have to move something around to make it compile properly. If this happens, the cygwin terminal will tell you which line in main.asm it had a problem with, so you can go right to it and know which bank you need to make room in.


Step 3: Setting up the into.

Ok, so you got everything sorted properly so your rom will compile with the new graphics? Ok, let's start making it so we can use them!

The first thing you will want to do is add the menu that asks if you are a boy or a girl. The way I did this is by making a copy of the YesNoChoice routine, and having it reference the unused "North/West" menu string.

So, let's open up engine/menu/text_box.asm and find the menu strings. So go ahead and search for TwoOptionMenuStrings and eventually you will come to:

TwoOptionMenuStrings:
    db 4,3,0
    dw .YesNoMenu
    db 6,3,0
    dw .NorthWestMenu
    db 6,3,0
    dw .SouthEastMenu
    db 6,3,0
    dw .YesNoMenu
    db 6,3,0
    dw .NorthEastMenu
    db 7,3,0
    dw .TradeCancelMenu
    db 7,4,1
    dw .HealCancelMenu
    db 4,3,0
    dw .NoYesMenu

.NoYesMenu
    db   "NO"
    next "[email protected]"
.YesNoMenu
    db   "YES"
    next "[email protected]"
.NorthWestMenu
    db   "NORTH"
    next "[email protected]"
.SouthEastMenu
    db   "SOUTH"
    next "[email protected]"
.NorthEastMenu
    db   "NORTH"
    next "[email protected]"
.TradeCancelMenu
    db   "TRADE"
    next "[email protected]"
.HealCancelMenu
    db   "HEAL"
    next "[email protected]"


The only entries we are interested in right now are the ones with NorthWest. So we'll just edit these really quick so we come up with this:

TwoOptionMenuStrings:
    db 4,3,0
    dw .YesNoMenu
    db 5,3,0
    dw .BoyGirlMenu
    db 6,3,0
    dw .SouthEastMenu
    db 6,3,0
    dw .YesNoMenu
    db 6,3,0
    dw .NorthEastMenu
    db 7,3,0
    dw .TradeCancelMenu
    db 7,4,1
    dw .HealCancelMenu
    db 4,3,0
    dw .NoYesMenu

.NoYesMenu
    db   "NO"
    next "[email protected]"
.YesNoMenu
    db   "YES"
    next "[email protected]"
.BoyGirlMenu
    db   "BOY"
    next "[email protected]"
.SouthEastMenu
    db   "SOUTH"
    next "[email protected]"
.NorthEastMenu
    db   "NORTH"
    next "[email protected]"
.TradeCancelMenu
    db   "TRADE"
    next "[email protected]"
.HealCancelMenu
    db   "HEAL"
    next "[email protected]"


Notice that I changed not only the text and label names, but I changed the numbers above the NorthWest choice. Those determine how large the box around the words will be, and by changing that value from 6 to 5, we make it so there isn't exta space after the Boy/Girl options.

Next, we'll need to declare a place to store the player's gender. That way when we add the code to call that menu choice, we have somewhere to save the result. So let's open up wram.asm and declare a new address!

If you search for wGameProgressFlagsEnd you'll find this:
wGameProgressFlagsEnd::

    ds 56


These bytes that come after those flags are unused, but are still within the block of WRAM that gets stored in the .sav file when you save the game. So here is a good place to declare the new address we'll be making use of in the rest of this tutorial. So, just change the code above to look like this:

wGameProgressFlagsEnd::

wPlayerGender::
; $00 = male
; $01 = female
    ds 1

; unused
    ds 55


Now that we have these edited, you can save that file and move on to the actual intro. If you look in /engine/oak_speech.asm you will see that this is the main code for the intro. Scroll down to the bottom, and paste this:

; displays boy/girl choice
BoyGirlChoice::
    call SaveScreenTilesToBuffer1
    call InitBoyGirlTextBoxParameters
    jr DisplayBoyGirlChoice
    
InitBoyGirlTextBoxParameters::
    ld a, $1 ; loads the value for the unused North/West choice, that was changed to say Boy/Girl
    ld [wTwoOptionMenuID], a
    coord hl, 13, 7 
    ld bc, $80e
    ret
    
DisplayBoyGirlChoice::
    ld a, $14
    ld [wTextBoxID], a
    call DisplayTextBoxID
    jp LoadScreenTilesFromBuffer1

This is a copy of the YesNoChoice routine, but modified to call our new Boy/Girl option instead.

Now that we have this subroutine added, we can scroll back up and write some new code to call it.

Near the top, you'll see a label called OakSpeech, and a few lines down, you'll see some code that looks like this:

xor a
    ld [hTilesetType],a
    ld a,[wd732]
    bit 1,a ; possibly a debug mode bit
    jp nz,.skipChoosingNames


Immediately under that, we'll add our new code for the gender selection. So immediately after the line about skipping the intro, we'll add this:

ld hl,BoyGirlText  ; added to the same file as the other oak text
    call PrintText     ; show this text
    call BoyGirlChoice ; added routine at the end of this file
    ld a, [wCurrentMenuItem]
    ld [wPlayerGender], a ; store player's gender. 00 for boy, 01 for girl
    call ClearScreen ; clear the screen before resuming normal intro


Now if you scroll down a bit you will find something that looks like this:

ld hl,OakSpeechText2
    call PrintText
    call GBFadeOutToWhite
    call ClearScreen
    ld de,RedPicFront
    ld bc,(Bank(RedPicFront) << 8) | $00
    call IntroDisplayPicCenteredOrUpperRight

So we'll need to change this up a bit, so it can show the other pic if you are a girl. Make it look like this:

ld hl,OakSpeechText2
    call PrintText
    call GBFadeOutToWhite
    call ClearScreen
    ld de,RedPicFront
    lb bc, Bank(RedPicFront), $00
    ld a, [wPlayerGender] ; check gender
    and a      ; check gender
    jr z, .NotLeaf1
    ld de,LeafPicFront
    lb bc, Bank(LeafPicFront), $00
.NotLeaf1:
    call IntroDisplayPicCenteredOrUpperRight

Next, we can scroll down a bit more until we see:

.skipChoosingNames
    call GBFadeOutToWhite
    call ClearScreen
    ld de,RedPicFront
    lb bc, Bank(RedPicFront), $00
    call IntroDisplayPicCenteredOrUpperRight

So we'll just change it to say:

.skipChoosingNames
    call GBFadeOutToWhite
    call ClearScreen
    ld de,RedPicFront
    lb bc, Bank(RedPicFront), $00
    ld a, [wPlayerGender] ; check gender
    and a      ; check gender
    jr z, .NotLeaf2
    ld de,LeafPicFront
    lb bc, Bank(LeafPicFront), $00
.NotLeaf2:
    call IntroDisplayPicCenteredOrUpperRight


You can see where this is going, really. A lot of checking the gender and just making it load the girl's stuff instead, otherwise keep loading the boy's stuff. We're still not done with this file yet though. So scroll down a bit more until you see:

call DelayFrames
    ld de,RedSprite
    ld bc,(BANK(RedSprite) << 8) | $0C
    ld hl,vSprites
    call CopyVideoData
    ld de,ShrinkPic1
    ld bc,(BANK(ShrinkPic1) << 8) | $00
    call IntroDisplayPicCenteredOrUpperRight

and make it look like this:

call DelayFrames
    ld de,RedSprite
    lb bc, BANK(RedSprite), $0C
    ld a, [wPlayerGender] ; check gender
    and a      ; check gender
    jr z, .NotLeaf3
    ld de,LeafSprite
    lb bc, BANK(LeafSprite), $0C
.NotLeaf3:
    ld hl,vSprites
    call CopyVideoData
    ld de,ShrinkPic1
    lb bc, BANK(ShrinkPic1), $00
    call IntroDisplayPicCenteredOrUpperRight

Now, we'll scroll down a bit more until we see:

OakSpeechText3:
    TX_FAR _OakSpeechText3
    db "@"

Since we added a text string earlier when asking your gender, we'll need to set this up here so the script can find it. So we'll add:

BoyGirlText: ; This is new so we had to add a reference to get it to compile
    TX_FAR _BoyGirlText
    db "@"

under the OakSpeechText3 part. That's all we have to do in this file, but we're not quite done with the intro. (The intro is probably the most complicated part in all honesty).

Now we'll go ahead and save that file, and open /engine/oak_speech2.asm to keep working. At the top you will see:

ChoosePlayerName:
    call OakSpeechSlidePicRight
    ld de, DefaultNamesPlayer
    call DisplayIntroNameTextBox
    ld a, [wCurrentMenuItem]
    and a
    jr z, .customName
    ld hl, DefaultNamesPlayerList
    call GetDefaultName
    ld de, wPlayerName
    call OakSpeechSlidePicLeft
    jr .done

and change that to this:

ChoosePlayerName:
    call OakSpeechSlidePicRight
    ld a, [wPlayerGender] ; Added gender check
    and a
    jr nz, .AreGirl ; Skip to girl names if you are a girl instead
    ld de, DefaultNamesPlayer
    call DisplayIntroNameTextBox
    ld a, [wCurrentMenuItem]
    and a
    jr z, .customName
    ld hl, DefaultNamesPlayerList
    call GetDefaultName
    ld de, wPlayerName
    call OakSpeechSlidePicLeft
    jr .done
.AreGirl ; Copy of the boy naming routine, just with girl's names
    ld de, DefaultNamesGirl
    call DisplayIntroNameTextBox
    ld a, [wCurrentMenuItem]
    and a
    jr z, .customName
    ld hl, DefaultNamesGirlList
    call GetDefaultName
    ld de, wPlayerName
    call OakSpeechSlidePicLeft
    jr .done ; End of new Girl Names routine

This adds a copy of the name routine that will instead call the girl's default names, which we will add in a minute. But first, we still have a little more to do.

If you will look at where it says:

.customName
    ld hl, wPlayerName
    xor a ; NAME_PLAYER_SCREEN
    ld [wNamingScreenType], a
    call DisplayNamingScreen
    ld a, [wcf4b]
    cp "@"
    jr z, .customName
    call ClearScreen
    call Delay3
    ld de, RedPicFront
    ld b, BANK(RedPicFront)
    call IntroDisplayPicCenteredOrUpperRight
.done
    ld hl, YourNameIsText
    jp PrintText

we'll need to change this, so that entering a custom name won't make you look like the boy when you get back to the intro. So we'll make the code look like this:

.customName
    ld hl, wPlayerName
    xor a ; NAME_PLAYER_SCREEN
    ld [wNamingScreenType], a
    call DisplayNamingScreen
    ld a, [wcf4b]
    cp "@"
    jr z, .customName
    call ClearScreen
    call Delay3
    ld de, RedPicFront
    ld b, BANK(RedPicFront)
    ld a, [wPlayerGender] ; Added gender check
    and a      ; Added gender check
    jr z, .AreBoy3
    ld de, LeafPicFront
    ld b, BANK(LeafPicFront)
.AreBoy3
    call IntroDisplayPicCenteredOrUpperRight
.done
    ld hl, YourNameIsText
    jp PrintText

Now then, we can get around to adding the name list for the girl player. So scroll down until you see:

IF _RED
DefaultNamesPlayer:
    db   "NEW NAME"
    next "RED"
    next "ASH"
    next "JACK"
    db   "@"

DefaultNamesRival:
    db   "NEW NAME"
    next "BLUE"
    next "GARY"
    next "JOHN"
    db   "@"
ENDC

and add a new entry for your girl names. It will look something like this:

IF _RED
DefaultNamesPlayer:
    db   "NEW NAME"
    next "RED"
    next "ASH"
    next "JACK"
    db   "@"
    
DefaultNamesGirl:
    db   "NEW NAME"
    next "SCARLET"
    next "LEAF"
    next "NICOLE"
    db   "@"

DefaultNamesRival:
    db   "NEW NAME"
    next "BLUE"
    next "GARY"
    next "JOHN"
    db   "@"
ENDC

Obviously, you don't have to use the same names I came up with. Just make sure they aren't too long for a player name and you are fine.

So that sounds like we are done with the intro, right? Not quite. We only added the entries for the name menu. We still need to enter the actual list it will reference, because Red Version was weird. So we'll scroll down a little more until we find:

IF DEF(_RED)
DefaultNamesPlayerList:
    db "NEW [email protected]"
    db "[email protected]"
    db "[email protected]"
    db "[email protected]"
DefaultNamesRivalList:
    db "NEW [email protected]"
    db "[email protected]"
    db "[email protected]"
    db "[email protected]"
ENDC

and add the girl list in there. It should look like this:

IF DEF(_RED)
DefaultNamesPlayerList:
    db "NEW [email protected]"
    db "[email protected]"
    db "[email protected]"
    db "[email protected]"
DefaultNamesGirlList:
    db "NEW [email protected]"
    db "[email protected]"
    db "[email protected]"
    db "[email protected]"
DefaultNamesRivalList:
    db "NEW [email protected]"
    db "[email protected]"
    db "[email protected]"
    db "[email protected]"
ENDC

You also need to add those entries for the girl's name lists to the IF_BLUE lists as well, if you plan on compiling as a version other than Red. That is it for the actual ASM on the intro, but we still need to open another file to finish the intro up. Remember that text string we made up to reference earlier in the gender select menu? Yeah, we have to actually put that string into the game.

So let's save that file and open up /text/oakspeech.asm and scroll down to the bottom of the file. There we can add an entry that looks like this:

_BoyGirlText::
    text "Play as a boy, or"
    line "as a girl?"
    done

Then just save it and you're done with the intro. At this point, I would recommend compiling it again and testing the intro, just to make sure everything worked the way you wanted it to..

Step 4: Setting up the player's overworld sprites.

Ok, so you got the intro working nicely? Great! Time to move on to getting the game to show the proper sprites when you are fishing as the girl.

So let's go ahead and open up /engine/overworld/player_animations.asm and have a look. You'll want to search for FishingAnim: to find what you are looking for. It will look like this:

FishingAnim:
    ld c, 10
    call DelayFrames
    ld hl, wd736
    set 6, [hl] ; reserve the last 4 OAM entries
    ld de, RedSprite
    ld hl, vNPCSprites
    lb bc, BANK(RedSprite), $c
    call CopyVideoData
    ld a, $4
    ld hl, RedFishingTiles
    call LoadAnimSpriteGfx

You'll want to replace that with this:

FishingAnim:
    ld c, 10
    call DelayFrames
    ld hl, wd736
    set 6, [hl] ; reserve the last 4 OAM entries
    ld a, [wPlayerGender] ; added gender check
    and a      ; added gender check
    jr z, .BoySpriteLoad
    ld de, LeafSprite
    ld hl, vNPCSprites
    ld bc, (BANK(LeafSprite) << 8) + $0c
    jr .KeepLoadingSpriteStuff
.BoySpriteLoad
    ld de, RedSprite
    ld hl, vNPCSprites
    lb bc, BANK(RedSprite), $c
.KeepLoadingSpriteStuff
    call CopyVideoData
    ld a, [wPlayerGender] ; added gender check
    and a      ; added gender check
    jr z, .BoyTiles ; skip loading Leaf's stuff if you're Red
    ld a, $4
    ld hl, LeafFishingTiles
    jr .ContinueRoutine ; go back to main routine after loading Leaf's stuff
.BoyTiles ; alternately, load Red's stuff
    ld a, $4
    ld hl, RedFishingTiles
.ContinueRoutine
    call LoadAnimSpriteGfx

Now I know, I know. That looks like a mess. But it's really just more of the same stuff we did in the intro. All we've done is copy part of it to make an alternate version it can load to get the girl's sprite and fishing tiles. Speaking of those fishing tiles, we'll need to add that little table it is referencing.

So let's scroll down a bit until we see:

RedFishingTiles:
    dw RedFishingTilesFront
    db 2, BANK(RedFishingTilesFront)
    dw vNPCSprites + $20

    dw RedFishingTilesBack
    db 2, BANK(RedFishingTilesBack)
    dw vNPCSprites + $60

    dw RedFishingTilesSide
    db 2, BANK(RedFishingTilesSide)
    dw vNPCSprites + $a0

    dw RedFishingRodTiles
    db 3, BANK(RedFishingRodTiles)
    dw vNPCSprites2 + $7d0

We'll want to add a new table under it, so that it will look like this:

RedFishingTiles:
    dw RedFishingTilesFront
    db 2, BANK(RedFishingTilesFront)
    dw vNPCSprites + $20

    dw RedFishingTilesBack
    db 2, BANK(RedFishingTilesBack)
    dw vNPCSprites + $60

    dw RedFishingTilesSide
    db 2, BANK(RedFishingTilesSide)
    dw vNPCSprites + $a0

    dw RedFishingRodTiles
    db 3, BANK(RedFishingRodTiles)
    dw vNPCSprites2 + $7d0
    
LeafFishingTiles: ; newly added table of Leaf's sprites
    dw LeafFishingTilesFront
    db 2, BANK(LeafFishingTilesFront)
    dw vNPCSprites + $20

    dw LeafFishingTilesBack
    db 2, BANK(LeafFishingTilesBack)
    dw vNPCSprites + $60

    dw LeafFishingTilesSide
    db 2, BANK(LeafFishingTilesSide)
    dw vNPCSprites + $a0

    dw RedFishingRodTiles
    db 3, BANK(RedFishingRodTiles)
    dw vNPCSprites2 + $7d0

You'll notice that leaf's table still calls one of the original graphics that Red used. I don't see a point in making an identical copy of the actual fishing pole tiles, only the part that is the actual player, so her table calls the same fishing rod sprite the boy did.

Now to move on to your walking and cycling sprites. You'll open /home/overworld.asm and take a look at it for this part. You'll want to find the routine called LoadWalkingPlayerSpriteGraphics for this part. You'll eventually find a routine that looks like this:

LoadWalkingPlayerSpriteGraphics::
    ld de,RedSprite
    ld hl,vNPCSprites
    jr LoadPlayerSpriteGraphicsCommon

LoadSurfingPlayerSpriteGraphics::
    ld de,SeelSprite
    ld hl,vNPCSprites
    jr LoadPlayerSpriteGraphicsCommon

LoadBikePlayerSpriteGraphics::
    ld de,RedCyclingSprite
    ld hl,vNPCSprites

And we'll just change this up a little to look like this:

LoadWalkingPlayerSpriteGraphics::
    ld de,RedSprite
    ld a, [wPlayerGender]
    and a
    jr z, .AreGuy1
    ld de,LeafSprite
.AreGuy1
    ld hl,vNPCSprites
    jr LoadPlayerSpriteGraphicsCommon

LoadSurfingPlayerSpriteGraphics::
    ld de,SurfingLapras
    ld hl,vNPCSprites
    jr LoadPlayerSpriteGraphicsCommon

LoadBikePlayerSpriteGraphics::
    ld de,RedCyclingSprite
    ld a, [wPlayerGender]
    and a
    jr z, .AreGuy2
    ld de,LeafCyclingSprite
.AreGuy2
    ld hl,vNPCSprites

Now you can save this file, because that is all we had to do in here. If you were to scroll down a little more, you would see that we didn't mess with the part of the code that loaded which bank these sprites were in. That is why we kept Red and Leaf in the same bank when we inserted their sprites. It just seemed simpler to do it that way to me. As with all of the other sections, you'll probably want to stop and compile the rom again to make sure everything went ok before moving on.

Step 5: Adding The Girl's Backsprite.

This section will be relatively short compared to the others, because there isn't much to do here. We'll open up engine/battle/core.asm for this part.

Search until you find LoadPlayerBackPic: and see that it looks like this:

LoadPlayerBackPic:
    ld a, [wBattleType]
    dec a ; is it the old man tutorial?
    ld de, RedPicBack
    jr nz, .next
    ld de, OldManPic
.next


You'll just want to change this to be:

LoadPlayerBackPic:
    ld a, [wBattleType]
    dec a
    ld de, OldManPic
    jr z, .next
    ld a, [wPlayerGender]
    and a
    jr z, .RedBack
    ld de, LeafPicBack
    jr .next
.RedBack
    ld de, RedPicBack
.next

This just reorganises that a bit and adds in the check for the girl's backsprite. This also assumes that all 3 backpics are stored in the same bank, so make sure you did that unless you want to mess with the routine more on your own to allow them to be in different banks.

As always, you'll probably want to save and compile to test this before going on.

Step 6: Adding The Girl To The Hall Of Fame.

For this step, you'll want to open /engine/hall_of_fame.asm and search for HoFLoadPlayerPics: to get to the function we need. It should look something like this:

HoFLoadPlayerPics:
    ld de, RedPicFront
    ld a, BANK(RedPicFront)
    call UncompressSpriteFromDE
    ld hl, sSpriteBuffer1
    ld de, sSpriteBuffer0
    ld bc, $310
    call CopyData
    ld de, vFrontPic
    call InterlaceMergeSpriteBuffers
    ld de, RedPicBack
    ld a, BANK(RedPicBack)
    call UncompressSpriteFromDE

We'll want to edit that so it looks like this:

HoFLoadPlayerPics:
    ld a, [wPlayerGender] ; New gender check
    and a      ; New gender check
    jr nz, .GirlStuff1
    ld de, RedPicFront
    ld a, BANK(RedPicFront)
    jr .Routine ; skip the girl stuff and go to main routine
.GirlStuff1
    ld de, LeafPicFront
    ld a, BANK(LeafPicFront)
.Routine ; resume original routine
    call UncompressSpriteFromDE
    ld hl, sSpriteBuffer1
    ld de, sSpriteBuffer0
    ld bc, $310
    call CopyData
    ld de, vFrontPic
    call InterlaceMergeSpriteBuffers
    ld a, [wPlayerGender] ; new gender check
    and a      ; new gender check
    jr nz, .GirlStuff2
    ld de, RedPicBack
    ld a, BANK(RedPicBack)
    jr .routine2 ; skip the girl stuff and continue original routine if guy
.GirlStuff2
    ld de, LeafPicBack
    ld a, BANK(LeafPicBack)
.routine2 ; original routine
    call UncompressSpriteFromDE

This will change it so it shows the girl's front and back sprites when your team is entered in the hall of fame. Save it and you are done with this step.

Step 7: Adding The Girl To The Trainer Card

This is the final step in the tutorial. You'll want to open up /engine/menu/start_sub_menus.asm for this part. Search for the function DrawTrainerInfo: and you should see something like this:

DrawTrainerInfo:
    ld de,RedPicFront
    lb bc, BANK(RedPicFront), $01
    predef DisplayPicCenteredOrUpperRight

So we'll just change that to:

DrawTrainerInfo:
    ld de,RedPicFront
    lb bc, BANK(RedPicFront), $01
    ld a, [wPlayerGender]
    and a
    jr z, .AreBoy
    ld de, LeafPicFront
    lb bc, BANK(LeafPicFront), $01
.AreBoy
    predef DisplayPicCenteredOrUpperRight

And you should be all set! Save it, compile it, and give it a test. If everything went as planned (and assuming I didn't accidentally leave anything out when writing this) you should now have a fully functioning gender selection system in place in Pokemon Red. Let me know if you have any problems and I will try my best to help you figure them out.

Credits:
IIMarckus, Kanzure, comet, Danny-E33, Sanky, and everyone else who contributed to the Pokered disassembly project.
Danny-E33 - Getting me interested in Pokered, and for the Gen II backsprite routine I used in that video
Pia Carrot - Talking about Pokered a lot at PHO and originally asking me to write this tutorial.
ないすべての情報が必要です。- Asking about this on Discord until I updated it.