RESPUESTA A LA PREGUNTA 8491 - C/Visual C Pero te voy a decir que un BMP ocupa demasiado, amenos que tenga la compresión RLE ( Run Lenght Encoded), por eso te recomiendo que cargues mejor un archivo gráfico PCX, ya que en este formato, por defecto ya viene con compresión RLE, por lo tanto ocupa menos que un BMP, aunque los 2 tuvieran la misma imagen. Es por eso que en mi página WEB ( ver firma ) no he puesto información sobre como cargar el BMP, solo he puesto información para cargar los PCX's. Por cierto en mi página encontrarás una rutina para cargar un PCX con la BGI ( svga256.bgi )de Borland C++, es decir con las rutinas de graphics.h, asi como también una rutina para cargar el PCX en la VGA en la resolución estándar de 320x200. Aunque muy pronto publicaré una rutina para cargar BMP's , PCX's, GIF's, JPG's con la BGI de borland C++ en modo diferentes modos VGA y SVGA , preferentemente el true Color (16 millones de colores ) y a cualquier resolución, preferentemente será 800x600 píxeles. Solo como comentario lo que lo voy a hacer en C++, utilizando herencia es decir que cada formato gráfico ( CPCX, CBMP, CGIF, CJPG ) será una clase hija de la clase base CImagen, y encapsulando todas las funciones tengo pensado crear una librería de carga de gráficos para Borland C++, como CImagen.lib para uso gratuito, con esta librería no solo se podrá visualizar un archivo gráfico, sino también se podrá crearlo. Volviendo a lo de los BMP, para ver como funciona el programa adjunto, te recomiendo que luego de crear el EXE, crees 2 archivos BMP de 256 colores y con un tamaño menor a 320x200 y guárdalos con el nombre prueba.bmp y krat.bmp y los copies en la misma carpeta donde se encuentra el EXE. Al ejecutar el programa veras que los 2 BMP's se cargan superponiéndose uno encima de otro, primero en una resolución de 320x200 ( Modo VGA ) y luego lo mismo pero en una resolución de 640x480 ( Modo VESA SVGA ). Por último, el código está un poco desordenado, pero es que no le he dado mantenimiento, ni he tenido tiempo de retocarlo, pero creo que se entiende. Una cosa importante es que no corras el programa desde el IDE (Entorno de programación ) de tu compilador, ya que el programa necesita como mínimo 64K libres, asi que si lo haces puedes colgar tu PC, ya que el IDE ocupa gran parte de esta memoria. Solo corre el EXE!!! Aquí te envió la rutina para cargar BMP's: /*************************************************************************** ***********/ #include #include #include #include #include #include #include #define INPUT_STATUS_1 0x03da #define VRETRACE 0x08 class VIDEO { public: unsigned char far *vga; VIDEO(); ~VIDEO(); void pixel(int x, int y, unsigned char color); void linea(int x1, int y1, int x2, int y2, unsigned char color); void limpiar(unsigned char color); void desplegar(); }; unsigned char far *vga_mem = (unsigned char far *) 0xA0000000L; void modo_grafico(int); void modo_texto(); VIDEO::VIDEO() { //0xff ff vga=(unsigned char far*)farmalloc(sizeof(unsigned char far)*64000); } VIDEO::~VIDEO() { farfree(vga); } void VIDEO::pixel(int x, int y, unsigned char color) { if (x>=0 && x<320 && y>=0 && y<200) vga[(y<<8)+(y<<6)+x]=color; } void VIDEO::linea(int x1, int y1, int x2, int y2, unsigned char color) { int i,dx,dy,sdx=0,sdy=1,dxabs,dyabs,x,y,px,py; x1=160+x1*200; x2=160+x2*200; y1=100-y1*200; y2=100-y2*200; dx=x2-x1; dy=y2-y1; dxabs=abs(dx); dyabs=abs(dy); if (dx) sdx=dx/dxabs; if (dy) sdy=dy/dyabs; x=dyabs>>1; y=dxabs>>1; px=x1; py=y1; // vga[(py<<8)+(py<<6)+px]=color; pixel(px,py,color); if (dxabs>=dyabs) { for(i=0;i=dxabs) { y-=dxabs; py+=sdy; } px+=sdx; // vga[(py<<8)+(py<<6)+px]=color; pixel(px,py,color); } } else { for (i=0;i=dyabs); { x-=dyabs; px+=sdx; } py+=sdy; // vga[(py<<8)+(py<<6)+px]=color; pixel(px,py,color); } } } void VIDEO::limpiar(unsigned char color) { for (unsigned int i=0;i<0xffff;i++) vga[i]=color; } void VIDEO::desplegar() { // while ((inp(INPUT_STATUS_1) & VRETRACE)); // retraso vertical // while (!(inp(INPUT_STATUS_1) & VRETRACE)); _fmemcpy(vga_mem,vga,65000); } void modo_grafico(int modo) { if( modo==0 )_AX=0x00013; else { _AX=0x4f02; _BX=0x101; } geninterrupt(0x10); } void modo_texto() { _AX=0x0003; geninterrupt(0x10); } void putpixel(unsigned int x,unsigned int y,unsigned char color) { asm mov ah,0x0c; asm mov al,color; asm mov cx,x; asm mov dx,y; asm mov bx,0x01; asm int 0x10; asm{ mov ah,0x0c; mov al,color; mov cx,x; mov dx,y; mov bx,0x01; int 0x10; } } /* #endif #define VIDEO_INT 0x10 // interruptor de video #define VGA_256_COLOR_MODE 0x13 // para los 256 colores #define SET_MODE 0x00 // funcion de bios para modo de video #define TEXT_MODE 0x03 // modo texto */ //#define ANCHO_PANTALLA 320 //#define ALTO_PANTALLA 200 //#define NUM_COLORS 256 #define PALETTE_INDEX 0x03c8 #define PALETTE_DATA 0x03c9 #define NO_TRANSPARENCIA 0 #define TRANSPARENCIA 1 class BMP { protected: unsigned char far *bitmap; unsigned char far paleta[256*3]; void fskip(FILE *fp, int n); public: //CABECERA //#bytes char tipo[2]; //2 unsigned long tamano; //4 char reservado[4]; //4 unsigned long desplazamiento; //4 //Total: 14 bytes //INFORMACION DEL BMP //#bytes unsigned long bytes_en_cabecera; //4 unsigned long ancho; //4 unsigned long alto; //4 int planos; //2 int bits_por_pixel; //2 unsigned long compresion; //4 unsigned long tamano_de_imagen; //4 unsigned long resolucion_h; //4 unsigned long resolucion_v; //4 unsigned long n_indices; //4 retorna el numero de colores de la paleta unsigned long n_i_indices; //4 //Total: 40 bytes ~BMP(); int abrir(char *nom); void asign_paleta(); void rotar_paleta(); void dibujar(VIDEO &video,int x,int y); void dibujarppp(int x,int y); void pintar(); }; /* Información sobre la cabecera de un BMP por Fabian Sierra, extraida de www.lawebdelprogrmador.com: tipo es un 'número mágico' que se usa para comprobar que el archivo es .bmp. tamano es el tamaño del archivo bmp incluyendo la cabecera y bmp_info reservado no se usa normalmente (por lo menos hasta el año pasado no se usaba). Desplazamiento es el desplazamiento de los datos con respecto al inicio del archivo. Es igual al tamaño de las estructuras de cabecera, cuando no hay paleta y cuando hay paleta se suman los bytes utilizados por la paleta. Bytes_en_cabecera es exactamente eso y a mí me parece un dato inútil. Planos es un campo que nunca he utilizado.Bits_por_pixel es importante; ya lo explicaré en detalle. Compresion... no tengo idea. Si me topo con un archivo con un valor anómalo en este campo,lo descarto. Los colores se generan en la pantalla usando una combinación de rojo,verde y azul. Al conjunto de combinaciones se le llama la paleta de colores. Un color es referenciado como un número.El rango del número depende de los bits usados para referenciarlo.Si es 1 bit,se permiten 2 colores. Si son 4,16,etc. Para cada pixel se especifica su color.Entonces, el campo bits_por_pixel indica cuántos bits representan un pixel en la pantalla. Si vas leyendo pixel a pixel... Inmediatamente después de ambas cabeceras comienza la especificación de qué componentes de rojo,verde y azul se usarán para cada color. El tamaño de esta sección se calcula sabiendo el número de colores y que se utilizan 4 bytes para especificar cada color;uno para el rojo,otro para el verde y otro para el azul; el otro no se utiliza, no sé por qué. Debes usar setpalette para especificar la paleta a usar. Dos datos.Los colores están invertidos en la paleta;primero el azul y al final el rojo. Los pixels están en orden inverso;comienzan en la última línea. */ BMP::~BMP() { if (bitmap) farfree(bitmap); } int BMP::abrir(char *nom) { FILE *fp; if ((fp=fopen(nom,"rb"))==NULL) return 0; //LEE LA CABECERA fread(&tipo,sizeof(unsigned int), 1, fp); fread(&tamano,sizeof(unsigned long), 1, fp); fread(&reservado,sizeof(unsigned long), 1, fp); fread(&desplazamiento,sizeof(unsigned long), 1, fp); //LEE INFO DEL BMP fread(&bytes_en_cabecera,sizeof(unsigned long), 1, fp); fread(&ancho,sizeof(unsigned long), 1, fp); fread(&alto,sizeof(unsigned long), 1, fp); fread(&planos,sizeof(unsigned int), 1, fp); fread(&bits_por_pixel,sizeof(unsigned int), 1, fp); fread(&compresion,sizeof(unsigned long), 1, fp); fread(&tamano_de_imagen,sizeof(unsigned long), 1, fp); fread(&resolucion_h,sizeof(unsigned long), 1, fp); fread(&resolucion_v,sizeof(unsigned long), 1, fp); fread(&n_indices,sizeof(unsigned long), 1, fp); fread(&n_i_indices,sizeof(unsigned long), 1, fp); if (n_indices==0 && bits_por_pixel==8) n_indices=256; for(int i=0;i> 2; paleta[i*3+1] = fgetc(fp) >> 2; paleta[i*3+0] = fgetc(fp) >> 2; fgetc(fp); } bitmap = (unsigned char far *) farmalloc(sizeof(unsigned char far)*(ancho)*(alto)); int ex_ancho=(4-ancho%4)%4,k; for (int j=alto-1;j>=0;j--) { for(i=0;i