[Scummvm-git-logs] scummvm master -> 299b3b3ad628c71b268054daf5af7818206f898c

whoozle noreply at scummvm.org
Sun Jul 19 12:14:05 UTC 2026


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

Summary:
299b3b3ad6 PHOENIXVR: Support V2 VR format


Commit: 299b3b3ad628c71b268054daf5af7818206f898c
    https://github.com/scummvm/scummvm/commit/299b3b3ad628c71b268054daf5af7818206f898c
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2026-07-19T13:13:41+01:00

Commit Message:
PHOENIXVR: Support V2 VR format

It's essentially the same as V1, with FOURCC readable chunk types.
Current version is missing 3D texture and stop frame, to be found later,
but it allows loading main menu

Changed paths:
    engines/phoenixvr/phoenixvr.cpp
    engines/phoenixvr/phoenixvr.h
    engines/phoenixvr/region_set.cpp
    engines/phoenixvr/vr.cpp
    engines/phoenixvr/vr.h


diff --git a/engines/phoenixvr/phoenixvr.cpp b/engines/phoenixvr/phoenixvr.cpp
index ec856dcc018..33266d0d42c 100644
--- a/engines/phoenixvr/phoenixvr.cpp
+++ b/engines/phoenixvr/phoenixvr.cpp
@@ -342,6 +342,10 @@ PhoenixVREngine::PhoenixVREngine(OSystem *syst, const ADGameDescription *gameDes
 	}
 }
 
