void video_screen_update_partial(int scrnum, int scanline) { internal_screen_info *screen = &scrinfo[scrnum]; rectangle clip = Machine->screen[scrnum].visarea; LOG_PARTIAL_UPDATES(("Partial: video_screen_update_partial(%d,%d): ", scrnum, scanline)); /* these two checks only apply if we're allowed to skip frames */ if (!(Machine->drv->video_attributes & VIDEO_ALWAYS_UPDATE)) { /* if skipping this frame, bail */ if (video_skip_this_frame()) { LOG_PARTIAL_UPDATES(("skipped due to frameskipping\n")); return; } /* skip if this screen is not visible anywhere */ if (!(render_get_live_screens_mask() & (1 << scrnum))) { LOG_PARTIAL_UPDATES(("skipped because screen not live\n")); return; } } /* skip if less than the lowest so far */ if (scanline < screen->last_partial_scanline) { LOG_PARTIAL_UPDATES(("skipped because less than previous\n")); return; } /* set the start/end scanlines */ if (screen->last_partial_scanline > clip.min_y) clip.min_y = screen->last_partial_scanline; if (scanline < clip.max_y) clip.max_y = scanline; /* render if necessary */ if (clip.min_y <= clip.max_y) { UINT32 flags; profiler_mark(PROFILER_VIDEO); LOG_PARTIAL_UPDATES(("updating %d-%d\n", clip.min_y, clip.max_y)); flags = (*Machine->drv->video_update)(Machine, scrnum, screen->bitmap[screen->curbitmap], &clip); performance.partial_updates_this_frame++; profiler_mark(PROFILER_END); /* if we modified the bitmap, we have to commit */ screen->changed |= (~flags & UPDATE_HAS_NOT_CHANGED); } /* remember where we left off */ screen->last_partial_scanline = scanline + 1; }
void video_save_active_screen_snapshots(void) { UINT32 screenmask = render_get_live_screens_mask(); mame_file *fp; int scrnum; /* write one snapshot per visible screen */ for (scrnum = 0; scrnum < MAX_SCREENS; scrnum++) if (screenmask & (1 << scrnum)) { mame_file_error filerr = mame_fopen_next(SEARCHPATH_SCREENSHOT, "png", &fp); if (filerr == FILERR_NONE) { video_screen_save_snapshot(fp, scrnum); mame_fclose(fp); } } }
void video_frame_update(void) { int skipped_it = video_skip_this_frame(); int paused = mame_is_paused(Machine); int phase = mame_get_phase(Machine); int livemask; int scrnum; /* only render sound and video if we're in the running phase */ if (phase == MAME_PHASE_RUNNING) { /* update sound */ sound_frame_update(); /* finish updating the screens */ for (scrnum = 0; scrnum < MAX_SCREENS; scrnum++) if (Machine->drv->screen[scrnum].tag != NULL) video_screen_update_partial(scrnum, Machine->screen[scrnum].visarea.max_y); /* now add the quads for all the screens */ livemask = render_get_live_screens_mask(); for (scrnum = 0; scrnum < MAX_SCREENS; scrnum++) { if (livemask & (1 << scrnum)) { internal_screen_info *screen = &scrinfo[scrnum]; /* only update if empty and not a vector game; otherwise assume the driver did it directly */ if (render_container_is_empty(render_container_get_screen(scrnum)) && !(Machine->drv->video_attributes & VIDEO_TYPE_VECTOR)) { mame_bitmap *bitmap = screen->bitmap[screen->curbitmap]; if (!skipping_this_frame && screen->changed) { rectangle fixedvis = Machine->screen[scrnum].visarea; fixedvis.max_x++; fixedvis.max_y++; render_texture_set_bitmap(screen->texture, bitmap, &fixedvis, Machine->drv->screen[scrnum].palette_base, screen->format); screen->curbitmap = 1 - screen->curbitmap; } render_screen_add_quad(scrnum, 0.0f, 0.0f, 1.0f, 1.0f, MAKE_ARGB(0xff,0xff,0xff,0xff), screen->texture, PRIMFLAG_BLENDMODE(BLENDMODE_NONE) | PRIMFLAG_SCREENTEX(1)); } } } /* update our movie recording state */ if (!paused) movie_record_frame(0); /* reset the screen changed flags */ for (scrnum = 0; scrnum < MAX_SCREENS; scrnum++) scrinfo[scrnum].changed = 0; } /* draw any crosshairs */ crosshair_render(); /* draw the user interface */ ui_update_and_render(); /* call the OSD to update */ skipping_this_frame = osd_update(mame_timer_get_time()); /* empty the containers */ for (scrnum = 0; scrnum < MAX_SCREENS; scrnum++) if (Machine->drv->screen[scrnum].tag != NULL) render_container_empty(render_container_get_screen(scrnum)); /* update FPS */ recompute_fps(skipped_it); /* call the end-of-frame callback */ if (phase == MAME_PHASE_RUNNING) { /* reset partial updates if we're paused or if the debugger is active */ if (paused || mame_debug_is_active()) video_reset_partial_updates(); /* otherwise, call the video EOF callback */ else if (Machine->drv->video_eof != NULL) { profiler_mark(PROFILER_VIDEO); (*Machine->drv->video_eof)(Machine); profiler_mark(PROFILER_END); } } }
static void dump_screenshot(int write_file) { mame_file_error filerr; mame_file *fp; char buf[128]; int is_blank = 0; int scrnum; UINT32 screenmask; if (write_file) { /* dump a screenshot */ snprintf(buf, sizeof(buf) / sizeof(buf[0]), (screenshot_num >= 0) ? "_%s_%d.png" : "_%s.png", current_testcase.name, screenshot_num); filerr = mame_fopen(SEARCHPATH_SCREENSHOT, buf, OPEN_FLAG_WRITE | OPEN_FLAG_CREATE, &fp); if (filerr == FILERR_NONE) { screenmask = render_get_live_screens_mask(); if (screenmask != 0) { /* choose a screen */ for (scrnum = 0; scrnum < MAX_SCREENS; scrnum++) { if (screenmask & (1 << scrnum)) break; } video_screen_save_snapshot(fp, scrnum); report_message(MSG_INFO, "Saved screenshot as %s", buf); } else { report_message(MSG_FAILURE, "Could not save screenshot; no live screen"); } mame_fclose(fp); } else { /* report the error */ report_message(MSG_FAILURE, "Could not save screenshot; error #%d", filerr); } if (screenshot_num >= 0) screenshot_num++; } #if 0 /* check to see if bitmap is blank */ bitmap = scrbitmap[0]; is_blank = 1; color = bitmap->read(bitmap, 0, 0); for (y = 0; is_blank && (y < bitmap->height); y++) { for (x = 0; is_blank && (x < bitmap->width); x++) { if (bitmap->read(bitmap, x, y) != color) is_blank = 0; } } #endif if (is_blank) { had_failure = TRUE; report_message(MSG_FAILURE, "Screenshot is blank"); } }