Files
itgmania212121/stepmania/src/PercentageDisplay.cpp
T

251 lines
8.3 KiB
C++
Raw Normal View History

#include "global.h"
#include "PercentageDisplay.h"
#include "GameState.h"
#include "ThemeManager.h"
#include "PrefsManager.h"
2003-10-04 08:45:53 +00:00
#include "ActorUtil.h"
#include "RageLog.h"
#include "StageStats.h"
#include "PlayerState.h"
2005-08-30 02:01:05 +00:00
#include "XmlFile.h"
ThemeMetric<int> PERCENT_DECIMAL_PLACES ( "PercentageDisplay", "PercentDecimalPlaces" );
ThemeMetric<int> PERCENT_TOTAL_SIZE ( "PercentageDisplay", "PercentTotalSize" );
2005-08-30 02:01:05 +00:00
REGISTER_ACTOR_CLASS( PercentageDisplay )
PercentageDisplay::PercentageDisplay()
{
m_pPlayerState = NULL;
m_pPlayerStageStats = NULL;
2005-08-30 02:01:05 +00:00
m_Last = -1;
m_LastMax = -1;
2006-07-23 03:29:16 +00:00
m_iDancePointsDigits = 0;
2006-07-25 23:41:15 +00:00
m_Format.SetFromExpression( "FormatPercentScore" );
2005-08-30 02:01:05 +00:00
}
void PercentageDisplay::LoadFromNode( const XNode* pNode )
2005-08-30 02:01:05 +00:00
{
pNode->GetAttrValue( "DancePointsDigits", m_iDancePointsDigits );
pNode->GetAttrValue( "PercentUseRemainder", m_bUseRemainder );
pNode->GetAttrValue( "ApplyScoreDisplayOptions", m_bApplyScoreDisplayOptions );
pNode->GetAttrValue( "AutoRefresh", m_bAutoRefresh );
RString sStr = "FormatPercentScore";
pNode->GetAttrValue( "Format", sStr );
m_Format.SetFromExpression( sStr );
2005-08-30 02:01:05 +00:00
const XNode *pChild = pNode->GetChild( "Percent" );
if( pChild == NULL )
2006-10-09 08:08:59 +00:00
RageException::Throw( "%s: PercentageDisplay: missing the node \"Percent\"", ActorUtil::GetWhere(pNode).c_str() );
m_textPercent.LoadFromNode( pChild );
2005-08-30 02:01:05 +00:00
this->AddChild( &m_textPercent );
if( !PREFSMAN->m_bDancePointsForOni && m_bUseRemainder )
{
const XNode *pChild = pNode->GetChild( "PercentRemainder" );
if( pChild == NULL )
2006-10-09 08:08:59 +00:00
RageException::Throw( "%s: ComboGraph: missing the node \"PercentRemainder\"", ActorUtil::GetWhere(pNode).c_str() );
m_textPercentRemainder.LoadFromNode( pChild );
2005-08-30 02:01:05 +00:00
this->AddChild( &m_textPercentRemainder );
}
// only run the Init command after we load Fonts.
ActorFrame::LoadFromNode( pNode );
2005-08-30 02:01:05 +00:00
}
void PercentageDisplay::Load( const PlayerState *pPlayerState, const PlayerStageStats *pPlayerStageStats )
{
m_pPlayerState = pPlayerState;
m_pPlayerStageStats = pPlayerStageStats;
Refresh();
}
2006-01-22 01:00:06 +00:00
void PercentageDisplay::Load( const PlayerState *pPlayerState, const PlayerStageStats *pPlayerStageStats, const RString &sMetricsGroup, bool bAutoRefresh )
2005-02-02 07:14:09 +00:00
{
m_pPlayerState = pPlayerState;
m_pPlayerStageStats = pPlayerStageStats;
m_bAutoRefresh = bAutoRefresh;
2003-10-05 00:30:55 +00:00
2005-08-30 02:01:05 +00:00
m_iDancePointsDigits = THEME->GetMetricI( sMetricsGroup, "DancePointsDigits" );
m_bUseRemainder = THEME->GetMetricB( sMetricsGroup, "PercentUseRemainder" );
m_bApplyScoreDisplayOptions = THEME->GetMetricB( sMetricsGroup, "ApplyScoreDisplayOptions" );
2006-09-22 03:53:42 +00:00
m_Format = THEME->GetMetricR( sMetricsGroup, "Format" );
2006-08-14 04:49:27 +00:00
if( m_Format.IsNil() )
{
LOG->Trace( "Format is nil in [%s]. Defaulting to 'FormatPercentScore'.", sMetricsGroup.c_str() );
m_Format.SetFromExpression( "FormatPercentScore" );
}
2003-10-05 00:30:55 +00:00
if( PREFSMAN->m_bDancePointsForOni )
m_textPercent.SetName( "DancePoints" + PlayerNumberToString(m_pPlayerState->m_PlayerNumber) );
2003-10-05 00:30:55 +00:00
else
m_textPercent.SetName( "Percent" + PlayerNumberToString(m_pPlayerState->m_PlayerNumber) );
2005-08-30 02:02:00 +00:00
m_textPercent.LoadFromFont( THEME->GetPathF(sMetricsGroup,"text") );
ActorUtil::SetXY( m_textPercent, sMetricsGroup );
2005-05-04 18:30:31 +00:00
ASSERT( m_textPercent.HasCommand("Off") );
2003-10-05 00:30:55 +00:00
this->AddChild( &m_textPercent );
2005-08-30 02:01:05 +00:00
if( !PREFSMAN->m_bDancePointsForOni && m_bUseRemainder )
2003-10-05 00:30:55 +00:00
{
m_textPercentRemainder.SetName( "PercentRemainder" + PlayerNumberToString(m_pPlayerState->m_PlayerNumber) );
m_textPercentRemainder.LoadFromFont( THEME->GetPathF(sMetricsGroup,"remainder") );
ActorUtil::SetXY( m_textPercentRemainder, sMetricsGroup );
2005-05-04 18:30:31 +00:00
ASSERT( m_textPercentRemainder.HasCommand("Off") );
2003-10-05 00:30:55 +00:00
m_textPercentRemainder.SetText( "456" );
this->AddChild( &m_textPercentRemainder );
}
Refresh();
}
void PercentageDisplay::Update( float fDeltaTime )
2003-10-05 00:30:55 +00:00
{
ActorFrame::Update( fDeltaTime );
if( m_bAutoRefresh )
Refresh();
2003-10-05 00:30:55 +00:00
}
void PercentageDisplay::Refresh()
{
const int iActualDancePoints = m_pPlayerStageStats->iActualDancePoints;
const int iCurPossibleDancePoints = m_pPlayerStageStats->iCurPossibleDancePoints;
if( iActualDancePoints == m_Last && iCurPossibleDancePoints == m_LastMax )
return;
2003-10-05 00:30:55 +00:00
m_Last = iActualDancePoints;
m_LastMax = iCurPossibleDancePoints;
2006-01-22 01:00:06 +00:00
RString sNumToDisplay;
if( PREFSMAN->m_bDancePointsForOni )
{
2005-08-30 02:01:05 +00:00
sNumToDisplay = ssprintf( "%*d", m_iDancePointsDigits, max( 0, iActualDancePoints ) );
}
else
{
float fPercentDancePoints = m_pPlayerStageStats->GetPercentDancePoints();
float fCurMaxPercentDancePoints = m_pPlayerStageStats->GetCurMaxPercentDancePoints();
2005-08-30 02:01:05 +00:00
if( m_bApplyScoreDisplayOptions )
{
switch( m_pPlayerState->m_PlayerOptions.GetCurrent().m_ScoreDisplay )
{
case PlayerOptions::SCORING_ADD:
// nothing to do
break;
case PlayerOptions::SCORING_SUBTRACT:
fPercentDancePoints = 1.0f - ( fCurMaxPercentDancePoints - fPercentDancePoints );
break;
case PlayerOptions::SCORING_AVERAGE:
if( fCurMaxPercentDancePoints == 0.0f ) // don't divide by zero fats
fPercentDancePoints = 0.0f;
else
fPercentDancePoints = fPercentDancePoints / fCurMaxPercentDancePoints;
break;
}
}
2004-01-25 05:34:23 +00:00
// clamp percentage - feedback is that negative numbers look weird here.
CLAMP( fPercentDancePoints, 0.f, 1.f );
2005-08-30 02:01:05 +00:00
if( m_bUseRemainder )
2003-10-05 00:30:55 +00:00
{
int iPercentWhole = int(fPercentDancePoints*100);
int iPercentRemainder = int( (fPercentDancePoints*100 - int(fPercentDancePoints*100)) * 10 );
sNumToDisplay = ssprintf( "%2d", iPercentWhole );
2003-10-05 00:30:55 +00:00
m_textPercentRemainder.SetText( ssprintf(".%01d%%", iPercentRemainder) );
2004-01-12 06:45:36 +00:00
}
else
{
Lua *L = LUA->Get();
m_Format.PushSelf( L );
ASSERT( !lua_isnil(L, -1) );
2006-09-26 08:54:54 +00:00
LuaHelpers::Push( L, fPercentDancePoints );
lua_call( L, 1, 1 ); // 1 args, 1 result
2006-09-22 08:48:49 +00:00
LuaHelpers::Pop( L, sNumToDisplay );
LUA->Release(L);
2004-01-12 06:45:36 +00:00
// HACK: Use the last frame in the numbers texture as '-'
sNumToDisplay.Replace('-','x');
2003-10-05 00:30:55 +00:00
}
}
m_textPercent.SetText( sNumToDisplay );
}
2006-01-22 01:00:06 +00:00
RString PercentageDisplay::FormatPercentScore( float fPercentDancePoints )
{
// TRICKY: printf will round, but we want to truncate. Otherwise, we may display a percent
// score that's too high and doesn't match up with the calculated grade.
float fTruncInterval = powf( 0.1f, (float)PERCENT_TOTAL_SIZE-1 );
// TRICKY: ftruncf is rounding 1.0000000 to 0.99990004. Give a little boost to
// fPercentDancePoints to correct for this.
fPercentDancePoints += 0.000001f;
fPercentDancePoints = ftruncf( fPercentDancePoints, fTruncInterval );
2006-01-22 01:00:06 +00:00
RString s = ssprintf( "%*.*f%%", (int)PERCENT_TOTAL_SIZE, (int)PERCENT_DECIMAL_PLACES, fPercentDancePoints*100 );
return s;
}
2005-08-30 02:01:05 +00:00
// lua start
2006-09-29 09:54:50 +00:00
#include "LuaManager.h"
2005-05-29 02:21:24 +00:00
LuaFunction( FormatPercentScore, PercentageDisplay::FormatPercentScore( FArg(1) ) )
2005-08-30 02:01:05 +00:00
#include "LuaBinding.h"
class LunaPercentageDisplay: public Luna<PercentageDisplay>
{
public:
static int LoadFromStats( T* p, lua_State *L )
{
const PlayerState *pStageStats = Luna<PlayerState>::check( L, 1 );
const PlayerStageStats *pPlayerStageStats = Luna<PlayerStageStats>::check( L, 2 );
p->Load( pStageStats, pPlayerStageStats );
return 0;
}
2006-09-27 20:10:14 +00:00
LunaPercentageDisplay()
2005-08-30 02:01:05 +00:00
{
2006-09-27 20:10:14 +00:00
ADD_METHOD( LoadFromStats );
2005-08-30 02:01:05 +00:00
}
};
LUA_REGISTER_DERIVED_CLASS( PercentageDisplay, ActorFrame )
// lua end
/*
2004-06-08 00:08:04 +00:00
* (c) 2001-2003 Chris Danford
* All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, and/or sell copies of the Software, and to permit persons to
* whom the Software is furnished to do so, provided that the above
* copyright notice(s) and this permission notice appear in all copies of
* the Software and that both the above copyright notice(s) and this
* permission notice appear in supporting documentation.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
* THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS
* INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT
* OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/