6502's cornerFree Span Buffer [3]
2002-12-28
Index

Welcome!
Who am I
Demo
Documents
Small ones
Problems
Chess
Images
Music
My blog
Write me

Versione italiana 


Data structure updating

The kernel of the algorithm is the function that draws the visible part of a segment and updates the list of available spans. To see how it works let's say we have to draw a segment (xa,xb) and let's check how this segment may interact with a span (x0,x1):

Segment-span interaction types
This picture shows all the possible interactions between a segment (xa,xb) and an available span (x0,x1).

  
Case 1: x1 <= xa
In this case we can simply ignore the available span and go to the next span on the scanline.
  
Case 2: x0<xa; xa<x1<=xb
In this case the visible part is (xa,x1) and the span has to be updated setting the right limit at xa.
  
Case 3: x0<xa; x1>xb
This is the worst case and requires the drawing of (xa,xb), the modification of the right end of the available span (setting it to xa) and the creation of a new available span (xb,x1). However after this operation there's no point in checking other spans on the scanline (spans on a scanline never overlap).
  
Case 4: x0>=xa; x1<=xb
In this case the visible part is (x0,x1) and the span can be removed from the list of available spans. The algorithm must however continue the search for more eventual available spans on the same scanline.
  
Case 5: xa<x0<xb; x1>xb
In this case the visible part is (x0,xb) and the left end of the span has to be modified in xb. After that this scanline is completed.
  
Case 6: x0>=xb
This case doesn't require any drawing and informs that no more checks on this scanline are needed.

The following function draws the visible parts of a segment and updates the span list of the scanline. It's the C translation of the cases described above.


void DrawSegment(int y,int xa,int xb)
{
  Span *old,*current,*n;
  for (old=NULL,current=FirstSpan[y];
       current!=NULL;
       old=current,current=current->next)
  {
    if (current->x1<=xa) // Case 1
      continue;
    
    if (current->x0<xa)
    {
      if (current->x1<=xb) // Case 2
      {
        DrawPart(y,xa,current->x1);
        current->x1=xa;
      }
      else // Case 3
      {
        DrawPart(y,xa,xb);
        n=NewSpan();
        n->next=current->next;
        current->next=n;
        n->x1=current->x1;
        current->x1=xa; n->x0=xb;
        return;
      }
    }
    else
    {
      if (current->x0>=xb) // Case 6
        return;
      
      if (current->x1<=xb) // Case 4
      {
        DrawPart(y,current->x0,current->x1);
        n=current->next; FreeSpan(current);
        if (old) old->next=n;
            else FirstSpan[y]=n;
        current=n;
        if (current==NULL) return;
      }
      else // Case 5
      {
        DrawPart(y,current->x0,xb);
        current->x0=xb;
      }
    }
  }
}