Skeetendo

’Cause all games were better on the GBC

You are not logged in.

#26 2012-09-02 11:12:04

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

Re: Pokemon Red: Palettes

I had a hunch that the reason trainers all use that pallete is because their Pokemon ID is theoretically 0x00. I based this hunch on the following from the disassembly:

MonsterPalettes: ; 65C8
    db PAL_MEWMON    ; MISSINGNO
    db PAL_GREENMON  ; BULBASAUR

Any other list in Pokedex order starts with the first entry (entry 0 if you're a computer programmer) as Bulbasaur. However, this time 0 and 0 line up.

This hunch was correct.

Set an access breakpoint on 1C:65C8 for both read and write. Get into a trainer battle and wait for the debugger to interrupt. It should do it after the trainer sprites slide across the screen, right before they hit their final position.

Look around the (daunting, I may admit) screen and see if you can find the reason it broke there (you're looking for your 65C8). A hint is that it should be in the register list at the top right. From there, you should step forward one line at a time (Run -> Run to next line, or F3) and watch what values are loaded where. The value for PAL_MEWMON (0x10) should be loaded into one of the registers. Try changing it by double clicking on the register pair, and typing in a new value (if you just add one to get 0x11, you'll be using PAL_BLUEMON). Keep in mind that you only want to change one value of the pair and for the other you should retype what was already there. Hopefully you should notice something changing colors.

Next is finding how that routine started in the first place. Thankfully, you don't have to Run forward long before you find a "ret" command. Once you return to the previous section, look at the line above. It should be a "call" statement, which you should remember.

I'm gonna make this next part pretty easy. Looking around that area, there's something that might be slightly recognizable.
ld hl, CFD8
If you've ever used Gameshark before, you may remember the wild Pokemon code is 01xxD8CF, because this is accessing the same RAM address. This information can be found here, along with the other address, D014, being your current Pokemon's number. Now it should be pretty clear which call does frontsprites and which does backsprites. And once again like I said, this same code is called whether its a Pokemon or a trainer, because trainers just have ID 0. You can actually use the fact that trainers are ID 0 to your advantage later when you start writing code. Hopefully, you see where I'm going with this. If the ID is 0, you'll want to use the trainer ID instead of Pokemon ID in in the lookup, as well use a separate table.

So the very last part before I end this post is how do we find where the trainer ID is stored. If you've ever used the Gameshark code I was talking about earlier, you should know that using that in conjunction with 0xC9 or above makes you face a trainer. So why is it 0 then whenever palettes are loaded? Well, let's watch it's value in the RAM.

Go into access breakpoints again, disable the one you used before, and set one for read and write on CFD8. Next, reset the Gameboy, and get into another trainer fight. When the battle starts, you should see the trainer's ID being loaded from a register, into CFD8. That's cool, but not that important. Click back to the main screen to start running again. It should break immediately. You should see this value being loaded back into a register, have C8 subtracted from it, a jp command that should never execute for a trainer, and then you'll see this value loaded somewhere into RAM. Note this address down too, then go back to the game.

After the battle starts, it should break yet again. This time, you'll see 0 being loaded into CFD8. Why it does it, who knows, but it's just in time because the next time the debugger breaks should be right around the code I had you looking at in the beginning.

Now, hopefully you should have enough to go on here. If not, tell me everything you've done so far, what addresses I told you to note down, etc., and we'll go from there.

Just to let you know, I've got trainers loading a custom palette based on their ID. The trainer backsprite still uses the same one but that shouldn't be much more effort now.


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

Offline

#27 2012-09-02 15:24:18

Danny-E 33
Administrator
Registered: 2012-06-09
Post 98/1,025

Re: Pokemon Red: Palettes

Gosh, I want to sit down and start this right now! But unfortunately, I'm getting ready for work.. Gah, I hate growing up D:
Thank you so much for the shove in the right direction :) I think now I can finish this out. I'll start workin on this around 6 tonight.
Thanks alot for your help!


