]> git.localhorst.tv Git - blank.git/commitdiff
also post UI messages to graphical output
authorDaniel Karbach <daniel.karbach@localhorst.tv>
Tue, 28 Jul 2015 15:40:49 +0000 (17:40 +0200)
committerDaniel Karbach <daniel.karbach@localhorst.tv>
Tue, 28 Jul 2015 15:40:49 +0000 (17:40 +0200)
src/app/IntervalTimer.hpp
src/graphics/FixedText.hpp [new file with mode: 0644]
src/graphics/MessageBox.hpp [new file with mode: 0644]
src/graphics/Text.hpp
src/graphics/Viewport.hpp
src/graphics/align.hpp
src/graphics/render.cpp
src/ui/HUD.hpp
src/ui/Interface.hpp
src/ui/ui.cpp

index 0d6790be20850ebfb9276fc62f88b09408793917..bcf1baef29e290fafbe90079d4daabc05052914b 100644 (file)
@@ -23,6 +23,9 @@ public:
                value = 0;
                speed = 0;
        }
+       void Reset() noexcept {
+               value = 0;
+       }
 
        bool Running() const noexcept {
                return speed != 0;
@@ -31,6 +34,9 @@ public:
        bool Hit() const noexcept {
                return Running() && value % intv < last_dt;
        }
+       bool HitOnce() const noexcept {
+               return value >= intv;
+       }
        int Elapsed() const noexcept {
                return value;
        }
diff --git a/src/graphics/FixedText.hpp b/src/graphics/FixedText.hpp
new file mode 100644 (file)
index 0000000..7f05c0a
--- /dev/null
@@ -0,0 +1,57 @@
+#ifndef BLANK_GRAPHICS_FIXEDTEXT_HPP_
+#define BLANK_GRAPHICS_FIXEDTEXT_HPP_
+
+#include "Text.hpp"
+
+
+namespace blank {
+
+class FixedText
+: public Text {
+
+public:
+       FixedText() noexcept;
+
+       void Position(const glm::vec3 &p) noexcept {
+               pos = p;
+       }
+       void Position(
+               const glm::vec3 &p,
+               Gravity g
+       ) noexcept {
+               pos = p;
+               grav = g;
+               Pivot(g);
+       }
+       void Position(
+               const glm::vec3 &p,
+               Gravity g,
+               Gravity pv
+       ) noexcept {
+               pos = p;
+               grav = g;
+               Pivot(pv);
+       }
+
+       void Foreground(const glm::vec4 &col) noexcept { fg = col; }
+       void Background(const glm::vec4 &col) noexcept { bg = col; }
+
+       void Show() noexcept { visible = true; }
+       void Hide() noexcept { visible = false; }
+       void Toggle() noexcept { visible = !visible; }
+       bool Visible() const noexcept { return visible; }
+
+       void Render(Viewport &) noexcept;
+
+private:
+       glm::vec4 bg;
+       glm::vec4 fg;
+       glm::vec3 pos;
+       Gravity grav;
+       bool visible;
+
+};
+
+}
+
+#endif
diff --git a/src/graphics/MessageBox.hpp b/src/graphics/MessageBox.hpp
new file mode 100644 (file)
index 0000000..a52c9b0
--- /dev/null
@@ -0,0 +1,51 @@
+#ifndef BLANK_GRAPHICS_MESSAGEBOX_HPP_
+#define BLANK_GRAPHICS_MESSAGEBOX_HPP_
+
+#include "align.hpp"
+#include "Text.hpp"
+
+#include <deque>
+#include <string>
+#include <glm/glm.hpp>
+
+
+namespace blank {
+
+class Font;
+class Viewport;
+
+class MessageBox {
+
+public:
+       explicit MessageBox(const Font &);
+
+       void Position(const glm::vec3 &, Gravity) noexcept;
+
+       void Foreground(const glm::vec4 &col) noexcept { fg = col; }
+       void Background(const glm::vec4 &col) noexcept { bg = col; }
+
+       void PushLine(const char *);
+       void PushLine(const std::string &l) {
+               PushLine(l.c_str());
+       }
+
+       void Render(Viewport &) noexcept;
+
+private:
+       const Font &font;
+       std::deque<Text> lines;
+       std::size_t max_lines;
+
+       glm::vec3 pos;
+       glm::vec3 adv;
+
+       glm::vec4 bg;
+       glm::vec4 fg;
+
+       Gravity grav;
+
+};
+
+}
+
+#endif
index 5d7a8b3a47577118301005043f1ff72e9b4b8220..989145f9bff79268f07788048798aa3b5e12dcb7 100644 (file)
@@ -24,53 +24,22 @@ public:
                Set(f, s.c_str());
        }
 
-       void Position(const glm::vec3 &p) noexcept {
-               pos = p;
-       }
-       void Position(
-               const glm::vec3 &p,
-               Gravity g
-       ) noexcept {
-               pos = p;
-               grav = g;
-               pivot = g;
-               dirty = true;
-       }
-       void Position(
-               const glm::vec3 &p,
-               Gravity g,
-               Gravity pv
-       ) noexcept {
-               pos = p;
-               grav = g;
-               pivot = pv;
+       void Pivot(Gravity p) {
+               pivot = p;
                dirty = true;
        }
 
-       void Foreground(const glm::vec4 &col) noexcept { fg = col; }
-       void Background(const glm::vec4 &col) noexcept { bg = col; }
-
        void Render(Viewport &) noexcept;
 
-       void Show() noexcept { visible = true; }
-       void Hide() noexcept { visible = false; }
-       void Toggle() noexcept { visible = !visible; }
-       bool Visible() const noexcept { return visible; }
-
 private:
        void Update();
 
 private:
        Texture tex;
        SpriteModel sprite;
-       glm::vec4 bg;
-       glm::vec4 fg;
        glm::vec2 size;
-       glm::vec3 pos;
-       Gravity grav;
        Gravity pivot;
        bool dirty;
-       bool visible;
 
 };
 
index 0bd6e89018d1ff6ed2d46b719a9131d086edda51..1995ce6c3f0342b7319e107164f8f42a07f363fb 100644 (file)
@@ -42,7 +42,7 @@ public:
        void ClearDepth() noexcept;
 
        void SetCursor(const glm::vec3 &);
-       void SetCursor(const glm::vec3 &, Gravity = Gravity::NORTH_WEST);
+       void SetCursor(const glm::vec3 &, Gravity);
        void MoveCursor(const glm::vec3 &);
        const glm::mat4 &Cursor() const noexcept { return cursor; }
 
