[Scummvm-git-logs] scummvm master -> da245124ab8408ae7726426ca56ac3b61a38e7dc

sev- noreply at scummvm.org
Fri May 2 12:07:19 UTC 2025


This automated email contains information about 8 new commits which have been
pushed to the 'scummvm' repo located at https://api.github.com/repos/scummvm/scummvm .

Summary:
6a1a5e407a COMMON: QT: Fix pHdr atom parsing
a1e42ebda8 COMMON: QT: Tidied up and enhanced debug output
d6912415a9 COMMON: QT: Added more debug info to QTVR atoms
d5ceb21c04 COMMON: QT: Initialize panorama structs on construction
a9458a46f1 VIDEO: QTVR: Default to the first node when incorrect node id is provided
0b48f74018 VIDEO: QTVR: Added more debug output to atom reading
fb06f19fef VIDEO: QTVR: Initial support for single-node movies
da245124ab VIDEO: QTVR: Support for tracks without hotspots


Commit: 6a1a5e407a15b362fd65ab7e81f247c623557f97
    https://github.com/scummvm/scummvm/commit/6a1a5e407a15b362fd65ab7e81f247c623557f97
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2025-05-02T12:53:56+02:00

Commit Message:
COMMON: QT: Fix pHdr atom parsing

Changed paths:
    common/formats/quicktime.cpp
    common/formats/quicktime.h


