AaronCameron.net
Because you all make me very, very tired.
Not a Member? - Login or Create an Account
Wednesday the 23rd of May 2012 @ 06:10pm
Front Page Journal Projects Your Profile About
[]

LibN2L-4 Library Code Reference

Classes
Compounds
Files
Members
Method Index
Full Reference

cSurfaceCommonImp.cpp

Go to the documentation of this file.
00001 /************************************************************************
00002 Nova-2 Library (libN2L, or simply n2l) Game development C++ Library
00003 Copyright (C) 2003  Aaron Cameron
00004 
00005 This library is free software; you can redistribute it and/or
00006 modify it under the terms of the GNU Lesser General Public
00007 License as published by the Free Software Foundation; either
00008 version 2.1 of the License, or (at your option) any later version.
00009 
00010 This library is distributed in the hope that it will be useful,
00011 but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013 Lesser General Public License for more details.
00014 
00015 You should have received a copy of the GNU Lesser General Public
00016 License along with this library; if not, write to the Free Software
00017 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00018 
00019 A copy of the GNU Lesser General Public License has been provided with
00020 this library in the file 'COPYING'.
00021 
00022 Contact information for the author of this library has been provided
00023 with this library in the file 'AUTHOR'.
00024 ************************************************************************/
00025 #include "cSurfaceCommonImp.h"
00026 
00027 namespace n2l
00028 {
00029 
00030 
00031     /* ************************************************************ */
00032     cSurfaceCommonImp::cSurfaceCommonImp() :
00033         mOwned(true),
00034         mSurface(0),
00035         mReadLockCount(0),
00036         mWriteLockCount(0)
00037     {
00038         requireSDLSubSystem(SDLSubSystemInitFlag_Video);
00039     }
00040 
00041 
00042     /* ************************************************************ */
00043     cSurfaceCommonImp::~cSurfaceCommonImp()
00044     {
00045         cSurfaceCommonImp::free();
00046         releaseSDLSubSystem(SDLSubSystemInitFlag_Video);
00047     }
00048 
00049 
00050     /* ************************************************************ */
00051     void cSurfaceCommonImp::blit(   const tVector2s & iDestPos,
00052                                     const cSurfaceInterface & iSurface,
00053                                     const tRectangle2u & iSrcRect )
00054     {
00055         if (empty())
00056             throw cBadDataUseException( "cSurfaceCommonImp::blit",
00057                                         "Blitting to an empty surface" );
00058         if (iSurface.empty())
00059             throw cBadDataUseException( "cSurfaceCommonImp::blit",
00060                                         "Blitting from an empty surface" );
00061 
00062         // Check for outstanding locks on either of the surfaces.
00063 
00064         // Build SDL rects
00065         SDL_Rect srcRect, destRect;
00066         srcRect.x = iSrcRect.x();
00067         srcRect.y = iSrcRect.y();
00068         srcRect.w = iSrcRect.w();
00069         srcRect.h = iSrcRect.h();
00070         if (srcRect.w==0)
00071             srcRect.w = iSurface.properties().size().x();
00072         if (srcRect.h==0)
00073             srcRect.h = iSurface.properties().size().y();
00074 
00075         destRect.x = iDestPos.x();
00076         destRect.y = iDestPos.y();
00077         
00078         // Do the actual blit
00079         if (-1==SDL_BlitSurface(iSurface.rawSurface(),&srcRect,
00080                                 mSurface,&destRect ))
00081             throw cSDLException("cSurfaceCommonImp::blit",
00082                                 "SDL BlitSurface failed");
00083     }
00084 
00085 
00086     /* ************************************************************ */
00087     const bool cSurfaceCommonImp::empty() const
00088     {
00089         return (0==mSurface);
00090     }
00091 
00092 
00093     /* ************************************************************ */
00094     const cPixelFormat & cSurfaceCommonImp::format() const
00095     {
00096         return mFormat;
00097     }
00098 
00099 
00100     /* ************************************************************ */
00101     const cSurfaceProperties & cSurfaceCommonImp::properties() const
00102     {
00103         return mProperties;
00104     }
00105 
00106 
00107     /* ************************************************************ */
00108     const void * const cSurfaceCommonImp::aquireROBuffer() const
00109     {
00110         if (writeLocks()) return 0;
00111         if (empty())
00112             throw cBadDataUseException(
00113                                     "cSurfaceCommonImp::aquireROBuffer",
00114                                     "There\'s no surface here to lock!" );
00115         incReadLock();
00116 
00117         SDL_Surface * const surfaceImpPtr = rawSurface();
00118 
00119         // Do we have to do anything, or are we just book-keeping
00120         if (readLocks()>1) return surfaceImpPtr->pixels;
00121 
00122         // Do whatever we have to do to get access to the raw surface
00123         if (SDL_MUSTLOCK(surfaceImpPtr))
00124             if (-1==SDL_LockSurface(surfaceImpPtr))
00125                 throw cSDLException(    "cSurfaceCommonImp::aquireROBuffer",
00126                                         "Couldn\'t lock surface" );
00127 
00128         // That's it.
00129         return surfaceImpPtr->pixels;
00130     }
00131 
00132 
00133     /* ************************************************************ */
00134     void cSurfaceCommonImp::releaseROBuffer() const
00135     {
00136         if (0==readLocks())
00137             throw cException(   "cSurfaceCommonImp::releaseROBuffer",
00138                                 "Release of a non-existant lock" );
00139         if (empty())
00140             throw cBadDataUseException(
00141                                     "cSurfaceCommonImp::releaseROBuffer",
00142                                     "Surface implementation has gone away"  );
00143 
00144         // Do we do anything other than remove a reference count?
00145         if (readLocks()>1) {
00146             decReadLock();
00147             return;
00148         }
00149 
00150         // Undo anything we had to emulate to get a raw surface (assuming this
00151         // is the last lock, that is)
00152         SDL_Surface * surfaceImpPtr( rawSurface() );
00153         if (SDL_MUSTLOCK(surfaceImpPtr))
00154             SDL_UnlockSurface(surfaceImpPtr);
00155 
00156         // That's it, move on.
00157         decReadLock();
00158     }
00159 
00160 
00161     /* ************************************************************ */
00162     const bool cSurfaceCommonImp::supportsRWBuffer() const
00163     {
00164         // For now.
00165         return false;
00166     }
00167 
00168 
00169     /* ************************************************************ */
00170     void * const cSurfaceCommonImp::aquireRWBuffer()
00171     {
00172         // For now
00173         throw cUnsupportedMethodException(
00174                                 "cSurfaceCommonImp::aquireRWBuffer",
00175                                 "RW Buffers not supported" );
00176     }
00177 
00178 
00179     /* ************************************************************ */
00180     void cSurfaceCommonImp::releaseRWBuffer() const
00181     {
00182         // For now
00183         throw cUnsupportedMethodException(
00184                                 "cSurfaceCommonImp::releaseRWBuffer",
00185                                 "RW Buffers not supported" );
00186     }
00187 
00188 
00189 
00190     /* ************************************************************ */
00191     const bool cSurfaceCommonImp::surfaceIsSupported(
00192                                 const cPixelFormat & iFormat, // 
00193                                 const cSurfaceProperties &  ) const // iProperties
00194     {
00195         if (iFormat.bitsPerPixel()==8) return false;
00197         // Do an intensive test
00198         return true;
00199     }
00200 
00201 
00202     /* ************************************************************ */
00203     void cSurfaceCommonImp::free()
00204     {
00205         if (empty()) return;
00207         if (mOwned) SDL_FreeSurface(mSurface);
00208         mSurface = 0;
00209     }
00210 
00211 
00212     /* ************************************************************ */
00213     void cSurfaceCommonImp::setRawSurface(  SDL_Surface * const ioSurface,
00214                                             const tBool iTakeOwnership )
00215     {
00216         // Make sure that we have an empty surface reference
00217         free();
00218         // Do it.
00219         mOwned = iTakeOwnership;
00220         mSurface = ioSurface;
00221     }
00222 
00223 
00224     /* ************************************************************ */
00225     SDL_Surface * const cSurfaceCommonImp::rawSurface() const
00226     {
00227         return mSurface;
00228     }
00229 
00230 
00231     /* ************************************************************ */
00232     void cSurfaceCommonImp::setFormat( const cPixelFormat & iFormat )
00233     {
00234         mFormat.assign(iFormat);
00235     }
00236 
00237 
00238     /* ************************************************************ */
00239     void cSurfaceCommonImp::setProperties( const cSurfaceProperties & iProperties )
00240     {
00241         mProperties.assign(iProperties);
00242     }
00243 
00244 
00245     /* ************************************************************ */
00246     const cSurfaceCommonImp::tLockCount cSurfaceCommonImp::readLocks() const
00247     {
00248         return mReadLockCount;
00249     }
00250 
00251 
00252     /* ************************************************************ */
00253     const cSurfaceCommonImp::tLockCount cSurfaceCommonImp::writeLocks() const
00254     {
00255         return mWriteLockCount;
00256     }
00257 
00258 
00259     /* ************************************************************ */
00260     void cSurfaceCommonImp::incReadLock() const
00261     {
00262         ++mReadLockCount;
00263     }
00264 
00265 
00266     /* ************************************************************ */
00267     void cSurfaceCommonImp::incWriteLock() const
00268     {
00269         ++mWriteLockCount;
00270     }
00271 
00272 
00273     /* ************************************************************ */
00274     void cSurfaceCommonImp::decReadLock() const
00275     {
00276         --mReadLockCount;
00277     }
00278 
00279 
00280     /* ************************************************************ */
00281     void cSurfaceCommonImp::decWriteLock() const
00282     {
00283         --mWriteLockCount;
00284     }
00285 
00286 
00287     /* ************************************************************ */
00288     void cSurfaceCommonImp::clearSurface( const tUint32 iPixelColour )
00289     {
00290         if (empty())
00291             throw cBadDataUseException( "cSurfaceCommonImp::clearSurface",
00292                                         "The surface is empty" );
00293         SDL_FillRect( rawSurface(), 0, iPixelColour );
00294     }
00295 
00296 
00297     /* ************************************************************ */
00298     const tUint32 cSurfaceCommonImp::mapRGBA(   const tUbyte iR,
00299                                         const tUbyte iG,
00300                                         const tUbyte iB,
00301                                         const tUbyte iA ) const
00302     {
00303         if (empty())
00304             throw cBadDataUseException( "cSurfaceCommonImp::mapRGBA",
00305                                         "The surface is empty" );
00306         return SDL_MapRGBA( rawSurface()->format, iR,iG,iB,iA );
00307     }
00308 
00309 
00310     /* ************************************************************ */
00311     const tUint32 cSurfaceCommonImp::mapRGB(    const tUbyte iR,
00312                                     const tUbyte iG,
00313                                     const tUbyte iB ) const
00314     {
00315         if (empty())
00316             throw cBadDataUseException( "cSurfaceCommonImp::mapRGB",
00317                                         "The surface is empty" );
00318         return SDL_MapRGB( rawSurface()->format, iR,iG,iB );
00319     }
00320 
00321 
00322 
00323 
00324 } // namespace
©2012 Aaron Cameron