🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

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