// optimized wallpaper scroller by kamran sethi and khurram rashid
// fastics karachi.

   class cscroll
    {
     private:

     int NewOffset;

 ///////////////////////////////////////////////////////////////////////

     public:
    int status;
    int speed;
    int Skip;

    BITMAP wallpaper;
    BITMAP scrollpaper;
//////////////////////////////////////////////////////////////////////////
//constructor class;
  void initialize (void)
  {
   speed = 0;
   status= 0;
   NewOffset = Skip*320;
  }
///////////////////////////////////////////////////////////////////////////
int cscroll::scroll_bitmap_vertically(void);
int cscroll::scroll_bitmap_horizontally(void);
int cscroll::scroll_bitmap_vertically_db(void);
int cscroll::scroll_bitmap_horizontally_db(void);
int cscroll::partially_scroll_bitmap_horizontally_db(void);
int cscroll::partial_scroll_horizontally_db (void);
int cscroll::scroll_bitmap_down_db(void);
};


  int cscroll::scroll_bitmap_vertically(void)
  {
   int ReturnVal = 0;

       int j;
  word screen_offset = 0;
  word bitmap_offset = 0;

//////////////////////////// update speed /////////////////////////////////

  status+=speed;
//////////////////////////// update speed /////////////////////////////////

//////////////////////////// check input  /////////////////////////////////
  if (status >   199  ) { status = 0; ReturnVal= 1;}
  if (status < (-199) ) { status = 0; ReturnVal= 1;}
//////////////////////////// check input  /////////////////////////////////

//////////////////////////// for right movement ////////////////////////////
#if 0
  if (status >= 0)
  {

  for(j=0;j<wallpaper.height-abs(status);j++)
  {
 memcpy(&video_buffer[screen_offset],
 &wallpaper.data[bitmap_offset+(wallpaper.width*status)],
 wallpaper.width);

 bitmap_offset+=wallpaper.width;
 screen_offset+=SCREEN_WIDTH;
  }

  screen_offset = 0;
  bitmap_offset = 0;

  for(j=0;j<abs(status);j++)
  {
 memcpy(&video_buffer[screen_offset+(wallpaper.width)*(wallpaper.height-abs(status))],
 &wallpaper.data[bitmap_offset],
 wallpaper.width);


 bitmap_offset+=wallpaper.width;
 screen_offset+=SCREEN_WIDTH;
  }
   screen_offset = 0;
   bitmap_offset = 0;
  }

//////////////////////////// for right movement ////////////////////////////
//////////////////////////// for left movement ////////////////////////////

  else if (status < 0)
  {

  for(j=0;j<(wallpaper.height-abs(status));j++)
  {
 memcpy(&video_buffer[screen_offset+(wallpaper.width)*abs(status)],
 &wallpaper.data[bitmap_offset],
 wallpaper.width);


 bitmap_offset+=wallpaper.width;
 screen_offset+=SCREEN_WIDTH;
  }
   screen_offset = 0;
   bitmap_offset = 0;

   for(j=0;j<abs(status);j++)
  {
 memcpy(&video_buffer[screen_offset],
 &wallpaper.data[bitmap_offset+(wallpaper.width*(wallpaper.height-abs(status)))],
 wallpaper.width);
 bitmap_offset+=wallpaper.width;
 screen_offset+=SCREEN_WIDTH;
  }

  screen_offset = 0;
  bitmap_offset = 0;

  }
#endif
  return(ReturnVal);
  }
//////////////////////////// for left movement ////////////////////////////
////////////////////////////////////////////////////////////////////////////

