• 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.

Quick Research & Development Thread

Joexv

ManMadeOfGouda joexv.github.io
1,037
Posts
11
Years
I dont know if anyone would really need this, but if you want to skip part of the oak intro(where he sends out the Pokemon AND the text that goes with it)

put 79 FD 12 08 at 0x812f9E8
 
4
Posts
13
Years
  • Seen Jul 2, 2022
I've been digging into Forecast to try and figure out how to change the types of Castform's weather forms. More specifically, I want to make it possible to have a base form and weather forms that have one shared type with separate dual types. I have an okay amount of hex knowledge and exactly zero scripting knowledge, and I think I've gotten as far as that can take me. Here's what I've figured out so far:

Relevant offsets are, in FireRed (with their normal values in parentheses):
0x8019E70 (00)
0x8019E78 (00)
0x8019E9A (0A)
0x8019EA2 (0A)
0x8019EA6 (0A)
0x8019EC6 (0B)
0x8019ECE (0B)
0x8019ED2 (0B)
0x8019EF2 (0F)
0x8019EFA (0F)
0x8019EFE (0F)
There may be more.

To make sure we're on the same page, those values correspond to types. 00=Normal, 0A=Fire, 0B=Water, and 0F=Ice.

The first two are the primary and secondary types of Castform's base form. If Castform's primary type doesn't match the value at 0x8019E70 AND its secondary type doesn't match 0x8019E78, it will "change" from its Base form into its Base form as soon as it's sent in (in clear weather). If even one of the types matches, it won't do that.

The other sets of three values are of course related to the Sun, Rain, and Hail forms. Only thing is, I can't quite figure out what makes them work. I do know this much:
-If 0x8019E9A and 0x8019E70 are the same value, OR if 0x8019EA2 and 0x8019E78 are the same value, Castform is unable to change from its Base form to its Sun form at all. This leads me to believe that 0x8019E9A and 0x8019EA2 determine Sun's primary and secondary types, respectively. The same is true for changing between ANY two forms.
-Setting the first two values to XX and the third to YY (where XX and YY correspond to types) will cause Castform to transform into that weather form repeatedly forever, soft-locking the game:
XzzBei4.gif

-No matter what I've tried, I've been unable to get Castform's weather forms to be dual-typed. Which is a shame, since that's what I've been trying to do all this time.

http://www.pokecommunity.com/showpost.php?p=5716298&postcount=11
I basically figured this much out using only this post from years ago, where someone found the script for Forecast's form change. Figured it might help to include it here. Someone who knows enough about battle scripts might be able to find something in there that I didn't.

EDIT: I think I've figured out how the three values work. I say I think because I haven't figured out a way to prove it. But I have a good feeling about this because it makes everything else make sense.
My theory is that the first two values for each weather form are to check the type, and THAT'S IT. The third value is then the ONLY one that says what Castform's type changes to.
If this is the case, it seems very possible to, say, remove one of the type checks so that it only checks one of them, which in the process makes room to allow the weather form to set a dual type.
Time to figure out how to get that to work, then.

EDIT2: Okay yeah that's absolutely the case. Now I just need to figure out how to script this.
 
Last edited:

leyn09

Truant Trainer
84
Posts
12
Years


Nop, like 00 00

