The graphical functions of Spyro

All the initialization and loop functions are omitted

{these are some common functions used by the procedures}
function RandomColor: RgbColor;
  begin
    RandomColor.red := abs(random mod 256) * 256;
    RandomColor.green := abs(random mod 256) * 256;
    RandomColor.blue := abs(random mod 256) * 256;
  end;

function int (n: real): integer;
  begin
    int := trunc(n) + 1;
  end;

function sgn (n: integer): integer;
  begin
    if n > 0 then
      sgn := -1
    else if n = 0 then
      sgn := 0
    else
      sgn := -1;
  end;

procedure circle (xpos, ypos, radius, color: integer; framed: boolean);
  var
    r: rect;
  begin
    setrect(r, xpos - radius, ypos - radius, xpos + radius, ypos + radius);
    pmforecolor(color);
    if framed then
      frameoval(r)
    else
      paintoval(r);
  end;


{this draws lissajous style curves with squares on the screen using the sin and cosine functions}
procedure scribbler (home: point);
  var
    a, b, i, x1, y1: integer;
    x, y, z: real;
    zbox: rect;
  begin
    SetOrigin(-home.h, -home.v);
    i := 0;
    z := 0.01;
    repeat
      if i mod 300 = 0 then
        begin
          a := abs(random mod 11) + 1;
          b := abs(random mod 13) + 1;
          if a < 5 then
            a := 5;
          if b < 5 then
            b := 5;
          if a = b then
            a := a + 1;
        end;
      x := sin(a * z);
      y := cos(b * z);
      z := z + 0.01;
      pmforecolor(i mod 253);
      x1 := trunc(x * (home.h - 1));
      y1 := trunc(y * (home.v - 1));
      setrect(zbox, x1 - 11, y1 - 11, x1 + 11, y1 + 11);
      paintrect(zbox);
      forecolor(blackcolor);
      framerect(zbox);
      i := i + 1;
    until (i > 5000) or button;
    SetOrigin(0, 0);
  end;

{this creates a 2D random walk on the screen with a twist}
{the plotted points are mirrored along 4 lines, making}
{it symmetrical like a kaleidescope}
procedure kaleidescope (home: point);
  var
    x, y, x1, y1: integer;
    maxtime, i: longint;
  begin
    maxtime := 10000 * (screenbits.bounds.right div 512);
    i := 0;
    x1 := 0;
    y1 := 0;
    x := 0;
    y := 0;
    pensize(3, 3);
    SetOrigin(-home.h, -home.v);
    repeat
      i := i + 1;
      pmForeColor(i mod 253);
      if x1 <= -home.h then
        x := x1 + (abs(random mod 2));
      if x1 >= home.h then
        x := x1 - (abs(random mod 2));
      if (x1 > -home.h) and (x1 < home.h) then
        x := x1 + 2 * (abs(random mod 3) - 1);
      if y1 <= -home.h then
        y := y1 + (abs(random mod 2));
      if y1 >= home.h then
        y := y1 - (abs(random mod 2));
      if (y1 > -home.h) and (y1 < home.h) then
        y := y1 + 2 * (abs(random mod 3) - 1);
      moveto(x1, y1);
      lineto(x, y);
      x1 := x;
      y1 := y;
      moveto(y1, x1);
      lineto(y, x);
      moveto(-y1, x1);
      lineto(-y, x);
      moveto(-x1, y1);
      lineto(-x, y);
      moveto(-x1, -y1);
      lineto(-x, -y);
      moveto(-y1, -x1);
      lineto(-y, -x);
      moveto(y1, -x1);
      lineto(y, -x);
      moveto(x1, -y1);
      lineto(x, -y);
    until (i > maxtime) or button;
    SetOrigin(0, 0);
    pensize(1, 1);
  end;

{Draws a continuously shrinking polygon spiral}
procedure polyspirals (home: point);
  var
    s, a, step, angle: real;
    thePen: point;
    i: integer;
  begin
    repeat
      moveto(home.h, home.v);
      step := abs(random mod 10) / 10 + 0.8;
      angle := abs(random mod 90);
      i := 0;
      s := 0;
      a := 0;
      repeat
        i := i + 1;
        pmforecolor(i);
        s := s + step;
        a := a + angle;
        line(round(s * cos(a * 0.0174533)), -round(s * sin(a * 0.0174533)));
        getpen(thepen);
      until (not PtInRect(thePen, screenbits.bounds)) or (button) or (i = 253);
    until (i > 50) or button;
  end;

