ready for presentation (we've some smaller bugs..)
This commit is contained in:
parent
6ded692102
commit
57ea664f53
11 changed files with 144 additions and 96 deletions
6
.gitignore
vendored
Normal file
6
.gitignore
vendored
Normal file
|
@ -0,0 +1,6 @@
|
|||
obj/
|
||||
*.hex
|
||||
*.bin
|
||||
*.elf
|
||||
*.lss
|
||||
*.o
|
4
Makefile
4
Makefile
|
@ -62,7 +62,7 @@ TARGET = main
|
|||
OBJDIR = obj
|
||||
|
||||
# List C source files here (C dependencies are automatically generated)
|
||||
SRC = $(TARGET).c tetris.c display.c
|
||||
SRC = $(TARGET).c tetris.c display.c conway.c
|
||||
|
||||
# List C++ source files here (C dependencies are automatically generated)
|
||||
CPPSRC =
|
||||
|
@ -248,7 +248,7 @@ AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex
|
|||
|
||||
# Uncomment the following if you do /not/ wish a verification to be
|
||||
# performed after programming the device.
|
||||
#AVRDUDE_NO_VERIFY = -V
|
||||
AVRDUDE_NO_VERIFY = -V
|
||||
|
||||
# Increase verbosity level
|
||||
#AVRDUDE_VERBOSE = -v -v
|
||||
|
|
24
conway.c
24
conway.c
|
@ -1,4 +1,9 @@
|
|||
#include <avr/io.h>
|
||||
#include <util/delay.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "main.h"
|
||||
#include "display.h"
|
||||
#include "conway.h"
|
||||
|
||||
volatile extern uint8_t *volatile display_buffer; /* Buffer für Display */
|
||||
|
@ -62,14 +67,8 @@ void conway_start() {
|
|||
|
||||
uint8_t i = 0;
|
||||
|
||||
/* populate world */
|
||||
/* with pattern
|
||||
worlds[i][1] |= 0b00001100;
|
||||
worlds[i][2] |= 0b00011000;
|
||||
worlds[i][3] |= 0b00001000;*/
|
||||
|
||||
/* by random */
|
||||
for (uint8_t q = 0; q < 8; q++) {
|
||||
for (uint8_t q = 0; q < 32; q++) {
|
||||
uint8_t row = rand() % 16;
|
||||
uint8_t col = rand() % 8;
|
||||
display_set(col, row, 1);
|
||||
|
@ -83,8 +82,17 @@ void conway_start() {
|
|||
i = 1 - i; // switch world
|
||||
|
||||
if (~PINB & KEY_Y) {
|
||||
_delay_ms(10);
|
||||
return; // exit
|
||||
}
|
||||
if (~PINB & KEY_A) {
|
||||
worlds[i][7] |= 0b00001100;
|
||||
worlds[i][8] |= 0b00011000;
|
||||
worlds[i][9] |= 0b00001000;
|
||||
}
|
||||
if (~PINB & KEY_B) {
|
||||
worlds[i][7] |= 0b00010000;
|
||||
worlds[i][8] |= 0b00001000;
|
||||
worlds[i][9] |= 0b00111000;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
4
conway.h
4
conway.h
|
@ -1,4 +1,6 @@
|
|||
#include <stdint.h>
|
||||
|
||||
uint8_t conway_cell_neighbours(uint8_t x, uint8_t y, uint8_t *world);
|
||||
uint8_t conway_next_cell_gen(uint8_t x, uint8_t y, uint8_t *world);
|
||||
void conway_next_gen(uint8_t *world, uint8_t *next_gen);
|
||||
void conway_start();
|
||||
void conway_start( void );
|
||||
|
|
89
display.c
89
display.c
|
@ -1,14 +1,30 @@
|
|||
#include <avr/io.h>
|
||||
#include <avr/interrupt.h>
|
||||
#include <util/delay.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "display.h"
|
||||
#include "font.h"
|
||||
#include "tetris.h"
|
||||
|
||||
volatile uint8_t *volatile display_buffer; /* Buffer für Display */
|
||||
|
||||
extern volatile board_t brd;
|
||||
extern volatile stone_t stn;
|
||||
|
||||
void display_set(uint8_t col, uint8_t row, uint8_t val) {
|
||||
if (val) {
|
||||
display_buffer[row] |= (1 << col);
|
||||
}
|
||||
else {
|
||||
display_buffer[row] &= ~(1 << col);
|
||||
}
|
||||
}
|
||||
|
||||
void display_toggle(uint8_t col, uint8_t row) {
|
||||
display_buffer[row] ^= (1 << col);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialisiere Display im Multiplexing Modus
|
||||
*/
|
||||
|
@ -35,32 +51,44 @@ uint8_t * display_print(char *text, uint8_t *buffer) {
|
|||
|
||||
strupr(text); /* Nur Großbuchstaben sind verfügbar */
|
||||
|
||||
for (uint16_t c = 0; c < len; c++) {
|
||||
char chr = text[len-c-1];
|
||||
uint8_t pattern;
|
||||
for (uint16_t c = len-1; c >= 0; c--) {
|
||||
char p = text[c];
|
||||
char q = (p >= ' ' && p <= '_') ? p - ' ' : 0;
|
||||
|
||||
if (chr >= ' ' && chr <= '_')
|
||||
pattern = chr - ' ';
|
||||
else
|
||||
pattern = 0; /* space */
|
||||
|
||||
for (uint8_t p = 0; p < 3; p++) {
|
||||
buffer[p+c*4+16] = font[pattern][p];
|
||||
}
|
||||
//buffer[c*4+16] = 0; /* padding */
|
||||
mempcpy(buffer[c*4], font[q], 3);
|
||||
}
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
void display_laufschrift(uint8_t *buffer, uint16_t bytes, uint8_t speed, uint8_t rounds) {
|
||||
display_buffer = buffer;
|
||||
while(1) {
|
||||
if (display_buffer == buffer) {
|
||||
display_buffer = buffer+bytes-16;
|
||||
if (rounds-- == 0) {
|
||||
return;
|
||||
void display_laufschrift(char *text, uint8_t speed, uint8_t rounds) {
|
||||
uint16_t len = 4 * strlen(text) + 16; // 4 Bytes pro Character + 2 * 16 Bytes Padding
|
||||
uint8_t *orig_buffer = display_buffer;
|
||||
|
||||
volatile uint8_t *buffer = malloc(len);
|
||||
|
||||
memset(buffer, 0, len);
|
||||
display_buffer = display_print("test", buffer);
|
||||
|
||||
while ( TRUE ) {
|
||||
buffer[15]++;
|
||||
_delay_ms(500);
|
||||
}
|
||||
|
||||
//display_roll(buffer, len, speed, rounds);
|
||||
|
||||
display_buffer = orig_buffer; /* reset to old buffer */
|
||||
free(buffer);
|
||||
}
|
||||
|
||||
void display_roll(uint16_t bytes, uint8_t speed, uint8_t rounds) {
|
||||
uint8_t *end_buffer = display_buffer;
|
||||
display_buffer += bytes - 16;
|
||||
|
||||
while (rounds) {
|
||||
if (display_buffer == end_buffer) {
|
||||
display_buffer = end_buffer + bytes - 16;
|
||||
rounds--;
|
||||
}
|
||||
|
||||
display_buffer--;
|
||||
|
@ -73,32 +101,27 @@ void display_laufschrift(uint8_t *buffer, uint16_t bytes, uint8_t speed, uint8_t
|
|||
*/
|
||||
ISR(TIMER0_COMP_vect) {
|
||||
static uint8_t column;
|
||||
static uint8_t counter;
|
||||
|
||||
uint8_t row_mask = (1 << column);
|
||||
uint16_t column_mask = 0;
|
||||
|
||||
for (uint8_t i = 4; i < NUM_LINES; i++) {
|
||||
if (row_mask & brd[i]) { /* fixed pixels, dimmed */
|
||||
column_mask |= (1 << (i-4));
|
||||
for (uint8_t i = 0; i < 16; i++) {
|
||||
if (row_mask & display_buffer[i]) { /* fixed pixels, dimmed */
|
||||
column_mask |= (1 << i);
|
||||
}
|
||||
|
||||
if (tetris) { /* in tetris mode ? */
|
||||
if (i >= tetris->stn.pos_y && i < tetris->stn.pos_y+4) { /* in clipping of falling stone ? */
|
||||
if (row_mask & tetris->stn.clipping[i-stn.pos_y]) {
|
||||
column_mask |= (1 << (i-4));
|
||||
}
|
||||
if (i+4 >= stn.pos_y && i < stn.pos_y) { /* in clipping of falling stone ? */
|
||||
if (row_mask & stn.clipping[i+4-stn.pos_y]) {
|
||||
column_mask |= (1 << i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PORTD = 0;
|
||||
PORTC = (uint8_t) column_mask;
|
||||
PORTA = (uint8_t) (column_mask >> 8);
|
||||
PORTD = row_mask;
|
||||
|
||||
column++;
|
||||
if (column == 8) {
|
||||
column = 0;
|
||||
counter++;
|
||||
}
|
||||
column %= 8;
|
||||
}
|
||||
|
|
|
@ -1,8 +1,12 @@
|
|||
#ifndef _DISPLAY_H_
|
||||
#define _DISPLAY_H_
|
||||
|
||||
void display_set(uint8_t col, uint8_t row, uint8_t val);
|
||||
void display_toggle(uint8_t col, uint8_t row);
|
||||
|
||||
void display_init( void );
|
||||
void display_laufschrift(uint8_t *buffer, uint16_t bytes, uint8_t speed, uint8_t rounds);
|
||||
void display_laufschrift(char * text, uint8_t speed, uint8_t rounds);
|
||||
void display_roll(uint16_t bytes, uint8_t speed, uint8_t rounds);
|
||||
uint8_t * display_print(char *text, uint8_t *buffer);
|
||||
|
||||
#endif /* _DISPLAY_H_ */
|
||||
|
|
2
font.h
2
font.h
|
@ -301,7 +301,7 @@ const uint8_t font[][3] = {
|
|||
0b01111111,
|
||||
0b00000000
|
||||
},
|
||||
{ // \
|
||||
{
|
||||
0b00000011,
|
||||
0b00011100,
|
||||
0b01100000
|
||||
|
|
44
main.c
44
main.c
|
@ -1,11 +1,16 @@
|
|||
#include <avr/io.h>
|
||||
#include <util/delay.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "main.h"
|
||||
#include "display.h"
|
||||
#include "tetris.h"
|
||||
#include "conway.h"
|
||||
|
||||
static uint8_t rwth_logo[] = {0x7c, 0x50, 0x2c, 0x00, 0x78, 0x04, 0x18, 0x04, 0x78, 0x40, 0x7c, 0x40, 0x7c, 0x10, 0x7c, 0x00};
|
||||
volatile extern uint8_t *volatile display_buffer; /* Buffer für Display */
|
||||
|
||||
static uint8_t rwth_logo[] = {0x00, 0x7c, 0x10, 0x7c, 0x40, 0x7c, 0x40, 0x78, 0x04, 0x18, 0x04, 0x78, 0x00, 0x2c, 0x50, 0x7c};
|
||||
static char bill_txt[] = "'Nobody will ever need more than 640k RAM!' - Bill Gates, 1981 ;-)";
|
||||
|
||||
uint8_t get_seed() {
|
||||
uint8_t seed = 0;
|
||||
|
@ -18,6 +23,22 @@ uint8_t get_seed() {
|
|||
return seed;
|
||||
}
|
||||
|
||||
void random_start() {
|
||||
volatile uint8_t random_buffer[16];
|
||||
display_buffer = memset(random_buffer, 0, 16);
|
||||
|
||||
while ( TRUE ) {
|
||||
uint8_t row = rand() % 16;
|
||||
uint8_t col = rand() % 8;
|
||||
display_toggle(col, row);
|
||||
|
||||
if (~PINB & KEY_Y) {
|
||||
break;
|
||||
}
|
||||
_delay_ms(20);
|
||||
}
|
||||
}
|
||||
|
||||
int main( void ) {
|
||||
display_init();
|
||||
srand(get_seed());
|
||||
|
@ -33,28 +54,17 @@ int main( void ) {
|
|||
|
||||
/* Demo 1: Tetris */
|
||||
tetris_start();
|
||||
_delay_ms(300);
|
||||
|
||||
/* Demo 4: Conways Game of Life */
|
||||
conway_start();
|
||||
_delay_ms(300);
|
||||
|
||||
/* Demo 2: Laufschrift */
|
||||
/*char text[] = "'Nobody will ever need more than 640k RAM!' - Bill Gates, 1981 ;-)";
|
||||
uint16_t len = 4*strlen(text)+32; // 4 Bytes pro Character + 2 * 16 Bytes Padding
|
||||
volatile uint8_t text_buffer[len];
|
||||
display_print(text, text_buffer);
|
||||
|
||||
// Starte Laufschrift
|
||||
display_laufschrift(text_buffer, len, 120, 1);*/
|
||||
/// display_laufschrift("test", 120, 1);
|
||||
|
||||
/* Demo 3: Zufall */
|
||||
/*volatile uint8_t random_buffer[16];
|
||||
display_buffer = memset(random_buffer, 0, 16);
|
||||
srand(get_seed());
|
||||
|
||||
for (uint16_t i = 0; i < 450; i++) {
|
||||
display_toggle(rand()%8, rand()%16);
|
||||
display_buffer[0] = i;
|
||||
_delay_ms(20);
|
||||
}*/
|
||||
random_start();
|
||||
_delay_ms(300);
|
||||
}
|
||||
}
|
||||
|
|
BIN
tetris
BIN
tetris
Binary file not shown.
52
tetris.c
52
tetris.c
|
@ -4,9 +4,12 @@
|
|||
|
||||
#include "tetris.h"
|
||||
|
||||
volatile tetris_t *volatile tetris = NULL;
|
||||
extern volatile uint8_t *volatile display_buffer; /* Buffer für Display */
|
||||
|
||||
//static int16_t scoring[] = {0, 40, 100, 300, 1200}; /* scoring multiplicator for 0-4 flushed lines */
|
||||
volatile uint8_t *volatile brd = NULL; /* NULL if not in tetris mode */
|
||||
volatile stone_t stn;
|
||||
|
||||
static int16_t scoring[] = {0, 40, 100, 300, 1200}; /* scoring multiplicator for 0-4 flushed lines */
|
||||
|
||||
static clipping_t shapes[][4] = { /* including 4 ccw rotations */
|
||||
{ // SHAPE_I
|
||||
|
@ -101,7 +104,7 @@ bool_t tetris_turn_stone() {
|
|||
}
|
||||
}
|
||||
|
||||
copy_clipping(tmp, stn.clipping);
|
||||
tetris_copy_clipping(tmp, stn.clipping);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -168,22 +171,17 @@ bool_t tetris_detect_collision(direction_t dir) {
|
|||
}
|
||||
|
||||
void tetris_start() {
|
||||
tetris_t state;
|
||||
|
||||
uint8_t debounce = 0;
|
||||
uint8_t lines = 0;
|
||||
uint8_t frames = 48;
|
||||
uint8_t score = 0;
|
||||
uint8_t level = 0;
|
||||
//uint16_t score = 0;
|
||||
//uint16_t stones = 0;
|
||||
uint16_t lines = 0;
|
||||
uint8_t debounce;
|
||||
|
||||
tetris = &state;
|
||||
display_buffer = state.brd+4; /* skipping "virtual" lines */
|
||||
brd = malloc(sizeof(board_t));
|
||||
display_buffer = brd+4; /* skipping first 4 "virtual" lines */
|
||||
|
||||
/* starting with empty board */
|
||||
for (uint8_t i = 0; i < NUM_LINES; i++) {
|
||||
brd[i] = 0;
|
||||
}
|
||||
memset(brd, 0, NUM_LINES);
|
||||
|
||||
while ( TRUE ) { /* main loop */
|
||||
/* add new stone on the top of our board */
|
||||
|
@ -195,7 +193,7 @@ void tetris_start() {
|
|||
stn.pos_x = 0;
|
||||
stn.pos_y = 0;
|
||||
|
||||
copy_clipping(shapes[shape][orientation], stn.clipping);
|
||||
tetris_copy_clipping(shapes[shape][orientation], stn.clipping);
|
||||
|
||||
if (lines > (level + 1) * 10) {
|
||||
level++; /* next level */
|
||||
|
@ -233,16 +231,17 @@ void tetris_start() {
|
|||
}
|
||||
}
|
||||
if (keys & KEY_Y) {
|
||||
_delay_ms(10);
|
||||
free(brd);
|
||||
memset(stn.clipping, 0, 4);
|
||||
return; // exit tetris
|
||||
}
|
||||
|
||||
if (keys) {
|
||||
debounce = 6
|
||||
debounce = 9;
|
||||
}
|
||||
}
|
||||
|
||||
_delay_ms(900 / FRAMES); // sleep for 1 frame (10% for calculations)
|
||||
_delay_ms(900 / FRAMES); // sleep for 1 frame (100ms approx for calculations)
|
||||
}
|
||||
} while (tetris_detect_collision(DIR_DOWN) == FALSE);
|
||||
|
||||
|
@ -251,17 +250,18 @@ void tetris_start() {
|
|||
}
|
||||
|
||||
/* check for completed lines and calculate score */
|
||||
uint8_t flushed = flush_lines();
|
||||
//score += (level + 1) * scoring[flushed];
|
||||
//stones++;
|
||||
uint8_t flushed = tetris_flush_lines();
|
||||
score += (level + 1) * scoring[flushed];
|
||||
lines += flushed;
|
||||
|
||||
if (brd[3] > 0) {
|
||||
//return; /* game over */
|
||||
for (uint8_t i = 0; i < NUM_LINES; i++) { /* restart with empty board */
|
||||
brd[i] = 0; /* starting with empty board */
|
||||
}
|
||||
_delay_ms(1000);
|
||||
free(brd);
|
||||
memset(stn.clipping, 0, 4);
|
||||
return; /* game over */
|
||||
}
|
||||
}
|
||||
|
||||
free(brd);
|
||||
brd = NULL;
|
||||
return;
|
||||
}
|
||||
|
|
5
tetris.h
5
tetris.h
|
@ -12,11 +12,6 @@
|
|||
typedef uint8_t board_t[NUM_LINES];
|
||||
typedef uint8_t clipping_t[4];
|
||||
|
||||
typedef struct {
|
||||
stone_t stn;
|
||||
board_t brd;
|
||||
} tetris_t;
|
||||
|
||||
/* Named according to: http://de.wikipedia.org/wiki/Tetris */
|
||||
typedef enum {
|
||||
SHAPE_I, /* line of four dots */
|
||||
|
|
Loading…
Add table
Reference in a new issue