Example #1
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);
                }
            }
        }
    }

}
Example #2
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);
        }
    }
}
Example #3
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;
                }
            }
        }
    }
}