int cscroll::scroll_bitmap_horizontally(void)
{

  ////////////////////////////    SCROLL

  int ReturnVal = 0;
       int j;
  word screen_offset = 0;
  word bitmap_offset = 0;
//////////////////////////// update speed /////////////////////////////////

  status+=speed;
//////////////////////////// update speed /////////////////////////////////

//////////////////////////// check input  /////////////////////////////////
  if (status >   319  ) { status = 0; ReturnVal=1;}
  if (status < (-319) ) { status = 0; ReturnVal=1;}
//////////////////////////// check input  /////////////////////////////////

#if 0
//////////////////////////// for right movement ////////////////////////////
  if (status >= 0)
  {
  for(j=0;j<wallpaper.height;j++)
  {
 memcpy(&video_buffer[screen_offset+status],&wallpaper.data[bitmap_offset],
 wallpaper.width-status);

 memcpy(&video_buffer[screen_offset],
 &wallpaper.data[bitmap_offset+wallpaper.width-status],
 status);
 bitmap_offset+=wallpaper.width;
 screen_offset+=SCREEN_WIDTH;
  }
  }
//////////////////////////// for right movement ////////////////////////////
//////////////////////////// for left movement ////////////////////////////
  else if (status < 0)
  {
  for(j=0;j<wallpaper.height;j++)
  {

 memcpy(&video_buffer[screen_offset],
 &wallpaper.data[bitmap_offset+abs(status)],
 wallpaper.width-abs(status));

 memcpy(&video_buffer[screen_offset+wallpaper.width-abs(status)],
 &wallpaper.data[bitmap_offset],
 abs(status));

 bitmap_offset+=wallpaper.width;
 screen_offset+=SCREEN_WIDTH;
  }
  }
#endif
  return(ReturnVal);

//////////////////////////// for left movement ////////////////////////////

////////////////////////////  end-scroll  ////////////////////////////

}
///////////////////////////////////////////////////////////////////////////

  int cscroll::scroll_bitmap_vertically_db(void)
  {

       int j;
       int ReturnVal = 0;
  word screen_offset = 0;
  word bitmap_offset = 0;

//////////////////////////// update speed /////////////////////////////////

  status+=speed;
//////////////////////////// update speed /////////////////////////////////

//////////////////////////// check input  /////////////////////////////////
  if (status >   199  ) { status = 0; ReturnVal = 1;}
  if (status < (-199) ) { status = 0; ReturnVal = 1;}
//////////////////////////// check input  /////////////////////////////////
	
//////////////////////////// for right movement ////////////////////////////
#if 1
  if (status >= 0)
  {

  for(j=0;j<wallpaper.height-abs(status);j++)
  {
 memcpy(&double_buffer[screen_offset],
 &wallpaper.data[bitmap_offset+(wallpaper.width*status)],
 wallpaper.width);

 bitmap_offset+=wallpaper.width;
 screen_offset+=SCREEN_WIDTH;
  }

  screen_offset = 0;
  bitmap_offset = 0;

  for(j=0;j<abs(status);j++)
  {
 memcpy(&double_buffer[screen_offset+(wallpaper.width)*(wallpaper.height-abs(status))],
 &wallpaper.data[bitmap_offset],
 wallpaper.width);


 bitmap_offset+=wallpaper.width;
 screen_offset+=SCREEN_WIDTH;
  }
   screen_offset = 0;
   bitmap_offset = 0;

  }

//////////////////////////// for right movement ////////////////////////////
//////////////////////////// for left movement ////////////////////////////

  else if (status < 0)
  {

  for(j=0;j<(wallpaper.height-abs(status));j++)
  {
 memcpy(&double_buffer[screen_offset+(wallpaper.width)*abs(status)],
 &wallpaper.data[bitmap_offset],
 wallpaper.width);


 bitmap_offset+=wallpaper.width;
 screen_offset+=SCREEN_WIDTH;
  }
   screen_offset = 0;
   bitmap_offset = 0;

   for(j=0;j<abs(status);j++)
  {
 memcpy(&double_buffer[screen_offset],
 &wallpaper.data[bitmap_offset+(wallpaper.width*(wallpaper.height-abs(status)))],
 wallpaper.width);
 bitmap_offset+=wallpaper.width;
 screen_offset+=SCREEN_WIDTH;
  }

  screen_offset = 0;
  bitmap_offset = 0;

  }
#endif
  return(ReturnVal);
  }
//////////////////////////// for left movement ////////////////////////////
////////////////////////////////////////////////////////////////////////////

