Skeetendo

’Cause all games were better on the GBC

You are not logged in.

#1 2011-06-22 17:37:15

Sherkel
Member
From: U.S. of A.
Registered: 2011-01-08
Post 2/43

Now about modifying sprite routines

I am trying to rearrange the trainer pic pointers so that the rival and Oak are switched. I have found the pointers with the ROM map, but I am having a bit of trouble, as the ROM map says that the sprites themselves are in Bank 13, but I see no pointers to bank 13.
Any help?

Last edited by Sherkel (2011-06-23 22:58:16)


Formerly known as Tombstoner

Offline

#2 2011-06-22 18:30:23

Mateo
Member
From: The Sims 4
Registered: 2009-11-25
Post 731/3,460

Re: Now about modifying sprite routines

Which version are you hacking? Since all versions from Red/Green through Crystal have sprites for a rival and for oak, we need a bit more information than that I'm afraid. But once I know which version you're hacking I'll be able to help more. Also, moving this out of the hacks section to idea discussion.

Offline

#3 2011-06-22 18:42:37

Sherkel
Member
From: U.S. of A.
Registered: 2011-01-08
Post 3/43

Re: Now about modifying sprite routines

It's RB. Thanks.


Formerly known as Tombstoner

Offline

#4 2011-06-22 19:25:39

Miksy91
Member
Registered: 2010-10-16
Post 420/2,306

Re: Now about modifying sprite routines

I didn't spend that much time with this but I believe there is one single pointer (not 3-byte) somewhere that leads to the whole trainer pic structure.
Pictures separated with FF, maybe ?

You might be able to find the asm that defines all that somewhere, Sawakita may know where it is as he knows a lot about rby anyways.

Last edited by Miksy91 (2011-06-22 19:26:07)

Offline

#5 2011-06-22 19:29:14

Sherkel
Member
From: U.S. of A.
Registered: 2011-01-08
Post 4/43

Re: Now about modifying sprite routines

Unfortunately, I know absolutely nothing when it comes to ASM.
I think I understand what you're saying at the beginning, but how would something like that work?


Formerly known as Tombstoner

Offline

#6 2011-06-22 19:50:10

Miksy91
Member
Registered: 2010-10-16
Post 421/2,306

Re: Now about modifying sprite routines

Well, I don't understand asm either...or actually only a couple of commands like 21 xx yy.
Anyway, for example in G/S pointer 6C 00 40 leads to the whole item name structure, each item separated with byte 50.

I dunno, the game is programmed to do so.

Offline

#7 2011-06-22 20:34:32

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

Re: Now about modifying sprite routines

TrainerType Header is a 5 byte long structure:
[1st-2nd byte] = Pointer to sprite (little-endian)
[3rd-4th byte] = payout coefficient (the curious thing about this value is that not only it's written in big-endian format, but also it's written in a pseudo decimal format, i.e. what you see in hexadecimal is actually the value in decimal. Example: 0x0010 means 10, not 16, 0x0099 means 99, not 153). To understand this better you could also give a look at the Payout explanation page at Bulbapedia.
[5th byte] = unused (or padding)?

Examples:

Youngster:      00 40  00 15  00
Bug Catcher:    C6 40  00 10  00
...
Lance:          1F 7B  00 99  00

Starting address of the table (north american versions):
Red/Blue  : 0x39914
Yellow      : 0x39893

The order is the same as the trainers' names list that follow the said data-table. So first entry is "YOUNGSTER", second is "BUG CATCHER" and so on. To swap sprites just swap the pointers.


