Frank Duignan
/
NRF52832_ili9341
Basic driver working
display.cpp@80:ff42f77928ad, 2021-02-03 (annotated)
- Committer:
- f3d
- Date:
- Wed Feb 03 11:30:30 2021 +0000
- Revision:
- 80:ff42f77928ad
- Child:
- 81:7087ba9d18bb
Basic driver working
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
f3d | 80:ff42f77928ad | 1 | #include "mbed.h" |
f3d | 80:ff42f77928ad | 2 | #include "display.h" |
f3d | 80:ff42f77928ad | 3 | //mosi,miso,clk,ss |
f3d | 80:ff42f77928ad | 4 | SPI spi(P0_25,P0_26,P0_27,P0_28); |
f3d | 80:ff42f77928ad | 5 | DigitalOut Rst(P0_7); |
f3d | 80:ff42f77928ad | 6 | DigitalOut DC(P0_6); |
f3d | 80:ff42f77928ad | 7 | |
f3d | 80:ff42f77928ad | 8 | void Display::begin() |
f3d | 80:ff42f77928ad | 9 | { |
f3d | 80:ff42f77928ad | 10 | while(0) |
f3d | 80:ff42f77928ad | 11 | { |
f3d | 80:ff42f77928ad | 12 | DC = 1; |
f3d | 80:ff42f77928ad | 13 | Rst = 1; |
f3d | 80:ff42f77928ad | 14 | wait(0.5); |
f3d | 80:ff42f77928ad | 15 | DC = 0; |
f3d | 80:ff42f77928ad | 16 | Rst = 0; |
f3d | 80:ff42f77928ad | 17 | wait(0.5); |
f3d | 80:ff42f77928ad | 18 | } |
f3d | 80:ff42f77928ad | 19 | spi.format(8, 0); |
f3d | 80:ff42f77928ad | 20 | spi.frequency(8000000); |
f3d | 80:ff42f77928ad | 21 | resetDisplay(); |
f3d | 80:ff42f77928ad | 22 | |
f3d | 80:ff42f77928ad | 23 | LCD_Write_Cmd(0xC0); // Power control |
f3d | 80:ff42f77928ad | 24 | LCD_Write_Data(0x21); // Set GVDD (varies contrast) |
f3d | 80:ff42f77928ad | 25 | |
f3d | 80:ff42f77928ad | 26 | LCD_Write_Cmd(0xC1); // Power control |
f3d | 80:ff42f77928ad | 27 | LCD_Write_Data(0x10); // default value |
f3d | 80:ff42f77928ad | 28 | |
f3d | 80:ff42f77928ad | 29 | LCD_Write_Cmd(0xC5); //VCM control |
f3d | 80:ff42f77928ad | 30 | LCD_Write_Data(0x31); // default values |
f3d | 80:ff42f77928ad | 31 | LCD_Write_Data(0x3c); // |
f3d | 80:ff42f77928ad | 32 | |
f3d | 80:ff42f77928ad | 33 | LCD_Write_Cmd(0xC7); //VCM control2 |
f3d | 80:ff42f77928ad | 34 | LCD_Write_Data(0xc0); // default value |
f3d | 80:ff42f77928ad | 35 | |
f3d | 80:ff42f77928ad | 36 | LCD_Write_Cmd(0x36); // Memory Access Control |
f3d | 80:ff42f77928ad | 37 | LCD_Write_Data(0x48); // Set display orientation and RGB colour order |
f3d | 80:ff42f77928ad | 38 | |
f3d | 80:ff42f77928ad | 39 | LCD_Write_Cmd(0x3A); // Set Pixel format |
f3d | 80:ff42f77928ad | 40 | LCD_Write_Data(0x55); // To 16 bits per pixel |
f3d | 80:ff42f77928ad | 41 | |
f3d | 80:ff42f77928ad | 42 | LCD_Write_Cmd(0xB1); // Frame rate control |
f3d | 80:ff42f77928ad | 43 | LCD_Write_Data(0x00); // Use Fosc without divisor |
f3d | 80:ff42f77928ad | 44 | LCD_Write_Data(0x1B); // set 70Hz refresh rate |
f3d | 80:ff42f77928ad | 45 | |
f3d | 80:ff42f77928ad | 46 | LCD_Write_Cmd(0xB6); // Display Function Control |
f3d | 80:ff42f77928ad | 47 | LCD_Write_Data(0x00); // Use default values |
f3d | 80:ff42f77928ad | 48 | LCD_Write_Data(0x82); |
f3d | 80:ff42f77928ad | 49 | LCD_Write_Data(0x27); |
f3d | 80:ff42f77928ad | 50 | |
f3d | 80:ff42f77928ad | 51 | LCD_Write_Cmd(0x11); //Exit Sleep |
f3d | 80:ff42f77928ad | 52 | wait(0.120); |
f3d | 80:ff42f77928ad | 53 | |
f3d | 80:ff42f77928ad | 54 | LCD_Write_Cmd(0x29); //Display on |
f3d | 80:ff42f77928ad | 55 | LCD_Write_Cmd(0x2c); |
f3d | 80:ff42f77928ad | 56 | wait(0.005); |
f3d | 80:ff42f77928ad | 57 | |
f3d | 80:ff42f77928ad | 58 | fillRectangle(0,0,SCREEN_WIDTH,SCREEN_HEIGHT,RGBToWord(0,0,0)); |
f3d | 80:ff42f77928ad | 59 | |
f3d | 80:ff42f77928ad | 60 | |
f3d | 80:ff42f77928ad | 61 | } |
f3d | 80:ff42f77928ad | 62 | |
f3d | 80:ff42f77928ad | 63 | void Display::CommandMode() |
f3d | 80:ff42f77928ad | 64 | { |
f3d | 80:ff42f77928ad | 65 | DC = 0; |
f3d | 80:ff42f77928ad | 66 | } |
f3d | 80:ff42f77928ad | 67 | void Display::DataMode() |
f3d | 80:ff42f77928ad | 68 | { |
f3d | 80:ff42f77928ad | 69 | DC = 1; |
f3d | 80:ff42f77928ad | 70 | } |
f3d | 80:ff42f77928ad | 71 | void Display::LCD_Write_Cmd(uint8_t cmd) |
f3d | 80:ff42f77928ad | 72 | { |
f3d | 80:ff42f77928ad | 73 | CommandMode(); |
f3d | 80:ff42f77928ad | 74 | spi.write(cmd); |
f3d | 80:ff42f77928ad | 75 | } |
f3d | 80:ff42f77928ad | 76 | void Display::LCD_Write_Data(uint8_t data) |
f3d | 80:ff42f77928ad | 77 | { |
f3d | 80:ff42f77928ad | 78 | DataMode(); |
f3d | 80:ff42f77928ad | 79 | spi.write(data); |
f3d | 80:ff42f77928ad | 80 | } |
f3d | 80:ff42f77928ad | 81 | void Display::resetDisplay() |
f3d | 80:ff42f77928ad | 82 | { |
f3d | 80:ff42f77928ad | 83 | Rst = 0; |
f3d | 80:ff42f77928ad | 84 | wait(0.01); |
f3d | 80:ff42f77928ad | 85 | Rst = 1; |
f3d | 80:ff42f77928ad | 86 | wait(0.12); |
f3d | 80:ff42f77928ad | 87 | } |
f3d | 80:ff42f77928ad | 88 | void Display::openAperture(uint16_t x1,uint16_t y1,uint16_t x2,uint16_t y2) |
f3d | 80:ff42f77928ad | 89 | { |
f3d | 80:ff42f77928ad | 90 | LCD_Write_Cmd(0x2a); |
f3d | 80:ff42f77928ad | 91 | LCD_Write_Data(x1>>8); |
f3d | 80:ff42f77928ad | 92 | LCD_Write_Data(x1); |
f3d | 80:ff42f77928ad | 93 | LCD_Write_Data(x2>>8); |
f3d | 80:ff42f77928ad | 94 | LCD_Write_Data(x2); |
f3d | 80:ff42f77928ad | 95 | LCD_Write_Cmd(0x2b); |
f3d | 80:ff42f77928ad | 96 | LCD_Write_Data(y1>>8); |
f3d | 80:ff42f77928ad | 97 | LCD_Write_Data(y1); |
f3d | 80:ff42f77928ad | 98 | LCD_Write_Data(y2>>8); |
f3d | 80:ff42f77928ad | 99 | LCD_Write_Data(y2); |
f3d | 80:ff42f77928ad | 100 | LCD_Write_Cmd(0x2c); |
f3d | 80:ff42f77928ad | 101 | } |
f3d | 80:ff42f77928ad | 102 | // Simple Pixel drawing routines |
f3d | 80:ff42f77928ad | 103 | void Display::putPixel(uint16_t x, uint16_t y, uint16_t Colour) |
f3d | 80:ff42f77928ad | 104 | { |
f3d | 80:ff42f77928ad | 105 | uint16_t rx; |
f3d | 80:ff42f77928ad | 106 | openAperture(x,y,x+1,y+1); |
f3d | 80:ff42f77928ad | 107 | DataMode(); |
f3d | 80:ff42f77928ad | 108 | spi.write((const char *) &Colour,2,(char *)&rx,0); |
f3d | 80:ff42f77928ad | 109 | } |
f3d | 80:ff42f77928ad | 110 | void Display::putImage(uint16_t x, uint16_t y, uint16_t width, uint16_t height, const uint16_t *Image) |
f3d | 80:ff42f77928ad | 111 | { |
f3d | 80:ff42f77928ad | 112 | uint16_t rx; |
f3d | 80:ff42f77928ad | 113 | uint16_t Colour; |
f3d | 80:ff42f77928ad | 114 | openAperture(x,y,width,height); |
f3d | 80:ff42f77928ad | 115 | for (y = 0; y < height; y++) |
f3d | 80:ff42f77928ad | 116 | for (x=0; x < width; x++) |
f3d | 80:ff42f77928ad | 117 | { |
f3d | 80:ff42f77928ad | 118 | Colour = *(Image++); |
f3d | 80:ff42f77928ad | 119 | spi.write((const char *) &Colour,2,(char *)&rx,0); |
f3d | 80:ff42f77928ad | 120 | } |
f3d | 80:ff42f77928ad | 121 | } |
f3d | 80:ff42f77928ad | 122 | void Display::fillRectangle(uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint16_t Colour) |
f3d | 80:ff42f77928ad | 123 | { |
f3d | 80:ff42f77928ad | 124 | /* in an effort to reduce overhead here a large word buffer is created. If the number of words to |
f3d | 80:ff42f77928ad | 125 | to write is greater than or equal to the size of this buffer then it is filled with the relevant colour |
f3d | 80:ff42f77928ad | 126 | and used as the source of data in the spi.write function. This greatly speeds up the writing of |
f3d | 80:ff42f77928ad | 127 | large arease of the screen. The choice of buffer size is interesting. |
f3d | 80:ff42f77928ad | 128 | */ |
f3d | 80:ff42f77928ad | 129 | #define BUF_SIZE 32 |
f3d | 80:ff42f77928ad | 130 | uint16_t rx; |
f3d | 80:ff42f77928ad | 131 | uint16_t txBuffer[BUF_SIZE]; |
f3d | 80:ff42f77928ad | 132 | int count; |
f3d | 80:ff42f77928ad | 133 | openAperture(x,y,width,height); |
f3d | 80:ff42f77928ad | 134 | DataMode(); |
f3d | 80:ff42f77928ad | 135 | count = (width*height)/BUF_SIZE; |
f3d | 80:ff42f77928ad | 136 | if (count) |
f3d | 80:ff42f77928ad | 137 | { // big area |
f3d | 80:ff42f77928ad | 138 | for (int i=0;i<BUF_SIZE;i++) |
f3d | 80:ff42f77928ad | 139 | { |
f3d | 80:ff42f77928ad | 140 | txBuffer[i]=Colour; |
f3d | 80:ff42f77928ad | 141 | } |
f3d | 80:ff42f77928ad | 142 | while(count--) |
f3d | 80:ff42f77928ad | 143 | { |
f3d | 80:ff42f77928ad | 144 | spi.write((const char *)txBuffer,2*BUF_SIZE,(char *)&rx,0); |
f3d | 80:ff42f77928ad | 145 | } |
f3d | 80:ff42f77928ad | 146 | count = (width*height)%BUF_SIZE; // write remainder of block |
f3d | 80:ff42f77928ad | 147 | while (count--) |
f3d | 80:ff42f77928ad | 148 | { |
f3d | 80:ff42f77928ad | 149 | spi.write((const char *) &Colour,2,(char *)&rx,0); // write a block of colour |
f3d | 80:ff42f77928ad | 150 | } |
f3d | 80:ff42f77928ad | 151 | |
f3d | 80:ff42f77928ad | 152 | } |
f3d | 80:ff42f77928ad | 153 | else |
f3d | 80:ff42f77928ad | 154 | { |
f3d | 80:ff42f77928ad | 155 | // small area so write 1 word at a time. |
f3d | 80:ff42f77928ad | 156 | count = (width*height); |
f3d | 80:ff42f77928ad | 157 | while(count--) |
f3d | 80:ff42f77928ad | 158 | { |
f3d | 80:ff42f77928ad | 159 | spi.write((const char *) &Colour,2,(char *)&rx,0); |
f3d | 80:ff42f77928ad | 160 | } |
f3d | 80:ff42f77928ad | 161 | |
f3d | 80:ff42f77928ad | 162 | } |
f3d | 80:ff42f77928ad | 163 | } |
f3d | 80:ff42f77928ad | 164 | |
f3d | 80:ff42f77928ad | 165 | void Display::drawLineLowSlope(uint16_t x0, uint16_t y0, uint16_t x1,uint16_t y1, uint16_t Colour) |
f3d | 80:ff42f77928ad | 166 | { |
f3d | 80:ff42f77928ad | 167 | // Reference : https://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm |
f3d | 80:ff42f77928ad | 168 | int dx = x1 - x0; |
f3d | 80:ff42f77928ad | 169 | int dy = y1 - y0; |
f3d | 80:ff42f77928ad | 170 | int yi = 1; |
f3d | 80:ff42f77928ad | 171 | if (dy < 0) |
f3d | 80:ff42f77928ad | 172 | { |
f3d | 80:ff42f77928ad | 173 | yi = -1; |
f3d | 80:ff42f77928ad | 174 | dy = -dy; |
f3d | 80:ff42f77928ad | 175 | } |
f3d | 80:ff42f77928ad | 176 | int D = 2*dy - dx; |
f3d | 80:ff42f77928ad | 177 | |
f3d | 80:ff42f77928ad | 178 | int y = y0; |
f3d | 80:ff42f77928ad | 179 | |
f3d | 80:ff42f77928ad | 180 | for (int x=x0; x <= x1;x++) |
f3d | 80:ff42f77928ad | 181 | { |
f3d | 80:ff42f77928ad | 182 | putPixel(x,y,Colour); |
f3d | 80:ff42f77928ad | 183 | if (D > 0) |
f3d | 80:ff42f77928ad | 184 | { |
f3d | 80:ff42f77928ad | 185 | y = y + yi; |
f3d | 80:ff42f77928ad | 186 | D = D - 2*dx; |
f3d | 80:ff42f77928ad | 187 | } |
f3d | 80:ff42f77928ad | 188 | D = D + 2*dy; |
f3d | 80:ff42f77928ad | 189 | |
f3d | 80:ff42f77928ad | 190 | } |
f3d | 80:ff42f77928ad | 191 | } |
f3d | 80:ff42f77928ad | 192 | |
f3d | 80:ff42f77928ad | 193 | void Display::drawLineHighSlope(uint16_t x0, uint16_t y0, uint16_t x1,uint16_t y1, uint16_t Colour) |
f3d | 80:ff42f77928ad | 194 | { |
f3d | 80:ff42f77928ad | 195 | // Reference : https://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm |
f3d | 80:ff42f77928ad | 196 | |
f3d | 80:ff42f77928ad | 197 | int dx = x1 - x0; |
f3d | 80:ff42f77928ad | 198 | int dy = y1 - y0; |
f3d | 80:ff42f77928ad | 199 | int xi = 1; |
f3d | 80:ff42f77928ad | 200 | if (dx < 0) |
f3d | 80:ff42f77928ad | 201 | { |
f3d | 80:ff42f77928ad | 202 | xi = -1; |
f3d | 80:ff42f77928ad | 203 | dx = -dx; |
f3d | 80:ff42f77928ad | 204 | } |
f3d | 80:ff42f77928ad | 205 | int D = 2*dx - dy; |
f3d | 80:ff42f77928ad | 206 | int x = x0; |
f3d | 80:ff42f77928ad | 207 | |
f3d | 80:ff42f77928ad | 208 | for (int y=y0; y <= y1; y++) |
f3d | 80:ff42f77928ad | 209 | { |
f3d | 80:ff42f77928ad | 210 | putPixel(x,y,Colour); |
f3d | 80:ff42f77928ad | 211 | if (D > 0) |
f3d | 80:ff42f77928ad | 212 | { |
f3d | 80:ff42f77928ad | 213 | x = x + xi; |
f3d | 80:ff42f77928ad | 214 | D = D - 2*dy; |
f3d | 80:ff42f77928ad | 215 | } |
f3d | 80:ff42f77928ad | 216 | D = D + 2*dx; |
f3d | 80:ff42f77928ad | 217 | } |
f3d | 80:ff42f77928ad | 218 | } |
f3d | 80:ff42f77928ad | 219 | void Display::drawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t Colour) |
f3d | 80:ff42f77928ad | 220 | { |
f3d | 80:ff42f77928ad | 221 | // Reference : https://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm |
f3d | 80:ff42f77928ad | 222 | if ( iabs(y1 - y0) < iabs(x1 - x0) ) |
f3d | 80:ff42f77928ad | 223 | { |
f3d | 80:ff42f77928ad | 224 | if (x0 > x1) |
f3d | 80:ff42f77928ad | 225 | { |
f3d | 80:ff42f77928ad | 226 | drawLineLowSlope(x1, y1, x0, y0, Colour); |
f3d | 80:ff42f77928ad | 227 | } |
f3d | 80:ff42f77928ad | 228 | else |
f3d | 80:ff42f77928ad | 229 | { |
f3d | 80:ff42f77928ad | 230 | drawLineLowSlope(x0, y0, x1, y1, Colour); |
f3d | 80:ff42f77928ad | 231 | } |
f3d | 80:ff42f77928ad | 232 | } |
f3d | 80:ff42f77928ad | 233 | else |
f3d | 80:ff42f77928ad | 234 | { |
f3d | 80:ff42f77928ad | 235 | if (y0 > y1) |
f3d | 80:ff42f77928ad | 236 | { |
f3d | 80:ff42f77928ad | 237 | drawLineHighSlope(x1, y1, x0, y0, Colour); |
f3d | 80:ff42f77928ad | 238 | } |
f3d | 80:ff42f77928ad | 239 | else |
f3d | 80:ff42f77928ad | 240 | { |
f3d | 80:ff42f77928ad | 241 | drawLineHighSlope(x0, y0, x1, y1, Colour); |
f3d | 80:ff42f77928ad | 242 | } |
f3d | 80:ff42f77928ad | 243 | |
f3d | 80:ff42f77928ad | 244 | } |
f3d | 80:ff42f77928ad | 245 | } |
f3d | 80:ff42f77928ad | 246 | |
f3d | 80:ff42f77928ad | 247 | |
f3d | 80:ff42f77928ad | 248 | uint16_t Display::RGBToWord(uint16_t R, uint16_t G, uint16_t B) |
f3d | 80:ff42f77928ad | 249 | { |
f3d | 80:ff42f77928ad | 250 | uint16_t rvalue = 0; |
f3d | 80:ff42f77928ad | 251 | rvalue += G >> 5; |
f3d | 80:ff42f77928ad | 252 | rvalue += (G & (0b111)) << 13; |
f3d | 80:ff42f77928ad | 253 | rvalue += (B >> 3) << 8; |
f3d | 80:ff42f77928ad | 254 | rvalue += (R >> 3) << 3; |
f3d | 80:ff42f77928ad | 255 | return rvalue; |
f3d | 80:ff42f77928ad | 256 | } |
f3d | 80:ff42f77928ad | 257 | void Display::drawRectangle(uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint16_t Colour) |
f3d | 80:ff42f77928ad | 258 | { |
f3d | 80:ff42f77928ad | 259 | drawLine(x,y,x+w,y,Colour); |
f3d | 80:ff42f77928ad | 260 | drawLine(x,y,x,y+h,Colour); |
f3d | 80:ff42f77928ad | 261 | drawLine(x+w,y,x+w,y+h,Colour); |
f3d | 80:ff42f77928ad | 262 | drawLine(x,y+h,x+w,y+h,Colour); |
f3d | 80:ff42f77928ad | 263 | } |
f3d | 80:ff42f77928ad | 264 | |
f3d | 80:ff42f77928ad | 265 | void Display::drawCircle(uint16_t x0, uint16_t y0, uint16_t radius, uint16_t Colour) |
f3d | 80:ff42f77928ad | 266 | { |
f3d | 80:ff42f77928ad | 267 | // Reference : https://en.wikipedia.org/wiki/Midpoint_circle_algorithm |
f3d | 80:ff42f77928ad | 268 | int x = radius-1; |
f3d | 80:ff42f77928ad | 269 | int y = 0; |
f3d | 80:ff42f77928ad | 270 | int dx = 1; |
f3d | 80:ff42f77928ad | 271 | int dy = 1; |
f3d | 80:ff42f77928ad | 272 | int err = dx - (radius << 1); |
f3d | 80:ff42f77928ad | 273 | if (radius > x0) |
f3d | 80:ff42f77928ad | 274 | return; // don't draw even parially off-screen circles |
f3d | 80:ff42f77928ad | 275 | if (radius > y0) |
f3d | 80:ff42f77928ad | 276 | return; // don't draw even parially off-screen circles |
f3d | 80:ff42f77928ad | 277 | |
f3d | 80:ff42f77928ad | 278 | if ((x0+radius) > SCREEN_WIDTH) |
f3d | 80:ff42f77928ad | 279 | return; // don't draw even parially off-screen circles |
f3d | 80:ff42f77928ad | 280 | if ((y0+radius) > SCREEN_HEIGHT) |
f3d | 80:ff42f77928ad | 281 | return; // don't draw even parially off-screen circles |
f3d | 80:ff42f77928ad | 282 | while (x >= y) |
f3d | 80:ff42f77928ad | 283 | { |
f3d | 80:ff42f77928ad | 284 | putPixel(x0 + x, y0 + y, Colour); |
f3d | 80:ff42f77928ad | 285 | putPixel(x0 + y, y0 + x, Colour); |
f3d | 80:ff42f77928ad | 286 | putPixel(x0 - y, y0 + x, Colour); |
f3d | 80:ff42f77928ad | 287 | putPixel(x0 - x, y0 + y, Colour); |
f3d | 80:ff42f77928ad | 288 | putPixel(x0 - x, y0 - y, Colour); |
f3d | 80:ff42f77928ad | 289 | putPixel(x0 - y, y0 - x, Colour); |
f3d | 80:ff42f77928ad | 290 | putPixel(x0 + y, y0 - x, Colour); |
f3d | 80:ff42f77928ad | 291 | putPixel(x0 + x, y0 - y, Colour); |
f3d | 80:ff42f77928ad | 292 | |
f3d | 80:ff42f77928ad | 293 | if (err <= 0) |
f3d | 80:ff42f77928ad | 294 | { |
f3d | 80:ff42f77928ad | 295 | y++; |
f3d | 80:ff42f77928ad | 296 | err += dy; |
f3d | 80:ff42f77928ad | 297 | dy += 2; |
f3d | 80:ff42f77928ad | 298 | } |
f3d | 80:ff42f77928ad | 299 | |
f3d | 80:ff42f77928ad | 300 | if (err > 0) |
f3d | 80:ff42f77928ad | 301 | { |
f3d | 80:ff42f77928ad | 302 | x--; |
f3d | 80:ff42f77928ad | 303 | dx += 2; |
f3d | 80:ff42f77928ad | 304 | err += dx - (radius << 1); |
f3d | 80:ff42f77928ad | 305 | } |
f3d | 80:ff42f77928ad | 306 | } |
f3d | 80:ff42f77928ad | 307 | } |
f3d | 80:ff42f77928ad | 308 | void Display::fillCircle(uint16_t x0, uint16_t y0, uint16_t radius, uint16_t Colour) |
f3d | 80:ff42f77928ad | 309 | { |
f3d | 80:ff42f77928ad | 310 | // Reference : https://en.wikipedia.org/wiki/Midpoint_circle_algorithm |
f3d | 80:ff42f77928ad | 311 | // Similar to drawCircle but fills the circle with lines instead |
f3d | 80:ff42f77928ad | 312 | int x = radius-1; |
f3d | 80:ff42f77928ad | 313 | int y = 0; |
f3d | 80:ff42f77928ad | 314 | int dx = 1; |
f3d | 80:ff42f77928ad | 315 | int dy = 1; |
f3d | 80:ff42f77928ad | 316 | int err = dx - (radius << 1); |
f3d | 80:ff42f77928ad | 317 | |
f3d | 80:ff42f77928ad | 318 | if (radius > x0) |
f3d | 80:ff42f77928ad | 319 | return; // don't draw even parially off-screen circles |
f3d | 80:ff42f77928ad | 320 | if (radius > y0) |
f3d | 80:ff42f77928ad | 321 | return; // don't draw even parially off-screen circles |
f3d | 80:ff42f77928ad | 322 | |
f3d | 80:ff42f77928ad | 323 | if ((x0+radius) > SCREEN_WIDTH) |
f3d | 80:ff42f77928ad | 324 | return; // don't draw even parially off-screen circles |
f3d | 80:ff42f77928ad | 325 | if ((y0+radius) > SCREEN_HEIGHT) |
f3d | 80:ff42f77928ad | 326 | return; // don't draw even parially off-screen circles |
f3d | 80:ff42f77928ad | 327 | while (x >= y) |
f3d | 80:ff42f77928ad | 328 | { |
f3d | 80:ff42f77928ad | 329 | drawLine(x0 - x, y0 + y,x0 + x, y0 + y, Colour); |
f3d | 80:ff42f77928ad | 330 | drawLine(x0 - y, y0 + x,x0 + y, y0 + x, Colour); |
f3d | 80:ff42f77928ad | 331 | drawLine(x0 - x, y0 - y,x0 + x, y0 - y, Colour); |
f3d | 80:ff42f77928ad | 332 | drawLine(x0 - y, y0 - x,x0 + y, y0 - x, Colour); |
f3d | 80:ff42f77928ad | 333 | |
f3d | 80:ff42f77928ad | 334 | if (err <= 0) |
f3d | 80:ff42f77928ad | 335 | { |
f3d | 80:ff42f77928ad | 336 | y++; |
f3d | 80:ff42f77928ad | 337 | err += dy; |
f3d | 80:ff42f77928ad | 338 | dy += 2; |
f3d | 80:ff42f77928ad | 339 | } |
f3d | 80:ff42f77928ad | 340 | |
f3d | 80:ff42f77928ad | 341 | if (err > 0) |
f3d | 80:ff42f77928ad | 342 | { |
f3d | 80:ff42f77928ad | 343 | x--; |
f3d | 80:ff42f77928ad | 344 | dx += 2; |
f3d | 80:ff42f77928ad | 345 | err += dx - (radius << 1); |
f3d | 80:ff42f77928ad | 346 | } |
f3d | 80:ff42f77928ad | 347 | } |
f3d | 80:ff42f77928ad | 348 | } |