forwarding a radium compilation fix.
[AROS-Contrib.git] / fish / mandel / mand1.c
blob504bc30d1dac8b57a87754eb7a822df7bbd47a25
1 /*
2 MAND1.C - Graphics routines
3 Mandelbrot Self-Squared Dragon Generator
4 For the Commodore Amiga
5 Version 1.00
7 Accompanies MAND.C
9 Copyright (C) 1985, Robert S. French
10 Placed in the Public Domain
12 Assorted Goodies and Intuition-stuff by =RJ Mical= 1985
13 Hope you appreciate them. I especially like the zoom.
15 This program may be distributed free of charge as long as the above
16 notice is retained.
21 #include "mand.h"
23 /*----------------------*/
24 /* Graphics definitions */
26 extern struct GfxBase *GfxBase;
27 extern struct IntuitionBase *IntuitionBase;
29 extern struct RastPort *rp,*rp2;
30 extern struct ViewPort *vp;
32 extern struct Window *w,*w2;
33 extern struct Screen *screen;
34 extern struct IntuiMessage *message;
36 extern long last_color;
38 extern BOOL SettingCenter, SettingBoxSize;
40 /*----------------------------------*/
41 /* Miscellaneous Global Definitions */
43 extern union kludge {
44 float f;
45 KLUDGE_INT i;
46 } start_r,end_r,start_i,end_i; /* Block bounds for set */
47 extern int max_x,max_y; /* Graphics window size */
48 extern int max_count,color_inc,color_offset,color_set,color_mode,color_div;
49 extern int color_inset,func_num;
51 extern int v_starty,max_mem;
52 extern long v_offset;
53 extern UWORD *color_table,*v_mand_store;
55 extern int modified,want_read;
57 extern FILE *console,*v_fp,*redir_fp;
59 extern SHORT ZoomCenterX, ZoomCenterY, ZoomBoxSizeX, ZoomBoxSizeY;
60 extern SHORT ZoomBoxStartX, ZoomBoxStartY;
62 void loc_abort(char *s);
64 /*----------------*/
65 /* Color routines */
67 void init_colors()
69 switch (color_set) {
70 case 0: init_cincr(); break;
71 case 1: init_c7rot(); break;
75 void init_cincr()
76 /* this routine initializes the color table with sequential values from
77 * 0 to 4095
80 UWORD i;
82 for (i=0;i<4096;i++)
83 *(color_table + i) = i;
87 void init_c7rot()
88 /* this routine initializes the color table with this pattern:
89 * 0 = 0
90 * 1-15 = unit steps of blue
91 * 16-30 = unit steps of green
92 * 31-45 = unit steps of red
93 * 46-60 = unit steps of sky sky blue (blue and green)
94 * 61-75 = unit steps of purple (blue and red)
95 * 76-90 = unit steps of yellow (green and red)
96 * 91-115 = unit steps of white (all colors)
99 UWORD i,j,*base;
101 base = color_table;
102 *(base++) = 0;
104 for (j = 0; j < 39; j++) {
105 for (i = 1; i < 16; i++)
106 *(base++) = i; /* gimme the blues */
107 for (i = 1; i < 16; i++)
108 *(base++) = i << 4; /* these are the greens */
109 for (i = 1; i < 16; i++)
110 *(base++) = i << 8; /* the reds */
111 for (i = 1; i < 16; i++)
112 *(base++) = i | (i << 4); /* blue and green */
113 for (i = 1; i < 16; i++)
114 *(base++) = i | (i << 8); /* blue and red */
115 for (i = 1; i < 16; i++)
116 *(base++) = (i << 4) | (i << 8); /* green and red */
117 for (i = 1; i < 16; i++)
118 *(base++) = i | (i << 4) | (i << 8); /* all three */
123 int gen_mand()
125 void write_out();
127 int x_coord,y_coord,count;
128 union kludge x_gap,y_gap,z_r,z_i,u_r,u_i,temp,temp2,temp3,const0;
129 union kludge const1,const2,const12;
130 ULONG class;
131 USHORT code;
133 /* if there was a display open, close it now */
134 CloseDisplay();
135 /* reset the display variables: */
136 SettingCenter = SettingBoxSize = FALSE;
138 if (v_fp) {
139 fclose(v_fp);
140 v_fp = NULL;
143 v_fp = fopen("Mandelbrot.temp.file","w+");
144 if (v_fp == NULL) {
145 loc_abort("Can't open temporary file!");
148 v_starty = 1;
149 v_offset = 0L;
150 modified = FALSE;
151 want_read = FALSE;
152 ZoomCenterX = (max_x >> 1);
153 ZoomCenterY = (max_y >> 1);
154 ZoomBoxSizeX = max_x;
155 ZoomBoxSizeY = max_y;
157 if (open_winds())
158 return (1);
160 x_gap.i = SPDiv(SPFlt(max_x),SPSub(start_r.i,end_r.i));
161 y_gap.i = SPDiv(SPFlt(max_y),SPSub(start_i.i,end_i.i));
163 const0.i = SPFlt(0);
164 const1.i = SPFlt(1);
165 const2.i = SPFlt(2);
166 const12.i = SPDiv(SPFlt(2),SPFlt(1));
168 for (y_coord = 0; y_coord < max_y; y_coord++)
170 last_color = 0xfff;
171 v_pos_line(y_coord);
172 modified = TRUE;
173 for (x_coord = 0; x_coord < max_x; x_coord++)
175 while ((message = (struct IntuiMessage *)GetMsg(w->UserPort)))
177 class = message->Class;
178 code = message->Code;
179 ReplyMsg((struct Message *)message);
180 if (class == MENUPICK)
182 switch MENUNUM(code)
184 case MENU_OPTIONS:
185 switch ITEMNUM(code)
187 case OPTIONS_STOP:
188 return (0);
189 case OPTIONS_CLOSE:
190 CloseDisplay();
191 fclose(v_fp);
192 v_fp = NULL;
193 return (1);
199 if (func_num == 0)
200 z_r.i = const0.i;
201 else
202 z_r.i = const12.i;
204 z_i.i = const0.i;
205 u_r.i = SPAdd(start_r.i,SPMul(SPFlt(x_coord),x_gap.i));
206 u_i.i = SPAdd(start_i.i,SPMul(SPFlt(max_y-y_coord-1),y_gap.i));
208 #if 0
209 kprintf("%d %d %d %d\n", (LONG)(start_r.f * 1000.0),
210 (LONG)(x_gap.f * 1000.0),
211 (LONG)(start_i.f * 1000.0),
212 (LONG)(y_gap.f * 1000.0));
214 u_r.f = -2.0 + (((float)x_coord) * 4.0 / 320.0);
215 u_i.f = -2.0 + (((float)y_coord) * 4.0 / 200.0);
216 #endif
218 count = 0;
220 for (count = 0;
221 SPFix( SPAdd( SPMul(z_r.i, z_r.i), SPMul(z_i.i,z_i.i))) < 4
222 && (count < max_count);
223 count++) {
224 if (func_num == 0) { /* z = z^2-u */
225 temp.i = SPSub(u_r.i,SPSub(SPMul(z_i.i,z_i.i),SPMul(z_r.i,z_r.i)));
226 z_i.i = SPSub(u_i.i,SPMul(SPMul(const2.i,z_r.i),z_i.i));
227 z_r = temp;
229 else if (func_num == 1) { /* z = uz(1-z) */
230 temp2.i = SPSub(z_r.i,const1.i);
231 temp3.i = SPNeg(z_i.i);
232 temp.i = SPSub(SPMul(temp3.i,z_i.i),SPMul(temp2.i,z_r.i));
233 z_i.i = SPAdd(SPMul(temp2.i,z_i.i),SPMul(temp3.i,z_r.i));
234 z_r = temp;
235 temp.i = SPSub(SPMul(z_i.i,u_i.i),SPMul(z_r.i,u_r.i));
236 z_i.i = SPAdd(SPMul(z_r.i,u_i.i),SPMul(z_i.i,u_r.i));
237 z_r = temp;
240 if (count >= max_count)
241 count = 0;
242 *(v_mand_store+(y_coord-v_starty)*max_x+x_coord) = count;
243 write_out(count,x_coord,y_coord);
247 DisplayBeep(NULL); /* hey, we're done! */
248 return (0);
251 int disp_mand()
253 void write_out();
255 int x_coord,y_coord,count;
257 if (open_winds())
258 return (1);
260 want_read = TRUE;
262 for (y_coord=0;y_coord<max_y;y_coord++) {
263 last_color = 0xfff;
264 v_pos_line(y_coord);
265 for (x_coord=0;x_coord<max_x;x_coord++) {
266 count = *(v_mand_store+(y_coord-v_starty)*max_x+x_coord);
267 write_out(count,x_coord,y_coord);
271 return (0);
274 void write_out(count,x,y)
275 int count,x,y;
277 void ham_write();
278 SHORT modulus;
279 int color;
281 y += STARTY;
283 if (!(color_mode & NOT_HOLDANDMODIFY)) {
284 if (count == 0)
285 color = color_inset;
286 else
287 color = count * color_inc + color_offset;
288 ham_write(*(color_table+color),x,y);
290 else /* we're not hold-and-modify, so ... */ {
291 if (color_mode & HIRES_MODE) modulus = 13;
292 else modulus = 29;
294 if (count == 0) color = 2;
295 else color = (((count - 1) / color_div) % modulus) + 3;
296 //kprintf("writepixel: color = %d count = %d\n", color, count);
297 SetAPen(rp, color);
298 WritePixel(rp, x, y);
302 void ham_write(color, x, y)
303 int color;
304 int x, y;
306 if ((color & 0xf00) != (last_color & 0xf00)) {
307 SetAPen(rp,((color & 0xf00) >> 8) + 0x20);
308 WritePixel(rp,x,y);
309 last_color = (last_color & 0xff) | (color & 0xf00);
310 return;
313 if ((color & 0xf0) != (last_color & 0xf0)) {
314 SetAPen(rp,((color & 0xf0) >> 4) + 0x30);
315 WritePixel(rp,x,y);
316 last_color = (last_color & 0xf0f) | (color & 0xf0);
317 return;
320 SetAPen(rp,(color & 0xf) + 0x10);
321 WritePixel(rp,x,y);
322 last_color = (last_color & 0xff0) | (color & 0xf);
323 return;
327 void DrawZoomCenter()
329 SetDrMd(w->RPort, COMPLEMENT);
330 Move(w->RPort, 0, ZoomCenterY);
331 Draw(w->RPort, max_x, ZoomCenterY);
332 Move(w->RPort, ZoomCenterX, 0);
333 Draw(w->RPort, ZoomCenterX, max_y);
337 void RecalcZoomBox()
339 ZoomBoxSizeX = (abs(w->MouseX - ZoomCenterX) << 1) + 1;
340 ZoomBoxSizeY = (abs(w->MouseY - ZoomCenterY) << 1) + 1;
341 if (w->MouseX < ZoomCenterX) ZoomBoxStartX = w->MouseX;
342 else ZoomBoxStartX = ZoomCenterX - ((ZoomBoxSizeX - 1) >> 1);
343 if (w->MouseY < ZoomCenterY) ZoomBoxStartY = w->MouseY;
344 else ZoomBoxStartY = ZoomCenterY - ((ZoomBoxSizeY - 1) >> 1);
348 void DrawZoomBox()
350 SHORT endx, endy;
352 endx = ZoomBoxStartX + ZoomBoxSizeX - 1;
353 endy = ZoomBoxStartY + ZoomBoxSizeY - 1;
355 SetDrMd(w->RPort, COMPLEMENT);
356 Move(w->RPort, ZoomBoxStartX, ZoomBoxStartY);
357 Draw(w->RPort, ZoomBoxStartX, endy);
358 Draw(w->RPort, endx, endy);
359 Draw(w->RPort, endx, ZoomBoxStartY);
360 Draw(w->RPort, ZoomBoxStartX, ZoomBoxStartY);
364 void CloseDisplay()
366 if (w) CloseWindow(w);
367 if (screen) CloseScreen(screen);
368 w = NULL;
369 screen = NULL;