Port of Artekit space invaders demo (http://www.artekit.eu/space-invaders-for-stm32/) for the STM32F3 Discovery board. Also shows game of life if started with the user button pressed.

Dependencies:   STM32F3-Discovery

Committer:
MartinJohnson
Date:
Tue May 17 23:53:10 2016 +0000
Revision:
2:1c1f7677ac17
Parent:
1:1b37c4b989b4
Remove old logo

Who changed what in which revision?

UserRevisionLine numberNew contents of line
MartinJohnson 1:1b37c4b989b4 1 #include "stm32f30x.h"
MartinJohnson 1:1b37c4b989b4 2 #include "video.h"
MartinJohnson 1:1b37c4b989b4 3
MartinJohnson 1:1b37c4b989b4 4 typedef unsigned Unit;
MartinJohnson 1:1b37c4b989b4 5
MartinJohnson 1:1b37c4b989b4 6 #define cols 416
MartinJohnson 1:1b37c4b989b4 7 #define rows 300
MartinJohnson 1:1b37c4b989b4 8 #define bits 32
MartinJohnson 1:1b37c4b989b4 9
MartinJohnson 1:1b37c4b989b4 10 extern char *fb[VID_VSIZE*2];
MartinJohnson 1:1b37c4b989b4 11
MartinJohnson 1:1b37c4b989b4 12 typedef struct {
MartinJohnson 1:1b37c4b989b4 13 Unit sum;
MartinJohnson 1:1b37c4b989b4 14 Unit carry;
MartinJohnson 1:1b37c4b989b4 15 } AddResult;
MartinJohnson 1:1b37c4b989b4 16
MartinJohnson 1:1b37c4b989b4 17 static void half_add(AddResult *c,Unit a, Unit b) {
MartinJohnson 1:1b37c4b989b4 18 c->sum=a^b;
MartinJohnson 1:1b37c4b989b4 19 c->carry=a&b;
MartinJohnson 1:1b37c4b989b4 20 }
MartinJohnson 1:1b37c4b989b4 21
MartinJohnson 1:1b37c4b989b4 22 static void full_add(AddResult *d, Unit a, Unit b, Unit c) {
MartinJohnson 1:1b37c4b989b4 23 AddResult r0,r1;
MartinJohnson 1:1b37c4b989b4 24 half_add(&r0,a, b);
MartinJohnson 1:1b37c4b989b4 25 half_add(&r1,r0.sum, c);
MartinJohnson 1:1b37c4b989b4 26 d->sum=r1.sum;
MartinJohnson 1:1b37c4b989b4 27 d->carry=r0.carry | r1.carry;
MartinJohnson 1:1b37c4b989b4 28 }
MartinJohnson 1:1b37c4b989b4 29
MartinJohnson 1:1b37c4b989b4 30 static Unit col_step(Unit above[3],
MartinJohnson 1:1b37c4b989b4 31 Unit current[3],
MartinJohnson 1:1b37c4b989b4 32 Unit below[3]) {
MartinJohnson 1:1b37c4b989b4 33 AddResult a_inf,b_inf,c_inf,next0,next1a,next1b;
MartinJohnson 1:1b37c4b989b4 34 /*
MartinJohnson 1:1b37c4b989b4 35 * Compute row-wise influence sums. This produces 96 2-bit sums (represented
MartinJohnson 1:1b37c4b989b4 36 * as three pairs of 32-vectors) giving the number of live cells in the 1D
MartinJohnson 1:1b37c4b989b4 37 * Moore neighborhood around each position.
MartinJohnson 1:1b37c4b989b4 38 */
MartinJohnson 1:1b37c4b989b4 39 full_add(&a_inf,(above[1] << 1) | (above[0] >> (bits - 1)),
MartinJohnson 1:1b37c4b989b4 40 above[1],
MartinJohnson 1:1b37c4b989b4 41 (above[1] >> 1) | (above[2] << (bits - 1)));
MartinJohnson 1:1b37c4b989b4 42 half_add(&c_inf,(current[1] << 1) | (current[0] >> (bits - 1)),
MartinJohnson 1:1b37c4b989b4 43 /* middle bits of current[1] don't count */
MartinJohnson 1:1b37c4b989b4 44 (current[1] >> 1) | (current[2] << (bits - 1)));
MartinJohnson 1:1b37c4b989b4 45 full_add(&b_inf,(below[1] << 1) | (below[0] >> (bits - 1)),
MartinJohnson 1:1b37c4b989b4 46 below[1],
MartinJohnson 1:1b37c4b989b4 47 (below[1] >> 1) | (below[2] << (bits - 1)));
MartinJohnson 1:1b37c4b989b4 48
MartinJohnson 1:1b37c4b989b4 49 /*
MartinJohnson 1:1b37c4b989b4 50 * Sum the row-wise sums into a two-dimensional Moore neighborhood population
MartinJohnson 1:1b37c4b989b4 51 * count. Such a count can overflow into four bits, but we don't care: Conway
MartinJohnson 1:1b37c4b989b4 52 * has the same result for 8/9 and 0/1 (the cell is cleared in both cases).
MartinJohnson 1:1b37c4b989b4 53 *
MartinJohnson 1:1b37c4b989b4 54 * Thus, we don't need a four-bit addition. Instead, we just retain the
MartinJohnson 1:1b37c4b989b4 55 * carry output from the two intermediate additions and use it as a mask.
MartinJohnson 1:1b37c4b989b4 56 */
MartinJohnson 1:1b37c4b989b4 57 full_add(&next0,a_inf.sum, c_inf.sum, b_inf.sum);
MartinJohnson 1:1b37c4b989b4 58 full_add(&next1a,a_inf.carry, next0.carry, b_inf.carry);
MartinJohnson 1:1b37c4b989b4 59 half_add(&next1b,c_inf.carry, next1a.sum);
MartinJohnson 1:1b37c4b989b4 60
MartinJohnson 1:1b37c4b989b4 61 /*
MartinJohnson 1:1b37c4b989b4 62 * Apply Niemiec's optimization: OR the current cell state vector into the
MartinJohnson 1:1b37c4b989b4 63 * 9-cell neighborhoold population count to derive the new state cheaply. The
MartinJohnson 1:1b37c4b989b4 64 * cell is set iff its three-bit sum is 0b011.
MartinJohnson 1:1b37c4b989b4 65 */
MartinJohnson 1:1b37c4b989b4 66 return (next0.sum | current[1])
MartinJohnson 1:1b37c4b989b4 67 & next1b.sum
MartinJohnson 1:1b37c4b989b4 68 & ~next1a.carry
MartinJohnson 1:1b37c4b989b4 69 & ~next1b.carry;
MartinJohnson 1:1b37c4b989b4 70 }
MartinJohnson 1:1b37c4b989b4 71
MartinJohnson 1:1b37c4b989b4 72
MartinJohnson 1:1b37c4b989b4 73
MartinJohnson 1:1b37c4b989b4 74 static void step(Unit const *current_map,
MartinJohnson 1:1b37c4b989b4 75 Unit *next_map,
MartinJohnson 1:1b37c4b989b4 76 Unit width,
MartinJohnson 1:1b37c4b989b4 77 Unit height) {
MartinJohnson 1:1b37c4b989b4 78 // We keep sliding windows of state in these arrays.
MartinJohnson 1:1b37c4b989b4 79 Unit above[3]={ 0, 0, 0 };
MartinJohnson 1:1b37c4b989b4 80 Unit current[3]={ 0, 0, 0 };
MartinJohnson 1:1b37c4b989b4 81 Unit below[3]={ 0, 0, 0 };
MartinJohnson 1:1b37c4b989b4 82 unsigned x,y;
MartinJohnson 1:1b37c4b989b4 83
MartinJohnson 1:1b37c4b989b4 84 // Bootstrap for first column of first row.
MartinJohnson 1:1b37c4b989b4 85 current[0] = current[1] = 0;
MartinJohnson 1:1b37c4b989b4 86 current[2] = current_map[0];
MartinJohnson 0:404dae88af71 87
MartinJohnson 1:1b37c4b989b4 88 below[0] = below[1] = 0;
MartinJohnson 1:1b37c4b989b4 89 below[2] = current_map[width];
MartinJohnson 1:1b37c4b989b4 90
MartinJohnson 1:1b37c4b989b4 91 #define ADV(name, next) \
MartinJohnson 1:1b37c4b989b4 92 name[0] = name[1]; \
MartinJohnson 1:1b37c4b989b4 93 name[1] = name[2]; \
MartinJohnson 1:1b37c4b989b4 94 name[2] = (next)
MartinJohnson 1:1b37c4b989b4 95
MartinJohnson 1:1b37c4b989b4 96 // First row, wherein above[x] = 0, less final column
MartinJohnson 1:1b37c4b989b4 97 for (x = 0; x < width - 1; ++x) {
MartinJohnson 1:1b37c4b989b4 98 ADV(current, current_map[x + 1]);
MartinJohnson 1:1b37c4b989b4 99 ADV(below, current_map[width + x + 1]);
MartinJohnson 1:1b37c4b989b4 100 next_map[x] = col_step(above, current, below);
MartinJohnson 1:1b37c4b989b4 101 }
MartinJohnson 1:1b37c4b989b4 102
MartinJohnson 1:1b37c4b989b4 103
MartinJohnson 1:1b37c4b989b4 104 // Final column of first row, wherein we cannot fetch next values.
MartinJohnson 1:1b37c4b989b4 105 ADV(current, 0);
MartinJohnson 1:1b37c4b989b4 106 ADV(below, 0);
MartinJohnson 1:1b37c4b989b4 107 next_map[width - 1] = col_step(above, current, below);
MartinJohnson 1:1b37c4b989b4 108
MartinJohnson 1:1b37c4b989b4 109 // Remaining rows except the last.
MartinJohnson 1:1b37c4b989b4 110 for (y = 1; y < height - 1; ++y) {
MartinJohnson 1:1b37c4b989b4 111 unsigned offset = y * width;
MartinJohnson 1:1b37c4b989b4 112
MartinJohnson 1:1b37c4b989b4 113 // Bootstrap row like we did for row 1.
MartinJohnson 1:1b37c4b989b4 114 above[0] = above[1] = 0;
MartinJohnson 1:1b37c4b989b4 115 current[0] = current[1] = 0;
MartinJohnson 1:1b37c4b989b4 116 below[0] = below[1] = 0;
MartinJohnson 1:1b37c4b989b4 117
MartinJohnson 1:1b37c4b989b4 118 above[2] = current_map[offset - width];
MartinJohnson 1:1b37c4b989b4 119 current[2] = current_map[offset];
MartinJohnson 1:1b37c4b989b4 120 below[2] = current_map[offset + width];
MartinJohnson 1:1b37c4b989b4 121
MartinJohnson 1:1b37c4b989b4 122 for (x = 0; x < width - 1; ++x) {
MartinJohnson 1:1b37c4b989b4 123 ADV(above, current_map[offset - width + x + 1]);
MartinJohnson 1:1b37c4b989b4 124 ADV(current, current_map[offset + x + 1]);
MartinJohnson 1:1b37c4b989b4 125 ADV(below, current_map[offset + width + x + 1]);
MartinJohnson 1:1b37c4b989b4 126 next_map[offset + x] = col_step(above, current, below);
MartinJohnson 1:1b37c4b989b4 127 }
MartinJohnson 1:1b37c4b989b4 128
MartinJohnson 1:1b37c4b989b4 129 // Last column.
MartinJohnson 1:1b37c4b989b4 130 ADV(above, 0);
MartinJohnson 1:1b37c4b989b4 131 ADV(current, 0);
MartinJohnson 1:1b37c4b989b4 132 ADV(below, 0);
MartinJohnson 1:1b37c4b989b4 133 next_map[offset + width - 1] = col_step(above, current, below);
MartinJohnson 1:1b37c4b989b4 134 }
MartinJohnson 1:1b37c4b989b4 135
MartinJohnson 1:1b37c4b989b4 136 // Final row, wherein below[x] = 0.
MartinJohnson 1:1b37c4b989b4 137 unsigned offset = width * (height - 1);
MartinJohnson 1:1b37c4b989b4 138 above[0] = above[1] = 0;
MartinJohnson 1:1b37c4b989b4 139 current[0] = current[1] = 0;
MartinJohnson 1:1b37c4b989b4 140 below[0] = below[1] = below[2] = 0;
MartinJohnson 1:1b37c4b989b4 141
MartinJohnson 1:1b37c4b989b4 142 above[2] = current_map[offset - width];
MartinJohnson 1:1b37c4b989b4 143 current[2] = current_map[offset];
MartinJohnson 1:1b37c4b989b4 144
MartinJohnson 1:1b37c4b989b4 145 for (x = 0; x < width - 1; ++x) {
MartinJohnson 1:1b37c4b989b4 146 ADV(above, current_map[offset - width + x + 1]);
MartinJohnson 1:1b37c4b989b4 147 ADV(current, current_map[offset + x + 1]);
MartinJohnson 1:1b37c4b989b4 148 next_map[offset + x] = col_step(above, current, below);
MartinJohnson 1:1b37c4b989b4 149 }
MartinJohnson 1:1b37c4b989b4 150
MartinJohnson 1:1b37c4b989b4 151 // Final column
MartinJohnson 1:1b37c4b989b4 152 ADV(above, 0);
MartinJohnson 1:1b37c4b989b4 153 ADV(current, 0);
MartinJohnson 1:1b37c4b989b4 154 next_map[offset + width - 1] = col_step(above, current, below);
MartinJohnson 1:1b37c4b989b4 155
MartinJohnson 1:1b37c4b989b4 156 #undef ADV
MartinJohnson 1:1b37c4b989b4 157 }
MartinJohnson 1:1b37c4b989b4 158
MartinJohnson 1:1b37c4b989b4 159 extern unsigned fboffset;
MartinJohnson 1:1b37c4b989b4 160
MartinJohnson 1:1b37c4b989b4 161 void conway_demo() {
MartinJohnson 1:1b37c4b989b4 162 Unit *current=(Unit *)fb[0];
MartinJohnson 1:1b37c4b989b4 163 Unit *next=(Unit *)fb[rows];
MartinJohnson 1:1b37c4b989b4 164 SPI1->CR1 |= SPI_FirstBit_LSB;
MartinJohnson 1:1b37c4b989b4 165
MartinJohnson 1:1b37c4b989b4 166 while(1) {
MartinJohnson 1:1b37c4b989b4 167 step(current,next,cols/bits,rows);
MartinJohnson 1:1b37c4b989b4 168 fboffset=300*52;
MartinJohnson 1:1b37c4b989b4 169 sysDelayMs(1);
MartinJohnson 1:1b37c4b989b4 170 step(next,current,cols/bits,rows);
MartinJohnson 1:1b37c4b989b4 171 fboffset=0;
MartinJohnson 1:1b37c4b989b4 172 sysDelayMs(1);
MartinJohnson 1:1b37c4b989b4 173 }
MartinJohnson 1:1b37c4b989b4 174 }
MartinJohnson 1:1b37c4b989b4 175