Skeetendo

’Cause all games were better on the GBC

You are not logged in.

#51 2012-09-18 00:07:10

Danny-E 33
Administrator
Registered: 2012-06-09
Post 131/1,024

Re: Pokemon Red: Backsprites

Okay, thank you for that explination.

But now that I see it in action, I'm lost.. :P

First I just set the breakpoint at 0x6C92, but there was a very short amount of code before the sprite was already loaded onto the screen, when I used F3 to execute one line at a time.

F:6C92

ld a, [D05A] ; loads 0xFF into a
dec a        ; sets the carry flag, unsets the zero flag
ld de, 7E0A
jr nz, 6C9E  ; moves forward 0x03 bytes because the zero flag is not set

And at that point, the player backspite was on the screen so I added another breakpoint at F:6C9E to watch the rest of the code but it took a long time of pressing F3 before the sprite loaded on the screen...

F:6C9E

ld a, 0C
call 36EB
ld a, 03
call 3E6D       ; I do not know the meaning of these two routines
ld hl, C300
xor a           ; or's with what? Itself?
ld (FF00+8B), a
ld b, 07
ld e, A0
ld c, 03
ld d, 38
ld [hl], d
inc hl
ld [hl],e       ; put the values 38 and A0 at 0xC300 and 0x C301, respectively
ld a, 08
add d
ld d,a
inc hl
ld a, (FF00+8B)
ldi [hl], a
inc a
ld (FF00+8B), a
inc hl
dec c
jr nz, 6CB6

At this point, the z flag is not set and it jumps to 0x6CB6 which goes into a seemingly never ending cycle.
When it finally does get out of that cycle, the sprites begin loading on the screen.

I honestly have no idea where the answer is that I'm looking for. I have no idea what exactly this code does or how I want to modify it..


Red Hack: Pokémon Prototype

Total number of registered users: 7000+
Total number of active users: ~12

Offline

#52 2012-09-18 18:03:27

Sawakita
Administrator
Registered: 2010-10-16
Post 299/364

Re: Pokemon Red: Backsprites

Danny-E 33 wrote:

First I just set the breakpoint at 0x6C92, but there was a very short amount of code before the sprite was already loaded onto the screen, when I used F3 to execute one line at a time.

