home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Chip 2011 November
/
CHIP_2011_11.iso
/
Programy
/
Inne
/
Gry
/
Atomic_Tanks
/
Atomic-Tanks-5.1.exe
/
src
/
floattext.cpp
< prev
next >
Wrap
C/C++ Source or Header
|
2010-04-06
|
9KB
|
274 lines
#include "floattext.h"
FLOATTEXT::FLOATTEXT (GLOBALDATA *global, ENVIRONMENT *env, char *text, int xpos, int ypos, int color, alignType alignment)
{
initialise ();
setEnvironment (env);
_text = NULL;
x = (double)xpos;
y = (double)ypos;
_current.x = (int)x;
_current.y = (int)y;
_current.w = 0;
_current.h = 0;
set_pos (xpos, ypos);
if (text)
set_text (text);
else
set_text( "");
set_color (color);
_align = alignment;
_global = global;
_halfColor = color;
sway = NO_SWAY;
original_x = xpos;
delta_x = 0;
}
FLOATTEXT::~FLOATTEXT()
{
if (_env)
{
/* To be sure to really remove the full text (might fail due to font differences),
we "enlarge" the text by 25%: */
if (_current.w)
{
_current.x -= (int)((double)_current.w * 1.125);
_current.w = (int)((double)_current.w * 1.250);
}
if (_current.h)
{
_current.y -= (int)((double)_current.h * 1.125);
_current.h = (int)((double)_current.h * 1.250);
}
switch (_align)
{
case LEFT:
_env->make_bgupdate (_current.x, _current.y, _current.w, _current.h);
_env->make_bgupdate (_old.x, _old.y, _old.w, _old.h);
break;
case RIGHT:
_env->make_bgupdate (_current.x - _current.w, _current.y - _current.h, _current.w, _current.h);
_env->make_bgupdate (_old.x - _old.w, _old.y - _old.h, _old.w, _old.h);
break;
case CENTRE:
_env->make_bgupdate (_current.x - (_current.w / 2), _current.y - (_current.h / 2), _current.w + 2, _current.h + 2);
_env->make_bgupdate (_old.x - (_old.w / 2), _old.y - (_old.h / 2), _old.w + 2, _old.h + 2);
break;
default:
_env->make_bgupdate (_current.x - _current.w, _current.y - _current.h, 2 * _current.w, 2 * _current.h);
_env->make_bgupdate (_old.x - _old.w, _old.y - _old.h, 2 * _old.w, 2 * _old.h);
}
_env->removeObject (this);
}
_global = NULL;
_env = NULL;
if (_text)
{
free(_text);
_text = NULL;
}
}
int FLOATTEXT::applyPhysics()
{
VIRTUAL_OBJECT::applyPhysics ();
if ( (!delta_x) && (sway) )
delta_x = -1;
x += delta_x;
if (x < original_x - sway)
delta_x = -delta_x;
else if (x > original_x + sway)
delta_x = -delta_x;
set_pos ((int)x, (int)y);
age++;
if ( (maxAge != -1) && (age > maxAge) )
destroy = TRUE;
return (0);
}
void FLOATTEXT::setEnvironment(ENVIRONMENT *env)
{
if (!_env || (_env != env))
{
_env = env;
_index = _env->addObject (this);
}
}
void FLOATTEXT::draw(BITMAP *dest)
{
if (_current.w)
{
double dFrontFade = 1.0;
double dShadFade = 0.75;
int iFrontCol = _color;
int iShadCol = _halfColor;
int iBackCol = _color;
// get Background color:
if ( (_env->dShadowedText > 0.0) || (_env->dFadingText > 0.0) )
{
switch (_align)
{
case LEFT:
iBackCol = _env->getAvgBgColor( _current.x, _current.y,
_current.x + _current.w, _current.y + _current.h,
xv, yv);
break;
case RIGHT:
iBackCol = _env->getAvgBgColor( _current.x - _current.w, _current.y - _current.h,
_current.x, _current.y,
xv, yv);
break;
case CENTRE:
iBackCol = _env->getAvgBgColor( _current.x - (_current.w / 2), _current.y - (_current.h / 2),
_current.x + (_current.w / 2) + 2,_current.y + (_current.h / 2) + 2,
xv, yv);
break;
}
}
if ((maxAge > 0) && (age >= (maxAge / 2)) && (_env->dFadingText > 0.0))
{
double dCalcAge = (double)age - (double)(maxAge / 2);
double dCalcMax = (double)(maxAge / 2);
dFrontFade = 1.0 - (dCalcAge / dCalcMax);
dShadFade = 0.75 - (0.75 * (dCalcAge / dCalcMax));
if (dFrontFade < 0.0) dFrontFade = 0.0;
if (dFrontFade > 1.0) dFrontFade = 1.0;
if (dShadFade < 0.0) dShadFade = 0.0;
if (dShadFade > 1.0) dShadFade = 1.0;
iFrontCol = newmakecol((getr(iFrontCol) * dFrontFade) + (getr(iBackCol) * (1.0 - dFrontFade)),
(getg(iFrontCol) * dFrontFade) + (getg(iBackCol) * (1.0 - dFrontFade)),
(getb(iFrontCol) * dFrontFade) + (getb(iBackCol) * (1.0 - dFrontFade)));
}
if (_env->dShadowedText > 0.0)
iShadCol = newmakecol( (getr(iShadCol) * dShadFade) + (getr(iBackCol) * (1.0 - dShadFade)),
(getg(iShadCol) * dShadFade) + (getg(iBackCol) * (1.0 - dShadFade)),
(getb(iShadCol) * dShadFade) + (getb(iBackCol) * (1.0 - dShadFade)));
if (_align == LEFT)
{
if (_env->dShadowedText > 0.0)
textout_ex (dest, font, _text,
_current.x + 1, _current.y + 1, iShadCol, -1);
textout_ex (dest, font, _text,
_current.x, _current.y, iFrontCol, -1);
}
else if (_align == RIGHT)
{
if (_env->dShadowedText > 0.0)
textout_ex (dest, font, _text,
_current.x - _current.w + 1,
_current.y - _current.h + 1, iShadCol, -1);
textout_ex (dest, font, _text,
_current.x - _current.w,
_current.y - _current.h, iFrontCol, -1);
}
else
{
if (_env->dShadowedText > 0.0)
textout_centre_ex (dest, font, _text,
_current.x + 1, _current.y + 1, iShadCol, -1);
textout_centre_ex (dest, font, _text,
_current.x, _current.y, iFrontCol, -1);
}
}
}
/*
This is too limiting, creating a more flexible text setting function below.
-- Jesse
void FLOATTEXT::set_text(char *text)
{
strncpy (_text, text, 80);
if (strlen (text) > 0)
{
_current.w = text_length (font, _text) + 3;
_text[79] = '\0';
}
else
_current.w = 0;
_current.h = text_height (font) + 15;
}
*/
// Returns TRUE on success or FALSE on failure.
int FLOATTEXT::set_text(char *text)
{
int my_length = strlen(text);
// clean up old text
if (_text)
free(_text);
_text = (char *) calloc( my_length + 1, sizeof(char));
if (! _text)
return FALSE;
strcpy(_text, text);
if (my_length)
_current.w = text_length(font, _text) + 3;
else
_current.w = 0;
_current.h = text_height(font) + 15;
return TRUE;
}
void FLOATTEXT::set_color(int color)
{
int red = getr(color);
int green = getg(color);
int blue = getb(color);
int iAverage = (red + green + blue) / 3;
_color = color;
if (!(red & 0xc0) && !(green & 0xc0) && !(blue & 0xc0))
_halfColor = makecol(red | 0x80, green | 0x80, blue | 0x80); // Color is too dark, shadow should be bright
else
_halfColor = makecol( red > iAverage?(red / 4):(red / 6),
green > iAverage?(green / 4):(green / 6),
blue > iAverage?(blue / 4):(blue / 6));
}
void FLOATTEXT::newRound()
{
age = maxAge + 1;
}
void FLOATTEXT::set_pos(int x, int y)
{
_current.x = x;
_current.y = y;
}
void FLOATTEXT::set_speed(double x_speed, double y_speed)
{
double mix_it_up; // avoid over-lapping text
mix_it_up = rand() % SPEED_RANGE; // (0-5)
mix_it_up -= 3.0; // -3 to +2
mix_it_up /= 10.0; // -0.3 to + 0.2
xv = x_speed;
yv = y_speed + mix_it_up;
if ( (yv == 0.0) && (y_speed < 0.0) )
yv = -0.1; // avoid text that does not move
}