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