Red Hack: Pokémon Prototype

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

Offline

#28 2012-09-02 16:53:13

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

Re: Pokemon Red: Palettes

That's funny because I forgot to mention that I'm working today myself, and so I won't be able to help or anything until either after 10pm or maybe on break.


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

Offline

#29 2012-09-03 03:39:42

Danny-E 33
Administrator
Registered: 2012-06-09
Post 99/1,025

Re: Pokemon Red: Palettes

stag019 wrote:

Set an access breakpoint on 1C:65C8 for both read and write. Get into a trainer battle and wait for the debugger to interrupt. It should do it after the trainer sprites slide across the screen, right before they hit their final position.

Hey! I got a break to work for once! :P

stag019 wrote:

Look around the (daunting, I may admit) screen and see if you can find the reason it broke there (you're looking for your 65C8). A hint is that it should be in the register list at the top right. From there, you should step forward one line at a time (Run -> Run to next line, or F3) and watch what values are loaded where. The value for PAL_MEWMON (0x10) should be loaded into one of the registers. Try changing it by double clicking on the register pair, and typing in a new value (if you just add one to get 0x11, you'll be using PAL_BLUEMON). Keep in mind that you only want to change one value of the pair and for the other you should retype what was already there. Hopefully you should notice something changing colors.

Okay, so I saw 10 being loaded into register a once which was for the player back sprite, then again a few lines later for the enemy front sprite. I changed both of those to 11 once they were in register a, and saw them copied into register b. For my hack, this loaded Bulbasaur's custom palette, instead of the default BLUEMON palette.

stag019 wrote:

Next is finding how that routine started in the first place. Thankfully, you don't have to Run forward long before you find a "ret" command. Once you return to the previous section, look at the line above. It should be a "call" statement, which you should remember.

Alright, right after I saw the first "ret" command, I followed it and went up one line and saw 1C:5E22 Call 5F97, correct?

stag019 wrote:

I'm gonna make this next part pretty easy. Looking around that area, there's something that might be slightly recognizable.
ld hl, CFD8
If you've ever used Gameshark before, you may remember the wild Pokemon code is 01xxD8CF, because this is accessing the same RAM address. This information can be found here, along with the other address, D014, being your current Pokemon's number. Now it should be pretty clear which call does frontsprites and which does backsprites. And once again like I said, this same code is called whether its a Pokemon or a trainer, because trainers just have ID 0. You can actually use the fact that trainers are ID 0 to your advantage later when you start writing code. Hopefully, you see where I'm going with this. If the ID is 0, you'll want to use the trainer ID instead of Pokemon ID in in the lookup, as well use a separate table.

I didn't quite follow what you meant here. Like, how this can be used to my advantage when I write the code and use a seperate table. And I'm not sure what you meant by, it should be pretty clear which call is for the front sprite and which call is for the back sprite.***

***I took a look at the RAM Map again. Are you saying when it references CFD8, it's using the ID for the enemy's front sprite (Pokemon, trainer, or both?) and when it uses D014, it's using the ID for your back sprite (Pokemon, trainer, or both?)

stag019 wrote:

So the very last part before I end this post is how do we find where the trainer ID is stored. If you've ever used the Gameshark code I was talking about earlier, you should know that using that in conjunction with 0xC9 or above makes you face a trainer. So why is it 0 then whenever palettes are loaded? Well, let's watch it's value in the RAM.

Go into access breakpoints again, disable the one you used before, and set one for read and write on CFD8. Next, reset the Gameboy, and get into another trainer fight. When the battle starts, you should see the trainer's ID being loaded from a register, into CFD8. That's cool, but not that important.

Here I saw DF being loaded from register a to CFD8. DF should be the trainer ID for Birdkeeper, right?

stag019 wrote:

Click back to the main screen to start running again. It should break immediately. You should see this value being loaded back into a register, have C8 subtracted from it, a jp command that should never execute for a trainer, and then you'll see this value loaded somewhere into RAM. Note this address down too, then go back to the game.

