News:

Printed Amstrad Addict magazine announced, check it out here!

Main Menu
avatar_AMSDOS

Rough Mandelbrot

Started by AMSDOS, 07:06, 15 August 10

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

AMSDOS

As discussed in other programming threads, I've made a Rough cut version of a Mandelbrot to almost working stage on the CPC:


The Headaches:

* early versions of this program was clearly overwriting itself on the Y-Axis - Solution: Subtract Ypos by one once Xpos had made the end of the line, so it doesn't appear to be overwriting itself now.

* Haven't really picked up on this if this is happening on the X-Axis! Because I'm using MODE 1 every neighbouring pixel is every second step (just like the Y-Axis) therefore it's like 0,2,4,6,8,10. My program using Horrible Nesting FOR Statements and everything is incremented by 1 (no steps allowed in TP FORs, if they do exist, they aren't well documented!) I setup the programs Width and Height to 640x400 which appears to have returned a valid image!  :-\

* As mentioned earlier the program uses Nested FOR loops, need to find some examples of Nested Repeat Until loops - I prefer these in TP because I can increment everything by what I want and it would work out more effectively on a CPC given it's way to map out pixels across the screen. Resolving this would help stop the program when it's done.

* Resulting program is horribly slow on a CPC in realtime!  ???  Would run faster once colour values are calculated and stored into an constant array! Program should work faster once less plotting is done too.
* Using the old Amstrad Languages :D   * with the Firmware :P
* I also like to problem solve code in BASIC :)   * And type-in Type-Ins! :D

Home Computing Weekly Programs
Popular Computing Weekly Programs
Your Computer Programs
Updated Other Program Links on Profile Page (Update April 16/15 phew!)
Programs for Turbo Pascal 3

AMSDOS

Some major refinements and this Mandelbrot seems to be looking a bit better:
   
* I've scrapped the Nested FOR and have used a Nested REPEAT...UNTIL statement instead. As a result I can calculate every 2 pixel point for MODE 1 and the program finished on time!  ;D

* Program will still run slow at Realtime, I ran it with Realtime off and it still takes a few minutes (5 or 6 minutes!).

At the moment the program is still calculating itself (which accounts for the delay), I've made very little change to the original function apart from replacing some obvious TP5.5 code, other less important features of the program were also removed or were replaced with Amstrad equivalents resulting in the following program:


{
For all of you who are interested on fractals, here is a little program,
taken from a source code in Modula-2, that will draw a Mandelbrot fractal.
Just one problem: If your computer doesn't have a math coprocessor, the
program will run "a bit" slow.
Try modifying all the constants, you'll get strange results.}
{$U+} { Supposed to be used for Breaking During Programs }
Program Mandelbrot;     {Using real numbers. For TP 6.0 and above }

Const Colours=15;       {Number of colors to be on the image.     }
      Width=640;        {Width of the image.                      }
      Height=400;       {Height of the image.                     }
      Limit=8.0;        {Until when we calculate.                 }
      XRMin=-2.0;       {Left limit of the fractal.               }
      XRMax=1.0;        {Right limit of the fractal.              }
      YRMin=-1.3;       {Lower limit of the fractal.              }
      YRMax=1.3;        {Upper limit of the fractal.              }
Var XPos,YPos:Integer;
Procedure mode(mo:byte);
begin
   Inline($3A/mo/
          $CD/$9B/$BE/
          $0E/$BC);
end;
Procedure grapen(col:byte);
begin
   Inline($3A/col/
          $CD/$9B/$BE/
          $DE/$BB);
end;
Procedure Plot(Xpos, Ypos : integer);
begin
   Inline($2A/ypos/
          $ED/$5B/xpos/
          $CD/$9B/$BE/
          $EA/$BB);
end;


{ Calculates the color for each point. }
Function ComputeColour(XPos,YPos:Integer):Byte;
Var RealP,ImagP:Real;
    CurrX,CurrY:Real;
    a2,b2:Real;
    Counter:Byte;
Begin
CurrX:=XPos/Width*(XRMax-XRMin)+XRMin;
  CurrY:=YPos/Height*(YRMax-YRMin)+YRMin;
  RealP:=0;
  ImagP:=0;
  Counter:=0;
  Repeat
    a2:=Sqr(RealP);
    b2:=Sqr(ImagP);
    ImagP:=2*RealP*ImagP+CurrY;
    RealP:=a2-b2+CurrX;
    counter:=succ(counter);
  Until (Counter>=Colours) or (a2+b2>=Limit);
  ComputeColour:=Counter-1;
End;
var xpos2, ypos2 : integer;
Begin
  mode(1);
   ypos2:=height;
   xpos2:=0;
   repeat
    begin
     xpos2:=0;
     repeat
      begin
       grapen(ComputeColour(Xpos2,Ypos2));
       plot(Xpos2, Ypos2);
       xpos2:=xpos2+2;
      end;
     until (xpos2=width);
    ypos2:=ypos2-2;
    end;
   until (ypos2=0);
  repeat until keypressed;
  mode(2);
End.
* Using the old Amstrad Languages :D   * with the Firmware :P
* I also like to problem solve code in BASIC :)   * And type-in Type-Ins! :D

