-Changed drawing model. Everything is handled through DrawingContext now and
authorMatthias Braun <matze@braunis.de>
Sun, 30 May 2004 01:08:50 +0000 (01:08 +0000)
committerMatthias Braun <matze@braunis.de>
Sun, 30 May 2004 01:08:50 +0000 (01:08 +0000)
 has an additional layer argument. So now you can paint into
 background/foreground as you like. The DrawingContext will queue app all
 commands, sort them and execute them in 1 go.

SVN-Revision: 1361

70 files changed:
data/CREDITS
src/Makefile.am
src/background.cpp
src/background.h
src/badguy.cpp
src/badguy.h
src/button.cpp
src/button.h
src/camera.cpp
src/camera.h
src/collision.cpp
src/collision.h
src/display_manager.cpp [deleted file]
src/display_manager.h [deleted file]
src/drawable.h [deleted file]
src/game_object.h
src/gameloop.cpp
src/gameloop.h
src/gameobjs.cpp
src/gameobjs.h
src/globals.cpp
src/globals.h
src/high_scores.cpp
src/intro.cpp
src/level.cpp
src/level.h
src/leveleditor.cpp
src/leveleditor.h
src/lispreader.cpp
src/lispreader.h
src/menu.cpp
src/menu.h
src/mousecursor.cpp
src/mousecursor.h
src/particlesystem.cpp
src/particlesystem.h
src/player.cpp
src/player.h
src/scene.h
src/screen.cpp [deleted file]
src/screen.h [deleted file]
src/screen/drawing_context.cpp [new file with mode: 0644]
src/screen/drawing_context.h [new file with mode: 0644]
src/screen/font.cpp [new file with mode: 0644]
src/screen/font.h [new file with mode: 0644]
src/screen/screen.cpp [new file with mode: 0644]
src/screen/screen.h [new file with mode: 0644]
src/screen/texture.cpp [new file with mode: 0644]
src/screen/texture.h [new file with mode: 0644]
src/setup.cpp
src/special.cpp
src/special.h
src/sprite.cpp
src/sprite.h
src/supertux.cpp
src/text.cpp [deleted file]
src/text.h [deleted file]
src/texture.cpp [deleted file]
src/texture.h [deleted file]
src/tile.cpp
src/tile.h
src/tilemap.cpp
src/tilemap.h
src/title.cpp
src/type.cpp
src/vector.h
src/world.cpp
src/world.h
src/worldmap.cpp
src/worldmap.h

index 1160e15..17d6a1b 100644 (file)
 -Contact
 
        Visit our webpage at
-http://super-tux.sf.net
+*http://super-tux.sf.net
 
        Or visit us directly at IRC:
-#supertux at irc.freenode.net
+*#supertux at irc.freenode.net
 
        Comments, ideas and suggestions
        go to our mailing list
-super-tux-devel@lists.sourceforge.net
+*super-tux-devel@lists.sourceforge.net
 
 
 
index 8c230e7..bbe3130 100644 (file)
@@ -1,6 +1,14 @@
 bin_PROGRAMS = supertux
 
 supertux_SOURCES = \
+screen/drawing_context.h \
+screen/drawing_context.cpp \
+screen/font.h \
+screen/font.cpp \
+screen/screen.h \
+screen/screen.cpp \
+screen/texture.cpp \
+screen/texture.h \
 lispwriter.h \
 lispwriter.cpp \
 badguy.cpp \
@@ -38,8 +46,6 @@ player.cpp \
 player.h \
 scene.cpp \
 scene.h \
-screen.cpp \
-screen.h \
 setup.cpp \
 setup.h \
 sound.cpp \
@@ -47,10 +53,6 @@ sound.h \
 special.cpp \
 special.h \
 supertux.cpp \
-text.cpp \
-text.h \
-texture.cpp \
-texture.h \
 timer.cpp \
 timer.h \
 title.cpp \
@@ -81,8 +83,6 @@ camera.cpp \
 camera.h \
 game_object.cpp \
 game_object.h \
-display_manager.h \
-display_manager.cpp \
 drawable.h \
 background.h \
 background.cpp \
index 975bff9..14584e9 100644 (file)
 
 #include "globals.h"
 #include "camera.h"
-#include "display_manager.h"
+#include "screen/drawing_context.h"
 
-Background::Background(DisplayManager& displaymanager)
+Background::Background()
+  : type(INVALID), image(0)
 {
-  displaymanager.add_drawable(this, LAYER_BACKGROUND0);
 }
 
 Background::~Background()
 {
+  delete image;
 }
 
 void
@@ -37,34 +38,39 @@ Background::action(float)
 }
 
 void
-Background::set_image(Surface* image, float speed)
+Background::set_image(const std::string& name, float speed)
 {
-  bgtype = BACKGROUND_IMAGE;
-  this->image = image;
+  type = IMAGE;
   this->speed = speed;
+
+  delete image;
+  image = new Surface(datadir + "/images/background/" + name, IGNORE_ALPHA);
 }
 
 void
 Background::set_gradient(Color top, Color bottom)
 {
-  bgtype = BACKGROUND_GRADIENT;
+  type = GRADIENT;
   gradient_top = top;
   gradient_bottom = bottom;
 }
 
 void
-Background::draw(Camera& viewport, int )
+Background::draw(DrawingContext& context)
 {
-  if(bgtype == BACKGROUND_GRADIENT) {
-    drawgradient(gradient_top, gradient_bottom);
-  } else if(bgtype == BACKGROUND_IMAGE) {
-    int sx = int(-viewport.get_translation().x * float(speed/100.))
+  if(type == GRADIENT) {
+    context.draw_gradient(gradient_top, gradient_bottom, LAYER_BACKGROUND0);
+  } else if(type == IMAGE) {
+    int sx = int(-context.get_translation().x * float(speed/100.))
       % image->w - image->w;
-    int sy = int(-viewport.get_translation().y * float(speed/100.))
+    int sy = int(-context.get_translation().y * float(speed/100.))
       % image->h - image->h;
+    context.push_transform();
+    context.set_translation(Vector(0, 0));
     for(int x = sx; x < screen->w; x += image->w)
       for(int y = sy; y < screen->h; y += image->h)
-        image->draw(x, y);
+        context.draw_surface(image, Vector(x, y), LAYER_BACKGROUND0);
+    context.pop_transform();
   }
 }
 
index 45af0e0..c441c50 100644 (file)
 #ifndef __BACKGROUND_H__
 #define __BACKGROUND_H__
 
-#include "texture.h"
+#include "screen/texture.h"
+#include "screen/drawing_context.h"
 #include "game_object.h"
-#include "drawable.h"
-
-enum {
-  BACKGROUND_GRADIENT,
-  BACKGROUND_IMAGE
-};
 
 class DisplayManager;
 
-class Background : public GameObject, public Drawable
+class Background : public GameObject
 {
 public:
-  Background(DisplayManager& displaymanager);
+  Background();
   virtual ~Background();
 
-  void set_image(Surface* image, float bkgd_speed);
+  void set_image(const std::string& name, float bkgd_speed);
 
   void set_gradient(Color top, Color bottom);
 
   virtual void action(float elapsed_time);
 
-  virtual void draw(Camera& viewport, int layer);
+  virtual void draw(DrawingContext& context);
 
 private:
-  int bgtype;
+  enum Type {
+    INVALID, GRADIENT, IMAGE      
+  };
+  
+  Type type;
   float speed;
   Surface* image;
   Color gradient_top, gradient_bottom;
index c075dd1..87ef1b7 100644 (file)
 #include "globals.h"
 #include "defines.h"
 #include "badguy.h"
-#include "scene.h"
-#include "screen.h"
-#include "world.h"
 #include "tile.h"
 #include "resources.h"
 #include "sprite_manager.h"
-#include "gameloop.h"
-#include "display_manager.h"
-#include "lispwriter.h"
+#include "world.h"
 #include "camera.h"
+#include "lispwriter.h"
+#include "level.h"
 
 Sprite* img_mriceblock_flat_left;
 Sprite* img_mriceblock_flat_right;
@@ -158,12 +155,9 @@ std::string badguykind_to_string(BadGuyKind kind)
     }
 }
 
