1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295
|
;
; 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
; 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.
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
|