1 /*
2
3 SDL_gfxPrimitives - Graphics primitives for SDL surfaces
4
5 Note: Does not lock or update surfaces. Implement in calling routine.
6
7 */
8
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <math.h>
12 #include <string.h>
13
14 #include <SDL.h>
15
16 #include "SDL_gfxPrimitives.h"
17 #include "SDL_gfxPrimitives_font.h"
18
19 /* -===================- */
20
21 /* Define this flag to use surface blits for alpha blended drawing. */
22 /* This is usually slower that direct surface calculations. */
23
24 #undef SURFACE_ALPHA_PIXEL
25
26 /* ----- Defines for pixel clipping tests */
27
28 #define clip_xmin(surface) surface->clip_rect.x
29 #define clip_xmax(surface) surface->clip_rect.x+surface->clip_rect.w-1
30 #define clip_ymin(surface) surface->clip_rect.y
31 #define clip_ymax(surface) surface->clip_rect.y+surface->clip_rect.h-1
32
33 /* ----- Pixel - fast, no blending, no locking, clipping */
34
fastPixelColorNolock(SDL_Surface * dst,Sint16 x,Sint16 y,Uint32 color)35 int fastPixelColorNolock (SDL_Surface *dst, Sint16 x, Sint16 y, Uint32 color)
36 {
37 int bpp;
38 Uint8 *p;
39
40 /* Honor clipping setup at pixel level */
41 if ( (x >= clip_xmin(dst)) &&
42 (x <= clip_xmax(dst)) &&
43 (y >= clip_ymin(dst)) &&
44 (y <= clip_ymax(dst)) ) {
45
46 /* Get destination format */
47 bpp = dst->format->BytesPerPixel;
48 p = (Uint8 *)dst->pixels + y * dst->pitch + x * bpp;
49 switch(bpp) {
50 case 1:
51 *p = color;
52 break;
53 case 2:
54 *(Uint16 *)p = color;
55 break;
56 case 3:
57 if(SDL_BYTEORDER == SDL_BIG_ENDIAN) {
58 p[0] = (color >> 16) & 0xff;
59 p[1] = (color >> 8) & 0xff;
60 p[2] = color & 0xff;
61 } else {
62 p[0] = color & 0xff;
63 p[1] = (color >> 8) & 0xff;
64 p[2] = (color >> 16) & 0xff;
65 }
66 break;
67 case 4:
68 *(Uint32 *)p = color;
69 break;
70 } /* switch */
71
72
73 }
74
75 return(0);
76 }
77
78 /* ----- Pixel - fast, no blending, no locking, no clipping */
79
80 /* (faster but dangerous, make sure we stay in surface bounds) */
81
fastPixelColorNolockNoclip(SDL_Surface * dst,Sint16 x,Sint16 y,Uint32 color)82 int fastPixelColorNolockNoclip (SDL_Surface *dst, Sint16 x, Sint16 y, Uint32 color)
83 {
84 int bpp;
85 Uint8 *p;
86
87 /* Get destination format */
88 bpp = dst->format->BytesPerPixel;
89 p = (Uint8 *)dst->pixels + y * dst->pitch + x * bpp;
90 switch(bpp) {
91 case 1:
92 *p = color;
93 break;
94 case 2:
95 *(Uint16 *)p = color;
96 break;
97 case 3:
98 if(SDL_BYTEORDER == SDL_BIG_ENDIAN) {
99 p[0] = (color >> 16) & 0xff;
100 p[1] = (color >> 8) & 0xff;
101 p[2] = color & 0xff;
102 } else {
103 p[0] = color & 0xff;
104 p[1] = (color >> 8) & 0xff;
105 p[2] = (color >> 16) & 0xff;
106 }
107 break;
108 case 4:
109 *(Uint32 *)p = color;
110 break;
111 } /* switch */
112
113 return(0);
114 }
115
116 /* ----- Pixel - fast, no blending, locking, clipping */
117
fastPixelColor(SDL_Surface * dst,Sint16 x,Sint16 y,Uint32 color)118 int fastPixelColor (SDL_Surface *dst, Sint16 x, Sint16 y, Uint32 color)
119 {
120 int result;
121
122 /* Lock the surface */
123 if ( SDL_MUSTLOCK(dst) ) {
124 if ( SDL_LockSurface(dst) < 0 ) {
125 return(-1);
126 }
127 }
128
129 result=fastPixelColorNolock (dst,x,y,color);
130
131 /* Unlock surface */
132 if ( SDL_MUSTLOCK(dst) ) {
133 SDL_UnlockSurface (dst);
134 }
135
136 return(result);
137 }
138
139 /* ----- Pixel - fast, no blending, locking, RGB input */
140
fastPixelRGBA(SDL_Surface * dst,Sint16 x,Sint16 y,Uint8 r,Uint8 g,Uint8 b,Uint8 a)141 int fastPixelRGBA (SDL_Surface *dst, Sint16 x, Sint16 y, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
142 {
143 Uint32 color;
144
145 /* Setup color */
146 color=SDL_MapRGBA(dst->format, r, g, b, a);
147
148 /* Draw */
149 return(fastPixelColor(dst, x, y, color));
150
151 }
152
153 /* ----- Pixel - fast, no blending, no locking RGB input */
154
fastPixelRGBANolock(SDL_Surface * dst,Sint16 x,Sint16 y,Uint8 r,Uint8 g,Uint8 b,Uint8 a)155 int fastPixelRGBANolock (SDL_Surface *dst, Sint16 x, Sint16 y, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
156 {
157 Uint32 color;
158
159 /* Setup color */
160 color=SDL_MapRGBA(dst->format, r, g, b, a);
161
162 /* Draw */
163 return(fastPixelColorNolock(dst, x, y, color));
164 }
165
166 #ifdef SURFACE_ALPHA_PIXEL
167
168 /* ----- Pixel - using single pixel blit with blending enabled if a<255 */
169
170 static SDL_Surface *gfxPrimitivesSinglePixel=NULL;
171
pixelColor(SDL_Surface * dst,Sint16 x,Sint16 y,Uint32 color)172 int pixelColor (SDL_Surface *dst, Sint16 x, Sint16 y, Uint32 color)
173 {
174 SDL_Rect srect;
175 SDL_Rect drect;
176 int result;
177
178 /* Setup source rectangle for pixel */
179 srect.x=0;
180 srect.y=0;
181 srect.w=1;
182 srect.h=1;
183
184 /* Setup destination rectangle for pixel */
185 drect.x=x;
186 drect.y=y;
187 drect.w=1;
188 drect.h=1;
189
190 /* Create single pixel in 32bit RGBA format */
191 if (gfxPrimitivesSinglePixel==NULL) {
192 gfxPrimitivesSinglePixel=SDL_CreateRGBSurface(SDL_SWSURFACE | SDL_HWSURFACE | SDL_SRCALPHA, 1, 1, 32, 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF);
193 }
194
195 /* Draw color into pixel*/
196 SDL_FillRect (gfxPrimitivesSinglePixel, &srect, color);
197
198 /* Draw pixel onto destination surface */
199 result=SDL_BlitSurface (gfxPrimitivesSinglePixel, &srect, dst, &drect);
200
201 return(result);
202 }
203
204 #else
205
206 /* PutPixel routine with alpha blending, input color in destination format */
207
_putPixelAlpha(SDL_Surface * surface,Sint16 x,Sint16 y,Uint32 color,Uint8 alpha)208 int _putPixelAlpha(SDL_Surface *surface, Sint16 x, Sint16 y, Uint32 color, Uint8 alpha)
209 {
210 Uint32 Rmask = surface->format->Rmask, Gmask = surface->format->Gmask, Bmask = surface->format->Bmask, Amask = surface->format->Amask;
211 Uint32 R,G,B,A = 0;
212
213 if (x>=clip_xmin(surface) && x<=clip_xmax(surface) && y>=clip_ymin(surface) && y<=clip_ymax(surface)) {
214
215 switch (surface->format->BytesPerPixel) {
216 case 1: { /* Assuming 8-bpp */
217 if( alpha == 255 ){
218 *((Uint8 *)surface->pixels + y*surface->pitch + x) = color;
219 } else {
220 Uint8 *pixel = (Uint8 *)surface->pixels + y*surface->pitch + x;
221
222 Uint8 dR = surface->format->palette->colors[*pixel].r;
223 Uint8 dG = surface->format->palette->colors[*pixel].g;
224 Uint8 dB = surface->format->palette->colors[*pixel].b;
225 Uint8 sR = surface->format->palette->colors[color].r;
226 Uint8 sG = surface->format->palette->colors[color].g;
227 Uint8 sB = surface->format->palette->colors[color].b;
228
229 dR = dR + ((sR-dR)*alpha >> 8);
230 dG = dG + ((sG-dG)*alpha >> 8);
231 dB = dB + ((sB-dB)*alpha >> 8);
232
233 *pixel = SDL_MapRGB(surface->format, dR, dG, dB);
234 }
235 }
236 break;
237
238 case 2: { /* Probably 15-bpp or 16-bpp */
239 if ( alpha == 255 ) {
240 *((Uint16 *)surface->pixels + y*surface->pitch/2 + x) = color;
241 } else {
242 Uint16 *pixel = (Uint16 *)surface->pixels + y*surface->pitch/2 + x;
243 Uint32 dc = *pixel;
244
245 R = ((dc & Rmask) + (( (color & Rmask) - (dc & Rmask) ) * alpha >> 8)) & Rmask;
246 G = ((dc & Gmask) + (( (color & Gmask) - (dc & Gmask) ) * alpha >> 8)) & Gmask;
247 B = ((dc & Bmask) + (( (color & Bmask) - (dc & Bmask) ) * alpha >> 8)) & Bmask;
248 if( Amask )
249 A = ((dc & Amask) + (( (color & Amask) - (dc & Amask) ) * alpha >> 8)) & Amask;
250
251 *pixel= R | G | B | A;
252 }
253 }
254 break;
255
256 case 3: { /* Slow 24-bpp mode, usually not used */
257 Uint8 *pix = (Uint8 *)surface->pixels + y * surface->pitch + x*3;
258 Uint8 rshift8=surface->format->Rshift/8;
259 Uint8 gshift8=surface->format->Gshift/8;
260 Uint8 bshift8=surface->format->Bshift/8;
261 Uint8 ashift8=surface->format->Ashift/8;
262
263
264 if ( alpha == 255 ) {
265 *(pix+rshift8) = color>>surface->format->Rshift;
266 *(pix+gshift8) = color>>surface->format->Gshift;
267 *(pix+bshift8) = color>>surface->format->Bshift;
268 *(pix+ashift8) = color>>surface->format->Ashift;
269 } else {
270 Uint8 dR, dG, dB, dA=0;
271 Uint8 sR, sG, sB, sA=0;
272
273 pix = (Uint8 *)surface->pixels + y * surface->pitch + x*3;
274
275 dR = *((pix)+rshift8);
276 dG = *((pix)+gshift8);
277 dB = *((pix)+bshift8);
278 dA = *((pix)+ashift8);
279
280 sR = (color>>surface->format->Rshift)&0xff;
281 sG = (color>>surface->format->Gshift)&0xff;
282 sB = (color>>surface->format->Bshift)&0xff;
283 sA = (color>>surface->format->Ashift)&0xff;
284
285 dR = dR + ((sR-dR)*alpha >> 8);
286 dG = dG + ((sG-dG)*alpha >> 8);
287 dB = dB + ((sB-dB)*alpha >> 8);
288 dA = dA + ((sA-dA)*alpha >> 8);
289
290 *((pix)+rshift8) = dR;
291 *((pix)+gshift8) = dG;
292 *((pix)+bshift8) = dB;
293 *((pix)+ashift8) = dA;
294 }
295 }
296 break;
297
298 case 4: { /* Probably 32-bpp */
299 if ( alpha == 255 ) {
300 *((Uint32 *)surface->pixels + y*surface->pitch/4 + x) = color;
301 } else {
302 Uint32 *pixel = (Uint32 *)surface->pixels + y*surface->pitch/4 + x;
303 Uint32 dc = *pixel;
304
305 R = ((dc & Rmask) + (( (color & Rmask) - (dc & Rmask) ) * alpha >> 8)) & Rmask;
306 G = ((dc & Gmask) + (( (color & Gmask) - (dc & Gmask) ) * alpha >> 8)) & Gmask;
307 B = ((dc & Bmask) + (( (color & Bmask) - (dc & Bmask) ) * alpha >> 8)) & Bmask;
308 if ( Amask )
309 A = ((dc & Amask) + (( (color & Amask) - (dc & Amask) ) * alpha >> 8)) & Amask;
310
311 *pixel = R | G | B | A;
312 }
313 }
314 break;
315 }
316 }
317
318 return(0);
319 }
320
321 /* ----- Pixel - pixel draw with blending enabled if a<255 */
322
pixelColor(SDL_Surface * dst,Sint16 x,Sint16 y,Uint32 color)323 int pixelColor (SDL_Surface *dst, Sint16 x, Sint16 y, Uint32 color)
324 {
325 Uint8 alpha;
326 Uint32 mcolor;
327 int result=0;
328
329 /* Lock the surface */
330 if ( SDL_MUSTLOCK(dst) ) {
331 if ( SDL_LockSurface(dst) < 0 ) {
332 return(-1);
333 }
334 }
335
336 /* Setup color */
337 alpha=color &0x000000ff;
338 mcolor=SDL_MapRGBA(dst->format, (color & 0xff000000) >> 24, (color & 0x00ff0000) >> 16, (color & 0x0000ff00) >> 8, alpha);
339
340 /* Draw */
341 result = _putPixelAlpha(dst,x,y,mcolor,alpha);
342
343 /* Unlock the surface */
344 if (SDL_MUSTLOCK(dst) ) {
345 SDL_UnlockSurface(dst);
346 }
347
348 return(result);
349 }
350
351
352 /* Filled rectangle with alpha blending, color in destination format */
353
_filledRectAlpha(SDL_Surface * surface,Sint16 x1,Sint16 y1,Sint16 x2,Sint16 y2,Uint32 color,Uint8 alpha)354 int _filledRectAlpha (SDL_Surface *surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color, Uint8 alpha)
355 {
356 Uint32 Rmask = surface->format->Rmask, Gmask = surface->format->Gmask, Bmask = surface->format->Bmask, Amask = surface->format->Amask;
357 Uint32 R,G,B,A=0;
358 Sint16 x,y;
359
360 switch (surface->format->BytesPerPixel) {
361 case 1: { /* Assuming 8-bpp */
362 Uint8 *row, *pixel;
363 Uint8 dR, dG, dB;
364
365 Uint8 sR = surface->format->palette->colors[color].r;
366 Uint8 sG = surface->format->palette->colors[color].g;
367 Uint8 sB = surface->format->palette->colors[color].b;
368
369 for(y = y1; y<=y2; y++){
370 row = (Uint8 *)surface->pixels + y*surface->pitch;
371 for(x = x1; x <= x2; x++){
372 pixel = row + x;
373
374 dR = surface->format->palette->colors[*pixel].r;
375 dG = surface->format->palette->colors[*pixel].g;
376 dB = surface->format->palette->colors[*pixel].b;
377
378 dR = dR + ((sR-dR)*alpha >> 8);
379 dG = dG + ((sG-dG)*alpha >> 8);
380 dB = dB + ((sB-dB)*alpha >> 8);
381
382 *pixel = SDL_MapRGB(surface->format, dR, dG, dB);
383 }
384 }
385 }
386 break;
387
388 case 2: { /* Probably 15-bpp or 16-bpp */
389 Uint16 *row, *pixel;
390 Uint32 dR=(color & Rmask),dG=(color & Gmask),dB=(color & Bmask),dA=(color & Amask);
391
392 for(y = y1; y<=y2; y++){
393 row = (Uint16 *)surface->pixels + y*surface->pitch/2;
394 for(x = x1; x <= x2; x++){
395 pixel = row + x;
396
397 R = ((*pixel & Rmask) + (( dR - (*pixel & Rmask) ) * alpha >> 8)) & Rmask;
398 G = ((*pixel & Gmask) + (( dG - (*pixel & Gmask) ) * alpha >> 8)) & Gmask;
399 B = ((*pixel & Bmask) + (( dB - (*pixel & Bmask) ) * alpha >> 8)) & Bmask;
400 if( Amask )
401 A = ((*pixel & Amask) + (( dA - (*pixel & Amask) ) * alpha >> 8)) & Amask;
402
403 *pixel= R | G | B | A;
404 }
405 }
406 }
407 break;
408
409 case 3: { /* Slow 24-bpp mode, usually not used */
410 Uint8 *row,*pix;
411 Uint8 dR, dG, dB, dA;
412 Uint8 rshift8=surface->format->Rshift/8;
413 Uint8 gshift8=surface->format->Gshift/8;
414 Uint8 bshift8=surface->format->Bshift/8;
415 Uint8 ashift8=surface->format->Ashift/8;
416
417 Uint8 sR = (color>>surface->format->Rshift)&0xff;
418 Uint8 sG = (color>>surface->format->Gshift)&0xff;
419 Uint8 sB = (color>>surface->format->Bshift)&0xff;
420 Uint8 sA = (color>>surface->format->Ashift)&0xff;
421
422 for(y = y1; y<=y2; y++){
423 row = (Uint8 *)surface->pixels + y * surface->pitch;
424 for(x = x1; x <= x2; x++){
425 pix = row + x*3;
426
427 dR = *((pix)+rshift8);
428 dG = *((pix)+gshift8);
429 dB = *((pix)+bshift8);
430 dA = *((pix)+ashift8);
431
432 dR = dR + ((sR-dR)*alpha >> 8);
433 dG = dG + ((sG-dG)*alpha >> 8);
434 dB = dB + ((sB-dB)*alpha >> 8);
435 dA = dA + ((sA-dA)*alpha >> 8);
436
437 *((pix)+rshift8) = dR;
438 *((pix)+gshift8) = dG;
439 *((pix)+bshift8) = dB;
440 *((pix)+ashift8) = dA;
441 }
442 }
443
444 }
445 break;
446
447 case 4: { /* Probably 32-bpp */
448 Uint32 *row, *pixel;
449 Uint32 dR=(color & Rmask),dG=(color & Gmask),dB=(color & Bmask),dA=(color & Amask);
450
451 for(y = y1; y<=y2; y++){
452 row = (Uint32 *)surface->pixels + y*surface->pitch/4;
453 for(x = x1; x <= x2; x++){
454 pixel = row + x;
455
456 R = ((*pixel & Rmask) + (( dR - (*pixel & Rmask) ) * alpha >> 8)) & Rmask;
457 G = ((*pixel & Gmask) + (( dG - (*pixel & Gmask) ) * alpha >> 8)) & Gmask;
458 B = ((*pixel & Bmask) + (( dB - (*pixel & Bmask) ) * alpha >> 8)) & Bmask;
459 if( Amask )
460 A = ((*pixel & Amask) + (( dA - (*pixel & Amask) ) * alpha >> 8)) & Amask;
461
462 *pixel= R | G | B | A;
463 }
464 }
465 }
466 break;
467 }
468
469 return(0);
470 }
471
472 /* Draw rectangle with alpha enabled from RGBA color. */
473
filledRectAlpha(SDL_Surface * dst,Sint16 x1,Sint16 y1,Sint16 x2,Sint16 y2,Uint32 color)474 int filledRectAlpha (SDL_Surface *dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color)
475 {
476 Uint8 alpha;
477 Uint32 mcolor;
478 int result=0;
479
480 /* Lock the surface */
481 if ( SDL_MUSTLOCK(dst) ) {
482 if ( SDL_LockSurface(dst) < 0 ) {
483 return(-1);
484 }
485 }
486
487 /* Setup color */
488 alpha = color & 0x000000ff;
489 mcolor=SDL_MapRGBA(dst->format, (color & 0xff000000) >> 24, (color & 0x00ff0000) >> 16, (color & 0x0000ff00) >> 8, alpha);
490
491 /* Draw */
492 result = _filledRectAlpha(dst,x1,y1,x2,y2,mcolor,alpha);
493
494 /* Unlock the surface */
495 if (SDL_MUSTLOCK(dst) ) {
496 SDL_UnlockSurface(dst);
497 }
498
499 return(result);
500 }
501
502 /* Draw horizontal line with alpha enabled from RGBA color */
503
HLineAlpha(SDL_Surface * dst,Sint16 x1,Sint16 x2,Sint16 y,Uint32 color)504 int HLineAlpha(SDL_Surface *dst, Sint16 x1, Sint16 x2, Sint16 y, Uint32 color)
505 {
506 return (filledRectAlpha(dst, x1, y, x2, y, color));
507 }
508
509
510 /* Draw vertical line with alpha enabled from RGBA color */
511
VLineAlpha(SDL_Surface * dst,Sint16 x,Sint16 y1,Sint16 y2,Uint32 color)512 int VLineAlpha(SDL_Surface *dst, Sint16 x, Sint16 y1, Sint16 y2, Uint32 color)
513 {
514 return (filledRectAlpha(dst, x, y1, x, y2, color));
515 }
516
517 #endif
518
519
520 /* Pixel - using alpha weight on color for AA-drawing */
521
pixelColorWeight(SDL_Surface * dst,Sint16 x,Sint16 y,Uint32 color,Uint32 weight)522 int pixelColorWeight (SDL_Surface *dst, Sint16 x, Sint16 y, Uint32 color, Uint32 weight)
523 {
524 Uint32 a;
525
526 /* Get alpha */
527 a=(color & (Uint32)0x000000ff);
528
529 /* Modify Alpha by weight */
530 a = ((a*weight) >> 8);
531
532 return(pixelColor (dst,x,y, (color & (Uint32)0xffffff00) | (Uint32)a ));
533 }
534
pixelRGBA(SDL_Surface * dst,Sint16 x,Sint16 y,Uint8 r,Uint8 g,Uint8 b,Uint8 a)535 int pixelRGBA (SDL_Surface *dst, Sint16 x, Sint16 y, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
536 {
537 Uint32 color;
538
539 /* Check Alpha */
540 if (a==255) {
541 /* No alpha blending required */
542 /* Setup color */
543 color=SDL_MapRGBA(dst->format, r, g, b, a);
544 /* Draw */
545 return(fastPixelColor (dst, x, y, color));
546 } else {
547 /* Alpha blending required */
548 /* Draw */
549 return(pixelColor (dst, x, y, ((Uint32)r << 24) | ((Uint32)g << 16) | ((Uint32)b << 8) | (Uint32)a ));
550 }
551 }
552
553 /* ----- Horizontal line */
554
555 #ifdef SURFACE_ALPHA_PIXEL
556 static SDL_Surface *gfxPrimitivesHline=NULL;
557 #endif
558
hlineColor(SDL_Surface * dst,Sint16 x1,Sint16 x2,Sint16 y,Uint32 color)559 int hlineColor (SDL_Surface *dst, Sint16 x1, Sint16 x2, Sint16 y, Uint32 color)
560 {
561 Sint16 left,right,top,bottom;
562 Uint8 *pixel,*pixellast;
563 int dx;
564 int pixx, pixy;
565 Sint16 w;
566 Sint16 xtmp;
567 int result=-1;
568 Uint8 *colorptr;
569 #ifdef SURFACE_ALPHA_PIXEL
570 Uint32 a;
571 SDL_Rect srect;
572 SDL_Rect drect;
573 #endif
574
575 /* Get clipping boundary */
576 left = dst->clip_rect.x;
577 right = dst->clip_rect.x+dst->clip_rect.w-1;
578 top = dst->clip_rect.y;
579 bottom = dst->clip_rect.y+dst->clip_rect.h-1;
580
581 /* Swap x1, x2 if required */
582 if (x1>x2) {
583 xtmp=x1; x1=x2; x2=xtmp;
584 }
585
586 /* Visible */
587 if ((x1>right) || (x2<left) || (y<top) || (y>bottom)) {
588 return(0);
589 }
590
591 /* Clip x */
592 if (x1<left) {
593 x1=left;
594 }
595 if (x2>right) {
596 x2=right;
597 }
598
599 /* Calculate width */
600 w=x2-x1;
601
602 /* Sanity check on width */
603 if (w<0) {
604 return(0);
605 }
606
607 /* Alpha check */
608 if ((color & 255)==255) {
609
610 /* No alpha-blending required */
611
612 /* Setup color */
613 colorptr=(Uint8 *)&color;
614 if (SDL_BYTEORDER == SDL_BIG_ENDIAN) {
615 color=SDL_MapRGBA(dst->format, colorptr[0], colorptr[1], colorptr[2], colorptr[3]);
616 } else {
617 color=SDL_MapRGBA(dst->format, colorptr[3], colorptr[2], colorptr[1], colorptr[0]);
618 }
619
620 /* Lock surface */
621 SDL_LockSurface(dst);
622
623 /* More variable setup */
624 dx=w;
625 pixx = dst->format->BytesPerPixel;
626 pixy = dst->pitch;
627 pixel = ((Uint8*)dst->pixels) + pixx * (int)x1 + pixy * (int)y;
628
629 /* Draw */
630 switch(dst->format->BytesPerPixel) {
631 case 1:
632 memset (pixel, color, dx);
633 break;
634 case 2:
635 pixellast = pixel + dx + dx;
636 for (; pixel<=pixellast; pixel += pixx) {
637 *(Uint16*)pixel = color;
638 }
639 break;
640 case 3:
641 pixellast = pixel + dx + dx + dx;
642 for (; pixel<=pixellast; pixel += pixx) {
643 if (SDL_BYTEORDER == SDL_BIG_ENDIAN) {
644 pixel[0] = (color >> 16) & 0xff;
645 pixel[1] = (color >> 8) & 0xff;
646 pixel[2] = color & 0xff;
647 } else {
648 pixel[0] = color & 0xff;
649 pixel[1] = (color >> 8) & 0xff;
650 pixel[2] = (color >> 16) & 0xff;
651 }
652 }
653 break;
654 default: /* case 4*/
655 dx = dx + dx;
656 pixellast = pixel + dx + dx;
657 for (; pixel<=pixellast; pixel += pixx) {
658 *(Uint32*)pixel = color;
659 }
660 break;
661 }
662
663 /* Unlock surface */
664 SDL_UnlockSurface(dst);
665
666 /* Set result code */
667 result=0;
668
669 } else {
670
671 /* Alpha blending blit */
672
673 #ifdef SURFACE_ALPHA_PIXEL
674
675 /* Adjust width for Rect setup */
676 w++;
677
678 /* Setup source rectangle for pixel */
679 srect.x=0;
680 srect.y=0;
681 srect.w=w;
682 srect.h=1;
683
684 /* Setup rectangle for destination line */
685 drect.x=x1;
686 drect.y=y;
687 drect.w=w;
688 drect.h=1;
689
690 /* Maybe deallocate existing surface if size is too small */
691 if ((gfxPrimitivesHline!=NULL) && (gfxPrimitivesHline->w<w) ) {
692 SDL_FreeSurface(gfxPrimitivesHline);
693 gfxPrimitivesHline=NULL;
694 }
695
696 /* Create horizontal line surface in destination format if necessary */
697 if (gfxPrimitivesHline==NULL) {
698 gfxPrimitivesHline=SDL_CreateRGBSurface(SDL_SWSURFACE | SDL_HWSURFACE | SDL_SRCALPHA, w, 1, 32, 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF);
699 }
700
701 /* Get alpha */
702 a=(color & (Uint32)0x000000ff);
703
704 /* Toggle alpha blending if necessary, reset otherwise */
705 if (a != 255) {
706 SDL_SetAlpha (gfxPrimitivesHline, SDL_SRCALPHA, 255);
707 } else {
708 SDL_SetAlpha (gfxPrimitivesHline, 0, 255);
709 }
710
711 /* Draw color into pixel*/
712 SDL_FillRect (gfxPrimitivesHline, &srect, color);
713
714 /* Draw pixel onto destination surface */
715 result=SDL_BlitSurface (gfxPrimitivesHline, &srect, dst, &drect);
716
717 #else
718
719 result=HLineAlpha (dst, x1, x1+w, y, color);
720
721 #endif
722
723 }
724
725 return(result);
726 }
727
hlineRGBA(SDL_Surface * dst,Sint16 x1,Sint16 x2,Sint16 y,Uint8 r,Uint8 g,Uint8 b,Uint8 a)728 int hlineRGBA (SDL_Surface *dst, Sint16 x1, Sint16 x2, Sint16 y, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
729 {
730 /* Draw */
731 return(hlineColor(dst, x1, x2, y, ((Uint32)r << 24) | ((Uint32)g << 16) | ((Uint32)b << 8) | (Uint32)a));
732 }
733
734 /* ----- Vertical line */
735
736 #ifdef SURFACE_ALPHA_PIXEL
737 static SDL_Surface *gfxPrimitivesVline=NULL;
738 #endif
739
vlineColor(SDL_Surface * dst,Sint16 x,Sint16 y1,Sint16 y2,Uint32 color)740 int vlineColor (SDL_Surface *dst, Sint16 x, Sint16 y1, Sint16 y2, Uint32 color)
741 {
742 Sint16 left,right,top,bottom;
743 Uint8 *pixel, *pixellast;
744 int dy;
745 int pixx, pixy;
746 Sint16 h;
747 Sint16 ytmp;
748 int result=-1;
749 Uint8 *colorptr;
750 #ifdef SURFACE_ALPHA_PIXEL
751 SDL_Rect srect;
752 SDL_Rect drect;
753 Uint32 a;
754 #endif
755
756 /* Get clipping boundary */
757 left = dst->clip_rect.x;
758 right = dst->clip_rect.x+dst->clip_rect.w-1;
759 top = dst->clip_rect.y;
760 bottom = dst->clip_rect.y+dst->clip_rect.h-1;
761
762 /* Swap y1, y2 if required */
763 if (y1>y2) {
764 ytmp=y1; y1=y2; y2=ytmp;
765 }
766
767 /* Visible */
768 if ((y2<top) || (y1>bottom) || (x<left) || (x>right)) {
769 return(0);
770 }
771
772 /* Clip y */
773 if (y1<top) {
774 y1=top;
775 }
776 if (y2>bottom) {
777 y2=bottom;
778 }
779
780 /* Calculate height */
781 h=y2-y1;
782
783 /* Sanity check on height */
784 if (h<0) {
785 return(0);
786 }
787
788 /* Alpha check */
789 if ((color & 255)==255) {
790
791 /* No alpha-blending required */
792
793 /* Setup color */
794 colorptr=(Uint8 *)&color;
795 if (SDL_BYTEORDER == SDL_BIG_ENDIAN) {
796 color=SDL_MapRGBA(dst->format, colorptr[0], colorptr[1], colorptr[2], colorptr[3]);
797 } else {
798 color=SDL_MapRGBA(dst->format, colorptr[3], colorptr[2], colorptr[1], colorptr[0]);
799 }
800
801 /* Lock surface */
802 SDL_LockSurface(dst);
803
804 /* More variable setup */
805 dy=h;
806 pixx = dst->format->BytesPerPixel;
807 pixy = dst->pitch;
808 pixel = ((Uint8*)dst->pixels) + pixx * (int)x + pixy * (int)y1;
809 pixellast = pixel + pixy*dy;
810
811 /* Draw */
812 switch(dst->format->BytesPerPixel) {
813 case 1:
814 for (; pixel<=pixellast; pixel += pixy) {
815 *(Uint8*)pixel = color;
816 }
817 break;
818 case 2:
819 for (; pixel<=pixellast; pixel += pixy) {
820 *(Uint16*)pixel = color;
821 }
822 break;
823 case 3:
824 for (; pixel<=pixellast; pixel += pixy) {
825 if(SDL_BYTEORDER == SDL_BIG_ENDIAN) {
826 pixel[0] = (color >> 16) & 0xff;
827 pixel[1] = (color >> 8) & 0xff;
828 pixel[2] = color & 0xff;
829 } else {
830 pixel[0] = color & 0xff;
831 pixel[1] = (color >> 8) & 0xff;
832 pixel[2] = (color >> 16) & 0xff;
833 }
834 }
835 break;
836 default: /* case 4*/
837 for (; pixel<=pixellast; pixel += pixy) {
838 *(Uint32*)pixel = color;
839 }
840 break;
841 }
842
843 /* Unlock surface */
844 SDL_UnlockSurface(dst);
845
846 /* Set result code */
847 result=0;
848
849 } else {
850
851 /* Alpha blending blit */
852
853 #ifdef SURFACE_ALPHA_PIXEL
854
855 /* Adjust height for Rect setup */
856 h++;
857
858 /* Setup source rectangle for pixel */
859 srect.x=0;
860 srect.y=0;
861 srect.w=1;
862 srect.h=h;
863
864 /* Setup rectangle for line */
865 drect.x=x;
866 drect.y=y1;
867 drect.w=1;
868 drect.h=h;
869
870 /* Maybe deallocate existing surface if size is too small */
871 if ( (gfxPrimitivesVline!=NULL) && (gfxPrimitivesVline->h<h) ) {
872 SDL_FreeSurface(gfxPrimitivesVline);
873 gfxPrimitivesVline=NULL;
874 }
875
876 /* Create horizontal line surface in destination format if necessary */
877 if (gfxPrimitivesVline==NULL) {
878 gfxPrimitivesVline=SDL_CreateRGBSurface(SDL_SWSURFACE | SDL_HWSURFACE | SDL_SRCALPHA, 1, h, 32, 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF);
879 }
880
881 /* Get alpha */
882 a=(color & (Uint32)0x000000ff);
883
884 /* Toggle alpha blending if necessary, reset otherwise */
885 if (a != 255) {
886 SDL_SetAlpha (gfxPrimitivesVline, SDL_SRCALPHA, 255);
887 } else {
888 SDL_SetAlpha (gfxPrimitivesVline, 0, 255);
889 }
890
891 /* Draw color into pixel*/
892 SDL_FillRect (gfxPrimitivesVline, &srect, color);
893
894 /* Draw Vline onto destination surface */
895 result=SDL_BlitSurface (gfxPrimitivesVline, &srect, dst, &drect);
896
897 #else
898
899 result=VLineAlpha(dst,x, y1, y1+h, color);
900
901 #endif
902
903 }
904
905 return(result);
906 }
907
vlineRGBA(SDL_Surface * dst,Sint16 x,Sint16 y1,Sint16 y2,Uint8 r,Uint8 g,Uint8 b,Uint8 a)908 int vlineRGBA (SDL_Surface *dst, Sint16 x, Sint16 y1, Sint16 y2, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
909 {
910 /* Draw */
911 return(vlineColor(dst, x, y1, y2, ((Uint32)r << 24) | ((Uint32)g << 16) | ((Uint32)b << 8) | (Uint32)a));
912 }
913
914 /* ----- Rectangle */
915
rectangleColor(SDL_Surface * dst,Sint16 x1,Sint16 y1,Sint16 x2,Sint16 y2,Uint32 color)916 int rectangleColor (SDL_Surface *dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color)
917 {
918 int result;
919 Sint16 w,h, xtmp, ytmp;
920
921
922 /* Swap x1, x2 if required */
923 if (x1>x2) {
924 xtmp=x1; x1=x2; x2=xtmp;
925 }
926
927 /* Swap y1, y2 if required */
928 if (y1>y2) {
929 ytmp=y1; y1=y2; y2=ytmp;
930 }
931
932 /* Calculate width&height */
933 w=x2-x1;
934 h=y2-y1;
935
936 /* Sanity check */
937 if ((w<0) || (h<0)) {
938 return(0);
939 }
940
941 /* Test for special cases of straight lines or single point */
942 if (x1==x2) {
943 if (y1==y2) {
944 return(pixelColor(dst, x1, y1, color));
945 } else {
946 return(vlineColor(dst, x1, y1, y2, color));
947 }
948 } else {
949 if (y1==y2) {
950 return(hlineColor(dst, x1, x2, y1, color));
951 }
952 }
953
954 /* Draw rectangle */
955 result=0;
956 result |= vlineColor(dst, x1, y1, y2, color);
957 result |= vlineColor(dst, x2, y1, y2, color);
958 result |= hlineColor(dst, x1, x2, y1, color);
959 result |= hlineColor(dst, x1, x2, y2, color);
960
961 return(result);
962
963 }
964
rectangleRGBA(SDL_Surface * dst,Sint16 x1,Sint16 y1,Sint16 x2,Sint16 y2,Uint8 r,Uint8 g,Uint8 b,Uint8 a)965 int rectangleRGBA (SDL_Surface *dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
966 {
967 /* Draw */
968 return(rectangleColor(dst, x1, y1, x2, y2, ((Uint32)r << 24) | ((Uint32)g << 16) | ((Uint32)b << 8) | (Uint32)a));
969 }
970
971 /* --------- Clipping routines for box/line */
972
973 /* Clipping based heavily on code from */
974 /* http://www.ncsa.uiuc.edu/Vis/Graphics/src/clipCohSuth.c */
975
976 #define CLIP_LEFT_EDGE 0x1
977 #define CLIP_RIGHT_EDGE 0x2
978 #define CLIP_BOTTOM_EDGE 0x4
979 #define CLIP_TOP_EDGE 0x8
980 #define CLIP_INSIDE(a) (!a)
981 #define CLIP_REJECT(a,b) (a&b)
982 #define CLIP_ACCEPT(a,b) (!(a|b))
983
clipEncode(Sint16 x,Sint16 y,Sint16 left,Sint16 top,Sint16 right,Sint16 bottom)984 static int clipEncode (Sint16 x, Sint16 y, Sint16 left, Sint16 top, Sint16 right, Sint16 bottom)
985 {
986 int code = 0;
987 if (x < left) {
988 code |= CLIP_LEFT_EDGE;
989 } else if (x > right) {
990 code |= CLIP_RIGHT_EDGE;
991 }
992 if (y < top) {
993 code |= CLIP_TOP_EDGE;
994 } else if (y > bottom) {
995 code |= CLIP_BOTTOM_EDGE;
996 }
997 return code;
998 }
999
clipLine(SDL_Surface * dst,Sint16 * x1,Sint16 * y1,Sint16 * x2,Sint16 * y2)1000 static int clipLine(SDL_Surface *dst, Sint16 *x1, Sint16 *y1, Sint16 *x2, Sint16 *y2)
1001 {
1002 Sint16 left,right,top,bottom;
1003 int code1, code2;
1004 int draw = 0;
1005 Sint16 swaptmp;
1006 float m;
1007
1008 /* Get clipping boundary */
1009 left = dst->clip_rect.x;
1010 right = dst->clip_rect.x+dst->clip_rect.w-1;
1011 top = dst->clip_rect.y;
1012 bottom = dst->clip_rect.y+dst->clip_rect.h-1;
1013
1014 while (1) {
1015 code1 = clipEncode (*x1, *y1, left, top, right, bottom);
1016 code2 = clipEncode (*x2, *y2, left, top, right, bottom);
1017 if (CLIP_ACCEPT(code1, code2)) {
1018 draw = 1;
1019 break;
1020 } else if (CLIP_REJECT(code1, code2))
1021 break;
1022 else {
1023 if(CLIP_INSIDE (code1)) {
1024 swaptmp = *x2; *x2 = *x1; *x1 = swaptmp;
1025 swaptmp = *y2; *y2 = *y1; *y1 = swaptmp;
1026 swaptmp = code2; code2 = code1; code1 = swaptmp;
1027 }
1028 if (*x2 != *x1) {
1029 m = (*y2 - *y1) / (float)(*x2 - *x1);
1030 } else {
1031 m = 1.0f;
1032 }
1033 if (code1 & CLIP_LEFT_EDGE) {
1034 *y1 += (Sint16)((left - *x1) * m);
1035 *x1 = left;
1036 } else if (code1 & CLIP_RIGHT_EDGE) {
1037 *y1 += (Sint16)((right - *x1) * m);
1038 *x1 = right;
1039 } else if (code1 & CLIP_BOTTOM_EDGE) {
1040 if (*x2 != *x1) {
1041 *x1 += (Sint16)((bottom - *y1) / m);
1042 }
1043 *y1 = bottom;
1044 } else if (code1 & CLIP_TOP_EDGE) {
1045 if (*x2 != *x1) {
1046 *x1 += (Sint16)((top - *y1) / m);
1047 }
1048 *y1 = top;
1049 }
1050 }
1051 }
1052
1053 return draw;
1054 }
1055
1056 /* ----- Filled rectangle (Box) */
1057
1058 #ifdef SURFACE_ALPHA_PIXEL
1059 static SDL_Surface *gfxPrimitivesBox=NULL;
1060 #endif
1061
boxColor(SDL_Surface * dst,Sint16 x1,Sint16 y1,Sint16 x2,Sint16 y2,Uint32 color)1062 int boxColor (SDL_Surface *dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color)
1063 {
1064 Uint8 *pixel, *pixellast;
1065 int x, dx;
1066 int dy;
1067 int pixx, pixy;
1068 Sint16 w,h,tmp;
1069 int result;
1070 Uint8 *colorptr;
1071 #ifdef SURFACE_ALPHA_PIXEL
1072 Uint32 a;
1073 SDL_Rect srect;
1074 SDL_Rect drect;
1075 #endif
1076
1077 /* Clip diagonal and test if we have to draw */
1078 if (!(clipLine(dst,&x1,&y1,&x2,&y2))) {
1079 return(0);
1080 }
1081
1082 /* Test for special cases of straight lines or single point */
1083 if (x1==x2) {
1084 if (y1<y2) {
1085 return(vlineColor(dst, x1, y1, y2, color));
1086 } else if (y1>y2) {
1087 return(vlineColor(dst, x1, y2, y1, color));
1088 } else {
1089 return(pixelColor(dst, x1, y1, color));
1090 }
1091 }
1092 if (y1==y2) {
1093 if (x1<x2) {
1094 return(hlineColor(dst, x1, x2, y1, color));
1095 } else if (x1>x2) {
1096 return(hlineColor(dst, x2, x1, y1, color));
1097 }
1098 }
1099
1100 /* Order coordinates */
1101 if (x1>x2) {
1102 tmp=x1;
1103 x1=x2;
1104 x2=tmp;
1105 }
1106 if (y1>y2) {
1107 tmp=y1;
1108 y1=y2;
1109 y2=tmp;
1110 }
1111
1112 /* Calculate width&height */
1113 w=x2-x1;
1114 h=y2-y1;
1115
1116 /* Alpha check */
1117 if ((color & 255)==255) {
1118
1119 /* No alpha-blending required */
1120
1121 /* Setup color */
1122 colorptr=(Uint8 *)&color;
1123 if (SDL_BYTEORDER == SDL_BIG_ENDIAN) {
1124 color=SDL_MapRGBA(dst->format, colorptr[0], colorptr[1], colorptr[2], colorptr[3]);
1125 } else {
1126 color=SDL_MapRGBA(dst->format, colorptr[3], colorptr[2], colorptr[1], colorptr[0]);
1127 }
1128
1129 /* Lock surface */
1130 SDL_LockSurface(dst);
1131
1132 /* More variable setup */
1133 dx=w;
1134 dy=h;
1135 pixx = dst->format->BytesPerPixel;
1136 pixy = dst->pitch;
1137 pixel = ((Uint8*)dst->pixels) + pixx * (int)x1 + pixy * (int)y1;
1138 pixellast = pixel + pixx*dx + pixy*dy;
1139
1140 /* Draw */
1141 switch(dst->format->BytesPerPixel) {
1142 case 1:
1143 for (; pixel<=pixellast; pixel += pixy) {
1144 memset(pixel,(Uint8)color,dx);
1145 }
1146 break;
1147 case 2:
1148 pixy -= (pixx*dx);
1149 for (; pixel<=pixellast; pixel += pixy) {
1150 for (x=0; x<dx; x++) {
1151 *(Uint16*)pixel = color;
1152 pixel += pixx;
1153 }
1154 }
1155 break;
1156 case 3:
1157 pixy -= (pixx*dx);
1158 for (; pixel<=pixellast; pixel += pixy) {
1159 for (x=0; x<dx; x++) {
1160 if(SDL_BYTEORDER == SDL_BIG_ENDIAN) {
1161 pixel[0] = (color >> 16) & 0xff;
1162 pixel[1] = (color >> 8) & 0xff;
1163 pixel[2] = color & 0xff;
1164 } else {
1165 pixel[0] = color & 0xff;
1166 pixel[1] = (color >> 8) & 0xff;
1167 pixel[2] = (color >> 16) & 0xff;
1168 }
1169 pixel += pixx;
1170 }
1171 }
1172 break;
1173 default: /* case 4*/
1174 pixy -= (pixx*dx);
1175 for (; pixel<=pixellast; pixel += pixy) {
1176 for (x=0; x<dx; x++) {
1177 *(Uint32*)pixel = color;
1178 pixel += pixx;
1179 }
1180 }
1181 break;
1182 }
1183
1184 /* Unlock surface */
1185 SDL_UnlockSurface(dst);
1186
1187 result=0;
1188
1189 } else {
1190
1191 #ifdef SURFACE_ALPHA_PIXEL
1192
1193 /* Setup source rectangle for pixel */
1194 srect.x=0;
1195 srect.y=0;
1196 srect.w=w;
1197 srect.h=h;
1198
1199 /* Setup rectangle for line */
1200 drect.x=x1;
1201 drect.y=y1;
1202 drect.w=w;
1203 drect.h=h;
1204
1205 /* Maybe deallocate existing surface if size is too small */
1206 if ((gfxPrimitivesBox!=NULL) && ((gfxPrimitivesBox->w<w) || (gfxPrimitivesBox->h<h))) {
1207 SDL_FreeSurface(gfxPrimitivesBox);
1208 gfxPrimitivesBox=NULL;
1209 }
1210
1211 /* Create box surface in destination format if necessary */
1212 if (gfxPrimitivesBox==NULL) {
1213 gfxPrimitivesBox=SDL_CreateRGBSurface(SDL_SWSURFACE | SDL_HWSURFACE | SDL_SRCALPHA, w, h, 32, 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF);
1214 }
1215
1216 /* Get alpha */
1217 a=(color & (Uint32)0x000000ff);
1218
1219 /* Toggle alpha blending if necessary, reset otherwise */
1220 if (a != 255) {
1221 SDL_SetAlpha (gfxPrimitivesBox, SDL_SRCALPHA, 255);
1222 } else {
1223 SDL_SetAlpha (gfxPrimitivesBox, 0, 255);
1224 }
1225
1226 /* Draw color into pixel*/
1227 SDL_FillRect (gfxPrimitivesBox, &srect, color);
1228
1229 /* Draw pixel onto destination surface */
1230 result=SDL_BlitSurface (gfxPrimitivesBox, &srect, dst, &drect);
1231
1232 #else
1233
1234 result=filledRectAlpha(dst,x1,y1,x1+w,y1+h,color);
1235
1236 #endif
1237
1238 }
1239
1240 return(result);
1241 }
1242
boxRGBA(SDL_Surface * dst,Sint16 x1,Sint16 y1,Sint16 x2,Sint16 y2,Uint8 r,Uint8 g,Uint8 b,Uint8 a)1243 int boxRGBA (SDL_Surface *dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
1244 {
1245 /* Draw */
1246 return(boxColor(dst, x1, y1, x2, y2, ((Uint32)r << 24) | ((Uint32)g << 16) | ((Uint32)b << 8) | (Uint32)a));
1247 }
1248
1249 /* ----- Line */
1250
1251 /* Non-alpha line drawing code adapted from routine */
1252 /* by Pete Shinners, pete@shinners.org */
1253 /* Originally from pygame, http://pygame.seul.org */
1254
1255 #define ABS(a) (((a)<0) ? -(a) : (a))
1256
lineColor(SDL_Surface * dst,Sint16 x1,Sint16 y1,Sint16 x2,Sint16 y2,Uint32 color)1257 int lineColor(SDL_Surface *dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color)
1258 {
1259 int pixx, pixy;
1260 int x,y;
1261 int dx,dy;
1262 int ax,ay;
1263 int sx,sy;
1264 int swaptmp;
1265 Uint8 *pixel;
1266 Uint8 *colorptr;
1267
1268 /* Clip line and test if we have to draw */
1269 if (!(clipLine(dst,&x1,&y1,&x2,&y2))) {
1270 return(0);
1271 }
1272
1273 /* Test for special cases of straight lines or single point */
1274 if (x1==x2) {
1275 if (y1<y2) {
1276 return(vlineColor(dst, x1, y1, y2, color));
1277 } else if (y1>y2) {
1278 return(vlineColor(dst, x1, y2, y1, color));
1279 } else {
1280 return(pixelColor(dst, x1, y1, color));
1281 }
1282 }
1283 if (y1==y2) {
1284 if (x1<x2) {
1285 return(hlineColor(dst, x1, x2, y1, color));
1286 } else if (x1>x2) {
1287 return(hlineColor(dst, x2, x1, y1, color));
1288 }
1289 }
1290
1291 /* Variable setup */
1292 dx = x2 - x1;
1293 dy = y2 - y1;
1294 sx = (dx >= 0) ? 1 : -1;
1295 sy = (dy >= 0) ? 1 : -1;
1296
1297 /* Check for alpha blending */
1298 if ((color & 255)==255) {
1299
1300 /* No alpha blending - use fast pixel routines */
1301
1302 /* Setup color */
1303 colorptr=(Uint8 *)&color;
1304 if (SDL_BYTEORDER == SDL_BIG_ENDIAN) {
1305 color=SDL_MapRGBA(dst->format, colorptr[0], colorptr[1], colorptr[2], colorptr[3]);
1306 } else {
1307 color=SDL_MapRGBA(dst->format, colorptr[3], colorptr[2], colorptr[1], colorptr[0]);
1308 }
1309
1310 /* Lock surface */
1311 SDL_LockSurface(dst);
1312
1313 /* More variable setup */
1314 dx = sx * dx + 1;
1315 dy = sy * dy + 1;
1316 pixx = dst->format->BytesPerPixel;
1317 pixy = dst->pitch;
1318 pixel = ((Uint8*)dst->pixels) + pixx * (int)x1 + pixy * (int)y1;
1319 pixx *= sx;
1320 pixy *= sy;
1321 if (dx < dy) {
1322 swaptmp = dx; dx = dy; dy = swaptmp;
1323 swaptmp = pixx; pixx = pixy; pixy = swaptmp;
1324 }
1325
1326 /* Draw */
1327 x=0;
1328 y=0;
1329 switch(dst->format->BytesPerPixel) {
1330 case 1:
1331 for(; x < dx; x++, pixel += pixx) {
1332 *pixel = color;
1333 y += dy;
1334 if (y >= dx) {
1335 y -= dx; pixel += pixy;
1336 }
1337 }
1338 break;
1339 case 2:
1340 for (; x < dx; x++, pixel += pixx) {
1341 *(Uint16*)pixel = color;
1342 y += dy;
1343 if (y >= dx) {
1344 y -= dx;
1345 pixel += pixy;
1346 }
1347 }
1348 break;
1349 case 3:
1350 for(; x < dx; x++, pixel += pixx) {
1351 if(SDL_BYTEORDER == SDL_BIG_ENDIAN) {
1352 pixel[0] = (color >> 16) & 0xff;
1353 pixel[1] = (color >> 8) & 0xff;
1354 pixel[2] = color & 0xff;
1355 } else {
1356 pixel[0] = color & 0xff;
1357 pixel[1] = (color >> 8) & 0xff;
1358 pixel[2] = (color >> 16) & 0xff;
1359 }
1360 y += dy;
1361 if (y >= dx) {
1362 y -= dx;
1363 pixel += pixy;
1364 }
1365 }
1366 break;
1367 default: /* case 4 */
1368 for(; x < dx; x++, pixel += pixx) {
1369 *(Uint32*)pixel = color;
1370 y += dy;
1371 if (y >= dx) {
1372 y -= dx;
1373 pixel += pixy;
1374 }
1375 }
1376 break;
1377 }
1378
1379 /* Unlock surface */
1380 SDL_UnlockSurface(dst);
1381
1382 } else {
1383
1384 /* Alpha blending required - use single-pixel blits */
1385
1386 ax = ABS(dx) << 1;
1387 ay = ABS(dy) << 1;
1388 x = x1;
1389 y = y1;
1390 if (ax > ay) {
1391 int d = ay - (ax >> 1);
1392 while (x != x2) {
1393 pixelColor(dst, x, y, color);
1394 if (d > 0 || (d == 0 && sx == 1)) {
1395 y += sy;
1396 d -= ax;
1397 }
1398 x += sx;
1399 d += ay;
1400 }
1401 } else {
1402 int d = ax - (ay >> 1);
1403 while (y != y2) {
1404 pixelColor(dst, x, y, color);
1405 if (d > 0 || ((d == 0) && (sy == 1))) {
1406 x += sx;
1407 d -= ay;
1408 }
1409 y += sy;
1410 d += ax;
1411 }
1412 }
1413 pixelColor(dst, x, y, color);
1414
1415 }
1416
1417 return(0);
1418 }
1419
lineRGBA(SDL_Surface * dst,Sint16 x1,Sint16 y1,Sint16 x2,Sint16 y2,Uint8 r,Uint8 g,Uint8 b,Uint8 a)1420 int lineRGBA (SDL_Surface *dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
1421 {
1422 /* Draw */
1423 return(lineColor(dst, x1, y1, x2, y2, ((Uint32)r << 24) | ((Uint32)g << 16) | ((Uint32)b << 8) | (Uint32)a));
1424 }
1425
1426 /* AA Line */
1427
1428 #define AAlevels 256
1429 #define AAbits 8
1430
1431 /*
1432
1433 This implementation of the Wu antialiasing code is based on Mike Abrash's
1434 DDJ article which was reprinted as Chapter 42 of his Graphics Programming
1435 Black Book, but has been optimized to work with SDL and utilizes 32-bit
1436 fixed-point arithmetic. (A. Schiffler).
1437
1438 */
1439
aalineColorInt(SDL_Surface * dst,Sint16 x1,Sint16 y1,Sint16 x2,Sint16 y2,Uint32 color,int draw_endpoint)1440 int aalineColorInt (SDL_Surface *dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color, int draw_endpoint)
1441 {
1442 Sint32 xx0,yy0,xx1,yy1;
1443 int result;
1444 Uint32 intshift, erracc, erradj;
1445 Uint32 erracctmp, wgt, wgtcompmask;
1446 int dx, dy, tmp, xdir, y0p1, x0pxdir;
1447
1448 /* Clip line and test if we have to draw */
1449 if (!(clipLine(dst,&x1,&y1,&x2,&y2))) {
1450 return(0);
1451 }
1452
1453 /* Keep on working with 32bit numbers */
1454 xx0=x1;
1455 yy0=y1;
1456 xx1=x2;
1457 yy1=y2;
1458
1459 /* Reorder points if required */
1460 if (yy0 > yy1) {
1461 tmp = yy0; yy0 = yy1; yy1 = tmp;
1462 tmp = xx0; xx0 = xx1; xx1 = tmp;
1463 }
1464
1465 /* Calculate distance */
1466 dx = xx1 - xx0;
1467 dy = yy1 - yy0;
1468
1469 /* Adjust for negative dx and set xdir */
1470 if (dx >= 0) {
1471 xdir=1;
1472 } else {
1473 xdir=-1;
1474 dx=(-dx);
1475 }
1476
1477 /* Check for special cases */
1478 if (dx==0) {
1479 /* Vertical line */
1480 return (vlineColor(dst,x1,y1,y2,color));
1481 } else if (dy==0) {
1482 /* Horizontal line */
1483 return (hlineColor(dst,x1,x2,y1,color));
1484 } else if (dx==dy) {
1485 /* Diagonal line */
1486 return (lineColor(dst,x1,y1,x2,y2,color));
1487 }
1488
1489 /* Line is not horizontal, vertical or diagonal */
1490 result=0;
1491 /* Zero accumulator */
1492 erracc = 0;
1493 /* # of bits by which to shift erracc to get intensity level */
1494 intshift = 32 - AAbits;
1495 /* Mask used to flip all bits in an intensity weighting */
1496 wgtcompmask = AAlevels - 1;
1497
1498 /* Draw the initial pixel in the foreground color */
1499 result |= pixelColor (dst, x1, y1, color);
1500
1501 /* x-major or y-major? */
1502 if (dy > dx) {
1503
1504 /* y-major. Calculate 16-bit fixed point fractional part of a pixel that
1505 X advances every time Y advances 1 pixel, truncating the result so that
1506 we won't overrun the endpoint along the X axis */
1507 /* Not-so-portable version: erradj = ((Uint64)dx << 32) / (Uint64)dy; */
1508 erradj = ((dx << 16) / dy)<<16;
1509
1510 /* draw all pixels other than the first and last */
1511 x0pxdir=xx0+xdir;
1512 while (--dy) {
1513 erracctmp = erracc;
1514 erracc += erradj;
1515 if (erracc <= erracctmp) {
1516 /* rollover in error accumulator, x coord advances */
1517 xx0=x0pxdir;
1518 x0pxdir += xdir;
1519 }
1520 yy0++; /* y-major so always advance Y */
1521
1522 /* the AAbits most significant bits of erracc give us the intensity
1523 weighting for this pixel, and the complement of the weighting for
1524 the paired pixel. */
1525 wgt = (erracc >> intshift) & 255;
1526 result |= pixelColorWeight (dst, xx0, yy0, color, 255-wgt);
1527 result |= pixelColorWeight (dst, x0pxdir, yy0, color, wgt);
1528 }
1529
1530 } else {
1531
1532 /* x-major line. Calculate 16-bit fixed-point fractional part of a pixel
1533 that Y advances each time X advances 1 pixel, truncating the result so
1534 that we won't overrun the endpoint along the X axis. */
1535 /* Not-so-portable version: erradj = ((Uint64)dy << 32) / (Uint64)dx; */
1536 erradj = ((dy << 16) / dx)<<16;
1537
1538 /* draw all pixels other than the first and last */
1539 y0p1=yy0+1;
1540 while (--dx) {
1541
1542 erracctmp = erracc;
1543 erracc += erradj;
1544 if (erracc <= erracctmp) {
1545 /* Accumulator turned over, advance y */
1546 yy0=y0p1;
1547 y0p1++;
1548 }
1549 xx0 += xdir; /* x-major so always advance X */
1550 /* the AAbits most significant bits of erracc give us the intensity
1551 weighting for this pixel, and the complement of the weighting for
1552 the paired pixel. */
1553 wgt = (erracc >> intshift) & 255;
1554 result |= pixelColorWeight (dst, xx0, yy0, color, 255-wgt);
1555 result |= pixelColorWeight (dst, xx0, y0p1, color, wgt);
1556 }
1557 }
1558
1559 /* Do we have to draw the endpoint */
1560 if (draw_endpoint) {
1561 /* Draw final pixel, always exactly intersected by the line and doesn't
1562 need to be weighted. */
1563 result |= pixelColor (dst, x2, y2, color);
1564 }
1565
1566 return(result);
1567 }
1568
aalineColor(SDL_Surface * dst,Sint16 x1,Sint16 y1,Sint16 x2,Sint16 y2,Uint32 color)1569 int aalineColor (SDL_Surface *dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color)
1570 {
1571 return(aalineColorInt(dst,x1,y1,x2,y1,color,1));
1572 }
1573
aalineRGBA(SDL_Surface * dst,Sint16 x1,Sint16 y1,Sint16 x2,Sint16 y2,Uint8 r,Uint8 g,Uint8 b,Uint8 a)1574 int aalineRGBA (SDL_Surface *dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
1575 {
1576 return(aalineColorInt(dst, x1, y1, x2, y2, ((Uint32)r << 24) | ((Uint32)g << 16) | ((Uint32)b << 8) | (Uint32)a, 1));
1577 }
1578
1579
1580 /* ----- Circle */
1581
1582 /* Note: Based on algorithm from sge library, modified by A. Schiffler */
1583 /* with multiple pixel-draw removal and other minor speedup changes. */
1584
circleColor(SDL_Surface * dst,Sint16 x,Sint16 y,Sint16 r,Uint32 color)1585 int circleColor(SDL_Surface *dst, Sint16 x, Sint16 y, Sint16 r, Uint32 color)
1586 {
1587 int result;
1588 Sint16 x1,y1,x2,y2;
1589 Sint16 cx = 0;
1590 Sint16 cy = r;
1591 Sint16 ocx = (Sint16)0xffff;
1592 Sint16 ocy = (Sint16)0xffff;
1593 Sint16 df = 1 - r;
1594 Sint16 d_e = 3;
1595 Sint16 d_se = -2 * r + 5;
1596 Sint16 xpcx, xmcx, xpcy, xmcy;
1597 Sint16 ypcy, ymcy, ypcx, ymcx;
1598 Uint8 *colorptr;
1599
1600 /* Sanity check radius */
1601 if (r<0) {
1602 return(-1);
1603 }
1604
1605 /* Special case for r=0 - draw a point */
1606 if (r==0) {
1607 return(pixelColor (dst, x, y, color));
1608 }
1609
1610 /* Test if bounding box of circle is visible */
1611 x1=x-r;
1612 y1=y-r;
1613 x2=x+r;
1614 y2=y+r;
1615 if (!(clipLine(dst,&x1,&y1,&x2,&y2))) {
1616 return(0);
1617 }
1618
1619 /* Draw circle */
1620 result=0;
1621 /* Alpha Check */
1622 if ((color & 255) ==255) {
1623
1624 /* No Alpha - direct memory writes */
1625
1626 /* Setup color */
1627 colorptr=(Uint8 *)&color;
1628 if (SDL_BYTEORDER == SDL_BIG_ENDIAN) {
1629 color=SDL_MapRGBA(dst->format, colorptr[0], colorptr[1], colorptr[2], colorptr[3]);
1630 } else {
1631 color=SDL_MapRGBA(dst->format, colorptr[3], colorptr[2], colorptr[1], colorptr[0]);
1632 }
1633
1634 /* Lock surface */
1635 SDL_LockSurface(dst);
1636
1637 /* Draw */
1638 do {
1639 if ((ocy!=cy) || (ocx!=cx)) {
1640 xpcx=x+cx;
1641 xmcx=x-cx;
1642 if (cy>0) {
1643 ypcy=y+cy;
1644 ymcy=y-cy;
1645 result |= fastPixelColorNolock(dst,xmcx,ypcy,color);
1646 result |= fastPixelColorNolock(dst,xpcx,ypcy,color);
1647 result |= fastPixelColorNolock(dst,xmcx,ymcy,color);
1648 result |= fastPixelColorNolock(dst,xpcx,ymcy,color);
1649 } else {
1650 result |= fastPixelColorNolock(dst,xmcx,y,color);
1651 result |= fastPixelColorNolock(dst,xpcx,y,color);
1652 }
1653 ocy=cy;
1654 xpcy=x+cy;
1655 xmcy=x-cy;
1656 if (cx>0) {
1657 ypcx=y+cx;
1658 ymcx=y-cx;
1659 result |= fastPixelColorNolock(dst,xmcy,ypcx,color);
1660 result |= fastPixelColorNolock(dst,xpcy,ypcx,color);
1661 result |= fastPixelColorNolock(dst,xmcy,ymcx,color);
1662 result |= fastPixelColorNolock(dst,xpcy,ymcx,color);
1663 } else {
1664 result |= fastPixelColorNolock(dst,xmcy,y,color);
1665 result |= fastPixelColorNolock(dst,xpcy,y,color);
1666 }
1667 ocx=cx;
1668 }
1669 /* Update */
1670 if (df < 0) {
1671 df += d_e;
1672 d_e += 2;
1673 d_se += 2;
1674 } else {
1675 df += d_se;
1676 d_e += 2;
1677 d_se += 4;
1678 cy--;
1679 }
1680 cx++;
1681 } while(cx <= cy);
1682
1683 /* Unlock surface */
1684 SDL_UnlockSurface(dst);
1685
1686 } else {
1687
1688 /* Using Alpha - blended pixel blits */
1689
1690 do {
1691 /* Draw */
1692 if ((ocy!=cy) || (ocx!=cx)) {
1693 xpcx=x+cx;
1694 xmcx=x-cx;
1695 if (cy>0) {
1696 ypcy=y+cy;
1697 ymcy=y-cy;
1698 result |= pixelColor(dst,xmcx,ypcy,color);
1699 result |= pixelColor(dst,xpcx,ypcy,color);
1700 result |= pixelColor(dst,xmcx,ymcy,color);
1701 result |= pixelColor(dst,xpcx,ymcy,color);
1702 } else {
1703 result |= pixelColor(dst,xmcx,y,color);
1704 result |= pixelColor(dst,xpcx,y,color);
1705 }
1706 ocy=cy;
1707 xpcy=x+cy;
1708 xmcy=x-cy;
1709 if (cx>0) {
1710 ypcx=y+cx;
1711 ymcx=y-cx;
1712 result |= pixelColor(dst,xmcy,ypcx,color);
1713 result |= pixelColor(dst,xpcy,ypcx,color);
1714 result |= pixelColor(dst,xmcy,ymcx,color);
1715 result |= pixelColor(dst,xpcy,ymcx,color);
1716 } else {
1717 result |= pixelColor(dst,xmcy,y,color);
1718 result |= pixelColor(dst,xpcy,y,color);
1719 }
1720 ocx=cx;
1721 }
1722 /* Update */
1723 if (df < 0) {
1724 df += d_e;
1725 d_e += 2;
1726 d_se += 2;
1727 } else {
1728 df += d_se;
1729 d_e += 2;
1730 d_se += 4;
1731 cy--;
1732 }
1733 cx++;
1734 } while(cx <= cy);
1735
1736 } /* Alpha check */
1737
1738 return(result);
1739 }
1740
circleRGBA(SDL_Surface * dst,Sint16 x,Sint16 y,Sint16 rad,Uint8 r,Uint8 g,Uint8 b,Uint8 a)1741 int circleRGBA (SDL_Surface *dst, Sint16 x, Sint16 y, Sint16 rad, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
1742 {
1743 /* Draw */
1744 return(circleColor(dst, x, y, rad, ((Uint32)r << 24) | ((Uint32)g << 16) | ((Uint32)b << 8) | (Uint32)a));
1745 }
1746
1747 /* ----- AA Circle */
1748
1749 /* Low-speed antialiased circle implementation by drawing aalines. */
1750 /* Works best for larger radii. */
1751
aacircleColor(SDL_Surface * dst,Sint16 x,Sint16 y,Sint16 r,Uint32 color)1752 int aacircleColor(SDL_Surface *dst, Sint16 x, Sint16 y, Sint16 r, Uint32 color)
1753 {
1754 return (aaellipseColor(dst, x, y, r, r, color));
1755 }
1756
aacircleRGBA(SDL_Surface * dst,Sint16 x,Sint16 y,Sint16 rad,Uint8 r,Uint8 g,Uint8 b,Uint8 a)1757 int aacircleRGBA (SDL_Surface *dst, Sint16 x, Sint16 y, Sint16 rad, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
1758 {
1759 /* Draw */
1760 return(aaellipseColor(dst, x, y, rad, rad, ((Uint32)r << 24) | ((Uint32)g << 16) | ((Uint32)b << 8) | (Uint32)a));
1761 }
1762
1763 /* ----- Filled Circle */
1764
1765 /* Note: Based on algorithm from sge library with multiple-hline draw removal */
1766 /* and other speedup changes. */
1767
filledCircleColor(SDL_Surface * dst,Sint16 x,Sint16 y,Sint16 r,Uint32 color)1768 int filledCircleColor(SDL_Surface *dst, Sint16 x, Sint16 y, Sint16 r, Uint32 color)
1769 {
1770 int result;
1771 Sint16 x1,y1,x2,y2;
1772 Sint16 cx = 0;
1773 Sint16 cy = r;
1774 Sint16 ocx = (Sint16)0xffff;
1775 Sint16 ocy = (Sint16)0xffff;
1776 Sint16 df = 1 - r;
1777 Sint16 d_e = 3;
1778 Sint16 d_se = -2 * r + 5;
1779 Sint16 xpcx, xmcx, xpcy, xmcy;
1780 Sint16 ypcy, ymcy, ypcx, ymcx;
1781
1782 /* Sanity check radius */
1783 if (r<0) {
1784 return(-1);
1785 }
1786
1787 /* Special case for r=0 - draw a point */
1788 if (r==0) {
1789 return(pixelColor (dst, x, y, color));
1790 }
1791
1792 /* Test bounding box */
1793 x1=x-r;
1794 y1=y-r;
1795 x2=x+r;
1796 y2=y+r;
1797 if (!(clipLine(dst,&x1,&y1,&x2,&y2))) {
1798 return(0);
1799 }
1800
1801 /* Draw */
1802 result=0;
1803 do {
1804 xpcx=x+cx;
1805 xmcx=x-cx;
1806 xpcy=x+cy;
1807 xmcy=x-cy;
1808 if (ocy!=cy) {
1809 if (cy>0) {
1810 ypcy=y+cy;
1811 ymcy=y-cy;
1812 result |= hlineColor(dst,xmcx,xpcx,ypcy,color);
1813 result |= hlineColor(dst,xmcx,xpcx,ymcy,color);
1814 } else {
1815 result |= hlineColor(dst,xmcx,xpcx,y,color);
1816 }
1817 ocy=cy;
1818 }
1819 if (ocx!=cx) {
1820 if (cx!=cy) {
1821 if (cx>0) {
1822 ypcx=y+cx;
1823 ymcx=y-cx;
1824 result |= hlineColor(dst,xmcy,xpcy,ymcx,color);
1825 result |= hlineColor(dst,xmcy,xpcy,ypcx,color);
1826 } else {
1827 result |= hlineColor(dst,xmcy,xpcy,y,color);
1828 }
1829 }
1830 ocx=cx;
1831 }
1832 /* Update */
1833 if (df < 0) {
1834 df += d_e;
1835 d_e += 2;
1836 d_se += 2;
1837 } else {
1838 df += d_se;
1839 d_e += 2;
1840 d_se += 4;
1841 cy--;
1842 }
1843 cx++;
1844 } while(cx <= cy);
1845
1846 return(result);
1847 }
1848
filledCircleRGBA(SDL_Surface * dst,Sint16 x,Sint16 y,Sint16 rad,Uint8 r,Uint8 g,Uint8 b,Uint8 a)1849 int filledCircleRGBA (SDL_Surface *dst, Sint16 x, Sint16 y, Sint16 rad, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
1850 {
1851 /* Draw */
1852 return(filledCircleColor(dst, x, y, rad, ((Uint32)r << 24) | ((Uint32)g << 16) | ((Uint32)b << 8) | (Uint32)a));
1853 }
1854
1855
1856 /* ----- Ellipse */
1857
1858 /* Note: Based on algorithm from sge library with multiple-hline draw removal */
1859 /* and other speedup changes. */
1860
ellipseColor(SDL_Surface * dst,Sint16 x,Sint16 y,Sint16 rx,Sint16 ry,Uint32 color)1861 int ellipseColor (SDL_Surface *dst, Sint16 x, Sint16 y, Sint16 rx, Sint16 ry, Uint32 color)
1862 {
1863 int result;
1864 Sint16 x1, y1, x2, y2;
1865 int ix, iy;
1866 int h, i, j, k;
1867 int oh, oi, oj, ok;
1868 int xmh, xph, ypk, ymk;
1869 int xmi, xpi, ymj, ypj;
1870 int xmj, xpj, ymi, ypi;
1871 int xmk, xpk, ymh, yph;
1872 Uint8 *colorptr;
1873
1874 /* Sanity check radii */
1875 if ((rx<0) || (ry<0)) {
1876 return(-1);
1877 }
1878
1879 /* Special case for rx=0 - draw a vline */
1880 if (rx==0) {
1881 return(vlineColor (dst, x, y-ry, y+ry, color));
1882 }
1883 /* Special case for ry=0 - draw a hline */
1884 if (ry==0) {
1885 return(hlineColor (dst, x-rx, x+rx, y, color));
1886 }
1887
1888 /* Test bounding box */
1889 x1=x-rx;
1890 y1=y-ry;
1891 x2=x+rx;
1892 y2=y+ry;
1893 if (!(clipLine(dst,&x1,&y1,&x2,&y2))) {
1894 return(0);
1895 }
1896
1897 /* Init vars */
1898 oh = oi = oj = ok = 0xFFFF;
1899
1900 /* Draw */
1901 result=0;
1902 /* Check alpha */
1903 if ((color & 255)==255) {
1904
1905 /* No Alpha - direct memory writes */
1906
1907 /* Setup color */
1908 colorptr=(Uint8 *)&color;
1909 if (SDL_BYTEORDER == SDL_BIG_ENDIAN) {
1910 color=SDL_MapRGBA(dst->format, colorptr[0], colorptr[1], colorptr[2], colorptr[3]);
1911 } else {
1912 color=SDL_MapRGBA(dst->format, colorptr[3], colorptr[2], colorptr[1], colorptr[0]);
1913 }
1914
1915 /* Lock surface */
1916 SDL_LockSurface(dst);
1917
1918 if (rx > ry) {
1919 ix = 0;
1920 iy = rx * 64;
1921
1922 do {
1923 h = (ix + 32) >> 6;
1924 i = (iy + 32) >> 6;
1925 j = (h * ry) / rx;
1926 k = (i * ry) / rx;
1927
1928 if (((ok!=k) && (oj!=k)) || ((oj!=j) && (ok!=j)) || (k!=j)) {
1929 xph=x+h;
1930 xmh=x-h;
1931 if (k>0) {
1932 ypk=y+k;
1933 ymk=y-k;
1934 result |= fastPixelColorNolock (dst,xmh,ypk, color);
1935 result |= fastPixelColorNolock (dst,xph,ypk, color);
1936 result |= fastPixelColorNolock (dst,xmh,ymk, color);
1937 result |= fastPixelColorNolock (dst,xph,ymk, color);
1938 } else {
1939 result |= fastPixelColorNolock (dst,xmh,y, color);
1940 result |= fastPixelColorNolock (dst,xph,y, color);
1941 }
1942 ok=k;
1943 xpi=x+i;
1944 xmi=x-i;
1945 if (j>0) {
1946 ypj=y+j;
1947 ymj=y-j;
1948 result |= fastPixelColorNolock (dst,xmi,ypj, color);
1949 result |= fastPixelColorNolock (dst,xpi,ypj, color);
1950 result |= fastPixelColorNolock (dst,xmi,ymj, color);
1951 result |= fastPixelColorNolock (dst,xpi,ymj, color);
1952 } else {
1953 result |= fastPixelColorNolock (dst,xmi,y, color);
1954 result |= fastPixelColorNolock (dst,xpi,y, color);
1955 }
1956 oj=j;
1957 }
1958
1959 ix = ix + iy / rx;
1960 iy = iy - ix / rx;
1961
1962 } while (i > h);
1963 } else {
1964 ix = 0;
1965 iy = ry * 64;
1966
1967 do {
1968 h = (ix + 32) >> 6;
1969 i = (iy + 32) >> 6;
1970 j = (h * rx) / ry;
1971 k = (i * rx) / ry;
1972
1973 if (((oi!=i) && (oh!=i)) || ((oh!=h) && (oi!=h) && (i!=h))) {
1974 xmj=x-j;
1975 xpj=x+j;
1976 if (i>0) {
1977 ypi=y+i;
1978 ymi=y-i;
1979 result |= fastPixelColorNolock (dst,xmj,ypi,color);
1980 result |= fastPixelColorNolock (dst,xpj,ypi,color);
1981 result |= fastPixelColorNolock (dst,xmj,ymi,color);
1982 result |= fastPixelColorNolock (dst,xpj,ymi,color);
1983 } else {
1984 result |= fastPixelColorNolock (dst,xmj,y,color);
1985 result |= fastPixelColorNolock (dst,xpj,y,color);
1986 }
1987 oi=i;
1988 xmk=x-k;
1989 xpk=x+k;
1990 if (h>0) {
1991 yph=y+h;
1992 ymh=y-h;
1993 result |= fastPixelColorNolock (dst,xmk,yph,color);
1994 result |= fastPixelColorNolock (dst,xpk,yph,color);
1995 result |= fastPixelColorNolock (dst,xmk,ymh,color);
1996 result |= fastPixelColorNolock (dst,xpk,ymh,color);
1997 } else {
1998 result |= fastPixelColorNolock (dst,xmk,y,color);
1999 result |= fastPixelColorNolock (dst,xpk,y,color);
2000 }
2001 oh=h;
2002 }
2003
2004 ix = ix + iy / ry;
2005 iy = iy - ix / ry;
2006
2007 } while(i > h);
2008 }
2009
2010 /* Unlock surface */
2011 SDL_UnlockSurface(dst);
2012
2013 } else {
2014
2015 if (rx > ry) {
2016 ix = 0;
2017 iy = rx * 64;
2018
2019 do {
2020 h = (ix + 32) >> 6;
2021 i = (iy + 32) >> 6;
2022 j = (h * ry) / rx;
2023 k = (i * ry) / rx;
2024
2025 if (((ok!=k) && (oj!=k)) || ((oj!=j) && (ok!=j)) || (k!=j)) {
2026 xph=x+h;
2027 xmh=x-h;
2028 if (k>0) {
2029 ypk=y+k;
2030 ymk=y-k;
2031 result |= pixelColor (dst,xmh,ypk, color);
2032 result |= pixelColor (dst,xph,ypk, color);
2033 result |= pixelColor (dst,xmh,ymk, color);
2034 result |= pixelColor (dst,xph,ymk, color);
2035 } else {
2036 result |= pixelColor (dst,xmh,y, color);
2037 result |= pixelColor (dst,xph,y, color);
2038 }
2039 ok=k;
2040 xpi=x+i;
2041 xmi=x-i;
2042 if (j>0) {
2043 ypj=y+j;
2044 ymj=y-j;
2045 result |= pixelColor (dst,xmi,ypj, color);
2046 result |= pixelColor (dst,xpi,ypj, color);
2047 result |= pixelColor (dst,xmi,ymj, color);
2048 result |= pixelColor (dst,xpi,ymj, color);
2049 } else {
2050 result |= pixelColor (dst,xmi,y, color);
2051 result |= pixelColor (dst,xpi,y, color);
2052 }
2053 oj=j;
2054 }
2055
2056 ix = ix + iy / rx;
2057 iy = iy - ix / rx;
2058
2059 } while (i > h);
2060 } else {
2061 ix = 0;
2062 iy = ry * 64;
2063
2064 do {
2065 h = (ix + 32) >> 6;
2066 i = (iy + 32) >> 6;
2067 j = (h * rx) / ry;
2068 k = (i * rx) / ry;
2069
2070 if (((oi!=i) && (oh!=i)) || ((oh!=h) && (oi!=h) && (i!=h))) {
2071 xmj=x-j;
2072 xpj=x+j;
2073 if (i>0) {
2074 ypi=y+i;
2075 ymi=y-i;
2076 result |= pixelColor (dst,xmj,ypi,color);
2077 result |= pixelColor (dst,xpj,ypi,color);
2078 result |= pixelColor (dst,xmj,ymi,color);
2079 result |= pixelColor (dst,xpj,ymi,color);
2080 } else {
2081 result |= pixelColor (dst,xmj,y,color);
2082 result |= pixelColor (dst,xpj,y,color);
2083 }
2084 oi=i;
2085 xmk=x-k;
2086 xpk=x+k;
2087 if (h>0) {
2088 yph=y+h;
2089 ymh=y-h;
2090 result |= pixelColor (dst,xmk,yph,color);
2091 result |= pixelColor (dst,xpk,yph,color);
2092 result |= pixelColor (dst,xmk,ymh,color);
2093 result |= pixelColor (dst,xpk,ymh,color);
2094 } else {
2095 result |= pixelColor (dst,xmk,y,color);
2096 result |= pixelColor (dst,xpk,y,color);
2097 }
2098 oh=h;
2099 }
2100
2101 ix = ix + iy / ry;
2102 iy = iy - ix / ry;
2103
2104 } while(i > h);
2105 }
2106
2107 } /* Alpha check */
2108
2109 return(result);
2110 }
2111
ellipseRGBA(SDL_Surface * dst,Sint16 x,Sint16 y,Sint16 rx,Sint16 ry,Uint8 r,Uint8 g,Uint8 b,Uint8 a)2112 int ellipseRGBA (SDL_Surface *dst, Sint16 x, Sint16 y, Sint16 rx, Sint16 ry, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
2113 {
2114 /* Draw */
2115 return(ellipseColor(dst, x, y, rx, ry, ((Uint32)r << 24) | ((Uint32)g << 16) | ((Uint32)b << 8) | (Uint32)a));
2116 }
2117
2118 /* ----- AA Ellipse */
2119
2120 /* Low-speed antialiased ellipse implementation by drawing aalines. */
2121 /* Works best for larger radii. */
2122
aaellipseColor(SDL_Surface * dst,Sint16 x,Sint16 y,Sint16 rx,Sint16 ry,Uint32 color)2123 int aaellipseColor(SDL_Surface *dst, Sint16 x, Sint16 y, Sint16 rx, Sint16 ry, Uint32 color)
2124 {
2125 int result;
2126 Sint16 x1, y1, x2, y2;
2127 double angle;
2128 double deltaAngle;
2129 double drx, dry, dr;
2130 int posX, posY, oldPosX, oldPosY;
2131 int i, r;
2132
2133 /* Sanity check radii */
2134 if ((rx<0) || (ry<0)) {
2135 return(-1);
2136 }
2137
2138 /* Special case for rx=0 - draw a vline */
2139 if (rx==0) {
2140 return(vlineColor (dst, x, y-ry, y+ry, color));
2141 }
2142 /* Special case for ry=0 - draw a hline */
2143 if (ry==0) {
2144 return(hlineColor (dst, x-rx, x+rx, y, color));
2145 }
2146
2147 /* Test bounding box */
2148 x1=x-rx;
2149 y1=y-ry;
2150 x2=x+rx;
2151 y2=y+ry;
2152 if (!(clipLine(dst,&x1,&y1,&x2,&y2))) {
2153 return(0);
2154 }
2155
2156 /* Draw */
2157 r=(rx+ry)>>1;
2158 dr=(double)r;
2159 drx=(double)rx;
2160 dry=(double)ry;
2161 deltaAngle=(2*M_PI)/dr;
2162 angle=deltaAngle;
2163 oldPosX=x+rx;
2164 oldPosY=y;
2165
2166 result=0;
2167 for(i=0; i<r; i++) {
2168 posX=x+(int)(drx*cos(angle));
2169 posY=y+(int)(dry*sin(angle));
2170 result |= aalineColorInt (dst, oldPosX, oldPosY, posX, posY, color, 1);
2171 oldPosX=posX;
2172 oldPosY=posY;
2173 angle += deltaAngle;
2174 }
2175
2176 return (result);
2177 }
2178
aaellipseRGBA(SDL_Surface * dst,Sint16 x,Sint16 y,Sint16 rx,Sint16 ry,Uint8 r,Uint8 g,Uint8 b,Uint8 a)2179 int aaellipseRGBA (SDL_Surface *dst, Sint16 x, Sint16 y, Sint16 rx, Sint16 ry, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
2180 {
2181 /* Draw */
2182 return(aaellipseColor(dst, x, y, rx, ry, ((Uint32)r << 24) | ((Uint32)g << 16) | ((Uint32)b << 8) | (Uint32)a));
2183 }
2184
2185 /* ---- Filled Ellipse */
2186
2187 /* Note: Based on algorithm from sge library with multiple-hline draw removal */
2188 /* and other speedup changes. */
2189
filledEllipseColor(SDL_Surface * dst,Sint16 x,Sint16 y,Sint16 rx,Sint16 ry,Uint32 color)2190 int filledEllipseColor (SDL_Surface *dst, Sint16 x, Sint16 y, Sint16 rx, Sint16 ry, Uint32 color)
2191 {
2192 int result;
2193 Sint16 x1,y1,x2,y2;
2194 int ix, iy;
2195 int h, i, j, k;
2196 int oh, oi, oj, ok;
2197 int xmh, xph;
2198 int xmi, xpi;
2199 int xmj, xpj;
2200 int xmk, xpk;
2201
2202 /* Sanity check radii */
2203 if ((rx<0) || (ry<0)) {
2204 return(-1);
2205 }
2206
2207 /* Special case for rx=0 - draw a vline */
2208 if (rx==0) {
2209 return(vlineColor (dst, x, y-ry, y+ry, color));
2210 }
2211 /* Special case for ry=0 - draw a hline */
2212 if (ry==0) {
2213 return(hlineColor (dst, x-rx, x+rx, y, color));
2214 }
2215
2216 /* Test bounding box */
2217 x1=x-rx;
2218 y1=y-ry;
2219 x2=x+rx;
2220 y2=y+ry;
2221 if (!(clipLine(dst,&x1,&y1,&x2,&y2))) {
2222 return(0);
2223 }
2224
2225 /* Init vars */
2226 oh = oi = oj = ok = 0xFFFF;
2227
2228 /* Draw */
2229 result=0;
2230 if (rx > ry) {
2231 ix = 0;
2232 iy = rx * 64;
2233
2234 do {
2235 h = (ix + 32) >> 6;
2236 i = (iy + 32) >> 6;
2237 j = (h * ry) / rx;
2238 k = (i * ry) / rx;
2239
2240 if ((ok!=k) && (oj!=k)) {
2241 xph=x+h;
2242 xmh=x-h;
2243 if (k>0) {
2244 result |= hlineColor (dst,xmh,xph,y+k,color);
2245 result |= hlineColor (dst,xmh,xph,y-k,color);
2246 } else {
2247 result |= hlineColor (dst,xmh,xph,y,color);
2248 }
2249 ok=k;
2250 }
2251 if ((oj!=j) && (ok!=j) && (k!=j)) {
2252 xmi=x-i;
2253 xpi=x+i;
2254 if (j>0) {
2255 result |= hlineColor (dst,xmi,xpi,y+j,color);
2256 result |= hlineColor (dst,xmi,xpi,y-j,color);
2257 } else {
2258 result |= hlineColor (dst,xmi,xpi,y ,color);
2259 }
2260 oj=j;
2261 }
2262
2263 ix = ix + iy / rx;
2264 iy = iy - ix / rx;
2265
2266 } while (i > h);
2267 } else {
2268 ix = 0;
2269 iy = ry * 64;
2270
2271 do {
2272 h = (ix + 32) >> 6;
2273 i = (iy + 32) >> 6;
2274 j = (h * rx) / ry;
2275 k = (i * rx) / ry;
2276
2277 if ((oi!=i) && (oh!=i)) {
2278 xmj=x-j;
2279 xpj=x+j;
2280 if (i>0) {
2281 result |= hlineColor (dst,xmj,xpj,y+i,color);
2282 result |= hlineColor (dst,xmj,xpj,y-i,color);
2283 } else {
2284 result |= hlineColor (dst,xmj,xpj,y,color);
2285 }
2286 oi=i;
2287 }
2288 if ((oh!=h) && (oi!=h) && (i!=h)) {
2289 xmk=x-k;
2290 xpk=x+k;
2291 if (h>0) {
2292 result |= hlineColor (dst,xmk,xpk,y+h,color);
2293 result |= hlineColor (dst,xmk,xpk,y-h,color);
2294 } else {
2295 result |= hlineColor (dst,xmk,xpk,y ,color);
2296 }
2297 oh=h;
2298 }
2299
2300 ix = ix + iy / ry;
2301 iy = iy - ix / ry;
2302
2303 } while(i > h);
2304 }
2305
2306 return(result);
2307 }
2308
2309
filledEllipseRGBA(SDL_Surface * dst,Sint16 x,Sint16 y,Sint16 rx,Sint16 ry,Uint8 r,Uint8 g,Uint8 b,Uint8 a)2310 int filledEllipseRGBA (SDL_Surface *dst, Sint16 x, Sint16 y, Sint16 rx, Sint16 ry, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
2311 {
2312 /* Draw */
2313 return(filledEllipseColor(dst, x, y, rx, ry, ((Uint32)r << 24) | ((Uint32)g << 16) | ((Uint32)b << 8) | (Uint32)a));
2314 }
2315
2316 /* ---- Polygon */
2317
polygonColor(SDL_Surface * dst,Sint16 * vx,Sint16 * vy,int n,Uint32 color)2318 int polygonColor (SDL_Surface *dst, Sint16 *vx, Sint16 *vy, int n, Uint32 color)
2319 {
2320 int result;
2321 int i;
2322 Sint16 *x1, *y1, *x2, *y2;
2323
2324 /* Sanity check */
2325 if (n<3) {
2326 return(-1);
2327 }
2328
2329 /* Pointer setup */
2330 x1=x2=vx;
2331 y1=y2=vy;
2332 x2++;
2333 y2++;
2334
2335 /* Draw */
2336 result=0;
2337 for (i=1; i<n; i++) {
2338 result |= lineColor (dst, *x1, *y1, *x2, *y2, color);
2339 x1=x2;
2340 y1=y2;
2341 x2++;
2342 y2++;
2343 }
2344 result |= lineColor (dst, *x1, *y1, *vx, *vy, color);
2345
2346 return(result);
2347 }
2348
polygonRGBA(SDL_Surface * dst,Sint16 * vx,Sint16 * vy,int n,Uint8 r,Uint8 g,Uint8 b,Uint8 a)2349 int polygonRGBA (SDL_Surface *dst, Sint16 *vx, Sint16 *vy, int n, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
2350 {
2351 /* Draw */
2352 return(polygonColor(dst, vx, vy, n, ((Uint32)r << 24) | ((Uint32)g << 16) | ((Uint32)b << 8) | (Uint32)a));
2353 }
2354
2355 /* ---- Filled Polygon */
2356
2357 int gfxPrimitivesCompareInt(const void *a, const void *b);
2358
2359 static int *gfxPrimitivesPolyInts=NULL;
2360 static int gfxPrimitivesPolyAllocated=0;
2361
filledPolygonColor(SDL_Surface * dst,Sint16 * vx,Sint16 * vy,int n,int color)2362 int filledPolygonColor (SDL_Surface *dst, Sint16 *vx, Sint16 *vy, int n, int color)
2363 {
2364 int result;
2365 int i;
2366 int y;
2367 int miny, maxy;
2368 int x1, y1;
2369 int x2, y2;
2370 int ind1, ind2;
2371 int ints;
2372
2373 /* Sanity check */
2374 if (n<3) {
2375 return -1;
2376 }
2377
2378 /* Allocate temp array, only grow array */
2379 if (!gfxPrimitivesPolyAllocated) {
2380 gfxPrimitivesPolyInts = (int *) malloc(sizeof(int) * n);
2381 gfxPrimitivesPolyAllocated = n;
2382 } else {
2383 if (gfxPrimitivesPolyAllocated<n) {
2384 gfxPrimitivesPolyInts = (int *) realloc(gfxPrimitivesPolyInts, sizeof(int) * n);
2385 gfxPrimitivesPolyAllocated = n;
2386 }
2387 }
2388
2389 /* Determine Y maxima */
2390 miny = vy[0];
2391 maxy = vy[0];
2392 for (i=1; (i < n); i++) {
2393 if (vy[i] < miny) {
2394 miny = vy[i];
2395 } else if (vy[i] > maxy) {
2396 maxy = vy[i];
2397 }
2398 }
2399
2400 /* Draw, scanning y */
2401 result=0;
2402 for (y=miny; (y <= maxy); y++) {
2403 ints = 0;
2404 for (i=0; (i < n); i++) {
2405 if (!i) {
2406 ind1 = n-1;
2407 ind2 = 0;
2408 } else {
2409 ind1 = i-1;
2410 ind2 = i;
2411 }
2412 y1 = vy[ind1];
2413 y2 = vy[ind2];
2414 if (y1 < y2) {
2415 x1 = vx[ind1];
2416 x2 = vx[ind2];
2417 } else if (y1 > y2) {
2418 y2 = vy[ind1];
2419 y1 = vy[ind2];
2420 x2 = vx[ind1];
2421 x1 = vx[ind2];
2422 } else {
2423 continue;
2424 }
2425 if ((y >= y1) && (y < y2)) {
2426 gfxPrimitivesPolyInts[ints++] = (y-y1) * (x2-x1) / (y2-y1) + x1;
2427 } else if ((y == maxy) && (y > y1) && (y <= y2)) {
2428 gfxPrimitivesPolyInts[ints++] = (y-y1) * (x2-x1) / (y2-y1) + x1;
2429 }
2430 }
2431 qsort(gfxPrimitivesPolyInts, ints, sizeof(int), gfxPrimitivesCompareInt);
2432
2433 for (i=0; (i<ints); i+=2) {
2434 result |= hlineColor(dst, gfxPrimitivesPolyInts[i], gfxPrimitivesPolyInts[i+1], y, color);
2435 }
2436 }
2437
2438 return (result);
2439 }
2440
filledPolygonRGBA(SDL_Surface * dst,Sint16 * vx,Sint16 * vy,int n,Uint8 r,Uint8 g,Uint8 b,Uint8 a)2441 int filledPolygonRGBA (SDL_Surface *dst, Sint16 *vx, Sint16 *vy, int n, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
2442 {
2443 /* Draw */
2444 return(filledPolygonColor(dst, vx, vy, n, ((Uint32)r << 24) | ((Uint32)g << 16) | ((Uint32)b << 8) | (Uint32)a));
2445 }
2446
gfxPrimitivesCompareInt(const void * a,const void * b)2447 int gfxPrimitivesCompareInt(const void *a, const void *b)
2448 {
2449 return (*(const int *)a) - (*(const int *)b);
2450 }
2451
2452 /* ---- Character (8x8 internal font) */
2453
2454 static SDL_Surface *gfxPrimitivesFont[256];
2455 static Uint32 gfxPrimitivesFontColor[256];
2456
characterColor(SDL_Surface * dst,Sint16 x,Sint16 y,char c,Uint32 color)2457 int characterColor (SDL_Surface *dst, Sint16 x, Sint16 y, char c, Uint32 color)
2458 {
2459 SDL_Rect srect;
2460 SDL_Rect drect;
2461 int result;
2462 int ix, iy, k;
2463 unsigned char *charpos;
2464 unsigned char bits[8]={128,64,32,16,8,4,2,1};
2465 unsigned char *bitpos;
2466 Uint8 *curpos;
2467 int forced_redraw;
2468
2469 /* Setup source rectangle for 8x8 bitmap */
2470 srect.x=0;
2471 srect.y=0;
2472 srect.w=8;
2473 srect.h=8;
2474
2475 /* Setup destination rectangle for 8x8 bitmap */
2476 drect.x=x;
2477 drect.y=y;
2478 drect.w=8;
2479 drect.h=8;
2480
2481 /* Create new 8x8 bitmap surface if not already present */
2482 if (gfxPrimitivesFont[(unsigned char)c]==NULL) {
2483 gfxPrimitivesFont[(unsigned char)c]=SDL_CreateRGBSurface(SDL_SWSURFACE | SDL_HWSURFACE | SDL_SRCALPHA, 8, 8, 32, 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF);
2484 /* Check pointer */
2485 if (gfxPrimitivesFont[(unsigned char)c]==NULL) {
2486 return (-1);
2487 }
2488 /* Definitely redraw */
2489 forced_redraw=1;
2490 } else {
2491 forced_redraw=0;
2492 }
2493
2494 /* Check if color has changed */
2495 if ((gfxPrimitivesFontColor[(unsigned char)c]!=color) || (forced_redraw)) {
2496 /* Redraw character */
2497 SDL_SetAlpha (gfxPrimitivesFont[(unsigned char)c], SDL_SRCALPHA, 255);
2498 gfxPrimitivesFontColor[(unsigned char)c]=color;
2499
2500 /* Variable setup */
2501 k = (unsigned char)c;
2502 k *= 8;
2503 charpos=gfxPrimitivesFontdata;
2504 charpos += k;
2505
2506 /* Clear bitmap */
2507 curpos=(Uint8 *)gfxPrimitivesFont[(unsigned char)c]->pixels;
2508 memset (curpos, 0, 8*8*4);
2509
2510 /* Drawing loop */
2511 for (iy=0; iy<8; iy++) {
2512 bitpos=bits;
2513 for (ix=0; ix<8; ix++) {
2514 if ((*charpos & *bitpos)==*bitpos) {
2515 memcpy(curpos,&color,4);
2516 }
2517 bitpos++;
2518 curpos += 4;;
2519 }
2520 charpos++;
2521 }
2522 }
2523
2524 /* Draw bitmap onto destination surface */
2525 result=SDL_BlitSurface (gfxPrimitivesFont[(unsigned char)c], &srect, dst, &drect);
2526
2527 return(result);
2528 }
2529
characterRGBA(SDL_Surface * dst,Sint16 x,Sint16 y,char c,Uint8 r,Uint8 g,Uint8 b,Uint8 a)2530 int characterRGBA (SDL_Surface *dst, Sint16 x, Sint16 y, char c, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
2531 {
2532 /* Draw */
2533 return(characterColor(dst, x, y, c, ((Uint32)r << 24) | ((Uint32)g << 16) | ((Uint32)b << 8) | (Uint32)a));
2534 }
2535
stringColor(SDL_Surface * dst,Sint16 x,Sint16 y,char * c,Uint32 color)2536 int stringColor (SDL_Surface *dst, Sint16 x, Sint16 y, char *c, Uint32 color)
2537 {
2538 int result;
2539 int i,length;
2540 char *curchar;
2541 int curx;
2542
2543 length=strlen(c);
2544 curchar=c;
2545 curx=x;
2546 result=0;
2547 for (i=0; i<length; i++) {
2548 result |= characterColor(dst,curx,y,*curchar,color);
2549 curchar++;
2550 curx += 8;
2551 }
2552
2553 return(result);
2554 }
2555
stringRGBA(SDL_Surface * dst,Sint16 x,Sint16 y,char * c,Uint8 r,Uint8 g,Uint8 b,Uint8 a)2556 int stringRGBA (SDL_Surface *dst, Sint16 x, Sint16 y, char *c, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
2557 {
2558 /* Draw */
2559 return(stringColor(dst, x, y, c, ((Uint32)r << 24) | ((Uint32)g << 16) | ((Uint32)b << 8) | (Uint32)a));
2560 }
2561
2562