diff --git a/stepmania/Themes/default/metrics.ini b/stepmania/Themes/default/metrics.ini index b7befcd244..4e474280ad 100644 --- a/stepmania/Themes/default/metrics.ini +++ b/stepmania/Themes/default/metrics.ini @@ -2386,6 +2386,9 @@ WarningCommand0=stoptweening;stopeffect;linear,0.2;zoomx,1 [ScreenOptions] Fallback=ScreenWithMenuElements NumRowsShown=10 +RowInitCommand= +RowOnCommand= +RowOffCommand= RowPositionTransformFunction=function(self,positionIndex,itemIndex,numItems) self:y(SCREEN_CENTER_Y-152+34*positionIndex) end RowOffScreenTopTransformFunction=function(self,positionIndex,itemIndex,numItems) self:y(SCREEN_CENTER_Y-152+34*(-0.5)) end RowOffScreenCenterTransformFunction=function(self,positionIndex,itemIndex,numItems) self:y(SCREEN_CENTER_Y-152+34*(4.5)) end diff --git a/stepmania/src/ActorScroller.cpp b/stepmania/src/ActorScroller.cpp index 332e5a1181..729d331148 100644 --- a/stepmania/src/ActorScroller.cpp +++ b/stepmania/src/ActorScroller.cpp @@ -39,8 +39,6 @@ ActorScroller::ActorScroller() m_quadMask.SetBlendMode( BLEND_NO_EFFECT ); // don't change color values m_quadMask.SetUseZBuffer( true ); // we want to write to the Zbuffer m_quadMask.SetHidden( true ); - - m_iSubdivisions = 1; } void ActorScroller::Load2( @@ -62,9 +60,9 @@ void ActorScroller::Load2( m_fMaskHeight = fItemHeight; m_exprTransformFunction.SetFromExpression( - ssprintf("function(self,offset,itemIndex,numItems) return self:y(%f*offset) end",fItemHeight) + ssprintf("function(self,offset,itemIndex,numItems) return self:y(%f*offset) end",fItemHeight), + 1 ); - m_iSubdivisions = 1; m_bLoop = bLoop; m_fSecondsPerItem = fSecondsPerItem; @@ -101,8 +99,7 @@ void ActorScroller::Load3( m_fSecondsPerItem = fSecondsPerItem; m_fNumItemsToDraw = fNumItemsToDraw; m_bFastCatchup = bFastCatchup; - m_exprTransformFunction.SetFromExpression( sTransformFunction ); - m_iSubdivisions = iSubdivisions; + m_exprTransformFunction.SetFromExpression( sTransformFunction, iSubdivisions ); m_fQuantizePixels = 0; m_bUseMask = bUseMask; m_bLoop = bLoop; @@ -143,7 +140,7 @@ void ActorScroller::LoadFromNode( const CString &sDir, const XNode *pNode ) GET_VALUE( "ItemPaddingStart", fItemPaddingStart ); GET_VALUE( "ItemPaddingEnd", fItemPaddingEnd ); GET_VALUE( "TransformFunction", sTransformFunction ); - pNode->GetAttrValue( "Subdivisions", m_iSubdivisions ); + pNode->GetAttrValue( "Subdivisions", iSubdivisions ); #undef GET_VALUE Load3( @@ -209,50 +206,17 @@ void ActorScroller::UpdateInternal( float fDeltaTime ) m_fCurrentItem = fmodf( m_fCurrentItem, m_fNumItemsToDraw+1 ); } -const Actor::TweenState &ActorScroller::GetPosition( float fPositionOffsetFromCenter, int iItemIndex, int iNumItems ) -{ - PositionOffsetAndItemIndex key = { fPositionOffsetFromCenter, iItemIndex }; - - map::iterator iter = m_mapPositionToTweenStateCache.find( key ); - if( iter != m_mapPositionToTweenStateCache.end() ) - return iter->second; - - Actor a; - - Lua *L = LUA->Get(); - m_exprTransformFunction.PushSelf( L ); - ASSERT( !lua_isnil(L, -1) ); - a.PushSelf( L ); - LuaHelpers::Push( fPositionOffsetFromCenter, L ); - LuaHelpers::Push( iItemIndex, L ); - LuaHelpers::Push( iNumItems, L ); - lua_call( L, 4, 0 ); // 4 args, 0 results - LUA->Release(L); - - return m_mapPositionToTweenStateCache[key] = a.DestTweenState(); -} - -void ActorScroller::PositionItem( Actor *pActor, float fPositionOffsetFromCenter, int iItemIndex, int iNumItems ) -{ - float fInterval = 1.0f / m_iSubdivisions; - float fFloor = QuantizeDown( fPositionOffsetFromCenter, fInterval ); - float fCeil = QuantizeUp( fPositionOffsetFromCenter, fInterval ); - - if( fFloor == fCeil ) - { - pActor->DestTweenState() = GetPosition( fCeil, iItemIndex, iNumItems ); - } - else - { - const Actor::TweenState &tsFloor = GetPosition( fFloor, iItemIndex, iNumItems ); - const Actor::TweenState &tsCeil = GetPosition( fCeil, iItemIndex, iNumItems ); - - float fPercentTowardCeil = SCALE( fPositionOffsetFromCenter, fFloor, fCeil, 0.0f, 1.0f ); - Actor::TweenState::MakeWeightedAverage( pActor->DestTweenState(), tsFloor, tsCeil, fPercentTowardCeil ); - } -} - void ActorScroller::DrawPrimitives() +{ + PositionItemsAndDrawPrimitives( true, true ); +} + +void ActorScroller::PositionItems() +{ + PositionItemsAndDrawPrimitives( true, false ); +} + +void ActorScroller::PositionItemsAndDrawPrimitives( bool bPosition, bool bDrawPrimitives ) { // Optimization: If we weren't loaded, then fall back to the ActorFrame logic if( !m_bLoaded ) @@ -277,11 +241,11 @@ void ActorScroller::DrawPrimitives() if( m_bUseMask ) { - PositionItem( &m_quadMask, fPositionFullyOffScreenTop, -1, m_SubActors.size() ); - m_quadMask.Draw(); + if( bPosition ) m_exprTransformFunction.PositionItem( &m_quadMask, fPositionFullyOffScreenTop, -1, m_SubActors.size() ); + if( bDrawPrimitives ) m_quadMask.Draw(); - PositionItem( &m_quadMask, fPositionFullyOffScreenBottom, m_SubActors.size(), m_SubActors.size() ); - m_quadMask.Draw(); + if( bPosition ) m_exprTransformFunction.PositionItem( &m_quadMask, fPositionFullyOffScreenBottom, m_SubActors.size(), m_SubActors.size() ); + if( bDrawPrimitives ) m_quadMask.Draw(); fFirstItemToDraw = fPositionFullyOffScreenTop + m_fCurrentItem; fLastItemToDraw = fPositionFullyOffScreenBottom + m_fCurrentItem; @@ -304,11 +268,15 @@ void ActorScroller::DrawPrimitives() else if( iIndex < 0 || iIndex >= (int)m_SubActors.size() ) continue; - PositionItem( m_SubActors[iIndex], fPosition, iIndex, m_SubActors.size() ); - if( bDelayedDraw ) - subs.push_back( m_SubActors[iIndex] ); - else - m_SubActors[iIndex]->Draw(); + if( bPosition ) + m_exprTransformFunction.PositionItem( m_SubActors[iIndex], fPosition, iIndex, m_SubActors.size() ); + if( bDrawPrimitives ) + { + if( bDelayedDraw ) + subs.push_back( m_SubActors[iIndex] ); + else + m_SubActors[iIndex]->Draw(); + } } if( bDelayedDraw ) diff --git a/stepmania/src/ActorScroller.h b/stepmania/src/ActorScroller.h index f51dd4fd8b..643eb20012 100644 --- a/stepmania/src/ActorScroller.h +++ b/stepmania/src/ActorScroller.h @@ -6,6 +6,7 @@ #include "ActorFrame.h" #include "Quad.h" struct XNode; +#include "LuaExpressionTransform.h" class ActorScroller : public ActorFrame { @@ -32,6 +33,8 @@ public: virtual void UpdateInternal( float fDelta ); virtual void DrawPrimitives(); // handles drawing and doesn't call ActorFrame::DrawPrimitives + void PositionItems(); + void LoadFromNode( const CString &sDir, const XNode *pNode ); virtual Actor *Copy() const; @@ -49,8 +52,9 @@ public: void PushSelf( lua_State *L ); protected: + void PositionItemsAndDrawPrimitives( bool bPosition, bool bDrawPrimitives ); + const Actor::TweenState &GetPosition( float fPositionOffsetFromCenter, int iItemIndex, int iNumItems ); - void PositionItem( Actor *pActor, float fPositionOffsetFromCenter, int iItemIndex, int iNumItems ); bool m_bLoaded; float m_fCurrentItem; // Item at top of list, usually between 0 and m_SubActors.size(), approaches destination @@ -68,24 +72,7 @@ protected: float m_fMaskHeight; Quad m_quadMask; - LuaExpression m_exprTransformFunction; // params: self,offset,itemIndex,numItems - int m_iSubdivisions; // 1 == one evaluation per position - struct PositionOffsetAndItemIndex - { - float fPositionOffsetFromCenter; - int iItemIndex; - - bool operator<( const PositionOffsetAndItemIndex &other ) const - { - if( fPositionOffsetFromCenter < other.fPositionOffsetFromCenter ) - return true; - else if( fPositionOffsetFromCenter > other.fPositionOffsetFromCenter ) - return false; - else - return iItemIndex < other.iItemIndex; - } - }; - map m_mapPositionToTweenStateCache; + LuaExpressionTransform m_exprTransformFunction; // params: self,offset,itemIndex,numItems }; class ActorScrollerAutoDeleteChildren : public ActorScroller diff --git a/stepmania/src/LuaExpressionTransform.cpp b/stepmania/src/LuaExpressionTransform.cpp new file mode 100644 index 0000000000..d8c0ca0c1a --- /dev/null +++ b/stepmania/src/LuaExpressionTransform.cpp @@ -0,0 +1,85 @@ +#include "global.h" +#include "LuaExpressionTransform.h" +#include "LuaReference.h" +#include "LuaManager.h" + +LuaExpressionTransform::LuaExpressionTransform() +{ + m_pexprTransformFunction = new LuaExpression; + m_iNumSubdivisions = 1; +} + +void LuaExpressionTransform::SetFromExpression( const CString &sExpression, int iNumSubdivisions ) +{ + m_pexprTransformFunction->SetFromExpression( sExpression ); + m_iNumSubdivisions = iNumSubdivisions; +} + +const Actor::TweenState &LuaExpressionTransform::GetPosition( float fPositionOffsetFromCenter, int iItemIndex, int iNumItems ) +{ + PositionOffsetAndItemIndex key = { fPositionOffsetFromCenter, iItemIndex }; + + map::iterator iter = m_mapPositionToTweenStateCache.find( key ); + if( iter != m_mapPositionToTweenStateCache.end() ) + return iter->second; + + Actor a; + + Lua *L = LUA->Get(); + m_pexprTransformFunction->PushSelf( L ); + ASSERT( !lua_isnil(L, -1) ); + a.PushSelf( L ); + LuaHelpers::Push( fPositionOffsetFromCenter, L ); + LuaHelpers::Push( iItemIndex, L ); + LuaHelpers::Push( iNumItems, L ); + lua_call( L, 4, 0 ); // 4 args, 0 results + LUA->Release(L); + + return m_mapPositionToTweenStateCache[key] = a.DestTweenState(); +} + +void LuaExpressionTransform::PositionItem( Actor *pActor, float fPositionOffsetFromCenter, int iItemIndex, int iNumItems ) +{ + float fInterval = 1.0f / m_iNumSubdivisions; + float fFloor = QuantizeDown( fPositionOffsetFromCenter, fInterval ); + float fCeil = QuantizeUp( fPositionOffsetFromCenter, fInterval ); + + if( fFloor == fCeil ) + { + pActor->DestTweenState() = GetPosition( fCeil, iItemIndex, iNumItems ); + } + else + { + const Actor::TweenState &tsFloor = GetPosition( fFloor, iItemIndex, iNumItems ); + const Actor::TweenState &tsCeil = GetPosition( fCeil, iItemIndex, iNumItems ); + + float fPercentTowardCeil = SCALE( fPositionOffsetFromCenter, fFloor, fCeil, 0.0f, 1.0f ); + Actor::TweenState::MakeWeightedAverage( pActor->DestTweenState(), tsFloor, tsCeil, fPercentTowardCeil ); + } +} + + +/* + * (c) 2003-2004 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. + */ diff --git a/stepmania/src/LuaExpressionTransform.h b/stepmania/src/LuaExpressionTransform.h new file mode 100644 index 0000000000..50185d31a2 --- /dev/null +++ b/stepmania/src/LuaExpressionTransform.h @@ -0,0 +1,67 @@ +/* LuaExpressionTransform - . */ + +#ifndef LuaExpressionTransform_H +#define LuaExpressionTransform_H + +#include "Actor.h" +class LuaExpression; +#include + +class LuaExpressionTransform +{ +public: + LuaExpressionTransform(); + + void SetFromExpression( const CString &sExpression, int iNumSubdivisions ); + + void PositionItem( Actor *pActor, float fPositionOffsetFromCenter, int iItemIndex, int iNumItems ); + const Actor::TweenState &GetPosition( float fPositionOffsetFromCenter, int iItemIndex, int iNumItems ); + +protected: + + LuaExpression *m_pexprTransformFunction; // params: self,offset,itemIndex,numItems + int m_iNumSubdivisions; // 1 == one evaluation per position + struct PositionOffsetAndItemIndex + { + float fPositionOffsetFromCenter; + int iItemIndex; + + bool operator<( const PositionOffsetAndItemIndex &other ) const + { + if( fPositionOffsetFromCenter < other.fPositionOffsetFromCenter ) + return true; + else if( fPositionOffsetFromCenter > other.fPositionOffsetFromCenter ) + return false; + else + return iItemIndex < other.iItemIndex; + } + }; + map m_mapPositionToTweenStateCache; +}; + +#endif + +/* + * (c) 2003-2004 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. + */ diff --git a/stepmania/src/Makefile.am b/stepmania/src/Makefile.am index 83a0194883..1496025668 100644 --- a/stepmania/src/Makefile.am +++ b/stepmania/src/Makefile.am @@ -100,6 +100,7 @@ HighScore.cpp HighScore.h \ InputEventPlus.h \ Inventory.cpp Inventory.h LuaFunctions.h \ LuaReference.cpp LuaReference.h \ +LuaExpressionTransform.cpp LuaExpressionTransform.h \ LyricsLoader.cpp LyricsLoader.h MenuInput.h \ NoteData.cpp NoteData.h NoteDataUtil.cpp NoteDataUtil.h NoteDataWithScoring.cpp NoteDataWithScoring.h \ NoteFieldPositioning.cpp NoteFieldPositioning.h NoteTypes.cpp NoteTypes.h NotesLoader.cpp NotesLoader.h \ diff --git a/stepmania/src/OptionRow.cpp b/stepmania/src/OptionRow.cpp index 555aa56280..d381a74fca 100644 --- a/stepmania/src/OptionRow.cpp +++ b/stepmania/src/OptionRow.cpp @@ -68,8 +68,9 @@ OptionRow::OptionRow( const OptionRowType *pSource ) ZERO( m_OptionIcons ); Clear(); - this->AddChild( &m_Frame ); + + m_tsDestination.Init(); } OptionRow::~OptionRow() @@ -590,11 +591,12 @@ void OptionRow::UpdateEnabledDisabled() bThisRowHasFocusByAll &= m_bRowHasFocus[p]; bool bRowEnabled = !m_RowDef.m_vEnabledForPlayers.empty(); - if( m_Frame.DestTweenState() != m_FrameDestination.DestTweenState() ) + + if( m_Frame.DestTweenState() != m_tsDestination ) { m_Frame.StopTweening(); m_Frame.BeginTweening( m_pParentType->TWEEN_SECONDS ); - m_Frame.DestTweenState() = m_FrameDestination.DestTweenState(); + m_Frame.DestTweenState() = m_tsDestination; } if( bThisRowHasFocusByAny ) @@ -769,7 +771,7 @@ void OptionRow::GetWidthXY( PlayerNumber pn, int iChoiceOnRow, int &iWidthOut, i * their final positions. (This is so we don't tween colors, too.) m_FrameDestination * is the actual destination position, even though we may not have set up the * tween yet. */ - float fY = m_FrameDestination.DestTweenState().pos.y; + float fY = m_tsDestination.pos.y; iYOut = int(roundf(fY)); } diff --git a/stepmania/src/OptionRow.h b/stepmania/src/OptionRow.h index fbc3026ad0..ba3b3dcf91 100644 --- a/stepmania/src/OptionRow.h +++ b/stepmania/src/OptionRow.h @@ -192,7 +192,6 @@ public: void GetWidthXY( PlayerNumber pn, int iChoiceOnRow, int &iWidthOut, int &iXOut, int &iYOut ); // ScreenOptions calls positions m_FrameDestination, then m_Frame tween to that same TweenState. - Actor &GetFrameDestination() { return m_FrameDestination; } void SetRowHidden( bool bRowHidden ) { m_bHidden = bRowHidden; } bool GetRowHidden() { return m_bHidden; } unsigned GetTextItemsSize() { return m_textItems.size(); } @@ -235,7 +234,9 @@ protected: // Only one will true at a time if m_RowDef.bMultiSelect vector m_vbSelected[NUM_PLAYERS]; // size = m_RowDef.choices.size() - Actor m_FrameDestination; // m_Frame should approach the destination TweenState of this. +public: + Actor::TweenState m_tsDestination; // this should approach m_tsDestination. +protected: bool m_bHidden; // currently off screen }; diff --git a/stepmania/src/ScreenOptions.cpp b/stepmania/src/ScreenOptions.cpp index 8e80ad3e10..9ef78b3264 100644 --- a/stepmania/src/ScreenOptions.cpp +++ b/stepmania/src/ScreenOptions.cpp @@ -13,6 +13,7 @@ #include "Command.h" #include "GameCommand.h" #include "OptionRowHandler.h" +#include "LuaBinding.h" /* @@ -73,6 +74,9 @@ static CString OPTION_EXPLANATION( CString s ) //REGISTER_SCREEN_CLASS( ScreenOptions ); // can't be instantiated ScreenOptions::ScreenOptions( CString sClassName ) : ScreenWithMenuElements(sClassName), NUM_ROWS_SHOWN (m_sName,"NumRowsShown"), + ROW_INIT_COMMAND (m_sName,"RowInitCommand"), + ROW_ON_COMMAND (m_sName,"RowOnCommand"), + ROW_OFF_COMMAND (m_sName,"RowOffCommand"), EXPLANATION_X (m_sName,EXPLANATION_X_NAME,NUM_PLAYERS), EXPLANATION_Y (m_sName,EXPLANATION_Y_NAME,NUM_PLAYERS), EXPLANATION_ON_COMMAND (m_sName,EXPLANATION_ON_COMMAND_NAME,NUM_PLAYERS), @@ -100,10 +104,10 @@ ScreenOptions::ScreenOptions( CString sClassName ) : ScreenWithMenuElements(sCla m_OptionsNavigation = PREFSMAN->m_bArcadeOptionsNavigation? NAV_THREE_KEY:NAV_FIVE_KEY; m_InputMode = INPUTMODE_SHARE_CURSOR; - m_exprRowPositionTransformFunction .SetFromExpression( THEME->GetMetric(m_sName,"RowPositionTransformFunction") ); - m_exprRowOffScreenTopTransformFunction .SetFromExpression( THEME->GetMetric(m_sName,"RowOffScreenTopTransformFunction") ); - m_exprRowOffScreenCenterTransformFunction .SetFromExpression( THEME->GetMetric(m_sName,"RowOffScreenCenterTransformFunction") ); - m_exprRowOffScreenBottomTransformFunction .SetFromExpression( THEME->GetMetric(m_sName,"RowOffScreenBottomTransformFunction") ); + m_exprRowPositionTransformFunction .SetFromExpression( THEME->GetMetric(m_sName,"RowPositionTransformFunction"), 1 ); + m_exprRowOffScreenTopTransformFunction .SetFromExpression( THEME->GetMetric(m_sName,"RowOffScreenTopTransformFunction"), 1 ); + m_exprRowOffScreenCenterTransformFunction .SetFromExpression( THEME->GetMetric(m_sName,"RowOffScreenCenterTransformFunction"), 1 ); + m_exprRowOffScreenBottomTransformFunction .SetFromExpression( THEME->GetMetric(m_sName,"RowOffScreenBottomTransformFunction"), 1 ); } @@ -249,6 +253,18 @@ void ScreenOptions::InitMenu( const vector &vDefs, const ve m_framePage.SortByDrawOrder(); + FOREACH( OptionRow*, m_pRows, p ) + { + int iIndex = p - m_pRows.begin(); + + Lua *L = LUA->Get(); + LuaHelpers::Push( iIndex, L ); + (*p)->m_pLuaInstance->Set( L, "iIndex" ); + LUA->Release( L ); + + (*p)->RunCommands( ROW_INIT_COMMAND ); + } + // poke once at all the explanation metrics so that we catch missing ones early for( int r=0; r<(int)m_pRows.size(); r++ ) // foreach row { @@ -309,7 +325,7 @@ void ScreenOptions::BeginScreen() CHECKPOINT; - PositionItems(); + PositionRows(); PositionAllUnderlines(); PositionIcons(); RefreshAllIcons(); @@ -320,22 +336,15 @@ void ScreenOptions::BeginScreen() AfterChangeValueOrRow( p ); CHECKPOINT; - - /* It's tweening into position, but on the initial tween-in we only want to - * tween in the whole page at once. Since the tweens are nontrivial, it's - * easiest to queue the tweens and then force them to finish. */ - for( int r=0; r<(int) m_pRows.size(); r++ ) // foreach options line - { - OptionRow &row = *m_pRows[r]; - row.FinishTweening(); - } - } void ScreenOptions::TweenOnScreen() { ScreenWithMenuElements::TweenOnScreen(); + FOREACH( OptionRow*, m_pRows, p ) + (*p)->RunCommands( ROW_ON_COMMAND ); + ON_COMMAND( m_sprPage ); FOREACH_HumanPlayer( p ) { @@ -353,6 +362,16 @@ void ScreenOptions::TweenOnScreen() m_framePage.SortByDrawOrder(); } +void ScreenOptions::TweenOffScreen() +{ + ScreenWithMenuElements::TweenOffScreen(); + + FOREACH( OptionRow*, m_pRows, p ) + (*p)->RunCommands( ROW_OFF_COMMAND ); + + OFF_COMMAND( m_framePage ); +} + ScreenOptions::~ScreenOptions() { LOG->Trace( "ScreenOptions::~ScreenOptions()" ); @@ -614,7 +633,7 @@ void ScreenOptions::HandleScreenMessage( const ScreenMessage SM ) SCREENMAN->PlayStartSound(); - OFF_COMMAND( m_framePage ); + TweenOffScreen(); } else if( SM == SM_GainFocus ) { @@ -629,7 +648,7 @@ void ScreenOptions::HandleScreenMessage( const ScreenMessage SM ) } -void ScreenOptions::PositionItems() +void ScreenOptions::PositionRows() { const int total = NUM_ROWS_SHOWN; const int halfsize = total / 2; @@ -663,7 +682,9 @@ void ScreenOptions::PositionItems() first_start = max( P1Choice - halfsize, 0 ); first_end = first_start + total; second_start = second_end = first_end; - } else { + } + else + { /* First half: */ const int earliest = min( P1Choice, P2Choice ); first_start = max( earliest - halfsize/2, 0 ); @@ -710,29 +731,14 @@ void ScreenOptions::PositionItems() OptionRow &row = *Rows[i]; - LuaExpression *pExpr = NULL; - if( i < first_start ) - pExpr = &m_exprRowOffScreenTopTransformFunction; - else if( i < first_end ) - pExpr = &m_exprRowPositionTransformFunction; - else if( i < second_start ) - pExpr = &m_exprRowOffScreenCenterTransformFunction; - else if( i < second_end ) - pExpr = &m_exprRowPositionTransformFunction; - else - pExpr = &m_exprRowOffScreenBottomTransformFunction; + LuaExpressionTransform *pExpr = NULL; + if( i < first_start ) pExpr = &m_exprRowOffScreenTopTransformFunction; + else if( i < first_end ) pExpr = &m_exprRowPositionTransformFunction; + else if( i < second_start ) pExpr = &m_exprRowOffScreenCenterTransformFunction; + else if( i < second_end ) pExpr = &m_exprRowPositionTransformFunction; + else pExpr = &m_exprRowOffScreenBottomTransformFunction; - Lua *L = LUA->Get(); - - pExpr->PushSelf( L ); - - ASSERT( !lua_isnil(L, -1) ); - row.GetFrameDestination().PushSelf( L ); - LuaHelpers::Push( pos, L ); - LuaHelpers::Push( i, L ); - LuaHelpers::Push( min( (int)Rows.size(), (int)NUM_ROWS_SHOWN ), L ); - lua_call( L, 4, 0 ); // 4 args, 0 results - LUA->Release(L); + row.m_tsDestination = pExpr->GetPosition( pos, i, min( (int)Rows.size(), (int)NUM_ROWS_SHOWN ) ); bool bHidden = i < first_start || @@ -745,7 +751,7 @@ void ScreenOptions::PositionItems() if( ExitRow ) { - ExitRow->GetFrameDestination().SetY( SEPARATE_EXIT_ROW_Y ); + ExitRow->m_tsDestination.pos.y = SEPARATE_EXIT_ROW_Y; ExitRow->SetRowHidden( second_end != (int) Rows.size() ); } } @@ -762,7 +768,7 @@ void ScreenOptions::AfterChangeValueOrRow( PlayerNumber pn ) return; /* Update m_fY and m_bHidden[]. */ - PositionItems(); + PositionRows(); /* Do positioning. */ PositionAllUnderlines(); diff --git a/stepmania/src/ScreenOptions.h b/stepmania/src/ScreenOptions.h index 8836dedec3..7b7fc650f7 100644 --- a/stepmania/src/ScreenOptions.h +++ b/stepmania/src/ScreenOptions.h @@ -9,6 +9,7 @@ #include "ThemeMetric.h" #include "OptionRow.h" #include "OptionsCursor.h" +#include "LuaExpressionTransform.h" class OptionRowHandler; @@ -39,6 +40,7 @@ protected: OptionRowType m_OptionRowType; virtual void TweenOnScreen(); + virtual void TweenOffScreen(); virtual void ImportOptions( int iRow, const vector &vpns ) = 0; virtual void ExportOptions( int iRow, const vector &vpns ) = 0; @@ -53,7 +55,7 @@ protected: virtual void RefreshIcons( int iRow, PlayerNumber pn ); void RefreshAllIcons(); void PositionCursors(); - void PositionItems(); + void PositionRows(); void TweenCursor( PlayerNumber pn ); void UpdateText( int iRow ); void UpdateEnabledDisabled(); @@ -133,10 +135,13 @@ protected: // metrics ThemeMetric NUM_ROWS_SHOWN; - LuaExpression m_exprRowPositionTransformFunction; // params: self,positionIndex,itemIndex,numItems - LuaExpression m_exprRowOffScreenTopTransformFunction; // params: self,positionIndex,itemIndex,numItems - LuaExpression m_exprRowOffScreenCenterTransformFunction; // params: self,positionIndex,itemIndex,numItems - LuaExpression m_exprRowOffScreenBottomTransformFunction; // params: self,positionIndex,itemIndex,numItems + ThemeMetric ROW_INIT_COMMAND; + ThemeMetric ROW_ON_COMMAND; + ThemeMetric ROW_OFF_COMMAND; + LuaExpressionTransform m_exprRowPositionTransformFunction; // params: self,positionIndex,itemIndex,numItems + LuaExpressionTransform m_exprRowOffScreenTopTransformFunction; // params: self,positionIndex,itemIndex,numItems + LuaExpressionTransform m_exprRowOffScreenCenterTransformFunction; // params: self,positionIndex,itemIndex,numItems + LuaExpressionTransform m_exprRowOffScreenBottomTransformFunction; // params: self,positionIndex,itemIndex,numItems ThemeMetric1D EXPLANATION_X; ThemeMetric1D EXPLANATION_Y; ThemeMetric1D EXPLANATION_ON_COMMAND; diff --git a/stepmania/src/StepMania-net2003.vcproj b/stepmania/src/StepMania-net2003.vcproj index 4a05003a9b..f36ff1adce 100644 --- a/stepmania/src/StepMania-net2003.vcproj +++ b/stepmania/src/StepMania-net2003.vcproj @@ -877,6 +877,12 @@ cl /Zl /nologo /c verstub.cpp /Fo"$(IntDir)"\ + + + + diff --git a/stepmania/src/StepMania.dsp b/stepmania/src/StepMania.dsp index 35699819d3..6d787268eb 100644 --- a/stepmania/src/StepMania.dsp +++ b/stepmania/src/StepMania.dsp @@ -62,7 +62,7 @@ IntDir=.\../Debug6 TargetDir=\cvs\stepmania\Program TargetName=StepMania-debug SOURCE="$(InputPath)" -PreLink_Cmds=archutils\Win32\verinc cl /Zl /nologo /c verstub.cpp /Fo$(IntDir)\ +PreLink_Cmds=archutils\Win32\verinc cl /Zl /nologo /c verstub.cpp /Fo$(IntDir)\ PostBuild_Cmds=archutils\Win32\mapconv $(IntDir)\$(TargetName).map $(TargetDir)\StepMania.vdi # End Special Build Tool @@ -99,7 +99,7 @@ IntDir=.\../Release6 TargetDir=\cvs\stepmania\Program TargetName=StepMania SOURCE="$(InputPath)" -PreLink_Cmds=archutils\Win32\verinc cl /Zl /nologo /c verstub.cpp /Fo$(IntDir)\ +PreLink_Cmds=archutils\Win32\verinc cl /Zl /nologo /c verstub.cpp /Fo$(IntDir)\ PostBuild_Cmds=archutils\Win32\mapconv $(IntDir)\$(TargetName).map $(TargetDir)\StepMania.vdi # End Special Build Tool @@ -904,6 +904,14 @@ SOURCE=.\LuaBinding.h # End Source File # Begin Source File +SOURCE=.\LuaExpressionTransform.cpp +# End Source File +# Begin Source File + +SOURCE=.\LuaExpressionTransform.h +# End Source File +# Begin Source File + SOURCE=.\LuaFunctions.h # End Source File # Begin Source File diff --git a/stepmania/src/StepMania.vcproj b/stepmania/src/StepMania.vcproj index a38fbbacc7..a4ba707c78 100644 --- a/stepmania/src/StepMania.vcproj +++ b/stepmania/src/StepMania.vcproj @@ -857,6 +857,12 @@ cl /Zl /nologo /c verstub.cpp /Fo"$(IntDir)"\ + + + +