From f44de31053e79d0fc78afbb35e3e40aca9bf36f3 Mon Sep 17 00:00:00 2001 From: Cruel Date: Mon, 17 Aug 2015 02:24:40 -0400 Subject: [PATCH] Add Console class for reading stdout using GPU --- include/cpp3ds/Graphics/Console.hpp | 77 ++++++++++++++++ src/cpp3ds/Graphics/Console.cpp | 134 ++++++++++++++++++++++++++++ 2 files changed, 211 insertions(+) create mode 100644 include/cpp3ds/Graphics/Console.hpp create mode 100644 src/cpp3ds/Graphics/Console.cpp diff --git a/include/cpp3ds/Graphics/Console.hpp b/include/cpp3ds/Graphics/Console.hpp new file mode 100644 index 0000000..55196b1 --- /dev/null +++ b/include/cpp3ds/Graphics/Console.hpp @@ -0,0 +1,77 @@ +#ifndef CPP3DS_CONSOLE_HPP +#define CPP3DS_CONSOLE_HPP + +//////////////////////////////////////////////////////////// +// Headers +//////////////////////////////////////////////////////////// +#include +#include +#include +#include + +namespace cpp3ds +{ + +extern std::vector g_stdout; + +//////////////////////////////////////////////////////////// +/// \brief Class holding a valid drawing context +/// +//////////////////////////////////////////////////////////// +class Console : public Drawable +{ +public: + + //////////////////////////////////////////////////////////// + /// \brief Default constructor + /// + /// The constructor creates and activates the context + /// + //////////////////////////////////////////////////////////// + Console(); + + //////////////////////////////////////////////////////////// + /// \brief Destructor + /// + /// The destructor deactivates and destroys the context + /// + //////////////////////////////////////////////////////////// + ~Console(); + +public: + + void create(); + + void update(float delta); + + void write(String text); + + bool processEvent(Event& event); + + void setVisible(bool visible); + +private: + + //////////////////////////////////////////////////////////// + /// \brief Draw the console to a render target + /// + /// \param target Render target to draw to + /// \param states Current render states + /// + //////////////////////////////////////////////////////////// + virtual void draw(RenderTarget& target, RenderStates states) const; + + //////////////////////////////////////////////////////////// + // Member data + //////////////////////////////////////////////////////////// + Font m_font; + std::vector m_lines; + unsigned int m_limit; + bool m_initialized; + bool m_visible; +}; + +} // namespace cpp3ds + + +#endif // CPP3DS_CONSOLE_HPP diff --git a/src/cpp3ds/Graphics/Console.cpp b/src/cpp3ds/Graphics/Console.cpp new file mode 100644 index 0000000..6651636 --- /dev/null +++ b/src/cpp3ds/Graphics/Console.cpp @@ -0,0 +1,134 @@ +//////////////////////////////////////////////////////////// +// Headers +//////////////////////////////////////////////////////////// +#include +#include +#include +#include +#include +#include +#include +#include +#ifndef EMULATION +#include +#endif + +namespace cpp3ds { + std::vector g_stdout; +} + +extern "C" { + +#ifndef EMULATION +ssize_t console_write(struct _reent *r, int fd, const char *ptr, size_t len) { + cpp3ds::g_stdout.push_back(cpp3ds::String(ptr)); + return len; +} + +static const devoptab_t dotab_stdout = { + "con", 0, NULL, NULL, console_write, NULL, NULL, NULL +}; +#endif + +} + +namespace cpp3ds +{ +//////////////////////////////////////////////////////////// +Console::Console() +{ + // +} + + +//////////////////////////////////////////////////////////// +Console::~Console() +{ + if (m_initialized) + { + // + } +} + + +//////////////////////////////////////////////////////////// +void Console::create() +{ + if (!m_initialized) { + m_initialized = true; +#ifndef EMULATION + devoptab_list[STD_OUT] = &dotab_stdout; + devoptab_list[STD_ERR] = &dotab_stdout; + setvbuf(stdout, NULL, _IONBF, 0); + setvbuf(stderr, NULL, _IONBF, 0); + + priv::ResourceInfo font = priv::core_resources["sansation.ttf"]; + m_font.loadFromMemory(font.data, font.size); +#endif + + m_limit = 1000; + } +} + + +//////////////////////////////////////////////////////////// +void Console::update(float delta) +{ + for (String& s : g_stdout) + write(s); + g_stdout.clear(); + + if (m_lines.size() > m_limit) + m_lines.erase(m_lines.begin(), m_lines.end() - m_limit); +} + + +//////////////////////////////////////////////////////////// +void Console::write(String text) +{ + Text line(text, m_font, 12); + m_lines.push_back(line); +} + + +//////////////////////////////////////////////////////////// +bool Console::processEvent(Event& event) +{ + if (event.type == Event::KeyPressed) { + if (event.key.code == Keyboard::A) { + m_visible = !m_visible; + return false; + } + } + + // Allow event to also be processed by the game + return true; +} + + +//////////////////////////////////////////////////////////// +void Console::setVisible(bool visible) +{ + m_visible = visible; +} + + +//////////////////////////////////////////////////////////// +void Console::draw(RenderTarget& target, RenderStates states) const +{ + if (!m_visible) + return; + + int h = 240; + int i = m_lines.size(); + + while (h > 0 && i > 0) { + Text text = m_lines[--i]; + h -= text.getGlobalBounds().height; + text.setPosition(0, h); + target.draw(text); + } +} + + +} // namespace cpp3ds