To clarify what GoGo said, basically type 8 00s (meaning, 16 0s) at that location. 00 actually corresponds to a THUMB instruction (pretty sure it's lsl r0,#0x0 or something like that) which shifts r0 zero bits to the left - practically nothing. You have to use this, as ARMv4 THUMB doesn't have a NOP instruction like 65816 ASM does (that's the ASM variant which the SNES uses).

Actually the defined nop instruction in Thumb is mov r8, r8. Many other instructions raise something called flags.

The instruction lsl, for example, raises the Zero flag, Carry flag and Sign flag. In the case of lsl r0, r0, #0x0, you won't set the carry flag but the other two can be set. This kind of practice could create unexpected results, so it's much better to use mov r8, r8 instead. That's the bytes "C0 46 C0 46".

Thanks for the clarifications!
 
794
Posts
10
Years
Castform Stuff

Castform switching is a bit complicated, but type changing shouldn't be that much of a problem.
The routine that's responsible for changing its type is located at: 080426BC in Emerald and at 08019DAC in Fire Red.
I think they're both the same, but I'll use emerald one as example.
Full routine:
Spoiler:


If you're wondering how I got that, it's from emerald IDA, a very useful tool. Anyway, there are three important labels there, chack hail, check sun and check rain. First, they check if Castform already has type related to the weather and if it does, they don't do anything. If it has a different type, it'll change them.
Take a look at that part from check_hail:
ROM:0804280E MOVS R0, #types_ice
ROM:08042810 STRB R0, [R2]
ROM:08042812 STRB R0, [R1]
#types_ice in reality is a value of 0x0F, it's just there to make code reading easier. STRB means that it stores this value at addresses in r2 and r1 which are responsible for pokemon types in battle. All you'd have to do is hook somewhere there and change the value of second type. If you know ASM, this shouldn't be that hard, if you don't however, I suggest you take a look at ASM tutorials.
 

Substitute Doll

An Alolan Exeggutor
115
Posts
8
Years

Here is more Castform stuff, the routines FOR FIRERED

This is Castform_Transform as named in IDA
Spoiler:


This is Castform_Switch as named in IDA
Spoiler:


Like Dizzy, I got these routines using IDA, and if anyone would like to add on, they can.
 

GoGoJJTech

(☞゚ヮ゚)☞ http://GoGoJJTech.com ☜(゚ヮ゚☜)
2,475
Posts
11
Years
In Emerald, there are three map names that are hidden on the hoenn map.
The three values at 0x085A1C34 are map names. 0xC8, 0xC9, and 0xD3.
0xC8 is "NAVEL ROCK"
0xC9 is "MT. EMBER"
0xD3 is "TANOBY CHAMBERS"
IDK if you can get to these locations in Emerald (or if you can even open the map in them via fly) but there you have that. I can be completely wrong here
 

GoGoJJTech

(☞゚ヮ゚)☞ http://GoGoJJTech.com ☜(゚ヮ゚☜)
2,475
Posts
11
Years
Navel Rock is where you can get Ho-oh and Lugia, Tanoby Chambers and Mt. Ember are only in Fire Red and I think are inaccessible.

Would there be a reason for these to be hidden on the Hoenn map? I don't see why it's necessary to have this list, even if it's a tiny one like this.
 

Joexv

ManMadeOfGouda joexv.github.io
1,037
Posts
11
Years
Not sure why im doing all this again, but oh well. May come in handy to someone.
Plus these are gonna be more of notes for me:
To remove the platform that Professor Oak/The hero sprites stand on in the intro place 0x00 at 0x812F832
To stop Oaks palette from loading NOP out 6 bytes at 0x813126C
(To restore it 24 48 60 21 40 22)
To remove Oak I cannot find a decent place to NOP out his call, so just blank him out with unlz

For anyone whos reading this and is wanting to mess with the intro. Doing these things is not the best way to do it. Write a custom one with C or ASM DO NOT mess with this one to a great extent unless you know what you are doing!


The bytes around 0x130203 seem to have an effect on what sprite is displayed.
For example I changed the 48 to 42 and it swapped the player to the VS.Seeker animation(I think I havent actually played FR to know this or not)

So I may get more documentation on it eventually but I dont have much as of now.
 
325
Posts
10
Years
So I watched all the battle animations that I could find.
Spoiler:
 
794
Posts
10
Years
Pokemon Emerald
cmd8a
Spoiler:


Berry data
Spoiler:


copyvarifnotzero
Spoiler:
 
Last edited:

Telinc1

Weirdo Extraordinaire
168
Posts
10
Years
About time I finally decide to actually find something on my own! Put 00 00 00 00 at 080F8121, 080F8168, 08056C96 and 080F82BE to completely skip looking for location previews. Useful for people who don't want them and don't want to wipe out the table. I've tested it pretty well and I haven't yet noticed any side effects from doing it. And just a warning, I haven't confirmed whether the table (it's at 0x0843E9E8 by the way) actually gets read or not, so I'd advise against using it as free space.
 

AkameTheBulbasaur

Akame Marukawa of Iyotono
409
Posts
10
Years
About time I finally decide to actually find something on my own! Put 00 00 00 00 at 080F8121, 080F8168, 08056C96 and 080F82BE to completely skip looking for location previews. Useful for people who don't want them and don't want to wipe out the table. I've tested it pretty well and I haven't yet noticed any side effects from doing it. And just a warning, I haven't confirmed whether the table (it's at 0x0843E9E8 by the way) actually gets read or not, so I'd advise against using it as free space.

Branching off of this post, the Location Preview table is structured with three pointers for each entry. (EDIT: The first four bytes are explained in the post below this.) The second pointer is to the image of the preview, the third is to a Tilemap for the image, and the last is to the image's palette.

Spoiler:


