-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
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 \
player.h \
scene.cpp \
scene.h \
-screen.cpp \
-screen.h \
setup.cpp \
setup.h \
sound.cpp \
special.cpp \
special.h \
supertux.cpp \
-text.cpp \
-text.h \
-texture.cpp \
-texture.h \
timer.cpp \
timer.h \
title.cpp \
camera.h \
game_object.cpp \
game_object.h \
-display_manager.h \
-display_manager.cpp \
drawable.h \
background.h \
background.cpp \
#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
}
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();
}
}
#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;
#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;
}
}
-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);
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;
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);
remove_me();
}
-
void
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);
}
#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: */
class Player;
/* Badguy type: */
-class BadGuy : public MovingObject, public Drawable, public Serializable
+class BadGuy : public MovingObject, public Serializable
{
public:
/* Enemy modes: */
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,
#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;
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];
{
hlast = b;
}
+#endif
#define SUPERTUX_BUTTON_H
#include <vector>
-#include "texture.h"
-#include "drawable.h"
+#include "screen/texture.h"
+
+// TODO
+#if 0
enum ButtonState {
BUTTON_NONE = -1,
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)
std::vector<Button*> item;
std::vector<Button*>::iterator last_clicked;
};
+#endif
#endif /*SUPERTUX_BUTTON_H*/
#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),
{
}
-void
-Camera::set_translation(const Vector& newtranslation)
+const Vector&
+Camera::get_translation() const
{
- translation = newtranslation;
+ return World::current()->context.get_translation();
}
void
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
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
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;
}
}
static void* test_goal_tile_function(Tile* tile)
{
- if(tile && tile->goal)
+ if(tile && (tile->attributes & Tile::GOAL))
return tile;
return 0;
}
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 */
// 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);
+++ /dev/null
-// $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);
-}
-
+++ /dev/null
-// $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
-
+++ /dev/null
-// $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
-
#include <string>
-class DisplayManager;
+class DrawingContext;
/**
* Base class for all game objects. This contains functions for:
*/
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; }
#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"
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);
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
/* (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
{
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);
void process_events();
void levelintro();
- void drawstatus();
+ void drawstatus(DrawingContext& context);
void drawendscreen();
void drawresultscreen(void);
// 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
}
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);
}
}
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);
}
}
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;
}
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 */
#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;
}
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;
}
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);
}
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
#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;
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;
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;
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;
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);
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);
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;
#include <string>
#include <SDL.h>
-#include "text.h"
+#include "screen/font.h"
#include "menu.h"
#include "mousecursor.h"
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;
#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"
Surface* bkgd;
SDL_Event event;
+ DrawingContext context;
bkgd = new Surface(datadir + "/images/highscore/highscore.png", IGNORE_ALPHA);
hs_score = 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)
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);
- }*/
}
// 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);
}
#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"
#include "music_manager.h"
#include "gameobjs.h"
#include "world.h"
+#include "background.h"
#include "lispwriter.h"
using namespace std;
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);
}
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);
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);
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);
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... */
#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;
/** 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
{
class Level
{
- public:
+public:
Surface* img_bkgd;
MusicRef level_song;
MusicRef level_song_fast;
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;
*/
int load(const std::string& filename, World* world);
- void load_gfx();
-
void load_song();
void free_song();
MusicRef get_level_music();
#include <algorithm>
#include "leveleditor.h"
-#include "screen.h"
+#include "screen/screen.h"
#include "defines.h"
#include "globals.h"
#include "setup.h"
#include "resources.h"
#include "music_manager.h"
#include "background.h"
-#include "display_manager.h"
+
+// TODO
+#if 0
/* definitions to aid development */
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);
}
}
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),
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;
object_properties_menu->event(event);
}
- cap_screen->draw(0,0);
+ //cap_screen->draw(0,0);
object_properties_menu->draw();
object_properties_menu->action();
SDL_Delay(25);
}
- delete cap_screen;
+ //delete cap_screen;
Menu::set_current(0);
delete object_properties_menu;
}
le_selection_mode = temp_le_selection_mode;
le_help_shown = false;
}
+
+#endif
#ifndef SUPERTUX_LEVELEDITOR_H
#define SUPERTUX_LEVELEDITOR_H
+#if 0 // TODO
+
struct square
{
int x1, y1, x2, y2;
int le_init(void);
void le_checkevents(void);
+#endif
+
#endif /*SUPERTUX_LEVELEDITOR_H*/
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)
{
/** */
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
+
#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"
/* 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);
dialog->event(event);
}
- cap_screen->draw(0,0);
+ //cap_screen->draw(0,0);
dialog->draw();
dialog->action();
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;
flipscreen();
SDL_Delay(25);
}
-
-
+#endif
+ return false;
}
void
}
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;
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;
{
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:
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);
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;
}
}
/* 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&
#include <SDL.h>
#include <vector>
-#include "texture.h"
+#include "screen/texture.h"
#include "timer.h"
#include "type.h"
#include "mousecursor.h"
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 */
// 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;
mid_y = y;
}
-void MouseCursor::draw()
+void MouseCursor::draw(DrawingContext& context)
{
int x,y,w,h;
Uint8 ispressed = SDL_GetMouseState(&x,&y);
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();
}
#include <string>
#include "timer.h"
-#include "texture.h"
+#include "screen/texture.h"
#define MC_FRAME_PERIOD 800 // in ms
};
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*/
#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()
}
}
-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);
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 {
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);
// 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;
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;
}
}
#define SUPERTUX_PARTICLESYSTEM_H
#include <vector>
-#include "texture.h"
-#include "drawable.h"
+#include "screen/texture.h"
#include "game_object.h"
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
virtual ~Particle()
{ }
- float x, y;
- int layer;
+ Vector pos;
Surface* texture;
};
class SnowParticleSystem : public ParticleSystem
{
public:
- SnowParticleSystem(DisplayManager& displaymanager);
+ SnowParticleSystem();
virtual ~SnowParticleSystem();
virtual void action(float elapsed_time);
class CloudParticleSystem : public ParticleSystem
{
public:
- CloudParticleSystem(DisplayManager& displaymanager);
+ CloudParticleSystem();
virtual ~CloudParticleSystem();
virtual void action(float elapsed_time);
#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
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();
}
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);
{
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
}
void
-Player::draw(Camera& viewport, int layer)
+Player::draw(DrawingContext& context)
{
PlayerSprite* sprite;
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
}
void
-Player::check_bounds(Camera& viewport)
+Player::check_bounds(DrawingContext& viewport)
{
/* Keep tux in bounds: */
if (base.x < 0)
#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: */
extern PlayerSprite firetux;
extern PlayerSprite icetux;
-class Player : public MovingObject, public Drawable
+class Player : public MovingObject
{
public:
enum HurtMode { KILL, SHRINK };
Physic physic;
public:
- Player(DisplayManager& display_manager);
+ Player();
virtual ~Player();
int key_event(SDLKey key, int state);
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);
#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)
+++ /dev/null
-// $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);
-}
-
+++ /dev/null
-// $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*/
--- /dev/null
+#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();
+}
+
--- /dev/null
+#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
+
--- /dev/null
+// $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);
+}
+
--- /dev/null
+// $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*/
+
--- /dev/null
+// $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));
+ }
+}
+
--- /dev/null
+// $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*/
--- /dev/null
+// $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 */
--- /dev/null
+// $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: */
#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"
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;
/* 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);
#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"
#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;
}
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
//---------------------------------------------------------------------------
-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_;
}
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
#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"
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);
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);
#include "globals.h"
#include "sprite.h"
#include "setup.h"
+#include "screen/drawing_context.h"
Sprite::Sprite(lisp_object_t* cur)
{
}
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)
{
if (frame < surfaces.size())
surfaces[frame]->draw_part(sx, sy, x - x_hotspot, y - y_hotspot, w, h);
}
+#endif
void
Sprite::reset()
#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 };
/** 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;
#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[])
if (launch_leveleditor_mode && level_startup_file)
{
- leveleditor(level_startup_file);
+ // TODO
+ // leveleditor(level_startup_file);
}
else if (level_startup_file)
{
title();
}
- clearscreen(0, 0, 0);
- updatescreen();
+ SDL_FillRect(screen, 0, 0);
+ SDL_Flip(screen);
unloadshared();
st_general_free();
+++ /dev/null
-// $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);
-}
-
+++ /dev/null
-// $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*/
-
+++ /dev/null
-// $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 */
+++ /dev/null
-// $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: */
#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)
{
}
}
}
+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()
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)
{
}
else
{
- puts("Unhandled symbol");
+ std::cerr << "Unknown symbol: " <<
+ lisp_symbol(lisp_car(element)) << "\n";
}
cur = lisp_cdr(cur);
}
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);
+ }
+}
#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
*/
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
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;
}
};
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) {
// 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()
}
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);
+}
#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;
};
#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"
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);
}
}
-void draw_background()
-{
- /* Draw the title background: */
-
- bkg_title->draw_bg();
-}
-
void draw_demo(GameSession* session, double frame_ratio)
{
World* world = session->get_world();
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);
/* --- 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
/* 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)
generate_contrib_menu();
break;
case MNID_LEVELEDITOR:
- leveleditor();
+ // TODO
+ //leveleditor();
Menu::set_current(main_menu);
break;
case MNID_CREDITS:
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);
}
}
- 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;
#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"
return Vector(x / s, y / s);
}
+ Vector operator-() const
+ {
+ return Vector(-x, -y);
+ }
+
const Vector& operator +=(const Vector& other)
{
x += other.x;
#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"
#include "resources.h"
#include "gameobjs.h"
#include "camera.h"
-#include "display_manager.h"
#include "background.h"
#include "tilemap.h"
// 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);
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();
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);
}
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);
{
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 != "")
{
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)
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),
{
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
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;
}
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
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);
Level* plevel = get_level();
Tile* tile = gettile(x, y);
- if (tile->brick)
+ if (tile->attributes & Tile::BRICK)
{
if (tile->data > 0)
{
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
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);
#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. */
std::vector<GameObject*> gameobjects;
Camera* camera;
- DisplayManager displaymanager;
+ DrawingContext context;
public:
static World* current()
#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"
}
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;
break;
}
- return Point((int)x, (int)y);
+ return Vector((int)x, (int)y);
}
void
}
void
-Tux::update(float delta)
+Tux::action(float delta)
{
if (!moving)
{
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))
{
}
// 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;
reader.read_int("x", &level.x);
reader.read_int("y", &level.y);
- get_level_title(&level); // get level's title
-
levels.push_back(level);
}
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;
}
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);
}
}
-Point
-WorldMap::get_next_tile(Point pos, Direction direction)
+Vector
+WorldMap::get_next_tile(Vector pos, Direction direction)
{
switch(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);
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);
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);
quit = true;
player_status.reset();
break;
+ }
case GameSession::ES_NONE:
+ assert(false);
// Should never be reached
break;
}
}
else
{
- tux->update(delta);
+ tux->action(delta);
tux->set_direction(input_direction);
}
}
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*
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())
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;
}
}
last_update_time = update_time = st_get_ticks();
+ DrawingContext context;
while(!quit)
{
float delta = ((float)(update_time-last_update_time))/100.0;
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;
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);
}
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);
#include <vector>
#include <string>
+#include "vector.h"
#include "musicref.h"
-#include "screen.h"
+#include "screen/screen.h"
namespace WorldMapNS {
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;
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; }
};
/** */
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();
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);