2 MAND1.C - Graphics routines
3 Mandelbrot Self-Squared Dragon Generator
4 For the Commodore Amiga
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
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 */
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
;
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
);
70 case 0: init_cincr(); break;
71 case 1: init_c7rot(); break;
76 /* this routine initializes the color table with sequential values from
83 *(color_table
+ i
) = i
;
88 /* this routine initializes the color table with this pattern:
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)
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 */
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
;
133 /* if there was a display open, close it now */
135 /* reset the display variables: */
136 SettingCenter
= SettingBoxSize
= FALSE
;
143 v_fp
= fopen("Mandelbrot.temp.file","w+");
145 loc_abort("Can't open temporary file!");
152 ZoomCenterX
= (max_x
>> 1);
153 ZoomCenterY
= (max_y
>> 1);
154 ZoomBoxSizeX
= max_x
;
155 ZoomBoxSizeY
= max_y
;
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
));
166 const12
.i
= SPDiv(SPFlt(2),SPFlt(1));
168 for (y_coord
= 0; y_coord
< max_y
; y_coord
++)
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
)
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
));
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);
221 SPFix( SPAdd( SPMul(z_r
.i
, z_r
.i
), SPMul(z_i
.i
,z_i
.i
))) < 4
222 && (count
< max_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
));
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
));
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
));
240 if (count
>= max_count
)
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! */
255 int x_coord
,y_coord
,count
;
262 for (y_coord
=0;y_coord
<max_y
;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
);
274 void write_out(count
,x
,y
)
283 if (!(color_mode
& NOT_HOLDANDMODIFY
)) {
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;
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);
298 WritePixel(rp
, x
, y
);
302 void ham_write(color
, x
, y
)
306 if ((color
& 0xf00) != (last_color
& 0xf00)) {
307 SetAPen(rp
,((color
& 0xf00) >> 8) + 0x20);
309 last_color
= (last_color
& 0xff) | (color
& 0xf00);
313 if ((color
& 0xf0) != (last_color
& 0xf0)) {
314 SetAPen(rp
,((color
& 0xf0) >> 4) + 0x30);
316 last_color
= (last_color
& 0xf0f) | (color
& 0xf0);
320 SetAPen(rp
,(color
& 0xf) + 0x10);
322 last_color
= (last_color
& 0xff0) | (color
& 0xf);
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
);
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);
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
);
366 if (w
) CloseWindow(w
);
367 if (screen
) CloseScreen(screen
);