Files
retrobsd/share/examples/c/tftetris.c
Sergey 84445ee1f7 Fixed bug in fsutil, occasionally resulted in unexpected fsck errors.
It was caused by garbage at end of file names.
2015-06-21 20:00:36 -07:00

941 lines
21 KiB
C

/*
Arduino/RetroBSD Tetris
Copyright (C) 2015 João André Esteves Vilaça
https://github.com/vilaca/Handheld-Color-Console
Adapted for RetroBSD by Alexey Frunze.
Required Hardware:
- PICadillo-35T board
- Funduino joystick shield v1.a
This program is free 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; either version 2 of the License, or
(at your option) any later version.
This program is free 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; either version 2 of the License, or
(at your option) any later version.
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.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <fcntl.h>
#include <unistd.h>
volatile int quit = 0;
volatile int jx = 0, jy = 0;
#include <sys/ioctl.h>
#include <sys/gpio.h>
#include <sys/time.h>
int fd = -1;
int fdx = -1;
int fdy = -1;
struct timeval start_time;
unsigned long millis(void)
{
static int init;
struct timeval t;
unsigned long ms;
if (!init)
{
gettimeofday(&start_time, 0);
init = 1;
return 0;
}
gettimeofday(&t, 0);
ms = (t.tv_sec - start_time.tv_sec) * 1000UL;
ms += t.tv_usec / 1000;
ms -= start_time.tv_usec / 1000;
return ms;
}
void delay(unsigned long ms)
{
usleep(ms * 1000);
}
#define PIX_BUF_SIZ 128 // 28 fps on full-screen continuous box()
void fill(unsigned count, unsigned short color)
{
unsigned short data[1 + PIX_BUF_SIZ];
unsigned cnt = (count < PIX_BUF_SIZ) ? count : PIX_BUF_SIZ;
while (cnt)
data[cnt--] = color;
while (count)
{
cnt = (count < PIX_BUF_SIZ) ? count : PIX_BUF_SIZ;
*data = cnt;
ioctl(fd, 0xDADA, data);
count -= cnt;
}
}
void lineh(unsigned x, unsigned y,
unsigned length, unsigned short color)
{
unsigned short wincoo[4];
wincoo[0] = x;
wincoo[1] = wincoo[3] = y;
wincoo[2] = x + length - 1;
ioctl(fd, 0xC0C0, wincoo);
fill(length, color);
}
void linev(unsigned x, unsigned y,
unsigned length, unsigned short color)
{
unsigned short wincoo[4];
wincoo[0] = wincoo[2] = x;
wincoo[1] = y;
wincoo[3] = y + length - 1;
ioctl(fd, 0xC0C0, wincoo);
fill(length, color);
}
void box(unsigned x, unsigned y,
unsigned width, unsigned height,
unsigned short color,
int solid)
{
if (solid)
{
unsigned short wincoo[4];
wincoo[0] = x; wincoo[1] = y;
wincoo[2] = x + width - 1; wincoo[3] = y + height - 1;
ioctl(fd, 0xC0C0, wincoo);
fill(width * height, color);
}
else
{
lineh(x, y, width, color);
lineh(x, y + height - 1, width, color);
linev(x, y, height, color);
linev(x + width - 1, y, height, color);
}
}
void beep(int frq, int d)
{
(void)frq; // TBD???
delay(d);
}
void boxb(unsigned x, unsigned y, unsigned w, unsigned h, unsigned short c)
{
box(x, y, w, h - 1, c, 1);
box(x, y + h - 1, 1, 1, c, 1);
}
int Joystick_fire(void)
{
return 0; // TBD???
}
int Joystick_getX(void)
{
char buf[21] = { 0 };
jx = 512;
if (read(fdx, buf, sizeof buf - 1) > 0)
jx = strtol(buf, 0, 0);
jx -= 512;
jx = -jx;
if (-128 < jx && jx < 128)
jx = 0;
return jx;
}
int Joystick_getY(void)
{
char buf[21] = { 0 };
jy = 512;
if (read(fdy, buf, sizeof buf - 1) > 0)
jy = strtol(buf, 0, 0);
jy -= 512;
jy = -jy;
if (-128 < jy && jy < 128)
jy = 0;
return jy;
}
void Joystick_waitForRelease(int howLong)
{
int c = 0;
do
{
delay(10);
c += 10;
}
while ((Joystick_fire() || Joystick_getY() || Joystick_getX()) && c < howLong);
}
void randomizer(void);
void score(void);
void scoreBoard(void);
void draw(void);
void moveDown(void);
void userInput(unsigned long now);
void chooseNewShape(void);
int touches(int xi, int yi, int roti);
//TFT resolution 480x320
#define LCD_WIDTH 480//320//480
#define LCD_HEIGHT 320//200//320
#define MIN(X, Y) (((X) < (Y)) ? (X) : (Y))
#define FONT_SPACE 6
#define FONT_X 8
extern unsigned char simpleFont[][8];
enum
{
BOARD_WIDTH = 11,
BOARD_HEIGHT = 20,
BLOCK_SIZE = MIN(LCD_WIDTH / BOARD_WIDTH - 1, LCD_HEIGHT / BOARD_HEIGHT - 1),
BOARD_LEFT = (LCD_WIDTH - BOARD_WIDTH * BLOCK_SIZE) / 4 * 3,
BOARD_RIGHT = BOARD_LEFT + BLOCK_SIZE * BOARD_WIDTH,
BOARD_TOP = (LCD_HEIGHT - BOARD_HEIGHT * BLOCK_SIZE) / 2,
BOARD_BOTTOM = BOARD_TOP + BOARD_HEIGHT * BLOCK_SIZE
};
//Basic Colors
#define BLACK 0x0000
#define BLUE 0x001f
#define CYAN 0x07ff
#define DARKCYAN 0x03EF /* 0, 128, 128 */
#define DARKGREEN 0x03E0
#define DARKGREY 0x7BEF /* 128, 128, 128 */
#define GRAY1 0x8410
#define GRAY2 0x4208
#define GRAY3 0x2104
#define GREEN 0x07e0
#define LIGHTGREEN 0xAFE5 /* 173, 255, 47 */
#define LIGHTGREY 0xC618 /* 192, 192, 192 */
#define MAGENTA 0xF81F /* 255, 0, 255 */
#define MAROON 0x7800 /* 128, 0, 0 */
#define NAVY 0x000F /* 0, 0, 128 */
#define OLIVE 0x7BE0 /* 128, 128, 0 */
#define ORANGE 0xFD20 /* 255, 165, 0 */
#define PURPLE 0x780F /* 128, 0, 128 */
#define RED 0xf800
#define WHITE 0xffff
#define YELLOW 0xffe0
#define PIT_COLOR CYAN
#define BG_COLOR BLACK
typedef unsigned char byte;
// used to clear the position from the screen
typedef struct
{
byte x, y, rot;
} Backup;
#define DROP_WAIT_INIT 1100
#define INPUT_WAIT_ROT 200
#define INPUT_WAIT_MOVE 100
#define INPUT_WAIT_NEW_SHAPE 400
// shapes definitions
byte l_shape[4][4][2] =
{
{ {0, 0}, {0, 1}, {0, 2}, {1, 2} },
{ {0, 1}, {1, 1}, {2, 0}, {2, 1} },
{ {0, 0}, {1, 0}, {1, 1}, {1, 2} },
{ {0, 0}, {0, 1}, {1, 0}, {2, 0} },
};
byte j_shape[4][4][2] =
{
{ {1, 0}, {1, 1}, {0, 2}, {1, 2} },
{ {0, 0}, {1, 0}, {2, 0}, {2, 1} },
{ {0, 0}, {1, 0}, {0, 1}, {0, 2} },
{ {0, 0}, {0, 1}, {1, 1}, {2, 1} },
};
byte o_shape[1][4][2] =
{
{ {0, 0}, {0, 1}, {1, 0}, {1, 1} }
};
byte s_shape[2][4][2] =
{
{ {0, 1}, {1, 0}, {1, 1}, {2, 0} },
{ {0, 0}, {0, 1}, {1, 1}, {1, 2} }
};
byte z_shape[2][4][2] =
{
{ {0, 0}, {1, 0}, {1, 1}, {2, 1} },
{ {1, 0}, {0, 1}, {1, 1}, {0, 2} }
};
byte t_shape[4][4][2] =
{
{ {0, 0}, {1, 0}, {2, 0}, {1, 1} },
{ {0, 0}, {0, 1}, {1, 1}, {0, 2} },
{ {1, 0}, {0, 1}, {1, 1}, {2, 1} },
{ {1, 0}, {0, 1}, {1, 1}, {1, 2} }
};
byte i_shape[2][4][2] =
{
{ {0, 0}, {1, 0}, {2, 0}, {3, 0} },
{ {0, 0}, {0, 1}, {0, 2}, {0, 3} } // TBD??? rotate at the center
};
// All game shapes and their colors
byte* all_shapes[7] =
{
l_shape[0][0],
j_shape[0][0],
o_shape[0][0],
s_shape[0][0],
z_shape[0][0],
t_shape[0][0],
i_shape[0][0]
};
unsigned short colors[7] = { ORANGE, BLUE, YELLOW, GREEN, RED, MAGENTA, CYAN };
// how many rotated variations each shape has
byte shapes[7] = { 4, 4, 1, 2, 2, 4, 2 };
// game progress
int lines, level;
// current shapes
byte current;
// tetris guidelines have all 7 shapes
// selected in sequence to avoid
// long runs without a shape
byte next[7];
byte next_c;
unsigned long lastInput, lastDrop;
byte board[BOARD_HEIGHT][BOARD_WIDTH];
byte x, y, rot;
Backup old;
int newShape;
unsigned long dropWait;
void drawChar(byte ascii, unsigned poX, unsigned poY, unsigned size, unsigned short fgcolor)
{
if ((ascii < 32) || (ascii > 127))
ascii = '?' - 32;
for (int i = 0; i < FONT_X; i++)
{
byte temp = simpleFont[ascii - 32][i];
for (byte f = 0; f < 8; f++)
if ((temp >> f) & 1)
box(poX + i * size, poY + f * size, size, size, fgcolor, 1);
}
}
void drawString(char* string, unsigned poX, unsigned poY, unsigned size, unsigned short fgcolor)
{
while (*string)
{
drawChar(*string++, poX, poY, size, fgcolor);
poX += FONT_SPACE * size;
}
}
void drawCenteredString(char* string, unsigned poY, unsigned size, unsigned short fgcolor)
{
unsigned len = strlen(string) * FONT_SPACE * size;
unsigned left = (LCD_WIDTH - len) / 2;
drawString(string, left, poY, size, fgcolor);
}
void drawNumber(long long_num, unsigned poX, unsigned poY, unsigned size, unsigned short fgcolor)
{
char buf[12], *p = buf + sizeof buf;
int neg = long_num < 0;
unsigned long n = neg ? -(unsigned long)long_num : (unsigned long)long_num;
*--p = '\0';
do
{
*--p = '0' + n % 10;
n /= 10;
} while (n);
if (neg)
*--p = '-';
drawString(p, poX, poY, size, fgcolor);
}
void bcackground(void)
{
// draw black-blue gradient background
for (int i = 0; i < LCD_HEIGHT; i++)
{
int c = 31 - i * 31 / (LCD_HEIGHT - 1);
if (i < BOARD_BOTTOM)
{
lineh(0, i, BOARD_LEFT - 1, c);
lineh(BOARD_RIGHT, i, LCD_WIDTH - BOARD_RIGHT, c);
}
else
{
lineh(0, i, LCD_WIDTH, c);
}
}
// draw the board left limit
linev(BOARD_LEFT - 1, BOARD_TOP, BOARD_BOTTOM - BOARD_TOP, PIT_COLOR);
// draw the board right limit
linev(BOARD_RIGHT - 1, BOARD_TOP, BOARD_BOTTOM - BOARD_TOP, PIT_COLOR);
// draw the board bottom limit
lineh(BOARD_LEFT - 1, BOARD_BOTTOM - 1, BOARD_RIGHT - BOARD_LEFT + 1, PIT_COLOR);
// draw the grid
for (int i = BOARD_LEFT + BLOCK_SIZE - 1; i < BOARD_RIGHT - 1; i += BLOCK_SIZE)
linev(i, BOARD_TOP, BOARD_BOTTOM - BOARD_TOP - 1, GRAY2);
for (int i = BOARD_TOP + BLOCK_SIZE - 1; i < BOARD_BOTTOM - 1; i += BLOCK_SIZE)
lineh(BOARD_LEFT, i, BOARD_RIGHT - BOARD_LEFT - 1, GRAY2);
}
void scoreBoard(void)
{
box(6, 3, 128, 50, BLACK, 1);
drawString("Level", 8, 8, 2, YELLOW);
drawString("Lines", 8, 32, 2, 0x3f);
drawNumber(level, 74, 8, 2, YELLOW);
drawNumber(lines, 74, 32, 2, 0x3f);
box(5, 2, 130, 52, WHITE, 0);
}
void hint(void)
{
// draw next shape hint box
box(30, 100, BLOCK_SIZE * 6, BLOCK_SIZE * 5, BLACK, 1);
box(29, 99, BLOCK_SIZE * 6 + 1, BLOCK_SIZE * 5 + 1, WHITE, 0);
byte* shape = all_shapes[next[next_c]];
for (int i = 0; i < 4; i++)
{
byte* block = shape + i * 2;
boxb(30 + BLOCK_SIZE + block[0] * BLOCK_SIZE,
100 + BLOCK_SIZE + block[1] * BLOCK_SIZE,
BLOCK_SIZE - 1,
BLOCK_SIZE - 1,
colors[next[next_c]]);
}
}
void gameLoop(void)
{
box(0, 0, LCD_WIDTH, LCD_HEIGHT, BG_COLOR, 1);
// initialize game logic
newShape = 1;
lines = 0;
lastInput = 0;
lastDrop = 0;
dropWait = DROP_WAIT_INIT;
level = 1;
// clean board
for (int i = 0; i < BOARD_WIDTH; i++)
for (int j = 0; j < BOARD_HEIGHT; j++)
board[j][i] = 0;
// next shape
randomizer();
bcackground();
scoreBoard();
do
{
// get clock
unsigned long now = millis();
// display new shape
if (newShape)
{
Joystick_waitForRelease(INPUT_WAIT_NEW_SHAPE);
newShape = 0;
// a new shape enters the game
chooseNewShape();
// draw next shape hint box
hint();
// check if new shape is placed over other shape(s)
// on the board
if (touches(0, 0, 0))
{
// draw shape to screen
draw();
// game over
return;
}
// draw shape to screen
draw();
}
else
{
// check if enough time has passed since last time the shape
// was moved down the board
if (now - lastDrop > dropWait || Joystick_getY() > 0)
{
// update clock
lastDrop = now;
moveDown();
}
}
if (!newShape && now - lastInput > INPUT_WAIT_MOVE)
{
userInput(now);
}
} while (!quit);
}
void chooseNewShape(void)
{
current = next[next_c];
next_c++;
if (next_c == 7)
randomizer();
// new shape must be postioned at the middle of
// the top of the board
// with zero rotation
rot = 0;
y = 0;
x = BOARD_WIDTH / 2 - 1;
old.rot = rot;
old.y = y;
old.x = x;
}
void userInput(unsigned long now)
{
int jx = Joystick_getX();
if (jx < 0 && x > 0 && !touches(-1, 0, 0))
{
x--;
}
else if (jx > 0 && x < BOARD_WIDTH && !touches(1, 0, 0))
{
x++;
}
else if (Joystick_fire())
{
while (!touches(0, 1, 0))
y++;
}
else if (now - lastInput > INPUT_WAIT_ROT)
{
if (Joystick_getY() < 0 && !touches(0, 0, 1))
{
rot++;
rot %= shapes[current];
}
}
else
{
return;
}
lastInput = now;
draw();
}
void moveDown(void)
{
// prepare to move down
// check if board is clear bellow
if (touches(0, 1, 0))
{
// moving down touches another shape
newShape = 1;
// this shape wont move again
// add it to the board
byte* shape = all_shapes[current];
for (int i = 0; i < 4; i++)
{
byte* block = shape + (rot * 4 + i) * 2;
board[block[1] + y][block[0] + x] = current + 1;
}
// check if lines were made
score();
beep(1500, 25);
}
else
{
// move shape down
y++;
draw();
}
}
void draw(void)
{
byte* shape = all_shapes[current];
for (int i = 0; i < 4; i++)
{
byte* block = shape + (rot * 4 + i) * 2;
boxb(BOARD_LEFT + block[0] * BLOCK_SIZE + BLOCK_SIZE * x,
BOARD_TOP + block[1] * BLOCK_SIZE + BLOCK_SIZE * y,
BLOCK_SIZE - 1,
BLOCK_SIZE - 1,
colors[current]);
board[block[1] + y][block[0] + x] = 255;
}
// erase old
for (int i = 0; i < 4; i++)
{
byte* block = shape + (old.rot * 4 + i) * 2;
if (board[block[1] + old.y][block[0] + old.x] == 255)
continue;
boxb(BOARD_LEFT + block[0] * BLOCK_SIZE + BLOCK_SIZE * old.x,
BOARD_TOP + block[1] * BLOCK_SIZE + BLOCK_SIZE * old.y,
BLOCK_SIZE - 1,
BLOCK_SIZE - 1,
BG_COLOR);
}
for (int i = 0; i < 4; i++)
{
byte* block = shape + (rot * 4 + i) * 2;
board[block[1] + y][block[0] + x] = 0;
}
old.x = x;
old.y = y;
old.rot = rot;
}
int touches(int xi, int yi, int roti)
{
byte* shape = all_shapes[current];
for (int i = 0; i < 4; i++)
{
byte* block = shape + (((rot + roti) % shapes[current]) * 4 + i) * 2;
int x2 = x + block[0] + xi;
int y2 = y + block[1] + yi;
if (y2 == BOARD_HEIGHT || x2 == BOARD_WIDTH || board[y2][x2])
return 1;
}
return 0;
}
void score(void)
{
// we scan a max of 4 lines
int ll = y + 3; // BUG!!! was uninitialized
if (y + 3 >= BOARD_HEIGHT)
ll = BOARD_HEIGHT - 1;
// scan board from current position
for (int l = y; l <= ll; l++)
{
// check if there's a complete line on the board
int line = 1;
for (int c = 0; c < BOARD_WIDTH; c++)
{
if (board[l][c] == 0)
{
line = 0;
break;
}
}
if (!line)
{
// move to next line
continue;
}
beep(3000, 50);
lines++;
if (lines % 10 == 0)
{
level++;
dropWait /= 2;
}
scoreBoard();
// move board down
for (int row = l; row > 0; row --)
{
for (int c = 0; c < BOARD_WIDTH; c++)
{
byte v = board[row - 1][c];
board[row][c] = v;
boxb(BOARD_LEFT + BLOCK_SIZE * c,
BOARD_TOP + BLOCK_SIZE * row,
BLOCK_SIZE - 1,
BLOCK_SIZE - 1,
v == 0 ? BLACK : colors[v - 1]);
}
}
// clear top line
for (int c = 0; c < BOARD_WIDTH; c++)
board[0][c] = 0;
box(BOARD_LEFT,
0,
BOARD_RIGHT - BOARD_LEFT,
BLOCK_SIZE,
BLACK,
1);
}
delay(350);
}
// create a sequence of 7 random shapes
void randomizer(void)
{
// randomize 7 shapes
for (byte i = 0; i < 7; i ++)
{
int retry;
byte shape;
do
{
shape = rand() % 7;
// check if already in sequence
retry = 0;
for (int j = 0; j < i; j++)
{
if (shape == next[j])
{
retry = 1;
break;
}
}
} while (retry);
next[i] = shape;
}
next_c = 0;
}
void drawPreGameScreen(void)
{
box(0, 0, LCD_WIDTH, LCD_HEIGHT, WHITE, 1);
drawCenteredString("Tetris", 40, 8, BLUE);
drawCenteredString("Move joystick to start", 110, 2, BLACK);
drawCenteredString("http://vilaca.eu", 220, 2, PURPLE);
}
void gameOver(void)
{
box(32, LCD_HEIGHT / 2 - 24, LCD_WIDTH - 64, 48, BLACK, 1);
drawCenteredString("Game Over", LCD_HEIGHT / 2 - 16, 4, WHITE);
box(32, LCD_HEIGHT / 2 - 24, LCD_WIDTH - 64, 48, RED, 0);
beep(600, 200);
delay(300);
beep(600, 200);
delay(300);
beep(200, 600);
delay(1500);
}
unsigned char simpleFont[][8] =
{
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x5F,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x07,0x00,0x07,0x00,0x00,0x00},
{0x00,0x14,0x7F,0x14,0x7F,0x14,0x00,0x00},
{0x00,0x24,0x2A,0x7F,0x2A,0x12,0x00,0x00},
{0x00,0x23,0x13,0x08,0x64,0x62,0x00,0x00},
{0x00,0x36,0x49,0x55,0x22,0x50,0x00,0x00},
{0x00,0x00,0x05,0x03,0x00,0x00,0x00,0x00},
{0x00,0x1C,0x22,0x41,0x00,0x00,0x00,0x00},
{0x00,0x41,0x22,0x1C,0x00,0x00,0x00,0x00},
{0x00,0x08,0x2A,0x1C,0x2A,0x08,0x00,0x00},
{0x00,0x08,0x08,0x3E,0x08,0x08,0x00,0x00},
{0x00,0xA0,0x60,0x00,0x00,0x00,0x00,0x00},
{0x00,0x08,0x08,0x08,0x08,0x08,0x00,0x00},
{0x00,0x60,0x60,0x00,0x00,0x00,0x00,0x00},
{0x00,0x20,0x10,0x08,0x04,0x02,0x00,0x00},
{0x00,0x3E,0x51,0x49,0x45,0x3E,0x00,0x00},
{0x00,0x00,0x42,0x7F,0x40,0x00,0x00,0x00},
{0x00,0x62,0x51,0x49,0x49,0x46,0x00,0x00},
{0x00,0x22,0x41,0x49,0x49,0x36,0x00,0x00},
{0x00,0x18,0x14,0x12,0x7F,0x10,0x00,0x00},
{0x00,0x27,0x45,0x45,0x45,0x39,0x00,0x00},
{0x00,0x3C,0x4A,0x49,0x49,0x30,0x00,0x00},
{0x00,0x01,0x71,0x09,0x05,0x03,0x00,0x00},
{0x00,0x36,0x49,0x49,0x49,0x36,0x00,0x00},
{0x00,0x06,0x49,0x49,0x29,0x1E,0x00,0x00},
{0x00,0x00,0x36,0x36,0x00,0x00,0x00,0x00},
{0x00,0x00,0xAC,0x6C,0x00,0x00,0x00,0x00},
{0x00,0x08,0x14,0x22,0x41,0x00,0x00,0x00},
{0x00,0x14,0x14,0x14,0x14,0x14,0x00,0x00},
{0x00,0x41,0x22,0x14,0x08,0x00,0x00,0x00},
{0x00,0x02,0x01,0x51,0x09,0x06,0x00,0x00},
{0x00,0x32,0x49,0x79,0x41,0x3E,0x00,0x00},
{0x00,0x7E,0x09,0x09,0x09,0x7E,0x00,0x00},
{0x00,0x7F,0x49,0x49,0x49,0x36,0x00,0x00},
{0x00,0x3E,0x41,0x41,0x41,0x22,0x00,0x00},
{0x00,0x7F,0x41,0x41,0x22,0x1C,0x00,0x00},
{0x00,0x7F,0x49,0x49,0x49,0x41,0x00,0x00},
{0x00,0x7F,0x09,0x09,0x09,0x01,0x00,0x00},
{0x00,0x3E,0x41,0x41,0x51,0x72,0x00,0x00},
{0x00,0x7F,0x08,0x08,0x08,0x7F,0x00,0x00},
{0x00,0x41,0x7F,0x41,0x00,0x00,0x00,0x00},
{0x00,0x20,0x40,0x41,0x3F,0x01,0x00,0x00},
{0x00,0x7F,0x08,0x14,0x22,0x41,0x00,0x00},
{0x00,0x7F,0x40,0x40,0x40,0x40,0x00,0x00},
{0x00,0x7F,0x02,0x0C,0x02,0x7F,0x00,0x00},
{0x00,0x7F,0x04,0x08,0x10,0x7F,0x00,0x00},
{0x00,0x3E,0x41,0x41,0x41,0x3E,0x00,0x00},
{0x00,0x7F,0x09,0x09,0x09,0x06,0x00,0x00},
{0x00,0x3E,0x41,0x51,0x21,0x5E,0x00,0x00},
{0x00,0x7F,0x09,0x19,0x29,0x46,0x00,0x00},
{0x00,0x26,0x49,0x49,0x49,0x32,0x00,0x00},
{0x00,0x01,0x01,0x7F,0x01,0x01,0x00,0x00},
{0x00,0x3F,0x40,0x40,0x40,0x3F,0x00,0x00},
{0x00,0x1F,0x20,0x40,0x20,0x1F,0x00,0x00},
{0x00,0x3F,0x40,0x38,0x40,0x3F,0x00,0x00},
{0x00,0x63,0x14,0x08,0x14,0x63,0x00,0x00},
{0x00,0x03,0x04,0x78,0x04,0x03,0x00,0x00},
{0x00,0x61,0x51,0x49,0x45,0x43,0x00,0x00},
{0x00,0x7F,0x41,0x41,0x00,0x00,0x00,0x00},
{0x00,0x02,0x04,0x08,0x10,0x20,0x00,0x00},
{0x00,0x41,0x41,0x7F,0x00,0x00,0x00,0x00},
{0x00,0x04,0x02,0x01,0x02,0x04,0x00,0x00},
{0x00,0x80,0x80,0x80,0x80,0x80,0x00,0x00},
{0x00,0x01,0x02,0x04,0x00,0x00,0x00,0x00},
{0x00,0x20,0x54,0x54,0x54,0x78,0x00,0x00},
{0x00,0x7F,0x48,0x44,0x44,0x38,0x00,0x00},
{0x00,0x38,0x44,0x44,0x28,0x00,0x00,0x00},
{0x00,0x38,0x44,0x44,0x48,0x7F,0x00,0x00},
{0x00,0x38,0x54,0x54,0x54,0x18,0x00,0x00},
{0x00,0x08,0x7E,0x09,0x02,0x00,0x00,0x00},
{0x00,0x18,0xA4,0xA4,0xA4,0x7C,0x00,0x00},
{0x00,0x7F,0x08,0x04,0x04,0x78,0x00,0x00},
{0x00,0x00,0x7D,0x00,0x00,0x00,0x00,0x00},
{0x00,0x80,0x84,0x7D,0x00,0x00,0x00,0x00},
{0x00,0x7F,0x10,0x28,0x44,0x00,0x00,0x00},
{0x00,0x41,0x7F,0x40,0x00,0x00,0x00,0x00},
{0x00,0x7C,0x04,0x18,0x04,0x78,0x00,0x00},
{0x00,0x7C,0x08,0x04,0x7C,0x00,0x00,0x00},
{0x00,0x38,0x44,0x44,0x38,0x00,0x00,0x00},
{0x00,0xFC,0x24,0x24,0x18,0x00,0x00,0x00},
{0x00,0x18,0x24,0x24,0xFC,0x00,0x00,0x00},
{0x00,0x00,0x7C,0x08,0x04,0x00,0x00,0x00},
{0x00,0x48,0x54,0x54,0x24,0x00,0x00,0x00},
{0x00,0x04,0x7F,0x44,0x00,0x00,0x00,0x00},
{0x00,0x3C,0x40,0x40,0x7C,0x00,0x00,0x00},
{0x00,0x1C,0x20,0x40,0x20,0x1C,0x00,0x00},
{0x00,0x3C,0x40,0x30,0x40,0x3C,0x00,0x00},
{0x00,0x44,0x28,0x10,0x28,0x44,0x00,0x00},
{0x00,0x1C,0xA0,0xA0,0x7C,0x00,0x00,0x00},
{0x00,0x44,0x64,0x54,0x4C,0x44,0x00,0x00},
{0x00,0x08,0x36,0x41,0x00,0x00,0x00,0x00},
{0x00,0x00,0x7F,0x00,0x00,0x00,0x00,0x00},
{0x00,0x41,0x36,0x08,0x00,0x00,0x00,0x00},
{0x00,0x02,0x01,0x01,0x02,0x01,0x00,0x00},
{0x00,0x02,0x05,0x05,0x02,0x00,0x00,0x00}
};
int main(void)
{
// get TFT display handle
if ((fd = open("/dev/tft0", O_RDWR)) < 0)
{
perror("/dev/tft0");
return 1;
}
// get joystick's x ADC handle
if ((fdx = open("/dev/adc0", O_RDWR)) < 0)
{
perror("/dev/adc0");
return 1;
}
// get joystick's y ADC handle
if ((fdy = open("/dev/adc1", O_RDWR)) < 0)
{
perror("/dev/adc1");
return 1;
}
srand(time(NULL));
drawPreGameScreen();
while (!Joystick_fire() && !Joystick_getY() && !Joystick_getX());
gameLoop();
gameOver();
while (!Joystick_fire() && !Joystick_getY() && !Joystick_getX());
box(0, 0, LCD_WIDTH, LCD_HEIGHT, BLACK, 1);
}