start working out the Graphics/* code, this is a long way from compiling, let alone working new_graphics
authorTero Marttila <terom@fixme.fi>
Wed, 21 Jan 2009 01:57:24 +0200
branchnew_graphics
changeset 410 41fd46cffc52
parent 409 1a03ff151abc
child 411 106aaf6eadfe
start working out the Graphics/* code, this is a long way from compiling, let alone working
src/Graphics/Console.cc
src/Graphics/Console.hh
src/Graphics/Display.cc
src/Graphics/Display.hh
src/Graphics/Drawable.hh
src/Graphics/GUI.hh
src/Graphics/GUIStyle.hh
src/Graphics/GameView.cc
src/Graphics/GameView.hh
src/Graphics/PlayerInfo.cc
src/Graphics/PlayerInfo.hh
src/Graphics/View.hh
src/Types.hh
--- /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 {