//------------------------------------------------------------------- // animate3.cpp // // programmer: ALLAN CRUSE // written on: 01 OCT 2003 //------------------------------------------------------------------- #include // for printf(), perror() #include // for open() #include // for exit() #include // for read(), write(), close() #include // for mman() #include // for tcgetattr(), tcsetattr() #define VRAM_BASE_ADDRESS 0xA0000000 #define VGA_MEMORY_LENGTH ( 4 << 20) unsigned char *vram = (unsigned char*)VRAM_BASE_ADDRESS; const int display_mode = 0x4101, hres = 640, vres = 480; void draw_segments( int x, int y, int xcent, int ycent, int color ) { int minx = 0, miny = 0, maxx = hres-1, maxy = vres-1; int xlo, xhi, v, h; xlo = xcent-x, xhi = xcent+x; if ( xlo < minx ) xlo = minx; if ( xhi > maxx ) xhi = maxx; if ( ( v = ycent-y ) >= miny ) for (h = xlo; h <= xhi; h++) vram[ v*hres + h ] = color; if ( ( v = ycent+y ) <= maxy ) for (h = xlo; h <= xhi; h++) vram[ v*hres + h ] = color; xlo = xcent-y, xhi = xcent+y; if ( xlo < minx ) xlo = minx; if ( xhi > maxx ) xhi = maxx; if ( ( v = ycent-x ) >= miny ) for (h = xlo; h <= xhi; h++) vram[ v*hres + h ] = color; if ( ( v = ycent+x ) <= maxy ) for (h = xlo; h <= xhi; h++) vram[ v*hres + h ] = color; } void fill_circle( int x, int y, int radius, int color ) { int xcent = x, ycent = y, decis = 3 - 2*radius; y = radius, x = 0; while ( x <= y ) { draw_segments( x, y, xcent, ycent, color ); if ( decis < 0 ) { decis += 4*x + 6; ++x; } else { decis += 4*(x - y) + 10; --y; ++x; } } } void map_system_memory( int base, int size ) { int prot = PROT_READ | PROT_WRITE; int flag = MAP_FIXED | MAP_SHARED; void *mm = (void*)base; int fd = open( "/dev/vram", O_RDWR ); if ( fd < 0 ) { perror( "/dev/vram" ); exit(1); } if ( mmap( mm, size, prot, flag, fd, 0 ) == MAP_FAILED ) { perror( "mmap" ); exit(1); } close( fd ); } int main( int argc, char **argv ) { struct termios otty; tcgetattr( 0, &otty ); struct termios tty = otty; tty.c_lflag &= ~( ECHO | ICANON | ISIG ); tty.c_cc[ VMIN ] = 1; tty.c_cc[ VTIME ] = 0; tcsetattr( 0, TCSAFLUSH, &tty ); // map video memory into application's address-space system( "/sbin/insmod vram.o" ); map_system_memory( VRAM_BASE_ADDRESS, VGA_MEMORY_LENGTH ); // enter graphics mode char command[ 40 ]; sprintf( command, " clear ; mode3 %d ", display_mode ); system( command ); // loop to draw several filled circles int fgcolor = 14, bgcolor = 0, r = vres/16; int x = hres/8, y = vres/4; for (int i = 0; i < 4; i++) { fill_circle( x, y, r, fgcolor ); getchar(); x += hres/4; } // this loop superimposes a triangle on one of the circles x -= hres/4; for (int v = 0; v <= r; v++) for (int h = v+x; h <= x+r; h++) { vram[ (y-v)*hres + h ] = bgcolor; vram[ (y+v)*hres + h ] = bgcolor; } getchar(); // this loop superimposes a narrower triangle on another circle x -= hres/4; for (int v = 0; v <= r; v++) for (int h = v+v+x; h <= x+r; h++) { vram[ (y-v)*hres + h ] = bgcolor; vram[ (y+v)*hres + h ] = bgcolor; } getchar(); // this loop superimposes a still narrower triangle on another circle x -= hres/4; for (int v = 0; v <= r; v++) for (int h = v+v+v+v+x; h <= x+r; h++) { vram[ (y-v)*hres + h ] = bgcolor; vram[ (y+v)*hres + h ] = bgcolor; } getchar(); // build the array of sprite x-locations int sprite[ 8 ] = {0}; sprite[ 0 ] = 0*(hres/4); sprite[ 1 ] = 1*(hres/4); sprite[ 2 ] = 2*(hres/4); sprite[ 3 ] = 3*(hres/4); sprite[ 4 ] = 3*(hres/4); sprite[ 5 ] = 2*(hres/4); sprite[ 6 ] = 1*(hres/4); sprite[ 7 ] = 0*(hres/4); // start the bitblt loop to cycle through the sprite-array int dstx = 0, dsty = vres/2; int srcx = 0, srcy = 0; int i = 0; while ( i < 256 ) { srcx = sprite[ i%8 ]; dstx += 2; for (int v = 0; v <= vres/2; v++) for (int h = 0; h <= hres/4; h++) vram[ (dsty+v)*hres + dstx+h ] = vram[ (srcy+v)*hres + srcx+h ]; getchar(); ++i; } getchar(); // leave graphics mode system( "mode3 3" ); tcsetattr( 0, TCSAFLUSH, &otty ); }