Home Computing Weekly Programs
Popular Computing Weekly Programs
Your Computer Programs
Updated Other Program Links on Profile Page (Update April 16/15 phew!)
Programs for Turbo Pascal 3

robcfg

Quote* Program will still run slow at Realtime, I ran it with Realtime off and it still takes a few minutes (5 or 6 minutes!).


Well, I remember a type-in from the Amstrad User magazine that generated pretty nice mandelbrot sets (all machine code, you know, endless DATA lines XD) but still took 6 hours per image.


I used to go to school and tell my mother not to stop the computer, hehehe


So, nice work!

Devilmarkus

#3
Thats a cool routine.

I know, I am cheating here, but I implemented a Mandelbrot application into JavaCPC Desktop, which generates the same in ~1 second.


It works in MODE 1 and MODE 0.
When you put your ear on a hot stove, you can smell how stupid you are ...

Amstrad CPC games in your webbrowser

JavaCPC Desktop Full Release

AMSDOS

Yeah I'm not sure how to get it in under 1 second (unless it's a screen dump!  ;D ), nice choice of colours though.

Calculations seems to be the thing with Mandelbrots, storing it into an array would ultimately speed it up, though at the size it is at the moment (320x200) that's gonna be 64k! Course I could reduce it by half if I use Mode 0. Originally I had this thing on a PC displaying a 80x50 Mandelbrot, unfortunately I cannot remember how to incorporate the whole thing in 80x50, something to do with those limit values under the width, height & colour values or maybe it's the limit which needs to be adjusted to a quarter of 8.
* Using the old Amstrad Languages :D   * with the Firmware :P
* I also like to problem solve code in BASIC :)   * And type-in Type-Ins! :D

Home Computing Weekly Programs
Popular Computing Weekly Programs
Your Computer Programs
Updated Other Program Links on Profile Page (Update April 16/15 phew!)
Programs for Turbo Pascal 3

Devilmarkus