-BadGuy::BadGuy(DisplayManager& display_manager, BadGuyKind kind_,
-    LispReader& lispreader)
+BadGuy::BadGuy(BadGuyKind kind_, LispReader& lispreader)
   : removable(false), squishcount(0)
 {
-  display_manager.add_drawable(this, LAYER_OBJECTS);
-
   lispreader.read_float("x", &start_position.x);
   lispreader.read_float("y", &start_position.y);
 
@@ -175,11 +169,9 @@ BadGuy::BadGuy(DisplayManager& display_manager, BadGuyKind kind_,
   init();
 }
 
-BadGuy::BadGuy(DisplayManager& display_manager, BadGuyKind kind_,
-    float x, float y)
+BadGuy::BadGuy(BadGuyKind kind_, float x, float y)
+  : removable(false), squishcount(0)
 {
-  display_manager.add_drawable(this, LAYER_OBJECTS);
-
   start_position.x = x;
   start_position.y = y;
   stay_on_platform = false;
@@ -662,8 +654,9 @@ BadGuy::action_fish(double elapsed_time)
   static const int WAITTIME = 1000;
     
   // go in wait mode when back in water
-  if(dying == DYING_NOT && gettile(base.x, base.y+ base.height)->water
-        && physic.get_velocity_y() <= 0 && mode == NORMAL)
+  if(dying == DYING_NOT 
+      && gettile(base.x, base.y+ base.height)->attributes & Tile::WATER
+      && physic.get_velocity_y() <= 0 && mode == NORMAL)
     {
       mode = FISH_WAIT;
       set_sprite(0, 0);
@@ -866,7 +859,6 @@ BadGuy::action_walkingtree(double elapsed_time)
     remove_me();
 }
 
-
 void
 BadGuy::action(float elapsed_time)
 {
@@ -981,27 +973,24 @@ BadGuy::action(float elapsed_time)
 }
 
 void
-BadGuy::draw(Camera& viewport, int)
+BadGuy::draw(DrawingContext& context)
 {
-  float scroll_x = viewport.get_translation().x;
-  float scroll_y = viewport.get_translation().y;
-
-  // Don't try to draw stuff that is outside of the screen
-  if(base.x <= scroll_x - base.width || base.x >= scroll_x + screen->w)
+  Sprite* sprite = (dir == LEFT) ? sprite_left : sprite_right;
+  if(sprite == 0)
     return;
-  
-  if(sprite_left == 0 || sprite_right == 0)
-    {
-      return;
-    }
 
+  sprite->draw(context, Vector(base.x, base.y), LAYER_OBJECTS);
+#if 0
   Sprite* sprite = (dir == LEFT) ? sprite_left : sprite_right;
   if(dying == DYING_FALLING && physic.get_velocity_y() < 0)
     sprite->draw(viewport.world2screen(Vector(base.x, base.y)), SD_VERTICAL_FLIP);
   else
     sprite->draw(viewport.world2screen(Vector(base.x, base.y)));
+#endif
 
-  if (debug_mode)
+  float scroll_x = context.get_translation().x;
+  float scroll_y = context.get_translation().y;
+  if(debug_mode)
     fillrect(base.x - scroll_x, base.y - scroll_y, base.width, base.height, 75,0,75, 150);
 }
 
index f5cd806..d1a6b84 100644 (file)
 #define SUPERTUX_BADGUY_H
 
 #include "SDL.h"
-#include "defines.h"
-#include "bitmask.h"
-#include "type.h"
 #include "timer.h"
-#include "texture.h"
+#include "screen/texture.h"
 #include "physic.h"
-#include "collision.h"
 #include "sprite.h"
 #include "moving_object.h"
-#include "drawable.h"
+#include "collision.h"
 #include "serializable.h"
 
 /* Bad guy kinds: */
@@ -62,7 +58,7 @@ void free_badguy_gfx();
 class Player;
 
 /* Badguy type: */
-class BadGuy : public MovingObject, public Drawable, public Serializable
+class BadGuy : public MovingObject, public Serializable
 {
 public:
   /* Enemy modes: */
@@ -118,14 +114,14 @@ private:
   int animation_offset;
 
 public:
-  BadGuy(DisplayManager& display_manager, BadGuyKind kind, float x, float y);
-  BadGuy(DisplayManager& display_manager, BadGuyKind kind, LispReader& reader);
+  BadGuy(BadGuyKind kind, float x, float y);
+  BadGuy(BadGuyKind kind, LispReader& reader);
   virtual ~BadGuy();
 
   virtual void write(LispWriter& writer);
 
   virtual void action(float frame_ratio);
-  virtual void draw(Camera& viewport, int layer);
+  virtual void draw(DrawingContext& context);
   virtual void collision(const MovingObject& other, int type);
 
   void collision(void* p_c_object, int c_object,
index 3c1d083..15b2be1 100644 (file)
 #include <string.h>
 #include <stdlib.h>
 #include "setup.h"
-#include "screen.h"
+#include "screen/screen.h"
 #include "globals.h"
 #include "button.h"
 #include "camera.h"
 
+// TODO
+#if 0
+
 Timer Button::popup_timer;
 
-Button::Button(std::string icon_file, std::string ninfo, SDLKey nshortcut, int x, int y, int mw, int mh)
+Button::Button(Surface* button_image, const std::string& ninfo,
+    SDLKey nshortcut, int x, int y, int mw, int mh)
 {
   popup_timer.init(false);
 
-  add_icon(icon_file,mw,mh);
+  if(button_image)
+    icon.push_back(button_image);
+
+  info = ninfo;
+
+  shortcut = nshortcut;
+
+  rect.x = x;
+  rect.y = y;
+  rect.w = icon[0]->w;
+  rect.h = icon[0]->h;
+  tag = -1;
+  state = BUTTON_NONE;
+  show_info = false;
+  drawable = NULL;
+}
+
+Button::Button(const std::string& imagefilename, const std::string& ninfo,
+    SDLKey nshortcut, int x, int y, int mw, int mh)
+{
+  popup_timer.init(false);
 
+  add_icon(imagefilename, mw, mh);
+  
   info = ninfo;
 
   shortcut = nshortcut;
@@ -48,7 +74,7 @@ Button::Button(std::string icon_file, std::string ninfo, SDLKey nshortcut, int x
   drawable = NULL;
 }
 
-void Button::add_icon(std::string icon_file, int mw, int mh)
+void Button::add_icon(const std::string& icon_file, int mw, int mh)
 {
   char filename[1024];
 
@@ -300,5 +326,6 @@ void ButtonPanel::highlight_last(bool b)
 {
   hlast = b;
 }
+#endif
 
 
index 950e898..28b7774 100644 (file)
 #define SUPERTUX_BUTTON_H
 
 #include <vector>
-#include "texture.h"
-#include "drawable.h"
+#include "screen/texture.h"
+
+// TODO
+#if 0
 
 enum ButtonState {
   BUTTON_NONE = -1,
@@ -42,13 +44,17 @@ class Button
   friend class ButtonPanel;
 
 public:
-  Button(std::string icon_file, std::string info, SDLKey shortcut, int x, int y, int mw = -1, int h = -1);
+  Button(Surface* icon_file, const std::string& info, SDLKey shortcut,
+      int x, int y, int mw = -1, int h = -1);
+  Button(const std::string& icon_name, const std::string& info, SDLKey shortcut,
+      int x, int y, int mw = -1, int h = -1);
+  
   ~Button();
   void event(SDL_Event& event);
   void draw();
   int get_state();
   void set_active(bool active) { active ? state = BUTTON_NONE : state = BUTTON_DEACTIVE; };
-  void add_icon(std::string icon_file, int mw, int mh);
+  void add_icon(const std::string& imagefile, int mw, int mh);
   SDL_Rect get_pos() { return rect; }
   int get_tag(){return tag; }
   void set_drawable(Drawable* newdrawable)
@@ -89,5 +95,6 @@ private:
   std::vector<Button*> item;
   std::vector<Button*>::iterator last_clicked;
 };
+#endif
 
 #endif /*SUPERTUX_BUTTON_H*/
index 3fdf3ac..e8cd4f5 100644 (file)
@@ -25,6 +25,7 @@
 #include "player.h"
 #include "level.h"
 #include "globals.h"
+#include "world.h"
 
 Camera::Camera(Player* newplayer, Level* newlevel)
   : player(newplayer), level(newlevel), do_backscrolling(true),
@@ -40,10 +41,10 @@ Camera::~Camera()
 {
 }
 
-void
-Camera::set_translation(const Vector& newtranslation)
+const Vector&
+Camera::get_translation() const
 {
-  translation = newtranslation;
+  return World::current()->context.get_translation();
 }
 
 void
@@ -128,10 +129,12 @@ static const float max_speed_y = 1.4;
 void
 Camera::action(float elapsed_time)
 {
+  translation = World::current()->context.get_translation();
   if(mode == NORMAL)
     scroll_normal(elapsed_time);
   else if(mode == AUTOSCROLL)
     scroll_autoscroll(elapsed_time);
+  World::current()->context.set_translation(translation);
 }
 
 void
index 453a06a..b64e71d 100644 (file)
@@ -35,28 +35,21 @@ public:
   Camera(Player* player = 0, Level* level = 0);
   virtual ~Camera();
 
-  /** transforms a coordinate in world space to screen space.
-   * Basically you have to apply this function to each coordinate that you want
-   * to display on screen.
-   */
-  Vector world2screen(const Vector& worldpos) const
-  {
-    return worldpos - translation;                   
-  }                                                  
-
   /// parse camera mode from lisp file
   void read(LispReader& reader);
   /// write camera mode to a lisp file
   virtual void write(LispWriter& writer);
 
-  /** returns the current translation (=scroll) vector of the viewport */
-  const Vector& get_translation() const
-  { return translation; }
-  /** set the curren translation vector of the viewport */
-  void set_translation(const Vector& translation);
+  /** @deprecated@ */
+  const Vector& get_translation() const;
 
   virtual void action(float elapsed_time);
 
+  virtual void draw(DrawingContext& context)
+  {
+    (void) context;
+  }
+
   enum CameraMode
   {
     NORMAL, AUTOSCROLL, MANUAL
index 58c48c6..d431f40 100644 (file)
@@ -59,7 +59,7 @@ bool collision_object_map(const base_type& base)
   for(int x = starttilex; x*32 < max_x; ++x) {
     for(int y = starttiley; y*32 < max_y; ++y) {
       Tile* tile = tilemanager.get(level.get_tile_at(x, y));
-      if(tile && tile->solid)
+      if(tile && (tile->attributes & Tile::SOLID))
         return true;
     }
   }
@@ -91,7 +91,7 @@ void* collision_func(const base_type& base, tiletestfunction function)
 
 static void* test_goal_tile_function(Tile* tile)
 {
-  if(tile && tile->goal)
+  if(tile && (tile->attributes & Tile::GOAL))
     return tile;
   return 0;
 }
@@ -248,44 +248,37 @@ Tile* gettile(float x, float y)
 bool issolid(float x, float y)
 {
   Tile* tile = gettile(x,y);
-  return tile && tile->solid;
+  return tile && (tile->attributes & Tile::SOLID);
 }
 
-bool isunisolid(float x, float y)
-{
-    Tile* tile = gettile(x,y);
-    return tile && tile->unisolid;
-}
-
-
 bool isbrick(float x, float y)
 {
   Tile* tile = gettile(x,y);
-  return tile && tile->brick;
+  return tile && (tile->attributes & Tile::BRICK);
 }
 
 bool isice(float x, float y)
 {
   Tile* tile = gettile(x,y);
-  return tile && tile->ice;
+  return tile && (tile->attributes & Tile::ICE);
 }
 
 bool isspike(float x, float y)
 {
   Tile* tile = gettile(x,y);
-  return tile && tile->spike;
+  return tile && (tile->attributes & Tile::SPIKE);
 }
 
 bool isfullbox(float x, float y)
 {
   Tile* tile = gettile(x,y);
-  return tile && tile->fullbox;
+  return tile && (tile->attributes & Tile::FULLBOX);
 }
 
-bool isdistro(float x, float y)
+bool iscoin(float x, float y)
 {
   Tile* tile = gettile(x,y);
-  return tile && tile->distro;
+  return tile && (tile->attributes & Tile::COIN);
 }
 
 /* EOF */
index a30451b..b6c243e 100644 (file)
@@ -53,7 +53,6 @@ Tile* gettile(float x, float y);
 
 // Some little helper function to check for tile properties
 bool  issolid(float x, float y);
-bool  isunisolid(float x, float y);
 bool  isbrick(float x, float y);
 bool  isice(float x, float y);
 bool  isspike(float x, float y);
diff --git a/src/display_manager.cpp b/src/display_manager.cpp
deleted file mode 100644 (file)
index 3a9b660..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-//  $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 "display_manager.h"
-
-#include <algorithm>
-
-DisplayManager::DisplayManager()
-{
-}
-
-DisplayManager::~DisplayManager()
-{
-}
-
-void
-DisplayManager::add_drawable(Drawable* drawable, int layer)
-{
-  DisplayList::iterator i 
-    = std::lower_bound(displaylist.begin(), displaylist.end(), layer);
-  if(i == displaylist.end())
-    displaylist.push_back(DrawingQueueEntry(drawable, layer));
-  else
-    displaylist.insert(i, DrawingQueueEntry(drawable, layer));
-}
-
-void
-DisplayManager::remove_drawable(Drawable* drawable)
-{
-  for(DisplayList::iterator i = displaylist.begin(); i != displaylist.end();) {
-    if(i->object == drawable)
-      i = displaylist.erase(i);
-    else
-      ++i;
-  }
-}
-
-void
-DisplayManager::draw(Camera& camera)
-{
-  for(DisplayList::iterator i = displaylist.begin(); i != displaylist.end();
-      ++i)
-    i->object->draw(camera, i->layer);
-}
-
diff --git a/src/display_manager.h b/src/display_manager.h
deleted file mode 100644 (file)
index 29cc10b..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-//  $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.
-#ifndef __DISPLAY_MANAGER_H__
-#define __DISPLAY_MANAGER_H__
-
-#include <vector>
-
-#include "drawable.h"
-#include "camera.h"
-
-// some constants for predefined layer values
-enum {
-  LAYER_BACKGROUND0 = -300,
-  LAYER_BACKGROUND1 = -200,
-  LAYER_BACKGROUNDTILES = -100,
-  LAYER_TILES = 0,
-  LAYER_OBJECTS = 100,
-  LAYER_FOREGROUNDTILES = 200,
-  LAYER_FOREGROUND0 = 300,
-  LAYER_FOREGROUND1 = 400
-};
-
-/** This class holds a list of all things that should be drawn to screen
- */
-class DisplayManager
-{
-public:
-  DisplayManager();
-  ~DisplayManager();
-  
-  /** adds an object to the list of stuff that should be drawn each frame.
-   * The layer argument specifies how early an object is drawn.
-   */
-  void add_drawable(Drawable* object, int layer);
-
-  void remove_drawable(Drawable* object);
-
-  void draw(Camera& camera);
-
-private:
-  class DrawingQueueEntry {
-  public:
-    DrawingQueueEntry(Drawable* newobject, int newlayer)
-      : object(newobject), layer(newlayer)
-    { }
-
-    bool operator <(int olayer) const
-    {
-      return layer < olayer;
-    }
-
-    Drawable* object;
-    int layer;
-  };
-
-  typedef std::vector<DrawingQueueEntry> DisplayList;
-  DisplayList displaylist;
-};
-
-#endif
-
diff --git a/src/drawable.h b/src/drawable.h
deleted file mode 100644 (file)
index d96f200..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-//  $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.
-#ifndef __DRAWABLE_H__
-#define __DRAWABLE_H__
-
-class Camera;
-
-/** interface for all game objects that can be drawn on screen.
- */
-class Drawable
-{
-public:
-  /** This function draws the object on screen.
-   */                                              
-  virtual void draw(Camera& viewport, int layer) = 0;
-};
-
-#endif
-
index d2824b5..fe81d95 100644 (file)
@@ -21,7 +21,7 @@
 
 #include <string>
 
-class DisplayManager;
+class DrawingContext;
 
 /**
  * Base class for all game objects. This contains functions for:
@@ -47,6 +47,11 @@ public:
    */
   virtual void action(float elapsed_time) = 0;
 
+  /** The GameObject should draw itself onto the provided DrawingContext if this
+   * function is called.
+   */
+  virtual void draw(DrawingContext& context) = 0;
+
   /** returns true if the object is not scheduled to be removed yet */
   bool is_valid() const
   { return !wants_to_die; }
index c50f53b..a39342d 100644 (file)
@@ -39,7 +39,7 @@
 #include "defines.h"
 #include "globals.h"
 #include "gameloop.h"
-#include "screen.h"
+#include "screen/screen.h"
 #include "setup.h"
 #include "high_scores.h"
 #include "menu.h"
@@ -147,20 +147,19 @@ GameSession::levelintro(void)
   
   char str[60];
 
-  Camera dummy;
-  world->background->draw(dummy, LAYER_BACKGROUND0);
+  DrawingContext context;
+  world->background->draw(context);
 
   sprintf(str, "%s", world->get_level()->name.c_str());
-  gold_text->drawf(str, 0, 220, A_HMIDDLE, A_TOP, 1);
+  context.draw_text_center(gold_text, str, Vector(0, 220), 0);
 
   sprintf(str, "TUX x %d", player_status.lives);
-  white_text->drawf(str, 0, 240, A_HMIDDLE, A_TOP, 1);
+  context.draw_text_center(white_text, str, Vector(0, 240), 0);
   
   sprintf(str, "by %s", world->get_level()->author.c_str());
-  white_small_text->drawf(str, 0, 400, A_HMIDDLE, A_TOP, 1);
-  
+  context.draw_text_center(white_small_text, str, Vector(0, 400), 0);
 
-  flipscreen();
+  context.do_drawing();
 
   SDL_Event event;
   wait_for_event(event,1000,3000,true);
@@ -492,27 +491,37 @@ GameSession::action(double frame_ratio)
 void 
 GameSession::draw()
 {
+  DrawingContext& context = world->context;
+  
   world->draw();
-  drawstatus();
+  drawstatus(context);
 
   if(game_pause)
     {
       int x = screen->h / 20;
       for(int i = 0; i < x; ++i)
         {
-          fillrect(i % 2 ? (pause_menu_frame * i)%screen->w : -((pause_menu_frame * i)%screen->w) ,(i*20+pause_menu_frame)%screen->h,screen->w,10,20,20,20, rand() % 20 + 1);
+          context.draw_filled_rect(
+              Vector(i % 2 ? (pause_menu_frame * i)%screen->w :
+                -((pause_menu_frame * i)%screen->w)
+                ,(i*20+pause_menu_frame)%screen->h),
+              Vector(screen->w,10),
+              Color(20,20,20, rand() % 20 + 1), LAYER_FOREGROUND1+1);
         }
-      fillrect(0,0,screen->w,screen->h,rand() % 50, rand() % 50, rand() % 50, 128);
-      blue_text->drawf("PAUSE - Press 'P' To Play", 0, 230, A_HMIDDLE, A_TOP, 1);
+      context.draw_filled_rect(
+          Vector(0,0), Vector(screen->w, screen->h),
+          Color(rand() % 50, rand() % 50, rand() % 50, 128), LAYER_FOREGROUND1);
+      world->context.draw_text_center(blue_text, "PAUSE - Press 'P' To Play",
+          Vector(0, 230), LAYER_FOREGROUND1+2);
     }
 
   if(Menu::current())
     {
-      Menu::current()->draw();
-      mouse_cursor->draw();
+      Menu::current()->draw(context);
+      mouse_cursor->draw(context);
     }
 
-  updatescreen();
+  context.do_drawing();
 }
 
 void
@@ -668,50 +677,68 @@ void bumpbrick(float x, float y)
 
 /* (Status): */
 void
-GameSession::drawstatus()
+GameSession::drawstatus(DrawingContext& context)
 {
+  context.push_transform();
+  context.set_translation(Vector(0, 0));
+  
   char str[60];
-
+  
   snprintf(str, 60, "%d", player_status.score);
-  white_text->draw("SCORE", 0, 0, 1);
-  gold_text->draw(str, 96, 0, 1);
+  context.draw_text(white_text, "SCORE", Vector(0, 0), LAYER_FOREGROUND1);
+  context.draw_text(gold_text, str, Vector(96, 0), LAYER_FOREGROUND1);
 
   if(st_gl_mode == ST_GL_TEST)
     {
-      white_text->draw("Press ESC To Return",0,20,1);
+      context.draw_text(white_text, "Press ESC To Return", Vector(0,20),
+          LAYER_FOREGROUND1);
     }
 
   if(!time_left.check()) {
-    white_text->draw("TIME'S UP", screen->w/2 - white_text->w*8, 0, 1);
+    context.draw_text_center(white_text, "TIME's UP", Vector(0, 0),
+        LAYER_FOREGROUND1);
   } else if (time_left.get_left() > TIME_WARNING || (global_frame_counter % 10) < 5) {
     sprintf(str, "%d", time_left.get_left() / 1000 );
-    white_text->draw("TIME", screen->w/2 - white_text->w*4, 0, 1);
-    gold_text->draw(str, screen->w/2 + gold_text->w, 0, 1);
+    context.draw_text_center(white_text, "TIME",
+        Vector(0, 0), LAYER_FOREGROUND1);
+    context.draw_text_center(gold_text, str,
+        Vector(4*16, 0), LAYER_FOREGROUND1);
   }
 
   sprintf(str, "%d", player_status.distros);
-  white_text->draw("COINS", screen->w - white_text->w*9, 0, 1);
-  gold_text->draw(str, screen->w - gold_text->w*2, 0, 1);
+  context.draw_text(white_text, "COINS",
+      Vector(screen->w - white_text->w*9, 0), LAYER_FOREGROUND1);
+  context.draw_text(gold_text, str,
+      Vector(screen->w - gold_text->w*2, 0), LAYER_FOREGROUND1);
 
-  white_text->draw("LIVES", screen->w - white_text->w*9, 20);
+  context.draw_text(white_text, "LIVES",
+      Vector(screen->w - white_text->w*9, 20), LAYER_FOREGROUND1);
   if (player_status.lives >= 5)
     {
       sprintf(str, "%dx", player_status.lives);
-      gold_text->draw_align(str, screen->w - gold_text->w, 20, A_RIGHT, A_TOP);
-      tux_life->draw(screen->w - gold_text->w, 20);
+      float x = screen->w - gold_text->get_text_width(str) - tux_life->w;
+      context.draw_text(gold_text, str, Vector(x, 20), LAYER_FOREGROUND1);
+      context.draw_surface(tux_life, Vector(screen->w - 16, 20),
+          LAYER_FOREGROUND1);
     }
   else
     {
       for(int i= 0; i < player_status.lives; ++i)
-        tux_life->draw(screen->w - tux_life->w*4 +(tux_life->w*i), 20);
+        context.draw_surface(tux_life, 
+            Vector(screen->w - tux_life->w*4 +(tux_life->w*i), 20),
+            LAYER_FOREGROUND1);
     }
 
   if(show_fps)
     {
       sprintf(str, "%2.1f", fps_fps);
-      white_text->draw("FPS", screen->w - white_text->w*9, 40, 1);
-      gold_text->draw_align(str, screen->w, 40, A_RIGHT, A_TOP);
+      context.draw_text(white_text, "FPS", 
+          Vector(screen->w - white_text->w*9, 40), LAYER_FOREGROUND1);
+      context.draw_text(gold_text, str,
+          Vector(screen->w-4*16, 40), LAYER_FOREGROUND1);
     }
+
+  context.pop_transform();
 }
 
 void
@@ -719,18 +746,19 @@ GameSession::drawresultscreen(void)
 {
   char str[80];
 
-  Camera dummy;
-  world->background->draw(dummy, LAYER_BACKGROUND0);  
+  DrawingContext context;
+  world->background->draw(context);  
 
-  blue_text->drawf("Result:", 0, 200, A_HMIDDLE, A_TOP, 1);
+  context.draw_text_center(blue_text, "Result:", Vector(0, 200),
+      LAYER_FOREGROUND1);
 
   sprintf(str, "SCORE: %d", player_status.score);
-  gold_text->drawf(str, 0, 224, A_HMIDDLE, A_TOP, 1);
+  context.draw_text_center(gold_text, str, Vector(0, 224), LAYER_FOREGROUND1);
 
   sprintf(str, "COINS: %d", player_status.distros);
-  gold_text->drawf(str, 0, 256, A_HMIDDLE, A_TOP, 1);
+  context.draw_text_center(gold_text, str, Vector(0, 256), LAYER_FOREGROUND1);
 
-  flipscreen();
+  context.do_drawing();
   
   SDL_Event event;
   wait_for_event(event,2000,5000,true);
index 42f3385..a2eb7c7 100644 (file)
@@ -103,7 +103,7 @@ class GameSession
   void process_events();
 
   void levelintro();
-  void drawstatus();
+  void drawstatus(DrawingContext& context);
   void drawendscreen();
   void drawresultscreen(void);
 
index 76722c7..9c8e79c 100644 (file)
@@ -20,6 +20,7 @@
 //  02111-1307, USA.
 #include <algorithm>
 #include <iostream>
+#include <math.h>
 #include "world.h"
 #include "tile.h"
 #include "gameloop.h"
 #include "sprite_manager.h"
 #include "resources.h"
 #include "level.h"
-#include "display_manager.h"
 
-BouncyDistro::BouncyDistro(DisplayManager& displaymanager, const Vector& pos)
+BouncyDistro::BouncyDistro(const Vector& pos)
   : position(pos)
 {
   ym = -2;
-  displaymanager.add_drawable(this, LAYER_OBJECTS);
 }
 
 void
@@ -47,17 +46,15 @@ BouncyDistro::action(float elapsed_time)
 }
 
 void
-BouncyDistro::draw(Camera& viewport, int )
+BouncyDistro::draw(DrawingContext& context)
 {
-  img_distro[0]->draw(viewport.world2screen(position));
+  context.draw_surface(img_distro[0], position, LAYER_OBJECTS);
 }
 
 
-BrokenBrick::BrokenBrick(DisplayManager& displaymanager, Tile* ntile,
-    const Vector& pos, const Vector& nmovement)
+BrokenBrick::BrokenBrick(Tile* ntile,const Vector& pos, const Vector& nmovement)
   : tile(ntile), position(pos), movement(nmovement)
 {
-  displaymanager.add_drawable(this, LAYER_OBJECTS);
   timer.start(200);
 }
 
@@ -71,27 +68,18 @@ BrokenBrick::action(float elapsed_time)
 }
 
 void
-BrokenBrick::draw(Camera& viewport, int )
+BrokenBrick::draw(DrawingContext& context)
 {
-  SDL_Rect src, dest;
-  src.x = rand() % 16;
-  src.y = rand() % 16;
-  src.w = 16;
-  src.h = 16;
-
-  dest.x = (int)(position.x - viewport.get_translation().x);
-  dest.y = (int)(position.y - viewport.get_translation().y);
-  dest.w = 16;
-  dest.h = 16;
-  
   if (tile->images.size() > 0)
-    tile->images[0]->draw_part(src.x,src.y,dest.x,dest.y,dest.w,dest.h);
+    context.draw_surface_part(tile->images[0],
+        Vector(rand() % 16, rand() % 16),
+        Vector(16, 16),
+        position, LAYER_OBJECTS + 1);
 }
 
-BouncyBrick::BouncyBrick(DisplayManager& displaymanager, const Vector& pos)
+BouncyBrick::BouncyBrick(const Vector& pos)
   : position(pos), offset(0), offset_m(-BOUNCY_BRICK_SPEED)
 {
-  displaymanager.add_drawable(this, LAYER_OBJECTS);
   shape    = World::current()->get_level()->gettileid(pos.x, pos.y);
 }
 
@@ -110,16 +98,15 @@ BouncyBrick::action(float elapsed_time)
 }
 
 void
-BouncyBrick::draw(Camera& viewport, int)
+BouncyBrick::draw(DrawingContext& context)
 {
-  Tile::draw(viewport.world2screen(position + Vector(0, offset)), shape);
+  TileManager::instance()->
+    draw_tile(context, shape, position + Vector(0, offset), LAYER_TILES+1);
 }
 
-FloatingScore::FloatingScore(DisplayManager& displaymanager, 
-    const Vector& pos, int score)
+FloatingScore::FloatingScore(const Vector& pos, int score)
   : position(pos)
 {
-  displaymanager.add_drawable(this, LAYER_OBJECTS);
   timer.start(1000);
   snprintf(str, 10, "%d", score);
   position.x -= strlen(str) * 8;
@@ -135,9 +122,9 @@ FloatingScore::action(float elapsed_time)
 }
 
 void
-FloatingScore::draw(Camera& viewport, int )
+FloatingScore::draw(DrawingContext& context)
 {
-  gold_text->draw(str, viewport.world2screen(position));
+  context.draw_text(gold_text, str, position, LAYER_OBJECTS);
 }
 
 /* Trampoline */
@@ -145,10 +132,8 @@ FloatingScore::draw(Camera& viewport, int )
 #define TRAMPOLINE_FRAMES 4
 Sprite *img_trampoline[TRAMPOLINE_FRAMES];
 
-Trampoline::Trampoline(DisplayManager& displaymanager, LispReader& reader)
+Trampoline::Trampoline(LispReader& reader)
 {
-  displaymanager.add_drawable(this, LAYER_OBJECTS);
-  
   reader.read_float("x", &base.x);
   reader.read_float("y", &base.y); 
   base.width = 32;
@@ -174,9 +159,9 @@ Trampoline::write(LispWriter& writer)
 }
 
 void
-Trampoline::draw(Camera& viewport, int )
+Trampoline::draw(DrawingContext& context)
 {
-  img_trampoline[frame]->draw(viewport.world2screen(Vector(base.x, base.y)));
+  img_trampoline[frame]->draw(context, Vector(base.x, base.y), LAYER_OBJECTS);
   frame = 0;
 }
 
@@ -284,10 +269,8 @@ Trampoline::collision(void *p_c_object, int c_object, CollisionType type)
 
 Sprite *img_flying_platform;
 
-FlyingPlatform::FlyingPlatform(DisplayManager& displaymanager, LispReader& reader)
+FlyingPlatform::FlyingPlatform(LispReader& reader)
 {
-  displaymanager.add_drawable(this, LAYER_OBJECTS);
-
   reader.read_int_vector("x",  &pos_x);
   reader.read_int_vector("y",  &pos_y);
 
@@ -323,9 +306,9 @@ FlyingPlatform::write(LispWriter& writer)
 }
 
 void
-FlyingPlatform::draw(Camera& viewport, int )
+FlyingPlatform::draw(DrawingContext& context)
 {
-img_flying_platform->draw(viewport.world2screen(Vector(base.x, base.y)));
+  img_flying_platform->draw(context, Vector(base.x, base.y), LAYER_OBJECTS);
 }
 
 void
index 49515a3..c4ce9ff 100644 (file)
 #define SUPERTUX_GAMEOBJS_H
 
 #include "type.h"
-#include "texture.h"
+#include "screen/texture.h"
 #include "timer.h"
 #include "scene.h"
 #include "physic.h"
 #include "collision.h"
 #include "game_object.h"
-#include "drawable.h"
 #include "moving_object.h"
 #include "lispwriter.h"
 
 #define NO_BOUNCE 0
 #define BOUNCE 1
 
-class BouncyDistro : public GameObject, public Drawable
+class BouncyDistro : public GameObject
 {
 public:
-  BouncyDistro(DisplayManager& displaymanager, const Vector& pos);
+  BouncyDistro(const Vector& pos);
   virtual void action(float elapsed_time);
-  virtual void draw(Camera& viewport, int layer);
+  virtual void draw(DrawingContext& context);
 
 private:
   Vector position;
@@ -56,14 +55,13 @@ extern Surface* img_distro[4];
 
 class Tile;
 
-class BrokenBrick : public GameObject, public Drawable
+class BrokenBrick : public GameObject
 {
 public:
-  BrokenBrick(DisplayManager& displaymanager, Tile* tile,
-      const Vector& pos, const Vector& movement);
+  BrokenBrick(Tile* tile, const Vector& pos, const Vector& movement);
 
   virtual void action(float elapsed_time);
-  virtual void draw(Camera& viewport, int layer);
+  virtual void draw(DrawingContext& context);
 
 private:
   Timer timer;
@@ -72,12 +70,12 @@ private:
   Vector movement;
 };
 
-class BouncyBrick : public GameObject, public Drawable
+class BouncyBrick : public GameObject
 {
 public:
-  BouncyBrick(DisplayManager& displaymanager, const Vector& pos);
+  BouncyBrick(const Vector& pos);
   virtual void action(float elapsed_time);
-  virtual void draw(Camera& viewport, int layer);
+  virtual void draw(DrawingContext& context);
   
 private:
   Vector position;
@@ -86,13 +84,13 @@ private:
   int shape;      
 };
 
-class FloatingScore : public GameObject, public Drawable
+class FloatingScore : public GameObject
 {
 public:
-  FloatingScore(DisplayManager& displaymanager, const Vector& pos, int s);
+  FloatingScore(const Vector& pos, int s);
   
   virtual void action(float elapsed_time);
-  virtual void draw(Camera& viewport, int layer);
+  virtual void draw(DrawingContext& context);
 
 private:
   Vector position;
@@ -100,14 +98,14 @@ private:
   Timer timer;  
 };
 
-class Trampoline : public MovingObject, public Drawable, public Serializable
+class Trampoline : public MovingObject, public Serializable
 {
 public:
-  Trampoline(DisplayManager& displaymanager, LispReader& reader);
+  Trampoline(LispReader& reader);
  
   virtual void write(LispWriter& writer);
   virtual void action(float frame_ratio);
-  virtual void draw(Camera& viewport, int layer);
+  virtual void draw(DrawingContext& context);
 
   virtual void collision(const MovingObject& other, int);
   void collision(void *p_c_object, int c_object, CollisionType type);
@@ -120,14 +118,14 @@ public:
   unsigned int frame;
 };
 
-class FlyingPlatform : public MovingObject, public Drawable, public Serializable
+class FlyingPlatform : public MovingObject, public Serializable
 {
 public:
-  FlyingPlatform(DisplayManager& displaymanager, LispReader& reader);
+  FlyingPlatform(LispReader& reader);
  
   virtual void write(LispWriter& writer);
   virtual void action(float frame_ratio);
-  virtual void draw(Camera& viewport, int layer);
+  virtual void draw(DrawingContext& context);
 
   virtual void collision(const MovingObject& other, int);
   void collision(void *p_c_object, int c_object, CollisionType type);
index 1da3e4a..0c16a30 100644 (file)
@@ -38,16 +38,16 @@ JoystickKeymap::JoystickKeymap()
 JoystickKeymap joystick_keymap;
 
 SDL_Surface * screen;
-Text* black_text;
-Text* gold_text;
-Text* silver_text;
-Text* blue_text;
-Text* red_text;
-Text* green_text;
-Text* yellow_nums;
-Text* white_text;
-Text* white_small_text;
-Text* white_big_text;
+Font* black_text;
+Font* gold_text;
+Font* silver_text;
+Font* blue_text;
+Font* red_text;
+Font* green_text;
+Font* yellow_nums;
+Font* white_text;
+Font* white_small_text;
+Font* white_big_text;
 
 MouseCursor * mouse_cursor;
 
index 0dcb117..a30e66a 100644 (file)
@@ -24,7 +24,7 @@
 
 #include <string>
 #include <SDL.h>
-#include "text.h"
+#include "screen/font.h"
 #include "menu.h"
 #include "mousecursor.h"
 
@@ -47,16 +47,16 @@ struct JoystickKeymap
 extern JoystickKeymap joystick_keymap;
 
 extern SDL_Surface * screen;
-extern Text* black_text;
-extern Text* gold_text;
-extern Text* silver_text;
-extern Text* white_text;
-extern Text* white_small_text;
-extern Text* white_big_text;
-extern Text* blue_text;
-extern Text* red_text;
-extern Text* green_text;
-extern Text* yellow_nums;
+extern Font* black_text;
+extern Font* gold_text;
+extern Font* silver_text;
+extern Font* white_text;
+extern Font* white_small_text;
+extern Font* white_big_text;
+extern Font* blue_text;
+extern Font* red_text;
+extern Font* green_text;
+extern Font* yellow_nums;
 
 extern MouseCursor * mouse_cursor;
 
index cb3d410..044c882 100644 (file)
@@ -26,8 +26,9 @@
 #include "globals.h"
 #include "high_scores.h"
 #include "menu.h"
-#include "screen.h"
-#include "texture.h"
+#include "screen/drawing_context.h"
+#include "screen/screen.h"
+#include "screen/texture.h"
 #include "setup.h"
 #include "lispreader.h"
 
@@ -84,6 +85,7 @@ void save_hs(int score)
   Surface* bkgd;
   SDL_Event event;
 
+  DrawingContext context;
   bkgd = new Surface(datadir + "/images/highscore/highscore.png", IGNORE_ALPHA);
 
   hs_score = score;
@@ -98,17 +100,19 @@ void save_hs(int score)
   /* ask for player's name */
   while(Menu::current())
     {
-      bkgd->draw_bg();
+      context.draw_surface(bkgd, Vector(0, 0), LAYER_BACKGROUND0);
 
-      blue_text->drawf("Congratulations", 0, 130, A_HMIDDLE, A_TOP, 2, NO_UPDATE);
-      blue_text->draw("Your score:", 150, 180, 1, NO_UPDATE);
+      context.draw_text_center(blue_text, "Congratulations", 
+          Vector(0, 130), LAYER_FOREGROUND1);
+      context.draw_text(blue_text, "Your score:", Vector(150, 180),
+          LAYER_FOREGROUND1);
       sprintf(str, "%d", hs_score);
-      yellow_nums->draw(str, 350, 170, 1, NO_UPDATE);
+      context.draw_text(yellow_nums, str, Vector(250, 170), LAYER_FOREGROUND1);
 
-      Menu::current()->draw();
+      Menu::current()->draw(context);
       Menu::current()->action();
 
-      flipscreen();
+      context.do_drawing();
 
       while(SDL_PollEvent(&event))
         if(event.type == SDL_KEYDOWN)
@@ -156,18 +160,4 @@ void save_hs(int score)
       fprintf( fi,")");
       fclose(fi);
     }
-
-/*
-  fi = opendata(highscore_filename, "w");
-  if (fi != NULL)
-    {
-      fprintf(fi, "# Supertux highscore file\n\n");
-
-      fprintf(fi, "name=%s\n", hs_name);
-      fprintf(fi, "highscore=%d\n", hs_score);
-
-      fprintf(fi, "# (File automatically created.)\n");
-
-      fclose(fi);
-    }*/
 }
index 991c77f..a0aa618 100644 (file)
 //  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 <iostream>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <unistd.h>
-#include <SDL.h>
-#include <SDL_image.h>
-
-#include "defines.h"
-#include "globals.h"
 #include "intro.h"
-#include "text.h"
-
-#include "screen.h"
+#include "globals.h"
+#include "defines.h"
+#include "screen/font.h"
+#include "screen/screen.h"
 
 void draw_intro()
 {
-display_text_file("intro.txt", "/images/background/arctis.jpg", SCROLL_SPEED_MESSAGE);
+  display_text_file("intro.txt", "/images/background/arctis.jpg", SCROLL_SPEED_MESSAGE);
 }
 
index 485e5e8..ab90191 100644 (file)
@@ -26,7 +26,8 @@
 #include <fstream>
 #include "globals.h"
 #include "setup.h"
-#include "screen.h"
+#include "camera.h"
+#include "screen/screen.h"
 #include "level.h"
 #include "physic.h"
 #include "scene.h"
@@ -36,6 +37,7 @@
 #include "music_manager.h"
 #include "gameobjs.h"
 #include "world.h"
+#include "background.h"
 #include "lispwriter.h"
 
 using namespace std;
@@ -220,20 +222,12 @@ Level::init_defaults()
   name       = "UnNamed";
   author     = "UnNamed";
   song_title = "Mortimers_chipdisko.mod";
-  bkgd_image = "arctis.jpg";
   width      = 0;
   height     = 0;
   start_pos.x = 100;
   start_pos.y = 170;
   time_left  = 100;
   gravity    = 10.;
-  bkgd_speed = 50;
-  bkgd_top.red   = 0;
-  bkgd_top.green = 0;
-  bkgd_top.blue  = 0;
-  bkgd_bottom.red   = 255;
-  bkgd_bottom.green = 255;
-  bkgd_bottom.blue  = 255;
 
   resize(21, 19);
 }
@@ -288,19 +282,40 @@ Level::load(const std::string& filename, World* world)
       if(!reader.read_int("height",  &height)) {
         printf("Warning: no height specified for level.\n");
       }
-      
-      bkgd_speed = 50;
+
+
+      // read old background stuff
+      int bkgd_speed = 50;
       reader.read_int("bkgd_speed",  &bkgd_speed);
       
-      bkgd_top.red = bkgd_top.green = bkgd_top.blue = 0;
-      reader.read_int("bkgd_red_top",  &bkgd_top.red);
-      reader.read_int("bkgd_green_top",  &bkgd_top.green);
-      reader.read_int("bkgd_blue_top",  &bkgd_top.blue);
+      Color bkgd_top, bkgd_bottom;
+      int r, g, b;
+      reader.read_int("bkgd_red_top", &r);
+      reader.read_int("bkgd_green_top",  &g);
+      reader.read_int("bkgd_blue_top",  &b);
+      bkgd_top.red = r;
+      bkgd_top.green = g;
+      bkgd_top.blue = b;
+
+      reader.read_int("bkgd_red_bottom",  &r);
+      reader.read_int("bkgd_green_bottom",  &g);
+      reader.read_int("bkgd_blue_bottom",  &b);
+      bkgd_bottom.red = r;
+      bkgd_bottom.green = g;
+      bkgd_bottom.blue = b;
+
+      std::string bkgd_image;
+      reader.read_string("background",  &bkgd_image);
 
-      bkgd_bottom.red = bkgd_bottom.green = bkgd_bottom.blue = 0;
-      reader.read_int("bkgd_red_bottom",  &bkgd_bottom.red);
-      reader.read_int("bkgd_green_bottom",  &bkgd_bottom.green);
-      reader.read_int("bkgd_blue_bottom",  &bkgd_bottom.blue);
+      if(world) {
+        Background* background = new Background();
+        if(bkgd_image != "")
+          background->set_image(bkgd_image, bkgd_speed);
+        else
+          background->set_gradient(bkgd_top, bkgd_bottom);
+
+        world->add_object(background);
+      }
 
       gravity = 10;
       reader.read_float("gravity",  &gravity);
@@ -310,8 +325,6 @@ Level::load(const std::string& filename, World* world)
       reader.read_string("author", &author);
       song_title = "";
       reader.read_string("music",  &song_title);
-      bkgd_image = "";
-      reader.read_string("background",  &bkgd_image);
       particle_system = "";
       reader.read_string("particle_system", &particle_system);
 
@@ -408,13 +421,6 @@ Level::save(const std::string& subset, int level, World* world)
   writer.write_string("music", song_title);
   writer.write_string("background", bkgd_image);
   writer.write_string("particle_system", particle_system);
-  writer.write_int("bkgd_speed", bkgd_speed);
-  writer.write_int("bkgd_red_top", bkgd_top.red);
-  writer.write_int("bkgd_green_top", bkgd_top.green);
-  writer.write_int("bkgd_blue_top", bkgd_top.blue);
-  writer.write_int("bkgd_red_bottom", bkgd_bottom.red);
-  writer.write_int("bkgd_green_bottom", bkgd_bottom.green);
-  writer.write_int("bkgd_blue_bottom", bkgd_bottom.blue);
   writer.write_int("time", time_left);
   writer.write_int("width", width);
   writer.write_int("height", height);
@@ -461,26 +467,6 @@ Level::cleanup()
   name = "";
   author = "";
   song_title = "";
-  bkgd_image = "";
-}
-
-void 
-Level::load_gfx()
-{
-  if(!bkgd_image.empty())
-    {
-      char fname[1024];
-      snprintf(fname, 1024, "%s/background/%s", st_dir, bkgd_image.c_str());
-      if(!faccessible(fname))
-        snprintf(fname, 1024, "%s/images/background/%s", datadir.c_str(), bkgd_image.c_str());
-      delete img_bkgd;
-      img_bkgd = new Surface(fname, IGNORE_ALPHA);
-    }
-  else
-    {
-      delete img_bkgd;
-      img_bkgd = 0;
-    }
 }
 
 /* Load a level-specific graphic... */
index 1f2fe94..be51d5a 100644 (file)
 #define SUPERTUX_LEVEL_H
 
 #include <string>
-#include "texture.h"
-#include "badguy.h"
+#include "screen/texture.h"
 #include "lispreader.h"
 #include "musicref.h"
-#include "gameobjs.h"
 
 class Tile;
 class World;
@@ -34,33 +32,32 @@ class World;
 /** This type holds meta-information about a level-subset. 
     It could be extended to handle manipulation of subsets. */
 class LevelSubset
-  {
-  public:
-    LevelSubset();
-    ~LevelSubset();
-
-    static void create(const std::string& subset_name);
-    void load(char *subset);
-    void save();
-
-    std::string name;
-    std::string title;
-    std::string description;
-    Surface* image;
-    int levels;
+{
+public:
+  LevelSubset();
+  ~LevelSubset();
+
+  static void create(const std::string& subset_name);
+  void load(char *subset);
+  void save();
+
+  std::string name;
+  std::string title;
+  std::string description;
+  Surface* image;
+  int levels;
  
-  private:
-    void parse(lisp_object_t* cursor);
-  };
+private:
+  void parse(lisp_object_t* cursor);
+};
 
 #define LEVEL_NAME_MAX 20
 
-
 enum TileMapType {
  TM_BG,
  TM_IA,
  TM_FG
- };
+};
 
 struct ResetPoint
 {
@@ -70,7 +67,7 @@ struct ResetPoint
 
 class Level 
 {
- public:
+public:
   Surface* img_bkgd;
   MusicRef level_song;
   MusicRef level_song_fast;
@@ -81,17 +78,11 @@ class Level
   std::string bkgd_image;
   std::string particle_system;
   std::vector<unsigned int> bg_tiles; /* Tiles in the background */
-  std::vector<unsigned int> ia_tiles; /* Tiles which can interact in the game (solids for example)*/
+  std::vector<unsigned int> ia_tiles; /* solid Tiles in the game */
   std::vector<unsigned int> fg_tiles; /* Tiles in the foreground */
-//  std::vector<unsigned int> bg_tiles[15]; /* Tiles in the background */
-//  std::vector<unsigned int> ia_tiles[15]; /* Tiles which can interact in the game (solids for example)*/
-//  std::vector<unsigned int> fg_tiles[15]; /* Tiles in the foreground */
   int time_left;
-  Color bkgd_top;
-  Color bkgd_bottom;
   int width;
   int height;
-  int bkgd_speed;
   Vector start_pos;
   float gravity;
 
@@ -121,8 +112,6 @@ class Level
    */
   int  load(const std::string& filename, World* world);
 
-  void load_gfx();
-  
   void load_song();
   void free_song();
   MusicRef get_level_music();
index 67182b8..bb163d8 100644 (file)
@@ -31,7 +31,7 @@
 #include <algorithm>
 #include "leveleditor.h"
 
-#include "screen.h"
+#include "screen/screen.h"
 #include "defines.h"
 #include "globals.h"
 #include "setup.h"
@@ -45,7 +45,9 @@
 #include "resources.h"
 #include "music_manager.h"
 #include "background.h"
-#include "display_manager.h"
+
+// TODO
+#if 0
 
 /* definitions to aid development */
 
@@ -472,29 +474,18 @@ void le_init_menus()
       for(std::vector<int>::const_iterator sit = (*it).tiles.begin();
           sit != (*it).tiles.end(); ++sit, ++i)
       {
-        std::string imagefile = "/images/tilesets/" ;
-        bool only_editor_image = false;
-        if(!TileManager::instance()->get(*sit)->filenames.empty())
-        {
-          imagefile += TileManager::instance()->get(*sit)->filenames[0];
-        }
-        else if(!TileManager::instance()->get(*sit)->editor_filenames.empty())
-        {
-          imagefile += TileManager::instance()->get(*sit)->editor_filenames[0];
-          only_editor_image = true;
-        }
+        Tile& tile = *(TileManager::instance()->get(*sit));
+        Surface* image;
+        if(tile.editor_images.size() > 0)
+          image = tile.editor_images[0];
+        else if(tile.images.size() > 0)
+          image = tile.images[0];
         else
-        {
-          imagefile += "notile.png";
-        }
-        Button* button = new Button(imagefile, it->name, SDLKey(SDLK_a + i),
+          // TODO use some notile image...
+          image = 0;
+
+        Button* button = new Button(image, it->name, SDLKey(SDLK_a + i),
                                     0, 0, 32, 32);
-        if(!only_editor_image)
-          if(!TileManager::instance()->get(*sit)->editor_filenames.empty())
-          {
-            imagefile = "/images/tilesets/" + TileManager::instance()->get(*sit)->editor_filenames[0];
-            button->add_icon(imagefile,32,32);
-          }
         tilegroups_map[it->name]->additem(button, *sit);
       }
     }
@@ -511,7 +502,7 @@ void le_init_menus()
   for(int i = 0; i < NUM_BadGuyKinds; ++i)
   {
     BadGuy bad_tmp(dummy, BadGuyKind(i), 0, 0);
-    objects_map["BadGuys"]->additem(new Button("", "BadGuy",(SDLKey)(i+'a'),0,0,32,32),1000000+i);
+    objects_map["BadGuys"]->additem(new Button(0, "BadGuy",(SDLKey)(i+'a'),0,0,32,32),1000000+i);
     objects_map["BadGuys"]->manipulate_button(i)->set_drawable(new
         BadGuy(dummy,
           BadGuyKind(i),
@@ -1033,7 +1024,8 @@ void le_drawlevel()
 
 void le_change_object_properties(GameObject *pobj)
 {
-  Surface* cap_screen = Surface::CaptureScreen();
+  //Surface* cap_screen = Surface::CaptureScreen();
+    
   Menu* object_properties_menu = new Menu();
   bool loop = true;
 
@@ -1069,7 +1061,7 @@ void le_change_object_properties(GameObject *pobj)
       object_properties_menu->event(event);
     }
 
-    cap_screen->draw(0,0);
+    //cap_screen->draw(0,0);
 
     object_properties_menu->draw();
     object_properties_menu->action();
@@ -1099,7 +1091,7 @@ void le_change_object_properties(GameObject *pobj)
     SDL_Delay(25);
   }
 
-  delete cap_screen;
+  //delete cap_screen;
   Menu::set_current(0);
   delete object_properties_menu;
 }
@@ -1935,3 +1927,5 @@ void le_showhelp()
   le_selection_mode = temp_le_selection_mode;
   le_help_shown = false;
 }
+
+#endif
index 48b8a6e..d277416 100644 (file)
@@ -23,6 +23,8 @@
 #ifndef SUPERTUX_LEVELEDITOR_H
 #define SUPERTUX_LEVELEDITOR_H
 
+#if 0 // TODO
+
 struct square
 {
   int x1, y1, x2, y2;
@@ -40,4 +42,6 @@ void testlevel(void);
 int le_init(void);
 void le_checkevents(void);
 
+#endif
+
 #endif /*SUPERTUX_LEVELEDITOR_H*/
index 3edb5ca..7f9f7a5 100644 (file)
@@ -1195,17 +1195,11 @@ LispReader::read_bool (const char* name, bool* b)
   return false;
 }
 
-#if 0
-void mygzungetc(char c, void* file)
-{
-  gzungetc(c, file);
-}
-
-lisp_stream_t* lisp_stream_init_gzfile (lisp_stream_t *stream, gzFile file)
+lisp_object_t*
+LispReader::get_lisp()
 {
-  return lisp_stream_init_any (stream, file, gzgetc, mygzungetc);
+  return lst;
 }
-#endif
 
 lisp_object_t* lisp_read_from_gzfile(const char* filename)
 {
index bde266c..81f2c40 100644 (file)
@@ -170,24 +170,27 @@ void lisp_dump (lisp_object_t *obj, FILE *out);
 
 /** */
 class LispReader
-  {
-  private:
-    lisp_object_t* lst;
-
-    lisp_object_t* search_for(const char* name);
-  public:
-    /** cur == ((pos 1 2 3) (id 12 3 4)...) */
-    LispReader (lisp_object_t* l);
-
-    bool read_int_vector (const char* name, std::vector<int>* vec);
-    bool read_int_vector (const char* name, std::vector<unsigned int>* vec);
-    bool read_char_vector (const char* name, std::vector<char>* vec);
-    bool read_string_vector (const char* name, std::vector<std::string>* vec);
-    bool read_string (const char* name, std::string* str);
-    bool read_int (const char* name, int* i);
-    bool read_float (const char* name, float* f);
-    bool read_bool (const char* name, bool* b);
-    bool read_lisp (const char* name, lisp_object_t** b);
-  };
+{
+private:
+  lisp_object_t* lst;
+
+  lisp_object_t* search_for(const char* name);
+public:
+  /** cur == ((pos 1 2 3) (id 12 3 4)...) */
+  LispReader (lisp_object_t* l);
+
+  bool read_int_vector (const char* name, std::vector<int>* vec);
+  bool read_int_vector (const char* name, std::vector<unsigned int>* vec);
+  bool read_char_vector (const char* name, std::vector<char>* vec);
+  bool read_string_vector (const char* name, std::vector<std::string>* vec);
+  bool read_string (const char* name, std::string* str);
+  bool read_int (const char* name, int* i);
+  bool read_float (const char* name, float* f);
+  bool read_bool (const char* name, bool* b);
+  bool read_lisp (const char* name, lisp_object_t** b);
+
+  lisp_object_t* get_lisp();
+};
 
 #endif
+
index f9fc8ae..34dd529 100644 (file)
@@ -32,7 +32,8 @@
 #include "defines.h"
 #include "globals.h"
 #include "menu.h"
-#include "screen.h"
+#include "screen/screen.h"
+#include "screen/drawing_context.h"
 #include "setup.h"
 #include "sound.h"
 #include "scene.h"
@@ -66,7 +67,9 @@ Menu* Menu::current_ = 0;
 /* just displays a Yes/No text that can be used to confirm stuff */
 bool confirm_dialog(std::string text)
 {
-  Surface* cap_screen = Surface::CaptureScreen();
+  // TODO
+#if 0
+  //Surface* cap_screen = Surface::CaptureScreen();
   
   Menu* dialog = new Menu;
   dialog->additem(MN_DEACTIVE, text,0,0);
@@ -86,7 +89,7 @@ bool confirm_dialog(std::string text)
       dialog->event(event);
     }
 
-    cap_screen->draw(0,0);
+    //cap_screen->draw(0,0);
 
     dialog->draw();
     dialog->action();
@@ -94,13 +97,13 @@ bool confirm_dialog(std::string text)
     switch (dialog->check())
     {
     case true:
-      delete cap_screen;
+      //delete cap_screen;
       Menu::set_current(0);
       delete dialog;
       return true;
       break;
     case false:
-      delete cap_screen;
+      //delete cap_screen;
       Menu::set_current(0);
       delete dialog;
       return false;
@@ -113,8 +116,8 @@ bool confirm_dialog(std::string text)
     flipscreen();
     SDL_Delay(25);
   }
-
-
+#endif
+  return false;
 }
 
 void
@@ -506,13 +509,12 @@ Menu::check()
 }
 
 void
-Menu::draw_item(int index, // Position of the current item in the menu
-                int menu_width,
-                int menu_height)
+Menu::draw_item(DrawingContext& context,
+    int index, // Position of the current item in the menu
+    int menu_width, int menu_height)
 {
   MenuItem& pitem = item[index];
 
-  int font_width  = 16;
   int effect_offset = 0;
   {
     int effect_time = 0;
@@ -523,13 +525,14 @@ Menu::draw_item(int index, // Position of the current item in the menu
     effect_offset = (index % 2) ? effect_time : -effect_time;
   }
 
+  Font* text_font = white_text;
   int x_pos       = pos_x;
   int y_pos       = pos_y + 24*index - menu_height/2 + 12 + effect_offset;
   int shadow_size = 2;
-  int text_width  = strlen(pitem.text) * font_width;
-  int input_width = (strlen(pitem.input)+ 1) * font_width;
-  int list_width  = strlen(string_list_active(pitem.list)) * font_width;
-  Text* text_font = white_text;
+  int text_width  = int(text_font->get_text_width(pitem.text));
+  int input_width = int(text_font->get_text_width(pitem.input) + 10);
+  int list_width  =
+    int(text_font->get_text_width(string_list_active(pitem.list)));
 
   if (arrange_left)
     x_pos += 24 - menu_width/2 + (text_width + input_width + list_width)/2;
@@ -544,30 +547,29 @@ Menu::draw_item(int index, // Position of the current item in the menu
   {
   case MN_DEACTIVE:
     {
-      black_text->draw_align(pitem.text,
-                             x_pos, y_pos,
-                             A_HMIDDLE, A_VMIDDLE, 2);
+      context.draw_text_center(blue_text, pitem.text,
+          Vector(0, y_pos - int(blue_text->get_height()/2)),
+          LAYER_FOREGROUND1);
       break;
     }
 
   case MN_HL:
     {
+      // TODO
       int x = pos_x - menu_width/2;
       int y = y_pos - 12 - effect_offset;
       /* Draw a horizontal line with a little 3d effect */
-      fillrect(x, y + 6,
-               menu_width, 4,
-               150,200,255,225);
-      fillrect(x, y + 6,
-               menu_width, 2,
-               255,255,255,255);
+      context.draw_filled_rect(Vector(x, y + 6),
+          Vector(menu_width, 4), Color(150,200,255,225), LAYER_FOREGROUND1);
+      context.draw_filled_rect(Vector(x, y + 6),
+          Vector(menu_width, 2), Color(255,255,255,255), LAYER_FOREGROUND1);
       break;
     }
   case MN_LABEL:
     {
-      white_big_text->draw_align(pitem.text,
-                                 x_pos, y_pos,
-                                 A_HMIDDLE, A_VMIDDLE, 2);
+      context.draw_text_center(white_big_text,
+          pitem.text, Vector(0, y_pos - int(white_big_text->get_height()/2)),
+          LAYER_FOREGROUND1);
       break;
     }
   case MN_TEXTFIELD:
@@ -575,15 +577,18 @@ Menu::draw_item(int index, // Position of the current item in the menu
   case MN_CONTROLFIELD_KB:
   case MN_CONTROLFIELD_JS:
     {
-      int input_pos = input_width/2;
-      int text_pos  = (text_width + font_width)/2;
-
-      fillrect(x_pos - input_pos + text_pos - 1, y_pos - 10,
-               input_width + font_width + 2, 20,
-               255,255,255,255);
-      fillrect(x_pos - input_pos + text_pos, y_pos - 9,
-               input_width + font_width, 18,
-               0,0,0,128);
+      int width = text_width + input_width + 5;
+      int text_pos = screen->w/2 - width/2;
+      int input_pos = text_pos + text_width + 10;
+
+      context.draw_filled_rect(
+          Vector(input_pos - 5, y_pos - 10),
+          Vector(input_width + 10, 20),
+          Color(255,255,255,255), LAYER_FOREGROUND1-5);
+      context.draw_filled_rect(
+          Vector(input_pos - 4, y_pos - 9),
+          Vector(input_width + 8, 18),
+          Color(0,0,0,128), LAYER_FOREGROUND1-4);
 
       if(pitem.kind == MN_CONTROLFIELD_KB)
         get_controlfield_key_into_input(&pitem);
@@ -593,74 +598,95 @@ Menu::draw_item(int index, // Position of the current item in the menu
       if(pitem.kind == MN_TEXTFIELD || pitem.kind == MN_NUMFIELD)
       {
         if(active_item == index)
-          gold_text->draw_align((pitem.get_input_with_symbol(true)).c_str(), x_pos + text_pos, y_pos, A_HMIDDLE, A_VMIDDLE, 2);
+          context.draw_text(gold_text,
+              pitem.get_input_with_symbol(true),
+              Vector(input_pos, y_pos - int(gold_text->get_height()/2)),
+              LAYER_FOREGROUND1);
         else
-          gold_text->draw_align((pitem.get_input_with_symbol(false)).c_str(), x_pos + text_pos, y_pos, A_HMIDDLE, A_VMIDDLE, 2);
+          context.draw_text(gold_text,
+              pitem.get_input_with_symbol(false),
+              Vector(input_pos, y_pos - int(gold_text->get_height()/2)),
+              LAYER_FOREGROUND1);
       }
       else
-        gold_text->draw_align(pitem.input,
-                              x_pos + text_pos, y_pos,
-                              A_HMIDDLE, A_VMIDDLE, 2);
+        context.draw_text(gold_text, pitem.input,
+            Vector(input_pos, y_pos - int(gold_text->get_height()/2)),
+            LAYER_FOREGROUND1);
 
-      text_font->draw_align(pitem.text,
-                            x_pos - (input_width + font_width)/2, y_pos,
-                            A_HMIDDLE, A_VMIDDLE, shadow_size);
+      context.draw_text(text_font, pitem.text,
+          Vector(text_pos, y_pos - int(text_font->get_height()/2)),
+          LAYER_FOREGROUND1);
       break;
     }
   case MN_STRINGSELECT:
     {
-      int list_pos_2 = list_width + font_width;
+      int list_pos_2 = list_width + 16;
       int list_pos   = list_width/2;
-      int text_pos   = (text_width + font_width)/2;
+      int text_pos   = (text_width + 16)/2;
 
       /* Draw arrows */
-      arrow_left->draw(  x_pos - list_pos + text_pos - 17, y_pos - 8);
-      arrow_right->draw( x_pos - list_pos + text_pos - 1 + list_pos_2, y_pos - 8);
+      context.draw_surface(arrow_left,
+          Vector(x_pos - list_pos + text_pos - 17, y_pos - 8),
+          LAYER_FOREGROUND1);
+      context.draw_surface(arrow_right,
+          Vector(x_pos - list_pos + text_pos - 1 + list_pos_2, y_pos - 8),
+          LAYER_FOREGROUND1);
 
       /* Draw input background */
-      fillrect(x_pos - list_pos + text_pos - 1, y_pos - 10,
-               list_pos_2 + 2, 20,
-               255,255,255,255);
-      fillrect(x_pos - list_pos + text_pos, y_pos - 9,
-               list_pos_2, 18,
-               0,0,0,128);
-
-      gold_text->draw_align(string_list_active(pitem.list),
-                            x_pos + text_pos, y_pos,
-                            A_HMIDDLE, A_VMIDDLE,2);
-
-      text_font->draw_align(pitem.text,
-                            x_pos - list_pos_2/2, y_pos,
-                            A_HMIDDLE, A_VMIDDLE, shadow_size);
+      context.draw_filled_rect(
+          Vector(x_pos - list_pos + text_pos - 1, y_pos - 10),
+          Vector(list_pos_2 + 2, 20),
+          Color(255,255,255,255), LAYER_FOREGROUND1 - 4);
+      context.draw_filled_rect(
+          Vector(x_pos - list_pos + text_pos, y_pos - 9),
+          Vector(list_pos_2, 18),
+          Color(0,0,0,128), LAYER_FOREGROUND1 - 5);
+
+      context.draw_text_center(text_font, string_list_active(pitem.list),
+          Vector(text_pos, y_pos - int(text_font->get_height()/2)),
+          LAYER_FOREGROUND1);
+      context.draw_text_center(text_font, pitem.text,
+          Vector(list_pos_2/2, y_pos - int(text_font->get_height()/2)),
+          LAYER_FOREGROUND1);
       break;
     }
   case MN_BACK:
     {
-      text_font->draw_align(pitem.text, x_pos, y_pos, A_HMIDDLE, A_VMIDDLE, shadow_size);
-      back->draw( x_pos + text_width/2  + font_width, y_pos - 8);
+      context.draw_text_center(text_font, pitem.text,
+          Vector(0, y_pos - int(text_font->get_height()/2)),
+          LAYER_FOREGROUND1);
+      context.draw_surface(back,
+          Vector(x_pos + text_width/2  + 16, y_pos - 8),
+          LAYER_FOREGROUND1);
       break;
     }
 
   case MN_TOGGLE:
     {
-      text_font->draw_align(pitem.text, x_pos, y_pos, A_HMIDDLE, A_VMIDDLE, shadow_size);
+      context.draw_text_center(text_font, pitem.text,
+          Vector(0, y_pos - (text_font->get_height()/2)),
+          LAYER_FOREGROUND1);
 
       if(pitem.toggled)
-        checkbox_checked->draw(
-          x_pos + (text_width+font_width)/2,
-          y_pos - 8);
+        context.draw_surface(checkbox_checked,
+            Vector(x_pos + (text_width+16)/2, y_pos - 8),
+            LAYER_FOREGROUND1 + 1);
       else
-        checkbox->draw(
-          x_pos + (text_width+font_width)/2,
-          y_pos - 8);
+        context.draw_surface(checkbox,
+            Vector(x_pos + (text_width+16)/2, y_pos - 8),
+            LAYER_FOREGROUND1 + 1);                                      
       break;
     }
   case MN_ACTION:
-    text_font->draw_align(pitem.text, x_pos, y_pos, A_HMIDDLE, A_VMIDDLE, shadow_size);
+    context.draw_text_center(text_font, pitem.text,
+        Vector(0, y_pos - int(text_font->get_height()/2)),
+        LAYER_FOREGROUND1);
     break;
 
   case MN_GOTO:
-    text_font->draw_align(pitem.text, x_pos, y_pos, A_HMIDDLE, A_VMIDDLE, shadow_size);
+    context.draw_text_center(text_font, pitem.text,
+        Vector(0, y_pos - int(text_font->get_height()/2)),
+        LAYER_FOREGROUND1);
     break;
   }
 }
@@ -691,21 +717,25 @@ int Menu::get_height() const
 
 /* Draw the current menu. */
 void
-Menu::draw()
+Menu::draw(DrawingContext& context)
 {
   int menu_height = get_height();
   int menu_width  = get_width();
 
+  context.push_transform();
+  context.set_translation(Vector(0, 0));  
+
   /* Draw a transparent background */
-  fillrect(pos_x - menu_width/2,
-           pos_y - 24*item.size()/2 - 10,
-           menu_width,menu_height + 20,
-           150,180,200,125);
+  context.draw_filled_rect(
+      Vector(pos_x - menu_width/2, pos_y - 24*item.size()/2 - 10),
+      Vector(menu_width,menu_height + 20),
+      Color(150,180,200,125), LAYER_FOREGROUND1-10);
 
   for(unsigned int i = 0; i < item.size(); ++i)
   {
-    draw_item(i, menu_width, menu_height);
+    draw_item(context, i, menu_width, menu_height);
   }
+  context.pop_transform();
 }
 
 MenuItem&
index 4ac921d..c77777f 100644 (file)
@@ -22,7 +22,7 @@
 
 #include <SDL.h>
 #include <vector>
-#include "texture.h"
+#include "screen/texture.h"
 #include "timer.h"
 #include "type.h"
 #include "mousecursor.h"
@@ -213,8 +213,9 @@ public:
   void Menu::get_controlfield_key_into_input(MenuItem *item);
   void Menu::get_controlfield_js_into_input(MenuItem *item);
 
-  void draw   ();
-  void draw_item(int index, int menu_width, int menu_height);
+  void draw(DrawingContext& context);
+  void draw_item(DrawingContext& context,
+      int index, int menu_width, int menu_height);
   void set_pos(int x, int y, float rw = 0, float rh = 0);
 
   /** translate a SDL_Event into a menu_action */
index ff794b2..a073565 100644 (file)
@@ -16,8 +16,7 @@
 //  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 "screen.h"
+#include "screen/drawing_context.h"
 #include "mousecursor.h"
 
 MouseCursor* MouseCursor::current_ = 0;
@@ -59,7 +58,7 @@ void MouseCursor::set_mid(int x, int y)
   mid_y = y;
 }
 
-void MouseCursor::draw()
+void MouseCursor::draw(DrawingContext& context)
 {
   int x,y,w,h;
   Uint8 ispressed = SDL_GetMouseState(&x,&y);
@@ -88,5 +87,9 @@ void MouseCursor::draw()
       timer.start(MC_FRAME_PERIOD);
     }
 
-  cursor->draw_part(w*cur_frame, h*cur_state , x-mid_x, y-mid_y, w, h);
+  context.push_transform();
+  context.set_translation(Vector(0, 0));
+  context.draw_surface_part(cursor, Vector(w*cur_frame, h*cur_state), Vector(w,
+        h), Vector(x-mid_x, y-mid_y), LAYER_FOREGROUND1+100);
+  context.pop_transform();
 }
index 16b0ba6..a9b89bc 100644 (file)
@@ -22,7 +22,7 @@
 
 #include <string>
 #include "timer.h"
-#include "texture.h"
+#include "screen/texture.h"
 
 #define MC_FRAME_PERIOD 800  // in ms
 
@@ -34,26 +34,26 @@ enum {
 };
 
 class MouseCursor
-  {
-    public:
-    MouseCursor(std::string cursor_file, int frames);
-    ~MouseCursor();
-    int state();
-    void set_state(int nstate);
-    void set_mid(int x, int y);
-    void draw();
+{
+public:
+  MouseCursor(std::string cursor_file, int frames);
+  ~MouseCursor();
+  int state();
+  void set_state(int nstate);
+  void set_mid(int x, int y);
+  void draw(DrawingContext& context);
     
-    static MouseCursor* current() { return current_; };
-    static void set_current(MouseCursor* pcursor) {  current_ = pcursor; };
+  static MouseCursor* current() { return current_; };
+  static void set_current(MouseCursor* pcursor) {  current_ = pcursor; };
     
-    private:
-    int mid_x, mid_y;
-    static MouseCursor* current_;    
-    int state_before_click;
-    int cur_state;
-    int cur_frame, tot_frames;
-    Surface* cursor;
-    Timer timer;
-  };
+private:
+  int mid_x, mid_y;
+  static MouseCursor* current_;    
+  int state_before_click;
+  int cur_state;
+  int cur_frame, tot_frames;
+  Surface* cursor;
+  Timer timer;
+};
 
 #endif /*SUPERTUX_MOUSECURSOR_H*/
index 7604d32..88b7288 100644 (file)
 #include "level.h"
 #include "scene.h"
 #include "camera.h"
-#include "display_manager.h"
 
-ParticleSystem::ParticleSystem(DisplayManager& displaymanager)
+ParticleSystem::ParticleSystem()
 {
     virtual_width = screen->w;
     virtual_height = screen->h;
-
-    displaymanager.add_drawable(this, LAYER_BACKGROUND1);
 }
 
 ParticleSystem::~ParticleSystem()
@@ -44,39 +41,34 @@ ParticleSystem::~ParticleSystem()
     }
 }
 
-void ParticleSystem::draw(Camera& viewport, int layer)
+void ParticleSystem::draw(DrawingContext& context)
 {
+  float scrollx = context.get_translation().x;
+  float scrolly = context.get_translation().y;
+
+  context.push_transform();
+  context.set_translation(Vector(0,0));
+  
     std::vector<Particle*>::iterator i;
     for(i = particles.begin(); i != particles.end(); ++i) {
         Particle* particle = *i;
-        if(particle->layer != layer)
-            continue;
 
-        float scrollx = viewport.get_translation().x;
-        float scrolly = viewport.get_translation().y;
-        
         // remap x,y coordinates onto screencoordinates
-        float x = fmodf(particle->x - scrollx, virtual_width);
-        if(x < 0) x += virtual_width;
-        float y = fmodf(particle->y - scrolly, virtual_height);
-        if(y < 0) y += virtual_height;
-        float xmax = fmodf(x + particle->texture->w, virtual_width);
-        float ymax = fmodf(y + particle->texture->h, virtual_height);
-
-        // particle on screen
-        if(x >= screen->w && xmax >= screen->w)
-            continue;
-        if(y >= screen->h && ymax >= screen->h)
-            continue;
-        
-        if(x > screen->w) x -= virtual_width;
-        if(y > screen->h) y -= virtual_height;
-        particle->texture->draw(x, y);
+        Vector pos;
+        pos.x = fmodf(particle->pos.x - scrollx, virtual_width);
+        if(pos.x < 0) pos.x += virtual_width;
+        pos.y = fmodf(particle->pos.y - scrolly, virtual_height);
+        if(pos.y < 0) pos.y += virtual_height;
+
+        if(pos.x > screen->w) pos.x -= virtual_width;
+        if(pos.y > screen->h) pos.y -= virtual_height;
+        context.draw_surface(particle->texture, pos, LAYER_BACKGROUND1);
     }
+
+    context.pop_transform();
 }
 
-SnowParticleSystem::SnowParticleSystem(DisplayManager& displaymanager)
-  : ParticleSystem(displaymanager)
+SnowParticleSystem::SnowParticleSystem()
 {
     snowimages[0] = new Surface(datadir+"/images/shared/snow0.png", USE_ALPHA);
     snowimages[1] = new Surface(datadir+"/images/shared/snow1.png", USE_ALPHA);
@@ -88,9 +80,8 @@ SnowParticleSystem::SnowParticleSystem(DisplayManager& displaymanager)
     size_t snowflakecount = size_t(virtual_width/10.0);
     for(size_t i=0; i<snowflakecount; ++i) {
         SnowParticle* particle = new SnowParticle;
-        particle->x = rand() % int(virtual_width);
-        particle->y = rand() % screen->h;
-        particle->layer = LAYER_BACKGROUND1;
+        particle->pos.x = rand() % int(virtual_width);
+        particle->pos.y = rand() % screen->h;
         int snowsize = rand() % 3;
         particle->texture = snowimages[snowsize];
         do {
@@ -113,16 +104,15 @@ void SnowParticleSystem::action(float elapsed_time)
     std::vector<Particle*>::iterator i;
     for(i = particles.begin(); i != particles.end(); ++i) {
         SnowParticle* particle = (SnowParticle*) *i;
-        particle->y += particle->speed * elapsed_time;
-        if(particle->y > screen->h) {
-            particle->y = fmodf(particle->y , virtual_height);
-            particle->x = rand() % int(virtual_width);
+        particle->pos.y += particle->speed * elapsed_time;
+        if(particle->pos.y > screen->h) {
+            particle->pos.y = fmodf(particle->pos.y , virtual_height);
+            particle->pos.x = rand() % int(virtual_width);
         }
     }
 }
 
-CloudParticleSystem::CloudParticleSystem(DisplayManager& displaymanager)
-  : ParticleSystem(displaymanager)
+CloudParticleSystem::CloudParticleSystem()
 {
     cloudimage = new Surface(datadir + "/images/shared/cloud.png", USE_ALPHA);
 
@@ -131,9 +121,8 @@ CloudParticleSystem::CloudParticleSystem(DisplayManager& displaymanager)
     // create some random clouds
     for(size_t i=0; i<15; ++i) {
         CloudParticle* particle = new CloudParticle;
-        particle->x = rand() % int(virtual_width);
-        particle->y = rand() % int(virtual_height);
-        particle->layer = LAYER_BACKGROUND1;
+        particle->pos.x = rand() % int(virtual_width);
+        particle->pos.y = rand() % int(virtual_height);
         particle->texture = cloudimage;
         particle->speed = -float(250 + rand() % 200) / 1000.0;
 
@@ -151,6 +140,6 @@ void CloudParticleSystem::action(float elapsed_time)
     std::vector<Particle*>::iterator i;
     for(i = particles.begin(); i != particles.end(); ++i) {
         CloudParticle* particle = (CloudParticle*) *i;
-        particle->x += particle->speed * elapsed_time;
+        particle->pos.x += particle->speed * elapsed_time;
     }
 }
index 8bd117a..11bff4a 100644 (file)
@@ -21,8 +21,7 @@
 #define SUPERTUX_PARTICLESYSTEM_H
 
 #include <vector>
-#include "texture.h"
-#include "drawable.h"
+#include "screen/texture.h"
 #include "game_object.h"
 
 class DisplayManager;
@@ -42,13 +41,13 @@ class DisplayManager;
  * initialize particles in the constructor and move them in the simulate
  * function.
  */
-class ParticleSystem : public GameObject, public Drawable
+class ParticleSystem : public GameObject
 {
 public:
-    ParticleSystem(DisplayManager& displaymanager);
+    ParticleSystem();
     virtual ~ParticleSystem();
     
-    virtual void draw(Camera& view, int layer);
+    virtual void draw(DrawingContext& context);
 
 protected:
     class Particle
@@ -57,8 +56,7 @@ protected:
         virtual ~Particle()
         { }
 
-        float x, y;
-        int layer;
+        Vector pos;
         Surface* texture;
     };
     
@@ -69,7 +67,7 @@ protected:
 class SnowParticleSystem : public ParticleSystem
 {
 public:
-    SnowParticleSystem(DisplayManager& displaymanager);
+    SnowParticleSystem();
     virtual ~SnowParticleSystem();
 
     virtual void action(float elapsed_time);
@@ -90,7 +88,7 @@ private:
 class CloudParticleSystem : public ParticleSystem
 {
 public:
-    CloudParticleSystem(DisplayManager& displaymanager);
+    CloudParticleSystem();
     virtual ~CloudParticleSystem();
 
     virtual void action(float elapsed_time);
index e041dd5..379257d 100644 (file)
@@ -27,7 +27,8 @@
 #include "scene.h"
 #include "tile.h"
 #include "sprite.h"
-#include "screen.h"
+#include "gameobjs.h"
+#include "screen/screen.h"
 
 // behavior definitions:
 #define TILES_FOR_BUTTJUMP 3
@@ -71,10 +72,8 @@ void player_input_init(player_input_type* pplayer_input)
   pplayer_input->old_up = UP;
 }
 
-Player::Player(DisplayManager& display_manager)
+Player::Player()
 {
-  display_manager.add_drawable(this, LAYER_OBJECTS-1); // for tux himself
-  display_manager.add_drawable(this, LAYER_OBJECTS+1); // for the arm
   init();
 }
 
@@ -262,7 +261,7 @@ Player::action(float elapsed_time)
           if (isbrick(base.x, base.y) ||
               isfullbox(base.x, base.y))
             {
-              World::current()->trygrabdistro(base.x, base.y - 32,BOUNCE);
+              World::current()->trygrabdistro(base.x, base.y - 32, BOUNCE);
               World::current()->trybumpbadguy(base.x, base.y - 64);
 
               World::current()->trybreakbrick(base.x, base.y, size == SMALL);
@@ -313,10 +312,7 @@ Player::on_ground()
 {
   return ( issolid(base.x + base.width / 2, base.y + base.height) ||
            issolid(base.x + 1, base.y + base.height) ||
-           issolid(base.x + base.width - 1, base.y + base.height) ||
-          isunisolid(base.x + base.width / 2, base.y + base.height) ||
-          isunisolid(base.x + 1, base.y + base.height) ||
-          isunisolid(base.x + base.width - 1, base.y + base.height) );
+           issolid(base.x + base.width - 1, base.y + base.height));
 }
 
 bool
@@ -624,7 +620,7 @@ Player::grabdistros()
 }
 
 void
-Player::draw(Camera& viewport, int layer)
+Player::draw(DrawingContext& context)
 {
   PlayerSprite* sprite;
           
@@ -637,98 +633,97 @@ Player::draw(Camera& viewport, int layer)
   else
     sprite = &largetux;
 
-  Vector pos = viewport.world2screen(Vector(base.x, base.y));
+  int layer = LAYER_OBJECTS - 1;
+  Vector pos = Vector(base.x, base.y);
 
-  if(layer == LAYER_OBJECTS + 1) {
-    // Draw arm overlay graphics when Tux is holding something
-    if ((holding_something && physic.get_velocity_y() == 0) || shooting_timer.check() && !duck)
-    {
-      if (dir == RIGHT)
-        sprite->grab_right->draw(pos);
-      else
-        sprite->grab_left->draw(pos);
-    }
-
-    // Draw blinking star overlay
-    if (invincible_timer.started() &&
-        (invincible_timer.get_left() > TUX_INVINCIBLE_TIME_WARNING || global_frame_counter % 3))
-    {
-      if (size == SMALL || duck)
-        smalltux_star->draw(pos);
-      else
-        largetux_star->draw(pos);
-    }
-    
-    return;
-  }
-  
   if (!safe_timer.started() || (global_frame_counter % 2) == 0)
     {
       if (dying == DYING_SQUISHED)
         {
-          smalltux_gameover->draw(pos);
+          smalltux_gameover->draw(context, pos, LAYER_OBJECTS);
         }
       else
         {
           if(growing_timer.check())
             {
               if (dir == RIGHT)
-                growingtux_right->draw(pos);
+                growingtux_right->draw(context, pos, layer);
               else 
-                growingtux_left->draw(pos);
+                growingtux_left->draw(context, pos, layer);
             }
           else if (duck && size != SMALL)
             {
               if (dir == RIGHT)
-                sprite->duck_right->draw(pos);
+                sprite->duck_right->draw(context, pos, layer);
               else 
-                sprite->duck_left->draw(pos);
+                sprite->duck_left->draw(context, pos, layer);
             }
           else if (skidding_timer.started())
             {
               if (dir == RIGHT)
-                sprite->skid_right->draw(pos);
+                sprite->skid_right->draw(context, pos, layer);
               else
-                sprite->skid_left->draw(pos); 
+                sprite->skid_left->draw(context, pos, layer);
             }
           else if (kick_timer.started())
             {
               if (dir == RIGHT)
-                sprite->kick_right->draw(pos);
+                sprite->kick_right->draw(context, pos, layer);
               else
-                sprite->kick_left->draw(pos); 
+                sprite->kick_left->draw(context, pos, layer);
             }
           else if (physic.get_velocity_y() != 0)
             {
               if (dir == RIGHT)
-                sprite->jump_right->draw(pos);
+                sprite->jump_right->draw(context, pos, layer);
               else
-                sprite->jump_left->draw(pos);                   
+                sprite->jump_left->draw(context, pos, layer);
             }
           else
             {
               if (fabsf(physic.get_velocity_x()) < 1.0f) // standing
                 {
                   if (dir == RIGHT)
-                    sprite->stand_right->draw(pos);
+                    sprite->stand_right->draw(context, pos, layer);
                   else
-                    sprite->stand_left->draw(pos);
+                    sprite->stand_left->draw(context, pos, layer);
                 }
               else // moving
                 {
                   if (dir == RIGHT)
-                    sprite->walk_right->draw(pos);
+                    sprite->walk_right->draw(context, pos, layer);
                   else
-                    sprite->walk_left->draw(pos);
+                    sprite->walk_left->draw(context, pos, layer);
                 }
             }
         }
     }     
-  
+
+  // Draw arm overlay graphics when Tux is holding something
+  if ((holding_something && physic.get_velocity_y() == 0) || shooting_timer.check() && !duck)
+  {
+    if (dir == RIGHT)
+      sprite->grab_right->draw(context, pos, LAYER_OBJECTS + 1);
+    else
+      sprite->grab_left->draw(context, pos, LAYER_OBJECTS + 1);
+  }
+
+  // Draw blinking star overlay
+  if (invincible_timer.started() &&
+      (invincible_timer.get_left() > TUX_INVINCIBLE_TIME_WARNING || global_frame_counter % 3))
+  {
+    if (size == SMALL || duck)
+      smalltux_star->draw(context, pos, LAYER_OBJECTS + 2);
+    else
+      largetux_star->draw(context, pos, LAYER_OBJECTS + 2);
+  }
+#if 0 // TODO
   if (debug_mode)
     fillrect(base.x - viewport.get_translation().x,
         base.y - viewport.get_translation().y, 
              base.width, base.height, 75,75,75, 150);
+#endif
 }
 
 void
@@ -908,7 +903,7 @@ Player::move(const Vector& vector)
 }
 
 void
-Player::check_bounds(Camera& viewport)
+Player::check_bounds(DrawingContext& viewport)
 {
   /* Keep tux in bounds: */
   if (base.x < 0)
index 21a00a2..b3496eb 100644 (file)
 #include "bitmask.h"
 #include "type.h"
 #include "timer.h"
-#include "texture.h"
+#include "screen/texture.h"
 #include "collision.h"
 #include "sound.h"
 #include "moving_object.h"
-#include "drawable.h"
 #include "physic.h"
 
 /* Times: */
@@ -109,7 +108,7 @@ extern PlayerSprite largetux;
 extern PlayerSprite firetux;
 extern PlayerSprite icetux;
 
-class Player : public MovingObject, public Drawable
+class Player : public MovingObject
 {
 public:
   enum HurtMode { KILL, SHRINK };
@@ -148,7 +147,7 @@ public:
   Physic physic;
 
 public:
-  Player(DisplayManager& display_manager);
+  Player();
   virtual ~Player();
   
   int  key_event(SDLKey key, int state);
@@ -157,14 +156,14 @@ public:
   void grabdistros();
 
   virtual void action(float elapsed_time);
-  virtual void draw(Camera& viewport, int layer);
+  virtual void draw(DrawingContext& context);
   virtual void collision(const MovingObject& other_object,
       int collision_type);
 
   void collision(void* p_c_object, int c_object);
   void kill(HurtMode mode);
   void player_remove_powerups();
-  void check_bounds(Camera& viewport);
+  void check_bounds(DrawingContext& context);
   bool on_ground();
   bool under_solid();
   bool tiles_on_air(int tiles);
index a4f7215..7527198 100644 (file)
@@ -20,7 +20,7 @@
 #ifndef SUPERTUX_SCENE_H
 #define SUPERTUX_SCENE_H
 
-#include "texture.h"
+#include "screen/texture.h"
 #include "timer.h"
 
 #define FRAME_RATE 10 // 100 Frames per second (10ms)
diff --git a/src/screen.cpp b/src/screen.cpp
deleted file mode 100644 (file)
index 8e99e9b..0000000
+++ /dev/null
@@ -1,361 +0,0 @@
-//  $Id$
-//
-//  SuperTux -  A Jump'n Run
-//  Copyright (C) 2000 Bill Kendrick <bill@newbreedsoftware.com>
-//
-//  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 <iostream>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <unistd.h>
-#include <SDL.h>
-#include <SDL_image.h>
-
-#ifndef WIN32
-#include <sys/types.h>
-#include <ctype.h>
-#endif
-
-#include "defines.h"
-#include "globals.h"
-#include "screen.h"
-#include "setup.h"
-#include "type.h"
-
-/* Needed for line calculations */
-#define SGN(x) ((x)>0 ? 1 : ((x)==0 ? 0:(-1)))
-#define ABS(x) ((x)>0 ? (x) : (-x))
-
-/* --- CLEAR SCREEN --- */
-
-void clearscreen(int r, int g, int b)
-{
-#ifndef NOOPENGL
-  if(use_gl)
-    {
-      glClearColor(r/256, g/256, b/256, 1.0);
-      glClear(GL_COLOR_BUFFER_BIT);
-    }
-  else
-  {
-#endif
-
-    SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, r, g, b));
-#ifndef NOOPENGL
-
-    }
-#endif
-}
-
-/* --- DRAWS A VERTICAL GRADIENT --- */
-
-void drawgradient(Color top_clr, Color bot_clr)
-{
-#ifndef NOOPENGL
-  if(use_gl)
-    {
-      glBegin(GL_QUADS);
-      glColor3ub(top_clr.red, top_clr.green, top_clr.blue);
-      glVertex2f(0, 0);
-      glVertex2f(screen->w, 0);
-      glColor3ub(bot_clr.red, bot_clr.green, bot_clr.blue);
-      glVertex2f(screen->w, screen->h);
-      glVertex2f(0, screen->h);
-      glEnd();
-    }
-  else
-  {
-#endif
-
-    for(float y = 0; y < screen->h; y += 2)
-      fillrect(0, (int)y, screen->w, 2,
-       (int)(((float)(top_clr.red-bot_clr.red)/(0-screen->h)) * y + top_clr.red),
-       (int)(((float)(top_clr.green-bot_clr.green)/(0-screen->h)) * y + top_clr.green),
-       (int)(((float)(top_clr.blue-bot_clr.blue)/(0-screen->h)) * y + top_clr.blue),
-       255);
-/* calculates the color for each line, based in the generic equation for functions: y = mx + b */
-
-#ifndef NOOPENGL
-
-    }
-#endif
-}
-
-/** This fade shrinks to the given point */
-
-#define LOOP_DELAY 20
-void shrink_fade(Point point, int fade_time)
-{
-float left_inc  = (float)point.x / ((float)fade_time / LOOP_DELAY);
-float right_inc = ((float)screen->w - point.x) / ((float)fade_time / LOOP_DELAY);
-float up_inc    = (float)point.y / ((float)fade_time / LOOP_DELAY);
-float down_inc  = ((float)screen->h - point.y) / ((float)fade_time / LOOP_DELAY);
-
-float left_cor = 0, right_cor = 0, up_cor = 0, down_cor = 0;
-
-while(left_cor < point.x && right_cor < screen->w - point.x &&
-      up_cor < point.y && down_cor < screen->h - point.y)
-  {
-  left_cor  += left_inc;
-  right_cor += right_inc;
-  up_cor    += up_inc;
-  down_cor  += down_inc;
-
-  fillrect(0, 0, left_cor, screen->h, 0,0,0);  // left side
-  fillrect(screen->w - right_cor, 0, right_cor, screen->h, 0,0,0);  // right side
-  fillrect(0, 0, screen->w, up_cor, 0,0,0);  // up side
-  fillrect(0, screen->h - down_cor, screen->w, down_cor+1, 0,0,0);  // down side
-
-  flipscreen();
-  SDL_Delay(LOOP_DELAY);
-  }
-}
-
-/* 'Stolen' from the SDL documentation.
- * Set the pixel at (x, y) to the given value
- * NOTE: The surface must be locked before calling this!
- */
-void putpixel(SDL_Surface *surface, int x, int y, Uint32 pixel)
-{
-  int bpp = surface->format->BytesPerPixel;
-  /* Here p is the address to the pixel we want to set */
-  Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;
-
-  switch(bpp)
-    {
-    case 1:
-      *p = pixel;
-      break;
-
-    case 2:
-      *(Uint16 *)p = pixel;
-      break;
-
-    case 3:
-      if(SDL_BYTEORDER == SDL_BIG_ENDIAN)
-        {
-          p[0] = (pixel >> 16) & 0xff;
-          p[1] = (pixel >> 8) & 0xff;
-          p[2] = pixel & 0xff;
-        }
-      else
-        {
-          p[0] = pixel & 0xff;
-          p[1] = (pixel >> 8) & 0xff;
-          p[2] = (pixel >> 16) & 0xff;
-        }
-      break;
-
-    case 4:
-      *(Uint32 *)p = pixel;
-      break;
-    }
-}
-
-/* Draw a single pixel on the screen. */
-void drawpixel(int x, int y, Uint32 pixel)
-{
-  /* Lock the screen for direct access to the pixels */
-  if ( SDL_MUSTLOCK(screen) )
-    {
-      if ( SDL_LockSurface(screen) < 0 )
-        {
-          fprintf(stderr, "Can't lock screen: %s\n", SDL_GetError());
-          return;
-        }
-    }
-
-  if(!(x < 0 || y < 0 || x > screen->w || y > screen->h))
-    putpixel(screen, x, y, pixel);
-
-  if ( SDL_MUSTLOCK(screen) )
-    {
-      SDL_UnlockSurface(screen);
-    }
-  /* Update just the part of the display that we've changed */
-  SDL_UpdateRect(screen, x, y, 1, 1);
-}
-
-void drawline(int x1, int y1, int x2, int y2, int r, int g, int b, int a)
-{
-#ifndef NOOPENGL
-  if(use_gl)
-    {
-      glEnable(GL_BLEND);
-      glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-      glColor4ub(r, g, b,a);
-
-      glBegin(GL_LINES);
-      glVertex2f(x1, y1);
-      glVertex2f(x2, y2);
-      glEnd();
-      glDisable(GL_BLEND);
-    }
-  else
-    {
-#endif
-
-      /* Basic unantialiased Bresenham line algorithm */
-      int lg_delta, sh_delta, cycle, lg_step, sh_step;
-      Uint32 color = SDL_MapRGBA(screen->format, r, g, b, a);
-
-      lg_delta = x2 - x1;
-      sh_delta = y2 - y1;
-      lg_step = SGN(lg_delta);
-      lg_delta = ABS(lg_delta);
-      sh_step = SGN(sh_delta);
-      sh_delta = ABS(sh_delta);
-      if (sh_delta < lg_delta)
-        {
-          cycle = lg_delta >> 1;
-          while (x1 != x2)
-            {
-              drawpixel(x1, y1, color);
-              cycle += sh_delta;
-              if (cycle > lg_delta)
-                {
-                  cycle -= lg_delta;
-                  y1 += sh_step;
-                }
-              x1 += lg_step;
-            }
-          drawpixel(x1, y1, color);
-        }
-      cycle = sh_delta >> 1;
-      while (y1 != y2)
-        {
-          drawpixel(x1, y1, color);
-          cycle += lg_delta;
-          if (cycle > sh_delta)
-            {
-              cycle -= sh_delta;
-              x1 += lg_step;
-            }
-          y1 += sh_step;
-        }
-      drawpixel(x1, y1, color);
-#ifndef NOOPENGL
-
-    }
-#endif
-}
-
-/* --- FILL A RECT --- */
-
-void fillrect(float x, float y, float w, float h, int r, int g, int b, int a)
-{
-if(w < 0)
-       {
-       x += w;
-       w = -w;
-       }
-if(h < 0)
-       {
-       y += h;
-       h = -h;
-       }
-
-#ifndef NOOPENGL
-  if(use_gl)
-    {
-      glEnable(GL_BLEND);
-      glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-      glColor4ub(r, g, b,a);
-
-      glBegin(GL_POLYGON);
-      glVertex2f(x, y);
-      glVertex2f(x+w, y);
-      glVertex2f(x+w, y+h);
-      glVertex2f(x, y+h);
-      glEnd();
-      glDisable(GL_BLEND);
-    }
-  else
-    {
-#endif
-      SDL_Rect src, rect;
-      SDL_Surface *temp = NULL;
-
-      rect.x = (int)x;
-      rect.y = (int)y;
-      rect.w = (int)w;
-      rect.h = (int)h;
-
-      if(a != 255)
-        {
-          temp = SDL_CreateRGBSurface(screen->flags, rect.w, rect.h, screen->format->BitsPerPixel,
-                                      screen->format->Rmask,
-                                      screen->format->Gmask,
-                                      screen->format->Bmask,
-                                      screen->format->Amask);
-
-
-          src.x = 0;
-          src.y = 0;
-          src.w = rect.w;
-          src.h = rect.h;
-
-          SDL_FillRect(temp, &src, SDL_MapRGB(screen->format, r, g, b));
-
-          SDL_SetAlpha(temp, SDL_SRCALPHA, a);
-
-          SDL_BlitSurface(temp,0,screen,&rect);
-
-          SDL_FreeSurface(temp);
-        }
-      else
-        SDL_FillRect(screen, &rect, SDL_MapRGB(screen->format, r, g, b));
-
-#ifndef NOOPENGL
-
-    }
-#endif
-}
-
-
-/* --- UPDATE SCREEN --- */
-
-void updatescreen(void)
-{
-  if(use_gl)  /*clearscreen(0,0,0);*/
-    SDL_GL_SwapBuffers();
-  else
-    SDL_UpdateRect(screen, 0, 0, screen->w, screen->h);
-}
-
-void flipscreen(void)
-{
-  if(use_gl)
-    SDL_GL_SwapBuffers();
-  else
-    SDL_Flip(screen);
-}
-
-void fadeout()
-{
-  clearscreen(0, 0, 0);
-  white_text->draw_align("Loading...", screen->w/2, screen->h/2, A_HMIDDLE, A_TOP);
-  flipscreen();
-}
-
-void update_rect(SDL_Surface *scr, Sint32 x, Sint32 y, Sint32 w, Sint32 h)
-{
-  if(!use_gl)
-    SDL_UpdateRect(scr, x, y, w, h);
-}
-
diff --git a/src/screen.h b/src/screen.h
deleted file mode 100644 (file)
index 466fe7e..0000000
+++ /dev/null
@@ -1,76 +0,0 @@
-//  $Id$
-//
-//  SuperTux -  A Jump'n Run
-//  Copyright (C) 2000 Bill Kendrick <bill@newbreedsoftware.com>
-//
-//  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.
-
-#ifndef SUPERTUX_SCREEN_H
-#define SUPERTUX_SCREEN_H
-
-#include <SDL.h>
-#ifndef NOOPENGL
-#include <SDL_opengl.h>
-#endif
-#include "texture.h"
-
-#define NO_UPDATE false
-#define UPDATE true
-#define USE_ALPHA 0
-#define IGNORE_ALPHA 1
-
-struct Color
-{
-  Color() 
-    : red(0), green(0), blue(0)
-  {}
-  
-  Color(int red_, int green_, int blue_)
-    : red(red_), green(green_), blue(blue_)
-  {}
-
-  int red, green, blue;
-};
-
-struct Point
-{
-  Point() : x(0), y(0) {}
-
-  Point(const Point& pos)
-    : x(pos.x), y(pos.y) {}
-
-  Point& operator=(const Point& pos)
-  { x = pos.x;
-    y = pos.y; 
-    return *this; }
-
-  Point(int x_, int y_)
-    : x(x_), y(y_) {}
-
-  int x;
-  int y;
-};
-
-void drawline(int x1, int y1, int x2, int y2, int r, int g, int b, int a);
-void clearscreen(int r, int g, int b);
-void drawgradient(Color top_clr, Color bot_clr);
-void fillrect(float x, float y, float w, float h, int r, int g, int b, int a = 255);
-void shrink_fade(Point point, int fade_time);
-void updatescreen(void);
-void flipscreen(void);
-void update_rect(SDL_Surface *scr, Sint32 x, Sint32 y, Sint32 w, Sint32 h);
-void fadeout();
-
-#endif /*SUPERTUX_SCREEN_H*/
diff --git a/src/screen/drawing_context.cpp b/src/screen/drawing_context.cpp
new file mode 100644 (file)
index 0000000..c01d13f
--- /dev/null
@@ -0,0 +1,314 @@
+#include "drawing_context.h"
+
+#include <iostream>
+#include <algorithm>
+#include "texture.h"
+#include "globals.h"
+#include "font.h"
+
+DrawingContext::DrawingContext()
+{
+}
+
+DrawingContext::~DrawingContext()
+{
+}
+
+void
+DrawingContext::draw_surface(const Surface* surface, const Vector& position,
+    int layer)
+{
+  assert(surface != 0);
+  
+  DrawingRequest request;
+
+  request.type = SURFACE;
+  request.layer = layer;
+  request.request_data = const_cast<Surface*> (surface);
+  request.pos = transform.apply(position);
+
+  drawingrequests.push_back(request);
+}
+
+void
+DrawingContext::draw_surface_part(const Surface* surface, const Vector& source,
+    const Vector& size, const Vector& dest, int layer)
+{
+  assert(surface != 0);
+
+  DrawingRequest request;
+
+  request.type = SURFACE_PART;
+  request.layer = layer;
+  request.pos = transform.apply(dest);
+  
+  SurfacePartRequest* surfacepartrequest = new SurfacePartRequest();
+  surfacepartrequest->size = size;
+  surfacepartrequest->source = source;
+  surfacepartrequest->surface = surface;
+  request.request_data = surfacepartrequest;
+
+  drawingrequests.push_back(request);
+}
+
+void
+DrawingContext::draw_text(Font* font, const std::string& text,
+    const Vector& position, int layer)
+{
+  DrawingRequest request;
+
+  request.type = TEXT;
+  request.layer = layer;
+  request.pos = transform.apply(position);
+
+  TextRequest* textrequest = new TextRequest;
+  textrequest->font = font;
+  textrequest->text = text;
+  request.request_data = textrequest;
+
+  drawingrequests.push_back(request);
+}
+
+void
+DrawingContext::draw_text_center(Font* font, const std::string& text,
+    const Vector& position, int layer)
+{
+  DrawingRequest request;
+
+  request.type = TEXT;
+  request.layer = layer;
+  request.pos = transform.apply(position) + Vector(screen->w/2 - 
+      font->get_text_width(text)/2, 0);
+
+  TextRequest* textrequest = new TextRequest;
+  textrequest->font = font;
+  textrequest->text = text;
+  request.request_data = textrequest;
+
+  drawingrequests.push_back(request);
+}
+
+void
+DrawingContext::draw_gradient(Color top, Color bottom, int layer)
+{
+  DrawingRequest request;
+
+  request.type = GRADIENT;
+  request.layer = layer;
+  request.pos = Vector(0,0);
+
+  GradientRequest* gradientrequest = new GradientRequest;
+  gradientrequest->top = top;
+  gradientrequest->bottom = bottom;
+  request.request_data = gradientrequest;
+
+  drawingrequests.push_back(request);
+}
+
+void
+DrawingContext::draw_filled_rect(const Vector& topleft, const Vector& size,
+        Color color, int layer)
+{
+  DrawingRequest request;
+
+  request.type = FILLRECT;
+  request.layer = layer;
+  request.pos = topleft;
+
+  FillRectRequest* fillrectrequest = new FillRectRequest;
+  fillrectrequest->size = size;
+  fillrectrequest->color = color;
+  request.request_data = fillrectrequest;
+
+  drawingrequests.push_back(request);
+}
+
+void
+DrawingContext::draw_surface_part(DrawingRequest& request)
+{
+  SurfacePartRequest* surfacepartrequest
+    = (SurfacePartRequest*) request.request_data;
+
+  surfacepartrequest->surface->impl->draw_part(
+      surfacepartrequest->source.x, surfacepartrequest->source.y,
+      request.pos.x, request.pos.y,
+      surfacepartrequest->size.x, surfacepartrequest->size.y, 255);
+
+  delete surfacepartrequest;
+}
+
+void
+DrawingContext::draw_gradient(DrawingRequest& request)
+{
+  GradientRequest* gradientrequest = (GradientRequest*) request.request_data;
+  const Color& top = gradientrequest->top;
+  const Color& bottom = gradientrequest->bottom;
+  
+#ifndef NOOPENGL
+  if(use_gl)
+    {
+      glBegin(GL_QUADS);
+      glColor3ub(top.red, top.green, top.blue);
+      glVertex2f(0, 0);
+      glVertex2f(screen->w, 0);
+      glColor3ub(bottom.red, bottom.green, bottom.blue);
+      glVertex2f(screen->w, screen->h);
+      glVertex2f(0, screen->h);
+      glEnd();
+    }
+  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);
+#ifndef NOOPENGL
+
+    }
+#endif
+
+  delete gradientrequest;
+}
+
+void
+DrawingContext::draw_text(DrawingRequest& request)
+{
+  TextRequest* textrequest = (TextRequest*) request.request_data;
+  
+  textrequest->font->draw(textrequest->text, request.pos);
+
+  delete textrequest;
+}
+
+void
+DrawingContext::draw_filled_rect(DrawingRequest& request)
+{
+  FillRectRequest* fillrectrequest = (FillRectRequest*) request.request_data;
+
+  float x = request.pos.x;
+  float y = request.pos.y;
+  float w = fillrectrequest->size.x;
+  float h = fillrectrequest->size.y;
+#ifndef NOOPENGL
+  if(use_gl)
+    {
+      glEnable(GL_BLEND);
+      glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+      glColor4ub(fillrectrequest->color.red, fillrectrequest->color.green,
+          fillrectrequest->color.blue, fillrectrequest->color.alpha);
+
+      glBegin(GL_POLYGON);
+      glVertex2f(x, y);
+      glVertex2f(x+w, y);
+      glVertex2f(x+w, y+h);
+      glVertex2f(x, y+h);
+      glEnd();
+      glDisable(GL_BLEND);
+    }
+  else
+    {
+#endif
+      SDL_Rect src, rect;
+      SDL_Surface *temp = NULL;
+                                                                                
+      rect.x = (int)x;
+      rect.y = (int)y;
+      rect.w = (int)w;
+      rect.h = (int)h;
+                                                                                
+      if(fillrectrequest->color.alpha != 255)
+        {
+          temp = SDL_CreateRGBSurface(screen->flags, rect.w, rect.h, screen->format->BitsPerPixel,
+                                      screen->format->Rmask,
+                                      screen->format->Gmask,
+                                      screen->format->Bmask,
+                                      screen->format->Amask);
+                                                                                
+                                                                                
+          src.x = 0;
+          src.y = 0;
+          src.w = rect.w;
+          src.h = rect.h;
+                                                                                
+          SDL_FillRect(temp, &src, SDL_MapRGB(screen->format, 
+                fillrectrequest->color.red, fillrectrequest->color.green,
+                fillrectrequest->color.blue));
+                                                                                
+          SDL_SetAlpha(temp, SDL_SRCALPHA, fillrectrequest->color.alpha);
+                                                                                
+          SDL_BlitSurface(temp,0,screen,&rect);
+                                                                                
+          SDL_FreeSurface(temp);
+        }
+      else
+        SDL_FillRect(screen, &rect, SDL_MapRGB(screen->format, 
+              fillrectrequest->color.red, fillrectrequest->color.green,
+              fillrectrequest->color.blue));
+                                                                                
+#ifndef NOOPENGL
+                                                                                
+    }
+#endif
+
+  delete fillrectrequest;
+}
+
+void
+DrawingContext::do_drawing()
+{
+  std::sort(drawingrequests.begin(), drawingrequests.end());
+
+  for(DrawingRequests::iterator i = drawingrequests.begin();
+      i != drawingrequests.end(); ++i) {
+    switch(i->type) {
+      case SURFACE:
+      {
+        const Surface* surface = (const Surface*) i->request_data;
+        surface->impl->draw(i->pos.x, i->pos.y, 255);
+        break;
+      }
+      case SURFACE_PART:
+        draw_surface_part(*i);
+        break;
+      case GRADIENT:
+        draw_gradient(*i);
+        break;
+      case TEXT:
+        draw_text(*i);
+        break;
+      case FILLRECT:
+        draw_filled_rect(*i);
+        break;
+    }
+  }
+
+  // update screen
+  if(use_gl)
+    SDL_GL_SwapBuffers();
+  else
+    SDL_Flip(screen);
+
+  drawingrequests.clear();
+}
+
+void
+DrawingContext::push_transform()
+{
+  transformstack.push_back(transform);
+}
+
+void
+DrawingContext::pop_transform()
+{
+  assert(!transformstack.empty());
+
+  transform = transformstack.back();
+  transformstack.pop_back();
+}
+
diff --git a/src/screen/drawing_context.h b/src/screen/drawing_context.h
new file mode 100644 (file)
index 0000000..c763cfb
--- /dev/null
@@ -0,0 +1,151 @@
+#ifndef __DRAWINGCONTEXT_H__
+#define __DRAWINGCONTEXT_H__
+
+#include <vector>
+#include <string>
+#include "vector.h"
+#include <SDL.h>
+
+class Surface;
+class Font;
+
+// some constants for predefined layer values
+enum {
+  LAYER_BACKGROUND0 = -300,
+  LAYER_BACKGROUND1 = -200,
+  LAYER_BACKGROUNDTILES = -100,
+  LAYER_TILES = 0,
+  LAYER_OBJECTS = 100,
+  LAYER_FOREGROUNDTILES = 200,
+  LAYER_FOREGROUND0 = 300,
+  LAYER_FOREGROUND1 = 400
+};
+
+class Color
+{
+public:
+  Color() 
+    : red(0), green(0), blue(0), alpha(0)
+  {}
+  
+  Color(Uint8 red_, Uint8 green_, Uint8 blue_, Uint8 alpha_ = 0)
+    : red(red_), green(green_), blue(blue_), alpha(alpha_)
+  {}
+
+  Color(const Color& o)
+    : red(o.red), green(o.green), blue(o.blue), alpha(o.alpha)
+  { }
+
+  Uint8 red, green, blue, alpha;
+};
+
+/**
+ * This class provides functions for drawing things on screen. It also
+ * maintains a stack of transforms that are applied to graphics.
+ */
+class DrawingContext
+{
+public:
+  DrawingContext();
+  ~DrawingContext();
+
+  /** Adds a drawing request for a surface into the request list */
+  void draw_surface(const Surface* surface, const Vector& position, int layer);
+  /** Adds a drawing request for part of a surface */
+  void draw_surface_part(const Surface* surface, const Vector& source,
+      const Vector& size, const Vector& dest, int layer);
+  /** draws a text */
+  void draw_text(Font* font, const std::string& text, const Vector& position,
+      int layer);
+  /** draws aligned text */
+  void draw_text_center(Font* font, const std::string& text,
+      const Vector& position, int layer);
+  /** draws a color gradient onto the whole screen */  
+  void draw_gradient(Color from, Color to, int layer);
+  /** fills a rectangle */
+  void draw_filled_rect(const Vector& topleft, const Vector& downright,
+          Color color, int layer);
+  
+  /** Processes all pending drawing requests and flushes the list */
+  void do_drawing();
+
+  const Vector& get_translation() const
+  { return transform.translation; }
+  void set_translation(const Vector& newtranslation)
+  { transform.translation = newtranslation; }
+
+  void push_transform();
+  void pop_transform();
+
+private:
+  class Transform
+  {
+  public:
+    Vector translation; // only translation for now...
+
+    Vector apply(const Vector& v) const
+    {
+      return v - translation;
+    }
+  };
+
+  /// the transform stack
+  std::vector<Transform> transformstack;
+  /// the currently active transform
+  Transform transform;
+
+  enum RequestType
+  {
+    SURFACE, SURFACE_PART, TEXT, GRADIENT, FILLRECT
+  };
+
+  struct SurfacePartRequest
+  {
+    const Surface* surface;
+    Vector source, size;
+  };
+
+  struct TextRequest
+  {
+    Font* font;
+    std::string text;
+  };
+
+  struct GradientRequest
+  {
+    Color top, bottom;
+    Vector size;
+  };
+
+  struct FillRectRequest
+  {
+    Color color;
+    Vector size;
+  };
+
+  struct DrawingRequest
+  {
+    int layer;
+
+    RequestType type;
+    Vector pos;
+
+    void* request_data;
+
+    bool operator<(const DrawingRequest& other) const
+    {
+      return layer < other.layer;
+    }
+  };
+
+  void draw_surface_part(DrawingRequest& request);
+  void draw_text(DrawingRequest& request);
+  void draw_gradient(DrawingRequest& request);
+  void draw_filled_rect(DrawingRequest& request);
+  
+  typedef std::vector<DrawingRequest> DrawingRequests;
+  DrawingRequests drawingrequests;
+};
+
+#endif
+
diff --git a/src/screen/font.cpp b/src/screen/font.cpp
new file mode 100644 (file)
index 0000000..45f9e93
--- /dev/null
@@ -0,0 +1,283 @@
+//  $Id$
+// 
+//  SuperTux
+//  Copyright (C) 2004 Tobias Glaesser <tobi.web@gmx.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 <stdlib.h>
+#include <string.h>
+#include "globals.h"
+#include "defines.h"
+#include "screen.h"
+#include "font.h"
+#include "drawing_context.h"
+
+Font::Font(const std::string& file, int kind_, int w_, int h_, int shadowsize_)
+{
+  kind = kind_;
+  w = w_;
+  h = h_;
+  shadowsize = shadowsize_;
+
+  int mx, my;
+  SDL_Surface *conv;
+  int pixels;
+  int i;
+  
+  if(kind == TEXT_TEXT)
+    {
+      mx = 26;
+      my = 3;
+    }
+  else if(kind == TEXT_NUM)
+    {
+      mx = 10;
+      my = 1;
+    }
+  else
+    {
+      mx = 0;
+      my = 0;
+    }
+
+  chars = new Surface(file, USE_ALPHA);
+
+  // Load shadow font.
+  conv = SDL_DisplayFormatAlpha(chars->impl->get_sdl_surface());
+  pixels = conv->w * conv->h;
+  SDL_LockSurface(conv);
+  for(i = 0; i < pixels; ++i)
+    {
+      Uint32 *p = (Uint32 *)conv->pixels + i;
+      *p = *p & conv->format->Amask;
+    }
+  SDL_UnlockSurface(conv);
+  SDL_SetAlpha(conv, SDL_SRCALPHA, 128);
+  shadow_chars = new Surface(conv, USE_ALPHA);
+
+  SDL_FreeSurface(conv);
+}
+
+Font::~Font()
+{
+  delete chars;
+  delete shadow_chars;
+}
+
+float
+Font::get_height() const
+{
+  return h;
+}
+
+float
+Font::get_text_width(const std::string& text) const
+{
+  return text.size() * w;
+}
+
+void
+Font::draw(const std::string& text, const Vector& pos)
+{
+  if(shadowsize != 0)
+    draw_chars(shadow_chars, text, pos + Vector(shadowsize, shadowsize));
+
+  draw_chars(chars, text, pos);
+}
+
+void
+Font::draw_chars(Surface* pchars, const std::string& text, const Vector& pos)
+{
+  size_t i, j;
+
+  SurfaceImpl* impl = pchars->impl;
+
+  int x = int(pos.x);
+  int y = int(pos.y);
+  if(kind == TEXT_TEXT)
+    {
+      for( i = 0, j = 0; i < text.size(); ++i,++j)
+        {
+          if( text[i] >= ' ' && text[i] <= '/')
+            impl->draw_part((int)(text[i] - ' ')*w,  0 , x+(j*w), y, w, h, 255);
+          else if( text[i] >= '0' && text[i] <= '?')
+            impl->draw_part((int)(text[i] - '0')*w, h*1, x+(j*w), y, w, h, 255);
+          else if ( text[i] >= '@' && text[i] <= 'O')
+            impl->draw_part((int)(text[i] - '@')*w, h*2, x+(j*w), y, w, h, 255);
+          else if ( text[i] >= 'P' && text[i] <= '_')
+            impl->draw_part((int)(text[i] - 'P')*w, h*3, x+(j*w), y, w, h, 255);
+          else if ( text[i] >= '`' && text[i] <= 'o')
+            impl->draw_part((int)(text[i] - '`')*w, h*4, x+(j*w), y, w, h, 255);
+          else if ( text[i] >= 'p' && text[i] <= '~')
+            impl->draw_part((int)(text[i] - 'p')*w, h*5, x+(j*w), y, w, h, 255);
+          else if ( text[i] == '\n')
+            {
+              y += h + 2;
+              j = 0;
+            }
+        }
+    }
+  else if(kind == TEXT_NUM)
+    {
+      for( i = 0, j = 0; i < text.size(); ++i, ++j)
+        {
+          if ( text[i] >= '0' && text[i] <= '9')
+            impl->draw_part((int)(text[i] - '0')*w, 0, x+(j*w), y, w, h, 255);
+          else if ( text[i] == '\n')
+            {
+              y += h + 2;
+              j = 0;
+            }
+        }
+    }
+}
+
+/* --- SCROLL TEXT FUNCTION --- */
+
+#define MAX_VEL     10
+#define SPEED_INC   0.01
+#define SCROLL      60
+#define ITEMS_SPACE 4
+
+void display_text_file(const std::string& file, const std::string& surface, float scroll_speed)
+{
+  Surface* sur = new Surface(datadir + surface, IGNORE_ALPHA);
+  display_text_file(file, sur, scroll_speed);
+  delete sur;
+}
+
+void display_text_file(const std::string& file, Surface* surface, float scroll_speed)
+{
+  int done;
+  float scroll;
+  float speed;
+  FILE* fi;
+  char temp[1024];
+  std::vector<std::string> names;
+  char filename[1024];
+  
+  sprintf(filename,"%s/%s", datadir.c_str(), file.c_str());
+  if((fi = fopen(filename,"r")) != NULL)
+    {
+      while(fgets(temp, sizeof(temp), fi) != NULL)
+        {
+          temp[strlen(temp)-1]='\0';
+          names.push_back(temp);
+        }
+      fclose(fi);
+    }
+  else
+    {
+      names.push_back("File was not found!");
+      names.push_back(filename);
+      names.push_back("Shame on the guy, who");
+      names.push_back("forgot to include it");
+      names.push_back("in your SuperTux distribution.");
+    }
+
+  scroll = 0;
+  speed = scroll_speed / 50;
+  done = 0;
+
+  DrawingContext context;
+  SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
+
+  Uint32 lastticks = SDL_GetTicks();
+  while(!done)
+    {
+      /* in case of input, exit */
+      SDL_Event event;
+      while(SDL_PollEvent(&event))
+        switch(event.type)
+          {
+          case SDL_KEYDOWN:
+            switch(event.key.keysym.sym)
+              {
+              case SDLK_UP:
+                speed -= SPEED_INC;
+                break;
+              case SDLK_DOWN:
+                speed += SPEED_INC;
+                break;
+              case SDLK_SPACE:
+              case SDLK_RETURN:
+                if(speed >= 0)
+                  scroll += SCROLL;
+                break;
+              case SDLK_ESCAPE:
+                done = 1;
+                break;
+              default:
+                break;
+              }
+            break;
+          case SDL_QUIT:
+            done = 1;
+            break;
+          default:
+            break;
+          }
+
+      if(speed > MAX_VEL)
+        speed = MAX_VEL;
+      else if(speed < -MAX_VEL)
+        speed = -MAX_VEL;
+
+      /* draw the credits */
+      context.draw_surface(surface, Vector(0,0), 0);
+
+      float y = 0;
+      for(size_t i = 0; i < names.size(); i++) {
+        if(names[i].size() == 0) {
+          y += white_text->get_height() + ITEMS_SPACE;
+          continue;
+        }
+
+        Font* font = 0;
+        switch(names[i][0])
+        {
+          case ' ': font = white_small_text; break;
+          case '\t': font = white_text; break;
+          case '-': font = white_big_text; break;
+          case '*': font = blue_text; break;
+          default: font = blue_text; break;
+        }
+
+        context.draw_text_center(font,
+            names[i].substr(1, names[i].size()-1),
+            Vector(0, screen->h + y - scroll), LAYER_FOREGROUND1);
+        y += font->get_height() + ITEMS_SPACE;
+      }
+
+      context.do_drawing();
+
+      if(screen->h+y-scroll < 0 && 20+screen->h+y-scroll < 0)
+        done = 1;
+
+      Uint32 ticks = SDL_GetTicks();
+      scroll += speed * (ticks - lastticks);
+      lastticks = ticks;
+      if(scroll < 0)
+        scroll = 0;
+
+      SDL_Delay(10);
+    }
+
+  SDL_EnableKeyRepeat(0, 0);    // disables key repeating
+  Menu::set_current(main_menu);
+}
+
diff --git a/src/screen/font.h b/src/screen/font.h
new file mode 100644 (file)
index 0000000..7f398bc
--- /dev/null
@@ -0,0 +1,63 @@
+//  $Id$
+// 
+//  SuperTux
+//  Copyright (C) 2004 Tobias Glaesser <tobi.web@gmx.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.
+
+#ifndef SUPERTUX_TEXT_H
+#define SUPERTUX_TEXT_H
+
+#include <string>
+#include "texture.h"
+#include "vector.h"
+
+void display_text_file(const std::string& file, const std::string& surface, float scroll_speed);
+void display_text_file(const std::string& file, Surface* surface, float scroll_speed);
+
+/* Kinds of texts. */
+enum {
+   TEXT_TEXT,
+   TEXT_NUM
+};
+
+/* Text type */
+class Font
+{
+public:
+  Surface* chars;
+  Surface* shadow_chars;
+  int kind;
+  int w;
+  int h;
+  int shadowsize;
+public:
+  Font(const std::string& file, int kind, int w, int h, int shadowsize = 2);
+  ~Font();
+
+  float get_height() const;
+  float get_text_width(const std::string& text) const;
+
+private:
+  friend class DrawingContext;
+  
+  void draw(const std::string& text, const Vector& pos);
+  void draw_chars(Surface* pchars, const std::string& text, 
+      const Vector& position);
+};
+
+#endif /*SUPERTUX_TEXT_H*/
+
diff --git a/src/screen/screen.cpp b/src/screen/screen.cpp
new file mode 100644 (file)
index 0000000..a9cf2bc
--- /dev/null
@@ -0,0 +1,329 @@
+//  $Id$
+//
+//  SuperTux -  A Jump'n Run
+//  Copyright (C) 2000 Bill Kendrick <bill@newbreedsoftware.com>
+//
+//  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 <iostream>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <SDL.h>
+#include <SDL_image.h>
+
+#ifndef WIN32
+#include <sys/types.h>
+#include <ctype.h>
+#endif
+
+#include "defines.h"
+#include "globals.h"
+#include "screen.h"
+#include "setup.h"
+#include "drawing_context.h"
+#include "type.h"
+
+/* Needed for line calculations */
+#define SGN(x) ((x)>0 ? 1 : ((x)==0 ? 0:(-1)))
+#define ABS(x) ((x)>0 ? (x) : (-x))
+
+/* --- FADE IN --- */
+
+/** Fades the given surface into a black one. If fade_out is true, it will fade out, else
+it will fade in */
+
+#if 0
+void fade(Surface *surface, int seconds, bool fade_out);
+
+void fade(const std::string& surface, int seconds, bool fade_out)
+{
+Surface* sur = new Surface(datadir + surface, IGNORE_ALPHA);
+fade(sur, seconds, fade_out);
+delete sur;
+}
+
+void fade(Surface *surface, int seconds, bool fade_out)
+{
+float alpha;
+if (fade_out)
+  alpha = 0;
+else
+  alpha = 255;
+
+  int cur_time, old_time;
+  cur_time = SDL_GetTicks();
+
+  while(alpha >= 0 && alpha < 256)
+    {
+    surface->draw(0,0,(int)alpha);
+    flipscreen();
+
+    old_time = cur_time;
+    cur_time = SDL_GetTicks();
+
+    /* Calculate the next alpha value */
+    float calc = (float) ((cur_time - old_time) / seconds);
+    if(fade_out)
+      alpha += 255 * calc;
+    else
+      alpha -= 255 * calc;
+    }
+}
+#endif
+
+/* 'Stolen' from the SDL documentation.
+ * Set the pixel at (x, y) to the given value
+ * NOTE: The surface must be locked before calling this!
+ */
+void putpixel(SDL_Surface *surface, int x, int y, Uint32 pixel)
+{
+  int bpp = surface->format->BytesPerPixel;
+  /* Here p is the address to the pixel we want to set */
+  Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;
+
+  switch(bpp)
+    {
+    case 1:
+      *p = pixel;
+      break;
+
+    case 2:
+      *(Uint16 *)p = pixel;
+      break;
+
+    case 3:
+      if(SDL_BYTEORDER == SDL_BIG_ENDIAN)
+        {
+          p[0] = (pixel >> 16) & 0xff;
+          p[1] = (pixel >> 8) & 0xff;
+          p[2] = pixel & 0xff;
+        }
+      else
+        {
+          p[0] = pixel & 0xff;
+          p[1] = (pixel >> 8) & 0xff;
+          p[2] = (pixel >> 16) & 0xff;
+        }
+      break;
+
+    case 4:
+      *(Uint32 *)p = pixel;
+      break;
+    }
+}
+
+/* Draw a single pixel on the screen. */
+void drawpixel(int x, int y, Uint32 pixel)
+{
+  /* Lock the screen for direct access to the pixels */
+  if ( SDL_MUSTLOCK(screen) )
+    {
+      if ( SDL_LockSurface(screen) < 0 )
+        {
+          fprintf(stderr, "Can't lock screen: %s\n", SDL_GetError());
+          return;
+        }
+    }
+
+  if(!(x < 0 || y < 0 || x > screen->w || y > screen->h))
+    putpixel(screen, x, y, pixel);
+
+  if ( SDL_MUSTLOCK(screen) )
+    {
+      SDL_UnlockSurface(screen);
+    }
+  /* Update just the part of the display that we've changed */
+  SDL_UpdateRect(screen, x, y, 1, 1);
+}
+
+void drawline(int x1, int y1, int x2, int y2, int r, int g, int b, int a)
+{
+#ifndef NOOPENGL
+  if(use_gl)
+    {
+      glEnable(GL_BLEND);
+      glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+      glColor4ub(r, g, b,a);
+
+      glBegin(GL_LINES);
+      glVertex2f(x1, y1);
+      glVertex2f(x2, y2);
+      glEnd();
+      glDisable(GL_BLEND);
+    }
+  else
+    {
+#endif
+
+      /* Basic unantialiased Bresenham line algorithm */
+      int lg_delta, sh_delta, cycle, lg_step, sh_step;
+      Uint32 color = SDL_MapRGBA(screen->format, r, g, b, a);
+
+      lg_delta = x2 - x1;
+      sh_delta = y2 - y1;
+      lg_step = SGN(lg_delta);
+      lg_delta = ABS(lg_delta);
+      sh_step = SGN(sh_delta);
+      sh_delta = ABS(sh_delta);
+      if (sh_delta < lg_delta)
+        {
+          cycle = lg_delta >> 1;
+          while (x1 != x2)
+            {
+              drawpixel(x1, y1, color);
+              cycle += sh_delta;
+              if (cycle > lg_delta)
+                {
+                  cycle -= lg_delta;
+                  y1 += sh_step;
+                }
+              x1 += lg_step;
+            }
+          drawpixel(x1, y1, color);
+        }
+      cycle = sh_delta >> 1;
+      while (y1 != y2)
+        {
+          drawpixel(x1, y1, color);
+          cycle += lg_delta;
+          if (cycle > sh_delta)
+            {
+              cycle -= sh_delta;
+              x1 += lg_step;
+            }
+          y1 += sh_step;
+        }
+      drawpixel(x1, y1, color);
+#ifndef NOOPENGL
+
+    }
+#endif
+}
+
+/* --- FILL A RECT --- */
+
+void fillrect(float x, float y, float w, float h, int r, int g, int b, int a)
+{
+if(w < 0)
+       {
+       x += w;
+       w = -w;
+       }
+if(h < 0)
+       {
+       y += h;
+       h = -h;
+       }
+
+#ifndef NOOPENGL
+  if(use_gl)
+    {
+      glEnable(GL_BLEND);
+      glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+      glColor4ub(r, g, b,a);
+
+      glBegin(GL_POLYGON);
+      glVertex2f(x, y);
+      glVertex2f(x+w, y);
+      glVertex2f(x+w, y+h);
+      glVertex2f(x, y+h);
+      glEnd();
+      glDisable(GL_BLEND);
+    }
+  else
+    {
+#endif
+      SDL_Rect src, rect;
+      SDL_Surface *temp = NULL;
+
+      rect.x = (int)x;
+      rect.y = (int)y;
+      rect.w = (int)w;
+      rect.h = (int)h;
+
+      if(a != 255)
+        {
+          temp = SDL_CreateRGBSurface(screen->flags, rect.w, rect.h, screen->format->BitsPerPixel,
+                                      screen->format->Rmask,
+                                      screen->format->Gmask,
+                                      screen->format->Bmask,
+                                      screen->format->Amask);
+
+
+          src.x = 0;
+          src.y = 0;
+          src.w = rect.w;
+          src.h = rect.h;
+
+          SDL_FillRect(temp, &src, SDL_MapRGB(screen->format, r, g, b));
+
+          SDL_SetAlpha(temp, SDL_SRCALPHA, a);
+
+          SDL_BlitSurface(temp,0,screen,&rect);
+
+          SDL_FreeSurface(temp);
+        }
+      else
+        SDL_FillRect(screen, &rect, SDL_MapRGB(screen->format, r, g, b));
+
+#ifndef NOOPENGL
+
+    }
+#endif
+}
+
+
+void fadeout()
+{
+  fillrect(0, 0, screen->w, screen->h, 0, 0, 0, 255);
+  
+  DrawingContext context;
+  context.draw_text_center(white_text, "Loading...",
+      Vector(0, screen->h/2), LAYER_FOREGROUND1);
+  context.do_drawing();
+}
+
+#define LOOP_DELAY 20.0
+void shrink_fade(const Vector& point, float fade_time)
+{
+  float left_inc  = point.x / (fade_time / LOOP_DELAY);
+  float right_inc = (screen->w - point.x) / (fade_time / LOOP_DELAY);
+  float up_inc    = point.y / (fade_time / LOOP_DELAY);
+  float down_inc  = (screen->h - point.y) / (fade_time / LOOP_DELAY);
+                                                                                
+  float left_cor = 0, right_cor = 0, up_cor = 0, down_cor = 0;
+                                                                                
+  while(left_cor < point.x && right_cor < screen->w - point.x &&
+      up_cor < point.y && down_cor < screen->h - point.y)
+  {
+    left_cor  += left_inc;
+    right_cor += right_inc;
+    up_cor    += up_inc;
+    down_cor  += down_inc;
+                                                                                
+    fillrect(0, 0, left_cor, screen->h, 0,0,0);  // left side
+    fillrect(screen->w - right_cor, 0, right_cor, screen->h, 0,0,0);  // right side
+    fillrect(0, 0, screen->w, up_cor, 0,0,0);  // up side
+    fillrect(0, screen->h - down_cor, screen->w, down_cor+1, 0,0,0);  // down side                                                                                
+    DrawingContext context; // ugly...
+    context.do_drawing();
+    
+    SDL_Delay(int(LOOP_DELAY));
+  }
+}
+
diff --git a/src/screen/screen.h b/src/screen/screen.h
new file mode 100644 (file)
index 0000000..64c42c2
--- /dev/null
@@ -0,0 +1,45 @@
+//  $Id$
+//
+//  SuperTux -  A Jump'n Run
+//  Copyright (C) 2000 Bill Kendrick <bill@newbreedsoftware.com>
+//
+//  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.
+
+#ifndef SUPERTUX_SCREEN_H
+#define SUPERTUX_SCREEN_H
+
+#include <SDL.h>
+#ifndef NOOPENGL
+#include <SDL_opengl.h>
+#endif
+#include "texture.h"
+
+class Vector;
+
+#define NO_UPDATE false
+#define UPDATE true
+#define USE_ALPHA 0
+#define IGNORE_ALPHA 1
+
+void drawline(int x1, int y1, int x2, int y2, int r, int g, int b, int a);
+void fillrect(float x, float y, float w, float h, int r, int g, int b,
+    int a = 255);
+void shrink_fade(const Vector& point, float fade_time);
+//void black_fade(Surface* surface, int seconds, bool fade_out);
+void fade(const std::string& surface, int seconds, bool fade_out);
+void update_rect(SDL_Surface *scr, Sint32 x, Sint32 y, Sint32 w, Sint32 h);
+void fadeout();
+
+#endif /*SUPERTUX_SCREEN_H*/
diff --git a/src/screen/texture.cpp b/src/screen/texture.cpp
new file mode 100644 (file)
index 0000000..6813296
--- /dev/null
@@ -0,0 +1,695 @@
+//  $Id$
+//
+//  SuperTux
+//  Copyright (C) 2004 Tobias Glaesser <tobi.web@gmx.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 <assert.h>
+#include <iostream>
+#include <algorithm>
+#include "SDL.h"
+#include "SDL_image.h"
+#include "texture.h"
+#include "globals.h"
+#include "setup.h"
+
+Surface::Surfaces Surface::surfaces;
+
+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), 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), surface(0), file(file_), use_alpha(use_alpha_),
+    x(x_), y(y_), w(w_), h(h_)
+{}
+
+SurfaceData::~SurfaceData()
+{
+  SDL_FreeSurface(surface);
+}
+
+SurfaceImpl*
+SurfaceData::create()
+{
+#ifndef NOOPENGL
+  if (use_gl)
+    return create_SurfaceOpenGL();
+  else
+    return create_SurfaceSDL();
+#else
+  return create_SurfaceSDL();
+#endif
+}
+
+SurfaceSDL*
+SurfaceData::create_SurfaceSDL()
+{
+  switch(type)
+  {
+  case LOAD:
+    return new SurfaceSDL(file, use_alpha);
+  case LOAD_PART:
+    return new SurfaceSDL(file, x, y, w, h, use_alpha);
+  case SURFACE:
+    return new SurfaceSDL(surface, use_alpha);
+  }
+  assert(0);
+}
+
+SurfaceOpenGL*
+SurfaceData::create_SurfaceOpenGL()
+{
+#ifndef NOOPENGL
+  switch(type)
+  {
+  case LOAD:
+    return new SurfaceOpenGL(file, use_alpha);
+  case LOAD_PART:
+    return new SurfaceOpenGL(file, x, y, w, h, use_alpha);
+  case SURFACE:
+    return new SurfaceOpenGL(surface, use_alpha);
+  }
+#endif
+  assert(0);
+}
+
+#ifndef NOOPENGL
+/* Quick utility function for texture creation */
+static int power_of_two(int input)
+{
+  int value = 1;
+
+  while ( value < input )
+  {
+    value <<= 1;
+  }
+  return value;
+}
+#endif
+
+Surface::Surface(SDL_Surface* surf, int use_alpha)
+    : data(surf, use_alpha), w(0), h(0)
+{
+  impl = data.create();
+  if (impl)
+  {
+    w = impl->w;
+    h = impl->h;
+  }
+  surfaces.push_back(this);
+}
+
+Surface::Surface(const std::string& file, int use_alpha)
+    : data(file, use_alpha), w(0), h(0)
+{
+  impl = data.create();
+  if (impl)
+  {
+    w = impl->w;
+    h = impl->h;
+  }
+  surfaces.push_back(this);
+}
+
+Surface::Surface(const std::string& file, int x, int y, int w, int h, int use_alpha)
+    : data(file, x, y, w, h, use_alpha), w(0), h(0)
+{
+  impl = data.create();
+  if (impl)
+  {
+    w = impl->w;
+    h = impl->h;
+  }
+  surfaces.push_back(this);
+}
+
+void
+Surface::reload()
+{
+  delete impl;
+  impl = data.create();
+  if (impl)
+  {
+    w = impl->w;
+    h = impl->h;
+  }
+}
+
+Surface::~Surface()
+{
+#ifdef DEBUG
+  bool found = false;
+  for(std::list<Surface*>::iterator i = surfaces.begin(); i != surfaces.end();
+      ++i)
+  {
+    if(*i == this)
+    {
+      found = true; break;
+    }
+  }
+  if(!found)
+    printf("Error: Surface freed twice!!!\n");
+#endif
+  surfaces.remove(this);
+  delete impl;
+}
+
+void
+Surface::reload_all()
+{
+  for(Surfaces::iterator i = surfaces.begin(); i != surfaces.end(); ++i)
+  {
+    (*i)->reload();
+  }
+}
+
+void
+Surface::debug_check()
+{
+  for(Surfaces::iterator i = surfaces.begin(); i != surfaces.end(); ++i)
+  {
+    printf("Surface not freed: T:%d F:%s.\n", (*i)->data.type,
+           (*i)->data.file.c_str());
+  }
+}
+
+void
+Surface::resize(int w_, int h_)
+{
+  if (impl)
+  {
+    w = w_;
+    h = h_;
+    if (impl->resize(w_,h_) == -2)
+      reload();
+  }
+}
+
+SDL_Surface*
+sdl_surface_part_from_file(const std::string& file, int x, int y, int w, int h,  int use_alpha)
+{
+  SDL_Rect src;
+  SDL_Surface * sdl_surface;
+  SDL_Surface * temp;
+  SDL_Surface * conv;
+
+  temp = IMG_Load(file.c_str());
+
+  if (temp == NULL)
+    st_abort("Can't load", file);
+
+  /* Set source rectangle for conv: */
+
+  src.x = x;
+  src.y = y;
+  src.w = w;
+  src.h = h;
+
+  conv = SDL_CreateRGBSurface(temp->flags, w, h, temp->format->BitsPerPixel,
+                              temp->format->Rmask,
+                              temp->format->Gmask,
+                              temp->format->Bmask,
+                              temp->format->Amask);
+
+  /* #if SDL_BYTEORDER == SDL_BIG_ENDIAN
+     0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff);
+     #else
+
+     0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000);
+     #endif*/
+
+  SDL_SetAlpha(temp,0,0);
+
+  SDL_BlitSurface(temp, &src, conv, NULL);
+  if(use_alpha == IGNORE_ALPHA && !use_gl)
+    sdl_surface = SDL_DisplayFormat(conv);
+  else
+    sdl_surface = SDL_DisplayFormatAlpha(conv);
+
+  if (sdl_surface == NULL)
+    st_abort("Can't covert to display format", file);
+
+  if (use_alpha == IGNORE_ALPHA && !use_gl)
+    SDL_SetAlpha(sdl_surface, 0, 0);
+
+  SDL_FreeSurface(temp);
+  SDL_FreeSurface(conv);
+
+  return sdl_surface;
+}
+
+SDL_Surface*
+sdl_surface_from_file(const std::string& file, int use_alpha)
+{
+  SDL_Surface* sdl_surface;
+  SDL_Surface* temp;
+
+  temp = IMG_Load(file.c_str());
+
+  if (temp == NULL)
+    st_abort("Can't load", file);
+
+  if(use_alpha == IGNORE_ALPHA && !use_gl)
+    sdl_surface = SDL_DisplayFormat(temp);
+  else
+    sdl_surface = SDL_DisplayFormatAlpha(temp);
+
+  if (sdl_surface == NULL)
+    st_abort("Can't covert to display format", file);
+
+  if (use_alpha == IGNORE_ALPHA && !use_gl)
+    SDL_SetAlpha(sdl_surface, 0, 0);
+
+  SDL_FreeSurface(temp);
+
+  return sdl_surface;
+}
+
+SDL_Surface*
+sdl_surface_from_sdl_surface(SDL_Surface* sdl_surf, int use_alpha)
+{
+  SDL_Surface* sdl_surface;
+  Uint32 saved_flags;
+  Uint8  saved_alpha;
+
+  /* Save the alpha blending attributes */
+  saved_flags = sdl_surf->flags&(SDL_SRCALPHA|SDL_RLEACCELOK);
+  saved_alpha = sdl_surf->format->alpha;
+  if ( (saved_flags & SDL_SRCALPHA)
+       == SDL_SRCALPHA )
+  {
+    SDL_SetAlpha(sdl_surf, 0, 0);
+  }
+
+  if(use_alpha == IGNORE_ALPHA && !use_gl)
+    sdl_surface = SDL_DisplayFormat(sdl_surf);
+  else
+    sdl_surface = SDL_DisplayFormatAlpha(sdl_surf);
+
+  /* Restore the alpha blending attributes */
+  if ( (saved_flags & SDL_SRCALPHA)
+       == SDL_SRCALPHA )
+  {
+    SDL_SetAlpha(sdl_surface, saved_flags, saved_alpha);
+  }
+
+  if (sdl_surface == NULL)
+    st_abort("Can't covert to display format", "SURFACE");
+
+  if (use_alpha == IGNORE_ALPHA && !use_gl)
+    SDL_SetAlpha(sdl_surface, 0, 0);
+
+  return sdl_surface;
+}
+
+//---------------------------------------------------------------------------
+
+SurfaceImpl::SurfaceImpl()
+{}
+
+SurfaceImpl::~SurfaceImpl()
+{
+  SDL_FreeSurface(sdl_surface);
+}
+
+SDL_Surface* SurfaceImpl::get_sdl_surface() const
+{
+  return sdl_surface;
+}
+
+int SurfaceImpl::resize(int w_, int h_)
+{
+  w = w_;
+  h = h_;
+  SDL_Rect dest;
+  dest.x = 0;
+  dest.y = 0;
+  dest.w = w;
+  dest.h = h;
+  int ret = SDL_SoftStretch(sdl_surface, NULL,
+                            sdl_surface, &dest);
+  return ret;
+}
+
+#ifndef NOOPENGL
+SurfaceOpenGL::SurfaceOpenGL(SDL_Surface* surf, int use_alpha)
+{
+  sdl_surface = sdl_surface_from_sdl_surface(surf, use_alpha);
+  create_gl(sdl_surface,&gl_texture);
+
+  w = sdl_surface->w;
+  h = sdl_surface->h;
+}
+
+SurfaceOpenGL::SurfaceOpenGL(const std::string& file, int use_alpha)
+{
+  sdl_surface = sdl_surface_from_file(file, use_alpha);
+  create_gl(sdl_surface,&gl_texture);
+
+  w = sdl_surface->w;
+  h = sdl_surface->h;
+}
+
+SurfaceOpenGL::SurfaceOpenGL(const std::string& file, int x, int y, int w, int h, int use_alpha)
+{
+  sdl_surface = sdl_surface_part_from_file(file,x,y,w,h,use_alpha);
+  create_gl(sdl_surface, &gl_texture);
+
+  w = sdl_surface->w;
+  h = sdl_surface->h;
+}
+
+SurfaceOpenGL::~SurfaceOpenGL()
+{
+  glDeleteTextures(1, &gl_texture);
+}
+
+void
+SurfaceOpenGL::create_gl(SDL_Surface * surf, GLuint * tex)
+{
+  Uint32 saved_flags;
+  Uint8  saved_alpha;
+  int w, h;
+  SDL_Surface *conv;
+
+  w = power_of_two(surf->w);
+  h = power_of_two(surf->h),
+
+#if SDL_BYTEORDER == SDL_BIG_ENDIAN
+      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,
+                                  0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000);
+#endif
+
+  /* Save the alpha blending attributes */
+  saved_flags = surf->flags&(SDL_SRCALPHA|SDL_RLEACCELOK);
+  saved_alpha = surf->format->alpha;
+  if ( (saved_flags & SDL_SRCALPHA)
+       == SDL_SRCALPHA )
+  {
+    SDL_SetAlpha(surf, 0, 0);
+  }
+
+  SDL_BlitSurface(surf, 0, conv, 0);
+
+  /* Restore the alpha blending attributes */
+  if ( (saved_flags & SDL_SRCALPHA)
+       == SDL_SRCALPHA )
+  {
+    SDL_SetAlpha(surf, saved_flags, saved_alpha);
+  }
+
+  glGenTextures(1, &*tex);
+  glBindTexture(GL_TEXTURE_2D , *tex);
+  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+  glPixelStorei(GL_UNPACK_ROW_LENGTH, conv->pitch / conv->format->BytesPerPixel);
+  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB10_A2, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, conv->pixels);
+  glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
+
+  SDL_FreeSurface(conv);
+}
+
+int
+SurfaceOpenGL::draw(float x, float y, Uint8 alpha)
+{
+  float pw = power_of_two(w);
+  float ph = power_of_two(h);
+
+  glEnable(GL_TEXTURE_2D);
+  glEnable(GL_BLEND);
+  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+  glColor4ub(alpha, alpha, alpha, alpha);
+
+  glBindTexture(GL_TEXTURE_2D, gl_texture);
+
+  glBegin(GL_QUADS);
+  glTexCoord2f(0, 0);
+  glVertex2f(x, y);
+  glTexCoord2f((float)w / pw, 0);
+  glVertex2f((float)w+x, y);
+  glTexCoord2f((float)w / pw, (float)h / ph);  glVertex2f((float)w+x, (float)h+y);
+  glTexCoord2f(0, (float)h / ph);
+  glVertex2f(x, (float)h+y);
+  glEnd();
+
+  glDisable(GL_TEXTURE_2D);
+  glDisable(GL_BLEND);
+
+  return 0;
+}
+
+int
+SurfaceOpenGL::draw_part(float sx, float sy, float x, float y, float w, float h, Uint8 alpha)
+{
+  float pw = power_of_two(int(this->w));
+  float ph = power_of_two(int(this->h));
+
+  glBindTexture(GL_TEXTURE_2D, gl_texture);
+
+  glEnable(GL_BLEND);
+  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+  glColor4ub(alpha, alpha, alpha, alpha);
+
+  glEnable(GL_TEXTURE_2D);
+
+
+  glBegin(GL_QUADS);
+  glTexCoord2f(sx / pw, sy / ph);
+  glVertex2f(x, y);
+  glTexCoord2f((float)(sx + w) / pw, sy / ph);
+  glVertex2f(w+x, y);
+  glTexCoord2f((sx+w) / pw, (sy+h) / ph);
+  glVertex2f(w +x, h+y);
+  glTexCoord2f(sx / pw, (float)(sy+h) / ph);
+  glVertex2f(x, h+y);
+  glEnd();
+
+  glDisable(GL_TEXTURE_2D);
+  glDisable(GL_BLEND);
+
+  return 0;
+}
+
+#if 0
+int
+SurfaceOpenGL::draw_stretched(float x, float y, int sw, int sh, Uint8 alpha)
+{
+  float pw = power_of_two(int(this->w));
+  float ph = power_of_two(int(this->h));
+
+  glBindTexture(GL_TEXTURE_2D, gl_texture);
+
+  glEnable(GL_BLEND);
+  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+  glColor4ub(alpha, alpha, alpha, alpha);
+
+  glEnable(GL_TEXTURE_2D);
+
+
+  glBegin(GL_QUADS);
+  glTexCoord2f(0, 0);
+  glVertex2f(x, y);
+  glTexCoord2f((float)w / pw, 0);
+  glVertex2f(sw+x, y);
+  glTexCoord2f((float)w / pw, (float)h / ph);  glVertex2f((float)sw+x, (float)sh+y);
+  glVertex2f(sw +x, sh+y);
+  glTexCoord2f(0, (float)h / ph);
+  glVertex2f(x, sh+y);
+  glEnd();
+
+  glDisable(GL_TEXTURE_2D);
+  glDisable(GL_BLEND);
+
+  return 0;
+}
+#endif
+
+#endif
+
+SurfaceSDL::SurfaceSDL(SDL_Surface* surf, int use_alpha)
+{
+  sdl_surface = sdl_surface_from_sdl_surface(surf, use_alpha);
+  w = sdl_surface->w;
+  h = sdl_surface->h;
+}
+
+SurfaceSDL::SurfaceSDL(const std::string& file, int use_alpha)
+{
+  sdl_surface = sdl_surface_from_file(file, use_alpha);
+  w = sdl_surface->w;
+  h = sdl_surface->h;
+}
+
+SurfaceSDL::SurfaceSDL(const std::string& file, int x, int y, int w, int h,  int use_alpha)
+{
+  sdl_surface = sdl_surface_part_from_file(file, x, y, w, h, use_alpha);
+  w = sdl_surface->w;
+  h = sdl_surface->h;
+}
+
+int
+SurfaceSDL::draw(float x, float y, Uint8 alpha)
+{
+  SDL_Rect dest;
+
+  dest.x = (int)x;
+  dest.y = (int)y;
+  dest.w = w;
+  dest.h = h;
+
+  if(alpha != 255)
+    {
+    /* Create a Surface, make it using colorkey, blit surface into temp, apply alpha
+      to temp sur, blit the temp into the screen */
+    /* Note: this has to be done, since SDL doesn't allow to set alpha to surfaces that
+      already have an alpha mask yet... */
+
+    SDL_Surface* sdl_surface_copy = SDL_CreateRGBSurface (sdl_surface->flags,
+                                    sdl_surface->w, sdl_surface->h, sdl_surface->format->BitsPerPixel,
+                                    sdl_surface->format->Rmask, sdl_surface->format->Gmask,
+                                    sdl_surface->format->Bmask,
+                                    0);
+    int colorkey = SDL_MapRGB(sdl_surface_copy->format, 255, 0, 255);
+    SDL_FillRect(sdl_surface_copy, NULL, colorkey);
+    SDL_SetColorKey(sdl_surface_copy, SDL_SRCCOLORKEY, colorkey);
+
+
+    SDL_BlitSurface(sdl_surface, NULL, sdl_surface_copy, NULL);
+    SDL_SetAlpha(sdl_surface_copy ,SDL_SRCALPHA,alpha);
+
+    int ret = SDL_BlitSurface(sdl_surface_copy, NULL, screen, &dest);
+
+    SDL_FreeSurface (sdl_surface_copy);
+    return ret;
+    }
+
+  int ret = SDL_BlitSurface(sdl_surface, NULL, screen, &dest);
+
+  return ret;
+}
+
+int
+SurfaceSDL::draw_part(float sx, float sy, float x, float y, float w, float h, Uint8 alpha)
+{
+  SDL_Rect src, dest;
+
+  src.x = (int)sx;
+  src.y = (int)sy;
+  src.w = (int)w;
+  src.h = (int)h;
+
+  dest.x = (int)x;
+  dest.y = (int)y;
+  dest.w = (int)w;
+  dest.h = (int)h;
+
+  if(alpha != 255)
+    {
+    /* Create a Surface, make it using colorkey, blit surface into temp, apply alpha
+      to temp sur, blit the temp into the screen */
+    /* Note: this has to be done, since SDL doesn't allow to set alpha to surfaces that
+      already have an alpha mask yet... */
+
+    SDL_Surface* sdl_surface_copy = SDL_CreateRGBSurface (sdl_surface->flags,
+                                    sdl_surface->w, sdl_surface->h, sdl_surface->format->BitsPerPixel,
+                                    sdl_surface->format->Rmask, sdl_surface->format->Gmask,
+                                    sdl_surface->format->Bmask,
+                                    0);
+    int colorkey = SDL_MapRGB(sdl_surface_copy->format, 255, 0, 255);
+    SDL_FillRect(sdl_surface_copy, NULL, colorkey);
+    SDL_SetColorKey(sdl_surface_copy, SDL_SRCCOLORKEY, colorkey);
+
+
+    SDL_BlitSurface(sdl_surface, NULL, sdl_surface_copy, NULL);
+    SDL_SetAlpha(sdl_surface_copy ,SDL_SRCALPHA,alpha);
+
+    int ret = SDL_BlitSurface(sdl_surface_copy, NULL, screen, &dest);
+
+    SDL_FreeSurface (sdl_surface_copy);
+    return ret;
+    }
+
+  int ret = SDL_BlitSurface(sdl_surface, &src, screen, &dest);
+
+  return ret;
+}
+
+#if 0
+int
+SurfaceSDL::draw_stretched(float x, float y, int sw, int sh, Uint8 alpha, bool update)
+{
+  SDL_Rect dest;
+
+  dest.x = (int)x;
+  dest.y = (int)y;
+  dest.w = (int)sw;
+  dest.h = (int)sh;
+
+  if(alpha != 255)
+    SDL_SetAlpha(sdl_surface ,SDL_SRCALPHA,alpha);
+
+
+  SDL_Surface* sdl_surface_copy = SDL_CreateRGBSurface (sdl_surface->flags,
+                                  sw, sh, sdl_surface->format->BitsPerPixel,
+                                  sdl_surface->format->Rmask, sdl_surface->format->Gmask,
+                                  sdl_surface->format->Bmask,
+                                  0);
+
+  SDL_BlitSurface(sdl_surface, NULL, sdl_surface_copy, NULL);
+  SDL_SoftStretch(sdl_surface_copy, NULL, sdl_surface_copy, &dest);
+
+  int ret = SDL_BlitSurface(sdl_surface_copy,NULL,screen,&dest);
+  SDL_FreeSurface(sdl_surface_copy);
+
+  if (update == UPDATE)
+    update_rect(screen, dest.x, dest.y, dest.w, dest.h);
+
+  return ret;
+}
+#endif
+
+SurfaceSDL::~SurfaceSDL()
+{}
+
+/* EOF */
diff --git a/src/screen/texture.h b/src/screen/texture.h
new file mode 100644 (file)
index 0000000..3f65a88
--- /dev/null
@@ -0,0 +1,160 @@
+//  $Id$
+// 
+//  SuperTux
+//  Copyright (C) 2004 Tobias Glaesser <tobi.web@gmx.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.
+
+#ifndef SUPERTUX_TEXTURE_H
+#define SUPERTUX_TEXTURE_H
+
+#include <SDL.h>
+#include <string>
+#ifndef NOOPENGL
+#include <SDL_opengl.h>
+#endif
+
+#include <list>
+#include "screen.h"
+#include "vector.h"
+
+SDL_Surface* sdl_surface_from_sdl_surface(SDL_Surface* sdl_surf, int use_alpha);
+
+class SurfaceImpl;
+class SurfaceSDL;
+class SurfaceOpenGL;
+class DrawingContext;
+
+/** This class holds all the data necessary to construct a surface */
+class SurfaceData 
+{
+public:
+  enum ConstructorType { LOAD, LOAD_PART, SURFACE };
+  ConstructorType type;
+  SDL_Surface* surface;
+  std::string file;
+  int use_alpha;
+  int x;
+  int y;
+  int w;
+  int h;
+
+  SurfaceData(SDL_Surface* surf, int use_alpha_);
+  SurfaceData(const std::string& file_, int use_alpha_);
+  SurfaceData(const std::string& file_, int x_, int y_, int w_, int h_, int use_alpha_);
+  ~SurfaceData();
+
+  SurfaceSDL* create_SurfaceSDL();
+  SurfaceOpenGL* create_SurfaceOpenGL();
+  SurfaceImpl* create();
+};
+
+/** Container class that holds a surface, necessary so that we can
+    switch Surface implementations (OpenGL, SDL) on the fly */
+class Surface
+{
+public:
+  SurfaceData data;
+  SurfaceImpl* impl;
+  int w; 
+  int h;
+  
+  typedef std::list<Surface*> Surfaces;
+  static Surfaces surfaces;
+public:
+  static void reload_all();
+  static void debug_check();
+
+  Surface(SDL_Surface* surf, int use_alpha);  
+  Surface(const std::string& file, int use_alpha);  
+  Surface(const std::string& file, int x, int y, int w, int h, int use_alpha);
+  ~Surface();
+  
+  /** Reload the surface, which is necesarry in case of a mode swich */
+  void reload();
+
+  void resize(int widht, int height);
+};
+
+/** Surface implementation, all implementation have to inherit from
+    this class */
+class SurfaceImpl
+{
+protected:
+  SDL_Surface* sdl_surface;
+
+public:
+  int w;
+  int h;
+
+public:
+  SurfaceImpl();
+  virtual ~SurfaceImpl();
+  
+  /** Return 0 on success, -2 if surface needs to be reloaded */
+  virtual int draw(float x, float y, Uint8 alpha) = 0;
+  virtual int draw_part(float sx, float sy, float x, float y, float w, float h,  Uint8 alpha) = 0;
+#if 0
+  virtual int draw_stretched(float x, float y, int w, int h, Uint8 alpha, bool update) = 0;
+#endif
+  int resize(int w_, int h_);
+
+  SDL_Surface* get_sdl_surface() const; // @evil@ try to avoid this function
+};
+
+class SurfaceSDL : public SurfaceImpl
+{
+public:
+  SurfaceSDL(SDL_Surface* surf, int use_alpha);
+  SurfaceSDL(const std::string& file, int use_alpha);  
+  SurfaceSDL(const std::string& file, int x, int y, int w, int h, int use_alpha);
+  virtual ~SurfaceSDL();
+
+  int draw(float x, float y, Uint8 alpha);
+  int draw_part(float sx, float sy, float x, float y, float w, float h,  Uint8 alpha);
+#if 0
+  int draw_stretched(float x, float y, int w, int h, Uint8 alpha);
+#endif
+};
+
+#ifndef NOOPENGL
+class SurfaceOpenGL : public SurfaceImpl
+{
+public:
+  unsigned gl_texture;
+
+public:
+  SurfaceOpenGL(SDL_Surface* surf, int use_alpha);
+  SurfaceOpenGL(const std::string& file, int use_alpha);  
+  SurfaceOpenGL(const std::string& file, int x, int y, int w, int h, int use_alpha);
+  virtual ~SurfaceOpenGL();
+
+  int draw(float x, float y, Uint8 alpha);
+  int draw_part(float sx, float sy, float x, float y, float w, float h,  Uint8 alpha);
+#if 0
+  int draw_stretched(float x, float y, int w, int h, Uint8 alpha);
+#endif
+
+private:
+  void create_gl(SDL_Surface * surf, GLuint * tex);
+};
+#endif 
+
+#endif /*SUPERTUX_TEXTURE_H*/
+
+/* Local Variables: */
+/* mode: c++ */
+/* End: */
index 4b9d283..98cc84c 100644 (file)
@@ -42,8 +42,8 @@
 #include "defines.h"
 #include "globals.h"
 #include "setup.h"
-#include "screen.h"
-#include "texture.h"
+#include "screen/screen.h"
+#include "screen/texture.h"
 #include "menu.h"
 #include "gameloop.h"
 #include "configfile.h"
@@ -505,7 +505,7 @@ bool process_load_game_menu()
           draw_intro();
         }
 
-      shrink_fade(Point((screen->w/2),(screen->h/2)), 1000);
+      // shrink_fade(Point((screen->w/2),(screen->h/2)), 1000);
       fadeout();
       WorldMapNS::WorldMap worldmap;
      
@@ -582,16 +582,19 @@ void st_general_setup(void)
 
   /* Load global images: */
 
-  black_text  = new Text(datadir + "/images/status/letters-black.png", TEXT_TEXT, 16,18);
-  gold_text   = new Text(datadir + "/images/status/letters-gold.png", TEXT_TEXT, 16,18);
-  silver_text = new Text(datadir + "/images/status/letters-silver.png", TEXT_TEXT, 16,18);
-  blue_text   = new Text(datadir + "/images/status/letters-blue.png", TEXT_TEXT, 16,18);
-  red_text    = new Text(datadir + "/images/status/letters-red.png", TEXT_TEXT, 16,18);
-  green_text  = new Text(datadir + "/images/status/letters-green.png", TEXT_TEXT, 16,18);
-  white_text  = new Text(datadir + "/images/status/letters-white.png", TEXT_TEXT, 16,18);
-  white_small_text = new Text(datadir + "/images/status/letters-white-small.png", TEXT_TEXT, 8,9);
-  white_big_text   = new Text(datadir + "/images/status/letters-white-big.png", TEXT_TEXT, 20,22);
-  yellow_nums = new Text(datadir + "/images/status/numbers.png", TEXT_NUM, 32,32);
+  black_text  = new Font(datadir + "/images/status/letters-black.png", TEXT_TEXT, 16,18);
+  gold_text   = new Font(datadir + "/images/status/letters-gold.png", TEXT_TEXT, 16,18);
+  silver_text = new Font(datadir + "/images/status/letters-silver.png", TEXT_TEXT, 16,18);
+  blue_text   = new Font(datadir + "/images/status/letters-blue.png", TEXT_TEXT,
+      16,18, 3);
+  red_text    = new Font(datadir + "/images/status/letters-red.png", TEXT_TEXT, 16,18);
+  green_text  = new Font(datadir + "/images/status/letters-green.png", TEXT_TEXT, 16,18);
+  white_text  = new Font(datadir + "/images/status/letters-white.png", TEXT_TEXT, 16,18);
+  white_small_text = new Font(datadir +
+      "/images/status/letters-white-small.png", TEXT_TEXT, 8,9, 1);
+  white_big_text   = new Font(datadir + "/images/status/letters-white-big.png",
+      TEXT_TEXT, 20,22, 3);
+  yellow_nums = new Font(datadir + "/images/status/numbers.png", TEXT_NUM, 32,32);
 
   /* Load GUI/menu images: */
   checkbox = new Surface(datadir + "/images/status/checkbox.png", USE_ALPHA);
index adfebe0..8dd89ae 100644 (file)
@@ -22,8 +22,9 @@
 #include "SDL.h"
 #include "defines.h"
 #include "special.h"
+#include "camera.h"
 #include "gameloop.h"
-#include "screen.h"
+#include "screen/screen.h"
 #include "sound.h"
 #include "scene.h"
 #include "globals.h"
@@ -44,11 +45,8 @@ Sprite* img_1up;
 #define BULLET_STARTING_YM 0
 #define BULLET_XM 6
 
-Bullet::Bullet(DisplayManager& display_manager, const Vector& pos, float xm,
-    int dir, int kind_)
+Bullet::Bullet(const Vector& pos, float xm, int dir, int kind_)
 {
-  display_manager.add_drawable(this, LAYER_OBJECTS);
-  
   life_count = 3;
   base.width = 4;
   base.height = 4;
@@ -112,12 +110,11 @@ Bullet::action(float elapsed_time)
 }
 
 void 
-Bullet::draw(Camera& viewport, int )
+Bullet::draw(DrawingContext& context)
 {
-  if(kind == FIRE_BULLET)
-    img_firebullet->draw(viewport.world2screen(Vector(base.x, base.y)));
-  else if(kind == ICE_BULLET)
-    img_icebullet->draw(viewport.world2screen(Vector(base.x, base.y)));
+  Sprite* sprite = kind == FIRE_BULLET ? img_firebullet : img_icebullet;
+  sprite->draw(context, Vector(base.x, base.y), LAYER_OBJECTS);
 }
 
 void
