Adding a Chat Queue

From IrrWizard

Jump to: navigation, search

Contents

Indroduction

This article will show you how to add g0dsoft's ChatQue. The original post can be found on the Irrlicht forum here


ChatQue class

Copy and paste the ChatQue.h and ChatQue.cpp, and add it to the 'engine' folder of the project. Pay no attention to the length of code, it's just a strict copy/paste job.

ChatQue.h:

/*
chatQue is copyright g0dsoft 2006
Version: 0.1
Code by: Mark Laprairie
Contact: webmaster@g0dsoft.com
Url: www.g0dsoft.com

chatQue.h
ChatQue is a object for simulating half-life style chat display
capable of colors, fading away, shadows and any custom font.

Example usage
ChatQue que(device,rect<s32>(0,0,100,100),5000,true,500);
que.addMessage(L"Hello world!");
//Just befor you call driver->endScene();
que.draw();

ToDo:
     -Length clipping for text that leaves the rect.
     -Word wrapping.
(If you make these changes,  make sure to tell me!)

*/

#ifndef __CHATQUE_H__
#define __CHATQUE_H__

#define CHATQUE_STRINGLENGTH 240

#include <irrlicht.h>
#include <list>

using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;
using namespace std;

class ChatQue {
public:
    //Constructor
    ChatQue(IrrlichtDevice * device,const core::rect<s32> drawArea,float textLife = 5000, 
bool setFade = false, float fadeTime = 1000.00, bool setShadows = true);
    ~ChatQue();
    //Main Functions
    void addMessage(const wchar_t* text,SColor chatColor = SColor(255,255,255,255), 
SColor  chatColorShadow = SColor(255,0,0,0));

    void addMessage(wchar_t* text,SColor chatColor = SColor(255,255,255,255),
SColor chatColorShadow = SColor(255,0,0,0));
    void addMessage(core::stringw text,SColor chatColor = SColor(255,255,255,255), 
SColor  chatColorShadow = SColor(255,0,0,0));

    void draw();
    
    void setFade(bool setFade = true);
    void setRect(const core::rect<s32> drawArea);
    void setFadeTime(float fadeTime = 1000.00);
    void setFont(irr::gui::IGUIFont* font);
    void setMaxLines(unsigned short maxLines);
    void setShadows(bool setShadows = true);
    void setVisible(bool setVisible = true);
    void setLife(float setLife = 1000);
    void setDebug(bool setDebug = true);
    
protected: 
    //Helper functions
    void chatQue_calculateRect(const core::rect<s32> drawArea);
    void chatQue_calculateFontHeight(irr::gui::IGUIFont* font);
    void chatQue_calculateMaxLines();
    
    struct chatQueMessage{
        wchar_t message[CHATQUE_STRINGLENGTH];
        SColor chatColor;
        SColor chatColorShadow;
        SColor chatColorFade;
        SColor chatColorShadowFade;
        float created;
        float fade;
        bool chatQue_memoryManaged;
    };  
    
    //Rect replacment
    unsigned int m_xWidth;
    unsigned int m_yHeight;
    unsigned int m_y;
    unsigned int m_x; 
    //Font height
    unsigned short m_fontHeight;
    
    IrrlichtDevice* chatQue_device;
    bool chatQue_fade;
    bool chatQue_shadows;
    bool chatQue_visible;
    bool chatQue_debug;
    float chatQue_fadeTime;
    float chatQue_life;
    unsigned short chatQue_maxLines;
    std::list<chatQueMessage> chatQue_list;
    IGUIFont* chatQue_font;
 };

#endif //chatque.h

ChatQue.cpp:

/*
chatQue is copyright g0dsoft 2006
Version: 0.1
Code by: Mark Laprairie
Contact: webmaster@g0dsoft.com
Url: www.g0dsoft.com

chatQue.cpp
ChatQue is a object for simulating half-life style chat display
capable of colors, fading away, shadows and any custom font.

Example usage
ChatQue que(device,rect<s32>(0,0,100,100),5000,true,500);
que.addMessage(L"Hello world!");
//Just befor you call driver->endScene();
que.draw();

ToDo:
     -Length clipping for text that leaves the rect.
    -Word wrapping.
*/

#include "chatQue.h"

ChatQue::ChatQue(IrrlichtDevice * device,const core::rect<s32> drawArea,float textLife,
bool setFade, float fadeTime, bool setShadows)
{
    chatQue_device = device;
    chatQue_fade = setFade;
    m_fontHeight = 0;
    chatQue_calculateRect(drawArea);
    chatQue_font = device->getGUIEnvironment()->getFont("media/font_lucida.bmp");
    setFont(chatQue_font);
    chatQue_life = textLife;
    chatQue_visible = true;
    chatQue_debug = false;
    chatQue_fadeTime = fadeTime;
}

ChatQue::~ChatQue()
{
  std::list<chatQueMessage>::iterator iter;
  for (iter=chatQue_list.begin(); iter != chatQue_list.end(); iter++)
  {     
        if(iter->chatQue_memoryManaged == true)
           delete iter->message;
  }
  chatQue_list.erase(chatQue_list.begin(),chatQue_list.end());
}
 
void ChatQue::addMessage(wchar_t* text, SColor chatColor, SColor chatColorShadow)
{
  addMessage((const wchar_t*) text,chatColor,chatColorShadow);
}

void ChatQue::addMessage(core::stringw text, SColor chatColor, SColor chatColorShadow)
{
  addMessage((const wchar_t*) text.c_str(),chatColor,chatColorShadow);
}

