pingus-cvs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Pingus-CVS] CVS: Games/Pingus/src/gui cursor.cxx,NONE,1.1 cursor.hxx,N


From: grumbel
Subject: [Pingus-CVS] CVS: Games/Pingus/src/gui cursor.cxx,NONE,1.1 cursor.hxx,NONE,1.1 display.cxx,NONE,1.1 display.hxx,NONE,1.1 display_graphic_context.cxx,NONE,1.1 display_graphic_context.hxx,NONE,1.1 game_delta.hxx,NONE,1.1 game_delta_recorder.hxx,NONE,1.1 graphic_context.hxx,NONE,1.1 gui_screen.cxx,NONE,1.1 gui_screen.hxx,NONE,1.1 input_debug_screen.cxx,NONE,1.1 input_debug_screen.hxx,NONE,1.1 screen.cxx,NONE,1.1 screen.hxx,NONE,1.1 screen_manager.cxx,NONE,1.1 screen_manager.hxx,NONE,1.1 screen_manager_impl.hxx,NONE,1.1 screen_ptr.cxx,NONE,1.1 screen_ptr.hxx,NONE,1.1screen_state.hxx,NONE,1.1
Date: 19 Feb 2003 09:51:46 -0000

Update of /usr/local/cvsroot/Games/Pingus/src/gui
In directory dark:/tmp/cvs-serv23090/gui

Added Files:
        cursor.cxx cursor.hxx display.cxx display.hxx 
        display_graphic_context.cxx display_graphic_context.hxx 
        game_delta.hxx game_delta_recorder.hxx graphic_context.hxx 
        gui_screen.cxx gui_screen.hxx input_debug_screen.cxx 
        input_debug_screen.hxx screen.cxx screen.hxx 
        screen_manager.cxx screen_manager.hxx screen_manager_impl.hxx 
        screen_ptr.cxx screen_ptr.hxx screen_state.hxx 
Log Message:
moved a whole bunch of files around


--- NEW FILE: cursor.cxx ---
//  $Id: cursor.cxx,v 1.1 2003/02/19 09:51:44 grumbel Exp $
//
//  Pingus - A free Lemmings clone
//  Copyright (C) 2000 Ingo Ruhnke <address@hidden>
//
//  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 "cursor.hxx"

Cursor::Cursor (std::string ident, std::string datafile)
  : sprite (ident, datafile, 15.0f)
{
  sprite.set_align_center();
}

Cursor::~Cursor ()
{
}

void
Cursor::update (float delta)
{
  sprite.update (delta);
}
  
void 
Cursor::on_event()
{
  //sprite.put_screen (controller->get_pos ());
}

/* EOF */

--- NEW FILE: cursor.hxx ---
//  $Id: cursor.hxx,v 1.1 2003/02/19 09:51:44 grumbel Exp $
// 
//  Pingus - A free Lemmings clone
//  Copyright (C) 2000 Ingo Ruhnke <address@hidden>
//
//  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 HEADER_PINGUS_CURSOR_HXX
#define HEADER_PINGUS_CURSOR_HXX

#include <string>
#include "display.hxx"
#include "../sprite.hxx"

/** A simple mouse cursor class and stupid. We can't use the X11/win32
    nativ mouse cursor because we want also to support non-mouse input
    devices and because we want to support multiple cursors */
class Cursor : public DisplayHook
{
private:
  Sprite sprite;
  
public:
  Cursor (std::string ident, std::string datafile);
  virtual ~Cursor ();
  
  virtual void update (float delta);
  virtual void on_event();
  
private:
  Cursor (const Cursor&);
  Cursor& operator= (const Cursor&);
};

#endif

/* EOF */

--- NEW FILE: display.cxx ---
//  $Id: display.cxx,v 1.1 2003/02/19 09:51:44 grumbel Exp $
//
//  Pingus - A free Lemmings clone
//  Copyright (C) 2000 Ingo Ruhnke <address@hidden>
//
//  This program is free software; you can redistribute it and/or
//  modify it under the terms of the GNU General Public License
//  as published by the Free Software Foundation; either version 2
//  of the License, or (at your option) any later version.
//
//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU General Public License for more details.
//
//  You should have received a copy of the GNU General Public License
//  along with this program; if not, write to the Free Software
//  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

#include <algorithm>
#include <stdio.h>
#include <iostream>
#include <ClanLib/Display/Display/display.h>
#include <ClanLib/Display/Display/mousecursor.h>
#include "../globals.hxx"
#include "display.hxx"

std::list<DisplayHook*> Display::display_hooks;
bool Display::displaying_cursor = false;

DisplayHook::DisplayHook() : is_visible(false)
{
}

void
DisplayHook::toggle_display()
{
  if (is_visible)
    Display::remove_flip_screen_hook(this);
  else
    Display::add_flip_screen_hook(this);
  
  is_visible = !is_visible;
}

void
Display::draw_rect(int x1, int y1, int x2, int y2, float r, float g, float b, 
float a)
{
  CL_Display::draw_line(x1, y1, x2, y1, r, g, b, a);
  CL_Display::draw_line(x1, y2, x2, y2, r, g, b, a);
  CL_Display::draw_line(x1, y1, x1, y2, r, g, b, a);
  CL_Display::draw_line(x2, y1, x2, y2, r, g, b, a);
}

void
Display::show_cursor(bool async)
{
  if (swcursor_enabled)
    CL_MouseCursor::show(async);
}

void 
Display::hide_cursor()
{
  if (swcursor_enabled)
    CL_MouseCursor::hide();
}
 
void
Display::set_cursor(CL_MouseCursorProvider *provider, int frame)
{
  if (swcursor_enabled)
    CL_MouseCursor::set_cursor(provider, frame);
}

bool
Display::cursor_shown()
{
  return displaying_cursor;
}

void
Display::flip_display(bool sync)
{
  for(std::list<DisplayHook*>::iterator i = display_hooks.begin();
      i != display_hooks.end();
      i++)
    {
      (*i)->on_event();
    }
  
  CL_Display::flip_display(sync);
  //CL_Display::put_display (CL_Rect (320, 0, 800, 600));
}

void
Display::add_flip_screen_hook(DisplayHook* hook)
{
  if (std::find(display_hooks.begin(), display_hooks.end(), hook) == 
display_hooks.end())
    display_hooks.push_back(hook);
  else
    std::cout << "Display: Trying to insert a display hook multiple times..." 
<< std::endl;
}

void
Display::remove_flip_screen_hook(DisplayHook* hook)
{
  display_hooks.remove(hook);
}

