/**
 * fill_short_pathname_representation:
 * @out_rep            : output representation
 * @in_path            : input path
 * @size               : size of output representation
 *
 * Generates a short representation of path. It should only
 * be used for displaying the result; the output representation is not
 * binding in any meaningful way (for a normal path, this is the same as basename)
 * In case of more complex URLs, this should cut everything except for
 * the main image file.
 *
 * E.g.: "/path/to/game.img" -> game.img
 *       "/path/to/myarchive.7z#folder/to/game.img" -> game.img
 */
void fill_short_pathname_representation_wrapper(char* out_rep,
      const char *in_path, size_t size)
{
#ifdef HAVE_COMPRESSION
   char *path_short = (char*)malloc(PATH_MAX_LENGTH * sizeof(char));
   char *last_slash = NULL;

   path_short[0]    = '\0';

   fill_pathname(path_short, path_basename(in_path), "",
         PATH_MAX_LENGTH * sizeof(char)
         );

   last_slash  = find_last_slash(path_short);

   if (last_slash != NULL)
   {
      /* We handle paths like:
       * /path/to/file.7z#mygame.img
       * short_name: mygame.img:
       *
       * We check whether something is actually
       * after the hash to avoid going over the buffer.
       */
      retro_assert(strlen(last_slash) > 1);
      strlcpy(out_rep, last_slash + 1, size);
      free(path_short);
      return;
   }

   free(path_short);
#endif

   fill_short_pathname_representation(out_rep, in_path, size);
}
Пример #2
0
/**
 * fill_short_pathname_representation:
 * @out_rep            : output representation
 * @in_path            : input path
 * @size               : size of output representation
 *
 * Generates a short representation of path. It should only
 * be used for displaying the result; the output representation is not
 * binding in any meaningful way (for a normal path, this is the same as basename)
 * In case of more complex URLs, this should cut everything except for
 * the main image file.
 *
 * E.g.: "/path/to/game.img" -> game.img
 *       "/path/to/myarchive.7z#folder/to/game.img" -> game.img
 */
void fill_short_pathname_representation(char* out_rep,
      const char *in_path, size_t size)
{
   char path_short[PATH_MAX_LENGTH] = {0};
   char *last_hash                  = NULL;

   fill_pathname(path_short, path_basename(in_path), "",
            sizeof(path_short));

   last_hash = (char*)strchr(path_short,'#');
   /* We handle paths like:
    * /path/to/file.7z#mygame.img
    * short_name: mygame.img:
    */
   if(last_hash != NULL)
   {
      /* We check whether something is actually
       * after the hash to avoid going over the buffer.
       */
      rarch_assert(strlen(last_hash) > 1);
      strlcpy(out_rep,last_hash + 1, size);
   }
   else
      strlcpy(out_rep,path_short, size);
}
Пример #3
0
/**
 * fill_short_pathname_representation:
 * @out_rep            : output representation
 * @in_path            : input path
 * @size               : size of output representation
 *
 * Generates a short representation of path. It should only
 * be used for displaying the result; the output representation is not
 * binding in any meaningful way (for a normal path, this is the same as basename)
 * In case of more complex URLs, this should cut everything except for
 * the main image file.
 *
 * E.g.: "/path/to/game.img" -> game.img
 *       "/path/to/myarchive.7z#folder/to/game.img" -> game.img
 */
void fill_short_pathname_representation(char* out_rep,
                                        const char *in_path, size_t size)
{
    char path_short[PATH_MAX_LENGTH];
#ifdef HAVE_COMPRESSION
    char *last_slash                  = NULL;
#endif

    path_short[0] = '\0';

    fill_pathname(path_short, path_basename(in_path), "",
                  sizeof(path_short));

#ifdef HAVE_COMPRESSION
    last_slash  = find_last_slash(path_short);
    if (last_slash != NULL)
    {
        /* We handle paths like:
         * /path/to/file.7z#mygame.img
         * short_name: mygame.img:
         *
         * We check whether something is actually
         * after the hash to avoid going over the buffer.
         */
        retro_assert(strlen(last_slash) > 1);
        strlcpy(out_rep, last_slash + 1, size);
    }
    else
#endif
        strlcpy(out_rep, path_short, size);
}
Пример #4
0
const char *core_info_get_custom_config(const char *core_id, char *buffer, size_t buffer_length)
{
   if (!core_id || !buffer || !buffer_length)
      return 0;

   fill_pathname_join(buffer, g_defaults.menu_config_dir, path_basename(core_id), buffer_length);
   fill_pathname(buffer, buffer, ".cfg", buffer_length);
   return buffer;
}
Пример #5
0
/**
 * fill_short_pathname_representation:
 * @out_rep            : output representation
 * @in_path            : input path
 * @size               : size of output representation
 *
 * Generates a short representation of path. It should only
 * be used for displaying the result; the output representation is not
 * binding in any meaningful way (for a normal path, this is the same as basename)
 * In case of more complex URLs, this should cut everything except for
 * the main image file.
 *
 * E.g.: "/path/to/game.img" -> game.img
 *       "/path/to/myarchive.7z#folder/to/game.img" -> game.img
 */
