PART II

In part two we will try to read a text inputed by user. For that we have to define a array of chars where we will store our string. (yea, i know that array of chars isn’t best way to do that but i wanted to do it simple) So, declarations:

char message[256]; //Message array
char ch = 0;       //Single char for reading
int index = 0;     //index to message array
bool sts = false;  //Something to send variable
                   //It tells program is there anything to send

Now, let’s take a look to our GetInput() function.

void GetInput()
{
     if(key[KEY_ESC]) exit_chat = true;
}

Yea, there is only exiting for now. For reading user input the easiest way is to use readkey() function. Allegro keyboard array is great, but we cannot write hundred times if(key[KEY_A]) message[index] = ‘a’; if(key[KEY_B]) message[index] = ‘b’; ... and so on. Thats why we use readkey(). But there is problem, readkey() pauses cpu and waits for input, and we don’t want that because program wouldn’t be able to do any operation. To avoid this, we use other smart function: keypressed(). It checks if there is something in keyboard queue waiting to be read. So, the code which we will add to GetInput() should look like this

 
     if(keypressed()) //Function to check if there is any char waiting
     {                 
       ch = readkey();                 
       message[index++] = ch; //Putting char to array and then
                              //incrementing index
       textprintf_ex(buffer, font, text_length(font, nickname)+15,
       SCREEN_H-76, makecol(255,255,255), makecol(0,0,0), "%s", message); 
       if(index>255) index = 255; //Brutal forcing index not to
                                  //writing over the array
     }

text_lenght(FONT*, const char*) is a allegro function to checking size in pixels of string. We use it to avoid writing ON nickname.

Yea, thats great, but sometimes you may make a mistake and you want to undo what you have written. For this, we use ←Backspace key:

     if(key[KEY_BACKSPACE] && index > 0)
     {
           message[--index] = 0; //Decrementing index and then
                                 //clearing array of mistaken char
           do{}while(key[KEY_BACKSPACE]); //pausing, used to avoid
                                          //clearing too meany chars
           
           clear_to_color(buffer, makecol(0, 0, 0)); //clearing writng_screen
           textprintf_ex(buffer, font, text_length(font, nickname)+15
           , SCREEN_H-76, makecol(255,255,255), makecol(0,0,0), "%s", napis);
           clear_keybuf(); //remove backspace from keyboard queue
     }

You have to remember that this part of code must be BEFORE reading. (if(keypressed) ...and so on) Now, we probably want to accept what we have written. In every chat program we use Enter for that and i think it’s so obvious that i’m wondering why im writing it here :P

But there is one more thing. We will need a function to put our message to talk_screen. And, it would be cool if this function scrolled our talk_screen. So, here is a example of that kind of function:

void put_string(char* nick, char* msg)
{
     static int y_pos = 30; //Position where our message
     textprintf_ex(talk_screen, font, 1, y_pos, makecol(255,255,255), -1, "%s> %s", nick,msg); 
     y_pos+=15;
 
     //Scroling
     if(y_pos>330) 
     {
        blit(talk_screen, talk_screen_temp, 0, 0, 0, 0, talk_screen_temp->w, talk_screen_temp->h); 
        clear_to_color(talk_screen, makecol(128, 128, 128));     
        blit(talk_screen_temp, talk_screen, 0, 105, 0, 0, talk_screen_temp->w, talk_screen_temp->h);
        y_pos-=105;
     }
      
}

The first part is simple. We have static position and incrementing position every time we write something. The second part, scrolling, is simple too ;) We copy our talk_screen to temporary bitmap, we clear talk_screen and, at last, we copy back temporary bitmap but a litte higher. At the end, we are decrementing position of next message.

Now, we can get back to our GetInput function and make it work!

As you remember i was writing about using enter etc ;). So, code it:

     if(key[KEY_ENTER] || key[KEY_ENTER_PAD])
     {
           put_string(nickname, message); //Drawing our message
           index = 0;                     //clearing index
           do{}while(key[KEY_ENTER] || key[KEY_ENTER_PAD]); //pausing
           clear_keybuf();                //clearing keyboard queue
           clear_to_color(buffer, makecol(0, 0, 0)); //clearing buffer
           sts = true;                    //telling our networking
                                          //engine (which doesn't exist
                                          //for now) that there is
                                          //something to send 
     }

Also remember to put this on top of the GetInput() func (but not before exiting) Now, we can compile it and see how it works but wait a while. In our Process() function we should add those litte lines:

void Process()
{
      // sts is true when there is something to send
      // zoidcom will do it's work here later
      if(sts) 
      {
        sts = false;      
        for(int u = 0; u < 256; u++)
        message[u] = 0; 
      }
}

Now, we got super single-computer chat. But there is a problem, we probably want to chat with someone, not only with ourselfs. Read how to do it (and at last use zoidcom!) in part III.

Complete source code (including part I):

#include <zoidcom.h> //Zoidcom library include
#include <allegro.h> //Allegro library include
#include <conio.h>   //Windows library for getch() func
 
BITMAP* buffer;
BITMAP* talk_screen;
BITMAP* talk_screen_temp;
 
bool exit_chat = false;
char* nickname;
 
char message[256]; //Message array
char ch = 0;       //Single char for reading
int index = 0;     //index to message array
bool sts = false;  //Something to send variable
                   //It tells program is there anything to send
 
 
 
void put_string(char* msg, char* nick)
{
     static int y_pos = 30; //Position where our message
     textprintf_ex(talk_screen, font, 1, y_pos, makecol(255,255,255), -1, "%s> %s", nick,msg); 
     y_pos+=15;
 
     //Scroling
     if(y_pos>330) 
     {
        blit(talk_screen, talk_screen_temp, 0, 0, 0, 0, talk_screen_temp->w, talk_screen_temp->h); 
        clear_to_color(talk_screen, makecol(128, 128, 128));     
        blit(talk_screen_temp, talk_screen, 0, 105, 0, 0, talk_screen_temp->w, talk_screen_temp->h);
        y_pos-=105;
     }
      
}
 
 
void start()
{
   allegro_init(); //Allegro needed function
   install_keyboard(); //Instaling keyboard
 
   //////////////// GRAPHICS INIT /////////////////////////////////
   set_color_depth(16); 
   if(set_gfx_mode(GFX_AUTODETECT_WINDOWED, 640, 480, 0, 0) <= -1)
   {
      set_color_depth(15);
      if(set_gfx_mode(GFX_AUTODETECT_WINDOWED, 640, 480, 0, 0) <= -1)
      {
         allegro_message("Error initializating graphics", NULL);
         exit(1);
      }
   }      
   //////////////// WINDOW PROCEDURES ////////////////////////////
   // Window title, write everything you want here
   set_window_title("Chatic v0.01 SERWER");
 
   // callback function for this litte [X] button in top right of
   // your window, we will write it soon, if you dont want it
   // just comment this line 
   //set_close_button_callback(close_button_handler);
 
   //For working in background, very important.
   //You will get strange results if you dont put this line
   set_display_switch_mode(SWITCH_BACKGROUND);
 
 
   //For double buffering
   buffer = create_bitmap(SCREEN_W,SCREEN_H);
 
   //Our chat will be composited with two windows:
   //talk_screen where messages are being displayed,
   //and write_screen where you type your message.
   //write_screen isnt really exist, we will write
   //directly on buffer
   // (-81) is size of talk screen and also size of write_screen
   talk_screen = create_bitmap(SCREEN_W, SCREEN_H-81);
 
   //temporary bitmap, we will need it to make text move
   //smothly
   talk_screen_temp = create_bitmap(SCREEN_W, SCREEN_H-81);
 
   //clearing bitmaps
   clear_to_color(buffer, makecol(0, 0, 0));
   clear_to_color(talk_screen, makecol(128, 128, 128));
   clear_to_color(talk_screen_temp, makecol(128, 128, 128));
 
 
   //Configuration
   //I've maked simple config file to read your nickname
   //and other options, if you don't want to use it, comment
   //this but rememer to declare char* nickname = "nickname";
     push_config_state();
      set_config_file("config.ini");
      nickname = ustrdup(get_config_string("user", "name", "noname"));
     pop_config_state();
 
   //Messages on start
   textprintf_ex(talk_screen, font, 1, 1, makecol(255,255,255), -1, "Chatic version 0.01 SERVER started..."); 
   textprintf_ex(talk_screen, font, 1, 15, makecol(255,255,255), -1, "All ok..."); 
   
}
 
void DrawAll()
{
    //Lines for divide talk_screen from write_screen
    line(buffer, 0, SCREEN_H-79, SCREEN_W, SCREEN_H-79, makecol(192,192,192));
    line(buffer, 0, SCREEN_H-80, SCREEN_W, SCREEN_H-80, makecol(255,255,255));
    line(buffer, 0, SCREEN_H-81, SCREEN_W, SCREEN_H-81, makecol(192,192,192));
 
    //Your nickname should be always drawed to write_screen
    //I will explain why, later
    textprintf_ex(buffer, font, 1, SCREEN_H-76, makecol(255,255,255), -1, "%s>", nickname); 
 
    //Drawing talk_screen to buffer and buffer to screen
    blit(talk_screen, buffer, 0, 0, 0, 0, talk_screen->w, talk_screen->h);
    blit(buffer, screen, 0, 0, 0, 0, SCREEN_W, SCREEN_H);
     
}
 
void Process()
{
      if(sts) 
      {
        sts = false;      
        for(int u = 0; u < 256; u++)
        message[u] = 0; 
      }
}
 
void GetInput()
{
     if(key[KEY_ESC]) exit_chat = true;
     
     if(key[KEY_ENTER] || key[KEY_ENTER_PAD])
     {
           put_string(message, nickname); //Drawing our message
           index = 0;                     //clearing index
           do{}while(key[KEY_ENTER] || key[KEY_ENTER_PAD]); //pausing
           clear_keybuf();                //clearing keyboard queue
           clear_to_color(buffer, makecol(0, 0, 0)); //clearing buffer
           sts = true;                    //telling our networking
                                          //engine (which doesn't exist
                                          //for now) that there is
                                          //something to send 
     }
     
     if(key[KEY_BACKSPACE] && index > 0){
           
           message[--index] = 0;
           do{}while(key[KEY_BACKSPACE]);
           
           clear_to_color(buffer, makecol(0, 0, 0));
           textprintf_ex(buffer, font, text_length(font, nickname)+15
           , SCREEN_H-76, makecol(255,255,255), makecol(0,0,0), "%s", message);
           clear_keybuf(); 
           } 
     
     if(keypressed()) 
     {                 
       ch = readkey();                 
       message[index++] = ch;
       textprintf_ex(buffer, font, text_length(font, nickname)+15,
       SCREEN_H-76, makecol(255,255,255), makecol(0,0,0), "%s", message); 
       if(index>255) index = 255; //Brutal forcing index not to
                                  //writing over the array
     }
}
 
void shutdown()
{
    destroy_bitmap(buffer);
    destroy_bitmap(talk_screen);
    destroy_bitmap(talk_screen_temp);
    allegro_exit();
}
 
int main() 
{
    start();
    do {
        DrawAll();
        GetInput();
        Process();
 
        
    } while(!exit_chat);     
    shutdown();
 
    
  return 0;   
}
END_OF_MAIN();
 
allegrozoidcomchat2.txt · Last modified: 2006/10/25 20:16 by sharkyx
 
Recent changes RSS feed Creative Commons License Donate Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki