Modified Bob Stone's code for ILI9341 QVGA TFT's without touch capability. Navigation is now done with rotary encoders - two for position, & one setting the maxiterations.

Dependencies:   SPI_TFT_ILI9341 TFT_fonts mbed

Fork of Mandelbrot by Bob Stone

Should have mentioned in the above: Encoder code is specific to the STM32F4, tested on Nucleo F401, should work on the Nucleo F411..

/media/uploads/gregeric/img_20150121_093103_744-1-.jpg /media/uploads/gregeric/img_20150121_093055_682-1-.jpg

Committer:
gregeric
Date:
Thu Jan 22 10:01:49 2015 +0000
Revision:
3:267e7130007d
Parent:
2:b1169b84a563
Increase debounce time, shown necessary after round of testing.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
RorschachUK 0:a954bd7fd162 1 /* Mandelbrot for mbed - April 2013
RorschachUK 0:a954bd7fd162 2 * Uses Peter Drescher's library for Mikroelektronika's TFT-Proto screen, an inexpensive SPI-driven QVGA touch panel
RorschachUK 0:a954bd7fd162 3 * Library: http://mbed.org/cookbook/SPI-driven-QVGA-TFT
RorschachUK 0:a954bd7fd162 4 * Manufacturer's page for the screen: http://www.mikroe.com/add-on-boards/display/tft-proto/
RorschachUK 0:a954bd7fd162 5 * UK distributor: http://www.mcustore.com/tft-proto-board.html
RorschachUK 0:a954bd7fd162 6 * Partly adapted from Kamil Ondrousek's code for another screen: http://mbed.org/users/JLS/code/Mandelbrot-2/
RorschachUK 0:a954bd7fd162 7 */
gregeric 2:b1169b84a563 8
gregeric 2:b1169b84a563 9
gregeric 2:b1169b84a563 10 /* Adaptation for displays without touch screen from Bob Stone's https://developer.mbed.org/users/RorschachUK/code/Mandelbrot/
gregeric 2:b1169b84a563 11 * Instead, using cheap rotary encoders with integral button.
gregeric 2:b1169b84a563 12 * Two encoders navigate the complex plane Z, a third changes the maxiterations value.
gregeric 2:b1169b84a563 13 * Status (Z, zoom, maxiters) is shown on bottom of screen.
gregeric 2:b1169b84a563 14 *
gregeric 2:b1169b84a563 15 * Max-iters can be changed on the fly so that its effect on detail & colour rendering can be evaluated quickly.
gregeric 2:b1169b84a563 16 * Drawing can be interrupted with any of the buttons to allow re-centering or re-zooming without having to wait for a full redraw.
gregeric 2:b1169b84a563 17 *
gregeric 2:b1169b84a563 18 * After the rendering is completed, or interrupted, these controls are available:
gregeric 2:b1169b84a563 19 * Turning either of the position encoders will move a small cursor around the complex plane.
gregeric 2:b1169b84a563 20 * Turning the third encoder will adjust maxiters.
gregeric 2:b1169b84a563 21 * The buttons atop the Zr&Zi encoders set new zoom out/in levels & initiate drawing at that new zoom.
gregeric 2:b1169b84a563 22 * The button atop the maxiters encoder initiates a re-draw at the current zoom.
gregeric 2:b1169b84a563 23 * State rendering/idle is indicated by a '+'/' ' in the bottom right corner.
gregeric 2:b1169b84a563 24 *
gregeric 2:b1169b84a563 25 * David Lowe Jan 2015
gregeric 2:b1169b84a563 26 */
gregeric 2:b1169b84a563 27
RorschachUK 0:a954bd7fd162 28 #include "mbed.h"
gregeric 2:b1169b84a563 29 #include "SPI_TFT_ILI9341.h"
gregeric 2:b1169b84a563 30 #include "Encoder.h"
gregeric 2:b1169b84a563 31 #include "Arial10x10.h"
RorschachUK 0:a954bd7fd162 32
RorschachUK 0:a954bd7fd162 33 #define WIDTH 320
RorschachUK 0:a954bd7fd162 34 #define HEIGHT 240
gregeric 2:b1169b84a563 35 #define ORIENTATION 3
gregeric 2:b1169b84a563 36 SPI_TFT_ILI9341 tt(SPI_MOSI, SPI_MISO, SPI_SCK, D9, D6, D7,"TFT"); // mosi, miso, sclk, cs, reset, dc
RorschachUK 0:a954bd7fd162 37
gregeric 2:b1169b84a563 38 // Wire all encoder commons to 3V3,
gregeric 2:b1169b84a563 39 // encoder A&B outputs to A0 A1, D4 D5, D10 PB7
gregeric 2:b1169b84a563 40 TIM_Encoder_InitTypeDef encoder2, encoder3, encoder4;
gregeric 2:b1169b84a563 41 TIM_HandleTypeDef timer2, timer3, timer4;
gregeric 2:b1169b84a563 42
gregeric 2:b1169b84a563 43 //Wire one side of button to 3V3 (same as encoder common connections)
gregeric 2:b1169b84a563 44 InterruptIn zoominbutton(D3); //@ encoder3: real (x) axis, button -> redraw zoom out
gregeric 2:b1169b84a563 45 InterruptIn zoomoutbutton(D2); //@ encoder2: imaginary (y) axis, button -> redraw zoom in
gregeric 2:b1169b84a563 46 InterruptIn zoomsamebutton(USER_BUTTON); //@ encoder4: iterations, button -> redraw zoom unchanged
gregeric 2:b1169b84a563 47
gregeric 2:b1169b84a563 48 //Setup base Mandelbrot
gregeric 2:b1169b84a563 49 double centrex = -0.5;
gregeric 2:b1169b84a563 50 double centrey = -0.0;
gregeric 2:b1169b84a563 51 double zoom=0.5;
gregeric 2:b1169b84a563 52 int32_t log2zoom=-1;
RorschachUK 0:a954bd7fd162 53
gregeric 2:b1169b84a563 54 #define MAXITERS 8192
gregeric 2:b1169b84a563 55 #define MINITERS 64
gregeric 2:b1169b84a563 56 #define maxiters (MINITERS+TIM4->CNT)
gregeric 2:b1169b84a563 57 uint16_t lastiters=MINITERS;
gregeric 2:b1169b84a563 58
gregeric 3:267e7130007d 59 enum nextaction_t {
gregeric 2:b1169b84a563 60 idle=0,
gregeric 2:b1169b84a563 61 zoomin,
gregeric 2:b1169b84a563 62 zoomout,
gregeric 2:b1169b84a563 63 zoomsame,
gregeric 2:b1169b84a563 64 interrupted
gregeric 2:b1169b84a563 65 };
gregeric 2:b1169b84a563 66
gregeric 3:267e7130007d 67 nextaction_t buttonpressed;
gregeric 2:b1169b84a563 68
gregeric 2:b1169b84a563 69 void GotZoomIn(void)
gregeric 2:b1169b84a563 70 {
gregeric 2:b1169b84a563 71 buttonpressed=zoomin;
gregeric 2:b1169b84a563 72 }
RorschachUK 0:a954bd7fd162 73
gregeric 2:b1169b84a563 74 void GotZoomOut(void)
gregeric 2:b1169b84a563 75 {
gregeric 2:b1169b84a563 76 buttonpressed=zoomout;
gregeric 2:b1169b84a563 77 }
RorschachUK 0:a954bd7fd162 78
gregeric 2:b1169b84a563 79 void GotZoomSame(void)
gregeric 2:b1169b84a563 80 {
gregeric 2:b1169b84a563 81 buttonpressed=zoomsame;
gregeric 2:b1169b84a563 82 }
gregeric 2:b1169b84a563 83
gregeric 2:b1169b84a563 84 void UpdateStats(void)
gregeric 2:b1169b84a563 85 {
gregeric 2:b1169b84a563 86 //invert orientation & set cursor to top left (our bottom right at usual orientation)
gregeric 2:b1169b84a563 87 tt.set_orientation(ORIENTATION^2);
gregeric 2:b1169b84a563 88 tt.locate(0,0);
gregeric 2:b1169b84a563 89 //indicate "rendering active" & erase a few chars at line end
gregeric 2:b1169b84a563 90 tt.printf("+ ");
RorschachUK 0:a954bd7fd162 91
gregeric 2:b1169b84a563 92 //write current infos to bottom of screen: real, imag, log2(zoom), maxiters
gregeric 2:b1169b84a563 93 tt.set_orientation(ORIENTATION);
gregeric 2:b1169b84a563 94 tt.locate(0,240-10);
gregeric 2:b1169b84a563 95 tt.printf("%1.16f%+1.16fi %d %d", centrex, -centrey, log2zoom, maxiters);
gregeric 2:b1169b84a563 96 }
gregeric 2:b1169b84a563 97
gregeric 2:b1169b84a563 98 void DrawMandelbrot(void)
gregeric 2:b1169b84a563 99 {
gregeric 2:b1169b84a563 100 double xmin = centrex - 1.0/zoom;
gregeric 2:b1169b84a563 101 double xmax = centrex + 1.0/zoom;
gregeric 2:b1169b84a563 102 double ymin = centrey - HEIGHT / (WIDTH * zoom);
gregeric 2:b1169b84a563 103 double ymax = centrey + HEIGHT / (WIDTH *zoom);
gregeric 2:b1169b84a563 104
gregeric 2:b1169b84a563 105 double dx = (xmax - xmin) / WIDTH;
gregeric 2:b1169b84a563 106 double dy = (ymax - ymin) / HEIGHT;
gregeric 2:b1169b84a563 107
gregeric 2:b1169b84a563 108 double y = ymin;
gregeric 2:b1169b84a563 109
gregeric 2:b1169b84a563 110 double c;
RorschachUK 0:a954bd7fd162 111 unsigned int cr, cg, cb;
gregeric 2:b1169b84a563 112
RorschachUK 0:a954bd7fd162 113 for (int j = 0; j < HEIGHT; j++) {
gregeric 2:b1169b84a563 114 double x = xmin;
RorschachUK 0:a954bd7fd162 115
RorschachUK 0:a954bd7fd162 116 for (int i = 0; i < WIDTH; i++) {
gregeric 2:b1169b84a563 117 double a = x;
gregeric 2:b1169b84a563 118 double b = y;
RorschachUK 0:a954bd7fd162 119 int n = 0;
RorschachUK 0:a954bd7fd162 120
gregeric 2:b1169b84a563 121 if (maxiters!=lastiters) { //update stats if user changes maxiters on-the-fly
gregeric 2:b1169b84a563 122 UpdateStats();
gregeric 2:b1169b84a563 123 lastiters=maxiters;
gregeric 2:b1169b84a563 124 }
gregeric 2:b1169b84a563 125
gregeric 2:b1169b84a563 126 while (n < maxiters) {
gregeric 2:b1169b84a563 127 double aa = a * a;
gregeric 2:b1169b84a563 128 double bb = b * b;
gregeric 2:b1169b84a563 129 double twoab = 2.0 * a * b;
RorschachUK 0:a954bd7fd162 130
RorschachUK 0:a954bd7fd162 131 a = aa - bb + x;
RorschachUK 0:a954bd7fd162 132 b = twoab + y;
RorschachUK 0:a954bd7fd162 133
RorschachUK 0:a954bd7fd162 134 if(aa + bb > 16.0) {
RorschachUK 0:a954bd7fd162 135 break;
RorschachUK 0:a954bd7fd162 136 }
RorschachUK 0:a954bd7fd162 137 n++;
RorschachUK 0:a954bd7fd162 138 }
RorschachUK 0:a954bd7fd162 139
gregeric 2:b1169b84a563 140 if (n == maxiters) {
RorschachUK 0:a954bd7fd162 141 //It's in the set - Black
RorschachUK 0:a954bd7fd162 142 tt.pixel(i,j,Black);
RorschachUK 0:a954bd7fd162 143 } else {
RorschachUK 0:a954bd7fd162 144 //Not in the set - pick a colour
gregeric 2:b1169b84a563 145 c = 3.0 * (maxiters-n)/maxiters;
RorschachUK 0:a954bd7fd162 146 cr = ((c < 1.0) ? 255 * ( 1.0 - c) : (c > 2.0) ? 255 * (c - 2.0) : 0);
RorschachUK 0:a954bd7fd162 147 cg = ((c < 1.0) ? 255 * c : (c > 2.0) ? 0 : 255 * (2.0 - c));
RorschachUK 0:a954bd7fd162 148 cb = ((c < 1.0) ? 0 : (c > 2.0) ? 255 * (3.0 - c) : 255 * (c - 1.0));
RorschachUK 0:a954bd7fd162 149 tt.pixel(i,j, RGB(cr,cg,cb));
RorschachUK 0:a954bd7fd162 150 }
RorschachUK 0:a954bd7fd162 151 x += dx;
gregeric 2:b1169b84a563 152 if (buttonpressed) return;
RorschachUK 0:a954bd7fd162 153 }
RorschachUK 0:a954bd7fd162 154 y += dy;
RorschachUK 0:a954bd7fd162 155 }
RorschachUK 0:a954bd7fd162 156 }
RorschachUK 0:a954bd7fd162 157
gregeric 2:b1169b84a563 158 void PixelBrot(int i, int j)
gregeric 2:b1169b84a563 159 {
gregeric 2:b1169b84a563 160 double xmin = centrex - 1.0/zoom;
gregeric 2:b1169b84a563 161 double xmax = centrex + 1.0/zoom;
gregeric 2:b1169b84a563 162 double ymin = centrey - HEIGHT / (WIDTH * zoom);
gregeric 2:b1169b84a563 163 double ymax = centrey + HEIGHT / (WIDTH *zoom);
gregeric 2:b1169b84a563 164
gregeric 2:b1169b84a563 165 double dx = (xmax - xmin) / WIDTH;
gregeric 2:b1169b84a563 166 double dy = (ymax - ymin) / HEIGHT;
gregeric 2:b1169b84a563 167
gregeric 2:b1169b84a563 168 double x=xmin+dx*i;
gregeric 2:b1169b84a563 169 double y=ymin+dy*j;
gregeric 2:b1169b84a563 170
gregeric 2:b1169b84a563 171 double a = x;
gregeric 2:b1169b84a563 172 double b = y;
gregeric 2:b1169b84a563 173 int n = 0;
gregeric 2:b1169b84a563 174 double c;
gregeric 2:b1169b84a563 175 unsigned int cr, cg, cb;
gregeric 2:b1169b84a563 176
gregeric 2:b1169b84a563 177 while (n < maxiters) {
gregeric 2:b1169b84a563 178 double aa = a * a;
gregeric 2:b1169b84a563 179 double bb = b * b;
gregeric 2:b1169b84a563 180 double twoab = 2.0 * a * b;
gregeric 2:b1169b84a563 181
gregeric 2:b1169b84a563 182 a = aa - bb + x;
gregeric 2:b1169b84a563 183 b = twoab + y;
gregeric 2:b1169b84a563 184
gregeric 2:b1169b84a563 185 if(aa + bb > 16.0) {
gregeric 2:b1169b84a563 186 break;
gregeric 2:b1169b84a563 187 }
gregeric 2:b1169b84a563 188 n++;
gregeric 2:b1169b84a563 189 }
gregeric 2:b1169b84a563 190
gregeric 2:b1169b84a563 191 if (n == maxiters) {
gregeric 2:b1169b84a563 192 //It's in the set - Black
gregeric 2:b1169b84a563 193 tt.pixel(i,j,Black);
gregeric 2:b1169b84a563 194 } else {
gregeric 2:b1169b84a563 195 //Not in the set - pick a colour
gregeric 2:b1169b84a563 196 c = 3.0 * (maxiters-n)/maxiters;
gregeric 2:b1169b84a563 197 cr = ((c < 1.0) ? 255 * ( 1.0 - c) : (c > 2.0) ? 255 * (c - 2.0) : 0);
gregeric 2:b1169b84a563 198 cg = ((c < 1.0) ? 255 * c : (c > 2.0) ? 0 : 255 * (2.0 - c));
gregeric 2:b1169b84a563 199 cb = ((c < 1.0) ? 0 : (c > 2.0) ? 255 * (3.0 - c) : 255 * (c - 1.0));
gregeric 2:b1169b84a563 200 tt.pixel(i,j, RGB(cr,cg,cb));
gregeric 2:b1169b84a563 201 }
gregeric 2:b1169b84a563 202
gregeric 2:b1169b84a563 203 }
gregeric 2:b1169b84a563 204
gregeric 2:b1169b84a563 205 void EraseCursor(int x, int y)
gregeric 2:b1169b84a563 206 {
gregeric 2:b1169b84a563 207 int x1,x2,y1,y2;
gregeric 2:b1169b84a563 208
gregeric 2:b1169b84a563 209 x1=x-3;
gregeric 2:b1169b84a563 210 if (x1<0) x1=0;
gregeric 2:b1169b84a563 211 if (x1>WIDTH-1) x1=WIDTH-1;
gregeric 2:b1169b84a563 212 x2=x+3;
gregeric 2:b1169b84a563 213 if (x2<0) x2=0;
gregeric 2:b1169b84a563 214 if (x2>WIDTH-1) x2=WIDTH-1;
gregeric 2:b1169b84a563 215
gregeric 2:b1169b84a563 216 y1=y-3;
gregeric 2:b1169b84a563 217 if (y1<0) y1=0;
gregeric 2:b1169b84a563 218 if (y1>HEIGHT-1) y1=HEIGHT-1;
gregeric 2:b1169b84a563 219 y2=y+3;
gregeric 2:b1169b84a563 220 if (y2<0) y2=0;
gregeric 2:b1169b84a563 221 if (y2>HEIGHT-1) y2=HEIGHT-1;
gregeric 2:b1169b84a563 222
gregeric 2:b1169b84a563 223 if (x<0) x=0;
gregeric 2:b1169b84a563 224 if (x>WIDTH-1) x=WIDTH-1;
gregeric 2:b1169b84a563 225
gregeric 2:b1169b84a563 226 if (y<0) y=0;
gregeric 2:b1169b84a563 227 if (y>HEIGHT-1) y=HEIGHT-1;
gregeric 2:b1169b84a563 228
gregeric 2:b1169b84a563 229 //Overwite crosshair
gregeric 2:b1169b84a563 230 int i;
gregeric 2:b1169b84a563 231 for(i=x1; i<=x2; i++) PixelBrot(i,y);
gregeric 2:b1169b84a563 232 for(i=y1; i<=y2; i++) PixelBrot(x,i);
gregeric 2:b1169b84a563 233 }
gregeric 2:b1169b84a563 234
gregeric 2:b1169b84a563 235 void DrawCursor(int x, int y)
gregeric 2:b1169b84a563 236 {
gregeric 2:b1169b84a563 237 int x1,x2,y1,y2;
gregeric 2:b1169b84a563 238
gregeric 2:b1169b84a563 239 x1=x-3;
gregeric 2:b1169b84a563 240 if (x1<0) x1=0;
gregeric 2:b1169b84a563 241 if (x1>WIDTH-1) x1=WIDTH-1;
gregeric 2:b1169b84a563 242 x2=x+3;
gregeric 2:b1169b84a563 243 if (x2<0) x2=0;
gregeric 2:b1169b84a563 244 if (x2>WIDTH-1) x2=WIDTH-1;
gregeric 2:b1169b84a563 245
gregeric 2:b1169b84a563 246 y1=y-3;
gregeric 2:b1169b84a563 247 if (y1<0) y1=0;
gregeric 2:b1169b84a563 248 if (y1>HEIGHT-1) y1=HEIGHT-1;
gregeric 2:b1169b84a563 249 y2=y+3;
gregeric 2:b1169b84a563 250 if (y2<0) y2=0;
gregeric 2:b1169b84a563 251 if (y2>HEIGHT-1) y2=HEIGHT-1;
gregeric 2:b1169b84a563 252
gregeric 2:b1169b84a563 253 if (x<0) x=0;
gregeric 2:b1169b84a563 254 if (x>WIDTH-1) x=WIDTH-1;
gregeric 2:b1169b84a563 255
gregeric 2:b1169b84a563 256 if (y<0) y=0;
gregeric 2:b1169b84a563 257 if (y>HEIGHT-1) y=HEIGHT-1;
gregeric 2:b1169b84a563 258
gregeric 2:b1169b84a563 259 //Draw crosshair
gregeric 2:b1169b84a563 260 tt.line(x,y1,x,y2,White);
gregeric 2:b1169b84a563 261 tt.line(x1,y,x2,y,White);
gregeric 2:b1169b84a563 262 }
gregeric 2:b1169b84a563 263
gregeric 2:b1169b84a563 264 void InitEncoders(void)
gregeric 2:b1169b84a563 265 {
gregeric 2:b1169b84a563 266 //TIM1 is used by mbed for SPI clocking
gregeric 2:b1169b84a563 267
gregeric 2:b1169b84a563 268 //A0 A1, common to 3V3
gregeric 2:b1169b84a563 269 //counting on both B-input only, 2 ticks per cycle, full 32-bit count
gregeric 2:b1169b84a563 270 EncoderInit(encoder2, timer2, TIM2, 0xffffffff, TIM_ENCODERMODE_TI2);
gregeric 2:b1169b84a563 271
gregeric 2:b1169b84a563 272 //D4 D5, common to 3V3
gregeric 2:b1169b84a563 273 //counting on B-input only, 2 ticks per cycle, full 16-bit count
gregeric 2:b1169b84a563 274 EncoderInit(encoder3, timer3, TIM3, 0xffff, TIM_ENCODERMODE_TI2);
gregeric 2:b1169b84a563 275
gregeric 2:b1169b84a563 276 //D10 PB7, common to 3V3
gregeric 2:b1169b84a563 277 //counting on both A&B edges, 4 ticks per cycle, max count used to limit maxiters to range (MINITERS..MAXITERS)
gregeric 2:b1169b84a563 278 EncoderInit(encoder4, timer4, TIM4, MAXITERS-MINITERS+3, TIM_ENCODERMODE_TI12);
gregeric 2:b1169b84a563 279
gregeric 2:b1169b84a563 280 //TIM5 is used by mbed for us_ticker
gregeric 2:b1169b84a563 281 }
gregeric 2:b1169b84a563 282
RorschachUK 0:a954bd7fd162 283 int main()
RorschachUK 0:a954bd7fd162 284 {
RorschachUK 0:a954bd7fd162 285 //Setup screen
RorschachUK 0:a954bd7fd162 286 tt.background(Black); // set background to black
RorschachUK 0:a954bd7fd162 287 tt.foreground(White); // set chars to white
RorschachUK 0:a954bd7fd162 288 tt.cls(); // clear the screen
gregeric 2:b1169b84a563 289 tt.set_font((unsigned char*)Arial10x10);
gregeric 2:b1169b84a563 290
gregeric 2:b1169b84a563 291 InitEncoders();
RorschachUK 0:a954bd7fd162 292
gregeric 2:b1169b84a563 293 zoominbutton.rise(&GotZoomIn);
gregeric 2:b1169b84a563 294 zoominbutton.mode(PullDown);
gregeric 2:b1169b84a563 295 zoomoutbutton.rise(&GotZoomOut);
gregeric 2:b1169b84a563 296 zoomoutbutton.mode(PullDown);
gregeric 2:b1169b84a563 297 zoomsamebutton.rise(&GotZoomSame);
gregeric 2:b1169b84a563 298 zoomsamebutton.mode(PullDown);
RorschachUK 0:a954bd7fd162 299
RorschachUK 0:a954bd7fd162 300 while(true) {
gregeric 2:b1169b84a563 301
gregeric 2:b1169b84a563 302 //log status @ PC serial port
gregeric 2:b1169b84a563 303 printf("%1.18f%+1.18fi, %+d, %d\n\r", centrex, -centrey, log2zoom, maxiters);
gregeric 2:b1169b84a563 304
gregeric 3:267e7130007d 305 wait(0.3); //debounce
gregeric 2:b1169b84a563 306 buttonpressed=idle;
gregeric 2:b1169b84a563 307
gregeric 2:b1169b84a563 308 UpdateStats();
gregeric 2:b1169b84a563 309
gregeric 2:b1169b84a563 310 //Draw the thing, can be interrupted by a button press
gregeric 2:b1169b84a563 311 tt.set_orientation(ORIENTATION);
gregeric 2:b1169b84a563 312 DrawMandelbrot();
gregeric 2:b1169b84a563 313
gregeric 3:267e7130007d 314 wait(0.3); //debounce
gregeric 2:b1169b84a563 315 //flag that we should update status bar, but not commence new render
gregeric 2:b1169b84a563 316 if (buttonpressed) buttonpressed=interrupted;
gregeric 2:b1169b84a563 317
gregeric 2:b1169b84a563 318 //throw away any user-twiddling of real & imaginary encoders made while rendering
gregeric 2:b1169b84a563 319 TIM2->CNT=0;
gregeric 2:b1169b84a563 320 TIM3->CNT=0;
gregeric 2:b1169b84a563 321
gregeric 2:b1169b84a563 322 int16_t shiftx, shifty;
gregeric 2:b1169b84a563 323 int16_t lastshiftx=0, lastshifty=0;
gregeric 2:b1169b84a563 324
gregeric 2:b1169b84a563 325 while(true) { // loop until a redraw button is pressed, then go draw something
gregeric 2:b1169b84a563 326
gregeric 2:b1169b84a563 327 while(true) { //loop forever until real or imag or iters dials have moved, or any of the redraw buttons pressed
gregeric 2:b1169b84a563 328 shiftx=(int16_t)TIM2->CNT/2;
gregeric 2:b1169b84a563 329 shifty=(int16_t)TIM3->CNT/2;
gregeric 2:b1169b84a563 330 if (buttonpressed) break;
gregeric 2:b1169b84a563 331 if (shiftx!=lastshiftx || shifty!=lastshifty || maxiters!=lastiters) break;
gregeric 2:b1169b84a563 332 }
gregeric 2:b1169b84a563 333
gregeric 3:267e7130007d 334 if(maxiters==lastiters) { //we're here cos cursor moved (speeds up redraw when twiddling maxiter knob
gregeric 3:267e7130007d 335 EraseCursor(WIDTH/2+lastshiftx, HEIGHT/2+lastshifty);
gregeric 3:267e7130007d 336 DrawCursor(WIDTH/2+shiftx, HEIGHT/2+shifty);
gregeric 3:267e7130007d 337 }
gregeric 2:b1169b84a563 338
gregeric 2:b1169b84a563 339 lastshiftx=shiftx;
gregeric 2:b1169b84a563 340 lastshifty=shifty;
gregeric 2:b1169b84a563 341 lastiters=maxiters;
gregeric 2:b1169b84a563 342
gregeric 2:b1169b84a563 343 if(buttonpressed==interrupted) buttonpressed=idle; //draw was halted, update status & wait for new controls
gregeric 2:b1169b84a563 344 if(buttonpressed) break; //go redraw whole screen with updated centre/zoom/maxiters
gregeric 2:b1169b84a563 345
gregeric 2:b1169b84a563 346 //erase a few chars at line end
gregeric 2:b1169b84a563 347 tt.set_orientation(ORIENTATION^2);
gregeric 2:b1169b84a563 348 tt.locate(0,0);
gregeric 2:b1169b84a563 349 tt.printf(" ");
gregeric 2:b1169b84a563 350
gregeric 2:b1169b84a563 351 //write ammended infos to bottom of screen: real, imag, log2(zoom), maxiters
gregeric 2:b1169b84a563 352 tt.set_orientation(ORIENTATION);
gregeric 2:b1169b84a563 353 tt.locate(0,240-10);
gregeric 2:b1169b84a563 354 tt.printf("%1.16f%+1.16fi %d %d",centrex+((double)(shiftx*2))/(WIDTH*zoom),
gregeric 2:b1169b84a563 355 -(centrey+((double)(shifty*2))/(WIDTH*zoom)),
gregeric 2:b1169b84a563 356 buttonpressed==1 ? log2zoom+2 : (buttonpressed==2 ? log2zoom-2 : log2zoom),
gregeric 2:b1169b84a563 357 maxiters);
RorschachUK 0:a954bd7fd162 358 }
gregeric 2:b1169b84a563 359
gregeric 2:b1169b84a563 360 centrex += ((double)(shiftx*2))/(WIDTH*zoom);
gregeric 2:b1169b84a563 361 centrey += ((double)(shifty*2))/(WIDTH*zoom);
gregeric 2:b1169b84a563 362
gregeric 2:b1169b84a563 363 if(buttonpressed==zoomin) {
gregeric 2:b1169b84a563 364 zoom*=4.0;
gregeric 2:b1169b84a563 365 log2zoom+=2;
gregeric 2:b1169b84a563 366 }
gregeric 2:b1169b84a563 367 if(buttonpressed==zoomout) {
gregeric 2:b1169b84a563 368 zoom/=4.0;
gregeric 2:b1169b84a563 369 log2zoom-=2;
gregeric 2:b1169b84a563 370 }
gregeric 2:b1169b84a563 371 //buttonpressed==zoomsame, redraw with zoom unchanged
RorschachUK 0:a954bd7fd162 372 }
RorschachUK 0:a954bd7fd162 373 }