@@ -136,11 +133,8 @@ Bullet::collision(int c_object)
 
 //---------------------------------------------------------------------------
 
-Upgrade::Upgrade(DisplayManager& display_manager, const Vector& pos,
-    Direction dir_, UpgradeKind kind_)
+Upgrade::Upgrade(const Vector& pos, Direction dir_, UpgradeKind kind_)
 {
-  display_manager.add_drawable(this, LAYER_OBJECTS);
-  
   kind = kind_;
   dir = dir_;
 
@@ -243,53 +237,24 @@ Upgrade::action(float elapsed_time)
 }
 
 void
-Upgrade::draw(Camera& viewport, int)
+Upgrade::draw(DrawingContext& context)
 {
-  SDL_Rect dest;
-
-  if (base.height < 32)
-    {
-      /* Rising up... */
-
-      dest.x = (int)(base.x - viewport.get_translation().x);
-      dest.y = (int)(base.y + 32 - base.height - viewport.get_translation().y);
-      dest.w = 32;
-      dest.h = (int)base.height;
+  Sprite* sprite;
+  switch(kind) {
+    case UPGRADE_GROWUP: sprite = img_growup; break;
+    case UPGRADE_ICEFLOWER: sprite = img_iceflower; break;
+    case UPGRADE_FIREFLOWER: sprite = img_fireflower; break;
+    case UPGRADE_HERRING: sprite = img_star; break;
+    case UPGRADE_1UP: sprite = img_1up; break;
+    default:
+      assert(!"wrong type in Powerup::draw()");
+  }
 
-      if (kind == UPGRADE_GROWUP)
-        img_growup->draw_part(0,0,dest.x,dest.y,dest.w,dest.h);
-      else if (kind == UPGRADE_ICEFLOWER)
-        img_iceflower->draw_part(0,0,dest.x,dest.y,dest.w,dest.h);
-      else if (kind == UPGRADE_FIREFLOWER)
-        img_fireflower->draw_part(0,0,dest.x,dest.y,dest.w,dest.h);
-      else if (kind == UPGRADE_HERRING)
-        img_star->draw_part(0,0,dest.x,dest.y,dest.w,dest.h);
-      else if (kind == UPGRADE_1UP)
-        img_1up->draw_part( 0, 0, dest.x, dest.y, dest.w, dest.h);
-    }
+  if(base.height < 32) // still raising up?
+    sprite->draw(context, Vector(base.x, base.y + (32 - base.height)),
+        LAYER_TILES - 10);
   else
-    {
-      if (kind == UPGRADE_GROWUP)
-        {
-          img_growup->draw(viewport.world2screen(Vector(base.x, base.y)));
-        }
-      else if (kind == UPGRADE_ICEFLOWER)
-        {
-          img_iceflower->draw(viewport.world2screen(Vector(base.x, base.y)));
-        }
-      else if (kind == UPGRADE_FIREFLOWER)
-        {
-          img_fireflower->draw(viewport.world2screen(Vector(base.x, base.y)));
-        }
-      else if (kind == UPGRADE_HERRING)
-        {
-          img_star->draw(viewport.world2screen(Vector(base.x, base.y)));
-        }
-      else if (kind == UPGRADE_1UP)
-        {
-          img_1up->draw(viewport.world2screen(Vector(base.x, base.y)));
-        }
-    }
+    sprite->draw(context, Vector(base.x, base.y), LAYER_OBJECTS);
 }
 
 void
