#include <wgt5.h>

/*
==============================================================================
		      WordUp Graphics Toolkit Version 5.0
			     Demonstration Program 68a

 This example shows how to make a scrolling image with depth.  It scrolls
 each horizontal line of the ground by different amounts, the fastest
 being closest to you.

 *** PROJECT ***
 This program requires the WGT5_WC.LIB file to be linked.

 *** DATA FILES ***
 STREET.PAL, RUN.SPR
							   WATCOM C++ VERSION
==============================================================================
*/

color pal[256];         /* The palette used for every graphic image */
block sprites[200];     /* Array of images for the running robot */

block background;       /* Holds the background scrolling image */
block work;             /* Page for constructing each frame */

int oldmode;

/* A structure which holds the scrolling values for each horizontal line */
typedef struct
 {
  int x;                /* Current x value, shifted by 8 */
  int increment;        /* fixed point increment */
 } line_scroll;
line_scroll lines[80];  /* 80 scrolling lines along the ground */

/* A simple sprite structure */
typedef struct
 {
  int x;
  int y;
  int anm;              /* Sprite number */
 } sprite;
sprite people[5];


int backx = 0;          /* X value for the scrolling rocks */
int backinc;            /* X increment for scrolling rocks */


/* Loads the graphics files, and allocates buffers */
void load_graphics (void)
{
 work = wallocblock (320, 200);
 /* Allocate a work buffer */

 wloadsprites (pal, "run.spr", sprites, 0, 199);
 background = wloadpak ("street.pak");
 wsetpalette (0, 255, pal);
}



/* Frees the buffers and sprites */
void free_graphics (void)
{
 wfreesprites (sprites, 0, 199);
 wfreeblock (background);
 wfreeblock (work);
}


/* Set up the initial scrolling values */
void init_lines (void)
{
int i;
int inc;

 inc = 128;     /* slowest scrolling speed (128/256 of a pixel */
 
 backx = 0;     /* rocks x value */
 backinc = inc; /* rocks same speed as the ground */

 for (i = 0; i < 80; i++)
  {
   lines[i].x = 0;              /* clear out the x value */
   lines[i].increment = inc;    /* set the scroll speed */
   inc += 32;                   /* Make the next row move faster */
  }

}



/* Construct the background image */
void animate_lines (void)
{
block source1, source2;
block dest1, dest2;
block origsource, origdest;
int i;
int x;

 wcopyscreen (0, 0, 319, 51, background, 0, 0, work);
 /* Draw the moon stationary */
 
 
 x = backx >> 8;
 
 /* Copy the rocks */
 wcopyscreen (x, 52, 319, 119, background, 0, 52, work);
 if (x > 0)
   wcopyscreen (0, 52, x-1, 119, background, 320 - x, 52, work);
 
 /* Scroll the rocks */
 backx += backinc;
 if (backx >= 81920)   /* 81920 is 320 << 8 */
     backx -= 81920;

 
 origdest = abuf + 120 * 320;           /* First row to copy */
 origsource = background + 120 * 320;   /* First row to copy */
 
 for (i = 0; i < 80; i++)
  {
   /* Scroll this line */
   lines[i].x += lines[i].increment;
   if (lines[i].x >= 81920)   /* 81920 is 320 << 8, wraps scroll around */
      lines[i].x -= 81920;


   x = lines[i].x >> 8;
   /* Get the x coord */

   dest1 = origdest + i * 320;
   dest2 = dest1 + (319 - x);
   source1 = origsource + i * 320;
   source2 = source1 + x;
   
   /* Copy the line in two steps */
   memcpy (dest1, source2, 320 - x);
   if (x > 0)
    memcpy (dest2, source1, x + 1);
   
  }

}



/* Animates and displays the running man */
void animate_man (void)
{
 people[0].anm++;
 if (people[0].anm > 29)
   people[0].anm = 0;

 wputblock (people[0].x, people[0].y, sprites[people[0].anm], 1);
}



void main (void)
{
  oldmode = wgetmode ();
  if (!vgadetected ())
  {
    printf ("VGA is required to run this program...");
    exit (1);
  }

  printf ("WGT Example #68a\n\n");
  printf ("This example shows how to make a scrolling image with depth.  It scrolls\n");
  printf ("each horizontal line of the ground by different amounts, the fastest\n");
  printf ("being closest to you.\n");
  printf ("\nPress any key to begin.\n");
  getch ();

  vga256 ();

  load_graphics ();

  init_lines ();

  /* Set the position of the running man */
  people[0].x = 120;
  people[0].y = 50;
  people[0].anm = 0;


  do {
   wsetscreen (work);
   animate_lines ();
   animate_man ();
   wnormscreen ();
   wretrace ();
   wputblock (0, 0, work, 0);
   } while (!kbhit ());

  free_graphics ();
  wsetmode (oldmode);
}
