Files
itgmania212121/stepmania/src/LifeMeterBar.cpp
T

217 lines
5.5 KiB
C++
Raw Normal View History

2002-04-28 20:42:32 +00:00
#include "stdafx.h"
/*
-----------------------------------------------------------------------------
Class: LifeMeterBar
Desc: See header.
2002-05-19 01:59:48 +00:00
Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved.
2002-04-28 20:42:32 +00:00
Chris Danford
-----------------------------------------------------------------------------
*/
#include "LifeMeterBar.h"
#include "ThemeManager.h"
const int NUM_SECTIONS = 3;
const float SECTION_WIDTH = 1.0f/NUM_SECTIONS;
LifeMeterBar::LifeMeterBar()
{
m_fLifePercentage = 0.5f;
m_fTrailingLifePercentage = 0;
m_fLifeVelocity = 0;
2002-05-27 08:23:27 +00:00
ResetBarVelocity();
2002-04-28 20:42:32 +00:00
}
void LifeMeterBar::ChangeLife( TapNoteScore score )
{
2002-05-27 08:23:27 +00:00
bool bWasDoingGreat = IsDoingGreat();
2002-04-28 20:42:32 +00:00
switch( score )
{
2002-05-28 20:01:22 +00:00
case TNS_PERFECT: m_fLifePercentage += 0.02f; break;
2002-05-27 08:23:27 +00:00
case TNS_GREAT: m_fLifePercentage += 0.01f; break;
case TNS_GOOD: m_fLifePercentage += 0.00f; break;
case TNS_BOO: m_fLifePercentage -= 0.05f; break;
case TNS_MISS: m_fLifePercentage -= 0.10f; break;
2002-04-28 20:42:32 +00:00
}
2002-05-28 20:01:22 +00:00
m_fLifePercentage = clamp( m_fLifePercentage, 0, 1 );
2002-04-28 20:42:32 +00:00
2002-05-27 08:23:27 +00:00
bool bIsDoingGreat = IsDoingGreat();
if( bWasDoingGreat && !bIsDoingGreat )
m_fLifePercentage -= 0.10f; // make it take a while to get back to "doing great"
ResetBarVelocity();
2002-04-28 20:42:32 +00:00
}
2002-05-27 08:23:27 +00:00
void LifeMeterBar::ResetBarVelocity()
{
// update bar animation
const float fDelta = m_fLifePercentage - m_fTrailingLifePercentage;
m_fLifeVelocity = fDelta * 5; // change in life percent per second
}
bool LifeMeterBar::IsDoingGreat()
2002-04-28 20:42:32 +00:00
{
2002-05-28 20:01:22 +00:00
return m_fLifePercentage >= 1;
2002-05-27 08:23:27 +00:00
}
bool LifeMeterBar::IsAboutToFail()
{
return m_fLifePercentage < 0.3f;
}
bool LifeMeterBar::HasFailed()
{
return m_bHasFailed;
2002-04-28 20:42:32 +00:00
}
void LifeMeterBar::Update( float fDeltaTime )
{
2002-05-27 08:23:27 +00:00
m_fLifeVelocity *= 1-fDeltaTime*2; // dampen
2002-04-28 20:42:32 +00:00
2002-05-28 20:01:22 +00:00
// there are some cases where we want to snap the meter
bool bSnap = m_fTrailingLifePercentage >= 1;
if( bSnap )
2002-04-28 20:42:32 +00:00
{
2002-05-27 08:23:27 +00:00
m_fTrailingLifePercentage = m_fLifePercentage;
2002-04-28 20:42:32 +00:00
m_fLifeVelocity = 0;
}
else
{
2002-05-27 08:23:27 +00:00
m_fTrailingLifePercentage += m_fLifeVelocity * fDeltaTime;
2002-04-28 20:42:32 +00:00
m_fTrailingLifePercentage = clamp( m_fTrailingLifePercentage, 0, 1 );
}
2002-05-27 08:23:27 +00:00
if( m_fLifePercentage == 0 )
m_bHasFailed = true;
2002-04-28 20:42:32 +00:00
}
const D3DXCOLOR COLOR_NORMAL_1 = D3DXCOLOR(1,1,1,1);
const D3DXCOLOR COLOR_NORMAL_2 = D3DXCOLOR(0,1,0,1);
const D3DXCOLOR COLOR_FULL_1 = D3DXCOLOR(1,0,0,1);
const D3DXCOLOR COLOR_FULL_2 = D3DXCOLOR(1,1,0,1);
D3DXCOLOR LifeMeterBar::GetColor( float fPercentIntoSection )
{
2002-05-19 01:59:48 +00:00
float fPercentColor1 = fabsf( fPercentIntoSection*2 - 1 );
2002-05-27 08:23:27 +00:00
fPercentColor1 *= fPercentColor1 * fPercentColor1 * fPercentColor1; // make the color bunch around one side
2002-04-28 20:42:32 +00:00
if( m_fLifePercentage == 1 )
return COLOR_FULL_1 * fPercentColor1 + COLOR_FULL_2 * (1-fPercentColor1);
else
return COLOR_NORMAL_1 * fPercentColor1 + COLOR_NORMAL_2 * (1-fPercentColor1);
}
2002-05-19 01:59:48 +00:00
void LifeMeterBar::DrawPrimitives()
2002-04-28 20:42:32 +00:00
{
// make the object in logical units centered at the origin
2002-05-19 01:59:48 +00:00
LPDIRECT3DVERTEXBUFFER8 pVB = DISPLAY->GetVertexBuffer();
RAGEVERTEX* v;
2002-04-28 20:42:32 +00:00
pVB->Lock( 0, 0, (BYTE**)&v, 0 );
int iNumV = 0;
float fPercentIntoSection = (GetTickCount()/300.0f)*SECTION_WIDTH;
fPercentIntoSection -= (int)fPercentIntoSection;
fPercentIntoSection = 1-fPercentIntoSection;
fPercentIntoSection -= (int)fPercentIntoSection;
ASSERT( fPercentIntoSection >= 0 && fPercentIntoSection < 1 );
float fX = - 0.5f;
while( fX < m_fTrailingLifePercentage-0.5f )
{
//
// draw middle
//
v[iNumV++].p = D3DXVECTOR3( fX, -0.5f, 0 );
v[iNumV++].p = D3DXVECTOR3( fX, 0.5f, 0 );
iNumV -= 2;
const D3DXCOLOR color = GetColor( fPercentIntoSection );
v[iNumV++].color = color;
v[iNumV++].color = color;
if( fPercentIntoSection < 0.5f )
{
const float fPercentToAdd = 0.5f-fPercentIntoSection;
fPercentIntoSection += fPercentToAdd;
fX += fPercentToAdd*SECTION_WIDTH;
}
else if( fPercentIntoSection < 1.0f )
{
const float fPercentToAdd = 1.0f-fPercentIntoSection;
fPercentIntoSection = 0;
fX += fPercentToAdd*SECTION_WIDTH;
}
else
ASSERT( false );
}
const float fXToSubtract = fX - (m_fTrailingLifePercentage-0.5f);
fX -= fXToSubtract;
fPercentIntoSection -= fXToSubtract/SECTION_WIDTH;
if( fPercentIntoSection < 0 )
fPercentIntoSection += 1;
//
// draw right edge
//
v[iNumV++].p = D3DXVECTOR3( fX, -0.5f, 0 );
v[iNumV++].p = D3DXVECTOR3( fX, 0.5f, 0 );
iNumV -= 2;
const D3DXCOLOR color = GetColor( fPercentIntoSection );
v[iNumV++].color = color;
v[iNumV++].color = color;
//
// draw black filler
//
v[iNumV++].p = D3DXVECTOR3( fX, -0.5f, 0 );
v[iNumV++].p = D3DXVECTOR3( fX, 0.5f, 0 );
v[iNumV++].p = D3DXVECTOR3( 0.5f, -0.5f, 0 );
v[iNumV++].p = D3DXVECTOR3( 0.5f, 0.5f, 0 );
iNumV -= 4;
const D3DXCOLOR colorBlack = D3DXCOLOR(0,0,0,1);
v[iNumV++].color = colorBlack;
v[iNumV++].color = colorBlack;
v[iNumV++].color = colorBlack;
v[iNumV++].color = colorBlack;
pVB->Unlock();
2002-05-19 01:59:48 +00:00
LPDIRECT3DDEVICE8 pd3dDevice = DISPLAY->GetDevice();
2002-04-28 20:42:32 +00:00
pd3dDevice->SetTexture( 0, NULL );
// set texture and alpha properties
pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG2 );
pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE );
pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG2 );
pd3dDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
pd3dDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );
// finally! Pump those triangles!
2002-05-19 01:59:48 +00:00
pd3dDevice->SetVertexShader( D3DFVF_RAGEVERTEX );
pd3dDevice->SetStreamSource( 0, pVB, sizeof(RAGEVERTEX) );
2002-04-28 20:42:32 +00:00
pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, iNumV-2 );
}