#define LEVEL_LIST(F)F(Level0);F(Level1);F(Level2);
class Level0:public TGame::ILevel{
public:
#define PRO_VARIABLE()\
ADDVAR(TCounterInc,PointCounter,TCounterInc(0,0,3))\
ADDVAR(real,Speed,2.5)\
ADDVAR(real,dAng,6.28/(2*Sys.UPS))\
ADDVAR(vec2d,p,vec2d_zero)\
ADDVAR(vec2d,v,vec2d(Speed,0))\
ADDVAR(TCell,Cell,TCell())\
ADDVAR(vec2d,hms,vec2d(768,768)*0.5)\
ADDVAR(PointArray,PA,MakeQuadAABB(-hms,+hms))\
ADDVAR(TGame*,Game,NULL)
//=====+>>>>>Level0
#include "GenVar.inl"
//<<<<<+=====Level0
public:
  void Init(TGame*Game){
    this->Game=Game;
    Game->User.DoReset();
    Game->User.Init(Game);
    Game->User.Speed=Speed;
    Game->User.dAng=dAng;
    Game->User.p=p;
    Game->User.v=v;
    Game->User.n=15;
    Cell.DoReset();
    Cell.p=vec2d(-50,0);
    Cell.Init(Game);
  };
  void Render(QapDev*RD){
    {
      vec2d hms=vec2d(768,768)*0.5;
      vec2d pmin(+hms),pmax(-hms);
      RD->SetBlendMode(QapDX::BT_SUB);
      RD->SetColor(0xff008000);
      RD->BindTex(0,0);
      RD->DrawPolyLine(MakeQuadAABB(pmin,pmax),2,true);
    }
    {
      RD->SetBlendMode(QapDX::BT_SUB);
      RD->SetColor(0xff008000);
      RD->BindTex(0,Game->Atlas.pTex);
      Game->User.Render(RD);
    }
    Cell.Render(RD);
  };
  static bool CollideWithPolySegment(TGame::TUserBody&User,PointArray&PA)
  {
    int c=PA.size();
    for(int i=0;i<c;i++)
      if(-1!=User.CD_Points2Segment(PA[(i+0)%c],PA[(i+1)%c]))
        return true;
    return false;
  }
  void Update(TGame*Game){
    Game->User.Update(Game);
    {
      if(CollideWithPolySegment(Game->User,PA))
      {
        Game->User.deaded=true;
      }
    }
    Cell.Update(Game);
  };
  bool Win(){return !PointCounter;}
  bool Fail(){return Game->User.deaded;}
  void OnPickCell(){
    if(!PointCounter)return;
    PointCounter++;
    Game->User.n++;//dead=true;
    const real wh=768-64;
    Cell.p=TQuad(vec2d_zero,vec2d(wh,wh)).RndPoint();
    Cell.p=vec2i(Cell.p);
    Cell.dead=!PointCounter;
  };
  void AddText(TextRender*TE){
    string BEG="^7";
    string SEP=" ^2: ^8";
    #define GOO(TEXT,VALUE)TE->AddText(string(BEG)+string(TEXT)+string(SEP)+string(VALUE));
    GOO("PointCounter",PointCounter);
    #undef GOO
  }
};
class Level1:public TGame::ILevel{
public:
#define PRO_VARIABLE()\
ADDVAR(TCounterInc,PointCounter,TCounterInc(0,0,15))\
ADDVAR(real,Speed,2.5)\
ADDVAR(real,dAng,6.28/(2*Sys.UPS))\
ADDVAR(vec2d,p,vec2d_zero)\
ADDVAR(vec2d,v,vec2d(Speed,0))\
ADDVAR(TCell,Cell,TCell())\
ADDVAR(vec2d,hms,vec2d(768,768)*0.5)\
ADDVAR(PointArray,PA,MakeQuadAABB(-hms,+hms))\
ADDVAR(TGame*,Game,NULL)
//=====+>>>>>Level1
#include "GenVar.inl"
//<<<<<+=====Level1
public:
  void Init(TGame*Game){
    this->Game=Game;
    Game->User.DoReset();
    Game->User.Init(Game);
    Game->User.Speed=Speed;
    Game->User.dAng=dAng;
    Game->User.p=p;
    Game->User.v=v;
    Game->User.n=3;
    Cell.DoReset();
    Cell.p=vec2d(-50,0);
    Cell.Init(Game);
  };
  void Render(QapDev*RD){
    {
      vec2d hms=vec2d(768,768)*0.5;
      vec2d pmin(+hms),pmax(-hms);
      RD->SetBlendMode(QapDX::BT_SUB);
      RD->SetColor(0xff008000);
      RD->BindTex(0,0);
      RD->DrawPolyLine(MakeQuadAABB(pmin,pmax),2,true);
    }
    {
      RD->SetBlendMode(QapDX::BT_SUB);
      RD->SetColor(0xff008000);
      RD->BindTex(0,Game->Atlas.pTex);
      Game->User.Render(RD);
    }
    Cell.Render(RD);
  };
  static bool CollideWithPolySegment(TGame::TUserBody&User,PointArray&PA)
  {
    int c=PA.size();
    for(int i=0;i<c;i++)
      if(-1!=User.CD_Points2Segment(PA[(i+0)%c],PA[(i+1)%c]))
        return true;
    return false;
  }
  void Update(TGame*Game){
    Game->User.Update(Game);
    {
      if(CollideWithPolySegment(Game->User,PA))
      {
        Game->User.deaded=true;
      }
    }
    Cell.Update(Game);
  };
  bool Win(){return !PointCounter;}
  bool Fail(){return Game->User.deaded;}
  void OnPickCell(){
    if(!PointCounter)return;
    PointCounter++;
    Game->User.n++;//dead=true;
    const real wh=768-64;
    Cell.p=TQuad(vec2d_zero,vec2d(wh,wh)).RndPoint();
    Cell.p=vec2i(Cell.p);
    Cell.dead=!PointCounter;
  };
  void AddText(TextRender*TE){
    string BEG="^7";
    string SEP=" ^2: ^8";
    #define GOO(TEXT,VALUE)TE->AddText(string(BEG)+string(TEXT)+string(SEP)+string(VALUE));
    GOO("PointCounter",PointCounter);
    #undef GOO
  }
};
class Level2:public TGame::ILevel{
public:
#define PRO_VARIABLE()\
ADDVAR(TCounterInc,PointCounter,TCounterInc(0,0,45))\
ADDVAR(real,Speed,3.5)\
ADDVAR(real,dAng,6.28/(1.42*Sys.UPS))\
ADDVAR(vec2d,p,vec2d_zero)\
ADDVAR(vec2d,v,vec2d(Speed,0))\
ADDVAR(TCell,Cell,TCell())\
ADDVAR(vec2d,hms,vec2d(768,768)*0.5)\
ADDVAR(PointArray,PA,MakeQuadAABB(-hms,+hms))\
ADDVAR(TGame*,Game,NULL)
//=====+>>>>>Level2
#include "GenVar.inl"
//<<<<<+=====Level2
public:
  void Init(TGame*Game){
    this->Game=Game;
    Game->User.DoReset();
    Game->User.Init(Game);
    Game->User.Speed=Speed;
    Game->User.dAng=dAng;
    Game->User.p=p;
    Game->User.v=v;
    Game->User.n=2;
    Cell.DoReset();
    Cell.p=vec2d(-250,-250);
    Cell.Init(Game);
  };
  void Render(QapDev*RD){
    {
      vec2d hms=vec2d(768,768)*0.5;
      vec2d pmin(+hms),pmax(-hms);
      RD->SetBlendMode(QapDX::BT_SUB);
      RD->SetColor(0xff008000);
      RD->BindTex(0,0);
      RD->DrawPolyLine(MakeQuadAABB(pmin,pmax),2,true);
    }
    {
      RD->SetBlendMode(QapDX::BT_SUB);
      RD->SetColor(0xff008000);
      RD->BindTex(0,Game->Atlas.pTex);
      Game->User.Render(RD);
    }
    Cell.Render(RD);
  };
  static bool CollideWithPolySegment(TGame::TUserBody&User,PointArray&PA)
  {
    int c=PA.size();
    for(int i=0;i<c;i++)
      if(-1!=User.CD_Points2Segment(PA[(i+0)%c],PA[(i+1)%c]))
        return true;
    return false;
  }
  void Update(TGame*Game){
    Game->User.Update(Game);
    {
      if(CollideWithPolySegment(Game->User,PA))
      {
        Game->User.deaded=true;
      }
    }
    Cell.Update(Game);
  };
  bool Win(){return !PointCounter;}
  bool Fail(){return Game->User.deaded;}
  void OnPickCell(){
    if(!PointCounter)return;
    PointCounter++;
    Game->User.n++;//dead=true;
    const real wh=768-64;
    Cell.p=TQuad(vec2d_zero,vec2d(wh,wh)).RndPoint();
    Cell.p=vec2i(Cell.p);
    Cell.dead=!PointCounter;
  };
  void AddText(TextRender*TE){
    string BEG="^7";
    string SEP=" ^2: ^8";
    #define GOO(TEXT,VALUE)TE->AddText(string(BEG)+string(TEXT)+string(SEP)+string(VALUE));
    GOO("PointCounter",PointCounter);
    #undef GOO
  }
};