I haven't been able to successfully insert a new Location Preview, or change the maps that they appear on (if anybody has any info on that I'd love to know), but I'm sure it's probably possible.

Changing the pre-existing images on the pre-existing maps with Location Previews is as easy as copying the image, tilemap and palette pointers and replacing another entry on the list with them.
 
Last edited:
417
Posts
9
Years
  • Age 33
  • Seen Nov 20, 2016
Branching off of this post, the Location Preview table is structured with four pointers for each entry. I don't know what the first pointer is exactly (but I believe it has something to do with which map name the Location Preview appears in upon entering). The second pointer is to the image of the preview, the third is to a Tilemap for the image, and the last is to the image's palette.

Spoiler:


I haven't been able to successfully insert a new Location Preview, or change the maps that they appear on (if anybody has any info on that I'd love to know), but I'm sure it's probably possible.

Changing the pre-existing images on the pre-existing maps with Location Previews is as easy as copying the image, tilemap and palette pointers and replacing another entry on the list with them.
That's because the first four bytes are not a pointer.
Code:
0x0: map_name (byte)
0x1: map_transition (byte)
0x2: worldmap_flag (short)
0x4: img_ptr (long)
0x8: tile_ptr (long)
0xC: palettes_ptr (long)

Examples:
worldmap flag 0x8A5 = Viridian Forest
worldmap flag 0x8A9 = Mt. Moon
worldmap flag 0x8B0 = Rock Tunnel
 

Telinc1

Weirdo Extraordinaire
168
Posts
10
Years
That's because the first four bytes are not a pointer.
Code:
0x0: map_name (byte)
0x1: map_transition (byte)
0x2: worldmap_flag (short)
0x4: img_ptr (long)
0x8: tile_ptr (long)
0xC: palettes_ptr (long)
Examples:
worldmap flag 0x8A5 = Viridian Forest
worldmap flag 0x8A9 = Mt. Moon
worldmap flag 0x8B0 = Rock Tunnel
Some of this is documented here (that's where I got the table offset from). This is nice though, as that post doesn't really mention the purpose of the first couple of bytes that much (what does the game need the world map flag for, though?). Just so people don't have to go there to see, the map_transition is 0 for caves (screen fades to white and then transitions to black before fading out) and 1 for everything else (screen just fades to the map). Other values make the game ignore the picture (according to the post; I'll research that a bit, because I'm not sure how much the author of that post knew about the table's structure, so maybe other values do mean something else or can be hooked into).
 
794
Posts
10
Years
Pokemon Emerald
cmdc3 increments a counter specified in the argument(0 for the first counter ,1 for the second counter, etc.) by 1. There are 64 in-game encrypted counters, though only the first 51 can be accessed.

cmdb2 it's a nop

cmdb1 a buggy command that gets the value of first argument three times and doesn't return it in any way

cmd24 probably gotoasm
 
417
Posts
9
Years
  • Age 33
  • Seen Nov 20, 2016
Some of this is documented here (that's where I got the table offset from). This is nice though, as that post doesn't really mention the purpose of the first couple of bytes that much (what does the game need the world map flag for, though?). Just so people don't have to go there to see, the map_transition is 0 for caves (screen fades to white and then transitions to black before fading out) and 1 for everything else (screen just fades to the map). Other values make the game ignore the picture (according to the post; I'll research that a bit, because I'm not sure how much the author of that post knew about the table's structure, so maybe other values do mean something else or can be hooked into).
I don't know what specifically it needs the worldmap flag for. I only know because I saw it load the halfword then use it as an argument for the flag check routine. See 0x080F8582. I didn't really read beyond that, as it seems sufficient for any table extension you'd want to do.

The transition byte, I don't really know. It seems to always be fed as an argument 0 or 1. Although you could theoretically add new ways of loading the map, I'm not sure why you would need to.

Quick scan:
0x080F8104: 0x1B, number of entries (zero indexed)
0x080F8108: 0x1C, 1 more than number of pics, indicates no pic
0x080F8126: 0x1C, check for no matching pic
0x080F81AC: 0x1C, check for no matching pic
0x080F8552: 0x1C, check for no matching pic
0x080F857A: 0x1C, check for no matching pic

Note that I literally looked for these while typing up the post, so I may have missed something.
 
457
Posts
10
Years
  • Age 29
  • Seen Apr 9, 2024
Field Move Selection Table

One more thing about expanding the move name list: Do you remember selecting field moves from Pokemon menu, right? You can clear the original and old move name table to have more free space. However, after that, the selection becomes blank, right? Want to know why? It is because there is a table in the ROM to load the selection of field moves. Here's the table:

