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

📄 game.c

📁 最新版IAR FOR ARM(EWARM)5.11中的代码例子
💻 C
📖 第 1 页 / 共 3 页
字号:
//*****************************************************************************
//
// game.c - A "fly through the tunnel and shoot things" game.
//
// Copyright (c) 2006-2007 Luminary Micro, Inc.  All rights reserved.
// 
// Software License Agreement
// 
// Luminary Micro, Inc. (LMI) is supplying this software for use solely and
// exclusively on LMI's microcontroller products.
// 
// The software is owned by LMI and/or its suppliers, and is protected under
// applicable copyright laws.  All rights are reserved.  You may not combine
// this software with "viral" open-source software in order to form a larger
// program.  Any use in violation of the foregoing restrictions may subject
// the user to criminal sanctions under applicable laws, as well as to civil
// liability for the breach of the terms and conditions of this license.
// 
// THIS SOFTWARE IS PROVIDED "AS IS".  NO WARRANTIES, WHETHER EXPRESS, IMPLIED
// OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
// LMI SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
// CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
// 
// This is part of revision 1952 of the Stellaris Peripheral Driver Library.
//
//*****************************************************************************

#include "../../../hw_memmap.h"
#include "../../../hw_types.h"
#include "../../../src/uart.h"
#include "../osram96x16x1.h"
#include "game.h"
#include "globals.h"
#include "random.h"

//*****************************************************************************
//
// A bitmap for the "Press Button To Play" screen.  The bitmap is as follows:
//
//     xxx.........................xxx........x...x...............xxxxx.......
//     x..x........................x..x.......x...x.................x.........
//     x..x.x.xx..xx...xxx..xxx....x..x.x..x.xxx.xxx..xx..xxx.......x..xx.....
//     xxx..xx...x..x.x....x.......xxx..x..x..x...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..x......x.x..x....
//     x....x.....xxx.xxx..xxx.....xxx...xxx...x...x..xx..x..x......x..xx.....
//     .......................................................................
//
// Continued...
//
//    xxx..x..........
//    x..x.x..........
//    x..x.x..xx..x..x
//    xxx..x.x..x.x..x
//    x....x.x..x.x..x
//    x....x.x..x..xxx
//    x....x..xxx....x
//    ............xxx.
//
//*****************************************************************************
static const unsigned char g_pucPlay[87] =
{
    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, 0x00, 0x00, 0x00, 0x00, 0x01,
    0x01, 0x7f, 0x01, 0x39, 0x44, 0x44, 0x38, 0x00, 0x00, 0x00, 0x00, 0x7f,
    0x09, 0x09, 0x06, 0x00, 0x7f, 0x00, 0x38, 0x44, 0x44, 0x78, 0x00, 0x9c,
    0xa0, 0xa0, 0x7c
};

//*****************************************************************************
//
// A bitmap for the space ship.  The bitmap is as follows:
//
//     x....
//     xxx..
//     xxxxx
//
//*****************************************************************************
static const unsigned char g_pucShip[5] =
{
    0x07, 0x06, 0x06, 0x04, 0x04
};

//*****************************************************************************
//
// A bitmap for mine type one.  The bitmap is as follows:
//
//     .x.
//     xxx
//     .x.
//
//*****************************************************************************
static const unsigned char g_pucMine1[3] =
{
    0x02, 0x07, 0x02
};

//*****************************************************************************
//
// A bitmap for mine type two.  The bitmap is as follows:
//
//     x..x
//     .xx.
//     .xx.
//     x..x
//
//*****************************************************************************
static const unsigned char g_pucMine2[4] =
{
    0x09, 0x06, 0x06, 0x09
};

//*****************************************************************************
//
// A bitmap for the first stage of an explosion.  The bitmap is as follows:
//
//     x
//
//*****************************************************************************
static const unsigned char g_pucExplosion1[1] =
{
    0x01
};

//*****************************************************************************
//
// A bitmap for the second stage of an explosion.  The bitmap is as follows:
//
//     x.x
//     .x.
//     x.x
//
//*****************************************************************************
static const unsigned char g_pucExplosion2[3] =
{
    0x05, 0x02, 0x05
};

