00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include "OSDLFromGfx.h"
00028
00029 #include "OSDLPixel.h"
00030
00031 #include "Ceylan.h"
00032
00033
00034
00035
00036
00037 #ifdef OSDL_USES_CONFIG_H
00038 #include <OSDLConfig.h>
00039 #endif // OSDL_USES_CONFIG_H
00040
00041 #if OSDL_ARCH_NINTENDO_DS
00042 #include "OSDLConfigForNintendoDS.h"
00043 #endif // OSDL_ARCH_NINTENDO_DS
00044
00045
00046
00047 #if OSDL_USES_SDL
00048
00049 #include "SDL.h"
00050
00051 using namespace OSDL::Video ;
00052
00053 using namespace Ceylan ;
00054 using namespace Ceylan::Log ;
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073 int filledCircleColorNotBlended( SDL_Surface * dst,
00074 Ceylan::Sint16 x, Ceylan::Sint16 y,
00075 Ceylan::Sint16 r, OSDL::Video::Pixels::ColorDefinition ) ;
00076
00077
00078 static int clipLine(SDL_Surface * dst, Ceylan::Sint16 * x1, Ceylan::Sint16 * y1,
00079 Ceylan::Sint16 * x2, Ceylan::Sint16 * y2) ;
00080
00081
00082
00083 int VLineAlpha(SDL_Surface * dst, Ceylan::Sint16 x, Ceylan::Sint16 y1,
00084 Ceylan::Sint16 y2, Ceylan::Uint32 color) ;
00085
00086
00087 int filledRectAlpha(SDL_Surface * dst, Ceylan::Sint16 x1, Ceylan::Sint16 y1,
00088 Ceylan::Sint16 x2, Ceylan::Sint16 y2, Ceylan::Uint32 color) ;
00089
00090
00091 int lineColor(SDL_Surface * dst, Ceylan::Sint16 x1, Ceylan::Sint16 y1,
00092 Ceylan::Sint16 x2, Ceylan::Sint16 y2, Ceylan::Uint32 color) ;
00093
00094 int hlineColor(SDL_Surface * dst, Ceylan::Sint16 x1, Ceylan::Sint16 x2,
00095 Ceylan::Sint16 y, Ceylan::Uint32 color) ;
00096
00097
00098 int vlineColor(SDL_Surface * dst, Ceylan::Sint16 x, Ceylan::Sint16 y1,
00099 Ceylan::Sint16 y2, Ceylan::Uint32 color) ;
00100
00101
00102 int pixelColorWeightNolock(SDL_Surface * dst, Ceylan::Sint16 x,
00103 Ceylan::Sint16 y, Ceylan::Uint32 color, Ceylan::Uint32 weight) ;
00104
00105 int _putPixelAlpha(SDL_Surface * surface, Ceylan::Sint16 x, Ceylan::Sint16 y,
00106 Ceylan::Uint32 color, Ceylan::Uint8 alpha) ;
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122 #define clip_xmin(surface) surface->clip_rect.x
00123 #define clip_xmax(surface) surface->clip_rect.x+surface->clip_rect.w-1
00124 #define clip_ymin(surface) surface->clip_rect.y
00125 #define clip_ymax(surface) surface->clip_rect.y+surface->clip_rect.h-1
00126
00127
00128
00129
00130
00131
00132 #define CLIP_LEFT_EDGE 0x1
00133 #define CLIP_RIGHT_EDGE 0x2
00134 #define CLIP_BOTTOM_EDGE 0x4
00135 #define CLIP_TOP_EDGE 0x8
00136 #define CLIP_INSIDE(a) (!a)
00137 #define CLIP_REJECT(a,b) (a&b)
00138 #define CLIP_ACCEPT(a,b) (!(a|b))
00139
00140 static int clipEncode(Ceylan::Sint16 x, Ceylan::Sint16 y, Ceylan::Sint16 left,
00141 Ceylan::Sint16 top, Ceylan::Sint16 right, Ceylan::Sint16 bottom)
00142 {
00143 int code = 0;
00144
00145 if (x < left) {
00146 code |= CLIP_LEFT_EDGE;
00147 } else if (x > right) {
00148 code |= CLIP_RIGHT_EDGE;
00149 }
00150 if (y < top) {
00151 code |= CLIP_TOP_EDGE;
00152 } else if (y > bottom) {
00153 code |= CLIP_BOTTOM_EDGE;
00154 }
00155 return code;
00156 }
00157
00158
00159
00160
00179 int putPixelAlpha( SDL_Surface * surface, Ceylan::Sint16 x, Ceylan::Sint16 y,
00180 OSDL::Video::Pixels::PixelColor color,
00181 OSDL::Video::Pixels::ColorElement alpha )
00182 {
00183
00184
00185 #if OSDL_DEBUG_PIXEL
00186
00187 if ( x % 20 == 0 && y % 20 == 0 )
00188 {
00189 LogPlug::trace( "putPixelAlpha (OSDLFromGfx.cc): putting at ["
00190 + Ceylan::toString( x ) + ";" + Ceylan::toString( y )
00191 + "] pixel color " + Pixels::toString(
00192 Pixels::convertPixelColorToColorDefinition(
00193 * surface->format, color ) )
00194 + " with alpha coordinate = "
00195 + Ceylan::toNumericalString( alpha ) ) ;
00196 }
00197
00198 #endif // OSDL_DEBUG_PIXEL
00199
00200 Ceylan::Uint32 Rmask = surface->format->Rmask ;
00201 Ceylan::Uint32 Gmask = surface->format->Gmask ;
00202 Ceylan::Uint32 Bmask = surface->format->Bmask ;
00203 Ceylan::Uint32 Amask = surface->format->Amask ;
00204
00205 Ceylan::Uint32 R, G, B, A = 0 ;
00206
00207
00208 if ( x >= clip_xmin(surface) && x <= clip_xmax(surface)
00209 && y >= clip_ymin(surface) && y <= clip_ymax(surface) )
00210 {
00211
00212 switch( surface->format->BytesPerPixel )
00213 {
00214
00215 case 1:
00216 {
00217
00218
00219 if (alpha == 255)
00220 {
00221 *((Ceylan::Uint8 *) surface->pixels + y * surface->pitch + x)
00222 = color ;
00223 }
00224 else
00225 {
00226 Ceylan::Uint8 *pixel =
00227 (Ceylan::Uint8 *) surface->pixels + y * surface->pitch + x ;
00228
00229 Ceylan::Uint8 dR = surface->format->palette->colors[*pixel].r;
00230 Ceylan::Uint8 dG = surface->format->palette->colors[*pixel].g;
00231 Ceylan::Uint8 dB = surface->format->palette->colors[*pixel].b;
00232 Ceylan::Uint8 sR = surface->format->palette->colors[color].r;
00233 Ceylan::Uint8 sG = surface->format->palette->colors[color].g;
00234 Ceylan::Uint8 sB = surface->format->palette->colors[color].b;
00235
00236 dR = dR + ((sR - dR) * alpha >> 8);
00237 dG = dG + ((sG - dG) * alpha >> 8);
00238 dB = dB + ((sB - dB) * alpha >> 8);
00239
00240 *pixel = SDL_MapRGB(surface->format, dR, dG, dB);
00241 }
00242 }
00243 break ;
00244
00245 case 2:
00246 {
00247
00248
00249 if (alpha == 255)
00250 {
00251
00252 *((Ceylan::Uint16 *) surface->pixels + y * surface->pitch / 2
00253 + x) = color;
00254
00255 }
00256 else
00257 {
00258
00259 Ceylan::Uint16 *pixel = (Ceylan::Uint16 *) surface->pixels
00260 + y * surface->pitch / 2 + x;
00261 Ceylan::Uint32 dc = *pixel;
00262
00263 R = ((dc & Rmask)
00264 + (((color & Rmask) - (dc & Rmask)) * alpha >> 8)) & Rmask;
00265
00266 G = ((dc & Gmask)
00267 + (((color & Gmask) - (dc & Gmask)) * alpha >> 8)) & Gmask;
00268 B = ((dc & Bmask)
00269 + (((color & Bmask) - (dc & Bmask)) * alpha >> 8)) & Bmask;
00270
00271 if (Amask)
00272 A = ((dc & Amask) + (((color & Amask) - (dc & Amask))
00273 * alpha >> 8)) & Amask;
00274
00275 *pixel = R | G | B | A;
00276
00277 }
00278 }
00279 break;
00280
00281 case 3:
00282 {
00283
00284 Ceylan::Uint8 *pix = (Ceylan::Uint8 *) surface->pixels
00285 + y * surface->pitch + x * 3;
00286 Ceylan::Uint8 rshift8 = surface->format->Rshift / 8;
00287 Ceylan::Uint8 gshift8 = surface->format->Gshift / 8;
00288 Ceylan::Uint8 bshift8 = surface->format->Bshift / 8;
00289 Ceylan::Uint8 ashift8 = surface->format->Ashift / 8;
00290
00291
00292 if (alpha == 255)
00293 {
00294 *(pix + rshift8) = color >> surface->format->Rshift;
00295 *(pix + gshift8) = color >> surface->format->Gshift;
00296 *(pix + bshift8) = color >> surface->format->Bshift;
00297 *(pix + ashift8) = color >> surface->format->Ashift;
00298 }
00299 else
00300 {
00301 Ceylan::Uint8 dR, dG, dB, dA = 0;
00302 Ceylan::Uint8 sR, sG, sB, sA = 0;
00303
00304 pix = (Ceylan::Uint8 *) surface->pixels
00305 + y * surface->pitch + x * 3;
00306
00307 dR = *((pix) + rshift8);
00308 dG = *((pix) + gshift8);
00309 dB = *((pix) + bshift8);
00310 dA = *((pix) + ashift8);
00311
00312 sR = (color >> surface->format->Rshift) & 0xff;
00313 sG = (color >> surface->format->Gshift) & 0xff;
00314 sB = (color >> surface->format->Bshift) & 0xff;
00315 sA = (color >> surface->format->Ashift) & 0xff;
00316
00317 dR = dR + ((sR - dR) * alpha >> 8);
00318 dG = dG + ((sG - dG) * alpha >> 8);
00319 dB = dB + ((sB - dB) * alpha >> 8);
00320 dA = dA + ((sA - dA) * alpha >> 8);
00321
00322 *((pix) + rshift8) = dR;
00323 *((pix) + gshift8) = dG;
00324 *((pix) + bshift8) = dB;
00325 *((pix) + ashift8) = dA;
00326 }
00327 }
00328 break;
00329
00330
00331 case 4:
00332 {
00333
00334 if (alpha == 255)
00335 {
00336 *((Ceylan::Uint32 *) surface->pixels
00337 + y * surface->pitch / 4 + x) = color;
00338 }
00339 else
00340 {
00341
00342 Ceylan::Uint32 *pixel = (Ceylan::Uint32 *) surface->pixels
00343 + y * surface->pitch / 4 + x;
00344
00345 Ceylan::Uint32 dc = *pixel;
00346
00347 R = ((dc & Rmask)
00348 + (((color & Rmask) - (dc & Rmask)) * alpha >> 8)) & Rmask;
00349
00350 G = ((dc & Gmask)
00351 + (((color & Gmask) - (dc & Gmask)) * alpha >> 8)) & Gmask;
00352
00353 B = ((dc & Bmask)
00354 + (((color & Bmask) - (dc & Bmask)) * alpha >> 8)) & Bmask;
00355
00356 if (Amask)
00357 A = ((dc & Amask) + (((color & Amask) - (dc & Amask))
00358 * alpha >> 8)) & Amask;
00359
00360 *pixel = R | G | B | A;
00361
00362 }
00363 }
00364 break;
00365
00366 default:
00367 LogPlug::error( "putPixelAlpha: unexpected bpp ("
00368 + Ceylan::toString( surface->format->BytesPerPixel ) + ")" ) ;
00369 break ;
00370
00371
00372 }
00373
00374
00375 }
00376 else
00377 {
00378
00379
00380 #if OSDL_DEBUG_PIXEL
00381 LogPlug::trace( "putPixelAlpha (OSDLFromGfx.cc): "
00382 "pixel clipped out since location ["
00383 + Ceylan::toString( x ) + ";" + Ceylan::toString( y )
00384 + "] is out of surface bounds" ) ;
00385 #endif // OSDL_DEBUG_PIXEL
00386
00387 }
00388
00389 return 0 ;
00390
00391 }
00392
00393
00394
00395 int filledCircleRGBANotBlended( SDL_Surface * dst, Ceylan::Sint16 x,
00396 Ceylan::Sint16 y, Ceylan::Sint16 rad, Ceylan::Uint8 r, Ceylan::Uint8 g,
00397 Ceylan::Uint8 b, Ceylan::Uint8 a )
00398 {
00399
00400
00401
00402
00403 return::filledCircleColorNotBlended( dst, x, y, rad,
00404 Pixels::convertRGBAToColorDefinition( r, g, b, a ) ) ;
00405
00406 }
00407
00408
00409 int pixelColorNolock(SDL_Surface * dst, Ceylan::Sint16 x, Ceylan::Sint16 y,
00410 Ceylan::Uint32 color)
00411 {
00412 Ceylan::Uint8 alpha;
00413 Ceylan::Uint32 mcolor;
00414 int result = 0;
00415
00416
00417
00418
00419 alpha = color & 0x000000ff;
00420 mcolor =
00421 SDL_MapRGBA(dst->format, (color & 0xff000000) >> 24,
00422 (color & 0x00ff0000) >> 16, (color & 0x0000ff00) >> 8, alpha);
00423
00424
00425
00426
00427 result = _putPixelAlpha(dst, x, y, mcolor, alpha);
00428
00429 return (result);
00430 }
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441 #ifdef OSDL_CIRCLE_NOT_BLENDED_IMPLEMENTED
00442
00443 int aacircleRGBANotBlended( SDL_Surface * dst, Ceylan::Sint16 x,
00444 Ceylan::Sint16 y, Ceylan::Sint16 rad, Ceylan::Uint8 r, Ceylan::Uint8 g,
00445 Ceylan::Uint8 b, Ceylan::Uint8 a )
00446 {
00447
00448
00449
00450
00451 return::aaellipseColorNotBlended( dst, x, y, rad, rad,
00452 Pixels::convertRGBAToColorDefinition( r, g, b, a ) ) ;
00453
00454 }
00455
00456
00457
00458 int::circleRGBANotBlended( SDL_Surface * dst, Ceylan::Sint16 x,
00459 Ceylan::Sint16 y, Ceylan::Sint16 rad, Ceylan::Uint8 r,
00460 Ceylan::Uint8 g, Ceylan::Uint8 b, Ceylan::Uint8 a)
00461 {
00462
00463
00464
00465
00466 return::circleColor( dst, x, y, rad,
00467 Pixels::convertRGBAToColorDefinition( r, g, b, a ) ) ;
00468
00469 }
00470
00471
00472 #endif // OSDL_CIRCLE_NOT_BLENDED_IMPLEMENTED
00473
00474
00475
00476 int filledCircleColorNotBlended( SDL_Surface * dst, Ceylan::Sint16 x,
00477 Ceylan::Sint16 y, Ceylan::Sint16 r, Pixels::ColorDefinition color )
00478 {
00479
00480 #if OSDL_USES_SDL_GFX
00481
00482 #if OSDL_DEBUG_PIXEL
00483
00484 LogPlug::trace( "filledCircleColorNotBlended: "
00485 "drawing a non-blended disc at ["
00486 + Ceylan::toString( x ) + ";" + Ceylan::toString( y )
00487 + "], with radius = " + Ceylan::toString( r )
00488 + " and color definition " + Pixels::toString( color ) ) ;
00489
00490 #endif // OSDL_DEBUG_PIXEL
00491
00492 Ceylan::Sint16 left, right, top, bottom;
00493 int result;
00494 Ceylan::Sint16 x1, y1, x2, y2;
00495 Ceylan::Sint16 cx = 0;
00496 Ceylan::Sint16 cy = r;
00497 Ceylan::Sint16 ocx = ( Ceylan::Sint16 ) 0xffff;
00498 Ceylan::Sint16 ocy = ( Ceylan::Sint16 ) 0xffff;
00499 Ceylan::Sint16 df = 1 - r;
00500 Ceylan::Sint16 d_e = 3;
00501 Ceylan::Sint16 d_se = -2 * r + 5;
00502 Ceylan::Sint16 xpcx, xmcx, xpcy, xmcy;
00503 Ceylan::Sint16 ypcy, ymcy, ypcx, ymcx;
00504
00505 Pixels::PixelColor convertedColor = SDL_MapRGBA( dst->format,
00506 color.r, color.g, color.b, color.unused ) ;
00507
00508
00509
00510
00511 if (r < 0) {
00512 return (-1);
00513 }
00514
00515
00516
00517
00518 if (r == 0) {
00519
00520
00521
00522
00523
00524
00525
00526 fastPixelColor( dst, x, y, convertedColor ) ;
00527 }
00528
00529
00530
00531
00532 left = dst->clip_rect.x;
00533 right = dst->clip_rect.x + dst->clip_rect.w - 1;
00534 top = dst->clip_rect.y;
00535 bottom = dst->clip_rect.y + dst->clip_rect.h - 1;
00536
00537
00538
00539
00540 x1 = x - r;
00541 x2 = x + r;
00542 y1 = y - r;
00543 y2 = y + r;
00544 if ((x1<left) && (x2<left)) {
00545 return(0);
00546 }
00547 if ((x1>right) && (x2>right)) {
00548 return(0);
00549 }
00550 if ((y1<top) && (y2<top)) {
00551 return(0);
00552 }
00553 if ((y1>bottom) && (y2>bottom)) {
00554 return(0);
00555 }
00556
00557
00558
00559
00560 result = 0;
00561 do {
00562 xpcx = x + cx;
00563 xmcx = x - cx;
00564 xpcy = x + cy;
00565 xmcy = x - cy;
00566 if (ocy != cy) {
00567 if (cy > 0) {
00568 ypcy = y + cy;
00569 ymcy = y - cy;
00570
00571
00572
00573
00574
00575
00576
00577 result |= hlineColorStore(dst, xmcx, xpcx, ypcy, convertedColor);
00578 result |= hlineColorStore(dst, xmcx, xpcx, ymcy, convertedColor);
00579 } else {
00580 result |= hlineColorStore(dst, xmcx, xpcx, y, convertedColor);
00581 }
00582 ocy = cy;
00583 }
00584 if (ocx != cx) {
00585 if (cx != cy) {
00586 if (cx > 0) {
00587 ypcx = y + cx;
00588 ymcx = y - cx;
00589 result |= hlineColorStore(dst, xmcy, xpcy, ymcx, convertedColor);
00590 result |= hlineColorStore(dst, xmcy, xpcy, ypcx, convertedColor);
00591 } else {
00592 result |= hlineColorStore(dst, xmcy, xpcy, y, convertedColor);
00593 }
00594 }
00595 ocx = cx;
00596 }
00597
00598
00599
00600 if (df < 0) {
00601 df += d_e;
00602 d_e += 2;
00603 d_se += 2;
00604 } else {
00605 df += d_se;
00606 d_e += 2;
00607 d_se += 4;
00608 cy--;
00609 }
00610 cx++;
00611 } while (cx <= cy);
00612
00613 return (result);
00614 }
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629 int hlineColorStore( SDL_Surface * dst, Ceylan::Sint16 x1,
00630 Ceylan::Sint16 x2, Ceylan::Sint16 y, Pixels::PixelColor color )
00631 {
00632 Ceylan::Sint16 left, right, top, bottom;
00633 Ceylan::Uint8 *pixel, *pixellast;
00634 int dx;
00635 int pixx, pixy;
00636 Ceylan::Sint16 w;
00637 Ceylan::Sint16 xtmp;
00638 int result = -1;
00639
00640
00641
00642
00643 left = dst->clip_rect.x;
00644 right = dst->clip_rect.x + dst->clip_rect.w - 1;
00645 top = dst->clip_rect.y;
00646 bottom = dst->clip_rect.y + dst->clip_rect.h - 1;
00647
00648
00649
00650
00651 if ((x1<left) && (x2<left)) {
00652 return(0);
00653 }
00654 if ((x1>right) && (x2>right)) {
00655 return(0);
00656 }
00657 if ((y<top) || (y>bottom)) {
00658 return (0);
00659 }
00660
00661
00662
00663
00664 if (x1 < left) {
00665 x1 = left;
00666 }
00667 if (x2 > right) {
00668 x2 = right;
00669 }
00670
00671
00672
00673
00674 if (x1 > x2) {
00675 xtmp = x1;
00676 x1 = x2;
00677 x2 = xtmp;
00678 }
00679
00680
00681
00682
00683 w = x2 - x1;
00684
00685
00686
00687
00688 if (w < 0) {
00689 return (0);
00690 }
00691
00692
00693
00694
00695 SDL_LockSurface(dst);
00696
00697
00698
00699
00700 dx = w;
00701 pixx = dst->format->BytesPerPixel;
00702 pixy = dst->pitch;
00703 pixel = ((Ceylan::Uint8 *) dst->pixels) + pixx * (int) x1 + pixy * (int) y;
00704
00705
00706
00707
00708 switch (dst->format->BytesPerPixel) {
00709 case 1:
00710 memset(pixel, color, dx);
00711 break;
00712 case 2:
00713 pixellast = pixel + dx + dx;
00714 for (; pixel <= pixellast; pixel += pixx) {
00715 *( Ceylan::Uint16 * ) pixel = color;
00716 }
00717 break;
00718 case 3:
00719 pixellast = pixel + dx + dx + dx;
00720 for (; pixel <= pixellast; pixel += pixx) {
00721 if (SDL_BYTEORDER == SDL_BIG_ENDIAN) {
00722 pixel[0] = (color >> 16) & 0xff;
00723 pixel[1] = (color >> 8) & 0xff;
00724 pixel[2] = color & 0xff;
00725 } else {
00726 pixel[0] = color & 0xff;
00727 pixel[1] = (color >> 8) & 0xff;
00728 pixel[2] = (color >> 16) & 0xff;
00729 }
00730 }
00731 break;
00732 default:
00733 dx = dx + dx;
00734 pixellast = pixel + dx + dx;
00735 for (; pixel <= pixellast; pixel += pixx)
00736 {
00737 *( Ceylan::Uint32 * ) pixel = color;
00738 }
00739 break;
00740 }
00741
00742
00743
00744
00745 SDL_UnlockSurface(dst);
00746
00747
00748
00749
00750 result = 0;
00751
00752 return (result);
00753
00754 #else // OSDL_USES_SDL_GFX
00755
00756 throw VideoException( "OSDLFromGfx: filledCircleColorNotBlended "
00757 "not available: no SDL_gfx support available." ) ;
00758
00759 #endif // OSDL_USES_SDL_GFX
00760
00761 }
00762
00763
00764
00765
00766
00767
00768
00769
00770 int fastPixelColor(SDL_Surface * dst, Ceylan::Sint16 x,
00771 Ceylan::Sint16 y, Ceylan::Uint32 color)
00772 {
00773
00774 #if OSDL_USES_SDL_GFX
00775
00776 int result;
00777
00778
00779
00780
00781 if (SDL_MUSTLOCK(dst)) {
00782 if (SDL_LockSurface(dst) < 0) {
00783 return (-1);
00784 }
00785 }
00786
00787 result = fastPixelColorNolock(dst, x, y, color);
00788
00789
00790
00791
00792 if (SDL_MUSTLOCK(dst)) {
00793 SDL_UnlockSurface(dst);
00794 }
00795
00796 return (result);
00797
00798 #else // OSDL_USES_SDL_GFX
00799
00800 throw VideoException( "OSDLFromGfx: fastPixelColor "
00801 "not available: no SDL_gfx support available." ) ;
00802
00803 #endif // OSDL_USES_SDL_GFX
00804
00805 }
00806
00807
00808
00809
00810
00811
00812
00813
00814
00815
00816 int fastPixelColorNolock(SDL_Surface * dst, Ceylan::Sint16 x,
00817 Ceylan::Sint16 y, Pixels::PixelColor color)
00818 {
00819
00820 int bpp;
00821 Ceylan::Uint8 *p;
00822
00823
00824
00825
00826 if ((x >= clip_xmin(dst)) && (x <= clip_xmax(dst)) && (y >= clip_ymin(dst))
00827 && (y <= clip_ymax(dst))) {
00828
00829
00830
00831
00832 bpp = dst->format->BytesPerPixel;
00833 p = (Ceylan::Uint8 *) dst->pixels + y * dst->pitch + x * bpp;
00834 switch (bpp) {
00835 case 1:
00836 *p = color;
00837 break;
00838 case 2:
00839 *( Ceylan::Uint16 * ) p = color;
00840 break;
00841 case 3:
00842 if (SDL_BYTEORDER == SDL_BIG_ENDIAN) {
00843 p[0] = (color >> 16) & 0xff;
00844 p[1] = (color >> 8) & 0xff;
00845 p[2] = color & 0xff;
00846 } else {
00847 p[0] = color & 0xff;
00848 p[1] = (color >> 8) & 0xff;
00849 p[2] = (color >> 16) & 0xff;
00850 }
00851 break;
00852 case 4:
00853 *( Ceylan::Uint32 * ) p = color;
00854 break;
00855 }
00856
00857
00858 }
00859
00860 return (0);
00861
00862 }
00863
00864
00865
00866
00867
00868 int fastPixelColorNolockNoclip(SDL_Surface * dst, Ceylan::Sint16 x,
00869 Ceylan::Sint16 y, Ceylan::Uint32 color)
00870 {
00871 int bpp;
00872 Ceylan::Uint8 *p;
00873
00874
00875
00876
00877 bpp = dst->format->BytesPerPixel;
00878 p = (Ceylan::Uint8 *) dst->pixels + y * dst->pitch + x * bpp;
00879 switch (bpp) {
00880 case 1:
00881 *p = color;
00882 break;
00883 case 2:
00884 *(Ceylan::Uint16 *) p = color;
00885 break;
00886 case 3:
00887 if (SDL_BYTEORDER == SDL_BIG_ENDIAN) {
00888 p[0] = (color >> 16) & 0xff;
00889 p[1] = (color >> 8) & 0xff;
00890 p[2] = color & 0xff;
00891 } else {
00892 p[0] = color & 0xff;
00893 p[1] = (color >> 8) & 0xff;
00894 p[2] = (color >> 16) & 0xff;
00895 }
00896 break;
00897 case 4:
00898 *(Ceylan::Uint32 *) p = color;
00899 break;
00900 }
00901
00902 return (0);
00903 }
00904
00905
00906
00907
00908 #define AAlevels 256
00909 #define AAbits 8
00910
00911
00912
00913
00914
00915
00916
00917
00918
00919
00920 int aalineColorInt(SDL_Surface * dst, Ceylan::Sint16 x1, Ceylan::Sint16 y1,
00921 Ceylan::Sint16 x2, Ceylan::Sint16 y2, Ceylan::Uint32 color, int draw_endpoint)
00922 {
00923 Ceylan::Sint32 xx0, yy0, xx1, yy1;
00924 int result;
00925 Ceylan::Uint32 intshift, erracc, erradj;
00926 Ceylan::Uint32 erracctmp, wgt, wgtcompmask;
00927 int dx, dy, tmp, xdir, y0p1, x0pxdir;
00928
00929
00930
00931
00932 if (!(clipLine(dst, &x1, &y1, &x2, &y2))) {
00933 return (0);
00934 }
00935
00936
00937
00938
00939 xx0 = x1;
00940 yy0 = y1;
00941 xx1 = x2;
00942 yy1 = y2;
00943
00944
00945
00946
00947 if (yy0 > yy1) {
00948 tmp = yy0;
00949 yy0 = yy1;
00950 yy1 = tmp;
00951 tmp = xx0;
00952 xx0 = xx1;
00953 xx1 = tmp;
00954 }
00955
00956
00957
00958
00959 dx = xx1 - xx0;
00960 dy = yy1 - yy0;
00961
00962
00963
00964
00965 if (dx >= 0) {
00966 xdir = 1;
00967 } else {
00968 xdir = -1;
00969 dx = (-dx);
00970 }
00971
00972
00973
00974
00975 if (dx == 0) {
00976
00977
00978
00979 return (vlineColor(dst, x1, y1, y2, color));
00980 } else if (dy == 0) {
00981
00982
00983
00984 return (hlineColor(dst, x1, x2, y1, color));
00985 } else if (dx == dy) {
00986
00987
00988
00989 return (lineColor(dst, x1, y1, x2, y2, color));
00990 }
00991
00992
00993
00994
00995 result = 0;
00996
00997
00998
00999
01000 erracc = 0;
01001
01002
01003
01004
01005 intshift = 32 - AAbits;
01006
01007
01008
01009 wgtcompmask = AAlevels - 1;
01010
01011
01012 if (SDL_MUSTLOCK(dst)) {
01013 if (SDL_LockSurface(dst) < 0) {
01014 return (-1);
01015 }
01016 }
01017
01018
01019
01020
01021 result |= pixelColorNolock(dst, x1, y1, color);
01022
01023
01024
01025
01026 if (dy > dx) {
01027
01028
01029
01030
01031
01032
01033
01034
01035
01036
01037 erradj = ((dx << 16) / dy) << 16;
01038
01039
01040
01041
01042 x0pxdir = xx0 + xdir;
01043 while (--dy) {
01044 erracctmp = erracc;
01045 erracc += erradj;
01046 if (erracc <= erracctmp) {
01047
01048
01049
01050 xx0 = x0pxdir;
01051 x0pxdir += xdir;
01052 }
01053 yy0++;
01054
01055
01056
01057
01058
01059
01060 wgt = (erracc >> intshift) & 255;
01061 result |= pixelColorWeightNolock (dst, xx0, yy0, color, 255 - wgt);
01062 result |= pixelColorWeightNolock (dst, x0pxdir, yy0, color, wgt);
01063 }
01064
01065 }
01066 else
01067 {
01068
01069
01070
01071
01072
01073
01074
01075
01076
01077
01078 erradj = ((dy << 16) / dx) << 16;
01079
01080
01081
01082
01083 y0p1 = yy0 + 1;
01084 while (--dx) {
01085
01086 erracctmp = erracc;
01087 erracc += erradj;
01088 if (erracc <= erracctmp) {
01089
01090
01091
01092 yy0 = y0p1;
01093 y0p1++;
01094 }
01095 xx0 += xdir;
01096
01097
01098
01099
01100
01101 wgt = (erracc >> intshift) & 255;
01102 result |= pixelColorWeightNolock (dst, xx0, yy0, color, 255 - wgt);
01103 result |= pixelColorWeightNolock (dst, xx0, y0p1, color, wgt);
01104 }
01105 }
01106
01107
01108
01109
01110 if (draw_endpoint) {
01111
01112
01113
01114
01115 result |= pixelColorNolock (dst, x2, y2, color);
01116 }
01117
01118
01119 if (SDL_MUSTLOCK(dst)) {
01120 SDL_UnlockSurface(dst);
01121 }
01122
01123 return (result);
01124 }
01125
01126
01127
01128
01129
01130 int pixelColor(SDL_Surface * dst, Ceylan::Sint16 x, Ceylan::Sint16 y,
01131 Ceylan::Uint32 color)
01132 {
01133 Ceylan::Uint8 alpha;
01134 Ceylan::Uint32 mcolor;
01135 int result = 0;
01136
01137
01138
01139
01140 if (SDL_MUSTLOCK(dst)) {
01141 if (SDL_LockSurface(dst) < 0) {
01142 return (-1);
01143 }
01144 }
01145
01146
01147
01148
01149 alpha = color & 0x000000ff;
01150 mcolor =
01151 SDL_MapRGBA(dst->format, (color & 0xff000000) >> 24,
01152 (color & 0x00ff0000) >> 16, (color & 0x0000ff00) >> 8, alpha);
01153
01154
01155
01156
01157 result = _putPixelAlpha(dst, x, y, mcolor, alpha);
01158
01159
01160
01161
01162 if (SDL_MUSTLOCK(dst)) {
01163 SDL_UnlockSurface(dst);
01164 }
01165
01166 return (result);
01167 }
01168
01169
01170
01171
01172 int pixelColorWeightNolock(SDL_Surface * dst, Ceylan::Sint16 x,
01173 Ceylan::Sint16 y, Ceylan::Uint32 color, Ceylan::Uint32 weight)
01174 {
01175 Ceylan::Uint32 a;
01176
01177
01178
01179
01180 a = (color & (Ceylan::Uint32) 0x000000ff);
01181
01182
01183
01184
01185 a = ((a * weight) >> 8);
01186
01187 return (pixelColorNolock(dst, x, y,
01188 (color & (Ceylan::Uint32) 0xffffff00) | (Ceylan::Uint32) a));
01189 }
01190
01191 static int clipLine(SDL_Surface * dst, Ceylan::Sint16 * x1,
01192 Ceylan::Sint16 * y1, Ceylan::Sint16 * x2, Ceylan::Sint16 * y2)
01193 {
01194 Ceylan::Sint16 left, right, top, bottom;
01195 int code1, code2;
01196 int draw = 0;
01197 Ceylan::Sint16 swaptmp;
01198 float m;
01199
01200
01201
01202
01203 left = dst->clip_rect.x;
01204 right = dst->clip_rect.x + dst->clip_rect.w - 1;
01205 top = dst->clip_rect.y;
01206 bottom = dst->clip_rect.y + dst->clip_rect.h - 1;
01207
01208 while (1) {
01209 code1 = clipEncode(*x1, *y1, left, top, right, bottom);
01210 code2 = clipEncode(*x2, *y2, left, top, right, bottom);
01211 if (CLIP_ACCEPT(code1, code2)) {
01212 draw = 1;
01213 break;
01214 } else if (CLIP_REJECT(code1, code2))
01215 break;
01216 else {
01217 if (CLIP_INSIDE(code1)) {
01218 swaptmp = *x2;
01219 *x2 = *x1;
01220 *x1 = swaptmp;
01221 swaptmp = *y2;
01222 *y2 = *y1;
01223 *y1 = swaptmp;
01224 swaptmp = code2;
01225 code2 = code1;
01226 code1 = swaptmp;
01227 }
01228 if (*x2 != *x1) {
01229 m = (*y2 - *y1) / (float) (*x2 - *x1);
01230 } else {
01231 m = 1.0f;
01232 }
01233 if (code1 & CLIP_LEFT_EDGE) {
01234 *y1 += (Ceylan::Sint16) ((left - *x1) * m);
01235 *x1 = left;
01236 } else if (code1 & CLIP_RIGHT_EDGE) {
01237 *y1 += (Ceylan::Sint16) ((right - *x1) * m);
01238 *x1 = right;
01239 } else if (code1 & CLIP_BOTTOM_EDGE) {
01240 if (*x2 != *x1) {
01241 *x1 += (Ceylan::Sint16) ((bottom - *y1) / m);
01242 }
01243 *y1 = bottom;
01244 } else if (code1 & CLIP_TOP_EDGE) {
01245 if (*x2 != *x1) {
01246 *x1 += (Ceylan::Sint16) ((top - *y1) / m);
01247 }
01248 *y1 = top;
01249 }
01250 }
01251 }
01252
01253 return draw;
01254 }
01255
01256
01257
01258
01259 int vlineColor(SDL_Surface * dst, Ceylan::Sint16 x, Ceylan::Sint16 y1,
01260 Ceylan::Sint16 y2, Ceylan::Uint32 color)
01261 {
01262 Ceylan::Sint16 left, right, top, bottom;
01263 Ceylan::Uint8 *pixel, *pixellast;
01264 int dy;
01265 int pixx, pixy;
01266 Ceylan::Sint16 h;
01267 Ceylan::Sint16 ytmp;
01268 int result = -1;
01269 Ceylan::Uint8 *colorptr;
01270
01271
01272
01273
01274 left = dst->clip_rect.x;
01275 right = dst->clip_rect.x + dst->clip_rect.w - 1;
01276 top = dst->clip_rect.y;
01277 bottom = dst->clip_rect.y + dst->clip_rect.h - 1;
01278
01279
01280
01281
01282 if ((x<left) || (x>right)) {
01283 return (0);
01284 }
01285 if ((y1<top) && (y2<top)) {
01286 return(0);
01287 }
01288 if ((y1>bottom) && (y2>bottom)) {
01289 return(0);
01290 }
01291
01292
01293
01294
01295 if (y1 < top) {
01296 y1 = top;
01297 }
01298 if (y2 > bottom) {
01299 y2 = bottom;
01300 }
01301
01302
01303
01304
01305 if (y1 > y2) {
01306 ytmp = y1;
01307 y1 = y2;
01308 y2 = ytmp;
01309 }
01310
01311
01312
01313
01314 h = y2 - y1;
01315
01316
01317
01318
01319 if (h < 0) {
01320 return (0);
01321 }
01322
01323
01324
01325
01326 if ((color & 255) == 255) {
01327
01328
01329
01330
01331
01332
01333
01334
01335 colorptr = (Ceylan::Uint8 *) & color;
01336 if (SDL_BYTEORDER == SDL_BIG_ENDIAN)
01337 {
01338 color = SDL_MapRGBA(dst->format, colorptr[0], colorptr[1],
01339 colorptr[2], colorptr[3]);
01340 }
01341 else
01342 {
01343 color = SDL_MapRGBA(dst->format, colorptr[3], colorptr[2],
01344 colorptr[1], colorptr[0]);
01345 }
01346
01347
01348
01349
01350 SDL_LockSurface(dst);
01351
01352
01353
01354
01355 dy = h;
01356 pixx = dst->format->BytesPerPixel;
01357 pixy = dst->pitch;
01358 pixel = ((Ceylan::Uint8 *) dst->pixels) + pixx * (int) x + pixy * (int) y1;
01359 pixellast = pixel + pixy * dy;
01360
01361
01362
01363
01364 switch (dst->format->BytesPerPixel) {
01365 case 1:
01366 for (; pixel <= pixellast; pixel += pixy) {
01367 *(Ceylan::Uint8 *) pixel = color;
01368 }
01369 break;
01370 case 2:
01371 for (; pixel <= pixellast; pixel += pixy) {
01372 *(Ceylan::Uint16 *) pixel = color;
01373 }
01374 break;
01375 case 3:
01376 for (; pixel <= pixellast; pixel += pixy) {
01377 if (SDL_BYTEORDER == SDL_BIG_ENDIAN) {
01378 pixel[0] = (color >> 16) & 0xff;
01379 pixel[1] = (color >> 8) & 0xff;
01380 pixel[2] = color & 0xff;
01381 } else {
01382 pixel[0] = color & 0xff;
01383 pixel[1] = (color >> 8) & 0xff;
01384 pixel[2] = (color >> 16) & 0xff;
01385 }
01386 }
01387 break;
01388 default:
01389 for (; pixel <= pixellast; pixel += pixy) {
01390 *(Ceylan::Uint32 *) pixel = color;
01391 }
01392 break;
01393 }
01394
01395
01396
01397
01398 SDL_UnlockSurface(dst);
01399
01400
01401
01402
01403 result = 0;
01404
01405 } else {
01406
01407
01408
01409
01410
01411 result = VLineAlpha(dst, x, y1, y1 + h, color);
01412
01413 }
01414
01415 return (result);
01416 }
01417
01418
01419
01420
01421 int VLineAlpha(SDL_Surface * dst, Ceylan::Sint16 x, Ceylan::Sint16 y1,
01422 Ceylan::Sint16 y2, Ceylan::Uint32 color)
01423 {
01424 return (filledRectAlpha(dst, x, y1, x, y2, color));
01425 }
01426
01427
01428
01429
01430
01431 int _filledRectAlpha(SDL_Surface * surface, Ceylan::Sint16 x1,
01432 Ceylan::Sint16 y1, Ceylan::Sint16 x2, Ceylan::Sint16 y2,
01433 Ceylan::Uint32 color, Ceylan::Uint8 alpha)
01434 {
01435 Ceylan::Uint32 Rmask = surface->format->Rmask, Gmask =
01436 surface->format->Gmask, Bmask = surface->format->Bmask,
01437 Amask = surface->format->Amask;
01438 Ceylan::Uint32 R, G, B, A = 0;
01439 Ceylan::Sint16 x, y;
01440
01441 switch (surface->format->BytesPerPixel) {
01442 case 1:{
01443 Ceylan::Uint8 *row, *pixel;
01444 Ceylan::Uint8 dR, dG, dB;
01445
01446 Ceylan::Uint8 sR = surface->format->palette->colors[color].r;
01447 Ceylan::Uint8 sG = surface->format->palette->colors[color].g;
01448 Ceylan::Uint8 sB = surface->format->palette->colors[color].b;
01449
01450 for (y = y1; y <= y2; y++) {
01451 row = (Ceylan::Uint8 *) surface->pixels + y * surface->pitch;
01452 for (x = x1; x <= x2; x++) {
01453 pixel = row + x;
01454
01455 dR = surface->format->palette->colors[*pixel].r;
01456 dG = surface->format->palette->colors[*pixel].g;
01457 dB = surface->format->palette->colors[*pixel].b;
01458
01459 dR = dR + ((sR - dR) * alpha >> 8);
01460 dG = dG + ((sG - dG) * alpha >> 8);
01461 dB = dB + ((sB - dB) * alpha >> 8);
01462
01463 *pixel = SDL_MapRGB(surface->format, dR, dG, dB);
01464 }
01465 }
01466 }
01467 break;
01468
01469 case 2:{
01470 Ceylan::Uint16 *row, *pixel;
01471 Ceylan::Uint32 dR = (color & Rmask), dG = (color & Gmask),
01472 dB = (color & Bmask), dA = (color & Amask);
01473
01474 for (y = y1; y <= y2; y++) {
01475 row = (Ceylan::Uint16 *) surface->pixels + y * surface->pitch / 2;
01476 for (x = x1; x <= x2; x++) {
01477 pixel = row + x;
01478
01479 R = ((*pixel & Rmask) + ((dR - (*pixel & Rmask)) * alpha >> 8)) & Rmask;
01480 G = ((*pixel & Gmask) + ((dG - (*pixel & Gmask)) * alpha >> 8)) & Gmask;
01481 B = ((*pixel & Bmask) + ((dB - (*pixel & Bmask)) * alpha >> 8)) & Bmask;
01482 if (Amask)
01483 A = ((*pixel & Amask) + ((dA - (*pixel & Amask)) * alpha >> 8)) & Amask;
01484
01485 *pixel = R | G | B | A;
01486 }
01487 }
01488 }
01489 break;
01490
01491 case 3:{
01492 Ceylan::Uint8 *row, *pix;
01493 Ceylan::Uint8 dR, dG, dB, dA;
01494 Ceylan::Uint8 rshift8 = surface->format->Rshift / 8;
01495 Ceylan::Uint8 gshift8 = surface->format->Gshift / 8;
01496 Ceylan::Uint8 bshift8 = surface->format->Bshift / 8;
01497 Ceylan::Uint8 ashift8 = surface->format->Ashift / 8;
01498
01499 Ceylan::Uint8 sR = (color >> surface->format->Rshift) & 0xff;
01500 Ceylan::Uint8 sG = (color >> surface->format->Gshift) & 0xff;
01501 Ceylan::Uint8 sB = (color >> surface->format->Bshift) & 0xff;
01502 Ceylan::Uint8 sA = (color >> surface->format->Ashift) & 0xff;
01503
01504 for (y = y1; y <= y2; y++) {
01505 row = (Ceylan::Uint8 *) surface->pixels + y * surface->pitch;
01506 for (x = x1; x <= x2; x++) {
01507 pix = row + x * 3;
01508
01509 dR = *((pix) + rshift8);
01510 dG = *((pix) + gshift8);
01511 dB = *((pix) + bshift8);
01512 dA = *((pix) + ashift8);
01513
01514 dR = dR + ((sR - dR) * alpha >> 8);
01515 dG = dG + ((sG - dG) * alpha >> 8);
01516 dB = dB + ((sB - dB) * alpha >> 8);
01517 dA = dA + ((sA - dA) * alpha >> 8);
01518
01519 *((pix) + rshift8) = dR;
01520 *((pix) + gshift8) = dG;
01521 *((pix) + bshift8) = dB;
01522 *((pix) + ashift8) = dA;
01523 }
01524 }
01525
01526 }
01527 break;
01528
01529 case 4:{
01530 Ceylan::Uint32 Rshift, Gshift, Bshift, Ashift;
01531 Ceylan::Uint32 *row, *pixel;
01532 Ceylan::Uint32 dR = (color & Rmask), dG = (color & Gmask), dB = (color & Bmask), dA = (color & Amask);
01533
01534 Rshift = surface->format->Rshift;
01535 Gshift = surface->format->Gshift;
01536 Bshift = surface->format->Bshift;
01537 Ashift = surface->format->Ashift;
01538
01539 for (y = y1; y <= y2; y++) {
01540 row = (Ceylan::Uint32 *) surface->pixels + y * surface->pitch / 4;
01541 for (x = x1; x <= x2; x++) {
01542 pixel = row + x;
01543
01544 R = ((*pixel & Rmask)
01545 + ((((dR - (*pixel & Rmask)) >> Rshift) * alpha >> 8) << Rshift)) & Rmask;
01546 G = ((*pixel & Gmask)
01547 + ((((dG - (*pixel & Gmask)) >> Gshift) * alpha >> 8) << Gshift)) & Gmask;
01548 B = ((*pixel & Bmask)
01549 + ((((dB - (*pixel & Bmask)) >> Bshift) * alpha >> 8) << Bshift)) & Bmask;
01550 if (Amask)
01551 A = ((*pixel & Amask)
01552 + ((((dA - (*pixel & Amask)) >> Ashift) * alpha >> 8) << Ashift)) & Amask;
01553
01554 *pixel = R | G | B | A;
01555 }
01556 }
01557 }
01558 break;
01559 }
01560
01561 return (0);
01562 }
01563
01564
01565
01566
01567 int HLineAlpha(SDL_Surface * dst, Ceylan::Sint16 x1, Ceylan::Sint16 x2,
01568 Ceylan::Sint16 y, Ceylan::Uint32 color)
01569 {
01570 return (filledRectAlpha(dst, x1, y, x2, y, color));
01571 }
01572
01573
01574
01575
01576 int filledRectAlpha(SDL_Surface * dst, Ceylan::Sint16 x1, Ceylan::Sint16 y1,
01577 Ceylan::Sint16 x2, Ceylan::Sint16 y2, Ceylan::Uint32 color)
01578 {
01579 Ceylan::Uint8 alpha;
01580 Ceylan::Uint32 mcolor;
01581 int result = 0;
01582
01583
01584
01585
01586 if (SDL_MUSTLOCK(dst)) {
01587 if (SDL_LockSurface(dst) < 0) {
01588 return (-1);
01589 }
01590 }
01591
01592
01593
01594
01595 alpha = color & 0x000000ff;
01596 mcolor =
01597 SDL_MapRGBA(dst->format, (color & 0xff000000) >> 24,
01598 (color & 0x00ff0000) >> 16, (color & 0x0000ff00) >> 8, alpha);
01599
01600
01601
01602
01603 result = _filledRectAlpha(dst, x1, y1, x2, y2, mcolor, alpha);
01604
01605
01606
01607
01608 if (SDL_MUSTLOCK(dst)) {
01609 SDL_UnlockSurface(dst);
01610 }
01611
01612 return (result);
01613 }
01614
01615
01616 int hlineColor(SDL_Surface * dst, Ceylan::Sint16 x1, Ceylan::Sint16 x2,
01617 Ceylan::Sint16 y, Ceylan::Uint32 color)
01618 {
01619 Ceylan::Sint16 left, right, top, bottom;
01620 Ceylan::Uint8 *pixel, *pixellast;
01621 int dx;
01622 int pixx, pixy;
01623 Ceylan::Sint16 w;
01624 Ceylan::Sint16 xtmp;
01625 int result = -1;
01626 Ceylan::Uint8 *colorptr;
01627
01628
01629
01630
01631 left = dst->clip_rect.x;
01632 right = dst->clip_rect.x + dst->clip_rect.w - 1;
01633 top = dst->clip_rect.y;
01634 bottom = dst->clip_rect.y + dst->clip_rect.h - 1;
01635
01636
01637
01638
01639 if ((x1<left) && (x2<left)) {
01640 return(0);
01641 }
01642 if ((x1>right) && (x2>right)) {
01643 return(0);
01644 }
01645 if ((y<top) || (y>bottom)) {
01646 return (0);
01647 }
01648
01649
01650
01651
01652 if (x1 < left) {
01653 x1 = left;
01654 }
01655 if (x2 > right) {
01656 x2 = right;
01657 }
01658
01659
01660
01661
01662 if (x1 > x2) {
01663 xtmp = x1;
01664 x1 = x2;
01665 x2 = xtmp;
01666 }
01667
01668
01669
01670
01671 w = x2 - x1;
01672
01673
01674
01675
01676 if (w < 0) {
01677 return (0);
01678 }
01679
01680
01681
01682
01683 if ((color & 255) == 255) {
01684
01685
01686
01687
01688
01689
01690
01691
01692 colorptr = (Ceylan::Uint8 *) & color;
01693 if (SDL_BYTEORDER == SDL_BIG_ENDIAN) {
01694 color = SDL_MapRGBA(dst->format, colorptr[0], colorptr[1],
01695 colorptr[2], colorptr[3]);
01696 }
01697 else
01698 {
01699 color = SDL_MapRGBA(dst->format, colorptr[3], colorptr[2],
01700 colorptr[1], colorptr[0]);
01701 }
01702
01703
01704
01705
01706 SDL_LockSurface(dst);
01707
01708
01709
01710
01711 dx = w;
01712 pixx = dst->format->BytesPerPixel;
01713 pixy = dst->pitch;
01714 pixel = ((Ceylan::Uint8 *) dst->pixels) + pixx * (int) x1 + pixy * (int) y;
01715
01716
01717
01718
01719 switch (dst->format->BytesPerPixel) {
01720 case 1:
01721 memset(pixel, color, dx);
01722 break;
01723 case 2:
01724 pixellast = pixel + dx + dx;
01725 for (; pixel <= pixellast; pixel += pixx) {
01726 *(Ceylan::Uint16 *) pixel = color;
01727 }
01728 break;
01729 case 3:
01730 pixellast = pixel + dx + dx + dx;
01731 for (; pixel <= pixellast; pixel += pixx) {
01732 if (SDL_BYTEORDER == SDL_BIG_ENDIAN) {
01733 pixel[0] = (color >> 16) & 0xff;
01734 pixel[1] = (color >> 8) & 0xff;
01735 pixel[2] = color & 0xff;
01736 } else {
01737 pixel[0] = color & 0xff;
01738 pixel[1] = (color >> 8) & 0xff;
01739 pixel[2] = (color >> 16) & 0xff;
01740 }
01741 }
01742 break;
01743 default:
01744 dx = dx + dx;
01745 pixellast = pixel + dx + dx;
01746 for (; pixel <= pixellast; pixel += pixx) {
01747 *(Ceylan::Uint32 *) pixel = color;
01748 }
01749 break;
01750 }
01751
01752
01753
01754
01755 SDL_UnlockSurface(dst);
01756
01757
01758
01759
01760 result = 0;
01761
01762 } else {
01763
01764
01765
01766
01767
01768 result = HLineAlpha(dst, x1, x1 + w, y, color);
01769
01770 }
01771
01772 return (result);
01773 }
01774
01775
01776
01777
01778
01779
01780
01781
01782
01783
01784 #define ABS(a) (((a)<0) ? -(a): (a))
01785
01786 int lineColor(SDL_Surface * dst, Ceylan::Sint16 x1, Ceylan::Sint16 y1,
01787 Ceylan::Sint16 x2, Ceylan::Sint16 y2, Ceylan::Uint32 color)
01788 {
01789 int pixx, pixy;
01790 int x, y;
01791 int dx, dy;
01792 int ax, ay;
01793 int sx, sy;
01794 int swaptmp;
01795 Ceylan::Uint8 *pixel;
01796 Ceylan::Uint8 *colorptr;
01797
01798
01799
01800
01801 if (!(clipLine(dst, &x1, &y1, &x2, &y2))) {
01802 return (0);
01803 }
01804
01805
01806
01807
01808 if (x1 == x2) {
01809 if (y1 < y2) {
01810 return (vlineColor(dst, x1, y1, y2, color));
01811 } else if (y1 > y2) {
01812 return (vlineColor(dst, x1, y2, y1, color));
01813 } else {
01814 return (pixelColor(dst, x1, y1, color));
01815 }
01816 }
01817 if (y1 == y2) {
01818 if (x1 < x2) {
01819 return (hlineColor(dst, x1, x2, y1, color));
01820 } else if (x1 > x2) {
01821 return (hlineColor(dst, x2, x1, y1, color));
01822 }
01823 }
01824
01825
01826
01827
01828 dx = x2 - x1;
01829 dy = y2 - y1;
01830 sx = (dx >= 0) ? 1 : -1;
01831 sy = (dy >= 0) ? 1 : -1;
01832
01833
01834 if (SDL_MUSTLOCK(dst)) {
01835 if (SDL_LockSurface(dst) < 0) {
01836 return (-1);
01837 }
01838 }
01839
01840
01841
01842
01843 if ((color & 255) == 255) {
01844
01845
01846
01847
01848
01849
01850
01851
01852 colorptr = (Ceylan::Uint8 *) & color;
01853 if (SDL_BYTEORDER == SDL_BIG_ENDIAN) {
01854 color = SDL_MapRGBA(dst->format, colorptr[0], colorptr[1], colorptr[2],
01855 colorptr[3]);
01856 }
01857 else
01858 {
01859 color = SDL_MapRGBA(dst->format, colorptr[3], colorptr[2], colorptr[1],
01860 colorptr[0]);
01861 }
01862
01863
01864
01865
01866 dx = sx * dx + 1;
01867 dy = sy * dy + 1;
01868 pixx = dst->format->BytesPerPixel;
01869 pixy = dst->pitch;
01870 pixel = ((Ceylan::Uint8 *) dst->pixels) + pixx * (int) x1 + pixy * (int) y1;
01871 pixx *= sx;
01872 pixy *= sy;
01873 if (dx < dy) {
01874 swaptmp = dx;
01875 dx = dy;
01876 dy = swaptmp;
01877 swaptmp = pixx;
01878 pixx = pixy;
01879 pixy = swaptmp;
01880 }
01881
01882
01883
01884
01885 x = 0;
01886 y = 0;
01887 switch (dst->format->BytesPerPixel) {
01888 case 1:
01889 for (; x < dx; x++, pixel += pixx) {
01890 *pixel = color;
01891 y += dy;
01892 if (y >= dx) {
01893 y -= dx;
01894 pixel += pixy;
01895 }
01896 }
01897 break;
01898 case 2:
01899 for (; x < dx; x++, pixel += pixx) {
01900 *(Ceylan::Uint16 *) pixel = color;
01901 y += dy;
01902 if (y >= dx) {
01903 y -= dx;
01904 pixel += pixy;
01905 }
01906 }
01907 break;
01908 case 3:
01909 for (; x < dx; x++, pixel += pixx) {
01910 if (SDL_BYTEORDER == SDL_BIG_ENDIAN) {
01911 pixel[0] = (color >> 16) & 0xff;
01912 pixel[1] = (color >> 8) & 0xff;
01913 pixel[2] = color & 0xff;
01914 } else {
01915 pixel[0] = color & 0xff;
01916 pixel[1] = (color >> 8) & 0xff;
01917 pixel[2] = (color >> 16) & 0xff;
01918 }
01919 y += dy;
01920 if (y >= dx) {
01921 y -= dx;
01922 pixel += pixy;
01923 }
01924 }
01925 break;
01926 default:
01927 for (; x < dx; x++, pixel += pixx) {
01928 *(Ceylan::Uint32 *) pixel = color;
01929 y += dy;
01930 if (y >= dx) {
01931 y -= dx;
01932 pixel += pixy;
01933 }
01934 }
01935 break;
01936 }
01937
01938 } else {
01939
01940
01941
01942
01943
01944 ax = ABS(dx) << 1;
01945 ay = ABS(dy) << 1;
01946 x = x1;
01947 y = y1;
01948 if (ax > ay) {
01949 int d = ay - (ax >> 1);
01950
01951 while (x != x2) {
01952 pixelColorNolock (dst, x, y, color);
01953 if (d > 0 || (d == 0 && sx == 1)) {
01954 y += sy;
01955 d -= ax;
01956 }
01957 x += sx;
01958 d += ay;
01959 }
01960 } else {
01961 int d = ax - (ay >> 1);
01962
01963 while (y != y2) {
01964 pixelColorNolock (dst, x, y, color);
01965 if (d > 0 || ((d == 0) && (sy == 1))) {
01966 x += sx;
01967 d -= ay;
01968 }
01969 y += sy;
01970 d += ax;
01971 }
01972 }
01973 pixelColorNolock (dst, x, y, color);
01974
01975 }
01976
01977
01978 if (SDL_MUSTLOCK(dst)) {
01979 SDL_UnlockSurface(dst);
01980 }
01981
01982 return (0);
01983 }
01984
01985
01986
01987
01988
01989
01990
01991 int _putPixelAlpha(SDL_Surface * surface, Ceylan::Sint16 x, Ceylan::Sint16 y,
01992 Ceylan::Uint32 color, Ceylan::Uint8 alpha)
01993 {
01994 Ceylan::Uint32 Rmask = surface->format->Rmask,
01995 Gmask =
01996 surface->format->Gmask,
01997 Bmask = surface->format->Bmask,
01998 Amask = surface->format->Amask;
01999
02000 Ceylan::Uint32 R, G, B, A = 0;
02001
02002 if (x >= clip_xmin(surface) && x <= clip_xmax(surface)
02003 && y >= clip_ymin(surface) && y <= clip_ymax(surface)) {
02004
02005 switch (surface->format->BytesPerPixel) {
02006 case 1:{
02007 if (alpha == 255) {
02008 *((Ceylan::Uint8 *) surface->pixels + y * surface->pitch + x) = color;
02009 } else {
02010 Ceylan::Uint8 *pixel = (Ceylan::Uint8 *) surface->pixels + y * surface->pitch + x;
02011
02012 Ceylan::Uint8 dR = surface->format->palette->colors[*pixel].r;
02013 Ceylan::Uint8 dG = surface->format->palette->colors[*pixel].g;
02014 Ceylan::Uint8 dB = surface->format->palette->colors[*pixel].b;
02015 Ceylan::Uint8 sR = surface->format->palette->colors[color].r;
02016 Ceylan::Uint8 sG = surface->format->palette->colors[color].g;
02017 Ceylan::Uint8 sB = surface->format->palette->colors[color].b;
02018
02019 dR = dR + ((sR - dR) * alpha >> 8);
02020 dG = dG + ((sG - dG) * alpha >> 8);
02021 dB = dB + ((sB - dB) * alpha >> 8);
02022
02023 *pixel = SDL_MapRGB(surface->format, dR, dG, dB);
02024 }
02025 }
02026 break;
02027
02028 case 2:{
02029 if (alpha == 255)
02030 {
02031 *((Ceylan::Uint16 *) surface->pixels + y * surface->pitch / 2 + x) =
02032 color;
02033 } else {
02034 Ceylan::Uint16 *pixel = (Ceylan::Uint16 *) surface->pixels
02035 + y * surface->pitch / 2 + x;
02036 Ceylan::Uint32 dc = *pixel;
02037
02038 R = ((dc & Rmask) + (((color & Rmask) - (dc & Rmask)) * alpha >> 8))
02039 & Rmask;
02040 G = ((dc & Gmask) + (((color & Gmask) - (dc & Gmask)) * alpha >> 8))
02041 & Gmask;
02042 B = ((dc & Bmask) + (((color & Bmask) - (dc & Bmask)) * alpha >> 8))
02043 & Bmask;
02044 if (Amask)
02045 A = ((dc & Amask) + (((color & Amask) - (dc & Amask)) * alpha >> 8))
02046 & Amask;
02047
02048 *pixel = R | G | B | A;
02049 }
02050 }
02051 break;
02052
02053 case 3:{
02054 Ceylan::Uint8 *pix = (Ceylan::Uint8 *) surface->pixels
02055 + y * surface->pitch + x * 3;
02056 Ceylan::Uint8 rshift8 = surface->format->Rshift / 8;
02057 Ceylan::Uint8 gshift8 = surface->format->Gshift / 8;
02058 Ceylan::Uint8 bshift8 = surface->format->Bshift / 8;
02059 Ceylan::Uint8 ashift8 = surface->format->Ashift / 8;
02060
02061
02062 if (alpha == 255) {
02063 *(pix + rshift8) = color >> surface->format->Rshift;
02064 *(pix + gshift8) = color >> surface->format->Gshift;
02065 *(pix + bshift8) = color >> surface->format->Bshift;
02066 *(pix + ashift8) = color >> surface->format->Ashift;
02067 } else {
02068 Ceylan::Uint8 dR, dG, dB, dA = 0;
02069 Ceylan::Uint8 sR, sG, sB, sA = 0;
02070
02071 pix = (Ceylan::Uint8 *) surface->pixels + y * surface->pitch + x * 3;
02072
02073 dR = *((pix) + rshift8);
02074 dG = *((pix) + gshift8);
02075 dB = *((pix) + bshift8);
02076 dA = *((pix) + ashift8);
02077
02078 sR = (color >> surface->format->Rshift) & 0xff;
02079 sG = (color >> surface->format->Gshift) & 0xff;
02080 sB = (color >> surface->format->Bshift) & 0xff;
02081 sA = (color >> surface->format->Ashift) & 0xff;
02082
02083 dR = dR + ((sR - dR) * alpha >> 8);
02084 dG = dG + ((sG - dG) * alpha >> 8);
02085 dB = dB + ((sB - dB) * alpha >> 8);
02086 dA = dA + ((sA - dA) * alpha >> 8);
02087
02088 *((pix) + rshift8) = dR;
02089 *((pix) + gshift8) = dG;
02090 *((pix) + bshift8) = dB;
02091 *((pix) + ashift8) = dA;
02092 }
02093 }
02094 break;
02095
02096 case 4:{
02097 if (alpha == 255) {
02098 *((Ceylan::Uint32 *) surface->pixels + y * surface->pitch / 4 + x) = color;
02099 } else {
02100 Ceylan::Uint32 Rshift, Gshift, Bshift, Ashift;
02101 Ceylan::Uint32 *pixel = (Ceylan::Uint32 *) surface->pixels
02102 + y * surface->pitch / 4 + x;
02103 Ceylan::Uint32 dc = *pixel;
02104
02105 Rshift = surface->format->Rshift;
02106 Gshift = surface->format->Gshift;
02107 Bshift = surface->format->Bshift;
02108 Ashift = surface->format->Ashift;
02109
02110 R = ((dc & Rmask) + (((((color & Rmask) - (dc & Rmask)) >> Rshift) * alpha >> 8) << Rshift)) & Rmask;
02111 G = ((dc & Gmask) + (((((color & Gmask) - (dc & Gmask)) >> Gshift) * alpha >> 8) << Gshift)) & Gmask;
02112 B = ((dc & Bmask) + (((((color & Bmask) - (dc & Bmask)) >> Bshift) * alpha >> 8) << Bshift)) & Bmask;
02113 if (Amask)
02114 A = ((dc & Amask) + (((((color & Amask) - (dc & Amask)) >> Ashift) * alpha >> 8) << Ashift)) & Amask;
02115
02116 *pixel = R | G | B | A;
02117 }
02118 }
02119 break;
02120 }
02121 }
02122
02123 return (0);
02124 }
02125
02126
02127
02128 #endif // OSDL_USES_SDL