+// $Id$
+//
+// SuperTux
+// Copyright (C) 2004 Tobias Glaesser <tobi.web@gmx.de>
//
-// C Implementation: texture
-//
-// Description:
-//
-//
-// Author: Tobias Glaesser <tobi.web@gmx.de>, (C) 2004
-//
-// Copyright: See COPYING file that comes with this distribution
-//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+// 02111-1307, USA.
#include <assert.h>
+#include <iostream>
#include "SDL.h"
#include "SDL_image.h"
#include "texture.h"
Surface::Surfaces Surface::surfaces;
-SurfaceData::SurfaceData(SDL_Surface* surf, int use_alpha_)
- : type(SURFACE), surface(surf), use_alpha(use_alpha_)
-{
+SurfaceData::SurfaceData(SDL_Surface* temp, int use_alpha_)
+ : type(SURFACE), surface(0), use_alpha(use_alpha_)
+{
+ // Copy the given surface and make sure that it is not stored in
+ // video memory
+ surface = SDL_CreateRGBSurface(temp->flags & (~SDL_HWSURFACE),
+ temp->w, temp->h,
+ temp->format->BitsPerPixel,
+ temp->format->Rmask,
+ temp->format->Gmask,
+ temp->format->Bmask,
+ temp->format->Amask);
+ if(!surface)
+ st_abort("No memory left.", "");
+ SDL_SetAlpha(temp,0,0);
+ SDL_BlitSurface(temp, NULL, surface, NULL);
}
SurfaceData::SurfaceData(const std::string& file_, int use_alpha_)
- : type(LOAD), file(file_), use_alpha(use_alpha_)
+ : type(LOAD), surface(0), file(file_), use_alpha(use_alpha_)
{
}
SurfaceData::SurfaceData(const std::string& file_, int x_, int y_, int w_, int h_, int use_alpha_)
- : type(LOAD_PART), file(file_), use_alpha(use_alpha_),
+ : type(LOAD_PART), surface(0), file(file_), use_alpha(use_alpha_),
x(x_), y(y_), w(w_), h(h_)
{
}
+SurfaceData::~SurfaceData()
+{
+ SDL_FreeSurface(surface);
+}
+
SurfaceImpl*
SurfaceData::create()
{
case LOAD_PART:
return new SurfaceSDL(file, x, y, w, h, use_alpha);
case SURFACE:
- return 0; //new SurfaceSDL(surface, use_alpha);
+ return new SurfaceSDL(surface, use_alpha);
}
assert(0);
}
case LOAD_PART:
return new SurfaceOpenGL(file, x, y, w, h, use_alpha);
case SURFACE:
- return 0; //new SurfaceOpenGL(surface, use_alpha);
+ return new SurfaceOpenGL(surface, use_alpha);
}
assert(0);
}
void
Surface::draw(float x, float y, Uint8 alpha, bool update)
{
- if (impl) impl->draw(x, y, alpha, update);
+ if (impl)
+ {
+ if (impl->draw(x, y, alpha, update) == -2)
+ reload();
+ }
}
void
Surface::draw_bg(Uint8 alpha, bool update)
{
- if (impl) impl->draw_bg(alpha, update);
+ if (impl)
+ {
+ if (impl->draw_bg(alpha, update) == -2)
+ reload();
+ }
}
void
Surface::draw_part(float sx, float sy, float x, float y, float w, float h, Uint8 alpha, bool update)
{
- if (impl) impl->draw_part(sx, sy, x, y, w, h, alpha, update);
+ if (impl)
+ {
+ if (impl->draw_part(sx, sy, x, y, w, h, alpha, update) == -2)
+ reload();
+ }
}
SDL_Surface*
return sdl_surface;
}
+//---------------------------------------------------------------------------
+
+SurfaceImpl::SurfaceImpl()
+{
+}
+
+SurfaceImpl::~SurfaceImpl()
+{
+ SDL_FreeSurface(sdl_surface);
+}
+
+SDL_Surface* SurfaceImpl::get_sdl_surface() const
+{
+ return sdl_surface;
+}
+
#ifndef NOOPENGL
SurfaceOpenGL::SurfaceOpenGL(SDL_Surface* surf, int use_alpha)
{
SurfaceOpenGL::~SurfaceOpenGL()
{
- SDL_FreeSurface(sdl_surface);
glDeleteTextures(1, &gl_texture);
}
h = power_of_two(surf->h),
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
- conv = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, surf->format->BitsPerPixel,
+ conv = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, surf->format->BitsPerPixel,
0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff);
#else
conv = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, surf->format->BitsPerPixel,
SDL_FreeSurface(conv);
}
-void
+int
SurfaceOpenGL::draw(float x, float y, Uint8 alpha, bool update)
{
float pw = power_of_two(w);
glDisable(GL_TEXTURE_2D);
glDisable(GL_BLEND);
- /* Avoid compiler warnings */
- if(update)
- {}
+ (void) update; // avoid compiler warning
+
+ return 0;
}
-void
+int
SurfaceOpenGL::draw_bg(Uint8 alpha, bool update)
{
float pw = power_of_two(w);
glDisable(GL_TEXTURE_2D);
- /* Avoid compiler warnings */
- if(update)
- {}
+ (void) update; // avoid compiler warning
+
+ return 0;
}
-void
+int
SurfaceOpenGL::draw_part(float sx, float sy, float x, float y, float w, float h, Uint8 alpha, bool update)
{
float pw = power_of_two(int(this->w));
/* Avoid compiler warnings */
if(update)
{}
+ return 0;
}
#endif
h = sdl_surface->h;
}
-void
+int
SurfaceSDL::draw(float x, float y, Uint8 alpha, bool update)
{
SDL_Rect dest;
dest.h = h;
if(alpha != 255) /* SDL isn't capable of this kind of alpha :( therefore we'll leave now. */
- return;
+ return -1;
SDL_SetAlpha(sdl_surface ,SDL_SRCALPHA,alpha);
- SDL_BlitSurface(sdl_surface, NULL, screen, &dest);
+ int ret = SDL_BlitSurface(sdl_surface, NULL, screen, &dest);
if (update == UPDATE)
SDL_UpdateRect(screen, dest.x, dest.y, dest.w, dest.h);
+
+ return ret;
}
-void
+int
SurfaceSDL::draw_bg(Uint8 alpha, bool update)
{
SDL_Rect dest;
if(alpha != 255)
SDL_SetAlpha(sdl_surface ,SDL_SRCALPHA,alpha);
- SDL_SoftStretch(sdl_surface, NULL, screen, &dest);
+
+ int ret = SDL_SoftStretch(sdl_surface, NULL, screen, &dest);
if (update == UPDATE)
SDL_UpdateRect(screen, dest.x, dest.y, dest.w, dest.h);
+
+ return ret;
}
-void
+int
SurfaceSDL::draw_part(float sx, float sy, float x, float y, float w, float h, Uint8 alpha, bool update)
{
SDL_Rect src, dest;
if(alpha != 255)
SDL_SetAlpha(sdl_surface ,SDL_SRCALPHA,alpha);
- SDL_BlitSurface(sdl_surface, &src, screen, &dest);
+ int ret = SDL_BlitSurface(sdl_surface, &src, screen, &dest);
if (update == UPDATE)
update_rect(screen, dest.x, dest.y, dest.w, dest.h);
+
+ return ret;
}
SurfaceSDL::~SurfaceSDL()
{
- SDL_FreeSurface(sdl_surface);
}
/* EOF */