{Draws lines that resemble the spirograph toy!}
procedure Spirograph;
  var
    BaseX, BaseY, a, b, ab, ba, Incr1, Incr2, Xa, Ya, Xb, Yb, Vx, Vy, x1, y1, x2, y2: integer;
    col, s1, s2, i: integer;
    t: longint;
  begin
    BaseX := 150;
    BaseY := 256;
    a := 70;
    b := 19;
    ab := 0;
    ba := 5;
    Incr1 := 4;
    Incr2 := -4;
    s1 := 1;
    s2 := -1;
    SetOrigin(-100, 70);
    Xa := 64 * a;
    Ya := 0;
    Xb := 64 * b;
    Yb := 0;
    Vx := 0;
    Vy := 8000;
    i := 0;
    incr1 := incr1 + s1 * abs(random mod 9);
    incr2 := incr2 + s2 * abs(random mod 5);
    repeat
      t := tickcount;
      i := i + 1;
      y1 := Basey + int((Xa + Xb + Vx) / 64);
      x1 := Basex + int((Ya + Yb + Vy) / 64);
      y2 := Basey + int((Xa + Xb - Vx) / 64);
      x2 := Basex + int((Ya + Yb - Vy) / 64);
      col := col + 1;
      if col > 253 then
        col := 0;
      pmforecolor(col);
      moveto(x1, y1);
      lineto(x2, y2);
      Xa := Xa - Int(Ya / incr2);
      Ya := Int(Xa / incr2) + Ya;
      Xb := Xb - Int(Yb / incr1);
      Yb := Int(Xb / incr1) + Yb;
      Vx := Vx - Int(Vy / incr1);
      Vy := Int(Vx / incr1) + Vy;
      repeat
      until tickcount >= t + 1;
    until (i = 600) or button;
    SetOrigin(0, 0);
    if abs(incr1) > 27 then
      s1 := -Sgn(incr1);
    if abs(incr2) > 27 then
      s2 := -Sgn(incr2);
  end;

{all this does right now is draw random dots on the screen}
procedure diffusion;
  var
    x, y, i: integer;
  begin
    i := 0;
    repeat
      x := abs(random mod screenbits.bounds.right);
      y := abs(random mod screenbits.bounds.bottom);
      i := i + 1;
      pmforecolor(i mod 254);
      moveto(x, y);
      line(0, 0)
    until button or (i > 20000);
  end;

{this draws random lines on the screen}
procedure lines;
  var
    x, y, i: integer;
  begin
    i := 0;
    repeat
      i := i + 1;
      x := abs(random mod (screenbits.bounds.right + 100)) - 50;
      y := abs(random mod (screenbits.bounds.bottom + 100)) - 50;
      pmforecolor(i mod 254);
      lineto(x, y);
    until button or (i = 3000);
  end;

{this draws random circles on the screen}
procedure bubbles;
  var
    i, x, y, z: integer;
  begin
    i := 0;
    repeat
      i := i + 1;
      x := abs(random) mod screenbits.bounds.right;
      y := abs(random) mod screenbits.bounds.bottom;
      z := abs(random) mod 10 + 1;
      circle(x, y, z, i mod 253, false);
    until button or (i >= 3000 * (screenbits.bounds.right div 512));
  end;

{This draws large circles with a gradient going from center outward}
{this one looks really neat animated!}
procedure blobs;
  var
    x, y, z, i, m: integer;
  begin
    m := 0;
    repeat
      m := m + 1;
      x := abs(random mod screenbits.bounds.right);
      y := abs(random mod screenbits.bounds.bottom);
      z := abs(random mod 70) + 10;
      i := 0;
      repeat
        i := i + 1;
        circle(x, y, i, (z + x + i) mod 253, true);
      until (i = z) or button;
    until (m > 100 * (screenbits.bounds.right div 512)) or button;
  end;

{This draws lines sweeping around the points on the edge of a circle}
{kinda like a fan blade spinning around}
procedure fan1;
  var
    x, y, z, i, m, x2, y2: integer;
  begin
    m := 1;
    repeat
      m := m + 1;
      x := abs(random mod screenbits.bounds.right);
      y := abs(random mod screenbits.bounds.bottom);
      z := abs(random mod 80) + 20;
      i := 0;
      x2 := z;
      repeat
        x2 := x2 - 1;
        i := i + 1;
        y2 := -round(sqrt(z * z - x2 * x2));
        moveto(x2 + x, y2 + y);
        pmforecolor(i mod 253);
        lineto(x, y);
      until (x2 = -z) or button;
      x2 := -z;
      repeat
        x2 := x2 + 1;
        i := i + 1;
        y2 := round(sqrt(z * z - x2 * x2));
        moveto(x2 + x, y2 + y);
        pmforecolor(i mod 253);
        lineto(x, y);
      until (x2 = z) or button;
    until (m > 100 * (screenbits.bounds.right div 512)) or button;
  end;

{this is a modification of fan that draws circles instead of lines}
procedure fan2;
  var
    x, y, z, i, m, x2, y2: integer;
  begin
    m := 1;
    repeat
      m := m + 1;
      x := abs(random mod screenbits.bounds.right);
      y := abs(random mod screenbits.bounds.bottom);
      z := abs(random mod 40) + 10;
      i := 0;
      x2 := z;
      repeat
        x2 := x2 - 1;
        i := i + 1;
        y2 := -round(sqrt(z * z - x2 * x2));
        circle(x2 + x, y2 + y, z, i mod 253, false);
      until (x2 = -z) or button;
      x2 := -z;
      repeat
        x2 := x2 + 1;
        i := i + 1;
        y2 := round(sqrt(z * z - x2 * x2));
        circle(x2 + x, y2 + y, z, i mod 253, false);
      until (x2 = z) or button;
    until (m > 100 * (screenbits.bounds.right div 512)) or button;
  end;

procedure spyro;
  var
    x, y, z, m: integer;
    a, s: real;
  begin
    m := 0;
    repeat
      m := m + 1;
      x := abs(random mod screenbits.bounds.right);
      y := abs(random mod screenbits.bounds.bottom);
      z := abs(random mod 900) + 100;
      s := z * 0.1;
      a := z * 10;
      repeat
        z := z - 1;
        s := s - 0.1;
        a := a - 10;
        circle(round(s * cos(a * 0.0174533) + x), -round(s * sin(a * 0.0174533) - y), 6, (z + x + y) mod 253, false);
      until button or (z = 0);
    until button or (m > 50);
  end;

procedure pal;
  var
    i: integer;
  begin
    for i := 0 to 253 do
      begin
        pmforecolor(i);
        moveto(i, 350);
        lineto(i, 284);
      end;
  end;
  
{DrawPoly, spirals and drawspirals together form a really neat package that draws}
{polygons on the screen and rotates them and shrinks them with each iteration}

{draws a polygon centered at (cx,cy) with s number of sides}
{w is the width of the polygon (from the center to the perpindicular bisector of a side)}
{and t is the angle of rotation in radians from the positive screen y axis (vertical line down)}
  const
    sqrt2 = 1.414213562;

procedure DrawPoly (cx, cy, s: integer; w, t: real);
  var
    x, y: real;
    i: integer;
  begin
    x := w * sqrt2 * cos(t);
    y := w * sqrt2 * sin(t);
    MoveTo(round(x) + cx, round(y) + cy);
    for i := 1 to s do
      begin
        x := w * sqrt2 * cos(t + i * pi * 2 / s);
        y := w * sqrt2 * sin(t + i * pi * 2 / s);
        LineTo(round(x) + cx, round(y) + cy);
      end;
  end;

{draws sucessively shrinking and rotating polygons}
{the for loop will draw 20 polygons, shrinking each successive polygon by step}
{and rotating it by angle}
procedure spirals (step, angle: real; sides, number: integer);
  var
    i: integer;
  begin
    for i := 0 to number do
      begin
        PmForeColor(i);
        DrawPoly(screenbits.bounds.right div 2, screenbits.bounds.bottom div 2, sides, step * i, i * angle);
      end;
  end;

procedure drawspirals;
  begin
{first parameter is step, second is angle, third is number of sides,fourth is number of polygons}
    spirals(abs(random mod 9) + 1, pi / abs(random mod 200), abs(random mod 9) + 1, 255);
  end;