text: /*****************************************************************************
  * Model: game.qm
  * File:  ./mine2.c
  *
  * This code has been generated by QM tool (see state-machine.com/qm).
  * DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost.
  *
  * This program is open source software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as published
  * by the Free Software Foundation.
  *
  * This program is distributed in the hope that it will be useful, but
  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  * for more details.
  *****************************************************************************/
  /*${.::mine2.c} ............................................................*/
  #include "qpn.h"
  #include "game.h"
  #include "bsp.h"
  
  Q_DEFINE_THIS_MODULE("mine2")
  
  /* encapsulated delcaration of the Mine2 HSM -------------------------------*/
  /*${AOs::Mine2} ............................................................*/
  typedef struct Mine2 {
  /* protected: */
      QMsm super;
  
  /* private: */
      uint8_t x;
      uint8_t y;
      uint8_t exp_ctr;
  } Mine2;
  
  /* protected: */
  static QState Mine2_initial(Mine2 * const me);
  static QState Mine2_unused  (Mine2 * const me);
  static QMState const Mine2_unused_s = {
      (QMState const *)0, /* superstate (top) */
      Q_STATE_CAST(&Mine2_unused),
      Q_ACTION_CAST(0), /* no entry action */
      Q_ACTION_CAST(0), /* no exit action */
      Q_ACTION_CAST(0)  /* no intitial tran. */
  };
  static QState Mine2_used  (Mine2 * const me);
  static QState Mine2_used_x(Mine2 * const me);
  static QMState const Mine2_used_s = {
      (QMState const *)0, /* superstate (top) */
      Q_STATE_CAST(&Mine2_used),
      Q_ACTION_CAST(0), /* no entry action */
      Q_ACTION_CAST(&Mine2_used_x),
      Q_ACTION_CAST(0)  /* no intitial tran. */
  };
  static QState Mine2_planted  (Mine2 * const me);
  static QMState const Mine2_planted_s = {
      &Mine2_used_s, /* superstate */
      Q_STATE_CAST(&Mine2_planted),
      Q_ACTION_CAST(0), /* no entry action */
      Q_ACTION_CAST(0), /* no exit action */
      Q_ACTION_CAST(0)  /* no intitial tran. */
  };
  static QState Mine2_exploding  (Mine2 * const me);
  static QState Mine2_exploding_e(Mine2 * const me);
  static QMState const Mine2_exploding_s = {
      &Mine2_used_s, /* superstate */
      Q_STATE_CAST(&Mine2_exploding),
      Q_ACTION_CAST(&Mine2_exploding_e),
      Q_ACTION_CAST(0), /* no exit action */
      Q_ACTION_CAST(0)  /* no intitial tran. */
  };
  
  
  /* local objects -----------------------------------------------------------*/
  static Mine2 l_mine2[GAME_MINES_MAX]; /* a pool of type-2 mines */
  
  /* helper macro to provide the ID of this mine */
  #define MINE_ID(me_)    ((me_) - l_mine2)
  
  /* Mine2 class definition --------------------------------------------------*/
  /*${AOs::Mine2_ctor} .......................................................*/
  QMsm * Mine2_ctor(uint8_t id) {
      Mine2 *me;
      Q_REQUIRE(id < GAME_MINES_MAX);
  
      me = &l_mine2[id];
      QMsm_ctor(&me->super, Q_STATE_CAST(&Mine2_initial));
      return (QMsm *)me;
  }
  /*${AOs::Mine2} ............................................................*/
  /*${AOs::Mine2::SM} ........................................................*/
  static QState Mine2_initial(Mine2 * const me) {
      static QMTranActTable const tatbl_ = { /* transition-action table */
          &Mine2_unused_s,
          {
              Q_ACTION_CAST(0) /* zero terminator */
          }
      };
      /* ${AOs::Mine2::SM::initial} */
      return QM_TRAN_INIT(&tatbl_);
  }
  /*${AOs::Mine2::SM::unused} ................................................*/
  /* ${AOs::Mine2::SM::unused} */
  static QState Mine2_unused(Mine2 * const me) {
      QState status_;
      switch (Q_SIG(me)) {
          /* ${AOs::Mine2::SM::unused::MINE_PLANT} */
          case MINE_PLANT_SIG: {
              static QMTranActTable const tatbl_ = { /* transition-action table */
                  &Mine2_planted_s,
                  {
                      Q_ACTION_CAST(0) /* zero terminator */
                  }
              };
              me->x = (uint8_t)Q_PAR(me);
              me->y = (uint8_t)(Q_PAR(me) >> 8);
              status_ = QM_TRAN(&tatbl_);
              break;
          }
          default: {
              status_ = QM_SUPER();
              break;
          }
      }
      return status_;
  }
  /*${AOs::Mine2::SM::used} ..................................................*/
  /* ${AOs::Mine2::SM::used} */
  static QState Mine2_used_x(Mine2 * const me) {
      /* tell the Tunnel that this mine is becoming disabled */
      QACTIVE_POST(&AO_Tunnel, MINE_DISABLED_SIG, MINE_ID(me));
      return QM_EXIT(&Mine2_used_s);
  }
  /* ${AOs::Mine2::SM::used} */
  static QState Mine2_used(Mine2 * const me) {
      QState status_;
      switch (Q_SIG(me)) {
          /* ${AOs::Mine2::SM::used::MINE_RECYCLE} */
          case MINE_RECYCLE_SIG: {
              static struct {
                  QMState const *target;
                  QActionHandler act[2];
              } const tatbl_ = { /* transition-action table */
                  &Mine2_unused_s, /* target state */
                  {
                      Q_ACTION_CAST(&Mine2_used_x), /* exit */
                      Q_ACTION_CAST(0) /* zero terminator */
                  }
              };
              status_ = QM_TRAN(&tatbl_);
              break;
          }
          default: {
              status_ = QM_SUPER();
              break;
          }
      }
      return status_;
  }
  /*${AOs::Mine2::SM::used::planted} .........................................*/
  /* ${AOs::Mine2::SM::used::planted} */
  static QState Mine2_planted(Mine2 * const me) {
      QState status_;
      switch (Q_SIG(me)) {
          /* ${AOs::Mine2::SM::used::planted::TIME_TICK} */
          case TIME_TICK_SIG: {
              /* ${AOs::Mine2::SM::used::planted::TIME_TICK::[me->x>=GAME_SPEED_X]} */
              if (me->x >= GAME_SPEED_X) {
                  me->x -= GAME_SPEED_X;              /* move the mine 1 step */
  
                  /* tell the Tunnel to draw the Mine */
                  QACTIVE_POST(&AO_Tunnel, MINE_IMG_SIG,
                               (MINE2_BMP << 16)
                               | me->x
                               | (me->y << 8));
                  status_ = QM_HANDLED();
              }
              /* ${AOs::Mine2::SM::used::planted::TIME_TICK::[else]} */
              else {
                  static struct {
                      QMState const *target;
                      QActionHandler act[2];
                  } const tatbl_ = { /* transition-action table */
                      &Mine2_unused_s, /* target state */
                      {
                          Q_ACTION_CAST(&Mine2_used_x), /* exit */
                          Q_ACTION_CAST(0) /* zero terminator */
                      }
                  };
                  status_ = QM_TRAN(&tatbl_);
              }
              break;
          }
          /* ${AOs::Mine2::SM::used::planted::SHIP_IMG} */
          case SHIP_IMG_SIG: {
              uint8_t x   = (uint8_t)Q_PAR(me);
              uint8_t y   = (uint8_t)(Q_PAR(me) >> 8);
              uint8_t bmp = (uint8_t)(Q_PAR(me) >> 16);
              /* ${AOs::Mine2::SM::used::planted::SHIP_IMG::[do_bitmaps_overlap(MINE2_BMP,me~} */
              if (do_bitmaps_overlap(MINE2_BMP, me->x, me->y, bmp, x, y)) {
                  static struct {
                      QMState const *target;
                      QActionHandler act[2];
                  } const tatbl_ = { /* transition-action table */
                      &Mine2_unused_s, /* target state */
                      {
                          Q_ACTION_CAST(&Mine2_used_x), /* exit */
                          Q_ACTION_CAST(0) /* zero terminator */
                      }
                  };
                  QACTIVE_POST(&AO_Ship, HIT_MINE_SIG,  2);
                  /* go straight to 'disabled' and let the Ship do the exploding */
                  status_ = QM_TRAN(&tatbl_);
              }
              else {
                  status_ = QM_UNHANDLED();
              }
              break;
          }
          /* ${AOs::Mine2::SM::used::planted::MISSILE_IMG} */
          case MISSILE_IMG_SIG: {
              uint8_t x   = (uint8_t)Q_PAR(me);
              uint8_t y   = (uint8_t)(Q_PAR(me) >> 8);
              uint8_t bmp = (uint8_t)(Q_PAR(me) >> 16);
              /* ${AOs::Mine2::SM::used::planted::MISSILE_IMG::[do_bitmaps_overlap(MINE2_MISSIL~} */
              if (do_bitmaps_overlap(MINE2_MISSILE_BMP, me->x, me->y, bmp, x, y)) {
                  static struct {
                      QMState const *target;
                      QActionHandler act[2];
                  } const tatbl_ = { /* transition-action table */
                      &Mine2_exploding_s, /* target state */
                      {
                          Q_ACTION_CAST(&Mine2_exploding_e), /* entry */
                          Q_ACTION_CAST(0) /* zero terminator */
                      }
                  };
                  /* NOTE: Mine type-2 is nastier than Mine type-1.
                  * The type-2 mine can hit the Ship with any of its
                  * "tentacles". However, it can be destroyed by the
                  * Missile only by hitting its center, defined as
                  * a smaller bitmap MINE2_MISSILE_BMP.
                  */
                  /* post the score for destroying Mine type-2 */
                  QACTIVE_POST(&AO_Missile, DESTROYED_MINE_SIG, 45);
                  status_ = QM_TRAN(&tatbl_);
              }
              else {
                  status_ = QM_UNHANDLED();
              }
              break;
          }
          default: {
              status_ = QM_SUPER();
              break;
          }
      }
      return status_;
  }
  /*${AOs::Mine2::SM::used::exploding} .......................................*/
  /* ${AOs::Mine2::SM::used::exploding} */
  static QState Mine2_exploding_e(Mine2 * const me) {
      me->exp_ctr = 0;
      return QM_ENTRY(&Mine2_exploding_s);
  }
  /* ${AOs::Mine2::SM::used::exploding} */
  static QState Mine2_exploding(Mine2 * const me) {
      QState status_;
      switch (Q_SIG(me)) {
          /* ${AOs::Mine2::SM::used::exploding::TIME_TICK} */
          case TIME_TICK_SIG: {
              /* ${AOs::Mine2::SM::used::exploding::TIME_TICK::[(me->x>=GAME_SPEED_X)&&(me->exp~} */
              if ((me->x >= GAME_SPEED_X) && (me->exp_ctr < 15)) {
                  ++me->exp_ctr; /* advance the explosion counter */
                  me->x -= GAME_SPEED_X; /* move explosion by 1 step */
  
                  /* tell the Game to render the current stage of Explosion */
                  QACTIVE_POST(&AO_Tunnel, EXPLOSION_SIG,
                           ((EXPLOSION0_BMP + (me->exp_ctr >> 2)) << 16)
                           | (me->x + 1)
                           | (((int)me->y - 4 + 2)) << 8);
                  status_ = QM_HANDLED();
              }
              /* ${AOs::Mine2::SM::used::exploding::TIME_TICK::[else]} */
              else {
                  static struct {
                      QMState const *target;
                      QActionHandler act[2];
                  } const tatbl_ = { /* transition-action table */
                      &Mine2_unused_s, /* target state */
                      {
                          Q_ACTION_CAST(&Mine2_used_x), /* exit */
                          Q_ACTION_CAST(0) /* zero terminator */
                      }
                  };
                  status_ = QM_TRAN(&tatbl_);
              }
              break;
          }
          default: {
              status_ = QM_SUPER();
              break;
          }
      }
      return status_;
  }
  
  