commit e7a7000ff55411a613f4ab2999234c778a7359dc Author: Steffen Vogel Date: Thu May 19 22:16:25 2011 +0200 initial commit diff --git a/main.c b/main.c new file mode 100644 index 0000000..8479bf6 --- /dev/null +++ b/main.c @@ -0,0 +1,200 @@ +#include +#include +#include +#include +#include + +#include "main.h" + +static stone_t shapes[NUM_SHAPES] = { + {SHAPE_I, { + 0b00000000, + 0b00000000, + 0b00000000, + 0b00111100 + }, 0}, + {SHAPE_J, { + 0b00000000, + 0b00001000, + 0b00001000, + 0b00011000 + }, 0 + }, + {SHAPE_L, { + 0b00000000, + 0b00010000, + 0b00010000, + 0b00011000 + }, 0}, + {SHAPE_O, { + 0b00000000, + 0b00000000, + 0b00011000, + 0b00011000 + }, 0}, + {SHAPE_S, { + 0b00000000, + 0b00000000, + 0b00011000, + 0b00110000 + }, 0}, + {SHAPE_T, { + 0b00000000, + 0b00000000, + 0b00010000, + 0b00111000 + }, 0}, + {SHAPE_Z, { + 0b00000000, + 0b00000000, + 0b00011000, + 0b00001100 + }, 0} + +}; + +void draw_screen(board_t brd, stone_t stn, uint16_t score, uint8_t level, uint8_t stones) { + /* clear screen */ + clear(); + + for (uint8_t i = 0; i < NUM_LINES; i++) { + addch('|'); + + for (uint8_t j = 0; j < 8; j++) { + + if (brd[i] & (1 << j)) { /* fixed pixel */ + addch('#'); + } + else if (i >= stn.pos && i < stn.pos+4 && stn.clipping[i-stn.pos] & (1 << j)) { + addch('0'); + } + else { + addch(' '); + } + } + + printw("%c\n", (i == 3) ? '-' : '|'); + } + + printw("----------"); + printw("\nScore: %i\tLevel: %i\tStones: %i\n", score, level, stones); +} + +uint8_t flush_lines(board_t brd) { + uint8_t lines = 0; + + for (uint8_t i = NUM_LINES-1; i >= 0; i--) { + if (brd[i] == 0xFF) { + lines++; + + //for () { /* restock with remaining lines */ + + //} + } + else if (brd[i] == 0x00) { /* empty line, no following line can be non-empty => aborting */ + break; + } + } + + return lines; /* required to calculate score */ +} + +bool_t turn_stone(stone_t s) { + +} + +bool_t shift_stone(stone_t stn, direction_t dir) { + if (dir == DIR_DOWN) { + stn.pos++; + } + else { + for (uint8_t i = 0; i < 4; i++) { + if (dir == DIR_LEFT) { + stn.clipping[i] <<= 1; + } + else if (dir == DIR_RIGHT) { + stn.clipping[i] >>= 1; + } + } + } + stn.clipping[3] = 0; +} + +bool_t detect_collision(board_t brd, stone_t stn) { + return FALSE; // TODO implement +} + +WINDOW * init_screen() { + WINDOW * win = initscr(); + noecho(); + cbreak(); + timeout(0); + keypad(win, 1); + curs_set(0); + + return win; +} + +void main() { + board_t brd; + stone_t falling; + uint8_t level = 0; + uint16_t score = 0; + uint16_t stones = 0; + uint16_t steps = 0; + + memset(&brd, 0, NUM_LINES); /* init board */ + WINDOW * win = init_screen(); /* init terminal */ + + /* init prng */ + // TODO init with adc value & eeprom seed + srand(129); + + while (TRUE) { + /* add new stone on the top of our board */ + falling = shapes[rand() % NUM_SHAPES]; + + if (stones > level * 10) { + level++; /* next level */ + } + + while (detect_collision(brd, falling) == FALSE) { + /* lets fall stone */ + falling.pos++; + + draw_screen(brd, falling, score, level, stones); + printw("Steps: %i\n", steps++); + + /* poll for user interaction */ + switch (getch()) { + case KEY_UP: + turn_stone(falling); + break; + case KEY_LEFT: + shift_stone(falling, DIR_LEFT); + break; + case KEY_RIGHT: + shift_stone(falling, DIR_RIGHT); + break; + case KEY_DOWN: + shift_stone(falling, DIR_DOWN); + break; + } + flushinp(); + refresh(); + usleep(800000); + } + + /* check for completed lines and calculate score */ + uint8_t lines = flush_lines(brd); + score += lines * lines; + + if (brd[3] > 0) { + break; /* game over */ + } + } + + // TODO handle highscore + + endwin(); /* reset terminal */ +} diff --git a/main.h b/main.h new file mode 100644 index 0000000..7029086 --- /dev/null +++ b/main.h @@ -0,0 +1,47 @@ +#ifndef _MAIN_H_ +#define _MAIN_H_ + +#include + +#define TRUE 1 +#define FALSE 0 + +#define NUM_SHAPES 7 +#define NUM_LINES 20 /* 16 visible + 4 to spawn new stones */ + +typedef uint8_t board_t[NUM_LINES]; +typedef uint8_t bool_t; + +/* Named according to: http://de.wikipedia.org/wiki/Tetris */ +typedef enum { + SHAPE_I, /* line of four dots */ + SHAPE_J, /* inverted L */ + SHAPE_L, + SHAPE_O, /* cubeoid */ + SHAPE_S, + SHAPE_T, + SHAPE_Z /* inverted S */ +} shape_t; + +typedef enum { + DIR_LEFT, + DIR_RIGHT, + DIR_DOWN +} direction_t; + +typedef struct { + shape_t shape; + uint8_t clipping[4]; + uint8_t pos; +} stone_t; + +uint8_t flush_lines(board_t brd); +bool_t turn_stone(stone_t stn); +bool_t shift_stone(stone_t stn, direction_t dir); +bool_t detect_collision(board_t brd, stone_t stn); + +/* platform dependent */ +void draw_screen(board_t brd, stone_t stn, uint16_t score, uint8_t level, uint8_t stones); + + +#endif /* _MAIN_H_ */ diff --git a/tetris b/tetris new file mode 100755 index 0000000..cae565c Binary files /dev/null and b/tetris differ