643 lines
23 KiB
C++
Raw Normal View History

2013-12-30 17:41:15 -05:00
//****************************************************************************
2012-08-14 18:00:48 -04:00
// Model: game.qm
2013-10-10 20:01:51 -04:00
// File: ./tunnel.cpp
2012-08-14 18:00:48 -04:00
//
2013-10-10 20:01:51 -04:00
// 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.
2012-08-14 18:00:48 -04:00
//
2013-10-10 20:01:51 -04:00
// 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.
2013-12-30 17:41:15 -05:00
//****************************************************************************
2014-04-13 21:35:34 -04:00
//${.::tunnel.cpp} ...........................................................
2015-05-14 16:05:04 -04:00
#include "qpcpp.h"
2012-08-14 18:00:48 -04:00
#include "bsp.h"
#include "game.h"
#include <string.h> // for memmove() and memcpy()
Q_DEFINE_THIS_FILE
2013-12-30 17:41:15 -05:00
// declaration of the Tunnel AO ----------------------------------------------
namespace GAME {
2016-12-01 10:31:49 -05:00
#if ((QP_VERSION < 580) || (QP_VERSION != ((QP_RELEASE^4294967295) % 0x3E8)))
#error qpcpp version 5.8.0 or higher required
#endif
2014-04-13 21:35:34 -04:00
//${AOs::Tunnel} .............................................................
2016-12-01 10:31:49 -05:00
class Tunnel : public QP::QActive {
2012-08-14 18:00:48 -04:00
private:
QP::QTimeEvt m_blinkTimeEvt;
QP::QTimeEvt m_screenTimeEvt;
2016-12-01 10:31:49 -05:00
QP::QHsm * m_mines[GAME_MINES_MAX];
QP::QHsm * m_mine1_pool[GAME_MINES_MAX];
QP::QHsm * m_mine2_pool[GAME_MINES_MAX];
2012-08-14 18:00:48 -04:00
uint8_t m_blink_ctr;
uint8_t m_last_mine_x;
uint8_t m_last_mine_y;
uint8_t m_wall_thickness_top;
uint8_t m_wall_thickness_bottom;
2016-06-10 21:51:18 -04:00
uint8_t m_wall_gap;
2012-08-14 18:00:48 -04:00
public:
Tunnel();
2016-06-10 21:51:18 -04:00
void advance();
2012-08-14 18:00:48 -04:00
private:
void plantMine();
void dispatchToAllMines(QP::QEvt const * e);
protected:
static QP::QState initial(Tunnel * const me, QP::QEvt const * const e);
2016-12-01 10:31:49 -05:00
static QP::QState active(Tunnel * const me, QP::QEvt const * const e);
static QP::QState show_logo(Tunnel * const me, QP::QEvt const * const e);
static QP::QState demo(Tunnel * const me, QP::QEvt const * const e);
static QP::QState playing(Tunnel * const me, QP::QEvt const * const e);
static QP::QState game_over(Tunnel * const me, QP::QEvt const * const e);
static QP::QState screen_saver(Tunnel * const me, QP::QEvt const * const e);
static QP::QState screen_saver_hide(Tunnel * const me, QP::QEvt const * const e);
static QP::QState screen_saver_show(Tunnel * const me, QP::QEvt const * const e);
static QP::QState final(Tunnel * const me, QP::QEvt const * const e);
2012-08-14 18:00:48 -04:00
};
2013-10-10 20:01:51 -04:00
2013-12-30 17:41:15 -05:00
} // namespace GAME
namespace GAME {
// local objects -------------------------------------------------------------
2015-05-14 16:05:04 -04:00
static Tunnel l_tunnel; // the sole instance of the Tunnel active object
2012-08-14 18:00:48 -04:00
// Public-scope objects ------------------------------------------------------
2016-12-01 10:31:49 -05:00
QP::QActive * const AO_Tunnel = &l_tunnel; // opaque pointer
2012-08-14 18:00:48 -04:00
2013-12-30 17:41:15 -05:00
} // namespace GAME
2012-08-14 18:00:48 -04:00
// Active object definition ==================================================
2013-12-30 17:41:15 -05:00
namespace GAME {
2014-04-13 21:35:34 -04:00
//${AOs::Tunnel} .............................................................
//${AOs::Tunnel::Tunnel} .....................................................
2013-12-30 17:41:15 -05:00
Tunnel::Tunnel()
2016-12-01 10:31:49 -05:00
: QActive(Q_STATE_CAST(&Tunnel::initial)),
2013-12-30 17:41:15 -05:00
m_blinkTimeEvt(this, BLINK_TIMEOUT_SIG, 0U),
m_screenTimeEvt(this, SCREEN_TIMEOUT_SIG, 0U),
m_last_mine_x(0U), m_last_mine_y(0U)
2012-08-14 18:00:48 -04:00
{
for (uint8_t n = 0U; n < GAME_MINES_MAX; ++n) {
2013-12-30 17:41:15 -05:00
m_mine1_pool[n] = Mine1_getInst(n); // initialize mine1-type pool
m_mine2_pool[n] = Mine2_getInst(n); // initialize mine2-type pool
2016-12-01 10:31:49 -05:00
m_mines[n] = static_cast<QHsm *>(0); // mine 'n' is unused
2012-08-14 18:00:48 -04:00
}
}
2014-04-13 21:35:34 -04:00
//${AOs::Tunnel::advance} ....................................................
2012-08-14 18:00:48 -04:00
void Tunnel::advance() {
2016-06-10 21:51:18 -04:00
uint32_t rnd = (BSP_random() & 0xFFU);
2012-08-14 18:00:48 -04:00
// reduce the top wall thickness 18.75% of the time
if ((rnd < 48U) && (m_wall_thickness_top > 0U)) {
--m_wall_thickness_top;
}
// reduce the bottom wall thickness 18.75% of the time
if ((rnd > 208U) && (m_wall_thickness_bottom > 0U)) {
--m_wall_thickness_bottom;
}
2016-06-10 21:51:18 -04:00
rnd = (BSP_random() & 0xFFU);
2012-08-14 18:00:48 -04:00
2016-06-10 21:51:18 -04:00
// grow the bottom wall thickness 19.14% of the time
if ((rnd < 49U)
&& ((GAME_TUNNEL_HEIGHT
2012-08-14 18:00:48 -04:00
- m_wall_thickness_top
2016-06-10 21:51:18 -04:00
- m_wall_thickness_bottom) > m_wall_gap))
2012-08-14 18:00:48 -04:00
{
2016-06-10 21:51:18 -04:00
++m_wall_thickness_bottom;
2012-08-14 18:00:48 -04:00
}
2016-06-10 21:51:18 -04:00
// grow the top wall thickness 19.14% of the time
if ((rnd > 207U)
&& ((GAME_TUNNEL_HEIGHT
2012-08-14 18:00:48 -04:00
- m_wall_thickness_top
2016-06-10 21:51:18 -04:00
- m_wall_thickness_bottom) > m_wall_gap))
2012-08-14 18:00:48 -04:00
{
2016-06-10 21:51:18 -04:00
++m_wall_thickness_top;
2012-08-14 18:00:48 -04:00
}
// advance the Tunnel by 1 game step to the left
2016-06-10 21:51:18 -04:00
// and copy the Tunnel layer to the main frame buffer
//
BSP_advanceWalls(m_wall_thickness_top, m_wall_thickness_bottom);
2012-08-14 18:00:48 -04:00
}
2014-04-13 21:35:34 -04:00
//${AOs::Tunnel::plantMine} ..................................................
2012-08-14 18:00:48 -04:00
void Tunnel::plantMine() {
2016-06-10 21:51:18 -04:00
uint32_t rnd = (BSP_random() & 0xFFU);
2012-08-14 18:00:48 -04:00
if (m_last_mine_x > 0U) {
--m_last_mine_x; // shift the last Mine 1 position to the left
}
// last mine far enough?
2016-06-10 21:51:18 -04:00
if ((m_last_mine_x + GAME_MINES_DIST_MIN < GAME_TUNNEL_WIDTH)
2012-08-14 18:00:48 -04:00
&& (rnd < 8U)) // place the mines only 5% of the time
{
uint8_t n;
for (n = 0U; n < Q_DIM(m_mines); ++n) { // look for disabled mines
2016-12-01 10:31:49 -05:00
if (m_mines[n] == (QHsm *)0) {
2012-08-14 18:00:48 -04:00
break;
}
}
if (n < Q_DIM(m_mines)) { // a disabled Mine found?
2016-06-10 21:51:18 -04:00
rnd = (BSP_random() & 0xFFFFU);
2012-08-14 18:00:48 -04:00
if ((rnd & 1U) == 0U) { // choose the type of the mine
m_mines[n] = m_mine1_pool[n];
}
else {
m_mines[n] = m_mine2_pool[n];
}
2016-06-10 21:51:18 -04:00
// new Mine is planted by the end of the tunnel
m_last_mine_x = GAME_TUNNEL_WIDTH - 8U;
2012-08-14 18:00:48 -04:00
// choose a random y-position for the Mine in the Tunnel
2016-06-10 21:51:18 -04:00
rnd %= (GAME_TUNNEL_HEIGHT
2012-08-14 18:00:48 -04:00
- m_wall_thickness_top
- m_wall_thickness_bottom - 4U);
m_last_mine_y = (uint8_t)(m_wall_thickness_top + 2U + rnd);
ObjectPosEvt ope; // event to dispatch to the Mine
ope.sig = MINE_PLANT_SIG;
ope.x = m_last_mine_x;
ope.y = m_last_mine_y;
m_mines[n]->dispatch(&ope); // direct dispatch
}
}
}
2015-05-22 20:38:16 -04:00
//${AOs::Tunnel::dispatchToAllMines} .........................................
2012-08-14 18:00:48 -04:00
void Tunnel::dispatchToAllMines(QP::QEvt const * e) {
for (uint8_t n = 0U; n < GAME_MINES_MAX; ++n) {
2016-12-01 10:31:49 -05:00
if (m_mines[n] != static_cast<QHsm *>(0)) { // is the mine used?
2012-08-14 18:00:48 -04:00
m_mines[n]->dispatch(e);
}
}
}
2014-04-13 21:35:34 -04:00
//${AOs::Tunnel::SM} .........................................................
2012-08-14 18:00:48 -04:00
QP::QState Tunnel::initial(Tunnel * const me, QP::QEvt const * const e) {
2014-04-13 21:35:34 -04:00
// ${AOs::Tunnel::SM::initial}
2012-08-14 18:00:48 -04:00
for (uint8_t n = 0; n < GAME_MINES_MAX; ++n) {
2015-05-14 16:05:04 -04:00
me->m_mine1_pool[n]->init(); // take the initial tran. for Mine1
me->m_mine2_pool[n]->init(); // take the initial tran. for Mine2
2012-08-14 18:00:48 -04:00
}
2016-06-10 21:51:18 -04:00
BSP_randomSeed(1234U); // seed the pseudo-random generator
2012-08-14 18:00:48 -04:00
me->subscribe(TIME_TICK_SIG);
me->subscribe(PLAYER_TRIGGER_SIG);
me->subscribe(PLAYER_QUIT_SIG);
2016-06-10 21:51:18 -04:00
// object dictionary for Tunnel object...
2015-05-14 16:05:04 -04:00
QS_OBJ_DICTIONARY(&l_tunnel);
2012-08-14 18:00:48 -04:00
QS_OBJ_DICTIONARY(&l_tunnel.m_blinkTimeEvt);
QS_OBJ_DICTIONARY(&l_tunnel.m_screenTimeEvt);
2016-06-10 21:51:18 -04:00
// function dictionaries for Tunnel SM...
2015-05-14 16:05:04 -04:00
QS_FUN_DICTIONARY(&Tunnel::initial);
2012-08-14 18:00:48 -04:00
QS_FUN_DICTIONARY(&Tunnel::final);
QS_FUN_DICTIONARY(&Tunnel::active);
QS_FUN_DICTIONARY(&Tunnel::playing);
QS_FUN_DICTIONARY(&Tunnel::demo);
QS_FUN_DICTIONARY(&Tunnel::game_over);
QS_FUN_DICTIONARY(&Tunnel::screen_saver);
QS_FUN_DICTIONARY(&Tunnel::screen_saver_hide);
QS_FUN_DICTIONARY(&Tunnel::screen_saver_show);
2016-06-10 21:51:18 -04:00
// local signals...
2015-05-14 16:05:04 -04:00
QS_SIG_DICTIONARY(BLINK_TIMEOUT_SIG, &l_tunnel);
2012-08-14 18:00:48 -04:00
QS_SIG_DICTIONARY(SCREEN_TIMEOUT_SIG, &l_tunnel);
QS_SIG_DICTIONARY(SHIP_IMG_SIG, &l_tunnel);
QS_SIG_DICTIONARY(MISSILE_IMG_SIG, &l_tunnel);
QS_SIG_DICTIONARY(MINE_IMG_SIG, &l_tunnel);
QS_SIG_DICTIONARY(MINE_DISABLED_SIG, &l_tunnel);
QS_SIG_DICTIONARY(EXPLOSION_SIG, &l_tunnel);
QS_SIG_DICTIONARY(SCORE_SIG, &l_tunnel);
2015-05-14 16:05:04 -04:00
(void)e; // unused parameter
2016-12-01 10:31:49 -05:00
return Q_TRAN(&show_logo);
2012-08-14 18:00:48 -04:00
}
2014-04-13 21:35:34 -04:00
//${AOs::Tunnel::SM::active} .................................................
2012-08-14 18:00:48 -04:00
QP::QState Tunnel::active(Tunnel * const me, QP::QEvt const * const e) {
2013-10-10 20:01:51 -04:00
QP::QState status_;
2012-08-14 18:00:48 -04:00
switch (e->sig) {
2014-04-13 21:35:34 -04:00
// ${AOs::Tunnel::SM::active::MINE_DISABLED}
2012-08-14 18:00:48 -04:00
case MINE_DISABLED_SIG: {
Q_ASSERT((Q_EVT_CAST(MineEvt)->id < GAME_MINES_MAX)
2016-12-01 10:31:49 -05:00
&& (me->m_mines[Q_EVT_CAST(MineEvt)->id] != static_cast<QHsm *>(0)));
me->m_mines[Q_EVT_CAST(MineEvt)->id] = static_cast<QHsm *>(0);
status_ = Q_HANDLED();
2012-08-14 18:00:48 -04:00
break;
}
2014-04-13 21:35:34 -04:00
// ${AOs::Tunnel::SM::active::PLAYER_QUIT}
2012-08-14 18:00:48 -04:00
case PLAYER_QUIT_SIG: {
2016-12-01 10:31:49 -05:00
status_ = Q_TRAN(&final);
2012-08-14 18:00:48 -04:00
break;
}
default: {
2016-12-01 10:31:49 -05:00
status_ = Q_SUPER(&top);
2012-08-14 18:00:48 -04:00
break;
}
}
2013-10-10 20:01:51 -04:00
return status_;
2012-08-14 18:00:48 -04:00
}
2014-04-13 21:35:34 -04:00
//${AOs::Tunnel::SM::active::show_logo} ......................................
2013-10-10 20:01:51 -04:00
QP::QState Tunnel::show_logo(Tunnel * const me, QP::QEvt const * const e) {
QP::QState status_;
2012-08-14 18:00:48 -04:00
switch (e->sig) {
2016-12-01 10:31:49 -05:00
// ${AOs::Tunnel::SM::active::show_logo}
case Q_ENTRY_SIG: {
me->m_blinkTimeEvt.armX(BSP_TICKS_PER_SEC/2U,
BSP_TICKS_PER_SEC/2U); // every 1/2 sec
me->m_screenTimeEvt.armX(BSP_TICKS_PER_SEC*5U, 0U); // in 5 sec
me->m_blink_ctr = 0U;
BSP_paintString(24U, (GAME_TUNNEL_HEIGHT / 2U) - 8U, "Quantum LeAps");
BSP_paintString(16U, (GAME_TUNNEL_HEIGHT / 2U) + 0U, "state-machine.com");
BSP_paintString(1U, GAME_TUNNEL_HEIGHT - 18U, "Fire missile: BTN0");
BSP_paintString(1U, GAME_TUNNEL_HEIGHT - 10U, "Fly ship up: BTN1");
BSP_updateScreen();
status_ = Q_HANDLED();
break;
}
// ${AOs::Tunnel::SM::active::show_logo}
case Q_EXIT_SIG: {
me->m_blinkTimeEvt.disarm();
me->m_screenTimeEvt.disarm();
status_ = Q_HANDLED();
break;
}
2014-04-13 21:35:34 -04:00
// ${AOs::Tunnel::SM::active::show_logo::SCREEN_TIMEOUT}
2013-10-10 20:01:51 -04:00
case SCREEN_TIMEOUT_SIG: {
2016-12-01 10:31:49 -05:00
status_ = Q_TRAN(&demo);
2013-10-10 20:01:51 -04:00
break;
}
2014-04-13 21:35:34 -04:00
// ${AOs::Tunnel::SM::active::show_logo::BLINK_TIMEOUT}
2013-10-10 20:01:51 -04:00
case BLINK_TIMEOUT_SIG: {
2016-06-10 21:51:18 -04:00
me->m_blink_ctr ^= 1U; // toggle the blink counter
2015-05-22 20:38:16 -04:00
// ${AOs::Tunnel::SM::active::show_logo::BLINK_TIMEOUT::[me->m_blink_ctr==0U]}
2013-10-10 20:01:51 -04:00
if (me->m_blink_ctr == 0U) {
2016-06-10 21:51:18 -04:00
BSP_paintString(24U + 8U*6U, (GAME_TUNNEL_HEIGHT / 2U) - 8U, "LeAps");
BSP_updateScreen();
2016-12-01 10:31:49 -05:00
status_ = Q_HANDLED();
2013-10-10 20:01:51 -04:00
}
2014-04-13 21:35:34 -04:00
// ${AOs::Tunnel::SM::active::show_logo::BLINK_TIMEOUT::[else]}
2013-10-10 20:01:51 -04:00
else {
2016-06-10 21:51:18 -04:00
BSP_paintString(24U + 8U*6U, (GAME_TUNNEL_HEIGHT / 2U) - 8U, "LeaPs");
BSP_updateScreen();
2016-12-01 10:31:49 -05:00
status_ = Q_HANDLED();
2013-10-10 20:01:51 -04:00
}
break;
}
default: {
2016-12-01 10:31:49 -05:00
status_ = Q_SUPER(&active);
2013-10-10 20:01:51 -04:00
break;
}
}
return status_;
}
2014-04-13 21:35:34 -04:00
//${AOs::Tunnel::SM::active::demo} ...........................................
2013-10-10 20:01:51 -04:00
QP::QState Tunnel::demo(Tunnel * const me, QP::QEvt const * const e) {
QP::QState status_;
switch (e->sig) {
2016-12-01 10:31:49 -05:00
// ${AOs::Tunnel::SM::active::demo}
case Q_ENTRY_SIG: {
me->m_last_mine_x = 0U; // last mine at right edge of the tunnel
me->m_last_mine_y = 0U;
// set the tunnel properties...
me->m_wall_thickness_top = 0U;
me->m_wall_thickness_bottom = 0U;
me->m_wall_gap = GAME_WALLS_GAP_Y;
BSP_clearWalls(); // erase the tunnel walls
me->m_blinkTimeEvt.armX(BSP_TICKS_PER_SEC/2U,
BSP_TICKS_PER_SEC/2U); // every 1/2 sec
me->m_screenTimeEvt.armX(BSP_TICKS_PER_SEC*20U, 0U); // in 20 sec
me->m_blink_ctr = 0U; // init the blink counter
status_ = Q_HANDLED();
break;
}
// ${AOs::Tunnel::SM::active::demo}
case Q_EXIT_SIG: {
me->m_blinkTimeEvt.disarm();
me->m_screenTimeEvt.disarm();
status_ = Q_HANDLED();
break;
}
2014-04-13 21:35:34 -04:00
// ${AOs::Tunnel::SM::active::demo::BLINK_TIMEOUT}
2012-08-14 18:00:48 -04:00
case BLINK_TIMEOUT_SIG: {
me->m_blink_ctr ^= 1U; /* toggle the blink cunter */
2016-12-01 10:31:49 -05:00
status_ = Q_HANDLED();
2012-08-14 18:00:48 -04:00
break;
}
2014-04-13 21:35:34 -04:00
// ${AOs::Tunnel::SM::active::demo::SCREEN_TIMEOUT}
2012-08-14 18:00:48 -04:00
case SCREEN_TIMEOUT_SIG: {
2016-12-01 10:31:49 -05:00
status_ = Q_TRAN(&screen_saver);
2012-08-14 18:00:48 -04:00
break;
}
2014-04-13 21:35:34 -04:00
// ${AOs::Tunnel::SM::active::demo::TIME_TICK}
2012-08-14 18:00:48 -04:00
case TIME_TICK_SIG: {
me->advance();
if (me->m_blink_ctr != 0U) {
2016-06-10 21:51:18 -04:00
// add the text into the frame buffer
BSP_paintString((GAME_TUNNEL_WIDTH - 10U*6U)/2U,
(GAME_TUNNEL_HEIGHT - 4U)/2U,
"Press BTN0");
2012-08-14 18:00:48 -04:00
}
2016-06-10 21:51:18 -04:00
BSP_updateScreen();
2016-12-01 10:31:49 -05:00
status_ = Q_HANDLED();
2012-08-14 18:00:48 -04:00
break;
}
2014-04-13 21:35:34 -04:00
// ${AOs::Tunnel::SM::active::demo::PLAYER_TRIGGER}
2012-08-14 18:00:48 -04:00
case PLAYER_TRIGGER_SIG: {
2016-12-01 10:31:49 -05:00
status_ = Q_TRAN(&playing);
2012-08-14 18:00:48 -04:00
break;
}
default: {
2016-12-01 10:31:49 -05:00
status_ = Q_SUPER(&active);
2012-08-14 18:00:48 -04:00
break;
}
}
2013-10-10 20:01:51 -04:00
return status_;
2012-08-14 18:00:48 -04:00
}
2014-04-13 21:35:34 -04:00
//${AOs::Tunnel::SM::active::playing} ........................................
2012-08-14 18:00:48 -04:00
QP::QState Tunnel::playing(Tunnel * const me, QP::QEvt const * const e) {
2013-10-10 20:01:51 -04:00
QP::QState status_;
2012-08-14 18:00:48 -04:00
switch (e->sig) {
2016-12-01 10:31:49 -05:00
// ${AOs::Tunnel::SM::active::playing}
case Q_ENTRY_SIG: {
static QP::QEvt const takeoff = QEVT_INITIALIZER(TAKE_OFF_SIG);
me->m_wall_gap = GAME_WALLS_GAP_Y;
AO_Ship->POST(&takeoff, me); // post the TAKEOFF sig
status_ = Q_HANDLED();
break;
}
// ${AOs::Tunnel::SM::active::playing}
case Q_EXIT_SIG: {
QP::QEvt recycle;
recycle.sig = MINE_RECYCLE_SIG;
me->dispatchToAllMines(&recycle); // recycle all Mines
status_ = Q_HANDLED();
break;
}
2014-04-13 21:35:34 -04:00
// ${AOs::Tunnel::SM::active::playing::TIME_TICK}
2012-08-14 18:00:48 -04:00
case TIME_TICK_SIG: {
// render this frame on the display
2016-06-10 21:51:18 -04:00
BSP_updateScreen();
2012-08-14 18:00:48 -04:00
me->advance();
me->plantMine();
me->dispatchToAllMines(e);
2016-12-01 10:31:49 -05:00
status_ = Q_HANDLED();
2012-08-14 18:00:48 -04:00
break;
}
2014-04-13 21:35:34 -04:00
// ${AOs::Tunnel::SM::active::playing::SHIP_IMG}
2012-08-14 18:00:48 -04:00
case SHIP_IMG_SIG: {
uint8_t x = Q_EVT_CAST(ObjectImageEvt)->x;
int8_t y = Q_EVT_CAST(ObjectImageEvt)->y;
uint8_t bmp = Q_EVT_CAST(ObjectImageEvt)->bmp;
// did the Ship/Missile hit the tunnel wall?
2016-06-10 21:51:18 -04:00
if (BSP_isWallHit(bmp, x, y)) {
2012-08-14 18:00:48 -04:00
static QP::QEvt const hit = QEVT_INITIALIZER(HIT_WALL_SIG);
AO_Ship->POST(&hit, me);
}
2016-06-10 21:51:18 -04:00
BSP_paintBitmap(x, y, bmp);
2012-08-14 18:00:48 -04:00
me->dispatchToAllMines(e); // let Mines check for hits
2016-12-01 10:31:49 -05:00
status_ = Q_HANDLED();
2012-08-14 18:00:48 -04:00
break;
}
2014-04-13 21:35:34 -04:00
// ${AOs::Tunnel::SM::active::playing::MISSILE_IMG}
2012-08-14 18:00:48 -04:00
case MISSILE_IMG_SIG: {
uint8_t x = Q_EVT_CAST(ObjectImageEvt)->x;
int8_t y = Q_EVT_CAST(ObjectImageEvt)->y;
uint8_t bmp = Q_EVT_CAST(ObjectImageEvt)->bmp;
// did the Ship/Missile hit the tunnel wall?
2016-06-10 21:51:18 -04:00
if (BSP_isWallHit(bmp, x, y)) {
2012-08-14 18:00:48 -04:00
static QP::QEvt const hit = QEVT_INITIALIZER(HIT_WALL_SIG);
AO_Missile->POST(&hit, me);
}
2016-06-10 21:51:18 -04:00
BSP_paintBitmap(x, y, bmp);
2012-08-14 18:00:48 -04:00
me->dispatchToAllMines(e); // let Mines check for hits
2016-12-01 10:31:49 -05:00
status_ = Q_HANDLED();
2012-08-14 18:00:48 -04:00
break;
}
2014-04-13 21:35:34 -04:00
// ${AOs::Tunnel::SM::active::playing::MINE_IMG}
2012-08-14 18:00:48 -04:00
case MINE_IMG_SIG: {
2016-06-10 21:51:18 -04:00
BSP_paintBitmap(Q_EVT_CAST(ObjectImageEvt)->x,
Q_EVT_CAST(ObjectImageEvt)->y,
Q_EVT_CAST(ObjectImageEvt)->bmp);
2016-12-01 10:31:49 -05:00
status_ = Q_HANDLED();
2012-08-14 18:00:48 -04:00
break;
}
2014-04-13 21:35:34 -04:00
// ${AOs::Tunnel::SM::active::playing::EXPLOSION}
2012-08-14 18:00:48 -04:00
case EXPLOSION_SIG: {
2016-06-10 21:51:18 -04:00
BSP_paintBitmap(Q_EVT_CAST(ObjectImageEvt)->x,
Q_EVT_CAST(ObjectImageEvt)->y,
Q_EVT_CAST(ObjectImageEvt)->bmp);
2016-12-01 10:31:49 -05:00
status_ = Q_HANDLED();
2012-08-14 18:00:48 -04:00
break;
}
2014-04-13 21:35:34 -04:00
// ${AOs::Tunnel::SM::active::playing::SCORE}
2012-08-14 18:00:48 -04:00
case SCORE_SIG: {
BSP_updateScore(Q_EVT_CAST(ScoreEvt)->score);
// increase difficulty of the game:
// the tunnel gets narrower as the score goes up
//
2016-06-10 21:51:18 -04:00
me->m_wall_gap = (uint8_t)(GAME_WALLS_GAP_Y
- Q_EVT_CAST(ScoreEvt)->score/100U);
if (me->m_wall_gap < GAME_WALLS_MIN_GAP_Y) {
me->m_wall_gap = GAME_WALLS_MIN_GAP_Y;
}
2016-12-01 10:31:49 -05:00
status_ = Q_HANDLED();
2012-08-14 18:00:48 -04:00
break;
}
2014-04-13 21:35:34 -04:00
// ${AOs::Tunnel::SM::active::playing::GAME_OVER}
2012-08-14 18:00:48 -04:00
case GAME_OVER_SIG: {
2016-06-10 21:51:18 -04:00
BSP_clearWalls();
BSP_updateScore(Q_EVT_CAST(ScoreEvt)->score);
BSP_updateScreen();
2016-12-01 10:31:49 -05:00
status_ = Q_TRAN(&game_over);
2012-08-14 18:00:48 -04:00
break;
}
default: {
2016-12-01 10:31:49 -05:00
status_ = Q_SUPER(&active);
2012-08-14 18:00:48 -04:00
break;
}
}
2013-10-10 20:01:51 -04:00
return status_;
2012-08-14 18:00:48 -04:00
}
2014-04-13 21:35:34 -04:00
//${AOs::Tunnel::SM::active::game_over} ......................................
2012-08-14 18:00:48 -04:00
QP::QState Tunnel::game_over(Tunnel * const me, QP::QEvt const * const e) {
2013-10-10 20:01:51 -04:00
QP::QState status_;
2012-08-14 18:00:48 -04:00
switch (e->sig) {
2016-12-01 10:31:49 -05:00
// ${AOs::Tunnel::SM::active::game_over}
case Q_ENTRY_SIG: {
me->m_blinkTimeEvt.armX(BSP_TICKS_PER_SEC/2U,
BSP_TICKS_PER_SEC/2U); // every 1/2 sec
me->m_screenTimeEvt.armX(BSP_TICKS_PER_SEC*5U, 0U); // in 5 se
me->m_blink_ctr = 0U;
BSP_paintString((GAME_TUNNEL_WIDTH - 6U * 9U) / 2U,
(GAME_TUNNEL_HEIGHT / 2U) - 4U,
"Game Over");
BSP_updateScreen();
status_ = Q_HANDLED();
break;
}
// ${AOs::Tunnel::SM::active::game_over}
case Q_EXIT_SIG: {
me->m_blinkTimeEvt.disarm();
me->m_screenTimeEvt.disarm();
BSP_updateScore(0U); // update the score on the display
status_ = Q_HANDLED();
break;
}
2014-04-13 21:35:34 -04:00
// ${AOs::Tunnel::SM::active::game_over::BLINK_TIMEOUT}
2012-08-14 18:00:48 -04:00
case BLINK_TIMEOUT_SIG: {
2016-06-10 21:51:18 -04:00
me->m_blink_ctr ^= 1U; // toggle the blink counter
BSP_paintString((GAME_TUNNEL_WIDTH - 6U*9U) / 2U,
(GAME_TUNNEL_HEIGHT / 2U) - 4U,
2012-08-14 18:00:48 -04:00
((me->m_blink_ctr == 0U)
2016-06-10 21:51:18 -04:00
? "Game Over"
: " "));
BSP_updateScreen();
2016-12-01 10:31:49 -05:00
status_ = Q_HANDLED();
2012-08-14 18:00:48 -04:00
break;
}
2014-04-13 21:35:34 -04:00
// ${AOs::Tunnel::SM::active::game_over::SCREEN_TIMEOUT}
2012-08-14 18:00:48 -04:00
case SCREEN_TIMEOUT_SIG: {
2016-12-01 10:31:49 -05:00
status_ = Q_TRAN(&demo);
2012-08-14 18:00:48 -04:00
break;
}
default: {
2016-12-01 10:31:49 -05:00
status_ = Q_SUPER(&active);
2012-08-14 18:00:48 -04:00
break;
}
}
2013-10-10 20:01:51 -04:00
return status_;
2012-08-14 18:00:48 -04:00
}
2014-04-13 21:35:34 -04:00
//${AOs::Tunnel::SM::active::screen_saver} ...................................
2012-08-14 18:00:48 -04:00
QP::QState Tunnel::screen_saver(Tunnel * const me, QP::QEvt const * const e) {
2013-10-10 20:01:51 -04:00
QP::QState status_;
2012-08-14 18:00:48 -04:00
switch (e->sig) {
2016-12-01 10:31:49 -05:00
// ${AOs::Tunnel::SM::active::screen_saver::initial}
case Q_INIT_SIG: {
status_ = Q_TRAN(&screen_saver_hide);
break;
}
2014-04-13 21:35:34 -04:00
// ${AOs::Tunnel::SM::active::screen_saver::PLAYER_TRIGGER}
2012-08-14 18:00:48 -04:00
case PLAYER_TRIGGER_SIG: {
2016-12-01 10:31:49 -05:00
status_ = Q_TRAN(&demo);
2012-08-14 18:00:48 -04:00
break;
}
default: {
2016-12-01 10:31:49 -05:00
status_ = Q_SUPER(&active);
2012-08-14 18:00:48 -04:00
break;
}
}
2013-10-10 20:01:51 -04:00
return status_;
2012-08-14 18:00:48 -04:00
}
2015-05-22 20:38:16 -04:00
//${AOs::Tunnel::SM::active::screen_saver::screen_saver_hide} ................
2012-08-14 18:00:48 -04:00
QP::QState Tunnel::screen_saver_hide(Tunnel * const me, QP::QEvt const * const e) {
2013-10-10 20:01:51 -04:00
QP::QState status_;
2012-08-14 18:00:48 -04:00
switch (e->sig) {
2016-12-01 10:31:49 -05:00
// ${AOs::Tunnel::SM::active::screen_saver::screen_saver_hide}
case Q_ENTRY_SIG: {
BSP_displayOff(); // power down the display
me->m_screenTimeEvt.armX(BSP_TICKS_PER_SEC*3U, 0U); // in 3 sec
status_ = Q_HANDLED();
break;
}
// ${AOs::Tunnel::SM::active::screen_saver::screen_saver_hide}
case Q_EXIT_SIG: {
me->m_screenTimeEvt.disarm();
BSP_displayOn(); // power up the display
status_ = Q_HANDLED();
break;
}
// ${AOs::Tunnel::SM::active::screen_saver::screen_saver_hid~::SCREEN_TIMEOUT}
2012-08-14 18:00:48 -04:00
case SCREEN_TIMEOUT_SIG: {
2016-12-01 10:31:49 -05:00
status_ = Q_TRAN(&screen_saver_show);
2012-08-14 18:00:48 -04:00
break;
}
default: {
2016-12-01 10:31:49 -05:00
status_ = Q_SUPER(&screen_saver);
2012-08-14 18:00:48 -04:00
break;
}
}
2013-10-10 20:01:51 -04:00
return status_;
2012-08-14 18:00:48 -04:00
}
2015-05-22 20:38:16 -04:00
//${AOs::Tunnel::SM::active::screen_saver::screen_saver_show} ................
2012-08-14 18:00:48 -04:00
QP::QState Tunnel::screen_saver_show(Tunnel * const me, QP::QEvt const * const e) {
2013-10-10 20:01:51 -04:00
QP::QState status_;
2012-08-14 18:00:48 -04:00
switch (e->sig) {
2016-12-01 10:31:49 -05:00
// ${AOs::Tunnel::SM::active::screen_saver::screen_saver_show}
case Q_ENTRY_SIG: {
BSP_clearFB(); // clear the screen frame buffer
uint32_t rnd = BSP_random();
BSP_paintString((uint8_t)(rnd % (GAME_TUNNEL_WIDTH - 10U*6U)),
(uint8_t) (rnd % (GAME_TUNNEL_HEIGHT - 8U)),
"Press BTN0");
BSP_updateScreen();
me->m_screenTimeEvt.armX(BSP_TICKS_PER_SEC/3U, 0U); // in 1/3 sec
status_ = Q_HANDLED();
break;
}
// ${AOs::Tunnel::SM::active::screen_saver::screen_saver_show}
case Q_EXIT_SIG: {
me->m_screenTimeEvt.disarm();
BSP_clearFB();
BSP_updateScreen();
status_ = Q_HANDLED();
break;
}
// ${AOs::Tunnel::SM::active::screen_saver::screen_saver_sho~::SCREEN_TIMEOUT}
2012-08-14 18:00:48 -04:00
case SCREEN_TIMEOUT_SIG: {
2016-12-01 10:31:49 -05:00
status_ = Q_TRAN(&screen_saver_hide);
2012-08-14 18:00:48 -04:00
break;
}
default: {
2016-12-01 10:31:49 -05:00
status_ = Q_SUPER(&screen_saver);
2012-08-14 18:00:48 -04:00
break;
}
}
2013-10-10 20:01:51 -04:00
return status_;
2012-08-14 18:00:48 -04:00
}
2014-04-13 21:35:34 -04:00
//${AOs::Tunnel::SM::final} ..................................................
2012-08-14 18:00:48 -04:00
QP::QState Tunnel::final(Tunnel * const me, QP::QEvt const * const e) {
2013-10-10 20:01:51 -04:00
QP::QState status_;
2012-08-14 18:00:48 -04:00
switch (e->sig) {
2016-12-01 10:31:49 -05:00
// ${AOs::Tunnel::SM::final}
case Q_ENTRY_SIG: {
BSP_clearFB();
BSP_updateScreen();
QP::QF::stop(); // stop QF and cleanup
status_ = Q_HANDLED();
break;
}
2012-08-14 18:00:48 -04:00
default: {
2016-12-01 10:31:49 -05:00
status_ = Q_SUPER(&top);
2012-08-14 18:00:48 -04:00
break;
}
}
2013-10-10 20:01:51 -04:00
return status_;
2012-08-14 18:00:48 -04:00
}
2013-12-30 17:41:15 -05:00
} // namespace GAME