2 ; Ullrich von Bassewitz, 2009-10-25
4 ; Clips the line in ptr1/ptr2/ptr3/ptr4 to the screen coordinates
9 .export _tgi_clip_x1, _tgi_clip_y1, _tgi_clip_x2, _tgi_clip_y2
10 .export _tgi_clip_o1, _tgi_clip_o2 ; Debugging!
11 .export _tgi_clip_dx, _tgi_clip_dy
12 .export _tgi_xmax, _tgi_ymax
15 .import imul16x16r32, idiv32by16r16
16 .import return0, return1
18 .include "tgi-kernel.inc"
19 .include "zeropage.inc"
25 ;----------------------------------------------------------------------------
26 ; outcode constants. These aren't really used because most stuff is done by
27 ; shifting the values, but they're here for documentation.
37 ;----------------------------------------------------------------------------
38 ; Generate a Cohen Sutherland outcode for tgi_clip_x1/tgi_clip_y1 in _tgi_clip_o1
44 ; _tgi_clip_o1 = CLIP_BOTTOM;
45 ; } else if (Y1 >= yres) {
46 ; _tgi_clip_o1 = CLIP_TOP;
49 ; _tgi_clip_o1 |= CLIP_LEFT;
50 ; } else if (X1 >= xres) {
51 ; _tgi_clip_o1 |= CLIP_RIGHT;
57 ldy #CLIP_BOTTOM ; Assume line needs bottom clip
61 lda _tgi_clip_y1+1 ; High byte of Y1
62 bmi L2 ; Jump if bottom clip
64 ldy #CLIP_TOP ; Assume line needs top clip
65 ldx _tgi_clip_y1 ; Low byte of Y1
72 ldy #CLIP_NONE ; No clipping actually
79 ldy #CLIP_LEFT ; Assume line needs left clip
81 lda _tgi_clip_x1+1 ; High byte of X1
82 bmi L4 ; Jump if left clip
84 ldy #CLIP_RIGHT ; Assume line needs right clip
86 ldx _tgi_clip_x1 ; Low byte of X1
93 ldy #CLIP_NONE ; No clipping actually
104 ;----------------------------------------------------------------------------
105 ; Generate a Cohen Sutherland outcode for tgi_clip_x2/tgi_clip_y2 in _tgi_clip_o2
111 ; _tgi_clip_o2 = CLIP_BOTTOM;
112 ; } else if (Y2 >= yres) {
113 ; _tgi_clip_o2 = CLIP_TOP;
116 ; _tgi_clip_o2 |= CLIP_LEFT;
117 ; } else if (X2 >= xres) {
118 ; _tgi_clip_o2 |= CLIP_RIGHT;
124 ldy #CLIP_BOTTOM ; Assume line needs bottom clip
128 lda _tgi_clip_y2+1 ; High byte of Y2
129 bmi L2 ; Jump if bottom clip
131 ldy #CLIP_TOP ; Assume line needs top clip
132 ldx _tgi_clip_y2 ; Low byte of Y4
139 ldy #CLIP_NONE ; No clipping actually
146 ldy #CLIP_LEFT ; Assume line needs left clip
148 lda _tgi_clip_x2+1 ; High byte of X2
149 bmi L4 ; Jump if left clip
151 ldy #CLIP_RIGHT ; Assume line needs right clip
153 ldx _tgi_clip_x2 ; Low byte of X2
160 ldy #CLIP_NONE ; No clipping actually
172 ;----------------------------------------------------------------------------
173 ; Calculate dx and dy
200 ;----------------------------------------------------------------------------
201 ; Multiplicate value in y/a by dy, then divide by dx.
209 ldx _tgi_clip_dy+1 ; rhs
210 jsr imul16x16r32 ; Multiplicate
212 ; Move the result of the multiplication into ptr1:ptr2
221 ; Load divisor and divide
231 ;----------------------------------------------------------------------------
232 ; Multiplicate value in y/a by dx, then divide by dy.
240 ldx _tgi_clip_dx+1 ; rhs
241 jsr imul16x16r32 ; Multiplicate
243 ; Move the result of the multiplication into ptr1:ptr2
252 ; Load divisor and divide
262 ;----------------------------------------------------------------------------
263 ; Clip a line using Cohen Sutherland
274 ; if ((_tgi_clip_o1 | _tgi_clip_o2) == 0) accept;
276 Loop: lda _tgi_clip_o1
281 ; if ((_tgi_clip_o1 & _tgi_clip_o2) != 0) reject;
288 ; Check if X1/Y1 needs clipping
295 lsr a ; Check for CLIP_LEFT
298 ; tgi_clip_y1 += (0 - tgi_clip_x1) * tgi_clip_dy / tgi_clip_dx;
305 L3: lsr a ; Check for CLIP_RIGHT
308 ; tgi_clip_y1 += (tgi_xmax - tgi_clip_x1) * tgi_clip_dy / tgi_clip_dx;
309 ; tgi_clip_x1 = tgi_xmax;
337 L5: lsr a ; Check for CLIP_BOTTOM
340 ; tgi_clip_x1 = (0 - tgi_clip_y1) * tgi_clip_dx / tgi_clip_dy;
347 L6: lsr a ; Check for CLIP_TOP
350 ; tgi_clip_x1 += (tgi_ymax - tgi_clip_y1) * tgi_clip_dx / tgi_clip_dy;
351 ; tgi_clip_y1 = ymax;
374 ; We need to recalculate outcode1 in this case
378 ; Check if X2/Y2 needs clipping
380 L10: lda _tgi_clip_o2
385 lsr a ; Check for CLIP_LEFT
388 ; tgi_clip_y2 += (0 - tgi_clip_x2) * tgi_clip_dy / tgi_clip_dx;
395 L11: lsr a ; Check for CLIP_RIGHT
398 ; tgi_clip_y2 += (tgi_xmax - tgi_clip_x2) * tgi_clip_dy / tgi_clip_dx;
399 ; tgi_clip_x2 = tgi_xmax;
427 L13: lsr a ; Check for CLIP_BOTTOM
430 ; tgi_clip_x2 += (0 - tgi_clip_y2) * tgi_clip_dx / tgi_clip_dy;
437 L14: lsr a ; Check for CLIP_TOP
440 ; tgi_clip_x2 += (tgi_ymax - tgi_clip_y2) * tgi_clip_dx / tgi_clip_dy;
441 ; tgi_clip_y2 = tgi_ymax;
464 ; We need to recalculate outcode2 in this case
477 ;----------------------------------------------------------------------------