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 ShimmerEffect::Render(Effect *effect, const SettingsMap &SettingsMap, RenderBuffer &buffer) {
    float oset = buffer.GetEffectTimeIntervalPosition();
    int Duty_Factor = GetValueCurveInt("Shimmer_Duty_Factor", 50, SettingsMap, oset);
    bool Use_All_Colors = SettingsMap.GetBool("CHECKBOX_Shimmer_Use_All_Colors", false);
    float cycles = GetValueCurveDouble("Shimmer_Cycles", 1.0, SettingsMap, oset);
    int colorcnt=buffer.GetColorCount();
    
    double position = buffer.GetEffectTimeIntervalPosition(cycles);
    
    double ColorIdx = round(position * 0.999 * (double)colorcnt);
    
    double pos2 = position * colorcnt;
    while (pos2 > 1.0) {
        pos2 -= 1.0;
    }
    if (pos2 * 100 > Duty_Factor) {
        return;
    }
    
    xlColor color;
    buffer.palette.GetColor(ColorIdx, color);
    for (int y=0; y<buffer.BufferHt; y++) {
        for (int x=0; x<buffer.BufferWi; x++) {
            if(Use_All_Colors) { // Should we randomly assign colors from palette or cycle thru sequentially?
                ColorIdx=rand() % colorcnt; // Select random numbers from 0 up to number of colors the user has checked. 0-5 if 6 boxes checked
                buffer.palette.GetColor(ColorIdx, color); // Now go and get the hsv value for this ColorIdx
            }
            
            buffer.SetPixel(x,y,color); // Turn pixel
        }
    }
}
Beispiel #3
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 #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> FireworksEffect::CheckEffectSettings(const SettingsMap& settings, AudioManager* media, Model* model, Effect* eff)
{
    std::list<std::string> res;

    if (media == nullptr && settings.GetBool("E_CHECKBOX_Fireworks_UseMusic", false))
    {
        res.push_back(wxString::Format("    WARN: Fireworks effect cant grow to music if there is no music. Model '%s', Start %s", model->GetName(), FORMATTIME(eff->GetStartTimeMS())).ToStdString());
    }

    return res;
}
Beispiel #6
0
void MorphEffect::Render(Effect *effect, const SettingsMap &SettingsMap, RenderBuffer &buffer) {

    int start_x1 = SettingsMap.GetInt("SLIDER_Morph_Start_X1", 0);
    int start_y1 = SettingsMap.GetInt("SLIDER_Morph_Start_Y1", 0);
    int start_x2 = SettingsMap.GetInt("SLIDER_Morph_Start_X2", 0);
    int start_y2 = SettingsMap.GetInt("SLIDER_Morph_Start_Y2", 0);
    int end_x1 = SettingsMap.GetInt("SLIDER_Morph_End_X1", 0);
    int end_y1 = SettingsMap.GetInt("SLIDER_Morph_End_Y1", 0);
    int end_x2 = SettingsMap.GetInt("SLIDER_Morph_End_X2", 0);
    int end_y2 = SettingsMap.GetInt("SLIDER_Morph_End_Y2", 0);
    int start_length = SettingsMap.GetInt("SLIDER_MorphStartLength", 0);
    int end_length = SettingsMap.GetInt("SLIDER_MorphEndLength", 0);
    bool start_linked = SettingsMap.GetBool("CHECKBOX_Morph_Start_Link");
    bool end_linked = SettingsMap.GetBool("CHECKBOX_Morph_End_Link");
    int duration = SettingsMap.GetInt("SLIDER_MorphDuration", 0);
    int acceleration = SettingsMap.GetInt("SLIDER_MorphAccel", 0);
    bool showEntireHeadAtStart = SettingsMap.GetBool("CHECKBOX_ShowHeadAtStart");
    int repeat_count = SettingsMap.GetInt("SLIDER_Morph_Repeat_Count", 0);
    int repeat_skip = SettingsMap.GetInt("SLIDER_Morph_Repeat_Skip", 0);
    int stagger = SettingsMap.GetInt("SLIDER_Morph_Stagger", 0);

    double eff_pos = buffer.GetEffectTimeIntervalPosition();
    double step_size = 0.1;

    int hcols = 0, hcole = 1;
    int tcols = 2, tcole = 3;
    int num_tail_colors = 2;
    switch (buffer.palette.Size()) {
        case 1:  //one color selected, use it for all
            hcols = hcole = tcols = tcole = 0;
            break;
        case 2: //two colors, head/tail
            hcols = hcole = 0;
            tcols = tcole = 1;
            break;
        case 3: //three colors, head /tail start/end
            hcols = hcole = 0;
            tcols = 1;
            tcole = 2;
            break;
        case 4:
            break;
        case 5:
            num_tail_colors = 3;
            break;
        case 6:
            num_tail_colors = 4;
            break;
    }

    int x1a = calcPosition(start_x1, buffer.BufferWi);
    int y1a = calcPosition(start_y1, buffer.BufferHt);
    int x2a = calcPosition(end_x1, buffer.BufferWi);
    int y2a = calcPosition(end_y1, buffer.BufferHt);

    int x1b, x2b, y1b, y2b;

    if( start_linked )
    {
        x1b = x1a;
        y1b = y1a;
    }
    else
    {
        x1b = calcPosition(start_x2, buffer.BufferWi);
        y1b = calcPosition(start_y2, buffer.BufferHt);
    }

    if( end_linked )
    {
        x2b = x2a;
        y2b = y2a;
    }
    else
    {
        x2b = calcPosition(end_x2, buffer.BufferWi);
        y2b = calcPosition(end_y2, buffer.BufferHt);
    }

    xlColor head_color, tail_color, test_color;

    // compute direction
    int delta_xa = x2a - x1a;
    int delta_xb = x2b - x1b;
    int delta_ya = y2a - y1a;
    int delta_yb = y2b - y1b;
    int direction = delta_xa + delta_xb + delta_ya + delta_yb;
    int repeat_x = 0;
    int repeat_y = 0;
    double effect_pct = 1.0;
    double stagger_pct = 0.0;
    if( repeat_count > 0 )
    {
        if( (std::abs((float)delta_xa) + std::abs((float)delta_xb)) < (std::abs((float)delta_ya) + std::abs((float)delta_yb)) )
        {
            repeat_x = repeat_skip;
        }
        else
        {
            repeat_y = repeat_skip;
        }
        double stagger_val = (double)(std::abs((double)stagger))/200.0;
        effect_pct = 1.0 / (1 + stagger_val * repeat_count);
        stagger_pct = effect_pct * stagger_val;
    }

    std::vector<int> v_ax;
    std::vector<int> v_ay;
    std::vector<int> v_bx;
    std::vector<int> v_by;

    StoreLine(x1a, y1a, x2a, y2a, &v_ax, &v_ay);  // store side a
    StoreLine(x1b, y1b, x2b, y2b, &v_bx, &v_by);  // store side b

    int size_a = v_ax.size();
    int size_b = v_bx.size();

    std::vector<int> *v_lngx;  // pointer to longest vector x
    std::vector<int> *v_lngy;  // pointer to longest vector y
    std::vector<int> *v_shtx;  // pointer to shorter vector x
    std::vector<int> *v_shty;  // pointer to shorter vector y

    if( size_a > size_b )
    {
        v_lngx = &v_ax;
        v_lngy = &v_ay;
        v_shtx = &v_bx;
        v_shty = &v_by;
    }
    else
    {
        v_lngx = &v_bx;
        v_lngy = &v_by;
        v_shtx = &v_ax;
        v_shty = &v_ay;
    }

    double pos_a, pos_b;
    double total_tail_length, alpha_pct;
    double total_length = v_lngx->size();     // total length of longest vector
    double head_duration = duration/100.0;    // time the head is in the frame
    double head_end_of_head_pos = total_length + 1;
    double tail_end_of_head_pos = total_length + 1;
    double head_end_of_tail_pos = -1;
    double tail_end_of_tail_pos = -1;

    for( int repeat = 0; repeat <= repeat_count; repeat++ )
    {
        double eff_pos_adj = buffer.calcAccel(eff_pos, acceleration);
        double eff_start_pct = (stagger >= 0) ? stagger_pct*repeat : stagger_pct*(repeat_count-repeat);
        double eff_end_pct = eff_start_pct + effect_pct;
        eff_pos_adj = (eff_pos_adj - eff_start_pct) / (eff_end_pct - eff_start_pct);
        if( eff_pos_adj < 0.0 )
        {
            head_end_of_head_pos = -1;
            tail_end_of_head_pos = -1;
            head_end_of_tail_pos = -1;
            tail_end_of_tail_pos = -1;
            total_tail_length = 1.0;
            if( showEntireHeadAtStart )
            {
                head_end_of_head_pos = start_length;
            }
        }
        else
        {
            if( head_duration > 0.0 )
            {
                double head_loc_pct = eff_pos_adj / head_duration;
                head_end_of_head_pos = total_length * head_loc_pct;
                double current_total_head_length = end_length * head_loc_pct + start_length * (1.0 - head_loc_pct);  // adjusted head length excluding clipping
                head_end_of_head_pos += current_total_head_length * head_loc_pct * head_duration;
                total_tail_length = total_length * ( 1 / head_duration - 1.0);
                if( showEntireHeadAtStart )
                {
                    head_end_of_head_pos += current_total_head_length * (1.0 - eff_pos_adj);
                }
                tail_end_of_head_pos = head_end_of_head_pos - current_total_head_length;
                head_end_of_tail_pos = tail_end_of_head_pos - step_size;
                tail_end_of_tail_pos = head_end_of_tail_pos - total_tail_length;
                buffer.Get2ColorBlend(hcols, hcole, std::min( head_loc_pct, 1.0), head_color);
            }
            else
            {
                total_tail_length = total_length;
                head_end_of_tail_pos = total_length * 2 * eff_pos_adj;
                tail_end_of_tail_pos = head_end_of_tail_pos - total_tail_length;
            }
        }

        // draw the tail
        for( double i = std::min(head_end_of_tail_pos, total_length-1); i >= tail_end_of_tail_pos && i >= 0.0; i -= step_size )
        {
            double pct = ((total_length == 0) ? 0.0 : i / total_length);
            pos_a = i;
            pos_b = v_shtx->size() * pct;
            double tail_color_pct = (i-tail_end_of_tail_pos) / total_tail_length;
            if( num_tail_colors > 2 )
            {
                double color_index = ((double)num_tail_colors - 1.0) * (1.0 - tail_color_pct);
                tail_color_pct = color_index - (double)((int)color_index);
                tcols = (int)color_index + 2;
                tcole = tcols + 1;
                if( tcole == num_tail_colors+1 )
                {
                    alpha_pct = (1.0 - tail_color_pct);
                }
                else
                {
                    alpha_pct = 1.0;
                }
                buffer.Get2ColorBlend(tcols, tcole, tail_color_pct, tail_color);
            }
            else
            {
                if( tail_color_pct > 0.5 )
                {
                    alpha_pct = 1.0;
                }
                else
                {
                    alpha_pct = tail_color_pct / 0.5;
                }
                buffer.Get2ColorBlend(tcole, tcols, tail_color_pct, tail_color);
            }
            if( buffer.allowAlpha ) {
                tail_color.alpha = 255 * alpha_pct;
            }
            buffer.DrawThickLine( (*v_lngx)[pos_a]+(repeat_x*repeat), (*v_lngy)[pos_a]+(repeat_y*repeat), (*v_shtx)[pos_b]+(repeat_x*repeat), (*v_shty)[pos_b]+(repeat_y*repeat), tail_color, direction >= 0);
        }

        // draw the head
        for( double i = std::max(tail_end_of_head_pos, 0.0); i <= head_end_of_head_pos && i < total_length; i += step_size )
        {
            double pct = ((total_length == 0) ? 0.0 : i / total_length);
            pos_a = i;
            pos_b = v_shtx->size() * pct;
            buffer.DrawThickLine( (*v_lngx)[pos_a]+(repeat_x*repeat), (*v_lngy)[pos_a]+(repeat_y*repeat), (*v_shtx)[pos_b]+(repeat_x*repeat), (*v_shty)[pos_b]+(repeat_y*repeat), head_color, direction >= 0);
        }
    }
}
Beispiel #7
0
void GalaxyEffect::Render(Effect *effect, const SettingsMap &SettingsMap, RenderBuffer &buffer) {
    int center_x = SettingsMap.GetInt("SLIDER_Galaxy_CenterX");
    int center_y = SettingsMap.GetInt("SLIDER_Galaxy_CenterY");
    int start_radius = SettingsMap.GetInt("SLIDER_Galaxy_Start_Radius");
    int end_radius = SettingsMap.GetInt("SLIDER_Galaxy_End_Radius");
    int start_angle = SettingsMap.GetInt("SLIDER_Galaxy_Start_Angle");
    int revolutions = SettingsMap.GetInt("SLIDER_Galaxy_Revolutions");
    int start_width = SettingsMap.GetInt("SLIDER_Galaxy_Start_Width");
    int end_width = SettingsMap.GetInt("SLIDER_Galaxy_End_Width");
    int duration = SettingsMap.GetInt("SLIDER_Galaxy_Duration");
    int acceleration = SettingsMap.GetInt("SLIDER_Galaxy_Accel");
    bool reverse_dir = SettingsMap.GetBool("CHECKBOX_Galaxy_Reverse");
    bool blend_edges = SettingsMap.GetBool("CHECKBOX_Galaxy_Blend_Edges");
    bool inward = SettingsMap.GetBool("CHECKBOX_Galaxy_Inward");

    if( revolutions == 0 ) return;
    std::vector< std::vector<double> > temp_colors_pct(buffer.BufferWi, std::vector<double>(buffer.BufferHt));
    std::vector< std::vector<double> > pixel_age(buffer.BufferWi, std::vector<double>(buffer.BufferHt));

    double eff_pos = buffer.GetEffectTimeIntervalPosition();
    int num_colors = buffer.palette.Size();
    xlColor color, c_old, c_new;
    HSVValue hsv1;
    double eff_pos_adj = buffer.calcAccel(eff_pos, acceleration);
    double revs = (double)revolutions;

    double pos_x = buffer.BufferWi * center_x/100.0;
    double pos_y = buffer.BufferHt * center_y/100.0;

    double head_duration = duration/100.0;    // time the head is in the frame
    double tail_length = revs * (1.0 - head_duration);
    double color_length = tail_length / num_colors;
    if(color_length < 1.0) color_length = 1.0;


    double tail_end_of_tail = ((revs + tail_length) * eff_pos_adj) - tail_length;
    double head_end_of_tail = tail_end_of_tail + tail_length;

    double radius1 = start_radius;
    double radius2 = end_radius;
    double width1 = start_width;
    double width2 = end_width;

    double step = buffer.GetStepAngle(radius1, radius2);

    for( int x = 0; x < buffer.BufferWi; x++ )
    {
        for( int y = 0; y < buffer.BufferHt; y++ )
        {
            temp_colors_pct[x][y] = 0.0;
            pixel_age[x][y] = 0.0;
        }
    }
    buffer.ClearTempBuf();

    double last_check = (inward ? std::min(head_end_of_tail,revs) : std::max(0.0, tail_end_of_tail) ) + (double)start_angle;

    for( double i = (inward ? std::min(head_end_of_tail,revs) : std::max(0.0, tail_end_of_tail));
        (inward ? i >= std::max(0.0, tail_end_of_tail) : i <= std::min(head_end_of_tail,revs));
        (inward ? i -= step : i += step) )
    {
        double adj_angle = i + (double)start_angle;
        if( reverse_dir )
        {
            adj_angle *= -1.0;
        }
        double color_val = (head_end_of_tail-i) / color_length;
        int color_int = (int)color_val;
        double color_pct = color_val - (double)color_int;
        int color2 = std::min(color_int+1, num_colors-1);
        if( color_int < color2 )
        {
            buffer.Get2ColorBlend(color_int, color2, std::min( color_pct, 1.0), color);
        }
        else
        {
            buffer.palette.GetColor(color2, color);
        }
        HSVValue hsv(color);
        double full_brightness = hsv.value;
        double pct = i/revs;
        double current_radius = radius2 * pct + radius1 * (1.0 - pct);
        double current_width = width2 * pct + width1 * (1.0 - pct);
        double half_width = current_width / 2.0;
        double inside_radius = current_radius - half_width;
        for( double r = inside_radius; ; r += 0.5 )
        {
            if( r > current_radius ) r = current_radius;
            double x1 = buffer.sin(ToRadians(adj_angle)) * r + (double)pos_x;
            double y1 = buffer.cos(ToRadians(adj_angle)) * r + (double)pos_y;
            double outside_radius = current_radius + (current_radius - r);
            double x2 = buffer.sin(ToRadians(adj_angle)) * outside_radius + (double)pos_x;
            double y2 = buffer.cos(ToRadians(adj_angle)) * outside_radius + (double)pos_y;
            double color_pct2 = (r-inside_radius)/(current_radius-inside_radius);
            if( blend_edges )
            {
                if( hsv.value > 0.0 )
                {
                    if ((int)x1 >= 0 && (int)x1 < buffer.BufferWi && (int)y1 >= 0 && (int)y1 < buffer.BufferHt)
                    {
                        buffer.SetTempPixel((int)x1,(int)y1,color);
                        temp_colors_pct[(int)x1][(int)y1] = color_pct2;
                        pixel_age[(int)x1][(int)y1] = adj_angle;
                    }
                    if ((int)x2 >= 0 && (int)x2 < buffer.BufferWi && (int)y2 >= 0 && (int)y2 < buffer.BufferHt)
                    {
                        buffer.SetTempPixel((int)x2,(int)y2,color);
                        temp_colors_pct[(int)x2][(int)y2] = color_pct2;
                        pixel_age[(int)x2][(int)y2] = adj_angle;
                    }
                }
            }
            else
            {
                hsv.value = full_brightness * color_pct2;
                if( hsv.value > 0.0 )
                {
                    buffer.SetPixel(x1,y1,hsv);
                    buffer.SetPixel(x2,y2,hsv);
                }
            }
            if( r >= current_radius ) break;
        }
        // blend old data down into final buffer
        if( blend_edges && ( (inward ? (last_check-adj_angle) : (adj_angle-last_check)) >= 90.0) )
        {
            for( int x = 0; x < buffer.BufferWi; x++ )
            {
                for( int y = 0; y < buffer.BufferHt; y++ )
                {
                    if( temp_colors_pct[x][y] > 0.0 && ((inward ? (pixel_age[x][y]-adj_angle) : (adj_angle-pixel_age[x][y])) >= 180.0) )
                    {
                        buffer.GetTempPixel(x,y,c_new);
                        buffer.GetPixel(x,y,c_old);
                        buffer.Get2ColorAlphaBlend(c_old, c_new, temp_colors_pct[x][y], color);
                        buffer.SetPixel(x,y,color);
                        temp_colors_pct[x][y] = 0.0;
                        pixel_age[x][y] = 0.0;
                    }
                }
            }
            last_check = adj_angle;
        }
    }

    // blend remaining data down into final buffer
    if( blend_edges )
    {
        for( int x = 0; x < buffer.BufferWi; x++ )
        {
            for( int y = 0; y < buffer.BufferHt; y++ )
            {
                if( temp_colors_pct[x][y] > 0.0 )
                {
                    buffer.GetTempPixel(x,y,c_new);
                    buffer.GetPixel(x,y,c_old);
                    buffer.Get2ColorAlphaBlend(c_old, c_new, temp_colors_pct[x][y], color);
                    buffer.SetPixel(x,y,color);
                }
            }
        }
    }

}
Beispiel #8
0
void MarqueeEffect::Render(Effect *effect, const SettingsMap &SettingsMap, RenderBuffer &buffer) {

    int BandSize = SettingsMap.GetInt("SLIDER_Marquee_Band_Size", 0);
    int SkipSize = SettingsMap.GetInt("SLIDER_Marquee_Skip_Size", 0);
    int Thickness = SettingsMap.GetInt("SLIDER_Marquee_Thickness", 0);
    int stagger = SettingsMap.GetInt("SLIDER_Marquee_Stagger", 0);
    int mSpeed = SettingsMap.GetInt("SLIDER_Marquee_Speed", 1);
    int mStart = SettingsMap.GetInt("SLIDER_Marquee_Start", 0);
    bool reverse_dir = SettingsMap.GetBool("CHECKBOX_Marquee_Reverse");
    int x_scale = SettingsMap.GetInt("SLIDER_Marquee_ScaleX", 0);
    int y_scale = SettingsMap.GetInt("SLIDER_Marquee_ScaleY", 0);
    int xc_adj = SettingsMap.GetInt("SLIDER_MarqueeXC", 0);
    int yc_adj = SettingsMap.GetInt("SLIDER_MarqueeYC", 0);
    bool pixelOffsets = SettingsMap.GetBool("CHECKBOX_Marquee_PixelOffsets");
    bool wrap_x = SettingsMap.GetBool("CHECKBOX_Marquee_WrapX");

    int x = 0;
    xlColor color;
    size_t colorcnt = buffer.GetColorCount();
    int color_size = BandSize +  SkipSize;
    int repeat_size = color_size * colorcnt;
    int eff_pos = buffer.curPeriod - buffer.curEffStartPer;

    x = (mSpeed * eff_pos) / 5;
    int corner_x1 = 0;
    int corner_y1 = 0;
    int corner_x2 = (int)((double)buffer.BufferWi * (double)x_scale / 100.0) - 1;
    int corner_y2 = (int)((double)buffer.BufferHt * (double)y_scale / 100.0) - 1;
    int sign = 1;
    if( reverse_dir ) {
        sign = -1;
    }

    int xoffset_adj = xc_adj;
    int yoffset_adj = yc_adj;
    if (!pixelOffsets) {
        xoffset_adj = (xoffset_adj*buffer.BufferWi)/100.0; // xc_adj is from -100 to 100
        yoffset_adj = (yoffset_adj*buffer.BufferHt)/100.0; // yc_adj is from -100 to 100
    }

    for( int thick = 0; thick < Thickness; thick++ )
    {
        int current_color = ((x + mStart) % repeat_size) / color_size;
        int current_pos = (((x + mStart) % repeat_size) % color_size);
        if( sign < 0 )
        {
            current_color = colorcnt - current_color - 1;
        }
       // wxLogDebug(wxString::Format("Color: %d,  Pos: %d", current_color, current_pos));
        UpdateMarqueeColor(current_pos, current_color, colorcnt, color_size, thick*(stagger+1) * sign);
        for( int x_pos = corner_x1; x_pos <= corner_x2; x_pos++ )
        {
            color = xlBLACK;
            if( current_pos < BandSize )
            {
                buffer.palette.GetColor(current_color, color);
            }
            buffer.ProcessPixel(x_pos + xoffset_adj, corner_y2 + yoffset_adj, color, wrap_x);
            UpdateMarqueeColor(current_pos, current_color, colorcnt, color_size, 1*sign);
        }
        UpdateMarqueeColor(current_pos, current_color, colorcnt, color_size, thick*2*sign);
        for( int y_pos = corner_y2; y_pos >=corner_y1 ; y_pos-- )
        {
            color = xlBLACK;
            if( current_pos < BandSize )
            {
                buffer.palette.GetColor(current_color, color);
            }
            buffer.ProcessPixel(corner_x2 + xoffset_adj, y_pos + yoffset_adj, color, wrap_x);
            UpdateMarqueeColor(current_pos, current_color, colorcnt, color_size, 1*sign);
        }
        UpdateMarqueeColor(current_pos, current_color, colorcnt, color_size, thick*2*sign);
        for( int x_pos = corner_x2; x_pos >= corner_x1; x_pos-- )
        {
            color = xlBLACK;
            if( current_pos < BandSize )
            {
                buffer.palette.GetColor(current_color, color);
            }
            buffer.ProcessPixel(x_pos + xoffset_adj, corner_y1 + yoffset_adj, color, wrap_x);
            UpdateMarqueeColor(current_pos, current_color, colorcnt, color_size, 1*sign);
        }
        UpdateMarqueeColor(current_pos, current_color, colorcnt, color_size, thick*2*sign);
        for( int y_pos = corner_y1; y_pos <= corner_y2-1; y_pos++ )
        {
            color = xlBLACK;
            if( current_pos < BandSize )
            {
                buffer.palette.GetColor(current_color, color);
            }
            buffer.ProcessPixel(corner_x1 + xoffset_adj, y_pos + yoffset_adj, color, wrap_x);
            UpdateMarqueeColor(current_pos, current_color, colorcnt, color_size, 1*sign);
        }
        corner_x1++;
        corner_y1++;
        corner_x2--;
        corner_y2--;
    }
}
Beispiel #9
0
void ColorWashEffect::Render(Effect *effect, const SettingsMap &SettingsMap, RenderBuffer &buffer) {
    bool HorizFade = SettingsMap.GetBool(CHECKBOX_ColorWash_HFade);
    bool VertFade = SettingsMap.GetBool(CHECKBOX_ColorWash_VFade);
    float cycles = SettingsMap.GetDouble(TEXTCTRL_ColorWash_Cycles, 1.0);
    bool EntireModel = SettingsMap.GetInt(CHECKBOX_ColorWash_EntireModel, 1);
    int x1 = SettingsMap.GetInt(SLIDER_ColorWash_X1, -50);
    int y1 = SettingsMap.GetInt(SLIDER_ColorWash_Y1, -50);
    int x2 = SettingsMap.GetInt(SLIDER_ColorWash_X2, 50);
    int y2 = SettingsMap.GetInt(SLIDER_ColorWash_Y2, 50);
    bool shimmer = SettingsMap.GetInt(CHECKBOX_ColorWash_Shimmer, 0);
    bool circularPalette = SettingsMap.GetInt(CHECKBOX_ColorWash_CircularPalette, 0);
    
    
    int x,y;
    xlColor color, orig;
    
    double position = buffer.GetEffectTimeIntervalPosition(cycles);
    buffer.GetMultiColorBlend(position, circularPalette, color);
    
    int startX = 0;
    int startY = 0;
    int endX = buffer.BufferWi - 1;
    int endY = buffer.BufferHt - 1;
    
    if (!EntireModel) {
        startX = std::min(x1, x2);
        endX = std::max(x1, x2);
        startY = std::min(y1, y2);
        endY = std::max(y1, y2);
        startX = std::round(double(buffer.BufferWi - 0.5) * (double)startX / 100.0);
        endX = std::round(double(buffer.BufferWi - 0.5) * (double)endX / 100.0);
        startY = std::round(double(buffer.BufferHt - 0.5) * (double)startY / 100.0);
        endY = std::round(double(buffer.BufferHt - 0.5) * (double)endY / 100.0);
        startX = std::max(startX, 0);
        endX = std::min(endX, buffer.BufferWi - 1);
        startY = std::max(startY, 0);
        endY = std::min(endY, buffer.BufferHt - 1);
    }
    int tot = buffer.curPeriod - buffer.curEffStartPer;
    if (!shimmer || (tot % 2) == 0) {
        double HalfHt=double(endY - startY)/2.0;
        double HalfWi=double(endX - startX)/2.0;
        
        orig = color;
        HSVValue hsvOrig = color.asHSV();
        xlColor color2 = color;
        for (x=startX; x <= endX; x++)
        {
            HSVValue hsv = hsvOrig;
            if (HorizFade) {
                if (buffer.allowAlpha) {
                    color.alpha = (double)orig.alpha*(1.0-std::abs(HalfWi-x-startX)/HalfWi);
                } else {
                    hsv.value*=1.0-std::abs(HalfWi-x-startX)/HalfWi;
                    color = hsv;
                }
            }
            color2.alpha = color.alpha;
            for (y=startY; y<=endY; y++) {
                if (VertFade) {
                    if (buffer.allowAlpha) {
                        color.alpha = (double)color2.alpha*(1.0-std::abs(HalfHt-(y-startY))/HalfHt);
                    } else {
                        HSVValue hsv2 = hsv;
                        hsv2.value*=1.0-std::abs(HalfHt-(y-startY))/HalfHt;
                        color = hsv2;
                    }
                }
                buffer.SetPixel(x, y, color);
            }
        }
    } else {
        orig = xlBLACK;
    }
    wxMutexLocker lock(effect->GetBackgroundDisplayList().lock);
    if (VertFade || HorizFade) {
        effect->GetBackgroundDisplayList().resize((buffer.curEffEndPer - buffer.curEffStartPer + 1) * 4 * 2);
        int total = buffer.curEffEndPer - buffer.curEffStartPer + 1;
        double x1 = double(buffer.curPeriod - buffer.curEffStartPer) / double(total);
        double x2 = (buffer.curPeriod - buffer.curEffStartPer + 1.0) / double(total);
        int idx = (buffer.curPeriod - buffer.curEffStartPer) * 8;
        buffer.SetDisplayListVRect(effect, idx, x1, 0.0, x2, 0.5,
                                   xlBLACK, orig);
        buffer.SetDisplayListVRect(effect, idx + 4, x1, 0.5, x2, 1.0,
                                   orig, xlBLACK);
    } else {
        effect->GetBackgroundDisplayList().resize((buffer.curEffEndPer - buffer.curEffStartPer + 1) * 4);
        int midX = (startX + endX) / 2;
        int midY = (startY + endY) / 2;
        buffer.CopyPixelsToDisplayListX(effect, midY, midX, midX);
    }

}
Beispiel #10
0
void TwinkleEffect::Render(Effect *effect, const SettingsMap &SettingsMap, RenderBuffer &buffer) {
    
    int Count = SettingsMap.GetInt("SLIDER_Twinkle_Count", 3);
    int Steps = SettingsMap.GetInt("SLIDER_Twinkle_Steps", 30);
    bool Strobe = SettingsMap.GetBool("CHECKBOX_Twinkle_Strobe", false);
    bool reRandomize = SettingsMap.GetBool("CHECKBOX_Twinkle_ReRandom", false);
    
    int lights = (buffer.BufferHt*buffer.BufferWi)*(Count / 100.0); // Count is in range of 1-100 from slider bar
    int step = 1;
    if (lights > 0) {
        step = buffer.BufferHt*buffer.BufferWi / lights;
    }
    int max_modulo = Steps;
    if (max_modulo<2) 
        max_modulo = 2;  // scm  could we be getting 0 passed in?
    int max_modulo2 = max_modulo / 2;
    if (max_modulo2<1) 
        max_modulo2 = 1;
    
    if(step<1) 
        step=1;
    
    TwinkleRenderCache *cache = (TwinkleRenderCache*)buffer.infoCache[id];
    if (cache == nullptr) {
        cache = new TwinkleRenderCache();
        buffer.infoCache[id] = cache;
    }
    std::vector<StrobeClass> &strobe = cache->strobe;
    
    size_t colorcnt=buffer.GetColorCount();

    int i = 0;

    if (buffer.needToInit) {
        buffer.needToInit = false;
        strobe.clear();
        for (int y=0; y < buffer.BufferHt; y++) {
            for (int x=0; x < buffer.BufferWi; x++) {
                i++;
                if (i%step==1 || step==1) {
                    int s = strobe.size();
                    strobe.resize(s + 1);
                    strobe[s].duration = rand() % max_modulo;
                    
                    strobe[s].x = x;
                    strobe[s].y = y;
                    
                    strobe[s].colorindex = rand() % colorcnt;
                }
            }
        }
    }
    
    for (size_t x = 0; x < strobe.size(); x++) {
        strobe[x].duration++;
        if (strobe[x].duration < 0) {
            continue;
        }
        if (strobe[x].duration == max_modulo) {
            strobe[x].duration = 0;
            if (reRandomize) {
                strobe[x].duration -= rand() % max_modulo2;
                strobe[x].colorindex = rand() % colorcnt;
            }
        }
        int i7 = strobe[x].duration;
        HSVValue hsv;
        buffer.palette.GetHSV(strobe[x].colorindex, hsv);
        double v = hsv.value;
        if(i7<=max_modulo2)
        {
            if(max_modulo2>0) v = (1.0*i7)/max_modulo2;
            else v =0;
        }
        else
        {
            if(max_modulo2>0)v = (max_modulo-i7)*1.0/(max_modulo2);
            else v = 0;
        }
        if(v<0.0) v=0.0;
        
        if(Strobe)
        {
            if(i7==max_modulo2)  v = 1.0;
            else v = 0.0;
        }
        if (buffer.allowAlpha) {
            xlColor color;
            buffer.palette.GetColor(strobe[x].colorindex, color);
            color.alpha = 255.0 * v;
            buffer.SetPixel(strobe[x].x,strobe[x].y,color); // Turn pixel on
        } else {
            buffer.palette.GetHSV(strobe[x].colorindex, hsv);
            //  we left the Hue and Saturation alone, we are just modifiying the Brightness Value
            hsv.value = v;
            buffer.SetPixel(strobe[x].x,strobe[x].y,hsv); // Turn pixel on
        }
    }
}
Beispiel #11
0
void ShockwaveEffect::Render(Effect *effect, const SettingsMap &SettingsMap, RenderBuffer &buffer) {
    int center_x = SettingsMap.GetInt("SLIDER_Shockwave_CenterX", 0);
    int center_y = SettingsMap.GetInt("SLIDER_Shockwave_CenterY", 0);
    int start_radius = SettingsMap.GetInt("SLIDER_Shockwave_Start_Radius", 0);
    int end_radius = SettingsMap.GetInt("SLIDER_Shockwave_End_Radius", 0);
    int start_width = SettingsMap.GetInt("SLIDER_Shockwave_Start_Width", 0);
    int end_width = SettingsMap.GetInt("SLIDER_Shockwave_End_Width", 0);
    int acceleration = SettingsMap.GetInt("SLIDER_Shockwave_Accel", 0);
    bool blend_edges = SettingsMap.GetBool("CHECKBOX_Shockwave_Blend_Edges");

    std::vector< std::vector<double> > temp_colors_pct(buffer.BufferWi, std::vector<double>(buffer.BufferHt));
    double eff_pos = buffer.GetEffectTimeIntervalPosition();
    int num_colors = buffer.palette.Size();
    if( num_colors == 0 )
        num_colors = 1;
    xlColor color, c_old, c_new;
    double eff_pos_adj = buffer.calcAccel(eff_pos, acceleration);

    double blend_pct = 1.0 / (num_colors-1);
    double color_pct1 = eff_pos_adj / blend_pct;
    int color_index = (int)color_pct1;
    blend_pct = color_pct1 - (double)color_index;
    buffer.Get2ColorBlend(color_index, std::min(color_index+1,num_colors-1), std::min( blend_pct, 1.0), color);

    double pos_x = buffer.BufferWi * center_x/100.0;
    double pos_y = buffer.BufferHt * center_y/100.0;

    double radius1 = start_radius;
    double radius2 = end_radius;
    double radius_center = radius1 + (radius2 - radius1) * eff_pos_adj;
    double half_width = (start_width + (end_width - start_width) * eff_pos_adj) / 2.0;
    radius1 = radius_center - half_width;
    radius2 = radius_center + half_width;

    double step = buffer.GetStepAngle(radius1, radius2);

    for( int x = 0; x < buffer.BufferWi; x++ )
    {
        for( int y = 0; y < buffer.BufferHt; y++ )
        {
            temp_colors_pct[x][y] = 0.0;
        }
    }
    buffer.ClearTempBuf();

    for( double current_angle = 0.0; current_angle <= 360.0; current_angle += step )
    {
        for( double r = std::max(0.0, radius1); r <= radius2; r += 0.5 )
        {
            double x1 = buffer.sin(ToRadians(current_angle)) * r + (double)pos_x;
            double y1 = buffer.cos(ToRadians(current_angle)) * r + (double)pos_y;

            if( blend_edges )
            {
                double color_pct = 1.0 - std::abs(r-radius_center)/half_width;
                if( color_pct > 0.0 )
                {
                    if (x1 >= 0 && x1 < buffer.BufferWi && y1 >= 0 && y1 < buffer.BufferHt)
                    {
                        if (buffer.allowAlpha) {
                            color.alpha = 255.0 * color_pct;
                            buffer.SetPixel((int)x1,(int)y1,color);
                        } else {
                            temp_colors_pct[(int)x1][(int)y1] = color_pct;
                            buffer.SetTempPixel((int)x1,(int)y1,color);
                        }
                    }
                }
            }
            else
            {
                buffer.SetPixel((int)x1,(int)y1,color);
            }
        }
    }

    // blend element data into final buffer
    if( blend_edges && !buffer.allowAlpha )
    {
        for( int x = 0; x < buffer.BufferWi; x++ )
        {
            for( int y = 0; y < buffer.BufferHt; y++ )
            {
                if( temp_colors_pct[x][y] > 0.0 )
                {
                    buffer.GetTempPixel(x,y,c_new);
                    buffer.GetPixel(x,y,c_old);
                    buffer.Get2ColorAlphaBlend(c_old, c_new, temp_colors_pct[x][y], color);
                    buffer.SetPixel(x,y,color);
                    temp_colors_pct[x][y] = 0.0;
                }
            }
        }
    }
}
Beispiel #12
0
void PinwheelEffect::Render(Effect *effect, const SettingsMap &SettingsMap, RenderBuffer &buffer) {

    float oset = buffer.GetEffectTimeIntervalPosition();

    int pinwheel_arms = SettingsMap.GetInt("SLIDER_Pinwheel_Arms", 3);
    int pinwheel_twist = GetValueCurveInt("Pinwheel_Twist", 0, SettingsMap, oset);
    int pinwheel_thickness = GetValueCurveInt("Pinwheel_Thickness", 0, SettingsMap, oset);
    bool pinwheel_rotation = SettingsMap.GetBool("CHECKBOX_Pinwheel_Rotation");
    const std::string &pinwheel_3d = SettingsMap["CHOICE_Pinwheel_3D"];
    int xc_adj = GetValueCurveInt("PinwheelXC", 0, SettingsMap, oset);
    int yc_adj = GetValueCurveInt("PinwheelYC", 0, SettingsMap, oset);
    int pinwheel_armsize = GetValueCurveInt("Pinwheel_ArmSize", 100, SettingsMap, oset);
    int pspeed = GetValueCurveInt("Pinwheel_Speed", 10, SettingsMap, oset);
    const std::string &pinwheel_style = SettingsMap["CHOICE_Pinwheel_Style"];

    int xc;
    float tmax;
    HSVValue hsv, hsv1;
    double pos = (buffer.curPeriod - buffer.curEffStartPer) * pspeed * buffer.frameTimeInMs / 50;
    int degrees_per_arm = 1;
    if (pinwheel_arms > 0) degrees_per_arm = 360 / pinwheel_arms;
    float armsize = (pinwheel_armsize / 100.0);

    if (pinwheel_style == "New Render Method")
    {
        std::vector<size_t> colorarray;
        colorarray.resize(pinwheel_arms);
        for (int i = 0; i < pinwheel_arms; i++) { colorarray[i] = i%buffer.GetColorCount(); }

        xc = (int)(ceil(std::hypot(buffer.BufferWi, buffer.BufferHt) / 2));
        xc_adj = xc_adj*buffer.BufferWi / 200;
        yc_adj = yc_adj*buffer.BufferHt / 200;


        int max_radius = xc * armsize;
        if (pinwheel_thickness == 0) pinwheel_thickness = 1;
        tmax = (pinwheel_thickness / 100.0)*degrees_per_arm;

        // Force single visible line in case width is narrower than visible
        float pi_180 = M_PI/180;
        for(int a=0; a<pinwheel_arms; a++)
        {
            int ColorIdx = a%pinwheel_arms;
            xlColor color;
            buffer.palette.GetHSV(colorarray[ColorIdx], hsv);
            color = xlColor(hsv);

            int angle = (a*degrees_per_arm);
            if (pinwheel_rotation == 1) // do we have CW rotation
            {
                angle = (270 - angle) + pos;
            } else {
                angle = angle - 90 - pos;
            }
            int x,y, degrees_twist;
            for (float r=0; r<=max_radius; r+=0.5)
            {
                degrees_twist = (r/max_radius) * pinwheel_twist;
                int t2 = (int)angle%degrees_per_arm;
                double round = (float)t2 / (float)tmax;
                x = floor((int)(r * buffer.cos((angle + degrees_twist) * pi_180)) + xc_adj + buffer.BufferWi / 2);
                y = floor((int)(r * buffer.sin((angle + degrees_twist) * pi_180)) + yc_adj + buffer.BufferHt / 2);
                if (buffer.palette.IsSpatial(colorarray[ColorIdx]))
                {
                    buffer.palette.GetSpatialColor(colorarray[ColorIdx], xc_adj + buffer.BufferWi / 2, yc_adj + buffer.BufferHt / 2, x, y, round, max_radius, color);
                }
                buffer.SetPixel(x,y,color);
            }
        }

        // Draw actual pinwheel arms
        for (int x = 0; x < buffer.BufferWi; x++)
        {
            int x1 = x - xc_adj - (buffer.BufferWi / 2);
            for (int y = 0; y < buffer.BufferHt; y++)
            {
                int y1 = y - yc_adj - (buffer.BufferHt / 2);
                double r = std::hypot(x1, y1);
                if (r <= max_radius) {
                    double degrees_twist = (r / max_radius)*pinwheel_twist;
                    double theta = (std::atan2(x1, y1) * 180 / 3.14159) + degrees_twist;
                    if (pinwheel_rotation == 1) // do we have CW rotation
                    {
                        theta = pos + theta + (tmax/2);
                    } else {
                        theta = pos - theta + (tmax/2);
                    }
                    theta = theta + 540.0;
                    int t2 = (int)theta%degrees_per_arm;
                    if (t2 <= tmax) {
                        double round = (float)t2 / (float)tmax;
                        t2 = std::abs(t2 - (tmax/2)) * 2;
                        xlColor color;
                        int ColorIdx2 = ((int)((theta/degrees_per_arm)))%pinwheel_arms;
                        if (buffer.palette.IsSpatial(colorarray[ColorIdx2]))
                        {
                            buffer.palette.GetSpatialColor(colorarray[ColorIdx2], xc_adj + buffer.BufferWi / 2, yc_adj + buffer.BufferHt / 2, x, y, round, max_radius, color);
                            hsv = color.asHSV();
                        } else {
                            buffer.palette.GetHSV(colorarray[ColorIdx2], hsv);
                        }
                        hsv1=hsv;
                        color = xlColor(hsv1);
                        if(pinwheel_3d=="3D")
                        {
                            if (buffer.allowAlpha) {
                                color.alpha = 255.0 * ((tmax - t2) / tmax);
                            }
                            else {
                                hsv1.value = hsv.value * ((tmax - t2) / tmax);
                                color = hsv1;
                            }
                        }
                        else if (pinwheel_3d == "3D Inverted")
                        {
                            if (buffer.allowAlpha) {
                                color.alpha = 255.0 * ((t2) / tmax);
                            }
                            else {
                                hsv1.value = hsv.value * ((t2) / tmax);
                                color = hsv1;
                            }
                        }
                        buffer.SetPixel(x, y, color);
                    }
                }
            }
        }
    } else { // Old Render Method
        int a,xc,ColorIdx,base_degrees;
        float t,tmax;
        float radius;
        HSVValue hsv,hsv0,hsv1;
        size_t colorcnt=buffer.GetColorCount();

        xc= (int)(std::max(buffer.BufferWi, buffer.BufferHt)/2);
        radius = xc/100.0;

        for(a=1; a<=pinwheel_arms; a++)
        {
            ColorIdx=a%colorcnt;
            buffer.palette.GetHSV(ColorIdx, hsv); // Now go and get the hsv value for this ColorIdx
            if(pinwheel_rotation==1) // do we have CW rotation
            {
                base_degrees = (a-1)*degrees_per_arm + pos; // yes
            }
            else
            {
                base_degrees = (a-1)*degrees_per_arm - pos; // no, we are CCW
            }
            Draw_arm(buffer, base_degrees, xc*armsize, pinwheel_twist,hsv,xc_adj,yc_adj);
            if(pinwheel_thickness>0)
            {
                tmax= (pinwheel_thickness/100.0)*degrees_per_arm/2.0;
                hsv1=hsv;
                xlColor color(hsv1);
                for (t=1; t<=tmax; t++)
                {
                    if(pinwheel_3d=="3D")
                    {
                        if (buffer.allowAlpha) {
                            color.alpha = 255.0 * ((tmax-t)/tmax);
                        } else {
                            hsv1.value = hsv.value * ((tmax-t)/tmax);
                            color = hsv1;
                        }
                    }
                    else if(pinwheel_3d=="3D Inverted")
                    {
                        if (buffer.allowAlpha) {
                            color.alpha = 255.0 * ((t)/tmax);
                        } else {
                            hsv1.value = hsv.value * ((t)/tmax);
                            color = hsv1;
                        }
                    }
                    Draw_arm(buffer, base_degrees-t, xc*armsize, pinwheel_twist,color,xc_adj,yc_adj);
                    Draw_arm(buffer, base_degrees+t, xc*armsize, pinwheel_twist,color,xc_adj,yc_adj);
                }
            }
        }
    }
}
Beispiel #13
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);
            }
        }
    }
}