Code:
[B][COLOR="Red"]3F 98 31 08[/COLOR][/B] [B][COLOR="Blue"]71 54 1B 08[/COLOR][/B] 00 9F 31 08 71 54 1B 08
21 A4 31 08 71 54 1B 08 0A 9B 31 08 71 54 1B 08
61 9A 31 08 71 54 1B 08 73 98 31 08 71 54 1B 08
43 A6 31 08 71 54 1B 08 EF 9D 31 08 71 54 1B 08
90 9C 31 08 71 54 1B 08 1B 9C 31 08 71 54 1B 08
36 A6 31 08 71 54 1B 08 0C A2 31 08 71 54 1B 08
57 9E 31 08 71 54 1B 08 2A A3 31 08 71 54 1B 08
*Emerald's Field Move Selection Table

The table contains two pointers for each slot: the first pointer leads to a string of a move's name, actually inside the move name table; and, the second pointer... I dunno what it actually does but further investigation (it leads to an ASM routine I suppose), and every slot has the same pointer. For real, that table is part of the Pokemon Menu selection table (Shift, Summary, Exit, etc.). Here's the location of the field move selection table:

Code:
Emerald: 0x08615CA0 (14 field moves available)
FireRed: 0x0845A6A8 (12 field moves available)
LeafGreen: 0x0845A138 (12 field moves available)
Ruby: 0x0839F4FC (14 field moves available)
Sapphire: 0x0839F344 (14 field moves available)

Here's then the list of the second pointer for those who care:

Code:
Emerald: 0x081B5471
FireRed: 0x081245A5
LeafGreen: 0x081245F5
Ruby: 0x0808A9A5
Sapphire: 0x0808A9A5

Only thing you need to do is to find the new string of the move, and replace the first pointer with the pointer of the location of the new string. In the easy way, you just need to multiply the slot number of a field move by 0xD. It is because that is the limit of the string. Add it by the location of a move table. Then, convert it into pointer and place it in the table. This maybe sound confusing since the table is arranged in how the HMs are unlock according to badges, plus non-HM field moves. In the list, the HMs go first then the other field moves (Secret Power, Teleport, Milk Drink) comes last. Here is the list of how the slots were ordered:

Code:
R/S/E:		FR/LG:
Cut		Flash
Flash		Cut
Rock Smash	Fly
Strength	Strength
Surf		Surf
Fly		Rock Smash
Dive		Waterfall
Waterfall	Teleport
Teleport	Dig
Dig		Milk Drink
Secret Power	Softboiled
Milk Drink	Sweet Scent
Softboiled
Sweet Scent

To be helpful, I made an ASM routine that will generate the table according to your customized location of your move name table. To note that this is NOT actually an ASM routine that programs stuff but generating a table:

Routines:
Spoiler:

I wonder if it can be expanded though to add more field moves like Rock Climb, Defog, etc. Alright! That's it! Hope you've understand what it just wrote.
 
Last edited:
794
Posts
10
Years

So, I'll be addressing Emerald. The actual table starts at 0x08615C08 and contains all pokemon menu options. It goes like this:
ptr to text
ptr to function to execute
Field moves are also in that table. It seems the order of those options displayed is determined somewhere else.
0x081B5470 is a function that's executed upon selecting a field move. This function checks obtained badges, whether you can use the move here, executes appropriate script, etc. I may try to look around to find the limiter.
 

Blah

Free supporter
1,924
Posts
11
Years
So, I'll be addressing Emerald. The actual table starts at 0x08615C08 and contains all pokemon menu options. It goes like this:
ptr to text
ptr to function to execute
Field moves are also in that table. It seems the order of those options displayed is determined somewhere else.
0x081B5470 is a function that's executed upon selecting a field move. This function checks obtained badges, whether you can use the move here, executes appropriate script, etc. I may try to look around to find the limiter.
I found this stuff for FR and expanded it successfully. Check the ASM resource thread, I have a post there titled field moves, it may be useful as it's probably 1:1 with EM. Also we need a better organisation of things discovered. That's like the 5th person who's trying to expand field moves now :D
 
5,256
Posts
16
Years
When a new save is generated, the default wallpapers for the storage system will loop through the first four wallpapers for every box. This always annoyed me way back when I first played FRLG; it felt like they were just wasting the assets.

To make the boxes use wallpapers 1 through 14, change the byte at 0x8C836 to 0xD (you can make it higher but as there are only fourteen boxes, it won't really affect anything). As the wallpapers are assigned at the time of generating the save, this will only affect new saves.
 
Back
Top