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
///////////////////////// /////////////////////////
fix movie texture crash
life meter snaking
eval letters glow faster
The "groove bar" reports at the results screen is broken. The "groove bar" reports at the results screen is broken.
Getting a nearly full voltage bar on a Getting a nearly full voltage bar on a
song when I barely maitain combo (it should be max combo/max possible combo), 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 AutoPlayY=360
SecondsBetweenComments=10 SecondsBetweenComments=10
DemonstrationSeconds=30 DemonstrationSeconds=30
TickEarlySeconds=0.018 TickEarlySeconds=0.058
[ScreenEvaluation] [ScreenEvaluation]
BannerX=320 BannerX=320
@@ -440,6 +440,8 @@ SectionColor7=0.8, 0.6, 0.0, 1
MeterWidth=258 MeterWidth=258
MeterHeight=20 MeterHeight=20
DangerThreshold=0.2 DangerThreshold=0.2
NumChambers=30
NumStrips=2
[TransitionKeepAlive] [TransitionKeepAlive]
StopMusicOnNext=0 StopMusicOnNext=0
+230 -51
View File
@@ -23,12 +23,193 @@
#define METER_WIDTH THEME->GetMetricI("LifeMeterBar","MeterWidth") #define METER_WIDTH THEME->GetMetricI("LifeMeterBar","MeterWidth")
#define METER_HEIGHT THEME->GetMetricI("LifeMeterBar","MeterHeight") #define METER_HEIGHT THEME->GetMetricI("LifeMeterBar","MeterHeight")
#define DANGER_THRESHOLD THEME->GetMetricF("LifeMeterBar","DangerThreshold") #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; 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() LifeMeterBar::LifeMeterBar()
{ {
m_pStream = new LifeMeterStream;
switch( GAMESTATE->m_SongOptions.m_DrainType ) switch( GAMESTATE->m_SongOptions.m_DrainType )
{ {
case SongOptions::DRAIN_NORMAL: m_fLifePercentage = 0.5f; break; case SongOptions::DRAIN_NORMAL: m_fLifePercentage = 0.5f; break;
@@ -41,39 +222,28 @@ LifeMeterBar::LifeMeterBar()
m_fLifeVelocity = 0; m_fLifeVelocity = 0;
m_fHotAlpha = 0; m_fHotAlpha = 0;
m_bFailedEarlier = false; 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.SetDiffuse( D3DXCOLOR(0,0,0,1) );
m_quadBlackBackground.SetZoomX( (float)m_iMeterWidth ); m_quadBlackBackground.SetZoomX( (float)g_iMeterWidth );
m_quadBlackBackground.SetZoomY( (float)m_iMeterHeight ); m_quadBlackBackground.SetZoomY( (float)g_iMeterHeight );
m_frame.AddChild( &m_quadBlackBackground ); m_frame.AddChild( &m_quadBlackBackground );
if( GAMESTATE->IsExtraStage()||GAMESTATE->IsExtraStage2() ) this->AddChild( m_pStream );
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 );
if( GAMESTATE->IsExtraStage()||GAMESTATE->IsExtraStage2() ) AfterLifeChanged();
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 );
m_sprFrame.Load( THEME->GetPathTo("Graphics","gameplay lifemeter bar") ); LifeMeterBar::~LifeMeterBar()
m_frame.AddChild( &m_sprFrame ); {
delete m_pStream;
this->AddChild( &m_frame );
ResetBarVelocity();
} }
void LifeMeterBar::Load( PlayerNumber pn ) void LifeMeterBar::Load( PlayerNumber pn )
{ {
LifeMeter::Load( pn ); LifeMeter::Load( pn );
m_pStream->m_PlayerNumber = pn;
if( pn == PLAYER_2 ) if( pn == PLAYER_2 )
m_frame.SetZoomX( -1 ); m_frame.SetZoomX( -1 );
} }
@@ -110,9 +280,9 @@ void LifeMeterBar::ChangeLife( TapNoteScore score )
{ {
case TNS_PERFECT: fDeltaLife = +0; break; case TNS_PERFECT: fDeltaLife = +0; break;
case TNS_GREAT: fDeltaLife = +0; break; case TNS_GREAT: fDeltaLife = +0; break;
case TNS_GOOD: fDeltaLife = -100; break; case TNS_GOOD: fDeltaLife = -1.0; break;
case TNS_BOO: fDeltaLife = -100; break; case TNS_BOO: fDeltaLife = -1.0; break;
case TNS_MISS: fDeltaLife = -100; break; case TNS_MISS: fDeltaLife = -1.0; break;
} }
break; break;
default: default:
@@ -130,20 +300,17 @@ void LifeMeterBar::ChangeLife( TapNoteScore score )
if( m_fLifePercentage <= FAIL_THRESHOLD ) if( m_fLifePercentage <= FAIL_THRESHOLD )
m_bFailedEarlier = true; m_bFailedEarlier = true;
ResetBarVelocity(); m_fLifeVelocity += fDeltaLife;
} }
void LifeMeterBar::ChangeLife( HoldNoteScore score ) 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() bool LifeMeterBar::IsHot()
@@ -153,7 +320,7 @@ bool LifeMeterBar::IsHot()
bool LifeMeterBar::IsInDanger() bool LifeMeterBar::IsInDanger()
{ {
return m_fLifePercentage < m_fDangerThreshold; return m_fLifePercentage < g_fDangerThreshold;
} }
bool LifeMeterBar::IsFailing() bool LifeMeterBar::IsFailing()
@@ -170,23 +337,40 @@ void LifeMeterBar::Update( float fDeltaTime )
{ {
LifeMeter::Update( fDeltaTime ); LifeMeter::Update( fDeltaTime );
float fDelta = m_fLifePercentage - m_fTrailingLifePercentage; // HACK: Tweaking these values is very difficulty. Update the
m_fLifeVelocity += fDelta * fDeltaTime; // accelerate // "physics" many times so that the spring motion appears faster
m_fLifeVelocity *= 1-fDeltaTime; // dampen
m_fTrailingLifePercentage += m_fLifeVelocity * fDeltaTime;
float fNewDelta = m_fLifePercentage - m_fTrailingLifePercentage; for( int i=0; i<10; i++ )
{
if( fDelta * fNewDelta < 0 ) // the deltas have different signs const float fDelta = m_fLifePercentage - m_fTrailingLifePercentage;
m_fLifeVelocity /= 4; // make some drag const float fSign = (fDelta>0) ? 1 : -1;
CLAMP( m_fTrailingLifePercentage, 0, 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 ); CLAMP( m_fHotAlpha, 0, 1 );
if( IsHot() )
m_fLifeVelocity = max( 0, m_fLifeVelocity );
} }
void LifeMeterBar::DrawPrimitives() void LifeMeterBar::DrawPrimitives()
{ {
/*
// set custom texture coords // set custom texture coords
static RECT rectSize; static RECT rectSize;
rectSize.left = -m_iMeterWidth/2; rectSize.left = -m_iMeterWidth/2;
@@ -210,26 +394,21 @@ void LifeMeterBar::DrawPrimitives()
m_sprStreamHot.SetDiffuse( D3DXCOLOR(1,1,1,m_fHotAlpha) ); 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<g_fDangerThreshold) ? sinf( TIMER->GetTimeSinceStart()*D3DX_PI*4 )/2+0.5f : 0;
float fPercentRed = (m_fTrailingLifePercentage<m_fDangerThreshold) ? sinf( TIMER->GetTimeSinceStart()*D3DX_PI*4 )/2+0.5f : 0;
m_quadBlackBackground.SetDiffuse( D3DXCOLOR(fPercentRed*0.8f,0,0,1) ); 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(); ActorFrame::DrawPrimitives();
} }
/* /*
Chris: Chris: I'm making the coloring of the lifemeter a property
I'm making the coloring of the lifemeter a property of the theme. of the theme. That's where it belongs anyway...
That's where it belongs anyway...
const D3DXCOLOR COLOR_EZ2NORMAL_1 = D3DXCOLOR(0.7f,0.4f,0,1); const D3DXCOLOR COLOR_EZ2NORMAL_1 = D3DXCOLOR(0.7f,0.4f,0,1);
+6 -7
View File
@@ -13,12 +13,14 @@
#include "LifeMeter.h" #include "LifeMeter.h"
#include "Sprite.h" #include "Sprite.h"
#include "Quad.h" #include "Quad.h"
class LifeMeterStream;
class LifeMeterBar : public LifeMeter class LifeMeterBar : public LifeMeter
{ {
public: public:
LifeMeterBar(); LifeMeterBar();
~LifeMeterBar();
virtual void Load( PlayerNumber pn ); virtual void Load( PlayerNumber pn );
@@ -27,6 +29,7 @@ public:
virtual void ChangeLife( TapNoteScore score ); virtual void ChangeLife( TapNoteScore score );
virtual void ChangeLife( HoldNoteScore score ); virtual void ChangeLife( HoldNoteScore score );
virtual void AfterLifeChanged();
virtual void OnDancePointsChange() {}; // this life meter doesn't care virtual void OnDancePointsChange() {}; // this life meter doesn't care
virtual bool IsInDanger(); virtual bool IsInDanger();
virtual bool IsHot(); 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 ActorFrame m_frame; // hold everything and mirror this for PLAYER_2 instead of mirroring all the individual Actors
Quad m_quadBlackBackground; Quad m_quadBlackBackground;
Sprite m_sprStreamNormal; LifeMeterStream* m_pStream;
Sprite m_sprStreamHot;
Sprite m_sprFrame;
float m_fLifePercentage; float m_fLifePercentage;
float m_fTrailingLifePercentage; // this approaches m_fLifePercentage float m_fTrailingLifePercentage; // this approaches m_fLifePercentage
float m_fLifeVelocity; // how m_fTrailingLifePercentage approaches m_fLifePercentage float m_fLifeVelocity;
float m_fHotAlpha; float m_fHotAlpha;
bool m_bFailedEarlier; // set this to true when life dips below 0 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; 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; m_pTexture = pTexture;
if( m_pTexture == NULL )
return S_OK;
LPDIRECT3DTEXTURE8 pD3DTexture = pTexture->GetD3DTexture();
// get the format of the texture // get the format of the texture
D3DSURFACE_DESC ddsd; D3DSURFACE_DESC ddsd;
@@ -189,6 +187,9 @@ HRESULT CTextureRenderer::SetRenderTarget( RageMovieTexture* pTexture )
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
HRESULT CTextureRenderer::DoRenderSample( IMediaSample * pSample ) HRESULT CTextureRenderer::DoRenderSample( IMediaSample * pSample )
{ {
if( m_pTexture == NULL )
throw RageException( "DoRenderSample called while m_pTexture was NULL!" );
BYTE *pBmpBuffer; // Bitmap buffer BYTE *pBmpBuffer; // Bitmap buffer
// Get the video bitmap buffer // Get the video bitmap buffer
@@ -516,11 +517,15 @@ void RageMovieTexture::CheckMovieStatus()
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void RageMovieTexture::CleanupDShow() void RageMovieTexture::CleanupDShow()
{ {
m_pCTR->SetRenderTarget( NULL );
// Shut down the graph // Shut down the graph
if (m_pGB) { if (m_pGB) {
Stop(); Stop();
m_pGB.Release (); 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() void RageMovieTexture::Play()
+1 -1
View File
@@ -18,7 +18,7 @@
#include "GameState.h" #include "GameState.h"
const float SCORE_TWEEN_TIME = 0.5f; const float SCORE_TWEEN_TIME = 0.2f;
ScoreDisplayNormal::ScoreDisplayNormal() ScoreDisplayNormal::ScoreDisplayNormal()
+7 -3
View File
@@ -60,19 +60,24 @@ const CString CREDIT_LINES[] =
"", "",
"", "",
"", "",
"TESTING:",
"Gotetsu",
"",
"",
"",
"PROGRAMMING:", "PROGRAMMING:",
"Chris Danford", "Chris Danford",
"Lord Frieza (Andrew Livy)", "Lord Frieza (Andrew Livy)",
"Glenn Maynard", "Glenn Maynard",
"Bruno Figueiredo", "Bruno Figueiredo",
"Dro Kulix (Peter S. May)", "Dro Kulix (Peter S. May)",
"nmspaz (Jared Roberts)",
"Mantis (Ben Nordstrom)", "Mantis (Ben Nordstrom)",
"Parasyte (Chris Gomez)", "Parasyte (Chris Gomez)",
"dirkthedaring (Michael Patterson)", "dirkthedaring (Michael Patterson)",
"angedelamort (Sauleil Lamarre)", "angedelamort (Sauleil Lamarre)",
"Edwin Evans", "Edwin Evans",
"Brian 'Bork' Bugh", "Brian 'Bork' Bugh",
"nmspaz (Jared Roberts)",
"Elvis314 (Joel Maher)", "Elvis314 (Joel Maher)",
"Kefabi (Garth Smith)", "Kefabi (Garth Smith)",
"Pkillah (Playah Killah)", "Pkillah (Playah Killah)",
@@ -104,8 +109,7 @@ const CString CREDIT_LINES[] =
"BeMaNiFiNiNaTiC (Jeremy Hine)", "BeMaNiFiNiNaTiC (Jeremy Hine)",
"Garett Sakamoto", "Garett Sakamoto",
"SailorBob", "SailorBob",
"AngelTK {Kenny Lai}", "AngelTK (Kenny Lai)",
"Gotetsu",
"Illusionz - Issaquah, WA", "Illusionz - Issaquah, WA",
"Quarters - Kirkland, WA", "Quarters - Kirkland, WA",
"Segapark - Bournemouth, UK", "Segapark - Bournemouth, UK",
+1 -1
View File
@@ -285,7 +285,7 @@ void ScreenTitleMenu::HandleScreenMessage( const ScreenMessage SM )
if( RandomFloat(0,1)>0.8f ) if( RandomFloat(0,1)>0.8f )
GAMESTATE->m_PlayerOptions[p].m_bDark = true; 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_SongOptions.m_FailType = SongOptions::FAIL_OFF;
GAMESTATE->m_bDemonstration = true; GAMESTATE->m_bDemonstration = true;