int cscroll::scroll_bitmap_horizontally_db(void)
{

  ////////////////////////////    SCROLL

    int ReturnVal= 0;
       int j;
  word screen_offset = 0;
  word bitmap_offset = 0;
//////////////////////////// update speed /////////////////////////////////

  status+=speed;
//////////////////////////// update speed /////////////////////////////////

//////////////////////////// check input  /////////////////////////////////
  if (status >   319  ) { status = 0; ReturnVal=1;}
  if (status < (-319) ) { status = 0; ReturnVal=1;}
//////////////////////////// check input  /////////////////////////////////

#if 1
//////////////////////////// for right movement ////////////////////////////
  if (status >= 0)
  {
  for(j=0;j<wallpaper.height;j++)
  {
 memcpy(&double_buffer[screen_offset+status],&wallpaper.data[bitmap_offset],
 wallpaper.width-status);

 memcpy(&double_buffer[screen_offset],
 &wallpaper.data[bitmap_offset+wallpaper.width-status],
 status);
 bitmap_offset+=wallpaper.width;
 screen_offset+=SCREEN_WIDTH;
  }
  }
//////////////////////////// for right movement ////////////////////////////
//////////////////////////// for left movement ////////////////////////////
  else if (status < 0)
  {
  for(j=0;j<wallpaper.height;j++)
  {

 memcpy(&double_buffer[screen_offset],
 &wallpaper.data[bitmap_offset+abs(status)],
 wallpaper.width-abs(status));

 memcpy(&double_buffer[screen_offset+wallpaper.width-abs(status)],
 &wallpaper.data[bitmap_offset],
 abs(status));

 bitmap_offset+=wallpaper.width;
 screen_offset+=SCREEN_WIDTH;
  }
  }
//////////////////////////// for left movement ////////////////////////////
#endif
  return (ReturnVal);
////////////////////////////  end-scroll  ////////////////////////////

}

int cscroll::partially_scroll_bitmap_horizontally_db(void)
{

  ////////////////////////////    SCROLL

    int ReturnVal= 0;
       int j;
  word screen_offset = NewOffset;
  word bitmap_offset = NewOffset;
//////////////////////////// update speed /////////////////////////////////

  status+=speed;
//////////////////////////// update speed /////////////////////////////////

//////////////////////////// check input  /////////////////////////////////
  if (status >   319  ) { status = 0; ReturnVal=1;}
  if (status < (-319) ) { status = 0; ReturnVal=1;}
//////////////////////////// check input  /////////////////////////////////

#if 0
//////////////////////////// for right movement ////////////////////////////
  if (status >= 0)
  {
  for(j=0;j<wallpaper.height-Skip;j++)
  {
 memcpy(&double_buffer[screen_offset+status],&wallpaper.data[bitmap_offset],
 wallpaper.width-status);

 memcpy(&double_buffer[screen_offset],
 &wallpaper.data[bitmap_offset+wallpaper.width-status],
 status);
 bitmap_offset+=wallpaper.width;
 screen_offset+=SCREEN_WIDTH;
  }
  }
//////////////////////////// for right movement ////////////////////////////
//////////////////////////// for left movement ////////////////////////////
  else if (status < 0)
  {
  for(j=0;j<wallpaper.height-Skip;j++)
  {

 memcpy(&double_buffer[screen_offset],
 &wallpaper.data[bitmap_offset+abs(status)],
 wallpaper.width-abs(status));

 memcpy(&double_buffer[screen_offset+wallpaper.width-abs(status)],
 &wallpaper.data[bitmap_offset],
 abs(status));

 bitmap_offset+=wallpaper.width;
 screen_offset+=SCREEN_WIDTH;
  }
  }
//////////////////////////// for left movement ////////////////////////////
#endif
  return (ReturnVal);
////////////////////////////  end-scroll  ////////////////////////////

}


