Browse Source

various gui improvements, render and tick state for client

Kajetan Johannes Hammerle 3 years ago
parent
commit
a2d11d80e3

+ 34 - 19
client/Game.cpp

@@ -6,27 +6,17 @@ Game::Game(TextInput*& textInput, const Controller& controller,
            const Clock& fps, const Clock& tps, RenderSettings& settings,
            const Size& size, Client& client)
     : controller(controller), fps(fps), tps(tps), renderSettings(settings),
-      size(size), client(client), state(State::START),
+      size(size), client(client), tickState(&Game::tickConnectState),
+      renderState(&Game::renderConnectState),
       baseGUI(size, textInput, controller), startGUI(baseGUI),
-      world(blockRegistry), worldRenderer(world), connected(false) {
+      world(blockRegistry), worldRenderer(world) {
     pos = Vector3(16.0f, 30.0f, -10.0f);
     rotation = Quaternion(Vector3(1.0f, 0.0f, 0.0f), 30) * rotation;
     rotation = Quaternion(Vector3(0.0f, 1.0f, 0.0f), 30) * rotation;
 }
 
 void Game::tick() {
-    switch(state) {
-        case State::START: startGUI.tick(); break;
-    }
-    /*if(!connected && controller.down.wasReleased()) {
-        if(client.connect("127.0.0.1", 11196, 3000)) {
-            std::cout << client.getError() << '\n';
-        } else {
-            std::cout << "connected\n";
-        }
-    } else {
-        client.consumeEvents(*this);
-    }*/
+    (this->*tickState)();
 
     lastRotation = rotation;
     lastPos = pos;
@@ -77,17 +67,14 @@ void Game::renderWorld(float lag, ShaderMatrix& sm) {
 }
 
 void Game::renderOverlay(float lag, ShaderMatrix& sm, Renderer& r) {
-    switch(state) {
-        case State::START: startGUI.render(lag, sm, r); break;
-    }
-    (void)lag;
+    (this->*renderState)(lag, sm, r);
     sm.identity().scale(2.0f).update();
     StringBuffer<100> s;
     s.append("FPS: &074")
         .append(fps.getUpdatesPerSecond())
         .append(" &999TPS: &722")
         .append(tps.getUpdatesPerSecond());
-    r.drawString(Vector2(10.0f, 10.0f), s);
+    r.renderString(Vector2(10.0f, 10.0f), s);
 }
 
 bool Game::isRunning() const {
@@ -112,4 +99,32 @@ void Game::onPacket(InPacket& in) {
             std::cout << s << '\n';
             break;
     }
+}
+
+void Game::tickConnectState() {
+    startGUI.tick();
+    StartGUI::Address a;
+    if(startGUI.getAddress(a)) {
+        if(client.connect(a, 11196, 3000)) {
+            std::cout << client.getError() << '\n';
+        } else {
+            std::cout << "connected\n";
+            tickState = &Game::tickConnectedState;
+            renderState = &Game::renderConnectedState;
+        }
+    }
+}
+
+void Game::tickConnectedState() {
+    client.consumeEvents(*this);
+}
+
+void Game::renderConnectState(float lag, ShaderMatrix& sm, Renderer& r) {
+    startGUI.render(lag, sm, r);
+}
+
+void Game::renderConnectedState(float lag, ShaderMatrix& sm, Renderer& r) {
+    (void)lag;
+    (void)sm;
+    (void)r;
 }

+ 24 - 20
client/Game.h

@@ -15,24 +15,6 @@
 #include "utils/Size.h"
 
 class Game final {
-public:
-    enum State { START };
-
-    Game(TextInput*& textInput, const Controller& controller, const Clock& fps,
-         const Clock& tps, RenderSettings& renderSettings, const Size& size,
-         Client& client);
-
-    void tick();
-    void renderWorld(float lag, ShaderMatrix& sm);
-    void renderOverlay(float lag, ShaderMatrix& sm, Renderer& r);
-
-    bool isRunning() const;
-
-    void onConnect();
-    void onDisconnect();
-    void onPacket(InPacket& in);
-
-private:
     const Controller& controller;
     const Clock& fps;
     const Clock& tps;
@@ -40,7 +22,10 @@ private:
     const Size& size;
     Client& client;
 
-    State state;
+    typedef void (Game::*TickState)();
+    TickState tickState;
+    typedef void (Game::*RenderState)(float, ShaderMatrix&, Renderer&);
+    RenderState renderState;
     BaseGUI baseGUI;
     StartGUI startGUI;
 
@@ -54,7 +39,26 @@ private:
 
     WorldRenderer worldRenderer;
 
-    bool connected;
+public:
+    Game(TextInput*& textInput, const Controller& controller, const Clock& fps,
+         const Clock& tps, RenderSettings& renderSettings, const Size& size,
+         Client& client);
+
+    void tick();
+    void renderWorld(float lag, ShaderMatrix& sm);
+    void renderOverlay(float lag, ShaderMatrix& sm, Renderer& r);
+
+    bool isRunning() const;
+
+    void onConnect();
+    void onDisconnect();
+    void onPacket(InPacket& in);
+
+private:
+    void tickConnectState();
+    void tickConnectedState();
+    void renderConnectState(float lag, ShaderMatrix& sm, Renderer& r);
+    void renderConnectedState(float lag, ShaderMatrix& sm, Renderer& r);
 };
 
 #endif

+ 68 - 27
client/gui/BaseGUI.cpp

@@ -4,22 +4,33 @@ static const Color4 INPUT_BACKGROUND(0x00, 0x00, 0x00, 0xA0);
 static const Color4 INPUT_BACKGROUND_2(0x00, 0x00, 0x00, 0x80);
 const Vector2 BaseGUI::FIXED_SIZE(400.0f, 300.0f);
 
+BaseGUI::Base::Base() : hovered(false), pressed(false) {
+}
+
 BaseGUI::BaseGUI(const Size& size, TextInput*& textInput,
                  const Controller& controller)
     : size(size), textInput(textInput), controller(controller) {
 }
 
+void BaseGUI::tickBase(Base& b) {
+    b.hovered = isIn(b.pos, b.size, controller.getMouse() / scale);
+    b.pressed = b.hovered && controller.leftClick.wasReleased();
+}
+
 void BaseGUI::tick() {
-    if(controller.leftClick.wasReleased()) {
-        Vector2 mousePos = controller.getMouse() / scale;
-        for(Input& input : inputs) {
-            if(isIn(input.pos, input.size, mousePos)) {
-                textInput = &input.text;
-                textInput->setActive(true);
-                break;
-            }
+    for(Label& label : labels) {
+        tickBase(label.base);
+    }
+    for(Input& input : inputs) {
+        tickBase(input.base);
+        if(input.base.pressed) {
+            textInput = &input.text;
+            textInput->setActive(true);
         }
     }
+    for(Button& button : buttons) {
+        tickBase(button.base);
+    }
 }
 
 void BaseGUI::updateScale(ShaderMatrix& sm) {
@@ -30,34 +41,58 @@ void BaseGUI::updateScale(ShaderMatrix& sm) {
     sm.scale(scale).update();
 }
 
-void BaseGUI::render(float, ShaderMatrix&, Renderer& r) {
-    Vector2 mousePos = controller.getMouse() / scale;
+void BaseGUI::renderBase(Renderer& r, const Base& base) {
+    r.renderRectangle(base.pos, base.size,
+                      base.hovered ? INPUT_BACKGROUND_2 : INPUT_BACKGROUND);
+}
+
+void BaseGUI::renderLabels(Renderer& r) {
+    for(const Label& label : labels) {
+        renderCenteredString(r, label.base, label.text);
+    }
+}
+
+void BaseGUI::renderInputs(Renderer& r) {
     for(Input& input : inputs) {
-        input.text.setLimit(r.charsInSpace(input.size[0] - 20.0f));
-        if(isIn(input.pos, input.size, mousePos)) {
-            r.drawRectangle(input.pos, input.size, INPUT_BACKGROUND_2);
-        } else {
-            r.drawRectangle(input.pos, input.size, INPUT_BACKGROUND);
-        }
+        input.text.setLimit(r.charsInSpace(input.base.size[0] - 20.0f));
+        renderBase(r, input.base);
         StringBuffer<256> text(input.text);
-        Vector2 size = r.getStringSize(text);
-        Vector2 pos = input.pos + (input.size - size) * 0.5f;
-        drawString(r, pos, text);
+        Vector2 pos = renderCenteredString(r, input.base, text);
         if(textInput == &input.text) {
             Vector2 cursor = r.getStringSize(text, input.text.getCursor());
-            drawString(r, Vector2(pos[0] + cursor[0], pos[1] + 2.0f), "&292_");
-            drawString(r, Vector2(pos[0] + cursor[0], pos[1] + 3.0f), "&292_");
+            renderString(r, Vector2(pos[0] + cursor[0], pos[1] + 2.0f),
+                         "&292_");
+            renderString(r, Vector2(pos[0] + cursor[0], pos[1] + 3.0f),
+                         "&292_");
         }
     }
 }
 
+void BaseGUI::renderButtons(Renderer& r) {
+    for(const Button& button : buttons) {
+        renderBase(r, button.base);
+        renderCenteredString(r, button.base, button.text);
+    }
+}
+
+void BaseGUI::render(float, ShaderMatrix&, Renderer& r) {
+    renderLabels(r);
+    renderInputs(r);
+    renderButtons(r);
+}
+
 Vector2 BaseGUI::round(const Vector2& v) const {
     return Vector2(static_cast<int>(v[0] * scale) / scale,
                    static_cast<int>(v[1] * scale) / scale);
 }
 
-void BaseGUI::drawString(Renderer& r, const Vector2& pos, const char* s) {
-    r.drawString(round(pos), s);
+void BaseGUI::renderString(Renderer& r, const Vector2& pos, const char* s) {
+    r.renderString(round(pos), s);
+}
+
+BaseGUI::Label& BaseGUI::addLabel(const char* text) {
+    labels.add({Base(), text});
+    return labels[labels.getLength() - 1];
 }
 
 BaseGUI::Input& BaseGUI::addInput() {
@@ -65,10 +100,16 @@ BaseGUI::Input& BaseGUI::addInput() {
     return inputs[inputs.getLength() - 1];
 }
 
-void BaseGUI::drawCenteredString(Renderer& r, const Vector2& pos,
-                                 const Vector2& size, const char* text) {
-    Vector2 textSize = r.getStringSize(text);
-    drawString(r, pos + (size - textSize) * 0.5f, text);
+BaseGUI::Button& BaseGUI::addButton(const char* text) {
+    buttons.add({Base(), text});
+    return buttons[buttons.getLength() - 1];
+}
+
+Vector2 BaseGUI::renderCenteredString(Renderer& r, const Base& b,
+                                      const char* text) {
+    Vector2 pos = b.pos + (b.size - r.getStringSize(text)) * 0.5f;
+    renderString(r, pos, text);
+    return pos;
 }
 
 bool BaseGUI::isIn(const Vector2& pos, const Vector2& size,

+ 31 - 4
client/gui/BaseGUI.h

@@ -19,13 +19,32 @@ struct BaseGUI final {
     float scale;
     Vector2 scaledSize;
 
-    struct Input final {
+    struct Base {
         Vector2 pos;
         Vector2 size;
+        bool hovered;
+        bool pressed;
+        Base();
+    };
+
+    struct Label {
+        Base base;
+        StringBuffer<50> text;
+    };
+    List<Label> labels;
+
+    struct Input {
+        Base base;
         TextInput text;
     };
     List<Input> inputs;
 
+    struct Button {
+        Base base;
+        StringBuffer<20> text;
+    };
+    List<Button> buttons;
+
     BaseGUI(const Size& size, TextInput*& textInput,
             const Controller& controller);
 
@@ -33,12 +52,20 @@ struct BaseGUI final {
     void updateScale(ShaderMatrix& sm);
     void render(float lag, ShaderMatrix& sm, Renderer& r);
     Vector2 round(const Vector2& v) const;
-    void drawString(Renderer& r, const Vector2& pos, const char* s);
+    void renderString(Renderer& r, const Vector2& pos, const char* s);
+    Label& addLabel(const char* text);
     Input& addInput();
-    void drawCenteredString(Renderer& r, const Vector2& pos,
-                            const Vector2& size, const char* text);
+    Button& addButton(const char* text);
     bool isIn(const Vector2& pos, const Vector2& size,
               const Vector2& point) const;
+
+private:
+    void tickBase(Base& b);
+    Vector2 renderCenteredString(Renderer& r, const Base& b, const char* text);
+    void renderBase(Renderer& r, const Base& b);
+    void renderLabels(Renderer& r);
+    void renderInputs(Renderer& r);
+    void renderButtons(Renderer& r);
 };
 
 #endif

+ 18 - 8
client/gui/StartGUI.cpp

@@ -1,7 +1,8 @@
 #include "client/gui/StartGUI.h"
 
 StartGUI::StartGUI(BaseGUI b)
-    : base(b), address(base.addInput()), test(base.addInput()) {
+    : base(b), info(base.addLabel("Connect to server ...")),
+      address(base.addInput()), connect(base.addButton("Connect ...")) {
 }
 
 void StartGUI::tick() {
@@ -14,14 +15,23 @@ void StartGUI::render(float lag, ShaderMatrix& sm, Renderer& r) {
     Vector2 size = Vector2(BaseGUI::FIXED_SIZE[0] - 80.0f, 110.0f);
     Vector2 pos = (base.scaledSize - size) * 0.5f;
 
-    address.pos = pos + Vector2(40.0f, 30.0f);
-    address.size = Vector2(size[0] - 80.0f, 30.0f);
+    info.base.pos = pos;
+    info.base.size = Vector2(size[0], 30.0f);
 
-    test.pos = pos + Vector2(40.0f, 70.0f);
-    test.size = Vector2(size[0] - 80.0f, 30.0f);
+    address.base.pos = pos + Vector2(40.0f, 30.0f);
+    address.base.size = Vector2(size[0] - 80.0f, 30.0f);
 
-    r.drawRectangle(pos, size, Color4(0x50, 0x50, 0x50, 0xFF));
-    base.drawCenteredString(r, pos, Vector2(size[0], 30.0f),
-                            "Connect to server ...");
+    connect.base.pos = pos + Vector2(40.0f, 70.0f);
+    connect.base.size = Vector2(size[0] - 80.0f, 30.0f);
+
+    r.renderRectangle(pos, size, Color4(0x50, 0x50, 0x50, 0xFF));
     base.render(lag, sm, r);
+}
+
+bool StartGUI::getAddress(Address& a) const {
+    if(connect.base.pressed) {
+        address.text.toString(a);
+        return true;
+    }
+    return false;
 }

+ 5 - 1
client/gui/StartGUI.h

@@ -5,14 +5,18 @@
 
 class StartGUI final {
     BaseGUI base;
+    BaseGUI::Label& info;
     BaseGUI::Input& address;
-    BaseGUI::Input& test;
+    BaseGUI::Button& connect;
 
 public:
     StartGUI(BaseGUI b);
 
     void tick();
     void render(float lag, ShaderMatrix& sm, Renderer& r);
+
+    typedef StringBuffer<64> Address;
+    bool getAddress(Address& a) const;
 };
 
 #endif

+ 3 - 3
client/rendering/Renderer.cpp

@@ -66,7 +66,7 @@ void Renderer::addChar(char32_t c) {
     vertices += 4;
 }
 
-void Renderer::drawString(const Vector2& pos, const char* text, int limit) {
+void Renderer::renderString(const Vector2& pos, const char* text, int limit) {
     setupString(pos, text, limit);
     while(hasStringData()) {
         char32_t c = readUnicode();
@@ -93,8 +93,8 @@ Vector2 Renderer::getStringSize(const char* text, int limit) {
     return size;
 }
 
-void Renderer::drawRectangle(const Vector2& pos, const Vector2& size,
-                             Color4 c) {
+void Renderer::renderRectangle(const Vector2& pos, const Vector2& size,
+                               Color4 c) {
     buffer.clear();
     buffer.add(pos[0]).add(pos[1]).add(0.0f).add(0.0f).add(c);
     buffer.add(pos[0]).add(pos[1] + size[1]).add(0.0f).add(0.0f).add(c);

+ 2 - 2
client/rendering/Renderer.h

@@ -22,9 +22,9 @@ class Renderer final {
 public:
     Renderer();
 
-    void drawString(const Vector2& pos, const char* text, int limit = -1);
+    void renderString(const Vector2& pos, const char* text, int limit = -1);
     Vector2 getStringSize(const char* text, int limit = -1);
-    void drawRectangle(const Vector2& pos, const Vector2& size, Color4 c);
+    void renderRectangle(const Vector2& pos, const Vector2& size, Color4 c);
     int charsInSpace(float width);
 
 private: