Hosting courtesy of Sourceforge

SourceForge Logo
Main Page   Namespace List   Class Hierarchy   Compound List   File List   Namespace Members   Compound Members   File Members  

draw.cpp

Go to the documentation of this file.
00001 //
00002 //      Copyright (C) 2002 Robert Renaud
00003 //
00004 //      This program is free software; you can redistribute it and/or
00005 //      modify it under the terms of the GNU General Public License
00006 //      as published by the Free Software Foundation; either version 2
00007 //      of the License, or (at your option) any later version.
00008 //
00009 //      This program is distributed in the hope that it will be useful,
00010 //      but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 //      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
00012 //
00013 //      See the GNU General Public License for more details.
00014 //
00015 //      You should have received a copy of the GNU General Public License
00016 //      along with this program; if not, write to the Free Software
00017 //      Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
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         // else baseFolder = ""; // does nothing
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                 // if string doesn't contain a '/', assume its a relative path, and append the base directory
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"); // replace with class derived from GeneralException
00211 
00212 }
00213 
00214 void Graphics::putpixel(SDL_Surface *surface, int x, int y, Uint32 pixel)
00215 {
00216     int bpp = surface->format->BytesPerPixel;
00217     /* Here p is the address to the pixel we want to set */
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     /* Here p is the address to the pixel we want to retrieve */
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;       /* shouldn't happen, but avoids warnings */
00271     }
00272 }
00273 
00274 Uint32 Graphics::makeTopLeftPixelTrans( SDL_Surface* lpSurface ) {
00275         SDL_LockSurface( lpSurface ); //lock surface so we can get the pixel to make transparent
00276         Uint32 pixel = getpixel( lpSurface, 0, 0 ); //pick top left pixel
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 

Generated on Tue May 21 07:26:51 2002 for BomberLAN by doxygen1.2.12 written by Dimitri van Heesch, © 1997-2001