726 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			726 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
; CARD_HELPER_VARS_START defines the beginning of the $100 bytes set aside for system usage
 | 
						|
PUSHS "Card Helper Vars", WRAM0[CARD_HELPER_VARS_START]
 | 
						|
cvCardBank: db
 | 
						|
cvCardAddress: dw
 | 
						|
cvNeedsCleanup: db
 | 
						|
POPS
 | 
						|
 | 
						|
FindCardTileMap: ; puts the tilemap into hl
 | 
						|
  ld hl, cvCardAddress
 | 
						|
  ld c, [hl] 
 | 
						|
  inc hl 
 | 
						|
  ld b, [hl]
 | 
						|
  ld l, c 
 | 
						|
  ld h, b 
 | 
						|
  ld bc, Card_Offset_tilemap
 | 
						|
  add hl, bc ; address of the length and address of the tilemap
 | 
						|
  
 | 
						|
  inc hl 
 | 
						|
  inc hl ; step past the two-byte length of the tilemap
 | 
						|
  
 | 
						|
  ld c, [hl]
 | 
						|
  inc hl
 | 
						|
  ld b, [hl]
 | 
						|
  
 | 
						|
  ld h, b
 | 
						|
  ld l, c
 | 
						|
  
 | 
						|
  ret
 | 
						|
FindCardKeyTiles: 
 | 
						|
  ld hl, cvCardAddress
 | 
						|
  ld c, [hl] 
 | 
						|
  inc hl 
 | 
						|
  ld b, [hl]
 | 
						|
  ld l, c 
 | 
						|
  ld h, b 
 | 
						|
  ld bc, Card_Offset_keytiles
 | 
						|
  add hl, bc ; address of the length and address of the key tilels
 | 
						|
  
 | 
						|
  inc hl 
 | 
						|
  inc hl ; step past the two-byte length of the key tiles
 | 
						|
  
 | 
						|
  ld c, [hl]
 | 
						|
  inc hl
 | 
						|
  ld b, [hl]
 | 
						|
  
 | 
						|
  ld h, b
 | 
						|
  ld l, c
 | 
						|
  
 | 
						|
  ret
 | 
						|
FindCardSpriteTiles:
 | 
						|
  ld hl, cvCardAddress
 | 
						|
  ld c, [hl] 
 | 
						|
  inc hl 
 | 
						|
  ld b, [hl]
 | 
						|
  ld l, c 
 | 
						|
  ld h, b 
 | 
						|
  ld bc, Card_Offset_spritetiles
 | 
						|
  add hl, bc ; address of the length and address of the sprite tile data
 | 
						|
  
 | 
						|
  inc hl 
 | 
						|
  inc hl ; step past the two-byte length of the sprite tile data
 | 
						|
  
 | 
						|
  ld c, [hl]
 | 
						|
  inc hl
 | 
						|
  ld b, [hl]
 | 
						|
  
 | 
						|
  ld h, b
 | 
						|
  ld l, c 
 | 
						|
  ret
 | 
						|
 | 
						|
CardPreload: ; maybe we should do a non-async preload task that empties the handles and banks the rom?
 | 
						|
  ; first and foremost, clear the card init, update, and draw handles, so there's 
 | 
						|
  ; no chance of trying to jump into code from a previous card.
 | 
						|
  di
 | 
						|
  ld bc, Instructions.rett
 | 
						|
  ld hl, CARD_INIT
 | 
						|
  ld [hl], c
 | 
						|
  inc hl 
 | 
						|
  ld [hl], b
 | 
						|
  ld hl, CARD_UPDATE
 | 
						|
  ld [hl], c
 | 
						|
  inc hl 
 | 
						|
  ld [hl], b
 | 
						|
  ld hl, CARD_DRAW
 | 
						|
  ld [hl], c
 | 
						|
  inc hl 
 | 
						|
  ld [hl], b
 | 
						|
  ld hl, CARD_PRINT_PREP
 | 
						|
  ld [hl], c
 | 
						|
  inc hl 
 | 
						|
  ld [hl], b
 | 
						|
  
 | 
						|
  ld a, [vSelectedCardIndex]
 | 
						|
  ld [vPreviousCardIndex], a 
 | 
						|
  
 | 
						|
  ld b, 0
 | 
						|
  ld c, a ; load bc from a, the number of the card in the cards list
 | 
						|
  ld hl, Cards + 1 ; skip the length prefix
 | 
						|
  add hl, bc
 | 
						|
  add hl, bc
 | 
						|
  add hl, bc ; triple add bc entries are bank, addr, addr
 | 
						|
  
 | 
						|
  ld a, [hl+]
 | 
						|
  ld [cvCardBank], a 
 | 
						|
  ld [rROMB0], a ; select the specified bank
 | 
						|
  ; follow the pointer we're looking at, and write it to cvCardAddress
 | 
						|
  ld a, [hl+]
 | 
						|
  ld [cvCardAddress], a 
 | 
						|
  ld a, [hl+]
 | 
						|
  ld [cvCardAddress + 1], a 
 | 
						|
 | 
						|
  reti
 | 
						|
 | 
						|
LoadCardData:
 | 
						|
LoadCardDataAsync: 
 | 
						|
  ld a, [vSelectedCardIndex]
 | 
						|
  ld b, 0
 | 
						|
  ld c, a ; bc from a, the number of the card in the cards list
 | 
						|
  ld hl, DECK_FLIPS + 1
 | 
						|
  add hl, bc
 | 
						|
  ld a, [hl]
 | 
						|
  ld [vCurrentCardReversed], a 
 | 
						|
  
 | 
						|
  cp a, 0
 | 
						|
  jp z, LoadUpright
 | 
						|
  jp nz, LoadReversed
 | 
						|
  ret ; shouldn't ever get here
 | 
						|
 | 
						|
 | 
						|
LoadUpright:
 | 
						|
  ; card struct starts with a sequence of length-prefixed strings in memory
 | 
						|
  ; so when we're done writing one, hl will be correctly placed to read the next
 | 
						|
  ; length-prefixed print doesn't require passing a length
 | 
						|
  ; so all we have to set is the destination for each
 | 
						|
  
 | 
						|
  ld a, [cvCardAddress]
 | 
						|
  ld l, a 
 | 
						|
  ld a, [cvCardAddress + 1]
 | 
						|
  ld h, a ; hl now contains the address of the card data.
 | 
						|
  ;ld bc, Card_Offset_title
 | 
						|
  ;add hl, bc ; unnecessary because card_offset_tile is zero bc the title is first
 | 
						|
  ; print six texts
 | 
						|
  ld de, _SCRN0 + 32*11 + 10
 | 
						|
  call PrintString
 | 
						|
  ld de, _SCRN0 + 32*12 + 10
 | 
						|
  call PrintString
 | 
						|
  ld de, _SCRN0 + 32*13 + 10
 | 
						|
  call PrintString
 | 
						|
  ld de, _SCRN0 + 32*14 + 10
 | 
						|
  call PrintString
 | 
						|
  ld de, _SCRN0 + 32*15 + 10
 | 
						|
  call PrintString
 | 
						|
  ld de, _SCRN0 + 32*16 + 10
 | 
						|
  call PrintString
 | 
						|
  
 | 
						|
  ; load tilemap
 | 
						|
  ld a, [cvCardAddress]
 | 
						|
  ld l, a 
 | 
						|
  ld a, [cvCardAddress + 1]
 | 
						|
  ld h, a ; hl now contains the address of the card data.
 | 
						|
  ld bc, Card_Offset_tilemap ; jump straight to sprite tiles length and location!
 | 
						|
  add hl, bc
 | 
						|
  ; [hl+] and [hl+] read the length first, into bc
 | 
						|
  ld a, [hl+]
 | 
						|
  ld c, a
 | 
						|
  ld a, [hl+]
 | 
						|
  ld b, a ; bc has length
 | 
						|
  ld a, [hl+]
 | 
						|
  ld e, a
 | 
						|
  ld a, [hl+]
 | 
						|
  ld d, a ; de has source of tile range copy
 | 
						|
  
 | 
						|
  ld h, d 
 | 
						|
  ld l, e  ; source
 | 
						|
  ld de, _SCRN0 + 32 + 1 ; destination
 | 
						|
  ld b, 16 ; height
 | 
						|
  ld c, 8 ; width
 | 
						|
  
 | 
						|
  call CopyTilesToMap
 | 
						|
  
 | 
						|
  ld a, [cvCardAddress]
 | 
						|
  ld l, a 
 | 
						|
  ld a, [cvCardAddress + 1]
 | 
						|
  ld h, a ; hl now contains the address of the card data.
 | 
						|
  
 | 
						|
  ld bc, Card_Offset_functions ; jump straight to function handles
 | 
						|
  add hl, bc ; hl now points to the card functions
 | 
						|
  
 | 
						|
  di ; make sure we never call any callbacks without them being fully set
 | 
						|
  nop
 | 
						|
  ld a, [hl+]
 | 
						|
  ld [CARD_INIT], a 
 | 
						|
  ld a, [hl+]
 | 
						|
  ld [CARD_INIT+1], a 
 | 
						|
  ld a, [hl+]
 | 
						|
  ld [CARD_UPDATE], a 
 | 
						|
  ld a, [hl+]
 | 
						|
  ld [CARD_UPDATE+1], a 
 | 
						|
  ld a, [hl+]
 | 
						|
  ld [CARD_DRAW], a 
 | 
						|
  ld a, [hl+]
 | 
						|
  ld [CARD_DRAW+1], a 
 | 
						|
  ld a, [hl+]
 | 
						|
  ld [CARD_PRINT_PREP], a 
 | 
						|
  ld a, [hl+]
 | 
						|
  ld [CARD_PRINT_PREP+1], a
 | 
						|
  ei
 | 
						|
  
 | 
						|
  call CardInit
 | 
						|
  
 | 
						|
 | 
						|
  ld a, [cvCardAddress]
 | 
						|
  ld l, a 
 | 
						|
  ld a, [cvCardAddress + 1]
 | 
						|
  ld h, a ; hl now contains the address of the card data.
 | 
						|
  
 | 
						|
  ld bc, Card_Offset_keytiles ; jump straight to keytiles length and location!
 | 
						|
  add hl, bc
 | 
						|
  
 | 
						|
  ld a, [hl+]
 | 
						|
  ld c, a
 | 
						|
  ld a, [hl+]
 | 
						|
  ld b, a ; bc has length of tile data
 | 
						|
  ld a, [hl+]
 | 
						|
  ld e, a
 | 
						|
  ld a, [hl+]
 | 
						|
  ld d, a ; de has source of tile range copy
 | 
						|
 | 
						|
  ld h, d
 | 
						|
  ld l, e ; hl takes the source
 | 
						|
 | 
						|
  ld de, _VRAM + $1000 + VARIABLE_TILES_START*$10 ; always load tile data into the same spot in vram
 | 
						|
  call CopyRangeBy8s
 | 
						|
  
 | 
						|
  
 | 
						|
  ld a, [cvCardAddress]
 | 
						|
  ld l, a 
 | 
						|
  ld a, [cvCardAddress + 1]
 | 
						|
  ld h, a ; hl now contains the address of the card data.
 | 
						|
  
 | 
						|
  ld bc, Card_Offset_spritetiles ; jump straight to sprite tiles length and location!
 | 
						|
  add hl, bc
 | 
						|
  
 | 
						|
  ld a, [hl+]
 | 
						|
  ld c, a
 | 
						|
  ld a, [hl+]
 | 
						|
  ld b, a ; bc has length of tile data
 | 
						|
  ld a, [hl+]
 | 
						|
  ld e, a
 | 
						|
  ld a, [hl+]
 | 
						|
  ld d, a ; de has source of tile range copy
 | 
						|
 | 
						|
  ld h, d
 | 
						|
  ld l, e ; hl takes the source
 | 
						|
 | 
						|
  ld de, _VRAM ; sprite tiles get loaded into the bottom of vram 
 | 
						|
  call CopyRangeBy8s
 | 
						|
  
 | 
						|
  ret
 | 
						|
