The PokéCommunity Forums  

Go Back   The PokéCommunity Forums > Fan Games > Binary ROM Hacking
Reload this Page Script [Resolved] What is the offset location of the Rival's name? Trying to nickname a Pokémon after the Rival.

Notices
For all updates, view the main page.

Binary ROM Hacking Need a helping hand or just want to talk about binary ROM hacks? Get comments and answers to any ROM Hacking-related problems, questions or thoughts you have here.

Ad Content
Reply
 
Thread Tools
  #1   Link to this post, but load the entire thread.  
Old November 21st, 2019 (3:24 PM). Edited November 26th, 2019 by Dr. POP.
Dr. POP's Avatar
Dr. POP Dr. POP is offline
 
Join Date: Sep 2009
Location: Mt. Silver
Gender: Male
Posts: 119
So I have tried the best I could to figure this out by myself, but unfortunately to no avail. What started as a relatively simple XSE script has made me delve into the depths of RAM memory - which I, admittedly, do not fully understand. Help would be highly appreciated!

In short, I want the player to receive a Pokémon, which carries the (nick)name the player gave to the Rival in the introduction. (I won't go into detail exactly why, but let's just say the Rival naming sequence becomes the starter nicknaming sequence.) As I do not master ASM yet, I would like to try to do this fully in XSE. This post shows how to rename an obtained Pokémon to the Player's name through a simple XSE script. It does so by copying the bytes of the Pokémon's OT to the Pokémon's nickname.
Spoiler:
Quote:
Originally Posted by DrFuji View Post
Changing a Pokemon's nickname to the player's name is pretty simple to do through copying bytes in the the game's memory and easily be done in XSE. Here's a script that will give the player two Bulbasaurs and change the first one's name to the player's name:

Code:
#dynamic 0x800000

#org @start
setflag 0x828
givepokemon 0x1 0x1 0x0 0x0 0x0 0x0
givepokemon 0x1 0x1 0x0 0x0 0x0 0x0
copybyte 0x0202428C 0x02024298
copybyte 0x0202428D 0x02024299
copybyte 0x0202428E 0x0202429A
copybyte 0x0202428F 0x0202429B
copybyte 0x02024290 0x0202429C
copybyte 0x02024291 0x0202429D
copybyte 0x02024292 0x0202429E
writebytetooffset 0xFF 0x02024293
writebytetooffset 0xFF 0x02024294
writebytetooffset 0xFF 0x02024295
end
In this script I'm copying the original trainer name from the Pokemon's data and overwriting the nickname data. As the trainer name can only be a maximum of seven letters we then need to pad the last three letters with 0xFF just in case the Pokemon's name is longer that that. If the Pokemon was traded it will have the trader's trainer name but it should be fine in 99% of cases. If the Pokemon you're trying to assign the name to isn't the first one in your party you will have to add 0x64 to each of the pointers for each Pokemon until you reach the party member you want to nickname. You could also give a Pokemon a static name just by using the writebytetooffset command if you wanted a Pokemon to have a specific name that wasn't the trainer's.

This script is designed for FireRed but it can be ported over to Emerald like this though I haven't tested it:
Code:
copybyte 0x020244F4 0x02024500
copybyte 0x020244F5 0x02024501
copybyte 0x020244F6 0x02024502
copybyte 0x020244F7 0x02024503
copybyte 0x020244F8 0x02024504
copybyte 0x020244F9 0x02024505
copybyte 0x020244FA 0x02024506
writebytetooffset 0xFF 0x020244FB
writebytetooffset 0xFF 0x020244FC
writebytetooffset 0xFF 0x020244FD
Hopefully that's what you're after!

This seems to work fine. I would like to do the same, but instead of the Player's (OT's) name, it would copy the Rival's name. I thought I could achieve this by finding the location of the Rival's name and replacing the offsets referring to the OT (in bold in the spoiler above) in the script with the offsets of the Rival's name. However, it does not seem to be that easy. I don't know which offsets to copy the bytes from.

This post contains a list/map of the RAM offsets, including the Rival's name. It explains that it is stored in the so-called Dynamic Memory Allocation (DMA) and that the actual offsets change all the time. An excerpt of the post is included below. A simple addition of 0x03005008 + 0x000039D4 = 0x030089DC is not succesful because the actual DMA pointers change while the game is running.
Spoiler:
Quote:
MA - Dynamic Memory Allocation

Very important are the DMA save pointers at:

Code:
0x03005008 saveblock1_mapdata                                                               
0x0300500C saveblock2_trainerdata                                                           
0x03005010 saveblock3_boxdata
Here's the DMA structures. The memory positions are relative to the memory addresses that are saved at those DMA save pointer locations above. The DMA pointers change while the game is running, often when leaving buildings or exiting certain menus.

Sav1

Code:
...
0x000039D4 rivals_name:    .byte 8 dup(?)
...
...

But perhaps there is a much easier solution. In this post, the user has a similar question but suggests it can be bypassed using "copyvar to 0x8005 or something" in XSE. But for this I still need to know the location of the variable containing the Rival's name...
Spoiler:
Quote:
I have ASM code that needs to access a certain variable in the DMA, namely 0x4011, but as you probably know the actual location of this variable in the RAM changes all the time. I could (probably) get around this by using copyvar to 0x8005 or something before callasm-ing (as XSE script is evidently able to bypass this BS), but as this might not be an option in the future I wanted to know how seasoned ASM coders got around this, and the location of the IWRAM DMA cache (which contains pointers to each variable protected by DMA).

I am pretty confused at this point. Is there an accessible point where the Rival's name is stored, which can be identified and copied? Given the frequency with which the name is invoked throughout the game, and with [rival] in message boxes, I would be surprised if this wasn't somehow possible. Many thanks in advance, and apologies if I missed something obvious!

---

PS: Other posts I used and thought could be relevant, but didn't want to go through in this post:

Bulbapedia information about the save data structure . It mentions the following:
Spoiler:
Code:
RSE		FRLG	 
Offset	Size	Offset	Size	Contents
N/A		0x0BCC	8	Rival name

This post by FBI which mentions the Rival's name is located in the EWRAM, which has offsets ranging from 0x02000000 to 0x0203FFFF.
Spoiler:
First of all, you'll notice that there are two sections of WRAM, which have been labeled. One is 32KB and the other is 256 KB. The 256KB of EWRAM is what's available for your game to use for its RAM data. For example: the save structures, player name, rival name, NPC states, malloc calls ect are all placed in this 256 KB RAM slot we call EWRAM.

This post contains an ASM script on renaming the Rival in the overworld. I can't read ASM, but it doesn't seem like any of the mentioned offsets can be used in the script. I have tried it with 0x03005008 which was unsuccesful.
Spoiler:
...
Code:
...
place: .word 0x080568E1
ramlocation: .word 0x03005008
standard: .word 0x00003A4C
actualroutine: .word 0x0809D955
rivalname: .word 0x08FFFFFF


Edit: This question is resolved, with thanks to DrFuji below.
Reply With Quote
  #2   Link to this post, but load the entire thread.  
Old November 21st, 2019 (5:11 PM). Edited November 21st, 2019 by DrFuji.
DrFuji's Avatar
DrFuji DrFuji is offline
Heiki Hecchara‌‌
 
Join Date: Sep 2009
Location: Aussie
Age: 30
Gender: Male
Nature: Jolly
Posts: 1,693
Since the rival's name is at a DMA address, there's a few ways you can go about getting it. Firstly, you could use ASM to get it, but since you want to use a script, that's out. Secondly, you could use eval to dynamically load the DMA pointer and manipulate it to extract your needed bytes, but that's overly complicated and would take a long time to explain. The third and best way to get the rival's name is to have it be moved to another point in the RAM that isn't dynamic.

A good way to move the rival name's into a non-DMA part of the RAM is to have it occupy the displayed text as that will always start at 0x02021D18. You can use the command 'preparemsg' to load a prepared text string without actually having a msgbox appear on screen, ruining the immersion. Here's what a script based off the one you quoted earlier with this in mind:

Spoiler:
#dynamic 0x800000

#org @start
preparemsg @rival
copybyte 0x0202428C 0x02021D18
copybyte 0x0202428D 0x02021D19
copybyte 0x0202428E 0x02021D1A
copybyte 0x0202428F 0x02021D1B
copybyte 0x02024290 0x02021D1C
copybyte 0x02024291 0x02021D1D
copybyte 0x02024292 0x02021D1E
copybyte 0x02024293 0x02021D1F
end

#org @rival
= [rival]


This script will rename the first Pokemon in your party to your rival's name. One interesting thing about this is that your Pokemon will most likely have some random letters at the end of their name in the RAM that will never be loaded in-game as a 0xFF terminator will always be copied to it's nickname after the rival's name is finished. I hope this is what you're looking for.
__________________
Reply With Quote
  #3   Link to this post, but load the entire thread.  
Old November 25th, 2019 (2:53 PM). Edited November 26th, 2019 by Dr. POP.
Dr. POP's Avatar
Dr. POP Dr. POP is offline
 
Join Date: Sep 2009
Location: Mt. Silver
Gender: Male
Posts: 119
Quote:
Originally Posted by DrFuji View Post
Since the rival's name is at a DMA address, there's a few ways you can go about getting it. Firstly, you could use ASM to get it, but since you want to use a script, that's out. Secondly, you could use eval to dynamically load the DMA pointer and manipulate it to extract your needed bytes, but that's overly complicated and would take a long time to explain. The third and best way to get the rival's name is to have it be moved to another point in the RAM that isn't dynamic.

A good way to move the rival name's into a non-DMA part of the RAM is to have it occupy the displayed text as that will always start at 0x02021D18. You can use the command 'preparemsg' to load a prepared text string without actually having a msgbox appear on screen, ruining the immersion. Here's what a script based off the one you quoted earlier with this in mind:

Spoiler:
#dynamic 0x800000

#org @start
preparemsg @rival
copybyte 0x0202428C 0x02021D18
copybyte 0x0202428D 0x02021D19
copybyte 0x0202428E 0x02021D1A
copybyte 0x0202428F 0x02021D1B
copybyte 0x02024290 0x02021D1C
copybyte 0x02024291 0x02021D1D
copybyte 0x02024292 0x02021D1E
copybyte 0x02024293 0x02021D1F
end

#org @rival
= [rival]


This script will rename the first Pokemon in your party to your rival's name. One interesting thing about this is that your Pokemon will most likely have some random letters at the end of their name in the RAM that will never be loaded in-game as a 0xFF terminator will always be copied to it's nickname after the rival's name is finished. I hope this is what you're looking for.
This seems to be exactly what I'm looking for! Thanks alot, I did not know about the preparemsg command, but it makes a lot of sense. I will test it out tomorrow. :-)

Edit: I have tested DrFuji's script and it works exactly as intended. Thank you once again very much!
Reply With Quote
Reply

Quick Reply

Join the conversation!

Create an account to post a reply in this thread, participate in other discussions, and more!

Create a PokéCommunity Account
Ad Content
Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -8. The time now is 9:14 AM.