#5
Maybe this helps you. (It's my Java-source incl. some PC-palette effects and smooth effects etc...)
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package jemu.ui;

/**
* Title:        JavaCPC
* Description:  The Java Amstrad CPC Emulator
* Copyright:    Copyright (c) 2006-2010
* Company:
* @author
* @version 6.8
*/
import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;

public final class Mandel3 extends Applet
        implements MouseListener, MouseMotionListener, KeyListener {

    public boolean toCPC = false;
    private int maxCount = 192;
    private boolean smooth = true;
    public boolean antialias = false;
    private boolean drag = false;
    private boolean toDrag = false;
    private boolean rect = true, oldRect = true;
    private Color[][] colors;
    private int pal = 0;
    private double viewX = 0.0;
    private double viewY = 0.0;
    private double zoom = 1.0;
    private int mouseX, mouseY;
    private int dragX, dragY, oldX, oldY;
    private static final int[][][] colpal = {
        {{0, 10, 20}, {50, 100, 240}, {20, 3, 26}, {230, 60, 20},
            {25, 10, 9}, {230, 170, 0}, {20, 40, 10}, {0, 100, 0},
            {5, 10, 10}, {210, 70, 30}, {90, 0, 50}, {180, 90, 120},
            {0, 20, 40}, {30, 70, 200}},
        {{70, 0, 20}, {100, 0, 100}, {255, 0, 0}, {255, 200, 0}},
        {{40, 70, 10}, {40, 170, 10}, {100, 255, 70}, {255, 255, 255}},
        {{0, 0, 0}, {0, 0, 255}, {0, 255, 255}, {255, 255, 255}, {0, 128, 255}},
        {{0, 0, 0}, {255, 255, 255}, {128, 128, 128}},};

    public void init() {
        addMouseListener(this);
        addMouseMotionListener(this);
        addKeyListener(this);
        // initialize color palettes
        colors = new Color[colpal.length][];
        for (int p = 0; p < colpal.length; p++) {
            colors[p] = new Color[colpal[p].length * 12];
            for (int i = 0; i < colpal[p].length; i++) {
                int[] c1 = colpal[p][i];
                int[] c2 = colpal[p][(i + 1) % colpal[p].length];
                for (int j = 0; j < 12; j++) {
                    colors[p][i * 12 + j] = new Color(
                            (c1[0] * (11 - j) + c2[0] * j) / 11,
                            (c1[1] * (11 - j) + c2[1] * j) / 11,
                            (c1[2] * (11 - j) + c2[2] * j) / 11);
                }
            }
        }
        pal = (pal + 1) % colors.length;
        pal = (pal + 1) % colors.length;
        pal = (pal + 1) % colors.length;
        pal = (pal + 1) % colors.length;
        Switches.getfromautotype = 1;
        Autotype.autotext = mode0;
    }
    String mode0 = "10 MODE 0\n"
            + "20 FOR t=0 TO 15:READ a:INK t,a:NEXT\n"
            + "30 DATA 0,1,2,11,23,21,18,9,12,24,25,16,15,6,3,4\n"
            + "40 GOTO 40\n"
            + "run\n";
    String flip = "10 MODE 0\n"
            + "20 INK 0,0\n"
            + "30 INK 1,1,0\n"
            + "40 INK 2,1\n"
            + "50 INK 3,1,2\n"
            + "60 INK 4,2\n"
            + "70 INK 5,2,11\n"
            + "80 INK 6,11\n"
            + "90 INK 7,11,14\n"
            + "100 INK 8,14\n"
            + "110 INK 9,14,20\n"
            + "120 INK 10,20\n"
            + "130 INK 11,20,23\n"
            + "140 INK 12,23\n"
            + "150 INK 13,23,26\n"
            + "160 INK 14,26\n"
            + "170 INK 15,26\n"
            + "180 SPEED INK 1,1\n"
            + "190 GOTO 190\n"
            + "run\n";
    // To prevent background clearing for each paint()

    public void update(Graphics g) {
        paint(g);
    }

    public void paint(Graphics g) {
        Dimension size = getSize();
        // select-rectangle or offset-line drawing
        if (drag) {
            g.setColor(Color.black);
            g.setXORMode(Color.white);
            if (oldRect) {
                int x = Math.min(mouseX, oldX);
                int y = Math.min(mouseY, oldY);
                int w = Math.max(mouseX, oldX) - x;
                int h = Math.max(mouseY, oldY) - y;
                double r = Math.max((double) w / size.width, (double) h / size.height);
                g.drawRect(x, y, (int) (size.width * r), (int) (size.height * r));
            } else {
                g.drawLine(mouseX, mouseY, oldX, oldY);
            }
            if (rect) {
                int x = Math.min(mouseX, dragX);
                int y = Math.min(mouseY, dragY);
                int w = Math.max(mouseX, dragX) - x;
                int h = Math.max(mouseY, dragY) - y;
                double r = Math.max((double) w / size.width, (double) h / size.height);
                g.drawRect(x, y, (int) (size.width * r), (int) (size.height * r));
            } else {
                g.drawLine(mouseX, mouseY, dragX, dragY);
            }
            oldX = dragX;
            oldY = dragY;
            oldRect = rect;
            drag = false;
            return;
        }
        // fractal image drawing
        for (int y = 0; y < size.height; y++) {
            for (int x = 0; x < size.width; x++) {
                double r = zoom / Math.min(size.width, size.height);
                double dx = 2.5 * (x * r + viewX) - 2;
                double dy = 1.25 - 2.5 * (y * r + viewY);
                Color color = color(dx, dy);
                // computation of average color for antialiasing
                if (antialias) {
                    Color c1 = color(dx, dy + 0.5 * r);
                    Color c2 = color(dx + 0.5 * r, dy);
                    Color c3 = color(dx + 0.5 * r, dy + 0.5 * r);
                    int red = (color.getRed() + c1.getRed() + c2.getRed() + c3.getRed()) / 4;
                    int green = (color.getGreen() + c1.getGreen() + c2.getGreen() + c3.getGreen()) / 4;
                    int blue = (color.getBlue() + c1.getBlue() + c2.getBlue() + c3.getBlue()) / 4;
                    color = new Color(red, green, blue);
                }
                g.setColor(color);
                g.drawLine(x, y, x, y); // draws point
                int mode = jemu.system.cpc.GateArray.getSMode();
                int cpcX = x;
                if (mode == 0) {
                    cpcX /= 2;
                }
                if (mode == 2) {
                    cpcX *= 2;
                }
                int pen = color.getRed() + color.getGreen() + color.getBlue();
                pen /= 51;
                if (mode == 1) {
                    pen = (int) (pen /= (double) 3.75);
                }
                if (mode == 2) {
                    pen = (int) (pen /= (double) 7.5);
                }
                if (toCPC) {
                    jemu.system.cpc.CPC.PLOT(cpcX, y, pen, mode, false);
                    if (mode == 2) {
                        jemu.system.cpc.CPC.PLOT(cpcX + 1, y, pen, mode, false);
                    }
                }
            }
        }
        toCPC = false;
    }

    // Computes a color for a given point
    private Color color(double x, double y) {
        int count = mandel(0.0, 0.0, x, y);
        int palSize = colors[pal].length;
        Color color = colors[pal][count / 256 % palSize];
        if (smooth) {
            Color color2 = colors[pal][(count / 256 + palSize - 1) % palSize];
            int k1 = count % 256;
            int k2 = 255 - k1;
            int red = (k1 * color.getRed() + k2 * color2.getRed()) / 255;
            int green = (k1 * color.getGreen() + k2 * color2.getGreen()) / 255;
            int blue = (k1 * color.getBlue() + k2 * color2.getBlue()) / 255;
            color = new Color(red, green, blue);
        }
        return color;
    }

    // Computes a value for a given complex number
    private int mandel(double zRe, double zIm, double pRe, double pIm) {
        double zRe2 = zRe * zRe;
        double zIm2 = zIm * zIm;
        double zM2 = 0.0;
        int count = 0;
        while (zRe2 + zIm2 < 4.0 && count < maxCount) {
            zM2 = zRe2 + zIm2;
            zIm = 2.0 * zRe * zIm + pIm;
            zRe = zRe2 - zIm2 + pRe;
            zRe2 = zRe * zRe;
            zIm2 = zIm * zIm;
            count++;
        }
        if (count == 0 || count == maxCount) {
            return 0;
        }
        // transition smoothing
        zM2 += 0.000000001;
        return 256 * count + (int) (255.0 * Math.log(4 / zM2) / Math.log((zRe2 + zIm2) / zM2));
    }

    // methods from MouseListener interface
    public void mousePressed(MouseEvent e) {
        mouseX = dragX = oldX = e.getX();
        mouseY = dragY = oldY = e.getY();
        toDrag = true;
    }

    public void mouseReleased(MouseEvent e) {
        int x = e.getX();
        int y = e.getY();
        if ((e.getModifiers() & InputEvent.BUTTON1_MASK) != 0) {
            if ((e.getModifiers() & InputEvent.SHIFT_MASK) != 0) { // moved
                int width = getSize().width;
                int height = getSize().height;
                viewX += zoom * (mouseX - x) / Math.min(width, height);
                viewY += zoom * (mouseY - y) / Math.min(width, height);
                repaint();
            } else if (x != mouseX && y != mouseY) { // zoomed
                int width = getSize().width;
                int height = getSize().height;
                int mx = Math.min(x, mouseX);
                int my = Math.min(y, mouseY);
                viewX += zoom * mx / Math.min(width, height);
                viewY += zoom * my / Math.min(width, height);
                int w = Math.max(x, mouseX) - mx;
                int h = Math.max(y, mouseY) - my;
                double r = Math.max((double) w / width, (double) h / height);
                zoom *= r;
                drag = false;
                repaint();
            }
        } else if ((e.getModifiers() & InputEvent.BUTTON3_MASK) != 0) {
            addIter();
        }
        toDrag = false;
    }

    public void zoomOut() {
        viewX -= 0.5 * zoom;
        viewY -= 0.5 * zoom;
        zoom *= 2.0;
        repaint();
    }

    public void addIter() {
        maxCount += maxCount / 4;
        repaint();
    }

    public void subIter() {
        maxCount -= maxCount / 4;
        if (maxCount <= 4) {
            maxCount = 4;
        }
        repaint();
    }

    public void mouseClicked(MouseEvent e) {
    }

    public void mouseEntered(MouseEvent e) {
    }

    public void mouseExited(MouseEvent e) {
    }

    // methods from MouseMotionListener interface
    public void mouseDragged(MouseEvent e) {
        if ((e.getModifiers() & InputEvent.BUTTON1_MASK) != 0) {
            dragX = e.getX();
            dragY = e.getY();
            drag = true;
            repaint();
        }
    }

    public void mouseMoved(MouseEvent e) {
    }

    // methods from KeyListener interface
    public void reset() {
        maxCount = 192;
        viewX = viewY = 0.0;
        zoom = 1.0;
        repaint();
    }

    public void keyPressed(KeyEvent e) {
        if (e.getKeyCode() == KeyEvent.VK_ESCAPE) { // init
            reset();
        } else if (e.getKeyCode() == KeyEvent.VK_O) { // zoom out
            zoomOut();
        } else if (e.getKeyCode() == KeyEvent.VK_P) { // next palette
            pal = (pal + 1) % colors.length;
            repaint();
        } else if (e.getKeyCode() == KeyEvent.VK_S) { // smoothing
            smooth = !smooth;
            repaint();
        } else if (e.getKeyCode() == KeyEvent.VK_A) { // antialiasing
            antialias = !antialias;
            repaint();
        } else if (e.getKeyCode() == KeyEvent.VK_SHIFT) { // move/zoom mode
            if (rect == true) {
                oldRect = true;
                rect = false;
                if (toDrag) {
                    drag = true;
                    repaint();
                }
            }
        }
    }

    public void toCPC() {
        toCPC = true;
        repaint();
    }

    public void keyReleased(KeyEvent e) {
        if (e.getKeyCode() == KeyEvent.VK_SHIFT) { // move/zoom mode
            if (rect == false) {
                oldRect = false;
                rect = true;
                if (toDrag) {
                    drag = true;
                    repaint();
                }
            }
        }
    }

    public void keyTyped(KeyEvent e) {
    }

    public static void main(String[] args) {
        Frame applet = new Frame("Mandelbrot");
        Mandel3 mandel = new Mandel3();
        applet.add(mandel);
        applet.setSize(320, 200);
        applet.setVisible(true);
        mandel.init();

    }
}


BTW.: This is how it looks on a flipped screen (Using SPEED INK 1,1 and 2 colour values for some INKs)
(Deinterlaced!)
When you put your ear on a hot stove, you can smell how stupid you are ...

Amstrad CPC games in your webbrowser

JavaCPC Desktop Full Release

AMSDOS

Devilmarkus wrote:

Maybe this helps you. (It's my Java-source incl. some PC-palette effects and smooth effects ets)

Looks quite impressive, unfortunately I'm not very good at Java! :(

Should be able to find something in the amount of Pascal stuff I've got to be able to make a Data file with all the calculated information in it.
Test trialed my program at 80 Width x 50 Height which worked, don't know what I was doing in the other program the other day, but it was only drawing a fragment of the Mandelbrot! Unfortunately 80 x 50 is too small to look at!  ???  Perhaps either Mode 0 resolution or Mode 1 at half size will do in making a Data file!

BTW.: This is how it looks on a flipped screen (Using SPEED INK 1,1 and 2 colour values for some INKs)
(Deinterlaced!)


Still looks just as good!  :)

* Using the old Amstrad Languages :D   * with the Firmware :P
* I also like to problem solve code in BASIC :)   * And type-in Type-Ins! :D

