• 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?".
  • Forum moderator applications are now open! Click here for details.
  • 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

Mr.Pkmn

Ordinary ASM Magician
53
Posts
15
Years
  • Seen Nov 17, 2023
How can we fix the broken sun weather in FRLG? Heavy rain works fine but intense sunlight makes the screen black.
Also I wonder if the snowy weather could set auto-hail, like other weathers do...
 

TheDarkShark

Metal Headed Hacker
56
Posts
13
Years
@DavidJCobb: lol, while fiddling with the values in the memory viewer i managed to open a second textbox. All it does is showing the same text though...
Here's what I did: open apply a new value to the text box's y coordinate (in this case i chose 8) and open the text box. While it's open, apply a new value (here 0xf) and return to the game. when pressing A it will open the second text box.
Actually, only the second text box will be hidden when the script is ended, the first one is cleared.
Just in case you can use this...
 
275
Posts
13
Years
  • Seen Oct 9, 2019
@DavidJCobb: lol, while fiddling with the values in the memory viewer i managed to open a second textbox. All it does is showing the same text though...
Here's what I did: open apply a new value to the text box's y coordinate (in this case i chose 8) and open the text box. While it's open, apply a new value (here 0xf) and return to the game. when pressing A it will open the second text box.
Actually, only the second text box will be hidden when the script is ended, the first one is cleared.
Just in case you can use this...
Ah, yes, you've taken advantage of our ability to modify the textbox's recorded coordinates before a screen repaint erases it. It is a clever technique.

However, I am looking to do something more ambitious: my goal is to manipulate the textbox generated by the showcoins/showmoney commands. These boxes, unlike the standard ones, are variable in size and can have their positions changed without properly-timed memory alterations.

The uses for a dynamically-positioned variably-sized non-blocking second message box are many and varied. For example, in dialogue-heavy hacks, the second box could function as a nametag positioned directly above the standard one, thereby removing the need to repeat the speaker's name in the main dialogue.

I am still having difficulty dissecting and identifying all of the code, but I already know of two things I can try. Furthermore I plan on finding the offsets of every single piece of ASM code that runs as part of the showcoins functionality. I may also investigate showmoney functionality and look for commonalities. If I can't accomplish my goal, I hope to at least save a significant amount of time for others who may pursue it in the future.
 
275
Posts
13
Years
  • Seen Oct 9, 2019
I have managed to create ASM code that successfully displays a secondary message box with header text and body text.

successn.png

The capabilities and limitations of the code that I know of are as follows:

  • It has header and body text. You can specify strings for both, but you can't, say, display only a header.
  • The position and size cannot yet be changed. The underlying code is capable of taking single-byte X and Y arguments, but currently I just force them both to 0. SEE NEW CODE AT BOTTOM
  • I don't know if it works with \n, \l, \p, or any other formatting control codes. I didn't try any.
  • To hide the box, you can call hidecoins. It requires X and Y arguments, but doesn't appear to use them; it will hide the secondary box regardless of position and size.
Here's an example script to demonstrate how you would load your strings and call the ASM:

Spoiler:

And finally, the ASM:

Spoiler:

This is the first fully-functional ASM code I have ever written. There is still much to be done, but this is a big step. C:

EDIT: New code. This one allows you to specify the box X, Y, width, and height using script variables.

successv3.png

Script:
Spoiler:

And new assembly:
Spoiler:
 
Last edited:

Mr.Pkmn

Ordinary ASM Magician
53
Posts
15
Years
  • Seen Nov 17, 2023
I'm sorry to bump, but since it was the last post of the page i throught it passed unnoticed...

How can we fix the broken sun weather in FRLG? Heavy rain works fine but intense sunlight makes the screen black.
Also I wonder if the snowy weather could set auto-hail, like other weathers do...
 

TheDarkShark

Metal Headed Hacker
56
Posts
13
Years
@Mr.Pkmn: I think fog has already been researched. I'm sure it'd be easy to find the main weather-routine by debugging that one.

@DavidJCobb: Ah, so that's what you meant... I thought you wanted another textbox like I have an the screenshot I posted above. I think I'll take a look into porting this over to the German version of Firered... but I already told Jambo I would port the trainer mugshot thing first. I'll see what I can do. Pretty neat, anyway. I think I can make good use of the text-rendering when I work on my hack again...
 

EdensElite

No0b, but getting there.
190
Posts
12
Years
  • Age 28
  • UK
  • Seen Jul 4, 2014
How do you edit the PC Boxes? I assume its they are graphics in the ROM but I can't find them on unLZ.
 
275
Posts
13
Years
  • Seen Oct 9, 2019
Out of boredom, I dug through every single script and OW in a clean FireRed BPRE ROM and wrote down every single flag and variable I could find. My findings are below, and include OW-visibility flags, item ownership flags, and more. (Not trainer or world map flags, though.)

Summarized flag findings:
Flags 0x000 - 0x006, at minimum, are temporary flags and are directly manipulated by the game engine.

Flags 0x011 - 0x01F are used to control the visibility of destructible OWs, i.e. Rock Smash boulders. They are probably cleared by the game engine every time a map is loaded, as no level scripts clear them. Do not use them on standard OWs.

Flag 0x266 appears to be directly manipulated by the game engine. If set, there is an EGG waiting for you in the Four Island Daycare Center. It is unset manually by scripts if you choose to discard the egg.

The game does not use checkitem to see if you have an item; instead, Game Freak scripts will always check for flags that were set as part of the event sequence that gave you the item (or it may even check for the OW-visibility flags if it was a pickup). E.x. the game uses "checkflag 0x271" after manually setting it, not "checkitem ITEM_BICYCLE 0x1".

A similar thing is done with badges. The "champ-in-making" guy that always chills next to a Gym statue doesn't check badge flags directly; there are eight flags (4B0-4B7) that are set along with those flags, which he checks. Redundant...

Not all of the listed OW-visibility flags are set/cleared directly. Most of them correspond to Person IDs in AMap, and are indirectly altered when one uses "hidesprite" on the Persons (referring to them by Person event number rather than ID).

Notable flags:
Flags 0x011 - 0x01F are used to control the visibility of destructible OWs.

Flag 0x266 is set by the game engine if an Egg is in the Daycare.

Flags 0x4B0 - 0x4B7 affect the "champ-in-making" guy's dialogue in Gyms.

Flags 0x4B8 - 0x4BC are set if the player has beaten {whoever} in the Elite Four during their current attempt at it. They're cleared upon entering the Hall of Fame registration room.

Flags 0x500 - 0x700 are trainer flags.

Flags 0x820 - 0x827 are read directly by the game engine and determine Badge acquisition. But we already knew this.

Flag 0x82D is set if you customize your profile by talking to some woman in some PokeCenter. Apparently directly set by the game engine.

If Flag 0x834 is set, then the player knows the name of Bill's PC (as opposed to "Someone's" PC). Don't know if this affects the PC menu, but it affects dialogue shown when receiving a Pokemon and having it sent to the PC.

Flag 0x842 may have something to do with wireless functionality or some minigame. It's checked after healing at a PokeCenter.

Flag 0x844 is set when Celio connects to Lanette -- IOW when you can trade with R/S/E. Don't mistake it for the E4 completion flag like I almost did.

Flag 0x849 is set when you solve the Tanoby Key.

If Flags 0x84A and 0x84B are cleared, the Vermilion City dockworker won't even bother checking for the MysticTicket and AuroraTicket, respectively. You won't be able to use them. I don't know what sets or clears these flags.

Flags 0x890 - 0x8FD are world map flags.

Flags 0x900 and up overlap the RAM used for script variables and hence ARE NOT SAFE TO USE.

Summarized variable findings:
0x4020 - 0x4024 are all pedometers, the first of them controlling REPEL expiration.

