Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: Background for the Shell

File size: 10.9 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 "debug.h"
26#include <stdarg.h>
27#include <stdio.h>
28
29using namespace std;
30
31
32/**
33 * standard constructor
34 */
35Shell::Shell ()
36{
37  this->setClassID(CL_SHELL, "Shell");
38  this->setName("Shell");
39
40  this->buffer = new tList<char>;
41
42  this->textSize = 10;
43
44  //this->bufferSize = 0;
45  this->bufferText = NULL;
46  this->setBufferSize(100);
47  this->setBufferDisplaySize(10);
48  this->setAbsCoor2D(3, GraphicsEngine::getInstance()->getResolutionY());
49  this->delayed = 0;
50  this->setRepeatDelay(.3, .05);
51  this->pressedKey = SDLK_FIRST;
52
53  this->inputLineText = TextEngine::getInstance()->createText("fonts/earth.ttf", 10, TEXT_DYNAMIC, 255, 0, 0);
54  this->inputLineText->setAlignment(TEXT_ALIGN_LEFT);
55  this->inputLineText->setText(NULL);
56  this->inputLine = new char[1];
57  this->inputLine[0] = '\0';
58  this->inputLineText->setParent2D(this);
59
60
61  EventHandler* evh = EventHandler::getInstance();
62  evh->subscribe(this, ES_ALL, SDLK_BACKQUOTE);
63  for (int i = 1; i < SDLK_F15; i++)
64    evh->subscribe(this, ES_SHELL, i);
65}
66
67Shell* Shell::singletonRef = NULL;
68
69/**
70 * standard deconstructor
71 */
72Shell::~Shell ()
73{
74  // delete the displayable Buffers
75  for (int i = 0; i < this->bufferDisplaySize; i++)
76    delete this->bufferText[i];
77  delete this->bufferText;
78
79  // delete the inputLine
80  delete this->inputLineText;
81  delete this->inputLine;
82
83  // delete all the Chars in the Buffers
84  tIterator<char>* charIterator = this->buffer->getIterator();
85  char* charElem = charIterator->nextElement();
86  while (charElem != NULL)
87  {
88    delete charElem;
89    charElem = charIterator->nextElement();
90  }
91  delete charIterator;
92
93  Shell::singletonRef = NULL;
94}
95
96/**
97 * sets The count of Lines to display in the buffer.
98 * @param bufferDisplaySize the count of lines to display in the Shell-Buffer.
99 */
100void Shell::setBufferDisplaySize(unsigned int bufferDisplaySize)
101{
102  if (this->bufferText != NULL)
103  {
104    for (unsigned int i = 0; i < this->bufferDisplaySize; i++)
105      delete this->bufferText[i];
106    delete this->bufferText;
107  }
108
109  this->bufferText = new Text*[bufferDisplaySize];
110  for (unsigned int i = 0; i < bufferDisplaySize; i++)
111  {
112    this->bufferText[i] = TextEngine::getInstance()->createText("fonts/earth.ttf", this->textSize, TEXT_DYNAMIC, 255, 0, 0);
113    this->bufferText[i]->setAlignment(TEXT_ALIGN_LEFT);
114    this->bufferText[i]->setRelCoor2D(5, 12+12*i);
115    this->bufferText[i]->setText(NULL);
116    this->bufferText[i]->setParent2D(this);
117  }
118
119
120  this->bufferDisplaySize = bufferDisplaySize;
121}
122
123/**
124 * deletes all the Buffers
125 */
126void Shell::flushBuffers()
127{
128  // remove all chars from the BufferTexts.
129  if (this->bufferText)
130    for (int i; i < this->bufferDisplaySize; i++)
131    {
132      this->bufferText[i]->setText(NULL);
133    }
134
135
136  // delete all the Chars in the Buffers
137  tIterator<char>* charIterator = this->buffer->getIterator();
138  char* charElem = charIterator->nextElement();
139
140  while (charElem != NULL)
141  {
142    delete charElem;
143
144    charElem = charIterator->nextElement();
145  }
146  delete charIterator;
147}
148
149/**
150 * adds a new Line to the List of Buffers
151 * @param line the Line as in the first argument in printf
152 * @param args the arguments as a va_list
153 *
154 * @todo optimize
155 */
156bool Shell::addBufferLineStatic(const char* line, ...)
157{
158  va_list arguments;
159  va_start(arguments, line);
160
161#if DEBUG < 3
162  if (Shell::singletonRef == NULL)
163#endif
164
165  vprintf(line, arguments);
166#if DEBUG < 3
167  else
168#else
169  if (Shell::singletonRef != NULL)
170#endif
171    Shell::singletonRef->addBufferLine(line, arguments);
172  return true;
173}
174int curr = 0;
175
176/**
177 * add a Line to the List of Buffers
178 * @param line
179 * @param arguments
180 *
181 * This function Adds one line to the buffer.
182 * and displays the line as the First Line of the display-buffer
183 */
184void Shell::addBufferLine(const char* line, va_list arguments)
185{
186   vsprintf(this->bufferArray, line, arguments);
187
188   char* newLine = new char[strlen(this->bufferArray)+1];
189   strcpy(newLine, this->bufferArray);
190
191   this->buffer->add(newLine);
192
193   if (this->buffer->getSize() > this->bufferSize)
194   {
195     delete this->buffer->firstElement();
196     this->buffer->remove(this->buffer->firstElement());
197   }
198
199   if (likely(bufferText != NULL))
200   {
201     Text* moveText = this->bufferText[this->bufferDisplaySize-1];
202     for (int i = this->bufferDisplaySize-1; i > 0; i--)
203     {
204       this->bufferText[i] = this->bufferText[i-1];
205     }
206     this->bufferText[0] = moveText;
207   }
208   this->bufferText[0]->setText(newLine);
209   // this->bufferText->
210//  this->inputLineText->setText(newLine);
211}
212
213/**
214 * moves the buffer around lineCount lines upwards (negative values move down)
215 * @param lineCount the Count of lines to move upwards
216 *
217 * @todo
218 */
219void Shell::moveBuffer(int lineCount)
220{
221}
222
223/**
224 * @param lineNumber the n-th line from the bottom
225 * @returns the Buffer at Line lineNumber
226 */
227const char* Shell::getBufferLine(unsigned int lineNumber)
228{
229  tIterator<char>* charIterator = this->buffer->getIterator();
230  char* charElem = charIterator->nextElement();
231
232  int i = 1;
233  while (charElem != NULL)
234  {
235    if (i++ < lineNumber)
236    {
237      delete charIterator;
238      return charElem;
239    }
240
241    charElem = charIterator->nextElement();
242  }
243  delete charIterator;
244}
245
246
247/**
248 * deletes the InputLine
249 */
250void Shell::flushInputLine()
251{
252  if (likely(this->inputLine != NULL))
253  {
254    delete [] this->inputLine;
255  }
256  this->inputLine = new char[1];
257  *this->inputLine = '\0';
258
259}
260
261/**
262 * adds one character to the inputLine
263 * @param character the character to add to the inputLine
264 */
265void Shell::addCharacter(char character)
266{
267  char* addCharLine = new char[strlen(inputLine)+2];
268
269  sprintf(addCharLine, "%s%c", this->inputLine, character);
270  delete this->inputLine;
271  this->inputLine = addCharLine;
272  this->inputLineText->setText(inputLine);
273}
274
275/**
276 * adds multiple Characters to thr inputLine
277 * @param characters a '\0' terminated char-array to add to the InputLine
278 */
279void Shell::addCharacters(const char* characters)
280{
281  char* addCharLine = new char[strlen(inputLine)+strlen(characters)+1];
282
283  sprintf(addCharLine, "%s%s", this->inputLine, characters);
284  delete this->inputLine;
285  this->inputLine = addCharLine;
286  this->inputLineText->setText(inputLine);
287}
288
289/**
290 * removes characterCount characters from the InputLine
291 * @param characterCount the count of Characters to remove from the input Line
292 */
293void Shell::removeCharacters(unsigned int characterCount)
294{
295  if (strlen(this->inputLine) == 0)
296    return;
297
298  if (characterCount > strlen(this->inputLine))
299    characterCount = strlen(this->inputLine);
300
301  char* removeCharLine = new char[strlen(inputLine)-characterCount+1];
302
303  strncpy(removeCharLine, this->inputLine, strlen(inputLine)-characterCount);
304  removeCharLine[strlen(inputLine)-characterCount] = '\0';
305  delete this->inputLine;
306  this->inputLine = removeCharLine;
307  this->inputLineText->setText(inputLine);
308}
309
310/**
311 * executes the command stored in the inputLine
312 * @return true if the command was commited successfully, false otherwise
313 */
314bool Shell::executeCommand()
315{
316
317  this->addBufferLineStatic("Execute Command: %s\n", this->inputLine);
318  delete this->inputLine;
319  this->inputLine = new char[1];
320  this->inputLine[0]='\0';
321  this->inputLineText->setText(this->inputLine);
322  return false;
323}
324
325/**
326 * sets the Repeate-delay and rate
327 * @param repeatDelay the Delay it takes, to repeate a key
328 * @param repeatRate the rate to repeate a pressed key
329 */
330void Shell::setRepeatDelay(float repeatDelay, float repeatRate)
331{
332  this->repeatDelay = repeatDelay;
333  this->repeatRate = repeatRate;
334
335}
336
337
338#include "key_names.h"
339/**
340 * listens for some event
341 * @param event the Event happened
342 */
343void Shell::process(const Event &event)
344{
345  if (event.bPressed)
346  {
347    PRINTF(4)("Shell received command %s\n", SDLKToKeyname(event.type));
348    if (event.type == SDLK_BACKQUOTE)
349    {
350      if (EventHandler::getInstance()->getState() == ES_GAME)
351      {
352        EventHandler::getInstance()->setState(ES_SHELL);
353        this->setRelCoorSoft2D(0, GraphicsEngine::getInstance()->getResolutionY()-150, 1, 5);
354      }
355
356      else
357      {
358        EventHandler::getInstance()->setState(ES_GAME);
359        this->setRelCoorSoft2D(0, GraphicsEngine::getInstance()->getResolutionY()+10, 1, 5);
360      }
361    }
362    else if (event.type == SDLK_TAB)
363      this->autoComplete();
364    else if (event.type == SDLK_BACKSPACE)
365    {
366      this->delayed = this->repeatDelay;
367      this->pressedKey = SDLK_BACKSPACE;
368      this->removeCharacters(1);
369    }
370    else if (event.type == SDLK_RETURN)
371      this->executeCommand();
372    else if (likely(event.type < 127))
373    {
374      this->delayed = this->repeatDelay;
375      this->pressedKey = event.type;
376      this->addCharacter(event.type);
377    }
378  }
379  else // if(!event.bPressed)
380  {
381    if (this->pressedKey == event.type)
382      this->pressedKey = SDLK_FIRST;
383    this->delayed = 0.0;
384  }
385}
386
387/**
388 * ticks the Shell for dt Seconds
389 * @param dt the elapsed time since the last tick();
390 */
391void Shell::tick(float dt)
392{
393  if (this->delayed > 0.0)
394    this->delayed -= dt;
395  else if (this->pressedKey != SDLK_FIRST )
396  {
397    this->delayed = this->repeatRate;
398    if (this->pressedKey == SDLK_BACKSPACE)
399      this->removeCharacters(1);
400    else if (pressedKey < 127)
401      this->addCharacter(this->pressedKey);
402  }
403}
404
405/**
406 * displays the Shell
407 */
408void Shell::draw() const
409{
410  glPushMatrix();
411  // transform for alignment.
412  // setting the Blending effects
413
414  glColor4f(0.0f, 0.0f, 0.8f, .4);
415  glEnable(GL_BLEND);
416  glDisable(GL_TEXTURE_2D);
417  glBlendFunc(GL_SRC_ALPHA, GL_ONE);
418
419//  glBindTexture(GL_TEXTURE_2D, this->texture);
420  glBegin(GL_QUADS);
421
422//  glTexCoord2f(this->texCoord.minU, this->texCoord.minV);
423  glVertex2f(this->getAbsCoor2D().x,   this->getAbsCoor2D().);
424
425//  glTexCoord2f(this->texCoord.maxU, this->texCoord.minV);
426  glVertex2f(this->getAbsCoor2D().x + 800, this->getAbsCoor2D().);
427
428//  glTexCoord2f(this->texCoord.maxU, this->texCoord.maxV);
429  glVertex2f(this->getAbsCoor2D().x + 800, this->getAbsCoor2D().y + 150);
430
431//  glTexCoord2f(this->texCoord.minU, this->texCoord.maxV);
432  glVertex2f(this->getAbsCoor2D().x, this->getAbsCoor2D().y + 150);
433
434  glEnd();
435}
436
437
438/**
439 * autocompletes the Shell's inputLine
440 * @returns true, if a result was found, false otherwise
441 */
442bool Shell::autoComplete()
443{
444  PRINTF(3)("AutoCompletion not implemented yet\n");
445}
446
447/**
448 * displays some nice output from the Shell
449 */
450void Shell::debug() const
451{
452  if (this->pressedKey != SDLK_FIRST)
453    printf("%s::%f %f\n", SDLKToKeyname(this->pressedKey), this->delayed, this->repeatDelay);
454
455}
Note: See TracBrowser for help on using the repository browser.