Here I wrote down 0F:6F58 ld [D031],a, is that correct?

stag019 wrote:

After the battle starts, it should break yet again. This time, you'll see 0 being loaded into CFD8.

Okay, I see 0 being loaded from register a to CFD8 at 0F:6F6D.

stag019 wrote:

Why it does it, who knows, but it's just in time because the next time the debugger breaks should be right around the code I had you looking at in the beginning.

Okay, it broke at 1C:5F9C, which is slightly after the code we looked at at the beginning around 1C:5E22. Now why is this important?

stag019 wrote:

Now, hopefully you should have enough to go on here. If not, tell me everything you've done so far, what addresses I told you to note down, etc., and we'll go from there.

Well, I imagine somewhere I have to add a call to a new routine where it secifies a unique palette for each trainer id, but I don't know how to decide where this call goes or where to call to.. :P

stag019 wrote:

Just to let you know, I've got trainers loading a custom palette based on their ID. The trainer backsprite still uses the same one but that shouldn't be much more effort now.

Well I'm glad to know it's totally fesable! :) Really, thank you so much for teaching me how to use a debugger by walking through a real example with me :)

Last edited by Danny-E 33 (2012-09-03 20:34:10)


Red Hack: Pokémon Prototype

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

Offline

#30 2012-09-03 21:00:51

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

Re: Pokemon Red: Palettes

I worked on it a little bit more after that post and got the back picture loading a palette (even Old Man loads a different palette).

First, I'll answer every question in your post....

Alright, right after I saw the first "ret" command, I followed it and went up one line and saw 1C:5E22 Call 5F97, correct?

Yes

***I took a look at the RAM Map again. Are you saying when it references CFD8, it's using the ID for the enemy's front sprite (Pokemon, trainer, or both?) and when it uses D014, it's using the ID for your back sprite (Pokemon, trainer, or both?)

