#include "rocket.h"

Fsm * RocketMomentum::Routine(Dp * dp, Db * db)
{
	db->RocketX += db->RocketVx;
	db->RocketY += db->RocketVy;
	if (db->RocketVx > 10) db->RocketVx = 10;
	if (db->RocketVx < -10) db->RocketVx = -10;
	if (db->RocketVy > 10) db->RocketVy = 10;
	if (db->RocketVy < -10) db->RocketVy = -10;
	return this;
}

Fsm * ViewportFollowRocket::Routine(Dp * dp, Db * db)
{
	dp->X = db->RocketX;
	dp->Y = db->RocketY;
	return this;
}


class Rocket00 : public Fsm { Fsm* Routine(Dp * dp,Db * db); };
class Rocket22 : public Fsm { Fsm* Routine(Dp * dp,Db * db); };
class Rocket45 : public Fsm { Fsm* Routine(Dp * dp,Db * db); };
class Rocket67 : public Fsm { Fsm* Routine(Dp * dp,Db * db); };
class Rocket90 : public Fsm { Fsm* Routine(Dp * dp,Db * db); };
class Rocket112 : public Fsm { Fsm* Routine(Dp * dp,Db * db); };
class Rocket135 : public Fsm { Fsm* Routine(Dp * dp,Db * db); };
class Rocket157 : public Fsm { Fsm* Routine(Dp * dp,Db * db); };
class Rocket180 : public Fsm { Fsm* Routine(Dp * dp,Db * db); };
class Rocket207 : public Fsm { Fsm* Routine(Dp * dp,Db * db); };
class Rocket225 : public Fsm { Fsm* Routine(Dp * dp,Db * db); };
class Rocket247 : public Fsm { Fsm* Routine(Dp * dp,Db * db); };
class Rocket270 : public Fsm { Fsm* Routine(Dp * dp,Db * db); };
class Rocket292 : public Fsm { Fsm* Routine(Dp * dp,Db * db); };
class Rocket315 : public Fsm { Fsm* Routine(Dp * dp,Db * db); };
class Rocket337 : public Fsm { Fsm* Routine(Dp * dp,Db * db); };

class RocketThrust00 : public Fsm { Fsm* Routine(Dp * dp,Db * db); };
class RocketThrust22 : public Fsm { Fsm* Routine(Dp * dp,Db * db); };
class RocketThrust45 : public Fsm { Fsm* Routine(Dp * dp,Db * db); };
class RocketThrust67 : public Fsm { Fsm* Routine(Dp * dp,Db * db); };
class RocketThrust90 : public Fsm { Fsm* Routine(Dp * dp,Db * db); };
class RocketThrust112 : public Fsm { Fsm* Routine(Dp * dp,Db * db); };
class RocketThrust135 : public Fsm { Fsm* Routine(Dp * dp,Db * db); };
class RocketThrust157 : public Fsm { Fsm* Routine(Dp * dp,Db * db); };
class RocketThrust180 : public Fsm { Fsm* Routine(Dp * dp,Db * db); };
class RocketThrust207 : public Fsm { Fsm* Routine(Dp * dp,Db * db); };
class RocketThrust225 : public Fsm { Fsm* Routine(Dp * dp,Db * db); };
class RocketThrust247 : public Fsm { Fsm* Routine(Dp * dp,Db * db); };
class RocketThrust270 : public Fsm { Fsm* Routine(Dp * dp,Db * db); };
class RocketThrust292 : public Fsm { Fsm* Routine(Dp * dp,Db * db); };
class RocketThrust315 : public Fsm { Fsm* Routine(Dp * dp,Db * db); };
class RocketThrust337 : public Fsm { Fsm* Routine(Dp * dp,Db * db); };

Fsm* Rocket::Routine(Dp * dp,Db * db)
{
	db->RocketX = 0;
	db->RocketY = 0;
	db->RocketVx = 0;
	db->RocketVy = 0;
	return Singleton<Rocket00>();
}

Fsm* Rocket00::Routine(Dp * dp,Db * db)
{
	dp->Blit(rocket00, db->RocketX, db->RocketY);
	if (dp->Btns[BtnLt]) return Singleton<Rocket337>();
	if (dp->Btns[BtnRt]) return Singleton<Rocket22>();
	if (dp->Btns[BtnUp]) return Singleton<RocketThrust00>();
	return this;
}

Fsm* Rocket22::Routine(Dp * dp,Db * db)
{
	dp->Blit(rocket22, db->RocketX, db->RocketY);
	if (dp->Btns[BtnLt]) return Singleton<Rocket00>();
	if (dp->Btns[BtnRt]) return Singleton<Rocket45>();
	if (dp->Btns[BtnUp]) return Singleton<RocketThrust22>();
	return this;
}

