From 84445ee1f72fe4d5b15fc2a5ad4b1885cebba29c Mon Sep 17 00:00:00 2001 From: Sergey Date: Sun, 21 Jun 2015 20:00:36 -0700 Subject: [PATCH] Fixed bug in fsutil, occasionally resulted in unexpected fsck errors. It was caused by garbage at end of file names. --- rootfs.manifest | 5 +- share/examples/c/tft.c | 219 ++++++++ share/examples/c/tftetris.c | 940 +++++++++++++++++++++++++++++++++ tools/fsutil/inode.c | 3 +- tools/virtualmips/dev_sdcard.c | 8 +- 5 files changed, 1169 insertions(+), 6 deletions(-) create mode 100644 share/examples/c/tft.c create mode 100644 share/examples/c/tftetris.c diff --git a/rootfs.manifest b/rootfs.manifest index ab54d51..a606843 100644 --- a/rootfs.manifest +++ b/rootfs.manifest @@ -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 diff --git a/share/examples/c/tft.c b/share/examples/c/tft.c new file mode 100644 index 0000000..40eba94 --- /dev/null +++ b/share/examples/c/tft.c @@ -0,0 +1,219 @@ +#include +#include +#include +#include +#include +#include + +#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; +} diff --git a/share/examples/c/tftetris.c b/share/examples/c/tftetris.c new file mode 100644 index 0000000..7054ed6 --- /dev/null +++ b/share/examples/c/tftetris.c @@ -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 +#include +#include +#include +#include + +volatile int quit = 0; +volatile int jx = 0, jy = 0; + +#include +#include +#include + +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); +} diff --git a/tools/fsutil/inode.c b/tools/fsutil/inode.c index d28c93f..806c3aa 100644 --- a/tools/fsutil/inode.c +++ b/tools/fsutil/inode.c @@ -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; diff --git a/tools/virtualmips/dev_sdcard.c b/tools/virtualmips/dev_sdcard.c index 82b8f9b..4e4eeeb 100644 --- a/tools/virtualmips/dev_sdcard.c +++ b/tools/virtualmips/dev_sdcard.c @@ -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; }