diff --git a/common/formats/quicktime.cpp b/common/formats/quicktime.cpp
index 8793b4da11a..bad89101fc4 100644
--- a/common/formats/quicktime.cpp
+++ b/common/formats/quicktime.cpp
@@ -1058,7 +1058,7 @@ int QuickTimeParser::readPHDR(Atom atom) {
 	pHdr.minZoom = readAppleFloatField(_fd);
 	pHdr.maxHPan = readAppleFloatField(_fd);
 	pHdr.maxVPan = readAppleFloatField(_fd);
-	pHdr.minHPan = readAppleFloatField(_fd);
+	pHdr.maxZoom = readAppleFloatField(_fd);
 
 	_fd->readSint64BE(); // reserved1 + reserved2
 
diff --git a/common/formats/quicktime.h b/common/formats/quicktime.h
index 9d517c316be..e027e57c711 100644
--- a/common/formats/quicktime.h
+++ b/common/formats/quicktime.h
@@ -192,6 +192,7 @@ public:
 		float maxHPan;
 		float maxVPan;
 		float minZoom;
+		float maxZoom;
 
 		int32 nameStrOffset;
 		int32 commentStrOffset;


Commit: a1e42ebda8337941a1ea6f4a39bde84af354c292
    https://github.com/scummvm/scummvm/commit/a1e42ebda8337941a1ea6f4a39bde84af354c292
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2025-05-02T13:08:29+02:00

Commit Message:
COMMON: QT: Tidied up and enhanced debug output

Changed paths:
    common/formats/quicktime.cpp


diff --git a/common/formats/quicktime.cpp b/common/formats/quicktime.cpp
index bad89101fc4..21fbc565c10 100644
--- a/common/formats/quicktime.cpp
+++ b/common/formats/quicktime.cpp
@@ -259,7 +259,7 @@ int QuickTimeParser::readDefault(Atom atom) {
 
 		total_size += 8;
 		a.offset += 8;
-		debugC(4, kDebugLevelGVideo, "type: %08x  %.4s  sz: %x %x %x", a.type, tag2str(a.type), a.size, atom.size, total_size);
+		debugC(1, kDebugLevelGVideo, "type: %.4s (%08x) sz: %x %x %x", tag2str(a.type), a.type, a.size, atom.size, total_size);
 
 		if (a.size == 1) { // 64 bit extended size
 			warning("64 bit extended size is not supported in QuickTime");
@@ -284,7 +284,7 @@ int QuickTimeParser::readDefault(Atom atom) {
 
 		if (a.size + (uint32)_fd->pos() > (uint32)_fd->size()) {
 			_fd->seek(_fd->size());
-			debugC(0, kDebugLevelGVideo, "Skipping junk found at the end of the QuickTime file");
+			debugC(0, kDebugLevelGVideo, ">>> Skipping junk found at the end of the QuickTime file");
 			return 0;
 		} else if (_parseTable[i].type == 0) { // skip leaf atom data
 			debugC(0, kDebugLevelGVideo, ">>> Skipped [%s] (%08x) at %d (0x%x)", tag2str(a.type), a.type, (uint32)_fd->pos(), (uint32)_fd->pos());
@@ -391,7 +391,7 @@ int QuickTimeParser::readMVHD(Atom atom) {
 	}
 
 	_timeScale = _fd->readUint32BE(); // time scale
-	debugC(0, kDebugLevelGVideo, "time scale = %i\n", _timeScale);
+	debugC(2, kDebugLevelGVideo, "  time scale = %i", _timeScale);
 
 	// duration
 	_duration = (version == 1) ? (_fd->readUint32BE(), _fd->readUint32BE()) : _fd->readUint32BE();
@@ -412,8 +412,8 @@ int QuickTimeParser::readMVHD(Atom atom) {
 	_scaleFactorX = Rational(0x10000, xMod);
 	_scaleFactorY = Rational(0x10000, yMod);
 
-	_scaleFactorX.debugPrintC(1, kDebugLevelGVideo, "readMVHD(): scaleFactorX =");
-	_scaleFactorY.debugPrintC(1, kDebugLevelGVideo, "readMVHD(): scaleFactorY =");
+	_scaleFactorX.debugPrintC(1, kDebugLevelGVideo, "  scaleFactorX =");
+	_scaleFactorY.debugPrintC(1, kDebugLevelGVideo, "  scaleFactorY =");
 
 	_fd->readUint32BE(); // preview time
 	_fd->readUint32BE(); // preview duration
@@ -487,8 +487,8 @@ int QuickTimeParser::readTKHD(Atom atom) {
 	track->scaleFactorX = Rational(0x10000, xMod);
 	track->scaleFactorY = Rational(0x10000, yMod);
 
-	track->scaleFactorX.debugPrintC(1, kDebugLevelGVideo, "readTKHD(): scaleFactorX =");
-	track->scaleFactorY.debugPrintC(1, kDebugLevelGVideo, "readTKHD(): scaleFactorY =");
+	track->scaleFactorX.debugPrintC(2, kDebugLevelGVideo, "  scaleFactorX =");
+	track->scaleFactorY.debugPrintC(2, kDebugLevelGVideo, "  scaleFactorY =");
 
 	// these are fixed-point, 16:16
 	//_fd->readUint32BE() >> 16; // track width
@@ -507,7 +507,7 @@ int QuickTimeParser::readELST(Atom atom) {
 	uint32 editCount = _fd->readUint32BE();
 	track->editList.resize(editCount);
 
-	debugC(2, kDebugLevelGVideo, "Track %d edit list count: %d", _tracks.size() - 1, editCount);
+	debugC(2, kDebugLevelGVideo, "  Track %d edit list count: %d", _tracks.size() - 1, editCount);
 
 	uint32 offset = 0;
 
@@ -516,8 +516,8 @@ int QuickTimeParser::readELST(Atom atom) {
 		track->editList[i].mediaTime = _fd->readSint32BE();
 		track->editList[i].mediaRate = Rational(_fd->readUint32BE(), 0x10000);
 		track->editList[i].timeOffset = offset;
-		debugCN(3, kDebugLevelGVideo, "\tDuration = %d (Offset = %d), Media Time = %d, ", track->editList[i].trackDuration, offset, track->editList[i].mediaTime);
-		track->editList[i].mediaRate.debugPrintC(3, kDebugLevelGVideo, "Media Rate =");
+		debugCN(3, kDebugLevelGVideo, "    Duration = %d (Offset = %d), Media Time = %d, ", track->editList[i].trackDuration, offset, track->editList[i].mediaTime);
+		track->editList[i].mediaRate.debugPrintC(2, kDebugLevelGVideo, "Media Rate =");
 		offset += track->editList[i].trackDuration;
 	}
 
@@ -534,13 +534,13 @@ int QuickTimeParser::readHDLR(Atom atom) {
 	uint32 ctype = _fd->readUint32BE();
 	uint32 type = _fd->readUint32BE(); // component subtype
 
-	debugC(0, kDebugLevelGVideo, "ctype= %s (0x%08lx)", tag2str(ctype), (long)ctype);
-	debugC(0, kDebugLevelGVideo, "stype= %s", tag2str(type));
+	debugC(2, kDebugLevelGVideo, "  ctype= %s (0x%08lx)", tag2str(ctype), (long)ctype);
+	debugC(2, kDebugLevelGVideo, "  stype= %s", tag2str(type));
 
 	if (ctype == MKTAG('m', 'h', 'l', 'r')) // MOV
-		debugC(0, kDebugLevelGVideo, "MOV detected");
+		debugC(0, kDebugLevelGVideo, "  MOV detected");
 	else if (ctype == 0)
-		debugC(0, kDebugLevelGVideo, "MPEG-4 detected");
+		debugC(0, kDebugLevelGVideo, "  MPEG-4 detected");
 
 	if (type == MKTAG('v', 'i', 'd', 'e'))
 		track->codecType = CODEC_TYPE_VIDEO;
@@ -613,7 +613,7 @@ int QuickTimeParser::readSTSD(Atom atom) {
 		_fd->readUint16BE(); // reserved
 		_fd->readUint16BE(); // index
 
-		debugC(0, kDebugLevelGVideo, "sampledesc %d: size=%d 4CC= %s codec_type=%d", i, size, tag2str(format), track->codecType);
+		debugC(3, kDebugLevelGVideo, "  sampledesc %d: size=%d 4CC= %s codec_type=%d", i, size, tag2str(format), track->codecType);
 
 		track->sampleDescs.push_back(readSampleDesc(track, format, size - 16));
 
@@ -641,7 +641,7 @@ int QuickTimeParser::readSTSC(Atom atom) {
 
 	track->sampleToChunkCount = _fd->readUint32BE();
 
-	debugC(0, kDebugLevelGVideo, "track[%i].stsc.entries = %i", _tracks.size() - 1, track->sampleToChunkCount);
+	debugC(2, kDebugLevelGVideo, "  track[%i].stsc.entries = %i", _tracks.size() - 1, track->sampleToChunkCount);
 
 	track->sampleToChunk = new SampleToChunkEntry[track->sampleToChunkCount];
 
@@ -666,7 +666,7 @@ int QuickTimeParser::readSTSS(Atom atom) {
 
 	track->keyframeCount = _fd->readUint32BE();
 
-	debugC(0, kDebugLevelGVideo, "keyframeCount = %d", track->keyframeCount);
+	debugC(2, kDebugLevelGVideo, "  keyframeCount = %d", track->keyframeCount);
 
 	track->keyframes = new uint32[track->keyframeCount];
 
@@ -675,7 +675,7 @@ int QuickTimeParser::readSTSS(Atom atom) {
 
 	for (uint32 i = 0; i < track->keyframeCount; i++) {
 		track->keyframes[i] = _fd->readUint32BE() - 1; // Adjust here, the frames are based on 1
-		debugC(6, kDebugLevelGVideo, "keyframes[%d] = %d", i, track->keyframes[i]);
+		debugC(3, kDebugLevelGVideo, "    keyframes[%d] = %d", i, track->keyframes[i]);
 
 	}
 	return 0;
@@ -690,7 +690,7 @@ int QuickTimeParser::readSTSZ(Atom atom) {
 	track->sampleSize = _fd->readUint32BE();
 	track->sampleCount = _fd->readUint32BE();
 
-	debugC(5, kDebugLevelGVideo, "sampleSize = %d sampleCount = %d", track->sampleSize, track->sampleCount);
+	debugC(2, kDebugLevelGVideo, "  sampleSize = %d sampleCount = %d", track->sampleSize, track->sampleCount);
 
 	if (track->sampleSize)
 		return 0; // there isn't any table following
@@ -702,7 +702,7 @@ int QuickTimeParser::readSTSZ(Atom atom) {
 
 	for(uint32 i = 0; i < track->sampleCount; i++) {
 		track->sampleSizes[i] = _fd->readUint32BE();
-		debugC(6, kDebugLevelGVideo, "sampleSizes[%d] = %d", i, track->sampleSizes[i]);
+		debugC(3, kDebugLevelGVideo, "    sampleSizes[%d] = %d", i, track->sampleSizes[i]);
 	}
 
 	return 0;
@@ -718,13 +718,13 @@ int QuickTimeParser::readSTTS(Atom atom) {
 	track->timeToSampleCount = _fd->readUint32BE();
 	track->timeToSample = new TimeToSampleEntry[track->timeToSampleCount];
 
-	debugC(0, kDebugLevelGVideo, "track[%d].stts.entries = %d", _tracks.size() - 1, track->timeToSampleCount);
+	debugC(2, kDebugLevelGVideo, "  track[%d].stts.entries = %d", _tracks.size() - 1, track->timeToSampleCount);
 
 	for (int32 i = 0; i < track->timeToSampleCount; i++) {
 		track->timeToSample[i].count = _fd->readUint32BE();
 		track->timeToSample[i].duration = _fd->readUint32BE();
 
-		debugC(1, kDebugLevelGVideo, "\tCount = %d, Duration = %d", track->timeToSample[i].count, track->timeToSample[i].duration);
+		debugC(3, kDebugLevelGVideo, "    Count = %d, Duration = %d", track->timeToSample[i].count, track->timeToSample[i].duration);
 
 		totalSampleCount += track->timeToSample[i].count;
 	}
@@ -857,7 +857,7 @@ int QuickTimeParser::readESDS(Atom atom) {
 
 	sampleDesc->_extraData = _fd->readStream(length);
 
-	debugC(0, kDebugLevelGVideo, "MPEG-4 object type = %02x", sampleDesc->_objectTypeMP4);
+	debugC(2, kDebugLevelGVideo, "  MPEG-4 object type = %02x", sampleDesc->_objectTypeMP4);
 	return 0;
 }
 
@@ -940,7 +940,12 @@ int QuickTimeParser::readNAVG(Atom atom) {
 	_nav.initialVPan = readAppleFloatField(_fd);
 	_fd->readUint32BE(); // reserved2
 
-	return 0;
+	debugC(2, kDebugLevelGVideo, "  cols: %d rows: %d loop_size: %d frame_duration: %d movie_type: %d",
+		_nav.columns, _nav.rows, _nav.loop_size, _nav.frame_duration, _nav.movie_type);
+	debugC(2, kDebugLevelGVideo, "  fov: %f hpan: [%f - %f] vpan: [%f - %f] initHpan: %f initVPan: %f",
+		_nav.field_of_view, _nav.startHPan, _nav.endHPan, _nav.startVPan, _nav.endVPan, _nav.initialHPan, _nav.initialVPan);
+
+		return 0;
 }
 
 int QuickTimeParser::readGMIN(Atom atom) {
@@ -965,10 +970,19 @@ int QuickTimeParser::readPINF(Atom atom) {
 	_fd->readUint32BE(); // reserved
 	_fd->readSint16BE(); // padding
 	int16 numEntries = _fd->readSint16BE();
+
+	debugC(2, kDebugLevelGVideo, "  name: '%s'", track->panoInfo.name.c_str());
+	debugC(2, kDebugLevelGVideo, "  defNodeId: %d defZoon: %f  entries: %d",
+		track->panoInfo.defNodeID, track->panoInfo.defZoom, numEntries);
+
+
 	track->panoInfo.nodes.resize(numEntries);
 	for (int16 i = 0; i < numEntries; i++) {
 		track->panoInfo.nodes[i].nodeID = _fd->readUint32BE();
 		track->panoInfo.nodes[i].timestamp = _fd->readUint32BE();
+
+		debugC(3, kDebugLevelGVideo, "    [%d] nodeId: %d timestamp: %d",
+			i, track->panoInfo.nodes[i].nodeID, track->panoInfo.nodes[i].timestamp);
 	}
 
 	return 0;
@@ -1008,12 +1022,12 @@ int QuickTimeParser::readDREF(Atom atom) {
 				track->filename = _fd->readString('\0', filenameSize);
 				_fd->seek(63 - filenameSize, SEEK_CUR);
 				_fd->seek(16, SEEK_CUR);
-				debugC(5, kDebugLevelGVideo, "volume: %s, filename: %s", track->volume.c_str(), track->filename.c_str());
+				debugC(2, kDebugLevelGVideo, "  volume: %s, filename: %s", track->volume.c_str(), track->filename.c_str());
 
 				track->nlvlFrom = _fd->readSint16BE();
 				track->nlvlTo = _fd->readSint16BE();
 				_fd->seek(16, SEEK_CUR);
-				debugC(5, kDebugLevelGVideo, "nlvlFrom: %d, nlvlTo: %d", track->nlvlFrom, track->nlvlTo);
+				debugC(2, kDebugLevelGVideo, "  nlvlFrom: %d, nlvlTo: %d", track->nlvlFrom, track->nlvlTo);
 
 				for (int16 subType = 0; subType != -1 && _fd->pos() < endPos;) {
 					subType = _fd->readSint16BE();
@@ -1024,10 +1038,10 @@ int QuickTimeParser::readDREF(Atom atom) {
 						if (track->path.substr(0, volumeSize) == track->volume) {
 							track->path = track->path.substr(volumeSize);
 						}
-						debugC(5, kDebugLevelGVideo, "path: %s", track->path.c_str());
+						debugC(3, kDebugLevelGVideo, "    path: %s", track->path.c_str());
 					} else if (subType == 0) {
 						track->directory = _fd->readString('\0', subTypeSize);
-						debugC(5, kDebugLevelGVideo, "directory: %s", track->directory.c_str());
+						debugC(3, kDebugLevelGVideo, "    directory: %s", track->directory.c_str());
 					} else {
 						_fd->seek(subTypeSize, SEEK_CUR);
 					}
@@ -1065,6 +1079,10 @@ int QuickTimeParser::readPHDR(Atom atom) {
 	pHdr.nameStrOffset = _fd->readSint32BE();
 	pHdr.commentStrOffset = _fd->readSint32BE();
 
+	debugC(2, kDebugLevelGVideo, "    nodeID: %d hpan: %f [%f - %f] vpan: %f [%f - %f] zoom: %f [%f - %f]",
+		pHdr.nodeID, pHdr.defHPan, pHdr.minHPan, pHdr.maxHPan, pHdr.defVPan, pHdr.minVPan, pHdr.maxVPan,
+		pHdr.defZoom, pHdr.minZoom, pHdr.maxZoom);
+
 	return 0;
 }
 


Commit: d6912415a9c5aac1aeddf610d31006981aa64f04
    https://github.com/scummvm/scummvm/commit/d6912415a9c5aac1aeddf610d31006981aa64f04
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2025-05-02T13:32:18+02:00

Commit Message:
COMMON: QT: Added more debug info to QTVR atoms

Changed paths:
    common/formats/quicktime.cpp


diff --git a/common/formats/quicktime.cpp b/common/formats/quicktime.cpp
index 21fbc565c10..80a5cfa9d65 100644
--- a/common/formats/quicktime.cpp
+++ b/common/formats/quicktime.cpp
@@ -1094,6 +1094,8 @@ int QuickTimeParser::readPHOT(Atom atom) {
 	int16 numHotSpots = _fd->readSint16BE();
 	pHotSpotTable.hotSpots.resize(numHotSpots);
 
+	debugC(2, kDebugLevelGVideo, "  numHotspots: %d", numHotSpots);
+
 	for (int i = 0; i < numHotSpots; i++) {
 		pHotSpotTable.hotSpots[i].id = _fd->readUint16BE();
 
@@ -1119,6 +1121,21 @@ int QuickTimeParser::readPHOT(Atom atom) {
 
 		pHotSpotTable.hotSpots[i].nameStrOffset = _fd->readSint32BE();
 		pHotSpotTable.hotSpots[i].commentStrOffset = _fd->readSint32BE();
+
+		debugC(3, kDebugLevelGVideo, "    [%d]: id: %d type: %s (%08x) typedata: %d",
+			i, pHotSpotTable.hotSpots[i].id, tag2str(pHotSpotTable.hotSpots[i].type),
+			pHotSpotTable.hotSpots[i].type, pHotSpotTable.hotSpots[i].typeData);
+		debugC(3, kDebugLevelGVideo, "      hpan: %f vpan: %f zoom: %f",
+			pHotSpotTable.hotSpots[i].viewHPan, pHotSpotTable.hotSpots[i].viewVPan,
+			pHotSpotTable.hotSpots[i].viewZoom);
+		debugC(3, kDebugLevelGVideo, "      bbox: [%d, %d, %d, %d]",
+			pHotSpotTable.hotSpots[i].rect.top, pHotSpotTable.hotSpots[i].rect.left,
+			pHotSpotTable.hotSpots[i].rect.right, pHotSpotTable.hotSpots[i].rect.bottom);
+		debugC(3, kDebugLevelGVideo, "      curOver: %d curDown: %d curUp: %d",
+			pHotSpotTable.hotSpots[i].mouseOverCursorID, pHotSpotTable.hotSpots[i].mouseDownCursorID,
+			pHotSpotTable.hotSpots[i].mouseUpCursorID);
+		debugC(3, kDebugLevelGVideo, "      nameOffset: %d commentOffset: %d",
+			pHotSpotTable.hotSpots[i].nameStrOffset, pHotSpotTable.hotSpots[i].commentStrOffset);
 	}
 
 	return 0;
@@ -1129,6 +1146,8 @@ int QuickTimeParser::readSTRT(Atom atom) {
 
 	pStrTable.strings = _fd->readString(0, atom.size);
 
+	debugC(2, kDebugLevelGVideo, "  %s", pStrTable.strings.c_str());
+
 	return 0;
 }
 
@@ -1140,6 +1159,8 @@ int QuickTimeParser::readPLNK(Atom atom) {
 	int16 numLinks = _fd->readSint16BE();
 	pLinkTable.links.resize(numLinks);
 
+	debugC(2, kDebugLevelGVideo, "  numlinks: %d", numLinks);
+
 	for (int i = 0; i < numLinks; i++) {
 		pLinkTable.links[i].id = _fd->readUint16BE();
 
@@ -1158,6 +1179,11 @@ int QuickTimeParser::readPLNK(Atom atom) {
 
 		pLinkTable.links[i].nameStrOffset = _fd->readSint32BE();
 		pLinkTable.links[i].commentStrOffset = _fd->readSint32BE();
+
+		debugC(3, kDebugLevelGVideo, "    [%d]: id: %d node: %d hpan: %f vpan: %f zoom: %f name: %d comment: %d",
+			i, pLinkTable.links[i].id, pLinkTable.links[i].toNodeID, pLinkTable.links[i].toHPan,
+			pLinkTable.links[i].toVPan, pLinkTable.links[i].toZoom, pLinkTable.links[i].nameStrOffset,
+			pLinkTable.links[i].commentStrOffset);
 	}
 
 	return 0;
@@ -1171,6 +1197,8 @@ int QuickTimeParser::readPNAV(Atom atom) {
 	int16 numNavs = _fd->readSint16BE();
 	pLinkTable.navs.resize(numNavs);
 
+	debugC(2, kDebugLevelGVideo, "  numNavs: %d", numNavs);
+
 	for (int i = 0; i < numNavs; i++) {
 		pLinkTable.navs[i].id = _fd->readUint16BE();
 
@@ -1190,6 +1218,16 @@ int QuickTimeParser::readPNAV(Atom atom) {
 
 		pLinkTable.navs[i].nameStrOffset = _fd->readSint32BE();
 		pLinkTable.navs[i].commentStrOffset = _fd->readSint32BE();
+
+		debugC(3, kDebugLevelGVideo, "    [%d]: id: %d hpan: %f vpan: %f zoom: %f",
+			i, pLinkTable.navs[i].id, pLinkTable.navs[i].navgHPan, pLinkTable.navs[i].navgVPan,
+			pLinkTable.navs[i].navgZoom);
+		debugC(3, kDebugLevelGVideo, "      rect: [%d, %d, %d, %d]",
+			pLinkTable.navs[i].zoomRect.top, pLinkTable.navs[i].zoomRect.left,
+			pLinkTable.navs[i].zoomRect.right, pLinkTable.navs[i].zoomRect.bottom);
+		debugC(3, kDebugLevelGVideo, "      name: %d comment: %d",
+			pLinkTable.navs[i].nameStrOffset, pLinkTable.navs[i].commentStrOffset);
+
 	}
 
 	return 0;


Commit: d5ceb21c04bff8b5002d34a3558892b8e86985ec
    https://github.com/scummvm/scummvm/commit/d5ceb21c04bff8b5002d34a3558892b8e86985ec
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2025-05-02T13:33:26+02:00

Commit Message:
COMMON: QT: Initialize panorama structs on construction

Changed paths:
    common/formats/quicktime.h


diff --git a/common/formats/quicktime.h b/common/formats/quicktime.h
index e027e57c711..4d2c090f858 100644
--- a/common/formats/quicktime.h
+++ b/common/formats/quicktime.h
@@ -168,14 +168,14 @@ public:
 	};
 
 	struct PanoramaNode {
-		uint32 nodeID;
-		uint32 timestamp;
+		uint32 nodeID = 0;
+		uint32 timestamp = 0;
 	};
 
 	struct PanoramaInformation {
 		String name;
-		uint32 defNodeID;
-		float defZoom;
+		uint32 defNodeID = 0;
+		float defZoom = 0.0f;
 		Array<PanoramaNode> nodes;
 	};
 


Commit: a9458a46f1d5c8f6aeb246b6e0d6fa35e27233b1
    https://github.com/scummvm/scummvm/commit/a9458a46f1d5c8f6aeb246b6e0d6fa35e27233b1
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2025-05-02T13:35:17+02:00

Commit Message:
VIDEO: QTVR: Default to the first node when incorrect node id is provided

Changed paths:
    video/qtvr_decoder.cpp


diff --git a/video/qtvr_decoder.cpp b/video/qtvr_decoder.cpp
index 3881e896bf6..bfeeb826ebf 100644
--- a/video/qtvr_decoder.cpp
+++ b/video/qtvr_decoder.cpp
@@ -461,8 +461,8 @@ void QuickTimeDecoder::goToNode(uint32 nodeID) {
 	}
 
 	if (idx == -1) {
-		warning("QuickTimeDecoder::goToNode(): Incorrect nodeID: %d", nodeID);
-		return;
+		warning("QuickTimeDecoder::goToNode(): Incorrect nodeID: %d (numNodes: %d)", nodeID, _panoTrack->panoSamples.size());
+		idx = 0;
 	}
 
 	_currentSample = idx;
@@ -887,7 +887,7 @@ void QuickTimeDecoder::PanoTrackHandler::constructPanorama() {
 		}
 
 	if (nodeidx == -1) {
-		warning("constructPanorama(): Missing node %d in anoInfo", sample->hdr.nodeID);
+		warning("constructPanorama(): Missing node %d in panoInfo", sample->hdr.nodeID);
 		nodeidx = 0;
 	}
 


Commit: 0b48f74018034cd27df1f49010ce7d6472f56cea
    https://github.com/scummvm/scummvm/commit/0b48f74018034cd27df1f49010ce7d6472f56cea
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2025-05-02T13:58:33+02:00

Commit Message:
VIDEO: QTVR: Added more debug output to atom reading

Changed paths:
    video/qtvr_decoder.cpp


diff --git a/video/qtvr_decoder.cpp b/video/qtvr_decoder.cpp
index bfeeb826ebf..c83d4df1cdf 100644
--- a/video/qtvr_decoder.cpp
+++ b/video/qtvr_decoder.cpp
@@ -123,7 +123,18 @@ Common::QuickTimeParser::SampleDesc *QuickTimeDecoder::readPanoSampleDesc(Common
 	if (entry->_maximumZoom == 0.0)
 		entry->_maximumZoom = 65.0;
 
-	return entry;
+	debugC(2, kDebugLevelGVideo, "    version: %d.%d sceneTrackID: %d loResSceneTrackID: %d hotSpotTrackID: %d",
+		entry->_majorVersion, entry->_minorVersion, entry->_sceneTrackID, entry->_loResSceneTrackID, entry->_hotSpotTrackID);
+	debugC(2, kDebugLevelGVideo, "    hpan: [%f - %f] vpan: [%f - %f] zoom: [%f - %f]",
+		entry->_hPanStart, entry->_hPanEnd, entry->_vPanTop, entry->_vPanBottom, entry->_minimumZoom, entry->_maximumZoom);
+	debugC(2, kDebugLevelGVideo, "    sceneDims: [%d x %d] frames: %d sceneFrm: [%d x %d] bpp: %d",
+		entry->_sceneSizeX, entry->_sceneSizeY, entry->_numFrames, entry->_sceneNumFramesX,
+		entry->_sceneNumFramesY, entry->_sceneColorDepth);
+	debugC(2, kDebugLevelGVideo, "    hotspotDims: [%d x %d] hotspotFrm: [%d x %d] bpp: %d",
+		entry->_hotSpotSizeX, entry->_hotSpotSizeY, entry->_hotSpotNumFramesX, entry->_hotSpotNumFramesY,
+		entry->_hotSpotColorDepth);
+
+		return entry;
 }
 
 void QuickTimeDecoder::closeQTVR() {


Commit: fb06f19fefee0235633ffbb80bdeda9d2f294c7c
    https://github.com/scummvm/scummvm/commit/fb06f19fefee0235633ffbb80bdeda9d2f294c7c
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2025-05-02T13:58:50+02:00

Commit Message:
VIDEO: QTVR: Initial support for single-node movies

Changed paths:
    video/qtvr_decoder.cpp


diff --git a/video/qtvr_decoder.cpp b/video/qtvr_decoder.cpp
index c83d4df1cdf..552d5db22d0 100644
--- a/video/qtvr_decoder.cpp
+++ b/video/qtvr_decoder.cpp
@@ -735,6 +735,19 @@ Graphics::Surface *QuickTimeDecoder::PanoTrackHandler::constructMosaic(VideoTrac
 }
 
 void QuickTimeDecoder::PanoTrackHandler::initPanorama() {
+	if (_decoder->_panoTrack->panoInfo.nodes.size() == 0) {
+		// This is a single node panorama
+		// We add one node to the list, so the rest of our code
+		// is happy
+		PanoTrackSample *sample = &_parent->panoSamples[0];
+
+		_decoder->_panoTrack->panoInfo.nodes.resize(1);
+		_decoder->_panoTrack->panoInfo.nodes[0].nodeID = sample->hdr.nodeID;
+		_decoder->_panoTrack->panoInfo.nodes[0].timestamp = 0;
+
+		_decoder->_panoTrack->panoInfo.defNodeID = sample->hdr.nodeID;
+	}
+
 	_decoder->goToNode(_decoder->_panoTrack->panoInfo.defNodeID);
 }
 


Commit: da245124ab8408ae7726426ca56ac3b61a38e7dc
    https://github.com/scummvm/scummvm/commit/da245124ab8408ae7726426ca56ac3b61a38e7dc
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2025-05-02T14:06:28+02:00

Commit Message:
VIDEO: QTVR: Support for tracks without hotspots

Changed paths:
    video/qtvr_decoder.cpp


diff --git a/video/qtvr_decoder.cpp b/video/qtvr_decoder.cpp
index 552d5db22d0..79090f4d97d 100644
--- a/video/qtvr_decoder.cpp
+++ b/video/qtvr_decoder.cpp
@@ -514,8 +514,10 @@ QuickTimeDecoder::PanoTrackHandler::~PanoTrackHandler() {
 		_upscaledConstructedPano->free();
 		delete _upscaledConstructedPano;
 
-		_constructedHotspots->free();
-		delete _constructedHotspots;
+		if (_constructedHotspots) {
+			_constructedHotspots->free();
+			delete _constructedHotspots;
+		}
 	}
 
 	if (_projectedPano) {
@@ -892,8 +894,10 @@ void QuickTimeDecoder::PanoTrackHandler::constructPanorama() {
 		_constructedPano->free();
 		delete _constructedPano;
 
-		_constructedHotspots->free();
-		delete _constructedHotspots;
+		if (_constructedHotspots) {
+			_constructedHotspots->free();
+			delete _constructedHotspots;
+		}
 	}
 
 	debugC(1, kDebugLevelGVideo, "scene: %d (%d x %d) hotspots: %d (%d x %d)", desc->_sceneTrackID, desc->_sceneSizeX, desc->_sceneSizeY,
@@ -929,17 +933,19 @@ void QuickTimeDecoder::PanoTrackHandler::constructPanorama() {
 	// or that the upscaledConstructedPanorama has upscaled a different panorama, not the current constructedPano
 	_upscaleLevel = 0;
 
-	track = (VideoTrackHandler *)(_decoder->getTrack(_decoder->Common::QuickTimeParser::_tracks[desc->_hotSpotTrackID - 1]->targetTrack));
+	if (desc->_hotSpotTrackID) {
+		track = (VideoTrackHandler *)(_decoder->getTrack(_decoder->Common::QuickTimeParser::_tracks[desc->_hotSpotTrackID - 1]->targetTrack));
 
-	track->seek(Audio::Timestamp(0, timestamp, _decoder->_timeScale));
+		track->seek(Audio::Timestamp(0, timestamp, _decoder->_timeScale));
 
-	_constructedHotspots = constructMosaic(track, desc->_hotSpotNumFramesX, desc->_hotSpotNumFramesY, "dumps/pano-hotspot.png");
+		_constructedHotspots = constructMosaic(track, desc->_hotSpotNumFramesX, desc->_hotSpotNumFramesY, "dumps/pano-hotspot.png");
+	}
 
 	_isPanoConstructed = true;
 }
 
 Common::Point QuickTimeDecoder::PanoTrackHandler::projectPoint(int16 mx, int16 my) {
-	if (!_isPanoConstructed)
+	if (!_isPanoConstructed || !_constructedHotspots)
 		return Common::Point(-1, -1);
 
 	uint16 w = _decoder->getWidth(), h = _decoder->getHeight();
@@ -1429,13 +1435,16 @@ Graphics::FloatPoint QuickTimeDecoder::getPanAngles(int16 x, int16 y) {
 void QuickTimeDecoder::lookupHotspot(int16 x, int16 y) {
 	PanoTrackHandler *track = (PanoTrackHandler *)getTrack(_panoTrack->targetTrack);
 
+	if (!track->_constructedHotspots)
+		return;
+
 	Common::Point hotspotPoint = track->projectPoint(x, y);
 
 	if (hotspotPoint.x < 0) {
 		_rolloverHotspot = nullptr;
 		_rolloverHotspotID = 0;
 	} else {
-		int hotspotId = (int)(((PanoTrackHandler *)getTrack(_panoTrack->targetTrack))->_constructedHotspots->getPixel(hotspotPoint.y, hotspotPoint.x));
+		int hotspotId = (int)track->_constructedHotspots->getPixel(hotspotPoint.y, hotspotPoint.x);
 
 		_rolloverHotspotID = hotspotId;
 
@@ -1733,8 +1742,10 @@ void QuickTimeDecoder::handlePanoKey(Common::KeyState &state, bool down, bool re
 		_zoomState = kZoomNone;
 	}
 
-	if (state.keycode == Common::KEYCODE_h && down && !repeat)
-		renderHotspots(!_renderHotspots);
+	if (state.keycode == Common::KEYCODE_h && down && !repeat) {
+		if (track->_constructedHotspots)
+			renderHotspots(!_renderHotspots);
+	}
 }
 
 enum {




More information about the Scummvm-git-logs mailing list