index 304d209..550e2a4 100644 (file)
@@ -23,7 +23,7 @@
 #include <SDL.h>
 #include "bitmask.h"
 #include "type.h"
-#include "texture.h"
+#include "screen/texture.h"
 #include "collision.h"
 #include "player.h"
 #include "physic.h"
@@ -41,19 +41,18 @@ enum UpgradeKind {
 void load_special_gfx();
 void free_special_gfx();
 
-class Upgrade : public MovingObject, public Drawable
+class Upgrade : public MovingObject
 {
 public:
   UpgradeKind kind;
   Direction  dir;
   Physic physic;
 
-  Upgrade(DisplayManager& display_manager, const Vector& pos, Direction dir,
-      UpgradeKind kind);
+  Upgrade(const Vector& pos, Direction dir, UpgradeKind kind);
   virtual ~Upgrade();
   
   virtual void action(float frame_ratio);
-  virtual void draw(Camera& viewport, int layer);
+  virtual void draw(DrawingContext& context);
 
   virtual void collision(const MovingObject& other, int);
   void collision(void* p_c_object, int c_object, CollisionType type);
@@ -67,14 +66,14 @@ enum BulletsKind {
   ICE_BULLET
 };
 
-class Bullet : public MovingObject, public Drawable
+class Bullet : public MovingObject
 {
 public:
-  Bullet(DisplayManager& manager, const Vector& pos, float xm, int dir,
+  Bullet(const Vector& pos, float xm, int dir,
       int kind);
   
   virtual void action(float frame_ratio);
-  virtual void draw(Camera& viewport, int layer);
+  virtual void draw(DrawingContext& context);
   void collision(int c_object);
 
   virtual void collision(const MovingObject& other_object, int type);
index f5f1f65..c4d552f 100644 (file)
@@ -22,6 +22,7 @@
 #include "globals.h"
 #include "sprite.h"
 #include "setup.h"
+#include "screen/drawing_context.h"
 
 Sprite::Sprite(lisp_object_t* cur)
 {
@@ -73,22 +74,29 @@ Sprite::update(float /*delta*/)
 }
 
 void
-Sprite::draw(float x, float y, int special_drawing)
+Sprite::draw(DrawingContext& context, const Vector& pos, int layer,
+    int special_drawing)
 {
   time = SDL_GetTicks();
   unsigned int frame = get_current_frame();
 
   if (frame < surfaces.size())
-    {
+  {
+    Surface* surface = surfaces[frame];
+    
+#if 0 // TODO
     if(special_drawing == SD_SEMI_TRANSPARENT)
       surfaces[frame]->draw(x - x_hotspot, y - y_hotspot, 128);
     if(special_drawing == SD_VERTICAL_FLIP)
       surfaces[frame]->draw(x - x_hotspot, y - y_hotspot, 255, true);
     else
       surfaces[frame]->draw(x - x_hotspot, y - y_hotspot);
-    }
+#endif
+    context.draw_surface(surface, pos - Vector(x_hotspot, y_hotspot), layer);
+  }
 }
 
+#if 0
 void
 Sprite::draw_part(float sx, float sy, float x, float y, float w, float h)
 {
@@ -98,6 +106,7 @@ Sprite::draw_part(float sx, float sy, float x, float y, float w, float h)
   if (frame < surfaces.size())
     surfaces[frame]->draw_part(sx, sy, x - x_hotspot, y - y_hotspot, w, h);
 }
+#endif
 
 void
 Sprite::reset()
index 2a4acf3..1c53618 100644 (file)
@@ -23,7 +23,7 @@
 #include <string>
 #include <vector>
 #include "lispreader.h"
-#include "texture.h"
+#include "screen/texture.h"
 #include "vector.h"
 
 enum SpecialDrawing { SD_NONE, SD_VERTICAL_FLIP, SD_SEMI_TRANSPARENT };
@@ -58,16 +58,13 @@ class Sprite
 
   /** Update the sprite and process to the next frame */
   void update(float delta);
-  void draw(float x, float y, int special_drawing = SD_NONE);
-  void draw_part(float sx, float sy, float x, float y, float w, float h);
+  void draw(DrawingContext& context, const Vector& pos, int layer,
+      int special_drawing = SD_NONE);
   int get_current_frame() const;
 
   float get_fps() { return fps; } ;
   int get_frames() { return surfaces.size(); } ;
 
-  void draw(const Vector& pos, int special_drawing = SD_NONE)
-  { draw(pos.x, pos.y, special_drawing); }
-
   std::string get_name() const { return name; } 
   int get_width() const;
   int get_height() const;
index 8cbc3be..6d17be6 100644 (file)
 #include "title.h"
 #include "gameloop.h"
 #include "leveleditor.h"
-#include "screen.h"
+#include "screen/screen.h"
 #include "worldmap.h"
 #include "resources.h"
-#include "texture.h"
+#include "screen/texture.h"
 #include "tile.h"
 
 int main(int argc, char * argv[])
@@ -53,7 +53,8 @@ int main(int argc, char * argv[])
 
     if (launch_leveleditor_mode && level_startup_file)
     {
-    leveleditor(level_startup_file);
+      // TODO
+      // leveleditor(level_startup_file);
     }
     else if (level_startup_file)
     {
@@ -65,8 +66,8 @@ int main(int argc, char * argv[])
       title();
     }
 
-    clearscreen(0, 0, 0);
-    updatescreen();
+    SDL_FillRect(screen, 0, 0);
+    SDL_Flip(screen);
 
     unloadshared();
     st_general_free();
diff --git a/src/text.cpp b/src/text.cpp
deleted file mode 100644 (file)
index 6e66f3d..0000000
+++ /dev/null
@@ -1,370 +0,0 @@
-//  $Id$
-// 
-//  SuperTux
-//  Copyright (C) 2004 Tobias Glaesser <tobi.web@gmx.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 <stdlib.h>
-#include <string.h>
-#include "globals.h"
-#include "defines.h"
-#include "screen.h"
-#include "text.h"
-
-Text::Text(const std::string& file, int kind_, int w_, int h_)
-{
-  kind = kind_;
-  w = w_;
-  h = h_;
-
-  int mx, my;
-  SDL_Surface *conv;
-  int pixels;
-  int i;
-  
-  if(kind == TEXT_TEXT)
-    {
-      mx = 26;
-      my = 3;
-    }
-  else if(kind == TEXT_NUM)
-    {
-      mx = 10;
-      my = 1;
-    }
-  else
-    {
-      mx = 0;
-      my = 0;
-    }
-
-  chars = new Surface(file, USE_ALPHA);
-
-  // Load shadow font.
-  conv = SDL_DisplayFormatAlpha(chars->impl->get_sdl_surface());
-  pixels = conv->w * conv->h;
-  SDL_LockSurface(conv);
-  for(i = 0; i < pixels; ++i)
-    {
-      Uint32 *p = (Uint32 *)conv->pixels + i;
-      *p = *p & conv->format->Amask;
-    }
-  SDL_UnlockSurface(conv);
-  SDL_SetAlpha(conv, SDL_SRCALPHA, 128);
-  shadow_chars = new Surface(conv, USE_ALPHA);
-
-  SDL_FreeSurface(conv);
-}
-
-Text::~Text()
-{
-  delete chars;
-  delete shadow_chars;
-}
-
-void
-Text::draw(const  char* text, int x, int y, int shadowsize, int update)
-{
-  if(text != NULL)
-    {
-      if(shadowsize != 0)
-        draw_chars(shadow_chars, text,x+shadowsize,y+shadowsize, update);
-
-      draw_chars(chars, text,x,y, update);
-    }
-}
-
-void
-Text::draw_chars(Surface* pchars,const  char* text, int x, int y, int update)
-{
-  int i,j,len;
-
-  len = strlen(text);
-  int w = this->w;
-  int h = this->h;
-
-  if(kind == TEXT_TEXT)
-    {
-      for( i = 0, j = 0; i < len; ++i,++j)
-        {
-          if( text[i] >= ' ' && text[i] <= '/')
-            pchars->draw_part((int)(text[i] - ' ')*w,  0 , x+(j*w), y, w, h, 255,  update);
-          else if( text[i] >= '0' && text[i] <= '?')
-            pchars->draw_part((int)(text[i] - '0')*w, h*1, x+(j*w), y, w, h, 255,  update);
-          else if ( text[i] >= '@' && text[i] <= 'O')
-            pchars->draw_part((int)(text[i] - '@')*w, h*2, x+(j*w), y, w, h, 255,  update);
-          else if ( text[i] >= 'P' && text[i] <= '_')
-            pchars->draw_part((int)(text[i] - 'P')*w, h*3, x+(j*w), y, w, h, 255,  update);
-          else if ( text[i] >= '`' && text[i] <= 'o')
-            pchars->draw_part((int)(text[i] - '`')*w, h*4, x+(j*w), y, w, h, 255,  update);
-          else if ( text[i] >= 'p' && text[i] <= '~')
-            pchars->draw_part((int)(text[i] - 'p')*w, h*5, x+(j*w), y, w, h, 255,  update);
-          else if ( text[i] == '\n')
-            {
-              y += h + 2;
-              j = 0;
-            }
-        }
-    }
-  else if(kind == TEXT_NUM)
-    {
-      for( i = 0, j = 0; i < len; ++i, ++j)
-        {
-          if ( text[i] >= '0' && text[i] <= '9')
-            pchars->draw_part((int)(text[i] - '0')*w, 0, x+(j*w), y, w, h, 255, update);
-          else if ( text[i] == '\n')
-            {
-              y += h + 2;
-              j = 0;
-            }
-        }
-    }
-}
-
-void
-Text::draw_align(const char* text, int x, int y,
-                      TextHAlign halign, TextVAlign valign, int shadowsize, int update)
-{
-  if(text != NULL)
-    {
-      switch (halign)
-        {
-        case A_RIGHT:
-          x += -(strlen(text)*w);
-          break;
-        case A_HMIDDLE:
-          x += -((strlen(text)*w)/2);
-          break;
-        case A_LEFT:
-          // default
-          break;
-        }
-
-      switch (valign)
-        {
-        case A_BOTTOM:
-          y -= h;
-          break;
-          
-        case A_VMIDDLE:
-          y -= h/2;
-
-        case A_TOP:
-          // default
-          break;
-        }
-
-      draw(text, x, y, shadowsize, update);
-    }
-}
-
-void
-Text::drawf(const  char* text, int x, int y,
-                 TextHAlign halign, TextVAlign valign, int shadowsize, int update)
-{
-  if(text != NULL)
-    {
-      if(halign == A_RIGHT)  /* FIXME: this doesn't work correctly for strings with newlines.*/
-        x += screen->w - (strlen(text)*w);
-      else if(halign == A_HMIDDLE)
-        x += screen->w/2 - ((strlen(text)*w)/2);
-
-      if(valign == A_BOTTOM)
-        y += screen->h - h;
-      else if(valign == A_VMIDDLE)
-        y += screen->h/2 - h/2;
-
-      draw(text,x,y,shadowsize, update);
-    }
-}
-
-/* --- ERASE TEXT: --- */
-
-void
-Text::erasetext(const  char * text, int x, int y, Surface * ptexture, int update, int shadowsize)
-{
-  SDL_Rect dest;
-
-  dest.x = x;
-  dest.y = y;
-  dest.w = strlen(text) * w + shadowsize;
-  dest.h = h;
-
-  if (dest.w > screen->w)
-    dest.w = screen->w;
-
-  ptexture->draw_part(dest.x,dest.y,dest.x,dest.y,dest.w,dest.h, 255, update);
-
-  if (update == UPDATE)
-    update_rect(screen, dest.x, dest.y, dest.w, dest.h);
-}
-
-
-/* --- ERASE CENTERED TEXT: --- */
-
-void
-Text::erasecenteredtext(const  char * text, int y, Surface * ptexture, int update, int shadowsize)
-{
-  erasetext(text, screen->w / 2 - (strlen(text) * 8), y, ptexture, update, shadowsize);
-}
-
-
-/* --- SCROLL TEXT FUNCTION --- */
-
-#define MAX_VEL     10
-#define SPEED_INC   0.01
-#define SCROLL      60
-#define ITEMS_SPACE 4
-
-void display_text_file(const std::string& file, const std::string& surface, float scroll_speed)
-{
-  Surface* sur = new Surface(datadir + surface, IGNORE_ALPHA);
-  display_text_file(file, sur, scroll_speed);
-  delete sur;
-}
-
-void display_text_file(const std::string& file, Surface* surface, float scroll_speed)
-{
-  int done;
-  float scroll;
-  float speed;
-  int y;
-  int length;
-  FILE* fi;
-  char temp[1024];
-  string_list_type names;
-  char filename[1024];
-  string_list_init(&names);
-  sprintf(filename,"%s/%s", datadir.c_str(), file.c_str());
-  if((fi = fopen(filename,"r")) != NULL)
-    {
-      while(fgets(temp, sizeof(temp), fi) != NULL)
-        {
-          temp[strlen(temp)-1]='\0';
-          string_list_add_item(&names,temp);
-        }
-      fclose(fi);
-    }
-  else
-    {
-      string_list_add_item(&names,"File was not found!");
-      string_list_add_item(&names,filename);
-      string_list_add_item(&names,"Shame on the guy, who");
-      string_list_add_item(&names,"forgot to include it");
-      string_list_add_item(&names,"in your SuperTux distribution.");
-    }
-
-
-  scroll = 0;
-  speed = scroll_speed / 50;
-  done = 0;
-
-  length = names.num_items;
-
-  SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
-
-  Uint32 lastticks = SDL_GetTicks();
-  while(done == 0)
-    {
-      /* in case of input, exit */
-      SDL_Event event;
-      while(SDL_PollEvent(&event))
-        switch(event.type)
-          {
-          case SDL_KEYDOWN:
-            switch(event.key.keysym.sym)
-              {
-              case SDLK_UP:
-                speed -= SPEED_INC;
-                break;
-              case SDLK_DOWN:
-                speed += SPEED_INC;
-                break;
-              case SDLK_SPACE:
-              case SDLK_RETURN:
-                if(speed >= 0)
-                  scroll += SCROLL;
-                break;
-              case SDLK_ESCAPE:
-                done = 1;
-                break;
-              default:
-                break;
-              }
-            break;
-          case SDL_QUIT:
-            done = 1;
-            break;
-          default:
-            break;
-          }
-
-      if(speed > MAX_VEL)
-        speed = MAX_VEL;
-      else if(speed < -MAX_VEL)
-        speed = -MAX_VEL;
-
-      /* draw the credits */
-      surface->draw_bg();
-
-      y = 0;
-      for(int i = 0; i < length; i++)
-        {
-        switch(names.item[i][0])
-          {
-          case ' ':
-            white_small_text->drawf(names.item[i]+1, 0, screen->h+y-int(scroll),
-                A_HMIDDLE, A_TOP, 1);
-            y += white_small_text->h+ITEMS_SPACE;
-            break;
-          case '       ':
-            white_text->drawf(names.item[i]+1, 0, screen->h+y-int(scroll),
-                A_HMIDDLE, A_TOP, 1);
-            y += white_text->h+ITEMS_SPACE;
-            break;
-          case '-':
-            white_big_text->drawf(names.item[i]+1, 0, screen->h+y-int(scroll),
-                A_HMIDDLE, A_TOP, 3);
-            y += white_big_text->h+ITEMS_SPACE;
-            break;
-          default:
-            blue_text->drawf(names.item[i], 0, screen->h+y-int(scroll),
-                A_HMIDDLE, A_TOP, 1);
-            y += blue_text->h+ITEMS_SPACE;
-            break;
-          }
-        }
-
-      flipscreen();
-
-      if(screen->h+y-scroll < 0 && 20+screen->h+y-scroll < 0)
-        done = 1;
-
-      Uint32 ticks = SDL_GetTicks();
-      scroll += speed * (ticks - lastticks);
-      lastticks = ticks;
-      if(scroll < 0)
-        scroll = 0;
-
-      SDL_Delay(10);
-    }
-  string_list_free(&names);
-
-  SDL_EnableKeyRepeat(0, 0);    // disables key repeating
-  Menu::set_current(main_menu);
-}
-
diff --git a/src/text.h b/src/text.h
deleted file mode 100644 (file)
index 0e6d7ce..0000000
+++ /dev/null
@@ -1,78 +0,0 @@
-//  $Id$
-// 
-//  SuperTux
-//  Copyright (C) 2004 Tobias Glaesser <tobi.web@gmx.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.
-
-#ifndef SUPERTUX_TEXT_H
-#define SUPERTUX_TEXT_H
-
-#include <string>
-#include "texture.h"
-#include "vector.h"
-
-void display_text_file(const std::string& file, const std::string& surface, float scroll_speed);
-void display_text_file(const std::string& file, Surface* surface, float scroll_speed);
-
-/* Kinds of texts. */
-enum {
-   TEXT_TEXT,
-   TEXT_NUM
-};
-
-enum TextHAlign {
-   A_LEFT,
-   A_HMIDDLE,
-   A_RIGHT,
-};
-
-enum TextVAlign {
-   A_TOP,
-   A_VMIDDLE,
-   A_BOTTOM,
-};
-
-/* Text type */
-class Text
-{
- public:
-  Surface* chars;
-  Surface* shadow_chars;
-  int kind;
-  int w;
-  int h;
- public:
-  Text(const std::string& file, int kind, int w, int h);
-  ~Text();
-
-  void draw(const char* text, int x, int y, int shadowsize = 1, int update = NO_UPDATE);
-  void draw_chars(Surface* pchars, const char* text, int x, int y, int update = NO_UPDATE);
-  void drawf(const char* text, int x, int y, TextHAlign halign, TextVAlign valign, int shadowsize, int update = NO_UPDATE);
-  void draw_align(const char* text, int x, int y, TextHAlign halign, TextVAlign valign, int shadowsize = 1, int update = NO_UPDATE);
-  void erasetext(const char * text, int x, int y, Surface* surf, int update, int shadowsize);
-  void erasecenteredtext(const char * text, int y, Surface* surf, int update, int shadowsize);
-
-  /// conveniance function
-  void draw(const char* text, const Vector& pos, int shadowsize = 1, int update
-      = NO_UPDATE)
-  {
-    draw(text, int(pos.x), int(pos.y), shadowsize, update);
-  }
-};
-
-#endif /*SUPERTUX_TEXT_H*/
-
diff --git a/src/texture.cpp b/src/texture.cpp
deleted file mode 100644 (file)
index ae09bb3..0000000
+++ /dev/null
@@ -1,899 +0,0 @@
-//  $Id$
-//
-//  SuperTux
-//  Copyright (C) 2004 Tobias Glaesser <tobi.web@gmx.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 <assert.h>
-#include <iostream>
-#include <algorithm>
-#include "SDL.h"
-#include "SDL_image.h"
-#include "texture.h"
-#include "globals.h"
-#include "setup.h"
-
-Surface::Surfaces Surface::surfaces;
-
-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), 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), surface(0), file(file_), use_alpha(use_alpha_),
-    x(x_), y(y_), w(w_), h(h_)
-{}
-
-SurfaceData::~SurfaceData()
-{
-  SDL_FreeSurface(surface);
-}
-
-SurfaceImpl*
-SurfaceData::create()
-{
-#ifndef NOOPENGL
-  if (use_gl)
-    return create_SurfaceOpenGL();
-  else
-    return create_SurfaceSDL();
-#else
-  return create_SurfaceSDL();
-#endif
-}
-
-SurfaceSDL*
-SurfaceData::create_SurfaceSDL()
-{
-  switch(type)
-  {
-  case LOAD:
-    return new SurfaceSDL(file, use_alpha);
-  case LOAD_PART:
-    return new SurfaceSDL(file, x, y, w, h, use_alpha);
-  case SURFACE:
-    return new SurfaceSDL(surface, use_alpha);
-  }
-  assert(0);
-}
-
-SurfaceOpenGL*
-SurfaceData::create_SurfaceOpenGL()
-{
-#ifndef NOOPENGL
-  switch(type)
-  {
-  case LOAD:
-    return new SurfaceOpenGL(file, use_alpha);
-  case LOAD_PART:
-    return new SurfaceOpenGL(file, x, y, w, h, use_alpha);
-  case SURFACE:
-    return new SurfaceOpenGL(surface, use_alpha);
-  }
-#endif
-  assert(0);
-}
-
-#ifndef NOOPENGL
-/* Quick utility function for texture creation */
-static int power_of_two(int input)
-{
-  int value = 1;
-
-  while ( value < input )
-  {
-    value <<= 1;
-  }
-  return value;
-}
-#endif
-
-Surface::Surface(SDL_Surface* surf, int use_alpha)
-    : data(surf, use_alpha), w(0), h(0)
-{
-  impl = data.create();
-  if (impl)
-  {
-    w = impl->w;
-    h = impl->h;
-  }
-  surfaces.push_back(this);
-}
-
-Surface::Surface(const std::string& file, int use_alpha)
-    : data(file, use_alpha), w(0), h(0)
-{
-  impl = data.create();
-  if (impl)
-  {
-    w = impl->w;
-    h = impl->h;
-  }
-  surfaces.push_back(this);
-}
-
-Surface::Surface(const std::string& file, int x, int y, int w, int h, int use_alpha)
-    : data(file, x, y, w, h, use_alpha), w(0), h(0)
-{
-  impl = data.create();
-  if (impl)
-  {
-    w = impl->w;
-    h = impl->h;
-  }
-  surfaces.push_back(this);
-}
-
-void
-Surface::reload()
-{
-  delete impl;
-  impl = data.create();
-  if (impl)
-  {
-    w = impl->w;
-    h = impl->h;
-  }
-}
-
-Surface::~Surface()
-{
-#ifdef DEBUG
-  bool found = false;
-  for(std::list<Surface*>::iterator i = surfaces.begin(); i != surfaces.end();
-      ++i)
-  {
-    if(*i == this)
-    {
-      found = true; break;
-    }
-  }
-  if(!found)
-    printf("Error: Surface freed twice!!!\n");
-#endif
-  surfaces.remove(this);
-  delete impl;
-}
-
-void
-Surface::reload_all()
-{
-  for(Surfaces::iterator i = surfaces.begin(); i != surfaces.end(); ++i)
-  {
-    (*i)->reload();
-  }
-}
-
-void
-Surface::debug_check()
-{
-  for(Surfaces::iterator i = surfaces.begin(); i != surfaces.end(); ++i)
-  {
-    printf("Surface not freed: T:%d F:%s.\n", (*i)->data.type,
-           (*i)->data.file.c_str());
-  }
-}
-
-void
-Surface::draw(float x, float y, Uint8 alpha, bool upside_down, bool update)
-{
-  if (impl)
-  {
-    if (impl->draw(x, y, alpha, upside_down, update) == -2)
-      reload();
-  }
-}
-
-void
-Surface::draw_bg(Uint8 alpha, bool 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)
-  {
-    if (impl->draw_part(sx, sy, x, y, w, h, alpha, update) == -2)
-      reload();
-  }
-}
-
-void
-Surface::draw_stretched(float x, float y, int w, int h, Uint8 alpha, bool update)
-{
-  if (impl)
-  {
-    if (impl->draw_stretched(x, y, w, h, alpha, update) == -2)
-      reload();
-  }
-}
-
-void
-Surface::resize(int w_, int h_)
-{
-  if (impl)
-  {
-    w = w_;
-    h = h_;
-    if (impl->resize(w_,h_) == -2)
-      reload();
-  }
-}
-
-Surface* Surface::CaptureScreen()
-{
-  Surface *cap_screen;
-
-  if (!(screen->flags & SDL_OPENGL))
-  {
-    cap_screen = new Surface(SDL_GetVideoSurface(),false);
-  }
-
-#ifndef NOOPENGL
-  if (use_gl)
-  {
-    SDL_Surface *temp;
-    unsigned char *pixels;
-    int i;
-    temp = SDL_CreateRGBSurface(SDL_SWSURFACE, screen->w, screen->h, 24,
-#if SDL_BYTEORDER == SDL_LIL_ENDIAN
-                                0x000000FF, 0x0000FF00, 0x00FF0000, 0
-#else
-                                0x00FF0000, 0x0000FF00, 0x000000FF, 0
-#endif
-                               );
-    if (temp == NULL)
-      st_abort("Error while trying to capture the screen in OpenGL mode","");
-
-    pixels = (unsigned char*) malloc(3 * screen->w * screen->h);
-    if (pixels == NULL)
-    {
-      SDL_FreeSurface(temp);
-      st_abort("Error while trying to capture the screen in OpenGL mode","");
-    }
-
-    glReadPixels(0, 0, screen->w, screen->h, GL_RGB, GL_UNSIGNED_BYTE, pixels);
-
-    for (i=0; i<screen->h; i++)
-      memcpy(((char *) temp->pixels) + temp->pitch * i, pixels + 3*screen->w * (screen->h-i-1), screen->w*3);
-    free(pixels);
-
-    cap_screen = new Surface(temp,false);
-    SDL_FreeSurface(temp);
-
-  }
-#endif
-  
-return cap_screen;
-}
-
-SDL_Surface*
-sdl_surface_part_from_file(const std::string& file, int x, int y, int w, int h,  int use_alpha)
-{
-  SDL_Rect src;
-  SDL_Surface * sdl_surface;
-  SDL_Surface * temp;
-  SDL_Surface * conv;
-
-  temp = IMG_Load(file.c_str());
-
-  if (temp == NULL)
-    st_abort("Can't load", file);
-
-  /* Set source rectangle for conv: */
-
-  src.x = x;
-  src.y = y;
-  src.w = w;
-  src.h = h;
-
-  conv = SDL_CreateRGBSurface(temp->flags, w, h, temp->format->BitsPerPixel,
-                              temp->format->Rmask,
-                              temp->format->Gmask,
-                              temp->format->Bmask,
-                              temp->format->Amask);
-
-  /* #if SDL_BYTEORDER == SDL_BIG_ENDIAN
-     0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff);
-     #else
-
-     0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000);
-     #endif*/
-
-  SDL_SetAlpha(temp,0,0);
-
-  SDL_BlitSurface(temp, &src, conv, NULL);
-  if(use_alpha == IGNORE_ALPHA && !use_gl)
-    sdl_surface = SDL_DisplayFormat(conv);
-  else
-    sdl_surface = SDL_DisplayFormatAlpha(conv);
-
-  if (sdl_surface == NULL)
-    st_abort("Can't covert to display format", file);
-
-  if (use_alpha == IGNORE_ALPHA && !use_gl)
-    SDL_SetAlpha(sdl_surface, 0, 0);
-
-  SDL_FreeSurface(temp);
-  SDL_FreeSurface(conv);
-
-  return sdl_surface;
-}
-
-SDL_Surface*
-sdl_surface_from_file(const std::string& file, int use_alpha)
-{
-  SDL_Surface* sdl_surface;
-  SDL_Surface* temp;
-
-  temp = IMG_Load(file.c_str());
-
-  if (temp == NULL)
-    st_abort("Can't load", file);
-
-  if(use_alpha == IGNORE_ALPHA && !use_gl)
-    sdl_surface = SDL_DisplayFormat(temp);
-  else
-    sdl_surface = SDL_DisplayFormatAlpha(temp);
-
-  if (sdl_surface == NULL)
-    st_abort("Can't covert to display format", file);
-
-  if (use_alpha == IGNORE_ALPHA && !use_gl)
-    SDL_SetAlpha(sdl_surface, 0, 0);
-
-  SDL_FreeSurface(temp);
-
-  return sdl_surface;
-}
-
-SDL_Surface*
-sdl_surface_from_sdl_surface(SDL_Surface* sdl_surf, int use_alpha)
-{
-  SDL_Surface* sdl_surface;
-  Uint32 saved_flags;
-  Uint8  saved_alpha;
-
-  /* Save the alpha blending attributes */
-  saved_flags = sdl_surf->flags&(SDL_SRCALPHA|SDL_RLEACCELOK);
-  saved_alpha = sdl_surf->format->alpha;
-  if ( (saved_flags & SDL_SRCALPHA)
-       == SDL_SRCALPHA )
-  {
-    SDL_SetAlpha(sdl_surf, 0, 0);
-  }
-
-  if(use_alpha == IGNORE_ALPHA && !use_gl)
-    sdl_surface = SDL_DisplayFormat(sdl_surf);
-  else
-    sdl_surface = SDL_DisplayFormatAlpha(sdl_surf);
-
-  /* Restore the alpha blending attributes */
-  if ( (saved_flags & SDL_SRCALPHA)
-       == SDL_SRCALPHA )
-  {
-    SDL_SetAlpha(sdl_surface, saved_flags, saved_alpha);
-  }
-
-  if (sdl_surface == NULL)
-    st_abort("Can't covert to display format", "SURFACE");
-
-  if (use_alpha == IGNORE_ALPHA && !use_gl)
-    SDL_SetAlpha(sdl_surface, 0, 0);
-
-  return sdl_surface;
-}
-
-//---------------------------------------------------------------------------
-
-SurfaceImpl::SurfaceImpl()
-{}
-
-SurfaceImpl::~SurfaceImpl()
-{
-  SDL_FreeSurface(sdl_surface);
-}
-
-SDL_Surface* SurfaceImpl::get_sdl_surface() const
-{
-  return sdl_surface;
-}
-
-int SurfaceImpl::resize(int w_, int h_)
-{
-  w = w_;
-  h = h_;
-  SDL_Rect dest;
-  dest.x = 0;
-  dest.y = 0;
-  dest.w = w;
-  dest.h = h;
-  int ret = SDL_SoftStretch(sdl_surface, NULL,
-                            sdl_surface, &dest);
-  return ret;
-}
-
-#ifndef NOOPENGL
-SurfaceOpenGL::SurfaceOpenGL(SDL_Surface* surf, int use_alpha)
-{
-  sdl_surface = sdl_surface_from_sdl_surface(surf, use_alpha);
-  create_gl(sdl_surface,&gl_texture);
-
-  w = sdl_surface->w;
-  h = sdl_surface->h;
-}
-
-SurfaceOpenGL::SurfaceOpenGL(const std::string& file, int use_alpha)
-{
-  sdl_surface = sdl_surface_from_file(file, use_alpha);
-  create_gl(sdl_surface,&gl_texture);
-
-  w = sdl_surface->w;
-  h = sdl_surface->h;
-}
-
-SurfaceOpenGL::SurfaceOpenGL(const std::string& file, int x, int y, int w, int h, int use_alpha)
-{
-  sdl_surface = sdl_surface_part_from_file(file,x,y,w,h,use_alpha);
-  create_gl(sdl_surface, &gl_texture);
-
-  w = sdl_surface->w;
-  h = sdl_surface->h;
-}
-
-SurfaceOpenGL::~SurfaceOpenGL()
-{
-  glDeleteTextures(1, &gl_texture);
-}
-
-void
-SurfaceOpenGL::create_gl(SDL_Surface * surf, GLuint * tex)
-{
-  Uint32 saved_flags;
-  Uint8  saved_alpha;
-  int w, h;
-  SDL_Surface *conv;
-
-  w = power_of_two(surf->w);
-  h = power_of_two(surf->h),
-
-#if SDL_BYTEORDER == SDL_BIG_ENDIAN
-      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,
-                                  0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000);
-#endif
-
-  /* Save the alpha blending attributes */
-  saved_flags = surf->flags&(SDL_SRCALPHA|SDL_RLEACCELOK);
-  saved_alpha = surf->format->alpha;
-  if ( (saved_flags & SDL_SRCALPHA)
-       == SDL_SRCALPHA )
-  {
-    SDL_SetAlpha(surf, 0, 0);
-  }
-
-  SDL_BlitSurface(surf, 0, conv, 0);
-
-  /* Restore the alpha blending attributes */
-  if ( (saved_flags & SDL_SRCALPHA)
-       == SDL_SRCALPHA )
-  {
-    SDL_SetAlpha(surf, saved_flags, saved_alpha);
-  }
-
-  glGenTextures(1, &*tex);
-  glBindTexture(GL_TEXTURE_2D , *tex);
-  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
-  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
-  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-  glPixelStorei(GL_UNPACK_ROW_LENGTH, conv->pitch / conv->format->BytesPerPixel);
-  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB10_A2, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, conv->pixels);
-  glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
-
-  SDL_FreeSurface(conv);
-}
-
-int
-SurfaceOpenGL::draw(float x, float y, Uint8 alpha, bool upside_down, bool update)
-{
-  float pw = power_of_two(w);
-  float ph = power_of_two(h);
-
-  glEnable(GL_TEXTURE_2D);
-  glEnable(GL_BLEND);
-  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-
-  glColor4ub(alpha, alpha, alpha, alpha);
-
-  glBindTexture(GL_TEXTURE_2D, gl_texture);
-
-  glBegin(GL_QUADS);
-  if(upside_down)
-    {
-    glTexCoord2f(0, 0);
-    glVertex2f(x, (float)h+y);
-
-    glTexCoord2f((float)w / pw, 0);
-    glVertex2f((float)w+x, (float)h+y);
-
-    glTexCoord2f((float)w / pw, (float)h / ph);
-    glVertex2f((float)w+x, y);
-    
-    glTexCoord2f(0, (float)h / ph);
-    glVertex2f(x, y);
-    }
-  else
-    {
-    glTexCoord2f(0, 0);
-    glVertex2f(x, y);
-
-    glTexCoord2f((float)w / pw, 0);
-    glVertex2f((float)w+x, y);
-
-    glTexCoord2f((float)w / pw, (float)h / ph);
-    glVertex2f((float)w+x, (float)h+y);
-
-    glTexCoord2f(0, (float)h / ph);
-    glVertex2f(x, (float)h+y);
-    }
-  glEnd();
-
-  glDisable(GL_TEXTURE_2D);
-  glDisable(GL_BLEND);
-
-  (void) update; // avoid compiler warning
-
-  return 0;
-}
-
-int
-SurfaceOpenGL::draw_bg(Uint8 alpha, bool update)
-{
-  float pw = power_of_two(w);
-  float ph = power_of_two(h);
-
-  glColor3ub(alpha, alpha, alpha);
-
-  glEnable(GL_TEXTURE_2D);
-  glBindTexture(GL_TEXTURE_2D, gl_texture);
-
-  glBegin(GL_QUADS);
-  glTexCoord2f(0, 0);
-  glVertex2f(0, 0);
-  glTexCoord2f((float)w / pw, 0);
-  glVertex2f(screen->w, 0);
-  glTexCoord2f((float)w / pw, (float)h / ph);
-  glVertex2f(screen->w, screen->h);
-  glTexCoord2f(0, (float)h / ph);
-  glVertex2f(0, screen->h);
-  glEnd();
-
-  glDisable(GL_TEXTURE_2D);
-
-  (void) update; // avoid compiler warning
-
-  return 0;
-}
-
-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));
-  float ph = power_of_two(int(this->h));
-
-  glBindTexture(GL_TEXTURE_2D, gl_texture);
-
-  glEnable(GL_BLEND);
-  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-
-  glColor4ub(alpha, alpha, alpha, alpha);
-
-  glEnable(GL_TEXTURE_2D);
-
-
-  glBegin(GL_QUADS);
-  glTexCoord2f(sx / pw, sy / ph);
-  glVertex2f(x, y);
-  glTexCoord2f((float)(sx + w) / pw, sy / ph);
-  glVertex2f(w+x, y);
-  glTexCoord2f((sx+w) / pw, (sy+h) / ph);
-  glVertex2f(w +x, h+y);
-  glTexCoord2f(sx / pw, (float)(sy+h) / ph);
-  glVertex2f(x, h+y);
-  glEnd();
-
-  glDisable(GL_TEXTURE_2D);
-  glDisable(GL_BLEND);
-
-  (void) update; // avoid warnings
-  return 0;
-}
-
-int
-SurfaceOpenGL::draw_stretched(float x, float y, int sw, int sh, Uint8 alpha, bool update)
-{
-  float pw = power_of_two(int(this->w));
-  float ph = power_of_two(int(this->h));
-
-  glBindTexture(GL_TEXTURE_2D, gl_texture);
-
-  glEnable(GL_BLEND);
-  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-
-  glColor4ub(alpha, alpha, alpha, alpha);
-
-  glEnable(GL_TEXTURE_2D);
-
-
-  glBegin(GL_QUADS);
-  glTexCoord2f(0, 0);
-  glVertex2f(x, y);
-  glTexCoord2f((float)w / pw, 0);
-  glVertex2f(sw+x, y);
-  glTexCoord2f((float)w / pw, (float)h / ph);  glVertex2f((float)sw+x, (float)sh+y);
-  glVertex2f(sw +x, sh+y);
-  glTexCoord2f(0, (float)h / ph);
-  glVertex2f(x, sh+y);
-  glEnd();
-
-  glDisable(GL_TEXTURE_2D);
-  glDisable(GL_BLEND);
-
-  (void) update; // avoid warnings
-  return 0;
-}
-
-#endif
-
-SurfaceSDL::SurfaceSDL(SDL_Surface* surf, int use_alpha)
-{
-  sdl_surface = sdl_surface_from_sdl_surface(surf, use_alpha);
-  w = sdl_surface->w;
-  h = sdl_surface->h;
-}
-
-SurfaceSDL::SurfaceSDL(const std::string& file, int use_alpha)
-{
-  sdl_surface = sdl_surface_from_file(file, use_alpha);
-  w = sdl_surface->w;
-  h = sdl_surface->h;
-}
-
-SurfaceSDL::SurfaceSDL(const std::string& file, int x, int y, int w, int h,  int use_alpha)
-{
-  sdl_surface = sdl_surface_part_from_file(file, x, y, w, h, use_alpha);
-  w = sdl_surface->w;
-  h = sdl_surface->h;
-}
-
-int
-SurfaceSDL::draw(float x, float y, Uint8 alpha, bool upside_down, bool update)
-{
-  SDL_Rect dest;
-
-  dest.x = (int)x;
-  dest.y = (int)y;
-  dest.w = w;
-  dest.h = h;
-
-  if(upside_down)   // 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, update) == -2)
-        return -2;
-    return 0;
-    }
-
-  if(alpha != 255)
-    {
-    /* Create a Surface, make it using colorkey, blit surface into temp, apply alpha
-      to temp sur, blit the temp into the screen */
-    /* Note: this has to be done, since SDL doesn't allow to set alpha to surfaces that
-      already have an alpha mask yet... */
-
-    SDL_Surface* sdl_surface_copy = SDL_CreateRGBSurface (sdl_surface->flags,
-                                    sdl_surface->w, sdl_surface->h, sdl_surface->format->BitsPerPixel,
-                                    sdl_surface->format->Rmask, sdl_surface->format->Gmask,
-                                    sdl_surface->format->Bmask,
-                                    0);
-    int colorkey = SDL_MapRGB(sdl_surface_copy->format, 255, 0, 255);
-    SDL_FillRect(sdl_surface_copy, NULL, colorkey);
-    SDL_SetColorKey(sdl_surface_copy, SDL_SRCCOLORKEY, colorkey);
-
-
-    SDL_BlitSurface(sdl_surface, NULL, sdl_surface_copy, NULL);
-    SDL_SetAlpha(sdl_surface_copy ,SDL_SRCALPHA,alpha);
-
-    int ret = SDL_BlitSurface(sdl_surface_copy, NULL, screen, &dest);
-
-    if (update == UPDATE)
-      SDL_UpdateRect(screen, dest.x, dest.y, dest.w, dest.h);
-
-    SDL_FreeSurface (sdl_surface_copy);
-    return ret;
-    }
-
-  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;
-}
-
-int
-SurfaceSDL::draw_bg(Uint8 alpha, bool update)
-{
-  SDL_Rect dest;
-
-  dest.x = 0;
-  dest.y = 0;
-  dest.w = screen->w;
-  dest.h = screen->h;
-
-  if(alpha != 255)
-    {
-    /* Create a Surface, make it using colorkey, blit surface into temp, apply alpha
-      to temp sur, blit the temp into the screen */
-    /* Note: this has to be done, since SDL doesn't allow to set alpha to surfaces that
-      already have an alpha mask yet... */
-
-    SDL_Surface* sdl_surface_copy = SDL_CreateRGBSurface (sdl_surface->flags,
-                                    sdl_surface->w, sdl_surface->h, sdl_surface->format->BitsPerPixel,
-                                    sdl_surface->format->Rmask, sdl_surface->format->Gmask,
-                                    sdl_surface->format->Bmask,
-                                    0);
-    int colorkey = SDL_MapRGB(sdl_surface_copy->format, 255, 0, 255);
-    SDL_FillRect(sdl_surface_copy, NULL, colorkey);
-    SDL_SetColorKey(sdl_surface_copy, SDL_SRCCOLORKEY, colorkey);
-
-
-    SDL_BlitSurface(sdl_surface, NULL, sdl_surface_copy, NULL);
-    SDL_SetAlpha(sdl_surface_copy ,SDL_SRCALPHA,alpha);
-
-    int ret = SDL_BlitSurface(sdl_surface_copy, NULL, screen, &dest);
-
-    if (update == UPDATE)
-      SDL_UpdateRect(screen, dest.x, dest.y, dest.w, dest.h);
-
-    SDL_FreeSurface (sdl_surface_copy);
-    return ret;
-    }
-
-  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;
-}
-
-int
-SurfaceSDL::draw_part(float sx, float sy, float x, float y, float w, float h, Uint8 alpha, bool update)
-{
-  SDL_Rect src, dest;
-
-  src.x = (int)sx;
-  src.y = (int)sy;
-  src.w = (int)w;
-  src.h = (int)h;
-
-  dest.x = (int)x;
-  dest.y = (int)y;
-  dest.w = (int)w;
-  dest.h = (int)h;
-
-  if(alpha != 255)
-    {
-    /* Create a Surface, make it using colorkey, blit surface into temp, apply alpha
-      to temp sur, blit the temp into the screen */
-    /* Note: this has to be done, since SDL doesn't allow to set alpha to surfaces that
-      already have an alpha mask yet... */
-
-    SDL_Surface* sdl_surface_copy = SDL_CreateRGBSurface (sdl_surface->flags,
-                                    sdl_surface->w, sdl_surface->h, sdl_surface->format->BitsPerPixel,
-                                    sdl_surface->format->Rmask, sdl_surface->format->Gmask,
-                                    sdl_surface->format->Bmask,
-                                    0);
-    int colorkey = SDL_MapRGB(sdl_surface_copy->format, 255, 0, 255);
-    SDL_FillRect(sdl_surface_copy, NULL, colorkey);
-    SDL_SetColorKey(sdl_surface_copy, SDL_SRCCOLORKEY, colorkey);
-
-
-    SDL_BlitSurface(sdl_surface, NULL, sdl_surface_copy, NULL);
-    SDL_SetAlpha(sdl_surface_copy ,SDL_SRCALPHA,alpha);
-
-    int ret = SDL_BlitSurface(sdl_surface_copy, NULL, screen, &dest);
-
-    if (update == UPDATE)
-      SDL_UpdateRect(screen, dest.x, dest.y, dest.w, dest.h);
-
-    SDL_FreeSurface (sdl_surface_copy);
-    return ret;
-    }
-
-  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;
-}
-
-int
-SurfaceSDL::draw_stretched(float x, float y, int sw, int sh, Uint8 alpha, bool update)
-{
-  SDL_Rect dest;
-
-  dest.x = (int)x;
-  dest.y = (int)y;
-  dest.w = (int)sw;
-  dest.h = (int)sh;
-
-  if(alpha != 255)
-    SDL_SetAlpha(sdl_surface ,SDL_SRCALPHA,alpha);
-
-
-  SDL_Surface* sdl_surface_copy = SDL_CreateRGBSurface (sdl_surface->flags,
-                                  sw, sh, sdl_surface->format->BitsPerPixel,
-                                  sdl_surface->format->Rmask, sdl_surface->format->Gmask,
-                                  sdl_surface->format->Bmask,
-                                  0);
-
-  SDL_BlitSurface(sdl_surface, NULL, sdl_surface_copy, NULL);
-  SDL_SoftStretch(sdl_surface_copy, NULL, sdl_surface_copy, &dest);
-
-  int ret = SDL_BlitSurface(sdl_surface_copy,NULL,screen,&dest);
-  SDL_FreeSurface(sdl_surface_copy);
-
-  if (update == UPDATE)
-    update_rect(screen, dest.x, dest.y, dest.w, dest.h);
-
-  return ret;
-}
-
-SurfaceSDL::~SurfaceSDL()
-{}
-
-/* EOF */
diff --git a/src/texture.h b/src/texture.h
deleted file mode 100644 (file)
index 0e68e70..0000000
+++ /dev/null
@@ -1,169 +0,0 @@
-//  $Id$
-// 
-//  SuperTux
-//  Copyright (C) 2004 Tobias Glaesser <tobi.web@gmx.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.
-
-#ifndef SUPERTUX_TEXTURE_H
-#define SUPERTUX_TEXTURE_H
-
-#include <SDL.h>
-#include <string>
-#ifndef NOOPENGL
-#include <SDL_opengl.h>
-#endif
-
-#include <list>
-#include "screen.h"
-#include "vector.h"
-
-SDL_Surface* sdl_surface_from_sdl_surface(SDL_Surface* sdl_surf, int use_alpha);
-
-class SurfaceImpl;
-class SurfaceSDL;
-class SurfaceOpenGL;
-
-/** This class holds all the data necessary to construct a surface */
-class SurfaceData 
-{
-public:
-  enum ConstructorType { LOAD, LOAD_PART, SURFACE };
-  ConstructorType type;
-  SDL_Surface* surface;
-  std::string file;
-  int use_alpha;
-  int x;
-  int y;
-  int w;
-  int h;
-
-  SurfaceData(SDL_Surface* surf, int use_alpha_);
-  SurfaceData(const std::string& file_, int use_alpha_);
-  SurfaceData(const std::string& file_, int x_, int y_, int w_, int h_, int use_alpha_);
-  ~SurfaceData();
-
-  SurfaceSDL* create_SurfaceSDL();
-  SurfaceOpenGL* create_SurfaceOpenGL();
-  SurfaceImpl* create();
-};
-
-/** Container class that holds a surface, necessary so that we can
-    switch Surface implementations (OpenGL, SDL) on the fly */
-class Surface
-{
-public:
-  SurfaceData data;
-  SurfaceImpl* impl;
-  int w; 
-  int h;
-  
-  typedef std::list<Surface*> Surfaces;
-  static Surfaces surfaces;
-public:
-  static void reload_all();
-  static void debug_check();
-
-  Surface(SDL_Surface* surf, int use_alpha);  
-  Surface(const std::string& file, int use_alpha);  
-  Surface(const std::string& file, int x, int y, int w, int h, int use_alpha);
-  ~Surface();
-  
-  /** Captures the screen and returns it as Surface*, the user is expected to call the destructor. */
-  static Surface* CaptureScreen();
-  
-  /** Reload the surface, which is necesarry in case of a mode swich */
-  void reload();
-
-  void draw(float x, float y, Uint8 alpha = 255, bool upside_down = false, bool update = false);
-  void draw_bg(Uint8 alpha = 255, bool update = false);
-  void draw_part(float sx, float sy, float x, float y, float w, float h,  Uint8 alpha = 255, bool update = false);
-  void draw_stretched(float x, float y, int w, int h, Uint8 alpha, bool update = false);
-  void resize(int w_, int h_);
-
-  /// conveniance function
-  void draw(const Vector& pos, Uint8 alpha = 255, bool upside_down = false, bool update = false)
-  {
-    draw(pos.x, pos.y, alpha, upside_down, update);
-  }
-};
-
-/** Surface implementation, all implementation have to inherit from
-    this class */
-class SurfaceImpl
-{
-protected:
-  SDL_Surface* sdl_surface;
-
-public:
-  int w;
-  int h;
-
-public:
-  SurfaceImpl();
-  virtual ~SurfaceImpl();
-  
-  /** Return 0 on success, -2 if surface needs to be reloaded */
-  virtual int draw(float x, float y, Uint8 alpha, bool upside_down, bool update) = 0;
-  virtual int draw_bg(Uint8 alpha, bool update) = 0;
-  virtual int draw_part(float sx, float sy, float x, float y, float w, float h,  Uint8 alpha, bool update) = 0;
-  virtual int draw_stretched(float x, float y, int w, int h, Uint8 alpha, bool update) = 0;
-  int resize(int w_, int h_);
-
-  SDL_Surface* get_sdl_surface() const; // @evil@ try to avoid this function
-};
-
-class SurfaceSDL : public SurfaceImpl
-{
-public:
-  SurfaceSDL(SDL_Surface* surf, int use_alpha);
-  SurfaceSDL(const std::string& file, int use_alpha);  
-  SurfaceSDL(const std::string& file, int x, int y, int w, int h, int use_alpha);
-  virtual ~SurfaceSDL();
-
-  int draw(float x, float y, Uint8 alpha, bool upside_down, bool update);
-  int draw_bg(Uint8 alpha, bool update);
-  int draw_part(float sx, float sy, float x, float y, float w, float h,  Uint8 alpha, bool update);
-  int draw_stretched(float x, float y, int w, int h, Uint8 alpha, bool update);
-};
-
-#ifndef NOOPENGL
-class SurfaceOpenGL : public SurfaceImpl
-{
-public:
-  unsigned gl_texture;
-
-public:
-  SurfaceOpenGL(SDL_Surface* surf, int use_alpha);
-  SurfaceOpenGL(const std::string& file, int use_alpha);  
-  SurfaceOpenGL(const std::string& file, int x, int y, int w, int h, int use_alpha);
-  virtual ~SurfaceOpenGL();
-
-  int draw(float x, float y, Uint8 alpha, bool upside_down, bool update);
-  int draw_bg(Uint8 alpha, bool update);
-  int draw_part(float sx, float sy, float x, float y, float w, float h,  Uint8 alpha, bool update);
-  int draw_stretched(float x, float y, int w, int h, Uint8 alpha, bool update);
-
-private:
-  void create_gl(SDL_Surface * surf, GLuint * tex);
-};
-#endif 
-
-#endif /*SUPERTUX_TEXTURE_H*/
-
-/* Local Variables: */
-/* mode: c++ */
-/* End: */
index 3cb7427..d38ff62 100644 (file)
 
 #include "tile.h"
 #include "scene.h"
