⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tunnel.c

📁 事件驱动程序设计很好的框架
💻 C
📖 第 1 页 / 共 2 页
字号:
    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 + -