LoadReversed: ; same as LoadRightSideUp but loads in the reversed data
 | 
						|
  ; card struct starts with a sequence of length-prefixed strings in memory
 | 
						|
  ; so when we're done writing one, hl will be correctly placed to read the next
 | 
						|
  ; length-prefixed print doesn't require passing a length
 | 
						|
  ; so all we have to set is the destination for each
 | 
						|
  
 | 
						|
  
 | 
						|
  ; draw the title
 | 
						|
  ld a, [cvCardAddress]
 | 
						|
  ld l, a 
 | 
						|
  ld a, [cvCardAddress + 1]
 | 
						|
  ld h, a ; hl now contains the address of the card data.
 | 
						|
  ld bc, Card_Offset_reverse
 | 
						|
  add hl, bc ; jump to the reverse texts and print
 | 
						|
  ld de, _SCRN0 + 32*11 + 10
 | 
						|
  call PrintString
 | 
						|
  ld de, _SCRN0 + 32*12 + 10
 | 
						|
  call PrintString
 | 
						|
  ld de, _SCRN0 + 32*13 + 10
 | 
						|
  call PrintString
 | 
						|
  ld de, _SCRN0 + 32*14 + 10
 | 
						|
  call PrintString
 | 
						|
  ld de, _SCRN0 + 32*15 + 10
 | 
						|
  call PrintString
 | 
						|
  ld de, _SCRN0 + 32*16 + 10
 | 
						|
  call PrintString
 | 
						|
 
 | 
						|
  
 | 
						|
  ; move the tilemap into memory
 | 
						|
  ld a, [cvCardAddress]
 | 
						|
  ld l, a 
 | 
						|
  ld a, [cvCardAddress + 1]
 | 
						|
  ld h, a ; hl now contains the address of the card data.
 | 
						|
  ld bc, Card_Offset_tilemap ; jump straight to tilemap location!
 | 
						|
  add hl, bc
 | 
						|
  
 | 
						|
  ; [hl+] and [hl+] read the length first, into bc
 | 
						|
  ld a, [hl+]
 | 
						|
  ld c, a
 | 
						|
  ld a, [hl+]
 | 
						|
  ld b, a ; bc has length
 | 
						|
  ld a, [hl+]
 | 
						|
  ld e, a
 | 
						|
  ld a, [hl+]
 | 
						|
  ld d, a ; de has source of tile range copy
 | 
						|
  
 | 
						|
  ld h, d 
 | 
						|
  ld l, e  ; source
 | 
						|
  ld de, _SCRN0 + 32 + 1 ; destination
 | 
						|
  ld b, 16 ; height
 | 
						|
  ld c, 8 ; width
 | 
						|
  
 | 
						|
  call CopyTilesToMapButRotated
 | 
						|
  
 | 
						|
  ; move key tile data into vram
 | 
						|
  ld a, [cvCardAddress]
 | 
						|
  ld l, a 
 | 
						|
  ld a, [cvCardAddress + 1]
 | 
						|
  ld h, a ; hl now contains the address of the card data.
 | 
						|
  ld bc, Card_Offset_functions ; jump straight to function handles
 | 
						|
  add hl, bc ; hl now points to the card functions
 | 
						|
  
 | 
						|
  di ; make sure we never call any callbacks without them being fully set
 | 
						|
  ld a, [hl+]
 | 
						|
  ld [CARD_INIT], a 
 | 
						|
  ld a, [hl+]
 | 
						|
  ld [CARD_INIT+1], a 
 | 
						|
  ld a, [hl+]
 | 
						|
  ld [CARD_UPDATE], a 
 | 
						|
  ld a, [hl+]
 | 
						|
  ld [CARD_UPDATE+1], a 
 | 
						|
  ld a, [hl+]
 | 
						|
  ld [CARD_DRAW], a 
 | 
						|
  ld a, [hl+]
 | 
						|
  ld [CARD_DRAW+1], a 
 | 
						|
  ld a, [hl+]
 | 
						|
  ld [CARD_PRINT_PREP], a 
 | 
						|
  ld a, [hl+]
 | 
						|
  ld [CARD_PRINT_PREP+1], a
 | 
						|
  ei
 | 
						|
  
 | 
						|
  call CardInit
 | 
						|
  
 | 
						|
 | 
						|
  ld a, [cvCardAddress]
 | 
						|
  ld l, a 
 | 
						|
  ld a, [cvCardAddress + 1]
 | 
						|
  ld h, a ; hl now contains the address of the card data.
 | 
						|
  
 | 
						|
  ld bc, Card_Offset_keytiles ; jump straight to keytiles length and location!
 | 
						|
  add hl, bc
 | 
						|
  
 | 
						|
  ld a, [hl+]
 | 
						|
  ld c, a
 | 
						|
  ld a, [hl+]
 | 
						|
  ld b, a ; bc has length of tile data
 | 
						|
  ld a, [hl+]
 | 
						|
  ld e, a
 | 
						|
  ld a, [hl+]
 | 
						|
  ld d, a ; de has source of tile range copy
 | 
						|
 | 
						|
  ld h, d
 | 
						|
  ld l, e ; hl takes the source
 | 
						|
 | 
						|
  ld de, _VRAM + $1000 + VARIABLE_TILES_START*$10 ; always load tile data into the same spot in vram
 | 
						|
  call CopyRangeOfTilesButRotated
 | 
						|
  
 | 
						|
  
 | 
						|
  ld a, [cvCardAddress]
 | 
						|
  ld l, a 
 | 
						|
  ld a, [cvCardAddress + 1]
 | 
						|
  ld h, a ; hl now contains the address of the card data.
 | 
						|
  
 | 
						|
  ld bc, Card_Offset_spritetiles ; jump straight to sprite tiles length and location!
 | 
						|
  add hl, bc
 | 
						|
  
 | 
						|
  ld a, [hl+]
 | 
						|
  ld c, a
 | 
						|
  ld a, [hl+]
 | 
						|
  ld b, a ; bc has length of tile data
 | 
						|
  ld a, [hl+]
 | 
						|
  ld e, a
 | 
						|
  ld a, [hl+]
 | 
						|
  ld d, a ; de has source of tile range copy
 | 
						|
 | 
						|
  ld h, d
 | 
						|
  ld l, e ; hl takes the source
 | 
						|
 | 
						|
  ld de, _VRAM ; sprite tiles get loaded into the bottom of vram 
 | 
						|
  call CopyRangeOfTilesButRotated
 | 
						|
  
 | 
						|
  ret
 | 
						|
  
 | 
						|
ReverseString:
 | 
						|
  db 10, "(reversed)"
 | 
						|
EmptyString:
 | 
						|
  db 10, "          "
 | 
						|
 | 
						|
CardInit:
 | 
						|
  ldh a, [rLCDC]
 | 
						|
  and a, %1111_1011
 | 
						|
  ldh [rLCDC], a 
 | 
						|
  
 | 
						|
  ld hl, ZEROES
 | 
						|
  ld de, MY_OAM
 | 
						|
  ld bc, $100
 | 
						|
  call CopyRange
 | 
						|
  
 | 
						|
  ld a, %11100100
 | 
						|
  ldh [rOBP1], a
 | 
						|
  call AdjustOBP1
 | 
						|
  ld a, %11100100
 | 
						|
  ldh [rOBP0], a 
 | 
						|
  call AdjustOBP0
 | 
						|
  
 | 
						|
  call CARD_INIT - 1
 | 
						|
  
 | 
						|
  ld a, [vCurrentCardReversed]
 | 
						|
  cp a, 0 
 | 
						|
  call nz, RotateSprites180
 | 
						|
  ret 
 | 
						|
  
 | 
						|
CardUpdate:
 | 
						|
  ld a, 0
 | 
						|
  ld [cvNeedsCleanup], a 
 | 
						|
  
 | 
						|
  ld a, [vCurrentCardReversed]
 | 
						|
  cp a, 0 
 | 
						|
  call nz, RotateSprites180
 | 
						|
  
 | 
						|
  call CARD_UPDATE - 1
 | 
						|
  
 | 
						|
  ld a, [vCurrentCardReversed]
 | 
						|
  cp a, 0 
 | 
						|
  call nz, RotateSprites180
 | 
						|
  
 | 
						|
  ld a, [cvNeedsCleanup]
 | 
						|
  cp a, 0
 | 
						|
  call nz, CleanUpOutsideSprites
 | 
						|
  
 | 
						|
  ret
 | 
						|
  
 | 
						|
CardDraw:
 | 
						|
  call CARD_DRAW - 1
 | 
						|
  ret  
 | 
						|
  
 | 
						|
CardPrintPrep:
 | 
						|
  call CARD_PRINT_PREP - 1
 | 
						|
  ret  
 | 
						|
  
 | 
						|
RotateSprites180:
 | 
						|
  ld hl, MY_OAM
 | 
						|
  
 | 
						|
  .loop
 | 
						|
    ld a, 0 
 | 
						|
    cp a, [hl] ; if y value is nonzero, 
 | 
						|
    jr nz, :+ ; if y value is nonzero, skip this block where we jump to the next oam entry
 | 
						|
      inc l 
 | 
						|
      inc l 
 | 
						|
      inc l 
 | 
						|
      inc l 
 | 
						|
      
 | 
						|
      ld a, l
 | 
						|
      cp a, $A0 ; this indicates we've reached the end of the mirror OAM 
 | 
						|
      jr nz, .loop
 | 
						|
      ret
 | 
						|
    :
 | 
						|
    
 | 
						|
    ld a, 168
 | 
						|
    sub a, [hl] 
 | 
						|
    ld [hl+], a 
 | 
						|
    
 | 
						|
    ld b, [hl]
 | 
						|
    ld a, 0 
 | 
						|
    cp a, [hl]
 | 
						|
    jr nz, :+ ; if x value is nonzero, skip this block where we jump to the next oam entry
 | 
						|
      inc l 
 | 
						|
      inc l 
 | 
						|
      inc l 
 | 
						|
      
 | 
						|
      ld a, l
 | 
						|
      cp a, $A0 ; this indicates we've reached the end of the mirror OAM 
 | 
						|
      jr nz, .loop
 | 
						|
      ret
 | 
						|
    :
 | 
						|
    ld a, 88
 | 
						|
    sub a, [hl]
 | 
						|
    ld [hl+], a 
 | 
						|
    
 | 
						|
    inc l
 | 
						|
    inc l 
 | 
						|
    
 | 
						|
    ld a, l
 | 
						|
    cp a, $A0 ; this indicates we've reached the end of the mirror OAM 
 | 
						|
    jp nz, .loop
 | 
						|
  
 | 
						|
  ret
 | 
						|
 | 
						|
