diff --git a/stepmania/src/BannerCache.cpp b/stepmania/src/BannerCache.cpp index 78105116b6..5bc22786ac 100644 --- a/stepmania/src/BannerCache.cpp +++ b/stepmania/src/BannerCache.cpp @@ -11,10 +11,11 @@ #include "SDL_utils.h" #include "SDL_dither.h" #include "SDL_rotozoom.h" -#include "SDL_utils.h" #include "RageDisplay.h" #include "RageTexture.h" #include "RageTextureManager.h" +#include "RageSurface.h" +#include "RageSurfaceUtils.h" #include "Banner.h" @@ -44,7 +45,7 @@ BannerCache *BANNERCACHE; -static map m_BannerPathToImage; +static map g_BannerPathToImage; CString BannerCache::GetBannerCachePath( CString BannerPath ) { @@ -63,11 +64,11 @@ void BannerCache::LoadBanner( CString BannerPath ) for( int tries = 0; tries < 2; ++tries ) { - if( m_BannerPathToImage.find(BannerPath) != m_BannerPathToImage.end() ) + if( g_BannerPathToImage.find(BannerPath) != g_BannerPathToImage.end() ) return; /* already loaded */ CHECKPOINT_M( ssprintf( "BannerCache::LoadBanner: %s", CachePath.c_str() ) ); - SDL_Surface *img = mySDL_LoadSurface( CachePath ); + RageSurface *img = RageSurfaceUtils::LoadSurface( CachePath ); if( img == NULL ) { if(tries == 0) @@ -87,17 +88,17 @@ void BannerCache::LoadBanner( CString BannerPath ) } } - m_BannerPathToImage[BannerPath] = img; + g_BannerPathToImage[BannerPath] = img; } } void BannerCache::OutputStats() const { - map::const_iterator ban; + map::const_iterator ban; int total_size = 0; - for( ban = m_BannerPathToImage.begin(); ban != m_BannerPathToImage.end(); ++ban ) + for( ban = g_BannerPathToImage.begin(); ban != g_BannerPathToImage.end(); ++ban ) { - SDL_Surface * const &img = ban->second; + RageSurface * const &img = ban->second; const int size = img->pitch * img->h; total_size += size; } @@ -106,11 +107,11 @@ void BannerCache::OutputStats() const void BannerCache::UnloadAllBanners() { - map::iterator it; - for( it = m_BannerPathToImage.begin(); it != m_BannerPathToImage.end(); ++it ) - SDL_FreeSurface(it->second); + map::iterator it; + for( it = g_BannerPathToImage.begin(); it != g_BannerPathToImage.end(); ++it ) + delete it->second; - m_BannerPathToImage.clear(); + g_BannerPathToImage.clear(); } BannerCache::BannerCache() @@ -127,11 +128,11 @@ struct BannerTexture: public RageTexture { unsigned m_uTexHandle; unsigned GetTexHandle() const { return m_uTexHandle; }; // accessed by RageDisplay - /* This is a reference to a pointer in m_BannerPathToImage. */ - SDL_Surface *&img; + /* This is a reference to a pointer in g_BannerPathToImage. */ + RageSurface *&img; int width, height; - BannerTexture( RageTextureID name, SDL_Surface *&img_, int width_, int height_ ): + BannerTexture( RageTextureID name, RageSurface *&img_, int width_, int height_ ): RageTexture(name), img(img_), width(width_), height(height_) { Create(); @@ -159,7 +160,7 @@ struct BannerTexture: public RageTexture img->h > DISPLAY->GetMaxTextureSize() ) { LOG->Warn("Converted %s at runtime", GetID().filename.c_str() ); - ConvertSDLSurface(img, img->w, img->h, 32, 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000); + RageSurfaceUtils::ConvertSurface(img, img->w, img->h, 32, 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000); zoomSurface(img, min( img->w, DISPLAY->GetMaxTextureSize() ), min( img->h, DISPLAY->GetMaxTextureSize() )); } @@ -218,7 +219,7 @@ RageTextureID BannerCache::LoadCachedBanner( CString BannerPath ) ID = Sprite::SongBannerTexture(ID); /* It's not in a texture. Do we have it loaded? */ - if( m_BannerPathToImage.find(BannerPath) == m_BannerPathToImage.end() ) + if( g_BannerPathToImage.find(BannerPath) == g_BannerPathToImage.end() ) { /* Oops, the image is missing. Warn and continue. */ LOG->Warn( "Banner cache for '%s' wasn't loaded", BannerPath.c_str() ); @@ -228,7 +229,7 @@ RageTextureID BannerCache::LoadCachedBanner( CString BannerPath ) /* This is a reference to a pointer. BannerTexture's ctor may change it * when converting; this way, the conversion will end up in the map so we * only have to convert once. */ - SDL_Surface *&img = m_BannerPathToImage[BannerPath]; + RageSurface *&img = g_BannerPathToImage[BannerPath]; ASSERT( img ); int src_width = 0, src_height = 0; @@ -300,7 +301,7 @@ void BannerCache::CacheBanner( CString BannerPath ) void BannerCache::CacheBannerInternal( CString BannerPath ) { - SDL_Surface *img = RageSurface::LoadFile( BannerPath ); + RageSurface *img = RageSurfaceUtils::LoadFile( BannerPath ); if( img == NULL ) { LOG->Warn( "BannerCache::CacheBanner: Couldn't load %s: %s", BannerPath.c_str(), SDL_GetError() ); @@ -322,18 +323,18 @@ void BannerCache::CacheBannerInternal( CString BannerPath ) * This also makes the banner take less memory, though that could also be * done by RLEing the surface. */ - ApplyHotPinkColorKey( img ); + RageSurfaceUtils::ApplyHotPinkColorKey( img ); - ConvertSDLSurface(img, img->w, img->h, 32, 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000); + RageSurfaceUtils::ConvertSurface(img, img->w, img->h, 32, 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000); - SDL_Surface *dst = SDL_CreateRGBSurface( - SDL_SWSURFACE, 256, 64, img->format->BitsPerPixel, + RageSurface *dst = CreateSurface( + 256, 64, img->format->BitsPerPixel, img->format->Rmask, img->format->Gmask, img->format->Bmask, img->format->Amask ); if( img->format->BitsPerPixel == 8 ) { ASSERT( img->format->palette ); - mySDL_SetPalette(dst, img->format->palette->colors, 0, 256); + dst->fmt.palette = img->fmt.palette; } const float fCustomImageCoords[8] = { @@ -343,10 +344,10 @@ void BannerCache::CacheBannerInternal( CString BannerPath ) 0.78f, 0.02f, // top right }; - mySDL_BlitTransform( img, dst, fCustomImageCoords ); + RageSurfaceUtils::BlitTransform( img, dst, fCustomImageCoords ); // SDL_SaveBMP( dst, BannerPath + "-test.bmp" ); - SDL_FreeSurface( img ); + delete img; img = dst; WasRotatedBanner = true; @@ -368,42 +369,42 @@ void BannerCache::CacheBannerInternal( CString BannerPath ) width = max( width, min(32, power_of_two(src_width)) ); height = max( height, min(32, power_of_two(src_height)) ); - ApplyHotPinkColorKey( img ); + RageSurfaceUtils::ApplyHotPinkColorKey( img ); { - ConvertSDLSurface(img, img->w, img->h, 32, 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000); + RageSurfaceUtils::ConvertSurface(img, img->w, img->h, 32, 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000); zoomSurface(img, width, height); /* Dither to the final format. We use A1RGB5, since that's usually supported * natively by both OpenGL and D3D. */ - SDL_Surface *dst = SDL_CreateRGBSurfaceSane(SDL_SWSURFACE, img->w, img->h, - 16, 0x7C00, 0x03E0, 0x001F, 0x8000 ); + RageSurface *dst = CreateSurface( img->w, img->h, 16, + 0x7C00, 0x03E0, 0x001F, 0x8000 ); /* SM_SDL_OrderedDither is still faster than SM_SDL_ErrorDiffusionDither, and * these images are very small and only displayed briefly. */ SM_SDL_OrderedDither(img, dst); - SDL_FreeSurface( img ); + delete img; img = dst; } const CString CachePath = GetBannerCachePath(BannerPath); - mySDL_SaveSurface( img, CachePath ); + RageSurfaceUtils::SaveSurface( img, CachePath ); if( PREFSMAN->m_BannerCache == PrefsManager::BNCACHE_LOW_RES ) { /* If an old image is loaded, free it. */ - if( m_BannerPathToImage.find(BannerPath) != m_BannerPathToImage.end() ) + if( g_BannerPathToImage.find(BannerPath) != g_BannerPathToImage.end() ) { - SDL_Surface *oldimg = m_BannerPathToImage[BannerPath]; - SDL_FreeSurface( oldimg ); - m_BannerPathToImage.erase(BannerPath); + RageSurface *oldimg = g_BannerPathToImage[BannerPath]; + delete oldimg; + g_BannerPathToImage.erase(BannerPath); } /* Keep it; we're just going to load it anyway. */ - m_BannerPathToImage[BannerPath] = img; + g_BannerPathToImage[BannerPath] = img; } else - SDL_FreeSurface(img); + delete img; /* Remember the original size. */ BannerData.SetValue( BannerPath, "Path", CachePath ); diff --git a/stepmania/src/RageBitmapTexture.cpp b/stepmania/src/RageBitmapTexture.cpp index 557e9466c7..4363faf283 100644 --- a/stepmania/src/RageBitmapTexture.cpp +++ b/stepmania/src/RageBitmapTexture.cpp @@ -8,6 +8,8 @@ #include "RageTypes.h" #include "arch/Dialog/Dialog.h" #include "PrefsManager.h" +#include "RageSurface.h" +#include "RageSurfaceUtils.h" #include "SDL.h" #include "SDL_rotozoom.h" @@ -67,26 +69,26 @@ void RageBitmapTexture::Create() /* Create (and return) a surface ready to be loaded to OpenGL */ /* Load the image into an SDL surface. */ - SDL_Surface *img = RageSurfaceUtils::LoadFile( actualID.filename ); + RageSurface *img = RageSurfaceUtils::LoadFile( actualID.filename ); /* Tolerate corrupt/unknown images. */ if( img == NULL ) { LOG->Warn( "RageBitmapTexture: Couldn't load %s: %s", actualID.filename.c_str(), SDL_GetError() ); - img = mySDL_MakeDummySurface( 64, 64 ); + img = RageSurfaceUtils::MakeDummySurface( 64, 64 ); ASSERT( img != NULL ); } - if(actualID.bHotPinkColorKey) - ApplyHotPinkColorKey( img ); + if( actualID.bHotPinkColorKey ) + RageSurfaceUtils::ApplyHotPinkColorKey( img ); { /* Do this after setting the color key for paletted images; it'll also return * TRAIT_NO_TRANSPARENCY if the color key is never used. */ - int traits = FindSurfaceTraits(img); - if(traits & TRAIT_NO_TRANSPARENCY) + int traits = RageSurfaceUtils::FindSurfaceTraits(img); + if( traits & RageSurfaceUtils::TRAIT_NO_TRANSPARENCY ) actualID.iAlphaBits = 0; - else if(traits & TRAIT_BOOL_TRANSPARENCY) + else if( traits & RageSurfaceUtils::TRAIT_BOOL_TRANSPARENCY ) actualID.iAlphaBits = 1; } @@ -155,7 +157,7 @@ void RageBitmapTexture::Create() if( img->w != m_iImageWidth || img->h != m_iImageHeight ) { /* resize currently only does RGBA8888 */ - ConvertSDLSurface(img, img->w, img->h, 32, 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000); + RageSurfaceUtils::ConvertSurface(img, img->w, img->h, 32, 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000); zoomSurface(img, m_iImageWidth, m_iImageHeight ); } @@ -164,9 +166,9 @@ void RageBitmapTexture::Create() if( actualID.iGrayscaleBits != -1 && DISPLAY->SupportsTextureFormat(RageDisplay::FMT_PAL) ) { - SDL_Surface *dst = mySDL_Palettize( img, actualID.iGrayscaleBits, actualID.iAlphaBits ); + RageSurface *dst = RageSurfaceUtils::Palettize( img, actualID.iGrayscaleBits, actualID.iAlphaBits ); - SDL_FreeSurface(img); + delete img; img = dst; } @@ -218,11 +220,11 @@ void RageBitmapTexture::Create() { /* Dither down to the destination format. */ const RageDisplay::PixelFormatDesc *pfd = DISPLAY->GetPixelFormatDesc(pixfmt); - SDL_Surface *dst = SDL_CreateRGBSurfaceSane(SDL_SWSURFACE, img->w, img->h, - pfd->bpp, pfd->masks[0], pfd->masks[1], pfd->masks[2], pfd->masks[3]); + RageSurface *dst = CreateSurface( img->w, img->h, pfd->bpp, + pfd->masks[0], pfd->masks[1], pfd->masks[2], pfd->masks[3] ); SM_SDL_ErrorDiffusionDither(img, dst); - SDL_FreeSurface(img); + delete img; img = dst; } } @@ -230,7 +232,7 @@ void RageBitmapTexture::Create() /* This needs to be done *after* the final resize, since that resize * may introduce new alpha bits that need to be set. It needs to be * done *before* we set up the palette, since it might change it. */ - FixHiddenAlpha(img); + RageSurfaceUtils::FixHiddenAlpha(img); /* Make we're using a supported format. * Every card supports either RGBA8 or RGBA4. */ @@ -245,8 +247,8 @@ void RageBitmapTexture::Create() /* Convert the data to the destination format and dimensions * required by OpenGL if it's not in it already. */ const RageDisplay::PixelFormatDesc *pfd = DISPLAY->GetPixelFormatDesc(pixfmt); - ConvertSDLSurface(img, m_iTextureWidth, m_iTextureHeight, - pfd->bpp, pfd->masks[0], pfd->masks[1], pfd->masks[2], pfd->masks[3]); + RageSurfaceUtils::ConvertSurface( img, m_iTextureWidth, m_iTextureHeight, + pfd->bpp, pfd->masks[0], pfd->masks[1], pfd->masks[2], pfd->masks[3] ); m_uTexHandle = DISPLAY->CreateTexture( pixfmt, img, actualID.bMipMaps ); @@ -293,7 +295,7 @@ void RageBitmapTexture::Create() - SDL_FreeSurface( img ); + delete img; /* See if the apparent "size" is being overridden. */ GetResolutionFromFileName(actualID.filename, m_iSourceWidth, m_iSourceHeight); diff --git a/stepmania/src/RageDisplay.cpp b/stepmania/src/RageDisplay.cpp index a2ab87862f..16c01567e7 100644 --- a/stepmania/src/RageDisplay.cpp +++ b/stepmania/src/RageDisplay.cpp @@ -9,6 +9,7 @@ #include "RageFile.h" #include "SDL_SaveJPEG.h" #include "SDL_rotozoom.h" +#include "RageSurface.h" // // Statistics stuff @@ -572,14 +573,15 @@ RageMatrix RageDisplay::GetPerspectiveMatrix(float fovy, float aspect, float zNe return GetFrustumMatrix(xmin, xmax, ymin, ymax, zNear, zFar); } -SDL_Surface *RageDisplay::CreateSurfaceFromPixfmt( PixelFormat pixfmt, +RageSurface *RageDisplay::CreateSurfaceFromPixfmt( PixelFormat pixfmt, void *pixels, int width, int height, int pitch ) { const PixelFormatDesc *tpf = GetPixelFormatDesc(pixfmt); - SDL_Surface *surf = SDL_CreateRGBSurfaceFrom( - pixels, width, height, tpf->bpp, pitch, - tpf->masks[0], tpf->masks[1], tpf->masks[2], tpf->masks[3]); + RageSurface *surf = CreateSurfaceFrom( + width, height, tpf->bpp, + tpf->masks[0], tpf->masks[1], tpf->masks[2], tpf->masks[3], + (uint8_t *) pixels, pitch ); return surf; } @@ -629,7 +631,7 @@ void RageDisplay::ChangeCentering( int trans_x, int trans_y, float scale_x, floa bool RageDisplay::SaveScreenshot( CString sPath, GraphicsFileFormat format ) { - SDL_Surface* surface = this->CreateScreenshot(); + RageSurface* surface = this->CreateScreenshot(); CString buf; buf.reserve( 1024*1024 ); @@ -646,8 +648,12 @@ bool RageDisplay::SaveScreenshot( CString sPath, GraphicsFileFormat format ) switch( format ) { case SAVE_LOSSLESS: - SDL_SaveBMP_RW( surface, &rw, false ); + { + SDL_Surface *pSDLSurf = SDLSurfaceFromRageSurface( surface ); + SDL_SaveBMP_RW( pSDLSurf, &rw, false ); + delete pSDLSurf; break; + } case SAVE_LOSSY_LOW_QUAL: IMG_SaveJPG_RW( surface, &rw, false ); case SAVE_LOSSY_HIGH_QUAL: @@ -660,7 +666,7 @@ bool RageDisplay::SaveScreenshot( CString sPath, GraphicsFileFormat format ) SDL_RWclose( &rw ); - SDL_FreeSurface( surface ); + delete surface; surface = NULL; RageFile out; diff --git a/stepmania/src/RageDisplay.h b/stepmania/src/RageDisplay.h index be16d5d05e..fb15e84c7e 100644 --- a/stepmania/src/RageDisplay.h +++ b/stepmania/src/RageDisplay.h @@ -10,7 +10,7 @@ #include "ModelTypes.h" const int REFRESH_DEFAULT = 0; -struct SDL_Surface; +struct RageSurface; const int MAX_TEXTURE_UNITS = 2; // RageCompiledGeometry holds vertex data in a format that is most efficient @@ -172,12 +172,12 @@ public: * (unsigned in OpenGL, texture pointer in D3D) */ virtual unsigned CreateTexture( PixelFormat pixfmt, // format of img and of texture in video mem - SDL_Surface* img, // must be in pixfmt + RageSurface* img, // must be in pixfmt bool bGenerateMipMaps ) = 0; virtual void UpdateTexture( unsigned uTexHandle, - SDL_Surface* img, + RageSurface* img, int xoffset, int yoffset, int width, int height ) = 0; virtual void DeleteTexture( unsigned uTexHandle ) = 0; @@ -257,7 +257,7 @@ protected: // bNewDeviceOut is set true if a new device was created and textures // need to be reloaded. virtual CString TryVideoMode( VideoModeParams params, bool &bNewDeviceOut ) = 0; - virtual SDL_Surface* CreateScreenshot() = 0; // allocates a surface. Caller must SDL_FreeSurface it. + virtual RageSurface* CreateScreenshot() = 0; // allocates a surface. Caller must SDL_FreeSurface it. virtual void SetViewport(int shift_left, int shift_down) = 0; @@ -299,7 +299,7 @@ public: /* Centering matrix */ void ChangeCentering( int trans_x, int trans_y, float scale_x, float scale_y ); - SDL_Surface *CreateSurfaceFromPixfmt( PixelFormat pixfmt, void *pixels, int width, int height, int pitch ); + RageSurface *CreateSurfaceFromPixfmt( PixelFormat pixfmt, void *pixels, int width, int height, int pitch ); PixelFormat FindPixelFormat( int bpp, int Rmask, int Gmask, int Bmask, int Amask, bool realtime=false ); protected: diff --git a/stepmania/src/RageDisplay_D3D.cpp b/stepmania/src/RageDisplay_D3D.cpp index 6af49f3744..a60d9385e2 100644 --- a/stepmania/src/RageDisplay_D3D.cpp +++ b/stepmania/src/RageDisplay_D3D.cpp @@ -15,10 +15,12 @@ #include "StepMania.h" #include "RageUtil.h" #include "D3dx8math.h" -#include "SDL_video.h" // for SDL_Surface +#include "SDL_video.h" // for RageSurface #include "SDL_utils.h" #include "D3DX8Core.h" #include "PrefsManager.h" +#include "RageSurface.h" +#include "RageSurfaceUtils.h" #include "arch/arch.h" @@ -654,7 +656,7 @@ bool RageDisplay_D3D::SupportsTextureFormat( PixelFormat pixfmt, bool realtime ) return SUCCEEDED( hr ); } -SDL_Surface* RageDisplay_D3D::CreateScreenshot() +RageSurface* RageDisplay_D3D::CreateScreenshot() { #ifndef _XBOX /* Get the back buffer. */ @@ -687,17 +689,17 @@ SDL_Surface* RageDisplay_D3D::CreateScreenshot() pCopy->LockRect( &lr, &rect, D3DLOCK_READONLY ); } - SDL_Surface *surface = CreateSurfaceFromPixfmt( FMT_RGBA8, lr.pBits, desc.Width, desc.Height, lr.Pitch); + RageSurface *surface = CreateSurfaceFromPixfmt( FMT_RGBA8, lr.pBits, desc.Width, desc.Height, lr.Pitch); ASSERT( surface ); /* We need to make a copy, since lr.pBits will go away when we call UnlockRect(). */ - SDL_Surface *SurfaceCopy = - SDL_CreateRGBSurfaceSane( SDL_SWSURFACE, surface->w, surface->h, + RageSurface *SurfaceCopy = + CreateSurface( surface->w, surface->h, surface->format->BitsPerPixel, surface->format->Rmask, surface->format->Gmask, surface->format->Bmask, surface->format->Amask ); - CopySDLSurface( surface, SurfaceCopy ); - SDL_FreeSurface( surface ); + RageSurfaceUtils::CopySurface( surface, SurfaceCopy ); + delete surface; pCopy->UnlockRect(); pCopy->Release(); @@ -1164,7 +1166,7 @@ void RageDisplay_D3D::DeleteTexture( unsigned uTexHandle ) unsigned RageDisplay_D3D::CreateTexture( PixelFormat pixfmt, - SDL_Surface* img, + RageSurface* img, bool bGenerateMipMaps ) { // texture must be power of two @@ -1188,11 +1190,11 @@ unsigned RageDisplay_D3D::CreateTexture( memset( pal.p, 0, sizeof(pal.p) ); for( int i=0; iformat->palette->ncolors; i++ ) { - SDL_Color c = img->format->palette->colors[i]; + RageSurfaceColor &c = img->format->palette->colors[i]; pal.p[i].peRed = c.r; pal.p[i].peGreen = c.g; pal.p[i].peBlue = c.b; - pal.p[i].peFlags = c.unused; + pal.p[i].peFlags = c.a; } ASSERT( g_TexResourceToTexturePalette.find(uTexHandle) == g_TexResourceToTexturePalette.end() ); @@ -1206,7 +1208,7 @@ unsigned RageDisplay_D3D::CreateTexture( void RageDisplay_D3D::UpdateTexture( unsigned uTexHandle, - SDL_Surface* img, + RageSurface* img, int xoffset, int yoffset, int width, int height ) { IDirect3DTexture8* pTex = (IDirect3DTexture8*)uTexHandle; @@ -1251,18 +1253,15 @@ void RageDisplay_D3D::UpdateTexture( if(D3DFORMATS[texpixfmt] == desc.Format) break; ASSERT( texpixfmt != NUM_PIX_FORMATS ); - SDL_Surface *Texture = CreateSurfaceFromPixfmt(PixelFormat(texpixfmt), lr.pBits, width, height, lr.Pitch); + RageSurface *Texture = CreateSurfaceFromPixfmt(PixelFormat(texpixfmt), lr.pBits, width, height, lr.Pitch); ASSERT( Texture ); SDL_Rect area; area.x = area.y = 0; area.w = (uint16_t) width; area.h = (uint16_t) height; - SDL_SetAlpha( img, 0, SDL_ALPHA_OPAQUE ); -// SDL_SetColorKey( img, 0, 0 ); -// SDL_BlitSurface( img, &area, Texture, &area ); - mySDL_BlitSurface( img, Texture, width, height, false ); + RageSurfaceUtils::Blit( img, Texture, width, height, false ); - SDL_FreeSurface( Texture ); + delete Texture; #endif pTex->UnlockRect( 0 ); diff --git a/stepmania/src/RageDisplay_D3D.h b/stepmania/src/RageDisplay_D3D.h index 4cd75f3656..21916b8d2d 100644 --- a/stepmania/src/RageDisplay_D3D.h +++ b/stepmania/src/RageDisplay_D3D.h @@ -33,11 +33,11 @@ public: bool SupportsTextureFormat( PixelFormat pixfmt, bool realtime=false ); unsigned CreateTexture( PixelFormat pixfmt, - SDL_Surface* img, + RageSurface* img, bool bGenerateMipMaps ); void UpdateTexture( unsigned uTexHandle, - SDL_Surface* img, + RageSurface* img, int xoffset, int yoffset, int width, int height ); void DeleteTexture( unsigned uTexHandle ); @@ -86,7 +86,7 @@ protected: void DrawCompiledGeometryInternal( const RageCompiledGeometry *p, int iMeshIndex ); CString TryVideoMode( VideoModeParams params, bool &bNewDeviceOut ); - SDL_Surface* CreateScreenshot(); + RageSurface* CreateScreenshot(); void SetViewport(int shift_left, int shift_down); RageMatrix GetOrthoMatrix( float l, float r, float b, float t, float zn, float zf ); }; diff --git a/stepmania/src/RageDisplay_Null.cpp b/stepmania/src/RageDisplay_Null.cpp index 0f38e0f452..66eebb34bf 100644 --- a/stepmania/src/RageDisplay_Null.cpp +++ b/stepmania/src/RageDisplay_Null.cpp @@ -13,6 +13,7 @@ #include "RageTypes.h" #include "StepMania.h" #include "RageUtil.h" +#include "RageSurface.h" static RageDisplay::PixelFormatDesc PIXEL_FORMAT_DESC[RageDisplay::NUM_PIX_FORMATS] = { { @@ -78,12 +79,12 @@ RageDisplay_Null::RageDisplay_Null( VideoModeParams p ) SetVideoMode( p ); } -SDL_Surface* RageDisplay_Null::CreateScreenshot() +RageSurface* RageDisplay_Null::CreateScreenshot() { const PixelFormatDesc &desc = PIXEL_FORMAT_DESC[FMT_RGB8]; - SDL_Surface *image = SDL_CreateRGBSurfaceSane( - SDL_SWSURFACE, 640, 480, - desc.bpp, desc.masks[0], desc.masks[1], desc.masks[2], desc.masks[3] ); + RageSurface *image = CreateSurface( + 640, 480, desc.bpp, + desc.masks[0], desc.masks[1], desc.masks[2], desc.masks[3] ); memset( image->pixels, 0, 480*image->pitch ); diff --git a/stepmania/src/RageDisplay_Null.h b/stepmania/src/RageDisplay_Null.h index 443684af99..a5470c8d0c 100644 --- a/stepmania/src/RageDisplay_Null.h +++ b/stepmania/src/RageDisplay_Null.h @@ -1,6 +1,4 @@ -/* - * RageDisplay_Null: diagnostic display device - */ +/* RageDisplay_Null: diagnostic display device */ #ifndef RAGEDISPLAY_NULL_H #define RAGEDISPLAY_NULL_H @@ -21,11 +19,11 @@ public: bool SupportsTextureFormat( PixelFormat pixfmt, bool realtime=false ) { return true; } unsigned CreateTexture( PixelFormat pixfmt, - SDL_Surface* img, + RageSurface* img, bool bGenerateMipMaps ) { return 1; } void UpdateTexture( unsigned uTexHandle, - SDL_Surface* img, + RageSurface* img, int xoffset, int yoffset, int width, int height ) { } void DeleteTexture( unsigned uTexHandle ) { } @@ -76,7 +74,7 @@ protected: VideoModeParams m_Params; CString TryVideoMode( VideoModeParams params, bool &bNewDeviceOut ) { m_Params = params; return ""; } - SDL_Surface* CreateScreenshot(); + RageSurface* CreateScreenshot(); void SetViewport(int shift_left, int shift_down) { } RageMatrix GetOrthoMatrix( float l, float r, float b, float t, float zn, float zf ); bool SupportsSurfaceFormat( PixelFormat pixfmt ) { return true; } diff --git a/stepmania/src/RageDisplay_OGL.cpp b/stepmania/src/RageDisplay_OGL.cpp index efea9c4374..a9da1d3b71 100644 --- a/stepmania/src/RageDisplay_OGL.cpp +++ b/stepmania/src/RageDisplay_OGL.cpp @@ -16,6 +16,8 @@ #include "glext.h" #include "RageFile.h" +#include "RageSurface.h" +#include "RageSurfaceUtils.h" #include "PrefsManager.h" // XXX /* Windows's broken gl.h defines GL_EXT_paletted_texture incompletely: */ @@ -831,15 +833,14 @@ void RageDisplay_OGL::EndFrame() ProcessStatsOnFlip(); } -SDL_Surface* RageDisplay_OGL::CreateScreenshot() +RageSurface* RageDisplay_OGL::CreateScreenshot() { int width = wind->GetVideoModeParams().width; int height = wind->GetVideoModeParams().height; const PixelFormatDesc &desc = PIXEL_FORMAT_DESC[FMT_RGBA8]; - SDL_Surface *image = SDL_CreateRGBSurfaceSane( - SDL_SWSURFACE, width, height, - desc.bpp, desc.masks[0], desc.masks[1], desc.masks[2], 0 ); + RageSurface *image = CreateSurface( width, height, desc.bpp, + desc.masks[0], desc.masks[1], desc.masks[2], 0 ); glReadPixels(0, 0, wind->GetVideoModeParams().width, wind->GetVideoModeParams().height, GL_RGBA, GL_UNSIGNED_BYTE, image->pixels); @@ -1612,7 +1613,7 @@ void RageDisplay_OGL::DeleteTexture( unsigned uTexHandle ) } -RageDisplay::PixelFormat RageDisplay_OGL::GetImgPixelFormat( SDL_Surface* &img, bool &FreeImg, int width, int height ) +RageDisplay::PixelFormat RageDisplay_OGL::GetImgPixelFormat( RageSurface* &img, bool &FreeImg, int width, int height ) { PixelFormat pixfmt = FindPixelFormat( img->format->BitsPerPixel, img->format->Rmask, img->format->Gmask, img->format->Bmask, img->format->Amask ); @@ -1627,16 +1628,9 @@ RageDisplay::PixelFormat RageDisplay_OGL::GetImgPixelFormat( SDL_Surface* &img, const PixelFormatDesc *pfd = DISPLAY->GetPixelFormatDesc(pixfmt); - SDL_SetAlpha( img, 0, SDL_ALPHA_OPAQUE ); - - SDL_Rect area; - area.x = area.y = 0; - area.w = short(width); - area.h = short(height); - - SDL_Surface *imgconv = SDL_CreateRGBSurfaceSane(SDL_SWSURFACE, width, height, - pfd->bpp, pfd->masks[0], pfd->masks[1], pfd->masks[2], pfd->masks[3]); - SDL_BlitSurface(img, &area, imgconv, &area); + RageSurface *imgconv = CreateSurface( width, height, + pfd->bpp, pfd->masks[0], pfd->masks[1], pfd->masks[2], pfd->masks[3] ); + RageSurfaceUtils::Blit( img, imgconv, width, height, false ); img = imgconv; FreeImg = true; } @@ -1648,7 +1642,7 @@ RageDisplay::PixelFormat RageDisplay_OGL::GetImgPixelFormat( SDL_Surface* &img, unsigned RageDisplay_OGL::CreateTexture( PixelFormat pixfmt, - SDL_Surface* img, + RageSurface* img, bool bGenerateMipMaps ) { ASSERT( pixfmt < NUM_PIX_FORMATS ); @@ -1731,7 +1725,7 @@ unsigned RageDisplay_OGL::CreateTexture( palette[p++] = img->format->palette->colors[i].r; palette[p++] = img->format->palette->colors[i].g; palette[p++] = img->format->palette->colors[i].b; - palette[p++] = img->format->palette->colors[i].unused; + palette[p++] = img->format->palette->colors[i].a; } /* Set the palette. */ @@ -1803,14 +1797,14 @@ unsigned RageDisplay_OGL::CreateTexture( glFlush(); if( FreeImg ) - SDL_FreeSurface( img ); + delete img; return uTexHandle; } void RageDisplay_OGL::UpdateTexture( unsigned uTexHandle, - SDL_Surface* img, + RageSurface* img, int xoffset, int yoffset, int width, int height ) { glBindTexture( GL_TEXTURE_2D, uTexHandle ); @@ -1834,7 +1828,7 @@ void RageDisplay_OGL::UpdateTexture( glFlush(); if( FreeImg ) - SDL_FreeSurface( img ); + delete img; } CString RageDisplay_OGL::GetTextureDiagnostics( unsigned id ) const diff --git a/stepmania/src/RageDisplay_OGL.h b/stepmania/src/RageDisplay_OGL.h index c42977a84c..a1783889e4 100644 --- a/stepmania/src/RageDisplay_OGL.h +++ b/stepmania/src/RageDisplay_OGL.h @@ -1,6 +1,4 @@ -/* - * RageDisplay_OGL: OpenGL display implementation - */ +/* RageDisplay_OGL: OpenGL display implementation */ #ifndef RAGEDISPLAY_OGL_H #define RAGEDISPLAY_OGL_H @@ -23,11 +21,11 @@ public: bool SupportsTextureFormat( PixelFormat pixfmt, bool realtime=false ); unsigned CreateTexture( PixelFormat pixfmt, - SDL_Surface* img, + RageSurface* img, bool bGenerateMipMaps ); void UpdateTexture( unsigned uTexHandle, - SDL_Surface* img, + RageSurface* img, int xoffset, int yoffset, int width, int height ); void DeleteTexture( unsigned uTexHandle ); @@ -79,10 +77,10 @@ protected: void DrawLineStripInternal( const RageSpriteVertex v[], int iNumVerts, float LineWidth ); CString TryVideoMode( VideoModeParams params, bool &bNewDeviceOut ); - SDL_Surface* CreateScreenshot(); + RageSurface* CreateScreenshot(); void SetViewport(int shift_left, int shift_down); RageMatrix GetOrthoMatrix( float l, float r, float b, float t, float zn, float zf ); - PixelFormat GetImgPixelFormat( SDL_Surface* &img, bool &FreeImg, int width, int height ); + PixelFormat GetImgPixelFormat( RageSurface* &img, bool &FreeImg, int width, int height ); bool SupportsSurfaceFormat( PixelFormat pixfmt ); void SendCurrentMatrices(); }; diff --git a/stepmania/src/RageSoundReader_WAV.cpp b/stepmania/src/RageSoundReader_WAV.cpp index 32d65859eb..810e6b5d6a 100644 --- a/stepmania/src/RageSoundReader_WAV.cpp +++ b/stepmania/src/RageSoundReader_WAV.cpp @@ -42,7 +42,6 @@ uint32_t RageSoundReader_WAV::ConvertBytePosToMs(int BytesPerSample, int channel return (uint32_t) ((frame_no / frames_per_ms) + 0.5f); } -/* Better than SDL_ReadLE16, since you can detect i/o errors... */ bool RageSoundReader_WAV::read_le16( RageFile &f, int16_t *si16 ) const { const int ret = f.Read( si16, sizeof(int16_t) ); @@ -68,7 +67,6 @@ bool RageSoundReader_WAV::read_le16( RageFile &f, uint16_t *ui16 ) const } -/* Better than SDL_ReadLE32, since you can detect i/o errors... */ bool RageSoundReader_WAV::read_le32( RageFile &f, int32_t *si32 ) const { const int ret = f.Read( si32, sizeof(int32_t) ); diff --git a/stepmania/src/RageSurfaceUtils.h b/stepmania/src/RageSurfaceUtils.h index 58b3cfe8d0..904c7d68e7 100644 --- a/stepmania/src/RageSurfaceUtils.h +++ b/stepmania/src/RageSurfaceUtils.h @@ -1,3 +1,5 @@ +/* Utility functions for RageSurfaces. */ + #ifndef RAGE_SURFACE_UTILS_H #define RAGE_SURFACE_UTILS_H diff --git a/stepmania/src/RageSurface_Load.cpp b/stepmania/src/RageSurface_Load.cpp index e5ddef293b..1fad08b182 100644 --- a/stepmania/src/RageSurface_Load.cpp +++ b/stepmania/src/RageSurface_Load.cpp @@ -9,7 +9,7 @@ #include "SDL_utils.h" #include -static RageSurfaceUtils::OpenResult RageSurface_Load_BMP( const CString &sPath, SDL_Surface *&ret, bool bHeaderOnly, CString &error ) +static RageSurfaceUtils::OpenResult RageSurface_Load_BMP( const CString &sPath, RageSurface *&ret, bool bHeaderOnly, CString &error ) { RageFile f; if( !f.Open(sPath) ) @@ -20,23 +20,24 @@ static RageSurfaceUtils::OpenResult RageSurface_Load_BMP( const CString &sPath, SDL_RWops rw; OpenRWops( &rw, &f ); - ret = SDL_LoadBMP_RW( &rw, false ); + SDL_Surface *pSDLSurface = SDL_LoadBMP_RW( &rw, false ); SDL_RWclose( &rw ); - if( ret == NULL ) + if( pSDLSurface == NULL ) { error = SDL_GetError(); return RageSurfaceUtils::OPEN_UNKNOWN_FILE_FORMAT; } - mySDL_FixupPalettedAlpha( ret ); + ret = RageSurfaceFromSDLSurface( pSDLSurface ); + return RageSurfaceUtils::OPEN_OK; } -static SDL_Surface *TryOpenFile( CString sPath, bool bHeaderOnly, CString &error, CString format, bool &bKeepTrying ) +static RageSurface *TryOpenFile( CString sPath, bool bHeaderOnly, CString &error, CString format, bool &bKeepTrying ) { - SDL_Surface *ret = NULL; + RageSurface *ret = NULL; RageSurfaceUtils::OpenResult result; if( !format.CompareNoCase("png") ) result = RageSurface_Load_PNG( sPath, ret, bHeaderOnly, error ); @@ -96,7 +97,7 @@ static SDL_Surface *TryOpenFile( CString sPath, bool bHeaderOnly, CString &error return NULL; } -SDL_Surface *RageSurfaceUtils::LoadFile( const CString &sPath, bool bHeaderOnly ) +RageSurface *RageSurfaceUtils::LoadFile( const CString &sPath, bool bHeaderOnly ) { { RageFile TestOpen; @@ -123,7 +124,7 @@ SDL_Surface *RageSurfaceUtils::LoadFile( const CString &sPath, bool bHeaderOnly /* If the extension matches a format, try that first. */ if( FileTypes.find(format) != FileTypes.end() ) { - SDL_Surface *ret = TryOpenFile( sPath, bHeaderOnly, error, format, bKeepTrying ); + RageSurface *ret = TryOpenFile( sPath, bHeaderOnly, error, format, bKeepTrying ); if( ret ) return ret; FileTypes.erase( format ); @@ -131,7 +132,7 @@ SDL_Surface *RageSurfaceUtils::LoadFile( const CString &sPath, bool bHeaderOnly for( set::iterator it = FileTypes.begin(); bKeepTrying && it != FileTypes.end(); ++it ) { - SDL_Surface *ret = TryOpenFile( sPath, bHeaderOnly, error, *it, bKeepTrying ); + RageSurface *ret = TryOpenFile( sPath, bHeaderOnly, error, *it, bKeepTrying ); if( ret ) { LOG->Warn("File \"%s\" is really %s", sPath.c_str(), it->c_str()); diff --git a/stepmania/src/RageSurface_Load.h b/stepmania/src/RageSurface_Load.h index 38e0c95b8f..1867a9b412 100644 --- a/stepmania/src/RageSurface_Load.h +++ b/stepmania/src/RageSurface_Load.h @@ -1,7 +1,7 @@ #ifndef RAGE_SURFACE_LOAD_H #define RAGE_SURFACE_LOAD_H -struct SDL_Surface; +struct RageSurface; namespace RageSurfaceUtils { enum OpenResult @@ -13,7 +13,7 @@ namespace RageSurfaceUtils /* If bHeaderOnly is true, the loader is only required to return a surface * with the width and height set (but may return a complete surface). */ - SDL_Surface *LoadFile( const CString &sPath, bool bHeaderOnly=false ); + RageSurface *LoadFile( const CString &sPath, bool bHeaderOnly=false ); } #endif diff --git a/stepmania/src/RageSurface_Load_GIF.cpp b/stepmania/src/RageSurface_Load_GIF.cpp index 43a2b99db4..d941e9804c 100644 --- a/stepmania/src/RageSurface_Load_GIF.cpp +++ b/stepmania/src/RageSurface_Load_GIF.cpp @@ -4,6 +4,7 @@ #include "RageUtil.h" #include "RageLog.h" #include "SDL_utils.h" +#include "RageSurface.h" #define MAXCOLORMAPSIZE 256 @@ -18,11 +19,11 @@ #define LM_to_uint(a,b) (((b)<<8)|(a)) -static SDL_Surface *ReadImage( RageFile &f, int len, int height, - const SDL_Color localColorMap[MAXCOLORMAPSIZE], +static RageSurface *ReadImage( RageFile &f, int len, int height, + const RageSurfaceColor localColorMap[MAXCOLORMAPSIZE], int interlace, int ignore ); -static bool ReadPalette( RageFile &f, int number, SDL_Color buffer[MAXCOLORMAPSIZE] ) +static bool ReadPalette( RageFile &f, int number, RageSurfaceColor buffer[MAXCOLORMAPSIZE] ) { for( int i = 0; i < number; ++i ) { @@ -32,7 +33,7 @@ static bool ReadPalette( RageFile &f, int number, SDL_Color buffer[MAXCOLORMAPSI return false; if( !ReadOK(f, &buffer[i].b, sizeof(buffer[i].b)) ) return false; - buffer[i].unused = 0xFF; + buffer[i].a = 0xFF; } return true; @@ -58,7 +59,7 @@ static int GetDataBlock( RageFile &f, unsigned char *buf ) } -RageSurfaceUtils::OpenResult RageSurface_Load_GIF( const CString &sPath, SDL_Surface *&ret, bool bHeaderOnly, CString &error ) +RageSurfaceUtils::OpenResult RageSurface_Load_GIF( const CString &sPath, RageSurface *&ret, bool bHeaderOnly, CString &error ) { unsigned char buf[256]; int imageCount = 0; @@ -100,7 +101,7 @@ RageSurfaceUtils::OpenResult RageSurface_Load_GIF( const CString &sPath, SDL_Sur return RageSurfaceUtils::OPEN_FATAL_ERROR; } - SDL_Color GlobalColorMap[MAXCOLORMAPSIZE]; + RageSurfaceColor GlobalColorMap[MAXCOLORMAPSIZE]; unsigned int GlobalBitPixel = 0; GlobalBitPixel = 2 << (buf[4] & 0x07); @@ -172,7 +173,7 @@ RageSurfaceUtils::OpenResult RageSurface_Load_GIF( const CString &sPath, SDL_Sur } int bitPixel = 1 << ((buf[8] & 0x07) + 1); - SDL_Color LocalColorMap[MAXCOLORMAPSIZE]; + RageSurfaceColor LocalColorMap[MAXCOLORMAPSIZE]; if( BitSet(buf[8], LOCALCOLORMAP) ) { @@ -194,7 +195,7 @@ RageSurfaceUtils::OpenResult RageSurface_Load_GIF( const CString &sPath, SDL_Sur continue; if( transparency != -1 ) - mySDL_AddColorKey( ret, transparency ); + ret->format->palette->colors[ transparency ].a = 0; return RageSurfaceUtils::OPEN_OK; } @@ -388,8 +389,8 @@ int LWZState::ReadByte( RageFile &f ) return code; } -static SDL_Surface *ReadImage( RageFile &f, int len, int height, - const SDL_Color localColorMap[MAXCOLORMAPSIZE], +static RageSurface *ReadImage( RageFile &f, int len, int height, + const RageSurfaceColor localColorMap[MAXCOLORMAPSIZE], int interlace, int ignore ) { int xpos = 0, ypos = 0, pass = 0; @@ -409,8 +410,8 @@ static SDL_Surface *ReadImage( RageFile &f, int len, int height, return NULL; } - SDL_Surface *image = SDL_CreateRGBSurfaceSane( SDL_SWSURFACE, len, height, 8, 0, 0, 0, 0 ); - mySDL_SetPalette( image, localColorMap, 0, 256 ); + RageSurface *image = CreateSurface( len, height, 8, 0, 0, 0, 0 ); + memcpy( image->fmt.palette->colors, localColorMap, 256*sizeof(RageSurfaceColor) ); int v; while( (v = state.ReadByte(f)) >= 0 ) diff --git a/stepmania/src/RageSurface_Load_GIF.h b/stepmania/src/RageSurface_Load_GIF.h index f4c12a8bab..b8bed4d6f6 100644 --- a/stepmania/src/RageSurface_Load_GIF.h +++ b/stepmania/src/RageSurface_Load_GIF.h @@ -2,7 +2,7 @@ #define RAGE_SURFACE_LOAD_GIF_H #include "RageSurface_Load.h" -RageSurfaceUtils::OpenResult RageSurface_Load_GIF( const CString &sPath, SDL_Surface *&ret, bool bHeaderOnly, CString &error ); +RageSurfaceUtils::OpenResult RageSurface_Load_GIF( const CString &sPath, RageSurface *&ret, bool bHeaderOnly, CString &error ); #endif diff --git a/stepmania/src/RageSurface_Load_JPEG.cpp b/stepmania/src/RageSurface_Load_JPEG.cpp index 6473920447..d4837866bd 100644 --- a/stepmania/src/RageSurface_Load_JPEG.cpp +++ b/stepmania/src/RageSurface_Load_JPEG.cpp @@ -4,6 +4,7 @@ #include "RageLog.h" #include "SDL_utils.h" #include "RageFile.h" +#include "RageSurface.h" #include @@ -105,7 +106,7 @@ void RageFile_JPEG_term_source( j_decompress_ptr cinfo ) { } -static SDL_Surface *RageSurface_Load_JPEG( RageFile *f, const char *fn, char errorbuf[JMSG_LENGTH_MAX] ) +static RageSurface *RageSurface_Load_JPEG( RageFile *f, const char *fn, char errorbuf[JMSG_LENGTH_MAX] ) { struct jpeg_decompress_struct cinfo; @@ -114,7 +115,7 @@ static SDL_Surface *RageSurface_Load_JPEG( RageFile *f, const char *fn, char err jerr.pub.error_exit = my_error_exit; jerr.pub.output_message = my_output_message; - SDL_Surface *volatile img = NULL; /* volatile to prevent possible problems with setjmp */ + RageSurface *volatile img = NULL; /* volatile to prevent possible problems with setjmp */ if( setjmp(jerr.setjmp_buffer) ) { @@ -122,8 +123,7 @@ static SDL_Surface *RageSurface_Load_JPEG( RageFile *f, const char *fn, char err memcpy( errorbuf, myerr->errorbuf, JMSG_LENGTH_MAX ); jpeg_destroy_decompress( &cinfo ); - if( img ) - SDL_FreeSurface( img ); + delete img; return NULL; } @@ -164,17 +164,17 @@ static SDL_Surface *RageSurface_Load_JPEG( RageFile *f, const char *fn, char err if( cinfo.out_color_space == JCS_GRAYSCALE ) { - img = SDL_CreateRGBSurfaceSane( SDL_SWSURFACE, cinfo.output_width, cinfo.output_height, 8, 0, 0, 0, 0 ); + img = CreateSurface( cinfo.output_width, cinfo.output_height, 8, 0, 0, 0, 0 ); for( int i = 0; i < 256; ++i ) { - SDL_Color color; + RageSurfaceColor color; color.r = color.g = color.b = (int8_t) i; - color.unused = 0xFF; - mySDL_SetPalette( img, &color, i, 1 ); + color.a = 0xFF; + img->fmt.palette->colors[i] = color; } } else { - img = SDL_CreateRGBSurfaceSane( SDL_SWSURFACE, cinfo.output_width, cinfo.output_height, 24, + img = CreateSurface( cinfo.output_width, cinfo.output_height, 24, Swap24BE( 0xFF0000 ), Swap24BE( 0x00FF00 ), Swap24BE( 0x0000FF ), @@ -195,7 +195,7 @@ static SDL_Surface *RageSurface_Load_JPEG( RageFile *f, const char *fn, char err } -RageSurfaceUtils::OpenResult RageSurface_Load_JPEG( const CString &sPath, SDL_Surface *&ret, bool bHeaderOnly, CString &error ) +RageSurfaceUtils::OpenResult RageSurface_Load_JPEG( const CString &sPath, RageSurface *&ret, bool bHeaderOnly, CString &error ) { RageFile f; if( !f.Open( sPath ) ) diff --git a/stepmania/src/RageSurface_Load_JPEG.h b/stepmania/src/RageSurface_Load_JPEG.h index 12aad0b323..8c88d7298a 100644 --- a/stepmania/src/RageSurface_Load_JPEG.h +++ b/stepmania/src/RageSurface_Load_JPEG.h @@ -2,7 +2,7 @@ #define RAGE_SURFACE_LOAD_JPEG_H #include "RageSurface_Load.h" -RageSurfaceUtils::OpenResult RageSurface_Load_JPEG( const CString &sPath, SDL_Surface *&ret, bool bHeaderOnly, CString &error ); +RageSurfaceUtils::OpenResult RageSurface_Load_JPEG( const CString &sPath, RageSurface *&ret, bool bHeaderOnly, CString &error ); #endif diff --git a/stepmania/src/RageSurface_Load_PNG.cpp b/stepmania/src/RageSurface_Load_PNG.cpp index b111897086..11e53152f4 100644 --- a/stepmania/src/RageSurface_Load_PNG.cpp +++ b/stepmania/src/RageSurface_Load_PNG.cpp @@ -4,6 +4,7 @@ #include "RageLog.h" #include "SDL_utils.h" #include "RageFile.h" +#include "RageSurface.h" #if defined(WIN32) #include "libpng/include/png.h" @@ -51,7 +52,7 @@ static void PNG_Warning( png_struct *png, const char *warning ) /* Since libpng forces us to use longjmp (gross!), this function shouldn't create any C++ * objects, and needs to watch out for memleaks. */ -static SDL_Surface *RageSurface_Load_PNG( RageFile *f, const char *fn, char errorbuf[1024], bool bHeaderOnly ) +static RageSurface *RageSurface_Load_PNG( RageFile *f, const char *fn, char errorbuf[1024], bool bHeaderOnly ) { error_info error; error.err = errorbuf; @@ -72,12 +73,11 @@ static SDL_Surface *RageSurface_Load_PNG( RageFile *f, const char *fn, char erro return NULL; } - SDL_Surface *volatile img = NULL; + RageSurface *volatile img = NULL; if( setjmp(png_jmpbuf(png)) ) { png_destroy_read_struct( &png, &info_ptr, NULL ); - if( img ) - SDL_FreeSurface( img ); + delete img; return NULL; } @@ -93,7 +93,7 @@ static SDL_Surface *RageSurface_Load_PNG( RageFile *f, const char *fn, char erro * the image. Just return an empty surface with only the width and height set. */ if( bHeaderOnly ) { - img = SDL_CreateRGBSurfaceFrom( NULL, width, height, 32, width*4, 0, 0, 0, 0 ); + img = CreateSurfaceFrom( width, height, 32, 0, 0, 0, 0, NULL, width*4 ); png_destroy_read_struct( &png, &info_ptr, NULL ); if( !img ) { @@ -113,7 +113,7 @@ static SDL_Surface *RageSurface_Load_PNG( RageFile *f, const char *fn, char erro png_set_gray_1_2_4_to_8( png ); /* These are set for type == PALETTE. */ - SDL_Color colors[256]; + RageSurfaceColor colors[256]; int iColorKey = -1; /* We import three types of files: paletted, RGBX and RGBA. The only difference @@ -127,7 +127,7 @@ static SDL_Surface *RageSurface_Load_PNG( RageFile *f, const char *fn, char erro for( int i = 0; i < 256; ++i ) { colors[i].r = colors[i].g = colors[i].b = (int8_t) i; - colors[i].unused = 0xFF; + colors[i].a = 0xFF; } type = PALETTE; @@ -185,9 +185,9 @@ static SDL_Surface *RageSurface_Load_PNG( RageFile *f, const char *fn, char erro colors[i].r = palette[i].red; colors[i].g = palette[i].green; colors[i].b = palette[i].blue; - colors[i].unused = 0xFF; + colors[i].a = 0xFF; if( i < num_trans ) - colors[i].unused = trans[i]; + colors[i].a = trans[i]; } } @@ -198,16 +198,16 @@ static SDL_Surface *RageSurface_Load_PNG( RageFile *f, const char *fn, char erro switch( type ) { case PALETTE: - img = SDL_CreateRGBSurfaceSane( SDL_SWSURFACE, width, height, 8, 0, 0, 0, 0 ); - mySDL_SetPalette( img, colors, 0, 256 ); + img = CreateSurface( width, height, 8, 0, 0, 0, 0 ); + memcpy( img->fmt.palette->colors, colors, 256*sizeof(RageSurfaceColor) ); if( iColorKey != -1 ) - mySDL_AddColorKey( img, iColorKey ); + img->format->palette->colors[ iColorKey ].a = 0; break; case RGBX: case RGBA: - img = SDL_CreateRGBSurfaceSane( SDL_SWSURFACE, width, height, 32, + img = CreateSurface( width, height, 32, Swap32BE( 0xFF000000 ), Swap32BE( 0x00FF0000 ), Swap32BE( 0x0000FF00 ), @@ -236,7 +236,7 @@ static SDL_Surface *RageSurface_Load_PNG( RageFile *f, const char *fn, char erro } -RageSurfaceUtils::OpenResult RageSurface_Load_PNG( const CString &sPath, SDL_Surface *&ret, bool bHeaderOnly, CString &error ) +RageSurfaceUtils::OpenResult RageSurface_Load_PNG( const CString &sPath, RageSurface *&ret, bool bHeaderOnly, CString &error ) { RageFile f; if( !f.Open( sPath ) ) diff --git a/stepmania/src/RageSurface_Load_PNG.h b/stepmania/src/RageSurface_Load_PNG.h index 0eed00e739..bf4f340bf4 100644 --- a/stepmania/src/RageSurface_Load_PNG.h +++ b/stepmania/src/RageSurface_Load_PNG.h @@ -2,7 +2,7 @@ #define RAGE_SURFACE_LOAD_PNG_H #include "RageSurface_Load.h" -RageSurfaceUtils::OpenResult RageSurface_Load_PNG( const CString &sPath, SDL_Surface *&ret, bool bHeaderOnly, CString &error ); +RageSurfaceUtils::OpenResult RageSurface_Load_PNG( const CString &sPath, RageSurface *&ret, bool bHeaderOnly, CString &error ); #endif diff --git a/stepmania/src/RageSurface_Load_XPM.cpp b/stepmania/src/RageSurface_Load_XPM.cpp index 0166aec609..a55dec33ed 100644 --- a/stepmania/src/RageSurface_Load_XPM.cpp +++ b/stepmania/src/RageSurface_Load_XPM.cpp @@ -6,6 +6,7 @@ #include "RageUtil.h" #include "RageLog.h" #include "SDL_utils.h" +#include "RageSurface.h" #define CheckLine() \ if( xpm[line] == NULL ) { \ @@ -13,7 +14,7 @@ return NULL; \ } -SDL_Surface *RageSurface_Load_XPM( char * const *xpm, CString &error ) +RageSurface *RageSurface_Load_XPM( char * const *xpm, CString &error ) { int line = 0; @@ -32,7 +33,7 @@ SDL_Surface *RageSurface_Load_XPM( char * const *xpm, CString &error ) return NULL; } - vector colors; + vector colors; map name_to_color; for( int i = 0; i < num_colors; ++i ) @@ -55,24 +56,24 @@ SDL_Surface *RageSurface_Load_XPM( char * const *xpm, CString &error ) int r, g, b; if( sscanf( clr, "%2x%2x%2x", &r, &g, &b ) != 3 ) continue; - SDL_Color colorval; + RageSurfaceColor colorval; colorval.r = (uint8_t) r; colorval.g = (uint8_t) g; colorval.b = (uint8_t) b; - colorval.unused = 0xFF; + colorval.a = 0xFF; colors.push_back( colorval ); name_to_color[name] = colors.size()-1; } - SDL_Surface *img; + RageSurface *img; if( colors.size() <= 256 ) { - img = SDL_CreateRGBSurfaceSane( SDL_SWSURFACE, width, height, 8, 0, 0, 0, 0 ); - mySDL_SetPalette( img, &colors[0], 0, colors.size() ); + img = CreateSurface( width, height, 8, 0, 0, 0, 0 ); + memcpy( img->fmt.palette->colors, &colors[0], colors.size()*sizeof(RageSurfaceColor) ); } else { - img = SDL_CreateRGBSurfaceSane( SDL_SWSURFACE, width, height, 32, + img = CreateSurface( width, height, 32, 0xFF000000, 0x00FF0000, 0x0000FF00, 0 ); } @@ -83,7 +84,7 @@ SDL_Surface *RageSurface_Load_XPM( char * const *xpm, CString &error ) if( (int) row.size() != width*color_length ) { error = ssprintf( "row %i is not expected length (%i != %i)", y, int(row.size()), width*color_length ); - SDL_FreeSurface( img ); + delete img; return NULL; } @@ -98,7 +99,7 @@ SDL_Surface *RageSurface_Load_XPM( char * const *xpm, CString &error ) if( it == name_to_color.end() ) { error = ssprintf( "%ix%i is unknown color \"%s\"", x, y, color_name.c_str() ); - SDL_FreeSurface( img ); + delete img; return NULL; } @@ -106,7 +107,7 @@ SDL_Surface *RageSurface_Load_XPM( char * const *xpm, CString &error ) { p[x] = (int8_t) it->second; } else { - const SDL_Color &color = colors[it->second]; + const RageSurfaceColor &color = colors[it->second]; p32[x] = (color.r << 24) + (color.g << 16) + (color.b << 8); } } diff --git a/stepmania/src/RageSurface_Load_XPM.h b/stepmania/src/RageSurface_Load_XPM.h index a86fc94118..5cd7a32192 100644 --- a/stepmania/src/RageSurface_Load_XPM.h +++ b/stepmania/src/RageSurface_Load_XPM.h @@ -1,8 +1,8 @@ #ifndef RAGE_SURFACE_LOAD_XPM_H #define RAGE_SURFACE_LOAD_XPM_H -struct SDL_Surface; -SDL_Surface *RageSurface_Load_XPM( char * const *xpm, CString &error ); +struct RageSurface; +RageSurface *RageSurface_Load_XPM( char * const *xpm, CString &error ); #endif diff --git a/stepmania/src/SDL_SaveJPEG.cpp b/stepmania/src/SDL_SaveJPEG.cpp index 9f914e8d2f..2f48403ece 100644 --- a/stepmania/src/SDL_SaveJPEG.cpp +++ b/stepmania/src/SDL_SaveJPEG.cpp @@ -1,5 +1,6 @@ #include "global.h" -#include "SDL.h" +#include "RageSurface.h" +#include "RageSurfaceUtils.h" #include "SDL_utils.h" #include "RageUtil.h" @@ -95,10 +96,10 @@ static void jpeg_SDL_RW_dest( jpeg::j_compress_ptr cinfo, SDL_RWops *ctx ) } /* Save a JPEG to a file. cjpeg.c and example.c from jpeglib were helpful in writing this. */ -void IMG_SaveJPG_RW( SDL_Surface *surface, SDL_RWops *dest, bool bHighQual ) +void IMG_SaveJPG_RW( RageSurface *surface, SDL_RWops *dest, bool bHighQual ) { - SDL_Surface *dst_surface; - if( ConvertSDLSurface( surface, dst_surface, + RageSurface *dst_surface; + if( RageSurfaceUtils::ConvertSurface( surface, dst_surface, surface->w, surface->h, 24, Swap24BE(0xFF0000), Swap24BE(0x00FF00), Swap24BE(0x0000FF), 0 ) ) surface = dst_surface; @@ -150,8 +151,7 @@ void IMG_SaveJPG_RW( SDL_Surface *surface, SDL_RWops *dest, bool bHighQual ) jpeg::jpeg_finish_compress( &cinfo ); jpeg::jpeg_destroy_compress( &cinfo ); - if( dst_surface ) - SDL_FreeSurface( dst_surface ); + delete dst_surface; } /* diff --git a/stepmania/src/SDL_SaveJPEG.h b/stepmania/src/SDL_SaveJPEG.h index 885ca77671..d8763e9e36 100644 --- a/stepmania/src/SDL_SaveJPEG.h +++ b/stepmania/src/SDL_SaveJPEG.h @@ -1,8 +1,8 @@ #ifndef SDL_SAVE_JPEG_H #define SDL_SAVE_JPEG_H -struct SDL_Surface; -void IMG_SaveJPG_RW( SDL_Surface *surface, SDL_RWops *dest, bool bHighQual=true ); +struct RageSurface; +void IMG_SaveJPG_RW( RageSurface *surface, SDL_RWops *dest, bool bHighQual=true ); #endif diff --git a/stepmania/src/SDL_dither.cpp b/stepmania/src/SDL_dither.cpp index b841e6ac2b..18f62a0800 100644 --- a/stepmania/src/SDL_dither.cpp +++ b/stepmania/src/SDL_dither.cpp @@ -1,9 +1,9 @@ #include "global.h" #include "RageUtil.h" -#include "SDL.h" #include "SDL_dither.h" -#include "SDL_utils.h" +#include "RageSurface.h" +#include "RageSurfaceUtils.h" #define DitherMatDim 4 @@ -52,7 +52,7 @@ static uint8_t DitherPixel(int x, int y, int intensity, int conv) return uint8_t((out_intensity + 1) >> 16); } -void SM_SDL_OrderedDither(const SDL_Surface *src, SDL_Surface *dst) +void SM_SDL_OrderedDither(const RageSurface *src, RageSurface *dst) { static bool DitherMatCalc_initted = false; if( !DitherMatCalc_initted ) @@ -75,8 +75,8 @@ void SM_SDL_OrderedDither(const SDL_Surface *src, SDL_Surface *dst) ASSERT( dst->format->BytesPerPixel > 1 ); uint32_t src_cbits[4], dst_cbits[4]; - mySDL_GetBitsPerChannel( src->format, src_cbits ); - mySDL_GetBitsPerChannel( dst->format, dst_cbits ); + RageSurfaceUtils::GetBitsPerChannel( src->format, src_cbits ); + RageSurfaceUtils::GetBitsPerChannel( dst->format, dst_cbits ); /* Calculate the ratio from the old bit depth to the new for each color channel. */ int conv[4]; @@ -104,7 +104,7 @@ void SM_SDL_OrderedDither(const SDL_Surface *src, SDL_Surface *dst) for( int col = 0; col < src->w; ++col ) { uint8_t colors[4]; - mySDL_GetRawRGBAV( srcp, src, colors ); + RageSurfaceUtils::GetRawRGBAV( srcp, src->fmt, colors ); /* Note that we don't dither the alpha channel. */ for( int c = 0; c < 3; ++c ) @@ -135,7 +135,7 @@ void SM_SDL_OrderedDither(const SDL_Surface *src, SDL_Surface *dst) } /* Raw value -> int -> pixel */ - mySDL_SetRawRGBAV(dstp, dst, colors); + RageSurfaceUtils::SetRawRGBAV(dstp, dst, colors); srcp += src->format->BytesPerPixel; dstp += dst->format->BytesPerPixel; @@ -167,14 +167,14 @@ void SM_SDL_OrderedDither(const SDL_Surface *src, SDL_Surface *dst) /* This is very similar to SM_SDL_OrderedDither, except instead of using a matrix * containing rounding values, we truncate and then add the resulting error for * each pixel to the next pixel on the same line. (Maybe we could do both?) */ -void SM_SDL_ErrorDiffusionDither(const SDL_Surface *src, SDL_Surface *dst) +void SM_SDL_ErrorDiffusionDither(const RageSurface *src, RageSurface *dst) { /* We can't dither to paletted surfaces. */ ASSERT( dst->format->BytesPerPixel > 1 ); uint32_t src_cbits[4], dst_cbits[4]; - mySDL_GetBitsPerChannel( src->format, src_cbits ); - mySDL_GetBitsPerChannel( dst->format, dst_cbits ); + RageSurfaceUtils::GetBitsPerChannel( src->format, src_cbits ); + RageSurfaceUtils::GetBitsPerChannel( dst->format, dst_cbits ); /* Calculate the ratio from the old bit depth to the new for each color channel. */ int conv[4]; @@ -204,7 +204,7 @@ void SM_SDL_ErrorDiffusionDither(const SDL_Surface *src, SDL_Surface *dst) for( int col = 0; col < src->w; ++col ) { uint8_t colors[4]; - mySDL_GetRawRGBAV( srcp, src, colors ); + RageSurfaceUtils::GetRawRGBAV( srcp, src->fmt, colors ); for( int c = 0; c < 3; ++c ) { @@ -264,7 +264,7 @@ void SM_SDL_ErrorDiffusionDither(const SDL_Surface *src, SDL_Surface *dst) colors[3] = uint8_t((out_intensity + 32767) >> 16); } - mySDL_SetRawRGBAV( dstp, dst, colors ); + RageSurfaceUtils::SetRawRGBAV( dstp, dst, colors ); srcp += src->format->BytesPerPixel; dstp += dst->format->BytesPerPixel; diff --git a/stepmania/src/SDL_dither.h b/stepmania/src/SDL_dither.h index 4830e7fa01..dc0c86a288 100644 --- a/stepmania/src/SDL_dither.h +++ b/stepmania/src/SDL_dither.h @@ -1,9 +1,9 @@ #ifndef SM_SDL_DITHER_H #define SM_SDL_DITHER_H -struct SDL_Surface; -void SM_SDL_OrderedDither(const SDL_Surface *src, SDL_Surface *dst); -void SM_SDL_ErrorDiffusionDither(const SDL_Surface *src, SDL_Surface *dst); +struct RageSurface; +void SM_SDL_OrderedDither(const RageSurface *src, RageSurface *dst); +void SM_SDL_ErrorDiffusionDither(const RageSurface *src, RageSurface *dst); #endif diff --git a/stepmania/src/SDL_rotozoom.cpp b/stepmania/src/SDL_rotozoom.cpp index f0c15675a3..e2bf2469bf 100644 --- a/stepmania/src/SDL_rotozoom.cpp +++ b/stepmania/src/SDL_rotozoom.cpp @@ -1,6 +1,6 @@ #include "global.h" #include "SDL_rotozoom.h" -#include "SDL.h" +#include "RageSurface.h" #include using namespace std; @@ -13,7 +13,7 @@ using namespace std; * lines.) */ -static void ZoomSurface( SDL_Surface * src, SDL_Surface * dst ) +static void ZoomSurface( RageSurface * src, RageSurface * dst ) { /* Ratio from source to dest. */ const float sx = float(src->w) / dst->w; @@ -121,7 +121,7 @@ static void ZoomSurface( SDL_Surface * src, SDL_Surface * dst ) } -void zoomSurface( SDL_Surface *&src, int dstwidth, int dstheight ) +void zoomSurface( RageSurface *&src, int dstwidth, int dstheight ) { if( src == NULL ) return; @@ -140,14 +140,14 @@ void zoomSurface( SDL_Surface *&src, int dstwidth, int dstheight ) int target_width = int(src->w*xscale + .5); int target_height = int(src->h*yscale + .5); - SDL_Surface *dst = - SDL_CreateRGBSurface(SDL_SWSURFACE, target_width, target_height, 32, + RageSurface *dst = + CreateSurface(target_width, target_height, 32, src->format->Rmask, src->format->Gmask, src->format->Bmask, src->format->Amask); ZoomSurface( src, dst ); - SDL_FreeSurface(src); + delete src; src = dst; } diff --git a/stepmania/src/SDL_rotozoom.h b/stepmania/src/SDL_rotozoom.h index f719eb5dee..dc40f7aa2c 100644 --- a/stepmania/src/SDL_rotozoom.h +++ b/stepmania/src/SDL_rotozoom.h @@ -1,8 +1,8 @@ #ifndef SDL_ROTOZOOM_H #define SDL_ROTOZOOM_H -struct SDL_Surface; -void zoomSurface( SDL_Surface *&src, int dstwidth, int dstheight ); +struct RageSurface; +void zoomSurface( RageSurface *&src, int dstwidth, int dstheight ); #endif diff --git a/stepmania/src/SDL_utils.cpp b/stepmania/src/SDL_utils.cpp index 9c10bc12b7..f63dc74215 100644 --- a/stepmania/src/SDL_utils.cpp +++ b/stepmania/src/SDL_utils.cpp @@ -7,6 +7,8 @@ #include "RageFile.h" #include "RageLog.h" #include "RageUtil.h" +#include "RageSurface.h" +#include "RageSurfaceUtils.h" /* Pull in all of our SDL libraries here. */ #ifdef _XBOX @@ -23,407 +25,7 @@ #endif #endif -/* These conditionals in the inner loop are slow. Templates? */ -inline Uint32 decodepixel(const Uint8 *p, int bpp) -{ - switch(bpp) - { - case 1: return *p; - case 2: return *(Uint16 *)p; - case 3: - if( BYTE_ORDER == BIG_ENDIAN ) - return p[0] << 16 | p[1] << 8 | p[2]; - else - return p[0] | p[1] << 8 | p[2] << 16; - case 4: return *(Uint32 *)p; - default: return 0; /* shouldn't happen, but avoids warnings */ - } -} - -void encodepixel(Uint8 *p, int bpp, Uint32 pixel) -{ - switch(bpp) - { - case 1: *p = Uint8(pixel); break; - case 2: *(Uint16 *)p = Uint16(pixel); break; - case 3: - if( BYTE_ORDER == BIG_ENDIAN ) - { - p[0] = Uint8((pixel >> 16) & 0xff); - p[1] = Uint8((pixel >> 8) & 0xff); - p[2] = Uint8(pixel & 0xff); - } else { - p[0] = Uint8(pixel & 0xff); - p[1] = Uint8((pixel >> 8) & 0xff); - p[2] = Uint8((pixel >> 16) & 0xff); - } - break; - case 4: *(Uint32 *)p = pixel; break; - } -} - -/* Get and set colors without scaling them to 0..255. Get them into - * an array, which is much easier to work with. We need the surface - * to get at flags, or we won't know if colorkey is valid. (Why isn't - * format self-contained?) Use mySDL_GetBitsPerChannel() to get the - * number of bits per channel. */ -void mySDL_GetRawRGBAV(Uint32 pixel, const SDL_Surface *src, Uint8 *v) -{ - const SDL_PixelFormat *fmt = src->format; - if( src->format->BytesPerPixel == 1 ) - { - v[0] = fmt->palette->colors[pixel].r; - v[1] = fmt->palette->colors[pixel].g; - v[2] = fmt->palette->colors[pixel].b; - v[3] = fmt->palette->colors[pixel].unused; - } else { - v[0] = Uint8((pixel & fmt->Rmask) >> fmt->Rshift); - v[1] = Uint8((pixel & fmt->Gmask) >> fmt->Gshift); - v[2] = Uint8((pixel & fmt->Bmask) >> fmt->Bshift); - v[3] = Uint8((pixel & fmt->Amask) >> fmt->Ashift); - } -} - -void mySDL_GetRawRGBAV(const Uint8 *p, const SDL_Surface *src, Uint8 *v) -{ - Uint32 pixel = decodepixel(p, src->format->BytesPerPixel); - mySDL_GetRawRGBAV(pixel, src, v); -} - -void mySDL_GetRGBAV(Uint32 pixel, const SDL_Surface *src, Uint8 *v) -{ - mySDL_GetRawRGBAV(pixel, src, v); - const SDL_PixelFormat *fmt = src->format; - v[0] = v[0] << fmt->Rloss; - v[1] = v[1] << fmt->Gloss; - v[2] = v[2] << fmt->Bloss; - // Correct for surfaces that don't have an alpha channel. - if( fmt->Aloss == 8) - v[3] = 255; - else - v[3] = v[3] << fmt->Aloss; -} - -void mySDL_GetRGBAV(const Uint8 *p, const SDL_Surface *src, Uint8 *v) -{ - Uint32 pixel = decodepixel(p, src->format->BytesPerPixel); - if( src->format->BytesPerPixel == 1 ) // paletted - { - memcpy( v, &src->format->palette->colors[pixel], sizeof(SDL_Color)); - } - else // RGBA - mySDL_GetRGBAV(pixel, src, v); -} - - -/* Inverse of mySDL_GetRawRGBAV. */ -Uint32 mySDL_SetRawRGBAV(const SDL_PixelFormat *fmt, const Uint8 *v) -{ - return v[0] << fmt->Rshift | - v[1] << fmt->Gshift | - v[2] << fmt->Bshift | - v[3] << fmt->Ashift; -} - -void mySDL_SetRawRGBAV(Uint8 *p, const SDL_Surface *src, const Uint8 *v) -{ - Uint32 pixel = mySDL_SetRawRGBAV(src->format, v); - encodepixel(p, src->format->BytesPerPixel, pixel); -} - -/* Inverse of mySDL_GetRGBAV. */ -Uint32 mySDL_SetRGBAV(const SDL_PixelFormat *fmt, const Uint8 *v) -{ - return (v[0] >> fmt->Rloss) << fmt->Rshift | - (v[1] >> fmt->Gloss) << fmt->Gshift | - (v[2] >> fmt->Bloss) << fmt->Bshift | - (v[3] >> fmt->Aloss) << fmt->Ashift; -} - -void mySDL_SetRGBAV(Uint8 *p, const SDL_Surface *src, const Uint8 *v) -{ - Uint32 pixel = mySDL_SetRGBAV(src->format, v); - encodepixel(p, src->format->BytesPerPixel, pixel); -} - - -/* Get the number of bits representing each color channel in fmt. */ -void mySDL_GetBitsPerChannel(const SDL_PixelFormat *fmt, Uint32 bits[4]) -{ - if( fmt->BytesPerPixel == 1 ) - { - /* If we're paletted, the palette is 8888. For some reason, the - * *loss values are all 8 on paletted surfaces; they should be - * 0, to represent the palette. Since they're not, we have to - * special case this. */ - bits[0] = bits[1] = bits[2] = bits[3] = 8; - return; - } - - /* The actual bits stored in each color is 8-loss. */ - bits[0] = 8 - fmt->Rloss; - bits[1] = 8 - fmt->Gloss; - bits[2] = 8 - fmt->Bloss; - bits[3] = 8 - fmt->Aloss; -} - -/* SDL_SetPalette only works when SDL video has been initialized, even on software - * surfaces. */ -void mySDL_SetPalette(SDL_Surface *dst, const SDL_Color *colors, int start, int cnt) -{ - ASSERT( dst->format->palette ); - ASSERT( start+cnt <= dst->format->palette->ncolors ); - memcpy( dst->format->palette->colors + start, colors, - cnt * sizeof(SDL_Color) ); -} - -void CopySDLSurface( SDL_Surface *src, SDL_Surface *dest ) -{ - /* Copy the palette, if we have one. */ - if( src->format->BitsPerPixel == 8 && dest->format->BitsPerPixel == 8 ) - { - ASSERT( dest->format->palette ); - mySDL_SetPalette( dest, src->format->palette->colors, - 0, src->format->palette->ncolors); - } - - mySDL_BlitSurface( src, dest, -1, -1, false ); -} - -bool CompareSDLFormats( const SDL_PixelFormat *pf1, const SDL_PixelFormat *pf2 ) -{ - if( pf1->BitsPerPixel != pf2->BitsPerPixel ) return false; - if( pf1->Rmask == pf2->Rmask ) return false; - if( pf1->Gmask == pf2->Gmask ) return false; - if( pf1->Bmask == pf2->Bmask ) return false; - if( pf1->Amask == pf2->Amask ) return false; - return true; -} - -bool ConvertSDLSurface( SDL_Surface *src, SDL_Surface *&dst, - int width, int height, int bpp, - Uint32 R, Uint32 G, Uint32 B, Uint32 A ) -{ - dst = SDL_CreateRGBSurfaceSane( SDL_SWSURFACE, width, height, bpp, R, G, B, A ); - ASSERT( dst != NULL ); - - /* If the formats are the same, no conversion is needed. */ - if( width == src->w && height == src->h && CompareSDLFormats( src->format, dst->format ) ) - { - SDL_FreeSurface( dst ); - dst = NULL; - return false; - } - - CopySDLSurface( src, dst ); - return true; -} - -void ConvertSDLSurface(SDL_Surface *&image, - int width, int height, int bpp, - Uint32 R, Uint32 G, Uint32 B, Uint32 A) -{ - SDL_Surface *ret_image; - if( !ConvertSDLSurface( image, ret_image, width, height, bpp, R, G, B, A ) ) - return; - - SDL_FreeSurface( image ); - image = ret_image; -} - -SDL_Surface *SDL_CreateRGBSurfaceSane - (Uint32 flags, int width, int height, int depth, - Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask) -{ - SDL_Surface *ret = SDL_CreateRGBSurface(flags, width, height, depth, - Rmask, Gmask, Bmask, Amask); - - if(ret == NULL) - RageException::Throw("SDL_CreateRGBSurface(%i, %i, %i, %i, %8x, %8x, %8x, %8x) failed: %s", - flags, width, height, depth, Rmask, Gmask, Bmask, Amask, SDL_GetError()); - - return ret; -} - -static void FindAlphaRGB(const SDL_Surface *img, Uint8 &r, Uint8 &g, Uint8 &b, bool reverse) -{ - r = g = b = 0; - - /* If we have no alpha, there's no alpha color. */ - if( img->format->BitsPerPixel > 8 && !img->format->Amask ) - return; - - /* Eww. Sorry. Iterate front-to-back or in reverse. */ - for(int y = reverse? img->h-1:0; - reverse? (y >=0):(y < img->h); reverse? (--y):(++y)) - { - Uint8 *row = (Uint8 *)img->pixels + img->pitch*y; - if(reverse) - row += img->format->BytesPerPixel * (img->w-1); - - for(int x = 0; x < img->w; ++x) - { - Uint32 val = decodepixel(row, img->format->BytesPerPixel); - if( img->format->BitsPerPixel == 8 ) - { - if( img->format->palette->colors[val].unused ) - { - /* This color isn't fully transparent, so grab it. */ - r = img->format->palette->colors[val].r; - g = img->format->palette->colors[val].g; - b = img->format->palette->colors[val].b; - return; - } - } - else - { - if( val & img->format->Amask ) - { - /* This color isn't fully transparent, so grab it. */ - SDL_GetRGB(val, img->format, &r, &g, &b); - return; - } - } - - if( reverse ) - row -= img->format->BytesPerPixel; - else - row += img->format->BytesPerPixel; - } - } - - /* Huh? The image is completely transparent. */ - r = g = b = 0; -} - -/* Set the underlying RGB values of all pixels in 'img' that are - * completely transparent. */ -static void SetAlphaRGB(const SDL_Surface *img, Uint8 r, Uint8 g, Uint8 b) -{ - /* If it's a paletted surface, all we have to do is change the palette. */ - if( img->format->BitsPerPixel == 8 ) - { - for( int c = 0; c < img->format->palette->ncolors; ++c ) - { - if( img->format->palette->colors[c].unused ) - continue; - img->format->palette->colors[c].r = r; - img->format->palette->colors[c].g = g; - img->format->palette->colors[c].b = b; - } - return; - } - - - /* If it's RGBA and there's no alpha channel, we have nothing to do. */ - if( img->format->BitsPerPixel > 8 && !img->format->Amask ) - return; - - Uint32 trans = SDL_MapRGBA(img->format, r, g, b, 0); - for( int y = 0; y < img->h; ++y ) - { - Uint8 *row = (Uint8 *)img->pixels + img->pitch*y; - - for( int x = 0; x < img->w; ++x ) - { - Uint32 val = decodepixel( row, img->format->BytesPerPixel ); - if( val != trans && !(val&img->format->Amask) ) - { - encodepixel( row, img->format->BytesPerPixel, trans ); - } - - row += img->format->BytesPerPixel; - } - } -} - -/* When we scale up images (which we always do in high res), pixels - * that are completely transparent can be blended with opaque pixels, - * causing their RGB elements to show. This is visible in many textures - * as a pixel-wide border in the wrong color. This is tricky to fix. - * We need to set the RGB components of completely transparent pixels - * to a reasonable color. - * - * Most images have a single border color. For these, the transparent - * color is easy: search through the image top-bottom-left-right, - * find the first non-transparent pixel, and pull out its RGB. - * - * A few images don't. We can only make a guess here. What we'll do - * is, after the above search, do the same in reverse (bottom-top-right- - * left). If the color we find is different, we'll just set the border - * color to black. - */ -void FixHiddenAlpha( SDL_Surface *img ) -{ - Uint8 r, g, b; - FindAlphaRGB(img, r, g, b, false); - - Uint8 cr, cg, cb; /* compare */ - FindAlphaRGB(img, cr, cg, cb, true); - - if( cr != r || cg != g || cb != b ) - r = g = b = 0; - - SetAlphaRGB(img, r, g, b); -} - -/* Find various traits of a surface. Do these all at once, so we only have to - * iterate the surface once. */ - -/* We could theoretically do a test to see if an image fits in GL_ALPHA4, - * by looking at the least significant bits of each alpha value. This is - * not likely to ever find a match, though, so don't bother; only use 8alphaonly - * if it's explicitly enabled. - * - * XXX: We could do the FindAlphaRGB search here, too, but we need that information - * in a different place. */ - -int FindSurfaceTraits( const SDL_Surface *img ) -{ - const int NEEDS_NO_ALPHA=0, NEEDS_BOOL_ALPHA=1, NEEDS_FULL_ALPHA=2; - int alpha_type = NEEDS_NO_ALPHA; - - Uint32 max_alpha; - if( img->format->BitsPerPixel == 8 ) - max_alpha = 0xFF; - else - max_alpha = img->format->Amask; - - for(int y = 0; y < img->h; ++y) - { - Uint8 *row = (Uint8 *)img->pixels + img->pitch*y; - - for(int x = 0; x < img->w; ++x) - { - Uint32 val = decodepixel(row, img->format->BytesPerPixel); - - Uint32 alpha; - if( img->format->BitsPerPixel == 8 ) - alpha = img->format->palette->colors[val].unused; - else - alpha = (val & img->format->Amask); - - if( alpha == 0 ) - alpha_type = max( alpha_type, NEEDS_BOOL_ALPHA ); - else if( alpha != max_alpha ) - alpha_type = max( alpha_type, NEEDS_FULL_ALPHA ); - - row += img->format->BytesPerPixel; - } - } - - int ret = 0; - switch( alpha_type ) - { - case NEEDS_NO_ALPHA: ret |= TRAIT_NO_TRANSPARENCY; break; - case NEEDS_BOOL_ALPHA: ret |= TRAIT_BOOL_TRANSPARENCY; break; - case NEEDS_FULL_ALPHA: break; - default: ASSERT(0); - } - - return ret; -} bool SDL_GetEvent( SDL_Event &event, int mask ) { @@ -461,7 +63,7 @@ void mySDL_PushEvents( vector &events ) /* For some bizarre reason, SDL_EventState flushes all events. This is a pain, so * avoid it. */ -Uint8 mySDL_EventState( Uint8 type, int state ) +uint8_t mySDL_EventState( uint8_t type, int state ) { if(state == SDL_QUERY) return SDL_EventState(type, state); @@ -470,7 +72,7 @@ Uint8 mySDL_EventState( Uint8 type, int state ) mySDL_GetAllEvents(events); /* Set the event mask. */ - Uint8 ret = SDL_EventState(type, state); + uint8_t ret = SDL_EventState(type, state); /* Don't readding events that we just turned off; they'll just sit around * in the buffer. */ @@ -488,566 +90,7 @@ Uint8 mySDL_EventState( Uint8 type, int state ) return ret; } -void mySDL_WM_SetIcon( CString sIconFile ) -{ -#if !defined(DARWIN) - if( sIconFile.empty() ) - { - SDL_WM_SetIcon(NULL, NULL); - return; - } - SDL_Surface *srf = RageSurfaceUtils::LoadFile(sIconFile); - if( srf == NULL ) - return; - - /* Windows icons are 32x32 and SDL can't resize them for us, which - * causes mask corruption. (Actually, the above icon *is* 32x32; - * this is here just in case it changes.) */ - ConvertSDLSurface(srf, srf->w, srf->h, - 32, 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF); - zoomSurface(srf, 32, 32); - - SDL_SetAlpha( srf, SDL_SRCALPHA, SDL_ALPHA_OPAQUE ); - SDL_WM_SetIcon(srf, NULL /* derive from alpha */); - SDL_FreeSurface(srf); -#endif -} - - -struct SurfaceHeader -{ - int width, height, pitch; - int Rmask, Gmask, Bmask, Amask; - int bpp; -}; - -/* Save and load SDL_Surfaces to disk. This avoids problems with bitmaps. */ -bool mySDL_SaveSurface( SDL_Surface *img, CString file ) -{ - RageFile f; - if( !f.Open( file, RageFile::WRITE ) ) - return false; - - SurfaceHeader h; - memset( &h, 0, sizeof(h) ); - - h.height = img->h; - h.width = img->w; - h.pitch = img->pitch; - h.Rmask = img->format->Rmask; - h.Gmask = img->format->Gmask; - h.Bmask = img->format->Bmask; - h.Amask = img->format->Amask; - h.bpp = img->format->BitsPerPixel; - - f.Write( &h, sizeof(h) ); - - if(h.bpp == 8) - f.Write( img->format->palette->colors, 256 * sizeof(SDL_Color) ); - - f.Write( img->pixels, img->h * img->pitch ); - - return true; -} - -SDL_Surface *mySDL_LoadSurface( CString file ) -{ - RageFile f; - if( !f.Open( file ) ) - return false; - - SurfaceHeader h; - if( f.Read( &h, sizeof(h) ) != sizeof(h) ) - return NULL; - - SDL_Color palette[256]; - if(h.bpp == 8) - if( f.Read( palette, 256 * sizeof(SDL_Color) != 256 * sizeof(SDL_Color) ) ) - return NULL; - - /* Create the surface. */ - SDL_Surface *img = SDL_CreateRGBSurface( - SDL_SWSURFACE, h.width, h.height, h.bpp, - h.Rmask, h.Gmask, h.Bmask, h.Amask); - ASSERT( img ); - ASSERT( h.pitch == img->pitch ); - - if( f.Read( img->pixels, h.height * h.pitch ) != h.height * h.pitch ) - { - SDL_FreeSurface( img ); - return NULL; - } - - /* Set the palette. */ - if( h.bpp == 8 ) - mySDL_SetPalette( img, palette, 0, 256 ); - - return img; -} - - -/* Annoying: SDL_MapRGB will do a nearest-match if the specified color isn't found. - * This breaks color keyed images that don't actually use the color key. */ -bool mySDL_MapRGBExact( SDL_PixelFormat *fmt, Uint8 R, Uint8 G, Uint8 B, Uint32 &color ) -{ - color = SDL_MapRGB(fmt, R, G, B); - - if( fmt->BitsPerPixel == 8 ) { - if(fmt->palette->colors[color].r != R || - fmt->palette->colors[color].g != G || - fmt->palette->colors[color].b != B ) - return false; - } - - return true; -} - -inline static float scale( float x, float l1, float h1, float l2, float h2 ) -{ - return ((x - l1) / (h1 - l1) * (h2 - l2) + l2); -} - -inline void mySDL_GetRawRGBAV_XY( const SDL_Surface *src, Uint8 *v, int x, int y ) -{ - const Uint8 *srcp = (const Uint8 *) src->pixels + (y * src->pitch); - const Uint8 *srcpx = srcp + (x * src->format->BytesPerPixel); - - mySDL_GetRawRGBAV(srcpx, src, v); -} - -#include "RageUtil.h" - -/* Completely unoptimized. */ -void mySDL_BlitTransform( const SDL_Surface *src, SDL_Surface *dst, - const float fCoords[8] /* TL, BR, BL, TR */ ) -{ - ASSERT( src->format->BytesPerPixel == dst->format->BytesPerPixel ); - - const float Coords[8] = { - (fCoords[0] * (src->w)), (fCoords[1] * (src->h)), - (fCoords[2] * (src->w)), (fCoords[3] * (src->h)), - (fCoords[4] * (src->w)), (fCoords[5] * (src->h)), - (fCoords[6] * (src->w)), (fCoords[7] * (src->h)) - }; - - const int TL_X = 0, TL_Y = 1, BL_X = 2, BL_Y = 3, - BR_X = 4, BR_Y = 5, TR_X = 6, TR_Y = 7; - - for( int y = 0; y < dst->h; ++y ) - { - Uint8 *dstp = (Uint8 *) dst->pixels + (y * dst->pitch); /* line */ - Uint8 *dstpx = dstp; /* pixel */ - - const float start_y = scale(float(y), 0, float(dst->h), Coords[TL_Y], Coords[BL_Y]); - const float end_y = scale(float(y), 0, float(dst->h), Coords[TR_Y], Coords[BR_Y]); - - const float start_x = scale(float(y), 0, float(dst->h), Coords[TL_X], Coords[BL_X]); - const float end_x = scale(float(y), 0, float(dst->h), Coords[TR_X], Coords[BR_X]); - - for( int x = 0; x < dst->w; ++x ) - { - const float src_xp = scale(float(x), 0, float(dst->w), start_x, end_x); - const float src_yp = scale(float(x), 0, float(dst->w), start_y, end_y); - - /* If the surface is two pixels wide, src_xp is 0..2. .5 indicates - * pixel[0]; 1 indicates 50% pixel[0], 50% pixel[1]; 1.5 indicates - * pixel[1]; 2 indicates 50% pixel[1], 50% pixel[2] (which is clamped - * to pixel[1]). */ - int src_x[2], src_y[2]; - src_x[0] = (int) truncf(src_xp - 0.5f); - src_x[1] = src_x[0] + 1; - - src_y[0] = (int) truncf(src_yp - 0.5f); - src_y[1] = src_y[0] + 1; - - /* Emulate GL_REPEAT. */ - src_x[0] = clamp(src_x[0], 0, src->w); - src_x[1] = clamp(src_x[1], 0, src->w); - src_y[0] = clamp(src_y[0], 0, src->h); - src_y[1] = clamp(src_y[1], 0, src->h); - - /* Decode our four pixels. */ - Uint8 v[4][4]; - mySDL_GetRawRGBAV_XY(src, v[0], src_x[0], src_y[0]); - mySDL_GetRawRGBAV_XY(src, v[1], src_x[0], src_y[1]); - mySDL_GetRawRGBAV_XY(src, v[2], src_x[1], src_y[0]); - mySDL_GetRawRGBAV_XY(src, v[3], src_x[1], src_y[1]); - - /* Distance from the pixel chosen: */ - float weight_x = src_xp - (src_x[0] + 0.5f); - float weight_y = src_yp - (src_y[0] + 0.5f); - - /* Filter: */ - Uint8 out[4] = { 0,0,0,0 }; - for(int i = 0; i < 4; ++i) - { - float sum = 0; - sum += v[0][i] * (1-weight_x) * (1-weight_y); - sum += v[1][i] * (1-weight_x) * (weight_y); - sum += v[2][i] * (weight_x) * (1-weight_y); - sum += v[3][i] * (weight_x) * (weight_y); - out[i] = (Uint8) clamp( lrintf(sum), 0, 255 ); - } - - /* If the source has no alpha, set the destination to opaque. */ - if( src->format->Amask == 0 ) - out[3] = Uint8( dst->format->Amask >> dst->format->Ashift ); - - mySDL_SetRawRGBAV(dstpx, dst, out); - - dstpx += dst->format->BytesPerPixel; - } - } -} - -/* - * Simplified: - * - * No source alpha. - * Palette -> palette blits assume the palette is identical (no mapping). - * No color key. - * No general blitting rects. - */ - -static void blit_same_type( SDL_Surface *src_surf, const SDL_Surface *dst_surf, int width, int height ) -{ - const char *src = (const char *) src_surf->pixels; - const char *dst = (const char *) dst_surf->pixels; - - /* Bytes to skip at the end of a line. */ - const int srcskip = src_surf->pitch - width*src_surf->format->BytesPerPixel; - const int dstskip = dst_surf->pitch - width*dst_surf->format->BytesPerPixel; - - /* XXX: duff's this */ - while( height-- ) - { - int x = 0; - while( x++ < width ) - { - /* (Relatively) fast. */ - switch( src_surf->format->BytesPerPixel ) - { - case 1: *((Uint8 *)dst) = *((Uint8 *)src); break; - case 2: *((Uint16 *)dst) = *((Uint16 *)src); break; - case 3: ((Uint8 *)dst)[0] = ((Uint8 *)src)[0]; - ((Uint8 *)dst)[1] = ((Uint8 *)src)[1]; - ((Uint8 *)dst)[2] = ((Uint8 *)src)[2]; - break; - case 4: *((Uint32 *)dst) = *((Uint32 *)src); break; - } - - src += src_surf->format->BytesPerPixel; - dst += dst_surf->format->BytesPerPixel; - } - - src += srcskip; - dst += dstskip; - } -} - -/* Rescaling blit with no ckey. This is used to update movies in - * D3D, so optimization is very important. */ -static void blit_rgba_to_rgba( SDL_Surface *src_surf, const SDL_Surface *dst_surf, int width, int height ) -{ - const char *src = (const char *) src_surf->pixels; - const char *dst = (const char *) dst_surf->pixels; - - /* Bytes to skip at the end of a line. */ - const int srcskip = src_surf->pitch - width*src_surf->format->BytesPerPixel; - const int dstskip = dst_surf->pitch - width*dst_surf->format->BytesPerPixel; - - Uint32 src_bits[4], dst_bits[4]; - mySDL_GetBitsPerChannel(src_surf->format, src_bits); - mySDL_GetBitsPerChannel(dst_surf->format, dst_bits); - - const int rshifts[4] = { - src_surf->format->Rshift + src_bits[0] - dst_bits[0], - src_surf->format->Gshift + src_bits[1] - dst_bits[1], - src_surf->format->Bshift + src_bits[2] - dst_bits[2], - src_surf->format->Ashift + src_bits[3] - dst_bits[3], - }; - const int lshifts[4] = { - dst_surf->format->Rshift, - dst_surf->format->Gshift, - dst_surf->format->Bshift, - dst_surf->format->Ashift, - }; - - const Uint32 masks[4] = { - src_surf->format->Rmask, - src_surf->format->Gmask, - src_surf->format->Bmask, - src_surf->format->Amask - }; - - int ormask = 0; - if( src_surf->format->Amask == 0 ) - ormask = dst_surf->format->Amask; - - while( height-- ) - { - int x = 0; - while( x++ < width ) - { - unsigned int pixel = decodepixel((Uint8 *) src, src_surf->format->BytesPerPixel); - - /* Convert pixel to the destination RGBA. */ - unsigned int opixel = 0; - opixel |= (pixel & masks[0]) >> rshifts[0] << lshifts[0]; - opixel |= (pixel & masks[1]) >> rshifts[1] << lshifts[1]; - opixel |= (pixel & masks[2]) >> rshifts[2] << lshifts[2]; - opixel |= (pixel & masks[3]) >> rshifts[3] << lshifts[3]; - - // Correct surfaces that don't have an alpha channel. - opixel |= ormask; - - /* Store it. */ - encodepixel((Uint8 *) dst, dst_surf->format->BytesPerPixel, opixel); - - src += src_surf->format->BytesPerPixel; - dst += dst_surf->format->BytesPerPixel; - } - - src += srcskip; - dst += dstskip; - } -} - -static void blit_generic( SDL_Surface *src_surf, const SDL_Surface *dst_surf, int width, int height ) -{ - const char *src = (const char *) src_surf->pixels; - const char *dst = (const char *) dst_surf->pixels; - - /* Bytes to skip at the end of a line. */ - const int srcskip = src_surf->pitch - width*src_surf->format->BytesPerPixel; - const int dstskip = dst_surf->pitch - width*dst_surf->format->BytesPerPixel; - - while( height-- ) - { - int x = 0; - while( x++ < width ) - { - unsigned int pixel = decodepixel((Uint8 *) src, src_surf->format->BytesPerPixel); - - Uint8 colors[4]; - /* Convert pixel to the destination RGBA. */ - colors[0] = src_surf->format->palette->colors[pixel].r; - colors[1] = src_surf->format->palette->colors[pixel].g; - colors[2] = src_surf->format->palette->colors[pixel].b; - colors[3] = src_surf->format->palette->colors[pixel].unused; - pixel = mySDL_SetRGBAV(dst_surf->format, colors); - - /* Store it. */ - encodepixel((Uint8 *) dst, dst_surf->format->BytesPerPixel, pixel); - - src += src_surf->format->BytesPerPixel; - dst += dst_surf->format->BytesPerPixel; - } - - src += srcskip; - dst += dstskip; - } - -} - -/* Blit src onto dst. */ -void mySDL_BlitSurface( - SDL_Surface *src, SDL_Surface *dst, int width, int height, bool ckey) -{ - if(width == -1) - width = src->w; - if(height == -1) - height = src->h; - width = min(src->w, dst->w); - height = min(src->h, dst->h); - - /* Types of blits: - * RGBA->RGBA, same format without colorkey - * RGBA->RGBA, same format with colorkey - * PAL->PAL; ignore colorkey flag - * RGBA->RGBA different format without colorkey - * RGBA->RGBA different format with colorkey - * PAL->RGBA with colorkey - * PAL->RGBA without colorkey - */ - if( src->format->BytesPerPixel == dst->format->BytesPerPixel && - src->format->Rmask == dst->format->Rmask && - src->format->Gmask == dst->format->Gmask && - src->format->Bmask == dst->format->Bmask && - src->format->Amask == dst->format->Amask ) - { - /* RGBA->RGBA with the same format, or PAL->PAL. Simple copy. */ - blit_same_type(src, dst, width, height); - } - - else if( src->format->BytesPerPixel != 1 && dst->format->BytesPerPixel != 1 ) - { - /* RGBA->RGBA with different formats. */ - blit_rgba_to_rgba(src, dst, width, height); - } - - else if( src->format->BytesPerPixel == 1 && dst->format->BytesPerPixel != 1 ) - { - /* PAL->RGBA. */ - blit_generic(src, dst, width, height); - } - else - /* We don't do RGBA->PAL. */ - ASSERT(0); - - /* - * The destination surface may be larger than the source. For example, we may be - * blitting a 200x200 image onto a 256x256 surface for OpenGL. Normally, that extra - * space isn't actually used; we'll only render the image space. However, bilinear - * filtering will cause the lines of pixels at 201x... and ...x201 to be visible. We - * need to make sure those pixels make sense. - * - * Previously, we just cleared the image to transparent or the color key. This - * has two problems. First, we may not have space for a color key (an image with - * 256 non-transparent palette colors). Second, that's not completely correct; - * it'll force the outside border of the image to filter to transparent. If the image - * is being tiled with another image, that may leave seams. - * - * (In some cases, filtering to transparent is preferable, particularly when displaying - * a sprite in perspective. If you want that, add blank space to the image explicitly.) - * - * Copy the last column (200x... -> 201x...), then the last row (...x200 -> ...x201). - */ - - if( width < dst->w ) - { - /* Duplicate the last column. */ - int offset = dst->format->BytesPerPixel * (width-1); - Uint8 *p = (Uint8 *) dst->pixels + offset; - - for( int y = 0; y < height; ++y ) - { - Uint32 pixel = decodepixel( p, dst->format->BytesPerPixel ); - encodepixel( p+dst->format->BytesPerPixel, dst->format->BytesPerPixel, pixel ); - - p += dst->pitch; - } - } - - - if( height < dst->h ) - { - /* Duplicate the last row. */ - char *srcp = (char *) dst->pixels; - srcp += dst->pitch * (height-1); - memcpy( srcp + dst->pitch, srcp, dst->pitch ); - } -} - -/* - * This converts an image to a special 8-bit paletted format. The palette is set up - * so that palette indexes look like regular, packed components. - * - * For example, an image with 8 bits of grayscale and 0 bits of alpha has a palette - * that looks like { 0,0,0,255 }, { 1,1,1,255 }, { 2,2,2,255 }, ... { 255,255,255,255 }. - * This results in index components that can be treated as grayscale values. - * - * An image with 2 bits of grayscale and 2 bits of alpha look like - * { 0,0,0,0 }, { 85,85,85,0 }, { 170,170,170,0 }, { 255,255,255,0 }, - * { 0,0,0,85 }, { 85,85,85,85 }, { 170,170,170,85 }, { 255,255,255,85 }, ... - * - * This results in index components that can be pulled apart like regular packed - * values: the first two bits of the index are the grayscale component, and the next - * two bits are the alpha component. - * - * This gives us a generic way to handle arbitrary 8-bit texture formats. - */ -SDL_Surface *mySDL_Palettize( SDL_Surface *src_surf, int GrayBits, int AlphaBits ) -{ - AlphaBits = min( AlphaBits, 8-src_surf->format->Aloss ); - - const int TotalBits = GrayBits + AlphaBits; - ASSERT( TotalBits <= 8 ); - - SDL_Surface *dst_surf = SDL_CreateRGBSurfaceSane(SDL_SWSURFACE, src_surf->w, src_surf->h, - 8, 0,0,0,0 ); - - /* Set up the palette. */ - const int TotalColors = 1 << TotalBits; - const int Ivalues = 1 << GrayBits; // number of intensity values - const int Ishift = 0; // intensity shift - const int Imask = ((1 << GrayBits) - 1) << Ishift; // intensity mask - const int Iloss = 8-GrayBits; - - const int Avalues = 1 << AlphaBits; // number of alpha values - const int Ashift = GrayBits; // alpha shift - const int Amask = ((1 << AlphaBits) - 1) << Ashift; // alpha mask - const int Aloss = 8-AlphaBits; - - for( int index = 0; index < TotalColors; ++index ) - { - const int I = (index & Imask) >> Ishift; - const int A = (index & Amask) >> Ashift; - - int ScaledI; - if( Ivalues == 1 ) - ScaledI = 255; // if only one intensity value, always fullbright - else - ScaledI = clamp( int(roundf(I * (255.0f / (Ivalues-1)))), 0, 255 ); - - int ScaledA; - if( Avalues == 1 ) - ScaledA = 255; // if only one alpha value, always opaque - else - ScaledA = clamp( int(roundf(A * (255.0f / (Avalues-1)))), 0, 255 ); - - SDL_Color c; - c.r = Uint8(ScaledI); - c.g = Uint8(ScaledI); - c.b = Uint8(ScaledI); - c.unused = Uint8(ScaledA); - - SDL_SetColors( dst_surf, &c, index, 1); - } - - const char *src = (const char *) src_surf->pixels; - const char *dst = (const char *) dst_surf->pixels; - - int height = src_surf->h; - int width = src_surf->w; - - /* Bytes to skip at the end of a line. */ - const int srcskip = src_surf->pitch - width*src_surf->format->BytesPerPixel; - const int dstskip = dst_surf->pitch - width*dst_surf->format->BytesPerPixel; - - while( height-- ) - { - int x = 0; - while( x++ < width ) - { - unsigned int pixel = decodepixel((Uint8 *) src, src_surf->format->BytesPerPixel); - - Uint8 colors[4]; - mySDL_GetRGBAV(pixel, src_surf, colors); - - int Ival = 0; - Ival += colors[0]; - Ival += colors[1]; - Ival += colors[2]; - Ival /= 3; - - pixel = (Ival >> Iloss) << Ishift | - (colors[3] >> Aloss) << Ashift; - - /* Store it. */ - *((Uint8 *) dst) = Uint8(pixel); - - src += src_surf->format->BytesPerPixel; - dst += dst_surf->format->BytesPerPixel; - } - - src += srcskip; - dst += dstskip; - } - - return dst_surf; -} int RWRageFile_Seek( struct SDL_RWops *context, int offset, int whence ) { @@ -1147,20 +190,6 @@ void OpenRWops( SDL_RWops *rw, CString *sBuf ) rw->close = RWString_Close; } -SDL_Surface *mySDL_MakeDummySurface( int height, int width ) -{ - SDL_Surface *ret_image = SDL_CreateRGBSurfaceSane( - SDL_SWSURFACE, width, height, 8, 0,0,0,0); - ASSERT( ret_image != NULL ); - - SDL_Color pink = { 0xFF, 0x10, 0xFF, 0xFF }; - mySDL_SetPalette( ret_image, &pink, 0, 1 ); - - memset( ret_image->pixels, 0, ret_image->h*ret_image->pitch ); - - return ret_image; -} - /* SDL sometimes fails to set an error, in which case we get the null string. We * sometimes use that as a sentinel return value. This function returns "(none)" * if no error is set. */ @@ -1172,123 +201,93 @@ CString mySDL_GetError() return error; } -/* When we receive surfaces from other libraries, the "unused" palette entry is - * undefined. We use it for alpha, so set it to 255. */ -void mySDL_FixupPalettedAlpha( SDL_Surface *img ) + +void mySDL_WM_SetIcon( CString sIconFile ) { - if( img->format->BitsPerPixel != 8 ) - return; - - for( int index = 0; index < img->format->palette->ncolors; ++index ) - img->format->palette->colors[index].unused = 0xFF; - - /* If the surface had a color key set, transfer it. */ - if( img->flags & SDL_SRCCOLORKEY ) +#if !defined(DARWIN) + if( sIconFile.empty() ) { - img->flags &= ~SDL_SRCCOLORKEY; - ASSERT_M( (int)img->format->colorkey < img->format->palette->ncolors, ssprintf("%i",img->format->colorkey) ); - img->format->palette->colors[ img->format->colorkey ].unused = 0; - } -} - -void mySDL_AddColorKey( SDL_Surface *img, Uint32 color ) -{ - ASSERT_M( img->format->BitsPerPixel == 8, ssprintf( "%i", img->format->BitsPerPixel) ); - ASSERT_M( color < (Uint32) img->format->palette->ncolors, ssprintf("%i < %i", color, img->format->palette->ncolors ) ); - img->format->palette->colors[ color ].unused = 0; -} - -/* HACK: Some banners and textures have #F800F8 as the color key. Search the edge - * it; if we find it, use that as the color key. */ -static bool ImageUsesOffHotPink( const SDL_Surface *img ) -{ - Uint32 OffHotPink; - if( !mySDL_MapRGBExact( img->format, 0xF8, 0, 0xF8, OffHotPink ) ) - return false; - - const uint8_t *p = (uint8_t*) img->pixels; - for( int x = 0; x < img->w; ++x ) - { - Uint32 val = decodepixel( p, img->format->BytesPerPixel ); - if( val == OffHotPink ) - return true; - p += img->format->BytesPerPixel; - } - - p = (uint8_t*)img->pixels; - p += img->pitch * (img->h-1); - for( int i=0; i < img->w; i++ ) - { - Uint32 val = decodepixel( p, img->format->BytesPerPixel ); - if( val == OffHotPink ) - return true; - p += img->format->BytesPerPixel; - } - return false; -} - -/* Set #FF00FF and #F800F8 to transparent. img may be reallocated if it has no alpha - * bits. */ -void ApplyHotPinkColorKey( SDL_Surface *&img ) -{ - if( img->format->BitsPerPixel == 8 ) - { - Uint32 color; - if( mySDL_MapRGBExact( img->format, 0xF8, 0, 0xF8, color ) ) - mySDL_AddColorKey( img, color ); - if( mySDL_MapRGBExact( img->format, 0xFF, 0, 0xFF, color ) ) - mySDL_AddColorKey( img, color ); + SDL_WM_SetIcon(NULL, NULL); return; } - /* RGBA. */ - /* Make sure we have alpha. */ - if( !img->format->Amask ) + RageSurface *srf = RageSurfaceUtils::LoadFile(sIconFile); + if( srf == NULL ) + return; + + /* Windows icons are 32x32 and SDL can't resize them for us, which + * causes mask corruption. (Actually, the above icon *is* 32x32; + * this is here just in case it changes.) */ + RageSurfaceUtils::ConvertSurface(srf, srf->w, srf->h, + 32, 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF); + zoomSurface(srf, 32, 32); + + SDL_Surface *sdl_srf = SDLSurfaceFromRageSurface( srf ); + delete srf; + + SDL_SetAlpha( sdl_srf, SDL_SRCALPHA, SDL_ALPHA_OPAQUE ); + SDL_WM_SetIcon( sdl_srf, NULL /* derive from alpha */ ); + SDL_FreeSurface( sdl_srf ); +#endif +} + +/* Create an SDL surface from a RageSurface. */ +SDL_Surface *SDLSurfaceFromRageSurface( RageSurface *surf ) +{ + /* SDL will free the data with free(), so we can't just give it surf->pixels. */ + char *buf = (char *) malloc( surf->pitch * surf->h ); + if( buf == NULL ) + RageException::Throw( "malloc(%i): %s", surf->pitch * surf->h, strerror(errno) ); + memcpy( buf, surf->pixels, surf->pitch * surf->h ); + SDL_Surface *ret = SDL_CreateRGBSurfaceFrom( buf, + surf->w, surf->h, surf->fmt.BitsPerPixel, + surf->pitch, surf->fmt.Rmask, surf->fmt.Gmask, surf->fmt.Bmask, surf->fmt.Amask ); + + /* Copy the palette. */ + if( surf->format->BytesPerPixel == 1 ) { - /* We don't have any alpha. Try to enable it without copying. */ - int usable_bits = (1<format->BitsPerPixel)-1; - usable_bits &= ~img->format->Rmask; - usable_bits &= ~img->format->Gmask; - usable_bits &= ~img->format->Bmask; - - for( int i = 0; img->format->Amask == 0 && i < 32; ++i ) + ASSERT( sizeof(RageSurfaceColor) == sizeof(SDL_Color) ); + memcpy( ret->format->palette->colors, surf->fmt.palette->colors, + 256 * sizeof(RageSurfaceColor) ); + } + + /* XXX: if we have one alpha value, transfer to colorkey */ + return ret; +} + +RageSurface *RageSurfaceFromSDLSurface( SDL_Surface *surf ) +{ + uint8_t *buf = new uint8_t[surf->pitch * surf->h]; + memcpy( buf, surf->pixels, surf->pitch * surf->h ); + RageSurface *ret = CreateSurfaceFrom( + surf->w, surf->h, surf->format->BitsPerPixel, + surf->format->Rmask, surf->format->Gmask, surf->format->Bmask, surf->format->Amask, + buf, surf->pitch ); + + /* Copy the palette. */ + if( surf->format->BytesPerPixel == 1 ) + { + ASSERT( sizeof(RageSurfaceColor) == sizeof(SDL_Color) ); + memcpy( ret->fmt.palette->colors, surf->format->palette->colors, + 256 * sizeof(RageSurfaceColor) ); + } + + /* Convert SDL "colorkey" to an alpha palette entry. 's "unused" palette entry is undefined. We use it for alpha, so set it to 255. */ + if( surf->format->BitsPerPixel == 8 ) + { + for( int index = 0; index < ret->fmt.palette->ncolors; ++index ) + ret->fmt.palette->colors[index].a = 0xFF; + + /* If the surface had a color key set, transfer it. */ + if( surf->flags & SDL_SRCCOLORKEY ) { - if( usable_bits & (1<format->Amask = 1<format->Aloss = 7; - img->format->Ashift = (Uint8) i; - } - } - - if( img->format->Amask == 0 ) - ConvertSDLSurface( img, img->w, img->h, - 32, 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF ); - } - - Uint32 HotPink; - - bool bHaveColorKey; - if( ImageUsesOffHotPink(img) ) - bHaveColorKey = mySDL_MapRGBExact( img->format, 0xF8, 0, 0xF8, HotPink ); - else - bHaveColorKey = mySDL_MapRGBExact( img->format, 0xFF, 0, 0xFF, HotPink ); - if( !bHaveColorKey ) - return; - - for( int y = 0; y < img->h; ++y ) - { - Uint8 *row = (Uint8 *)img->pixels + img->pitch*y; - - for( int x = 0; x < img->w; ++x ) - { - Uint32 val = decodepixel( row, img->format->BytesPerPixel ); - if( val == HotPink ) - encodepixel( row, img->format->BytesPerPixel, 0 ); - - row += img->format->BytesPerPixel; + ASSERT_M( (int)surf->format->colorkey < surf->format->palette->ncolors, ssprintf("%i",surf->format->colorkey) ); + int ckey = surf->format->colorkey; + ret->fmt.palette->colors[ ckey ].a = 0; } } + + return ret; } /* diff --git a/stepmania/src/SDL_utils.h b/stepmania/src/SDL_utils.h index 12e24da8fe..f1f64e076e 100644 --- a/stepmania/src/SDL_utils.h +++ b/stepmania/src/SDL_utils.h @@ -10,78 +10,27 @@ #include "SDL_syswm.h" // for SDL_SysWMinfo #undef Font #undef Screen - -Uint32 decodepixel(const Uint8 *p, int bpp); -void encodepixel(Uint8 *p, int bpp, Uint32 pixel); - -void mySDL_GetRawRGBAV(Uint32 pixel, const SDL_Surface *src, Uint8 *v); -void mySDL_GetRawRGBAV(const Uint8 *p, const SDL_Surface *src, Uint8 *v); -void mySDL_GetRGBAV(Uint32 pixel, const SDL_Surface *src, Uint8 *v); -void mySDL_GetRGBAV(const Uint8 *p, const SDL_Surface *src, Uint8 *v); - -Uint32 mySDL_SetRawRGBAV(const SDL_PixelFormat *fmt, const Uint8 *v); -void mySDL_SetRawRGBAV(Uint8 *p, const SDL_Surface *src, const Uint8 *v); -Uint32 mySDL_SetRGBAV(const SDL_PixelFormat *fmt, const Uint8 *v); -void mySDL_SetRGBAV(Uint8 *p, const SDL_Surface *src, const Uint8 *v); - -void mySDL_GetBitsPerChannel(const SDL_PixelFormat *fmt, Uint32 bits[4]); -void mySDL_SetPalette( SDL_Surface *dst, const SDL_Color *colors, int start, int cnt ); -void CopySDLSurface( SDL_Surface *src, SDL_Surface *dest ); -bool ConvertSDLSurface( SDL_Surface *src, SDL_Surface *&dst, - int width, int height, int bpp, - Uint32 R, Uint32 G, Uint32 B, Uint32 A ); -void ConvertSDLSurface(SDL_Surface *&image, - int width, int height, int bpp, - Uint32 R, Uint32 G, Uint32 B, Uint32 A); -SDL_Surface *SDL_CreateRGBSurfaceSane - (Uint32 flags, int width, int height, int depth, - Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask); - -void FixHiddenAlpha(SDL_Surface *img); +struct RageSurface; /* Check for an event; return true if one was waiting. */ bool SDL_GetEvent(SDL_Event &event, int mask); /* Change the event state without dropping extra events. */ -Uint8 mySDL_EventState(Uint8 type, int state); +uint8_t mySDL_EventState(uint8_t type, int state); void mySDL_GetAllEvents(vector &events); void mySDL_PushEvents(vector &events); -/* The surface contains no transparent pixels and/or never uses its color - * key, so it doesn't need any alpha bits at all. */ -#define TRAIT_NO_TRANSPARENCY 0x0001 /* 0alpha */ -/* The surface contains only transparent values of 0 or 1; no translucency. - * It only needs one bit of alpha. */ -#define TRAIT_BOOL_TRANSPARENCY 0x0002 /* 1alpha */ -int FindSurfaceTraits(const SDL_Surface *img); - - -void mySDL_WM_SetIcon( CString sIconFile ); - -bool mySDL_SaveSurface( SDL_Surface *img, CString file ); -SDL_Surface *mySDL_LoadSurface( CString file ); - -bool mySDL_MapRGBExact( SDL_PixelFormat *fmt, Uint8 R, Uint8 G, Uint8 B, Uint32 &color ); - -void mySDL_BlitTransform( const SDL_Surface *src, SDL_Surface *dst, - const float fCoords[8] /* TL, BR, BL, TR */ ); -void mySDL_BlitSurface( - SDL_Surface *src, SDL_Surface *dst, int width, int height, bool ckey); - -SDL_Surface *mySDL_Palettize( SDL_Surface *src_surf, int GrayBits, int AlphaBits ); - -void mySDL_FixupPalettedAlpha( SDL_Surface *img ); -void mySDL_AddColorKey( SDL_Surface *img, Uint32 color ); -void ApplyHotPinkColorKey( SDL_Surface *&img ); - class RageFile; void OpenRWops( SDL_RWops *rw, RageFile *f ); void OpenRWops( SDL_RWops *rw, CString *sBuf ); -SDL_Surface *mySDL_MakeDummySurface( int height, int width ); CString mySDL_GetError(); +void mySDL_WM_SetIcon( CString sIconFile ); +SDL_Surface *SDLSurfaceFromRageSurface( RageSurface *surf ); +RageSurface *RageSurfaceFromSDLSurface( SDL_Surface *surf ); + #endif /* diff --git a/stepmania/src/Song.cpp b/stepmania/src/Song.cpp index 350b888c6e..b6d1b3c861 100644 --- a/stepmania/src/Song.cpp +++ b/stepmania/src/Song.cpp @@ -21,6 +21,7 @@ #include "arch/arch.h" #include "RageFile.h" #include "RageFileManager.h" +#include "RageSurface.h" #include "NoteDataUtil.h" #include "SDL_utils.h" #include "ProfileManager.h" @@ -697,7 +698,7 @@ void Song::TidyUpData() CString sPath = m_sSongDir + arrayImages[i]; /* We only care about the dimensions. */ - SDL_Surface *img = RageSurfaceUtils::LoadFile( sPath, true ); + RageSurface *img = RageSurfaceUtils::LoadFile( sPath, true ); if( !img ) { LOG->Trace("Couldn't load '%s': %s", sPath.c_str(), SDL_GetError()); @@ -706,7 +707,7 @@ void Song::TidyUpData() const int width = img->w; const int height = img->h; - SDL_FreeSurface( img ); + delete img; if( !HasBackground() && width >= 320 && height >= 240 ) {