Console.cpp

Go to the documentation of this file.
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.

SourceForge.net Logo