0x4036 is used for Selphy's Pokemon-fetching game. (She's the woman at Resort Gorgeous). I don't know what modifies this var -- possibly the game engine itself?

0x403A is used in elevator scripts and is directly modified when special 0xD8 is called. Don't store anything that you want to be permanent in this variable.

Vars 0x4064 through 0x4066 are used as part of the boulder puzzles in Victory Road. They're also cleared upon entering Route 23, along with 0x4067.

0x4069 sets which fossil is being revived in Cinnabar Island, and 0x406A sets the progress (1 = active, 2 = complete).

Full findings:
Spoiler:

EDIT: Updated with information from JPAN's special list as well as some hidden scripts I found (that are executed directly by the game engine, and are not referenced in maps).
 
Last edited:

knizz

192
Posts
16
Years
  • Seen Oct 28, 2020
DavidJCobb, I wish I knew you when I was still ROM Hacking. Great work.
 
275
Posts
13
Years
  • Seen Oct 9, 2019
DavidJCobb, I wish I knew you when I was still ROM Hacking. Great work.
Thanks. I've seen some of your work; coming from someone of your skill, that compliment means a lot.

* * * * *​

Building on some work by knizz --

As I said once in another thread there is an array of npc-data at 02036E38 . . .

-- I have deciphered more of the OW/Person data structure:

