mirror of https://github.com/xemu-project/xemu.git
Fix VGA screen dump
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6159 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
parent
6fa724a34a
commit
4c5e8c5ce8
113
hw/vga.c
113
hw/vga.c
|
@ -1223,6 +1223,35 @@ static const uint8_t cursor_glyph[32 * 4] = {
|
||||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void vga_get_text_resolution(VGAState *s, int *pwidth, int *pheight,
|
||||||
|
int *pcwidth, int *pcheight)
|
||||||
|
{
|
||||||
|
int width, cwidth, height, cheight;
|
||||||
|
|
||||||
|
/* total width & height */
|
||||||
|
cheight = (s->cr[9] & 0x1f) + 1;
|
||||||
|
cwidth = 8;
|
||||||
|
if (!(s->sr[1] & 0x01))
|
||||||
|
cwidth = 9;
|
||||||
|
if (s->sr[1] & 0x08)
|
||||||
|
cwidth = 16; /* NOTE: no 18 pixel wide */
|
||||||
|
width = (s->cr[0x01] + 1);
|
||||||
|
if (s->cr[0x06] == 100) {
|
||||||
|
/* ugly hack for CGA 160x100x16 - explain me the logic */
|
||||||
|
height = 100;
|
||||||
|
} else {
|
||||||
|
height = s->cr[0x12] |
|
||||||
|
((s->cr[0x07] & 0x02) << 7) |
|
||||||
|
((s->cr[0x07] & 0x40) << 3);
|
||||||
|
height = (height + 1) / cheight;
|
||||||
|
}
|
||||||
|
|
||||||
|
*pwidth = width;
|
||||||
|
*pheight = height;
|
||||||
|
*pcwidth = cwidth;
|
||||||
|
*pcheight = cheight;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Text mode update
|
* Text mode update
|
||||||
* Missing:
|
* Missing:
|
||||||
|
@ -1275,24 +1304,8 @@ static void vga_draw_text(VGAState *s, int full_update)
|
||||||
line_offset = s->line_offset;
|
line_offset = s->line_offset;
|
||||||
s1 = s->vram_ptr + (s->start_addr * 4);
|
s1 = s->vram_ptr + (s->start_addr * 4);
|
||||||
|
|
||||||
/* total width & height */
|
vga_get_text_resolution(s, &width, &height, &cw, &cheight);
|
||||||
cheight = (s->cr[9] & 0x1f) + 1;
|
|
||||||
cw = 8;
|
|
||||||
if (!(s->sr[1] & 0x01))
|
|
||||||
cw = 9;
|
|
||||||
if (s->sr[1] & 0x08)
|
|
||||||
cw = 16; /* NOTE: no 18 pixel wide */
|
|
||||||
x_incr = cw * ((ds_get_bits_per_pixel(s->ds) + 7) >> 3);
|
x_incr = cw * ((ds_get_bits_per_pixel(s->ds) + 7) >> 3);
|
||||||
width = (s->cr[0x01] + 1);
|
|
||||||
if (s->cr[0x06] == 100) {
|
|
||||||
/* ugly hack for CGA 160x100x16 - explain me the logic */
|
|
||||||
height = 100;
|
|
||||||
} else {
|
|
||||||
height = s->cr[0x12] |
|
|
||||||
((s->cr[0x07] & 0x02) << 7) |
|
|
||||||
((s->cr[0x07] & 0x40) << 3);
|
|
||||||
height = (height + 1) / cheight;
|
|
||||||
}
|
|
||||||
if ((height * width) > CH_ATTR_SIZE) {
|
if ((height * width) > CH_ATTR_SIZE) {
|
||||||
/* better than nothing: exit if transient size is too big */
|
/* better than nothing: exit if transient size is too big */
|
||||||
return;
|
return;
|
||||||
|
@ -2542,11 +2555,29 @@ int ppm_save(const char *filename, uint8_t *data,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* save the vga display in a PPM image even if no display is
|
static void vga_screen_dump_blank(VGAState *s, const char *filename)
|
||||||
available */
|
{
|
||||||
static void vga_screen_dump(void *opaque, const char *filename)
|
FILE *f;
|
||||||
|
unsigned int y, x, w, h;
|
||||||
|
|
||||||
|
w = s->last_scr_width * sizeof(uint32_t);
|
||||||
|
h = s->last_scr_height;
|
||||||
|
|
||||||
|
f = fopen(filename, "wb");
|
||||||
|
if (!f)
|
||||||
|
return;
|
||||||
|
fprintf(f, "P6\n%d %d\n%d\n", w, h, 255);
|
||||||
|
for (y = 0; y < h; y++) {
|
||||||
|
for (x = 0; x < w; x++) {
|
||||||
|
fputc(0, f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fclose(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void vga_screen_dump_common(VGAState *s, const char *filename,
|
||||||
|
int w, int h)
|
||||||
{
|
{
|
||||||
VGAState *s = (VGAState *)opaque;
|
|
||||||
DisplayState *saved_ds, ds1, *ds = &ds1;
|
DisplayState *saved_ds, ds1, *ds = &ds1;
|
||||||
|
|
||||||
/* XXX: this is a little hackish */
|
/* XXX: this is a little hackish */
|
||||||
|
@ -2559,14 +2590,42 @@ static void vga_screen_dump(void *opaque, const char *filename)
|
||||||
ds->dpy_refresh = vga_save_dpy_refresh;
|
ds->dpy_refresh = vga_save_dpy_refresh;
|
||||||
ds->depth = 32;
|
ds->depth = 32;
|
||||||
|
|
||||||
|
ds->linesize = w * sizeof(uint32_t);
|
||||||
|
ds->data = qemu_mallocz(h * ds->linesize);
|
||||||
s->ds = ds;
|
s->ds = ds;
|
||||||
s->graphic_mode = -1;
|
s->graphic_mode = -1;
|
||||||
vga_update_display(s);
|
vga_update_display(s);
|
||||||
|
ppm_save(filename, ds->data, w, h, ds->linesize);
|
||||||
if (ds_get_data(ds)) {
|
qemu_free(ds->data);
|
||||||
ppm_save(filename, ds_get_data(ds), vga_save_w, vga_save_h,
|
|
||||||
ds_get_linesize(s->ds));
|
|
||||||
qemu_free(ds_get_data(ds));
|
|
||||||
}
|
|
||||||
s->ds = saved_ds;
|
s->ds = saved_ds;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void vga_screen_dump_graphic(VGAState *s, const char *filename)
|
||||||
|
{
|
||||||
|
int w, h;
|
||||||
|
|
||||||
|
s->get_resolution(s, &w, &h);
|
||||||
|
vga_screen_dump_common(s, filename, w, h);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void vga_screen_dump_text(VGAState *s, const char *filename)
|
||||||
|
{
|
||||||
|
int w, h, cwidth, cheight;
|
||||||
|
|
||||||
|
vga_get_text_resolution(s, &w, &h, &cwidth, &cheight);
|
||||||
|
vga_screen_dump_common(s, filename, w * cwidth, h * cheight);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* save the vga display in a PPM image even if no display is
|
||||||
|
available */
|
||||||
|
static void vga_screen_dump(void *opaque, const char *filename)
|
||||||
|
{
|
||||||
|
VGAState *s = (VGAState *)opaque;
|
||||||
|
|
||||||
|
if (!(s->ar_index & 0x20))
|
||||||
|
vga_screen_dump_blank(s, filename);
|
||||||
|
else if (s->gr[6] & 1)
|
||||||
|
vga_screen_dump_graphic(s, filename);
|
||||||
|
else
|
||||||
|
vga_screen_dump_text(s, filename);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue