00001
00002
00003
00004
00005
00006
00007
00008
00009 #include <stdio.h>
00010 #include <stdlib.h>
00011 #include <math.h>
00012 #include <string.h>
00013
00014 #include "SDL_gfxPrimitives.h"
00015 #include "SDL_rotozoom.h"
00016 #include "SDL_gfxPrimitives_font.h"
00017
00018
00019
00020 #define DEFAULT_ALPHA_PIXEL_ROUTINE
00021 #undef EXPERIMENTAL_ALPHA_PIXEL_ROUTINE
00022
00023
00024
00025 #define clip_xmin(surface) surface->clip_rect.x
00026 #define clip_xmax(surface) surface->clip_rect.x+surface->clip_rect.w-1
00027 #define clip_ymin(surface) surface->clip_rect.y
00028 #define clip_ymax(surface) surface->clip_rect.y+surface->clip_rect.h-1
00029
00040 int fastPixelColorNolock(SDL_Surface * dst, Sint16 x, Sint16 y, Uint32 color)
00041 {
00042 int bpp;
00043 Uint8 *p;
00044
00045
00046
00047
00048 if ((x >= clip_xmin(dst)) && (x <= clip_xmax(dst)) && (y >= clip_ymin(dst)) && (y <= clip_ymax(dst))) {
00049
00050
00051
00052
00053 bpp = dst->format->BytesPerPixel;
00054 p = (Uint8 *) dst->pixels + y * dst->pitch + x * bpp;
00055 switch (bpp) {
00056 case 1:
00057 *p = color;
00058 break;
00059 case 2:
00060 *(Uint16 *) p = color;
00061 break;
00062 case 3:
00063 if (SDL_BYTEORDER == SDL_BIG_ENDIAN) {
00064 p[0] = (color >> 16) & 0xff;
00065 p[1] = (color >> 8) & 0xff;
00066 p[2] = color & 0xff;
00067 } else {
00068 p[0] = color & 0xff;
00069 p[1] = (color >> 8) & 0xff;
00070 p[2] = (color >> 16) & 0xff;
00071 }
00072 break;
00073 case 4:
00074 *(Uint32 *) p = color;
00075 break;
00076 }
00077
00078
00079 }
00080
00081 return (0);
00082 }
00083
00097 int fastPixelColorNolockNoclip(SDL_Surface * dst, Sint16 x, Sint16 y, Uint32 color)
00098 {
00099 int bpp;
00100 Uint8 *p;
00101
00102
00103
00104
00105 bpp = dst->format->BytesPerPixel;
00106 p = (Uint8 *) dst->pixels + y * dst->pitch + x * bpp;
00107 switch (bpp) {
00108 case 1:
00109 *p = color;
00110 break;
00111 case 2:
00112 *(Uint16 *) p = color;
00113 break;
00114 case 3:
00115 if (SDL_BYTEORDER == SDL_BIG_ENDIAN) {
00116 p[0] = (color >> 16) & 0xff;
00117 p[1] = (color >> 8) & 0xff;
00118 p[2] = color & 0xff;
00119 } else {
00120 p[0] = color & 0xff;
00121 p[1] = (color >> 8) & 0xff;
00122 p[2] = (color >> 16) & 0xff;
00123 }
00124 break;
00125 case 4:
00126 *(Uint32 *) p = color;
00127 break;
00128 }
00129
00130 return (0);
00131 }
00132
00143 int fastPixelColor(SDL_Surface * dst, Sint16 x, Sint16 y, Uint32 color)
00144 {
00145 int result;
00146
00147
00148
00149
00150 if (SDL_MUSTLOCK(dst)) {
00151 if (SDL_LockSurface(dst) < 0) {
00152 return (-1);
00153 }
00154 }
00155
00156 result = fastPixelColorNolock(dst, x, y, color);
00157
00158
00159
00160
00161 if (SDL_MUSTLOCK(dst)) {
00162 SDL_UnlockSurface(dst);
00163 }
00164
00165 return (result);
00166 }
00167
00181 int fastPixelRGBA(SDL_Surface * dst, Sint16 x, Sint16 y, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
00182 {
00183 Uint32 color;
00184
00185
00186
00187
00188 color = SDL_MapRGBA(dst->format, r, g, b, a);
00189
00190
00191
00192
00193 return (fastPixelColor(dst, x, y, color));
00194 }
00195
00209 int fastPixelRGBANolock(SDL_Surface * dst, Sint16 x, Sint16 y, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
00210 {
00211 Uint32 color;
00212
00213
00214
00215
00216 color = SDL_MapRGBA(dst->format, r, g, b, a);
00217
00218
00219
00220
00221 return (fastPixelColorNolock(dst, x, y, color));
00222 }
00223
00239 int _putPixelAlpha(SDL_Surface *dst, Sint16 x, Sint16 y, Uint32 color, Uint8 alpha)
00240 {
00241 SDL_PixelFormat *format;
00242 Uint32 Rmask, Gmask, Bmask, Amask;
00243 Uint32 Rshift, Gshift, Bshift, Ashift;
00244 Uint32 R, G, B, A;
00245
00246 if (dst == NULL)
00247 {
00248 return (-1);
00249 }
00250
00251 if (x >= clip_xmin(dst) && x <= clip_xmax(dst) &&
00252 y >= clip_ymin(dst) && y <= clip_ymax(dst))
00253 {
00254
00255 format = dst->format;
00256
00257 switch (format->BytesPerPixel) {
00258 case 1:
00259 {
00260 if (alpha == 255) {
00261 *((Uint8 *) dst->pixels + y * dst->pitch + x) = color;
00262 } else {
00263 Uint8 *pixel = (Uint8 *) dst->pixels + y * dst->pitch + x;
00264 SDL_Palette *palette = format->palette;
00265 SDL_Color *colors = palette->colors;
00266 SDL_Color dColor = colors[*pixel];
00267 SDL_Color sColor = colors[color];
00268 Uint8 dR = dColor.r;
00269 Uint8 dG = dColor.g;
00270 Uint8 dB = dColor.b;
00271 Uint8 sR = sColor.r;
00272 Uint8 sG = sColor.g;
00273 Uint8 sB = sColor.b;
00274
00275 dR = dR + ((sR - dR) * alpha >> 8);
00276 dG = dG + ((sG - dG) * alpha >> 8);
00277 dB = dB + ((sB - dB) * alpha >> 8);
00278
00279 *pixel = SDL_MapRGB(format, dR, dG, dB);
00280 }
00281 }
00282 break;
00283
00284 case 2:
00285 {
00286 if (alpha == 255) {
00287 *((Uint16 *) dst->pixels + y * dst->pitch / 2 + x) = color;
00288 } else {
00289 Uint16 *pixel = (Uint16 *) dst->pixels + y * dst->pitch / 2 + x;
00290 Uint32 dc = *pixel;
00291
00292 Rmask = format->Rmask;
00293 Gmask = format->Gmask;
00294 Bmask = format->Bmask;
00295 Amask = format->Amask;
00296 R = ((dc & Rmask) + (((color & Rmask) - (dc & Rmask)) * alpha >> 8)) & Rmask;
00297 G = ((dc & Gmask) + (((color & Gmask) - (dc & Gmask)) * alpha >> 8)) & Gmask;
00298 B = ((dc & Bmask) + (((color & Bmask) - (dc & Bmask)) * alpha >> 8)) & Bmask;
00299 if (Amask) {
00300 A = ((dc & Amask) + (((color & Amask) - (dc & Amask)) * alpha >> 8)) & Amask;
00301 }
00302 *pixel = R | G | B | A;
00303 }
00304 }
00305 break;
00306
00307 case 3:
00308 {
00309 Uint8 Rshift8, Gshift8, Bshift8, Ashift8;
00310 Uint8 *pixel = (Uint8 *) dst->pixels + y * dst->pitch + x * 3;
00311
00312 Rshift = format->Rshift;
00313 Gshift = format->Gshift;
00314 Bshift = format->Bshift;
00315 Ashift = format->Ashift;
00316
00317 Rshift8 = Rshift / 8;
00318 Gshift8 = Gshift / 8;
00319 Bshift8 = Bshift / 8;
00320 Ashift8 = Ashift / 8;
00321
00322 if (alpha == 255) {
00323 *(pixel + Rshift8) = color >> Rshift;
00324 *(pixel + Gshift8) = color >> Gshift;
00325 *(pixel + Bshift8) = color >> Bshift;
00326 *(pixel + Ashift8) = color >> Ashift;
00327 } else {
00328 Uint8 dR, dG, dB, dA = 0;
00329 Uint8 sR, sG, sB, sA = 0;
00330
00331 dR = *((pixel) + Rshift8);
00332 dG = *((pixel) + Gshift8);
00333 dB = *((pixel) + Bshift8);
00334 dA = *((pixel) + Ashift8);
00335
00336 sR = (color >> Rshift) & 0xff;
00337 sG = (color >> Gshift) & 0xff;
00338 sB = (color >> Bshift) & 0xff;
00339 sA = (color >> Ashift) & 0xff;
00340
00341 dR = dR + ((sR - dR) * alpha >> 8);
00342 dG = dG + ((sG - dG) * alpha >> 8);
00343 dB = dB + ((sB - dB) * alpha >> 8);
00344 dA = dA + ((sA - dA) * alpha >> 8);
00345
00346 *((pixel) + Rshift8) = dR;
00347 *((pixel) + Gshift8) = dG;
00348 *((pixel) + Bshift8) = dB;
00349 *((pixel) + Ashift8) = dA;
00350 }
00351 }
00352 break;
00353
00354 #ifdef DEFAULT_ALPHA_PIXEL_ROUTINE
00355
00356 case 4:
00357 {
00358 if (alpha == 255) {
00359 *((Uint32 *) dst->pixels + y * dst->pitch / 4 + x) = color;
00360 } else {
00361 Uint32 *pixel = (Uint32 *) dst->pixels + y * dst->pitch / 4 + x;
00362 Uint32 dc = *pixel;
00363
00364 Rmask = format->Rmask;
00365 Gmask = format->Gmask;
00366 Bmask = format->Bmask;
00367 Amask = format->Amask;
00368
00369 Rshift = format->Rshift;
00370 Gshift = format->Gshift;
00371 Bshift = format->Bshift;
00372 Ashift = format->Ashift;
00373
00374 A = 0;
00375 R = ((dc & Rmask) + (((((color & Rmask) - (dc & Rmask)) >> Rshift) * alpha >> 8) << Rshift)) & Rmask;
00376 G = ((dc & Gmask) + (((((color & Gmask) - (dc & Gmask)) >> Gshift) * alpha >> 8) << Gshift)) & Gmask;
00377 B = ((dc & Bmask) + (((((color & Bmask) - (dc & Bmask)) >> Bshift) * alpha >> 8) << Bshift)) & Bmask;
00378 if (Amask) {
00379 A = ((dc & Amask) + (((((color & Amask) - (dc & Amask)) >> Ashift) * alpha >> 8) << Ashift)) & Amask;
00380 }
00381 *pixel = R | G | B | A;
00382 }
00383 }
00384 break;
00385 #endif
00386
00387 #ifdef EXPERIMENTAL_ALPHA_PIXEL_ROUTINE
00388
00389 case 4:{
00390 if (alpha == 255) {
00391 *((Uint32 *) dst->pixels + y * dst->pitch / 4 + x) = color;
00392 } else {
00393 Uint32 *pixel = (Uint32 *) dst->pixels + y * dst->pitch / 4 + x;
00394 Uint32 dR, dG, dB, dA;
00395 Uint32 dc = *pixel;
00396
00397 Uint32 surfaceAlpha, preMultR, preMultG, preMultB;
00398 Uint32 aTmp;
00399
00400 Rmask = format->Rmask;
00401 Gmask = format->Gmask;
00402 Bmask = format->Bmask;
00403 Amask = format->Amask;
00404
00405 dR = (color & Rmask);
00406 dG = (color & Gmask);
00407 dB = (color & Bmask);
00408 dA = (color & Amask);
00409
00410 Rshift = format->Rshift;
00411 Gshift = format->Gshift;
00412 Bshift = format->Bshift;
00413 Ashift = format->Ashift;
00414
00415 preMultR = (alpha * (dR >> Rshift));
00416 preMultG = (alpha * (dG >> Gshift));
00417 preMultB = (alpha * (dB >> Bshift));
00418
00419 surfaceAlpha = ((dc & Amask) >> Ashift);
00420 aTmp = (255 - alpha);
00421 if (A = 255 - ((aTmp * (255 - surfaceAlpha)) >> 8 )) {
00422 aTmp *= surfaceAlpha;
00423 R = (preMultR + ((aTmp * ((dc & Rmask) >> Rshift)) >> 8)) / A << Rshift & Rmask;
00424 G = (preMultG + ((aTmp * ((dc & Gmask) >> Gshift)) >> 8)) / A << Gshift & Gmask;
00425 B = (preMultB + ((aTmp * ((dc & Bmask) >> Bshift)) >> 8)) / A << Bshift & Bmask;
00426 }
00427 *pixel = R | G | B | (A << Ashift & Amask);
00428
00429 }
00430 }
00431 break;
00432 #endif
00433 }
00434 }
00435
00436 return (0);
00437 }
00438
00449 int pixelColor(SDL_Surface * dst, Sint16 x, Sint16 y, Uint32 color)
00450 {
00451 Uint8 alpha;
00452 Uint32 mcolor;
00453 int result = 0;
00454
00455
00456
00457
00458 if (SDL_MUSTLOCK(dst)) {
00459 if (SDL_LockSurface(dst) < 0) {
00460 return (-1);
00461 }
00462 }
00463
00464
00465
00466
00467 alpha = color & 0x000000ff;
00468 mcolor =
00469 SDL_MapRGBA(dst->format, (color & 0xff000000) >> 24,
00470 (color & 0x00ff0000) >> 16, (color & 0x0000ff00) >> 8, alpha);
00471
00472
00473
00474
00475 result = _putPixelAlpha(dst, x, y, mcolor, alpha);
00476
00477
00478
00479
00480 if (SDL_MUSTLOCK(dst)) {
00481 SDL_UnlockSurface(dst);
00482 }
00483
00484 return (result);
00485 }
00486
00497 int pixelColorNolock(SDL_Surface * dst, Sint16 x, Sint16 y, Uint32 color)
00498 {
00499 Uint8 alpha;
00500 Uint32 mcolor;
00501 int result = 0;
00502
00503
00504
00505
00506 alpha = color & 0x000000ff;
00507 mcolor =
00508 SDL_MapRGBA(dst->format, (color & 0xff000000) >> 24,
00509 (color & 0x00ff0000) >> 16, (color & 0x0000ff00) >> 8, alpha);
00510
00511
00512
00513
00514 result = _putPixelAlpha(dst, x, y, mcolor, alpha);
00515
00516 return (result);
00517 }
00518
00519
00535 int _filledRectAlpha(SDL_Surface * dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color, Uint8 alpha)
00536 {
00537 SDL_PixelFormat *format;
00538 Uint32 Rmask, Bmask, Gmask, Amask;
00539 Uint32 Rshift, Bshift, Gshift, Ashift;
00540 Uint8 sR, sG, sB, sA;
00541 Uint32 R, G, B, A;
00542 Sint16 x, y;
00543
00544 format = dst->format;
00545 switch (format->BytesPerPixel) {
00546 case 1:
00547 {
00548 Uint8 *row, *pixel;
00549 Uint8 dR, dG, dB;
00550 SDL_Palette *palette = format->palette;
00551 SDL_Color *colors = palette->colors;
00552 sR = colors[color].r;
00553 sG = colors[color].g;
00554 sB = colors[color].b;
00555
00556 for (y = y1; y <= y2; y++) {
00557 row = (Uint8 *) dst->pixels + y * dst->pitch;
00558 for (x = x1; x <= x2; x++) {
00559 pixel = row + x;
00560
00561 dR = colors[*pixel].r;
00562 dG = colors[*pixel].g;
00563 dB = colors[*pixel].b;
00564
00565 dR = dR + ((sR - dR) * alpha >> 8);
00566 dG = dG + ((sG - dG) * alpha >> 8);
00567 dB = dB + ((sB - dB) * alpha >> 8);
00568
00569 *pixel = SDL_MapRGB(format, dR, dG, dB);
00570 }
00571 }
00572 }
00573 break;
00574
00575 case 2:
00576 {
00577 Uint16 *row, *pixel;
00578 Uint32 dR, dG, dB, dA;
00579 Rmask = format->Rmask;
00580 Gmask = format->Gmask;
00581 Bmask = format->Bmask;
00582 Amask = format->Amask;
00583
00584 dR = (color & Rmask);
00585 dG = (color & Gmask);
00586 dB = (color & Bmask);
00587 dA = (color & Amask);
00588
00589 A = 0;
00590
00591 for (y = y1; y <= y2; y++) {
00592 row = (Uint16 *) dst->pixels + y * dst->pitch / 2;
00593 for (x = x1; x <= x2; x++) {
00594 pixel = row + x;
00595
00596 R = ((*pixel & Rmask) + ((dR - (*pixel & Rmask)) * alpha >> 8)) & Rmask;
00597 G = ((*pixel & Gmask) + ((dG - (*pixel & Gmask)) * alpha >> 8)) & Gmask;
00598 B = ((*pixel & Bmask) + ((dB - (*pixel & Bmask)) * alpha >> 8)) & Bmask;
00599 if (Amask)
00600 {
00601 A = ((*pixel & Amask) + ((dA - (*pixel & Amask)) * alpha >> 8)) & Amask;
00602 *pixel = R | G | B | A;
00603 } else {
00604 *pixel = R | G | B;
00605 }
00606 }
00607 }
00608 }
00609 break;
00610
00611 case 3:
00612 {
00613 Uint8 *row, *pix;
00614 Uint8 dR, dG, dB, dA;
00615 Uint8 Rshift8, Gshift8, Bshift8, Ashift8;
00616
00617 Rshift = format->Rshift;
00618 Gshift = format->Gshift;
00619 Bshift = format->Bshift;
00620 Ashift = format->Ashift;
00621
00622 Rshift8 = Rshift / 8;
00623 Gshift8 = Gshift / 8;
00624 Bshift8 = Bshift / 8;
00625 Ashift8 = Ashift / 8;
00626
00627 sR = (color >> Rshift) & 0xff;
00628 sG = (color >> Gshift) & 0xff;
00629 sB = (color >> Bshift) & 0xff;
00630 sA = (color >> Ashift) & 0xff;
00631
00632 for (y = y1; y <= y2; y++) {
00633 row = (Uint8 *) dst->pixels + y * dst->pitch;
00634 for (x = x1; x <= x2; x++) {
00635 pix = row + x * 3;
00636
00637 dR = *((pix) + Rshift8);
00638 dG = *((pix) + Gshift8);
00639 dB = *((pix) + Bshift8);
00640 dA = *((pix) + Ashift8);
00641
00642 dR = dR + ((sR - dR) * alpha >> 8);
00643 dG = dG + ((sG - dG) * alpha >> 8);
00644 dB = dB + ((sB - dB) * alpha >> 8);
00645 dA = dA + ((sA - dA) * alpha >> 8);
00646
00647 *((pix) + Rshift8) = dR;
00648 *((pix) + Gshift8) = dG;
00649 *((pix) + Bshift8) = dB;
00650 *((pix) + Ashift8) = dA;
00651 }
00652 }
00653 }
00654 break;
00655
00656 #ifdef DEFAULT_ALPHA_PIXEL_ROUTINE
00657 case 4:
00658 {
00659 Uint32 *row, *pixel;
00660 Uint32 dR, dG, dB, dA;
00661
00662 Rmask = format->Rmask;
00663 Gmask = format->Gmask;
00664 Bmask = format->Bmask;
00665 Amask = format->Amask;
00666
00667 Rshift = format->Rshift;
00668 Gshift = format->Gshift;
00669 Bshift = format->Bshift;
00670 Ashift = format->Ashift;
00671
00672 dR = (color & Rmask);
00673 dG = (color & Gmask);
00674 dB = (color & Bmask);
00675 dA = (color & Amask);
00676
00677 for (y = y1; y <= y2; y++) {
00678 row = (Uint32 *) dst->pixels + y * dst->pitch / 4;
00679 for (x = x1; x <= x2; x++) {
00680 pixel = row + x;
00681
00682 R = ((*pixel & Rmask) + ((((dR - (*pixel & Rmask)) >> Rshift) * alpha >> 8) << Rshift)) & Rmask;
00683 G = ((*pixel & Gmask) + ((((dG - (*pixel & Gmask)) >> Gshift) * alpha >> 8) << Gshift)) & Gmask;
00684 B = ((*pixel & Bmask) + ((((dB - (*pixel & Bmask)) >> Bshift) * alpha >> 8) << Bshift)) & Bmask;
00685 if (Amask)
00686 {
00687 A = ((*pixel & Amask) + ((((dA - (*pixel & Amask)) >> Ashift) * alpha >> 8) << Ashift)) & Amask;
00688 *pixel = R | G | B | A;
00689 } else {
00690 *pixel = R | G | B;
00691 }
00692 }
00693 }
00694 }
00695 break;
00696 #endif
00697
00698 #ifdef EXPERIMENTAL_ALPHA_PIXEL_ROUTINE
00699 case 4:{
00700 Uint32 *row, *pixel;
00701 Uint32 dR, dG, dB, dA;
00702 Uint32 dc;
00703 Uint32 surfaceAlpha, preMultR, preMultG, preMultB;
00704 Uint32 aTmp;
00705
00706 Rmask = format->Rmask;
00707 Gmask = format->Gmask;
00708 Bmask = format->Bmask;
00709 Amask = format->Amask;
00710
00711 dR = (color & Rmask);
00712 dG = (color & Gmask);
00713 dB = (color & Bmask);
00714 dA = (color & Amask);
00715
00716 Rshift = format->Rshift;
00717 Gshift = format->Gshift;
00718 Bshift = format->Bshift;
00719 Ashift = format->Ashift;
00720
00721 preMultR = (alpha * (dR >> Rshift));
00722 preMultG = (alpha * (dG >> Gshift));
00723 preMultB = (alpha * (dB >> Bshift));
00724
00725 for (y = y1; y <= y2; y++) {
00726 row = (Uint32 *) dst->pixels + y * dst->pitch / 4;
00727 for (x = x1; x <= x2; x++) {
00728 pixel = row + x;
00729 dc = *pixel;
00730
00731 surfaceAlpha = ((dc & Amask) >> Ashift);
00732 aTmp = (255 - alpha);
00733 if (A = 255 - ((aTmp * (255 - surfaceAlpha)) >> 8 )) {
00734 aTmp *= surfaceAlpha;
00735 R = (preMultR + ((aTmp * ((dc & Rmask) >> Rshift)) >> 8)) / A << Rshift & Rmask;
00736 G = (preMultG + ((aTmp * ((dc & Gmask) >> Gshift)) >> 8)) / A << Gshift & Gmask;
00737 B = (preMultB + ((aTmp * ((dc & Bmask) >> Bshift)) >> 8)) / A << Bshift & Bmask;
00738 }
00739 *pixel = R | G | B | (A << Ashift & Amask);
00740
00741 }
00742 }
00743 }
00744 break;
00745 #endif
00746
00747 }
00748
00749 return (0);
00750 }
00751
00764 int filledRectAlpha(SDL_Surface * dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color)
00765 {
00766 Uint8 alpha;
00767 Uint32 mcolor;
00768 int result = 0;
00769
00770
00771
00772
00773 if (SDL_MUSTLOCK(dst)) {
00774 if (SDL_LockSurface(dst) < 0) {
00775 return (-1);
00776 }
00777 }
00778
00779
00780
00781
00782 alpha = color & 0x000000ff;
00783 mcolor =
00784 SDL_MapRGBA(dst->format, (color & 0xff000000) >> 24,
00785 (color & 0x00ff0000) >> 16, (color & 0x0000ff00) >> 8, alpha);
00786
00787
00788
00789
00790 result = _filledRectAlpha(dst, x1, y1, x2, y2, mcolor, alpha);
00791
00792
00793
00794
00795 if (SDL_MUSTLOCK(dst)) {
00796 SDL_UnlockSurface(dst);
00797 }
00798
00799 return (result);
00800 }
00801
00813 int _HLineAlpha(SDL_Surface * dst, Sint16 x1, Sint16 x2, Sint16 y, Uint32 color)
00814 {
00815 return (filledRectAlpha(dst, x1, y, x2, y, color));
00816 }
00817
00818
00830 int _VLineAlpha(SDL_Surface * dst, Sint16 x, Sint16 y1, Sint16 y2, Uint32 color)
00831 {
00832 return (filledRectAlpha(dst, x, y1, x, y2, color));
00833 }
00834
00846 int pixelColorWeight(SDL_Surface * dst, Sint16 x, Sint16 y, Uint32 color, Uint32 weight)
00847 {
00848 Uint32 a;
00849
00850
00851
00852
00853 a = (color & (Uint32) 0x000000ff);
00854
00855
00856
00857
00858 a = ((a * weight) >> 8);
00859
00860 return (pixelColor(dst, x, y, (color & (Uint32) 0xffffff00) | (Uint32) a));
00861 }
00862
00874 int pixelColorWeightNolock(SDL_Surface * dst, Sint16 x, Sint16 y, Uint32 color, Uint32 weight)
00875 {
00876 Uint32 a;
00877
00878
00879
00880
00881 a = (color & (Uint32) 0x000000ff);
00882
00883
00884
00885
00886 a = ((a * weight) >> 8);
00887
00888 return (pixelColorNolock(dst, x, y, (color & (Uint32) 0xffffff00) | (Uint32) a));
00889 }
00890
00904 int pixelRGBA(SDL_Surface * dst, Sint16 x, Sint16 y, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
00905 {
00906 Uint32 color;
00907
00908
00909
00910
00911 if (a == 255) {
00912
00913
00914
00915
00916
00917
00918 color = SDL_MapRGBA(dst->format, r, g, b, a);
00919
00920
00921
00922 return (fastPixelColor(dst, x, y, color));
00923 } else {
00924
00925
00926
00927
00928
00929
00930 return (pixelColor(dst, x, y, ((Uint32) r << 24) | ((Uint32) g << 16) | ((Uint32) b << 8) | (Uint32) a));
00931 }
00932 }
00933
00934
00950 int hlineColorStore(SDL_Surface * dst, Sint16 x1, Sint16 x2, Sint16 y, Uint32 color)
00951 {
00952 Sint16 left, right, top, bottom;
00953 Uint8 *pixel, *pixellast;
00954 int dx;
00955 int pixx, pixy;
00956 Sint16 w;
00957 Sint16 xtmp;
00958 int result = -1;
00959
00960
00961
00962
00963 if ((dst->clip_rect.w==0) || (dst->clip_rect.h==0)) {
00964 return(0);
00965 }
00966
00967
00968
00969
00970 if (x1 > x2) {
00971 xtmp = x1;
00972 x1 = x2;
00973 x2 = xtmp;
00974 }
00975
00976
00977
00978
00979
00980 left = dst->clip_rect.x;
00981 if (x2<left) {
00982 return(0);
00983 }
00984 right = dst->clip_rect.x + dst->clip_rect.w - 1;
00985 if (x1>right) {
00986 return(0);
00987 }
00988 top = dst->clip_rect.y;
00989 bottom = dst->clip_rect.y + dst->clip_rect.h - 1;
00990 if ((y<top) || (y>bottom)) {
00991 return (0);
00992 }
00993
00994
00995
00996
00997 if (x1 < left) {
00998 x1 = left;
00999 }
01000 if (x2 > right) {
01001 x2 = right;
01002 }
01003
01004
01005
01006
01007 w = x2 - x1;
01008
01009
01010
01011
01012 if (SDL_MUSTLOCK(dst)) {
01013 if (SDL_LockSurface(dst) < 0) {
01014 return (-1);
01015 }
01016 }
01017
01018
01019
01020
01021 dx = w;
01022 pixx = dst->format->BytesPerPixel;
01023 pixy = dst->pitch;
01024 pixel = ((Uint8 *) dst->pixels) + pixx * (int) x1 + pixy * (int) y;
01025
01026
01027
01028
01029 switch (dst->format->BytesPerPixel) {
01030 case 1:
01031 memset(pixel, color, dx+1);
01032 break;
01033 case 2:
01034 pixellast = pixel + dx + dx;
01035 for (; pixel <= pixellast; pixel += pixx) {
01036 *(Uint16 *) pixel = color;
01037 }
01038 break;
01039 case 3:
01040 pixellast = pixel + dx + dx + dx;
01041 for (; pixel <= pixellast; pixel += pixx) {
01042 if (SDL_BYTEORDER == SDL_BIG_ENDIAN) {
01043 pixel[0] = (color >> 16) & 0xff;
01044 pixel[1] = (color >> 8) & 0xff;
01045 pixel[2] = color & 0xff;
01046 } else {
01047 pixel[0] = color & 0xff;
01048 pixel[1] = (color >> 8) & 0xff;
01049 pixel[2] = (color >> 16) & 0xff;
01050 }
01051 }
01052 break;
01053 default:
01054 dx = dx + dx;
01055 pixellast = pixel + dx + dx;
01056 for (; pixel <= pixellast; pixel += pixx) {
01057 *(Uint32 *) pixel = color;
01058 }
01059 break;
01060 }
01061
01062
01063
01064
01065 SDL_UnlockSurface(dst);
01066
01067
01068
01069
01070 result = 0;
01071
01072 return (result);
01073 }
01074
01092 int hlineRGBAStore(SDL_Surface * dst, Sint16 x1, Sint16 x2, Sint16 y, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
01093 {
01094
01095
01096
01097 return (hlineColorStore(dst, x1, x2, y, ((Uint32) r << 24) | ((Uint32) g << 16) | ((Uint32) b << 8) | (Uint32) a));
01098 }
01099
01111 int hlineColor(SDL_Surface * dst, Sint16 x1, Sint16 x2, Sint16 y, Uint32 color)
01112 {
01113 Sint16 left, right, top, bottom;
01114 Uint8 *pixel, *pixellast;
01115 int dx;
01116 int pixx, pixy;
01117 Sint16 w;
01118 Sint16 xtmp;
01119 int result = -1;
01120 Uint8 *colorptr;
01121
01122
01123
01124
01125 if ((dst->clip_rect.w==0) || (dst->clip_rect.h==0)) {
01126 return(0);
01127 }
01128
01129
01130
01131
01132 if (x1 > x2) {
01133 xtmp = x1;
01134 x1 = x2;
01135 x2 = xtmp;
01136 }
01137
01138
01139
01140
01141
01142 left = dst->clip_rect.x;
01143 if (x2<left) {
01144 return(0);
01145 }
01146 right = dst->clip_rect.x + dst->clip_rect.w - 1;
01147 if (x1>right) {
01148 return(0);
01149 }
01150 top = dst->clip_rect.y;
01151 bottom = dst->clip_rect.y + dst->clip_rect.h - 1;
01152 if ((y<top) || (y>bottom)) {
01153 return (0);
01154 }
01155
01156
01157
01158
01159 if (x1 < left) {
01160 x1 = left;
01161 }
01162 if (x2 > right) {
01163 x2 = right;
01164 }
01165
01166
01167
01168
01169 w = x2 - x1;
01170
01171
01172
01173
01174 if ((color & 255) == 255) {
01175
01176
01177
01178
01179
01180
01181
01182
01183 colorptr = (Uint8 *) & color;
01184 if (SDL_BYTEORDER == SDL_BIG_ENDIAN) {
01185 color = SDL_MapRGBA(dst->format, colorptr[0], colorptr[1], colorptr[2], colorptr[3]);
01186 } else {
01187 color = SDL_MapRGBA(dst->format, colorptr[3], colorptr[2], colorptr[1], colorptr[0]);
01188 }
01189
01190
01191
01192
01193 if (SDL_MUSTLOCK(dst)) {
01194 if (SDL_LockSurface(dst) < 0) {
01195 return (-1);
01196 }
01197 }
01198
01199
01200
01201
01202 dx = w;
01203 pixx = dst->format->BytesPerPixel;
01204 pixy = dst->pitch;
01205 pixel = ((Uint8 *) dst->pixels) + pixx * (int) x1 + pixy * (int) y;
01206
01207
01208
01209
01210 switch (dst->format->BytesPerPixel) {
01211 case 1:
01212 memset(pixel, color, dx+1);
01213 break;
01214 case 2:
01215 pixellast = pixel + dx + dx;
01216 for (; pixel <= pixellast; pixel += pixx) {
01217 *(Uint16 *) pixel = color;
01218 }
01219 break;
01220 case 3:
01221 pixellast = pixel + dx + dx + dx;
01222 for (; pixel <= pixellast; pixel += pixx) {
01223 if (SDL_BYTEORDER == SDL_BIG_ENDIAN) {
01224 pixel[0] = (color >> 16) & 0xff;
01225 pixel[1] = (color >> 8) & 0xff;
01226 pixel[2] = color & 0xff;
01227 } else {
01228 pixel[0] = color & 0xff;
01229 pixel[1] = (color >> 8) & 0xff;
01230 pixel[2] = (color >> 16) & 0xff;
01231 }
01232 }
01233 break;
01234 default:
01235 dx = dx + dx;
01236 pixellast = pixel + dx + dx;
01237 for (; pixel <= pixellast; pixel += pixx) {
01238 *(Uint32 *) pixel = color;
01239 }
01240 break;
01241 }
01242
01243
01244
01245
01246 SDL_UnlockSurface(dst);
01247
01248
01249
01250
01251 result = 0;
01252
01253 } else {
01254
01255
01256
01257
01258 result = _HLineAlpha(dst, x1, x1 + w, y, color);
01259 }
01260
01261 return (result);
01262 }
01263
01278 int hlineRGBA(SDL_Surface * dst, Sint16 x1, Sint16 x2, Sint16 y, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
01279 {
01280
01281
01282
01283 return (hlineColor(dst, x1, x2, y, ((Uint32) r << 24) | ((Uint32) g << 16) | ((Uint32) b << 8) | (Uint32) a));
01284 }
01285
01297 int vlineColor(SDL_Surface * dst, Sint16 x, Sint16 y1, Sint16 y2, Uint32 color)
01298 {
01299 Sint16 left, right, top, bottom;
01300 Uint8 *pixel, *pixellast;
01301 int dy;
01302 int pixx, pixy;
01303 Sint16 h;
01304 Sint16 ytmp;
01305 int result = -1;
01306 Uint8 *colorptr;
01307
01308
01309
01310
01311 if ((dst->clip_rect.w==0) || (dst->clip_rect.h==0)) {
01312 return(0);
01313 }
01314
01315
01316
01317
01318 if (y1 > y2) {
01319 ytmp = y1;
01320 y1 = y2;
01321 y2 = ytmp;
01322 }
01323
01324
01325
01326
01327
01328 left = dst->clip_rect.x;
01329 right = dst->clip_rect.x + dst->clip_rect.w - 1;
01330 if ((x<left) || (x>right)) {
01331 return (0);
01332 }
01333 top = dst->clip_rect.y;
01334 if (y2<top) {
01335 return(0);
01336 }
01337 bottom = dst->clip_rect.y + dst->clip_rect.h - 1;
01338 if (y1>bottom) {
01339 return(0);
01340 }
01341
01342
01343
01344
01345 if (y1 < top) {
01346 y1 = top;
01347 }
01348 if (y2 > bottom) {
01349 y2 = bottom;
01350 }
01351
01352
01353
01354
01355 h = y2 - y1;
01356
01357
01358
01359
01360 if ((color & 255) == 255) {
01361
01362
01363
01364
01365
01366
01367
01368
01369 colorptr = (Uint8 *) & color;
01370 if (SDL_BYTEORDER == SDL_BIG_ENDIAN) {
01371 color = SDL_MapRGBA(dst->format, colorptr[0], colorptr[1], colorptr[2], colorptr[3]);
01372 } else {
01373 color = SDL_MapRGBA(dst->format, colorptr[3], colorptr[2], colorptr[1], colorptr[0]);
01374 }
01375
01376
01377
01378
01379 if (SDL_MUSTLOCK(dst)) {
01380 if (SDL_LockSurface(dst) < 0) {
01381 return (-1);
01382 }
01383 }
01384
01385
01386
01387
01388 dy = h;
01389 pixx = dst->format->BytesPerPixel;
01390 pixy = dst->pitch;
01391 pixel = ((Uint8 *) dst->pixels) + pixx * (int) x + pixy * (int) y1;
01392 pixellast = pixel + pixy * dy;
01393
01394
01395
01396
01397 switch (dst->format->BytesPerPixel) {
01398 case 1:
01399 for (; pixel <= pixellast; pixel += pixy) {
01400 *(Uint8 *) pixel = color;
01401 }
01402 break;
01403 case 2:
01404 for (; pixel <= pixellast; pixel += pixy) {
01405 *(Uint16 *) pixel = color;
01406 }
01407 break;
01408 case 3:
01409 for (; pixel <= pixellast; pixel += pixy) {
01410 if (SDL_BYTEORDER == SDL_BIG_ENDIAN) {
01411 pixel[0] = (color >> 16) & 0xff;
01412 pixel[1] = (color >> 8) & 0xff;
01413 pixel[2] = color & 0xff;
01414 } else {
01415 pixel[0] = color & 0xff;
01416 pixel[1] = (color >> 8) & 0xff;
01417 pixel[2] = (color >> 16) & 0xff;
01418 }
01419 }
01420 break;
01421 default:
01422 for (; pixel <= pixellast; pixel += pixy) {
01423 *(Uint32 *) pixel = color;
01424 }
01425 break;
01426 }
01427
01428
01429
01430
01431 SDL_UnlockSurface(dst);
01432
01433
01434
01435
01436 result = 0;
01437
01438 } else {
01439
01440
01441
01442
01443
01444 result = _VLineAlpha(dst, x, y1, y1 + h, color);
01445
01446 }
01447
01448 return (result);
01449 }
01450
01465 int vlineRGBA(SDL_Surface * dst, Sint16 x, Sint16 y1, Sint16 y2, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
01466 {
01467
01468
01469
01470 return (vlineColor(dst, x, y1, y2, ((Uint32) r << 24) | ((Uint32) g << 16) | ((Uint32) b << 8) | (Uint32) a));
01471 }
01472
01485 int rectangleColor(SDL_Surface * dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color)
01486 {
01487 int result;
01488 Sint16 w, h, xtmp, ytmp;
01489
01490
01491
01492
01493 if ((dst->clip_rect.w==0) || (dst->clip_rect.h==0)) {
01494 return(0);
01495 }
01496
01497
01498
01499
01500 if (x1 > x2) {
01501 xtmp = x1;
01502 x1 = x2;
01503 x2 = xtmp;
01504 }
01505
01506
01507
01508
01509 if (y1 > y2) {
01510 ytmp = y1;
01511 y1 = y2;
01512 y2 = ytmp;
01513 }
01514
01515
01516
01517
01518 w = x2 - x1;
01519 h = y2 - y1;
01520
01521
01522
01523
01524 if ((w < 0) || (h < 0)) {
01525 return (0);
01526 }
01527
01528
01529
01530
01531 if (x1 == x2) {
01532 if (y1 == y2) {
01533 return (pixelColor(dst, x1, y1, color));
01534 } else {
01535 return (vlineColor(dst, x1, y1, y2, color));
01536 }
01537 } else {
01538 if (y1 == y2) {
01539 return (hlineColor(dst, x1, x2, y1, color));
01540 }
01541 }
01542
01543
01544
01545
01546 result = 0;
01547 result |= hlineColor(dst, x1, x2, y1, color);
01548 result |= hlineColor(dst, x1, x2, y2, color);
01549 y1 += 1;
01550 y2 -= 1;
01551 if (y1<=y2) {
01552 result |= vlineColor(dst, x1, y1, y2, color);
01553 result |= vlineColor(dst, x2, y1, y2, color);
01554 }
01555 return (result);
01556
01557 }
01558
01574 int rectangleRGBA(SDL_Surface * dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
01575 {
01576
01577
01578
01579 return (rectangleColor
01580 (dst, x1, y1, x2, y2, ((Uint32) r << 24) | ((Uint32) g << 16) | ((Uint32) b << 8) | (Uint32) a));
01581 }
01582
01583
01584
01585
01586
01587
01588 #define CLIP_LEFT_EDGE 0x1
01589 #define CLIP_RIGHT_EDGE 0x2
01590 #define CLIP_BOTTOM_EDGE 0x4
01591 #define CLIP_TOP_EDGE 0x8
01592 #define CLIP_INSIDE(a) (!a)
01593 #define CLIP_REJECT(a,b) (a&b)
01594 #define CLIP_ACCEPT(a,b) (!(a|b))
01595
01608 static int _clipEncode(Sint16 x, Sint16 y, Sint16 left, Sint16 top, Sint16 right, Sint16 bottom)
01609 {
01610 int code = 0;
01611
01612 if (x < left) {
01613 code |= CLIP_LEFT_EDGE;
01614 } else if (x > right) {
01615 code |= CLIP_RIGHT_EDGE;
01616 }
01617 if (y < top) {
01618 code |= CLIP_TOP_EDGE;
01619 } else if (y > bottom) {
01620 code |= CLIP_BOTTOM_EDGE;
01621 }
01622 return code;
01623 }
01624
01634 static int _clipLine(SDL_Surface * dst, Sint16 * x1, Sint16 * y1, Sint16 * x2, Sint16 * y2)
01635 {
01636 Sint16 left, right, top, bottom;
01637 int code1, code2;
01638 int draw = 0;
01639 Sint16 swaptmp;
01640 float m;
01641
01642
01643
01644
01645 left = dst->clip_rect.x;
01646 right = dst->clip_rect.x + dst->clip_rect.w - 1;
01647 top = dst->clip_rect.y;
01648 bottom = dst->clip_rect.y + dst->clip_rect.h - 1;
01649
01650 while (1) {
01651 code1 = _clipEncode(*x1, *y1, left, top, right, bottom);
01652 code2 = _clipEncode(*x2, *y2, left, top, right, bottom);
01653 if (CLIP_ACCEPT(code1, code2)) {
01654 draw = 1;
01655 break;
01656 } else if (CLIP_REJECT(code1, code2))
01657 break;
01658 else {
01659 if (CLIP_INSIDE(code1)) {
01660 swaptmp = *x2;
01661 *x2 = *x1;
01662 *x1 = swaptmp;
01663 swaptmp = *y2;
01664 *y2 = *y1;
01665 *y1 = swaptmp;
01666 swaptmp = code2;
01667 code2 = code1;
01668 code1 = swaptmp;
01669 }
01670 if (*x2 != *x1) {
01671 m = (*y2 - *y1) / (float) (*x2 - *x1);
01672 } else {
01673 m = 1.0f;
01674 }
01675 if (code1 & CLIP_LEFT_EDGE) {
01676 *y1 += (Sint16) ((left - *x1) * m);
01677 *x1 = left;
01678 } else if (code1 & CLIP_RIGHT_EDGE) {
01679 *y1 += (Sint16) ((right - *x1) * m);
01680 *x1 = right;
01681 } else if (code1 & CLIP_BOTTOM_EDGE) {
01682 if (*x2 != *x1) {
01683 *x1 += (Sint16) ((bottom - *y1) / m);
01684 }
01685 *y1 = bottom;
01686 } else if (code1 & CLIP_TOP_EDGE) {
01687 if (*x2 != *x1) {
01688 *x1 += (Sint16) ((top - *y1) / m);
01689 }
01690 *y1 = top;
01691 }
01692 }
01693 }
01694
01695 return draw;
01696 }
01697
01710 int boxColor(SDL_Surface * dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color)
01711 {
01712 Sint16 left, right, top, bottom;
01713 Uint8 *pixel, *pixellast;
01714 int x, dx;
01715 int dy;
01716 int pixx, pixy;
01717 Sint16 w, h, tmp;
01718 int result;
01719 Uint8 *colorptr;
01720
01721
01722
01723
01724 if ((dst->clip_rect.w==0) || (dst->clip_rect.h==0)) {
01725 return(0);
01726 }
01727
01728
01729
01730
01731
01732 if (x1 > x2) {
01733 tmp = x1;
01734 x1 = x2;
01735 x2 = tmp;
01736 }
01737 if (y1 > y2) {
01738 tmp = y1;
01739 y1 = y2;
01740 y2 = tmp;
01741 }
01742
01743
01744
01745
01746
01747 left = dst->clip_rect.x;
01748 if (x2<left) {
01749 return(0);
01750 }
01751 right = dst->clip_rect.x + dst->clip_rect.w - 1;
01752 if (x1>right) {
01753 return(0);
01754 }
01755 top = dst->clip_rect.y;
01756 if (y2<top) {
01757 return(0);
01758 }
01759 bottom = dst->clip_rect.y + dst->clip_rect.h - 1;
01760 if (y1>bottom) {
01761 return(0);
01762 }
01763
01764
01765 if (x1<left) {
01766 x1=left;
01767 } else if (x1>right) {
01768 x1=right;
01769 }
01770 if (x2<left) {
01771 x2=left;
01772 } else if (x2>right) {
01773 x2=right;
01774 }
01775 if (y1<top) {
01776 y1=top;
01777 } else if (y1>bottom) {
01778 y1=bottom;
01779 }
01780 if (y2<top) {
01781 y2=top;
01782 } else if (y2>bottom) {
01783 y2=bottom;
01784 }
01785
01786
01787
01788
01789 if (x1 == x2) {
01790 if (y1 == y2) {
01791 return (pixelColor(dst, x1, y1, color));
01792 } else {
01793 return (vlineColor(dst, x1, y1, y2, color));
01794 }
01795 }
01796 if (y1 == y2) {
01797 return (hlineColor(dst, x1, x2, y1, color));
01798 }
01799
01800
01801
01802
01803 w = x2 - x1;
01804 h = y2 - y1;
01805
01806
01807
01808
01809 if ((color & 255) == 255) {
01810
01811
01812
01813
01814
01815
01816
01817
01818 colorptr = (Uint8 *) & color;
01819 if (SDL_BYTEORDER == SDL_BIG_ENDIAN) {
01820 color = SDL_MapRGBA(dst->format, colorptr[0], colorptr[1], colorptr[2], colorptr[3]);
01821 } else {
01822 color = SDL_MapRGBA(dst->format, colorptr[3], colorptr[2], colorptr[1], colorptr[0]);
01823 }
01824
01825
01826
01827
01828 if (SDL_MUSTLOCK(dst)) {
01829 if (SDL_LockSurface(dst) < 0) {
01830 return (-1);
01831 }
01832 }
01833
01834
01835
01836
01837 dx = w;
01838 dy = h;
01839 pixx = dst->format->BytesPerPixel;
01840 pixy = dst->pitch;
01841 pixel = ((Uint8 *) dst->pixels) + pixx * (int) x1 + pixy * (int) y1;
01842 pixellast = pixel + pixx * dx + pixy * dy;
01843 dx++;
01844
01845
01846
01847
01848 switch (dst->format->BytesPerPixel) {
01849 case 1:
01850 for (; pixel <= pixellast; pixel += pixy) {
01851 memset(pixel, (Uint8) color, dx);
01852 }
01853 break;
01854 case 2:
01855 pixy -= (pixx * dx);
01856 for (; pixel <= pixellast; pixel += pixy) {
01857 for (x = 0; x < dx; x++) {
01858 *(Uint16*) pixel = color;
01859 pixel += pixx;
01860 }
01861 }
01862 break;
01863 case 3:
01864 pixy -= (pixx * dx);
01865 for (; pixel <= pixellast; pixel += pixy) {
01866 for (x = 0; x < dx; x++) {
01867 if (SDL_BYTEORDER == SDL_BIG_ENDIAN) {
01868 pixel[0] = (color >> 16) & 0xff;
01869 pixel[1] = (color >> 8) & 0xff;
01870 pixel[2] = color & 0xff;
01871 } else {
01872 pixel[0] = color & 0xff;
01873 pixel[1] = (color >> 8) & 0xff;
01874 pixel[2] = (color >> 16) & 0xff;
01875 }
01876 pixel += pixx;
01877 }
01878 }
01879 break;
01880 default:
01881 pixy -= (pixx * dx);
01882 for (; pixel <= pixellast; pixel += pixy) {
01883 for (x = 0; x < dx; x++) {
01884 *(Uint32 *) pixel = color;
01885 pixel += pixx;
01886 }
01887 }
01888 break;
01889 }
01890
01891
01892
01893
01894 SDL_UnlockSurface(dst);
01895
01896 result = 0;
01897
01898 } else {
01899
01900 result = filledRectAlpha(dst, x1, y1, x1 + w, y1 + h, color);
01901
01902 }
01903
01904 return (result);
01905 }
01906
01922 int boxRGBA(SDL_Surface * dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
01923 {
01924
01925
01926
01927 return (boxColor(dst, x1, y1, x2, y2, ((Uint32) r << 24) | ((Uint32) g << 16) | ((Uint32) b << 8) | (Uint32) a));
01928 }
01929
01930
01931
01932
01933
01934
01935
01936 #define ABS(a) (((a)<0) ? -(a) : (a))
01937
01950 int lineColor(SDL_Surface * dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color)
01951 {
01952 int pixx, pixy;
01953 int x, y;
01954 int dx, dy;
01955 int ax, ay;
01956 int sx, sy;
01957 int swaptmp;
01958 Uint8 *pixel;
01959 Uint8 *colorptr;
01960
01961
01962
01963
01964 if (!(_clipLine(dst, &x1, &y1, &x2, &y2))) {
01965 return (0);
01966 }
01967
01968
01969
01970
01971 if (x1 == x2) {
01972 if (y1 < y2) {
01973 return (vlineColor(dst, x1, y1, y2, color));
01974 } else if (y1 > y2) {
01975 return (vlineColor(dst, x1, y2, y1, color));
01976 } else {
01977 return (pixelColor(dst, x1, y1, color));
01978 }
01979 }
01980 if (y1 == y2) {
01981 if (x1 < x2) {
01982 return (hlineColor(dst, x1, x2, y1, color));
01983 } else if (x1 > x2) {
01984 return (hlineColor(dst, x2, x1, y1, color));
01985 }
01986 }
01987
01988
01989
01990
01991 dx = x2 - x1;
01992 dy = y2 - y1;
01993 sx = (dx >= 0) ? 1 : -1;
01994 sy = (dy >= 0) ? 1 : -1;
01995
01996
01997 if (SDL_MUSTLOCK(dst)) {
01998 if (SDL_LockSurface(dst) < 0) {
01999 return (-1);
02000 }
02001 }
02002
02003
02004
02005
02006 if ((color & 255) == 255) {
02007
02008
02009
02010
02011
02012
02013
02014
02015 colorptr = (Uint8 *) & color;
02016 if (SDL_BYTEORDER == SDL_BIG_ENDIAN) {
02017 color = SDL_MapRGBA(dst->format, colorptr[0], colorptr[1], colorptr[2], colorptr[3]);
02018 } else {
02019 color = SDL_MapRGBA(dst->format, colorptr[3], colorptr[2], colorptr[1], colorptr[0]);
02020 }
02021
02022
02023
02024
02025 dx = sx * dx + 1;
02026 dy = sy * dy + 1;
02027 pixx = dst->format->BytesPerPixel;
02028 pixy = dst->pitch;
02029 pixel = ((Uint8 *) dst->pixels) + pixx * (int) x1 + pixy * (int) y1;
02030 pixx *= sx;
02031 pixy *= sy;
02032 if (dx < dy) {
02033 swaptmp = dx;
02034 dx = dy;
02035 dy = swaptmp;
02036 swaptmp = pixx;
02037 pixx = pixy;
02038 pixy = swaptmp;
02039 }
02040
02041
02042
02043
02044 x = 0;
02045 y = 0;
02046 switch (dst->format->BytesPerPixel) {
02047 case 1:
02048 for (; x < dx; x++, pixel += pixx) {
02049 *pixel = color;
02050 y += dy;
02051 if (y >= dx) {
02052 y -= dx;
02053 pixel += pixy;
02054 }
02055 }
02056 break;
02057 case 2:
02058 for (; x < dx; x++, pixel += pixx) {
02059 *(Uint16 *) pixel = color;
02060 y += dy;
02061 if (y >= dx) {
02062 y -= dx;
02063 pixel += pixy;
02064 }
02065 }
02066 break;
02067 case 3:
02068 for (; x < dx; x++, pixel += pixx) {
02069 if (SDL_BYTEORDER == SDL_BIG_ENDIAN) {
02070 pixel[0] = (color >> 16) & 0xff;
02071 pixel[1] = (color >> 8) & 0xff;
02072 pixel[2] = color & 0xff;
02073 } else {
02074 pixel[0] = color & 0xff;
02075 pixel[1] = (color >> 8) & 0xff;
02076 pixel[2] = (color >> 16) & 0xff;
02077 }
02078 y += dy;
02079 if (y >= dx) {
02080 y -= dx;
02081 pixel += pixy;
02082 }
02083 }
02084 break;
02085 default:
02086 for (; x < dx; x++, pixel += pixx) {
02087 *(Uint32 *) pixel = color;
02088 y += dy;
02089 if (y >= dx) {
02090 y -= dx;
02091 pixel += pixy;
02092 }
02093 }
02094 break;
02095 }
02096
02097 } else {
02098
02099
02100
02101
02102
02103 ax = ABS(dx) << 1;
02104 ay = ABS(dy) << 1;
02105 x = x1;
02106 y = y1;
02107 if (ax > ay) {
02108 int d = ay - (ax >> 1);
02109
02110 while (x != x2) {
02111 pixelColorNolock (dst, x, y, color);
02112 if (d > 0 || (d == 0 && sx == 1)) {
02113 y += sy;
02114 d -= ax;
02115 }
02116 x += sx;
02117 d += ay;
02118 }
02119 } else {
02120 int d = ax - (ay >> 1);
02121
02122 while (y != y2) {
02123 pixelColorNolock (dst, x, y, color);
02124 if (d > 0 || ((d == 0) && (sy == 1))) {
02125 x += sx;
02126 d -= ay;
02127 }
02128 y += sy;
02129 d += ax;
02130 }
02131 }
02132 pixelColorNolock (dst, x, y, color);
02133
02134 }
02135
02136
02137 if (SDL_MUSTLOCK(dst)) {
02138 SDL_UnlockSurface(dst);
02139 }
02140
02141 return (0);
02142 }
02143
02159 int lineRGBA(SDL_Surface * dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
02160 {
02161
02162
02163
02164 return (lineColor(dst, x1, y1, x2, y2, ((Uint32) r << 24) | ((Uint32) g << 16) | ((Uint32) b << 8) | (Uint32) a));
02165 }
02166
02167
02168
02169 #define AAlevels 256
02170 #define AAbits 8
02171
02192 int _aalineColor(SDL_Surface * dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color, int draw_endpoint)
02193 {
02194 Sint32 xx0, yy0, xx1, yy1;
02195 int result;
02196 Uint32 intshift, erracc, erradj;
02197 Uint32 erracctmp, wgt, wgtcompmask;
02198 int dx, dy, tmp, xdir, y0p1, x0pxdir;
02199
02200
02201
02202
02203 if ((dst->clip_rect.w==0) || (dst->clip_rect.h==0)) {
02204 return(0);
02205 }
02206
02207
02208
02209
02210 if (!(_clipLine(dst, &x1, &y1, &x2, &y2))) {
02211 return (0);
02212 }
02213
02214
02215
02216
02217 xx0 = x1;
02218 yy0 = y1;
02219 xx1 = x2;
02220 yy1 = y2;
02221
02222
02223
02224
02225 if (yy0 > yy1) {
02226 tmp = yy0;
02227 yy0 = yy1;
02228 yy1 = tmp;
02229 tmp = xx0;
02230 xx0 = xx1;
02231 xx1 = tmp;
02232 }
02233
02234
02235
02236
02237 dx = xx1 - xx0;
02238 dy = yy1 - yy0;
02239
02240
02241
02242
02243 if (dx >= 0) {
02244 xdir = 1;
02245 } else {
02246 xdir = -1;
02247 dx = (-dx);
02248 }
02249
02250
02251
02252
02253 if (dx == 0) {
02254
02255
02256
02257 if (draw_endpoint)
02258 {
02259 return (vlineColor(dst, x1, y1, y2, color));
02260 } else {
02261 if (dy>0) {
02262 return (vlineColor(dst, x1, y1, y2-1, color));
02263 } else {
02264 return (pixelColor(dst, x1, y1, color));
02265 }
02266 }
02267 } else if (dy == 0) {
02268
02269
02270
02271 if (draw_endpoint)
02272 {
02273 return (hlineColor(dst, x1, x2, y1, color));
02274 } else {
02275 if (dx>0) {
02276 return (hlineColor(dst, x1, x2-1, y1, color));
02277 } else {
02278 return (pixelColor(dst, x1, y1, color));
02279 }
02280 }
02281 } else if ((dx == dy) && (draw_endpoint)) {
02282
02283
02284
02285 return (lineColor(dst, x1, y1, x2, y2, color));
02286 }
02287
02288
02289
02290
02291 result = 0;
02292
02293
02294
02295
02296 erracc = 0;
02297
02298
02299
02300
02301 intshift = 32 - AAbits;
02302
02303
02304
02305
02306 wgtcompmask = AAlevels - 1;
02307
02308
02309 if (SDL_MUSTLOCK(dst)) {
02310 if (SDL_LockSurface(dst) < 0) {
02311 return (-1);
02312 }
02313 }
02314
02315
02316
02317
02318 result |= pixelColorNolock(dst, x1, y1, color);
02319
02320
02321
02322
02323 if (dy > dx) {
02324
02325
02326
02327
02328
02329
02330
02331
02332
02333 erradj = ((dx << 16) / dy) << 16;
02334
02335
02336
02337
02338 x0pxdir = xx0 + xdir;
02339 while (--dy) {
02340 erracctmp = erracc;
02341 erracc += erradj;
02342 if (erracc <= erracctmp) {
02343
02344
02345
02346 xx0 = x0pxdir;
02347 x0pxdir += xdir;
02348 }
02349 yy0++;
02350
02351
02352
02353
02354
02355
02356 wgt = (erracc >> intshift) & 255;
02357 result |= pixelColorWeightNolock (dst, xx0, yy0, color, 255 - wgt);
02358 result |= pixelColorWeightNolock (dst, x0pxdir, yy0, color, wgt);
02359 }
02360
02361 } else {
02362
02363
02364
02365
02366
02367
02368
02369
02370
02371 erradj = ((dy << 16) / dx) << 16;
02372
02373
02374
02375
02376 y0p1 = yy0 + 1;
02377 while (--dx) {
02378
02379 erracctmp = erracc;
02380 erracc += erradj;
02381 if (erracc <= erracctmp) {
02382
02383
02384
02385 yy0 = y0p1;
02386 y0p1++;
02387 }
02388 xx0 += xdir;
02389
02390
02391
02392
02393
02394 wgt = (erracc >> intshift) & 255;
02395 result |= pixelColorWeightNolock (dst, xx0, yy0, color, 255 - wgt);
02396 result |= pixelColorWeightNolock (dst, xx0, y0p1, color, wgt);
02397 }
02398 }
02399
02400
02401
02402
02403 if (draw_endpoint) {
02404
02405
02406
02407
02408 result |= pixelColorNolock (dst, x2, y2, color);
02409 }
02410
02411
02412 if (SDL_MUSTLOCK(dst)) {
02413 SDL_UnlockSurface(dst);
02414 }
02415
02416 return (result);
02417 }
02418
02431 int aalineColor(SDL_Surface * dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color)
02432 {
02433 return (_aalineColor(dst, x1, y1, x2, y2, color, 1));
02434 }
02435
02451 int aalineRGBA(SDL_Surface * dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
02452 {
02453 return (_aalineColor
02454 (dst, x1, y1, x2, y2, ((Uint32) r << 24) | ((Uint32) g << 16) | ((Uint32) b << 8) | (Uint32) a, 1));
02455 }
02456
02457
02458
02459
02475 int circleColor(SDL_Surface * dst, Sint16 x, Sint16 y, Sint16 rad, Uint32 color)
02476 {
02477 Sint16 left, right, top, bottom;
02478 int result;
02479 Sint16 x1, y1, x2, y2;
02480 Sint16 cx = 0;
02481 Sint16 cy = rad;
02482 Sint16 ocx = (Sint16) 0xffff;
02483 Sint16 ocy = (Sint16) 0xffff;
02484 Sint16 df = 1 - rad;
02485 Sint16 d_e = 3;
02486 Sint16 d_se = -2 * rad + 5;
02487 Sint16 xpcx, xmcx, xpcy, xmcy;
02488 Sint16 ypcy, ymcy, ypcx, ymcx;
02489 Uint8 *colorptr;
02490
02491
02492
02493
02494 if ((dst->clip_rect.w==0) || (dst->clip_rect.h==0)) {
02495 return(0);
02496 }
02497
02498
02499
02500
02501 if (rad < 0) {
02502 return (-1);
02503 }
02504
02505
02506
02507
02508 if (rad == 0) {
02509 return (pixelColor(dst, x, y, color));
02510 }
02511
02512
02513
02514
02515
02516 x2 = x + rad;
02517 left = dst->clip_rect.x;
02518 if (x2<left) {
02519 return(0);
02520 }
02521 x1 = x - rad;
02522 right = dst->clip_rect.x + dst->clip_rect.w - 1;
02523 if (x1>right) {
02524 return(0);
02525 }
02526 y2 = y + rad;
02527 top = dst->clip_rect.y;
02528 if (y2<top) {
02529 return(0);
02530 }
02531 y1 = y - rad;
02532 bottom = dst->clip_rect.y + dst->clip_rect.h - 1;
02533 if (y1>bottom) {
02534 return(0);
02535 }
02536
02537
02538
02539
02540 result = 0;
02541
02542
02543 if (SDL_MUSTLOCK(dst)) {
02544 if (SDL_LockSurface(dst) < 0) {
02545 return (-1);
02546 }
02547 }
02548
02549
02550
02551
02552 if ((color & 255) == 255) {
02553
02554
02555
02556
02557
02558
02559
02560
02561 colorptr = (Uint8 *) & color;
02562 if (SDL_BYTEORDER == SDL_BIG_ENDIAN) {
02563 color = SDL_MapRGBA(dst->format, colorptr[0], colorptr[1], colorptr[2], colorptr[3]);
02564 } else {
02565 color = SDL_MapRGBA(dst->format, colorptr[3], colorptr[2], colorptr[1], colorptr[0]);
02566 }
02567
02568
02569
02570
02571 do {
02572 ypcy = y + cy;
02573 ymcy = y - cy;
02574 if (cx > 0) {
02575 xpcx = x + cx;
02576 xmcx = x - cx;
02577 result |= fastPixelColorNolock(dst, xmcx, ypcy, color);
02578 result |= fastPixelColorNolock(dst, xpcx, ypcy, color);
02579 result |= fastPixelColorNolock(dst, xmcx, ymcy, color);
02580 result |= fastPixelColorNolock(dst, xpcx, ymcy, color);
02581 } else {
02582 result |= fastPixelColorNolock(dst, x, ymcy, color);
02583 result |= fastPixelColorNolock(dst, x, ypcy, color);
02584 }
02585 xpcy = x + cy;
02586 xmcy = x - cy;
02587 if ((cx > 0) && (cx != cy)) {
02588 ypcx = y + cx;
02589 ymcx = y - cx;
02590 result |= fastPixelColorNolock(dst, xmcy, ypcx, color);
02591 result |= fastPixelColorNolock(dst, xpcy, ypcx, color);
02592 result |= fastPixelColorNolock(dst, xmcy, ymcx, color);
02593 result |= fastPixelColorNolock(dst, xpcy, ymcx, color);
02594 } else if (cx == 0) {
02595 result |= fastPixelColorNolock(dst, xmcy, y, color);
02596 result |= fastPixelColorNolock(dst, xpcy, y, color);
02597 }
02598
02599
02600
02601 if (df < 0) {
02602 df += d_e;
02603 d_e += 2;
02604 d_se += 2;
02605 } else {
02606 df += d_se;
02607 d_e += 2;
02608 d_se += 4;
02609 cy--;
02610 }
02611 cx++;
02612 } while (cx <= cy);
02613
02614
02615
02616
02617 SDL_UnlockSurface(dst);
02618
02619 } else {
02620
02621
02622
02623
02624
02625 do {
02626
02627
02628
02629 ypcy = y + cy;
02630 ymcy = y - cy;
02631 if (cx > 0) {
02632 xpcx = x + cx;
02633 xmcx = x - cx;
02634 result |= pixelColorNolock (dst, xmcx, ypcy, color);
02635 result |= pixelColorNolock (dst, xpcx, ypcy, color);
02636 result |= pixelColorNolock (dst, xmcx, ymcy, color);
02637 result |= pixelColorNolock (dst, xpcx, ymcy, color);
02638 } else {
02639 result |= pixelColorNolock (dst, x, ymcy, color);
02640 result |= pixelColorNolock (dst, x, ypcy, color);
02641 }
02642 xpcy = x + cy;
02643 xmcy = x - cy;
02644 if ((cx > 0) && (cx != cy)) {
02645 ypcx = y + cx;
02646 ymcx = y - cx;
02647 result |= pixelColorNolock (dst, xmcy, ypcx, color);
02648 result |= pixelColorNolock (dst, xpcy, ypcx, color);
02649 result |= pixelColorNolock (dst, xmcy, ymcx, color);
02650 result |= pixelColorNolock (dst, xpcy, ymcx, color);
02651 } else if (cx == 0) {
02652 result |= pixelColorNolock (dst, xmcy, y, color);
02653 result |= pixelColorNolock (dst, xpcy, y, color);
02654 }
02655
02656
02657
02658 if (df < 0) {
02659 df += d_e;
02660 d_e += 2;
02661 d_se += 2;
02662 } else {
02663 df += d_se;
02664 d_e += 2;
02665 d_se += 4;
02666 cy--;
02667 }
02668 cx++;
02669 } while (cx <= cy);
02670
02671 }
02672
02673
02674 if (SDL_MUSTLOCK(dst)) {
02675 SDL_UnlockSurface(dst);
02676 }
02677
02678 return (result);
02679 }
02680
02695 int circleRGBA(SDL_Surface * dst, Sint16 x, Sint16 y, Sint16 rad, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
02696 {
02697
02698
02699
02700 return (circleColor(dst, x, y, rad, ((Uint32) r << 24) | ((Uint32) g << 16) | ((Uint32) b << 8) | (Uint32) a));
02701 }
02702
02703
02704
02722 int arcColor(SDL_Surface * dst, Sint16 x, Sint16 y, Sint16 rad, Sint16 start, Sint16 end, Uint32 color)
02723 {
02724 Sint16 left, right, top, bottom;
02725 int result;
02726 Sint16 x1, y1, x2, y2;
02727 Sint16 cx = 0;
02728 Sint16 cy = rad;
02729 Sint16 ocx = (Sint16) 0xffff;
02730 Sint16 ocy = (Sint16) 0xffff;
02731 Sint16 df = 1 - rad;
02732 Sint16 d_e = 3;
02733 Sint16 d_se = -2 * rad + 5;
02734 Sint16 xpcx, xmcx, xpcy, xmcy;
02735 Sint16 ypcy, ymcy, ypcx, ymcx;
02736 Uint8 *colorptr;
02737 Uint8 drawoct;
02738 int startoct, endoct, oct, stopval_start, stopval_end;
02739 double temp;
02740
02741
02742
02743
02744 if ((dst->clip_rect.w==0) || (dst->clip_rect.h==0)) {
02745 return(0);
02746 }
02747
02748
02749
02750
02751 if (rad < 0) {
02752 return (-1);
02753 }
02754
02755
02756
02757
02758 if (rad == 0) {
02759 return (pixelColor(dst, x, y, color));
02760 }
02761
02762
02763
02764
02765
02766 x2 = x + rad;
02767 left = dst->clip_rect.x;
02768 if (x2<left) {
02769 return(0);
02770 }
02771 x1 = x - rad;
02772 right = dst->clip_rect.x + dst->clip_rect.w - 1;
02773 if (x1>right) {
02774 return(0);
02775 }
02776 y2 = y + rad;
02777 top = dst->clip_rect.y;
02778 if (y2<top) {
02779 return(0);
02780 }
02781 y1 = y - rad;
02782 bottom = dst->clip_rect.y + dst->clip_rect.h - 1;
02783 if (y1>bottom) {
02784 return(0);
02785 }
02786
02787
02788
02789
02790
02791
02792
02793
02794
02795
02796
02797
02798
02799
02800
02801
02802
02803 drawoct = 0;
02804
02805
02806
02807
02808 start %= 360;
02809 end %= 360;
02810
02811 while (start < 0) start += 360;
02812 while (end < 0) end += 360;
02813 start %= 360;
02814 end %= 360;
02815
02816
02817 startoct = start / 45;
02818 endoct = end / 45;
02819 oct = startoct - 1;
02820
02821
02822
02823 do {
02824 oct = (oct + 1) % 8;
02825
02826 if (oct == startoct) {
02827
02828 switch (oct)
02829 {
02830 case 0:
02831 case 3:
02832 temp = sin(start * M_PI / 180);
02833 break;
02834 case 1:
02835 case 6:
02836 temp = cos(start * M_PI / 180);
02837 break;
02838 case 2:
02839 case 5:
02840 temp = -cos(start * M_PI / 180);
02841 break;
02842 case 4:
02843 case 7:
02844 temp = -sin(start * M_PI / 180);
02845 break;
02846 }
02847 temp *= rad;
02848 stopval_start = (int)temp;
02849
02850
02851
02852
02853
02854 if (oct % 2) drawoct |= (1 << oct);
02855 else drawoct &= 255 - (1 << oct);
02856 }
02857 if (oct == endoct) {
02858
02859 switch (oct)
02860 {
02861 case 0:
02862 case 3:
02863 temp = sin(end * M_PI / 180);
02864 break;
02865 case 1:
02866 case 6:
02867 temp = cos(end * M_PI / 180);
02868 break;
02869 case 2:
02870 case 5:
02871 temp = -cos(end * M_PI / 180);
02872 break;
02873 case 4:
02874 case 7:
02875 temp = -sin(end * M_PI / 180);
02876 break;
02877 }
02878 temp *= rad;
02879 stopval_end = (int)temp;
02880
02881
02882 if (startoct == endoct) {
02883
02884
02885 if (start > end) {
02886
02887
02888 drawoct = 255;
02889 } else {
02890 drawoct &= 255 - (1 << oct);
02891 }
02892 }
02893 else if (oct % 2) drawoct &= 255 - (1 << oct);
02894 else drawoct |= (1 << oct);
02895 } else if (oct != startoct) {
02896 drawoct |= (1 << oct);
02897 }
02898 } while (oct != endoct);
02899
02900
02901
02902
02903 if (SDL_MUSTLOCK(dst)) {
02904 if (SDL_LockSurface(dst) < 0) {
02905 return (-1);
02906 }
02907 }
02908
02909
02910
02911
02912 result = 0;
02913
02914
02915
02916
02917 if ((color & 255) == 255) {
02918
02919
02920
02921
02922
02923
02924
02925
02926 colorptr = (Uint8 *) & color;
02927 if (SDL_BYTEORDER == SDL_BIG_ENDIAN) {
02928 color = SDL_MapRGBA(dst->format, colorptr[0], colorptr[1], colorptr[2], colorptr[3]);
02929 } else {
02930 color = SDL_MapRGBA(dst->format, colorptr[3], colorptr[2], colorptr[1], colorptr[0]);
02931 }
02932
02933
02934
02935
02936 do {
02937 ypcy = y + cy;
02938 ymcy = y - cy;
02939 if (cx > 0) {
02940 xpcx = x + cx;
02941 xmcx = x - cx;
02942
02943 if (drawoct & 4) result |= fastPixelColorNolock(dst, xmcx, ypcy, color);
02944 if (drawoct & 2) result |= fastPixelColorNolock(dst, xpcx, ypcy, color);
02945 if (drawoct & 32) result |= fastPixelColorNolock(dst, xmcx, ymcy, color);
02946 if (drawoct & 64) result |= fastPixelColorNolock(dst, xpcx, ymcy, color);
02947 } else {
02948 if (drawoct & 6) result |= fastPixelColorNolock(dst, x, ypcy, color);
02949 if (drawoct & 96) result |= fastPixelColorNolock(dst, x, ymcy, color);
02950 }
02951
02952 xpcy = x + cy;
02953 xmcy = x - cy;
02954 if (cx > 0 && cx != cy) {
02955 ypcx = y + cx;
02956 ymcx = y - cx;
02957 if (drawoct & 8) result |= fastPixelColorNolock(dst, xmcy, ypcx, color);
02958 if (drawoct & 1) result |= fastPixelColorNolock(dst, xpcy, ypcx, color);
02959 if (drawoct & 16) result |= fastPixelColorNolock(dst, xmcy, ymcx, color);
02960 if (drawoct & 128) result |= fastPixelColorNolock(dst, xpcy, ymcx, color);
02961 } else if (cx == 0) {
02962 if (drawoct & 24) result |= fastPixelColorNolock(dst, xmcy, y, color);
02963 if (drawoct & 129) result |= fastPixelColorNolock(dst, xpcy, y, color);
02964 }
02965
02966
02967
02968
02969 if (stopval_start == cx) {
02970
02971 if (drawoct & (1 << startoct)) drawoct &= 255 - (1 << startoct);
02972 else drawoct |= (1 << startoct);
02973 }
02974 if (stopval_end == cx) {
02975 if (drawoct & (1 << endoct)) drawoct &= 255 - (1 << endoct);
02976 else drawoct |= (1 << endoct);
02977 }
02978
02979
02980
02981
02982 if (df < 0) {
02983 df += d_e;
02984 d_e += 2;
02985 d_se += 2;
02986 } else {
02987 df += d_se;
02988 d_e += 2;
02989 d_se += 4;
02990 cy--;
02991 }
02992 cx++;
02993 } while (cx <= cy);
02994
02995
02996
02997
02998 SDL_UnlockSurface(dst);
02999
03000 } else {
03001
03002
03003
03004
03005
03006 do {
03007 ypcy = y + cy;
03008 ymcy = y - cy;
03009 if (cx > 0) {
03010 xpcx = x + cx;
03011 xmcx = x - cx;
03012
03013
03014 if (drawoct & 4) result |= pixelColorNolock(dst, xmcx, ypcy, color);
03015 if (drawoct & 2) result |= pixelColorNolock(dst, xpcx, ypcy, color);
03016 if (drawoct & 32) result |= pixelColorNolock(dst, xmcx, ymcy, color);
03017 if (drawoct & 64) result |= pixelColorNolock(dst, xpcx, ymcy, color);
03018 } else {
03019 if (drawoct & 96) result |= pixelColorNolock(dst, x, ymcy, color);
03020 if (drawoct & 6) result |= pixelColorNolock(dst, x, ypcy, color);
03021 }
03022
03023 xpcy = x + cy;
03024 xmcy = x - cy;
03025 if (cx > 0 && cx != cy) {
03026 ypcx = y + cx;
03027 ymcx = y - cx;
03028 if (drawoct & 8) result |= pixelColorNolock(dst, xmcy, ypcx, color);
03029 if (drawoct & 1) result |= pixelColorNolock(dst, xpcy, ypcx, color);
03030 if (drawoct & 16) result |= pixelColorNolock(dst, xmcy, ymcx, color);
03031 if (drawoct & 128) result |= pixelColorNolock(dst, xpcy, ymcx, color);
03032 } else if (cx == 0) {
03033 if (drawoct & 24) result |= pixelColorNolock(dst, xmcy, y, color);
03034 if (drawoct & 129) result |= pixelColorNolock(dst, xpcy, y, color);
03035 }
03036
03037
03038
03039
03040 if (stopval_start == cx) {
03041
03042
03043 if (drawoct & (1 << startoct)) drawoct &= 255 - (1 << startoct);
03044 else drawoct |= (1 << startoct);
03045 }
03046 if (stopval_end == cx) {
03047 if (drawoct & (1 << endoct)) drawoct &= 255 - (1 << endoct);
03048 else drawoct |= (1 << endoct);
03049 }
03050
03051
03052
03053
03054 if (df < 0) {
03055 df += d_e;
03056 d_e += 2;
03057 d_se += 2;
03058 } else {
03059 df += d_se;
03060 d_e += 2;
03061 d_se += 4;
03062 cy--;
03063 }
03064 cx++;
03065 } while (cx <= cy);
03066
03067 }
03068
03069
03070 if (SDL_MUSTLOCK(dst)) {
03071 SDL_UnlockSurface(dst);
03072 }
03073
03074 return (result);
03075 }
03076
03093 int arcRGBA(SDL_Surface * dst, Sint16 x, Sint16 y, Sint16 rad, Sint16 start, Sint16 end, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
03094 {
03095
03096
03097
03098 return (arcColor(dst, x, y, rad, start, end, ((Uint32) r << 24) | ((Uint32) g << 16) | ((Uint32) b << 8) | (Uint32) a));
03099 }
03100
03101
03102
03103
03117 int aacircleColor(SDL_Surface * dst, Sint16 x, Sint16 y, Sint16 rad, Uint32 color)
03118 {
03119 return (aaellipseColor(dst, x, y, rad, rad, color));
03120 }
03121
03136 int aacircleRGBA(SDL_Surface * dst, Sint16 x, Sint16 y, Sint16 rad, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
03137 {
03138
03139
03140
03141 return (aaellipseColor
03142 (dst, x, y, rad, rad, ((Uint32) r << 24) | ((Uint32) g << 16) | ((Uint32) b << 8) | (Uint32) a));
03143 }
03144
03145
03146
03161 int filledCircleColor(SDL_Surface * dst, Sint16 x, Sint16 y, Sint16 rad, Uint32 color)
03162 {
03163 Sint16 left, right, top, bottom;
03164 int result;
03165 Sint16 x1, y1, x2, y2;
03166 Sint16 cx = 0;
03167 Sint16 cy = rad;
03168 Sint16 ocx = (Sint16) 0xffff;
03169 Sint16 ocy = (Sint16) 0xffff;
03170 Sint16 df = 1 - rad;
03171 Sint16 d_e = 3;
03172 Sint16 d_se = -2 * rad + 5;
03173 Sint16 xpcx, xmcx, xpcy, xmcy;
03174 Sint16 ypcy, ymcy, ypcx, ymcx;
03175
03176
03177
03178
03179 if ((dst->clip_rect.w==0) || (dst->clip_rect.h==0)) {
03180 return(0);
03181 }
03182
03183
03184
03185
03186 if (rad < 0) {
03187 return (-1);
03188 }
03189
03190
03191
03192
03193 if (rad == 0) {
03194 return (pixelColor(dst, x, y, color));
03195 }
03196
03197
03198
03199
03200
03201 x2 = x + rad;
03202 left = dst->clip_rect.x;
03203 if (x2<left) {
03204 return(0);
03205 }
03206 x1 = x - rad;
03207 right = dst->clip_rect.x + dst->clip_rect.w - 1;
03208 if (x1>right) {
03209 return(0);
03210 }
03211 y2 = y + rad;
03212 top = dst->clip_rect.y;
03213 if (y2<top) {
03214 return(0);
03215 }
03216 y1 = y - rad;
03217 bottom = dst->clip_rect.y + dst->clip_rect.h - 1;
03218 if (y1>bottom) {
03219 return(0);
03220 }
03221
03222
03223
03224
03225 result = 0;
03226 do {
03227 xpcx = x + cx;
03228 xmcx = x - cx;
03229 xpcy = x + cy;
03230 xmcy = x - cy;
03231 if (ocy != cy) {
03232 if (cy > 0) {
03233 ypcy = y + cy;
03234 ymcy = y - cy;
03235 result |= hlineColor(dst, xmcx, xpcx, ypcy, color);
03236 result |= hlineColor(dst, xmcx, xpcx, ymcy, color);
03237 } else {
03238 result |= hlineColor(dst, xmcx, xpcx, y, color);
03239 }
03240 ocy = cy;
03241 }
03242 if (ocx != cx) {
03243 if (cx != cy) {
03244 if (cx > 0) {
03245 ypcx = y + cx;
03246 ymcx = y - cx;
03247 result |= hlineColor(dst, xmcy, xpcy, ymcx, color);
03248 result |= hlineColor(dst, xmcy, xpcy, ypcx, color);
03249 } else {
03250 result |= hlineColor(dst, xmcy, xpcy, y, color);
03251 }
03252 }
03253 ocx = cx;
03254 }
03255
03256
03257
03258 if (df < 0) {
03259 df += d_e;
03260 d_e += 2;
03261 d_se += 2;
03262 } else {
03263 df += d_se;
03264 d_e += 2;
03265 d_se += 4;
03266 cy--;
03267 }
03268 cx++;
03269 } while (cx <= cy);
03270
03271 return (result);
03272 }
03273
03288 int filledCircleRGBA(SDL_Surface * dst, Sint16 x, Sint16 y, Sint16 rad, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
03289 {
03290
03291
03292
03293 return (filledCircleColor
03294 (dst, x, y, rad, ((Uint32) r << 24) | ((Uint32) g << 16) | ((Uint32) b << 8) | (Uint32) a));
03295 }
03296
03297
03298
03314 int ellipseColor(SDL_Surface * dst, Sint16 x, Sint16 y, Sint16 rx, Sint16 ry, Uint32 color)
03315 {
03316 Sint16 left, right, top, bottom;
03317 int result;
03318 Sint16 x1, y1, x2, y2;
03319 int ix, iy;
03320 int h, i, j, k;
03321 int oh, oi, oj, ok;
03322 int xmh, xph, ypk, ymk;
03323 int xmi, xpi, ymj, ypj;
03324 int xmj, xpj, ymi, ypi;
03325 int xmk, xpk, ymh, yph;
03326 Uint8 *colorptr;
03327
03328
03329
03330
03331 if ((dst->clip_rect.w==0) || (dst->clip_rect.h==0)) {
03332 return(0);
03333 }
03334
03335
03336
03337
03338 if ((rx < 0) || (ry < 0)) {
03339 return (-1);
03340 }
03341
03342
03343
03344
03345 if (rx == 0) {
03346 return (vlineColor(dst, x, y - ry, y + ry, color));
03347 }
03348
03349
03350
03351 if (ry == 0) {
03352 return (hlineColor(dst, x - rx, x + rx, y, color));
03353 }
03354
03355
03356
03357
03358
03359 x2 = x + rx;
03360 left = dst->clip_rect.x;
03361 if (x2<left) {
03362 return(0);
03363 }
03364 x1 = x - rx;
03365 right = dst->clip_rect.x + dst->clip_rect.w - 1;
03366 if (x1>right) {
03367 return(0);
03368 }
03369 y2 = y + ry;
03370 top = dst->clip_rect.y;
03371 if (y2<top) {
03372 return(0);
03373 }
03374 y1 = y - ry;
03375 bottom = dst->clip_rect.y + dst->clip_rect.h - 1;
03376 if (y1>bottom) {
03377 return(0);
03378 }
03379
03380
03381
03382
03383 oh = oi = oj = ok = 0xFFFF;
03384
03385
03386
03387
03388 result = 0;
03389
03390
03391 if (SDL_MUSTLOCK(dst)) {
03392 if (SDL_LockSurface(dst) < 0) {
03393 return (-1);
03394 }
03395 }
03396
03397
03398
03399
03400 if ((color & 255) == 255) {
03401
03402
03403
03404
03405
03406
03407
03408
03409 colorptr = (Uint8 *) & color;
03410 if (SDL_BYTEORDER == SDL_BIG_ENDIAN) {
03411 color = SDL_MapRGBA(dst->format, colorptr[0], colorptr[1], colorptr[2], colorptr[3]);
03412 } else {
03413 color = SDL_MapRGBA(dst->format, colorptr[3], colorptr[2], colorptr[1], colorptr[0]);
03414 }
03415
03416
03417 if (rx > ry) {
03418 ix = 0;
03419 iy = rx * 64;
03420
03421 do {
03422 h = (ix + 32) >> 6;
03423 i = (iy + 32) >> 6;
03424 j = (h * ry) / rx;
03425 k = (i * ry) / rx;
03426
03427 if (((ok != k) && (oj != k)) || ((oj != j) && (ok != j)) || (k != j)) {
03428 xph = x + h;
03429 xmh = x - h;
03430 if (k > 0) {
03431 ypk = y + k;
03432 ymk = y - k;
03433 result |= fastPixelColorNolock(dst, xmh, ypk, color);
03434 result |= fastPixelColorNolock(dst, xph, ypk, color);
03435 result |= fastPixelColorNolock(dst, xmh, ymk, color);
03436 result |= fastPixelColorNolock(dst, xph, ymk, color);
03437 } else {
03438 result |= fastPixelColorNolock(dst, xmh, y, color);
03439 result |= fastPixelColorNolock(dst, xph, y, color);
03440 }
03441 ok = k;
03442 xpi = x + i;
03443 xmi = x - i;
03444 if (j > 0) {
03445 ypj = y + j;
03446 ymj = y - j;
03447 result |= fastPixelColorNolock(dst, xmi, ypj, color);
03448 result |= fastPixelColorNolock(dst, xpi, ypj, color);
03449 result |= fastPixelColorNolock(dst, xmi, ymj, color);
03450 result |= fastPixelColorNolock(dst, xpi, ymj, color);
03451 } else {
03452 result |= fastPixelColorNolock(dst, xmi, y, color);
03453 result |= fastPixelColorNolock(dst, xpi, y, color);
03454 }
03455 oj = j;
03456 }
03457
03458 ix = ix + iy / rx;
03459 iy = iy - ix / rx;
03460
03461 } while (i > h);
03462 } else {
03463 ix = 0;
03464 iy = ry * 64;
03465
03466 do {
03467 h = (ix + 32) >> 6;
03468 i = (iy + 32) >> 6;
03469 j = (h * rx) / ry;
03470 k = (i * rx) / ry;
03471
03472 if (((oi != i) && (oh != i)) || ((oh != h) && (oi != h) && (i != h))) {
03473 xmj = x - j;
03474 xpj = x + j;
03475 if (i > 0) {
03476 ypi = y + i;
03477 ymi = y - i;
03478 result |= fastPixelColorNolock(dst, xmj, ypi, color);
03479 result |= fastPixelColorNolock(dst, xpj, ypi, color);
03480 result |= fastPixelColorNolock(dst, xmj, ymi, color);
03481 result |= fastPixelColorNolock(dst, xpj, ymi, color);
03482 } else {
03483 result |= fastPixelColorNolock(dst, xmj, y, color);
03484 result |= fastPixelColorNolock(dst, xpj, y, color);
03485 }
03486 oi = i;
03487 xmk = x - k;
03488 xpk = x + k;
03489 if (h > 0) {
03490 yph = y + h;
03491 ymh = y - h;
03492 result |= fastPixelColorNolock(dst, xmk, yph, color);
03493 result |= fastPixelColorNolock(dst, xpk, yph, color);
03494 result |= fastPixelColorNolock(dst, xmk, ymh, color);
03495 result |= fastPixelColorNolock(dst, xpk, ymh, color);
03496 } else {
03497 result |= fastPixelColorNolock(dst, xmk, y, color);
03498 result |= fastPixelColorNolock(dst, xpk, y, color);
03499 }
03500 oh = h;
03501 }
03502
03503 ix = ix + iy / ry;
03504 iy = iy - ix / ry;
03505
03506 } while (i > h);
03507 }
03508
03509 } else {
03510
03511 if (rx > ry) {
03512 ix = 0;
03513 iy = rx * 64;
03514
03515 do {
03516 h = (ix + 32) >> 6;
03517 i = (iy + 32) >> 6;
03518 j = (h * ry) / rx;
03519 k = (i * ry) / rx;
03520
03521 if (((ok != k) && (oj != k)) || ((oj != j) && (ok != j)) || (k != j)) {
03522 xph = x + h;
03523 xmh = x - h;
03524 if (k > 0) {
03525 ypk = y + k;
03526 ymk = y - k;
03527 result |= pixelColorNolock (dst, xmh, ypk, color);
03528 result |= pixelColorNolock (dst, xph, ypk, color);
03529 result |= pixelColorNolock (dst, xmh, ymk, color);
03530 result |= pixelColorNolock (dst, xph, ymk, color);
03531 } else {
03532 result |= pixelColorNolock (dst, xmh, y, color);
03533 result |= pixelColorNolock (dst, xph, y, color);
03534 }
03535 ok = k;
03536 xpi = x + i;
03537 xmi = x - i;
03538 if (j > 0) {
03539 ypj = y + j;
03540 ymj = y - j;
03541 result |= pixelColorNolock (dst, xmi, ypj, color);
03542 result |= pixelColorNolock (dst, xpi, ypj, color);
03543 result |= pixelColorNolock (dst, xmi, ymj, color);
03544 result |= pixelColor(dst, xpi, ymj, color);
03545 } else {
03546 result |= pixelColorNolock (dst, xmi, y, color);
03547 result |= pixelColorNolock (dst, xpi, y, color);
03548 }
03549 oj = j;
03550 }
03551
03552 ix = ix + iy / rx;
03553 iy = iy - ix / rx;
03554
03555 } while (i > h);
03556 } else {
03557 ix = 0;
03558 iy = ry * 64;
03559
03560 do {
03561 h = (ix + 32) >> 6;
03562 i = (iy + 32) >> 6;
03563 j = (h * rx) / ry;
03564 k = (i * rx) / ry;
03565
03566 if (((oi != i) && (oh != i)) || ((oh != h) && (oi != h) && (i != h))) {
03567 xmj = x - j;
03568 xpj = x + j;
03569 if (i > 0) {
03570 ypi = y + i;
03571 ymi = y - i;
03572 result |= pixelColorNolock (dst, xmj, ypi, color);
03573 result |= pixelColorNolock (dst, xpj, ypi, color);
03574 result |= pixelColorNolock (dst, xmj, ymi, color);
03575 result |= pixelColorNolock (dst, xpj, ymi, color);
03576 } else {
03577 result |= pixelColorNolock (dst, xmj, y, color);
03578 result |= pixelColorNolock (dst, xpj, y, color);
03579 }
03580 oi = i;
03581 xmk = x - k;
03582 xpk = x + k;
03583 if (h > 0) {
03584 yph = y + h;
03585 ymh = y - h;
03586 result |= pixelColorNolock (dst, xmk, yph, color);
03587 result |= pixelColorNolock (dst, xpk, yph, color);
03588 result |= pixelColorNolock (dst, xmk, ymh, color);
03589 result |= pixelColorNolock (dst, xpk, ymh, color);
03590 } else {
03591 result |= pixelColorNolock (dst, xmk, y, color);
03592 result |= pixelColorNolock (dst, xpk, y, color);
03593 }
03594 oh = h;
03595 }
03596
03597 ix = ix + iy / ry;
03598 iy = iy - ix / ry;
03599
03600 } while (i > h);
03601 }
03602
03603 }
03604
03605
03606 if (SDL_MUSTLOCK(dst)) {
03607 SDL_UnlockSurface(dst);
03608 }
03609
03610 return (result);
03611 }
03612
03628 int ellipseRGBA(SDL_Surface * dst, Sint16 x, Sint16 y, Sint16 rx, Sint16 ry, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
03629 {
03630
03631
03632
03633 return (ellipseColor(dst, x, y, rx, ry, ((Uint32) r << 24) | ((Uint32) g << 16) | ((Uint32) b << 8) | (Uint32) a));
03634 }
03635
03636
03637
03638
03639
03640
03641 #if defined(WIN32) && !defined(__MINGW_H) && !defined(__SYMBIAN32__)
03642 #ifdef _M_X64
03643 #include <emmintrin.h>
03644 static __inline long
03645 lrint(float f)
03646 {
03647 return _mm_cvtss_si32(_mm_load_ss(&f));
03648 }
03649 #else
03650 __inline long int
03651 lrint (double flt)
03652 {
03653 int intgr;
03654 _asm
03655 {
03656 fld flt
03657 fistp intgr
03658 };
03659 return intgr;
03660 }
03661 #endif
03662 #endif
03663
03679 int aaellipseColor(SDL_Surface * dst, Sint16 x, Sint16 y, Sint16 rx, Sint16 ry, Uint32 color)
03680 {
03681 Sint16 left, right, top, bottom;
03682 Sint16 x1,y1,x2,y2;
03683 int i;
03684 int a2, b2, ds, dt, dxt, t, s, d;
03685 Sint16 xp, yp, xs, ys, dyt, od, xx, yy, xc2, yc2;
03686 float cp;
03687 double sab;
03688 Uint8 weight, iweight;
03689 int result;
03690
03691
03692
03693
03694 if ((dst->clip_rect.w==0) || (dst->clip_rect.h==0)) {
03695 return(0);
03696 }
03697
03698
03699
03700
03701 if ((rx < 0) || (ry < 0)) {
03702 return (-1);
03703 }
03704
03705
03706
03707
03708 if (rx == 0) {
03709 return (vlineColor(dst, x, y - ry, y + ry, color));
03710 }
03711
03712
03713
03714 if (ry == 0) {
03715 return (hlineColor(dst, x - rx, x + rx, y, color));
03716 }
03717
03718
03719
03720
03721
03722 x2 = x + rx;
03723 left = dst->clip_rect.x;
03724 if (x2<left) {
03725 return(0);
03726 }
03727 x1 = x - rx;
03728 right = dst->clip_rect.x + dst->clip_rect.w - 1;
03729 if (x1>right) {
03730 return(0);
03731 }
03732 y2 = y + ry;
03733 top = dst->clip_rect.y;
03734 if (y2<top) {
03735 return(0);
03736 }
03737 y1 = y - ry;
03738 bottom = dst->clip_rect.y + dst->clip_rect.h - 1;
03739 if (y1>bottom) {
03740 return(0);
03741 }
03742
03743
03744 a2 = rx * rx;
03745 b2 = ry * ry;
03746
03747 ds = 2 * a2;
03748 dt = 2 * b2;
03749
03750 xc2 = 2 * x;
03751 yc2 = 2 * y;
03752
03753 sab = sqrt(a2 + b2);
03754 od = (Sint16)lrint(sab*0.01) + 1;
03755 dxt = (Sint16)lrint((double)a2 / sab) + od;
03756
03757 t = 0;
03758 s = -2 * a2 * ry;
03759 d = 0;
03760
03761 xp = x;
03762 yp = y - ry;
03763
03764
03765 if (SDL_MUSTLOCK(dst)) {
03766 if (SDL_LockSurface(dst) < 0) {
03767 return (-1);
03768 }
03769 }
03770
03771
03772 result = 0;
03773
03774
03775 result |= pixelColorNolock(dst, xp, yp, color);
03776 result |= pixelColorNolock(dst, xc2 - xp, yp, color);
03777 result |= pixelColorNolock(dst, xp, yc2 - yp, color);
03778 result |= pixelColorNolock(dst, xc2 - xp, yc2 - yp, color);
03779
03780 for (i = 1; i <= dxt; i++) {
03781 xp--;
03782 d += t - b2;
03783
03784 if (d >= 0)
03785 ys = yp - 1;
03786 else if ((d - s - a2) > 0) {
03787 if ((2 * d - s - a2) >= 0)
03788 ys = yp + 1;
03789 else {
03790 ys = yp;
03791 yp++;
03792 d -= s + a2;
03793 s += ds;
03794 }
03795 } else {
03796 yp++;
03797 ys = yp + 1;
03798 d -= s + a2;
03799 s += ds;
03800 }
03801
03802 t -= dt;
03803
03804
03805 if (s != 0.0) {
03806 cp = (float) abs(d) / (float) abs(s);
03807 if (cp > 1.0) {
03808 cp = 1.0;
03809 }
03810 } else {
03811 cp = 1.0;
03812 }
03813
03814
03815 weight = (Uint8) (cp * 255);
03816 iweight = 255 - weight;
03817
03818
03819 xx = xc2 - xp;
03820 result |= pixelColorWeightNolock(dst, xp, yp, color, iweight);
03821 result |= pixelColorWeightNolock(dst, xx, yp, color, iweight);
03822
03823 result |= pixelColorWeightNolock(dst, xp, ys, color, weight);
03824 result |= pixelColorWeightNolock(dst, xx, ys, color, weight);
03825
03826
03827 yy = yc2 - yp;
03828 result |= pixelColorWeightNolock(dst, xp, yy, color, iweight);
03829 result |= pixelColorWeightNolock(dst, xx, yy, color, iweight);
03830
03831 yy = yc2 - ys;
03832 result |= pixelColorWeightNolock(dst, xp, yy, color, weight);
03833 result |= pixelColorWeightNolock(dst, xx, yy, color, weight);
03834 }
03835
03836
03837 dyt = (Sint16)lrint((double)b2 / sab ) + od;
03838
03839 for (i = 1; i <= dyt; i++) {
03840 yp++;
03841 d -= s + a2;
03842
03843 if (d <= 0)
03844 xs = xp + 1;
03845 else if ((d + t - b2) < 0) {
03846 if ((2 * d + t - b2) <= 0)
03847 xs = xp - 1;
03848 else {
03849 xs = xp;
03850 xp--;
03851 d += t - b2;
03852 t -= dt;
03853 }
03854 } else {
03855 xp--;
03856 xs = xp - 1;
03857 d += t - b2;
03858 t -= dt;
03859 }
03860
03861 s += ds;
03862
03863
03864 if (t != 0.0) {
03865 cp = (float) abs(d) / (float) abs(t);
03866 if (cp > 1.0) {
03867 cp = 1.0;
03868 }
03869 } else {
03870 cp = 1.0;
03871 }
03872
03873
03874 weight = (Uint8) (cp * 255);
03875 iweight = 255 - weight;
03876
03877
03878 xx = xc2 - xp;
03879 yy = yc2 - yp;
03880 result |= pixelColorWeightNolock(dst, xp, yp, color, iweight);
03881 result |= pixelColorWeightNolock(dst, xx, yp, color, iweight);
03882
03883 result |= pixelColorWeightNolock(dst, xp, yy, color, iweight);
03884 result |= pixelColorWeightNolock(dst, xx, yy, color, iweight);
03885
03886
03887 xx = xc2 - xs;
03888 result |= pixelColorWeightNolock(dst, xs, yp, color, weight);
03889 result |= pixelColorWeightNolock(dst, xx, yp, color, weight);
03890
03891 result |= pixelColorWeightNolock(dst, xs, yy, color, weight);
03892 result |= pixelColorWeightNolock(dst, xx, yy, color, weight);
03893
03894 }
03895
03896
03897 if (SDL_MUSTLOCK(dst)) {
03898 SDL_UnlockSurface(dst);
03899 }
03900
03901 return (result);
03902 }
03903
03919 int aaellipseRGBA(SDL_Surface * dst, Sint16 x, Sint16 y, Sint16 rx, Sint16 ry, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
03920 {
03921
03922
03923
03924 return (aaellipseColor
03925 (dst, x, y, rx, ry, ((Uint32) r << 24) | ((Uint32) g << 16) | ((Uint32) b << 8) | (Uint32) a));
03926 }
03927
03928
03929
03930
03931
03932
03933
03949 int filledEllipseColor(SDL_Surface * dst, Sint16 x, Sint16 y, Sint16 rx, Sint16 ry, Uint32 color)
03950 {
03951 Sint16 left, right, top, bottom;
03952 int result;
03953 Sint16 x1, y1, x2, y2;
03954 int ix, iy;
03955 int h, i, j, k;
03956 int oh, oi, oj, ok;
03957 int xmh, xph;
03958 int xmi, xpi;
03959 int xmj, xpj;
03960 int xmk, xpk;
03961
03962
03963
03964
03965 if ((dst->clip_rect.w==0) || (dst->clip_rect.h==0)) {
03966 return(0);
03967 }
03968
03969
03970
03971
03972 if ((rx < 0) || (ry < 0)) {
03973 return (-1);
03974 }
03975
03976
03977
03978
03979 if (rx == 0) {
03980 return (vlineColor(dst, x, y - ry, y + ry, color));
03981 }
03982
03983
03984
03985 if (ry == 0) {
03986 return (hlineColor(dst, x - rx, x + rx, y, color));
03987 }
03988
03989
03990
03991
03992
03993 x2 = x + rx;
03994 left = dst->clip_rect.x;
03995 if (x2<left) {
03996 return(0);
03997 }
03998 x1 = x - rx;
03999 right = dst->clip_rect.x + dst->clip_rect.w - 1;
04000 if (x1>right) {
04001 return(0);
04002 }
04003 y2 = y + ry;
04004 top = dst->clip_rect.y;
04005 if (y2<top) {
04006 return(0);
04007 }
04008 y1 = y - ry;
04009 bottom = dst->clip_rect.y + dst->clip_rect.h - 1;
04010 if (y1>bottom) {
04011 return(0);
04012 }
04013
04014
04015
04016
04017 oh = oi = oj = ok = 0xFFFF;
04018
04019
04020
04021
04022 result = 0;
04023 if (rx > ry) {
04024 ix = 0;
04025 iy = rx * 64;
04026
04027 do {
04028 h = (ix + 32) >> 6;
04029 i = (iy + 32) >> 6;
04030 j = (h * ry) / rx;
04031 k = (i * ry) / rx;
04032
04033 if ((ok != k) && (oj != k)) {
04034 xph = x + h;
04035 xmh = x - h;
04036 if (k > 0) {
04037 result |= hlineColor(dst, xmh, xph, y + k, color);
04038 result |= hlineColor(dst, xmh, xph, y - k, color);
04039 } else {
04040 result |= hlineColor(dst, xmh, xph, y, color);
04041 }
04042 ok = k;
04043 }
04044 if ((oj != j) && (ok != j) && (k != j)) {
04045 xmi = x - i;
04046 xpi = x + i;
04047 if (j > 0) {
04048 result |= hlineColor(dst, xmi, xpi, y + j, color);
04049 result |= hlineColor(dst, xmi, xpi, y - j, color);
04050 } else {
04051 result |= hlineColor(dst, xmi, xpi, y, color);
04052 }
04053 oj = j;
04054 }
04055
04056 ix = ix + iy / rx;
04057 iy = iy - ix / rx;
04058
04059 } while (i > h);
04060 } else {
04061 ix = 0;
04062 iy = ry * 64;
04063
04064 do {
04065 h = (ix + 32) >> 6;
04066 i = (iy + 32) >> 6;
04067 j = (h * rx) / ry;
04068 k = (i * rx) / ry;
04069
04070 if ((oi != i) && (oh != i)) {
04071 xmj = x - j;
04072 xpj = x + j;
04073 if (i > 0) {
04074 result |= hlineColor(dst, xmj, xpj, y + i, color);
04075 result |= hlineColor(dst, xmj, xpj, y - i, color);
04076 } else {
04077 result |= hlineColor(dst, xmj, xpj, y, color);
04078 }
04079 oi = i;
04080 }
04081 if ((oh != h) && (oi != h) && (i != h)) {
04082 xmk = x - k;
04083 xpk = x + k;
04084 if (h > 0) {
04085 result |= hlineColor(dst, xmk, xpk, y + h, color);
04086 result |= hlineColor(dst, xmk, xpk, y - h, color);
04087 } else {
04088 result |= hlineColor(dst, xmk, xpk, y, color);
04089 }
04090 oh = h;
04091 }
04092
04093 ix = ix + iy / ry;
04094 iy = iy - ix / ry;
04095
04096 } while (i > h);
04097 }
04098
04099 return (result);
04100 }
04101
04117 int filledEllipseRGBA(SDL_Surface * dst, Sint16 x, Sint16 y, Sint16 rx, Sint16 ry, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
04118 {
04119
04120
04121
04122 return (filledEllipseColor
04123 (dst, x, y, rx, ry, ((Uint32) r << 24) | ((Uint32) g << 16) | ((Uint32) b << 8) | (Uint32) a));
04124 }
04125
04126
04127
04144 int _pieColor(SDL_Surface * dst, Sint16 x, Sint16 y, Sint16 rad, Sint16 start, Sint16 end, Uint32 color, Uint8 filled)
04145 {
04146 Sint16 left, right, top, bottom;
04147 Sint16 x1, y1, x2, y2;
04148 int result;
04149 double angle, start_angle, end_angle;
04150 double deltaAngle;
04151 double dr;
04152 int posX, posY;
04153 int numpoints, i;
04154 Sint16 *vx, *vy;
04155
04156
04157
04158
04159 if ((dst->clip_rect.w==0) || (dst->clip_rect.h==0)) {
04160 return(0);
04161 }
04162
04163
04164
04165
04166 if (rad < 0) {
04167 return (-1);
04168 }
04169
04170
04171
04172
04173 start = start % 360;
04174 end = end % 360;
04175
04176
04177
04178
04179 if (rad == 0) {
04180 return (pixelColor(dst, x, y, color));
04181 }
04182
04183
04184
04185
04186
04187
04188 x2 = x + rad;
04189 left = dst->clip_rect.x;
04190 if (x2<left) {
04191 return(0);
04192 }
04193 x1 = x - rad;
04194 right = dst->clip_rect.x + dst->clip_rect.w - 1;
04195 if (x1>right) {
04196 return(0);
04197 }
04198 y2 = y + rad;
04199 top = dst->clip_rect.y;
04200 if (y2<top) {
04201 return(0);
04202 }
04203 y1 = y - rad;
04204 bottom = dst->clip_rect.y + dst->clip_rect.h - 1;
04205 if (y1>bottom) {
04206 return(0);
04207 }
04208
04209
04210
04211
04212 dr = (double) rad;
04213 deltaAngle = 3.0 / dr;
04214 start_angle = (double) start *(2.0 * M_PI / 360.0);
04215 end_angle = (double) end *(2.0 * M_PI / 360.0);
04216 if (start > end) {
04217 end_angle += (2.0 * M_PI);
04218 }
04219
04220
04221 numpoints = 1;
04222 angle = start_angle;
04223 while (angle <= end_angle) {
04224 angle += deltaAngle;
04225 numpoints++;
04226 }
04227
04228
04229 if (numpoints == 1) {
04230 return (pixelColor(dst, x, y, color));
04231 } else if (numpoints == 2) {
04232 posX = x + (int) (dr * cos(start_angle));
04233 posY = y + (int) (dr * sin(start_angle));
04234 return (lineColor(dst, x, y, posX, posY, color));
04235 }
04236
04237
04238 vx = vy = (Sint16 *) malloc(2 * sizeof(Uint16) * numpoints);
04239 if (vx == NULL) {
04240 return (-1);
04241 }
04242 vy += numpoints;
04243
04244
04245 vx[0] = x;
04246 vy[0] = y;
04247
04248
04249 i = 1;
04250 angle = start_angle;
04251 while (angle <= end_angle) {
04252 vx[i] = x + (int) (dr * cos(angle));
04253 vy[i] = y + (int) (dr * sin(angle));
04254 angle += deltaAngle;
04255 i++;
04256 }
04257
04258
04259 if (filled) {
04260 result = filledPolygonColor(dst, vx, vy, numpoints, color);
04261 } else {
04262 result = polygonColor(dst, vx, vy, numpoints, color);
04263 }
04264
04265
04266 free(vx);
04267
04268 return (result);
04269 }
04270
04284 int pieColor(SDL_Surface * dst, Sint16 x, Sint16 y, Sint16 rad,
04285 Sint16 start, Sint16 end, Uint32 color)
04286 {
04287 return (_pieColor(dst, x, y, rad, start, end, color, 0));
04288
04289 }
04290
04307 int pieRGBA(SDL_Surface * dst, Sint16 x, Sint16 y, Sint16 rad,
04308 Sint16 start, Sint16 end, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
04309 {
04310 return (_pieColor(dst, x, y, rad, start, end,
04311 ((Uint32) r << 24) | ((Uint32) g << 16) | ((Uint32) b << 8) | (Uint32) a, 0));
04312
04313 }
04314
04328 int filledPieColor(SDL_Surface * dst, Sint16 x, Sint16 y, Sint16 rad, Sint16 start, Sint16 end, Uint32 color)
04329 {
04330 return (_pieColor(dst, x, y, rad, start, end, color, 1));
04331 }
04332
04349 int filledPieRGBA(SDL_Surface * dst, Sint16 x, Sint16 y, Sint16 rad,
04350 Sint16 start, Sint16 end, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
04351 {
04352 return (_pieColor(dst, x, y, rad, start, end,
04353 ((Uint32) r << 24) | ((Uint32) g << 16) | ((Uint32) b << 8) | (Uint32) a, 1));
04354 }
04355
04356
04357
04374 int trigonColor(SDL_Surface * dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Sint16 x3, Sint16 y3, Uint32 color)
04375 {
04376 Sint16 vx[3];
04377 Sint16 vy[3];
04378
04379 vx[0]=x1;
04380 vx[1]=x2;
04381 vx[2]=x3;
04382 vy[0]=y1;
04383 vy[1]=y2;
04384 vy[2]=y3;
04385
04386 return(polygonColor(dst,vx,vy,3,color));
04387 }
04388
04406 int trigonRGBA(SDL_Surface * dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Sint16 x3, Sint16 y3,
04407 Uint8 r, Uint8 g, Uint8 b, Uint8 a)
04408 {
04409 Sint16 vx[3];
04410 Sint16 vy[3];
04411
04412 vx[0]=x1;
04413 vx[1]=x2;
04414 vx[2]=x3;
04415 vy[0]=y1;
04416 vy[1]=y2;
04417 vy[2]=y3;
04418
04419 return(polygonRGBA(dst,vx,vy,3,r,g,b,a));
04420 }
04421
04422
04423
04440 int aatrigonColor(SDL_Surface * dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Sint16 x3, Sint16 y3, Uint32 color)
04441 {
04442 Sint16 vx[3];
04443 Sint16 vy[3];
04444
04445 vx[0]=x1;
04446 vx[1]=x2;
04447 vx[2]=x3;
04448 vy[0]=y1;
04449 vy[1]=y2;
04450 vy[2]=y3;
04451
04452 return(aapolygonColor(dst,vx,vy,3,color));
04453 }
04454
04472 int aatrigonRGBA(SDL_Surface * dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Sint16 x3, Sint16 y3,
04473 Uint8 r, Uint8 g, Uint8 b, Uint8 a)
04474 {
04475 Sint16 vx[3];
04476 Sint16 vy[3];
04477
04478 vx[0]=x1;
04479 vx[1]=x2;
04480 vx[2]=x3;
04481 vy[0]=y1;
04482 vy[1]=y2;
04483 vy[2]=y3;
04484
04485 return(aapolygonRGBA(dst,vx,vy,3,r,g,b,a));
04486 }
04487
04488
04489
04506 int filledTrigonColor(SDL_Surface * dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Sint16 x3, Sint16 y3, Uint32 color)
04507 {
04508 Sint16 vx[3];
04509 Sint16 vy[3];
04510
04511 vx[0]=x1;
04512 vx[1]=x2;
04513 vx[2]=x3;
04514 vy[0]=y1;
04515 vy[1]=y2;
04516 vy[2]=y3;
04517
04518 return(filledPolygonColor(dst,vx,vy,3,color));
04519 }
04520
04540 int filledTrigonRGBA(SDL_Surface * dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Sint16 x3, Sint16 y3,
04541 Uint8 r, Uint8 g, Uint8 b, Uint8 a)
04542 {
04543 Sint16 vx[3];
04544 Sint16 vy[3];
04545
04546 vx[0]=x1;
04547 vx[1]=x2;
04548 vx[2]=x3;
04549 vy[0]=y1;
04550 vy[1]=y2;
04551 vy[2]=y3;
04552
04553 return(filledPolygonRGBA(dst,vx,vy,3,r,g,b,a));
04554 }
04555
04556
04557
04569 int polygonColor(SDL_Surface * dst, const Sint16 * vx, const Sint16 * vy, int n, Uint32 color)
04570 {
04571 int result;
04572 int i;
04573 const Sint16 *x1, *y1, *x2, *y2;
04574
04575
04576
04577
04578 if ((dst->clip_rect.w==0) || (dst->clip_rect.h==0)) {
04579 return(0);
04580 }
04581
04582
04583
04584
04585 if (vx == NULL) {
04586 return (-1);
04587 }
04588 if (vy == NULL) {
04589 return (-1);
04590 }
04591
04592
04593
04594
04595 if (n < 3) {
04596 return (-1);
04597 }
04598
04599
04600
04601
04602 x1 = x2 = vx;
04603 y1 = y2 = vy;
04604 x2++;
04605 y2++;
04606
04607
04608
04609
04610 result = 0;
04611 for (i = 1; i < n; i++) {
04612 result |= lineColor(dst, *x1, *y1, *x2, *y2, color);
04613 x1 = x2;
04614 y1 = y2;
04615 x2++;
04616 y2++;
04617 }
04618 result |= lineColor(dst, *x1, *y1, *vx, *vy, color);
04619
04620 return (result);
04621 }
04622
04637 int polygonRGBA(SDL_Surface * dst, const Sint16 * vx, const Sint16 * vy, int n, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
04638 {
04639
04640
04641
04642 return (polygonColor(dst, vx, vy, n, ((Uint32) r << 24) | ((Uint32) g << 16) | ((Uint32) b << 8) | (Uint32) a));
04643 }
04644
04645
04646
04658 int aapolygonColor(SDL_Surface * dst, const Sint16 * vx, const Sint16 * vy, int n, Uint32 color)
04659 {
04660 int result;
04661 int i;
04662 const Sint16 *x1, *y1, *x2, *y2;
04663
04664
04665
04666
04667 if ((dst->clip_rect.w==0) || (dst->clip_rect.h==0)) {
04668 return(0);
04669 }
04670
04671
04672
04673
04674 if (vx == NULL) {
04675 return (-1);
04676 }
04677 if (vy == NULL) {
04678 return (-1);
04679 }
04680
04681
04682
04683
04684 if (n < 3) {
04685 return (-1);
04686 }
04687
04688
04689
04690
04691 x1 = x2 = vx;
04692 y1 = y2 = vy;
04693 x2++;
04694 y2++;
04695
04696
04697
04698
04699 result = 0;
04700 for (i = 1; i < n; i++) {
04701 result |= _aalineColor(dst, *x1, *y1, *x2, *y2, color, 0);
04702 x1 = x2;
04703 y1 = y2;
04704 x2++;
04705 y2++;
04706 }
04707 result |= _aalineColor(dst, *x1, *y1, *vx, *vy, color, 0);
04708
04709 return (result);
04710 }
04711
04726 int aapolygonRGBA(SDL_Surface * dst, const Sint16 * vx, const Sint16 * vy, int n, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
04727 {
04728
04729
04730
04731 return (aapolygonColor(dst, vx, vy, n, ((Uint32) r << 24) | ((Uint32) g << 16) | ((Uint32) b << 8) | (Uint32) a));
04732 }
04733
04734
04735
04744 int _gfxPrimitivesCompareInt(const void *a, const void *b)
04745 {
04746 return (*(const int *) a) - (*(const int *) b);
04747 }
04748
04754 static int *gfxPrimitivesPolyIntsGlobal = NULL;
04755
04761 static int gfxPrimitivesPolyAllocatedGlobal = 0;
04762
04778 int filledPolygonColorMT(SDL_Surface * dst, const Sint16 * vx, const Sint16 * vy, int n, Uint32 color, int **polyInts, int *polyAllocated)
04779 {
04780 int result;
04781 int i;
04782 int y, xa, xb;
04783 int miny, maxy;
04784 int x1, y1;
04785 int x2, y2;
04786 int ind1, ind2;
04787 int ints;
04788 int *gfxPrimitivesPolyInts = NULL;
04789 int gfxPrimitivesPolyAllocated = 0;
04790
04791
04792
04793
04794 if ((dst->clip_rect.w==0) || (dst->clip_rect.h==0)) {
04795 return(0);
04796 }
04797
04798
04799
04800
04801 if (vx == NULL) {
04802 return (-1);
04803 }
04804 if (vy == NULL) {
04805 return (-1);
04806 }
04807
04808
04809
04810
04811 if (n < 3) {
04812 return -1;
04813 }
04814
04815
04816
04817
04818 if ((polyInts==NULL) || (polyAllocated==NULL)) {
04819
04820 gfxPrimitivesPolyInts = gfxPrimitivesPolyIntsGlobal;
04821 gfxPrimitivesPolyAllocated = gfxPrimitivesPolyAllocatedGlobal;
04822 } else {
04823
04824 gfxPrimitivesPolyInts = *polyInts;
04825 gfxPrimitivesPolyAllocated = *polyAllocated;
04826 }
04827
04828
04829
04830
04831 if (!gfxPrimitivesPolyAllocated) {
04832 gfxPrimitivesPolyInts = (int *) malloc(sizeof(int) * n);
04833 gfxPrimitivesPolyAllocated = n;
04834 } else {
04835 if (gfxPrimitivesPolyAllocated < n) {
04836 gfxPrimitivesPolyInts = (int *) realloc(gfxPrimitivesPolyInts, sizeof(int) * n);
04837 gfxPrimitivesPolyAllocated = n;
04838 }
04839 }
04840
04841
04842
04843
04844 if (gfxPrimitivesPolyInts==NULL) {
04845 gfxPrimitivesPolyAllocated = 0;
04846 }
04847
04848
04849
04850
04851 if ((polyInts==NULL) || (polyAllocated==NULL)) {
04852 gfxPrimitivesPolyIntsGlobal = gfxPrimitivesPolyInts;
04853 gfxPrimitivesPolyAllocatedGlobal = gfxPrimitivesPolyAllocated;
04854 } else {
04855 *polyInts = gfxPrimitivesPolyInts;
04856 *polyAllocated = gfxPrimitivesPolyAllocated;
04857 }
04858
04859
04860
04861
04862 if (gfxPrimitivesPolyInts==NULL) {
04863 return(-1);
04864 }
04865
04866
04867
04868
04869 miny = vy[0];
04870 maxy = vy[0];
04871 for (i = 1; (i < n); i++) {
04872 if (vy[i] < miny) {
04873 miny = vy[i];
04874 } else if (vy[i] > maxy) {
04875 maxy = vy[i];
04876 }
04877 }
04878
04879
04880
04881
04882 result = 0;
04883 for (y = miny; (y <= maxy); y++) {
04884 ints = 0;
04885 for (i = 0; (i < n); i++) {
04886 if (!i) {
04887 ind1 = n - 1;
04888 ind2 = 0;
04889 } else {
04890 ind1 = i - 1;
04891 ind2 = i;
04892 }
04893 y1 = vy[ind1];
04894 y2 = vy[ind2];
04895 if (y1 < y2) {
04896 x1 = vx[ind1];
04897 x2 = vx[ind2];
04898 } else if (y1 > y2) {
04899 y2 = vy[ind1];
04900 y1 = vy[ind2];
04901 x2 = vx[ind1];
04902 x1 = vx[ind2];
04903 } else {
04904 continue;
04905 }
04906 if ( ((y >= y1) && (y < y2)) || ((y == maxy) && (y > y1) && (y <= y2)) ) {
04907 gfxPrimitivesPolyInts[ints++] = ((65536 * (y - y1)) / (y2 - y1)) * (x2 - x1) + (65536 * x1);
04908 }
04909 }
04910
04911 qsort(gfxPrimitivesPolyInts, ints, sizeof(int), _gfxPrimitivesCompareInt);
04912
04913 for (i = 0; (i < ints); i += 2) {
04914 xa = gfxPrimitivesPolyInts[i] + 1;
04915 xa = (xa >> 16) + ((xa & 32768) >> 15);
04916 xb = gfxPrimitivesPolyInts[i+1] - 1;
04917 xb = (xb >> 16) + ((xb & 32768) >> 15);
04918 result |= hlineColor(dst, xa, xb, y, color);
04919 }
04920 }
04921
04922 return (result);
04923 }
04924
04943 int filledPolygonRGBAMT(SDL_Surface * dst, const Sint16 * vx, const Sint16 * vy, int n, Uint8 r, Uint8 g, Uint8 b, Uint8 a, int **polyInts, int *polyAllocated)
04944 {
04945
04946
04947
04948 return (filledPolygonColorMT(dst, vx, vy, n, ((Uint32) r << 24) | ((Uint32) g << 16) | ((Uint32) b << 8) | (Uint32) a, polyInts, polyAllocated));
04949 }
04950
04965 int filledPolygonColor(SDL_Surface * dst, const Sint16 * vx, const Sint16 * vy, int n, Uint32 color)
04966 {
04967
04968
04969
04970 return (filledPolygonColorMT(dst, vx, vy, n, color, NULL, NULL));
04971 }
04972
04987 int filledPolygonRGBA(SDL_Surface * dst, const Sint16 * vx, const Sint16 * vy, int n, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
04988 {
04989
04990
04991
04992 return (filledPolygonColorMT(dst, vx, vy, n, ((Uint32) r << 24) | ((Uint32) g << 16) | ((Uint32) b << 8) | (Uint32) a, NULL, NULL));
04993 }
04994
05008 int _HLineTextured(SDL_Surface * dst, Sint16 x1, Sint16 x2, Sint16 y, SDL_Surface *texture, int texture_dx, int texture_dy)
05009 {
05010 Sint16 left, right, top, bottom;
05011 Sint16 w;
05012 Sint16 xtmp;
05013 int result = 0;
05014 int texture_x_walker;
05015 int texture_y_start;
05016 SDL_Rect source_rect,dst_rect;
05017 int pixels_written,write_width;
05018
05019
05020
05021
05022 if ((dst->clip_rect.w==0) || (dst->clip_rect.h==0)) {
05023 return(0);
05024 }
05025
05026
05027
05028
05029 if (x1 > x2) {
05030 xtmp = x1;
05031 x1 = x2;
05032 x2 = xtmp;
05033 }
05034
05035
05036
05037
05038
05039 left = dst->clip_rect.x;
05040 if (x2<left) {
05041 return(0);
05042 }
05043 right = dst->clip_rect.x + dst->clip_rect.w - 1;
05044 if (x1>right) {
05045 return(0);
05046 }
05047 top = dst->clip_rect.y;
05048 bottom = dst->clip_rect.y + dst->clip_rect.h - 1;
05049 if ((y<top) || (y>bottom)) {
05050 return (0);
05051 }
05052
05053
05054
05055
05056 if (x1 < left) {
05057 x1 = left;
05058 }
05059 if (x2 > right) {
05060 x2 = right;
05061 }
05062
05063
05064
05065
05066 w = x2 - x1;
05067
05068
05069
05070
05071 texture_x_walker = (x1 - texture_dx) % texture->w;
05072 if (texture_x_walker < 0){
05073 texture_x_walker = texture->w + texture_x_walker ;
05074 }
05075
05076 texture_y_start = (y + texture_dy) % texture->h;
05077 if (texture_y_start < 0){
05078 texture_y_start = texture->h + texture_y_start;
05079 }
05080
05081
05082 source_rect.y = texture_y_start;
05083 source_rect.x = texture_x_walker;
05084 source_rect.h = 1;
05085
05086
05087 dst_rect.y = y;
05088
05089
05090
05091 if (w <= texture->w -texture_x_walker){
05092 source_rect.w = w;
05093 source_rect.x = texture_x_walker;
05094 dst_rect.x= x1;
05095 result = (SDL_BlitSurface (texture, &source_rect , dst, &dst_rect) == 0);
05096 } else {
05097
05098 pixels_written = texture->w - texture_x_walker;
05099 source_rect.w = pixels_written;
05100 source_rect.x = texture_x_walker;
05101 dst_rect.x= x1;
05102 result |= (SDL_BlitSurface (texture, &source_rect , dst, &dst_rect) == 0);
05103 write_width = texture->w;
05104
05105
05106
05107 source_rect.x = 0;
05108 while (pixels_written < w){
05109 if (write_width >= w - pixels_written) {
05110 write_width = w - pixels_written;
05111 }
05112 source_rect.w = write_width;
05113 dst_rect.x = x1 + pixels_written;
05114 result |= (SDL_BlitSurface (texture,&source_rect , dst, &dst_rect) == 0);
05115 pixels_written += write_width;
05116 }
05117 }
05118
05119 return result;
05120 }
05121
05145 int texturedPolygonMT(SDL_Surface * dst, const Sint16 * vx, const Sint16 * vy, int n,
05146 SDL_Surface * texture, int texture_dx, int texture_dy, int **polyInts, int *polyAllocated)
05147 {
05148 int result;
05149 int i;
05150 int y, xa, xb;
05151 int minx,maxx,miny, maxy;
05152 int x1, y1;
05153 int x2, y2;
05154 int ind1, ind2;
05155 int ints;
05156 int *gfxPrimitivesPolyInts = NULL;
05157 int gfxPrimitivesPolyAllocated = 0;
05158
05159
05160
05161
05162 if ((dst->clip_rect.w==0) || (dst->clip_rect.h==0)) {
05163 return(0);
05164 }
05165
05166
05167
05168
05169 if (n < 3) {
05170 return -1;
05171 }
05172
05173
05174
05175
05176 if ((polyInts==NULL) || (polyAllocated==NULL)) {
05177
05178 gfxPrimitivesPolyInts = gfxPrimitivesPolyIntsGlobal;
05179 gfxPrimitivesPolyAllocated = gfxPrimitivesPolyAllocatedGlobal;
05180 } else {
05181
05182 gfxPrimitivesPolyInts = *polyInts;
05183 gfxPrimitivesPolyAllocated = *polyAllocated;
05184 }
05185
05186
05187
05188
05189 if (!gfxPrimitivesPolyAllocated) {
05190 gfxPrimitivesPolyInts = (int *) malloc(sizeof(int) * n);
05191 gfxPrimitivesPolyAllocated = n;
05192 } else {
05193 if (gfxPrimitivesPolyAllocated < n) {
05194 gfxPrimitivesPolyInts = (int *) realloc(gfxPrimitivesPolyInts, sizeof(int) * n);
05195 gfxPrimitivesPolyAllocated = n;
05196 }
05197 }
05198
05199
05200
05201
05202 if (gfxPrimitivesPolyInts==NULL) {
05203 gfxPrimitivesPolyAllocated = 0;
05204 }
05205
05206
05207
05208
05209 if ((polyInts==NULL) || (polyAllocated==NULL)) {
05210 gfxPrimitivesPolyIntsGlobal = gfxPrimitivesPolyInts;
05211 gfxPrimitivesPolyAllocatedGlobal = gfxPrimitivesPolyAllocated;
05212 } else {
05213 *polyInts = gfxPrimitivesPolyInts;
05214 *polyAllocated = gfxPrimitivesPolyAllocated;
05215 }
05216
05217
05218
05219
05220 if (gfxPrimitivesPolyInts==NULL) {
05221 return(-1);
05222 }
05223
05224
05225
05226
05227 miny = vy[0];
05228 maxy = vy[0];
05229 minx = vx[0];
05230 maxx = vx[0];
05231 for (i = 1; (i < n); i++) {
05232 if (vy[i] < miny) {
05233 miny = vy[i];
05234 } else if (vy[i] > maxy) {
05235 maxy = vy[i];
05236 }
05237 if (vx[i] < minx) {
05238 minx = vx[i];
05239 } else if (vx[i] > maxx) {
05240 maxx = vx[i];
05241 }
05242 }
05243 if (maxx <0 || minx > dst->w){
05244 return -1;
05245 }
05246 if (maxy <0 || miny > dst->h){
05247 return -1;
05248 }
05249
05250
05251
05252
05253 result = 0;
05254 for (y = miny; (y <= maxy); y++) {
05255 ints = 0;
05256 for (i = 0; (i < n); i++) {
05257 if (!i) {
05258 ind1 = n - 1;
05259 ind2 = 0;
05260 } else {
05261 ind1 = i - 1;
05262 ind2 = i;
05263 }
05264 y1 = vy[ind1];
05265 y2 = vy[ind2];
05266 if (y1 < y2) {
05267 x1 = vx[ind1];
05268 x2 = vx[ind2];
05269 } else if (y1 > y2) {
05270 y2 = vy[ind1];
05271 y1 = vy[ind2];
05272 x2 = vx[ind1];
05273 x1 = vx[ind2];
05274 } else {
05275 continue;
05276 }
05277 if ( ((y >= y1) && (y < y2)) || ((y == maxy) && (y > y1) && (y <= y2)) ) {
05278 gfxPrimitivesPolyInts[ints++] = ((65536 * (y - y1)) / (y2 - y1)) * (x2 - x1) + (65536 * x1);
05279 }
05280 }
05281
05282 qsort(gfxPrimitivesPolyInts, ints, sizeof(int), _gfxPrimitivesCompareInt);
05283
05284 for (i = 0; (i < ints); i += 2) {
05285 xa = gfxPrimitivesPolyInts[i] + 1;
05286 xa = (xa >> 16) + ((xa & 32768) >> 15);
05287 xb = gfxPrimitivesPolyInts[i+1] - 1;
05288 xb = (xb >> 16) + ((xb & 32768) >> 15);
05289 result |= _HLineTextured(dst, xa, xb, y, texture, texture_dx, texture_dy);
05290 }
05291 }
05292
05293 return (result);
05294 }
05295
05312 int texturedPolygon(SDL_Surface * dst, const Sint16 * vx, const Sint16 * vy, int n, SDL_Surface *texture, int texture_dx, int texture_dy)
05313 {
05314
05315
05316
05317 return (texturedPolygonMT(dst, vx, vy, n, texture, texture_dx, texture_dy, NULL, NULL));
05318 }
05319
05320
05321
05322
05326 static SDL_Surface *gfxPrimitivesFont[256];
05327
05331 static Uint32 gfxPrimitivesFontColor[256];
05332
05336 static const unsigned char *currentFontdata = gfxPrimitivesFontdata;
05337
05341 static Uint32 charWidth = 8;
05342
05346 static Uint32 charHeight = 8;
05347
05351 static Uint32 charWidthLocal = 8;
05352
05356 static Uint32 charHeightLocal = 8;
05357
05361 static Uint32 charPitch = 1;
05362
05366 static Uint32 charRotation = 0;
05367
05371 static Uint32 charSize = 8;
05372
05386 void gfxPrimitivesSetFont(const void *fontdata, Uint32 cw, Uint32 ch)
05387 {
05388 int i;
05389
05390 if ((fontdata) && (cw) && (ch)) {
05391 currentFontdata = fontdata;
05392 charWidth = cw;
05393 charHeight = ch;
05394 } else {
05395 currentFontdata = gfxPrimitivesFontdata;
05396 charWidth = 8;
05397 charHeight = 8;
05398 }
05399
05400 charPitch = (charWidth+7)/8;
05401 charSize = charPitch * charHeight;
05402
05403
05404 if ((charRotation==1) || (charRotation==3))
05405 {
05406 charWidthLocal = charHeight;
05407 charHeightLocal = charWidth;
05408 }
05409 else
05410 {
05411 charWidthLocal = charWidth;
05412 charHeightLocal = charHeight;
05413 }
05414
05415
05416 for (i = 0; i < 256; i++) {
05417 if (gfxPrimitivesFont[i]) {
05418 SDL_FreeSurface(gfxPrimitivesFont[i]);
05419 gfxPrimitivesFont[i] = NULL;
05420 }
05421 }
05422 }
05423
05432 void gfxPrimitivesSetFontRotation(Uint32 rotation)
05433 {
05434 int i;
05435
05436 rotation = rotation & 3;
05437 if (charRotation != rotation)
05438 {
05439
05440 charRotation = rotation;
05441
05442
05443 if ((charRotation==1) || (charRotation==3))
05444 {
05445 charWidthLocal = charHeight;
05446 charHeightLocal = charWidth;
05447 }
05448 else
05449 {
05450 charWidthLocal = charWidth;
05451 charHeightLocal = charHeight;
05452 }
05453
05454
05455 for (i = 0; i < 256; i++) {
05456 if (gfxPrimitivesFont[i]) {
05457 SDL_FreeSurface(gfxPrimitivesFont[i]);
05458 gfxPrimitivesFont[i] = NULL;
05459 }
05460 }
05461 }
05462 }
05463
05479 int characterColor(SDL_Surface * dst, Sint16 x, Sint16 y, char c, Uint32 color)
05480 {
05481 Sint16 left, right, top, bottom;
05482 Sint16 x1, y1, x2, y2;
05483 SDL_Rect srect;
05484 SDL_Rect drect;
05485 int result;
05486 Uint32 ix, iy;
05487 const unsigned char *charpos;
05488 Uint8 *curpos;
05489 int forced_redraw;
05490 Uint8 patt, mask;
05491 Uint8 *linepos;
05492 Uint32 pitch;
05493 SDL_Surface *rotatedCharacter;
05494 Uint32 ci;
05495
05496
05497
05498
05499 if ((dst->clip_rect.w==0) || (dst->clip_rect.h==0)) {
05500 return(0);
05501 }
05502
05503
05504
05505
05506
05507
05508 left = dst->clip_rect.x;
05509 x2 = x + charWidthLocal;
05510 if (x2<left) {
05511 return(0);
05512 }
05513 right = dst->clip_rect.x + dst->clip_rect.w - 1;
05514 x1 = x;
05515 if (x1>right) {
05516 return(0);
05517 }
05518 top = dst->clip_rect.y;
05519 y2 = y + charHeightLocal;
05520 if (y2<top) {
05521 return(0);
05522 }
05523 bottom = dst->clip_rect.y + dst->clip_rect.h - 1;
05524 y1 = y;
05525 if (y1>bottom) {
05526 return(0);
05527 }
05528
05529
05530
05531
05532 srect.x = 0;
05533 srect.y = 0;
05534 srect.w = charWidthLocal;
05535 srect.h = charHeightLocal;
05536
05537
05538
05539
05540 drect.x = x;
05541 drect.y = y;
05542 drect.w = charWidthLocal;
05543 drect.h = charHeightLocal;
05544
05545
05546 ci = (unsigned char) c;
05547
05548
05549
05550
05551
05552 if (gfxPrimitivesFont[ci] == NULL) {
05553 gfxPrimitivesFont[ci] =
05554 SDL_CreateRGBSurface(SDL_SWSURFACE | SDL_HWSURFACE | SDL_SRCALPHA,
05555 charWidth, charHeight, 32,
05556 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF);
05557
05558
05559
05560 if (gfxPrimitivesFont[ci] == NULL) {
05561 return (-1);
05562 }
05563
05564
05565
05566 forced_redraw = 1;
05567 } else {
05568 forced_redraw = 0;
05569 }
05570
05571
05572
05573
05574 if ((gfxPrimitivesFontColor[ci] != color) || (forced_redraw)) {
05575
05576
05577
05578 SDL_SetAlpha(gfxPrimitivesFont[ci], SDL_SRCALPHA, 255);
05579 gfxPrimitivesFontColor[ci] = color;
05580
05581
05582 if (SDL_LockSurface(gfxPrimitivesFont[ci]) != 0)
05583 return (-1);
05584
05585
05586
05587
05588 charpos = currentFontdata + ci * charSize;
05589 linepos = (Uint8 *) gfxPrimitivesFont[ci]->pixels;
05590 pitch = gfxPrimitivesFont[ci]->pitch;
05591
05592
05593
05594
05595 patt = 0;
05596 for (iy = 0; iy < charHeight; iy++) {
05597 mask = 0x00;
05598 curpos = linepos;
05599 for (ix = 0; ix < charWidth; ix++) {
05600 if (!(mask >>= 1)) {
05601 patt = *charpos++;
05602 mask = 0x80;
05603 }
05604
05605 if (patt & mask)
05606 *(Uint32 *)curpos = color;
05607 else
05608 *(Uint32 *)curpos = 0;
05609 curpos += 4;
05610 }
05611 linepos += pitch;
05612 }
05613
05614
05615 SDL_UnlockSurface(gfxPrimitivesFont[ci]);
05616
05617
05618 if (charRotation>0)
05619 {
05620 rotatedCharacter = rotateSurface90Degrees(gfxPrimitivesFont[ci], charRotation);
05621 SDL_FreeSurface(gfxPrimitivesFont[ci]);
05622 gfxPrimitivesFont[ci] = rotatedCharacter;
05623 }
05624 }
05625
05626
05627
05628
05629 result = SDL_BlitSurface(gfxPrimitivesFont[ci], &srect, dst, &drect);
05630
05631 return (result);
05632 }
05633
05648 int characterRGBA(SDL_Surface * dst, Sint16 x, Sint16 y, char c, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
05649 {
05650
05651
05652
05653 return (characterColor(dst, x, y, c, ((Uint32) r << 24) | ((Uint32) g << 16) | ((Uint32) b << 8) | (Uint32) a));
05654 }
05655
05670 int stringColor(SDL_Surface * dst, Sint16 x, Sint16 y, const char *s, Uint32 color)
05671 {
05672 int result = 0;
05673 Sint16 curx = x;
05674 Sint16 cury = y;
05675 const char *curchar = s;
05676
05677 while (*curchar && !result) {
05678 result |= characterColor(dst, curx, cury, *curchar, color);
05679 switch (charRotation)
05680 {
05681 case 0:
05682 curx += charWidthLocal;
05683 break;
05684 case 2:
05685 curx -= charWidthLocal;
05686 break;
05687 case 1:
05688 cury += charHeightLocal;
05689 break;
05690 case 3:
05691 cury -= charHeightLocal;
05692 break;
05693 }
05694 curchar++;
05695 }
05696
05697 return (result);
05698 }
05699
05714 int stringRGBA(SDL_Surface * dst, Sint16 x, Sint16 y, const char *s, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
05715 {
05716
05717
05718
05719 return (stringColor(dst, x, y, s, ((Uint32) r << 24) | ((Uint32) g << 16) | ((Uint32) b << 8) | (Uint32) a));
05720 }
05721
05722
05723
05733 double _evaluateBezier (double *data, int ndata, double t)
05734 {
05735 double mu, result;
05736 int n,k,kn,nn,nkn;
05737 double blend,muk,munk;
05738
05739
05740 if (t<0.0) {
05741 return(data[0]);
05742 }
05743 if (t>=(double)ndata) {
05744 return(data[ndata-1]);
05745 }
05746
05747
05748 mu=t/(double)ndata;
05749
05750
05751 n=ndata-1;
05752 result=0.0;
05753 muk = 1;
05754 munk = pow(1-mu,(double)n);
05755 for (k=0;k<=n;k++) {
05756 nn = n;
05757 kn = k;
05758 nkn = n - k;
05759 blend = muk * munk;
05760 muk *= mu;
05761 munk /= (1-mu);
05762 while (nn >= 1) {
05763 blend *= nn;
05764 nn--;
05765 if (kn > 1) {
05766 blend /= (double)kn;
05767 kn--;
05768 }
05769 if (nkn > 1) {
05770 blend /= (double)nkn;
05771 nkn--;
05772 }
05773 }
05774 result += data[k] * blend;
05775 }
05776
05777 return(result);
05778 }
05779
05792 int bezierColor(SDL_Surface * dst, const Sint16 * vx, const Sint16 * vy, int n, int s, Uint32 color)
05793 {
05794 int result;
05795 int i;
05796 double *x, *y, t, stepsize;
05797 Sint16 x1, y1, x2, y2;
05798
05799
05800
05801
05802 if (n < 3) {
05803 return (-1);
05804 }
05805 if (s < 2) {
05806 return (-1);
05807 }
05808
05809
05810
05811
05812 stepsize=(double)1.0/(double)s;
05813
05814
05815 if ((x=(double *)malloc(sizeof(double)*(n+1)))==NULL) {
05816 return(-1);
05817 }
05818 if ((y=(double *)malloc(sizeof(double)*(n+1)))==NULL) {
05819 free(x);
05820 return(-1);
05821 }
05822 for (i=0; i<n; i++) {
05823 x[i]=vx[i];
05824 y[i]=vy[i];
05825 }
05826 x[n]=vx[0];
05827 y[n]=vy[0];
05828
05829
05830
05831
05832 result = 0;
05833 t=0.0;
05834 x1=(Sint16)lrint(_evaluateBezier(x,n+1,t));
05835 y1=(Sint16)lrint(_evaluateBezier(y,n+1,t));
05836 for (i = 0; i <= (n*s); i++) {
05837 t += stepsize;
05838 x2=(Sint16)_evaluateBezier(x,n,t);
05839 y2=(Sint16)_evaluateBezier(y,n,t);
05840 result |= lineColor(dst, x1, y1, x2, y2, color);
05841 x1 = x2;
05842 y1 = y2;
05843 }
05844
05845
05846 free(x);
05847 free(y);
05848
05849 return (result);
05850 }
05851
05867 int bezierRGBA(SDL_Surface * dst, const Sint16 * vx, const Sint16 * vy, int n, int s, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
05868 {
05869
05870
05871
05872 return (bezierColor(dst, vx, vy, n, s, ((Uint32) r << 24) | ((Uint32) g << 16) | ((Uint32) b << 8) | (Uint32) a));
05873 }