1 /*
2 * SDL_prim.c
3 *
4 * Copyright (C) 2003-2005 Ryan McGuigan <ryan@tempestgames.com>
5 *
6 * See the included 'COPYING' file for license information.
7 *
8 * Simple SDL Primitive C functions. My goal while writing this
9 * was to keep everything as simple as possible, both in the design
10 * of these functions and in the usage of these functions.
11 *
12 * I hope someone finds this useful.
13 *
14 * Adapted to compile without warning on g++ -W -Wall -O2 by tdd@insia.org
15 * (20050413)
16 *
17 */
18
19
20 #include "SDL_prim.h"
21
22
23 /*
24 * simple pixel drawing function.
25 *
26 * tests to be sure pixel is within bounds of the surface, so you
27 * can draw off the surface to your hearts content
28 *
29 * it's probably not good practice to be drawing off the surface though...
30 *
31 */
32 inline
SDL_putPixel(SDL_Surface * surf,int x,int y,Uint32 clr)33 void SDL_putPixel(SDL_Surface *surf, int x, int y, Uint32 clr)
34 {
35 int Bpp = surf->format->BytesPerPixel;
36 Uint8 *p;
37
38 if (! (x < 0 || x >= surf->w || y < 0 || y >= surf->h) )
39 {
40 p = (Uint8*)surf->pixels + y * surf->pitch + x * Bpp;
41
42 switch(Bpp) {
43 case 1:
44 *p = clr;
45 break;
46
47 case 2:
48 *(Uint16*)p = clr;
49 break;
50
51 case 3:
52 if (SDL_BYTEORDER == SDL_BIG_ENDIAN) {
53 p[0] = (clr >> 16) & 0xff;
54 p[1] = (clr >> 8) & 0xff;
55 p[2] = clr & 0xff;
56 } else {
57 p[0] = clr & 0xff;
58 p[1] = (clr >> 8) & 0xff;
59 p[2] = (clr >> 16) & 0xff;
60 }
61 break;
62
63 case 4:
64 *(Uint32*)p = clr;
65 break;
66 }
67 }
68 }
69
70
71 /*
72 * returns pointer to pixel at x, y
73 */
74 inline
SDL_getPixel(SDL_Surface * surf,int x,int y)75 Uint8* SDL_getPixel(SDL_Surface *surf, int x, int y)
76 {
77 if (! (x < 0 || x >= surf->w || y < 0 || y >= surf->h) )
78 return (Uint8*)surf->pixels + y * surf->pitch + x * surf->format->BytesPerPixel;
79 else
80 return 0;
81 }
82
83
84 /*
85 * slow pixel blending function
86 *
87 * called from SDL_blendPixel for 8 bit surfaces.
88 * may be useful for something else, I dunno.
89 *
90 */
91 inline
__slow_SDL_blendPixel(SDL_Surface * surf,int x,int y,Uint32 clr,Uint8 alpha)92 void __slow_SDL_blendPixel( SDL_Surface *surf, int x, int y, Uint32 clr,
93 Uint8 alpha)
94 {
95 Uint8 *p;
96 Uint8 r, g, b, r2, g2, b2;
97
98 if ( (p = SDL_getPixel(surf, x, y)) ) {
99 SDL_GetRGB(clr, surf->format, &r, &g, &b);
100 SDL_GetRGB(*p, surf->format, &r2, &g2, &b2);
101
102 /* The 3 following lines use explicit cast now - tdd */
103 r = r2 + (int) (( r - r2 ) * ( alpha / 255.0 ));
104 g = g2 + (int) (( g - g2 ) * ( alpha / 255.0 ));
105 b = b2 + (int) (( b - b2 ) * ( alpha / 255.0 ));
106
107 clr = SDL_MapRGB(surf->format, r, g, b);
108
109 SDL_putPixel(surf, x, y, clr);
110 }
111 }
112
113
114 /*
115 * blends pixel onto surface according to alpha
116 */
117 inline
SDL_blendPixel(SDL_Surface * surf,int x,int y,Uint32 clr,Uint8 alpha)118 void SDL_blendPixel( SDL_Surface *surf, int x, int y, Uint32 clr,
119 Uint8 alpha)
120 {
121 Uint8 *p;
122 Uint32 R, G, B;
123
124 if ( (p = SDL_getPixel(surf, x, y)) ) {
125 switch(surf->format->BytesPerPixel) {
126 case 1: /* 8 bpp */
127 __slow_SDL_blendPixel(surf, x, y, clr, alpha);
128 break;
129
130 case 2: /* 16 bpp */
131 R = ( (*(Uint16*)p & surf->format->Rmask) + ( ((clr & surf->format->Rmask) - ((*(Uint16*)p) & surf->format->Rmask)) * alpha >> 8) ) & surf->format->Rmask;
132 G = ( (*(Uint16*)p & surf->format->Gmask) + ( ((clr & surf->format->Gmask) - ((*(Uint16*)p) & surf->format->Gmask)) * alpha >> 8) ) & surf->format->Gmask;
133 B = ( (*(Uint16*)p & surf->format->Bmask) + ( ((clr & surf->format->Bmask) - ((*(Uint16*)p) & surf->format->Bmask)) * alpha >> 8) ) & surf->format->Bmask;
134 *(Uint16*)p = R | G | B;
135 break;
136
137 case 3: /* 24 bpp */
138 if (SDL_BYTEORDER == SDL_BIG_ENDIAN) {
139 p[0] = ( p[0] + ((((clr >> 16) & 0xff) - p[0]) * alpha >> 8) ) & 0xff;
140 p[1] = ( p[1] + ((((clr >> 8) & 0xff) - p[1]) * alpha >> 8) ) & 0xff;
141 p[2] = ( p[2] + (((clr & 0xff) - p[2]) * alpha >> 8) ) & 0xff;
142 } else {
143 p[0] = ( p[0] + (((clr & 0xff) - p[0]) * alpha >> 8) ) & 0xff;
144 p[1] = ( p[1] + ((((clr >> 8) & 0xff) - p[1]) * alpha >> 8) ) & 0xff;
145 p[2] = ( p[2] + ((((clr >> 16) & 0xff) - p[2]) * alpha >> 8) ) & 0xff;
146 }
147 break;
148
149 case 4: /* 32 bpp */
150 R = ( (*(Uint32*)p & surf->format->Rmask) + ( ((clr & surf->format->Rmask) - (*(Uint32*)p & surf->format->Rmask)) * alpha >> 8) ) & surf->format->Rmask;
151 G = ( (*(Uint32*)p & surf->format->Gmask) + ( ((clr & surf->format->Gmask) - (*(Uint32*)p & surf->format->Gmask)) * alpha >> 8) ) & surf->format->Gmask;
152 B = ( (*(Uint32*)p & surf->format->Bmask) + ( ((clr & surf->format->Bmask) - (*(Uint32*)p & surf->format->Bmask)) * alpha >> 8) ) & surf->format->Bmask;
153 *(Uint32*)p = R | G | B;
154 break;
155 }
156 }
157 }
158
159
160 /*
161 * Self explanatory. draws lines, supports anti-aliasing and
162 * alpha blending
163 *
164 */
SDL_drawLine_TG(SDL_Surface * surf,int x,int y,int x2,int y2,Uint32 clr,Uint8 alpha,Uint8 flags)165 void SDL_drawLine_TG( SDL_Surface *surf, int x, int y, int x2, int y2,
166 Uint32 clr, Uint8 alpha, Uint8 flags )
167 {
168 int xaa, yaa, *a, *b, *a2, *b2, da, xd, yd;
169 float aa, db;
170 float realb;
171
172 /*
173 * for the sake of my sanity when i look at this again...
174 *
175 * xaa: the x aa offset value, either 1 or 0
176 * yaa: the y aa offset value, either 1 or 0
177 * *a: reference to either x or y, depending on which way we are
178 * drawing.
179 * *b: reference to either x or y, depending on which way we are
180 * drawing.
181 * *a2: reference to either x2 or y2, depending on which way we are
182 * drawing.
183 * *b2: reference to either x2 or y2, depending on which way we are
184 * drawing.
185 * x: starting x value, current x value
186 * y: starting y value, current y value
187 * x2: ending x value
188 * y2: ending y value
189 * xd: distance from x to x2
190 * yd: distance from y to y2
191 * da: change in a for each iteration, either 1 or -1
192 * db: change in b with respect to a
193 * realb: real b value, as b is an int, and db is going to be a
194 * fraction
195 * aa: anti-aliasing value, fraction part of realb
196 *
197 */
198
199 /* find x and y distances */
200 xd = x2 - x;
201 yd = y2 - y;
202
203 if (abs(xd) >= abs(yd)) {
204 /* draw left/right to left/right */
205 xaa = 0;
206 yaa = 1;
207 a = &x;
208 b = &y;
209 a2 = &x2;
210 b2 = &y2;
211 db = (float)yd / xd;
212 } else {
213 /* draw top/bottom to top/bottom */
214 xaa = 1;
215 yaa = 0;
216 a = &y;
217 b = &x;
218 a2 = &y2;
219 b2 = &x2;
220 db = (float)xd / yd;
221 }
222
223 if (!(alpha < 255 && (flags & SDL_TG_ALPHA)))
224 alpha = 255;
225
226 /* left or right? */
227 da = (*a <= *a2) ? 1 : -1;
228 /* up or down? */
229 db *= da;
230 /* init realb */
231 realb = (float)*b;
232 /* we're stopping when we hit *a2, so we have to add +/-1 to it */
233 *a2 += da;
234
235 if (flags & SDL_TG_LOCK)
236 __SDL_PRIM_LOCKSURFACE(surf)
237
238 for (; *a != *a2; *a += da) {
239 /* Explicit cast now - tdd */
240 *b = (int) floor(realb + 0.5);
241
242 if (flags & SDL_TG_ANTIALIAS) {
243 aa = (realb + 0.5 - *b) * alpha;
244 SDL_blendPixel(surf, x + xaa, y + yaa, clr, (int)aa);
245 SDL_blendPixel(surf, x - xaa, y - yaa, clr, alpha - (int)aa);
246 }
247
248 if (alpha < 255)
249 SDL_blendPixel(surf, x, y, clr, alpha);
250 else
251 SDL_putPixel(surf, x, y, clr);
252
253 realb += db;
254 }
255
256 if (flags & SDL_TG_LOCK)
257 __SDL_PRIM_UNLOCKSURFACE(surf)
258 }
259
260
261
262 /*
263 * Circle drawing/filling function. Uses a more optimized algorithm
264 * when drawing non-anti-aliased circles, uses a mathematically correct algo
265 * when drawing anti-aliased circles. After much trial and error, I have
266 * removed 100% of pixel overlapping, no more spots in anti-aliased circles.
267 *
268 */
SDL_drawCircle_TG(SDL_Surface * surf,int x1,int y1,int r,Uint32 clr,Uint8 alpha,Uint8 flags)269 void SDL_drawCircle_TG( SDL_Surface *surf, int x1, int y1, int r, Uint32 clr,
270 Uint8 alpha, Uint8 flags )
271 {
272 int x = 0, tmp, dy = 0, y = r, r2, aa = 0, fy = 0;
273 int r2p = r * r;
274 float aatmp;
275
276 # define __CIRCLE_OUTAA \
277 { \
278 if (x) { \
279 SDL_blendPixel(surf, x1 + x, y1 + y + 1, clr, aa); \
280 SDL_blendPixel(surf, x1 + x, y1 - y - 1, clr, aa); \
281 } \
282 SDL_blendPixel(surf, x1 - x, y1 + y + 1, clr, aa); \
283 SDL_blendPixel(surf, x1 - x, y1 - y - 1, clr, aa); \
284 }
285
286 # define __CIRCLE_INAA \
287 { \
288 if (x) { \
289 SDL_blendPixel(surf, x1 + x, y1 + y - 1, clr, alpha - aa); \
290 SDL_blendPixel(surf, x1 + x, y1 - y + 1, clr, alpha - aa); \
291 } \
292 SDL_blendPixel(surf, x1 - x, y1 + y - 1, clr, alpha - aa); \
293 SDL_blendPixel(surf, x1 - x, y1 - y + 1, clr, alpha - aa); \
294 }
295
296 # define __CIRCLE_OUTAA_ROT90 \
297 { \
298 if (x) { \
299 SDL_blendPixel(surf, x1 + y + 1, y1 + x, clr, aa); \
300 SDL_blendPixel(surf, x1 - y - 1, y1 - x, clr, aa); \
301 } \
302 SDL_blendPixel(surf, x1 - y - 1, y1 + x, clr, aa); \
303 SDL_blendPixel(surf, x1 + y + 1, y1 - x, clr, aa); \
304 }
305
306 # define __CIRCLE_INAA_ROT90 \
307 { \
308 if (x) { \
309 SDL_blendPixel(surf, x1 + y - 1, y1 + x, clr, alpha - aa); \
310 SDL_blendPixel(surf, x1 - y + 1, y1 - x, clr, alpha - aa); \
311 } \
312 SDL_blendPixel(surf, x1 - y + 1, y1 + x, clr, alpha - aa); \
313 SDL_blendPixel(surf, x1 + y - 1, y1 - x, clr, alpha - aa); \
314 }
315
316 # define __CIRCLE_BLEND \
317 { \
318 if (x) { \
319 SDL_blendPixel(surf, x1 + x, y1 + y, clr, alpha); \
320 SDL_blendPixel(surf, x1 + x, y1 - y, clr, alpha); \
321 } \
322 SDL_blendPixel(surf, x1 - x, y1 + y, clr, alpha); \
323 SDL_blendPixel(surf, x1 - x, y1 - y, clr, alpha); \
324 }
325
326 # define __CIRCLE_BLEND_ROT90 \
327 { \
328 if (x) { \
329 SDL_blendPixel(surf, x1 - y, y1 + x, clr, alpha); \
330 SDL_blendPixel(surf, x1 + y, y1 + x, clr, alpha); \
331 } \
332 SDL_blendPixel(surf, x1 + y, y1 - x, clr, alpha); \
333 SDL_blendPixel(surf, x1 - y, y1 - x, clr, alpha); \
334 }
335
336 # define __CIRCLE_DRAW \
337 { \
338 if (x) { \
339 SDL_putPixel(surf, x1 + x, y1 + y, clr); \
340 SDL_putPixel(surf, x1 + x, y1 - y, clr); \
341 } \
342 SDL_putPixel(surf, x1 - x, y1 + y, clr); \
343 SDL_putPixel(surf, x1 - x, y1 - y, clr); \
344 }
345
346 # define __CIRCLE_DRAW_ROT90 \
347 { \
348 if (x) { \
349 SDL_putPixel(surf, x1 - y, y1 + x, clr); \
350 SDL_putPixel(surf, x1 + y, y1 + x, clr); \
351 } \
352 SDL_putPixel(surf, x1 + y, y1 - x, clr); \
353 SDL_putPixel(surf, x1 - y, y1 - x, clr); \
354 }
355
356 if (!(alpha < 255 && (flags & SDL_TG_ALPHA)))
357 alpha = 255;
358
359 if (r < 6)
360 r2 = 0;
361 else
362 r2 = r / 2;
363
364 if (flags & SDL_TG_LOCK)
365 __SDL_PRIM_LOCKSURFACE(surf)
366
367 if (flags & SDL_TG_FILL) {
368 if (alpha < 255)
369 SDL_blendPixel(surf, x1, y1, clr, alpha);
370 else
371 SDL_putPixel(surf, x1, y1, clr);
372 }
373
374 do {
375 if (alpha < 255) {
376 __CIRCLE_BLEND
377 __CIRCLE_BLEND_ROT90
378 } else {
379 __CIRCLE_DRAW
380 __CIRCLE_DRAW_ROT90
381 }
382
383 if (flags & SDL_TG_FILL) {
384 /* Fill the circle... */
385 if (alpha < 255) {
386 for (fy = y - 1; fy >= (x ? x : 1); fy--) {
387 if (x) {
388 SDL_blendPixel(surf, x1 - x, y1 + fy, clr, alpha);
389 SDL_blendPixel(surf, x1 - x, y1 - fy, clr, alpha);
390 }
391 SDL_blendPixel(surf, x1 + x, y1 + fy, clr, alpha);
392 SDL_blendPixel(surf, x1 + x, y1 - fy, clr, alpha);
393
394 if (fy > x) {
395 if (x) {
396 SDL_blendPixel(surf, x1 - fy, y1 + x, clr, alpha);
397 SDL_blendPixel(surf, x1 + fy, y1 + x, clr, alpha);
398 }
399 SDL_blendPixel(surf, x1 - fy, y1 - x, clr, alpha);
400 SDL_blendPixel(surf, x1 + fy, y1 - x, clr, alpha);
401 }
402 }
403 } else {
404 for (fy = y - 1; fy >= (x ? x : 1); fy--) {
405 if (x) {
406 SDL_putPixel(surf, x1 - x, y1 + fy, clr);
407 SDL_putPixel(surf, x1 - x, y1 - fy, clr);
408 }
409 SDL_putPixel(surf, x1 + x, y1 + fy, clr);
410 SDL_putPixel(surf, x1 + x, y1 - fy, clr);
411
412 if (fy > x) {
413 if (x) {
414 SDL_putPixel(surf, x1 - fy, y1 + x, clr);
415 SDL_putPixel(surf, x1 + fy, y1 + x, clr);
416 }
417 SDL_putPixel(surf, x1 - fy, y1 - x, clr);
418 SDL_putPixel(surf, x1 + fy, y1 - x, clr);
419 }
420 }
421 }
422 }
423
424 if (flags & SDL_TG_ANTIALIAS) {
425 /*
426 * anti-aliased circle algorithm. this is
427 * mathematically correct, but fairly expensive.
428 * looks extremely good though.
429 *
430 * this is also very simple, we simply find the y
431 * value with respect to each x value, using a circle
432 * equation. the anti-alias values are based on the
433 * real y coordinates.
434 */
435 __CIRCLE_OUTAA
436 __CIRCLE_OUTAA_ROT90
437 if (!(flags & SDL_TG_FILL)) {
438 __CIRCLE_INAA
439 if (x < y-1)
440 __CIRCLE_INAA_ROT90
441 }
442
443 aatmp = sqrt((float)r2p - x*x);
444 /* Explicit cast now - tdd */
445 y = (int) aatmp;
446 aatmp = aatmp - (int)aatmp;
447 /* Explicit cast now - tdd */
448 aa = (int) (aatmp * alpha);
449 x++;
450 } else {
451 /*
452 * i came up with this circle drawing algorithm on my
453 * own. i don't know how it compares to other circle
454 * drawing algos as far as optimization, but this seems
455 * to work pretty well. it's also pretty damn
456 * simple, which is what i'm all about.
457 */
458
459 /* move along x axis */
460 x++;
461
462 /*
463 * adjust y if we're moving too far out of the circle.
464 * the r2 is simply the radius over 2, unless the
465 * radius is less than a particular value(above).
466 * this simply makes the circle look more accurate,
467 * as we're working with integers so it's never exact,
468 * and we don't want to change the y value unless we're
469 * going off by a particular amount. this also more
470 * closely approximates the above, mathematically
471 * correct, algo.
472 */
473 if (dy)
474 y += dy;
475 tmp = (r2p - x*x - y*y + r2);
476 if (tmp < 0)
477 dy = -1;
478 else if (dy)
479 dy = 0;
480 }
481 } while (x < y);
482
483 if (x == y) {
484 if (alpha < 255)
485 __CIRCLE_BLEND
486 else
487 __CIRCLE_DRAW
488
489 if (flags & SDL_TG_ANTIALIAS) {
490 __CIRCLE_OUTAA
491 __CIRCLE_OUTAA_ROT90
492 }
493 }
494 else if (flags & SDL_TG_ANTIALIAS)
495 __CIRCLE_OUTAA
496
497 if (flags & SDL_TG_LOCK)
498 __SDL_PRIM_UNLOCKSURFACE(surf)
499 }
500
501
502 /*
503 * draws triangles
504 *
505 * this isn't very good, there is a good amount of pixel overlapping,
506 * and there are sometimes pixels dangling off the corners...
507 *
508 * bleh, fuck it, i'll fix it later
509 *
510 */
SDL_drawTriangle_TG(SDL_Surface * surf,int x1,int y1,int x2,int y2,int x3,int y3,Uint32 clr,Uint8 alpha,Uint8 flags)511 void SDL_drawTriangle_TG(SDL_Surface *surf, int x1, int y1, int x2, int y2,
512 int x3, int y3, Uint32 clr, Uint8 alpha, Uint8 flags)
513 {
514 int x, y, c, xlen, ylen, i, aaoffset;
515 float a1, b1, a2, b2, slopea, slopeb, aa, aastep, pb1, pb2;
516 float slope1, slope2, slope3;
517
518 /* avoid compiler warnings... */
519 aa = 0.0;
520 aastep = 0.0;
521 aaoffset = 0;
522
523 # define __TRI_DRAW(PB, B, SLOPE) \
524 { \
525 if (fabs(SLOPE) > 1.0) { \
526 c = (PB) > (B) ? -1 : 1; \
527 if (flags & SDL_TG_ANTIALIAS) { \
528 aastep = alpha / fabs(SLOPE); \
529 aa = alpha; \
530 } \
531 /* Explicit cast now - tdd */ \
532 for (y = (int) (PB); ( c > 0 ? y < floor(B) : y > (B) ); y += c) { \
533 if (alpha < 255) \
534 SDL_blendPixel(surf, x, y, clr, alpha); \
535 else \
536 SDL_putPixel(surf, x, y, clr); \
537 if (flags & SDL_TG_ANTIALIAS) { \
538 SDL_blendPixel(surf, x - 1, y, clr, (int)aa); \
539 SDL_blendPixel(surf, x + 1, y, clr, (int)(alpha - aa)); \
540 aa -= aastep; \
541 } \
542 } \
543 } else { \
544 if (alpha < 255) \
545 SDL_blendPixel(surf, x, (int)(B), clr, (int)alpha); \
546 else \
547 SDL_putPixel(surf, x, (int)(B), clr); \
548 if (flags & SDL_TG_ANTIALIAS) { \
549 aa = (B) - (int)(B); \
550 aa *= alpha; \
551 SDL_blendPixel(surf, x, (int)(B) + 1, clr, (int)aa); \
552 SDL_blendPixel(surf, x, (int)(B) - 1, clr, (int)(alpha - aa)); \
553 } \
554 } \
555 }
556
557 # define __TRI_FILL_AA(PB, B, B2, SLOPE) \
558 { \
559 if (fabs(SLOPE) > 2.0) { \
560 c = (SLOPE > 0) ? 1 : -1; \
561 if (SLOPE > 0) { \
562 if (SLOPE == slope3) { \
563 aaoffset = 0; \
564 aa = 0; \
565 aastep = alpha / SLOPE; \
566 } \
567 else { \
568 aaoffset = -1; \
569 aa = alpha; \
570 aastep = alpha / SLOPE * -1; \
571 } \
572 } \
573 else { \
574 if (SLOPE == slope3) { \
575 aaoffset = 0; \
576 aa = 0; \
577 aastep = alpha / SLOPE * -1; \
578 } \
579 else { \
580 aaoffset = -1; \
581 aa = alpha; \
582 aastep = alpha / SLOPE; \
583 } \
584 } \
585 /* Explicit cast now - tdd */ \
586 for (y = (int) ((PB) + c); ( c > 0 ? y < floor(B) : y > (B) ); y += c) { \
587 SDL_blendPixel(surf, x + aaoffset, y, clr, (int)aa); \
588 aa += aastep; \
589 } \
590 } else { \
591 if (B > B2) \
592 c = 1; \
593 else \
594 c = -1; \
595 aa = fabs( (B) - (int)(B) ); \
596 if (c < 0) \
597 aa = alpha - aa * alpha; \
598 else \
599 aa *= alpha; \
600 /* Explicit cast now - tdd */ \
601 SDL_blendPixel(surf, x, (int) ((B) + c), clr, (int)aa); \
602 } \
603 }
604
605 if ( !(flags & SDL_TG_ALPHA && alpha < 255) )
606 alpha = 255;
607
608 /*
609 * sort points by X coordinate so we can split the drawing
610 * at a slope change
611 */
612 while ( !(x1 <= x2 && x1 <= x3) ) {
613 x = x1;
614 y = y1;
615 x1 = x2;
616 y1 = y2;
617 x2 = x3;
618 y2 = y3;
619 x3 = x;
620 y3 = y;
621 }
622 while ( !(x2 <= x3) ) {
623 x = x2;
624 y = y2;
625 x2 = x3;
626 y2 = y3;
627 x3 = x;
628 y3 = y;
629 }
630
631 xlen = x3 - x1;
632 ylen = y3 - y1;
633 slope1 = (float)ylen / xlen;
634
635 xlen = x1 - x2;
636 ylen = y1 - y2;
637 slope2 = (float)ylen / xlen;
638
639 xlen = x2 - x3;
640 ylen = y2 - y3;
641 slope3 = (float)ylen / xlen;
642
643 a1 = x1;
644 a2 = x2;
645 b1 = y1;
646 b2 = y1;
647 slopea = slope1;
648 slopeb = slope2;
649
650 pb1 = b1;
651 pb2 = b2;
652
653 if (flags & SDL_TG_LOCK)
654 __SDL_PRIM_LOCKSURFACE(surf)
655
656 for (i = 0; i <= 1; i++) {
657 if ((a1 == x1 && a1 != a2) || (a1 != x1 && a1 - 1 != a2)) {
658 /* Explicit cast now - tdd */
659 for (x = (int) a1; x <= a2; x++) {
660 if (flags & SDL_TG_FILL) {
661 c = ((int)b1 < (int)b2) ? 1 : -1;
662 for (y = (int)b1; (c > 0 ? y <= (int)b2 : y >= (int)b2); y += c) {
663 if (alpha < 255)
664 SDL_blendPixel(surf, x, y, clr, alpha);
665 else
666 SDL_putPixel(surf, x, y, clr);
667 }
668 if (flags & SDL_TG_ANTIALIAS) {
669 __TRI_FILL_AA(pb1, b1, b2, slopea)
670 __TRI_FILL_AA(pb2, b2, b1, slopeb)
671 }
672 }
673 else {
674 __TRI_DRAW(pb1, b1, slopea)
675 __TRI_DRAW(pb2, b2, slopeb)
676 }
677 pb1 = b1;
678 pb2 = b2;
679
680 b1 += slopea;
681 b2 += slopeb;
682 }
683 } else if (!(flags & SDL_TG_FILL)) {
684 if (a1 == x1)
685 SDL_drawLine_TG(surf, x1,y1, x2,y2, clr, alpha, flags);
686 else
687 SDL_drawLine_TG(surf, x2,y2, x3,y3, clr, alpha, flags);
688 }
689
690 a1 = x2 + 1;
691 a2 = x3;
692 b2 = y2;
693 slopeb = slope3;
694 b2 += slopeb;
695 }
696
697 if (flags & SDL_TG_LOCK)
698 __SDL_PRIM_UNLOCKSURFACE(surf)
699 }
700
701
702