denbeste@world.std.com : Steven C. Den Beste "rm2.c": This is based on the program "retmand" which someone else posted recently. I could not have done this without him, and I hereby announce my gratitude. Nonetheless, I suspect that this is so dramatically modified at this point that the original author wouldn't recognize it. this point that the original author wouldn't recognize it. The original program just drew the entire Mandelbrot drawing, using random colors each time. That's all it did - but to do that it had to implement the entire algorithm for CALCULATING it, and all the code for displaying stuff on the Retina. Those are the parts I couldn't have handled. In particular, it used the smart algorithm for calculating the Mandelbrot diagram (the one which optimizes square sections) instead of the stupid algorithm (the one which calculates each point every time). the stupid algorithm (the one which calculates each point every time). What I DO know how to do is enhance, clean up, and optimize. But to do that I had to perform some modifications. First and foremost: The original code was written for the SAS compiler. I've got Aztec C 5.0. Regrettably, they aren't compatible. For a while I tried to maintain compatibility with #ifdef's, but that got so complex that I finally gave up and deleted everything non-aztec, so this code is thoroughly MANXified now. Adapting this back to SAS is probably going to be a pain. The core of any Mandelbrot program is a routine which iterates a rather strange function, waiting until the value of the function exceeds a certain threshold. The value it returns is the integer count of the number of loops it took for this to take place. All the calculations are done in floating point. As a result, Mandelbrot programs have a tendency to take enormous amounts of time unless handled well. One finds implementations using fixed-point integers, but these lead to strange results where the program has a "floor" of detail, for instance. Using floating point prevents this flaw. tance. Using floating point prevents this flaw. The innermost loop of this function can iterate literally millions of times depending on the area you are viewing and the dimensions of the screen. Any tiny gains in this function can have significant results in the total compute time. So I dug out my 68882 manual and got to work. It's in ASM now in a separate module (another reason it's probably going to be hard to re-SASify). My code is optimized to take advantage of the '882's capability to perform simultaneous operations. (Don't worry - it works just fine for an '881 - it just takes longer.) The big win is that there are 8 registers out there, and I can store a lot of values permanently in the FPU - effectively, they become "register double" variables. It is possible that more juice can be squeezed out of this routine, and even a microsecond or two can make a big difference. I invite anyone who is into this sort of thing to try. I'm a programmer by profession, and we tend to avoid ASM like the plague because it is almost always too expensive to debug. (We use it for interrupt routines, task switchers and not a hell of a lot else.) As with the original, this program uses the default screen size for 8-bit screens, as set with "RetinaScreenMode". In the mean time I've added a bunch of features. There are now a bunch of parameters you can specify on the command line, as follows: /r number - specify the "r" (actually horizontal) value of the CENTER of the screen. Negative is left. Values range from about minus 2 to plus 2. /i number - specify the "i" (actually vertical) value of the CENTER of the screen. Negative is up. Values range from about minus 1 to plus 1. /w number - specify the width of the screen in "r" coordinate terms. The vertical size is computed to maintain an aspect ratio of 1.2 to 1. I made /r and /i specify the CENTER deliberately. If you can locate the center of a feature, it is convenient to generate the frames of a zoom movie, since all you have to do is change the "w" value. If /r and /i specified the upper left corner, that would be a royal pain. (The names "R" and "I" for these coordinates were established by Mandelbrot himself, and are maintained here for historical reasons.) If you don't specify any of the above three parameters, you get the entire Mandelbrot diagram. /c number - Choose a color set. Frankly, right now I'm not very happy with the ones I've chosen. If you don't specify anything, you get a standard set I think works fairly well. If you specify "/c 0" you get the random color set the old program would have given you by default. The others are somewhat obscure. There is plenty of opportunity here for enhancement. /q Use a quarter of the screen. Actually a misnomer - this divides the screen linearly by 4, so it divides the area by 16. Use this when you're trying to home in on /r and /i values for interesting features to cut way down on the compute time. /h Use a half (that is, 1/4 by area) of the screen. /t number Raise the top of the drawing. The default is 256. Values above 256 will cause the color set to recycle. Values can be specified up to 32767. Please note that depending on the image you are computing, raising this value can radically slow down compute time. /d number Often used with "/t". This takes the output of the function and divides it by the parameter for every pixel. In essence it is lowering the color thresholds. For instance, "/d 3" means that the first color threshold represents the first THREE step-values, the second represents the next THREE step-values, and so on. This does not alter the time to compute the drawing, but it can alter its image quite a bit. /s filename If this parameter is NOT present, then when the picture is completely drawn it will stay on the screen until you hit the "ENTER" key. If this parameter IS present, then when the image is complete it will be written out as a 24-bit PPM file, and then this program will automatically terminate. This means if you want to create the frames for a zoom movie, you can set up a batch file and let it run overnight, or for a week, or for a month, or for ... WARNING: These files are ENORMOUS. You can chew up disk space really fast. The file takes 3 bytes per pixel. An 800*600 frame is 1.5 megabytes (sigh). You might want to make your batch file alternate between creating files with this program and crunching them with "lha", which can typically collapse such a file to 100 Kb or less, depending on image complexity. Alternatively, you can use "ppmtogif" which won't do as well as "lha" but leaves them in a displayable form. By definition these files always have fewer than 256 colors, so "ppmtogif" won't ever tell you to go use "ppmquant" first. /m threshold What happens if the Mandelbrot threshold of 4.0 is modified? Beats heck out of me, but this parameter allows you to experiment. (My early experimenting shows that values above about 2.1 all act about the same, and below 1.9 the whole image turns black.) To get you started, here are some interesting parameter values to try: /r -.93402 /i -.247638 /w .00004 /d 2 /t 512 /r -.5554 /i -.5292 /w .006 /r -1.2909 /i -.0861 /w .00155 /r -.6763 /i -.36742 /w .0003 /r -676204 /i -.367276 /w .000017 /r -.6762039 /i -.3672763 /w .0000021 /d 2 /t 512 or /r -.6762039 /i -.3672763 /w .0000021 /d 3 /t 768 Even with all the optimization, these are not going to be fast drawings, but the results are spectacular (in my own highly biased opinion). These tended to take more than half an hour on my system at 800*600. Your mileage may vary. (My system is a GVP G-force 68040 at 33 MHZ running burst mode, so a 25 MHZ 68030 is probably going to run 4 or 5 times as long.) If you find any interesting coordinates and feel like doing so, please send them to me via email at the address at the top line. Bugs are likewise of interest. Oh, I also added a hell of a lot of comments. There ARE a few comments here which are not mine, but you'll pick up on my style rapidly. Where there's a chance of confusion, I'll include my initials: SCDB. ...and for my next trick: The one obvious need here is a simple way to pick out the coordinate of some object, so as to center and zoom on that object. The obvious way to do that is to use the mouse. Well, I can't. To do that I have to turn on a Sprite, and the part of the Retina includes for that uses a standard SAS include named "utility/tagitem.h", which Aztec doesn't have. I can't find the equivalent structure ("struct TagItem") or define ("TAG_USER") anywhere in the include structure I've got and I haven't got the faintest idea of what they should be. If someone can tell me, I'll try to put it in. In the mean time, the only way to home in on objects is to use "/q" and to tweak the "/r" and "/i" values.