Example #1
0
static void deinit_shader_dir(void)
{
   // It handles NULL, no worries :D
   dir_list_free(g_extern.shader_dir.list);
   g_extern.shader_dir.list = NULL;
   g_extern.shader_dir.ptr  = 0;
}
Example #2
0
static bool find_first_libretro(char *path, size_t size,
      const char *dir, const char *rom_path)
{
   bool ret = false;
   const char *ext = path_get_extension(rom_path);
   if (!ext || !*ext)
   {
      RARCH_ERR("Path has no extension. Cannot infer libretro implementation.\n");
      return false;
   }

   RARCH_LOG("Searching for valid libretro implementation in: \"%s\".\n", dir);

   struct string_list *list = dir_list_new(dir, DYNAMIC_EXT, false);
   if (!list)
   {
      RARCH_ERR("Couldn't open directory: \"%s\".\n", dir);
      return false;
   }

   for (size_t i = 0; i < list->size && !ret; i++)
   {
      RARCH_LOG("Checking library: \"%s\".\n", list->elems[i].data);
      dylib_t lib = dylib_load(list->elems[i].data);
      if (!lib)
         continue;

      void (*proc)(struct retro_system_info*) = 
         (void (*)(struct retro_system_info*))dylib_proc(lib, "retro_get_system_info");

      if (!proc)
      {
         dylib_close(lib);
         continue;
      }

      struct retro_system_info info = {0};
      proc(&info);

      if (!info.valid_extensions)
      {
         dylib_close(lib);
         continue;
      }

      struct string_list *supported_ext = string_split(info.valid_extensions, "|"); 

      if (string_list_find_elem(supported_ext, ext))
      {
         strlcpy(path, list->elems[i].data, size);
         ret = true;
      }

      string_list_free(supported_ext);
      dylib_close(lib);
   }

   dir_list_free(list);
   return ret;
}
Example #3
0
/*!
 *****************************************************************************
 *
 ****************************************************************************/
static void __free(void *data)
{
        struct dircache_entry *e = data;
        if (e)
                dir_list_free(&e->dir_entry_list);
        free(e);
}
Example #4
0
void core_info_get_name(const char *path, char *s, size_t len)
{
   size_t i;
   settings_t             *settings = config_get_ptr();
   struct string_list *contents     = dir_list_new_special(
         settings->paths.directory_libretro,
         DIR_LIST_CORES, NULL);
   const char       *path_basedir   = !string_is_empty(settings->paths.path_libretro_info) ?
      settings->paths.path_libretro_info : settings->paths.directory_libretro;

   if (!contents)
      return;

   for (i = 0; i < contents->size; i++)
   {
      size_t path_size                = PATH_MAX_LENGTH * sizeof(char);
      char *info_path                 = NULL;
      config_file_t *conf             = NULL;
      char *new_core_name             = NULL;
      const char *current_path        = contents->elems[i].data;

      if (!string_is_equal(current_path, path))
         continue;

      info_path                       = (char*)malloc(PATH_MAX_LENGTH * sizeof(char));
      info_path[0]                    = '\0';

      if (!core_info_list_iterate(info_path,
               path_size, path_basedir, contents, i)
            && path_is_valid(info_path))
      {
         free(info_path);
         continue;
      }

      conf = config_file_new(info_path);

      if (!conf)
      {
         free(info_path);
         continue;
      }

      if (config_get_string(conf, "corename",
            &new_core_name))
      {
         strlcpy(s, new_core_name, len);
         free(new_core_name);
      }

      config_file_free(conf);
      free(info_path);
      break;
   }

   if (contents)
      dir_list_free(contents);
   contents = NULL;
}
Example #5
0
static void shader_dir_free(rarch_dir_list_t *dir_list)
{
   if (!dir_list)
      return;

   dir_list_free(dir_list->list);
   dir_list->list = NULL;
   dir_list->ptr  = 0;
}
Example #6
0
static void filebrowser_free(void *data)
{
   filebrowser_t *filebrowser = (filebrowser_t*)data;

   dir_list_free(filebrowser->list);
   filebrowser->list = NULL;
   filebrowser->current_dir.ptr   = 0;
   free(filebrowser);
}
Example #7
0
void core_info_get_name(const char *path, char *s, size_t len)
{
   size_t i;
   core_info_t *core_info           = NULL;
   core_info_list_t *core_info_list = NULL;
   struct string_list *contents     = NULL;
   settings_t             *settings = config_get_ptr();

   if (!settings)
      return;

   contents     = dir_list_new_special(
         settings->directory.libretro,
         DIR_LIST_CORES, NULL);

   if (!contents)
      return;

   core_info_list = (core_info_list_t*)calloc(1, sizeof(*core_info_list));
   if (!core_info_list)
      goto error;

   core_info = (core_info_t*)calloc(contents->size, sizeof(*core_info));
   if (!core_info)
      goto error;

   core_info_list->list = core_info;
   core_info_list->count = contents->size;

   for (i = 0; i < contents->size; i++)
   {
      config_file_t *conf = NULL;

      if (!string_is_equal(contents->elems[i].data, path))
         continue;

      conf = core_info_list_iterate(contents, i);

      if (conf)
      {
         config_get_string(conf, "corename",
               &core_info[i].core_name);
         core_info[i].config_data = (void*)conf;
      }

      core_info[i].path = strdup(contents->elems[i].data);

      strlcpy(s, core_info[i].core_name, len);
   }

error:
   if (contents)
      dir_list_free(contents);
   contents = NULL;
   core_info_list_free(core_info_list);
}
Example #8
0
static void zarch_zui_render_lay_root_load_free(zui_t *zui)
{
   if (!zui)
      return;

   free(zui->load_cwd);
   dir_list_free(zui->load_dlist);
   zui->load_cwd   = NULL;
   zui->load_dlist = NULL;
}
Example #9
0
static void zarch_zui_render_lay_root_load_set_new_path(zui_t *zui, const char *newpath)
{
   if (!zui)
      return;

   free(zui->load_cwd);
   zui->load_cwd = strdup(newpath);
   dir_list_free(zui->load_dlist);
   zui->load_dlist = NULL;
}
Example #10
0
static void find_and_set_first_file(void)
{
   //Last fallback - we'll need to start the first executable file 
   // we can find in the RetroArch cores directory

#if defined(_XBOX)
   char ** dir_list = dir_list_new("game:\\", ".xex");
#elif defined(__CELLOS_LV2__)
   char ** dir_list = dir_list_new(LIBRETRO_DIR_PATH, ".SELF");
#endif

   if (!dir_list)
   {
      RARCH_ERR("Failed last fallback - RetroArch Salamander will exit.\n");
      return;
   }

   char * first_executable = dir_list[0];

   if(first_executable)
   {
#ifdef _XBOX
      //Check if it's RetroArch Salamander itself - if so, first_executable needs to
      //be overridden
      char fname_tmp[MAX_PATH_LENGTH];

      fill_pathname_base(fname_tmp, first_executable, sizeof(fname_tmp));

      if(strcmp(fname_tmp, "RetroArch-Salamander.xex") == 0)
      {
         RARCH_WARN("First entry is RetroArch Salamander itself, increment entry by one and check if it exists.\n");
	 first_executable = dir_list[1];
	 fill_pathname_base(fname_tmp, first_executable, sizeof(fname_tmp));

	 if(!first_executable)
	 {
            RARCH_WARN("There is no second entry - no choice but to boot RetroArch Salamander\n");
	    first_executable = dir_list[0];
	    fill_pathname_base(fname_tmp, first_executable, sizeof(fname_tmp));
	 }
      }

      snprintf(first_executable, sizeof(first_executable), "game:\\%s", fname_tmp);
#endif
      RARCH_LOG("Start first entry in libretro cores dir: [%s].\n", first_executable);
      strlcpy(libretro_path, first_executable, sizeof(libretro_path));
   }
   else
   {
      RARCH_ERR("Failed last fallback - RetroArch Salamander will exit.\n");
   }

   dir_list_free(dir_list);
}
Example #11
0
/*We need to set libretro to the first entry in the cores
 * directory so that it will be saved to the config file
 */