IncrementTimer:
 | 
						|
  ; hl is the location in memory of a timer
 | 
						|
  ; squashes a and de
 | 
						|
  ; uses the value from rDELTAT
 | 
						|
  ld d, h 
 | 
						|
  ld e, l 
 | 
						|
  inc de
 | 
						|
  ld a, [rDELTAT]
 | 
						|
  add a, [hl]
 | 
						|
  ld [hl], a 
 | 
						|
  ld h, d 
 | 
						|
  ld l, e 
 | 
						|
  ld a, [hl] 
 | 
						|
  adc a, 0 
 | 
						|
  ld [hl], a 
 | 
						|
  dec hl 
 | 
						|
  ret
 | 
						|
 | 
						|
; this set of functions and data are for masking sprites off at the edge of the 
 | 
						|
; frame, which is afaik only used on one card (the moon). whee!
 | 
						|
; set cvNeedsCleanup each frame to enable these, and call SetUpEdgeMasks
 | 
						|
; in your card init function
 | 
						|
SetUpEdgeMasks: 
 | 
						|
  ld hl, EdgeMasks
 | 
						|
  ld de, _VRAM + 8*16*16 ; 8 rows of 16 tiles each, 16 bytes per tile
 | 
						|
  ld bc, EdgeMasks.end - EdgeMasks
 | 
						|
  call CopyRange
 | 
						|
  
 | 
						|
  ld a, %00_00_00_00
 | 
						|
  ld [rOBP1], a 
 | 
						|
  ret
 | 
						|
  
 | 
						|
  
 | 
						|
EdgeMasks:
 | 
						|
  dw `00000000, `00000000, `00000000, `00000000, `00000000, `00000000, `00000000, `00000000, 
 | 
						|
  dw `00000003, `00000003, `00000003, `00000003, `00000003, `00000003, `00000003, `00000003,
 | 
						|
  dw `00000033, `00000033, `00000033, `00000033, `00000033, `00000033, `00000033, `00000033, 
 | 
						|
  dw `00000333, `00000333, `00000333, `00000333, `00000333, `00000333, `00000333, `00000333, 
 | 
						|
  dw `00003333, `00003333, `00003333, `00003333, `00003333, `00003333, `00003333, `00003333,
 | 
						|
  dw `00033333, `00033333, `00033333, `00033333, `00033333, `00033333, `00033333, `00033333,
 | 
						|
  dw `00333333, `00333333, `00333333, `00333333, `00333333, `00333333, `00333333, `00333333,
 | 
						|
  dw `03333333, `03333333, `03333333, `03333333, `03333333, `03333333, `03333333, `03333333,
 | 
						|
  dw `33333333, `33333333, `33333333, `33333333, `33333333, `33333333, `33333333, `33333333, 
 | 
						|
.end
 | 
						|
 | 
						|
