Mandelbrot GS
Mandelbrot GS
program Mandelbrot;
uses Types, QuickDraw, Events;
const
size = 100000000;
max = 400000000;
type
colourMode = (defaultMode, repeatMode, rangeMode, beautyMode);
var
key, n: integer;
mode: colourMode;
cursorOn, graphOn: boolean;
event: eventRecord;
tempPalette: array [1..15] of integer;
colourTable: array [0..999] of integer;
procedure ProcessEvent(static rStart, iStart, increment: extended;
iteration: integer; mirror: boolean); forward;
procedure SetColourTable(iteration: integer);
begin
case mode of
defaultMode:
for n := 0 to (iteration - 1) do
colourTable[n] := ((n * 30) div iteration) mod 15 + 1;
repeatMode:
for n := 0 to (iteration - 1) do
colourTable[n] := n mod 15 + 1;
rangeMode:
for n := 0 to (iteration - 1) do
colourTable[n] := (n * 15) div iteration + 1;
beautyMode:
for n := 0 to 999 do
colourTable[n] := n mod 15 + 1;
end;
end;
procedure Paint (static rStart, iStart, increment: extended; iteration: integer; mirror: boolean);
var
x, y, n, sx, sy, cx, cy, yEnd, colour: integer;
r, i, zr, zi, zr2, zi2, dist, temp, rStartInt, iStartInt, incInt,
incStartInt: longInt;
begin
rStartInt := Round(rStart * size);
iStartInt := Round(iStart * size);
incStartInt := Round(increment * size);
incInt := incStartInt * 2;
SetColourTable(iteration);
if mirror then yEnd := 49
else yEnd := 99;
for sx := 0 to 1 do
for sy := 0 to 1 do begin
i := iStartInt - incStartInt * sy;
temp := rStartInt + incStartInt * sx;
for y := 0 to yEnd do begin
r := temp;
for x := 0 to 159 do begin
zr := 0;
zi := 0;
zr2 := 0;
zi2 := 0;
if GetNextEvent(EveryEvent, event) then
ProcessEvent(rStart, iStart, increment, iteration, mirror);
for n := 1 to iteration do begin
zi := (2 * zr * zi + i) div 10000;
zr := (zr2 - zi2 + r) div 10000;
zr2 := zr * zr;
zi2 := zi * zi;
dist := abs(zr2 + zi2);
if dist > max then begin
if mode = beautyMode then
SetSolidPenPat(colourTable[dist div 100000000 + 1])
else
SetSolidPenPat(colourTable[n]);
cx := x * 2 + sx;
cy := y * 2 + sy;
MoveTo(cx, cy);
Line(0, 0);
if mirror then begin
MoveTo(cx, 199 - cy);
Line(0, 0);
end;
Leave;
end;
end;
r := r + incInt;
end;
i := i - incInt;
end;
end;
graphOn := true;
GrafOn;
while true do
if GetNextEvent(EveryEvent, event) then
ProcessEvent(rStart, iStart, increment, iteration, mirror);
end;
procedure ProcessEvent(static rStart, iStart, increment: extended;
iteration: integer; mirror: boolean);
var
nextIteration, time, temp, dir: integer;
loc: point;
box: rect;
begin
case event.what of
KeyDownEvt: begin
key := event.message;
case key of
8: if mode <> defaultMode then begin
mode := defaultMode;
Paint(rStart, iStart, increment, iteration, mirror);
end;
9: begin
time := 5000;
for n := 1 to 15 do
tempPalette[n] := GetColorEntry(0, n);
while true do begin
if dir > 0 then begin
temp := GetColorEntry(0, 15);
for n := 14 downto 1 do
SetColorEntry(0, n + 1, GetColorEntry(0, n));
SetColorEntry(0, 1, temp);
end
else
begin
temp := GetColorEntry(0, 1);
for n := 1 to 14 do
SetColorEntry(0, n, GetColorEntry(0, n + 1));
SetColorEntry(0, 15, temp);
end;
for n := 1 to time do;
if GetNextEvent(EveryEvent, event) then
case event.what of
KeyDownEvt:
begin
key := event.message;
if key = 9 then
if dir > 0 then dir := 0
else dir := 1
else
if key = 48 then time := 0
else
if (key > 48) and (key < 58) then
time := (58 - key) * 1000
else begin
for n := 1 to 15 do
SetColorEntry(0, n, tempPalette[n]);
Leave;
end;
end;
end;
end;
end;
10: if mode <> rangeMode then begin
mode := rangeMode;
Paint(rStart, iStart, increment, iteration, mirror);
end;
11: if mode <> beautyMode then begin
mode := beautyMode;
Paint(rStart, iStart, increment, iteration, mirror);
end;
13: if cursorOn then begin
HideCursor;
cursorOn := false;
end
else begin
ShowCursor;
cursorOn := true;
end;
21: if mode <> repeatMode then begin
mode := repeatMode;
Paint(rStart, iStart, increment, iteration, mirror);
end;
27: Halt;
32: begin
ClearScreen(Black);
Paint(-2.6, 1.2, 0.012, 30, true);
end;
48: begin
for n := 0 to 7 do
SetColorEntry(0, n * 2 + 1, 4095);
for n := 1 to 7 do
SetColorEntry(0, n * 2, 15);
end;
49: for n := 1 to 15 do
SetColorEntry(0, n, 15 * n);
50: begin
for n := 1 to 8 do
SetColorEntry(0, n, (n * 2 - 1) * 256 + 240);
for n := 9 to 15 do
SetColorEntry(0, n, 4080 - (n - 8) * 32);
end;
51: begin
for n := 1 to 8 do
SetColorEntry(0, n, 7 + n);
for n := 9 to 15 do
SetColorEntry(0, n, (n - 8) * 32 + 15);
end;
52: begin
for n := 1 to 8 do
SetColorEntry(0, n, (7 + n) * 256);
for n := 9 to 15 do
SetColorEntry(0, n, 3840 + 34 * (n - 8));
end;
53: for n := 1 to 5 do begin
SetColorEntry(0, n, n + 10);
SetColorEntry(0, n + 5, (n + 10) * 16);
SetColorEntry(0, n + 10, (n + 10) * 256);
end;
54: for n := 0 to 4 do begin
SetColorEntry(0, n + 1, (15 - n * 3) * 16 + n * 3);
SetColorEntry(0, n + 6, (n * 3) * 256 + 15 - n * 3);
SetColorEntry(0, n + 11, (15 - n * 3) * 256 + (n * 3) * 16);
end;
55: for n := 0 to 4 do begin
SetColorEntry(0, n + 1, 4095 - (15 - n * 3) * 16 - n * 3);
SetColorEntry(0, n + 6, 4095 - (n * 3) * 256 - (15 - n * 3));
SetColorEntry(0, n + 11, 4095 - (15 - n * 3) * 256 - (n * 3) * 16);
end;
56: for n := 0 to 4 do begin
SetColorEntry(0, n * 3 + 1, 3840);
SetColorEntry(0, n * 3 + 2, 240);
SetColorEntry(0, n * 3 + 3, 15);
end;
57: for n := 0 to 2 do begin
SetColorEntry(0, n * 5 + 1, 2176 + (n + 1) * 544);
SetColorEntry(0, n * 5 + 2, 2056 + (n + 1) * 514);
SetColorEntry(0, n * 5 + 3, 136 + (n + 1) * 34);
SetColorEntry(0, n * 5 + 4, 128 + (n + 1) * 32);
SetColorEntry(0, n * 5 + 5, 8 + (n + 1) * 2);
end;
127: if graphOn then begin
GrafOff;
graphOn := false;
end
else begin
GrafOn;
graphOn := true;
end;
end;
end;
MouseDownEvt: begin
GetMouse(loc);
if (loc.v > 96) and (loc.v < 103) then loc.v := 99;
SetRect(box, (loc.h - 32), (loc.v - 20), (loc.h + 32), (loc.v + 20));
InvertRect(box);
while true do
if GetNextEvent(EveryEvent, event) then
case event.what of
MouseDownEvt: begin
ClearScreen(Black);
nextIteration := iteration * 2;
if nextIteration > 1000 then nextIteration := 1000;
Paint(rStart + (loc.h - 32) * increment,
iStart - (loc.v - 20) * increment,
increment / 5, nextIteration, (loc.v = 99) and mirror);
end;
KeyDownEvt: begin
InvertRect(box);
Leave;
end;
end;
end;
end;
end;
begin
Graphics(320);
ClearScreen(Black);
SetPenSize(1, 1);
graphOn := true;
cursorOn := true;
mode := repeatMode;
for n := 1 to 15 do
SetColorEntry(0, n, 15 * n);
MoveTo(0, 10);
Writeln(' Mandelbrot GS v1.1 ');
SetForeColor(1);
SetBackColor(Black);
MoveTo(185, 10);
Writeln('By Lim Thye Chean');
SetForeColor(13);
MoveTo(0, 25);
Writeln(' <Space>: Return to first level');
Writeln(' <Delete>: Hide/Show screen');
Writeln(' <Return>: Hide/Show cursor');
Writeln(' <Tab>: Colour cycle');
Writeln(' 0-9: Select speed');
Writeln(' <Tab>: Toggle direction');
Writeln(' Other keys to continue');
Writeln(' <Esc>: Quit the program');
Writeln(' 0-9: Change colour palette');
Writeln(' 4 Arrow keys: Select colour mode');
Writeln(' (favorite: Beauty)');
Writeln;
Writeln(' To select an area, click on it.');
Writeln(' Click again to zoom');
Writeln(' Other keys to continue');
SetForeColor(15);
MoveTo(0, 180);
Writeln(' Arrows: Colour mode is Default');
Writeln(' <Esc>: Quit, <Space> to start...');
while true do
if GetNextEvent(EveryEvent, event) then
case event.what of
KeyDownEvt: begin
key := event.message;
case key of
8: begin
mode := defaultMode;
MoveTo(0, 180);
Writeln(' Arrows: Colour mode is Default');
end;
10: begin
mode := rangeMode;
MoveTo(0, 180);
Writeln(' Arrows: Colour mode is Range ');
end;
11: begin
mode := beautyMode;
MoveTo(0, 180);
Writeln(' Arrows: Colour mode is Beauty ');
end;
21: begin
mode := repeatMode;
MoveTo(0, 180);
Writeln(' Arrows: Colour mode is Repeat ');
end;
27: Halt;
32: begin
ClearScreen(Black);
Paint(-2.6, 1.2, 0.012, 30, true);
end;
end;
end;
end;
end.
Mandelbrot GS is one of the best Apple IIGS fractal program written in Complete Pascal. It is released in 1992.
I have also released a much better and faster fractal program called Mandelbrot II GS in 1993, which has a lot of cool features like preview zooming and 640 mode support. You can download it here.