Glitch City Laboratories Archives

Glitch City Laboratories closed on 1 September 2020 (announcement). This is an archived copy of a thread from Glitch City Laboratories Forums.

You can join Glitch City Research Institute to ask questions or discuss current developments.

You may also download the archive of this forum in .tar.gz, .sql.gz, or .sqlite.gz formats.

Generation I Glitch Discussion

Pokemon Red/Blue Oak's lab sprite glitch - Page 1

Pokemon Red/Blue Oak's lab sprite glitch

Posted by: Crystal_
Date: 2016-06-27 12:29:01
So I've been looking into this glitch…
https://www.youtube.com/watch?v=I_JjAIvG9zA

The thing is, there are a total of 11 sprites in the oak's lab before getting your first Pokemon: 2 Pokedex, Oak, Blue, 3 Pokeballs, a lady, 2 scientists, and yourself. That's one more than the number allowed to be displayed at once, as the OAM buffer can only hold data for 40 objects (fe00-fe9f) and each sprite is made of 4.

There is a 10-half-block vertical separation between the two dexes and the two scientists though, meaning they should never be all displayed at once, EXCEPT when you are four half-blocks above the scientists and walk up, or when you are four half-blocks below the dexes and walk down. In these cases, parts of all four sprites are on screen as the background map scrolls during your movement.

The issue comes from the clear unused OAM routine: https://github.com/pret/pokered/blob/2b2c6fe/engine/overworld/oam.asm#L147
If there are 11 sprites, hOAMBufferOffset is going to end up becoming $b0 given that PrepareOAMData is taking care of what would be a total of 44 objects ($00 to $af). Normally, it should be multiples of $10 from $00 through $a0. The game would then attempt to clear unused OAM data starting from what should be the last sprite in use, indicated by hOAMBufferOffset. If there are, say, 6 sprites on screen, every four bytes from $c360 to $c3a0 are set to $a0 in order to make all those sprites invisible in the wram sprite buffer (y coordinate of $a0 is just below the screen). If there are 11 sprites, however, every four bytes from $c3b0 through $c4a0 are going to become corrupted with $a0 because the game won't stop until the lower byte of the address equals $a0 (supposed to be the address of the last sprite when preceded by $c3). With the tilemap starting at $c3a0, this leads to the screen getting corrupted with character "a" every four tiles.

Most of the times, however, the scientists are alrealdy invisible by the time the pokedexes show up, so there are never more than 9 sprites overlapping. But it's not always, given that the glitch pops up every once in a while, which leaves me wondering, what is the timing factor that leads to the pokedex sprites appearing when the scientists are still considered to be visible?

Anyway, after that, some sprites seemingly at random became invisible, leaving only a total of five on screen, but I haven't really looked beyond that. So yeah, has anyone been able to figure out more than me about this mysterious glitch?

EDIT: Figured out why the sprites disappear. If they are above one of the corrupted tiles, the tile will have a value higher than $60 (because they were corrupted with $a0), so the game thinks they are hidden by a text box: https://github.com/pret/pokered/blob/master/engine/overworld/movement.asm#L508

Re: Pokemon Red/Blue Oak's lab sprite glitch

Posted by: TheUnReturned
Date: 2016-07-10 07:32:11
It looks like it just shows the game is broken.


Wait.
Whenever there's more than 10 sprites on screen show up, it will keep corrupting until the sprites were hidden by a textbox?

Re: Pokemon Red/Blue Oak's lab sprite glitch

Posted by: TheUnReturned
Date: 2016-07-13 05:30:50

So I've been looking into this glitch…
https://www.youtube.com/watch?v=I_JjAIvG9zA

The thing is, there are a total of 11 sprites in the oak's lab before getting your first Pokemon: 2 Pokedex, Oak, Blue, 3 Pokeballs, a lady, 2 scientists, and yourself. That's one more than the number allowed to be displayed at once, as the OAM buffer can only hold data for 40 objects (fe00-fe9f) and each sprite is made of 4.

There is a 10-half-block vertical separation between the two dexes and the two scientists though, meaning they should never be all displayed at once, EXCEPT when you are four half-blocks above the scientists and walk up, or when you are four half-blocks below the dexes and walk down. In these cases, parts of all four sprites are on screen as the background map scrolls during your movement.