+int PhoenixVREngine::version() const {
+	return (_gameDescription->flags & PHOENIXVR_V2) ? 2 : 1;
+}
+
 void PhoenixVREngine::resetState() {
 	_angleX.resetRange();
 	_angleX.set(0);
@@ -489,8 +493,7 @@ void PhoenixVREngine::loadNextScript() {
 	if (!s)
 		error("can't open script file %s", nextScript.c_str());
 
-	int version = (_gameDescription->flags & PHOENIXVR_V2) ? 2 : 1;
-	_script.reset(Script::load(*s, version));
+	_script.reset(Script::load(*s, version()));
 	for (auto &var : _script->getVarNames())
 		declareVariable(var);
 	if (gameIdMatches("dracula1")) {
@@ -1712,7 +1715,7 @@ Common::Error PhoenixVREngine::run() {
 		setNextScript("intro.lst");
 	else if (gameIdMatches("lochness"))
 		setNextScript("first.lst");
-	else if (_gameDescription->flags & PHOENIXVR_V2)
+	else if (version() == 2)
 		setNextLevel();
 	else
 		setNextScript("script.lst");
diff --git a/engines/phoenixvr/phoenixvr.h b/engines/phoenixvr/phoenixvr.h
index aa3d34791bd..78722442dc1 100644
--- a/engines/phoenixvr/phoenixvr.h
+++ b/engines/phoenixvr/phoenixvr.h
@@ -96,6 +96,8 @@ public:
 
 	uint32 getFeatures() const;
 
+	int version() const;
+
 	bool gameIdMatches(const char *gameId) const;
 
 	/**
diff --git a/engines/phoenixvr/region_set.cpp b/engines/phoenixvr/region_set.cpp
index 3060165db67..e97236a78c9 100644
--- a/engines/phoenixvr/region_set.cpp
+++ b/engines/phoenixvr/region_set.cpp
@@ -21,19 +21,33 @@
 
 #include "phoenixvr/region_set.h"
 #include "common/debug.h"
-#include "common/file.h"
 #include "phoenixvr/math.h"
+#include "phoenixvr/phoenixvr.h"
 
 namespace PhoenixVR {
 RegionSet::RegionSet(Common::SeekableReadStream &s) {
-	auto n = s.readUint32LE();
-	while (n--) {
-		auto a = s.readFloatLE();
-		auto b = s.readFloatLE();
-		auto c = s.readFloatLE();
-		auto d = s.readFloatLE();
-		_regions.push_back(Region{MIN(a, b), MAX(a, b), MIN(c, d), MAX(c, d)});
-		debug("region %s", _regions.back().toString().c_str());
+	auto version = g_engine->version();
+	if (version == 1) {
+		auto n = s.readUint32LE();
+		while (n--) {
+			auto a = s.readFloatLE();
+			auto b = s.readFloatLE();
+			auto c = s.readFloatLE();
+			auto d = s.readFloatLE();
+			_regions.push_back(Region{MIN(a, b), MAX(a, b), MIN(c, d), MAX(c, d)});
+			debug("region %s", _regions.back().toString().c_str());
+		}
+	} else if (version == 2) {
+		while (!s.eos()) {
+			auto a = s.readFloatLE();
+			auto b = s.readFloatLE();
+			auto c = s.readFloatLE();
+			auto d = s.readFloatLE();
+			_regions.push_back(Region{MIN(a, b), MAX(a, b), MIN(c, d), MAX(c, d)});
+			debug("region %s", _regions.back().toString().c_str());
+		}
+	} else {
+		error("invalid version %d", version);
 	}
 }
 
diff --git a/engines/phoenixvr/vr.cpp b/engines/phoenixvr/vr.cpp
index aa525c1c66c..96eae5e43bd 100644
--- a/engines/phoenixvr/vr.cpp
+++ b/engines/phoenixvr/vr.cpp
@@ -23,8 +23,6 @@
 #include "common/array.h"
 #include "common/bitstream.h"
 #include "common/debug.h"
-#include "common/file.h"
-#include "common/memstream.h"
 #include "common/system.h"
 #include "common/textconsole.h"
 #include "graphics/screen.h"
@@ -46,6 +44,18 @@ namespace PhoenixVR {
 #define CHUNK_ANIMATION_BLOCK (0xa0b1c211)
 #define CHUNK_ANIMATION_RESTART (0xa0b1c221)
 
+/* HEAD */
+#define V2_CHUNK_VR (0x44414548)
+/* STPC */
+#define V2_CHUNK_STATIC_2D (0x43505453)
+/* STWP */
+#define V2_CHUNK_STATIC_3D (0x50575453)
+/* ANWP */
+#define V2_CHUNK_ANIMATION (0x50574e41)
+/* FRAM */
+#define V2_CHUNK_ANIMATION_BLOCK (0x4d415246)
+#define V2_CHUNK_ANIMATION_RESTART (0xa0b1c221)
+
 namespace {
 
 constexpr int kStaticImageWidth = 640;
@@ -358,16 +368,20 @@ void unpack(Graphics::Surface &pic, const byte *huff, uint huffSize, const byte
 VR VR::loadStatic(const Graphics::PixelFormat &format, Common::SeekableReadStream &s) {
 	VR vr;
 	auto magic = s.readUint32LE();
-	if (magic != CHUNK_VR) {
+	if (magic == CHUNK_VR) {
+		vr._v2 = false;
+	} else if (magic == V2_CHUNK_VR) {
+		vr._v2 = true;
+	} else
 		error("wrong VR magic");
-	}
+
 	auto fsize = s.readUint32LE();
 	while (s.pos() < fsize) {
 		auto chunkPos = s.pos();
 		auto chunkId = s.readUint32LE();
 		auto chunkSize = s.readUint32LE();
-		bool pic2d = chunkId == CHUNK_STATIC_2D;
-		bool pic3d = chunkId == CHUNK_STATIC_3D;
+		bool pic2d = chunkId == CHUNK_STATIC_2D || chunkId == V2_CHUNK_STATIC_2D;
+		bool pic3d = chunkId == CHUNK_STATIC_3D || chunkId == V2_CHUNK_STATIC_3D;
 		if (pic2d || pic3d) {
 			auto quality = s.readUint32LE();
 			auto dataSize = s.readUint32LE();
@@ -403,7 +417,7 @@ VR VR::loadStatic(const Graphics::PixelFormat &format, Common::SeekableReadStrea
 			auto *dcPtr = acPtr + 4 + dcOffset;
 			auto *dcEnd = vrData.data() + vrData.size();
 			unpack(*pic->surfacePtr(), huff, huffSize, acPtr, dcPtr - acPtr, dcPtr, dcEnd - dcPtr, quality);
-		} else if (chunkId == CHUNK_ANIMATION) {
+		} else if (chunkId == CHUNK_ANIMATION || chunkId == V2_CHUNK_ANIMATION) {
 			Animation animation;
 			animation.name = s.readString(0, 32);
 			auto numFrames = s.readUint32LE();
@@ -416,10 +430,10 @@ VR VR::loadStatic(const Graphics::PixelFormat &format, Common::SeekableReadStrea
 				debug("animation frame at %08x: %08x %u", (uint32)animChunkPos, animChunkId, animChunkSize);
 				assert(animChunkSize >= 8);
 				Animation::Frame frame;
-				if (animChunkId == CHUNK_ANIMATION_BLOCK) {
+				if (animChunkId == CHUNK_ANIMATION_BLOCK || animChunkId == V2_CHUNK_ANIMATION_BLOCK) {
 					frame.blockData.resize(animChunkSize - 8);
 					s.read(frame.blockData.data(), frame.blockData.size());
-				} else if (animChunkId == CHUNK_ANIMATION_RESTART) {
+				} else if (animChunkId == CHUNK_ANIMATION_RESTART || animChunkId == V2_CHUNK_ANIMATION_RESTART) {
 					assert(animChunkSize - 8 == 4);
 					byte buf[4] = {};
 					s.read(buf, sizeof(buf));
@@ -428,7 +442,7 @@ VR VR::loadStatic(const Graphics::PixelFormat &format, Common::SeekableReadStrea
 				} else {
 					Common::Array<byte> buf(animChunkSize - 8);
 					s.read(buf.data(), buf.size());
-					warning("unknown frame type");
+					warning("unknown frame type %08x", animChunkId);
 				}
 				animation.frames.push_back(Common::move(frame));
 				s.seek(animChunkPos + animChunkSize);
diff --git a/engines/phoenixvr/vr.h b/engines/phoenixvr/vr.h
index 1fa52bfc40b..7998ccf3bfe 100644
--- a/engines/phoenixvr/vr.h
+++ b/engines/phoenixvr/vr.h
@@ -63,6 +63,7 @@ class VR {
 	bool _showWaves = false;
 	float _wavesT = 0;
 	bool _ignoreRightPixel = false;
+	bool _v2 = false;
 
 public:
 	static VR loadStatic(const Graphics::PixelFormat &format, Common::SeekableReadStream &s);




More information about the Scummvm-git-logs mailing list