What follows is code extracted from Blue (i.e. no guarantees for other versions' addresses).
The bank for sprites is hardcoded in the routine that begins at 0x3F057:

; $d033-$d034 contains pointer to the current trainer's sprite
; $d12b works as boolean flag:
; IF [$d12b]==0 goto bank 0x13 ( = bank of trainers' frontpics'),
; ELSE goto bank 0x04 ( = bank of hiro's frontpic) ["d12b > 0" when you're in a link-battle, thus requiring the player's frontpic to be loaded]
    ld a,[$d033]
    ld e,a
    ld a,[$d034]
    ld d,a
    ld a,[$d12b]
    and a
    ld a,$13
    jr z,.load_pic
    ld a,$04
.load_pic
    call $36eb
;  ...
;function at $36eb decompresses sprite located at:
;  address = value contained in de
;  bank    = value contained in a

Last edited by Sawakita (2011-06-23 21:02:54)

Offline

#8 2011-06-22 21:08:58

Sherkel
Member
From: U.S. of A.
Registered: 2011-01-08
Post 5/43

Re: Now about modifying sprite routines

Wow! Thanks!


Formerly known as Tombstoner

Offline

#9 2011-06-23 00:41:31

224/700

Re: Now about modifying sprite routines

Sawakita wrote:

[3rd-4th byte] = payout coefficient (the curious thing about this value is that not only it's written in big-endian format, but also it's written in a pseudo decimal format, i.e. what you see in hexadecimal is actually the value in decimal. Example: 0x0010 means 10, not 16, 0x0099 means 99, not 153). To understand this better you could also give a look at the Payout explanation page at Bulbapedia.

This is called BCD (binary‐coded decimal), and is used in a few places in Red, mostly money‐related. I have no idea why; I never liked BCD, because it’s easy to get undefined values (e.g., what does 0x1A mean?).

#10 2011-06-23 16:32:12

Sherkel
Member
From: U.S. of A.
Registered: 2011-01-08
Post 7/43

Re: Now about modifying sprite routines

I'm having another problem now. I'm trying to replace Blaine's sprite with Snorlax's. The trainer sprite pointer, as mentioned above, is only two bytes and the routine makes it go to bank 13, so I couldn't just change the pointer. Instead, I located Snorlax's sprite (at least, I'm pretty sure I did):
[C * 0x4000] + [0x5BEA - 0x4000] = 0x31BEA
Copied the first nine bytes there, and then located Blaine's sprite:
[0x13 * 0x4000] + [0x7150 - 0x4000] = 0x4F150
And then copied down those nine bytes. It showed a glitchy mess where Blaine's sprite should be, which means I edited the right location, but in the wrong way.
Can anyone help with this?


Formerly known as Tombstoner

Offline

#11 2011-06-23 17:36:50

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

Re: Now about modifying sprite routines

I'm having another problem now. I'm trying to replace Blaine's sprite with Snorlax's. The trainer sprite pointer, as mentioned above, is only two bytes and the routine makes it go to bank 13, so I couldn't just change the pointer. Instead, I located Snorlax's sprite (at least, I'm pretty sure I did):
[C * 0x4000] + [0x5BEA - 0x4000] = 0x31BEA
Copied the first nine bytes there, and then located Blaine's sprite:
[0x13 * 0x4000] + [0x7150 - 0x4000] = 0x4F150
And then copied down those nine bytes. It showed a glitchy mess where Blaine's sprite should be, which means I edited the right location, but in the wrong way.
Can anyone help with this?

Where did you get the value 0x5BEA from and why did you copy just the first 9 bytes?

RGBY compression is efficient, but 9 bytes result from an original size of 0x310 bytes would be too little, really. The correct pointer to Snorlax's sprite is 0x5B19, and the size of the compressed sprite is 0x1CC bytes (sprite is located at 0x31B19-0x31CE4). Notice that every compressed sprite begins with 0x55 or 0x66 or 0x77 (learn more by reading the documentation written by Tauwasser)

Also, Blaine's sprite is just 0x102 bytes large, so you can't just overwrite it with Snorlax's sprite, because you would corrupt the following sprite. To get rid of this trouble (considering there's not enough free space at the end of bank 0x13) you should rewrite the ASM routine so that it allows trainers' sprites to be located in various banks instead of only one.

Offline

#12 2011-06-23 17:41:49

Sherkel
Member
From: U.S. of A.
Registered: 2011-01-08
Post 8/43

Re: Now about modifying sprite routines

I calculated it wrong, and misread somewhere that compressed sprites are 9 bytes (it is actually just the header.)
So, seeing as I know nothing about ASM and don't want to trouble you or someone else to do it, should I just copy a different sprite?
EDIT: Wait. Shoot. I could just copy the sprite to bank 13 and repoint it, right?

Last edited by Sherkel (2011-06-23 17:42:48)


Formerly known as Tombstoner

Offline

#13 2011-06-23 17:49:59

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

Re: Now about modifying sprite routines

Tombstoner wrote:

I calculated it wrong, and misread somewhere that compressed sprites are 9 bytes (it is actually just the header.)
So, seeing as I know nothing about ASM and don't want to trouble you or someone else to do it, should I just copy a different sprite?
EDIT: Wait. Shoot. I could just copy the sprite to bank 13 and repoint it, right?

Actually the header is 9 bits, not bytes.

Anyway as I said, and you can see, the free space in bank 0x13 is small; smaller in fact than Blaine's sprite size (something like 0x5E bytes).

Offline

#14 2011-06-23 18:04:35

Sherkel
Member
From: U.S. of A.
Registered: 2011-01-08
Post 9/43

Re: Now about modifying sprite routines

Ah, I now see. :(
I guess I better go learn ASM and leave this for later.


Formerly known as Tombstoner

Offline

#15 2011-06-23 19:46:01

Sherkel
Member
From: U.S. of A.
Registered: 2011-01-08
Post 10/43

Re: Now about modifying sprite routines

Okay, after a bit of searching around, I managed to decipher most of that code you posted.
The only part I didn't understand was the line with
jr z,.load_pic
I used this document to find the opcodes, but didn't quite understand what jr meant.
Also, to make them available in multiple banks, could I just add another boolean flag, and make it so that when it's true it goes to another bank where the Snorlax sprite is?

Last edited by Sherkel (2011-06-23 19:52:17)


Formerly known as Tombstoner

Offline

#16 2011-06-23 20:25:53

Miksy91
Member
Registered: 2010-10-16
Post 426/2,306

Re: Now about modifying sprite routines

"JR - Jumps ahead a certain amount of bytes right after the command."

Offline

#17 2011-06-23 21:05:48

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

Re: Now about modifying sprite routines

First of all I apologize because, in the code I posted before, an important line was missing, right after "ld a,[$d12b]".
Anyway The mnemonic jr means relative jump, if you see its hexadecimal corresponding value it's clearer to understand (".loadpic" is just a label I gave to the address $705D). Here it's the code dumped with BGB:

ROMF:704b fa 33 d0         ld   a,(d033)
ROMF:704e 5f               ld   e,a
ROMF:704f fa 34 d0         ld   a,(d034)
ROMF:7052 57               ld   d,a
ROMF:7053 fa 2b d1         ld   a,(d12b)
ROMF:7056 a7               and  a,a       ;IF a==0 THEN zero flag is set
ROMF:7057 3e 13            ld   a,13
ROMF:7059 28 02            jr   z,705d
ROMF:705b 3e 04            ld   a,04
ROMF:705d cd eb 36         call 36eb
ROMF:7060 11 00 90         ld   de,9000
ROMF:7063 3e 77            ld   a,77
ROMF:7065 4f               ld   c,a
ROMF:7066 c3 72 16         jp   1672

As you can see the hex value is 28 02 which means: "if zero flag is set, jump to the address that is 2 byte ahead of the next command's address" (i.e. D75B + 2 = D75D).

About your edit: you could read RAM location $D059, which contains, when you're about fighting with a trainer, the trainer's ID. Then compare it to Blaine's ID (which should be $EF, if I'm not wrong): if matches then switch to bank where snorlax's sprite is located (of course Blaine's sprite pointer must point to Snorlax's sprite). The code could be something like this:

;
;Edited routine
;
    ld a,[$d033]
    ld e,a
    ld a,[$d034]
    ld d,a
    ld a,[$D059]
    cp a,$EF       ;if a==$EF then zero flag is set
    ld a,$0C       ;bank where Snorlax's pic is
    jr z,.loadpic
    ld a,($D12B)
    and a,a
    ld a,$13
    jr z,.loadpic
    ld a,$04
.loadpic
    call $36eb
    ld de,$9000
    ld a,$77
    ld c,a
    jp $1672

Got it?

Last edited by Sawakita (2011-06-23 21:07:41)

Offline

#18 2011-06-23 22:22:17

Sherkel
Member
From: U.S. of A.
Registered: 2011-01-08
Post 11/43

Re: Now about modifying sprite routines

Wow, thanks for all your help! I really appreciate it.
I hate to bother you again, but...I've never done any sort of ASM before this. How do I turn that code into hex which I can type into the ROM?
EDIT: OH WAIT--I should use this, right?Ah, now I can finally get this thing going.
Just before I put it in, would these hex codes be correct?

ld a,[$d033]    fa 33 d0
    ld e,a        5f
    ld a,[$d034]    fa 34 d0
    ld d,a        57
    ld a,[$D059]    fa 59 d0
    cp a,$EF    bf ef
    ld a,$0C    3e 0c
    jr z,.loadpic    28 06
    ld a,($D12B)    fa 2b d1
    and a,a        a7
    ld a,$13        3e 13
    jr z,.loadpic    28 02
    ld a,$04        3e 04
.loadpic
    call $36eb    cd eb 36
    ld de,$9000    11 00 90
    ld a,$77        3e 77
    ld c,a        4f
    jp $1672    c3 72 16

Hmm...won't there not be enough space for this? Perhaps I could try jumps...

Last edited by Sherkel (2011-06-24 01:19:49)


Formerly known as Tombstoner

Offline

#19 2011-06-24 11:39:02

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

Re: Now about modifying sprite routines

You could do it that way in a hex editor or you could try this program made by Jigglypuff. It doesn't support labels, but it's certainly faster (and less error-prone) than writing it in plain hexadecimal. I used to use that program when I started hacking, it's not bad for small ASM hacks.

In fact there was a couple of errors in your menmonic-to-hex conversion (lines in bold):
    ld a,[$d033]    fa 33 d0
    ld e,a        5f
    ld a,[$d034]    fa 34 d0
    ld d,a        57
    ld a,[$D059]    fa 59 d0
    cp a,$EF    FE EF
    ld a,$0C    3e 0c
    jr z,.loadpic    28 0A
    ld a,($D12B)    fa 2b d1
    and a,a        a7
    ld a,$13        3e 13
    jr z,.loadpic    28 02
    ld a,$04        3e 04
.loadpic
    call $36eb    cd eb 36
    ld de,$9000    11 00 90
    ld a,$77        3e 77
    ld c,a        4f
    jp $1672    c3 72 16

Tombstoner wrote:

mm...won't there not be enough space for this? Perhaps I could try jumps...

Yes, basically you could just overwrite, in the original routine, the first instruction ("ld a,[$d033]") with a jp to your new routine address, which you have to rewrite in some free space in the same bank the original routine was.

Offline

#20 2011-06-24 13:21:42

Sherkel
Member
From: U.S. of A.
Registered: 2011-01-08
Post 13/43

Re: Now about modifying sprite routines

Okay. I've tried everything you've said, but Blaine's sprite is still a glitchy mess. Here's what I did:
Changed the pointer for Blaine's sprite from $5071 to $5B19
Changed the first instruction from ld a,[$d033] (fa 33 d0) to jp 7bc8 (c3 c8 7b)
Added the whole new routine at address 0F:7BC8
I don't want to bother you any more, but since I may be so close I want to make this work.


Formerly known as Tombstoner

Offline

#21 2011-06-24 18:34:52

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

Re: Now about modifying sprite routines

Changed the pointer for Blaine's sprite from $5071 to $5B19

Notice that $5071 is in little-endian format, while $5B19 is big-endian, pay attention not confusing them.

Anyway I might have found what the problem is: looking at your hack's thread it seems that you replaced R/B sprites with Yellow ones (you didn't say anything about it here in this thread, so I took for granted that the sprites and their pointers were unchanged). If this is the case pokemon sprites' pointers are different (in fact Snorlax's sprite pointer is 0x5BEA in a Yellow ROM). Of course, since you didnt say anything about the fact that you changed the sprites, I couldn't have any chance to know it. So, well, this should fix the problem: take the pointer you find in Snorlax's base stats data-table.

Last edited by Sawakita (2011-06-24 19:56:34)

Offline

#22 2011-06-24 19:07:20

Sherkel
Member
From: U.S. of A.
Registered: 2011-01-08
Post 15/43

Re: Now about modifying sprite routines

Hahaha! THAT'S how I got 5BEA earlier! I didn't think I calculated that wrong! Oh my gosh, thanks for bearing with me.


Formerly known as Tombstoner

Offline

#23 2011-06-24 19:31:17

Sherkel
Member
From: U.S. of A.
Registered: 2011-01-08
Post 16/43

Re: Now about modifying sprite routines

Put the pointer in in the correct form, still a glitchy mess...arghhh. This seems hopeless now; I hate to have wasted all of our time. I'm going to do one last ditch effort which is changing the jp 7bc8 to jp 3bc8, because the position in the bank the program gave and the one Calculator gave are different...
EDIT: Darn, says unknown opcode...and if I'm reading BGB's debugger correctly, it says it's at 0114 in bank 0...

Last edited by Sherkel (2011-06-24 19:35:18)


Formerly known as Tombstoner

Offline

#24 2011-06-24 19:59:21

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

Re: Now about modifying sprite routines

No, jp 7BC8 was correct (check this link to see how Game Boy's Memory Map is structured). Also, I tried everything by myself and it worked perfectly. If you want, you can make an .ips patch of your hack and send it to me and I'll see what's wrong with it for you.

Last edited by Sawakita (2011-06-24 19:59:58)

Offline

#25 2011-06-24 20:01:47

Sherkel
Member
From: U.S. of A.
Registered: 2011-01-08
Post 17/43

Re: Now about modifying sprite routines

That would be very much appreciated. I'll do it right now.
EDIT: Sent.

Last edited by Sherkel (2011-06-24 20:07:16)


Formerly known as Tombstoner

Offline

Board footer

Powered by FluxBB