-#include "assert.h"
+#include <assert.h>
+#include <iostream>
+#include "screen/drawing_context.h"
 
 TileManager* TileManager::instance_  = 0;
 std::set<TileGroup>* TileManager::tilegroups_  = 0;
 
 Tile::Tile()
+  : id(-1), attributes(0), data(0), next_tile(0), anim_speed(25)
 {
 }
 
@@ -41,6 +44,62 @@ Tile::~Tile()
   }
 }
 
+int
+Tile::read(LispReader& reader)
+{
+  if(!reader.read_int("id", &id)) {
+    std::cerr << "Missing tile-id.\n";
+    return -1;
+  }
+  
+  bool value;
+  if(reader.read_bool("solid", &value) && value)
+    attributes |= SOLID;
+  if(reader.read_bool("unisolid", &value) && value)
+    attributes |= GOAL;                            
+  if(reader.read_bool("brick", &value) && value)
+    attributes |= BRICK;
+  if(reader.read_bool("ice", &value) && value)
+    attributes |= ICE;
+  if(reader.read_bool("water", &value) && value)
+    attributes |= WATER;
+  if(reader.read_bool("spike", &value) && value)
+    attributes |= SPIKE;
+  if(reader.read_bool("fullbox", &value) && value)
+    attributes |= FULLBOX;
+  if(reader.read_bool("distro", &value) && value)
+    attributes |= COIN;
+  if(reader.read_bool("coin", &value) && value)
+    attributes |= COIN;
+  if(reader.read_bool("goal", &value) && value)
+    attributes |= GOAL;
+
+  reader.read_int("data", &data);
+  reader.read_int("anim-speed", &anim_speed);
+  reader.read_int("next-tile", &next_tile);
+
+  std::vector<std::string> filenames;
+  reader.read_string_vector("images", &filenames);
+  std::vector<std::string> editor_filenames;
+  reader.read_string_vector("editor-images", &editor_filenames);
+
+  // read images
+  for(std::vector<std::string>::iterator i = filenames.begin();
+      i != filenames.end(); ++i) {
+    Surface* surface 
+      = new Surface(datadir + "/images/tilesets/" + *i, USE_ALPHA);
+    images.push_back(surface);
+  }
+  for(std::vector<std::string>::iterator i = editor_filenames.begin();
+      i != editor_filenames.end(); ++i) {
+    Surface* surface 
+      = new Surface(datadir + "/images/tilesets/" + *i, USE_ALPHA);
+    editor_images.push_back(surface);
+  }
+
+  return id;
+}
+
 //---------------------------------------------------------------------------
 
 TileManager::TileManager()
@@ -83,67 +142,21 @@ void TileManager::load_tileset(std::string filename)
 
           if (strcmp(lisp_symbol(lisp_car(element)), "tile") == 0)
             {
-             
-            
-              Tile* tile = new Tile;
-              tile->id      = -1;
-              tile->solid   = false;
-             tile->unisolid = false;
-              tile->brick   = false;
-              tile->ice     = false;
-              tile->water   = false;
-              tile->spike   = false;
-              tile->fullbox = false;
-              tile->distro  = false;
-              tile->goal    = false;
-              tile->data    = 0;
-              tile->next_tile  = 0;
-              tile->anim_speed = 25;
-
               LispReader reader(lisp_cdr(element));
-              assert(reader.read_int("id",  &tile->id));
-              reader.read_bool("solid",     &tile->solid);
-             reader.read_bool("unisolid",  &tile->unisolid);
-              reader.read_bool("brick",     &tile->brick);
-              reader.read_bool("ice",       &tile->ice);
-              reader.read_bool("water",     &tile->water);
-              reader.read_bool("spike",     &tile->spike);
-              reader.read_bool("fullbox",   &tile->fullbox);
-              reader.read_bool("distro",    &tile->distro);
-              reader.read_bool("goal",      &tile->goal);
-              reader.read_int("data",       &tile->data);
-              reader.read_int("anim-speed", &tile->anim_speed);
-              reader.read_int("next-tile",  &tile->next_tile);
-              reader.read_string_vector("images",  &tile->filenames);
-             reader.read_string_vector("editor-images", &tile->editor_filenames);
-
-              for(std::vector<std::string>::iterator it = tile->
-                  filenames.begin();
-                  it != tile->filenames.end();
-                  ++it)
-                {
-                  Surface* cur_image;
-                  tile->images.push_back(cur_image);
-                  tile->images[tile->images.size()-1] = new Surface(
-                               datadir +  "/images/tilesets/" + (*it),
-                               USE_ALPHA);
-                }
-              for(std::vector<std::string>::iterator it = tile->editor_filenames.begin();
-                  it != tile->editor_filenames.end();
-                  ++it)
-                {
-                  Surface* cur_image;
-                  tile->editor_images.push_back(cur_image);
-                  tile->editor_images[tile->editor_images.size()-1] = new Surface(
-                               datadir + "/images/tilesets/" + (*it),
-                               USE_ALPHA);
-                }
-               
-              if (tile->id + tileset_id >= int(tiles.size())
-                 )
-                tiles.resize(tile->id + tileset_id+1);
-
-              tiles[tile->id + tileset_id] = tile;
+
+              Tile* tile = new Tile;
+              int tile_id = tile->read(reader);
+              if(tile_id < 0) {
+                std::cerr 
+                  << "Warning: parse error when reading a tile, skipping.\n";
+                continue;
+              }
+
+              tile_id += tileset_id;
+
+              if(tile_id >= int(tiles.size()))
+                tiles.resize(tile_id+1);
+              tiles[tile_id] = tile;
             }
           else if (strcmp(lisp_symbol(lisp_car(element)), "tileset") == 0)
             {
@@ -171,7 +184,8 @@ void TileManager::load_tileset(std::string filename)
             }
           else
             {
-              puts("Unhandled symbol");
+              std::cerr << "Unknown symbol: " << 
+                lisp_symbol(lisp_car(element)) << "\n";
             }
 
           cur = lisp_cdr(cur);
@@ -187,52 +201,28 @@ void TileManager::load_tileset(std::string filename)
 }
 
 void
-Tile::draw(float x, float y, unsigned int c, Uint8 alpha)
+TileManager::draw_tile(DrawingContext& context, unsigned int c,
+    const Vector& pos, int layer)
 {
-  if (c != 0)
-    {
-      Tile* ptile = TileManager::instance()->get(c);
-      if(ptile)
-        {
-          if(ptile->images.size() > 1)
-            {
-              ptile->images[( ((global_frame_counter*25) / ptile->anim_speed) % (ptile->images.size()))]->draw(x,y, alpha);
-            }
-          else if (ptile->images.size() == 1)
-            {
-              ptile->images[0]->draw(x,y, alpha);
-            }
-          else
-            {
-              //printf("Tile not dravable %u\n", c);
-            }
-        }
-    }
-}
+  if(c == 0)
+    return;
 
-void
-Tile::draw_stretched(float x, float y, int w, int h, unsigned int c, Uint8 alpha)
-{
-  if (c != 0)
-    {
-      Tile* ptile = TileManager::instance()->get(c);
-      if(ptile)
-        {
-          if(ptile->images.size() > 1)
-            {
-              ptile->images[( ((global_frame_counter*25) / ptile->anim_speed) % (ptile->images.size()))]->draw_stretched(x,y,w,h, alpha);
-            }
-          else if (ptile->images.size() == 1)
-            {
-              ptile->images[0]->draw_stretched(x,y, w, h, alpha);
-            }
-          else
-            {
-              //printf("Tile not dravable %u\n", c);
-            }
-        }
-    }
-}
+  Tile* tile = get(c);
+  if(!tile)
+    return;
 
-// EOF //
+  if(!tile->images.size())
+    return;
+
+  if(tile->images.size() > 1)
+  {
+    size_t frame 
+      = ((global_frame_counter*25) / tile->anim_speed) % tile->images.size();
+    context.draw_surface(tile->images[frame], pos, layer);
+  }
+  else if (tile->images.size() == 1)
+  {
+    context.draw_surface(tile->images[0], pos, layer);
+  }
+}
 
index 9123422..e72fbee 100644 (file)
 #include <set>
 #include <map>
 #include <vector>
-#include "texture.h"
+#include "screen/texture.h"
 #include "globals.h"
 #include "lispreader.h"
 #include "setup.h"
+#include "polygon.h"
 #include "vector.h"
 
+class LispReader;
+
 /**
 Tile Class
 */
@@ -39,46 +42,43 @@ public:
   Tile();
   ~Tile();
 
+  /// parses the tile and returns it's id number
+  int read(LispReader& reader);
+
   int id;
 
   std::vector<Surface*> images;
   std::vector<Surface*> editor_images;
   
-  std::vector<std::string>  filenames;
-  std::vector<std::string> editor_filenames;
+  /// bitset for tileflags
+  enum {
+      /** solid tile that is indestructable by Tux */
+      SOLID     = 0x0001,
+      /** uni-directional solid tile */
+      UNISOLID  = 0x0002,
+      /** a brick that can be destroyed by jumping under it */
+      BRICK     = 0x0004,
+      /** an ice brick that makes tux sliding more than usual */
+      ICE       = 0x0008,
+      /** a water tile in which tux starts to swim */
+      WATER     = 0x0010,
+      /** a tile that hurts the player if he touches it */
+      SPIKE     = 0x0020,
+      /** Bonusbox, content is stored in \a data */
+      FULLBOX   = 0x0040,
+      /** Tile is a coin */
+      COIN      = 0x0080,
+      /** the level should be finished when touching a goaltile.
+       * if data is 0 then the endsequence should be triggered, if data is 1
+       * then we can finish the level instantly.
+       */
+      GOAL      = 0x0100
+  };
+
+  /** tile attributes */
+  uint32_t attributes;
   
-  /** solid tile that is indestructable by Tux */
-  bool solid;
-
-  /** uni-directional solid tile */
-  bool unisolid;
-
-  /** a brick that can be destroyed by jumping under it */
-  bool brick;
-
-  /** FIXME: ? */
-  bool ice;
-
-  /** water */
-  bool water;
-
-  /** spike - kills player on contact */
-  bool spike;
-
-  /** Bonusbox, content is stored in \a data */
-  bool fullbox;
-
-  /** Tile is a distro/coin */
-  bool distro;
-
-
-  /** the level should be finished when touching a goaltile.
-   * if data is 0 then the endsequence should be triggered, if data is 1
-   * then we can finish the level instantly.
-   */
-  bool goal;
-
-  /** General purpose data attached to a tile (content of a box, type of coin) */
+  /** General purpose data attached to a tile (content of a box, type of coin)*/
   int data;
 
   /** Id of the tile that is going to replace this tile once it has
@@ -88,12 +88,22 @@ public:
   int anim_speed;
   
   /** Draw a tile on the screen: */
-  static void draw(float x, float y, unsigned int c, Uint8 alpha = 255);
-  static void draw_stretched(float x, float y, int w, int h, unsigned int c, Uint8 alpha = 255);
+  static void draw(const Vector& pos, unsigned int c, Uint8 alpha = 255);
+
+  /// returns the width of the tile in pixels
+  int getWidth() const
+  { 
+    if(!images.size())
+      return 0;
+    return images[0]->w;
+  }
 
-  static void draw(const Vector& pos, unsigned int c, Uint8 alpha = 255)
+  /// returns the height of the tiles in pixels
+  int getHeight() const
   {
-    draw(pos.x, pos.y, c, alpha);
+    if(!images.size())
+      return 0;
+    return images[0]->h;
   }
 };
 
@@ -122,8 +132,13 @@ class TileManager
   std::string current_tileset;
   
  public:
