fade out console
[supertux.git] / src / console.cpp
index da30b22..edef8b5 100644 (file)
 #include "main.hpp"
 #include "resources.hpp"
 
-namespace {
-  int ticks; // TODO: use a clock?
-}
+/// speed (pixels/s) the console closes
+static const float FADE_SPEED = 1;
 
 Console::Console()
+  : backgroundOffset(0), height(0), alpha(1.0), offset(0), focused(false),
+    stayOpen(0)
 {
-  background = new Surface("images/engine/console.png");
-  background2 = new Surface("images/engine/console2.png");
+  font.reset(new Font("images/engine/fonts/white-small.png",
+                      "images/engine/fonts/shadow-small.png", 8, 9, 1));
+  background.reset(new Surface("images/engine/console.png"));
+  background2.reset(new Surface("images/engine/console2.png"));
 }
 
 Console::~Console() 
 {
-  delete background;
-  delete background2;
 }
 
 void 
@@ -72,7 +73,7 @@ Console::execute_script(const std::string& command)
 {
   using namespace Scripting;
 
-  HSQUIRRELVM vm = script_manager->get_global_vm();
+  HSQUIRRELVM vm = ScriptManager::instance->get_vm();
 
   if(command == "")
     return;
@@ -94,7 +95,7 @@ Console::execute_script(const std::string& command)
   }
   int newtop = sq_gettop(vm);
   if(newtop < oldtop) {
-    msg_fatal << "Script destroyed squirrel stack..." << std::endl;
+    log_fatal << "Script destroyed squirrel stack..." << std::endl;
   } else {
     sq_settop(vm, oldtop);
   }
@@ -151,12 +152,19 @@ Console::addLine(std::string s)
     s = "..."+s.substr(99-3);
   }
   lines.push_front(s);
-  while (lines.size() >= 65535) lines.pop_back();
+  
+  while (lines.size() >= 1000)
+    lines.pop_back();
+  
   if (height < 64) {
-    if (height < 4+9) height=4+9;
-    height+=9;
+    if(height < 4)
+      height = 4;
+    height += font->get_height();
   }
-  ticks=60;
+
+  alpha = 1.0;
+  if(stayOpen < 5)
+    stayOpen += 1;
 }
 
 void
@@ -177,6 +185,7 @@ Console::parse(std::string s)
   }
 
   // command is args[0]
+  if (args.size() == 0) return;
   std::string command = args.front();
   args.erase(args.begin());
 
@@ -196,7 +205,7 @@ Console::parse(std::string s)
 
   // send command to the most recently registered ccr
   ConsoleCommandReceiver* ccr = i->second.front();
-  if (ccr->consoleCommand(command, args) != true) msg_warning << "Sent command to registered ccr, but command was unhandled" << std::endl;
+  if (ccr->consoleCommand(command, args) != true) log_warning << "Sent command to registered ccr, but command was unhandled" << std::endl;
 }
 
 bool
@@ -204,12 +213,12 @@ Console::consoleCommand(std::string command, std::vector<std::string> arguments)
 {
   if (command == "ccrs") {
     if (arguments.size() != 1) {
-      msg_info << "Usage: ccrs <command>" << std::endl;
+      log_info << "Usage: ccrs <command>" << std::endl;
       return true;
     }
     std::map<std::string, std::list<ConsoleCommandReceiver*> >::iterator i = commands.find(arguments[0]);
     if ((i == commands.end()) || (i->second.size() == 0)) {
-      msg_info << "unknown command: \"" << arguments[0] << "\"" << std::endl;
+      log_info << "unknown command: \"" << arguments[0] << "\"" << std::endl;
       return true;
     }
 
@@ -221,7 +230,7 @@ Console::consoleCommand(std::string command, std::vector<std::string> arguments)
       ccr_list << "[" << *j << "]";
     }
 
-    msg_info << "registered ccrs for \"" << arguments[0] << "\": " << ccr_list.str() << std::endl;
+    log_info << "registered ccrs for \"" << arguments[0] << "\": " << ccr_list.str() << std::endl;
     return true;
   }
 
@@ -239,6 +248,7 @@ Console::show()
 {
   focused = true;
   height = 256;
+  alpha = 1.0;
 }
 
 void 
@@ -246,6 +256,7 @@ Console::hide()
 {
   focused = false;
   height = 0;
+  stayOpen = 0;
 
   // clear input buffer
   inputBuffer.str(std::string());
@@ -262,22 +273,33 @@ Console::toggle()
   }
 }
 