void fill_short_pathname_representation(char* out_rep,
      const char *in_path, size_t size)
{
   char path_short[PATH_MAX_LENGTH];

   path_short[0] = '\0';

   fill_pathname(path_short, path_basename(in_path), "",
            sizeof(path_short));

   strlcpy(out_rep, path_short, size);
}
Пример #6
0
void rarch_fill_pathnames(void)
{
   global_t   *global   = global_get_ptr();

   rarch_init_savefile_paths();
   fill_pathname(global->bsv.movie_path, global->savefile_name, "",
         sizeof(global->bsv.movie_path));

   if (!*global->basename)
      return;

   if (!*global->ups_name)
      fill_pathname_noext(global->ups_name, global->basename, ".ups",
            sizeof(global->ups_name));
   if (!*global->bps_name)
      fill_pathname_noext(global->bps_name, global->basename, ".bps",
            sizeof(global->bps_name));
   if (!*global->ips_name)
      fill_pathname_noext(global->ips_name, global->basename, ".ips",
            sizeof(global->ips_name));
}
Пример #7
0
static void rarch_init_savefile_paths(void)
{
   global_t *global = global_get_ptr();

   event_command(EVENT_CMD_SAVEFILES_DEINIT);

   global->savefiles = string_list_new();
   rarch_assert(global->savefiles);

   if (*global->subsystem)
   {
      /* For subsystems, we know exactly which RAM types are supported. */

      unsigned i, j;
      const struct retro_subsystem_info *info =
         libretro_find_subsystem_info(
               global->system.special, global->system.num_special,
               global->subsystem);

      /* We'll handle this error gracefully later. */
      unsigned num_content = min(info ? info->num_roms : 0,
            global->subsystem_fullpaths ?
            global->subsystem_fullpaths->size : 0);

      bool use_sram_dir = path_is_directory(global->savefile_dir);

      for (i = 0; i < num_content; i++)
      {
         for (j = 0; j < info->roms[i].num_memory; j++)
         {
            union string_list_elem_attr attr;
            char path[PATH_MAX_LENGTH], ext[32];
            const struct retro_subsystem_memory_info *mem =
               (const struct retro_subsystem_memory_info*)
               &info->roms[i].memory[j];

            snprintf(ext, sizeof(ext), ".%s", mem->extension);

            if (use_sram_dir)
            {
               /* Redirect content fullpath to save directory. */
               strlcpy(path, global->savefile_dir, sizeof(path));
               fill_pathname_dir(path,
                     global->subsystem_fullpaths->elems[i].data, ext,
                     sizeof(path));
            }
            else
            {
               fill_pathname(path, global->subsystem_fullpaths->elems[i].data,
                     ext, sizeof(path));
            }

            attr.i = mem->type;
            string_list_append(global->savefiles, path, attr);
         }
      }

      /* Let other relevant paths be inferred from the main SRAM location. */
      if (!global->has_set_save_path)
         fill_pathname_noext(global->savefile_name, global->basename, ".srm",
               sizeof(global->savefile_name));
      if (path_is_directory(global->savefile_name))
      {
         fill_pathname_dir(global->savefile_name, global->basename, ".srm",
               sizeof(global->savefile_name));
         RARCH_LOG("Redirecting save file to \"%s\".\n",
               global->savefile_name);
      }
   }
   else
   {
      char savefile_name_rtc[PATH_MAX_LENGTH];
      union string_list_elem_attr attr;

      attr.i = RETRO_MEMORY_SAVE_RAM;
      string_list_append(global->savefiles, global->savefile_name, attr);

      /* Infer .rtc save path from save ram path. */
      attr.i = RETRO_MEMORY_RTC;
      fill_pathname(savefile_name_rtc,
            global->savefile_name, ".rtc", sizeof(savefile_name_rtc));
      string_list_append(global->savefiles, savefile_name_rtc, attr);
   }
}
Пример #8
0
int lutro_load(const char *path)
{
   char mainfile[PATH_MAX_LENGTH];
   char gamedir[PATH_MAX_LENGTH];

   strlcpy(mainfile, path, PATH_MAX_LENGTH);
   strlcpy(gamedir, path, PATH_MAX_LENGTH);

   if (path_is_directory(mainfile))
      fill_pathname_join(mainfile, gamedir, "main.lua", sizeof(mainfile));
   else
      path_basedir(gamedir);

   if (!strcmp(path_get_extension(mainfile), "lutro"))
   {
      fill_pathname(gamedir, mainfile, "/", sizeof(gamedir));
      lutro_unzip(mainfile, gamedir);
      fill_pathname_join(mainfile, gamedir, "main.lua", sizeof(mainfile));
   }

   fill_pathname_slash(gamedir, sizeof(gamedir));

   char package_path[PATH_MAX_LENGTH];
   snprintf(package_path, PATH_MAX_LENGTH, ";%s?.lua;%s?/init.lua", gamedir, gamedir);
   lutro_set_package_path(L, package_path);

   if(luaL_dofile(L, mainfile))
   {
       fprintf(stderr, "%s\n", lua_tostring(L, -1));
       lua_pop(L, 1);

       return 0;
   }

   lua_getglobal(L, "lutro");

   strlcpy(settings.gamedir, gamedir, PATH_MAX_LENGTH);

   lua_pushnumber(L, 0);
   lua_setfield(L, -2, "camera_x");

   lua_pushnumber(L, 0);
   lua_setfield(L, -2, "camera_y");

   lua_getfield(L, -1, "conf");

   if (lua_isnoneornil(L, -1))
   {
      puts("skipping custom configuration.");
   }
   else
   {
      lua_getfield(L, -2, "settings");

      if(lua_pcall(L, 1, 0, 0))
      {
         fprintf(stderr, "%s\n", lua_tostring(L, -1));
         lua_pop(L, 1);

         return 0;
      }

      lua_getfield(L, -1, "settings");

      lua_getfield(L, -1, "width");
      settings.width = lua_tointeger(L, -1);
      lua_remove(L, -1);

      lua_getfield(L, -1, "height");
      settings.height = lua_tointeger(L, -1);
      lua_remove(L, -1);

      lua_getfield(L, -1, "live_enable");
      settings.live_enable = lua_toboolean(L, -1);
      lua_remove(L, -1);

      lua_getfield(L, -1, "live_call_load");
      settings.live_call_load = lua_toboolean(L, -1);
      lua_remove(L, -1);
   }

   lua_pop(L, 1); // either lutro.settings or lutro.conf

   lutro_graphics_init();

#ifdef HAVE_INOTIFY
   if (settings.live_enable)
      lutro_live_init();
#endif

   lua_getfield(L, -1, "load");

   if (lua_isnoneornil(L, -1))
   {
      puts("skipping custom initialization.");
   }
   else
   {
      if(lua_pcall(L, 0, 0, 0))
      {
         fprintf(stderr, "%s\n", lua_tostring(L, -1));
         lua_pop(L, 1);

         return 0;
      }
   }

   lua_pop(L, 1);

   return 1;
}
Пример #9
0
static void init_menulist(unsigned menu_id)
{
   XuiListDeleteItems(m_menulist, 0, XuiListGetItemCount(m_menulist));

   switch (menu_id)
   {
      case INGAME_MENU_CORE_OPTIONS_MODE:
   if (g_extern.system.core_options)
   {
      size_t opts = core_option_size(g_extern.system.core_options);
      for (size_t i = 0; i < opts; i++)
      {
         char label[256];
         strlcpy(label, core_option_get_desc(g_extern.system.core_options, i),
            sizeof(label));
         snprintf(label, sizeof(label), "%s : %s", label,
            core_option_get_val(g_extern.system.core_options, i));
         mbstowcs(strw_buffer, label,
            sizeof(strw_buffer) / sizeof(wchar_t));
         XuiListInsertItems(m_menulist, i, 1);
         XuiListSetText(m_menulist, i, strw_buffer);
      }
   }
   else
   {
      XuiListInsertItems(m_menulist, 0, 1);
      XuiListSetText(m_menulist, 0, L"No options available.");
   }
         break;
      case INGAME_MENU_LOAD_GAME_HISTORY_MODE:
         {
            size_t history_size = rom_history_size(rgui->history);

            if (history_size)
            {
               size_t opts = history_size;
               for (size_t i = 0; i < opts; i++)
               {
                  const char *path = NULL;
                  const char *core_path = NULL;
                  const char *core_name = NULL;

                  rom_history_get_index(rgui->history, i,
                        &path, &core_path, &core_name);

                  char path_short[PATH_MAX];
                  fill_pathname(path_short, path_basename(path), "", sizeof(path_short));

                  char fill_buf[PATH_MAX];
                  snprintf(fill_buf, sizeof(fill_buf), "%s (%s)",
                        path_short, core_name);

                  mbstowcs(strw_buffer, fill_buf, sizeof(strw_buffer) / sizeof(wchar_t));
                  XuiListInsertItems(m_menulist, i, 1);
                  XuiListSetText(m_menulist, i, strw_buffer);
               }
            }
            else
            {
               XuiListInsertItems(m_menulist, 0, 1);
               XuiListSetText(m_menulist, 0, L"No history available.");
            }
         }
         break;
      case INGAME_MENU_INPUT_OPTIONS_MODE:
         {
            unsigned i;
            char buttons[RARCH_FIRST_META_KEY][128];
            unsigned keybind_end = RETRO_DEVICE_ID_JOYPAD_R3 + 1;

            for(i = 0; i < keybind_end; i++)
            {
               struct platform_bind key_label;
               strlcpy(key_label.desc, "Unknown", sizeof(key_label.desc));
               key_label.joykey = g_settings.input.binds[rgui->current_pad][i].joykey;

               if (driver.input->set_keybinds)
                  driver.input->set_keybinds(&key_label, 0, 0, 0, (1ULL << KEYBINDS_ACTION_GET_BIND_LABEL));

               snprintf(buttons[i], sizeof(buttons[i]), "%s #%d: %s", 
                     g_settings.input.binds[rgui->current_pad][i].desc,
                     rgui->current_pad, key_label.desc);
               mbstowcs(strw_buffer, buttons[i], sizeof(strw_buffer) / sizeof(wchar_t));
               XuiListInsertItems(m_menulist, i, 1);
               XuiListSetText(m_menulist, i, strw_buffer);
            }

            //set_dpad_emulation_label(rgui->current_pad, buttons[0], sizeof(buttons[0]));
            //mbstowcs(strw_buffer, buttons[0], sizeof(strw_buffer) / sizeof(wchar_t));
            XuiListInsertItems(m_menulist, keybind_end, 1);
            //XuiListSetText(m_menulist, SETTING_CONTROLS_DPAD_EMULATION, strw_buffer);
            XuiListSetText(m_menulist, SETTING_CONTROLS_DPAD_EMULATION, L"Stub");

            XuiListInsertItems(m_menulist, keybind_end + 1, 1);
            XuiListSetText(m_menulist, SETTING_CONTROLS_DEFAULT_ALL, L"Reset all buttons to default");
         }
         break;
      case INGAME_MENU_SETTINGS_MODE:
         XuiListInsertItems(m_menulist, INGAME_MENU_REWIND_ENABLED, 1);
         XuiListSetText(m_menulist, INGAME_MENU_REWIND_ENABLED, g_settings.rewind_enable ? L"Rewind: ON" : L"Rewind: OFF");
         menu_settings_create_menu_item_label_w(strw_buffer, S_LBL_REWIND_GRANULARITY, sizeof(strw_buffer));
         XuiListInsertItems(m_menulist, INGAME_MENU_REWIND_GRANULARITY, 1);
         XuiListSetText(m_menulist, INGAME_MENU_REWIND_GRANULARITY, strw_buffer);

         XuiListInsertItems(m_menulist, SETTING_EMU_SHOW_DEBUG_INFO_MSG, 1);
         XuiListSetText(m_menulist, SETTING_EMU_SHOW_DEBUG_INFO_MSG, (g_settings.fps_show) ? L"Show Framerate: ON" : L"Show Framerate: OFF");
         break;
      case INGAME_MENU_MAIN_MODE:
         XuiListInsertItems(m_menulist, INGAME_MENU_CHANGE_LIBRETRO_CORE, 1);
         XuiListSetText(m_menulist, INGAME_MENU_CHANGE_LIBRETRO_CORE, L"Core ...");

         XuiListInsertItems(m_menulist, INGAME_MENU_LOAD_GAME_HISTORY_MODE, 1);
         XuiListSetText(m_menulist, INGAME_MENU_LOAD_GAME_HISTORY_MODE, L"Load Game (History) ...");

         XuiListInsertItems(m_menulist, INGAME_MENU_CHANGE_GAME, 1);
         XuiListSetText(m_menulist, INGAME_MENU_CHANGE_GAME, L"Load Game ...");

         XuiListInsertItems(m_menulist, INGAME_MENU_CORE_OPTIONS_MODE, 1);
         XuiListSetText(m_menulist, INGAME_MENU_CORE_OPTIONS_MODE, L"Core Options ...");

         XuiListInsertItems(m_menulist, INGAME_MENU_VIDEO_OPTIONS_MODE, 1);
         XuiListSetText(m_menulist, INGAME_MENU_VIDEO_OPTIONS_MODE, L"Video Options ...");

         XuiListInsertItems(m_menulist, INGAME_MENU_AUDIO_OPTIONS_MODE, 1);
         XuiListSetText(m_menulist, INGAME_MENU_AUDIO_OPTIONS_MODE, L"Audio Options ...");

         XuiListInsertItems(m_menulist, INGAME_MENU_INPUT_OPTIONS_MODE, 1);
         XuiListSetText(m_menulist, INGAME_MENU_INPUT_OPTIONS_MODE, L"Input Options ...");

         XuiListInsertItems(m_menulist, INGAME_MENU_PATH_OPTIONS_MODE, 1);
         XuiListSetText(m_menulist, INGAME_MENU_PATH_OPTIONS_MODE, L"Path Options ...");

         XuiListInsertItems(m_menulist, INGAME_MENU_SETTINGS_MODE, 1);
         XuiListSetText(m_menulist, INGAME_MENU_SETTINGS_MODE, L"Settings ...");

         menu_settings_create_menu_item_label_w(strw_buffer, S_LBL_LOAD_STATE_SLOT, sizeof(strw_buffer));
         XuiListInsertItems(m_menulist, INGAME_MENU_LOAD_STATE, 1);
         XuiListSetText(m_menulist, INGAME_MENU_LOAD_STATE, strw_buffer);

         menu_settings_create_menu_item_label_w(strw_buffer, S_LBL_SAVE_STATE_SLOT, sizeof(strw_buffer));
         XuiListInsertItems(m_menulist, INGAME_MENU_SAVE_STATE, 1);
         XuiListSetText(m_menulist, INGAME_MENU_SAVE_STATE, strw_buffer);

         XuiListInsertItems(m_menulist, INGAME_MENU_SCREENSHOT_MODE, 1);
         XuiListSetText(m_menulist, INGAME_MENU_SCREENSHOT_MODE, L"Take Screenshot");

         XuiListInsertItems(m_menulist, INGAME_MENU_RETURN_TO_GAME, 1);
         XuiListSetText(m_menulist, INGAME_MENU_RETURN_TO_GAME, L"Resume Game");

         XuiListInsertItems(m_menulist, INGAME_MENU_RESET, 1);
         XuiListSetText(m_menulist, INGAME_MENU_RESET, L"Restart Game");

         XuiListInsertItems(m_menulist, INGAME_MENU_QUIT_RETROARCH, 1);
         XuiListSetText(m_menulist, INGAME_MENU_QUIT_RETROARCH, L"Quit RetroArch");
         break;
   }
}
Пример #10
0
static bool path_init_subsystem(void)
{
   unsigned i, j;
   const struct retro_subsystem_info *info = NULL;
   rarch_system_info_t             *system = NULL;
   global_t                        *global = global_get_ptr();

   runloop_ctl(RUNLOOP_CTL_SYSTEM_INFO_GET, &system);

   if (!system)
      return false;

   if (path_is_empty(RARCH_PATH_SUBSYSTEM))
      return false;

   /* For subsystems, we know exactly which RAM types are supported. */

   info = libretro_find_subsystem_info(
         system->subsystem.data,
         system->subsystem.size,
         path_get(RARCH_PATH_SUBSYSTEM));

   /* We'll handle this error gracefully later. */

   if (info)
   {
      unsigned num_content = MIN(info->num_roms,
            path_is_empty(RARCH_PATH_SUBSYSTEM) ?
            0 : subsystem_fullpaths->size);

      for (i = 0; i < num_content; i++)
      {
         for (j = 0; j < info->roms[i].num_memory; j++)
         {
            union string_list_elem_attr attr;
            char path[PATH_MAX_LENGTH];
            char ext[32];
            const struct retro_subsystem_memory_info *mem =
               (const struct retro_subsystem_memory_info*)
               &info->roms[i].memory[j];

            path[0] = ext[0] = '\0';

            snprintf(ext, sizeof(ext), ".%s", mem->extension);

            if (path_is_directory(dir_get(RARCH_DIR_SAVEFILE)))
            {
               /* Use SRAM dir */
               /* Redirect content fullpath to save directory. */
               strlcpy(path, dir_get(RARCH_DIR_SAVEFILE), sizeof(path));
               fill_pathname_dir(path,
                     subsystem_fullpaths->elems[i].data, ext,
                     sizeof(path));
            }
            else
            {
               fill_pathname(path, subsystem_fullpaths->elems[i].data,
                     ext, sizeof(path));
            }

            attr.i = mem->type;
            string_list_append((struct string_list*)savefile_ptr_get(), path, attr);
         }
      }
   }

   if (global)
   {
      /* Let other relevant paths be inferred from the main SRAM location. */
      if (!retroarch_override_setting_is_set(RARCH_OVERRIDE_SETTING_SAVE_PATH, NULL))
         fill_pathname_noext(global->name.savefile,
               path_main_basename,
               file_path_str(FILE_PATH_SRM_EXTENSION),
               sizeof(global->name.savefile));

      if (path_is_directory(global->name.savefile))
      {
         fill_pathname_dir(global->name.savefile,
               path_main_basename,
               file_path_str(FILE_PATH_SRM_EXTENSION),
               sizeof(global->name.savefile));
         RARCH_LOG("%s \"%s\".\n",
               msg_hash_to_str(MSG_REDIRECTING_SAVEFILE_TO),
               global->name.savefile);
      }
   }

   return true;
}