/* EOF */

--- NEW FILE: display.hxx ---
//  $Id: display.hxx,v 1.1 2003/02/19 09:51:44 grumbel Exp $
// 
//  Pingus - A free Lemmings clone
//  Copyright (C) 2000 Ingo Ruhnke <address@hidden>
//
//  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 HEADER_PINGUS_DISPLAY_HXX
#define HEADER_PINGUS_DISPLAY_HXX

#include "../pingus.hxx"
#include <list>

class DisplayHook;
class CL_MouseCursorProvider;

/** A flip display hook can be used to attach an event to a
    flip_screen(). An example usage for this is a software mouse
    cursor or a frame counter */
class DisplayHook
{
protected:
  bool is_visible;
public:
  DisplayHook();
  virtual ~DisplayHook() {}
  /** Called sortly before a flip_display () */
  virtual void on_event() = 0;
  virtual void toggle_display();
  
private:
  DisplayHook (const DisplayHook&);
  DisplayHook& operator= (const DisplayHook&);
};

/** This is a kind of wrapper class around CL_Display, it provides
    ways to set the cursor and hooks for flip_display() */
class Display
{
private:
  static bool displaying_cursor;
  static std::list<DisplayHook*> display_hooks;
public:
  static void draw_rect(int x1, int y1, int x2, int y2, float r, float g, float 
b, float a);

  static void show_cursor(bool show_async=true);
  static void hide_cursor();
  static void set_cursor(CL_MouseCursorProvider *provider, int frame=0);
  static bool cursor_shown();

  static void flip_display(bool sync=false);

  static void add_flip_screen_hook(DisplayHook*);
  static void remove_flip_screen_hook(DisplayHook*);
  
private:
  Display ();
  Display (const Display&);
  Display& operator= (const Display&);
};

#endif

/* EOF */

--- NEW FILE: display_graphic_context.cxx ---
//  $Id: display_graphic_context.cxx,v 1.1 2003/02/19 09:51:44 grumbel Exp $
//
//  Pingus - A free Lemmings clone
//  Copyright (C) 2002 Ingo Ruhnke <address@hidden>
//
//  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 <ClanLib/Display/Display/display.h>
#include <ClanLib/Display/Font/font.h>
#include <config.h>
#include "display_graphic_context.hxx"
#include "../math.hxx"
#include "../sprite.hxx"

DisplayGraphicContext::DisplayGraphicContext (int x1_, int y1_, int x2_, int 
y2_, 
                                              int /*x_offset*/, int 
/*y_offset*/)
  : x1(x1_), y1(y1_), x2(x2_), y2(y2_), offset(-(x2_ - x1_) / 2.0f, -(y2_ - 
x1_) / 2.0f, 1.0f)
{ 
  center = Vector ((x2 - x1)/2.0f + x1,
                      (y2 - y1)/2.0f + y1);
  std::cout << "View: " << x1 << ", " << y1 << ", " << x2 << ", " << y2 
  << std::endl;
}

DisplayGraphicContext::~DisplayGraphicContext ()
{
}

void
DisplayGraphicContext::set_offset (float x, float y)
{
  offset.x = x;
  offset.y = y;
}

CL_Rect
DisplayGraphicContext::get_clip_rect()
{
  // FIXME: Zooming isn't handled
  // FIXME: This might be of-by-one
  Vector pos = -offset - center;
  return CL_Rect (int(pos.x), int(pos.y),
                  int(pos.x + get_width () + 1), int(pos.y + get_height () + 
1));
}

Vector
DisplayGraphicContext::get_offset ()
{
  return offset;
}

float
DisplayGraphicContext::get_zoom ()
{
  return offset.z;
}

void
DisplayGraphicContext::set_zoom (float new_zoom)
{
  offset.z = new_zoom;
  //std::cout << "Zoom: " << offset.z << std::endl;
}

void 
DisplayGraphicContext::zoom_to (const CL_Rect & arg_rect)
{
  CL_Rect rect;

  rect.x1 = Math::min (arg_rect.x1, arg_rect.x2);
  rect.x2 = Math::max (arg_rect.x1, arg_rect.x2);
  rect.y1 = Math::min (arg_rect.y1, arg_rect.y2);
  rect.y2 = Math::max (arg_rect.y1, arg_rect.y2);
  
  Vector pos1 = screen_to_world (Vector(rect.x1, rect.y1));
  Vector pos2 = screen_to_world (Vector(rect.x2, rect.y2));

  Vector center_ = (pos2 + pos1) * 0.5f;
  offset = -center_;

  float width  = pos2.x - pos1.x;
  float height = pos2.y - pos1.y;

  if (width < 10 && height < 10)
    return ;

  float screen_relation = float(get_width ()) / float(get_height ());
  float rect_reation = width / height;
  
  if (rect_reation > screen_relation)
    {
      set_zoom (get_width () / (pos2.x - pos1.x));
    }
  else
    {
      set_zoom (get_height () / (pos2.y - pos1.y));
    }
}

int 
DisplayGraphicContext::get_width ()
{
  return x2 - x1;
}

int
DisplayGraphicContext::get_height ()
{
  return y2 - y1;
}

void 
DisplayGraphicContext::move (const Vector & delta)
{
  offset += delta;
}

Vector
DisplayGraphicContext::screen_to_world (Vector pos)
{
  return ((pos - center) * (1.0f/offset.z)) - offset;
}

Vector
DisplayGraphicContext::world_to_screen (Vector pos)
{
  return ((pos + offset) * offset.z) + center;
}

float 
DisplayGraphicContext::get_x_offset ()
{
  return offset.x;
}

float 
DisplayGraphicContext::get_y_offset ()
{
  return offset.y;
}

void 
DisplayGraphicContext::draw (Sprite& sprite, const Vector& pos)
{
  Vector tmp_pos = pos;
  sprite.put_screen (tmp_pos + offset + center);
}

void 
DisplayGraphicContext::draw (Sprite& sprite, const Vector& pos, int frame)
{
  CL_Surface sur (sprite.get_surface ());
  draw (sur, 
        (int) pos.x + sprite.get_x_align (),
        (int) pos.y + sprite.get_y_align (), 
        frame);
}