CleanUpOutsideSprites:
 | 
						|
  ld hl, MY_OAM + 10*4
 | 
						|
  call HideObviousTiles
 | 
						|
 | 
						|
  ; now we hide the overlapping edges
 | 
						|
  ld hl, MY_OAM + 10*4
 | 
						|
  ld de, MY_OAM
 | 
						|
  .hideEdgesOfSprite
 | 
						|
    ld a, 0 
 | 
						|
    cp a, [hl]
 | 
						|
    jp z, .skipFromY
 | 
						|
    
 | 
						|
    inc l 
 | 
						|
    cp a, [hl]
 | 
						|
    jp z, .skipFromX
 | 
						|
    
 | 
						|
    ; now we know that the sprite does not have y=0 or x=0.
 | 
						|
    ;dec hl 
 | 
						|
    
 | 
						|
    ;call WriteTopEdgeMaskIfNecessary
 | 
						|
    ;call WriteBottomEdgeMaskIfNecessary
 | 
						|
    ;inc hl
 | 
						|
    call WriteLeftEdgeMaskIfNecessary
 | 
						|
    dec l 
 | 
						|
    inc l
 | 
						|
    call WriteRightEdgeMaskIfNecessary
 | 
						|
    dec l
 | 
						|
    
 | 
						|
    .skipFromY
 | 
						|
    inc l
 | 
						|
    .skipFromX
 | 
						|
    inc l
 | 
						|
    inc l 
 | 
						|
    inc l 
 | 
						|
    ld a, $A0
 | 
						|
    cp a, l 
 | 
						|
    jp nz, .hideEdgesOfSprite
 | 
						|
  ret
 | 
						|
 | 
						|
  
 | 
						|
HideObviousTiles:
 | 
						|
.processSprite
 | 
						|
  ;hl points at an OAM entry's y value
 | 
						|
  ld a, 16 ; sprites are visible if y value >= 17
 | 
						|
  cp a, [hl]
 | 
						|
  jr c, :+ ; skip if 17-y < 0
 | 
						|
    ld [hl], 0 
 | 
						|
  : 
 | 
						|
  ld a, 152 ; sprites are visible if y value is < 152
 | 
						|
  cp a, [hl]
 | 
						|
  jr nc, :+ ; skip if 152 - y < 0
 | 
						|
    ld [hl], 0
 | 
						|
  :
 | 
						|
  inc hl ; look at x value
 | 
						|
  ld a, 8 ; sprites are visible if x value >= 8
 | 
						|
  cp a, [hl]
 | 
						|
  jr c, :+ ; skip if 8-y <= 0
 | 
						|
    ld [hl], 0
 | 
						|
  :
 | 
						|
  ld a, 79 ; sprites are visible if x value < 80
 | 
						|
  cp a, [hl]
 | 
						|
  jr nc, :+
 | 
						|
    ld [hl], 0
 | 
						|
  :
 | 
						|
  inc l ; now pointing at tile ID
 | 
						|
  inc l ; now pointing at attributes
 | 
						|
  inc l ; now pointing at next OAM y value
 | 
						|
  ld a, l 
 | 
						|
  cp a, $A0
 | 
						|
  jr nz, .processSprite
 | 
						|
  
 | 
						|
  ret
 | 
						|
  
 | 
						|
WriteTopEdgeMaskIfNecessary:
 | 
						|
  ;hl points at an OAM entry, de points at an empty OAM spot for masks
 | 
						|
  ld a, 24 ; sprites are clear if y value > 24
 | 
						|
  cp a, [hl]
 | 
						|
  ret c ; skip if 24-y < 0
 | 
						|
 | 
						|
  ; writing an edge mask on the TOP  
 | 
						|
  ; else write an edge sprite
 | 
						|
  ld a, 16 ; y value should be 16 (covers top row)
 | 
						|
  ld [de], a ; y value in first slot
 | 
						|
  inc e ;write head moves forward to x
 | 
						|
  inc l ; read head moves forward to x
 | 
						|
  ld a, [hl] ; x value matches the sprite we're mirroring
 | 
						|
  ld [de], a 
 | 
						|
  
 | 
						|
  inc e ; write head moves forward to tile ID
 | 
						|
  ld a, 8*16 + 8
 | 
						|
  ld [de], a 
 | 
						|
  
 | 
						|
  inc e ; write head moves forward to attribute
 | 
						|
  ld a, OAMF_PRI | OAMF_PAL1
 | 
						|
  ld [de], a 
 | 
						|
  
 | 
						|
  dec l
 | 
						|
  inc e
 | 
						|
 | 
						|
  ret
 | 
						|
 | 
						|
WriteBottomEdgeMaskIfNecessary:
 | 
						|
  ld a, 145 ; sprites don't overlap edge if y value is <= 145
 | 
						|
  cp a, [hl]
 | 
						|
  ret nc ; skip if 145 - y >= 0
 | 
						|
  
 | 
						|
  ; writing an edge mask on the BOTTOM
 | 
						|
  ld a, 144 ; y value should be 144 (covers bottom row)
 | 
						|
  ld [de], a ; y value in first slot
 | 
						|
  inc e ;write head moves forward to x
 | 
						|
  inc l ; read head moves forward to x
 | 
						|
  ld a, [hl] ; x value matches the sprite we're mirroring
 | 
						|
  ld [de], a 
 | 
						|
  
 | 
						|
  inc e ; write head moves forward to tile ID
 | 
						|
  ld a, 8*16 + 8
 | 
						|
  ld [de], a ; tile ID 1 for the hidden ones
 | 
						|
  
 | 
						|
  inc e ; write head moves forward to attribute
 | 
						|
  ld a, OAMF_PRI | OAMF_PAL1 ;OAM_PRIO | OAM_PAL1
 | 
						|
  ld [de], a 
 | 
						|
  
 | 
						|
  dec l
 | 
						|
  inc e
 | 
						|
  
 | 
						|
  ret
 | 
						|
  
 | 
						|
WriteLeftEdgeMaskIfNecessary:
 | 
						|
  ld a, 16 ; sprites dno't need coverage if x value > 16
 | 
						|
  cp a, [hl]
 | 
						|
  ret c ; skip if 16-y < 0
 | 
						|
  
 | 
						|
  ; else write an edge mask on the LEFT
 | 
						|
  dec l
 | 
						|
  ld a, [hl] ; copy y over from sprite
 | 
						|
  ld [de], a 
 | 
						|
  
 | 
						|
  inc l ; point at x now
 | 
						|
  inc e ; point at x now
 | 
						|
  
 | 
						|
  ld a, 8 ; x value should be 8 (covers left edge)
 | 
						|
  ld [de], a ; x value
 | 
						|
  
 | 
						|
  inc e ; write head moves forward to tile ID
 | 
						|
  ld a, 8*16+7
 | 
						|
  ld [de], a ; tile ID 1 for the hidden ones
 | 
						|
  
 | 
						|
  inc e ; write head moves forward to attribute
 | 
						|
  ld a, OAMF_PRI | OAMF_PAL1  
 | 
						|
  ld [de], a 
 | 
						|
  
 | 
						|
  inc e
 | 
						|
  
 | 
						|
  ret
 | 
						|
  
 | 
						|
WriteRightEdgeMaskIfNecessary:
 | 
						|
  ld a, 72 ; sprites dont needd coverage if x value < 72
 | 
						|
  cp a, [hl]
 | 
						|
  ret nc
 | 
						|
  
 | 
						|
  ; else write an edge mask on the RIGHT
 | 
						|
  dec l
 | 
						|
  ld a, [hl] ; copy y over from sprite
 | 
						|
  ld [de], a 
 | 
						|
  
 | 
						|
  inc l ; point at x now
 | 
						|
  inc e ; point at x now
 | 
						|
  
 | 
						|
  ld a, [hl] ; x value should match the sprite we're masking...
 | 
						|
  ld [de], a ; x value
 | 
						|
  
 | 
						|
  inc e ; write head moves forward to tile ID
 | 
						|
  ; a currently holds the x coordinate
 | 
						|
  sub a, 72 ; subtract off 72 to get the amount that we're overlapping
 | 
						|
  add a, 8*16 ; add the offset for the mask sprites...
 | 
						|
  ld [de], a ; that makes the tile ID for the mask we want!
 | 
						|
  
 | 
						|
  inc e ; write head moves forward to attribute
 | 
						|
  ld a, OAMF_PRI | OAMF_PAL1
 | 
						|
  ld [de], a 
 | 
						|
  
 | 
						|
  inc e
 | 
						|
  
 | 
						|
  ret |