The issue comes from the clear unused OAM routine: https://github.com/pret/pokered/blob/2b2c6fe/engine/overworld/oam.asm#L147
If there are 11 sprites, hOAMBufferOffset is going to end up becoming $b0 given that PrepareOAMData is taking care of what would be a total of 44 objects ($00 to $af). Normally, it should be multiples of $10 from $00 through $a0. The game would then attempt to clear unused OAM data starting from what should be the last sprite in use, indicated by hOAMBufferOffset. If there are, say, 6 sprites on screen, every four bytes from $c360 to $c3a0 are set to $a0 in order to make all those sprites invisible in the wram sprite buffer (y coordinate of $a0 is just below the screen). If there are 11 sprites, however, every four bytes from $c3b0 through $c4a0 are going to become corrupted with $a0 because the game won't stop until the lower byte of the address equals $a0 (supposed to be the address of the last sprite when preceded by $c3). With the tilemap starting at $c3a0, this leads to the screen getting corrupted with character "a" every four tiles.

Most of the times, however, the scientists are alrealdy invisible by the time the pokedexes show up, so there are never more than 9 sprites overlapping. But it's not always, given that the glitch pops up every once in a while, which leaves me wondering, what is the timing factor that leads to the pokedex sprites appearing when the scientists are still considered to be visible?

Anyway, after that, some sprites seemingly at random became invisible, leaving only a total of five on screen, but I haven't really looked beyond that. So yeah, has anyone been able to figure out more than me about this mysterious glitch?

EDIT: Figured out why the sprites disappear. If they are above one of the corrupted tiles, the tile will have a value higher than $60 (because they were corrupted with $a0), so the game thinks they are hidden by a text box: https://github.com/pret/pokered/blob/master/engine/overworld/movement.asm#L508

Yeah… it's really intresting
https://youtu.be/7IQVBi9azjU
I still do not get what's wrong though ._.

Re: Pokemon Red/Blue Oak's lab sprite glitch

Posted by: ISSOtm
Date: 2016-07-13 19:16:01
Beware not to mistake the Game Boy's sprites with the game's logical sprites. Usually one game sprite represents four Game Boy sprites.

Re: Pokemon Red/Blue Oak's lab sprite glitch

Posted by: TheUnReturned
Date: 2016-07-13 20:23:58

Beware not to mistake the Game Boy's sprites with the game's logical sprites. Usually one game sprite represents four Game Boy sprites.

According to what I see in the OAM (in the video I have given)
Usually the last four sprites is the top left gameboy sprite, and seems to be always the same. I'm not sure about the use of that, maybe to prevent too much sprites from appearing
But when you and many thing disappear, I noticed that last 4 sprites were replaced.
That's something?

Re: Pokemon Red/Blue Oak's lab sprite glitch

Posted by: ISSOtm
Date: 2016-07-14 14:02:49
Probably the clearing routine that overflowed ans replaced sprites, I guess.

Re: Pokemon Red/Blue Oak's lab sprite glitch

Posted by: TheUnReturned
Date: 2016-07-15 01:12:52
I'm on a plane, so I occupied myself by struggling to type an understandable passage. Please don't mind if you don't understand all, it's my fault.

OAM doesn't have enough space to handle 11 GB sprites (44 game sprites) So the 11th sprite overflowed to the address after the last address of OAM (supposingly  $c3a0)
And $c3a0 is where tilemap starts.
And basically it's recreating another OAM in the tilemap.

My theory is that there's actually a square outline of address with $a0 covering the tilemap.
That's because it need to make the sprites $a0 once you walked away and the sprite is off screen
If not, sprite will "appear" and still be loaded offscreen. In theory (yes theory), there's 255(256) sprite (including glitched). But since if you never seen that sprite AFTER the whole OAM is unloaded (all filled with A0 00 00 00) (example of this will be after rebooting the gameboy, resetting the game) , it wouldn't really be ever be loaded (changed from $a0)
But once you seen 10+ sprite, this glitch will happen.
So (without actually testing and just randomly guessing a answer that seems fit) developer added a extra $a0 outline.
That follows you as you walk.
Once it fully covers a sprite, the sprite will be A0 00 00 00'd

There's a reason why I guessed this
Since the screen is corrupted every 4 bytes, with 1 of the a0's on the edge of screen and another 1 almost on the edge, but one byte space
So I think that there's extra 2 bytes off screen
Then somehow come up with this

