mirror of https://github.com/stella-emu/stella.git
made ROM info delay adaptive
some cleanup of the new JPG reading code
This commit is contained in:
parent
6e4710750f
commit
7691b2606f
|
@ -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);
|
||||
// }
|
||||
//}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in New Issue