示例#1
0
/* 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;
}
示例#2
0
/* 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;
}