- added palette for 8 bpp support

(TODO: support for standard VGA 4 bit mode - saving as 8 bpp BMP)
This commit is contained in:
Volker Ruppert 2011-08-05 15:47:33 +00:00
parent 20becdfbe7
commit c7f63fca93
7 changed files with 100 additions and 70 deletions

View File

@ -417,8 +417,9 @@ void bx_gui_c::copy_handler(void)
void bx_gui_c::snapshot_handler(void)
{
int fd, i, j, mode, pitch;
Bit8u *snapshot_ptr = NULL, *row_buffer, *pixel_ptr, *row_ptr;
Bit8u bmp_header[54], iBits, b1, b2;
Bit8u *snapshot_ptr = NULL, *palette_ptr = NULL;
Bit8u *row_buffer, *pixel_ptr, *row_ptr;
Bit8u bmp_header[54], pal_entry[4], iBits, b1, b2;
Bit32u ilen, len, rlen;
char filename[BX_PATHNAME_LEN];
unsigned iHeight, iWidth, iDepth;
@ -442,7 +443,7 @@ void bx_gui_c::snapshot_handler(void)
fclose(fp);
free(snapshot_ptr);
} else if (mode == BX_GUI_SNAPSHOT_GFX) {
ilen = DEV_vga_get_gfx_snapshot(&snapshot_ptr, &iHeight, &iWidth, &iDepth);
ilen = DEV_vga_get_gfx_snapshot(&snapshot_ptr, &palette_ptr, &iHeight, &iWidth, &iDepth);
BX_INFO(("GFX snapshot: %u x %u x %u bpp (%u bytes)", iWidth, iHeight, iDepth, ilen));
if (BX_GUI_THIS dialog_caps & BX_GUI_DLG_SNAPSHOT) {
int ret = SIM->ask_filename (filename, sizeof(filename),
@ -466,65 +467,71 @@ void bx_gui_c::snapshot_handler(void)
free(snapshot_ptr);
return;
}
if (iDepth != 8) {
iBits = (iDepth == 8) ? 8 : 24;
rlen = (iWidth * (iBits >> 3) + 3) & ~3;
len = rlen * iHeight + 54;
memset(bmp_header, 0, 54);
bmp_header[0] = 0x42;
bmp_header[1] = 0x4d;
bmp_header[2] = len & 0xff;
bmp_header[3] = (len >> 8) & 0xff;
bmp_header[4] = (len >> 16) & 0xff;
bmp_header[5] = (len >> 24) & 0xff;
bmp_header[10] = 54;
bmp_header[14] = 40;
bmp_header[18] = iWidth & 0xff;
bmp_header[19] = (iWidth >> 8) & 0xff;
bmp_header[22] = iHeight & 0xff;
bmp_header[23] = (iHeight >> 8) & 0xff;
bmp_header[26] = 1;
bmp_header[28] = iBits;
write(fd, bmp_header, 54);
// TODO: palette for 8 bpp
pitch = iWidth * ((iDepth + 1) >> 3);
row_buffer = (Bit8u*)malloc(rlen);
row_ptr = snapshot_ptr + ((iHeight - 1) * pitch);
for (i = iHeight; i > 0; i--) {
memset(row_buffer, 0, rlen);
if (iDepth == 24) {
memcpy(row_buffer, row_ptr, pitch);
} else if ((iDepth == 15) || (iDepth == 16)) {
pixel_ptr = row_ptr;
for (j = 0; j < (iWidth * 3); j+=3) {
b1 = *(pixel_ptr++);
b2 = *(pixel_ptr++);
*(row_buffer+j) = (b1 << 3);
if (iDepth == 15) {
*(row_buffer+j+1) = ((b1 & 0xe0) >> 2) | (b2 << 6);
*(row_buffer+j+2) = (b2 & 0x7c) << 1;
} else {
*(row_buffer+j+1) = ((b1 & 0xe0) >> 3) | (b2 << 5);
*(row_buffer+j+2) = (b2 & 0xf8);
}
}
} else if (iDepth == 32) {
pixel_ptr = row_ptr;
for (j = 0; j < (iWidth * 3); j+=3) {
*(row_buffer+j) = *(pixel_ptr++);
*(row_buffer+j+1) = *(pixel_ptr++);
*(row_buffer+j+2) = *(pixel_ptr++);
pixel_ptr++;
iBits = (iDepth == 8) ? 8 : 24;
rlen = (iWidth * (iBits >> 3) + 3) & ~3;
len = rlen * iHeight + 54;
memset(bmp_header, 0, 54);
bmp_header[0] = 0x42;
bmp_header[1] = 0x4d;
bmp_header[2] = len & 0xff;
bmp_header[3] = (len >> 8) & 0xff;
bmp_header[4] = (len >> 16) & 0xff;
bmp_header[5] = (len >> 24) & 0xff;
bmp_header[10] = 54;
bmp_header[14] = 40;
bmp_header[18] = iWidth & 0xff;
bmp_header[19] = (iWidth >> 8) & 0xff;
bmp_header[22] = iHeight & 0xff;
bmp_header[23] = (iHeight >> 8) & 0xff;
bmp_header[26] = 1;
bmp_header[28] = iBits;
write(fd, bmp_header, 54);
if ((iDepth == 8) && (palette_ptr != NULL)) {
pal_entry[3] = 0;
pixel_ptr = palette_ptr;
for (i = 0; i < 256; i++) {
pal_entry[0] = *(pixel_ptr++);
pal_entry[1] = *(pixel_ptr++);
pal_entry[2] = *(pixel_ptr++);
write(fd, pal_entry, 4);
}
}
pitch = iWidth * ((iDepth + 1) >> 3);
row_buffer = (Bit8u*)malloc(rlen);
row_ptr = snapshot_ptr + ((iHeight - 1) * pitch);
for (i = iHeight; i > 0; i--) {
memset(row_buffer, 0, rlen);
if ((iDepth == 8) || (iDepth == 24)) {
memcpy(row_buffer, row_ptr, pitch);
} else if ((iDepth == 15) || (iDepth == 16)) {
pixel_ptr = row_ptr;
for (j = 0; j < (int)(iWidth * 3); j+=3) {
b1 = *(pixel_ptr++);
b2 = *(pixel_ptr++);
*(row_buffer+j) = (b1 << 3);
if (iDepth == 15) {
*(row_buffer+j+1) = ((b1 & 0xe0) >> 2) | (b2 << 6);
*(row_buffer+j+2) = (b2 & 0x7c) << 1;
} else {
*(row_buffer+j+1) = ((b1 & 0xe0) >> 3) | (b2 << 5);
*(row_buffer+j+2) = (b2 & 0xf8);
}
}
write(fd, row_buffer, rlen);
row_ptr -= pitch;
} else if (iDepth == 32) {
pixel_ptr = row_ptr;
for (j = 0; j < (int)(iWidth * 3); j+=3) {
*(row_buffer+j) = *(pixel_ptr++);
*(row_buffer+j+1) = *(pixel_ptr++);
*(row_buffer+j+2) = *(pixel_ptr++);
pixel_ptr++;
}
}
free(row_buffer);
} else {
BX_ERROR(("snapshot button failed: GFX mode with %u bpp not implemented", iDepth));
write(fd, row_buffer, rlen);
row_ptr -= pitch;
}
free(row_buffer);
close(fd);
if (palette_ptr != NULL) free(palette_ptr);
free(snapshot_ptr);
} else {
BX_ERROR(("snapshot button failed: VGA mode not implemented"));

View File

@ -255,7 +255,7 @@ public:
unsigned *txHeight, unsigned *txWidth) {
STUBFUNC(vga, get_text_snapshot);
}
virtual Bit32u get_gfx_snapshot(Bit8u **snapshot_ptr,
virtual Bit32u get_gfx_snapshot(Bit8u **snapshot_ptr, Bit8u **palette_ptr,
unsigned *iHeight, unsigned *iWidth, unsigned *iDepth) {
STUBFUNC(vga, get_gfx_snapshot);
return 0;

View File

@ -829,8 +829,8 @@ void bx_svga_cirrus_c::get_text_snapshot(Bit8u **text_snapshot,
BX_CIRRUS_THIS bx_vga_c::get_text_snapshot(text_snapshot,txHeight,txWidth);
}
Bit32u bx_svga_cirrus_c::get_gfx_snapshot(Bit8u **snapshot_ptr, unsigned *iHeight,
unsigned *iWidth, unsigned *iDepth)
Bit32u bx_svga_cirrus_c::get_gfx_snapshot(Bit8u **snapshot_ptr, Bit8u **palette_ptr,
unsigned *iHeight, unsigned *iWidth, unsigned *iDepth)
{
Bit32u len, len1;
unsigned i;
@ -850,9 +850,18 @@ Bit32u bx_svga_cirrus_c::get_gfx_snapshot(Bit8u **snapshot_ptr, unsigned *iHeigh
src_ptr += BX_CIRRUS_THIS svga_pitch;
dst_ptr += len1;
}
if (*iDepth == 8) {
*palette_ptr = (Bit8u*)malloc(256 * 3);
dst_ptr = *palette_ptr;
for (i = 0; i < 256; i++) {
*(dst_ptr++) = (BX_CIRRUS_THIS s.pel.data[i].blue << 2);
*(dst_ptr++) = (BX_CIRRUS_THIS s.pel.data[i].green << 2);
*(dst_ptr++) = (BX_CIRRUS_THIS s.pel.data[i].red << 2);
}
}
return len;
} else {
return BX_CIRRUS_THIS bx_vga_c::get_gfx_snapshot(snapshot_ptr, iHeight, iWidth, iDepth);
return BX_CIRRUS_THIS bx_vga_c::get_gfx_snapshot(snapshot_ptr, palette_ptr, iHeight, iWidth, iDepth);
}
}

View File

@ -79,8 +79,8 @@ public:
virtual int get_snapshot_mode(void);
virtual void get_text_snapshot(Bit8u **text_snapshot,
unsigned *txHeight, unsigned *txWidth);
virtual Bit32u get_gfx_snapshot(Bit8u **snapshot_ptr, unsigned *iHeight,
unsigned *iWidth, unsigned *iDepth);
virtual Bit32u get_gfx_snapshot(Bit8u **snapshot_ptr, Bit8u **palette_ptr,
unsigned *iHeight, unsigned *iWidth, unsigned *iDepth);
virtual void trigger_timer(void *this_ptr);
virtual Bit8u get_actl_palette_idx(Bit8u index);
virtual void register_state(void);

View File

@ -2742,11 +2742,11 @@ void bx_vga_c::get_text_snapshot(Bit8u **text_snapshot, unsigned *txHeight,
}
}
Bit32u bx_vga_c::get_gfx_snapshot(Bit8u **snapshot_ptr, unsigned *iHeight,
unsigned *iWidth, unsigned *iDepth)
Bit32u bx_vga_c::get_gfx_snapshot(Bit8u **snapshot_ptr, Bit8u **palette_ptr,
unsigned *iHeight, unsigned *iWidth, unsigned *iDepth)
{
Bit32u len, len1;
unsigned i;
unsigned i, shift;
Bit8u *dst_ptr, *src_ptr;
if (BX_VGA_THIS vbe.enabled) {
@ -2763,6 +2763,20 @@ Bit32u bx_vga_c::get_gfx_snapshot(Bit8u **snapshot_ptr, unsigned *iHeight,
src_ptr += BX_VGA_THIS s.line_offset;
dst_ptr += len1;
}
if (*iDepth == 8) {
*palette_ptr = (Bit8u*)malloc(256 * 3);
dst_ptr = *palette_ptr;
if (BX_VGA_THIS vbe.dac_8bit) {
shift = 0;
} else {
shift = 2;
}
for (i = 0; i < 256; i++) {
*(dst_ptr++) = (BX_VGA_THIS s.pel.data[i].blue << shift);
*(dst_ptr++) = (BX_VGA_THIS s.pel.data[i].green << shift);
*(dst_ptr++) = (BX_VGA_THIS s.pel.data[i].red << shift);
}
}
return len;
} else {
*iHeight = 0;

View File

@ -138,8 +138,8 @@ public:
virtual int get_snapshot_mode(void);
virtual void get_text_snapshot(Bit8u **text_snapshot, unsigned *txHeight,
unsigned *txWidth);
virtual Bit32u get_gfx_snapshot(Bit8u **snapshot_ptr, unsigned *iHeight,
unsigned *iWidth, unsigned *iDepth);
virtual Bit32u get_gfx_snapshot(Bit8u **snapshot_ptr, Bit8u **palette_ptr,
unsigned *iHeight, unsigned *iWidth, unsigned *iDepth);
virtual Bit8u get_actl_palette_idx(Bit8u index);
virtual void init_vga_extension(void);

View File

@ -211,8 +211,8 @@ extern "C" {
#define DEV_vga_get_snapshot_mode() bx_devices.pluginVgaDevice->get_snapshot_mode()
#define DEV_vga_get_text_snapshot(rawsnap, height, width) \
(bx_devices.pluginVgaDevice->get_text_snapshot(rawsnap, height, width))
#define DEV_vga_get_gfx_snapshot(rawsnap, height, width, depth) \
(bx_devices.pluginVgaDevice->get_gfx_snapshot(rawsnap, height, width, depth))
#define DEV_vga_get_gfx_snapshot(rawsnap, palette, height, width, depth) \
(bx_devices.pluginVgaDevice->get_gfx_snapshot(rawsnap, palette, height, width, depth))
#define DEV_vga_refresh() \
(bx_devices.pluginVgaDevice->trigger_timer(bx_devices.pluginVgaDevice))
#define DEV_vga_get_actl_pal_idx(index) (bx_devices.pluginVgaDevice->get_actl_palette_idx(index))