Joined: Wed May 19, 2010 6:12 pm Posts: 2610
|
I'm also trying to do an Alien Soldier type game, but I'm also doing a hell of a lot of sprite animation, which is why that animation code is so long. It has to figure out how a constantly changing combination of sprites onscreen are going to fit into VRAM. I'm still trying to crunch the code down. I hope this is a noticeable improvement.
Code: animation: ldy {metasprite_request} bne + //no animation, if "metasprite_request" is blank jsr clear_vram_slot stz {frame_id} rts +; lda {animation_update} //sprite is animated if "metapsprite" is different from bne + //"metasprite_request" or "animation_update" is set cpy {metasprite} bne + rts +; lda $000c,y tax clc adc {total_dma_legnth} //check if there is enough DMA time for sprite cmp #$0081 bcc ++ lda {first_object_to_dma} bne + tdc sta {first_object_to_dma} +; rts +; stx {vram_size} jsr clear_vram_slot //clear previous animation frame stz {180_degrees_flip} lda {animation_update} cmp #$0002 //if "animation_update" is 2, then frame is rotated 180 degrees bne + lda #$c000 sta {180_degrees_flip} +; stz {animation_update} ldy {metasprite_request} sty {metasprite}
lda $000e,y clc adc {animation_index} inc #2 sta {frame_id} tax lda {animation_copies},x inc sta {animation_copies},x dec beq + //if animation_copies is not 0, then no further processing is needed rts +;
lda $000a,y //find the ROM address of sprite graphics asl #5 //ROM address = metasprite ROM address + (animation frame)*(metasprite ROM size) sta {vram_width} sep #$20 lda {animation_index} lsr sta $4202 lda $000c,y sta $4203 nop rep #$20 lda $4216 asl #5 clc adc $0006,y sta {temp3} //"temp3" is ROM address lda $0008,y sta {temp2} //"temp2" is ROM bank lda $0010,y bpl + //if $0010,y is $7fff or less, it is the metasprite data itself tya //if $0010,y is $8000 or more, it is the address pointing to metasprite data clc adc {animation_index} tax ldy $0010,x +; phd lda #$0000 tcd ldx #$ffff -; lda $0010,y bne + txa invalid_chr: pld ldx {frame_id} sta {animation_chr},x lda {vram_size} clc adc {total_dma_legnth} sta {total_dma_legnth} rts //this is where the game exits the routine +; sty.b {temp5} lda $0012,y sta.b {temp_x} lda $0011,y and #$0070 lsr #4 sta.b {temp8} //"temp8" counts down the horizontal sprite run lda $0018,y adc.b {temp3} -; sta.b {temp} //"temp" is the ROM address of the sprite being added sta.b {temp9} //"temp9" is the ROM address of the top sprite in a vertical run lda $0014,y sta.b {temp_y} lda $0011,y and #$000f sta.b {temp7} //"temp7" counts down the vertical sprite run jmp find_vram_slot find_vram_slot_done: ldy.b {temp5} //this puts all the "OAM" information lda.b {temp6} //onto the linked list ora $0016,y sta {sprite_attributes},x lda.b {temp4} sta {sprite_size},x lda.b {temp_y} sta {sprite_y},x clc adc.b {temp10} sta.b {temp_y} lda.b {temp_x} sta {sprite_x},x dec.b {temp7} //decreases "temp 7" until all sprites bpl find_vram_slot //in the vertical run are put on linked list dec.b {temp8} //decreases "temp 8" until all sprites bmi + //in the horizontal run are put on linked list clc adc.b {temp10} sta.b {temp_x} lda.b {temp10} asl #2 adc.b {temp9} jmp - +; tya clc adc #$000a tay jmp --
find_vram_slot: lda $0010,y txy and #$0003 dec beq small_slot cmp #$0001 beq large_slot
repeat_slot: //this finds repeat slots tsb.b {temp4} ldx {repeat_slot_stack_index} dex dex bpl + tya jmp invalid_chr +; lda {repeat_slot_stack},x stx {repeat_slot_stack_index} tax tya sta {sprite_name},x //puts it on linked list jmp find_vram_slot_done
macro add_and_store(a,b) { adc {a} sta {b},y }
macro find_slot(stack_index,stack) { sta.b {temp4} ldx {stack_index} dex dex bpl + tya jmp invalid_chr +; lda {stack},x stx {stack_index} tax tya sta {sprite_name},x //adds slot to linked list lda x16_lut,x ldy.b {dma_updates} sta {dma_destination},y //sets up dma queue clc add_and_store(#$0100,{dma_destination}+8) }
small_slot: //this finds 16x16 VRAM slot find_slot({small_slot_stack_index},{small_slot_stack}) lda.b {temp} sta {dma_address},y add_and_store({vram_width},{dma_address}+8) adc {vram_width} sta.b {temp} lda.b {temp2} ora #$4000 sta {dma_bank},y sta {dma_bank}+8,y lda #$0010 jmp ++
large_slot: //finds open 32x32 VRAM slot find_slot({large_slot_stack_index},{large_slot_stack}) add_and_store(#$0100,{dma_destination}+16) add_and_store(#$0100,{dma_destination}+24) lda.b {temp} sta {dma_address},y add_and_store({vram_width},{dma_address}+8) add_and_store({vram_width},{dma_address}+16) add_and_store({vram_width},{dma_address}+24) adc {vram_width} sta.b {temp} lda.b {temp2} ora #$8000 sta {dma_bank},y sta {dma_bank}+8,y sta {dma_bank}+16,y sta {dma_bank}+24,y lda #$0020 +; sta.b {temp10} clc adc.b {dma_updates} sta.b {dma_updates} stx.b {temp6} jmp find_vram_slot_done
x16_lut: dw $0000,$0020,$0040,$0060,$0080,$00a0,$00c0,$00e0,$0110,$0120,$0140,$0160,$0180,$01a0,$01c0,$01e0 dw $0200,$0220,$0240,$0260,$0280,$02a0,$02c0,$02e0,$0310,$0320,$0340,$0360,$0380,$03a0,$03c0,$03e0 dw $0400,$0420,$0440,$0460,$0480,$04a0,$04c0,$04e0,$0510,$0520,$0540,$0560,$0580,$05a0,$05c0,$05e0 dw $0600,$0620,$0640,$0660,$0680,$06a0,$06c0,$06e0,$0710,$0720,$0740,$0760,$0780,$07a0,$07c0,$07e0 dw $0800,$0820,$0840,$0860,$0880,$08a0,$08c0,$08e0,$0910,$0920,$0940,$0960,$0980,$09a0,$09c0,$09e0 dw $0a00,$0a20,$0a40,$0a60,$0a80,$0aa0,$0ac0,$0ae0,$0b10,$0b20,$0b40,$0b60,$0b80,$0ba0,$0bc0,$0be0 dw $0c00,$0c20,$0c40,$0c60,$0c80,$0ca0,$0cc0,$0ce0,$0d10,$0d20,$0d40,$0d60,$0d80,$0da0,$0dc0,$0de0 dw $0e00,$0e20,$0e40,$0e60,$0e80,$0ea0,$0ec0,$0ee0,$0f10,$0f20,$0f40,$0f60,$0f80,$0fa0,$0fc0,$0fe0 dw $1000,$1020,$1040,$1060,$1080,$10a0,$10c0,$10e0,$1110,$1120,$1140,$1160,$1180,$11a0,$11c0,$11e0 dw $1200,$1220,$1240,$1260,$1280,$12a0,$12c0,$12e0,$1310,$1320,$1340,$1360,$1380,$13a0,$13c0,$13e0 dw $1400,$1420,$1440,$1460,$1480,$14a0,$14c0,$14e0,$1510,$1520,$1540,$1560,$1580,$15a0,$15c0,$15e0 dw $1600,$1620,$1640,$1660,$1680,$16a0,$16c0,$16e0,$1710,$1720,$1740,$1760,$1780,$17a0,$17c0,$17e0 dw $1800,$1820,$1840,$1860,$1880,$18a0,$18c0,$18e0,$1910,$1920,$1940,$1960,$1980,$19a0,$19c0,$19e0 dw $1a00,$1a20,$1a40,$1a60,$1a80,$1aa0,$1ac0,$1ae0,$1b10,$1b20,$1b40,$1b60,$1b80,$1ba0,$1bc0,$1be0 dw $1c00,$1c20,$1c40,$1c60,$1c80,$1ca0,$1cc0,$1ce0,$1d10,$1d20,$1d40,$1d60,$1d80,$1da0,$1dc0,$1de0 dw $1e00,$1e20,$1e40,$1e60,$1e80,$1ea0,$1ec0,$1ee0,$1f10,$1f20,$1f40,$1f60,$1f80,$1fa0,$1fc0,$1fe0
no_slot_to_clear: plb rts
macro clear_slot(stack_index,stack) { ldx {stack_index} sta {stack},x inx inx stx {stack_index} }
clear_vram_slot: //this routine clears the VRAM slots of the previous animation frame pea $807e plb ldy {frame_id} beq no_slot_to_clear lda {animation_copies}-$7e0000,y beq + dec sta {animation_copies}-$7e0000,y bne no_slot_to_clear +; lda {animation_chr}-$7e0000,y -; cmp #$ffff beq no_slot_to_clear tay ldx {sprite_size}-$7e0000,y beq clear_small_slot cpx #$0001 beq clear_large_slot clear_slot({repeat_slot_stack_index},{repeat_slot_stack}) bra +
clear_small_slot: clear_slot({small_slot_stack_index},{small_slot_stack}) bra +
clear_large_slot: clear_slot({large_slot_stack_index},{large_slot_stack}) +; lda {sprite_name}-$7e0000,y jmp -
Last edited by psycopathicteen on Tue Aug 08, 2017 7:57 pm, edited 1 time in total.
|
|