Skip to content

Commit ebcae54

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

1 file changed

Lines changed: 63 additions & 4 deletions

File tree

libretro/main.cpp

Lines changed: 63 additions & 4 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")
@@ -713,13 +763,22 @@ bool retro_load_game(const struct retro_game_info* game)
713763

714764
VMManager::ApplySettings();
715765

716-
image_index = 0;
717766
disk_images.clear();
718767
VMBootParameters boot_params;
719768
if(game && game->path)
720769
{
721-
disk_images.push_back(game->path);
722-
boot_params.filename = game->path;
770+
std::vector<std::string> game_paths;
771+
if (Path::GetExtension(game->path) == "m3u")
772+
{
773+
game_paths = read_m3u_file(game->path);
774+
log_cb(RETRO_LOG_DEBUG, "Found %u game images in M3U file.", game_paths.size());
775+
}
776+
else
777+
{
778+
game_paths.push_back(game->path);
779+
}
780+
disk_images.assign(game_paths.begin(), game_paths.end());
781+
boot_params.filename = disk_images[get_image_index()];
723782
}
724783

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

0 commit comments

Comments
 (0)