00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "draw.h"
00021 #include <cmath>
00022
00023 using namespace Graphics;
00024
00025 SingleFrameImage::SingleFrameImage() :
00026 image(NULL)
00027 {
00028 #ifdef DEBUG_GRAPHICS_DRAWING
00029 debugOut << "SingleFrameImage::SingleFrameImage()" << endl;
00030 #endif
00031 }
00032
00033 SingleFrameImage::SingleFrameImage(const string& BMP_filename, Uint32 SDL_Flags) {
00034 readFromFile(BMP_filename);
00035 setTransparency(SDL_Flags);
00036 }
00037
00038 void SingleFrameImage::readFromFile(const string& BMP_filename) {
00039 #ifdef DEBUG_GRAPHICS_DRAWING
00040 debugOut << "Assigning " << BMP_filename << " for SingleFrameImage" << endl;
00041 #endif
00042 image = ImageManager::getInstance()->getImage(BMP_filename);
00043 }
00044 void SingleFrameImage::drawAt(SDL_Surface* screen, SDL_Rect *loc) {
00045 SDL_BlitSurface(image , NULL , screen, loc);
00046 }
00047
00048 void SingleFrameImage::setTransparency(Uint32 flags) {
00049 #ifdef DEBUG_GRAPHICS_DRAWING
00050 Uint8 bpp = image->format->BitsPerPixel;
00051 debugOut << "SingleFrameImage::setTransparency(" << int(flags) << ") for image with "
00052 << int(bpp) << " BitsPerPixel" << endl;
00053 #endif
00054 makeTopLeftPixelTrans(image);
00055 }
00056
00057 AbstractImage* SingleFrameImage::dynCopyImage() {
00058 return new SingleFrameImage(*this);
00059 }
00060
00061 AnimatedImage::AnimatedImage() :
00062 nextFrameIndex(0),
00063 curUpdates(0),
00064 frameVec(0, (SDL_Surface*) 0)
00065 {
00066 #ifdef DEBUG_GRAPHICS_DRAWING
00067 debugOut << "AnimatedImage()" << endl;
00068 #endif
00069 }
00070
00071 AnimatedImage::AnimatedImage(const string& ANI_filename, Uint32 flags) :
00072 nextFrameIndex(0),
00073 curUpdates(0),
00074 frameVec(0, (SDL_Surface*) 0 )
00075 {
00076 readFromFile(ANI_filename);
00077 setTransparency(flags);
00078 }
00079
00080 void AnimatedImage::readFromFile(const string& ANI_filename) {
00081 size_t lastSlashLoc = ANI_filename.rfind('/');
00082 string baseFolder;
00083 if (lastSlashLoc != string::npos) baseFolder = ANI_filename.substr(0, lastSlashLoc + 1);
00084
00085
00086 #ifdef DEBUG_GRAPHICS_DRAWING
00087 debugOut << "AnimatedImage::readFromFile() Trying to open " << ANI_filename
00088 << " with base folder " << baseFolder <<endl;
00089 #endif
00090 ifstream input(ANI_filename.c_str());
00091
00092 input >> numFrames;
00093 frameVec.reserve(numFrames);
00094
00095 input >> maxUpdates;
00096
00097 #ifdef DEBUG_GRAPHICS_DRAWING
00098 debugOut << "\tinputted numFrames as "<< numFrames << endl;
00099 #endif
00100
00101 std::string bmpFilename;
00102 for (size_t i = 0; i < numFrames; i++) {
00103 input >> bmpFilename;
00104 #ifdef DEBUG_GRAPHICS_DRAWING
00105 debugOut << "\t\tAssigning " << bmpFilename << " as frame " << i << endl;
00106 #endif
00107
00108
00109 if (bmpFilename.find('/') == string::npos) {
00110 frameVec.push_back(ImageManager::getInstance()->getImage(baseFolder + bmpFilename));
00111 } else {
00112 frameVec.push_back(ImageManager::getInstance()->getImage(bmpFilename));
00113 }
00114 if (!input) throw Util::GeneralException("error reading image " +
00115 bmpFilename + " in animation file "+ ANI_filename, __FILE__, __LINE__);
00116 }
00117 }
00118
00119 void AnimatedImage::drawAt(SDL_Surface * screen, SDL_Rect *loc) {
00120 curUpdates++;
00121 if (curUpdates >= maxUpdates) {
00122 nextFrameIndex++;
00123 nextFrameIndex%=numFrames;
00124 curUpdates=0;
00125 #ifdef DEBUG_GRAPHICS_DRAWING
00126 debugOut << "incrementing frame... frame is now " << nextFrameIndex
00127 << " , numFrames = " << numFrames << endl;
00128 #endif
00129 }
00130 SDL_BlitSurface(frameVec[nextFrameIndex], NULL, screen, loc);
00131 }
00132
00133 void AnimatedImage::setTransparency(Uint32 flags) {
00134 #ifdef DEBUG_GRAPHICS_DRAWING
00135 debugOut << "AnimatedImage::setTransparency(" << flags << ") with "
00136 << int(frameVec[0]->format->BytesPerPixel) << " BytesPerPixel"<< endl;
00137 #endif
00138 if (flags && SDL_SRCCOLORKEY) {
00139 for (size_t i = 0; i < frameVec.size(); i++) {
00140 makeTopLeftPixelTrans(frameVec[i]);
00141 }
00142 }
00143 }
00144
00145 AbstractImage* AnimatedImage::dynCopyImage() {
00146 return new AnimatedImage(*this);
00147 }
00148
00149 ImageFrame::ImageFrame(DrawableAt* imageToFrame, Uint32 pixelColor, Uint8 width) :
00150 framedImage(imageToFrame),
00151 borderColor(pixelColor),
00152 borderWidth(width)
00153 { }
00154
00155 void ImageFrame::drawAt(SDL_Surface* surf, SDL_Rect* rect) {
00156 if (framedImage != NULL) framedImage->drawAt(surf, rect);
00157
00158 int x=0, y=0;
00159 int xMax = rect->x + rect->w;
00160 int yMax = rect->y + rect->h;
00161
00162 SDL_LockSurface(surf);
00163 for (x = rect->x; x < xMax; x++) {
00164 for (int vertOffset = 0; y < borderWidth; y++) {
00165 putpixel(surf, x, rect->y + vertOffset , borderColor);
00166 putpixel(surf, x, rect->y + rect->h - vertOffset, borderColor);
00167 }
00168 }
00169
00170 for ( y = rect->y; y < yMax; y++) {
00171 for (int horizOffset =0; x < borderWidth; x++) {
00172 putpixel(surf, rect->x + horizOffset, y, borderColor);
00173 putpixel(surf, rect->x + rect->w - horizOffset, y, borderColor);
00174 }
00175 }
00176 SDL_UnlockSurface(surf);
00177 }
00178
00179 ImageFrame::~ImageFrame() {
00180 if (framedImage != NULL) delete framedImage;
00181 }
00182
00183
00184 ReadImage::ReadImage(AbstractImage*& imgPointer) :
00185 imgPointerRef(imgPointer)
00186 { }
00187
00188 void ReadImage::getValue(std::istream &input) {
00189 std::string filename;
00190 input >> filename;
00191
00192 imgPointerRef = dynGenerateImage(filename);
00193 }
00194
00195
00196 Graphics::AbstractImage* Graphics::dynGenerateImage(const string& filename) {
00197 string extension = filename.substr(filename.rfind('.'));
00198 #ifdef DEBUG_GRAPHICS_DRAWING
00199 debugOut << "Graphics::dynGenerateImage(), filename is " << filename
00200 << " extension is " << extension << endl;
00201 #endif
00202 if (extension == ".bmp") {
00203 return new SingleFrameImage(filename);
00204 } else if (extension == ".ani") {
00205 return new AnimatedImage(filename);
00206 }
00207 #ifdef DEBUG_GRAPHICS_DRAWING
00208 debugOut << "extension " << extension << " unrecognized, throwing exception\n";
00209 #endif
00210 throw Util::GeneralException("Unrecognized extension");
00211
00212 }
00213
00214 void Graphics::putpixel(SDL_Surface *surface, int x, int y, Uint32 pixel)
00215 {
00216 int bpp = surface->format->BytesPerPixel;
00217
00218 Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;
00219
00220 switch(bpp) {
00221 case 1:
00222 *p = pixel;
00223 break;
00224
00225 case 2:
00226 *(Uint16 *)p = pixel;
00227 break;
00228
00229 case 3:
00230 if(SDL_BYTEORDER == SDL_BIG_ENDIAN) {
00231 p[0] = (pixel >> 16) & 0xff;
00232 p[1] = (pixel >> 8) & 0xff;
00233 p[2] = pixel & 0xff;
00234 } else {
00235 p[0] = pixel & 0xff;
00236 p[1] = (pixel >> 8) & 0xff;
00237 p[2] = (pixel >> 16) & 0xff;
00238 }
00239 break;
00240
00241 case 4:
00242 *(Uint32 *)p = pixel;
00243 break;
00244 }
00245 }
00246
00247 Uint32 Graphics::getpixel(SDL_Surface *surface, int x, int y)
00248 {
00249 int bpp = surface->format->BytesPerPixel;
00250
00251 Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;
00252
00253 switch(bpp) {
00254 case 1:
00255 return *p;
00256
00257 case 2:
00258 return *(Uint16 *)p;
00259
00260 case 3:
00261 if(SDL_BYTEORDER == SDL_BIG_ENDIAN)
00262 return p[0] << 16 | p[1] << 8 | p[2];
00263 else
00264 return p[0] | p[1] << 8 | p[2] << 16;
00265
00266 case 4:
00267 return *(Uint32 *)p;
00268
00269 default:
00270 return 0;
00271 }
00272 }
00273
00274 Uint32 Graphics::makeTopLeftPixelTrans( SDL_Surface* lpSurface ) {
00275 SDL_LockSurface( lpSurface );
00276 Uint32 pixel = getpixel( lpSurface, 0, 0 );
00277 SDL_SetColorKey( lpSurface, SDL_SRCCOLORKEY | SDL_RLEACCEL, pixel );
00278 SDL_UnlockSurface( lpSurface );
00279
00280 return pixel;
00281 }
00282
00283 Uint8 Graphics::calcRedComp(SDL_PixelFormat* format, Uint32 pixel) {
00284 pixel&=format->Rmask;
00285 pixel>>=format->Rshift;
00286 pixel<<=format->Rloss;
00287 return (Uint8) pixel;
00288 }
00289
00290 Uint8 Graphics::calcGreenComp(SDL_PixelFormat* format, Uint32 pixel) {
00291 pixel&=format->Gmask;
00292 pixel>>=format->Gshift;
00293 pixel<<=format->Gloss;
00294 return (Uint8) pixel;
00295 }
00296
00297 Uint8 Graphics::calcBlueComp(SDL_PixelFormat* format, Uint32 pixel) {
00298 pixel&=format->Bmask;
00299 pixel>>=format->Bshift;
00300 pixel<<=format->Bloss;
00301 return (Uint8) pixel;
00302 }
00303
00304