diff --git a/src/emucore/CartDetector.cxx b/src/emucore/CartDetector.cxx index 6d5713f2e..6b443e297 100644 --- a/src/emucore/CartDetector.cxx +++ b/src/emucore/CartDetector.cxx @@ -19,6 +19,7 @@ #include "Logger.hxx" #include "CartDetector.hxx" +#include "MovieCart/StreamReader.hxx" // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Bankswitch::Type CartDetector::autodetectType(const ByteBuffer& image, size_t size) @@ -694,11 +695,34 @@ bool CartDetector::isProbablyMDM(const ByteBuffer& image, size_t size) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool CartDetector::isProbablyMVC(const ByteBuffer& image, size_t size) { - // MVC version 0, frame 0 + // MVC version 0 uInt8 sig[] = { 'M', 'V', 'C', 0 }; - return searchForBytes(image, std::min(size, 5), sig, 4); + int sigSize = sizeof(sig); + return searchForBytes(image, std::min(size, sigSize+1), sig, sigSize); } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +size_t CartDetector::isProbablyMVC(std::istream &in, size_t maxSize) +{ + const size_t frameSize = 2 * MVC_FIELD_PAD_SIZE; + bool found = false; + + // Returns size of field if stream is probably an MVC movie cartridge + + if (maxSize >= frameSize) + { + auto pos = in.tellg(); + + ByteBuffer image = make_unique(frameSize); + in.read(reinterpret_cast(image.get()), frameSize); + + in.seekg(pos); + + found = isProbablyMVC(image, frameSize); + } + + return found ? frameSize : 0; +} // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool CartDetector::isProbablySB(const ByteBuffer& image, size_t size) diff --git a/src/emucore/CartDetector.hxx b/src/emucore/CartDetector.hxx index 0061b1054..d845dad78 100644 --- a/src/emucore/CartDetector.hxx +++ b/src/emucore/CartDetector.hxx @@ -40,6 +40,13 @@ class CartDetector */ static Bankswitch::Type autodetectType(const ByteBuffer& image, size_t size); + + /** + MVC cartridges are of arbitary large length + Returns size of frame if stream is probably an MVC movie cartridge + */ + static size_t isProbablyMVC(std::istream &in, size_t size); + private: /** Search the image for the specified byte signature diff --git a/src/emucore/FSNode.cxx b/src/emucore/FSNode.cxx index b0aa64394..28a6100f5 100644 --- a/src/emucore/FSNode.cxx +++ b/src/emucore/FSNode.cxx @@ -17,6 +17,7 @@ #include "FSNodeFactory.hxx" #include "FSNode.hxx" +#include "CartDetector.hxx" // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - FilesystemNode::FilesystemNode(const AbstractFSNodePtr& realNode) @@ -355,6 +356,12 @@ size_t FilesystemNode::read(ByteBuffer& buffer) const if (sizeRead == 0) throw runtime_error("Zero-byte file"); + // In the case of MVC (MovieCart) files, contents are streaming data + // of arbitrary length, so just read first frame. + size_t subSize = CartDetector::isProbablyMVC(in, sizeRead); + if (subSize > 0) + sizeRead = subSize; + buffer = make_unique(sizeRead); in.read(reinterpret_cast(buffer.get()), sizeRead); }