]> git.sur5r.net Git - cc65/blobdiff - libsrc/tgi/tgi_vectorchar.s
clrscr.s switch to text mode
[cc65] / libsrc / tgi / tgi_vectorchar.s
index dafef75b27b6a728f17c9785be864c4edc12b420..bd4cc84c41a43cb7458de048b74b67e1e5ee16ef 100644 (file)
@@ -3,17 +3,17 @@
 ;
 ; void __fastcall__ tgi_vectorchar (const unsigned char* Ops);
 ; /* Draw one character of the vector font at the current graphics cursor
-;  * position using the current font magnification.
-;  */
+; ** position using the current font magnification.
+; */
 ;
 
-        .export         _tgi_vectorchar
-
-        .import         push0ax, tosmuleax
+        .import         imul16x16r32, umul16x16r32, negax, negeax
 
         .include        "tgi-kernel.inc"
+        .include        "tgi-vectorfont.inc"
         .include        "zeropage.inc"
 
+        .macpack        longbranch
 
 ;----------------------------------------------------------------------------
 ; Data
@@ -27,18 +27,120 @@ Y1:     .res    2
 X2:     .res    2
 Y2:     .res    2
 
+;----------------------------------------------------------------------------
+; Get the next operation from the Ops pointer, remove the flag bit and sign
+; extend the 8 bit value to 16 bits.
+
+.code
+.proc   GetOp
+
+; Load delta value
+
+        ldy     #0
+        lda     (Ops),y
+        inc     Ops
+        bne     :+
+        inc     Ops+1
+
+; Move bit 7 into Flag, then sign extend the value in A and extend the sign
+; into X.
+
+:       asl     a                       ; Flag into carry
+        ror     Flag
+        ldx     #0
+        cmp     #$80                    ; Sign bit into carry
+        ror     a                       ; Sign extend the value
+        bpl     :+
+        dex                             ; Value is negative
+
+; Done
+
+:       rts
+
+.endproc
 
 
+;----------------------------------------------------------------------------
+; Get and process one coordinate value. The scale factor is passed in a/x
+
+.code
+GetProcessedYCoord:
+        lda     _tgi_textscaleh+0
+        ldx     _tgi_textscaleh+1
+
+GetProcessedCoord:
+
+; Save scale factor as left operand for multiplication
+
+        sta     ptr1
+        stx     ptr1+1
+
+; Load next operation value.
+
+        jsr     GetOp
+
+; Multiplicate with the scale factor.
+
+        jmp     tgi_imulround           ; Multiplicate, round and scale
+
+;----------------------------------------------------------------------------
+; Add the base coordinate with offset in Y to the value in A/X
+
+.code
+.proc   AddBaseCoord
+
+        clc
+        adc     _tgi_curx+0,y
+        pha
+        txa
+        adc     _tgi_curx+1,y
+        tax
+        pla
+        rts
+
+.endproc
+
+;----------------------------------------------------------------------------
+; Subtract the value in a/x from the base coordinate with offset in Y
+; This is
+;
+;   ax = _tgi_cur[xy] - ax
+;
+; which can be transformed to
+;
+;   ax = _tgi_cur[xy] + (~ax + 1);
+
+
+.code
+.proc   SubBaseCoord
+
+        eor     #$FF
+        sec                             ; + 1
+        adc     _tgi_curx+0,y
+        pha
+        txa
+        eor     #$FF
+        adc     _tgi_curx+1,y
+        tax
+        pla
+        rts
+
+.endproc
+
 ;----------------------------------------------------------------------------
 ;
 
 .code
 .proc   _tgi_vectorchar
 
+; Multiplicate the char value by two and save into Y
+
+        asl     a
+        tay
+
 ; Since we will call tgi_lineto, which uses the zero page, and we do also
 ; need the zero page, make room in the register bank.
 
-        tay
         lda     Ops
         pha
         lda     Ops+1
@@ -46,49 +148,109 @@ Y2:     .res    2
         lda     Flag
         pha
 
-; Save the pointer
+; Calculate a pointer to the vector ops for the given char (now in Y). We
+; definitely expect a font here, that has to be checked by the caller.
+
+        lda     _tgi_vectorfont
+        clc
+        adc     #<(TGI_VECTORFONT::CHARS - 2*TGI_VF_FIRSTCHAR)
+        sta     Ops
+        lda     _tgi_vectorfont+1
+        adc     #>(TGI_VECTORFONT::CHARS - 2*TGI_VF_FIRSTCHAR)
+        sta     Ops+1
 
-        sty     Ops
+        iny
+        lda     (Ops),y
+        tax
+        dey
+        lda     (Ops),y
+        sta     Ops
         stx     Ops+1
 
 ; Main loop executing vector operations
 
 Loop:   lda     _tgi_textscalew+0
         ldx     _tgi_textscalew+1
