Skip to content

Commit af65ea0

Browse files
committed
add m3u support
1 parent 0b690a2 commit af65ea0

1 file changed

Lines changed: 63 additions & 3 deletions

File tree

libretro/main.cpp

Lines changed: 63 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include <libretro.h>
1414
#include <string>
1515
#include <thread>
16+
#include <fstream>
1617

1718
#include "options.h"
1819

@@ -358,11 +359,60 @@ void retro_get_system_info(retro_system_info* info)
358359
#endif
359360

360361
info->library_name = "pcsx2";
361-
info->valid_extensions = "elf|iso|ciso|cue|bin|gz";
362+
info->valid_extensions = "elf|iso|ciso|cue|bin|gz|m3u";
362363
info->need_fullpath = true;
363364
info->block_extract = true;
364365
}
365366

367+
368+
static std::vector<std::string>
369+
read_m3u_file(const std::string& m3u_file)
370+
{
371+
log_cb(RETRO_LOG_DEBUG, "Reading M3U file");
372+
std::vector<std::string> result;
373+
std::ifstream m3u_data(m3u_file);
374+
if (!m3u_data.is_open())
375+
{
376+
log_cb(RETRO_LOG_ERROR, "M3U file \"%s\" cannot be read", m3u_file.c_str());
377+
return result;
378+
}
379+
// This is the UTF-8 representation of U+FEFF.
380+
const std::string utf8_bom = "\xEF\xBB\xBF";
381+
std::string line;
382+
getline(m3u_data, line);
383+
if (line.rfind(utf8_bom,0) == 0)
384+
{
385+
log_cb(RETRO_LOG_WARN, "M3U file \"%s\" contains UTF-8 BOM", m3u_file.c_str());
386+
line.erase(0, utf8_bom.length());
387+
}
388+
std::string m3u_parent = Path::Canonicalize(Path::GetDirectory(m3u_file));
389+
for (line; !m3u_data.eof(); getline(m3u_data, line))
390+
{
391+
if (!line.rfind('#', 0) == 0) // Comments start with #
392+
{
393+
std::string m3u_path = line;
394+
if (!Path::IsAbsolute(line))
395+
{
396+
m3u_path = Path::Combine(m3u_parent, line);
397+
}
398+
std::ifstream discFile(m3u_path);
399+
if (discFile.is_open())
400+
{
401+
log_cb(RETRO_LOG_DEBUG, "Found disc image in M3U file, %s", m3u_path.c_str());
402+
result.push_back(m3u_path);
403+
}
404+
else
405+
{
406+
log_cb(RETRO_LOG_WARN, "File specified in the M3U file \"%s\" was not found", m3u_path.c_str());
407+
}
408+
}
409+
}
410+
if (result.empty())
411+
log_cb(RETRO_LOG_ERROR, "No paths found in the M3U file \"%s\"", m3u_file.c_str());
412+
413+
return result;
414+
}
415+
366416
void retro_get_system_av_info(retro_system_av_info* info)
367417
{
368418
if (Options::renderer == "Software" || Options::renderer == "Null")
@@ -718,8 +768,18 @@ bool retro_load_game(const struct retro_game_info* game)
718768
VMBootParameters boot_params;
719769
if(game && game->path)
720770
{
721-
disk_images.push_back(game->path);
722-
boot_params.filename = game->path;
771+
std::vector<std::string> game_paths;
772+
if (Path::GetExtension(game->path) == "m3u")
773+
{
774+
game_paths = read_m3u_file(game->path);
775+
log_cb(RETRO_LOG_DEBUG, "Found %u game images in M3U file.", game_paths.size());
776+
}
777+
else
778+
{
779+
game_paths.push_back(game->path);
780+
}
781+
disk_images.assign(game_paths.begin(), game_paths.end());
782+
boot_params.filename = disk_images[0];
723783
}
724784

725785
cpu_thread = std::thread(cpu_thread_entry, boot_params);

0 commit comments

Comments
 (0)