/*FILE HEADER**************************************************************
 *
 *  File name		: $Id$
 *  RCS Revision Number	: $Revision: 1.1 $
 *  Last Modified	: $Date: 94/10/28 09:23:35 $
 *  CSCI name		: Real-Time Graphics System - Applications Interface
 *  CSC name		: All functions
 *  Notes:
 *      This file contains code used to debug and test the SVME-770 RTGS.
 *      This code is provided as an example of how to call the RTGS functions
 *      from a host application.
 *  History		:
 *      Created 94/01/17 by Jeff Sanderson
 *
 *END FILE HEADER*********************************************************/

#include "dy4std.h"
#include "es.h"
#include "css.h"

#include "rtgs_ai.h"
#include "video.h"
#include "colours.h"

#include "test.h"

/*-----------------------------------------------------------------------*/
#define BITS_PER_BYTE  8
#define PIX_PER_BYTE    1

#define LADY_X         288
#define LADY_Y         192

#define WF_W		( 1024 )
#define WF_H		( 768 )

#define WF_X		( ( RES_X - WF_W ) / 2 )
#define WF_Y		( ( RES_Y - WF_H ) / 2 )

#define WF_PTCH		( WF_W * 8 )

#define LEFT    0
#define RIGHT   1
#define UP      2
#define DOWN    3

/*-----------------------------------------------------------------------*/

void test_waterfall( void );
void wf( int dir, int stp, int x, int y, int w, int h , int *buf, int ptch);


#include "lady2.h"    /* file containing decl of bitmap */

/*-----------------------------------------------------------------------*/
extern uint32  *symbols[ 4 ];

