All there but errors need fixing

Dependencies:   mbed

Overview:

Rookie Tetris is a jigsaw style game based on the classic Tetris.

A block will appear at the top of the screen, you must move it (your options for movement are left, right and down - you cannot move up the board). The block will stop when it if placed either on the floor of the board or on-top of another block.

Your goal is to fill a complete row of the board with the blocks; when you do so the row will delete and the pattern above it will drop down. The game is over when your pattern is tall enough to reach to the top of the board!

Controls:

Use the joystick to move your block! Your block cannot move out of the parameters of the board.

Pot 2 controls the contrast of the screen.

Committer:
el18rs
Date:
Fri May 22 10:36:01 2020 +0000
Revision:
1:35dba0833c7d
Start

Who changed what in which revision?

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