# HG changeset patch # User Tero Marttila # Date 1232495844 -7200 # Node ID 41fd46cffc52bd69d8bbab94c7e042c74a101c93 # Parent 1a03ff151abce90b05bede99902af11dcec7a6b8 start working out the Graphics/* code, this is a long way from compiling, let alone working diff -r 1a03ff151abc -r 41fd46cffc52 src/Graphics/Console.cc --- /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); +} + + +} diff -r 1a03ff151abc -r 41fd46cffc52 src/Graphics/Console.hh --- /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 +#include + +namespace graphics +{ + +class Console : public CL_Component { +protected: + /** our list of messages */ + std::list 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 diff -r 1a03ff151abc -r 41fd46cffc52 src/Graphics/Display.cc --- /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 & Graphics::getDisplayModes (void) { + return CL_DisplayMode::get_display_modes(); +} + +const CL_DisplayMode Graphics::getBestMode (void) { + const std::vector &modes = Graphics::getDisplayModes(); + + const CL_DisplayMode *best_mode = NULL; + + for (std::vector::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; +} + +} + diff -r 1a03ff151abc -r 41fd46cffc52 src/Graphics/Display.hh --- /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 + +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 & 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 diff -r 1a03ff151abc -r 41fd46cffc52 src/Graphics/Drawable.hh --- /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 diff -r 1a03ff151abc -r 41fd46cffc52 src/Graphics/GUI.hh --- /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 + + +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 diff -r 1a03ff151abc -r 41fd46cffc52 src/Graphics/GUIStyle.hh --- /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 +#include + +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 diff -r 1a03ff151abc -r 41fd46cffc52 src/Graphics/GameView.cc --- /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); +} + + +}; diff -r 1a03ff151abc -r 41fd46cffc52 src/Graphics/GameView.hh --- /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 diff -r 1a03ff151abc -r 41fd46cffc52 src/Graphics/PlayerInfo.cc --- /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 + +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() + ); +} + + + +} diff -r 1a03ff151abc -r 41fd46cffc52 src/Graphics/PlayerInfo.hh --- /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 diff -r 1a03ff151abc -r 41fd46cffc52 src/Graphics/View.hh --- /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 diff -r 1a03ff151abc -r 41fd46cffc52 src/Types.hh --- 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 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 {