diff --git a/desktop/README.md b/desktop/README.md index 2d1717d..2efafe0 100644 --- a/desktop/README.md +++ b/desktop/README.md @@ -201,8 +201,8 @@ $1B00 | & Desk Acc | +-------------+ | | | Save Area | | | | | $0800 +-------------+ +-------------+ - | Text | | Text | - | | | | + | Drawing | | Drawing | + | Temp Buffer | | Temp Buffer | $0400 +-------------+ +-------------+ | Invoker | | | $0300 +-------------+ +-------------+ diff --git a/desktop/mgtk.s b/desktop/mgtk.s index f98f2f2..c7549e9 100644 --- a/desktop/mgtk.s +++ b/desktop/mgtk.s @@ -87,6 +87,7 @@ glyph_last := $FE ; last glyph index glyph_height_p := $FF ; glyph height + ;;; ============================================================ ;;; MGTK @@ -388,8 +389,8 @@ jump_table: .addr ActivateCtlImpl ; $4C ActivateCtl ;; Extra Calls - .addr L51B3 ; $4D ??? - .addr SetMenuSelection ; $4E SetMenuSelection + .addr BitBltImpl ; $4D BitBlt + .addr SetMenuSelectionImpl; $4E SetMenuSelection ;; Entry point param lengths ;; (length, ZP destination, hide cursor flag) @@ -856,29 +857,52 @@ hires_table_hi: ;;; current_penmode ;; ZP usage - src_addr := $82 ; pointer to source bitmap - vid_addr := $84 ; pointer to video memory - left_char := $86 ; offset of leftmost coordinate in chars (0-39) - bits_addr := $8E ; pointer to pattern/bitmap - width_mod14 := $87 ; width of rectangle mod 14 - left_sidemask := $88 ; bitmask applied to clip left edge of rect - right_sidemask := $89 ; bitmask applied to clip right edge of rect - src_y_coord := $8C + src_addr := $82 ; pointer to source bitmap + vid_addr := $84 ; pointer to video memory + left_bytes := $86 ; offset of leftmost coordinate in chars (0-39) + bits_addr := $8E ; pointer to pattern/bitmap + width_mod14 := $87 ; width of rectangle mod 14 + left_sidemask := $88 ; bitmask applied to clip left edge of rect + right_sidemask := $89 ; bitmask applied to clip right edge of rect + src_y_coord := $8C - src_mapwidth := $90 ; source stride; $80 = DHGR layout - width_char := $91 ; width of rectangle in chars + src_mapwidth := $90 ; source stride; $80 = DHGR layout + width_bytes := $91 ; width of rectangle in chars - left_masks_table := $92 ; bitmasks for left edge indexed by page (0=main, 1=aux) - right_masks_table := $96 ; bitmasks for right edge indexed by page (0=main, 1=aux) + left_masks_table := $92 ; bitmasks for left edge indexed by page (0=main, 1=aux) + right_masks_table := $96 ; bitmasks for right edge indexed by page (0=main, 1=aux) - top := $94 ; top/starting/current y-coordinate - bottom := $98 ; bottom/ending/maximum y-coordinate + top := $94 ; top/starting/current y-coordinate + bottom := $98 ; bottom/ending/maximum y-coordinate + left := $92 + right := $96 + fixed_div_dividend := $A1 ; parameters used by fixed_div proc + fixed_div_divisor := $A3 + fixed_div_quotient := $9F ;; Text page usage (main/aux) pattern_buffer := $0400 ; buffer for currently selected pattern (page-aligned) bitmap_buffer := $0601 ; scratchpad area for drawing bitmaps/patterns + poly_maxima_links := $0428 + poly_maxima_prev_vertex := $0468 + poly_maxima_next_vertex := $04A8 + poly_maxima_slope0 := $0528 + poly_maxima_slope1 := $04E8 + poly_maxima_slope2 := $0568 + poly_maxima_slope3 := $05A8 + poly_maxima_yl_table := $05E8 + + poly_vertex_prev_link := $0680 + poly_vertex_next_link := $06BC + + poly_xl_buffer := $0700 + poly_xh_buffer := $073C + poly_yl_buffer := $0780 + poly_yh_buffer := $07BC + + .assert pattern_buffer @@ -1190,7 +1214,7 @@ start_fill_jmp_addr := *+1 ror a ror a and #$C0 ; to high 2 bits - ora left_char + ora left_bytes sta bits_addr lda #>pattern_buffer @@ -1213,7 +1237,7 @@ next_line_jmp_addr := *+1 bcc :+ inc vid_addr+1 clc -: ldy width_char +: ldy width_bytes jsr fillmode_jmp jmp fill_next_line @@ -1228,7 +1252,7 @@ next_line_jmp_addr := *+1 sta vid_addr+1 lda hires_table_lo,x clc - adc left_char + adc left_bytes sta vid_addr ldy #1 ; aux mem @@ -1252,7 +1276,7 @@ next_line_jmp_addr := *+1 ora #$80 sta right_sidemask - ldy width_char + ldy width_bytes ;; Fall-through .endproc @@ -1308,8 +1332,8 @@ fill_mode_table_onechar: x1 := $92 x2 := $96 - x1_char := $86 - x2_char := $82 + x1_bytes := $86 + x2_bytes := $82 add16 x_offset, x2, x2 add16 y_offset, bottom, bottom @@ -1327,8 +1351,8 @@ fill_mode_table_onechar: lda div7_table,x ldy mod7_table,x -set_x2_char: - sta x2_char +set_x2_bytes: + sta x2_bytes tya rol a tay @@ -1345,8 +1369,8 @@ set_x2_char: lda div7_table,x ldy mod7_table,x -set_x1_char: - sta x1_char +set_x1_bytes: + sta x1_bytes tya rol a tay @@ -1355,12 +1379,12 @@ set_x1_char: sta left_masks_table+1 lda main_left_masks,y sta left_masks_table - lda x2_char + lda x2_bytes sec - sbc x1_char + sbc x1_bytes set_width: ; Set width for destination. - sta width_char + sta width_bytes pha lda current_penmode asl a @@ -1393,7 +1417,7 @@ ll_ge256: ; Divmod for left limit >= 256 adc #$24 plp ldy mod7_table+4,x - bpl set_x1_char + bpl set_x1_bytes rl_ge256: ; Divmod for right limit >= 256 lda x2 @@ -1406,7 +1430,7 @@ rl_ge256: ; Divmod for right limit >= 256 plp ldy mod7_table+4,x bmi divmod7 - jmp set_x2_char + jmp set_x2_bytes .endproc @@ -1435,11 +1459,11 @@ rl_ge256: ; Divmod for right limit >= 256 ;; Set up destination (for either on-screen or off-screen bitmap.) -.proc set_up_dest +.proc set_dest DEST_NDBM := 0 ; draw to off-screen bitmap DEST_DHGR := 1 ; draw to DHGR screen - lda left_char + lda left_bytes ldx top ldy current_mapwidth jsr ndbm_calc_dest @@ -1461,7 +1485,7 @@ rl_ge256: ; Divmod for right limit >= 256 jsr ndbm_fix_width txa inx - stx src_width_char + stx src_width_bytes jsr set_up_fill_mode::set_width copy16 shift_line_jmp_addr, dhgr_get_srcbits::shift_bits_jmp_addr @@ -1486,7 +1510,7 @@ on_screen: ;; Fix up the width and masks for an off-screen destination, ndbm_fix_width: - lda width_char + lda width_bytes asl a tax inx @@ -1520,7 +1544,7 @@ shift_line_table: ;; Set source for bitmap transfer (either on-screen or off-screen bitmap.) -.proc set_up_source +.proc set_source SRC_NDBM := 0 SRC_DHGR := 1 @@ -1587,169 +1611,193 @@ ndbm_calc_off := ndbm_calc_dest::calc_off ;;; ============================================================ ;;; SetPattern -SetPatternImpl: - lda #$00 - sta $8E +;; Expands the pattern to 8 rows of DHGR-style bitmaps at +;; $0400, $0440, $0480, $04C0, $0500, $0540, $0580, $05C0 +;; (using both main and aux mem.) + +.proc SetPatternImpl + lda #pattern_buffer + sta bits_addr+1 + + ldx #7 +loop: lda x_offset + and #7 tay + lda current_penpattern,x -L4FAA: dey - bmi L4FB2 +: dey + bmi :+ cmp #$80 rol a - bne L4FAA -L4FB2: ldy #$27 -L4FB4: pha + bne :- + +: ldy #$27 +: pha lsr a sta LOWSCR - sta ($8E),y + sta (bits_addr),y pla ror a pha lsr a sta HISCR - sta ($8E),y + sta (bits_addr),y pla ror a dey - bpl L4FB4 - lda $8E + bpl :- + + lda bits_addr sec sbc #$40 - sta $8E - bcs L4FDD - ldy $8F + sta bits_addr + bcs next + + ldy bits_addr+1 dey - cpy #$04 - bcs L4FDB - ldy #$05 -L4FDB: sty $8F -L4FDD: dex - bpl L4FA3 + cpy #>pattern_buffer + bcs :+ + ldy #>pattern_buffer+1 +: sty bits_addr+1 + +next: dex + bpl loop sta LOWSCR rts +.endproc + ;;; ============================================================ ;;; FrameRect -;;; 4 bytes of params, copied to $9F +;;; 8 bytes of params, copied to $9F -L4FE4: .byte 0 - -FrameRectImpl: +frect_ctr: .byte 0 +.proc FrameRectImpl left := $9F + top := $A1 right := $A3 + bottom := $A5 - ldy #$03 -L4FE7: ldx #$07 -L4FE9: lda $9F,x - sta $92,x + ldy #3 +rloop: ldx #7 +: lda left,x + sta left_masks_table,x dex - bpl L4FE9 - ldx L5016,y - lda $9F,x + bpl :- + ldx rect_sides,y + lda left,x pha lda $A0,x - ldx L501A,y + ldx rect_coords,y sta $93,x pla - sta $92,x - sty L4FE4 - jsr L501E - ldy L4FE4 + sta left_masks_table,x + sty frect_ctr + jsr draw_line + ldy frect_ctr dey - bpl L4FE7 - ldx #$03 -L500E: lda $9F,x + bpl rloop + ldx #3 +: lda left,x sta current_penloc,x dex - bpl L500E -L5015: rts + bpl :- +.endproc +prts: rts -L5016: .byte $00,$02,$04,$06 -L501A: .byte $04,$06,$00,$02 +rect_sides: + .byte 0,2,4,6 +rect_coords: + .byte 4,6,0,2 -L501E: lda current_penwidth ; Also: draw horizontal line $92 to $96 at $98 +.proc draw_line + x2 := right + + lda current_penwidth ; Also: draw horizontal line $92 to $96 at $98 sec sbc #1 cmp #$FF - beq L5015 - adc $96 - sta $96 - bcc L502F - inc $96+1 + beq prts + adc x2 + sta x2 + bcc :+ + inc x2+1 -L502F: lda current_penheight +: lda current_penheight sec sbc #1 cmp #$FF - beq L5015 - adc $98 - sta $98 + beq prts + adc bottom + sta bottom bcc PaintRectImpl - inc $98+1 + inc bottom+1 ;; Fall through... +.endproc + ;;; ============================================================ ;;; PaintRect -;;; 4 bytes of params, copied to $92 +;;; 8 bytes of params, copied to $92 -PaintRectImpl: - jsr L514C -L5043: jsr L50A9 - bcc L5015 +.proc PaintRectImpl + jsr check_rect +do_paint: + jsr clip_rect + bcc prts jsr set_up_fill_mode - jsr set_up_dest + jsr set_dest jmp do_fill +.endproc + ;;; ============================================================ ;;; InRect -;;; 4 bytes of params, copied to $92 +;;; 8 bytes of params, copied to $92 .proc InRectImpl - - left := $92 - right := $96 - - jsr L514C + jsr check_rect ldax current_penloc_x cpx left+1 bmi fail bne :+ cmp left bcc fail + : cpx right+1 bmi :+ bne fail cmp right bcc :+ bne fail + : ldax current_penloc_y cpx top+1 bmi fail bne :+ cmp top bcc fail + : cpx bottom+1 bmi :+ bne fail cmp bottom bcc :+ bne fail -: exit_call $80 ; success! +: exit_call MGTK::error_in_object ; success! fail: rts .endproc @@ -1757,113 +1805,139 @@ fail: rts ;;; ============================================================ ;;; SetPortBits -SetPortBitsImpl: +.proc SetPortBitsImpl sub16 current_viewloc_x, current_maprect_x1, x_offset sub16 current_viewloc_y, current_maprect_y1, y_offset rts +.endproc -L50A9: lda current_maprect_x2+1 - cmp $92+1 - bmi L50B7 - bne L50B9 + + clipped_left := $9B ; number of bits clipped off left side + clipped_top := $9D ; number of bits clipped off top side + + +.proc clip_rect + lda current_maprect_x2+1 + cmp left+1 + bmi fail + bne in_left lda current_maprect_x2 - cmp $92 - bcs L50B9 -L50B7: clc -L50B8: rts + cmp left + bcs in_left +fail: clc +fail2: rts -L50B9: lda $96+1 +in_left: + lda right+1 cmp current_maprect_x1+1 - bmi L50B7 - bne L50C7 - lda $96 + bmi fail + bne in_right + lda right cmp current_maprect_x1 - bcc L50B8 -L50C7: lda current_maprect_y2+1 - cmp $94+1 - bmi L50B7 - bne L50D5 + bcc fail2 + +in_right: + lda current_maprect_y2+1 + cmp top+1 + bmi fail + bne in_bottom lda current_maprect_y2 - cmp $94 - bcc L50B8 -L50D5: lda $98+1 + cmp top + bcc fail2 + +in_bottom: + lda bottom+1 cmp current_maprect_y1+1 - bmi L50B7 - bne L50E3 - lda $98 + bmi fail + bne in_top + lda bottom cmp current_maprect_y1 - bcc L50B8 -L50E3: ldy #$00 - lda $92 + bcc fail2 + +in_top: ldy #0 + lda left sec sbc current_maprect_x1 tax - lda $92+1 + lda left+1 sbc current_maprect_x1+1 - bpl L50FE - stx $9B - sta $9C - copy16 current_maprect_x1, $92 + bpl :+ + + stx clipped_left + sta clipped_left+1 + copy16 current_maprect_x1, left iny -L50FE: lda current_maprect_x2 + +: lda current_maprect_x2 sec - sbc $96 + sbc right tax lda current_maprect_x2+1 - sbc $96+1 - bpl L5116 - copy16 current_maprect_x2, $96 + sbc right+1 + bpl :+ + + copy16 current_maprect_x2, right tya ora #$04 tay -L5116: lda $94 + +: lda top sec sbc current_maprect_y1 tax - lda $94+1 + lda top+1 sbc current_maprect_y1+1 - bpl L5130 - stx $9D - sta $9E - copy16 current_maprect_y1, $94 + bpl :+ + + stx clipped_top + sta clipped_top+1 + copy16 current_maprect_y1, top iny iny -L5130: lda current_maprect_y2 + +: lda current_maprect_y2 sec - sbc $98 + sbc bottom tax lda current_maprect_y2+1 - sbc $98+1 - bpl L5148 - copy16 current_maprect_y2, $98 + sbc bottom+1 + bpl :+ + copy16 current_maprect_y2, bottom tya ora #$08 tay -L5148: sty $9A + +: sty $9A sec rts +.endproc -L514C: sec - lda $96 - sbc $92 - lda $96+1 - sbc $92+1 - bmi L5163 + +.proc check_rect sec - lda $98 - sbc $94 - lda $98+1 - sbc $94+1 - bmi L5163 + lda right + sbc left + lda right+1 + sbc left+1 + bmi bad_rect + sec + lda bottom + sbc top + lda bottom+1 + sbc top+1 + bmi bad_rect rts -L5163: exit_call $81 +bad_rect: + exit_call MGTK::error_empty_object +.endproc + ;;; ============================================================ ;;; 16 bytes of params, copied to $8A -src_width_char: +src_width_bytes: .res 1 ; width of source data in chars L5169: .byte 0 @@ -1872,16 +1946,19 @@ PaintBitsImpl: dbi_left := $8A dbi_top := $8C - dbi_bitmap := $8E - dbi_stride := $90 - dbi_hoff := $92 - dbi_voff := $94 - dbi_width := $96 - dbi_height := $98 + dbi_bitmap := $8E ; aka bits_addr + dbi_stride := $90 ; aka src_mapwidth + dbi_hoff := $92 ; aka left + dbi_voff := $94 ; aka top + dbi_width := $96 ; aka right + dbi_height := $98 ; aka bottom dbi_x := $9B dbi_y := $9D + offset := $82 + + ldx #3 ; copy left/top to $9B/$9D : lda dbi_left,x ; and hoff/voff to $8A/$8C (overwriting left/top) sta dbi_x,x @@ -1890,133 +1967,159 @@ PaintBitsImpl: dex bpl :- - sub16 dbi_width, dbi_hoff, $82 + sub16 dbi_width, dbi_hoff, offset lda dbi_x - sta dbi_hoff + sta left clc - adc $82 - sta dbi_width + adc offset + sta right lda dbi_x+1 - sta dbi_hoff+1 - adc $83 - sta dbi_width+1 + sta left+1 + adc offset+1 + sta right+1 - sub16 dbi_height, dbi_voff, $82 + sub16 dbi_height, dbi_voff, offset lda dbi_y - sta dbi_voff + sta top clc - adc $82 - sta dbi_height + adc offset + sta bottom lda dbi_y+1 - sta dbi_voff+1 - adc $83 - sta dbi_height+1 - ;; fall through + sta top+1 + adc offset+1 + sta bottom+1 + ;; fall through to BitBlt ;;; ============================================================ -;;; $4D IMPL +;;; $4D BitBlt ;;; 16 bytes of params, copied to $8A -L51B3: lda #0 - sta $9B - sta $9C - sta $9D - lda $8F + src_byte_off := $8A ; char offset within source line + bit_offset := $9B + shift_bytes := $81 + +.proc BitBltImpl + lda #0 + sta clipped_left + sta clipped_left+1 + sta clipped_top + + lda bits_addr+1 sta $80 - jsr L50A9 - bcs L51C5 + + jsr clip_rect + bcs :+ rts -L51C5: jsr set_up_fill_mode - lda $91 +: jsr set_up_fill_mode + lda width_bytes asl a - ldx $93 - beq L51D1 + ldx left_masks_table+1 ; need left mask on aux? + beq :+ adc #1 -L51D1: ldx $96 - beq L51D7 +: ldx right_masks_table ; need right mask on main? + beq :+ adc #1 -L51D7: sta L5169 - sta src_width_char +: sta L5169 + sta src_width_bytes ; adjusted width in chars + lda #2 - sta $81 - lda #0 - sec - sbc $9D + sta shift_bytes + lda #0 ; Calculate starting Y-coordinate + sec ; = dbi_top - clipped_top + sbc clipped_top clc - adc $8C - sta $8C - lda #0 - sec - sbc $9B + adc dbi_top + sta dbi_top + + lda #0 ; Calculate starting X-coordinate + sec ; = dbi_left - clipped_left + sbc clipped_left tax lda #0 - sbc $9C + sbc clipped_left+1 tay + txa clc - adc $8A + adc dbi_left tax tya - adc $8B + adc dbi_left+1 + jsr divmod7 - sta $8A - tya + sta src_byte_off + tya ; bit offset between src and dest rol a cmp #7 ldx #1 - bcc L520E + bcc :+ dex sbc #7 -L520E: stx dhgr_get_srcbits::offset1_addr + +: stx dhgr_get_srcbits::offset1_addr inx stx dhgr_get_srcbits::offset2_addr - sta $9B - lda $8A + sta bit_offset + + lda src_byte_off rol a - jsr set_up_source - jsr set_up_dest - copy16 #$0601, $8E - ldx #$01 - lda $87 + + jsr set_source + jsr set_dest + copy16 #bitmap_buffer, bits_addr + ldx #1 + lda width_mod14 + sec - sbc #$07 - bcc L5234 - sta $87 + sbc #7 + bcc :+ + sta width_mod14 dex -L5234: stx dhgr_shift_line::offset1_addr +: stx dhgr_shift_line::offset1_addr inx stx dhgr_shift_line::offset2_addr - lda $87 + + lda width_mod14 sec - sbc $9B - bcs L5249 + sbc bit_offset + bcs :+ adc #7 - inc src_width_char - dec $81 -L5249: tay - bne L5250 - ldx #0 - beq L5276 -L5250: tya + inc src_width_bytes + dec shift_bytes +: tay ; check if bit shift required + bne :+ + ldx #2*BITS_NO_BITSHIFT + beq no_bitshift + +: tya asl a tay copy16 shift_table_main,y, dhgr_shift_bits::shift_main_addr copy16 shift_table_aux,y, dhgr_shift_bits::shift_aux_addr - ldy $81 + ldy shift_bytes sty dhgr_shift_bits::offset2_addr dey sty dhgr_shift_bits::offset1_addr - ldx #2 -L5276: copy16 L5285,x, dhgr_get_srcbits::shift_bits_jmp_addr + + ldx #2*BITS_BITSHIFT +no_bitshift: + copy16 shift_bits_table,x, dhgr_get_srcbits::shift_bits_jmp_addr jmp bit_blit -L5285: .addr shift_line_jmp, dhgr_shift_bits +BITS_NO_BITSHIFT := 0 +BITS_BITSHIFT := 1 + +;; BITS_NO_BITSHIFT BITS_BITSHIFT +shift_bits_table: + .addr shift_line_jmp, dhgr_shift_bits +.endproc + shift_table_aux := *-2 .addr shift_1_aux,shift_2_aux,shift_3_aux @@ -2027,106 +2130,147 @@ L5285: .addr shift_line_jmp, dhgr_shift_bits .addr shift_4_main,shift_5_main,shift_6_main -L52A1: stx $B0 - asl a - asl a - sta $B3 + vertex_limit := $B3 + vertices_count := $B4 + poly_oper := $BA ; positive = paint; negative = test + start_index := $AE + poly_oper_paint := $00 + poly_oper_test := $80 + + +.proc load_poly + point_index := $82 + low_point := $A7 + + max_poly_points := 60 + + stx $B0 + asl a + asl a ; # of vertices * 4 = length + sta vertex_limit + + ;; Initialize rect to first point of polygon. ldy #3 ; Copy params_addr... to $92... and $96... : lda (params_addr),y - sta $92,y - sta $96,y + sta left,y + sta right,y dey bpl :- - copy16 $94, $A7 ; y coord + copy16 top, low_point ; y coord + ldy #0 - stx $AE -L52C0: stx $82 + stx start_index +loop: stx point_index + lda (params_addr),y - sta $0700,x + sta poly_xl_buffer,x pha iny lda (params_addr),y - sta $073C,x + sta poly_xh_buffer,x tax pla iny - cpx $92+1 - bmi L52DB - bne L52E1 - cmp $92 - bcs L52E1 -L52DB: stax $92 - bcc L52EF -L52E1: cpx $96+1 - bmi L52EF - bne L52EB - cmp $96 - bcc L52EF -L52EB: stax $96 -L52EF: ldx $82 + + cpx left+1 + bmi :+ + bne in_left + cmp left + bcs in_left + +: stax left + bcc in_right + +in_left: + cpx right+1 + bmi in_right + bne :+ + cmp right + bcc in_right + +: stax right + +in_right: + ldx point_index lda (params_addr),y - sta $0780,x + sta poly_yl_buffer,x pha iny lda (params_addr),y - sta $07BC,x + sta poly_yh_buffer,x tax pla iny - cpx $94+1 - bmi L530A - bne L5310 - cmp $94 - bcs L5310 -L530A: stax $94 - bcc L531E -L5310: cpx $98+1 - bmi L531E - bne L531A - cmp $98 - bcc L531E -L531A: stax $98 -L531E: cpx $A8 - stx $A8 - bmi L5330 - bne L532C - cmp $A7 - bcc L5330 - beq L5330 -L532C: ldx $82 - stx $AE -L5330: sta $A7 - ldx $82 + + cpx top+1 + bmi :+ + bne in_top + cmp top + bcs in_top + +: stax top + bcc in_bottom + +in_top: cpx bottom+1 + bmi in_bottom + bne :+ + cmp bottom + bcc in_bottom + +: stax bottom + +in_bottom: + cpx low_point+1 + stx low_point+1 + bmi set_low_point + bne :+ + cmp low_point + bcc set_low_point + beq set_low_point + +: ldx point_index + stx start_index + +set_low_point: + sta low_point + + ldx point_index inx - cpx #$3C - beq L5398 - cpy $B3 - bcc L52C0 - lda $94 - cmp $98 - bne L5349 - lda $94+1 - cmp $98+1 - beq L5398 -L5349: stx $B3 - bit $BA - bpl L5351 + cpx #max_poly_points + beq bad_poly + cpy vertex_limit + bcc loop + + lda top + cmp bottom + bne :+ + lda top+1 + cmp bottom+1 + beq bad_poly + +: stx vertex_limit + bit poly_oper + bpl :+ sec rts -L5351: jmp L50A9 +: jmp clip_rect +.endproc -L5354: lda $B4 - bpl L5379 + +.proc next_poly + lda vertices_count + bpl orts asl a asl a adc params_addr sta params_addr bcc ora_2_param_bytes inc params_addr+1 - + ;; Fall-through +.endproc ;; ORAs together first two bytes at (params_addr) and stores ;; in $B4, then advances params_addr @@ -2135,441 +2279,558 @@ ora_2_param_bytes: lda (params_addr),y iny ora (params_addr),y - sta $B4 + sta vertices_count inc16 params_addr inc16 params_addr ldy #$80 -L5379: rts +orts: rts ;;; ============================================================ ;;; InPoly InPolyImpl: - lda #$80 - bne L5380 + lda #poly_oper_test + bne PaintPolyImpl_entry2 ;;; ============================================================ ;;; PaintPoly ;; also called from the end of LineToImpl -PaintPolyImpl: lda #$00 -L5380: sta $BA + num_maxima := $AD + max_num_maxima := 8 + + low_vertex := $B0 + + +.proc PaintPolyImpl + + lda #poly_oper_paint +entry2: sta poly_oper ldx #0 - stx $AD + stx num_maxima jsr ora_2_param_bytes -L5389: jsr L52A1 - bcs L539D - ldx $B0 -L5390: jsr L5354 - bmi L5389 - jmp L546F -L5398: exit_call $82 +loop: jsr load_poly + bcs process_poly + ldx low_vertex +next: jsr next_poly + bmi loop + + jmp fill_polys + +bad_poly: + exit_call MGTK::error_bad_object +.endproc + + + temp_yh := $83 + next_vertex := $AA + current_vertex := $AC + loop_ctr := $AF + + +.proc process_poly + ldy #1 + sty loop_ctr ; do 2 iterations of the following loop + + ldy start_index ; starting vertex + cpy low_vertex ; lowest vertex + bne :+ + ldy vertex_limit ; highest vertex +: dey + sty $AB ; one before starting vertex -L539D: ldy #1 - sty $AF - ldy $AE - cpy $B0 - bne L53A9 - ldy $B3 -L53A9: dey - sty $AB php -L53AD: sty $AC +loop: sty current_vertex ; current vertex iny - cpy $B3 - bne L53B6 - ldy $B0 -L53B6: sty $AA - cpy $AE - bne L53BE - dec $AF -L53BE: lda $0780,y - ldx $07BC,y - stx $83 -L53C6: sty $A9 - iny - cpy $B3 - bne L53CF - ldy $B0 -L53CF: cmp $0780,y - bne L53DB - ldx $07BC,y - cpx $83 - beq L53C6 -L53DB: ldx $AB + cpy vertex_limit + bne :+ + ldy low_vertex + +: sty next_vertex ; next vertex + cpy start_index ; have we come around complete circle? + bne :+ + dec loop_ctr ; this completes one loop + +: lda poly_yl_buffer,y + ldx poly_yh_buffer,y + stx temp_yh +vloop: sty $A9 ; starting from next vertex, search ahead + iny ; for a subsequent vertex with differing y + cpy vertex_limit + bne :+ + ldy low_vertex +: + cmp poly_yl_buffer,y + bne :+ + ldx poly_yh_buffer,y + cpx temp_yh + beq vloop + +: ldx $AB ; find y difference with current vertex sec - sbc $0780,x - lda $83 - sbc $07BC,x - bmi L5448 - lda $A9 - plp - bmi L53F8 + sbc poly_yl_buffer,x + lda temp_yh + sbc poly_yh_buffer,x + bmi y_less + + lda $A9 ; vertex before new vertex + + plp ; check maxima flag + bmi new_maxima ; if set, go create new maxima + tay - sta $0680,x - lda $AA - sta $06BC,x - bpl L545D -L53F8: ldx $AD - cpx #$10 - bcs L5398 - sta $0468,x - lda $AA - sta $04A8,x + sta poly_vertex_prev_link,x ; link current vertex -> vertex before new vertex + lda next_vertex + sta poly_vertex_next_link,x ; link current vertex -> next vertex + bpl next + +new_maxima: + ldx num_maxima + cpx #2*max_num_maxima ; too many maxima points (documented limitation) + bcs bad_poly + + sta poly_maxima_prev_vertex,x ; vertex before new vertex + lda next_vertex + sta poly_maxima_next_vertex,x ; current vertex + ldy $AB - lda $0680,y - sta $0469,x - lda $06BC,y - sta $04A9,x - lda $0780,y - sta $05E8,x - sta $05E9,x - lda $07BC,y - sta low_zp_stash_buffer,x - sta L5E02,x - lda $0700,y - sta L5E32,x - lda $073C,y - sta L5E42,x - ldy $AC - lda $0700,y - sta L5E31,x - lda $073C,y - sta L5E41,x + lda poly_vertex_prev_link,y + sta poly_maxima_prev_vertex+1,x + lda poly_vertex_next_link,y + sta poly_maxima_next_vertex+1,x + + lda poly_yl_buffer,y + sta poly_maxima_yl_table,x + sta poly_maxima_yl_table+1,x + + lda poly_yh_buffer,y + sta poly_maxima_yh_table,x + sta poly_maxima_yh_table+1,x + + lda poly_xl_buffer,y + sta poly_maxima_xl_table+1,x + lda poly_xh_buffer,y + sta poly_maxima_xh_table+1,x + + ldy current_vertex + lda poly_xl_buffer,y + sta poly_maxima_xl_table,x + lda poly_xh_buffer,y + sta poly_maxima_xh_table,x inx inx - stx $AD + stx num_maxima ldy $A9 - bpl L545D -L5448: plp - bmi L5450 + bpl next + +y_less: plp ; check maxima flag + bmi :+ lda #$80 - sta $0680,x -L5450: ldy $AA + sta poly_vertex_prev_link,x ; link current vertex -> #$80 + +: ldy next_vertex txa - sta $0680,y - lda $AC - sta $06BC,y - lda #$80 -L545D: php + sta poly_vertex_prev_link,y ; link next vertex -> current vertex + lda current_vertex + sta poly_vertex_next_link,y + lda #$80 ; set negative flag so next iteration captures a maxima + +next: php sty $AB ldy $A9 - bit $AF - bmi L5469 - jmp L53AD + bit loop_ctr + bmi :+ + jmp loop -L5469: plp - ldx $B3 - jmp L5390 +: plp + ldx vertex_limit + jmp PaintPolyImpl::next +.endproc -L546F: ldx #$00 - stx $B1 + + scan_y := $A9 + lr_flag := $AB + start_maxima := $B1 + +.proc fill_polys + ldx #0 + stx start_maxima lda #$80 - sta $0428 + sta poly_maxima_links sta $B2 -L547A: inx - cpx $AD - bcc L5482 - beq L54B2 + +loop: inx + cpx num_maxima + bcc :+ + beq links_done rts -L5482: lda $B1 -L5484: tay - lda $05E8,x - cmp $05E8,y - bcs L54A2 - tya - sta $0428,x - cpy $B1 - beq L549E +: lda start_maxima +next_link: + tay + lda poly_maxima_yl_table,x + cmp poly_maxima_yl_table,y + bcs x_ge_y + tya ; poly_maxima_y[xReg] < poly_maxima_y[yReg] + sta poly_maxima_links,x ; then xReg linked to yReg + cpy start_maxima + beq :+ ; if yReg was the start, set the start to xReg ldy $82 txa - sta $0428,y - jmp L547A + sta poly_maxima_links,y ; else $82 linked to xReg + jmp loop -L549E: stx $B1 - bcs L547A -L54A2: sty $82 - lda $0428,y - bpl L5484 - sta $0428,x +: stx start_maxima ; set start to xReg + bcs loop ; always + +x_ge_y: sty $82 ; poly_maxima_y[xReg] >= poly_maxima_y[yReg] + lda poly_maxima_links,y + bpl next_link ; if yReg was the end + sta poly_maxima_links,x ; then set xReg as end txa - sta $0428,y - bpl L547A -L54B2: ldx $B1 - lda $05E8,x - sta $A9 - sta $94 - lda low_zp_stash_buffer,x - sta $AA - sta $95 -L54C2: ldx $B1 + sta poly_maxima_links,y ; and link yReg to xReg + bpl loop ; always +links_done: + + ldx start_maxima + lda poly_maxima_yl_table,x + sta scan_y + sta top + lda poly_maxima_yh_table,x + sta scan_y+1 + sta top+1 + +scan_loop: + ldx start_maxima bmi L5534 -L54C6: lda $05E8,x - cmp $A9 +scan_next: + lda poly_maxima_yl_table,x + cmp scan_y bne L5532 - lda low_zp_stash_buffer,x - cmp $AA + lda poly_maxima_yh_table,x + cmp scan_y+1 bne L5532 - lda $0428,x + + lda poly_maxima_links,x sta $82 - jsr L5606 + jsr calc_slope + lda $B2 bmi L5517 + L54E0: tay - lda L5E41,x - cmp L5E41,y + lda poly_maxima_xh_table,x + cmp poly_maxima_xh_table,y bmi L5520 - bne L5507 - lda L5E31,x - cmp L5E31,y + bne :+ + + lda poly_maxima_xl_table,x + cmp poly_maxima_xl_table,y bcc L5520 - bne L5507 - lda L5E11,x - cmp L5E11,y + bne :+ + + lda poly_maxima_x_frach,x + cmp poly_maxima_x_frach,y bcc L5520 - bne L5507 - lda L5E21,x - cmp L5E21,y + bne :+ + + lda poly_maxima_x_fracl,x + cmp poly_maxima_x_fracl,y bcc L5520 -L5507: sty $83 - lda $0428,y + +: sty $83 + lda poly_maxima_links,y bpl L54E0 - sta $0428,x + sta poly_maxima_links,x txa - sta $0428,y + sta poly_maxima_links,y bpl L552E -L5517: sta $0428,x + +L5517: sta poly_maxima_links,x stx $B2 jmp L552E -L551F: rts +done: rts L5520: tya cpy $B2 beq L5517 - sta $0428,x + sta poly_maxima_links,x txa ldy $83 - sta $0428,y + sta poly_maxima_links,y + L552E: ldx $82 - bpl L54C6 + bpl scan_next + L5532: stx $B1 -L5534: lda #$00 - sta $AB +L5534: lda #0 + sta lr_flag + lda $B2 sta $83 - bmi L551F -L553E: tax - lda $A9 - cmp $05E8,x - bne L5584 - lda $AA - cmp low_zp_stash_buffer,x - bne L5584 - ldy $0468,x - lda $0680,y - bpl L556C - cpx $B2 - beq L5564 - ldy $83 - lda $0428,x - sta $0428,y - jmp L55F8 + bmi done -L5564: lda $0428,x - sta $B2 - jmp L55F8 - -L556C: sta $0468,x - lda $0700,y - sta L5E31,x - lda $073C,y - sta L5E41,x - lda $06BC,y - sta $04A8,x - jsr L5606 -L5584: stx $AC - ldy L5E41,x - lda L5E31,x +scan_loop2: tax - lda $AB + lda scan_y + cmp poly_maxima_yl_table,x + bne scan_point + lda scan_y+1 + cmp poly_maxima_yh_table,x + bne scan_point + + ldy poly_maxima_prev_vertex,x + lda poly_vertex_prev_link,y + bpl shift_point + + cpx $B2 + beq :+ + + ldy $83 + lda poly_maxima_links,x + sta poly_maxima_links,y + jmp scan_next_link + +: lda poly_maxima_links,x + sta $B2 + jmp scan_next_link + +shift_point: + sta poly_maxima_prev_vertex,x + lda poly_xl_buffer,y + sta poly_maxima_xl_table,x + lda poly_xh_buffer,y + sta poly_maxima_xh_table,x + lda poly_vertex_next_link,y + sta poly_maxima_next_vertex,x + + jsr calc_slope + +scan_point: + stx current_vertex + ldy poly_maxima_xh_table,x + lda poly_maxima_xl_table,x + tax + + lda lr_flag ; alternate flag left/right eor #$FF - sta $AB - bpl L559B - stx $92 - sty $93 - bmi L55CE -L559B: stx $96 - sty $97 - cpy $93 - bmi L55A9 - bne L55B5 - cpx $92 - bcs L55B5 -L55A9: lda $92 - stx $92 - sta $96 - lda $93 - sty $93 - sta $97 -L55B5: lda $A9 - sta $94 - sta $98 - lda $AA - sta $95 - sta $99 - bit $BA - bpl L55CB + sta lr_flag + bpl :+ + + stx left + sty left+1 + bmi skip_rect + +: stx right + sty right+1 + + cpy left+1 + bmi :+ + bne no_swap_lr + cpx left + bcs no_swap_lr + +: lda left + stx left + sta right + lda left+1 + sty left+1 + sta right+1 + +no_swap_lr: + lda scan_y + sta top + sta bottom + lda scan_y+1 + sta top+1 + sta bottom+1 + + bit poly_oper + bpl do_paint + jsr InRectImpl - jmp L55CE + jmp skip_rect -L55CB: jsr L5043 -L55CE: ldx $AC - lda L5E21,x +do_paint: + jsr PaintRectImpl::do_paint + +skip_rect: + ldx current_vertex + + lda poly_maxima_x_fracl,x clc - adc $0528,x - sta L5E21,x - lda L5E11,x - adc $04E8,x - sta L5E11,x - lda L5E31,x - adc $0568,x - sta L5E31,x - lda L5E41,x - adc $05A8,x - sta L5E41,x - lda $0428,x -L55F8: bmi L55FD - jmp L553E + adc poly_maxima_slope0,x + sta poly_maxima_x_fracl,x + lda poly_maxima_x_frach,x + adc poly_maxima_slope1,x + sta poly_maxima_x_frach,x -L55FD: inc16 $A9 - jmp L54C2 + lda poly_maxima_xl_table,x + adc poly_maxima_slope2,x + sta poly_maxima_xl_table,x + lda poly_maxima_xh_table,x + adc poly_maxima_slope3,x + sta poly_maxima_xh_table,x -L5606: ldy $04A8,x - lda $0780,y - sta $05E8,x + lda poly_maxima_links,x +scan_next_link: + bmi :+ + jmp scan_loop2 + +: inc16 scan_y + jmp scan_loop +.endproc + + +.proc calc_slope + index := $84 + + ldy poly_maxima_next_vertex,x + + lda poly_yl_buffer,y + sta poly_maxima_yl_table,x sec - sbc $A9 - sta $A3 - lda $07BC,y - sta low_zp_stash_buffer,x - sbc $AA - sta $A4 + sbc scan_y + sta