Fsm* Rocket45::Routine(Dp * dp,Db * db)
{
	dp->Blit(rocket45, db->RocketX, db->RocketY);
	if (dp->Btns[BtnLt]) return Singleton<Rocket22>();;
	if (dp->Btns[BtnRt]) return Singleton<Rocket67>();
	if (dp->Btns[BtnUp]) return Singleton<RocketThrust45>();
	return this;
}

Fsm* Rocket67::Routine(Dp * dp,Db * db)
{
	dp->Blit(rocket67, db->RocketX, db->RocketY);
	if (dp->Btns[BtnLt]) return Singleton<Rocket45>();
	if (dp->Btns[BtnRt]) return Singleton<Rocket90>();
	if (dp->Btns[BtnUp]) return Singleton<RocketThrust67>();
	return this;
}

Fsm* Rocket90::Routine(Dp * dp,Db * db)
{
	dp->Blit(rocket90, db->RocketX, db->RocketY);
	if (dp->Btns[BtnLt]) return Singleton<Rocket67>();
	if (dp->Btns[BtnRt]) return Singleton<Rocket112>();
	if (dp->Btns[BtnUp]) return Singleton<RocketThrust90>();
	return this;
}

Fsm* Rocket112::Routine(Dp * dp,Db * db)
{
	dp->Blit(rocket112, db->RocketX, db->RocketY);
	if (dp->Btns[BtnLt]) return Singleton<Rocket90>();
	if (dp->Btns[BtnRt]) return Singleton<Rocket135>();
	if (dp->Btns[BtnUp]) return Singleton<RocketThrust112>();
	return this;
}

Fsm* Rocket135::Routine(Dp * dp,Db * db)
{
	dp->Blit(rocket135, db->RocketX, db->RocketY);
	if (dp->Btns[BtnLt]) return Singleton<Rocket112>();
	if (dp->Btns[BtnRt]) return Singleton<Rocket157>();
	if (dp->Btns[BtnUp]) return Singleton<RocketThrust135>();
	return this;
}

Fsm* Rocket157::Routine(Dp * dp,Db * db)
{
	dp->Blit(rocket157, db->RocketX, db->RocketY);
	if (dp->Btns[BtnLt]) return Singleton<Rocket135>();
	if (dp->Btns[BtnRt]) return Singleton<Rocket180>();
	if (dp->Btns[BtnUp]) return Singleton<RocketThrust157>();
	return this;
}

Fsm* Rocket180::Routine(Dp * dp,Db * db)
{
	dp->Blit(rocket180, db->RocketX, db->RocketY);
	if (dp->Btns[BtnLt]) return Singleton<Rocket157>();
	if (dp->Btns[BtnRt]) return Singleton<Rocket207>();
	if (dp->Btns[BtnUp]) return Singleton<RocketThrust180>();
	return this;
}

Fsm* Rocket207::Routine(Dp * dp,Db * db)
{
	dp->Blit(rocket207, db->RocketX, db->RocketY);
	if (dp->Btns[BtnLt]) return Singleton<Rocket180>();
	if (dp->Btns[BtnRt]) return Singleton<Rocket225>();
	if (dp->Btns[BtnUp]) return Singleton<RocketThrust207>();
	return this;
}

Fsm* Rocket225::Routine(Dp * dp,Db * db)
{
	dp->Blit(rocket225, db->RocketX, db->RocketY);
	if (dp->Btns[BtnLt]) return Singleton<Rocket207>();
	if (dp->Btns[BtnRt]) return Singleton<Rocket247>();
	if (dp->Btns[BtnUp]) return Singleton<RocketThrust225>();
	return this;
}

Fsm* Rocket247::Routine(Dp * dp,Db * db)
{
	dp->Blit(rocket247, db->RocketX, db->RocketY);
	if (dp->Btns[BtnLt]) return Singleton<Rocket225>();
	if (dp->Btns[BtnRt]) return Singleton<Rocket270>();
	if (dp->Btns[BtnUp]) return Singleton<RocketThrust247>();
	return this;
}

Fsm* Rocket270::Routine(Dp * dp,Db * db)
{
	dp->Blit(rocket270, db->RocketX, db->RocketY);
	if (dp->Btns[BtnLt]) return Singleton<Rocket247>();
	if (dp->Btns[BtnRt]) return Singleton<Rocket292>();
	if (dp->Btns[BtnUp]) return Singleton<RocketThrust270>();
	return this;
}

Fsm* Rocket292::Routine(Dp * dp,Db * db)
{
	dp->Blit(rocket292, db->RocketX, db->RocketY);
	if (dp->Btns[BtnLt]) return Singleton<Rocket270>();
	if (dp->Btns[BtnRt]) return Singleton<Rocket315>();
	if (dp->Btns[BtnUp]) return Singleton<RocketThrust292>();
	return this;
}

