00001 #ifdef WIN32
00002 #pragma warning(disable : 4786 )
00003 #endif
00004
00005 #include "CSPicture.h"
00006 #include "CSBitmap.h"
00007 #include "CSXMLHelper.h"
00008
00009 using namespace std;
00010 const char *CSPicture::CLASS = "CSPicture";
00011 CSPictures CSPicture::mAllPictures;
00012
00013 CSPictureLoader CSPictureLoader::INSTANCE;
00014 CSPictureDirectLoader CSPictureDirectLoader::INSTANCE;
00015
00016
00017 CSPicture::CSPicture(const std::string &filename, bool isDirectLoad)
00018 {
00019 static char *functionName="CSPicture";
00020 mLoadName = filename;
00021 mFactor = 0;
00022 mScaledPicture = 0;
00023 mRLEUse = RLE_PERHAPS;
00024 mAlpha = -1;
00025 mId = 0;
00026 mR = 0;
00027 mG = 0;
00028 mB = 0;
00029 mPicture = 0;
00030 mScaledWidth = 0;
00031 mScaledHeight = 0;
00032 mStartPixelsX = 0;
00033 mStartPixelsY = 0;
00034 mProjection = 0;
00035 mPixelProjectionCount = 0;
00036 mRLEAccelleration = 0;
00037 mIsCreatedAsScaled = false;
00038 mColorKey = -1;
00039 mIsSolid = false;
00040 CSPictureData data;
00041 mIsDirectLoad = isDirectLoad;
00042 if (!isDirectLoad)
00043 {
00044 loadPictureData(filename, data);
00045 }
00046 initialize(data, isDirectLoad);
00047 addPicture(this);
00048 }
00049
00050
00051
00052
00053
00054
00055
00056 SDL_Surface *CSPicture::convertToCurrentScreen(CSBitmap *image, SDL_Rect rect)
00057 {
00058 static char *functionName="convertToCurrentScreen";
00059 SDL_Surface *picture = 0;
00060 int flags = SDLMain::getScreen()->flags;
00061 if (image->picture->w > 1000)
00062 {
00063 if ((flags & SDL_HWSURFACE) == SDL_HWSURFACE)
00064 {
00065 flags -= SDL_HWSURFACE;
00066 }
00067 }
00068
00069
00070
00071 if (mAlpha >=0)
00072 {
00073 if ((flags & SDL_HWSURFACE) == SDL_HWSURFACE)
00074 {
00075 flags -= SDL_HWSURFACE;
00076 }
00077 }
00078 picture = SDL_CreateRGBSurface(flags,
00079 rect.w,
00080 rect.h,
00081 SDLMain::getScreen()->format->BitsPerPixel,
00082 SDLMain::getScreen()->format->Rmask,
00083 SDLMain::getScreen()->format->Gmask,
00084 SDLMain::getScreen()->format->Bmask,
00085 SDLMain::getScreen()->format->Amask);
00086
00087 if (picture == 0)
00088 {
00089 SDLMain::shutdown((std::string)"Create Surface Error error: " + SDL_GetError(), 1);
00090 }
00091 LOG_DEBUG_PRINT("image->picture->w: ", image->picture->w)
00092 LOG_DEBUG_PRINT("image->picture->h: ", (long) image->picture->h)
00093 LOG_DEBUG_PRINT("rect.x: ", (long) rect.x)
00094 LOG_DEBUG_PRINT("rect.y: ", (long) rect.y)
00095 LOG_DEBUG_PRINT("rect.w: ", (long) rect.w)
00096 LOG_DEBUG_PRINT("rect.h: ", (long) rect.h)
00097 LOG_DEBUG_PRINT("picture->w: ", (long) picture->w)
00098 LOG_DEBUG_PRINT("picture->h: ", (long) picture->h)
00099 LOG_DEBUG_PRINT("image->picture->format->BytesPerPixel: ", (long) image->picture->format->BytesPerPixel)
00100 LOG_DEBUG_PRINT("picture->format->BytesPerPixel: ", (long) picture->format->BytesPerPixel)
00101
00102 LOG_DEBUG_PRINT("picture: ", (long) picture)
00103 LOG_DEBUG_PRINT("image->picture: ", (long) image->picture)
00104 LOG_DEBUG_PRINT("image->picture->format_version: ", (long) image->picture->format_version)
00105 LOG_DEBUG_PRINT("picture->format_version: ", (long) picture->format_version)
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121 static long helperSingleton = 0;
00122 picture->format_version+=helperSingleton++;
00123
00124 if (SDL_BlitSurface(image->picture, &rect, picture, 0) < 0)
00125 {
00126 SDLMain::shutdown((std::string)"Display Format error: " + SDL_GetError(), 1);
00127 }
00128
00129 mR = image->r;
00130 mG = image->g;
00131 mB = image->b;
00132 if ((image->r>=0) && (image->g>=0) && (image->b>=0))
00133 {
00134 if (!(SDLMain::getScreen()->flags & SDL_HWSURFACE))
00135 {
00136 int key;
00137 key = SDL_MapRGB(picture->format, image->r, image->g, image->b);
00138 SDL_SetColorKey(picture, SDL_SRCCOLORKEY | mRLEAccelleration, key);
00139 }
00140 }
00141
00142
00143 if ((image->r>=0) && (image->g>=0) && (image->b>=0))
00144 {
00145 if (SDLMain::getScreen()->flags & SDL_HWSURFACE)
00146 {
00147 int key;
00148 key = SDL_MapRGB(picture->format, image->r, image->g, image->b);
00149 SDL_SetColorKey(picture, SDL_SRCCOLORKEY | mRLEAccelleration , key);
00150 }
00151 }
00152 mColorKey = picture->format->colorkey;
00153 if (mAlpha >=0) SDL_SetAlpha(picture, mRLEAccelleration | SDL_SRCALPHA, mAlpha);
00154
00155 bool mIsDoublebuffer = (picture->flags & SDL_DOUBLEBUF) == SDL_DOUBLEBUF;
00156 bool mIsHardware = (picture->flags & SDL_HWSURFACE) == SDL_HWSURFACE;
00157 bool mIsFullscreen = (picture->flags & SDL_FULLSCREEN) == SDL_FULLSCREEN;
00158 return picture;
00159 }
00160
00161 void CSPicture::initialize(const CSPictureData &data, bool isDirectLoad)
00162 {
00163 static char *functionName="initialize";
00164
00165
00166 if (isDirectLoad)
00167 {
00168 mId = 0;
00169 CSBitmap *image = CSBitmapDirectLoader::INSTANCE.load(mLoadName);
00170 mUpdateRegion.x = mPictureRegion.x = 0;
00171 mUpdateRegion.y = mPictureRegion.y = 0;
00172 mUpdateRegion.h = mPictureRegion.h = image->picture->h;
00173 mUpdateRegion.w = mPictureRegion.w = image->picture->w;
00174
00175 buildPixelProjection(image, mUpdateRegion);
00176 mAlpha = -1;
00177 mPicture = convertToCurrentScreen(image, mPictureRegion);
00178 mRLEUse = false;
00179
00180 mPixelPictureRegion = mPictureRegion;
00181 mPixelPictureRegion.x = 0;
00182 mPixelPictureRegion.y = 0;
00183 buildOptimizeData();
00184 checkRLEAccelleration();
00185 }
00186 else
00187 {
00188 mId = strdup(data.id);
00189 mFileName = strdup(data.filename);
00190
00191
00192
00193 CSBitmap *image = CSBitmapLoader::INSTANCE.load(data.filename);
00194 if (data.position.x + data.position.y + data.position.w + data.position.h == 0)
00195 {
00196 mUpdateRegion.x = mPictureRegion.x = data.position.x;
00197 mUpdateRegion.y = mPictureRegion.y = data.position.y;
00198 mUpdateRegion.h = mPictureRegion.h = image->picture->h;
00199 mUpdateRegion.w = mPictureRegion.w = image->picture->w;
00200 }
00201 else
00202 {
00203 mUpdateRegion.x = mPictureRegion.x = data.position.x;
00204 mUpdateRegion.y = mPictureRegion.y = data.position.y;
00205 mUpdateRegion.h = mPictureRegion.h = data.position.h;
00206 mUpdateRegion.w = mPictureRegion.w = data.position.w;
00207 }
00208
00209 buildPixelProjection(image, mUpdateRegion);
00210 mAlpha = data.alpha;
00211 mPicture = convertToCurrentScreen(image, mPictureRegion);
00212 mRLEUse = data.rleUse;
00213
00214 mPixelPictureRegion = mPictureRegion;
00215 mPixelPictureRegion.x = 0;
00216 mPixelPictureRegion.y = 0;
00217 buildOptimizeData();
00218 checkRLEAccelleration();
00219 }
00220 }
00221
00222 CSPicture::CSPicture(const CSPicture &picture)
00223 {
00224 static char *functionName="CSPicture";
00225 LOG_ENTER
00226 mFactor = 0;
00227 mScaledWidth = 0;
00228 mScaledHeight = 0;
00229 mScaledPicture = 0;
00230 mPicture = 0;
00231 mProjection = 0;
00232 mUpdateRegion = picture.mUpdateRegion;
00233 mPictureRegion = picture.mPictureRegion;
00234 mRLEUse = picture.mRLEUse;
00235 mAlpha = picture.mAlpha;
00236 mIsCreatedAsScaled = picture.mIsCreatedAsScaled;
00237 mLoadName = picture.mLoadName;
00238 mIsDirectLoad = picture.mIsDirectLoad;
00239
00240 mPixelPictureRegion = picture.mPixelPictureRegion;
00241 mStartPixelsX = picture.mStartPixelsX;
00242 mStartPixelsY = picture.mStartPixelsY;
00243
00244 mPixelProjectionCount = picture.mPixelProjectionCount;
00245 mRLEAccelleration = picture.mRLEAccelleration;
00246 if (picture.mId)
00247 {
00248 mId = strdup(picture.mId);
00249 }
00250 else
00251 {
00252 mId = 0;
00253 }
00254 mFileName = strdup(picture.mFileName);
00255 mIsSolid = picture.mIsSolid;
00256 mColorKey = picture.mColorKey;
00257 mR = picture.mR;
00258 mG = picture.mG;
00259 mB = picture.mB;
00260 mFactor = picture.mFactor;
00261
00262 if (mIsDirectLoad)
00263 {
00264 mPicture = convertToCurrentScreen(CSBitmapDirectLoader::INSTANCE.load(mLoadName), mPictureRegion);
00265 }
00266 else
00267 {
00268 mPicture = convertToCurrentScreen(CSBitmapLoader::INSTANCE.load(mFileName), mPictureRegion);
00269 }
00270 if (mIsSolid)
00271 {
00272 SDL_SetColorKey(mPicture, mRLEAccelleration, mColorKey+11);
00273 SDL_Surface *h = mPicture;
00274 mPicture = SDL_DisplayFormat(h);
00275 SDLMain::freeSurface(h);
00276 }
00277 else
00278 {
00279 SDL_Surface *h = mPicture;
00280
00281 if (!(SDLMain::getScreen()->flags & SDL_HWSURFACE))
00282 {
00283 SDL_SetColorKey(mPicture, SDL_SRCCOLORKEY| mRLEAccelleration, mColorKey);
00284 }
00285 mPicture = SDL_DisplayFormat(h);
00286
00287
00288 if (SDLMain::getScreen()->flags & SDL_HWSURFACE)
00289 {
00290 SDL_SetColorKey(mPicture, SDL_SRCCOLORKEY| mRLEAccelleration, mColorKey);
00291 }
00292 buildOptimizeData();
00293 SDLMain::freeSurface(h);
00294 }
00295
00296 int x,y;
00297 if (picture.mProjection != 0)
00298 {
00299 mProjection = (unsigned char **) new void *[mUpdateRegion.h];
00300 for (y = 0; y<mUpdateRegion.h; y++)
00301 {
00302 mProjection[y] = (unsigned char *) new unsigned char[mUpdateRegion.w];
00303 }
00304 for (y = 0; y<mUpdateRegion.h; y++)
00305 {
00306 for (x = 0; x<mUpdateRegion.w; x++)
00307 {
00308 mProjection[y][x] = picture.mProjection[y][x];
00309 }
00310 }
00311 }
00312 addPicture(this);
00313 LOG_EXIT
00314 }
00315
00316 CSPicture::~CSPicture()
00317 {
00318 static char *functionName="~CSPicture";
00319 LOG_ENTER
00320 removePicture(this);
00321 if (mId)
00322 {
00323 free(mId);
00324 mId = 0;
00325 }
00326 if (mFileName)
00327 {
00328 free(mFileName);
00329 mFileName = 0;
00330 }
00331 if (mProjection != 0)
00332 {
00333 for (int y = 0; y<mPictureRegion.h; y++)
00334 {
00335 delete[] mProjection[y];
00336 }
00337 delete[] mProjection;
00338 mProjection = 0;
00339 }
00340 if (mScaledPicture != 0)
00341 {
00342 if (SDLMain::isInitialized())
00343 {
00344 SDLMain::freeSurface(mScaledPicture);
00345 }
00346 mScaledPicture = 0;
00347 }
00348 LOG_EXIT
00349 }
00350
00351 void CSPicture::setSolid(bool b)
00352 {
00353 static char *functionName="setSolid";
00354 if (b == mIsSolid)
00355 {
00356 return;
00357 }
00358
00359 SDL_Surface *h = mPicture;
00360 mIsSolid = b;
00361 if (mIsSolid)
00362 {
00363 SDL_SetColorKey(mPicture, mRLEAccelleration, mColorKey+11);
00364 mPicture = SDL_DisplayFormat(h);
00365 mPixelPictureRegion = mPictureRegion;
00366 mPixelPictureRegion.x = 0;
00367 mPixelPictureRegion.y = 0;
00368 mStartPixelsX = 0;
00369 mStartPixelsY = 0;
00370 mUpdateRegion.h = mPictureRegion.h;
00371 mUpdateRegion.w = mPictureRegion.w;
00372 }
00373 else
00374 {
00375
00376 if (!(SDLMain::getScreen()->flags & SDL_HWSURFACE))
00377 {
00378 SDL_SetColorKey(mPicture, SDL_SRCCOLORKEY| mRLEAccelleration, mColorKey);
00379 }
00380 mPicture = SDL_DisplayFormat(h);
00381
00382
00383 if (SDLMain::getScreen()->flags & SDL_HWSURFACE)
00384 {
00385 SDL_SetColorKey(mPicture, SDL_SRCCOLORKEY| mRLEAccelleration, mColorKey);
00386 }
00387 buildOptimizeData();
00388 }
00389 SDLMain::freeSurface(h);
00390 }
00391
00392 void CSPicture::setAlpha(int alpha)
00393 {
00394 static char *functionName="setAlpha";
00395 LOG_ENTER
00396 if (alpha < 0)
00397 {
00398 mAlpha = -1;
00399 SDL_SetAlpha(mPicture, mRLEAccelleration, 0);
00400 LOG_EXIT
00401 return;
00402 }
00403 mAlpha = alpha;
00404 SDL_SetAlpha(mPicture, mRLEAccelleration | SDL_SRCALPHA, alpha);
00405 LOG_EXIT
00406 }
00407
00408 void CSPicture::display(SDL_Surface *destination, int x, int y)
00409 {
00410 static char *functionName="display";
00411 if ((!mIsSolid) && (mPixelProjectionCount == 0))
00412 {
00413 return;
00414 }
00415
00416 mUpdateRegion.x = mStartPixelsX + x;
00417 mUpdateRegion.y = mStartPixelsY + y;
00418
00419 if (SDL_BlitSurface(mPicture, &mPixelPictureRegion, destination, &mUpdateRegion)< 0)
00420 {
00421 SDLMain::shutdown((std::string)"BlitSurface error: " + SDL_GetError(), 1);
00422 }
00423 }
00424
00425 void CSPicture::display(int x, int y)
00426 {
00427 static char *functionName="display";
00428 if ((!mIsSolid) && (mPixelProjectionCount == 0))
00429 {
00430 return;
00431 }
00432
00433 mUpdateRegion.x = mStartPixelsX + x;
00434 mUpdateRegion.y = mStartPixelsY + y;
00435
00436 if (SDL_BlitSurface(mPicture, &mPixelPictureRegion, SDLMain::getScreen(), &mUpdateRegion)< 0)
00437 {
00438 SDLMain::shutdown((std::string)"BlitSurface error: " + SDL_GetError(), 1);
00439 }
00440
00441 SDLMain::addUpdateRect(mUpdateRegion);
00442 }
00443
00444 void CSPicture::display(CSDisplayParams *displayParams)
00445 {
00446 static char *functionName="display";
00447 if ((!mIsSolid) && (mPixelProjectionCount == 0))
00448 {
00449 return;
00450 }
00451
00452
00453
00454 mUpdateRegion.x = mStartPixelsX + displayParams->mXDisplayStart + displayParams->mXPos - displayParams->mXWorldStart;
00455 mUpdateRegion.y = mStartPixelsY + displayParams->mYDisplayStart + displayParams->mYPos - displayParams->mYWorldStart;
00456
00457
00458 if (SDL_BlitSurface(mPicture, &mPixelPictureRegion, SDLMain::getScreen(), &mUpdateRegion)< 0)
00459 {
00460 SDLMain::shutdown((std::string)"BlitSurface error: " + SDL_GetError(), 1);
00461 }
00462
00463 SDLMain::addUpdateRect(mUpdateRegion);
00464 }
00465
00466 void CSPicture::resetSurface()
00467 {
00468 static char *functionName="resetSurface";
00469 LOG_ENTER
00470 SDLMain::freeSurface(mPicture);
00471
00472 if (mIsCreatedAsScaled)
00473 {
00474 SDL_Surface *picture = 0;
00475 if (mIsDirectLoad)
00476 {
00477 picture = convertToCurrentScreen(CSBitmapDirectLoader::INSTANCE.load(mLoadName), mPictureRegion);
00478 }
00479 else
00480 {
00481 picture = convertToCurrentScreen(CSBitmapLoader::INSTANCE.load(mFileName), mPictureRegion);
00482 }
00483 if (picture == 0)
00484 {
00485 SDLMain::shutdown((std::string)"ConvertError: " + SDL_GetError(), 13);
00486 }
00487 mPicture = SDLMain::getInstance()->scale(picture, mFactor);
00488 if (mPicture == 0)
00489 {
00490 SDLMain::shutdown((std::string)"ScaleError: " + SDL_GetError(), 12);
00491 }
00492 SDLMain::freeSurface(picture);
00493
00494 if (mIsSolid)
00495 {
00496 SDL_SetColorKey(mPicture, mRLEAccelleration, mColorKey+11);
00497 SDL_Surface *h = mPicture;
00498 mPicture = SDL_DisplayFormat(h);
00499 if (mPicture == 0)
00500 {
00501 SDLMain::shutdown((std::string)"Format Error: " + SDL_GetError(), 14);
00502 }
00503 SDLMain::freeSurface(h);
00504 }
00505 else
00506 {
00507 SDL_Surface *h = mPicture;
00508
00509 if (!(SDLMain::getScreen()->flags & SDL_HWSURFACE))
00510 {
00511 SDL_SetColorKey(mPicture, SDL_SRCCOLORKEY| mRLEAccelleration, mColorKey);
00512 }
00513 mPicture = SDL_DisplayFormat(h);
00514
00515
00516 if (SDLMain::getScreen()->flags & SDL_HWSURFACE)
00517 {
00518 SDL_SetColorKey(mPicture, SDL_SRCCOLORKEY| mRLEAccelleration, mColorKey);
00519 }
00520 SDLMain::freeSurface(h);
00521 }
00522 }
00523 else
00524 {
00525
00526
00527
00528 if (mIsDirectLoad)
00529 {
00530 mPicture = convertToCurrentScreen(CSBitmapDirectLoader::INSTANCE.load(mLoadName), mPictureRegion);
00531 }
00532 else
00533 {
00534 mPicture = convertToCurrentScreen(CSBitmapLoader::INSTANCE.load(mFileName), mPictureRegion);
00535 }
00536 if (mPicture == 0)
00537 {
00538 SDLMain::shutdown((std::string)"ConvertError: " + SDL_GetError(), 16);
00539 }
00540 if (mIsSolid)
00541 {
00542 SDL_SetColorKey(mPicture, mRLEAccelleration, mColorKey+11);
00543 SDL_Surface *h = mPicture;
00544 mPicture = SDL_DisplayFormat(h);
00545 if (mPicture == 0)
00546 {
00547 SDLMain::shutdown((std::string)"Format Error: " + SDL_GetError(), 15);
00548 }
00549 SDLMain::freeSurface(h);
00550 }
00551 else
00552 {
00553 SDL_Surface *h = mPicture;
00554
00555 if (!(SDLMain::getScreen()->flags & SDL_HWSURFACE))
00556 {
00557 SDL_SetColorKey(mPicture, SDL_SRCCOLORKEY| mRLEAccelleration, mColorKey);
00558 }
00559 mPicture = SDL_DisplayFormat(h);
00560
00561
00562 if (SDLMain::getScreen()->flags & SDL_HWSURFACE)
00563 {
00564 SDL_SetColorKey(mPicture, SDL_SRCCOLORKEY| mRLEAccelleration, mColorKey);
00565 }
00566 SDLMain::freeSurface(h);
00567 }
00568 mFactor = 0;
00569 }
00570 if (mScaledPicture != 0)
00571 {
00572 SDLMain::freeSurface(mScaledPicture);
00573 mScaledPicture = 0;
00574 }
00575 setAlpha(mAlpha);
00576 LOG_EXIT
00577 }
00578
00579
00580
00581 void CSPicture::addPicture(CSPicture *picture)
00582 {
00583 if (picture == 0)
00584 {
00585 return;
00586 }
00587 removePicture(picture);
00588 mAllPictures.push_back(picture);
00589 }
00590
00591 void CSPicture::removePicture(CSPicture *picture)
00592 {
00593 if (picture == 0)
00594 {
00595 return;
00596 }
00597
00598 CSPictures::iterator iter = mAllPictures.begin();
00599 while ( iter != mAllPictures.end())
00600 {
00601 if ((*iter) == picture)
00602 {
00603 mAllPictures.erase(iter);
00604 iter = mAllPictures.begin();
00605 }
00606 else
00607 {
00608 iter++;
00609 }
00610 }
00611 }
00612
00613
00614
00615 void CSPicture::resetSurfaces()
00616 {
00617 static char *functionName="resetSurfaces";
00618 LOG_ENTER
00619 CSPictures::iterator iter = mAllPictures.begin();
00620 while ( iter != mAllPictures.end())
00621 {
00622 (*iter)->resetSurface();
00623 iter++;
00624 }
00625 LOG_EXIT
00626 }
00627
00628
00629
00630
00631
00632
00633
00634
00635 void CSPicture::buildPixelProjection(CSBitmap *image, const SDL_Rect &position)
00636 {
00637 static char *functionName="buildPixelProjection";
00638
00639 if ( (position.x == 0) &&
00640 (position.y == 0) &&
00641 (position.h == 0) &&
00642 (position.w == 0)
00643 )
00644 {
00645
00646
00647
00648
00649 return;
00650 }
00651
00652
00653 mPixelProjectionCount = 0;
00654
00655
00656 int key = SDL_MapRGB(image->picture->format, image->r, image->g, image->b);
00657 int x,y;
00658
00659
00660
00661 if (mProjection != 0)
00662 {
00663 for (y = 0; y<mPictureRegion.h; y++)
00664 {
00665 delete[] mProjection[y];
00666 }
00667 delete[] mProjection;
00668 mProjection = 0;
00669 }
00670
00671
00672 mProjection = (unsigned char **) new void *[position.h];
00673 for (y = 0; y<position.h; y++)
00674 {
00675 mProjection[y] = 0;
00676 }
00677 for (y = 0; y<position.h; y++)
00678 {
00679 mProjection[y] = (unsigned char *) new unsigned char[position.w];
00680 }
00681
00682 if (SDL_MUSTLOCK(image->picture))
00683 {
00684 SDL_LockSurface(image->picture);
00685 }
00686 for (y = 0; y<position.h; y++)
00687 {
00688 for (x = 0; x<position.w; x++)
00689 {
00690 Uint32 p = SDLMain::getPixel(image->picture, x+position.x, y+position.y);
00691
00692 if (key == p)
00693 {
00694 mProjection[y][x] = 0;
00695 }
00696 else
00697 {
00698 mProjection[y][x] = 1;
00699 mPixelProjectionCount++;
00700 }
00701
00702 }
00703 }
00704
00705 if (SDL_MUSTLOCK(image->picture))
00706 {
00707 SDL_UnlockSurface(image->picture);
00708 }
00709 }
00710
00711 void CSPicture::checkRLEAccelleration()
00712 {
00713 static char *functionName="checkRLEAccelleration";
00714 if (mRLEUse == RLE_YES)
00715 {
00716 mRLEAccelleration = SDL_RLEACCEL;
00717 return;
00718 }
00719
00720 if (mRLEUse == RLE_NO)
00721 {
00722 return;
00723 }
00724
00725
00726
00727 if (mPixelProjectionCount <((mUpdateRegion.h*mUpdateRegion.w)/4))
00728 {
00729
00730
00731 mRLEAccelleration = SDL_RLEACCEL;
00732 }
00733 }
00734
00735 void CSPicture::loadPictureData(const std::string &filename, CSPictureData &data)
00736 {
00737 static char *functionName="loadPictureData";
00738 LOG_ENTER
00739 CSXMLHelper xmlSupport(filename, "PICTURE");
00740 try
00741 {
00742 if (xmlSupport.getError())
00743 {
00744 LOG_EXIT
00745 throw "error";
00746 }
00747
00748 data.id = strdup(xmlSupport.getString("ID").c_str());
00749 int hasPositionData = xmlSupport.getInt("count(/PICTURE/X)");
00750 if (hasPositionData == 1)
00751 {
00752 data.position.x = xmlSupport.getInt("X");
00753 data.position.y = xmlSupport.getInt("Y");
00754 data.position.w = xmlSupport.getInt("WIDTH");
00755 data.position.h = xmlSupport.getInt("HEIGHT");
00756 }
00757 else
00758 {
00759 data.position.x = 0;
00760 data.position.y = 0;
00761 data.position.w = 0;
00762 data.position.h = 0;
00763 }
00764
00765 int hasRLEData = xmlSupport.getInt("count(/PICTURE/RLE_USE)");
00766 if (hasRLEData == 1)
00767 {
00768 data.rleUse = xmlSupport.getInt("RLE_USE");
00769 }
00770 int hasAlpha = xmlSupport.getInt("count(/PICTURE/ALPHA)");
00771 if (hasAlpha == 1)
00772 {
00773 data.alpha = xmlSupport.getInt("ALPHA");
00774 }
00775 data.filename = strdup(xmlSupport.getString("BITMAP").c_str());
00776 }
00777 catch(...)
00778 {
00779 LOG_EXIT
00780 SDLMain::shutdown((std::string)"XML error \"" + filename + "\": " + xmlSupport.getErrorMessage().c_str(), 1);
00781 }
00782 LOG_EXIT
00783 }
00784
00785
00786
00787
00788 void CSPicture::buildOptimizeData()
00789 {
00790 static char *functionName="buildOptimizeData";
00791 if (mProjection == 0)
00792 {
00793 return;
00794 }
00795
00796 int x,y;
00797 unsigned int startPixelsX = 0;
00798 unsigned int startPixelsY = 0;
00799 unsigned int endPixelsX = mPictureRegion.w;
00800 unsigned int endPixelsY = mPictureRegion.h;
00801
00802 for (y = 0; y<mPictureRegion.h; y++)
00803 {
00804 bool hasY = false;
00805 for (x = 0; x<mPictureRegion.w; x++)
00806 {
00807 if (mProjection[y][x] == 1)
00808 {
00809 hasY = true;
00810 break;
00811 }
00812 }
00813 if (hasY)
00814 {
00815 break;
00816 }
00817 startPixelsY++;
00818 }
00819
00820 for (x = 0; x<mPictureRegion.w; x++)
00821 {
00822 bool hasX = false;
00823 for (y = 0; y<mPictureRegion.h; y++)
00824 {
00825 if (mProjection[y][x] == 1)
00826 {
00827 hasX = true;
00828 break;
00829 }
00830 }
00831 if (hasX)
00832 {
00833 break;
00834 }
00835 startPixelsX++;
00836 }
00837
00838 for (y = mPictureRegion.h-1; y>=startPixelsY; y--)
00839 {
00840 bool hasY = false;
00841 for (x = 0; x<mPictureRegion.w; x++)
00842 {
00843 if (mProjection[y][x] == 1)
00844 {
00845 hasY = true;
00846 break;
00847 }
00848 }
00849 if (hasY)
00850 {
00851 break;
00852 }
00853 endPixelsY = y;
00854 }
00855
00856 for (x = mPictureRegion.w-1; x>=startPixelsX; x--)
00857 {
00858 bool hasX = false;
00859 for (y = 0; y<mPictureRegion.h; y++)
00860 {
00861 if (mProjection[y][x] == 1)
00862 {
00863 hasX = true;
00864 break;
00865 }
00866 }
00867 if (hasX)
00868 {
00869 break;
00870 }
00871 endPixelsX = x;
00872 }
00873
00874 mStartPixelsX = startPixelsX;
00875 mStartPixelsY = startPixelsY;
00876 mPixelPictureRegion.x += startPixelsX;
00877 mPixelPictureRegion.y += startPixelsY;
00878 mPixelPictureRegion.w = endPixelsX - startPixelsX;
00879 mPixelPictureRegion.h = endPixelsY - startPixelsY;
00880 mUpdateRegion.w = endPixelsX - startPixelsX;
00881 mUpdateRegion.h = endPixelsY - startPixelsY;
00882 }
00883
00884
00885
00886
00887
00888
00889 void CSPicture::scale(int width, int divideX, int height, int divideY)
00890 {
00891 static char *functionName="scale";
00892 if (mIsDirectLoad)
00893 {
00894 CSBitmapDirectLoader::INSTANCE.scale((char *) mLoadName.c_str(), width, divideX*mUpdateRegion.w, height, divideY*mUpdateRegion.h);
00895 }
00896 else
00897 {
00898 CSBitmapLoader::INSTANCE.scale(mFileName, width, divideX*mUpdateRegion.w, height, divideY*mUpdateRegion.h);
00899 }
00900
00901 if (mProjection != 0)
00902 {
00903 for (int y = 0; y<mPictureRegion.h; y++)
00904 {
00905 delete[] mProjection[y];
00906 }
00907 delete[] mProjection;
00908 mProjection = 0;
00909 }
00910
00911 mUpdateRegion.x = mPictureRegion.x = SDLMain::getInstance()->scaleX(width, divideX*mUpdateRegion.w, mUpdateRegion.x);
00912 mUpdateRegion.y = mPictureRegion.y = SDLMain::getInstance()->scaleY(height, divideY*mUpdateRegion.h, mUpdateRegion.y);
00913 mUpdateRegion.w = mPictureRegion.w = SDLMain::getInstance()->scaleX(width, divideX*mUpdateRegion.w, mUpdateRegion.w);
00914 mUpdateRegion.h = mPictureRegion.h = SDLMain::getInstance()->scaleY(height, divideY*mUpdateRegion.h, mUpdateRegion.h);
00915
00916 resetSurface();
00917
00918 CSBitmap *image = 0;
00919 if (mIsDirectLoad)
00920 {
00921 image = CSBitmapDirectLoader::INSTANCE.load(mLoadName);
00922 }
00923 else
00924 {
00925 image = CSBitmapLoader::INSTANCE.load(mFileName);
00926 }
00927 buildPixelProjection(image, mUpdateRegion);
00928 mPixelPictureRegion = mPictureRegion;
00929 mPixelPictureRegion.x = 0;
00930 mPixelPictureRegion.y = 0;
00931 buildOptimizeData();
00932 checkRLEAccelleration();
00933 }
00934
00935 void CSPicture::getRGB(int &r, int &b, int &g)
00936 {
00937 static char *functionName="getRGB";
00938 r = mR;
00939 g = mG;
00940 b = mB;
00941 }
00942
00943
00944
00945
00946
00947
00948
00949
00950 SDL_Surface *CSPicture::getScaledPicture(double factor)
00951 {
00952 static char *functionName="getScaledPicture";
00953 if ((mFactor == factor) && (mScaledPicture != 0))
00954 {
00955 return mScaledPicture;
00956 }
00957 mFactor = factor;
00958 if (mScaledPicture != 0)
00959 {
00960 SDLMain::freeSurface(mScaledPicture);
00961 mScaledPicture = 0;
00962 }
00963
00964 mScaledPicture = SDLMain::getInstance()->scale(mPicture, factor);
00965 if (!isSolid())
00966 {
00967 int key;
00968 key = SDL_MapRGB(mScaledPicture->format, mR, mG, mB);
00969 SDL_SetColorKey(mScaledPicture, SDL_SRCCOLORKEY, key);
00970 }
00971 return mScaledPicture;
00972 }
00973
00974
00975
00976
00977
00978
00979
00980
00981 SDL_Surface *CSPicture::getScaledPicture(int w, int h)
00982 {
00983 static char *functionName="getScaledPicture";
00984
00985 if ((mScaledWidth == h) && (mScaledHeight == h) && (mScaledPicture != 0))
00986 {
00987 return mScaledPicture;
00988 }
00989 mScaledWidth = w;
00990 mScaledHeight = h;
00991 if (mScaledPicture != 0)
00992 {
00993 SDLMain::freeSurface(mScaledPicture);
00994 mScaledPicture = 0;
00995 }
00996
00997 mScaledPicture = SDLMain::getInstance()->scale(mPicture, w,h);
00998 if (!isSolid())
00999 {
01000 int key;
01001 key = SDL_MapRGB(mScaledPicture->format, mR, mG, mB);
01002 SDL_SetColorKey(mScaledPicture, SDL_SRCCOLORKEY, key);
01003 }
01004 return mScaledPicture;
01005 }
01006
01007 bool CSPicture::isTransparent(int x, int y)
01008 {
01009 static char *functionName="isTransparent";
01010 LOG_ENTER
01011 if (SDL_MUSTLOCK(mPicture))
01012 {
01013 SDL_LockSurface(mPicture);
01014 }
01015 bool val = mColorKey == SDLMain::getPixel(mPicture, x, y);
01016 if (SDL_MUSTLOCK(mPicture))
01017 {
01018 SDL_UnlockSurface(mPicture);
01019 }
01020 LOG_EXIT
01021 return val;
01022 }
01023
01024
01025
01026
01027
01028 CSPicture* CSPicture::createScaledPicture(CSPicture* picture, double factor)
01029 {
01030 CSPicture *newPicture = new CSPicture(*picture);
01031 newPicture->mIsCreatedAsScaled = true;
01032 newPicture->mFactor = factor;
01033 newPicture->resetSurface();
01034
01035 newPicture->mUpdateRegion.x = newPicture->mUpdateRegion.x * newPicture->mFactor;
01036 newPicture->mUpdateRegion.y = newPicture->mUpdateRegion.y * newPicture->mFactor;
01037 newPicture->mUpdateRegion.w = newPicture->mUpdateRegion.w * newPicture->mFactor;
01038 newPicture->mUpdateRegion.h = newPicture->mUpdateRegion.h * newPicture->mFactor;
01039 newPicture->mPixelPictureRegion = newPicture->mUpdateRegion;
01040 newPicture->mPixelPictureRegion.x = 0;
01041 newPicture->mPixelPictureRegion.y = 0;
01042
01043
01044
01045
01046
01047 newPicture->buildOptimizeData();
01048 newPicture->checkRLEAccelleration();
01049
01050 return newPicture;
01051 }