static void find_first_libretro_core(char *first_file,
   size_t size_of_first_file, const char *dir,
   const char * ext)
{
   size_t i;
   bool ret = false;
   struct string_list *list = dir_list_new(dir, ext, false, true, false, false);

   if (!list)
   {
      RARCH_ERR("Couldn't read directory."
            " Cannot infer default libretro core.\n");
      return;
   }

   RARCH_LOG("Searching for valid libretro implementation in: \"%s\".\n",
         dir);
   
   for (i = 0; i < list->size && !ret; i++)
   {
      char fname[PATH_MAX_LENGTH];
      char salamander_name[PATH_MAX_LENGTH];
      const char *libretro_elem = (const char*)list->elems[i].data;

      RARCH_LOG("Checking library: \"%s\".\n", libretro_elem);

      if (!libretro_elem)
         continue;

      fill_pathname_base(fname, libretro_elem, sizeof(fname));

      if (!frontend_driver_get_salamander_basename(
               salamander_name, sizeof(salamander_name)))
         break;

      if (!strncmp(fname, salamander_name, sizeof(fname)))
      {
         if (list->size == (i + 1))
         {
            RARCH_WARN("Entry is RetroArch Salamander itself, "
                  "but is last entry. No choice but to set it.\n");
            strlcpy(first_file, fname, size_of_first_file);
         }

         continue;
      }

      strlcpy(first_file, fname, size_of_first_file);
      RARCH_LOG("First found libretro core is: \"%s\".\n", first_file);
      ret = true;
   }

   dir_list_free(list);
}
Example #12
0
static void event_set_savestate_auto_index(void)
{
   size_t i;
   char state_dir[PATH_MAX_LENGTH]  = {0};
   char state_base[PATH_MAX_LENGTH] = {0};
   struct string_list *dir_list     = NULL;
   unsigned max_idx                 = 0;
   settings_t *settings             = config_get_ptr();
   global_t   *global               = global_get_ptr();

   if (!settings->savestate_auto_index)
      return;

   /* Find the file in the same directory as global->savestate_name
    * with the largest numeral suffix.
    *
    * E.g. /foo/path/content.state, will try to find
    * /foo/path/content.state%d, where %d is the largest number available.
    */

   fill_pathname_basedir(state_dir, global->savestate_name,
         sizeof(state_dir));
   fill_pathname_base(state_base, global->savestate_name,
         sizeof(state_base));

   if (!(dir_list = dir_list_new_special(state_dir, DIR_LIST_PLAIN)))
      return;

   for (i = 0; i < dir_list->size; i++)
   {
      unsigned idx;
      char elem_base[PATH_MAX_LENGTH] = {0};
      const char *end                 = NULL;
      const char *dir_elem            = dir_list->elems[i].data;

      fill_pathname_base(elem_base, dir_elem, sizeof(elem_base));

      if (strstr(elem_base, state_base) != elem_base)
         continue;

      end = dir_elem + strlen(dir_elem);
      while ((end > dir_elem) && isdigit(end[-1]))
         end--;

      idx = strtoul(end, NULL, 0);
      if (idx > max_idx)
         max_idx = idx;
   }

   dir_list_free(dir_list);

   settings->state_slot = max_idx;
   RARCH_LOG("Found last state slot: #%d\n", settings->state_slot);
}
Example #13
0
bool dir_free_shader(void)
{
   struct rarch_dir_list *dir_list = 
      (struct rarch_dir_list*)&dir_shader_list;

   dir_list_free(dir_list->list);
   dir_list->list = NULL;
   dir_list->ptr  = 0;

   return true;
}
Example #14
0
void rarch_manage_libretro_set_first_file(char *first_file, size_t size_of_first_file, const char *libretro_path, const char * exe_ext)
{
   //We need to set libretro to the first entry in the cores
   //directory so that it will be saved to the config file

   struct string_list *dir_list = dir_list_new(libretro_path, exe_ext, false);

   const char * first_exe;

   if (!dir_list)
   {
      RARCH_ERR("Couldn't read directory.\n");
      RARCH_ERR("Failed to set first entry to libretro path.\n");
      goto end;
   }

   first_exe = dir_list->elems[0].data;

   if(first_exe)
   {
#ifdef _XBOX
      char fname_tmp[PATH_MAX];
      fill_pathname_base(fname_tmp, first_exe, sizeof(fname_tmp));

      if(strcmp(fname_tmp, "RetroArch-Salamander.xex") == 0)
      {
         RARCH_WARN("First entry is RetroArch Salamander itself, increment entry by one and check if it exists.\n");
	 first_exe = dir_list->elems[1].data;
	 fill_pathname_base(fname_tmp, first_exe, sizeof(fname_tmp));

	 if(!first_exe)
	 {
            RARCH_ERR("Unlikely error happened - no second entry - no choice but to set it to RetroArch Salamander\n");
	    first_exe = dir_list->elems[0].data;
	    fill_pathname_base(fname_tmp, first_exe, sizeof(fname_tmp));
	 }
      }

      strlcpy(first_file, fname_tmp, size_of_first_file);
#else
      strlcpy(first_file, first_exe, size_of_first_file);
#endif
      RARCH_LOG("Set first entry in libretro core dir to libretro path: [%s].\n", first_file);
   }

end:
   dir_list_free(dir_list);
}
Example #15
0
//We need to set libretro to the first entry in the cores
//directory so that it will be saved to the config file
static void find_first_libretro_core(char *first_file,
   size_t size_of_first_file, const char *dir,
   const char * ext)
{
   struct string_list *list;
   size_t i;
   bool ret = false;

   RARCH_LOG("Searching for valid libretro implementation in: \"%s\".\n", dir);

   list = (struct string_list*)dir_list_new(dir, ext, false);
   if (!list)
   {
      RARCH_ERR("Couldn't read directory. Cannot infer default libretro core.\n");
      return;
   }
   
   for (i = 0; i < list->size && !ret; i++)
   {
      char fname[PATH_MAX];
      const char *libretro_elem = (const char*)list->elems[i].data;

      RARCH_LOG("Checking library: \"%s\".\n", libretro_elem);

      if (!libretro_elem)
         continue;

      fill_pathname_base(fname, libretro_elem, sizeof(fname));

      if (strncmp(fname, SALAMANDER_FILE, sizeof(fname)) == 0)
      {
         if ((i + 1) == list->size)
         {
            RARCH_WARN("Entry is RetroArch Salamander itself, but is last entry. No choice but to set it.\n");
            strlcpy(first_file, fname, size_of_first_file);
         }

         continue;
      }

      strlcpy(first_file, fname, size_of_first_file);
      RARCH_LOG("First found libretro core is: \"%s\".\n", first_file);
      ret = true;
   }

   dir_list_free(list);
}
Example #16
0
void core_info_get_name(const char *path, char *s, size_t len)
{
   size_t i;
   settings_t             *settings = config_get_ptr();
   struct string_list *contents     = dir_list_new_special(
         settings->paths.directory_libretro,
         DIR_LIST_CORES, NULL);

   if (!contents)
      return;

   for (i = 0; i < contents->size; i++)
   {
      char info_path[PATH_MAX_LENGTH];
      config_file_t *conf             = NULL;
      char *new_core_name             = NULL;

      info_path[0]                    = '\0';

      if (!string_is_equal(contents->elems[i].data, path))
         continue;

      if (!core_info_list_iterate(info_path,
               sizeof(info_path), contents, i)
            && path_is_valid(info_path))
         continue;

      conf = config_file_new(info_path);

      if (!conf)
         continue;

      if (config_get_string(conf, "corename",
            &new_core_name))
      {
         strlcpy(s, new_core_name, len);
         free(new_core_name);
      }

      config_file_free(conf);
      break;
   }

   if (contents)
      dir_list_free(contents);
   contents = NULL;
}
Example #17
0
static int
find_rom_canonical_name(const char *hash, char *game_name, size_t max_len)
{
	// TODO: Error handling
	size_t i;
	int rv;
	int fd;
	int offs;
	char *dat_path;
	const char *dat_name;
	const char *dat_name_dot;
	struct string_list *files;

	files = dir_list_new("db", "dat", false);
	if (!files) {
		return -1;
	}

	for (i = 0; i < files->size; i++) {
		dat_path = files->elems[i].data;
		dat_name = path_basename(dat_path);

		dat_name_dot = strchr(dat_name, '.');
		if (!dat_name_dot) {
			continue;
		}

		offs = dat_name_dot - dat_name + 1;
		memcpy(game_name, dat_name, offs);

		fd = open(dat_path, O_RDONLY);
		if (fd < 0) {
			continue;
		}

		if (find_hash(fd, hash, game_name + offs, max_len - offs) == 0) {
			rv = 0;
			close(fd);
			goto clean;
		}
		close(fd);
	}
	rv = -1;
clean:
	dir_list_free(files);
	return rv;
}
Example #18
0
static bool directory_parse(void *data, const char *path)
{
   filebrowser_t *filebrowser = (filebrowser_t*)data;

   struct string_list *list = dir_list_new(path,
         filebrowser->current_dir.extensions, true);
   if(!list || list->size < 1)
      return false;
   
   dir_list_sort(list, true);

   filebrowser->current_dir.ptr   = 0;
   strlcpy(filebrowser->current_dir.directory_path,
         path, sizeof(filebrowser->current_dir.directory_path));

   if (filebrowser->list)
      dir_list_free(filebrowser->list);

   filebrowser->list = list;

   return true;

}
Example #19
0
static bool gfx_ctx_drm_egl_init(void *data)
{
   const char *gpu;
   int i;
   unsigned monitor_index;
   unsigned gpu_index = 0;
   unsigned monitor = max(g_settings.video.monitor_index, 1);
   struct string_list *gpu_descriptors  = NULL;

   gfx_ctx_drm_egl_data_t *drm = (gfx_ctx_drm_egl_data_t*)calloc(1, sizeof(gfx_ctx_drm_egl_data_t));

   if (!drm)
      return NULL;

   drm->g_drm_fd = -1;
   gpu_descriptors = (struct string_list*)dir_list_new("/dev/dri", NULL, false);

nextgpu:
   free_drm_resources(drm);

   if (!gpu_descriptors || gpu_index == gpu_descriptors->size)
   {
      RARCH_ERR("[KMS/EGL]: Couldn't find a suitable DRM device.\n");
      goto error;
   }
   gpu = gpu_descriptors->elems[gpu_index++].data;

   drm->g_drm_fd = open(gpu, O_RDWR);
   if (drm->g_drm_fd < 0)
   {
      RARCH_WARN("[KMS/EGL]: Couldn't open DRM device.\n");
      goto nextgpu;
   }

   drm->g_resources = drmModeGetResources(drm->g_drm_fd);
   if (!drm->g_resources)
   {
      RARCH_WARN("[KMS/EGL]: Couldn't get device resources.\n");
      goto nextgpu;
   }

   /* Enumerate all connectors. */
   monitor_index = 0;
   RARCH_LOG("[KMS/EGL]: Found %d connectors.\n",
         drm->g_resources->count_connectors);

   for (i = 0; i < drm->g_resources->count_connectors; i++)
   {
      drmModeConnectorPtr conn = drmModeGetConnector(
            drm->g_drm_fd, drm->g_resources->connectors[i]);

      if (conn)
      {
         bool connected = conn->connection == DRM_MODE_CONNECTED;
         RARCH_LOG("[KMS/EGL]: Connector %d connected: %s\n", i, connected ? "yes" : "no");
         RARCH_LOG("[KMS/EGL]: Connector %d has %d modes.\n", i, conn->count_modes);
         if (connected && conn->count_modes > 0)
         {
            monitor_index++;
            RARCH_LOG("[KMS/EGL]: Connector %d assigned to monitor index: #%u.\n", i, monitor_index);
         }
         drmModeFreeConnector(conn);
      }
   }

   monitor_index = 0;
   for (i = 0; i < drm->g_resources->count_connectors; i++)
   {
      drm->g_connector = drmModeGetConnector(drm->g_drm_fd,
            drm->g_resources->connectors[i]);

      if (!drm->g_connector)
         continue;
      if (drm->g_connector->connection == DRM_MODE_CONNECTED
            && drm->g_connector->count_modes > 0)
      {
         monitor_index++;
         if (monitor_index == monitor)
            break;
      }

      drmModeFreeConnector(drm->g_connector);
      drm->g_connector = NULL;
   }

   if (!drm->g_connector)
   {
      RARCH_WARN("[KMS/EGL]: Couldn't get device connector.\n");
      goto nextgpu;
   }

   for (i = 0; i < drm->g_resources->count_encoders; i++)
   {
      drm->g_encoder = drmModeGetEncoder(drm->g_drm_fd,
            drm->g_resources->encoders[i]);

      if (!drm->g_encoder)
         continue;
      if (drm->g_encoder->encoder_id == drm->g_connector->encoder_id)
         break;

      drmModeFreeEncoder(drm->g_encoder);
      drm->g_encoder = NULL;
   }

   if (!drm->g_encoder)
   {
      RARCH_WARN("[KMS/EGL]: Couldn't find DRM encoder.\n");
      goto nextgpu;
   }

   for (i = 0; i < drm->g_connector->count_modes; i++)
   {
      RARCH_LOG("[KMS/EGL]: Mode %d: (%s) %d x %d, %u Hz\n",
            i,
            drm->g_connector->modes[i].name,
            drm->g_connector->modes[i].hdisplay,
            drm->g_connector->modes[i].vdisplay,
            drm->g_connector->modes[i].vrefresh);
   }

   drm->g_crtc_id   = drm->g_encoder->crtc_id;
   drm->g_orig_crtc = drmModeGetCrtc(drm->g_drm_fd, drm->g_crtc_id);
   if (!drm->g_orig_crtc)
      RARCH_WARN("[KMS/EGL]: Cannot find original CRTC.\n");

   drm->g_connector_id = drm->g_connector->connector_id;

   /* First mode is assumed to be the "optimal" 
    * one for get_video_size() purposes. */
   drm->g_fb_width  = drm->g_connector->modes[0].hdisplay;
   drm->g_fb_height = drm->g_connector->modes[0].vdisplay;

   drm->g_gbm_dev = gbm_create_device(drm->g_drm_fd);

   if (!drm->g_gbm_dev)
   {
      RARCH_WARN("[KMS/EGL]: Couldn't create GBM device.\n");
      goto nextgpu;
   }

   dir_list_free(gpu_descriptors);

   driver.video_context_data = drm;

   return true;

error:
   dir_list_free(gpu_descriptors);

   gfx_ctx_drm_egl_destroy_resources(drm);

   if (drm)
      free(drm);

   return false;
}
static void task_database_handler(retro_task_t *task)
{
   const char *name                 = NULL;
   database_info_handle_t  *dbinfo  = NULL;
   database_state_handle_t *dbstate = NULL;
   db_handle_t *db                  = NULL;

   if (!task)
      goto task_finished;

   db      = (db_handle_t*)task->state;

   if (!db)
      goto task_finished;

   if (!db->scan_started)
   {
      db->scan_started = true;

      if (!string_is_empty(db->fullpath))
      {
         if (db->is_directory)
            db->handle = database_info_dir_init(db->fullpath, DATABASE_TYPE_ITERATE, task, db->show_hidden_files);
         else
            db->handle = database_info_file_init(db->fullpath, DATABASE_TYPE_ITERATE, task);
      }

      task_free_title(task);

      if (db->handle)
         db->handle->status = DATABASE_STATUS_ITERATE_BEGIN;
   }

   dbinfo  = db->handle;
   dbstate = &db->state;

   if (!dbinfo || task_get_cancelled(task))
      goto task_finished;

   switch (dbinfo->status)
   {
      case DATABASE_STATUS_ITERATE_BEGIN:
         if (dbstate && !dbstate->list)
         {
            if (!string_is_empty(db->content_database_path))
               dbstate->list        = dir_list_new(
                     db->content_database_path,
                     "rdb", false,
                     db->show_hidden_files,
                     false, false);

            /* If the scan path matches a database path exactly then
             * save time by only processing that database. */
            if (dbstate->list && db->is_directory)
            {
               size_t i;
               char *dirname = NULL;

               if (!string_is_empty(db->fullpath))
                  dirname    = find_last_slash(db->fullpath) + 1;

               if (!string_is_empty(dirname))
               {
                  for (i = 0; i < dbstate->list->size; i++)
                  {
                     const char *data = dbstate->list->elems[i].data;
                     char *dbname     = NULL;
                     bool strmatch    = false;
                     char *dbpath     = strdup(data);

                     path_remove_extension(dbpath);

                     dbname         = find_last_slash(dbpath) + 1;
                     strmatch       = strcasecmp(dbname, dirname) == 0;

                     free(dbpath);

                     if (strmatch)
                     {
                        struct string_list *single_list = string_list_new();
                        string_list_append(single_list,
                              data,
                              dbstate->list->elems[i].attr);
                        dir_list_free(dbstate->list);
                        dbstate->list = single_list;
                        break;
                     }
                  }
               }
            }
         }
         dbinfo->status = DATABASE_STATUS_ITERATE_START;
         break;
      case DATABASE_STATUS_ITERATE_START:
         name = database_info_get_current_element_name(dbinfo);
         task_database_cleanup_state(dbstate);
         dbstate->list_index  = 0;
         dbstate->entry_index = 0;
         task_database_iterate_start(dbinfo, name);
         break;
      case DATABASE_STATUS_ITERATE:
         if (task_database_iterate(db, dbstate, dbinfo) == 0)
         {
            dbinfo->status = DATABASE_STATUS_ITERATE_NEXT;
            dbinfo->type   = DATABASE_TYPE_ITERATE;
         }
         break;
      case DATABASE_STATUS_ITERATE_NEXT:
         if (task_database_iterate_next(dbinfo) == 0)
         {
            dbinfo->status = DATABASE_STATUS_ITERATE_START;
            dbinfo->type   = DATABASE_TYPE_ITERATE;
         }
         else
         {
            const char *msg = NULL;
            if (db->is_directory)
               msg = msg_hash_to_str(MSG_SCANNING_OF_DIRECTORY_FINISHED);
            else
               msg = msg_hash_to_str(MSG_SCANNING_OF_FILE_FINISHED);
#ifdef RARCH_INTERNAL
            runloop_msg_queue_push(msg, 0, 180, true);
#else
            fprintf(stderr, "msg: %s\n", msg);
#endif
            ui_companion_driver_notify_refresh();
            goto task_finished;
         }
         break;
      default:
      case DATABASE_STATUS_FREE:
      case DATABASE_STATUS_NONE:
         goto task_finished;
   }

   return;
task_finished:
   if (task)
      task_set_finished(task, true);

   if (dbstate)
   {
      if (dbstate->list)
         dir_list_free(dbstate->list);
   }

   if (db)
   {
      if (!string_is_empty(db->playlist_directory))
         free(db->playlist_directory);
      if (!string_is_empty(db->content_database_path))
         free(db->content_database_path);
      if (!string_is_empty(db->fullpath))
         free(db->fullpath);
      if (db->state.buf)
         free(db->state.buf);

      if (db->handle)
         database_info_free(db->handle);
      free(db);
   }

   if (dbinfo)
      free(dbinfo);
}
static void task_database_handler(retro_task_t *task)
{
   db_handle_t *db                  = (db_handle_t*)task->state;
   database_info_handle_t  *dbinfo  = db->handle;
   database_state_handle_t *dbstate = &db->state;
   const char *name                 = dbinfo ? 
      dbinfo->list->elems[dbinfo->list_ptr].data : NULL;

   if (!dbinfo || task->cancelled)
      goto task_finished;

   switch (dbinfo->status)
   {
      case DATABASE_STATUS_ITERATE_BEGIN:
         if (dbstate && !dbstate->list)
            dbstate->list = dir_list_new_special(
                  NULL, DIR_LIST_DATABASES, NULL);
         dbinfo->status = DATABASE_STATUS_ITERATE_START;
         break;
      case DATABASE_STATUS_ITERATE_START:
         task_database_cleanup_state(dbstate);
         dbstate->list_index  = 0;
         dbstate->entry_index = 0;
         task_database_iterate_start(dbinfo, name);
         break;
      case DATABASE_STATUS_ITERATE:
         if (task_database_iterate(&db->state, dbinfo) == 0)
         {
            dbinfo->status = DATABASE_STATUS_ITERATE_NEXT;
            dbinfo->type   = DATABASE_TYPE_ITERATE;
         }
         break;
      case DATABASE_STATUS_ITERATE_NEXT:
         if (task_database_iterate_next(dbinfo) == 0)
         {
            dbinfo->status = DATABASE_STATUS_ITERATE_START;
            dbinfo->type   = DATABASE_TYPE_ITERATE;
         }
         else
         {
            runloop_msg_queue_push(
                  msg_hash_to_str(MSG_SCANNING_OF_DIRECTORY_FINISHED),
                  0, 180, true);
            goto task_finished;
         }
         break;
      default:
      case DATABASE_STATUS_FREE:
      case DATABASE_STATUS_NONE:
         goto task_finished;
   }

   return;
task_finished:
   task->finished = true;

   if (dbstate->list)
      dir_list_free(dbstate->list);

   if (db->state.buf)
      free(db->state.buf);

   if (db->handle)
      database_info_free(db->handle);

   free(dbinfo);
   free(db);
}
Example #22
0
static void task_database_handler(retro_task_t *task)
{
   const char *name                 = NULL;
   database_info_handle_t  *dbinfo  = NULL;
   database_state_handle_t *dbstate = NULL;
   db_handle_t *db                  = NULL;

   if (!task)
      goto task_finished;

   db      = (db_handle_t*)task->state;

   if (!db)
      goto task_finished;

   if (!db->scan_started)
   {
      db->scan_started = true;

      if (db->is_directory)
         db->handle = database_info_dir_init(db->fullpath, DATABASE_TYPE_ITERATE, task);
      else
         db->handle = database_info_file_init(db->fullpath, DATABASE_TYPE_ITERATE, task);

      task_free_title(task);

      if (db->handle)
         db->handle->status = DATABASE_STATUS_ITERATE_BEGIN;
   }

   dbinfo  = db->handle;
   dbstate = &db->state;

   if (!dbinfo || task_get_cancelled(task))
      goto task_finished;

   switch (dbinfo->status)
   {
      case DATABASE_STATUS_ITERATE_BEGIN:
         if (dbstate && !dbstate->list)
         {
            dbstate->list        = dir_list_new_special(
                  db->content_database_path,
                  DIR_LIST_DATABASES, NULL);
         }
         dbinfo->status = DATABASE_STATUS_ITERATE_START;
         break;
      case DATABASE_STATUS_ITERATE_START:
         name = database_info_get_current_element_name(dbinfo);
         task_database_cleanup_state(dbstate);
         dbstate->list_index  = 0;
         dbstate->entry_index = 0;
         task_database_iterate_start(dbinfo, name);
         break;
      case DATABASE_STATUS_ITERATE:
         if (task_database_iterate(db, dbstate, dbinfo) == 0)
         {
            dbinfo->status = DATABASE_STATUS_ITERATE_NEXT;
            dbinfo->type   = DATABASE_TYPE_ITERATE;
         }
         break;
      case DATABASE_STATUS_ITERATE_NEXT:
         if (task_database_iterate_next(dbinfo) == 0)
         {
            dbinfo->status = DATABASE_STATUS_ITERATE_START;
            dbinfo->type   = DATABASE_TYPE_ITERATE;
         }
         else
         {
            runloop_msg_queue_push(
                  msg_hash_to_str(MSG_SCANNING_OF_DIRECTORY_FINISHED),
                  0, 180, true);
            goto task_finished;
         }
         break;
      default:
      case DATABASE_STATUS_FREE:
      case DATABASE_STATUS_NONE:
         goto task_finished;
   }

   return;
task_finished:
   if (task)
      task_set_finished(task, true);

   if (dbstate)
   {
      if (dbstate->list)
         dir_list_free(dbstate->list);
   }

   if (db)
   {
      if (db->state.buf)
         free(db->state.buf);

      if (db->handle)
         database_info_free(db->handle);
      free(db);
   }

   if (dbinfo)
      free(dbinfo);
}
Example #23
0
static int zarch_zui_render_lay_root_load(zui_t *zui, zui_tabbed_t *tabbed)
{
   char parent_dir[PATH_MAX_LENGTH];
   settings_t *settings = config_get_ptr();
   global_t     *global = global_get_ptr();

   if (zarch_zui_tab(zui, tabbed, "Load", 1))
   {
      unsigned cwd_offset;

      if (!zui->load_cwd)
         zui->load_cwd = strdup(settings->menu_content_directory);

      if (!zui->load_dlist)
      {
         zui->load_dlist = dir_list_new(zui->load_cwd, global->core_info.current->supported_extensions, true, true);
         dir_list_sort(zui->load_dlist, true);
         zui->load_dlist_first  = 0;
      }

      cwd_offset = min(strlen(zui->load_cwd), 60);

      zarch_zui_draw_text(zui, ZUI_FG_NORMAL, 15, tabbed->tabline_size + 5 + 41, &zui->load_cwd[strlen(zui->load_cwd) - cwd_offset]);

      if (zarch_zui_button(zui, zui->width - 290 - 129, tabbed->tabline_size + 5, "Home"))
         zarch_zui_render_lay_root_load_free(zui);

      if (zui->load_dlist)
      {
         fill_pathname_parent_dir(parent_dir, zui->load_cwd, sizeof(parent_dir));
         if (parent_dir[0] != '\0' &&
               zarch_zui_list_item(zui, tabbed, 0, tabbed->tabline_size + 73, " ..", 0, NULL /* TODO/FIXME */))
         {
            zarch_zui_render_lay_root_load_set_new_path(zui, parent_dir);
         }
         else
         {
            unsigned size = zui->load_dlist->size;
            unsigned i, j = 1;
            unsigned skip = 0;

            for (i = 0; i < size; ++i)
            {
               const char *basename = path_basename(zui->load_dlist->elems[i].data);
               if (basename[0] != '.')
                  break;
               skip++;
            }

            zui->load_dlist_first += zui->mouse.wheel;

            if (zui->load_dlist_first < 0)
               zui->load_dlist_first = 0;
            else if (zui->load_dlist_first > size - 5)
               zui->load_dlist_first = size - 5;

            zui->load_dlist_first = min(max(zui->load_dlist_first, 0), size - 5 - skip);

            for (i = skip + zui->load_dlist_first; i < size; ++i)
            {
               char label[PATH_MAX_LENGTH];
               const char *path     = NULL;
               const char *basename = NULL;

               if (j > 10)
                  break;

               path = zui->load_dlist->elems[i].data;
               basename = path_basename(path);

               *label = 0;
               strncat(label, "  ", sizeof(label)-1);
               strncat(label, basename, sizeof(label)-1);

               if (path_is_directory(path))
                  strncat(label, "/", sizeof(label)-1);

               if (zarch_zui_list_item(zui, tabbed, 0, tabbed->tabline_size + 73 + j * 54,
                        label, i, NULL))
               {
                  if (path_is_directory(path))
                  {
                     zarch_zui_render_lay_root_load_set_new_path(zui, path);
                     break;
                  }

                  zui->pick_cores     = NULL;
                  zui->pick_supported = 0;
                  strncpy(zui->pick_content, path, sizeof(zui->pick_content)-1);
                  core_info_list_get_supported_cores(global->core_info.list, path,
                        &zui->pick_cores, &zui->pick_supported);
                  layout = LAY_PICK_CORE;
                  break;
               }
               j++;
            }
         }
      }
   }
   else if (zui->load_dlist)
   {
      dir_list_free(zui->load_dlist);
      zui->load_dlist = NULL;
   }

   return 0;
}
Example #24
0
static core_info_list_t *core_info_list_new(const char *path)
{
   size_t i;
   core_info_t *core_info           = NULL;
   core_info_list_t *core_info_list = NULL;
   struct string_list *contents     = dir_list_new_special(
                                      path, DIR_LIST_CORES, NULL);
   settings_t             *settings = config_get_ptr();
   const char       *path_basedir   = !string_is_empty(settings->paths.path_libretro_info) ?
      settings->paths.path_libretro_info : settings->paths.directory_libretro;

   if (!contents)
      return NULL;


   core_info_list = (core_info_list_t*)calloc(1, sizeof(*core_info_list));
   if (!core_info_list)
      goto error;

   core_info = (core_info_t*)calloc(contents->size, sizeof(*core_info));
   if (!core_info)
      goto error;

   core_info_list->list  = core_info;
   core_info_list->count = contents->size;

   for (i = 0; i < contents->size; i++)
   {
      size_t info_path_size = PATH_MAX_LENGTH * sizeof(char);
      char *info_path       = (char*)malloc(PATH_MAX_LENGTH * sizeof(char));

      info_path[0]          = '\0';

      if (
            core_info_list_iterate(info_path, info_path_size,
               path_basedir, contents, i)
            && path_is_valid(info_path))
      {
         char *tmp           = NULL;
         bool tmp_bool       = false;
         unsigned count      = 0;
         config_file_t *conf = config_file_new(info_path);

         free(info_path);

         if (!conf)
            continue;

         if (config_get_string(conf, "display_name", &tmp)
               && !string_is_empty(tmp))
         {
            core_info[i].display_name = strdup(tmp);
            free(tmp);
            tmp = NULL;
         }
         if (config_get_string(conf, "corename", &tmp)
               && !string_is_empty(tmp))
         {
            core_info[i].core_name = strdup(tmp);
            free(tmp);
            tmp = NULL;
         }

         if (config_get_string(conf, "systemname", &tmp)
               && !string_is_empty(tmp))
         {
            core_info[i].systemname = strdup(tmp);
            free(tmp);
            tmp = NULL;
         }

         if (config_get_string(conf, "manufacturer", &tmp)
               && !string_is_empty(tmp))
         {
            core_info[i].system_manufacturer = strdup(tmp);
            free(tmp);
            tmp = NULL;
         }

         config_get_uint(conf, "firmware_count", &count);

         core_info[i].firmware_count = count;

         if (config_get_string(conf, "supported_extensions", &tmp)
               && !string_is_empty(tmp))
         {
            core_info[i].supported_extensions      = strdup(tmp);
            core_info[i].supported_extensions_list =
               string_split(core_info[i].supported_extensions, "|");

            free(tmp);
            tmp = NULL;
         }

         if (config_get_string(conf, "authors", &tmp)
               && !string_is_empty(tmp))
         {
            core_info[i].authors      = strdup(tmp);
            core_info[i].authors_list =
               string_split(core_info[i].authors, "|");

            free(tmp);
            tmp = NULL;
         }

         if (config_get_string(conf, "permissions", &tmp)
               && !string_is_empty(tmp))
         {
            core_info[i].permissions      = strdup(tmp);
            core_info[i].permissions_list =
               string_split(core_info[i].permissions, "|");

            free(tmp);
            tmp = NULL;
         }

         if (config_get_string(conf, "license", &tmp)
               && !string_is_empty(tmp))
         {
            core_info[i].licenses      = strdup(tmp);
            core_info[i].licenses_list =
               string_split(core_info[i].licenses, "|");

            free(tmp);
            tmp = NULL;
         }

         if (config_get_string(conf, "categories", &tmp)
               && !string_is_empty(tmp))
         {
            core_info[i].categories      = strdup(tmp);
            core_info[i].categories_list =
               string_split(core_info[i].categories, "|");

            free(tmp);
            tmp = NULL;
         }

         if (config_get_string(conf, "database", &tmp)
               && !string_is_empty(tmp))
         {
            core_info[i].databases      = strdup(tmp);
            core_info[i].databases_list =
               string_split(core_info[i].databases, "|");

            free(tmp);
            tmp = NULL;
         }

         if (config_get_string(conf, "notes", &tmp)
               && !string_is_empty(tmp))
         {
            core_info[i].notes     = strdup(tmp);
            core_info[i].note_list = string_split(core_info[i].notes, "|");

            free(tmp);
            tmp = NULL;
         }

         if (tmp)
            free(tmp);
         tmp    = NULL;

         if (config_get_bool(conf, "supports_no_game",
               &tmp_bool))
            core_info[i].supports_no_game = tmp_bool;

         if (config_get_bool(conf, "database_match_archive_member",
               &tmp_bool))
            core_info[i].database_match_archive_member = tmp_bool;

         core_info[i].config_data = conf;
      }
      else
         free(info_path);

      if (!string_is_empty(contents->elems[i].data))
         core_info[i].path = strdup(contents->elems[i].data);

      if (!core_info[i].display_name)
         core_info[i].display_name =
            strdup(path_basename(core_info[i].path));
   }

   if (core_info_list)
   {
      core_info_list_resolve_all_extensions(core_info_list);
      core_info_list_resolve_all_firmware(core_info_list);
   }

   dir_list_free(contents);
   return core_info_list;

error:
   if (contents)
      dir_list_free(contents);
   core_info_list_free(core_info_list);
   return NULL;
}
Example #25
0
static int zarch_zui_render_lay_root_load(zui_t *zui,
      struct zui_tabbed *tabbed)
{
   char parent_dir[PATH_MAX_LENGTH];
   settings_t           *settings   = config_get_ptr();
   core_info_list_t           *list = NULL;

   parent_dir[0] = '\0';

   if (zarch_zui_tab(zui, tabbed, "Load", 1))
   {
      unsigned cwd_offset;

      if (!zui->load_cwd)
         zui->load_cwd = strdup(settings->directory.menu_content);

      if (!zui->load_dlist)
      {
         core_info_t *core_info = NULL;
         core_info_get_current_core(&core_info);

         zui->load_dlist = dir_list_new(zui->load_cwd,
               core_info->supported_extensions, true, true, false, true);
         dir_list_sort(zui->load_dlist, true);
         zui->load_dlist_first  = 0;
      }

      cwd_offset = MIN(strlen(zui->load_cwd), 60);

      zarch_zui_draw_text(zui, ZUI_FG_NORMAL, 15,
            tabbed->tabline_size + 5 + 41,
            &zui->load_cwd[strlen(zui->load_cwd) - cwd_offset]);

      if (zarch_zui_button(zui, zui->width - 290 - 129,
               tabbed->tabline_size + 5, "Home"))
         zarch_zui_render_lay_root_load_free(zui);

      if (zui->load_dlist)
      {
         fill_pathname_parent_dir(parent_dir,
               zui->load_cwd, sizeof(parent_dir));
         if (!string_is_empty(parent_dir) &&
               zarch_zui_list_item(zui, tabbed, 0,
                  tabbed->tabline_size + 73, " ..", 0, NULL, false /* TODO/FIXME */))
         {
            zarch_zui_render_lay_root_load_set_new_path(zui, parent_dir);
         }
         else
         {
            static int gamepad_index = 0;
            unsigned size = zui->load_dlist->size;
            unsigned i, j = 1;
            unsigned skip = 0;

            for (i = 0; i < size; ++i)
            {
               const char *basename = 
                  path_basename(zui->load_dlist->elems[i].data);
               if (basename[0] != '.')
                  break;
               skip++;
            }

            if (zarch_zui_gamepad_input(zui, &gamepad_index,
                     &zui->load_dlist_first, skip))
               zui->load_dlist_first = gamepad_index;

            for (i = skip + zui->load_dlist_first; i < size; ++i)
            {
               char label[PATH_MAX_LENGTH];
               const char        *path     = NULL;
               const char        *basename = NULL;

               if (j > 10)
                  break;

               label[0] = '\0';

               path     = zui->load_dlist->elems[i].data;
               basename = path_basename(path);

               *label = 0;
               strncat(label, "  ", sizeof(label)-1);
               strncat(label, basename, sizeof(label)-1);

               if (path_is_directory(path))
                  strncat(label, "/", sizeof(label)-1);

               if (zarch_zui_list_item(zui, tabbed, 0,
                        tabbed->tabline_size + 73 + j * ZUI_ITEM_SIZE_PX,
                        label, i, NULL, gamepad_index == (signed)(i-skip)))
               {
                  if (path_is_directory(path))
                  {
                     zarch_zui_render_lay_root_load_set_new_path(zui, path);
                     break;
                  }

                  zui->pick_cores     = NULL;
                  zui->pick_supported = 0;
                  strlcpy(zui->pick_content,
                        path, sizeof(zui->pick_content));

                  core_info_get_list(&list);

                  core_info_list_get_supported_cores(list, path,
                        &zui->pick_cores, &zui->pick_supported);
                  zarch_layout = LAY_PICK_CORE;
                  break;
               }
               j++;
            }
         }
      }
   }
   else if (zui->load_dlist)
   {
      dir_list_free(zui->load_dlist);
      zui->load_dlist = NULL;
   }