Bytes 0 - 8: Unknown.
Byte 9: Map number for this Person event.
Byte 10: Map bank number for this Person event.
Bytes 11 - 15: Unknown
Bytes 16 - 17: Tile X (stepping off of)
Bytes 18 - 19: Tile Y (stepping off of)
Bytes 20 - 21: Tile X (stepping onto)
Bytes 22 - 23: Tile Y (stepping oto)
Byte 24: Unknown. Changes with last movement direction. (11 down, 44 right, 33 left)
Bytes 25 - 27: Unknown.
Byte 28: Sprite frame
Bytes 29 - 31: Unknown.
Byte 32: Facing direction (same format as PLAYERFACING script var's values).
Bytes 33 - 35: Unknown.

Offset of the facing direction byte for Person event N: 0x02036E38 + (0x24 * N) + 0x20

* * * * *​

EDIT: Found offsets for some scripts that people may find interesting.

0x081A4EB4 and 0x081A4EC1
Something to do with trainer battles... Is this used by the core game engine?

0x081A6843
This script handles hidden-item Signposts. Inputs are 0x8005 (item ID) and 0x8006 (amount). If the item ID is 0 (item: ????????) then it is treated as a Coins pickup.

0x081A6955
Script for the PC.

0x081A6AC8
Script for SURF. It does not include the badge check; that is evidently done in ASM before this is called.

0x081A6B0D
Script for current that is too fast to SURF in.

0x081A7705
Script for the Mystery Gift questionnaire.

0x081A77A0
Appears to be the script that is executed if you press Select without having a Key Item registered to that button.

0x081A8D49
I have no idea, but it has something to do with digging up an item. Where in FireRed can you do that?

0x081A8D97
Script for PokeCenter healing after whiting out.

0x081A8DD8
Script for Mom healing after whiting out.

0x081A8DFD
Script for whiting out (on the overworld, in battles, or both?).

0x081AD008
Script for a Fame Checker entry. This actually runs inside the Fame Checker. The others probably do, too.

0x081BE2B7
Script for WATERFALL. Like the SURF script, the badge check is performed elsewhere.

0x081BE38B
Script for DIVE (submerging). Apparently an R/S/E leftover. Like SURF and WATERFALL, there's no badge check here.

0x081BE3D4
Script for DIVE (emerging). No badge check.

0x081BE420
Script for if you try to use DIVE when you cannot emerge at the spot you're currently standing on.

0x081BF546
Internal script for hatching an EGG (by walking).

0x081BFB65
Script executed when REPEL wears off.

* * * * *​

And some string offsets:

0x0826CF8C - 0x0826D19D
Nicknames of the Pokemon you can receive in in-game trades.

0x081C55C9
Strings for saving the game.

0x081B2DF8 - 0x081BB1B3(?)
L/R help strings.
 
Last edited:

NarutoActor

The rocks cry out to me
1,974
Posts
15
Years
'Offset of the facing direction byte for Person event N: 0x02036E38 + (0x24 * N) + 0x20'
This is extremely useful I have been trying to find this out recently too. Good job :D

Actually, I have a question. If you talk to the npc does the value change, or is it strictly the facing the player has in advance map.
 
275
Posts
13
Years
  • Seen Oct 9, 2019
'Offset of the facing direction byte for Person event N: 0x02036E38 + (0x24 * N) + 0x20'
This is extremely useful I have been trying to find this out recently too. Good job :D

Actually, I have a question. If you talk to the npc does the value change, or is it strictly the facing the player has in advance map.
It varies depending on the movement behavior that you have set. What I found was that the byte was not updated after talking if the behavior was "No Movement". When using either the rotate-clockwise or walk-around-randomly behaviors, however, the OW's facing byte updated when they moved, when they turned, and when the "faceplayer" command was used.

EDIT: I also just updated my list of every known flag and variable in FireRed. A list of all Hidden IDs (hidden-item Signposts) has been added as well.
 
Last edited:
275
Posts
13
Years
  • Seen Oct 9, 2019
I just found a few interesting quirks about some FireRed scripting commands. When I get around to it, I'll be uploading an updated version of a command reference I've been working on.

- - -

Setworldmapflag will set a flag if it is one of the sixteen entries in a list of world map flag numbers whose maps can be flown to. (That is, it will work for Viridian City's world map flag, but not for, say, Rock Tunnel's.)

- - -

Braille2 sets variable 0x8004 to a value based on the width of the braille string at the pointer you give it.

Because braille strings do not support the \p or \l control codes, Game Freak had to create a "fake" message cursor every time they wanted to show multi-part or multi-line braille strings. To facilitate this, they created special 0x1B2, which draws a cursor on the screen at a position specified by variables 0x8004 (X) and 0x8005 (Y).

braille2 will calculate the length of a specified braille string, and then set 0x8004 to a value based on that length. If you then show that string in a message box and call special 0x1B2, a cursor will appear exactly at the end of the braille string. For an example of its usage, view the scripts for the Signpost events in the Ruby or Sapphire rooms in Mt. Ember.

- - -

Setwildbattle will actually generate a 100-byte Pokemon data structure. If you know how, you can then manipulate this data structure before calling dowildbattle if you want to change its moveset or something.

- - -

If hidepokepic is called too soon after showpokepic, the script will freeze and hang with the pokepic box visible. I suspect the problems arise if you try to hide a pokepic while the game is still trying to display one.

- - -

Givepokemon will send the new Pokemon to the player's PC if their party is full. The number of the box to which the Pokemon is sent is stored in 0x4037 (yes, the game itself writes that var as part of the command). LASTRESULT is set to 0 if the Pokemon is stored in the party, 1 if it's sent to the PC, and 2 if there's no room in the party or the PC.
 
275
Posts
13
Years
  • Seen Oct 9, 2019
During my analysis of cmda6, I discovered that Game Freak implemented their own script-controlled walking ASM into the Advance-generation games. There can be up to eight subroutines to run on every frame of animation, only one of which may be active at any given time. You can select a subroutine to activate using cmda6.

At 0x03005090, there is a list of ASM functions to be executed on every frame of animation. Each entry in the list is a pointer to the routine, some metadata about the list item itself, and thirty-or-so bytes for the routine to work with (so that it may maintain its state).

When on the overworld, one of the items on this list is 0x0806E811, a walking routine manager. This routine manager will check one of the bytes in its execution-list-item (set by cmda6) and based on that byte, it will call one of eight walking subroutines.

Those subroutines in turn check the player's coordinates against stored values to see if the player has moved. If so, the subroutine processes player movement accordingly (check the tile they're standing on, change it if necessary, what have you).

