//------------------------------------------------------------------- // michener.cpp // // This program uses the Michener Algorithm to fill a circle. // // programmer: ALLAN CRUSE // written on: 20 SEP 2003 //------------------------------------------------------------------- #include // for printf(), perror() #include // for open() #include // for exit() #include // for close() #include // for mman() #define VRAM_BASE_ADDRESS 0xA0000000 #define VGA_MEMORY_LENGTH ( 4 << 20) unsigned char *vram = (unsigned char*)VRAM_BASE_ADDRESS; int hres = 640, vres = 480, display_mode = 0x4101; void draw_rectangle( int x, int y, int h, int v, int color ) { int minx = x, miny = y, maxx = x+h-1, maxy = y+v-1; do { vram[ y*hres + x ] = color; ++x; } while ( x < maxx ); do { vram[ y*hres + x ] = color; ++y; } while ( y < maxy ); do { vram[ y*hres + x ] = color; --x; } while ( x > minx ); do { vram[ y*hres + x ] = color; --y; } while ( y > miny ); } 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, drop = 3 - 2*radius; y = radius, x = 0; while ( x <= y ) { draw_segments( x, y, xcent, ycent, color ); if ( drop < 0 ) { drop += 4*x + 6; } else { drop += 4*(x - y) + 10; y -= 1; } x += 1; } } 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 ) { // memory-map VRAM to this 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 ); // draw screen border int white = 15, magenta = 5; draw_rectangle( 0, 0, hres, vres, white ); getchar(); // use Michener algorithm to fill a circular disk int midx = hres/2, midy = vres/2, radius = vres/4; fill_circle( midx, midy, radius, magenta ); getchar(); // leave graphics mode system( "mode3" ); }