void test_waterfall( void )
{
    int   loopcount;
    int   *buff1;
    int   *buff2;
    int   *lady_gcc;
    uint32   step;
    uint32   base;
    uint32   end;
    uint32   ptr;
    uint32   len1;
    uint32   len2;
    uint32   num_lines;

    init( "Waterfall test" );

    lady_gcc = ( int * )Gcc_malloc(( LADY_X * LADY_Y / BITS_PER_BYTE ), 0 );
    malloc_check( lady_gcc );

    buff1 = ( int * )Gcc_malloc(( WF_W * WF_H / PIX_PER_BYTE ), 0 );
    malloc_check( buff1 );

    buff2 = ( int * )Gcc_malloc(( WF_W * WF_H / PIX_PER_BYTE ), 0 );
    malloc_check( buff2 );

    /* set up images */

    Copy_bitmap_to_gcc(( char * )( lady2 ), ( char * )( lady_gcc ), 
                       ( LADY_X * LADY_Y / BITS_PER_BYTE ));

    Clear_screen( BLACK, 0, 0 );
    Set_transparency_mode( OPAQUE );
#ifdef PICT
    Set_foreground_colour( WHITE );
    Bitblt_bit_expand( lady_gcc,  64,  32, LADY_X, LADY_Y, LADY_X );
    Set_foreground_colour( RED );
    Bitblt_bit_expand( lady_gcc,  64, 224, LADY_X, LADY_Y, LADY_X );
    Set_foreground_colour( GREEN );
    Bitblt_bit_expand( lady_gcc,  64, 416, LADY_X, LADY_Y, LADY_X );
    Set_foreground_colour( BLUE );
    Bitblt_bit_expand( lady_gcc,  64, 608, LADY_X, LADY_Y, LADY_X );
    Set_foreground_colour( WHITE );
    Bitblt_bit_expand( lady_gcc,  64, 800, LADY_X, LADY_Y, LADY_X );
    Set_foreground_colour( RED );
    Bitblt_bit_expand( lady_gcc, 352,  32, LADY_X, LADY_Y, LADY_X );
    Set_foreground_colour( GREEN );
    Bitblt_bit_expand( lady_gcc, 352, 224, LADY_X, LADY_Y, LADY_X );
    Set_foreground_colour( BLUE );
    Bitblt_bit_expand( lady_gcc, 352, 416, LADY_X, LADY_Y, LADY_X );
    Set_foreground_colour( WHITE );
    Bitblt_bit_expand( lady_gcc, 352, 608, LADY_X, LADY_Y, LADY_X );
    Set_foreground_colour( RED );
    Bitblt_bit_expand( lady_gcc, 352, 800, LADY_X, LADY_Y, LADY_X );
    Set_foreground_colour( GREEN );
    Bitblt_bit_expand( lady_gcc, 640,  32, LADY_X, LADY_Y, LADY_X );
    Set_foreground_colour( BLUE );
    Bitblt_bit_expand( lady_gcc, 640, 224, LADY_X, LADY_Y, LADY_X );
    Set_foreground_colour( WHITE );
    Bitblt_bit_expand( lady_gcc, 640, 416, LADY_X, LADY_Y, LADY_X );
    Set_foreground_colour( RED );
    Bitblt_bit_expand( lady_gcc, 640, 608, LADY_X, LADY_Y, LADY_X );
    Set_foreground_colour( GREEN );
    Bitblt_bit_expand( lady_gcc, 640, 800, LADY_X, LADY_Y, LADY_X );
    Set_foreground_colour( BLUE );
    Bitblt_bit_expand( lady_gcc, 928,  32, LADY_X, LADY_Y, LADY_X );
    Set_foreground_colour( WHITE );
    Bitblt_bit_expand( lady_gcc, 928, 224, LADY_X, LADY_Y, LADY_X );
    Set_foreground_colour( RED );
    Bitblt_bit_expand( lady_gcc, 928, 416, LADY_X, LADY_Y, LADY_X );
    Set_foreground_colour( GREEN );
    Bitblt_bit_expand( lady_gcc, 928, 608, LADY_X, LADY_Y, LADY_X );
    Set_foreground_colour( BLUE );
    Bitblt_bit_expand( lady_gcc, 928, 800, LADY_X, LADY_Y, LADY_X );
#else
    Clear_screen( BLACK, 0, 0 );
    Set_foreground_colour( WHITE );
    Draw_grid( 0x8 );
    Set_foreground_colour( BLUE );
    Draw_line( 0, 0, RES_X, RES_Y );
#endif

    /* 
     * Save the image offscreen 
     */

    Bitblt_xy_to_linear( WF_X, WF_Y, buff1, WF_W, WF_H, WF_PTCH );

    
    /* 
     * Set up the frame buffering 
     */

    Set_frame_buffering( 0, 1 );
    Flip_buffers( ON, BLACK );
    Flip_buffers( ON, BLACK );
    
    base = ( uint32 )( GSP_ADDR( buff1 ));
    end  = ( uint32 )( GSP_ADDR( buff1 )) + ( WF_H  * WF_PTCH );
    ptr  = end;
    num_lines = (( end - base ) / WF_PTCH );

    for( step = 1; step < 10 ; step++ )
    {
        Printf("Scrolling by %d line at a time\n", step );
	Bitblt_linear_to_xy( buff1, WF_X, WF_Y, WF_W, WF_H, WF_PTCH );

        Printf("Single buffering method\n", step );
        Set_frame_buffering( 0, 0 );
	loopcount =  0x80;
	while( loopcount-- )
	{
	    wf( DOWN, ( int )step, WF_X, WF_Y, WF_W, WF_H, buff2, WF_PTCH );
	}
        Key_wait();

        Printf("double buffering method\n", step );
        Set_frame_buffering( 0, 1 );
	loopcount =  0x80;
	while( loopcount-- )
	{
	    if(( ptr == end ) || ( ptr == base ))
	    {
		ptr = end;
		Bitblt_linear_to_xy( ( int * )( VME_ADDR( base ) ), 
                                     WF_X, WF_Y, 
                                     WF_W, WF_H, 
                                     WF_PTCH );
	    }
	    else 
	    {
                if( ptr < base )
                {
		    ptr = end - ( base - ptr );
                }
		len1 = ( end - ptr ) / WF_PTCH;
		len2 = num_lines - len1;
		Bitblt_linear_to_xy( ( int * )( VME_ADDR( ptr ) ), 
                                     WF_X, WF_Y, 
                                     WF_W, ( int )len1, 
                                     WF_PTCH );
		Bitblt_linear_to_xy( ( int * )( VME_ADDR( base ) ), 
                                     WF_X, ( WF_Y + ( int )len1 ), 
                                     WF_W, ( int )len2, 
                                     WF_PTCH );
	    }
	    Flip_buffers( ON, BLACK );
	    ptr -= ( step * WF_PTCH );
	}
        Key_wait();
    }
}

/*-----------------------------------------------------------------------*/

void wf( int dir, int stp, int x, int y, int w, int h , int *buf, int ptch )
{
    switch( dir )
    {
        case LEFT :
        {
	    Bitblt_xy_to_linear( x, y, buf, stp, h, ptch );
	    Bitblt_xy_to_xy(( x + stp ), y, x, y, ( w - stp ), h );
	    Bitblt_linear_to_xy( buf, ( x + w - stp ), y, stp, h, ptch );
            break;
        }
        case RIGHT :
        {
	    Bitblt_xy_to_linear(( x + w - stp ), y, buf, stp, h, ptch );
	    Bitblt_xy_to_xy( x, y, ( x + stp ), y, ( w - stp ), h );
	    Bitblt_linear_to_xy( buf, x, y, stp, h, ptch );
            break;
        }
        case UP :
        {
	    Bitblt_xy_to_linear( x, y, buf, w, stp, ptch );
	    Bitblt_xy_to_xy( x, ( y + stp ), x, y, w, ( h - stp ));
	    Bitblt_linear_to_xy( buf, x, ( y + h - stp ), w, stp, ptch );
            break;
        }
        case DOWN :
        {
	    Bitblt_xy_to_linear( x, ( y + h - stp ), buf, w, stp, ptch );
	    Bitblt_xy_to_xy( x, y, x, ( y + stp ), w, ( h - stp ));
	    Bitblt_linear_to_xy( buf, x, y, w, stp, ptch );
            break;
        }
    }
}

/*-----------------------------------------------------------------------*/
