X-Git-Url: https://git.verplant.org/?a=blobdiff_plain;f=lib%2Fvideo%2Fsurface.cpp;h=73dc131b4bf0b73b78bf7f28237746b5a21ca6e4;hb=1028ce017d6809007e39a8f7c034a0d62bfe3052;hp=b609f7a9b19c1c710924d5a4234d13c840158a01;hpb=580daade35c151e51a90560fe0cac8c7e1b05ca7;p=supertux.git diff --git a/lib/video/surface.cpp b/lib/video/surface.cpp index b609f7a9b..73dc131b4 100644 --- a/lib/video/surface.cpp +++ b/lib/video/surface.cpp @@ -26,6 +26,7 @@ #include "SDL_image.h" #include "../video/surface.h" +#include "../video/screen.h" #include "../app/globals.h" #include "../app/setup.h" @@ -196,6 +197,11 @@ Surface::reload() } } +void Surface::apply_mask(Color color) +{ +impl->apply_mask(color); +} + Surface::~Surface() { #ifdef DEBUG @@ -246,6 +252,32 @@ Surface::resize(int w_, int h_) } } +void +apply_filter_to_surface(SDL_Surface* surface, int filter, Color color) +{ +if(filter == MASK_FILTER) + { + Uint8 r,g,b,a; + SDL_Rect rect; + rect.w = rect.h = 1; + SDL_LockSurface(surface); + for(int x = 0; x < surface->w; x++) + for(int y = 0; y < surface->h; y++) + { +// SDL_LockSurface(surface); + SDL_GetRGBA(getpixel(surface,x,y), surface->format, &r,&g,&b,&a); +// SDL_UnlockSurface(surface); + if(a != 0) + { + putpixel(surface, x,y, color.map_rgba(surface)); +// rect.x = x; rect.y = y; +// SDL_FillRect(surface, &rect, color.map_rgba(surface)); + } + } + SDL_UnlockSurface(surface); + } +} + SDL_Surface* sdl_surface_part_from_file(const std::string& file, int x, int y, int w, int h, bool use_alpha) { @@ -568,7 +600,21 @@ SurfaceOpenGL::draw(float x, float y, Uint8 alpha, Uint32 effect) glBegin(GL_QUADS); - if(effect & VERTICAL_FLIP) + if(effect & VERTICAL_FLIP & HORIZONTAL_FLIP) + { + glTexCoord2f(0, 0); + glVertex2f((float)w+x, (float)h+y); + + glTexCoord2f((float)w / pw, 0); + glVertex2f(x, (float)h+y); + + glTexCoord2f((float)w / pw, (float)h / ph); + glVertex2f(x, y); + + glTexCoord2f(0, (float)h / ph); + glVertex2f((float)w+x, y); + } + else if(effect & VERTICAL_FLIP) { glTexCoord2f(0, 0); glVertex2f(x, (float)h+y); @@ -582,6 +628,20 @@ SurfaceOpenGL::draw(float x, float y, Uint8 alpha, Uint32 effect) glTexCoord2f(0, (float)h / ph); glVertex2f(x, y); } + else if(effect & HORIZONTAL_FLIP) + { + glTexCoord2f(0, 0); + glVertex2f((float)w+x, y); + + glTexCoord2f((float)w / pw, 0); + glVertex2f(x, y); + + glTexCoord2f((float)w / pw, (float)h / ph); + glVertex2f(x, (float)h+y); + + glTexCoord2f(0, (float)h / ph); + glVertex2f((float)w+x, (float)h+y); + } else { glTexCoord2f(0, 0); @@ -625,7 +685,21 @@ SurfaceOpenGL::draw_part(float sx, float sy, float x, float y, float w, float h, glBegin(GL_QUADS); - if(effect & VERTICAL_FLIP) + if(effect & VERTICAL_FLIP & HORIZONTAL_FLIP) + { + glTexCoord2f(sx / pw, (float)(sy+h) / ph); + glVertex2f((float)w+x, (float)h+y); + + glTexCoord2f((sx+w) / pw, (sy+h) / ph); + glVertex2f(x, (float)h+y); + + glTexCoord2f((float)(sx + w) / pw, sy / ph); + glVertex2f(x, y); + + glTexCoord2f(sx / pw, sy / ph); + glVertex2f((float)w+x, y); + } + else if(effect & VERTICAL_FLIP) { glTexCoord2f(sx / pw, sy / ph); glVertex2f(x, y); @@ -639,6 +713,20 @@ SurfaceOpenGL::draw_part(float sx, float sy, float x, float y, float w, float h, glTexCoord2f(sx / pw, (float)(sy+h) / ph); glVertex2f(x, h+y); } + else if(effect & HORIZONTAL_FLIP) + { + glTexCoord2f(sx / pw, sy / ph); + glVertex2f((float)w+x, y); + + glTexCoord2f((float)(sx + w) / pw, sy / ph); + glVertex2f(x, y); + + glTexCoord2f((sx+w) / pw, (sy+h) / ph); + glVertex2f(x, (float)h+y); + + glTexCoord2f(sx / pw, (float)(sy+h) / ph); + glVertex2f((float)w+x, (float)h+y); + } else { glTexCoord2f(sx / pw, (float)(sy+h) / ph); @@ -684,7 +772,21 @@ SurfaceOpenGL::draw_stretched(float x, float y, int sw, int sh, Uint8 alpha, Uin glBegin(GL_QUADS); - if(effect & VERTICAL_FLIP) + if(effect & VERTICAL_FLIP & HORIZONTAL_FLIP) + { + glTexCoord2f(0, 0); + glVertex2f((float)sw+x, (float)sh+y); + + glTexCoord2f((float)w / pw, 0); + glVertex2f(x, (float)sh+y); + + glTexCoord2f((float)w / pw, (float)h / ph); + glVertex2f(x, y); + + glTexCoord2f(0, (float)h / ph); + glVertex2f((float)sw+x, y); + } + else if(effect & VERTICAL_FLIP) { glTexCoord2f(0, 0); glVertex2f(x, (float)sh+y); @@ -698,6 +800,20 @@ SurfaceOpenGL::draw_stretched(float x, float y, int sw, int sh, Uint8 alpha, Uin glTexCoord2f(0, (float)h / ph); glVertex2f(x, y); } + else if(effect & HORIZONTAL_FLIP) + { + glTexCoord2f(0, 0); + glVertex2f((float)sw+x, y); + + glTexCoord2f((float)w / pw, 0); + glVertex2f(x, y); + + glTexCoord2f((float)w / pw, (float)h / ph); + glVertex2f(x, (float)sh+y); + + glTexCoord2f(0, (float)h / ph); + glVertex2f((float)sw+x, (float)sh+y); + } else { glTexCoord2f(0, 0); @@ -720,6 +836,16 @@ SurfaceOpenGL::draw_stretched(float x, float y, int sw, int sh, Uint8 alpha, Uin return 0; } +void +SurfaceOpenGL::apply_mask(Color color) +{ + ::apply_filter_to_surface(sdl_surface, MASK_FILTER, color); + create_gl(sdl_surface,&gl_texture); + + w = sdl_surface->w; + h = sdl_surface->h; +} + #endif SurfaceSDL::SurfaceSDL(SDL_Surface* surf, bool use_alpha) @@ -763,13 +889,29 @@ SurfaceSDL::draw(float x, float y, Uint8 alpha, Uint32 effect) if(effect & SEMI_TRANSPARENT) alpha = 128; - if(effect & VERTICAL_FLIP) // FIXME: feel free to replace this hack + if(effect & VERTICAL_FLIP & HORIZONTAL_FLIP) + { + // FIXME: this hack is damn slow. Just keep it cause it isn't that used. + for(float sx = 0; sx < w; sx++) + for(float sy = 0; sy < h; sy++) + if(draw_part(sx, sy, x+(w-sx), y+(h-sy), 1, 1, alpha, NONE_EFFECT) == -2) + return -2; + return 0; + } + else if(effect & VERTICAL_FLIP) // FIXME: feel free to replace this hack { for(float sy = 0; sy < h; sy++) if(draw_part(0, sy, x, y+(h-sy), w, 1, alpha, NONE_EFFECT) == -2) return -2; return 0; } + else if(effect & HORIZONTAL_FLIP) // FIXME: feel free to replace this hack + { + for(float sx = 0; sx < w; sx++) + if(draw_part(sx, 0, x+(w-sx), y, 1, h, alpha, NONE_EFFECT) == -2) + return -2; + return 0; + } if(alpha != 255) { @@ -820,13 +962,29 @@ SurfaceSDL::draw_part(float sx, float sy, float x, float y, float w, float h, Ui if(effect & SEMI_TRANSPARENT) alpha = 128; - if(effect & VERTICAL_FLIP) // FIXME: feel free to replace this hack + if(effect & VERTICAL_FLIP & HORIZONTAL_FLIP) + { + // FIXME: this hack is damn slow. Just keep it cause it isn't that used. + for(float sx_ = 0; sx_ < w; sx++) + for(float sy_ = 0; sy_ < h; sy++) + if(draw_part(sx_, sy_, sx+(w-sx_), sy+(h-sy_), 1, 1, alpha, NONE_EFFECT) == -2) + return -2; + return 0; + } + else if(effect & VERTICAL_FLIP) // FIXME: feel free to replace this hack { for(float sy_ = sy; sy_ < h; sy_++) if(draw_part(sx, sy_, x, y+(h-sy_), w, 1, alpha, NONE_EFFECT) == -2) return -2; return 0; } + else if(effect & HORIZONTAL_FLIP) // FIXME: feel free to replace this hack + { + for(float sx_ = 0; sx_ < w; sx_++) + if(draw_part(sx_, 0, sx+(w-sx_), sy, 1, h, alpha, NONE_EFFECT) == -2) + return -2; + return 0; + } if(alpha != 255) { @@ -890,6 +1048,15 @@ SurfaceSDL::draw_stretched(float x, float y, int sw, int sh, Uint8 alpha, Uint32 return ret; } +void +SurfaceSDL::apply_mask(Color color) +{ + ::apply_filter_to_surface(sdl_surface, MASK_FILTER, color); + + w = sdl_surface->w; + h = sdl_surface->h; +} + SurfaceSDL::~SurfaceSDL() {}