1 /* Ok, one other line algorithm.
2 * With subpixel and anti-alias, that's the point !
3 * Starting : Tue Sep 21 17:44:20 MET DST 1999
4 * Wed Sep 22 00:11:58 MET DST 1999 : almost done.
5 * I had some eating time and washing too, so I did not
6 * spend all this time on it. I must do a max routine
7 * (put the max value between the point and the current
8 * point). Not sure about my anti-alias stuff. Gonna watch some
9 * demos to see what it give with them.
10 * Let's go.
11 */
12
13 #include "line.h"
14
15 #include <stdio.h>
16 #include <stdlib.h>
17 #include <string.h>
18
19 #include "screen.h"
20 #include "device.h"
21 #include "poly.h"
22
23 device_line *the_lines;
24
25 /* returns a*b/c in int 16:16 */
muldiv(int a,int b,int c)26 static inline int muldiv(int a, int b, int c)
27 {
28 #ifdef PC_ARCHI
29 register int r;
30 __asm__ volatile ("imul %2 \n"
31 "idiv %3 \n"
32 : "=a" (r)
33 : "a" (a), "b" (b), "c" (c)
34 : "eax", "ebx", "ecx", "edx"
35 );
36 return r;
37 #else
38 return (double)a*(double)b/(double)c;
39 #endif
40 }
41
drawline8(device * d,line * l)42 void drawline8(device *d, line *l)
43 {
44 /* lots of goto for lisibility (if if else if if else else is impossible to debug) */
45 register int x1=l->p1.x*65536., x2=l->p2.x*65536.,
46 y1=l->p1.y*65536., y2=l->p2.y*65536., dx, dy;
47 register int xcur;
48 register int xinc;
49 register int ycur;
50 register int yinc;
51 register int i;
52 register int y1i=(y1+65535)>>16, y2i=(y2+65535)>>16;
53 register int x1i=(x1+65535)>>16, x2i=(x2+65535)>>16;
54 register unsigned char *dest;
55 register unsigned char col1=l->color;
56 register int xf;
57 register int yf;
58
59 /* in asm, those two subs are good for us, because we can test if x1<x2 and if y1<y2 at the same time, but it's C */
60 dx=x2-x1;
61 dy=y2-y1;
62
63 if (dx<0)
64 goto x1_sup_x2;
65 if (dx)
66 goto x1_inf_x2;
67
68 /* here x1==x2 */
69 if (dy<0)
70 goto x1_eq_x2_and_y1_sup_y2;
71 if (dy>0)
72 goto x1_eq_x2_and_y1_inf_y2;
73 /* here x1==x2 && y1==y2 */
74 if (y1i<y2i) {
75 dest=d->buffer+y1i*SCREEN_X+(x1>>16);
76 } else {
77 dest=d->buffer+y2i*SCREEN_X+(x1>>16);
78 }
79 *dest=col1;
80 return;
81 x1_eq_x2_and_y1_sup_y2:
82 dest=d->buffer+y2i*SCREEN_X+(x1>>16);
83 for (i=y2i; i<y1i; dest+=SCREEN_X, i++) {
84 *dest=col1;
85 }
86 return;
87 x1_eq_x2_and_y1_inf_y2:
88 dest=d->buffer+y1i*SCREEN_X+(x1>>16);
89 for (i=y1i; i<y2i; dest+=SCREEN_X, i++) {
90 *dest=col1;
91 }
92 return;
93
94 x1_inf_x2:
95 if (dy<0)
96 goto x1_inf_x2_and_y1_sup_y2;
97 if (dy>0)
98 goto x1_inf_x2_and_y1_inf_y2;
99 /* x1<x2 && y1==y2 */
100 dest=d->buffer+(y1>>16)*SCREEN_X+x1i;
101 for (i=x1i; i<x2i; dest++, i++) {
102 *dest=col1;
103 }
104 return;
105
106 x1_inf_x2_and_y1_sup_y2:
107 /*
108 (x2, y2)
109
110
111 (x1, y1)
112 */
113 /* remove those abs in the asm code */
114 if (abs(dx)>abs(dy))
115 goto x1_inf_x2_and_y1_sup_y2_dx_sup_dy;
116 if (abs(dx)<abs(dy))
117 goto x1_inf_x2_and_y1_sup_y2_dx_inf_dy;
118 /* here dx == dy */
119 dest=d->buffer+y2i*SCREEN_X+(x2>>16);
120 for (i=y2i; i<y1i; dest+=SCREEN_X-1, i++) {
121 *dest=col1;
122 }
123 return;
124 x1_inf_x2_and_y1_sup_y2_dx_sup_dy:
125 /*
126 xxxx
127 xxxx
128 xxxx
129 xxxx
130 */
131 yinc=muldiv(dy, 65536, dx);
132 ycur=y2+muldiv(yinc, (x2i<<16)-x2, 65536);
133 yf=ycur&65535;
134 dest=d->buffer+(ycur>>16)*SCREEN_X+x2i;
135 for (i=x2i; i>x1i; i--, dest--) {
136 *dest=col1;
137 yf-=yinc;
138 if (yf>65535) {
139 yf-=65536;
140 dest+=SCREEN_X;
141 }
142 }
143 return;
144 x1_inf_x2_and_y1_sup_y2_dx_inf_dy:
145 /*
146 x
147 x
148 x
149 x
150 x
151 x
152 x
153 x
154 x
155 */
156 xinc=muldiv(dx, 65536, dy);
157 xcur=x2+muldiv(xinc, (y2i<<16)-y2, 65536);
158 xf=xcur&65535;
159 dest=d->buffer+y2i*SCREEN_X+(xcur>>16);
160 for (i=y2i; i<y1i; i++, dest+=SCREEN_X) {
161 *dest=col1;
162 xf+=xinc;
163 if (xf<0) {
164 xf+=65536;
165 dest--;
166 }
167 }
168 return;
169
170 x1_inf_x2_and_y1_inf_y2:
171 /*
172 (x1, y1)
173
174
175 (x2, y2)
176 */
177 if (abs(dx)>abs(dy))
178 goto x1_inf_x2_and_y1_inf_y2_and_dx_sup_dy;
179 if (abs(dx)<abs(dy))
180 goto x1_inf_x2_and_y1_inf_y2_and_dx_inf_dy;
181 /* here dx == dy */
182 dest=d->buffer+y1i*SCREEN_X+(x1>>16);
183 for (i=y1i; i<y2i; dest+=SCREEN_X+1, i++) {
184 *dest=col1;
185 }
186 return;
187
188 x1_inf_x2_and_y1_inf_y2_and_dx_sup_dy:
189 /*
190 xxxx
191 xxxx
192 xxxx
193 */
194 yinc=muldiv(dy, 65536, dx);
195 ycur=y1+muldiv(yinc, (x1i<<16)-x1, 65536);
196 yf=ycur&65535;
197 dest=d->buffer+(ycur>>16)*SCREEN_X+x1i;
198 for (i=x1i; i<x2i; i++, dest++) {
199 *dest=col1;
200 yf+=yinc;
201 if (yf>65535) {
202 yf-=65536;
203 dest+=SCREEN_X;
204 }
205 }
206 return;
207 x1_inf_x2_and_y1_inf_y2_and_dx_inf_dy:
208 /*
209 x
210 x
211 x
212 x
213 x
214 x
215 x
216 x
217 x
218 */
219 xinc=muldiv(dx, 65536, dy);
220 xcur=x1+muldiv(xinc, (y1i<<16)-y1, 65536);
221 xf=xcur&65535;
222 dest=d->buffer+y1i*SCREEN_X+(xcur>>16);
223 for (i=y1i; i<y2i; i++, dest+=SCREEN_X) {
224 *dest=col1;
225 xf+=xinc;
226 if (xf>65536) {
227 xf-=65536;
228 dest++;
229 }
230 }
231 return;
232
233 x1_sup_x2:
234 if (dy<0)
235 goto x1_sup_x2_and_y1_sup_y2;
236 if (dy>0)
237 goto x1_sup_x2_and_y1_inf_y2;
238 /* x1>x2 && y1==y2 */
239 dest=d->buffer+(y2>>16)*SCREEN_X+x2i;
240 for (i=x2i; i<x1i; dest++, i++) {
241 *dest=col1;
242 }
243 return;
244 x1_sup_x2_and_y1_sup_y2:
245 /*
246 (x2, y2)
247
248
249 (x1, y1)
250 */
251 if (abs(dx)>abs(dy))
252 goto x1_sup_x2_and_y1_sup_y2_and_dx_sup_dy;
253 if (abs(dx)<abs(dy))
254 goto x1_sup_x2_and_y1_sup_y2_and_dx_inf_dy;
255 /* here dx == dy */
256 dest=d->buffer+y2i*SCREEN_X+(x2>>16);
257 for (i=y2i; i<y1i; dest+=SCREEN_X+1, i++) {
258 *dest=col1;
259 }
260 return;
261 x1_sup_x2_and_y1_sup_y2_and_dx_sup_dy:
262 yinc=muldiv(dy, 65536, dx);
263 ycur=y2+muldiv(yinc, (x2i<<16)-x2, 65536);
264 yf=ycur&65535;
265 dest=d->buffer+(ycur>>16)*SCREEN_X+x2i;
266 for (i=x2i; i<x1i; i++, dest++) {
267 *dest=col1;
268 yf+=yinc;
269 if (yf>65535) {
270 yf-=65536;
271 dest+=SCREEN_X;
272 }
273 }
274 return;
275 x1_sup_x2_and_y1_sup_y2_and_dx_inf_dy:
276 xinc=muldiv(dx, 65536, dy);
277 xcur=x2+muldiv(xinc, (y2i<<16)-y2, 65536);
278 xf=xcur&65535;
279 dest=d->buffer+y2i*SCREEN_X+(xcur>>16);
280 for (i=y2i; i<y1i; i++, dest+=SCREEN_X) {
281 *dest=col1;
282 xf+=xinc;
283 if (xf>65536) {
284 xf-=65536;
285 dest++;
286 }
287 }
288 return;
289
290 x1_sup_x2_and_y1_inf_y2:
291 /*
292 (x1, y1)
293
294
295 (x2, y2)
296 */
297 if (abs(dx)>abs(dy))
298 goto x1_sup_x2_and_y1_inf_y2_and_dx_sup_dy;
299 if (abs(dx)<abs(dy))
300 goto x1_sup_x2_and_y1_inf_y2_and_dx_inf_dy;
301 /* here dx == dy */
302 dest=d->buffer+y1i*SCREEN_X+(x1>>16);
303 for (i=y1i; i<y2i; dest+=SCREEN_X-1, i++) {
304 *dest=col1;
305 }
306 return;
307 x1_sup_x2_and_y1_inf_y2_and_dx_sup_dy:
308 yinc=muldiv(dy, 65536, dx);
309 ycur=y1+muldiv(yinc, (x1i<<16)-x1, 65536);
310 yf=ycur&65535;
311 dest=d->buffer+(ycur>>16)*SCREEN_X+x1i;
312 for (i=x1i; i>x2i; i--, dest--) {
313 *dest=col1;
314 yf-=yinc;
315 if (yf>65535) {
316 yf-=65536;
317 dest+=SCREEN_X;
318 }
319 }
320 return;
321 x1_sup_x2_and_y1_inf_y2_and_dx_inf_dy:
322 xinc=muldiv(dx, 65536, dy);
323 xcur=x1+muldiv(xinc, (y1i<<16)-y1, 65536);
324 xf=xcur&65535;
325 dest=d->buffer+y1i*SCREEN_X+(xcur>>16);
326 for (i=y1i; i<y2i; i++, dest+=SCREEN_X) {
327 *dest=col1;
328 xf+=xinc;
329 if (xf<0) {
330 xf+=65536;
331 dest--;
332 }
333 }
334 return;
335 }
336
drawline16(device * d,line * l)337 void drawline16(device *d, line *l)
338 {
339 /* lots of goto for lisibility (if if else if if else else is impossible to debug) */
340 register int x1=l->p1.x*65536., x2=l->p2.x*65536., y1=l->p1.y*65536., y2=l->p2.y*65536., dx, dy;
341 register int xcur;
342 register int xinc;
343 register int ycur;
344 register int yinc;
345 register int i;
346 register int y1i=(y1+65535)>>16, y2i=(y2+65535)>>16;
347 register int x1i=(x1+65535)>>16, x2i=(x2+65535)>>16;
348 register unsigned short *dest;
349 register unsigned short col1=l->color;
350 register int xf;
351 register int yf;
352
353 /* in asm, those two subs are good for us, because we can test if x1<x2 and if y1<y2 at the same time, but it's C */
354 dx=x2-x1;
355 dy=y2-y1;
356
357 if (dx<0)
358 goto x1_sup_x2;
359 if (dx)
360 goto x1_inf_x2;
361
362 /* here x1==x2 */
363 if (dy<0)
364 goto x1_eq_x2_and_y1_sup_y2;
365 if (dy>0)
366 goto x1_eq_x2_and_y1_inf_y2;
367 /* here x1==x2 && y1==y2 */
368 if (y1i<y2i) {
369 dest=(unsigned short *)d->buffer+y1i*SCREEN_X+(x1>>16);
370 } else {
371 dest=(unsigned short *)d->buffer+y2i*SCREEN_X+(x1>>16);
372 }
373 *dest=col1;
374 return;
375 x1_eq_x2_and_y1_sup_y2:
376 dest=(unsigned short *)d->buffer+y2i*SCREEN_X+(x1>>16);
377 for (i=y2i; i<y1i; dest+=SCREEN_X, i++) {
378 *dest=col1;
379 }
380 return;
381 x1_eq_x2_and_y1_inf_y2:
382 dest=(unsigned short *)d->buffer+y1i*SCREEN_X+(x1>>16);
383 for (i=y1i; i<y2i; dest+=SCREEN_X, i++) {
384 *dest=col1;
385 }
386 return;
387
388 x1_inf_x2:
389 if (dy<0)
390 goto x1_inf_x2_and_y1_sup_y2;
391 if (dy>0)
392 goto x1_inf_x2_and_y1_inf_y2;
393 /* x1<x2 && y1==y2 */
394 dest=(unsigned short *)d->buffer+(y1>>16)*SCREEN_X+x1i;
395 for (i=x1i; i<x2i; dest++, i++) {
396 *dest=col1;
397 }
398 return;
399
400 x1_inf_x2_and_y1_sup_y2:
401 /*
402 (x2, y2)
403
404
405 (x1, y1)
406 */
407 /* remove those abs in the asm code */
408 if (abs(dx)>abs(dy))
409 goto x1_inf_x2_and_y1_sup_y2_dx_sup_dy;
410 if (abs(dx)<abs(dy))
411 goto x1_inf_x2_and_y1_sup_y2_dx_inf_dy;
412 /* here dx == dy */
413 dest=(unsigned short *)d->buffer+y2i*SCREEN_X+(x2>>16);
414 for (i=y2i; i<y1i; dest+=SCREEN_X-1, i++) {
415 *dest=col1;
416 }
417 return;
418 x1_inf_x2_and_y1_sup_y2_dx_sup_dy:
419 /*
420 xxxx
421 xxxx
422 xxxx
423 xxxx
424 */
425 yinc=muldiv(dy, 65536, dx);
426 ycur=y2+muldiv(yinc, (x2i<<16)-x2, 65536);
427 yf=ycur&65535;
428 dest=(unsigned short *)d->buffer+(ycur>>16)*SCREEN_X+x2i;
429 for (i=x2i; i>x1i; i--, dest--) {
430 *dest=col1;
431 yf-=yinc;
432 if (yf>65535) {
433 yf-=65536;
434 dest+=SCREEN_X;
435 }
436 }
437 return;
438 x1_inf_x2_and_y1_sup_y2_dx_inf_dy:
439 /*
440 x
441 x
442 x
443 x
444 x
445 x
446 x
447 x
448 x
449 */
450 xinc=muldiv(dx, 65536, dy);
451 xcur=x2+muldiv(xinc, (y2i<<16)-y2, 65536);
452 xf=xcur&65535;
453 dest=(unsigned short *)d->buffer+y2i*SCREEN_X+(xcur>>16);
454 for (i=y2i; i<y1i; i++, dest+=SCREEN_X) {
455 *dest=col1;
456 xf+=xinc;
457 if (xf<0) {
458 xf+=65536;
459 dest--;
460 }
461 }
462 return;
463
464 x1_inf_x2_and_y1_inf_y2:
465 /*
466 (x1, y1)
467
468
469 (x2, y2)
470 */
471 if (abs(dx)>abs(dy))
472 goto x1_inf_x2_and_y1_inf_y2_and_dx_sup_dy;
473 if (abs(dx)<abs(dy))
474 goto x1_inf_x2_and_y1_inf_y2_and_dx_inf_dy;
475 /* here dx == dy */
476 dest=(unsigned short *)d->buffer+y1i*SCREEN_X+(x1>>16);
477 for (i=y1i; i<y2i; dest+=SCREEN_X+1, i++) {
478 *dest=col1;
479 }
480 return;
481
482 x1_inf_x2_and_y1_inf_y2_and_dx_sup_dy:
483 /*
484 xxxx
485 xxxx
486 xxxx
487 */
488 yinc=muldiv(dy, 65536, dx);
489 ycur=y1+muldiv(yinc, (x1i<<16)-x1, 65536);
490 yf=ycur&65535;
491 dest=(unsigned short *)d->buffer+(ycur>>16)*SCREEN_X+x1i;
492 for (i=x1i; i<x2i; i++, dest++) {
493 *dest=col1;
494 yf+=yinc;
495 if (yf>65535) {
496 yf-=65536;
497 dest+=SCREEN_X;
498 }
499 }
500 return;
501 x1_inf_x2_and_y1_inf_y2_and_dx_inf_dy:
502 /*
503 x
504 x
505 x
506 x
507 x
508 x
509 x
510 x
511 x
512 */
513 xinc=muldiv(dx, 65536, dy);
514 xcur=x1+muldiv(xinc, (y1i<<16)-y1, 65536);
515 xf=xcur&65535;
516 dest=(unsigned short *)d->buffer+y1i*SCREEN_X+(xcur>>16);
517 for (i=y1i; i<y2i; i++, dest+=SCREEN_X) {
518 *dest=col1;
519 xf+=xinc;
520 if (xf>65536) {
521 xf-=65536;
522 dest++;
523 }
524 }
525 return;
526
527 x1_sup_x2:
528 if (dy<0)
529 goto x1_sup_x2_and_y1_sup_y2;
530 if (dy>0)
531 goto x1_sup_x2_and_y1_inf_y2;
532 /* x1>x2 && y1==y2 */
533 dest=(unsigned short *)d->buffer+(y2>>16)*SCREEN_X+x2i;
534 for (i=x2i; i<x1i; dest++, i++) {
535 *dest=col1;
536 }
537 return;
538 x1_sup_x2_and_y1_sup_y2:
539 /*
540 (x2, y2)
541
542
543 (x1, y1)
544 */
545 if (abs(dx)>abs(dy))
546 goto x1_sup_x2_and_y1_sup_y2_and_dx_sup_dy;
547 if (abs(dx)<abs(dy))
548 goto x1_sup_x2_and_y1_sup_y2_and_dx_inf_dy;
549 /* here dx == dy */
550 dest=(unsigned short *)d->buffer+y2i*SCREEN_X+(x2>>16);
551 for (i=y2i; i<y1i; dest+=SCREEN_X+1, i++) {
552 *dest=col1;
553 }
554 return;
555 x1_sup_x2_and_y1_sup_y2_and_dx_sup_dy:
556 yinc=muldiv(dy, 65536, dx);
557 ycur=y2+muldiv(yinc, (x2i<<16)-x2, 65536);
558 yf=ycur&65535;
559 dest=(unsigned short *)d->buffer+(ycur>>16)*SCREEN_X+x2i;
560 for (i=x2i; i<x1i; i++, dest++) {
561 *dest=col1;
562 yf+=yinc;
563 if (yf>65535) {
564 yf-=65536;
565 dest+=SCREEN_X;
566 }
567 }
568 return;
569 x1_sup_x2_and_y1_sup_y2_and_dx_inf_dy:
570 xinc=muldiv(dx, 65536, dy);
571 xcur=x2+muldiv(xinc, (y2i<<16)-y2, 65536);
572 xf=xcur&65535;
573 dest=(unsigned short *)d->buffer+y2i*SCREEN_X+(xcur>>16);
574 for (i=y2i; i<y1i; i++, dest+=SCREEN_X) {
575 *dest=col1;
576 xf+=xinc;
577 if (xf>65536) {
578 xf-=65536;
579 dest++;
580 }
581 }
582 return;
583
584 x1_sup_x2_and_y1_inf_y2:
585 /*
586 (x1, y1)
587
588
589 (x2, y2)
590 */
591 if (abs(dx)>abs(dy))
592 goto x1_sup_x2_and_y1_inf_y2_and_dx_sup_dy;
593 if (abs(dx)<abs(dy))
594 goto x1_sup_x2_and_y1_inf_y2_and_dx_inf_dy;
595 /* here dx == dy */
596 dest=(unsigned short *)d->buffer+y1i*SCREEN_X+(x1>>16);
597 for (i=y1i; i<y2i; dest+=SCREEN_X-1, i++) {
598 *dest=col1;
599 }
600 return;
601 x1_sup_x2_and_y1_inf_y2_and_dx_sup_dy:
602 yinc=muldiv(dy, 65536, dx);
603 ycur=y1+muldiv(yinc, (x1i<<16)-x1, 65536);
604 yf=ycur&65535;
605 dest=(unsigned short *)d->buffer+(ycur>>16)*SCREEN_X+x1i;
606 for (i=x1i; i>x2i; i--, dest--) {
607 *dest=col1;
608 yf-=yinc;
609 if (yf>65535) {
610 yf-=65536;
611 dest+=SCREEN_X;
612 }
613 }
614 return;
615 x1_sup_x2_and_y1_inf_y2_and_dx_inf_dy:
616 xinc=muldiv(dx, 65536, dy);
617 xcur=x1+muldiv(xinc, (y1i<<16)-y1, 65536);
618 xf=xcur&65535;
619 dest=(unsigned short *)d->buffer+y1i*SCREEN_X+(xcur>>16);
620 for (i=y1i; i<y2i; i++, dest+=SCREEN_X) {
621 *dest=col1;
622 xf+=xinc;
623 if (xf<0) {
624 xf+=65536;
625 dest--;
626 }
627 }
628 return;
629 }
630
drawline24(device * d,line * l)631 void drawline24(device *d, line *l)
632 {
633 /* lots of goto for lisibility (if if else if if else else is impossible to debug) */
634 register int x1=l->p1.x*65536., x2=l->p2.x*65536., y1=l->p1.y*65536., y2=l->p2.y*65536., dx, dy;
635 register int xcur;
636 register int xinc;
637 register int ycur;
638 register int yinc;
639 register int i;
640 register int y1i=(y1+65535)>>16, y2i=(y2+65535)>>16;
641 register int x1i=(x1+65535)>>16, x2i=(x2+65535)>>16;
642 register unsigned char *dest;
643 register unsigned char col1=l->color&255;
644 register unsigned char col2=(l->color>>8)&255;
645 register unsigned char col3=l->color>>16;
646 register int xf;
647 register int yf;
648
649 /* in asm, those two subs are good for us, because we can test if x1<x2 and if y1<y2 at the same time, but it's C */
650 dx=x2-x1;
651 dy=y2-y1;
652
653 if (dx<0)
654 goto x1_sup_x2;
655 if (dx)
656 goto x1_inf_x2;
657
658 /* here x1==x2 */
659 if (dy<0)
660 goto x1_eq_x2_and_y1_sup_y2;
661 if (dy>0)
662 goto x1_eq_x2_and_y1_inf_y2;
663 /* here x1==x2 && y1==y2 */
664 if (y1i<y2i) {
665 dest=d->buffer+(y1i*SCREEN_X+(x1>>16))*3;
666 } else {
667 dest=d->buffer+(y2i*SCREEN_X+(x1>>16))*3;
668 }
669 *dest=col1;
670 *(dest+1)=col2;
671 *(dest+2)=col3;
672 return;
673 x1_eq_x2_and_y1_sup_y2:
674 dest=d->buffer+(y2i*SCREEN_X+(x1>>16))*3;
675 for (i=y2i; i<y1i; dest+=SCREEN_X*3, i++) {
676 *dest=col1;
677 *(dest+1)=col2;
678 *(dest+2)=col3;
679 }
680 return;
681 x1_eq_x2_and_y1_inf_y2:
682 dest=d->buffer+(y1i*SCREEN_X+(x1>>16))*3;
683 for (i=y1i; i<y2i; dest+=SCREEN_X*3, i++) {
684 *dest=col1;
685 *(dest+1)=col2;
686 *(dest+2)=col3;
687 }
688 return;
689
690 x1_inf_x2:
691 if (dy<0)
692 goto x1_inf_x2_and_y1_sup_y2;
693 if (dy>0)
694 goto x1_inf_x2_and_y1_inf_y2;
695 /* x1<x2 && y1==y2 */
696 dest=d->buffer+((y1>>16)*SCREEN_X+x1i)*3;
697 for (i=x1i; i<x2i; dest+=3, i++) {
698 *dest=col1;
699 *(dest+1)=col2;
700 *(dest+2)=col3;
701 }
702 return;
703
704 x1_inf_x2_and_y1_sup_y2:
705 /*
706 (x2, y2)
707
708
709 (x1, y1)
710 */
711 /* remove those abs in the asm code */
712 if (abs(dx)>abs(dy))
713 goto x1_inf_x2_and_y1_sup_y2_dx_sup_dy;
714 if (abs(dx)<abs(dy))
715 goto x1_inf_x2_and_y1_sup_y2_dx_inf_dy;
716 /* here dx == dy */
717 dest=d->buffer+(y2i*SCREEN_X+(x2>>16))*3;
718 for (i=y2i; i<y1i; dest+=(SCREEN_X-1)*3, i++) {
719 *dest=col1;
720 *(dest+1)=col2;
721 *(dest+2)=col3;
722 }
723 return;
724 x1_inf_x2_and_y1_sup_y2_dx_sup_dy:
725 /*
726 xxxx
727 xxxx
728 xxxx
729 xxxx
730 */
731 yinc=muldiv(dy, 65536, dx);
732 ycur=y2+muldiv(yinc, (x2i<<16)-x2, 65536);
733 yf=ycur&65535;
734 dest=d->buffer+((ycur>>16)*SCREEN_X+x2i)*3;
735 for (i=x2i; i>x1i; i--, dest-=3) {
736 *dest=col1;
737 *(dest+1)=col2;
738 *(dest+2)=col3;
739 yf-=yinc;
740 if (yf>65535) {
741 yf-=65536;
742 dest+=SCREEN_X*3;
743 }
744 }
745 return;
746 x1_inf_x2_and_y1_sup_y2_dx_inf_dy:
747 /*
748 x
749 x
750 x
751 x
752 x
753 x
754 x
755 x
756 x
757 */
758 xinc=muldiv(dx, 65536, dy);
759 xcur=x2+muldiv(xinc, (y2i<<16)-y2, 65536);
760 xf=xcur&65535;
761 dest=d->buffer+(y2i*SCREEN_X+(xcur>>16))*3;
762 for (i=y2i; i<y1i; i++, dest+=SCREEN_X*3) {
763 *dest=col1;
764 *(dest+1)=col2;
765 *(dest+2)=col3;
766 xf+=xinc;
767 if (xf<0) {
768 xf+=65536;
769 dest-=3;
770 }
771 }
772 return;
773
774 x1_inf_x2_and_y1_inf_y2:
775 /*
776 (x1, y1)
777
778
779 (x2, y2)
780 */
781 if (abs(dx)>abs(dy))
782 goto x1_inf_x2_and_y1_inf_y2_and_dx_sup_dy;
783 if (abs(dx)<abs(dy))
784 goto x1_inf_x2_and_y1_inf_y2_and_dx_inf_dy;
785 /* here dx == dy */
786 dest=d->buffer+(y1i*SCREEN_X+(x1>>16))*3;
787 for (i=y1i; i<y2i; dest+=(SCREEN_X+1)*3, i++) {
788 *dest=col1;
789 *(dest+1)=col2;
790 *(dest+2)=col3;
791 }
792 return;
793
794 x1_inf_x2_and_y1_inf_y2_and_dx_sup_dy:
795 /*
796 xxxx
797 xxxx
798 xxxx
799 */
800 yinc=muldiv(dy, 65536, dx);
801 ycur=y1+muldiv(yinc, (x1i<<16)-x1, 65536);
802 yf=ycur&65535;
803 dest=d->buffer+((ycur>>16)*SCREEN_X+x1i)*3;
804 for (i=x1i; i<x2i; i++, dest+=3) {
805 *dest=col1;
806 *(dest+1)=col2;
807 *(dest+2)=col3;
808 yf+=yinc;
809 if (yf>65535) {
810 yf-=65536;
811 dest+=SCREEN_X*3;
812 }
813 }
814 return;
815 x1_inf_x2_and_y1_inf_y2_and_dx_inf_dy:
816 /*
817 x
818 x
819 x
820 x
821 x
822 x
823 x
824 x
825 x
826 */
827 xinc=muldiv(dx, 65536, dy);
828 xcur=x1+muldiv(xinc, (y1i<<16)-y1, 65536);
829 xf=xcur&65535;
830 dest=d->buffer+(y1i*SCREEN_X+(xcur>>16))*3;
831 for (i=y1i; i<y2i; i++, dest+=SCREEN_X*3) {
832 *dest=col1;
833 *(dest+1)=col2;
834 *(dest+2)=col3;
835 xf+=xinc;
836 if (xf>65536) {
837 xf-=65536;
838 dest+=3;
839 }
840 }
841 return;
842
843 x1_sup_x2:
844 if (dy<0)
845 goto x1_sup_x2_and_y1_sup_y2;
846 if (dy>0)
847 goto x1_sup_x2_and_y1_inf_y2;
848 /* x1>x2 && y1==y2 */
849 dest=d->buffer+((y2>>16)*SCREEN_X+x2i)*3;
850 for (i=x2i; i<x1i; dest+=3, i++) {
851 *dest=col1;
852 *(dest+1)=col2;
853 *(dest+2)=col3;
854 }
855 return;
856 x1_sup_x2_and_y1_sup_y2:
857 /*
858 (x2, y2)
859
860
861 (x1, y1)
862 */
863 if (abs(dx)>abs(dy))
864 goto x1_sup_x2_and_y1_sup_y2_and_dx_sup_dy;
865 if (abs(dx)<abs(dy))
866 goto x1_sup_x2_and_y1_sup_y2_and_dx_inf_dy;
867 /* here dx == dy */
868 dest=d->buffer+(y2i*SCREEN_X+(x2>>16))*3;
869 for (i=y2i; i<y1i; dest+=(SCREEN_X+1)*3, i++) {
870 *dest=col1;
871 *(dest+1)=col2;
872 *(dest+2)=col3;
873 }
874 return;
875 x1_sup_x2_and_y1_sup_y2_and_dx_sup_dy:
876 yinc=muldiv(dy, 65536, dx);
877 ycur=y2+muldiv(yinc, (x2i<<16)-x2, 65536);
878 yf=ycur&65535;
879 dest=d->buffer+((ycur>>16)*SCREEN_X+x2i)*3;
880 for (i=x2i; i<x1i; i++, dest+=3) {
881 *dest=col1;
882 *(dest+1)=col2;
883 *(dest+2)=col3;
884 yf+=yinc;
885 if (yf>65535) {
886 yf-=65536;
887 dest+=SCREEN_X*3;
888 }
889 }
890 return;
891 x1_sup_x2_and_y1_sup_y2_and_dx_inf_dy:
892 xinc=muldiv(dx, 65536, dy);
893 xcur=x2+muldiv(xinc, (y2i<<16)-y2, 65536);
894 xf=xcur&65535;
895 dest=d->buffer+(y2i*SCREEN_X+(xcur>>16))*3;
896 for (i=y2i; i<y1i; i++, dest+=SCREEN_X*3) {
897 *dest=col1;
898 *(dest+1)=col2;
899 *(dest+2)=col3;
900 xf+=xinc;
901 if (xf>65536) {
902 xf-=65536;
903 dest+=3;
904 }
905 }
906 return;
907
908 x1_sup_x2_and_y1_inf_y2:
909 /*
910 (x1, y1)
911
912
913 (x2, y2)
914 */
915 if (abs(dx)>abs(dy))
916 goto x1_sup_x2_and_y1_inf_y2_and_dx_sup_dy;
917 if (abs(dx)<abs(dy))
918 goto x1_sup_x2_and_y1_inf_y2_and_dx_inf_dy;
919 /* here dx == dy */
920 dest=d->buffer+(y1i*SCREEN_X+(x1>>16))*3;
921 for (i=y1i; i<y2i; dest+=(SCREEN_X-1)*3, i++) {
922 *dest=col1;
923 *(dest+1)=col2;
924 *(dest+2)=col3;
925 }
926 return;
927 x1_sup_x2_and_y1_inf_y2_and_dx_sup_dy:
928 yinc=muldiv(dy, 65536, dx);
929 ycur=y1+muldiv(yinc, (x1i<<16)-x1, 65536);
930 yf=ycur&65535;
931 dest=d->buffer+((ycur>>16)*SCREEN_X+x1i)*3;
932 for (i=x1i; i>x2i; i--, dest-=3) {
933 *dest=col1;
934 *(dest+1)=col2;
935 *(dest+2)=col3;
936 yf-=yinc;
937 if (yf>65535) {
938 yf-=65536;
939 dest+=SCREEN_X*3;
940 }
941 }
942 return;
943 x1_sup_x2_and_y1_inf_y2_and_dx_inf_dy:
944 xinc=muldiv(dx, 65536, dy);
945 xcur=x1+muldiv(xinc, (y1i<<16)-y1, 65536);
946 xf=xcur&65535;
947 dest=d->buffer+(y1i*SCREEN_X+(xcur>>16))*3;
948 for (i=y1i; i<y2i; i++, dest+=SCREEN_X*3) {
949 *dest=col1;
950 *(dest+1)=col2;
951 *(dest+2)=col3;
952 xf+=xinc;
953 if (xf<0) {
954 xf+=65536;
955 dest-=3;
956 }
957 }
958 return;
959 }
960
drawline32(device * d,line * l)961 void drawline32(device *d, line *l)
962 {
963 /* lots of goto for lisibility (if if else if if else else is impossible to debug) */
964 register int x1=l->p1.x*65536.,
965 x2=l->p2.x*65536.,
966 y1=l->p1.y*65536.,
967 y2=l->p2.y*65536.;
968 register int dx, dy;
969 register int xcur;
970 register int xinc;
971 register int ycur;
972 register int yinc;
973 register int i;
974 register int y1i=(y1+65535)>>16, y2i=(y2+65535)>>16;
975 register int x1i=(x1+65535)>>16, x2i=(x2+65535)>>16;
976 /*
977 register int y1i=y1>>16, y2i=y2>>16;
978 register int x1i=x1>>16, x2i=x2>>16;
979 */
980 register unsigned int *dest;
981 register unsigned int col1=l->color;
982 register int xf;
983 register int yf;
984
985 /* in asm, those two subs are good for us, because we can test if x1<x2 and if y1<y2 at the same time, but it's C */
986 dx=x2-x1;
987 dy=y2-y1;
988
989 if (dx<0)
990 goto x1_sup_x2;
991 if (dx)
992 goto x1_inf_x2;
993
994 /* here x1==x2 */
995 if (dy<0)
996 goto x1_eq_x2_and_y1_sup_y2;
997 if (dy>0)
998 goto x1_eq_x2_and_y1_inf_y2;
999 /* here x1==x2 && y1==y2 */
1000 if (y1i<y2i) {
1001 dest=(unsigned int *)d->buffer+y1i*SCREEN_X+(x1>>16);
1002 } else {
1003 dest=(unsigned int *)d->buffer+y2i*SCREEN_X+(x1>>16);
1004 }
1005 *dest=col1;
1006 return;
1007 x1_eq_x2_and_y1_sup_y2:
1008 dest=(unsigned int *)d->buffer+y2i*SCREEN_X+(x1>>16);
1009 for (i=y2i; i<y1i; dest+=SCREEN_X, i++) {
1010 *dest=col1;
1011 }
1012 return;
1013 x1_eq_x2_and_y1_inf_y2:
1014 dest=(unsigned int *)d->buffer+y1i*SCREEN_X+(x1>>16);
1015 for (i=y1i; i<y2i; dest+=SCREEN_X, i++) {
1016 *dest=col1;
1017 }
1018 return;
1019
1020 x1_inf_x2:
1021 if (dy<0)
1022 goto x1_inf_x2_and_y1_sup_y2;
1023 if (dy>0)
1024 goto x1_inf_x2_and_y1_inf_y2;
1025 /* x1<x2 && y1==y2 */
1026 dest=(unsigned int *)d->buffer+(y1>>16)*SCREEN_X+x1i;
1027 for (i=x1i; i<x2i; dest++, i++) {
1028 *dest=col1;
1029 }
1030 return;
1031
1032 x1_inf_x2_and_y1_sup_y2:
1033 /*
1034 (x2, y2)
1035
1036
1037 (x1, y1)
1038 */
1039 /* remove those abs in the asm code */
1040 if (abs(dx)>abs(dy))
1041 goto x1_inf_x2_and_y1_sup_y2_dx_sup_dy;
1042 if (abs(dx)<abs(dy))
1043 goto x1_inf_x2_and_y1_sup_y2_dx_inf_dy;
1044 /* here dx == dy */
1045 dest=(unsigned int *)d->buffer+y2i*SCREEN_X+(x2>>16);
1046 for (i=y2i; i<y1i; dest+=SCREEN_X-1, i++) {
1047 *dest=col1;
1048 }
1049 return;
1050 x1_inf_x2_and_y1_sup_y2_dx_sup_dy:
1051 /*
1052 xxxx
1053 xxxx
1054 xxxx
1055 xxxx
1056 */
1057 yinc=muldiv(dy, 65536, dx);
1058 ycur=y2+muldiv(yinc, (x2i<<16)-x2, 65536);
1059 yf=ycur&65535;
1060 dest=(unsigned int *)d->buffer+(ycur>>16)*SCREEN_X+x2i;
1061 for (i=x2i; i>x1i; i--, dest--) {
1062 *dest=col1;
1063 yf-=yinc;
1064 if (yf>65535) {
1065 yf-=65536;
1066 dest+=SCREEN_X;
1067 }
1068 }
1069 return;
1070 x1_inf_x2_and_y1_sup_y2_dx_inf_dy:
1071 /*
1072 x
1073 x
1074 x
1075 x
1076 x
1077 x
1078 x
1079 x
1080 x
1081 */
1082 xinc=muldiv(dx, 65536, dy);
1083 xcur=x2+muldiv(xinc, (y2i<<16)-y2, 65536);
1084 xf=xcur&65535;
1085 dest=(unsigned int *)d->buffer+y2i*SCREEN_X+(xcur>>16);
1086 for (i=y2i; i<y1i; i++, dest+=SCREEN_X) {
1087 *dest=col1;
1088 xf+=xinc;
1089 if (xf<0) {
1090 xf+=65536;
1091 dest--;
1092 }
1093 }
1094 return;
1095
1096 x1_inf_x2_and_y1_inf_y2:
1097 /*
1098 (x1, y1)
1099
1100
1101 (x2, y2)
1102 */
1103 if (abs(dx)>abs(dy))
1104 goto x1_inf_x2_and_y1_inf_y2_and_dx_sup_dy;
1105 if (abs(dx)<abs(dy))
1106 goto x1_inf_x2_and_y1_inf_y2_and_dx_inf_dy;
1107 /* here dx == dy */
1108 dest=(unsigned int *)d->buffer+y1i*SCREEN_X+(x1>>16);
1109 for (i=y1i; i<y2i; dest+=SCREEN_X+1, i++) {
1110 *dest=col1;
1111 }
1112 return;
1113
1114 x1_inf_x2_and_y1_inf_y2_and_dx_sup_dy:
1115 /*
1116 xxxx
1117 xxxx
1118 xxxx
1119 */
1120 yinc=muldiv(dy, 65536, dx);
1121 ycur=y1+muldiv(yinc, (x1i<<16)-x1, 65536);
1122 yf=ycur&65535;
1123 dest=(unsigned int *)d->buffer+(ycur>>16)*SCREEN_X+x1i;
1124 for (i=x1i; i<x2i; i++, dest++) {
1125 *dest=col1;
1126 yf+=yinc;
1127 if (yf>65535) {
1128 yf-=65536;
1129 dest+=SCREEN_X;
1130 }
1131 }
1132 return;
1133 x1_inf_x2_and_y1_inf_y2_and_dx_inf_dy:
1134 /*
1135 x
1136 x
1137 x
1138 x
1139 x
1140 x
1141 x
1142 x
1143 x
1144 */
1145 xinc=muldiv(dx, 65536, dy);
1146 xcur=x1+muldiv(xinc, (y1i<<16)-y1, 65536);
1147 xf=xcur&65535;
1148 dest=(unsigned int *)d->buffer+y1i*SCREEN_X+(xcur>>16);
1149 for (i=y1i; i<y2i; i++, dest+=SCREEN_X) {
1150 *dest=col1;
1151 xf+=xinc;
1152 if (xf>65536) {
1153 xf-=65536;
1154 dest++;
1155 }
1156 }
1157 return;
1158
1159 x1_sup_x2:
1160 if (dy<0)
1161 goto x1_sup_x2_and_y1_sup_y2;
1162 if (dy>0)
1163 goto x1_sup_x2_and_y1_inf_y2;
1164 /* x1>x2 && y1==y2 */
1165 dest=(unsigned int *)d->buffer+(y2>>16)*SCREEN_X+x2i;
1166 for (i=x2i; i<x1i; dest++, i++) {
1167 *dest=col1;
1168 }
1169 return;
1170 x1_sup_x2_and_y1_sup_y2:
1171 /*
1172 (x2, y2)
1173
1174
1175 (x1, y1)
1176 */
1177 if (abs(dx)>abs(dy))
1178 goto x1_sup_x2_and_y1_sup_y2_and_dx_sup_dy;
1179 if (abs(dx)<abs(dy))
1180 goto x1_sup_x2_and_y1_sup_y2_and_dx_inf_dy;
1181 /* here dx == dy */
1182 dest=(unsigned int *)d->buffer+y2i*SCREEN_X+(x2>>16);
1183 for (i=y2i; i<y1i; dest+=SCREEN_X+1, i++) {
1184 *dest=col1;
1185 }
1186 return;
1187 x1_sup_x2_and_y1_sup_y2_and_dx_sup_dy:
1188 yinc=muldiv(dy, 65536, dx);
1189 ycur=y2+muldiv(yinc, (x2i<<16)-x2, 65536);
1190 yf=ycur&65535;
1191 dest=(unsigned int *)d->buffer+(ycur>>16)*SCREEN_X+x2i;
1192 for (i=x2i; i<x1i; i++, dest++) {
1193 *dest=col1;
1194 yf+=yinc;
1195 if (yf>65535) {
1196 yf-=65536;
1197 dest+=SCREEN_X;
1198 }
1199 }
1200 return;
1201 x1_sup_x2_and_y1_sup_y2_and_dx_inf_dy:
1202 xinc=muldiv(dx, 65536, dy);
1203 xcur=x2+muldiv(xinc, (y2i<<16)-y2, 65536);
1204 xf=xcur&65535;
1205 dest=(unsigned int *)d->buffer+y2i*SCREEN_X+(xcur>>16);
1206 for (i=y2i; i<y1i; i++, dest+=SCREEN_X) {
1207 *dest=col1;
1208 xf+=xinc;
1209 if (xf>65536) {
1210 xf-=65536;
1211 dest++;
1212 }
1213 }
1214 return;
1215
1216 x1_sup_x2_and_y1_inf_y2:
1217 /*
1218 (x1, y1)
1219
1220
1221 (x2, y2)
1222 */
1223 if (abs(dx)>abs(dy))
1224 goto x1_sup_x2_and_y1_inf_y2_and_dx_sup_dy;
1225 if (abs(dx)<abs(dy))
1226 goto x1_sup_x2_and_y1_inf_y2_and_dx_inf_dy;
1227 /* here dx == dy */
1228 dest=(unsigned int *)d->buffer+y1i*SCREEN_X+(x1>>16);
1229 for (i=y1i; i<y2i; dest+=SCREEN_X-1, i++) {
1230 *dest=col1;
1231 }
1232 return;
1233 x1_sup_x2_and_y1_inf_y2_and_dx_sup_dy:
1234 yinc=muldiv(dy, 65536, dx);
1235 ycur=y1+muldiv(yinc, (x1i<<16)-x1, 65536);
1236 yf=ycur&65535;
1237 dest=(unsigned int *)d->buffer+(ycur>>16)*SCREEN_X+x1i;
1238 for (i=x1i; i>x2i; i--, dest--) {
1239 *dest=col1;
1240 yf-=yinc;
1241 if (yf>65535) {
1242 yf-=65536;
1243 dest+=SCREEN_X;
1244 }
1245 }
1246 return;
1247 x1_sup_x2_and_y1_inf_y2_and_dx_inf_dy:
1248 xinc=muldiv(dx, 65536, dy);
1249 xcur=x1+muldiv(xinc, (y1i<<16)-y1, 65536);
1250 xf=xcur&65535;
1251 dest=(unsigned int *)d->buffer+y1i*SCREEN_X+(xcur>>16);
1252 for (i=y1i; i<y2i; i++, dest+=SCREEN_X) {
1253 *dest=col1;
1254 xf+=xinc;
1255 if (xf<0) {
1256 xf+=65536;
1257 dest--;
1258 }
1259 }
1260 return;
1261 }
1262
drawline(device * d,line * l)1263 void drawline(device *d, line *l)
1264 {
1265 #if 0
1266 void fill_left(device *, point *, point *);
1267 extern device_line *the_lines;
1268 int miny, maxy;
1269 int minx, maxx;
1270
1271 if (l->p1.y<l->p2.y) {
1272 miny=((int)(l->p1.y*65536.)+65535)>>16;
1273 maxy=((int)(l->p2.y*65536.)+65535)>>16;
1274 } else {
1275 miny=((int)(l->p2.y*65536.)+65535)>>16;
1276 maxy=((int)(l->p1.y*65536.)+65535)>>16;
1277 }
1278
1279 fill_left(d, &l->p1, &l->p2);
1280
1281 minx=the_lines[miny].x_left/65536+1;
1282 maxx=the_lines[maxy-1].x_left/65536+1;
1283
1284 if (d->depth==8) {
1285 register int i, j;
1286 register int col=l->color;
1287 register unsigned char *p=(unsigned char *)d->buffer, *q;
1288 register device_line *cur_line=&the_lines[(int)miny];
1289
1290 p+=miny*SCREEN_X;
1291
1292 if (minx<maxx) {
1293 for (i=miny; i<maxy-1; i++, p+=SCREEN_X, cur_line++) {
1294 register const int xleft=(cur_line->x_left/65536)+1;
1295 register /*const */int xright=((cur_line+1)->x_left/65536);
1296 q=p;
1297 q+=xleft;
1298 if (xleft>xright)
1299 xright++;
1300 for (j=xleft; j<=xright /*cur_line->x_right*/; j++, q++)
1301 *q=col;
1302 }
1303 } else {
1304 for (i=miny; i<maxy-1; i++, p+=SCREEN_X, cur_line++) {
1305 register /*const */int xright=(cur_line->x_left/65536)+1;
1306 register const int xleft=(cur_line+1)->x_left/65536;
1307 q=p;
1308 q+=xleft;
1309 if (xleft>xright)
1310 xright++;
1311 for (j=xleft; j<=xright /*cur_line->x_right*/; j++, q++)
1312 *q=col;
1313 }
1314 }
1315 } else
1316 drawline16(d, l);
1317 #endif
1318 if (d->depth==8)
1319 drawline8(d, l);
1320 else if (d->depth==16)
1321 drawline16(d, l);
1322 else if (d->depth==24)
1323 drawline24(d, l);
1324 else if (d->depth==32)
1325 drawline32(d, l);
1326 }
1327
1328 #define LEFT 1
1329 #define RIGHT 2
1330 #define UP 4
1331 #define DOWN 8
1332
copy_point(point * dest,point * src)1333 static inline void copy_point(point *dest, point *src)
1334 {
1335 /* this one is useless, take it away !!! */
1336 memcpy(dest, src, sizeof(point));
1337 }
1338
do_clip_left(point * res,point * p1,point * p2)1339 static inline void do_clip_left(point *res, point *p1, point *p2)
1340 {
1341 register double factor=p2->x/(p2->x-p1->x);
1342 res->x=0;
1343 res->y=p2->y-(p2->y-p1->y)*factor;
1344 }
1345
do_clip_right(point * res,point * p1,point * p2)1346 static inline void do_clip_right(point *res, point *p1, point *p2)
1347 {
1348 register double factor=(p2->x-SCREEN_X+2)/(p2->x-p1->x);
1349 res->x=SCREEN_X-2;
1350 res->y=p2->y-(p2->y-p1->y)*factor;
1351 }
1352
do_clip_up(point * res,point * p1,point * p2)1353 static inline void do_clip_up(point *res, point *p1, point *p2)
1354 {
1355 register double factor=p2->y/(p2->y-p1->y);
1356 res->x=p2->x-(p2->x-p1->x)*factor;
1357 res->y=0;
1358 }
1359
do_clip_down(point * res,point * p1,point * p2)1360 static inline void do_clip_down(point *res, point *p1, point *p2)
1361 {
1362 register double factor=(p2->y-(SCREEN_Y-2))/(p2->y-p1->y);
1363 res->x=p2->x-(p2->x-p1->x)*factor;
1364 res->y=SCREEN_Y-2;
1365 }
1366
clip_and_draw_line(device * d,line * l)1367 void clip_and_draw_line(device *d, line *l)
1368 {
1369 register int clip=0;
1370 register double a, b;
1371 register point *pp, *pp1;
1372 point next;
1373
1374 /* step 1 - do we clip ? */
1375 a=l->p1.x;
1376 b=l->p1.y;
1377 if (a<0)
1378 clip|=LEFT;
1379 if (a>SCREEN_X-2)
1380 clip|=RIGHT;
1381 if (b<0)
1382 clip|=UP;
1383 if (b>SCREEN_Y-2)
1384 clip|=DOWN;
1385 a=l->p2.x;
1386 b=l->p2.y;
1387 if (a<0)
1388 clip|=LEFT;
1389 if (a>SCREEN_X-2)
1390 clip|=RIGHT;
1391 if (b<0)
1392 clip|=UP;
1393 if (b>SCREEN_Y-2)
1394 clip|=DOWN;
1395
1396 pp=&l->p1;
1397 pp1=&l->p2;
1398
1399 /* step 2 - clip left ? */
1400 if (!(clip&LEFT))
1401 goto no_left;
1402 if (pp->x>0 && pp1->x<0) {
1403 do_clip_left(&next, pp, pp1);
1404 copy_point(pp1, &next);
1405 } else if (pp->x<0 && pp1->x>0) {
1406 do_clip_left(&next, pp, pp1);
1407 copy_point(pp, &next);
1408 }
1409
1410 no_left:
1411 /* step 3 - right ? */
1412 if (!(clip&RIGHT))
1413 goto no_right;
1414 if (pp->x<SCREEN_X-2 && pp1->x>SCREEN_X-2) {
1415 do_clip_right(&next, pp, pp1);
1416 copy_point(pp1, &next);
1417 } else if (pp->x>SCREEN_X-2 && pp1->x<SCREEN_X-2) {
1418 do_clip_right(&next, pp, pp1);
1419 copy_point(pp, &next);
1420 }
1421
1422 no_right:
1423 /* step 4 - up ? */
1424 if (!(clip&UP))
1425 goto no_up;
1426 if (pp->y>0 && pp1->y<0) {
1427 do_clip_up(&next, pp, pp1);
1428 copy_point(pp1, &next);
1429 } else if (pp->y<0 && pp1->y>0) {
1430 do_clip_up(&next, pp, pp1);
1431 copy_point(pp, &next);
1432 }
1433
1434 no_up:
1435 /* step 5 - down ? */
1436 if (!(clip&DOWN))
1437 goto no_down;
1438 if (pp->y<SCREEN_Y-2 && pp1->y>SCREEN_Y-2) {
1439 do_clip_down(&next, pp, pp1);
1440 copy_point(pp1, &next);
1441 } else if (pp->y>SCREEN_Y-2 && pp1->y<SCREEN_Y-2) {
1442 do_clip_down(&next, pp, pp1);
1443 copy_point(pp, &next);
1444 }
1445
1446 no_down:
1447 /* step 6 - draw the resulting line (clipping may have outed it all, so let's test it) */
1448 if (pp->x>=0 && pp->x<=SCREEN_X-2 && pp->y>=0 && pp->y<=SCREEN_Y-2
1449 && pp1->x>=0 && pp1->x<=SCREEN_X-2 && pp1->y>=0 && pp1->y<=SCREEN_Y-2)
1450 drawline(d, l);
1451 #if 0
1452 else
1453 fprintf(stderr, "clip=%d p1=%f %f, p2=%f %f\n", clip, pp->x, pp->y, pp1->x, pp1->y);
1454 #endif
1455 }
1456