Jump to content

Like
0Likes
Dislike
Text Input in an Allegro Game


edittext version c++ string int buffer char allegro caret
Describes how to process input using both C and C++.

4: Adsense



A common request in the Allegro forums is for a way to process player text input. cin doesn't work. The Allegro GUI does, but is simplistic and limiting (*cough* and ugly *cough*). Back when I
wrote an article on the standard C++ string class, I wrote a small C++ program that stored player input in a std::string. Since then, I made a simpler C version that uses a char array. The code is
very short and simple to use, so modifying it for your purposes (to word wrap, for example, if you want that) is dirt easy. I get asked for it often, so I'm just submitting it for ease of
finding.


Both the C and C++ version just take the input and print it onscreen. The C++ version lets you move the caret around, processes the Insert key to toggle replacing and inserting, and lets you both
delete and backspace. None of that's really necessary; It's only there because the string class makes it so easy. The functionality can be added to the C version easily enough, I know. But I'm a lazy
spoilt C++ coder, so all effort to that end is left as an exercise to the reader.


Here is the C version.



// edittext.c

#include <allegro.h>



#define BUFFERSIZE 128

#define WHITE makecol(255, 255, 255)



int main()

{

   BITMAP* buffer = NULL;

   char    edittext[BUFFERSIZE];

   int     caret  = 0;



   /* typical Allegro initialization */

   allegro_init();

   install_keyboard();

   set_gfx_mode(GFX_AUTODETECT, 320, 240, 0, 0);



   buffer = create_bitmap(320, 240);



   do

   {

      if(keypressed())

      {

         int  newkey   = readkey();

         char ASCII    = newkey & 0xff;

         char scancode = newkey >> 8;



         /* a character key was pressed; add it to the string */

         if(ASCII >= 32 && ASCII <= 126)

         {

                                if(caret < BUFFERSIZE - 1)

                                {

                                        edittext[caret] = ASCII;

                                        caret++;

                                        edittext[caret] = '\0';

                                }

         }

         else if(scancode == KEY_BACKSPACE)

         {

            if (caret > 0) caret--;

            edittext[caret] = '\0';

         }

      }

      

      /* all drawing goes here */

      clear(buffer);

      textout(buffer, font, edittext, 0, 10, WHITE);

      vline(buffer, caret * 8, 8, 18, WHITE);

      blit(buffer, screen, 0, 0, 0, 0, 320, 240);



   }

   while(!key[KEY_ESC]);

   

   destroy_bitmap(buffer);



   return 0;

}

END_OF_MAIN()


The C++ version, as stated, is slightly more robust. This is essentially the code from my original article.


C++:



// edittext.cpp

#include <allegro.h>

#include <string>

using namespace std;



#define WHITE makecol(255, 255, 255)



int main()

{

   // typical Allegro initialization

   allegro_init();

   install_keyboard();

   set_gfx_mode(GFX_AUTODETECT, 320, 240, 0, 0);



   // all variables are here

   BITMAP* buffer = create_bitmap(320, 240); // initialize the double buffer

   string  edittext;                         // an empty string for editting

   string::iterator iter = edittext.begin(); // string iterator

   int     caret  = 0;                       // tracks the text caret

   bool    insert = true;                    // true if text should be inserted

   

   // the game loop

   do

   {

      while(keypressed())

      {

         int  newkey   = readkey();

         char ASCII    = newkey & 0xff;

         char scancode = newkey >> 8;



         // a character key was pressed; add it to the string

         if(ASCII >= 32 && ASCII <= 126)

         {

            // add the new char, inserting or replacing as need be

            if(insert || iter == edittext.end())

               iter = edittext.insert(iter, ASCII);

            else

               edittext.replace(caret, 1, 1, ASCII);



            // increment both the caret and the iterator

            caret++;

            iter++;

         }

         // some other, "special" key was pressed; handle it here

         else

            switch(scancode)

            {

               case KEY_DEL:

                  if(iter != edittext.end()) iter = edittext.erase(iter);

               break;



               case KEY_BACKSPACE:

                  if(iter != edittext.begin())

                  {

                     caret--;

                     iter--;

                     iter = edittext.erase(iter);

                  }

               break;

            

               case KEY_RIGHT:

                  if(iter != edittext.end())   caret++, iter++;

               break;

            

               case KEY_LEFT:

                  if(iter != edittext.begin()) caret--, iter--;

               break;

            

               case KEY_INSERT:

                  insert = !insert;

               break;



               default:



               break;

            }

      }

      

      // clear screen

      clear(buffer);



      // output the string to the screen

      textout(buffer, font, edittext.c_str(), 0, 10, WHITE);



      // output some stats using Allegro's printf functions

      textprintf(buffer, font,  0, 20, WHITE, "length:   %d", edittext.length());

      textprintf(buffer, font,  0, 30, WHITE, "capacity: %d", edittext.capacity());

      textprintf(buffer, font,  0, 40, WHITE, "empty?:   %d", edittext.empty());

      if(insert)

         textout(buffer, font, "Inserting", 0, 50, WHITE);

      else

         textout(buffer, font, "Replacing", 0, 50, WHITE);



      // draw the caret

      vline(buffer, caret * 8, 8, 18, WHITE);



      // blit to screen

      blit(buffer, screen, 0, 0, 0, 0, 320, 240);



   }while(!key[KEY_ESC]); // end of game loop

   

   // clean up

   destroy_bitmap(buffer);

   set_gfx_mode(GFX_TEXT, 0, 0, 0, 0);

   

   return 0;

}

END_OF_MAIN()


I hope that was helpful to you. Comments, questions, feedback, etc. can be posted in the forums or sent to crbarry@mts.net.



0 Comments

Note: GameDev.net moderates article comments.