start working out the Graphics/* code, this is a long way from compiling, let alone working
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Graphics/Console.cc Wed Jan 21 01:57:24 2009 +0200
@@ -0,0 +1,23 @@
+
+#include "Console.hh"
+
+namespace graphics
+{
+
+Console::Console (const CL_Rect& pos, CL_Component* parent) :
+ CL_Component(pos, parent),
+ messages(), input(getInputPosition(), this)
+{
+ // hide by default
+ show(false);
+
+}
+
+CL_Rect Console::getInputPosition (void) {
+ CL_Rect pos = get_position();
+
+ return CL_Rect(pos.left, pos.bottom - 30, pos.right, pos.bottom);
+}
+
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Graphics/Console.hh Wed Jan 21 01:57:24 2009 +0200
@@ -0,0 +1,33 @@
+#ifndef GRAPHICS_CONSOLE_HH
+#define GRAPHICS_CONSOLE_HH
+
+#include <ClanLib/gui.h>
+#include <list>
+
+namespace graphics
+{
+
+class Console : public CL_Component {
+protected:
+ /** our list of messages */
+ std::list<std::string> messages;
+
+ /** our input dialog */
+ CL_InputBox input;
+
+public:
+ /**
+ * Construct a new console, positioned in the given area, with the given parent
+ */
+ Console (const CL_Rect& pos, CL_Component* parent);
+
+private:
+ /**
+ * Calculate the position for the input box
+ */
+ CL_Rect getInputPosition (void);
+};
+
+}
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Graphics/Display.cc Wed Jan 21 01:57:24 2009 +0200
@@ -0,0 +1,30 @@
+
+#include "Display.hh"
+
+namespace graphics
+{
+
+const std::vector<CL_DisplayMode> & Graphics::getDisplayModes (void) {
+ return CL_DisplayMode::get_display_modes();
+}
+
+const CL_DisplayMode Graphics::getBestMode (void) {
+ const std::vector<CL_DisplayMode> &modes = Graphics::getDisplayModes();
+
+ const CL_DisplayMode *best_mode = NULL;
+
+ for (std::vector<CL_DisplayMode>::const_iterator it = modes.begin(); it != modes.end(); it++)
+ if (best_mode == NULL || (
+ it->get_resolution().width * it->get_resolution().height >
+ best_mode->get_resolution().width * best_mode->get_resolution().height
+ ))
+ best_mode = &*it;
+
+ if (best_mode == NULL)
+ throw Error("No available video modes!");
+
+ return *best_mode;
+}
+
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Graphics/Display.hh Wed Jan 21 01:57:24 2009 +0200
@@ -0,0 +1,92 @@
+#ifndef GRAPHICS_DISPLAY_HH
+#define GRAPHICS_DISPLAY_HH
+
+#include "../Types.hh"
+#include "../Config.hh"
+#include "../Timer.hh"
+
+#include <ClanLib/display.h>
+
+namespace graphics
+{
+
+struct DisplayConfig {
+ /** Display resolution */
+ PixelDimensions resolution;
+
+ /** Fullscreen mode? */
+ bool fullscreen;
+};
+
+/**
+ * We wrap ClanLib's DisplayWindow for our own functionality. This is the core of the graphics code
+ */
+class Display : public CL_DisplayWindow {
+private:
+ /**
+ * Our engine reference
+ */
+ Engine &engine;
+
+ /**
+ * Our configuration
+ */
+ DisplayConfig config;
+
+ /**
+ * Our timer that drives redraws
+ */
+ Timer update_timer;
+
+ CL_SlotContainer slots;
+
+public:
+ /**
+ * Construct default display, empty window unless otherwise build
+ */
+ Display (Engine &engine, const DisplayConfig &config) :
+ engine(engine), config(config), update_timer(GRAPHICS_UPDATE_INTERVAL_MS)
+ {
+ // connect timer signal
+ slots.connect(update_timer.sig_tick(), this, &Display::on_update);
+ slots.connect(this->sig_resize(), this, &Display::on_window_resize);
+
+ }
+
+ /**
+ * Returns a vector of CL_DisplayModes that lists possible display modes to use for fullscreen mode.
+ */
+ static const std::vector<CL_DisplayMode> & getDisplayModes (void);
+
+ /**
+ * Returns the "best" CL_DisplayMode to use for fullscreen mode.
+ *
+ * Currently, this just means the largest resolution.
+ */
+ static const CL_DisplayMode getBestMode (void);
+
+ /**
+ * Get current resolution
+ *
+ * XXX: should be PixelDimensions...
+ */
+ PixelCoordinate getResolution (void) {
+ return PixelCoordinate(get_width(), get_height());
+ }
+
+private:
+ /**
+ * Draw next frame
+ */
+ void on_update (TimeMS dt);
+
+ /**
+ * Handles window resize. This just updates resolution
+ */
+ void on_window_resize (int new_x, int new_y);
+
+};
+
+}
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Graphics/Drawable.hh Wed Jan 21 01:57:24 2009 +0200
@@ -0,0 +1,23 @@
+#ifndef GRAPHICS_DRAWABLE_HH
+#define GRAPHICS_DRAWABLE_HH
+
+#include "Display.hh"
+
+namespace graphics
+{
+
+/**
+ * Abstract interface class to define something that's drawable
+ */
+class Drawable {
+public:
+ /**
+ * Draw graphics onto the given display
+ */
+ virtual void draw (Display *display) = 0;
+}
+
+}
+
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Graphics/GUI.hh Wed Jan 21 01:57:24 2009 +0200
@@ -0,0 +1,31 @@
+#ifndef GRAPHICS_GUI_HH
+#define GRAPHICS_GUI_HH
+
+#include "GUIStyle.hh"
+
+#include <ClanLib/gui.h>
+
+
+namespace Graphics
+{
+
+/**
+ * Our CL_GUIManager, for when we use ClanLib's GUI stuff
+ */
+class GUI : public CL_GUIManager {
+public:
+ /**
+ * Construct default manager
+ */
+ GUI (CL_ResourceManager *resources) :
+ CL_GUIManager(new GUIStyle(resources))
+ {
+
+ }
+
+
+};
+
+}
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Graphics/GUIStyle.hh Wed Jan 21 01:57:24 2009 +0200
@@ -0,0 +1,36 @@
+#ifndef GRAPHICS_GUI_STYLE_HH
+#define GRAPHICS_GUI_STYLE_HH
+
+#include <ClanLib/gui.h>
+#include <ClanLib/guistyleboring.h>
+
+namespace graphics
+{
+
+/**
+ * Our CL_StyleManager used for drawing ClanLib's GUI components
+ */
+class GUIStyle : public CL_StyleManager_Boring {
+public:
+ /**
+ * Construct GUI style
+ */
+ GUIStyle (CL_ResourceManager *resources) :
+ CL_StyleManager_Boring(resources)
+ {
+
+ }
+
+ /**
+ * Handle attaching style objects to components
+ */
+ virtual void connect_styles (const std::string &type, CL_Component *owner) {
+
+ // default to parent impl
+ CL_StyleManager_Boring::connect_styles(type, component);
+ }
+};
+
+}
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Graphics/GameView.cc Wed Jan 21 01:57:24 2009 +0200
@@ -0,0 +1,48 @@
+
+#include "GameView.hh"
+
+namespace graphics
+{
+
+
+void GameView::draw (Display *display) {
+ CL_GraphicContext *gc = display->get_gc();
+
+ // calculate camera
+ PixelCoordinate camera(0, 0);
+
+ // ...to track our local player
+ if (player != NULL) {
+ // display resolution
+ PixelCoordinate resolution = display->getResolution();
+
+ // try and center the screen on the player
+ PixelCoordinate target = player->getCoordinate() - PixelCoordinate(resolution.x / 2, (resolution.y - 100) / 2);
+
+ // ...but keep the world in view
+ PixelCoordinate max = state.terrain.getDimensions() - resolution + PixelCoordinate(0, 100);
+
+ // ...by limiting the value to 0...max
+ camera = PixelCoordinate(
+ value_between(0, target.x, max.x),
+ value_between(0, target.y, max.y)
+ );
+ }
+
+ // Black background
+ gc->clear(CL_Color::black);
+
+ // Draw the game
+ state.draw(this, camera, flags & GUI_INPUT_DISPLAY_WEAPON);
+
+ // draw player info box
+ if (player != NULL) {
+ draw_player_info(gc, player);
+ }
+
+ // draw messages
+ message_view.draw(this);
+}
+
+
+};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Graphics/GameView.hh Wed Jan 21 01:57:24 2009 +0200
@@ -0,0 +1,48 @@
+#ifndef GRAPHICS_GAME_VIEW_HH
+#define GRAPHICS_GAME_VIEW_HH
+
+#include "Drawable.hh"
+#include "../GameState.hh"
+
+namespace graphics
+{
+
+/**
+ * This is the main in-game view, which is what the player sees when they are playing
+ */
+class GameView : public Drawable {
+protected:
+ /** The GameState that we're drawing */
+ GameState &state;
+
+ /** The player that we are controlling, if any */
+ LocalPlayer *player;
+
+public:
+ /**
+ * Constructed once the game is running
+ */
+ GameView (GameState &state, LocalPlayer *player) :
+ state(state), player(player)
+ {
+
+ }
+
+ /**
+ * Set a player where none was set before
+ */
+ void setPlayer (LocalPlayer *player) {
+ assert(!this->player);
+
+ // remember it
+ this->player = player;
+ }
+
+ /**
+ * Draw this view onto the given display
+ */
+ void draw (Display *display);
+};
+
+}
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Graphics/PlayerInfo.cc Wed Jan 21 01:57:24 2009 +0200
@@ -0,0 +1,117 @@
+
+#include "PlayerInfo.hh"
+
+#include <sstream>
+
+namespace graphics
+{
+
+void PlayerInfo::draw (Display *display) {
+ CL_GraphicContext *gc = display->get_gc();
+
+ // draw status info at bottom of display
+ gc->fill_rect(
+ CL_Rect(area.left, area.top, area.right, area.bottom),
+ CL_Gradient(
+ CL_Color(0, 0, 0),
+ CL_Color(50, 50, 50),
+ CL_Color(50, 50, 50, 150),
+ CL_Color(100, 100, 100, 200)
+ )
+ );
+
+ // Health
+ gc->draw_rect(
+ CL_Rect(
+ area.left + 9,
+ area.top + 9,
+ area.left + 11 + 100 * bar_length,
+ area.top + 31
+ ),
+ CL_Color(150, 150, 150)
+ );
+
+ gc->fill_rect(
+ CL_Rect(
+ area.left + 10,
+ area.top + 10,
+ area.left + 10 + (int) (p->getHealthPercent() * bar_length),
+ area.top + 30
+ ),
+ CL_Gradient(
+ CL_Color(200, 0, 0),
+ CL_Color(200 - (int)(p->getHealthPercent() * 2), (int)(p->getHealthPercent() * 2), 0),
+ CL_Color(200, 0, 0),
+ CL_Color(200 - (int)(p->getHealthPercent() * 2), (int)(p->getHealthPercent() * 2), 0)
+ )
+ );
+
+ // stats - kills
+ std::stringstream sskills;
+ sskills << "Kills: " << p->getKills();
+ getSimpleFont().draw(
+ area.left + 20 + 100 * bar_length,
+ area.top + 10,
+ sskills.str(),
+ get_gc()
+ );
+
+ // stats - deaths
+ std::stringstream ssdeaths;
+ ssdeaths << "Deaths: " << p->getDeaths();
+ getSimpleFont().draw(
+ area.left + 20 + 100 * bar_length,
+ area.top + 30,
+ ssdeaths.str(),
+ get_gc()
+ );
+
+ // stats - ratio
+ std::stringstream ssratio;
+ ssratio << "Ratio: " << (p->getKills()+1) / (p->getDeaths()+1);
+ getSimpleFont().draw(
+ area.left + 20 + 100 * bar_length,
+ area.top + 50,
+ ssratio.str(),
+ get_gc()
+ );
+
+
+ // Weapon clip / reloading
+ gc->draw_rect(
+ CL_Rect(
+ area.left + 9,
+ area.top + 69,
+ area.left + 11 + 100 * bar_length,
+ area.top + 91
+ ),
+ CL_Color(150, 150, 150)
+ );
+
+ gc->fill_rect(
+ CL_Rect(
+ area.left + 10,
+ area.top + 70,
+ area.left + 10 + (100 - (int) (p->getCurrentWeapon()->getReloadTimer() * 100 / p->getCurrentWeapon()->getReloadTime())) * bar_length,
+ area.top + 90
+ ),
+ CL_Gradient(
+ CL_Color(100, 100, 0),
+ CL_Color(100, 100, 0),
+ CL_Color(100, 100, 0),
+ CL_Color(100, 100, 100)
+ )
+ );
+
+ // current weapon name
+ getSimpleFont().draw(
+ area.left + 20 + 100 * bar_length,
+ area.top + 70,
+ p->getCurrentWeapon()->getName(),
+ get_gc()
+ );
+}
+
+
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Graphics/PlayerInfo.hh Wed Jan 21 01:57:24 2009 +0200
@@ -0,0 +1,37 @@
+#ifndef GRAPHICS_PLAYER_INFO_HH
+#define GRAPHICS_PLAYER_INFO_HH
+
+#include "View.hh"
+#include "../Player.hh"
+
+namespace graphics
+{
+
+class PlayerInfo : public View {
+private:
+ /**
+ * The player whose info we are drawing
+ *
+ * XXX: should this be LocalPlayer or is Player good?
+ */
+ Player *player;
+
+public:
+ /**
+ * Set initial view area and player
+ */
+ PlayerInfo (const PixelArea &area, Player *player) :
+ View(area), player(player)
+ {
+
+ }
+
+ /**
+ * Draw the player info onto the given display
+ */
+ virtual void draw (Display *display);
+}
+
+}
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Graphics/View.hh Wed Jan 21 01:57:24 2009 +0200
@@ -0,0 +1,39 @@
+#ifndef GRAPHICS_VIEW_HH
+#define GRAPHICS_VIEW_HH
+
+#include "../Types.hh"
+
+namespace graphics
+{
+
+/**
+ * A view is some area of the display that displays something
+ */
+class View : public Drawable {
+protected:
+ /**
+ * The area of the screen that is ours to draw on
+ */
+ PixelArea area;
+
+public:
+ /**
+ * Set the initial area that is drawn into
+ */
+ View (const PixelArea &area) :
+ area(area)
+ {
+
+ }
+
+ /**
+ * Update the view area
+ */
+ void updateArea (const PixelArea &area) {
+ this->area = area;
+ }
+};
+
+}
+
+#endif
--- a/src/Types.hh Wed Jan 21 00:21:42 2009 +0200
+++ b/src/Types.hh Wed Jan 21 01:57:24 2009 +0200
@@ -30,6 +30,19 @@
typedef VectorType<PixelDimension> PixelCoordinate;
/**
+ * Dimensions of something in pixels
+ */
+struct PixelDimensions {
+ /** Item width/height */
+ PixelDimension width, height;
+
+ /** Simple constructor */
+ PixelDimensions (PixelDimension width, PixelDimension height) :
+ width(width), height(height)
+ { }
+};
+
+/**
* A rectangular area of pixels
*/
struct PixelArea {