void 
DisplayGraphicContext::draw (CL_Surface& sur, const Vector& pos)
{
  if (offset.z == 1.0)
    {   
      sur.put_screen (int(pos.x + get_x_offset () + center.x),
                      int(pos.y + get_y_offset () + center.y));
    }
  else
    {
      sur.put_screen (int((pos.x + get_x_offset ()) * offset.z + center.x),
                      int((pos.y + get_y_offset ()) * offset.z + center.y),
                      offset.z, offset.z);
    }
  //CL_Display::draw_line (x1, y1, x2, y2, 1.0, 1.0, 0.0);
  //CL_Display::draw_line (x1, y2, x2, y1, 1.0, 1.0, 0.0);
}

void 
DisplayGraphicContext::draw (CL_Surface& sur, const Vector& pos, int frame)
{
  draw (sur, int(pos.x), int(pos.y), frame);
}

void 
DisplayGraphicContext::draw (CL_Surface& sur, int x_pos, int y_pos)
{
  if (offset.z == 1.0)
    {
      sur.put_screen (int(x_pos + get_x_offset () + center.x),
                      int(y_pos + get_y_offset () + center.y));
    }
  else
    {
      sur.put_screen (int((x_pos + get_x_offset ()) * offset.z + center.x),
                      int((y_pos + get_y_offset ()) * offset.z + center.y),
                      offset.z, offset.z);
    }
}

void 
DisplayGraphicContext::draw (CL_Surface& sur, int x_pos, int y_pos, int frame)
{
  if (offset.z == 1.0)
    {
      sur.put_screen (int(x_pos + get_x_offset () + center.x),
                      int(y_pos + get_y_offset () + center.y),
                      frame);  
    }
  else
    {
      sur.put_screen (int((x_pos + get_x_offset ()) * offset.z + center.x),
                      int((y_pos + get_y_offset ()) * offset.z + center.y),
                      offset.z, offset.z,
                      frame);  
    }
}

void 
DisplayGraphicContext::draw (CL_Surface& sur, int x_pos, int y_pos, 
            float size_x, float size_y, int frame)
{
  sur.put_screen (int(x_pos + get_x_offset () + center.x),
                  int(y_pos + get_y_offset () + center.y),
                  size_x * offset.z, 
                  size_y * offset.z, frame); 
}

void 
DisplayGraphicContext::draw_line (const Vector& pos1, const Vector& pos2,
                       float r, float g, float b, float a)
{
  draw_line (int(pos1.x), int(pos1.y), int(pos2.x), int(pos2.y), r, g, b, a);
}

void 
DisplayGraphicContext::draw_line (int x1_, int y1_, int x2_, int y2_, 
                                  float r, float g, float b, float a)
{
  CL_Display::draw_line (static_cast<int>((x1_ + get_x_offset()) * offset.z + 
center.x),
                         static_cast<int>((y1_ + get_y_offset()) * offset.z + 
center.y),
                         static_cast<int>((x2_ + get_x_offset()) * offset.z + 
center.x),
                         static_cast<int>((y2_ + get_y_offset()) * offset.z + 
center.y),
                         r, g, b, a);
}

void 
DisplayGraphicContext::draw_fillrect (int x1_, int y1_, int x2_, int y2_, 
                                      float r, float g, float b, float a)
{
  CL_Display::fill_rect (static_cast<int>((x1_ + get_x_offset()) * offset.z + 
center.x),
                         static_cast<int>((y1_ + get_y_offset()) * offset.z + 
center.y), 
                         static_cast<int>((x2_ + get_x_offset()) * offset.z + 
center.x),
                         static_cast<int>((y2_ + get_y_offset()) * offset.z + 
center.y),
                         r, g, b, a);
}

void 
DisplayGraphicContext::draw_rect (int x1_, int y1_, int x2_, int y2_, 
                 float r, float g, float b, float a)
{
  CL_Display::draw_rect (static_cast<int>((x1_ + get_x_offset()) * offset.z + 
center.x),
                         static_cast<int>((y1_ + get_y_offset()) * offset.z + 
center.y), 
                         static_cast<int>((x2_ + get_x_offset()) * offset.z + 
center.x),
                         static_cast<int>((y2_ + get_y_offset()) * offset.z + 
center.y),
                         r, g, b, a);
}

void 
DisplayGraphicContext::draw_pixel (int /*x_pos*/, int /*y_pos*/, 
                   float /*r*/, float /*g*/, float /*b*/, float /*a*/)
{
  //CL_Display::put_pixel (x1 + get_x_offset (),
  //                     y1 + get_y_offset (), r, g, b, a);
  std::cout << "View::draw_pixel () not implemented" << std::endl;
}

void 
DisplayGraphicContext::draw_circle (int x_pos, int y_pos, int radius,
                                    float r, float g, float b, float a)
{
  // FIXME: Probally not the fast circle draw algo on this world...
  const float pi = 3.1415927f * 2.0f;
  const float steps = 8;
  Vector current (radius, 0);
  Vector next = current.rotate (pi/steps, Vector (0, 0, 1.0f));

  for (int i = 0; i < steps; ++i)
    {
      draw_line (int(x_pos + current.x), int(y_pos + current.y),
                 int(x_pos + next.x), int(y_pos + next.y),
                 r, g, b, a);
      current = next;
      next = next.rotate (pi/8, Vector (0, 0, 1.0f));
    }
}

void
DisplayGraphicContext::print_left (FontHandle font, int x_pos, int y_pos, const 
std::string& str)
{
  font->print_left(int(x_pos + get_x_offset () + center.x),
                   int(y_pos + get_y_offset () + center.y),
                   str.c_str ());
}

void
DisplayGraphicContext::print_center (FontHandle font, int x_pos, int y_pos, 
const std::string& str)
{
  font->print_center(int(x_pos + get_x_offset () + center.x),
                     int(y_pos + get_y_offset () + center.y),
                     str.c_str ());  
}
  
void
DisplayGraphicContext::print_right (FontHandle font, int x_pos, int y_pos, 
const std::string& str)
{
  font->print_right(int(x_pos + get_x_offset () + center.x),
                    int(y_pos + get_y_offset () + center.y),
                    str.c_str ());
}

/* EOF */

--- NEW FILE: display_graphic_context.hxx ---
//  $Id: display_graphic_context.hxx,v 1.1 2003/02/19 09:51:44 grumbel Exp $
// 
//  Pingus - A free Lemmings clone
//  Copyright (C) 2002 Ingo Ruhnke <address@hidden>
//
//  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 HEADER_DISPLAY_GRAPHIC_CONTEXT_HXX
#define HEADER_DISPLAY_GRAPHIC_CONTEXT_HXX

#include "../vector.hxx"
#include <ClanLib/Core/Math/rect.h>

#include "graphic_context.hxx"

/** A GraphicContext which represents the display and allows you to
    paint on it */
class DisplayGraphicContext : public GraphicContext
{
private:
  /** Position of the display on the screen */
  int x1, y1, x2, y2;

  /** scroll offset */
  Vector offset;

  /** center of the display */
  Vector center;

public:
  DisplayGraphicContext (int x1, int y1, int x2, int y2, 
                         int /*x_offset*/, int /*y_offset*/);
  virtual ~DisplayGraphicContext ();
  
  Vector get_offset ();

  float get_x_offset ();
  float get_y_offset ();

  void  set_offset (float x, float y);

  CL_Rect get_clip_rect();

  int   get_width ();
  int   get_height ();

  float get_zoom ();
  void  set_zoom (float new_zoom);

  /** Set the current zoom and offset, so that the given rectangle is
      completly visible on the screen and maximally zoomed. */
  void zoom_to (const CL_Rect & rect);

  /// Scroll the view by the given delta
  void move (const Vector & delta);

  /** Converts a given screen coordinate, as returned by
      CL_Mouse::get_x(), into the world coordinate system. */
  Vector screen_to_world (Vector pos);
  Vector world_to_screen (Vector pos);

  void draw (Sprite& sprite, const Vector& pos);
  void draw (Sprite& sprite, const Vector& pos, int frame);
  void draw (CL_Surface& sur, const Vector& pos);
  void draw (CL_Surface& sur, const Vector& pos, int frame);

  void draw (CL_Surface& sur, int x_pos, int y_pos);
  void draw (CL_Surface& sur, int x_pos, int y_pos, int frame);

  /** Draw a scaled surface */
  void draw (CL_Surface& sur, int x_pos, int y_pos, 
             float size_x, float size_y, int frame);

  /** Draw a line */
  void draw_line (const Vector& pos1, const Vector& pos2,
                  float r, float g, float b, float a = 1.0f);
  /** Draw a line */
  void draw_line (int x1, int y1, int x2, int y2, 
                  float r, float g, float b, float a = 1.0f);

  /** Draw a filled rectangle (FIXME: [x1,x2] or [x1,x2[ ?) */
  void draw_fillrect (int x1, int y1, int x2, int y2, 
                      float r, float g, float b, float a = 1.0f);

  /** Draw an unfilled rectangle (FIXME: [x1,x2] or [x1,x2[ ?) */
  void draw_rect (int x1, int y1, int x2, int y2, 
                  float r, float g, float b, float a = 1.0f);

  /** Draw a singel pixel */
  void draw_pixel (int x_pos, int y_pos, 
                   float r, float g, float b, float a = 1.0f);

  /** Draw a circle */
  void draw_circle (int x_pos, int y_pos, int radius,
                    float r, float g, float b, float a = 1.0f);

  void print_left (FontHandle font, int x_pos, int y_pos, const std::string& 
str);
  
  void print_center (FontHandle font, int x_pos, int y_pos, const std::string& 
str);
  
  void print_right (FontHandle font, int x_pos, int y_pos, const std::string& 
str);

private:
  DisplayGraphicContext (const DisplayGraphicContext&);
  DisplayGraphicContext& operator= (const DisplayGraphicContext&);
};

#endif

/* EOF */

--- NEW FILE: game_delta.hxx ---
//  $Id: game_delta.hxx,v 1.1 2003/02/19 09:51:44 grumbel Exp $
// 
//  Pingus - A free Lemmings clone
//  Copyright (C) 2000 Ingo Ruhnke <address@hidden>
//
//  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 HEADER_PINGUS_GAME_DELTA_HXX
#define HEADER_PINGUS_GAME_DELTA_HXX

#include <list>
#include "../delta_manager.hxx"
#include "../input/event_fwd.hxx"

/** Input for the game engine */
class GameDelta
{
private:
  /** time delta since the last update */
  const float time_delta;

  const unsigned int absolute_time;
    
  /** Reference to the event list from the controller, we must not
      delete the Event* */
  const Input::EventLst& events; 
    
public:
  /** Construct a GameDelta with both time and events */
  GameDelta (float time_delta_arg,
             unsigned int absolute_time_arg,
             const Input::EventLst& e)
    : time_delta (time_delta_arg),
      absolute_time (absolute_time_arg),
      events (e) {}

  /** Return the time that has passed in seconds since the last update() */
  float get_time () const { return time_delta; }

  /** @return the time since the application startup in miliseconds
      (1/1000 second) */
  unsigned int get_absolute_time () const { return absolute_time; }

  /** Return the events */
  const Input::EventLst& get_events () const { return events; }
  
private:
  GameDelta (const GameDelta&);
  GameDelta& operator= (const GameDelta&);
};

#endif

/* EOF */

--- NEW FILE: game_delta_recorder.hxx ---
//  $Id: game_delta_recorder.hxx,v 1.1 2003/02/19 09:51:44 grumbel Exp $
// 
//  Pingus - A free Lemmings clone
//  Copyright (C) 2000 Ingo Ruhnke <address@hidden>
//
//  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 HEADER_PINGUS_GAME_DELTA_RECORDER_HXX
#define HEADER_PINGUS_GAME_DELTA_RECORDER_HXX

class GameDeltaRecorder
{
private:
  
public:
  GameDeltaRecorder ();
  GameDelta* get ();
};

#endif

/* EOF */

--- NEW FILE: graphic_context.hxx ---
//  $Id: graphic_context.hxx,v 1.1 2003/02/19 09:51:44 grumbel Exp $
// 
//  Pingus - A free Lemmings clone
//  Copyright (C) 2002 Ingo Ruhnke <address@hidden>
//
//  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 HEADER_PINGUS_GRAPHIC_CONTEXT_HXX
#define HEADER_PINGUS_GRAPHIC_CONTEXT_HXX

#include <string>
#include "../vector.hxx"
#include <ClanLib/Core/Math/rect.h>

class Sprite;
class CL_Surface;
class CL_Font;

typedef CL_Font* FontHandle;

/** Abstract interface */
class GraphicContext
{
private:
public:
  virtual Vector get_offset () =0;

  /** Return the rectandle which represents the visible part of the
      world, so that objects outsite it can be cliped away easily */
  virtual CL_Rect get_clip_rect () =0;

  virtual float get_x_offset () =0;
  virtual float get_y_offset () =0;

  virtual int   get_width ()  =0;
  virtual int   get_height () =0;

  virtual float get_zoom () =0;
  virtual void  set_zoom (float new_zoom) =0;

  /** Set the current zoom and offset, so that the given rectangle is
      completly visible on the screen and maximally zoomed. */
  virtual void zoom_to (const CL_Rect & rect) =0;

