int ticks; // TODO: use a clock?
}
-Console::Console(DrawingContext* context) : context(context)
+Console::Console(DrawingContext* context) : context(context)
{
background = new Surface("images/engine/console.jpg");
}
}
void
-Console::flush()
+Console::flush(ConsoleStreamBuffer* buffer)
{
- lines.push_front(outputBuffer.str());
- if (lines.size() >= 256) lines.pop_back();
- if (height < 64) {
- if (height < 4) height=4;
- height+=9;
- }
- ticks=120;
- std::cerr << outputBuffer.str() << std::flush;
- outputBuffer.str(std::string());
+ if (buffer == &outputBuffer) {
+ std::string s = outputBuffer.str();
+ if ((s.length() > 0) && ((s[s.length()-1] == '\n') || (s[s.length()-1] == '\r'))) {
+ while ((s[s.length()-1] == '\n') || (s[s.length()-1] == '\r')) s.erase(s.length()-1);
+ addLine(s);
+ outputBuffer.str(std::string());
+ }
+ }
+ if (buffer == &inputBuffer) {
+ std::string s = inputBuffer.str();
+ if ((s.length() > 0) && ((s[s.length()-1] == '\n') || (s[s.length()-1] == '\r'))) {
+ while ((s[s.length()-1] == '\n') || (s[s.length()-1] == '\r')) s.erase(s.length()-1);
+ addLine("> "+s);
+ parse(s);
+ inputBuffer.str(std::string());
+ }
+ }
+}
+
+void
+Console::addLine(std::string s)
+{
+ lines.push_front(s);
+ if (lines.size() >= 256) lines.pop_back();
+ if (height < 64) {
+ if (height < 4+9) height=4+9;
+ height+=9;
+ }
+ ticks=120;
+ std::cerr << s << std::endl;
+}
+
+void
+Console::parse(std::string s)
+{
+ addLine("unknown command: \"" + s + "\"");
+}
+
+bool
+Console::hasFocus()
+{
+ return focused;
+}
+
+void
+Console::show()
+{
+ focused = true;
+ height = 128;
+}
+
+void
+Console::hide()
+{
+ focused = false;
+ ticks = 0;
}
void
Console::draw()
{
if (height == 0) return;
- if (ticks-- < 0) {
- height-=1;
- ticks=0;
- if (height < 0) height=0;
+ if (!focused) {
+ if (ticks-- < 0) {
+ height-=1;
+ ticks=0;
+ if (height < 0) height=0;
+ }
+ if (height == 0) return;
}
- if (height == 0) return;
context->draw_surface(background, Vector(SCREEN_WIDTH/2 - background->get_width()/2, height - background->get_height()), LAYER_FOREGROUND1+1);
int lineNo = 0;
+
+ if (focused) {
+ lineNo++;
+ float py = height-4-1*9;
+ context->draw_text(white_small_text, "> "+inputBuffer.str(), Vector(4, py), LEFT_ALLIGN, LAYER_FOREGROUND1+1);
+ }
+
for (std::list<std::string>::iterator i = lines.begin(); i != lines.end(); i++) {
lineNo++;
float py = height-4-lineNo*9;
if (py < -9) break;
- context->draw_text(white_small_text, *i, Vector(BORDER_X, py), LEFT_ALLIGN, LAYER_FOREGROUND1+1);
+ context->draw_text(white_small_text, *i, Vector(4, py), LEFT_ALLIGN, LAYER_FOREGROUND1+1);
}
}
int Console::height = 0;
+bool Console::focused = false;
std::list<std::string> Console::lines;
+ConsoleStreamBuffer Console::inputBuffer;
ConsoleStreamBuffer Console::outputBuffer;
+std::ostream Console::input(&Console::inputBuffer);
std::ostream Console::output(&Console::outputBuffer);
Console(DrawingContext* context);
~Console();
- static std::ostream output;
+ static std::ostream input; /**< stream of keyboard input to send to the console. Do not forget to send std::endl or to flush the stream. */
+ static std::ostream output; /**< stream of characters to output to the console. Do not forget to send std::endl or to flush the stream. */
- static void flush();
+ static void flush(ConsoleStreamBuffer* buffer); /**< act upon changes in a stream, normally called by the stream itself */
- void draw();
+ void draw(); /**< draw the console to its */
+ static void show(); /**< display the console */
+ static void hide(); /**< hide the console */
+ static bool hasFocus(); /**< true if characters should be sent to the console instead of their normal target */
protected:
- static std::list<std::string> lines;
- DrawingContext* context;
- Surface* background;
- static int height;
+ static std::list<std::string> lines; /**< backbuffer of lines sent to the console */
+ DrawingContext* context; /**< context to draw to */
+ Surface* background; /**< console background image */
+ static int height; /**< height of the console in px */
+ static bool focused; /**< true if console has input focus */
- static ConsoleStreamBuffer outputBuffer;
+ static ConsoleStreamBuffer inputBuffer; /**< stream buffer used by input stream */
+ static ConsoleStreamBuffer outputBuffer; /**< stream buffer used by output stream */
+
+ static void addLine(std::string s); /**< display a line in the console */
+ static void parse(std::string s); /**< react to a given command */
};
class ConsoleStreamBuffer : public std::stringbuf
public:
int sync()
{
- Console::flush();
+ Console::flush(this);
return std::stringbuf::sync();
}
};
#include "lisp/lisp.hpp"
#include "lisp/list_iterator.hpp"
#include "game_session.hpp"
+#include "console.hpp"
class JoystickKeyboardController::JoystickMenu : public Menu
{
(event.key.keysym.unicode & 0xFF80) == 0) {
memmove(last_keys, last_keys+1, sizeof(last_keys)-1);
last_keys[sizeof(last_keys)-1] = event.key.keysym.unicode;
+
+ if (Console::hasFocus()) {
+ // if the Console is open, send keys there
+ char c = event.key.keysym.unicode;
+ if ((c >= 32) && (c <= 126)) {
+ Console::input << c;
+ }
+ if ((c == '\n') || (c == '\r')) {
+ Console::input << std::endl;
+ }
+ if (c == '\t') {
+ Console::hide();
+ }
+ } else {
+ char c = event.key.keysym.unicode;
+ if (c == '\t') {
+ Console::show();
+ }
+ }
+
if(GameSession::current() != NULL)
GameSession::current()->try_cheats();
}
-
- // menu mode?
- if(Menu::current()) { // menu mode
+
+ if(Console::hasFocus()) {
+ // console is open - ignore key
+ }
+ else if(Menu::current()) {
+ // menu mode
process_menu_key_event(event);
return;
} else {