Harry Rance 200925395 Embedded Systems Project

Dependencies:   mbed

Committer:
harryrance
Date:
Tue Apr 11 17:54:59 2017 +0000
Revision:
0:c9bf674fe0c7
Child:
5:2eb139b24219
REVISED - All changed to object oriented format with separate header files. Back to having an array of aliens moving across and down the screen, speeding up with each increment and Game Over screen appearing when array touches shields. Runs smoother.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
harryrance 0:c9bf674fe0c7 1 #include "mbed.h"
harryrance 0:c9bf674fe0c7 2 #include "N5110.h"
harryrance 0:c9bf674fe0c7 3
harryrance 0:c9bf674fe0c7 4 // overloaded constructor includes power pin - LCD Vcc connected to GPIO pin
harryrance 0:c9bf674fe0c7 5 // this constructor works fine with LPC1768 - enough current sourced from GPIO
harryrance 0:c9bf674fe0c7 6 // to power LCD. Doesn't work well with K64F.
harryrance 0:c9bf674fe0c7 7 N5110::N5110(PinName pwrPin, PinName scePin, PinName rstPin, PinName dcPin, PinName mosiPin, PinName sclkPin, PinName ledPin)
harryrance 0:c9bf674fe0c7 8 {
harryrance 0:c9bf674fe0c7 9 spi = new SPI(mosiPin,NC,sclkPin); // create new SPI instance and initialise
harryrance 0:c9bf674fe0c7 10 // set up pins as required
harryrance 0:c9bf674fe0c7 11 led = new PwmOut(ledPin);
harryrance 0:c9bf674fe0c7 12 pwr = new DigitalOut(pwrPin);
harryrance 0:c9bf674fe0c7 13 sce = new DigitalOut(scePin);
harryrance 0:c9bf674fe0c7 14 rst = new DigitalOut(rstPin);
harryrance 0:c9bf674fe0c7 15 dc = new DigitalOut(dcPin);
harryrance 0:c9bf674fe0c7 16 }
harryrance 0:c9bf674fe0c7 17
harryrance 0:c9bf674fe0c7 18 // overloaded constructor does not include power pin - LCD Vcc must be tied to +3V3
harryrance 0:c9bf674fe0c7 19 // Best to use this with K64F as the GPIO hasn't sufficient output current to reliably
harryrance 0:c9bf674fe0c7 20 // drive the LCD.
harryrance 0:c9bf674fe0c7 21 N5110::N5110(PinName scePin, PinName rstPin, PinName dcPin, PinName mosiPin, PinName sclkPin, PinName ledPin)
harryrance 0:c9bf674fe0c7 22 {
harryrance 0:c9bf674fe0c7 23 spi = new SPI(mosiPin,NC,sclkPin); // create new SPI instance and initialise
harryrance 0:c9bf674fe0c7 24 // set up pins as required
harryrance 0:c9bf674fe0c7 25 pwr = NULL; // pwr not needed so null it to be safe
harryrance 0:c9bf674fe0c7 26 led = new PwmOut(ledPin);
harryrance 0:c9bf674fe0c7 27 sce = new DigitalOut(scePin);
harryrance 0:c9bf674fe0c7 28 rst = new DigitalOut(rstPin);
harryrance 0:c9bf674fe0c7 29 dc = new DigitalOut(dcPin);
harryrance 0:c9bf674fe0c7 30 }
harryrance 0:c9bf674fe0c7 31
harryrance 0:c9bf674fe0c7 32 // initialise function - powers up and sends the initialisation commands
harryrance 0:c9bf674fe0c7 33 void N5110::init()
harryrance 0:c9bf674fe0c7 34 {
harryrance 0:c9bf674fe0c7 35 turnOn(); // power up
harryrance 0:c9bf674fe0c7 36 reset(); // reset LCD - must be done within 100 ms
harryrance 0:c9bf674fe0c7 37
harryrance 0:c9bf674fe0c7 38 initSPI();
harryrance 0:c9bf674fe0c7 39 // function set - extended
harryrance 0:c9bf674fe0c7 40 sendCommand(0x20 | CMD_FS_ACTIVE_MODE | CMD_FS_HORIZONTAL_MODE | CMD_FS_EXTENDED_MODE);
harryrance 0:c9bf674fe0c7 41 // Don't completely understand these parameters - they seem to work as they are
harryrance 0:c9bf674fe0c7 42 // Consult the datasheet if you need to change them
harryrance 0:c9bf674fe0c7 43 sendCommand(CMD_VOP_7V38); // operating voltage - these values are from Chris Yan's Library
harryrance 0:c9bf674fe0c7 44 sendCommand(CMD_TC_TEMP_2); // temperature control
harryrance 0:c9bf674fe0c7 45 sendCommand(CMD_BI_MUX_48); // changing this can sometimes improve the contrast on some displays
harryrance 0:c9bf674fe0c7 46
harryrance 0:c9bf674fe0c7 47 // function set - basic
harryrance 0:c9bf674fe0c7 48 sendCommand(0x20 | CMD_FS_ACTIVE_MODE | CMD_FS_HORIZONTAL_MODE | CMD_FS_BASIC_MODE);
harryrance 0:c9bf674fe0c7 49 normalMode(); // normal video mode by default
harryrance 0:c9bf674fe0c7 50 sendCommand(CMD_DC_NORMAL_MODE); // black on white
harryrance 0:c9bf674fe0c7 51
harryrance 0:c9bf674fe0c7 52 clearRAM(); // RAM is undefined at power-up so clear
harryrance 0:c9bf674fe0c7 53 clear(); // clear buffer
harryrance 0:c9bf674fe0c7 54 setBrightness(0.5);
harryrance 0:c9bf674fe0c7 55 }
harryrance 0:c9bf674fe0c7 56
harryrance 0:c9bf674fe0c7 57 // sets normal video mode (black on white)
harryrance 0:c9bf674fe0c7 58 void N5110::normalMode()
harryrance 0:c9bf674fe0c7 59 {
harryrance 0:c9bf674fe0c7 60 sendCommand(CMD_DC_NORMAL_MODE);
harryrance 0:c9bf674fe0c7 61 }
harryrance 0:c9bf674fe0c7 62
harryrance 0:c9bf674fe0c7 63 // sets normal video mode (white on black)
harryrance 0:c9bf674fe0c7 64 void N5110::inverseMode()
harryrance 0:c9bf674fe0c7 65 {
harryrance 0:c9bf674fe0c7 66 sendCommand(CMD_DC_INVERT_VIDEO);
harryrance 0:c9bf674fe0c7 67 }
harryrance 0:c9bf674fe0c7 68
harryrance 0:c9bf674fe0c7 69 // function to power up the LCD and backlight - only works when using GPIO to power
harryrance 0:c9bf674fe0c7 70 void N5110::turnOn()
harryrance 0:c9bf674fe0c7 71 {
harryrance 0:c9bf674fe0c7 72 if (pwr != NULL) {
harryrance 0:c9bf674fe0c7 73 pwr->write(1); // apply power
harryrance 0:c9bf674fe0c7 74 }
harryrance 0:c9bf674fe0c7 75 }
harryrance 0:c9bf674fe0c7 76
harryrance 0:c9bf674fe0c7 77 // function to power down LCD
harryrance 0:c9bf674fe0c7 78 void N5110::turnOff()
harryrance 0:c9bf674fe0c7 79 {
harryrance 0:c9bf674fe0c7 80 clear(); // clear buffer
harryrance 0:c9bf674fe0c7 81 refresh();
harryrance 0:c9bf674fe0c7 82 setBrightness(0.0); // turn backlight off
harryrance 0:c9bf674fe0c7 83 clearRAM(); // clear RAM to ensure specified current consumption
harryrance 0:c9bf674fe0c7 84 // send command to ensure we are in basic mode
harryrance 0:c9bf674fe0c7 85 sendCommand(0x20 | CMD_FS_ACTIVE_MODE | CMD_FS_HORIZONTAL_MODE | CMD_FS_BASIC_MODE);
harryrance 0:c9bf674fe0c7 86 // clear the display
harryrance 0:c9bf674fe0c7 87 sendCommand(CMD_DC_CLEAR_DISPLAY);
harryrance 0:c9bf674fe0c7 88 // enter the extended mode and power down
harryrance 0:c9bf674fe0c7 89 sendCommand(0x20 | CMD_FS_POWER_DOWN_MODE | CMD_FS_HORIZONTAL_MODE | CMD_FS_EXTENDED_MODE);
harryrance 0:c9bf674fe0c7 90 // small delay and then turn off the power pin
harryrance 0:c9bf674fe0c7 91 wait_ms(10);
harryrance 0:c9bf674fe0c7 92
harryrance 0:c9bf674fe0c7 93 // if we are powering the LCD using the GPIO then make it low to turn off
harryrance 0:c9bf674fe0c7 94 if (pwr != NULL) {
harryrance 0:c9bf674fe0c7 95 pwr->write(0); // turn off power
harryrance 0:c9bf674fe0c7 96 }
harryrance 0:c9bf674fe0c7 97
harryrance 0:c9bf674fe0c7 98 }
harryrance 0:c9bf674fe0c7 99
harryrance 0:c9bf674fe0c7 100 // function to change LED backlight brightness
harryrance 0:c9bf674fe0c7 101 void N5110::setBrightness(float brightness)
harryrance 0:c9bf674fe0c7 102 {
harryrance 0:c9bf674fe0c7 103 // check whether brightness is within range
harryrance 0:c9bf674fe0c7 104 if (brightness < 0.0f)
harryrance 0:c9bf674fe0c7 105 brightness = 0.0f;
harryrance 0:c9bf674fe0c7 106 if (brightness > 1.0f)
harryrance 0:c9bf674fe0c7 107 brightness = 1.0f;
harryrance 0:c9bf674fe0c7 108 // set PWM duty cycle
harryrance 0:c9bf674fe0c7 109 led->write(brightness);
harryrance 0:c9bf674fe0c7 110 }
harryrance 0:c9bf674fe0c7 111
harryrance 0:c9bf674fe0c7 112
harryrance 0:c9bf674fe0c7 113 // pulse the active low reset line
harryrance 0:c9bf674fe0c7 114 void N5110::reset()
harryrance 0:c9bf674fe0c7 115 {
harryrance 0:c9bf674fe0c7 116 rst->write(0); // reset the LCD
harryrance 0:c9bf674fe0c7 117 rst->write(1);
harryrance 0:c9bf674fe0c7 118 }
harryrance 0:c9bf674fe0c7 119
harryrance 0:c9bf674fe0c7 120 // function to initialise SPI peripheral
harryrance 0:c9bf674fe0c7 121 void N5110::initSPI()
harryrance 0:c9bf674fe0c7 122 {
harryrance 0:c9bf674fe0c7 123 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
harryrance 0:c9bf674fe0c7 124 spi->frequency(4000000); // maximum of screen is 4 MHz
harryrance 0:c9bf674fe0c7 125 }
harryrance 0:c9bf674fe0c7 126
harryrance 0:c9bf674fe0c7 127 // send a command to the display
harryrance 0:c9bf674fe0c7 128 void N5110::sendCommand(unsigned char command)
harryrance 0:c9bf674fe0c7 129 {
harryrance 0:c9bf674fe0c7 130 dc->write(0); // set DC low for command
harryrance 0:c9bf674fe0c7 131 sce->write(0); // set CE low to begin frame
harryrance 0:c9bf674fe0c7 132 spi->write(command); // send command
harryrance 0:c9bf674fe0c7 133 dc->write(1); // turn back to data by default
harryrance 0:c9bf674fe0c7 134 sce->write(1); // set CE high to end frame (expected for transmission of single byte)
harryrance 0:c9bf674fe0c7 135
harryrance 0:c9bf674fe0c7 136 }
harryrance 0:c9bf674fe0c7 137
harryrance 0:c9bf674fe0c7 138 // send data to the display at the current XY address
harryrance 0:c9bf674fe0c7 139 // dc is set to 1 (i.e. data) after sending a command and so should
harryrance 0:c9bf674fe0c7 140 // be the default mode.
harryrance 0:c9bf674fe0c7 141 void N5110::sendData(unsigned char data)
harryrance 0:c9bf674fe0c7 142 {
harryrance 0:c9bf674fe0c7 143 sce->write(0); // set CE low to begin frame
harryrance 0:c9bf674fe0c7 144 spi->write(data);
harryrance 0:c9bf674fe0c7 145 sce->write(1); // set CE high to end frame (expected for transmission of single byte)
harryrance 0:c9bf674fe0c7 146 }
harryrance 0:c9bf674fe0c7 147
harryrance 0:c9bf674fe0c7 148 // this function writes 0 to the 504 bytes to clear the RAM
harryrance 0:c9bf674fe0c7 149 void N5110::clearRAM()
harryrance 0:c9bf674fe0c7 150 {
harryrance 0:c9bf674fe0c7 151 sce->write(0); //set CE low to begin frame
harryrance 0:c9bf674fe0c7 152 for(int i = 0; i < WIDTH * HEIGHT; i++) { // 48 x 84 bits = 504 bytes
harryrance 0:c9bf674fe0c7 153 spi->write(0x00); // send 0's
harryrance 0:c9bf674fe0c7 154 }
harryrance 0:c9bf674fe0c7 155 sce->write(1); // set CE high to end frame
harryrance 0:c9bf674fe0c7 156
harryrance 0:c9bf674fe0c7 157 }
harryrance 0:c9bf674fe0c7 158
harryrance 0:c9bf674fe0c7 159 // function to set the XY address in RAM for subsequenct data write
harryrance 0:c9bf674fe0c7 160 void N5110::setXYAddress(int x, int y)
harryrance 0:c9bf674fe0c7 161 {
harryrance 0:c9bf674fe0c7 162 if (x>=0 && x<WIDTH && y>=0 && y<HEIGHT) { // check within range
harryrance 0:c9bf674fe0c7 163 sendCommand(0x80 | x); // send addresses to display with relevant mask
harryrance 0:c9bf674fe0c7 164 sendCommand(0x40 | y);
harryrance 0:c9bf674fe0c7 165 }
harryrance 0:c9bf674fe0c7 166 }
harryrance 0:c9bf674fe0c7 167
harryrance 0:c9bf674fe0c7 168 // These functions are used to set, clear and get the value of pixels in the display
harryrance 0:c9bf674fe0c7 169 // Pixels are addressed in the range of 0 to 47 (y) and 0 to 83 (x). The refresh()
harryrance 0:c9bf674fe0c7 170 // function must be called after set and clear in order to update the display
harryrance 0:c9bf674fe0c7 171 void N5110::setPixel(int x, int y)
harryrance 0:c9bf674fe0c7 172 {
harryrance 0:c9bf674fe0c7 173 if (x>=0 && x<WIDTH && y>=0 && y<HEIGHT) { // check within range
harryrance 0:c9bf674fe0c7 174 // calculate bank and shift 1 to required position in the data byte
harryrance 0:c9bf674fe0c7 175 buffer[x][y/8] |= (1 << y%8);
harryrance 0:c9bf674fe0c7 176 }
harryrance 0:c9bf674fe0c7 177 }
harryrance 0:c9bf674fe0c7 178
harryrance 0:c9bf674fe0c7 179 void N5110::clearPixel(int x, int y)
harryrance 0:c9bf674fe0c7 180 {
harryrance 0:c9bf674fe0c7 181 if (x>=0 && x<WIDTH && y>=0 && y<HEIGHT) { // check within range
harryrance 0:c9bf674fe0c7 182 // calculate bank and shift 1 to required position (using bit clear)
harryrance 0:c9bf674fe0c7 183 buffer[x][y/8] &= ~(1 << y%8);
harryrance 0:c9bf674fe0c7 184 }
harryrance 0:c9bf674fe0c7 185 }
harryrance 0:c9bf674fe0c7 186
harryrance 0:c9bf674fe0c7 187 int N5110::getPixel(int x, int y)
harryrance 0:c9bf674fe0c7 188 {
harryrance 0:c9bf674fe0c7 189 if (x>=0 && x<WIDTH && y>=0 && y<HEIGHT) { // check within range
harryrance 0:c9bf674fe0c7 190 // return relevant bank and mask required bit
harryrance 0:c9bf674fe0c7 191
harryrance 0:c9bf674fe0c7 192 int pixel = (int) buffer[x][y/8] & (1 << y%8);
harryrance 0:c9bf674fe0c7 193
harryrance 0:c9bf674fe0c7 194 if (pixel)
harryrance 0:c9bf674fe0c7 195 return 1;
harryrance 0:c9bf674fe0c7 196 else
harryrance 0:c9bf674fe0c7 197 return 0;
harryrance 0:c9bf674fe0c7 198 }
harryrance 0:c9bf674fe0c7 199
harryrance 0:c9bf674fe0c7 200 return 0;
harryrance 0:c9bf674fe0c7 201
harryrance 0:c9bf674fe0c7 202 }
harryrance 0:c9bf674fe0c7 203
harryrance 0:c9bf674fe0c7 204 // function to refresh the display
harryrance 0:c9bf674fe0c7 205 void N5110::refresh()
harryrance 0:c9bf674fe0c7 206 {
harryrance 0:c9bf674fe0c7 207 setXYAddress(0,0); // important to set address back to 0,0 before refreshing display
harryrance 0:c9bf674fe0c7 208 // address auto increments after printing string, so buffer[0][0] will not coincide
harryrance 0:c9bf674fe0c7 209 // with top-left pixel after priting string
harryrance 0:c9bf674fe0c7 210
harryrance 0:c9bf674fe0c7 211 sce->write(0); //set CE low to begin frame
harryrance 0:c9bf674fe0c7 212
harryrance 0:c9bf674fe0c7 213 for(int j = 0; j < BANKS; j++) { // be careful to use correct order (j,i) for horizontal addressing
harryrance 0:c9bf674fe0c7 214 for(int i = 0; i < WIDTH; i++) {
harryrance 0:c9bf674fe0c7 215 spi->write(buffer[i][j]); // send buffer
harryrance 0:c9bf674fe0c7 216 }
harryrance 0:c9bf674fe0c7 217 }
harryrance 0:c9bf674fe0c7 218 sce->write(1); // set CE high to end frame
harryrance 0:c9bf674fe0c7 219
harryrance 0:c9bf674fe0c7 220 }
harryrance 0:c9bf674fe0c7 221
harryrance 0:c9bf674fe0c7 222 // fills the buffer with random bytes. Can be used to test the display.
harryrance 0:c9bf674fe0c7 223 // The rand() function isn't seeded so it probably creates the same pattern everytime
harryrance 0:c9bf674fe0c7 224 void N5110::randomiseBuffer()
harryrance 0:c9bf674fe0c7 225 {
harryrance 0:c9bf674fe0c7 226 int i,j;
harryrance 0:c9bf674fe0c7 227 for(j = 0; j < BANKS; j++) { // be careful to use correct order (j,i) for horizontal addressing
harryrance 0:c9bf674fe0c7 228 for(i = 0; i < WIDTH; i++) {
harryrance 0:c9bf674fe0c7 229 buffer[i][j] = rand()%256; // generate random byte
harryrance 0:c9bf674fe0c7 230 }
harryrance 0:c9bf674fe0c7 231 }
harryrance 0:c9bf674fe0c7 232
harryrance 0:c9bf674fe0c7 233 }
harryrance 0:c9bf674fe0c7 234
harryrance 0:c9bf674fe0c7 235 // function to print 5x7 font
harryrance 0:c9bf674fe0c7 236 void N5110::printChar(char c,int x,int y)
harryrance 0:c9bf674fe0c7 237 {
harryrance 0:c9bf674fe0c7 238 if (y>=0 && y<BANKS) { // check if printing in range of y banks
harryrance 0:c9bf674fe0c7 239
harryrance 0:c9bf674fe0c7 240 for (int i = 0; i < 5 ; i++ ) {
harryrance 0:c9bf674fe0c7 241 int pixel_x = x+i;
harryrance 0:c9bf674fe0c7 242 if (pixel_x > WIDTH-1) // ensure pixel isn't outside the buffer size (0 - 83)
harryrance 0:c9bf674fe0c7 243 break;
harryrance 0:c9bf674fe0c7 244 buffer[pixel_x][y] = font5x7[(c - 32)*5 + i];
harryrance 0:c9bf674fe0c7 245 // array is offset by 32 relative to ASCII, each character is 5 pixels wide
harryrance 0:c9bf674fe0c7 246 }
harryrance 0:c9bf674fe0c7 247
harryrance 0:c9bf674fe0c7 248 }
harryrance 0:c9bf674fe0c7 249 }
harryrance 0:c9bf674fe0c7 250
harryrance 0:c9bf674fe0c7 251 // function to print string at specified position
harryrance 0:c9bf674fe0c7 252 void N5110::printString(const char * str,int x,int y)
harryrance 0:c9bf674fe0c7 253 {
harryrance 0:c9bf674fe0c7 254 if (y>=0 && y<BANKS) { // check if printing in range of y banks
harryrance 0:c9bf674fe0c7 255
harryrance 0:c9bf674fe0c7 256 int n = 0 ; // counter for number of characters in string
harryrance 0:c9bf674fe0c7 257 // loop through string and print character
harryrance 0:c9bf674fe0c7 258 while(*str) {
harryrance 0:c9bf674fe0c7 259
harryrance 0:c9bf674fe0c7 260 // writes the character bitmap data to the buffer, so that
harryrance 0:c9bf674fe0c7 261 // text and pixels can be displayed at the same time
harryrance 0:c9bf674fe0c7 262 for (int i = 0; i < 5 ; i++ ) {
harryrance 0:c9bf674fe0c7 263 int pixel_x = x+i+n*6;
harryrance 0:c9bf674fe0c7 264 if (pixel_x > WIDTH-1) // ensure pixel isn't outside the buffer size (0 - 83)
harryrance 0:c9bf674fe0c7 265 break;
harryrance 0:c9bf674fe0c7 266 buffer[pixel_x][y] = font5x7[(*str - 32)*5 + i];
harryrance 0:c9bf674fe0c7 267 }
harryrance 0:c9bf674fe0c7 268 str++; // go to next character in string
harryrance 0:c9bf674fe0c7 269 n++; // increment index
harryrance 0:c9bf674fe0c7 270 }
harryrance 0:c9bf674fe0c7 271 }
harryrance 0:c9bf674fe0c7 272 }
harryrance 0:c9bf674fe0c7 273
harryrance 0:c9bf674fe0c7 274 // function to clear the screen buffer
harryrance 0:c9bf674fe0c7 275 void N5110::clear()
harryrance 0:c9bf674fe0c7 276 {
harryrance 0:c9bf674fe0c7 277 memset(buffer,0,sizeof(buffer));
harryrance 0:c9bf674fe0c7 278 }
harryrance 0:c9bf674fe0c7 279
harryrance 0:c9bf674fe0c7 280 // function to plot array on display
harryrance 0:c9bf674fe0c7 281 void N5110::plotArray(float array[])
harryrance 0:c9bf674fe0c7 282 {
harryrance 0:c9bf674fe0c7 283 for (int i=0; i<WIDTH; i++) { // loop through array
harryrance 0:c9bf674fe0c7 284 // elements are normalised from 0.0 to 1.0, so multiply
harryrance 0:c9bf674fe0c7 285 // by 47 to convert to pixel range, and subtract from 47
harryrance 0:c9bf674fe0c7 286 // since top-left is 0,0 in the display geometry
harryrance 0:c9bf674fe0c7 287 setPixel(i,47 - int(array[i]*47.0f));
harryrance 0:c9bf674fe0c7 288 }
harryrance 0:c9bf674fe0c7 289
harryrance 0:c9bf674fe0c7 290 }
harryrance 0:c9bf674fe0c7 291
harryrance 0:c9bf674fe0c7 292 // function to draw circle
harryrance 0:c9bf674fe0c7 293 void N5110:: drawCircle(int x0,int y0,int radius,int fill)
harryrance 0:c9bf674fe0c7 294 {
harryrance 0:c9bf674fe0c7 295 // from http://en.wikipedia.org/wiki/Midpoint_circle_algorithm
harryrance 0:c9bf674fe0c7 296 int x = radius;
harryrance 0:c9bf674fe0c7 297 int y = 0;
harryrance 0:c9bf674fe0c7 298 int radiusError = 1-x;
harryrance 0:c9bf674fe0c7 299
harryrance 0:c9bf674fe0c7 300 while(x >= y) {
harryrance 0:c9bf674fe0c7 301
harryrance 0:c9bf674fe0c7 302 // if transparent, just draw outline
harryrance 0:c9bf674fe0c7 303 if (fill == 0) {
harryrance 0:c9bf674fe0c7 304 setPixel( x + x0, y + y0);
harryrance 0:c9bf674fe0c7 305 setPixel(-x + x0, y + y0);
harryrance 0:c9bf674fe0c7 306 setPixel( y + x0, x + y0);
harryrance 0:c9bf674fe0c7 307 setPixel(-y + x0, x + y0);
harryrance 0:c9bf674fe0c7 308 setPixel(-y + x0, -x + y0);
harryrance 0:c9bf674fe0c7 309 setPixel( y + x0, -x + y0);
harryrance 0:c9bf674fe0c7 310 setPixel( x + x0, -y + y0);
harryrance 0:c9bf674fe0c7 311 setPixel(-x + x0, -y + y0);
harryrance 0:c9bf674fe0c7 312 } else { // drawing filled circle, so draw lines between points at same y value
harryrance 0:c9bf674fe0c7 313
harryrance 0:c9bf674fe0c7 314 int type = (fill==1) ? 1:0; // black or white fill
harryrance 0:c9bf674fe0c7 315
harryrance 0:c9bf674fe0c7 316 drawLine(x+x0,y+y0,-x+x0,y+y0,type);
harryrance 0:c9bf674fe0c7 317 drawLine(y+x0,x+y0,-y+x0,x+y0,type);
harryrance 0:c9bf674fe0c7 318 drawLine(y+x0,-x+y0,-y+x0,-x+y0,type);
harryrance 0:c9bf674fe0c7 319 drawLine(x+x0,-y+y0,-x+x0,-y+y0,type);
harryrance 0:c9bf674fe0c7 320 }
harryrance 0:c9bf674fe0c7 321
harryrance 0:c9bf674fe0c7 322 y++;
harryrance 0:c9bf674fe0c7 323 if (radiusError<0) {
harryrance 0:c9bf674fe0c7 324 radiusError += 2 * y + 1;
harryrance 0:c9bf674fe0c7 325 } else {
harryrance 0:c9bf674fe0c7 326 x--;
harryrance 0:c9bf674fe0c7 327 radiusError += 2 * (y - x) + 1;
harryrance 0:c9bf674fe0c7 328 }
harryrance 0:c9bf674fe0c7 329 }
harryrance 0:c9bf674fe0c7 330
harryrance 0:c9bf674fe0c7 331 }
harryrance 0:c9bf674fe0c7 332
harryrance 0:c9bf674fe0c7 333 void N5110::drawLine(int x0,int y0,int x1,int y1,int type)
harryrance 0:c9bf674fe0c7 334 {
harryrance 0:c9bf674fe0c7 335 int y_range = y1-y0; // calc range of y and x
harryrance 0:c9bf674fe0c7 336 int x_range = x1-x0;
harryrance 0:c9bf674fe0c7 337 int start,stop,step;
harryrance 0:c9bf674fe0c7 338
harryrance 0:c9bf674fe0c7 339 // if dotted line, set step to 2, else step is 1
harryrance 0:c9bf674fe0c7 340 step = (type==2) ? 2:1;
harryrance 0:c9bf674fe0c7 341
harryrance 0:c9bf674fe0c7 342 // make sure we loop over the largest range to get the most pixels on the display
harryrance 0:c9bf674fe0c7 343 // for instance, if drawing a vertical line (x_range = 0), we need to loop down the y pixels
harryrance 0:c9bf674fe0c7 344 // or else we'll only end up with 1 pixel in the x column
harryrance 0:c9bf674fe0c7 345 if ( abs(x_range) > abs(y_range) ) {
harryrance 0:c9bf674fe0c7 346
harryrance 0:c9bf674fe0c7 347 // ensure we loop from smallest to largest or else for-loop won't run as expected
harryrance 0:c9bf674fe0c7 348 start = x1>x0 ? x0:x1;
harryrance 0:c9bf674fe0c7 349 stop = x1>x0 ? x1:x0;
harryrance 0:c9bf674fe0c7 350
harryrance 0:c9bf674fe0c7 351 // loop between x pixels
harryrance 0:c9bf674fe0c7 352 for (int x = start; x<= stop ; x+=step) {
harryrance 0:c9bf674fe0c7 353 // do linear interpolation
harryrance 0:c9bf674fe0c7 354 int y = y0 + (y1-y0)*(x-x0)/(x1-x0);
harryrance 0:c9bf674fe0c7 355
harryrance 0:c9bf674fe0c7 356 if (type == 0) // if 'white' line, turn off pixel
harryrance 0:c9bf674fe0c7 357 clearPixel(x,y);
harryrance 0:c9bf674fe0c7 358 else
harryrance 0:c9bf674fe0c7 359 setPixel(x,y); // else if 'black' or 'dotted' turn on pixel
harryrance 0:c9bf674fe0c7 360 }
harryrance 0:c9bf674fe0c7 361 } else {
harryrance 0:c9bf674fe0c7 362
harryrance 0:c9bf674fe0c7 363 // ensure we loop from smallest to largest or else for-loop won't run as expected
harryrance 0:c9bf674fe0c7 364 start = y1>y0 ? y0:y1;
harryrance 0:c9bf674fe0c7 365 stop = y1>y0 ? y1:y0;
harryrance 0:c9bf674fe0c7 366
harryrance 0:c9bf674fe0c7 367 for (int y = start; y<= stop ; y+=step) {
harryrance 0:c9bf674fe0c7 368 // do linear interpolation
harryrance 0:c9bf674fe0c7 369 int x = x0 + (x1-x0)*(y-y0)/(y1-y0);
harryrance 0:c9bf674fe0c7 370
harryrance 0:c9bf674fe0c7 371 if (type == 0) // if 'white' line, turn off pixel
harryrance 0:c9bf674fe0c7 372 clearPixel(x,y);
harryrance 0:c9bf674fe0c7 373 else
harryrance 0:c9bf674fe0c7 374 setPixel(x,y); // else if 'black' or 'dotted' turn on pixel
harryrance 0:c9bf674fe0c7 375
harryrance 0:c9bf674fe0c7 376 }
harryrance 0:c9bf674fe0c7 377 }
harryrance 0:c9bf674fe0c7 378
harryrance 0:c9bf674fe0c7 379 }
harryrance 0:c9bf674fe0c7 380
harryrance 0:c9bf674fe0c7 381 void N5110::drawRect(int x0,int y0,int width,int height,int fill)
harryrance 0:c9bf674fe0c7 382 {
harryrance 0:c9bf674fe0c7 383 if (fill == 0) { // transparent, just outline
harryrance 0:c9bf674fe0c7 384 drawLine(x0,y0,x0+(width-1),y0,1); // top
harryrance 0:c9bf674fe0c7 385 drawLine(x0,y0+(height-1),x0+(width-1),y0+(height-1),1); // bottom
harryrance 0:c9bf674fe0c7 386 drawLine(x0,y0,x0,y0+(height-1),1); // left
harryrance 0:c9bf674fe0c7 387 drawLine(x0+(width-1),y0,x0+(width-1),y0+(height-1),1); // right
harryrance 0:c9bf674fe0c7 388 } else { // filled rectangle
harryrance 0:c9bf674fe0c7 389 int type = (fill==1) ? 1:0; // black or white fill
harryrance 0:c9bf674fe0c7 390 for (int y = y0; y<y0+height; y++) { // loop through rows of rectangle
harryrance 0:c9bf674fe0c7 391 drawLine(x0,y,x0+(width-1),y,type); // draw line across screen
harryrance 0:c9bf674fe0c7 392 }
harryrance 0:c9bf674fe0c7 393 }
harryrance 0:c9bf674fe0c7 394 }
harryrance 0:c9bf674fe0c7 395