made ROM info delay adaptive

some cleanup of the new JPG reading code
This commit is contained in:
Thomas Jentzsch 2022-08-17 09:17:04 +02:00
parent 6e4710750f
commit 7691b2606f
9 changed files with 153 additions and 126 deletions

View File

@ -33,7 +33,7 @@ JPGLibrary::JPGLibrary(OSystem& osystem)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void JPGLibrary::loadImage(const string& filename, FBSurface& surface,
VariantList& comments)
VariantList& metaData)
{
const auto loadImageERROR = [&](const char* s) {
if(s)
@ -63,8 +63,8 @@ void JPGLibrary::loadImage(const string& filename, FBSurface& surface,
myReadInfo.height = njGetHeight();
myReadInfo.pitch = myReadInfo.width * 3;
// Read the comments we got TODO
//readComments(png_ptr, info_ptr, comments);
// TODO: Read the meta data we got
//readMetaData(png_ptr, info_ptr, metaData);
// Load image into the surface, setting the correct dimensions
loadImagetoSurface(surface);
@ -103,8 +103,8 @@ void JPGLibrary::loadImagetoSurface(FBSurface& surface)
}
//// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
//void JPGLibrary::readComments(const png_structp png_ptr, png_infop info_ptr,
// VariantList& comments)
//void JPGLibrary::readMetaData(const png_structp png_ptr, png_infop info_ptr,
// VariantList& metaData)
//{
// png_textp text_ptr;
// int numComments = 0;
@ -112,10 +112,10 @@ void JPGLibrary::loadImagetoSurface(FBSurface& surface)
// // TODO: currently works only if comments are *before* the image data
// png_get_text(png_ptr, info_ptr, &text_ptr, &numComments);
//
// comments.clear();
// metaData.clear();
// for(int i = 0; i < numComments; ++i)
// {
// VarList::push_back(comments, text_ptr[i].key, text_ptr[i].text);
// VarList::push_back(metaData, text_ptr[i].key, text_ptr[i].text);
// }
//}

View File

@ -40,12 +40,13 @@ class JPGLibrary
@param filename The filename to load the JPG image
@param surface The FBSurface into which to place the JPG data
@param metaData The meta data of the JPG image
@post On success, the FBSurface containing image data, otherwise a
runtime_error is thrown containing a more detailed
error message.
*/
void loadImage(const string& filename, FBSurface& surface, VariantList& comments);
void loadImage(const string& filename, FBSurface& surface, VariantList& metaData);
private:
// Global OSystem object
@ -70,10 +71,10 @@ class JPGLibrary
void loadImagetoSurface(FBSurface& surface);
///**
// Read EXIF metadata chunks from the image.
// Read EXIF meta data chunks from the image.
//*/
//void readComments(const png_structp png_ptr, png_infop info_ptr,
// VariantList& comments);
//void readmetaData(const png_structp png_ptr, png_infop info_ptr,
// VariantList& metaData);
private:
// Following constructors and assignment operators not supported

View File

@ -33,7 +33,7 @@ PNGLibrary::PNGLibrary(OSystem& osystem)
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void PNGLibrary::loadImage(const string& filename, FBSurface& surface, VariantList& comments)
void PNGLibrary::loadImage(const string& filename, FBSurface& surface, VariantList& metaData)
{
png_structp png_ptr{nullptr};
png_infop info_ptr{nullptr};
@ -109,8 +109,8 @@ void PNGLibrary::loadImage(const string& filename, FBSurface& surface, VariantLi
// We're finished reading
png_read_end(png_ptr, info_ptr);
// Read the comments we got
readComments(png_ptr, info_ptr, comments);
// Read the meta data we got
readMetaData(png_ptr, info_ptr, metaData);
// Load image into the surface, setting the correct dimensions
loadImagetoSurface(surface);
@ -121,7 +121,7 @@ void PNGLibrary::loadImage(const string& filename, FBSurface& surface, VariantLi
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void PNGLibrary::saveImage(const string& filename, const VariantList& comments)
void PNGLibrary::saveImage(const string& filename, const VariantList& metaData)
{
std::ofstream out(filename, std::ios_base::binary);
if(!out.is_open())
@ -147,12 +147,12 @@ void PNGLibrary::saveImage(const string& filename, const VariantList& comments)
rows[k] = buffer.data() + k*width*4;
// And save the image
saveImageToDisk(out, rows, width, height, comments);
saveImageToDisk(out, rows, width, height, metaData);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void PNGLibrary::saveImage(const string& filename, const FBSurface& surface,
const Common::Rect& rect, const VariantList& comments)
const Common::Rect& rect, const VariantList& metaData)
{
std::ofstream out(filename, std::ios_base::binary);
if(!out.is_open())
@ -176,12 +176,12 @@ void PNGLibrary::saveImage(const string& filename, const FBSurface& surface,
rows[k] = buffer.data() + k*width*4;
// And save the image
saveImageToDisk(out, rows, width, height, comments);
saveImageToDisk(out, rows, width, height, metaData);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void PNGLibrary::saveImageToDisk(std::ofstream& out, const vector<png_bytep>& rows,
png_uint_32 width, png_uint_32 height, const VariantList& comments)
png_uint_32 width, png_uint_32 height, const VariantList& metaData)
{
png_structp png_ptr = nullptr;
png_infop info_ptr = nullptr;
@ -212,8 +212,8 @@ void PNGLibrary::saveImageToDisk(std::ofstream& out, const vector<png_bytep>& ro
PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT,
PNG_FILTER_TYPE_DEFAULT);
// Write comments
writeComments(png_ptr, info_ptr, comments);
// Write meta data
writeMetaData(png_ptr, info_ptr, metaData);
// Write the file header information. REQUIRED
png_write_info(png_ptr, info_ptr);
@ -331,18 +331,18 @@ void PNGLibrary::takeSnapshot(uInt32 number)
filename = sspath + ".png";
// Some text fields to add to the PNG snapshot
VariantList comments;
VariantList metaData;
ostringstream version;
VarList::push_back(comments, "Title", "Snapshot");
VarList::push_back(metaData, "Title", "Snapshot");
version << "Stella " << STELLA_VERSION << " (Build " << STELLA_BUILD << ") ["
<< BSPF::ARCH << "]";
VarList::push_back(comments, "Software", version.str());
VarList::push_back(metaData, "Software", version.str());
const string& name = (myOSystem.settings().getString("snapname") == "int")
? myOSystem.console().properties().get(PropType::Cart_Name)
: myOSystem.romFile().getName();
VarList::push_back(comments, "ROM Name", name);
VarList::push_back(comments, "ROM MD5", myOSystem.console().properties().get(PropType::Cart_MD5));
VarList::push_back(comments, "TV Effects", myOSystem.frameBuffer().tiaSurface().effectsInfo());
VarList::push_back(metaData, "ROM Name", name);
VarList::push_back(metaData, "ROM MD5", myOSystem.console().properties().get(PropType::Cart_MD5));
VarList::push_back(metaData, "TV Effects", myOSystem.frameBuffer().tiaSurface().effectsInfo());
// Now create a PNG snapshot
string message = "Snapshot saved";
@ -352,7 +352,7 @@ void PNGLibrary::takeSnapshot(uInt32 number)
{
Common::Rect rect;
const FBSurface& surface = myOSystem.frameBuffer().tiaSurface().baseSurface(rect);
myOSystem.png().saveImage(filename, surface, rect, comments);
myOSystem.png().saveImage(filename, surface, rect, metaData);
}
catch(const runtime_error& e)
{
@ -367,7 +367,7 @@ void PNGLibrary::takeSnapshot(uInt32 number)
try
{
myOSystem.png().saveImage(filename, comments);
myOSystem.png().saveImage(filename, metaData);
}
catch(const runtime_error& e)
{
@ -429,38 +429,37 @@ void PNGLibrary::loadImagetoSurface(FBSurface& surface)
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void PNGLibrary::writeComments(const png_structp png_ptr, png_infop info_ptr,
const VariantList& comments)
void PNGLibrary::writeMetaData(const png_structp png_ptr, png_infop info_ptr,
const VariantList& metaData)
{
const uInt32 numComments = static_cast<uInt32>(comments.size());
if(numComments == 0)
const uInt32 numMetaData = static_cast<uInt32>(metaData.size());
if(numMetaData == 0)
return;
vector<png_text> text_ptr(numComments);
for(uInt32 i = 0; i < numComments; ++i)
vector<png_text> text_ptr(numMetaData);
for(uInt32 i = 0; i < numMetaData; ++i)
{
text_ptr[i].key = const_cast<char*>(comments[i].first.c_str());
text_ptr[i].text = const_cast<char*>(comments[i].second.toCString());
text_ptr[i].key = const_cast<char*>(metaData[i].first.c_str());
text_ptr[i].text = const_cast<char*>(metaData[i].second.toCString());
text_ptr[i].compression = PNG_TEXT_COMPRESSION_NONE;
text_ptr[i].text_length = 0;
}
png_set_text(png_ptr, info_ptr, text_ptr.data(), numComments);
png_set_text(png_ptr, info_ptr, text_ptr.data(), numMetaData);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void PNGLibrary::readComments(const png_structp png_ptr, png_infop info_ptr,
VariantList& comments)
void PNGLibrary::readMetaData(const png_structp png_ptr, png_infop info_ptr,
VariantList& metaData)
{
png_textp text_ptr;
int numComments = 0;
int numMetaData = 0;
// TODO: currently works only if comments are *before* the image data
png_get_text(png_ptr, info_ptr, &text_ptr, &numComments);
png_get_text(png_ptr, info_ptr, &text_ptr, &numMetaData);
comments.clear();
for(int i = 0; i < numComments; ++i)
metaData.clear();
for(int i = 0; i < numMetaData; ++i)
{
VarList::push_back(comments, text_ptr[i].key, text_ptr[i].text);
VarList::push_back(metaData, text_ptr[i].key, text_ptr[i].text);
}
}

View File

@ -15,7 +15,7 @@
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//============================================================================
#ifdef IMAGE_SUPPORT
#ifdef IMAGE_SUPPORT
#ifndef PNGLIBRARY_HXX
#define PNGLIBRARY_HXX
@ -43,12 +43,13 @@ class PNGLibrary
@param filename The filename to load the PNG image
@param surface The FBSurface into which to place the PNG data
@param metaData The meta data of the PNG image
@post On success, the FBSurface containing image data, otherwise a
runtime_error is thrown containing a more detailed
error message.
*/
void loadImage(const string& filename, FBSurface& surface, VariantList& comments);
void loadImage(const string& filename, FBSurface& surface, VariantList& metaData);
/**
Save the current FrameBuffer image to a PNG file. Note that in most
@ -56,14 +57,14 @@ class PNGLibrary
*any* mode.
@param filename The filename to save the PNG image
@param comments The text comments to add to the PNG image
@param metaData The meta data s to add to the PNG image
@post On success, the PNG file has been saved to 'filename',
otherwise a runtime_error is thrown containing a
more detailed error message.
*/
void saveImage(const string& filename,
const VariantList& comments = VariantList{});
const VariantList& metaData = VariantList{});
/**
Save the given surface to a PNG file.
@ -71,7 +72,7 @@ class PNGLibrary
@param filename The filename to save the PNG image
@param surface The surface data for the PNG image
@param rect The area of the surface to use
@param comments The text comments to add to the PNG image
@param metaData The meta data to add to the PNG image
@post On success, the PNG file has been saved to 'filename',
otherwise a runtime_error is thrown containing a
@ -79,7 +80,7 @@ class PNGLibrary
*/
void saveImage(const string& filename, const FBSurface& surface,
const Common::Rect& rect = Common::Rect{},
const VariantList& comments = VariantList{});
const VariantList& metaData = VariantList{});
/**
Called at regular intervals, and used to determine whether a
@ -155,15 +156,15 @@ class PNGLibrary
/** The actual method which saves a PNG image.
@param out The output stream for writing PNG data
@param rows Pointer into PNG RGB data for each row
@param width The width of the PNG image
@param height The height of the PNG image
@param comments The text comments to add to the PNG image
@param out The output stream for writing PNG data
@param rows Pointer into PNG RGB data for each row
@param width The width of the PNG image
@param height The height of the PNG image
@param metaData The meta data to add to the PNG image
*/
void saveImageToDisk(std::ofstream& out, const vector<png_bytep>& rows,
png_uint_32 width, png_uint_32 height,
const VariantList& comments);
const VariantList& metaData);
/**
Load the PNG data from 'ReadInfo' into the FBSurface. The surface
@ -176,14 +177,14 @@ class PNGLibrary
/**
Write PNG tEXt chunks to the image.
*/
void writeComments(const png_structp png_ptr, png_infop info_ptr,
const VariantList& comments);
void writeMetaData(const png_structp png_ptr, png_infop info_ptr,
const VariantList& metaData);
/**
Read PNG tEXt chunks from the image.
*/
void readComments(const png_structp png_ptr, png_infop info_ptr,
VariantList& comments);
void readMetaData(const png_structp png_ptr, png_infop info_ptr,
VariantList& metaData);
/** PNG library callback functions */
static void png_read_data(const png_structp ctx, png_bytep area, png_size_t size);

View File

@ -328,7 +328,7 @@ void LauncherDialog::addRomWidgets(int ypos)
TIAConstants::viewableHeight * imgZoom);
// Calculate font area, and in the process the font that can be used
// Infofont is unknown yet, but used in image label too. Assuming maximum font height.
// Infofont is unknown yet, but used in image label too. Assuming maximum font height.
int imageHeight = imgSize.h + RomImageWidget::labelHeight(_font);
const Common::Size fontArea(imageWidth - fontWidth * 2,
@ -676,16 +676,25 @@ void LauncherDialog::loadRomInfo()
return;
// Update ROM info UI item, delayed
myRomInfoTime = TimerManager::getTicks() / 1000 + 250; // TODO: define pending load delay
myRomInfoTime = TimerManager::getTicks() / 1000 + myRomImageWidget->pendingLoadTime();
myPendingRomInfo = true;
const string& md5 = selectedRomMD5();
if(md5 != EmptyString)
if(!md5.empty())
{
myRomImageWidget->setProperties(currentNode(), md5, false);
myRomInfoWidget->setProperties(currentNode(), md5, false);
// The properties for the currently selected ROM
Properties properties;
// Make sure to load a per-ROM properties entry, if one exists
instance().propSet().loadPerROM(currentNode(), md5);
// And now get the properties for this ROM
instance().propSet().getMD5(md5, properties);
myRomImageWidget->setProperties(currentNode(), properties, false);
myRomInfoWidget->setProperties(currentNode(), properties, false);
}
else
else
{
myRomImageWidget->clearProperties();
myRomInfoWidget->clearProperties();
@ -703,8 +712,16 @@ void LauncherDialog::loadPendingRomInfo()
const string& md5 = selectedRomMD5();
if(md5 != EmptyString)
{
myRomImageWidget->setProperties(currentNode(), md5);
myRomInfoWidget->setProperties(currentNode(), md5);
// The properties for the currently selected ROM
Properties properties;
// Make sure to load a per-ROM properties entry, if one exists
instance().propSet().loadPerROM(currentNode(), md5);
// And now get the properties for this ROM
instance().propSet().getMD5(md5, properties);
myRomImageWidget->setProperties(currentNode(), properties);
myRomInfoWidget->setProperties(currentNode(), properties);
}
}

View File

@ -25,13 +25,13 @@
#include "PNGLibrary.hxx"
#include "Props.hxx"
#include "PropsSet.hxx"
#include "TimerManager.hxx"
#include "RomImageWidget.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
RomImageWidget::RomImageWidget(GuiObject* boss, const GUI::Font& font,
int x, int y, int w, int h)
: Widget(boss, font, x, y, w, h),
CommandSender(boss)
: Widget(boss, font, x, y, w, h)
{
_flags = Widget::FLAG_ENABLED | Widget::FLAG_TRACK_MOUSE;
_bgcolor = kDlgColor;
@ -40,15 +40,10 @@ RomImageWidget::RomImageWidget(GuiObject* boss, const GUI::Font& font,
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void RomImageWidget::setProperties(const FSNode& node, const string& md5, bool full)
void RomImageWidget::setProperties(const FSNode& node, const Properties properties, bool full)
{
myHaveProperties = true;
// Make sure to load a per-ROM properties entry, if one exists
instance().propSet().loadPerROM(node, md5);
// And now get the properties for this ROM
instance().propSet().getMD5(md5, myProperties);
myProperties = properties;
// Decide whether the information should be shown immediately
if(instance().eventHandler().state() == EventHandlerState::LAUNCHER)
@ -80,6 +75,7 @@ void RomImageWidget::reloadProperties(const FSNode& node)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void RomImageWidget::parseProperties(const FSNode& node, bool full)
{
uInt64 startTime = TimerManager::getTicks() / 1000;
if(myNavSurface == nullptr)
{
// Create navigation surface
@ -111,7 +107,7 @@ void RomImageWidget::parseProperties(const FSNode& node, bool full)
});
}
#ifdef IMAGE_SUPPORT
#ifdef IMAGE_SUPPORT
if(!full)
{
myImageIdx = 0;
@ -119,23 +115,24 @@ void RomImageWidget::parseProperties(const FSNode& node, bool full)
// Get a valid filename representing a snapshot file for this rom and load the snapshot
const string& path = instance().snapshotLoadDir().getPath();
// 1. Try to load first snapshot by property name
string fileName = path + myProperties.get(PropType::Cart_Name);// +".png"; // TODO: try jpg
tryImageTypes(fileName);
loadImage(fileName);
string fileName = path + myProperties.get(PropType::Cart_Name);
tryImageFormats(fileName);
if(!mySurfaceIsValid)
{
// 2. If none exists, try to load first snapshot by ROM file name
fileName = path + node.getNameWithExt("png"); // TODO: try jpg
loadImage(fileName);
fileName = path + node.getName();
tryImageFormats(fileName);
}
if(mySurfaceIsValid)
myImageList.emplace_back(fileName);
else
{
// 3. If no ROM snapshots exist, try to load a default snapshot
loadImage(path + "default_snapshot.png"); // TODO: try jpg???
fileName = path + "default_snapshot";
tryImageFormats(fileName);
}
}
else
{
@ -152,11 +149,16 @@ void RomImageWidget::parseProperties(const FSNode& node, bool full)
}
#else
mySurfaceIsValid = false;
mySurfaceErrorMsg = "PNG image loading not supported";
mySurfaceErrorMsg = "Image loading not supported";
setDirty();
#endif
if(mySurface)
mySurface->setVisible(mySurfaceIsValid);
// Update maximum load time
myMaxLoadTime = std::min(
static_cast<uInt64>(500ull / timeFactor),
std::max(myMaxLoadTime, TimerManager::getTicks() / 1000 - startTime));
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -178,7 +180,7 @@ bool RomImageWidget::getImageList(const string& propName, const string& romName)
const std::regex symbols{R"([-[\]{}()*+?.,\^$|#])"}; // \s
const string rgxPropName = std::regex_replace(propName, symbols, R"(\$&)");
const string rgxRomName = std::regex_replace(romName, symbols, R"(\$&)");
// Look for <name.png> or <name_#.png> (# is a number)
// Look for <name.png|jpg> or <name_#.png|jpg> (# is a number)
const std::regex rgx("^(" + rgxPropName + "|" + rgxRomName + ")(_\\d+){0,1}\\.(png|jpg)$");
FSNode::NameFilter filter = ([&](const FSNode& node)
@ -191,15 +193,15 @@ bool RomImageWidget::getImageList(const string& propName, const string& romName)
FSNode node(instance().snapshotLoadDir().getPath());
node.getChildren(myImageList, FSNode::ListMode::FilesOnly, filter, false, false);
// Sort again, not considering extensions, else <filename.png> would be at
// Sort again, not considering extensions, else <filename.png|jpg> would be at
// the end of the list
std::sort(myImageList.begin(), myImageList.end(),
[](const FSNode& node1, const FSNode& node2)
{
{
int compare = BSPF::compareIgnoreCase(node1.getNameWithExt(), node2.getNameWithExt());
return
return
compare < 0 ||
(compare == 0 &&
(compare == 0 &&
node1.getName().substr(node1.getName().find_last_of('.') + 1) >
node2.getName().substr(node2.getName().find_last_of('.') + 1)); // PNGs first!
}
@ -208,7 +210,7 @@ bool RomImageWidget::getImageList(const string& propName, const string& romName)
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool RomImageWidget::tryImageTypes(string& fileName)
bool RomImageWidget::tryImageFormats(string& fileName)
{
if(loadImage(fileName + ".png"))
{
@ -235,6 +237,15 @@ bool RomImageWidget::loadImage(const string& fileName)
else
mySurfaceIsValid = loadJpg(fileName);
if(mySurfaceIsValid)
{
// Scale surface to available image area
const Common::Rect& src = mySurface->srcRect();
const float scale = std::min(float(_w) / src.w(), float(myImageHeight) / src.h()) *
instance().frameBuffer().hidpiScaleFactor();
mySurface->setDstSize(static_cast<uInt32>(src.w() * scale), static_cast<uInt32>(src.h() * scale));
}
if(mySurface)
mySurface->setVisible(mySurfaceIsValid);
@ -247,27 +258,21 @@ bool RomImageWidget::loadPng(const string& fileName)
{
try
{
VariantList comments;
instance().png().loadImage(fileName, *mySurface, comments);
// Scale surface to available image area
const Common::Rect& src = mySurface->srcRect();
const float scale = std::min(float(_w) / src.w(), float(myImageHeight) / src.h()) *
instance().frameBuffer().hidpiScaleFactor();
mySurface->setDstSize(static_cast<uInt32>(src.w() * scale), static_cast<uInt32>(src.h() * scale));
VariantList metaData;
instance().png().loadImage(fileName, *mySurface, metaData);
// Retrieve label for loaded image
myLabel.clear();
for(auto comment = comments.begin(); comment != comments.end(); ++comment)
for(auto data = metaData.begin(); data != metaData.end(); ++data)
{
if(comment->first == "Title")
if(data->first == "Title")
{
myLabel = comment->second.toString();
myLabel = data->second.toString();
break;
}
if(comment->first == "Software"
&& comment->second.toString().find("Stella") == 0)
myLabel = "Snapshot"; // default for Stella snapshots with missing "Title" comment
if(data->first == "Software"
&& data->second.toString().find("Stella") == 0)
myLabel = "Snapshot"; // default for Stella snapshots with missing "Title" meta data
}
return true;
}
@ -283,17 +288,17 @@ bool RomImageWidget::loadJpg(const string& fileName)
{
try
{
VariantList comments;
instance().jpg().loadImage(fileName, *mySurface, comments);
VariantList metaData;
instance().jpg().loadImage(fileName, *mySurface, metaData);
myLabel.clear();
// TODO
return true;
}
catch(const runtime_error& e)
{
mySurfaceErrorMsg = e.what();
}
//mySurfaceErrorMsg = "JPG image loading not supported";
}
return false;
}

View File

@ -23,7 +23,7 @@ class Properties;
#include "Widget.hxx"
class RomImageWidget : public Widget, public CommandSender
class RomImageWidget : public Widget
{
public:
RomImageWidget(GuiObject *boss, const GUI::Font& font,
@ -35,11 +35,13 @@ class RomImageWidget : public Widget, public CommandSender
return font.getFontHeight() * 9 / 8;
}
void setProperties(const FSNode& node, const string& md5, bool full = true);
void setProperties(const FSNode& node, const Properties properties, bool full = true);
void clearProperties();
void reloadProperties(const FSNode& node);
bool changeImage(int direction = 1);
uInt64 pendingLoadTime() { return myMaxLoadTime * timeFactor; }
protected:
void drawWidget(bool hilite) override;
#ifdef IMAGE_SUPPORT
@ -51,14 +53,18 @@ class RomImageWidget : public Widget, public CommandSender
void parseProperties(const FSNode& node, bool full = true);
#ifdef IMAGE_SUPPORT
bool getImageList(const string& propName, const string& romName);
bool tryImageTypes(string& fileName);
bool tryImageFormats(string& fileName);
bool loadImage(const string& fileName);
bool loadPng(const string& fileName);
bool loadJpg(const string& fileName);
#endif
private:
// Surface pointer holding the PNG image
// Pending load time safety factor
static constexpr double timeFactor = 1.2;
private:
// Surface pointer holding the image
shared_ptr<FBSurface> mySurface;
// Surface pointer holding the navigation elements
@ -91,6 +97,9 @@ class RomImageWidget : public Widget, public CommandSender
// Label for the loaded image
string myLabel;
// Maximum load time, for adapting pending loads delay
uInt64 myMaxLoadTime{0};
private:
// Following constructors and assignment operators not supported
RomImageWidget() = delete;

View File

@ -39,15 +39,10 @@ RomInfoWidget::RomInfoWidget(GuiObject* boss, const GUI::Font& font,
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void RomInfoWidget::setProperties(const FSNode& node, const string& md5, bool full)
void RomInfoWidget::setProperties(const FSNode& node, const Properties properties, bool full)
{
myHaveProperties = true;
// Make sure to load a per-ROM properties entry, if one exists
instance().propSet().loadPerROM(node, md5);
// And now get the properties for this ROM
instance().propSet().getMD5(md5, myProperties);
myProperties = properties;
// Decide whether the information should be shown immediately
if(instance().eventHandler().state() == EventHandlerState::LAUNCHER)
@ -96,7 +91,7 @@ void RomInfoWidget::parseProperties(const FSNode& node, bool full)
myRomInfo.push_back("Rarity: " + value);
if((value = myProperties.get(PropType::Cart_Note)) != EmptyString)
myRomInfo.push_back("Note: " + value);
if(full)
{
const bool swappedPorts = myProperties.get(PropType::Console_SwapPorts) == "YES";

View File

@ -35,7 +35,7 @@ class RomInfoWidget : public Widget, public CommandSender
int x, int y, int w, int h);
~RomInfoWidget() override = default;
void setProperties(const FSNode& node, const string& md5, bool full = true);
void setProperties(const FSNode& node, const Properties properties, bool full = true);
void clearProperties();
void reloadProperties(const FSNode& node);