#include "INCLUDE:Lattice/math.h" #include "INCLUDE:Lattice/stdio.h" #include "INCLUDE:libraries/dos.h" #include "INCLUDE:exec/types.h" #include "INCLUDE:graphics/gfx.h" #include "INCLUDE:graphics/gfxmacros.h" #include "INCLUDE:exec/exec.h" #include "INCLUDE:exec/execbase.h" #include "INCLUDE:graphics/view.h" #include "INCLUDE:graphics/gfxbase.h" #include "INCLUDE:graphics/text.h" #include "INCLUDE:exec/libraries.h" #include "INCLUDE:intuition/intuition.h" #include "qman_data.include" /*---------------------------------------*/ /* */ /* // QMan ! // */ /* */ /* (That's supposed to stand for */ /* "Quick Mandelbrot.") */ /*---------------------------------------*/ void main() { GfxBase = (struct GfxBase *)OpenLibrary("graphics.library",0); IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",0); scale = 67108864.0; /* 2 ** 26 */ xptr = (int)&x_table[0]; kflag = 1; /* start off looking at the skew set */ Restart: restart_selected = FALSE; top = 1.1; bottom = -1.1; if ( kflag == 1 ) { left = -1.5; right = 1.0; } else { left = -2.0; right = 0.5; } random_colors = FALSE; cycle_colors = 1; /* initially cycle colors */ ilace = 2; /* start out without interlace */ vertical_res = 200; smooth_flag = 1; /* smoothing is initially on */ NewScreen: SetUpMandelGraphics(); SetUpMandelMenus(); SetMenuStrip( mandel_window, &qman ); screen_changed = FALSE; while (1 == 1) { NextPicture: Move( rp, 0, 0 ); ClearScreen( rp ); xincr = (right - left)/640.0; yincr = (top - bottom)/(double)vertical_res; left_x = left; for (i = 0; i < 640; i++ ) { x_table[i] = scale * left_x; left_x = left_x + xincr; } imagc = scale * top; /* Set bit plane pointers for next Mandelbrot picture: */ bp1 = (int) rp -> BitMap -> Planes[0]; bp2 = (int) rp -> BitMap -> Planes[1]; bp3 = (int) rp -> BitMap -> Planes[2]; bp4 = (int) rp -> BitMap -> Planes[3]; new_region_selected = FALSE; for ( y = 0; y < vertical_res; y++ ) { message = (struct IntuiMessage *) GetMsg( mandel_window -> UserPort ); if ( message != NULL ) { ProcessMessage(); if ( new_region_selected ) goto NextPicture; if ( screen_changed ) goto NewScreen; if ( restart_selected ) goto Restart; } if ( cycle_colors == 1 ) NextColor(); /* Call the appropriate assembly routine to draw the current row: */ if ( smooth_flag == 1 ) msmooth(); else mandel(); imagc = imagc - scale * yincr; } /* y-loop */ /* - - - - - - - - - - - - - - - - - - - - - - - - - -*/ cycle_count = 0; while( 1 == 1 ) { cycle_count = (cycle_count + 1) % 4000; if ( (cycle_count == 0) && (cycle_colors == 1) ) NextColor(); message = (struct IntuiMessage *) GetMsg( mandel_window -> UserPort ); if ( message != NULL ) { ProcessMessage(); if ( new_region_selected ) goto NextPicture; if ( screen_changed ) goto NewScreen; if ( restart_selected ) goto Restart; } } /* inner forever loop */ /* - - - - - - - - - - - - - - - - - - - - - - - - - -*/ } /* outer forever loop */ } /* main */ /*--------------------------------------------*/ #include "qman_graphics.include" #include "qman_menus.include" /*--------------------------------------------*/ void ProcessMessage() { struct MenuItem *Item; if ( message -> Class != MENUPICK ) return; if ( message -> Code == MENUNULL ) return; Item = (struct MenuItem *)ItemAddress( &qman, message -> Code ); if ( Item -> Command == 'q' ) { CloseWindow( mandel_window ); CloseScreen( mandel_screen ); exit(); } if ( Item -> Command == 'n' ) NextColor(); if ( Item -> Command == 'b' ) random_colors = FALSE; if ( Item -> Command == 'r' ) random_colors = TRUE; if ( Item -> Command == 'c' ) { /* toggle cycle option: */ ClearMenuStrip( mandel_window ); if ( cycle_colors == 1 ) /* cycling currently on */ cycle.Flags = cycle.Flags ^ CHECKED; /* turn cycling off */ else cycle.Flags = cycle.Flags | CHECKED; /* turn cycling on */ cycle_colors = 3 - cycle_colors; SetMenuStrip( mandel_window, &qman ); } if ( Item -> Command == 'm' ) { /* toggle smoothing option: */ ClearMenuStrip( mandel_window ); if ( smooth_flag == 1 ) /* smoothing currently on */ smooth.Flags = smooth.Flags ^ CHECKED; /* turn smoothing off */ else smooth.Flags = smooth.Flags | CHECKED; /* turn smoothing on */ smooth_flag = 3 - smooth_flag; SetMenuStrip( mandel_window, &qman ); } if ( Item -> Command == 'k' ) { /* toggle skew option: */ ClearMenuStrip( mandel_window ); if ( kflag == 1 ) /* skew currently on */ skew.Flags = skew.Flags ^ CHECKED; /* turn skew off */ else skew.Flags = skew.Flags | CHECKED; /* turn skew on */ kflag = 1 - kflag; SetMenuStrip( mandel_window, &qman ); } if ( Item -> Command == 'i' ) { /* toggle ilace option: */ ilace = 3 - ilace; vertical_res = 600 - vertical_res; screen_changed = TRUE; CloseWindow( mandel_window ); CloseScreen( mandel_screen ); } if ( Item -> Command == 's' ) { restart_selected = TRUE; CloseWindow( mandel_window ); CloseScreen( mandel_screen ); } if ( Item -> Command == 'z' ) SelectZoom(); ReplyMsg( message ); } /* end of ProcessMessage() */ /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - */ void NextColor() { int permute, greenzap; if ( random_colors ) { for( i = 3; i < 13; i++) { reds[i] = lrand48() % 16; greens[i] = lrand48() % 16; blues[i] = lrand48() % 16; SetRGB4( vp, i, reds[i], greens[i], blues[i] ); } } /* random colors */ else { /* generate the colors a little less chaotically! */ reds[3] = lrand48() % 16; greens[3] = lrand48() % 16; blues[3] = lrand48() % 16; greenzap = lrand48() % 12; permute = lrand48() % 6; for( i = 4; i < 13; i++) { reds[i] = (reds[i-1] + 1) % 16; greens[i] = (greens[i-1] + 15) % 16; if ( greenzap == 0 ) greens[i] = 0; blues[i] = blues[3]; switch( permute ) { case 0 : SetRGB4(vp,i,reds[i],greens[i],blues[i]); break; case 1 : SetRGB4(vp,i,reds[i],blues[i],greens[i]); break; case 2 : SetRGB4(vp,i,greens[i],reds[i],blues[i]); break; case 3 : SetRGB4(vp,i,greens[i],blues[i],reds[i]); break; case 4 : SetRGB4(vp,i,blues[i],reds[i],greens[i]); break; case 5 : SetRGB4(vp,i,blues[i],greens[i],reds[i]); break; } /* switch */ } /* i-loop */ } /* else */ } /* End of NextColor */ /* - - - - - - - - - - - - - - - - - - - - - - - - - */ void SelectZoom() { struct IntuiMessage *click, *click2; int IDCMP_flags, s3, t3; SHORT quad[10]; SetDrMd( rp, COMPLEMENT ); SetAPen( rp, 1 ); new_region_selected = TRUE; UpperLeft: WaitPort( mandel_window -> UserPort ); click = (struct IntuiMessage *) GetMsg( mandel_window -> UserPort ); if ( click -> Code != SELECTDOWN ) { ReplyMsg( click ); goto UpperLeft; } left = left + xincr * (double)click -> MouseX; top = top - yincr * (double)click -> MouseY; x1 = click -> MouseX; y1 = click -> MouseY; x3 = x1; y3 = y1; IDCMP_flags = MOUSEBUTTONS | MENUPICK | MOUSEMOVE; ModifyIDCMP( mandel_window, IDCMP_flags ); Move( rp, x1, y1 ); quad[3] = y1; quad[6] = x1; quad[8] = x1; quad[9] = y1; LowerRight: WaitPort( mandel_window -> UserPort ); click = (struct IntuiMessage *) GetMsg( mandel_window -> UserPort ); click2 = (struct IntuiMessage *) GetMsg( mandel_window -> UserPort ); if (click2 != NULL ) { ReplyMsg( click ); click = click2; } if ( click -> Code != SELECTUP ) { s3 = click -> MouseX; t3 = click -> MouseY; ReplyMsg( click ); if ( (s3 < x1) || (t3 < y1) ) goto LowerRight; x2 = x3; y2 = y3; x3 = s3; y3 = t3; quad[2] = x2; quad[4] = x2; quad[5] = y2; quad[7] = y2; PolyDraw( rp, 4, &quad[2] ); quad[2] = x3; quad[4] = x3; quad[5] = y3; quad[7] = y3; PolyDraw( rp, 4, &quad[2] ); goto LowerRight; } else ReplyMsg( click ); right = right - xincr * (double)(640 - click -> MouseX); bottom = bottom + yincr * (double)(vertical_res - click -> MouseY); IDCMP_flags = MOUSEBUTTONS | MENUPICK; ModifyIDCMP( mandel_window, IDCMP_flags ); SetDrMd( rp, JAM1 ); }