Not quite. When it's referencing those two addresses, it's asking for the ID of the Pokemon/trainer itself (not an ID for a sprite, which doesn't exist). However, like I said, for any trainer, the ID located there is 0.

Here I saw DF being loaded from register a to CFD8. DF should be the trainer ID for Birdkeeper, right?

According to the hex list, yes.

Here I wrote down 0F:6F58 ld [D031],a, is that correct?

Yes.

Okay, it broke at 1C:5F9C, which is slightly after the code we looked at at the beginning around 1C:5E22. Now why is this important?

It's not really, I'm just showing you how CFD8 is cleared of the trainer's ID before the palette is loaded.

And now to try to get you to see what you need to do next.

Well, I imagine somewhere I have to add a call to a new routine where it secifies a unique palette for each trainer id, but I don't know how to decide where this call goes or where to call to.. :P

Look at the code between 5FAA and 5FB5. If I told you D11E was the ID for the Pokemon, and you already know 65C8 is the start of the table of palettes for each Pokemon, can you tell me what the code does. Tell me what each line does to what, and what the important thing at the end is.

Edit: Also if you'd like this to go faster, join the IRC channel sometime when I'm there, and I can help you out.

Last edited by stag019 (2012-09-03 22:08:09)


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

Offline

#31 2012-09-05 04:18:27

Danny-E 33
Administrator
Registered: 2012-06-09
Post 100/1,025

Re: Pokemon Red: Palettes

stag019 wrote:

Look at the code between 5FAA and 5FB5. If I told you D11E was the ID for the Pokemon, and you already know 65C8 is the start of the table of palettes for each Pokemon, can you tell me what the code does. Tell me what each line does to what, and what the important thing at the end is.

It starts by loading the ID of the Pokemon into a. Does D11E currently contain the correct ID of the trainer at the time that this is being accessed? Or have any trainer ID's already been replaced with 00?*

Then it stores a into e.

Then it puts 00 into d.

Then it gives register pair hl the address 65C8. The palette assingment table, right? (not the actual table of the palettes that the Pokemon use, only a list of the ID's of the palettes that each Pokemon is assigned. But isn't this list in Pokedex order, not internal ID order? So at some point, the ID stored in D11E had to have already been replaced with the Pokedex number, instead of using the default internal ID, right? Although, I'm not sure if that really matters.)

Then it adds hl and de. At this point it should be 65C8+00ee where ee is the ID loaded from D11E. And I think this value is stored in hl, correct?

Then it loads a with the byte from the address specified from hl. Which should be the byte of the palette assingment table that corresponds to the ID of the Pokemon being loaded.

*I've concluded that at this point, the trainer ID has to have been overwritten with 00 by now so that it does 65C8+0000 so that hl will still contain 65C8 so register a will load 10 from the very beginning of the palette assignment table, which is the palette ID for trainers, Mew, and Mewtwo.
Could the correct ID of the trainer being loaded still be found in D031? Except it would be that value plus C8 for the actual trainer ID? Since there was the sub command to see if the c flag would be set or unset for the jp c command to determine if a Pokemon is being loaded, which is why that code should never be accessed with a trainer. Does that work?

So this has helped me understand the process of how a palette is loaded for a sprite, but I'm still a bit iffy about where/how to properly inject this new code.

So in the beginning of this string of code you talked about (5FAA-5FB5), I can add a call to free space in bank 1C where it can do a quick check to see if the ID>=C9 and then if that's false, continue with the code that's already there. Otherwise, replace hl with the start of a new array of palette ID's. Then subtract C9 from a and put that result in e. Put 00 in d. Then add hl and de. Put the byte at that address into a, which should be the ID of the palette for any trainer ID from C9 onward.

Is that at all close to what you had in mind? If not, feel free to point out whenever my thought process is illogical, inconvenient, or unefficient.

Thank you for driving me so hard to solve my problems for myself :)) I've given this my best educated guess, so hopefully you can tell me what ideas would make this plan better, cause I'm sure I haven't come up with the most accurate or efficient plan yet. And when you describe your reasonable approach to this problem, it will show me how to be an even better problem solver. :)

(Also, keep in mind, I've used up every byte of free space in bank 1C whenever I repointed the table of actual palette data so I could include unique palettes for every Pokemon. The only free space in bank 1C is where that table of palette data used to be :P )

Last edited by Danny-E 33 (2012-09-05 05:26:16)


Red Hack: Pokémon Prototype

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

Offline

#32 2012-09-05 21:39:56

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

Re: Pokemon Red: Palettes

Danny-E 33 wrote:

Could the correct ID of the trainer being loaded still be found in D031? Except it would be that value plus C8 for the actual trainer ID? Since there was the sub command to see if the c flag would be set or unset for the jp c command to determine if a Pokemon is being loaded, which is why that code should never be accessed with a trainer. Does that work?

Yes, except for one thing. When the sub opcode is run, it doesn't just use it for the comparison, it actually already did the subtraction for you. Therefore, the value in D031 already contains the trainer ID with C8 subtracted from it.

But yeah I realized now I lied and that D11E does in fact contain the Pokemon's Pokedex number, (or 0 for a trainer) and not their ID number.

Without making things any more complicated, you'll want to copy the code from 5F97 all the way down to and including it's return opcode at 5FB5. That way, since you already know two pointers to 5F97, you can simply change those two rather than adding your own jumps or calls. However, as I mentioned before, the only relevant part is the 5FAA part to the end.

Go back into BGB and make it break at 1C:65C8 like you did in the beginning. Once it breaks, go to file, save ASM, and select a file, start address (5F97), and length (1F). This will give you a file to work on your assembly with. You're going to want to write it twice, once for front pictures (which will deal with the whole loading a value from a table) and once for back pictures (which you'll simply load in the correct pallet id without worrying about a table). Keep in mind that if you organize the code just the right way, you won't have to rewrite any of the existing code there at all. My front picture code moves one line, and adds 4 lines. My back picture code moves the same line, and adds 9 lines (although this code also keep in mind the old man that teaches you to catch a Weedle and gives him a different palette).

