--** Starfield demo.

#INCLUDE "course.module"
#INCLUDE "sdlraster.module"

VAL INT WIDTH IS 800:
VAL INT HEIGHT IS 600:
VAL INT NUM.STARS IS 500:

--* Clear rasters, and control the speed of the display.
PROC clear (CHAN RASTER in?, out!)
  TIMER tim:
  INT t:
  SEQ
    tim ? t
    WHILE TRUE
      RASTER r:
      SEQ
        in ? r
        --{{{  make sure 1/10s has passed since the last update
        t := t PLUS (1000000 / 10)
        tim ? AFTER t
        --}}}
        raster.clear (r, #000000)
        out ! r
:

--* Draw a single star.
PROC star (CHAN RASTER in?, out!, VAL INT init.x, y, col, speed)
  INITIAL INT x IS init.x:
  WHILE TRUE
    RASTER r:
    SEQ
      in ? r
      r[y][x] := col
      x := (x + speed) \ WIDTH
      out ! r
:

PROC starfield ()
  INITIAL INT seed IS 2509:
  [NUM.STARS]INT x, y, col, speed:
  SEQ
    --{{{  randomly select initial settings for stars
    SEQ i = 0 FOR NUM.STARS
      SEQ
        x[i], seed := random (WIDTH, seed)
        y[i], seed := random (HEIGHT, seed)
        col[i], seed := random (#FFFFFF, seed)
        speed[i], seed := random (9, seed)
        speed[i] := speed[i] + 1
    --}}}
    --{{{  display the starfield
    CHAN RASTER c:
    [NUM.STARS + 1]CHAN RASTER cs:
    PAR
      raster.display.simple ("Starfield", WIDTH, HEIGHT, 2, cs[NUM.STARS]?, c!)
      clear (c?, cs[0]!)
      PAR i = 0 FOR NUM.STARS
        star (cs[i]?, cs[i + 1]!, x[i], y[i], col[i], speed[i])
    --}}}
:
