mirror of
https://github.com/ENSL/NS.git
synced 2024-12-11 21:31:04 +00:00
dc79b89150
git-svn-id: https://unknownworlds.svn.cloudforge.com/ns1@220 67975925-1194-0748-b3d5-c16f83f1a3a1
607 lines
17 KiB
C++
607 lines
17 KiB
C++
//======== (C) Copyright 2002 Charles G. Cleveland All rights reserved. =========
|
|
//
|
|
// The copyright to the contents herein is the property of Charles G. Cleveland.
|
|
// The contents may be used and/or copied only with the written permission of
|
|
// Charles G. Cleveland, or in accordance with the terms and conditions stipulated in
|
|
// the agreement/contract under which the contents have been supplied.
|
|
//
|
|
// Purpose:
|
|
//
|
|
// $Workfile: FadingImageLabel.cpp $
|
|
// $Date: 2002/09/09 19:46:34 $
|
|
//
|
|
//-------------------------------------------------------------------------------
|
|
// $Log: FadingImageLabel.cpp,v $
|
|
// Revision 1.16 2002/09/09 19:46:34 Flayra
|
|
// - Changes to try to make this draw properly in software
|
|
//
|
|
// Revision 1.15 2002/08/31 18:04:32 Flayra
|
|
// - Work at VALVe
|
|
//
|
|
// Revision 1.14 2002/07/23 16:52:59 Flayra
|
|
// - Added support for multiple sprite frames (for pie nodes and max sprite problem), added document headers
|
|
//
|
|
//===============================================================================
|
|
#include "ui/FadingImageLabel.h"
|
|
#include "ui/UIUtil.h"
|
|
#include "util/STLUtil.h"
|
|
|
|
#include <assert.h>
|
|
#include "cl_dll/hud.h"
|
|
#include "cl_dll/cl_util.h"
|
|
#include "common/const.h"
|
|
#include "common/com_model.h"
|
|
#include "engine/studio.h"
|
|
#include "common/entity_state.h"
|
|
#include "common/cl_entity.h"
|
|
#include "common/dlight.h"
|
|
#include "common/triangleapi.h"
|
|
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <memory.h>
|
|
#include <math.h>
|
|
|
|
#include "cl_dll/studio_util.h"
|
|
#include "cl_dll/r_studioint.h"
|
|
|
|
#include "cl_dll/StudioModelRenderer.h"
|
|
#include "cl_dll/GameStudioModelRenderer.h"
|
|
|
|
extern engine_studio_api_t IEngineStudio;
|
|
|
|
|
|
const char* kFrameIndicator = "-frame";
|
|
|
|
//FadingImageLabel::FadingImageLabel(const char* inImageName, int inX, int inY)/*, int inWidth, int inHeight)*/ : CImageLabel(inImageName, inX, inY, 64, 32), mTextImage("Default text")
|
|
//{
|
|
// this->Init();
|
|
//}
|
|
|
|
FadingImageLabel::FadingImageLabel(int inX, int inY)/*, int inWidth, int inHeight)*/ : /*Panel(inX, inY, 64, 32),*/ mTextImage("Default text")
|
|
{
|
|
this->Init();
|
|
this->mImageMode = false;
|
|
}
|
|
|
|
FadingImageLabel::~FadingImageLabel()
|
|
{
|
|
}
|
|
|
|
void FadingImageLabel::DoPaint()
|
|
{
|
|
//const float thePercentToChopOffXEdge = .1f;
|
|
//const float thePercentToChopOffYEdge = 0.0f;
|
|
|
|
int theX, theY;
|
|
this->getPos(theX, theY);
|
|
|
|
//if(!IEngineStudio.IsHardware())
|
|
//{
|
|
// theX += ScreenWidth/2;
|
|
// theY += ScreenHeight/2;
|
|
//}
|
|
|
|
int theWidth, theHeight;
|
|
this->getSize(theWidth, theHeight);
|
|
|
|
//ASSERT(this->mVisibleWidth <= theWidth);
|
|
//ASSERT(this->mVisibleHeight <= theHeight);
|
|
|
|
if((this->mVisibleWidth <= theWidth) && (this->mVisibleHeight <= theHeight))
|
|
{
|
|
int r, g, b, a;
|
|
this->getBgColor(r, g, b, a);
|
|
|
|
float theGammaSlope = gHUD.GetGammaSlope();
|
|
r = r/theGammaSlope;
|
|
g = g/theGammaSlope;
|
|
b = b/theGammaSlope;
|
|
|
|
// Don't take gamma slope into account for alpha
|
|
a = 255 - a;
|
|
|
|
////int theXBorder = thePercentToChopOffXEdge*ScreenWidth;
|
|
////int theYBorder = thePercentToChopOffYEdge*ScreenHeight;
|
|
int theXBorder = (theWidth - this->mVisibleWidth)/2;
|
|
int theYBorder = (theHeight - this->mVisibleHeight)/2;
|
|
|
|
//vguiSimpleBox(theXBorder, theYBorder, theWidth - theXBorder*2 + theXBorder, theHeight - theYBorder*2 + theYBorder, r, g, b, a);
|
|
|
|
if(!this->mImageMode)
|
|
{
|
|
//FillRGBA(theXBorder, theYBorder, theWidth - theXBorder*2, theHeight - theYBorder*2, r, g, b, a);
|
|
|
|
//int theSprite = Safe_SPR_Load("sprites/marinenode.spr");
|
|
//DrawScaledHUDSprite(theSprite, kRenderTransAdd, 1, theX, theY, theWidth, theHeight, 0);
|
|
|
|
gEngfuncs.pTriAPI->RenderMode(kRenderTransAlpha);
|
|
gEngfuncs.pTriAPI->CullFace(TRI_NONE);
|
|
//gEngfuncs.pTriAPI->Brightness(1);
|
|
theX = theXBorder;
|
|
theY = theYBorder;
|
|
theWidth = theWidth - theXBorder*2;
|
|
theHeight = theHeight - theYBorder*2;
|
|
|
|
// 0 = selectable, valid
|
|
// 1 = selectable, valid, current
|
|
// 2 = selectable, invalid
|
|
// 3 = selectable, invalid, current
|
|
int theFrame = 0;
|
|
|
|
if(this->GetEnabled() && this->GetDrawHighlighted())
|
|
{
|
|
theFrame = 1;
|
|
}
|
|
else if(!this->GetEnabled())
|
|
{
|
|
theFrame = this->GetFadeState() ? 3 : 2;
|
|
}
|
|
|
|
//char theFrameNumber[64];
|
|
//sprintf(theFrameNumber, "Frame %d", theFrame);
|
|
//this->mTextImage.setText(theFrameNumber);
|
|
|
|
if(!this->mSprite)
|
|
{
|
|
this->mSprite = Safe_SPR_Load(this->mImageName.c_str());
|
|
this->mSpriteWidth = SPR_Width(this->mSprite, this->mSpriteFrame);
|
|
this->mSpriteHeight = SPR_Height(this->mSprite, this->mSpriteFrame);
|
|
ASSERT(this->mSprite > 0);
|
|
}
|
|
|
|
if(this->mSprite && gEngfuncs.pTriAPI->SpriteTexture((struct model_s*)gEngfuncs.GetSpritePointer(this->mSprite), theFrame))
|
|
{
|
|
gEngfuncs.pTriAPI->Begin(TRI_TRIANGLE_STRIP);
|
|
|
|
vec3_t theVertex;
|
|
|
|
gEngfuncs.pTriAPI->TexCoord2f(0, 1);
|
|
theVertex.x = theX;
|
|
theVertex.y = theY + theHeight;
|
|
theVertex.z = 0;
|
|
//gEngfuncs.pTriAPI->Color4ub(255, 255, 255, a);
|
|
gEngfuncs.pTriAPI->Vertex3fv((float*)&theVertex);
|
|
|
|
gEngfuncs.pTriAPI->TexCoord2f(0, 0);
|
|
theVertex.x = theX;
|
|
theVertex.y = theY;
|
|
//gEngfuncs.pTriAPI->Color4ub(255, 255, 255, a);
|
|
gEngfuncs.pTriAPI->Vertex3fv((float*)&theVertex);
|
|
|
|
gEngfuncs.pTriAPI->TexCoord2f(1, 1);
|
|
theVertex.x = theX + theWidth;
|
|
theVertex.y = theY + theHeight;
|
|
//gEngfuncs.pTriAPI->Color4ub(255, 255, 255, a);
|
|
gEngfuncs.pTriAPI->Vertex3fv((float*)&theVertex);
|
|
|
|
gEngfuncs.pTriAPI->TexCoord2f(1, 0);
|
|
theVertex.x = theX + theWidth;
|
|
theVertex.y = theY;
|
|
//gEngfuncs.pTriAPI->Color4ub(255, 255, 255, a);
|
|
gEngfuncs.pTriAPI->Vertex3fv((float*)&theVertex);
|
|
|
|
gEngfuncs.pTriAPI->End();
|
|
}
|
|
|
|
gEngfuncs.pTriAPI->RenderMode(kRenderNormal);
|
|
}
|
|
else
|
|
{
|
|
SPR_Set(this->mSprite, a, a, a);
|
|
|
|
int theSpriteWidth = SPR_Width(this->mSprite, this->mSpriteFrame);
|
|
int theSpriteHeight = SPR_Height(this->mSprite, this->mSpriteFrame);
|
|
|
|
//SPR_DrawAdditive(theFrame, (theWidth - theSpriteWidth)/2, (theHeight - theSpriteHeight)/2, NULL);
|
|
SPR_DrawHoles(this->mSpriteFrame, (theWidth - theSpriteWidth)/2, (theHeight - theSpriteHeight)/2, NULL);
|
|
}
|
|
}
|
|
}
|
|
|
|
void FadingImageLabel::FadedIn()
|
|
{
|
|
Panel::setVisible(true);
|
|
}
|
|
|
|
void FadingImageLabel::FadedOut()
|
|
{
|
|
Panel::setVisible(false);
|
|
}
|
|
|
|
//vgui::Color FadingImageLabel::GetColor() const
|
|
//{
|
|
// return vgui::Color(255, 255, 255, this->GetValveAlpha());
|
|
//}
|
|
|
|
void FadingImageLabel::getBgColor(int& r, int& g, int& b, int& a)
|
|
{
|
|
Panel::getBgColor(r, g, b, a);
|
|
a = this->GetValveAlpha();
|
|
}
|
|
|
|
void FadingImageLabel::getBgColor(Color& outColor)
|
|
{
|
|
Panel::getBgColor(outColor);
|
|
|
|
int r, g, b, a;
|
|
outColor.getColor(r, g, b, a);
|
|
|
|
a = this->GetValveAlpha();
|
|
outColor.setColor(r, g, b, a);
|
|
}
|
|
|
|
void FadingImageLabel::getContentSize(int& wide, int& tall)
|
|
{
|
|
if(!this->mImageMode)
|
|
{
|
|
this->getTextSize(wide, tall);
|
|
}
|
|
else
|
|
{
|
|
wide = this->mSpriteWidth;
|
|
tall = this->mSpriteHeight;
|
|
}
|
|
}
|
|
|
|
bool FadingImageLabel::GetDrawHighlighted() const
|
|
{
|
|
return false;
|
|
}
|
|
|
|
bool FadingImageLabel::GetEnabled() const
|
|
{
|
|
return true;
|
|
}
|
|
|
|
bool FadingImageLabel::GetFadeState() const
|
|
{
|
|
return this->mFadeToVisibiltyState;
|
|
}
|
|
|
|
void FadingImageLabel::getTextSize(int& wide,int& tall)
|
|
{
|
|
int theTextWidth, theTextHeight;
|
|
this->mTextImage.getTextSize(theTextWidth, theTextHeight);
|
|
|
|
wide = theTextWidth;
|
|
tall = theTextHeight;
|
|
|
|
if(this->mSpriteWidth > theTextWidth)
|
|
{
|
|
theTextWidth = this->mSpriteWidth;
|
|
}
|
|
if(this->mSpriteHeight > theTextHeight)
|
|
{
|
|
theTextHeight = this->mSpriteHeight;
|
|
}
|
|
}
|
|
|
|
int FadingImageLabel::GetValveAlpha() const
|
|
{
|
|
return this->mValveAlpha;
|
|
}
|
|
|
|
void FadingImageLabel::GetVisibleSize(int& outWidth, int& outHeight)
|
|
{
|
|
outWidth = this->mVisibleWidth;
|
|
outHeight = this->mVisibleHeight;
|
|
}
|
|
|
|
void FadingImageLabel::Init()
|
|
{
|
|
// default time to fade in or out
|
|
this->mBaseFadeTime = .3f;
|
|
|
|
this->mTimeToFade = this->mBaseFadeTime;
|
|
this->mTimeVisChanged = -1;
|
|
this->mTimeScalar = 0.0f;
|
|
this->mMaxAlpha = 1.0f;
|
|
this->mVisibleWidth = 0;
|
|
this->mVisibleHeight = 0;
|
|
|
|
// this needs to be set to our visibility
|
|
this->mFadeToVisibiltyState = false;
|
|
this->mAlwaysDrawText = false;
|
|
|
|
// Valve keeps alpha backwards
|
|
this->mValveAlpha = (this->isVisible() ? 0 : 255);
|
|
|
|
this->mImageMode = false;
|
|
this->mSprite = 0;
|
|
this->mSpriteWidth = this->mSpriteHeight = 0;
|
|
this->mSpriteFrame = 0;
|
|
}
|
|
|
|
void FadingImageLabel::paint()
|
|
{
|
|
// Calculate current translucency
|
|
float theAlphaToUse = (this->mFadeToVisibiltyState ? this->mTimeScalar : 1.0f - this->mTimeScalar);
|
|
|
|
// Bias in accelerated fashion for dramatic effect (maps to sin(0-pi/2) so it fades fast then slows down)
|
|
theAlphaToUse = sin(theAlphaToUse*3.141519/2.0f);
|
|
|
|
// For some reason Valve thinks alpha of 255 is transparent
|
|
this->mValveAlpha = 255 - (int)(255.0f*theAlphaToUse);
|
|
|
|
//int r, g, b, a;
|
|
//theColor.getColor(r, g, b, a);
|
|
//this->setFgColor(r, g, b, a);
|
|
|
|
// Set translucency
|
|
//if(this->m_pTGA)
|
|
//{
|
|
// //this->m_pTGA->setColor(this->GetColor());
|
|
// vgui::Color theColor;
|
|
// this->getBgColor(theColor);
|
|
// //this->setBgColor(theColor);
|
|
// this->m_pTGA->setColor(theColor);
|
|
//
|
|
// //int r, g, b, a;
|
|
// //theColor.getColor(r, g, b, a);
|
|
// //this->setFgColor(r, g, b, a);
|
|
//}
|
|
//else
|
|
//{
|
|
// ASSERT(false);
|
|
//}
|
|
|
|
// Figure out whether we're in image mode or not
|
|
|
|
this->DoPaint();
|
|
|
|
// Draw text on top when faded in (check < 2 in case rounding makes it negative)
|
|
if((this->mValveAlpha < 2 || this->mAlwaysDrawText) && (!this->mImageMode))
|
|
{
|
|
// Fade text out as well
|
|
Color theColor;
|
|
this->mTextImage.getColor(theColor);
|
|
|
|
int r, g, b, a;
|
|
theColor.getColor(r, g, b, a);
|
|
//theColor.setColor(r, g, b, this->mValveAlpha);
|
|
//this->mTextImage.setColor(theColor);
|
|
//this->mTextImage.doPaint(this);
|
|
|
|
int theX, theY;
|
|
this->getPos(theX, theY);
|
|
|
|
int theWidth, theHeight;
|
|
this->getSize(theWidth, theHeight);
|
|
|
|
const AvHFont& theFont = gHUD.GetSmallFont();
|
|
|
|
float theTextX = (theWidth - theFont.GetStringWidth(mText.c_str())) / 2;
|
|
float theTextY = (theHeight - theFont.GetStringHeight()) / 2;
|
|
|
|
theFont.DrawString(theTextX, theTextY, mText.c_str(), r, g, b);
|
|
|
|
}
|
|
}
|
|
|
|
void FadingImageLabel::paintBackground()
|
|
{
|
|
// Do nothing, we don't draw in our bg color anymore, we only draw in FillRGBA
|
|
int a = 0;
|
|
}
|
|
|
|
// Called
|
|
void FadingImageLabel::RecalculateTextPosition()
|
|
{
|
|
int theLabelWidth, theLabelHeight;
|
|
this->getSize(theLabelWidth, theLabelHeight);
|
|
|
|
int theTextWidth, theTextHeight;
|
|
this->mTextImage.getTextSize(theTextWidth, theTextHeight);
|
|
|
|
// Center text in middle of label
|
|
if((theTextWidth <= theLabelWidth) && (theTextHeight <= theLabelHeight))
|
|
{
|
|
this->mTextImage.setPos(theLabelWidth/2 - theTextWidth/2, theLabelHeight/2 - theTextHeight/2);
|
|
}
|
|
// If it can't be centered on image, align with upper left corner
|
|
else
|
|
{
|
|
this->mTextImage.setPos(0, 0);
|
|
}
|
|
|
|
// Center image now
|
|
//int theImageWidth = this->getImageWide();
|
|
//int theImageHeight = this->getImageTall();
|
|
//int theImageX = theLabelWidth/2 - theImageWidth/2;
|
|
//int theImageY = theLabelHeight/2 - theImageHeight/2;
|
|
//this->m_pTGA->setPos(theImageX, theImageY);
|
|
}
|
|
|
|
void FadingImageLabel::SetAlwaysDrawText(bool inState)
|
|
{
|
|
this->mAlwaysDrawText = inState;
|
|
}
|
|
|
|
void FadingImageLabel::SetBaseFadeTime(float inSeconds)
|
|
{
|
|
this->mBaseFadeTime = inSeconds;
|
|
}
|
|
|
|
void FadingImageLabel::SetFadeState(bool inNewState)
|
|
{
|
|
// if new state is different
|
|
if(this->mFadeToVisibiltyState != inNewState)
|
|
{
|
|
// set fade to state
|
|
this->mFadeToVisibiltyState = inNewState;
|
|
|
|
float theCurrentTime = gHUD.m_flTime;
|
|
|
|
// set new fade to time in case a change was specified during a change
|
|
this->mTimeToFade = min(this->mBaseFadeTime, (theCurrentTime - this->mTimeVisChanged));
|
|
this->mMaxAlpha = min(1.0f, (theCurrentTime - this->mTimeVisChanged)/this->mBaseFadeTime);
|
|
|
|
// remember time that it was set
|
|
this->mTimeVisChanged = theCurrentTime;
|
|
|
|
// if new state is visible, set vgui::Panel::setVisible(true)
|
|
if(!this->isVisible() && inNewState)
|
|
{
|
|
this->FadedIn();
|
|
}
|
|
}
|
|
}
|
|
|
|
void FadingImageLabel::setFont(Scheme::SchemeFont inSchemeFont)
|
|
{
|
|
this->mTextImage.setFont(inSchemeFont);
|
|
}
|
|
|
|
void FadingImageLabel::setFont(Font* inFont)
|
|
{
|
|
ASSERT(inFont != NULL);
|
|
this->mTextImage.setFont(inFont);
|
|
|
|
// Sanity check
|
|
Font* theFont = this->mTextImage.getFont();
|
|
}
|
|
|
|
void FadingImageLabel::setPos(int x,int y)
|
|
{
|
|
// Don't set size smaller than we need for out text though!
|
|
Panel::setPos(x, y);
|
|
|
|
this->RecalculateTextPosition();
|
|
}
|
|
|
|
void FadingImageLabel::setSize(int wide,int tall)
|
|
{
|
|
//int theTextWidth, theTextHeight;
|
|
//this->mTextImage.getTextSize(theTextWidth, theTextHeight);
|
|
//int theNewWidth = max(wide, theTextWidth);
|
|
//int theNewHeight = max(tall, theTextHeight);
|
|
//CImageLabel::setSize(theNewWidth, theNewHeight);
|
|
|
|
Panel::setSize(wide, tall);
|
|
this->RecalculateTextPosition();
|
|
}
|
|
|
|
void FadingImageLabel::SetSizeKeepCenter(int inWidth, int inHeight)
|
|
{
|
|
int theX, theY;
|
|
this->getPos(theX, theY);
|
|
|
|
int theOldWidth, theOldHeight;
|
|
this->getSize(theOldWidth, theOldHeight);
|
|
|
|
// Calculate center of label
|
|
int theCenterX = theX + theOldWidth/2;
|
|
int theCenterY = theY + theOldHeight/2;
|
|
|
|
int theXDiff = (theOldWidth - inWidth)/2;
|
|
int theYDiff = (theOldHeight - inHeight)/2;
|
|
this->setSize(inWidth, inHeight);
|
|
|
|
this->setPos(theX + theXDiff, theY + theYDiff);
|
|
|
|
// Did it work?
|
|
int theNewX, theNewY;
|
|
this->getPos(theNewX, theNewY);
|
|
int theNewCenterX = theNewX + inWidth/2;
|
|
int theNewCenterY = theNewY + inHeight/2;
|
|
|
|
// Does the new center equal the old center?
|
|
ASSERT(abs(theNewCenterX - theCenterX) <= 1);
|
|
ASSERT(abs(theNewCenterY - theCenterY) <= 1);
|
|
}
|
|
|
|
void FadingImageLabel::SetSpriteName(const string& inSpriteName)
|
|
{
|
|
this->mImageName = inSpriteName;
|
|
}
|
|
|
|
void FadingImageLabel::setText(const char* inText)
|
|
{
|
|
//if(this->mSprite == 0)
|
|
//{
|
|
if(*inText == '!')
|
|
{
|
|
this->mImageMode = true;
|
|
this->mTextImage.setText("");
|
|
this->mText = "";
|
|
|
|
// If image name has '-frame' in it, then we draw a frame out of the sprite
|
|
string theImageName = string(inText + 1);
|
|
int theIndex = theImageName.find(kFrameIndicator);
|
|
if(theIndex != std::string::npos)
|
|
{
|
|
// Parse out frame number
|
|
string theFrameString = theImageName.substr(theIndex + strlen(kFrameIndicator));
|
|
this->mSpriteFrame = MakeIntFromString(theFrameString);
|
|
|
|
// Set theImageName
|
|
theImageName = theImageName.substr(0, theIndex);
|
|
}
|
|
|
|
this->SetSpriteName(theImageName);
|
|
}
|
|
else
|
|
{
|
|
this->mTextImage.setText(inText);
|
|
this->mText = inText;
|
|
this->RecalculateTextPosition();
|
|
}
|
|
//}
|
|
}
|
|
|
|
void FadingImageLabel::setVisible(bool inVisibility)
|
|
{
|
|
Panel::setVisible(inVisibility);
|
|
this->mValveAlpha = (this->isVisible() ? 0 : 255);
|
|
}
|
|
|
|
void FadingImageLabel::SetVisibleSize(int inVisWidth, int inVisHeight)
|
|
{
|
|
int theWidth, theHeight;
|
|
this->getSize(theWidth, theHeight);
|
|
|
|
this->mVisibleWidth = min(inVisWidth, theWidth);
|
|
this->mVisibleHeight = min(inVisHeight, theHeight);
|
|
}
|
|
|
|
void FadingImageLabel::setVisibleWithoutFading(bool inNewState)
|
|
{
|
|
this->mFadeToVisibiltyState = inNewState;
|
|
this->mTimeToFade = 0.0f;
|
|
|
|
Panel::setVisible(inNewState);
|
|
|
|
// TODO: Call FadedIn or FadedOut?
|
|
}
|
|
|
|
void FadingImageLabel::Update(float theCurrentTime)
|
|
{
|
|
bool theIsVisible = this->isVisible();
|
|
|
|
// if fade-to state different than our current state
|
|
//if((theIsVisible != this->mFadeToVisibiltyState) && (this->mTimeVisChanged != -1))
|
|
if(this->mTimeVisChanged != -1)
|
|
{
|
|
// set current alpha scalar depending on time since fade invoked
|
|
this->mTimeScalar = min((theCurrentTime - this->mTimeVisChanged)/this->mTimeToFade, 1);
|
|
|
|
// if fade-to time has passed and we were fading out, set vgui::Panel::setVisible(false);
|
|
if(!this->mFadeToVisibiltyState && this->mTimeScalar >= 1.0f)
|
|
{
|
|
if(theIsVisible)
|
|
{
|
|
this->FadedOut();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void FadingImageLabel::VidInit(void)
|
|
{
|
|
// Can we unload the sprite?
|
|
this->mSprite = 0;
|
|
this->mSpriteWidth = this->mSpriteHeight = 0;
|
|
}
|
|
|
|
|