Bitmap *Buffer;

void Init()
{
  Buffer = new Bitmap(SCREEN_W, SCREEN_H);
}
void Draw()
{
  if (ShowShadows)
  {
    Canvas::SetTo(*Buffer);
    Canvas::Fill(Rgba::BLACK);
    //Blenders::Set(ADDITIVE_BLENDER);
      Player->DrawLights();
    //Blenders::Set(ALPHA_BLENDER);
    Canvas::SetTo(SCREEN_BACKBUF);
  }
  
  //DRAW THE MAP AND OBJECTS HERE
  
  if (ShowShadows)
  {
    Blenders::Set(GL_ONE_MINUS_DST_ALPHA, GL_SRC_COLOR);
      Buffer->Blit(0, 0);
    Blenders::Set(ALPHA_BLENDER);
  }
}

class CPlayer
{
  //...
  vector<Vec2D> LightPoly;
  //...
};

inline void CPlayer::CalculateLight()
{
  float fAngle = (Angle+90)-65;
  LightPoly.clear();
  LightPoly.push_back(Vec2D(X, Y));
  
  for (int i=0; i<20; i++)
  {
    fAngle -= 2.5f;
    for (int l=0; l<200; l+=10)
    {
      float X2 = X+cos(fAngle*AL_PI/180)*l;
      float Y2 = Y+sin(fAngle*AL_PI/180)*l;
      
      if (Map[MAPID]->BlockedTile(X2, Y2)) //IF THE LIGHT RAY HITS A BLOCKED TILE, IE. A WALL
      {
        //FOR ADDED POLYGON SMOOTHNESS, BUT IT WORKS ONLY ON RECTANGLES
        if (X2<int(X2/TILESIZE)*TILESIZE+10) { X2 = int(X2/TILESIZE)*TILESIZE; }
        else if (X2>int(X2/TILESIZE+1)*TILESIZE-10) { X2 = int(X2/TILESIZE+1)*TILESIZE; }
        
        if (Y2<int(Y2/TILESIZE)*TILESIZE+10) { Y2 = int(Y2/TILESIZE)*TILESIZE; }
        else if (Y2>int(Y2/TILESIZE+1)*TILESIZE-10) { Y2 = int(Y2/TILESIZE+1)*TILESIZE; }
        //=============================================================
        
        LightPoly.push_back(Vec2D(X2, Y2));
        break;
      }
      //ELSE ADD A VERTEX AT THE END OF THE RAY (TO AVOID HAVING 8K VERTICES)
      else if (l>=189) { LightPoly.push_back(Vec2D(X2, Y2)); }
    }
  }
}
inline void CPlayer::DrawLights()
{
  Light.BlitTransformed(X, Y, 300, 300, 50, 50, 0.0, Tinted(Rgba(1.0, 1.0, 1.0, 1.0)), 1.0);
  if (ShowShadows && FlashlightON) { for (int i=0; i<LightPoly.size(); i++) { Poly(LightPoly).Draw(Rgba(0.9, 0.9, 0.8)); } }
}