From 9562fde36d6d28188210eb6053b9e2f9a9242702 Mon Sep 17 00:00:00 2001
From: Clyne Sullivan <clyne@bitgloo.com>
Date: Sat, 9 Jul 2022 11:27:17 -0400
Subject: mouse events; wip ui dialog box

---
 lib/libentityx.a             | Bin 414808 -> 396050 bytes
 lib/sol2/include/sol/sol.hpp |   2 ++
 src/engine.cpp               |  17 ++++++-------
 src/events/render.hpp        |   2 ++
 src/input.hpp                |  28 ++++++++++++++++++++--
 src/render.cpp               |   2 +-
 src/text.cpp                 |  18 ++++++++++----
 src/text.hpp                 |  17 ++++++++++++-
 src/ui.cpp                   |  56 +++++++++++++++++++++++++++++++++++++++++++
 src/ui.hpp                   |  42 ++++++++++++++++++++++++++++++++
 src/world.cpp                |   4 ++--
 11 files changed, 167 insertions(+), 21 deletions(-)
 create mode 100644 src/ui.cpp
 create mode 100644 src/ui.hpp

diff --git a/lib/libentityx.a b/lib/libentityx.a
index c1b2a0d..fc17564 100644
Binary files a/lib/libentityx.a and b/lib/libentityx.a differ
diff --git a/lib/sol2/include/sol/sol.hpp b/lib/sol2/include/sol/sol.hpp
index 9dfe941..82e79f4 100644
--- a/lib/sol2/include/sol/sol.hpp
+++ b/lib/sol2/include/sol/sol.hpp
@@ -22,6 +22,8 @@
 #ifndef SOL_HPP
 #define SOL_HPP
 
+#include <limits>
+
 #if defined(UE_BUILD_DEBUG) || defined(UE_BUILD_DEVELOPMENT) || defined(UE_BUILD_TEST) || defined(UE_BUILD_SHIPPING) || defined(UE_SERVER)
 #define SOL_INSIDE_UNREAL
 #ifdef check
diff --git a/src/engine.cpp b/src/engine.cpp
index a3c4c6a..a12b41f 100644
--- a/src/engine.cpp
+++ b/src/engine.cpp
@@ -29,6 +29,7 @@
 #include "render.hpp"
 #include "physics.hpp"
 #include "text.hpp"
+#include "ui.hpp"
 
 #include "components/EventListener.hpp"
 #include "components/Script.hpp"
@@ -54,6 +55,7 @@ int Engine::init(void)
     systems.add<ScriptSystem>(entities, *(systems.system<WorldSystem>().get()));
     systems.add<PhysicsSystem>();
     systems.add<TextSystem>();
+    systems.add<UISystem>();
     systems.configure();
 
     // Load game script and entity data
@@ -144,6 +146,7 @@ void Engine::renderLoop(int& fpsCounter)
     entityx::TimeDelta dt = 0; /**< Elapsed milliseconds since each loop */
     while (shouldRun()) {
         systems.update<TextSystem>(dt);
+        systems.update<UISystem>(dt);
         systems.update<RenderSystem>(dt);
         fpsCounter++;
     }
