Adding a Chat Queue
From IrrWizard
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");
...
}
