void BootupAnimation::renderInStateLogo()
{
	if (!m_logoSurf || !m_logoBrightSurf)
		return;

	const int kLowAlpha  = 0x00 - 0x80;
	const int kHighAlpha = 0xFF;

	static int sCurrAlpha = kLowAlpha;
	static int sDelta = 0x08;

	HostBase* host = HostBase::instance();
	const HostInfo& info = host->getInfo();

	int w = (int) (m_logoSurf->width());
	int h = (int) (m_logoSurf->height());

	int dx = (info.displayWidth  - w) / 2;
	int dy = (info.displayHeight - h) / 2;
	int dr = dx + w;
	int db = dy + h;

	m_ctxt->push();

	m_ctxt->setStrokeColor(PColor32(0x00, 0x00, 0x00, 0x00));
	m_ctxt->setFillColor(PColor32(0x00, 0x00, 0x00, 0xFF));
	m_ctxt->drawRect(0, 0, (int) info.displayWidth, (int) info.displayHeight);

	if (m_rotation != 0) {
		m_ctxt->translate((int)info.displayWidth/2, (int) info.displayHeight/2);
		m_ctxt->rotate(m_rotation);
		m_ctxt->translate((int) -info.displayWidth/2, (int) -info.displayHeight/2);
	}

	if (m_logoSurf) {
		m_ctxt->bitblt(m_logoSurf, dx, dy, dr, db);
	}

	if (m_logoBrightSurf) {
		m_ctxt->setFillOpacity(MAX(MIN(sCurrAlpha, 0xFF), 0x00));
		m_ctxt->bitblt(m_logoBrightSurf, dx, dy, dr, db);
	}

	m_ctxt->pop();

	m_ctxt->flip();

	sCurrAlpha += sDelta;
	if (sCurrAlpha <= kLowAlpha) {
		sDelta = 0x0F;
		sCurrAlpha = kLowAlpha;
	}
	else if (sCurrAlpha >= kHighAlpha) {
		sDelta = -0x0F;
		sCurrAlpha = kHighAlpha;
	}
}
bool WindowContentTransitionRunner::crossFadeTick()
{
    static const int danielNumer = 2;
    static const int danielDenom = 5;

    if (m_toSceneAnimObject.currA == m_toSceneAnimObject.targA) {

        return false;
    }

    int deltaA = m_toSceneAnimObject.targA - m_toSceneAnimObject.currA;

    SCALE_DELTA(deltaA, danielNumer, danielDenom);
    m_toSceneAnimObject.currA += deltaA;

    deltaA = m_fromSceneAnimObject.targA - m_fromSceneAnimObject.currA;
    SCALE_DELTA(deltaA, danielNumer, danielDenom);
    m_fromSceneAnimObject.currA += deltaA;

    m_ipcBuffer->lock();

    m_dstContext->push();

    m_dstContext->setStrokeColor(PColor32(0x00, 0x00, 0x00, 0x00));
    m_dstContext->setFillColor(PColor32(0x00, 0x00, 0x00, 0xFF));
    m_dstContext->drawRect(0, 0, (int) m_fromSceneSurface->width(), (int) m_fromSceneSurface->height());

    m_dstContext->setFillOpacity(0xFF);

    m_dstContext->bitblt(m_toSceneSurface, 0, 0,
                         (int) m_toSceneSurface->width(),
                         (int) m_toSceneSurface->height());

    m_dstContext->setFillOpacity(m_fromSceneAnimObject.currA);

    m_dstContext->bitblt(m_fromSceneSurface, 0, 0,
                         (int) m_fromSceneSurface->width(),
                         (int) m_fromSceneSurface->height());


    m_dstContext->pop();

    m_ipcBuffer->unlock();

    return true;
}
bool WindowContentTransitionRunner::rotateTick()
{
    static const int danielNumer = 3;
    static const int danielDenom = 5;

    if (m_targRotateAngle == m_currRotateAngle) {

        return false;
    }

    int delta = m_targRotateAngle - m_currRotateAngle;
    SCALE_DELTA(delta, danielNumer, danielDenom);

    m_currRotateAngle += delta;

    // Painting --------------------------------------------------------------

    m_app->beginPaint();

    m_dstContext->push();

    // Fill with black
    m_dstContext->setStrokeColor(PColor32(0x00, 0x00, 0x00, 0x00));
    m_dstContext->setFillColor(PColor32(0x00, 0x00, 0x00, 0xFF));
    m_dstContext->drawRect(0, 0, (int) m_toSceneSurface->width(), (int) m_toSceneSurface->height());

    m_dstContext->translate((int) m_toSceneSurface->width()/2, (int) m_toSceneSurface->height()/2);
    m_dstContext->rotate(m_currRotateAngle);
    m_dstContext->translate(-(int) m_toSceneSurface->width()/2, -(int) m_toSceneSurface->height()/2);
    m_dstContext->bitblt(m_toSceneSurface, 0, 0,
                         (int) m_toSceneSurface->width(),
                         (int) m_toSceneSurface->height());

    m_dstContext->pop();

    m_app->endPaint();

    return true;
}
void BootupAnimation::renderInStateActivity()
{
	if (!m_activityStaticSurf || !m_activitySpinnerSurf || !m_activityProgressSurf)
		return;

	const HostInfo& info = HostBase::instance()->getInfo();

	int wStatic = (int) (m_activityStaticSurf->width());
	int hStatic = (int) (m_activityStaticSurf->height());
	int dxStatic = (info.displayWidth - wStatic) / 2;
	int dyStatic = (info.displayHeight - hStatic) / 2;

	int wSpinner = (int) (m_activitySpinnerSurf->width());
	int hSpinner = (int) (m_activitySpinnerSurf->height()) / s_activitySpinnerTotal;
	int dxSpinner = (info.displayWidth - wSpinner) / 2;
	int dySpinner = (info.displayHeight - hSpinner) / 2;

	m_ctxt->push();

	// Fill with black
	m_ctxt->setStrokeColor(PColor32(0x00, 0x00, 0x00, 0x00));
	m_ctxt->setFillColor(PColor32(0x00, 0x00, 0x00, 0xFF));
	m_ctxt->drawRect(0, 0, (int) info.displayWidth, (int) info.displayHeight);

	if (m_rotation != 0) {
		m_ctxt->translate((int)info.displayWidth/2, (int) info.displayHeight/2);
		m_ctxt->rotate(m_rotation);
		m_ctxt->translate((int) -info.displayWidth/2, (int) -info.displayHeight/2);
	}
	
	int progress = m_activityProgress;

	if (progress == 0) {
		m_ctxt->bitblt(m_activityStaticSurf, dxStatic, dyStatic,
					   dxStatic + wStatic, dyStatic + hStatic);
	}
	else {
		progress = progress - 1;
		m_ctxt->bitblt(m_activityProgressSurf,
					   0, progress * hStatic,
					   wStatic, hStatic + progress * hStatic,
					   dxStatic, dyStatic,
					   dxStatic + wStatic,
					   dyStatic + hStatic);
	}

	m_ctxt->bitblt(m_activitySpinnerSurf,
				   0, m_activitySpinner * hSpinner,
				   wSpinner, hSpinner + m_activitySpinner * hSpinner,
				   dxSpinner, dySpinner,
				   dxSpinner + wSpinner,
				   dySpinner + hSpinner);


	m_font->setPointSize(s_fontHeight1);
	m_ctxt->setFont(m_font);

	int xTextLine1 = (info.displayWidth - m_widthLine1) / 2;
	int xTextLine2 = (info.displayWidth - m_widthLine2) / 2;
	int yTextLine1 = (info.displayHeight - s_fontHeight1 * 2);
	int yTextLine2 = (info.displayHeight - s_fontHeight1);
	int xTextOffset = 0;
	int yTextOffset = 0;

	m_ctxt->setStrokeColor(PColor32(0xFF, 0xFF, 0xFF, 0xC0));
	m_ctxt->setFillColor(PColor32(0xFF, 0xFF, 0xFF, 0xC0));

	xTextOffset = xTextLine1;
	yTextOffset = yTextLine1;
	for (unsigned int i = 0; i < m_textLine1.size(); i++) {
		m_ctxt->drawCharacter(m_textLine1[i], xTextOffset, yTextOffset);
		xTextOffset += m_glyphOffsetsLine1[i];
	}

	m_font->setPointSize(s_fontHeight2);
	m_ctxt->setFont(m_font);

	m_ctxt->setStrokeColor(PColor32(0xFF, 0xFF, 0xFF, 0x80));
	m_ctxt->setFillColor(PColor32(0xFF, 0xFF, 0xFF, 0x80));

	xTextOffset = xTextLine2;
	yTextOffset = yTextLine2;
	for (unsigned int i = 0; i < m_textLine2.size(); i++) {
		m_ctxt->drawCharacter(m_textLine2[i], xTextOffset, yTextOffset);
		xTextOffset += m_glyphOffsetsLine2[i];
	}

	m_ctxt->pop();

	m_activitySpinner = (m_activitySpinner + 1) % s_activitySpinnerTotal;

	if (m_activityProgress == s_activityProgressTotal) {

		// Fill with black
		m_ctxt->push();
		m_ctxt->setStrokeColor(PColor32(0x00, 0x00, 0x00, 0x00));
		m_ctxt->setFillColor(PColor32(0x00, 0x00, 0x00, 0xFF));
		m_ctxt->drawRect(0, 0, (int) info.displayWidth, (int) info.displayHeight);
		m_ctxt->pop();

		m_logoScale = 1.0f;
		m_logoAlpha = 0xFF;
		m_state = StateLogo;
	}

	m_ctxt->flip();
}
void BootupAnimation::init()
{
	s_frameTime = s_frameTimeSlow;

	HostBase* host = HostBase::instance();
	const HostInfo& info = host->getInfo();

	m_ctxt = PGContext::create();
	m_ctxt->setDisplay(PPrimary, 0, PFORMAT_8888, 3);
	
	// Fill with black
	m_ctxt->push();
	m_ctxt->setStrokeColor(PColor32(0x00, 0x00, 0x00, 0x00));
	m_ctxt->setFillColor(PColor32(0x00, 0x00, 0x00, 0xFF));
	m_ctxt->drawRect(0, 0, (int) info.displayWidth, (int) info.displayHeight);
	m_ctxt->pop();

	std::string imageRootPath = Settings::LunaSettings()->lunaSystemResourcesPath + "/";
	std::string imagePath;

	imagePath = imageRootPath + "hp-logo.png";
	m_logoSurf = PGSurface::createFromPNGFile(imagePath.c_str());
	if (!m_logoSurf)
		g_warning("Failed to load image: %s", imagePath.c_str());

	imagePath = imageRootPath + "hp-logo-bright.png";
	m_logoBrightSurf = PGSurface::createFromPNGFile(imagePath.c_str());
	if (!m_logoBrightSurf)
		g_warning("Failed to load image: %s", imagePath.c_str());

	imagePath = imageRootPath + "activity-static.png";
	m_activityStaticSurf = PGSurface::createFromPNGFile(imagePath.c_str());
	if (!m_activityStaticSurf)
		g_warning("Failed to load image: %s", imagePath.c_str());
	
	imagePath = imageRootPath + "activity-spinner.png";
	m_activitySpinnerSurf = PGSurface::createFromPNGFile(imagePath.c_str());
	if (!m_activitySpinnerSurf)
		g_warning("Failed to load image: %s", imagePath.c_str());

	imagePath = imageRootPath + "activity-progress.png";
	m_activityProgressSurf = PGSurface::createFromPNGFile(imagePath.c_str());
	if (!m_activityProgressSurf)
		g_warning("Failed to load image: %s", imagePath.c_str());

	const char* fontName = Settings::LunaSettings()->fontBootupAnimation.c_str();
	m_font = PGFont::createFromFile(fontName, s_fontHeight1);
	if (!m_font) {
		g_critical("%s: Failed to load font: %s", __PRETTY_FUNCTION__, fontName);
	}

	m_fallbackFonts = new PGFallbackFonts();

	generateUtf16AndGlyphOffsets();

	m_logoScale = 1.0f;
	m_logoAlpha = 0xFF;

	m_activityProgress = 0;
	m_activitySpinner = 0;

	switch (Settings::LunaSettings()->homeButtonOrientationAngle) {
	case 90:
		m_rotation = -90;
		break;
	case -90:
	case 270:
		m_rotation = 90;
		break;
	case 180:
		m_rotation = 180;
		break;
	default:
		m_rotation = 0;
	}
}
bool WindowContentTransitionRunner::zoomAndCrossFadeTick()
{
    static const int danielNumer = 3;
    static const int danielDenom = 5;

    if (m_toSceneAnimObject.currX == m_toSceneAnimObject.targX &&
            m_toSceneAnimObject.currY == m_toSceneAnimObject.targY &&
            m_toSceneAnimObject.currR == m_toSceneAnimObject.targR &&
            m_toSceneAnimObject.currB == m_toSceneAnimObject.targB &&
            m_toSceneAnimObject.currA == m_toSceneAnimObject.targA) {

        return false;
    }

    int deltaX = m_toSceneAnimObject.targX - m_toSceneAnimObject.currX;
    int deltaY = m_toSceneAnimObject.targY - m_toSceneAnimObject.currY;
    int deltaR = m_toSceneAnimObject.targR - m_toSceneAnimObject.currR;
    int deltaH = m_toSceneAnimObject.targB - m_toSceneAnimObject.currB;
    int deltaA = m_toSceneAnimObject.targA - m_toSceneAnimObject.currA;

    SCALE_DELTA(deltaX, danielNumer, danielDenom);
    SCALE_DELTA(deltaY, danielNumer, danielDenom);
    SCALE_DELTA(deltaR, danielNumer, danielDenom);
    SCALE_DELTA(deltaH, danielNumer, danielDenom);
    SCALE_DELTA(deltaA, danielNumer, danielDenom);


    m_toSceneAnimObject.currX += deltaX;
    m_toSceneAnimObject.currY += deltaY;
    m_toSceneAnimObject.currR += deltaR;
    m_toSceneAnimObject.currB += deltaH;
    m_toSceneAnimObject.currA += deltaA;

    deltaX = m_fromSceneAnimObject.targX - m_fromSceneAnimObject.currX;
    deltaY = m_fromSceneAnimObject.targY - m_fromSceneAnimObject.currY;
    deltaR = m_fromSceneAnimObject.targR - m_fromSceneAnimObject.currR;
    deltaH = m_fromSceneAnimObject.targB - m_fromSceneAnimObject.currB;
    deltaA = m_fromSceneAnimObject.targA - m_fromSceneAnimObject.currA;

    SCALE_DELTA(deltaX, danielNumer, danielDenom);
    SCALE_DELTA(deltaY, danielNumer, danielDenom);
    SCALE_DELTA(deltaR, danielNumer, danielDenom);
    SCALE_DELTA(deltaH, danielNumer, danielDenom);
    SCALE_DELTA(deltaA, danielNumer, danielDenom);


    m_fromSceneAnimObject.currX += deltaX;
    m_fromSceneAnimObject.currY += deltaY;
    m_fromSceneAnimObject.currR += deltaR;
    m_fromSceneAnimObject.currB += deltaH;
    m_fromSceneAnimObject.currA += deltaA;

    m_ipcBuffer->lock();

    m_dstContext->push();

    m_dstContext->setStrokeColor(PColor32(0x00, 0x00, 0x00, 0x00));
    m_dstContext->setFillColor(PColor32(0x00, 0x00, 0x00, 0xFF));
    m_dstContext->drawRect(0, 0, (int) m_fromSceneSurface->width(), (int) m_fromSceneSurface->height());

    if (m_transitionIsPop) {

        m_dstContext->setFillOpacity(m_fromSceneAnimObject.currA);

        m_dstContext->bitblt(m_fromSceneSurface, m_fromSceneAnimObject.currX, m_fromSceneAnimObject.currY,
                             m_fromSceneAnimObject.currR, m_fromSceneAnimObject.currB);

        m_dstContext->setFillOpacity(m_toSceneAnimObject.currA);

        m_dstContext->bitblt(m_toSceneSurface, m_toSceneAnimObject.currX, m_toSceneAnimObject.currY,
                             m_toSceneAnimObject.currR, m_toSceneAnimObject.currB);
    }
    else {

        m_dstContext->setFillOpacity(m_toSceneAnimObject.currA);

        m_dstContext->bitblt(m_toSceneSurface, m_toSceneAnimObject.currX, m_toSceneAnimObject.currY,
                             m_toSceneAnimObject.currR, m_toSceneAnimObject.currB);

        m_dstContext->setFillOpacity(m_fromSceneAnimObject.currA);

        m_dstContext->bitblt(m_fromSceneSurface, m_fromSceneAnimObject.currX, m_fromSceneAnimObject.currY,
                             m_fromSceneAnimObject.currR, m_fromSceneAnimObject.currB);
    }


    m_dstContext->pop();

    m_ipcBuffer->unlock();

    return true;
}