Added support for scraping title screens, box back covers and physical media images.

This commit is contained in:
Leon Styhre 2021-10-28 21:00:23 +02:00
parent d21688ebda
commit d5fa6bc82c
15 changed files with 283 additions and 30 deletions

View file

@ -208,7 +208,7 @@ const std::string FileData::getMediaDirectory()
return mediaDirPath; return mediaDirPath;
} }
const std::string FileData::getMediafilePath(std::string subdirectory, std::string mediatype) const const std::string FileData::getMediafilePath(std::string subdirectory) const
{ {
const std::vector<std::string> extList = {".png", ".jpg"}; const std::vector<std::string> extList = {".png", ".jpg"};
std::string subFolders; std::string subFolders;
@ -234,53 +234,76 @@ const std::string FileData::getMediafilePath(std::string subdirectory, std::stri
const std::string FileData::getImagePath() const const std::string FileData::getImagePath() const
{ {
// Look for a mix image (a combination of screenshot, 2D/3D box and marquee). // Look for a mix image (a combination of screenshot, 2D/3D box and marquee).
std::string image = getMediafilePath("miximages", "miximage"); std::string image = getMediafilePath("miximages");
if (image != "") if (image != "")
return image; return image;
// If no mix image was found, try screenshot instead. // If no mix image was found, try screenshot instead.
image = getMediafilePath("screenshots", "screenshot"); image = getMediafilePath("screenshots");
if (image != "")
return image;
// If no screenshot image was found, try title screen instead.
image = getMediafilePath("titlescreens");
if (image != "") if (image != "")
return image; return image;
// If no screenshot was found either, try cover. // If no screenshot was found either, try cover.
return getMediafilePath("covers", "cover"); return getMediafilePath("covers");
} }
const std::string FileData::get3DBoxPath() const const std::string FileData::get3DBoxPath() const
{ {
// Return path to the 3D box image. // Return path to the 3D box image.
return getMediafilePath("3dboxes", "3dbox"); return getMediafilePath("3dboxes");
}
const std::string FileData::getBackCoverPath() const
{
// Return path to the box back cover image.
return getMediafilePath("backcovers");
} }
const std::string FileData::getCoverPath() const const std::string FileData::getCoverPath() const
{ {
// Return path to the cover image. // Return path to the box cover image.
return getMediafilePath("covers", "cover"); return getMediafilePath("covers");
} }
const std::string FileData::getMarqueePath() const const std::string FileData::getMarqueePath() const
{ {
// Return path to the marquee image. // Return path to the marquee image.
return getMediafilePath("marquees", "marquee"); return getMediafilePath("marquees");
}
const std::string FileData::getPhysicalMediaPath() const
{
// Return path to the physical media image.
return getMediafilePath("physicalmedia");
} }
const std::string FileData::getMiximagePath() const const std::string FileData::getMiximagePath() const
{ {
// Return path to the miximage. // Return path to the miximage.
return getMediafilePath("miximages", "miximage"); return getMediafilePath("miximages");
} }
const std::string FileData::getScreenshotPath() const const std::string FileData::getScreenshotPath() const
{ {
// Return path to the screenshot image. // Return path to the screenshot image.
return getMediafilePath("screenshots", "screenshot"); return getMediafilePath("screenshots");
}
const std::string FileData::getTitleScreenPath() const
{
// Return path to the title screen image.
return getMediafilePath("titlescreens");
} }
const std::string FileData::getThumbnailPath() const const std::string FileData::getThumbnailPath() const
{ {
// Return path to the thumbnail image. // Return path to the thumbnail image.
return getMediafilePath("thumbnails", "thumbnail"); return getMediafilePath("thumbnails");
} }
const std::string FileData::getVideoPath() const const std::string FileData::getVideoPath() const

View file

@ -60,13 +60,16 @@ public:
const bool getHasFoldersFlag() { return mHasFolders; } const bool getHasFoldersFlag() { return mHasFolders; }
static const std::string getROMDirectory(); static const std::string getROMDirectory();
static const std::string getMediaDirectory(); static const std::string getMediaDirectory();
const std::string getMediafilePath(std::string subdirectory, std::string mediatype) const; const std::string getMediafilePath(std::string subdirectory) const;
const std::string getImagePath() const; const std::string getImagePath() const;
const std::string get3DBoxPath() const; const std::string get3DBoxPath() const;
const std::string getBackCoverPath() const;
const std::string getCoverPath() const; const std::string getCoverPath() const;
const std::string getMarqueePath() const; const std::string getMarqueePath() const;
const std::string getPhysicalMediaPath() const;
const std::string getMiximagePath() const; const std::string getMiximagePath() const;
const std::string getScreenshotPath() const; const std::string getScreenshotPath() const;
const std::string getTitleScreenPath() const;
const std::string getThumbnailPath() const; const std::string getThumbnailPath() const;
const std::string getVideoPath() const; const std::string getVideoPath() const;

View file

@ -41,7 +41,8 @@ bool MediaViewer::startMediaViewer(FileData* game)
mHasVideo = false; mHasVideo = false;
mHasImages = false; mHasImages = false;
mCurrentImageIndex = 0; mCurrentImageIndex = 0;
mScreenShotIndex = -1; mScreenshotIndex = -1;
mTitleScreenIndex = -1;
mGame = game; mGame = game;
@ -125,9 +126,12 @@ void MediaViewer::render(const glm::mat4& /*parentTrans*/)
mImage->render(trans); mImage->render(trans);
#if defined(USE_OPENGL_21) #if defined(USE_OPENGL_21)
if (mCurrentImageIndex == mScreenShotIndex && if (mCurrentImageIndex == mScreenshotIndex &&
Settings::getInstance()->getBool("MediaViewerScreenshotScanlines")) Settings::getInstance()->getBool("MediaViewerScreenshotScanlines"))
Renderer::shaderPostprocessing(Renderer::SHADER_SCANLINES); Renderer::shaderPostprocessing(Renderer::SHADER_SCANLINES);
else if (mCurrentImageIndex == mTitleScreenIndex &&
Settings::getInstance()->getBool("MediaViewerScreenshotScanlines"))
Renderer::shaderPostprocessing(Renderer::SHADER_SCANLINES);
#endif #endif
// This is necessary so that the video loops if viewing an image when // This is necessary so that the video loops if viewing an image when
@ -164,15 +168,23 @@ void MediaViewer::findMedia()
if (!mHasVideo && (mediaFile = mGame->getScreenshotPath()) != "") { if (!mHasVideo && (mediaFile = mGame->getScreenshotPath()) != "") {
mImageFiles.push_back(mediaFile); mImageFiles.push_back(mediaFile);
mScreenShotIndex = 0; mScreenshotIndex = 0;
} }
if ((mediaFile = mGame->getCoverPath()) != "") if ((mediaFile = mGame->getCoverPath()) != "")
mImageFiles.push_back(mediaFile); mImageFiles.push_back(mediaFile);
if ((mediaFile = mGame->getBackCoverPath()) != "")
mImageFiles.push_back(mediaFile);
if ((mediaFile = mGame->getTitleScreenPath()) != "") {
mImageFiles.push_back(mediaFile);
mTitleScreenIndex = static_cast<int>(mImageFiles.size() - 1);
}
if (mHasVideo && (mediaFile = mGame->getScreenshotPath()) != "") { if (mHasVideo && (mediaFile = mGame->getScreenshotPath()) != "") {
mImageFiles.push_back(mediaFile); mImageFiles.push_back(mediaFile);
mScreenShotIndex = static_cast<int>(mImageFiles.size() - 1); mScreenshotIndex = static_cast<int>(mImageFiles.size() - 1);
} }
if ((mediaFile = mGame->getMiximagePath()) != "") if ((mediaFile = mGame->getMiximagePath()) != "")

View file

@ -44,7 +44,8 @@ private:
bool mDisplayingImage; bool mDisplayingImage;
int mCurrentImageIndex; int mCurrentImageIndex;
int mScreenShotIndex; int mScreenshotIndex;
int mTitleScreenIndex;
std::string mVideoFile; std::string mVideoFile;
std::vector<std::string> mImageFiles; std::vector<std::string> mImageFiles;

View file

@ -66,11 +66,11 @@ GuiMediaViewerOptions::GuiMediaViewerOptions(Window* window, const std::string&
} }
}); });
// Render scanlines for screenshots using a shader. // Render scanlines for screenshots and title screens using a shader.
auto screenshot_scanlines = std::make_shared<SwitchComponent>(mWindow); auto screenshot_scanlines = std::make_shared<SwitchComponent>(mWindow);
screenshot_scanlines->setState( screenshot_scanlines->setState(
Settings::getInstance()->getBool("MediaViewerScreenshotScanlines")); Settings::getInstance()->getBool("MediaViewerScreenshotScanlines"));
addWithLabel("RENDER SCANLINES FOR SCREENSHOTS", screenshot_scanlines); addWithLabel("RENDER SCANLINES FOR SCREENSHOTS AND TITLES", screenshot_scanlines);
addSaveFunc([screenshot_scanlines, this] { addSaveFunc([screenshot_scanlines, this] {
if (screenshot_scanlines->getState() != if (screenshot_scanlines->getState() !=
Settings::getInstance()->getBool("MediaViewerScreenshotScanlines")) { Settings::getInstance()->getBool("MediaViewerScreenshotScanlines")) {

View file

@ -221,7 +221,7 @@ void GuiScraperMenu::openContentOptions()
// Scrape game names. // Scrape game names.
auto scrape_game_names = std::make_shared<SwitchComponent>(mWindow); auto scrape_game_names = std::make_shared<SwitchComponent>(mWindow);
scrape_game_names->setState(Settings::getInstance()->getBool("ScrapeGameNames")); scrape_game_names->setState(Settings::getInstance()->getBool("ScrapeGameNames"));
s->addWithLabel("SCRAPE GAME NAMES", scrape_game_names); s->addWithLabel("GAME NAMES", scrape_game_names);
s->addSaveFunc([scrape_game_names, s] { s->addSaveFunc([scrape_game_names, s] {
if (scrape_game_names->getState() != Settings::getInstance()->getBool("ScrapeGameNames")) { if (scrape_game_names->getState() != Settings::getInstance()->getBool("ScrapeGameNames")) {
Settings::getInstance()->setBool("ScrapeGameNames", scrape_game_names->getState()); Settings::getInstance()->setBool("ScrapeGameNames", scrape_game_names->getState());
@ -232,7 +232,7 @@ void GuiScraperMenu::openContentOptions()
// Scrape ratings. // Scrape ratings.
auto scrape_ratings = std::make_shared<SwitchComponent>(mWindow); auto scrape_ratings = std::make_shared<SwitchComponent>(mWindow);
scrape_ratings->setState(Settings::getInstance()->getBool("ScrapeRatings")); scrape_ratings->setState(Settings::getInstance()->getBool("ScrapeRatings"));
s->addWithLabel("SCRAPE RATINGS", scrape_ratings); s->addWithLabel("RATINGS", scrape_ratings);
s->addSaveFunc([scrape_ratings, s] { s->addSaveFunc([scrape_ratings, s] {
if (scrape_ratings->getState() != Settings::getInstance()->getBool("ScrapeRatings")) { if (scrape_ratings->getState() != Settings::getInstance()->getBool("ScrapeRatings")) {
Settings::getInstance()->setBool("ScrapeRatings", scrape_ratings->getState()); Settings::getInstance()->setBool("ScrapeRatings", scrape_ratings->getState());
@ -252,7 +252,7 @@ void GuiScraperMenu::openContentOptions()
// Scrape controllers (arcade systems only). // Scrape controllers (arcade systems only).
auto scrapeControllers = std::make_shared<SwitchComponent>(mWindow); auto scrapeControllers = std::make_shared<SwitchComponent>(mWindow);
scrapeControllers->setState(Settings::getInstance()->getBool("ScrapeControllers")); scrapeControllers->setState(Settings::getInstance()->getBool("ScrapeControllers"));
s->addWithLabel("SCRAPE CONTROLLERS (ARCADE SYSTEMS ONLY)", scrapeControllers); s->addWithLabel("CONTROLLERS (ARCADE SYSTEMS ONLY)", scrapeControllers);
s->addSaveFunc([scrapeControllers, s] { s->addSaveFunc([scrapeControllers, s] {
if (scrapeControllers->getState() != if (scrapeControllers->getState() !=
Settings::getInstance()->getBool("ScrapeControllers")) { Settings::getInstance()->getBool("ScrapeControllers")) {
@ -274,7 +274,7 @@ void GuiScraperMenu::openContentOptions()
// Scrape other metadata. // Scrape other metadata.
auto scrape_metadata = std::make_shared<SwitchComponent>(mWindow); auto scrape_metadata = std::make_shared<SwitchComponent>(mWindow);
scrape_metadata->setState(Settings::getInstance()->getBool("ScrapeMetadata")); scrape_metadata->setState(Settings::getInstance()->getBool("ScrapeMetadata"));
s->addWithLabel("SCRAPE OTHER METADATA", scrape_metadata); s->addWithLabel("OTHER METADATA", scrape_metadata);
s->addSaveFunc([scrape_metadata, s] { s->addSaveFunc([scrape_metadata, s] {
if (scrape_metadata->getState() != Settings::getInstance()->getBool("ScrapeMetadata")) { if (scrape_metadata->getState() != Settings::getInstance()->getBool("ScrapeMetadata")) {
Settings::getInstance()->setBool("ScrapeMetadata", scrape_metadata->getState()); Settings::getInstance()->setBool("ScrapeMetadata", scrape_metadata->getState());
@ -285,7 +285,7 @@ void GuiScraperMenu::openContentOptions()
// Scrape videos. // Scrape videos.
auto scrape_videos = std::make_shared<SwitchComponent>(mWindow); auto scrape_videos = std::make_shared<SwitchComponent>(mWindow);
scrape_videos->setState(Settings::getInstance()->getBool("ScrapeVideos")); scrape_videos->setState(Settings::getInstance()->getBool("ScrapeVideos"));
s->addWithLabel("SCRAPE VIDEOS", scrape_videos); s->addWithLabel("VIDEOS", scrape_videos);
s->addSaveFunc([scrape_videos, s] { s->addSaveFunc([scrape_videos, s] {
if (scrape_videos->getState() != Settings::getInstance()->getBool("ScrapeVideos")) { if (scrape_videos->getState() != Settings::getInstance()->getBool("ScrapeVideos")) {
Settings::getInstance()->setBool("ScrapeVideos", scrape_videos->getState()); Settings::getInstance()->setBool("ScrapeVideos", scrape_videos->getState());
@ -305,7 +305,7 @@ void GuiScraperMenu::openContentOptions()
// Scrape screenshots images. // Scrape screenshots images.
auto scrape_screenshots = std::make_shared<SwitchComponent>(mWindow); auto scrape_screenshots = std::make_shared<SwitchComponent>(mWindow);
scrape_screenshots->setState(Settings::getInstance()->getBool("ScrapeScreenshots")); scrape_screenshots->setState(Settings::getInstance()->getBool("ScrapeScreenshots"));
s->addWithLabel("SCRAPE SCREENSHOT IMAGES", scrape_screenshots); s->addWithLabel("SCREENSHOT IMAGES", scrape_screenshots);
s->addSaveFunc([scrape_screenshots, s] { s->addSaveFunc([scrape_screenshots, s] {
if (scrape_screenshots->getState() != if (scrape_screenshots->getState() !=
Settings::getInstance()->getBool("ScrapeScreenshots")) { Settings::getInstance()->getBool("ScrapeScreenshots")) {
@ -314,10 +314,22 @@ void GuiScraperMenu::openContentOptions()
} }
}); });
// Scrape cover images. // Scrape title screen images.
auto scrapeTitleScreens = std::make_shared<SwitchComponent>(mWindow);
scrapeTitleScreens->setState(Settings::getInstance()->getBool("ScrapeTitleScreens"));
s->addWithLabel("TITLE SCREEN IMAGES", scrapeTitleScreens);
s->addSaveFunc([scrapeTitleScreens, s] {
if (scrapeTitleScreens->getState() !=
Settings::getInstance()->getBool("ScrapeTitleScreens")) {
Settings::getInstance()->setBool("ScrapeTitleScreens", scrapeTitleScreens->getState());
s->setNeedsSaving();
}
});
// Scrape box cover images.
auto scrape_covers = std::make_shared<SwitchComponent>(mWindow); auto scrape_covers = std::make_shared<SwitchComponent>(mWindow);
scrape_covers->setState(Settings::getInstance()->getBool("ScrapeCovers")); scrape_covers->setState(Settings::getInstance()->getBool("ScrapeCovers"));
s->addWithLabel("SCRAPE BOX COVER IMAGES", scrape_covers); s->addWithLabel("BOX COVER IMAGES", scrape_covers);
s->addSaveFunc([scrape_covers, s] { s->addSaveFunc([scrape_covers, s] {
if (scrape_covers->getState() != Settings::getInstance()->getBool("ScrapeCovers")) { if (scrape_covers->getState() != Settings::getInstance()->getBool("ScrapeCovers")) {
Settings::getInstance()->setBool("ScrapeCovers", scrape_covers->getState()); Settings::getInstance()->setBool("ScrapeCovers", scrape_covers->getState());
@ -325,10 +337,31 @@ void GuiScraperMenu::openContentOptions()
} }
}); });
// Scrape box back cover images.
auto scrapeBackCovers = std::make_shared<SwitchComponent>(mWindow);
scrapeBackCovers->setState(Settings::getInstance()->getBool("ScrapeBackCovers"));
s->addWithLabel("BOX BACK COVER IMAGES", scrapeBackCovers);
s->addSaveFunc([scrapeBackCovers, s] {
if (scrapeBackCovers->getState() != Settings::getInstance()->getBool("ScrapeBackCovers")) {
Settings::getInstance()->setBool("ScrapeBackCovers", scrapeBackCovers->getState());
s->setNeedsSaving();
}
});
// Box back cover images are not supported by TheGamesDB, so gray out the option if this
// scraper is selected.
if (Settings::getInstance()->getString("Scraper") == "thegamesdb") {
scrapeBackCovers->setEnabled(false);
scrapeBackCovers->setOpacity(DISABLED_OPACITY);
scrapeBackCovers->getParent()
->getChild(scrapeBackCovers->getChildIndex() - 1)
->setOpacity(DISABLED_OPACITY);
}
// Scrape marquee images. // Scrape marquee images.
auto scrape_marquees = std::make_shared<SwitchComponent>(mWindow); auto scrape_marquees = std::make_shared<SwitchComponent>(mWindow);
scrape_marquees->setState(Settings::getInstance()->getBool("ScrapeMarquees")); scrape_marquees->setState(Settings::getInstance()->getBool("ScrapeMarquees"));
s->addWithLabel("SCRAPE MARQUEE (WHEEL) IMAGES", scrape_marquees); s->addWithLabel("MARQUEE (WHEEL) IMAGES", scrape_marquees);
s->addSaveFunc([scrape_marquees, s] { s->addSaveFunc([scrape_marquees, s] {
if (scrape_marquees->getState() != Settings::getInstance()->getBool("ScrapeMarquees")) { if (scrape_marquees->getState() != Settings::getInstance()->getBool("ScrapeMarquees")) {
Settings::getInstance()->setBool("ScrapeMarquees", scrape_marquees->getState()); Settings::getInstance()->setBool("ScrapeMarquees", scrape_marquees->getState());
@ -339,7 +372,7 @@ void GuiScraperMenu::openContentOptions()
// Scrape 3D box images. // Scrape 3D box images.
auto scrape_3dboxes = std::make_shared<SwitchComponent>(mWindow); auto scrape_3dboxes = std::make_shared<SwitchComponent>(mWindow);
scrape_3dboxes->setState(Settings::getInstance()->getBool("Scrape3DBoxes")); scrape_3dboxes->setState(Settings::getInstance()->getBool("Scrape3DBoxes"));
s->addWithLabel("SCRAPE 3D BOX IMAGES", scrape_3dboxes); s->addWithLabel("3D BOX IMAGES", scrape_3dboxes);
s->addSaveFunc([scrape_3dboxes, s] { s->addSaveFunc([scrape_3dboxes, s] {
if (scrape_3dboxes->getState() != Settings::getInstance()->getBool("Scrape3DBoxes")) { if (scrape_3dboxes->getState() != Settings::getInstance()->getBool("Scrape3DBoxes")) {
Settings::getInstance()->setBool("Scrape3DBoxes", scrape_3dboxes->getState()); Settings::getInstance()->setBool("Scrape3DBoxes", scrape_3dboxes->getState());
@ -357,6 +390,29 @@ void GuiScraperMenu::openContentOptions()
->setOpacity(DISABLED_OPACITY); ->setOpacity(DISABLED_OPACITY);
} }
// Scrape physical media images.
auto scrapePhysicalMedia = std::make_shared<SwitchComponent>(mWindow);
scrapePhysicalMedia->setState(Settings::getInstance()->getBool("ScrapePhysicalMedia"));
s->addWithLabel("PHYSICAL MEDIA IMAGES", scrapePhysicalMedia);
s->addSaveFunc([scrapePhysicalMedia, s] {
if (scrapePhysicalMedia->getState() !=
Settings::getInstance()->getBool("ScrapePhysicalMedia")) {
Settings::getInstance()->setBool("ScrapePhysicalMedia",
scrapePhysicalMedia->getState());
s->setNeedsSaving();
}
});
// Physical media images are not supported by TheGamesDB, so gray out the option if this
// scraper is selected.
if (Settings::getInstance()->getString("Scraper") == "thegamesdb") {
scrapePhysicalMedia->setEnabled(false);
scrapePhysicalMedia->setOpacity(DISABLED_OPACITY);
scrapePhysicalMedia->getParent()
->getChild(scrapePhysicalMedia->getChildIndex() - 1)
->setOpacity(DISABLED_OPACITY);
}
mWindow->pushGui(s); mWindow->pushGui(s);
} }
@ -884,10 +940,19 @@ void GuiScraperMenu::start()
contentToScrape = true; contentToScrape = true;
break; break;
} }
if (Settings::getInstance()->getBool("ScrapeTitleScreens")) {
contentToScrape = true;
break;
}
if (Settings::getInstance()->getBool("ScrapeCovers")) { if (Settings::getInstance()->getBool("ScrapeCovers")) {
contentToScrape = true; contentToScrape = true;
break; break;
} }
if (scraperService == "screenscraper" &&
Settings::getInstance()->getBool("ScrapeBackCovers")) {
contentToScrape = true;
break;
}
if (Settings::getInstance()->getBool("ScrapeMarquees")) { if (Settings::getInstance()->getBool("ScrapeMarquees")) {
contentToScrape = true; contentToScrape = true;
break; break;
@ -897,6 +962,11 @@ void GuiScraperMenu::start()
contentToScrape = true; contentToScrape = true;
break; break;
} }
if (scraperService == "screenscraper" &&
Settings::getInstance()->getBool("ScrapePhysicalMedia")) {
contentToScrape = true;
break;
}
} while (0); } while (0);
if (!contentToScrape) { if (!contentToScrape) {

View file

@ -678,9 +678,12 @@ void GuiScraperSearch::update(int deltaTime)
for (unsigned int i = 0; i < results_scrape.size(); i++) { for (unsigned int i = 0; i < results_scrape.size(); i++) {
if (results_scrape[i].gameID == it->gameID) { if (results_scrape[i].gameID == it->gameID) {
results_scrape[i].box3DUrl = it->box3DUrl; results_scrape[i].box3DUrl = it->box3DUrl;
results_scrape[i].backcoverUrl = it->backcoverUrl;
results_scrape[i].coverUrl = it->coverUrl; results_scrape[i].coverUrl = it->coverUrl;
results_scrape[i].marqueeUrl = it->marqueeUrl; results_scrape[i].marqueeUrl = it->marqueeUrl;
results_scrape[i].screenshotUrl = it->screenshotUrl; results_scrape[i].screenshotUrl = it->screenshotUrl;
results_scrape[i].titlescreenUrl = it->titlescreenUrl;
results_scrape[i].physicalmediaUrl = it->physicalmediaUrl;
results_scrape[i].videoUrl = it->videoUrl; results_scrape[i].videoUrl = it->videoUrl;
results_scrape[i].scraperRequestAllowance = it->scraperRequestAllowance; results_scrape[i].scraperRequestAllowance = it->scraperRequestAllowance;
results_scrape[i].mediaURLFetch = COMPLETED; results_scrape[i].mediaURLFetch = COMPLETED;

View file

@ -378,6 +378,7 @@ void processMediaURLs(const Value& images,
result.coverUrl = ""; result.coverUrl = "";
result.marqueeUrl = ""; result.marqueeUrl = "";
result.screenshotUrl = ""; result.screenshotUrl = "";
result.titlescreenUrl = "";
// Quite excessive testing for valid values, but you never know what the server has // Quite excessive testing for valid values, but you never know what the server has
// returned and we don't want to crash the program due to malformed data. // returned and we don't want to crash the program due to malformed data.
@ -399,6 +400,9 @@ void processMediaURLs(const Value& images,
if (mediatype == "screenshot") if (mediatype == "screenshot")
if (gameMedia[i]["filename"].IsString()) if (gameMedia[i]["filename"].IsString())
result.screenshotUrl = base_url + gameMedia[i]["filename"].GetString(); result.screenshotUrl = base_url + gameMedia[i]["filename"].GetString();
if (mediatype == "titlescreen")
if (gameMedia[i]["filename"].IsString())
result.titlescreenUrl = base_url + gameMedia[i]["filename"].GetString();
} }
} }
result.mediaURLFetch = COMPLETED; result.mediaURLFetch = COMPLETED;

View file

@ -185,6 +185,14 @@ MDResolveHandle::MDResolveHandle(const ScraperSearchResult& result,
mediaFileInfo.resizeFile = true; mediaFileInfo.resizeFile = true;
scrapeFiles.push_back(mediaFileInfo); scrapeFiles.push_back(mediaFileInfo);
} }
if (Settings::getInstance()->getBool("ScrapeBackCovers") && result.backcoverUrl != "") {
mediaFileInfo.fileURL = result.backcoverUrl;
mediaFileInfo.fileFormat = result.backcoverFormat;
mediaFileInfo.subDirectory = "backcovers";
mediaFileInfo.existingMediaFile = search.game->getBackCoverPath();
mediaFileInfo.resizeFile = true;
scrapeFiles.push_back(mediaFileInfo);
}
if (Settings::getInstance()->getBool("ScrapeCovers") && result.coverUrl != "") { if (Settings::getInstance()->getBool("ScrapeCovers") && result.coverUrl != "") {
mediaFileInfo.fileURL = result.coverUrl; mediaFileInfo.fileURL = result.coverUrl;
mediaFileInfo.fileFormat = result.coverFormat; mediaFileInfo.fileFormat = result.coverFormat;
@ -193,6 +201,14 @@ MDResolveHandle::MDResolveHandle(const ScraperSearchResult& result,
mediaFileInfo.resizeFile = true; mediaFileInfo.resizeFile = true;
scrapeFiles.push_back(mediaFileInfo); scrapeFiles.push_back(mediaFileInfo);
} }
if (Settings::getInstance()->getBool("ScrapePhysicalMedia") && result.physicalmediaUrl != "") {
mediaFileInfo.fileURL = result.physicalmediaUrl;
mediaFileInfo.fileFormat = result.physicalmediaFormat;
mediaFileInfo.subDirectory = "physicalmedia";
mediaFileInfo.existingMediaFile = search.game->getPhysicalMediaPath();
mediaFileInfo.resizeFile = true;
scrapeFiles.push_back(mediaFileInfo);
}
if (Settings::getInstance()->getBool("ScrapeMarquees") && result.marqueeUrl != "") { if (Settings::getInstance()->getBool("ScrapeMarquees") && result.marqueeUrl != "") {
mediaFileInfo.fileURL = result.marqueeUrl; mediaFileInfo.fileURL = result.marqueeUrl;
mediaFileInfo.fileFormat = result.marqueeFormat; mediaFileInfo.fileFormat = result.marqueeFormat;
@ -209,6 +225,14 @@ MDResolveHandle::MDResolveHandle(const ScraperSearchResult& result,
mediaFileInfo.resizeFile = true; mediaFileInfo.resizeFile = true;
scrapeFiles.push_back(mediaFileInfo); scrapeFiles.push_back(mediaFileInfo);
} }
if (Settings::getInstance()->getBool("ScrapeTitleScreens") && result.titlescreenUrl != "") {
mediaFileInfo.fileURL = result.titlescreenUrl;
mediaFileInfo.fileFormat = result.titlescreenFormat;
mediaFileInfo.subDirectory = "titlescreens";
mediaFileInfo.existingMediaFile = search.game->getTitleScreenPath();
mediaFileInfo.resizeFile = true;
scrapeFiles.push_back(mediaFileInfo);
}
if (Settings::getInstance()->getBool("ScrapeVideos") && result.videoUrl != "") { if (Settings::getInstance()->getBool("ScrapeVideos") && result.videoUrl != "") {
mediaFileInfo.fileURL = result.videoUrl; mediaFileInfo.fileURL = result.videoUrl;
mediaFileInfo.fileFormat = result.videoFormat; mediaFileInfo.fileFormat = result.videoFormat;
@ -401,6 +425,56 @@ void MediaDownloadHandle::update()
// Download is done, save it to disk. // Download is done, save it to disk.
// There's an incredibly annoying issue where some box back covers at ScreenScraper only contain
// a single color, like pure black or more commonly pure green. The hack below checks if the
// same pixel value is set throughout the image and if so skips the file saving. This is not
// very efficient but these images are not technically corrupt so the actual pixel values need
// to be read and compared.
if (Settings::getInstance()->getString("Scraper") == "screenscraper" &&
mMediaType == "backcovers") {
bool emptyImage = false;
FREE_IMAGE_FORMAT imageFormat = FIF_UNKNOWN;
std::string imageData = mReq->getContent();
FIMEMORY* memoryStream = FreeImage_OpenMemory(reinterpret_cast<BYTE*>(&imageData.at(0)),
static_cast<DWORD>(imageData.size()));
imageFormat = FreeImage_GetFileTypeFromMemory(memoryStream, 0);
if (imageFormat != FIF_UNKNOWN) {
emptyImage = true;
FIBITMAP* tempImage = FreeImage_LoadFromMemory(imageFormat, memoryStream);
RGBQUAD firstPixel;
RGBQUAD currPixel;
FreeImage_GetPixelColor(tempImage, 0, 0, &firstPixel);
for (unsigned int x = 0; x < FreeImage_GetWidth(tempImage); x++) {
if (!emptyImage)
break;
for (unsigned int y = 0; y < FreeImage_GetHeight(tempImage); y++) {
FreeImage_GetPixelColor(tempImage, x, y, &currPixel);
if (currPixel.rgbBlue != firstPixel.rgbBlue ||
currPixel.rgbGreen != firstPixel.rgbGreen ||
currPixel.rgbRed != firstPixel.rgbRed) {
emptyImage = false;
break;
}
}
}
FreeImage_Unload(tempImage);
}
FreeImage_CloseMemory(memoryStream);
if (emptyImage) {
LOG(LogWarning) << "ScreenScraper: Image does not seem to contain any data, not saving "
"it to disk: \""
<< mSavePath << "\"";
setStatus(ASYNC_DONE);
return;
}
}
// This is just a temporary workaround to avoid saving media files to disk that are // This is just a temporary workaround to avoid saving media files to disk that are
// actually just containing error messages from the scraper service. The proper solution // actually just containing error messages from the scraper service. The proper solution
// is to implement file checksum checks to determine if the server response contains valid // is to implement file checksum checks to determine if the server response contains valid

View file

@ -60,16 +60,22 @@ struct ScraperSearchResult {
std::string thumbnailImageUrl; std::string thumbnailImageUrl;
std::string box3DUrl; std::string box3DUrl;
std::string backcoverUrl;
std::string coverUrl; std::string coverUrl;
std::string marqueeUrl; std::string marqueeUrl;
std::string physicalmediaUrl;
std::string screenshotUrl; std::string screenshotUrl;
std::string titlescreenUrl;
std::string videoUrl; std::string videoUrl;
// Needed to pre-set the image type. // Needed to pre-set the image type.
std::string box3DFormat; std::string box3DFormat;
std::string backcoverFormat;
std::string coverFormat; std::string coverFormat;
std::string marqueeFormat; std::string marqueeFormat;
std::string physicalmediaFormat;
std::string screenshotFormat; std::string screenshotFormat;
std::string titlescreenFormat;
std::string videoFormat; std::string videoFormat;
// Indicates whether any new media files were downloaded and saved. // Indicates whether any new media files were downloaded and saved.

View file

@ -524,15 +524,24 @@ void ScreenScraperRequest::processGame(const pugi::xml_document& xmldoc,
// 3D box. // 3D box.
processMedia(result, media_list, ssConfig.media_3dbox, result.box3DUrl, processMedia(result, media_list, ssConfig.media_3dbox, result.box3DUrl,
result.box3DFormat, region); result.box3DFormat, region);
// Cover. // Box back cover.
processMedia(result, media_list, ssConfig.media_backcover, result.backcoverUrl,
result.backcoverFormat, region);
// Box cover.
processMedia(result, media_list, ssConfig.media_cover, result.coverUrl, processMedia(result, media_list, ssConfig.media_cover, result.coverUrl,
result.coverFormat, region); result.coverFormat, region);
// Marquee (wheel). // Marquee (wheel).
processMedia(result, media_list, ssConfig.media_marquee, result.marqueeUrl, processMedia(result, media_list, ssConfig.media_marquee, result.marqueeUrl,
result.marqueeFormat, region); result.marqueeFormat, region);
// Physical media.
processMedia(result, media_list, ssConfig.media_physicalmedia, result.physicalmediaUrl,
result.physicalmediaFormat, region);
// Screenshot. // Screenshot.
processMedia(result, media_list, ssConfig.media_screenshot, result.screenshotUrl, processMedia(result, media_list, ssConfig.media_screenshot, result.screenshotUrl,
result.screenshotFormat, region); result.screenshotFormat, region);
// Title screen.
processMedia(result, media_list, ssConfig.media_titlescreen, result.titlescreenUrl,
result.titlescreenFormat, region);
// Video. // Video.
processMedia(result, media_list, ssConfig.media_video, result.videoUrl, processMedia(result, media_list, ssConfig.media_video, result.videoUrl,
result.videoFormat, region); result.videoFormat, region);

View file

@ -71,9 +71,12 @@ public:
// //
std::string media_3dbox = "box-3D"; std::string media_3dbox = "box-3D";
std::string media_backcover = "box-2D-back";
std::string media_cover = "box-2D"; std::string media_cover = "box-2D";
std::string media_marquee = "wheel"; std::string media_marquee = "wheel";
std::string media_physicalmedia = "support-2D";
std::string media_screenshot = "ss"; std::string media_screenshot = "ss";
std::string media_titlescreen = "sstitle";
std::string media_video = "video"; std::string media_video = "video";
bool isArcadeSystem; bool isArcadeSystem;

View file

@ -250,6 +250,13 @@ void BasicGameListView::removeMedia(FileData* game)
removeEmptyDirFunc(systemMediaDir, mediaType, path); removeEmptyDirFunc(systemMediaDir, mediaType, path);
} }
if (Utils::FileSystem::exists(game->getTitleScreenPath())) {
mediaType = "titlescreens";
path = game->getTitleScreenPath();
Utils::FileSystem::removeFile(path);
removeEmptyDirFunc(systemMediaDir, mediaType, path);
}
if (Utils::FileSystem::exists(game->getCoverPath())) { if (Utils::FileSystem::exists(game->getCoverPath())) {
mediaType = "covers"; mediaType = "covers";
path = game->getCoverPath(); path = game->getCoverPath();
@ -257,6 +264,13 @@ void BasicGameListView::removeMedia(FileData* game)
removeEmptyDirFunc(systemMediaDir, mediaType, path); removeEmptyDirFunc(systemMediaDir, mediaType, path);
} }
if (Utils::FileSystem::exists(game->getBackCoverPath())) {
mediaType = "backcovers";
path = game->getBackCoverPath();
Utils::FileSystem::removeFile(path);
removeEmptyDirFunc(systemMediaDir, mediaType, path);
}
if (Utils::FileSystem::exists(game->getMarqueePath())) { if (Utils::FileSystem::exists(game->getMarqueePath())) {
mediaType = "marquees"; mediaType = "marquees";
path = game->getMarqueePath(); path = game->getMarqueePath();
@ -271,6 +285,13 @@ void BasicGameListView::removeMedia(FileData* game)
removeEmptyDirFunc(systemMediaDir, mediaType, path); removeEmptyDirFunc(systemMediaDir, mediaType, path);
} }
if (Utils::FileSystem::exists(game->getPhysicalMediaPath())) {
mediaType = "physicalmedia";
path = game->getPhysicalMediaPath();
Utils::FileSystem::removeFile(path);
removeEmptyDirFunc(systemMediaDir, mediaType, path);
}
if (Utils::FileSystem::exists(game->getThumbnailPath())) { if (Utils::FileSystem::exists(game->getThumbnailPath())) {
mediaType = "thumbnails"; mediaType = "thumbnails";
path = game->getThumbnailPath(); path = game->getThumbnailPath();

View file

@ -600,6 +600,13 @@ void GridGameListView::removeMedia(FileData* game)
removeEmptyDirFunc(systemMediaDir, mediaType, path); removeEmptyDirFunc(systemMediaDir, mediaType, path);
} }
if (Utils::FileSystem::exists(game->getTitleScreenPath())) {
mediaType = "titlescreens";
path = game->getTitleScreenPath();
Utils::FileSystem::removeFile(path);
removeEmptyDirFunc(systemMediaDir, mediaType, path);
}
if (Utils::FileSystem::exists(game->getCoverPath())) { if (Utils::FileSystem::exists(game->getCoverPath())) {
mediaType = "covers"; mediaType = "covers";
path = game->getCoverPath(); path = game->getCoverPath();
@ -607,6 +614,13 @@ void GridGameListView::removeMedia(FileData* game)
removeEmptyDirFunc(systemMediaDir, mediaType, path); removeEmptyDirFunc(systemMediaDir, mediaType, path);
} }
if (Utils::FileSystem::exists(game->getBackCoverPath())) {
mediaType = "backcovers";
path = game->getBackCoverPath();
Utils::FileSystem::removeFile(path);
removeEmptyDirFunc(systemMediaDir, mediaType, path);
}
if (Utils::FileSystem::exists(game->getMarqueePath())) { if (Utils::FileSystem::exists(game->getMarqueePath())) {
mediaType = "marquees"; mediaType = "marquees";
path = game->getMarqueePath(); path = game->getMarqueePath();
@ -621,6 +635,13 @@ void GridGameListView::removeMedia(FileData* game)
removeEmptyDirFunc(systemMediaDir, mediaType, path); removeEmptyDirFunc(systemMediaDir, mediaType, path);
} }
if (Utils::FileSystem::exists(game->getPhysicalMediaPath())) {
mediaType = "physicalmedia";
path = game->getPhysicalMediaPath();
Utils::FileSystem::removeFile(path);
removeEmptyDirFunc(systemMediaDir, mediaType, path);
}
if (Utils::FileSystem::exists(game->getThumbnailPath())) { if (Utils::FileSystem::exists(game->getThumbnailPath())) {
mediaType = "thumbnails"; mediaType = "thumbnails";
path = game->getThumbnailPath(); path = game->getThumbnailPath();

View file

@ -108,9 +108,12 @@ void Settings::setDefaults()
mBoolMap["ScrapeMetadata"] = {true, true}; mBoolMap["ScrapeMetadata"] = {true, true};
mBoolMap["ScrapeVideos"] = {true, true}; mBoolMap["ScrapeVideos"] = {true, true};
mBoolMap["ScrapeScreenshots"] = {true, true}; mBoolMap["ScrapeScreenshots"] = {true, true};
mBoolMap["ScrapeTitleScreens"] = {true, true};
mBoolMap["ScrapeCovers"] = {true, true}; mBoolMap["ScrapeCovers"] = {true, true};
mBoolMap["ScrapeBackCovers"] = {true, true};
mBoolMap["ScrapeMarquees"] = {true, true}; mBoolMap["ScrapeMarquees"] = {true, true};
mBoolMap["Scrape3DBoxes"] = {true, true}; mBoolMap["Scrape3DBoxes"] = {true, true};
mBoolMap["ScrapePhysicalMedia"] = {true, true};
mStringMap["MiximageResolution"] = {"1280x960", "1280x960"}; mStringMap["MiximageResolution"] = {"1280x960", "1280x960"};
mStringMap["MiximageScreenshotScaling"] = {"sharp", "sharp"}; mStringMap["MiximageScreenshotScaling"] = {"sharp", "sharp"};