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