Home Computing Weekly Programs
Popular Computing Weekly Programs
Your Computer Programs
Updated Other Program Links on Profile Page (Update April 16/15 phew!)
Programs for Turbo Pascal 3

AMSDOS

Dam I hate it when I right!!  :-[  For some reason I thought I could get away from 16k of information, but it's not it's 64k of information!! 16k or 16384 to be exact is 16384 colour points, this in theory should equate to 81.92 Lines of good stuff before disaster strikes which is what's happening. I've got a routine in one my AA which produces a Spectrum screen, anyone know the Resolution of a Spectrum screen by any chance?
* Using the old Amstrad Languages :D   * with the Firmware :P
* I also like to problem solve code in BASIC :)   * And type-in Type-Ins! :D

Home Computing Weekly Programs
Popular Computing Weekly Programs
Your Computer Programs
Updated Other Program Links on Profile Page (Update April 16/15 phew!)
Programs for Turbo Pascal 3

arnoldemu

Quote from: CP/M User on 10:10, 17 August 10
Dam I hate it when I right!!  :-[  For some reason I thought I could get away from 16k of information, but it's not it's 64k of information!! 16k or 16384 to be exact is 16384 colour points, this in theory should equate to 81.92 Lines of good stuff before disaster strikes which is what's happening. I've got a routine in one my AA which produces a Spectrum screen, anyone know the Resolution of a Spectrum screen by any chance?
256x192
equivalent to mode 1 sized pixels.
My games. My Games
My website with coding examples: Unofficial Amstrad WWW Resource

AMSDOS

#9
Oh dear, that's still acculates to 49152 points to plot. Would have to make this thing a multiload in order to make this thing work.

I've got it!! 50 Lines equates to exactly 16Kbs of Colour Data! So 4 files will do the job (almost temped to load the whole lot into the second 64k - though it seems like extra trouble to make that work). But to do it in 16Kb clumps I would have to:

* load the first data
* draw that in - 200 to 150
* load the second data
* draw in the following lines - 149 to 99
* load the third data
* draw the next lines - 98 to 48
* load the last set of data
* draw those lines in - this is where it gets tricky because there's less than 50.

Gone wrong somewhere cause 4 files at 16Kb each is 200 Lines of Colour Information. Loading the files is one procedure, drawing them is another. Obviously though each one is loaded goes into the same array (16Kb in Size), a couple of other variables to tell the Drawing procedure where it's upto should make it possible.

And the other good aspect I forgot to mention was using Arrays to store the information rather than calculating it has indeed made the program draw out faster!  ;D
* Using the old Amstrad Languages :D   * with the Firmware :P
* I also like to problem solve code in BASIC :)   * And type-in Type-Ins! :D