Fsm* Rocket315::Routine(Dp * dp,Db * db)
{
	dp->Blit(rocket315, db->RocketX, db->RocketY);
	if (dp->Btns[BtnLt]) return Singleton<Rocket292>();
	if (dp->Btns[BtnRt]) return Singleton<Rocket337>();
	if (dp->Btns[BtnUp]) return Singleton<RocketThrust315>();
	return this;
}

Fsm* Rocket337::Routine(Dp * dp,Db * db)
{
	dp->Blit(rocket337, db->RocketX, db->RocketY);
	if (dp->Btns[BtnLt]) return Singleton<Rocket315>();
	if (dp->Btns[BtnRt]) return Singleton<Rocket00>();
	if (dp->Btns[BtnUp]) return Singleton<RocketThrust337>();
	return this;
}

Fsm* RocketThrust00::Routine(Dp * dp,Db * db)
{
	db->RocketVy -= 2;
	dp->Blit(rocketThrust00, db->RocketX, db->RocketY);
	dp->Blit(rocket00, db->RocketX, db->RocketY);
	if (dp->Btns[BtnLt]) return Singleton<RocketThrust337>();
	if (dp->Btns[BtnRt]) return Singleton<RocketThrust22>();
	if (dp->Btns[BtnUp]) return this;
	return Singleton<Rocket00>();
}

Fsm* RocketThrust22::Routine(Dp * dp,Db * db)
{
	db->RocketVx += 1;
	db->RocketVy -= 2;
	dp->Blit(rocketThrust22, db->RocketX, db->RocketY);
	dp->Blit(rocket22, db->RocketX, db->RocketY);
	if (dp->Btns[BtnLt]) return Singleton<RocketThrust00>();
	if (dp->Btns[BtnRt]) return Singleton<RocketThrust45>();
	if (dp->Btns[BtnUp]) return this;
	return Singleton<Rocket22>();
}

Fsm* RocketThrust45::Routine(Dp * dp,Db * db)
{
	db->RocketVx += 2;
	db->RocketVy -= 2;
	dp->Blit(rocketThrust45, db->RocketX, db->RocketY);
	dp->Blit(rocket45, db->RocketX, db->RocketY);
	if (dp->Btns[BtnLt]) return Singleton<RocketThrust22>();
	if (dp->Btns[BtnRt]) return Singleton<RocketThrust67>();
	if (dp->Btns[BtnUp]) return this;
	return Singleton<Rocket45>();
}

Fsm* RocketThrust67::Routine(Dp * dp,Db * db)
{
	db->RocketVx += 2;
	db->RocketVy -= 1;
	dp->Blit(rocketThrust67, db->RocketX, db->RocketY);
	dp->Blit(rocket67, db->RocketX, db->RocketY);
	if (dp->Btns[BtnLt]) return Singleton<RocketThrust45>();
	if (dp->Btns[BtnRt]) return Singleton<RocketThrust90>();
	if (dp->Btns[BtnUp]) return this;
	return Singleton<Rocket67>();
}

Fsm* RocketThrust90::Routine(Dp * dp,Db * db)
{
	db->RocketVx += 2;
	dp->Blit(rocketThrust90, db->RocketX, db->RocketY);
	dp->Blit(rocket90, db->RocketX, db->RocketY);
	if (dp->Btns[BtnLt]) return Singleton<RocketThrust67>();
	if (dp->Btns[BtnRt]) return Singleton<RocketThrust112>();
	if (dp->Btns[BtnUp]) return this;
	return Singleton<Rocket90>();
}

Fsm* RocketThrust112::Routine(Dp * dp,Db * db)
{
	db->RocketVx += 2;
	db->RocketVy += 1;
	dp->Blit(rocketThrust112, db->RocketX, db->RocketY);
	dp->Blit(rocket112, db->RocketX, db->RocketY);
	if (dp->Btns[BtnLt]) return Singleton<RocketThrust90>();
	if (dp->Btns[BtnRt]) return Singleton<RocketThrust135>();
	if (dp->Btns[BtnUp]) return this;
	return Singleton<Rocket112>();
}

Fsm* RocketThrust135::Routine(Dp * dp,Db * db)
{
	db->RocketVx += 2;
	db->RocketVy += 2;
	dp->Blit(rocketThrust135, db->RocketX, db->RocketY);
	dp->Blit(rocket135, db->RocketX, db->RocketY);
	if (dp->Btns[BtnLt]) return Singleton<RocketThrust112>();
	if (dp->Btns[BtnRt]) return Singleton<RocketThrust157>();
	if (dp->Btns[BtnUp]) return this;
	return Singleton<Rocket135>();
}

