Optimized gradient when top color is the same as the bottom one.
[supertux.git] / src / screen / drawing_context.cpp
index efee7a5..13d260d 100644 (file)
@@ -1,8 +1,26 @@
-#include <assert.h>
-#include "drawing_context.h"
-
-#include <iostream>
+//  $Id$
+//
+//  SuperTux -  A Jump'n Run
+//  Copyright (C) 2004 Matthias Braun <matze@braunis.de
+//
+//  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 <algorithm>
+#include <cassert>
+#include <iostream>
+
+#include "drawing_context.h"
 #include "texture.h"
 #include "globals.h"
 #include "font.h"
@@ -17,7 +35,7 @@ DrawingContext::~DrawingContext()
 
 void
 DrawingContext::draw_surface(const Surface* surface, const Vector& position,
-    int layer)
+    int layer, Uint32 drawing_effect)
 {
   assert(surface != 0);
   
@@ -27,13 +45,14 @@ DrawingContext::draw_surface(const Surface* surface, const Vector& position,
   request.layer = layer;
   request.request_data = const_cast<Surface*> (surface);
   request.pos = transform.apply(position);
+  request.drawing_effect = drawing_effect;
 
   drawingrequests.push_back(request);
 }
 
 void
 DrawingContext::draw_surface_part(const Surface* surface, const Vector& source,
-    const Vector& size, const Vector& dest, int layer)
+    const Vector& size, const Vector& dest, int layer, Uint32 drawing_effect)
 {
   assert(surface != 0);
 
@@ -42,6 +61,7 @@ DrawingContext::draw_surface_part(const Surface* surface, const Vector& source,
   request.type = SURFACE_PART;
   request.layer = layer;
   request.pos = transform.apply(dest);
+  request.drawing_effect = drawing_effect;
   
   SurfacePartRequest* surfacepartrequest = new SurfacePartRequest();
   surfacepartrequest->size = size;
@@ -114,7 +134,7 @@ DrawingContext::draw_filled_rect(const Vector& topleft, const Vector& size,
 
   request.type = FILLRECT;
   request.layer = layer;
-  request.pos = topleft;
+  request.pos = transform.apply(topleft);
 
   FillRectRequest* fillrectrequest = new FillRectRequest;
   fillrectrequest->size = size;
@@ -133,7 +153,8 @@ DrawingContext::draw_surface_part(DrawingRequest& request)
   surfacepartrequest->surface->impl->draw_part(
       surfacepartrequest->source.x, surfacepartrequest->source.y,
       request.pos.x, request.pos.y,
-      surfacepartrequest->size.x, surfacepartrequest->size.y, 255);
+      surfacepartrequest->size.x, surfacepartrequest->size.y, 255,
+      request.drawing_effect);
 
   delete surfacepartrequest;
 }
@@ -160,15 +181,22 @@ DrawingContext::draw_gradient(DrawingRequest& request)
   else
   {
 #endif
-    float redstep = (float(bottom.red)-float(top.red)) / float(screen->h);
-    float greenstep = (float(bottom.green)-float(top.green)) / float(screen->h);
-    float bluestep = (float(bottom.blue) - float(top.blue)) / float(screen->h);
-
-    for(float y = 0; y < screen->h; y += 2)
-      fillrect(0, (int)y, screen->w, 2,
-          int(float(top.red) + redstep * y),
-          int(float(top.green) + greenstep * y),
-          int(float(top.blue) + bluestep * y), 255);
+    if(&top == &bottom)
+      {
+      fillrect(0, 0, screen->w, screen->h, top.red, top.green, top.blue);
+      }
+    else
+      {
+      float redstep = (float(bottom.red)-float(top.red)) / float(screen->h);
+      float greenstep = (float(bottom.green)-float(top.green)) / float(screen->h);
+      float bluestep = (float(bottom.blue) - float(top.blue)) / float(screen->h);
+
+      for(float y = 0; y < screen->h; y += 2)
+        fillrect(0, (int)y, screen->w, 2,
+            int(float(top.red) + redstep * y),
+            int(float(top.green) + greenstep * y),
+            int(float(top.blue) + bluestep * y), 255);
+      }
 #ifndef NOOPENGL
 
     }
@@ -263,7 +291,7 @@ DrawingContext::draw_filled_rect(DrawingRequest& request)
 void
 DrawingContext::do_drawing()
 {
-  std::sort(drawingrequests.begin(), drawingrequests.end());
+  std::stable_sort(drawingrequests.begin(), drawingrequests.end());
 
   for(DrawingRequests::iterator i = drawingrequests.begin();
       i != drawingrequests.end(); ++i) {
@@ -271,7 +299,7 @@ DrawingContext::do_drawing()
       case SURFACE:
       {
         const Surface* surface = (const Surface*) i->request_data;
-        surface->impl->draw(i->pos.x, i->pos.y, 255);
+        surface->impl->draw(i->pos.x, i->pos.y, 255, i->drawing_effect);
         break;
       }
       case SURFACE_PART: