void SettingsManager::saveSettings(const SettingsMap &settingsMap) { QStringList keys = settingsMap.keys(); foreach (QString key, keys) _settings->setValue(key, settingsMap.value(key)); _settings->sync(); }
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") ); }
SettingsMap SettingsManager::settings() const { QStringList keys = _settings->allKeys(); SettingsMap map; foreach (QString key, keys) map.insert(key, _settings->value(key)); return map; }
tribool init_internal_subsystems(GameEngine &engine, const SettingsMap &settings){ auto flags = settings.count(settings::subsystems_flags)? settings.at(settings::subsystems_flags) == settings::subsystems_init_all? INIT_EVERYTHING : stoul(settings.at(settings::subsystems_flags)) : 0; BOOST_LOG_TRIVIAL(trace) << "Initializing game engine: calling #init_internal_subsystems (flags: " << flags << ")"; return init_internal_subsystems(engine, flags); }
double RenderableEffect::GetValueCurveDouble(wxString name, double def, const SettingsMap &SettingsMap, float offset) { double res = SettingsMap.GetDouble("TEXTCTRL_" + name, def); wxString vc = SettingsMap.Get("VALUECURVE_" + name, ""); if (vc != "") { ValueCurve valc(vc.ToStdString()); if (valc.IsActive()) { res = valc.GetOutputValueAt(offset); } } return res; }
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 } } }
TEST(TestSettingsMap, HandleAll) { SettingsMap t; t.set("foo", "kittens"); t.set("object", folly::dynamic::object("test", "ok")); EXPECT_TRUE(t.get("foo").isString()); EXPECT_TRUE(t.get("invalid_key").empty()); EXPECT_EQ(2, t.get("invalid_key", {1, 2}).size()); EXPECT_THROW(t.require("invalid_key"), runtime_error); EXPECT_TRUE(t.get("object").isObject()); EXPECT_EQ(t.require("object")["test"], "ok"); }
void TendrilEffect::Render(Effect *effect, const SettingsMap &SettingsMap, RenderBuffer &buffer) { Render(buffer, SettingsMap.GetInt("TEXTCTRL_Tendril_Movement", 1), SettingsMap.GetInt("TEXTCTRL_Tendril_TuneMovement", 10), SettingsMap.GetInt("TEXTCTRL_Tendril_Speed", 10), SettingsMap.GetInt("TEXTCTRL_Tendril_Thickness", 1), SettingsMap.GetFloat("TEXTCTRL_Tendril_Friction", 10) / 20 * 0.2 + 0.4, // 0.4->0.6 but on screen 0-20: def 0.5 SettingsMap.GetFloat("TEXTCTRL_Tendril_Dampening", 10) / 20 * 0.5, // 0->0.5 but on screen 0-20: def 0.25 SettingsMap.GetFloat("TEXTCTRL_Tendril_Tension", 20) / 39 * 0.039 + 0.96, // 0.960->0.999 but on screen 0->39: def 0.980 SettingsMap.GetInt("TEXTCTRL_Tendril_Trails", 1), SettingsMap.GetInt("TEXTCTRL_Tendril_Length", 60) ); }
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) ); }
void StateEffect::Render(Effect *effect, const SettingsMap &SettingsMap, RenderBuffer &buffer) { RenderState(buffer, effect->GetParentEffectLayer()->GetParentElement()->GetSequenceElements(), SettingsMap.Get("CHOICE_State_StateDefinition", ""), SettingsMap["CHOICE_State_State"], SettingsMap["CHOICE_State_TimingTrack"], SettingsMap["CHOICE_State_Mode"], SettingsMap["CHOICE_State_Color"] ); }
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; }
static void clear( SettingsMap &cache, SettingsMap &overrides, const QString &myKey) { // Do the actual clearing.. SettingsMap::iterator it = cache.find(myKey); if (it != cache.end()) { SettingsMap::const_iterator oit = overrides.find(myKey); if (oit == overrides.end()) { LOG(VB_DATABASE, LOG_INFO, QString("Clearing Settings Cache for '%1'.").arg(myKey)); cache.erase(it); } else { LOG(VB_DATABASE, LOG_INFO, QString("Clearing Cache of overridden '%1' ignored.") .arg(myKey)); } } }
void LDViewExportOption::resetSettings(SettingsMap &settings) { SettingsMap::const_iterator it; QString value; for (it = settings.begin(); it != settings.end(); it++) { LDExporterSetting *setting = it->first; setting->reset(); switch (setting->getType()) { case LDExporterSetting::TBool: if (strcmp(it->second->metaObject()->className(), "QGroupBox") == 0) { ((QGroupBox *)it->second)->setChecked(setting->getBoolValue()); } else { ((QCheckBox *)it->second)->setChecked(setting->getBoolValue()); } break; case LDExporterSetting::TLong: case LDExporterSetting::TFloat: case LDExporterSetting::TString: ucstringtoqstring(value, setting->getStringValue()); ((QLineEdit *)it->second)->setText(value); break; case LDExporterSetting::TEnum: ((QComboBox *)it->second)->setCurrentIndex( setting->getSelectedOption()); break; default: // No default, but gets rid of warnings. break; } } }
std::list<std::string> StateEffect::CheckEffectSettings(const SettingsMap& settings, AudioManager* media, Model* model, Effect* eff) { std::list<std::string> res; // -Buffer not rotated wxString bufferTransform = settings.Get("B_CHOICE_BufferTransform", "None"); if (bufferTransform != "None") { res.push_back(wxString::Format(" WARN: State effect with transformed buffer '%s' may not render correctly. Model '%s', Start %s", model->GetName(), bufferTransform, FORMATTIME(eff->GetStartTimeMS())).ToStdString()); } wxString timing = settings.Get("E_CHOICE_State_TimingTrack", ""); wxString state = settings.Get("E_CHOICE_State_State", ""); // - Face chosen or specific phoneme if (state == "" && timing == "") { res.push_back(wxString::Format(" ERR: State effect with no timing selected. Model '%s', Start %s", model->GetName(), FORMATTIME(eff->GetStartTimeMS())).ToStdString()); } return res; }
TEST(TestSettingsMap, HandleConvert) { SettingsMap t; t.set("foo", "kittens"); t.set("bar", "moo"); t.set("int", "5"); t.set("double", 5.5); t.set("true", true); t.set("false", "false"); EXPECT_EQ("kittens", t.convert<string>("foo")); EXPECT_EQ("moo", t.convert<string>("bar")); EXPECT_EQ("default", t.convert<string>("invalid_key", "default")); EXPECT_EQ(5, t.convert<int>("int")); EXPECT_EQ(5.5, t.convert<double>("double")); EXPECT_EQ(77, t.convert<int>("missing", 77)); EXPECT_TRUE(t.convert<bool>("true")); EXPECT_FALSE(t.convert<bool>("false")); }
void init_window(GameEngine &engine, const SettingsMap &settings){ size_t width = stoul(settings.count(settings::window_width)? settings.at(settings::window_width) : settings::window_width_example); size_t height = stoul(settings.count(settings::window_height)? settings.at(settings::window_height) : settings::window_height_example); const char *title = settings.count(settings::window_title)? settings.at(settings::window_title).c_str() : settings::window_title_example; BOOST_LOG_TRIVIAL(trace) << "Initializing game engine: calling #init_window" << "(width: " << width << ", height: " << height << ")"; init_window(engine, width, height, title); }
int RenderableEffect::GetValueCurveInt(wxString name, int def, const SettingsMap &SettingsMap, float offset) { int res = def; if (SettingsMap.Contains("SLIDER_" + name)) { res = SettingsMap.GetInt("SLIDER_" + name, def); } else if (SettingsMap.Contains("TEXTCTRL_" + name)) { res = SettingsMap.GetInt("TEXTCTRL_" + name, def); } if (SettingsMap.Contains("VALUECURVE_" + name)) { wxString vc = SettingsMap.Get("VALUECURVE_" + name, ""); ValueCurve valc(vc.ToStdString()); if (valc.IsActive()) { res = valc.GetOutputValueAt(offset); } } return res; }
void GarlandsEffect::Render(Effect *effect, const SettingsMap &SettingsMap, RenderBuffer &buffer) { int GarlandType = SettingsMap.GetInt("SLIDER_Garlands_Type", 0); int Spacing = SettingsMap.GetInt("SLIDER_Garlands_Spacing", 0); float cycles = SettingsMap.GetDouble("TEXTCTRL_Garlands_Cycles", 1.0); if (Spacing < 1) { Spacing = 1; } int x,y,yadj,ylimit,ring; double ratio; xlColor color; int dir = GetDirection(SettingsMap.Get("CHOICE_Garlands_Direction", "Up")); double position = buffer.GetEffectTimeIntervalPosition(cycles); if (dir > 3) { dir -= 4; if (position > 0.5) { position = (1.0 - position) * 2.0; } else { position *= 2.0; } } int buffMax = buffer.BufferHt; int garlandWid = buffer.BufferWi; if (dir > 1) { buffMax = buffer.BufferWi; garlandWid = buffer.BufferHt; } double PixelSpacing=Spacing*buffMax/100.0; if (PixelSpacing < 2.0) PixelSpacing=2.0; double total = buffMax * PixelSpacing - buffMax + 1; double positionOffset = total * position; for (ring = 0; ring < buffMax; ring++) { ratio=double(buffMax-ring-1)/double(buffMax); buffer.GetMultiColorBlend(ratio, false, color); y = 1.0 + ring*PixelSpacing - positionOffset; ylimit=ring; for (x=0; x<garlandWid; x++) { yadj=y; switch (GarlandType) { case 1: switch (x%5) { case 2: yadj-=2; break; case 1: case 3: yadj-=1; break; } break; case 2: switch (x%5) { case 2: yadj-=4; break; case 1: case 3: yadj-=2; break; } break; case 3: switch (x%6) { case 3: yadj-=6; break; case 2: case 4: yadj-=4; break; case 1: case 5: yadj-=2; break; } break; case 4: switch (x%5) { case 1: case 3: yadj-=2; break; } break; } if (yadj < ylimit) yadj=ylimit; if (yadj < buffMax) { if (dir == 1 || dir == 2) { yadj = buffMax - yadj - 1; } if (dir > 1) { buffer.SetPixel(yadj,x,color); } else { buffer.SetPixel(x,yadj,color); } } } } }
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--; } }
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); } } }
void StrobeEffect::Render(Effect *effect, const SettingsMap &SettingsMap, RenderBuffer &buffer) { int Number_Strobes = SettingsMap.GetInt("SLIDER_Number_Strobes", 1); int StrobeDuration = SettingsMap.GetInt("SLIDER_Strobe_Duration", 1); int Strobe_Type = SettingsMap.GetInt("SLIDER_Strobe_Type", 0); StrobeRenderCache *cache = (StrobeRenderCache*)buffer.infoCache[id]; if (cache == nullptr) { cache = new StrobeRenderCache(); buffer.infoCache[id] = cache; } std::vector<StrobeClass> &strobe = cache->strobe; if (StrobeDuration == 0) { StrobeDuration = 1; } if (buffer.needToInit) { buffer.needToInit = false; strobe.resize(StrobeDuration * Number_Strobes); for (int x = 0; x < strobe.size(); x++) { strobe[x].duration = -1; } } int offset = ((buffer.curPeriod-buffer.curEffStartPer) % StrobeDuration) * Number_Strobes; int ColorIdx; StrobeClass m; HSVValue hsv; size_t colorcnt=buffer.GetColorCount(); // create new strobe, randomly place a strobe for(int i = 0; i < Number_Strobes; i++) { strobe[offset + i].x =rand() % buffer.BufferWi; // randomly pick a x,y location for strobe to fire strobe[offset + i].y =rand() % buffer.BufferHt; strobe[offset + i].duration = StrobeDuration; ColorIdx=rand()%colorcnt; buffer.palette.GetHSV(ColorIdx, strobe[offset + i].hsv); // take first checked color as color of flash buffer.palette.GetColor(ColorIdx, strobe[offset + i].color); // take first checked color as color of flash } // render strobe, we go through all storbes and decide if they should be turned on int x,y,n=0; for (std::vector<StrobeClass>::iterator it=strobe.begin(); it!=strobe.end(); ++it) { n++; hsv=it->hsv; xlColor color(it->color); x=it->x; y=it->y; if(it->duration > 0) { buffer.SetPixel(x,y,color); } double v = 1.0; if(it->duration==1) { v = 0.5; } else if(it->duration==2) { v = 0.75; } if (buffer.allowAlpha) { color.alpha = 255.0 * v; } else { hsv.value *= v; color = hsv; } if(Strobe_Type==2) { int r = rand()%2; if(r==0) { buffer.SetPixel(x,y-1,color); buffer.SetPixel(x,y+1,color); } else { buffer.SetPixel(x-1,y,color); buffer.SetPixel(x+1,y,color); } } if(Strobe_Type==3) { buffer.SetPixel(x,y-1,color); buffer.SetPixel(x,y+1,color); buffer.SetPixel(x-1,y,color); buffer.SetPixel(x+1,y,color); } if(Strobe_Type==4) { int r = rand()%2; if(r==0) { buffer.SetPixel(x,y-1,color); buffer.SetPixel(x,y+1,color); buffer.SetPixel(x-1,y,color); buffer.SetPixel(x+1,y,color); } else { buffer.SetPixel(x+1,y-1,color); buffer.SetPixel(x+1,y+1,color); buffer.SetPixel(x-1,y-1,color); buffer.SetPixel(x-1,y+1,color); } } it->duration--; // decrease the frame counter on this strobe, when it gets to zero we no longer will turn it on } }
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; } }
void RenderableEffect::AdjustSettingsToBeFitToTime(int effectIdx, SettingsMap &settings, int startMS, int endMS, xlColorVector &colors) { if (effectIdx == EffectManager::eff_FACES && settings.Get("E_CHOICE_Faces_FaceDefinition", "") == "" && settings.Get("E_CHOICE_Faces_TimingTrack", "") == "") { settings["E_CHOICE_Faces_FaceDefinition"] = "xlights_papagayo.xml"; } int ftt = wxAtoi(settings.Get("T_CHECKBOX_FitToTime", "1")); switch (effectIdx) { //these effects have never used the FitToTime or speed settings, nothing to do case EffectManager::eff_OFF: case EffectManager::eff_GALAXY: case EffectManager::eff_FAN: case EffectManager::eff_MARQUEE: case EffectManager::eff_MORPH: case EffectManager::eff_SHOCKWAVE: case EffectManager::eff_GLEDIATOR: case EffectManager::eff_FACES: break; case EffectManager::eff_STROBE: case EffectManager::eff_TWINKLE: break; //these effects have been updated to have a dedicated repeat or speed or other control //and now ignore the FitToTime and Speed sliders, but the settings need adjusting case EffectManager::eff_ON: if (settings.Get("E_TEXTCTRL_On_Cycles", "") == "") { float cycles = 1.0; if (!ftt) { int speed = wxAtoi(settings.Get("T_SLIDER_Speed", "10")); int totalTime = endMS - startMS; int maxState = totalTime * speed / 50; cycles = maxState / 200; } settings["E_TEXTCTRL_On_Cycles"] = wxString::Format("%0.2f", cycles); } break; case EffectManager::eff_SNOWSTORM: if (settings.Get("E_SLIDER_Snowstorm_Speed", "") == "") { settings["E_SLIDER_Snowstorm_Speed"] = settings.Get("T_SLIDER_Speed", "10"); } break; case EffectManager::eff_SNOWFLAKES: if (settings.Get("E_SLIDER_Snowflakes_Speed", "") == "") { settings["E_SLIDER_Snowflakes_Speed"] = settings.Get("T_SLIDER_Speed", "10"); } break; case EffectManager::eff_BUTTERFLY: if (settings.Get("E_SLIDER_Butterfly_Speed", "") == "") { settings["E_SLIDER_Butterfly_Speed"] = settings.Get("T_SLIDER_Speed", "10"); } break; case EffectManager::eff_CIRCLES: if (settings.Get("E_SLIDER_Circles_Speed", "") == "") { settings["E_SLIDER_Circles_Speed"] = settings.Get("T_SLIDER_Speed", "10"); } break; case EffectManager::eff_LIFE: if (settings.Get("E_SLIDER_Life_Speed", "") == "") { settings["E_SLIDER_Life_Speed"] = settings.Get("T_SLIDER_Speed", "10"); } break; case EffectManager::eff_METEORS: if (settings.Get("E_SLIDER_Meteors_Speed", "") == "") { settings["E_SLIDER_Meteors_Speed"] = settings.Get("T_SLIDER_Speed", "10"); } break; case EffectManager::eff_TREE: if (settings.Get("E_SLIDER_Tree_Speed", "") == "") { settings["E_SLIDER_Tree_Speed"] = settings.Get("T_SLIDER_Speed", "10"); } break; case EffectManager::eff_PINWHEEL: if (settings.Get("E_TEXTCTRL_Pinwheel_Speed", "") == "") { settings["E_TEXTCTRL_Pinwheel_Speed"] = settings.Get("T_SLIDER_Speed", "10"); } break; case EffectManager::eff_PLASMA: if (settings.Get("E_TEXTCTRL_Plasma_Speed", "") == "") { settings["E_TEXTCTRL_Plasma_Speed"] = settings.Get("T_SLIDER_Speed", "10"); } break; case EffectManager::eff_TEXT: if (settings.Get("E_TEXTCTRL_Text_Speed1", "") == "") { settings["E_TEXTCTRL_Text_Speed1"] = settings.Get("T_SLIDER_Speed", "10"); } if (settings.Get("E_TEXTCTRL_Text_Speed2", "") == "") { settings["E_TEXTCTRL_Text_Speed2"] = settings.Get("T_SLIDER_Speed", "10"); } if (settings.Get("E_TEXTCTRL_Text_Speed3", "") == "") { settings["E_TEXTCTRL_Text_Speed3"] = settings.Get("T_SLIDER_Speed", "10"); } if (settings.Get("E_TEXTCTRL_Text_Speed4", "") == "") { settings["E_TEXTCTRL_Text_Speed4"] = settings.Get("T_SLIDER_Speed", "10"); } if (settings.Get("E_SLIDER_Text_Position1", "") != "") { int pos = wxAtoi(settings.Get("E_SLIDER_Text_Position1", "50")) * 2 - 100; settings.erase("E_SLIDER_Text_Position1"); settings["E_SLIDER_Text_YStart1"] = wxString::Format("%d", pos); settings["E_SLIDER_Text_XStart1"] = wxString::Format("%d", pos); settings["E_SLIDER_Text_XEnd1"] = wxString::Format("%d", pos); settings["E_SLIDER_Text_YEnd1"] = wxString::Format("%d", pos); } break; case EffectManager::eff_WAVE: if (settings.Get("E_TEXTCTRL_Wave_Speed", "") == "") { settings["E_TEXTCTRL_Wave_Speed"] = settings.Get("T_SLIDER_Speed", "10"); } break; case EffectManager::eff_SPIROGRAPH: if (settings.Get("E_TEXTCTRL_Spirograph_Speed", "") == "") { settings["E_TEXTCTRL_Spirograph_Speed"] = settings.Get("T_SLIDER_Speed", "10"); } if (settings.Get("E_CHECKBOX_Spirograph_Animate", "") != "") { int i = wxAtoi(settings.Get("E_CHECKBOX_Spirograph_Animate", "0")); settings["E_TEXTCTRL_Spirograph_Animate"] = (i == 0 ? "0" : "10"); settings.erase("E_CHECKBOX_Spirograph_Animate"); } break; case EffectManager::eff_COLORWASH: if (settings.Get("E_TEXTCTRL_ColorWash_Cycles", "") == "") { double count = wxAtoi(settings.Get("E_SLIDER_ColorWash_Count", "1")); settings.erase("E_SLIDER_ColorWash_Count"); if (settings["T_CHECKBOX_FitToTime"] == "1") { count = 1.0; settings["E_CHECKBOX_ColorWash_CircularPalette"] = "0"; } else { settings["E_CHECKBOX_ColorWash_CircularPalette"] = "1"; } settings["E_TEXTCTRL_ColorWash_Cycles"] = wxString::Format("%0.2f", count); } break; case EffectManager::eff_FIRE: if (settings.Get("E_TEXTCTRL_Fire_GrowthCycles", "") == "") { bool grow = settings["E_CHECKBOX_Fire_GrowFire"] == "1"; settings.erase("E_CHECKBOX_Fire_GrowFire"); if (grow) { int speed = wxAtoi(settings.Get("T_SLIDER_Speed", "10")); int totalTime = endMS - startMS; double maxState = totalTime * speed / 50; double cycles = maxState / 500.0; settings["E_TEXTCTRL_Fire_GrowthCycles"] = wxString::Format("%0.2f", cycles); } else { settings["E_TEXTCTRL_Fire_GrowthCycles"] = "0.0"; } } break; case EffectManager::eff_FIREWORKS: if (settings.Get("E_SLIDER_Fireworks_Number_Explosions", "") != "") { int cnt = wxAtoi(settings.Get("E_SLIDER_Fireworks_Number_Explosions", "10")); settings.erase("E_SLIDER_Fireworks_Number_Explosions"); int speed = wxAtoi(settings.Get("T_SLIDER_Speed", "10")); int total = (speed * cnt) / 50; if (total > 50) { total = 50; } if (total < 1) { total = 1; } settings["E_SLIDER_Fireworks_Explosions"] = wxString::Format("%d", total); } break; case EffectManager::eff_RIPPLE: if (settings.Get("E_TEXTCTRL_Ripple_Cycles", "") == "") { float cycles = 1.0; if (!ftt) { int speed = wxAtoi(settings.Get("T_SLIDER_Speed", "10")); int totalTime = endMS - startMS; int maxState = totalTime * speed / 50; cycles = maxState / 200; } settings["E_TEXTCTRL_Ripple_Cycles"] = wxString::Format("%0.2f", cycles); } break; case EffectManager::eff_BARS: if (settings.Get("E_TEXTCTRL_Bars_Cycles", "") == "") { float cycles = 1.0; wxString dir = settings["E_CHOICE_Bars_Direction"]; if (!ftt) { int speed = wxAtoi(settings.Get("T_SLIDER_Speed", "10")); int totalTime = endMS - startMS; int maxState = totalTime * speed / 50; if (dir.Contains("Altern")) { cycles = maxState * 2; } else { cycles = maxState / 200; } } settings["E_TEXTCTRL_Bars_Cycles"] = wxString::Format("%0.2f", cycles); } break; case EffectManager::eff_SPIRALS: if (settings.Get("E_TEXTCTRL_Spirals_Movement", "") == "") { float cycles = 1.0; int dir = wxAtoi(settings.Get("E_SLIDER_Spirals_Direction", "1")); settings.erase("E_SLIDER_Spirals_Direction"); if (!ftt) { int speed = wxAtoi(settings.Get("T_SLIDER_Speed", "10")); int totalTime = endMS - startMS; int maxState = totalTime * speed / 50; cycles = maxState / 600; } settings["E_TEXTCTRL_Spirals_Movement"] = wxString::Format("%0.2f", dir * cycles); } break; case EffectManager::eff_CURTAIN: if (settings.Get("E_TEXTCTRL_Curtain_Speed", "") == "") { float cycles = 1.0; if (!ftt) { int speed = wxAtoi(settings.Get("T_SLIDER_Speed", "10")); int totalTime = endMS - startMS; int maxState = totalTime * speed / 50; cycles = maxState / 200; } settings["E_TEXTCTRL_Curtain_Speed"] = wxString::Format("%0.2f", cycles); } break; case EffectManager::eff_SINGLESTRAND: if ("Skips" == settings["E_NOTEBOOK_SSEFFECT_TYPE"]) { if (settings.Get("E_SLIDER_Skips_Advance", "") == "") { int speed = wxAtoi(settings.Get("T_SLIDER_Speed", "10")); settings["E_SLIDER_Skips_Advance"] = wxString::Format("%d", speed - 1); } } else { wxString type = settings.Get("E_CHOICE_Chase_Type1", "Left-Right"); if (type == "Auto reverse") { type = "Bounce from Left"; settings["E_CHOICE_Chase_Type1"] = type; } else if (type == "Bounce" || type == "Pacman") { type = "Dual Bounce"; settings["E_CHOICE_Chase_Type1"] = type; } if (settings.Get("E_TEXTCTRL_Chase_Rotations", "") == "") { float cycles = 1.0; if (!ftt) { int speed = wxAtoi(settings.Get("T_SLIDER_Speed", "10")); int totalTime = endMS - startMS; int maxState = totalTime * speed / 50; cycles = maxState / 250.0; } settings["E_TEXTCTRL_Chase_Rotations"] = wxString::Format("%0.2f", cycles); } } break; case EffectManager::eff_SHIMMER: if (settings.Get("E_TEXTCTRL_Shimmer_Cycles", "") == "") { float cycles = 1.0; int speed = wxAtoi(settings.Get("T_SLIDER_Speed", "10")); int totalTime = endMS - startMS; int maxState = totalTime * speed / 50; cycles = maxState / (100.0 * colors.size()); settings["E_TEXTCTRL_Shimmer_Cycles"] = wxString::Format("%0.2f", cycles); } break; case EffectManager::eff_PICTURES: if (settings.Get("E_TEXTCTRL_Pictures_FrameRateAdj", "") == "") { if (settings.Get("E_CHECKBOX_MovieIs20FPS", "") == "1") { settings["E_TEXTCTRL_Pictures_FrameRateAdj"] = "1.0"; } else if (settings.Get("E_SLIDER_Pictures_GifSpeed", "") == "0") { settings["E_TEXTCTRL_Pictures_FrameRateAdj"] = "0.0"; } else if (!ftt) { int speed = wxAtoi(settings.Get("T_SLIDER_Speed", "10")); int totalTime = endMS - startMS; int maxState = totalTime * speed / 50; double cycles = maxState / 300.0; settings["E_TEXTCTRL_Pictures_Speed"] = wxString::Format("%0.2f", cycles); } settings.erase("E_CHECKBOX_MovieIs20FPS"); settings.erase("E_SLIDER_Pictures_GifSpeed"); } break; case EffectManager::eff_GARLANDS: //Don't attempt to map the Garlands speed settings. In v3, the Garland speed depended on the Speed setting, the //Spacing setting as well as the height of the model. We don't have the height of the model here so really //no way to figure out the speed or an appropriate mapping break; //these all need code updated and new sliders and such before we can map them //these all have state/speed requirements case EffectManager::eff_PIANO: break; } settings.erase("T_CHECKBOX_FitToTime"); settings.erase("T_SLIDER_Speed"); }
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); } } } } }
void SnowflakesEffect::Render(Effect *effect, const SettingsMap &SettingsMap, RenderBuffer &buffer) { int Count = SettingsMap.GetInt("SLIDER_Snowflakes_Count", 5); int SnowflakeType = SettingsMap.GetInt("SLIDER_Snowflakes_Type", 1); int sSpeed = SettingsMap.GetInt("SLIDER_Snowflakes_Speed", 10); std::string falling = SettingsMap.Get("CHOICE_Falling", "Driving"); int i,n,x,x0,y0,y,check,delta_y; xlColor color1,color2, color3; bool wrapx = false; // set to true if you want snowflakes to draw wrapped around when near edges in the accumulate effect. SnowflakesRenderCache *cache = (SnowflakesRenderCache*)buffer.infoCache[id]; if (cache == nullptr) { cache = new SnowflakesRenderCache(); buffer.infoCache[id] = cache; } int &LastSnowflakeCount = cache->LastSnowflakeCount; int &LastSnowflakeType = cache->LastSnowflakeType; int &effectState = cache->effectState; std::string& LastFalling = cache->LastFalling; buffer.palette.GetColor(0, color1); buffer.palette.GetColor(1, color2); if (buffer.needToInit || Count != LastSnowflakeCount || SnowflakeType != LastSnowflakeType || falling != LastFalling) { // initialize buffer.needToInit = false; LastSnowflakeCount=Count; LastSnowflakeType=SnowflakeType; LastFalling = falling; buffer.ClearTempBuf(); effectState = 0; // place Count snowflakes for (n=0; n < Count; n++) { delta_y=buffer.BufferHt/4; y0=(n % 4)*delta_y; if (y0+delta_y > buffer.BufferHt) delta_y = buffer.BufferHt-y0; if (delta_y<1) delta_y=1; // find unused space for (check=0; check < 20; check++) { x=rand() % buffer.BufferWi; y=y0 + (rand() % delta_y); if (buffer.GetTempPixel(x,y) == xlBLACK) { effectState++; break; } } // draw flake, SnowflakeType=0 is random type switch (SnowflakeType == 0 ? rand() % 5 : SnowflakeType-1) { case 0: // single node if(falling != "Driving") { buffer.SetTempPixel(x, y, color1, 0); } else { buffer.SetTempPixel(x, y, color1); } break; case 1: // 5 nodes if (x < 1) x+=1; if (y < 1) y+=1; if (x > buffer.BufferWi-2) x-=1; if (y > buffer.BufferHt-2) y-=1; if(falling != "Driving") { buffer.SetTempPixel(x,y,color1, 1); } else { buffer.SetTempPixel(x,y,color1); buffer.SetTempPixel(x-1,y,color2); buffer.SetTempPixel(x+1,y,color2); buffer.SetTempPixel(x,y-1,color2); buffer.SetTempPixel(x,y+1,color2); } break; case 2: // 3 nodes if (x < 1) x+=1; if (y < 1) y+=1; if (x > buffer.BufferWi-2) x-=1; if (y > buffer.BufferHt-2) y-=1; if(falling != "Driving") { buffer.SetTempPixel(x,y,color1, 2); } else { buffer.SetTempPixel(x,y,color1); if (rand() % 100 > 50) // % 2 was not so random { buffer.SetTempPixel(x-1,y,color2); buffer.SetTempPixel(x+1,y,color2); } else { buffer.SetTempPixel(x,y-1,color2); buffer.SetTempPixel(x,y+1,color2); } } break; case 3: // 9 nodes if (x < 2) x+=2; if (y < 2) y+=2; if (x > buffer.BufferWi-3) x-=2; if (y > buffer.BufferHt-3) y-=2; if(falling != "Driving") { buffer.SetTempPixel(x, y, color1, 3); } else { buffer.SetTempPixel(x, y, color1); for (i=1; i<=2; i++) { buffer.SetTempPixel(x-i,y,color2); buffer.SetTempPixel(x+i,y,color2); buffer.SetTempPixel(x,y-i,color2); buffer.SetTempPixel(x,y+i,color2); } } break; case 4: // 13 nodes if (x < 2) x+=2; if (y < 2) y+=2; if (x > buffer.BufferWi-3) x-=2; if (y > buffer.BufferHt-3) y-=2; if(falling != "Driving") { buffer.SetTempPixel(x, y, color1, 4); } else { buffer.SetTempPixel(x, y, color1); buffer.SetTempPixel(x-1,y,color2); buffer.SetTempPixel(x+1,y,color2); buffer.SetTempPixel(x,y-1,color2); buffer.SetTempPixel(x,y+1,color2); buffer.SetTempPixel(x-1,y+2,color2); buffer.SetTempPixel(x+1,y+2,color2); buffer.SetTempPixel(x-1,y-2,color2); buffer.SetTempPixel(x+1,y-2,color2); buffer.SetTempPixel(x+2,y-1,color2); buffer.SetTempPixel(x+2,y+1,color2); buffer.SetTempPixel(x-2,y-1,color2); buffer.SetTempPixel(x-2,y+1,color2); } break; case 5: // 45 nodes (not enabled) break; } } } // move snowflakes int movement = (buffer.curPeriod - buffer.curEffStartPer) * sSpeed * buffer.frameTimeInMs / 50; int new_x,new_y,new_x2,new_y2; int starty = 0; if (falling == "Falling & Accumulating") { starty = 1; } bool driving = falling == "Driving"; for (x=0; x<buffer.BufferWi; x++) { new_x = (x+movement/20) % buffer.BufferWi; // CW new_x2 = (x-movement/20) % buffer.BufferWi; // CCW if (new_x2 < 0) new_x2 += buffer.BufferWi; for (y=starty; y<buffer.BufferHt; y++) { if (!driving) { // this controls the speed by skipping movement when slow if (((buffer.curPeriod-buffer.curEffStartPer) * (sSpeed+1)) / 30 != ((buffer.curPeriod-buffer.curEffStartPer-1) * (sSpeed + 1)) / 30) { // if there is a flake to move buffer.GetTempPixel(x, y, color3); if (color3 != xlBLACK) { // check where we can move to? int moves = possible_downward_moves(buffer, x, y); x0 = x; //we have something to move // randomly move the flake left or right if (moves > 0 || (falling == "Falling" && y == 0)) { switch(rand() % 5) { case 0: if (moves & 1) { x0 = x - 1; } else { if (moves & 2) { x0 = x; } else { x0 = x + 1; } } break; case 1: if (moves & 4) { x0 = x + 1; } else { if (moves & 2) { x0 = x; } else { x0 = x - 1; } } break; default: //down more often then left/right to look less "jittery" if (moves & 2) { x0 = x; } else if ((moves & 5) == 4) { x0 = x + 1; } else if ((moves & 5) == 1) { x0 = x - 1; } else { switch(rand() % 2) { case 0: x0 = x+1; break; default: x0 = x-1; break; } } break; } // handle wrap around if (x0 < 0) { x0 += buffer.BufferWi; } else if (x0 >= buffer.BufferWi) { x0 -= buffer.BufferWi; } // and move it down y0 = y - 1; buffer.SetTempPixel(x, y, xlBLACK); if (y0 >= 0) { // move the flake down buffer.SetTempPixel(x0, y0, color3); if (falling == "Falling & Accumulating") { int nextmoves = possible_downward_moves(buffer, x0, y0); if (nextmoves == 0) { // we cant move any further so we can add one at the top effectState--; } } } else { // falling should always be just falling ... never accumulate effectState--; } } } } } else { new_y = (y+movement/10) % buffer.BufferHt; new_y2 = (new_y+buffer.BufferHt/2) % buffer.BufferHt; buffer.GetTempPixel(new_x,new_y,color1); if (color1 == xlBLACK) buffer.GetTempPixel(new_x2,new_y2,color1); // strip off the alpha channel buffer.SetPixel(x, y, color1); } } } if (!driving) { // add new flakes to the top check = 0; int placedFullCount = 0; while (effectState < Count && check < 20) { // find unused space x=rand() % buffer.BufferWi; if (buffer.GetTempPixel(x, buffer.BufferHt-1) == xlBLACK) { effectState++; buffer.SetTempPixel(x, buffer.BufferHt-1, color1, SnowflakeType == 0 ? rand() % 5 : SnowflakeType-1); int nextmoves = possible_downward_moves(buffer, x, buffer.BufferHt-1); if (nextmoves == 0) { //the placed pixel fills the column, make sure we note that so we can place //another snowflake placedFullCount++; } } check++; } effectState -= placedFullCount; // paint my current state for (int y=0; y < buffer.BufferHt; y++) { for (int x=0; x < buffer.BufferWi; x++) { buffer.GetTempPixel(x, y, color3); if (color3 != xlBLACK) { // draw flake, SnowflakeType=0 is random type switch (color3.Alpha()) { case 0: // single node buffer.SetPixel(x, y, color1); break; case 1: // 5 nodes buffer.SetPixel(x,y,color1); set_pixel_if_not_color(buffer, x-1, y, color2, color1, wrapx, false); set_pixel_if_not_color(buffer, x+1, y, color2, color1, wrapx, false); set_pixel_if_not_color(buffer, x, y-1, color2, color1, wrapx, false); set_pixel_if_not_color(buffer, x, y+1, color2, color1, wrapx, false); break; case 2: { // 3 nodes buffer.SetPixel(x,y,color1); bool isAtBottom = true; for (int yt = 0; yt < y - 1; yt++) { if (buffer.GetTempPixel(x, yt) == xlBLACK) { isAtBottom = false; break; } } // when flake has settled always paint it horizontally if (isAtBottom) { set_pixel_if_not_color(buffer, x-1, y, color2, color1, wrapx, false); set_pixel_if_not_color(buffer, x+1, y, color2, color1, wrapx, false); } else { if (rand() % 100 > 50) // % 2 was not so random { set_pixel_if_not_color(buffer, x-1, y, color2, color1, wrapx, false); set_pixel_if_not_color(buffer, x+1, y, color2, color1, wrapx, false); } else { set_pixel_if_not_color(buffer, x, y-1, color2, color1, wrapx, false); set_pixel_if_not_color(buffer, x, y+1, color2, color1, wrapx, false); } } } break; case 3: // 9 nodes buffer.SetPixel(x,y,color1); for (i=1; i<=2; i++) { set_pixel_if_not_color(buffer, x-i, y, color2, color1, wrapx, false); set_pixel_if_not_color(buffer, x+i, y, color2, color1, wrapx, false); set_pixel_if_not_color(buffer, x, y-i, color2, color1, wrapx, false); set_pixel_if_not_color(buffer, x, y+i, color2, color1, wrapx, false); } break; case 4: // 13 nodes buffer.SetPixel(x,y,color1); set_pixel_if_not_color(buffer, x-1, y, color2, color1, wrapx, false); set_pixel_if_not_color(buffer, x+1, y, color2, color1, wrapx, false); set_pixel_if_not_color(buffer, x, y+1, color2, color1, wrapx, false); set_pixel_if_not_color(buffer, x, y-1, color2, color1, wrapx, false); set_pixel_if_not_color(buffer, x-1, y+2, color2, color1, wrapx, false); set_pixel_if_not_color(buffer, x+1, y+2, color2, color1, wrapx, false); set_pixel_if_not_color(buffer, x-1, y-2, color2, color1, wrapx, false); set_pixel_if_not_color(buffer, x+1, y-2, color2, color1, wrapx, false); set_pixel_if_not_color(buffer, x+2, y-1, color2, color1, wrapx, false); set_pixel_if_not_color(buffer, x+2, y+1, color2, color1, wrapx, false); set_pixel_if_not_color(buffer, x-2, y-1, color2, color1, wrapx, false); set_pixel_if_not_color(buffer, x-2, y+1, color2, color1, wrapx, false); break; case 5: // 45 nodes (not enabled) break; } } } } } }
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 } } }
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); } }
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); } } } } }
void TreeEffect::Render(Effect *effect, const SettingsMap &SettingsMap, RenderBuffer &buffer) { int Branches = SettingsMap.GetInt("SLIDER_Tree_Branches", 1); int tspeed = SettingsMap.GetInt("SLIDER_Tree_Speed", 10); int effectState = (buffer.curPeriod - buffer.curEffStartPer) * tspeed * buffer.frameTimeInMs / 50; int x,y,i,r,ColorIdx,pixels_per_branch; int maxFrame,mod,branch,row,b,f_mod,m,frame; int number_garlands,f_mod_odd,s_odd_row,odd_even; float V,H; number_garlands=1; xlColor color; if(Branches<1) Branches=1; pixels_per_branch=(int)(0.5+buffer.BufferHt/Branches); if(pixels_per_branch<1) pixels_per_branch=1; maxFrame=(Branches+1) * buffer.BufferWi; if(effectState>0 && maxFrame>0) frame = (effectState/4)%maxFrame; else frame=1; i=0; for (y=0; y<buffer.BufferHt; y++) // For my 20x120 megatree, BufferHt=120 { for (x=0; x<buffer.BufferWi; x++) // BufferWi=20 in the above example { if(pixels_per_branch>0) mod=y%pixels_per_branch; else mod=0; if(mod==0) mod=pixels_per_branch; V=1-(1.0*mod/pixels_per_branch)*0.70; i++; ColorIdx=0; buffer.palette.GetColor(ColorIdx, color); // Now go and get the hsv value for this ColorIdx if (buffer.allowAlpha) { color.alpha = 255.0 * V; } else { HSVValue hsv = color.asHSV(); hsv.value = V; // we have now set the color for the background tree color = hsv; } // $orig_rgbval=$rgb_val; branch = (int)((y-1)/pixels_per_branch); row = pixels_per_branch-mod; // now row=0 is bottom of branch, row=1 is one above bottom // mod = which pixel we are in the branch // mod=1,row=pixels_per_branch-1 top picrl in branch // mod=2, second pixel down into branch // mod=pixels_per_branch,row=0 last pixel in branch // // row = 0, the $p is in the bottom row of tree // row =1, the $p is in second row from bottom b = (int) ((effectState)/buffer.BufferWi)%Branches; // what branch we are on based on frame # // // b = 0, we are on bottomow row of tree during frames 1 to BufferWi // b = 1, we are on second row from bottom, frames = BufferWi+1 to 2*BufferWi // b = 2, we are on third row from bottome, frames - 2*BufferWi+1 to 3*BufferWi f_mod = (effectState/4)%buffer.BufferWi; // if(f_mod==0) f_mod=BufferWi; // f_mod is to BufferWi-1 on each row // f_mod == 0, left strand of this row // f_mod==BufferWi, right strand of this row // m=(x%6); if(m==0) m=6; // use $m to indicate where we are in horizontal pattern // m=1, 1sr strand // m=2, 2nd strand // m=6, last strand in 6 strand pattern r=branch%5; H = r/4.0; odd_even=b%2; s_odd_row = buffer.BufferWi-x+1; f_mod_odd = buffer.BufferWi-f_mod+1; if(branch<=b && x<=frame && // for branches below or equal to current row (((row==3 || (number_garlands==2 && row==6)) && (m==1 || m==6)) || ((row==2 || (number_garlands==2 && row==5)) && (m==2 || m==5)) || ((row==1 || (number_garlands==2 && row==4)) && (m==3 || m==4)) )) if((odd_even ==0 && x<=f_mod) || (odd_even ==1 && s_odd_row<=f_mod)) { HSVValue hsv; hsv.hue = H; hsv.saturation=1.0; hsv.value=1.0; color = hsv; } // if(branch>b) // { // return $rgb_val; // for branches below current, dont dont balnk anything out // } // else if(branch==b) // { // if(odd_even ==0 && x>f_mod) // { // $rgb_val=$orig_rgbval;// we are even row ,counting from bottom as zero // } // if(odd_even ==1 && s_odd_row>f_mod) // { // $rgb_val=$orig_rgbval;// we are even row ,counting from bottom as zero // } // } //if($branch>$b) $rgb_val=$orig_rgbval; // erase rows above our current row. // Yes, so now decide on what color it should be // we left the Hue and Saturation alone, we are just modifiying the Brightness Value buffer.SetPixel(x,y,color); // Turn pixel on } } }
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; } } } } }