Home Computing Weekly Programs
Popular Computing Weekly Programs
Your Computer Programs
Updated Other Program Links on Profile Page (Update April 16/15 phew!)
Programs for Turbo Pascal 3

AMSDOS

Of course what I think is going on now is because everything is incremented twice, the array is half it's size and now it's drawing the first half of my 16k Array file and returning zeros for the rest or if something is in memory - saving that instead cause it's not written to. Have to increment everything by 1 again I think!  :o
* Using the old Amstrad Languages :D   * with the Firmware :P
* I also like to problem solve code in BASIC :)   * And type-in Type-Ins! :D

Home Computing Weekly Programs
Popular Computing Weekly Programs
Your Computer Programs
Updated Other Program Links on Profile Page (Update April 16/15 phew!)
Programs for Turbo Pascal 3

AMSDOS

Aaaugh!  ???  I was right the first time and doing everything right, except was only dumping half the screen to the array instead of doing the complete bit, so confusing because it's not pixel for pixel resolution in Mode 1!
* Using the old Amstrad Languages :D   * with the Firmware :P
* I also like to problem solve code in BASIC :)   * And type-in Type-Ins! :D

Home Computing Weekly Programs
Popular Computing Weekly Programs
Your Computer Programs
Updated Other Program Links on Profile Page (Update April 16/15 phew!)
Programs for Turbo Pascal 3

