; ; Ullrich von Bassewitz, 2009-11-02 ; ; 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. ; */ ; .import imul16x16r32, umul16x16r32, negax, negeax .include "tgi-kernel.inc" .include "tgi-vectorfont.inc" .include "zeropage.inc" .macpack longbranch ;---------------------------------------------------------------------------- ; Data Ops = regbank Flag = regbank+2 .bss X1: .res 2 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 ; Multiply with the scale factor. jmp tgi_imulround ; Multiply, 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 ; Multiply 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. lda Ops pha lda Ops+1 pha lda Flag pha ; 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 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 ; 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); ; ldy _tgi_textdir ; Horizontal or vertical text? bne @Vertical ; Jump if vertical ; Process horizontal text ldy #0 jsr AddBaseCoord sta X2 stx X2+1 ; Get Y vector jsr GetProcessedYCoord ; 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 ; 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 dey 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 @Move: ldy #3 : lda X2,y sta X1,y dey bpl :- ; Loop if not done bit Flag bvc Loop ; Done. Restore zp and return. pla sta Flag pla sta Ops+1 pla sta Ops rts .endproc