00001 /* 00002 SagaEngine library 00003 Copyright (c) 2002-2006 Skalden Studio AS 00004 00005 This software is provided 'as-is', without any express or implied 00006 warranty. In no event will the authors be held liable for any 00007 damages arising from the use of this software. 00008 00009 Permission is granted to distribute the library under the terms of the 00010 Q Public License version 1.0. Be sure to read and understand the license 00011 before using the library. It should be included here, or you may read it 00012 at http://www.trolltech.com/products/qt/licenses/licensing/qpl 00013 00014 The original version of this library can be located at: 00015 http://www.sagaengine.com/ 00016 00017 Rune Myrland 00018 rune@skalden.com 00019 */ 00020 00021 00022 #include "O3dPre.hpp" 00023 #include "Console.hpp" 00024 #include "ConsoleHandler.hpp" 00025 #include "util/error/Log.hpp" 00026 #include "../schema/O3dSchema.hpp" 00027 #include <OIS.h> 00028 #include <cstring> 00029 #include <OgreUTFString.h> 00030 #ifndef NO_CEGUI 00031 #include <CEGUI/CEGUIFontManager.h> 00032 #else 00033 #include "../area/O3dManager.hpp" 00034 #endif 00035 00036 namespace se_ogre { 00037 #ifndef NO_CEGUI 00038 CEGUI::MouseButton convertOgreButtonToCegui(int buttonID) { 00039 switch (buttonID) { 00040 case OIS::MB_Left: 00041 return CEGUI::LeftButton; 00042 case OIS::MB_Right: 00043 return CEGUI::RightButton; 00044 case OIS::MB_Middle: 00045 return CEGUI::MiddleButton; 00046 case OIS::MB_Button3: 00047 return CEGUI::X1Button; 00048 default: 00049 return CEGUI::LeftButton; 00050 } 00051 } 00052 #endif 00053 00054 Console 00055 ::Console() 00056 : isFocused_(false), handler_(0) 00057 , inCount_(0), outCount_(0), lineCount_(0) 00058 #ifndef NO_CEGUI 00059 , guiRenderer_(0), guiSystem_(0), editorGuiSheet_(0) 00060 #endif 00061 { 00062 output_ = new wchar_t[ OUTPUT_BUFFER_SIZE ]; 00063 output_[ outCount_ ] = 0; 00064 input_ = new wchar_t[ INPUT_BUFFER_SIZE ]; 00065 clearInput(); 00066 } 00067 00068 00069 Console 00070 ::~Console() { 00071 #ifndef NO_CEGUI 00072 00073 if(editorGuiSheet_) { 00074 CEGUI::WindowManager::getSingleton().destroyWindow(editorGuiSheet_); 00075 } 00076 if(guiSystem_) { 00077 delete guiSystem_; 00078 guiSystem_ = 0; 00079 } 00080 if(guiRenderer_) { 00081 delete guiRenderer_; 00082 guiRenderer_ = 0; 00083 } 00084 #endif 00085 delete[] input_; 00086 delete[] output_; 00087 } 00088 00089 00090 void Console 00091 ::clearInput() { 00092 inCount_ = 0; 00093 input_[ inCount_++ ] = '>'; 00094 input_[ inCount_++ ] = ' '; 00095 input_[ inCount_ ] = 0; 00096 } 00097 00098 00099 void Console 00100 ::flipFocus() { 00101 isFocused_ = !isFocused_; 00102 #ifndef NO_CEGUI 00103 if(isFocused()) { 00104 editBox_->show(); 00105 editBox_->activate(); 00106 } 00107 else { 00108 editBox_->deactivate(); 00109 editBox_->hide(); 00110 } 00111 #else 00112 O3dSchema::worldManager->showDebugOverlay(isFocused()); 00113 #endif 00114 } 00115 00116 00117 void Console 00118 ::updateConsole() { 00119 #ifndef NO_CEGUI 00120 // Text is output text with current input line appended 00121 CEGUI::String s; 00122 s = output_; 00123 s += input_; 00124 // Show text 00125 editBox_->setText(s); 00126 // Scroll to bottom 00127 editBox_->ensureCaratIsVisible(); 00128 editBox_->setCaratIndex(s.length()); 00129 #else 00130 const wchar_t* from = output_; 00131 int match = 0; 00132 static const int MAX_LINES = 4; 00133 while(lineCount_ - match > MAX_LINES) { 00134 Assert(*from != 0); 00135 if(*from == '\n') { 00136 ++match; 00137 } 00138 ++from; 00139 } 00140 Ogre::UTFString s(from); 00141 s.append("\n"); 00142 s.append(input_); 00143 if(O3dSchema::worldManager) { 00144 O3dSchema::worldManager->setDebugText(s); 00145 } 00146 #endif 00147 } 00148 00149 00150 void Console 00151 ::setupGuiSystem() { 00152 #ifndef NO_CEGUI 00153 // setup GUI system 00154 guiRenderer_ = new CEGUI::OgreCEGUIRenderer(O3dSchema::window, Ogre::RENDER_QUEUE_OVERLAY, false, 3000, O3dSchema::sceneManager); 00155 guiSystem_ = new CEGUI::System(guiRenderer_); 00156 CEGUI::Logger::getSingleton().setLoggingLevel(CEGUI::Informative); 00157 LogDetail("Initialized CEGUI logger"); 00158 00159 /* 00160 // Setup Render To Texture for preview window 00161 rttTexture_ = Ogre::Root::getSingleton().getRenderSystem()->createRenderTexture( "ceguiTex", 512, 512, Ogre::TEX_TYPE_2D, Ogre::PF_A8R8G8B8 ); 00162 LogDetail("Created CEGUI render texture"); 00163 00164 // Update when needed 00165 rttTexture_->setActive(false); 00166 rttTexture_->setAutoUpdated(false); 00167 */ 00168 00169 /* 00170 { 00171 Ogre::Camera* rttCam = O3dSchema::sceneManager->createCamera("CeguiCam"); 00172 Ogre::SceneNode* camNode = O3dSchema::sceneManager->getSceneNode("MainSceneNode")->createChildSceneNode("ceguiCamNode"); 00173 camNode->attachObject(rttCam); 00174 rttCam->setPosition(0,0,200); 00175 //rttCam->setVisible(false); 00176 Ogre::Viewport *v = rttTexture_->addViewport( rttCam ); 00177 v->setOverlaysEnabled(false); 00178 v->setClearEveryFrame(true); 00179 v->setBackgroundColour(Ogre::ColourValue::Black); 00180 } 00181 */ 00182 { 00183 CEGUI::SchemeManager::getSingleton().loadScheme((CEGUI::utf8*)"TaharezLook.scheme"); 00184 guiSystem_->setDefaultMouseCursor((CEGUI::utf8*)"TaharezLook", (CEGUI::utf8*)"MouseArrow"); 00185 CEGUI::MouseCursor::getSingleton().setImage("TaharezLook", "MouseMoveCursor"); 00186 guiSystem_->setDefaultFont((CEGUI::utf8*)"Tahoma-12"); 00187 } 00188 /* 00189 LogDetail("Created CEGUI viewport"); 00190 00191 // Retrieve CEGUI texture for the RTT 00192 CEGUI::Texture* ceguiTexture = guiRenderer_->createTexture((CEGUI::utf8*)"ceguiTex"); 00193 LogDetail("Created CEGUI texture"); 00194 00195 CEGUI::Imageset* rttImageSet = CEGUI::ImagesetManager::getSingleton().createImageset((CEGUI::utf8*)"ceguiImageset", ceguiTexture); 00196 rttImageSet->defineImage((CEGUI::utf8*)"ceguiImage", CEGUI::Point(0.0f, 0.0f), CEGUI::Size(ceguiTexture->getWidth(), ceguiTexture->getHeight()), CEGUI::Point(0.0f,0.0f)); 00197 00198 CEGUI::SchemeManager::getSingleton().loadScheme((CEGUI::utf8*)"TaharezLook.scheme"); 00199 guiSystem_->setDefaultMouseCursor((CEGUI::utf8*)"TaharezLook", (CEGUI::utf8*)"MouseArrow"); 00200 00201 // selecting the font 00202 //CEGUI::Font *font = CEGUI::FontManager::getSingleton().createFont((CEGUI::utf8*)"verdana.font"); 00203 //guiSystem_->setDefaultFont(font); 00204 guiSystem_->setDefaultFont((CEGUI::utf8*)"Tahoma-12"); 00205 */ 00206 00207 #endif 00208 } 00209 00210 void Console 00211 ::renderGui() { 00212 #ifndef NO_CEGUI 00213 guiSystem_->renderGUI(); 00214 #endif 00215 } 00216 00217 00218 void Console 00219 ::createConsoleWindow() { 00220 #ifndef NO_CEGUI 00221 if(!editorGuiSheet_) { 00222 editorGuiSheet_ = CEGUI::WindowManager::getSingleton().createWindow((CEGUI::utf8*)"DefaultWindow", (CEGUI::utf8*)"Sheet"); 00223 guiSystem_->setGUISheet(editorGuiSheet_); 00224 } 00225 00227 editBox_ = (CEGUI::MultiLineEditbox*)CEGUI::WindowManager::getSingleton().createWindow("TaharezLook/MultiLineEditbox", (CEGUI::utf8*)"Console"); 00228 editorGuiSheet_->addChildWindow(editBox_); 00229 /* 00230 editBox_->setPosition(CEGUI::Point(0.0f, 0.0f)); 00231 editBox_->setSize(CEGUI::Size(0.3f, 0.6f)); 00232 */ 00233 00234 // TODO: Do manual update on the RenderTexture, to avoid performance drop. (from wumpus) 00235 updateConsole(); 00236 if(isFocused()) { 00237 editBox_->activate(); 00238 } 00239 else { 00240 editBox_->hide(); 00241 } 00242 #else 00243 updateConsole(); 00244 #endif 00245 } 00246 00247 00248 void Console 00249 ::initXMLMenu(const char* filename) { 00250 #ifndef NO_CEGUI 00251 editorGuiSheet_ = CEGUI::WindowManager::getSingleton().loadWindowLayout((CEGUI::utf8*)filename); 00252 guiSystem_->setGUISheet(editorGuiSheet_); 00253 #endif 00254 } 00255 00256 00257 void Console 00258 ::setConsoleHandler(ConsoleHandler* h) { 00259 // Cannot reset handler via this method 00260 Assert(h); 00261 00262 // The handler should not be registered with 00263 // another console 00264 Assert(!h->console_); 00265 00266 // Reset replaced handler 00267 if(handler_) { 00268 handler_->console_ = 0; 00269 } 00270 00271 // Register new handler 00272 handler_ = h; 00273 // Register console with new handler 00274 h->console_ = this; 00275 } 00276 00277 00278 void Console 00279 ::output(const char* msg) { 00280 const unsigned char* src = (const unsigned char*)msg; 00281 00282 int len = (int)strlen(msg); 00283 if(outCount_ + len >= OUTPUT_BUFFER_SIZE - 1) { 00284 lineCount_ = 0; 00285 for(int i = 0; i < outCount_ - len; ++i) { 00286 output_[i] = output_[ i + len ]; 00287 if(output_[i] == '\n') 00288 ++lineCount_; 00289 } 00290 outCount_ -= len; 00291 } 00292 00293 while(*src != 0 && outCount_ < OUTPUT_BUFFER_SIZE) { 00294 if(*src == '\n') 00295 ++lineCount_; 00296 output_[ outCount_++ ] = *(src++); 00297 } 00298 } 00299 00300 void Console 00301 ::output(const wchar_t* msg) { 00302 const wchar_t* src = msg; 00303 00304 int len = (int)wcslen(msg); 00305 if(outCount_ + len >= OUTPUT_BUFFER_SIZE - 1) { 00306 lineCount_ = 0; 00307 for(int i = 0; i < outCount_ - len; ++i) { 00308 output_[i] = output_[ i + len ]; 00309 if(output_[i] == '\n') 00310 ++lineCount_; 00311 } 00312 outCount_ -= len; 00313 } 00314 00315 while(*src != 0 && outCount_ < OUTPUT_BUFFER_SIZE) { 00316 if(*src == '\n') 00317 ++lineCount_; 00318 output_[ outCount_++ ] = *(src++); 00319 } 00320 } 00321 00322 00323 void Console 00324 ::keyPressed(const OIS::KeyEvent* e) { 00325 #ifndef NO_CEGUI 00326 if(editBox_->hasInputFocus()) { 00327 switch(e->key) { 00328 case OIS::KC_RETURN: 00329 output(input_); 00330 output("\n"); 00331 if(handler_) handler_->parseCommand(&input_[2]); 00332 clearInput(); 00333 break; 00334 00335 case OIS::KC_UP: 00336 case OIS::KC_DOWN: 00337 case OIS::KC_PGUP: 00338 case OIS::KC_PGDOWN: 00339 CEGUI::System::getSingleton().injectKeyDown(e->key); 00340 CEGUI::System::getSingleton().injectChar(e->text); 00341 // Don't update console after cursor keys, 00342 // because doing so moves the cursor back to the 00343 // end of the document 00344 return; 00345 00346 case OIS::KC_BACK: 00347 if(inCount_ > 2) { 00348 input_[ --inCount_ ] = 0; 00349 } 00350 break; 00351 } 00352 00353 char ch = e->text; 00354 if(ch && inCount_ < INPUT_BUFFER_SIZE - 1) { 00355 input_[ inCount_++ ] = ch; 00356 input_[ inCount_ ] = 0; 00357 LogDetail("Key: " << inCount_ << " (" << (int)ch << ") " << input_); 00358 } 00359 updateConsole(); 00360 } 00361 else { 00362 CEGUI::System::getSingleton().injectKeyDown(e->key); 00363 CEGUI::System::getSingleton().injectChar(e->text); 00364 } 00365 #else 00366 switch(e->key) { 00367 case OIS::KC_RETURN: 00368 output(input_); 00369 output("\n"); 00370 if(handler_) handler_->parseCommand(&input_[2]); 00371 clearInput(); 00372 break; 00373 00374 case OIS::KC_UP: 00375 case OIS::KC_DOWN: 00376 case OIS::KC_PGUP: 00377 case OIS::KC_PGDOWN: 00378 // Don't update console after cursor keys, 00379 // because doing so moves the cursor back to the 00380 // end of the document 00381 return; 00382 00383 case OIS::KC_BACK: 00384 if(inCount_ > 2) { 00385 input_[ --inCount_ ] = 0; 00386 } 00387 break; 00388 00389 default: 00390 { 00391 unsigned char ch = e->text; 00392 if(ch && inCount_ < INPUT_BUFFER_SIZE - 1) { 00393 input_[ inCount_++ ] = ch; 00394 input_[ inCount_ ] = 0; 00395 //LogDetail("Key: " << inCount_ << " (" << (int)ch << ") " << input_); 00396 } 00397 } 00398 } 00399 00400 updateConsole(); 00401 #endif 00402 } 00403 00404 00405 void Console 00406 ::mouseMoved (const OIS::MouseEvent *e) { 00407 #ifndef NO_CEGUI 00408 CEGUI::System::getSingleton().injectMouseMove( 00409 e->state.X.rel * guiRenderer_->getWidth(), 00410 e->state.Y.rel * guiRenderer_->getHeight()); 00411 #endif 00412 } 00413 00414 00415 void Console 00416 ::mouseDragged (const OIS::MouseEvent *e) { 00417 mouseMoved(e); 00418 } 00419 00420 00421 void Console 00422 ::mousePressed (const OIS::MouseEvent *e, int button) { 00423 #ifndef NO_CEGUI 00424 CEGUI::System::getSingleton().injectMouseButtonDown( 00425 convertOgreButtonToCegui(button)); 00426 #endif 00427 } 00428 00429 00430 void Console 00431 ::mouseReleased (const OIS::MouseEvent *e, int button) { 00432 #ifndef NO_CEGUI 00433 CEGUI::System::getSingleton().injectMouseButtonUp( 00434 convertOgreButtonToCegui(button)); 00435 #endif 00436 } 00437 00438 }
Home Page | SagaEngine trunk (updated nightly) reference generated Sun Dec 2 20:06:05 2007 by Doxygen version 1.3.9.1.