struct RGBQUAD {
unsigned char rgbBlue;
unsigned char rgbGreen;
unsigned char rgbRed;
unsigned char rgbReserved;
};
struct BITMAPFILEHEADER {
unsigned short int bfType;
unsigned long bfSize;
unsigned short int bfReserved1;
unsigned short int bfReserved2;
unsigned long bfOffBits;
};
struct BITMAPINFOHEADER {
unsigned long biSize;
long biWidth;
long biHeight;
unsigned short int biPlanes;
unsigned short int biBitCount;
unsigned long biCompression;
unsigned long biSizeImage;
long biXPelsPerMeter;
long biYPelsPerMeter;
unsigned long biClrUsed;
unsigned long biClrImportant;
};
RGBQUAD get_ega_color( int color ) {
RGBQUAD v;
v.rgbReserved = 0;
switch ( color ) {
case BLACK: v.rgbRed = 0; v.rgbGreen=0; v.rgbBlue=0; break;
case BLUE: v.rgbRed = 0; v.rgbGreen=0; v.rgbBlue=128; break;
case GREEN: v.rgbRed = 0; v.rgbGreen=128; v.rgbBlue=0; break;
case CYAN: v.rgbRed = 0; v.rgbGreen=128; v.rgbBlue=128; break;
case RED: v.rgbRed = 128; v.rgbGreen=0; v.rgbBlue=0; break;
case MAGENTA: v.rgbRed = 128; v.rgbGreen=0; v.rgbBlue=128; break;
case BROWN: v.rgbRed = 128; v.rgbGreen=64; v.rgbBlue=0; break;
case LIGHTGRAY: v.rgbRed = 128; v.rgbGreen=128; v.rgbBlue=128; break;
case DARKGRAY: v.rgbRed = 64; v.rgbGreen=64; v.rgbBlue=64; break;
case LIGHTBLUE: v.rgbRed = 0; v.rgbGreen=0; v.rgbBlue=255; break;
case LIGHTGREEN: v.rgbRed = 0; v.rgbGreen=255; v.rgbBlue=0; break;
case LIGHTCYAN: v.rgbRed = 0; v.rgbGreen=255; v.rgbBlue=255; break;
case LIGHTRED: v.rgbRed = 255; v.rgbGreen=0; v.rgbBlue=0; break;
case LIGHTMAGENTA: v.rgbRed = 255; v.rgbGreen=0; v.rgbBlue=255; break;
case YELLOW: v.rgbRed = 255; v.rgbGreen=255; v.rgbBlue=0; break;
case WHITE: v.rgbRed = 255; v.rgbGreen=255; v.rgbBlue=255; break;
}
return v;
}
void save_ega_screen( char * lpFile ) {
int nWidth = getmaxx() + 1;
int nHeight = getmaxy() + 1;
FILE * pFile = fopen( lpFile, "wb" );
// save bitmap file header
BITMAPFILEHEADER fileHeader;
fileHeader.bfType = 0x4d42;
fileHeader.bfSize = 0;
fileHeader.bfReserved1 = 0;
fileHeader.bfReserved2 = 0;
fileHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + 16*sizeof(RGBQUAD);
fwrite( (char*)&fileHeader, sizeof(fileHeader), 1, pFile );
// save bitmap info header
BITMAPINFOHEADER infoHeader;
infoHeader.biSize = sizeof(infoHeader) ;
infoHeader.biWidth = nWidth;
infoHeader.biHeight = nHeight;
infoHeader.biPlanes = 1;
infoHeader.biBitCount = 4;
infoHeader.biCompression = 0; // BI_RGB
infoHeader.biSizeImage = 0;
infoHeader.biXPelsPerMeter = 0;
infoHeader.biYPelsPerMeter = 0;
infoHeader.biClrUsed = 16;
infoHeader.biClrImportant = 16;
fwrite( (char*)&infoHeader, sizeof(infoHeader), 1, pFile );
// palette output
RGBQUAD palette[16];
memset( &palette[0], 16*sizeof(RGBQUAD), 0 );
for (long clr=0; clr<16; clr ++ ) {
palette[ clr ] = get_ega_color( clr );
}
fwrite( (char*)(&palette), 1, 16*sizeof(RGBQUAD), pFile );
// raster output
int maxx = (getmaxx()+1) / 2;
int maxy = (getmaxy()+1);
for ( int y = maxy; y <= 0; y -- ) {
for ( int x = 0; x<maxx; x++ ) {
// we will place 2 pixels into one byte
unsigned char pix1 = getpixel( x*2, y );
unsigned char pix2 = getpixel( x*2 + 1, y );
unsigned char temp = pix2 | (pix1<<4);
fwrite( &temp, sizeof( temp ), 1, pFile );
}
}
fclose ( pFile );
}