![[]](/images/special/trans.gif)
LibN2L-4 Library Code ReferenceClassesCompounds Files Members Method Index Full Reference cSurfaceCommonImp.cppGo 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 |