00001
00002
00003
00004
00005
00006 #include "SDL.h"
00007 #include "SDL_opengl.h"
00008
00009 #include <sstream>
00010 #include <string>
00011 #include <iostream>
00012 #include <vector>
00013
00014 #include "globals_client.h"
00015 #include "log.h"
00016 #include "console.h"
00017 #include "platform.h"
00018 #include "settings.h"
00019 #include "application_client.h"
00020 #include "conversions.h"
00021 #include "translator.h"
00022
00023 #include "font_manager.h"
00024
00025 using namespace std;
00026
00027 const int CONSOLE_ONOFF = SDLK_BACKQUOTE;
00028 const float CONSOLE_TOP = 10.0f;
00029 const float CONSOLE_LEFT = 20.0f;
00030
00031 Console::Console()
00032 {
00033 mPriority = IA_PRIORITY_CONSOLE;
00034 mActive = false;
00035
00036 mFont = 0;
00037 mLineWrap = true;
00038
00039 mTitle = 0;
00040
00041 mInHistory = g_settings.getInt(SETTING_CONSOLE_LINES);
00042
00043
00044 mLogForwarding = true;
00045
00046 mHistoryIgnore = false;
00047 }
00048
00049 Console::~Console()
00050 {
00051 TIN
00052 }
00053
00054
00055 void Console::init()
00056 {
00057 TIN
00058
00059
00060 getAppClient().getInputManager().setKeyReceiver(CONSOLE_ONOFF, this);
00061 getAppClient().getInputManager().addInputAcceptor(*this);
00062
00063
00064
00065 mFont = FontManager::getRef().get("FreeMono.ttf", 20);
00066 if (!mFont)
00067 {
00068 LOGE << "Loading font failed!" << endl;
00069 DIE();
00070 }
00071
00072
00073 registerLog();
00074
00075
00076 mTitle = LNG_CACHE_("-- Console --");
00077 }
00078
00079 void Console::clean()
00080 {
00081 TIN
00082
00083
00084 getAppClient().getInputManager().setKeyReceiver(CONSOLE_ONOFF, 0);
00085 getAppClient().getInputManager().removeInputAcceptor(*this);
00086
00087
00088 mFont = 0;
00089
00090
00091 g_log.setAcceptor(0);
00092
00093
00094 LNG_UNCACHE(mTitle);
00095 }
00096
00097
00098 bool Console::wantKey(const SDL_keysym &keysym)
00099 {
00100
00101 if (keysym.sym == CONSOLE_ONOFF) return true;
00102
00103 return mActive;
00104 }
00105
00106 bool Console::keyDown(const SDL_keysym &keysym)
00107 {
00108 TIN
00109
00110 if (keysym.sym == CONSOLE_ONOFF)
00111 {
00112 mActive = !mActive;
00113 getAppClient().getInputManager().WantAllInput(mActive);
00114 LOGD << " Console is " << mActive << endl;
00115 return true;
00116 }
00117
00118 if (!mActive) return false;
00119
00120 LOGT << "Processing new key " << keysym.sym << " :-)\n";
00121
00122 switch (keysym.sym)
00123 {
00124
00125
00126 case SDLK_RETURN:
00127 processCommand( mInputLine.getLineU() );
00128
00129 mInputLine.clear();
00130
00131 break;
00132
00133
00134 case SDLK_UP:
00135 LOGI << "History in console not implemented yet." << endl;
00136 break;
00137 case SDLK_DOWN:
00138 LOGI << "History in console not implemented yet." << endl;
00139 break;
00140 case SDLK_TAB:
00141 LOGI << "Completion in console is not implemented." << endl;
00142 break;
00143
00144
00145 default:
00146
00147 mInputLine.processKey(keysym);
00148
00149 break;
00150 }
00151
00152 return true;
00153 }
00154
00155 void Console::logLine(const std::string &line)
00156 {
00157 if ( mLogForwarding )
00158 addConsoleMessage(line);
00159 }
00160
00161
00162 void Console::registerLog()
00163 {
00164 if ( mLogForwarding )
00165 {
00166 g_log.setAcceptor(this);
00167 }
00168 else
00169 {
00170 g_log.setAcceptor(0);
00171 }
00172 }
00173
00174
00175 void Console::render()
00176 {
00177 TIN;
00178
00179
00180 assertL(mFont.isValid());
00181
00182 mFont->RenderUTF8( xtos(getAppClient().getGFX().getFps()),
00183 (float)(getAppClient().getGFX().getWidth() - 50),
00184 (float)(getAppClient().getGFX().getHeight() - 30) );
00185
00186
00187 if (!mActive) return;
00188
00189
00190 getAppClient().getGFX().set2DOpenGL();
00191 glLoadIdentity();
00192 glColor3f( 1.0, 1.0, 1.0);
00193
00194
00195
00196 mFont->RenderUTF8(
00197 LNG_GET(mTitle),
00198 CONSOLE_LEFT,
00199 getAppClient().getGFX().getHeight() - (CONSOLE_TOP + mFont->Ascent())
00200 );
00201
00202
00203
00204
00205 mHistoryMutex.lock();
00206 mHistoryIgnore = true;
00207
00208 list<string>::iterator it = mMessageHistory.begin();
00209 int i = mInHistory+1;
00210 for(; it != mMessageHistory.end(); ++it, --i)
00211 {
00212 mFont->RenderUTF8(
00213 *it,
00214 CONSOLE_LEFT,
00215 getAppClient().getGFX().getHeight() - (CONSOLE_TOP + i*mFont->Ascent())
00216 );
00217 }
00218
00219 mHistoryIgnore = false;
00220 mHistoryMutex.unlock();
00221
00222
00223 mFont->RenderUTF8(
00224 mInputLine.getLineURender(),
00225 CONSOLE_LEFT,
00226 getAppClient().getGFX().getHeight() - (CONSOLE_TOP + (mInHistory+2)*mFont->Ascent())
00227 );
00228
00229 }
00230
00231 void Console::addConsoleMessage(const std::string &msg)
00232 {
00233
00234
00235
00236 mHistoryMutex.lock();
00237 if (!mHistoryIgnore)
00238 {
00239
00240
00241
00242
00243 if (mFont && mLineWrap)
00244 {
00245
00246 int maxW = getAppClient().getGFX().getWidth()-2*(int)CONSOLE_LEFT-mFont->getWwidth();
00247
00248 wstring src, dst;
00249 utf8tows(msg.c_str(), src);
00250
00251 while (!src.empty())
00252 {
00253 wchar_t w;
00254
00255 w = src[0];
00256 src.erase(0,1);
00257 dst += w;
00258
00259 string dst_utf;
00260 wstoutf8(dst, dst_utf);
00261
00262 if (mFont->getTextWidth(dst_utf) >= maxW)
00263 {
00264 mMessageHistory.push_front(dst_utf);
00265 dst.erase(0);
00266 }
00267
00268 }
00269
00270 if (!dst.empty())
00271 {
00272 string dst_utf;
00273 wstoutf8(dst, dst_utf);
00274 mMessageHistory.push_front(dst_utf);
00275 }
00276
00277 }
00278 else
00279 {
00280 mMessageHistory.push_front(msg);
00281 }
00282
00283
00284
00285 while ((signed int)mMessageHistory.size() > mInHistory)
00286 {
00287 mMessageHistory.pop_back();
00288 }
00289 }
00290
00291 mHistoryMutex.unlock();
00292 }
00293
00294
00295 void Console::processCommand(const std::string &cmd)
00296 {
00297 TIN
00298
00299 LOGD << "Console command: " << cmd << endl;
00300
00301 addConsoleMessage(cmd);
00302
00303 getAppClient().getCommander().addCommand(cmd);
00304 }