367 lines
		
	
	
		
			8.8 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			367 lines
		
	
	
		
			8.8 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
CopyTilesToMap:
 | 
						|
  ; copy tiles from where they are linearly packed at an origin (hl)
 | 
						|
  ; to a rectangle in the tilemap in vram (de)
 | 
						|
  ; assuming it has height in b and width in c.
 | 
						|
  ld a, b
 | 
						|
  or a, c
 | 
						|
  ret z
 | 
						|
  push bc
 | 
						|
.copyTile
 | 
						|
  ld a, [hl+] ; load from the tile map into a
 | 
						|
  ld [de], a ; load from a into the destination
 | 
						|
  inc de
 | 
						|
  dec c
 | 
						|
  jr nz, .copyTile ; if there's lines left to copy, jump back and redo
 | 
						|
.doneWithLine
 | 
						|
  pop bc
 | 
						|
 | 
						|
  ; this adds 32-c to de
 | 
						|
  ld a, 32
 | 
						|
  sub a, c ; first calculate 32-c
 | 
						|
  add a, e 
 | 
						|
  ld e, a 
 | 
						|
  ld a, d 
 | 
						|
  adc a, 0
 | 
						|
  ld d, a 
 | 
						|
 | 
						|
  dec b
 | 
						|
  jr nz, CopyTilesToMap
 | 
						|
  ret
 | 
						|
  
 | 
						|
CopyTilesToMapButRotated:
 | 
						|
  ; copy tiles from where they are linearly packed at an origin (hl)
 | 
						|
  ; to a rectangle in the tilemap in vram (de)
 | 
						|
  ; assuming it has height in b and width in c.
 | 
						|
  ;
 | 
						|
  ; however! also rotate by 180 degrees!
 | 
						|
  push bc ; quick little add-multiply; hl should increase by b*c, we're gonna squash em so save to stack
 | 
						|
  ld a, b ; saving
 | 
						|
  ld b, 0 ; zero out b so that bc is just c
 | 
						|
  .multLoop
 | 
						|
    add hl, bc ; step forward by c
 | 
						|
    dec a ; take off a row
 | 
						|
    jp nz, .multLoop ; if we've got rows left, repeat
 | 
						|
  
 | 
						|
  dec hl 
 | 
						|
  pop bc
 | 
						|
.body
 | 
						|
  ld a, b
 | 
						|
  or a, c
 | 
						|
  ret z
 | 
						|
  push bc
 | 
						|
.copyTile
 | 
						|
  ld a, [hl-] ; load from the tile map into a
 | 
						|
  ld [de], a ; load from a into the destination
 | 
						|
  inc de
 | 
						|
  dec c
 | 
						|
  jr nz, .copyTile ; if there's lines left to copy, jump back and redo
 | 
						|
.doneWithLine
 | 
						|
  pop bc
 | 
						|
 | 
						|
  ; this adds 32-c to de
 | 
						|
  ld a, 32
 | 
						|
  sub a, c ; first calculate 32-c
 | 
						|
  add a, e 
 | 
						|
  ld e, a 
 | 
						|
  ld a, d 
 | 
						|
  adc a, 0
 | 
						|
  ld d, a 
 | 
						|
 | 
						|
  dec b
 | 
						|
  jr nz, .body
 | 
						|
  ret
 | 
						|
  
 | 
						|
PositionMetaSprite:
 | 
						|
  ; location in memory to write to: de
 | 
						|
  ; y and x in b and c 
 | 
						|
  ; height and width in a & %11110000 and a & %00001111 ??? that's deranged
 | 
						|
  ld h, d 
 | 
						|
  ld l, e
 | 
						|
  
 | 
						|
  ld d, a 
 | 
						|
  push bc ; hold onto the upper-left corner so we can update it each row
 | 
						|
 | 
						|
.writeRow
 | 
						|
  pop bc 
 | 
						|
  ld a, d 
 | 
						|
  push bc ; refresh af and bc from their authoritative versions
 | 
						|
  and a, $0F ; take only the horizontal tile count
 | 
						|
 | 
						|
.buildSprite
 | 
						|
  ; 
 | 
						|
  ld [hl], b ; write y byte
 | 
						|
  inc l 
 | 
						|
  ld [hl], c ; write x byte
 | 
						|
  inc l 
 | 
						|
  inc l 
 | 
						|
  res OAMB_XFLIP, [hl] ; make sure xflip is turned off
 | 
						|
  inc l ; skip the attributes byte
 | 
						|
  ; we're going to wait to get our a value (number of tiles left to draw in this
 | 
						|
  ; row) until after we've used a for changing c
 | 
						|
  
 | 
						|
  ;we've written a whole sprite. hl and de are in the right state, we need to 
 | 
						|
  ; update a and bc.
 | 
						|
  
 | 
						|
  ; update bc
 | 
						|
  ld e, a
 | 
						|
  ld a, c 
 | 
						|
  add a, 8 
 | 
						|
  ld c, a 
 | 
						|
  ld a, e
 | 
						|
  dec a
 | 
						|
  jp nz, .buildSprite ; if there are still tiles left to draw in this row, do it!
 | 
						|
  
 | 
						|
  ; otherwise we have no more tiles to write this row bc needs to be updated
 | 
						|
  
 | 
						|
  pop bc
 | 
						|
  ld a, b 
 | 
						|
  add a, 8
 | 
						|
  ld b, a ; add 8 to the y coordinate
 | 
						|
  
 | 
						|
  ld a, d  
 | 
						|
  sub a, $10
 | 
						|
  ld d, a  
 | 
						|
  push bc
 | 
						|
  
 | 
						|
  and a, $F0
 | 
						|
  ; stakc has bc and af, ready for repeating from the top
 | 
						|
  jp nz, .writeRow ; last numerical operation was and a, $F0 so checking if upper byte is zero
 | 
						|
  
 | 
						|
  pop bc
 | 
						|
 | 
						|
  ret
 | 
						|
  
 | 
						|
 | 
						|
  
 | 
						|
; this function is used by practically all the card animations and all over the place.
 | 
						|
; it uses every register. this was a bad idea and i should have just used the stack.
 | 
						|
; if i were rewriting this, i would like to do it differently.
 | 
						|
BuildMetaSprite:
 | 
						|
  ; takkes similar args as copytilestomapunsafe but builds several sprites
 | 
						|
  ; instead.
 | 
						|
  ; location of source tile map: hl
 | 
						|
  ; location in memory to write to: de
 | 
						|
  ; y and x in b and c 
 | 
						|
  ; height and width in a & %11110000 and a & %00001111 ??? that's deranged
 | 
						|
  push hl
 | 
						|
  push de
 | 
						|
  pop hl ; want hl and de to be swapped just for the sake of consistent apis
 | 
						|
  pop de ; hl now holds the OAM location, de holds the sprite map
 | 
						|
  ; fundamentally the reason for this is we need to advance through the OAM 
 | 
						|
  ; four times for every time we addvance de, so it makes maybe more sense
 | 
						|
  ; to increment hl more often? but we can't use hl+ much because we're loading
 | 
						|
  ; from different places. so maybe this is unnecessary
 | 
						|
  push af ; save to the stack so we can retrieve it for row-wise decrement
 | 
						|
  push bc ; hold onto the upper-left corner so we can update it each row
 | 
						|
 | 
						|
  
 | 
						|
.writeRow
 | 
						|
  pop bc 
 | 
						|
  pop af
 | 
						|
  push af
 | 
						|
  push bc ; refresh af and bc from their authoritative stack versions
 | 
						|
  and a, $0F ; take only the horizontal tile count
 | 
						|
 | 
						|
.buildSprite
 | 
						|
  ; 
 | 
						|
  ld [hl], b ; write y byte
 | 
						|
  inc hl 
 | 
						|
  ld [hl], c ; write x byte
 | 
						|
  inc hl 
 | 
						|
  push af ; save a before we use it for transferring de to hl
 | 
						|
  ld a, [de]
 | 
						|
  inc de ; move to the next sprite
 | 
						|
  ld [hl], a 
 | 
						|
  inc hl 
 | 
						|
  res OAMB_XFLIP, [hl] ; make sure xflip is turned off
 | 
						|
  inc hl ; skip the attributes byte
 | 
						|
  ; we're going to wait to get our a value (number of tiles left to draw in this
 | 
						|
  ; row) until after we've used a for changing c
 | 
						|
  
 | 
						|
  ;we've written a whole sprite. hl and de are in the right state, we need to 
 | 
						|
  ; update a and bc.
 | 
						|
  
 | 
						|
  ; update bc
 | 
						|
  ld a, c 
 | 
						|
  add a, 8 
 | 
						|
  ld c, a 
 | 
						|
  pop af ; get back the number of tiles to draw in this row 
 | 
						|
  dec a
 | 
						|
  jp nz, .buildSprite ; if there are still tiles left to draw in this row, do it!
 | 
						|
  
 | 
						|
  ; otherwise we have no more tiles to write this row bc needs to be updated
 | 
						|
  
 | 
						|
  
 | 
						|
  pop bc
 | 
						|
  ld a, b 
 | 
						|
  add a, 8
 | 
						|
  ld b, a ; add 8 to the y coordinate
 | 
						|
  
 | 
						|
  pop af 
 | 
						|
  sub a, $10
 | 
						|
  push af 
 | 
						|
  push bc
 | 
						|
  
 | 
						|
  and a, $F0
 | 
						|
  ; stakc has bc and af, ready for repeating from the top
 | 
						|
  jp nz, .writeRow ; last numerical operation was and a, $F0 so checking if upper byte is zero
 | 
						|
  
 | 
						|
  pop bc
 | 
						|
  pop af 
 | 
						|
  
 | 
						|
  ret
 | 
						|
  
 | 
						|
 | 
						|
  
 | 
						|
  
 | 
						|
  
 | 
						|
BuildMetaSpritePackedHflip:
 | 
						|
  ; same as BuildMetaSprite but it skips blank tiles aand also flips the
 | 
						|
  ; whole thing horizontally
 | 
						|
  push hl
 | 
						|
  push de
 | 
						|
  pop hl ; want hl and de to be swapped just for the sake of consistent apis
 | 
						|
  pop de ; hl now holds the OAM location, de holds the sprite map
 | 
						|
  push af ; save to the stack so we can retrieve it for row-wise decrement
 | 
						|
  push bc ; hold onto the upper-left corner so we can update it each row
 | 
						|
 | 
						|
  
 | 
						|
.writeRow
 | 
						|
  pop bc 
 | 
						|
  pop af
 | 
						|
  push af
 | 
						|
  push bc ; refresh af and bc from their authoritative stack versions
 | 
						|
  and a, $0F ; take only the horizontal tile count
 | 
						|
 | 
						|
.buildSprite
 | 
						|
  ; 
 | 
						|
  ld [hl], b ; write y byte
 | 
						|
  inc hl 
 | 
						|
  ld [hl], c ; write x byte
 | 
						|
  inc hl 
 | 
						|
  push af ; save a before we use it for transferring de to hl
 | 
						|
  
 | 
						|
  ld a, [de]
 | 
						|
  inc de ; move to the next sprite
 | 
						|
  ld [hl], a
 | 
						|
  cp a, 0 
 | 
						|
  jp nz, :+
 | 
						|
 | 
						|
  dec hl 
 | 
						|
  dec hl
 | 
						|
  jp :++
 | 
						|
:
 | 
						|
  inc hl 
 | 
						|
  set OAMB_XFLIP, [hl] ; make sure xflip is turned off
 | 
						|
  inc hl ; skip the attributes byte
 | 
						|
  ; we're going to wait to get our a value (number of tiles left to draw in this
 | 
						|
  ; row) until after we've used a for changing c
 | 
						|
  
 | 
						|
  ;we've written a whole sprite. hl and de are in the right state, we need to 
 | 
						|
  ; update a and bc.
 | 
						|
  
 | 
						|
  ; update bc
 | 
						|
