Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/trunk/src/lib/shell/shell.cc @ 7286

Last change on this file since 7286 was 7221, checked in by bensch, 19 years ago

orxonox/trunk: merged the std-branche back, it runs on windows and Linux

svn merge https://svn.orxonox.net/orxonox/branches/std . -r7202:HEAD

File size: 14.2 KB
RevLine 
[4744]1/*
[1853]2   orxonox - the future of 3D-vertical-scrollers
3
4   Copyright (C) 2004 orx
5
6   This program is free software; you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation; either version 2, or (at your option)
9   any later version.
[1855]10
11   ### File Specific:
[5068]12   main-programmer: Benjamin Grauer
[1855]13   co-programmer: ...
[1853]14*/
15
[3955]16//#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_
[1853]17
[5068]18#include "shell.h"
[5129]19#include "shell_command.h"
[5175]20#include "shell_buffer.h"
[5179]21#include "shell_input.h"
[1853]22
[5175]23
[5344]24#include "text.h"
[5093]25#include "graphics_engine.h"
[5372]26#include "material.h"
[5093]27#include "event_handler.h"
[5129]28#include "debug.h"
[5113]29#include "class_list.h"
30
31#include "key_names.h"
[5075]32#include <stdarg.h>
33#include <stdio.h>
34
[1856]35using namespace std;
[1853]36
[5201]37SHELL_COMMAND(clear, Shell, clear)
38    ->describe("Clears the shell from unwanted lines (empties all buffers)")
39    ->setAlias("clear");
40SHELL_COMMAND(deactivate, Shell, deactivate)
41    ->describe("Deactivates the Shell. (moves it into background)")
[5204]42    ->setAlias("hide");
[5208]43SHELL_COMMAND(textsize, Shell, setTextSize)
[5374]44    ->describe("Sets the size of the Text size, linespacing")
[7198]45    ->defaultValues(15, 0);
[5374]46SHELL_COMMAND(textcolor, Shell, setTextColor)
47    ->describe("Sets the Color of the Shells Text (red, green, blue, alpha)")
[7198]48    ->defaultValues(SHELL_DEFAULT_TEXT_COLOR);
[5374]49SHELL_COMMAND(backgroundcolor, Shell, setBackgroundColor)
50    ->describe("Sets the Color of the Shells Background (red, green, blue, alpha)")
[7198]51    ->defaultValues(SHELL_DEFAULT_BACKGROUND_COLOR);
[5374]52SHELL_COMMAND(backgroundimage, Shell, setBackgroundImage)
53    ->describe("sets the background image to load for the Shell");
[5254]54SHELL_COMMAND(font, Shell, setFont)
55    ->describe("Sets the font of the Shell")
[7198]56    ->defaultValues(SHELL_DEFAULT_FONT);
[1856]57
[3245]58/**
[4838]59 * standard constructor
[5068]60 */
61Shell::Shell ()
[3365]62{
[5072]63  this->setClassID(CL_SHELL, "Shell");
64  this->setName("Shell");
65
[5245]66  // EVENT-Handler subscription of '`' to all States.
67  EventHandler::getInstance()->subscribe(this, ES_ALL, SDLK_BACKQUOTE);
[5425]68  EventHandler::getInstance()->subscribe(this, ES_ALL, SDLK_F12);
[5246]69  EventHandler::getInstance()->subscribe(this, ES_SHELL, SDLK_PAGEUP);
70  EventHandler::getInstance()->subscribe(this, ES_SHELL, SDLK_PAGEDOWN);
[5206]71
[5372]72  // BUFFER
73  this->bufferText = NULL;
74  this->bufferDisplaySize = 10;
75  this->bufferOffset = 0;
[5781]76  this->bufferIterator = ShellBuffer::getInstance()->getBuffer()->begin();
[5372]77
78  // INPUT LINE
79  this->shellInput = new ShellInput;
80
81  this->backgroundMaterial = new Material;
[5183]82  // Element2D and generals
[5175]83  this->setAbsCoor2D(3, -400);
[5329]84  this->textSize = 20;
[5208]85  this->lineSpacing = 0;
[5420]86  this->bActive = true;
[7221]87  this->fontFile = SHELL_DEFAULT_FONT;
[5072]88
[5080]89
[5113]90  this->rebuildText();
[5374]91
[5372]92  this->setTextColor(SHELL_DEFAULT_TEXT_COLOR);
93  this->setBackgroundColor(SHELL_DEFAULT_BACKGROUND_COLOR);
[5335]94
[5420]95  this->deactivate();
[5335]96  // register the shell at the ShellBuffer
97  ShellBuffer::getInstance()->registerShell(this);
[5068]98}
[4320]99
[3245]100/**
[4838]101 * standard deconstructor
[5068]102 */
103Shell::~Shell ()
[3543]104{
[5335]105  ShellBuffer::getInstance()->unregisterShell(this);
106
[5099]107  // delete the displayable Buffers
[5227]108  for (unsigned int i = 0; i < this->bufferDisplaySize; i++)
[5080]109    delete this->bufferText[i];
[5113]110  delete[] this->bufferText;
[5099]111  // delete the inputLine
[5180]112  delete this->shellInput;
[5372]113  delete this->backgroundMaterial;
[3543]114}
[5068]115
[5119]116/**
117 * activates the shell
118 *
119 * This also feeds the Last few lines from the main buffers into the displayBuffer
120 */
[5113]121void Shell::activate()
122{
123  if (this->bActive == true)
124    PRINTF(3)("The shell is already active\n");
125  this->bActive = true;
126
[5388]127  EventHandler::getInstance()->pushState(ES_SHELL);
[5786]128  EventHandler::getInstance()->withUNICODE(true);
129
[5113]130  this->setRelCoorSoft2D(0, 0, 1, 5);
[5118]131
[5787]132  list<char*>::const_iterator textLine = --ShellBuffer::getInstance()->getBuffer()->end();
133  bool top = false;
[5246]134  for (int i = 0; i < this->bufferDisplaySize; i++)
[5247]135  {
[5420]136    this->bufferText[i]->setVisibility(true);
[5787]137    if (!top)
138    {
[7221]139      this->bufferText[i]->setText((*textLine));
[5787]140    if (textLine != ShellBuffer::getInstance()->getBuffer()->begin())
141      top = true;
142      textLine--;
143    }
[5247]144  }
[5113]145}
146
[5119]147/**
148 * deactiveates the Shell.
149 */
[5113]150void Shell::deactivate()
151{
152  if (this->bActive == false)
153    PRINTF(3)("The shell is already inactive\n");
154  this->bActive = false;
155
[5786]156  EventHandler::getInstance()->withUNICODE(false);
[5388]157  EventHandler::getInstance()->popState();
158
[5253]159  this->setRelCoorSoft2D(0, -(int)this->shellHeight, 1, 5);
[5118]160
[5787]161  list<char*>::const_iterator textLine = --ShellBuffer::getInstance()->getBuffer()->end();
[5157]162  for (int i = 0; i < this->bufferDisplaySize; i++)
[5247]163  {
[5420]164    this->bufferText[i]->setVisibility(false);
[5787]165    if (textLine != ShellBuffer::getInstance()->getBuffer()->begin())
166    {
[7221]167      this->bufferText[i]->setText((*textLine));
[5787]168      textLine--;
169    }
[5247]170  }
[5248]171  this->bufferOffset = 0;
[5113]172}
173
[5119]174/**
[5251]175 * sets the File to load the fonts from
176 * @param fontFile the file to load the font from
[5254]177 *
178 * it is quite important, that the font pointed too really exists!
179 * (be aware that within orxonox fontFile is relative to the Data-Dir)
[5251]180 */
[7221]181void Shell::setFont(const std::string& fontFile)
[5251]182{
[5335]183//   if (!ResourceManager::isInDataDir(fontFile))
184//     return false;
185
[7221]186  this->fontFile = fontFile;
[5251]187
[5253]188  this->rebuildText();
[5251]189}
190
191/**
[5119]192 * sets the size of the text and spacing
193 * @param textSize the size of the Text in Pixels
194 * @param lineSpacing the size of the Spacing between two lines in pixels
195 *
196 * this also rebuilds the entire Text, inputLine and displayBuffer,
197 * to be accurate again.
198 */
[5113]199void Shell::setTextSize(unsigned int textSize, unsigned int lineSpacing)
200{
201  this->textSize = textSize;
202  this->lineSpacing = lineSpacing;
[5372]203  this->resetValues();
204}
[5113]205
[5372]206/**
207 * sets the color of the Font.
208 * @param r: red
209 * @param g: green
210 * @param b: blue
211 * @param a: alpha-value.
212 */
213void Shell::setTextColor(float r, float g, float b, float a)
214{
215  this->textColor[0] = r;
216  this->textColor[1] = g;
217  this->textColor[2] = b;
218  this->textColor[3] = a;
219
220  this->resetValues();
221}
222
223
224/**
225 * sets the color of the Backgrond.
226 * @param r: red
227 * @param g: green
228 * @param b: blue
229 * @param a: alpha-value.
230 */
231void Shell::setBackgroundColor(float r, float g, float b, float a)
232{
233  this->backgroundMaterial->setDiffuse(r, g, b);
234  this->backgroundMaterial->setTransparency(a);
235}
236
237/**
[5374]238 * sets a nice background image to the Shell's background
239 * @param fileName the filename of the Image to load
240 */
[7221]241void Shell::setBackgroundImage(const std::string& fileName)
[5374]242{
243  this->backgroundMaterial->setDiffuseMap(fileName);
244}
245
246
247/**
[5372]248 * resets the Values of all visible shell's commandos to the Shell's stored values
249 *
250 * this functions synchronizes the stored Data with the visible one.
251 */
252void Shell::resetValues()
253{
254  if (this->shellInput != NULL)
255  {
256    this->shellInput->setSize(this->textSize);
257    this->shellInput->setColor(this->textColor[0], this->textColor[1], this->textColor[2]);
258    this->shellInput->setBlending(this->textColor[3]);
[5420]259    this->shellInput->setRelCoor2D(5, (this->textSize + this->lineSpacing)*(this->bufferDisplaySize));
[5372]260  }
261
[5369]262  if (this->bufferText != NULL)
263  {
264    for (unsigned int i = 0; i < this->bufferDisplaySize; i++)
265    {
266      if (this->bufferText[i] != NULL)
267      {
268        this->bufferText[i]->setSize(this->textSize);
[5372]269        this->bufferText[i]->setColor(this->textColor[0], this->textColor[1], this->textColor[2]);
270        this->bufferText[i]->setBlending(this->textColor[3]);
271        this->bufferText[i]->setRelCoor2D(calculateLinePosition(i));
[5369]272      }
273    }
274  }
275  this->shellHeight = (this->textSize + this->lineSpacing) * (bufferDisplaySize+1);
[5113]276}
277
[5127]278/**
279 * rebuilds the Text's
280 *
281 * use this function, if you changed the Font/Size or something else.
282 */
[5113]283void Shell::rebuildText()
284{
[5251]285  this->shellInput->setFont(this->fontFile, this->textSize);
[5179]286  this->shellInput->setAlignment(TEXT_ALIGN_LEFT);
[5397]287  if (shellInput->getParent2D() != this)
[5253]288    this->shellInput->setParent2D(this);
[5113]289
290  this->setBufferDisplaySize(this->bufferDisplaySize);
291}
292
[5074]293/**
294 * sets The count of Lines to display in the buffer.
295 * @param bufferDisplaySize the count of lines to display in the Shell-Buffer.
296 */
[5072]297void Shell::setBufferDisplaySize(unsigned int bufferDisplaySize)
298{
[5251]299  Text** bufferText = this->bufferText;
300  this->bufferText = NULL;
301  if (bufferText != NULL)
[5072]302  {
[5080]303    for (unsigned int i = 0; i < this->bufferDisplaySize; i++)
[5251]304      delete bufferText[i];
305    delete[] bufferText;
[5072]306  }
[5080]307
[5787]308  list<char*>::const_iterator textLine = --ShellBuffer::getInstance()->getBuffer()->end();
[5251]309  bufferText = new Text*[bufferDisplaySize];
[5080]310  for (unsigned int i = 0; i < bufferDisplaySize; i++)
[5072]311  {
[5767]312    bufferText[i] = new Text(this->fontFile, this->textSize);
[5251]313    bufferText[i]->setAlignment(TEXT_ALIGN_LEFT);
314    bufferText[i]->setParent2D(this);
[5787]315    if(textLine != ShellBuffer::getInstance()->getBuffer()->begin())
316    {
317      bufferText[i]->setText(*textLine);
318      textLine--;
319    }
[5072]320  }
[5113]321  this->bufferDisplaySize = bufferDisplaySize;
[5111]322
[5251]323  this->bufferText = bufferText;
[5113]324  this->shellHeight = (this->textSize + this->lineSpacing) * (bufferDisplaySize+1);
[5072]325}
[5068]326
327/**
328 * deletes all the Buffers
329 */
[5175]330void Shell::flush()
[5068]331{
[5072]332  // remove all chars from the BufferTexts.
[5251]333  if (this->bufferText != NULL)
[5125]334    for (int i = 0; i < this->bufferDisplaySize; i++)
[5080]335    {
[7221]336      this->bufferText[i]->setText("");
[5080]337    }
[5246]338
339    ShellBuffer::getInstance()->flush();
340    // BUFFER FLUSHING
[5068]341}
342
343/**
[5118]344 * prints out some text to the input-buffers
345 * @param text the text to output.
346 */
[7221]347void Shell::printToDisplayBuffer(const std::string& text)
[5118]348{
349  if(likely(bufferText != NULL))
350  {
351    Text* lastText = this->bufferText[this->bufferDisplaySize-1];
[5113]352
[5118]353    Text* swapText;
354    Text* moveText = this->bufferText[0];
[5375]355    for (unsigned int i = 0; i < this->bufferDisplaySize; i++)
[5118]356    {
357      if ( i < this->bufferDisplaySize-1)
[5375]358        this->bufferText[i]->setRelCoorSoft2D(this->calculateLinePosition(i+1), 5);
[5118]359      swapText = this->bufferText[i];
[5375]360      this->bufferText[i] = moveText;
[5118]361      moveText = swapText;
362    }
[5375]363
364  /*  FANCY EFFECTS :)
[5376]365    1:
[5375]366        lastText->setRelCoor2D(this->calculateLinePosition(0)- Vector(-1000,0,0));
367        lastText->setRelCoorSoft2D(this->calculateLinePosition(0),10);
[5376]368    2:
[5377]369  */
[5383]370    lastText->setRelDir2D(-90);
371    lastText->setRelDirSoft2D(0, 20);
[5376]372    lastText->setRelCoor2D(this->calculateLinePosition(0)- Vector(-1000,0,0));
373    lastText->setRelCoorSoft2D(this->calculateLinePosition(0),10);
[5377]374
375 //   lastText->setRelCoor2D(this->calculateLinePosition(0));
[5118]376    this->bufferText[0] = lastText;
377
[7221]378    this->bufferText[0]->setText(text);
[5118]379  }
[5068]380}
381
382/**
[5783]383 * moves the Display buffer (up + or down - )
[5246]384 * @param lineCount the count by which to shift the InputBuffer.
[5783]385 *
386 * @todo make this work
[5246]387 */
388void Shell::moveDisplayBuffer(int lineCount)
389{
[5783]390  if (this->bufferOffset == 0)
391   {
392     this->bufferIterator = ShellBuffer::getInstance()->getBuffer()->end();
393//     for (unsigned int i = 0; i < this->bufferDisplaySize; i++)
[5248]394//       this->bufferIterator->prevStep();
[5783]395   }
396
397  // boundraries
398  if (this->bufferOffset + lineCount > (int)ShellBuffer::getInstance()->getBuffer()->size())
399    lineCount = (int)ShellBuffer::getInstance()->getBuffer()->size()- this->bufferOffset;
400  else if (this->bufferOffset + lineCount < 0)
401    lineCount = -bufferOffset;
402  this->bufferOffset += lineCount;
403
404  // moving the iterator to the right position
405  int move = 0;
406  while (move != lineCount)
407  {
408    if (move < lineCount)
409    {
410      ++move;
411      this->bufferIterator--;
412    }
413    else
414    {
415      --move;
416      this->bufferIterator++;
417    }
418  }
419  // redisplay the buffers
420  list<char*>::const_iterator it = this->bufferIterator;
421  for (unsigned int i = 0; i < this->bufferDisplaySize; i++)
422  {
[7221]423    this->bufferText[i]->setText((*it));
[5783]424    it--;
425  }
[5246]426}
427
428/**
[5166]429 * clears the Shell (empties all buffers)
430 */
[5130]431void Shell::clear()
432{
[5175]433  this->flush();
434  ShellBuffer::addBufferLineStatic("orxonox - shell\n ==================== \n", NULL);
[5130]435}
436
[5069]437/**
438 * listens for some event
439 * @param event the Event happened
440 */
441void Shell::process(const Event &event)
442{
[5093]443  if (event.bPressed)
444  {
[5425]445    if (event.type == SDLK_BACKQUOTE || event.type == SDLK_F12)
[5093]446    {
[5388]447      if (this->bActive == false)
[5113]448        this->activate();
[5093]449      else
[5113]450        this->deactivate();
[5093]451    }
[5246]452    else if (event.type == SDLK_PAGEUP)
453    {
[5248]454      this->moveDisplayBuffer(+this->bufferDisplaySize-1);
[5246]455    }
456    else if (event.type == SDLK_PAGEDOWN)
457    {
[5248]458      this->moveDisplayBuffer(-this->bufferDisplaySize+1);
[5246]459    }
[5093]460  }
[5069]461}
462
[5068]463/**
464 * displays the Shell
465 */
466void Shell::draw() const
467{
[5099]468  // transform for alignment.
469  // setting the Blending effects
470
[5372]471  this->backgroundMaterial->select();
[5099]472
[5158]473  glBegin(GL_TRIANGLE_STRIP);
[5099]474
[5158]475  glTexCoord2f(0, 0);
[5099]476  glVertex2f(this->getAbsCoor2D().x,   this->getAbsCoor2D().);
477
[5158]478  glTexCoord2f(1, 0);
[5113]479  glVertex2f(GraphicsEngine::getInstance()->getResolutionX() - this->getAbsCoor2D().x, this->getAbsCoor2D().);
[5099]480
[5158]481  glTexCoord2f(0, 1);
482  glVertex2f(this->getAbsCoor2D().x, this->getAbsCoor2D().y + this->shellHeight);
483
484  glTexCoord2f(1, 1);
[5113]485  glVertex2f(GraphicsEngine::getInstance()->getResolutionX() - this->getAbsCoor2D().x, this->getAbsCoor2D().y + this->shellHeight);
[5099]486
487  glEnd();
[5068]488}
489
[5120]490///////////////////////
491// HELPER FUNCTIONS  //
492///////////////////////
[5166]493
494/**
495 * calculates the position of a Buffer-Display Line
496 * @param lineNumber the lineNumber from the bottom to calculate the position from
497 * @returns the Position of the Line.
498 */
[5120]499Vector Shell::calculateLinePosition(unsigned int lineNumber)
500{
[5420]501  return Vector(5, (this->textSize + this->lineSpacing)*(this->bufferDisplaySize - lineNumber - 2) + this->textSize, 0);
[5120]502}
503
504
505
[5113]506/**
[5068]507 * displays some nice output from the Shell
508 */
509void Shell::debug() const
510{
[5119]511  PRINT(3)("Debugging output to console (not this shell)\n");
512
[5180]513//   if (this->pressedKey != SDLK_FIRST)
514//     printf("%s::%f %f\n", SDLKToKeyname(this->pressedKey), this->delayed, this->repeatDelay);
[5119]515
516
[5177]517  ShellBuffer::getInstance()->debug();
[5068]518}
[5166]519
520// void Shell::testI (int i)
521// {
522//   PRINTF(3)("This is the Test for one Int '%d'\n", i);
523// }
524//
525// void Shell::testS (const char* s)
526// {
527//   PRINTF(3)("This is the Test for one String '%s'\n", s);
528// }
529//
530// void Shell::testB (bool b)
531// {
532//   PRINTF(3)("This is the Test for one Bool: ");
533//   if (b)
534//     PRINTF(3)("true\n");
535//   else
536//     PRINTF(3)("false\n");
537// }
538//
539// void Shell::testF (float f)
540// {
541//   PRINTF(3)("This is the Test for one Float '%f'\n", f);
542// }
543//
544// void Shell::testSF (const char* s, float f)
545// {
546//   PRINTF(3)("This is the Test for one String '%s' and one Float '%f'\n",s , f);
547// }
Note: See TracBrowser for help on using the repository browser.