Jump to content

  • Log In with Google      Sign In   
  • Create Account


Like
0Likes
Dislike

Text Input in an Allegro Game

By Chris "23yrold3yrold" Barry | Published Aug 14 2004 07:44 AM in Game Programming

edittext version c++ string int buffer char allegro caret
If you find this article contains errors or problems rendering it unreadable (missing images or files, mangled code, improper text formatting, etc) please contact the editor so corrections can be made. Thank you for helping us improve this resource



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.








Comments

Note: Please offer only positive, constructive comments - we are looking to promote a positive atmosphere where collaboration is valued above all else.




PARTNERS