/************************************************************************ * Version 3.00 MANDELBROT - Self-Squared Dragon Generator 29-May-86 * * Commodore Amiga Graphics Routines MAND1.C * ************************************************************************* * Copyright (c) 1986, Robert S. French and R. J. Mical * * --------------------------------------------------------------------- * * This program has been placed in the public domain. A limited * * license is hereby granted for the unlimited use and distribution of * * this program, provided it is not used for commercial or profit- * * making purposes. Thank you. * ************************************************************************* * Author information: | Name: R. J. Mical * * | USnail: Commodore-Amiga, Inc. * * Name: Robert S. French | 983 University Avenue * * USnail: 2740 Frankfort Avenue | Los Gatos, CA 95030 * * Louisville, KY 40206 \-------------------------------------* * Phone: (502) 897-5096 UUCP: ihnp4!ptsfa!well!french * * ARPA: French#Robert%d@LLL-MFE or RFrench@MIT-MULTICS * ************************************************************************* * Please send any comments, suggestions, or bugs to one of the above * * addresses. * ************************************************************************/ #include "mand.h" #include "globals.h" int start_x,last_y,last_color; /*----------------*/ /* Color routines */ init_colors() { switch (color_set) { case 0: init_cincr(); break; case 1: init_c7rot(); break; case 2: copy_userpalette(); break; } } init_cincr() /* this routine initializes the color table with sequential values from * 0 to 4095 */ { UWORD i; for (i=0;i<4096;i++) *(color_table + i) = i; } init_c7rot() /* this routine initializes the color table with this pattern: * 0 = 0 * 1-15 = unit steps of blue * 16-30 = unit steps of green * 31-45 = unit steps of red * 46-60 = unit steps of cyan (blue and green) * 61-75 = unit steps of magenta (blue and red) * 76-90 = unit steps of yellow (green and red) * 91-115 = unit steps of white (all colors) */ { UWORD i,j,*base; base = color_table; *(base++) = 0; for (j = 0; j < 39; j++) { for (i = 1; i < 16; i++) *(base++) = i; for (i = 1; i < 16; i++) *(base++) = i << 4; for (i = 1; i < 16; i++) *(base++) = i << 8; for (i = 1; i < 16; i++) *(base++) = i | (i << 4); for (i = 1; i < 16; i++) *(base++) = i | (i << 8); for (i = 1; i < 16; i++) *(base++) = (i << 4) | (i << 8); for (i = 1; i < 16; i++) *(base++) = i | (i << 4) | (i << 8); } } copy_userpalette() { SHORT i; for (i = 3; i <= 32; i++) *(color_table + color_offset + (i - 2) * color_inc) = UserPalette[i]; } gen_mand() { void write_out(); int x_coord,y_coord,count; FLOATSTRUCT x_gap,y_gap,z_r,z_i,u_r,u_i,temp,const0; FLOATSTRUCT const1,z_r_squared,z_i_squared; ULONG class; USHORT code; int returncode; /* if there was a display open, close it now */ CloseDisplay(); /* show the current settings! */ CurrentSettings(); /* reset the display variables: */ SettingCenter = SettingBoxSize = FALSE; if (v_fp) { fclose(v_fp); v_fp = NULL; } v_fp = fopen(TEMPNAME,"w+"); if (v_fp == NULL) { abort("Can't open temporary file!"); } threed_stat = 0; v_starty = 1; v_offset = 0L; modified = FALSE; want_read = FALSE; last_y = -1; ZoomCenterX = (max_x >> 1); ZoomCenterY = (max_y >> 1); ZoomBoxSizeX = max_x; ZoomBoxSizeY = max_y; if (open_winds()) { returncode = 1; goto OPEN_W_RETURN; } MAKEFP(x_gap) = DIV(FLT(max_x),SUB(MAKEFP(start_r),MAKEFP(end_r))); MAKEFP(y_gap) = DIV(FLT(max_y),SUB(MAKEFP(end_i),MAKEFP(start_i))); MAKEFP(const0) = FLT(0); MAKEFP(const1) = FLT(1); u_i = end_i; for (y_coord = 0; y_coord < max_y; y_coord++) { u_r = start_r; last_color = 0xfff; v_pos_line(y_coord); modified = TRUE; for (x_coord = 0; x_coord < max_x; x_coord++) { while (message = (struct IntuiMessage *)GetMsg(w->UserPort)) { class = message->Class; code = message->Code; ReplyMsg(message); if (class == MENUPICK) { switch MENUNUM(code) { case MENU_PROJECT: ProjectMenu(code); break; case MENU_OPTIONS: switch ITEMNUM(code) { case OPTIONS_STOP: returncode = 0; fclose(v_fp); v_fp = NULL; goto OPEN_W_RETURN; case OPTIONS_CLOSE: CloseDisplay(); fclose(v_fp); v_fp = NULL; returncode = 1; goto OPEN_W_RETURN; } break; } } } z_r = const0; z_i = const0; for (count = 0; count < max_count; count++) { /* By setting these variables and reusing the results below, * we save approximately 10% execution time in this * innermost of inner loops. */ MAKEFP(z_r_squared) = MUL(MAKEFP(z_r), MAKEFP(z_r)); MAKEFP(z_i_squared) = MUL(MAKEFP(z_i), MAKEFP(z_i)); if ( FIX(ADD(MAKEFP(z_r_squared), MAKEFP(z_i_squared))) >= 4 ) break; if (func_num == 0) { MAKEFP(temp) = SUB(MAKEFP(u_r), SUB(MAKEFP(z_i_squared), MAKEFP(z_r_squared))); MAKEFP(z_i) = SUB(MAKEFP(u_i), MUL(ADD(MAKEFP(z_r),MAKEFP(z_r)), MAKEFP(z_i))); z_r = temp; } else { if (func_num == 1) { MAKEFP(temp) = ADD(MAKEFP(u_r), SUB(MAKEFP(z_i_squared), MAKEFP(z_r_squared))); MAKEFP(z_i) = ADD(MAKEFP(u_i), MUL(ADD(MAKEFP(z_r),MAKEFP(z_r)), MAKEFP(z_i))); z_r = temp; } } } if (count >= max_count) count = 0; *(v_mand_store+(y_coord-v_starty)*max_x+x_coord) = count; write_out(count,x_coord,y_coord); MAKEFP(u_r) = ADD(MAKEFP(u_r),MAKEFP(x_gap)); } MAKEFP(u_i) = ADD(MAKEFP(u_i),MAKEFP(y_gap)); } /* successful return with window opened */ returncode = 0; /* Now that we're drawing the primary display, * restore the entire menu system */ OPEN_W_RETURN: reset_menus(); return(returncode); } disp_mand() { void write_out(); int x_coord,y_coord,count; ULONG class; USHORT code; CloseDisplay(); if (open_winds()) return (1); reset_draw(); want_read = TRUE; threed_stat = 0; for (y_coord=0;y_coordUserPort)) { class = message->Class; code = message->Code; ReplyMsg(message); if (class == MENUPICK) { switch MENUNUM(code) { case MENU_PROJECT: ProjectMenu(code); break; case MENU_OPTIONS: switch ITEMNUM(code) { case OPTIONS_STOP: reset_menus(); return (0); case OPTIONS_CLOSE: CloseDisplay(); return (1); } break; } } } for (x_coord=0;x_coordUserPort)) { class = message->Class; code = message->Code; ReplyMsg(message); if (class == MENUPICK) { switch MENUNUM(code) { case MENU_PROJECT: ProjectMenu(code); break; case MENU_OPTIONS: switch ITEMNUM(code) { case OPTIONS_STOP: FreeMem(last_tab,max_x*4*sizeof(UWORD)); reset_menus(); return (0); case OPTIONS_CLOSE: FreeMem(last_tab,max_x*4*sizeof(UWORD)); CloseDisplay(); return (1); } break; } } } avg = 0; for (x2=x_coord;x2> 1) - avg; if (y3 < 0) y3 = 0; Move(rp,x_coord,((max_y + y_coord + 8) >> 1) + STARTY); Draw(rp,x_coord,y3 + STARTY); } for (y2=0;y2<7;y2++) for (x2=0;x2> 8) & 0xf; green = (color >> 4) & 0xf; blue = color & 0xf; redd = iabs(((last_color >> 8) & 0xf) - red); greend = iabs(((last_color >> 4) & 0xf) - green); blued = iabs((last_color & 0xf) - blue); if (redd >= greend && redd >= blued) { SetAPen(rp,red + 0x20); WritePixel(rp,x,y); last_color = (last_color & 0xff) | (color & 0xf00); return; } if (greend >= redd && greend >= blued) { SetAPen(rp,green + 0x30); WritePixel(rp,x,y); last_color = (last_color & 0xf0f) | (color & 0xf0); return; } SetAPen(rp,blue + 0x10); WritePixel(rp,x,y); last_color = (last_color & 0xff0) | blue; return; } DrawZoomCenter() { DrawCross(ZoomCenterX, ZoomCenterY); } DrawDisplayCenter() { DrawCross(max_x >> 1, max_y >> 1); } DrawCross(x, y) SHORT x, y; { SetDrMd(rp, COMPLEMENT); Move(rp, 0, y+STARTY); Draw(rp, rangex(x-4), y+STARTY); Move(rp, rangex(x+4), y+STARTY); Draw(rp, max_x-1, y+STARTY); Move(rp, x, STARTY); Draw(rp, x, rangey(y-3)+STARTY); Move(rp, x, rangey(y+3)+STARTY); Draw(rp, x, max_y+STARTY-1); } rangex(i) int i; { if (i<0) return (0); if (i>max_x-1) return (max_x-1); return (i); } rangey(i) int i; { if (i<0) return (0); if (i>max_y-1) return (max_y-1); return (i); } RecalcZoomBox() { ZoomBoxSizeY = (iabs(w->MouseY - ZoomCenterY) << 1) + 1; if (w->MouseY < ZoomCenterY) ZoomBoxStartY = w->MouseY; else ZoomBoxStartY = ZoomCenterY - ((ZoomBoxSizeY - 1) >> 1); /* if SetBoxProportional, size X proportional to Y */ if (SetBoxProportional) { ZoomBoxSizeX = (ZoomBoxSizeY * 8) / 5; ZoomBoxStartX = ZoomCenterX - ((ZoomBoxSizeX - 1) >> 1); } else { ZoomBoxSizeX = (iabs(w->MouseX - ZoomCenterX) << 1) + 1; if (w->MouseX < ZoomCenterX) ZoomBoxStartX = w->MouseX; else ZoomBoxStartX = ZoomCenterX - ((ZoomBoxSizeX - 1) >> 1); } } DrawZoomBox() { SetDrMd(rp, COMPLEMENT); DrawBox(rp, ZoomBoxStartX, ZoomBoxStartY, ZoomBoxStartX + ZoomBoxSizeX - 1, ZoomBoxStartY + ZoomBoxSizeY - 1); } CloseDisplay() { if (w) CloseWindow(w); if (w2) CloseWindow(w2); if (ColorWindow) CloseWindow(ColorWindow); if (screen) CloseScreen(screen); w = NULL; w2 = NULL; ColorWindow = NULL; screen = NULL; } DrawBox(rp, x1, y1, x2, y2) struct RastPort *rp; SHORT x1, y1, x2, y2; /* draws a box without overlapping the edges (in case of complement mode) */ { Move(rp, x1, y1 + SIGN(y2 - y1)+STARTY); Draw(rp, x1, y2+STARTY); Move(rp, x1 + SIGN(x2 - x1), y2+STARTY); Draw(rp, x2, y2+STARTY); Move(rp, x2, y2 - SIGN(y2 - y1)+STARTY); Draw(rp, x2, y1+STARTY); Move(rp, x2 - SIGN(x2 - x1), y1+STARTY); Draw(rp, x1, y1+STARTY); }