//*****************************************************************************
//
// A bitmap for the third stage of an explosion.  The bitmap is as follows:
//
//     x...x
//     .x.x.
//     ..x..
//     .x.x.
//     x...x
//
//*****************************************************************************
static const unsigned char g_pucExplosion3[5] =
{
    0x11, 0x0a, 0x04, 0x0a, 0x11
};

//*****************************************************************************
//
// A bitmap for the fourth stage of an explosion.  The bitmap is as follows:
//
//     x..x..x
//     .x.x.x.
//     ..x.x..
//     xx.x.xx
//     ..x.x..
//     .x.x.x.
//     x..x..x
//
//*****************************************************************************
static const unsigned char g_pucExplosion4[7] =
{
    0x49, 0x2a, 0x14, 0x6b, 0x14, 0x2a, 0x49
};

//*****************************************************************************
//
// This array contains the sequence of explosion images, along with the width
// of each one.
//
//*****************************************************************************
static const struct
{
    const unsigned char *pucImage;
    unsigned char ucAdjust;
    unsigned char ucWidth;
}
g_psExplosion[4] =
{
    { g_pucExplosion1, 0, 1 },
    { g_pucExplosion2, 1, 3 },
    { g_pucExplosion3, 2, 5 },
    { g_pucExplosion4, 3, 7 }
};

//*****************************************************************************
//
// Storage for the background image of the tunnel.  This is copied to the local
// frame buffer and then the other elements are overlaid upon it.
//
//*****************************************************************************
unsigned char g_pucBackground[192];

//*****************************************************************************
//
// The offsets from the top and bottom scan lines of the display to the wall of
// the tunnel.  The first element is the offset from the top scan line and the
// second element is the offfset from the bottom scan line.
//
//*****************************************************************************
static unsigned char g_pucOffset[2];

//*****************************************************************************
//
// An array of mines currently visible on the display.  Up to five mines can be
// displayed, and each has three variables associated with it: the type (in
// index zero), the horizontal position (in index one), and the vertical
// position (in index two).  If all three variables are negative one, then that
// mine does not exist.
//
//*****************************************************************************
static char g_pcMines[5][3];

//*****************************************************************************
//
// The location of the missile, if it has been fired.  The first entry contains
// the horizontal position and the second entry contains the vertical position.
// If both are negative one, then the missile has not been fired.
//
//*****************************************************************************
static char g_pcMissile[2];

//*****************************************************************************
//
// An array of explosions currently active on the display.  Up to five
// explosions can be displayed (the fifth being dedicated to the ship
// explosion), and each has three variables associated with it: the explosion
// step number (in index zero), the horizontal position (in index one), and the
// vertical position (in index two).  If the step number is negative one, then
// that explosion is not active.
//
//*****************************************************************************
static char g_pcExplosions[5][3];

//*****************************************************************************
//
// The point accumulated during the game.  One point is added for each time the
// display is scrolled to the left (i.e. the ship travels one step through the
// tunnel) and twenty-five points are added for each obstacle that is shot.
//
//*****************************************************************************
static unsigned long g_ulScore;

