#include "client/Chat.h" #include "client/Controls.h" #include "client/FontRenderer.h" #include "common/NetworkPackets.h" #include "data/RingBuffer.h" #include "network/Client.h" #include "rendering/GL.h" static constexpr int LINES = 20; static RingBuffer chat; static bool active = false; static int alpha = 255; static int getAlpha() { return alpha > 255 ? 255 : alpha; } static void enable() { Window::Input::enable(); Window::freeCursor(); active = true; } static void disable() { Window::Input::disable(); Window::trapCursor(); active = false; } void Chat::tick() { if(active) { alpha = 500; if(Controls::wasReleased(Controls::enter)) { OutPacket out(100); out.writeU8(static_cast(ToServerPacket::CHAT)); for(uint32 u : Window::Input::getUnicode()) { out.writeU32(u); } Client::send(out, PacketSendMode::RELIABLE); Window::Input::reset(); disable(); } if(Controls::wasReleased(Controls::escape)) { disable(); } } else { alpha = std::max(alpha - 5, 0); if(Controls::isDown(Controls::chat)) { enable(); } } } void Chat::render() { GL::disableDepthTesting(); GL::enableBlending(); Vector2 size = Window::getSize().toFloat(); IntVector2 padding(2.0f, 2.0f); FontRenderer::bind(); FontRenderer::setProjection(Matrix()); Matrix v; v.scale(Vector3(2.0f / size[0], -2.0f / size[1], 1.0f)); v.translate(Vector3(-1.0f, 1.0f, 0.0f)); FontRenderer::setView(v); int scale = ((size[1] - padding[1]) / 9.0f) / (LINES + 2); float y = size[1] / scale - 9.0f * (chat.getLength() + 2) - padding[1]; float max = 0.0f; for(int i = 0; i < chat.getLength(); i++) { max = std::max(max, FontRenderer::getWidth(chat[i], -1)); } Matrix model; model.translateTo(Vector3(1.0f, 1.0f, 0.0f)).scale(scale); FontRenderer::setModel(model); FontRenderer::draw( StringBuffer<50>("FPS: ").append(Window::getFramesPerSecond()), 255); model.translateTo(Vector3(padding[0] - 2.0f, y - 2.0f, 0.0f)).scale(scale); FontRenderer::setModel(model); if(chat.getLength() > 0) { FontRenderer::draw(Vector2(max + 4.0f, 9.0f * chat.getLength() + 4.0f), Color4(0, 0, 0, getAlpha() / 2)); } for(int i = 0; i < chat.getLength(); i++) { model.translateTo(Vector3(padding[0], i * 9.0f + y, 0.0f)).scale(scale); FontRenderer::setModel(model); FontRenderer::draw(chat[i], getAlpha()); } if(!active) { return; } float height = (chat.getLength() + 1) * 9.0f + y; StringBuffer<256> s; Window::Input::toString(s); float width = FontRenderer::getWidth(s, -1) + 8.0f; model.translateTo(Vector3(padding[0] - 2.0f, height - 2.0f, 0.0f)) .scale(scale); FontRenderer::setModel(model); FontRenderer::draw(Vector2(width + 4.0f, 12.0f), Color4(0, 0, 0, 127)); model.translateTo(Vector3(padding[0], height, 0.0f)).scale(scale); FontRenderer::setModel(model); FontRenderer::draw(s, 255); s.clear(); const List& unicode = Window::Input::getUnicode(); for(int i = 0; i < Window::Input::getCursor(); i++) { s.appendUnicode(unicode[i]); } width = FontRenderer::getWidth(s, -1); model.translateTo(Vector3(padding[0] + width, height + 2.0f, 0.0f)) .scale(scale); FontRenderer::setModel(model); FontRenderer::draw("_", 255); } bool Chat::isActive() { return active; } void Chat::add(const Message& msg) { if(chat.add(msg)) { chat.remove(); chat.add(msg); } alpha = 500; }