BOOL Dib::LoadFromFile(const char *filename) { if( mBMPFileHeader ) free( mBMPFileHeader ); HANDLE hFile; DWORD FileSize, ReadCount; hFile = CreateFile(filename, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if(INVALID_HANDLE_VALUE == hFile) { return FALSE; } FileSize = GetFileSize(hFile, NULL); if(mBMPFileHeader) free(mBMPFileHeader); mBMPFileHeader = (BITMAPFILEHEADER*)malloc(FileSize); ReadFile(hFile, mBMPFileHeader, FileSize, &ReadCount, NULL); CloseHandle(hFile); mRawData = (PBYTE)mBMPFileHeader + mBMPFileHeader->bfOffBits; mBMPInfo = (BITMAPINFO*)((PBYTE)mBMPFileHeader+sizeof(BITMAPFILEHEADER)); mBMPInfoHeader = (BITMAPINFOHEADER*)((PBYTE)mBMPFileHeader+sizeof(BITMAPFILEHEADER)); mRGBTable = (RGBQUAD*)((PBYTE)mBMPInfoHeader + mBMPInfoHeader->biSize); if(mBMPInfoHeader->biBitCount == 8) { CreateLogicalPallete(); } mColorCount= GetColorCount(); return TRUE; }
void RgbEffects::RenderColorWash(bool HorizFade, bool VertFade, int RepeatCount) { static int SpeedFactor=200; int x,y; wxColour color; wxImage::HSVValue hsv,hsv2; size_t colorcnt=GetColorCount(); int CycleLen=colorcnt*SpeedFactor; if (state > (colorcnt-1)*SpeedFactor*RepeatCount && RepeatCount < 10) { GetMultiColorBlend(double(RepeatCount%2), false, color); } else { GetMultiColorBlend(double(state % CycleLen) / double(CycleLen), true, color); } Color2HSV(color,hsv); double HalfHt=double(BufferHt-1)/2.0; double HalfWi=double(BufferWi-1)/2.0; for (x=0; x<BufferWi; x++) { for (y=0; y<BufferHt; y++) { hsv2=hsv; if (HorizFade) hsv2.value*=1.0-abs(HalfWi-x)/HalfWi; if (VertFade) hsv2.value*=1.0-abs(HalfHt-y)/HalfHt; SetPixel(x,y,hsv2); } } }
void RgbEffects::drawline3 (int Phoneme, int x1,int x2,int y6,int y7) { wxColour color; wxImage::HSVValue hsv; int ColorIdx,x,y; size_t colorcnt=GetColorCount(); ColorIdx=rand() % colorcnt; // Select random numbers from 0 up to number of colors the user has checked. 0-5 if 6 boxes checked palette.GetHSV(ColorIdx, hsv); hsv.hue = (float)Phoneme/10.0; hsv.value=1.0; for(y=y6+1; y<y7; y++) { SetPixel(x1,y,hsv); // Left side of mouyh SetPixel(x2,y,hsv); // rightside } for(x=x1+1; x<x2; x++) { SetPixel(x,y6,hsv); // Bottom SetPixel(x,y7,hsv); // Bottom } /* dy = (y7-y6)/2; xc = x1+dy; yc = y7+dy; radius = (double) dy; facesCircle(Phoneme,xc, yc, radius,90,270); xc = x1-dy; facesCircle(Phoneme,xc, yc, radius,270,630); */ }
// Does not open or close pFile. Assumes // caller will do it. BOOL CDIBitmap :: Save( CFile * pFile ) { ASSERT_VALID( pFile ); ASSERT( m_pInfo ); ASSERT( m_pPixels ); BITMAPFILEHEADER bmfHdr; DWORD dwPadWidth = PADWIDTH(GetWidth()); // Make sure bitmap data is in padded format PadBits(); bmfHdr.bfType = 0x4D42; // initialize to BitmapInfo size DWORD dwImageSize= m_pInfo->bmiHeader.biSize; // Add in palette size WORD wColors = GetColorCount(); WORD wPaletteSize = (WORD)(wColors*sizeof(RGBQUAD)); dwImageSize += wPaletteSize; // Add in size of actual bit array dwImageSize += PADWIDTH((GetWidth()) * DWORD(m_pInfo->bmiHeader.biBitCount)/8) * GetHeight(); m_pInfo->bmiHeader.biSizeImage = 0; bmfHdr.bfSize = dwImageSize + sizeof(BITMAPFILEHEADER); bmfHdr.bfReserved1 = 0; bmfHdr.bfReserved2 = 0; bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + m_pInfo->bmiHeader.biSize + wPaletteSize; pFile->Write(&bmfHdr, sizeof(BITMAPFILEHEADER)); pFile->Write(m_pInfo, sizeof(BITMAPINFO) + (wColors-1)*sizeof(RGBQUAD)); pFile->Write(m_pPixels, DWORD((dwPadWidth*(DWORD)m_pInfo->bmiHeader.biBitCount*GetHeight())/8) ); return TRUE; }
void RgbEffects::RenderMeteors(int MeteorType, int Count, int Length) { if (state == 0) meteors.clear(); int mspeed=state/4; state-=mspeed*4; // create new meteors MeteorClass m; wxImage::HSVValue hsv,hsv0,hsv1; palette.GetHSV(0,hsv0); palette.GetHSV(1,hsv1); size_t colorcnt=GetColorCount(); Count=BufferWi * Count / 100; int TailLength=(BufferHt < 10) ? Length / 10 : BufferHt * Length / 100; if (TailLength < 1) TailLength=1; int TailStart=BufferHt - TailLength; if (TailStart < 1) TailStart=1; for(int i=0; i<Count; i++) { m.x=rand() % BufferWi; m.y=BufferHt - 1 - rand() % TailStart; switch (MeteorType) { case 1: SetRangeColor(hsv0,hsv1,m.hsv); break; case 2: palette.GetHSV(rand()%colorcnt, m.hsv); break; } meteors.push_back(m); } // render meteors for (MeteorList::iterator it=meteors.begin(); it!=meteors.end(); ++it) { for(int ph=0; ph<TailLength; ph++) { switch (MeteorType) { case 0: hsv.hue=double(rand() % 1000) / 1000.0; hsv.saturation=1.0; hsv.value=1.0; break; default: hsv=it->hsv; break; } hsv.value*=1.0 - double(ph)/TailLength; SetPixel(it->x,it->y+ph,hsv); } it->y -= mspeed; } // delete old meteors meteors.remove_if(MeteorHasExpired(TailLength)); }
void RgbEffects::RenderFaces(int Phoneme) { int ColorIdx; size_t i,idx; int n,x,y,s; /* FacesPhoneme.Add("AI"); 0 FacesPhoneme.Add("E"); 1 FacesPhoneme.Add("FV"); 2 FacesPhoneme.Add("L"); 3 FacesPhoneme.Add("MBP"); 4 FacesPhoneme.Add("O"); 5 FacesPhoneme.Add("U"); 6 FacesPhoneme.Add("WQ"); 7 FacesPhoneme.Add("etc"); 8 FacesPhoneme.Add("rest"); 9 */ wxColour color; wxImage::HSVValue hsv; int maxframe=BufferHt*2; int frame=(BufferHt * state / 200)%maxframe; double offset=double(state)/100.0; size_t colorcnt=GetColorCount(); std::vector<int> chmap; chmap.resize(BufferHt * BufferWi,0); wxString html = "<html><body><table border=0>"; int Ht, Wt; Ht = BufferHt; Wt = BufferWi; mouth( Phoneme, Ht, Wt); // draw a mouth syllable //size_t NodeCount=GetNodeCount(); // above is from ModelClass::ChannelLayoutHtml() #if 0 //DEBUG //get list of models: wxString buf; for (auto it = xLightsFrame::PreviewModels.begin(); it != xLightsFrame::PreviewModels.end(); ++it) buf += ", " + (*it)->name; //ModelClassPtr* debug(1, "faces: models = %s", (const char*)buf + 2); //get info about one of the models: buf = xLightsFrame::PreviewModels[0]->name; debug(1, "first model is %s", (const char*)buf); buf = xLightsFrame::PreviewModels[0]->ChannelLayoutHtml(); if (buf.size() > 500) buf.resize(500); debug(1, "first 500 char of layout html = %s", (const char*)buf); #endif }
void RgbEffects::RenderBars(int PaletteRepeat, int Direction, bool Highlight, bool Show3D) { int x,y,n,pixel_ratio,ColorIdx; bool IsMovingDown,IsHighlightRow; wxImage::HSVValue hsv; size_t colorcnt=GetColorCount(); int BarCount = PaletteRepeat * colorcnt; int BarHt = BufferHt/BarCount+1; int HalfHt = BufferHt/2; int BlockHt=colorcnt * BarHt; int f_offset = state/4 % BlockHt; for (y=0; y<BufferHt; y++) { switch (Direction) { case 1: IsMovingDown=true; break; case 2: IsMovingDown=(y <= HalfHt); break; case 3: IsMovingDown=(y > HalfHt); break; default: IsMovingDown=false; break; } if (IsMovingDown) { n=y+f_offset; pixel_ratio = BarHt - n%BarHt - 1; IsHighlightRow=n % BarHt == 0; } else { n=y-f_offset+BlockHt; pixel_ratio = n%BarHt; IsHighlightRow=(n % BarHt == BarHt-1); // || (y == BufferHt-1); } ColorIdx=(n % BlockHt) / BarHt; palette.GetHSV(ColorIdx, hsv); if (Highlight && IsHighlightRow) hsv.saturation=0.0; if (Show3D) hsv.value *= double(pixel_ratio) / BarHt; for (x=0; x<BufferWi; x++) { SetPixel(x,y,hsv); } } }
// 0 <= n < 1 void RenderBuffer::GetMultiColorBlend(float n, bool circular, xlColor &color) { size_t colorcnt=GetColorCount(); if (colorcnt <= 1) { palette.GetColor(0,color); return; } if (n >= 1.0) n=0.99999f; if (n < 0.0) n=0.0f; float realidx=circular ? n*colorcnt : n*(colorcnt-1); int coloridx1=floor(realidx); int coloridx2=(coloridx1+1) % colorcnt; float ratio=realidx-float(coloridx1); Get2ColorBlend(coloridx1,coloridx2,ratio,color); }
// 0 <= n < 1 void RgbEffects::GetMultiColorBlend(double n, bool circular, xlColour &color) { size_t colorcnt=GetColorCount(); if (colorcnt <= 1) { palette.GetColor(0,color); return; } if (n >= 1.0) n=0.99999; if (n < 0.0) n=0.0; double realidx=circular ? n*colorcnt : n*(colorcnt-1); int coloridx1=floor(realidx); int coloridx2=(coloridx1+1) % colorcnt; double ratio=realidx-double(coloridx1); Get2ColorBlend(coloridx1,coloridx2,ratio,color); }
void RgbEffects::RenderSpirals(int PaletteRepeat, int Direction, int Rotation, int Thickness, bool Blend, bool Show3D) { int strand_base,strand,thick,x,y,ColorIdx; size_t colorcnt=GetColorCount(); int SpiralCount=colorcnt * PaletteRepeat; int deltaStrands=BufferWi / SpiralCount; int SpiralThickness=(deltaStrands * Thickness / 100) + 1; long SpiralState=state*Direction; wxImage::HSVValue hsv; wxColour color; for(int ns=0; ns < SpiralCount; ns++) { strand_base=ns * deltaStrands; ColorIdx=ns % colorcnt; palette.GetColor(ColorIdx,color); for(thick=0; thick < SpiralThickness; thick++) { strand = (strand_base + thick) % BufferWi; for(y=0; y < BufferHt; y++) { x=(strand + SpiralState/10 + y*Rotation/BufferHt) % BufferWi; if (x < 0) x += BufferWi; if (Blend) { GetMultiColorBlend(double(BufferHt-y-1)/double(BufferHt), false, color); } if (Show3D) { Color2HSV(color,hsv); if (Rotation < 0) { hsv.value*=double(thick+1)/SpiralThickness; } else { hsv.value*=double(SpiralThickness-thick)/SpiralThickness; } SetPixel(x,y,hsv); } else { SetPixel(x,y,color); } } } } }
void RgbEffects::RenderSpirograph(int int_R, int int_r, int int_d) { #define PI 3.14159265 int i,x,y,k,xc,yc,ColorIdx; int mod1440,state360; srand(1); float R,r,d,d_orig,t; wxImage::HSVValue hsv,hsv0,hsv1; // we will define an hsv color model. The RGB colot model would have been "wxColour color;" size_t colorcnt=GetColorCount(); xc= (int)(BufferWi/2); // 20x100 flex strips with 2 fols per strip = 40x50 yc= (int)(BufferHt/2); R=xc*(int_R/100.0); // Radius of the large circle just fits in the width of model r=xc*(int_r/100.0); // start little circle at 1/4 of max width if(r>R) r=R; d=xc*(int_d/100.0); ColorIdx=rand() % colorcnt; // Select random numbers from 0 up to number of colors the user has checked. 0-5 if 6 boxes checked palette.GetHSV(ColorIdx, hsv); // Now go and get the hsv value for this ColorIdx palette.GetHSV(0, hsv0); palette.GetHSV(1, hsv1); // // A hypotrochoid is a roulette traced by a point attached to a circle of radius r rolling around the inside of a fixed circle of radius R, where the point is a distance d from the center of the interior circle. //The parametric equations for a hypotrochoid are:[citation needed] // // more info: http://en.wikipedia.org/wiki/Hypotrochoid // //x(t) = (R-r) * cos t + d*cos ((R-r/r)*t); //y(t) = (R-r) * sin t + d*sin ((R-r/r)*t); mod1440=state%1440; state360 = state%360; d_orig=d; for(i=1; i<=360; i++) { d = (int)(d_orig+state/2)%100; t = (i+mod1440)*PI/180; x = (R-r) * cos (t) + d*cos ((R-r/r)*t) + xc; y = (R-r) * sin (t) + d*sin ((R-r/r)*t) + yc; if(i<=state360) SetPixel(x,y,hsv0); // Turn pixel on else SetPixel(x,y,hsv1); } }
void RgbEffects::RenderTwinkle(int Count) { int x,y,i,i7,r,ColorIdx; int lights = (BufferHt*BufferWi)*(Count/100.0); // Count is in range of 1-100 from slider bar int step=BufferHt*BufferWi/lights; if(step<1) step=1; srand(1); // always have the same random numbers for each frame (state) wxImage::HSVValue hsv; // we will define an hsv color model. The RGB colot model would have been "wxColour color;" size_t colorcnt=GetColorCount(); i=0; for (y=0; y<BufferHt; y++) // For my 20x120 megatree, BufferHt=120 { for (x=0; x<BufferWi; x++) // BufferWi=20 in the above example { i++; if(i%step==0) // Should we draw a light? { // Yes, so now decide on what color it should be ColorIdx=rand() % colorcnt; // Select random numbers from 0 up to number of colors the user has checked. 0-5 if 6 boxes checked palette.GetHSV(ColorIdx, hsv); // Now go and get the hsv value for this ColorIdx i7=(state/4+rand())%9; // Our twinkle is 9 steps. 4 ramping up, 5th at full brightness and then 4 more ramping down // Note that we are adding state to this calculation, this causes a different blink rate for each light if(i7==0 || i7==8) hsv.value = 0.1; if(i7==1 || i7==7) hsv.value = 0.3; if(i7==2 || i7==6) hsv.value = 0.5; if(i7==3 || i7==5) hsv.value = 0.7; if(i7==4 ) hsv.value = 1.0; // we left the Hue and Saturation alone, we are just modifiying the Brightness Value SetPixel(x,y,hsv); // Turn pixel on } } } }
void PixelBufferClass::RenderColorWash(int layer, bool HorizFade, bool VertFade) { int x,y; wxColour color; wxImage::HSVValue hsv,hsv2; size_t colorcnt=GetColorCount(layer); int CycleLen=colorcnt*100; ColorWashState[layer]+=Speed; double ratio= double(ColorWashState[layer]/4 % CycleLen) / double(CycleLen); GetMultiColorBlend(layer, ratio, true, color); Color2HSV(color,hsv); double HalfHt=double(BufferHt-1)/2.0; double HalfWi=double(BufferWi-1)/2.0; for (x=0; x<BufferWi; x++) { for (y=0; y<BufferHt; y++) { hsv2=hsv; if (HorizFade) hsv2.value*=1.0-abs(HalfWi-x)/HalfWi; if (VertFade) hsv2.value*=1.0-abs(HalfHt-y)/HalfHt; SetPixel(layer,x,y,hsv2); } } }
void PixelBufferClass::RenderBars(int layer, int BarCount, int Direction, bool Highlight, bool Show3D) { int x,y,n,pixel_ratio,ColorIdx; bool IsMovingDown,IsHighlightRow; wxImage::HSVValue hsv; size_t colorcnt=GetColorCount(layer); int BarWidth = BufferHt/BarCount+1; int HalfHt = BufferHt/2; BarState[layer]+=Speed; int f_offset = BarState[layer]/4 % BufferHt; for (x=0; x<BufferWi; x++) { for (y=0; y<BufferHt; y++) { ColorIdx=(y/BarWidth) % colorcnt; palette[layer].GetHSV(ColorIdx, hsv); switch (Direction) { case 1: IsMovingDown=true; break; case 2: IsMovingDown=(y <= HalfHt); break; case 3: IsMovingDown=(y > HalfHt); break; default: IsMovingDown=false; break; } if (IsMovingDown) { n=y-f_offset; pixel_ratio = BarWidth - y%BarWidth; IsHighlightRow=y % BarWidth == 0; } else { n=y+f_offset; pixel_ratio = y%BarWidth; IsHighlightRow=(y % BarWidth == BarWidth-1) || (y == BufferHt-1); } if (Highlight && IsHighlightRow) hsv.saturation=0.0; if (Show3D) hsv.value *= double(pixel_ratio) / BarWidth; n=n % BufferHt; if (n < 0) n+=BufferHt; SetPixel(layer,x,n,hsv); } } }
void RgbEffects::drawline1(int Phoneme, int x1,int x2,int y1,int y2) { wxColour color; wxImage::HSVValue hsv; int ColorIdx,x,y; size_t colorcnt=GetColorCount(); ColorIdx=rand() % colorcnt; // Select random numbers from 0 up to number of colors the user has checked. 0-5 if 6 boxes checked palette.GetHSV(ColorIdx, hsv); // Now go and get the hsv value for this ColorIdx hsv.hue = (float)Phoneme/10.0; hsv.value=1.0; for(x=x1+1; x<x2; x++) { SetPixel(x,y2,hsv); // Turn pixel on } for(y=y2+1; y<=y1; y++) { SetPixel(x1,y,hsv); // Left side of mouyh SetPixel(x2,y,hsv); // rightside } }
// 0 <= n < 1 void PixelBufferClass::GetMultiColorBlend(int layer, double n, bool circular, wxColour &color) { /* // debug wxClientDC dc(DrawWindow); wxString msg=wxString::Format(wxT("%6.4f"),n); wxColour txtcolor(255,255,255); dc.Clear(); dc.SetTextForeground(txtcolor); dc.DrawText(msg,0,0); */ size_t colorcnt=GetColorCount(layer); if (colorcnt <= 1) { palette[layer].GetColor(0,color); return; } if (n >= 1.0) n=0.99999; if (n < 0.0) n=0.0; double realidx=circular ? n*colorcnt : n*(colorcnt-1); int coloridx1=floor(realidx); int coloridx2=(coloridx1+1) % colorcnt; double ratio=realidx-double(coloridx1); Get2ColorBlend(layer,coloridx1,coloridx2,ratio,color); }
void RgbEffects::RenderTwinkle(int Count,int Steps, bool Strobe) { int x,y,i,i7,ColorIdx; int lights = (BufferHt*BufferWi)*(Count/100.0); // Count is in range of 1-100 from slider bar int step; if(lights>0) step=BufferHt*BufferWi/lights; else step=1; int max_modulo; 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; if(Strobe) srand (time(NULL)); // for strobe effect, make lights be random else srand(1); // else always have the same random numbers for each frame (state) wxImage::HSVValue hsv; // we will define an hsv color model. The RGB colot model would have been "wxColour color;" size_t colorcnt=GetColorCount(); i=0; for (y=0; y<BufferHt; y++) // For my 20x120 megatree, BufferHt=120 { for (x=0; x<BufferWi; x++) // BufferWi=20 in the above example { i++; if(i%step==1 || step==1) // Should we draw a light? { // Yes, so now decide on what color it should be ColorIdx=rand() % colorcnt; // Select random numbers from 0 up to number of colors the user has checked. 0-5 if 6 boxes checked palette.GetHSV(ColorIdx, hsv); // Now go and get the hsv value for this ColorIdx // mod_number=rand()% max_modulo; // if(mod_number<1) mod_number=1; // i7=(state/4) % mod_number; // Our twinkle is 9 steps. 4 ramping up, 5th at full brightness and then 4 more ramping down // Note that we are adding state to this calculation, this causes a different blink rate for each light i7=(state+rand())% max_modulo; // if(i7==0 || i7==8) hsv.value = 0.1; // if(i7==1 || i7==7) hsv.value = 0.3; // if(i7==2 || i7==6) hsv.value = 0.5; // if(i7==3 || i7==5) hsv.value = 0.7; // if(i7==4) hsv.value = 1.0; // else hsv.value = 0.0; if(i7<=max_modulo2) { if(max_modulo2>0) hsv.value = (1.0*i7)/max_modulo2; else hsv.value =0; } else { if(max_modulo2>0) hsv.value = (max_modulo-i7)*1.0/(max_modulo2); else hsv.value = 0; } if(hsv.value<0.0) hsv.value=0.0; if(Strobe) { if(i7==max_modulo2) hsv.value = 1.0; else hsv.value = 0.0; } // we left the Hue and Saturation alone, we are just modifiying the Brightness Value SetPixel(x,y,hsv); // Turn pixel on } } } }
//all shapes are loaded from same image file to reduce file I/O and caching //thiss also allows animated images to be self-contained void PianoRenderCache::Piano_load_shapes(RenderBuffer &buffer, const wxString& filename) { debug_function(10); //Debug debug("load_shapes('%s')", (const char*)filename.c_str()); debug(1, "load shapes file '%s'", (const char*)filename.c_str()); //reload shapes even if file name hasn't changed; color map might be different now // if (!CachedShapeFilename.CmpNoCase(filename)) { debug_more(2, ", no change"); return; } //no change if (!wxFileExists(filename)) return; Piano_flush_shapes(); //invalidate cached data if (!Shapes.LoadFile(filename, wxBITMAP_TYPE_ANY, 0) || !Shapes.IsOk()) { //wxMessageBox("Error loading image file: "+NewPictureName); Shapes.Clear(); return; } if (buffer.GetColorCount() < 2) return; //use colors from shapes file if no user-selected colors // int imgwidth=image.GetWidth(); // int imght =image.GetHeight(); // std::hash_map<WXCOLORREF, int> palcounts; //TODO: use wxImage.GetData for better performance? //TODO: use multiple images within same file? for (int y = Shapes.GetHeight() - 1; y >= 0; --y) //bottom->top for (int x = 0; x < Shapes.GetWidth(); ++x) //left->right if (!Shapes.IsTransparent(x, y)) { xlColor color, mapped; color.Set(Shapes.GetRed(x, y), Shapes.GetGreen(x, y), Shapes.GetBlue(x, y)); if (ColorMap.find(color.GetRGB()) != ColorMap.end()) continue; //already saw this color buffer.palette.GetColor(ColorMap.size() % buffer.GetColorCount(), mapped); //assign user-selected colors to shape palette sequentially, loop if run out of colors debug(10, "shape color[%d] 0x%x => user-selected color [%d] 0x%x", ColorMap.size(), color.GetRGB(), ColorMap.size() % GetColorCount(), mapped.GetRGB()); ColorMap[color.GetRGB()] = mapped; //.GetRGB(); // ShapePalette.push_back(c.GetRGB()); //keep a list of unique colors in order of occurrence from origin L-R, B-T } debug(2, "w %d, h %d, #colors %d", Shapes.GetWidth(), Shapes.GetHeight(), ColorMap.size()); CachedShapeFilename = filename; //don't load same file again }
void RgbEffects::RenderTree(int Branches) { int x,y,i,i7,r,ColorIdx,Count,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; srand(1); // always have the same random numbers for each frame (state) wxImage::HSVValue hsv; // we will define an hsv color model. The RGB colot model would have been "wxColour color;" pixels_per_branch=(int)(0.5+BufferHt/Branches); maxFrame=(Branches+1) *BufferWi; size_t colorcnt=GetColorCount(); frame = (state/4)%maxFrame; i=0; for (y=0; y<BufferHt; y++) // For my 20x120 megatree, BufferHt=120 { for (x=0; x<BufferWi; x++) // BufferWi=20 in the above example { mod=y%pixels_per_branch; if(mod==0) mod=pixels_per_branch; V=1-(1.0*mod/pixels_per_branch)*0.70; i++; ColorIdx=rand() % colorcnt; // Select random numbers from 0 up to number of colors the user has checked. 0-5 if 6 boxes checked ColorIdx=0; palette.GetHSV(ColorIdx, hsv); // Now go and get the hsv value for this ColorIdx hsv.value = V; // we have now set the color for the background tree // $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) ((state)/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 = (state/4)%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 = BufferWi-x+1; f_mod_odd = BufferWi-f_mod+1; if(branch<=b && x<=frame && // for branches below or equal to current row (((row==3 or (number_garlands==2 and row==6)) and (m==1 or m==6)) || ((row==2 or (number_garlands==2 and row==5)) and (m==2 or m==5)) || ((row==1 or (number_garlands==2 and row==4)) and (m==3 or m==4)) )) if((odd_even ==0 and x<=f_mod) || (odd_even ==1 and s_odd_row<=f_mod)) { hsv.hue = H; hsv.saturation=1.0; hsv.value=1.0; } // if(branch>b) // { // return $rgb_val; // for branches below current, dont dont balnk anything out // } // else if(branch==b) // { // if(odd_even ==0 and x>f_mod) // { // $rgb_val=$orig_rgbval;// we are even row ,counting from bottom as zero // } // if(odd_even ==1 and 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 SetPixel(x,y,hsv); // Turn pixel on } } }
void RgbEffects::RenderSingleStrandSkips(int Skips_BandSize, int Skips_SkipSize, int Skips_StartPos, const wxString & Skips_Direction) { int x = Skips_StartPos - 1; xlColour color, black(0,0,0); int second = 0; int max = BufferWi; int direction = mapDirection(Skips_Direction); if (direction > 1) { max /= 2; } size_t colorcnt = GetColorCount(); if (fitToTime) { int position = (GetEffectTimeIntervalPosition() * speed); x += position * Skips_BandSize; } else if (speed > 1) { int cur = state / 10; x += cur * Skips_BandSize; } while (x > max) { x -= (Skips_BandSize + Skips_SkipSize) * colorcnt; } int firstX = x; int colorIdx = 0; while (x < max) { palette.GetColor(colorIdx, color); colorIdx++; if (colorIdx >= colorcnt) { colorIdx = 0; } for (int cnt = 0; cnt < Skips_BandSize && x < max; cnt++) { int mappedX = mapX(x, max, direction, second); if (mappedX >= 0 && mappedX < BufferWi) { for (int y = 0; y < BufferHt; y++) { SetPixel(mappedX, y, color); } } if (second >= 0 && second < BufferWi) { for (int y = 0; y < BufferHt; y++) { SetPixel(second, y, color); } } x++; } x += Skips_SkipSize; } colorIdx = GetColorCount() - 1; x = firstX - 1; while (x >= 0) { x -= Skips_SkipSize; palette.GetColor(colorIdx, color); colorIdx--; if (colorIdx < 0) { colorIdx = GetColorCount() - 1; } for (int cnt = 0; cnt < Skips_BandSize && x >= 0; cnt++) { int mappedX = mapX(x, max, direction, second); if (mappedX >= 0 && mappedX < BufferWi) { for (int y = 0; y < BufferHt; y++) { SetPixel(mappedX, y, color); } } if (second >= 0 && second < BufferWi) { for (int y = 0; y < BufferHt; y++) { SetPixel(second, y, color); } } x--; } } }
void RgbEffects::draw_chase(int x,int y,wxImage::HSVValue hsv,int ColorScheme,int Number_Chases, int width,bool R_TO_L1,int Chase_Width,bool Chase_Fade3d1, int ChaseDirection) { float orig_v,new_v; int new_x,i,max_chase_width,pixels_per_chase; size_t colorcnt=GetColorCount(); int ColorIdx; orig_v=hsv.value; SetPixel(x,y,hsv); // Turn pixel on max_chase_width = width * Chase_Width/100.0; pixels_per_chase = width/Number_Chases; int pulsar=0; int n; float val; int mid = 0.5 + (max_chase_width/2.0); int pixels_per_color=max_chase_width/colorcnt; if(pixels_per_color<1) pixels_per_color=1; /* RRRRGGGG........+........................ .RRRRGGGG.......+........................ ..RRRRGGGG......+........................ ...RRRRGGGG.....+........................ ....RRRRGGGG....+........................ .....RRRRGGGG...+........................ ......RRRRGGGG..+........................ .......RRRRGGGG.+........................ ........RRRRGGGG+..............<=========== this is what fist version would end at .........RRRRGGG+........................ .........RRRRGG+........................ .........RRRRG+........................ .........RRRR+........................ .........RRR+........................ */ if(max_chase_width>=1) { for (i=0; i<=max_chase_width; i++) { if(pulsar==1) { n=state%10; switch (n) { case 0: case 4: pulse(x,y,hsv,0.30); break; case 1: case 3: pulse(x,y,hsv,0.50); pulse(x-1,y,hsv,0.30); pulse(x+1,y,hsv,0.30); break; case 2: pulse(x,y,hsv,1.0); pulse(x-1,y,hsv,0.50); pulse(x+1,y,hsv,0.50); pulse(x-2,y,hsv,0.30); pulse(x+2,y,hsv,0.30); break; } } else // not pulsar { if(ColorScheme==0) { if(max_chase_width) hsv.hue = 1.0 - (i*1.0/max_chase_width); // rainbow hue } // if(R_TO_L1) if(ChaseDirection==1) // are we going R-L? new_x = x-i; // yes else new_x = x+i; if(new_x<0) { y++; ChaseDirection=1; // we were going R to L, now switch to L-R new_x+=width; } else if(new_x>width) { y++; ChaseDirection=0; // we were going L-R, now switch to R-L new_x-=width; } //new_x=new_x%BufferWi; if(i<=pixels_per_chase) // as long as the chase fits, keep drawing it { if(ColorScheme==0) SetPixel(new_x,y,hsv); // Turn pixel on else { if(colorcnt==1) ColorIdx=0; else { ColorIdx=i/pixels_per_color; } if(ColorIdx>=colorcnt) ColorIdx=colorcnt-1; palette.GetHSV(ColorIdx, hsv); if(Chase_Fade3d1) hsv.value=orig_v - (i*1.0/max_chase_width); // fades data down over chase width if(hsv.value<0.0) hsv.value=0.0; SetPixel(new_x,y,hsv); // Turn pixel on } } } } } }
void RgbEffects::RenderSingleStrandChase(int ColorScheme,int Number_Chases, int Color_Mix1,int Chase_Spacing1, int Chase_Type1,bool Chase_Fade3d1,bool Chase_Group_All) { int x,x1,x0,y,i,ColorIdx,chases,width,slow_state; int x2=0; int x_2=0; int x2_mod=0; int color_index,x1_mod,mod_ChaseDirection; int MaxNodes,xt,Dual_Chases,All_Arches=0; int start1,start2,start1_mid,xend,start1_group; float dx; bool R_TO_L1; //srand (time(NULL)); // for strobe effect, make lights be random srand(1); // else always have the same random numbers for each frame (state) wxImage::HSVValue hsv; // we will define an hsv color model. The RGB colot model would have been "wxColour color;" size_t colorcnt=GetColorCount(); // global now set to how many colors have been picked y=BufferHt; i=0; int state_width = state/BufferWi; int state_col = (state_width*BufferWi) + state%10; int state_ht = state_width%BufferHt; // 0 .. (BufferHt-1) int curEffStartPer, curEffEndPer, nextEffTimePeriod; GetEffectPeriods( curEffStartPer, nextEffTimePeriod, curEffEndPer); double rtval = GetEffectTimeIntervalPosition(); if(Chase_Spacing1<1) Chase_Spacing1=1; int ymax=BufferHt; if(Chase_Group_All || Chase_Type1==3) MaxNodes= BufferWi*BufferHt; else MaxNodes=BufferWi; int MaxChase=MaxNodes*(Color_Mix1/100.0); if(MaxChase<1) MaxChase=1; int nodes_per_color = int(MaxChase/colorcnt); if(nodes_per_color<1) nodes_per_color=1; // fill chase buffer hsv.value=0.0; hsv.saturation=1.0; hsv.hue=0.0; int AutoReverse=0; start1 = state % BufferWi; start1 = (int)(state/2) % MaxNodes; // divide by 4 slows down chase start1_group = (int)(state/2) / MaxNodes; // divide by 4 slows down chase start2 = MaxNodes-start1; start1_mid = MaxNodes/2; if(state==0) ChaseDirection=0; // initialize it once at the beggining of this sequence. switch (Chase_Type1) { case 0: // "Normal. L-R" R_TO_L1=0; break; case 1: // "Normal. R-L" R_TO_L1=1; break; case 2: // "Auto reverse" AutoReverse=1; break; case 3: // "Bounce" Dual_Chases=1; break; case 4: // "Pacman" break; } // we have a global variablal, ChaseDirection, which indicates which way we are moving. int FIT_TO_TIME=(fitToTime); int numberFrames=0; if(fitToTime) // is "Fit to Time" checked? { numberFrames=nextEffTimePeriod-nextEffTimePeriod; // GetEffectPeriods( nextEffTimePeriod, nextEffTimePeriod, curEffEndPer); // double rtval = GetEffectTimeIntervalPosition(); // rtval 0 to 1.0. This indicates how far we are through this row on the grid. // 0.0 we are just starting the effect on this row // 1.0 we have come t the end of time for this effect } hsv.value=1.0; hsv.saturation=1.0; hsv.hue=0.0; // RED if(Chase_Group_All) { width=MaxNodes; } else { width=BufferWi; } if(Number_Chases<1) Number_Chases=1; if(ColorScheme<0) ColorScheme=0; dx = width/Number_Chases; if(dx<1) dx=1.0; for(chases=1; chases<=Number_Chases; chases++) { if(fitToTime) slow_state = width * rtval; else slow_state = (state/4)%width; // if(R_TO_L1) mod_ChaseDirection=ChaseDirection%2; // 0= R-L, 1=L-R if(AutoReverse) // if we are bouncing back and forth { if(mod_ChaseDirection==1) // which direction should we be going x1=int(0.5 + (chases-1)*dx)+slow_state; // L-R else x1=int(0.5 + width-((chases-1)*dx)-slow_state); // R-L } else // we are just doing L-R or R-L { if(R_TO_L1) // 1 = L-R, 0=R-L x1=int(0.5 + (chases-1)*dx)+slow_state; // L-R else x1=int(0.5 + width-((chases-1)*dx)-slow_state); // R-L } if(x1<=0) { x1+=width; ChaseDirection++; } else if(x1>=width) { x1-=width; ChaseDirection++; } if(x1<0) x1=0; x=x1%BufferWi; if(Chase_Group_All) { y = (x1%MaxNodes)/BufferWi; draw_chase(x,y,hsv,ColorScheme,Number_Chases,width,R_TO_L1,Color_Mix1,Chase_Fade3d1,ChaseDirection); // Turn pixel on } else { // NOT A GROUP for(y=0; y<BufferHt; y++) { draw_chase(x,y,hsv,ColorScheme,Number_Chases,width,R_TO_L1,Color_Mix1,Chase_Fade3d1,ChaseDirection); // Turn pixel on if(Dual_Chases) { if(R_TO_L1) // 1 = L-R, 0=R-L x2=width-x-1; else x2=width-x-1; draw_chase(x2,y,hsv,ColorScheme,Number_Chases,width,R_TO_L1,Color_Mix1,Chase_Fade3d1,ChaseDirection); // } } } } }
void RgbEffects::RenderCircles(int number,int radius, bool bounce, bool collide, bool random, bool radial, bool radial_3D, int start_x, int start_y, bool plasma) { int ii=0; int colorIdx; size_t colorCnt=GetColorCount(); wxImage::HSVValue hsv; float spd; float angle; static int numBalls = 0; RgbBalls *effectObjects; static bool metaType=false; if(plasma) { effectObjects = metaballs; } else { effectObjects = balls; } if (radial) { RenderRadial(start_x, start_y, radius, colorCnt, number, radial_3D); return; //radial is the easiest case so just get out. } if ( 0 == state || radius != effectObjects[ii]._radius || number != numBalls || metaType != plasma) { numBalls = number; for(ii=0; ii<number; ii++) { start_x = rand()%(BufferWi); start_y = rand()%(BufferHt); colorIdx = ii%colorCnt; palette.GetHSV(colorIdx, hsv); spd = rand()%3 + 1; angle = rand()%2?rand()%90:-rand()%90; effectObjects[ii].Reset((float) start_x, (float) start_y, spd, angle, (float)radius, hsv); } metaType=plasma; } else { RenderCirclesUpdate(number, effectObjects); } if (bounce) { //update position in case something hit a wall for(ii = 0; ii < number; ii++) { effectObjects[ii].Bounce(BufferWi,BufferHt); } } if(collide) { //update position if two balls collided } if (plasma) { RenderMetaBalls(numBalls); } else { for (ii=0; ii<number; ii++) { hsv = balls[ii].hsvcolor; for(int r = balls[ii]._radius; r >= 0; r--) { if(!bounce && !collide) { DrawCircle(balls[ii]._x, balls[ii]._y, r, hsv); } else { DrawCircleClipped(balls[ii]._x, balls[ii]._y, r, hsv); } } } } }
void RgbEffects::RenderSpirals(int PaletteRepeat, int Direction, int Rotation, int Thickness, bool Blend, bool Show3D, bool grow, bool shrink) { int strand_base,strand,thick,x,y,ColorIdx; size_t colorcnt=GetColorCount(); int SpiralCount=colorcnt * PaletteRepeat; int deltaStrands=BufferWi / SpiralCount; int SpiralThickness=(deltaStrands * Thickness / 100) + 1; int spiralGap = deltaStrands - SpiralThickness; long SpiralState; long ThicknessState = state/10; wxImage::HSVValue hsv; wxColour color; if (fitToTime) { double position = GetEffectTimeIntervalPosition(); if (grow&&shrink) { ThicknessState = position <= 0.5?spiralGap*(position*2):spiralGap*((1-position) * 2); } else if (grow) { ThicknessState = spiralGap *position; } else if (shrink) { ThicknessState = spiralGap * (1-position); } SpiralState = position*BufferWi*10*Direction; } else { SpiralState=state*Direction; } spiralGap += (spiralGap==0); if (grow && (!shrink || ((ThicknessState/spiralGap)%2)==0)) { SpiralThickness += ThicknessState%(spiralGap); } else if (shrink && (!grow || ((ThicknessState/spiralGap)%2)==1)) { SpiralThickness +=spiralGap-ThicknessState%(spiralGap); } for(int ns=0; ns < SpiralCount; ns++) { strand_base=ns * deltaStrands; ColorIdx=ns % colorcnt; palette.GetColor(ColorIdx,color); for(thick=0; thick < SpiralThickness; thick++) { strand = (strand_base + thick) % BufferWi; for(y=0; y < BufferHt; y++) { x=(strand + SpiralState/10 + y*Rotation/BufferHt) % BufferWi; if (x < 0) x += BufferWi; if (Blend) { GetMultiColorBlend(double(BufferHt-y-1)/double(BufferHt), false, color); } if (Show3D) { Color2HSV(color,hsv); if (Rotation < 0) { hsv.value*=double(thick+1)/SpiralThickness; } else { hsv.value*=double(SpiralThickness-thick)/SpiralThickness; } SetPixel(x,y,hsv); } else { SetPixel(x,y,color); } } } } }
void RgbEffects::RenderRipple(int Object_To_Draw, int Movement) { int x,y,i,i7,ColorIdx; int xc,yc; #if 0 if(step<1) step=1; if(Use_All_Colors) srand (time(NULL)); // for Use_All_Colors effect, make lights be random else srand(1); // else always have the same random numbers for each frame (state) #endif wxImage::HSVValue hsv; // we will define an hsv color model. The RGB colot model would have been "wxColour color;" srand (time(NULL)); size_t colorcnt=GetColorCount(); i=0; double position = GetEffectTimeIntervalPosition(); // how far are we into the row> value is 0.0 to 1.0 float rx; xc = BufferWi/2; yc=BufferHt/2; int on_off=0; int slices=200; int istate=state/slices; // istate will be a counter every slices units of state. each istate is a square wave int imod=(state/(slices/10))%10; // divide this square int icolor=istate%colorcnt; wxString TimeNow =wxNow(); rx=(state%slices)/(slices*1.0); int x1 = xc - (xc*rx); int x2 = xc + (xc*rx); int y1 = yc - (yc*rx); int y2 = yc + (yc*rx); enum {Square, Circle, Triangle} shape = Circle; double radius; // debug(10, "%s:%6d istate=%4d imod=%4d icolor=%1d", (const char*)TimeNow,state,istate,imod,icolor); ColorIdx=rand()% colorcnt; // Select random numbers from 0 up to number of colors the user has checked. 0-5 if 6 boxes checked palette.GetHSV(ColorIdx, hsv); // Now go and get the hsv value for this ColorIdx int explode; switch (Object_To_Draw) { case RENDER_RIPPLE_SQUARE: explode=1; if(Movement==MOVEMENT_EXPLODE) { // This is the object expanding out, or explode looikng int x1 = xc - (xc*rx); int x2 = xc + (xc*rx); int y1 = yc - (yc*rx); int y2 = yc + (yc*rx); for(y=y1; y<=y2; y++) { SetP(x1,y,hsv); // Turn pixel SetP(x2,y,hsv); // Turn pixel } for(x=x1; x<=x2; x++) { SetP(x,y1,hsv); // Turn pixel SetP(x,y2,hsv); // Turn pixel } hsv.value = (hsv.value /3)*2; for(y=y1; y<=y2; y++) { SetP(x1+1,y,hsv); // Turn pixel SetP(x2-1,y,hsv); // Turn pixel } for(x=x1; x<=x2; x++) { SetP(x,y1+1,hsv); // Turn pixel SetP(x,y2-1,hsv); // Turn pixel } hsv.value = hsv.value /3; for(y=y1; y<=y2; y++) { SetP(x1+2,y,hsv); // Turn pixel SetP(x2-2,y,hsv); // Turn pixel } for(x=x1; x<=x2; x++) { SetP(x,y1+2,hsv); // Turn pixel SetP(x,y2-2,hsv); // Turn pixel } } else if(Movement==MOVEMENT_IMPLODE) { int x1 = (xc*rx); int x2 = BufferWi - (xc*rx); int y1 = (yc*rx); int y2 = BufferHt - (yc*rx); for(y=y2; y>=y1; y--) { SetP(x1,y,hsv); // Turn pixel SetP(x2,y,hsv); // Turn pixel } for(x=x2; x>=x1; x--) { SetP(x,y1,hsv); // Turn pixel SetP(x,y2,hsv); // Turn pixel } } break; case RENDER_RIPPLE_CIRCLE: if(Movement==MOVEMENT_IMPLODE) radius = xc-(xc*rx); else radius = (xc*rx); Drawcircle( xc, yc, radius, hsv); radius=radius/2; Drawcircle( xc, yc, radius, hsv); radius=radius/2; Drawcircle( xc, yc, radius, hsv); radius=radius/2; Drawcircle( xc, yc, radius, hsv); break; case RENDER_RIPPLE_TRIANGLE: break; } }
void RgbEffects::RenderFireworks(int Number_Explosions,int Count,float Velocity,int Fade) { int idxFlakes=0; int i=0,mod100; int x25,x75,y25,y75,stateChunk,denom; const int maxFlakes = 1000; //float velocity = 3.5; int startX; int startY,ColorIdx; float v; wxImage::HSVValue hsv; wxColour color,rgbcolor; size_t colorcnt=GetColorCount(); if(state==0) for(i=0; i<maxFlakes; i++) { fireworkBursts[i]._bActive = false; } denom = (101-Number_Explosions)*100; if(denom<1) denom=1; stateChunk = (int)state/denom; if(stateChunk<1) stateChunk=1; mod100 = state%((101-Number_Explosions)*20); // mod100 = (int)(state/stateChunk); // mod100 = mod100%10; if(mod100 == 0) { x25=(int)BufferWi*0.25; x75=(int)BufferWi*0.75; y25=(int)BufferHt*0.25; y75=(int)BufferHt*0.75; startX=(int)BufferWi/2; startY=(int)BufferHt/2; if((x75-x25)>0) startX = x25 + rand()%(x75-x25); else startX=0; if((y75-y25)>0) startY = y25 + rand()%(y75-y25); else startY=0; // Create a new burst ColorIdx=rand() % colorcnt; // Select random numbers from 0 up to number of colors the user has checked. 0-5 if 6 boxes checked palette.GetHSV(ColorIdx, hsv); // Now go and get the hsv value for this ColorIdx for(i=0; i<Count; i++) { do { idxFlakes = (idxFlakes + 1) % maxFlakes; } while (fireworkBursts[idxFlakes]._bActive); fireworkBursts[idxFlakes].Reset(startX, startY, true, Velocity, hsv); } } // else if (mod100<10) // { // rgbcolor = wxColour(0,255,255); // Color2HSV(color,hsv); // y=(int)(startY-startY*(1.0/(mod100+1))); // SetPixel(startX,y,hsv); // } else { for (i=0; i<maxFlakes; i++) { // ... active flakes: if (fireworkBursts[i]._bActive) { // Update position fireworkBursts[i]._x += fireworkBursts[i]._dx; fireworkBursts[i]._y += (-fireworkBursts[i]._dy - fireworkBursts[i]._cycles*fireworkBursts[i]._cycles/10000000.0); // If this flake run for more than maxCycle or this flake is out of bounds, time to switch it off fireworkBursts[i]._cycles+=20; if (fireworkBursts[i]._cycles >= 10000 || fireworkBursts[i]._y >= BufferHt || fireworkBursts[i]._x < 0. || fireworkBursts[i]._x >= BufferWi) { fireworkBursts[i]._bActive = false; continue; } } } } for(i=0; i < 1000; i++) { if(fireworkBursts[i]._bActive == true) { v = ((Fade*10.0)-fireworkBursts[i]._cycles)/(Fade*10.0); if(v<0) v=0.0; hsv=fireworkBursts[i]._hsv; hsv.value=v; SetPixel(fireworkBursts[i]._x, fireworkBursts[i]._y, hsv); } } }
void RgbEffects::RenderSean(int Count) { int x,y,i,i7,r,ColorIdx; int lights = (BufferHt*BufferWi)*(Count/100.0); // Count is in range of 1-100 from slider bar int step=BufferHt*BufferWi/lights; if(step<1) step=1; double damping=0.8; srand(1); // always have the same random numbers for each frame (state) wxImage::HSVValue hsv,hsv0,hsv1; // we will define an hsv color model. The RGB colot model would have been "wxColour color;" wxColour color; int color1,color2,color3,color4,new_color,old_color; size_t colorcnt=GetColorCount(); i=0; palette.GetHSV(0, hsv0); // hsv0.hue, hsv0.saturation, hsv0.value palette.GetHSV(1, hsv1); if(state==0) { ClearWaveBuffer1(); ClearWaveBuffer2(); color1=100; } if(state%20==0) { color1=100; SetWaveBuffer2((BufferWi+state)%BufferWi,(BufferHt+state)%BufferHt,color1); SetWaveBuffer2((BufferWi+state)%BufferWi,(BufferHt+state)%BufferHt,color1); } for (y=1; y<BufferHt-1; y++) // For my 20x120 megatree, BufferHt=120 { for (x=1; x<BufferWi-1; x++) // BufferWi=20 in the above example { // GetTempPixel(x,y,color); // isLive=(color.GetRGB() != 0); old_color=GetWaveBuffer1(x,y) ; color1=GetWaveBuffer2(x-1,y-1); color2=GetWaveBuffer2(x+1,y+1) ; color3=GetWaveBuffer2(x+1,y-1) ; color4=GetWaveBuffer2(x+1,y+1) ; new_color = (color1+color2+color3+color4)/2 - old_color; // new_color = (127.0+224.0*0.99999*new_color/8192.); new_color=new_color/8.0; SetWaveBuffer1(x,y,new_color); } } for (y=0; y<BufferHt; y++) // For my 20x120 megatree, BufferHt=120 { for (x=0; x<BufferWi; x++) // BufferWi=20 in the above example { new_color=GetWaveBuffer1(x,y); if(new_color>= -0.01 && new_color<= 0.01) { SetPixel(x,y,hsv1); } else { if(new_color>0) { hsv0.value = (new_color%100)/100.0; SetPixel(x,y,hsv0); } else { hsv0.hue = 0.3; hsv0.value = -(new_color%100)/100.0; SetPixel(x,y,hsv0); } } } } WaveBuffer0=WaveBuffer2; WaveBuffer2=WaveBuffer1; WaveBuffer1=WaveBuffer0; }
void RgbEffects::RenderFaces(int Phoneme) { /* FacesPhoneme.Add("AI"); 0 FacesPhoneme.Add("E"); 1 FacesPhoneme.Add("FV"); 2 FacesPhoneme.Add("L"); 3 FacesPhoneme.Add("MBP"); 4 FacesPhoneme.Add("O"); 5 FacesPhoneme.Add("U"); 6 FacesPhoneme.Add("WQ"); 7 FacesPhoneme.Add("etc"); 8 FacesPhoneme.Add("rest"); 9 */ wxColour color; wxImage::HSVValue hsv; int maxframe=BufferHt*2; int frame=(BufferHt * state / 200)%maxframe; double offset=double(state)/100.0; size_t colorcnt=GetColorCount(); // xout->SetIntensity(1000, 1); std::vector<int> chmap; chmap.resize(BufferHt * BufferWi,0); wxString html = "<html><body><table border=0>"; int Ht, Wt; Ht = BufferHt; Wt = BufferWi; mouth( Phoneme, Ht, Wt); // draw a mouth syllable //size_t NodeCount=GetNodeCount(); // above is from ModelClass::ChannelLayoutHtml() #if 0 //DEBUG //get list of models: wxString buf; for (auto it = xLightsFrame::PreviewModels.begin(); it != xLightsFrame::PreviewModels.end(); ++it) buf += ", " + (*it)->name; //ModelClassPtr* debug(1, "faces: models = %s", (const char*)buf + 2); //get info about one of the models: buf = xLightsFrame::PreviewModels[0]->name; debug(1, "first model is %s", (const char*)buf); buf = xLightsFrame::PreviewModels[0]->ChannelLayoutHtml(); if (buf.size() > 500) buf.resize(500); debug(1, "first 500 char of layout html = %s", (const char*)buf); #endif #if 1 //example code to map pixels back to channels wxString model; //set to target model name (optional) for (int y=0; y<BufferHt; y++) // For my 20x120 megatree, BufferHt=120 { for (int x=0; x<BufferWi; x++) // BufferWi=20 in the above example { // ch = GetChannel(x,y); // <== I need something like this routine // wxImage::HSVValue hsv = GetPixel(x, y); GetPixel(x, y, color); // hsv0 = wxImage::RGBtoHSV( wxImage::RGBValue( c0.Red(), c0.Green(), c0.Blue())); // wxColor color, mapped; // color.Set(Shapes.GetRed(x, y), Shapes.GetGreen(x, y), Shapes.GetBlue(x, y)); // ColorMap[color.GetRGB() if (!color.GetRGB()) continue; //color == BLACK) continue; //pixel is off int ch = FindChannelAt(x, y, model); // debug(1, "pixel (%d, %d) = 0x%6x is channel %d in model %s", x, y, ch, (const char*)(model.IsEmpty()? "(any)": model.c_str())); } } #endif }
void RgbEffects::RenderSnowstorm(int Count, int Length) { // create new meteors wxImage::HSVValue hsv,hsv0,hsv1; palette.GetHSV(0,hsv0); palette.GetHSV(1,hsv1); size_t colorcnt=GetColorCount(); Count=BufferWi * BufferHt * Count / 2000 + 1; int TailLength=BufferWi * BufferHt * Length / 2000 + 2; SnowstormClass ssItem; wxPoint xy; int r; if (state == 0 || Count != LastSnowstormCount) { // create snowstorm elements LastSnowstormCount=Count; SnowstormItems.clear(); for(int i=0; i<Count; i++) { ssItem.idx=i; ssItem.ssDecay=0; ssItem.points.clear(); SetRangeColor(hsv0,hsv1,ssItem.hsv); // start in a random state r=rand() % (2*TailLength); if (r > 0) { xy.x=rand() % BufferWi; xy.y=rand() % BufferHt; ssItem.points.push_back(xy); } if (r >= TailLength) { ssItem.ssDecay = r - TailLength; r = TailLength; } for (int j=1; j < r; j++) { SnowstormAdvance(ssItem); } SnowstormItems.push_back(ssItem); } } // render Snowstorm Items int sz; int cnt=0; for (SnowstormList::iterator it=SnowstormItems.begin(); it!=SnowstormItems.end(); ++it) { if (it->points.size() > TailLength) { if (it->ssDecay > TailLength) { it->points.clear(); // start over it->ssDecay=0; } else if (rand() % 20 < speed) { it->ssDecay++; } } if (it->points.empty()) { xy.x=rand() % BufferWi; xy.y=rand() % BufferHt; it->points.push_back(xy); } else if (rand() % 20 < speed) { SnowstormAdvance(*it); } sz=it->points.size(); for(int pt=0; pt < sz; pt++) { hsv=it->hsv; hsv.value=1.0 - double(sz - pt + it->ssDecay)/TailLength; if (hsv.value < 0.0) hsv.value=0.0; SetPixel(it->points[pt].x,it->points[pt].y,hsv); } cnt++; } }
void RgbEffects::RenderText(int Position1, const wxString& Line1, const wxString& FontString1,int dir1,int TextRotation1,bool COUNTDOWN1, int Position2, const wxString& Line2, const wxString& FontString2,int dir2,int TextRotation2,bool COUNTDOWN2) { wxColour c; wxString vertMsg; wxBitmap bitmap(BufferWi,BufferHt); wxMemoryDC dc(bitmap); wxFont font; int ColorIdx,itmp,i; long L1,longsecs1,longsecs2,seconds; bool COUNTDOWN=true; int days,hours,minutes; bool DAYS_STRING=true; size_t colorcnt=GetColorCount(); srand(1); // always have the same random numbers for each frame (state) wxImage::HSVValue hsv; // we will define an hsv color model. The RGB colot model would have been "wxColour color;" ColorIdx=rand() % colorcnt; // Select random numbers from 0 up to number of colors the user has checked. 0-5 if 6 boxes checked palette.GetHSV(ColorIdx, hsv); // Now go and get the hsv value for this ColorIdx font.SetNativeFontInfoUserDesc(FontString1); dc.SetFont(font); palette.GetColor(0,c); dc.SetTextForeground(c); wxString msg; wxSize sz1 = dc.GetTextExtent(Line1); int maxwidth=sz1.GetWidth(); int maxht=sz1.GetHeight(); L1=0; if(state==0 and COUNTDOWN1 and Line1.ToLong(&L1)) { timer_countdown1=L1+1; // set their counter one higher since teh first thing we do it subtract one from it. } if(state==0 and COUNTDOWN2 and Line2.ToLong(&L1)) { timer_countdown2=L1+1; // we can have concurrent timers, one for each line of text } if(dir1==4) { maxht = maxht*Line1.length(); for(i=0; i<Line1.length(); i++) { msg = msg + Line1.GetChar(i) + "\n"; } } else if(dir1==5) { maxht = maxht*Line1.length(); for(i=0; i<Line1.length(); i++) { msg = msg + Line1.GetChar(Line1.length()-i-1) + "\n"; } } else { msg = Line1; if(COUNTDOWN1) { longsecs1=wxGetUTCTime () ; if(longsecs1 != old_longsecs1) timer_countdown1--; old_longsecs1=longsecs1; if(timer_countdown1 < 0) timer_countdown1=0; msg=wxString::Format(wxT("%i"),timer_countdown1); } if(TextRotation1==1) { itmp=maxwidth; maxwidth=maxht; maxht=itmp; } } int dctop= Position1 * BufferHt / 50 - BufferHt/2; int xlimit=(BufferWi+maxwidth)*8 + 1; int ylimit=(BufferHt+maxht)*8 + 1; // int xcentered=(BufferWi-maxwidth)/2; // original way int xcentered=Position1 * BufferWi / 50 - BufferWi/2; TextRotation1 *=90.0; switch (dir1) { case 0: // left //dc.DrawText(msg,BufferWi-state % xlimit/8,dctop); dc.DrawRotatedText(msg,BufferWi-state % xlimit/8,dctop,TextRotation1); break; case 1: // right //dc.DrawText(msg,state % xlimit/8-BufferWi,dctop); dc.DrawRotatedText(msg,state % xlimit/8-BufferWi,dctop,TextRotation1); break; case 2: // up // dc.DrawText(msg,xcentered,BufferHt-state % ylimit/8); dc.DrawRotatedText(msg,xcentered,BufferHt-state % ylimit/8,TextRotation1); break; case 3: // down // dc.DrawText(msg,xcentered,state % ylimit / 8 - BufferHt); dc.DrawRotatedText(msg,xcentered,state % ylimit / 8 - BufferHt,TextRotation1); break; case 4: // vertical text up dc.DrawText(msg,xcentered,BufferHt-(state % ylimit/8)); break; case 5: // vertical text down dc.DrawText(msg,xcentered,(state % ylimit/8) - maxht); break; default: // no movement - centered // dc.DrawText(msg,xcentered,dctop); dc.DrawRotatedText(msg,xcentered,dctop,TextRotation1); break; } // Line2 msg=""; font.SetNativeFontInfoUserDesc(FontString2); dc.SetFont(font); if(colorcnt>1) palette.GetColor(1,c); // scm 7-18-13. added if,. only pull color if we have at least two colors checked in palette dc.SetTextForeground(c); wxSize sz2 = dc.GetTextExtent(Line2); maxwidth=sz2.GetWidth(); maxht=sz2.GetHeight(); if(dir2==4) { maxht = maxht*Line2.length(); for(i=0; i<Line2.length(); i++) { msg = msg + Line2.GetChar(i) + "\n"; } } else if(dir2==5) { maxht = maxht*Line2.length(); for(i=0; i<Line2.length(); i++) { msg = msg + Line2.GetChar(Line2.length()-i-1) + "\n"; } } else { msg = Line2; if(COUNTDOWN2) { longsecs2=wxGetUTCTime () ; if(longsecs2 != old_longsecs2) timer_countdown2--; old_longsecs2=longsecs2; if(timer_countdown2 < 0) timer_countdown2=0; if(DAYS_STRING) { days = timer_countdown2 / 60 / 60 / 24; hours = (timer_countdown2 / 60 / 60) % 24; minutes = (timer_countdown2 / 60) % 60; seconds = timer_countdown2 % 60; msg=wxString::Format(wxT("%i d %i h %i m %i s"),days,hours,minutes,seconds); } else { msg=wxString::Format(wxT("%i"),timer_countdown2); } } if(TextRotation2==1) { itmp=maxwidth; maxwidth=maxht; maxht=itmp; } } dctop= Position2 * BufferHt / 50 - BufferHt/2; xlimit=(BufferWi+maxwidth)*8 + 1; ylimit=(BufferHt+maxht)*8 + 1; // int xcentered=(BufferWi-maxwidth)/2; // original way xcentered=Position2 * BufferWi / 50 - BufferWi/2; TextRotation2 *=90.0; switch (dir2) { case 0: // left //dc.DrawText(msg,BufferWi-state % xlimit/8,dctop); dc.DrawRotatedText(msg,BufferWi-state % xlimit/8,dctop,TextRotation2); break; case 1: // right //dc.DrawText(msg,state % xlimit/8-BufferWi,dctop); dc.DrawRotatedText(msg,state % xlimit/8-BufferWi,dctop,TextRotation2); break; case 2: // up // dc.DrawText(msg,xcentered,BufferHt-state % ylimit/8); dc.DrawRotatedText(msg,xcentered,BufferHt-state % ylimit/8,TextRotation2); break; case 3: // down // dc.DrawText(msg,xcentered,state % ylimit / 8 - BufferHt); dc.DrawRotatedText(msg,xcentered,state % ylimit / 8 - BufferHt,TextRotation2); break; case 4: // vertical text up dc.DrawText(msg,xcentered,BufferHt-(state % ylimit/8)); break; case 5: // vertical text down dc.DrawText(msg,xcentered,(state % ylimit/8) - maxht); break; default: // no movement - centered // dc.DrawText(msg,xcentered,dctop); dc.DrawRotatedText(msg,xcentered,dctop,TextRotation2); break; } // copy dc to buffer for(wxCoord x=0; x<BufferWi; x++) { for(wxCoord y=0; y<BufferHt; y++) { dc.GetPixel(x,BufferHt-y-1,&c); SetPixel(x,y,c); // ColorIdx=(n % BlockHt) / BarHt; // palette.GetHSV(ColorIdx, hsv); } } }