- Timestamp:
- Nov 2, 2009, 6:06:25 PM (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
code/branches/console/src/orxonox/gamestates/GSDedicated.cc
r5929 r6016 29 29 #include "GSDedicated.h" 30 30 31 #include <iomanip>32 #include <iostream>33 #include <boost/bind.hpp>34 35 #include "util/Clock.h"36 31 #include "util/Debug.h" 37 #include "util/Sleep.h"38 32 #include "core/CommandLine.h" 39 #include "core/CommandExecutor.h"40 33 #include "core/Game.h" 41 34 #include "core/GameMode.h" 42 35 #include "network/Server.h" 43 36 44 #ifdef ORXONOX_PLATFORM_UNIX45 #include <termios.h>46 #endif47 48 49 37 namespace orxonox 50 38 { 51 const unsigned int MAX_COMMAND_LENGTH = 255;52 53 39 DeclareGameState(GSDedicated, "dedicated", false, false); 54 40 55 termios* GSDedicated::originalTerminalSettings_;56 57 41 GSDedicated::GSDedicated(const GameStateInfo& info) 58 42 : GameState(info) 59 43 , server_(0) 60 , closeThread_(false)61 , cleanLine_(true)62 , inputIterator_(0)63 , cursorX_(0)64 , cursorY_(0)65 44 { 66 45 } … … 73 52 { 74 53 GameMode::setHasServer(true); 75 76 this->inputThread_ = new boost::thread(boost::bind(&GSDedicated::inputThread, this));77 78 #ifndef ORXONOX_PLATFORM_WINDOWS79 this->originalTerminalSettings_ = new termios;80 this->setTerminalMode();81 #endif82 54 83 55 this->server_ = new Server(CommandLine::getValue("port")); … … 91 63 this->server_->close(); 92 64 delete this->server_; 93 94 closeThread_ = true;95 #ifdef ORXONOX_PLATFORM_UNIX96 std::cout << "\033[0G\033[K";97 std::cout.flush();98 resetTerminalMode();99 delete this->originalTerminalSettings_;100 #else101 COUT(0) << "Press enter to end the game..." << std::endl;102 #endif103 inputThread_->join();104 delete this->inputThread_;105 65 106 66 GameMode::setHasServer(false); … … 110 70 { 111 71 server_->update(time); 112 processQueue();113 printLine();114 72 } 115 116 void GSDedicated::inputThread()117 {118 this->commandLine_ = new unsigned char[MAX_COMMAND_LENGTH];119 // memset( this->commandLine_, 0, MAX_COMMAND_LENGTH );120 unsigned char c;121 unsigned int escapeChar=0;122 while(!closeThread_)123 {124 #ifdef ORXONOX_PLATFORM_UNIX125 size_t count = read(STDIN_FILENO, &c, 1);126 if (count == 1)127 #else128 c = getchar();129 #endif130 {131 // boost::recursive_mutex::scoped_lock(this->inputLineMutex_);132 if ( inputIterator_>=MAX_COMMAND_LENGTH-1 && c!='\n' )133 continue;134 if( escapeChar > 0 )135 {136 if( c == '[' )137 {138 escapeChar = 2;139 continue;140 }141 else if ( escapeChar == 2 )142 {143 switch (c)144 {145 case 'A': //keyup146 147 break;148 case 'B': //keydown149 150 break;151 case 'C': //keyright152 if(cursorX_<inputIterator_)153 ++cursorX_;154 break;155 case 'D': //keyleft156 if(cursorX_>0)157 --cursorX_;158 break;159 default: //not supported...160 // std::cout << endl << c << endl;161 break;162 }163 escapeChar = 0;164 }165 }166 else // not in escape sequence mode167 {168 switch (c)169 {170 case '\n':171 this->cleanLine_ = true;172 {173 boost::recursive_mutex::scoped_lock(this->inputQueueMutex_);174 boost::recursive_mutex::scoped_lock(this->inputLineMutex_);175 this->commandQueue_.push( std::string((const char*)this->commandLine_,inputIterator_) );176 }177 memset( this->commandLine_, 0, inputIterator_ );178 inputIterator_ = 0;179 this->cursorX_ = 0;180 this->cursorY_ = 0;181 std::cout << endl;182 break;183 case 127: // backspace184 case '\b':185 deleteCharacter( this->cursorX_ );186 break;187 case '\t':188 {189 // boost::recursive_mutex::scoped_lock(this->inputLineMutex_);190 std::cout << endl << CommandExecutor::hint( std::string((const char*)this->commandLine_,inputIterator_) ) << endl;191 strncpy(reinterpret_cast<char*>(this->commandLine_), CommandExecutor::complete( std::string(reinterpret_cast<char*>(this->commandLine_),inputIterator_) ).c_str(), MAX_COMMAND_LENGTH);192 this->inputIterator_ = strlen((const char*)this->commandLine_);193 this->cursorX_ = this->inputIterator_;194 break;195 }196 case '\033': // 1. escape character197 escapeChar = 1;198 break;199 default:200 insertCharacter( this->cursorX_, c );201 break;202 }203 }204 }205 }206 207 delete[] this->commandLine_;208 }209 210 void GSDedicated::printLine()211 {212 #ifdef ORXONOX_PLATFORM_UNIX213 // set cursor to the begining of the line and erase the line214 std::cout << "\033[0G\033[K";215 // boost::recursive_mutex::scoped_lock(this->inputLineMutex_);216 // print status line217 std::cout << std::fixed << std::setprecision(2) << std::setw(5) << Game::getInstance().getAvgFPS() << " fps, " << std::setprecision(2) << std::setw(5) << Game::getInstance().getAvgTickTime() << " ms avg ticktime # ";218 //save cursor position219 std::cout << "\033[s";220 //print commandLine buffer221 std::cout << std::string((const char*)this->commandLine_, inputIterator_);222 //restore cursor position and move it cursorX_ to the right223 std::cout << "\033[u";224 if( this->cursorX_ > 0 )225 std::cout << "\033[" << this->cursorX_ << "C";226 std::cout.flush();227 #endif228 }229 230 void GSDedicated::processQueue()231 {232 std::string tempstr;233 {234 boost::recursive_mutex::scoped_lock lock1(this->inputQueueMutex_);235 while(true)236 {237 if ( !this->commandQueue_.empty() )238 {239 tempstr = this->commandQueue_.front();240 this->commandQueue_.pop();241 lock1.unlock();242 }243 else244 break;245 CommandExecutor::execute(tempstr, true);246 }247 }248 }249 250 void GSDedicated::setTerminalMode()251 {252 #ifdef ORXONOX_PLATFORM_UNIX253 termios new_settings;254 255 tcgetattr(0,this->originalTerminalSettings_);256 new_settings = *this->originalTerminalSettings_;257 new_settings.c_lflag &= ~( ICANON | ECHO );258 // new_settings.c_lflag |= ( ISIG | IEXTEN );259 new_settings.c_cc[VTIME] = 1;260 new_settings.c_cc[VMIN] = 0;261 tcsetattr(0,TCSANOW,&new_settings);262 COUT(0) << endl;263 // atexit(&GSDedicated::resetTerminalMode);264 #endif265 }266 267 void GSDedicated::resetTerminalMode()268 {269 #ifdef ORXONOX_PLATFORM_UNIX270 tcsetattr(0, TCSANOW, GSDedicated::originalTerminalSettings_);271 #endif272 }273 274 void GSDedicated::insertCharacter( unsigned int position, char c )275 {276 // std::cout << endl << static_cast<unsigned int>(c) << endl;277 // check that we do not exceed MAX_COMMAND_LENGTH278 if( inputIterator_+1 < MAX_COMMAND_LENGTH )279 {280 // if cursor not at end of line then move the rest of the line281 if( position != this->inputIterator_ )282 memmove( this->commandLine_+position+1, this->commandLine_+position, this->inputIterator_-position);283 // boost::recursive_mutex::scoped_lock(this->inputLineMutex_);284 this->commandLine_[position] = c;285 ++this->cursorX_;286 ++this->inputIterator_;287 }288 }289 void GSDedicated::deleteCharacter( unsigned int position )290 {291 // boost::recursive_mutex::scoped_lock(this->inputLineMutex_);292 if ( this->inputIterator_>0 && position>0 )293 {294 if ( position != this->inputIterator_ )295 memmove( this->commandLine_+position-1, this->commandLine_+position, this->inputIterator_-position);296 --this->cursorX_;297 --this->inputIterator_;298 }299 }300 301 73 }
Note: See TracChangeset
for help on using the changeset viewer.