Added snaking life meter and fixed Tick timing.

This commit is contained in:
Chris Danford
2002-09-12 00:40:48 +00:00
parent 144a7339f2
commit 686b704ed7
8 changed files with 265 additions and 70 deletions
+6
View File
@@ -2,6 +2,12 @@
Fix
/////////////////////////
fix movie texture crash
life meter snaking
eval letters glow faster
The "groove bar" reports at the results screen is broken.
Getting a nearly full voltage bar on a
song when I barely maitain combo (it should be max combo/max possible combo),
+3 -1
View File
@@ -322,7 +322,7 @@ AutoPlayX=320
AutoPlayY=360
SecondsBetweenComments=10
DemonstrationSeconds=30
TickEarlySeconds=0.018
TickEarlySeconds=0.058
[ScreenEvaluation]
BannerX=320
@@ -440,6 +440,8 @@ SectionColor7=0.8, 0.6, 0.0, 1
MeterWidth=258
MeterHeight=20
DangerThreshold=0.2
NumChambers=30
NumStrips=2
[TransitionKeepAlive]
StopMusicOnNext=0
+230 -51
View File
@@ -23,12 +23,193 @@
#define METER_WIDTH THEME->GetMetricI("LifeMeterBar","MeterWidth")
#define METER_HEIGHT THEME->GetMetricI("LifeMeterBar","MeterHeight")
#define DANGER_THRESHOLD THEME->GetMetricF("LifeMeterBar","DangerThreshold")
#define NUM_CHAMBERS THEME->GetMetricI("LifeMeterBar","NumChambers")
#define NUM_STRIPS THEME->GetMetricI("LifeMeterBar","NumStrips")
int g_iMeterWidth;
int g_iMeterHeight;
float g_fDangerThreshold;
int g_iNumChambers;
int g_iNumStrips;
const float FAIL_THRESHOLD = 0;
class LifeMeterStream : public Actor
{
public:
LifeMeterStream()
{
g_iMeterWidth = METER_WIDTH;
g_iMeterHeight = METER_HEIGHT;
g_fDangerThreshold = DANGER_THRESHOLD;
g_iNumChambers = NUM_CHAMBERS;
g_iNumStrips = NUM_STRIPS;
bool bExtra = GAMESTATE->IsExtraStage()||GAMESTATE->IsExtraStage2();
m_quadMask.SetDiffuse( D3DXCOLOR(0,0,0,0) );
m_quadMask.SetZ( -1 );
CString sGraphicPath;
sGraphicPath = ssprintf("gameplay %slifemeter stream normal", bExtra?"extra ":"");
m_sprStreamNormal.Load( THEME->GetPathTo("Graphics", sGraphicPath) );
sGraphicPath = ssprintf("gameplay %slifemeter stream hot", bExtra?"extra ":"");
m_sprStreamHot.Load( THEME->GetPathTo("Graphics", sGraphicPath) );
sGraphicPath = ssprintf("gameplay %slifemeter bar", bExtra?"extra ":"");
m_sprFrame.Load( THEME->GetPathTo("Graphics", sGraphicPath) );
}
Sprite m_sprStreamNormal;
Sprite m_sprStreamHot;
Sprite m_sprFrame;
Quad m_quadMask;
PlayerNumber m_PlayerNumber;
float m_fPercent;
float m_fHotAlpha;
void GetChamberIndexAndOverslow( float fPercent, int& iChamberOut, float& fChamberOverflowPercentOut )
{
iChamberOut = (int)(fPercent*g_iNumChambers);
fChamberOverflowPercentOut = fPercent*g_iNumChambers - iChamberOut;
}
float GetChamberLeftPercent( int iChamber )
{
return (iChamber+0) / (float)g_iNumChambers;
}
float GetChamberRightPercent( int iChamber )
{
return (iChamber+1) / (float)g_iNumChambers;
}
float GetRightEdgePercent( int iChamber, float fChamberOverflowPercent )
{
if( (iChamber%2) == 0 )
return (iChamber+fChamberOverflowPercent) / (float)g_iNumChambers;
else
return (iChamber+1) / (float)g_iNumChambers;
}
float GetHeightPercent( int iChamber, float fChamberOverflowPercent )
{
if( (iChamber%2) == 1 )
return 1-fChamberOverflowPercent;
else
return 0;
}
void DrawPrimitives()
{
DISPLAY->EnableZBuffer();
DrawMask( m_fPercent );
const float fPercentBetweenStrips = 1.0f/g_iNumStrips;
const float fPercentOffset = fmodf( GAMESTATE->m_fSongBeat/4+1000, fPercentBetweenStrips );
ASSERT( fPercentOffset >= 0 && fPercentOffset <= fPercentBetweenStrips );
for( float f=fPercentOffset+1; f>=fPercentOffset; f-=fPercentBetweenStrips )
{
DrawMask( f );
DrawStrip( f );
}
DISPLAY->DisableZBuffer();
m_sprFrame.Draw();
}
void DrawStrip( float fRightEdgePercent )
{
if( !GAMESTATE->IsPlayerEnabled(m_PlayerNumber) )
return;
RECT rect;
const float fChamberWidthInPercent = 1.0f/g_iNumChambers;
const float fStripWidthInPercent = 1.0f/g_iNumStrips;
const float fCorrectedRightEdgePercent = fRightEdgePercent + fChamberWidthInPercent;
const float fCorrectedStripWidthInPercent = fStripWidthInPercent + 2*fChamberWidthInPercent;
const float fCorrectedLeftEdgePercent = fCorrectedRightEdgePercent - fCorrectedStripWidthInPercent;
// set size of streams
rect.left = -g_iMeterWidth/2 + g_iMeterWidth*fCorrectedLeftEdgePercent;
rect.top = -g_iMeterHeight/2;
rect.right = -g_iMeterWidth/2 + g_iMeterWidth*min(1,fCorrectedRightEdgePercent);
rect.bottom = +g_iMeterHeight/2;
float fPercentCroppedFromRight = max( 0, fCorrectedRightEdgePercent-1 );
m_sprStreamNormal.StretchTo( &rect );
m_sprStreamHot.StretchTo( &rect );
// set custom texture coords
float fPrecentOffset = fRightEdgePercent;
FRECT frectCustomTexCoords(
0,
0,
1-fPercentCroppedFromRight,
1);
m_sprStreamNormal.SetCustomTextureRect( frectCustomTexCoords );
m_sprStreamHot.SetCustomTextureRect( frectCustomTexCoords );
m_sprStreamHot.SetDiffuse( D3DXCOLOR(1,1,1,m_fHotAlpha) );
m_sprStreamNormal.Draw();
m_sprStreamHot.Draw();
}
void DrawMask( float fPercent )
{
RECT rect;
int iChamber;
float fChamberOverflowPercent;
GetChamberIndexAndOverslow( fPercent, iChamber, fChamberOverflowPercent );
float fRightPercent = GetRightEdgePercent( iChamber, fChamberOverflowPercent );
float fHeightPercent = GetHeightPercent( iChamber, fChamberOverflowPercent );
float fChamberLeftPercent = GetChamberLeftPercent( iChamber );
float fChamberRightPercent = GetChamberRightPercent( iChamber );
// draw mask for vertical chambers
rect.left = -g_iMeterWidth/2 + fChamberLeftPercent*g_iMeterWidth;
rect.top = -g_iMeterHeight/2;
rect.right = -g_iMeterWidth/2 + fChamberRightPercent*g_iMeterWidth;
rect.bottom = -g_iMeterHeight/2 + fHeightPercent*g_iMeterHeight;
m_quadMask.StretchTo( &rect );
m_quadMask.Draw();
// draw mask for horizontal chambers
rect.left = -g_iMeterWidth/2 + fRightPercent*g_iMeterWidth;
rect.top = -g_iMeterHeight/2;
rect.right = +g_iMeterWidth/2;
rect.bottom = +g_iMeterHeight/2;
m_quadMask.StretchTo( &rect );
m_quadMask.Draw();
}
};
LifeMeterBar::LifeMeterBar()
{
m_pStream = new LifeMeterStream;
switch( GAMESTATE->m_SongOptions.m_DrainType )
{
case SongOptions::DRAIN_NORMAL: m_fLifePercentage = 0.5f; break;
@@ -41,39 +222,28 @@ LifeMeterBar::LifeMeterBar()
m_fLifeVelocity = 0;
m_fHotAlpha = 0;
m_bFailedEarlier = false;
m_iMeterWidth = METER_WIDTH;
m_iMeterHeight = METER_HEIGHT;
m_fDangerThreshold = DANGER_THRESHOLD;
m_quadBlackBackground.SetDiffuse( D3DXCOLOR(0,0,0,1) );
m_quadBlackBackground.SetZoomX( (float)m_iMeterWidth );
m_quadBlackBackground.SetZoomY( (float)m_iMeterHeight );
m_quadBlackBackground.SetZoomX( (float)g_iMeterWidth );
m_quadBlackBackground.SetZoomY( (float)g_iMeterHeight );
m_frame.AddChild( &m_quadBlackBackground );
if( GAMESTATE->IsExtraStage()||GAMESTATE->IsExtraStage2() )
m_sprStreamNormal.Load( THEME->GetPathTo("Graphics","gameplay extra lifemeter stream normal") );
else
m_sprStreamNormal.Load( THEME->GetPathTo("Graphics","gameplay lifemeter stream normal") );
m_frame.AddChild( &m_sprStreamNormal );
this->AddChild( m_pStream );
if( GAMESTATE->IsExtraStage()||GAMESTATE->IsExtraStage2() )
m_sprStreamHot.Load( THEME->GetPathTo("Graphics","gameplay extra lifemeter stream hot") );
else
m_sprStreamHot.Load( THEME->GetPathTo("Graphics","gameplay lifemeter stream hot") );
m_frame.AddChild( &m_sprStreamHot );
AfterLifeChanged();
}
m_sprFrame.Load( THEME->GetPathTo("Graphics","gameplay lifemeter bar") );
m_frame.AddChild( &m_sprFrame );
this->AddChild( &m_frame );
ResetBarVelocity();
LifeMeterBar::~LifeMeterBar()
{
delete m_pStream;
}
void LifeMeterBar::Load( PlayerNumber pn )
{
LifeMeter::Load( pn );
m_pStream->m_PlayerNumber = pn;
if( pn == PLAYER_2 )
m_frame.SetZoomX( -1 );
}
@@ -110,9 +280,9 @@ void LifeMeterBar::ChangeLife( TapNoteScore score )
{
case TNS_PERFECT: fDeltaLife = +0; break;
case TNS_GREAT: fDeltaLife = +0; break;
case TNS_GOOD: fDeltaLife = -100; break;
case TNS_BOO: fDeltaLife = -100; break;
case TNS_MISS: fDeltaLife = -100; break;
case TNS_GOOD: fDeltaLife = -1.0; break;
case TNS_BOO: fDeltaLife = -1.0; break;
case TNS_MISS: fDeltaLife = -1.0; break;
}
break;
default:
@@ -130,20 +300,17 @@ void LifeMeterBar::ChangeLife( TapNoteScore score )
if( m_fLifePercentage <= FAIL_THRESHOLD )
m_bFailedEarlier = true;
ResetBarVelocity();
m_fLifeVelocity += fDeltaLife;
}
void LifeMeterBar::ChangeLife( HoldNoteScore score )
{
// do nothing
}
void LifeMeterBar::ResetBarVelocity()
void LifeMeterBar::AfterLifeChanged()
{
// update bar animation
const float fDelta = m_fLifePercentage - m_fTrailingLifePercentage;
m_fLifeVelocity = fDelta * 5; // change in life percent per second
}
bool LifeMeterBar::IsHot()
@@ -153,7 +320,7 @@ bool LifeMeterBar::IsHot()
bool LifeMeterBar::IsInDanger()
{
return m_fLifePercentage < m_fDangerThreshold;
return m_fLifePercentage < g_fDangerThreshold;
}
bool LifeMeterBar::IsFailing()
@@ -170,23 +337,40 @@ void LifeMeterBar::Update( float fDeltaTime )
{
LifeMeter::Update( fDeltaTime );
float fDelta = m_fLifePercentage - m_fTrailingLifePercentage;
m_fLifeVelocity += fDelta * fDeltaTime; // accelerate
m_fLifeVelocity *= 1-fDeltaTime; // dampen
m_fTrailingLifePercentage += m_fLifeVelocity * fDeltaTime;
// HACK: Tweaking these values is very difficulty. Update the
// "physics" many times so that the spring motion appears faster
float fNewDelta = m_fLifePercentage - m_fTrailingLifePercentage;
for( int i=0; i<10; i++ )
{
if( fDelta * fNewDelta < 0 ) // the deltas have different signs
m_fLifeVelocity /= 4; // make some drag
CLAMP( m_fTrailingLifePercentage, 0, 1 );
const float fDelta = m_fLifePercentage - m_fTrailingLifePercentage;
const float fSign = (fDelta>0) ? 1 : -1;
m_fHotAlpha += IsHot() ? +fDeltaTime*2 : -fDeltaTime*2;
// const float fLinearForce = fSign * 0.2f;
// m_fLifeVelocity += fSpringForce * fDeltaTime;
const float fSpringForce = fDelta * 2.0f;
m_fLifeVelocity += fSpringForce * fDeltaTime;
const float fViscousForce = -m_fLifeVelocity * 0.2f;
m_fLifeVelocity += fViscousForce * fDeltaTime;
CLAMP( m_fLifeVelocity, -.02f, +.02f );
m_fTrailingLifePercentage += m_fLifeVelocity * fDeltaTime;
}
m_fHotAlpha += IsHot() ? + fDeltaTime*2 : -fDeltaTime*2;
CLAMP( m_fHotAlpha, 0, 1 );
if( IsHot() )
m_fLifeVelocity = max( 0, m_fLifeVelocity );
}
void LifeMeterBar::DrawPrimitives()
{
/*
// set custom texture coords
static RECT rectSize;
rectSize.left = -m_iMeterWidth/2;
@@ -210,26 +394,21 @@ void LifeMeterBar::DrawPrimitives()
m_sprStreamHot.SetDiffuse( D3DXCOLOR(1,1,1,m_fHotAlpha) );
*/
m_pStream->m_fPercent = m_fTrailingLifePercentage;
m_pStream->m_fHotAlpha = m_fHotAlpha;
float fPercentRed = (m_fTrailingLifePercentage<m_fDangerThreshold) ? sinf( TIMER->GetTimeSinceStart()*D3DX_PI*4 )/2+0.5f : 0;
float fPercentRed = (m_fTrailingLifePercentage<g_fDangerThreshold) ? sinf( TIMER->GetTimeSinceStart()*D3DX_PI*4 )/2+0.5f : 0;
m_quadBlackBackground.SetDiffuse( D3DXCOLOR(fPercentRed*0.8f,0,0,1) );
if( !GAMESTATE->IsPlayerEnabled(m_PlayerNumber) )
{
m_sprStreamNormal.SetDiffuse( D3DXCOLOR(1,1,1,0) );
m_sprStreamHot.SetDiffuse( D3DXCOLOR(1,1,1,0) );
}
ActorFrame::DrawPrimitives();
}
/*
Chris:
I'm making the coloring of the lifemeter a property of the theme.
That's where it belongs anyway...
Chris: I'm making the coloring of the lifemeter a property
of the theme. That's where it belongs anyway...
const D3DXCOLOR COLOR_EZ2NORMAL_1 = D3DXCOLOR(0.7f,0.4f,0,1);
+6 -7
View File
@@ -13,12 +13,14 @@
#include "LifeMeter.h"
#include "Sprite.h"
#include "Quad.h"
class LifeMeterStream;
class LifeMeterBar : public LifeMeter
{
public:
LifeMeterBar();
~LifeMeterBar();
virtual void Load( PlayerNumber pn );
@@ -27,6 +29,7 @@ public:
virtual void ChangeLife( TapNoteScore score );
virtual void ChangeLife( HoldNoteScore score );
virtual void AfterLifeChanged();
virtual void OnDancePointsChange() {}; // this life meter doesn't care
virtual bool IsInDanger();
virtual bool IsHot();
@@ -39,16 +42,12 @@ private:
ActorFrame m_frame; // hold everything and mirror this for PLAYER_2 instead of mirroring all the individual Actors
Quad m_quadBlackBackground;
Sprite m_sprStreamNormal;
Sprite m_sprStreamHot;
Sprite m_sprFrame;
LifeMeterStream* m_pStream;
float m_fLifePercentage;
float m_fTrailingLifePercentage; // this approaches m_fLifePercentage
float m_fLifeVelocity; // how m_fTrailingLifePercentage approaches m_fLifePercentage
float m_fLifeVelocity;
float m_fHotAlpha;
bool m_bFailedEarlier; // set this to true when life dips below 0
int m_iMeterWidth;
int m_iMeterHeight;
float m_fDangerThreshold;
};
+11 -6
View File
@@ -157,14 +157,12 @@ HRESULT CTextureRenderer::SetRenderTarget( RageMovieTexture* pTexture )
{
HRESULT hr;
LPDIRECT3DTEXTURE8 pD3DTexture = pTexture->GetD3DTexture();
if (pD3DTexture == NULL) {
DXTRACE_ERR(TEXT("SetRenderTarget called with a NULL texture!"), 0);
return E_FAIL;
}
m_pTexture = pTexture;
if( m_pTexture == NULL )
return S_OK;
LPDIRECT3DTEXTURE8 pD3DTexture = pTexture->GetD3DTexture();
// get the format of the texture
D3DSURFACE_DESC ddsd;
@@ -189,6 +187,9 @@ HRESULT CTextureRenderer::SetRenderTarget( RageMovieTexture* pTexture )
//-----------------------------------------------------------------------------
HRESULT CTextureRenderer::DoRenderSample( IMediaSample * pSample )
{
if( m_pTexture == NULL )
throw RageException( "DoRenderSample called while m_pTexture was NULL!" );
BYTE *pBmpBuffer; // Bitmap buffer
// Get the video bitmap buffer
@@ -516,11 +517,15 @@ void RageMovieTexture::CheckMovieStatus()
//-----------------------------------------------------------------------------
void RageMovieTexture::CleanupDShow()
{
m_pCTR->SetRenderTarget( NULL );
// Shut down the graph
if (m_pGB) {
Stop();
m_pGB.Release ();
}
// MEM LEAK! Why in the world does this cause a crash... I'm commenting it out for now.
// SAFE_DELETE( m_pCTR );
}
void RageMovieTexture::Play()
+1 -1
View File
@@ -18,7 +18,7 @@
#include "GameState.h"
const float SCORE_TWEEN_TIME = 0.5f;
const float SCORE_TWEEN_TIME = 0.2f;
ScoreDisplayNormal::ScoreDisplayNormal()
+7 -3
View File
@@ -60,19 +60,24 @@ const CString CREDIT_LINES[] =
"",
"",
"",
"TESTING:",
"Gotetsu",
"",
"",
"",
"PROGRAMMING:",
"Chris Danford",
"Lord Frieza (Andrew Livy)",
"Glenn Maynard",
"Bruno Figueiredo",
"Dro Kulix (Peter S. May)",
"nmspaz (Jared Roberts)",
"Mantis (Ben Nordstrom)",
"Parasyte (Chris Gomez)",
"dirkthedaring (Michael Patterson)",
"angedelamort (Sauleil Lamarre)",
"Edwin Evans",
"Brian 'Bork' Bugh",
"nmspaz (Jared Roberts)",
"Elvis314 (Joel Maher)",
"Kefabi (Garth Smith)",
"Pkillah (Playah Killah)",
@@ -104,8 +109,7 @@ const CString CREDIT_LINES[] =
"BeMaNiFiNiNaTiC (Jeremy Hine)",
"Garett Sakamoto",
"SailorBob",
"AngelTK {Kenny Lai}",
"Gotetsu",
"AngelTK (Kenny Lai)",
"Illusionz - Issaquah, WA",
"Quarters - Kirkland, WA",
"Segapark - Bournemouth, UK",
+1 -1
View File
@@ -285,7 +285,7 @@ void ScreenTitleMenu::HandleScreenMessage( const ScreenMessage SM )
if( RandomFloat(0,1)>0.8f )
GAMESTATE->m_PlayerOptions[p].m_bDark = true;
}
GAMESTATE->m_SongOptions.m_LifeType = SongOptions::LifeType(rand()%SongOptions::NUM_LIFE_TYPES);
GAMESTATE->m_SongOptions.m_LifeType = (randomf(0,1)>0.7f) ? SongOptions::LIFE_BATTERY : SongOptions::LIFE_BAR;
GAMESTATE->m_SongOptions.m_FailType = SongOptions::FAIL_OFF;
GAMESTATE->m_bDemonstration = true;