Fsm* RocketThrust157::Routine(Dp * dp,Db * db)
{
	db->RocketVx += 1;
	db->RocketVy += 2;
	dp->Blit(rocketThrust157, db->RocketX, db->RocketY);
	dp->Blit(rocket157, db->RocketX, db->RocketY);
	if (dp->Btns[BtnLt]) return Singleton<RocketThrust135>();
	if (dp->Btns[BtnRt]) return Singleton<RocketThrust180>();
	if (dp->Btns[BtnUp]) return this;
	return Singleton<Rocket157>();
}

Fsm* RocketThrust180::Routine(Dp * dp,Db * db)
{
	db->RocketVy += 2;
	dp->Blit(rocketThrust180, db->RocketX, db->RocketY);
	dp->Blit(rocket180, db->RocketX, db->RocketY);
	if (dp->Btns[BtnLt]) return Singleton<RocketThrust157>();
	if (dp->Btns[BtnRt]) return Singleton<RocketThrust207>();
	if (dp->Btns[BtnUp]) return this;
	return Singleton<Rocket180>();
}

Fsm* RocketThrust207::Routine(Dp * dp,Db * db)
{
	db->RocketVx -= 1;
	db->RocketVy += 2;
	dp->Blit(rocketThrust207, db->RocketX, db->RocketY);
	dp->Blit(rocket207, db->RocketX, db->RocketY);
	if (dp->Btns[BtnLt]) return Singleton<RocketThrust180>();
	if (dp->Btns[BtnRt]) return Singleton<RocketThrust225>();
	if (dp->Btns[BtnUp]) return this;
	return Singleton<Rocket207>();
}

Fsm* RocketThrust225::Routine(Dp * dp,Db * db)
{
	db->RocketVx -= 2;
	db->RocketVy += 2;
	dp->Blit(rocketThrust225, db->RocketX, db->RocketY);
	dp->Blit(rocket225, db->RocketX, db->RocketY);
	if (dp->Btns[BtnLt]) return Singleton<RocketThrust207>();
	if (dp->Btns[BtnRt]) return Singleton<RocketThrust247>();
	if (dp->Btns[BtnUp]) return this;
	return Singleton<Rocket225>();
}

Fsm* RocketThrust247::Routine(Dp * dp,Db * db)
{
	db->RocketVx -= 2;
	db->RocketVy += 1;
	dp->Blit(rocketThrust247, db->RocketX, db->RocketY);
	dp->Blit(rocket247, db->RocketX, db->RocketY);
	if (dp->Btns[BtnLt]) return Singleton<RocketThrust225>();
	if (dp->Btns[BtnRt]) return Singleton<RocketThrust270>();
	if (dp->Btns[BtnUp]) return this;
	return Singleton<Rocket247>();
}

Fsm* RocketThrust270::Routine(Dp * dp,Db * db)
{
	db->RocketVx -= 2;
	dp->Blit(rocketThrust270, db->RocketX, db->RocketY);
	dp->Blit(rocket270, db->RocketX, db->RocketY);
	if (dp->Btns[BtnLt]) return Singleton<RocketThrust247>();
	if (dp->Btns[BtnRt]) return Singleton<RocketThrust292>();
	if (dp->Btns[BtnUp]) return this;
	return Singleton<Rocket270>();
}

Fsm* RocketThrust292::Routine(Dp * dp,Db * db)
{
	db->RocketVx -= 2;
	db->RocketVy -= 1;
	dp->Blit(rocketThrust292, db->RocketX, db->RocketY);
	dp->Blit(rocket292, db->RocketX, db->RocketY);
	if (dp->Btns[BtnLt]) return Singleton<RocketThrust270>();
	if (dp->Btns[BtnRt]) return Singleton<RocketThrust315>();
	if (dp->Btns[BtnUp]) return this;
	return Singleton<Rocket292>();
}

Fsm* RocketThrust315::Routine(Dp * dp,Db * db)
{
	db->RocketVx -= 2;
	db->RocketVy -= 2;
	dp->Blit(rocketThrust315, db->RocketX, db->RocketY);
	dp->Blit(rocket315, db->RocketX, db->RocketY);
	if (dp->Btns[BtnLt]) return Singleton<RocketThrust292>();
	if (dp->Btns[BtnRt]) return Singleton<RocketThrust337>();
	if (dp->Btns[BtnUp]) return this;
	return Singleton<Rocket315>();
}

Fsm* RocketThrust337::Routine(Dp * dp,Db * db)
{
	db->RocketVx -= 1;
	db->RocketVy -= 2;
	dp->Blit(rocketThrust337, db->RocketX, db->RocketY);
	dp->Blit(rocket337, db->RocketX, db->RocketY);
	if (dp->Btns[BtnLt]) return Singleton<RocketThrust315>();
	if (dp->Btns[BtnRt]) return Singleton<RocketThrust00>();
	if (dp->Btns[BtnUp]) return this;
	return Singleton<Rocket337>();
}