int cscroll::partial_scroll_horizontally_db (void)
    {

  ////////////////////////////    SCROLL

    int ReturnVal=0;

       int j;
  word screen_offset = 0;
  word bitmap_offset = 0;
//////////////////////////// update speed /////////////////////////////////

  status+=speed;
//////////////////////////// update speed /////////////////////////////////

//////////////////////////// check input  /////////////////////////////////
  if (status >   319  ) { status = 0; ReturnVal = 1;}
  if (status < (-319) ) { status = 0; ReturnVal = 1;}
//////////////////////////// check input  /////////////////////////////////
#if 0
//////////////////////////// for right movement ////////////////////////////
  if (status >= 0)
  {
  for(j=0;j<wallpaper.height;j++)
  {
 memcpy(&double_buffer[screen_offset+status],&wallpaper.data[bitmap_offset],
 wallpaper.width-status);

 memcpy(&double_buffer[screen_offset],
 &wallpaper.data[bitmap_offset+wallpaper.width-status],
 status);
 bitmap_offset+=wallpaper.width;
 screen_offset+=SCREEN_WIDTH;
  }
  }
//////////////////////////// for right movement ////////////////////////////
//////////////////////////// for left movement ////////////////////////////
  else if (status < 0)
  {
  for(j=0;j<wallpaper.height;j++)
  {

 memcpy(&double_buffer[screen_offset],
 &wallpaper.data[bitmap_offset+abs(status)],
 wallpaper.width-abs(status));

 memcpy(&double_buffer[screen_offset+scrollpaper.width-abs(status)],
 &scrollpaper.data[bitmap_offset],
 abs(status));

 bitmap_offset+=wallpaper.width;
 screen_offset+=SCREEN_WIDTH;
  }
  }
#endif
  return (ReturnVal);
  }
//////////////////////////// for left movement ////////////////////////////

///////////////////////////////////////////////////////////////////////////

  int cscroll::scroll_bitmap_down_db(void)
  {

       int j;
       int ReturnVal = 0;
  word screen_offset = 0;
  word bitmap_offset = 0;

//////////////////////////// update speed /////////////////////////////////

  status+=speed;
//////////////////////////// update speed /////////////////////////////////

//////////////////////////// check input  /////////////////////////////////
  if (status >   199  ) { status = 0; ReturnVal = 1;}
  if (status < (-199) ) { status = 0; ReturnVal = 1;}
//////////////////////////// check input  /////////////////////////////////

//////////////////////////// for right movement ////////////////////////////
#if 0
  if (status >= 0)
  {


  for(j=0;j<wallpaper.height-abs(status);j++)
  {
 memcpy(&double_buffer[screen_offset],
 &wallpaper.data[bitmap_offset+(wallpaper.width*status)],
 wallpaper.width);

 bitmap_offset+=wallpaper.width;
 screen_offset+=SCREEN_WIDTH;
  }

  screen_offset = 0;
  bitmap_offset = 0;
  /*
  for(j=0;j<abs(status);j++)
  {
 memcpy(&double_buffer[screen_offset+(wallpaper.width)*(wallpaper.height-abs(status))],
 &wallpaper.data[bitmap_offset],
 wallpaper.width);


 bitmap_offset+=wallpaper.width;
 screen_offset+=SCREEN_WIDTH;
  }
   screen_offset = 0;
   bitmap_offset = 0;
  */
  }

//////////////////////////// for right movement ////////////////////////////
//////////////////////////// for left movement ////////////////////////////

  else if (status < 0)
  {
  /*
  for(j=0;j<(wallpaper.height-abs(status));j++)
  {
 memcpy(&double_buffer[screen_offset+(wallpaper.width)*abs(status)],
 &wallpaper.data[bitmap_offset],
 wallpaper.width);


 bitmap_offset+=wallpaper.width;
 screen_offset+=SCREEN_WIDTH;
  }
   screen_offset = 0;
   bitmap_offset = 0;
  */
   for(j=0;j<abs(status);j++)
  {
 memcpy(&double_buffer[screen_offset],
 &wallpaper.data[bitmap_offset+(wallpaper.width*(wallpaper.height-abs(status)))],
 wallpaper.width);
 bitmap_offset+=wallpaper.width;
 screen_offset+=SCREEN_WIDTH;
  }

  screen_offset = 0;
  bitmap_offset = 0;

  }
#endif
  return(ReturnVal);
  }
//////////////////////////// for left movement ////////////////////////////
////////////////////////////////////////////////////////////////////////////
