Author: Copyright 2012, MetaQuotes Software Corp.
0 Views
0 Downloads
0 Favorites
flame
//+------------------------------------------------------------------+
//|                                                        Flame.mq5 |
//|                        Copyright 2012, MetaQuotes Software Corp. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2012, MetaQuotes Software Corp."
#property link      "http://www.mql5.com"
#property version   "1.00"

#property indicator_chart_window // allow operation of a script and an Expert Advisor    
#property indicator_plots   1
#property indicator_buffers 1

#define SCREEN_CY 200            // define the height of the image (our flame is not high)                
//+------------------------------------------------------------------+
//| Necessary global variables                                       |
//+------------------------------------------------------------------+
uint    ExtPal[256];             // flame palette
uint    ExtScreen[];             // buffer for outputting to resource   
uchar   ExtFlame[][SCREEN_CY+1]; // flame calculation buffer
uint    ExtTime=0;               // time of the next event         
long    ExtChartID=0;            // our chart's ID
uint    ExtWidth=0;              // flame image width
uint    ExtY=0;                  // Point for binding the flame to the bottom
//+------------------------------------------------------------------+
//| Initialization                                                   |
//+------------------------------------------------------------------+
void OnInit()
  {
//--- store the chart's ID and create a graphical object bound to resource
   ExtChartID=ChartID();
   ObjectCreate(ExtChartID,"flame",OBJ_BITMAP_LABEL,0,0,0);
   ObjectSetString(ExtChartID,"flame",OBJPROP_BMPFILE,"::flame");
//--- create the palette
   double g=0,b=0,dg=1.5,db=0.63;
//---
   for(uint a,i=0;i<256;i++)
     {
      //--- the first 32 values of flame are completely transparent
      a=uchar(i<32?0:i-32);
      //--- generate color for the i value of flame
      ExtPal[i]=(a<<24)|(uint(255)<<16)|(uint(g+0.5)<<8)|uint(b+0.5);
      //--- increment the color components
      //--- the red color gets gradient due to transparency
      if(i>80)  g+=dg;
      if(i>160) b+=db;
     }
//--- determine the size of the chart and display the first frame
   Resize();
//--- arrange custom timer, OnTimer's 1 time per second is not enough
   EventChartCustom(ExtChartID,1302,0,0,NULL);
  }
//+------------------------------------------------------------------+
//| Remove                                                           |
//+------------------------------------------------------------------+
void OnDeinit(const int)
  {
   ObjectDelete(ExtChartID,"flame");
  }
//+------------------------------------------------------------------+
//| Calculate nothing                                                |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const int begin,
                const double &price[])
  {
   return(rates_total);
  }
//+------------------------------------------------------------------+
//| Event handling                                                   |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,const long &lp,const double &dp,const string &sp)
  {
   switch(id)
     {
      //--- organize custom timer
      case 2302:
         //--- time to draw the new frame?
         if(GetTickCount()>ExtTime)
           {
            //--- draw frame
            Calculate();
            //--- calculate time for the next frame
            ExtTime=GetTickCount()+20;
           }
         //--- generate next event for custom timer
         EventChartCustom(ExtChartID,1302,0,0,NULL);
         break;
         //--- changes on the chart
      case CHARTEVENT_CHART_CHANGE:
         //--- recalculate with new parameters
         Resize();
         break;
     }
  }
//+------------------------------------------------------------------+
//| Calculate and render frame                                       |
//+------------------------------------------------------------------+
void Calculate()
  {
//--- calculate new frame
   for(uint x=0;x<ExtWidth;x++)
      ExtFlame[x][SCREEN_CY]++;
//--- draw flame shapes
   for(uint y=SCREEN_CY-1;y>0;y--)
     {
      for(uint c,x=1,n=ExtWidth-1;x<n;x++)
        {
         c =ExtFlame[x-1][y]+ExtFlame[x+1][y];
         c+=ExtFlame[x-1][y+1]+ExtFlame[x][y+1]+ExtFlame[x+1][y+1];
         ExtFlame[x][y]=uchar(c/5);
        }
     }
//--- move flame to the resource buffer
   for(uint y=0;y<SCREEN_CY;y++)
      for(uint x=0;x<ExtWidth;x++)
         ExtScreen[y*ExtWidth+x]=ExtPal[ExtFlame[x][y]];
//--- update the resource and display it on the screen
   ResourceCreate("::flame",ExtScreen,ExtWidth,SCREEN_CY,0,0,ExtWidth,COLOR_FORMAT_ARGB_NORMALIZE);
   ChartRedraw(ExtChartID);
  }
//+------------------------------------------------------------------+
//| Chart update                                                     |
//+------------------------------------------------------------------+
void Resize()
  {
//--- request new chart size
   uint cx=(uint)ChartGetInteger(ExtChartID,CHART_WIDTH_IN_PIXELS);
   uint cy=(uint)ChartGetInteger(ExtChartID,CHART_HEIGHT_IN_PIXELS);
//--- chart's height changed - move the image
   if(ExtY!=cy)
     {
      ExtY=cy;
      ObjectSetInteger(ExtChartID,"flame",OBJPROP_YDISTANCE,ExtY-SCREEN_CY);
     }
//--- width changed
   if(ExtWidth!=cx)
     {
      //--- change size of the buffers
      ArrayResize(ExtScreen,cx*SCREEN_CY);
      ArrayResize(ExtFlame,cx);
      //--- expand the flame
      for(uint x=ExtWidth;x<cx;x++)
        {
         //--- zero out flame shapes
         for(uint y=0;y<SCREEN_CY;y++) ExtFlame[x][y]=0;
         //--- put some "wood"
            ExtFlame[x][SCREEN_CY]=uchar(rand()%256);
        }
      //--- update the size and re-draw the frame
      ExtWidth=cx;
      Calculate();
     }
  }
//+------------------------------------------------------------------+

Comments