Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/resource/src/orxonox/gamestates/GSDedicated.cc @ 3825

Last change on this file since 3825 was 3355, checked in by rgrieder, 15 years ago

Loading and unloading graphics automatically: As soon as a GameState requires graphics (defined at the GameState declaration with a bool) it gets loaded. And vice versa.

  • Property svn:eol-style set to native
File size: 10.0 KB
RevLine 
[1694]1/*
2 *   ORXONOX - the hottest 3D action shooter ever to exist
3 *                    > www.orxonox.net <
4 *
5 *
6 *   License notice:
7 *
8 *   This program is free software; you can redistribute it and/or
9 *   modify it under the terms of the GNU General Public License
10 *   as published by the Free Software Foundation; either version 2
11 *   of the License, or (at your option) any later version.
12 *
13 *   This program is distributed in the hope that it will be useful,
14 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
15 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 *   GNU General Public License for more details.
17 *
18 *   You should have received a copy of the GNU General Public License
19 *   along with this program; if not, write to the Free Software
20 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
21 *
22 *   Author:
23 *      Reto Grieder
24 *   Co-authors:
25 *      Fabian 'x3n' Landau
26 *
27 */
28
29#include "GSDedicated.h"
30
[3196]31#include "util/Debug.h"
32#include "util/Sleep.h"
[2896]33#include "core/Clock.h"
[1694]34#include "core/CommandLine.h"
[3198]35#include "core/CommandExecutor.h"
[2896]36#include "core/Game.h"
37#include "core/GameMode.h"
[1694]38#include "network/Server.h"
39
[3198]40#include <iostream>
41#include <iomanip>
42#include <boost/bind.hpp>
43
[3304]44#ifdef ORXONOX_PLATFORM_UNIX
[3198]45#include <termios.h>
46#endif
47
48
[1694]49namespace orxonox
50{
[3198]51    const unsigned int MAX_COMMAND_LENGTH = 255;
52   
[3280]53    DeclareGameState(GSDedicated, "dedicated", false, false);
[3198]54   
55    termios* GSDedicated::originalTerminalSettings_;
[2896]56
[3355]57    GSDedicated::GSDedicated(const GameStateInfo& info)
58        : GameState(info)
[1694]59        , server_(0)
[3198]60        , closeThread_(false)
[3205]61        , cleanLine_(true)
[3198]62        , inputIterator_(0)
63        , cursorX_(0)
64        , cursorY_(0)
[1694]65    {
66    }
67
68    GSDedicated::~GSDedicated()
69    {
70    }
71
[2896]72    void GSDedicated::activate()
[1694]73    {
[2896]74        GameMode::setHasServer(true);
[3198]75       
76        this->inputThread_ = new boost::thread(boost::bind(&GSDedicated::inputThread, this));
77       
78#ifndef ORXONOX_PLATFORM_WINDOWS
79        this->originalTerminalSettings_ = new termios;
80        this->setTerminalMode();
81#endif
[1696]82
[2171]83        this->server_ = new Server(CommandLine::getValue("port"));
[2087]84        COUT(0) << "Loading scene in server mode" << std::endl;
[1694]85
86        server_->open();
87    }
88
[2896]89    void GSDedicated::deactivate()
[1694]90    {
91        this->server_->close();
[1755]92        delete this->server_;
[3198]93       
94        closeThread_ = true;
[3304]95#ifdef ORXONOX_PLATFORM_UNIX
[3198]96        std::cout << "\033[0G\033[K";
97        std::cout.flush();
98        resetTerminalMode();
99        delete this->originalTerminalSettings_;
100#endif
[3304]101        COUT(0) << "Press enter to end the game..." << std::endl;
102        inputThread_->join();
103        delete this->inputThread_;
[1694]104
[2896]105        GameMode::setHasServer(false);
[1694]106    }
107
[2896]108    void GSDedicated::update(const Clock& time)
[1694]109    {
[3304]110        server_->update(time);
[3198]111        processQueue();
112        printLine();
[1694]113    }
[3198]114   
115    void GSDedicated::inputThread()
116    {
[3304]117        this->commandLine_ = new unsigned char[MAX_COMMAND_LENGTH];
118//         memset( this->commandLine_, 0, MAX_COMMAND_LENGTH );
[3198]119        unsigned char c;
120        unsigned int  escapeChar=0;
121        while(!closeThread_)
122        {
123            c = getchar();
124            {
125//                 boost::recursive_mutex::scoped_lock(this->inputLineMutex_);
126                if ( inputIterator_>=MAX_COMMAND_LENGTH-1 && c!='\n' )
127                    continue;
128                if( escapeChar > 0 )
129                {
130                    if( c == '[' )
131                    {
132                        escapeChar = 2;
133                        continue;
134                    }
135                    else if ( escapeChar == 2 )
136                    {
137                        switch (c)
138                        {
139                            case 'A': //keyup
140                               
141                                break;
142                            case 'B': //keydown
143                               
144                                break;
145                            case 'C': //keyright
146                                if(cursorX_<inputIterator_)
147                                    ++cursorX_;
148                                break;
149                            case 'D': //keyleft
150                                if(cursorX_>0)
151                                    --cursorX_;
152                                break;
153                            default: //not supported...
154//                                 std::cout << endl << c << endl;
155                                break;
156                        }
157                        escapeChar = 0;
158                    }
159                }
160                else // not in escape sequence mode
161                {
162                    switch (c)
163                    {
164                        case '\n':
165                            this->cleanLine_ = true;
166                            {
167                                boost::recursive_mutex::scoped_lock(this->inputQueueMutex_);
168                                boost::recursive_mutex::scoped_lock(this->inputLineMutex_);
169                                this->commandQueue_.push( std::string((const char*)this->commandLine_,inputIterator_) );
170                            }
171                            memset( this->commandLine_, 0, inputIterator_ );
172                            inputIterator_ = 0;
173                            this->cursorX_ = 0;
174                            this->cursorY_ = 0;
175                            std::cout << endl;
176                            break;
177                        case 127: // backspace
178                        case '\b':
179                            deleteCharacter( this->cursorX_ );
180                            break;
181                        case '\t':
182                        {
183//                             boost::recursive_mutex::scoped_lock(this->inputLineMutex_);
184                            std::cout << endl << CommandExecutor::hint( std::string((const char*)this->commandLine_,inputIterator_) ) << endl;
[3301]185                            strncpy(reinterpret_cast<char*>(this->commandLine_), CommandExecutor::complete( std::string(reinterpret_cast<char*>(this->commandLine_),inputIterator_) ).c_str(), MAX_COMMAND_LENGTH);
[3304]186                            this->inputIterator_ = strlen((const char*)this->commandLine_);
187                            this->cursorX_ = this->inputIterator_;
[3198]188                            break;
189                        }
190                        case '\033': // 1. escape character
191                            escapeChar = 1;
192                            break;
193                        default:
194                            insertCharacter( this->cursorX_, c );
195                            break;
196                    }
197                }
198            }
199        }
[3304]200
201        delete[] this->commandLine_;
[3198]202    }
203   
204    void GSDedicated::printLine()
205    {
[3304]206#ifdef ORXONOX_PLATFORM_UNIX
[3198]207        // set cursor to the begining of the line and erase the line
208        std::cout << "\033[0G\033[K";
209//         boost::recursive_mutex::scoped_lock(this->inputLineMutex_);
210        // print status line
211        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 # ";
212        //save cursor position
213        std::cout << "\033[s";
214        //print commandLine buffer
215        std::cout << std::string((const char*)this->commandLine_, inputIterator_);
216        //restore cursor position and move it cursorX_ to the right
217        std::cout << "\033[u";
218        if( this->cursorX_ > 0 )
219            std::cout << "\033[" << this->cursorX_ << "C";
220        std::cout.flush();
221#endif
222    }
223   
224    void GSDedicated::processQueue()
225    {
226        std::string tempstr;
227        {
228            boost::recursive_mutex::scoped_lock lock1(this->inputQueueMutex_);
229            while(true)
230            {
231                if ( !this->commandQueue_.empty() )
232                {
233                    tempstr = this->commandQueue_.front();
234                    this->commandQueue_.pop();
235                    lock1.unlock();
236                }
237                else
238                    break;
239                CommandExecutor::execute(tempstr, true);
240            }
241        }
242    }
243   
244    void GSDedicated::setTerminalMode()
245    {
[3304]246#ifdef ORXONOX_PLATFORM_UNIX
[3198]247        termios new_settings;
248     
249        tcgetattr(0,this->originalTerminalSettings_);
250        new_settings = *this->originalTerminalSettings_;
251        new_settings.c_lflag &= ~( ICANON | ECHO );
252//         new_settings.c_lflag |= ( ISIG | IEXTEN );
253        new_settings.c_cc[VTIME] = 0;
254        new_settings.c_cc[VMIN] = 1;
255        tcsetattr(0,TCSANOW,&new_settings);
256        COUT(0) << endl;
257//       atexit(&GSDedicated::resetTerminalMode);
258#endif
259    }
260   
261    void GSDedicated::resetTerminalMode()
262    {
[3304]263#ifdef ORXONOX_PLATFORM_UNIX
[3198]264        tcsetattr(0, TCSANOW, GSDedicated::originalTerminalSettings_);
265#endif
266    }
267   
268    void GSDedicated::insertCharacter( unsigned int position, char c )
269    {
[3301]270//         std::cout << endl << static_cast<unsigned int>(c) << endl;
[3198]271        // check that we do not exceed MAX_COMMAND_LENGTH
272        if( inputIterator_+1 < MAX_COMMAND_LENGTH )
273        {
274            // if cursor not at end of line then move the rest of the line
275            if( position != this->inputIterator_ )
276                    memmove( this->commandLine_+position+1, this->commandLine_+position, this->inputIterator_-position);
277//             boost::recursive_mutex::scoped_lock(this->inputLineMutex_);
278            this->commandLine_[position] = c;
279            ++this->cursorX_;
280            ++this->inputIterator_;
281        }
282    }
283    void GSDedicated::deleteCharacter( unsigned int position )
284    {
285//         boost::recursive_mutex::scoped_lock(this->inputLineMutex_);
286        if ( this->inputIterator_>0 && position>0 )
287        {
288            if ( position != this->inputIterator_ )
289                memmove( this->commandLine_+position-1, this->commandLine_+position, this->inputIterator_-position);
290            --this->cursorX_;
291            --this->inputIterator_;
292        }
293    }
294   
[1694]295}
Note: See TracBrowser for help on using the repository browser.