   return 0;
}
Example #26
0
void rarch_main_data_db_iterate(bool is_thread)
{
   database_info_handle_t      *db   = (db_ptr) ? db_ptr->handle : NULL;
   database_state_handle_t *db_state = (db_ptr) ? &db_ptr->state : NULL;
   const char *name = db ? db->list->elems[db->list_ptr].data    : NULL;

   if (!db)
      goto do_poll;

   switch (db->status)
   {
      case DATABASE_STATUS_ITERATE_BEGIN:
         if (db_state && !db_state->list)
            db_state->list = dir_list_new_special(NULL, DIR_LIST_DATABASES, NULL);
         db->status = DATABASE_STATUS_ITERATE_START;
         break;
      case DATABASE_STATUS_ITERATE_START:
         rarch_main_data_db_cleanup_state(db_state);
         db_state->list_index  = 0;
         db_state->entry_index = 0;
         database_info_iterate_start(db, name);
         break;
      case DATABASE_STATUS_ITERATE:
         if (database_info_iterate(&db_ptr->state, db) == 0)
         {
            db->status = DATABASE_STATUS_ITERATE_NEXT;
            db->type   = DATABASE_TYPE_ITERATE;
         }
         break;
      case DATABASE_STATUS_ITERATE_NEXT:
         if (database_info_iterate_next(db) == 0)
         {
            db->status = DATABASE_STATUS_ITERATE_START;
            db->type   = DATABASE_TYPE_ITERATE;
         }
         else
         {
            rarch_main_msg_queue_push_new(MSG_SCANNING_OF_DIRECTORY_FINISHED, 0, 180, true);
            pending_scan_finished = true;
            db->status = DATABASE_STATUS_FREE;
         }
         break;
      case DATABASE_STATUS_FREE:
         if (db_state->list)
            dir_list_free(db_state->list);
         db_state->list = NULL;
         rarch_main_data_db_cleanup_state(db_state);
         database_info_free(db);
         if (db_ptr->handle)
            free(db_ptr->handle);
         db_ptr->handle = NULL;
         break;
      default:
      case DATABASE_STATUS_NONE:
         goto do_poll;
   }

   return;

do_poll:
   if (database_info_poll(db_ptr) != -1)
   {
      if (db_ptr->handle)
         db_ptr->handle->status = DATABASE_STATUS_ITERATE_BEGIN;
   }
}
Example #27
0
/**
 * event_command:
 * @cmd                  : Event command index.
 *
 * Performs RetroArch event command with index @cmd.
 *
 * Returns: true (1) on success, otherwise false (0).
 **/
bool event_command(enum event_command cmd)
{
   unsigned i           = 0;
   bool boolean         = false;
   runloop_t *runloop   = rarch_main_get_ptr();
   driver_t  *driver    = driver_get_ptr();
   global_t  *global    = global_get_ptr();
   settings_t *settings = config_get_ptr();
   rarch_system_info_t *system = rarch_system_info_get_ptr();

   (void)i;

   switch (cmd)
   {
      case EVENT_CMD_LOAD_CONTENT_PERSIST:
#ifdef HAVE_DYNAMIC
         event_command(EVENT_CMD_LOAD_CORE);
#endif
         rarch_main_set_state(RARCH_ACTION_STATE_LOAD_CONTENT);
         break;
#ifdef HAVE_FFMPEG
      case EVENT_CMD_LOAD_CONTENT_FFMPEG:
         rarch_main_set_state(RARCH_ACTION_STATE_LOAD_CONTENT_FFMPEG);
         break;
#endif
      case EVENT_CMD_LOAD_CONTENT_IMAGEVIEWER:
         rarch_main_set_state(RARCH_ACTION_STATE_LOAD_CONTENT_IMAGEVIEWER);
         break;
      case EVENT_CMD_LOAD_CONTENT:
#ifdef HAVE_DYNAMIC
         event_command(EVENT_CMD_LOAD_CONTENT_PERSIST);
#else
         rarch_environment_cb(RETRO_ENVIRONMENT_SET_LIBRETRO_PATH,
               (void*)settings->libretro);
         rarch_environment_cb(RETRO_ENVIRONMENT_EXEC,
               (void*)global->fullpath);
         event_command(EVENT_CMD_QUIT);
#endif
         break;
      case EVENT_CMD_LOAD_CORE_DEINIT:
#ifdef HAVE_DYNAMIC
         libretro_free_system_info(&global->menu.info);
#endif
         break;
      case EVENT_CMD_LOAD_CORE_PERSIST:
         event_command(EVENT_CMD_LOAD_CORE_DEINIT);
         {
#ifdef HAVE_MENU
            menu_handle_t *menu = menu_driver_get_ptr();
            if (menu)
               event_update_system_info(&global->menu.info,
                     &menu->load_no_content);
#endif
         }
         break;
      case EVENT_CMD_LOAD_CORE:
         event_command(EVENT_CMD_LOAD_CORE_PERSIST);
#ifndef HAVE_DYNAMIC
         event_command(EVENT_CMD_QUIT);
#endif
         break;
      case EVENT_CMD_LOAD_STATE:
         /* Immutable - disallow savestate load when 
          * we absolutely cannot change game state. */
         if (global->bsv.movie)
            return false;

#ifdef HAVE_NETPLAY
         if (driver->netplay_data)
            return false;
#endif
         event_main_state(cmd);
         break;
      case EVENT_CMD_RESIZE_WINDOWED_SCALE:
         if (global->pending.windowed_scale == 0)
            return false;

         settings->video.scale = global->pending.windowed_scale;

         if (!settings->video.fullscreen)
            event_command(EVENT_CMD_REINIT);

         global->pending.windowed_scale = 0;
         break;
      case EVENT_CMD_MENU_TOGGLE:
         if (menu_driver_alive())
            rarch_main_set_state(RARCH_ACTION_STATE_MENU_RUNNING_FINISHED);
         else
            rarch_main_set_state(RARCH_ACTION_STATE_MENU_RUNNING);
         break;
      case EVENT_CMD_CONTROLLERS_INIT:
         event_init_controllers();
         break;
      case EVENT_CMD_RESET:
         RARCH_LOG(RETRO_LOG_RESETTING_CONTENT);
         rarch_main_msg_queue_push("Reset.", 1, 120, true);
         pretro_reset();

         /* bSNES since v073r01 resets controllers to JOYPAD
          * after a reset, so just enforce it here. */
         event_command(EVENT_CMD_CONTROLLERS_INIT);
         break;
      case EVENT_CMD_SAVE_STATE:
         if (settings->savestate_auto_index)
            settings->state_slot++;

         event_main_state(cmd);
         break;
      case EVENT_CMD_TAKE_SCREENSHOT:
         if (!take_screenshot())
            return false;
         break;
      case EVENT_CMD_PREPARE_DUMMY:
         {
#ifdef HAVE_MENU
            menu_handle_t *menu = menu_driver_get_ptr();
            if (menu)
               menu->load_no_content = false;
#endif
            rarch_main_data_deinit();

            *global->fullpath = '\0';

            rarch_main_set_state(RARCH_ACTION_STATE_LOAD_CONTENT);
         }
         break;
      case EVENT_CMD_UNLOAD_CORE:
         event_command(EVENT_CMD_PREPARE_DUMMY);
         event_command(EVENT_CMD_LOAD_CORE_DEINIT);
         break;
      case EVENT_CMD_QUIT:
         rarch_main_set_state(RARCH_ACTION_STATE_QUIT);
         break;
      case EVENT_CMD_REINIT:
         {
            const struct retro_hw_render_callback *hw_render =
               (const struct retro_hw_render_callback*)video_driver_callback();

            driver->video_cache_context     = hw_render->cache_context;
            driver->video_cache_context_ack = false;
            event_command(EVENT_CMD_RESET_CONTEXT);
            driver->video_cache_context     = false;

            /* Poll input to avoid possibly stale data to corrupt things. */
            input_driver_poll();

#ifdef HAVE_MENU
            menu_display_fb_set_dirty();

            if (menu_driver_alive())
               event_command(EVENT_CMD_VIDEO_SET_BLOCKING_STATE);
#endif
         }
         break;
      case EVENT_CMD_CHEATS_DEINIT:
         if (!global)
            break;

         if (global->cheat)
            cheat_manager_free(global->cheat);
         global->cheat = NULL;
         break;
      case EVENT_CMD_CHEATS_INIT:
         event_command(EVENT_CMD_CHEATS_DEINIT);
         event_init_cheats();
         break;
      case EVENT_CMD_REMAPPING_DEINIT:
         break;
      case EVENT_CMD_REMAPPING_INIT:
         event_command(EVENT_CMD_REMAPPING_DEINIT);
         event_init_remapping();
         break;
      case EVENT_CMD_REWIND_DEINIT:
         if (!global)
            break;
#ifdef HAVE_NETPLAY
         if (driver->netplay_data)
            return false;
#endif
         if (global->rewind.state)
            state_manager_free(global->rewind.state);
         global->rewind.state = NULL;
         break;
      case EVENT_CMD_REWIND_INIT:
         init_rewind();
         break;
      case EVENT_CMD_REWIND_TOGGLE:
         if (settings->rewind_enable)
            event_command(EVENT_CMD_REWIND_INIT);
         else
            event_command(EVENT_CMD_REWIND_DEINIT);
         break;
      case EVENT_CMD_AUTOSAVE_DEINIT:
#ifdef HAVE_THREADS
         event_deinit_autosave();
#endif
         break;
      case EVENT_CMD_AUTOSAVE_INIT:
         event_command(EVENT_CMD_AUTOSAVE_DEINIT);
#ifdef HAVE_THREADS
         event_init_autosave();
#endif
         break;
      case EVENT_CMD_AUTOSAVE_STATE:
         event_save_auto_state();
         break;
      case EVENT_CMD_AUDIO_STOP:
         if (!driver->audio_data)
            return false;
         if (!audio_driver_alive())
            return false;

         if (!audio_driver_stop())
            return false;
         break;
      case EVENT_CMD_AUDIO_START:
         if (!driver->audio_data || audio_driver_alive())
            return false;

         if (!settings->audio.mute_enable && !audio_driver_start())
         {
            RARCH_ERR("Failed to start audio driver. Will continue without audio.\n");
            driver->audio_active = false;
         }
         break;
      case EVENT_CMD_AUDIO_MUTE_TOGGLE:
         {
            const char *msg = !settings->audio.mute_enable ?
               "Audio muted." : "Audio unmuted.";

            if (!audio_driver_mute_toggle())
            {
               RARCH_ERR("Failed to unmute audio.\n");
               return false;
            }

            rarch_main_msg_queue_push(msg, 1, 180, true);
            RARCH_LOG("%s\n", msg);
         }
         break;
      case EVENT_CMD_OVERLAY_DEINIT:
#ifdef HAVE_OVERLAY
         if (driver->overlay)
            input_overlay_free(driver->overlay);
         driver->overlay = NULL;

         memset(&driver->overlay_state, 0, sizeof(driver->overlay_state));
#endif
         break;
      case EVENT_CMD_OVERLAY_INIT:
         event_command(EVENT_CMD_OVERLAY_DEINIT);
#ifdef HAVE_OVERLAY
         if (driver->osk_enable)
         {
            if (!*settings->osk.overlay)
               break;
         }
         else
         {
            if (!*settings->input.overlay)
               break;
         }

         driver->overlay = input_overlay_new(driver->osk_enable ? settings->osk.overlay : settings->input.overlay,
               driver->osk_enable ? settings->osk.enable   : settings->input.overlay_enable,
               settings->input.overlay_opacity, settings->input.overlay_scale);
         if (!driver->overlay)
            RARCH_ERR("Failed to load overlay.\n");
#endif
         break;
      case EVENT_CMD_OVERLAY_NEXT:
#ifdef HAVE_OVERLAY
         input_overlay_next(driver->overlay, settings->input.overlay_opacity);
#endif
         break;
      case EVENT_CMD_DSP_FILTER_DEINIT:
         if (!global)
            break;

         audio_driver_dsp_filter_free();
         break;
      case EVENT_CMD_DSP_FILTER_INIT:
         event_command(EVENT_CMD_DSP_FILTER_DEINIT);
         if (!*settings->audio.dsp_plugin)
            break;
         audio_driver_dsp_filter_init(settings->audio.dsp_plugin);
         break;
      case EVENT_CMD_GPU_RECORD_DEINIT:
         if (!global)
            break;

         if (global->record.gpu_buffer)
            free(global->record.gpu_buffer);
         global->record.gpu_buffer = NULL;
         break;
      case EVENT_CMD_RECORD_DEINIT:
         if (!recording_deinit())
            return false;
         break;
      case EVENT_CMD_RECORD_INIT:
         event_command(EVENT_CMD_HISTORY_DEINIT);
         if (!recording_init())
            return false;
         break;
      case EVENT_CMD_HISTORY_DEINIT:
         if (g_defaults.history)
         {
            content_playlist_write_file(g_defaults.history);
            content_playlist_free(g_defaults.history);
         }
         g_defaults.history = NULL;
         break;
      case EVENT_CMD_HISTORY_INIT:
         event_command(EVENT_CMD_HISTORY_DEINIT);
         if (!settings->history_list_enable)
            return false;
         RARCH_LOG("Loading history file: [%s].\n", settings->content_history_path);
         g_defaults.history = content_playlist_init(
               settings->content_history_path,
               settings->content_history_size);
         break;
      case EVENT_CMD_CORE_INFO_DEINIT:
         if (!global)
            break;

         if (global->core_info)
            core_info_list_free(global->core_info);
         global->core_info = NULL;
         break;
      case EVENT_CMD_DATA_RUNLOOP_FREE:
         rarch_main_data_free();
         break;
      case EVENT_CMD_CORE_INFO_INIT:
         event_command(EVENT_CMD_CORE_INFO_DEINIT);

         if (*settings->libretro_directory)
            global->core_info = core_info_list_new();
         break;
      case EVENT_CMD_CORE_DEINIT:
      {
         struct retro_hw_render_callback *cb = video_driver_callback();
         event_deinit_core(true);

         if (cb)
            memset(cb, 0, sizeof(*cb));

         break;
      }
      case EVENT_CMD_CORE_INIT:
         if (!event_init_core())
            return false;
         break;
      case EVENT_CMD_VIDEO_APPLY_STATE_CHANGES:
         video_driver_apply_state_changes();
         break;
      case EVENT_CMD_VIDEO_SET_NONBLOCKING_STATE:
         boolean = true; /* fall-through */
      case EVENT_CMD_VIDEO_SET_BLOCKING_STATE:
         video_driver_set_nonblock_state(boolean);
         break;
      case EVENT_CMD_VIDEO_SET_ASPECT_RATIO:
         video_driver_set_aspect_ratio(settings->video.aspect_ratio_idx);
         break;
      case EVENT_CMD_AUDIO_SET_NONBLOCKING_STATE:
         boolean = true; /* fall-through */
      case EVENT_CMD_AUDIO_SET_BLOCKING_STATE:
         audio_driver_set_nonblock_state(boolean);
         break;
      case EVENT_CMD_OVERLAY_SET_SCALE_FACTOR:
#ifdef HAVE_OVERLAY
         input_overlay_set_scale_factor(driver->overlay,
               settings->input.overlay_scale);
#endif
         break;
      case EVENT_CMD_OVERLAY_SET_ALPHA_MOD:
#ifdef HAVE_OVERLAY
         input_overlay_set_alpha_mod(driver->overlay,
               settings->input.overlay_opacity);
#endif
         break;
      case EVENT_CMD_DRIVERS_DEINIT:
         uninit_drivers(DRIVERS_CMD_ALL);
         break;
      case EVENT_CMD_DRIVERS_INIT:
         init_drivers(DRIVERS_CMD_ALL);
         break;
      case EVENT_CMD_AUDIO_REINIT:
         uninit_drivers(DRIVER_AUDIO);
         init_drivers(DRIVER_AUDIO);
         break;
      case EVENT_CMD_RESET_CONTEXT:
         event_command(EVENT_CMD_DRIVERS_DEINIT);
         event_command(EVENT_CMD_DRIVERS_INIT);
         break;
      case EVENT_CMD_QUIT_RETROARCH:
         rarch_main_set_state(RARCH_ACTION_STATE_FORCE_QUIT);
         break;
      case EVENT_CMD_RESUME:
         rarch_main_set_state(RARCH_ACTION_STATE_MENU_RUNNING_FINISHED);
         break;
      case EVENT_CMD_RESTART_RETROARCH:
#if defined(GEKKO) && defined(HW_RVL)
         fill_pathname_join(global->fullpath, g_defaults.core_dir,
               SALAMANDER_FILE,
               sizeof(global->fullpath));
#endif
         if (driver->frontend_ctx && driver->frontend_ctx->set_fork)
            driver->frontend_ctx->set_fork(true, false);
         break;
      case EVENT_CMD_MENU_SAVE_CONFIG:
         if (!event_save_core_config())
            return false;
         break;
      case EVENT_CMD_SHADERS_APPLY_CHANGES:
#ifdef HAVE_MENU
         menu_shader_manager_apply_changes();
#endif
         break;
      case EVENT_CMD_PAUSE_CHECKS:
         if (runloop->is_paused)
         {
            RARCH_LOG("Paused.\n");
            event_command(EVENT_CMD_AUDIO_STOP);

            if (settings->video.black_frame_insertion)
               video_driver_cached_frame();
         }
         else
         {
            RARCH_LOG("Unpaused.\n");
            event_command(EVENT_CMD_AUDIO_START);
         }
         break;
      case EVENT_CMD_PAUSE_TOGGLE:
         runloop->is_paused = !runloop->is_paused;
         event_command(EVENT_CMD_PAUSE_CHECKS);
         break;
      case EVENT_CMD_UNPAUSE:
         runloop->is_paused = false;
         event_command(EVENT_CMD_PAUSE_CHECKS);
         break;
      case EVENT_CMD_PAUSE:
         runloop->is_paused = true;
         event_command(EVENT_CMD_PAUSE_CHECKS);
         break;
      case EVENT_CMD_MENU_PAUSE_LIBRETRO:
         if (menu_driver_alive())
         {
            if (settings->menu.pause_libretro)
               event_command(EVENT_CMD_AUDIO_STOP);
            else
               event_command(EVENT_CMD_AUDIO_START);
         }
         else
         {
            if (settings->menu.pause_libretro)
               event_command(EVENT_CMD_AUDIO_START);
         }
         break;
      case EVENT_CMD_SHADER_DIR_DEINIT:
         if (!global)
            break;

         dir_list_free(global->shader_dir.list);
         global->shader_dir.list = NULL;
         global->shader_dir.ptr  = 0;
         break;
      case EVENT_CMD_SHADER_DIR_INIT:
         event_command(EVENT_CMD_SHADER_DIR_DEINIT);

         if (!*settings->video.shader_dir)
            return false;

         global->shader_dir.list = dir_list_new_special(NULL, DIR_LIST_SHADERS);

         if (!global->shader_dir.list || global->shader_dir.list->size == 0)
         {
            event_command(EVENT_CMD_SHADER_DIR_DEINIT);
            return false;
         }

         global->shader_dir.ptr  = 0;
         dir_list_sort(global->shader_dir.list, false);

         for (i = 0; i < global->shader_dir.list->size; i++)
            RARCH_LOG("Found shader \"%s\"\n",
                  global->shader_dir.list->elems[i].data);
         break;
      case EVENT_CMD_SAVEFILES:
         event_save_files();
         break;
      case EVENT_CMD_SAVEFILES_DEINIT:
         if (!global)
            break;

         if (global->savefiles)
            string_list_free(global->savefiles);
         global->savefiles = NULL;
         break;
      case EVENT_CMD_SAVEFILES_INIT:
         global->use_sram = global->use_sram && !global->sram_save_disable
#ifdef HAVE_NETPLAY
            && (!driver->netplay_data || !global->netplay_is_client)
#endif
            ;

         if (!global->use_sram)
            RARCH_LOG("SRAM will not be saved.\n");

         if (global->use_sram)
            event_command(EVENT_CMD_AUTOSAVE_INIT);
         break;
      case EVENT_CMD_MSG_QUEUE_DEINIT:
         rarch_main_msg_queue_free();
         break;
      case EVENT_CMD_MSG_QUEUE_INIT:
         event_command(EVENT_CMD_MSG_QUEUE_DEINIT);
         rarch_main_msg_queue_init();
         rarch_main_data_init_queues();
         break;
      case EVENT_CMD_BSV_MOVIE_DEINIT:
         if (!global)
            break;

         if (global->bsv.movie)
            bsv_movie_free(global->bsv.movie);
         global->bsv.movie = NULL;
         break;
      case EVENT_CMD_BSV_MOVIE_INIT:
         event_command(EVENT_CMD_BSV_MOVIE_DEINIT);
         event_init_movie();
         break;
      case EVENT_CMD_NETPLAY_DEINIT:
#ifdef HAVE_NETPLAY
         deinit_netplay();
#endif
         break;
      case EVENT_CMD_NETWORK_DEINIT:
#ifdef HAVE_NETWORKING
         network_deinit();
#endif
         break;
      case EVENT_CMD_NETWORK_INIT:
#ifdef HAVE_NETWORKING
         network_init();
#endif
         break;
      case EVENT_CMD_NETPLAY_INIT:
         event_command(EVENT_CMD_NETPLAY_DEINIT);
#ifdef HAVE_NETPLAY
         if (!init_netplay())
            return false;
#endif
         break;
      case EVENT_CMD_NETPLAY_FLIP_PLAYERS:
#ifdef HAVE_NETPLAY
         {
            netplay_t *netplay = (netplay_t*)driver->netplay_data;
            if (!netplay)
               return false;
            netplay_flip_users(netplay);
         }
#endif
         break;
      case EVENT_CMD_FULLSCREEN_TOGGLE:
         if (!video_driver_has_windowed())
            return false;

         /* If we go fullscreen we drop all drivers and 
          * reinitialize to be safe. */
         settings->video.fullscreen = !settings->video.fullscreen;
         event_command(EVENT_CMD_REINIT);
         break;
      case EVENT_CMD_COMMAND_DEINIT:
#ifdef HAVE_COMMAND
         if (driver->command)
            rarch_cmd_free(driver->command);
         driver->command = NULL;
#endif
         break;
      case EVENT_CMD_COMMAND_INIT:
         event_command(EVENT_CMD_COMMAND_DEINIT);

#ifdef HAVE_COMMAND
         event_init_command();
#endif
         break;
      case EVENT_CMD_TEMPORARY_CONTENT_DEINIT:
         if (!global)
            break;

         if (global->temporary_content)
            event_free_temporary_content();
         global->temporary_content = NULL;
         break;
      case EVENT_CMD_SUBSYSTEM_FULLPATHS_DEINIT:
         if (!global)
            break;

         if (global->subsystem_fullpaths)
            string_list_free(global->subsystem_fullpaths);
         global->subsystem_fullpaths = NULL;
         break;
      case EVENT_CMD_LOG_FILE_DEINIT:
         if (!global)
            break;

         if (global->log_file && global->log_file != stderr)
            fclose(global->log_file);
         global->log_file = NULL;
         break;
      case EVENT_CMD_DISK_EJECT_TOGGLE:
         if (system && system->disk_control.get_num_images)
         {
            const struct retro_disk_control_callback *control = 
               (const struct retro_disk_control_callback*)
               &system->disk_control;

            if (control)
               event_check_disk_eject(control);
         }
         else
            rarch_main_msg_queue_push("Core does not support Disk Options.", 1, 120, true);
         break;
      case EVENT_CMD_DISK_NEXT:
         if (system && system->disk_control.get_num_images)
         {
            const struct retro_disk_control_callback *control = 
               (const struct retro_disk_control_callback*)
               &system->disk_control;

            if (!control)
               return false;

            if (!control->get_eject_state())
               return false;

            event_check_disk_next(control);
         }
         else
            rarch_main_msg_queue_push("Core does not support Disk Options.", 1, 120, true);
         break;
      case EVENT_CMD_DISK_PREV:
         if (system && system->disk_control.get_num_images)
         {
            const struct retro_disk_control_callback *control = 
               (const struct retro_disk_control_callback*)
               &system->disk_control;

            if (!control)
               return false;

            if (!control->get_eject_state())
               return false;

            event_check_disk_prev(control);
         }
         else
            rarch_main_msg_queue_push("Core does not support Disk Options.", 1, 120, true);
         break;
      case EVENT_CMD_RUMBLE_STOP:
         for (i = 0; i < MAX_USERS; i++)
         {
            input_driver_set_rumble_state(i, RETRO_RUMBLE_STRONG, 0);
            input_driver_set_rumble_state(i, RETRO_RUMBLE_WEAK, 0);
         }
         break;
      case EVENT_CMD_GRAB_MOUSE_TOGGLE:
         {
            static bool grab_mouse_state  = false;

            grab_mouse_state = !grab_mouse_state;

            if (!driver->input || !input_driver_grab_mouse(grab_mouse_state))
               return false;

            RARCH_LOG("Grab mouse state: %s.\n",
                  grab_mouse_state ? "yes" : "no");

            video_driver_show_mouse(!grab_mouse_state);
         }
         break;
      case EVENT_CMD_PERFCNT_REPORT_FRONTEND_LOG:
         rarch_perf_log();
         break;
      case EVENT_CMD_VOLUME_UP:
         event_set_volume(0.5f);
         break;
      case EVENT_CMD_VOLUME_DOWN:
         event_set_volume(-0.5f);
         break;
      case EVENT_CMD_NONE:
      default:
         goto error;
   }

   return true;

error:
   return false;
}
Example #28
0
void core_info_get_name(const char *path, char *s, size_t len,
      const char *path_info, const char *dir_cores,
      const char *exts, bool dir_show_hidden_files,
      bool get_display_name)
{
   size_t i;
   const char       *path_basedir   = !string_is_empty(path_info) ?
      path_info : dir_cores;
   struct string_list *contents     = dir_list_new(
         dir_cores, exts, false, dir_show_hidden_files, false, false);
   const char *core_path_basename   = path_basename(path);

   if (!contents)
      return;

   for (i = 0; i < contents->size; i++)
   {
      size_t path_size                = PATH_MAX_LENGTH * sizeof(char);
      char *info_path                 = NULL;
      config_file_t *conf             = NULL;
      char *new_core_name             = NULL;
      const char *current_path        = contents->elems[i].data;

      if (!string_is_equal(path_basename(current_path), core_path_basename))
         continue;

      info_path                       = (char*)malloc(PATH_MAX_LENGTH * sizeof(char));
      info_path[0]                    = '\0';

      if (!core_info_list_iterate(info_path,
               path_size, path_basedir, contents, i)
            && path_is_valid(info_path))
      {
         free(info_path);
         continue;
      }

      conf                            = config_file_new(info_path);

      if (!conf)
      {
         free(info_path);
         continue;
      }

      if (config_get_string(conf, get_display_name ? "display_name" : "corename",
            &new_core_name))
      {
         strlcpy(s, new_core_name, len);
         free(new_core_name);
      }

      config_file_free(conf);
      free(info_path);
      break;
   }

   if (contents)
      dir_list_free(contents);
   contents = NULL;
}
Example #29
0
core_info_list_t *core_info_list_new(const char *modules_path)
{
   struct string_list *contents = dir_list_new(modules_path, EXT_EXECUTABLES, false);
   size_t all_ext_len, i;

   core_info_t *core_info = NULL;
   core_info_list_t *core_info_list = NULL;

   if (!contents)
      return NULL;

   core_info_list = (core_info_list_t*)calloc(1, sizeof(*core_info_list));
   if (!core_info_list)
      goto error;

   core_info = (core_info_t*)calloc(contents->size, sizeof(*core_info));
   if (!core_info)
      goto error;

   core_info_list->list = core_info;
   core_info_list->count = contents->size;

   for (i = 0; i < contents->size; i++)
   {
      char info_path_base[PATH_MAX], info_path[PATH_MAX];
      core_info[i].path = strdup(contents->elems[i].data);

      if (!core_info[i].path)
         break;

      fill_pathname_base(info_path_base, contents->elems[i].data, sizeof(info_path_base));
      path_remove_extension(info_path_base);

#if defined(RARCH_MOBILE) || defined(RARCH_CONSOLE)
      char *substr = strrchr(info_path_base, '_');
      if (substr)
         *substr = '\0';
#endif

      strlcat(info_path_base, ".info", sizeof(info_path_base));

      fill_pathname_join(info_path, (*g_settings.libretro_info_path) ? g_settings.libretro_info_path : modules_path,
            info_path_base, sizeof(info_path));

      core_info[i].data = config_file_new(info_path);

      if (core_info[i].data)
      {
         config_get_string(core_info[i].data, "display_name", &core_info[i].display_name);
         if (config_get_string(core_info[i].data, "supported_extensions", &core_info[i].supported_extensions) &&
               core_info[i].supported_extensions)
            core_info[i].supported_extensions_list = string_split(core_info[i].supported_extensions, "|");

         if (config_get_string(core_info[i].data, "authors", &core_info[i].authors) &&
               core_info[i].authors)
            core_info[i].authors_list = string_split(core_info[i].authors, "|");
      }

      if (!core_info[i].display_name)
         core_info[i].display_name = strdup(path_basename(core_info[i].path));
   }

   all_ext_len = 0;
   for (i = 0; i < core_info_list->count; i++)
   {
      all_ext_len += core_info_list->list[i].supported_extensions ?
         (strlen(core_info_list->list[i].supported_extensions) + 2) : 0;
   }

   if (all_ext_len)
   {
      all_ext_len += strlen("|zip");
      core_info_list->all_ext = (char*)calloc(1, all_ext_len);
   }

   if (core_info_list->all_ext)
   {
      for (i = 0; i < core_info_list->count; i++)
      {
         if (core_info_list->list[i].supported_extensions)
         {
            strlcat(core_info_list->all_ext, core_info_list->list[i].supported_extensions, all_ext_len);
            strlcat(core_info_list->all_ext, "|", all_ext_len);
         }
      }
      strlcat(core_info_list->all_ext, "|zip", all_ext_len);
   }

   dir_list_free(contents);
   return core_info_list;

error:
   if (contents)
      dir_list_free(contents);
   core_info_list_free(core_info_list);
   return NULL;
}
Example #30
0
core_info_list_t *core_info_list_new(const char *modules_path)
{
   size_t i;
   core_info_t *core_info = NULL;
   core_info_list_t *core_info_list = NULL;
   struct string_list *contents = (struct string_list*)dir_list_new(modules_path, EXT_EXECUTABLES, false);
   if (!contents)
      return NULL;

   core_info_list = (core_info_list_t*)calloc(1, sizeof(*core_info_list));
   if (!core_info_list)
      goto error;

   core_info = (core_info_t*)calloc(contents->size, sizeof(*core_info));
   if (!core_info)
      goto error;

   core_info_list->list = core_info;
   core_info_list->count = contents->size;

   for (i = 0; i < contents->size; i++)
   {
      char info_path_base[PATH_MAX], info_path[PATH_MAX];
      core_info[i].path = strdup(contents->elems[i].data);

      if (!core_info[i].path)
         break;

      fill_pathname_base(info_path_base, contents->elems[i].data, sizeof(info_path_base));
      path_remove_extension(info_path_base);

#if defined(RARCH_MOBILE) || defined(RARCH_CONSOLE)
      char *substr = strrchr(info_path_base, '_');
      if (substr)
         *substr = '\0';
#endif

      strlcat(info_path_base, ".info", sizeof(info_path_base));

      fill_pathname_join(info_path, (*g_settings.libretro_info_path) ? g_settings.libretro_info_path : modules_path,
            info_path_base, sizeof(info_path));

      core_info[i].data = config_file_new(info_path);

      if (core_info[i].data)
      {
         unsigned count = 0;
         config_get_string(core_info[i].data, "display_name", &core_info[i].display_name);
         config_get_string(core_info[i].data, "systemname", &core_info[i].systemname);
         config_get_uint(core_info[i].data, "firmware_count", &count);
         core_info[i].firmware_count = count;
         if (config_get_string(core_info[i].data, "supported_extensions", &core_info[i].supported_extensions) &&
               core_info[i].supported_extensions)
            core_info[i].supported_extensions_list = string_split(core_info[i].supported_extensions, "|");

         if (config_get_string(core_info[i].data, "authors", &core_info[i].authors) &&
               core_info[i].authors)
            core_info[i].authors_list = string_split(core_info[i].authors, "|");

         if (config_get_string(core_info[i].data, "permissions", &core_info[i].permissions) &&
               core_info[i].permissions)
            core_info[i].permissions_list = string_split(core_info[i].permissions, "|");
         if (config_get_string(core_info[i].data, "notes", &core_info[i].notes) &&
               core_info[i].notes)
            core_info[i].note_list = string_split(core_info[i].notes, "|");
      }

      if (!core_info[i].display_name)
         core_info[i].display_name = strdup(path_basename(core_info[i].path));
   }

   core_info_list_resolve_all_extensions(core_info_list);
   core_info_list_resolve_all_firmware(core_info_list);

   dir_list_free(contents);
   return core_info_list;

error:
   if (contents)
      dir_list_free(contents);
   core_info_list_free(core_info_list);
   return NULL;
}