/* Take frame bottom-up. */ static bool screenshot_dump( const char *name_base, const void *frame, unsigned width, unsigned height, int pitch, bool bgr24, void *userbuf, bool savestate, bool is_idle, bool is_paused) { char screenshot_path[PATH_MAX_LENGTH]; uint8_t *buf = NULL; #ifdef _XBOX1 d3d_video_t *d3d = (d3d_video_t*)video_driver_get_ptr(true); #endif settings_t *settings = config_get_ptr(); retro_task_t *task = (retro_task_t*)calloc(1, sizeof(*task)); screenshot_task_state_t *state = (screenshot_task_state_t*) calloc(1, sizeof(*state)); const char *screenshot_dir = settings->paths.directory_screenshot; screenshot_path[0] = '\0'; if (string_is_empty(screenshot_dir) || settings->bools.screenshots_in_content_dir) { fill_pathname_basedir(screenshot_path, name_base, sizeof(screenshot_path)); screenshot_dir = screenshot_path; } state->is_idle = is_idle; state->is_paused = is_paused; state->bgr24 = bgr24; state->height = height; state->width = width; state->pitch = pitch; state->frame = frame; state->userbuf = userbuf; state->silence = savestate; state->history_list_enable = settings->bools.history_list_enable; state->pixel_format_type = video_driver_get_pixel_format(); if (savestate) snprintf(state->filename, sizeof(state->filename), "%s.png", name_base); else { if (settings->bools.auto_screenshot_filename) fill_str_dated_filename(state->shotname, path_basename(name_base), IMG_EXT, sizeof(state->shotname)); else snprintf(state->shotname, sizeof(state->shotname), "%s.png", path_basename(name_base)); fill_pathname_join(state->filename, screenshot_dir, state->shotname, sizeof(state->filename)); } #ifdef _XBOX1 d3d->dev->GetBackBuffer(-1, D3DBACKBUFFER_TYPE_MONO, &state->surf); #elif defined(HAVE_RPNG) buf = (uint8_t*)malloc(width * height * 3); if (!buf) { if (task) free(task); free(state); return false; } state->out_buffer = buf; #endif task->type = TASK_TYPE_BLOCKING; task->state = state; task->handler = task_screenshot_handler; if (!savestate) task->title = strdup(msg_hash_to_str(MSG_TAKING_SCREENSHOT)); task_queue_push(task); return true; }
/* Take frame bottom-up. */ static bool screenshot_dump( const char *name_base, const void *frame, unsigned width, unsigned height, int pitch, bool bgr24, void *userbuf, bool savestate, bool is_idle, bool is_paused, bool fullpath, bool use_thread) { char screenshot_path[PATH_MAX_LENGTH]; uint8_t *buf = NULL; settings_t *settings = config_get_ptr(); retro_task_t *task; screenshot_task_state_t *state; const char *screenshot_dir = settings->paths.directory_screenshot; struct retro_system_info system_info; screenshot_path[0] = '\0'; if (!core_get_system_info(&system_info)) return false; task = task_init(); state = (screenshot_task_state_t*)calloc(1, sizeof(*state)); state->shotname[0] = '\0'; /* If fullpath is true, name_base already contains a static path + filename to save the screenshot to. */ if (fullpath) strlcpy(state->filename, name_base, sizeof(state->filename)); else { if (string_is_empty(screenshot_dir) || settings->bools.screenshots_in_content_dir) { fill_pathname_basedir(screenshot_path, name_base, sizeof(screenshot_path)); screenshot_dir = screenshot_path; } } state->is_idle = is_idle; state->is_paused = is_paused; state->bgr24 = bgr24; state->height = height; state->width = width; state->pitch = pitch; state->frame = frame; state->userbuf = userbuf; state->silence = savestate; state->history_list_enable = settings->bools.history_list_enable; state->pixel_format_type = video_driver_get_pixel_format(); if (!fullpath) { if (savestate) snprintf(state->filename, sizeof(state->filename), "%s.png", name_base); else { if (settings->bools.auto_screenshot_filename) { const char *screenshot_name = NULL; if (path_is_empty(RARCH_PATH_CONTENT)) { if (string_is_empty(system_info.library_name)) screenshot_name = "RetroArch"; else screenshot_name = system_info.library_name; } else screenshot_name = path_basename(name_base); fill_str_dated_filename(state->shotname, screenshot_name, IMG_EXT, sizeof(state->shotname)); } else snprintf(state->shotname, sizeof(state->shotname), "%s.png", path_basename(name_base)); fill_pathname_join(state->filename, screenshot_dir, state->shotname, sizeof(state->filename)); } } #if defined(HAVE_RPNG) buf = (uint8_t*)malloc(width * height * 3); if (!buf) { if (task) free(task); free(state); return false; } state->out_buffer = buf; #endif task->type = TASK_TYPE_BLOCKING; task->state = state; task->handler = task_screenshot_handler; if (use_thread) { if (!savestate) task->title = strdup(msg_hash_to_str(MSG_TAKING_SCREENSHOT)); if (!task_queue_push(task)) { /* There is already a blocking task going on */ if (task->title) task_free_title(task); free(task); if (state->out_buffer) free(state->out_buffer); free(state); return false; } } else { if (task) free(task); return screenshot_dump_direct(state); } return true; }