You are not logged in.
I believe this happens when you have more than 6 Pokemon in your party so addresses after wPartyGainExpFlags are tested to find out which Pokemon should gain experience. If you can replicate the bug, start by checking if wPartyCount gets corrupted.
wPartyCount indeed gets corrupted with the value 2a. It doesn't happen because the dugtrio is at level 42, it happens regardless of pokemon and level, even on a new game. It gets corrupted only in the battle with that specific trainer in the game, and if i shark the value of that address to 06 the glitch stops happening.
EGRIP comes from VICEGRIP, which is the next attack from scratch (the last move i used) in index order, if i use slash at the last turn, it shows ITUTE (from substitute, the next attack from slash) instead.
I noticed something really strange though, the glitch doesn't happen on VBA... that might be an emulator problem, but i still don't know why that happens.
I hope all this info helps on knowing what's going on
VBA (depending on the version) doesn't closely emulate gbc (or even GBA), my suggestion (bearing in mind I only understand the basics) is to use BGB and it's debugger. Hopefully someone else can give you a better, more in depth answer.
The saddest thing is there's no such thing as an ex addict. Either you're fighting addiction or you're not and if you start fighting you never stop. That's the nature of the monster.
Thanks bloodless :)
I tried creating a .sav file on vba and then load it on bgb. The glitch still happens.
At least i think it's safe to say that the problem is not on the save file, but on the way VBA executes/reads code
Sadly i was unable to find out where does the game read that 2a in that particular battle using the debugger
Set an access breakpoint on write at the wPartyCount address with the value 2a. Your answer will most likely be just a few instructions above. If the function where the debugger pops up is a generic function that doesn't tell you much about where the issue could come from, use the Trace option until you return from it so you can see who the caller is.
Hey Crystal_ :)
The access breakpoint doesn't work. To make sure of that, i set an access breakpoint on write at that address with the value 06 immediately after i started the game. It popped up at the CopyData function, as usual.
Then, i set it to the value 2a. When i challenge the trainer, the ram address changes to 2a, but the debugger doesn't pop up. Do you have any advice on what should i do?
Sorry for the inconvenience btw
Alright, finally the debugger popped up. I had to set it in all four functions for it to work. It showed the function SetupPokeballs. The code for that function is unmodified with respect to vanilla red/blue, but is stored on a different location (0E:6BD8) than vanilla r/b (0E:6990). The exact byte was the first byte of this function (1a) which translates ld a,(de) to asm.
Sadly, i don't see why this function would fail to load six pokeballs and load 42 instead, also, i don't see why would this happen with just that one trainer in the game, even if i change the roster index number.
I'm absolutely sure that before the battle (and during the battle with any other trainer) the address has the value 06, but when i enter into a battle with that traines, the address' value changes to 2a. This might sound noobish but is there a way for an address to change value without actually 'writing'? The debugger just won't pop up if i set it to write only :|
Alright, i found out some other things...
The glitch happens regardless of the number of pokemon you have in the party (from 1 to 6). Also, it happens on every new game, even if there is not a previous save file. The debugger doesn't pop up on write, even in this circumstance, even if i have it active from the beginning of the game. The value is always 2a.
I checked what functions could be malfunctioning in loading the number of pokemon i have in the party, and i suspect it's either SetupPlayerAndEnemyPokeballs or SetupOwnPartyPokeballs. Both of this functions got to load the wPartyCount byte and both are on draw_hud_pokeball_gfx.asm on the disassembly, along with SetupPokeballs, which is the function the debugger popped up on read. Sadly, i'm still lost at why would this happen only with that specific trainer.
But can you see the value changing to 2a in the memory viewer of the debugger? If so, set a breakpoint in the v-blank interrupt (0040) right before it happens, and get yourself to the last vblank interrupt before the 2a write occurs. Save a state there and start tracking down code from there (you can go faster until you approximate the line (LY) when it occurs; it's bound to happen with the same timing if it's done from the same recent save state). You should eventually stumble upon with whatever changes that value to 2a.
Thanks a lot for your help Crystal_
I set a breakpoint at 0040 and the debugger pops up at every frame. I challenged the trainer and i created a save state at the last frame the wPartyCount address' value is 06. The interrupt occurs at the RAM address DFED. One frame later, when the value is 2a, the interrupt occurs at the RAM address DFE3. Both these addresses belong to wBoxDataEnd, as the ordinal bytes $10B and $101 respectively. After searching the disassembly, i can't find any function that loads wBoxDataEnd, and looking at the addresses, they don't seem to store anything, as most of them (at least both the bytes the debugger points to) are constantly changing right before entering battle. How can i track down code from there?
Sorry if it's obvious, but it doesn't make sense to me that the debugger pops up on here...
EDIT: the trace option takes me to VBlank, then AutoBgMapTransfer, then VBlankCopyBgMap, RedrawRowOrColumn, VBlankCopy, VBlankCopyDouble, UpdateMovingBgTiles, then an unnamed function at FF80. The debugger returns at a step in this function:
Which in hex is 3D20. This step occupies the bytes FF86 and FF87.
Sadly, in the disassembly hram addresses are defined only from FF8A onwards, so i have no idea what does this code do.
EDIT2: According to DataCrystal, those bytes belong to the OAM DMA routine, which i don't know what it does.
Sigh... I guess it's back to school for me, at least until i understand the z80 assembly better.
Last edited by value chain (2016-12-27 10:49:45)
DFED and DFE3 are just the stack pointer. If you want to know where the game is executing code from, you should check the program counter (pc register at the top right corner of the debugger).
The OAM DMA routine is used to transfer sprite data to OAM memory. Only HRAM is accessible during that period so that's why the game is executing code from there, waiting until the transfer is complete.
What I meant is that you would trace the execution after returning from the vblank interrupt, that is, after the reti instruction. If one frame later the value is already 2a, it's because the error occurs at some point within these two frames.
Crystal_ YOU'RE AWESOME
Apparently the caller was the function ReadTrainer, which loads wEnemyPartyCount and SpecialTrainerMoves. I had one syntax error on that stored database. I corrected the error and the glitch stopped happening!
Thanks a whole bunch bud :D i can finally start hacking again in peace. How did wPartyCount get corrupted instead of wEnemyPartyCount is beyond me... but i've been stuck with this glitch for so long i (almost) only care that the glitch has been solved.