  /// Scroll the view by the given delta
  virtual void move (const Vector & delta) =0;

  /** Converts a given screen coordinate, as returned by
      CL_Mouse::get_x(), into the world coordinate system. */
  virtual Vector screen_to_world (Vector pos) =0;
  virtual Vector world_to_screen (Vector pos) =0;

  virtual void draw (Sprite& sprite, const Vector& pos) =0;
  virtual void draw (Sprite& sprite, const Vector& pos, int frame) =0;
  virtual void draw (CL_Surface& sur, const Vector& pos) =0;
  virtual void draw (CL_Surface& sur, const Vector& pos, int frame) =0;

  virtual void draw (CL_Surface& sur, int x_pos, int y_pos) =0;
  virtual void draw (CL_Surface& sur, int x_pos, int y_pos, int frame) =0;

  /** Draw a scaled surface */
  virtual void draw (CL_Surface& sur, int x_pos, int y_pos, 
                     float size_x, float size_y, int frame) =0;

  /** Draw a line */
  virtual void draw_line (const Vector& pos1, const Vector& pos2,
                          float r, float g, float b, float a = 1.0f) =0;
  /** Draw a line */
  virtual void draw_line (int x1, int y1, int x2, int y2, 
                          float r, float g, float b, float a = 1.0f) =0;

  /** Draw a filled rectangle (FIXME: [x1,x2] or [x1,x2[ ?) */
  virtual void draw_fillrect (int x1, int y1, int x2, int y2, 
                              float r, float g, float b, float a = 1.0f) =0;

  /** Draw an unfilled rectangle (FIXME: [x1,x2] or [x1,x2[ ?) */
  virtual void draw_rect (int x1, int y1, int x2, int y2, 
                          float r, float g, float b, float a = 1.0f) =0;

  /** Draw a singel pixel */
  virtual void draw_pixel (int x_pos, int y_pos, 
                           float r, float g, float b, float a = 1.0f) =0;

  /** Draw a circle */
  virtual void draw_circle (int x_pos, int y_pos, int radius,
                            float r, float g, float b, float a = 1.0f) =0;

  // Font handling routines
  /** Print a text left aligned */
  virtual void print_left (FontHandle font, int x_pos, int y_pos, const 
std::string& str) =0;

  /** Print a text centred to the given position */
  virtual void print_center (FontHandle font, int x_pos, int y_pos, const 
std::string& str) =0;
  
  /** Print a text right aligned */
  virtual void print_right (FontHandle font, int x_pos, int y_pos, const 
std::string& str) =0;
};

#endif

/* EOF */

--- NEW FILE: gui_screen.cxx ---
//  $Id: gui_screen.cxx,v 1.1 2003/02/19 09:51:44 grumbel Exp $
//
//  Pingus - A free Lemmings clone
//  Copyright (C) 2000 Ingo Ruhnke <address@hidden>
//
//  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 "../globals.hxx"
#include "../debug.hxx"
#include "gui_screen.hxx"
#include "gui_manager.hxx"

using namespace GUI;

GUIScreen::GUIScreen ()
  : gui_manager (new GUIManager ())
{
}

GUIScreen::~GUIScreen ()
{
  delete gui_manager;
}

/** Draw this screen */
bool
GUIScreen::draw (GraphicContext& gc)
{
  draw_background (gc);
  gui_manager->draw (gc);
  draw_foreground (gc);
  return true;
}

  /** Pass a delta to the screen */
void
GUIScreen::update (const GameDelta& delta)
{
  // Dispatch the recieved input events
  gui_manager->update (delta);

  update (delta.get_time ());

  for (Input::EventLst::const_iterator i = delta.get_events ().begin (); 
       i != delta.get_events ().end (); ++i)
    {
      switch (i->type)
        {
        case Input::PointerEventType:
          {
            // ignored cause this is handled in the gui_manager
          }
          break;

        case Input::ButtonEventType:
          {
            process_button_event (i->button);
          }
          break;

        case Input::AxisEventType:
          {
            if (i->axis.name == Input::action)
              {
                on_action_axis_move (i->axis.dir);
              }
          }
          break;

        case Input::ScrollEventType:
          {
            
          }
          break;

        default:
          std::cout << "GUIScreen::update (): unhandled event type: " << 
i->type << std::endl;
          break;
        }
    }
}

void
GUIScreen::process_button_event (const Input::ButtonEvent& event)
{
  //std::cout << "GUIScreen::process_button_event (Input::ButtonEvent* event)" 
<< std::endl;

  if (event.state == Input::pressed) 
    {
      switch (event.name)
        {
        case Input::primary:
          // ignoring, handled in the gui_manager
          break; 
        case Input::secondary:
          // ignoring, handled in the gui_manager
          break;
        case Input::pause:
          on_pause_press ();
          break;
        case Input::fast_forward:
          on_fast_forward_press ();
          break;
        case Input::armageddon:
          on_armageddon_press ();
          break;
        case Input::escape:
          on_escape_press ();
          break;
        default:
          perr(PINGUS_DEBUG_GUI) << "GUIScreen: ButtonEvent: unhandled event: " 
<< event.name << std::endl;
          break;
        }
    }
  else if (event.state == Input::released) 
    {
      switch (event.name)
        {
        case Input::primary:
          // ignoring, handled in the gui_manager
          break; 
        case Input::secondary:
          // ignoring, handled in the gui_manager
          break;
        case Input::pause:
          on_pause_release ();
          break;
        case Input::fast_forward:
          on_fast_forward_release ();
          break;
        case Input::armageddon:
          on_armageddon_release ();
          break;
        case Input::escape:
          on_escape_release ();
          break;
        default:
          perr(PINGUS_DEBUG_GUI) << "GUIScreen: ButtonEvent: unhandled event: " 
<< event.name << std::endl;
          break;
        }
    }
  else
    {
      perr(PINGUS_DEBUG_GUI) << "GUIScreen::process_button_event: got unknown 
event.state: " 
                             << event.state << std::endl;;
    }
}

/* EOF */

--- NEW FILE: gui_screen.hxx ---
//  $Id: gui_screen.hxx,v 1.1 2003/02/19 09:51:44 grumbel Exp $
// 
//  Pingus - A free Lemmings clone
//  Copyright (C) 2000 Ingo Ruhnke <address@hidden>
//
//  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 HEADER_PINGUS_GUISCREEN_HXX
#define HEADER_PINGUS_GUISCREEN_HXX

#include "screen.hxx"

namespace GUI
{
  class GUIManager;
}

namespace Input
{
  struct ButtonEvent;
}

class GUIScreen : public Screen
{
protected:
  GUI::GUIManager* gui_manager;

public:
  GUIScreen ();
  virtual ~GUIScreen ();

  /** Draw this screen */
  virtual void draw_foreground (GraphicContext& gc) { UNUSED_ARG(gc); }
  virtual void draw_background (GraphicContext& gc) { UNUSED_ARG(gc); }
  virtual bool draw (GraphicContext& gc);

  /** Pass a game delta to the screen */
  virtual void update (const GameDelta& delta);

  /** */
  virtual void update (float) {}

  virtual void on_pause_press () {}
  virtual void on_fast_forward_press () {}
  virtual void on_armageddon_press () {}
  virtual void on_escape_press () {}

  virtual void on_pause_release () {}
  virtual void on_fast_forward_release () {}
  virtual void on_armageddon_release () {}
  virtual void on_escape_release () {}

  virtual void on_action_axis_move (float) {}

private:
  void process_button_event (const Input::ButtonEvent& event);
  
  GUIScreen (const GUIScreen&);
  GUIScreen& operator= (const GUIScreen&);
};

#endif

/* EOF */

--- NEW FILE: input_debug_screen.cxx ---
//  $Id: input_debug_screen.cxx,v 1.1 2003/02/19 09:51:44 grumbel Exp $
//
//  Pingus - A free Lemmings clone
//  Copyright (C) 2000 Ingo Ruhnke <address@hidden>
//
//  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 "../input/event.hxx"
//#include "input/scroll_event.hxx"
#include "input_debug_screen.hxx"

using namespace Input;

InputDebugScreen::InputDebugScreen ()
{
}

InputDebugScreen::~InputDebugScreen ()
{
}

/** Draw this screen */
bool
InputDebugScreen::draw (GraphicContext& gc)
{
  std::cout << "InputDebugScreen::draw ()" << std::endl;
  CL_System::sleep(100);
  UNUSED_ARG(gc);
  return true;
}

/** Pass a delta to the screen */
void
InputDebugScreen::update (const GameDelta& delta)
{
  std::cout << "InputDebugScreen::update (" << delta.get_time () << ")" << 
std::endl;
  for (Input::EventLst::const_iterator i = delta.get_events ().begin (); 
       i != delta.get_events ().end ();
       ++i)
    {
      switch(i->type)
        {
        case ButtonEventType:
          std::cout << "InputDebugScreen: Button event : " << i->type << 
std::endl;
          break;

        case PointerEventType:
          std::cout << "InputDebugScreen: Pointer event : " << i->type << 
std::endl;
          break;

        case AxisEventType:
          std::cout << "InputDebugScreen: Axis event : " << i->type << 
std::endl;

          break;
        case ScrollEventType:
          { 
            std::cout << "InputDebugScreen: Scroll event : " 
                      << i->scroll.x_delta << " " << i->scroll.y_delta << 
std::endl;
          }
          break;

        default:
          std::cout << "InputDebugScreen: Unknown event : " << i->type << 
std::endl;
          break;
        }
    }
}

/** Called once the screen gets activated and becomes the current
    screen */
void
InputDebugScreen::on_startup ()
{
  std::cout << "InputDebugScreen::on_startup ()" << std::endl;
}

/** Called once the screen gets replaced or poped or shadowed by a
    newly pushed screen */ 
void
InputDebugScreen::on_shutdown ()
{
  std::cout << "InputDebugScreen::on_shutdown ()" << std::endl;
}

/* EOF */

--- NEW FILE: input_debug_screen.hxx ---
//  $Id: input_debug_screen.hxx,v 1.1 2003/02/19 09:51:44 grumbel Exp $
// 
//  Pingus - A free Lemmings clone
//  Copyright (C) 2000 Ingo Ruhnke <address@hidden>
//
//  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 HEADER_PINGUS_INPUT_DEBUG_SCREEN_HXX
#define HEADER_PINGUS_INPUT_DEBUG_SCREEN_HXX

#include "screen.hxx"

class InputDebugScreen : public Screen
{
private:
  
public:
  InputDebugScreen ();
  virtual ~InputDebugScreen ();

  /** Draw this screen */
  bool draw (GraphicContext& gc);

  /** Pass a delta to the screen */
  void update (const GameDelta& delta);

  /** Called once the screen gets activated and becomes the current
      screen */
  void on_startup ();

  /** Called once the screen gets replaced or poped or shadowed by a
      newly pushed screen */ 
  void on_shutdown ();
};

#endif

/* EOF */

--- NEW FILE: screen.cxx ---
//  $Id: screen.cxx,v 1.1 2003/02/19 09:51:44 grumbel Exp $
//
//  Pingus - A free Lemmings clone
//  Copyright (C) 2000 Ingo Ruhnke <address@hidden>
//
//  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 "screen.hxx"

/* EOF */

--- NEW FILE: screen.hxx ---
//  $Id: screen.hxx,v 1.1 2003/02/19 09:51:44 grumbel Exp $
// 
//  Pingus - A free Lemmings clone
//  Copyright (C) 2000 Ingo Ruhnke <address@hidden>
//
//  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 HEADER_PINGUS_SCREEN_HXX
#define HEADER_PINGUS_SCREEN_HXX

#include "game_delta.hxx"

class GraphicContext;

/** A interface for screens. A screen is a Pingus 'thing' which gets
    complete controll over the display and input. Examples of
    screens are the PingusMenu or a PingusGameSession */
class Screen
{
private:
    
public:
  Screen () { }
  virtual ~Screen () {}
  
  /** Draw this screen @return true if draw was successfull, false if
      frameskip has taken place ('causes a skip of flip_display) */
  virtual bool draw (GraphicContext& gc) =0;

  /** Pass a delta to the screen */
  virtual void update (const GameDelta& delta) =0;

  virtual unsigned int time_till_next_update() { return 0; }

  /** Called once the screen gets activated and becomes the current
      screen */
  virtual void on_startup () {}

  /** Called once the screen gets replaced or poped or shadowed by a
      newly pushed screen */ 
  virtual void on_shutdown () {}
  
private:
  Screen (const Screen&);
  Screen& operator= (const Screen&);
};

#endif

/* EOF */

--- NEW FILE: screen_manager.cxx ---
//  $Id: screen_manager.cxx,v 1.1 2003/02/19 09:51:44 grumbel Exp $
//
//  Pingus - A free Lemmings clone
//  Copyright (C) 2000 Ingo Ruhnke <address@hidden>
//
//  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 <ClanLib/Display/Display/display.h>

#include "display.hxx"
#include "screen_manager.hxx"
#include "../fade_out.hxx"
#include "../path_manager.hxx"
#include "../input/controller.hxx"

ScreenManager* ScreenManager::instance_ = 0;

ScreenManager::ScreenManager ()
  : display_gc (0, 0, CL_Display::get_width (), CL_Display::get_height (), 0, 0)
{
  cached_action = none;
}

ScreenManager::~ScreenManager ()
{
}

void
ScreenManager::display ()
{
  Input::Controller input_controller(path_manager.complete 
("controller/default.xml"));
  DeltaManager delta_manager;

  // Main loop for the menu
  while (!screens.empty())
    {
      float time_delta = delta_manager.getset ();

      if (time_delta > 1.0)
        {
          std::cout << "ScreenManager: detected large delta (" << 
delta_manager.get()
                    << "), ignoring and doing frameskip" << std::endl;
          continue;
        }

      // Let ClanLib fetch events
      CL_System::keep_alive ();

      // Get new events from ClanLib
      input_controller.update (time_delta);

      // Fill the delta with values
      GameDelta delta (time_delta, delta_manager.get_absolute(), 
                       input_controller.get_events ());

      last_screen = get_current_screen();

      // Most likly the screen will get changed in this update call
      get_current_screen()->update (delta);    

      // Last screen has poped, so we are going to end here
      if (screens.empty ())
        continue;

      if (cached_action == pop)
        {
          real_pop_screen ();
          cached_action = none;
        }
      else if (cached_action == replace)
        {
          real_replace_screen (replace_screen_arg);
          cached_action = none;
        }

      // FIXME: is there a more gentel way to do that instead of spreading the 
checks all around here?
      // Last screen has poped, so we are going to end here
      if (screens.empty ())
        continue;
      
      // skip draw if the screen changed to avoid glitches
      if (last_screen == get_current_screen())
        {
          if (get_current_screen()->draw (display_gc))
            Display::flip_display ();

          //CL_Display::put_display(CL_Rect(0, 0, 100, 100));
        }
      else
        {
          std::cout << "ScreenManager: fading screens" << std::endl;
          //fade_over (last_screen, get_current_screen());
        }

      // Stupid hack to make this thing take less CPU
      CL_System::sleep (0);

      /** Delete all screens that are no longer needed */
      delete_screens.clear();
    } 
}

ScreenPtr
ScreenManager::get_current_screen()
{
  assert(!screens.empty());
  return screens.back ();
}

ScreenManager*
ScreenManager::instance ()
{
  if (instance_)
    return instance_;
  else
    return instance_ = new ScreenManager ();
}

void
ScreenManager::push_screen (Screen* screen, bool delete_screen)
{
  std::cout << "XXXXXXXX ScreenManager::push_screen" << std::endl;

  if (!screens.empty())
    {
      std::cout << "ScreenManager::push_screen" << std::endl;
      screens.back ()->on_shutdown ();
    }

  screen->on_startup ();
  screens.push_back (ScreenPtr(screen, delete_screen));
}

void
ScreenManager::pop_screen ()
{
  assert (cached_action == none);
  cached_action = pop;
}

void
ScreenManager::replace_screen (Screen* screen, bool delete_screen)
{
  assert (cached_action == none);
  cached_action = replace;
  replace_screen_arg = ScreenPtr(screen, delete_screen);
}

void
ScreenManager::real_replace_screen (const ScreenPtr& ptr)
{
  std::cout << "XXXXXXXX ScreenManager::replace_screen" << std::endl;

  screens.back ()->on_shutdown ();

  delete_screens.push_back(screens.back ());
  
  screens.back () = ptr;
  screens.back ()->on_startup ();
}

void
ScreenManager::real_pop_screen ()
{
  std::cout << "XXXXXXXX ScreenManager::pop_screen" << std::endl;

  screens.back ()->on_shutdown ();

  delete_screens.push_back(screens.back ());
  
  std::cout << "ScreenManager::real_pop_screen ()" << std::endl;
  screens.pop_back ();

  if (!screens.empty ())
    {
      screens.back ()->on_startup ();
    }
}

void
ScreenManager::fade_out()
{
  FadeOut::black_rect();
}

void
ScreenManager::fade_over (const ScreenPtr& old_screen, const ScreenPtr& 
new_screen)
{
  FadeOut::fade_to_black();
  UNUSED_ARG(old_screen);
  UNUSED_ARG(new_screen);

#if 0
  DeltaManager delta_manager;
  float passed_time = 0;


  std::list<Input::Event*> events;
  while (passed_time < 2.0f)
    {
      float time_delta = delta_manager.getset ();
      passed_time += time_delta;

      int border_x = int((CL_Display::get_width ()/2) * passed_time/2.0f);
      int border_y = int((CL_Display::get_height ()/2) * passed_time/2.0f);

      //std::cout << "FadeOver: " << border_x << " " << border_y << std::endl;

      new_screen->draw (display_gc);

      CL_Display::push_clip_rect(CL_ClipRect (0 + border_x, 
                                              0 + border_y,
                                              CL_Display::get_width () - 
border_x,
                                              CL_Display::get_height () - 
border_y));
      old_screen->draw (display_gc);

      GameDelta delta (time_delta, events);
      new_screen->update (delta);
      old_screen->update (delta);

      CL_Display::pop_clip_rect ();

      Display::flip_display ();
      CL_System::keep_alive ();
    }
#endif 
}

void
ScreenManager::init()
{
  instance_ = 0;
}

void
ScreenManager::deinit()
{
  delete instance_;
}

/* EOF */

--- NEW FILE: screen_manager.hxx ---
//  $Id: screen_manager.hxx,v 1.1 2003/02/19 09:51:44 grumbel Exp $
// 
//  Pingus - A free Lemmings clone
//  Copyright (C) 2000 Ingo Ruhnke <address@hidden>
//
//  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 HEADER_PINGUS_SCREEN_MANAGER_HXX
#define HEADER_PINGUS_SCREEN_MANAGER_HXX

#include "../pingus.hxx"
#include <vector>

#include "screen_ptr.hxx"
#include "display_graphic_context.hxx"

class Screen;

class ScreenManager
{
private:
  static ScreenManager* instance_;

  DisplayGraphicContext display_gc;

  /** Screen stack (first is the screen, second is delete_screen,
      which tells if the screen should be deleted onces it got poped
      or replaced) */
  std::vector<ScreenPtr> screens;

  /** Screens in this vector will be deleted at the end of the
      main-loop. Its really more a keep alive vector, than a deleting
      one, but well... */
  std::vector<ScreenPtr> delete_screens;

  /** the screen that was used in the last update() */
  ScreenPtr last_screen;

  enum { none, pop, replace } cached_action;
  ScreenPtr replace_screen_arg;

protected:
  ScreenManager ();
public:
  ~ScreenManager ();

  /** Start the screen manager and let it take control, this will
      not return until the somebody signals a quit() */
  void display ();

  /** Replace the current screen */
  void replace_screen (Screen*, bool delete_screen = false);
    
  /** Add a screen on top of another screen */
  void push_screen (Screen*, bool delete_screen = false);

  /** Remove the current screen and fall back to the last one */
  void pop_screen ();

  /** Fade the screen out, this call blocks till the screen is black */
  void fade_out();

private:
  /** Replace the current screen */
  void real_replace_screen (const ScreenPtr&);
    
  /** Remove the current screen and fall back to the last one */
  void real_pop_screen ();

  /** FadeOver test*/
  void fade_over (const ScreenPtr& old_screen, const ScreenPtr& new_screen);

  /** @return a pointer to the current Screen */
  ScreenPtr get_current_screen();

public:  
  static ScreenManager* instance ();
  static void init();
  static void deinit();
private:
  ScreenManager (const ScreenManager&);
  ScreenManager& operator= (const ScreenManager&);
};

#endif

/* EOF */

--- NEW FILE: screen_manager_impl.hxx ---
//  $Id: screen_manager_impl.hxx,v 1.1 2003/02/19 09:51:44 grumbel Exp $
// 
//  Pingus - A free Lemmings clone
//  Copyright (C) 2000 Ingo Ruhnke <address@hidden>
//
//  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 HEADER_PINGUS_SCREEN_MANAGER_IMPL_HXX
#define HEADER_PINGUS_SCREEN_MANAGER_IMPL_HXX

#include "pingus.hxx"

class ScreenManagerImpl
{
private:
  typedef enum { PINGUSMAIN_MENU } States;
public:
  ScreenManagerImpl ();
  ~ScreenManagerImpl ();

  void display ();
  
private:
  ScreenManagerImpl (const ScreenManagerImpl&);
  ScreenManagerImpl& operator= (const ScreenManagerImpl&);
};

#endif

/* EOF */

--- NEW FILE: screen_ptr.cxx ---
//  $Id: screen_ptr.cxx,v 1.1 2003/02/19 09:51:44 grumbel Exp $
//
//  Pingus - A free Lemmings clone
//  Copyright (C) 2002 Ingo Ruhnke <address@hidden>
//
//  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 <typeinfo>
#include <iostream>
#include "screen_ptr.hxx"

void
ScreenPtr::decrease_refcount() 
{
  //std::cout << "ScreenPtr::decrease_refcount(): " << screen << std::endl;

  if (delete_it)
    {
      //std::cout << "*ref_count: " << *ref_count << std::endl;

      *ref_count -= 1;
        
      if (*ref_count == 0)
        {
          std::cout << "XXXXXXXXXXXXXX ScreenPtr: deleting: " 
                    << screen << " = " << typeid(*screen).name() << std::endl;
          delete screen;
          delete ref_count;
        }
    }
}

void
ScreenPtr::increase_refcount()
{
  //std::cout << "ScreenPtr::increase_refcount(): " << screen << std::endl;

  if (delete_it)
    {
      //std::cout << "*ref_count: " << *ref_count << std::endl;
      *ref_count += 1;
    }    
}

/* EOF */

--- NEW FILE: screen_ptr.hxx ---
//  $Id: screen_ptr.hxx,v 1.1 2003/02/19 09:51:44 grumbel Exp $
// 
//  Pingus - A free Lemmings clone
//  Copyright (C) 2002 Ingo Ruhnke <address@hidden>
//
//  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 HEADER_PINGUS_SCREEN_PTR_HXX
#define HEADER_PINGUS_SCREEN_PTR_HXX

#include "screen.hxx"

/** The ScreenPtr is a simple smart pointer to point at a Screen. It
    either deletes the pointer or not, depending on the value of
    delete_it */
class ScreenPtr
{
private:
  Screen* screen;
  bool    delete_it;
  long*   ref_count;

public:
  ScreenPtr() 
    : screen(0), delete_it(false), ref_count(0)
  {
  }

  ScreenPtr(Screen* arg_screen, bool arg_delete_it)
    : screen(arg_screen), delete_it(arg_delete_it)
  {
    if (delete_it)
      {
        ref_count = new long;
        *ref_count = 1;
      }
    else
      {
        ref_count = 0;
      }
  }

  ScreenPtr (const ScreenPtr& ptr)
    : screen(ptr.screen), delete_it(ptr.delete_it), ref_count(ptr.ref_count)
  {
    increase_refcount();
  }

  bool operator==(const ScreenPtr& ptr)
  {
    return screen == ptr.screen;
  }

  ScreenPtr& operator= (const ScreenPtr& ptr)
  {
    if (this != &ptr)
      {
        decrease_refcount();
        
        screen    = ptr.screen;
        delete_it = ptr.delete_it;
        ref_count = ptr.ref_count;
        
        increase_refcount();
      }
    return *this;
  }

  ~ScreenPtr()
  {
    decrease_refcount();
  }

  Screen* operator->()
  {
    return screen;
  }

  const Screen& operator*()
  {
    return *screen;
  }

  Screen* get()
  {
    return screen;
  }  

private:
  void decrease_refcount();
  void increase_refcount();
};

#endif

/* EOF */

--- NEW FILE: screen_state.hxx ---
//  $Id: screen_state.hxx,v 1.1 2003/02/19 09:51:44 grumbel Exp $
// 
//  Pingus - A free Lemmings clone
//  Copyright (C) 2000 Ingo Ruhnke <address@hidden>
//
//  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 HEADER_PINGUS_SCREEN_STATE_HXX
#define HEADER_PINGUS_SCREEN_STATE_HXX

#error "Not yet usable, might be removed soon"

class ScreenState
{
private:

public:
  enum State {
    first_intro, 
    main_menu, 
    contrib,
    contrib_game,
    story,
    worldmap,
    worldmap_game,
  };

  enum ScreenHandle { intro, story, menu, contrib, game, worldmap };

  State state;
};

#endif

/* EOF */





reply via email to

[Prev in Thread] Current Thread [Next in Thread]