Try writing some code out and putting it in the game. If you're unable to get it to work, show me what you've written here.


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

Offline

#33 2012-09-06 00:35:44

Danny-E 33
Administrator
Registered: 2012-06-09
Post 103/1,025

Re: Pokemon Red: Palettes

stag019 wrote:

Yes, except for one thing. When the sub opcode is run, it doesn't just use it for the comparison, it actually already did the subtraction for you. Therefore, the value in D031 already contains the trainer ID with C8 subtracted from it.

Right, exactly. That's what I was saying. Since it was sub command and not just a cp command. But now I wonder, can this be changed to a cp command so that the value is never overwritten and C8 will never have to be readded to it? Was there any other purpose the sub had besides setting/unsetting the c flag for jp c command?

And your post confused me just a bit...

stag019 wrote:

You're going to want to write it twice, once for front pictures (which will deal with the whole loading a value from a table) and once for back pictures (which you'll simply load in the correct pallet id without worrying about a table).

I don't get what you're saying I need to write twice. I don't understand what "it" is or how the routine should differ between the front or back sprite.

Are you saying that the code I'm copying (5F97-5FB5) needs to be copied twice back to back in the rom? The first copy will be accessed for front sprites and the second time will be accessed for back sprites?

stag019 wrote:

My front picture code moves one line, and adds 4 lines. My back picture code moves the same line, and adds 9 lines

Umm, what do you mean by moves one line and moves the same line?

Are you saying your copy of that code that is for the front sprites puts one line out of order from how it used to be, and then 4 lines added in? But your copy for the back sprites puts that same line out of order and then add 9 lines into it?

stag019 wrote:

Try writing some code out and putting it in the game. If you're unable to get it to work, show me what you've written here.

Alright, here I go! I'll let you know how this goes in just a bit :)


Red Hack: Pokémon Prototype

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

Offline

#34 2012-09-06 00:40:50

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

Re: Pokemon Red: Palettes

With my code, C8 doesn't need added to it. It's actually better that the C8 is already subtracted off. Therefore, the first entry (entry 0) in the palette table will be unused (or MissingNo. :P), the second entry (entry 1) will be used for Youngster, etc.

I didn't need to alter any code other than the one routine (5F97-5FB5). And yes, I'm saying you're going to want to copy that into the ROM twice (after you alter it).

And about the lines thing, yes, again, you asked the question then answered it correctly yourself.

And let me know how it goes. I'm in the IRC channel right now if you want to talk about it in realtime.


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

Offline

#35 2012-09-06 00:54:23

Danny-E 33
Administrator
Registered: 2012-06-09
Post 104/1,025

Re: Pokemon Red: Palettes

stag019 wrote:

With my code, C8 doesn't need added to it. It's actually better that the C8 is already subtracted off. Therefore, the first entry (entry 0) in the palette table will be unused (or MissingNo. :P), the second entry (entry 1) will be used for Youngster, etc.

Derp! I should have thought of that :P haha

stag019 wrote:

yes, again, you asked the question then answered it correctly yourself.

Sorry, I tend to second guess myself alot which just makes me redundant..

stag019 wrote:

I'm in the IRC channel right now if you want to talk about it in realtime.

...I don't know what an IRC Channel is... :P


Red Hack: Pokémon Prototype

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

Offline

#36 2012-09-06 00:56:25

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

Re: Pokemon Red: Palettes

Danny-E 33 wrote:

...I don't know what an IRC Channel is... :P

From that thread...

stag019 wrote:

The "official" Skeetendo IRC channel is located at  irc://nucleus.kafuka.org/#skeetendo.

If you've never used any IRC client before, I recommend googling for mIRC. I've never actually used it before, but I've heard great things of it. Also, it should hopefully allow the above link to work as soon as it installs, so anyone on the channel can help you become familiar with IRC if need be.