void ChatQue::addMessage(const wchar_t* text, SColor chatColor, SColor chatColorShadow)
{
    chatQueMessage lmsg;
    wcscpy(lmsg.message,text);
    lmsg.chatColor = chatColor;
    lmsg.chatColorShadow = chatColorShadow;
    lmsg.fade = 0;
    lmsg.chatQue_memoryManaged = false;
    lmsg.created = chatQue_device->getTimer()->getTime();
    chatQue_list.push_front(lmsg);
}

void ChatQue::draw()
{
  //Debug
  if(chatQue_debug && chatQue_visible)
    chatQue_device->getVideoDriver()->draw2DRectangle(video::SColor(100,155,155,255),
         core::rect<s32>(m_x, m_y - m_yHeight,m_x + m_xWidth,m_y));    
  //Main Update/Draw
  std::list<chatQueMessage>::iterator iter;
  unsigned short count = 0;
  unsigned int m_y_tmp = m_y;
  u32 l_time = chatQue_device->getTimer()->getTime();
  for (iter=chatQue_list.begin(); iter != chatQue_list.end(); iter++)
  { 
     //Max lines means no fade, special case delete
     if(count > chatQue_maxLines){
        if(iter->chatQue_memoryManaged == true)
           delete iter->message;
        chatQue_list.erase(iter,chatQue_list.end());
        return;
     }
     //Update
     if((iter->created + chatQue_life) < l_time){
        if(chatQue_fade){
            if(iter->fade == 0){
                iter->fade = l_time;
                iter->chatColorFade = iter->chatColor;
                iter->chatColorShadowFade = iter->chatColorShadow;
            }
            //Fade code
            f32 l_alpha = (   (f32)(l_time - iter->fade)/(f32)chatQue_fadeTime );
            iter->chatColor = iter->chatColorFade.getInterpolated(SColor(0,0,0,0),1-l_alpha);
            iter->chatColorShadow = iter->chatColorShadowFade.
getInterpolated(SColor(0,0,0,0),1-l_alpha);
        }
        if( ((l_time - iter->fade) >= chatQue_fadeTime) || !chatQue_fade ){
            if(iter->chatQue_memoryManaged == true)
               delete iter->message;
            chatQue_list.erase(iter,chatQue_list.end());
            return;
        }
     } 
     //Draw
     if (chatQue_visible){
         if (chatQue_font){
            if (chatQue_shadows)
                chatQue_font->draw(iter->message,
                  core::rect<s32>(m_x + 1,m_y_tmp - m_fontHeight+ 1,m_x+m_xWidth + 1,m_y_tmp + 1),
                  iter->chatColorShadow);        
            
            chatQue_font->draw(iter->message,
              core::rect<s32>(m_x,m_y_tmp - m_fontHeight,m_x+m_xWidth,m_y_tmp),
              iter->chatColor);    
            m_y_tmp -= m_fontHeight;
         }
     }
     count++;
  }
}
 
//!-- Start Helpers
 
void ChatQue::chatQue_calculateRect(const core::rect<s32> drawArea)
{
  m_xWidth  = drawArea.getWidth();
  m_yHeight = drawArea.getHeight();
  position2d<s32> l_positionTmp = drawArea.LowerRightCorner;
  m_y = l_positionTmp.Y;
  l_positionTmp = drawArea.UpperLeftCorner;
  m_x = l_positionTmp.X;  
}
 
void ChatQue::chatQue_calculateFontHeight(irr::gui::IGUIFont* font)
{
    dimension2d<s32> l_fontHeight = chatQue_font->getDimension(L"|");
    m_fontHeight = l_fontHeight.Height;   
}

void ChatQue::chatQue_calculateMaxLines()
{
    chatQue_maxLines = ((m_yHeight - m_fontHeight) / m_fontHeight);     
}

//!-- End Helpers

void ChatQue::setFade(bool setFade)
{
    chatQue_fade = setFade;
}
 
void ChatQue::setRect(const core::rect<s32> drawArea)
{
    chatQue_calculateRect(drawArea);
}
 
void ChatQue::setFadeTime(float fadeTime)
{
    chatQue_fadeTime = fadeTime;
}
 
void ChatQue::setFont(irr::gui::IGUIFont* font)
{    
    chatQue_font = font;
    chatQue_calculateFontHeight(font);
    chatQue_calculateMaxLines();
}
 
void ChatQue::setLife(float setLife)
{
    chatQue_life = setLife;
}

void ChatQue::setShadows(bool setShadows)
{
    chatQue_shadows = setShadows;
}

void ChatQue::setVisible(bool setVisible)
{
    chatQue_visible = setVisible;
}
 
void ChatQue::setDebug(bool setDebug)
{
    chatQue_debug = setDebug;
}
 

Adding to GameManager

In the CGameManager header file add a forward declaration for the ChatQue class , a private member pointer to the ChatQue and a public accessor, getChatQueue().

CGameManager.h:

...
class ChatQue;
class CGameManager : public IEventReceiver
{
public:
 	ChatQue* getChatQueue();
...
private:
       ChatQue* m_pChatQueue;
...

Now add the header file include and accessor function:

CGameManager.cpp

#include "../engine/chatQue.h"
//! Returns a pointer to the ChatQueue
ChatQue* CGameManager::getChatQueue()
{
    return m_pChatQueue;
}

Initialise the ChatQue in the Init() function of CGameManager:

void CGameManager::Init()
{
  ...
  // Chat queue
  m_pChatQueue = new ChatQue(this->getDevice(),rect<s32>(100,500,700,700),5000,true,500);

Using the ChatQueue

It can now be used via the GameManager anywhere in the system. It can be padded out with spaces for correct alignment if required.

void CGameStateLevel01::Init(CGameManager* pManager)
{
    ...	
    pManager->getChatQueue()->addMessage(L"Hello world chatqueue"); 
    ...
}
Personal tools