• Our software update is now concluded. You will need to reset your password to log in. In order to do this, you will have to click "Log in" in the top right corner and then "Forgot your password?".
  • Welcome to PokéCommunity! Register now and join one of the best fan communities on the 'net to talk Pokémon and more! We are not affiliated with The Pokémon Company or Nintendo.

Development: Fun with the naming function

Touched

Resident ASMAGICIAN
625
Posts
9
Years
  • Age 122
  • Seen Feb 1, 2018
I don't think the title was all that clear, but it was the best I could come up with. In case you're wondering what I meant, I mean this:

29vjix0.png


This function allows you to enter some text for a predefined purpose, and then add a callback to handle the result.

It is reused quite a bit around the game for the following purposes:

  • Naming the player in the intro
  • Naming the rival
  • Nicknaming Pokemon
  • (Re)Naming a PC Box

I seem to recall there being a few other types in RSE (That secret code person in Rustboro). However, these don't seem to be present in FireRed - but there are empty slots.

Basically the function would have a C signature resembling the following:

Code:
void name_screen(uint8_t type, uint32_t *dest, uint16_t image, uint16_t arg1, uint32_t *callback, uint32_t arg2);

The first parameter is the most interesting, in my opinion. It holds a value that is evaluated by a switch statement that tells the rest of the function what text to render, what picture to display, etc. The table for the functions that handle each case is at 0809DA04, and is pointed to at 0809DA00 (so you should be able to repoint it, if you so desire). Basically the switch currently has 7 cases, and a default handler. Here is what they do (in fire red):

Code:
0 Name the player
1 Name a PC box
2 Nickname Pokemon
3 Same as 2, apparently
4 Name the rival

If you try anything beyond 4, you'll crash the game, so these appear to be empty slots. However, after 7, the default handler kicks in and you'll be jumped to 0809D9F8. This seems to just call the callback immediately, though I didn't research it much. The compare opcode for this switch is at 0809D9EC:

Code:
ROM:0809D9EC                 CMP     R0, #7
ROM:0809D9EE                 BHI     def_809D9F8     @ default case

So if you expand that table, you'll need to change the byte at 0809D9EC to the new size.

The second argument is a pointer to the block of memory where the result will be stored.

The third argument, the image just controls what image is displayed (The player in the image above). If you choose 0 for the type, 0 will show the male player, 1 will show the female player, and other numbers will choose other player animations (fishing, pokeball, surfing, etc.). These animations freeze, however. For the nickname Pokemon, this number is the species. For anything else, it appears to do nothing.

The fourth parameter is usually zero, and I haven't found out what it does yet.

The callback is a pointer to the function that will be called after the naming is done. I just use 080568E0 if I call it from a script, this is a function that returns to the OW and resumes script execution. If you want to do extra stuff, just create your own callback and branch to that function afterwards.

The last argument seems to be another controlling parameter. In the nickname function, it appears to be set to some (decrypted) information from the Pokemon data structure, which will apparently control the gender symbol (and maybe other things)?

Now that I've got the description out of the way, lets look at an example routine:

Code:
.thumb
.align 2