IIMarckus wrote:

Maybe XChat instead, which is open source and not nagware. (Disclaimer: I’ve used neither one.)

stag019 wrote:

Another client you can use, if you don't want to install a program, is Mibbit. It works directly in your web browser.


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

Offline

#37 2012-09-06 06:30:11

Danny-E 33
Administrator
Registered: 2012-06-09
Post 105/1,025

Re: Pokemon Red: Palettes

So I've written out the new code for the copy I need to make for the front sprites, which turned out 4 lines longer and now the ld hl, $65C8 command is moved towards the beginning of that code, so that's promising.

But I haven't been able to test it, cause I'm still trying successfully repoint the original code to freespace without changing anything in the code. I'm just trying move the already existing code and get the game to work just the same.

First I copied the 1F bytes from 71F97-71FB5 to 72660. We talked about a pointer to that original location that is located at 1C:5E22, but you said there were two pointers. I found another one at 1C:5E18. Is that the one you were talking about? I changed both of those to 6660 (but in little-endian), which is the pointer for 72660.

Then when I tested to make sure the game still ran just like normal before I continued, the palettes were all screwed up. If I viewed an enty in my Pokedex or started a battle, the palettes were a mess... I put some breakpoints in the original location of the code that I moved and found a pointer at 1C:5E91 that points to 1C:5F9D which is in the middle of the code I copy/pasted. (but you had to have known about that pointer by now, right?)

I changed that pointer to 6666, but I'm not sure it changed anything.. I tried this on a clean Red rom, but I got the same results... is there a pointer I'm missing?

The more I think about it, the less it makes sense that repointing the routine doesn't work right. The only thing I can think of is there must be another call accessing that routine other than the two calls to 5F97 and the one call to 5F9D. But I can't find any other kind of way that the routine's original location is being accessed when I go looking for one with execution breakpoints. Using an execution breakpoint worked the first time when I set one at 5FB4. It broke, then I followed the ret command and went up a line and found that call at 5E91. But it doesn't break anymore, so I don't think there are any more calls to it... and now I don't know what to try.

Last edited by Danny-E 33 (2012-09-06 15:45:54)


Red Hack: Pokémon Prototype

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

Offline

#38 2012-09-06 20:25:57

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

Re: Pokemon Red: Palettes

I don't know what to tell you. On an unmodified Red rom, I copied the same bytes you stated and pasted them to 0x73BA0, and changed those two pointers to point there any everything worked fine for me.

