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
|