Merge branch 'master' of https://github.com/RetroBSD/retrobsd
This commit is contained in:
@@ -1,8 +1,22 @@
|
||||
#ifndef _STDDEF_H_
|
||||
#define _STDDEF_H_
|
||||
|
||||
typedef int ptrdiff_t;
|
||||
|
||||
#ifndef _SIZE_T
|
||||
#define _SIZE_T
|
||||
typedef unsigned size_t;
|
||||
#endif
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
/* Offset of member MEMBER in a struct of type TYPE. */
|
||||
|
||||
#if defined(__GNUC__) && __GNUC__ > 3
|
||||
#define offsetof(TYPE, MEMBER) __builtin_offsetof (TYPE, MEMBER)
|
||||
#else
|
||||
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE*)0)->MEMBER)
|
||||
#endif
|
||||
|
||||
#endif /* _STDDEF_H_ */
|
||||
|
||||
@@ -5,8 +5,6 @@
|
||||
*/
|
||||
#ifndef FILE
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#define BUFSIZ 1024
|
||||
extern struct _iobuf {
|
||||
int _cnt;
|
||||
@@ -40,6 +38,11 @@ extern struct _iobuf {
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
#ifndef _SIZE_T
|
||||
#define _SIZE_T
|
||||
typedef unsigned size_t;
|
||||
#endif
|
||||
|
||||
#define FILE struct _iobuf
|
||||
#define EOF (-1)
|
||||
|
||||
|
||||
@@ -43,8 +43,6 @@
|
||||
#ifndef _STDLIB_H_
|
||||
#define _STDLIB_H_
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
@@ -54,6 +52,11 @@
|
||||
|
||||
#define RAND_MAX 0x7fff
|
||||
|
||||
#ifndef _SIZE_T
|
||||
#define _SIZE_T
|
||||
typedef unsigned size_t;
|
||||
#endif
|
||||
|
||||
void abort (void);
|
||||
int abs (int);
|
||||
int atexit (void (*)(void));
|
||||
@@ -83,7 +86,7 @@ char *_findenv (const char *name, int *offset);
|
||||
void *alloca (size_t size);
|
||||
|
||||
int daemon (int, int);
|
||||
char *devname (dev_t dev, mode_t type);
|
||||
char *devname (int dev, int type);
|
||||
int getloadavg (unsigned loadavg[], int nelem);
|
||||
|
||||
extern char *suboptarg; /* getsubopt(3) external variable */
|
||||
|
||||
@@ -3,12 +3,15 @@
|
||||
* All rights reserved. The Berkeley software License Agreement
|
||||
* specifies the terms and conditions for redistribution.
|
||||
*/
|
||||
#include <sys/types.h>
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
#ifndef _SIZE_T
|
||||
#define _SIZE_T
|
||||
typedef unsigned size_t;
|
||||
#endif
|
||||
|
||||
char *strcat (char *, const char *);
|
||||
char *strncat (char *, const char *, size_t);
|
||||
char *strcpy (char *, const char *);
|
||||
|
||||
@@ -30,7 +30,10 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
#include <sys/types.h>
|
||||
#ifndef _SIZE_T
|
||||
#define _SIZE_T
|
||||
typedef unsigned size_t;
|
||||
#endif
|
||||
|
||||
int bcmp(const void *, const void *, size_t);
|
||||
void bcopy(const void *, void *, size_t);
|
||||
|
||||
@@ -6,7 +6,15 @@
|
||||
#ifndef _TIME_H
|
||||
#define _TIME_H
|
||||
|
||||
#include <sys/types.h> /* for time_t */
|
||||
#ifndef _TIME_T
|
||||
#define _TIME_T
|
||||
typedef long time_t;
|
||||
#endif
|
||||
|
||||
#ifndef _SIZE_T
|
||||
#define _SIZE_T
|
||||
typedef unsigned size_t;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Structure returned by gmtime and localtime calls (see ctime(3)).
|
||||
|
||||
@@ -983,6 +983,8 @@ file /share/examples/c/test1.c
|
||||
file /share/examples/c/test2.c
|
||||
file /share/examples/c/test3.c
|
||||
file /share/examples/c/tetris.c
|
||||
file /share/examples/c/tft.c
|
||||
file /share/examples/c/tftetris.c
|
||||
|
||||
#
|
||||
# Files: /share/examples/smallc
|
||||
@@ -1035,7 +1037,8 @@ file /share/examples/cube/backlight.c
|
||||
file /share/examples/cube/cube.c
|
||||
file /share/examples/cube/cube.h
|
||||
file /share/examples/cube/demo.c
|
||||
file /share/examples/cube/gpio.c
|
||||
file /share/examples/cube/fubarino.c
|
||||
file /share/examples/cube/duinomite.c
|
||||
|
||||
#
|
||||
# Files: /share/examples/dhrystone
|
||||
|
||||
219
share/examples/c/tft.c
Normal file
219
share/examples/c/tft.c
Normal file
@@ -0,0 +1,219 @@
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/gpio.h>
|
||||
#include <time.h>
|
||||
|
||||
#define BLACK 0x0000
|
||||
#define RED 0xF800
|
||||
#define GREEN 0x07E0
|
||||
#define BLUE 0x001F
|
||||
#define WHITE 0xFFFF
|
||||
|
||||
int fd = -1;
|
||||
|
||||
//#define PIX_BUF_SIZ 64 // 21 fps
|
||||
#define PIX_BUF_SIZ 128 // 28 fps on full-screen continuous box()
|
||||
//#define PIX_BUF_SIZ 256 // 32 fps
|
||||
//#define PIX_BUF_SIZ 512 // 34 fps
|
||||
|
||||
void pixel(unsigned x, unsigned y,
|
||||
unsigned short color)
|
||||
{
|
||||
unsigned short wincoo[4];
|
||||
unsigned short data[2];
|
||||
|
||||
wincoo[0] = wincoo[2] = x;
|
||||
wincoo[1] = wincoo[3] = y;
|
||||
ioctl(fd, 0xC0C0, wincoo);
|
||||
|
||||
*data = 1;
|
||||
data[1] = color;
|
||||
ioctl(fd, 0xDADA, data);
|
||||
}
|
||||
|
||||
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 line(int x1, int y1,
|
||||
int x2, int y2,
|
||||
unsigned short color)
|
||||
{
|
||||
int sx, sy, dx1, dy1, dx2, dy2, x, y, m, n, k, cnt;
|
||||
|
||||
sx = x2 - x1;
|
||||
sy = y2 - y1;
|
||||
|
||||
if (sy < 0 || sy == 0 && sx < 0)
|
||||
{
|
||||
k = x1; x1 = x2; x2 = k;
|
||||
k = y1; y1 = y2; y2 = k;
|
||||
sx = -sx;
|
||||
sy = -sy;
|
||||
}
|
||||
|
||||
if (sx > 0) dx1 = 1;
|
||||
else if (sx < 0) dx1 = -1;
|
||||
else dy1 = 0;
|
||||
|
||||
if (sy > 0) dy1 = 1;
|
||||
else if (sy < 0) dy1 = -1;
|
||||
else dy1 = 0;
|
||||
|
||||
m = (sx >= 0) ? sx : -sx;
|
||||
n = (sy >= 0) ? sy : -sy;
|
||||
dx2 = dx1;
|
||||
dy2 = 0;
|
||||
|
||||
if (m < n)
|
||||
{
|
||||
m = (sy >= 0) ? sy : -sy;
|
||||
n = (sx >= 0) ? sx : -sx;
|
||||
dx2 = 0;
|
||||
dy2 = dy1;
|
||||
}
|
||||
|
||||
x = x1; y = y1;
|
||||
cnt = m + 1;
|
||||
k = n / 2;
|
||||
|
||||
while (cnt--)
|
||||
{
|
||||
if (x >= 0 && x < 480 && y >= 0 && y < 320)
|
||||
pixel(x, y, color);
|
||||
|
||||
k += n;
|
||||
if (k < m)
|
||||
{
|
||||
x += dx2;
|
||||
y += dy2;
|
||||
}
|
||||
else
|
||||
{
|
||||
k -= m;
|
||||
x += dx1;
|
||||
y += dy1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
if ((fd = open ("/dev/tft0", O_RDWR)) < 0)
|
||||
{
|
||||
perror("/dev/tft0");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (argc > 1)
|
||||
{
|
||||
if (!strcmp(argv[1], "-blank"))
|
||||
{
|
||||
box(0, 0, 480, 320, BLACK, 1);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
for (int y = 0; y < 320; y++)
|
||||
for (int x = 0; x < 480; x++)
|
||||
pixel(x, y, (x<<3) ^ (y<<3));
|
||||
|
||||
sleep(2);
|
||||
|
||||
box(0, 0*100, 480, 100, RED, 1);
|
||||
box(0, 1*100, 480, 100, GREEN, 1);
|
||||
box(0, 2*100, 480, 100, BLUE, 1);
|
||||
|
||||
box(0, 0, 480, 320, WHITE, 0);
|
||||
|
||||
line(0, 0, 479, 319, RED | GREEN);
|
||||
line(479, 0, 0, 319, GREEN | BLUE);
|
||||
|
||||
sleep(2);
|
||||
|
||||
// for (;;) line(rand() & 511, rand() & 511, rand() & 511, rand() & 511, rand());
|
||||
|
||||
#if 01
|
||||
time_t t1 = time(NULL), t2;
|
||||
int fps = 0;
|
||||
do
|
||||
{
|
||||
t2 = time(NULL);
|
||||
box(0, 0, 480, 320, rand(), 1);
|
||||
fps++;
|
||||
} while (t2 < t1 + 10);
|
||||
|
||||
printf("%d fps\n", fps / 10);
|
||||
#endif
|
||||
|
||||
sleep(2);
|
||||
|
||||
box(0, 0, 480, 320, BLACK, 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
940
share/examples/c/tftetris.c
Normal file
940
share/examples/c/tftetris.c
Normal file
@@ -0,0 +1,940 @@
|
||||
/*
|
||||
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);
|
||||
}
|
||||
@@ -1,5 +1,10 @@
|
||||
PROG = all backlight cube demo
|
||||
OBJS = gpio.o
|
||||
|
||||
# Duinomite board
|
||||
#OBJS = duinomite.o
|
||||
|
||||
# Fubarino board
|
||||
OBJS = fubarino.o
|
||||
|
||||
all: $(PROG)
|
||||
|
||||
|
||||
@@ -6,8 +6,8 @@ LIBS += -lm
|
||||
|
||||
#all: demo
|
||||
|
||||
demo: demo.o gpio.o
|
||||
${CC} ${LDFLAGS} -o demo.elf demo.o gpio.o ${LIBS}
|
||||
demo: demo.o fubarino.o
|
||||
${CC} ${LDFLAGS} -o demo.elf demo.o fubarino.o ${LIBS}
|
||||
${OBJDUMP} -S demo.elf > demo.dis
|
||||
${SIZE} demo.elf
|
||||
${ELF2AOUT} demo.elf $@
|
||||
|
||||
@@ -112,7 +112,7 @@ void gpio_plane(unsigned char *data)
|
||||
int i, n, val;
|
||||
|
||||
/* Send 8 bytes of tada to shift registers. */
|
||||
for (i=0; i<8; i++) {
|
||||
for (i=0; i<8; i+=2) {
|
||||
val = *data++;
|
||||
for (n=0; n<8; n++) {
|
||||
/* SDI signal at RE5. */
|
||||
@@ -127,5 +127,19 @@ void gpio_plane(unsigned char *data)
|
||||
|
||||
val <<= 1;
|
||||
}
|
||||
val = *data++;
|
||||
for (n=0; n<8; n++) {
|
||||
/* SDI signal at RE5. */
|
||||
if (val & 1)
|
||||
ioctl(gpio, GPIO_PORTE | GPIO_SET, 1 << 5);
|
||||
else
|
||||
ioctl(gpio, GPIO_PORTE | GPIO_CLEAR, 1 << 5);
|
||||
|
||||
/* CLK signal at RE6. */
|
||||
ioctl(gpio, GPIO_PORTE | GPIO_SET, 1 << 6);
|
||||
ioctl(gpio, GPIO_PORTE | GPIO_CLEAR, 1 << 6);
|
||||
|
||||
val >>= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
143
share/examples/cube/fubarino.c
Normal file
143
share/examples/cube/fubarino.c
Normal file
@@ -0,0 +1,143 @@
|
||||
/*
|
||||
* Interface to LED cube 8x8x8.
|
||||
* The cube is connected to pins 4-13 of Fubarino board.
|
||||
*
|
||||
* Pin PIC32 Function
|
||||
* ---------------
|
||||
* 4 RD0 Y0 \
|
||||
* 5 RC13 Y1 | Layer select
|
||||
* 6 RC14 Y2 /
|
||||
* 7 RD1 Y3 - Upper backlignt
|
||||
* 8 RD2 Y4 - Lower backlight
|
||||
* 9 RD3 SDI - Serial data \
|
||||
* 10 RD4 CLK - Clock | to shift registers
|
||||
* 11 RD5 /LE - Latch enable |
|
||||
* 12 RD6 /OE - Output enable /
|
||||
* 13 RD7 EXT - Unknown
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/gpio.h>
|
||||
#include "cube.h"
|
||||
|
||||
static int gpio;
|
||||
|
||||
void gpio_init()
|
||||
{
|
||||
char *devname = "/dev/porta";
|
||||
|
||||
/* Open GPIO driver. */
|
||||
gpio = open(devname, 1);
|
||||
if (gpio < 0) {
|
||||
perror(devname);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
/* Configure pins RD0-RD7, RC13 and RC14 as output. */
|
||||
ioctl(gpio, GPIO_PORTD | GPIO_CONFOUT, 0xff);
|
||||
ioctl(gpio, GPIO_PORTD | GPIO_CLEAR, 0xff);
|
||||
ioctl(gpio, GPIO_PORTC | GPIO_CONFOUT, 3 << 13);
|
||||
ioctl(gpio, GPIO_PORTC | GPIO_CLEAR, 3 << 13);
|
||||
}
|
||||
|
||||
void gpio_ext(int on)
|
||||
{
|
||||
/* EXT signal at RD7. */
|
||||
if (on)
|
||||
ioctl(gpio, GPIO_PORTD | GPIO_SET, 1 << 7);
|
||||
else
|
||||
ioctl(gpio, GPIO_PORTD | GPIO_CLEAR, 1 << 7);
|
||||
}
|
||||
|
||||
void gpio_oe(int active)
|
||||
{
|
||||
/* /OE signal at RD6, active low. */
|
||||
if (active)
|
||||
ioctl(gpio, GPIO_PORTD | GPIO_CLEAR, 1 << 6);
|
||||
else
|
||||
ioctl(gpio, GPIO_PORTD | GPIO_SET, 1 << 6);
|
||||
}
|
||||
|
||||
void gpio_le(int active)
|
||||
{
|
||||
/* /LE signal at RD5, active low. */
|
||||
if (active)
|
||||
ioctl(gpio, GPIO_PORTD | GPIO_CLEAR, 1 << 5);
|
||||
else
|
||||
ioctl(gpio, GPIO_PORTD | GPIO_SET, 1 << 5);
|
||||
}
|
||||
|
||||
void gpio_backlight_upper(int on)
|
||||
{
|
||||
/* Y4 signal at RD2. */
|
||||
if (on)
|
||||
ioctl(gpio, GPIO_PORTD | GPIO_SET, 1 << 2);
|
||||
else
|
||||
ioctl(gpio, GPIO_PORTD | GPIO_CLEAR, 1 << 2);
|
||||
}
|
||||
|
||||
void gpio_backlight_lower(int on)
|
||||
{
|
||||
/* Y3 signal at RD1. */
|
||||
if (on)
|
||||
ioctl(gpio, GPIO_PORTD | GPIO_SET, 1 << 1);
|
||||
else
|
||||
ioctl(gpio, GPIO_PORTD | GPIO_CLEAR, 1 << 1);
|
||||
}
|
||||
|
||||
void gpio_layer(int z)
|
||||
{
|
||||
/* Y0-Y2 signals at RD0, RC13, RC14. */
|
||||
if (z & 1)
|
||||
ioctl(gpio, GPIO_PORTD | GPIO_CLEAR, 1 << 0);
|
||||
else
|
||||
ioctl(gpio, GPIO_PORTD | GPIO_SET, 1 << 0);
|
||||
|
||||
if (z & 2)
|
||||
ioctl(gpio, GPIO_PORTC | GPIO_CLEAR, 1 << 13);
|
||||
else
|
||||
ioctl(gpio, GPIO_PORTC | GPIO_SET, 1 << 13);
|
||||
|
||||
if (z & 4)
|
||||
ioctl(gpio, GPIO_PORTC | GPIO_CLEAR, 1 << 14);
|
||||
else
|
||||
ioctl(gpio, GPIO_PORTC | GPIO_SET, 1 << 14);
|
||||
}
|
||||
|
||||
void gpio_plane(unsigned char *data)
|
||||
{
|
||||
int i, n, val;
|
||||
|
||||
/* Send 8 bytes of tada to shift registers. */
|
||||
for (i=0; i<8; i+=2) {
|
||||
val = *data++;
|
||||
for (n=0; n<8; n++) {
|
||||
/* SDI signal at RD3. */
|
||||
if (val & 0x80)
|
||||
ioctl(gpio, GPIO_PORTD | GPIO_SET, 1 << 3);
|
||||
else
|
||||
ioctl(gpio, GPIO_PORTD | GPIO_CLEAR, 1 << 3);
|
||||
|
||||
/* CLK signal at RD4. */
|
||||
ioctl(gpio, GPIO_PORTD | GPIO_SET, 1 << 4);
|
||||
ioctl(gpio, GPIO_PORTD | GPIO_CLEAR, 1 << 4);
|
||||
|
||||
val <<= 1;
|
||||
}
|
||||
val = *data++;
|
||||
for (n=0; n<8; n++) {
|
||||
/* SDI signal at RD3. */
|
||||
if (val & 1)
|
||||
ioctl(gpio, GPIO_PORTD | GPIO_SET, 1 << 3);
|
||||
else
|
||||
ioctl(gpio, GPIO_PORTD | GPIO_CLEAR, 1 << 3);
|
||||
|
||||
/* CLK signal at RD4. */
|
||||
ioctl(gpio, GPIO_PORTD | GPIO_SET, 1 << 4);
|
||||
ioctl(gpio, GPIO_PORTD | GPIO_CLEAR, 1 << 4);
|
||||
|
||||
val >>= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1225,8 +1225,8 @@ unsigned getexpr (s)
|
||||
void reorder_flush ()
|
||||
{
|
||||
if (reorder_full) {
|
||||
fputword (reorder_word, sfile[segm]);
|
||||
fputrel (&reorder_rel, rfile[segm]);
|
||||
fputword (reorder_word, sfile[STEXT]);
|
||||
fputrel (&reorder_rel, rfile[STEXT]);
|
||||
reorder_full = 0;
|
||||
}
|
||||
}
|
||||
@@ -1945,7 +1945,7 @@ void pass1 ()
|
||||
clex = getlex (&cval);
|
||||
switch (clex) {
|
||||
case LEOF:
|
||||
reorder_flush();
|
||||
done: reorder_flush();
|
||||
segm = STEXT;
|
||||
align (2);
|
||||
segm = SDATA;
|
||||
@@ -1987,7 +1987,7 @@ void pass1 ()
|
||||
stab[cval].n_type &= ~N_TYPE;
|
||||
stab[cval].n_type |= segmtype [segm];
|
||||
continue;
|
||||
} else if (clex=='=' || clex==LEQU) {
|
||||
} else if (clex=='=') {
|
||||
/* Symbol definition. */
|
||||
cval = lookname();
|
||||
stab[cval].n_value = getexpr (&csegm);
|
||||
@@ -1996,22 +1996,6 @@ void pass1 ()
|
||||
stab[cval].n_type &= N_EXT;
|
||||
stab[cval].n_type |= segmtype [csegm];
|
||||
break;
|
||||
} else if (clex==LCOMM) {
|
||||
/* name .comm len */
|
||||
cval = lookname();
|
||||
if (stab[cval].n_type != N_UNDF &&
|
||||
stab[cval].n_type != N_LOC &&
|
||||
(stab[cval].n_type & N_TYPE) != N_COMM)
|
||||
uerror ("name already defined");
|
||||
if (stab[cval].n_type & N_LOC)
|
||||
stab[cval].n_type = N_COMM;
|
||||
else
|
||||
stab[cval].n_type = N_EXT | N_COMM;
|
||||
getexpr (&tval);
|
||||
if (tval != SABS)
|
||||
uerror ("bad .comm length");
|
||||
stab[cval].n_value = intval;
|
||||
break;
|
||||
}
|
||||
/* Machine instruction. */
|
||||
if (cval < 0)
|
||||
@@ -2165,6 +2149,24 @@ void pass1 ()
|
||||
}
|
||||
}
|
||||
break;
|
||||
case LEQU:
|
||||
/* .equ name,value */
|
||||
if (getlex (&cval) != LNAME)
|
||||
uerror ("bad parameter of .equ");
|
||||
cval = lookname();
|
||||
if (stab[cval].n_type != N_UNDF &&
|
||||
stab[cval].n_type != N_LOC &&
|
||||
(stab[cval].n_type & N_TYPE) != N_COMM)
|
||||
uerror ("name already defined");
|
||||
clex = getlex (&tval);
|
||||
if (clex != ',')
|
||||
uerror ("bad value of .equ");
|
||||
stab[cval].n_value = getexpr (&csegm);
|
||||
if (csegm == SEXT)
|
||||
uerror ("indirect equivalence");
|
||||
stab[cval].n_type &= N_EXT;
|
||||
stab[cval].n_type |= segmtype [csegm];
|
||||
break;
|
||||
case LCOMM:
|
||||
/* .comm name,len[,alignment] */
|
||||
if (getlex (&cval) != LNAME)
|
||||
@@ -2338,11 +2340,10 @@ void pass1 ()
|
||||
uerror ("bad syntax");
|
||||
}
|
||||
clex = getlex (&cval);
|
||||
if (clex != LEOL) {
|
||||
if (clex == LEOF)
|
||||
return;
|
||||
if (clex == LEOF)
|
||||
goto done;
|
||||
if (clex != LEOL)
|
||||
uerror ("bad instruction arguments");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <pwd.h>
|
||||
#include <grp.h>
|
||||
#include <syslog.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
@@ -14,6 +13,7 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/resource.h>
|
||||
#include <grp.h>
|
||||
|
||||
char userbuf[64] = "USER=";
|
||||
char homebuf[128] = "HOME=";
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <grp.h>
|
||||
|
||||
#define MAXGRP 200
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
#ifndef _STAT_H_
|
||||
#define _STAT_H_
|
||||
|
||||
#include <sys/time.h>
|
||||
|
||||
struct stat
|
||||
{
|
||||
dev_t st_dev;
|
||||
|
||||
@@ -50,7 +50,10 @@ typedef int ssize_t;
|
||||
#define _SSIZE_T
|
||||
#endif
|
||||
#endif
|
||||
typedef long time_t;
|
||||
#ifndef _TIME_T
|
||||
#define _TIME_T
|
||||
typedef long time_t;
|
||||
#endif
|
||||
typedef int dev_t;
|
||||
#ifndef _OFF_T
|
||||
#define _OFF_T
|
||||
|
||||
@@ -42,6 +42,12 @@ ifeq (/usr/local/mips-2013.11/bin/mips-sde-elf-gcc,$(wildcard /usr/local/mips-20
|
||||
LDFLAGS = -Wl,--oformat=elf32-tradlittlemips
|
||||
endif
|
||||
endif
|
||||
ifndef GCCPREFIX
|
||||
ifeq (/usr/local/mips-2014.05/bin/mips-sde-elf-gcc,$(wildcard /usr/local/mips-2014.05/bin/mips-sde-elf-gcc))
|
||||
GCCPREFIX = /usr/local/mips-2014.05/bin/mips-sde-elf-
|
||||
LDFLAGS = -Wl,--oformat=elf32-tradlittlemips
|
||||
endif
|
||||
endif
|
||||
|
||||
ifndef GCCPREFIX
|
||||
$(error Unable to locate any GCC MIPS toolchain!)
|
||||
|
||||
@@ -52,6 +52,13 @@ ifeq (/usr/local/mips-2013.11/bin/mips-sde-elf-gcc,$(wildcard /usr/local/mips-20
|
||||
INCLUDES =
|
||||
endif
|
||||
endif
|
||||
ifndef GCCPREFIX
|
||||
ifeq (/usr/local/mips-2014.05/bin/mips-sde-elf-gcc,$(wildcard /usr/local/mips-2014.05/bin/mips-sde-elf-gcc))
|
||||
GCCPREFIX = /usr/local/mips-2014.05/bin/mips-sde-elf-
|
||||
LDFLAGS = -Wl,--oformat=elf32-tradlittlemips
|
||||
INCLUDES =
|
||||
endif
|
||||
endif
|
||||
|
||||
ifndef GCCPREFIX
|
||||
$(error Unable to locate any GCC MIPS toolchain!)
|
||||
|
||||
@@ -825,7 +825,7 @@ int main (int argc, char **argv)
|
||||
return -1;
|
||||
}
|
||||
if (! fs_open (&fs, argv[i], (add + mount != 0), pindex)) {
|
||||
fprintf (stderr, "%s: cannot open\n", argv[i]);
|
||||
fprintf (stderr, "%s: cannot open filesystem\n", argv[i]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
@@ -722,7 +722,8 @@ create_file:
|
||||
}
|
||||
if (verbose > 2)
|
||||
printf ("*** name '%.*s' at offset %lu\n", namlen, namptr, offset+sizeof(dirent));
|
||||
if (! fs_inode_write (&dir, offset+sizeof(dirent), (unsigned char*) namptr, namlen)) {
|
||||
if (! fs_inode_write (&dir, offset+sizeof(dirent), (unsigned char*) namptr, namlen) ||
|
||||
! fs_inode_write (&dir, offset+sizeof(dirent)+namlen, (unsigned char*) "", 1)) {
|
||||
fprintf (stderr, "inode %d: write error at offset %ld\n",
|
||||
dir.number, offset+sizeof(dirent));
|
||||
return 0;
|
||||
|
||||
@@ -121,11 +121,11 @@ void dev_sdcard_select (cpu_mips_t *cpu, int unit, int on)
|
||||
sdcard_t *d = &pic32->sdcard[unit];
|
||||
|
||||
if (on) {
|
||||
TRACE ("sdcard%d: (((\n", unit);
|
||||
//TRACE ("sdcard%d: (((\n", unit);
|
||||
d->select = 1;
|
||||
d->count = 0;
|
||||
} else {
|
||||
TRACE ("sdcard%d: )))\n", unit);
|
||||
//TRACE ("sdcard%d: )))\n", unit);
|
||||
d->select = 0;
|
||||
}
|
||||
}
|
||||
@@ -142,7 +142,7 @@ unsigned dev_sdcard_io (cpu_mips_t *cpu, unsigned data)
|
||||
unsigned reply;
|
||||
|
||||
if (! d || ! d->fd) {
|
||||
TRACE ("sdcard: unselected i/o\n");
|
||||
//TRACE ("sdcard: unselected i/o\n");
|
||||
return 0xFF;
|
||||
}
|
||||
data = (unsigned char) data;
|
||||
@@ -354,6 +354,6 @@ unsigned dev_sdcard_io (cpu_mips_t *cpu, unsigned data)
|
||||
break;
|
||||
}
|
||||
}
|
||||
TRACE ("sdcard%d: send %02x, reply %02x\n", d->unit, data, reply);
|
||||
//TRACE ("sdcard%d: send %02x, reply %02x\n", d->unit, data, reply);
|
||||
return reply;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user