: ld a, c 
 | 
						|
  sub a, 8 
 | 
						|
  ld c, a 
 | 
						|
  pop af ; get back the number of tiles to draw in this row 
 | 
						|
  dec a
 | 
						|
  jp nz, .buildSprite ; if there are still tiles left to draw in this row, do it!
 | 
						|
  
 | 
						|
  ; otherwise we have no more tiles to write this row bc needs to be updated
 | 
						|
  
 | 
						|
  
 | 
						|
  pop bc
 | 
						|
  ld a, b 
 | 
						|
  add a, 8
 | 
						|
  ld b, a ; add 8 to the y coordinate
 | 
						|
  
 | 
						|
  pop af 
 | 
						|
  sub a, $10
 | 
						|
  push af 
 | 
						|
  push bc
 | 
						|
  
 | 
						|
  and a, $F0
 | 
						|
  ; stakc has bc and af, ready for repeating from the top
 | 
						|
  jp nz, .writeRow ; last numerical operation was and a, $F0 so checking if upper byte is zero
 | 
						|
  
 | 
						|
  pop bc
 | 
						|
  pop af 
 | 
						|
  
 | 
						|
  ret
 | 
						|
  
 | 
						|
  
 | 
						|
BuildMetaSpritePacked:
 | 
						|
  ; same args as BuildMetaSprite but this one skips blank sprites.
 | 
						|
  push hl
 | 
						|
  push de
 | 
						|
  pop hl ; want hl and de to be swapped just for the sake of consistent apis
 | 
						|
  pop de ; hl now holds the OAM location, de holds the sprite map
 | 
						|
  push af ; save to the stack so we can retrieve it for row-wise decrement
 | 
						|
  push bc ; hold onto the upper-left corner so we can update it each row
 | 
						|
 | 
						|
  
 | 
						|
.writeRow
 | 
						|
  pop bc 
 | 
						|
  pop af
 | 
						|
  push af
 | 
						|
  push bc ; refresh af and bc from their authoritative stack versions
 | 
						|
  and a, $0F ; take only the horizontal tile count
 | 
						|
 | 
						|
.buildSprite
 | 
						|
  ; 
 | 
						|
  ld [hl], b ; write y byte
 | 
						|
  inc hl 
 | 
						|
  ld [hl], c ; write x byte
 | 
						|
  inc hl 
 | 
						|
  push af ; save a before we use it for transferring de to hl
 | 
						|
  
 | 
						|
  ld a, [de]
 | 
						|
  inc de ; move to the next sprite
 | 
						|
  ld [hl], a
 | 
						|
  cp a, 0 
 | 
						|
  jp nz, :+
 | 
						|
 | 
						|
  dec hl 
 | 
						|
  dec hl
 | 
						|
  jp :++
 | 
						|
:
 | 
						|
  inc hl 
 | 
						|
  res OAMB_XFLIP, [hl] ; make sure xflip is turned off
 | 
						|
  inc hl ; skip the attributes byte
 | 
						|
  ; we're going to wait to get our a value (number of tiles left to draw in this
 | 
						|
  ; row) until after we've used a for changing c
 | 
						|
  
 | 
						|
  ;we've written a whole sprite. hl and de are in the right state, we need to 
 | 
						|
  ; update a and bc.
 | 
						|
  
 | 
						|
  ; update bc
 | 
						|
: ld a, c 
 | 
						|
  add a, 8 
 | 
						|
  ld c, a 
 | 
						|
  pop af ; get back the number of tiles to draw in this row 
 | 
						|
  dec a
 | 
						|
  jp nz, .buildSprite ; if there are still tiles left to draw in this row, do it!
 | 
						|
  
 | 
						|
  ; otherwise we have no more tiles to write this row bc needs to be updated
 | 
						|
  
 | 
						|
  
 | 
						|
  pop bc
 | 
						|
  ld a, b 
 | 
						|
  add a, 8
 | 
						|
  ld b, a ; add 8 to the y coordinate
 | 
						|
  
 | 
						|
  pop af 
 | 
						|
  sub a, $10
 | 
						|
  push af 
 | 
						|
  push bc
 | 
						|
  
 | 
						|
  and a, $F0
 | 
						|
  ; stakc has bc and af, ready for repeating from the top
 | 
						|
  jp nz, .writeRow ; last numerical operation was and a, $F0 so checking if upper byte is zero
 | 
						|
  
 | 
						|
  pop bc
 | 
						|
  pop af 
 | 
						|
  
 | 
						|
  ret
 | 
						|
  
 |