“Race Collision” is a one player game in which a truck has to avoid “particles” that appear on the road. By the use of the joystick, the player can guide themselves through the menu system to start the game. The truck is the main element of the game and it can be moved from side to side with the joystick. The road curves randomly from time to time and the player has to be careful to keep the truck within the road boundaries. Particles appear on the screen at random positions and 4 collisions lead to the end of the game.

Dependencies:   ELEC2645_JoystickLCD_LPC1768_2021

Committer:
eencae
Date:
Fri Dec 11 12:25:25 2020 +0000
Revision:
0:be41a15e7a86
Child:
1:2ae7a8b01771
Initial Commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
eencae 0:be41a15e7a86 1 #include "mbed.h"
eencae 0:be41a15e7a86 2 #include "N5110.h"
eencae 0:be41a15e7a86 3
eencae 0:be41a15e7a86 4 // overloaded constructor includes power pin - LCD Vcc connected to GPIO pin
eencae 0:be41a15e7a86 5 // this constructor works fine with LPC1768 - enough current sourced from GPIO
eencae 0:be41a15e7a86 6 // to power LCD. Doesn't work well with K64F.
eencae 0:be41a15e7a86 7 N5110::N5110(PinName const pwrPin,
eencae 0:be41a15e7a86 8 PinName const scePin,
eencae 0:be41a15e7a86 9 PinName const rstPin,
eencae 0:be41a15e7a86 10 PinName const dcPin,
eencae 0:be41a15e7a86 11 PinName const mosiPin,
eencae 0:be41a15e7a86 12 PinName const sclkPin,
eencae 0:be41a15e7a86 13 PinName const ledPin)
eencae 0:be41a15e7a86 14 :
eencae 0:be41a15e7a86 15 _spi(new SPI(mosiPin,NC,sclkPin)), // create new SPI instance and initialise
eencae 0:be41a15e7a86 16 _led(new DigitalOut(ledPin)),
eencae 0:be41a15e7a86 17 _pwr(new DigitalOut(pwrPin)),
eencae 0:be41a15e7a86 18 _sce(new DigitalOut(scePin)),
eencae 0:be41a15e7a86 19 _rst(new DigitalOut(rstPin)),
eencae 0:be41a15e7a86 20 _dc(new DigitalOut(dcPin))
eencae 0:be41a15e7a86 21 {}
eencae 0:be41a15e7a86 22
eencae 0:be41a15e7a86 23 // overloaded constructor does not include power pin - LCD Vcc must be tied to +3V3
eencae 0:be41a15e7a86 24 // Best to use this with K64F as the GPIO hasn't sufficient output current to reliably
eencae 0:be41a15e7a86 25 // drive the LCD.
eencae 0:be41a15e7a86 26 N5110::N5110(PinName const scePin,
eencae 0:be41a15e7a86 27 PinName const rstPin,
eencae 0:be41a15e7a86 28 PinName const dcPin,
eencae 0:be41a15e7a86 29 PinName const mosiPin,
eencae 0:be41a15e7a86 30 PinName const sclkPin,
eencae 0:be41a15e7a86 31 PinName const ledPin)
eencae 0:be41a15e7a86 32 :
eencae 0:be41a15e7a86 33 _spi(new SPI(mosiPin,NC,sclkPin)), // create new SPI instance and initialise
eencae 0:be41a15e7a86 34 _led(new DigitalOut(ledPin)),
eencae 0:be41a15e7a86 35 _pwr(NULL), // pwr not needed so null it to be safe
eencae 0:be41a15e7a86 36 _sce(new DigitalOut(scePin)),
eencae 0:be41a15e7a86 37 _rst(new DigitalOut(rstPin)),
eencae 0:be41a15e7a86 38 _dc(new DigitalOut(dcPin))
eencae 0:be41a15e7a86 39 {}
eencae 0:be41a15e7a86 40
eencae 0:be41a15e7a86 41
eencae 0:be41a15e7a86 42 N5110::~N5110()
eencae 0:be41a15e7a86 43 {
eencae 0:be41a15e7a86 44 delete _spi;
eencae 0:be41a15e7a86 45
eencae 0:be41a15e7a86 46 if(_pwr) {
eencae 0:be41a15e7a86 47 delete _pwr;
eencae 0:be41a15e7a86 48 }
eencae 0:be41a15e7a86 49
eencae 0:be41a15e7a86 50 delete _led;
eencae 0:be41a15e7a86 51 delete _sce;
eencae 0:be41a15e7a86 52 delete _rst;
eencae 0:be41a15e7a86 53 delete _dc;
eencae 0:be41a15e7a86 54 }
eencae 0:be41a15e7a86 55
eencae 0:be41a15e7a86 56 // initialise function - powers up and sends the initialisation commands
eencae 0:be41a15e7a86 57 void N5110::init()
eencae 0:be41a15e7a86 58 {
eencae 0:be41a15e7a86 59 turnOn(); // power up
eencae 0:be41a15e7a86 60 reset(); // reset LCD - must be done within 100 ms
eencae 0:be41a15e7a86 61 initSPI();
eencae 0:be41a15e7a86 62
eencae 0:be41a15e7a86 63 backLightOn();
eencae 0:be41a15e7a86 64 setContrast(0.55); // this may need tuning (say 0.4 to 0.6)
eencae 0:be41a15e7a86 65 setBias(3); // datasheet - 48:1 mux - don't mess with if you don't know what you're doing! (0 to 7)
eencae 0:be41a15e7a86 66 setTempCoefficient(0); // datasheet - may need increasing (range 0 to 3) at very low temperatures
eencae 0:be41a15e7a86 67 normalMode(); // normal video mode by default
eencae 0:be41a15e7a86 68
eencae 0:be41a15e7a86 69 clearRAM(); // RAM is undefined at power-up so clear to be sure
eencae 0:be41a15e7a86 70 clear(); // clear buffer
eencae 0:be41a15e7a86 71 }
eencae 0:be41a15e7a86 72
eencae 0:be41a15e7a86 73 // sets normal video mode (black on white)
eencae 0:be41a15e7a86 74 void N5110::normalMode()
eencae 0:be41a15e7a86 75 {
eencae 0:be41a15e7a86 76 sendCommand(0b00100000); // basic instruction
eencae 0:be41a15e7a86 77 sendCommand(0b00001100); // normal video mode- datasheet
eencae 0:be41a15e7a86 78 }
eencae 0:be41a15e7a86 79
eencae 0:be41a15e7a86 80 // sets normal video mode (white on black)
eencae 0:be41a15e7a86 81 void N5110::inverseMode()
eencae 0:be41a15e7a86 82 {
eencae 0:be41a15e7a86 83 sendCommand(0b00100000); // basic instruction
eencae 0:be41a15e7a86 84 sendCommand(0b00001101); // inverse video mode - datasheet
eencae 0:be41a15e7a86 85 }
eencae 0:be41a15e7a86 86
eencae 0:be41a15e7a86 87 // function to power up the LCD and backlight - only works when using GPIO to power
eencae 0:be41a15e7a86 88 void N5110::turnOn()
eencae 0:be41a15e7a86 89 {
eencae 0:be41a15e7a86 90 if (_pwr != NULL) {
eencae 0:be41a15e7a86 91 _pwr->write(1); // apply power
eencae 0:be41a15e7a86 92 }
eencae 0:be41a15e7a86 93 }
eencae 0:be41a15e7a86 94
eencae 0:be41a15e7a86 95 // function to power down LCD
eencae 0:be41a15e7a86 96 void N5110::turnOff()
eencae 0:be41a15e7a86 97 {
eencae 0:be41a15e7a86 98 clear(); // clear buffer
eencae 0:be41a15e7a86 99 refresh();
eencae 0:be41a15e7a86 100 backLightOff(); // turn backlight off
eencae 0:be41a15e7a86 101 clearRAM(); // clear RAM to ensure specified current consumption
eencae 0:be41a15e7a86 102 // send command to ensure we are in basic mode
eencae 0:be41a15e7a86 103
eencae 0:be41a15e7a86 104 sendCommand(0b00100000); // basic mode
eencae 0:be41a15e7a86 105 sendCommand(0b00001000); // clear display
eencae 0:be41a15e7a86 106 sendCommand(0b00100001); // extended mode
eencae 0:be41a15e7a86 107 sendCommand(0b00100100); // power down
eencae 0:be41a15e7a86 108
eencae 0:be41a15e7a86 109 // if we are powering the LCD using the GPIO then make it low to turn off
eencae 0:be41a15e7a86 110 if (_pwr != NULL) {
eencae 0:be41a15e7a86 111 wait_ms(10); // small delay and then turn off the power pin
eencae 0:be41a15e7a86 112 _pwr->write(0); // turn off power
eencae 0:be41a15e7a86 113 }
eencae 0:be41a15e7a86 114
eencae 0:be41a15e7a86 115 }
eencae 0:be41a15e7a86 116
eencae 0:be41a15e7a86 117 // function to change LED backlight brightness
eencae 0:be41a15e7a86 118 void N5110::backLightOn()
eencae 0:be41a15e7a86 119 {
eencae 0:be41a15e7a86 120 _led->write(1);
eencae 0:be41a15e7a86 121 }
eencae 0:be41a15e7a86 122
eencae 0:be41a15e7a86 123 // function to change LED backlight brightness
eencae 0:be41a15e7a86 124 void N5110::backLightOff()
eencae 0:be41a15e7a86 125 {
eencae 0:be41a15e7a86 126 _led->write(0);
eencae 0:be41a15e7a86 127 }
eencae 0:be41a15e7a86 128
eencae 0:be41a15e7a86 129 void N5110::setContrast(float contrast) {
eencae 0:be41a15e7a86 130
eencae 0:be41a15e7a86 131 // enforce limits
eencae 0:be41a15e7a86 132 if (contrast > 1.0f)
eencae 0:be41a15e7a86 133 contrast = 1.0f;
eencae 0:be41a15e7a86 134 else if (contrast < 0.0f)
eencae 0:be41a15e7a86 135 contrast = 0.0;
eencae 0:be41a15e7a86 136
eencae 0:be41a15e7a86 137 // convert to char in range 0 to 127 (i.e. 6 bits)
eencae 0:be41a15e7a86 138 char ic = char(contrast*127.0f);
eencae 0:be41a15e7a86 139
eencae 0:be41a15e7a86 140 sendCommand(0b00100001); // extended instruction set
eencae 0:be41a15e7a86 141 sendCommand(0b10000000 | ic); // set Vop (which controls contrast)
eencae 0:be41a15e7a86 142 sendCommand(0b00100000); // back to basic instruction set
eencae 0:be41a15e7a86 143 }
eencae 0:be41a15e7a86 144
eencae 0:be41a15e7a86 145 void N5110::setTempCoefficient(char tc) {
eencae 0:be41a15e7a86 146
eencae 0:be41a15e7a86 147 // enforce limits
eencae 0:be41a15e7a86 148 if (tc>3) {
eencae 0:be41a15e7a86 149 tc=3;
eencae 0:be41a15e7a86 150 }
eencae 0:be41a15e7a86 151
eencae 0:be41a15e7a86 152 // temperature coefficient may need increasing at low temperatures
eencae 0:be41a15e7a86 153
eencae 0:be41a15e7a86 154 sendCommand(0b00100001); // extended instruction set
eencae 0:be41a15e7a86 155 sendCommand(0b00000100 | tc);
eencae 0:be41a15e7a86 156 sendCommand(0b00100000); // back to basic instruction set
eencae 0:be41a15e7a86 157 }
eencae 0:be41a15e7a86 158
eencae 0:be41a15e7a86 159 void N5110::setBias(char bias) {
eencae 0:be41a15e7a86 160
eencae 0:be41a15e7a86 161 // from data sheet
eencae 0:be41a15e7a86 162 // bias mux rate
eencae 0:be41a15e7a86 163 // 0 1:100
eencae 0:be41a15e7a86 164 // 1 1:80
eencae 0:be41a15e7a86 165 // 2 1:65
eencae 0:be41a15e7a86 166 // 3 1:48 (default)
eencae 0:be41a15e7a86 167 // 4 1:40/1:34
eencae 0:be41a15e7a86 168 // 5 1:24
eencae 0:be41a15e7a86 169 // 6 1:18/1:16
eencae 0:be41a15e7a86 170 // 7 1:10/1:9/1:8
eencae 0:be41a15e7a86 171
eencae 0:be41a15e7a86 172 // enforce limits
eencae 0:be41a15e7a86 173 if (bias>7) {
eencae 0:be41a15e7a86 174 bias=7;
eencae 0:be41a15e7a86 175 }
eencae 0:be41a15e7a86 176
eencae 0:be41a15e7a86 177 sendCommand(0b00100001); // extended mode instruction
eencae 0:be41a15e7a86 178 sendCommand(0b00010000 | bias);
eencae 0:be41a15e7a86 179 sendCommand(0b00100000); // end of extended mode instruction
eencae 0:be41a15e7a86 180 }
eencae 0:be41a15e7a86 181
eencae 0:be41a15e7a86 182 // pulse the active low reset line
eencae 0:be41a15e7a86 183 void N5110::reset()
eencae 0:be41a15e7a86 184 {
eencae 0:be41a15e7a86 185 _rst->write(0); // reset the LCD
eencae 0:be41a15e7a86 186 _rst->write(1);
eencae 0:be41a15e7a86 187 }
eencae 0:be41a15e7a86 188
eencae 0:be41a15e7a86 189 // function to initialise SPI peripheral
eencae 0:be41a15e7a86 190 void N5110::initSPI()
eencae 0:be41a15e7a86 191 {
eencae 0:be41a15e7a86 192 _spi->format(8,1); // 8 bits, Mode 1 - polarity 0, phase 1 - base value of clock is 0, data captured on falling edge/propagated on rising edge
eencae 0:be41a15e7a86 193 _spi->frequency(4000000); // maximum of screen is 4 MHz
eencae 0:be41a15e7a86 194 }
eencae 0:be41a15e7a86 195
eencae 0:be41a15e7a86 196 // send a command to the display
eencae 0:be41a15e7a86 197 void N5110::sendCommand(unsigned char command)
eencae 0:be41a15e7a86 198 {
eencae 0:be41a15e7a86 199 _dc->write(0); // set DC low for command
eencae 0:be41a15e7a86 200 _sce->write(0); // set CE low to begin frame
eencae 0:be41a15e7a86 201 _spi->write(command); // send command
eencae 0:be41a15e7a86 202 _dc->write(1); // turn back to data by default
eencae 0:be41a15e7a86 203 _sce->write(1); // set CE high to end frame (expected for transmission of single byte)
eencae 0:be41a15e7a86 204 }
eencae 0:be41a15e7a86 205
eencae 0:be41a15e7a86 206 // send data to the display at the current XY address
eencae 0:be41a15e7a86 207 // dc is set to 1 (i.e. data) after sending a command and so should
eencae 0:be41a15e7a86 208 // be the default mode.
eencae 0:be41a15e7a86 209 void N5110::sendData(unsigned char data)
eencae 0:be41a15e7a86 210 {
eencae 0:be41a15e7a86 211 _sce->write(0); // set CE low to begin frame
eencae 0:be41a15e7a86 212 _spi->write(data);
eencae 0:be41a15e7a86 213 _sce->write(1); // set CE high to end frame (expected for transmission of single byte)
eencae 0:be41a15e7a86 214 }
eencae 0:be41a15e7a86 215
eencae 0:be41a15e7a86 216 // this function writes 0 to the 504 bytes to clear the RAM
eencae 0:be41a15e7a86 217 void N5110::clearRAM()
eencae 0:be41a15e7a86 218 {
eencae 0:be41a15e7a86 219 _sce->write(0); //set CE low to begin frame
eencae 0:be41a15e7a86 220 for(int i = 0; i < WIDTH * HEIGHT; i++) { // 48 x 84 bits = 504 bytes
eencae 0:be41a15e7a86 221 _spi->write(0x00); // send 0's
eencae 0:be41a15e7a86 222 }
eencae 0:be41a15e7a86 223 _sce->write(1); // set CE high to end frame
eencae 0:be41a15e7a86 224 }
eencae 0:be41a15e7a86 225
eencae 0:be41a15e7a86 226 // function to set the XY address in RAM for subsequenct data write
eencae 0:be41a15e7a86 227 void N5110::setXYAddress(unsigned int const x,
eencae 0:be41a15e7a86 228 unsigned int const y)
eencae 0:be41a15e7a86 229 {
eencae 0:be41a15e7a86 230 if (x<WIDTH && y<HEIGHT) { // check within range
eencae 0:be41a15e7a86 231 sendCommand(0b00100000); // basic instruction
eencae 0:be41a15e7a86 232 sendCommand(0b10000000 | x); // send addresses to display with relevant mask
eencae 0:be41a15e7a86 233 sendCommand(0b01000000 | y);
eencae 0:be41a15e7a86 234 }
eencae 0:be41a15e7a86 235 }
eencae 0:be41a15e7a86 236
eencae 0:be41a15e7a86 237 // These functions are used to set, clear and get the value of pixels in the display
eencae 0:be41a15e7a86 238 // Pixels are addressed in the range of 0 to 47 (y) and 0 to 83 (x). The refresh()
eencae 0:be41a15e7a86 239 // function must be called after set and clear in order to update the display
eencae 0:be41a15e7a86 240 void N5110::setPixel(unsigned int const x,
eencae 0:be41a15e7a86 241 unsigned int const y,
eencae 0:be41a15e7a86 242 bool const state)
eencae 0:be41a15e7a86 243 {
eencae 0:be41a15e7a86 244 if (x<WIDTH && y<HEIGHT) { // check within range
eencae 0:be41a15e7a86 245 // calculate bank and shift 1 to required position in the data byte
eencae 0:be41a15e7a86 246 if(state) buffer[x][y/8] |= (1 << y%8);
eencae 0:be41a15e7a86 247 else buffer[x][y/8] &= ~(1 << y%8);
eencae 0:be41a15e7a86 248 }
eencae 0:be41a15e7a86 249 }
eencae 0:be41a15e7a86 250
eencae 0:be41a15e7a86 251 void N5110::clearPixel(unsigned int const x,
eencae 0:be41a15e7a86 252 unsigned int const y)
eencae 0:be41a15e7a86 253 {
eencae 0:be41a15e7a86 254 if (x<WIDTH && y<HEIGHT) { // check within range
eencae 0:be41a15e7a86 255 // calculate bank and shift 1 to required position (using bit clear)
eencae 0:be41a15e7a86 256 buffer[x][y/8] &= ~(1 << y%8);
eencae 0:be41a15e7a86 257 }
eencae 0:be41a15e7a86 258 }
eencae 0:be41a15e7a86 259
eencae 0:be41a15e7a86 260 int N5110::getPixel(unsigned int const x,
eencae 0:be41a15e7a86 261 unsigned int const y) const
eencae 0:be41a15e7a86 262 {
eencae 0:be41a15e7a86 263 if (x<WIDTH && y<HEIGHT) { // check within range
eencae 0:be41a15e7a86 264 // return relevant bank and mask required bit
eencae 0:be41a15e7a86 265
eencae 0:be41a15e7a86 266 int pixel = (int) buffer[x][y/8] & (1 << y%8);
eencae 0:be41a15e7a86 267
eencae 0:be41a15e7a86 268 if (pixel)
eencae 0:be41a15e7a86 269 return 1;
eencae 0:be41a15e7a86 270 else
eencae 0:be41a15e7a86 271 return 0;
eencae 0:be41a15e7a86 272 }
eencae 0:be41a15e7a86 273
eencae 0:be41a15e7a86 274 return 0;
eencae 0:be41a15e7a86 275
eencae 0:be41a15e7a86 276 }
eencae 0:be41a15e7a86 277
eencae 0:be41a15e7a86 278 // function to refresh the display
eencae 0:be41a15e7a86 279 void N5110::refresh()
eencae 0:be41a15e7a86 280 {
eencae 0:be41a15e7a86 281 setXYAddress(0,0); // important to set address back to 0,0 before refreshing display
eencae 0:be41a15e7a86 282 // address auto increments after printing string, so buffer[0][0] will not coincide
eencae 0:be41a15e7a86 283 // with top-left pixel after priting string
eencae 0:be41a15e7a86 284
eencae 0:be41a15e7a86 285 _sce->write(0); //set CE low to begin frame
eencae 0:be41a15e7a86 286
eencae 0:be41a15e7a86 287 for(int j = 0; j < BANKS; j++) { // be careful to use correct order (j,i) for horizontal addressing
eencae 0:be41a15e7a86 288 for(int i = 0; i < WIDTH; i++) {
eencae 0:be41a15e7a86 289 _spi->write(buffer[i][j]); // send buffer
eencae 0:be41a15e7a86 290 }
eencae 0:be41a15e7a86 291 }
eencae 0:be41a15e7a86 292 _sce->write(1); // set CE high to end frame
eencae 0:be41a15e7a86 293
eencae 0:be41a15e7a86 294 }
eencae 0:be41a15e7a86 295
eencae 0:be41a15e7a86 296 // fills the buffer with random bytes. Can be used to test the display.
eencae 0:be41a15e7a86 297 // The rand() function isn't seeded so it probably creates the same pattern everytime
eencae 0:be41a15e7a86 298 void N5110::randomiseBuffer()
eencae 0:be41a15e7a86 299 {
eencae 0:be41a15e7a86 300 int i,j;
eencae 0:be41a15e7a86 301 for(j = 0; j < BANKS; j++) { // be careful to use correct order (j,i) for horizontal addressing
eencae 0:be41a15e7a86 302 for(i = 0; i < WIDTH; i++) {
eencae 0:be41a15e7a86 303 buffer[i][j] = rand()%256; // generate random byte
eencae 0:be41a15e7a86 304 }
eencae 0:be41a15e7a86 305 }
eencae 0:be41a15e7a86 306
eencae 0:be41a15e7a86 307 }
eencae 0:be41a15e7a86 308
eencae 0:be41a15e7a86 309 // function to print 5x7 font
eencae 0:be41a15e7a86 310 void N5110::printChar(char const c,
eencae 0:be41a15e7a86 311 unsigned int const x,
eencae 0:be41a15e7a86 312 unsigned int const y)
eencae 0:be41a15e7a86 313 {
eencae 0:be41a15e7a86 314 if (y<BANKS) { // check if printing in range of y banks
eencae 0:be41a15e7a86 315
eencae 0:be41a15e7a86 316 for (int i = 0; i < 5 ; i++ ) {
eencae 0:be41a15e7a86 317 int pixel_x = x+i;
eencae 0:be41a15e7a86 318 if (pixel_x > WIDTH-1) // ensure pixel isn't outside the buffer size (0 - 83)
eencae 0:be41a15e7a86 319 break;
eencae 0:be41a15e7a86 320 buffer[pixel_x][y] = font5x7[(c - 32)*5 + i];
eencae 0:be41a15e7a86 321 // array is offset by 32 relative to ASCII, each character is 5 pixels wide
eencae 0:be41a15e7a86 322 }
eencae 0:be41a15e7a86 323
eencae 0:be41a15e7a86 324 }
eencae 0:be41a15e7a86 325 }
eencae 0:be41a15e7a86 326
eencae 0:be41a15e7a86 327 // function to print string at specified position
eencae 0:be41a15e7a86 328 void N5110::printString(const char *str,
eencae 0:be41a15e7a86 329 unsigned int const x,
eencae 0:be41a15e7a86 330 unsigned int const y)
eencae 0:be41a15e7a86 331 {
eencae 0:be41a15e7a86 332 if (y<BANKS) { // check if printing in range of y banks
eencae 0:be41a15e7a86 333
eencae 0:be41a15e7a86 334 int n = 0 ; // counter for number of characters in string
eencae 0:be41a15e7a86 335 // loop through string and print character
eencae 0:be41a15e7a86 336 while(*str) {
eencae 0:be41a15e7a86 337
eencae 0:be41a15e7a86 338 // writes the character bitmap data to the buffer, so that
eencae 0:be41a15e7a86 339 // text and pixels can be displayed at the same time
eencae 0:be41a15e7a86 340 for (int i = 0; i < 5 ; i++ ) {
eencae 0:be41a15e7a86 341 int pixel_x = x+i+n*6;
eencae 0:be41a15e7a86 342 if (pixel_x > WIDTH-1) // ensure pixel isn't outside the buffer size (0 - 83)
eencae 0:be41a15e7a86 343 break;
eencae 0:be41a15e7a86 344 buffer[pixel_x][y] = font5x7[(*str - 32)*5 + i];
eencae 0:be41a15e7a86 345 }
eencae 0:be41a15e7a86 346 str++; // go to next character in string
eencae 0:be41a15e7a86 347 n++; // increment index
eencae 0:be41a15e7a86 348 }
eencae 0:be41a15e7a86 349 }
eencae 0:be41a15e7a86 350 }
eencae 0:be41a15e7a86 351
eencae 0:be41a15e7a86 352 // function to clear the screen buffer
eencae 0:be41a15e7a86 353 void N5110::clear()
eencae 0:be41a15e7a86 354 {
eencae 0:be41a15e7a86 355 memset(buffer,0,sizeof(buffer));
eencae 0:be41a15e7a86 356 }
eencae 0:be41a15e7a86 357
eencae 0:be41a15e7a86 358 // function to plot array on display
eencae 0:be41a15e7a86 359 void N5110::plotArray(float const array[])
eencae 0:be41a15e7a86 360 {
eencae 0:be41a15e7a86 361 for (int i=0; i<WIDTH; i++) { // loop through array
eencae 0:be41a15e7a86 362 // elements are normalised from 0.0 to 1.0, so multiply
eencae 0:be41a15e7a86 363 // by 47 to convert to pixel range, and subtract from 47
eencae 0:be41a15e7a86 364 // since top-left is 0,0 in the display geometry
eencae 0:be41a15e7a86 365 setPixel(i,47 - int(array[i]*47.0f),true);
eencae 0:be41a15e7a86 366 }
eencae 0:be41a15e7a86 367
eencae 0:be41a15e7a86 368 }
eencae 0:be41a15e7a86 369
eencae 0:be41a15e7a86 370 // function to draw circle
eencae 0:be41a15e7a86 371 void N5110:: drawCircle(unsigned int const x0,
eencae 0:be41a15e7a86 372 unsigned int const y0,
eencae 0:be41a15e7a86 373 unsigned int const radius,
eencae 0:be41a15e7a86 374 FillType const fill)
eencae 0:be41a15e7a86 375 {
eencae 0:be41a15e7a86 376 // from http://en.wikipedia.org/wiki/Midpoint_circle_algorithm
eencae 0:be41a15e7a86 377 int x = radius;
eencae 0:be41a15e7a86 378 int y = 0;
eencae 0:be41a15e7a86 379 int radiusError = 1-x;
eencae 0:be41a15e7a86 380
eencae 0:be41a15e7a86 381 while(x >= y) {
eencae 0:be41a15e7a86 382
eencae 0:be41a15e7a86 383 // if transparent, just draw outline
eencae 0:be41a15e7a86 384 if (fill == FILL_TRANSPARENT) {
eencae 0:be41a15e7a86 385 setPixel( x + x0, y + y0,true);
eencae 0:be41a15e7a86 386 setPixel(-x + x0, y + y0,true);
eencae 0:be41a15e7a86 387 setPixel( y + x0, x + y0,true);
eencae 0:be41a15e7a86 388 setPixel(-y + x0, x + y0,true);
eencae 0:be41a15e7a86 389 setPixel(-y + x0, -x + y0,true);
eencae 0:be41a15e7a86 390 setPixel( y + x0, -x + y0,true);
eencae 0:be41a15e7a86 391 setPixel( x + x0, -y + y0,true);
eencae 0:be41a15e7a86 392 setPixel(-x + x0, -y + y0,true);
eencae 0:be41a15e7a86 393 } else { // drawing filled circle, so draw lines between points at same y value
eencae 0:be41a15e7a86 394
eencae 0:be41a15e7a86 395 int type = (fill==FILL_BLACK) ? 1:0; // black or white fill
eencae 0:be41a15e7a86 396
eencae 0:be41a15e7a86 397 drawLine(x+x0,y+y0,-x+x0,y+y0,type);
eencae 0:be41a15e7a86 398 drawLine(y+x0,x+y0,-y+x0,x+y0,type);
eencae 0:be41a15e7a86 399 drawLine(y+x0,-x+y0,-y+x0,-x+y0,type);
eencae 0:be41a15e7a86 400 drawLine(x+x0,-y+y0,-x+x0,-y+y0,type);
eencae 0:be41a15e7a86 401 }
eencae 0:be41a15e7a86 402
eencae 0:be41a15e7a86 403 y++;
eencae 0:be41a15e7a86 404 if (radiusError<0) {
eencae 0:be41a15e7a86 405 radiusError += 2 * y + 1;
eencae 0:be41a15e7a86 406 } else {
eencae 0:be41a15e7a86 407 x--;
eencae 0:be41a15e7a86 408 radiusError += 2 * (y - x) + 1;
eencae 0:be41a15e7a86 409 }
eencae 0:be41a15e7a86 410 }
eencae 0:be41a15e7a86 411
eencae 0:be41a15e7a86 412 }
eencae 0:be41a15e7a86 413
eencae 0:be41a15e7a86 414 void N5110::drawLine(unsigned int const x0,
eencae 0:be41a15e7a86 415 unsigned int const y0,
eencae 0:be41a15e7a86 416 unsigned int const x1,
eencae 0:be41a15e7a86 417 unsigned int const y1,
eencae 0:be41a15e7a86 418 unsigned int const type)
eencae 0:be41a15e7a86 419 {
eencae 0:be41a15e7a86 420 // Note that the ranges can be negative so we have to turn the input values
eencae 0:be41a15e7a86 421 // into signed integers first
eencae 0:be41a15e7a86 422 int const y_range = static_cast<int>(y1) - static_cast<int>(y0);
eencae 0:be41a15e7a86 423 int const x_range = static_cast<int>(x1) - static_cast<int>(x0);
eencae 0:be41a15e7a86 424
eencae 0:be41a15e7a86 425 // if dotted line, set step to 2, else step is 1
eencae 0:be41a15e7a86 426 unsigned int const step = (type==2) ? 2:1;
eencae 0:be41a15e7a86 427
eencae 0:be41a15e7a86 428 // make sure we loop over the largest range to get the most pixels on the display
eencae 0:be41a15e7a86 429 // for instance, if drawing a vertical line (x_range = 0), we need to loop down the y pixels
eencae 0:be41a15e7a86 430 // or else we'll only end up with 1 pixel in the x column
eencae 0:be41a15e7a86 431 if ( abs(x_range) > abs(y_range) ) {
eencae 0:be41a15e7a86 432
eencae 0:be41a15e7a86 433 // ensure we loop from smallest to largest or else for-loop won't run as expected
eencae 0:be41a15e7a86 434 unsigned int const start = x_range > 0 ? x0:x1;
eencae 0:be41a15e7a86 435 unsigned int const stop = x_range > 0 ? x1:x0;
eencae 0:be41a15e7a86 436
eencae 0:be41a15e7a86 437 // loop between x pixels
eencae 0:be41a15e7a86 438 for (unsigned int x = start; x<= stop ; x+=step) {
eencae 0:be41a15e7a86 439 // do linear interpolation
eencae 0:be41a15e7a86 440 int const dx = static_cast<int>(x)-static_cast<int>(x0);
eencae 0:be41a15e7a86 441 unsigned int const y = y0 + y_range * dx / x_range;
eencae 0:be41a15e7a86 442
eencae 0:be41a15e7a86 443 // If the line type is '0', this will clear the pixel
eencae 0:be41a15e7a86 444 // If it is '1' or '2', the pixel will be set
eencae 0:be41a15e7a86 445 setPixel(x,y, type);
eencae 0:be41a15e7a86 446 }
eencae 0:be41a15e7a86 447 } else {
eencae 0:be41a15e7a86 448
eencae 0:be41a15e7a86 449 // ensure we loop from smallest to largest or else for-loop won't run as expected
eencae 0:be41a15e7a86 450 unsigned int const start = y_range > 0 ? y0:y1;
eencae 0:be41a15e7a86 451 unsigned int const stop = y_range > 0 ? y1:y0;
eencae 0:be41a15e7a86 452
eencae 0:be41a15e7a86 453 for (unsigned int y = start; y<= stop ; y+=step) {
eencae 0:be41a15e7a86 454 // do linear interpolation
eencae 0:be41a15e7a86 455 int const dy = static_cast<int>(y)-static_cast<int>(y0);
eencae 0:be41a15e7a86 456 unsigned int const x = x0 + x_range * dy / y_range;
eencae 0:be41a15e7a86 457
eencae 0:be41a15e7a86 458 // If the line type is '0', this will clear the pixel
eencae 0:be41a15e7a86 459 // If it is '1' or '2', the pixel will be set
eencae 0:be41a15e7a86 460 setPixel(x,y, type);
eencae 0:be41a15e7a86 461 }
eencae 0:be41a15e7a86 462 }
eencae 0:be41a15e7a86 463
eencae 0:be41a15e7a86 464 }
eencae 0:be41a15e7a86 465
eencae 0:be41a15e7a86 466 void N5110::drawRect(unsigned int const x0,
eencae 0:be41a15e7a86 467 unsigned int const y0,
eencae 0:be41a15e7a86 468 unsigned int const width,
eencae 0:be41a15e7a86 469 unsigned int const height,
eencae 0:be41a15e7a86 470 FillType const fill)
eencae 0:be41a15e7a86 471 {
eencae 0:be41a15e7a86 472 if (fill == FILL_TRANSPARENT) { // transparent, just outline
eencae 0:be41a15e7a86 473 drawLine(x0,y0,x0+(width-1),y0,1); // top
eencae 0:be41a15e7a86 474 drawLine(x0,y0+(height-1),x0+(width-1),y0+(height-1),1); // bottom
eencae 0:be41a15e7a86 475 drawLine(x0,y0,x0,y0+(height-1),1); // left
eencae 0:be41a15e7a86 476 drawLine(x0+(width-1),y0,x0+(width-1),y0+(height-1),1); // right
eencae 0:be41a15e7a86 477 } else { // filled rectangle
eencae 0:be41a15e7a86 478 int type = (fill==FILL_BLACK) ? 1:0; // black or white fill
eencae 0:be41a15e7a86 479 for (int y = y0; y<y0+height; y++) { // loop through rows of rectangle
eencae 0:be41a15e7a86 480 drawLine(x0,y,x0+(width-1),y,type); // draw line across screen
eencae 0:be41a15e7a86 481 }
eencae 0:be41a15e7a86 482 }
eencae 0:be41a15e7a86 483 }
eencae 0:be41a15e7a86 484
eencae 0:be41a15e7a86 485 void N5110::drawSprite(int x0,
eencae 0:be41a15e7a86 486 int y0,
eencae 0:be41a15e7a86 487 int nrows,
eencae 0:be41a15e7a86 488 int ncols,
eencae 0:be41a15e7a86 489 int *sprite)
eencae 0:be41a15e7a86 490 {
eencae 0:be41a15e7a86 491 for (int i = 0; i < nrows; i++) {
eencae 0:be41a15e7a86 492 for (int j = 0 ; j < ncols ; j++) {
eencae 0:be41a15e7a86 493
eencae 0:be41a15e7a86 494 int pixel = *((sprite+i*ncols)+j);
eencae 0:be41a15e7a86 495 setPixel(x0+j,y0+i, pixel);
eencae 0:be41a15e7a86 496 }
eencae 0:be41a15e7a86 497 }
eencae 0:be41a15e7a86 498 }