From a941e5a3df4d32d5c6fa902ef1eea8599e5dab8b Mon Sep 17 00:00:00 2001 From: Vince Weaver Date: Sat, 23 Mar 2019 01:25:13 -0400 Subject: [PATCH] ootw: add cropping sprite support horrible code but seems to work now also room limits are +128 now because I am not smart enough to figure out signed compare on 6502 --- ootw/Makefile | 3 +- ootw/gr_putsprite_crop.s | 192 ++++++++++++++++++++++++++++++++++++++- ootw/ootw_c2.s | 1 + ootw/ootw_c2_jail.s | 8 +- ootw/ootw_cavern.s | 4 +- ootw/ootw_mesa.s | 8 +- ootw/ootw_pool.s | 4 +- ootw/ootw_rope.s | 4 +- ootw/physicist.s | 42 +++++++-- ootw/zp.inc | 2 +- 10 files changed, 241 insertions(+), 27 deletions(-) diff --git a/ootw/Makefile b/ootw/Makefile index 6007d644..5c6c1271 100644 --- a/ootw/Makefile +++ b/ootw/Makefile @@ -22,7 +22,8 @@ OOTW: ootw.o ld65 -o OOTW ootw.o -C ../linker_scripts/apple2_1700.inc ootw.o: ootw.s \ - gr_copy.s gr_fast_clear.s gr_pageflip.s gr_unrle.s gr_putsprite.s \ + gr_copy.s gr_fast_clear.s gr_pageflip.s gr_unrle.s \ + gr_putsprite.s gr_putsprite_flipped.s gr_putsprite_crop.s \ gr_make_quake.s gr_overlay.s zp.inc \ keyboard.s sluggy.s \ ootw_rope.s earthquake.s ootw_mesa.s \ diff --git a/ootw/gr_putsprite_crop.s b/ootw/gr_putsprite_crop.s index 46bfb094..54f79693 100644 --- a/ootw/gr_putsprite_crop.s +++ b/ootw/gr_putsprite_crop.s @@ -16,6 +16,9 @@ put_sprite_crop: lda (INL),Y ; 5 sta CH ; xsize is in CH ; 3 iny ; 2 + clc + adc XPOS + sta XMAX lda (INL),Y ; byte 1 is ysize ; 5 sta CV ; ysize is in CV ; 3 @@ -38,6 +41,7 @@ put_sprite_crop_loop: clc ; 2 adc XPOS ; add in xpos ; 3 sta OUTL ; store out low byte of addy ; 3 + clc ; never wraps, handle negative lda gr_offsets+1,Y ; look up high byte ; 4 adc DRAW_PAGE ; ; 3 sta OUTH ; and store it out ; 3 @@ -45,7 +49,7 @@ put_sprite_crop_loop: ; OUTH:OUTL now points at right place - ldx CH ; load xsize into x ; 3 + ldx XPOS ; load xposition into x ; 3 ;=========== ; 34 crop_put_sprite_pixel: @@ -54,6 +58,11 @@ crop_put_sprite_pixel: sty TEMP ; save sprite pointer ; 3 + cpx #0 ; if off-screen left, skip draw + bmi skip_drawing + cpx #40 + bcs skip_drawing ; if off-screen right, skip draw + ldy #$0 ; 2 ; check if completely transparent @@ -117,11 +126,13 @@ crop_put_sprite_all: ; 9 crop_put_sprite_done_draw: +skip_drawing: ldy TEMP ; restore sprite pointer ; 3 inc OUTL ; increment output pointer ; 5 - dex ; decrement x counter ; 2 + inx ; increment x counter ; 2 + cpx XMAX bne crop_put_sprite_pixel ; if not done, keep looping ; 2nt/3 ;============== ; 12/13 @@ -154,3 +165,180 @@ crop_sprite_done: ; ; + ;============================================= + ; put_sprite_flipped_crop + ;============================================= + ; Sprite to display in INH,INL + ; Location is XPOS,YPOS + ; Note, only works if YPOS is multiple of two + + ; transparent color is $A (grey #2) + ; this means we can have black ($0) in a sprite + + +put_sprite_flipped_crop: + + ldy #0 ; byte 0 is xsize ; 2 + lda (INL),Y ; 5 + sta CH ; xsize is in CH ; 3 + iny ; 2 + + + lda (INL),Y ; byte 1 is ysize ; 5 + sta CV ; ysize is in CV ; 3 + dey ; make Y zero again ; 2 + + lda INH ; ??? + sta ppfc_smc+2 + clc + lda INL + adc #1 ; add one (not two) because X counts + ; from CH to 1 (not CH-1 to 0) + sta ppfc_smc+1 + bcc psfc16 + inc ppfc_smc+2 +psfc16: + + + lda YPOS ; make a copy of ypos ; 3 + + sta TEMPY ; as we modify it ; 3 + ;=========== + ; 28 + + + +put_spritefc_loop: +; sty TEMP ; save sprite pointer ; 3 + ldy TEMPY ; 3 + + bmi fcrop_increment_y ; if < 0, skip to next + cpy #48 ; bge if >= 48, done sprite + bcs fcrop_sprite_done + + + lda gr_offsets,Y ; lookup low-res memory address ; 4 + clc ; 2 + adc XPOS ; add in xpos ; 3 + sta OUTL ; store out low byte of addy ; 3 + lda gr_offsets+1,Y ; look up high byte ; 4 + clc + adc DRAW_PAGE ; ; 3 + sta OUTH ; and store it out ; 3 +; ldy TEMP ; restore sprite pointer ; 3 + + ; OUTH:OUTL now points at right place + + ldx CH ; load xsize into x ; 3 + ;=========== + ; 34 +put_spritefc_pixel: + + sec + txa ; want (CH-X)+XPOS + eor #$ff + adc CH + adc XPOS + + bmi cskip_drawing + cmp #41 + + bcs cskip_drawing ; if off-screen right, skip draw + +ppfc_smc: + lda $C000,X ; get sprite colors ; 5 +; iny ; increment sprite pointer ; 2 +; sty TEMP ; save sprite pointer ; 3 + ldy #$0 ; 2 + + ; check if completely transparent + ; if so, skip + + cmp #$aa ; if all zero, transparent ; 2 + beq put_spritefc_done_draw ; don't draw it ; 2nt/3 + ;============== + ; 16/17 + + sta COLOR ; save color for later ; 3 + + ; check if top pixel transparent + + and #$f0 ; check if top nibble zero ; 2 + cmp #$a0 + bne put_spritefc_bottom ; if not skip ahead ; 2nt/3 + ;============== + ; 7/8 + + lda COLOR + and #$0f + sta COLOR + + lda #$f0 ; setup mask ; 2 + sta MASK ; 3 + bmi put_spritefc_mask ; always? ; 3 + ;============= + ; 8 + +put_spritefc_bottom: + lda COLOR ; re-load color ; 3 + and #$0f ; check if bottom nibble zero ; 2 + cmp #$0a + bne put_spritefc_all ; if not, skip ahead ; 2nt/3 + ;============= + ; 7/8 + + lda COLOR + and #$f0 + sta COLOR + lda #$0f ; 2 + sta MASK ; setup mask ; 3 + ;=========== + ; 5 + +put_spritefc_mask: + lda (OUTL),Y ; get color at output ; 5 + and MASK ; mask off unneeded part ; 3 + ora COLOR ; or the color in ; 3 + sta (OUTL),Y ; store it back ; 6 + + jmp put_spritefc_done_draw ; we are done ; 3 + ;=========== + ; 20 + +put_spritefc_all: + lda COLOR ; load color ; 3 + sta (OUTL),Y ; and write it out ; 6 + ;============ + ; 9 + +put_spritefc_done_draw: +cskip_drawing: +; ldy TEMP ; restore sprite pointer ; 3 + + inc OUTL ; increment output pointer ; 5 + dex ; decrement x counter ; 2 + bne put_spritefc_pixel ; if not done, keep looping ; 2nt/3 + ;============== + ; 12/13 +fcrop_increment_y: + inc TEMPY ; each line has two y vars ; 5 + inc TEMPY ; 5 + + lda CH + clc + adc ppfc_smc+1 + sta ppfc_smc+1 + bcc psfco + inc ppfc_smc+2 +psfco: + + dec CV ; decemenet total y count ; 5 + beq fcrop_sprite_done ; loop if not done ; 2nt/3 + jmp put_spritefc_loop + ;============== + ; 17/18 + +fcrop_sprite_done: + rts ; return ; 6 + + diff --git a/ootw/ootw_c2.s b/ootw/ootw_c2.s index 28493200..db366940 100644 --- a/ootw/ootw_c2.s +++ b/ootw/ootw_c2.s @@ -79,6 +79,7 @@ end_message: .include "gr_copy.s" .include "gr_putsprite.s" .include "gr_putsprite_flipped.s" +.include "gr_putsprite_crop.s" .include "gr_offsets.s" .include "gr_run_sequence.s" .include "gr_overlay.s" diff --git a/ootw/ootw_c2_jail.s b/ootw/ootw_c2_jail.s index 9c93ffef..9c4d86d7 100644 --- a/ootw/ootw_c2_jail.s +++ b/ootw/ootw_c2_jail.s @@ -31,9 +31,9 @@ ootw_jail: bne jail1 jail0: - lda #20 + lda #(20+128) sta LEFT_LIMIT - lda #37 + lda #(39+128) sta RIGHT_LIMIT ; set right exit @@ -56,9 +56,9 @@ jail0: jmp jail_setup_done jail1: - lda #0 + lda #(-4+128) sta LEFT_LIMIT - lda #37 + lda #(39+128) sta RIGHT_LIMIT jail_setup_done: diff --git a/ootw/ootw_cavern.s b/ootw/ootw_cavern.s index d590d4d7..31311e24 100644 --- a/ootw/ootw_cavern.s +++ b/ootw/ootw_cavern.s @@ -19,9 +19,9 @@ ootw_cavern: ;====================== ; setup room boundaries - lda #0 + lda #(0+128) sta LEFT_LIMIT - lda #37 + lda #(37+128) sta RIGHT_LIMIT ;============================= diff --git a/ootw/ootw_mesa.s b/ootw/ootw_mesa.s index 5703aaec..8a80ebb8 100644 --- a/ootw/ootw_mesa.s +++ b/ootw/ootw_mesa.s @@ -23,16 +23,16 @@ ootw_mesa: lda BEAST_OUT ; if beast out, we can go full right beq beast_not_out_yet - lda #37 ; beast trigger + lda #(128+39) ; aliens trigger sta RIGHT_LIMIT jmp mesa_left beast_not_out_yet: - lda #20 ; beast trigger + lda #(128+20) ; beast trigger sta RIGHT_LIMIT mesa_left: - lda #0 + lda #(128-3) sta LEFT_LIMIT ;============================= @@ -226,7 +226,7 @@ trigger_beast: lda #0 sta GAME_OVER - lda #37 ; update right side of screen + lda #(39+128) ; update right side of screen sta RIGHT_LIMIT ; this is mostly for testing jsr beast_cutscene diff --git a/ootw/ootw_pool.s b/ootw/ootw_pool.s index ad7e79c8..391e163b 100644 --- a/ootw/ootw_pool.s +++ b/ootw/ootw_pool.s @@ -25,9 +25,9 @@ ootw_pool: ;=========================== ; Setup right/left exit paramaters - lda #37 + lda #(40+128) sta RIGHT_LIMIT - lda #0 + lda #(-5+128) sta LEFT_LIMIT ;============================= diff --git a/ootw/ootw_rope.s b/ootw/ootw_rope.s index 790b83ce..12b865f6 100644 --- a/ootw/ootw_rope.s +++ b/ootw/ootw_rope.s @@ -19,9 +19,9 @@ ootw_rope: ;================================= ; Setup right/left exit paramaters - lda #37 + lda #(39+128) sta RIGHT_LIMIT - lda #11 + lda #(11+128) sta LEFT_LIMIT lda #0 diff --git a/ootw/physicist.s b/ootw/physicist.s index 369e7399..ca67714d 100644 --- a/ootw/physicist.s +++ b/ootw/physicist.s @@ -293,7 +293,7 @@ facing_left: jmp put_sprite_crop facing_right: - jmp put_sprite_flipped + jmp put_sprite_flipped_crop @@ -303,32 +303,56 @@ facing_right: check_screen_limit: + clc lda PHYSICIST_X + adc #$80 cmp LEFT_LIMIT - bpl just_fine_left ; (bge==bcs) + bcs just_fine_left ; (bge==bcs) too_far_left: -; inc PHYSICIST_X - lda #1 sta GAME_OVER rts just_fine_left: - ; Check right edige of screen + ; Check right edge of screen - lda PHYSICIST_X +; lda PHYSICIST_X cmp RIGHT_LIMIT bcc just_fine_right ; blt too_far_right: - -; dec PHYSICIST_X - lda #2 sta GAME_OVER just_fine_right: rts + + + +; LIMIT VALUE FLAGS +; 0 10 ----- +; 0 0 Z---- +; 0 FF + + +; 1 -> 129 +; 0 -> 128 +; -1 -> 127 FF + 80 = 7f + + + +; XPOS XSIZE XMAX +; -5 8 3 +; -4 4 +; -3 5 +; -2 6 +; -1 7 +; 0 8 +; 1 9 +; 2 +; 3 +; 4 +; 5 diff --git a/ootw/zp.inc b/ootw/zp.inc index c1265569..0d5c425b 100644 --- a/ootw/zp.inc +++ b/ootw/zp.inc @@ -30,7 +30,7 @@ COLOR = $30 SEEDL = $4e SEEDH = $4f - +XMAX = $50 ;INVFLG = $32 ; dos33 zero page = 26-2f, 35-38, 3e 3f 40-4d