コード例 #1
0
ファイル: RgbEffects.cpp プロジェクト: josephcsible/xLights
RgbEffects::RgbEffects()
{
    //ctor
    // initialize FirePalette[]
    wxImage::HSVValue hsv;
    wxImage::RGBValue rgb;
    int i;
    // calc 100 reds, black to bright red
    hsv.hue=0.0;
    hsv.saturation=1.0;
    for (i=0; i<100; i++)
    {
        hsv.value=double(i)/100.0;
        rgb = wxImage::HSVtoRGB(hsv);
        FirePalette.push_back(xlColor(rgb));
    }

    // gives 100 hues red to yellow
    hsv.value=1.0;
    for (i=0; i<100; i++)
    {
        rgb = wxImage::HSVtoRGB(hsv);
        FirePalette.push_back(xlColor(rgb));
        hsv.hue+=0.00166666;
    }
}
コード例 #2
0
ファイル: PixelBuffer.cpp プロジェクト: josephcsible/xLights
void PixelBufferClass::SetPalette(int layer, wxColourVector& newcolors)
{
    xlColorVector p2;
    for (int x = 0; x < newcolors.size(); x++)
    {
        p2.push_back(xlColor(newcolors[x]));
    }
    Effect[layer].SetPalette(p2);
}
コード例 #3
0
ファイル: xlPoints.c プロジェクト: dotNetTest/openxl
void
myParticlesActorDrawPoint(void *user)
{
	XLuint id = xlGetInteger(XL_PARTICLES_PARTICLE);
	XLpoint *point;
	XLcolor *color;
	XLenum c;

	point = xlGetPoint(XL_POINT_DIRECTION_FIRST + id);
	c = XL_COLOR_FIRST + id;
	color = xlGetColor(c >= XL_COLOR_BLACK ? c + 1 : c);
	glPushMatrix();
	xlScale(xlVectorAssignMultReal(xlVectorTMP, xlVectorOne, XL_REAL(10)));
	xlColor(color);
	glBegin(GL_POINTS);
	xlVertex(point);
	glEnd();
	glPopMatrix();
}
コード例 #4
0
ファイル: xlPairs.c プロジェクト: dotNetTest/openxl
void
myParticlesActorDrawPair(void *user)
{
	XLuint particle;
	XLpair *pair;
	XLcolor *color;
	XLenum c;

	particle = xlGetInteger(XL_PARTICLES_PARTICLE);
	pair = xlGetPair(XL_PAIR_DIRECTION_FIRST + particle);
	c = XL_COLOR_FIRST + particle;
	color = xlGetColor(c >= XL_COLOR_BLACK ? c + 1 : c);

	glPushMatrix();
	xlScale(xlVectorAssignMultReal(xlVectorTMP, xlVectorOne, XL_REAL(10)));
	xlColor(color);
	glBegin(GL_POINTS);
	xlVertex2(pair);
	glEnd();
	glPopMatrix();
}
コード例 #5
0
void StateEffect::RenderState(RenderBuffer &buffer,
                             SequenceElements *elements, const std::string &faceDefinition,
                             const std::string& Phoneme, const std::string &trackName, const std::string& mode, const std::string& colourmode)
{
    if (buffer.needToInit) {
        buffer.needToInit = false;
        elements->AddRenderDependency(trackName, buffer.cur_model);
    
        if (buffer.isTransformed)
        {
            log4cpp::Category &logger_base = log4cpp::Category::getInstance(std::string("log_base"));
            logger_base.warn("State effect starting at %dms until %dms on model %s has a transformed buffer. This may not work as expected.", buffer.curEffStartPer * buffer.frameTimeInMs, buffer.curEffEndPer * buffer.frameTimeInMs, (const char *)buffer.cur_model.c_str());
        }
    }

    Element *track = elements->GetElement(trackName);
    std::recursive_mutex tmpLock;
    std::recursive_mutex *lock = &tmpLock;
    if (track != nullptr) {
        lock = &track->GetChangeLock();
    }
    std::unique_lock<std::recursive_mutex> locker(*lock);

    if (buffer.cur_model == "") {
        return;
    }

    Model* model_info = buffer.frame->AllModels[buffer.cur_model];
    if (model_info == nullptr) {
        return;
    }

    std::string definition = faceDefinition;
    bool found = true;
    std::map<std::string, std::map<std::string, std::string> >::iterator it = model_info->stateInfo.find(definition);
    if (it == model_info->stateInfo.end()) {
        //not found
        found = false;
    }
    if (!found) {
        if ("Coro" == definition && model_info->stateInfo.find("SingleNode") != model_info->stateInfo.end()) {
            definition = "SingleNode";
            found = true;
        } else if ("SingleNode" == definition && model_info->stateInfo.find("Coro") != model_info->stateInfo.end()) {
            definition = "Coro";
            found = true;
        }
    }

    if (definition == "")
    {
        return;
    }

    std::string modelType = found ? model_info->stateInfo[definition]["Type"] : definition;
    if (modelType == "") {
        modelType = definition;
    }

    int type = 1;

    if ("SingleNode" == modelType) {
        type = 0;
    } else if ("NodeRange" == modelType) {
        type = 1;
    }

    std::string tstates = Phoneme;
    int intervalnumber = 0;
    //GET label from timing track
    int startms = -1;
    int endms = -1;
    int posms = -1;
    if (tstates == "") {

        // if we dont have a track then exit
        if (track == NULL)
        {
            return;
        }

        EffectLayer *layer = track->GetEffectLayer(0);
        std::unique_lock<std::recursive_mutex> locker(layer->GetLock());
        int time = buffer.curPeriod * buffer.frameTimeInMs + 1;
        posms = buffer.curPeriod * buffer.frameTimeInMs;
        Effect *ef = layer->GetEffectByTime(time);
        if (ef == nullptr) {
            tstates = "";
        }
        else {
            startms = ef->GetStartTimeMS();
            endms = ef->GetEndTimeMS();
            tstates = ef->GetEffectName();
        }

        ef = layer->GetEffectByTime(buffer.curEffStartPer * buffer.frameTimeInMs + 1);
        while (ef != NULL && ef->GetStartTimeMS() <= time)
        {
            intervalnumber++;
            int endtime = ef->GetEndTimeMS();
            ef = layer->GetEffectByTime(endtime + 1);
            if (ef == NULL)
            {
                ef = layer->GetEffectAfterTime(endtime + 1);
            }
        }
    }

    std::vector<std::string> sstates;

    if (mode == "Default" || startms == -1)
    {
        wxString ss = wxString(tstates);
        wxStringTokenizer tkz(ss, wxT(" ,;:"));
        while (tkz.HasMoreTokens())
        {
            wxString token = tkz.GetNextToken();
            sstates.push_back(token.Lower().ToStdString());
        }
    }
    else if (mode == "Countdown")
    {
        // tstates should contain the starting number
        int val = wxAtoi(tstates);

        val = val * 1000;
        int subtracttime = (posms - startms);
        val = val - subtracttime;
        val = val / 1000;

        int v = val;
        bool force = false;
        if ((v / 1000) * 1000 > 0)
        {
            sstates.push_back(wxString::Format("%d", (v / 1000) * 1000).ToStdString());
            force = true;
        }
        v = v - (v / 1000) * 1000;
        if ((v / 100) * 100 > 0)
        {
            sstates.push_back(wxString::Format("%d", (v / 100) * 100).ToStdString());
            force = true;
        }
        else
        {
            if (force)
            {
                sstates.push_back("000");
            }
        }
        v = v - (v / 100) * 100;
        if ((v / 10) * 10 > 0)
        {
            sstates.push_back(wxString::Format("%d", (v / 10) * 10).ToStdString());
        }
        else
        {
            if (force)
            {
                sstates.push_back("00");
            }
        }
        v = v - (v / 10) * 10;
        sstates.push_back(wxString::Format("%d", v).ToStdString());
    }
    else if (mode == "Time Countdown")
    {
        wxDateTime dt;
        dt.ParseFormat(tstates.c_str(), "%H:%M:%S");

        if (!dt.IsValid())
        {
            dt.ParseFormat(tstates.c_str(), "%M:%S");
        }

        if (dt.IsValid())
        {
            dt.Subtract(wxTimeSpan(0, 0, 0, (buffer.curPeriod - buffer.curEffStartPer) * buffer.frameTimeInMs));
            int m = dt.GetMinute();
            if ((m / 10) * 1000 > 0)
            {
                sstates.push_back(wxString::Format("%d", (m / 10) * 1000).ToStdString());
            }
            else
            {
                sstates.push_back("0000");
            }
            m = m - (m / 10) * 10;
            if (m * 100 > 0)
            {
                sstates.push_back(wxString::Format("%d", m * 100).ToStdString());
            }
            else
            {
                sstates.push_back("000");
            }
            int s = dt.GetSecond();
            if ((s / 10) * 10 > 0)
            {
                sstates.push_back(wxString::Format("%d", (s / 10) * 10).ToStdString());
            }
            else
            {
                sstates.push_back("00");
            }
            s = s - (s / 10) * 10;
            sstates.push_back(wxString::Format("%d", s).ToStdString());
        }
        sstates.push_back("colon");
    }
    else if (mode == "Number") // used for FM frequencies
    {
        double f = wxAtof(tstates);
        sstates.push_back("dot");
        double f2 = f - int(f);
        f2 = (int)(f2 * 10 + 0.5);
        sstates.push_back(wxString::Format("%d", (int)f2).ToStdString());

        int v = f;
        bool force = false;
        if ((v / 100) * 1000 > 0)
        {
            sstates.push_back(wxString::Format("%d", (v / 100) * 1000).ToStdString());
            force = true;
        }
        v = v - (v / 100) * 100;
        if ((v / 10) * 100 > 0)
        {
            sstates.push_back(wxString::Format("%d", (v / 10) * 100).ToStdString());
        }
        else
        {
            if (force)
            {
                sstates.push_back("000");
            }
        }
        v = v - (v / 10) * 10;
        if (v * 10 > 0)
        {
            sstates.push_back(wxString::Format("%d", v * 10).ToStdString());
        }
        else
        {
            sstates.push_back("00");
        }
    }
    else if (mode == "Iterate")
    {
        float progressthroughtimeinterval = ((float)posms - (float)startms) / ((float)endms - (float)startms);

        std::vector<std::string> tmpstates;
        wxString ss = wxString(tstates);
        wxStringTokenizer tkz(ss, wxT(" ,;:"));
        while (tkz.HasMoreTokens())
        {
            wxString token = tkz.GetNextToken();
            tmpstates.push_back(token.Lower().ToStdString());
        }

        int which = tmpstates.size() * progressthroughtimeinterval;

        if (which < sstates.size())
        {
            sstates.push_back(tmpstates[which]);
        }
    }

    bool customColor = found ? model_info->stateInfo[definition]["CustomColors"] == "1" : false;

    // process each token
    for (size_t i = 0; i < sstates.size(); i++)
    {
        // get the channels
        std::string statename = FindState(model_info->stateInfo[definition], sstates[i]);
        std::string channels = model_info->stateInfo[definition][statename];

        if (statename != "" && channels != "")
        {
            xlColor color;
            if (colourmode == "Graduate")
            {
                buffer.GetMultiColorBlend(buffer.GetEffectTimeIntervalPosition(), false, color);
            }
            else if (colourmode == "Cycle")
            {
                buffer.palette.GetColor((intervalnumber - 1) % buffer.GetColorCount(), color);
            }
            else
            {
                // allocate
                int statenum = wxAtoi(statename.substr(1));
                buffer.palette.GetColor((statenum - 1) % buffer.GetColorCount(), color);
            }
            if (customColor) {
                std::string cname = model_info->stateInfo[definition][statename + "-Color"];
                if (cname == "") {
                    color = xlWHITE;
                }
                else {
                    color = xlColor(cname);
                }
            }

            wxStringTokenizer wtkz(channels, ",");
            while (wtkz.HasMoreTokens())
            {
                wxString valstr = wtkz.GetNextToken();

                if (type == 0) {
                    for (size_t n = 0; n < model_info->GetNodeCount(); n++) {
                        wxString nn = model_info->GetNodeName(n, true);
                        if (nn == valstr) {
                            for (auto a = buffer.Nodes[n]->Coords.begin() ; a != buffer.Nodes[n]->Coords.end(); a++) {
                                buffer.SetPixel(a->bufX, a->bufY, color);
                            }
                        }
                    }
                }
                else if (type == 1) {
                    int start, end;
                    if (valstr.Contains("-")) {
                        int idx = valstr.Index('-');
                        start = wxAtoi(valstr.Left(idx));
                        end = wxAtoi(valstr.Right(valstr.size() - idx - 1));
                    }
                    else {
                        start = end = wxAtoi(valstr);
                    }
                    if (start > end) {
                        start = end;
                    }
                    start--;
                    end--;
                    for (int n = start; n <= end; n++) {
                        if (n < buffer.Nodes.size()) {
                            for (auto a = buffer.Nodes[n]->Coords.begin() ; a != buffer.Nodes[n]->Coords.end(); a++) {
                                buffer.SetPixel(a->bufX, a->bufY, color);
                            }
                        }
                    }
                }
            }
        }
    }
}
コード例 #6
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);
                }
            }
        }
    }
}
コード例 #7
0
void OnEffect::Render(Effect *eff, const SettingsMap &SettingsMap, RenderBuffer &buffer) {
    int start = SettingsMap.GetInt(TEXTCTRL_Eff_On_Start, 100);
    int end = SettingsMap.GetInt(TEXTCTRL_Eff_On_End, 100);
    bool shimmer = SettingsMap.GetInt(CHECKBOX_On_Shimmer, 0) > 0;
    float cycles = SettingsMap.GetDouble(TEXTCTRL_On_Cycles, 1.0);
    int x,y;
    int cidx = 0;
    if (shimmer) {
        int tot = buffer.curPeriod - buffer.curEffStartPer;
        if (tot % 2) {
            if (buffer.palette.Size() <= 1) {
                return;
            }
            cidx = 1;
        }
    }

    bool spatialcolour = buffer.palette.IsSpatial(cidx);

    double adjust = buffer.GetEffectTimeIntervalPosition(cycles);

    xlColor color;
    if (start == 100 && end == 100) {
        buffer.palette.GetColor(cidx, color);
    } else {
        HSVValue hsv;
        buffer.palette.GetHSV(cidx,hsv);
        double d = adjust;
        d = start + (end - start) * d;
        d = d / 100.0;
        hsv.value = hsv.value * d;
        color = hsv;
    }
    
    int transparency = GetValueCurveInt("On_Transparency", 0, SettingsMap, adjust);
    if (transparency) {
        transparency *= 255;
        transparency /= 100;
        color.alpha = 255 - transparency;
    }

    ///////////////////////// DMX Support ////////////////////////
    // if the model is a DMX model this will write the color into
    // the proper red, green, and blue channels.
    //////////////////////////////////////////////////////////////
    if (buffer.cur_model != "") {
        Model* model_info = buffer.frame->AllModels[buffer.cur_model];
        if (model_info != nullptr) {
            if( model_info->GetDisplayAs() == "DMX" ) {
                xlColor c;
                DmxModel* dmx = (DmxModel*)model_info;
                int red_channel = dmx->GetRedChannel();
                int grn_channel = dmx->GetGreenChannel();
                int blu_channel = dmx->GetBlueChannel();
                if( red_channel != 0 ) {
                    c.red = color.red;
                    c.green = color.red;
                    c.blue = color.red;
                    buffer.SetPixel(red_channel-1, 0, c);
                }
                if( grn_channel != 0 ) {
                    c.red = color.green;
                    c.green = color.green;
                    c.blue = color.green;
                    buffer.SetPixel(grn_channel-1, 0, c);
                }
                if( blu_channel != 0 ) {
                    c.red = color.blue;
                    c.green = color.blue;
                    c.blue = color.blue;
                    buffer.SetPixel(blu_channel-1, 0, c);
                }
                return;
            }
        }
    }
    //////////////////////////////////////////////////////////////
    ///////////////////// End DMX Support ////////////////////////
    //////////////////////////////////////////////////////////////

    //Every Node set to selected color
    for (x=0; x<buffer.BufferWi; x++)
    {
        for (y=0; y<buffer.BufferHt; y++)
        {
            if (spatialcolour)
            {
                buffer.palette.GetSpatialColor(cidx, (float)x / (float)buffer.BufferWi, (float)y / (float)buffer.BufferHt, color);
                if (start == 100 && end == 100) {
                }
                else {
                    HSVValue hsv = color.asHSV();
                    double d = adjust;
                    d = start + (end - start) * d;
                    d = d / 100.0;
                    hsv.value = hsv.value * d;
                    color = hsv;
                }
                if (transparency) {
                    color.alpha = 255 - transparency;
                }
            }

            buffer.SetPixel(x,y,color);
        }
    }

    if (shimmer || cycles != 1.0) {
        std::lock_guard<std::recursive_mutex> lock(eff->GetBackgroundDisplayList().lock);
        eff->GetBackgroundDisplayList().resize((buffer.curEffEndPer - buffer.curEffStartPer + 1) * 6);
        buffer.CopyPixelsToDisplayListX(eff, 0, 0, 0);
    } else if (buffer.needToInit) {
        std::lock_guard<std::recursive_mutex> lock(eff->GetBackgroundDisplayList().lock);
        eff->GetBackgroundDisplayList().resize(6);
        if (start == 100 && end == 100) {
            buffer.palette.GetColor(0, color);
            buffer.SetDisplayListHRect(eff, 0, 0.0, 0.0, 1.0, 1.0, color, color);
        } else {
            HSVValue hsv;
            buffer.palette.GetHSV(cidx,hsv);
            hsv.value = hsv.value * start / 100.0;
            color = hsv;

            buffer.palette.GetHSV(cidx,hsv);
            hsv.value = hsv.value * end / 100.0;
            buffer.SetDisplayListHRect(eff, 0, 0.0, 0.0, 1.0, 1.0, color, xlColor(hsv));
        }
        buffer.needToInit = false;
    }
}