Text Input in an Allegro Game

Published August 14, 2004 by Chris "23yrold3yrold" Barry, posted by Myopic Rhino
Do you see issues with this article? Let us know.
Advertisement

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 

#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 
#include 
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.

Cancel Save
0 Likes 0 Comments

Comments

Nobody has left a comment. You can be the first!
You must log in to join the conversation.
Don't have a GameDev.net account? Sign up!
Advertisement