Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/trunk/src/util/shell.cc @ 5127

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

orxonox/trunk: now it is possible to add multi-non-newLine printf's into the Shell.
This is especially good, to print multiple entities from a loop onto the same line

File size: 21.2 KB
Line 
1/*
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.
10
11   ### File Specific:
12   main-programmer: Benjamin Grauer
13   co-programmer: ...
14*/
15
16//#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_
17
18#include "shell.h"
19
20#include "text_engine.h"
21#include "list.h"
22#include "graphics_engine.h"
23#include "event_handler.h"
24
25#include "load_param.h"
26#include "class_list.h"
27
28#include "key_names.h"
29#include "debug.h"
30#include <stdarg.h>
31#include <stdio.h>
32
33using namespace std;
34
35
36/**
37 * standard constructor
38 */
39Shell::Shell ()
40{
41  this->setClassID(CL_SHELL, "Shell");
42  this->setName("Shell");
43
44  this->keepBufferArray[0] = '\0';
45  this->keepBuffer = false;
46
47  this->bActive = false;
48  this->buffer = new tList<char>;
49  this->bufferIterator = this->buffer->getIterator();
50
51  this->textSize = 15;
52  this->lineSpacing = 5;
53
54  //this->bufferSize = 0;
55  this->bufferText = NULL;
56  this->setBufferSize(100);
57  this->bufferDisplaySize = 10;
58  this->setAbsCoor2D(3, -400);
59  this->delayed = 0;
60  this->setRepeatDelay(.3, .05);
61  this->pressedKey = SDLK_FIRST;
62
63  this->inputLineText = NULL;
64  this->inputLine = new char[1];
65  this->inputLine[0] = '\0';
66
67  this->rebuildText();
68  this->completionList = NULL;
69
70  // EVENT-Handler subscription of '`' to all States, and all other keyboard commands to ES_SEHLL
71  EventHandler* evh = EventHandler::getInstance();
72  evh->subscribe(this, ES_ALL, SDLK_BACKQUOTE);
73  for (int i = 1; i < SDLK_LAST; i++)
74    evh->subscribe(this, ES_SHELL, i);
75}
76
77Shell* Shell::singletonRef = NULL;
78
79/**
80 * standard deconstructor
81 */
82Shell::~Shell ()
83{
84  // delete the displayable Buffers
85  for (int i = 0; i < this->bufferDisplaySize; i++)
86    delete this->bufferText[i];
87  delete[] this->bufferText;
88
89  // delete the inputLine
90  delete this->inputLineText;
91  delete this->inputLine;
92
93  // delete all the Chars in the Buffers
94  char* charElem = this->bufferIterator->firstElement();
95  while (charElem != NULL)
96  {
97    delete charElem;
98    charElem = this->bufferIterator->nextElement();
99  }
100  delete this->bufferIterator;
101
102//  if (this->completionList != NULL)
103    //delete this->completionList;
104
105  Shell::singletonRef = NULL;
106}
107
108
109/**
110 * activates the shell
111 *
112 * This also feeds the Last few lines from the main buffers into the displayBuffer
113 */
114void Shell::activate()
115{
116  if (this->bActive == true)
117    PRINTF(3)("The shell is already active\n");
118  this->bActive = true;
119
120  EventHandler::getInstance()->setState(ES_SHELL);
121  this->setRelCoorSoft2D(0, 0, 1, 5);
122
123  this->bufferIterator->lastElement();
124  for (int i = 0; i < this->bufferDisplaySize; i++)
125    this->bufferText[i]->setText(this->bufferIterator->prevElement());
126}
127
128/**
129 * deactiveates the Shell.
130 */
131void Shell::deactivate()
132{
133  if (this->bActive == false)
134    PRINTF(3)("The shell is already inactive\n");
135  this->bActive = false;
136
137  EventHandler::getInstance()->setState(ES_GAME);
138  this->setRelCoorSoft2D(0, -400, 1, 5);
139
140}
141
142/**
143 * sets the size of the text and spacing
144 * @param textSize the size of the Text in Pixels
145 * @param lineSpacing the size of the Spacing between two lines in pixels
146 *
147 * this also rebuilds the entire Text, inputLine and displayBuffer,
148 * to be accurate again.
149 */
150void Shell::setTextSize(unsigned int textSize, unsigned int lineSpacing)
151{
152  this->textSize = textSize;
153  this->lineSpacing = lineSpacing;
154
155  this->rebuildText();
156}
157
158/**
159 * rebuilds the Text's
160 *
161 * use this function, if you changed the Font/Size or something else.
162 */
163void Shell::rebuildText()
164{
165  if (this->inputLineText == NULL)
166    delete this->inputLineText;
167  this->inputLineText = TextEngine::getInstance()->createText("fonts/Aniron_Bold.ttf", this->textSize, TEXT_RENDER_DYNAMIC);
168  this->inputLineText->setColor(1, 0, 0);
169  this->inputLineText->setAlignment(TEXT_ALIGN_LEFT);
170  this->inputLineText->setText(NULL);
171  this->inputLineText->setParent2D(this);
172  this->inputLineText->setRelCoor2D(5, (this->textSize + this->lineSpacing)*this->bufferDisplaySize + this->textSize);
173
174  this->setBufferDisplaySize(this->bufferDisplaySize);
175}
176
177/**
178 * sets The count of Lines to display in the buffer.
179 * @param bufferDisplaySize the count of lines to display in the Shell-Buffer.
180 */
181void Shell::setBufferDisplaySize(unsigned int bufferDisplaySize)
182{
183  if (this->bufferText != NULL)
184  {
185    for (unsigned int i = 0; i < this->bufferDisplaySize; i++)
186      delete this->bufferText[i];
187    delete[] this->bufferText;
188  }
189
190  this->bufferText = new Text*[bufferDisplaySize];
191  for (unsigned int i = 0; i < bufferDisplaySize; i++)
192  {
193    this->bufferText[i] = TextEngine::getInstance()->createText("fonts/Aniron_Bold.ttf", this->textSize, TEXT_RENDER_DYNAMIC);
194    this->bufferText[i]->setColor(1, 0, 0);
195    this->bufferText[i]->setAlignment(TEXT_ALIGN_LEFT);
196    this->bufferText[i]->setRelCoor2D(calculateLinePosition(i));
197    this->bufferText[i]->setText(NULL);
198    this->bufferText[i]->setParent2D(this);
199  }
200  this->bufferDisplaySize = bufferDisplaySize;
201
202  this->shellHeight = (this->textSize + this->lineSpacing) * (bufferDisplaySize+1);
203}
204
205/**
206 * deletes all the Buffers
207 */
208void Shell::flushBuffers()
209{
210  // remove all chars from the BufferTexts.
211  if (this->bufferText)
212    for (int i = 0; i < this->bufferDisplaySize; i++)
213    {
214      this->bufferText[i]->setText(NULL, true);
215    }
216
217  // delete all the Chars in the Buffers
218  tIterator<char>* charIterator = this->buffer->getIterator();
219  char* charElem = charIterator->firstElement();
220  while (charElem != NULL)
221  {
222    delete charElem;
223
224    charElem = charIterator->nextElement();
225  }
226  delete charIterator;
227  delete this->buffer;
228  this->buffer = new tList<char>;
229}
230
231/**
232 * adds a new Line to the List of Buffers
233 * @param line the Line as in the first argument in printf
234 * @param args the arguments as a va_list
235 */
236bool Shell::addBufferLineStatic(const char* line, ...)
237{
238  va_list arguments;
239  va_start(arguments, line);
240
241#if DEBUG < 3
242  if (Shell::singletonRef == NULL)
243#endif
244
245  vprintf(line, arguments);
246#if DEBUG < 3
247  else
248#else
249  if (Shell::singletonRef != NULL)
250#endif
251    Shell::singletonRef->addBufferLine(line, arguments);
252  return true;
253}
254
255/**
256 * add a Line to the List of Buffers
257 * @param line
258 * @param arguments
259 *
260 * This function Adds one line to the buffer.
261 * and displays the line as the First Line of the display-buffer
262 */
263void Shell::addBufferLine(const char* line, va_list arguments)
264{
265   vsprintf(this->bufferArray, line, arguments);
266
267   char* inputEnd;
268   char* newLineBegin;
269   char* newLineEnd;
270
271   // check if we have something left in the buffers
272   if (unlikely(this->keepBuffer))
273   {
274     strcat(this->keepBufferArray, this->bufferArray);
275     inputEnd = this->keepBufferArray + strlen(this->keepBufferArray);
276     newLineBegin = this->keepBufferArray;
277     this->keepBuffer = false;
278   }
279   else
280   {
281     inputEnd = this->bufferArray + strlen(this->bufferArray);
282     newLineBegin = this->bufferArray;
283   }
284
285   // adding all the new Lines
286   while (newLineBegin < inputEnd)
287   {
288     newLineEnd = strchr(newLineBegin, '\n');
289     if (newLineEnd != NULL && *newLineEnd == '\n')
290       *newLineEnd = '\0';
291     else
292     {
293//       newLineEnd = newLineBegin + strlen(newLineBegin);
294       strcpy(this->keepBufferArray, newLineBegin);
295       this->keepBuffer = true;
296       break;
297     }
298
299     char* addLine = new char[strlen(newLineBegin)+1];
300     strcpy(addLine, newLineBegin);
301
302     this->buffer->add(addLine);
303
304     if (this->buffer->getSize() > this->bufferSize)
305     {
306       delete this->buffer->firstElement();
307       this->buffer->remove(this->buffer->firstElement());
308     }
309
310     if (this->bActive)
311     {
312       this->printToDisplayBuffer(addLine);
313     }
314     newLineBegin = newLineEnd+1;
315   }
316}
317
318/**
319 * prints out some text to the input-buffers
320 * @param text the text to output.
321 */
322void Shell::printToDisplayBuffer(const char* text)
323{
324  if(likely(bufferText != NULL))
325  {
326    Text* lastText = this->bufferText[this->bufferDisplaySize-1];
327
328    Text* swapText;
329    Text* moveText = this->bufferText[0];
330    this->bufferText[0]->setRelCoorSoft2D(this->calculateLinePosition(1),10);
331    for (unsigned int i = 1; i < this->bufferDisplaySize; i++)
332    {
333      if ( i < this->bufferDisplaySize-1)
334        this->bufferText[i]->setRelCoorSoft2D(this->calculateLinePosition(i+1),5);
335      swapText = this->bufferText[i];
336      this  ->bufferText[i] = moveText;
337      moveText = swapText;
338    }
339    lastText->setRelCoor2D(this->calculateLinePosition(0));
340    this->bufferText[0] = lastText;
341
342    this->bufferText[0]->setText(text, true);
343  }
344}
345
346/**
347 * moves the buffer around lineCount lines upwards (negative values move down)
348 * @param lineCount the Count of lines to move upwards
349 *
350 * @todo
351 */
352void Shell::moveBuffer(int lineCount)
353{
354}
355
356/**
357 * @param lineNumber the n-th line from the bottom
358 * @returns the Buffer at Line lineNumber
359 */
360const char* Shell::getBufferLine(unsigned int lineNumber)
361{
362  tIterator<char>* charIterator = this->buffer->getIterator();
363  char* charElem = charIterator->firstElement();
364
365  int i = 1;
366  while (charElem != NULL)
367  {
368    if (i++ < lineNumber)
369    {
370      delete charIterator;
371      return charElem;
372    }
373
374    charElem = charIterator->nextElement();
375  }
376  delete charIterator;
377}
378
379/**
380 * deletes the InputLine
381 */
382void Shell::flushInputLine()
383{
384  if (likely(this->inputLine != NULL))
385  {
386    delete[] this->inputLine;
387  }
388  this->inputLine = new char[1];
389  *this->inputLine = '\0';
390  this->inputLineText->setText(this->inputLine, true);
391}
392
393/**
394 * adds one character to the inputLine
395 * @param character the character to add to the inputLine
396 */
397void Shell::addCharacter(char character)
398{
399  char* addCharLine = new char[strlen(inputLine)+2];
400
401  sprintf(addCharLine, "%s%c", this->inputLine, character);
402  delete this->inputLine;
403  this->inputLine = addCharLine;
404  this->inputLineText->setText(inputLine, true);
405}
406
407/**
408 * adds multiple Characters to thr inputLine
409 * @param characters a '\0' terminated char-array to add to the InputLine
410 */
411void Shell::addCharacters(const char* characters)
412{
413  char* addCharLine = new char[strlen(inputLine)+strlen(characters)+1];
414
415  sprintf(addCharLine, "%s%s", this->inputLine, characters);
416  delete this->inputLine;
417  this->inputLine = addCharLine;
418  this->inputLineText->setText(inputLine);
419}
420
421/**
422 * removes characterCount characters from the InputLine
423 * @param characterCount the count of Characters to remove from the input Line
424 */
425void Shell::removeCharacters(unsigned int characterCount)
426{
427  if (strlen(this->inputLine) == 0)
428    return;
429
430  if (characterCount > strlen(this->inputLine))
431    characterCount = strlen(this->inputLine);
432
433  char* removeCharLine = new char[strlen(inputLine)-characterCount+1];
434
435  strncpy(removeCharLine, this->inputLine, strlen(inputLine)-characterCount);
436  removeCharLine[strlen(inputLine)-characterCount] = '\0';
437  delete this->inputLine;
438  this->inputLine = removeCharLine;
439  this->inputLineText->setText(inputLine);
440}
441
442/**
443 * executes the command stored in the inputLine
444 * @return true if the command was commited successfully, false otherwise
445 */
446bool Shell::executeCommand()
447{
448  this->addBufferLineStatic("Execute Command: %s\n", this->inputLine);
449
450  if (!strcmp(this->inputLine, "clear"))
451  {
452    this->flushBuffers();
453    this->addBufferLine("orxonox - shell\n ==================== \n", NULL);
454  }
455
456  this->flushInputLine();
457
458  return false;
459}
460
461/**
462 * sets the Repeate-delay and rate
463 * @param repeatDelay the Delay it takes, to repeate a key
464 * @param repeatRate the rate to repeate a pressed key
465 */
466void Shell::setRepeatDelay(float repeatDelay, float repeatRate)
467{
468  this->repeatDelay = repeatDelay;
469  this->repeatRate = repeatRate;
470
471}
472
473/**
474 * listens for some event
475 * @param event the Event happened
476 */
477void Shell::process(const Event &event)
478{
479  if (event.bPressed)
480  {
481    PRINTF(4)("Shell received command %s\n", SDLKToKeyname(event.type));
482    if (event.type == SDLK_BACKQUOTE)
483    {
484      if (EventHandler::getInstance()->getState() == ES_GAME)
485        this->activate();
486      else
487        this->deactivate();
488    }
489    else if (event.type == SDLK_F1)
490      this->help();
491    else if (event.type == SDLK_F2)
492      this->debug();
493    else if (event.type == SDLK_TAB)
494      this->autoComplete();
495    else if (event.type == SDLK_BACKSPACE)
496    {
497      this->delayed = this->repeatDelay;
498      this->pressedKey = SDLK_BACKSPACE;
499      this->removeCharacters(1);
500    }
501    else if (event.type == SDLK_RETURN)
502      this->executeCommand();
503    else if (likely(event.type < 127))
504    {
505      this->delayed = this->repeatDelay;
506      this->pressedKey = event.type;
507      this->addCharacter(event.type);
508    }
509  }
510  else // if(!event.bPressed)
511  {
512    if (this->pressedKey == event.type)
513    {
514      this->pressedKey = SDLK_FIRST;
515      this->delayed = 0.0;
516    }
517  }
518}
519
520/**
521 * ticks the Shell for dt Seconds
522 * @param dt the elapsed time since the last tick();
523 */
524void Shell::tick(float dt)
525{
526  if (this->delayed > 0.0)
527    this->delayed -= dt;
528  else if (this->pressedKey != SDLK_FIRST )
529  {
530    this->delayed = this->repeatRate;
531    if (this->pressedKey == SDLK_BACKSPACE)
532      this->removeCharacters(1);
533    else if (pressedKey < 127)
534      this->addCharacter(this->pressedKey);
535  }
536}
537
538/**
539 * displays the Shell
540 */
541void Shell::draw() const
542{
543  glPushMatrix();
544  // transform for alignment.
545  // setting the Blending effects
546
547  glColor4f(0.0f, 0.0f, 0.8f, .4);
548  glEnable(GL_BLEND);
549  glDisable(GL_TEXTURE_2D);
550  glBlendFunc(GL_SRC_ALPHA, GL_ONE);
551
552//  glBindTexture(GL_TEXTURE_2D, this->texture);
553  glBegin(GL_QUADS);
554
555//  glTexCoord2f(this->texCoord.minU, this->texCoord.minV);
556  glVertex2f(this->getAbsCoor2D().x,   this->getAbsCoor2D().);
557
558//  glTexCoord2f(this->texCoord.maxU, this->texCoord.minV);
559  glVertex2f(GraphicsEngine::getInstance()->getResolutionX() - this->getAbsCoor2D().x, this->getAbsCoor2D().);
560
561//  glTexCoord2f(this->texCoord.maxU, this->texCoord.maxV);
562  glVertex2f(GraphicsEngine::getInstance()->getResolutionX() - this->getAbsCoor2D().x, this->getAbsCoor2D().y + this->shellHeight);
563
564//  glTexCoord2f(this->texCoord.minU, this->texCoord.maxV);
565  glVertex2f(this->getAbsCoor2D().x, this->getAbsCoor2D().y + this->shellHeight);
566
567  glEnd();
568}
569
570
571/**
572 * autocompletes the Shell's inputLine
573 * @returns true, if a result was found, false otherwise
574 *
575 * @todo implement it!!
576 */
577bool Shell::autoComplete()
578{
579  //PRINTF(3)("AutoCompletion not implemented yet\n");
580
581  char* completionLine = new char[strlen(inputLine)+1];
582  strcpy(completionLine, this->inputLine);
583
584  char* commandBegin = strrchr(completionLine, ' ');
585  if (commandBegin == NULL)
586    commandBegin = completionLine;
587  else
588  {
589    if(commandBegin >= completionLine + strlen(completionLine))
590      commandBegin = completionLine + strlen(completionLine);
591    else
592      commandBegin++;
593  }
594
595  char* objectStart;
596  if (objectStart = strstr(commandBegin, "::"))
597  {
598    char* classIdentity = new char[objectStart - commandBegin +1];
599    strncpy(classIdentity, commandBegin, objectStart - commandBegin);
600    classIdentity[objectStart - commandBegin] = '\0';
601    this->objectComplete(objectStart+2, ClassList::StringToID(classIdentity));
602    delete[] classIdentity;
603  }
604  else
605    this->classComplete(commandBegin);
606
607  delete[] completionLine;
608}
609
610/**
611 * autocompletes a className
612 * @param classBegin the Beginning of a String to autoComplete
613 * @return true on success, false otherwise
614 */
615bool Shell::classComplete(const char* classBegin)
616{
617  if (unlikely(classBegin == NULL))
618    return false;
619  const tList<const char>* clList = ClassList::getClassList();
620  if (clList != NULL)
621  {
622    const tList<const char>* classList = this->createCompleteList(clList, classBegin);
623    if (classList != NULL)
624      this->generalComplete(classList, classBegin, "%s::", "::");
625    else
626      return false;
627  }
628  else
629    return false;
630  return true;
631}
632
633/**
634 * autocompletes an ObjectName
635 * @param objectBegin the beginning string of a Object
636 * @param classID the ID of the Class to search for.
637 * @return true on success, false otherwise
638 */
639bool Shell::objectComplete(const char* objectBegin, long classID)
640{
641  printf("%s\n", objectBegin);
642
643  if (unlikely(objectBegin == NULL))
644    return false;
645  tList<BaseObject>* boList = ClassList::getList(classID);
646  if (boList != NULL)
647  {
648    printf("\n", boList->firstElement()->getName());
649    const tList<const char>* objectList = this->createCompleteList(boList, objectBegin);
650    if (objectList != NULL)
651      this->generalComplete(objectList, objectBegin, "%s");
652    else
653      return false;
654  }
655  else
656    return false;
657  return true;
658}
659
660bool Shell::functionComplete(const char* functionBegin)
661{
662}
663
664/**
665 * completes the inputline on grounds of an inputList
666 * @param stringList the List to parse through
667 * @param begin the String to search in the inputList, and to extend with it.
668 * @param displayAs how to display the found value to the user, printf-style, !!with only one %s!! ex.: "::%s::"
669 * @param addBack what should be added at the end of the completion
670 * @param addFront what should be added to the front of one finished completion
671 * @return true if ok, false otherwise
672 */
673bool Shell::generalComplete(const tList<const char>* stringList, const char* begin, const char* displayAs, const char* addBack, const char* addFront)
674{
675  if (stringList->getSize() == 0)
676    return false;
677
678  const char* addString = stringList->firstElement();
679  unsigned int addLength = 0;
680  unsigned int inputLenght = strlen(begin);
681
682  if (addString != NULL)
683    addLength = strlen(addString);
684  tIterator<const char>* charIterator = stringList->getIterator();
685  const char* charElem = charIterator->firstElement();
686  while (charElem != NULL)
687  {
688    PRINTF(0)(displayAs, charElem);
689    for (unsigned int i = inputLenght; i < addLength; i++)
690      if (addString[i] != charElem[i])
691    {
692      addLength = i;
693      break;
694    }
695    charElem = charIterator->nextElement();
696  }
697  delete charIterator;
698
699  if (addLength >= inputLenght)
700  {
701    char* adder = new char[addLength+1];
702    strncpy(adder, addString, addLength);
703    adder[addLength] = '\0';
704    this->removeCharacters(inputLenght);
705    this->addCharacters(adder);
706    if (addBack != NULL && stringList->getSize() == 1)
707      this->addCharacters("::");
708    delete[] adder;
709  }
710  return true;
711}
712
713/**
714 * searches for classes, which beginn with classNameBegin
715 * @param inputList the List to parse through
716 * @param classNameBegin the beginning string
717 * @return a NEW char-array with ClassNames. The LIST should be deleted afterwards,
718 * !! The strings MUST NOT be deleted !!
719 */
720const tList<const char>* Shell::createCompleteList(const tList<const char>* inputList, const char* classNameBegin)
721{
722  if (inputList == NULL || classNameBegin == NULL)
723    return NULL;
724  unsigned int searchLength = strlen(classNameBegin);
725  if (this->completionList != NULL)
726    delete this->completionList;
727  this->completionList = new tList<const char>;
728
729//  tList<const char>* classList = ClassList::getClassList();
730
731  tIterator<const char>* iterator = inputList->getIterator();
732  const char* enumString = iterator->firstElement();
733  while (enumString != NULL)
734  {
735    if (strlen(enumString)>searchLength+1 &&
736        !strncasecmp(enumString, classNameBegin, searchLength))
737    {
738      this->completionList->add(enumString);
739    }
740    enumString = iterator->nextElement();
741  }
742  delete iterator;
743
744  return this->completionList;
745}
746
747/**
748 * searches for classes, which beginn with classNameBegin
749 * @param inputList the List to parse through
750 * @param classNameBegin the beginning string
751 * @return a NEW char-array with ClassNames. The LIST should be deleted afterwards,
752 * !! The strings MUST NOT be deleted !!
753 */
754const tList<const char>* Shell::createCompleteList(const tList<BaseObject>* inputList, const char* classNameBegin)
755{
756  if (inputList == NULL || classNameBegin == NULL)
757    return NULL;
758  unsigned int searchLength = strlen(classNameBegin);
759  if (this->completionList != NULL)
760    delete this->completionList;
761  this->completionList = new tList<const char>;
762
763  tIterator<BaseObject>* iterator = inputList->getIterator();
764  BaseObject* enumBO = iterator->firstElement();
765  while (enumBO != NULL)
766  {
767    if (enumBO->getName() != NULL &&
768        strlen(enumBO->getName())>searchLength+1 &&
769        !strncasecmp(enumBO->getName(), classNameBegin, searchLength))
770    {
771      this->completionList->add(enumBO->getName());
772    }
773    enumBO = iterator->nextElement();
774  }
775  delete iterator;
776
777  return this->completionList;
778}
779
780void Shell::help() const
781{
782  PRINT(0)("Help for the most important Shell-commands\n");
783  PRINT(0)("F1 - HELP; F2 - DEBUG; ` - open/close shell\n");
784  PRINT(0)("input order:\n");
785  PRINT(0)("ClassName::objectName function [parameter1, [parameter2 ...]]  or\n");
786  PRINT(0)("Command [parameter]\n");
787}
788
789
790///////////////////////
791// HELPER FUNCTIONS  //
792///////////////////////
793Vector Shell::calculateLinePosition(unsigned int lineNumber)
794{
795  return Vector(5, (this->textSize + this->lineSpacing)*(this->bufferDisplaySize - lineNumber -1) + this->textSize, 0);
796}
797
798
799
800/**
801 * displays some nice output from the Shell
802 */
803void Shell::debug() const
804{
805  PRINT(3)("Debugging output to console (not this shell)\n");
806
807  if (this->pressedKey != SDLK_FIRST)
808    printf("%s::%f %f\n", SDLKToKeyname(this->pressedKey), this->delayed, this->repeatDelay);
809
810
811  char* tmpChar = this->bufferIterator->firstElement();
812  while(tmpChar != NULL)
813  {
814    printf(tmpChar);
815    tmpChar = this->bufferIterator->nextElement();
816  }
817}
Note: See TracBrowser for help on using the repository browser.