void save_screen_snapshot_as(void *fp,struct osd_bitmap *bitmap) { if (Machine->drv->video_attributes & VIDEO_TYPE_VECTOR) png_write_bitmap(fp,bitmap); else { struct osd_bitmap *copy; int sizex, sizey, scalex, scaley; sizex = Machine->visible_area.max_x - Machine->visible_area.min_x + 1; sizey = Machine->visible_area.max_y - Machine->visible_area.min_y + 1; scalex = 1; scaley = (Machine->drv->video_attributes & VIDEO_PIXEL_ASPECT_RATIO_1_2) ? 2 : 1; copy = bitmap_alloc_depth(sizex * scalex,sizey * scaley,bitmap->depth); if (copy) { copyrozbitmap(copy,bitmap, Machine->visible_area.min_x << 16,Machine->visible_area.min_y << 16, 0x10000 / scalex,0,0,0x10000 / scaley, /* zoom, no rotation */ 0, /* no wraparound */ 0,TRANSPARENCY_NONE,0,0); png_write_bitmap(fp,copy); bitmap_free(copy); } } }
/*------------------------------------------------- save_frame_with - save a frame with a given handler for screenshots and movies -------------------------------------------------*/ #if 0 /* AdvanceMAME has its snapshot code */ static void save_frame_with(mame_file *fp, mame_bitmap *bitmap, int (*write_handler)(mame_file *, mame_bitmap *)) { rectangle bounds; mame_bitmap *osdcopy; UINT32 saved_rgb_components[3]; /* allow the artwork system to override certain parameters */ if (Machine->drv->video_attributes & VIDEO_TYPE_VECTOR) { bounds.min_x = 0; bounds.max_x = bitmap->width - 1; bounds.min_y = 0; bounds.max_y = bitmap->height - 1; } else { bounds = Machine->visible_area; } memcpy(saved_rgb_components, direct_rgb_components, sizeof(direct_rgb_components)); artwork_override_screenshot_params(&bitmap, &bounds, direct_rgb_components); /* allow the OSD system to muck with the screenshot */ osdcopy = osd_override_snapshot(bitmap, &bounds); if (osdcopy) bitmap = osdcopy; /* now do the actual work */ if (Machine->drv->video_attributes & VIDEO_TYPE_VECTOR) { write_handler(fp, bitmap); } else { mame_bitmap *copy; int sizex, sizey, scalex, scaley; sizex = bounds.max_x - bounds.min_x + 1; sizey = bounds.max_y - bounds.min_y + 1; scalex = (Machine->drv->video_attributes & VIDEO_PIXEL_ASPECT_RATIO_2_1) ? 2 : 1; scaley = (Machine->drv->video_attributes & VIDEO_PIXEL_ASPECT_RATIO_1_2) ? 2 : 1; if(Machine->gamedrv->flags & ORIENTATION_SWAP_XY) { int temp; temp = scalex; scalex = scaley; scaley = temp; } copy = bitmap_alloc_depth(sizex * scalex,sizey * scaley,bitmap->depth); if (copy) { int x,y,sx,sy; sx = bounds.min_x; sy = bounds.min_y; switch (bitmap->depth) { case 8: for (y = 0;y < copy->height;y++) { for (x = 0;x < copy->width;x++) { ((UINT8 *)copy->line[y])[x] = ((UINT8 *)bitmap->line[sy+(y/scaley)])[sx +(x/scalex)]; } } break; case 15: case 16: for (y = 0;y < copy->height;y++) { for (x = 0;x < copy->width;x++) { ((UINT16 *)copy->line[y])[x] = ((UINT16 *)bitmap->line[sy+(y/scaley)])[sx +(x/scalex)]; } } break; case 32: for (y = 0;y < copy->height;y++) { for (x = 0;x < copy->width;x++) { ((UINT32 *)copy->line[y])[x] = ((UINT32 *)bitmap->line[sy+(y/scaley)])[sx +(x/scalex)]; } } break; default: logerror("Unknown color depth\n"); break; } write_handler(fp, copy); bitmap_free(copy); } } memcpy(direct_rgb_components, saved_rgb_components, sizeof(saved_rgb_components)); /* if the OSD system allocated a bitmap; free it */ if (osdcopy) bitmap_free(osdcopy); }
struct osd_bitmap *bitmap_alloc(int width,int height) { return bitmap_alloc_depth(width,height,Machine->scrbitmap->depth); }
static int vh_open(void) { int i; int width,height; for (i = 0;i < MAX_GFX_ELEMENTS;i++) Machine->gfx[i] = 0; Machine->uifont = 0; if (palette_start() != 0) { vh_close(); return 1; } /* convert the gfx ROMs into character sets. This is done BEFORE calling the driver's */ /* convert_color_prom() routine (in palette_init()) because it might need to check the */ /* Machine->gfx[] data */ if (drv->gfxdecodeinfo) { for (i = 0;i < MAX_GFX_ELEMENTS && drv->gfxdecodeinfo[i].memory_region != -1;i++) { int reglen = 8*memory_region_length(drv->gfxdecodeinfo[i].memory_region); struct GfxLayout glcopy; int j; memcpy(&glcopy,drv->gfxdecodeinfo[i].gfxlayout,sizeof(glcopy)); if (IS_FRAC(glcopy.total)) glcopy.total = reglen / glcopy.charincrement * FRAC_NUM(glcopy.total) / FRAC_DEN(glcopy.total); for (j = 0;j < MAX_GFX_PLANES;j++) { if (IS_FRAC(glcopy.planeoffset[j])) { glcopy.planeoffset[j] = FRAC_OFFSET(glcopy.planeoffset[j]) + reglen * FRAC_NUM(glcopy.planeoffset[j]) / FRAC_DEN(glcopy.planeoffset[j]); } } for (j = 0;j < MAX_GFX_SIZE;j++) { if (IS_FRAC(glcopy.xoffset[j])) { glcopy.xoffset[j] = FRAC_OFFSET(glcopy.xoffset[j]) + reglen * FRAC_NUM(glcopy.xoffset[j]) / FRAC_DEN(glcopy.xoffset[j]); } if (IS_FRAC(glcopy.yoffset[j])) { glcopy.yoffset[j] = FRAC_OFFSET(glcopy.yoffset[j]) + reglen * FRAC_NUM(glcopy.yoffset[j]) / FRAC_DEN(glcopy.yoffset[j]); } } if ((Machine->gfx[i] = decodegfx(memory_region(drv->gfxdecodeinfo[i].memory_region) + drv->gfxdecodeinfo[i].start, &glcopy)) == 0) { vh_close(); bailing = 1; printf("Out of memory decoding gfx\n"); return 1; } if (Machine->remapped_colortable) Machine->gfx[i]->colortable = &Machine->remapped_colortable[drv->gfxdecodeinfo[i].color_codes_start]; Machine->gfx[i]->total_colors = drv->gfxdecodeinfo[i].total_color_codes; } } width = drv->screen_width; height = drv->screen_height; if (Machine->drv->video_attributes & VIDEO_TYPE_VECTOR) scale_vectorgames(options.vector_width,options.vector_height,&width,&height); Machine->scrbitmap = bitmap_alloc_depth(width,height,Machine->color_depth); if (!Machine->scrbitmap) { vh_close(); return 1; } if (!(Machine->drv->video_attributes & VIDEO_TYPE_VECTOR)) { width = drv->default_visible_area.max_x - drv->default_visible_area.min_x + 1; height = drv->default_visible_area.max_y - drv->default_visible_area.min_y + 1; } if (Machine->orientation & ORIENTATION_SWAP_XY) { int temp; temp = width; width = height; height = temp; } /* create the display bitmap, and allocate the palette */ if (osd_create_display(width,height,Machine->color_depth, drv->frames_per_second,drv->video_attributes,Machine->orientation)) { vh_close(); return 1; } set_visible_area( drv->default_visible_area.min_x, drv->default_visible_area.max_x, drv->default_visible_area.min_y, drv->default_visible_area.max_y); /* create spriteram buffers if necessary */ if (drv->video_attributes & VIDEO_BUFFERS_SPRITERAM) { if (spriteram_size!=0) { buffered_spriteram= (unsigned char *) malloc(spriteram_size); if (!buffered_spriteram) { vh_close(); return 1; } if (spriteram_2_size!=0) buffered_spriteram_2 = (unsigned char *) malloc(spriteram_2_size); if (spriteram_2_size && !buffered_spriteram_2) { vh_close(); return 1; } } else { logerror("vh_open(): Video buffers spriteram but spriteram_size is 0\n"); buffered_spriteram=NULL; buffered_spriteram_2=NULL; } } /* build our private user interface font */ /* This must be done AFTER osd_create_display() so the function knows the */ /* resolution we are running at and can pick a different font depending on it. */ /* It must be done BEFORE palette_init() because that will also initialize */ /* (through osd_allocate_colors()) the uifont colortable. */ if ((Machine->uifont = builduifont()) == 0) { vh_close(); return 1; } /* initialize the palette - must be done after osd_create_display() */ if (palette_init()) { vh_close(); return 1; } return 0; }
struct mame_bitmap *osd_override_snapshot(struct mame_bitmap *bitmap, struct rectangle *bounds) { struct rectangle newbounds; struct mame_bitmap *copy; int x, y, w, h, t; // if we can send it in raw, no need to override anything if (!blit_swapxy && !blit_flipx && !blit_flipy) return NULL; // allocate a copy w = blit_swapxy ? bitmap->height : bitmap->width; h = blit_swapxy ? bitmap->width : bitmap->height; copy = bitmap_alloc_depth(w, h, bitmap->depth); if (!copy) return NULL; // populate the copy for (y = bounds->min_y; y <= bounds->max_y; y++) for (x = bounds->min_x; x <= bounds->max_x; x++) { int tx = x, ty = y; // apply the rotation/flipping if (blit_swapxy) { t = tx; tx = ty; ty = t; } if (blit_flipx) tx = copy->width - tx - 1; if (blit_flipy) ty = copy->height - ty - 1; // read the old pixel and copy to the new location switch (copy->depth) { case 15: case 16: *((UINT16 *)copy->base + ty * copy->rowpixels + tx) = *((UINT16 *)bitmap->base + y * bitmap->rowpixels + x); break; case 32: *((UINT32 *)copy->base + ty * copy->rowpixels + tx) = *((UINT32 *)bitmap->base + y * bitmap->rowpixels + x); break; } } // compute the oriented bounds newbounds = *bounds; // apply X/Y swap first if (blit_swapxy) { t = newbounds.min_x; newbounds.min_x = newbounds.min_y; newbounds.min_y = t; t = newbounds.max_x; newbounds.max_x = newbounds.max_y; newbounds.max_y = t; } // apply X flip if (blit_flipx) { t = copy->width - newbounds.min_x - 1; newbounds.min_x = copy->width - newbounds.max_x - 1; newbounds.max_x = t; } // apply Y flip if (blit_flipy) { t = copy->height - newbounds.min_y - 1; newbounds.min_y = copy->height - newbounds.max_y - 1; newbounds.max_y = t; } *bounds = newbounds; return copy; }