(Also, keep in mind, I've used up every byte of free space in bank 1C whenever I repointed the table of actual palette data so I could include unique palettes for every Pokemon. The only free space in bank 1C is where that table of palette data used to be :P )

How exactly did you do this? Perhaps something messed up with this code that caused the other code not to load right?


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

Offline

#39 2012-09-06 23:17:38

Danny-E 33
Administrator
Registered: 2012-06-09
Post 106/1,025

Re: Pokemon Red: Palettes

That's very strange... I did this process again, on a clean Red rom like I said, and I actually used 0x73BA0 too. Then changed those two pointers that point to the beginning of the code, but this time using the pointer A0 7B of course, instead of 60 66 like before.

But it looked exactly like it did in my hack file. Anything that was supposed to be black was black, but anything that was supposed to white was black too.. and every sprite used the route palette (palette id 0).

Then I found and changed the pointer I found that points to the middle of that code, hoping this would fix something but it didn't look any different.

Since I tried this twice, once on a clean rom, I doubt my custom palette table had anything to do with it since I got the exact same result. I don't know. I'll start it over again in a little while when I'm back at my own computer.

EDIT: Wow. So I started over and when I looked back at the last time I did it, I realized I changed bytes 71E1A and 71E1B to 60 66, instead of bytes 71E19 and 71E1A... >.<
Well it's working now.

But I've decided the other pointer I mentioned, at 71E91 that points to 71F9D, does have to be corrected. The only way it would be working for you if you didn't fix that pointer would be if you didn't clear the original routine's location with 00's and then it would still accurately read the old code whenever it is called using that pointer.

However, I don't think that call would ever be used for a trainer sprite, so there's no harm in leaving that code and pointer the way they are.

Last edited by Danny-E 33 (2012-09-07 03:48:01)


Red Hack: Pokémon Prototype

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

Offline

#40 2012-09-07 04:16:49

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

Re: Pokemon Red: Palettes

Danny-E 33 wrote:

EDIT: Wow. So I started over and when I looked back at the last time I did it, I realized I changed bytes 71E1A and 71E1B to 60 66, instead of bytes 71E19 and 71E1A... >.<
Well it's working now.

But I've decided the other pointer I mentioned, at 71E91 that points to 71F9D, does have to be corrected. The only way it would be working for you if you didn't fix that pointer would be if you didn't clear the original routine's location with 00's and then it would still accurately read the old code whenever it is called using that pointer.

However, I don't think that call would ever be used for a trainer sprite, so there's no harm in leaving that code and pointer the way they are.

Yes, that's exactly what I did. I figured it was easier that way. :P

So, have you written a custom routine that works, or did you just succeed in repointing the old routine? If you need any help on writing the custom routine, let me know what you have so far.


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

Offline

#41 2012-09-07 04:44:57

Danny-E 33
Administrator
Registered: 2012-06-09
Post 107/1,025

Re: Pokemon Red: Palettes

Well during my last post, I had only succeeded in repointing the old routine. I wrote my new routine during school today! :P I just hadn't had the chance to test it yet.

But it worked! Here's the code I used:

ld a, [D11E] ; FA 1E D1
ld hl, $65C8 ; 21 C8 65
cp 0         ; FE 00
jr nz $06    ; 20 06
ld a, [D031] ; FA 31 D0
ld hl, $6689 ; 21 89 66
ld e, a      ; 5F
ld d, $00    ; 16 00
add hl, de   ; 19
ld a, [hl]   ; 7E
ret          ; C9

The ret command is followed immediately by a 0x30 byte long table to specify a palette number for each of the 2F trainer ID's, plus the extra byte at the beginning of the table for ID C8, which is unused.

But I made a couple of observations. I noticed the player back sprite copied the palette of the enemy trainer sprite, which I now see why you say it is necessary to copy that code twice so that the player can load a unique palette. But also, when I played around with that first byte of the table that isn't associated with any trainer ID, it determined the palette of the player back sprite palette during wild Pokemon battles. That also meant that byte determines the palette for the old man back sprite which is always considered a wild Pokemon battle, so there's no need to worry about the old man mimicking the enemy palette since the enemy will never be a trainer.

However, I don't know where to go with this second copy of the code, how to call to it, how it should only be accessed when determining the player's back sprite palette, or how to alter the code to properly load a palette for the player.

Thank you so much for all your help so far! I'm thrilled I got this working so I can fully duplicate the GSC sprites in a gen 1 hack! :D

Last edited by Danny-E 33 (2012-09-16 06:34:33)


Red Hack: Pokémon Prototype

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

Offline

#42 2012-09-07 04:48:05

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

Re: Pokemon Red: Palettes

Remember when I said there was two pointers that needed changing? The one that is preceded by the DFC8 is used for front pictures, the other one is for back pictures. Copy the code, again, and rewrite is so that instead of

ld a, [D031] ; FA 31 D0
ld hl, $6689 ; 21 89 66

you simply load whichever palette ID you want into register a and then return immediately. Then change only the one pointer to point to that new routine instead of the old one.


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

Offline

#43 2012-09-07 05:11:57

Danny-E 33
Administrator
Registered: 2012-06-09
Post 108/1,025

Re: Pokemon Red: Palettes

Awesome! I got that working too without too much difficulty :)