norecess

This is wonderful. I would love such routine (an infinite zoom) nicely packed in a lovely small prod... even if it's slow.

AMSDOS

norecess wrote:

This is wonderful. I would love such routine (an infinite zoom) nicely packed in a lovely small prod... even if it's slow.

You mean like in a big software box with 3" disc inside and manual with a heafty price tag on the front?  :-[  No well, it's got to be free!  :)  I should perhaps justifiably go back to the program I posted in the second responce and throw in a Colour Routine - only problem there is I'd like some Inks which will work, the set post in the image posted looks like the standard BASIC colours which is fine. The ones used in Markus' example are great but it's in 16 and mine is only 4, the blue one of his maybe easier just have to remove some of the Blues and work in what's used around my Mandelbrot. CP/M v2.2 offers the worst unfortunately, though I'm not a fan of it! :(
* Using the old Amstrad Languages :D   * with the Firmware :P
* I also like to problem solve code in BASIC :)   * And type-in Type-Ins! :D

Home Computing Weekly Programs
Popular Computing Weekly Programs
Your Computer Programs
Updated Other Program Links on Profile Page (Update April 16/15 phew!)
Programs for Turbo Pascal 3

AMSDOS

#14
Well I've been successful in generating a Fast Mandelbrot in CP/M v2.2 on a CPC.

Screenshot:



Source:

