00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <cassert>
00024 #include <iostream>
00025
00026
00027
00028
00029
00030
00031
00032 #include "util/log/logger.h"
00033 #include "util/structures/rect.h"
00034 #include "video/imagemanager.h"
00035 #include "video/renderbackend.h"
00036
00037 #include "renderbackendsdl.h"
00038 #include "sdlblendingfunctions.h"
00039 #include "sdlimage.h"
00040
00041 namespace FIFE {
00042 static Logger _log(LM_VIDEO);
00043
00044 SDLImage::SDLImage(IResourceLoader* loader):
00045 Image(loader) {
00046 resetSdlimage();
00047 }
00048
00049 SDLImage::SDLImage(const std::string& name, IResourceLoader* loader):
00050 Image(name, loader) {
00051 resetSdlimage();
00052 }
00053
00054 SDLImage::SDLImage(SDL_Surface* surface):
00055 Image(surface) {
00056 resetSdlimage();
00057 }
00058
00059 SDLImage::SDLImage(const std::string& name, SDL_Surface* surface):
00060 Image(name, surface) {
00061 resetSdlimage();
00062 }
00063
00064 SDLImage::SDLImage(const uint8_t* data, uint32_t width, uint32_t height):
00065 Image(data, width, height) {
00066 resetSdlimage();
00067 }
00068
00069 SDLImage::SDLImage(const std::string& name, const uint8_t* data, uint32_t width, uint32_t height):
00070 Image(name, data, width, height) {
00071 resetSdlimage();
00072 }
00073
00074 void SDLImage::resetSdlimage() {
00075 m_last_alpha = 255;
00076 m_finalized = false;
00077 m_colorkey = RenderBackend::instance()->getColorKey();
00078 m_scale_x = 1.0;
00079 m_scale_y = 1.0;
00080 m_zoom_surface = NULL;
00081 }
00082
00083 SDLImage::~SDLImage() {
00084 if (m_zoom_surface) {
00085 SDL_FreeSurface(m_zoom_surface);
00086 }
00087 }
00088
00089 void SDLImage::setSurface(SDL_Surface* surface) {
00090 if (m_zoom_surface) {
00091 SDL_FreeSurface(m_zoom_surface);
00092 m_zoom_surface = NULL;
00093 }
00094 reset(surface);
00095 resetSdlimage();
00096 }
00097
00098 void SDL_BlitSurfaceWithAlpha( const SDL_Surface* src, const SDL_Rect* srcRect,
00099 SDL_Surface* dst, SDL_Rect* dstRect, uint8_t alpha ) {
00100 if( 0 == alpha ) {
00101 return;
00102 }
00103
00104 int32_t screenX, screenY;
00105 if( dstRect ) {
00106 screenX = dstRect->x;
00107 screenY = dstRect->y;
00108 } else {
00109 screenX = dst->clip_rect.x;
00110 screenY = dst->clip_rect.y;
00111 }
00112
00113 int32_t width, height, tX, tY;
00114 if( srcRect ) {
00115 tX = srcRect->x;
00116 tY = srcRect->y;
00117 width = srcRect->w;
00118 height = srcRect->h;
00119 } else {
00120 tX = src->clip_rect.x;
00121 tY = src->clip_rect.y;
00122 width = src->clip_rect.w;
00123 height = src->clip_rect.h;
00124 }
00125
00126
00127 if( ( screenX >= ( dst->clip_rect.x + dst->clip_rect.w ) ) ||
00128 ( screenY >= ( dst->clip_rect.y + dst->clip_rect.h ) ) ||
00129 ( ( screenX + width ) <= dst->clip_rect.x ) ||
00130 ( ( screenY + height ) <= dst->clip_rect.y ) ) {
00131 return;
00132 }
00133
00134 if( screenX < dst->clip_rect.x ) {
00135 int32_t dX = dst->clip_rect.x - screenX;
00136 screenX += dX;
00137 width -= dX;
00138 tX += dX;
00139 }
00140
00141 if( ( screenX + width ) > ( dst->clip_rect.x + dst->clip_rect.w ) ) {
00142 int32_t dX = ( screenX + width ) - ( dst->clip_rect.x + dst->clip_rect.w );
00143 width -= dX;
00144 }
00145
00146 if( screenY < dst->clip_rect.y ) {
00147 int32_t dY = dst->clip_rect.y - screenY;
00148 screenY += dY;
00149 height -= dY;
00150 tY += dY;
00151 }
00152
00153 if( ( screenY + height ) > ( dst->clip_rect.y + dst->clip_rect.h ) ) {
00154 int32_t dY = ( screenY + height ) - ( dst->clip_rect.y + dst->clip_rect.h );
00155 height -= dY;
00156 }
00157
00158 if( ( 0 >= height ) || ( 0 >= width ) ) {
00159 return;
00160 }
00161
00162 SDL_LockSurface( dst );
00163
00164 uint8_t* srcData = reinterpret_cast< uint8_t* > ( src->pixels );
00165 uint8_t* dstData = reinterpret_cast< uint8_t* > ( dst->pixels );
00166
00167
00168 srcData += tY * src->pitch + tX * src->format->BytesPerPixel;
00169 dstData += screenY * dst->pitch + screenX * dst->format->BytesPerPixel;
00170
00171 switch( src->format->BitsPerPixel ) {
00172 case 32: {
00173 switch( dst->format->BitsPerPixel ) {
00174 case 16: {
00175 if( 0xFFFF == ( dst->format->Rmask | dst->format->Gmask | dst->format->Bmask ) ) {
00176 for( int32_t y = height; y > 0; --y ) {
00177 SDL_BlendRow_RGBA8_to_RGB565( srcData, dstData, alpha, width );
00178 srcData += src->pitch;
00179 dstData += dst->pitch;
00180 }
00181 }
00182 }
00183 break;
00184
00185 case 24: {
00186 for( int32_t y = height; y > 0; --y ) {
00187 SDL_BlendRow_RGBA8_to_RGB8( srcData, dstData, alpha, width );
00188 srcData += src->pitch;
00189 dstData += dst->pitch;
00190 }
00191 }
00192 break;
00193
00194 case 32: {
00195 for( int32_t y = height; y > 0; --y ) {
00196 SDL_BlendRow_RGBA8_to_RGBA8( srcData, dstData, alpha, width );
00197 srcData += src->pitch;
00198 dstData += dst->pitch;
00199 }
00200 }
00201 break;
00202
00203 default:
00204 break;
00205 }
00206 }
00207 break;
00208
00209 case 16: {
00210 if( 0x000F == src->format->Amask ) {
00211 if( ( 16 == dst->format->BitsPerPixel ) &&
00212 ( 0xFFFF == ( dst->format->Rmask | dst->format->Gmask | dst->format->Bmask ) ) ) {
00213 for( int32_t y = height; y > 0; --y ) {
00214 SDL_BlendRow_RGBA4_to_RGB565( srcData, dstData, alpha, width );
00215 srcData += src->pitch;
00216 dstData += dst->pitch;
00217 }
00218 }
00219 }
00220 }
00221 break;
00222
00223 default:
00224 break;
00225 }
00226
00227 SDL_UnlockSurface( dst );
00228 }
00229
00230 void zoomSurface(SDL_Surface* src, SDL_Surface* dst) {
00231 uint32_t* src_pointer = static_cast<uint32_t*>(src->pixels);
00232 uint32_t* src_help_pointer = src_pointer;
00233 uint32_t* dst_pointer = static_cast<uint32_t*>(dst->pixels);
00234
00235 int32_t x, y, *sx_ca, *sy_ca;
00236 int32_t sx = static_cast<int32_t>(0xffff * src->w / dst->w);
00237 int32_t sy = static_cast<int32_t>(0xffff * src->h / dst->h);
00238 int32_t sx_c = 0;
00239 int32_t sy_c = 0;
00240
00241
00242 int32_t* sx_a = new int32_t[dst->w + 1];
00243 sx_ca = sx_a;
00244 for (x = 0; x <= dst->w; x++) {
00245 *sx_ca = sx_c;
00246 sx_ca++;
00247 sx_c &= 0xffff;
00248 sx_c += sx;
00249 }
00250
00251 int32_t* sy_a = new int32_t[dst->h + 1];
00252 sy_ca = sy_a;
00253 for (y = 0; y <= dst->h; y++) {
00254 *sy_ca = sy_c;
00255 sy_ca++;
00256 sy_c &= 0xffff;
00257 sy_c += sy;
00258 }
00259 sy_ca = sy_a;
00260
00261
00262
00263 if (SDL_MUSTLOCK(src)) {
00264 SDL_LockSurface(src);
00265 }
00266 if (SDL_MUSTLOCK(dst)) {
00267 SDL_LockSurface(dst);
00268 }
00269
00270 for (y = 0; y < dst->h; y++) {
00271 src_pointer = src_help_pointer;
00272 sx_ca = sx_a;
00273 for (x = 0; x < dst->w; x++) {
00274 *dst_pointer = *src_pointer;
00275 sx_ca++;
00276 src_pointer += (*sx_ca >> 16);
00277 dst_pointer++;
00278 }
00279 sy_ca++;
00280 src_help_pointer = (uint32_t*)((uint8_t*)src_help_pointer + (*sy_ca >> 16) * src->pitch);
00281 }
00282
00283 if (SDL_MUSTLOCK(dst)) {
00284 SDL_UnlockSurface(dst);
00285 }
00286 if (SDL_MUSTLOCK(src)) {
00287 SDL_UnlockSurface(src);
00288 }
00289
00290
00291 delete [] sx_a;
00292 delete [] sy_a;
00293 }
00294
00295 SDL_Surface* getZoomedSurface(SDL_Surface * src, double zoomx, double zoomy) {
00296 if (src == NULL)
00297 return NULL;
00298
00299 SDL_Surface *zoom_src;
00300 SDL_Surface *zoom_dst;
00301 int32_t dst_w = static_cast<int32_t>(round(src->w * zoomx));
00302 int32_t dst_h = static_cast<int32_t>(round(src->h * zoomy));
00303 if (dst_w < 1)
00304 dst_w = 1;
00305 if (dst_h < 1)
00306 dst_h = 1;
00307
00308
00309 if (src->format->Amask == 0) {
00310 zoom_src = SDL_CreateRGBSurface(SDL_SWSURFACE, src->w, src->h, 32,
00311 RMASK, GMASK,
00312 BMASK, AMASK);
00313 SDL_BlitSurface(src, NULL, zoom_src, NULL);
00314 } else {
00315 zoom_src = src;
00316 }
00317
00318 zoom_dst = SDL_CreateRGBSurface(SDL_SWSURFACE, dst_w, dst_h, 32,
00319 zoom_src->format->Rmask, zoom_src->format->Gmask,
00320 zoom_src->format->Bmask, zoom_src->format->Amask);
00321
00322
00323 zoomSurface(zoom_src, zoom_dst);
00324
00325 return zoom_dst;
00326 }
00327
00328 bool nearlyEqual(float a, float b) {
00329 return ABS(a - b) <= 0.00001;
00330 }
00331
00332 void SDLImage::render(const Rect& rect, uint8_t alpha, uint8_t const* ) {
00333 if (alpha == 0) {
00334 return;
00335 }
00336 validateShared();
00337 SDL_Surface* target = RenderBackend::instance()->getRenderTargetSurface();
00338 assert(target != m_surface);
00339
00340 if (rect.right() < 0 || rect.x > static_cast<int32_t>(target->w) ||
00341 rect.bottom() < 0 || rect.y > static_cast<int32_t>(target->h)) {
00342 return;
00343 }
00344 finalize();
00345
00346 SDL_Rect r;
00347 r.x = rect.x;
00348 r.y = rect.y;
00349 r.w = rect.w;
00350 r.h = rect.h;
00351
00352 float scale_x = static_cast<float>(rect.w) / static_cast<float>(m_surface->w);
00353 float scale_y = static_cast<float>(rect.h) / static_cast<float>(m_surface->h);
00354 bool zoomed = false;
00355 bool equal = false;
00356
00357 if (!nearlyEqual(scale_x, 1.0) && !nearlyEqual(scale_y, 1.0)) {
00358 zoomed = true;
00359 if(nearlyEqual(m_scale_x, scale_x) && nearlyEqual(m_scale_y, scale_y)) {
00360 equal = true;
00361 } else {
00362 m_scale_x = scale_x;
00363 m_scale_y = scale_y;
00364 }
00365 }
00366
00367 if (m_surface->format->Amask == 0) {
00368
00369 if (m_last_alpha != alpha) {
00370 m_last_alpha = alpha;
00371 SDL_SetAlpha(m_surface, SDL_SRCALPHA | SDL_RLEACCEL, alpha);
00372 }
00373 if (!zoomed) {
00374 SDL_BlitSurface(m_surface, 0, target, &r);
00375 } else if (equal && m_zoom_surface) {
00376 SDL_BlitSurface(m_zoom_surface, 0, target, &r);
00377 } else {
00378 SDL_FreeSurface(m_zoom_surface);
00379 m_zoom_surface = getZoomedSurface(m_surface, m_scale_x, m_scale_y);
00380 SDL_BlitSurface(m_zoom_surface, 0, target, &r);
00381 }
00382 } else {
00383 if( 255 != alpha ) {
00384
00385
00386 if (!zoomed) {
00387 SDL_BlitSurfaceWithAlpha( m_surface, 0, target, &r, alpha );
00388 } else if (equal && m_zoom_surface) {
00389 SDL_BlitSurfaceWithAlpha(m_zoom_surface, 0, target, &r, alpha );
00390 } else {
00391 SDL_FreeSurface(m_zoom_surface);
00392 m_zoom_surface = getZoomedSurface(m_surface, m_scale_x, m_scale_y);
00393 SDL_BlitSurfaceWithAlpha(m_zoom_surface, 0, target, &r, alpha );
00394 }
00395 } else {
00396 if (!zoomed) {
00397 SDL_BlitSurface(m_surface, 0, target, &r);
00398 } else if (equal && m_zoom_surface) {
00399 SDL_BlitSurface(m_zoom_surface, 0, target, &r);
00400 } else {
00401 SDL_FreeSurface(m_zoom_surface);
00402 m_zoom_surface = getZoomedSurface(m_surface, m_scale_x, m_scale_y);
00403 SDL_BlitSurface(m_zoom_surface, 0, target, &r);
00404 }
00405 }
00406 }
00407 }
00408
00409 void SDLImage::finalize() {
00410 if( m_finalized ) {
00411 return;
00412 }
00413 m_finalized = true;
00414 SDL_Surface *old_surface = m_surface;
00415 Uint32 key = SDL_MapRGB(m_surface->format, m_colorkey.r, m_colorkey.g, m_colorkey.b);
00416
00417 if (m_surface->format->Amask == 0) {
00418
00419 if (RenderBackend::instance()->isColorKeyEnabled()) {
00420 SDL_SetColorKey(m_surface, SDL_SRCCOLORKEY, key);
00421 }
00422
00423 m_surface = SDL_DisplayFormat(m_surface);
00424 } else {
00425 RenderBackendSDL* be = static_cast<RenderBackendSDL*>(RenderBackend::instance());
00426 bool m_isalphaoptimized = be->isAlphaOptimizerEnabled();
00427 if( m_isalphaoptimized ) {
00428 m_surface = optimize(m_surface);
00429 } else {
00430 SDL_SetAlpha(m_surface, SDL_SRCALPHA, 255);
00431
00432
00433 if (RenderBackend::instance()->isColorKeyEnabled()) {
00434 SDL_SetColorKey(m_surface, SDL_SRCCOLORKEY, key);
00435 }
00436
00437 m_surface = SDL_DisplayFormatAlpha(m_surface);
00438 }
00439 }
00440 SDL_FreeSurface(old_surface);
00441 }
00442
00443 SDL_Surface* SDLImage::optimize(SDL_Surface* src) {
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454 int32_t transparent = 0;
00455 int32_t opaque = 0;
00456 int32_t semitransparent = 0;
00457 int32_t alphasum = 0;
00458 int32_t alphasquaresum = 0;
00459 bool colors[(1 << 12)];
00460 memset(colors, 0, (1 << 12) * sizeof(bool));
00461
00462 int32_t bpp = src->format->BytesPerPixel;
00463 if(SDL_MUSTLOCK(src)) {
00464 SDL_LockSurface(src);
00465 }
00466
00467
00468
00469
00470 for(int32_t y = 0;y < src->h;y++) {
00471 for(int32_t x = 0;x < src->w;x++) {
00472 Uint8 *pixel = (Uint8 *) src->pixels + y * src->pitch + x * bpp;
00473 Uint32 mapped = 0;
00474 switch(bpp) {
00475 case 1:
00476 mapped = *pixel;
00477 break;
00478 case 2:
00479 mapped = *(Uint16 *)pixel;
00480 break;
00481 case 3:
00482 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
00483 mapped |= pixel[0] << 16;
00484 mapped |= pixel[1] << 8;
00485 mapped |= pixel[2] << 0;
00486 #else
00487 mapped |= pixel[0] << 0;
00488 mapped |= pixel[1] << 8;
00489 mapped |= pixel[2] << 16;
00490 #endif
00491 break;
00492 case 4:
00493 mapped = *(Uint32 *)pixel;
00494 break;
00495 }
00496 Uint8 red, green, blue, alpha;
00497 SDL_GetRGBA(mapped, src->format, &red, &green, &blue, &alpha);
00498 if(alpha < 16) {
00499 transparent++;
00500 } else if (alpha > 240) {
00501 opaque++;
00502 alphasum += alpha;
00503 alphasquaresum += alpha*alpha;
00504 } else {
00505 semitransparent++;
00506 alphasum += alpha;
00507 alphasquaresum += alpha*alpha;
00508 }
00509
00510 if( alpha != 0 ) {
00511 colors[((red & 0xf0) << 4) | (green & 0xf0) | ((blue & 0xf0) >> 4)] = true;
00512 }
00513 }
00514 }
00515 int32_t avgalpha = (opaque + semitransparent) ? alphasum / (opaque + semitransparent) : 0;
00516 int32_t alphavariance = 0;
00517
00518 if(SDL_MUSTLOCK(src)) {
00519 SDL_UnlockSurface(src);
00520 }
00521 alphasquaresum /= (opaque + semitransparent) ? (opaque + semitransparent) : 1;
00522 alphavariance = alphasquaresum - avgalpha*avgalpha;
00523 if(semitransparent > ((transparent + opaque + semitransparent) / 8)
00524 && alphavariance > 16) {
00525 FL_DBG(_log, LMsg("sdlimage")
00526 << "Trying to alpha-optimize image. FAILED: real alpha usage. "
00527 << " alphavariance=" << alphavariance
00528 << " total=" << (transparent + opaque + semitransparent)
00529 << " semitransparent=" << semitransparent
00530 << "(" << (float(semitransparent)/(transparent + opaque + semitransparent))
00531 << ")");
00532 return SDL_DisplayFormatAlpha(src);
00533 }
00534
00535
00536 int32_t keycolor = -1;
00537 for(int32_t i = 0;i < (1 << 12);i++) {
00538 if(!colors[i]) {
00539 keycolor = i;
00540 break;
00541 }
00542 }
00543 if(keycolor == -1) {
00544 FL_DBG(_log, LMsg("sdlimage") << "Trying to alpha-optimize image. FAILED: no free color");
00545 return SDL_DisplayFormatAlpha(src);
00546 }
00547
00548 SDL_Surface *dst = SDL_CreateRGBSurface(src->flags & ~(SDL_SRCALPHA) | SDL_SWSURFACE,
00549 src->w, src->h,
00550 src->format->BitsPerPixel,
00551 src->format->Rmask, src->format->Gmask,
00552 src->format->Bmask, 0);
00553 bpp = dst->format->BytesPerPixel;
00554
00555 Uint32 key = SDL_MapRGB(dst->format, m_colorkey.r, m_colorkey.g, m_colorkey.b);
00556
00557
00558 if (!RenderBackend::instance()->isColorKeyEnabled()) {
00559 key = SDL_MapRGB(dst->format,
00560 (((keycolor & 0xf00) >> 4) | 0xf),
00561 ((keycolor & 0xf0) | 0xf),
00562 (((keycolor & 0xf) << 4) | 0xf));
00563 }
00564
00565 if(SDL_MUSTLOCK(src)) {
00566 SDL_LockSurface(src);
00567 }
00568 if(SDL_MUSTLOCK(dst)) {
00569 SDL_LockSurface(dst);
00570 }
00571 for(int32_t y = 0;y < dst->h;y++) {
00572 for(int32_t x = 0;x < dst->w;x++) {
00573 Uint8 *srcpixel = (Uint8 *) src->pixels + y * src->pitch + x * bpp;
00574 Uint8 *dstpixel = (Uint8 *) dst->pixels + y * dst->pitch + x * bpp;
00575 Uint32 mapped = 0;
00576 switch(bpp) {
00577 case 1:
00578 mapped = *srcpixel;
00579 break;
00580 case 2:
00581 mapped = *(Uint16 *)srcpixel;
00582 break;
00583 case 3:
00584 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
00585 mapped |= srcpixel[0] << 16;
00586 mapped |= srcpixel[1] << 8;
00587 mapped |= srcpixel[2] << 0;
00588 #else
00589 mapped |= srcpixel[0] << 0;
00590 mapped |= srcpixel[1] << 8;
00591 mapped |= srcpixel[2] << 16;
00592 #endif
00593 break;
00594 case 4:
00595 mapped = *(Uint32 *)srcpixel;
00596 break;
00597 }
00598 Uint8 red, green, blue, alpha;
00599 SDL_GetRGBA(mapped, src->format, &red, &green, &blue, &alpha);
00600 if(alpha < (avgalpha / 4)) {
00601 mapped = key;
00602 } else {
00603 mapped = SDL_MapRGB(dst->format, red, green, blue);
00604 }
00605 switch(bpp) {
00606 case 1:
00607 *dstpixel = mapped;
00608 break;
00609 case 2:
00610 *(Uint16 *)dstpixel = mapped;
00611 break;
00612 case 3:
00613 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
00614 dstpixel[0] = (mapped >> 16) & 0xff;
00615 dstpixel[1] = (mapped >> 8) & 0xff;
00616 dstpixel[2] = (mapped >> 0) & 0xff;
00617 #else
00618 dstpixel[0] = (mapped >> 0) & 0xff;
00619 dstpixel[1] = (mapped >> 8) & 0xff;
00620 dstpixel[2] = (mapped >> 16) & 0xff;
00621 #endif
00622 break;
00623 case 4:
00624 *(Uint32 *)dstpixel = mapped;
00625 break;
00626 }
00627 }
00628 }
00629 if(SDL_MUSTLOCK(dst)) {
00630 SDL_UnlockSurface(dst);
00631 }
00632 if(SDL_MUSTLOCK(src)) {
00633 SDL_UnlockSurface(src);
00634 }
00635
00636
00637
00638
00639
00640
00641
00642 SDL_SetColorKey(dst, SDL_SRCCOLORKEY | SDL_RLEACCEL, key);
00643 SDL_Surface *convert = SDL_DisplayFormat(dst);
00644 SDL_FreeSurface(dst);
00645 FL_DBG(_log, LMsg("sdlimage ")
00646 << "Trying to alpha-optimize image. SUCCESS: colorkey is " << key);
00647 return convert;
00648 }
00649
00650 size_t SDLImage::getSize() {
00651 size_t zoomSize = 0;
00652 if (m_zoom_surface) {
00653 zoomSize = m_zoom_surface->h * m_zoom_surface->pitch;
00654 }
00655 if (m_surface) {
00656 zoomSize += m_surface->h * m_surface->pitch;
00657 }
00658
00659 return zoomSize;
00660 }
00661
00662 void SDLImage::useSharedImage(const ImagePtr& shared, const Rect& region) {
00663 if(shared->getState() != IResource::RES_LOADED) {
00664 shared->load();
00665 }
00666 SDL_Surface* src_surface = shared->getSurface();
00667 SDL_Surface* surface = SDL_CreateRGBSurface(SDL_SWSURFACE | SDL_SRCALPHA, region.w, region.h,
00668 src_surface->format->BitsPerPixel, src_surface->format->Rmask, src_surface->format->Gmask,
00669 src_surface->format->Bmask, src_surface->format->Amask);
00670
00671 SDL_SetAlpha(src_surface, 0, 0);
00672 SDL_Rect srcrect = { region.x, region.y, region.w, region.h };
00673 SDL_BlitSurface(src_surface, &srcrect, surface, NULL);
00674 SDL_SetAlpha(src_surface, SDL_SRCALPHA, 0);
00675
00676 setSurface(surface);
00677 m_shared = false;
00678 m_subimagerect = region;
00679 m_atlas_img = shared;
00680 m_atlas_name = shared->getName();
00681 setState(IResource::RES_LOADED);
00682 }
00683
00684 void SDLImage::forceLoadInternal() {
00685 validateShared();
00686 }
00687
00688 void SDLImage::validateShared() {
00689 if (m_atlas_name.empty()) {
00690 return;
00691 }
00692
00693 if (m_atlas_img->getState() == IResource::RES_NOT_LOADED ||
00694 getState() == IResource::RES_NOT_LOADED) {
00695 load();
00696 }
00697 }
00698
00699 void SDLImage::load() {
00700 if (!m_atlas_name.empty()) {
00701
00702
00703 if (!ImageManager::instance()->exists(m_atlas_name)) {
00704 ImagePtr newAtlas = ImageManager::instance()->create(m_atlas_name);
00705 m_atlas_img = newAtlas;
00706 }
00707 useSharedImage(m_atlas_img , m_subimagerect);
00708 } else {
00709 Image::load();
00710 }
00711 }
00712
00713 void SDLImage::free() {
00714 setSurface(NULL);
00715 m_state = IResource::RES_NOT_LOADED;
00716 }
00717 }