1;---------------------------------------------------------------------- 2; Commander X16 KERNAL: Graphics library 3;---------------------------------------------------------------------- 4; (C)2019 Michael Steil, License: 2-clause BSD 5; (Bresenham code based on GEOS by Berkeley Softworks) 6 7.include "mac.inc" 8.include "regs.inc" 9.include "fb.inc" 10 11.import leftMargin, windowTop, rightMargin, windowBottom 12.import FB_VERA 13 14.import font_init 15 16.export GRAPH_init 17.export GRAPH_clear 18.export GRAPH_set_window 19.export GRAPH_set_colors 20.export GRAPH_draw_line 21.export GRAPH_draw_rect 22.export GRAPH_draw_image 23.export GRAPH_move_rect 24.export GRAPH_draw_oval 25 26.segment "GDRVVEC" 27 28.export I_FB_init, I_FB_get_info, I_FB_set_palette, I_FB_cursor_position, I_FB_cursor_next_line, I_FB_get_pixel, I_FB_get_pixels, I_FB_set_pixel, I_FB_set_pixels, I_FB_set_8_pixels, I_FB_set_8_pixels_opaque, I_FB_fill_pixels, I_FB_filter_pixels, I_FB_move_pixels; [vectors] 29 30I_FB_BASE: 31I_FB_init: 32 .res 2 33I_FB_get_info: 34 .res 2 35I_FB_set_palette: 36 .res 2 37I_FB_cursor_position: 38 .res 2 39I_FB_cursor_next_line: 40 .res 2 41I_FB_get_pixel: 42 .res 2 43I_FB_get_pixels: 44 .res 2 45I_FB_set_pixel: 46 .res 2 47I_FB_set_pixels: 48 .res 2 49I_FB_set_8_pixels: 50 .res 2 51I_FB_set_8_pixels_opaque: 52 .res 2 53I_FB_fill_pixels: 54 .res 2 55I_FB_filter_pixels: 56 .res 2 57I_FB_move_pixels: 58 .res 2 59I_FB_END: 60 61 62.segment "KVAR" 63 64.export col1, col2, col_bg 65col1: .res 1 66col2: .res 1 67col_bg: .res 1 68 69.segment "GRAPH" 70 71;--------------------------------------------------------------- 72; GRAPH_init 73; 74; Function: Enable a given low-level graphics mode driver, 75; and switch to this mode. 76; 77; Pass: r0 pointer to FB_* driver vectors 78; If 0, this enables the default driver 79; (320x200@256c). 80;--------------------------------------------------------------- 81GRAPH_init: 82 lda r0L 83 ora r0H 84 bne :+ 85 LoadW r0, FB_VERA 86: 87 ; copy VERA driver vectors 88 ldy #<(I_FB_END - I_FB_BASE - 1) 89: lda (r0),y 90 sta I_FB_BASE,y 91 dey 92 bpl :- 93 94 jsr FB_init 95 96 jsr set_window_fullscreen 97 98 lda #0 ; primary: black 99 ldx #10 ; secondary: gray 100 ldy #1 ; background: white 101 jsr GRAPH_set_colors 102 103 jsr GRAPH_clear 104 105 jmp font_init 106 107;--------------------------------------------------------------- 108; GRAPH_clear 109; 110;--------------------------------------------------------------- 111GRAPH_clear: 112 PushB col1 113 PushB col2 114 lda col_bg 115 sta col1 116 sta col2 117 MoveW leftMargin, r0 118 MoveB windowTop, r1L 119 stz r1H 120 MoveW rightMargin, r2 121 SubW r0, r2 122 IncW r2 123 MoveB windowBottom, r3L 124 stz r3H 125 SubW r1, r3 126 IncW r3 127 sec 128 jsr GRAPH_draw_rect 129 PopB col2 130 PopB col1 131 rts 132 133set_window_fullscreen: 134 jsr FB_get_info 135 MoveW r0, r2 136 MoveW r1, r3 137 lda #0 138 sta r0L 139 sta r0H 140 sta r1L 141 sta r1H 142; fallthrough 143 144;--------------------------------------------------------------- 145; GRAPH_set_window 146; 147; Pass: r0 x 148; r1 y 149; r2 width 150; r3 height 151; 152; Note: 0/0/0/0 will set the window to full screen. 153;--------------------------------------------------------------- 154GRAPH_set_window: 155 lda r0L 156 ora r0H 157 ora r1L 158 ora r1H 159 ora r2L 160 ora r2H 161 ora r3L 162 ora r3H 163 beq set_window_fullscreen 164 165 MoveW r0, leftMargin 166 MoveW r1, windowTop 167 168 lda r0L 169 clc 170 adc r2L 171 sta rightMargin 172 lda r0H 173 adc r2H 174 sta rightMargin+1 175 lda rightMargin 176 bne :+ 177 dec rightMargin+1 178: dec rightMargin 179 180 lda r1L 181 clc 182 adc r3L 183 sta windowBottom 184 lda r1H 185 adc r3H 186 sta windowBottom+1 187 lda windowBottom 188 bne :+ 189 dec windowBottom+1 190: dec windowBottom 191 rts 192 193;--------------------------------------------------------------- 194; GRAPH_set_colors 195; 196; Pass: a primary color 197; x secondary color 198; y background color 199;--------------------------------------------------------------- 200GRAPH_set_colors: 201 sta col1 ; primary color 202 stx col2 ; secondary color 203 sty col_bg ; background color 204 rts 205 206;--------------------------------------------------------------- 207; GRAPH_draw_line 208; 209; Pass: r0 x1 210; r1 y2 211; r2 x1 212; r3 y2 213;--------------------------------------------------------------- 214GRAPH_draw_line: 215 CmpW r1, r3 ; horizontal? 216 bne @0a ; no 217 jmp HorizontalLine 218 219@0a: CmpW r0, r2 ; vertical? 220 bne @0 ; no 221 jmp VerticalLine 222 223; Bresenham 224@0: php 225 LoadB r7H, 0 226 lda r3L 227 sub r1L 228 sta r7L 229 bcs @1 230 lda #0 231 sub r7L 232 sta r7L 233@1: lda r2L 234 sub r0L 235 sta r12L 236 lda r2H 237 sbc r0H 238 sta r12H 239 ldx #r12 240 jsr abs 241 CmpW r12, r7 242 bcs @2 243 jmp @9 244@2: 245 lda r7L 246 asl 247 sta r9L 248 lda r7H 249 rol 250 sta r9H 251 lda r9L 252 sub r12L 253 sta r8L 254 lda r9H 255 sbc r12H 256 sta r8H 257 lda r7L 258 sub r12L 259 sta r10L 260 lda r7H 261 sbc r12H 262 sta r10H 263 asl r10L 264 rol r10H 265 LoadB r13L, $ff 266 CmpW r0, r2 267 bcc @4 268 CmpB r1L, r3L 269 bcc @3 270 LoadB r13L, 1 271@3: ldy r0H 272 ldx r0L 273 MoveW r2, r0 274 sty r2H 275 stx r2L 276 MoveB r3L, r1L 277 bra @5 278@4: ldy r3L 279 cpy r1L 280 bcc @5 281 LoadB r13L, 1 282@5: lda col1 283 plp 284 php 285 jsr FB_cursor_position 286 lda col1 287 jsr FB_set_pixel 288 CmpW r0, r2 289 bcs @8 290 inc r0L 291 bne @6 292 inc r0H 293@6: bbrf 7, r8H, @7 294 AddW r9, r8 295 bra @5 296@7: AddB r13L, r1L 297 AddW r10, r8 298 bra @5 299@8: plp 300 rts 301@9: lda r12L 302 asl 303 sta r9L 304 lda r12H 305 rol 306 sta r9H 307 lda r9L 308 sub r7L 309 sta r8L 310 lda r9H 311 sbc r7H 312 sta r8H 313 lda r12L 314 sub r7L 315 sta r10L 316 lda r12H 317 sbc r7H 318 sta r10H 319 asl r10L 320 rol r10H 321 LoadW r13, $ffff 322 CmpB r1L, r3L 323 bcc @B 324 CmpW r0, r2 325 bcc @A 326 LoadW r13, 1 327@A: MoveW r2, r0 328 ldx r1L 329 lda r3L 330 sta r1L 331 stx r3L 332 bra @C 333@B: CmpW r0, r2 334 bcs @C 335 LoadW r13, 1 336@C: lda col1 337 plp 338 php 339 jsr FB_cursor_position 340 lda col1 341 jsr FB_set_pixel 342 CmpB r1L, r3L 343 bcs @E 344 inc r1L 345 bbrf 7, r8H, @D 346 AddW r9, r8 347 bra @C 348@D: AddW r13, r0 349 AddW r10, r8 350 bra @C 351@E: plp 352 rts 353 354; calc abs of word in zp at location .x 355abs: 356 lda 1,x 357 bmi @0 358 rts 359@0: lda 1,x 360 eor #$FF 361 sta 1,x 362 lda 0,x 363 eor #$FF 364 sta 0,x 365 inc 0,x 366 bne @1 367 inc 1,x 368@1: rts 369 370;--------------------------------------------------------------- 371; HorizontalLine (internal) 372; 373; Pass: r0 x position of first pixel 374; r1 y position 375; r2 x position of last pixel 376;--------------------------------------------------------------- 377HorizontalLine: 378 ; make sure x2 > x1 379 lda r2L 380 sec 381 sbc r0L 382 lda r2H 383 sbc r0H 384 bcs @2 385 lda r0L 386 ldx r2L 387 stx r0L 388 sta r2L 389 lda r0H 390 ldx r2H 391 stx r0H 392 sta r2H 393 394@2: jsr FB_cursor_position 395 396 MoveW r2, r15 397 SubW r0, r15 398 IncW r15 399 400 PushW r0 401 PushW r1 402 MoveW r15, r0 403 LoadW r1, 0 404 lda col1 405 jsr FB_fill_pixels 406 PopW r1 407 PopW r0 408 rts 409 410;--------------------------------------------------------------- 411; VerticalLine (internal) 412; 413; Pass: r0 x 414; r1 y1 415; r2 (unused) 416; r3 y2 417; a color 418;--------------------------------------------------------------- 419VerticalLine: 420 ; make sure y2 >= y1 421 lda r3L 422 cmp r1L 423 bcs @0 424 ldx r1L 425 stx r3L 426 sta r1L 427 428@0: lda r3L 429 sec 430 sbc r1L 431 tax 432 inx 433 beq @2 ; .x = number of pixels to draw 434 435 jsr FB_cursor_position 436 437 PushW r0 438 PushW r1 439 LoadW r1, 320 440 stx r0L 441 stz r0H 442 lda col1 443 jsr FB_fill_pixels 444 PopW r1 445 PopW r0 446@2: rts 447 448;--------------------------------------------------------------- 449; GRAPH_draw_rect 450; 451; Pass: r0 x 452; r1 y 453; r2 width 454; r3 height 455; r4 corner radius [TODO] 456; c 1: fill 457;--------------------------------------------------------------- 458GRAPH_draw_rect: 459; check for empty 460 php 461 lda r2L 462 ora r2H 463 bne @0 464@4: plp 465 rts 466@0: lda r3L 467 ora r3H 468 beq @4 469 plp 470 471 bcc @3 472 473; fill 474 PushW r1 475 PushW r3 476 jsr FB_cursor_position 477 478@1: PushW r0 479 PushW r1 480 MoveW r2, r0 481 LoadW r1, 0 482 lda col2 483 jsr FB_fill_pixels 484 PopW r1 485 PopW r0 486 487 jsr FB_cursor_next_line 488 489 lda r3L 490 bne @2 491 dec r3H 492@2: dec r3L 493 lda r3L 494 ora r3H 495 bne @1 496 497 PopW r3 498 PopW r1 499 500; frame 501@3: 502 PushW r2 503 PushW r3 504 AddW r0, r2 505 lda r2L 506 bne :+ 507 dec r2H 508: dec r2L 509 AddW r1, r3 510 lda r3L 511 bne :+ 512 dec r3H 513: dec r3L 514 515 jsr HorizontalLine 516 PushB r1L 517 MoveB r3L, r1L 518 jsr HorizontalLine 519 PopB r1L 520 PushW r0 521 jsr VerticalLine 522 MoveW r2, r0 523 jsr VerticalLine 524 PopW r0 525 526 PopW r3 527 PopW r2 528 rts 529 530;--------------------------------------------------------------- 531; GRAPH_draw_image 532; 533; Pass: r0 x 534; r1 y 535; r2 image pointer 536; r3 width 537; r4 height 538;--------------------------------------------------------------- 539GRAPH_draw_image: 540 PushW r0 541 PushW r1 542 PushW r4 543 jsr FB_cursor_position 544 545 MoveW r2, r0 546 MoveW r3, r1 547@1: jsr FB_set_pixels 548 549 lda r4L 550 bne :+ 551 dec r4H 552: dec r4L 553 554 AddW r3, r0 ; update pointer 555 jsr FB_cursor_next_line 556 557 lda r4L 558 ora r4H 559 bne @1 560 561 PopW r4 562 PopW r1 563 PopW r0 564 rts 565 566;--------------------------------------------------------------- 567; GRAPH_move_rect 568; 569; Pass: r0 source x 570; r1 source y 571; r2 target x 572; r3 target y 573; r4 width 574; r5 height 575;--------------------------------------------------------------- 576GRAPH_move_rect: 577 CmpW r3, r1 578 bcc @2 579 580 AddW r5, r1 581 AddW r5, r3 582 IncW r5 583@1: jsr FB_move_pixels 584 DecW_ r1 585 DecW_ r3 586 DecW_ r5 587 lda r5L 588 ora r5H 589 bne @1 590 rts 591 592@2: jsr FB_move_pixels 593 IncW r1 ; sy 594 IncW r3 ; ty 595 DecW_ r5 596 lda r5L 597 ora r5H 598 bne @2 599 rts 600 601;--------------------------------------------------------------- 602; GRAPH_draw_oval 603; 604;--------------------------------------------------------------- 605GRAPH_draw_oval: 606 brk; NYI 607