main:
	push {r0-r4, lr}

	ldr r0, .RETURN
	
	@ Push any two registers to the stack so we can safely modify it
	push {r4-r5}
	@ We're going to add two values
	sub sp, #0x8

	@ Add the argument to stack. This is usually zero
	@ It holds Pokemon attributes for the nickname function
	mov r0, #0x0
	str r0, [sp, #0x0]

	@ Load the callback onto the stack. The resume function
	@ Returns to the overworld and continues script execution
	ldr r0, .RESUME
	str r0, [sp, #0x4]

	@ Load the other parameters
	ldr r4, .NAMECHOOSE

	@ Name screen type. Used in switch statement
	mov r0, #0x0

	@ Argument for name screen. Used to change picture next to name
	mov r2, #0x0

	@ Another argument. Unknown
	mov r3, #0x0

	@ A pointer to where the result should be stored
	ldr r1, .PLAYERDATA
	ldr r1, [r1]

	@ Call the naming function
	bl call_via_r4

	@ Restore the stack to it's former state
	add sp, #0x8
	pop {r4-r5}

	pop {r0-r4, pc}

call_via_r4:
	bx r4
	pop {pc}
	
.align 2
.NAMECHOOSE: .word 0x0809D954 + 1
.RESUME: .word 0x080568E0 + 1
.PLAYERDATA: .word 0x0300500C
.RETURN: .word 0x08130C64 +1

I'm not quite sure about the calling convention for ARM, but it appears that registers r0-r3 are used, any remaining arguments are pushed in normal order to the stack (as opposed to the reverse order of cdecl). If anyone has more information on this, please let me know.

So that heavily commented piece of code will rename the player. I guess you could do more with it if you changed the destination parameter to be a script buffer or something. This routine works from a script, so you could potentially do something like you see in GSC, where you have to name your rival later in the game.

The next step would be to try and expand that table of pointers and/or replace the useless (?) slots with something more useful. Also, I'd like to look at the individual cases and see what is common between them (maybe they all call a similar rendering function or something) - that way it'd be easy to create our own name screen types.
 

Turtl3Skulll

Blue Turtl3
76
Posts
10
Years
Dang!! You came out of nowhere and just keep finding so many things :)
Tell me if I understood this correctly. This will allow you to change your name, mid-way into the game??

If so, could it also be possible to change the player name w/o them needing to input it in??
Like in a game where they have a set name, or in one where they play as multiple characters.
 

Kenny1

On a break from Rom hacking, to improve other skil
86
Posts
10
Years
  • Age 23
  • Seen Nov 6, 2017
This is rather interesting, and could be used for many different things.
Might try research this a bit, to see what comes out of that.
 

Touched

Resident ASMAGICIAN
625
Posts
9
Years
  • Age 122
  • Seen Feb 1, 2018
So, because I was remaking the Oak tutorial, I needed to research this some more. Basically, it appears that the "type" as the index to a table.

There is a table at 083E248C that holds an array of pointers to a struct. There does not appear to be a limiter, so repointing this is very easy: There is only one reference to this pointer anyway (at 0809DB58).

Basically, each struct is 12 bytes long and controls almost all the parameters for a new naming function.

Here is the code as C, so you can just copy and paste into any code you might have that uses this.
Code:
typedef struct namingInstance {
	u8 prefilled; /* Whether the box is automatically filled. Reads from the destination parameter of the function */
	u8 length; /* The maximum characters a user can enter */
	u8 image_function_index; /* What function to use */
	enum {
		NONE,
		MALE,
		FEMALE
	} gender : 8; /* What gender symbol is displayed */
	u8 screen; /* Always 1. Probably used to change the default text case panel. */
	u8 unk1;
	u8 unk2;
	u8 unk3;
	char *prompt; /* 0xFF terminated string */
} namingInstance;

Next, you'd have to repoint the image function table. This basically tells the function what to do when loading an image. It's always loaded with that little green circle underneath. There is a table at 083E2394 pointed to by 0809EF44 which controls each image. The function which is called is 083E2394 + image_function_index * 4. The first function in that table is a nop.

Another thing I'd need to research is that each "prompt" ("Your name?" for the name the player) is also controlled by a function table (at 083E240C). This appears to load the Pokemon name for the nickname verison, allowing a dynamic string. I haven't yet figured out how this function is selected, yet.
 
Last edited:

Sierraffinity

Desperately trying to retire from ROM hacking
1,069
Posts
16
Years
There's a table located at 3E264C in FireRed and 58C198 in Emerald. Each entry in the table points to the string for each row in the text selection menu.The first four are for lowercase, the next four for uppercase, and the last four for others. Each entry in the string, like A or B, is preceded by FC11XX. That XX is the amount of pixels from the last letter the next one is spaced. It's a very odd system, but what can you do.
 
Last edited:
Back
Top