mirror of
https://github.com/QuantumLeaps/qpcpp.git
synced 2025-01-28 06:02:56 +08:00
1460 lines
53 KiB
XML
1460 lines
53 KiB
XML
<?xml version="1.0" encoding="UTF-8"?>
|
|
<model version="5.1.0" links="1">
|
|
<documentation>"Fly 'n' Shoot" game model from Chapters 1 & 9 of PSiCC2
|
|
|
|
NOTE: Requries QP6.</documentation>
|
|
<!--${qpcpp}-->
|
|
<framework name="qpcpp"/>
|
|
<!--${Events}-->
|
|
<package name="Events" stereotype="0x01" namespace="GAME::">
|
|
<!--${Events::ObjectPosEvt}-->
|
|
<class name="ObjectPosEvt" superclass="qpcpp::QEvt">
|
|
<!--${Events::ObjectPosEvt::x}-->
|
|
<attribute name="x" type="uint8_t" visibility="0x00" properties="0x00"/>
|
|
<!--${Events::ObjectPosEvt::y}-->
|
|
<attribute name="y" type="uint8_t" visibility="0x00" properties="0x00"/>
|
|
</class>
|
|
<!--${Events::ObjectImageEvt}-->
|
|
<class name="ObjectImageEvt" superclass="qpcpp::QEvt">
|
|
<!--${Events::ObjectImageEvt::x}-->
|
|
<attribute name="x" type="uint8_t" visibility="0x00" properties="0x00"/>
|
|
<!--${Events::ObjectImageEvt::y}-->
|
|
<attribute name="y" type="int8_t" visibility="0x00" properties="0x00"/>
|
|
<!--${Events::ObjectImageEvt::bmp}-->
|
|
<attribute name="bmp" type="uint8_t" visibility="0x00" properties="0x00"/>
|
|
</class>
|
|
<!--${Events::MineEvt}-->
|
|
<class name="MineEvt" superclass="qpcpp::QEvt">
|
|
<!--${Events::MineEvt::id}-->
|
|
<attribute name="id" type="uint8_t" visibility="0x00" properties="0x00"/>
|
|
<!--${Events::MineEvt::MineEvt}-->
|
|
<operation name="MineEvt" type="" visibility="0x00" properties="0x02">
|
|
<documentation>This constructor is called only for statically allocated MineEvt
|
|
NOTE: QP can call event constructors in Q_NEW, when the port is configured with the Q_EVT_CTOR macro</documentation>
|
|
<!--${Events::MineEvt::MineEvt::sig_p}-->
|
|
<parameter name="sig_p" type="QP::QSignal"/>
|
|
<!--${Events::MineEvt::MineEvt::id_p}-->
|
|
<parameter name="id_p" type="uint8_t"/>
|
|
<code>sig = sig_p;
|
|
poolId_ = 0U;
|
|
id = id_p;</code>
|
|
</operation>
|
|
</class>
|
|
<!--${Events::ScoreEvt}-->
|
|
<class name="ScoreEvt" superclass="qpcpp::QEvt">
|
|
<!--${Events::ScoreEvt::score}-->
|
|
<attribute name="score" type="uint16_t" visibility="0x00" properties="0x00"/>
|
|
<!--${Events::ScoreEvt::ScoreEvt}-->
|
|
<operation name="ScoreEvt" type="" visibility="0x00" properties="0x02">
|
|
<documentation>This constructor is called only for statically allocated MineEvt
|
|
NOTE: QP can call event constructors in Q_NEW, when the port is configured with the Q_EVT_CTOR macro</documentation>
|
|
<!--${Events::ScoreEvt::ScoreEvt::sig_p}-->
|
|
<parameter name="sig_p" type="QP::QSignal"/>
|
|
<!--${Events::ScoreEvt::ScoreEvt::score_p}-->
|
|
<parameter name="score_p" type="uint16_t"/>
|
|
<code>sig = sig_p;
|
|
poolId_ = 0U;
|
|
score = score_p;</code>
|
|
</operation>
|
|
</class>
|
|
</package>
|
|
<!--${AOs}-->
|
|
<package name="AOs" stereotype="0x02" namespace="GAME::">
|
|
<!--${AOs::Tunnel}-->
|
|
<class name="Tunnel" superclass="qpcpp::QActive">
|
|
<documentation>Tunnel Active Object</documentation>
|
|
<!--${AOs::Tunnel::m_blinkTimeEvt}-->
|
|
<attribute name="m_blinkTimeEvt" type="QP::QTimeEvt" visibility="0x02" properties="0x00"/>
|
|
<!--${AOs::Tunnel::m_screenTimeEvt}-->
|
|
<attribute name="m_screenTimeEvt" type="QP::QTimeEvt" visibility="0x02" properties="0x00"/>
|
|
<!--${AOs::Tunnel::m_mines[GAME_MINES_MAX]}-->
|
|
<attribute name="m_mines[GAME_MINES_MAX]" type="QP::QHsm *" visibility="0x02" properties="0x00"/>
|
|
<!--${AOs::Tunnel::m_mine1_pool[GAME_MINES_MAX]}-->
|
|
<attribute name="m_mine1_pool[GAME_MINES_MAX]" type="QP::QHsm *" visibility="0x02" properties="0x00"/>
|
|
<!--${AOs::Tunnel::m_mine2_pool[GAME_MINES_MAX]}-->
|
|
<attribute name="m_mine2_pool[GAME_MINES_MAX]" type="QP::QHsm *" visibility="0x02" properties="0x00"/>
|
|
<!--${AOs::Tunnel::m_blink_ctr}-->
|
|
<attribute name="m_blink_ctr" type="uint8_t" visibility="0x02" properties="0x00"/>
|
|
<!--${AOs::Tunnel::m_last_mine_x}-->
|
|
<attribute name="m_last_mine_x" type="uint8_t" visibility="0x02" properties="0x00"/>
|
|
<!--${AOs::Tunnel::m_last_mine_y}-->
|
|
<attribute name="m_last_mine_y" type="uint8_t" visibility="0x02" properties="0x00"/>
|
|
<!--${AOs::Tunnel::m_wall_thickness_top}-->
|
|
<attribute name="m_wall_thickness_top" type="uint8_t" visibility="0x02" properties="0x00"/>
|
|
<!--${AOs::Tunnel::m_wall_thickness_bottom}-->
|
|
<attribute name="m_wall_thickness_bottom" type="uint8_t" visibility="0x02" properties="0x00"/>
|
|
<!--${AOs::Tunnel::m_wall_gap}-->
|
|
<attribute name="m_wall_gap" type="uint8_t" visibility="0x02" properties="0x00"/>
|
|
<!--${AOs::Tunnel::Tunnel}-->
|
|
<operation name="Tunnel" type="" visibility="0x00" properties="0x00">
|
|
<code> : QActive(&initial),
|
|
m_blinkTimeEvt(this, BLINK_TIMEOUT_SIG, 0U),
|
|
m_screenTimeEvt(this, SCREEN_TIMEOUT_SIG, 0U),
|
|
m_last_mine_x(0U), m_last_mine_y(0U)
|
|
|
|
for (uint8_t n = 0U; n < GAME_MINES_MAX; ++n) {
|
|
m_mine1_pool[n] = Mine1_getInst(n); // initialize mine1-type pool
|
|
m_mine2_pool[n] = Mine2_getInst(n); // initialize mine2-type pool
|
|
m_mines[n] = nullptr; // mine 'n' is unused
|
|
}</code>
|
|
</operation>
|
|
<!--${AOs::Tunnel::advance}-->
|
|
<operation name="advance" type="void" visibility="0x00" properties="0x00">
|
|
<code>uint32_t rnd = (BSP_random() & 0xFFU);
|
|
|
|
// 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;
|
|
}
|
|
|
|
rnd = (BSP_random() & 0xFFU);
|
|
|
|
// grow the bottom wall thickness 19.14% of the time
|
|
if ((rnd < 49U)
|
|
&& ((GAME_TUNNEL_HEIGHT
|
|
- m_wall_thickness_top
|
|
- m_wall_thickness_bottom) > m_wall_gap))
|
|
{
|
|
++m_wall_thickness_bottom;
|
|
}
|
|
|
|
// grow the top wall thickness 19.14% of the time
|
|
if ((rnd > 207U)
|
|
&& ((GAME_TUNNEL_HEIGHT
|
|
- m_wall_thickness_top
|
|
- m_wall_thickness_bottom) > m_wall_gap))
|
|
{
|
|
++m_wall_thickness_top;
|
|
}
|
|
|
|
// advance the Tunnel by 1 game step to the left
|
|
// and copy the Tunnel layer to the main frame buffer
|
|
//
|
|
BSP_advanceWalls(m_wall_thickness_top, m_wall_thickness_bottom);</code>
|
|
</operation>
|
|
<!--${AOs::Tunnel::plantMine}-->
|
|
<operation name="plantMine" type="void" visibility="0x02" properties="0x00">
|
|
<code>uint32_t rnd = (BSP_random() & 0xFFU);
|
|
|
|
if (m_last_mine_x > 0U) {
|
|
--m_last_mine_x; // shift the last Mine 1 position to the left
|
|
}
|
|
// last mine far enough?
|
|
if ((m_last_mine_x + GAME_MINES_DIST_MIN < GAME_TUNNEL_WIDTH)
|
|
&& (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
|
|
if (m_mines[n] == (QHsm *)0) {
|
|
break;
|
|
}
|
|
}
|
|
if (n < Q_DIM(m_mines)) { // a disabled Mine found?
|
|
rnd = (BSP_random() & 0xFFFFU);
|
|
|
|
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];
|
|
}
|
|
|
|
// new Mine is planted by the end of the tunnel
|
|
m_last_mine_x = GAME_TUNNEL_WIDTH - 8U;
|
|
|
|
// choose a random y-position for the Mine in the Tunnel
|
|
rnd %= (GAME_TUNNEL_HEIGHT
|
|
- 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, m_prio); // direct dispatch
|
|
}
|
|
}</code>
|
|
</operation>
|
|
<!--${AOs::Tunnel::dispatchToAllMines}-->
|
|
<operation name="dispatchToAllMines" type="void" visibility="0x02" properties="0x00">
|
|
<!--${AOs::Tunnel::dispatchToAllMin~::e}-->
|
|
<parameter name="e" type="QP::QEvt const *"/>
|
|
<code>for (uint8_t n = 0U; n < GAME_MINES_MAX; ++n) {
|
|
if (m_mines[n] != nullptr) { // is the mine used?
|
|
m_mines[n]->dispatch(e, m_prio);
|
|
}
|
|
}</code>
|
|
</operation>
|
|
<!--${AOs::Tunnel::SM}-->
|
|
<statechart properties="0x02">
|
|
<!--${AOs::Tunnel::SM::initial}-->
|
|
<initial target="../1/2">
|
|
<action>for (uint8_t n = 0; n < GAME_MINES_MAX; ++n) {
|
|
m_mine1_pool[n]->init(m_prio); // take the initial tran. for Mine1
|
|
m_mine2_pool[n]->init(m_prio); // take the initial tran. for Mine2
|
|
}
|
|
|
|
BSP_randomSeed(1234U); // seed the pseudo-random generator
|
|
|
|
subscribe(TIME_TICK_SIG);
|
|
subscribe(PLAYER_TRIGGER_SIG);
|
|
subscribe(PLAYER_QUIT_SIG);
|
|
|
|
// object dictionary for Tunnel object...
|
|
QS_OBJ_DICTIONARY(&l_tunnel.m_blinkTimeEvt);
|
|
QS_OBJ_DICTIONARY(&l_tunnel.m_screenTimeEvt);
|
|
|
|
// local signals...
|
|
QS_SIG_DICTIONARY(BLINK_TIMEOUT_SIG, this);
|
|
QS_SIG_DICTIONARY(SCREEN_TIMEOUT_SIG, this);
|
|
QS_SIG_DICTIONARY(SHIP_IMG_SIG, this);
|
|
QS_SIG_DICTIONARY(MISSILE_IMG_SIG, this);
|
|
QS_SIG_DICTIONARY(MINE_IMG_SIG, this);
|
|
QS_SIG_DICTIONARY(MINE_DISABLED_SIG, this);
|
|
QS_SIG_DICTIONARY(EXPLOSION_SIG, this);
|
|
QS_SIG_DICTIONARY(SCORE_SIG, this);
|
|
|
|
(void)e; // unused parameter</action>
|
|
<initial_glyph conn="3,2,5,1,26,15,-3">
|
|
<action box="1,-2,11,2"/>
|
|
</initial_glyph>
|
|
</initial>
|
|
<!--${AOs::Tunnel::SM::active}-->
|
|
<state name="active">
|
|
<!--${AOs::Tunnel::SM::active::MINE_DISABLED}-->
|
|
<tran trig="MINE_DISABLED">
|
|
<action>Q_ASSERT((Q_EVT_CAST(MineEvt)->id < GAME_MINES_MAX)
|
|
&& (m_mines[Q_EVT_CAST(MineEvt)->id] != nullptr));
|
|
m_mines[Q_EVT_CAST(MineEvt)->id] = nullptr;</action>
|
|
<tran_glyph conn="2,9,3,-1,14">
|
|
<action box="0,-2,14,2"/>
|
|
</tran_glyph>
|
|
</tran>
|
|
<!--${AOs::Tunnel::SM::active::PLAYER_QUIT}-->
|
|
<tran trig="PLAYER_QUIT" target="../../2">
|
|
<tran_glyph conn="2,12,3,1,62,76,-38">
|
|
<action box="0,-2,11,2"/>
|
|
</tran_glyph>
|
|
</tran>
|
|
<!--${AOs::Tunnel::SM::active::show_logo}-->
|
|
<state name="show_logo">
|
|
<entry>m_blinkTimeEvt.armX(BSP_TICKS_PER_SEC/2U,
|
|
BSP_TICKS_PER_SEC/2U); // every 1/2 sec
|
|
m_screenTimeEvt.armX(BSP_TICKS_PER_SEC*5U, 0U); // in 5 sec
|
|
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();</entry>
|
|
<exit>m_blinkTimeEvt.disarm();
|
|
m_screenTimeEvt.disarm();</exit>
|
|
<!--${AOs::Tunnel::SM::active::show_logo::SCREEN_TIMEOUT}-->
|
|
<tran trig="SCREEN_TIMEOUT" target="../../3">
|
|
<tran_glyph conn="4,26,3,1,24,7,-2">
|
|
<action box="0,-2,13,2"/>
|
|
</tran_glyph>
|
|
</tran>
|
|
<!--${AOs::Tunnel::SM::active::show_logo::BLINK_TIMEOUT}-->
|
|
<tran trig="BLINK_TIMEOUT">
|
|
<action>m_blink_ctr ^= 1U; // toggle the blink counter</action>
|
|
<!--${AOs::Tunnel::SM::active::show_logo::BLINK_TIMEOUT::[m_blink_ctr==0U]}-->
|
|
<choice>
|
|
<guard>m_blink_ctr == 0U</guard>
|
|
<action>BSP_paintString(24U + 8U*6U, (GAME_TUNNEL_HEIGHT / 2U) - 8U, "LeAps");
|
|
BSP_updateScreen();</action>
|
|
<choice_glyph conn="18,23,4,-1,-3,7">
|
|
<action box="1,-3,15,2"/>
|
|
</choice_glyph>
|
|
</choice>
|
|
<!--${AOs::Tunnel::SM::active::show_logo::BLINK_TIMEOUT::[else]}-->
|
|
<choice>
|
|
<guard>else</guard>
|
|
<action>BSP_paintString(24U + 8U*6U, (GAME_TUNNEL_HEIGHT / 2U) - 8U, "LeaPs");
|
|
BSP_updateScreen();</action>
|
|
<choice_glyph conn="18,23,5,-1,7">
|
|
<action box="1,0,6,2"/>
|
|
</choice_glyph>
|
|
</choice>
|
|
<tran_glyph conn="4,23,3,-1,14">
|
|
<action box="0,-2,12,2"/>
|
|
</tran_glyph>
|
|
</tran>
|
|
<state_glyph node="4,15,22,14">
|
|
<entry box="1,2,5,2"/>
|
|
<exit box="1,4,5,2"/>
|
|
</state_glyph>
|
|
</state>
|
|
<!--${AOs::Tunnel::SM::active::demo}-->
|
|
<state name="demo">
|
|
<entry>m_last_mine_x = 0U; // last mine at right edge of the tunnel
|
|
m_last_mine_y = 0U;
|
|
// set the tunnel properties...
|
|
m_wall_thickness_top = 0U;
|
|
m_wall_thickness_bottom = 0U;
|
|
m_wall_gap = GAME_WALLS_GAP_Y;
|
|
|
|
BSP_clearWalls(); // erase the tunnel walls
|
|
|
|
m_blinkTimeEvt.armX(BSP_TICKS_PER_SEC/2U,
|
|
BSP_TICKS_PER_SEC/2U); // every 1/2 sec
|
|
m_screenTimeEvt.armX(BSP_TICKS_PER_SEC*20U, 0U); // in 20 sec
|
|
|
|
m_blink_ctr = 0U; // init the blink counter</entry>
|
|
<exit>m_blinkTimeEvt.disarm();
|
|
m_screenTimeEvt.disarm();</exit>
|
|
<!--${AOs::Tunnel::SM::active::demo::BLINK_TIMEOUT}-->
|
|
<tran trig="BLINK_TIMEOUT">
|
|
<action>m_blink_ctr ^= 1U; /* toggle the blink cunter */</action>
|
|
<tran_glyph conn="4,43,3,-1,14">
|
|
<action box="0,-2,13,2"/>
|
|
</tran_glyph>
|
|
</tran>
|
|
<!--${AOs::Tunnel::SM::active::demo::SCREEN_TIMEOUT}-->
|
|
<tran trig="SCREEN_TIMEOUT" target="../../6">
|
|
<tran_glyph conn="4,46,3,3,28">
|
|
<action box="0,-2,13,2"/>
|
|
</tran_glyph>
|
|
</tran>
|
|
<!--${AOs::Tunnel::SM::active::demo::TIME_TICK}-->
|
|
<tran trig="TIME_TICK">
|
|
<action>advance();
|
|
if (m_blink_ctr != 0U) {
|
|
// add the text into the frame buffer
|
|
BSP_paintString((GAME_TUNNEL_WIDTH - 10U*6U)/2U,
|
|
(GAME_TUNNEL_HEIGHT - 4U)/2U,
|
|
"Press BTN0");
|
|
}
|
|
BSP_updateScreen();</action>
|
|
<tran_glyph conn="4,40,3,-1,14">
|
|
<action box="0,-2,12,2"/>
|
|
</tran_glyph>
|
|
</tran>
|
|
<!--${AOs::Tunnel::SM::active::demo::PLAYER_TRIGGER}-->
|
|
<tran trig="PLAYER_TRIGGER" target="../../4">
|
|
<tran_glyph conn="4,49,3,1,24,6,-2">
|
|
<action box="0,-2,13,2"/>
|
|
</tran_glyph>
|
|
</tran>
|
|
<state_glyph node="4,31,22,20">
|
|
<entry box="1,2,6,2"/>
|
|
<exit box="1,4,5,2"/>
|
|
</state_glyph>
|
|
</state>
|
|
<!--${AOs::Tunnel::SM::active::playing}-->
|
|
<state name="playing">
|
|
<entry>static QP::QEvt const takeoff = QEVT_INITIALIZER(TAKE_OFF_SIG);
|
|
m_wall_gap = GAME_WALLS_GAP_Y;
|
|
AO_Ship->POST(&takeoff, this); // post the TAKEOFF sig</entry>
|
|
<exit>QP::QEvt recycle;
|
|
recycle.sig = MINE_RECYCLE_SIG;
|
|
dispatchToAllMines(&recycle); // recycle all Mines</exit>
|
|
<!--${AOs::Tunnel::SM::active::playing::TIME_TICK}-->
|
|
<tran trig="TIME_TICK">
|
|
<action>// render this frame on the display
|
|
BSP_updateScreen();
|
|
advance();
|
|
plantMine();
|
|
dispatchToAllMines(e);</action>
|
|
<tran_glyph conn="4,62,3,-1,14">
|
|
<action box="0,-2,9,2"/>
|
|
</tran_glyph>
|
|
</tran>
|
|
<!--${AOs::Tunnel::SM::active::playing::SHIP_IMG}-->
|
|
<tran trig="SHIP_IMG">
|
|
<action>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?
|
|
if (BSP_isWallHit(bmp, x, y)) {
|
|
static QP::QEvt const hit = QEVT_INITIALIZER(HIT_WALL_SIG);
|
|
AO_Ship->POST(&hit, this);
|
|
}
|
|
BSP_paintBitmap(x, y, bmp);
|
|
dispatchToAllMines(e); // let Mines check for hits</action>
|
|
<tran_glyph conn="4,65,3,-1,14">
|
|
<action box="0,-2,9,2"/>
|
|
</tran_glyph>
|
|
</tran>
|
|
<!--${AOs::Tunnel::SM::active::playing::MISSILE_IMG}-->
|
|
<tran trig="MISSILE_IMG">
|
|
<action>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?
|
|
if (BSP_isWallHit(bmp, x, y)) {
|
|
static QP::QEvt const hit = QEVT_INITIALIZER(HIT_WALL_SIG);
|
|
AO_Missile->POST(&hit, this);
|
|
}
|
|
BSP_paintBitmap(x, y, bmp);
|
|
dispatchToAllMines(e); // let Mines check for hits</action>
|
|
<tran_glyph conn="4,68,3,-1,14">
|
|
<action box="0,-2,12,2"/>
|
|
</tran_glyph>
|
|
</tran>
|
|
<!--${AOs::Tunnel::SM::active::playing::MINE_IMG}-->
|
|
<tran trig="MINE_IMG">
|
|
<action>BSP_paintBitmap(Q_EVT_CAST(ObjectImageEvt)->x,
|
|
Q_EVT_CAST(ObjectImageEvt)->y,
|
|
Q_EVT_CAST(ObjectImageEvt)->bmp);</action>
|
|
<tran_glyph conn="4,71,3,-1,14">
|
|
<action box="0,-2,9,2"/>
|
|
</tran_glyph>
|
|
</tran>
|
|
<!--${AOs::Tunnel::SM::active::playing::EXPLOSION}-->
|
|
<tran trig="EXPLOSION">
|
|
<action>BSP_paintBitmap(Q_EVT_CAST(ObjectImageEvt)->x,
|
|
Q_EVT_CAST(ObjectImageEvt)->y,
|
|
Q_EVT_CAST(ObjectImageEvt)->bmp);</action>
|
|
<tran_glyph conn="4,74,3,-1,14">
|
|
<action box="0,-2,11,2"/>
|
|
</tran_glyph>
|
|
</tran>
|
|
<!--${AOs::Tunnel::SM::active::playing::SCORE}-->
|
|
<tran trig="SCORE">
|
|
<action>BSP_updateScore(Q_EVT_CAST(ScoreEvt)->score);
|
|
// increase difficulty of the game:
|
|
// the tunnel gets narrower as the score goes up
|
|
//
|
|
m_wall_gap = (uint8_t)(GAME_WALLS_GAP_Y
|
|
- Q_EVT_CAST(ScoreEvt)->score/100U);
|
|
if (m_wall_gap < GAME_WALLS_MIN_GAP_Y) {
|
|
m_wall_gap = GAME_WALLS_MIN_GAP_Y;
|
|
}</action>
|
|
<tran_glyph conn="4,77,3,-1,14">
|
|
<action box="0,-2,6,2"/>
|
|
</tran_glyph>
|
|
</tran>
|
|
<!--${AOs::Tunnel::SM::active::playing::GAME_OVER}-->
|
|
<tran trig="GAME_OVER" target="../../5">
|
|
<action>BSP_clearWalls();
|
|
BSP_updateScore(Q_EVT_CAST(ScoreEvt)->score);
|
|
BSP_updateScreen();</action>
|
|
<tran_glyph conn="4,80,3,3,26,-10,2">
|
|
<action box="0,-2,10,2"/>
|
|
</tran_glyph>
|
|
</tran>
|
|
<state_glyph node="4,53,22,29">
|
|
<entry box="1,2,6,2"/>
|
|
<exit box="1,4,5,2"/>
|
|
</state_glyph>
|
|
</state>
|
|
<!--${AOs::Tunnel::SM::active::game_over}-->
|
|
<state name="game_over">
|
|
<entry>m_blinkTimeEvt.armX(BSP_TICKS_PER_SEC/2U,
|
|
BSP_TICKS_PER_SEC/2U); // every 1/2 sec
|
|
m_screenTimeEvt.armX(BSP_TICKS_PER_SEC*5U, 0U); // in 5 se
|
|
m_blink_ctr = 0U;
|
|
BSP_paintString((GAME_TUNNEL_WIDTH - 6U * 9U) / 2U,
|
|
(GAME_TUNNEL_HEIGHT / 2U) - 4U,
|
|
"Game Over");
|
|
BSP_updateScreen();</entry>
|
|
<exit>m_blinkTimeEvt.disarm();
|
|
m_screenTimeEvt.disarm();
|
|
BSP_updateScore(0U); // update the score on the display</exit>
|
|
<!--${AOs::Tunnel::SM::active::game_over::BLINK_TIMEOUT}-->
|
|
<tran trig="BLINK_TIMEOUT">
|
|
<action>m_blink_ctr ^= 1U; // toggle the blink counter
|
|
BSP_paintString((GAME_TUNNEL_WIDTH - 6U*9U) / 2U,
|
|
(GAME_TUNNEL_HEIGHT / 2U) - 4U,
|
|
((m_blink_ctr == 0U)
|
|
? "Game Over"
|
|
: " "));
|
|
BSP_updateScreen();</action>
|
|
<tran_glyph conn="32,80,3,-1,15">
|
|
<action box="0,-2,12,2"/>
|
|
</tran_glyph>
|
|
</tran>
|
|
<!--${AOs::Tunnel::SM::active::game_over::SCREEN_TIMEOUT}-->
|
|
<tran trig="SCREEN_TIMEOUT" target="../../3">
|
|
<tran_glyph conn="32,77,3,1,28,-11,-30,-18,-4">
|
|
<action box="0,-2,14,2"/>
|
|
</tran_glyph>
|
|
</tran>
|
|
<state_glyph node="32,68,26,14">
|
|
<entry box="1,2,6,2"/>
|
|
<exit box="1,4,5,2"/>
|
|
</state_glyph>
|
|
</state>
|
|
<!--${AOs::Tunnel::SM::active::screen_saver}-->
|
|
<state name="screen_saver">
|
|
<!--${AOs::Tunnel::SM::active::screen_saver::initial}-->
|
|
<initial target="../2">
|
|
<initial_glyph conn="34,35,5,1,20,7,-2">
|
|
<action box="1,-2,6,2"/>
|
|
</initial_glyph>
|
|
</initial>
|
|
<!--${AOs::Tunnel::SM::active::screen_saver::PLAYER_TRIGGER}-->
|
|
<tran trig="PLAYER_TRIGGER" target="../../3">
|
|
<tran_glyph conn="32,38,3,1,28,-8,-30,5,-4">
|
|
<action box="0,-2,13,2"/>
|
|
</tran_glyph>
|
|
</tran>
|
|
<!--${AOs::Tunnel::SM::active::screen_saver::screen_saver_hide}-->
|
|
<state name="screen_saver_hide">
|
|
<entry>BSP_displayOff(); // power down the display
|
|
m_screenTimeEvt.armX(BSP_TICKS_PER_SEC*3U, 0U); // in 3 sec</entry>
|
|
<exit>m_screenTimeEvt.disarm();
|
|
BSP_displayOn(); // power up the display</exit>
|
|
<!--${AOs::Tunnel::SM::active::screen_saver::screen_saver_hid~::SCREEN_TIMEOUT}-->
|
|
<tran trig="SCREEN_TIMEOUT" target="../../3">
|
|
<tran_glyph conn="34,48,3,1,20,6,-2">
|
|
<action box="0,-2,13,2"/>
|
|
</tran_glyph>
|
|
</tran>
|
|
<state_glyph node="34,40,18,10">
|
|
<entry box="1,2,5,2"/>
|
|
<exit box="1,4,5,2"/>
|
|
</state_glyph>
|
|
</state>
|
|
<!--${AOs::Tunnel::SM::active::screen_saver::screen_saver_show}-->
|
|
<state name="screen_saver_show">
|
|
<entry>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();
|
|
m_screenTimeEvt.armX(BSP_TICKS_PER_SEC/3U, 0U); // in 1/3 sec</entry>
|
|
<exit>m_screenTimeEvt.disarm();
|
|
BSP_clearFB();
|
|
BSP_updateScreen();</exit>
|
|
<!--${AOs::Tunnel::SM::active::screen_saver::screen_saver_sho~::SCREEN_TIMEOUT}-->
|
|
<tran trig="SCREEN_TIMEOUT" target="../../2">
|
|
<tran_glyph conn="34,60,3,1,22,-15,-4">
|
|
<action box="0,-2,13,2"/>
|
|
</tran_glyph>
|
|
</tran>
|
|
<state_glyph node="34,52,18,10">
|
|
<entry box="1,2,6,2"/>
|
|
<exit box="1,4,5,2"/>
|
|
</state_glyph>
|
|
</state>
|
|
<state_glyph node="32,31,26,33"/>
|
|
</state>
|
|
<state_glyph node="2,4,60,80"/>
|
|
</state>
|
|
<!--${AOs::Tunnel::SM::final}-->
|
|
<state name="final">
|
|
<entry>BSP_clearFB();
|
|
BSP_updateScreen();
|
|
QP::QF::stop(); // stop QF and cleanup</entry>
|
|
<state_glyph node="2,86,24,6">
|
|
<entry box="1,2,6,2"/>
|
|
</state_glyph>
|
|
</state>
|
|
<state_diagram size="68,94"/>
|
|
</statechart>
|
|
</class>
|
|
<!--${AOs::Ship}-->
|
|
<class name="Ship" superclass="qpcpp::QActive">
|
|
<documentation>Ship Active Object</documentation>
|
|
<!--${AOs::Ship::m_x}-->
|
|
<attribute name="m_x" type="uint8_t" visibility="0x02" properties="0x00"/>
|
|
<!--${AOs::Ship::m_y}-->
|
|
<attribute name="m_y" type="uint16_t" visibility="0x02" properties="0x00">
|
|
<documentation>vertical position of the ship in the 8s2 fixed-point notation.</documentation>
|
|
</attribute>
|
|
<!--${AOs::Ship::m_exp_ctr}-->
|
|
<attribute name="m_exp_ctr" type="uint8_t" visibility="0x02" properties="0x00"/>
|
|
<!--${AOs::Ship::m_score}-->
|
|
<attribute name="m_score" type="uint16_t" visibility="0x02" properties="0x00"/>
|
|
<!--${AOs::Ship::Ship}-->
|
|
<operation name="Ship" type="" visibility="0x00" properties="0x00">
|
|
<code> : QActive(&initial),
|
|
m_x(GAME_SHIP_X),
|
|
m_y(GAME_SHIP_Y << 2)</code>
|
|
</operation>
|
|
<!--${AOs::Ship::SM}-->
|
|
<statechart properties="0x02">
|
|
<!--${AOs::Ship::SM::initial}-->
|
|
<initial target="../1">
|
|
<action>subscribe(TIME_TICK_SIG);
|
|
subscribe(PLAYER_TRIGGER_SIG);
|
|
|
|
// local signals...
|
|
QS_SIG_DICTIONARY(PLAYER_SHIP_MOVE_SIG, this);
|
|
QS_SIG_DICTIONARY(TAKE_OFF_SIG, this);
|
|
QS_SIG_DICTIONARY(HIT_WALL_SIG, this);
|
|
QS_SIG_DICTIONARY(HIT_MINE_SIG, this);
|
|
QS_SIG_DICTIONARY(DESTROYED_MINE_SIG, this);
|
|
|
|
(void)e; // unused parameter</action>
|
|
<initial_glyph conn="3,2,5,1,36,4,-3">
|
|
<action box="1,-2,6,2"/>
|
|
</initial_glyph>
|
|
</initial>
|
|
<!--${AOs::Ship::SM::active}-->
|
|
<state name="active">
|
|
<!--${AOs::Ship::SM::active::initial}-->
|
|
<initial target="../1">
|
|
<initial_glyph conn="3,8,5,1,29,4,-2">
|
|
<action box="1,-2,6,2"/>
|
|
</initial_glyph>
|
|
</initial>
|
|
<!--${AOs::Ship::SM::active::parked}-->
|
|
<state name="parked">
|
|
<!--${AOs::Ship::SM::active::parked::TAKE_OFF}-->
|
|
<tran trig="TAKE_OFF" target="../../2">
|
|
<tran_glyph conn="4,16,3,1,28,6,-2">
|
|
<action box="0,-2,8,2"/>
|
|
</tran_glyph>
|
|
</tran>
|
|
<state_glyph node="4,10,26,8"/>
|
|
</state>
|
|
<!--${AOs::Ship::SM::active::flying}-->
|
|
<state name="flying">
|
|
<entry>m_score = 0U; // reset the score
|
|
ScoreEvt *sev = Q_NEW(ScoreEvt, SCORE_SIG);
|
|
sev->score = m_score;
|
|
AO_Tunnel->POST(sev, this);
|
|
|
|
// lauch the ship from the initial position
|
|
m_x = GAME_SHIP_X;
|
|
m_y = (GAME_SHIP_Y << 2);</entry>
|
|
<!--${AOs::Ship::SM::active::flying::TIME_TICK}-->
|
|
<tran trig="TIME_TICK">
|
|
<action>if (BSP_isThrottle()) {
|
|
if (m_y > 0U) {
|
|
m_y -= 1U;
|
|
}
|
|
}
|
|
else {
|
|
if (m_y < (GAME_TUNNEL_HEIGHT << 2)) {
|
|
m_y += 1U;
|
|
}
|
|
}
|
|
|
|
// tell the Tunnel to draw the Ship and test for hits
|
|
ObjectImageEvt *oie = Q_NEW(ObjectImageEvt, SHIP_IMG_SIG);
|
|
oie->x = m_x;
|
|
oie->y = m_y >> 2;
|
|
oie->bmp = SHIP_BMP;
|
|
AO_Tunnel->POST(oie, this);
|
|
|
|
++m_score; // increment the score for surviving another tick
|
|
|
|
if ((m_score % 10U) == 0U) { // is the score "round"?
|
|
ScoreEvt *sev = Q_NEW(ScoreEvt, SCORE_SIG);
|
|
sev->score = m_score;
|
|
AO_Tunnel->POST(sev, this);
|
|
}</action>
|
|
<tran_glyph conn="4,27,3,-1,16">
|
|
<action box="0,-2,9,2"/>
|
|
</tran_glyph>
|
|
</tran>
|
|
<!--${AOs::Ship::SM::active::flying::PLAYER_TRIGGER}-->
|
|
<tran trig="PLAYER_TRIGGER">
|
|
<action>ObjectPosEvt *ope = Q_NEW(ObjectPosEvt, MISSILE_FIRE_SIG);
|
|
ope->x = m_x;
|
|
ope->y = (m_y >> 2) + SHIP_HEIGHT - 1U;
|
|
AO_Missile->POST(ope, this);</action>
|
|
<tran_glyph conn="4,30,3,-1,16">
|
|
<action box="0,-2,13,2"/>
|
|
</tran_glyph>
|
|
</tran>
|
|
<!--${AOs::Ship::SM::active::flying::DESTROYED_MINE}-->
|
|
<tran trig="DESTROYED_MINE">
|
|
<action>m_score += Q_EVT_CAST(ScoreEvt)->score;
|
|
// the score will be sent to the Tunnel by the next TIME_TICK</action>
|
|
<tran_glyph conn="4,33,3,-1,16">
|
|
<action box="0,-2,13,2"/>
|
|
</tran_glyph>
|
|
</tran>
|
|
<!--${AOs::Ship::SM::active::flying::HIT_WALL}-->
|
|
<tran trig="HIT_WALL" target="../../3">
|
|
<tran_glyph conn="4,36,3,1,28,12,-2">
|
|
<action box="0,-2,8,2"/>
|
|
</tran_glyph>
|
|
</tran>
|
|
<!--${AOs::Ship::SM::active::flying::HIT_MINE}-->
|
|
<tran trig="HIT_MINE" target="../../3">
|
|
<tran_glyph conn="4,39,3,1,28,9,-2">
|
|
<action box="0,-2,10,2"/>
|
|
</tran_glyph>
|
|
</tran>
|
|
<state_glyph node="4,20,26,22">
|
|
<entry box="1,2,5,2"/>
|
|
</state_glyph>
|
|
</state>
|
|
<!--${AOs::Ship::SM::active::exploding}-->
|
|
<state name="exploding">
|
|
<entry>m_exp_ctr = 0U;</entry>
|
|
<!--${AOs::Ship::SM::active::exploding::TIME_TICK}-->
|
|
<tran trig="TIME_TICK">
|
|
<!--${AOs::Ship::SM::active::exploding::TIME_TICK::[m_exp_ctr<15U]}-->
|
|
<choice>
|
|
<guard>m_exp_ctr < 15U</guard>
|
|
<action>++m_exp_ctr;
|
|
// tell the Tunnel to draw the current stage of Explosion
|
|
ObjectImageEvt *oie = Q_NEW(ObjectImageEvt, EXPLOSION_SIG);
|
|
oie->bmp = EXPLOSION0_BMP + (m_exp_ctr >> 2);
|
|
oie->x = m_x; // x of explosion
|
|
oie->y = (int8_t)((int)(m_y >> 2) - 4U + SHIP_HEIGHT);
|
|
AO_Tunnel->POST(oie, this);</action>
|
|
<choice_glyph conn="13,52,5,-1,15">
|
|
<action box="1,0,15,2"/>
|
|
</choice_glyph>
|
|
</choice>
|
|
<!--${AOs::Ship::SM::active::exploding::TIME_TICK::[else]}-->
|
|
<choice target="../../../1">
|
|
<guard brief="else"/>
|
|
<action>ScoreEvt *gameOver = Q_NEW(ScoreEvt, GAME_OVER_SIG);
|
|
gameOver->score = m_score;
|
|
AO_Tunnel->POST(gameOver, this);</action>
|
|
<choice_glyph conn="13,52,4,1,4,21,-42,-4">
|
|
<action box="1,4,6,2"/>
|
|
</choice_glyph>
|
|
</choice>
|
|
<tran_glyph conn="4,52,3,-1,9">
|
|
<action box="0,-2,10,2"/>
|
|
</tran_glyph>
|
|
</tran>
|
|
<state_glyph node="4,44,26,14">
|
|
<entry box="1,2,13,4"/>
|
|
</state_glyph>
|
|
</state>
|
|
<state_glyph node="2,4,34,56"/>
|
|
</state>
|
|
<state_diagram size="40,62"/>
|
|
</statechart>
|
|
</class>
|
|
<!--${AOs::Missile}-->
|
|
<class name="Missile" superclass="qpcpp::QActive">
|
|
<documentation>Missile Active Object</documentation>
|
|
<!--${AOs::Missile::m_x}-->
|
|
<attribute name="m_x" type="uint8_t" visibility="0x02" properties="0x00"/>
|
|
<!--${AOs::Missile::m_y}-->
|
|
<attribute name="m_y" type="uint8_t" visibility="0x02" properties="0x00"/>
|
|
<!--${AOs::Missile::m_exp_ctr}-->
|
|
<attribute name="m_exp_ctr" type="uint8_t" visibility="0x02" properties="0x00"/>
|
|
<!--${AOs::Missile::Missile}-->
|
|
<operation name="Missile" type="" visibility="0x00" properties="0x00">
|
|
<code> : QActive(&initial)</code>
|
|
</operation>
|
|
<!--${AOs::Missile::SM}-->
|
|
<statechart properties="0x02">
|
|
<!--${AOs::Missile::SM::initial}-->
|
|
<initial target="../1">
|
|
<action>subscribe( TIME_TICK_SIG);
|
|
|
|
// local signals...
|
|
QS_SIG_DICTIONARY(MISSILE_FIRE_SIG, this);
|
|
QS_SIG_DICTIONARY(HIT_WALL_SIG, this);
|
|
QS_SIG_DICTIONARY(DESTROYED_MINE_SIG, this);
|
|
|
|
(void)e; // unused parameter</action>
|
|
<initial_glyph conn="3,3,5,1,35,4,-2">
|
|
<action box="1,-2,6,2"/>
|
|
</initial_glyph>
|
|
</initial>
|
|
<!--${AOs::Missile::SM::armed}-->
|
|
<state name="armed">
|
|
<!--${AOs::Missile::SM::armed::MISSILE_FIRE}-->
|
|
<tran trig="MISSILE_FIRE" target="../../2">
|
|
<action>m_x = Q_EVT_CAST(ObjectPosEvt)->x;
|
|
m_y = Q_EVT_CAST(ObjectPosEvt)->y;</action>
|
|
<tran_glyph conn="3,11,3,1,35,6,-2">
|
|
<action box="0,-2,11,2"/>
|
|
</tran_glyph>
|
|
</tran>
|
|
<state_glyph node="3,5,33,8"/>
|
|
</state>
|
|
<!--${AOs::Missile::SM::flying}-->
|
|
<state name="flying">
|
|
<!--${AOs::Missile::SM::flying::TIME_TICK}-->
|
|
<tran trig="TIME_TICK">
|
|
<!--${AOs::Missile::SM::flying::TIME_TICK::[m_x+GAME_MISSILE_SPEED_X<GAME_T~}-->
|
|
<choice>
|
|
<guard>m_x + GAME_MISSILE_SPEED_X < GAME_TUNNEL_WIDTH</guard>
|
|
<action brief="...">m_x += GAME_MISSILE_SPEED_X;
|
|
// tell the Tunnel to draw the Missile and test for wall hits
|
|
ObjectImageEvt *oie = Q_NEW(ObjectImageEvt, MISSILE_IMG_SIG);
|
|
oie->x = m_x;
|
|
oie->y = m_y;
|
|
oie->bmp = MISSILE_BMP;
|
|
AO_Tunnel->POST(oie, this);</action>
|
|
<choice_glyph conn="12,21,5,-1,20">
|
|
<action box="1,0,22,4"/>
|
|
</choice_glyph>
|
|
</choice>
|
|
<!--${AOs::Missile::SM::flying::TIME_TICK::[else]}-->
|
|
<choice target="../../../1">
|
|
<guard brief="else"/>
|
|
<choice_glyph conn="12,21,4,1,5,28,-17,-4">
|
|
<action box="1,5,6,2"/>
|
|
</choice_glyph>
|
|
</choice>
|
|
<tran_glyph conn="3,21,3,-1,9">
|
|
<action box="0,-2,9,2"/>
|
|
</tran_glyph>
|
|
</tran>
|
|
<!--${AOs::Missile::SM::flying::HIT_WALL}-->
|
|
<tran trig="HIT_WALL" target="../../3">
|
|
<tran_glyph conn="3,33,3,1,35,6,-2">
|
|
<action box="0,-2,9,2"/>
|
|
</tran_glyph>
|
|
</tran>
|
|
<!--${AOs::Missile::SM::flying::DESTROYED_MINE}-->
|
|
<tran trig="DESTROYED_MINE" target="../../1">
|
|
<action>AO_Ship->POST(e, this);</action>
|
|
<tran_glyph conn="3,30,3,1,39,-21,-6">
|
|
<action box="0,-2,15,2"/>
|
|
</tran_glyph>
|
|
</tran>
|
|
<state_glyph node="3,15,33,20"/>
|
|
</state>
|
|
<!--${AOs::Missile::SM::exploding}-->
|
|
<state name="exploding">
|
|
<entry>m_exp_ctr = 0U;</entry>
|
|
<!--${AOs::Missile::SM::exploding::TIME_TICK}-->
|
|
<tran trig="TIME_TICK">
|
|
<!--${AOs::Missile::SM::exploding::TIME_TICK::[(m_x>=GAME_SPEED_X)&&(m_exp_ctr~}-->
|
|
<choice>
|
|
<guard>(m_x >= GAME_SPEED_X) && (m_exp_ctr < 15U)</guard>
|
|
<action brief="...">++m_exp_ctr; // advance the explosion counter
|
|
m_x -= GAME_SPEED_X; // move the explosion by one step
|
|
|
|
// tell the Tunnel to render the current stage of Explosion
|
|
ObjectImageEvt *oie = Q_NEW(ObjectImageEvt, EXPLOSION_SIG);
|
|
oie->x = m_x + 3U; // x-pos of explosion
|
|
oie->y = (int8_t)((int)m_y - 4U); // y-pos
|
|
oie->bmp = EXPLOSION0_BMP + (m_exp_ctr >> 2);
|
|
AO_Tunnel->POST(oie, this);</action>
|
|
<choice_glyph conn="12,46,5,-1,20">
|
|
<action box="1,0,19,4"/>
|
|
</choice_glyph>
|
|
</choice>
|
|
<!--${AOs::Missile::SM::exploding::TIME_TICK::[else]}-->
|
|
<choice target="../../../1">
|
|
<guard brief="else"/>
|
|
<choice_glyph conn="12,46,4,1,5,32,-42,-8">
|
|
<action box="1,5,7,2"/>
|
|
</choice_glyph>
|
|
</choice>
|
|
<tran_glyph conn="3,46,3,-1,9">
|
|
<action box="0,-2,8,2"/>
|
|
</tran_glyph>
|
|
</tran>
|
|
<state_glyph node="3,37,33,16">
|
|
<entry box="1,2,14,4"/>
|
|
</state_glyph>
|
|
</state>
|
|
<state_diagram size="46,55"/>
|
|
</statechart>
|
|
</class>
|
|
<!--${AOs::Mine1}-->
|
|
<class name="Mine1" superclass="qpcpp::QHsm">
|
|
<documentation>The Mine1 orthogonal component</documentation>
|
|
<!--${AOs::Mine1::m_x}-->
|
|
<attribute name="m_x" type="uint8_t" visibility="0x02" properties="0x00"/>
|
|
<!--${AOs::Mine1::m_y}-->
|
|
<attribute name="m_y" type="uint8_t" visibility="0x02" properties="0x00"/>
|
|
<!--${AOs::Mine1::m_exp_ctr}-->
|
|
<attribute name="m_exp_ctr" type="uint8_t" visibility="0x02" properties="0x00"/>
|
|
<!--${AOs::Mine1::Mine1}-->
|
|
<operation name="Mine1" type="" visibility="0x00" properties="0x02">
|
|
<code> : QHsm(&initial)</code>
|
|
</operation>
|
|
<!--${AOs::Mine1::SM}-->
|
|
<statechart properties="0x02">
|
|
<!--${AOs::Mine1::SM::initial}-->
|
|
<initial target="../1">
|
|
<action>static bool dict_sent = false;
|
|
if (!dict_sent) {
|
|
dict_sent = true;
|
|
|
|
// object dictionaries for Mine1 pool...
|
|
QS_OBJ_DICTIONARY(&l_mine1[0]);
|
|
QS_OBJ_DICTIONARY(&l_mine1[1]);
|
|
QS_OBJ_DICTIONARY(&l_mine1[2]);
|
|
QS_OBJ_DICTIONARY(&l_mine1[3]);
|
|
QS_OBJ_DICTIONARY(&l_mine1[4]);
|
|
|
|
// function dictionaries for Mine1 SM
|
|
QS_FUN_DICTIONARY(&Mine1::initial);
|
|
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, this);
|
|
QS_SIG_DICTIONARY(MINE_DISABLED_SIG, this);
|
|
QS_SIG_DICTIONARY(MINE_RECYCLE_SIG, this);
|
|
QS_SIG_DICTIONARY(SHIP_IMG_SIG, this);
|
|
QS_SIG_DICTIONARY(MISSILE_IMG_SIG, this);
|
|
|
|
(void)e; // unused parameter</action>
|
|
<initial_glyph conn="2,2,5,1,31,4,-2">
|
|
<action box="0,-2,11,2"/>
|
|
</initial_glyph>
|
|
</initial>
|
|
<!--${AOs::Mine1::SM::unused}-->
|
|
<state name="unused">
|
|
<!--${AOs::Mine1::SM::unused::MINE_PLANT}-->
|
|
<tran trig="MINE_PLANT" target="../../2/2">
|
|
<action>m_x = Q_EVT_CAST(ObjectPosEvt)->x;
|
|
m_y = Q_EVT_CAST(ObjectPosEvt)->y;</action>
|
|
<tran_glyph conn="2,10,3,1,43,16,-8">
|
|
<action box="0,-2,10,2"/>
|
|
</tran_glyph>
|
|
</tran>
|
|
<state_glyph node="2,4,29,8"/>
|
|
</state>
|
|
<!--${AOs::Mine1::SM::used}-->
|
|
<state name="used">
|
|
<exit brief="...">// tell the Tunnel that this mine is becoming disabled
|
|
MineEvt *mev = Q_NEW(MineEvt, MINE_DISABLED_SIG);
|
|
mev->id = MINE_ID(this);
|
|
AO_Tunnel->POST(mev, this);</exit>
|
|
<!--${AOs::Mine1::SM::used::MINE_RECYCLE}-->
|
|
<tran trig="MINE_RECYCLE" target="../../1">
|
|
<tran_glyph conn="2,21,3,1,41,-13,-12">
|
|
<action box="0,-2,11,2"/>
|
|
</tran_glyph>
|
|
</tran>
|
|
<!--${AOs::Mine1::SM::used::exploding}-->
|
|
<state name="exploding">
|
|
<entry>m_exp_ctr = 0U;</entry>
|
|
<!--${AOs::Mine1::SM::used::exploding::TIME_TICK}-->
|
|
<tran trig="TIME_TICK">
|
|
<!--${AOs::Mine1::SM::used::exploding::TIME_TICK::[stillonscreen?]}-->
|
|
<choice>
|
|
<guard brief="still on screen?">(m_x >= GAME_SPEED_X) && (m_exp_ctr < 15)</guard>
|
|
<action>++m_exp_ctr; // advance the explosion counter
|
|
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 = m_x + 1U; // x of explosion
|
|
oie->y = (int8_t)((int)m_y - 4 + 2); // y of explosion
|
|
oie->bmp = EXPLOSION0_BMP + (m_exp_ctr >> 2);
|
|
AO_Tunnel->POST(oie, this);</action>
|
|
<choice_glyph conn="14,57,5,-1,21">
|
|
<action box="1,0,20,2"/>
|
|
</choice_glyph>
|
|
</choice>
|
|
<!--${AOs::Mine1::SM::used::exploding::TIME_TICK::[else]}-->
|
|
<choice target="../../../../1">
|
|
<guard brief="else"/>
|
|
<choice_glyph conn="14,57,4,1,5,37,-54,-20">
|
|
<action box="1,5,6,2"/>
|
|
</choice_glyph>
|
|
</choice>
|
|
<tran_glyph conn="4,57,3,-1,10">
|
|
<action box="0,-2,9,2"/>
|
|
</tran_glyph>
|
|
</tran>
|
|
<state_glyph node="4,50,33,14">
|
|
<entry box="1,2,5,2"/>
|
|
</state_glyph>
|
|
</state>
|
|
<!--${AOs::Mine1::SM::used::planted}-->
|
|
<state name="planted">
|
|
<!--${AOs::Mine1::SM::used::planted::TIME_TICK}-->
|
|
<tran trig="TIME_TICK">
|
|
<!--${AOs::Mine1::SM::used::planted::TIME_TICK::[m_x>=GAME_SPEED_X]}-->
|
|
<choice>
|
|
<guard>m_x >= GAME_SPEED_X</guard>
|
|
<action>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 = m_x;
|
|
oie->y = m_y;
|
|
oie->bmp = MINE1_BMP;
|
|
AO_Tunnel->POST(oie, this);</action>
|
|
<choice_glyph conn="15,30,5,-1,20">
|
|
<action box="1,0,20,2"/>
|
|
</choice_glyph>
|
|
</choice>
|
|
<!--${AOs::Mine1::SM::used::planted::TIME_TICK::[else]}-->
|
|
<choice target="../../../../1">
|
|
<guard brief="else"/>
|
|
<choice_glyph conn="15,30,4,1,4,32,-26,-16">
|
|
<action box="1,4,6,2"/>
|
|
</choice_glyph>
|
|
</choice>
|
|
<tran_glyph conn="4,30,3,-1,11">
|
|
<action box="0,-2,10,2"/>
|
|
</tran_glyph>
|
|
</tran>
|
|
<!--${AOs::Mine1::SM::used::planted::SHIP_IMG}-->
|
|
<tran trig="SHIP_IMG">
|
|
<action>uint8_t x = Q_EVT_CAST(ObjectImageEvt)->x;
|
|
uint8_t y = Q_EVT_CAST(ObjectImageEvt)->y;
|
|
uint8_t bmp = Q_EVT_CAST(ObjectImageEvt)->bmp;</action>
|
|
<!--${AOs::Mine1::SM::used::planted::SHIP_IMG::[collisionwithMINE1_BMP?]}-->
|
|
<choice target="../../../../1">
|
|
<guard brief="collision with MINE1_BMP?">BSP_doBitmapsOverlap(MINE1_BMP, m_x, m_y, bmp, x, y)</guard>
|
|
<action brief="...">static MineEvt const mine1_hit(HIT_MINE_SIG, 1U);
|
|
AO_Ship->POST(&mine1_hit, this);
|
|
// go straight to 'disabled' and let the Ship do
|
|
// the exploding</action>
|
|
<choice_glyph conn="15,37,5,1,34,-29,-18">
|
|
<action box="1,0,22,4"/>
|
|
</choice_glyph>
|
|
</choice>
|
|
<tran_glyph conn="4,37,3,-1,11">
|
|
<action box="0,-2,8,2"/>
|
|
</tran_glyph>
|
|
</tran>
|
|
<!--${AOs::Mine1::SM::used::planted::MISSILE_IMG}-->
|
|
<tran trig="MISSILE_IMG">
|
|
<action>uint8_t x = Q_EVT_CAST(ObjectImageEvt)->x;
|
|
uint8_t y = Q_EVT_CAST(ObjectImageEvt)->y;
|
|
uint8_t bmp = Q_EVT_CAST(ObjectImageEvt)->bmp;</action>
|
|
<!--${AOs::Mine1::SM::used::planted::MISSILE_IMG::[collisionwithMINE1_BMP?]}-->
|
|
<choice target="../../../1">
|
|
<guard brief="collision with MINE1_BMP?">BSP_doBitmapsOverlap(MINE1_BMP, m_x, m_y, bmp, x, y)</guard>
|
|
<action brief="...">static ScoreEvt const mine1_destroyed(DESTROYED_MINE_SIG, 25U);
|
|
AO_Missile->POST(&mine1_destroyed, this);</action>
|
|
<choice_glyph conn="15,43,5,1,24,9,-2">
|
|
<action box="1,0,22,4"/>
|
|
</choice_glyph>
|
|
</choice>
|
|
<tran_glyph conn="4,43,3,-1,11">
|
|
<action box="0,-2,11,2"/>
|
|
</tran_glyph>
|
|
</tran>
|
|
<state_glyph node="4,24,33,24"/>
|
|
</state>
|
|
<state_glyph node="2,14,39,52">
|
|
<exit box="1,2,5,2"/>
|
|
</state_glyph>
|
|
</state>
|
|
<state_diagram size="53,68"/>
|
|
</statechart>
|
|
</class>
|
|
<!--${AOs::Mine2}-->
|
|
<class name="Mine2" superclass="qpcpp::QHsm">
|
|
<documentation>The Mine2 orthogonal component</documentation>
|
|
<!--${AOs::Mine2::m_x}-->
|
|
<attribute name="m_x" type="uint8_t" visibility="0x02" properties="0x00"/>
|
|
<!--${AOs::Mine2::m_y}-->
|
|
<attribute name="m_y" type="uint8_t" visibility="0x02" properties="0x00"/>
|
|
<!--${AOs::Mine2::m_exp_ctr}-->
|
|
<attribute name="m_exp_ctr" type="uint8_t" visibility="0x02" properties="0x00"/>
|
|
<!--${AOs::Mine2::Mine2}-->
|
|
<operation name="Mine2" type="" visibility="0x00" properties="0x02">
|
|
<code> : QHsm(&initial)</code>
|
|
</operation>
|
|
<!--${AOs::Mine2::SM}-->
|
|
<statechart properties="0x02">
|
|
<!--${AOs::Mine2::SM::initial}-->
|
|
<initial target="../1">
|
|
<action>static bool dict_sent = false;
|
|
if (!dict_sent) {
|
|
dict_sent = true;
|
|
// object dictionaries for Mine2 pool...
|
|
QS_OBJ_DICTIONARY(&l_mine2[0]);
|
|
QS_OBJ_DICTIONARY(&l_mine2[1]);
|
|
QS_OBJ_DICTIONARY(&l_mine2[2]);
|
|
QS_OBJ_DICTIONARY(&l_mine2[3]);
|
|
QS_OBJ_DICTIONARY(&l_mine2[4]);
|
|
|
|
// function dictionaries for Mine2 SM...
|
|
QS_FUN_DICTIONARY(&Mine2::initial);
|
|
QS_FUN_DICTIONARY(&Mine2::unused);
|
|
QS_FUN_DICTIONARY(&Mine2::used);
|
|
QS_FUN_DICTIONARY(&Mine2::planted);
|
|
QS_FUN_DICTIONARY(&Mine2::exploding);
|
|
}
|
|
// local signals...
|
|
QS_SIG_DICTIONARY(MINE_PLANT_SIG, this);
|
|
QS_SIG_DICTIONARY(MINE_DISABLED_SIG, this);
|
|
QS_SIG_DICTIONARY(MINE_RECYCLE_SIG, this);
|
|
QS_SIG_DICTIONARY(SHIP_IMG_SIG, this);
|
|
QS_SIG_DICTIONARY(MISSILE_IMG_SIG, this);
|
|
|
|
(void)e; // unused parameter</action>
|
|
<initial_glyph conn="2,2,5,1,31,4,-2">
|
|
<action box="0,-2,11,2"/>
|
|
</initial_glyph>
|
|
</initial>
|
|
<!--${AOs::Mine2::SM::unused}-->
|
|
<state name="unused">
|
|
<!--${AOs::Mine2::SM::unused::MINE_PLANT}-->
|
|
<tran trig="MINE_PLANT" target="../../2/2">
|
|
<action>m_x = Q_EVT_CAST(ObjectPosEvt)->x;
|
|
m_y = Q_EVT_CAST(ObjectPosEvt)->y;</action>
|
|
<tran_glyph conn="2,10,3,1,43,16,-8">
|
|
<action box="0,-2,10,2"/>
|
|
</tran_glyph>
|
|
</tran>
|
|
<state_glyph node="2,4,29,8"/>
|
|
</state>
|
|
<!--${AOs::Mine2::SM::used}-->
|
|
<state name="used">
|
|
<exit brief="...">// tell the Tunnel that this mine is becoming disabled
|
|
MineEvt *mev = Q_NEW(MineEvt, MINE_DISABLED_SIG);
|
|
mev->id = MINE_ID(this);
|
|
AO_Tunnel->POST(mev, this);</exit>
|
|
<!--${AOs::Mine2::SM::used::MINE_RECYCLE}-->
|
|
<tran trig="MINE_RECYCLE" target="../../1">
|
|
<tran_glyph conn="2,21,3,1,41,-13,-12">
|
|
<action box="0,-2,11,2"/>
|
|
</tran_glyph>
|
|
</tran>
|
|
<!--${AOs::Mine2::SM::used::exploding}-->
|
|
<state name="exploding">
|
|
<entry>m_exp_ctr = 0U;</entry>
|
|
<!--${AOs::Mine2::SM::used::exploding::TIME_TICK}-->
|
|
<tran trig="TIME_TICK">
|
|
<!--${AOs::Mine2::SM::used::exploding::TIME_TICK::[stillonscreen?]}-->
|
|
<choice>
|
|
<guard brief="still on screen?">(m_x >= GAME_SPEED_X) && (m_exp_ctr < 15)</guard>
|
|
<action>++m_exp_ctr; // advance the explosion counter
|
|
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 = m_x + 1U; // x of explosion
|
|
oie->y = (int8_t)((int)m_y - 4 + 2); // y of explosion
|
|
oie->bmp = EXPLOSION0_BMP + (m_exp_ctr >> 2);
|
|
AO_Tunnel->POST(oie, this);</action>
|
|
<choice_glyph conn="14,57,5,-1,21">
|
|
<action box="1,0,20,2"/>
|
|
</choice_glyph>
|
|
</choice>
|
|
<!--${AOs::Mine2::SM::used::exploding::TIME_TICK::[else]}-->
|
|
<choice target="../../../../1">
|
|
<guard brief="else"/>
|
|
<choice_glyph conn="14,57,4,1,5,37,-54,-20">
|
|
<action box="1,5,6,2"/>
|
|
</choice_glyph>
|
|
</choice>
|
|
<tran_glyph conn="4,57,3,-1,10">
|
|
<action box="0,-2,9,2"/>
|
|
</tran_glyph>
|
|
</tran>
|
|
<state_glyph node="4,50,33,14">
|
|
<entry box="1,2,5,2"/>
|
|
</state_glyph>
|
|
</state>
|
|
<!--${AOs::Mine2::SM::used::planted}-->
|
|
<state name="planted">
|
|
<!--${AOs::Mine2::SM::used::planted::TIME_TICK}-->
|
|
<tran trig="TIME_TICK">
|
|
<!--${AOs::Mine2::SM::used::planted::TIME_TICK::[m_x>=GAME_SPEED_X]}-->
|
|
<choice>
|
|
<guard>m_x >= GAME_SPEED_X</guard>
|
|
<action>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 = m_x;
|
|
oie->y = m_y;
|
|
oie->bmp = MINE2_BMP;
|
|
AO_Tunnel->POST(oie, this);</action>
|
|
<choice_glyph conn="15,30,5,-1,20">
|
|
<action box="1,0,20,2"/>
|
|
</choice_glyph>
|
|
</choice>
|
|
<!--${AOs::Mine2::SM::used::planted::TIME_TICK::[else]}-->
|
|
<choice target="../../../../1">
|
|
<guard brief="else"/>
|
|
<choice_glyph conn="15,30,4,1,4,32,-26,-16">
|
|
<action box="1,4,6,2"/>
|
|
</choice_glyph>
|
|
</choice>
|
|
<tran_glyph conn="4,30,3,-1,11">
|
|
<action box="0,-2,10,2"/>
|
|
</tran_glyph>
|
|
</tran>
|
|
<!--${AOs::Mine2::SM::used::planted::SHIP_IMG}-->
|
|
<tran trig="SHIP_IMG">
|
|
<action>uint8_t x = Q_EVT_CAST(ObjectImageEvt)->x;
|
|
uint8_t y = Q_EVT_CAST(ObjectImageEvt)->y;
|
|
uint8_t bmp = Q_EVT_CAST(ObjectImageEvt)->bmp;</action>
|
|
<!--${AOs::Mine2::SM::used::planted::SHIP_IMG::[collisionwithMINE2_BMP?]}-->
|
|
<choice target="../../../../1">
|
|
<guard brief="collision with MINE2_BMP?">BSP_doBitmapsOverlap(MINE2_BMP, m_x, m_y, bmp, x, y)</guard>
|
|
<action brief="...">static MineEvt const mine2_hit(HIT_MINE_SIG, 2U);
|
|
AO_Ship->POST(&mine2_hit, this);
|
|
// go straight to 'disabled' and let the Ship do
|
|
// the exploding</action>
|
|
<choice_glyph conn="15,37,5,1,34,-29,-18">
|
|
<action box="1,0,22,4"/>
|
|
</choice_glyph>
|
|
</choice>
|
|
<tran_glyph conn="4,37,3,-1,11">
|
|
<action box="0,-2,8,2"/>
|
|
</tran_glyph>
|
|
</tran>
|
|
<!--${AOs::Mine2::SM::used::planted::MISSILE_IMG}-->
|
|
<tran trig="MISSILE_IMG">
|
|
<action>uint8_t x = Q_EVT_CAST(ObjectImageEvt)->x;
|
|
uint8_t y = Q_EVT_CAST(ObjectImageEvt)->y;
|
|
uint8_t bmp = Q_EVT_CAST(ObjectImageEvt)->bmp;</action>
|
|
<!--${AOs::Mine2::SM::used::planted::MISSILE_IMG::[collisionwithMINE2_MISSILE_BMP?~}-->
|
|
<choice target="../../../1">
|
|
<guard brief="collision with MINE2_MISSILE_BMP?">BSP_doBitmapsOverlap(MINE2_MISSILE_BMP, m_x, m_y, bmp, x, y)</guard>
|
|
<action brief="...">static ScoreEvt const mine2_destroyed(DESTROYED_MINE_SIG, 45U);
|
|
AO_Missile->POST(&mine2_destroyed, this);</action>
|
|
<choice_glyph conn="15,43,5,1,24,9,-2">
|
|
<action box="1,0,22,4"/>
|
|
</choice_glyph>
|
|
</choice>
|
|
<tran_glyph conn="4,43,3,-1,11">
|
|
<action box="0,-2,11,2"/>
|
|
</tran_glyph>
|
|
</tran>
|
|
<state_glyph node="4,24,33,24"/>
|
|
</state>
|
|
<state_glyph node="2,14,39,52">
|
|
<exit box="1,2,5,2"/>
|
|
</state_glyph>
|
|
</state>
|
|
<state_diagram size="53,68"/>
|
|
</statechart>
|
|
</class>
|
|
<!--${AOs::AO_Tunnel}-->
|
|
<attribute name="AO_Tunnel" type="QP::QActive * const" visibility="0x00" properties="0x00">
|
|
<documentation>// opaque pointer</documentation>
|
|
<code>= &l_tunnel;</code>
|
|
</attribute>
|
|
<!--${AOs::AO_Ship}-->
|
|
<attribute name="AO_Ship" type="QP::QActive * const" visibility="0x00" properties="0x00">
|
|
<documentation>// opaque pointer</documentation>
|
|
<code>= &l_ship;</code>
|
|
</attribute>
|
|
<!--${AOs::AO_Missile}-->
|
|
<attribute name="AO_Missile" type="QP::QActive * const" visibility="0x00" properties="0x00">
|
|
<documentation>// opaque pointer</documentation>
|
|
<code>= &l_missile;</code>
|
|
</attribute>
|
|
</package>
|
|
<!--${.}-->
|
|
<directory name=".">
|
|
<!--${.::game.hpp}-->
|
|
<file name="game.hpp">
|
|
<text>#ifndef GAME_HPP
|
|
#define GAME_HPP
|
|
|
|
namespace GAME {
|
|
|
|
enum GameSignals { // signals used in the game
|
|
TIME_TICK_SIG = QP::Q_USER_SIG, // published from tick ISR
|
|
PLAYER_TRIGGER_SIG, // published by Player (ISR) to trigger the Missile
|
|
PLAYER_QUIT_SIG, // published by Player (ISR) to quit the game
|
|
GAME_OVER_SIG, // published by Ship when it finishes exploding
|
|
|
|
// insert other published signals here ...
|
|
MAX_PUB_SIG, // the last published signal
|
|
|
|
PLAYER_SHIP_MOVE_SIG, // posted by Player (ISR) to the Ship to move it
|
|
|
|
BLINK_TIMEOUT_SIG, // signal for Tunnel's blink timeout event
|
|
SCREEN_TIMEOUT_SIG, // signal for Tunnel's screen timeout event
|
|
|
|
TAKE_OFF_SIG, // from Tunnel to Ship to grant permission to take off
|
|
HIT_WALL_SIG, // from Tunnel to Ship when Ship hits the wall
|
|
HIT_MINE_SIG, // from Mine to Ship or Missile when it hits the mine
|
|
SHIP_IMG_SIG, // from Ship to the Tunnel to draw and check for hits
|
|
MISSILE_IMG_SIG, // from Missile the Tunnel to draw and check for hits
|
|
MINE_IMG_SIG, // sent by Mine to the Tunnel to draw the mine
|
|
MISSILE_FIRE_SIG, // sent by Ship to the Missile to fire
|
|
DESTROYED_MINE_SIG, // from Missile to Ship when Missile destroyed Mine
|
|
EXPLOSION_SIG, // from any exploding object to render the explosion
|
|
MINE_PLANT_SIG, // from Tunnel to the Mine to plant it
|
|
MINE_DISABLED_SIG, // from Mine to Tunnel when it becomes disabled
|
|
MINE_RECYCLE_SIG, // sent by Tunnel to Mine to recycle the mine
|
|
SCORE_SIG, // from Ship to Tunnel to display the score
|
|
|
|
MAX_SIG // the last signal (keep always last)
|
|
};
|
|
|
|
#define GAME_TUNNEL_WIDTH BSP_SCREEN_WIDTH
|
|
#define GAME_TUNNEL_HEIGHT (BSP_SCREEN_HEIGHT - 10U)
|
|
#define GAME_MINES_MAX 5U
|
|
#define GAME_MINES_DIST_MIN 10U
|
|
#define GAME_SPEED_X 1U
|
|
#define GAME_MISSILE_SPEED_X 2U
|
|
#define GAME_SHIP_X 10U
|
|
#define GAME_SHIP_Y (GAME_TUNNEL_HEIGHT / 2U)
|
|
#define GAME_WALLS_GAP_Y 50U
|
|
#define GAME_WALLS_MIN_GAP_Y 20U
|
|
|
|
enum GameBitmapIds {
|
|
SHIP_BMP,
|
|
MISSILE_BMP,
|
|
MINE1_BMP,
|
|
MINE2_BMP,
|
|
MINE2_MISSILE_BMP,
|
|
EXPLOSION0_BMP,
|
|
EXPLOSION1_BMP,
|
|
EXPLOSION2_BMP,
|
|
EXPLOSION3_BMP,
|
|
MAX_BMP
|
|
};
|
|
|
|
// obtain instances of the Mines orthogonal components
|
|
QP::QHsm *Mine1_getInst(uint8_t id);
|
|
QP::QHsm *Mine2_getInst(uint8_t id);
|
|
|
|
} // namespace GAME
|
|
|
|
$declare${Events::ObjectPosEvt}
|
|
$declare${Events::ObjectImageEvt}
|
|
$declare${Events::MineEvt}
|
|
$declare${Events::ScoreEvt}
|
|
|
|
// opaque pointers to active objects in the application
|
|
$declare${AOs::AO_Tunnel}
|
|
$declare${AOs::AO_Ship}
|
|
$declare${AOs::AO_Missile}
|
|
|
|
#endif // GAME_HPP</text>
|
|
</file>
|
|
<!--${.::missile.cpp}-->
|
|
<file name="missile.cpp">
|
|
<text>#include "qpcpp.hpp"
|
|
#include "bsp.hpp"
|
|
#include "game.hpp"
|
|
|
|
//Q_DEFINE_THIS_FILE
|
|
|
|
$declare${AOs::Missile}
|
|
|
|
namespace GAME {
|
|
|
|
// local objects -------------------------------------------------------------
|
|
static Missile l_missile; // the sole instance of the Missile active object
|
|
|
|
} // namespace GAME
|
|
|
|
// Public-scope objects ------------------------------------------------------
|
|
$define${AOs::AO_Missile}
|
|
|
|
// Active object definition --------------------------------------------------
|
|
$define${AOs::Missile}</text>
|
|
</file>
|
|
<!--${.::ship.cpp}-->
|
|
<file name="ship.cpp">
|
|
<text>#include "qpcpp.hpp"
|
|
#include "bsp.hpp"
|
|
#include "game.hpp"
|
|
|
|
//Q_DEFINE_THIS_FILE
|
|
|
|
#define SHIP_WIDTH 5U
|
|
#define SHIP_HEIGHT 3U
|
|
|
|
// encapsulated delcaration of the Ship active object ------------------------
|
|
$declare${AOs::Ship}
|
|
|
|
namespace GAME {
|
|
|
|
// local objects -------------------------------------------------------------
|
|
static Ship l_ship; // the sole instance of the Ship active object
|
|
|
|
} // namespace GAME
|
|
|
|
// Public-scope objects ------------------------------------------------------
|
|
$define${AOs::AO_Ship}
|
|
|
|
// Active object definition --------------------------------------------------
|
|
$define${AOs::Ship}</text>
|
|
</file>
|
|
<!--${.::tunnel.cpp}-->
|
|
<file name="tunnel.cpp">
|
|
<text>#include "qpcpp.hpp"
|
|
#include "bsp.hpp"
|
|
#include "game.hpp"
|
|
#include <string.h> // for memmove() and memcpy()
|
|
|
|
Q_DEFINE_THIS_FILE
|
|
|
|
// declaration of the Tunnel AO ----------------------------------------------
|
|
$declare${AOs::Tunnel}
|
|
|
|
namespace GAME {
|
|
|
|
// local objects -------------------------------------------------------------
|
|
static Tunnel l_tunnel; // the sole instance of the Tunnel active object
|
|
|
|
} // namespace GAME
|
|
|
|
// Public-scope objects ------------------------------------------------------
|
|
$define${AOs::AO_Tunnel}
|
|
|
|
// Active object definition ==================================================
|
|
$define${AOs::Tunnel}</text>
|
|
</file>
|
|
<!--${.::mine1.cpp}-->
|
|
<file name="mine1.cpp">
|
|
<text>#include "qpcpp.hpp"
|
|
#include "bsp.hpp"
|
|
#include "game.hpp"
|
|
|
|
Q_DEFINE_THIS_FILE
|
|
|
|
// encapsulated delcaration of the Mine1 HSM ---------------------------------
|
|
$declare(AOs::Mine1)
|
|
|
|
namespace GAME {
|
|
|
|
// local objects -------------------------------------------------------------
|
|
static Mine1 l_mine1[GAME_MINES_MAX]; // a pool of type-1 mines
|
|
|
|
//............................................................................
|
|
QP::QHsm *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<uint8_t>(me - l_mine1);
|
|
}
|
|
|
|
} // namespace GAME
|
|
|
|
// Mine1 class definition ----------------------------------------------------
|
|
$define(AOs::Mine1)</text>
|
|
</file>
|
|
<!--${.::mine2.cpp}-->
|
|
<file name="mine2.cpp">
|
|
<text>#include "qpcpp.hpp"
|
|
#include "bsp.hpp"
|
|
#include "game.hpp"
|
|
|
|
Q_DEFINE_THIS_FILE
|
|
|
|
// encapsulated delcaration of the Mine1 HSM ---------------------------------
|
|
$declare(AOs::Mine2)
|
|
|
|
namespace GAME {
|
|
|
|
// local objects -------------------------------------------------------------
|
|
static Mine2 l_mine2[GAME_MINES_MAX]; // a pool of type-2 mines
|
|
|
|
//............................................................................
|
|
QP::QHsm *Mine2_getInst(uint8_t id) {
|
|
Q_REQUIRE(id < GAME_MINES_MAX);
|
|
return &l_mine2[id];
|
|
}
|
|
|
|
// helper function to provide the ID of this mine ............................
|
|
static inline uint8_t MINE_ID(Mine2 const * const me) {
|
|
return static_cast<uint8_t>(me - l_mine2);
|
|
}
|
|
|
|
} // namespace GAME
|
|
|
|
// Mine1 class definition ----------------------------------------------------
|
|
$define(AOs::Mine2)</text>
|
|
</file>
|
|
</directory>
|
|
</model>
|