gfxbrot.c and gfxjulia.c

Using, learning, programming and modding the Gigatron and anything related.
Forum rules
Be nice. No drama.
veekoo
Posts: 86
Joined: 07 Jun 2021, 07:07

Re: gfxbrot.c and gfxjulia.c

Post by veekoo »

I am working with mandelbrot and julia drawing with random dots, but not same dot many times.
Attached files work with 64k and ROM v5a.
Biggest problem of this is still it uses floating point calculation.
Maybe one day I make integer math fractals...
Screenshot from 2022-10-14 16-54-25.png
Screenshot from 2022-10-14 16-54-25.png (171.03 KiB) Viewed 393 times
Attachments
rndbrot.gt1
(3.82 KiB) Downloaded 7 times
rndjulia.gt1
(3.8 KiB) Downloaded 7 times
Last edited by veekoo on 14 Oct 2022, 17:24, edited 1 time in total.
veekoo
Posts: 86
Joined: 07 Jun 2021, 07:07

Re: gfxbrot.c and gfxjulia.c

Post by veekoo »

Maybe someone who knows integer fractals can adapt my code.
Codes can be found at:
https://github.com/veekooFIN/GigatronTTL-Fractals
lb3361
Posts: 235
Joined: 17 Feb 2021, 23:07

Re: gfxbrot.c and gfxjulia.c

Post by lb3361 »

veekoo wrote: 31 Jan 2022, 12:23 Maybe one day I make integer math fractals...
I do not have time to do it but the attached code might help you.

This code represents fractional numbers -16<x<16 as the integer 256*x. One can add or subtract such number using the normal integer addition or subtraction. A small vcpu routine, mul48, multiplies two such numbers. It only works when both its arguments and its result are strictly between -16 and +16, otherwise it silently returns erroneous results. This is just enough to implement Mandelbrot at the normal scale.
Attachments
fix48.zip
(2.25 KiB) Downloaded 9 times
veekoo
Posts: 86
Joined: 07 Jun 2021, 07:07

Re: gfxbrot.c and gfxjulia.c

Post by veekoo »

This guy from https://github.com/rahra/intfract had done good job documenting and given sources for integer fractals.

I tried this way to do it. Small scale tesing doesn't show great speed improvement.

Code: Select all

//*----------------------------------------------------------------------+
 |                                                                      |
 |     longbrot.c -- demonstrate fractal in gfx / quick and dirty        |
 |                                                                      |
 +----------------------------------------------------------------------*/
 
// Standard includes
#include <limits.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include <math.h>
#include <gigatron/console.h>
#include <gigatron/sys.h>

#define WIDTH 40
#define HEIGHT 30
#define NORM_BITS 13
#define F 8192

int mandelbrot(long real0, long imag0) {
  long realq, imagq; 
  long real, imag;
  int i;

  real = real0;
  imag = imag0;
  for (i = 0; i < 15; i++)
  {
    realq = (real * real) >> NORM_BITS;
    imagq = (imag * imag) >> NORM_BITS;

    if ((realq + imagq) > 32768) break;

    imag = ((real * imag) >> (NORM_BITS - 1)) + imag0;
    real = realq - imagq + real0;
  }
  return i;
}

void drawPixel(int x, int y, int color)
{
  screenMemory[y][x] = color;
}

void main(void) {
  int x, y, data;
  int col[16];
  long realmin, imagmin, realmax, imagmax;
  long deltareal, deltaimag, real0, imag0;  
  
  col[0] = 0x01;
  col[1] = 0x02;
  col[2] = 0x03;
  col[3] = 0x07;
  col[4] = 0x0b;
  col[5] = 0x0f;
  col[6] = 0x0e;
  col[7] = 0x0d;
  col[8] = 0x0c;
  col[9] = 0x3c;
  col[10] = 0x38;
  col[11] = 0x34;
  col[12] = 0x30;
  col[13] = 0x20;
  col[14] = 0x10;
  col[15] = 0x00;
  
  realmin = (long) ((-2.0) * (float) F);
  realmax = (long) ((0.7) * (float) F);
  imagmin = (long) ((-1.2) * (float) F);
  imagmax = (long) ((1.2) * (float) F); 
   
  for(y = 0; y < HEIGHT; y++ ) {
    for(x = 0; x < WIDTH; x++ ) {
      drawPixel(x,y,col[15]);
    }
  } 
  
  deltareal = (realmax - realmin) / (long) WIDTH;
  deltaimag = (imagmax - imagmin) / (long) HEIGHT;

  real0 = realmin; 
  for(x = 0; x < WIDTH; x++ ) {
    imag0 = imagmax;
    for(y = 0; y < HEIGHT; y++ ) {
      data = mandelbrot(real0, imag0);
      drawPixel(x,y,col[data]);
      imag0 -= deltaimag;
    }
    real0 += deltareal;
  }
}
Last edited by veekoo on 16 Oct 2022, 17:00, edited 3 times in total.
veekoo
Posts: 86
Joined: 07 Jun 2021, 07:07

Re: gfxbrot.c and gfxjulia.c

Post by veekoo »

Example picture of this code using long data type. Getting fast calculation might not happen with this code.

"Types short and int are 16 bits long. Type long is 32 bits long. Types float and double are 40 bits long, using the Microsoft Basic floating point format. Both long arithmetic or floating point arithmetic incur a significant speed penalty."
Attachments
longbrot.png
longbrot.png (9.19 KiB) Viewed 220 times
Last edited by veekoo on 18 Oct 2022, 05:03, edited 1 time in total.
lb3361
Posts: 235
Joined: 17 Feb 2021, 23:07

Re: gfxbrot.c and gfxjulia.c

Post by lb3361 »

I believe this reference on integer fractals was written with a substantially more powerful processor in mind.

As you know, the Gigatron does not have a hardware multiplier. Therefore a 32-bits multiplication must be computed with 32 32-bits additions and shifts. In addition the Gigatron hardware can only perform 8 bit operations. Since it does not provide access to the carry bit, one needs additional logic to determine whether there is a carry and to apply the carry as needed. For 16-bits additions and subtractions, this is implemented quite efficiently in native code. For 32-bits additions and subtractions, this must be done with vCPU instructions.

This means that it pays to make our fractional precision numbers fit inside a 16-bits integer. This is what is achieved by the fractional multiplication from my earlier post. Since it only uses 12 bits of the int variable, one needs only 12 loops in the multiplication routine, another little gain. Anyway this is close to what Marcel did in the original version of the Gigatron Mandelbrot program, and should have a comparable speed.

One can go faster thanks to qwertyface's quarter square multiplication trick. See viewtopic.php?p=2632#p2632 for details. Interestingly this can be achieved with just vCPU code, but only in a manner that is very specific to the Mandelbrot calculation.

PS. My latest version of the GLCC runtime has a 20% speedup on long additions and subtractions. But that only gives 10% on multiplications.
veekoo
Posts: 86
Joined: 07 Jun 2021, 07:07

Re: gfxbrot.c and gfxjulia.c

Post by veekoo »

I think for Gigatron community making another Mandelbrot in integer is not so important. A fast Julia might be intresting. Yes the example was for Amiga or PC. I noticed the update on GLCC and used it in here.

There is now long Mandelbrot and long Julia versions. Its integer math, but not 16-bit int.

These are faster than previous programs. Currently testing at fullscreen.

Gfx mandelbrot uses floating point and takes 2 hours 5 minutes to draw the screen. Long version takes 45 min.

Gfx julia uses floating point and takes 1 hour 50 minutes to draw the screen. Long version takes 35 min.
veekoo
Posts: 86
Joined: 07 Jun 2021, 07:07

Re: gfxbrot.c and gfxjulia.c

Post by veekoo »

In Mandelbrot family there is also Julia, but not many know Burning Ship. Very small modification to Mandelbrot program you get Burning Ship. In some illustrations you can actually see the ship.

Two pictures: 1. Burning Ship zoomed 2. Burning Ship original view
Attachments
burnship_zoomed.png
burnship_zoomed.png (8.25 KiB) Viewed 186 times
Screenshot from 2022-10-18 02-25-08.png
Screenshot from 2022-10-18 02-25-08.png (8.24 KiB) Viewed 206 times
lb3361
Posts: 235
Joined: 17 Feb 2021, 23:07

Re: gfxbrot.c and gfxjulia.c

Post by lb3361 »

veekoo wrote: 17 Oct 2022, 06:51 Gfx mandelbrot uses floating point and takes 2 hours 5 minutes to draw the screen. Long version takes 45 min.
Gfx julia uses floating point and takes 1 hour 50 minutes to draw the screen. Long version takes 35 min.
Not bad!
Post Reply