Paranoia2/cl_dll/vgui_subtitles.cpp

324 lines
7.8 KiB
C++

// ====================================
// Paranoia subtitle system interface
// written by BUzer
// ====================================
#include "hud.h"
#include "cl_util.h"
#include "const.h"
#include "entity_types.h"
#include "cdll_int.h"
#include "vgui_TeamFortressViewport.h"
#include "vgui_subtitles.h"
#include "VGUI_TextImage.h"
cvar_t *time_min;
cvar_t *time_max;
cvar_t *subtitles_enabled;
cvar_t *scroll_speed;
cvar_t *fade_speed;
Font* FontFromMessage(char* &ptext)
{
char fontname[64] = "Default Text";
if (ptext != NULL && ptext[0] != 0)
{
if (ptext[0] == '@')
{
// get font name
ptext++;
ptext = gEngfuncs.COM_ParseFile((char*)ptext, fontname);
ptext+=2;
}
}
CSchemeManager *pSchemes = gViewPort->GetSchemeManager();
SchemeHandle_t hTextScheme = pSchemes->getSchemeHandle( fontname );
return pSchemes->getFont( hTextScheme );
}
void SubtitleMessageAdd( client_textmessage_t *tempMessage )
{
if (!subtitles_enabled->value)
return;
if (gViewPort && gViewPort->m_pSubtitle)
gViewPort->m_pSubtitle->AddMessage( tempMessage );
else
gEngfuncs.Con_Printf("Subtitle error: CSubtitle or ViewPort is not constructed!\n");
}
void SubtitleInit()
{
time_min = gEngfuncs.pfnRegisterVariable( "subt_mintime", "0", 0 );
time_max = gEngfuncs.pfnRegisterVariable( "subt_maxtime", "0", 0 );
subtitles_enabled = gEngfuncs.pfnRegisterVariable( "subtitles", "0", FCVAR_ARCHIVE );
scroll_speed = gEngfuncs.pfnRegisterVariable( "subt_scrollspd", "250", 0 );
fade_speed = gEngfuncs.pfnRegisterVariable( "subt_fadespd", "0.2", 0 );
}
void CSubtitleTextPanel::paintBackground()
{
float fade = fade_speed->value;
float time = gEngfuncs.GetClientTime();
int r, g, b, a;
getFgColor(r, g, b ,a);
if (m_fBirthTime && (m_fBirthTime + fade > time))
{
float alpha = (time - m_fBirthTime) / fade;
setFgColor( r, g, b, 255 - (alpha * 255));
/* if (bkalpha)
{
// draw background
getBgColor(r, g, b ,a);
drawSetColor(r, g, b, 255 - (alpha * bkalpha));
drawFilledRect(0, 0, getWide(), getTall());
}*/
return;
}
if (gViewPort && gViewPort->m_pSubtitle) // hm..
{
if (gViewPort->m_pSubtitle->m_pCur == this)
{
float dietime = gViewPort->m_pSubtitle->m_fCurStartTime + m_fHoldTime;
if (dietime - fade < time)
{
float alpha = (dietime - time) / fade;
setFgColor( r, g, b, 255 - (alpha * 255));
/* if (bkalpha)
{
getBgColor(r, g, b ,a);
setBgColor(r, g, b, 255 - (alpha * bkalpha));
TextPanel::paintBackground();
}*/
return;
}
}
}
setFgColor( r, g, b, 0 );
}
void CSubtitleTextPanel::paint()
{
int mr, mg, mb, ma;
int ix, iy;
getFgColor(mr, mg, mb, ma);
getTextImage()->getPos(ix, iy);
getTextImage()->setPos(ix+1, iy+1);
getTextImage()->setColor( Color(0, 0, 0, ma) );
getTextImage()->doPaint(this);
getTextImage()->setPos(ix, iy);
getTextImage()->setColor( Color(mr, mg, mb, ma) );
getTextImage()->doPaint(this);
}
CSubtitle::CSubtitle() : Panel(XRES(10), YRES(10), XRES(330), YRES(240))
{
m_pLayer = new Panel;
m_pLayer->setParent(this);
m_pLayer->setPaintBackgroundEnabled(false);
setVisible(false);
m_pCur = NULL;
m_pWait = NULL;
lasttime = 0;
layerpos = 0;
}
void CSubtitle::Initialize()
{
m_pLayer->removeAllChildren();
setVisible(false);
m_pCur = NULL;
m_pWait = NULL;
lasttime = 0;
layerpos = 0;
}
void CSubtitle::AddMessage( client_textmessage_t *msg )
{
float time = gEngfuncs.GetClientTime();
float holdtime = msg->holdtime;
if (time_min->value && (holdtime < time_min->value)) holdtime = time_min->value;
if (time_max->value && (holdtime > time_max->value)) holdtime = time_max->value;
// CSchemeManager *pSchemes = gViewPort->GetSchemeManager();
// SchemeHandle_t hTextScheme = pSchemes->getSchemeHandle( "Default Text" );
// Font *pFont = pSchemes->getFont( hTextScheme );
char *pText = (char*)msg->pMessage;
client_textmessage_t *postMsg = NULL;
if (pText[0] == '$')
{
// get postMsg
char postMsgName[64];
pText = gEngfuncs.COM_ParseFile((char*)pText, postMsgName);
postMsg = TextMessageGet( &postMsgName[1] );
pText+=2;
if (!postMsg)
gEngfuncs.Con_Printf("WARNING: post-message %s not found in titles.txt!\n", postMsgName);
}
Font *pFont = FontFromMessage(pText);
int tw, th;
CSubtitleTextPanel *text = new CSubtitleTextPanel(pText, 0, 0, getWide(), 64 );
text->setParent( m_pLayer );
text->setFont(pFont);
text->msgAfterDeath = postMsg;
// text->setPaintBackgroundEnabled(false);
// text->setBgColor(msg->r2, msg->g2, msg->b2, 255);
// text->bkalpha = msg->fadeout;
// gEngfuncs.Con_Printf("added bkalpha: %d\n", text->bkalpha);
text->setFgColor(msg->r1, msg->g1, msg->b1, 0);
text->getTextImage()->getTextSizeWrapped( tw, th );
text->getTextImage()->setPos(0, 5);
th += 10;
text->setSize( getWide(), th );
text->m_fHoldTime = holdtime;
if (!isVisible())
{
layerpos = getTall()-th;
m_pLayer->setBounds(0, layerpos, getWide(), th);
text->m_fBirthTime = time;
m_fCurStartTime = time;
m_pCur = text;
m_pWait = NULL;
text->setVisible(true);
setVisible(true);
}
else
{
text->setVisible(false);
text->m_fBirthTime = 0;
if (!m_pWait)
{
int lt = m_pLayer->getTall();
m_pLayer->setSize(getWide(), lt+th);
text->setPos(0, lt);
m_pWait = text;
}
}
}
void CSubtitle::paintBackground()
{
float curtime = gEngfuncs.GetClientTime();
if (lasttime == 0) lasttime = curtime;
float deltatime = curtime - lasttime;
if (!subtitles_enabled->value)
{
Initialize();
return;
}
if (m_pCur)
{
if (m_fCurStartTime + m_pCur->m_fHoldTime <= curtime)
{
m_fCurStartTime = curtime;
client_textmessage_t *newmsg = m_pCur->msgAfterDeath;
m_pLayer->removeChild(m_pCur);
m_pCur = NULL;
if (newmsg)
AddMessage(newmsg);
if (m_pLayer->getChildCount() == 0)
{
m_pWait = NULL;
setVisible(false);
return;
}
// find oldest child to start fading int
float mintime = 99999;
int i;
for (i = 0; i < m_pLayer->getChildCount(); i++)
{
CSubtitleTextPanel *chld = (CSubtitleTextPanel*)m_pLayer->getChild(i);
if (chld->isVisible() && chld->m_fBirthTime < mintime)
{
m_pCur = chld;
mintime = chld->m_fBirthTime;
}
}
if (!m_pCur)
{
// get cur from waiting queue
m_pCur = m_pWait;
if (m_pCur)
{
layerpos = getTall() - m_pCur->getTall();
m_pLayer->setBounds(0, layerpos, getWide(), m_pCur->getTall());
m_pCur->setPos(0,0);
m_pCur->m_fBirthTime = curtime;
m_pCur->setVisible(true);
m_pWait = NULL;
for (i = 0; i < m_pLayer->getChildCount(); i++)
{
if (!m_pLayer->getChild(i)->isVisible())
{
m_pWait = (CSubtitleTextPanel*)m_pLayer->getChild(i);
int lt = m_pLayer->getTall();
m_pLayer->setSize(getWide(), lt + m_pWait->getTall());
m_pWait->setPos(0, lt);
break;
}
}
}
else
{
gEngfuncs.Con_Printf("ERROR: subtitles - has childs but no lists!\n");
setVisible(false);
return;
}
}
}
}
if (m_pWait)
{
float rest = layerpos + m_pLayer->getTall() - getTall();
float spd = rest > 40 ? 0.5 : (rest / 40 * 0.5); spd += 0.5;
layerpos -= (deltatime * scroll_speed->value * spd);
// gEngfuncs.Con_Printf("layerpos: %f, spd: %f, deltatime: %f, cvarspeed: %f\n", layerpos, spd, deltatime, scroll_speed->value);
if (layerpos + m_pLayer->getTall() <= getTall())
{
layerpos = getTall() - m_pLayer->getTall();
m_pWait->setVisible(true);
m_pWait->m_fBirthTime = curtime;
// find next waiting message
m_pWait = NULL;
for (int i = 0; i < m_pLayer->getChildCount(); i++)
{
if (!m_pLayer->getChild(i)->isVisible())
{
m_pWait = (CSubtitleTextPanel*)m_pLayer->getChild(i);
int lt = m_pLayer->getTall();
m_pLayer->setSize(getWide(), lt + m_pWait->getTall());
m_pWait->setPos(0, lt);
break;
}
}
}
m_pLayer->setPos(0, layerpos);
}
lasttime = curtime;
// Panel::paintBackground();
}