Skip to navigation

BBC Micro Elite

Drawing the sun

Drawing and storing the sun, and the systems on the Short-range Chart
---------------------------------------------------------------------
References: SUN, WPLS
  The sun in Elite is an absolute sight to behold, with its flickering fringes
  and bright, white glare that lights up even the darkest corners of space.
  Perhaps surprisingly, it turns out to be quite a lot easier to draw the sun
  than the meridians and craters of the planets.
  
  Let's see what it takes to let there be light in the Elite universe.
  
  Line by line
  ------------
  Unlike the planets, which are drawn as circles, the sun is drawn as a set of
  horizontal lines, with one line per pixel line on-screen. This is how the
  shimmering edges are drawn, by randomly making the lines shorter or longer
  (more on that later).
  
  Each line is defined by two parameters: the coordinate of the centre of the
  line, and the length of the line from its centre to one end (which we call the
  "half-width", as it's half the width of the full horizontal line). For the
  sun, all the lines have the same centre x-coordinate, which is the same
  x-coordinate as the centre of the sun.
  
  Given this, we can draw the sun line by line, and all we need to calculate is
  the half-width of the line for that particular y-coordinate. We can do this
  using nothing more complicated than Pythagoras - there's no need for any
  trigonometry here. Consider drawing a sun line near the bottom of a sun with
  radius K, let's say the line that is V lines below the centre. It looks
  something like this:
  
                           _ - _
                        =         =
                      =             =                   |`.
                     =               =                  |  `.  K
    We want          =       |`.     =                V |    `.
    to draw           =      |  `.  =         __-->     |      `.
    this line ------>  ._____|____`.   ___.--ยด          +--------`
                           - _ -                     SQRT(K^2 - V^2)
  
  Looking at the triangle from the centre of the sun down to the horizontal
  line we want to draw, we can apply Pythagoras to calculate that the half-width
  of the line we want to draw is SQRT(K^2 - V^2), so along with the value of V
  we have all the data we need to draw that line, and by extension the whole
  ball of fire.
  
  Flickering fringes
  ------------------
  The sun's flickering fringes are easy enough to implement in this model.
  
  We start by calculating a figure between 0 and 7, with bigger numbers for
  bigger suns, and call this the "fringe size", which we store in CNT. This
  defines the width of the pulsating fringe around the sun (which explains why
  the sun stops flickering when it's far away - it has a fringe size of 0).
  
  Then, when calculating the half-width of each line using the method above, we
  simply pick a random number between 0 and the fringe size, and add it to the
  half-width. This makes the sun symmetrical around its vertical meridian, and
  as the random number changes for each line and for each redraw of the sun, the
  sun's fringes shimmer and flicker. It's simple but very effective, and it adds
  very little effort, even to the erase procedure, as we can see in the next
  section.
  
  Drawing and storing sun lines with SUN
  --------------------------------------
  As with all objects in the sky, we can erase the sun from the screen by
  drawing it a second time in the same place as before, so it cancels out the
  existing sun using EOR logic. Although the maths above isn't complex, it is
  still pretty time-consuming, especially with a large sun on the screen, so
  as with the planets, the sun has its own line heap, stored at LSO, which
  stores the data for every line in the current sun.
  
  The first location at LSO has a special meaning:
  
    * LSO = 1   indicates the line heap contains data
    * LSO = &FF indicates the line heap is empty
  
  Because the sun is made up of lines and it can fill the entire space view,
  the sun's line heap contains 192 values, one for each of the lines on the
  screen. The value in LSO+Y contains details of the sun's line on pixel row Y,
  with a 0 indicating there is no line, and a non-zero value containing the
  half-width of the sun line on that y-coordinate. Along with the sun's centre
  coordinates in SUNX and SUNY, the line heap contains everything we need to
  know in order to draw the sun, all without having to recalculate anything.
  
  This also applies to the random fringe factor that we add to the half-width to
  make the sun shimmer. As we're only storing the half-width and that contains
  the random fringe size, we can store and redraw shimmering suns with no more
  effort then a clean ball sun. It's remarkably elegant for such a complicated-
  looking graphical effect.
  
  The SUN routine combines the drawing of the new sun and the removal of the
  old one into one pass through the line heap, from the bottom of the screen
  to the top (so from the end of the heap to the start). We do this in part 2
  by starting at the bottom and plotting each sun line in turn from the line
  heap as we move up the screen. As each line is plotted, thus erasing the
  old sun, it is removed from the line heap.
  
  We do this until we reach the point where we need to start drawing the new
  sun, at which point we move into part 3. This draws two horizontal lines that
  between them manage to remove the old sun's line and draw the new sun's line
  in the most efficient way. Each time, we replace the value in the line heap
  with the new line's half-width, so the new sun can be erased in the same way.
  Once the new sun is drawn, we then keep heading up the screen in part 4, where
  we redraw any remaining lines from the old sun, thus removing them from the
  screen, and leaving just the new sun on show.
  
  The LSO line heap block shares its memory with the ship line heap for the
  space station. This memory can be shared as our local bubble of universe can
  support either the sun or a space station, but not both.