But now I noticed that the black screen with palette 0 thing still happens when you view a Pokemon's stats in your party, even though it doesn't do it anymore for a Pokedex entry. Is there a way to set a breakpoint for when the a button is pressed or something so I can try to find where the call to the old routine's location is?


Red Hack: Pokémon Prototype

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

Offline

#44 2012-09-07 05:16:28

Danny-E 33
Administrator
Registered: 2012-06-09
Post 109/1,025

Re: Pokemon Red: Palettes

Nevermind. It's at 0x71E64 :)


Red Hack: Pokémon Prototype

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

Offline

#45 2012-09-07 05:21:13

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

Re: Pokemon Red: Palettes

So you've gotten this completely working then? If so, awesome, my job is accomplished.

Also, here's the data you might want for Old Man. Check RAM address D05A. If it's value is exactly 1, then the back sprite is old man. Otherwise, it is the player (0 for a normal battle, and 2 for a safari zone battle).


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

Offline

#46 2012-09-07 05:26:06

Miksy91
Member
Registered: 2010-10-16
Post 1,089/2,311

Re: Pokemon Red: Palettes

Nice job Danny!
Haven't been keeping an eye on this much but congratulations on getting your own code to work!

Offline

#47 2012-09-07 05:27:07

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

Re: Pokemon Red: Palettes

What's even better is that his code is exactly the same as I wrote. With just a little hint, he only needed to add and move a few lines. And he did it by himself, I just sorta showed him where everything was.


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

Offline

#48 2012-09-07 05:30:28

Danny-E 33
Administrator
Registered: 2012-06-09
Post 110/1,025

Re: Pokemon Red: Palettes

I found yet another reference to the middle of that code at 0x71F2E! I'm not sure in what instance this was intended to load sprites (perhaps Hall of Fame, or some other more unique case) but just like I stumbled upon the pointer to the middle of the code for a Pokedex page, or the pointer for the stats of a Pokemon in your party, I'm sure I eventually would have found a problem when some sprites were loaded and the palettes were all messed up because the pointer at 0x71F2E would point to 00's :P so I'm glad I avoided having that frustration later.

And yes, I believe everything is working seemlessly now :) thank you so much for all your wisdom and, more importantly, your patience. :)


Red Hack: Pokémon Prototype

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

Offline

#49 2012-09-07 06:24:21

Danny-E 33
Administrator
Registered: 2012-06-09
Post 111/1,025

Re: Pokemon Red: Palettes

Miksy91 wrote:

Nice job Danny!
Haven't been keeping an eye on this much but congratulations on getting your own code to work!

Thank you! Every bit I do, I feel more and more confident with asm. I feel like I've come a long way from my simple sprite bank loading routine! :P (which stag also provided me with the knowledge foundation I needed to even complete that simple task :P )

stag019 wrote:

What's even better is that his code is exactly the same as I wrote. With just a little hint, he only needed to add and move a few lines. And he did it by himself, I just sorta showed him where everything was.

And on top of all that you taught me how to get comftorble with a debugger


Red Hack: Pokémon Prototype

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

Offline

#50 2012-09-07 07:46:23

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

Re: Pokemon Red: Palettes

Danny-E 33 wrote:

And on top of all that you taught me how to get comftorble with a debugger

Which is especially good because I hardly know anything about it myself. To be honest this was like the second time I've ever used a debugger to figure something out, but I'm slowly getting the hang of it. I've hardly done any assembly myself, and if it were not for things like cKoolboyman's ROM/RAM maps, and the disassembly, I wouldn't be able to do any of this.

But yeah honestly, I don't see the point in zeroing out the old code. As long as the new code works correctly with every trainer sprite loaded, it's probably best that the old code stays, that way if something points to it, it points to the right information, rather than you having to find them all one by one and repointing them to your new code.

Did you give the Old Man a new palette? Also, can we get some screenshots or something showing different battles with different trainers showing their new colors?


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

Offline

Board footer

Powered by FluxBB