You are not logged in.
Hello, long time no see! I would like to expand the pool of Pokemon which the game is able to scroll through during it's title sequence. I initially just tried appending additional Pokemon to the end of the "IF DEF(_RED)" list (as that's the version I'm working with) and it compiled just fine, but produced no actual results. I then went in to titlescreen.asm and found a section of code commented "Generate a new Titlemon" ... I noticed a piece of the code was "and $f" which stuck out as there are initially 16 Pokemon on the list. While 0xF is 15, I assumed it just meant "number of Pokemon after the first one" or something (wouldn't be the biggest stretch I've come accross) and tried to change it.
This was successful to an extent. While REDUCING this number does, in fact, work exactly as I assumed it would (I.E. making it $2 will only cycle the first Pokemon, plus the two proceeding it on the list), INCREASING the value past $F is when things start to get strange...specifically, setting it to any value over $F will only cycle through the very first Pokemon on the list, plus however many + F extra....uh.....okay, so let's just make up an example.
the very first thing in my list, we'll say is Bulbasaur. The list would normally end with, let's say, Magikarp, so I added (let's just say) Psyduck, below that (db PSYDUCK) and let's say we add Slowpoke too. If I keep the value at $F, it will cycle through every Pokemon on the list up to and including Magikarp, as it normally would. If I set it to $10, it will ONLY cycle through Bulbasaur and Psyduck, $11 cycles it through only Bulbasaur, Psyduck, and Slowpoke, etc.....making sense? Because it sure wasn't to me. I actually think the only reason Bulbasaur was there at all in those cases was because it's defined as the starting Pokemon, anyway.
At any rate, does anyone know how I can possibly expand the list of Pokemon I can cycle through on the titlescreen? Am I missing something really obvious? Thanks!
So, this is the code in question:
TitleScreenPickNewMon: ld a, vBGMap0 / $100 call TitleScreenCopyTileMapToVRAM .loop ; Keep looping until a mon different from the current one is picked. call Random and $f ld c, a ld b, 0 ld hl, TitleMons add hl, bc ld a, [hl] ld hl, wTitleMonSpecies ; Can't be the same as before. cp [hl] jr z, .loop ld [hl], a call LoadTitleMonSprite ...
TitleMons: ; mons on the title screen are randomly chosen from here IF DEF(_RED) db CHARMANDER db SQUIRTLE db BULBASAUR db WEEDLE db NIDORAN_M db SCYTHER db PIKACHU db CLEFAIRY db RHYDON db ABRA db GASTLY db DITTO db PIDGEOTTO db ONIX db PONYTA db MAGIKARP ENDC ...
"call Random" sets a to any possible random value. a is an 8-bit register, so it can take any value from 0 to 255.
(In case you don't know, 8-bit means it can store 8 binary digits. Which is why the maximum value is eight 1s.)
Anyway, the TitleMons table does not have 256 entries. So the random value has to be truncated. If the top four bits are set to all 0, then the range will be %00000000 to %00001111, or 0 to 15. Which means each of the 16 TitleMons can be chosen. "and $f" sets a to a && $f, or a && %00001111, which has the effect of zeroing out those top four bits.
If you changed it to "and $1f", that would zero out the top three bits, leaving you with a value from 0 to 31. But then you need a table with 32 entries. If you want to have an arbitrary table length that might not be a power of 2, do this:
.loop ; Keep looping until a mon different from the current one is picked. call Random cp NUM_TITLE_MONS ; compare a with NUM_TITLE_MONS and set the carry flag c if a < NUM_TITLE_MONS jr nc, .loop ; if the carry flag is not set, then a >= NUM_TITLE_MONS, so try again ld c, a ld b, 0 ld hl, TitleMons add hl, bc ld a, [hl] ld hl, wTitleMonSpecies ...
TitleMons: ; mons on the title screen are randomly chosen from here IF DEF(_RED) db CHARMANDER ; 0 db SQUIRTLE ; 1 db BULBASAUR ; 2 ENDC NUM_TITLE_MONS EQU 3 ...
Last edited by Rangi (2017-01-27 02:47:36)
Thanks for this reply! I now understand completely how this works, so thank you for that :) Unfortunately, this code didn't seem to work quite right...I think I might be using an older/different (?) version of the disassembly as that function was called ".new" instead of ".loop"....but regardless, the error that kept popping up was that NUM_TITLE_MONS was undefined, despite having defined it t in the separate titlemons file, as you did. I did, however, find that one solution was just to change that particular line to "cp $16" (as I had expanded the list to now use 22 Pokemon), and it works perfectly!
While it would still be nice to know how/what I did wrong that the NUM_TITLE_MONS thing didn't work, I'm pretty pleased it's working never the less. Thanks for your help! :)
If you put NUM_TITLE_MONS in data/title_mons.asm as Rangi did here, then you are getting the error because the constant is being defined after it is referenced.
This is simply because the data/title_mons.asm file is included towards the bottom of engine/titlescreen.asm.
Constants have to be defined before you try referencing their value.
Also, if you want to just let all Pokemon scroll on the titlescreen, that could probably be worked out without too much issue too (I did it for Red++, it would just take a little adapting since, before doing that, I sorted IDs by national dex number and removed the Missingnos -- so if you did what I did exactly you would end up with Missingnos on the titlescreen too).
Last edited by Mateo (2017-02-03 04:23:23)
Check them out on Github