{
For all of you who are interested on fractals, here is a little program,
taken from a source code in Modula-2, that will draw a Mandelbrot fractal.
Just one problem: If your computer doesn't have a math coprocessor, the
program will run "a bit" slow.
Try modifying all the constants, you'll get strange results.}
{$U+} { Supposed to be used for Breaking During Programs }

Program Mandelbrot;     {Using real numbers. For TP 6.0 and above }
Type Filestr = String[14];
Const Colours=15;       {Number of colors to be on the image.     }
      Width=640;        {Width of the image.                      }
      Height=400;       {Height of the image.                     }
      Limit=8.0;        {Until when we calculate.                 }
      XRMin=-2.0;       {Left limit of the fractal.               }
      XRMax=1.0;        {Right limit of the fractal.              }
      YRMin=-1.3;       {Lower limit of the fractal.              }
      YRMax=1.3;        {Upper limit of the fractal.              }
      Bufsize = 128;
Var XPos,YPos:Integer;
    Coldata : array[0..16000] of byte absolute $4000;
Procedure Load(filename:Filestr);
var recsread : integer;
     source : file;
begin
  assign(source,filename);
  reset(source);
  repeat
   blockread(source,Coldata,bufsize,recsread);
  until recsread=0;
  close(source);
end;
Procedure mode(mo:byte);
begin
   Inline($3A/mo/
          $CD/$9B/$BE/
          $0E/$BC);
end;
Procedure grapen(col:byte);
begin
   Inline($3A/col/
          $CD/$9B/$BE/
          $DE/$BB);
end;
Procedure Plot(Xpos, Ypos : integer);
begin
   Inline($2A/ypos/
          $ED/$5B/xpos/
          $CD/$9B/$BE/
          $EA/$BB);
end;
Procedure drawblt(xpos2, ypos2, count, hlt : integer);
begin
repeat
  begin
   xpos2:=0;
   repeat
    begin
     grapen(Coldata[count]);
     plot(Xpos2, Ypos2);
     xpos2:=xpos2+2;
     count:=succ(count);
    end;
   until (xpos2=width);
  ypos2:=ypos2-2;
  end;
until (ypos2=hlt);
end;
Begin
  mode(1);
   load('mandel1.dat');
   drawblt(0,398,0,298);
   load('mandel2.dat');
   drawblt(0,298,0,198);
   load('mandel3.dat');
   drawblt(0,198,0,098);
   load('mandel4.dat');
   drawblt(0,098,0,0);
  repeat until keypressed;
  mode(2);
End.


Features:
   

         
  • 64Kb of Data used to generating the Coloured effect for the Mandelbrot.
  • Program loads this information in 16Kb segments, 4 files are used to represent this.
  • Process achieved is done by loading this data, followed by displaying it, loading the next segment and so on.
  • Program will continue drawing once information is loaded in the position it was in.
  • Time to completion on a CPC running in Real time slightly under 90 secs.
I've attached a ZIP file which contains the files to get the program up and going, I've attached the Data Files too cause my Setup program at the moment is in a bit of a mess. Source code and CP/M ".COM" file is there, it can only be run in CP/M v2.2 due to the specific related commands which relate to that version of CP/M. Only other thing missing from it is a routine to setup some alternative inks for it. For the effect above I had a program revert to BASIC colours in CP/M v2.2 to get that effect.

Other setbacks in the program, I found it's wise to save the program in Turbo Pascal and Compile it as a COM file. Running this particular Program as is in Turbo Pascal Environment could overwrite the source code which Turbo Pascal stores or Turbo Pascal itself ultimately crashing it due to the way the program ultimately uses memory. So it's safer to run it outside of Turbo Pascal!
* Using the old Amstrad Languages :D   * with the Firmware :P
* I also like to problem solve code in BASIC :)   * And type-in Type-Ins! :D

Home Computing Weekly Programs
Popular Computing Weekly Programs
Your Computer Programs
Updated Other Program Links on Profile Page (Update April 16/15 phew!)
Programs for Turbo Pascal 3

Targhan

If you want to see the fastest Mandelbrot fractal on CPC (to my knowledge), check out the 5KB Demo 3 (it's a megademo), there's a part with that. It's pretty fast (yet remains slow for an "effect"). Of course it's in assembly...
Targhan/Arkos

Arkos Tracker 2.0.1 now released! - Follow the news on Twitter!
Disark - A cross-platform Z80 disassembler/source converter
FDC Tool 1.1 - Read Amsdos files without the system

Imperial Mahjong
Orion Prime

AMSDOS

Which part is it on? I notice there's 4 or 5 Disk images to that demo!
* Using the old Amstrad Languages :D   * with the Firmware :P
* I also like to problem solve code in BASIC :)   * And type-in Type-Ins! :D

Home Computing Weekly Programs
Popular Computing Weekly Programs
Your Computer Programs
Updated Other Program Links on Profile Page (Update April 16/15 phew!)
Programs for Turbo Pascal 3

AMSDOS

Woo - I found the right Disk and counted 2:29 Seconds for the 5k Demo 3 Mandelbrot. Still a fine effort for a Mandelbrot given it's got Music and Scrolling Text Under it. My routine only beats it due to information being gathered to it in advance. But technically speaking a setup file is still required to collect that information and in realtime to gather that information is where the time gets chewed up.
The Demo makers could had made it like this possibly I'm not sure though, the advantage in Mode 0 compared to Mode 1, half the colour points are gone so you effectively halved the result which is a Full Mode 1 screen at a Resolution of 320x200 is 64000 Bytes or 64Kb to 160 x 200 which equals 32000 Bytes or 32Kb.
* Using the old Amstrad Languages :D   * with the Firmware :P
* I also like to problem solve code in BASIC :)   * And type-in Type-Ins! :D