@@ -153,16 +156,10 @@ void Engine::run(void)
 {
     int fpsCounter = 0;
 
-    // Start logic thread
-    logicThread = std::thread([this](void) {
-        logicLoop();
-    });
-
-    physicsThread = std::thread([this](void) {
-        physicsLoop();
-    });
+    logicThread = std::thread([this] { logicLoop(); });
+    physicsThread = std::thread([this] { physicsLoop(); });
 
-    debugThread = std::thread([this, &fpsCounter](void) {
+    debugThread = std::thread([this, &fpsCounter] {
         while (shouldRun()) {
             std::this_thread::sleep_for(250ms);
             fps = fpsCounter*4;
@@ -176,7 +173,7 @@ void Engine::run(void)
                 (void)p;
                 std::string pr = "pos: " + std::to_string(pos.x) 
                                + "," + std::to_string(pos.y);
-                systems.system<TextSystem>()->put("default", 0, -24, pr);
+                systems.system<TextSystem>()->put("default", 0, 24, pr);
                    
             });
         }
diff --git a/src/events/render.hpp b/src/events/render.hpp
index a3eb7d6..7bb45df 100644
--- a/src/events/render.hpp
+++ b/src/events/render.hpp
@@ -18,6 +18,8 @@
 #ifndef EVENTS_RENDER_HPP_
 #define EVENTS_RENDER_HPP_
 
+#include <GL/glew.h>
+
 struct NewRenderEvent
 {
     GLuint vbo;
diff --git a/src/input.hpp b/src/input.hpp
index fa92c39..c5156b7 100644
--- a/src/input.hpp
+++ b/src/input.hpp
@@ -33,7 +33,7 @@ struct KeyUpEvent
     SDL_Keycode sym;
     Uint16 mod;
 
-    KeyUpEvent(const SDL_Keysym& keysym) :
+    explicit KeyUpEvent(const SDL_Keysym& keysym) :
         sym(keysym.sym), mod(keysym.mod) {}
 };
 
@@ -45,10 +45,28 @@ struct KeyDownEvent {
     SDL_Keycode sym;
     Uint16 mod;
 
-    KeyDownEvent(const SDL_Keysym& keysym) :
+    explicit KeyDownEvent(const SDL_Keysym& keysym) :
         sym(keysym.sym), mod(keysym.mod) {}
 };
 
+struct MouseUpEvent {
+    Uint8 button;
+    Sint32 x;
+    Sint32 y;
+
+    explicit MouseUpEvent(const SDL_MouseButtonEvent& mbe) :
+        button(mbe.button), x(mbe.x), y(mbe.y) {}
+};
+
+struct MouseDownEvent {
+    Uint8 button;
+    Sint32 x;
+    Sint32 y;
+
+    explicit MouseDownEvent(const SDL_MouseButtonEvent& mbe) :
+        button(mbe.button), x(mbe.x), y(mbe.y) {}
+};
+
 /**
  * @class InputSystem
  * Listens for user input from SDL, and emits input events accordingly.
@@ -79,6 +97,12 @@ public:
                 if (auto key = event.key; key.repeat == 0)
                     events.emit<KeyDownEvent>(key.keysym);
                 break;
+            case SDL_MOUSEBUTTONUP:
+                events.emit<MouseUpEvent>(event.button);
+                break;
+            case SDL_MOUSEBUTTONDOWN:
+                events.emit<MouseDownEvent>(event.button);
+                break;
             default:
                 break;
             }
diff --git a/src/render.cpp b/src/render.cpp
index 0c60eed..6e30f21 100644
--- a/src/render.cpp
+++ b/src/render.cpp
@@ -345,7 +345,7 @@ int RenderSystem::init(void)
         return -1;
     }
 
-    SDL_GL_SetSwapInterval(0);
+    SDL_GL_SetSwapInterval(1);
 
     glEnable(GL_BLEND);
     glEnable(GL_DEPTH_TEST);
diff --git a/src/text.cpp b/src/text.cpp
index fb82875..c25eeae 100644
--- a/src/text.cpp
+++ b/src/text.cpp
@@ -13,13 +13,15 @@ TextSystem::~TextSystem(void)
 }
 
 void TextSystem::configure([[maybe_unused]] entityx::EntityManager& entities,
-                           [[maybe_unused]] entityx::EventManager& events)
+                           entityx::EventManager& events)
 {
+    shouldUpdateVBOs = false;
+
+    events.subscribe<ShowTextEvent>(*this);
+
     if (FT_Init_FreeType(&freetype) != 0) {
         // TODO handle error
     }
-
-    shouldUpdateVBOs = false;
 }
     
 /**
@@ -42,6 +44,11 @@ void TextSystem::update([[maybe_unused]] entityx::EntityManager& entites,
     }
 }
 
+void TextSystem::receive(const ShowTextEvent& ste)
+{
+    put(ste.font, ste.x, ste.y, ste.text);
+}
+
 void TextSystem::loadFont(const std::string& name,
                           const std::string& file,
                           int size)
@@ -138,7 +145,7 @@ void TextSystem::put(const std::string& font,
     if (fontData.find(font) == fontData.end())
         return;
 
-    y -= fontData[font].fontSize;
+    y += fontData[font].fontSize;
 
     auto& vector = fontData[font].text;
     if (auto i = std::find_if(vector.begin(), vector.end(), [&x, &y](const Text& t) {
@@ -146,7 +153,8 @@ void TextSystem::put(const std::string& font,
         vector.erase(i);
     }
 
-    fontData[font].text.emplace_back(text, x, y, -9.0f);
+    // Invert y axis so positive grows south.
+    fontData[font].text.emplace_back(text, x, -y, -9.0f);
     shouldUpdateVBOs = true;
 }
 
diff --git a/src/text.hpp b/src/text.hpp
index 1ef2afa..604710d 100644
--- a/src/text.hpp
+++ b/src/text.hpp
@@ -74,7 +74,20 @@ struct Font {
     std::basic_string<TextMeshData> buffer;
 };
 
-class TextSystem : public entityx::System<TextSystem>
+struct ShowTextEvent
+{
+    std::string font;
+    float x;
+    float y;
+    std::string text;
+
+    explicit ShowTextEvent(const std::string& _font, float _x, float _y,
+        const std::string& _text) :
+        font(_font), x(_x), y(_y), text(_text) {}
+};
+
+class TextSystem : public entityx::System<TextSystem>,
+                   public entityx::Receiver<TextSystem>
 {
 public:
     ~TextSystem(void);
@@ -92,6 +105,8 @@ public:
                 entityx::EventManager& events,
                 entityx::TimeDelta dt) final;
 
+    void receive(const ShowTextEvent&);
+
     void put(const std::string& font, float x, float y, const std::string& text);
 
     void loadFont(const std::string& name, const std::string& file, int size);
diff --git a/src/ui.cpp b/src/ui.cpp
new file mode 100644
index 0000000..a6c5081
--- /dev/null
+++ b/src/ui.cpp
@@ -0,0 +1,56 @@
+#include "ui.hpp"
+
+#include "events/render.hpp"
+#include "text.hpp"
+
+#include <SDL2/SDL_opengl.h>
+#include <iostream>
+#include <string>
+
+static NewRenderEvent NRE (0, 0, 0, 0);
+static const unsigned int NRE_TEX_DATA = 0xFF0000FF;
+static std::basic_string<TextMeshData> buffer;
+
+void UISystem::configure(entityx::EntityManager&, entityx::EventManager&)
+{
+}
+
+void UISystem::update(entityx::EntityManager&,
+    entityx::EventManager& events,
+    entityx::TimeDelta)
+{
+    static bool t = false;
+
+    if (!t) {
+        t = true;
+
+        glGenBuffers(1, &NRE.vbo);
+        glGenTextures(1, &NRE.tex);
+
+        glBindTexture(GL_TEXTURE_2D, NRE.tex);
+        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, &NRE_TEX_DATA);
+
+        glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+
+        buffer += { 30, -50, -8, 0, 0, 1 };
+        buffer += { 160, -50, -8, 0, 0, 1 };
+        buffer += { 160, -10, -8, 0, 0, 1 };
+        buffer += { 160, -10, -8, 0, 0, 1 };
+        buffer += { 30, -10, -8, 0, 0, 1 };
+        buffer += { 30, -50, -8, 0, 0, 1 };
+
+        glBindBuffer(GL_ARRAY_BUFFER, NRE.vbo);
+        glBufferData(GL_ARRAY_BUFFER,
+                     buffer.size() * sizeof(TextMeshData), buffer.data(),
+                     GL_DYNAMIC_DRAW);
+
+        NRE.normal = 0;
+        NRE.vertex = buffer.size();
+        events.emit<NewRenderEvent>(NRE);
+    }
+}
+
diff --git a/src/ui.hpp b/src/ui.hpp
new file mode 100644
index 0000000..809b5dc
--- /dev/null
+++ b/src/ui.hpp
@@ -0,0 +1,42 @@
+/**
+ * @file ui.hpp
+ *
+ *
+ * Copyright (C) 2022 Clyne Sullivan
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef SYSTEM_UI_HPP_
+#define SYSTEM_UI_HPP_
+
+#include <entityx/entityx.h>
+
+#include <map>
+#include <string>
+#include <tuple>
+#include <vector>
+
+class UISystem : public entityx::System<UISystem>
+{
+public:
+    void configure(entityx::EntityManager&, entityx::EventManager&) final;
+    
+    void update(entityx::EntityManager&,
+                entityx::EventManager&,
+                entityx::TimeDelta) final;
+};
+
+#endif // SYSTEM_UI_HPP_
+
diff --git a/src/world.cpp b/src/world.cpp
index 61a30de..69590e1 100644
--- a/src/world.cpp
+++ b/src/world.cpp
@@ -189,8 +189,8 @@ glm::vec3 World::collide(glm::vec3 &start, glm::vec3 &end, Physics &phys)
                 // Get all colliding world spaces
                 std::vector<glm::vec3> inter = getIntersectingPlanes(pos, phys);
 
-                if (i == 0.0f)
-                    std::cout << inter.size() << std::endl;
+                //if (i == 0.0f)
+                //    std::cout << inter.size() << std::endl;
 
                 // If there are no colliding world spaces, don't bother
                 if (inter.size()) {
-- 
cgit v1.2.3