// // WINDY.C // // Yet more frame buffer doodlings....someone might find some of this useful..... // // Richard Cutting // // http://www.netyaroze-europe.com/~rcutting // richard.cutting@virgin.net // #include typedef struct { unsigned long *block; int dx,dy,x,y,in_use,x_inc,y_inc,error,orig_x,orig_y,index; } BLOCK_type; #define WINDY 0x80090000 #define MAX_X 320 #define MAX_Y 240 extern DISPENV GsDISPENV; #define INC 1 BLOCK_type *split_image( int cell_w, int cell_h ) { register int x,y,delta,delta_x,delta_y,delta_z; RECT z; BLOCK_type *blocks; register BLOCK_type *p_block; z.w = cell_w; z.h = cell_h; delta = cell_w * cell_h; delta_x = MAX_X / cell_w; delta_y = MAX_Y / cell_h; delta_z = delta_x * delta_y; blocks = ( BLOCK_type * ) malloc( delta_z * sizeof( BLOCK_type ) ); p_block = blocks; for ( x = 0; x < MAX_X; x += cell_w ) { for ( y = 0; y < MAX_Y; y += cell_h ) { z.x = x; z.y = y; p_block->block = ( unsigned long * ) malloc( delta * sizeof( unsigned long ) ); StoreImage( &z, p_block->block ); p_block->x = x; p_block->y = y; p_block->in_use = 1; p_block++; } } return( blocks ); } void init_block_suck( BLOCK_type *p_block, int delta ) { register int i,j; register BLOCK_type *pr_block; for ( i = 0, pr_block = p_block; i < delta; i++, pr_block++ ) { pr_block->dx = pr_block->x; pr_block->dy = pr_block->y; pr_block->orig_x = pr_block->x; pr_block->orig_y = pr_block->y; if ( pr_block->dx >= 0 ) { pr_block->x_inc = -INC; } else { pr_block->x_inc = INC; pr_block->dx = -pr_block->dx; } if ( pr_block->dy >= 0 ) { pr_block->y_inc = -INC; } else { pr_block->y_inc = INC; pr_block->dy = -pr_block->dy; } pr_block->error = 0; pr_block->index = 0; } } void block_suck( int cell_w, int cell_h, int clear_flag ) { register int delta, dx, dy, x_inc, y_inc, error, j, i, x, y; register BLOCK_type *p_block; BLOCK_type *blocks; RECT rect; unsigned long *black; // Initialise rect.w = cell_w; rect.h = cell_h; if ( clear_flag ) { black = ( unsigned long * ) malloc( ( cell_w * cell_h ) * sizeof( unsigned long ) ); memset( black, 0, ( cell_w * cell_h ) * sizeof( unsigned long ) ); } delta = MAX_X / cell_w * MAX_Y / cell_h; blocks = split_image( cell_w, cell_h ); init_block_suck( blocks, delta ); while( 1 ) { i = 0; for ( j = 0, p_block = blocks; j < delta; j++, p_block++ ) { dx = p_block->dx; dy = p_block->dy; error = p_block->error; x_inc = p_block->x_inc; y_inc = p_block->y_inc; x = p_block->x; y = p_block->y; if ( dx > dy ) { if ( p_block->index > dx ) { i++; } else { error += dy; if ( error > dx ) { error -= dx; p_block->y += y_inc; } p_block->x += x_inc; p_block->index++; } } else { if ( p_block->index > dy ) { i++; } else { error += dx; if ( error > 0 ) { error -= dy; p_block->x += x_inc; } p_block->y += y_inc; p_block->index++; } } p_block->error = error; if ( clear_flag ) { rect.x = x; rect.y = y; LoadImage( &rect, black ); } rect.x = p_block->x; rect.y = p_block->y; LoadImage( &rect, p_block->block ); } VSync( 0 ); GsSwapDispBuff(); if ( i == delta ) { if ( clear_flag ) { free( black ); } for ( i = 0, p_block = blocks; i < delta; i++, p_block++ ) { free( p_block->block ); free( p_block ); } return; } } } main() { RECT vscr; GsIMAGE im; BLOCK_type *blocks; SetVideoMode( MODE_PAL ); GsInitGraph( 320, 240, 4, 0, 0 ); GsDefDispBuff( 0, 0, 0, 0 ); vscr.x = 320; vscr.y = 0; vscr.h = 240; vscr.w = 320; GsGetTimInfo(((u_long *)WINDY)+1, &im); LoadImage( &vscr, im.pixel ); MoveImage( &vscr, 0, 0 ); DrawSync(0); VSync(0); GsSwapDispBuff(); block_suck( 16, 16, 1 ); ResetGraph( 0 ); }