/[projet1]/users/chema/TINE/oobj3d/LineDraw.s
Defence Force logotype

Contents of /users/chema/TINE/oobj3d/LineDraw.s

Parent Directory Parent Directory | Revision Log Revision Log


Revision 223 - (show annotations)
Mon Feb 1 22:31:07 2010 UTC (10 years, 3 months ago) by Chema
File size: 22798 byte(s)
Some more minor changes. Totally removed the TRANSPORTER ship, as it was too complex. Added new version of LineDraw.s, with still minor glitches.

Scratched some cycles from the circle routine.
1 #include "params.h"
2
3 #ifndef FILLEDPOLYS
4
5
6 .zero
7
8 #ifdef OLDLINES
9 e .dsb 2 ; Error decision factor (slope) 2 bytes in zero page
10 #endif
11 i .dsb 1 ; Number of pixels to draw (iteration counter) 1 byte in zp
12 dx .dsb 1 ; Width
13 dy .dsb 1 ; Height
14 _CurrentPixelX .dsb 1
15 _CurrentPixelY .dsb 1
16 _OtherPixelX .dsb 1
17 _OtherPixelY .dsb 1
18
19
20 #define _LargeX0 X1
21 #define _LargeY0 Y1
22 #define _LargeX1 X2
23 #define _LargeY1 Y2
24
25 _LargeX .dsb 2
26 _LargeY .dsb 2
27 _ClipCode .dsb 1
28 _ClipCode0 .dsb 1
29 _ClipCode1 .dsb 1
30
31 #ifdef USE_ACCURATE_CLIPPING
32 .dsb 1
33 #endif
34 _ClipX0 .dsb 2
35 #ifdef USE_ACCURATE_CLIPPING
36 .dsb 1
37 #endif
38 _ClipY0 .dsb 2
39 #ifdef USE_ACCURATE_CLIPPING
40 .dsb 1
41 #endif
42 _ClipX1 .dsb 2
43 #ifdef USE_ACCURATE_CLIPPING
44 .dsb 1
45 #endif
46 _ClipY1 .dsb 2
47 #ifdef USE_ACCURATE_CLIPPING
48 .dsb 1
49 #endif
50 _ClipXc .dsb 2
51 #ifdef USE_ACCURATE_CLIPPING
52 .dsb 1
53 #endif
54 _ClipYc .dsb 2
55
56 .text
57
58 ;; To include double-buffer (on and off)
59 double_buff .byt $ff
60
61
62 .dsb 256-(*&255)
63
64 _HiresAddrLow .dsb 201
65
66 .dsb 256-(*&255)
67
68 _HiresAddrHigh .dsb 201
69
70 .dsb 256-(*&255)
71
72 _TableDiv6 .dsb 256
73
74 _TableBit6Reverse
75 .byt 32,16,8,4,2,1
76 .byt 32,16,8,4,2,1
77 .byt 32,16,8,4,2,1
78 .byt 32,16,8,4,2,1
79 .byt 32,16,8,4,2,1
80 .byt 32,16,8,4,2,1
81 .byt 32,16,8,4,2,1
82 .byt 32,16,8,4,2,1
83 .byt 32,16,8,4,2,1
84 .byt 32,16,8,4,2,1
85
86 .byt 32,16,8,4,2,1
87 .byt 32,16,8,4,2,1
88 .byt 32,16,8,4,2,1
89 .byt 32,16,8,4,2,1
90 .byt 32,16,8,4,2,1
91 .byt 32,16,8,4,2,1
92 .byt 32,16,8,4,2,1
93 .byt 32,16,8,4,2,1
94 .byt 32,16,8,4,2,1
95 .byt 32,16,8,4,2,1
96
97 .byt 32,16,8,4,2,1
98 .byt 32,16,8,4,2,1
99 .byt 32,16,8,4,2,1
100 .byt 32,16,8,4,2,1
101 .byt 32,16,8,4,2,1
102 .byt 32,16,8,4,2,1
103 .byt 32,16,8,4,2,1
104 .byt 32,16,8,4,2,1
105 .byt 32,16,8,4,2,1
106 .byt 32,16,8,4,2,1
107
108 .byt 32,16,8,4,2,1
109 .byt 32,16,8,4,2,1
110 .byt 32,16,8,4,2,1
111 .byt 32,16,8,4,2,1
112 .byt 32,16,8,4,2,1
113 .byt 32,16,8,4,2,1
114 .byt 32,16,8,4,2,1
115 .byt 32,16,8,4,2,1
116 .byt 32,16,8,4,2,1
117 .byt 32,16,8,4,2,1
118
119 #ifdef OLDLINES
120
121 .dsb 256-(*&255)
122
123
124 ;
125 ; This code is used when the things are moving faster
126 ; horizontally than vertically
127 ;
128 ; dx<dy
129 ;
130 draw_nearly_horizontal
131 .(
132 ; here we have DY in Y, and the OPCODE in A
133 sta _outer_patch ; Write a (dex / nop / inx) instruction
134
135 ;
136 ; Initialize counter to dx+1
137 ;
138 ldx dx
139 inx
140 stx i
141
142 ; Initialise e=dy*2-dx
143 lda dy
144 asl
145 sta _path_e_dy_0+1 ; dy
146 sta e
147 lda #0
148 rol
149 sta _path_e_dy_1+1 ; dy+1
150 sta 1+e
151
152 sec
153 lda e
154 sbc dx
155 sta e
156 lda 1+e
157 sbc #0
158 sta 1+e
159
160 ; Compute dx*2
161 lda dx
162 asl
163 sta _path_e_dx_0+1 ;dx
164 lda #0
165 rol
166 sta _path_e_dx_1+1 ;dx+1
167
168 ;
169 ; Draw loop
170 ;
171 ldx _CurrentPixelX
172 ldy _TableDiv6,x
173 sec
174 outer_loop
175 lda _TableBit6Reverse,x ; 4
176 ;eor (tmp0),y ; 5
177 ora (tmp0),y ; 5
178 sta (tmp0),y ; 6
179
180 lda 1+e
181 bmi end_inner_loop
182
183 ; e=e-2*dx
184 ;sec
185 lda e
186 _path_e_dx_0
187 sbc #0
188 sta e
189 lda 1+e
190 _path_e_dx_1
191 sbc #0
192 sta 1+e
193
194 ; Update screen adress
195 ;clc ; 2
196 lda tmp0+0 ; 3
197 adc #40 ; 2
198 sta tmp0+0 ; 3
199 bcc skip ; 2 (+1 if taken)
200 inc tmp0+1 ; 5
201 skip
202 ; ------------------Min=13 Max=17
203
204
205 end_inner_loop
206
207 _outer_patch
208 inx
209 ldy _TableDiv6,x
210
211 ; e=e+2*dy
212 clc
213 lda e
214 _path_e_dy_0
215 adc #0
216 sta e
217 lda 1+e
218 _path_e_dy_1
219 adc #0
220 sta 1+e
221
222 dec i
223 bne outer_loop
224 rts
225 .)
226
227
228
229
230 _DrawLine
231 ;jmp _DrawLine
232 ;
233 ; Compute deltas and signs
234 ;
235
236 ; Test Y value
237 .(
238 sec
239 lda _CurrentPixelY
240 sbc _OtherPixelY
241 sta dy
242 beq end
243 bcc cur_smaller
244
245 cur_bigger ; y1>y2
246 ; Swap X and Y
247 ; So we always draw from top to bottom
248 lda _CurrentPixelY
249 ldx _OtherPixelY
250 sta _OtherPixelY
251 stx _CurrentPixelY
252
253 lda _CurrentPixelX
254 ldx _OtherPixelX
255 sta _OtherPixelX
256 stx _CurrentPixelX
257
258 jmp end
259
260 cur_smaller ; y1<y2
261 ; Absolute value
262 eor #$ff
263 adc #1
264 sta dy
265 end
266 .)
267
268 ;
269 ; Initialise screen pointer
270 ;
271 ldy _CurrentPixelY
272 lda _HiresAddrLow,y ; 4
273 sta tmp0+0 ; 3
274 lda _HiresAddrHigh,y ; 4
275 sta tmp0+1 ; 3 => Total 14 cycles
276
277 ; Test X value
278 .(
279 sec
280 lda _CurrentPixelX
281 sbc _OtherPixelX
282 sta dx
283 beq draw_totaly_vertical
284 bcc cur_smaller
285
286 cur_bigger ; x1>x2
287 lda #$ca ; 0 DEC
288 bne end
289
290 cur_smaller ; x1<x2
291 ; Absolute value
292 eor #$ff
293 adc #1
294 sta dx
295
296 lda #$e8 ; 2 INC
297 end
298 .)
299
300 ; Compute slope and call the specialized code for mostly horizontal or vertical lines
301 ldy dy
302 beq draw_totaly_horizontal
303 cpy dx
304 bcs draw_nearly_vertical
305 jmp draw_nearly_horizontal
306
307 draw_totaly_horizontal
308 .(
309 ; here we have DY in Y, and the OPCODE in A
310 sta _outer_patch ; Write a (dex / nop / inx) instruction
311
312 ;
313 ; Initialize counter to dx+1
314 ;
315 ldx dx
316 inx
317 stx i
318
319
320 ldx _CurrentPixelX
321
322 ;
323 ; Draw loop
324 ;
325 outer_loop
326 ldy _TableDiv6,x
327 lda _TableBit6Reverse,x ; 4
328 ;eor (tmp0),y ; 5
329 ora (tmp0),y ; 5
330 sta (tmp0),y ; 6
331
332 _outer_patch
333 inx
334
335 dec i
336 bne outer_loop
337 rts
338 .)
339
340 draw_totaly_vertical
341 .(
342 ldx _CurrentPixelX
343 ldy _TableDiv6,x
344 lda _TableBit6Reverse,x ; 4
345 sta _mask_patch+1
346
347 ldx dy
348 inx
349
350 clc ; 2
351 loop
352 _mask_patch
353 lda #0 ; 2
354 ;eor (tmp0),y ; 5
355 ora (tmp0),y
356 sta (tmp0),y ; 6 => total = 13 cycles
357
358 ; Update screen adress
359 lda tmp0+0 ; 3
360 adc #40 ; 2
361 sta tmp0+0 ; 3
362 bcc skip ; 2 (+1 if taken)
363 inc tmp0+1 ; 5
364 clc ; 2
365 skip
366 ; ------------------Min=13 Max=17
367
368 dex
369 bne loop
370 rts
371 .)
372
373 .dsb 256-(*&255)
374
375 ;
376 ; This code is used when the things are moving faster
377 ; vertically than horizontally
378 ;
379 ; dy>dx
380 ;
381 draw_nearly_vertical
382 ;jmp draw_nearly_vertical
383 .(
384 ; here we have DY in Y, and the OPCODE in A
385 sta _inner_patch ; Write a (dex / nop / inx) instruction
386 ; just increment en store to know the number of iterations
387 iny
388 sty i
389
390
391 ; Compute dx*2
392 lda dy
393 asl
394 sta _path_e_dx_0+1 ;dx
395 lda #0
396 rol
397 sta _path_e_dx_1+1 ;dx+1
398
399
400 ; Normaly we should have swapped DX and DY, but instead just swap in the usage is more efficient
401 ; Initialise e
402 lda dx
403 asl
404 sta _path_e_dy_0+1 ; dy
405 sta e
406 lda #0
407 rol
408 sta _path_e_dy_1+1 ; dy+1
409 sta 1+e
410
411 ldx _CurrentPixelX
412 ldy _TableDiv6,x
413
414 sec
415 lda e
416 sbc dy
417 sta e
418 lda 1+e
419 sbc #0
420 sta 1+e
421 bmi end_inner_loop2 ; n=1 ?
422
423 ;
424 ; Draw loop
425 ;
426 outer_loop
427 lda _TableBit6Reverse,x ; 4
428 ;eor (tmp0),y ; 5
429 ora (tmp0),y ; 5
430 sta (tmp0),y ; 6
431 ; --------------------------=15
432
433 _inner_patch
434 inx
435
436 ldy _TableDiv6,x
437
438 ; e=e-2*dx
439 sec
440 lda e
441 _path_e_dx_0
442 sbc #0
443 sta e
444 lda 1+e
445 _path_e_dx_1
446 sbc #0
447 sta 1+e
448
449 end_inner_loop
450
451 ;;;;;;;;; SOLVING EXTRA PIXEL BUG
452 dec i
453 beq done
454
455 .(
456 ; Update screen adress
457 ;clc ; 2
458 lda tmp0+0 ; 3
459 adc #40 ; 2
460 sta tmp0+0 ; 3
461 bcc skip ; 2 (+1 if taken)
462 inc tmp0+1 ; 5
463 clc
464 skip
465 ; ------------------Min=13 Max=17
466 .)
467
468 ; e=e+2*dy
469 lda e
470 _path_e_dy_0
471 adc #0
472 sta e
473 lda 1+e
474 _path_e_dy_1
475 adc #0
476 sta 1+e
477
478 ;;;;;;;;; SOLVING EXTRA PIXEL BUG
479
480 ; bmi end_inner_loop2 ; n=1 ?
481
482 bpl outer_loop
483
484 ; dec i
485 ; bne outer_loop
486 ; rts
487
488 end_inner_loop2
489 lda _TableBit6Reverse,x ; 4
490 ;eor (tmp0),y ; 5
491 ora (tmp0),y ; 5
492 sta (tmp0),y ; 6
493 ; --------------------------=15
494
495 ; dec i ; 5
496 bne end_inner_loop
497
498 done
499 rts
500 .)
501
502 #else
503
504 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
505
506 .zero
507 save_a .dsb 1
508 save_y .dsb 1
509
510 .text
511
512 .dsb 256-(*&255)
513
514 ; nop $ea
515 ; inx $e8 11101000
516 ; dex $ca 11001010
517 ; iny $c8 11001000
518 ; dey $88 10001000
519
520
521
522 draw_totaly_vertical_8
523 .(
524 ldx _CurrentPixelX
525 ldy _TableDiv6,x
526 lda _TableBit6Reverse,x ; 4
527 sta _mask_patch+1
528
529 ldx dy
530 inx
531
532 clc ; 2
533 loop
534 _mask_patch
535 lda #0 ; 2
536 ora (tmp0),y ; 5
537 sta (tmp0),y ; 6 => total = 13 cycles
538
539 ; Update screen adress
540 lda tmp0+0 ; 3
541 adc #40 ; 2
542 sta tmp0+0 ; 3
543 bcc skip ; 2 (+1 if taken)
544 inc tmp0+1 ; 5
545 clc ; 2
546 skip
547 ; ------------------Min=13 Max=17
548
549 dex
550 bne loop
551 rts
552 .)
553
554
555
556 ;
557 ; Expects the following variables to be set when called:
558 ; _CurrentPixelX
559 ; _CurrentPixelY
560 ; _OtherPixelX
561 ; _OtherPixelY
562 ;
563 _DrawLine
564 ;
565 ; Compute deltas and signs
566 ;
567
568 ; Test Y value
569 .(
570 sec
571 lda _CurrentPixelY
572 sbc _OtherPixelY
573 beq end
574 bcc cur_smaller
575
576 cur_bigger ; y1>y2
577 ; Swap X and Y
578 ; So we always draw from top to bottom
579 ldy _CurrentPixelY
580 ldx _OtherPixelY
581 sty _OtherPixelY
582 stx _CurrentPixelY
583
584 ldy _CurrentPixelX
585 ldx _OtherPixelX
586 sty _OtherPixelX
587 stx _CurrentPixelX
588
589 jmp end
590
591 cur_smaller ; y1<y2
592 ; Absolute value
593 eor #$ff
594 adc #1
595 end
596 sta dy
597 .)
598
599 ;
600 ; Initialise screen pointer
601 ;
602 ldy _CurrentPixelY
603 lda _HiresAddrLow,y ; 4
604 sta tmp0+0 ; 3
605 lda _HiresAddrHigh,y ; 4
606 sta tmp0+1 ; 3 => Total 14 cycles
607
608 ; Test X value
609 .(
610 sec
611 lda _CurrentPixelX
612 sbc _OtherPixelX
613 sta dx
614 beq draw_totaly_vertical_8
615 bcc cur_smaller
616
617 cur_bigger ; x1>x2
618 lda #$ca ; dex
619 bne end
620
621 cur_smaller ; x1<x2
622 ; Absolute value
623 eor #$ff
624 adc #1
625 sta dx
626
627 lda #$e8 ; inx
628 end
629 .)
630
631 ; Compute slope and call the specialized code for mostly horizontal or vertical lines
632 ldy dy
633 beq draw_totaly_horizontal_8
634 cpy dx
635 bcs draw_nearly_vertical_8
636
637 draw_nearly_horizontal_8
638 .(
639 ; here we have DY in Y, and the OPCODE in A
640 sta __auto_stepx ; Write a (dex / nop / inx) instruction
641 sty __auto_ady+1
642
643 lda dx
644 sta __auto_dx+1
645
646 lda _OtherPixelX
647 sta __auto_cpx+1
648
649 ldx _CurrentPixelX ;Plotting coordinates
650 ldy _CurrentPixelY ;in X and Y
651 sty save_y
652
653 lda #00 ;Saves us a CMP
654 sec
655 sbc dy ; -DY
656 sta save_a ; 3
657
658 jmp draw_pixel
659
660 loop
661 __auto_stepx
662 inx ; Step in x
663 lda save_a ; 3
664 __auto_ady
665 adc #00 ; 2 +DY
666 sta save_a ; 3
667 bcc draw_pixel ; Time to step in y?
668
669 __auto_dx
670 sbc #00 ; 2 -DX
671 sta save_a ; 3
672
673 inc save_y ; 5 Steps in y
674 ldy save_y ; 3
675
676 ; Set the new screen adress
677 lda _HiresAddrLow,y ; 4
678 sta tmp0+0 ; 3
679 lda _HiresAddrHigh,y ; 4
680 sta tmp0+1 ; 3
681
682 draw_pixel
683 ; Draw the pixel
684 ldy _TableDiv6,x
685 lda _TableBit6Reverse,x
686 ora (tmp0),y
687 sta (tmp0),y
688
689 __auto_cpx
690 cpx #00 ; At the endpoint yet?
691 bne loop
692 rts
693 .)
694
695 draw_totaly_horizontal_8
696 .(
697 ; here we have DY in Y, and the OPCODE in A
698 sta _outer_patch ; Write a (dex / nop / inx) instruction
699
700 ldx _OtherPixelX
701 stx __auto_cpx+1
702
703 ldx _CurrentPixelX
704
705 ;
706 ; Draw loop
707 ;
708 outer_loop
709 ldy _TableDiv6,x
710 lda _TableBit6Reverse,x ; 4
711 ora (tmp0),y ; 5
712 sta (tmp0),y ; 6
713
714 _outer_patch
715 inx
716
717 __auto_cpx
718 cpx #00 ; At the endpoint yet?
719 bne outer_loop
720 rts
721 .)
722
723
724 ;
725 ; This code is used when the things are moving faster
726 ; vertically than horizontally
727 ;
728 ; dy>dx
729 ;
730 draw_nearly_vertical_8
731 .(
732 ; here we have DY in Y, and the OPCODE in A
733 sta __auto_stepx ; Write a (dex / nop / inx) instruction
734 sty __auto_dy+1
735
736 lda dx
737 sta __auto_adx+1
738
739 lda _OtherPixelY
740 sta __auto_cpy+1
741
742 ldx _CurrentPixelX ;Plotting coordinates
743 ldy _CurrentPixelY ;in X and Y
744
745 lda #00 ;Saves us a CMP
746 sec
747 sbc dx ; -DX
748
749 jmp draw_pixel
750
751 loop
752 iny ; Step in y
753 __auto_adx
754 adc #00 ; +DX
755 bcc skip ; Time to step in x?
756
757 __auto_stepx
758 inx ; Step in x
759
760 __auto_dy
761 sbc #00 ; -DY
762
763 skip
764 ; Set the new screen adress
765 sta save_a
766 lda _HiresAddrLow,y
767 sta tmp0+0
768 lda _HiresAddrHigh,y
769 sta tmp0+1
770
771 draw_pixel
772 ; Draw the pixel
773 sty save_y
774 ldy _TableDiv6,x
775 lda _TableBit6Reverse,x
776 ora (tmp0),y
777 sta (tmp0),y
778 lda save_a
779 ldy save_y
780
781 __auto_cpy
782 cpy #00 ; At the endpoint yet?
783 bne loop
784 rts
785 .)
786
787
788
789 #endif
790
791
792
793 _GenerateTables
794 .(
795
796 ; Generate screen offset data
797 .(
798 lda double_buff
799 beq toscreen
800
801 lda #<buffer
802 sta tmp0+0
803 lda #>buffer
804 sta tmp0+1
805 jmp nextstep
806 toscreen
807 lda #<$a000
808 sta tmp0+0
809 lda #>$a000
810 sta tmp0+1
811 nextstep
812
813 ldx #0
814 loop
815 ; generate two bytes screen adress
816 clc
817 lda tmp0+0
818 sta _HiresAddrLow,x
819 adc #40
820 sta tmp0+0
821 lda tmp0+1
822 sta _HiresAddrHigh,x
823 adc #0
824 sta tmp0+1
825
826 inx
827 cpx #201
828 bne loop
829 .)
830
831
832 ; Generate multiple of 6 data table
833 .(
834 lda #0
835 sta tmp0+1 ; cur div
836 sta tmp0+2 ; cur mod
837
838 ldx #0
839 loop
840 lda tmp0+1
841 sta _TableDiv6,x
842
843 ldy tmp0+2
844 iny
845 cpy #6
846 bne skip_mod
847 ldy #0
848 inc tmp0+1
849 skip_mod
850 sty tmp0+2
851
852 inx
853 bne loop
854 .)
855
856 .)
857 rts
858
859
860
861
862
863 _ClipComputeMidPoint
864 .(
865 ; xc=(x0+x1)>>1;
866 clc
867 #ifdef USE_ACCURATE_CLIPPING
868 lda _ClipX0-1
869 adc _ClipX1-1
870 sta _ClipXc-1
871 #endif
872 lda _ClipX0+0
873 adc _ClipX1+0
874 sta _ClipXc+0
875
876 lda _ClipX0+1
877 adc _ClipX1+1
878 sta _ClipXc+1
879
880 lda _ClipXc+1
881 cmp #$80
882 ror _ClipXc+1
883 ror _ClipXc+0
884 #ifdef USE_ACCURATE_CLIPPING
885 ror _ClipXc-1
886 #endif
887
888 ; yc=(y0+y1)>>1;
889 clc
890 #ifdef USE_ACCURATE_CLIPPING
891 lda _ClipY0-1
892 adc _ClipY1-1
893 sta _ClipYc-1
894 #endif
895 lda _ClipY0+0
896 adc _ClipY1+0
897 sta _ClipYc+0
898
899 lda _ClipY0+1
900 adc _ClipY1+1
901 sta _ClipYc+1
902
903 lda _ClipYc+1
904 cmp #$80
905 ror _ClipYc+1
906 ror _ClipYc+0
907 #ifdef USE_ACCURATE_CLIPPING
908 ror _ClipYc-1
909 #endif
910 rts
911 .)
912
913 _ClipMoveP1
914 .(
915 ; x1=xc;
916 lda _ClipXc+0
917 sta _ClipX1+0
918 lda _ClipXc+1
919 sta _ClipX1+1
920 #ifdef USE_ACCURATE_CLIPPING
921 lda _ClipXc-1
922 sta _ClipX1-1
923 #endif
924
925 ; y1=yc;
926 lda _ClipYc+0
927 sta _ClipY1+0
928 lda _ClipYc+1
929 sta _ClipY1+1
930 #ifdef USE_ACCURATE_CLIPPING
931 lda _ClipYc-1
932 sta _ClipY1-1
933 #endif
934 rts
935 .)
936
937 _ClipMoveP0
938 .(
939 ; x0=xc;
940 lda _ClipXc+0
941 sta _ClipX0+0
942 lda _ClipXc+1
943 sta _ClipX0+1
944 #ifdef USE_ACCURATE_CLIPPING
945 lda _ClipXc-1
946 sta _ClipX0-1
947 #endif
948
949 ; y0=yc;
950 lda _ClipYc+0
951 sta _ClipY0+0
952 lda _ClipYc+1
953 sta _ClipY0+1
954 #ifdef USE_ACCURATE_CLIPPING
955 lda _ClipYc-1
956 sta _ClipY0-1
957 #endif
958 rts
959 .)
960
961
962 _ClipReturnPc
963 .(
964 ; LargeX=ClipXc;
965 lda _ClipXc+0
966 sta _LargeX+0
967 lda _ClipXc+1
968 sta _LargeX+1
969
970 ; LargeY=ClipYc;
971 lda _ClipYc+0
972 sta _LargeY+0
973 lda _ClipYc+1
974 sta _LargeY+1
975
976 rts
977 .)
978
979 _ClipReturnP0
980 .(
981 ; LargeX=LargeX0;
982 lda _LargeX0+0
983 sta _LargeX+0
984 lda _LargeX0+1
985 sta _LargeX+1
986
987 ; LargeY=LargeY0;
988 lda _LargeY0+0
989 sta _LargeY+0
990 lda _LargeY0+1
991 sta _LargeY+1
992
993 rts
994 .)
995
996 _ClipReturnP1
997 .(
998 ; LargeX=LargeX1;
999 lda _LargeX1+0
1000 sta _LargeX+0
1001 lda _LargeX1+1
1002 sta _LargeX+1
1003
1004 ; LargeY=LargeY1;
1005 lda _LargeY1+0
1006 sta _LargeY+0
1007 lda _LargeY+1
1008 sta _LargeY+1
1009
1010 rts
1011 .)
1012
1013 _ClipSetNormalStartPoints
1014 .(
1015 ; x0=LargeX0;
1016 ; y0=LargeY0;
1017 lda _LargeX0+0
1018 sta _ClipX0+0
1019 lda _LargeX0+1
1020 sta _ClipX0+1
1021
1022 lda _LargeY0+0
1023 sta _ClipY0+0
1024 lda _LargeY0+1
1025 sta _ClipY0+1
1026
1027 ; x1=LargeX1;
1028 ; y1=LargeY1;
1029 lda _LargeX1+0
1030 sta _ClipX1+0
1031 lda _LargeX1+1
1032 sta _ClipX1+1
1033
1034 lda _LargeY1+0
1035 sta _ClipY1+0
1036 lda _LargeY1+1
1037 sta _ClipY1+1
1038
1039 rts
1040 .)
1041
1042 _ClipSetInvertedStartPoints
1043 .(
1044 ; x0=LargeX1;
1045 ; y0=LargeY1;
1046 lda _LargeX1+0
1047 sta _ClipX0+0
1048 lda _LargeX1+1
1049 sta _ClipX0+1
1050
1051 lda _LargeY1+0
1052 sta _ClipY0+0
1053 lda _LargeY1+1
1054 sta _ClipY0+1
1055
1056 ; x1=LargeX0;
1057 ; y1=LargeY0;
1058 lda _LargeX0+0
1059 sta _ClipX1+0
1060 lda _LargeX0+1
1061 sta _ClipX1+1
1062
1063 lda _LargeY0+0
1064 sta _ClipY1+0
1065 lda _LargeY0+1
1066 sta _ClipY1+1
1067
1068 rts
1069 .)
1070
1071
1072 _ClipDichoTopBottom
1073 .(
1074 .(
1075 ; if (LargeY0==CLIP_TOP)
1076 cpx _LargeY0+0
1077 bne skip
1078 lda _LargeY0+1
1079 bne skip
1080 jmp _ClipReturnP0
1081 skip
1082 .)
1083
1084 .(
1085 ; if (LargeY1==CLIP_TOP)
1086 cpx _LargeY1+0
1087 bne skip
1088 lda _LargeY1+1
1089 bne skip
1090 jmp _ClipReturnP1
1091 skip
1092 .)
1093
1094 sec
1095 lda _LargeY0+0
1096 sbc _LargeY1+0
1097 lda _LargeY0+1
1098 sbc _LargeY1+1
1099 bmi label4
1100
1101 label3
1102 ; (LargeY0>=LargeY1)
1103 jsr _ClipSetInvertedStartPoints
1104 jmp end_swap
1105
1106 label4
1107 ; (LargeY0<LargeY1)
1108 jsr _ClipSetNormalStartPoints
1109
1110 end_swap
1111
1112 #ifdef USE_ACCURATE_CLIPPING
1113 lda #0
1114 sta _ClipX0-1
1115 sta _ClipY0-1
1116 sta _ClipX1-1
1117 sta _ClipY1-1
1118 #endif
1119
1120 loop
1121 jsr _ClipComputeMidPoint
1122
1123 ; if (yc==CLIP_TOP)
1124 cpx _ClipYc+0
1125 bne not_done
1126 lda _ClipYc+1
1127 beq done
1128
1129 not_done
1130
1131 sec
1132 txa
1133 sbc _ClipYc+0
1134 lda #0
1135 sbc _ClipYc+1
1136 bmi replace_first
1137
1138 replace_second
1139 ; if (yc<CLIP_TOP)
1140 jsr _ClipMoveP0
1141 jmp loop
1142
1143 replace_first
1144 ; if (yc>CLIP_TOP)
1145 jsr _ClipMoveP1
1146 jmp loop
1147
1148 done
1149 ; Finished !
1150 jmp _ClipReturnPc
1151 .)
1152
1153
1154 _ClipDichoLeftRight
1155 .(
1156 .(
1157 ; if (LargeX0==CLIP_LEFT/RIGHT)
1158 cpx _LargeX0+0
1159 bne skip
1160 lda _LargeX0+1
1161 bne skip
1162 jmp _ClipReturnP0
1163 skip
1164 .)
1165
1166 .(
1167 ; if (LargeX1==CLIP_LEFT/RIGHT)
1168 cpx _LargeX1+0
1169 bne skip
1170 lda _LargeX1+1
1171 bne skip
1172 jmp _ClipReturnP1
1173 skip
1174 .)
1175
1176 sec
1177 lda _LargeX0+0
1178 sbc _LargeX1+0
1179 lda _LargeX0+1
1180 sbc _LargeX1+1
1181 bmi label4
1182
1183 label3
1184 ; (LargeX0>=LargeX1)
1185 jsr _ClipSetInvertedStartPoints
1186 jmp end_swap
1187
1188 label4
1189 ; (LargeX0<LargeX1)
1190 jsr _ClipSetNormalStartPoints
1191
1192 end_swap
1193
1194 #ifdef USE_ACCURATE_CLIPPING
1195 lda #0
1196 sta _ClipX0-1
1197 sta _ClipY0-1
1198 sta _ClipX1-1
1199 sta _ClipY1-1
1200 #endif
1201
1202 loop
1203 jsr _ClipComputeMidPoint
1204
1205 ; if (xc==CLIP_LEFT/RIGHT)
1206 cpx _ClipXc+0
1207 bne not_done
1208 lda _ClipXc+1
1209 beq done
1210
1211 not_done
1212
1213 sec
1214 txa
1215 sbc _ClipXc+0
1216 lda #0
1217 sbc _ClipXc+1
1218 bmi replace_first
1219
1220 replace_second
1221 ; if (xc<CLIP_LEFT/RIGHT)
1222 jsr _ClipMoveP0
1223 jmp loop
1224
1225 replace_first
1226 ; if (xc>CLIP_LEFT/RIGHT)
1227 jsr _ClipMoveP1
1228 jmp loop
1229
1230 done
1231 ; Finished !
1232 jmp _ClipReturnPc
1233 .)
1234
1235
1236
1237
1238 ;
1239 ; In this code, we assume that the CLIP_ values are fitting
1240 ; the resolution of an Oric screen, so they will never be out
1241 ; of a 240x200 screen resolution, fit in an unsigned byte.
1242 ;
1243 _ClipFindRegion
1244 ;jmp _ClipFindRegion
1245 .(
1246 ; Initialize with 'not clipped'
1247 lda #0
1248
1249 ;
1250 ; Bottom test
1251 ;
1252 .(
1253 ldy _LargeY+1
1254 bmi end_bottom ; If the high byte of Y is negative, it's certainly not clipped
1255 bne clip_bottom ; If it's not negative, then it needs to be clipped for sure
1256
1257 ldy _LargeY+0
1258 cpy #(CLIP_BOTTOM+1) ; 194
1259 bcc end_bottom
1260
1261 clip_bottom
1262 ora #1 ; Means (y >= CLIP_BOTTOM)
1263
1264 jmp end_top ; If the end point is clipped on the bottom, it cannot be on the top side as well
1265 .)
1266 end_bottom
1267
1268 ;
1269 ; Top test
1270 ;
1271 .(
1272 ldy _LargeY+1
1273 bmi clip_top ; If the high byte of Y is negative, it certainly needs to be clipped
1274 bne end_top ; If it's not negative, then it's too large to be clipped on top
1275
1276 ldy _LargeY+0
1277 cpy #CLIP_TOP ; 5
1278 bcs end_top
1279
1280 clip_top
1281 ora #2 ; Means (y < CLIP_TOP)
1282 .)
1283 end_top
1284
1285 ;
1286 ; Righttest
1287 ;
1288 .(
1289 ldy _LargeX+1
1290 bmi end_right ; If the high byte of X is negative, it's certainly not clipped
1291 bne clip_right ; If it's not negative, then it needs to be clipped for sure
1292
1293 ldy _LargeX+0
1294 cpy #(CLIP_RIGHT+1)
1295 bcc end_right
1296
1297 clip_right
1298 ora #4 ; Means (x >= CLIP_RIGHT)
1299
1300 jmp end_left ; If the end point is clipped on the right, it cannot be on the left side as well
1301 .)
1302 end_right
1303
1304 ;
1305 ; Left test
1306 ;
1307 .(
1308 ldy _LargeX+1
1309 bmi clip_left ; If the high byte of X is negative, it certainly needs to be clipped
1310 bne end_left ; If it's not negative, then it's too large to be clipped on left
1311
1312 ldy _LargeX+0
1313 cpy #CLIP_LEFT
1314 bcs end_left
1315
1316 clip_left
1317 ora #8 ; Means (x < CLIP_LEFT)
1318 .)
1319 end_left
1320
1321 ; Save the result
1322 sta _ClipCode
1323 rts
1324 .)
1325
1326
1327 ; Compute the outcode for the first point
1328 _ClipComputeCode0
1329 .(
1330 lda _LargeX0+0
1331 sta _LargeX+0
1332 lda _LargeX0+1
1333 sta _LargeX+1
1334
1335 lda _LargeY0+0
1336 sta _LargeY+0
1337 lda _LargeY0+1
1338 sta _LargeY+1
1339
1340 jsr _ClipFindRegion
1341
1342 lda _ClipCode
1343 sta _ClipCode0
1344
1345 rts
1346 .)
1347
1348 ; Compute the outcode for the second point
1349 _ClipComputeCode1
1350 .(
1351 lda _LargeX1+0
1352 sta _LargeX+0
1353 lda _LargeX1+1
1354 sta _LargeX+1
1355
1356 lda _LargeY1+0
1357 sta _LargeY+0
1358 lda _LargeY1+1
1359 sta _LargeY+1
1360
1361 jsr _ClipFindRegion
1362
1363 lda _ClipCode
1364 sta _ClipCode1
1365
1366 rts
1367 .)
1368
1369 _DrawClippedLine
1370 .(
1371 ; The region outcodes for the the endpoints
1372 jsr _ClipComputeCode0
1373 jsr _ClipComputeCode1
1374
1375 ; In theory, this can never end up in an infinite loop, it'll always come in one of the trivial cases eventually
1376 clip_loop
1377
1378 lda _ClipCode0
1379 ora _ClipCode1
1380 bne end_trivial_draw
1381 .(
1382 ; /accept because both endpoints are in screen or on the border, trivial accept
1383 lda _LargeX0
1384 sta _CurrentPixelX
1385 lda _LargeY0
1386 sta _CurrentPixelY
1387 lda _LargeX1
1388 sta _OtherPixelX
1389 lda _LargeY1
1390 sta _OtherPixelY
1391 jmp _DrawLine
1392 ;rts
1393 .)
1394 end_trivial_draw
1395
1396 lda _ClipCode0
1397 and _ClipCode1
1398 beq end_invisible_line
1399 .(
1400 ; The line isn't visible on screen, trivial reject
1401 rts
1402 .)
1403 end_invisible_line
1404
1405 .(
1406 ; if no trivial reject or accept, continue the loop
1407 .(
1408 lda _ClipCode0
1409 bne skip
1410 lda _ClipCode1
1411 skip
1412 .)
1413
1414 lsr
1415 bcc end_clip_bottom
1416 ; Clip bottom
1417 ldx #CLIP_BOTTOM
1418 jsr _ClipDichoTopBottom
1419 jmp end_clip_switch
1420 end_clip_bottom
1421
1422 lsr
1423 bcc end_clip_top
1424 ; Clip top
1425 ldx #CLIP_TOP
1426 jsr _ClipDichoTopBottom
1427 jmp end_clip_switch
1428 end_clip_top
1429
1430 lsr
1431 bcc end_clip_right
1432 ; Clip right
1433 ldx #CLIP_RIGHT
1434 jsr _ClipDichoLeftRight
1435 jmp end_clip_switch
1436 end_clip_right
1437
1438 lsr
1439 bcc end_clip_left
1440 ; Clip left
1441 ldx #CLIP_LEFT
1442 jsr _ClipDichoLeftRight
1443 jmp end_clip_switch
1444 end_clip_left
1445
1446 end_clip_switch
1447
1448 lda _ClipCode0
1449 beq clip_second_point
1450
1451 clip_first_point
1452 ; First endpoint was clipped
1453 lda _LargeX+0
1454 sta _LargeX0+0
1455 lda _LargeX+1
1456 sta _LargeX0+1
1457
1458 lda _LargeY+0
1459 sta _LargeY0+0
1460 lda _LargeY+1
1461 sta _LargeY0+1
1462
1463 jsr _ClipComputeCode0
1464
1465 jmp clip_loop
1466
1467 clip_second_point
1468 ; Second endpoint was clipped
1469 lda _LargeX+0
1470 sta _LargeX1+0
1471 lda _LargeX+1
1472 sta _LargeX1+1
1473
1474 lda _LargeY+0
1475 sta _LargeY1+0
1476 lda _LargeY+1
1477 sta _LargeY1+1
1478
1479 jsr _ClipComputeCode1
1480
1481 jmp clip_loop
1482
1483 .)
1484
1485 ; Not supposed to arrive here :p
1486 rts
1487 .)
1488
1489
1490 _DoubleBuffOn
1491 .(
1492 lda double_buff
1493 beq _SwitchDoubleBuff
1494 rts
1495 .)
1496
1497 _DoubleBuffOff
1498 .(
1499 lda double_buff
1500 bne _SwitchDoubleBuff
1501 rts
1502 .)
1503
1504
1505 _SwitchDoubleBuff
1506 .(
1507
1508 ; Patch the circle routine
1509 lda patch_circleclip+1
1510 cmp #199
1511 beq clip1
1512 lda #199
1513 jmp cont
1514 clip1
1515 lda #(CLIP_BOTTOM)
1516
1517 cont
1518 sta patch_circleclip+1
1519 lda double_buff
1520 eor #$ff
1521 sta double_buff
1522 jmp _GenerateTables
1523 .)
1524
1525
1526
1527 #undef e
1528 #undef i
1529 #undef dx
1530 #undef dy
1531
1532
1533 #endif
1534
1535
1536
1537
1538
1539

  ViewVC Help
Powered by ViewVC 1.1.26