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
 | |
|   
 |