You should use F7 to execute one line at a time (I never used F3, but it seems that it skips code when it meets a jump, which is not what you want). If you want to skip a call you can use F8 (when you're right at the call line).

Danny-E 33 wrote:
F:6C92

ld a, [D05A] ; loads 0xFF into a
dec a        ; sets the carry flag, unsets the zero flag
ld de, 7E0A
jr nz, 6C9E  ; moves forward 0x03 bytes because the zero flag is not set
ld de, 7E9A

I understand what you're going through, here. When I started learning ASM, I had a hard time focusing less on the meaning of the single intructions and more on the general effect of a chunk of code. What you should focus more on this first part of the routine (I added the line you skipped in your post, to give a better view of what's going on) is not just that a zero flag is set or not (well, of course, technically it's important, but not meaningful enough). I'll put some sort of pseudocode here so it's hopefully clearer:

if [D05A] == 1:
    [de] = 7E9A
else:
    [de] = 7E0A

Those two values are pointers to two compressed sprites, the player's backpic and the old man's, respectively. Now it does make more sense, right? When the old man's script runs the value 1 is stored in [D05A] so that the pointer to the old man's backpic is used. Instead, when you enter any other kind of battle a value of 0 is stored into [D05A], so that the player's backpic is used (notice that any value except 1 is valid for the player's backpic to be used, but we don't not care about it).

Danny-E 33 wrote:
F:6C9E

ld a, 0C
call 36EB

When you'll look into routine $36EB, you'll see that it calls $24FD, which we know very well, since it's the decompression routine. $36EB itself is short: it just copies the value from de into RAM:D0AB-D0AC which is read by the decompression routine to retrieve the compressed sprite's pointer. So this code simply decompresses a sprite, whose bank is the value in a, and whose 2-byte pointer is the value in de.

Danny-E 33 wrote:
ld a, 03
call 3E6D       ; I do not know the meaning of these two routines

I already told about this one, do you remember the pokemon's backpics' routine?

Danny-E 33 wrote:
ld hl, C300
xor a           ; or's with what? Itself?

It's an eXclusive OR. It the short for:

xor a, a    ; often the "left-sided" a is omitted

which is a fast way to achieve the same as:

ld a, 0

The meaning is the same (except for the affected flags, but here it's unimportant).

Danny-E 33 wrote:
ld (FF00+8B), a
ld b, 07
ld e, A0
ld c, 03
ld d, 38
ld [hl], d
inc hl
ld [hl],e       ; put the values 38 and A0 at 0xC300 and 0x C301, respectively
ld a, 08
add d
ld d,a
inc hl
ld a, (FF00+8B)
ldi [hl], a
inc a
ld (FF00+8B), a
inc hl
dec c
jr nz, 6CB6

At this point, the z flag is not set and it jumps to 0x6CB6 which goes into a seemingly never ending cycle.
When it finally does get out of that cycle, the sprites begin loading on the screen.

Notice that it's a nested loop (the inner one is between $6CB6 and $6CC6 while the outer loop is between $6CB2 and $6CD3). It basically produces an OAM arrangement ($C300-C353 is later copied to the OAM:FE00-FE53 using the Game Boy's DMA feature); it's used for the fancy scrolling scene, where the player shifts from right to left, while the enemy shifts from left to right.
This part of the routine should stay unmodified, as it's unrelated to the magnification issue.

Try focusing on the aspects that are similar to the pokemon's backsprite loading routine we have already hacked. Keep the OAM thingy as is and look rather at these ones:

;6CA3
ld a, 03
call 3E6D
...
;6CD5
ld de, 9310
call 16EA

which we know that can both be removed, if an appropriate, specific counter-measure is applied.

Offline

#53 2012-09-19 03:02:25

Danny-E 33
Administrator
Registered: 2012-06-09
Post 133/1,024

Re: Pokemon Red: Backsprites

Sawakita wrote:
Danny-E 33 wrote:

First I just set the breakpoint at 0x6C92, but there was a very short amount of code before the sprite was already loaded onto the screen, when I used F3 to execute one line at a time.

You should use F7 to execute one line at a time (I never used F3, but it seems that it skips code when it meets a jump, which is not what you want). If you want to skip a call you can use F8 (when you're right at the call line).

Oh wow. I was told to use F3, but I definitely prefer F7. I feel like there's more to it that just following all the calls. I feel like F3, F7, and F8 all behave differently but I don't know how or why exactly.

Sawakita wrote:
Danny-E 33 wrote:
F:6C92

ld a, [D05A] ; loads 0xFF into a
dec a        ; sets the carry flag, unsets the zero flag
ld de, 7E0A
jr nz, 6C9E  ; moves forward 0x03 bytes because the zero flag is not set
ld de, 7E9A

I understand what you're going through, here. When I started learning ASM, I had a hard time focusing less on the meaning of the single intructions and more on the general effect of a chunk of code. What you should focus more on this first part of the routine (I added the line you skipped in your post, to give a better view of what's going on) is not just that a zero flag is set or not (well, of course, technically it's important, but not meaningful enough).

Yeah, you're right. I think I'm getting a bit better at it though. :) I also think I slightly misspoke. Decrementing 0xFF does not set the carry flag :P I don't know why I said that initially. Unless I was mistaken when I noted that it was the value 0xFF that was retrieved from D05A. The important part is that it unsets the zero flag.

Sawakita wrote:

I'll put some sort of pseudocode here so it's hopefully clearer:

if [D05A] == 1:
    [de] = 7E9A
else:
    [de] = 7E0A

Those two values are pointers to two compressed sprites, the player's backpic and the old man's, respectively. Now it does make more sense, right? When the old man's script runs the value 1 is stored in [D05A] so that the pointer to the old man's backpic is used. Instead, when you enter any other kind of battle a value of 0 is stored into [D05A], so that the player's backpic is used (notice that any value except 1 is valid for the player's backpic to be used, but we don't not care about it).

Yes, it's making alot more sense. :) I'm definitely starting to see the big picture.

Sawakita wrote:
Danny-E 33 wrote:
ld a, 03
call 3E6D       ; I do not know the meaning of these two routines

I already told about this one, do you remember the pokemon's backpics' routine?

Right, right. When I double checked to see if that was a routine also called for Pokemon's backpics, I checked it with the new routine you described instead of looking at the old routine. Oops.

Sawakita wrote:
Danny-E 33 wrote:
ld hl, C300
xor a           ; or's with what? Itself?

It's an eXclusive OR. It the short for:

xor a, a    ; often the "left-sided" a is omitted

which is a fast way to achieve the same as:

ld a, 0

The meaning is the same (except for the affected flags, but here it's unimportant).

Very interesting. I didn't think about that when I was trying to figure out the usefullness of or-ing a with itself.

Sawakita wrote:

Try focusing on the aspects that are similar to the pokemon's backsprite loading routine we have already hacked. Keep the OAM thingy as is and look rather at these ones:

;6CA3
ld a, 03
call 3E6D
...
;6CD5
ld de, 9310
call 16EA

which we know that can both be removed, if an appropriate, specific counter-measure is applied.

Well when we did this the first time, it appeared you simply ommitted

ld a, 03

Then replaced

call 3E6D

with the call to the short custom code at 7BC8.
And then the original line that said

ld de, 9310

was included in the new code at 7BC8.
And lastly

call 16EA

seems to have been ommitted.

So I changed the 5 bytes at 6CA3 to

CD C8 7B
00
00

And then I replaced the 6 bytes at 6CD5 with all 00's.

And viola!
pyIFEQu.png
Success! (credit goes to Poketto for the awesome sprite)

Last edited by Danny-E 33 (2016-12-31 08:31:05)


Red Hack: Pokémon Prototype

Total number of registered users: 7000+
Total number of active users: ~12

Offline

#54 2012-09-19 03:08:10

stag019
Idea Killer
Registered: 2011-01-05
Post 218/630

Re: Pokemon Red: Backsprites

Danny-E 33 wrote:
Sawakita wrote:
Danny-E 33 wrote:

First I just set the breakpoint at 0x6C92, but there was a very short amount of code before the sprite was already loaded onto the screen, when I used F3 to execute one line at a time.

You should use F7 to execute one line at a time (I never used F3, but it seems that it skips code when it meets a jump, which is not what you want). If you want to skip a call you can use F8 (when you're right at the call line).

Oh wow. I was told to use F3, but I definitely prefer F7. I feel like there's more to it that just following all the calls. I feel like F3, F7, and F8 all behave differently but I don't know how or why exactly.

These are the kinda things people like Danny-E 33 and I need to learn. How to use a debugger. I never have before, and while I'm starting to understand how assembly works rather well, the difficult part is reverse engineering. You need to understand how to use a debugger, and then you need to understand how everything is stored in the game so that you know how to inject what code, and where.

There's no way I'd be able to do this without all the resources already available. Without Koolboyman's ROM and RAM maps, and the disassembly, I would be completely clueless. Thankfully, with so much labelled already, something like the palettes thing was really easy to do.


You can try to hide yourself in this world of pretend; when the paper's crumpled up, it can't be perfect again.

Offline

#55 2012-09-19 17:11:44

Sawakita
Administrator
Registered: 2010-10-16
Post 300/364

Re: Pokemon Red: Backsprites

Danny-E 33 wrote:

Success!

Glad you got it sorted.

stag019 wrote:

These are the kinda things people like Danny-E 33 and I need to learn. How to use a debugger. I never have before, and while I'm starting to understand how assembly works rather well, the difficult part is reverse engineering. You need to understand how to use a debugger, and then you need to understand how everything is stored in the game so that you know how to inject what code, and where.

Then try, experiment, get your hands dirty, make mistakes. That's how I did, and I'm pretty sure I'm not the only one, around here.

I know, one could say: "How can I learn if I don't know how to do this or that?", but when you'll realize how many people in the past had to guess and try things before they truly gained a certain knowledge, you'll agree that it's a good way to learn.

Last edited by Sawakita (2012-09-19 17:12:36)

Offline

#56 2012-09-20 02:23:46

Danny-E 33
Administrator
Registered: 2012-06-09
Post 134/1,024

Re: Pokemon Red: Backsprites

Sawakita wrote:
Danny-E 33 wrote:

Success!

Glad you got it sorted.

Thank you! I couldn't have done it with out you! Not for a long time, at least :P

Sawakita wrote:

Then try, experiment, get your hands dirty, make mistakes. That's how I did, and I'm pretty sure I'm not the only one, around here.

I know, one could say: "How can I learn if I don't know how to do this or that?", but when you'll realize how many people in the past had to guess and try things before they truly gained a certain knowledge, you'll agree that it's a good way to learn.

Well said, sir. :)


Red Hack: Pokémon Prototype

Total number of registered users: 7000+
Total number of active users: ~12

Offline

#57 2012-11-25 18:32:11

Danny-E 33
Administrator
Registered: 2012-06-09
Post 273/1,024

Re: Pokemon Red: Backsprites

Apparently, there is a seperate player back sprite loading routine for the Hall of Fame.
When I go through the Elite Four, and Oak brings me to the Hall of Fame, the player back sprite is still zoomed and pixely after it shows the rest of my party which displays the back sprites fine.
Do you think you could help me find the location of this routine and I'll see what I can do to fix it myself like the other player backsprite loading routine?


Red Hack: Pokémon Prototype

Total number of registered users: 7000+
Total number of active users: ~12

Offline

#58 2012-11-25 21:21:11

Sawakita
Administrator
Registered: 2010-10-16
Post 342/364

Re: Pokemon Red: Backsprites

There are several approaches you could try, but I'll cut it short and tell you the one I think is the best.

Put a breakpoint at 0x3e6d (the so called Predef routine) specifying the condition "a = 3"; the reason for doing this is that we want to break the flow when the routine that magnifies pics is called (do you already know how "Predef" routine works? 0x3e6d is called preventively putting the id of the predefined routine into a). At that point we should just have to go up one level in the stack of called routines, and we should then have found the wanted routine.

Offline

#59 2012-11-25 21:40:17

Danny-E 33
Administrator
Registered: 2012-06-09
Post 274/1,024

Re: Pokemon Red: Backsprites

So, are you talking about $429B? Which I belive I found that it is bank 1C?
I don't have enough time to look into right now, but I'll have a look tonight. Thanks for the help!


Red Hack: Pokémon Prototype

Total number of registered users: 7000+
Total number of active users: ~12

Offline

#60 2012-11-26 03:03:50

Danny-E 33
Administrator
Registered: 2012-06-09
Post 276/1,024

Re: Pokemon Red: Backsprites

Sawakita wrote:

Try focusing on the aspects that are similar to the pokemon's backsprite loading routine we have already hacked. Keep the OAM thingy as is and look rather at these ones:

;6CA3
ld a, 03
call 3E6D
...
;6CD5
ld de, 9310
call 16EA

which we know that can both be removed, if an appropriate, specific counter-measure is applied.

I don't see anything like this at 1C:429B...
There's actually:

ld a, $04
call $3E6D

at 1C:42A6, but that's actually never executed during the Hall of Fame scene...
I fear I may have picked the wrong routine when looking at the stack like you suggested...


Red Hack: Pokémon Prototype

Total number of registered users: 7000+
Total number of active users: ~12

Offline

#61 2012-11-26 21:36:43

Sawakita
Administrator
Registered: 2010-10-16
Post 346/364

Re: Pokemon Red: Backsprites

Same answer as here. Bear with me, please. :P

Offline

#62 2012-11-27 16:53:02

Danny-E 33
Administrator
Registered: 2012-06-09
Post 278/1,024

Re: Pokemon Red: Backsprites

Haha, no problem. :P

So as long as this routine resembles the other player backsprite loading routine and has those main components that we hacked before, I should be able to figure this out.

I'll try to take a look at this tonight and let you know if I have any problems.
Thanks alot!

EDIT: Oh! I have never tried using conditions with breakpoints before, but I wasn't able to get it to work.
I could get the address breakpoint to work, and I could get a seperate condition breakpoint to work when a = 3, but I couldn't get a address breakpoint to work with that condition. Is there something I'm not understanding?

Last edited by Danny-E 33 (2012-11-27 16:55:45)


Red Hack: Pokémon Prototype

Total number of registered users: 7000+
Total number of active users: ~12

Offline

#63 2012-11-27 21:39:06

Sawakita
Administrator
Registered: 2010-10-16
Post 348/364

Re: Pokemon Red: Backsprites

Danny-E 33 wrote:

EDIT: Oh! I have never tried using conditions with breakpoints before, but I wasn't able to get it to work.
I could get the address breakpoint to work, and I could get a seperate condition breakpoint to work when a = 3, but I couldn't get a address breakpoint to work with that condition. Is there something I'm not understanding?

I suspect this might be a matter of using the correct notation. Notation was changed between the various BGB versions: for example in 1.4.x you can simply write a=3 and it's accepted, while in older versions you might need to write a=$3.

Offline

#64 2012-11-28 02:04:56

Danny-E 33
Administrator
Registered: 2012-06-09
Post 280/1,024

Re: Pokemon Red: Backsprites

This was quite simple. Just changed the code at 1C:4365 to

ld a, $66
ld de, $9310
push de
jp $1670
nop
nop

Works great!

Thanks alot for all your help with the backsprite loading routines this far. I really think that should have covered everything.
I hope no more problems come up with any sprite loading. But I've been suprised before. ;)

EDIT: Oh yeah, and all I needed was to add the ($) to the condition and it worked fine. Thanks!

Last edited by Danny-E 33 (2012-11-29 16:50:35)


Red Hack: Pokémon Prototype

Total number of registered users: 7000+
Total number of active users: ~12

Offline

#65 2012-12-01 12:30:27

Sawakita
Administrator
Registered: 2010-10-16
Post 350/364

Re: Pokemon Red: Backsprites

I'm glad you got it sorted!

Offline

#66 2012-12-01 12:36:14

Danny-E 33
Administrator
Registered: 2012-06-09
Post 286/1,024

Re: Pokemon Red: Backsprites

Gosh, I'm really amazed at how much I've learned now. Especially compared to how uneducated I sounded in my very first post in this thread. I feel like I'm a whole new person.
Thank you so much.


Red Hack: Pokémon Prototype

Total number of registered users: 7000+
Total number of active users: ~12

Offline

Board footer

Powered by FluxBB