There are eight slots for walking subroutines, and the defined subroutines (pointed to by pointers at 0x083A7310) are:
#0 at 0x0806E955: Nop
#1 at 0x0806EB55: Broken (R/S/E leftover: Route 113 ash-covered grass)
#2 at 0x0806E955: Nop
#3 at 0x0806E955: Nop
#4 at 0x0806E9E1: Icefall Cave ice tiles
#5 at 0x0806E955: Nop
#6 at 0x0806E955: Nop
#7 at 0x0806EC41: Broken (R/S/E leftover: Granite Cave/Sky Pillar broken floor tiles)

(The three defined subroutines basically change certain tiles out from under the player's feet. Theoretically, though, a subroutine can do anything it wants on every frame of animation that the overworld is being processed.)

What this means is that we now have an official way -- something that was designed for this use -- to set up our own custom-made ASM functions to run the very instant the player takes a step. If we keep the broken functions in the table, we can define up to four custom ASM subroutines; if we ditch those, we can define six.

(We could also repoint and extend the subroutine pointer table, and modify the related ASM code, thereby allowing up to 255 custom subroutines to be predefined and activated with cmda6.)

One possible use case for all of this would be an alternate (and more script-friendly) implementation of JPAN-style walking scripts, which would work without breaking other game functions (i.e. wild encounters in tall grass).

For more information, see the description for cmda6 in my FireRed script command reference.

Oh, something else: the R/S/E leftovers prove that this discovery applies to all Advance-generation games. The offsets will differ, and the walking subroutines will have some differences in R/S/E, but the system itself exists in all Pokemon GBA games.
 
275
Posts
13
Years
  • Seen Oct 9, 2019
Here's some information that may make my previous discovery more useful.

First, a demonstration.

Next, the walking subroutine that I used in that demonstration, with comments added. Modifying this should allow for easily-controlled tile-changing-when-stepped on effects.

Spoiler:

The upshot of all of this is that it is now very easy to make polished effects like a floor cracking underneath the player's feet, for example -- complete with sound effects and perhaps even other behaviors.

That alone could be used for things like unique Gym puzzles. Theoretically, that is just scratching the surface of this functionality's potential, however. Remember that it runs on every frame of animation in which the overworld is being shown and/or processed. In theory, you could do things like timing how long the player stands on a block, or tampering with the movement patterns of an NPC (this runs when you take a step, not when you finish moving, so problems waiting for movement should be few and far between).

And so this concludes my research on CmdA6.
 
Last edited:

knizz

192
Posts
16
Years
  • Seen Oct 28, 2020
At 0x03005090, there is a list of ASM functions to be executed on every frame of animation. Each entry in the list is a pointer to the routine, some metadata about the list item itself, and thirty-or-so bytes for the routine to work with (so that it may maintain its state).
FINALLY! Finally someone understands the relevance of this list.
I called it callback3-list and all functions that can be in one of it's slots are prefixed with c3_ in my database. The walking routine manager (0x0806E811) is called c3_ash in it. The table with the eight slots (0x083A7310) is named 'ashtable'.

The ash handler calls 'music_play' and 'setmaptile' internally. Once at 0806EB22 (Tile 0x35B) and another time at 0806EAD8 (Tile 0x35A). A subfunction (0806E958) that is called from 0806EA82 and sets some flags.

I didn't know that this is controllable via the 0xA6 command. So thanks for telling.
 
106
Posts
15
Years
  • Seen May 29, 2019
Is the screen size for the GBA Pokémon games (240 x 160) set within the ROM or the GBA hardware? And if it was theoretically possible to expand it to the DS screen size (or greater)(256 x 192) would it be that size on an emulator or if it was played on a DS or would it still be limited to the original GBA screen size?
 
Back
Top