avr-game

annotate avrgame.c @ 2:363acf3e61d4

wha?
author John Tsiombikas <nuclear@member.fsf.org>
date Fri, 20 Mar 2015 21:03:38 +0200
parents 872e425f0e7f
children
rev   line source
nuclear@2 1 #include <string.h>
nuclear@0 2 #include <avr/io.h>
nuclear@1 3 #include <avr/interrupt.h>
nuclear@0 4 #include <util/delay.h>
nuclear@0 5 #include "dotmatrix.h"
nuclear@0 6
nuclear@0 7 /* hardware setup
nuclear@0 8 * - Port B[1,5]: lcd signals (see dotmatrix.h)
nuclear@0 9 * - B1: clk
nuclear@0 10 * - B2: Din
nuclear@0 11 * - B3: DC
nuclear@0 12 * - B4: CE
nuclear@0 13 * - B5: RST
nuclear@1 14 * - Port C[0,3]: buttons
nuclear@0 15 */
nuclear@0 16
nuclear@1 17 enum {
nuclear@1 18 BN_LEFT,
nuclear@1 19 BN_RIGHT,
nuclear@1 20 BN_ROT,
nuclear@1 21 BN_DROP
nuclear@1 22 };
nuclear@1 23
nuclear@1 24 void redraw(void);
nuclear@2 25 void draw_field(void);
nuclear@2 26 void putpixel(int x, int y, int c);
nuclear@0 27 /*int lcd_stream_write(char c, FILE *fp);*/
nuclear@1 28 /*FILE stream_lcd = FDEV_SETUP_STREAM(lcd_stream_write, NULL, _FDEV_SETUP_WRITE);*/
nuclear@0 29
nuclear@2 30 #define FB_SIZE (DM_WIDTH * DM_HEIGHT / 8)
nuclear@2 31 static unsigned char fb[FB_SIZE];
nuclear@2 32
nuclear@2 33 /* gameplay */
nuclear@2 34 static int bx = DM_WIDTH / 2, by = DM_HEIGHT / 2, brot;
nuclear@2 35 #define FIELD_WIDTH 10
nuclear@2 36 #define FIELD_HEIGHT 20
nuclear@2 37 static unsigned char field[FIELD_WIDTH][FIELD_HEIGHT];
nuclear@0 38
nuclear@0 39 int main(void)
nuclear@0 40 {
nuclear@0 41 /* stdout = stderr = &stream_lcd; */
nuclear@2 42 DDRD = 0xf0; /* lower nibble input */
nuclear@2 43 PORTD = 0xf0; /* disable 4 lower pull-ups */
nuclear@1 44
nuclear@1 45 /* enable pin change interrupts (PCINT2) */
nuclear@1 46 PCICR = (1 << PCIE2);
nuclear@1 47 /* unmask interrupts PCINT16-19 (first 4 bits) */
nuclear@1 48 PCMSK2 = 0xf;
nuclear@0 49
nuclear@0 50 dm_init();
nuclear@2 51 dm_test();
nuclear@2 52 for(;;);
nuclear@1 53
nuclear@1 54 sei();
nuclear@0 55
nuclear@0 56 for(;;) {
nuclear@1 57 redraw();
nuclear@2 58 _delay_ms(1);
nuclear@0 59 }
nuclear@0 60
nuclear@0 61 return 0;
nuclear@0 62 }
nuclear@0 63
nuclear@1 64 void redraw(void)
nuclear@1 65 {
nuclear@2 66 memset(fb, 0, FB_SIZE);
nuclear@2 67 draw_field();
nuclear@2 68
nuclear@2 69 dm_copy(0, 0, fb, FB_SIZE);
nuclear@1 70 }
nuclear@1 71
nuclear@2 72 #define HSPANS 6
nuclear@2 73 void draw_field(void)
nuclear@2 74 {
nuclear@2 75 int i, j;
nuclear@2 76 unsigned char *fbptr = fb;
nuclear@2 77
nuclear@2 78 /* draw borders */
nuclear@2 79 memset(fbptr, 0xff, HSPANS * 2); /* fill 2 full lines */
nuclear@2 80 fbptr += HSPANS * 2;
nuclear@2 81 fbptr[0] = 0x03; fbptr[HSPANS - 1] = 0xc0;
nuclear@2 82 fbptr += HSPANS;
nuclear@2 83 *fbptr++ = 0xfb;
nuclear@2 84 for(i=0; i<HSPANS - 2; i++) {
nuclear@2 85 *fbptr++ = 0xff;
nuclear@2 86 }
nuclear@2 87 *fbptr++ = 0xdf;
nuclear@2 88
nuclear@2 89
nuclear@2 90 for(i=0; i<DM_HEIGHT - 4; i++) {
nuclear@2 91 fbptr[0] = 0x0b; /* left border flipped(11010000) */
nuclear@2 92 fbptr[HSPANS - 1] = 0xd0; /* right border flipped(00001011) */
nuclear@2 93 fbptr += DM_WIDTH / 8;
nuclear@2 94 }
nuclear@2 95 return;
nuclear@2 96
nuclear@2 97 fbptr = fb;
nuclear@2 98 for(i=0; i<FIELD_HEIGHT * 4; i++) {
nuclear@2 99 int y = i / 4;
nuclear@2 100
nuclear@2 101 for(j=0; j<FIELD_WIDTH / 2; j++) {
nuclear@2 102 int x = j * 2;
nuclear@2 103 unsigned char span;
nuclear@2 104 if(field[x][y]) span |= 0xf0;
nuclear@2 105 if(field[x + 1][y]) span |= 0xf;
nuclear@2 106 fbptr[j] = span;
nuclear@2 107 }
nuclear@2 108 fbptr += DM_WIDTH / 8;
nuclear@2 109 }
nuclear@2 110 }
nuclear@2 111
nuclear@2 112 void putpixel(int x, int y, int c)
nuclear@2 113 {
nuclear@2 114 unsigned char *pptr = fb + y * DM_WIDTH / 8 + x / 8;
nuclear@2 115 int bit = x % 8;
nuclear@2 116 *pptr = (*pptr & ~bit) | ((c & 1) << bit);
nuclear@2 117 }
nuclear@2 118
nuclear@2 119
nuclear@1 120 ISR(PCINT2_vect)
nuclear@1 121 {
nuclear@2 122 static unsigned char prev_st;
nuclear@2 123 unsigned char st, diff;
nuclear@1 124
nuclear@2 125 st = PIND & 0xf;
nuclear@2 126 diff = st ^ prev_st;
nuclear@2 127 prev_st = st;
nuclear@2 128
nuclear@2 129 if(diff & (1 << BN_LEFT) & st) {
nuclear@1 130 bx -= 1;
nuclear@1 131 }
nuclear@2 132 if(diff & (1 << BN_RIGHT) & st) {
nuclear@1 133 bx += 1;
nuclear@1 134 }
nuclear@2 135 if(diff & (1 << BN_ROT) & st) {
nuclear@1 136 brot = (brot + 1) % 4;
nuclear@1 137 }
nuclear@2 138 if(diff & (1 << BN_DROP) & st) {
nuclear@2 139 by -= 1;
nuclear@1 140 }
nuclear@1 141 }
nuclear@1 142
nuclear@0 143 #if 0
nuclear@0 144 int lcd_stream_write(char c, FILE *fp)
nuclear@0 145 {
nuclear@0 146 return 0;
nuclear@0 147 }
nuclear@0 148 #endif