index 1e18f356e812b16047dd98a3af24e6dd76c334f5..6563e29f5b98ef23930c4a296ec7531adb6058c9 100644 (file)
@@ -7,9 +7,9 @@
 namespace blank {
 
 enum class Align {
-       LEFT,
-       CENTER,
-       RIGHT,
+       BEGIN,
+       MIDDLE,
+       END,
 };
 
 enum class Gravity {
index 1a6d1abd80c124e7367969b863b84771ffc6b40b..747bfa2dbee75a01d88e14bf55255f15007289c5 100644 (file)
@@ -1,6 +1,8 @@
 #include "BlendedSprite.hpp"
+#include "FixedText.hpp"
 #include "Font.hpp"
 #include "Format.hpp"
+#include "MessageBox.hpp"
 #include "Text.hpp"
 #include "Texture.hpp"
 #include "Viewport.hpp"
@@ -158,16 +160,70 @@ void Format::ReadPixelFormat(const SDL_PixelFormat &fmt) {
 }
 
 
+MessageBox::MessageBox(const Font &f)
+: font(f)
+, lines()
+, max_lines(10)
+, pos(0.0f)
+, adv(0.0f, font.LineSkip(), 0.0f)
+, bg(1.0f, 1.0f, 1.0f, 0.0f)
+, fg(1.0f, 1.0f, 1.0f, 1.0f)
+, grav(Gravity::NORTH_WEST) {
+
+}
+
+void MessageBox::Position(const glm::vec3 &p, Gravity g) noexcept {
+       pos = p;
+       grav = g;
+       if (get_y(g) == Align::END) {
+               adv.y = -font.LineSkip();
+       } else {
+               adv.y = font.LineSkip();
+       }
+       for (Text &txt : lines) {
+               txt.Pivot(g);
+       }
+}
+
+void MessageBox::PushLine(const char *text) {
+       lines.emplace_front();
+       Text &txt = lines.front();
+       txt.Set(font, text);
+       txt.Pivot(grav);
+
+       while (lines.size() > max_lines) {
+               lines.pop_back();
+       }
+}
+
+void MessageBox::Render(Viewport &viewport) noexcept {
+       BlendedSprite &prog = viewport.SpriteProgram();
+       prog.SetBG(bg);
+       prog.SetFG(fg);
+       viewport.SetCursor(pos, grav);
+       for (Text &txt : lines) {
+               prog.SetM(viewport.Cursor());
+               txt.Render(viewport);
+               viewport.MoveCursor(adv);
+       }
+}
+
+
 Text::Text() noexcept
 : tex()
 , sprite()
+, size(0.0f)
+, pivot(Gravity::NORTH_WEST)
+, dirty(false) {
+
+}
+
+FixedText::FixedText() noexcept
+: Text()
 , bg(1.0f, 1.0f, 1.0f, 0.0f)
 , fg(1.0f, 1.0f, 1.0f, 1.0f)
-, size(0.0f)
 , pos(0.0f)
 , grav(Gravity::NORTH_WEST)
-, pivot(Gravity::NORTH_WEST)
-, dirty(false)
 , visible(false) {
 
 }
@@ -183,16 +239,21 @@ void Text::Update() {
        dirty = false;
 }
 
+void FixedText::Render(Viewport &viewport) noexcept {
+       BlendedSprite &prog = viewport.SpriteProgram();
+       viewport.SetCursor(pos, grav);
+       prog.SetM(viewport.Cursor());
+       prog.SetBG(bg);
+       prog.SetFG(fg);
+       Text::Render(viewport);
+}
+
 void Text::Render(Viewport &viewport) noexcept {
        if (dirty) {
                Update();
        }
        BlendedSprite &prog = viewport.SpriteProgram();
-       viewport.SetCursor(pos, grav);
-       prog.SetM(viewport.Cursor());
        prog.SetTexture(tex);
-       prog.SetBG(bg);
-       prog.SetFG(fg);
        sprite.Draw();
 }
 
index 47e0fd453f635f7b048dab826d798f3a1c76cc77..718e712485b30a727a14426dd50ead4ad8227d7a 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef BLANK_UI_HUD_H_
 #define BLANK_UI_HUD_H_
 
-#include "../graphics/Text.hpp"
+#include "../graphics/FixedText.hpp"
 #include "../model/Model.hpp"
 #include "../model/OutlineModel.hpp"
 
@@ -35,7 +35,7 @@ private:
        Model::Buffer block_buf;
        glm::mat4 block_transform;
 
-       Text block_label;
+       FixedText block_label;
 
        bool block_visible;
 
index d6c301981ef45125ac10cbf7a4eeabd7b987dbe6..00b76e66b0c2232ea48cfc0eec1f053e03c3aaac 100644 (file)
@@ -4,12 +4,14 @@
 #include "HUD.hpp"
 #include "../app/FPSController.hpp"
 #include "../app/IntervalTimer.hpp"
+#include "../graphics/FixedText.hpp"
 #include "../graphics/Font.hpp"
-#include "../graphics/Text.hpp"
+#include "../graphics/MessageBox.hpp"
 #include "../model/geometry.hpp"
 #include "../model/OutlineModel.hpp"
 #include "../world/Block.hpp"
 
+#include <string>
 #include <glm/glm.hpp>
 
 
@@ -64,6 +66,11 @@ public:
        void ToggleCounter();
        void UpdateCounter();
 
+       void PostMessage(const char *);
+       void PostMessage(const std::string &msg) {
+               PostMessage(msg.c_str());
+       }
+
        void Update(int dt);
 
        void Render(Viewport &) noexcept;
@@ -86,7 +93,9 @@ private:
        OutlineModel outline;
        glm::mat4 outline_transform;
 
-       Text counter_text;
+       FixedText counter_text;
+       MessageBox messages;
+       IntervalTimer msg_timer;
 
        Config config;
 
index e3ddf1020a26bbde6cde0a2499c8c9c60008e810..0f2b81dfb76e95571d486ccb46b5fb36a62b3528 100644 (file)
@@ -105,6 +105,8 @@ Interface::Interface(
 , outline()
 , outline_transform(1.0f)
 , counter_text()
+, messages(font)
+, msg_timer(5000)
 , config(config)
 , place_timer(256)
 , remove_timer(256)
@@ -116,6 +118,9 @@ Interface::Interface(
        counter_text.Position(glm::vec3(-25.0f, 25.0f, 0.0f), Gravity::NORTH_EAST);
        counter_text.Foreground(glm::vec4(1.0f));
        counter_text.Background(glm::vec4(0.5f));
+       messages.Position(glm::vec3(25.0f, -25.0f, 0.0f), Gravity::SOUTH_WEST);
+       messages.Foreground(glm::vec4(1.0f));
+       messages.Background(glm::vec4(0.5f));
        hud.Display(selection);
 }
 
@@ -210,61 +215,83 @@ void Interface::TurnBlock() {
 
 void Interface::ToggleCollision() {
        ctrl.Controlled().WorldCollidable(!ctrl.Controlled().WorldCollidable());
-       std::cout << "collision " << (ctrl.Controlled().WorldCollidable() ? "on" : "off") << std::endl;
+       if (ctrl.Controlled().WorldCollidable()) {
+               PostMessage("collision on");
+       } else {
+               PostMessage("collision off");
+       }
 }
 
 void Interface::PrintBlockInfo() {
        std::cout << std::endl;
        if (!aim_chunk) {
-               std::cout << "not looking at any block" << std::endl;
+               PostMessage("not looking at any block");
                Ray aim = ctrl.Aim();
-               std::cout << "aim ray: " << aim.orig << ", " << aim.dir << std::endl;
+               std::stringstream s;
+               s << "aim ray: " << aim.orig << ", " << aim.dir;
+               PostMessage(s.str());
                return;
        }
-       std::cout << "looking at block " << aim_block
+       std::stringstream s;
+       s << "looking at block " << aim_block
                << " " << Chunk::ToCoords(aim_block)
                << " of chunk " << aim_chunk->Position()
-               << std::endl;
+       ;
+       PostMessage(s.str());
        Print(aim_chunk->BlockAt(aim_block));
 }
 
 void Interface::PrintChunkInfo() {
        std::cout << std::endl;
        if (!aim_chunk) {
-               std::cout << "not looking at any block" << std::endl;
+               PostMessage("not looking at any block");
                return;
        }
-       std::cout << "looking at chunk "
-               << aim_chunk->Position()
-               << std::endl;
+       std::stringstream s;
+       s << "looking at chunk " << aim_chunk->Position();
+       PostMessage(s.str());
 
-       std::cout << "  neighbors:" << std::endl;
+       PostMessage("  neighbors:");
        if (aim_chunk->HasNeighbor(Block::FACE_LEFT)) {
-               std::cout << " left  " << aim_chunk->GetNeighbor(Block::FACE_LEFT).Position() << std::endl;
+               s.str("");
+               s << " left  " << aim_chunk->GetNeighbor(Block::FACE_LEFT).Position();
+               PostMessage(s.str());
        }
        if (aim_chunk->HasNeighbor(Block::FACE_RIGHT)) {
-               std::cout << " right " << aim_chunk->GetNeighbor(Block::FACE_RIGHT).Position() << std::endl;
+               s.str("");
+               s << " right " << aim_chunk->GetNeighbor(Block::FACE_RIGHT).Position();
+               PostMessage(s.str());
        }
        if (aim_chunk->HasNeighbor(Block::FACE_UP)) {
-               std::cout << " up    " << aim_chunk->GetNeighbor(Block::FACE_UP).Position() << std::endl;
+               s.str("");
+               s << " up    " << aim_chunk->GetNeighbor(Block::FACE_UP).Position();
+               PostMessage(s.str());
        }
        if (aim_chunk->HasNeighbor(Block::FACE_DOWN)) {
-               std::cout << " down  " << aim_chunk->GetNeighbor(Block::FACE_DOWN).Position() << std::endl;
+               s.str("");
+               s << " down  " << aim_chunk->GetNeighbor(Block::FACE_DOWN).Position();
+               PostMessage(s.str());
        }
        if (aim_chunk->HasNeighbor(Block::FACE_FRONT)) {
-               std::cout << " front " << aim_chunk->GetNeighbor(Block::FACE_FRONT).Position() << std::endl;
+               s.str("");
+               s << " front " << aim_chunk->GetNeighbor(Block::FACE_FRONT).Position();
+               PostMessage(s.str());
        }
        if (aim_chunk->HasNeighbor(Block::FACE_BACK)) {
-               std::cout << " back  " << aim_chunk->GetNeighbor(Block::FACE_BACK).Position() << std::endl;
+               s.str("");
+               s << " back  " << aim_chunk->GetNeighbor(Block::FACE_BACK).Position();
+               PostMessage(s.str());
        }
        std::cout << std::endl;
 }
 
 void Interface::PrintLightInfo() {
-       std::cout
+       std::stringstream s;
+       s
                << "light level " << world.PlayerChunk().GetLight(world.Player().Position())
                << " at position " << world.Player().Position()
-               << std::endl;
+       ;
+       PostMessage(s.str());
 }
 
 void Interface::PrintSelectionInfo() {
@@ -273,10 +300,12 @@ void Interface::PrintSelectionInfo() {
 }
 
 void Interface::Print(const Block &block) {
-       std::cout << "type: " << block.type
+       std::stringstream s;
+       s << "type: " << block.type
                << ", face: " << block.GetFace()
                << ", turn: " << block.GetTurn()
-               << std::endl;
+       ;
+       PostMessage(s.str());
 }
 
 void Interface::ToggleCounter() {
@@ -376,16 +405,29 @@ void Interface::SelectPrevious() {
 }
 
 
+void Interface::PostMessage(const char *msg) {
+       messages.PushLine(msg);
+       msg_timer.Reset();
+       msg_timer.Start();
+       std::cout << msg << std::endl;
+}
+
+
 void Interface::Update(int dt) {
        ctrl.Velocity(glm::vec3(fwd - rev) * config.move_velocity);
        ctrl.Update(dt);
 
+       msg_timer.Update(dt);
        place_timer.Update(dt);
        remove_timer.Update(dt);
 
        aim = ctrl.Aim();
        CheckAim();
 
+       if (msg_timer.HitOnce()) {
+               msg_timer.Stop();
+       }
+
        if (remove_timer.Hit()) {
                RemoveBlock();
                CheckAim();
@@ -428,6 +470,10 @@ void Interface::Render(Viewport &viewport) noexcept {
                counter_text.Render(viewport);
        }
 
+       if (msg_timer.Running()) {
+               messages.Render(viewport);
+       }
+
        hud.Render(viewport);
 }