Beispiel #1
0
void MusicEffect::Render(Effect *effect, const SettingsMap &SettingsMap, RenderBuffer &buffer) {
	Render(buffer,
           SettingsMap.GetInt("TEXTCTRL_Music_Bars", 6),
		   SettingsMap.Get("CHOICE_Music_Type", "Collide"),
		   SettingsMap.GetInt("TEXTCTRL_Music_Sensitivity", 50),
		   SettingsMap.GetBool("CHECKBOX_Music_Scale", false),
 		   std::string(SettingsMap.Get("CHOICE_Music_Scaling", "All Notes")),
           SettingsMap.GetInt("TEXTCTRL_Music_Offset", 0),
           SettingsMap.GetInt("TEXTCTRL_Music_StartNote", 0),
           SettingsMap.GetInt("TEXTCTRL_Music_EndNote", 127),   
           SettingsMap.Get("CHOICE_Music_Colour", "Distinct"),
           SettingsMap.GetBool("CHECKBOX_Music_Fade", false)
        );
}
Beispiel #2
0
void VideoEffect::Render(Effect *effect, const SettingsMap &SettingsMap, RenderBuffer &buffer) {
    Render(buffer,
		   SettingsMap["FILEPICKERCTRL_Video_Filename"],
		SettingsMap.GetDouble("TEXTCTRL_Video_Starttime", 0.0),
		SettingsMap.GetBool("CHECKBOX_Video_AspectRatio", false),
		SettingsMap.Get("CHOICE_Video_DurationTreatment", "Normal")
		);
}
Beispiel #3
0
void StateEffect::Render(Effect *effect, const SettingsMap &SettingsMap, RenderBuffer &buffer) {
    RenderState(buffer,
                effect->GetParentEffectLayer()->GetParentElement()->GetSequenceElements(),
                SettingsMap.Get("CHOICE_State_StateDefinition", ""),
                SettingsMap["CHOICE_State_State"],
                SettingsMap["CHOICE_State_TimingTrack"],
                SettingsMap["CHOICE_State_Mode"],
                SettingsMap["CHOICE_State_Color"]
    );
}
Beispiel #4
0
void PixelBufferClass::SetLayerSettings(int layer, const SettingsMap &settingsMap) {
    LayerInfo *inf = layers[layer];
    inf->persistent = settingsMap.GetBool(CHECKBOX_OverlayBkg);
    inf->mask.clear();

    inf->fadeInSteps = (int)(settingsMap.GetDouble(TEXTCTRL_Fadein, 0.0)*1000)/frameTimeInMs;
    inf->fadeOutSteps = (int)(settingsMap.GetDouble(TEXTCTRL_Fadeout, 0.0)*1000)/frameTimeInMs;

    inf->inTransitionType = settingsMap.Get(CHOICE_In_Transition_Type, STR_FADE);
    inf->outTransitionType = settingsMap.Get(CHOICE_Out_Transition_Type, STR_FADE);
    inf->inTransitionAdjust = settingsMap.GetInt(SLIDER_In_Transition_Adjust, 0);
    inf->outTransitionAdjust = settingsMap.GetInt(SLIDER_Out_Transition_Adjust, 0);
    inf->inTransitionReverse = settingsMap.GetBool(CHECKBOX_In_Transition_Reverse);
    inf->outTransitionReverse = settingsMap.GetBool(CHECKBOX_Out_Transition_Reverse);

    inf->blur = settingsMap.GetInt(SLIDER_EffectBlur, 1);
    inf->sparkle_count = settingsMap.GetInt(SLIDER_SparkleFrequency, 0);

    inf->RotoZoom = settingsMap.GetInt(CHECKBOX_RotoZoom, 0) ;
    inf->ZoomCycles = settingsMap.GetInt(SLIDER_ZoomCycles, 1);
    inf->ZoomRotation = settingsMap.GetInt(SLIDER_ZoomRotation, 0);
    inf->ZoomInOut = settingsMap.GetInt(SLIDER_ZoomInOut, 0);

    inf->brightness = settingsMap.GetInt(SLIDER_Brightness, 100);
    inf->contrast=settingsMap.GetInt(SLIDER_Contrast, 0);

    SetMixType(layer, settingsMap.Get(CHOICE_LayerMethod, STR_NORMAL));

    inf->effectMixThreshold = (float)settingsMap.GetInt(SLIDER_EffectLayerMix, 0)/100.0;
    inf->effectMixVaries = settingsMap.GetBool(CHECKBOX_LayerMorph);


    const std::string &type = settingsMap.Get(CHOICE_BufferStyle, STR_DEFAULT);
    const std::string &transform = settingsMap.Get(CHOICE_BufferTransform, STR_NONE);
    if (inf->bufferType != type || inf->bufferTransform != transform)
    {
        inf->Nodes.clear();
        model->InitRenderBufferNodes(type, transform, inf->Nodes, inf->BufferWi, inf->BufferHt);
        inf->bufferType = type;
        inf->bufferTransform = transform;
        inf->buffer.InitBuffer(inf->BufferHt, inf->BufferWi);
    }
}
Beispiel #5
0
std::list<std::string> StateEffect::CheckEffectSettings(const SettingsMap& settings, AudioManager* media, Model* model, Effect* eff)
{
    std::list<std::string> res;

    // -Buffer not rotated
    wxString bufferTransform = settings.Get("B_CHOICE_BufferTransform", "None");

    if (bufferTransform != "None")
    {
        res.push_back(wxString::Format("    WARN: State effect with transformed buffer '%s' may not render correctly. Model '%s', Start %s", model->GetName(), bufferTransform, FORMATTIME(eff->GetStartTimeMS())).ToStdString());
    }

    wxString timing = settings.Get("E_CHOICE_State_TimingTrack", "");
    wxString state = settings.Get("E_CHOICE_State_State", "");

    // - Face chosen or specific phoneme
    if (state == "" && timing == "")
    {
        res.push_back(wxString::Format("    ERR: State effect with no timing selected. Model '%s', Start %s", model->GetName(), FORMATTIME(eff->GetStartTimeMS())).ToStdString());
    }

    return res;
}
Beispiel #6
0
double RenderableEffect::GetValueCurveDouble(wxString name, double def, const SettingsMap &SettingsMap, float offset)
{
    double res = SettingsMap.GetDouble("TEXTCTRL_" + name, def);

    wxString vc = SettingsMap.Get("VALUECURVE_" + name, "");
    if (vc != "")
    {
        ValueCurve valc(vc.ToStdString());
        if (valc.IsActive())
        {
            res = valc.GetOutputValueAt(offset);
        }
    }

    return res;
}
Beispiel #7
0
int RenderableEffect::GetValueCurveInt(wxString name, int def, const SettingsMap &SettingsMap, float offset)
{
    int res = def;
    if (SettingsMap.Contains("SLIDER_" + name))
    {
        res = SettingsMap.GetInt("SLIDER_" + name, def);
    }
    else if (SettingsMap.Contains("TEXTCTRL_" + name))
    {
        res = SettingsMap.GetInt("TEXTCTRL_" + name, def);
    }

    if (SettingsMap.Contains("VALUECURVE_" + name))
    {
        wxString vc = SettingsMap.Get("VALUECURVE_" + name, "");
        ValueCurve valc(vc.ToStdString());
        if (valc.IsActive())
        {
            res = valc.GetOutputValueAt(offset);
        }
    }

    return res;
}
Beispiel #8
0
std::list<std::string> MorphEffect::CheckEffectSettings(const SettingsMap& settings, AudioManager* media, Model* model, Effect* eff)
{
    std::list<std::string> res;

    if (settings.Get("E_VALUECURVE_Morph_Start_X1", "").find("Active=TRUE") != std::string::npos ||
        settings.Get("E_VALUECURVE_Morph_Start_X2", "").find("Active=TRUE") != std::string::npos ||
        settings.Get("E_VALUECURVE_Morph_Start_Y1", "").find("Active=TRUE") != std::string::npos ||
        settings.Get("E_VALUECURVE_Morph_Start_Y2", "").find("Active=TRUE") != std::string::npos ||
        settings.Get("E_VALUECURVE_Morph_End_X1", "").find("Active=TRUE") != std::string::npos ||
        settings.Get("E_VALUECURVE_Morph_End_X2", "").find("Active=TRUE") != std::string::npos ||
        settings.Get("E_VALUECURVE_Morph_End_Y1", "").find("Active=TRUE") != std::string::npos ||
        settings.Get("E_VALUECURVE_Morph_End_Y2", "").find("Active=TRUE") != std::string::npos ||
        settings.Get("E_VALUECURVE_MorphRepeat_Count", "").find("Active=TRUE") != std::string::npos ||
        settings.Get("E_VALUECURVE_MorphRepeat_Skip", "").find("Active=TRUE") != std::string::npos
        )
    {
        // we cant validate a value curve
    }
    else
    {
        int startx = std::max(1,std::abs(settings.GetInt("E_SLIDER_Morph_Start_X1", 0) - settings.GetInt("E_SLIDER_Morph_Start_X2", 0)) * model->GetDefaultBufferWi() / 80);
        int endx = std::max(1, std::abs(settings.GetInt("E_SLIDER_Morph_End_X1", 0) - settings.GetInt("E_SLIDER_Morph_End_X2", 0)) * model->GetDefaultBufferWi() / 80);
        int starty = std::max(1, std::abs(settings.GetInt("E_SLIDER_Morph_Start_Y1", 0) - settings.GetInt("E_SLIDER_Morph_Start_Y2", 0)) * model->GetDefaultBufferWi() / 80);
        int endy = std::max(1, std::abs(settings.GetInt("E_SLIDER_Morph_End_Y1", 0) - settings.GetInt("E_SLIDER_Morph_End_Y2", 0)) * model->GetDefaultBufferWi() / 80);

        int minmorph = std::min(startx, std::min(starty, std::min(endx, endy)));
        int repeat_count = settings.GetInt("E_SLIDER_Morph_Repeat_Count", 0);
        int repeat_skip = settings.GetInt("E_SLIDER_Morph_Repeat_Skip", 0);
        int maxmodel = std::max(model->GetDefaultBufferWi(), model->GetDefaultBufferHt());

        if ((minmorph + repeat_skip) * repeat_count > 2 * maxmodel)
        {
            res.push_back(wxString::Format("    WARN: Morph effect with repeat count and skip which are larger than necessary. This may lead to slow render times. Model '%s', Start %s", model->GetName(), FORMATTIME(eff->GetStartTimeMS())).ToStdString());
        }
    }

    return res;
}
Beispiel #9
0
void GarlandsEffect::Render(Effect *effect, const SettingsMap &SettingsMap, RenderBuffer &buffer) {
    int GarlandType = SettingsMap.GetInt("SLIDER_Garlands_Type", 0);
    int Spacing = SettingsMap.GetInt("SLIDER_Garlands_Spacing", 0);
    float cycles = SettingsMap.GetDouble("TEXTCTRL_Garlands_Cycles", 1.0);

    if (Spacing < 1) {
        Spacing = 1;
    }
    int x,y,yadj,ylimit,ring;
    double ratio;
    xlColor color;
    int dir = GetDirection(SettingsMap.Get("CHOICE_Garlands_Direction", "Up"));
    double position = buffer.GetEffectTimeIntervalPosition(cycles);
    if (dir > 3) {
        dir -= 4;
        if (position > 0.5) {
            position = (1.0 - position) * 2.0;
        } else {
            position *= 2.0;
        }
    }
    int buffMax = buffer.BufferHt;
    int garlandWid = buffer.BufferWi;
    if (dir > 1) {
        buffMax = buffer.BufferWi;
        garlandWid = buffer.BufferHt;
    }
    double PixelSpacing=Spacing*buffMax/100.0;
    if (PixelSpacing < 2.0) PixelSpacing=2.0;


    double total = buffMax * PixelSpacing - buffMax + 1;
    double positionOffset = total * position;

    for (ring = 0; ring < buffMax; ring++)
    {
        ratio=double(buffMax-ring-1)/double(buffMax);
        buffer.GetMultiColorBlend(ratio, false, color);

        y = 1.0 + ring*PixelSpacing - positionOffset;


        ylimit=ring;
        for (x=0; x<garlandWid; x++)
        {
            yadj=y;
            switch (GarlandType)
            {
            case 1:
                switch (x%5)
                {
                case 2:
                    yadj-=2;
                    break;
                case 1:
                case 3:
                    yadj-=1;
                    break;
                }
                break;
            case 2:
                switch (x%5)
                {
                case 2:
                    yadj-=4;
                    break;
                case 1:
                case 3:
                    yadj-=2;
                    break;
                }
                break;
            case 3:
                switch (x%6)
                {
                case 3:
                    yadj-=6;
                    break;
                case 2:
                case 4:
                    yadj-=4;
                    break;
                case 1:
                case 5:
                    yadj-=2;
                    break;
                }
                break;
            case 4:
                switch (x%5)
                {
                case 1:
                case 3:
                    yadj-=2;
                    break;
                }
                break;
            }
            if (yadj < ylimit) yadj=ylimit;
            if (yadj < buffMax) {
                if (dir == 1 || dir == 2) {
                    yadj = buffMax - yadj - 1;
                }
                if (dir > 1) {
                    buffer.SetPixel(yadj,x,color);
                } else {
                    buffer.SetPixel(x,yadj,color);
                }
            }
        }
    }
}
Beispiel #10
0
void RenderableEffect::AdjustSettingsToBeFitToTime(int effectIdx, SettingsMap &settings, int startMS, int endMS, xlColorVector &colors)
{
    if (effectIdx == EffectManager::eff_FACES
        && settings.Get("E_CHOICE_Faces_FaceDefinition", "") == ""
        && settings.Get("E_CHOICE_Faces_TimingTrack", "") == "")
    {
        settings["E_CHOICE_Faces_FaceDefinition"] = "xlights_papagayo.xml";
    }

    int ftt = wxAtoi(settings.Get("T_CHECKBOX_FitToTime", "1"));
    switch (effectIdx)
    {
            //these effects have never used the FitToTime or speed settings, nothing to do
        case EffectManager::eff_OFF:
        case EffectManager::eff_GALAXY:
        case EffectManager::eff_FAN:
        case EffectManager::eff_MARQUEE:
        case EffectManager::eff_MORPH:
        case EffectManager::eff_SHOCKWAVE:
        case EffectManager::eff_GLEDIATOR:
        case EffectManager::eff_FACES:
            break;
        case EffectManager::eff_STROBE:
        case EffectManager::eff_TWINKLE:
            break;
            //these effects have been updated to have a dedicated repeat or speed or other control
            //and now ignore the FitToTime and Speed sliders, but the settings need adjusting
        case EffectManager::eff_ON:
            if (settings.Get("E_TEXTCTRL_On_Cycles", "") == "")
            {
                float cycles = 1.0;
                if (!ftt)
                {
                    int speed = wxAtoi(settings.Get("T_SLIDER_Speed", "10"));
                    int totalTime = endMS - startMS;
                    int maxState = totalTime * speed / 50;
                    cycles = maxState / 200;
                }
                settings["E_TEXTCTRL_On_Cycles"] = wxString::Format("%0.2f", cycles);
            }
            break;
        case EffectManager::eff_SNOWSTORM:
            if (settings.Get("E_SLIDER_Snowstorm_Speed", "") == "")
            {
                settings["E_SLIDER_Snowstorm_Speed"] = settings.Get("T_SLIDER_Speed", "10");
            }
            break;
        case EffectManager::eff_SNOWFLAKES:
            if (settings.Get("E_SLIDER_Snowflakes_Speed", "") == "")
            {
                settings["E_SLIDER_Snowflakes_Speed"] = settings.Get("T_SLIDER_Speed", "10");
            }
            break;
        case EffectManager::eff_BUTTERFLY:
            if (settings.Get("E_SLIDER_Butterfly_Speed", "") == "")
            {
                settings["E_SLIDER_Butterfly_Speed"] = settings.Get("T_SLIDER_Speed", "10");
            }
            break;
        case EffectManager::eff_CIRCLES:
            if (settings.Get("E_SLIDER_Circles_Speed", "") == "")
            {
                settings["E_SLIDER_Circles_Speed"] = settings.Get("T_SLIDER_Speed", "10");
            }
            break;
        case EffectManager::eff_LIFE:
            if (settings.Get("E_SLIDER_Life_Speed", "") == "")
            {
                settings["E_SLIDER_Life_Speed"] = settings.Get("T_SLIDER_Speed", "10");
            }
            break;
        case EffectManager::eff_METEORS:
            if (settings.Get("E_SLIDER_Meteors_Speed", "") == "")
            {
                settings["E_SLIDER_Meteors_Speed"] = settings.Get("T_SLIDER_Speed", "10");
            }
            break;
        case EffectManager::eff_TREE:
            if (settings.Get("E_SLIDER_Tree_Speed", "") == "")
            {
                settings["E_SLIDER_Tree_Speed"] = settings.Get("T_SLIDER_Speed", "10");
            }
            break;
        case EffectManager::eff_PINWHEEL:
            if (settings.Get("E_TEXTCTRL_Pinwheel_Speed", "") == "")
            {
                settings["E_TEXTCTRL_Pinwheel_Speed"] = settings.Get("T_SLIDER_Speed", "10");
            }
            break;
        case EffectManager::eff_PLASMA:
            if (settings.Get("E_TEXTCTRL_Plasma_Speed", "") == "")
            {
                settings["E_TEXTCTRL_Plasma_Speed"] = settings.Get("T_SLIDER_Speed", "10");
            }
            break;
        case EffectManager::eff_TEXT:
            if (settings.Get("E_TEXTCTRL_Text_Speed1", "") == "")
            {
                settings["E_TEXTCTRL_Text_Speed1"] = settings.Get("T_SLIDER_Speed", "10");
            }
            if (settings.Get("E_TEXTCTRL_Text_Speed2", "") == "")
            {
                settings["E_TEXTCTRL_Text_Speed2"] = settings.Get("T_SLIDER_Speed", "10");
            }
            if (settings.Get("E_TEXTCTRL_Text_Speed3", "") == "")
            {
                settings["E_TEXTCTRL_Text_Speed3"] = settings.Get("T_SLIDER_Speed", "10");
            }
            if (settings.Get("E_TEXTCTRL_Text_Speed4", "") == "")
            {
                settings["E_TEXTCTRL_Text_Speed4"] = settings.Get("T_SLIDER_Speed", "10");
            }

            if (settings.Get("E_SLIDER_Text_Position1", "") != "") {
                int pos = wxAtoi(settings.Get("E_SLIDER_Text_Position1", "50")) * 2 - 100;
                settings.erase("E_SLIDER_Text_Position1");
                settings["E_SLIDER_Text_YStart1"] = wxString::Format("%d", pos);
                settings["E_SLIDER_Text_XStart1"] = wxString::Format("%d", pos);
                settings["E_SLIDER_Text_XEnd1"] = wxString::Format("%d", pos);
                settings["E_SLIDER_Text_YEnd1"] = wxString::Format("%d", pos);
            }
            break;
        case EffectManager::eff_WAVE:
            if (settings.Get("E_TEXTCTRL_Wave_Speed", "") == "")
            {
                settings["E_TEXTCTRL_Wave_Speed"] = settings.Get("T_SLIDER_Speed", "10");
            }
            break;
        case EffectManager::eff_SPIROGRAPH:
            if (settings.Get("E_TEXTCTRL_Spirograph_Speed", "") == "")
            {
                settings["E_TEXTCTRL_Spirograph_Speed"] = settings.Get("T_SLIDER_Speed", "10");
            }
            if (settings.Get("E_CHECKBOX_Spirograph_Animate", "") != "")
            {
                int i = wxAtoi(settings.Get("E_CHECKBOX_Spirograph_Animate", "0"));
                settings["E_TEXTCTRL_Spirograph_Animate"] = (i == 0 ? "0" : "10");
                settings.erase("E_CHECKBOX_Spirograph_Animate");
            }
            break;

        case EffectManager::eff_COLORWASH:
            if (settings.Get("E_TEXTCTRL_ColorWash_Cycles", "") == "")
            {
                double count = wxAtoi(settings.Get("E_SLIDER_ColorWash_Count", "1"));
                settings.erase("E_SLIDER_ColorWash_Count");
                if (settings["T_CHECKBOX_FitToTime"] == "1")
                {
                    count = 1.0;
                    settings["E_CHECKBOX_ColorWash_CircularPalette"] = "0";
                }
                else
                {
                    settings["E_CHECKBOX_ColorWash_CircularPalette"] = "1";
                }
                settings["E_TEXTCTRL_ColorWash_Cycles"] = wxString::Format("%0.2f", count);
            }
            break;
        case EffectManager::eff_FIRE:
            if (settings.Get("E_TEXTCTRL_Fire_GrowthCycles", "") == "")
            {
                bool grow = settings["E_CHECKBOX_Fire_GrowFire"] == "1";
                settings.erase("E_CHECKBOX_Fire_GrowFire");
                if (grow)
                {
                    int speed = wxAtoi(settings.Get("T_SLIDER_Speed", "10"));
                    int totalTime = endMS - startMS;
                    double maxState = totalTime * speed / 50;
                    double cycles = maxState / 500.0;
                    settings["E_TEXTCTRL_Fire_GrowthCycles"] = wxString::Format("%0.2f", cycles);
                }
                else
                {
                    settings["E_TEXTCTRL_Fire_GrowthCycles"] = "0.0";
                }
            }
            break;
        case EffectManager::eff_FIREWORKS:
            if (settings.Get("E_SLIDER_Fireworks_Number_Explosions", "") != "")
            {
                int cnt = wxAtoi(settings.Get("E_SLIDER_Fireworks_Number_Explosions", "10"));
                settings.erase("E_SLIDER_Fireworks_Number_Explosions");
                int speed = wxAtoi(settings.Get("T_SLIDER_Speed", "10"));
                int total = (speed * cnt) / 50;
                if (total > 50)
                {
                    total = 50;
                }
                if (total < 1)
                {
                    total = 1;
                }
                settings["E_SLIDER_Fireworks_Explosions"] = wxString::Format("%d", total);
            }
            break;
        case EffectManager::eff_RIPPLE:
            if (settings.Get("E_TEXTCTRL_Ripple_Cycles", "") == "")
            {
                float cycles = 1.0;
                if (!ftt)
                {
                    int speed = wxAtoi(settings.Get("T_SLIDER_Speed", "10"));
                    int totalTime = endMS - startMS;
                    int maxState = totalTime * speed / 50;
                    cycles = maxState / 200;
                }
                settings["E_TEXTCTRL_Ripple_Cycles"] = wxString::Format("%0.2f", cycles);
            }
            break;
        case EffectManager::eff_BARS:
            if (settings.Get("E_TEXTCTRL_Bars_Cycles", "") == "")
            {
                float cycles = 1.0;
                wxString dir = settings["E_CHOICE_Bars_Direction"];
                if (!ftt)
                {
                    int speed = wxAtoi(settings.Get("T_SLIDER_Speed", "10"));
                    int totalTime = endMS - startMS;
                    int maxState = totalTime * speed / 50;
                    if (dir.Contains("Altern"))
                    {
                        cycles = maxState * 2;
                    }
                    else
                    {
                        cycles = maxState / 200;
                    }
                }
                settings["E_TEXTCTRL_Bars_Cycles"] = wxString::Format("%0.2f", cycles);
            }
            break;
        case EffectManager::eff_SPIRALS:
            if (settings.Get("E_TEXTCTRL_Spirals_Movement", "") == "")
            {
                float cycles = 1.0;
                int dir = wxAtoi(settings.Get("E_SLIDER_Spirals_Direction", "1"));
                settings.erase("E_SLIDER_Spirals_Direction");
                if (!ftt)
                {
                    int speed = wxAtoi(settings.Get("T_SLIDER_Speed", "10"));
                    int totalTime = endMS - startMS;
                    int maxState = totalTime * speed / 50;
                    cycles = maxState / 600;
                }
                settings["E_TEXTCTRL_Spirals_Movement"] = wxString::Format("%0.2f", dir * cycles);
            }
            break;
        case EffectManager::eff_CURTAIN:
            if (settings.Get("E_TEXTCTRL_Curtain_Speed", "") == "")
            {
                float cycles = 1.0;
                if (!ftt)
                {
                    int speed = wxAtoi(settings.Get("T_SLIDER_Speed", "10"));
                    int totalTime = endMS - startMS;
                    int maxState = totalTime * speed / 50;
                    cycles = maxState / 200;
                }
                settings["E_TEXTCTRL_Curtain_Speed"] = wxString::Format("%0.2f", cycles);
            }
            break;
        case EffectManager::eff_SINGLESTRAND:
            if ("Skips" == settings["E_NOTEBOOK_SSEFFECT_TYPE"])
            {
                if (settings.Get("E_SLIDER_Skips_Advance", "") == "")
                {
                    int speed = wxAtoi(settings.Get("T_SLIDER_Speed", "10"));
                    settings["E_SLIDER_Skips_Advance"] = wxString::Format("%d", speed - 1);
                }
            }
            else
            {
                wxString type = settings.Get("E_CHOICE_Chase_Type1", "Left-Right");
                if (type == "Auto reverse")
                {
                    type = "Bounce from Left";
                    settings["E_CHOICE_Chase_Type1"] = type;
                }
                else if (type == "Bounce" || type == "Pacman")
                {
                    type = "Dual Bounce";
                    settings["E_CHOICE_Chase_Type1"] = type;
                }
                if (settings.Get("E_TEXTCTRL_Chase_Rotations", "") == "")
                {
                    float cycles = 1.0;
                    if (!ftt)
                    {
                        int speed = wxAtoi(settings.Get("T_SLIDER_Speed", "10"));
                        int totalTime = endMS - startMS;
                        int maxState = totalTime * speed / 50;
                        cycles = maxState / 250.0;
                    }
                    settings["E_TEXTCTRL_Chase_Rotations"] = wxString::Format("%0.2f", cycles);
                }
            }
            break;
        case EffectManager::eff_SHIMMER:
            if (settings.Get("E_TEXTCTRL_Shimmer_Cycles", "") == "")
            {
                float cycles = 1.0;
                int speed = wxAtoi(settings.Get("T_SLIDER_Speed", "10"));
                int totalTime = endMS - startMS;
                int maxState = totalTime * speed / 50;
                cycles = maxState / (100.0 * colors.size());
                settings["E_TEXTCTRL_Shimmer_Cycles"] = wxString::Format("%0.2f", cycles);
            }
            break;
        case EffectManager::eff_PICTURES:
            if (settings.Get("E_TEXTCTRL_Pictures_FrameRateAdj", "") == "")
            {
                if (settings.Get("E_CHECKBOX_MovieIs20FPS", "") == "1")
                {
                    settings["E_TEXTCTRL_Pictures_FrameRateAdj"] = "1.0";
                }
                else if (settings.Get("E_SLIDER_Pictures_GifSpeed", "") == "0")
                {
                    settings["E_TEXTCTRL_Pictures_FrameRateAdj"] = "0.0";
                }
                else if (!ftt)
                {
                    int speed = wxAtoi(settings.Get("T_SLIDER_Speed", "10"));
                    int totalTime = endMS - startMS;
                    int maxState = totalTime * speed / 50;
                    double cycles = maxState / 300.0;
                    settings["E_TEXTCTRL_Pictures_Speed"] = wxString::Format("%0.2f", cycles);
                }

                settings.erase("E_CHECKBOX_MovieIs20FPS");
                settings.erase("E_SLIDER_Pictures_GifSpeed");
            }
            break;
        case EffectManager::eff_GARLANDS:
            //Don't attempt to map the Garlands speed settings.  In v3, the Garland speed depended on the Speed setting, the
            //Spacing setting as well as the height of the model.  We don't have the height of the model here so really
            //no way to figure out the speed or an appropriate mapping
            break;

            //these all need code updated and new sliders and such before we can map them
            //these all have state/speed requirements
        case EffectManager::eff_PIANO:
            break;
    }
    settings.erase("T_CHECKBOX_FitToTime");
    settings.erase("T_SLIDER_Speed");
}
Beispiel #11
0
void SnowflakesEffect::Render(Effect *effect, const SettingsMap &SettingsMap, RenderBuffer &buffer) {

    int Count = SettingsMap.GetInt("SLIDER_Snowflakes_Count", 5);
    int SnowflakeType = SettingsMap.GetInt("SLIDER_Snowflakes_Type", 1);
    int sSpeed = SettingsMap.GetInt("SLIDER_Snowflakes_Speed", 10);
    std::string falling = SettingsMap.Get("CHOICE_Falling", "Driving");

    int i,n,x,x0,y0,y,check,delta_y;
    xlColor color1,color2, color3;
    bool wrapx = false; // set to true if you want snowflakes to draw wrapped around when near edges in the accumulate effect.


    SnowflakesRenderCache *cache = (SnowflakesRenderCache*)buffer.infoCache[id];
    if (cache == nullptr) {
        cache = new SnowflakesRenderCache();
        buffer.infoCache[id] = cache;
    }

    int &LastSnowflakeCount = cache->LastSnowflakeCount;
    int &LastSnowflakeType = cache->LastSnowflakeType;
    int &effectState = cache->effectState;
    std::string& LastFalling = cache->LastFalling;

    buffer.palette.GetColor(0, color1);
    buffer.palette.GetColor(1, color2);

    if (buffer.needToInit ||
        Count != LastSnowflakeCount ||
        SnowflakeType != LastSnowflakeType ||
        falling != LastFalling) {

        // initialize
        buffer.needToInit = false;
        LastSnowflakeCount=Count;
        LastSnowflakeType=SnowflakeType;
        LastFalling = falling;
        buffer.ClearTempBuf();
        effectState = 0;

        // place Count snowflakes
        for (n=0; n < Count; n++) {

            delta_y=buffer.BufferHt/4;
            y0=(n % 4)*delta_y;

            if (y0+delta_y > buffer.BufferHt) delta_y = buffer.BufferHt-y0;
            if (delta_y<1) delta_y=1;

            // find unused space
            for (check=0; check < 20; check++)
            {
                x=rand() % buffer.BufferWi;
                y=y0 + (rand() % delta_y);
                if (buffer.GetTempPixel(x,y) == xlBLACK) {
                    effectState++;
                    break;
                }
            }

            // draw flake, SnowflakeType=0 is random type
            switch (SnowflakeType == 0 ? rand() % 5 : SnowflakeType-1)
            {
                case 0:
                    // single node
                    if(falling != "Driving") {
                        buffer.SetTempPixel(x, y, color1, 0);
                    }
                    else {
                        buffer.SetTempPixel(x, y, color1);
                    }
                    break;
                case 1:
                    // 5 nodes
                    if (x < 1) x+=1;
                    if (y < 1) y+=1;
                    if (x > buffer.BufferWi-2) x-=1;
                    if (y > buffer.BufferHt-2) y-=1;
                    if(falling != "Driving") {
                        buffer.SetTempPixel(x,y,color1, 1);
                    }
                    else {
                        buffer.SetTempPixel(x,y,color1);
                        buffer.SetTempPixel(x-1,y,color2);
                        buffer.SetTempPixel(x+1,y,color2);
                        buffer.SetTempPixel(x,y-1,color2);
                        buffer.SetTempPixel(x,y+1,color2);
                    }
                    break;
                case 2:
                    // 3 nodes
                    if (x < 1) x+=1;
                    if (y < 1) y+=1;
                    if (x > buffer.BufferWi-2) x-=1;
                    if (y > buffer.BufferHt-2) y-=1;
                    if(falling != "Driving")
                    {
                        buffer.SetTempPixel(x,y,color1, 2);
                    }
                    else
                    {
                        buffer.SetTempPixel(x,y,color1);
                        if (rand() % 100 > 50)      // % 2 was not so random
                        {
                            buffer.SetTempPixel(x-1,y,color2);
                            buffer.SetTempPixel(x+1,y,color2);
                        }
                        else
                        {
                            buffer.SetTempPixel(x,y-1,color2);
                            buffer.SetTempPixel(x,y+1,color2);
                        }
                    }
                    break;
                case 3:
                    // 9 nodes
                    if (x < 2) x+=2;
                    if (y < 2) y+=2;
                    if (x > buffer.BufferWi-3) x-=2;
                    if (y > buffer.BufferHt-3) y-=2;
                    if(falling != "Driving") {
                        buffer.SetTempPixel(x, y, color1, 3);
                    }
                    else {
                        buffer.SetTempPixel(x, y, color1);
                        for (i=1; i<=2; i++)
                        {
                            buffer.SetTempPixel(x-i,y,color2);
                            buffer.SetTempPixel(x+i,y,color2);
                            buffer.SetTempPixel(x,y-i,color2);
                            buffer.SetTempPixel(x,y+i,color2);
                        }
                    }
                    break;
                case 4:
                    // 13 nodes
                    if (x < 2) x+=2;
                    if (y < 2) y+=2;
                    if (x > buffer.BufferWi-3) x-=2;
                    if (y > buffer.BufferHt-3) y-=2;
                    if(falling != "Driving") {
                        buffer.SetTempPixel(x, y, color1, 4);
                    }
                    else {
                        buffer.SetTempPixel(x, y, color1);
                        buffer.SetTempPixel(x-1,y,color2);
                        buffer.SetTempPixel(x+1,y,color2);
                        buffer.SetTempPixel(x,y-1,color2);
                        buffer.SetTempPixel(x,y+1,color2);

                        buffer.SetTempPixel(x-1,y+2,color2);
                        buffer.SetTempPixel(x+1,y+2,color2);
                        buffer.SetTempPixel(x-1,y-2,color2);
                        buffer.SetTempPixel(x+1,y-2,color2);
                        buffer.SetTempPixel(x+2,y-1,color2);
                        buffer.SetTempPixel(x+2,y+1,color2);
                        buffer.SetTempPixel(x-2,y-1,color2);
                        buffer.SetTempPixel(x-2,y+1,color2);
                    }
                    break;
                case 5:
                    // 45 nodes (not enabled)
                    break;
            }
        }
    }

    // move snowflakes
    int movement = (buffer.curPeriod - buffer.curEffStartPer) * sSpeed * buffer.frameTimeInMs / 50;
    int new_x,new_y,new_x2,new_y2;
    int starty = 0;
    if (falling == "Falling & Accumulating")
    {
        starty = 1;
    }

    bool driving = falling == "Driving";
    for (x=0; x<buffer.BufferWi; x++) {
        new_x = (x+movement/20) % buffer.BufferWi; // CW
        new_x2 = (x-movement/20) % buffer.BufferWi; // CCW
        if (new_x2 < 0) new_x2 += buffer.BufferWi;

        for (y=starty; y<buffer.BufferHt; y++) {
            if (!driving) {

                // this controls the speed by skipping movement when slow
                if (((buffer.curPeriod-buffer.curEffStartPer) * (sSpeed+1)) / 30 != ((buffer.curPeriod-buffer.curEffStartPer-1) * (sSpeed + 1)) / 30)
                {
                    // if there is a flake to move
                    buffer.GetTempPixel(x, y, color3);
                    if (color3 != xlBLACK) {

                        // check where we can move to?
                        int moves = possible_downward_moves(buffer, x, y);
                        x0 = x;

                        //we have something to move
                        // randomly move the flake left or right
                        if (moves > 0 || (falling == "Falling" && y == 0))
                        {
                            switch(rand() % 5)
                            {
                                case 0:
                                    if (moves & 1) {
                                        x0 = x - 1;
                                    }
                                    else {
                                        if (moves & 2) {
                                            x0 = x;
                                        }
                                        else {
                                            x0 = x + 1;
                                        }
                                    }
                                    break;
                                case 1:
                                    if (moves & 4) {
                                        x0 = x + 1;
                                    }
                                    else {
                                        if (moves & 2) {
                                            x0 = x;
                                        }
                                        else {
                                            x0 = x - 1;
                                        }
                                    }
                                    break;
                                default:  //down more often then left/right to look less "jittery"
                                    if (moves & 2) {
                                        x0 = x;
                                    }
                                    else if ((moves & 5) == 4) {
                                        x0 = x + 1;
                                    }
                                    else if ((moves & 5) == 1) {
                                        x0 = x - 1;
                                    }
                                    else {
                                        switch(rand() % 2)
                                        {
                                            case 0:
                                                x0 = x+1;
                                                break;
                                            default:
                                                x0 = x-1;
                                                break;
                                        }
                                    }
                                    break;
                            }

                            // handle wrap around
                            if (x0 < 0) {
                                x0 += buffer.BufferWi;
                            }
                            else if (x0 >= buffer.BufferWi) {
                                x0 -= buffer.BufferWi;
                            }

                            // and move it down
                            y0 = y - 1;

                            buffer.SetTempPixel(x, y, xlBLACK);
                            if (y0 >= 0)
                            {
                                // move the flake down
                                buffer.SetTempPixel(x0, y0, color3);

                                if (falling == "Falling & Accumulating")
                                {
                                    int nextmoves = possible_downward_moves(buffer, x0, y0);
                                    if (nextmoves == 0) {
                                        // we cant move any further so we can add one at the top
                                        effectState--;
                                    }
                                }
                            }
                            else
                            {
                                // falling should always be just falling ... never accumulate
                                effectState--;
                            }
                        }
                    }
                }
            } else {
                new_y = (y+movement/10) % buffer.BufferHt;
                new_y2 = (new_y+buffer.BufferHt/2) % buffer.BufferHt;
                buffer.GetTempPixel(new_x,new_y,color1);
                if (color1 == xlBLACK) buffer.GetTempPixel(new_x2,new_y2,color1);                // strip off the alpha channel
                buffer.SetPixel(x, y, color1);
            }
        }
    }

    if (!driving)
    {
        // add new flakes to the top
        check = 0;
        int placedFullCount = 0;
        while (effectState < Count && check < 20) {
            // find unused space
            x=rand() % buffer.BufferWi;
            if (buffer.GetTempPixel(x, buffer.BufferHt-1) == xlBLACK) {
                effectState++;
                buffer.SetTempPixel(x, buffer.BufferHt-1, color1, SnowflakeType == 0 ? rand() % 5 : SnowflakeType-1);

                int nextmoves = possible_downward_moves(buffer, x, buffer.BufferHt-1);
                if (nextmoves == 0) {
                    //the placed pixel fills the column, make sure we note that so we can place
                    //another snowflake
                    placedFullCount++;
                }
            }
            check++;
        }
        effectState -= placedFullCount;

        // paint my current state
        for (int y=0; y < buffer.BufferHt; y++) {
            for (int x=0; x < buffer.BufferWi; x++) {

                buffer.GetTempPixel(x, y, color3);
                if (color3 != xlBLACK)
                {
                    // draw flake, SnowflakeType=0 is random type
                    switch (color3.Alpha())
                    {
                        case 0:
                            // single node
                            buffer.SetPixel(x, y, color1);
                            break;
                        case 1:
                            // 5 nodes
                            buffer.SetPixel(x,y,color1);
                            set_pixel_if_not_color(buffer, x-1, y, color2, color1, wrapx, false);
                            set_pixel_if_not_color(buffer, x+1, y, color2, color1, wrapx, false);
                            set_pixel_if_not_color(buffer, x, y-1, color2, color1, wrapx, false);
                            set_pixel_if_not_color(buffer, x, y+1, color2, color1, wrapx, false);
                            break;
                        case 2:
                        {
                            // 3 nodes
                            buffer.SetPixel(x,y,color1);
                            bool isAtBottom = true;
                            for (int yt = 0; yt < y - 1; yt++) {
                                if (buffer.GetTempPixel(x, yt) == xlBLACK) {
                                    isAtBottom = false;
                                    break;
                                }
                            }

                            // when flake has settled always paint it horizontally
                            if (isAtBottom)
                            {
                                set_pixel_if_not_color(buffer, x-1, y, color2, color1, wrapx, false);
                                set_pixel_if_not_color(buffer, x+1, y, color2, color1, wrapx, false);
                            }
                            else {
                                if (rand() % 100 > 50)      // % 2 was not so random
                                {
                                    set_pixel_if_not_color(buffer, x-1, y, color2, color1, wrapx, false);
                                    set_pixel_if_not_color(buffer, x+1, y, color2, color1, wrapx, false);
                                }
                                else
                                {
                                    set_pixel_if_not_color(buffer, x, y-1, color2, color1, wrapx, false);
                                    set_pixel_if_not_color(buffer, x, y+1, color2, color1, wrapx, false);
                                }
                            }
                        }
                            break;
                        case 3:
                            // 9 nodes
                            buffer.SetPixel(x,y,color1);
                            for (i=1; i<=2; i++)
                            {
                                set_pixel_if_not_color(buffer, x-i, y, color2, color1, wrapx, false);
                                set_pixel_if_not_color(buffer, x+i, y, color2, color1, wrapx, false);
                                set_pixel_if_not_color(buffer, x, y-i, color2, color1, wrapx, false);
                                set_pixel_if_not_color(buffer, x, y+i, color2, color1, wrapx, false);
                            }
                            break;
                        case 4:
                            // 13 nodes
                            buffer.SetPixel(x,y,color1);
                            set_pixel_if_not_color(buffer, x-1, y, color2, color1, wrapx, false);
                            set_pixel_if_not_color(buffer, x+1, y, color2, color1, wrapx, false);
                            set_pixel_if_not_color(buffer, x, y+1, color2, color1, wrapx, false);
                            set_pixel_if_not_color(buffer, x, y-1, color2, color1, wrapx, false);

                            set_pixel_if_not_color(buffer, x-1, y+2, color2, color1, wrapx, false);
                            set_pixel_if_not_color(buffer, x+1, y+2, color2, color1, wrapx, false);
                            set_pixel_if_not_color(buffer, x-1, y-2, color2, color1, wrapx, false);
                            set_pixel_if_not_color(buffer, x+1, y-2, color2, color1, wrapx, false);
                            set_pixel_if_not_color(buffer, x+2, y-1, color2, color1, wrapx, false);
                            set_pixel_if_not_color(buffer, x+2, y+1, color2, color1, wrapx, false);
                            set_pixel_if_not_color(buffer, x-2, y-1, color2, color1, wrapx, false);
                            set_pixel_if_not_color(buffer, x-2, y+1, color2, color1, wrapx, false);
                            break;
                        case 5:
                            // 45 nodes (not enabled)
                            break;
                    }
                }
            }
        }
    }
}
Beispiel #12
0
void FireworksEffect::Render(Effect *effect, const SettingsMap &SettingsMap, RenderBuffer &buffer) {
    int Number_Explosions = SettingsMap.GetInt("SLIDER_Fireworks_Explosions", 16);
    int Count = SettingsMap.GetInt("SLIDER_Fireworks_Count", 50);
    float Velocity = SettingsMap.GetDouble("SLIDER_Fireworks_Velocity", 2.0f);
    int Fade = SettingsMap.GetInt("SLIDER_Fireworks_Fade", 50);

    float f = 0.0;
    bool useMusic = SettingsMap.GetBool("CHECKBOX_Fireworks_UseMusic", false);
    float sensitivity = (float)SettingsMap.GetInt("SLIDER_Fireworks_Sensitivity", 50) / 100.0;
    bool useTiming = SettingsMap.GetBool("CHECKBOX_FIRETIMING", false);
    wxString timing = SettingsMap.Get("CHOICE_FIRETIMINGTRACK", "");
    if (timing == "") useTiming = false;
    if (useMusic)
    {
        if (buffer.GetMedia() != nullptr) {
            std::list<float>* pf = buffer.GetMedia()->GetFrameData(buffer.curPeriod, FRAMEDATA_HIGH, "");
            if (pf != nullptr)
            {
                f = *pf->begin();
            }
        }
    }

    FireworksRenderCache *cache = (FireworksRenderCache*)buffer.infoCache[id];
    if (cache == nullptr) {
        cache = new FireworksRenderCache();
        buffer.infoCache[id] = cache;
    }
    
    int& next = cache->next;
    int& sincelasttriggered = cache->sincelasttriggered;
    int x25,x75,y25,y75;
    //float velocity = 3.5;
    int ColorIdx;
    float v;
    HSVValue hsv;
    size_t colorcnt = buffer.GetColorCount();
    
    if (buffer.needToInit) {
        SetPanelTimingTracks();
        cache->sincelasttriggered = 0;
        cache->next = 0;
        buffer.needToInit = false;
        for(int i=0; i<maxFlakes; i++) {
            cache->fireworkBursts[i]._bActive = false;
        }
        for (int x = 0; x < Number_Explosions; x++) {
            double start = -1;
            if (!useMusic)
            {
                start = buffer.curEffStartPer + buffer.rand01() * (buffer.curEffEndPer - buffer.curEffStartPer);
            }
            x25=(int)buffer.BufferWi*0.25;
            x75=(int)buffer.BufferWi*0.75;
            y25=(int)buffer.BufferHt*0.25;
            y75=(int)buffer.BufferHt*0.75;
            int startX;
            int startY;
            if((x75-x25)>0) startX = x25 + rand()%(x75-x25); else startX=0;
            if((y75-y25)>0) startY = y25 + rand()%(y75-y25); else startY=0;
            
            // Create a new burst
            ColorIdx=rand() % colorcnt; // Select random numbers from 0 up to number of colors the user has checked. 0-5 if 6 boxes checked
            for(int i=0; i<Count; i++) {
                cache->fireworkBursts[x * Count + i].Reset(startX, startY, false, Velocity, ColorIdx, start);
            }
        }

        if (timing != "")
        {
            effect->GetParentEffectLayer()->GetParentElement()->GetSequenceElements()->AddRenderDependency(timing.ToStdString(), buffer.cur_model);
        }
    }

    if (useMusic)
    {
        // only trigger a firework if music is greater than the sensitivity
        if (f > sensitivity)
        {
            // trigger if it was not previously triggered or has been triggered for REPEATTRIGGER frames
            if (sincelasttriggered == 0 || sincelasttriggered > REPEATTRIGGER)
            {
                // activate all the particles in the next firework
                for (int j = 0; j < Count; j++)
                {
                    cache->fireworkBursts[Count*next + j]._bActive = true;
                    buffer.palette.GetHSV(cache->fireworkBursts[Count*next + j]._colorindex, hsv); // Now go and get the hsv value for this ColorIdx
                    cache->fireworkBursts[Count*next + j]._hsv = hsv;
                }

                // use the next firework next time
                next++;
                if (next == Number_Explosions)
                {
                    next = 0;
                }
            }

            // if music is over the trigger level for REPEATTRIGGER frames then we will trigger another firework
            sincelasttriggered++;
            if (sincelasttriggered > REPEATTRIGGER)
            {
                sincelasttriggered = 0;
            }
        }
        else
        {
            // not triggered so clear last triggered counter
            sincelasttriggered = 0;
        }
    }

    if (useTiming)
    {
        if (mSequenceElements == nullptr)
        {
            // no timing tracks ... this shouldnt happen
        }
        else
        {
            // Load the names of the timing tracks
            Element* t = nullptr;
            for (size_t l = 0; l < mSequenceElements->GetElementCount(); l++)
            {
                Element* e = mSequenceElements->GetElement(l);
                if (e->GetEffectLayerCount() == 1 && e->GetType() == ELEMENT_TYPE_TIMING)
                {
                    if (e->GetName() == timing)
                    {
                        t = e;
                        break;
                    }
                }
            }

            if (t == nullptr)
            {
                // timing track not found ... this shouldnt happen
            }
            else
            {
                sincelasttriggered = 0;
                EffectLayer* el = t->GetEffectLayer(0);
                for (int j = 0; j < el->GetEffectCount(); j++)
                {
                    if (buffer.curPeriod == el->GetEffect(j)->GetStartTimeMS() / buffer.frameTimeInMs ||
                        buffer.curPeriod == el->GetEffect(j)->GetEndTimeMS() / buffer.frameTimeInMs)
                    {
                        // activate all the particles in the next firework
                        for (int k = 0; k < Count; k++)
                        {
                            cache->fireworkBursts[Count*next + k]._bActive = true;
                            buffer.palette.GetHSV(cache->fireworkBursts[Count*next + k]._colorindex, hsv); // Now go and get the hsv value for this ColorIdx
                            cache->fireworkBursts[Count*next + k]._hsv = hsv;
                        }

                        // use the next firework next time
                        next++;
                        if (next == Number_Explosions)
                        {
                            next = 0;
                        }
                        break;
                    }
                }
            }
        }
    }

    for (int i=0; i<(Count*Number_Explosions); i++) {
        if (!useMusic && !useTiming)
        {
            if (cache->fireworkBursts[i].startPeriod == buffer.curPeriod) {
                cache->fireworkBursts[i]._bActive = true;
                buffer.palette.GetHSV(cache->fireworkBursts[i]._colorindex, hsv); // Now go and get the hsv value for this ColorIdx
                cache->fireworkBursts[i]._hsv = hsv;
            }
        }

        // ... active flakes:
        if (cache->fireworkBursts[i]._bActive)
        {
            // Update position
            cache->fireworkBursts[i]._x += cache->fireworkBursts[i]._dx;
            cache->fireworkBursts[i]._y += (-cache->fireworkBursts[i]._dy - cache->fireworkBursts[i]._cycles*cache->fireworkBursts[i]._cycles/10000000.0);
            // If this flake run for more than maxCycle or this flake is out of bounds, time to switch it off
            cache->fireworkBursts[i]._cycles+=20;
            if (cache->fireworkBursts[i]._cycles >= 10000 || cache->fireworkBursts[i]._y >= buffer.BufferHt || cache->fireworkBursts[i]._y < 0 ||
                cache->fireworkBursts[i]._x < 0. || cache->fireworkBursts[i]._x >= buffer.BufferWi)
            {
                cache->fireworkBursts[i]._bActive = false;
                if (useMusic)
                {
                    cache->fireworkBursts[i].Reset();
                }
                continue;
            }
        }
        if(cache->fireworkBursts[i]._bActive == true)
        {
            v = ((Fade*10.0)-cache->fireworkBursts[i]._cycles)/(Fade*10.0);
            if (v<0) v=0.0;
            if (buffer.allowAlpha) {
                xlColor c(cache->fireworkBursts[i]._hsv);
                c.alpha = 255.0 * v;
                buffer.SetPixel(cache->fireworkBursts[i]._x, cache->fireworkBursts[i]._y, c);
            } else {
                hsv=cache->fireworkBursts[i]._hsv;
                hsv.value=v;
                buffer.SetPixel(cache->fireworkBursts[i]._x, cache->fireworkBursts[i]._y, hsv);
            }
        }
    }
}