From 32a9724841c2cb6cbafa75656c50b7fae78c3c7b Mon Sep 17 00:00:00 2001 From: Steve Checkoway Date: Sat, 9 Jun 2007 07:56:34 +0000 Subject: [PATCH] Move ColorBitmapText to SNetSelectBase since this is very specific to the SMO code. This should probably be done in a general way in BitmapText and the string parsing to color code should be kept where it is used instead of part of the bitmap text class. --- stepmania/src/BitmapText.cpp | 247 +------------------------- stepmania/src/BitmapText.h | 21 +-- stepmania/src/ScreenNetSelectBase.cpp | 241 +++++++++++++++++++++++++ stepmania/src/ScreenNetSelectBase.h | 22 ++- 4 files changed, 264 insertions(+), 267 deletions(-) diff --git a/stepmania/src/BitmapText.cpp b/stepmania/src/BitmapText.cpp index 10838a1dce..96ad1c9dd5 100644 --- a/stepmania/src/BitmapText.cpp +++ b/stepmania/src/BitmapText.cpp @@ -207,10 +207,10 @@ void BitmapText::BuildChars() float fX = SCALE( m_fHorizAlign, 0.0f, 1.0f, -m_size.x/2.0f, +m_size.x/2.0f - iLineWidth ); int iX = lrintf( fX ); - for( unsigned i = 0; i < sLine.size(); ++i ) + for( unsigned j = 0; j < sLine.size(); ++j ) { RageSpriteVertex v[4]; - const glyph &g = m_pFont->GetGlyph( sLine[i] ); + const glyph &g = m_pFont->GetGlyph( sLine[j] ); if( m_pFont->IsRightToLeft() ) iX -= g.m_iHadvance; @@ -620,249 +620,6 @@ void BitmapText::SetWrapWidthPixels( int iWrapWidthPixels ) SetText( m_sText, "", iWrapWidthPixels ); } -ColorBitmapText::ColorBitmapText( ) : BitmapText() -{ - m_vColors.clear(); -} - -void ColorBitmapText::SetText( const RString& _sText, const RString& _sAlternateText, int iWrapWidthPixels ) -{ - ASSERT( m_pFont ); - - RString sNewText = StringWillUseAlternate(_sText,_sAlternateText) ? _sAlternateText : _sText; - - if( iWrapWidthPixels == -1 ) // wrap not specified - iWrapWidthPixels = m_iWrapWidthPixels; - - if( m_sText == sNewText && iWrapWidthPixels==m_iWrapWidthPixels ) - return; - m_sText = sNewText; - m_iWrapWidthPixels = iWrapWidthPixels; - - // Set up the first color. - m_vColors.clear(); - ColorChange change; - change.c = RageColor ( 1, 1, 1, 1 ); - change.l = 0; - m_vColors.push_back( change ); - - m_wTextLines.clear(); - - RString sCurrentLine = ""; - int iLineWidth = 0; - - RString sCurrentWord = ""; - int iWordWidth = 0; - int iGlyphsSoFar = 0; - - for( unsigned i = 0; i < m_sText.length(); i++ ) - { - int iCharsLeft = m_sText.length() - i - 1; - - // First: Check for the special (color) case. - - RString FirstThree = m_sText.substr( i, 3 ); - if( FirstThree.CompareNoCase("|c0") == 0 && iCharsLeft > 8 ) - { - ColorChange change; - int r, g, b; - sscanf( m_sText, "|%*c0%2x%2x%2x", &r, &g, &b ); - change.c = RageColor( r/255.f, g/255.f, b/255.f, 1.f ); - change.l = iGlyphsSoFar; - if( iGlyphsSoFar == 0 ) - m_vColors[0] = change; - else - m_vColors.push_back( change ); - i+=8; - continue; - } - - char curChar = m_sText[0]; - int iCharLen = m_pFont->GetLineWidthInSourcePixels( wstring(1, curChar) ); - - switch( curChar ) - { - case ' ': - if( /* iLineWidth == 0 &&*/ iWordWidth == 0 ) - break; - sCurrentLine += sCurrentWord + " "; - iLineWidth += iWordWidth + iCharLen; - sCurrentWord = ""; - iWordWidth = 0; - iGlyphsSoFar++; - break; - case '\n': - if( iLineWidth + iWordWidth > iWrapWidthPixels ) - { - SimpleAddLine( sCurrentLine, iLineWidth ); - if( iWordWidth > 0 ) - iLineWidth = iWordWidth + //Add the width of a space - m_pFont->GetLineWidthInSourcePixels( RStringToWstring( " " ) ); - sCurrentLine = sCurrentWord + " "; - iWordWidth = 0; - sCurrentWord = ""; - iGlyphsSoFar++; - } - else - { - SimpleAddLine( sCurrentLine + sCurrentWord, iLineWidth + iWordWidth ); - sCurrentLine = ""; iLineWidth = 0; - sCurrentWord = ""; iWordWidth = 0; - } - break; - default: - if( iWordWidth + iCharLen > iWrapWidthPixels && iLineWidth == 0 ) - { - SimpleAddLine( sCurrentWord, iWordWidth ); - sCurrentWord = curChar; iWordWidth = iCharLen; - } - else if( iWordWidth + iLineWidth + iCharLen > iWrapWidthPixels ) - { - SimpleAddLine( sCurrentLine, iLineWidth ); - sCurrentLine = ""; - iLineWidth = 0; - sCurrentWord += curChar; - iWordWidth += iCharLen; - } - else - { - sCurrentWord += curChar; - iWordWidth += iCharLen; - } - iGlyphsSoFar++; - break; - } - } - - if( iWordWidth > 0 ) - { - sCurrentLine += sCurrentWord; - iLineWidth += iWordWidth; - } - - if( iLineWidth > 0 ) - SimpleAddLine( sCurrentLine, iLineWidth ); - - BuildChars(); - UpdateBaseZoom(); -} - -void ColorBitmapText::SimpleAddLine( const RString &sAddition, const int iWidthPixels) -{ - m_wTextLines.push_back( RStringToWstring( sAddition ) ); - m_iLineWidths.push_back( iWidthPixels ); -} - -void ColorBitmapText::DrawPrimitives( ) -{ - Actor::SetGlobalRenderStates(); // set Actor-specified render states - DISPLAY->SetTextureMode( TextureUnit_1, TextureMode_Modulate ); - - /* Draw if we're not fully transparent or the zbuffer is enabled */ - if( m_pTempState->diffuse[0].a != 0 ) - { - // - // render the shadow - // - if( m_fShadowLength != 0 ) - { - DISPLAY->PushMatrix(); - DISPLAY->TranslateWorld( m_fShadowLength, m_fShadowLength, 0 ); // shift by 5 units - - RageColor dim(0,0,0,0.5f*m_pTempState->diffuse[0].a); // semi-transparent black - - for( unsigned i=0; iPopMatrix(); - } - - // - // render the diffuse pass - // - int loc = 0, cur = 0; - RageColor c = m_pTempState->diffuse[0]; - - for( unsigned i=0; i m_vColors[cur].l ) - { - c = m_vColors[cur].c; - cur++; - } - } - for( unsigned j=0; j<4; j++ ) - m_aVertices[i+j].c = c; - } - - DrawChars(); - } - - /* render the glow pass */ - if( m_pTempState->glow.a > 0.0001f ) - { - DISPLAY->SetTextureMode( TextureUnit_1, TextureMode_Glow ); - - for( unsigned i=0; iglow; - DrawChars(); - } -} - -void ColorBitmapText::SetMaxLines( int iNumLines, int iDirection ) -{ - iNumLines = max( 0, iNumLines ); - iNumLines = min( (int)m_wTextLines.size(), iNumLines ); - if( iDirection == 0 ) - { - // Crop all bottom lines - m_wTextLines.resize( iNumLines ); - m_iLineWidths.resize( iNumLines ); - } - else - { - // Because colors are relative to the beginning, we have to crop them back - unsigned shift = 0; - - for( unsigned i = 0; i < m_wTextLines.size() - iNumLines; i++ ) - shift += m_wTextLines[i].length(); - - - // When we're cutting out text, we need to maintain the last - // color, so our text at the top doesn't become colorless. - RageColor LastColor; - - for( unsigned i = 0; i < m_vColors.size(); i++ ) - { - m_vColors[i].l -= shift; - if( m_vColors[i].l < 0 ) - { - LastColor = m_vColors[i].c; - m_vColors.erase( m_vColors.begin() + i ); - i--; - } - } - - // If we already have a color set for the first char - // do not override it. - if( m_vColors.size() > 0 && m_vColors[0].l > 0 ) - { - ColorChange tmp; - tmp.c = LastColor; - tmp.l = 0; - m_vColors.insert( m_vColors.begin(), tmp ); - } - - m_wTextLines.erase( m_wTextLines.begin(), m_wTextLines.end() - iNumLines ); - m_iLineWidths.erase( m_iLineWidths.begin(), m_iLineWidths.end() - iNumLines ); - } - BuildChars(); -} - // lua start #include "FontCharAliases.h" class LunaBitmapText: public Luna diff --git a/stepmania/src/BitmapText.h b/stepmania/src/BitmapText.h index 53bb6d3fdc..0c1a2cd869 100644 --- a/stepmania/src/BitmapText.h +++ b/stepmania/src/BitmapText.h @@ -21,7 +21,7 @@ public: bool LoadFromFont( const RString& sFontName ); bool LoadFromTextureAndChars( const RString& sTexturePath, const RString& sChars ); - void SetText( const RString& sText, const RString& sAlternateText = "", int iWrapWidthPixels = -1 ); + virtual void SetText( const RString& sText, const RString& sAlternateText = "", int iWrapWidthPixels = -1 ); void SetVertSpacing( int iSpacing ); void SetMaxWidth( float fMaxWidth ); void SetMaxHeight( float fMaxHeight ); @@ -70,25 +70,6 @@ protected: void UpdateBaseZoom(); }; -class ColorBitmapText : public BitmapText -{ -public: - ColorBitmapText(); - void SetText( const RString &sText, const RString &sAlternateText = "", int iWrapWidthPixels = -1 ); - void DrawPrimitives(); - void SetMaxLines( int iLines, bool bCutBottom = true ); //if bCutBottom = false then, it will crop the top - void SimpleAddLine( const RString &sAddition, int iWidthPixels ); - void SetMaxLines( int iNumLines, int iDirection ); -protected: - struct ColorChange - { - RageColor c; //Color to change to - int l; //Change Location - }; - vector m_vColors; -}; - - #endif /* diff --git a/stepmania/src/ScreenNetSelectBase.cpp b/stepmania/src/ScreenNetSelectBase.cpp index faefb2f9ad..32327e1aec 100644 --- a/stepmania/src/ScreenNetSelectBase.cpp +++ b/stepmania/src/ScreenNetSelectBase.cpp @@ -14,6 +14,8 @@ #include "GameState.h" #include "InputEventPlus.h" #include "RageInput.h" +#include "Font.h" +#include "RageDisplay.h" #define CHATINPUT_WIDTH THEME->GetMetricF(m_sName,"ChatInputBoxWidth") #define CHATINPUT_HEIGHT THEME->GetMetricF(m_sName,"ChatInputBoxHeight") @@ -218,6 +220,245 @@ void ScreenNetSelectBase::UpdateUsers() } } +void ColorBitmapText::SetText( const RString& _sText, const RString& _sAlternateText, int iWrapWidthPixels ) +{ + ASSERT( m_pFont ); + + RString sNewText = StringWillUseAlternate(_sText,_sAlternateText) ? _sAlternateText : _sText; + + if( iWrapWidthPixels == -1 ) // wrap not specified + iWrapWidthPixels = m_iWrapWidthPixels; + + if( m_sText == sNewText && iWrapWidthPixels==m_iWrapWidthPixels ) + return; + m_sText = sNewText; + m_iWrapWidthPixels = iWrapWidthPixels; + + // Set up the first color. + m_vColors.clear(); + ColorChange change; + change.c = RageColor ( 1, 1, 1, 1 ); + change.l = 0; + m_vColors.push_back( change ); + + m_wTextLines.clear(); + + RString sCurrentLine = ""; + int iLineWidth = 0; + + RString sCurrentWord = ""; + int iWordWidth = 0; + int iGlyphsSoFar = 0; + + for( unsigned i = 0; i < m_sText.length(); i++ ) + { + int iCharsLeft = m_sText.length() - i - 1; + + // First: Check for the special (color) case. + + RString FirstThree = m_sText.substr( i, 3 ); + if( FirstThree.CompareNoCase("|c0") == 0 && iCharsLeft > 8 ) + { + ColorChange change; + int r, g, b; + sscanf( m_sText, "|%*c0%2x%2x%2x", &r, &g, &b ); + change.c = RageColor( r/255.f, g/255.f, b/255.f, 1.f ); + change.l = iGlyphsSoFar; + if( iGlyphsSoFar == 0 ) + m_vColors[0] = change; + else + m_vColors.push_back( change ); + i+=8; + continue; + } + + char curChar = m_sText[0]; + int iCharLen = m_pFont->GetLineWidthInSourcePixels( wstring(1, curChar) ); + + switch( curChar ) + { + case ' ': + if( /* iLineWidth == 0 &&*/ iWordWidth == 0 ) + break; + sCurrentLine += sCurrentWord + " "; + iLineWidth += iWordWidth + iCharLen; + sCurrentWord = ""; + iWordWidth = 0; + iGlyphsSoFar++; + break; + case '\n': + if( iLineWidth + iWordWidth > iWrapWidthPixels ) + { + SimpleAddLine( sCurrentLine, iLineWidth ); + if( iWordWidth > 0 ) + iLineWidth = iWordWidth + //Add the width of a space + m_pFont->GetLineWidthInSourcePixels( RStringToWstring( " " ) ); + sCurrentLine = sCurrentWord + " "; + iWordWidth = 0; + sCurrentWord = ""; + iGlyphsSoFar++; + } + else + { + SimpleAddLine( sCurrentLine + sCurrentWord, iLineWidth + iWordWidth ); + sCurrentLine = ""; iLineWidth = 0; + sCurrentWord = ""; iWordWidth = 0; + } + break; + default: + if( iWordWidth + iCharLen > iWrapWidthPixels && iLineWidth == 0 ) + { + SimpleAddLine( sCurrentWord, iWordWidth ); + sCurrentWord = curChar; iWordWidth = iCharLen; + } + else if( iWordWidth + iLineWidth + iCharLen > iWrapWidthPixels ) + { + SimpleAddLine( sCurrentLine, iLineWidth ); + sCurrentLine = ""; + iLineWidth = 0; + sCurrentWord += curChar; + iWordWidth += iCharLen; + } + else + { + sCurrentWord += curChar; + iWordWidth += iCharLen; + } + iGlyphsSoFar++; + break; + } + } + + if( iWordWidth > 0 ) + { + sCurrentLine += sCurrentWord; + iLineWidth += iWordWidth; + } + + if( iLineWidth > 0 ) + SimpleAddLine( sCurrentLine, iLineWidth ); + + BuildChars(); + UpdateBaseZoom(); +} + +void ColorBitmapText::SimpleAddLine( const RString &sAddition, const int iWidthPixels) +{ + m_wTextLines.push_back( RStringToWstring( sAddition ) ); + m_iLineWidths.push_back( iWidthPixels ); +} + +void ColorBitmapText::DrawPrimitives( ) +{ + Actor::SetGlobalRenderStates(); // set Actor-specified render states + DISPLAY->SetTextureMode( TextureUnit_1, TextureMode_Modulate ); + + /* Draw if we're not fully transparent or the zbuffer is enabled */ + if( m_pTempState->diffuse[0].a != 0 ) + { + // + // render the shadow + // + if( m_fShadowLength != 0 ) + { + DISPLAY->PushMatrix(); + DISPLAY->TranslateWorld( m_fShadowLength, m_fShadowLength, 0 ); // shift by 5 units + + RageColor dim(0,0,0,0.5f*m_pTempState->diffuse[0].a); // semi-transparent black + + for( unsigned i=0; iPopMatrix(); + } + + // + // render the diffuse pass + // + int loc = 0, cur = 0; + RageColor c = m_pTempState->diffuse[0]; + + for( unsigned i=0; i m_vColors[cur].l ) + { + c = m_vColors[cur].c; + cur++; + } + } + for( unsigned j=0; j<4; j++ ) + m_aVertices[i+j].c = c; + } + + DrawChars(); + } + + /* render the glow pass */ + if( m_pTempState->glow.a > 0.0001f ) + { + DISPLAY->SetTextureMode( TextureUnit_1, TextureMode_Glow ); + + for( unsigned i=0; iglow; + DrawChars(); + } +} + +void ColorBitmapText::SetMaxLines( int iNumLines, int iDirection ) +{ + iNumLines = max( 0, iNumLines ); + iNumLines = min( (int)m_wTextLines.size(), iNumLines ); + if( iDirection == 0 ) + { + // Crop all bottom lines + m_wTextLines.resize( iNumLines ); + m_iLineWidths.resize( iNumLines ); + } + else + { + // Because colors are relative to the beginning, we have to crop them back + unsigned shift = 0; + + for( unsigned i = 0; i < m_wTextLines.size() - iNumLines; i++ ) + shift += m_wTextLines[i].length(); + + + // When we're cutting out text, we need to maintain the last + // color, so our text at the top doesn't become colorless. + RageColor LastColor; + + for( unsigned i = 0; i < m_vColors.size(); i++ ) + { + m_vColors[i].l -= shift; + if( m_vColors[i].l < 0 ) + { + LastColor = m_vColors[i].c; + m_vColors.erase( m_vColors.begin() + i ); + i--; + } + } + + // If we already have a color set for the first char + // do not override it. + if( m_vColors.size() > 0 && m_vColors[0].l > 0 ) + { + ColorChange tmp; + tmp.c = LastColor; + tmp.l = 0; + m_vColors.insert( m_vColors.begin(), tmp ); + } + + m_wTextLines.erase( m_wTextLines.begin(), m_wTextLines.end() - iNumLines ); + m_iLineWidths.erase( m_iLineWidths.begin(), m_iLineWidths.end() - iNumLines ); + } + BuildChars(); +} + + void UtilSetQuadInit( Actor& actor, const RString &sClassName ) { ActorUtil::LoadAllCommandsAndSetXYAndOnCommand( actor, sClassName ); diff --git a/stepmania/src/ScreenNetSelectBase.h b/stepmania/src/ScreenNetSelectBase.h index 0e4809476a..e321523d7c 100644 --- a/stepmania/src/ScreenNetSelectBase.h +++ b/stepmania/src/ScreenNetSelectBase.h @@ -8,6 +8,24 @@ #include "Quad.h" #include "BitmapText.h" +class ColorBitmapText : public BitmapText +{ +public: + void SetText( const RString &sText, const RString &sAlternateText = "", int iWrapWidthPixels = -1 ); + void DrawPrimitives(); + void SetMaxLines( int iLines, bool bCutBottom = true ); //if bCutBottom = false then, it will crop the top + void SimpleAddLine( const RString &sAddition, int iWidthPixels ); + void SetMaxLines( int iNumLines, int iDirection ); +protected: + struct ColorChange + { + RageColor c; //Color to change to + int l; //Change Location + }; + vector m_vColors; +}; + + class ScreenNetSelectBase : public ScreenWithMenuElements { public: @@ -21,8 +39,8 @@ public: void UpdateTextInput(); private: //Chatting - ColorBitmapText m_textChatInput; - ColorBitmapText m_textChatOutput; + ColorBitmapText m_textChatInput; + ColorBitmapText m_textChatOutput; Sprite m_sprChatInputBox; Sprite m_sprChatOutputBox; RString m_sTextInput;