//------------------------------------------------------------------- // hiviewer.cpp (A revision of our 'myviewer.cpp' demo) // // This is a possible answer to Question V on Midterm Exam II. // // This program presently displays the graphics image captured // in a file named "captured.img". Your job is to modify this // program so that the displayed image will be reduced in size // from 1024-by-768 to 512-by-384 (i.e., half as wide and half // as high as the original screen-image). You should draw the // smaller-sized image so that it is 'centered' on the screen. // // compile using: $ g++ shrinker.cpp int86.cpp -o shrinker // // NOTE: It is unnecessary to download the 'captured.img' file // from our class website when you are logged in to one of the // computer science department's workstations because the file // can be directly accessed via the local network file-system. // // programmer: ALLAN CRUSE // written on: 03 NOV 2005 //------------------------------------------------------------------- #include // for perror() #include // for open() #include // for exit() #include // for lseek() #include // for mmap() #include "int86.h" // for init8086(), int86() short *vram = (short*)0xA0000000; int vesa_mode = 0x4117, hres = 1024, vres = 768; struct vm86plus_struct vm; char imgname[] = "/home/web/cruse/cs686/captured.img"; int main( int argc, char **argv ) { // memory-map the image-data file into user-space int bmp = open( imgname, O_RDONLY ); if ( bmp < 0 ) { perror( imgname ); exit(1); } int sz = lseek( bmp, 0, SEEK_END ); int *img = (int*)mmap( NULL, sz, PROT_READ, MAP_PRIVATE, bmp, 0 ); if ( img == MAP_FAILED ) { perror( "mmap" ); exit(1); } // memory-map the video display-memory into user-space int vd = open( "/dev/vram", O_RDWR ); if ( vd < 0 ) { perror( "/dev/vram" ); exit(1); } int size = lseek( vd, 0, SEEK_END ); int prot = PROT_READ | PROT_WRITE; int flag = MAP_FIXED | MAP_SHARED; if ( mmap( (void*)vram, size, prot, flag, vd, 0 ) == MAP_FAILED ) { perror( "mmap" ); exit(1); } // enter graphics mode init8086(); vm.regs.eax = 0x4F02; vm.regs.ebx = vesa_mode; int86( 0x10, vm ); // here we transfer this memory-mapped image to the visible screen for (int y = 0; y < vres; y++) for (int x = 0; x < hres; x++) { // fetch the next pixel from the image-file int src_index = y * hres + x; int pel = img[ src_index ]; // convert this truecolor pixel to hicolor format int blue = (pel>>0)&0xFF; int green = (pel>>8)&0xFF; int red = (pel>>16)&0xFF; blue >>=3; green >>= 2; red >>= 3; pel = (red<<11)|(green<<5)|(blue<<0); // store this pixel to video display memory int dst_index = y * hres + x; vram[ dst_index ] = pel; } // wait until the user has finished viewing your displayed image getchar(); // leave graphics mode vm.regs.eax = 0x0003; int86( 0x10, vm ); printf( "\n" ); }