📄 tunnel.c
字号:
switch (e->sig) { case Q_ENTRY_SIG: { /* clear the screen frame buffer */ memset(l_frame, (uint8_t)0, (GAME_SCREEN_WIDTH * GAME_SCREEN_HEIGHT/8)); me->blink_ctr = (uint8_t)0; /* used as index to l_frame[] */ QTimeEvt_postEvery(&me->blinkTimeEvt, (QActive *)me, BSP_TICKS_PER_SEC/5); /* every 1/5 sec */ return Q_HANDLED(); } case Q_EXIT_SIG: { QTimeEvt_disarm(&me->blinkTimeEvt); return Q_HANDLED(); } case BLINK_TIMEOUT_SIG: { uint32_t rnd = random(); l_frame[me->blink_ctr] = (uint8_t)0; /* extinguish last pixel */ /* light up another pixel */ me->blink_ctr = rnd % (GAME_SCREEN_WIDTH * GAME_SCREEN_HEIGHT/8); l_frame[me->blink_ctr] = (uint8_t)(1 << ((rnd >> 8) & 0x7)); BSP_drawBitmap(l_frame, GAME_SCREEN_WIDTH, GAME_SCREEN_HEIGHT); return Q_HANDLED(); } } return Q_SUPER(&Tunnel_screen_saver);}/* helper functions --------------------------------------------------------*//** The bitmap for the "Press Button" text:** xxx.........................xxx........x...x...........* x..x........................x..x.......x...x...........* x..x.x.xx..xx...xxx..xxx....x..x.x..x.xxx.xxx..xx..xxx.* xxx..xx...x..x.x....x.......xxx..x..x..x...x..x..x.x..x* x....x....xxxx..xx...xx.....x..x.x..x..x...x..x..x.x..x* x....x....x.......x....x....x..x.x..x..x...x..x..x.x..x* x....x.....xxx.xxx..xxx.....xxx...xxx...x...x..xx..x..x* .......................................................*/static uint8_t const press_button_bits[] = { 0x7F, 0x09, 0x09, 0x06, 0x00, 0x7C, 0x08, 0x04, 0x04, 0x00, 0x38, 0x54, 0x54, 0x58, 0x00, 0x48, 0x54, 0x54, 0x24, 0x00, 0x48, 0x54, 0x54, 0x24, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x49, 0x49, 0x36, 0x00, 0x3C, 0x40, 0x40, 0x7C, 0x00, 0x04, 0x3F, 0x44, 0x00, 0x04, 0x3F, 0x44, 0x00, 0x38, 0x44, 0x44, 0x38, 0x00, 0x7C, 0x04, 0x04, 0x78};/* bitmap of the Ship:** x....* xxx..* xxxxx*/static uint8_t const ship_bits[] = { 0x07, 0x06, 0x06, 0x04, 0x04};/* bitmap of the Missile:** xxx*/static uint8_t const missile_bits[] = { 0x01, 0x01, 0x01};/* bitmap of the Mine type-1:** .x.* xxx* .x.*/static uint8_t const mine1_bits[] = { 0x02, 0x07, 0x02};/* bitmap of the Mine type-2:** x..x* .xx.* .xx.* x..x*/static uint8_t const mine2_bits[] = { 0x09, 0x06, 0x06, 0x09};/* 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* the following bitmap:** ....* .xx.* .xx.* ....*/static uint8_t const mine2_missile_bits[] = { 0x00, 0x06, 0x06, 0x00};/** The bitmap of the explosion stage 0:** .......* .......* ...x...* ..x.x..* ...x...* .......* .......*/static uint8_t const explosion0_bits[] = { 0x00, 0x00, 0x08, 0x14, 0x08, 0x00, 0x00};/** The bitmap of the explosion stage 1:** .......* .......* ..x.x..* ...x...* ..x.x..* .......* .......*/static uint8_t const explosion1_bits[] = { 0x00, 0x00, 0x14, 0x08, 0x14, 0x00, 0x00};/** The bitmap of the explosion stage 2:** .......* .x...x.* ..x.x..* ...x...* ..x.x..* .x...x.* .......*/static uint8_t const explosion2_bits[] = { 0x00, 0x22, 0x14, 0x08, 0x14, 0x22, 0x00};/** The bitmap of the explosion stage 3:** x..x..x* .x.x.x.* ..x.x..* xx.x.xx* ..x.x..* .x.x.x.* x..x..x*/static uint8_t const explosion3_bits[] = { 0x49, 0x2A, 0x14, 0x6B, 0x14, 0x2A, 0x49};typedef struct BitmapTag { /* the auxiliary structure to hold const bitmaps */ uint8_t const *bits; /* the bits in the bitmap */ uint8_t width; /* the width of the bitmap */} Bitmap;static Bitmap const l_bitmap[MAX_BMP] = { { press_button_bits, Q_DIM(press_button_bits) }, { ship_bits, Q_DIM(ship_bits) }, { missile_bits, Q_DIM(missile_bits) }, { mine1_bits, Q_DIM(mine1_bits) }, { mine2_bits, Q_DIM(mine2_bits) }, { mine2_missile_bits, Q_DIM(mine2_missile_bits) }, { explosion0_bits, Q_DIM(explosion0_bits) }, { explosion1_bits, Q_DIM(explosion1_bits) }, { explosion2_bits, Q_DIM(explosion2_bits) }, { explosion3_bits, Q_DIM(explosion3_bits) }};/*..........................................................................*/uint32_t random(void) { /* a very cheap pseudo-random-number generator */ /* "Super-Duper" Linear Congruential Generator (LCG) * LCG(2^32, 3*7*11*13*23, 0, seed) */ l_rnd = l_rnd * (3*7*11*13*23); return l_rnd >> 8;}/*..........................................................................*/void randomSeed(uint32_t seed) { l_rnd = seed;}/*..........................................................................*/void Tunnel_advance(Tunnel *me) { uint32_t rnd; uint32_t bmp1; /* bimap representing 1 column of the image */ rnd = (random() & 0xFF); /* reduce the top wall thickness 18.75% of the time */ if ((rnd < 48) && (me->wall_thickness_top > 0)) { --me->wall_thickness_top; } /* reduce the bottom wall thickness 18.75% of the time */ if ((rnd > 208) && (me->wall_thickness_bottom > 0)) { --me->wall_thickness_bottom; } rnd = (random() & 0xFF); /* grow the top wall thickness 18.75% of the time */ if ((rnd < 48) && ((GAME_SCREEN_HEIGHT - me->wall_thickness_top - me->wall_thickness_bottom) > me->minimal_gap) && ((me->last_mine_x < (GAME_SCREEN_WIDTH - 5)) || (me->last_mine_y > (me->wall_thickness_top + 1)))) { ++me->wall_thickness_top; } /* grow the bottom wall thickness 18.75% of the time */ if ((rnd > 208) && ((GAME_SCREEN_HEIGHT - me->wall_thickness_top - me->wall_thickness_bottom) > me->minimal_gap) && ((me->last_mine_x < (GAME_SCREEN_WIDTH - 5)) || (me->last_mine_y + 1 < (GAME_SCREEN_HEIGHT - me->wall_thickness_bottom)))) { ++me->wall_thickness_bottom; } /* advance the Tunnel by 1 game step to the left */ memmove(l_walls, l_walls + GAME_SPEED_X, (GAME_SCREEN_WIDTH * GAME_SCREEN_HEIGHT/8) - GAME_SPEED_X); bmp1 = (~(~0 << me->wall_thickness_top)) | (~0 << (GAME_SCREEN_HEIGHT - me->wall_thickness_bottom)); l_walls[GAME_SCREEN_WIDTH - 1] = (uint8_t)bmp1; l_walls[GAME_SCREEN_WIDTH + GAME_SCREEN_WIDTH - 1] = (uint8_t)(bmp1 >> 8); /* copy the Tunnel layer to the main frame buffer */ memcpy(l_frame, l_walls, (GAME_SCREEN_WIDTH * GAME_SCREEN_HEIGHT/8));}/*..........................................................................*/void Tunnel_plantMine(Tunnel *me) { uint32_t rnd = (random() & 0xFF); if (me->last_mine_x > 0) { --me->last_mine_x; /* shift the last Mine 1 position to the left */ } /* last mine far enough? */ if ((me->last_mine_x + GAME_MINES_DIST_MIN < GAME_SCREEN_WIDTH) && (rnd < 8)) /* place the mines only 5% of the time */ { uint8_t n; for (n = 0; n < Q_DIM(me->mines); ++n) { /* look for disabled mines */ if (me->mines[n] == (QHsm *)0) { break; } } if (n < Q_DIM(me->mines)) { /* a disabled Mine found? */ ObjectPosEvt ope; /* event to dispatch to the Mine */ rnd = (random() & 0xFFFF); if ((rnd & 1) == 0) { /* choose the type of the mine */ me->mines[n] = me->mine1_pool[n]; } else { me->mines[n] = me->mine2_pool[n]; } /* new Mine is planted in the last column of the tunnel */ me->last_mine_x = GAME_SCREEN_WIDTH; /* choose a random y-position for the Mine in the Tunnel */ rnd %= (GAME_SCREEN_HEIGHT - me->wall_thickness_top - me->wall_thickness_bottom - 4); me->last_mine_y = me->wall_thickness_top + 2 + rnd; ope.super.sig = MINE_PLANT_SIG; ope.x = me->last_mine_x; ope.y = me->last_mine_y; QHsm_dispatch(me->mines[n], (QEvent *)&ope); /* direct dispatch */ } }}/*..........................................................................*/void Tunnel_dispatchToAllMines(Tunnel *me, QEvent const *e) { uint8_t n; for (n = 0; n < GAME_MINES_MAX; ++n) { if (me->mines[n] != (QHsm *)0) { /* is the mine used? */ QHsm_dispatch(me->mines[n], e); } } (void)me; /* avoid the compiler warning */}/*..........................................................................*/void Tunnel_addImageAt(Tunnel *me, uint8_t bmp, uint8_t x_pos, int8_t y_pos){ uint8_t x; /* the x-index of the ship image */ uint8_t w; /* the width of the image */ Q_REQUIRE(bmp < Q_DIM(l_bitmap)); w = l_bitmap[bmp].width; if (w > GAME_SCREEN_WIDTH - x_pos) { w = GAME_SCREEN_WIDTH - x_pos; } for (x = 0; x < w; ++x) { uint32_t bmp1; if (y_pos >= 0) { bmp1 = (l_bitmap[bmp].bits[x] << (uint8_t)y_pos); } else { bmp1 = (l_bitmap[bmp].bits[x] >> (uint8_t)(-y_pos)); } l_frame[x_pos + x] |= (uint8_t)bmp1; l_frame[x_pos + x + GAME_SCREEN_WIDTH] |= (uint8_t)(bmp1 >> 8); } (void)me; /* avoid the compiler warning */}/*..........................................................................*/uint8_t Tunnel_isWallHit(Tunnel *me, uint8_t bmp, uint8_t x_pos, uint8_t y_pos){ uint8_t x; uint8_t w; /* the width of the image */ Q_REQUIRE(bmp < Q_DIM(l_bitmap)); w = l_bitmap[bmp].width; if (w > GAME_SCREEN_WIDTH - x_pos) { w = GAME_SCREEN_WIDTH - x_pos; } for (x = 0; x < w; ++x) { uint32_t bmp1 = ((uint32_t)l_bitmap[bmp].bits[x] << y_pos); if (((l_walls[x_pos + x] & (uint8_t)bmp1) != 0) || ((l_walls[x_pos + x + GAME_SCREEN_WIDTH] & (uint8_t)(bmp1 >> 8)) != 0)) { return (uint8_t)1; } } (void)me; /* avoid the compiler warning */ return (uint8_t)0;}/*..........................................................................*/uint8_t do_bitmaps_overlap(uint8_t bmp_id1, uint8_t x1, uint8_t y1, uint8_t bmp_id2, uint8_t x2, uint8_t y2){ uint8_t x; uint8_t x0; uint8_t w; uint32_t bits1; uint32_t bits2; Bitmap const *bmp1; Bitmap const *bmp2; Q_REQUIRE((bmp_id1 < Q_DIM(l_bitmap)) && (bmp_id2 < Q_DIM(l_bitmap))); bmp1 = &l_bitmap[bmp_id1]; bmp2 = &l_bitmap[bmp_id2]; /* is the incoming object starting to overlap the Mine bitmap? */ if ((x1 <= x2) && (x1 + bmp2->width > x2)) { x0 = x2 - x1; w = x1 + bmp2->width - x2; if (w > bmp1->width) { w = bmp1->width; } for (x = 0; x < w; ++x) { /* scan over the overlapping columns */ bits1 = ((uint32_t)bmp2->bits[x + x0] << y2); bits2 = ((uint32_t)bmp1->bits[x] << y1); if ((bits1 & bits2) != 0) { /* do the bits overlap? */ return (uint8_t)1; /* yes! */ } } } else { if ((x1 > x2) && (x2 + bmp1->width > x1)) { x0 = x1 - x2; w = x2 + bmp1->width - x1; if (w > bmp2->width) { w = bmp2->width; } for (x = 0; x < w; ++x) { /* scan over the overlapping columns */ bits1 = ((uint32_t)bmp1->bits[x + x0] << y1); bits2 = ((uint32_t)bmp2->bits[x] << y2); if ((bits1 & bits2) != 0) { /* do the bits overlap? */ return (uint8_t)1; /* yes! */ } } } } return (uint8_t)0; /* the bitmaps do not overlap */}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -