diff options
-rw-r--r-- | constants/gfx_constants.asm | 1 | ||||
-rw-r--r-- | home/pokemon.asm | 234 | ||||
-rw-r--r-- | hram.asm | 11 | ||||
-rw-r--r-- | shim.sym | 13 | ||||
-rw-r--r-- | sram.asm | 8 | ||||
-rw-r--r-- | wram.asm | 71 |
6 files changed, 328 insertions, 10 deletions
diff --git a/constants/gfx_constants.asm b/constants/gfx_constants.asm index 0da273f..536f4a4 100644 --- a/constants/gfx_constants.asm +++ b/constants/gfx_constants.asm @@ -34,6 +34,7 @@ HP_GREEN EQU 0 HP_YELLOW EQU 1 HP_RED EQU 2 +SPRITEBUFFERSIZE EQU 7*7 * 8 ; 7 * 7 (tiles) * 8 (bytes per tile) ; sprite_oam_struct members (see macros/wram.asm) const_def diff --git a/home/pokemon.asm b/home/pokemon.asm new file mode 100644 index 0000000..d38e1a0 --- /dev/null +++ b/home/pokemon.asm @@ -0,0 +1,234 @@ +INCLUDE "constants.asm" + +SECTION "3A4B", ROM0[$3a4b] +; copies the base stat data of a pokemon to wMonHeader +; INPUT: +; [wcb5b] = pokemon ID in dex order +GetMonHeader:: ; 3a4b (0:3a4b) + push bc + push de + push hl + ldh a, [hROMBank] + push af + ld a, BANK(MonBaseStats) + call Bankswitch + ld a, [wcb5b] + cp DEX_FD + jr z, .egg + dec a + ld bc, MonBaseStatsEnd - MonBaseStats + ld hl, MonBaseStats + call AddAMulBC + ld de, wMonHeader + ld bc, MonBaseStatsEnd - MonBaseStats + call CopyBytes + jr .done +.egg + ld de, EggPicFront + ld b, $55 ; egg sprite dimension + ld hl, wMonHSpriteDim + ld [hl], b + ld hl, wMonHFrontSprite + ld [hl], e + inc hl + ld [hl], d + jr .done +.done + ld a, [wcb5b] + ld [wMonHIndex], a + pop af + call Bankswitch + pop hl + pop de + pop bc + ret + +SECTION "3B3F", ROM0[$3b3f] + +; de: destination location +LoadMonFrontSprite:: ; 3b3f + push de + ld hl, wMonHFrontSprite - wMonHeader + call UncompressMonSprite + ld hl, wMonHSpriteDim + ld a, [hl] + ld c, a + pop de + ; fall through + +; postprocesses uncompressed sprite chunks to a 2bpp sprite and loads it into video ram +; calculates alignment parameters to place both sprite chunks in the center of the 7*7 tile sprite buffers +; de: destination location +; a,c: sprite dimensions (in tiles of 8x8 each) +LoadUncompressedSpriteData:: ; 3b4c (0:3b4c) + push de + and $0f + ldh [hSpriteWidth], a ; each byte contains 8 pixels (in 1bpp), so tiles=bytes for width + ld b, a + ld a, $07 + sub b ; 7-w + inc a ; 8-w + srl a ; (8-w)/2 ; horizontal center (in tiles, rounded up) + ld b, a + add a + add a + add a + sub b ; 7*((8-w)/2) ; skip for horizontal center (in tiles) + ldh [hSpriteOffset], a + ld a, c + swap a + and $0f + ld b, a + add a + add a + add a ; 8*tiles is height in bytes + ldh [hSpriteHeight], a + ld a, $07 + sub b ; 7-h ; skip for vertical center (in tiles, relative to current column) + ld b, a + ldh a, [hSpriteOffset] + add b ; 7*((8-w)/2) + 7-h ; combined overall offset (in tiles) + add a + add a + add a ; 8*(7*((8-w)/2) + 7-h) ; combined overall offset (in bytes) + ldh [hSpriteOffset], a + ld a, $00 + call OpenSRAM + ld hl, sSpriteBuffer0 + call ZeroSpriteBuffer ; zero buffer 0 + ld de, sSpriteBuffer1 + ld hl, sSpriteBuffer0 + call AlignSpriteDataCentered ; copy and align buffer 1 to 0 (containing the MSB of the 2bpp sprite) + ld hl, sSpriteBuffer1 + call ZeroSpriteBuffer ; zero buffer 1 + ld de, sSpriteBuffer2 + ld hl, sSpriteBuffer1 + call AlignSpriteDataCentered ; copy and align buffer 2 to 1 (containing the LSB of the 2bpp sprite) + call CloseSRAM + pop de + call InterlaceMergeSpriteBuffers + ret + +; fills the sprite buffer (pointed to in hl) with zeros +ZeroSpriteBuffer:: ; 3ba1 (0:3ba1) + ld bc, SPRITEBUFFERSIZE + xor a + jp ByteFill + +; copies and aligns the sprite data properly inside the sprite buffer +; sprite buffers are 7*7 tiles in size, the loaded sprite is centered within this area +AlignSpriteDataCentered:: ; 3ba8 (0:3ba8) + ldh a, [hSpriteOffset] + ld c, a + ld b, $00 + add hl, bc + ldh a, [hSpriteWidth] + ld b, a + ldh a, [hSpriteHeight] + ld c, a +.columnLoop + push bc + push hl +.columnInnerLoop + ld a, [de] + inc de + ld [hli], a + dec c + jr nz, .columnInnerLoop + pop hl + ld bc, 7*8 ; 7 tiles + add hl, bc ; advance one full column + pop bc + dec b + jr nz, .columnLoop + ret + +; combines the (7*7 tiles, 1bpp) sprite chunks in buffer 0 and 1 into a 2bpp sprite located in buffer 1 through 2 +; in the resulting sprite, the rows of the two source sprites are interlaced +; de: output address +InterlaceMergeSpriteBuffers:: ; 3bc6 (0:3bc6) + ld a, $00 + call OpenSRAM + push de + call _InterlaceMergeSpriteBuffers + pop hl + ld de, sSpriteBuffer1 + ld c, (2*SPRITEBUFFERSIZE)/16 ; $31, number of 16 byte chunks to be copied + ldh a, [hROMBank] + ld b, a + call CopyVideoDataOptimized + call CloseSRAM + ret + +; actual implementation of InterlaceMergeSpriteBuffers +; sprite flipping is now done during interlace merge loop +; and not as second loop after regular interlace merge +; to save time +_InterlaceMergeSpriteBuffers:: ; 3bdf (0:3bdf) + ld a, [wSpriteFlipped] + and a + jr nz, .flipped + ld hl, sSpriteBuffer2 + (SPRITEBUFFERSIZE - 1) ; destination: end of buffer 2 + ld de, sSpriteBuffer1 + (SPRITEBUFFERSIZE - 1) ; source 2: end of buffer 1 + ld bc, sSpriteBuffer0 + (SPRITEBUFFERSIZE - 1) ; source 1: end of buffer 0 + ld a, SPRITEBUFFERSIZE/2 ; $c4 + ldh [hSpriteInterlaceCounter], a +.interlaceLoop + ld a, [de] + dec de + ld [hld], a ; write byte of source 2 + ld a, [bc] + dec bc + ld [hld], a ; write byte of source 1 + ld a, [de] + dec de + ld [hld], a ; write byte of source 2 + ld a, [bc] + dec bc + ld [hld], a ; write byte of source 1 + ldh a, [hSpriteInterlaceCounter] + dec a + ldh [hSpriteInterlaceCounter], a + jr nz, .interlaceLoop + ld a, [wSpriteFlipped] ; always notFlipped; flip routine was optimized + and a + jr z, .notFlipped + ld bc, 2*SPRITEBUFFERSIZE + ld hl, sSpriteBuffer1 +.swapLoop + swap [hl] ; if flipped swap nybbles in all bytes + inc hl + dec bc + ld a, b + or c + jr nz, .swapLoop +.notFlipped + ret +.flipped + ld hl, sSpriteBuffer2 + (SPRITEBUFFERSIZE - 1) ; destination: end of buffer 2 + ld de, sSpriteBuffer1 + (SPRITEBUFFERSIZE - 1) ; source 2: end of buffer 1 + ld bc, sSpriteBuffer0 + (SPRITEBUFFERSIZE - 1) ; source 1: end of buffer 0 + ld a, SPRITEBUFFERSIZE/2 ; $c4 + ldh [hSpriteInterlaceCounter], a +.interlaceLoopFlipped + ld a, [de] + dec de + swap a + ld [hld], a ; write byte of source 2 + ld a, [bc] + dec bc + swap a + ld [hld], a ; write byte of source 1 + ld a, [de] + dec de + swap a + ld [hld], a ; write byte of source 2 + ld a, [bc] + dec bc + swap a + ld [hld], a ; write byte of source 1 + ldh a, [hSpriteInterlaceCounter] + dec a + ldh [hSpriteInterlaceCounter], a + jr nz, .interlaceLoopFlipped + ret @@ -15,7 +15,16 @@ hVBlank:: ; ff99 db - ds 54 ; TODO + ds 21 ; TODO + +hSpriteWidth:: ; ffaf +hSpriteInterlaceCounter:: ; ffaf + db +hSpriteHeight:: ; ffb0 + db +hSpriteOffset:: ; ffb1 + db + ds 30 ; TODO hLCDCPointer:: ; ffd0 @@ -1,13 +1,13 @@ ; ROM0 00:0317 DelayFrame 00:0324 DelayFrames -00:0D2A FarCopyData -00:0D68 CopyVideoData 00:0884 UpdateJoypad 00:095E UncompressSpriteData 00:0d1a LoadFontExtra 00:0d0a LoadFont -00:0d68 CopyGfx +00:0D2A FarCopyData +00:0D68 CopyVideoData +00:0DE4 CopyVideoDataOptimized 00:0E2A ClearTileMap 00:0e3d DrawTextBox 00:0E93 PlaceString @@ -38,10 +38,7 @@ 00:3655 SetHPPal.done 00:36C8 NamesPointers 00:36E0 GetName -00:3B3F LoadMonFrontSprite -00:3B4C LoadUncompressedSpriteData -00:3BA1 ZeroSpriteBuffer -00:3BC6 InterlaceMergeSpriteBuffers ; added functionality here +00:3AED UncompressMonSprite 00:3D86 WaitSFX 00:3D87 WaitSFX.wait 00:3DA5 MaxVolume @@ -99,8 +96,6 @@ 00:c5e8 wMapScriptNumber 00:ca22 wTrainerClass -00:cb5b wName -00:cb5c wNameCategory 00:CBF2 wWindowData 00:CBF2 wWindowStackPointer 00:CC02 wMenuDataHeader @@ -1,3 +1,11 @@ +INCLUDE "constants.asm" + +SECTION "Sprite Buffers", SRAM, BANK[0] + +sSpriteBuffer0:: ds SPRITEBUFFERSIZE ; a000 +sSpriteBuffer1:: ds SPRITEBUFFERSIZE ; a188 +sSpriteBuffer2:: ds SPRITEBUFFERSIZE ; a310 + SECTION "Unknown, bank 0", SRAM[$A600],BANK[0] s0_a600:: ; TODO: properly label this @@ -81,6 +81,9 @@ SECTION "LY overrides buffer", WRAM0[$C600] wLYOverrides:: ; c600 ds SCREEN_HEIGHT_PX +SECTION "CB56", WRAM0[$CB5B] +wcb5b:: ds 1 +wNameCategory:: ds 1 SECTION "CC38", WRAM0[$CC38] ; Please merge when more is disassembled @@ -95,6 +98,10 @@ wDebugWarpSelection:: ; cc39 wSGB:: ; cc40 db +SECTION "CCB5", WRAM0[$CCB5] + +wSpriteFlipped:: ; ccb5 + db SECTION "CD4F", WRAM0[$CD4F] @@ -116,6 +123,70 @@ SECTION "CE00", WRAM0[$CE00] wBattleMode:: ; ce00 db +SECTION "CE07", WRAM0[$CE07] + +wMonHeader:: + +wMonHIndex:: ; ce07 +; In the ROM base stats data structure, this is the dex number, but it is +; overwritten with the dex number after the header is copied to WRAM. + ds 1 + +wMonHBaseStats:: ; ce08 +wMonHBaseHP:: ; ce08 + ds 1 +wMonHBaseAttack:: ; ce09 + ds 1 +wMonHBaseDefense:: ; ce0a + ds 1 +wMonHBaseSpeed:: ; ce0b + ds 1 +wMonHBaseSpecialAtt:: ; ce0c + ds 1 +wMonHBaseSpecialDef:: ; ce0d + ds 1 + +wMonHTypes:: ; ce0e +wMonHType1:: ; ce0e + ds 1 +wMonHType2:: ; ce0f + ds 1 + +wMonHCatchRate:: ; ce10 + ds 1 +wMonHBaseEXP:: ; ce11 + ds 1 + +wMonHItems:: ; ce12 +wMonHItem1:: ; ce12 + ds 1 +wMonHItem2:: ; ce13 + ds 1 + +wMonHGenderRatio:: ; ce14 + ds 1 + +wMonHUnk0:: ; ce15 + ds 1 +wMonHUnk1:: ; ce16 + ds 1 +wMonHUnk2:: ; ce17 + ds 1 + +wMonHSpriteDim:: ; ce18 + ds 1 +wMonHFrontSprite:: ; ce19 + ds 2 +wMonHBackSprite:: ; ce1b + ds 2 + +wMonHGrowthRate:: ; ce1d + ds 1 + +wMonHLearnset:: ; ce1e +; bit field + flag_array 50 + 5 + ds 1 SECTION "CE3C", WRAM0[$CE3C] |