我正在尝试加载并在屏幕上绘制一个16色位图。我有一个加载它的功能和另一个用于绘制位图的功能。但是,在尝试绘制位图时,我将所有像素都变为白色。
我想我的调色板可能有问题。谁能告诉我我的调色板信息是否正确或者我的装载或绘图方法有问题吗?
加载位图:
typedef struct {
word width;
word height;
byte pallete[256 * 3];
byte *data;
} BITMAP;
/**************************************************************************
* load_bmp *
* Loads a bitmap file into memory. *
**************************************************************************/
void load_bmp(char *file, BITMAP *b) {
FILE *fp;
long index;
byte a;
word num_colors;
int x;
//SetGfxMode(0x3);
/* Opening file */
if ((fp = fopen(file,"rb")) == NULL) {
printf("Error al abrir el archivo %s.\n", file);
exit(1);
}
/* Validating if the image is a valid bitmap */
if (fgetc(fp) != 'B' || fgetc(fp) != 'M') {
fclose(fp);
printf("%s is not a bitmap file. \n", file);
exit(1);
}
/* Height and width of the image */
fskip(fp, 16);
fread(&b->width, sizeof(word), 1, fp);
fskip(fp, 2);
fread(&b->height, sizeof(word), 1, fp);
fskip(fp, 22);
fread(&num_colors, sizeof(word), 1, fp);
fskip(fp, 6);
/* We are loading a 16 color image */
if (num_colors == 0)
num_colors = 16;
/* Intentamos alojar memoria para la data del bitmap */
if ((b->data = (byte *)malloc((word)(b->width * b->height))) == NULL) {
fclose(fp);
printf("Error allocating memory for file %s.\n", file);
exit(1);
}
/* Reading palette info */
for (index = 0; index < num_colors; index++) {
b->pallete[(int)(index*3+2)] = fgetc(fp) >> 2;
b->pallete[(int)(index*3+1)] = fgetc(fp) >> 2;
b->pallete[(int)(index*3+0)] = fgetc(fp) >> 2;
x = fgetc(fp);
}
/* Leyendo el bitmap */
for (index = (b->height - 1) * b->width; index >= 0; index -= b->width) {
for (x = 0; x < b->width; x++) {
a = fgetc(fp);
//printf("%d",a);
//getch();
b->data[(word)(index + x)] = a;
}
}
fclose(fp);
}
绘制位图:
/**************************************************************************
* draw_transparent_bitmap *
* Draws a transparent bitmap. *
**************************************************************************/
void draw_transparent_bitmap(BITMAP *bmp, int x, int y) {
int i, j;
word bitmap_offset = 0;
byte data;
for (j = 0; j < bmp->height; j++) {
for (i = 0; i < bmp->width; i++, bitmap_offset++) {
data = bmp->data[bitmap_offset];
/* Pintando en pantalla */
if (data)
plot_pixel(x + i, j + y, data);
}
}
}
修改
更多信息:我使用12h模式16色VGA:
这是我的video_set和绘图像素函数:
void SetGfxMode(int mode)
{
__dpmi_regs regs;
memset(®s,0, sizeof(regs));
regs.x.ax=mode;
//regs.x.ax=0xD; //screen mode (EGA)
//regs.x.ax=0x13; //screen mode (VGA)
__dpmi_int(0x10,®s);
//_farsetsel(_dos_ds);
VGA=(byte *)0xA0000 + __djgpp_conventional_base;
unsigned char weird_number=(SCREEN_WIDTH/8);
for (int x=0; x<SCREEN_WIDTH; x++)
{
for (int y=0; y<SCREEN_HEIGHT; y++)
{
setpixel_i[x][y] = y*weird_number + x/8; /* Memory Location */
}
setpixel_b[x] = (0x80)>>(x%8); /* compute Bit Mask */
}
return;
}
Plot Pixel:
typedef unsigned char byte;
byte * VGA;
long int setpixel_i[SCREEN_WIDTH][SCREEN_HEIGHT];
unsigned char setpixel_b[SCREEN_WIDTH];
long int setpixel_ti;
byte double_buffer[SCREEN_SIZE];
unsigned char setpixel_tb;
void plot_pixel(int x, int y, int col)
{
#ifdef SCREEN_SAFE
if ((x<0) && (x>=SCREEN_WIDTH) && (y<0) && (y>=SCREEN_HEIGHT))
{return;}
#endif
//char far *screen = (char far *)0xA0000000; //djgpp doesn't understand far for some reason, maybe it's just me! heh
//long int i;
//unsigned char b;
outp(0x3ce,0x05); /* Graphics Mode */
outp(0x3cf,0x02); /* Write Mode 2 */
setpixel_ti=setpixel_i[x][y];
setpixel_tb=setpixel_b[x];
//i = y*40 + x/8; /* Memory Location */
//b = (0x80)>>(x%8); /* compute Bit Mask */
outp(0x3ce,0x08); /* Bit Mask Register */
outp(0x3cf,setpixel_tb); /* Bit Mask */
outp(0x3ce,0x03); /* Function Select Register */
outp(0x3cf,0x00); /* Replace Pixel */
setpixel_tb = VGA[setpixel_ti]; /* Dummy Read to refresh latch registers (THIS IS *VERY* IMPORTANT)*/
VGA[setpixel_ti] = col; /* Set Pixel */
}
设置托盘:
void set_pallete(byte *pallete){
int i;
outp(PALETTE_INDEX,0);
for(i=0;i<16*3;i++){
outp(PALETTE_DATA,pallete[i]);
}
}
Fskip
void fskip(FILE *fp, int num_bytes){
int i;
for(i=0; i<num_bytes; i++){
fgetc(fp);
}
}
主要
load_bmp("home16.bmp",&fondo_inicio);
set_pallete(fondo_inicio.pallete);
draw_transparent_bitmap(&fondo_inicio,0,0);