//*****************************************************************************
//
// Scroll the tunnel image one column to the left and add a new column of
// tunnel on the right side of the display.
//
//*****************************************************************************
static void
UpdateBackground(unsigned long ulGap)
{
    unsigned long ulCount, ulIdx;

    //
    // Loop through the array of mines.
    //
    for(ulIdx = 0; ulIdx < 5; ulIdx++)
    {
        //
        // Skip this mine if it is disabled.
        //
        if((g_pcMines[ulIdx][0] == (char)-1) &&
           (g_pcMines[ulIdx][1] == (char)-1) &&
           (g_pcMines[ulIdx][2] == (char)-1))
        {
            continue;
        }

        //
        // Stop searching if this mine is near or on the right side of the
        // display.
        //
        if(g_pcMines[ulIdx][1] > 91)
        {
            break;
        }
    }

    //
    // Get a random number based on the collected entropy.
    //
    ulCount = RandomNumber();

    //
    // If the top part of the tunnel is not at the top of the display, then
    // move it up 18.75% of the time.
    //
    if((ulCount < 0x30000000) && (g_pucOffset[0] != 0))
    {
        g_pucOffset[0]--;
    }

    //
    // If the top part of the tunnel is not too close to the bottom part of the
    // tunnel, and there is no mine on the right side of the display or the top
    // part of the tunnel is far enough away from the mine, then move it down
    // 18.75% of the time.
    //
    if((ulCount > 0xd0000000) && ((g_pucOffset[0] + ulGap) < g_pucOffset[1]) &&
       ((ulIdx == 5) || ((g_pcMines[ulIdx][2] - g_pucOffset[0]) > 1)))
    {
        g_pucOffset[0]++;
    }

    //
    // Get a new pseudo random number based on the original random number (no
    // new entropy will have been collected, so it will return the exact same
    // random number, which isn't so random).
    //
    ulCount = NEXT_RAND(ulCount);

    //
    // If the bottom part of the tunnel is not too close to the top part of the
    // tunnel, and there is no mine on the right side of the display or the
    // bottom part of the tunnel is far enough away from the mine, then move it
    // up 18.75% of the time.
    //
    if((ulCount < 0x30000000) && ((g_pucOffset[1] - ulGap) > g_pucOffset[0]) &&
       ((ulIdx == 5) || ((g_pucOffset[1] - g_pcMines[ulIdx][2]) > 5)))
    {
        g_pucOffset[1]--;
    }

    //
    // If the bottom part of the tunnel is not at the bottom of the display,
    // then move it down 18.75% of the time.
    //
    if((ulCount > 0xd0000000) && (g_pucOffset[1] != 16))
    {
        g_pucOffset[1]++;
    }

    //
    // Move the background image one column to the left.
    //
    for(ulCount = 0; ulCount < 192; ulCount++)
    {
        g_pucBackground[ulCount] = g_pucBackground[ulCount + 1];
    }

    //
    // Generate a new column on the right side of the background image.
    //
    g_pucBackground[95] = 0xff >> (8 - g_pucOffset[0]);
    g_pucBackground[191] = 0xff << (g_pucOffset[1] - 8);

    //
    // Copy the background image to the local frame buffer.
    //
    for(ulCount = 0; ulCount < 192; ulCount += 4)
    {
        *(unsigned long *)(g_pucFrame + ulCount) =
            *(unsigned long *)(g_pucBackground + ulCount);
    }
}

//*****************************************************************************
//
// Draws a image on the local frame buffer.
//
//*****************************************************************************
static void
DrawImage(const unsigned char *pucImage, long lX, long lY,
          unsigned long ulWidth)
{
    unsigned long ulIdx;

    //
    // Loop through the columns of this mine.
    //
    for(ulIdx = 0; ulIdx < ulWidth; ulIdx++)
    {
        //
        // See if this column is on the display.
        //
        if(((lX + (long)ulIdx) >= 0) && ((lX + ulIdx) < 96))
        {
            //
            // See if this mine is in the upper or lower row.
            //
            if(lY < 8)
            {
                //
                // Add this mine to the first row of the local frame buffer.
                // Part of the mine image may be in the second row as well, so
                // possibly add it there as well.
                //
                g_pucFrame[lX + ulIdx] |= pucImage[ulIdx] << lY;
                g_pucFrame[lX + ulIdx + 96] |= pucImage[ulIdx] >> (8 - lY);
            }
            else
            {
                //
                // Add this mine to the second row of the local frame buffer.
                //
                g_pucFrame[lX + ulIdx + 96] |= pucImage[ulIdx] << (lY - 8);
            }
        }
    }
}

//*****************************************************************************
//
// Update the mines in the tunnel.
//
//*****************************************************************************
static void
UpdateMines(void)
{
    unsigned long ulCount, ulIdx, ulMax;

    //
    // The maximum horizontal position of any mine found.
    //
    ulMax = 0;

    //
    // Loop through the five possible mines.
    //
    for(ulCount = 0; ulCount < 5; ulCount++)
    {
        //
        // Skip this mine if it does not exist.
        //
        if((g_pcMines[ulCount][0] == (char)-1) &&
           (g_pcMines[ulCount][1] == (char)-1) &&
           (g_pcMines[ulCount][2] == (char)-1))
        {
            continue;
        }

        //
        // Move the mine one step to the left (i.e. keep it in the same place
        // within the tunnel).
        //

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -