diff --git a/demos/second/part19_nuts/Makefile b/demos/second/part19_nuts/Makefile index 7459aa0f..fcc24fe8 100644 --- a/demos/second/part19_nuts/Makefile +++ b/demos/second/part19_nuts/Makefile @@ -11,12 +11,13 @@ all: NUTS #### NUTS: nuts.o - ld65 -o NUTS nuts.o -C $(LINKER_SCRIPTS)/apple2_6000.inc + ld65 -o NUTS nuts.o -C $(LINKER_SCRIPTS)/apple2_8000.inc nuts.o: nuts.s \ ../zx02_optim.s \ ../zp.inc ../hardware.inc ../qload2.inc \ - graphics/fc_iipix.hgr.zx02 + graphics/fc_iipix.hgr.zx02 \ + graphics/ship_sprites.inc ca65 -o nuts.o nuts.s -l nuts.lst ### diff --git a/demos/second/part19_nuts/graphics/Makefile b/demos/second/part19_nuts/graphics/Makefile index 59022aaf..9b8d9b7c 100644 --- a/demos/second/part19_nuts/graphics/Makefile +++ b/demos/second/part19_nuts/graphics/Makefile @@ -3,9 +3,20 @@ include ../../../../Makefile.inc ZX02 = ~/research/6502_compression/zx02.git/build/zx02 PNG_TO_HGR = ../../../../utils/hgr-utils/png2hgr PNG2GR = ../../../../utils/gr-utils/png2gr +HGR_SPRITE = ../../../../utils/hgr-utils/hgr_make_sprite all: nuts4.hgr.zx02 nuts_pg.hgr.zx02 nuts_blue.hgr.zx02 \ - fc_grey.hgr.zx02 fc_iipix.hgr.zx02 + fc_grey.hgr.zx02 fc_iipix.hgr.zx02 ship_sprites.inc + +#### + +ship_sprites.inc: ship_sprites.png + $(HGR_SPRITE) -s -l small_ship_sprite ship_sprites.png 14 7 27 13 > ship_sprites.inc + $(HGR_SPRITE) -s -l medium_ship_sprite ship_sprites.png 14 21 41 36 >> ship_sprites.inc + $(HGR_SPRITE) -s -l large_ship_sprite ship_sprites.png 14 49 69 81 >> ship_sprites.inc + + + #### diff --git a/demos/second/part19_nuts/graphics/ship_sprites.png b/demos/second/part19_nuts/graphics/ship_sprites.png new file mode 100644 index 00000000..c1ca9d01 Binary files /dev/null and b/demos/second/part19_nuts/graphics/ship_sprites.png differ diff --git a/demos/second/part19_nuts/hgr_copy_fast.s b/demos/second/part19_nuts/hgr_copy_fast.s new file mode 100644 index 00000000..3fb6861b --- /dev/null +++ b/demos/second/part19_nuts/hgr_copy_fast.s @@ -0,0 +1,54 @@ + ; special case + ;========================================================= + ; hgr copy from $A000/$8000 to current DRAW_PAGE + ;========================================================= + + ; would be faster if we unroll it, but much bigger + + ; old numbers + + ; 14+ ((14*256)+20)*32 + 5 = 115347 = 8.6fps + + ; theoretical unrolled, 30*6 bytes bigger (180 bytes?) + ; 2 + ((9*32)+5)*256 + 5 = 75015 = 13.3 fps + +hgr_copy: + ; copy from in A ($80/$A0) + + sta hgr_copy_smc+2 ; 4 + clc + adc #$20 + sta hgr_copy_end_smc+1 + +; lda #$A0 ; 2 + + ldx #0 ; 2 + + + + lda DRAW_PAGE + clc + adc #$20 + sta hgr_copy_smc+5 ; 4 + +hgr_copy_column: + +hgr_copy_smc: + lda $8000,X ; 4 + sta $2000,X ; 5 + + dex ; 2 + bne hgr_copy_column ; 2nt/3t + + + + inc hgr_copy_smc+2 ; 6 + inc hgr_copy_smc+5 ; 6 + + lda hgr_copy_smc+2 ; 4 +hgr_copy_end_smc: + cmp #$C0 ; 2 + bne hgr_copy_column ; 2/3 + + rts ; 6 + diff --git a/demos/second/part19_nuts/hgr_sprite_big.s b/demos/second/part19_nuts/hgr_sprite_big.s new file mode 100644 index 00000000..e25645eb --- /dev/null +++ b/demos/second/part19_nuts/hgr_sprite_big.s @@ -0,0 +1,205 @@ + ;=========================================== + ; hgr draw sprite (only at 7-bit boundaries) + ;=========================================== + ; can handle sprites bigger than a 256 byte page + + ; Note this is optimized for blue/orange sprites + ; it treats black0 as transparent + + ; SPRITE in INL/INH + ; Location at SPRITE_X SPRITE_Y + + ; xsize, ysize in first two bytes + + ; sprite AT INL/INH + + + ; orange = color5 1 101 0101 1 010 1010 + +hgr_draw_sprite_big: + lda SPRITE_X + ror + bcs hgr_draw_sprite_big_odd + +hgr_draw_sprite_big_even: + ldy #0 + lda (INL),Y ; load xsize + clc + adc SPRITE_X + sta big_sprite_width_end_smc+1 ; self modify for end of line + + iny ; load ysize + lda (INL),Y + sta big_sprite_ysize_smc+1 ; self modify + + ; point smc to sprite + lda INL ; 16-bit add + sta big_sprite_smc1+1 + lda INH + sta big_sprite_smc1+2 + + + ldx #0 ; X is pointer offset + stx CURRENT_ROW ; actual row + + ldx #2 + +hgr_big_sprite_yloop: + + lda CURRENT_ROW ; row + + clc + adc SPRITE_Y ; add in cursor_y + + ; calc GBASL/GBASH + + tay ; get output ROW into GBASL/H + lda hposn_low,Y + sta GBASL + lda hposn_high,Y + + clc + adc DRAW_PAGE + sta GBASH + + ldy SPRITE_X + +big_sprite_inner_loop: + + +big_sprite_smc1: + lda $f000,X ; load sprite data + beq big_sprite_transparent + sta (GBASL),Y ; store to screen + +big_sprite_transparent: + inx ; increment sprite offset + + ; if > 1 page + bne big_sprite_no_page_cross + inc big_sprite_smc1+2 + +big_sprite_no_page_cross: + iny ; increment output position + + +big_sprite_width_end_smc: + cpy #6 ; see if reached end of row + bne big_sprite_inner_loop ; if not, loop + + + inc CURRENT_ROW ; row + lda CURRENT_ROW ; row + +big_sprite_ysize_smc: + cmp #31 ; see if at end + bne hgr_big_sprite_yloop ; if not, loop + + rts + + + +hgr_draw_sprite_big_odd: + ldy #0 + lda (INL),Y ; load xsize + clc + adc SPRITE_X + sta osprite_width_end_smc+1 ; self modify for end of line + + iny ; load ysize + lda (INL),Y + sta osprite_ysize_smc+1 ; self modify + + ; point smc to sprite + lda INL ; 16-bit add + sta osprite_smc1+1 + lda INH + sta osprite_smc1+2 + + + ldx #0 ; X is pointer offset + stx CURRENT_ROW ; actual row + + ldx #2 + +ohgr_sprite_yloop: + + lda CURRENT_ROW ; row + + clc + adc SPRITE_Y ; add in cursor_y + + ; calc GBASL/GBASH + + tay ; get output ROW into GBASL/H + lda hposn_low,Y + sta GBASL + lda hposn_high,Y + + clc + adc DRAW_PAGE + sta GBASH + + ldy SPRITE_X + + clc + php ; store 0 carry on stack + +osprite_inner_loop: + + +osprite_smc1: + lda $f000,X ; load sprite data + + bne osprite_not_transparent + + ; we can't just skip if 0 because we might shift a bit in + ; from previous byte + + plp + bcs osprite_oops + clc + php + bcc osprite_transparent_done + +osprite_not_transparent: + plp ; restore carry from last +osprite_oops: + rol ; rotate in carry + asl ; one more time, bit6 in carry + php ; save on stack + sec ; assume blur/orange + ror ; rotate it back down + + sta (GBASL),Y ; store to screen + + +osprite_transparent_done: + inx ; increment sprite offset + + ; if > 1 page + bne osprite_no_page_cross + inc osprite_smc1+2 + +osprite_no_page_cross: + + iny ; increment output position + + + +osprite_width_end_smc: + cpy #6 ; see if reached end of row + bne osprite_inner_loop ; if not, loop + + + plp ; restore stack + + inc CURRENT_ROW ; row + lda CURRENT_ROW ; row + +osprite_ysize_smc: + cmp #31 ; see if at end + bne ohgr_sprite_yloop ; if not, loop + + rts + diff --git a/demos/second/part19_nuts/nuts.s b/demos/second/part19_nuts/nuts.s index e4c2bb24..8c621def 100644 --- a/demos/second/part19_nuts/nuts.s +++ b/demos/second/part19_nuts/nuts.s @@ -31,9 +31,9 @@ load_loop: lda #0 jsr hgr_page1_clearscreen + jsr hgr_page2_clearscreen -; jsr hgr_make_tables - + bit PAGE2 ; fc logo @@ -41,11 +41,63 @@ load_loop: sta zx_src_l+1 lda #>fc_iipix_data sta zx_src_h+1 - lda #$20 + lda #$60 jsr zx02_full_decomp - jsr wait_until_keypress + lda #0 + sta COUNT + sta DRAW_PAGE + +ship_sprite_loop: + + lda #$60 + jsr hgr_copy + + ldx COUNT + + lda ship_coords_x,X + cmp #$FF + beq done_ship_sprite_loop + + sta SPRITE_X + lda ship_coords_y,X + sta SPRITE_Y + + lda ship_size,X + tax + + lda ship_lookup_low,X + sta INL + lda ship_lookup_high,X + sta INH + + jsr hgr_draw_sprite_big + + lda DRAW_PAGE + beq ship_sprite_flip + + lda #0 + sta DRAW_PAGE + bit PAGE2 + jmp done_ship_sprite_flip + +ship_sprite_flip: + lda #$20 + sta DRAW_PAGE + bit PAGE1 + +done_ship_sprite_flip: + +; jsr wait_until_keypress + + inc COUNT + bne ship_sprite_loop ; bra + +done_ship_sprite_loop: + + bit PAGE1 + ; nuts4 logo lda #small_ship_sprite,>medium_ship_sprite,>large_ship_sprite + diff --git a/demos/second/start2.s b/demos/second/start2.s index 474e34a0..0b427cf9 100644 --- a/demos/second/start2.s +++ b/demos/second/start2.s @@ -136,16 +136,16 @@ load_loop: ;======================= ; run NUTS ;============================================ - ; copy NUTS from AUX $2000 to MAIN $6000 + ; copy NUTS from AUX $2000 to MAIN $8000 lda #$20 ; AUX src $2000 - ldy #$60 ; MAIN dest $6000 + ldy #$80 ; MAIN dest $8000 ldx #32 ; 32 pages jsr copy_aux_main ; run nuts - jsr $6000 + jsr $8000 ;======================= diff --git a/demos/second/zp.inc b/demos/second/zp.inc index 3663b5f7..c23e3b49 100644 --- a/demos/second/zp.inc +++ b/demos/second/zp.inc @@ -140,10 +140,11 @@ SCENE_COUNT = $EC STATE = $ED OFFSET = $EF -IRQ_COUNTDOWN = $F0 -;LASTKEY = $F1 -;PADDLE_STATUS = $F2 +; COMMON DON'T USE +IRQ_COUNTDOWN = $F0 +COUNT = $F1 + SPRITETEMP = $F2 XPOS = $F3 @@ -163,8 +164,7 @@ OUTH = $FF ; tunnel -RR = $F0 -COUNT = $F1 + XX = $F2 MINUSXX = $F3 YY = $F4 @@ -173,12 +173,17 @@ D = $F6 R = $F7 CX = $F8 CY = $F9 +RR = $FA ; Credits -BACKUP_OUTL = $F1 -BACKUP_OUTH = $F2 +BACKUP_OUTL = $F2 +BACKUP_OUTH = $F3 +; Nuts/ operner +SPRITE_Y = $F2 +SPRITE_X = $F3 +CURRENT_ROW = $F4