-        jsr     GetProcessedCoord
+        jsr     GetProcessedCoord       ; Get X vector
+
+; Depending on the text direction, the X vector is either applied to X as
+;
+;   X2 = _tgi_curx + XMag * XDelta
+;
+; or applied to Y as
+;
+;   Y2 = _tgi_cury - XMag * XDelta
+;
+; which can be transformed to
+;
+;   Y2 = _tgi_cury + (~(XMag * XDelta) + 1);
+;
+;
+; For the Y component we have
+;
+;   Y2 = _tgi_cury - YMag * YDelta
+;
+; which can be transformed to
+;
+;   Y2 = _tgi_cury + (~(YMag * YDelta) + 1);
+;
+; or applied to X as
+;
+;   X2 = _tgi_curx - YMag * YDelta
+;
+; which can be transformed to
+;
+;   X2 = _tgi_curx + (~(YMag * YDelta) + 1);
+;
 
-; X2 = tgi_curx + XMag * XDelta.
+        ldy     _tgi_textdir    ; Horizontal or vertical text?
+        bne     @Vertical       ; Jump if vertical
 
-        clc
-        adc     _tgi_curx+0
-        sta     X2+0
-        txa
-        adc     _tgi_curx+1
-        sta     X2+1
+; Process horizontal text
 
-; Process the Y value
+        ldy     #0
+        jsr     AddBaseCoord
+        sta     X2
+        stx     X2+1
 
-        lda     _tgi_textscaleh+0
-        ldx     _tgi_textscaleh+1
-        jsr     GetProcessedCoord
+; Get Y vector
 
-; Y2 = tgi_cury - YMag * YDelta;
-; Y2 = tgi_cury + (~(YMag * YDelta) + 1);
+        jsr     GetProcessedYCoord
 
-        eor     #$FF
-        sec                             ; + 1
-        adc     _tgi_cury+0
-        sta     Y2+0
-        txa
-        eor     #$FF
-        adc     _tgi_cury+1
-        sta     Y2+1
+; Apply to Y
+
+        ldy     #2
+        jsr     SubBaseCoord
+        sta     Y2
+        stx     Y2+1
+        jmp     @DrawMove
+
+; Process vertical text
+
+@Vertical:
+        ldy     #2
+        jsr     SubBaseCoord
+        sta     Y2
+        stx     Y2+1
+
+; Get Y vector
+
+        jsr     GetProcessedYCoord
+
+; Apply to X
+
+        ldy     #0
+        jsr     SubBaseCoord
+        sta     X2
+        stx     X2+1
 
-; Do the actual operation
+; Draw, then move - or just move
 
+@DrawMove:
         bit     Flag
         bpl     @Move                   ; Jump if move only
 
+.if     0
         ldy     #7                      ; Copy start coords into zp
 :       lda     X1,y
         sta     ptr1,y
@@ -96,6 +258,15 @@ Loop:   lda     _tgi_textscalew+0
         bpl     :-
 
         jsr     tgi_line                ; Call the driver
+.else
+        ldy     #7                      ; Copy start coords
+:       lda     X1,y
+        sta     tgi_clip_x1,y
+        dey
+        bpl     :-
+
+        jsr     tgi_clippedline         ; Call line clipper
+.endif
 
 ; Move the start position
 
@@ -112,7 +283,7 @@ Loop:   lda     _tgi_textscalew+0
 
 ; Done. Restore zp and return.
 
-@Done:  pla
+        pla
         sta     Flag
         pla
         sta     Ops+1
@@ -122,53 +293,3 @@ Loop:   lda     _tgi_textscalew+0
 
 .endproc
 
-;----------------------------------------------------------------------------
-; Get and process one coordinate value. The scale factor is passed in a/x
-
-.proc   GetProcessedCoord
-
-; Push the scale factor
-
-        jsr     push0ax
-
-; Load delta value
-
-        ldy     #0
-        lda     (Ops),y
-        inc     Ops
-        bne     :+
-        inc     Ops+1
-
-; Move bit 7 into Flag
-
-:       asl     a                       ; Flag into carry
-        ror     Flag
-
-; Sign extend the value
-
-        ldx     #0
-        cmp     #$80                    ; Sign bit into carry
-        bcc     :+
-        dex
-:       ror     a                       ; Sign extend the value
-
-; Multiplicate with the scale factor.
-
-        stx     sreg
-        stx     sreg+1
-        jsr     tosmuleax               ; Multiplicate
-
-; The result is a 16.8 fixed point value. Round and return it.
-
-        cmp     #$80                    ; Check digits after the dec point
-        txa
-        adc     #$00
-        tay
-        lda     sreg
-        adc     #$00
-        tax
-        tya
-        rts
-
-.endproc
-