Anyway, it should be wrong,
so just ignore that
So… a quote from _Crystal: "If there are 11 sprites, hOAMBufferOffset is going to end up becoming $b0 given that PrepareOAMData is taking care of what would be a total of 44 objects ($00 to $af)."
So it ended up the corruption starting at $c3b0 and ending at $c4b0!
And there we have 2 OAM:
1 from $c2a0 to $c3a0
2 from $c3b0 to $c4b0
And actually, you can see it isn't really that game breaking!
Because menu data starts at $CC24, and it's very very far away, it won't do anything to harm your game :0
So the end there's nothing to really investigate on about :9

Don't understand?
Basically the OAM is full, so the extra 11th sprite is overflowed to another place that stores tile data (map), and since OAM have unused bytes (blank space), they are make of A0,00,00 and 00, so when the 11th Sprite is overflowed and also "make" another OAM in the tile data, the "a"s are A0
,00,00 and more 00. So that's why you only see an "a" every four block/byte :3

Still don't understand?
Well, in short, there is blank, unused sprites to fill up the "cache" that store sprites
There's 11 Sprite on screen, a single "cache" cannot store all so it replaced the next "cache" that was supposed to store another thing to the kind of "cache" that store sprites which is called OAM.

If you still ask "what am I talking about", you have no hope

Re: Pokemon Red/Blue Oak's lab sprite glitch

Posted by: ISSOtm
Date: 2016-07-15 10:28:13
First, you swapped Game sprites and GB sprites. 1 Game sprite uses 4 GB sprites. The GB can display 40 sprites, with their data being taken from a memory area known as the OAM (refer to this). Accessing the OAM is quite a pain, so the game writes some GB sprite data to a buffer in RAM, which I'll refer to as the Pseudo-OAM, then uses a feature known as DMA transfer to commit data to the actual OAM.

Still according to the same page, vertical values >= 160 ($A0) are out of bounds and thus won't be displayed. So, to hide a sprite, the game places it out of bounds.

However, GB sprites are 8x8, and that's really small ! So, the programmers decided that, for the overworld, sprites would be grouped in 2x2 squares (16x16 pixels). Thus, they created a buffer I'll refer to as Game OAM, which holds data for the 16x16 pseudo-sprites (plus some metadata like movement).

The usual cycle works like so :

What happens here is that 11 Game Sprites are loaded, so when the game tries to clean their Pseudo-Sprites, it cleans data that is located right past the Pseudo-OAM. Tiles being corrupted in a one-per-four pattern comes from GB sprite structure being 4 bytes long. The game simply alters what it believes to be vertical positions to $A0.


Keep in mind, BGB / VBA cannot display you the Game OAM nor the Pseudo-OAM because they are game-specific, they can only display you the OAM, the real one.

Re: Pokemon Red/Blue Oak's lab sprite glitch

Posted by: TheUnReturned
Date: 2016-07-15 10:43:18

First, you swapped Game sprites and GB sprites. 1 Game sprite uses 4 GB sprites. The GB can display 40 sprites, with their data being taken from a memory area known as the OAM (refer to this). Accessing the OAM is quite a pain, so the game writes some GB sprite data to a buffer in RAM, which I'll refer to as the Pseudo-OAM, then uses a feature known as DMA transfer to commit data to the actual OAM.

Still according to the same page, vertical values >= 160 ($A0) are out of bounds and thus won't be displayed. So, to hide a sprite, the game places it out of bounds.

However, GB sprites are 8x8, and that's really small ! So, the programmers decided that, for the overworld, sprites would be grouped in 2x2 squares (16x16 pixels). Thus, they created a buffer I'll refer to as Game OAM, which holds data for the 16x16 pseudo-sprites (plus some metadata like movement).

The usual cycle works like so :

    [li]Run overworld code that will edit Game OAM[/li]
    [li]"Decompress" each Game sprite into four sprites, and write them to the Pseudo-OAM[/li]
    [li]Use a DMA transfer to commit that to the actual OAM[/li]
    [li]The GB's video driver takes care of the rest[/li]

What happens here is that 11 Game Sprites are loaded, so when the game tries to clean their Pseudo-Sprites, it cleans data that is located right past the Pseudo-OAM. Tiles being corrupted in a one-per-four pattern comes from GB sprite structure being 4 bytes long. The game simply alters what it believes to be vertical positions to $A0.


Keep in mind, BGB / VBA cannot display you the Game OAM nor the Pseudo-OAM because they are game-specific, they can only display you the OAM, the real one.
oh I see… Thank you!