-void 
-Console::draw(DrawingContext& context)
+void
+Console::update(float elapsed_time)
 {
-  if (height == 0) return;
-  if (!focused) {
-    if (ticks-- < 0) {
-      height-=10;
-      ticks=0;
-      if (height < 0) height=0;
+  if(stayOpen > 0) {
+    stayOpen -= elapsed_time;
+    if(stayOpen < 0)
+      stayOpen = 0;
+  } else if(!focused && height > 0) {
+    alpha -= elapsed_time * FADE_SPEED;
+    if(alpha < 0) {
+      alpha = 0;
+      height = 0;
     }
-    if (height == 0) return;
   }
+}
 
-  context.draw_surface(background2, Vector(SCREEN_WIDTH/2 - background->get_width()/2 - background->get_width() + backgroundOffset, height - background->get_height()), LAYER_FOREGROUND1+1);
-  context.draw_surface(background2, Vector(SCREEN_WIDTH/2 - background->get_width()/2 + backgroundOffset, height - background->get_height()), LAYER_FOREGROUND1+1);
-  context.draw_surface(background, Vector(SCREEN_WIDTH/2 - background->get_width()/2, height - background->get_height()), LAYER_FOREGROUND1+1);
+void 
+Console::draw(DrawingContext& context)
+{
+  if (height == 0)
+    return;
+
+  context.push_transform();
+  context.set_alpha(alpha);
+  context.draw_surface(background2.get(), Vector(SCREEN_WIDTH/2 - background->get_width()/2 - background->get_width() + backgroundOffset, height - background->get_height()), LAYER_FOREGROUND1+1);
+  context.draw_surface(background2.get(), Vector(SCREEN_WIDTH/2 - background->get_width()/2 + backgroundOffset, height - background->get_height()), LAYER_FOREGROUND1+1);
+  context.draw_surface(background.get(), Vector(SCREEN_WIDTH/2 - background->get_width()/2, height - background->get_height()), LAYER_FOREGROUND1+1);
   backgroundOffset+=10;
   if (backgroundOffset > (int)background->get_width()) backgroundOffset -= (int)background->get_width();
 
@@ -286,7 +308,7 @@ Console::draw(DrawingContext& context)
   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);
+    context.draw_text(font.get(), "> "+inputBuffer.str()+"_", Vector(4, py), LEFT_ALLIGN, LAYER_FOREGROUND1+1);
   }
 
   int skipLines = -offset;
@@ -295,8 +317,10 @@ Console::draw(DrawingContext& context)
     lineNo++;
     float py = height-4-lineNo*9;
     if (py < -9) break;
-    context.draw_text(white_small_text, *i, Vector(4, py), LEFT_ALLIGN, LAYER_FOREGROUND1+1);
+    context.draw_text(font.get(), *i, Vector(4, py), LEFT_ALLIGN, LAYER_FOREGROUND1+1);
   }
+
+  context.pop_transform();
 }
 
 void 
@@ -310,12 +334,12 @@ Console::unregisterCommand(std::string command, ConsoleCommandReceiver* ccr)
 {
   std::map<std::string, std::list<ConsoleCommandReceiver*> >::iterator i = commands.find(command);
   if ((i == commands.end()) || (i->second.size() == 0)) {
-    msg_warning << "Command \"" << command << "\" not associated with a command receiver. Not dissociated." << std::endl;
+    log_warning << "Command \"" << command << "\" not associated with a command receiver. Not dissociated." << std::endl;
     return;
   }
   std::list<ConsoleCommandReceiver*>::iterator j = find(i->second.begin(), i->second.end(), ccr);
   if (j == i->second.end()) {
-    msg_warning << "Command \"" << command << "\" not associated with given command receiver. Not dissociated." << std::endl;
+    log_warning << "Command \"" << command << "\" not associated with given command receiver. Not dissociated." << std::endl;
     return;
   }
   i->second.erase(j);
@@ -333,14 +357,9 @@ Console::unregisterCommands(ConsoleCommandReceiver* ccr)
   }
 }
 
-int Console::height = 0;
-bool Console::focused = false;
-std::list<std::string> Console::lines;
-std::map<std::string, std::list<ConsoleCommandReceiver*> > Console::commands;
+Console* Console::instance = NULL;
 ConsoleStreamBuffer Console::inputBuffer;
 ConsoleStreamBuffer Console::outputBuffer;
 std::ostream Console::input(&Console::inputBuffer);
 std::ostream Console::output(&Console::outputBuffer);
-int Console::offset = 0;
-int Console::backgroundOffset = 0;