-  static TileManager* instance() { return instance_ ? instance_ : instance_ = new TileManager(); }
-  static void destroy_instance() { delete instance_; instance_ = 0; }
+  static TileManager* instance()
+  { return instance_ ? instance_ : instance_ = new TileManager(); }
+  static void destroy_instance()
+  { delete instance_; instance_ = 0; }
+
+  void draw_tile(DrawingContext& context, unsigned int id,
+      const Vector& pos, int layer);
   
   static std::set<TileGroup>* tilegroups() { if(!instance_) { instance_ = new TileManager(); } return tilegroups_ ? tilegroups_ : tilegroups_ = new std::set<TileGroup>; }
   Tile* get(unsigned int id) {
index bb6a0ba..6741d74 100644 (file)
 //  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 "tilemap.h"
-#include "display_manager.h"
+
+#include <assert.h>
+#include <algorithm>
+#include "screen/drawing_context.h"
 #include "level.h"
 #include "tile.h"
 #include "globals.h"
 
-TileMap::TileMap(DisplayManager& display_manager, Level* newlevel)
+TileMap::TileMap(Level* newlevel)
   : level(newlevel)
 {
-  display_manager.add_drawable(this, LAYER_BACKGROUNDTILES);
-  display_manager.add_drawable(this, LAYER_TILES);
-  display_manager.add_drawable(this, LAYER_FOREGROUNDTILES);
+  tilemanager = TileManager::instance();
 }
 
 TileMap::~TileMap()
@@ -42,29 +41,31 @@ TileMap::action(float )
 }
 
 void
-TileMap::draw(Camera& viewport, int layer)
+TileMap::draw(const std::vector<unsigned int>& tiles, DrawingContext& context,
+    int layer)
 {
-  std::vector<unsigned int>* tiles;
-  switch(layer) {
-    case LAYER_BACKGROUNDTILES:
-      tiles = &level->bg_tiles; break;
-    case LAYER_TILES:
-      tiles = &level->ia_tiles; break;
-    case LAYER_FOREGROUNDTILES:
-      tiles = &level->fg_tiles; break;
-    default:
-      assert(!"Wrong layer when drawing tilemap.");
-  }
-
-  int tsx = int(viewport.get_translation().x / 32); // tilestartindex x
-  int tsy = int(viewport.get_translation().y / 32); // tilestartindex y
-  int sx = - (int(viewport.get_translation().x) % 32);
-  int sy = - (int(viewport.get_translation().y) % 32);
-  for(int x = sx, tx = tsx; x < screen->w && tx < level->width;
-      x += 32, ++tx) {
-    for(int y = sy, ty = tsy; y < screen->h && ty < level->height;
-          y += 32, ++ty) {
-      Tile::draw(x, y, (*tiles) [ty * level->width + tx]);
+  float start_x = context.get_translation().x;
+  float start_y = context.get_translation().y;
+  float end_x = std::min(start_x + screen->w, float(level->width * 32));
+  float end_y = std::min(start_y + screen->h, float(level->height * 32));
+  start_x -= int(start_x) % 32;
+  start_y -= int(start_y) % 32;  
+  int tsx = int(start_x / 32); // tilestartindex x
+  int tsy = int(start_y / 32); // tilestartindex y
+  
+  Vector pos;
+  int tx, ty;
+  for(pos.x = start_x, tx = tsx; pos.x < end_x; pos.x += 32, ++tx) {
+    for(pos.y = start_y, ty = tsy; pos.y < end_y; pos.y += 32, ++ty) {
+      tilemanager->draw_tile(context, tiles[ty*level->width + tx], pos, layer);
     }
   }
 }
+
+void
+TileMap::draw(DrawingContext& context)
+{
+  draw(level->bg_tiles, context, LAYER_BACKGROUNDTILES);
+  draw(level->ia_tiles, context, LAYER_TILES);
+  draw(level->fg_tiles, context, LAYER_FOREGROUNDTILES);
+}
index a1cc142..8d8f291 100644 (file)
 #ifndef __TILEMAP_H__
 #define __TILEMAP_H__
 
+#include <vector>
 #include "game_object.h"
-#include "drawable.h"
+#include "serializable.h"
 
 class Level;
+class TileManager;
 
 /**
  * This class is reponsible for drawing the level tiles
  */
-class TileMap : public GameObject, public Drawable
+class TileMap : public GameObject
 {
 public:
-  TileMap(DisplayManager& manager, Level* level);
+  TileMap(Level* level);
   virtual ~TileMap();
 
   virtual void action(float elapsed_time);
-  virtual void draw(Camera& viewport, int layer);
+  virtual void draw(const std::vector<unsigned int>& tiles,
+      DrawingContext& context, int layer);
+  virtual void draw(DrawingContext& context);
   
 private:
+  TileManager* tilemanager;
   Level* level;
 };
 
index a2fa619..9ef6a6d 100644 (file)
 #include "defines.h"
 #include "globals.h"
 #include "title.h"
-#include "screen.h"
+#include "screen/screen.h"
+#include "screen/texture.h"
 #include "high_scores.h"
 #include "menu.h"
-#include "texture.h"
 #include "timer.h"
 #include "setup.h"
 #include "level.h"
@@ -117,8 +117,6 @@ void check_contrib_menu()
           
               current_contrib_subset = subset.name;
 
-              std::cout << "Updating the contrib subset menu..." << subset.levels << std::endl;
-      
               contrib_subset_menu->clear();
 
               contrib_subset_menu->additem(MN_LABEL, subset.title, 0,0);
@@ -156,13 +154,6 @@ void check_contrib_subset_menu()
     }  
 }
 
-void draw_background()
-{
-  /* Draw the title background: */
-
-  bkg_title->draw_bg();
-}
-
 void draw_demo(GameSession* session, double frame_ratio)
 {
   World* world  = session->get_world();
@@ -221,9 +212,6 @@ void title(void)
 
   GameSession session(datadir + "/levels/misc/menu.stl", 0, ST_GL_DEMO_GAME);
 
-  clearscreen(0, 0, 0);
-  updatescreen();
-
   /* Load images: */
   bkg_title = new Surface(datadir + "/images/background/arctis.jpg", IGNORE_ALPHA);
   logo = new Surface(datadir + "/images/title/logo.png", USE_ALPHA);
@@ -232,13 +220,11 @@ void title(void)
   /* --- Main title loop: --- */
   frame = 0;
 
-  /* Draw the title background: */
-  bkg_title->draw_bg();
-
   update_time = st_get_ticks();
   random_timer.start(rand() % 2000 + 2000);
 
   Menu::set_current(main_menu);
+  DrawingContext& context = World::current()->context;
   while (Menu::current())
     {
       // if we spent to much time on a menu entry
@@ -266,22 +252,26 @@ void title(void)
 
       /* Draw the background: */
       draw_demo(&session, frame_ratio);
-      
+     
+      context.push_transform();
+      context.set_translation(Vector(0, 0));
       if (Menu::current() == main_menu)
-        logo->draw(screen->w/2 - logo->w/2, 30);
+        context.draw_surface(logo, Vector(screen->w/2 - logo->w/2, 30),
+            LAYER_FOREGROUND1+1);
 
-      white_small_text->draw(" SuperTux " VERSION "\n"
-                             "Copyright (c) 2003 SuperTux Devel Team\n"
-                             "This game comes with ABSOLUTELY NO WARRANTY. This is free software, and you\n"
-                             "are welcome to redistribute it under certain conditions; see the file COPYING\n"
-                             "for details.\n",
-                             0, screen->h - 70, 0);
+      context.draw_text(white_small_text,
+          " SuperTux " VERSION "\n"
+          "Copyright (c) 2003 SuperTux Devel Team\n"
+          "This game comes with ABSOLUTELY NO WARRANTY. This is free software, and you\n"
+          "are welcome to redistribute it under certain conditions; see the file COPYING\n"
+          "for details.\n", Vector(0, screen->h - 70), LAYER_FOREGROUND1);
+      context.pop_transform();
 
       /* Don't draw menu, if quit is true */
       Menu* menu = Menu::current();
       if(menu)
         {
-          menu->draw();
+          menu->draw(context);
           menu->action();
         
           if(menu == main_menu)
@@ -298,7 +288,8 @@ void title(void)
                   generate_contrib_menu();
                   break;
                 case MNID_LEVELEDITOR:
-                  leveleditor();
+                  // TODO
+                  //leveleditor();
                   Menu::set_current(main_menu);
                   break;
                 case MNID_CREDITS:
@@ -322,8 +313,6 @@ void title(void)
                 char str[1024];
                 sprintf(str,"Are you sure you want to delete slot %d?", slot);
                 
-                draw_background();
-
                 if(confirm_dialog(str))
                   {
                   sprintf(str,"%s/slot%d.stsg", st_save_dir, slot);
@@ -352,9 +341,9 @@ void title(void)
             }
         }
 
-      mouse_cursor->draw();
-      
-      flipscreen();
+      mouse_cursor->draw(context);
+     
+      context.do_drawing();
 
       /* Set the time of the last update and the time of the current update */
       last_update_time = update_time;
index 9638500..9b44385 100644 (file)
@@ -23,7 +23,7 @@
 #include "stdlib.h"
 #include "setup.h"
 #include "globals.h"
-#include "screen.h"
+#include "screen/screen.h"
 #include "defines.h"
 #include "type.h"
 #include "scene.h"
index 21f4a6a..699a4cc 100644 (file)
@@ -46,6 +46,11 @@ public:
     return Vector(x / s, y / s);
   }
 
+  Vector operator-() const
+  {
+    return Vector(-x, -y);
+  }
+
   const Vector& operator +=(const Vector& other)
   {
     x += other.x;
index 98b1ed5..3f63a2e 100644 (file)
@@ -26,7 +26,7 @@
 #include <string.h>
 #include "globals.h"
 #include "scene.h"
-#include "screen.h"
+#include "screen/screen.h"
 #include "defines.h"
 #include "world.h"
 #include "level.h"
@@ -34,7 +34,6 @@
 #include "resources.h"
 #include "gameobjs.h"
 #include "camera.h"
-#include "display_manager.h"
 #include "background.h"
 #include "tilemap.h"
 
@@ -49,10 +48,10 @@ World::World(const std::string& filename, int level_nr)
   // world calls child functions
   current_ = this;
 
-  tux = new Player(displaymanager);
+  tux = new Player;
   add_object(tux);
   
-  level = new Level();
+  level = new Level;
   camera = new Camera(tux, level);
   add_object(camera);                 
 
@@ -65,19 +64,11 @@ World::World(const std::string& filename, int level_nr)
   
   set_defaults();
 
-  level->load_gfx();
   // add background
   activate_particle_systems();
-  background = new Background(displaymanager);
-  if(level->img_bkgd) {
-    background->set_image(level->img_bkgd, level->bkgd_speed);
-  } else {
-    background->set_gradient(level->bkgd_top, level->bkgd_bottom);
-  }
-  add_object(background);
 
   // add tilemap
-  add_object(new TileMap(displaymanager, level));
+  add_object(new TileMap(level));
   level->load_song();
 
   apply_bonuses();
@@ -145,6 +136,9 @@ World::add_object(GameObject* object)
   FlyingPlatform* flying_platform = dynamic_cast<FlyingPlatform*> (object);
   if(flying_platform)
     flying_platforms.push_back(flying_platform);
+  Background* background = dynamic_cast<Background*> (object);
+  if(background)
+    this->background = background;
 
   gameobjects.push_back(object);
 }
@@ -159,14 +153,14 @@ World::parse_objects(lisp_object_t* cur)
     LispReader reader(lisp_cdr(data));
 
     if(object_type == "trampoline") {
-      add_object(new Trampoline(displaymanager, reader));
+      add_object(new Trampoline(reader));
     }
     else if(object_type == "flying-platform") {
-      add_object(new FlyingPlatform(displaymanager, reader));
+      add_object(new FlyingPlatform(reader));
     }
     else {
       BadGuyKind kind = badguykind_from_string(object_type);
-      add_object(new BadGuy(displaymanager, kind, reader));
+      add_object(new BadGuy(kind, reader));
     }
       
     cur = lisp_cdr(cur);
@@ -178,11 +172,11 @@ World::activate_particle_systems()
 {
   if (level->particle_system == "clouds")
     {
-      add_object(new CloudParticleSystem(displaymanager));
+      add_object(new CloudParticleSystem);
     }
   else if (level->particle_system == "snow")
     {
-      add_object(new SnowParticleSystem(displaymanager));
+      add_object(new SnowParticleSystem);
     }
   else if (level->particle_system != "")
     {
@@ -194,13 +188,16 @@ void
 World::draw()
 {
   /* Draw objects */
-  displaymanager.draw(*camera);
+  for(std::vector<GameObject*>::iterator i = gameobjects.begin();
+      i != gameobjects.end(); ++i)
+    if((*i)->is_valid())
+      (*i)->draw(context);
 }
 
 void
 World::action(float elapsed_time)
 {
-  tux->check_bounds(*camera);
+  tux->check_bounds(context);
     
   /* update objects (don't use iterators here, because the list might change
    * during the iteration)
@@ -216,9 +213,6 @@ World::action(float elapsed_time)
   for(std::vector<GameObject*>::iterator i = gameobjects.begin();
       i != gameobjects.end(); /* nothing */) {
     if((*i)->is_valid() == false) {
-      Drawable* drawable = dynamic_cast<Drawable*> (*i);
-      if(drawable)
-        displaymanager.remove_drawable(drawable);
       BadGuy* badguy = dynamic_cast<BadGuy*> (*i);
       if(badguy) {
         bad_guys.erase(std::remove(bad_guys.begin(), bad_guys.end(), badguy),
@@ -383,13 +377,13 @@ World::add_score(const Vector& pos, int s)
 {
   player_status.score += s;
 
-  add_object(new FloatingScore(displaymanager, pos, s));
+  add_object(new FloatingScore(pos, s));
 }
 
 void
 World::add_bouncy_distro(const Vector& pos)
 {
-  add_object(new BouncyDistro(displaymanager, pos));
+  add_object(new BouncyDistro(pos));
 }
 
 void
@@ -406,19 +400,19 @@ void
 World::add_broken_brick_piece(const Vector& pos, const Vector& movement,
     Tile* tile)
 {
-  add_object(new BrokenBrick(displaymanager, tile, pos, movement));
+  add_object(new BrokenBrick(tile, pos, movement));
 }
 
 void
 World::add_bouncy_brick(const Vector& pos)
 {
-  add_object(new BouncyBrick(displaymanager, pos));
+  add_object(new BouncyBrick(pos));
 }
 
 BadGuy*
 World::add_bad_guy(float x, float y, BadGuyKind kind)
 {
-  BadGuy* badguy = new BadGuy(displaymanager, kind, x, y);
+  BadGuy* badguy = new BadGuy(kind, x, y);
   add_object(badguy);
   return badguy;
 }
@@ -426,7 +420,7 @@ World::add_bad_guy(float x, float y, BadGuyKind kind)
 void
 World::add_upgrade(const Vector& pos, Direction dir, UpgradeKind kind)
 {
-  add_object(new Upgrade(displaymanager, pos, dir, kind));
+  add_object(new Upgrade(pos, dir, kind));
 }
 
 bool
@@ -445,9 +439,9 @@ World::add_bullet(const Vector& pos, float xm, Direction dir)
 
   Bullet* new_bullet = 0;
   if(tux->got_power == Player::FIRE_POWER)
-    new_bullet = new Bullet(displaymanager, pos, xm, dir, FIRE_BULLET);
+    new_bullet = new Bullet(pos, xm, dir, FIRE_BULLET);
   else if(tux->got_power == Player::ICE_POWER)
-    new_bullet = new Bullet(displaymanager, pos, xm, dir, ICE_BULLET);
+    new_bullet = new Bullet(pos, xm, dir, ICE_BULLET);
   else
     st_abort("wrong bullet type.", "");
   add_object(new_bullet);
@@ -490,7 +484,7 @@ World::trybreakbrick(float x, float y, bool small)
   Level* plevel = get_level();
   
   Tile* tile = gettile(x, y);
-  if (tile->brick)
+  if (tile->attributes & Tile::BRICK)
     {
       if (tile->data > 0)
         {
@@ -546,7 +540,7 @@ void
 World::tryemptybox(float x, float y, Direction col_side)
 {
   Tile* tile = gettile(x,y);
-  if (!tile->fullbox)
+  if (!(tile->attributes & Tile::FULLBOX))
     return;
 
   // according to the collision side, set the upgrade direction
@@ -602,7 +596,7 @@ void
 World::trygrabdistro(float x, float y, int bounciness)
 {
   Tile* tile = gettile(x, y);
-  if (tile && tile->distro)
+  if (tile && (tile->attributes & Tile::COIN))
     {
       level->change(x, y, TM_IA, tile->next_tile);
       play_sound(sounds[SND_DISTRO], SOUND_CENTER_SPEAKER);
index 072386f..d886cd3 100644 (file)
 #include "special.h"
 #include "badguy.h"
 #include "particlesystem.h"
-#include "gameobjs.h"
-#include "display_manager.h"
+#include "screen/drawing_context.h"
 
+class Camera;
 class Level;
 class Background;
+class Trampoline;
+class FlyingPlatform;
 
 /** The World class holds a level and all the game objects (badguys,
     bouncy distros, etc) that are needed to run a game. */
@@ -63,7 +65,7 @@ public:
   std::vector<GameObject*> gameobjects;
 
   Camera* camera;
-  DisplayManager displaymanager;
+  DrawingContext context;
 
 public:
   static World* current()
index 1132edd..944a39c 100644 (file)
@@ -23,8 +23,9 @@
 #include <assert.h>
 #include <unistd.h>
 #include "globals.h"
-#include "texture.h"
-#include "screen.h"
+#include "screen/texture.h"
+#include "screen/screen.h"
+#include "screen/drawing_context.h"
 #include "lispreader.h"
 #include "gameloop.h"
 #include "setup.h"
@@ -186,28 +187,28 @@ Tux::~Tux()
 }
 
 void
-Tux::draw(const Point& offset)
+Tux::draw(DrawingContext& context, const Vector& offset)
 {
-  Point pos = get_pos();
+  Vector pos = get_pos();
   switch (player_status.bonus)
     {
     case PlayerStatus::GROWUP_BONUS:
-      largetux_sprite->draw(pos.x + offset.x, 
-                            pos.y + offset.y - 10);
+      context.draw_surface(largetux_sprite,
+          Vector(pos.x + offset.x, pos.y + offset.y - 10), LAYER_OBJECTS);
       break;
     case PlayerStatus::FLOWER_BONUS:
-      firetux_sprite->draw(pos.x + offset.x, 
-                           pos.y + offset.y - 10);
+      context.draw_surface(firetux_sprite,
+          Vector(pos.x + offset.x, pos.y + offset.y - 10), LAYER_OBJECTS);
       break;
     case PlayerStatus::NO_BONUS:
-      smalltux_sprite->draw(pos.x + offset.x, 
-                            pos.y + offset.y - 10);
+      context.draw_surface(smalltux_sprite,
+          Vector(pos.x + offset.x, pos.y + offset.y - 10), LAYER_OBJECTS);
       break;
     }
 }
 
 
-Point
+Vector
 Tux::get_pos()
 {
   float x = tile_pos.x * 32;
@@ -231,7 +232,7 @@ Tux::get_pos()
       break;
     }
   
-  return Point((int)x, (int)y); 
+  return Vector((int)x, (int)y); 
 }
 
 void
@@ -243,7 +244,7 @@ Tux::stop()
 }
 
 void
-Tux::update(float delta)
+Tux::action(float delta)
 {
   if (!moving)
     {
@@ -252,7 +253,7 @@ Tux::update(float delta)
           WorldMap::Level* level = worldmap->at_level();
 
           // We got a new direction, so lets start walking when possible
-          Point next_tile;
+          Vector next_tile;
           if ((!level || level->solved)
               && worldmap->path_ok(input_direction, tile_pos, &next_tile))
             {
@@ -314,7 +315,7 @@ Tux::update(float delta)
                 }
 
               // Walk automatically to the next tile
-              Point next_tile;
+              Vector next_tile;
               if (worldmap->path_ok(direction, tile_pos, &next_tile))
                 {
                   tile_pos = next_tile;
@@ -426,8 +427,6 @@ WorldMap::load_map()
                       reader.read_int("x", &level.x);
                       reader.read_int("y", &level.y);
 
-                      get_level_title(&level);   // get level's title
-
                       levels.push_back(level);
                     }
                   
@@ -446,17 +445,17 @@ WorldMap::load_map()
     lisp_free(root_obj);
 }
 
-void WorldMap::get_level_title(Levels::pointer level)
+void WorldMap::get_level_title(Level& level)
 {
   /** get level's title */
-  level->title = "<no title>";
+  level.title = "<no title>";
 
   FILE * fi;
   lisp_object_t* root_obj = 0;
-  fi = fopen((datadir +  "/levels/" + level->name).c_str(), "r");
+  fi = fopen((datadir +  "/levels/" + level.name).c_str(), "r");
   if (fi == NULL)
   {
-    perror((datadir +  "/levels/" + level->name).c_str());
+    perror((datadir +  "/levels/" + level.name).c_str());
     return;
   }
 
@@ -466,13 +465,13 @@ void WorldMap::get_level_title(Levels::pointer level)
 
   if (root_obj->type == LISP_TYPE_EOF || root_obj->type == LISP_TYPE_PARSE_ERROR)
   {
-    printf("World: Parse Error in file %s", level->name.c_str());
+    printf("World: Parse Error in file %s", level.name.c_str());
   }
 
   if (strcmp(lisp_symbol(lisp_car(root_obj)), "supertux-level") == 0)
   {
     LispReader reader(lisp_cdr(root_obj));
-    reader.read_string("name",  &level->title);
+    reader.read_string("name",  &level.title);
   }
 
   lisp_free(root_obj);
@@ -571,8 +570,8 @@ WorldMap::get_input()
     }
 }
 
-Point
-WorldMap::get_next_tile(Point pos, Direction direction)
+Vector
+WorldMap::get_next_tile(Vector pos, Direction direction)
 {
   switch(direction)
     {
@@ -595,7 +594,7 @@ WorldMap::get_next_tile(Point pos, Direction direction)
 }
 
 bool
-WorldMap::path_ok(Direction direction, Point old_pos, Point* new_pos)
+WorldMap::path_ok(Direction direction, Vector old_pos, Vector* new_pos)
 {
   *new_pos = get_next_tile(old_pos, direction);
 
@@ -642,7 +641,8 @@ WorldMap::update(float delta)
 
               std::cout << "Enter the current level: " << level->name << std::endl;
               // do a shriking fade to the level
-              shrink_fade(Point((level->x*32 + 16 + offset.x),(level->y*32 + 16 + offset.y)), 2000);
+              shrink_fade(Vector((level->x*32 + 16 + offset.x),(level->y*32 + 16
+                      + offset.y)), 500);
               GameSession session(datadir +  "/levels/" + level->name,
                                   1, ST_GL_LOAD_LEVEL_FILE);
 
@@ -707,23 +707,29 @@ WorldMap::update(float delta)
                   player_status = old_player_status;
                   break;
                 case GameSession::ES_GAME_OVER:
+                {
                   /* draw an end screen */
                   /* in the future, this should make a dialog a la SuperMario, asking
                   if the player wants to restart the world map with no score and from
                   level 1 */
                   char str[80];
 
-                  drawgradient(Color (0, 255, 0), Color (255, 0, 255));
+                  DrawingContext context;
+                  context.draw_gradient(Color (0, 255, 0), Color (255, 0, 255),
+                      LAYER_BACKGROUND0);
 
-                  blue_text->drawf("GAMEOVER", 0, 200, A_HMIDDLE, A_TOP, 1);
+                  context.draw_text_center(blue_text, "GAMEOVER", 
+                      Vector(0, 200), LAYER_FOREGROUND1);
 
                   sprintf(str, "SCORE: %d", player_status.score);
-                  gold_text->drawf(str, 0, 224, A_HMIDDLE, A_TOP, 1);
+                  context.draw_text_center(gold_text, str,
+                      Vector(0, 224), LAYER_FOREGROUND1);
 
                   sprintf(str, "COINS: %d", player_status.distros);
-                  gold_text->drawf(str, 0, screen->w - gold_text->w*2, A_HMIDDLE, A_TOP, 1);
+                  context.draw_text_center(gold_text, str,
+                      Vector(0, screen->w - 32), LAYER_FOREGROUND1);
 
-                  flipscreen();
+                  context.do_drawing();
   
                   SDL_Event event;
                   wait_for_event(event,2000,5000,true);
@@ -731,7 +737,9 @@ WorldMap::update(float delta)
                   quit = true;
                   player_status.reset();
                   break;
+                }
                 case GameSession::ES_NONE:
+                  assert(false);
                   // Should never be reached 
                   break;
                 }
@@ -751,7 +759,7 @@ WorldMap::update(float delta)
     }
   else
     {
-      tux->update(delta);
+      tux->action(delta);
       tux->set_direction(input_direction);
     }
   
@@ -779,14 +787,16 @@ WorldMap::update(float delta)
 }
 
 Tile*
-WorldMap::at(Point p)
+WorldMap::at(Vector p)
 {
   assert(p.x >= 0 
          && p.x < width
          && p.y >= 0
          && p.y < height);
 
-  return tile_manager->get(tilemap[width * p.y + p.x]);
+  int x = int(p.x);
+  int y = int(p.y);
+  return tile_manager->get(tilemap[width * y + x]);
 }
 
 WorldMap::Level*
@@ -804,53 +814,66 @@ WorldMap::at_level()
 
 
 void
-WorldMap::draw(const Point& offset)
+WorldMap::draw(DrawingContext& context, const Vector& offset)
 {
   for(int y = 0; y < height; ++y)
     for(int x = 0; x < width; ++x)
       {
-        Tile* tile = at(Point(x, y));
-        tile->sprite->draw(x*32 + offset.x,
-                           y*32 + offset.y);
+        Tile* tile = at(Vector(x, y));
+        context.draw_surface(tile->sprite,
+            Vector(x*32 + offset.x, y*32 + offset.y), LAYER_TILES);
       }
   
   for(Levels::iterator i = levels.begin(); i != levels.end(); ++i)
     {
       if (i->solved)
-        leveldot_green->draw(i->x*32 + offset.x, 
-                             i->y*32 + offset.y);
+        context.draw_surface(leveldot_green,
+            Vector(i->x*32 + offset.x, i->y*32 + offset.y), LAYER_TILES+1);
       else
-        leveldot_red->draw(i->x*32 + offset.x, 
-                           i->y*32 + offset.y);        
+        context.draw_surface(leveldot_red,
+            Vector(i->x*32 + offset.x, i->y*32 + offset.y), LAYER_TILES+1);
     }
 
-  tux->draw(offset);
-  draw_status();
+  tux->draw(context, offset);
+  draw_status(context);
 }
 
 void
-WorldMap::draw_status()
+WorldMap::draw_status(DrawingContext& context)
 {
+  context.push_transform();
+  context.set_translation(Vector(0, 0));
+  
   char str[80];
   sprintf(str, "%d", player_status.score);
-  white_text->draw("SCORE", 0, 0);
-  gold_text->draw(str, 96, 0);
 
-  sprintf(str, "%d", player_status.distros);
-  white_text->draw_align("COINS", screen->w/2 - white_text->w*5, 0,  A_LEFT, A_TOP);
-  gold_text->draw_align(str, screen->w/2 + (white_text->w*5)/2, 0, A_RIGHT, A_TOP);
+  context.draw_text(white_text, "SCORE", Vector(0, 0), LAYER_FOREGROUND1);
+  context.draw_text(gold_text, str, Vector(96, 0), LAYER_FOREGROUND1);
 
-  white_text->draw("LIVES", screen->w - white_text->w*9, 0);
+  sprintf(str, "%d", player_status.distros);
+  context.draw_text(white_text, "COINS", Vector(screen->w/2 - 16*5, 0),
+      LAYER_FOREGROUND1);
+  context.draw_text(gold_text, str, Vector(screen->w/2 + (16*5)/2, 0),
+        LAYER_FOREGROUND1);
+
+  context.draw_text(white_text, "LIVES",
+      Vector(screen->w - white_text->get_text_width("LIVES")*2, 0),
+      LAYER_FOREGROUND1);
   if (player_status.lives >= 5)
     {
       sprintf(str, "%dx", player_status.lives);
-      gold_text->draw_align(str, screen->w - gold_text->w, 0, A_RIGHT, A_TOP);
-      tux_life->draw(screen->w - gold_text->w, 0);
+      context.draw_text(gold_text, str, 
+          Vector(screen->w - gold_text->get_text_width(str) - tux_life->w, 0),
+          LAYER_FOREGROUND1);
+      context.draw_surface(tux_life, Vector(screen->w - gold_text->w, 0),
+          LAYER_FOREGROUND1);
     }
   else
     {
       for(int i= 0; i < player_status.lives; ++i)
-        tux_life->draw(screen->w - tux_life->w*4 +(tux_life->w*i),0);
+        context.draw_surface(tux_life,
+            Vector(screen->w - tux_life->w*4 + (tux_life->w*i), 0),
+            LAYER_FOREGROUND1);
     }
 
   if (!tux->is_moving())
@@ -860,7 +883,13 @@ WorldMap::draw_status()
           if (i->x == tux->get_tile_pos().x && 
               i->y == tux->get_tile_pos().y)
             {
-              white_text->draw_align(i->title.c_str(), screen->w/2, screen->h,  A_HMIDDLE, A_BOTTOM);
+              if(i->title == "")
+                get_level_title(*i);
+
+              context.draw_text(white_text, i->title, 
+                  Vector(screen->w/2 - white_text->get_text_width(i->title)/2,
+                         screen->h - white_text->get_height() - 50),
+                  LAYER_FOREGROUND1);
               break;
             }
         }
@@ -882,6 +911,7 @@ WorldMap::display()
 
   last_update_time = update_time = st_get_ticks();
 
+  DrawingContext context;
   while(!quit)
     {
       float delta = ((float)(update_time-last_update_time))/100.0;
@@ -894,7 +924,7 @@ WorldMap::display()
       last_update_time = update_time;
       update_time      = st_get_ticks();
 
-      Point tux_pos = tux->get_pos();
+      Vector tux_pos = tux->get_pos();
       if (1)
         {
           offset.x = -tux_pos.x + screen->w/2;
@@ -907,16 +937,17 @@ WorldMap::display()
           if (offset.y < screen->h - height*32) offset.y = screen->h - height*32;
         } 
 
-      draw(offset);
+      draw(context, offset);
       get_input();
       update(delta);
 
       if(Menu::current())
         {
-          Menu::current()->draw();
-          mouse_cursor->draw();
+          Menu::current()->draw(context);
+          mouse_cursor->draw(context);
         }
-      flipscreen();
+
+      context.do_drawing();
 
       SDL_Delay(20);
     }
@@ -993,13 +1024,13 @@ WorldMap::loadgame(const std::string& filename)
   lisp_object_t* tux_cur = 0;
   if (reader.read_lisp("tux", &tux_cur))
     {
-      Point p;
+      Vector p;
       std::string back_str = "none";
       std::string bonus_str = "none";
 
       LispReader tux_reader(tux_cur);
-      tux_reader.read_int("x", &p.x);
-      tux_reader.read_int("y", &p.y);
+      tux_reader.read_float("x", &p.x);
+      tux_reader.read_float("y", &p.y);
       tux_reader.read_string("back", &back_str);
       tux_reader.read_string("bonus", &bonus_str);
       
index 0fb1021..b107771 100644 (file)
@@ -23,8 +23,9 @@
 #include <vector>
 #include <string>
 
+#include "vector.h"
 #include "musicref.h"
-#include "screen.h"
+#include "screen/screen.h"
 
 namespace WorldMapNS {
 
@@ -83,7 +84,7 @@ private:
 
   Direction input_direction;
   Direction direction;
-  Point tile_pos;
+  Vector tile_pos;
   /** Length by which tux is away from its current tile, length is in
       input_direction direction */
   float offset;
@@ -94,15 +95,15 @@ public:
   Tux(WorldMap* worldmap_);
   ~Tux();
   
-  void draw(const Point& offset);
-  void update(float delta);
+  void draw(DrawingContext& context, const Vector& offset);
+  void action(float elapsed_time);
 
   void set_direction(Direction d) { input_direction = d; }
 
   bool is_moving() const { return moving; }
-  Point get_pos();
-  Point get_tile_pos() const { return tile_pos; } 
-  void  set_tile_pos(Point p) { tile_pos = p; } 
+  Vector get_pos();
+  Vector get_tile_pos() const { return tile_pos; } 
+  void  set_tile_pos(Vector p) { tile_pos = p; } 
 };
 
 /** */
@@ -155,12 +156,12 @@ private:
   Direction input_direction;
   bool enter_level;
 
-  Point offset;
+  Vector offset;
   std::string savegame_file;
 
-  void get_level_title(Levels::pointer level);
+  void get_level_title(Level& level);
 
-  void draw_status();
+  void draw_status(DrawingContext& context);
 public:
   WorldMap();
   ~WorldMap();
@@ -176,15 +177,15 @@ public:
   void update(float delta);
 
   /** Draw one frame */
-  void draw(const Point& offset);
+  void draw(DrawingContext& context, const Vector& offset);
 
-  Point get_next_tile(Point pos, Direction direction);
-  Tile* at(Point pos);
+  Vector get_next_tile(Vector pos, Direction direction);
+  Tile* at(Vector pos);
   WorldMap::Level* at_level();
 
   /** Check if it is possible to walk from \a pos into \a direction,
       if possible, write the new position to \a new_pos */
-  bool path_ok(Direction direction, Point pos, Point* new_pos);
+  bool path_ok(Direction direction, Vector pos, Vector* new_pos);
 
   void savegame(const std::string& filename);
   void loadgame(const std::string& filename);