2013-12-19 17:10:14 +00:00
|
|
|
#include "common.h"
|
2018-04-18 20:28:05 +00:00
|
|
|
#include <algorithm>
|
2020-03-28 16:58:01 +00:00
|
|
|
#include <sstream>
|
2018-04-11 09:40:15 +00:00
|
|
|
|
2019-03-29 13:19:41 +00:00
|
|
|
// On windows, transform / to \\
|
|
|
|
|
2020-03-29 17:29:14 +00:00
|
|
|
std::string normalize_path_separator(std::string path)
|
2019-03-29 13:19:41 +00:00
|
|
|
{
|
2019-08-25 17:29:56 +00:00
|
|
|
#ifdef _WIN32
|
2019-03-29 13:19:41 +00:00
|
|
|
std::replace(path.begin(), path.end(), '/', '\\');
|
|
|
|
#endif
|
|
|
|
|
|
|
|
return path;
|
|
|
|
}
|
|
|
|
|
2018-04-11 09:40:15 +00:00
|
|
|
// given file/name.ext or file\name.ext returns file/ or file\, depending on the platform
|
|
|
|
// given name.ext returns ./ or .\, depending on the platform
|
2020-03-29 17:29:14 +00:00
|
|
|
std::string OS_dirname(std::string file)
|
2018-04-11 09:40:15 +00:00
|
|
|
{
|
2019-03-29 13:19:41 +00:00
|
|
|
file = normalize_path_separator(file);
|
2019-08-25 17:29:56 +00:00
|
|
|
#ifdef _WIN32
|
2018-04-11 09:40:15 +00:00
|
|
|
const char sep = '\\';
|
|
|
|
#else
|
|
|
|
const char sep = '/';
|
|
|
|
#endif
|
|
|
|
|
|
|
|
size_t last_slash = file.find_last_of(sep);
|
|
|
|
|
2020-03-29 17:29:14 +00:00
|
|
|
if (last_slash == std::string::npos)
|
2018-04-11 09:40:15 +00:00
|
|
|
{
|
2020-03-29 17:29:14 +00:00
|
|
|
std::string local_dir = ".";
|
2018-04-11 09:40:15 +00:00
|
|
|
local_dir += sep;
|
|
|
|
return local_dir;
|
|
|
|
}
|
|
|
|
|
|
|
|
return file.substr(0, last_slash + 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
#if 0 // TODO: Move this to some tests, make it platform agnostic
|
|
|
|
namespace {
|
|
|
|
struct OS_dirname_Test {
|
|
|
|
OS_dirname_Test() {
|
|
|
|
verify(OS_dirname("local/path") == "local/");
|
|
|
|
verify(OS_dirname("local/path/two") == "local/path/");
|
|
|
|
verify(OS_dirname("local/path/three\\a.exe") == "local/path/");
|
|
|
|
verify(OS_dirname("local.ext") == "./");
|
|
|
|
}
|
2018-04-18 20:28:05 +00:00
|
|
|
} test1;
|
|
|
|
|
|
|
|
struct normalize_path_separator_Test {
|
|
|
|
normalize_path_separator_Test() {
|
|
|
|
verify(normalize_path_separator("local/path") == "local/path");
|
|
|
|
verify(normalize_path_separator("local\\path") == "local/path");
|
|
|
|
verify(normalize_path_separator("local\\path\\") == "local/path/");
|
|
|
|
verify(normalize_path_separator("\\local\\path\\") == "/local/path/");
|
|
|
|
verify(normalize_path_separator("loc\\al\\pa\\th") == "loc/al/pa/th");
|
|
|
|
}
|
|
|
|
} test2;
|
2018-04-11 09:40:15 +00:00
|
|
|
}
|
2018-04-02 06:46:46 +00:00
|
|
|
#endif
|
2013-12-19 17:10:14 +00:00
|
|
|
|
2014-06-13 15:41:48 +00:00
|
|
|
Disc* load_gdi(const char* file)
|
2013-12-19 17:10:14 +00:00
|
|
|
{
|
2021-01-19 10:11:01 +00:00
|
|
|
FILE *t = nowide::fopen(file, "rb");
|
2013-12-19 17:10:14 +00:00
|
|
|
if (!t)
|
2020-01-31 09:35:10 +00:00
|
|
|
return nullptr;
|
2015-01-09 14:50:07 +00:00
|
|
|
|
2021-01-19 10:11:01 +00:00
|
|
|
size_t gdi_len = flycast::fsize(t);
|
2015-01-09 14:50:07 +00:00
|
|
|
|
|
|
|
char gdi_data[8193] = { 0 };
|
|
|
|
|
|
|
|
if (gdi_len >= sizeof(gdi_data))
|
|
|
|
{
|
2020-01-31 09:35:10 +00:00
|
|
|
WARN_LOG(GDROM, "GDI: file too big");
|
2021-01-19 10:11:01 +00:00
|
|
|
std::fclose(t);
|
2020-01-31 09:35:10 +00:00
|
|
|
return nullptr;
|
2015-01-09 14:50:07 +00:00
|
|
|
}
|
|
|
|
|
2021-01-19 10:11:01 +00:00
|
|
|
std::fread(gdi_data, 1, gdi_len, t);
|
|
|
|
std::fclose(t);
|
2015-01-09 14:50:07 +00:00
|
|
|
|
2020-03-29 17:29:14 +00:00
|
|
|
std::istringstream gdi(gdi_data);
|
2015-01-09 14:50:07 +00:00
|
|
|
|
2020-01-31 09:35:10 +00:00
|
|
|
u32 iso_tc = 0;
|
2015-01-09 14:50:07 +00:00
|
|
|
gdi >> iso_tc;
|
2020-01-31 09:35:10 +00:00
|
|
|
if (iso_tc == 0)
|
|
|
|
{
|
|
|
|
WARN_LOG(GDROM, "GDI: empty or invalid GDI file");
|
|
|
|
return nullptr;
|
|
|
|
}
|
2019-07-01 14:10:28 +00:00
|
|
|
INFO_LOG(GDROM, "GDI : %d tracks", iso_tc);
|
2020-03-29 17:29:14 +00:00
|
|
|
|
|
|
|
std::string basepath = OS_dirname(file);
|
2016-02-22 17:40:11 +00:00
|
|
|
|
2020-01-31 09:35:10 +00:00
|
|
|
Disc* disc = new Disc();
|
2013-12-19 17:10:14 +00:00
|
|
|
u32 TRACK=0,FADS=0,CTRL=0,SSIZE=0;
|
|
|
|
s32 OFFSET=0;
|
|
|
|
for (u32 i=0;i<iso_tc;i++)
|
|
|
|
{
|
2020-03-29 17:29:14 +00:00
|
|
|
std::string track_filename;
|
2015-01-09 14:50:07 +00:00
|
|
|
|
2013-12-19 17:10:14 +00:00
|
|
|
//TRACK FADS CTRL SSIZE file OFFSET
|
2015-01-09 14:50:07 +00:00
|
|
|
gdi >> TRACK;
|
|
|
|
gdi >> FADS;
|
|
|
|
gdi >> CTRL;
|
|
|
|
gdi >> SSIZE;
|
|
|
|
|
|
|
|
char last;
|
|
|
|
|
|
|
|
do {
|
|
|
|
gdi >> last;
|
|
|
|
} while (isspace(last));
|
|
|
|
|
|
|
|
if (last == '"')
|
2013-12-19 17:10:14 +00:00
|
|
|
{
|
2018-06-25 07:14:51 +00:00
|
|
|
gdi >> std::noskipws;
|
2015-01-09 14:50:07 +00:00
|
|
|
for(;;) {
|
2018-06-25 07:14:51 +00:00
|
|
|
gdi >> last;
|
2015-01-09 14:50:07 +00:00
|
|
|
if (last == '"')
|
|
|
|
break;
|
|
|
|
track_filename += last;
|
|
|
|
}
|
2018-06-24 12:30:46 +00:00
|
|
|
gdi >> std::skipws;
|
2013-12-19 17:10:14 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2015-01-09 14:50:07 +00:00
|
|
|
gdi >> track_filename;
|
|
|
|
track_filename = last + track_filename;
|
2013-12-19 17:10:14 +00:00
|
|
|
}
|
|
|
|
|
2015-01-09 14:50:07 +00:00
|
|
|
gdi >> OFFSET;
|
2013-12-19 17:10:14 +00:00
|
|
|
|
2019-07-01 14:10:28 +00:00
|
|
|
DEBUG_LOG(GDROM, "file[%d] \"%s\": FAD:%d, CTRL:%d, SSIZE:%d, OFFSET:%d", TRACK, track_filename.c_str(), FADS, CTRL, SSIZE, OFFSET);
|
2013-12-19 17:10:14 +00:00
|
|
|
|
|
|
|
Track t;
|
|
|
|
t.ADDR=0;
|
|
|
|
t.StartFAD=FADS+150;
|
|
|
|
t.EndFAD=0; //fill it in
|
|
|
|
t.file=0;
|
2019-03-16 11:06:29 +00:00
|
|
|
t.CTRL = CTRL;
|
2013-12-19 17:10:14 +00:00
|
|
|
|
|
|
|
if (SSIZE!=0)
|
|
|
|
{
|
2020-03-29 17:29:14 +00:00
|
|
|
std::string path = basepath + normalize_path_separator(track_filename);
|
2021-01-19 10:11:01 +00:00
|
|
|
t.file = new RawTrackFile(nowide::fopen(path.c_str(), "rb"), OFFSET, t.StartFAD,SSIZE);
|
2013-12-19 17:10:14 +00:00
|
|
|
}
|
2020-06-17 20:58:26 +00:00
|
|
|
if (!disc->tracks.empty())
|
|
|
|
disc->tracks.back().EndFAD = t.StartFAD - 1;
|
2013-12-19 17:10:14 +00:00
|
|
|
disc->tracks.push_back(t);
|
|
|
|
}
|
|
|
|
|
|
|
|
disc->FillGDSession();
|
|
|
|
|
|
|
|
return disc;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-06-13 15:41:48 +00:00
|
|
|
Disc* gdi_parse(const char* file)
|
2013-12-19 17:10:14 +00:00
|
|
|
{
|
|
|
|
size_t len=strlen(file);
|
|
|
|
if (len>4)
|
|
|
|
{
|
|
|
|
if (stricmp( &file[len-4],".gdi")==0)
|
|
|
|
{
|
|
|
|
return load_gdi(file);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|