Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
composite.cpp
00001 //////////////////////////////////////////////////////////// 00002 // Software generation of a grayscale composite TV signal // 00003 // Puts a 105x128 grayscale fractal zoom onscreen (slow!) // 00004 // // 00005 // Hacked together, (ab)uses the LPC1768 DAC output (p18) // 00006 // with some shifty looking timing sensitive code // 00007 // // 00008 // // 00009 // Rob Younger 26th Oct 2009, (tweaked 15th Nov 2009) // 00010 //////////////////////////////////////////////////////////// 00011 00012 //////////////////////////////////////////////////////////// 00013 // fire demo routine based on http://demo-effects.sourceforge.net/ 00014 // Copyright (C) 2003 W.P. van Paassen - peter@paassen.tmfweb.nl 00015 // which I guess means this version is GPL. 00016 // 00017 // note it uses a secondary buffer for the fire, which is 00018 // copied into the main buffer, innefficient but quick! 00019 // limits on available resolution due to inneficient mem use 00020 //////////////////////////////////////////////////////////// 00021 00022 // Generating video like it's 1982! 00023 00024 // Warning : this is *very* hacky code - just proof of concept! 00025 // This might blow up your mbed or your TV. 00026 // I claim no responsibility for anything :-) 00027 00028 // Start with a 180 Ohm resistor in series with the DAC output 00029 // before connecting to a composite AV input, 00030 // DAC is about 0-3.3v output, Composite in 1v p-p, with a 75 Ohm termination, so 180 Ohms is about right. 00031 00032 // but it also worked without any resistor for me! Start with a higher value if you aren't sure. 00033 // More likely to burn out your mbed or TV with low/no resistor - Use at your own risk! 00034 00035 00036 // HOW THIS WORKS: 00037 00038 // The DAC output is written as fast as possible to software generate a composite signal 00039 // dac.write_u16() seems to take about 0.5 us: I worked this timing out using a big loop of 00040 // dac.write_u16(0); 00041 // .... 00042 // dac.write_u16(0); 00043 // dac.write_u16(0xFFFF); 00044 // .... 00045 // dac.write_u16(0xFFFF); 00046 // Until I got a frequency I could measure on a multimeter. 00047 // 00048 // At full speed gives us about 1MHz max frequency - 00049 // I don't have an oscilloscope to see how well this actually works, probably totally out of spec! 00050 // 00051 // The software just runs loads of these to generate the composite signal as fast as possible! 00052 // 00053 // Since a TV output is generated continuously this would use 100% CPU time. 00054 // 00055 // Clever to-the-metal code would do things like use the horizontal and vertical blanking 00056 // intervals to do any required calculation. This isn't clever to-the-metal code! 00057 // Instead, I just don't draw the bottom few percent of the TV picture, and use this free time to run code. 00058 // This may well cause your TV to loose sync, but it works for me - I did say it was a hack! 00059 // 00060 // Driving the display takes 90%, main code gets 10% to play with at the end of each frame. 00061 // Tweak these percentages up and down, but loose too many lines and the tv is much more likely to 00062 // drop the signal, equally as you hit 100% CPU the frame calls might start to overlap and it all goes a bit wrong! 00063 // 00064 // This code actually starts with the end of previous frame signalling first, then all the setup, then the actual picture. 00065 // 00066 // It's coded up as a routine that draws a whole frame (field), which is called from main on a timer interrupt (at 50Hz for PAL) 00067 // This makes it easy to have a main routing that can operate normally, without you having to worry (too much) about the timing involved. 00068 // The picture elements of the signal are created by dumping a global frame buffer over to the DAC: 00069 // unsigned short int framebuffer[HEIGHT][WIDTH]; 00070 // The values in this framebuffer are the actual composite signal, NOT just shades of gray! 00071 // In other words, only write values between 0x56DB (black) and 0xFFFF (bright white). 00072 // For this reason, it's important to initialize the buffer to all 0x56DB or above 00073 00074 // Yes - there's probably a much better way to do this - but you don't want to slow down the DAC writes at all. 00075 // Adding checks or shifting the value from a normal range might be to slow - over to the real programmers to work out how to do this... 00076 00077 // The frame buffer is 105 pixels wide - this is just because 105 dac writes take up the time required for a horizontal tv line. 00078 // height is more arbitrary, as we draw every scan line - but I double or quadruple scan to get squarish pixels! 00079 // Use a modulo value in the picture write line to repeat the picture for small framebuffers. 00080 00081 // This program has a couple of demo routines. One draws a fractal, and the other just writes random values to the framebuffer 00082 00083 // A future enhancement could be to have two small framebuffers 105x64 and do double buffering? Needs to all be in fast memory though. 00084 // The code could definitely do with some tuning as the sync delays are all a bit off... 00085 00086 ////////////////////////////////////////////////////////////////////////////////////////////////////////// 00087 00088 00089 #include "mbed.h" 00090 00091 //Framebuffer size 00092 #define WIDTH 105 00093 #define HEIGHT 86 00094 00095 //TV signal generation controlling: 00096 #define LINES 256 //Visible lines drawn to screen 00097 #define SCAN 3 //Number of scanlines per pixel (vertical) 00098 #define DRAWWIDTH 105 //Pixels per line 00099 00100 // LINES: theoretically up to 286 for PAL, 241 for NTSC). 285 seems to be about 100% CPU on PAL. Smaller values means I stop drawing the signal early. 00101 // SCAN: controls double scan (e.g. 128 pixels to 256 lines) 00102 // DRAWWIDTH: number of pixels to attempt to draw in a line (should be =< framebuffer WIDTH). Very timing critical - expect different values to break 00103 00104 // Composite signal values for DAC output. These should really be scaled for 1v peak-to-peak 00105 #define IRE_m40 0x0000 //0volts 00106 #define IRE_0 0x4920 //Baseline 00107 #define IRE_7p5 0x56DB //Black 00108 #define IRE_100 0xFFFF //White 00109 // DAC is 10bit, but i'm using write_u16 to write to the DAC. 00110 // IRE is a definition: 00111 // the levels are -40 (0volts), 0 (baseline below black), 7.5 (Black), 100 (White). 00112 // IRE -40 is 0v, 100 is 1v, so scale accordingly! 00113 00114 AnalogOut dac(p18); // Video out pin 00115 Ticker timer; // Timer for calling the frame 00116 00117 DigitalOut led1(LED1);//Some status lights... 00118 DigitalOut led2(LED2); 00119 DigitalOut led3(LED3); 00120 DigitalOut led4(LED4); 00121 00122 // Framebuffer actually has video signal levels in it - not just grayscale data 00123 // This means it must be initialised to at least all black IRE_7p5 before it's used. 00124 // zero values will likely kill the output and TV will loose sync. 00125 unsigned short int framebuffer[HEIGHT][WIDTH]; 00126 00127 00128 00129 ///////////////////////////////////////////////////////////// 00130 //Software composite signal generation (very timing specific) 00131 ///////////////////////////////////////////////////////////// 00132 00133 void createframe() { 00134 00135 // Procedure to create a output frame to a tv - needs to run on a very regular sync (e.g. 50Hz or 60Hz) 00136 // Using the DAC to create this output, which seems to happily run at 2MHz update 00137 // dac.write_u16 seems to take almost spot on 0.5us, so I'm using multiples of this to create a signal. 00138 00139 // Could maybe be done with timing precision through multiple digital outputs and a resistor ladder to create an external DAC, but this didn't need any external components! 00140 00141 // Someone with an oscilloscope can tweak this to get the delays more up to standard! 00142 00143 // TV signal specs 00144 00145 // For 50Hz PAL, each line takes up 64us, and there are 625 lines, but split into two fields of about 312 lines. 00146 // I'm treating both fields exactly the same, so we have a 312(ish) lines at 50Hz. 00147 // NTSC is actually very similar but with slightly different timings/counts. (525 lines at 60Hz). 00148 00149 // Some info found through google: 00150 00151 //525line (NTSC) - required timing in us for a line 00152 //NAME LENGTH LEVEL 00153 //Front porch 1.5 IRE_0 00154 //Sync Tip 4.7 IRE_m40 00155 //Breezeway 0.6 IRE_0 00156 //Color Burst 2.5 IRE_0 00157 //Back Porch 1.6 IRE_0 00158 //Active Video 52.6 IRE_7p5 - IRE100 00159 00160 //Total line time = 63.5us ( * half of 525 lines * 60Hz) 00161 00162 //625line (PAL) - required timing in us for a line 00163 //NAME LENGTH LEVEL 00164 //Front porch 1.65 IRE_0 00165 //Sync Tip 4.7 IRE_m40 00166 //Breezeway 0.9 IRE_0 00167 //Color Burst 2.25 IRE_0 00168 //Back Porch 2.55 IRE_0 00169 //Active Video 51.95 IRE_7p5 - IRE100 00170 00171 //Total line time = 64us ( * half of 625 lines * 50Hz) 00172 00173 // There actually seem to be a lot of variations on this, but they all seem roughly the same. 00174 00175 // Colour needs a precision ~4MHz carrier signal applied over the 'color burst' and active video 00176 // with precise phase and amplitude control (sounds like a lot of work!) 00177 00178 // So for colour, Use svideo, VGA, or use 3 of these signals to generate an RGB scart signal? 00179 00180 //The basic frame format is 00181 //1) few lines of special start pulses, 00182 //2) some off screen lines, which had things like teletext/close captions 00183 //3) the tv picture bit you see, 00184 //4) some special pulses to say end of screen, go back to the top. 00185 // Then straight back to 1 for the next frame. 00186 00187 // To get the timing right - I do this: 00188 //4) some special pulses to say end of screen, go back to the top. 00189 //1) few lines of special start pulses, 00190 //2) some off screen lines, which had things like teletext/close captions 00191 //3) the tv picture bit you see, 00192 00193 // You can get away dropping the last few lines of 3) 00194 // I use this to drop back to the main program to run as normal. 00195 00196 // Ideally you'd use the few cycles between each line to do stuff, but that's going to be hard to get timing right. 00197 00198 00199 //////////////////////////////////////////////////////////// 00200 //Start of Frame 00201 //////////////////////////////////////////////////////////// 00202 00203 //Each dac.write is ~0.5us, so multiply up to create the timings. 00204 00205 // (This is a mix of PAL and NTSC - hack as appropriate) 00206 00207 // There are 21 lines per field in a vertical blanking period 00208 // the last 4 lines of a field indicate are just before flyback 00209 // then there are 5 blank lines for flyback itself... 00210 00211 //END OF A FRAME + FLYBACK + START OF NEW FRAME signalling (9 lines) 00212 for (int i = 0; i < 6; i++) { //6 equalizing pulses (time = 6 half lines) 00213 dac.write_u16(IRE_m40); //2.4us 00214 dac.write_u16(IRE_m40); 00215 dac.write_u16(IRE_m40); 00216 dac.write_u16(IRE_m40); 00217 // dac.write_u16(IRE_m40); 00218 dac.write_u16(IRE_0); //29.4us 00219 wait_us(28); 00220 } 00221 for (int i = 0; i < 6; i++) {// 6 serrated vertical pulses (time = 6 half lines) 00222 dac.write_u16(IRE_0); //2.4us 00223 dac.write_u16(IRE_0); 00224 dac.write_u16(IRE_0); 00225 dac.write_u16(IRE_0); 00226 // dac.write_u16(IRE_0); 00227 dac.write_u16(IRE_m40); //29.4us 00228 wait_us(28); 00229 } 00230 for (int i = 0; i < 6; i++) { // 6 equalizing pulses (time = 6 half lines) 00231 dac.write_u16(IRE_m40); //2.4us 00232 dac.write_u16(IRE_m40); 00233 dac.write_u16(IRE_m40); 00234 dac.write_u16(IRE_m40); 00235 // dac.write_u16(IRE_m40); 00236 dac.write_u16(IRE_0); //29.4us 00237 wait_us(28); 00238 } 00239 00240 00241 // The lines just above the top of the picture used for setup/teletext/closed captions etc. 00242 // about 17 lines for PAL, 12 for NTSC? 00243 for (int i = 0; i < 17; i++) { 00244 //10.9us (NTSC) or 12.5us (PAL) for horizontal blanking interval 00245 dac.write_u16(IRE_0); //Front porch 1.6us 00246 dac.write_u16(IRE_0); 00247 dac.write_u16(IRE_0); 00248 dac.write_u16(IRE_m40); //Sync Tip 4.7us 00249 dac.write_u16(IRE_m40); 00250 dac.write_u16(IRE_m40); 00251 dac.write_u16(IRE_m40); 00252 dac.write_u16(IRE_m40); 00253 dac.write_u16(IRE_m40); 00254 dac.write_u16(IRE_m40); 00255 dac.write_u16(IRE_m40); 00256 dac.write_u16(IRE_m40); 00257 // dac.write_u16(IRE_m40); //extra for PAL timing 00258 dac.write_u16(IRE_0); //Breezeway 0.5us 00259 dac.write_u16(IRE_0); //ColorBurst 2.5us 00260 dac.write_u16(IRE_0); 00261 dac.write_u16(IRE_0); 00262 dac.write_u16(IRE_0); 00263 dac.write_u16(IRE_0); 00264 dac.write_u16(IRE_m40); //Back Porch 1.6us (2.55us in PAL) 00265 dac.write_u16(IRE_m40); 00266 dac.write_u16(IRE_m40); 00267 dac.write_u16(IRE_m40); //extra for PAL timing 00268 dac.write_u16(IRE_m40); //extra for PAL timing 00269 00270 // for (int j = 0; j < DRAWWIDTH; j++) { 00271 // dac.write_u16(IRE_0); 00272 // } //next pixel 00273 00274 00275 //Then that video signal for 52.6us (52 for PAL) 00276 dac.write_u16(IRE_0); //Video signal for 52.6us 00277 wait_us(51); // replaces another 104 dac.write_u16(IRE_0) 00278 } 00279 00280 00281 //Draw the actual visible lines on screen: exactly same header as previous, but followed by real video data. 00282 // intentionally dropping the last few lines to throw some time to main() 00283 // otherwise this loop would use 100% of CPU. 00284 for (int i = 0; i < LINES; i++) { 00285 //10.9us (NTSC) or 12.5us (PAL) for horizontal blanking interval 00286 dac.write_u16(IRE_0); //Front porch 1.6us 00287 dac.write_u16(IRE_0); 00288 dac.write_u16(IRE_0); 00289 dac.write_u16(IRE_m40); //Sync Tip 4.7us 00290 dac.write_u16(IRE_m40); 00291 dac.write_u16(IRE_m40); 00292 dac.write_u16(IRE_m40); 00293 dac.write_u16(IRE_m40); 00294 dac.write_u16(IRE_m40); 00295 dac.write_u16(IRE_m40); 00296 dac.write_u16(IRE_m40); 00297 dac.write_u16(IRE_m40); 00298 // dac.write_u16(IRE_m40); //extra for PAL timing 00299 dac.write_u16(IRE_0); //Breezeway 0.5us 00300 dac.write_u16(IRE_0); //ColorBurst 2.5us 00301 dac.write_u16(IRE_0); 00302 dac.write_u16(IRE_0); 00303 dac.write_u16(IRE_0); 00304 dac.write_u16(IRE_0); 00305 dac.write_u16(IRE_m40); //Back Porch 1.6us (2.55us in PAL) 00306 dac.write_u16(IRE_m40); 00307 dac.write_u16(IRE_m40); 00308 dac.write_u16(IRE_m40); //extra for PAL timing 00309 dac.write_u16(IRE_m40); //extra for PAL timing 00310 00311 //Then that video signal for 52.6us (52 for PAL): 00312 00313 //////////////////////////////////////////////////////////// 00314 //Write out the video data 00315 //(very timing sensitive as must last ~53us, no more or less) 00316 //////////////////////////////////////////////////////////// 00317 00318 // Examples: 00319 00320 //1) draw random shade per line 00321 // dac.write_u16(rand() % 40000 + IRE_7p5); //Video signal for 52.6us 00322 // wait_us(52); 00323 00324 //2) draw black 00325 // dac.write_u16(IRE_7p5); 00326 // wait_us(51); 00327 00328 //3) draw white 00329 // dac.write_u16(IRE_100); 00330 // wait_us(51); 00331 00332 //4) draw framebuffer 00333 00334 // Code here is very timing critical. 00335 00336 // loop count is instruction dependent, if you add some code here, it will need be a different width 00337 // We have ~52.5us and a a dac write takes 0.5us so 104/105px seems correct. 00338 // Trial+error shows ~100-110 pixels to be OKish on a particular old TV. 00339 00340 int k =(i/ SCAN ); //double scan the framebuffer, particularly convenient for 128 vertical px but 256 line resolution.. 00341 00342 // The modulo is only needed if screen output size is bigger than framebuffer (wrapping occurs). 00343 // Stick to powers of 2 for modulo wrapping (or likely too slow). 00344 for (int j = 0; j < DRAWWIDTH; j++) { 00345 dac.write_u16( framebuffer[k%128][j%128] ); //modulo used to wrap framebuffer. Keep to power of 2 =< framebuffer sizes. 00346 } //next pixel 00347 00348 } //next line loop 00349 00350 //Default back to black when we don't bother drawing the last few lines of a frame! 00351 dac.write_u16(IRE_7p5); 00352 } //End of createframe routine 00353 00354 00355 00356 //////////////////////////////////////////////////////////// 00357 // randomfill the framebuffer // 00358 //////////////////////////////////////////////////////////// 00359 void randomfill () { 00360 for (int j = 0; j < HEIGHT; j++) { 00361 for (int i = 0; i < WIDTH; i++) { 00362 framebuffer[j][i] = rand(); 00363 if (framebuffer[j][i] < IRE_7p5 ) { 00364 framebuffer[j][i] = IRE_7p5; 00365 } 00366 } 00367 } 00368 } 00369 00370 //////////////////////////////////////////////////////////// 00371 // blank the framebuffer // 00372 //////////////////////////////////////////////////////////// 00373 void blankfill () { 00374 for (int j = 0; j < HEIGHT; j++) { 00375 for (int i = 0; i < WIDTH; i++) { 00376 framebuffer[j][i] = IRE_7p5; 00377 //framebuffer[j][i] = IRE_100; 00378 } 00379 } 00380 } 00381 00382 //////////////////////////////////////////////////////////// 00383 // zooming mandelbot fractal in the framebuffer // 00384 //////////////////////////////////////////////////////////// 00385 00386 void mandelbrot () { 00387 //Mandelbrot escape time algorithm (doubles+iteration=slow) 00388 //Taken from wikipedia pseudocode, 00389 //tweaked by using the speeded up version that google found on geocities 00390 //(oops - Geocities has shut down in the 3 weeks since I wrote this! first time I've used it in years!) 00391 //http://www.geocities.com/CapeCanaveral/5003/Mandel.txt 00392 //then put in a loop to zoom in on a intersting co-ords point i saw elsewhere... 00393 double zoom; 00394 for (int z = 0; z < 200; z++) {//2^50 is quite a lot of zoom - thats why you need precision! 00395 zoom= pow((double)1.2,z); 00396 00397 led1=0; 00398 led2=0; 00399 led3=0; 00400 led4=0; 00401 00402 double x,y; 00403 double x0,y0; 00404 // double xtemp; 00405 double xsq; 00406 double ysq; 00407 00408 unsigned short int iteration = 0; 00409 unsigned short int max_iteration = (z*2)+20; //arbitrary scaling so there are more interation allowed as you zoom 00410 for (int j = 0; j < HEIGHT; j++) { 00411 //little status hack as as drawing fractals (particularly with doubles on only 10% of a cpu is slow!) 00412 if (j== (( HEIGHT /4)-1)) { 00413 led1=1; 00414 } else if (j==(( HEIGHT /2)-1)) { 00415 led2=1; 00416 } else if (j==(3*( HEIGHT /4)-1)) { 00417 led3=1; 00418 } else if (j==( HEIGHT -1)) { 00419 led4=1; 00420 } 00421 //end of little status hack 00422 00423 00424 for (int i = 0; i < WIDTH; i++) { 00425 // x0=(((float) i) -32.0)/32.0;//redefine 0to63 as -1to+1 mandelbrot window 00426 // y0=(((float) j) -32.0)/32.0;//redefine 0to63 as -1to+1 mandelbrot window 00427 //-1.865725138512217656771 moves center point to something interesting 00428 x0=((((double) i) - ( WIDTH /2)) /zoom)-1.865725138512217656771;//redefine 0to63 as -1to+1 mandelbrot window 00429 y0=(((double) j) - ( HEIGHT /2)) /zoom;//redefine 0to63 as -1to+1 mandelbrot window 00430 iteration = 0; 00431 00432 //Standard version of mandelbrot loop based on wikipedia pseudocode 00433 // x=0; 00434 // y=0; 00435 // while ( ((x*x + y*y) <= (2*2)) && (iteration < max_iteration) ) { 00436 // xtemp = x*x - y*y + x0; 00437 // y = 2*x*y + y0; 00438 // x = xtemp; 00439 // iteration++; 00440 // } 00441 00442 //Speedy version of main mandelbrot loop (algorithm from geocities page) 00443 x=x0+x0*x0-y0*y0; 00444 y=y0+x0*y0+x0*y0; 00445 for (iteration=0;iteration<max_iteration && (ysq=y*y)+(xsq=x*x)<4;iteration++,y=y0+x*y+x*y,x=x0-ysq+xsq) ; 00446 00447 //Iteration count determines color (clamp max iteration to zero, and normalize for black to white) 00448 framebuffer[j][i] = (( iteration == max_iteration ) ? (IRE_7p5) : (IRE_7p5 + ((iteration%20)*2000)) ); 00449 } 00450 } 00451 }//zoom loop 00452 } 00453 00454 //////////////////////////////////////////////////////////// 00455 // fire the framebuffer // 00456 //////////////////////////////////////////////////////////// 00457 // based on demo at http://demo-effects.sourceforge.net/ 00458 // refer back to original code for how it should be done :-) 00459 void fire () { 00460 static unsigned char fire[WIDTH * HEIGHT]; 00461 int i,j,index,temp; 00462 00463 /* draw random bottom line in fire array*/ 00464 00465 j = WIDTH * (HEIGHT- 1); 00466 for (i = 0; i < WIDTH - 1; i++) { 00467 int random = 1 + (int)(16.0 * (rand()/(RAND_MAX+1.0))); 00468 if (random > 8) /* the lower the value, the intenser the fire, compensate a lower value with a higher decay value*/ 00469 fire[j + i] = 255; /*maximum heat*/ 00470 else 00471 fire[j + i] = 0; 00472 } 00473 00474 /* move fire upwards, start at bottom*/ 00475 00476 for (index = 0; index < HEIGHT-4 ; ++index) { 00477 for (i = 0; i < WIDTH - 1; ++i) { 00478 if (i == 0) { /* at the left border*/ 00479 temp = fire[j]; 00480 temp += fire[j + 1]; 00481 temp += fire[j - WIDTH]; 00482 temp /=3; 00483 } else if (i == WIDTH - 1) { /* at the right border*/ 00484 temp = fire[j + i]; 00485 temp += fire[j - WIDTH + i]; 00486 temp += fire[j + i - 1]; 00487 temp /= 3; 00488 } else { 00489 temp = fire[j + i]; 00490 temp += fire[j + i + 1]; 00491 temp += fire[j + i - 1]; 00492 temp += fire[j - WIDTH + i]; 00493 temp >>= 2; 00494 } 00495 if (temp > 1) 00496 temp -= 1; /* decay */ 00497 00498 fire[j - WIDTH + i] = temp; 00499 } 00500 j -= WIDTH; 00501 } 00502 00503 //dirty hack to convert the fire data to the framebuffer. better graduation of shades would look better! 00504 for (int j = HEIGHT-3 ; j >= 0; --j) { 00505 for (int i = WIDTH-1; i >= -1 ; --i) { 00506 framebuffer[j][i] = ((fire[j * WIDTH + i])*150)+IRE_7p5; 00507 } 00508 } 00509 00510 00511 } 00512 00513 00514 //////////////////////////////////////////////////////////// 00515 // main() showing use framebuffer // 00516 // Puts a grayscale pic in it // 00517 //////////////////////////////////////////////////////////// 00518 00519 int main() { 00520 00521 blankfill(); //set framebuffer to blank values 00522 00523 timer.attach_us(&createframe,20000);//attach the display (at 50Hz) 00524 00525 // int attached=0; //attach frame 00526 // //If you had a lot of setup in a main game loop, you could do something like this: 00527 // if (attached==0) { 00528 // timer.attach_us(&createframe,20000); 00529 // attached=1; 00530 // } 00531 00532 //Program loop 00533 while (1) { 00534 // Add you own demo code here. Expect it to get regularly interupted by the screen draw call! 00535 // very simple code can run at full fps. 00536 //Example - change HEIGHT to 64 and SCAN to 4 and use randomfill... 00537 //randomfill(); //random pixel fill 00538 00539 //Example - change HEIGHT to 86 and SCAN to 3 and use fire; 00540 fire(); 00541 00542 //Example - change HEIGHT to 128 and SCAN to 2 and use mandelbrot... 00543 //mandelbrot(); //mandelbrot procedure is a 200 loop zoom so takes ages - and each scene redraw takes a few seconds! 00544 } //while 00545 00546 } //main 00547 00548
Generated on Sun Jul 24 2022 14:44:43 by
