void SjOscSpectrum::Draw(wxDC& dc, SjOscSpectrumChData* chData, bool volumeBeat, bool showFigures, bool forceAnim) { if( forceAnim ) { // force an initial animation m_crazyState = CRAZY_FADEOUT; m_crazy = CRAZY_MAX; m_firstCrazy = TRUE; int b; if( !g_mainFrame->IsPlaying() ) { for( b = 0; b < NUM_BOXES; b++ ) { m_chData[0].m_boxMax[b] = (double)(NUM_BOXES-b)/(double)NUM_BOXES; m_chData[1].m_boxMax[b] = (double)(b)/(double)NUM_BOXES;; } } } // draw the boxes { double analyzerW = (double)m_clientSize.x * 0.7; long analyzerX = (long)( (m_clientSize.x-analyzerW)/2 ); double analyzerH = (double)(m_clientSize.y / 2) * 0.5; long analyzerY = (m_clientSize.y / 16); double cellW = (analyzerW / (double)NUM_BOXES); double boxW = cellW * 0.8; if( m_crazyState == CRAZY_FADEIN ) { m_crazy += CRAZY_INC; if( m_crazy > CRAZY_MAX ) { m_crazyState = CRAZY_STAY; m_crazySleep = SjTools::Rand(5000/SLEEP_MS); } } else if( m_crazyState == CRAZY_STAY ) { m_crazySleep--; if( m_crazySleep <= 0 ) { m_crazyState = CRAZY_FADEOUT; } } else if( m_crazyState == CRAZY_FADEOUT ) { m_crazy -= CRAZY_INC; if( m_crazy <= 0 ) { m_crazy = 0.0; m_crazyState = CRAZY_NONE; if( !m_firstCrazy && SjTools::Rand(3)!=0 ) { m_crazySleep = SjTools::Rand(1000/SLEEP_MS); } else { m_crazySleep = (10000/SLEEP_MS) + SjTools::Rand(CRAZY_RAND); } m_firstCrazy = FALSE; } } else { m_crazySleep--; if( m_crazySleep <= 0 && volumeBeat && showFigures ) { m_crazyState = CRAZY_FADEIN; } } long i; for( i = 0; i < NUM_BOXES; i++ ) { double val = chData->m_boxY[i]; #define FALLOFF_MS 800 chData->m_boxMax[i] -= 1.0F/((double)FALLOFF_MS/(double)SLEEP_MS); if( val > chData->m_boxMax[i] ) { chData->m_boxMax[i] = val; } DrawBand(dc, (int)( analyzerX + i*cellW ), (int)( analyzerY + m_clientSize.y/2*chData->chNum ), (int)( boxW ), (int)( analyzerH ), chData->m_boxMax[i], m_crazy); } } }
//+--------------------------------------------------------------------------- // // Member: CDispRoot::DrawBand // // Synopsis: Draw one band using the display tree, starting at the top node // in the saved redraw region array. // // Arguments: pContext draw context // // Notes: // //---------------------------------------------------------------------------- void CDispRoot::DrawBands(CDispDrawContext* pContext, CRegion* prgnRedraw, const CRegionStack& redrawRegionStack) { CDispContextStack* pSaveContextStack = pContext->GetContextStack(); Assert(_pOffscreenBuffer); long height = min(_rcContent.Height(), _pOffscreenBuffer->Height()); while(!prgnRedraw->IsEmpty()) { // compute next banding rectangle CRect rcBand; prgnRedraw->GetBounds(&rcBand); rcBand.left = _rcContent.left; rcBand.right = _rcContent.right; rcBand.bottom = rcBand.top + height; if(rcBand.bottom > _rcContent.bottom) { rcBand.bottom = _rcContent.bottom; } // BUGBUG (donmarsh) -- for some reason, we're getting here occasionally // with an empty rcBand. At one time, this could be caused by // _pOffscreenBuffer->Height() returning zero. I don't believe that // is possible any more. However, something is happening, and we have // to check for it, or we will go into an infinite loop. Assert(height>0 && _pOffscreenBuffer->Height()>0); Assert(!rcBand.IsEmpty()); Assert(prgnRedraw->Intersects(rcBand)); if(rcBand.bottom<=rcBand.top || !prgnRedraw->Intersects(rcBand)) { break; } _pOffscreenBuffer->SetBandOffset(rcBand.TopLeft()-_rcContainer.TopLeft()); // clip regions in redraw region stack to this band CRegionStack clippedRedrawRegionStack(redrawRegionStack, rcBand); if(clippedRedrawRegionStack.MoreToPop()) { pContext->SetRedrawRegionStack(&clippedRedrawRegionStack); // restore initial context stack pContext->SetContextStack(pSaveContextStack); pSaveContextStack->Restore(); #ifdef _DEBUG { HDC hdc = _pOffscreenBuffer->GetRawDC(); HBRUSH hbr = CreateSolidBrush(RGB(0, 255, 0)); CRect rc(-10000, -10000, 20000, 20000); FillRect(hdc, &rc, hbr); DeleteObject(hbr); } #endif // draw contents of this band DrawBand(pContext); // draw offscreen buffer to destination _pOffscreenBuffer->Draw(_pRenderSurface, rcBand); // discard clipped regions clippedRedrawRegionStack.DeleteStack(); } // remove band from redraw region prgnRedraw->Subtract(rcBand); } }