//**************************************************************************** // Model: game.qm // File: ./mine1.cpp // // 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. //**************************************************************************** // @(/3/5) ................................................................... #include "qp_port.h" #include "bsp.h" #include "game.h" Q_DEFINE_THIS_FILE // encapsulated delcaration of the Mine1 HSM --------------------------------- namespace GAME { // @(/2/3) ................................................................... class Mine1 : public QP::QMsm { private: uint8_t m_x; uint8_t m_y; uint8_t m_exp_ctr; public: Mine1() : QMsm(Q_STATE_CAST(&Mine1::initial)) {} protected: static QP::QState initial(Mine1 * const me, QP::QEvt const * const e); static QP::QState unused (Mine1 * const me, QP::QEvt const * const e); static QP::QMState const unused_s; static QP::QState used (Mine1 * const me, QP::QEvt const * const e); static QP::QState used_x(Mine1 * const me); static QP::QMState const used_s; static QP::QState exploding (Mine1 * const me, QP::QEvt const * const e); static QP::QState exploding_e(Mine1 * const me); static QP::QMState const exploding_s; static QP::QState planted (Mine1 * const me, QP::QEvt const * const e); static QP::QMState const planted_s; }; } // namespace GAME namespace GAME { // local objects ------------------------------------------------------------- static Mine1 l_mine1[GAME_MINES_MAX]; // a pool of type-1 mines //............................................................................ QP::QMsm *Mine1_getInst(uint8_t id) { Q_REQUIRE(id < GAME_MINES_MAX); return &l_mine1[id]; } // helper function to provide the ID of this mine ............................ static inline uint8_t MINE_ID(Mine1 const * const me) { return static_cast(me - l_mine1); } } // namespace GAME // Mine1 class definition ---------------------------------------------------- namespace GAME { // @(/2/3) ................................................................... // @(/2/3/4) ................................................................. // @(/2/3/4/0) QP::QState Mine1::initial(Mine1 * const me, QP::QEvt const * const e) { static bool dict_sent = false; if (!dict_sent) { dict_sent = true; QS_OBJ_DICTIONARY(&l_mine1[0]); // obj. dictionaries for Mine1 pool QS_OBJ_DICTIONARY(&l_mine1[1]); QS_OBJ_DICTIONARY(&l_mine1[2]); QS_OBJ_DICTIONARY(&l_mine1[3]); QS_OBJ_DICTIONARY(&l_mine1[4]); QS_FUN_DICTIONARY(&Mine1::initial);// fun. dictionaries for Mine1 HSM QS_FUN_DICTIONARY(&Mine1::unused); QS_FUN_DICTIONARY(&Mine1::used); QS_FUN_DICTIONARY(&Mine1::planted); QS_FUN_DICTIONARY(&Mine1::exploding); } // local signals QS_SIG_DICTIONARY(MINE_PLANT_SIG, me); QS_SIG_DICTIONARY(MINE_DISABLED_SIG, me); QS_SIG_DICTIONARY(MINE_RECYCLE_SIG, me); QS_SIG_DICTIONARY(SHIP_IMG_SIG, me); QS_SIG_DICTIONARY(MISSILE_IMG_SIG, me); return QM_INITIAL(&Mine1::unused_s, QP::QMsm::s_emptyAction_); } // @(/2/3/4/1) ............................................................... QP::QMState const Mine1::unused_s = { static_cast(0), Q_STATE_CAST(&Mine1::unused), Q_ACTION_CAST(0) }; QP::QState Mine1::unused(Mine1 * const me, QP::QEvt const * const e) { QP::QState status_; switch (e->sig) { // @(/2/3/4/1/0) case MINE_PLANT_SIG: { me->m_x = Q_EVT_CAST(ObjectPosEvt)->x; me->m_y = Q_EVT_CAST(ObjectPosEvt)->y; status_ = QM_TRAN(&planted_s, QP::QMsm::s_emptyAction_); break; } default: { status_ = QM_SUPER(); break; } } return status_; } // @(/2/3/4/2) ............................................................... QP::QMState const Mine1::used_s = { static_cast(0), Q_STATE_CAST(&Mine1::used), Q_ACTION_CAST(&Mine1::used_x) }; QP::QState Mine1::used_x(Mine1 * const me) { // tell the Tunnel that this mine is becoming disabled MineEvt *mev = Q_NEW(MineEvt, MINE_DISABLED_SIG); mev->id = MINE_ID(me); AO_Tunnel->POST(mev, me); return QM_EXIT(&used_s); } QP::QState Mine1::used(Mine1 * const me, QP::QEvt const * const e) { QP::QState status_; switch (e->sig) { // @(/2/3/4/2/0) case MINE_RECYCLE_SIG: { static QP::QActionHandler const act_[] = { Q_ACTION_CAST(&Mine1::used_x), Q_ACTION_CAST(0) }; status_ = QM_TRAN(&unused_s, &act_[0]); break; } default: { status_ = QM_SUPER(); break; } } return status_; } // @(/2/3/4/2/1) ............................................................. QP::QMState const Mine1::exploding_s = { &Mine1::used_s, Q_STATE_CAST(&Mine1::exploding), Q_ACTION_CAST(0) }; QP::QState Mine1::exploding_e(Mine1 * const me) { me->m_exp_ctr = 0U; return QM_ENTRY(&exploding_s); } QP::QState Mine1::exploding(Mine1 * const me, QP::QEvt const * const e) { QP::QState status_; switch (e->sig) { // @(/2/3/4/2/1/0) case TIME_TICK_SIG: { // @(/2/3/4/2/1/0/0) if ((me->m_x >= GAME_SPEED_X) && (me->m_exp_ctr < 15)) { ++me->m_exp_ctr; // advance the explosion counter me->m_x -= GAME_SPEED_X; // move explosion by 1 step // tell the Game to render the current stage of Explosion ObjectImageEvt *oie = Q_NEW(ObjectImageEvt, EXPLOSION_SIG); oie->x = me->m_x + 1U; // x of explosion oie->y = (int8_t)((int)me->m_y - 4 + 2); // y of explosion oie->bmp = EXPLOSION0_BMP + (me->m_exp_ctr >> 2); AO_Tunnel->POST(oie, me); status_ = QM_HANDLED(); } // @(/2/3/4/2/1/0/1) else { static QP::QActionHandler const act_[] = { Q_ACTION_CAST(&Mine1::used_x), Q_ACTION_CAST(0) }; status_ = QM_TRAN(&unused_s, &act_[0]); } break; } default: { status_ = QM_SUPER(); break; } } return status_; } // @(/2/3/4/2/2) ............................................................. QP::QMState const Mine1::planted_s = { &Mine1::used_s, Q_STATE_CAST(&Mine1::planted), Q_ACTION_CAST(0) }; QP::QState Mine1::planted(Mine1 * const me, QP::QEvt const * const e) { QP::QState status_; switch (e->sig) { // @(/2/3/4/2/2/0) case TIME_TICK_SIG: { // @(/2/3/4/2/2/0/0) if (me->m_x >= GAME_SPEED_X) { me->m_x -= GAME_SPEED_X; // move the mine 1 step // tell the Tunnel to draw the Mine ObjectImageEvt *oie = Q_NEW(ObjectImageEvt, MINE_IMG_SIG); oie->x = me->m_x; oie->y = me->m_y; oie->bmp = MINE1_BMP; AO_Tunnel->POST(oie, me); status_ = QM_HANDLED(); } // @(/2/3/4/2/2/0/1) else { static QP::QActionHandler const act_[] = { Q_ACTION_CAST(&Mine1::used_x), Q_ACTION_CAST(0) }; status_ = QM_TRAN(&unused_s, &act_[0]); } break; } // @(/2/3/4/2/2/1) case SHIP_IMG_SIG: { uint8_t x = Q_EVT_CAST(ObjectImageEvt)->x; uint8_t y = Q_EVT_CAST(ObjectImageEvt)->y; uint8_t bmp = Q_EVT_CAST(ObjectImageEvt)->bmp; // @(/2/3/4/2/2/1/0) if (do_bitmaps_overlap(MINE1_BMP, me->m_x, me->m_y, bmp, x, y)) { static QP::QActionHandler const act_[] = { Q_ACTION_CAST(&Mine1::used_x), Q_ACTION_CAST(0) }; static MineEvt const mine1_hit(HIT_MINE_SIG, 1U); AO_Ship->POST(&mine1_hit, me); // go straight to 'disabled' and let the Ship do // the exploding status_ = QM_TRAN(&unused_s, &act_[0]); } else { status_ = QM_UNHANDLED(); } break; } // @(/2/3/4/2/2/2) case MISSILE_IMG_SIG: { uint8_t x = Q_EVT_CAST(ObjectImageEvt)->x; uint8_t y = Q_EVT_CAST(ObjectImageEvt)->y; uint8_t bmp = Q_EVT_CAST(ObjectImageEvt)->bmp; // @(/2/3/4/2/2/2/0) if (do_bitmaps_overlap(MINE1_BMP, me->m_x, me->m_y, bmp, x, y)) { static QP::QActionHandler const act_[] = { Q_ACTION_CAST(&Mine1::exploding_e), Q_ACTION_CAST(0) }; static ScoreEvt const mine1_destroyed(DESTROYED_MINE_SIG, 25U); AO_Missile->POST(&mine1_destroyed, me); status_ = QM_TRAN(&exploding_s, &act_[0]); } else { status_ = QM_UNHANDLED(); } break; } default: { status_ = QM_SUPER(); break; } } return status_; } } // namespace GAME