home *** CD-ROM | disk | FTP | other *** search
/ Enter 2005 March / ENTER.ISO / files / fwp-0.0.6-win32-installer.exe / ConsoleFrontEnd.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2004-12-06  |  12.5 KB  |  427 lines

  1. #include "ConsoleFrontEnd.h"
  2. #include "ConsoleInfo.h"
  3. #include "Display.h"
  4. #include "Renderer.h"
  5. #include "vectormath.h"
  6. #include "SDL.h"
  7. #include "DisplayInfo.h"
  8. #include "Input.h"
  9. #include "Tokenizer.h"
  10. #include "TextureHandler.h"
  11. #include "ShaderHandler.h"
  12. #include "FontHandler.h"
  13. #include "Game.h"
  14. #include "version.h"
  15. #include <string.h>
  16.  
  17. #include "log.h"
  18.  
  19.  
  20. #define CONSOLE_FRONT_END_FONT_SCALE    0.7f
  21. #define cprint(x,y,str) drawScaledString(x, y, CONSOLE_FRONT_END_FONT_SCALE, CONSOLE_FRONT_END_FONT_SCALE, font, str);
  22.  
  23. ConsoleFrontEnd* consoleFrontEnd=NULL;
  24. //con_t con;
  25. /*
  26. bool initConsoleFE(){
  27. }
  28.  
  29. bool shutdownConsoleFE(){
  30. }
  31. */
  32.  
  33. ConsoleFrontEnd::ConsoleFrontEnd(Console* console){
  34.     this->console=console;
  35.  
  36.     promptStr=">> ";
  37.     inputStr=new char[CON_MAX_STRING_LENGTH];
  38.     inputStr[0]='\0';
  39.     inputStrIndex=0;
  40.  
  41.     for(int i=0;i<CON_MAX_HISTORY_LINES;i++){
  42.         historyLines[i] = NULL;
  43.     }
  44.     inputHistoryIndex=-1;
  45.     scrollIndex=0;
  46.     
  47.     isActive=false;
  48.     height = DISPLAY_VSCREEN_HEIGHT/3;
  49.     lineSpacing=1;
  50.  
  51. //    ConsoleInfo::cvar.con_FE_font->updateVar();
  52.     font=FontHandler::getFont("gui/fonts/courier_small_bold.font");
  53.     if(font==NULL){
  54.         error("(in ConsoleFrontEnd::ConsoleFrontEnd()): couldn't load console font.\n\n");
  55.     }
  56. /*
  57.     ConsoleInfo::cvar.console_backgroundTexture->updateVar();
  58.     backgroundTex=TextureHandler::getTexture(ConsoleInfo::var.backgroundTexture);
  59.     if(backgroundTex==NULL){
  60.         error("(in ConsoleFrontEnd::ConsoleFrontEnd()): couldn't load background texture '%s'.\n\n", ConsoleInfo::var.backgroundTexture);
  61.     }
  62. */
  63.     backgroundShader=ShaderHandler::getShader("gui/console/console_background.shader");
  64. //    if(backgroundShader==NULL){
  65. //        error("(in ConsoleFrontEnd::ConsoleFrontEnd()): couldn't load background Shader '%s'.\n\n", "arsch");
  66. //    }
  67.     
  68.     // NOT USED (ConsoleInfo::var.xyColor is used!!!
  69.     vectorInit4d(1.0f, 1.0f, 1.0f, 0.8f, backgroundColor);
  70.     vectorInit4d(0.0f, 0.5f, 1.0f, 1.0f, fontColor);
  71. }
  72.  
  73.  
  74. ConsoleFrontEnd::~ConsoleFrontEnd(){
  75.     delete[] inputStr;
  76.  
  77.     if(font!=NULL)
  78.         FontHandler::releaseFont(font);
  79.  
  80.     if(backgroundTex!=NULL)
  81.  
  82.         TextureHandler::releaseTexture(backgroundTex);
  83.  
  84.     if(backgroundShader!=NULL)
  85.         ShaderHandler::releaseShader(backgroundShader);
  86.  
  87.     clearHistory();
  88. }
  89.  
  90. void ConsoleFrontEnd::activate(){
  91.     SDL_EnableUNICODE(1);
  92.     SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
  93.     height = Display::info.var.height/3;
  94.     isActive=true;
  95. }
  96.  
  97. void ConsoleFrontEnd::deactivate(){
  98.     SDL_EnableUNICODE(0);
  99.  
  100.     SDL_EnableKeyRepeat(0, SDL_DEFAULT_REPEAT_INTERVAL);
  101.     isActive=false;
  102. }
  103.  
  104. void ConsoleFrontEnd::receiveKey(SDL_keysym* keysym){
  105.     int i,j;
  106.     SDLKey key=keysym->sym;
  107.  
  108.     if(key==SDLK_ESCAPE){
  109.         //deactivate();
  110.     }else if(key==SDLK_RIGHT){
  111.         if(inputStr[inputStrIndex]!='\0'){
  112.             inputStrIndex++;
  113.         }
  114.     }else if(key==SDLK_LEFT){
  115.         if(inputStrIndex>0){
  116.             inputStrIndex--;
  117.         }
  118.     }else if(key==SDLK_UP){
  119.         if(inputHistoryIndex+1<CON_MAX_HISTORY_LINES && historyLines[inputHistoryIndex+1]!=NULL){
  120.             inputHistoryIndex++;
  121.             strcpy(inputStr, historyLines[inputHistoryIndex]);
  122.             inputStrIndex=strlen(inputStr);
  123.         }
  124.     }else if(key==SDLK_DOWN){
  125.         if(inputHistoryIndex>0 && historyLines[inputHistoryIndex-1]!=NULL){
  126.             inputHistoryIndex--;
  127.             strcpy(inputStr, historyLines[inputHistoryIndex]);
  128.             inputStrIndex=strlen(inputStr);
  129.         }else if(inputHistoryIndex==0){
  130.             inputHistoryIndex--;    // -1 dann!
  131.             inputStr[0]='\0';
  132.             inputStrIndex=0;
  133.         }
  134.     }else if(key==SDLK_PAGEDOWN && !(keysym->mod & KMOD_CTRL) ){    // scroll down one line
  135.         if(scrollIndex>0)
  136.             scrollIndex--;
  137.     }else if(key==SDLK_PAGEUP && !(keysym->mod & KMOD_CTRL) ){    // scroll up one line
  138.         if(scrollIndex<CON_MAX_LINES && console->lines[scrollIndex]!=NULL)    // THINKABOUTME: scheisse, wenn unterwegs eine line NULL ist
  139.             scrollIndex++;
  140.     }else if(key==SDLK_PAGEDOWN && (keysym->mod & KMOD_CTRL) ){    // scroll down 10 lines
  141.         scrollIndex = scrollIndex-10>0 ? scrollIndex-10 : 0;
  142.     }else if(key==SDLK_PAGEUP && (keysym->mod & KMOD_CTRL) ){    // scroll up 10 lines
  143.         i=0;
  144.         while(i<10 && scrollIndex<CON_MAX_LINES && console->lines[scrollIndex]!=NULL){    // THINKABOUTME: scheisse, wenn unterwegs eine line NULL ist
  145.             scrollIndex++;
  146.             i++;
  147.         }
  148.     }else if(key==SDLK_HOME && (keysym->mod & KMOD_CTRL) ){    // scroll to top
  149.         while(scrollIndex<CON_MAX_LINES && console->lines[scrollIndex]!=NULL){    // THINKABOUTME: scheisse, wenn unterwegs eine line NULL ist
  150.             scrollIndex++;
  151.         }
  152.     }else if(key==SDLK_END && (keysym->mod & KMOD_CTRL) ){    // scroll to bottom
  153.         scrollIndex=0;
  154.  
  155.     }else if(key==SDLK_HOME && !(keysym->mod & KMOD_CTRL) ){
  156.         inputStrIndex=0;
  157.     }else if(key==SDLK_END && !(keysym->mod & KMOD_CTRL) ){
  158.         inputStrIndex=strlen(inputStr);
  159.     }else if(key==SDLK_RETURN){    // enter
  160.         if(strlen(inputStr) > 0)
  161.             appendHistoryLine(inputStr);
  162.  
  163.         char buff[CON_MAX_STRING_LENGTH];
  164.         strncpy(buff, inputStr, CON_MAX_STRING_LENGTH);
  165.         inputStr[0] = '\0';
  166.         inputStrIndex = 0;
  167.         inputHistoryIndex = -1;
  168.  
  169.         if(buff[0] == '/'){
  170.             sendToConsole(buff+1);
  171.         }else{
  172.             if( !Game::wasInit() || strlen(buff) == 0){
  173.                 sendToConsole(buff);
  174.             }else{
  175.                 Game::chatMessageAll(buff);
  176.             }
  177.         }
  178.     }else if(key==SDLK_BACKSPACE){    // backspace
  179.         if(inputStrIndex<=0)
  180.             return;
  181.  
  182.         i=inputStrIndex-1;
  183.         while(inputStr[i]!='\0'){
  184.             inputStr[i]=inputStr[i+1];
  185.             i++;
  186.         }
  187.         inputStrIndex-=1;
  188.     }else if(key==SDLK_DELETE){    // del
  189.         if(inputStr[inputStrIndex]=='\0')
  190.             return;
  191.  
  192.         i=inputStrIndex;
  193.         while(inputStr[i]!='\0'){
  194.             inputStr[i]=inputStr[i+1];
  195.             i++;
  196.         }
  197.     }else if(key==SDLK_TAB){    // tab -> auto complete
  198.         if(strlen(inputStr)>0){
  199.             // prepend a '/' if not already done
  200.             if(inputStr[0] != '/'){
  201.                 int l=strlen(inputStr);
  202.                 if(l < CON_MAX_STRING_LENGTH){
  203.                     for(i=l+1 ; i>=1 ; i--){
  204.                         inputStr[i] = inputStr[i-1];
  205.                     }
  206.                     inputStr[0] = '/';
  207.                 }
  208. //                printf("string: '%s'\n", inputStr);
  209.             }
  210.  
  211.             // ignore the '/' for testing...
  212.             char* cmpStr;
  213.             cmpStr = inputStr + 1;
  214.  
  215.             console->print("TAB suggests:\n");
  216.             int count=0;
  217.             const char* names[CON_MAX_CCMDS+CON_MAX_CVARS+CON_MAX_ALIASES];
  218.             for(i=0;i<CON_MAX_CCMDS;i++){
  219.                 if(console->cCmds[i]!=NULL && !strncmp(cmpStr, console->cCmds[i]->name, strlen(cmpStr))){
  220.                     console->print(" -> %s (%s)\n", console->cCmds[i]->name, console->cCmds[i]->infoStr);
  221.                     names[count]=console->cCmds[i]->name;
  222.                     count++;
  223.                 }
  224.             }
  225.             for(i=0;i<CON_MAX_CVARS;i++){
  226.                 if(console->cVars[i]!=NULL && !strncmp(cmpStr, console->cVars[i]->name, strlen(cmpStr))){
  227.                     console->print(" -> %s\n", console->cVars[i]->name /*, console->cVars[i]->infoStr*/);
  228.                     names[count]=console->cVars[i]->name;
  229.                     count++;
  230.                 }
  231.             }
  232.             for(i=0;i<CON_MAX_ALIASES;i++){
  233.                 if(console->aliases[i]!=NULL && !strncmp(cmpStr, console->aliases[i]->name, strlen(cmpStr))){
  234.                     console->print(" -> %s (alias for '%s')\n", console->aliases[i]->name , console->aliases[i]->string);
  235.                     names[count] = console->aliases[i]->name;
  236.                     count++;
  237.                 }
  238.             }
  239.  
  240.             if(count>0){
  241.                 int firstDiff=99999;
  242.                 for(i=0;i<count;i++){
  243.  
  244.                     for(j=0;j<count;j++){
  245.                         int n = strlen(cmpStr);
  246.                         while(!strncmp(names[i], names[j], n) && (unsigned int)n<=strlen(names[i]) && (unsigned int)n<=strlen(names[j])){
  247.                             n++;
  248.                         }
  249.                         firstDiff = n<firstDiff ? n : firstDiff;
  250.                     }
  251.                 }
  252.                 
  253.                 strncpy(cmpStr, names[0], firstDiff);
  254.                 cmpStr[firstDiff-1] = '\0';
  255.             }
  256.             inputStrIndex = strlen(inputStr);
  257.         }
  258.     }else{        // add char to inputStr
  259.         int l=strlen(inputStr);
  260.         if(l < CON_MAX_STRING_LENGTH){
  261.             char ch;
  262.             if ( (keysym->unicode & 0xFF80) == 0 && keysym->unicode!=0) {
  263.                 ch = keysym->unicode & 0x7F;
  264.                 for(i=l+1;i>inputStrIndex;i--){
  265.                     inputStr[i]=inputStr[i-1];
  266.                 }
  267.  
  268.                 inputStr[inputStrIndex]=ch;
  269.                 inputStrIndex++;
  270.                 //inputStr[inputStrIndex+1]='\0';
  271.                 //inputStrIndex = inputStrIndex >= CON_MAX_LINE_LENGTH-1 ? CON_MAX_LINE_LENGTH-1 : inputStrIndex+1;
  272.             }else{
  273. //                warn("(in ConsoleFrontEnd::recieveKey()): unicode of key not known!\n\n");
  274.             }
  275.         }
  276.     }
  277.  
  278. }
  279.  
  280.  
  281. void ConsoleFrontEnd::sendToConsole(char* str){
  282.     console->input(str);
  283. }
  284.  
  285. void ConsoleFrontEnd::clearInputString(){
  286.         inputStr[0]='\0';
  287.         inputStrIndex=0;
  288.         inputHistoryIndex=-1;
  289. }
  290.  
  291. void ConsoleFrontEnd::draw(){
  292.     height = DISPLAY_VSCREEN_HEIGHT/3;
  293.     
  294.     Renderer::beginDrawing();
  295.  
  296.     drawBackground();
  297.     drawLines();
  298.     drawPrompt();
  299.  
  300.     Renderer::endDrawing();
  301. }
  302.  
  303. void ConsoleFrontEnd::drawBackground(){
  304.     backgroundShader->setup(SDL_GetTicks());
  305.     glBegin(GL_QUADS);
  306.         glTexCoord2f(0.0f, 1.0f);
  307.         if(_glMultiTexCoord2fARB!=NULL)
  308.             _glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 0.0f, 1.0f);
  309.         glVertex2i(0, DISPLAY_VSCREEN_HEIGHT );
  310.  
  311.         glTexCoord2f(1.0, 1.0);
  312.         if(_glMultiTexCoord2fARB!=NULL)
  313.             _glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 1.0f, 1.0f);
  314.         glVertex2i(DISPLAY_VSCREEN_WIDTH, DISPLAY_VSCREEN_HEIGHT );
  315.  
  316.  
  317.         glTexCoord2f(1.0, 0.0);
  318.         if(_glMultiTexCoord2fARB!=NULL)
  319.             _glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 1.0f, 0.0f);
  320.         glVertex2i(DISPLAY_VSCREEN_WIDTH, DISPLAY_VSCREEN_HEIGHT - height);
  321.  
  322.  
  323.         glTexCoord2f(0.0, 0.0);
  324.         if(_glMultiTexCoord2fARB!=NULL)
  325.             _glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 0.0f, 0.0f);
  326.         glVertex2i(0, DISPLAY_VSCREEN_HEIGHT - height);
  327.     glEnd();
  328.     backgroundShader->setdown();
  329.  
  330.  
  331.     glColor4fv(ConsoleInfo::var.fontColor);
  332.     glBegin(GL_LINES);
  333.         glVertex2i(0, DISPLAY_VSCREEN_HEIGHT - height);
  334.         glVertex2i(DISPLAY_VSCREEN_WIDTH, DISPLAY_VSCREEN_HEIGHT - height);
  335.     glEnd();
  336. //    renderBitmapFormatString(screen.width-10, DisplayInfo::var.height-height+5, GLUT_BITMAP_TIMES_ROMAN_10, TEXT_ALIGN_RIGHT, "MAUSS version: %s", MAUSS_VERSION);
  337.     drawScaledAndAlignedFormatString(DISPLAY_VSCREEN_WIDTH-3, DISPLAY_VSCREEN_HEIGHT-height+3, CONSOLE_FRONT_END_FONT_SCALE*0.9f, CONSOLE_FRONT_END_FONT_SCALE*0.9f,
  338.         font, TEXT_ALIGN_RIGHT, "FWP v%s (%s)", FWP_VERSION_STRING, FWP_OS_STRING);
  339.  
  340. }
  341.  
  342. void ConsoleFrontEnd::drawPrompt(){
  343.  
  344.     glColor4fv(ConsoleInfo::var.fontColor);
  345.     drawScaledFormatString(10, DISPLAY_VSCREEN_HEIGHT-height+5, CONSOLE_FRONT_END_FONT_SCALE, CONSOLE_FRONT_END_FONT_SCALE,
  346.         font, "%s%s", promptStr, inputStr);
  347.  
  348.     if((SDL_GetTicks()/500)%2){
  349.         char buff[CON_MAX_STRING_LENGTH];
  350.         strncpy(buff, inputStr, inputStrIndex);
  351.         buff[inputStrIndex] = '\0';
  352.         float xOffs = (getStringWidth(font, promptStr)+getStringWidth(font, buff))*CONSOLE_FRONT_END_FONT_SCALE;
  353.         drawScaledString(10+(int)xOffs, DISPLAY_VSCREEN_HEIGHT-height+5, CONSOLE_FRONT_END_FONT_SCALE, CONSOLE_FRONT_END_FONT_SCALE, font, "_");
  354.     }
  355. }
  356.  
  357. void ConsoleFrontEnd::drawLines(){
  358.     int i;
  359.     int n = (int)( height/(lineSpacing + font->height*CONSOLE_FRONT_END_FONT_SCALE) );
  360.     int y = DISPLAY_VSCREEN_HEIGHT - height + 10;
  361.     char* p;
  362.     //char* pMin;
  363.     float charWidth = font->chars[(int)'A']->width*CONSOLE_FRONT_END_FONT_SCALE;    // FIXME: das muss es nicht geben!!!
  364.     unsigned int maxCharsPerLine = (int)(DISPLAY_VSCREEN_WIDTH/charWidth) -2;
  365.  
  366.     int stop = scrollIndex+n <= CON_MAX_LINES ? scrollIndex+n : CON_MAX_LINES;
  367.  
  368.     for(i=scrollIndex; i<stop; i++){
  369.         if(console->lines[i]==NULL){
  370.             y+= (int)( lineSpacing + font->height*CONSOLE_FRONT_END_FONT_SCALE );
  371.             continue;
  372.         }
  373.         
  374.         glColor4fv(ConsoleInfo::var.fontColor);
  375.         if(strlen(console->lines[i]) <= maxCharsPerLine){
  376.             y += (int)( (lineSpacing + font->height*CONSOLE_FRONT_END_FONT_SCALE) );
  377.             cprint(10, y, console->lines[i]);
  378.         }else{    // FIXME: sch∩┐╜er machen
  379.             char buff[256];
  380.  
  381.             int numLines = (int)( strlen(console->lines[i])/maxCharsPerLine ) + 1;
  382.             y += (int)( lineSpacing + font->height*CONSOLE_FRONT_END_FONT_SCALE ) * numLines;
  383.             p = console->lines[i];
  384.             while(p < console->lines[i] + strlen(console->lines[i])){
  385.                 strncpy(buff, p, maxCharsPerLine);
  386.                 buff[maxCharsPerLine]='\0';
  387.                 cprint(10, y, buff);
  388.                 y -= (int)( lineSpacing + font->height*CONSOLE_FRONT_END_FONT_SCALE );
  389.  
  390.                 p += maxCharsPerLine;
  391.             }
  392.             y += (int)( lineSpacing + font->height*CONSOLE_FRONT_END_FONT_SCALE ) * numLines;
  393.         }
  394.     }
  395. }
  396.  
  397.  
  398.  
  399.  
  400. void ConsoleFrontEnd::clearHistory(){
  401.     int i;
  402.  
  403.     for(i=0;i<CON_MAX_HISTORY_LINES;i++){
  404.         if(historyLines[i]!=NULL){
  405.             delete[] historyLines[i];
  406.             historyLines[i]=NULL;
  407.         }
  408.     }
  409. }
  410.  
  411. void ConsoleFrontEnd::appendHistoryLine(const char* line){
  412.     int i;
  413.  
  414.     if(historyLines[CON_MAX_HISTORY_LINES-1]!=NULL)        // delete last line
  415.         delete[] historyLines[CON_MAX_HISTORY_LINES-1];    
  416.  
  417.     for(i=CON_MAX_HISTORY_LINES-1; i>0; i--){    // move all one position up
  418.         historyLines[i]=historyLines[i-1];
  419.     }
  420.  
  421. //    int t=strlen(line);
  422.     historyLines[0]=newString(line);//new char[strlen(line)+1];
  423. //    historyLines[0]=strncpy(historyLines[0], line, strlen(line)+1);
  424. }
  425.  
  426.  
  427.