Home Computing Weekly Programs
Popular Computing Weekly Programs
Your Computer Programs
Updated Other Program Links on Profile Page (Update April 16/15 phew!)
Programs for Turbo Pascal 3

AMSDOS

#18
Wow by comparing the programs side by side it seems WebCPC favors the 5k Demo 3 Mandelbrot - taking a good 9 minutes to complete the Pascal version.  Unsure what happened earlier in the Emulator I was using for it to complete it in under 90 seconds, was also running in Real Time though which suggests to me it wasn't running as well as it should of!  ???  Nevermind!  ;D

Yep as feared my programming tool of choice was not running in Real Time of executing that program, most annoying!  >:(
* Using the old Amstrad Languages :D   * with the Firmware :P
* I also like to problem solve code in BASIC :)   * And type-in Type-Ins! :D

Home Computing Weekly Programs
Popular Computing Weekly Programs
Your Computer Programs
Updated Other Program Links on Profile Page (Update April 16/15 phew!)
Programs for Turbo Pascal 3

Targhan

I don't know a lot about fractals, but I know there are many mathematical tricks that can be applied in order to gain speed. But anyway, you will never compete with asm code with pascal...
Targhan/Arkos

Arkos Tracker 2.0.1 now released! - Follow the news on Twitter!
Disark - A cross-platform Z80 disassembler/source converter
FDC Tool 1.1 - Read Amsdos files without the system

Imperial Mahjong
Orion Prime

AMSDOS

Targhan wrote:

I don't know a lot about fractals, but I know there are many mathematical tricks that can be applied in order to gain speed. But anyway, you will never compete with asm code with pascal...

Ironically enough some my code is asm, though firmware isn't what you would call competitive with the real stuff!  ;D  In assembly I would do the same again by bypassing the mathematical tricks and draw the thing out with the Information. The downside to it would be plotting it - haven't found an alternative way of plotting to screen apart from using GRA SET PEN (BBDE) to set the Ink Colour and GRA PLOT ABSOLUTE (&BBEA) to draw it. Could probably do it like that to see how well it comes out. Assembly is quickest, though mathematical tricks wouldn't be it's main advantage.
* Using the old Amstrad Languages :D   * with the Firmware :P
* I also like to problem solve code in BASIC :)   * And type-in Type-Ins! :D

Home Computing Weekly Programs
Popular Computing Weekly Programs
Your Computer Programs
Updated Other Program Links on Profile Page (Update April 16/15 phew!)
Programs for Turbo Pascal 3

Gryzor

Quote from: robcfg on 10:04, 15 August 10

Well, I remember a type-in from the Amstrad User magazine that generated pretty nice mandelbrot sets (all machine code, you know, endless DATA lines XD) but still took 6 hours per image.


I used to go to school and tell my mother not to stop the computer, hehehe


So, nice work!

Hahaha - damn, I think I had done this, too... those were the days... :)

That said, look at those CPC colors... I wonder what this looks like on the c64 or the speccy!

AMSDOS

Gryzor wrote:

Hahaha - damn, I think I had done this, too... those were the days... :)

I don't recall the Mandelbrot from ACU which took 6 Hours to Draw, guess it must have took just as long to Typein?  ???  There was the occasional Typein in AA or 10 Liner In ACU though which I recall took a while to achieve their full effect, and I think some simply kept on going!  ???

That said, look at those CPC colors... I wonder what this looks like on the c64 or the speccy!

I've just (since Last Night) updated my Website which includes the Completed Mandelbrot setup file which saves the Colour Data, this is the program people will love to wait around for (unless your like me, you can use an Emulator to Turn off the Realtime!  ;) ), the program which takes those Colour Data Files and Draws the Mandelbrot and another program I added is the Worlds Largest Reset Colour program (I say that cause the resulting COM file includes a 8k Library File!  ;D ).

But speaking of Colours, I thought it would be good to make a Palette Program - something fancy so I can Load & Save Colour Palettes as well as Define them for any screen Mode - it would certainly give more flexibility to Defining Colours in CP/M v2.2.
* Using the old Amstrad Languages :D   * with the Firmware :P
* I also like to problem solve code in BASIC :)   * And type-in Type-Ins! :D

Home Computing Weekly Programs
Popular Computing Weekly Programs
Your Computer Programs
Updated Other Program Links on Profile Page (Update April 16/15 phew!)
Programs for Turbo Pascal 3

Powered by SMFPacks Menu Editor Mod