You are not logged in.
I'm basing this off the pokecrystal disassembly.
My hack of Crystal has added a bunch of new maps, and I assigned them to the 26 map groups according to which roof color I wanted. I then realized that each group also has a list of 23 valid sprites for outdoor maps (i.e ROUTE or TOWN) so I checked which sprites each map needed and made sure that they were all listed in the appropriate group.
However, I'm still getting glitches when sprites move. A sailor might appear normal standing still, so I know the correct sprite is being loaded, but the walking animation shows up as letters and numbers.
Here's my modified engine/overworld.asm with comments on each map group listing its outdoor maps. Can anyone see what the problem is? Do sprites have to be in a certain order? The bug seems related to sprites being different sizes, like SPRITE_YOUNGSTER has frames to walk but SPRITE_STANDING_YOUNGSTER doesn't, but I don't know what needs changing.
You sure the problem isn't something as simple as font being loaded while the sprites are trying to move?
You can check out with VBA or BGB what Video Ram looks like at any time. When moving sprites are loaded, all the people events that appear on the map should have both their standing and walking sprites totally loaded into VRAM.
And when font is loaded, it replaces most if not all the walking sprites so when the people events move around, the graphics are loaded from the offset where they should be, but there is some font data there.
If the issue is something bigger and is indeed related to coding, let us know.
Also, just remembered that you can actually use only 11 walking people events in each spritesheet / map group. The remaining 2 sprites should be something that are not moved (= item ball, fruit tree, rock smash stone etc.).
I thought you had meant 13 instead of 23 as being the sprite limitation for map group as I remembered that was the limitation for Gold and Silver, but it's actually 11. I guess it's possible that you can put that many sprites into the map group, but this probably means that the bug you're getting comes from the fact that not all of the sprites you're meaning to use in a map can fit into the area in VRAM that is reserved for them. At least, I think that's the problem but I may be wrong.
Last edited by Miksy91 (2016-07-18 18:43:12)
Thank you! That does sound correct; some of my map groups use a lot of sprites, and they're the ones where I noticed this bug.
However, it looks like the limit might be 9 walking sprites, not 11. Fuchsia City is in Group 17 and uses 10 walking sprites, the last being YOUNGSTER. Looking at the VRAM I see the first 9 sprites loaded in order on the right (after the player sprite, before the two still sprites), and YOUNGSTER is loaded on the left, where his walk animation overlaps the font. The same thing happens in National Park, part of Group 3, where the 10th walking sprite also happens to be Youngster and thus glitches. That seems... annoyingly low. Oh well.
Last edited by Rangi (2016-07-18 19:31:57)
Right - you can only use 9 walking sprites and 2 standing sprites in each map group. I actually checked that out between "Edit 1" and "Edit 2" and was meaning to write that there in an understandable way, but by accident (as I was thinking already ahead...) just wrote this "I thought you had meant 13 instead of 23 as being the sprite limitation for map group as I remembered that was the limitation for Gold and Silver, but it's actually 11." which doesn't really say that clearly at all. Also, that's bad english there in overall as well...
Anyway, yeah... you have to be able to work with only 9 walking sprites in each map group. It's totally possible, but you'll have to use generic sprites here and there on outside maps. If the map isn't ROUTE or TOWN though, you don't have to worry about this problem.
I would consider making it so that you mark each "unused slot" of each map group with some sprite you hardly even use (pokecenter nurse maybe?) in outside maps. That way you can keep track of which map groups have unused slots for new sprites and how many there are.
Last edited by Miksy91 (2016-07-19 08:02:13)
The reason the font is loaded at all is because Crystal shows you the name of the map you just entered. You really don't need the whole font for that... there's space from 1:9600 on for the letters making up the name instead of the whole font.
You can get rid of it by stubbing LoadOverworldFont in misc/mobile_41.asm.
To get rid of the map name box (which will now have garbled text), remove the call to ReturnFromMapSetupScript.inefficientcallba in engine/events_3.asm.
Since the game assumes the font is always there, it also never thinks any sprites need to be reloaded when you stop talking to someone. This used to be the case in Gold. The easiest way to add it back is to add the following to LoadOverworldFont:
LoadOverworldFont:: callba Function14157 ret
This just reloads the sprites. This will reintroduce some lag that was already in Gold, but it's a little worse since there's twice the sprites. You could add code that only reloads the font area, and call that instead. Follow the calls in Function14157 to see what you would need to adapt.
The game also avoids drawing sprites to the font area. To fix that, remove the check for bit 5 of wSpriteFlags:
GetUsedSprite: ... ld a, [wSpriteFlags] ; bit 5, a ; jr nz, .done bit 6, a jr nz, .done
Unused slots aren't a bad idea. But probably the best way is to refactor AddOutdoorSprites to use terminated lists (or lengths) instead of MAX_OUTDOOR_SPRITES, since the capacity is based on the size of the sprites, not how many there are.
There's another change that avoids drawing junk data, which reduces lag a bit. The full diff is below.
diff --git a/engine/events_3.asm b/engine/events_3.asm index b1c142a..e7eb0cc 100755 --- a/engine/events_3.asm +++ b/engine/events_3.asm @@ -4,7 +4,6 @@ ReturnFromMapSetupScript:: ; b8000 ; For some reson, GameFreak chose to use a callba here instead of just falling through. ; No other function in the game references the function at 2E:400A, here labeled ; ReturnFromMapSetupScript.inefficientcallba. - callba .inefficientcallba ; this is a waste of 6 ROM bytes and 6 stack bytes ret ; b800a diff --git a/engine/overworld.asm b/engine/overworld.asm index 5e12b09..0d8815f 100755 --- a/engine/overworld.asm +++ b/engine/overworld.asm @@ -639,14 +639,14 @@ endr pop hl ld a, [wSpriteFlags] - bit 5, a - jr nz, .done bit 6, a jr nz, .done ld a, [hUsedSpriteIndex] - call _DoesSpriteHaveFacings + call .DoesSpriteWalk jr c, .done ld a, h add $8 @@ -657,6 +657,29 @@ endr ret ; 14406 +.DoesSpriteWalk: + cp SPRITE_POKEMON + jr nc, .no + push hl + push bc + ld hl, SpriteHeaders + SPRITEHEADER_TYPE + dec a + ld c, a + ld b, 0 + ld a, NUM_SPRITEHEADER_FIELDS + call AddNTimes + ld a, [hl] + pop bc + pop hl + cp WALKING_SPRITE + jr z, .yes +.no + scf + ret +.yes + and a + ret + .GetTileAddr: ; 14406 ; Return the address of tile (a) in (hl). and $7f diff --git a/misc/mobile_41.asm b/misc/mobile_41.asm index 44db586..69d988e 100755 --- a/misc/mobile_41.asm +++ b/misc/mobile_41.asm @@ -1084,16 +1084,5 @@ INCBIN "gfx/unknown/106514.2bpp" LoadOverworldFont:: ; 106594 - ld de, .bgfont - ld hl, VTiles1 - lb bc, BANK(.bgfont), $80 - call Get2bpp - ld de, .bgfont + $80 tiles - ld hl, VTiles2 tile $7f - lb bc, BANK(.bgfont), 1 - call Get2bpp + callba Function14157 ret -; 1065ad - -.bgfont -INCBIN "gfx/unknown/1065ad.2bpp"
Last edited by comet (2016-07-21 18:49:05)