[Scummvm-git-logs] scummvm master -> 32ad0fc8affd2227c9eaca43002fb1e71d3f7029
bluegr
noreply at scummvm.org
Sat Sep 26 01:55:05 UTC 2026
This automated email contains information about 5 new commits which have been
pushed to the 'scummvm' repo located at https://api.github.com/repos/scummvm/scummvm .
Summary:
1c4a06b4c2 NANCY: Move reusable puzzle functionality into a common class
5d39de020c NANCY: Centralize puzzle solve sound handling
f34b5c1a4e NANCY: Place held items in the inventory in puzzles that perform this
3995181314 NANCY: Centralize more sound and viewport related puzzle code
32ad0fc8af NANCY: Centralize puzzle background image names and surfaces
Commit: 1c4a06b4c2fd2a5a2741413debb01d552fc1e64c
https://github.com/scummvm/scummvm/commit/1c4a06b4c2fd2a5a2741413debb01d552fc1e64c
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2026-09-26T04:54:23+03:00
Commit Message:
NANCY: Move reusable puzzle functionality into a common class
- A common PuzzleRecord class has been introduced for all puzzles
- Puzzle win scenes and cancel scenes are now common
- Exit/give-up hotspot reading/checking has been centralized
- Variables with the same functionality have been renamed across all
puzzles (e.g. winScene -> solveScene)
- Puzzle debug info, such as the win/cancel scenes is now common
Changed paths:
A engines/nancy/action/puzzlerecord.cpp
A engines/nancy/action/puzzlerecord.h
engines/nancy/action/puzzle/adjustpuzzle.cpp
engines/nancy/action/puzzle/adjustpuzzle.h
engines/nancy/action/puzzle/angletosspuzzle.cpp
engines/nancy/action/puzzle/angletosspuzzle.h
engines/nancy/action/puzzle/arcadepuzzle.cpp
engines/nancy/action/puzzle/arcadepuzzle.h
engines/nancy/action/puzzle/assemblypuzzle.cpp
engines/nancy/action/puzzle/assemblypuzzle.h
engines/nancy/action/puzzle/bballpuzzle.cpp
engines/nancy/action/puzzle/bballpuzzle.h
engines/nancy/action/puzzle/beadpuzzle.cpp
engines/nancy/action/puzzle/beadpuzzle.h
engines/nancy/action/puzzle/blockingpuzzle.h
engines/nancy/action/puzzle/blockspuzzle.cpp
engines/nancy/action/puzzle/blockspuzzle.h
engines/nancy/action/puzzle/boardgamepuzzle.cpp
engines/nancy/action/puzzle/boardgamepuzzle.h
engines/nancy/action/puzzle/bombpuzzle.cpp
engines/nancy/action/puzzle/bombpuzzle.h
engines/nancy/action/puzzle/buildpuzzle.cpp
engines/nancy/action/puzzle/buildpuzzle.h
engines/nancy/action/puzzle/bulpuzzle.cpp
engines/nancy/action/puzzle/bulpuzzle.h
engines/nancy/action/puzzle/cardgamepuzzle.cpp
engines/nancy/action/puzzle/cardgamepuzzle.h
engines/nancy/action/puzzle/collisionpuzzle.cpp
engines/nancy/action/puzzle/collisionpuzzle.h
engines/nancy/action/puzzle/cubepuzzle.cpp
engines/nancy/action/puzzle/cubepuzzle.h
engines/nancy/action/puzzle/cuttingpuzzle.cpp
engines/nancy/action/puzzle/cuttingpuzzle.h
engines/nancy/action/puzzle/decoderpuzzle.cpp
engines/nancy/action/puzzle/decoderpuzzle.h
engines/nancy/action/puzzle/dotconnectpuzzle.cpp
engines/nancy/action/puzzle/dotconnectpuzzle.h
engines/nancy/action/puzzle/drivingpuzzle.cpp
engines/nancy/action/puzzle/drivingpuzzle.h
engines/nancy/action/puzzle/dropsortpuzzle.cpp
engines/nancy/action/puzzle/dropsortpuzzle.h
engines/nancy/action/puzzle/escapegridpuzzle.cpp
engines/nancy/action/puzzle/escapegridpuzzle.h
engines/nancy/action/puzzle/gridmappuzzle.cpp
engines/nancy/action/puzzle/gridmappuzzle.h
engines/nancy/action/puzzle/hamradiopuzzle.h
engines/nancy/action/puzzle/hangmanpuzzle.cpp
engines/nancy/action/puzzle/hangmanpuzzle.h
engines/nancy/action/puzzle/lettergridpuzzle.cpp
engines/nancy/action/puzzle/lettergridpuzzle.h
engines/nancy/action/puzzle/leverpuzzle.cpp
engines/nancy/action/puzzle/leverpuzzle.h
engines/nancy/action/puzzle/magicboxpuzzle.cpp
engines/nancy/action/puzzle/magicboxpuzzle.h
engines/nancy/action/puzzle/magnetmazepuzzle.cpp
engines/nancy/action/puzzle/magnetmazepuzzle.h
engines/nancy/action/puzzle/matchpuzzle.cpp
engines/nancy/action/puzzle/matchpuzzle.h
engines/nancy/action/puzzle/mazechasepuzzle.cpp
engines/nancy/action/puzzle/mazechasepuzzle.h
engines/nancy/action/puzzle/memorypuzzle.cpp
engines/nancy/action/puzzle/memorypuzzle.h
engines/nancy/action/puzzle/meterpuzzle.h
engines/nancy/action/puzzle/mindpuzzle.cpp
engines/nancy/action/puzzle/mindpuzzle.h
engines/nancy/action/puzzle/minigolfpuzzle.cpp
engines/nancy/action/puzzle/minigolfpuzzle.h
engines/nancy/action/puzzle/mirrorlightpuzzle.h
engines/nancy/action/puzzle/mouselightpuzzle.h
engines/nancy/action/puzzle/multibuildpuzzle.cpp
engines/nancy/action/puzzle/multibuildpuzzle.h
engines/nancy/action/puzzle/necklacepuzzle.cpp
engines/nancy/action/puzzle/necklacepuzzle.h
engines/nancy/action/puzzle/onebuildpuzzle.cpp
engines/nancy/action/puzzle/onebuildpuzzle.h
engines/nancy/action/puzzle/orderingpuzzle.cpp
engines/nancy/action/puzzle/orderingpuzzle.h
engines/nancy/action/puzzle/overridelockpuzzle.cpp
engines/nancy/action/puzzle/overridelockpuzzle.h
engines/nancy/action/puzzle/pachinkopuzzle.cpp
engines/nancy/action/puzzle/pachinkopuzzle.h
engines/nancy/action/puzzle/paintpuzzle.h
engines/nancy/action/puzzle/passwordpuzzle.cpp
engines/nancy/action/puzzle/passwordpuzzle.h
engines/nancy/action/puzzle/peepholepuzzle.cpp
engines/nancy/action/puzzle/peepholepuzzle.h
engines/nancy/action/puzzle/pegspuzzle.cpp
engines/nancy/action/puzzle/pegspuzzle.h
engines/nancy/action/puzzle/quizpuzzle.cpp
engines/nancy/action/puzzle/quizpuzzle.h
engines/nancy/action/puzzle/raycastpuzzle.cpp
engines/nancy/action/puzzle/raycastpuzzle.h
engines/nancy/action/puzzle/riddlepuzzle.cpp
engines/nancy/action/puzzle/riddlepuzzle.h
engines/nancy/action/puzzle/rippedletterpuzzle.cpp
engines/nancy/action/puzzle/rippedletterpuzzle.h
engines/nancy/action/puzzle/rotatinglockpuzzle.cpp
engines/nancy/action/puzzle/rotatinglockpuzzle.h
engines/nancy/action/puzzle/safedialpuzzle.cpp
engines/nancy/action/puzzle/safedialpuzzle.h
engines/nancy/action/puzzle/scalepuzzle.cpp
engines/nancy/action/puzzle/scalepuzzle.h
engines/nancy/action/puzzle/setplayerclock.cpp
engines/nancy/action/puzzle/setplayerclock.h
engines/nancy/action/puzzle/sewingmachinepuzzle.h
engines/nancy/action/puzzle/sliderpuzzle.cpp
engines/nancy/action/puzzle/sliderpuzzle.h
engines/nancy/action/puzzle/sortpuzzle.cpp
engines/nancy/action/puzzle/sortpuzzle.h
engines/nancy/action/puzzle/soundequalizerpuzzle.cpp
engines/nancy/action/puzzle/soundequalizerpuzzle.h
engines/nancy/action/puzzle/soundmatchpuzzle.cpp
engines/nancy/action/puzzle/soundmatchpuzzle.h
engines/nancy/action/puzzle/spigotpuzzle.cpp
engines/nancy/action/puzzle/spigotpuzzle.h
engines/nancy/action/puzzle/stepobjectspuzzle.cpp
engines/nancy/action/puzzle/stepobjectspuzzle.h
engines/nancy/action/puzzle/tangrampuzzle.cpp
engines/nancy/action/puzzle/tangrampuzzle.h
engines/nancy/action/puzzle/telephone.cpp
engines/nancy/action/puzzle/telephone.h
engines/nancy/action/puzzle/towerpuzzle.cpp
engines/nancy/action/puzzle/towerpuzzle.h
engines/nancy/action/puzzle/turningpuzzle.cpp
engines/nancy/action/puzzle/turningpuzzle.h
engines/nancy/action/puzzle/twodialpuzzle.cpp
engines/nancy/action/puzzle/twodialpuzzle.h
engines/nancy/action/puzzle/typingquizpuzzle.cpp
engines/nancy/action/puzzle/typingquizpuzzle.h
engines/nancy/action/puzzle/weightsortpuzzle.cpp
engines/nancy/action/puzzle/weightsortpuzzle.h
engines/nancy/action/puzzle/whalesurvivorpuzzle.cpp
engines/nancy/action/puzzle/whalesurvivorpuzzle.h
engines/nancy/action/puzzle/wordfindpuzzle.cpp
engines/nancy/action/puzzle/wordfindpuzzle.h
engines/nancy/module.mk
diff --git a/engines/nancy/action/puzzle/adjustpuzzle.cpp b/engines/nancy/action/puzzle/adjustpuzzle.cpp
index 17e03539184..554372c6e11 100644
--- a/engines/nancy/action/puzzle/adjustpuzzle.cpp
+++ b/engines/nancy/action/puzzle/adjustpuzzle.cpp
@@ -100,7 +100,7 @@ void AdjustPuzzle::readData(Common::SeekableReadStream &stream) {
// Trailing count-prefixed array of 23-byte give-up hotspots
// {Rect, uint16 cursorType, uint16 sceneID, int16 flagLabel, byte flagValue}.
// The exit always jumps to the scene's first frame.
- readExitHotspot(stream, _exitHotspot, _exitCursorType, _exitScene, _exitFlag);
+ readExitHotspot(stream);
}
void AdjustPuzzle::init() {
@@ -228,9 +228,7 @@ void AdjustPuzzle::handleInput(NancyInput &input) {
const bool click = (input.input & NancyInput::kLeftMouseButtonUp) != 0;
// Give-up hotspot: leave the puzzle.
- if (!_exitHotspot.isEmpty() &&
- NancySceneState.getViewport().convertViewportToScreen(_exitHotspot).contains(input.mousePos)) {
- g_nancy->_cursor->setCursorType((CursorManager::CursorType)_exitCursorType, true);
+ if (hoverExitHotspot(input)) {
if (click) {
_exitRequested = true;
}
@@ -273,8 +271,7 @@ void AdjustPuzzle::execute() {
break;
case kRun:
if (_exitRequested) {
- NancySceneState.setEventFlag(_exitFlag);
- NancySceneState.changeScene(_exitScene);
+ _exitScene.execute();
break;
}
if ((_solved || _lost) && !_outcomeApplied) {
diff --git a/engines/nancy/action/puzzle/adjustpuzzle.h b/engines/nancy/action/puzzle/adjustpuzzle.h
index 4c1f59edc62..8ab37d8e7b8 100644
--- a/engines/nancy/action/puzzle/adjustpuzzle.h
+++ b/engines/nancy/action/puzzle/adjustpuzzle.h
@@ -23,7 +23,7 @@
#define NANCY_ACTION_ADJUSTPUZZLE_H
#include "engines/nancy/commontypes.h"
-#include "engines/nancy/action/actionrecord.h"
+#include "engines/nancy/action/puzzlerecord.h"
namespace Nancy {
namespace Action {
@@ -34,9 +34,9 @@ namespace Action {
// table of combinations to pick a result; hitting the "perfect" result solves
// the puzzle, any other shows a result overlay (Perfect-Vert / -Hor / -Mirror /
// -Lite, ...) and fails.
-class AdjustPuzzle : public RenderActionRecord {
+class AdjustPuzzle : public PuzzleRecord {
public:
- AdjustPuzzle() : RenderActionRecord(7) {}
+ AdjustPuzzle() : PuzzleRecord(7) {}
virtual ~AdjustPuzzle() {}
void init() override;
@@ -105,12 +105,6 @@ protected:
Outcome _winScene; // 0x21c (field0), scene at 0x21e
Outcome _loseScene; // 0x27d (field0), scene at 0x27f
- // Give-up hotspot (count-prefixed 23-byte trailer): click to leave the puzzle.
- Common::Rect _exitHotspot;
- uint16 _exitCursorType = 0;
- SceneChangeDescription _exitScene;
- FlagDescription _exitFlag;
-
// -- Runtime state --
Graphics::ManagedSurface _image;
Common::Array<Graphics::ManagedSurface> _overlayImages;
diff --git a/engines/nancy/action/puzzle/angletosspuzzle.cpp b/engines/nancy/action/puzzle/angletosspuzzle.cpp
index 4877d2d0a9a..8169c9e9173 100644
--- a/engines/nancy/action/puzzle/angletosspuzzle.cpp
+++ b/engines/nancy/action/puzzle/angletosspuzzle.cpp
@@ -174,9 +174,7 @@ void AngleTossPuzzle::handleInput(NancyInput &input) {
localMousePos -= Common::Point(vpPos.left, vpPos.top);
// Exit button
- if (_exitHotspot.contains(localMousePos)) {
- g_nancy->_cursor->setCursorType(g_nancy->_cursor->_puzzleExitCursor);
-
+ if (hoverExitHotspot(input)) {
if (input.input & NancyInput::kLeftMouseButtonUp) {
_exitPressed = true;
_state = kActionTrigger;
diff --git a/engines/nancy/action/puzzle/angletosspuzzle.h b/engines/nancy/action/puzzle/angletosspuzzle.h
index 4a83ee56432..bb2d0c282ec 100644
--- a/engines/nancy/action/puzzle/angletosspuzzle.h
+++ b/engines/nancy/action/puzzle/angletosspuzzle.h
@@ -22,7 +22,7 @@
#ifndef NANCY_ACTION_ANGLETOSSPUZZLE_H
#define NANCY_ACTION_ANGLETOSSPUZZLE_H
-#include "engines/nancy/action/actionrecord.h"
+#include "engines/nancy/action/puzzlerecord.h"
namespace Nancy {
namespace Action {
@@ -42,9 +42,9 @@ namespace Action {
// based on which of the four fail flags is set (too strong/weak, too left/right). After the
// separate AR instances (each with their own target) implement the 3-round mechanic.
-class AngleTossPuzzle : public RenderActionRecord {
+class AngleTossPuzzle : public PuzzleRecord {
public:
- AngleTossPuzzle() : RenderActionRecord(7) {}
+ AngleTossPuzzle() : PuzzleRecord(7) {}
virtual ~AngleTossPuzzle() {}
void init() override;
@@ -113,9 +113,6 @@ protected:
int16 _winFlag = -1; // 0x23e
- SceneChangeWithFlag _exitScene;
- Common::Rect _exitHotspot;
-
Graphics::ManagedSurface _image;
uint16 _curPower = 0;
diff --git a/engines/nancy/action/puzzle/arcadepuzzle.cpp b/engines/nancy/action/puzzle/arcadepuzzle.cpp
index 0b3a55daec2..ebd0fd18c6d 100644
--- a/engines/nancy/action/puzzle/arcadepuzzle.cpp
+++ b/engines/nancy/action/puzzle/arcadepuzzle.cpp
@@ -141,7 +141,7 @@ void ArcadePuzzle::readData(Common::SeekableReadStream &stream) {
_sounds[i].readNormal(stream);
_levelClearSound.readNormal(stream); // 49 bytes, +0x43b..+0x46b
- _winScene.readData(stream); // 25 bytes, +0x46c..+0x484
+ _solveScene.readData(stream); // 25 bytes, +0x46c..+0x484
stream.skip(1); // 1-byte gap, +0x485
_gameOverSound.readNormal(stream); // 49 bytes, +0x486..+0x4b6
@@ -594,7 +594,7 @@ void ArcadePuzzle::execute() {
// forever until they clear the required level(s). So
// kActionTrigger is only ever reached via kGameOverWin, and
// we just execute the win scene change + flag set.
- _winScene.execute();
+ _solveScene.execute();
finishExecution();
break;
diff --git a/engines/nancy/action/puzzle/arcadepuzzle.h b/engines/nancy/action/puzzle/arcadepuzzle.h
index 2660aa98d81..2f9edf9af99 100644
--- a/engines/nancy/action/puzzle/arcadepuzzle.h
+++ b/engines/nancy/action/puzzle/arcadepuzzle.h
@@ -22,7 +22,7 @@
#ifndef NANCY_ACTION_ARCADEPUZZLE_H
#define NANCY_ACTION_ARCADEPUZZLE_H
-#include "engines/nancy/action/actionrecord.h"
+#include "engines/nancy/action/puzzlerecord.h"
#include "engines/nancy/commontypes.h"
#include "graphics/managed_surface.h"
@@ -36,9 +36,9 @@ namespace Action {
// The player controls a paddle at the bottom of the screen, bouncing a ball
// to destroy bricks. The player needs to beat 2 levels to get the full prize.
// Data file is 0x4e8 (1256) bytes.
-class ArcadePuzzle : public RenderActionRecord {
+class ArcadePuzzle : public PuzzleRecord {
public:
- ArcadePuzzle() : RenderActionRecord(7) {}
+ ArcadePuzzle() : PuzzleRecord(7) {}
virtual ~ArcadePuzzle();
void init() override;
@@ -165,9 +165,6 @@ protected:
SoundDescription _gameOverSound; // 0x486
SoundDescription _lifeLostSound; // 0x4b7
- // Win scene (0x46c, 25 bytes)
- SceneChangeWithFlag _winScene;
-
// ---------- Runtime state ----------
// Note: this game has no lives â losing a ball just rewinds to a
diff --git a/engines/nancy/action/puzzle/assemblypuzzle.cpp b/engines/nancy/action/puzzle/assemblypuzzle.cpp
index d3e3d4662a1..283b6c6a14c 100644
--- a/engines/nancy/action/puzzle/assemblypuzzle.cpp
+++ b/engines/nancy/action/puzzle/assemblypuzzle.cpp
@@ -106,7 +106,7 @@ void AssemblyPuzzle::readData(Common::SeekableReadStream &stream) {
assembleTextLine(buf, _wrongPieceTexts[i], 200);
}
- _solveScene.readData(stream);
+ _solveScene.readData(stream); // has 9999 in nancy6, so the puzzle doesn't auto-exit
_solveSound.readNormal(stream);
stream.read(buf, 200);
assembleTextLine(buf, _solveText, 200);
@@ -164,9 +164,7 @@ void AssemblyPuzzle::handleInput(NancyInput &input) {
return;
}
- if (_pickedUpPiece == -1 && NancySceneState.getViewport().convertViewportToScreen(_exitHotspot).contains(input.mousePos)) {
- g_nancy->_cursor->setCursorType(g_nancy->_cursor->_puzzleExitCursor);
-
+ if (_pickedUpPiece == -1 && hoverExitHotspot(input)) {
if (input.input & NancyInput::kLeftMouseButtonUp) {
_state = kActionTrigger;
_completed = false;
diff --git a/engines/nancy/action/puzzle/assemblypuzzle.h b/engines/nancy/action/puzzle/assemblypuzzle.h
index 1a6b373cc01..31d37383c57 100644
--- a/engines/nancy/action/puzzle/assemblypuzzle.h
+++ b/engines/nancy/action/puzzle/assemblypuzzle.h
@@ -22,7 +22,7 @@
#ifndef NANCY_ACTION_ASSEMBLYPUZZLE_H
#define NANCY_ACTION_ASSEMBLYPUZZLE_H
-#include "engines/nancy/action/actionrecord.h"
+#include "engines/nancy/action/puzzlerecord.h"
#include "engines/nancy/misc/mousefollow.h"
namespace Nancy {
@@ -33,9 +33,9 @@ namespace Action {
// Minigame where the player is provided with the broken pieces of something
// (a piece of pottery in nancy6), and has to assemble it.
-class AssemblyPuzzle : public RenderActionRecord {
+class AssemblyPuzzle : public PuzzleRecord {
public:
- AssemblyPuzzle() : RenderActionRecord(7) {}
+ AssemblyPuzzle() : PuzzleRecord(7) {}
virtual ~AssemblyPuzzle() {}
AssemblyPuzzle(AssemblyPuzzle &&) = default;
@@ -84,13 +84,9 @@ protected:
Common::Array<SoundDescription> _wrongPieceSounds;
Common::Array<Common::String> _wrongPieceTexts;
- SceneChangeWithFlag _solveScene; // has 9999 in nancy6, so the puzzle doesn't auto-exit
SoundDescription _solveSound;
Common::String _solveText;
- SceneChangeWithFlag _exitScene;
- Common::Rect _exitHotspot;
-
Graphics::ManagedSurface _image;
int _pickedUpPiece = -1;
diff --git a/engines/nancy/action/puzzle/bballpuzzle.cpp b/engines/nancy/action/puzzle/bballpuzzle.cpp
index 764dc3ef651..799ab572446 100644
--- a/engines/nancy/action/puzzle/bballpuzzle.cpp
+++ b/engines/nancy/action/puzzle/bballpuzzle.cpp
@@ -223,9 +223,7 @@ void BBallPuzzle::handleInput(NancyInput &input) {
Common::Rect vpPos = NancySceneState.getViewport().getScreenPosition();
localMousePos -= { vpPos.left, vpPos.top };
- if (_exitHotspot.contains(localMousePos)) {
- g_nancy->_cursor->setCursorType(g_nancy->_cursor->_puzzleExitCursor);
-
+ if (hoverExitHotspot(input)) {
if (!_pressedButton &&input.input & NancyInput::kLeftMouseButtonUp) {
_state = kActionTrigger;
}
diff --git a/engines/nancy/action/puzzle/bballpuzzle.h b/engines/nancy/action/puzzle/bballpuzzle.h
index ab6100f96c7..d17289d9d8d 100644
--- a/engines/nancy/action/puzzle/bballpuzzle.h
+++ b/engines/nancy/action/puzzle/bballpuzzle.h
@@ -22,15 +22,15 @@
#ifndef NANCY_ACTION_BBALLPUZZLE_H
#define NANCY_ACTION_BBALLPUZZLE_H
-#include "engines/nancy/action/actionrecord.h"
+#include "engines/nancy/action/puzzlerecord.h"
#include "engines/nancy/misc/mousefollow.h"
namespace Nancy {
namespace Action {
-class BBallPuzzle : public RenderActionRecord {
+class BBallPuzzle : public PuzzleRecord {
public:
- BBallPuzzle() : RenderActionRecord(7) {}
+ BBallPuzzle() : PuzzleRecord(7) {}
virtual ~BBallPuzzle() {}
void init() override;
@@ -81,9 +81,6 @@ protected:
int16 _winFlag = 0;
- SceneChangeWithFlag _exitScene;
- Common::Rect _exitHotspot;
-
Graphics::ManagedSurface _image;
uint _curAngle = 0;
diff --git a/engines/nancy/action/puzzle/beadpuzzle.cpp b/engines/nancy/action/puzzle/beadpuzzle.cpp
index 80a97b5dd31..2de31d5a906 100644
--- a/engines/nancy/action/puzzle/beadpuzzle.cpp
+++ b/engines/nancy/action/puzzle/beadpuzzle.cpp
@@ -85,9 +85,9 @@ void BeadPuzzle::readData(Common::SeekableReadStream &stream) {
_perfectFlag.label = stream.readSint16LE();
_perfectFlag.flag = stream.readByte();
- _defaultScene.readData(stream);
+ _exitScene._sceneChange.readData(stream);
stream.skip(2);
- _solvedScene.readData(stream);
+ _solveScene._sceneChange.readData(stream);
stream.skip(2);
readRect(stream, _exitHotspot);
@@ -200,7 +200,7 @@ void BeadPuzzle::execute() {
g_nancy->_sound->stopSound(_partialSound);
g_nancy->_sound->stopSound(_wrongSound);
g_nancy->_sound->stopSound(_perfectSound);
- NancySceneState.changeScene(_subState == kExitToSolved ? _solvedScene : _defaultScene);
+ NancySceneState.changeScene(_subState == kExitToSolved ? _solveScene._sceneChange : _exitScene._sceneChange);
finishExecution();
break;
}
@@ -304,8 +304,7 @@ void BeadPuzzle::handleInput(NancyInput &input) {
}
}
- if (!_exitHotspot.isEmpty() && _exitHotspot.contains(mouseVP)) {
- g_nancy->_cursor->setCursorType(g_nancy->_cursor->_puzzleExitCursor);
+ if (hoverExitHotspot(input)) {
if (input.input & NancyInput::kLeftMouseButtonUp)
_subState = kExitToDefault;
}
diff --git a/engines/nancy/action/puzzle/beadpuzzle.h b/engines/nancy/action/puzzle/beadpuzzle.h
index c31713c6431..7364b7b9d69 100644
--- a/engines/nancy/action/puzzle/beadpuzzle.h
+++ b/engines/nancy/action/puzzle/beadpuzzle.h
@@ -22,7 +22,7 @@
#ifndef NANCY_ACTION_BEADPUZZLE_H
#define NANCY_ACTION_BEADPUZZLE_H
-#include "engines/nancy/action/actionrecord.h"
+#include "engines/nancy/action/puzzlerecord.h"
#include "engines/nancy/misc/mousefollow.h"
#include "engines/nancy/commontypes.h"
@@ -33,9 +33,9 @@ namespace Action {
// them onto a thread; when all slots are filled the sequence is scored against
// the solution, yielding perfect / partial / wrong results.
// Called from scene 6251 in Nancy10.
-class BeadPuzzle : public RenderActionRecord {
+class BeadPuzzle : public PuzzleRecord {
public:
- BeadPuzzle() : RenderActionRecord(7) {}
+ BeadPuzzle() : PuzzleRecord(7) {}
virtual ~BeadPuzzle() {}
void init() override;
@@ -87,11 +87,6 @@ protected:
SoundDescription _perfectSound;
FlagDescription _perfectFlag;
- SceneChangeDescription _defaultScene;
- SceneChangeDescription _solvedScene;
-
- Common::Rect _exitHotspot;
-
// Runtime state
enum SubState {
diff --git a/engines/nancy/action/puzzle/blockingpuzzle.h b/engines/nancy/action/puzzle/blockingpuzzle.h
index 298d1a7ad53..133c17eb648 100644
--- a/engines/nancy/action/puzzle/blockingpuzzle.h
+++ b/engines/nancy/action/puzzle/blockingpuzzle.h
@@ -24,7 +24,7 @@
#include "engines/nancy/commontypes.h"
#include "engines/nancy/movieplayer.h"
-#include "engines/nancy/action/actionrecord.h"
+#include "engines/nancy/action/puzzlerecord.h"
namespace Nancy {
namespace Action {
@@ -35,9 +35,9 @@ namespace Action {
// random from an idle-dominated sequence, with sound effects layered on top. Each
// fighter's health is a value-table entry (shown by a Meter puzzle, AR 179); a
// ValueTest scene change ends the fight when one is depleted.
-class BlockingPuzzle : public RenderActionRecord {
+class BlockingPuzzle : public PuzzleRecord {
public:
- BlockingPuzzle() : RenderActionRecord(7) {}
+ BlockingPuzzle() : PuzzleRecord(7) {}
virtual ~BlockingPuzzle();
void init() override;
diff --git a/engines/nancy/action/puzzle/blockspuzzle.cpp b/engines/nancy/action/puzzle/blockspuzzle.cpp
index 7db658c3c85..5349ea446dd 100644
--- a/engines/nancy/action/puzzle/blockspuzzle.cpp
+++ b/engines/nancy/action/puzzle/blockspuzzle.cpp
@@ -52,15 +52,15 @@ void BlocksPuzzle::readData(Common::SeekableReadStream &stream) {
// The scene change and flag applied once the board comes out solved. The frame is
// always the scene's first, and its sound carries over.
- _solveScene.sceneID = stream.readUint16LE(); // 0x6a
- _solveScene.continueSceneSound = kContinueSceneSound;
- _solveFlag.label = stream.readSint16LE(); // 0x6c
- _solveFlag.flag = stream.readByte(); // 0x6e
+ _solveScene._sceneChange.sceneID = stream.readUint16LE(); // 0x6a
+ _solveScene._sceneChange.continueSceneSound = kContinueSceneSound;
+ _solveScene._flag.label = stream.readSint16LE(); // 0x6c
+ _solveScene._flag.flag = stream.readByte(); // 0x6e
// A count-prefixed array of fixed 23-byte hotspot records:
// {rect, u16 cursorType, u16 sceneID, u16 frameID, byte}. The sample carries one - the
// "give up / exit" hotspot (leave the puzzle unsolved), with the exit cursor type.
- readExitHotspot(stream, _exitHotspot, _exitCursorType, _exitScene, _exitFlag);
+ readExitHotspot(stream);
// The block shapes, each a 13-byte descriptor of its row in the atlas image.
int16 numBlocks = stream.readSint16LE();
@@ -366,11 +366,9 @@ void BlocksPuzzle::execute() {
break;
case kActionTrigger:
if (_exitRequested) {
- NancySceneState.setEventFlag(_exitFlag);
- NancySceneState.changeScene(_exitScene);
+ _exitScene.execute();
} else {
- NancySceneState.setEventFlag(_solveFlag);
- NancySceneState.changeScene(_solveScene);
+ _solveScene.execute();
}
finishExecution();
@@ -453,9 +451,7 @@ void BlocksPuzzle::handleInput(NancyInput &input) {
}
}
- if (!_exitHotspot.isEmpty() &&
- NancySceneState.getViewport().convertViewportToScreen(_exitHotspot).contains(input.mousePos)) {
- setDataCursor(_exitCursorType, false);
+ if (hoverExitHotspot(input)) {
if (click) {
_exitRequested = true;
}
diff --git a/engines/nancy/action/puzzle/blockspuzzle.h b/engines/nancy/action/puzzle/blockspuzzle.h
index 668136f5a00..3de41606aa7 100644
--- a/engines/nancy/action/puzzle/blockspuzzle.h
+++ b/engines/nancy/action/puzzle/blockspuzzle.h
@@ -23,7 +23,7 @@
#define NANCY_ACTION_BLOCKSPUZZLE_H
#include "engines/nancy/commontypes.h"
-#include "engines/nancy/action/actionrecord.h"
+#include "engines/nancy/action/puzzlerecord.h"
#include "engines/nancy/misc/mousefollow.h"
namespace Nancy {
@@ -39,9 +39,9 @@ namespace Action {
// Turning happens in one of two places. Boards that declare a turntable area have blocks
// carried onto it and turned there; boards without one (the turntable rect is empty) turn
// the carried block in hand instead, on a right click.
-class BlocksPuzzle : public RenderActionRecord {
+class BlocksPuzzle : public PuzzleRecord {
public:
- BlocksPuzzle() : RenderActionRecord(7) {}
+ BlocksPuzzle() : PuzzleRecord(7) {}
virtual ~BlocksPuzzle() {}
void init() override;
@@ -115,18 +115,10 @@ protected:
Common::Rect _overlayDest; // 0x3a
Common::Rect _turntableDest; // 0x4a - empty when the board has no turntable
Common::Rect _turntableHotspot; // 0x5a - click to turn the block on the turntable
- SceneChangeDescription _solveScene; // 0x6a
- FlagDescription _solveFlag; // 0x6c
Common::Array<Block> _blocks;
Common::Array<Cell> _cells;
- // The clickable "give up / exit" hotspot (the base-class hotspot record).
- Common::Rect _exitHotspot;
- uint16 _exitCursorType = 0;
- SceneChangeDescription _exitScene;
- FlagDescription _exitFlag; // set on give-up
-
RandomSoundBlock _sounds[kNumSounds]; // turn / handle / success
// -- Runtime state --
diff --git a/engines/nancy/action/puzzle/boardgamepuzzle.cpp b/engines/nancy/action/puzzle/boardgamepuzzle.cpp
index 485b317ea91..493fa52db6e 100644
--- a/engines/nancy/action/puzzle/boardgamepuzzle.cpp
+++ b/engines/nancy/action/puzzle/boardgamepuzzle.cpp
@@ -58,7 +58,7 @@ void BoardGamePuzzle::readData(Common::SeekableReadStream &stream) {
_moves[i].jumpFrameEnd = stream.readSint16LE();
}
- _winScene.readData(stream); // 0x2e2, SceneChangeWithFlag
+ _solveScene.readData(stream); // 0x2e2, SceneChangeWithFlag
_loseScene.readData(stream); // 0x2fb, SceneChangeWithFlag
// Six random-sound blocks (button/click/clank/slide/key/beep).
@@ -240,7 +240,7 @@ void BoardGamePuzzle::execute() {
break;
case kActionTrigger:
if (_solved) {
- _winScene.execute();
+ _solveScene.execute();
} else if (_lost) {
_loseScene.execute();
}
diff --git a/engines/nancy/action/puzzle/boardgamepuzzle.h b/engines/nancy/action/puzzle/boardgamepuzzle.h
index c2a586829c8..8903d76b247 100644
--- a/engines/nancy/action/puzzle/boardgamepuzzle.h
+++ b/engines/nancy/action/puzzle/boardgamepuzzle.h
@@ -22,7 +22,7 @@
#ifndef NANCY_ACTION_BOARDGAMEPUZZLE_H
#define NANCY_ACTION_BOARDGAMEPUZZLE_H
-#include "engines/nancy/action/actionrecord.h"
+#include "engines/nancy/action/puzzlerecord.h"
#include "engines/nancy/commontypes.h"
#include "engines/nancy/movieplayer.h"
@@ -32,9 +32,9 @@ namespace Action {
// Movie-driven board game introduced in Nancy12 (AR 164) - the "Mother Clock"
// puzzle. The board states are pre-rendered frames of a Bink movie the game
// navigates between as moves are made.
-class BoardGamePuzzle : public RenderActionRecord {
+class BoardGamePuzzle : public PuzzleRecord {
public:
- BoardGamePuzzle() : RenderActionRecord(7) {}
+ BoardGamePuzzle() : PuzzleRecord(7) {}
virtual ~BoardGamePuzzle() {}
void init() override;
@@ -78,7 +78,6 @@ protected:
int16 _winTarget = 0; // land here exactly to win; overshoot loses
Common::Array<MoveRecord> _moves; // 12 scripted turn records (buf+0x26a)
- SceneChangeWithFlag _winScene; // buf+0x2e2
SceneChangeWithFlag _loseScene; // buf+0x2fb (also the exit/quit target)
RandomSoundBlock _sounds[kNumSounds]; // button / click / clank / slide / key / beep
diff --git a/engines/nancy/action/puzzle/bombpuzzle.cpp b/engines/nancy/action/puzzle/bombpuzzle.cpp
index e644e7f39d6..bfd598570c3 100644
--- a/engines/nancy/action/puzzle/bombpuzzle.cpp
+++ b/engines/nancy/action/puzzle/bombpuzzle.cpp
@@ -45,7 +45,7 @@ void BombPuzzle::init() {
setTransparent(true);
g_nancy->_resource->loadImage(_imageName, _image);
- RenderActionRecord::init();
+ PuzzleRecord::init();
}
void BombPuzzle::readData(Common::SeekableReadStream &stream) {
@@ -68,7 +68,7 @@ void BombPuzzle::readData(Common::SeekableReadStream &stream) {
_noToolSound.readNormal(stream);
_toolID = stream.readUint16LE();
- _solveSceneChange.readData(stream);
+ _solveScene.readData(stream);
stream.skip(2);
_solveSound.readNormal(stream);
@@ -233,7 +233,7 @@ void BombPuzzle::execute() {
}
g_nancy->_sound->stopSound(_solveSound);
- _solveSceneChange.execute();
+ _solveScene.execute();
}
g_nancy->_sound->stopSound(_snipSound);
diff --git a/engines/nancy/action/puzzle/bombpuzzle.h b/engines/nancy/action/puzzle/bombpuzzle.h
index 7ddd5e7c314..433f00381ac 100644
--- a/engines/nancy/action/puzzle/bombpuzzle.h
+++ b/engines/nancy/action/puzzle/bombpuzzle.h
@@ -22,14 +22,14 @@
#ifndef NANCY_ACTION_BOMBPUZZLE_H
#define NANCY_ACTION_BOMBPUZZLE_H
-#include "engines/nancy/action/actionrecord.h"
+#include "engines/nancy/action/puzzlerecord.h"
namespace Nancy {
namespace Action {
-class BombPuzzle : public RenderActionRecord {
+class BombPuzzle : public PuzzleRecord {
public:
- BombPuzzle() : RenderActionRecord(7) {}
+ BombPuzzle() : PuzzleRecord(7) {}
virtual ~BombPuzzle() {}
void init() override;
@@ -56,7 +56,6 @@ protected:
SoundDescription _snipSound;
SoundDescription _noToolSound;
uint16 _toolID = 0;
- SceneChangeWithFlag _solveSceneChange;
SoundDescription _solveSound;
SceneChangeWithFlag _failSceneChange;
SoundDescription _failSound;
diff --git a/engines/nancy/action/puzzle/buildpuzzle.cpp b/engines/nancy/action/puzzle/buildpuzzle.cpp
index c55d82fee57..2e053c21eea 100644
--- a/engines/nancy/action/puzzle/buildpuzzle.cpp
+++ b/engines/nancy/action/puzzle/buildpuzzle.cpp
@@ -159,11 +159,11 @@ void BuildPuzzle::readData(Common::SeekableReadStream &stream) {
_wrongIngredientFlag = stream.readSint16LE();
_solvedFlag = stream.readSint16LE();
- _solveScene.sceneID = stream.readUint16LE();
- _solveScene.frameID = stream.readUint16LE();
- _solveScene.continueSceneSound = kContinueSceneSound;
- _solveFlag.label = stream.readSint16LE();
- _solveFlag.flag = stream.readByte();
+ _solveScene._sceneChange.sceneID = stream.readUint16LE();
+ _solveScene._sceneChange.frameID = stream.readUint16LE();
+ _solveScene._sceneChange.continueSceneSound = kContinueSceneSound;
+ _solveScene._flag.label = stream.readSint16LE();
+ _solveScene._flag.flag = stream.readByte();
SoundDescription unused;
readSoundBlock(stream, unused);
@@ -735,7 +735,7 @@ void BuildPuzzle::pressButton(HeldButton button) {
void BuildPuzzle::takeOutcome() {
if (checkSolved()) {
- if (_solveScene.sceneID != kNoScene) {
+ if (_solveScene._sceneChange.sceneID != kNoScene) {
_isSolved = true;
_state = kActionTrigger;
}
@@ -951,8 +951,7 @@ void BuildPuzzle::execute() {
break;
case kActionTrigger:
if (_isSolved) {
- NancySceneState.setEventFlag(_solveFlag);
- NancySceneState.changeScene(_solveScene);
+ _solveScene.execute();
} else if (_isFailed) {
NancySceneState.setEventFlag(_failFlag);
NancySceneState.changeScene(_failScene);
diff --git a/engines/nancy/action/puzzle/buildpuzzle.h b/engines/nancy/action/puzzle/buildpuzzle.h
index c237dea73e8..9b40a52f79f 100644
--- a/engines/nancy/action/puzzle/buildpuzzle.h
+++ b/engines/nancy/action/puzzle/buildpuzzle.h
@@ -22,7 +22,7 @@
#ifndef NANCY_ACTION_BUILDPUZZLE_H
#define NANCY_ACTION_BUILDPUZZLE_H
-#include "engines/nancy/action/actionrecord.h"
+#include "engines/nancy/action/puzzlerecord.h"
#include "engines/nancy/renderobject.h"
namespace Nancy {
@@ -35,9 +35,9 @@ namespace Action {
// clothes design). Pieces are dragged into zones, and a zone is satisfied once
// it holds the quantities its ingredient list asks for; a piece is placed by
// being assigned a zone index rather than by matching a rect.
-class BuildPuzzle : public RenderActionRecord {
+class BuildPuzzle : public PuzzleRecord {
public:
- BuildPuzzle() : RenderActionRecord(7), _doneOverlay(0), _counter(97), _buttonPress(98), _cursorItem(99) {}
+ BuildPuzzle() : PuzzleRecord(7), _doneOverlay(0), _counter(97), _buttonPress(98), _cursorItem(99) {}
virtual ~BuildPuzzle() {}
void init() override;
@@ -189,9 +189,6 @@ protected:
byte _usePlacedGate = 0;
uint16 _stateItemID = 255; // shared item state tracking the placed count
- SceneChangeDescription _solveScene;
- FlagDescription _solveFlag;
-
// Used instead of _solveScene when the player leaves the zones unfinished.
SceneChangeDescription _failScene;
FlagDescription _failFlag;
diff --git a/engines/nancy/action/puzzle/bulpuzzle.cpp b/engines/nancy/action/puzzle/bulpuzzle.cpp
index ca5397d31e5..3e16e458c90 100644
--- a/engines/nancy/action/puzzle/bulpuzzle.cpp
+++ b/engines/nancy/action/puzzle/bulpuzzle.cpp
@@ -325,7 +325,7 @@ void BulPuzzle::readData(Common::SeekableReadStream &stream) {
_solveSoundDelay = stream.readUint16LE();
_solveSound.readNormal(stream);
- _exitScene.readData(stream);
+ _exitScene.readData(stream); // when losing (Nancy 11 shares the win scene, set apart by the flag)
_loseSoundDelay = stream.readUint16LE();
_loseSound.readNormal(stream);
}
@@ -491,9 +491,7 @@ void BulPuzzle::doAiTurn() {
}
void BulPuzzle::handleInput(NancyInput &input) {
- if (NancySceneState.getViewport().convertViewportToScreen(_exitHotspot).contains(input.mousePos)) {
- g_nancy->_cursor->setCursorType(g_nancy->_cursor->_puzzleExitCursor);
-
+ if (hoverExitHotspot(input)) {
if (input.input & NancyInput::kLeftMouseButtonUp) {
_state = kActionTrigger;
_nextMoveTime = 0;
diff --git a/engines/nancy/action/puzzle/bulpuzzle.h b/engines/nancy/action/puzzle/bulpuzzle.h
index 4cb9b9d81b2..0428f74817c 100644
--- a/engines/nancy/action/puzzle/bulpuzzle.h
+++ b/engines/nancy/action/puzzle/bulpuzzle.h
@@ -22,15 +22,15 @@
#ifndef NANCY_ACTION_BULPUZZLE_H
#define NANCY_ACTION_BULPUZZLE_H
-#include "engines/nancy/action/actionrecord.h"
+#include "engines/nancy/action/puzzlerecord.h"
namespace Nancy {
namespace Action {
// A puzzle based around a simplified version of the Mayan game Bul
-class BulPuzzle : public RenderActionRecord {
+class BulPuzzle : public PuzzleRecord {
public:
- BulPuzzle() : RenderActionRecord(7) {}
+ BulPuzzle() : PuzzleRecord(7) {}
virtual ~BulPuzzle() {}
void init() override;
@@ -110,15 +110,12 @@ protected:
SoundDescription _passSound;
SoundDescription _resetSound;
- SceneChangeWithFlag _solveScene;
uint16 _solveSoundDelay = 0;
SoundDescription _solveSound;
- SceneChangeWithFlag _exitScene; // when losing (Nancy 11 shares the win scene, set apart by the flag)
uint16 _loseSoundDelay = 0;
SoundDescription _loseSound;
SceneChangeWithFlag _giveUpScene; // nancy11: separate scene reached by giving up via the exit hotspot
- Common::Rect _exitHotspot;
// Nancy 11 voice clips: two players, seven tables each (entry counts 1,1,4,4,4,4,4).
// Table 0 = opening line, 2 = turn line, 5 = end-of-game line.
diff --git a/engines/nancy/action/puzzle/cardgamepuzzle.cpp b/engines/nancy/action/puzzle/cardgamepuzzle.cpp
index 3dfb7cbe745..77d4e7d0fd3 100644
--- a/engines/nancy/action/puzzle/cardgamepuzzle.cpp
+++ b/engines/nancy/action/puzzle/cardgamepuzzle.cpp
@@ -125,16 +125,16 @@ void CardGamePuzzle::readData(Common::SeekableReadStream &stream) {
_winSceneStartPlayer = stream.readUint16LE(); // 0x1304
_winSceneStartEnemy = stream.readUint16LE(); // 0x1306
- _winScene.frameID = stream.readUint16LE(); // 0x1308
- _winScene.verticalOffset = stream.readUint16LE(); // 0x130a
- _winScene.continueSceneSound = stream.readUint16LE();// 0x130c
+ _solveScene._sceneChange.frameID = stream.readUint16LE(); // 0x1308
+ _solveScene._sceneChange.verticalOffset = stream.readUint16LE(); // 0x130a
+ _solveScene._sceneChange.continueSceneSound = stream.readUint16LE();// 0x130c
stream.skip(0x131c - 0x130e); // listener vector + frame id
_winFlagPlayer = stream.readSint16LE(); // 0x131c
_winFlagEnemy = stream.readSint16LE(); // 0x131e
- _exitScene = stream.readUint16LE(); // 0x1320
- _exitSceneChange.frameID = stream.readUint16LE(); // 0x1322
- _exitSceneChange.verticalOffset = stream.readUint16LE(); // 0x1324
- _exitSceneChange.continueSceneSound = stream.readUint16LE();// 0x1326
+ _exitScene._sceneChange.sceneID = stream.readUint16LE(); // 0x1320
+ _exitScene._sceneChange.frameID = stream.readUint16LE(); // 0x1322
+ _exitScene._sceneChange.verticalOffset = stream.readUint16LE(); // 0x1324
+ _exitScene._sceneChange.continueSceneSound = stream.readUint16LE(); // 0x1326
stream.skip(0x1336 - 0x1328); // listener vector + flag
readRect(stream, _exitHotspot); // 0x1336 (ends at 0x1346)
@@ -567,10 +567,9 @@ void CardGamePuzzle::execute() {
SceneChangeDescription sceneChange;
if (_gaveUp) {
- sceneChange = _exitSceneChange;
- sceneChange.sceneID = _exitScene;
+ sceneChange = _exitScene._sceneChange;
} else {
- sceneChange = _winScene;
+ sceneChange = _solveScene._sceneChange;
const int playerScore = _board[1].score;
const int aiScore = _board[0].score;
@@ -644,8 +643,7 @@ void CardGamePuzzle::handleInput(NancyInput &input) {
}
// Exit hotspot is always available; leaving this way is "giving up" (goes to the exit scene)
- if (NancySceneState.getViewport().convertViewportToScreen(_exitHotspot).contains(input.mousePos)) {
- g_nancy->_cursor->setCursorType(g_nancy->_cursor->_puzzleExitCursor);
+ if (hoverExitHotspot(input)) {
if (input.input & NancyInput::kLeftMouseButtonUp) {
_gaveUp = true;
_state = kActionTrigger;
diff --git a/engines/nancy/action/puzzle/cardgamepuzzle.h b/engines/nancy/action/puzzle/cardgamepuzzle.h
index 1bda848e24d..232d4ccc4c7 100644
--- a/engines/nancy/action/puzzle/cardgamepuzzle.h
+++ b/engines/nancy/action/puzzle/cardgamepuzzle.h
@@ -22,7 +22,7 @@
#ifndef NANCY_ACTION_CARDGAMEPUZZLE_H
#define NANCY_ACTION_CARDGAMEPUZZLE_H
-#include "engines/nancy/action/actionrecord.h"
+#include "engines/nancy/action/puzzlerecord.h"
namespace Nancy {
namespace Action {
@@ -30,9 +30,9 @@ namespace Action {
// A "Go fish!" card game, new in Nancy 11 (Curse of Blackmoor Manor, AR 246).
// There are two variants, one with the cards placed in a grid vs a human NPC, and
// one with the cards placed in columns vs an automaton.
-class CardGamePuzzle : public RenderActionRecord {
+class CardGamePuzzle : public PuzzleRecord {
public:
- CardGamePuzzle() : RenderActionRecord(7) {}
+ CardGamePuzzle() : PuzzleRecord(7) {}
virtual ~CardGamePuzzle() {}
void init() override;
@@ -102,7 +102,6 @@ protected:
Common::Rect _cardDisplayDest[2]; // data+0x633
Common::Array<Common::Rect> _columnButtons; // data+0x653, one per column
Common::Array<Common::Rect> _faceDownSrc; // data+0x723, 3 rows
- Common::Rect _exitHotspot; // data+0x1336
// Animation timing (data+0x62b)
uint16 _moveAnimSteps = 0;
@@ -118,14 +117,11 @@ protected:
Common::Rect _deliverDest[2]; // where the hand sprite is drawn, by side
// Outcome scenes (data+0x1304 / 0x1320). The win block has two scene ids that share one set of
- // transition params (frame/scroll/sound), held in _winScene; the id is chosen by the result.
+ // transition params (frame/scroll/sound), held in _solveScene; the id is chosen by the result.
uint16 _winSceneStartPlayer = 0; // data+0x1304
uint16 _winSceneStartEnemy = 0; // data+0x1306
- SceneChangeDescription _winScene;
int16 _winFlagPlayer = -1; // data+0x131c
int16 _winFlagEnemy = -1; // data+0x131e
- uint16 _exitScene = 0; // data+0x1320
- SceneChangeDescription _exitSceneChange;
bool _gaveUp = false; // left via the exit hotspot rather than playing out
// Voiced lines / SFX (all on the card-game channel). Read selectively from the 0xba3..0x1304 block.
diff --git a/engines/nancy/action/puzzle/collisionpuzzle.cpp b/engines/nancy/action/puzzle/collisionpuzzle.cpp
index 053e9b8ba95..369a3af89ca 100644
--- a/engines/nancy/action/puzzle/collisionpuzzle.cpp
+++ b/engines/nancy/action/puzzle/collisionpuzzle.cpp
@@ -131,7 +131,7 @@ void CollisionPuzzle::registerGraphics() {
_pieces[i].registerGraphics();
}
- RenderActionRecord::registerGraphics();
+ PuzzleRecord::registerGraphics();
}
void CollisionPuzzle::updateGraphics() {
@@ -654,9 +654,7 @@ void CollisionPuzzle::handleInput(NancyInput &input) {
return;
}
} else {
- if (NancySceneState.getViewport().convertViewportToScreen(_exitHotspot).contains(input.mousePos)) {
- g_nancy->_cursor->setCursorType(g_nancy->_cursor->_puzzleExitCursor);
-
+ if (hoverExitHotspot(input)) {
if (input.input & NancyInput::kLeftMouseButtonUp) {
_state = kActionTrigger;
}
diff --git a/engines/nancy/action/puzzle/collisionpuzzle.h b/engines/nancy/action/puzzle/collisionpuzzle.h
index c92068b7188..656deb382ca 100644
--- a/engines/nancy/action/puzzle/collisionpuzzle.h
+++ b/engines/nancy/action/puzzle/collisionpuzzle.h
@@ -22,7 +22,7 @@
#ifndef NANCY_ACTION_COLLISIONPUZZLE_H
#define NANCY_ACTION_COLLISIONPUZZLE_H
-#include "engines/nancy/action/actionrecord.h"
+#include "engines/nancy/action/puzzlerecord.h"
namespace Nancy {
namespace Action {
@@ -35,10 +35,10 @@ namespace Action {
// - TileMovePuzzle: Many differently-sized tiles, one of which must reach the exit.
// Rectangular tiles can only move in the directions parallel to their longer sides.
// Exit is outside of the tile grid.
-class CollisionPuzzle : public RenderActionRecord {
+class CollisionPuzzle : public PuzzleRecord {
public:
enum PuzzleType { kCollision, kTileMove };
- CollisionPuzzle(PuzzleType type) : RenderActionRecord(7), _puzzleType(type) {}
+ CollisionPuzzle(PuzzleType type) : PuzzleRecord(7), _puzzleType(type) {}
virtual ~CollisionPuzzle() {}
void init() override;
@@ -111,13 +111,9 @@ protected:
SoundDescription _wallHitSound;
SoundDescription _exitButtonSound;
- SceneChangeWithFlag _solveScene;
uint16 _solveSoundDelay = 0;
SoundDescription _solveSound;
- SceneChangeWithFlag _exitScene;
- Common::Rect _exitHotspot;
-
Graphics::ManagedSurface _image;
Common::Array<Piece> _pieces;
diff --git a/engines/nancy/action/puzzle/cubepuzzle.cpp b/engines/nancy/action/puzzle/cubepuzzle.cpp
index c3f2d7ad488..97923cd7005 100644
--- a/engines/nancy/action/puzzle/cubepuzzle.cpp
+++ b/engines/nancy/action/puzzle/cubepuzzle.cpp
@@ -55,7 +55,7 @@ void CubePuzzle::init() {
void CubePuzzle::registerGraphics() {
_curPiece.registerGraphics();
- RenderActionRecord::registerGraphics();
+ PuzzleRecord::registerGraphics();
}
void CubePuzzle::readData(Common::SeekableReadStream &stream) {
@@ -149,9 +149,7 @@ void CubePuzzle::handleInput(NancyInput &input) {
return;
}
- if (_pickedUpPiece == -1 && NancySceneState.getViewport().convertViewportToScreen(_exitHotspot).contains(input.mousePos)) {
- g_nancy->_cursor->setCursorType(g_nancy->_cursor->_puzzleExitCursor);
-
+ if (_pickedUpPiece == -1 && hoverExitHotspot(input)) {
if (input.input & NancyInput::kLeftMouseButtonUp) {
_state = kActionTrigger;
_completed = false;
diff --git a/engines/nancy/action/puzzle/cubepuzzle.h b/engines/nancy/action/puzzle/cubepuzzle.h
index 587bc7b381d..644a6762eee 100644
--- a/engines/nancy/action/puzzle/cubepuzzle.h
+++ b/engines/nancy/action/puzzle/cubepuzzle.h
@@ -22,7 +22,7 @@
#ifndef NANCY_ACTION_CUBEPUZZLE_H
#define NANCY_ACTION_CUBEPUZZLE_H
-#include "engines/nancy/action/actionrecord.h"
+#include "engines/nancy/action/puzzlerecord.h"
#include "engines/nancy/misc/mousefollow.h"
namespace Nancy {
@@ -31,9 +31,9 @@ namespace Action {
// Similar idea to AssemblyPuzzle; the player is provided with broken pieces of
// a cube, and has to assemble it back together. However, the data is completely
// different to AssemblyPuzzle's, so we need separate implementations.
-class CubePuzzle : public RenderActionRecord {
+class CubePuzzle : public PuzzleRecord {
public:
- CubePuzzle() : RenderActionRecord(7) {}
+ CubePuzzle() : PuzzleRecord(7) {}
virtual ~CubePuzzle() {}
void init() override;
@@ -80,12 +80,8 @@ protected:
// Multiple solve scenes, one for each cube orientation
Common::Array<uint> _solveSceneIDs;
- SceneChangeWithFlag _solveScene;
SoundDescription _solveSound;
- SceneChangeWithFlag _exitScene;
- Common::Rect _exitHotspot;
-
Graphics::ManagedSurface _image;
Misc::MouseFollowObject _curPiece;
diff --git a/engines/nancy/action/puzzle/cuttingpuzzle.cpp b/engines/nancy/action/puzzle/cuttingpuzzle.cpp
index efb199e70f7..24acb7d9ebc 100644
--- a/engines/nancy/action/puzzle/cuttingpuzzle.cpp
+++ b/engines/nancy/action/puzzle/cuttingpuzzle.cpp
@@ -72,7 +72,7 @@ void CuttingPuzzle::readData(Common::SeekableReadStream &stream) {
_depthSound.readNormal(stream); // +0x46f (49 bytes)
_cutSound.readNormal(stream); // +0x4a0 (49 bytes)
- _puzzleSolvedScene.readData(stream); // +0x4d1 (25 bytes)
+ _solveScene.readData(stream); // +0x4d1 (25 bytes)
_doneSoundDelaySecs = stream.readUint16LE(); // +0x4ea
_doneSound.readNormal(stream); // +0x4ec (49 bytes)
@@ -84,7 +84,7 @@ void CuttingPuzzle::readData(Common::SeekableReadStream &stream) {
_missingGogglesScene.readData(stream); // +0x520 (20 bytes)
stream.skip(2); // +0x534 skip
- _cancelScene.readData(stream); // +0x536 (25 bytes)
+ _exitScene.readData(stream); // +0x536 (25 bytes)
readRect(stream, _exitHotspot);
}
@@ -323,10 +323,10 @@ void CuttingPuzzle::execute() {
}
}
if (anyGroove)
- NancySceneState.setEventFlag(_cancelScene._flag);
- NancySceneState.changeScene(_cancelScene._sceneChange);
+ NancySceneState.setEventFlag(_exitScene._flag);
+ NancySceneState.changeScene(_exitScene._sceneChange);
} else if (_solved) {
- _puzzleSolvedScene.execute();
+ _solveScene.execute();
} else if (_gogglesMissing) {
NancySceneState.changeScene(_missingGogglesScene);
}
@@ -368,7 +368,7 @@ void CuttingPuzzle::handleInput(NancyInput &input) {
if (_latheRunning)
return;
- if (!_exitHotspot.isEmpty() && _exitHotspot.contains(localMouse)) {
+ if (isExitHotspotHovered(input)) {
g_nancy->_cursor->setCursorType(CursorManager::kMoveBackward);
if (input.input & NancyInput::kLeftMouseButtonUp) {
_cancelled = true;
diff --git a/engines/nancy/action/puzzle/cuttingpuzzle.h b/engines/nancy/action/puzzle/cuttingpuzzle.h
index b56f43a7733..520cc7b96ed 100644
--- a/engines/nancy/action/puzzle/cuttingpuzzle.h
+++ b/engines/nancy/action/puzzle/cuttingpuzzle.h
@@ -22,7 +22,7 @@
#ifndef NANCY_ACTION_CUTTINGPUZZLE_H
#define NANCY_ACTION_CUTTINGPUZZLE_H
-#include "engines/nancy/action/actionrecord.h"
+#include "engines/nancy/action/puzzlerecord.h"
#include "engines/nancy/commontypes.h"
namespace Nancy {
@@ -41,9 +41,9 @@ namespace Action {
//
// The puzzle is solved when grooveDepths[i] == correctGrooves[i] for all i.
//
-class CuttingPuzzle : public RenderActionRecord {
+class CuttingPuzzle : public PuzzleRecord {
public:
- CuttingPuzzle() : RenderActionRecord(7) {}
+ CuttingPuzzle() : PuzzleRecord(7) {}
virtual ~CuttingPuzzle() {}
void init() override;
@@ -105,7 +105,6 @@ protected:
SoundDescription _depthSound; // data+0x46f depth adjust sound
SoundDescription _cutSound; // data+0x4a0 groove-cutting sound
- SceneChangeWithFlag _puzzleSolvedScene; // data+0x4d1 (25 bytes)
uint16 _doneSoundDelaySecs = 0; // data+0x4ea wait before playing done sound (seconds)
SoundDescription _doneSound; // data+0x4ec
@@ -113,8 +112,6 @@ protected:
int16 _itemID = -1; // data+0x51e
SceneChangeDescription _missingGogglesScene; // data+0x520 (20 bytes + 2-byte skip = 22 bytes total)
- SceneChangeWithFlag _cancelScene; // data+0x536 (25 bytes)
- Common::Rect _exitHotspot;
// ---- runtime state ----
diff --git a/engines/nancy/action/puzzle/decoderpuzzle.cpp b/engines/nancy/action/puzzle/decoderpuzzle.cpp
index 00e159c9e18..9e0f1440c1a 100644
--- a/engines/nancy/action/puzzle/decoderpuzzle.cpp
+++ b/engines/nancy/action/puzzle/decoderpuzzle.cpp
@@ -122,16 +122,16 @@ void DecoderPuzzle::readData(Common::SeekableReadStream &stream) {
_resetSound.readData(stream); // 0x12f
- _solveScene.sceneID = stream.readUint16LE(); // 0x1db
- _solveScene.frameID = stream.readUint16LE();
- _solveScene.continueSceneSound = kContinueSceneSound;
- _solveFlag.label = stream.readSint16LE();
- _solveFlag.flag = stream.readByte();
+ _solveScene._sceneChange.sceneID = stream.readUint16LE(); // 0x1db
+ _solveScene._sceneChange.frameID = stream.readUint16LE();
+ _solveScene._sceneChange.continueSceneSound = kContinueSceneSound;
+ _solveScene._flag.label = stream.readSint16LE();
+ _solveScene._flag.flag = stream.readByte();
_solveSound.readData(stream); // 0x185
- readExitHotspot(stream, _exitHotspot, _exitCursorType, _exitScene, _exitFlag);
- _exitScene.continueSceneSound = kContinueSceneSound;
+ readExitHotspot(stream);
+ _exitScene._sceneChange.continueSceneSound = kContinueSceneSound;
}
void DecoderPuzzle::init() {
@@ -171,7 +171,7 @@ void DecoderPuzzle::init() {
void DecoderPuzzle::onPause(bool paused) {
g_nancy->_input->setVKEnabled(!paused);
- RenderActionRecord::onPause(paused);
+ PuzzleRecord::onPause(paused);
}
void DecoderPuzzle::playSoundBlock(const RandomSoundBlock &block) {
@@ -347,11 +347,9 @@ void DecoderPuzzle::execute() {
}
if (_exitRequested) {
- NancySceneState.setEventFlag(_exitFlag);
- NancySceneState.changeScene(_exitScene);
+ _exitScene.execute();
} else {
- NancySceneState.setEventFlag(_solveFlag);
- NancySceneState.changeScene(_solveScene);
+ _solveScene.execute();
}
finishExecution();
@@ -364,10 +362,7 @@ void DecoderPuzzle::handleInput(NancyInput &input) {
return;
}
- if (!_exitHotspot.isEmpty() &&
- NancySceneState.getViewport().convertViewportToScreen(_exitHotspot).contains(input.mousePos)) {
- g_nancy->_cursor->setCursorType((CursorManager::CursorType)_exitCursorType, true);
-
+ if (hoverExitHotspot(input)) {
if (input.input & NancyInput::kLeftMouseButtonUp) {
_exitRequested = true;
_state = kActionTrigger;
diff --git a/engines/nancy/action/puzzle/decoderpuzzle.h b/engines/nancy/action/puzzle/decoderpuzzle.h
index 87cf962e7b5..28d0299e448 100644
--- a/engines/nancy/action/puzzle/decoderpuzzle.h
+++ b/engines/nancy/action/puzzle/decoderpuzzle.h
@@ -24,7 +24,7 @@
#include "engines/nancy/commontypes.h"
#include "engines/nancy/movieplayer.h"
-#include "engines/nancy/action/actionrecord.h"
+#include "engines/nancy/action/puzzlerecord.h"
namespace Nancy {
@@ -42,9 +42,9 @@ namespace Action {
// Each scene using it holds two records, one with the substitution table and one
// with none (every keystroke emits a random letter); they share the decoded line
// through the puzzle data.
-class DecoderPuzzle : public RenderActionRecord {
+class DecoderPuzzle : public PuzzleRecord {
public:
- DecoderPuzzle() : RenderActionRecord(7) {}
+ DecoderPuzzle() : PuzzleRecord(7) {}
virtual ~DecoderPuzzle() {}
void init() override;
@@ -96,16 +96,8 @@ protected:
Common::Rect _resetMovieRect; // 0x11f
RandomSoundBlock _resetSound; // 0x12f, plays while it runs
- SceneChangeDescription _solveScene; // 0x1db
- FlagDescription _solveFlag;
RandomSoundBlock _solveSound; // 0x185, plays before the scene change
- // Give-up hotspot, from the count-prefixed 23-byte trailer
- Common::Rect _exitHotspot;
- uint16 _exitCursorType = 0;
- SceneChangeDescription _exitScene;
- FlagDescription _exitFlag;
-
// -- Runtime state --
MoviePlayer _resetMovie;
diff --git a/engines/nancy/action/puzzle/dotconnectpuzzle.cpp b/engines/nancy/action/puzzle/dotconnectpuzzle.cpp
index 9cda9c2a8bd..aad7ed91eb3 100644
--- a/engines/nancy/action/puzzle/dotconnectpuzzle.cpp
+++ b/engines/nancy/action/puzzle/dotconnectpuzzle.cpp
@@ -57,17 +57,17 @@ void DotConnectPuzzle::readData(Common::SeekableReadStream &stream) {
_tooManyLinesSound.readNormal(stream);
_allCoveredSound.readNormal(stream);
- _winScene.readData(stream);
+ _solveScene._sceneChange.readData(stream);
stream.skip(2);
- _winFlag.label = stream.readSint16LE();
- _winFlag.flag = stream.readByte();
+ _solveScene._flag.label = stream.readSint16LE();
+ _solveScene._flag.flag = stream.readByte();
_winDelaySec = stream.readUint16LE();
_winSound.readNormal(stream);
- _exitScene.readData(stream);
+ _exitScene._sceneChange.readData(stream);
stream.skip(2);
- _exitFlag.label = stream.readSint16LE();
- _exitFlag.flag = stream.readByte();
+ _exitScene._flag.label = stream.readSint16LE();
+ _exitScene._flag.flag = stream.readByte();
readRect(stream, _exitHotspot);
}
@@ -151,11 +151,9 @@ void DotConnectPuzzle::execute() {
g_nancy->_sound->stopSound(_allCoveredSound);
g_nancy->_sound->stopSound(_winSound);
if (_subState == kExitToWin) {
- NancySceneState.setEventFlag(_winFlag);
- NancySceneState.changeScene(_winScene);
+ _solveScene.execute();
} else {
- NancySceneState.setEventFlag(_exitFlag);
- NancySceneState.changeScene(_exitScene);
+ _exitScene.execute();
}
finishExecution();
break;
@@ -169,8 +167,7 @@ void DotConnectPuzzle::handleInput(NancyInput &input) {
Common::Rect vpScreen = NancySceneState.getViewport().getScreenPosition();
Common::Point mouseVP = input.mousePos - Common::Point(vpScreen.left, vpScreen.top);
- if (!_exitHotspot.isEmpty() && _exitHotspot.contains(mouseVP)) {
- g_nancy->_cursor->setCursorType(g_nancy->_cursor->_puzzleExitCursor);
+ if (hoverExitHotspot(input)) {
if (input.input & NancyInput::kLeftMouseButtonUp) {
_subState = kExitToCancel;
}
diff --git a/engines/nancy/action/puzzle/dotconnectpuzzle.h b/engines/nancy/action/puzzle/dotconnectpuzzle.h
index e1d538e4aff..4032492c184 100644
--- a/engines/nancy/action/puzzle/dotconnectpuzzle.h
+++ b/engines/nancy/action/puzzle/dotconnectpuzzle.h
@@ -22,7 +22,7 @@
#ifndef NANCY_ACTION_DOTCONNECTPUZZLE_H
#define NANCY_ACTION_DOTCONNECTPUZZLE_H
-#include "engines/nancy/action/actionrecord.h"
+#include "engines/nancy/action/puzzlerecord.h"
#include "engines/nancy/commontypes.h"
namespace Nancy {
@@ -32,9 +32,9 @@ namespace Action {
// re-clicking the current tip pops the last line. Wins once kNumEdges lines
// have been drawn that match the solution either forward or fully reversed.
// Called from scene 6243 in Nancy10.
-class DotConnectPuzzle : public RenderActionRecord {
+class DotConnectPuzzle : public PuzzleRecord {
public:
- DotConnectPuzzle() : RenderActionRecord(7) {}
+ DotConnectPuzzle() : PuzzleRecord(7) {}
virtual ~DotConnectPuzzle() {}
void init() override;
@@ -76,16 +76,9 @@ protected:
SoundDescription _tooManyLinesSound;
SoundDescription _allCoveredSound;
- SceneChangeDescription _winScene;
- FlagDescription _winFlag;
uint16 _winDelaySec = 0;
SoundDescription _winSound;
- SceneChangeDescription _exitScene;
- FlagDescription _exitFlag;
-
- Common::Rect _exitHotspot;
-
// Runtime state
enum SubState {
diff --git a/engines/nancy/action/puzzle/drivingpuzzle.cpp b/engines/nancy/action/puzzle/drivingpuzzle.cpp
index 0716f7ca986..b6504b54a48 100644
--- a/engines/nancy/action/puzzle/drivingpuzzle.cpp
+++ b/engines/nancy/action/puzzle/drivingpuzzle.cpp
@@ -228,23 +228,23 @@ void DrivingPuzzle::playSoundBlock(const RandomSoundBlock &block) {
}
void DrivingPuzzle::armExit(const DestinationZone &dest) {
- _exitScene = dest.scene;
+ _exitScene._sceneChange = dest.scene;
+ _exitScene._flag.label = dest.eventFlag;
+ _exitScene._flag.flag = dest.eventFlagValue ? g_nancy->_true : g_nancy->_false;
_exitHasFade = dest.hasFade;
_exitFadeType = dest.fadeType;
_exitFadeTotalTime = dest.fadeTotalTime;
_exitFadeToBlackTime = dest.fadeToBlackTime;
_exitFadeRect = dest.fadeRect;
- _exitFlag = dest.eventFlag;
- _exitFlagValue = dest.eventFlagValue;
_state = kActionTrigger;
}
void DrivingPuzzle::armExitScene(uint16 sceneID, int16 flag, byte flagValue) {
- _exitScene = SceneChangeDescription();
- _exitScene.sceneID = sceneID;
+ _exitScene._sceneChange = SceneChangeDescription();
+ _exitScene._sceneChange.sceneID = sceneID;
+ _exitScene._flag.label = flag;
+ _exitScene._flag.flag = flagValue ? g_nancy->_true : g_nancy->_false;
_exitHasFade = false;
- _exitFlag = flag;
- _exitFlagValue = flagValue;
_state = kActionTrigger;
}
@@ -720,10 +720,9 @@ void DrivingPuzzle::execute() {
break;
case kActionTrigger:
g_nancy->_sound->stopSound(_soundBlocks[2].channel); // stop the engine ambience
- NancySceneState.setEventFlag(_exitFlag, _exitFlagValue ? g_nancy->_true : g_nancy->_false);
if (_exitHasFade)
NancySceneState.specialEffect(_exitFadeType, _exitFadeTotalTime, _exitFadeToBlackTime, _exitFadeRect);
- NancySceneState.changeScene(_exitScene);
+ _exitScene.execute();
finishExecution();
break;
}
diff --git a/engines/nancy/action/puzzle/drivingpuzzle.h b/engines/nancy/action/puzzle/drivingpuzzle.h
index 91b4f33c317..80cc3bbdc27 100644
--- a/engines/nancy/action/puzzle/drivingpuzzle.h
+++ b/engines/nancy/action/puzzle/drivingpuzzle.h
@@ -22,7 +22,7 @@
#ifndef NANCY_ACTION_DRIVINGPUZZLE_H
#define NANCY_ACTION_DRIVINGPUZZLE_H
-#include "engines/nancy/action/actionrecord.h"
+#include "engines/nancy/action/puzzlerecord.h"
#include "engines/nancy/commontypes.h"
#include "engines/nancy/action/navigationrecords.h"
#include "engines/nancy/action/actionzone.h"
@@ -64,11 +64,11 @@ namespace Action {
// - kChase: the "caught Jane" transition (state 1 -> 2, the win) is gated on an event
// flag the chase scene is expected to set (nothing in this record sets it); confirm
// what triggers it so a missed catch can't still win.
-class DrivingPuzzle : public RenderActionRecord {
+class DrivingPuzzle : public PuzzleRecord {
public:
enum Variant { kDriving = 0, kChase };
- DrivingPuzzle(Variant variant) : RenderActionRecord(7), _variant(variant) {}
+ DrivingPuzzle(Variant variant) : PuzzleRecord(7), _variant(variant) {}
virtual ~DrivingPuzzle() {}
void init() override;
@@ -298,15 +298,12 @@ protected:
int _parkedDest = -1; // destination zone the car is currently parked in (-1 == none)
// A pending exit to another scene (a location, the chase finish, or a chase outcome).
- // Armed via armExit()/armExitScene(); applied and finished in the kActionTrigger state.
- SceneChangeDescription _exitScene;
+ // Armed via armExit()/armExitScene() into _exitScene; applied and finished in the kActionTrigger state.
bool _exitHasFade = false;
byte _exitFadeType = 0;
uint16 _exitFadeTotalTime = 0;
uint16 _exitFadeToBlackTime = 0;
Common::Rect _exitFadeRect;
- int16 _exitFlag = -1;
- byte _exitFlagValue = 0;
// Chase (167) state machine: 0 = following the first path, 1 = waiting to switch,
// 2 = following the second path.
diff --git a/engines/nancy/action/puzzle/dropsortpuzzle.cpp b/engines/nancy/action/puzzle/dropsortpuzzle.cpp
index f610e9800f6..7c156359022 100644
--- a/engines/nancy/action/puzzle/dropsortpuzzle.cpp
+++ b/engines/nancy/action/puzzle/dropsortpuzzle.cpp
@@ -94,12 +94,12 @@ void DropSortPuzzle::readData(Common::SeekableReadStream &stream) {
_hornSound.readData(stream);
// Win scene + flag. frameID 0xffff means "no specific frame" (target may be a video) - keep 0.
- _winScene.sceneID = stream.readUint16LE();
+ _solveScene._sceneChange.sceneID = stream.readUint16LE();
uint16 winFrame = stream.readUint16LE();
- _winScene.frameID = (winFrame == 0xffff) ? 0 : winFrame;
- _winScene.continueSceneSound = kContinueSceneSound;
- _winFlag.label = stream.readSint16LE();
- _winFlag.flag = stream.readByte();
+ _solveScene._sceneChange.frameID = (winFrame == 0xffff) ? 0 : winFrame;
+ _solveScene._sceneChange.continueSceneSound = kContinueSceneSound;
+ _solveScene._flag.label = stream.readSint16LE();
+ _solveScene._flag.flag = stream.readByte();
_winSound.readData(stream);
@@ -113,7 +113,7 @@ void DropSortPuzzle::readData(Common::SeekableReadStream &stream) {
_loseSound.readData(stream);
// Count-prefixed 23-byte hotspot records; the first is the "give up / exit" hotspot.
- readExitHotspot(stream, _exitHotspot, _exitCursorType, _exitScene, _exitFlag);
+ readExitHotspot(stream);
}
void DropSortPuzzle::init() {
@@ -403,11 +403,9 @@ void DropSortPuzzle::execute() {
}
case kActionTrigger:
if (_exitRequested) {
- NancySceneState.setEventFlag(_exitFlag);
- NancySceneState.changeScene(_exitScene);
+ _exitScene.execute();
} else if (_solved) {
- NancySceneState.setEventFlag(_winFlag);
- NancySceneState.changeScene(_winScene);
+ _solveScene.execute();
} else {
NancySceneState.setEventFlag(_loseFlag);
NancySceneState.changeScene(_loseScene);
@@ -458,9 +456,7 @@ void DropSortPuzzle::handleInput(NancyInput &input) {
return;
}
- if (!_exitHotspot.isEmpty() &&
- NancySceneState.getViewport().convertViewportToScreen(_exitHotspot).contains(input.mousePos)) {
- g_nancy->_cursor->setCursorType((CursorManager::CursorType)_exitCursorType, true, false);
+ if (hoverExitHotspot(input)) {
if (click) {
_exitRequested = true;
}
diff --git a/engines/nancy/action/puzzle/dropsortpuzzle.h b/engines/nancy/action/puzzle/dropsortpuzzle.h
index 904c9842cb0..936ab19bdb3 100644
--- a/engines/nancy/action/puzzle/dropsortpuzzle.h
+++ b/engines/nancy/action/puzzle/dropsortpuzzle.h
@@ -24,7 +24,7 @@
#include "engines/nancy/commontypes.h"
#include "engines/nancy/movieplayer.h"
-#include "engines/nancy/action/actionrecord.h"
+#include "engines/nancy/action/puzzlerecord.h"
#include "engines/nancy/misc/mousefollow.h"
namespace Nancy {
@@ -39,9 +39,9 @@ namespace Action {
// it; three mistakes lose. Win once all candies are dispensed and the
// belt is empty. The scene ships several copies as a difficulty ramp
// (faster belt, shorter dispense interval).
-class DropSortPuzzle : public RenderActionRecord {
+class DropSortPuzzle : public PuzzleRecord {
public:
- DropSortPuzzle() : RenderActionRecord(7) {}
+ DropSortPuzzle() : PuzzleRecord(7) {}
virtual ~DropSortPuzzle() {}
void init() override;
@@ -117,19 +117,12 @@ protected:
RandomSoundBlock _dropSound; // candy dropped in the correct bin
RandomSoundBlock _hornSound; // candy dropped in the wrong bin (a strike)
- SceneChangeDescription _winScene;
- FlagDescription _winFlag;
RandomSoundBlock _winSound;
SceneChangeDescription _loseScene;
FlagDescription _loseFlag;
RandomSoundBlock _loseSound;
- Common::Rect _exitHotspot;
- uint16 _exitCursorType = 0;
- SceneChangeDescription _exitScene;
- FlagDescription _exitFlag; // set on give-up
-
// -- Runtime state --
Common::Array<BeltItem> _items; // candies currently on the belt, oldest first
uint _numDispensed = 0;
diff --git a/engines/nancy/action/puzzle/escapegridpuzzle.cpp b/engines/nancy/action/puzzle/escapegridpuzzle.cpp
index 55f6e880aa0..8d443b634ae 100644
--- a/engines/nancy/action/puzzle/escapegridpuzzle.cpp
+++ b/engines/nancy/action/puzzle/escapegridpuzzle.cpp
@@ -148,11 +148,11 @@ void EscapeGridPuzzle::readData(Common::SeekableReadStream &stream) {
actor.isPlayer = (stream.readByte() == 1);
}
- _solveScene.sceneID = stream.readUint16LE();
- _solveScene.frameID = stream.readUint16LE();
- _solveScene.continueSceneSound = kContinueSceneSound;
- _solveFlag.label = stream.readSint16LE();
- _solveFlag.flag = stream.readByte();
+ _solveScene._sceneChange.sceneID = stream.readUint16LE();
+ _solveScene._sceneChange.frameID = stream.readUint16LE();
+ _solveScene._sceneChange.continueSceneSound = kContinueSceneSound;
+ _solveScene._flag.label = stream.readSint16LE();
+ _solveScene._flag.flag = stream.readByte();
_solveSound.readData(stream);
_failScene.sceneID = stream.readUint16LE();
@@ -162,8 +162,8 @@ void EscapeGridPuzzle::readData(Common::SeekableReadStream &stream) {
_failFlag.flag = stream.readByte();
_failSound.readData(stream);
- readExitHotspot(stream, _exitHotspot, _exitCursorType, _exitScene, _exitFlag);
- _exitScene.continueSceneSound = kContinueSceneSound;
+ readExitHotspot(stream);
+ _exitScene._sceneChange.continueSceneSound = kContinueSceneSound;
}
static void loadPuzzleImage(const Common::Path &name, Graphics::ManagedSurface &surface, uint32 transColor) {
@@ -1071,11 +1071,9 @@ void EscapeGridPuzzle::execute() {
}
case kActionTrigger:
if (_exitRequested) {
- NancySceneState.setEventFlag(_exitFlag);
- NancySceneState.changeScene(_exitScene);
+ _exitScene.execute();
} else if (_outcome == 0) {
- NancySceneState.setEventFlag(_solveFlag);
- NancySceneState.changeScene(_solveScene);
+ _solveScene.execute();
} else {
NancySceneState.setEventFlag(_failFlag);
NancySceneState.changeScene(_failScene);
@@ -1108,10 +1106,9 @@ void EscapeGridPuzzle::handleInput(NancyInput &input) {
g_nancy->_cursor->setCursorType((CursorManager::CursorType)_busyCursorType, true, false);
}
- if (!_exitHotspot.isEmpty() &&
- NancySceneState.getViewport().convertViewportToScreen(_exitHotspot).contains(input.mousePos)) {
+ if (isExitHotspotHovered(input)) {
if (playerToMove) {
- g_nancy->_cursor->setCursorType((CursorManager::CursorType)_exitCursorType, true, false);
+ setExitCursor();
}
if (click) {
_exitRequested = true;
diff --git a/engines/nancy/action/puzzle/escapegridpuzzle.h b/engines/nancy/action/puzzle/escapegridpuzzle.h
index d55f97ab883..2ec48eeb417 100644
--- a/engines/nancy/action/puzzle/escapegridpuzzle.h
+++ b/engines/nancy/action/puzzle/escapegridpuzzle.h
@@ -23,7 +23,7 @@
#define NANCY_ACTION_ESCAPEGRIDPUZZLE_H
#include "engines/nancy/commontypes.h"
-#include "engines/nancy/action/actionrecord.h"
+#include "engines/nancy/action/puzzlerecord.h"
namespace Nancy {
@@ -36,9 +36,9 @@ namespace Action {
// Landing on a hex slides the whole line of hexes through it one step in the direction
// of the jump, carrying anyone standing on it, with the front hex wrapping around to the
// back; which hexes are solid and which are missing shifts along with it.
-class EscapeGridPuzzle : public RenderActionRecord {
+class EscapeGridPuzzle : public PuzzleRecord {
public:
- EscapeGridPuzzle() : RenderActionRecord(7) {}
+ EscapeGridPuzzle() : PuzzleRecord(7) {}
virtual ~EscapeGridPuzzle();
void init() override;
@@ -247,18 +247,11 @@ protected:
Common::Array<Character> _characters;
Common::Array<Actor> _actors;
- SceneChangeDescription _solveScene;
- FlagDescription _solveFlag;
RandomSoundBlock _solveSound;
SceneChangeDescription _failScene; // an opponent got there first
FlagDescription _failFlag;
RandomSoundBlock _failSound;
- Common::Rect _exitHotspot;
- uint16 _exitCursorType = 0;
- SceneChangeDescription _exitScene;
- FlagDescription _exitFlag;
-
// -- Runtime state --
Common::Array<Common::Point> _actorCells;
// An opponent does not head back to the hex it jumped to the turn before last.
diff --git a/engines/nancy/action/puzzle/gridmappuzzle.cpp b/engines/nancy/action/puzzle/gridmappuzzle.cpp
index 0d5061dd573..05e663ffa3d 100644
--- a/engines/nancy/action/puzzle/gridmappuzzle.cpp
+++ b/engines/nancy/action/puzzle/gridmappuzzle.cpp
@@ -94,16 +94,16 @@ void GridMapPuzzle::readData(Common::SeekableReadStream &stream) {
_pickupSound.readNormal(stream);
_placeSound.readNormal(stream);
- _winScene.readData(stream);
+ _solveScene._sceneChange.readData(stream);
stream.skip(2);
- _winFlag.label = stream.readSint16LE();
- _winFlag.flag = stream.readByte();
+ _solveScene._flag.label = stream.readSint16LE();
+ _solveScene._flag.flag = stream.readByte();
_winSound.readNormal(stream);
- _cancelScene.readData(stream);
+ _exitScene._sceneChange.readData(stream);
stream.skip(2);
- _cancelFlag.label = stream.readSint16LE();
- _cancelFlag.flag = stream.readByte();
+ _exitScene._flag.label = stream.readSint16LE();
+ _exitScene._flag.flag = stream.readByte();
readRect(stream, _exitHotspot);
stream.skip(18); // trailing cursor type + unused fields
@@ -241,11 +241,9 @@ void GridMapPuzzle::execute() {
GridMapPuzzleData *gmd = (GridMapPuzzleData *)NancySceneState.getPuzzleData(GridMapPuzzleData::getTag());
if (gmd)
gmd->itemState.clear();
- NancySceneState.setEventFlag(_winFlag);
- NancySceneState.changeScene(_winScene);
+ _solveScene.execute();
} else {
- NancySceneState.setEventFlag(_cancelFlag);
- NancySceneState.changeScene(_cancelScene);
+ _exitScene.execute();
}
finishExecution();
break;
@@ -363,8 +361,7 @@ void GridMapPuzzle::handleInput(NancyInput &input) {
g_nancy->_cursor->showCursor(_heldItem == -1);
if (!hitMap && !hitItems) {
- if (!_exitHotspot.isEmpty() && _exitHotspot.contains(mouseVP)) {
- g_nancy->_cursor->setCursorType(g_nancy->_cursor->_puzzleExitCursor);
+ if (hoverExitHotspot(input)) {
if (input.input & NancyInput::kLeftMouseButtonUp)
_subState = kExitToCancel;
} else {
diff --git a/engines/nancy/action/puzzle/gridmappuzzle.h b/engines/nancy/action/puzzle/gridmappuzzle.h
index 7b493a7fe67..c7a87ff825d 100644
--- a/engines/nancy/action/puzzle/gridmappuzzle.h
+++ b/engines/nancy/action/puzzle/gridmappuzzle.h
@@ -22,7 +22,7 @@
#ifndef NANCY_ACTION_GRIDMAPPUZZLE_H
#define NANCY_ACTION_GRIDMAPPUZZLE_H
-#include "engines/nancy/action/actionrecord.h"
+#include "engines/nancy/action/puzzlerecord.h"
#include "engines/nancy/misc/mousefollow.h"
#include "engines/nancy/commontypes.h"
@@ -34,9 +34,9 @@ namespace Action {
// either. Wins when the items-grid layout matches any of the solutions stored
// in the action record.
// Called from scene 6240 in Nancy10.
-class GridMapPuzzle : public RenderActionRecord {
+class GridMapPuzzle : public PuzzleRecord {
public:
- GridMapPuzzle() : RenderActionRecord(7) {}
+ GridMapPuzzle() : PuzzleRecord(7) {}
virtual ~GridMapPuzzle() {}
void init() override;
@@ -111,13 +111,6 @@ protected:
SoundDescription _placeSound;
SoundDescription _winSound;
- SceneChangeDescription _winScene;
- FlagDescription _winFlag;
- SceneChangeDescription _cancelScene;
- FlagDescription _cancelFlag;
-
- Common::Rect _exitHotspot;
-
// Runtime state
enum SubState {
diff --git a/engines/nancy/action/puzzle/hamradiopuzzle.h b/engines/nancy/action/puzzle/hamradiopuzzle.h
index cb598a205b9..ca9a5a95ad1 100644
--- a/engines/nancy/action/puzzle/hamradiopuzzle.h
+++ b/engines/nancy/action/puzzle/hamradiopuzzle.h
@@ -22,16 +22,16 @@
#ifndef NANCY_ACTION_HAMRADIOPUZZLE_H
#define NANCY_ACTION_HAMRADIOPUZZLE_H
-#include "engines/nancy/action/actionrecord.h"
+#include "engines/nancy/action/puzzlerecord.h"
namespace Nancy {
namespace Action {
// A puzzle that has the player input radio frequencies, and
// send morse code data via ham radio. Used in nancy6.
-class HamRadioPuzzle : public RenderActionRecord {
+class HamRadioPuzzle : public PuzzleRecord {
public:
- HamRadioPuzzle() : RenderActionRecord(7) {}
+ HamRadioPuzzle() : PuzzleRecord(7) {}
virtual ~HamRadioPuzzle() {}
void init() override;
@@ -99,14 +99,12 @@ protected:
CCSound _longMorseSound;
Common::Array<CCSound> _badFrequencySounds;
- SceneChangeWithFlag _solveScene;
uint16 _solveSoundDelay = 0; // not used
CCSound _solveSound;
Common::Rect _exitButtonDest;
Common::Rect _exitButtonSrc;
- SceneChangeWithFlag _exitScene;
uint16 _exitSoundDelay = 0; // not used
SoundDescription _exitSound; // not used
diff --git a/engines/nancy/action/puzzle/hangmanpuzzle.cpp b/engines/nancy/action/puzzle/hangmanpuzzle.cpp
index 9a25371f519..a5eb37e9ff2 100644
--- a/engines/nancy/action/puzzle/hangmanpuzzle.cpp
+++ b/engines/nancy/action/puzzle/hangmanpuzzle.cpp
@@ -91,7 +91,7 @@ void HangmanPuzzle::readData(Common::SeekableReadStream &stream) {
// Trailing count-prefixed array of 23-byte give-up hotspots
// {Rect, uint16 cursorType, uint16 sceneID, int16 flagLabel, byte flagValue}.
// The exit always jumps to the scene's first frame.
- readExitHotspot(stream, _exitHotspot, _exitCursorType, _exitScene, _exitFlag);
+ readExitHotspot(stream);
}
HangmanData *HangmanPuzzle::getPuzzleData() const {
@@ -344,9 +344,7 @@ void HangmanPuzzle::handleInput(NancyInput &input) {
}
// Give-up hotspot: leave the puzzle.
- if (!_exitHotspot.isEmpty() &&
- NancySceneState.getViewport().convertViewportToScreen(_exitHotspot).contains(input.mousePos)) {
- g_nancy->_cursor->setCursorType((CursorManager::CursorType)_exitCursorType, true);
+ if (hoverExitHotspot(input)) {
if (input.input & NancyInput::kLeftMouseButtonUp) {
_exitRequested = true;
}
@@ -373,8 +371,7 @@ void HangmanPuzzle::execute() {
break;
case kRun:
if (_exitRequested) {
- NancySceneState.setEventFlag(_exitFlag);
- NancySceneState.changeScene(_exitScene);
+ _exitScene.execute();
break;
}
updateFeedback();
diff --git a/engines/nancy/action/puzzle/hangmanpuzzle.h b/engines/nancy/action/puzzle/hangmanpuzzle.h
index a62b8c449db..02bd261ce7c 100644
--- a/engines/nancy/action/puzzle/hangmanpuzzle.h
+++ b/engines/nancy/action/puzzle/hangmanpuzzle.h
@@ -23,7 +23,7 @@
#define NANCY_ACTION_HANGMANPUZZLE_H
#include "engines/nancy/commontypes.h"
-#include "engines/nancy/action/actionrecord.h"
+#include "engines/nancy/action/puzzlerecord.h"
namespace Nancy {
@@ -39,9 +39,9 @@ namespace Action {
// carry a target letter sequence: playing exactly those letters, in order, takes
// a third outcome regardless of the word. The chosen word is remembered across
// visits so it is not immediately repeated.
-class HangmanPuzzle : public RenderActionRecord {
+class HangmanPuzzle : public PuzzleRecord {
public:
- HangmanPuzzle() : RenderActionRecord(7) {}
+ HangmanPuzzle() : PuzzleRecord(7) {}
virtual ~HangmanPuzzle() {}
void init() override;
@@ -113,12 +113,6 @@ protected:
SceneOutcome _winScene; // 0x2f1
SceneOutcome _loseScene; // 0x352
- // Give-up hotspot (count-prefixed 23-byte trailer): click to leave the puzzle.
- Common::Rect _exitHotspot;
- uint16 _exitCursorType = 0;
- SceneChangeDescription _exitScene;
- FlagDescription _exitFlag;
-
// -- Runtime state --
Graphics::ManagedSurface _puzzleImage;
Graphics::ManagedSurface _lettersImage;
diff --git a/engines/nancy/action/puzzle/lettergridpuzzle.cpp b/engines/nancy/action/puzzle/lettergridpuzzle.cpp
index a6d93b27429..c7d4785b4d0 100644
--- a/engines/nancy/action/puzzle/lettergridpuzzle.cpp
+++ b/engines/nancy/action/puzzle/lettergridpuzzle.cpp
@@ -80,16 +80,16 @@ void LetterGridPuzzle::readData(Common::SeekableReadStream &stream) {
_clickSound.readData(stream);
- _solveScene.sceneID = stream.readUint16LE();
- _solveScene.frameID = stream.readUint16LE();
- _solveScene.continueSceneSound = kContinueSceneSound;
- _solveFlag.label = stream.readSint16LE();
- _solveFlag.flag = stream.readByte();
+ _solveScene._sceneChange.sceneID = stream.readUint16LE();
+ _solveScene._sceneChange.frameID = stream.readUint16LE();
+ _solveScene._sceneChange.continueSceneSound = kContinueSceneSound;
+ _solveScene._flag.label = stream.readSint16LE();
+ _solveScene._flag.flag = stream.readByte();
_solveSound.readData(stream);
- readExitHotspot(stream, _exitHotspot, _exitCursorType, _exitScene, _exitFlag);
- _exitScene.continueSceneSound = kContinueSceneSound;
+ readExitHotspot(stream);
+ _exitScene._sceneChange.continueSceneSound = kContinueSceneSound;
// The marks live in a fixed-size global grid
if (_columns.size() > kMaxColumns) {
@@ -268,8 +268,7 @@ void LetterGridPuzzle::execute() {
break;
case kActionTrigger:
if (_exitRequested) {
- NancySceneState.setEventFlag(_exitFlag);
- NancySceneState.changeScene(_exitScene);
+ _exitScene.execute();
finishExecution();
break;
}
@@ -285,8 +284,7 @@ void LetterGridPuzzle::execute() {
break;
}
- NancySceneState.setEventFlag(_solveFlag);
- NancySceneState.changeScene(_solveScene);
+ _solveScene.execute();
finishExecution();
break;
}
@@ -297,9 +295,7 @@ void LetterGridPuzzle::handleInput(NancyInput &input) {
return;
}
- if (!_exitHotspot.isEmpty() &&
- NancySceneState.getViewport().convertViewportToScreen(_exitHotspot).contains(input.mousePos)) {
- g_nancy->_cursor->setCursorType((CursorManager::CursorType)_exitCursorType, true);
+ if (hoverExitHotspot(input)) {
if (input.input & NancyInput::kLeftMouseButtonUp) {
_exitRequested = true;
}
diff --git a/engines/nancy/action/puzzle/lettergridpuzzle.h b/engines/nancy/action/puzzle/lettergridpuzzle.h
index 26f7e604d08..fb9476ed2c1 100644
--- a/engines/nancy/action/puzzle/lettergridpuzzle.h
+++ b/engines/nancy/action/puzzle/lettergridpuzzle.h
@@ -23,7 +23,7 @@
#define NANCY_ACTION_LETTERGRIDPUZZLE_H
#include "engines/nancy/commontypes.h"
-#include "engines/nancy/action/actionrecord.h"
+#include "engines/nancy/action/puzzlerecord.h"
namespace Nancy {
namespace Action {
@@ -38,9 +38,9 @@ namespace Action {
//
// The marks are global game state: they survive leaving the puzzle and are only
// reset by a new game. They are kept in GridMapPuzzleData.
-class LetterGridPuzzle : public RenderActionRecord {
+class LetterGridPuzzle : public PuzzleRecord {
public:
- LetterGridPuzzle() : RenderActionRecord(7) {}
+ LetterGridPuzzle() : PuzzleRecord(7) {}
virtual ~LetterGridPuzzle() {}
void init() override;
@@ -93,15 +93,8 @@ protected:
RandomSoundBlock _clickSound;
- SceneChangeDescription _solveScene;
- FlagDescription _solveFlag;
RandomSoundBlock _solveSound; // plays out before the scene change
- Common::Rect _exitHotspot;
- uint16 _exitCursorType = 0;
- SceneChangeDescription _exitScene;
- FlagDescription _exitFlag;
-
// -- Runtime state --
Graphics::ManagedSurface _letterImage;
Graphics::ManagedSurface _markImage;
diff --git a/engines/nancy/action/puzzle/leverpuzzle.cpp b/engines/nancy/action/puzzle/leverpuzzle.cpp
index 950c95e2d6c..aa660051544 100644
--- a/engines/nancy/action/puzzle/leverpuzzle.cpp
+++ b/engines/nancy/action/puzzle/leverpuzzle.cpp
@@ -81,7 +81,7 @@ void LeverPuzzle::readData(Common::SeekableReadStream &stream) {
_moveSound.readNormal(stream);
_noMoveSound.readNormal(stream);
- _solveExitScene.readData(stream);
+ _solveScene.readData(stream);
_solveSoundDelay = stream.readUint16LE();
_solveSound.readNormal(stream);
_exitScene.readData(stream);
@@ -145,7 +145,7 @@ void LeverPuzzle::execute() {
// The flag is only set here: setting it as soon as the puzzle is solved can
// invalidate this record's own dependencies, which stops it from being executed
// again before it ever reaches this point.
- _solveExitScene.execute();
+ _solveScene.execute();
}
finishExecution();
@@ -157,9 +157,7 @@ void LeverPuzzle::handleInput(NancyInput &input) {
return;
}
- if (NancySceneState.getViewport().convertViewportToScreen(_exitHotspot).contains(input.mousePos)) {
- g_nancy->_cursor->setCursorType(g_nancy->_cursor->_puzzleExitCursor);
-
+ if (hoverExitHotspot(input)) {
if (input.input & NancyInput::kLeftMouseButtonUp) {
_state = kActionTrigger;
}
diff --git a/engines/nancy/action/puzzle/leverpuzzle.h b/engines/nancy/action/puzzle/leverpuzzle.h
index d7f4007c3ff..a13e82a8f91 100644
--- a/engines/nancy/action/puzzle/leverpuzzle.h
+++ b/engines/nancy/action/puzzle/leverpuzzle.h
@@ -22,15 +22,15 @@
#ifndef NANCY_ACTION_LEVERPUZZLE_H
#define NANCY_ACTION_LEVERPUZZLE_H
-#include "engines/nancy/action/actionrecord.h"
+#include "engines/nancy/action/puzzlerecord.h"
namespace Nancy {
namespace Action {
-class LeverPuzzle : public RenderActionRecord {
+class LeverPuzzle : public PuzzleRecord {
public:
enum SolveState { kNotSolved, kPlaySound, kWaitForSound };
- LeverPuzzle() : RenderActionRecord(7) {}
+ LeverPuzzle() : PuzzleRecord(7) {}
virtual ~LeverPuzzle() {}
void init() override;
@@ -45,11 +45,8 @@ public:
Common::Array<byte> _correctSequence;
SoundDescription _moveSound;
SoundDescription _noMoveSound;
- SceneChangeWithFlag _solveExitScene;
uint16 _solveSoundDelay = 0;
SoundDescription _solveSound;
- SceneChangeWithFlag _exitScene;
- Common::Rect _exitHotspot;
Common::Array<byte> _playerSequence;
Common::Array<bool> _leverDirection;
diff --git a/engines/nancy/action/puzzle/magicboxpuzzle.cpp b/engines/nancy/action/puzzle/magicboxpuzzle.cpp
index 70a1e7fc252..a43a4fc5498 100644
--- a/engines/nancy/action/puzzle/magicboxpuzzle.cpp
+++ b/engines/nancy/action/puzzle/magicboxpuzzle.cpp
@@ -95,11 +95,11 @@ void MagicBoxPuzzle::readData(Common::SeekableReadStream &stream) {
_sounds[i].readData(stream);
}
- _solveScene.sceneID = stream.readUint16LE();
- _solveScene.frameID = stream.readUint16LE();
- _solveScene.continueSceneSound = kContinueSceneSound;
- _solveFlag.label = stream.readSint16LE();
- _solveFlag.flag = stream.readByte();
+ _solveScene._sceneChange.sceneID = stream.readUint16LE();
+ _solveScene._sceneChange.frameID = stream.readUint16LE();
+ _solveScene._sceneChange.continueSceneSound = kContinueSceneSound;
+ _solveScene._flag.label = stream.readSint16LE();
+ _solveScene._flag.flag = stream.readByte();
_solveSound.readData(stream);
_failScene.sceneID = stream.readUint16LE();
@@ -109,8 +109,8 @@ void MagicBoxPuzzle::readData(Common::SeekableReadStream &stream) {
_failFlag.flag = stream.readByte();
_failSound.readData(stream);
- readExitHotspot(stream, _exitHotspot, _exitCursorType, _exitScene, _exitFlag);
- _exitScene.continueSceneSound = kContinueSceneSound;
+ readExitHotspot(stream);
+ _exitScene._sceneChange.continueSceneSound = kContinueSceneSound;
}
void MagicBoxPuzzle::init() {
@@ -323,11 +323,9 @@ void MagicBoxPuzzle::execute() {
break;
case kActionTrigger:
if (_exitRequested) {
- NancySceneState.setEventFlag(_exitFlag);
- NancySceneState.changeScene(_exitScene);
+ _exitScene.execute();
} else {
- NancySceneState.setEventFlag(_solveFlag);
- NancySceneState.changeScene(_solveScene);
+ _solveScene.execute();
}
finishExecution();
@@ -395,9 +393,7 @@ void MagicBoxPuzzle::handleInput(NancyInput &input) {
return;
}
- if (!_exitHotspot.isEmpty() &&
- NancySceneState.getViewport().convertViewportToScreen(_exitHotspot).contains(input.mousePos)) {
- setDataCursor(_exitCursorType, false);
+ if (hoverExitHotspot(input)) {
if (click) {
_exitRequested = true;
}
diff --git a/engines/nancy/action/puzzle/magicboxpuzzle.h b/engines/nancy/action/puzzle/magicboxpuzzle.h
index a1c775234b3..0ea27aa3b41 100644
--- a/engines/nancy/action/puzzle/magicboxpuzzle.h
+++ b/engines/nancy/action/puzzle/magicboxpuzzle.h
@@ -23,7 +23,7 @@
#define NANCY_ACTION_MAGICBOXPUZZLE_H
#include "engines/nancy/commontypes.h"
-#include "engines/nancy/action/actionrecord.h"
+#include "engines/nancy/action/puzzlerecord.h"
#include "engines/nancy/misc/mousefollow.h"
namespace Nancy {
@@ -31,9 +31,9 @@ namespace Action {
// Number-square puzzle, new in Nancy15 (AR 183). Loose numbered tiles are carried from a
// tray into the blank cells of a grid, until every row and column adds up to its target.
-class MagicBoxPuzzle : public RenderActionRecord {
+class MagicBoxPuzzle : public PuzzleRecord {
public:
- MagicBoxPuzzle() : RenderActionRecord(7) {}
+ MagicBoxPuzzle() : PuzzleRecord(7) {}
virtual ~MagicBoxPuzzle() {}
void init() override;
@@ -90,18 +90,11 @@ protected:
RandomSoundBlock _sounds[kNumSounds];
- SceneChangeDescription _solveScene;
- FlagDescription _solveFlag;
RandomSoundBlock _solveSound;
SceneChangeDescription _failScene;
FlagDescription _failFlag;
RandomSoundBlock _failSound;
- Common::Rect _exitHotspot;
- uint16 _exitCursorType = 0;
- SceneChangeDescription _exitScene;
- FlagDescription _exitFlag;
-
// -- Runtime state --
Common::Array<int> _slotCells; // board cell index of each slot
Common::Array<int> _slotContents; // piece in each slot, or -1
diff --git a/engines/nancy/action/puzzle/magnetmazepuzzle.cpp b/engines/nancy/action/puzzle/magnetmazepuzzle.cpp
index 3b541aecc47..c4deac9779b 100644
--- a/engines/nancy/action/puzzle/magnetmazepuzzle.cpp
+++ b/engines/nancy/action/puzzle/magnetmazepuzzle.cpp
@@ -80,18 +80,18 @@ void MagnetMazePuzzle::readData(Common::SeekableReadStream &stream) {
_bumpSound.readNormal(stream);
stream.seek(start + 0x48a);
- _winScene.readData(stream);
+ _solveScene._sceneChange.readData(stream);
stream.seek(start + 0x4a0);
- _winFlag.label = stream.readSint16LE();
- _winFlag.flag = stream.readByte();
+ _solveScene._flag.label = stream.readSint16LE();
+ _solveScene._flag.flag = stream.readByte();
_winDelaySec = stream.readUint16LE();
_winSound.readNormal(stream);
stream.seek(start + 0x4d6);
- _cancelScene.readData(stream);
+ _exitScene._sceneChange.readData(stream);
stream.seek(start + 0x4ec);
- _cancelFlag.label = stream.readSint16LE();
- _cancelFlag.flag = stream.readByte();
+ _exitScene._flag.label = stream.readSint16LE();
+ _exitScene._flag.flag = stream.readByte();
readRect(stream, _exitHotspot);
}
@@ -189,11 +189,9 @@ void MagnetMazePuzzle::execute() {
MagnetMazePuzzleData *mmd = (MagnetMazePuzzleData *)NancySceneState.getPuzzleData(MagnetMazePuzzleData::getTag());
if (mmd)
mmd->magnetState.clear();
- NancySceneState.setEventFlag(_winFlag);
- NancySceneState.changeScene(_winScene);
+ _solveScene.execute();
} else {
- NancySceneState.setEventFlag(_cancelFlag);
- NancySceneState.changeScene(_cancelScene);
+ _exitScene.execute();
}
finishExecution();
break;
@@ -302,8 +300,7 @@ void MagnetMazePuzzle::handleInput(NancyInput &input) {
redraw();
}
- if (!_exitHotspot.isEmpty() && _exitHotspot.contains(mouseVP)) {
- g_nancy->_cursor->setCursorType(g_nancy->_cursor->_puzzleExitCursor);
+ if (hoverExitHotspot(input)) {
if (input.input & NancyInput::kLeftMouseButtonUp)
_subState = kExitToCancel;
return;
diff --git a/engines/nancy/action/puzzle/magnetmazepuzzle.h b/engines/nancy/action/puzzle/magnetmazepuzzle.h
index 0cd4f266941..b72ddf0d855 100644
--- a/engines/nancy/action/puzzle/magnetmazepuzzle.h
+++ b/engines/nancy/action/puzzle/magnetmazepuzzle.h
@@ -22,7 +22,7 @@
#ifndef NANCY_ACTION_MAGNETMAZEPUZZLE_H
#define NANCY_ACTION_MAGNETMAZEPUZZLE_H
-#include "engines/nancy/action/actionrecord.h"
+#include "engines/nancy/action/puzzlerecord.h"
#include "engines/nancy/commontypes.h"
namespace Nancy {
@@ -35,9 +35,9 @@ namespace Action {
// Called in Nancy10 from scenes 3280 (normal mode, with overlaid pieces) and
// 3281 (easy mode, without overlaid pieces, triggered as a cheat mode when
// visiting the puzzle multiple times).
-class MagnetMazePuzzle : public RenderActionRecord {
+class MagnetMazePuzzle : public PuzzleRecord {
public:
- MagnetMazePuzzle() : RenderActionRecord(7) {}
+ MagnetMazePuzzle() : PuzzleRecord(7) {}
virtual ~MagnetMazePuzzle() {}
void init() override;
@@ -78,16 +78,9 @@ protected:
SoundDescription _resetSound;
SoundDescription _bumpSound;
- SceneChangeDescription _winScene;
- FlagDescription _winFlag;
uint16 _winDelaySec = 0;
SoundDescription _winSound;
- SceneChangeDescription _cancelScene;
- FlagDescription _cancelFlag;
-
- Common::Rect _exitHotspot;
-
// Runtime state
enum SubState {
diff --git a/engines/nancy/action/puzzle/matchpuzzle.cpp b/engines/nancy/action/puzzle/matchpuzzle.cpp
index bfa2ab610c9..c0921448c2a 100644
--- a/engines/nancy/action/puzzle/matchpuzzle.cpp
+++ b/engines/nancy/action/puzzle/matchpuzzle.cpp
@@ -114,14 +114,15 @@ void MatchPuzzle::readDataNancy14(Common::SeekableReadStream &stream) {
_timeUpSound.readData(stream);
_goButtonSound.readData(stream);
- _solveSceneChange._sceneChange.sceneID = stream.readUint16LE();
- _solveSceneChange._sceneChange.frameID = stream.readUint16LE();
- _solveSceneChange._flag.label = stream.readSint16LE();
- _solveSceneChange._flag.flag = stream.readByte();
+ _solveScene._sceneChange.sceneID = stream.readUint16LE();
+ _solveScene._sceneChange.frameID = stream.readUint16LE();
+ _solveScene._flag.label = stream.readSint16LE();
+ _solveScene._flag.flag = stream.readByte();
_exitCursorType = stream.readUint16LE();
- _exitSceneChange._sceneChange.sceneID = stream.readUint16LE();
- _exitSceneChange._sceneChange.frameID = stream.readUint16LE();
+ _exitCursorFromData = true;
+ _exitScene._sceneChange.sceneID = stream.readUint16LE();
+ _exitScene._sceneChange.frameID = stream.readUint16LE();
readRect(stream, _exitHotspot);
@@ -205,12 +206,12 @@ void MatchPuzzle::readData(Common::SeekableReadStream &stream) {
_shuffleSound.readNormal(stream); // data+0x71B..0x74B
_cardPlaceSound.readNormal(stream); // data+0x74C..0x77C
- _solveSceneChange.readData(stream); // data+0x77D..0x795 win scene
+ _solveScene.readData(stream); // data+0x77D..0x795 win scene
stream.skip(2); // data+0x796..0x797 pre-result delay (unused)
_matchSuccessSound.readNormal(stream); // data+0x798..0x7C8 win/time-up sound
- _exitSceneChange.readData(stream); // data+0x7C9..0x7E1 quit/exit scene
+ _exitScene.readData(stream); // data+0x7C9..0x7E1 quit/exit scene
readRect(stream, _exitHotspot); // data+0x7E2..0x7F1 exit hotspot
}
@@ -626,11 +627,11 @@ void MatchPuzzle::execute() {
g_nancy->_sound->stopSound(_matchSuccessSound);
if (_wonGame)
- _solveSceneChange.execute();
+ _solveScene.execute();
else if (_leftThroughButton)
_doneSceneChange.execute();
else
- _exitSceneChange.execute();
+ _exitScene.execute();
finishExecution();
break;
@@ -645,9 +646,9 @@ void MatchPuzzle::handleInput(NancyInput &input) {
Common::Point localMouse = input.mousePos;
localMouse -= Common::Point(vpPos.left, vpPos.top);
- if (!_exitHotspot.isEmpty() && _exitHotspot.contains(localMouse)) {
+ if (isExitHotspotHovered(input)) {
if (g_nancy->getGameType() >= kGameTypeNancy14)
- g_nancy->_cursor->setCursorType((CursorManager::CursorType)_exitCursorType, true);
+ setExitCursor();
else
g_nancy->_cursor->setCursorType(CursorManager::kMoveBackward);
diff --git a/engines/nancy/action/puzzle/matchpuzzle.h b/engines/nancy/action/puzzle/matchpuzzle.h
index 1dfa8996558..f1f797b8a1c 100644
--- a/engines/nancy/action/puzzle/matchpuzzle.h
+++ b/engines/nancy/action/puzzle/matchpuzzle.h
@@ -22,7 +22,7 @@
#ifndef NANCY_ACTION_MATCHPUZZLE_H
#define NANCY_ACTION_MATCHPUZZLE_H
-#include "engines/nancy/action/actionrecord.h"
+#include "engines/nancy/action/puzzlerecord.h"
#include "engines/nancy/commontypes.h"
#include "graphics/managed_surface.h"
@@ -38,9 +38,9 @@ namespace Action {
// "Model Match". The player swaps two neighbouring tiles to line up 3/4/5 of the
// same type in a row or column, which scores points and extends the timer. The
// matched tiles are then replaced with fresh random ones.
-class MatchPuzzle : public RenderActionRecord {
+class MatchPuzzle : public PuzzleRecord {
public:
- MatchPuzzle() : RenderActionRecord(7) {}
+ MatchPuzzle() : PuzzleRecord(7) {}
virtual ~MatchPuzzle() {}
void init() override;
@@ -167,11 +167,6 @@ protected:
SoundDescription _cardPlaceSound; // data+0x74C
SoundDescription _matchSuccessSound; // data+0x798 â played on win/time-up
- SceneChangeWithFlag _solveSceneChange; // data+0x77D win scene
- SceneChangeWithFlag _exitSceneChange; // data+0x7C9 quit scene
-
- Common::Rect _exitHotspot; // data+0x7E2 bottom-strip exit hotspot
-
// ---------- Nancy14-only data ----------
// Second sprite sheet, holding the pressed-down graphics of the two buttons
@@ -211,7 +206,6 @@ protected:
RandomSoundBlock _timeUpSound;
RandomSoundBlock _goButtonSound;
- uint16 _exitCursorType = 0;
SceneChangeWithFlag _doneSceneChange; // leaving through the button next to the board
// ---------- Runtime state ----------
diff --git a/engines/nancy/action/puzzle/mazechasepuzzle.cpp b/engines/nancy/action/puzzle/mazechasepuzzle.cpp
index 5541074266b..606aa7ac0e9 100644
--- a/engines/nancy/action/puzzle/mazechasepuzzle.cpp
+++ b/engines/nancy/action/puzzle/mazechasepuzzle.cpp
@@ -67,7 +67,7 @@ void MazeChasePuzzle::registerGraphics() {
for (uint i = 0; i < _pieces.size(); ++i) {
_pieces[i].registerGraphics();
}
- RenderActionRecord::registerGraphics();
+ PuzzleRecord::registerGraphics();
}
void MazeChasePuzzle::updateGraphics() {
@@ -305,9 +305,7 @@ void MazeChasePuzzle::handleInput(NancyInput &input) {
return;
}
- if (NancySceneState.getViewport().convertViewportToScreen(_exitHotspot).contains(input.mousePos)) {
- g_nancy->_cursor->setCursorType(g_nancy->_cursor->_puzzleExitCursor);
-
+ if (hoverExitHotspot(input)) {
if (input.input & NancyInput::kLeftMouseButtonUp) {
_state = kActionTrigger;
}
diff --git a/engines/nancy/action/puzzle/mazechasepuzzle.h b/engines/nancy/action/puzzle/mazechasepuzzle.h
index 9fa403471b3..2f47108bb01 100644
--- a/engines/nancy/action/puzzle/mazechasepuzzle.h
+++ b/engines/nancy/action/puzzle/mazechasepuzzle.h
@@ -22,7 +22,7 @@
#ifndef NANCY_ACTION_MAZECHASEPUZZLE_H
#define NANCY_ACTION_MAZECHASEPUZZLE_H
-#include "engines/nancy/action/actionrecord.h"
+#include "engines/nancy/action/puzzlerecord.h"
namespace Nancy {
namespace Action {
@@ -32,9 +32,9 @@ namespace Action {
// is performed via buttons, and both player and enemy navigate one
// tile at a time. Has some similarities to CollisionPuzzle, but was
// different enough to warrant its own class.
-class MazeChasePuzzle : public RenderActionRecord {
+class MazeChasePuzzle : public PuzzleRecord {
public:
- MazeChasePuzzle() : RenderActionRecord(7) {}
+ MazeChasePuzzle() : PuzzleRecord(7) {}
virtual ~MazeChasePuzzle() {}
void init() override;
@@ -107,13 +107,9 @@ protected:
SoundDescription _failSound;
SoundDescription _moveSound;
- SceneChangeWithFlag _solveScene;
uint16 _solveSoundDelay = 0;
SoundDescription _solveSound;
- SceneChangeWithFlag _exitScene;
- Common::Rect _exitHotspot;
-
Graphics::ManagedSurface _image;
Common::Array<Piece> _pieces;
diff --git a/engines/nancy/action/puzzle/memorypuzzle.cpp b/engines/nancy/action/puzzle/memorypuzzle.cpp
index 26f376f6cde..a3b6f8fc9c5 100644
--- a/engines/nancy/action/puzzle/memorypuzzle.cpp
+++ b/engines/nancy/action/puzzle/memorypuzzle.cpp
@@ -83,7 +83,7 @@ void MemoryPuzzle::readData(Common::SeekableReadStream &stream) {
_noMatchSound.readNormal(stream);
// 0x521: win scene + flag
- _winScene.readData(stream);
+ _solveScene.readData(stream);
stream.skip(1); // 0x53a: unknown
@@ -153,10 +153,10 @@ void MemoryPuzzle::readDataNancy11(Common::SeekableReadStream &stream) {
// Solve scene (0x168e), then an alternate-outcome scene (0x16a8, unused). The event flags
// store a 16-bit value rather than a simple on/off.
- _winScene._sceneChange.readData(stream);
- _winScene._sceneChange.continueSceneSound = stream.readUint16LE();
- _winScene._flag.label = stream.readSint16LE();
- _winScene._flag.flag = stream.readSint16LE() ? g_nancy->_true : g_nancy->_false;
+ _solveScene._sceneChange.readData(stream);
+ _solveScene._sceneChange.continueSceneSound = stream.readUint16LE();
+ _solveScene._flag.label = stream.readSint16LE();
+ _solveScene._flag.flag = stream.readSint16LE() ? g_nancy->_true : g_nancy->_false;
stream.skip(g_nancy->getGameType() >= kGameTypeNancy12 ? 24 : 26); // alternate scene
}
@@ -314,7 +314,7 @@ void MemoryPuzzle::execute() {
g_nancy->_sound->stopSound(_matchSound);
g_nancy->_sound->stopSound(_noMatchSound);
g_nancy->_sound->stopSound(_winSound);
- _winScene.execute();
+ _solveScene.execute();
finishExecution();
break;
}
diff --git a/engines/nancy/action/puzzle/memorypuzzle.h b/engines/nancy/action/puzzle/memorypuzzle.h
index f90efb7d393..9fd3c93464b 100644
--- a/engines/nancy/action/puzzle/memorypuzzle.h
+++ b/engines/nancy/action/puzzle/memorypuzzle.h
@@ -22,7 +22,7 @@
#ifndef NANCY_ACTION_MEMORYPUZZLE_H
#define NANCY_ACTION_MEMORYPUZZLE_H
-#include "engines/nancy/action/actionrecord.h"
+#include "engines/nancy/action/puzzlerecord.h"
#include "engines/nancy/commontypes.h"
namespace Nancy {
@@ -32,9 +32,9 @@ namespace Action {
// It has three tabs, each containing 24 cards(6x4 grid).
// The player flips cards to find matching pairs; matching pairs stay face-up.
// Player wins when matchedPairs >= requiredPairs.
-class MemoryPuzzle : public RenderActionRecord {
+class MemoryPuzzle : public PuzzleRecord {
public:
- MemoryPuzzle() : RenderActionRecord(7) {}
+ MemoryPuzzle() : PuzzleRecord(7) {}
virtual ~MemoryPuzzle() {}
void init() override;
@@ -82,7 +82,6 @@ protected:
SoundDescription _secondFlipSound;
SoundDescription _matchSound; // played when a matching pair is found
SoundDescription _noMatchSound; // pre-Nancy 11: played when a pair doesn't match
- SceneChangeWithFlag _winScene;
SoundDescription _winSound;
// Runtime state
diff --git a/engines/nancy/action/puzzle/meterpuzzle.h b/engines/nancy/action/puzzle/meterpuzzle.h
index 418104503e8..a2716713060 100644
--- a/engines/nancy/action/puzzle/meterpuzzle.h
+++ b/engines/nancy/action/puzzle/meterpuzzle.h
@@ -24,7 +24,7 @@
#include "engines/nancy/commontypes.h"
#include "engines/nancy/movieplayer.h"
-#include "engines/nancy/action/actionrecord.h"
+#include "engines/nancy/action/puzzlerecord.h"
namespace Nancy {
namespace Action {
@@ -34,9 +34,9 @@ namespace Action {
// Nancy14's oxygen meter while diving in the sewer). In modes 1/2 the value is
// a shared value table entry, driven by BlockingPuzzle (AR 180), used by
// Nancy14's health meters in the final fight.
-class MeterPuzzle : public RenderActionRecord {
+class MeterPuzzle : public PuzzleRecord {
public:
- MeterPuzzle() : RenderActionRecord(7) {}
+ MeterPuzzle() : PuzzleRecord(7) {}
virtual ~MeterPuzzle() {}
void init() override;
diff --git a/engines/nancy/action/puzzle/mindpuzzle.cpp b/engines/nancy/action/puzzle/mindpuzzle.cpp
index 6f359d81ed2..19957baeedc 100644
--- a/engines/nancy/action/puzzle/mindpuzzle.cpp
+++ b/engines/nancy/action/puzzle/mindpuzzle.cpp
@@ -41,7 +41,7 @@ void MindPuzzle::readData(Common::SeekableReadStream &stream) {
stream.skip(0x25 - 0x21); // 0x21: two count fields
readRect(stream, _exitHotspot); // 0x25: give-up / leave hotspot
- _winScene.readData(stream); // 0x35: scene reached on a solved code (25 bytes)
+ _solveScene.readData(stream); // 0x35: scene reached on a solved code (25 bytes)
_numGuesses = stream.readUint16LE(); // 0x4e
_loseScene.readData(stream); // 0x50: out-of-guesses / exit scene (25 bytes)
@@ -294,8 +294,7 @@ void MindPuzzle::execute() {
}
g_nancy->_sound->stopSound(_outcomeSound);
- NancySceneState.setEventFlag(_winScene._flag);
- NancySceneState.changeScene(_winScene._sceneChange);
+ _solveScene.execute();
} else {
// Out of guesses, or the player left via the exit hotspot.
NancySceneState.setEventFlag(_loseScene._flag);
@@ -384,8 +383,7 @@ void MindPuzzle::handleInput(NancyInput &input) {
}
// Leave the puzzle (give up) via the exit hotspot; this reports a loss.
- if (_exitHotspot.contains(mouseVP)) {
- g_nancy->_cursor->setCursorType(g_nancy->_cursor->_puzzleExitCursor);
+ if (hoverExitHotspot(input)) {
if (input.input & NancyInput::kLeftMouseButtonUp) {
_state = kActionTrigger;
}
diff --git a/engines/nancy/action/puzzle/mindpuzzle.h b/engines/nancy/action/puzzle/mindpuzzle.h
index 0e2ed73ff13..69488f91c4b 100644
--- a/engines/nancy/action/puzzle/mindpuzzle.h
+++ b/engines/nancy/action/puzzle/mindpuzzle.h
@@ -22,7 +22,7 @@
#ifndef NANCY_ACTION_MINDPUZZLE_H
#define NANCY_ACTION_MINDPUZZLE_H
-#include "engines/nancy/action/actionrecord.h"
+#include "engines/nancy/action/puzzlerecord.h"
#include "engines/nancy/misc/mousefollow.h"
#include "engines/nancy/commontypes.h"
@@ -33,9 +33,9 @@ namespace Action {
// color code over a number of rows, by placing colored balls in each row. Each
// submitted guess is scored with flag poles (right color, right slot) and plain
// poles (right color, wrong slot).
-class MindPuzzle : public RenderActionRecord {
+class MindPuzzle : public PuzzleRecord {
public:
- MindPuzzle() : RenderActionRecord(7) {}
+ MindPuzzle() : PuzzleRecord(7) {}
virtual ~MindPuzzle() {}
void init() override;
@@ -75,10 +75,8 @@ protected:
Common::Array<Common::Rect> _ballHitRects; // bottom-row clickable ball positions, one per color
Common::Rect _feedbackSrcRects[2]; // [0] right color, wrong slot (plain pole); [1] right color + slot (flag pole)
Common::Rect _submitButtonRect; // golf-club button: submit the current row
- Common::Rect _exitHotspot; // give-up / leave hotspot
Common::Array<Row> _rows;
- SceneChangeWithFlag _winScene; // reached on a solved code
SceneChangeWithFlag _loseScene; // reached when out of guesses or when leaving via the exit hotspot
RandomSoundBlock _sounds[kNumSounds]; // click / wall / wood / ball / applause / coin
diff --git a/engines/nancy/action/puzzle/minigolfpuzzle.cpp b/engines/nancy/action/puzzle/minigolfpuzzle.cpp
index 085f2d5e480..e530b4b00f9 100644
--- a/engines/nancy/action/puzzle/minigolfpuzzle.cpp
+++ b/engines/nancy/action/puzzle/minigolfpuzzle.cpp
@@ -615,7 +615,7 @@ void MinigolfPuzzle::updateBall() {
_sunkTime = now;
playSoundBlock(cup._sound);
- _winScene.sceneID = cup.specialEffectId;
+ _solveScene._sceneChange.sceneID = cup.specialEffectId;
if (cup.type == kZoneSceneChange && cup.tailId != -1) {
NancySceneState.setEventFlag(cup.tailId, cup.tailFlag ? g_nancy->_true : g_nancy->_false);
}
@@ -661,11 +661,11 @@ void MinigolfPuzzle::execute() {
// zone's special effect is the fade that covers the change, so start it just
// before the scene change (it captures the current frame, then dissolves to
// the new scene).
- if (_solved && _winScene.sceneID >= 1000 && _winScene.sceneID != kNoScene) {
+ if (_solved && _solveScene._sceneChange.sceneID >= 1000 && _solveScene._sceneChange.sceneID != kNoScene) {
if (_winHasFade) {
NancySceneState.specialEffect(_winFadeType, _winFadeTotalTime, _winFadeToBlackTime, _winFadeRect);
}
- NancySceneState.changeScene(_winScene);
+ NancySceneState.changeScene(_solveScene._sceneChange);
}
finishExecution();
break;
diff --git a/engines/nancy/action/puzzle/minigolfpuzzle.h b/engines/nancy/action/puzzle/minigolfpuzzle.h
index 85815382d96..325045829e9 100644
--- a/engines/nancy/action/puzzle/minigolfpuzzle.h
+++ b/engines/nancy/action/puzzle/minigolfpuzzle.h
@@ -22,7 +22,7 @@
#ifndef NANCY_ACTION_MINIGOLFPUZZLE_H
#define NANCY_ACTION_MINIGOLFPUZZLE_H
-#include "engines/nancy/action/actionrecord.h"
+#include "engines/nancy/action/puzzlerecord.h"
#include "engines/nancy/action/actionzone.h"
#include "engines/nancy/commontypes.h"
@@ -34,9 +34,9 @@ namespace Action {
// golf club (angle + power) to putt it around a brick-walled course into the hole.
// Derives from the shared Nancy12 PuzzleBase layout (header + frame rects + two
// sound blocks + ActionZone array), see ActionZone.
-class MinigolfPuzzle : public RenderActionRecord {
+class MinigolfPuzzle : public PuzzleRecord {
public:
- MinigolfPuzzle() : RenderActionRecord(7) {}
+ MinigolfPuzzle() : PuzzleRecord(7) {}
virtual ~MinigolfPuzzle() {}
void init() override;
@@ -85,7 +85,6 @@ protected:
// A hole can have several cups, each with its own target scene/flag (e.g. hole
// 4a's middle cup plays a cutscene). Set from the cup the ball actually drops in.
- SceneChangeDescription _winScene;
bool _winHasFade = false; // the cup's fade, played over the scene change
byte _winFadeType = 0;
uint16 _winFadeTotalTime = 0;
diff --git a/engines/nancy/action/puzzle/mirrorlightpuzzle.h b/engines/nancy/action/puzzle/mirrorlightpuzzle.h
index b2ad35d7c34..9810476e8ec 100644
--- a/engines/nancy/action/puzzle/mirrorlightpuzzle.h
+++ b/engines/nancy/action/puzzle/mirrorlightpuzzle.h
@@ -22,7 +22,7 @@
#ifndef NANCY_ACTION_MIRRORLIGHTPUZZLE_H
#define NANCY_ACTION_MIRRORLIGHTPUZZLE_H
-#include "engines/nancy/action/actionrecord.h"
+#include "engines/nancy/action/puzzlerecord.h"
#include "engines/nancy/commontypes.h"
#include "engines/nancy/action/actionzone.h"
@@ -32,9 +32,9 @@ namespace Action {
// Light-reflection puzzle introduced in Nancy12 (AR 163). The player turns a set
// of mirrors within their angle limits to route a beam of light from a source to
// a target zone.
-class MirrorLightPuzzle : public RenderActionRecord {
+class MirrorLightPuzzle : public PuzzleRecord {
public:
- MirrorLightPuzzle() : RenderActionRecord(7) {}
+ MirrorLightPuzzle() : PuzzleRecord(7) {}
virtual ~MirrorLightPuzzle() {}
void init() override;
diff --git a/engines/nancy/action/puzzle/mouselightpuzzle.h b/engines/nancy/action/puzzle/mouselightpuzzle.h
index b91d0370cae..ea0339f0fa8 100644
--- a/engines/nancy/action/puzzle/mouselightpuzzle.h
+++ b/engines/nancy/action/puzzle/mouselightpuzzle.h
@@ -22,7 +22,7 @@
#ifndef NANCY_ACTION_MOUSELIGHTPUZZLE_H
#define NANCY_ACTION_MOUSELIGHTPUZZLE_H
-#include "engines/nancy/action/actionrecord.h"
+#include "engines/nancy/action/puzzlerecord.h"
namespace Nancy {
namespace Action {
@@ -33,9 +33,9 @@ namespace Action {
// TODO: Optimize blitting; currently, the whole screen is redrawn
// TODO: Add noise to the circle mask; there are artifacts at low brightness
-class MouseLightPuzzle : public RenderActionRecord {
+class MouseLightPuzzle : public PuzzleRecord {
public:
- MouseLightPuzzle() : RenderActionRecord(10) {}
+ MouseLightPuzzle() : PuzzleRecord(10) {}
virtual ~MouseLightPuzzle() {}
void init() override;
diff --git a/engines/nancy/action/puzzle/multibuildpuzzle.cpp b/engines/nancy/action/puzzle/multibuildpuzzle.cpp
index 46eb26d0fd0..d85ff73834d 100644
--- a/engines/nancy/action/puzzle/multibuildpuzzle.cpp
+++ b/engines/nancy/action/puzzle/multibuildpuzzle.cpp
@@ -257,12 +257,12 @@ void MultiBuildPuzzle::readData(Common::SeekableReadStream &stream) {
_exitCursorID1 = stream.readSint16LE();
readFlag(stream, _submitScene._flag);
- _cancelScene._sceneChange.readData(stream);
+ _exitScene._sceneChange.readData(stream);
stream.skip(2);
readRect(stream, _exitHotspot2);
_exitCursorID2 = stream.readSint16LE();
- readFlag(stream, _cancelScene._flag);
+ readFlag(stream, _exitScene._flag);
return;
}
@@ -277,12 +277,12 @@ void MultiBuildPuzzle::readData(Common::SeekableReadStream &stream) {
stream.read(textBuf, 200);
assembleTextLine(textBuf, _solveText, 200);
- _cancelScene.readData(stream);
+ _exitScene.readData(stream);
readRect(stream, _exitHotspot);
readRect(stream, _exitHotspot2);
- _minCountFlag = _cancelScene._flag;
+ _minCountFlag = _exitScene._flag;
}
void MultiBuildPuzzle::execute() {
@@ -400,11 +400,11 @@ void MultiBuildPuzzle::execute() {
NancySceneState.setEventFlag(_submitScene._flag);
NancySceneState.changeScene(_submitScene._sceneChange);
} else if (_isCancelled) {
- NancySceneState.changeScene(_cancelScene._sceneChange);
+ NancySceneState.changeScene(_exitScene._sceneChange);
// Cancel flag is only set if at least one piece was placed (or
// spawned). For sandwich (all counter pieces) the spawn delta is
// what trips the gate when a bad ingredient was placed.
- if (_cancelScene._flag.label != kFlagNoLabel) {
+ if (_exitScene._flag.label != kFlagNoLabel) {
uint16 count = 0;
for (uint i = 0; i < _numPieces; ++i) {
if (_pieces[i]->isPlaced && _pieces[i]->counterByte == 0)
@@ -412,11 +412,10 @@ void MultiBuildPuzzle::execute() {
}
count += (uint16)(_pieces.size() - _numPieces);
if (count > 0)
- NancySceneState.setEventFlag(_cancelScene._flag);
+ NancySceneState.setEventFlag(_exitScene._flag);
}
} else {
- NancySceneState.setEventFlag(_solveScene._flag);
- NancySceneState.changeScene(_solveScene._sceneChange);
+ _solveScene.execute();
}
finishExecution();
break;
diff --git a/engines/nancy/action/puzzle/multibuildpuzzle.h b/engines/nancy/action/puzzle/multibuildpuzzle.h
index cfa1444662f..0e9cbd0a658 100644
--- a/engines/nancy/action/puzzle/multibuildpuzzle.h
+++ b/engines/nancy/action/puzzle/multibuildpuzzle.h
@@ -22,7 +22,7 @@
#ifndef NANCY_ACTION_MULTIBUILDPUZZLE_H
#define NANCY_ACTION_MULTIBUILDPUZZLE_H
-#include "engines/nancy/action/actionrecord.h"
+#include "engines/nancy/action/puzzlerecord.h"
#include "engines/nancy/cursor.h"
#include "engines/nancy/renderobject.h"
@@ -37,9 +37,9 @@ namespace Action {
// are bad and lead to food poisoning (win condition is checked on exit)
// - sand castle building: free placement of sand pieces (no win condition)
// - Nancy 13 burger counter: assemble an order, then ring it up at a hotspot
-class MultiBuildPuzzle : public RenderActionRecord {
+class MultiBuildPuzzle : public PuzzleRecord {
public:
- MultiBuildPuzzle() : RenderActionRecord(7) {}
+ MultiBuildPuzzle() : PuzzleRecord(7) {}
virtual ~MultiBuildPuzzle();
void init() override;
@@ -141,13 +141,10 @@ protected:
int16 _exitCursorID1 = -1; // -1: use _puzzleExitCursor
int16 _exitCursorID2 = -1;
- SceneChangeWithFlag _solveScene;
SoundDescription _solveSound;
Common::String _solveTextKey; // Looked up in CONVO chunk first
Common::String _solveText; // Raw fallback used if key missing
- SceneChangeWithFlag _cancelScene;
-
// "Enough pieces placed" flag; its own field in Nancy 13, the cancel scene's before.
FlagDescription _minCountFlag;
@@ -158,7 +155,6 @@ protected:
Common::String _submitTextKey;
Common::String _submitText;
- Common::Rect _exitHotspot;
Common::Rect _exitHotspot2;
Common::Rect _targetZone; // Valid drop area (drawer/plate/...)
diff --git a/engines/nancy/action/puzzle/necklacepuzzle.cpp b/engines/nancy/action/puzzle/necklacepuzzle.cpp
index 194be940a3c..ddd5efb6635 100644
--- a/engines/nancy/action/puzzle/necklacepuzzle.cpp
+++ b/engines/nancy/action/puzzle/necklacepuzzle.cpp
@@ -131,11 +131,11 @@ void NecklacePuzzle::readData(Common::SeekableReadStream &stream) {
_putDownSound.readData(stream);
_unknownSound.readData(stream);
- _solvedScene.sceneID = stream.readUint16LE();
- _solvedScene.frameID = stream.readUint16LE();
+ _solveScene._sceneChange.sceneID = stream.readUint16LE();
+ _solveScene._sceneChange.frameID = stream.readUint16LE();
int16 solvedOffset = stream.readSint16LE();
- _solvedScene.verticalOffset = solvedOffset >= 0 ? solvedOffset : 0;
- _solvedScene.continueSceneSound = stream.readByte();
+ _solveScene._sceneChange.verticalOffset = solvedOffset >= 0 ? solvedOffset : 0;
+ _solveScene._sceneChange.continueSceneSound = stream.readByte();
_solvedSound.readData(stream);
_unsolvedScene.sceneID = stream.readUint16LE();
@@ -145,7 +145,7 @@ void NecklacePuzzle::readData(Common::SeekableReadStream &stream) {
_unsolvedScene.continueSceneSound = stream.readByte();
_unsolvedSound.readData(stream);
- readExitHotspot(stream, _exitHotspot, _exitCursorType, _exitScene, _exitFlag);
+ readExitHotspot(stream);
}
void NecklacePuzzle::init() {
@@ -466,13 +466,13 @@ void NecklacePuzzle::execute() {
if (_solved) {
playSoundBlock(_solvedSound);
- if (_solvedScene.sceneID != kNoScene) {
- NancySceneState.changeScene(_solvedScene);
+ if (_solveScene._sceneChange.sceneID != kNoScene) {
+ NancySceneState.changeScene(_solveScene._sceneChange);
}
} else {
playSoundBlock(_unsolvedSound);
- NancySceneState.setEventFlag(_exitFlag);
- NancySceneState.changeScene(_unsolvedScene.sceneID != kNoScene ? _unsolvedScene : _exitScene);
+ NancySceneState.setEventFlag(_exitScene._flag);
+ NancySceneState.changeScene(_unsolvedScene.sceneID != kNoScene ? _unsolvedScene : _exitScene._sceneChange);
}
finishExecution();
@@ -562,8 +562,7 @@ void NecklacePuzzle::handleInput(NancyInput &input) {
return;
}
- if (!_exitHotspot.isEmpty() && _exitHotspot.contains(mouseVP)) {
- g_nancy->_cursor->setCursorType((CursorManager::CursorType)_exitCursorType, true, false);
+ if (hoverExitHotspot(input)) {
if (click) {
_exitRequested = true;
}
diff --git a/engines/nancy/action/puzzle/necklacepuzzle.h b/engines/nancy/action/puzzle/necklacepuzzle.h
index 8bbc6a85da8..09ed64d9ec5 100644
--- a/engines/nancy/action/puzzle/necklacepuzzle.h
+++ b/engines/nancy/action/puzzle/necklacepuzzle.h
@@ -23,7 +23,7 @@
#define NANCY_ACTION_NECKLACEPUZZLE_H
#include "engines/nancy/commontypes.h"
-#include "engines/nancy/action/actionrecord.h"
+#include "engines/nancy/action/puzzlerecord.h"
#include "engines/nancy/misc/mousefollow.h"
namespace Nancy {
@@ -38,9 +38,9 @@ namespace Action {
// How many of each shell are left is not kept in the record; it lives in the
// shared table values, so the box counts survive leaving and re-entering. Shells
// left on a strand are handed back when the puzzle is abandoned unsolved.
-class NecklacePuzzle : public RenderActionRecord {
+class NecklacePuzzle : public PuzzleRecord {
public:
- NecklacePuzzle() : RenderActionRecord(7) {}
+ NecklacePuzzle() : PuzzleRecord(7) {}
virtual ~NecklacePuzzle();
void init() override;
@@ -148,7 +148,6 @@ protected:
RandomSoundBlock _putDownSound;
RandomSoundBlock _unknownSound; // no known trigger; "NO SOUND" in the shipped record
- SceneChangeDescription _solvedScene;
RandomSoundBlock _solvedSound;
// Played when the puzzle is left unfinished. Its scene is 9999 in the shipped
@@ -156,11 +155,6 @@ protected:
SceneChangeDescription _unsolvedScene;
RandomSoundBlock _unsolvedSound;
- Common::Rect _exitHotspot;
- uint16 _exitCursorType = 0;
- SceneChangeDescription _exitScene;
- FlagDescription _exitFlag;
-
// -- Runtime state --
Common::Array<Graphics::ManagedSurface> _images;
diff --git a/engines/nancy/action/puzzle/onebuildpuzzle.cpp b/engines/nancy/action/puzzle/onebuildpuzzle.cpp
index ce1b3246fd5..40579c634bf 100644
--- a/engines/nancy/action/puzzle/onebuildpuzzle.cpp
+++ b/engines/nancy/action/puzzle/onebuildpuzzle.cpp
@@ -243,11 +243,10 @@ void OneBuildPuzzle::readDataNancy12(Common::SeekableReadStream &stream) {
if (isNancy13) {
// The give-up hotspot replaces the header's cancel scene.
- readExitHotspot(stream, _exitHotspot, _exitCursorType,
- _cancelScene._sceneChange, _cancelScene._flag);
- _cancelScene._sceneChange.continueSceneSound = kContinueSceneSound;
+ readExitHotspot(stream);
+ _exitScene._sceneChange.continueSceneSound = kContinueSceneSound;
} else {
- _cancelScene.readData(stream); // 0x1e8 (ends the 513-byte blob)
+ _exitScene.readData(stream); // 0x1e8 (ends the 513-byte blob)
}
// --- Random-sound blocks: pickup, rotate, drop, good, bad, completion, close-up ---
@@ -443,7 +442,7 @@ void OneBuildPuzzle::readData(Common::SeekableReadStream &stream) {
stream.read(textBuf, 200);
_completionText = resolveSubtitleText(completionKey);
- _cancelScene.readData(stream);
+ _exitScene.readData(stream);
readRect(stream, _exitHotspot);
}
@@ -517,10 +516,9 @@ void OneBuildPuzzle::execute() {
break;
case kActionTrigger:
if (_isCancelled) {
- _cancelScene.execute();
+ _exitScene.execute();
} else {
- NancySceneState.setEventFlag(_solveScene._flag);
- NancySceneState.changeScene(_solveScene._sceneChange);
+ _solveScene.execute();
}
break;
}
@@ -777,12 +775,7 @@ void OneBuildPuzzle::handleInput(NancyInput &input) {
return;
// Check exit hotspot
- Common::Rect exitScreen = NancySceneState.getViewport().convertViewportToScreen(_exitHotspot);
- if (exitScreen.contains(input.mousePos)) {
- if (_exitCursorType != 0)
- g_nancy->_cursor->setCursorType((CursorManager::CursorType)_exitCursorType, true, false);
- else
- g_nancy->_cursor->setCursorType(g_nancy->_cursor->_puzzleExitCursor);
+ if (hoverExitHotspot(input)) {
if (input.input & NancyInput::kLeftMouseButtonUp) {
_isCancelled = true;
_state = kActionTrigger;
diff --git a/engines/nancy/action/puzzle/onebuildpuzzle.h b/engines/nancy/action/puzzle/onebuildpuzzle.h
index 911f07c95d0..48c4b6ddb77 100644
--- a/engines/nancy/action/puzzle/onebuildpuzzle.h
+++ b/engines/nancy/action/puzzle/onebuildpuzzle.h
@@ -22,7 +22,7 @@
#ifndef NANCY_ACTION_ONEBUILDPUZZLE_H
#define NANCY_ACTION_ONEBUILDPUZZLE_H
-#include "engines/nancy/action/actionrecord.h"
+#include "engines/nancy/action/puzzlerecord.h"
#include "engines/nancy/renderobject.h"
namespace Nancy {
@@ -33,9 +33,9 @@ namespace Action {
// Left-clicking an unplaced piece picks it up; right-clicking any piece rotates it.
// If a piece is dropped (left-click) near its correct slot with correct rotation, it snaps in.
// Otherwise it returns to its previous position (or home in free placement mode).
-class OneBuildPuzzle : public RenderActionRecord {
+class OneBuildPuzzle : public PuzzleRecord {
public:
- OneBuildPuzzle() : RenderActionRecord(7), _finalAnimOverlay(99), _counterDisplay(99), _closeupDisplay(99) {}
+ OneBuildPuzzle() : PuzzleRecord(7), _finalAnimOverlay(99), _counterDisplay(99), _closeupDisplay(99) {}
virtual ~OneBuildPuzzle() {}
void init() override;
@@ -204,18 +204,11 @@ protected:
Common::String _badAlt2Filename;
Common::Array<Common::String> _badTexts; // 3 entries
- SceneChangeWithFlag _solveScene;
SoundDescription _completionSound;
Common::String _completionText;
SoundDescription _closeupSound;
- SceneChangeWithFlag _cancelScene;
- Common::Rect _exitHotspot;
- // Nancy13 stores this in the exit hotspot record; earlier games use
- // _puzzleExitCursor.
- uint16 _exitCursorType = 0;
-
// --- Runtime state ---
Graphics::ManagedSurface _image;
diff --git a/engines/nancy/action/puzzle/orderingpuzzle.cpp b/engines/nancy/action/puzzle/orderingpuzzle.cpp
index 9850584683e..556cbefb3b9 100644
--- a/engines/nancy/action/puzzle/orderingpuzzle.cpp
+++ b/engines/nancy/action/puzzle/orderingpuzzle.cpp
@@ -218,12 +218,12 @@ void OrderingPuzzle::readData(Common::SeekableReadStream &stream) {
}
if (ser.getVersion() == kGameTypeVampire) {
- _solveExitScene._sceneChange.readData(stream, true);
+ _solveScene._sceneChange.readData(stream, true);
ser.skip(2); // shouldStopRendering
- ser.syncAsSint16LE(_solveExitScene._flag.label);
- ser.syncAsByte(_solveExitScene._flag.flag);
+ ser.syncAsSint16LE(_solveScene._flag.label);
+ ser.syncAsByte(_solveScene._flag.flag);
} else {
- _solveExitScene.readData(stream);
+ _solveScene.readData(stream);
}
ser.syncAsUint16LE(_solveSoundDelay);
@@ -327,11 +327,11 @@ void OrderingPuzzle::readData(Common::SeekableReadStream &stream) {
// to gain the needed token to proceed.
// TODO: What is the correct way to handle this?
if (g_nancy->getGameType() == kGameTypeNancy11 && advanceSceneID == 2721 &&
- _solveExitScene._sceneChange.sceneID == 2720)
+ _solveScene._sceneChange.sceneID == 2720)
advanceSceneID = 2720;
if (advanceSceneID != 0 && advanceSceneID != kNoScene) {
- _solveExitScene._sceneChange.sceneID = advanceSceneID;
+ _solveScene._sceneChange.sceneID = advanceSceneID;
}
} else if (g_nancy->getGameType() >= kGameTypeNancy12) {
stream.skip(2); // advance scene
@@ -697,9 +697,9 @@ void OrderingPuzzle::execute() {
// The flag is only set here: setting it as soon as the solution is entered can
// invalidate this record's own dependencies, which stops it from being executed
// again before it ever reaches this point.
- _solveExitScene.execute();
+ _solveScene.execute();
} else {
- NancySceneState.changeScene(_solveExitScene._sceneChange);
+ NancySceneState.changeScene(_solveScene._sceneChange);
}
finishExecution();
@@ -724,7 +724,7 @@ void OrderingPuzzle::handleInput(NancyInput &input) {
}
}
- if (NancySceneState.getViewport().convertViewportToScreen(_exitHotspot).contains(input.mousePos)) {
+ if (isExitHotspotHovered(input)) {
setHoverCursor(_exitCursorID, g_nancy->_cursor->_puzzleExitCursor);
if (canClick && input.input & NancyInput::kLeftMouseButtonUp) {
diff --git a/engines/nancy/action/puzzle/orderingpuzzle.h b/engines/nancy/action/puzzle/orderingpuzzle.h
index 4ea568af399..90628314939 100644
--- a/engines/nancy/action/puzzle/orderingpuzzle.h
+++ b/engines/nancy/action/puzzle/orderingpuzzle.h
@@ -22,7 +22,7 @@
#ifndef NANCY_ACTION_ORDERINGPUZZLE_H
#define NANCY_ACTION_ORDERINGPUZZLE_H
-#include "engines/nancy/action/actionrecord.h"
+#include "engines/nancy/action/puzzlerecord.h"
namespace Nancy {
namespace Action {
@@ -36,11 +36,11 @@ namespace Action {
// - KeypadPuzzle: Buttons may auto-depress, stay down, and can be depressed manually by player.
// Adds an optional button for manually checking for correct solution, number of possible buttons is 30.
// - KeypadPuzzleTerse: Same as above, but data format is shorter, and supports up to 100 buttons
-class OrderingPuzzle : public RenderActionRecord {
+class OrderingPuzzle : public PuzzleRecord {
public:
enum SolveState { kNotSolved, kPlaySound, kWaitForSound, kStageBlink };
enum PuzzleType { kOrdering, kPiano, kOrderItems, kKeypad, kKeypadTerse };
- OrderingPuzzle(PuzzleType type) : RenderActionRecord(7), _puzzleType(type) {}
+ OrderingPuzzle(PuzzleType type) : PuzzleRecord(7), _puzzleType(type) {}
virtual ~OrderingPuzzle() {}
void init() override;
@@ -125,11 +125,8 @@ protected:
SoundDescription _itemSound;
SoundDescription _popUpSound;
- SceneChangeWithFlag _solveExitScene;
uint16 _solveSoundDelay = 0;
SoundDescription _solveSound;
- SceneChangeWithFlag _exitScene;
- Common::Rect _exitHotspot;
SolveState _solveState = kNotSolved;
Graphics::ManagedSurface _image;
diff --git a/engines/nancy/action/puzzle/overridelockpuzzle.cpp b/engines/nancy/action/puzzle/overridelockpuzzle.cpp
index 94590f376a9..51879096ebb 100644
--- a/engines/nancy/action/puzzle/overridelockpuzzle.cpp
+++ b/engines/nancy/action/puzzle/overridelockpuzzle.cpp
@@ -67,7 +67,7 @@ void OverrideLockPuzzle::readData(Common::SeekableReadStream &stream) {
_buttonPopTime = stream.readUint16LE();
- _solveExitScene.readData(stream);
+ _solveScene.readData(stream);
_solveSound.readNormal(stream);
_exitScene.readData(stream);
@@ -154,7 +154,7 @@ void OverrideLockPuzzle::execute() {
return;
}
- _solveExitScene.execute();
+ _solveScene.execute();
g_nancy->_sound->stopSound(_solveSound);
}
@@ -170,9 +170,7 @@ void OverrideLockPuzzle::handleInput(NancyInput &input) {
}
// Check the exit hotspot
- if (NancySceneState.getViewport().convertViewportToScreen(_exitHotspot).contains(input.mousePos)) {
- g_nancy->_cursor->setCursorType(g_nancy->_cursor->_puzzleExitCursor);
-
+ if (hoverExitHotspot(input)) {
if (input.input & NancyInput::kLeftMouseButtonUp) {
_state = kActionTrigger;
}
diff --git a/engines/nancy/action/puzzle/overridelockpuzzle.h b/engines/nancy/action/puzzle/overridelockpuzzle.h
index 021d0799331..db3d8160311 100644
--- a/engines/nancy/action/puzzle/overridelockpuzzle.h
+++ b/engines/nancy/action/puzzle/overridelockpuzzle.h
@@ -22,12 +22,12 @@
#ifndef NANCY_ACTION_OVERRIDELOCKPUZZLE_H
#define NANCY_ACTION_OVERRIDELOCKPUZZLE_H
-#include "engines/nancy/action/actionrecord.h"
+#include "engines/nancy/action/puzzlerecord.h"
namespace Nancy {
namespace Action {
-class OverrideLockPuzzle : public RenderActionRecord {
+class OverrideLockPuzzle : public PuzzleRecord {
public:
static const byte kButtonsStayDown = 1;
static const byte kButtonsPopUp = 2;
@@ -35,7 +35,7 @@ public:
static const byte kLightsCircular = 3;
static const byte kLightsRandom = 4;
- OverrideLockPuzzle() : RenderActionRecord(7) {}
+ OverrideLockPuzzle() : PuzzleRecord(7) {}
virtual ~OverrideLockPuzzle() {}
void init() override;
@@ -69,12 +69,8 @@ protected:
Time _buttonPopTime;
- SceneChangeWithFlag _solveExitScene;
SoundDescription _solveSound;
- SceneChangeWithFlag _exitScene;
- Common::Rect _exitHotspot;
-
Graphics::ManagedSurface _image;
Common::Array<byte> _buttonOrder;
diff --git a/engines/nancy/action/puzzle/pachinkopuzzle.cpp b/engines/nancy/action/puzzle/pachinkopuzzle.cpp
index 139d56e1458..876e4021013 100644
--- a/engines/nancy/action/puzzle/pachinkopuzzle.cpp
+++ b/engines/nancy/action/puzzle/pachinkopuzzle.cpp
@@ -108,7 +108,7 @@ void PachinkoPuzzle::readData(Common::SeekableReadStream &stream) {
readActionZoneArray(stream, _zones, true);
// The base trailer's hotspot records; the first is the give-up exit.
- readExitHotspot(stream, _exitHotspot, _exitCursorType, _exitScene, _exitFlag);
+ readExitHotspot(stream);
}
void PachinkoPuzzle::readMachine(Common::SeekableReadStream &stream, Machine &m) {
@@ -573,8 +573,7 @@ void PachinkoPuzzle::execute() {
NancySceneState.setEventFlag(_activeMachine->resultFlag);
NancySceneState.changeScene(_activeMachine->resultScene);
} else {
- NancySceneState.setEventFlag(_exitFlag);
- NancySceneState.changeScene(_exitScene);
+ _exitScene.execute();
}
finishExecution();
break;
@@ -612,9 +611,7 @@ void PachinkoPuzzle::handleInput(NancyInput &input) {
return;
}
- if (!_exitHotspot.isEmpty() &&
- NancySceneState.getViewport().convertViewportToScreen(_exitHotspot).contains(input.mousePos)) {
- setDataCursor(_exitCursorType, false);
+ if (hoverExitHotspot(input)) {
if (click) {
_exitRequested = true;
}
diff --git a/engines/nancy/action/puzzle/pachinkopuzzle.h b/engines/nancy/action/puzzle/pachinkopuzzle.h
index fa55b8ad901..1d3f8a5856b 100644
--- a/engines/nancy/action/puzzle/pachinkopuzzle.h
+++ b/engines/nancy/action/puzzle/pachinkopuzzle.h
@@ -24,7 +24,7 @@
#include "engines/nancy/commontypes.h"
#include "engines/nancy/movieplayer.h"
-#include "engines/nancy/action/actionrecord.h"
+#include "engines/nancy/action/puzzlerecord.h"
#include "engines/nancy/action/actionzone.h"
namespace Nancy {
@@ -37,9 +37,9 @@ namespace Action {
// zones, until it drops into one of four holes. Each hole feeds one of two climbers racing
// up the mountain to the pot: the Miner (a win) or the Yeti (a loss). The first to reach
// the pot plays its result animation, then exits through its own scene and event flag.
-class PachinkoPuzzle : public RenderActionRecord {
+class PachinkoPuzzle : public PuzzleRecord {
public:
- PachinkoPuzzle() : RenderActionRecord(7) {}
+ PachinkoPuzzle() : PuzzleRecord(7) {}
virtual ~PachinkoPuzzle() {}
void init() override;
@@ -140,12 +140,6 @@ protected:
Common::Array<ActionZone> _zones; // bumpers / walls / overlays
Common::Array<Hole> _holes; // the four catch holes (built from _zones)
- // The give-up / exit hotspot.
- Common::Rect _exitHotspot;
- uint16 _exitCursorType = 0;
- SceneChangeDescription _exitScene;
- FlagDescription _exitFlag; // set on give-up
-
// -- Runtime state --
enum State {
kRunning, // launcher live, balls in flight
diff --git a/engines/nancy/action/puzzle/paintpuzzle.h b/engines/nancy/action/puzzle/paintpuzzle.h
index 0a6b287b05c..c4f991e9a4d 100644
--- a/engines/nancy/action/puzzle/paintpuzzle.h
+++ b/engines/nancy/action/puzzle/paintpuzzle.h
@@ -24,7 +24,7 @@
#include "engines/nancy/commontypes.h"
#include "engines/nancy/util.h"
-#include "engines/nancy/action/actionrecord.h"
+#include "engines/nancy/action/puzzlerecord.h"
namespace Nancy {
namespace Action {
@@ -35,9 +35,9 @@ namespace Action {
// its target color. A filled region is its shape recolored to the chosen color.
// Nancy15 adds per-color objects (paint jars) drawn at the swatches, per-color
// event flags, order-independent solutions and single-paint regions.
-class PaintPuzzle : public RenderActionRecord {
+class PaintPuzzle : public PuzzleRecord {
public:
- PaintPuzzle() : RenderActionRecord(7) {}
+ PaintPuzzle() : PuzzleRecord(7) {}
virtual ~PaintPuzzle() {}
void init() override;
@@ -111,7 +111,6 @@ protected:
RandomSoundBlock _sounds[2]; // 0xa4/0xfa
- SceneChangeWithFlag _solveScene; // 0x1a6
RandomSoundBlock _solveSound; // 0x150, plays before the solve scene change
Common::Array<ExitHotspot> _exitHotspots;
diff --git a/engines/nancy/action/puzzle/passwordpuzzle.cpp b/engines/nancy/action/puzzle/passwordpuzzle.cpp
index 66fc2170237..4f71ac3910a 100644
--- a/engines/nancy/action/puzzle/passwordpuzzle.cpp
+++ b/engines/nancy/action/puzzle/passwordpuzzle.cpp
@@ -84,7 +84,7 @@ void PasswordPuzzle::readData(Common::SeekableReadStream &stream) {
_maxStringLength = g_nancy->getGameType() < kGameTypeNancy6 ? 12 : 31;
- _solveExitScene.readData(stream);
+ _solveScene.readData(stream);
_solveSound.readNormal(stream);
_failExitScene.readData(stream);
_failSound.readNormal(stream);
@@ -188,7 +188,7 @@ void PasswordPuzzle::execute() {
_failExitScene.execute();
break;
case kSolved:
- _solveExitScene.execute();
+ _solveScene.execute();
break;
}
@@ -199,7 +199,7 @@ void PasswordPuzzle::execute() {
void PasswordPuzzle::onPause(bool paused) {
g_nancy->_input->setVKEnabled(!paused);
- RenderActionRecord::onPause(paused);
+ PuzzleRecord::onPause(paused);
}
void PasswordPuzzle::handleInput(NancyInput &input) {
@@ -207,9 +207,7 @@ void PasswordPuzzle::handleInput(NancyInput &input) {
return;
}
- if (NancySceneState.getViewport().convertViewportToScreen(_exitHotspot).contains(input.mousePos)) {
- g_nancy->_cursor->setCursorType(g_nancy->_cursor->_puzzleExitCursor);
-
+ if (hoverExitHotspot(input)) {
if (input.input & NancyInput::kLeftMouseButtonUp) {
_state = kActionTrigger;
}
diff --git a/engines/nancy/action/puzzle/passwordpuzzle.h b/engines/nancy/action/puzzle/passwordpuzzle.h
index af7fa8690b4..002b1e21a00 100644
--- a/engines/nancy/action/puzzle/passwordpuzzle.h
+++ b/engines/nancy/action/puzzle/passwordpuzzle.h
@@ -22,15 +22,15 @@
#ifndef NANCY_ACTION_PASSWORDPUZZLE_H
#define NANCY_ACTION_PASSWORDPUZZLE_H
-#include "engines/nancy/action/actionrecord.h"
+#include "engines/nancy/action/puzzlerecord.h"
namespace Nancy {
namespace Action {
-class PasswordPuzzle : public RenderActionRecord {
+class PasswordPuzzle : public PuzzleRecord {
public:
enum SolveState { kNotSolved, kFailed, kSolved };
- PasswordPuzzle() : RenderActionRecord(7) {}
+ PasswordPuzzle() : PuzzleRecord(7) {}
virtual ~PasswordPuzzle();
void init() override;
@@ -47,12 +47,9 @@ public:
// _screenPosition 0x24
Common::Array<Common::String> _names;
Common::Array<Common::String> _passwords;
- SceneChangeWithFlag _solveExitScene;
SoundDescription _solveSound;
SceneChangeWithFlag _failExitScene;
SoundDescription _failSound;
- SceneChangeWithFlag _exitScene;
- Common::Rect _exitHotspot;
Common::String _playerNameInput;
Common::String _playerPasswordInput;
diff --git a/engines/nancy/action/puzzle/peepholepuzzle.cpp b/engines/nancy/action/puzzle/peepholepuzzle.cpp
index 3fc832aefee..981ff11fcb2 100644
--- a/engines/nancy/action/puzzle/peepholepuzzle.cpp
+++ b/engines/nancy/action/puzzle/peepholepuzzle.cpp
@@ -107,9 +107,7 @@ void PeepholePuzzle::handleInput(NancyInput &input) {
bool justReleased = false;
- if (NancySceneState.getViewport().convertViewportToScreen(_exitHotspot).contains(input.mousePos)) {
- g_nancy->_cursor->setCursorType(g_nancy->_cursor->_puzzleExitCursor);
-
+ if (hoverExitHotspot(input)) {
if (input.input & NancyInput::kLeftMouseButtonUp) {
_state = kActionTrigger;
}
diff --git a/engines/nancy/action/puzzle/peepholepuzzle.h b/engines/nancy/action/puzzle/peepholepuzzle.h
index 8ed36073230..985ef22ad3d 100644
--- a/engines/nancy/action/puzzle/peepholepuzzle.h
+++ b/engines/nancy/action/puzzle/peepholepuzzle.h
@@ -23,15 +23,16 @@
#define NANCY_ACTION_PEEPHOLEPUZZLE_H
#include "engines/nancy/action/autotext.h"
+#include "engines/nancy/action/puzzlerecord.h"
namespace Nancy {
namespace Action {
// Action record that, despite what its name suggests, is mostly used
// to render Nancy's diary in nancy6 and up.
-class PeepholePuzzle : public RenderActionRecord {
+class PeepholePuzzle : public PuzzleRecord {
public:
- PeepholePuzzle() : RenderActionRecord(7) {}
+ PeepholePuzzle() : PuzzleRecord(7) {}
virtual ~PeepholePuzzle() {}
void init() override;
@@ -64,9 +65,6 @@ protected:
byte _pixelsToScroll = 0;
- SceneChangeWithFlag _exitScene;
- Common::Rect _exitHotspot;
-
Graphics::ManagedSurface _innerImage;
Graphics::ManagedSurface _buttonsImage;
diff --git a/engines/nancy/action/puzzle/pegspuzzle.cpp b/engines/nancy/action/puzzle/pegspuzzle.cpp
index 189dbe6181c..5ce90fb4a27 100644
--- a/engines/nancy/action/puzzle/pegspuzzle.cpp
+++ b/engines/nancy/action/puzzle/pegspuzzle.cpp
@@ -48,9 +48,9 @@ void PegsPuzzle::readData(Common::SeekableReadStream &stream) {
// Win / lose scene changes, each {uint16 sceneID, uint16 frameID, byte}. A frameID of
// 0xffff means "no specific frame" (the target scene may be a video, so seeking to
// 65535 must be avoided) - keep the default frame 0.
- _winScene.sceneID = stream.readUint16LE(); // 0x28
+ _solveScene._sceneChange.sceneID = stream.readUint16LE(); // 0x28
uint16 winFrame = stream.readUint16LE(); // 0x2a
- _winScene.frameID = (winFrame == 0xffff) ? 0 : winFrame;
+ _solveScene._sceneChange.frameID = (winFrame == 0xffff) ? 0 : winFrame;
stream.skip(1); // 0x2c
_loseScene.sceneID = stream.readUint16LE(); // 0x2d
uint16 loseFrame = stream.readUint16LE(); // 0x2f
@@ -76,7 +76,7 @@ void PegsPuzzle::readData(Common::SeekableReadStream &stream) {
// A count-prefixed array of fixed 23-byte hotspot records:
// {rect, u16 cursorType, u16 sceneID, u16 frameID, byte}. The sample carries one - the
// "give up / exit" hotspot (leave the puzzle unsolved), with the exit cursor type.
- readExitHotspot(stream, _exitHotspot, _exitCursorType, _exitScene, _exitFlag);
+ readExitHotspot(stream);
// Five random-sound blocks: [0] peg select, [1] jump, [2] selection pulse, [3] win, [4] lose.
_sounds.resize(5);
@@ -337,10 +337,9 @@ void PegsPuzzle::execute() {
}
case kActionTrigger: {
if (_exitRequested) {
- NancySceneState.setEventFlag(_exitFlag);
- NancySceneState.changeScene(_exitScene);
+ _exitScene.execute();
} else {
- NancySceneState.changeScene(_solved ? _winScene : _loseScene);
+ NancySceneState.changeScene(_solved ? _solveScene._sceneChange : _loseScene);
}
finishExecution();
@@ -393,9 +392,7 @@ void PegsPuzzle::handleInput(NancyInput &input) {
return;
}
- if (!_exitHotspot.isEmpty() &&
- NancySceneState.getViewport().convertViewportToScreen(_exitHotspot).contains(input.mousePos)) {
- setDataCursor(_exitCursorType, false);
+ if (hoverExitHotspot(input)) {
if (click) {
_exitRequested = true;
}
diff --git a/engines/nancy/action/puzzle/pegspuzzle.h b/engines/nancy/action/puzzle/pegspuzzle.h
index 5d36a981567..4ec57bfb075 100644
--- a/engines/nancy/action/puzzle/pegspuzzle.h
+++ b/engines/nancy/action/puzzle/pegspuzzle.h
@@ -23,7 +23,7 @@
#define NANCY_ACTION_PEGSPUZZLE_H
#include "engines/nancy/commontypes.h"
-#include "engines/nancy/action/actionrecord.h"
+#include "engines/nancy/action/puzzlerecord.h"
#include "engines/nancy/misc/mousefollow.h"
namespace Nancy {
@@ -39,9 +39,9 @@ namespace Action {
// Pegs are dragged and dropped: clicking a movable peg picks it up (the hand/drag
// cursor carries the piece) and dropping it on a hole it can reach performs the jump.
// Cell state matches the original: 0 = peg, 1 = empty hole, 2 = blocked (no hole).
-class PegsPuzzle : public RenderActionRecord {
+class PegsPuzzle : public PuzzleRecord {
public:
- PegsPuzzle() : RenderActionRecord(7) {}
+ PegsPuzzle() : PuzzleRecord(7) {}
virtual ~PegsPuzzle() {}
void init() override;
@@ -86,7 +86,6 @@ protected:
byte _startEmptyFlag = 0; // 0x25 - 0 => mark _startEmptyPos empty at init
byte _startEmptyPos = 0; // 0x26 - the initially-empty hole (usually the centre)
byte _targetPegCount = 0; // 0x27 - win when pegs remaining <= this
- SceneChangeDescription _winScene; // 0x28 - shown when solved (9999 => none)
SceneChangeDescription _loseScene; // 0x2d - shown when no move remains and unsolved
Common::Rect _pegSrc; // 0x32 - normal peg sprite (viewport image)
Common::Rect _selectedSrc; // 0x42 - highlight sprite (selected peg / target holes)
@@ -100,12 +99,6 @@ protected:
Common::Array<byte> _blockedPositions;
- // The clickable "give up / exit" hotspot (the base-class hotspot record).
- Common::Rect _exitHotspot;
- uint16 _exitCursorType = 0; // the record's leading field is its cursor type
- SceneChangeDescription _exitScene;
- FlagDescription _exitFlag; // set on give-up
-
Common::Array<RandomSoundBlock> _sounds; // 5 blocks: select / jump / pulse / win / lose
// -- Runtime state --
diff --git a/engines/nancy/action/puzzle/quizpuzzle.cpp b/engines/nancy/action/puzzle/quizpuzzle.cpp
index 04a95347b69..9a8fa2ef66c 100644
--- a/engines/nancy/action/puzzle/quizpuzzle.cpp
+++ b/engines/nancy/action/puzzle/quizpuzzle.cpp
@@ -55,7 +55,7 @@ void QuizPuzzle::init() {
setTransparent(true);
g_nancy->_input->setVKEnabled(!_isDisplayOnly);
- RenderActionRecord::init();
+ PuzzleRecord::init();
}
// ---- Nancy 8 data format ----
@@ -108,7 +108,7 @@ void QuizPuzzle::readDataNancy8(Common::SeekableReadStream &stream) {
_doneSound.readNormal(stream);
_doneText = readSubtitleText(stream);
- _cancelScene.readData(stream);
+ _exitScene.readData(stream);
// The record is a fixed 699 bytes and nothing reads this tail. Leaving it
// unread would make the action record loader mistake it for a dependency.
@@ -159,7 +159,7 @@ void QuizPuzzle::readDataNancy9(Common::SeekableReadStream &stream) {
_doneSound.readNormal(stream);
_doneText = readSubtitleText(stream);
- _cancelScene.readData(stream);
+ _exitScene.readData(stream);
readRect(stream, _exitHotspot);
uint16 correctSoundChannel = stream.readUint16LE();
@@ -269,9 +269,10 @@ void QuizPuzzle::readDataNancy15(Common::SeekableReadStream &stream) {
// records the other puzzles use, and its flag is always set to true.
readRect(stream, _exitHotspot);
_exitCursorType = stream.readUint16LE();
- _cancelScene._sceneChange.sceneID = stream.readUint16LE();
- _cancelScene._flag.label = stream.readSint16LE();
- _cancelScene._flag.flag = g_nancy->_true;
+ _exitCursorFromData = true;
+ _exitScene._sceneChange.sceneID = stream.readUint16LE();
+ _exitScene._flag.label = stream.readSint16LE();
+ _exitScene._flag.flag = g_nancy->_true;
readExitHotspots(stream, _hotspots);
@@ -761,7 +762,7 @@ void QuizPuzzle::execute() {
case kActionTrigger:
if (_cancelled) {
- _cancelScene.execute();
+ _exitScene.execute();
} else if (_solved) {
_solveScene.execute();
}
@@ -782,15 +783,8 @@ void QuizPuzzle::handleInput(NancyInput &input) {
bool mouseOverHotspot = false;
// Nancy 9+: give-up hotspot. Clicking it cancels the puzzle.
- if (g_nancy->getGameType() != kGameTypeNancy8 && !_exitHotspot.isEmpty()) {
- Common::Rect exitScreen = NancySceneState.getViewport().convertViewportToScreen(_exitHotspot);
- if (exitScreen.contains(input.mousePos)) {
- if (_exitCursorType != 0) {
- g_nancy->_cursor->setCursorType((CursorManager::CursorType)_exitCursorType, true);
- } else {
- g_nancy->_cursor->setCursorType(g_nancy->_cursor->_puzzleExitCursor);
- }
-
+ if (g_nancy->getGameType() != kGameTypeNancy8) {
+ if (hoverExitHotspot(input)) {
if (input.input & NancyInput::kLeftMouseButtonUp) {
// From Nancy 15 the give-up hotspot submits the quiz: with every
// box answered it leads to the solve scene instead
@@ -901,7 +895,7 @@ void QuizPuzzle::handleInput(NancyInput &input) {
void QuizPuzzle::onPause(bool paused) {
g_nancy->_input->setVKEnabled(!paused && !_isDisplayOnly);
- RenderActionRecord::onPause(paused);
+ PuzzleRecord::onPause(paused);
}
void QuizPuzzle::drawText() {
diff --git a/engines/nancy/action/puzzle/quizpuzzle.h b/engines/nancy/action/puzzle/quizpuzzle.h
index ca6f619a4e4..6abe185df66 100644
--- a/engines/nancy/action/puzzle/quizpuzzle.h
+++ b/engines/nancy/action/puzzle/quizpuzzle.h
@@ -22,7 +22,7 @@
#ifndef NANCY_ACTION_QUIZPUZZLE_H
#define NANCY_ACTION_QUIZPUZZLE_H
-#include "engines/nancy/action/actionrecord.h"
+#include "engines/nancy/action/puzzlerecord.h"
#include "engines/nancy/commontypes.h"
#include "engines/nancy/util.h"
@@ -32,9 +32,9 @@ namespace Action {
// Text-entry quiz with multiple text boxes. Three data formats: Nancy 8,
// Nancy 9 - Nancy 14, and Nancy 15, which rewrote the record around
// count-prefixed answer lists and RandomSoundBlocks.
-class QuizPuzzle : public RenderActionRecord {
+class QuizPuzzle : public PuzzleRecord {
public:
- QuizPuzzle() : RenderActionRecord(7) {}
+ QuizPuzzle() : PuzzleRecord(7) {}
virtual ~QuizPuzzle();
void init() override;
@@ -120,11 +120,6 @@ private:
Common::String _doneText;
RandomSoundBlock _doneSoundBlock; // Nancy 15 solve sound
- SceneChangeWithFlag _solveScene; // entered when all boxes are solved
- SceneChangeWithFlag _cancelScene; // entered when the puzzle is given up on
- Common::Rect _exitHotspot; // Nancy 9+: viewport-relative give-up hotspot
- uint16 _exitCursorType = 0; // Nancy 15
-
// ---- Data (Nancy 8) ----
SoundDescription _correctSound; // one sound shared by every box
Common::String _correctText;
diff --git a/engines/nancy/action/puzzle/raycastpuzzle.cpp b/engines/nancy/action/puzzle/raycastpuzzle.cpp
index 08f37765634..dd665afc4b1 100644
--- a/engines/nancy/action/puzzle/raycastpuzzle.cpp
+++ b/engines/nancy/action/puzzle/raycastpuzzle.cpp
@@ -1088,7 +1088,7 @@ void RaycastPuzzle::init() {
void RaycastPuzzle::registerGraphics() {
_map.registerGraphics();
- RenderActionRecord::registerGraphics();
+ PuzzleRecord::registerGraphics();
}
void RaycastPuzzle::readData(Common::SeekableReadStream &stream) {
@@ -1132,7 +1132,7 @@ void RaycastPuzzle::execute() {
}
void RaycastPuzzle::onPause(bool pause) {
- RenderActionRecord::onPause(pause);
+ PuzzleRecord::onPause(pause);
g_nancy->_input->setKeymapEnabled(InputManager::_mazeKeymapID, !pause);
}
diff --git a/engines/nancy/action/puzzle/raycastpuzzle.h b/engines/nancy/action/puzzle/raycastpuzzle.h
index 22ead7fb3ac..56e87276658 100644
--- a/engines/nancy/action/puzzle/raycastpuzzle.h
+++ b/engines/nancy/action/puzzle/raycastpuzzle.h
@@ -22,7 +22,7 @@
#ifndef NANCY_ACTION_RAYCASTPUZZLE_H
#define NANCY_ACTION_RAYCASTPUZZLE_H
-#include "engines/nancy/action/actionrecord.h"
+#include "engines/nancy/action/puzzlerecord.h"
namespace Nancy {
@@ -34,10 +34,10 @@ class RaycastDeferredLoader;
class RaycastLevelBuilder;
// Action record implementing nancy3's maze minigame
-class RaycastPuzzle : public RenderActionRecord {
+class RaycastPuzzle : public PuzzleRecord {
friend class RaycastDeferredLoader;
public:
- RaycastPuzzle() : RenderActionRecord(7), _map(7) {}
+ RaycastPuzzle() : PuzzleRecord(7), _map(7) {}
~RaycastPuzzle() override;
void init() override;
@@ -76,7 +76,6 @@ protected:
uint16 _unknownSoundChannelID = 0;
SoundDescription _dummySound;
- SceneChangeWithFlag _solveScene;
SoundDescription _solveSound;
Common::Array<uint32> _wallMap, _infoMap;
diff --git a/engines/nancy/action/puzzle/riddlepuzzle.cpp b/engines/nancy/action/puzzle/riddlepuzzle.cpp
index 5ad797bae86..c06ea1743f1 100644
--- a/engines/nancy/action/puzzle/riddlepuzzle.cpp
+++ b/engines/nancy/action/puzzle/riddlepuzzle.cpp
@@ -60,9 +60,9 @@ void RiddlePuzzle::readData(Common::SeekableReadStream &stream) {
_typeSound.readNormal(stream);
_eraseSound.readNormal(stream);
_enterSound.readNormal(stream);
- _successSceneChange.readData(stream);
+ _solveScene.readData(stream);
_successSound.readNormal(stream);
- _exitSceneChange.readData(stream);
+ _exitScene.readData(stream);
_exitSound.readNormal(stream);
readRect(stream, _exitHotspot);
@@ -227,7 +227,7 @@ void RiddlePuzzle::execute() {
switch (_solveState) {
case kNotSolved:
sound = &_exitSound;
- sceneChange = &_exitSceneChange;
+ sceneChange = &_exitScene;
break;
case kFailed:
@@ -243,7 +243,7 @@ void RiddlePuzzle::execute() {
break;
case kSolvedAll:
sound = &_successSound;
- sceneChange = &_successSceneChange;
+ sceneChange = &_solveScene;
break;
default:
@@ -268,7 +268,7 @@ void RiddlePuzzle::execute() {
void RiddlePuzzle::onPause(bool paused) {
g_nancy->_input->setVKEnabled(!paused);
- RenderActionRecord::onPause(paused);
+ PuzzleRecord::onPause(paused);
}
void RiddlePuzzle::handleInput(NancyInput &input) {
@@ -276,9 +276,7 @@ void RiddlePuzzle::handleInput(NancyInput &input) {
return;
}
- if (NancySceneState.getViewport().convertViewportToScreen(_exitHotspot).contains(input.mousePos)) {
- g_nancy->_cursor->setCursorType(g_nancy->_cursor->_puzzleExitCursor);
-
+ if (hoverExitHotspot(input)) {
if (input.input & NancyInput::kLeftMouseButtonUp) {
_state = kActionTrigger;
}
diff --git a/engines/nancy/action/puzzle/riddlepuzzle.h b/engines/nancy/action/puzzle/riddlepuzzle.h
index 061aa67b4d1..b69b3ba33a7 100644
--- a/engines/nancy/action/puzzle/riddlepuzzle.h
+++ b/engines/nancy/action/puzzle/riddlepuzzle.h
@@ -22,7 +22,7 @@
#ifndef NANCY_ACTION_RIDDLEPUZZLE_H
#define NANCY_ACTION_RIDDLEPUZZLE_H
-#include "engines/nancy/action/actionrecord.h"
+#include "engines/nancy/action/puzzlerecord.h"
namespace Nancy {
@@ -30,10 +30,10 @@ struct RiddlePuzzleData;
namespace Action {
-class RiddlePuzzle : public RenderActionRecord {
+class RiddlePuzzle : public PuzzleRecord {
public:
enum SolveState { kWaitForSound, kNotSolved, kFailed, kSolvedOne, kSolvedAll };
- RiddlePuzzle() : RenderActionRecord(7) {}
+ RiddlePuzzle() : PuzzleRecord(7) {}
virtual ~RiddlePuzzle();
void init() override;
@@ -66,11 +66,8 @@ protected:
SoundDescription _typeSound;
SoundDescription _eraseSound;
SoundDescription _enterSound;
- SceneChangeWithFlag _successSceneChange;
SoundDescription _successSound;
- SceneChangeWithFlag _exitSceneChange;
SoundDescription _exitSound;
- Common::Rect _exitHotspot;
Common::Array<Riddle> _riddles;
Time _nextBlinkTime;
diff --git a/engines/nancy/action/puzzle/rippedletterpuzzle.cpp b/engines/nancy/action/puzzle/rippedletterpuzzle.cpp
index fbe8b7896bb..a6b9ad7775c 100644
--- a/engines/nancy/action/puzzle/rippedletterpuzzle.cpp
+++ b/engines/nancy/action/puzzle/rippedletterpuzzle.cpp
@@ -193,7 +193,7 @@ void RippedLetterPuzzle::readData(Common::SeekableReadStream &stream) {
_dropSound.readNormal(stream);
_rotateSound.readNormal(stream);
- _solveExitScene.readData(stream);
+ _solveScene.readData(stream);
_solveSound.readNormal(stream);
_exitScene.readData(stream);
@@ -289,11 +289,11 @@ void RippedLetterPuzzle::execute() {
_exitScene.execute();
break;
case kWaitForSound:
- if (_solveExitScene._sceneChange.sceneID == NancySceneState.getSceneInfo().sceneID) {
+ if (_solveScene._sceneChange.sceneID == NancySceneState.getSceneInfo().sceneID) {
// nancy9 scene 2484 is auto-solved for you, but has a valid scene change back to itself
return;
}
- _solveExitScene.execute();
+ _solveScene.execute();
_puzzleState->playerHasTriedPuzzle = false;
break;
}
@@ -428,7 +428,7 @@ void RippedLetterPuzzle::handleInput(NancyInput &input) {
if (_puzzleState->pickedUpPieceID == -1) {
// No piece picked up, check the exit hotspot
- if (NancySceneState.getViewport().convertViewportToScreen(_exitHotspot).contains(input.mousePos)) {
+ if (isExitHotspotHovered(input)) {
if (_customCursorID != -1)
g_nancy->_cursor->setCursorType((CursorManager::CursorType)_customCursorID, true);
else
diff --git a/engines/nancy/action/puzzle/rippedletterpuzzle.h b/engines/nancy/action/puzzle/rippedletterpuzzle.h
index 20d32da0d11..9cd6c9a3e7b 100644
--- a/engines/nancy/action/puzzle/rippedletterpuzzle.h
+++ b/engines/nancy/action/puzzle/rippedletterpuzzle.h
@@ -22,7 +22,7 @@
#ifndef NANCY_ACTION_RIPPEDLETTERPUZZLE_H
#define NANCY_ACTION_RIPPEDLETTERPUZZLE_H
-#include "engines/nancy/action/actionrecord.h"
+#include "engines/nancy/action/puzzlerecord.h"
#include "engines/nancy/misc/mousefollow.h"
namespace Nancy {
@@ -31,11 +31,11 @@ struct RippedLetterPuzzleData;
namespace Action {
-class RippedLetterPuzzle : public RenderActionRecord {
+class RippedLetterPuzzle : public PuzzleRecord {
public:
enum SolveState { kNotSolved, kWaitForSound };
enum RotationType { kRotationNone = 0, kRotation90 = 1, kRotation180 = 2 };
- RippedLetterPuzzle() : RenderActionRecord(7) {}
+ RippedLetterPuzzle() : PuzzleRecord(7) {}
virtual ~RippedLetterPuzzle() {}
void init() override;
@@ -72,12 +72,8 @@ public:
SoundDescription _dropSound;
SoundDescription _rotateSound;
- SceneChangeWithFlag _solveExitScene;
SoundDescription _solveSound;
- SceneChangeWithFlag _exitScene;
- Common::Rect _exitHotspot;
-
int16 _customCursorID = -1;
Misc::MouseFollowObject _pickedUpPiece;
diff --git a/engines/nancy/action/puzzle/rotatinglockpuzzle.cpp b/engines/nancy/action/puzzle/rotatinglockpuzzle.cpp
index 5b9498dfb34..74f708fd1bc 100644
--- a/engines/nancy/action/puzzle/rotatinglockpuzzle.cpp
+++ b/engines/nancy/action/puzzle/rotatinglockpuzzle.cpp
@@ -133,10 +133,10 @@ void RotatingLockPuzzle::readData(Common::SeekableReadStream &stream) {
// Nancy 10 splits the old SceneChangeWithFlag (25 bytes with embedded
// flag) into a 20-byte SceneChangeDescription + 2-byte pause tail,
// with the event flag stored as a separate (label, value) pair.
- _solveExitScene._sceneChange.readData(stream);
+ _solveScene._sceneChange.readData(stream);
stream.skip(2);
- _solveExitScene._flag.label = stream.readSint16LE();
- _solveExitScene._flag.flag = stream.readByte();
+ _solveScene._flag.label = stream.readSint16LE();
+ _solveScene._flag.flag = stream.readByte();
_solveSoundDelay = stream.readUint16LE();
_solveSound.readNormal(stream);
@@ -148,7 +148,7 @@ void RotatingLockPuzzle::readData(Common::SeekableReadStream &stream) {
readRect(stream, _exitHotspot);
} else {
- _solveExitScene.readData(stream);
+ _solveScene.readData(stream);
_solveSoundDelay = stream.readUint16LE();
_solveSound.readNormal(stream);
@@ -225,7 +225,7 @@ void RotatingLockPuzzle::execute() {
if (_solveState == kNotSolved)
_exitScene.execute();
else
- _solveExitScene.execute();
+ _solveScene.execute();
finishExecution();
}
@@ -236,9 +236,7 @@ void RotatingLockPuzzle::handleInput(NancyInput &input) {
return;
}
- if (NancySceneState.getViewport().convertViewportToScreen(_exitHotspot).contains(input.mousePos)) {
- g_nancy->_cursor->setCursorType(g_nancy->_cursor->_puzzleExitCursor);
-
+ if (hoverExitHotspot(input)) {
if (input.input & NancyInput::kLeftMouseButtonUp) {
_state = kActionTrigger;
}
diff --git a/engines/nancy/action/puzzle/rotatinglockpuzzle.h b/engines/nancy/action/puzzle/rotatinglockpuzzle.h
index bc9f81d0335..86420f5f1b8 100644
--- a/engines/nancy/action/puzzle/rotatinglockpuzzle.h
+++ b/engines/nancy/action/puzzle/rotatinglockpuzzle.h
@@ -22,17 +22,17 @@
#ifndef NANCY_ACTION_ROTATINGLOCKPUZZLE_H
#define NANCY_ACTION_ROTATINGLOCKPUZZLE_H
-#include "engines/nancy/action/actionrecord.h"
+#include "engines/nancy/action/puzzlerecord.h"
#include "engines/nancy/cursor.h"
namespace Nancy {
namespace Action {
-class RotatingLockPuzzle : public RenderActionRecord {
+class RotatingLockPuzzle : public PuzzleRecord {
public:
enum SolveState { kNotSolved, kPlaySound, kWaitForSound };
static const byte kRandomStart = 99;
- RotatingLockPuzzle() : RenderActionRecord(7) {}
+ RotatingLockPuzzle() : PuzzleRecord(7) {}
virtual ~RotatingLockPuzzle() {}
void init() override;
@@ -57,11 +57,8 @@ public:
CursorManager::CursorType _upCursorType = CursorManager::kMoveUp;
CursorManager::CursorType _downCursorType = CursorManager::kMoveDown;
SoundDescription _clickSound;
- SceneChangeWithFlag _solveExitScene;
uint16 _solveSoundDelay = 0;
SoundDescription _solveSound;
- SceneChangeWithFlag _exitScene;
- Common::Rect _exitHotspot;
SolveState _solveState = kNotSolved;
Graphics::ManagedSurface _image;
diff --git a/engines/nancy/action/puzzle/safedialpuzzle.cpp b/engines/nancy/action/puzzle/safedialpuzzle.cpp
index c3fe172a7c4..a8d392f26aa 100644
--- a/engines/nancy/action/puzzle/safedialpuzzle.cpp
+++ b/engines/nancy/action/puzzle/safedialpuzzle.cpp
@@ -225,9 +225,7 @@ void SafeDialPuzzle::handleInput(NancyInput &input) {
return;
}
- if (NancySceneState.getViewport().convertViewportToScreen(_exitHotspot).contains(input.mousePos)) {
- g_nancy->_cursor->setCursorType(g_nancy->_cursor->_puzzleExitCursor);
-
+ if (hoverExitHotspot(input)) {
if (input.input & NancyInput::kLeftMouseButtonUp) {
_state = kActionTrigger;
}
diff --git a/engines/nancy/action/puzzle/safedialpuzzle.h b/engines/nancy/action/puzzle/safedialpuzzle.h
index 7c775fd37b4..46998f65d3b 100644
--- a/engines/nancy/action/puzzle/safedialpuzzle.h
+++ b/engines/nancy/action/puzzle/safedialpuzzle.h
@@ -22,16 +22,16 @@
#ifndef NANCY_ACTION_SAFEDIALPUZZLE_H
#define NANCY_ACTION_SAFEDIALPUZZLE_H
-#include "engines/nancy/action/actionrecord.h"
+#include "engines/nancy/action/puzzlerecord.h"
namespace Nancy {
namespace Action {
// Handles the nancy3 safe puzzle with Chinese characters on the dial,
// as well as nancy4's sextant puzzle
-class SafeDialPuzzle : public RenderActionRecord {
+class SafeDialPuzzle : public PuzzleRecord {
public:
- SafeDialPuzzle() : RenderActionRecord(7) {}
+ SafeDialPuzzle() : PuzzleRecord(7) {}
virtual ~SafeDialPuzzle() {}
void init() override;
@@ -84,13 +84,9 @@ protected:
SoundDescription _selectSound;
SoundDescription _resetSound;
- SceneChangeWithFlag _solveScene;
uint _solveSoundDelay = 0;
SoundDescription _solveSound;
- SceneChangeWithFlag _exitScene;
- Common::Rect _exitHotspot;
-
Graphics::ManagedSurface _image1, _image2, _resetImage;
uint _numInbetweens = 1;
diff --git a/engines/nancy/action/puzzle/scalepuzzle.cpp b/engines/nancy/action/puzzle/scalepuzzle.cpp
index 31221d4057e..87966172577 100644
--- a/engines/nancy/action/puzzle/scalepuzzle.cpp
+++ b/engines/nancy/action/puzzle/scalepuzzle.cpp
@@ -54,10 +54,10 @@ void ScalePuzzle::readData(Common::SeekableReadStream &stream) {
// Applied when the puzzle comes out solved. Several scenes use 9999 (no scene) and
// leave the transition to whatever watches the solve flag.
- _solveScene.sceneID = stream.readUint16LE(); // 0x25
- _solveScene.continueSceneSound = kContinueSceneSound;
- _solveFlag.label = stream.readSint16LE(); // 0x27
- _solveFlag.flag = stream.readByte(); // 0x29
+ _solveScene._sceneChange.sceneID = stream.readUint16LE(); // 0x25
+ _solveScene._sceneChange.continueSceneSound = kContinueSceneSound;
+ _solveScene._flag.label = stream.readSint16LE(); // 0x27
+ _solveScene._flag.flag = stream.readByte(); // 0x29
_solveSound.readData(stream); // played once the puzzle comes out solved
@@ -104,7 +104,7 @@ void ScalePuzzle::readData(Common::SeekableReadStream &stream) {
// A count-prefixed array of fixed 23-byte hotspot records:
// {rect, u16 cursorType, u16 sceneID, u16 frameID, byte}. The sample carries one - the
// "give up / exit" hotspot, with the exit cursor type.
- readExitHotspot(stream, _exitHotspot, _exitCursorType, _exitScene, _exitFlag);
+ readExitHotspot(stream);
}
void ScalePuzzle::init() {
@@ -355,15 +355,13 @@ void ScalePuzzle::execute() {
break;
case kActionTrigger:
if (_exitRequested) {
- NancySceneState.setEventFlag(_exitFlag);
- NancySceneState.changeScene(_exitScene);
+ _exitScene.execute();
finishExecution();
} else {
// Solved: play the sound, set the solve flag, change scene (9999 = stay). The puzzle
// keeps running afterwards, so the player can still leave through the exit hotspot.
playSoundBlock(_solveSound);
- NancySceneState.setEventFlag(_solveFlag);
- NancySceneState.changeScene(_solveScene);
+ _solveScene.execute();
_solveTriggered = true;
_state = kRun;
}
@@ -426,9 +424,7 @@ void ScalePuzzle::handleInput(NancyInput &input) {
return;
}
- if (!_exitHotspot.isEmpty() &&
- NancySceneState.getViewport().convertViewportToScreen(_exitHotspot).contains(input.mousePos)) {
- setDataCursor(_exitCursorType, false);
+ if (hoverExitHotspot(input)) {
if (click) {
_exitRequested = true;
}
diff --git a/engines/nancy/action/puzzle/scalepuzzle.h b/engines/nancy/action/puzzle/scalepuzzle.h
index 2adafb5adf1..1f8e4da71d4 100644
--- a/engines/nancy/action/puzzle/scalepuzzle.h
+++ b/engines/nancy/action/puzzle/scalepuzzle.h
@@ -23,7 +23,7 @@
#define NANCY_ACTION_SCALEPUZZLE_H
#include "engines/nancy/commontypes.h"
-#include "engines/nancy/action/actionrecord.h"
+#include "engines/nancy/action/puzzlerecord.h"
namespace Nancy {
namespace Action {
@@ -42,9 +42,9 @@ namespace Action {
// number. Figures must be matched in order, the lights stay on once lit,
// and clearing the pans resets them. The puzzle is solved once every
// figure of the current scene is lit.
-class ScalePuzzle : public RenderActionRecord {
+class ScalePuzzle : public PuzzleRecord {
public:
- ScalePuzzle() : RenderActionRecord(7) {}
+ ScalePuzzle() : PuzzleRecord(7) {}
virtual ~ScalePuzzle() {}
void init() override;
@@ -106,8 +106,6 @@ protected:
Common::Path _imageName; // 0x00
uint16 _hoverCursorType = 0; // 0x21 - raw Nancy13 cursor type over a coin
uint16 _dragCursorType = 0; // 0x23 - raw Nancy13 cursor type while carrying
- SceneChangeDescription _solveScene; // 0x25 - applied when solved (9999 => none)
- FlagDescription _solveFlag; // 0x27 - set when solved
RandomSoundBlock _solveSound; // the first sound block; played once solved
Common::Array<Target> _targets; // the figures to match in this scene
@@ -128,13 +126,6 @@ protected:
RandomSoundBlock _dropTraySound; // 0x218 - coin dropped back into the tray
RandomSoundBlock _dropPanSound; // 0x1c4 - coin dropped onto a pan
- // The clickable "give up / exit" hotspot (the base-class hotspot record). Clicking it
- // always jumps to the scene's first frame and sets an event flag.
- Common::Rect _exitHotspot;
- uint16 _exitCursorType = 0;
- SceneChangeDescription _exitScene;
- FlagDescription _exitFlag;
-
// -- Runtime state --
int _indicatorZeroFrame = 0; // the "0" frame (frames.size() / 2)
int _tilt = 0; // the indicator value: sum(right) - sum(left)
diff --git a/engines/nancy/action/puzzle/setplayerclock.cpp b/engines/nancy/action/puzzle/setplayerclock.cpp
index 969479887ed..8fe8b6db8f3 100644
--- a/engines/nancy/action/puzzle/setplayerclock.cpp
+++ b/engines/nancy/action/puzzle/setplayerclock.cpp
@@ -87,7 +87,7 @@ void SetPlayerClock::readData(Common::SeekableReadStream &stream) {
}
_buttonSound.readNormal(stream);
- _alarmSetScene.readData(stream);
+ _solveScene.readData(stream);
_alarmSoundDelay = stream.readUint16LE();
_alarmSetSound.readNormal(stream);
_exitScene.readData(stream);
@@ -169,7 +169,7 @@ void SetPlayerClock::execute() {
g_nancy->_sound->stopSound(_buttonSound);
g_nancy->_sound->stopSound(_alarmSetSound);
NancySceneState.setPlayerTime(_alarmHours * 3600000, false);
- _alarmSetScene.execute();
+ _solveScene.execute();
finishExecution();
}
}
diff --git a/engines/nancy/action/puzzle/setplayerclock.h b/engines/nancy/action/puzzle/setplayerclock.h
index 65f56187437..cbb6aaba19a 100644
--- a/engines/nancy/action/puzzle/setplayerclock.h
+++ b/engines/nancy/action/puzzle/setplayerclock.h
@@ -22,16 +22,16 @@
#ifndef NANCY_ACTION_SETPLAYERCLOCK_H
#define NANCY_ACTION_SETPLAYERCLOCK_H
-#include "engines/nancy/action/actionrecord.h"
+#include "engines/nancy/action/puzzlerecord.h"
namespace Nancy {
namespace Action {
// Action record implementing an alarm clock. First used in nancy3
-class SetPlayerClock : public RenderActionRecord {
+class SetPlayerClock : public PuzzleRecord {
public:
enum AlarmState { kTimeMode, kAlarmMode, kWait };
- SetPlayerClock() : RenderActionRecord(7) {}
+ SetPlayerClock() : PuzzleRecord(7) {}
virtual ~SetPlayerClock();
void init() override;
@@ -74,10 +74,8 @@ protected:
Common::Rect _alarmLightSrc;
SoundDescription _buttonSound;
- SceneChangeWithFlag _alarmSetScene;
uint16 _alarmSoundDelay = 0;
SoundDescription _alarmSetSound; // NO SOUND in MHM
- SceneChangeWithFlag _exitScene;
Graphics::ManagedSurface _image;
diff --git a/engines/nancy/action/puzzle/sewingmachinepuzzle.h b/engines/nancy/action/puzzle/sewingmachinepuzzle.h
index 6885674267c..00485f6e872 100644
--- a/engines/nancy/action/puzzle/sewingmachinepuzzle.h
+++ b/engines/nancy/action/puzzle/sewingmachinepuzzle.h
@@ -22,7 +22,7 @@
#ifndef NANCY_ACTION_SEWINGMACHINEPUZZLE_H
#define NANCY_ACTION_SEWINGMACHINEPUZZLE_H
-#include "engines/nancy/action/actionrecord.h"
+#include "engines/nancy/action/puzzlerecord.h"
#include "engines/nancy/commontypes.h"
#include "engines/nancy/action/navigationrecords.h"
#include "engines/nancy/action/actionzone.h"
@@ -36,9 +36,9 @@ namespace Action {
// the end cross-dissolves to the trigger zone's win scene.
// TODO: the needle spot comes from the scene's needle-overlay rect, not from this
// record's own data.
-class SewingMachinePuzzle : public RenderActionRecord {
+class SewingMachinePuzzle : public PuzzleRecord {
public:
- SewingMachinePuzzle() : RenderActionRecord(7) {}
+ SewingMachinePuzzle() : PuzzleRecord(7) {}
virtual ~SewingMachinePuzzle() {}
void init() override;
diff --git a/engines/nancy/action/puzzle/sliderpuzzle.cpp b/engines/nancy/action/puzzle/sliderpuzzle.cpp
index d91377c5786..486d432e0fc 100644
--- a/engines/nancy/action/puzzle/sliderpuzzle.cpp
+++ b/engines/nancy/action/puzzle/sliderpuzzle.cpp
@@ -100,7 +100,7 @@ void SliderPuzzle::readData(Common::SeekableReadStream &stream) {
stream.skip((6 - _height) * 6 * 2);
_clickSound.readNormal(stream);
- _solveExitScene.readData(stream);
+ _solveScene.readData(stream);
_solveSound.readNormal(stream);
_exitScene.readData(stream);
readRect(stream, _exitHotspot);
@@ -161,7 +161,7 @@ void SliderPuzzle::execute() {
_exitScene.execute();
break;
case kWaitForSound:
- _solveExitScene.execute();
+ _solveScene.execute();
_puzzleState->playerHasTriedPuzzle = false;
break;
}
@@ -176,9 +176,7 @@ void SliderPuzzle::handleInput(NancyInput &input) {
return;
}
- if (NancySceneState.getViewport().convertViewportToScreen(_exitHotspot).contains(input.mousePos)) {
- g_nancy->_cursor->setCursorType(g_nancy->_cursor->_puzzleExitCursor);
-
+ if (hoverExitHotspot(input)) {
if (input.input & NancyInput::kLeftMouseButtonUp) {
_state = kActionTrigger;
}
diff --git a/engines/nancy/action/puzzle/sliderpuzzle.h b/engines/nancy/action/puzzle/sliderpuzzle.h
index 10fb0daaf32..5fc620009fd 100644
--- a/engines/nancy/action/puzzle/sliderpuzzle.h
+++ b/engines/nancy/action/puzzle/sliderpuzzle.h
@@ -22,7 +22,7 @@
#ifndef NANCY_ACTION_SLIDERPUZZLE_H
#define NANCY_ACTION_SLIDERPUZZLE_H
-#include "engines/nancy/action/actionrecord.h"
+#include "engines/nancy/action/puzzlerecord.h"
namespace Nancy {
@@ -31,10 +31,10 @@ struct SliderPuzzleData;
namespace Action {
-class SliderPuzzle: public RenderActionRecord {
+class SliderPuzzle: public PuzzleRecord {
public:
enum SolveState { kNotSolved, kWaitForSound };
- SliderPuzzle() : RenderActionRecord(7) {}
+ SliderPuzzle() : PuzzleRecord(7) {}
virtual ~SliderPuzzle() {}
void init() override;
@@ -53,10 +53,7 @@ public:
Common::Array<Common::Array<int16>> _startTileOrder;
Common::Array<Common::Array<int16>> _correctTileOrder;
SoundDescription _clickSound;
- SceneChangeWithFlag _solveExitScene;
SoundDescription _solveSound;
- SceneChangeWithFlag _exitScene;
- Common::Rect _exitHotspot;
bool _retainState = true;
diff --git a/engines/nancy/action/puzzle/sortpuzzle.cpp b/engines/nancy/action/puzzle/sortpuzzle.cpp
index 191fd4d9969..0fff06757b3 100644
--- a/engines/nancy/action/puzzle/sortpuzzle.cpp
+++ b/engines/nancy/action/puzzle/sortpuzzle.cpp
@@ -103,16 +103,16 @@ void SortPuzzle::readData(Common::SeekableReadStream &stream) {
_pickupSound.readNormal(stream);
_dropSound.readNormal(stream);
- _winScene.readData(stream);
+ _solveScene._sceneChange.readData(stream);
stream.skip(2);
- _winFlag.label = stream.readSint16LE();
- _winFlag.flag = stream.readByte();
+ _solveScene._flag.label = stream.readSint16LE();
+ _solveScene._flag.flag = stream.readByte();
_winSound.readNormal(stream);
- _cancelScene.readData(stream);
+ _exitScene._sceneChange.readData(stream);
stream.skip(2);
- _cancelFlag.label = stream.readSint16LE();
- _cancelFlag.flag = stream.readByte();
+ _exitScene._flag.label = stream.readSint16LE();
+ _exitScene._flag.flag = stream.readByte();
readRect(stream, _exitHotspot);
stream.skip(2); // exit cursor type id
@@ -164,16 +164,16 @@ void SortPuzzle::readDataNancy12(Common::SeekableReadStream &stream) {
_pickupSound.readNormal(stream); // 0x842
_dropSound.readNormal(stream); // 0x873
- _winScene.readData(stream); // 0x8a4
+ _solveScene._sceneChange.readData(stream); // 0x8a4
stream.skip(2);
- _winFlag.label = stream.readSint16LE();
- _winFlag.flag = stream.readByte();
+ _solveScene._flag.label = stream.readSint16LE();
+ _solveScene._flag.flag = stream.readByte();
_winSound.readNormal(stream); // 0x8bd
- _cancelScene.readData(stream); // 0x8ee
+ _exitScene._sceneChange.readData(stream); // 0x8ee
stream.skip(2);
- _cancelFlag.label = stream.readSint16LE();
- _cancelFlag.flag = stream.readByte();
+ _exitScene._flag.label = stream.readSint16LE();
+ _exitScene._flag.flag = stream.readByte();
readRect(stream, _exitHotspot); // 0x907
stream.skip(2); // exit cursor type id
@@ -362,11 +362,9 @@ void SortPuzzle::execute() {
spd->currentState.clear();
spd->solvedState.clear();
}
- NancySceneState.setEventFlag(_winFlag);
- NancySceneState.changeScene(_winScene);
+ _solveScene.execute();
} else {
- NancySceneState.setEventFlag(_cancelFlag);
- NancySceneState.changeScene(_cancelScene);
+ _exitScene.execute();
}
finishExecution();
break;
@@ -440,8 +438,7 @@ void SortPuzzle::handleInput(NancyInput &input) {
}
if (!hitCell) {
- if (!_exitHotspot.isEmpty() && _exitHotspot.contains(mouseVP)) {
- g_nancy->_cursor->setCursorType(g_nancy->_cursor->_puzzleExitCursor);
+ if (hoverExitHotspot(input)) {
if (input.input & NancyInput::kLeftMouseButtonUp)
_subState = kExitToCancel;
} else if (_hasHeld && useNewCursors) {
diff --git a/engines/nancy/action/puzzle/sortpuzzle.h b/engines/nancy/action/puzzle/sortpuzzle.h
index e5de3100e9f..6d67b620760 100644
--- a/engines/nancy/action/puzzle/sortpuzzle.h
+++ b/engines/nancy/action/puzzle/sortpuzzle.h
@@ -22,7 +22,7 @@
#ifndef NANCY_ACTION_SORTPUZZLE_H
#define NANCY_ACTION_SORTPUZZLE_H
-#include "engines/nancy/action/actionrecord.h"
+#include "engines/nancy/action/puzzlerecord.h"
#include "engines/nancy/misc/mousefollow.h"
#include "engines/nancy/commontypes.h"
@@ -34,9 +34,9 @@ namespace Action {
// (pre-shuffle) layout. Tiles are sorted per type, color and size, which is
// visible in the back of each gem when picked up.
// Called from scene 2036 in Nancy10.
-class SortPuzzle : public RenderActionRecord {
+class SortPuzzle : public PuzzleRecord {
public:
- SortPuzzle() : RenderActionRecord(7) {}
+ SortPuzzle() : PuzzleRecord(7) {}
virtual ~SortPuzzle() {}
void init() override;
@@ -114,13 +114,7 @@ protected:
SoundDescription _pickupSound;
SoundDescription _dropSound;
- SceneChangeDescription _winScene;
- FlagDescription _winFlag;
SoundDescription _winSound;
- SceneChangeDescription _cancelScene;
- FlagDescription _cancelFlag;
-
- Common::Rect _exitHotspot;
// Runtime state
diff --git a/engines/nancy/action/puzzle/soundequalizerpuzzle.cpp b/engines/nancy/action/puzzle/soundequalizerpuzzle.cpp
index 2b2f0691702..ac6559968c0 100644
--- a/engines/nancy/action/puzzle/soundequalizerpuzzle.cpp
+++ b/engines/nancy/action/puzzle/soundequalizerpuzzle.cpp
@@ -101,7 +101,7 @@ void SoundEqualizerPuzzle::registerGraphics() {
scrollbar->registerGraphics();
}
- RenderActionRecord::registerGraphics();
+ PuzzleRecord::registerGraphics();
}
void SoundEqualizerPuzzle::readData(Common::SeekableReadStream &stream) {
@@ -181,12 +181,12 @@ void SoundEqualizerPuzzle::readData(Common::SeekableReadStream &stream) {
}
}
- _exitScene.readData(stream);
+ _exitScene._sceneChange.readData(stream);
stream.skip(2);
_exitSound.readNormal(stream);
- _solveFlag.label = stream.readSint16LE();
- _solveFlag.flag = stream.readByte();
+ _solveScene._flag.label = stream.readSint16LE();
+ _solveScene._flag.flag = stream.readByte();
}
void SoundEqualizerPuzzle::execute() {
@@ -222,7 +222,7 @@ void SoundEqualizerPuzzle::execute() {
g_nancy->_sound->stopSound(_sounds[i]);
}
- NancySceneState.changeScene(_exitScene);
+ NancySceneState.changeScene(_exitScene._sceneChange);
finishExecution();
}
}
@@ -282,7 +282,7 @@ void SoundEqualizerPuzzle::updateSlider(uint sliderID) {
// Since the rate for the "solve" sound never actually changes,
// we only need the volume to be correct.
- NancySceneState.setEventFlag(_solveFlag);
+ NancySceneState.setEventFlag(_solveScene._flag);
} else {
g_nancy->_sound->setVolume(_sounds[sliderID - 3], _minVolume[sliderID - 3]);
}
diff --git a/engines/nancy/action/puzzle/soundequalizerpuzzle.h b/engines/nancy/action/puzzle/soundequalizerpuzzle.h
index 9e86eaf5d9b..dbb23144d32 100644
--- a/engines/nancy/action/puzzle/soundequalizerpuzzle.h
+++ b/engines/nancy/action/puzzle/soundequalizerpuzzle.h
@@ -22,7 +22,7 @@
#ifndef NANCY_ACTION_SOUNDEQUALIZERPUZZLE_H
#define NANCY_ACTION_SOUNDEQUALIZERPUZZLE_H
-#include "engines/nancy/action/actionrecord.h"
+#include "engines/nancy/action/puzzlerecord.h"
namespace UI {
class Scrollbar;
@@ -36,9 +36,9 @@ namespace Action {
class ViewportScrollbar;
-class SoundEqualizerPuzzle: public RenderActionRecord {
+class SoundEqualizerPuzzle: public PuzzleRecord {
public:
- SoundEqualizerPuzzle() : RenderActionRecord(7) {}
+ SoundEqualizerPuzzle() : PuzzleRecord(7) {}
virtual ~SoundEqualizerPuzzle();
void init() override;
@@ -76,11 +76,8 @@ public:
uint16 _solveMinRate = 0;
uint16 _solveMaxRate = 0;
- SceneChangeDescription _exitScene;
SoundDescription _exitSound;
- FlagDescription _solveFlag;
-
Graphics::ManagedSurface _image;
Common::Array<ViewportScrollbar *> _sliders;
diff --git a/engines/nancy/action/puzzle/soundmatchpuzzle.cpp b/engines/nancy/action/puzzle/soundmatchpuzzle.cpp
index 787337d73bb..91e5fbcd271 100644
--- a/engines/nancy/action/puzzle/soundmatchpuzzle.cpp
+++ b/engines/nancy/action/puzzle/soundmatchpuzzle.cpp
@@ -41,7 +41,7 @@ void SoundMatchPuzzle::readData(Common::SeekableReadStream &stream) {
_resetOnWrong = stream.readByte() != 0;
- _winScene.readData(stream); // 0x084
+ _solveScene.readData(stream); // 0x084
_winSound.readNormal(stream); // 0x09d
_exitScene.readData(stream); // 0x0ce
@@ -178,7 +178,7 @@ void SoundMatchPuzzle::execute() {
if (_isExiting)
_exitScene.execute();
else
- _winScene.execute();
+ _solveScene.execute();
finishExecution();
break;
}
@@ -272,8 +272,7 @@ void SoundMatchPuzzle::handleInput(NancyInput &input) {
}
}
- if (_exitHotspot.contains(mouseVP)) {
- g_nancy->_cursor->setCursorType(g_nancy->_cursor->_puzzleExitCursor);
+ if (hoverExitHotspot(input)) {
if (input.input & NancyInput::kLeftMouseButtonUp) {
_isExiting = true;
_state = kActionTrigger;
diff --git a/engines/nancy/action/puzzle/soundmatchpuzzle.h b/engines/nancy/action/puzzle/soundmatchpuzzle.h
index f09b61095df..a21fb50815e 100644
--- a/engines/nancy/action/puzzle/soundmatchpuzzle.h
+++ b/engines/nancy/action/puzzle/soundmatchpuzzle.h
@@ -22,7 +22,7 @@
#ifndef NANCY_ACTION_SOUNDMATCHPUZZLE_H
#define NANCY_ACTION_SOUNDMATCHPUZZLE_H
-#include "engines/nancy/action/actionrecord.h"
+#include "engines/nancy/action/puzzlerecord.h"
#include "engines/nancy/commontypes.h"
namespace Nancy {
@@ -32,9 +32,9 @@ namespace Action {
// The player hears a whale call by clicking one of 5 numbered buttons, then
// clicks the matching whale image. Correct pairs stay lit. Player wins when
// all the required pairs have been matched.
-class SoundMatchPuzzle : public RenderActionRecord {
+class SoundMatchPuzzle : public PuzzleRecord {
public:
- SoundMatchPuzzle() : RenderActionRecord(7) {}
+ SoundMatchPuzzle() : PuzzleRecord(7) {}
virtual ~SoundMatchPuzzle() {}
void init() override;
@@ -56,11 +56,7 @@ protected:
SoundDescription _feedbackSoundWrong; // played on incorrect whale click
SoundDescription _feedbackSoundRight; // played on correct whale click
- SceneChangeWithFlag _winScene;
SoundDescription _winSound; // played when all pairs are matched
- SceneChangeWithFlag _exitScene;
-
- Common::Rect _exitHotspot;
uint16 _requiredPairs = kNumButtons; // how many matches needed to win
diff --git a/engines/nancy/action/puzzle/spigotpuzzle.cpp b/engines/nancy/action/puzzle/spigotpuzzle.cpp
index 79eaacf3857..37cac5e37d4 100644
--- a/engines/nancy/action/puzzle/spigotpuzzle.cpp
+++ b/engines/nancy/action/puzzle/spigotpuzzle.cpp
@@ -261,9 +261,7 @@ void SpigotPuzzle::handleInput(NancyInput &input) {
Common::Point mousePos = input.mousePos;
mousePos -= { vpScreenPos.left, vpScreenPos.top };
- if (_exitHotspot.contains(mousePos)) {
- g_nancy->_cursor->setCursorType(g_nancy->_cursor->_puzzleExitCursor);
-
+ if (hoverExitHotspot(input)) {
if (input.input & NancyInput::kLeftMouseButtonUp) {
_state = kActionTrigger;
}
diff --git a/engines/nancy/action/puzzle/spigotpuzzle.h b/engines/nancy/action/puzzle/spigotpuzzle.h
index 91ab7430264..17a7e7b1a68 100644
--- a/engines/nancy/action/puzzle/spigotpuzzle.h
+++ b/engines/nancy/action/puzzle/spigotpuzzle.h
@@ -22,15 +22,15 @@
#ifndef NANCY_ACTION_SPIGOTPUZZLE_H
#define NANCY_ACTION_SPIGOTPUZZLE_H
-#include "engines/nancy/action/actionrecord.h"
+#include "engines/nancy/action/puzzlerecord.h"
namespace Nancy {
namespace Action {
// A puzzle in nancy7 where you pull spigots to input a password
-class SpigotPuzzle : public RenderActionRecord {
+class SpigotPuzzle : public PuzzleRecord {
public:
- SpigotPuzzle() : RenderActionRecord(7) {}
+ SpigotPuzzle() : PuzzleRecord(7) {}
virtual ~SpigotPuzzle() {}
void init() override;
@@ -72,13 +72,9 @@ protected:
SoundDescription _letterSound;
SoundDescription _spigotSound;
- SceneChangeWithFlag _solveScene;
uint16 _solveSoundDelay = 0;
SoundDescription _solveSound;
- SceneChangeWithFlag _exitScene;
- Common::Rect _exitHotspot;
-
Graphics::ManagedSurface _image;
Common::Array<uint16> _currentOrder;
diff --git a/engines/nancy/action/puzzle/stepobjectspuzzle.cpp b/engines/nancy/action/puzzle/stepobjectspuzzle.cpp
index 759fba0ac0d..70998275a8f 100644
--- a/engines/nancy/action/puzzle/stepobjectspuzzle.cpp
+++ b/engines/nancy/action/puzzle/stepobjectspuzzle.cpp
@@ -48,9 +48,9 @@ void StepObjectsPuzzle::readData(Common::SeekableReadStream &stream) {
_numCols = stream.readUint16LE();
_pitchY = stream.readUint16LE();
_pitchX = stream.readUint16LE();
- _solveScene.sceneID = stream.readUint16LE();
- _solveFlag.label = stream.readSint16LE();
- _solveFlag.flag = stream.readByte();
+ _solveScene._sceneChange.sceneID = stream.readUint16LE();
+ _solveScene._flag.label = stream.readSint16LE();
+ _solveScene._flag.flag = stream.readByte();
_numSteps = stream.readUint16LE();
_solution.resize(_numSteps);
@@ -77,7 +77,7 @@ void StepObjectsPuzzle::readData(Common::SeekableReadStream &stream) {
object.startCol = stream.readUint16LE();
}
- readExitHotspot(stream, _exitHotspot, _exitCursorType, _exitScene, _exitFlag);
+ readExitHotspot(stream);
_sounds.resize(kNumSounds);
for (uint i = 0; i < kNumSounds; ++i) {
@@ -387,11 +387,9 @@ void StepObjectsPuzzle::execute() {
break;
case kActionTrigger:
if (_solved) {
- NancySceneState.setEventFlag(_solveFlag);
- NancySceneState.changeScene(_solveScene);
+ _solveScene.execute();
} else {
- NancySceneState.setEventFlag(_exitFlag);
- NancySceneState.changeScene(_exitScene);
+ _exitScene.execute();
}
finishExecution();
@@ -452,8 +450,7 @@ void StepObjectsPuzzle::handleInput(NancyInput &input) {
}
}
- if (isHovered(_exitHotspot, input.mousePos)) {
- setDataCursor(_exitCursorType, false);
+ if (hoverExitHotspot(input)) {
if (click) {
_exitRequested = true;
}
diff --git a/engines/nancy/action/puzzle/stepobjectspuzzle.h b/engines/nancy/action/puzzle/stepobjectspuzzle.h
index 5be6bbf78f9..7d7755209d6 100644
--- a/engines/nancy/action/puzzle/stepobjectspuzzle.h
+++ b/engines/nancy/action/puzzle/stepobjectspuzzle.h
@@ -23,7 +23,7 @@
#define NANCY_ACTION_STEPOBJECTSPUZZLE_H
#include "engines/nancy/commontypes.h"
-#include "engines/nancy/action/actionrecord.h"
+#include "engines/nancy/action/puzzlerecord.h"
#include "engines/nancy/misc/mousefollow.h"
namespace Nancy {
@@ -35,9 +35,9 @@ namespace Action {
// shoe visits, so each cell can only be stepped on once, and the overall
// dance has to be done in one go. The puzzle is solved once the sequence
// of dance steps matches the scripted one.
-class StepObjectsPuzzle : public RenderActionRecord {
+class StepObjectsPuzzle : public PuzzleRecord {
public:
- StepObjectsPuzzle() : RenderActionRecord(7) {}
+ StepObjectsPuzzle() : PuzzleRecord(7) {}
virtual ~StepObjectsPuzzle() {}
void init() override;
@@ -113,19 +113,11 @@ protected:
uint16 _numCols = 0;
uint16 _pitchY = 0;
uint16 _pitchX = 0;
- SceneChangeDescription _solveScene;
- FlagDescription _solveFlag;
uint16 _numSteps = 0;
Common::Array<Step> _solution;
Common::Array<StepObject> _objects;
- // The clickable "give up / leave" hotspot.
- Common::Rect _exitHotspot;
- uint16 _exitCursorType = 0;
- SceneChangeDescription _exitScene;
- FlagDescription _exitFlag; // set on give-up
-
Common::Array<RandomSoundBlock> _sounds;
// Runtime state
diff --git a/engines/nancy/action/puzzle/tangrampuzzle.cpp b/engines/nancy/action/puzzle/tangrampuzzle.cpp
index 79a205eb5c3..c31d0c529c0 100644
--- a/engines/nancy/action/puzzle/tangrampuzzle.cpp
+++ b/engines/nancy/action/puzzle/tangrampuzzle.cpp
@@ -108,7 +108,7 @@ void TangramPuzzle::registerGraphics() {
tile.registerGraphics();
}
- RenderActionRecord::registerGraphics();
+ PuzzleRecord::registerGraphics();
}
void TangramPuzzle::readData(Common::SeekableReadStream &stream) {
@@ -234,9 +234,7 @@ void TangramPuzzle::handleInput(NancyInput &input) {
}
// No tile under cursor, check exit hotspot
- if (_exitHotspot.contains(mousePos)) {
- g_nancy->_cursor->setCursorType(g_nancy->_cursor->_puzzleExitCursor);
-
+ if (hoverExitHotspot(input)) {
if (input.input & NancyInput::kLeftMouseButtonUp) {
_state = kActionTrigger;
}
diff --git a/engines/nancy/action/puzzle/tangrampuzzle.h b/engines/nancy/action/puzzle/tangrampuzzle.h
index 13c5a3b56e1..e75db89b4d6 100644
--- a/engines/nancy/action/puzzle/tangrampuzzle.h
+++ b/engines/nancy/action/puzzle/tangrampuzzle.h
@@ -22,7 +22,7 @@
#ifndef NANCY_ACTION_TANGRAMPUZZLE_H
#define NANCY_ACTION_TANGRAMPUZZLE_H
-#include "engines/nancy/action/actionrecord.h"
+#include "engines/nancy/action/puzzlerecord.h"
#include "engines/nancy/misc/mousefollow.h"
namespace Nancy {
@@ -31,9 +31,9 @@ namespace Action {
// Handles a specific type of puzzle where clicking an object rotates it,
// as well as several other objects linked to it. Examples are the sun/moon
// and staircase spindle puzzles in nancy3
-class TangramPuzzle : public RenderActionRecord {
+class TangramPuzzle : public PuzzleRecord {
public:
- TangramPuzzle() : RenderActionRecord(7) {}
+ TangramPuzzle() : PuzzleRecord(7) {}
virtual ~TangramPuzzle();
void init() override;
@@ -91,12 +91,8 @@ protected:
SoundDescription _putDownSound;
SoundDescription _rotateSound;
- SceneChangeWithFlag _solveScene;
SoundDescription _solveSound;
- SceneChangeWithFlag _exitScene;
- Common::Rect _exitHotspot;
-
Graphics::ManagedSurface _tileImage;
Graphics::ManagedSurface _maskImage;
byte *_zBuffer = nullptr;
diff --git a/engines/nancy/action/puzzle/telephone.cpp b/engines/nancy/action/puzzle/telephone.cpp
index 60349ec7127..36403f0cca8 100644
--- a/engines/nancy/action/puzzle/telephone.cpp
+++ b/engines/nancy/action/puzzle/telephone.cpp
@@ -436,9 +436,7 @@ void Telephone::handleInput(NancyInput &input) {
// The exit hotspot stays active for as long as the record is running, even
// while ringing, talking, or playing the bad number message. Only the
// buttons are limited to the states where the phone accepts input.
- if (NancySceneState.getViewport().convertViewportToScreen(_exitHotspot).contains(input.mousePos)) {
- g_nancy->_cursor->setCursorType(g_nancy->_cursor->_puzzleExitCursor);
-
+ if (hoverExitHotspot(input)) {
if (input.input & NancyInput::kLeftMouseButtonUp) {
if (_phoneType == kTelephone) {
g_nancy->_sound->loadSound(_hangUpSound);
diff --git a/engines/nancy/action/puzzle/telephone.h b/engines/nancy/action/puzzle/telephone.h
index 44944d6ea40..896b1457b67 100644
--- a/engines/nancy/action/puzzle/telephone.h
+++ b/engines/nancy/action/puzzle/telephone.h
@@ -22,7 +22,7 @@
#ifndef NANCY_ACTION_TELEPHONE_H
#define NANCY_ACTION_TELEPHONE_H
-#include "engines/nancy/action/actionrecord.h"
+#include "engines/nancy/action/puzzlerecord.h"
namespace Nancy {
@@ -30,7 +30,7 @@ class Font;
namespace Action {
-class Telephone : public RenderActionRecord {
+class Telephone : public PuzzleRecord {
public:
struct PhoneCall {
Common::Array<byte> phoneNumber;
@@ -47,7 +47,7 @@ public:
enum PhoneType { kTelephone, kNewPhone };
Telephone(PhoneType phoneType) :
- RenderActionRecord(7),
+ PuzzleRecord(7),
_callState(kWaiting),
_buttonLastPushed(-1),
_selected(-1),
@@ -81,8 +81,6 @@ protected:
Common::String _addressBookString;
Common::String _dialAgainString;
SceneChangeWithFlag _reloadScene;
- SceneChangeWithFlag _exitScene;
- Common::Rect _exitHotspot;
Common::Array<PhoneCall> _calls;
// Number of digits a number needs before the phone starts dialing. Numbers
diff --git a/engines/nancy/action/puzzle/towerpuzzle.cpp b/engines/nancy/action/puzzle/towerpuzzle.cpp
index 395a39a922f..42af8f58699 100644
--- a/engines/nancy/action/puzzle/towerpuzzle.cpp
+++ b/engines/nancy/action/puzzle/towerpuzzle.cpp
@@ -83,11 +83,11 @@ void TowerPuzzle::readData(Common::SeekableReadStream &stream) {
_takeSound.readNormal(stream);
_dropSound.readNormal(stream);
- _solveExitScene._sceneChange.readData(stream);
+ _solveScene._sceneChange.readData(stream);
stream.skip(2);
_solveSound.readNormal(stream);
- _solveExitScene._flag.label = stream.readSint16LE();
- _solveExitScene._flag.flag = stream.readByte();
+ _solveScene._flag.label = stream.readSint16LE();
+ _solveScene._flag.flag = stream.readByte();
_exitScene.readData(stream);
readRect(stream, _exitHotspot);
@@ -159,7 +159,7 @@ void TowerPuzzle::execute() {
_exitScene.execute();
break;
case kWaitForSound:
- _solveExitScene.execute();
+ _solveScene.execute();
_puzzleState->playerHasTriedPuzzle = false;
_puzzleState->order.clear();
_puzzleState->order.resize(3, Common::Array<int8>(6, -1));
@@ -195,9 +195,7 @@ void TowerPuzzle::handleInput(NancyInput &input) {
// Not holding a ring
// First, check the exit hotspot
- if (NancySceneState.getViewport().convertViewportToScreen(_exitHotspot).contains(input.mousePos)) {
- g_nancy->_cursor->setCursorType(g_nancy->_cursor->_puzzleExitCursor);
-
+ if (hoverExitHotspot(input)) {
if (input.input & NancyInput::kLeftMouseButtonUp) {
// Player has clicked, exit
_state = kActionTrigger;
diff --git a/engines/nancy/action/puzzle/towerpuzzle.h b/engines/nancy/action/puzzle/towerpuzzle.h
index 23e7ac362d1..058ce320058 100644
--- a/engines/nancy/action/puzzle/towerpuzzle.h
+++ b/engines/nancy/action/puzzle/towerpuzzle.h
@@ -22,7 +22,7 @@
#ifndef NANCY_ACTION_TOWERPUZZLE_H
#define NANCY_ACTION_TOWERPUZZLE_H
-#include "engines/nancy/action/actionrecord.h"
+#include "engines/nancy/action/puzzlerecord.h"
#include "engines/nancy/misc/mousefollow.h"
namespace Nancy {
@@ -31,10 +31,10 @@ struct TowerPuzzleData;
namespace Action {
-class TowerPuzzle : public RenderActionRecord {
+class TowerPuzzle : public PuzzleRecord {
public:
enum SolveState { kNotSolved, kWaitForSound };
- TowerPuzzle() : RenderActionRecord(7) {}
+ TowerPuzzle() : PuzzleRecord(7) {}
virtual ~TowerPuzzle() {}
void init() override;
@@ -62,12 +62,8 @@ protected:
SoundDescription _takeSound;
SoundDescription _dropSound;
- SceneChangeWithFlag _solveExitScene;
SoundDescription _solveSound;
- SceneChangeWithFlag _exitScene;
- Common::Rect _exitHotspot;
-
Graphics::ManagedSurface _image;
Misc::MouseFollowObject _heldRing;
int8 _heldRingID = -1;
diff --git a/engines/nancy/action/puzzle/turningpuzzle.cpp b/engines/nancy/action/puzzle/turningpuzzle.cpp
index 61dbb4913d3..0c4ae89b0e1 100644
--- a/engines/nancy/action/puzzle/turningpuzzle.cpp
+++ b/engines/nancy/action/puzzle/turningpuzzle.cpp
@@ -216,7 +216,7 @@ void TurningPuzzle::readDataNancy13(Common::SeekableReadStream &stream) {
// A count-prefixed array of 23-byte hotspot records (as in PegsPuzzle);
// the first one is the "give up" hotspot.
- readExitHotspot(stream, _exitHotspot, _exitCursorType, _exitScene._sceneChange, _exitScene._flag);
+ readExitHotspot(stream);
uint16 numTypes = stream.readUint16LE();
_pieceTypes.resize(numTypes);
@@ -538,13 +538,7 @@ void TurningPuzzle::execute() {
void TurningPuzzle::handleInput(NancyInput &input) {
const bool isNancy13 = g_nancy->getGameType() >= kGameTypeNancy13;
- if (NancySceneState.getViewport().convertViewportToScreen(_exitHotspot).contains(input.mousePos)) {
- if (isNancy13)
- // Zone cursors use the idle sprite of their type, unlike the hover cursor below.
- g_nancy->_cursor->setCursorType((CursorManager::CursorType)_exitCursorType, true, false);
- else
- g_nancy->_cursor->setCursorType(g_nancy->_cursor->_puzzleExitCursor);
-
+ if (hoverExitHotspot(input)) {
if (input.input & NancyInput::kLeftMouseButtonUp)
_state = kActionTrigger;
diff --git a/engines/nancy/action/puzzle/turningpuzzle.h b/engines/nancy/action/puzzle/turningpuzzle.h
index b0d2e552b46..36466b6e870 100644
--- a/engines/nancy/action/puzzle/turningpuzzle.h
+++ b/engines/nancy/action/puzzle/turningpuzzle.h
@@ -22,7 +22,7 @@
#ifndef NANCY_ACTION_TURNINGPUZZLE_H
#define NANCY_ACTION_TURNINGPUZZLE_H
-#include "engines/nancy/action/actionrecord.h"
+#include "engines/nancy/action/puzzlerecord.h"
namespace Nancy {
namespace Action {
@@ -41,10 +41,10 @@ namespace Action {
// whose frames cycle inside a set of fixed slots), and a time limit, after which the puzzle
// plays its own sound and sends the player to a failure scene. Example: the pocket watch
// puzzle in Dieter's house.
-class TurningPuzzle : public RenderActionRecord {
+class TurningPuzzle : public PuzzleRecord {
public:
enum SolveState { kNotSolved, kWaitForAnimation, kWaitBeforeSound, kWaitForSound };
- TurningPuzzle() : RenderActionRecord(7) {}
+ TurningPuzzle() : PuzzleRecord(7) {}
virtual ~TurningPuzzle() {}
void init() override;
@@ -105,13 +105,9 @@ protected:
Common::Array<uint16> _correctOrder;
- SceneChangeWithFlag _solveScene;
uint16 _solveSoundDelay = 0;
SoundDescription _solveSound;
- SceneChangeWithFlag _exitScene;
- Common::Rect _exitHotspot;
-
// -- Nancy13 only --
Common::Array<PieceType> _pieceTypes;
Common::Array<uint16> _pieceTypeIDs; // per object
@@ -121,7 +117,6 @@ protected:
uint16 _hitInset = 0; // header 0x25 - hotspots are the dest rect shrunk by this
int16 _turnFlagLabel = -1; // header 0x27 - set once the player turns anything
byte _turnFlagValue = 0; // header 0x29
- uint16 _exitCursorType = 0; // from the exit hotspot record
RandomSoundBlock _turnSoundBlock;
RandomSoundBlock _solveSoundBlock;
bool _turnFlagSet = false;
diff --git a/engines/nancy/action/puzzle/twodialpuzzle.cpp b/engines/nancy/action/puzzle/twodialpuzzle.cpp
index 00e7096826c..1c23c4a75f5 100644
--- a/engines/nancy/action/puzzle/twodialpuzzle.cpp
+++ b/engines/nancy/action/puzzle/twodialpuzzle.cpp
@@ -248,9 +248,7 @@ void TwoDialPuzzle::handleInput(NancyInput &input) {
bool canClick = (_state == kRun) && !_isSolved &&
!g_nancy->_sound->isSoundPlaying(_rotateSounds[0]) && !g_nancy->_sound->isSoundPlaying(_rotateSounds[1]);
- if (NancySceneState.getViewport().convertViewportToScreen(_exitHotspot).contains(input.mousePos)) {
- g_nancy->_cursor->setCursorType(g_nancy->_cursor->_puzzleExitCursor);
-
+ if (hoverExitHotspot(input)) {
if (canClick && input.input & NancyInput::kLeftMouseButtonUp) {
_state = kActionTrigger;
}
diff --git a/engines/nancy/action/puzzle/twodialpuzzle.h b/engines/nancy/action/puzzle/twodialpuzzle.h
index ffa6b162d16..4a601bfad2b 100644
--- a/engines/nancy/action/puzzle/twodialpuzzle.h
+++ b/engines/nancy/action/puzzle/twodialpuzzle.h
@@ -22,16 +22,16 @@
#ifndef NANCY_ACTION_TWODIALPUZZLE_H
#define NANCY_ACTION_TWODIALPUZZLE_H
-#include "engines/nancy/action/actionrecord.h"
+#include "engines/nancy/action/puzzlerecord.h"
namespace Nancy {
namespace Action {
// Puzzle with two circular dials overlaid on top of each other. Each dial has one correct
// position, and can only be rotated in one direction.
-class TwoDialPuzzle : public RenderActionRecord {
+class TwoDialPuzzle : public PuzzleRecord {
public:
- TwoDialPuzzle() : RenderActionRecord(7) {}
+ TwoDialPuzzle() : PuzzleRecord(7) {}
virtual ~TwoDialPuzzle() {}
void init() override;
@@ -81,13 +81,9 @@ protected:
SoundDescription _rotateSounds[2];
- SceneChangeWithFlag _solveScene;
uint16 _solveSoundDelay = 0;
SoundDescription _solveSound;
- SceneChangeWithFlag _exitScene;
- Common::Rect _exitHotspot;
-
Graphics::ManagedSurface _image;
int16 _currentPositions[2] = { 0, 0 };
diff --git a/engines/nancy/action/puzzle/typingquizpuzzle.cpp b/engines/nancy/action/puzzle/typingquizpuzzle.cpp
index 3ca4f701dc5..bc5d4f9a486 100644
--- a/engines/nancy/action/puzzle/typingquizpuzzle.cpp
+++ b/engines/nancy/action/puzzle/typingquizpuzzle.cpp
@@ -95,9 +95,10 @@ void TypingQuizPuzzle::readData(Common::SeekableReadStream &stream) {
_wrongSound.readNormal(stream); // 0x497
_escapeSound.readNormal(stream); // 0x4c8
- _winScene.readData(stream); // 0x4f9 (20 bytes)
- _winScene.continueSceneSound = stream.readUint16LE(); // 0x50d
- _winFlag = stream.readSint16LE(); // 0x50f
+ _solveScene._sceneChange.readData(stream); // 0x4f9 (20 bytes)
+ _solveScene._sceneChange.continueSceneSound = stream.readUint16LE(); // 0x50d
+ _solveScene._flag.label = stream.readSint16LE(); // 0x50f
+ _solveScene._flag.flag = g_nancy->_true;
_winSound.readNormal(stream); // 0x511
@@ -380,8 +381,7 @@ void TypingQuizPuzzle::redraw() {
void TypingQuizPuzzle::triggerSceneChange() {
if (_reachedTarget) {
- NancySceneState.setEventFlag(_winFlag, g_nancy->_true);
- NancySceneState.changeScene(_winScene);
+ _solveScene.execute();
} else {
if (_reachedThreshold && _flagThreshold != -1)
NancySceneState.setEventFlag(_flagThreshold, g_nancy->_true);
diff --git a/engines/nancy/action/puzzle/typingquizpuzzle.h b/engines/nancy/action/puzzle/typingquizpuzzle.h
index e76147fccc8..fd53091bdd1 100644
--- a/engines/nancy/action/puzzle/typingquizpuzzle.h
+++ b/engines/nancy/action/puzzle/typingquizpuzzle.h
@@ -22,7 +22,7 @@
#ifndef NANCY_ACTION_TYPINGQUIZPUZZLE_H
#define NANCY_ACTION_TYPINGQUIZPUZZLE_H
-#include "engines/nancy/action/actionrecord.h"
+#include "engines/nancy/action/puzzlerecord.h"
#include "engines/nancy/commontypes.h"
#include "graphics/managed_surface.h"
@@ -36,9 +36,9 @@ namespace Action {
// a typing rate (characters per minute). If the final rate meets the target, the win
// scene fires; otherwise a default scene fires (with a different event flag depending on
// whether a partial threshold was reached). Unrelated to the text-entry QuizPuzzle (231).
-class TypingQuizPuzzle : public RenderActionRecord {
+class TypingQuizPuzzle : public PuzzleRecord {
public:
- TypingQuizPuzzle() : RenderActionRecord(7) {}
+ TypingQuizPuzzle() : PuzzleRecord(7) {}
virtual ~TypingQuizPuzzle() {}
void init() override;
@@ -123,9 +123,6 @@ private:
SoundDescription _wrongSound; // 0x497 wrong key
SoundDescription _escapeSound; // 0x4c8 balloon floated away
- SceneChangeDescription _winScene; // 0x4f9 (9999 = none)
- int16 _winFlag = -1; // 0x50f
-
SoundDescription _winSound; // 0x511 played when the target is met
SceneChangeDescription _defaultScene; // 0x542 (did not reach the target)
diff --git a/engines/nancy/action/puzzle/weightsortpuzzle.cpp b/engines/nancy/action/puzzle/weightsortpuzzle.cpp
index 635793e42ff..a918fbadeef 100644
--- a/engines/nancy/action/puzzle/weightsortpuzzle.cpp
+++ b/engines/nancy/action/puzzle/weightsortpuzzle.cpp
@@ -128,8 +128,8 @@ void WeightSortPuzzle::readData(Common::SeekableReadStream &stream) {
outcome.sound.readData(stream);
}
- readExitHotspot(stream, _exitHotspot, _exitCursorType, _exitScene, _exitFlag);
- _exitScene.continueSceneSound = kContinueSceneSound;
+ readExitHotspot(stream);
+ _exitScene._sceneChange.continueSceneSound = kContinueSceneSound;
}
// Drops the object at a random spot fully inside its container.
@@ -439,8 +439,7 @@ void WeightSortPuzzle::execute() {
break;
case kActionTrigger:
if (_exitRequested) {
- NancySceneState.setEventFlag(_exitFlag);
- NancySceneState.changeScene(_exitScene);
+ _exitScene.execute();
} else {
NancySceneState.setEventFlag(_outcomes[_outcome].flag);
NancySceneState.changeScene(_outcomes[_outcome].scene);
@@ -533,9 +532,7 @@ void WeightSortPuzzle::handleInput(NancyInput &input) {
return;
}
- if (!_exitHotspot.isEmpty() &&
- NancySceneState.getViewport().convertViewportToScreen(_exitHotspot).contains(input.mousePos)) {
- setDataCursor(_exitCursorType, false);
+ if (hoverExitHotspot(input)) {
if (click) {
_exitRequested = true;
}
diff --git a/engines/nancy/action/puzzle/weightsortpuzzle.h b/engines/nancy/action/puzzle/weightsortpuzzle.h
index bf3da58e078..0f3d16c14dd 100644
--- a/engines/nancy/action/puzzle/weightsortpuzzle.h
+++ b/engines/nancy/action/puzzle/weightsortpuzzle.h
@@ -23,7 +23,7 @@
#define NANCY_ACTION_WEIGHTSORTPUZZLE_H
#include "engines/nancy/commontypes.h"
-#include "engines/nancy/action/actionrecord.h"
+#include "engines/nancy/action/puzzlerecord.h"
#include "engines/nancy/misc/mousefollow.h"
namespace Nancy {
@@ -38,9 +38,9 @@ namespace Action {
//
// A board whose containers do not count towards either outcome never ends on its own and
// is left through the give-up hotspot, which is what the Nancy15 sort screen does.
-class WeightSortPuzzle : public RenderActionRecord {
+class WeightSortPuzzle : public PuzzleRecord {
public:
- WeightSortPuzzle() : RenderActionRecord(7) {}
+ WeightSortPuzzle() : PuzzleRecord(7) {}
virtual ~WeightSortPuzzle() {}
void init() override;
@@ -142,11 +142,6 @@ protected:
RandomSoundBlock _rejectSound; // a container refusing an object
Outcome _outcomes[kNumOutcomes];
- Common::Rect _exitHotspot;
- uint16 _exitCursorType = 0;
- SceneChangeDescription _exitScene;
- FlagDescription _exitFlag;
-
// -- Runtime state --
Common::Array<Object> _objects;
int _carriedObjectID = -1;
diff --git a/engines/nancy/action/puzzle/whalesurvivorpuzzle.cpp b/engines/nancy/action/puzzle/whalesurvivorpuzzle.cpp
index 624d0b1d75b..4ba77af415f 100644
--- a/engines/nancy/action/puzzle/whalesurvivorpuzzle.cpp
+++ b/engines/nancy/action/puzzle/whalesurvivorpuzzle.cpp
@@ -180,7 +180,7 @@ void WhaleSurvivorPuzzle::readData(Common::SeekableReadStream &stream) {
_sound5.readNormal(stream); // 0x9ea (unused/silence)
// Scenes and remaining sounds
- _winScene.readData(stream); // 0xa1b (25 bytes)
+ _solveScene.readData(stream); // 0xa1b (25 bytes)
stream.skip(1); // 0xa34 padding byte
_winSound.readNormal(stream); // 0xa35
_lossScene.readData(stream); // 0xa66 (25 bytes)
@@ -464,7 +464,7 @@ void WhaleSurvivorPuzzle::execute() {
g_nancy->_sound->stopSound(_gameOverSound);
if (_executeWin)
- _winScene.execute();
+ _solveScene.execute();
else
_lossScene.execute();
diff --git a/engines/nancy/action/puzzle/whalesurvivorpuzzle.h b/engines/nancy/action/puzzle/whalesurvivorpuzzle.h
index 1244cd65ad0..1ad962a35af 100644
--- a/engines/nancy/action/puzzle/whalesurvivorpuzzle.h
+++ b/engines/nancy/action/puzzle/whalesurvivorpuzzle.h
@@ -22,7 +22,7 @@
#ifndef NANCY_ACTION_WHALESURVIVORPUZZLE_H
#define NANCY_ACTION_WHALESURVIVORPUZZLE_H
-#include "engines/nancy/action/actionrecord.h"
+#include "engines/nancy/action/puzzlerecord.h"
#include "engines/nancy/commontypes.h"
#include "graphics/managed_surface.h"
@@ -34,9 +34,9 @@ namespace Action {
// The player controls Dolly the dall's porpoise, eating fish while avoiding hazards
// (sharks, octopuses, orcas, pollution) and periodically surfacing to breathe.
// Win by reaching the score target. Two difficulty levels (easy/hard).
-class WhaleSurvivorPuzzle : public RenderActionRecord {
+class WhaleSurvivorPuzzle : public PuzzleRecord {
public:
- WhaleSurvivorPuzzle() : RenderActionRecord(7) {}
+ WhaleSurvivorPuzzle() : PuzzleRecord(7) {}
virtual ~WhaleSurvivorPuzzle() {}
void init() override;
@@ -157,7 +157,6 @@ private:
SceneChangeWithFlag _lossScene; // 0xa1b
SoundDescription _winSound; // 0xa35
- SceneChangeWithFlag _winScene; // 0xa66
SoundDescription _gameOverSound; // 0xa80
SoundDescription _tryAgainSound; // 0xab1
diff --git a/engines/nancy/action/puzzle/wordfindpuzzle.cpp b/engines/nancy/action/puzzle/wordfindpuzzle.cpp
index a5b334caa78..dc352c68a39 100644
--- a/engines/nancy/action/puzzle/wordfindpuzzle.cpp
+++ b/engines/nancy/action/puzzle/wordfindpuzzle.cpp
@@ -45,7 +45,7 @@ void WordFindPuzzle::readData(Common::SeekableReadStream &stream) {
_cellGapX = stream.readUint16LE(); // 0x06
_cellGapY = stream.readUint16LE(); // 0x08
stream.skip(0x20); // 0x0a
- _solveScene.sceneID = stream.readUint16LE(); // 0x2a - shown once every word is found
+ _solveScene._sceneChange.sceneID = stream.readUint16LE(); // 0x2a - shown once every word is found
stream.skip(3); // 0x2c
readFilename(stream, _solutionImageName); // 0x2f
uint16 numWords = stream.readUint16LE(); // 0x50
@@ -70,7 +70,7 @@ void WordFindPuzzle::readData(Common::SeekableReadStream &stream) {
}
// The shared 23-byte exit-hotspot record.
- readExitHotspot(stream, _exitHotspot, _exitCursorType, _exitScene, _exitFlag);
+ readExitHotspot(stream);
_sounds.resize(4);
for (uint i = 0; i < 4; ++i) {
@@ -306,9 +306,9 @@ void WordFindPuzzle::execute() {
}
case kActionTrigger: {
if (!_allFound) {
- NancySceneState.setEventFlag(_exitFlag);
+ NancySceneState.setEventFlag(_exitScene._flag);
}
- NancySceneState.changeScene(_allFound ? _solveScene : _exitScene);
+ NancySceneState.changeScene(_allFound ? _solveScene._sceneChange : _exitScene._sceneChange);
finishExecution();
break;
@@ -376,9 +376,7 @@ void WordFindPuzzle::handleInput(NancyInput &input) {
return;
}
- if (!_exitHotspot.isEmpty() &&
- NancySceneState.getViewport().convertViewportToScreen(_exitHotspot).contains(input.mousePos)) {
- g_nancy->_cursor->setCursorType((CursorManager::CursorType)_exitCursorType, true, false);
+ if (hoverExitHotspot(input)) {
if (input.input & NancyInput::kLeftMouseButtonUp) {
_state = kActionTrigger;
}
diff --git a/engines/nancy/action/puzzle/wordfindpuzzle.h b/engines/nancy/action/puzzle/wordfindpuzzle.h
index 2a9a8eaa086..0d7a367d436 100644
--- a/engines/nancy/action/puzzle/wordfindpuzzle.h
+++ b/engines/nancy/action/puzzle/wordfindpuzzle.h
@@ -24,7 +24,7 @@
#include "engines/nancy/commontypes.h"
#include "engines/nancy/movieplayer.h"
-#include "engines/nancy/action/actionrecord.h"
+#include "engines/nancy/action/puzzlerecord.h"
namespace Nancy {
@@ -37,9 +37,9 @@ namespace Action {
// scene visits), building a connected chain of orthogonally-adjacent letter cells;
// once the chain has the word's length and matches the answer path, the word's
// animation plays and the next word becomes active.
-class WordFindPuzzle : public RenderActionRecord {
+class WordFindPuzzle : public PuzzleRecord {
public:
- WordFindPuzzle() : RenderActionRecord(7) {}
+ WordFindPuzzle() : PuzzleRecord(7) {}
virtual ~WordFindPuzzle() {}
void init() override;
@@ -78,15 +78,9 @@ protected:
uint16 _cursorType = 0; // base 0x00
uint16 _cellGapX = 0; // base 0x06 - added to a letter's width to get the column pitch
uint16 _cellGapY = 0; // base 0x08 - row pitch component
- SceneChangeDescription _solveScene; // base 0x2a - shown once every word is found
Common::Path _solutionImageName; // base 0x2f
Common::Array<Word> _words;
- Common::Rect _exitHotspot;
- uint16 _exitCursorType = 0;
- SceneChangeDescription _exitScene;
- FlagDescription _exitFlag; // set on give-up
-
Common::Array<RandomSoundBlock> _sounds; // 4 blocks
// -- Runtime state --
diff --git a/engines/nancy/action/puzzlerecord.cpp b/engines/nancy/action/puzzlerecord.cpp
new file mode 100644
index 00000000000..03afbb03662
--- /dev/null
+++ b/engines/nancy/action/puzzlerecord.cpp
@@ -0,0 +1,89 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "engines/nancy/nancy.h"
+#include "engines/nancy/cursor.h"
+#include "engines/nancy/input.h"
+#include "engines/nancy/util.h"
+
+#include "engines/nancy/state/scene.h"
+
+#include "engines/nancy/action/puzzlerecord.h"
+
+namespace Nancy {
+namespace Action {
+
+static void appendSceneInfo(Common::String &info, const char *name, const SceneChangeWithFlag &scene) {
+ if (scene._sceneChange.sceneID == kNoScene) {
+ return;
+ }
+
+ if (!info.empty()) {
+ info += ", ";
+ }
+
+ info += Common::String::format("%s scene %u", name, scene._sceneChange.sceneID);
+
+ if (scene._flag.label != kEvNoEvent) {
+ info += Common::String::format(" (flag %d, %s -> %s)", scene._flag.label,
+ g_nancy->getEventFlagName(scene._flag.label).c_str(),
+ scene._flag.flag == g_nancy->_true ? "true" : "false");
+ }
+}
+
+Common::String PuzzleRecord::getRecordExtraInfo() const {
+ Common::String info;
+ appendSceneInfo(info, "Solve", _solveScene);
+ appendSceneInfo(info, "Exit", _exitScene);
+ return info;
+}
+
+void PuzzleRecord::readExitHotspot(Common::SeekableReadStream &stream) {
+ Nancy::readExitHotspot(stream, _exitHotspot, _exitCursorType, _exitScene._sceneChange, _exitScene._flag);
+ _exitCursorFromData = true;
+}
+
+bool PuzzleRecord::isExitHotspotHovered(const NancyInput &input) const {
+ return !_exitHotspot.isEmpty() &&
+ NancySceneState.getViewport().convertViewportToScreen(_exitHotspot).contains(input.mousePos);
+}
+
+void PuzzleRecord::setExitCursor() const {
+ if (_exitCursorFromData) {
+ // Zone cursors use the idle sprite in Nancy13, and the hotspot sprite from Nancy14 on
+ g_nancy->_cursor->setCursorType((CursorManager::CursorType)_exitCursorType, true,
+ g_nancy->getGameType() >= kGameTypeNancy14);
+ } else {
+ g_nancy->_cursor->setCursorType(g_nancy->_cursor->_puzzleExitCursor);
+ }
+}
+
+bool PuzzleRecord::hoverExitHotspot(const NancyInput &input) const {
+ if (!isExitHotspotHovered(input)) {
+ return false;
+ }
+
+ setExitCursor();
+ return true;
+}
+
+} // End of namespace Action
+} // End of namespace Nancy
diff --git a/engines/nancy/action/puzzlerecord.h b/engines/nancy/action/puzzlerecord.h
new file mode 100644
index 00000000000..db9eabb01d8
--- /dev/null
+++ b/engines/nancy/action/puzzlerecord.h
@@ -0,0 +1,64 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef NANCY_ACTION_PUZZLERECORD_H
+#define NANCY_ACTION_PUZZLERECORD_H
+
+#include "engines/nancy/commontypes.h"
+#include "engines/nancy/action/actionrecord.h"
+
+namespace Nancy {
+namespace Action {
+
+// Common base for all puzzle action records. Holds the scene changes and
+// give-up hotspot that nearly every puzzle has.
+class PuzzleRecord : public RenderActionRecord {
+public:
+ PuzzleRecord(uint zOrder) : RenderActionRecord(zOrder) {}
+ virtual ~PuzzleRecord() {}
+
+ Common::String getRecordExtraInfo() const override;
+
+protected:
+ // Reads the Nancy 13+ count-prefixed give-up hotspot array into the exit fields,
+ // keeping only the first record.
+ void readExitHotspot(Common::SeekableReadStream &stream);
+
+ bool isExitHotspotHovered(const NancyInput &input) const;
+ void setExitCursor() const;
+
+ // Shows the exit cursor and returns true while the mouse is over the give-up hotspot
+ bool hoverExitHotspot(const NancyInput &input) const;
+
+ // Scene the puzzle moves to when solved; its flag is set on solve
+ SceneChangeWithFlag _solveScene;
+
+ // Scene the puzzle moves to when left unsolved, e.g. via the give-up hotspot
+ SceneChangeWithFlag _exitScene;
+ Common::Rect _exitHotspot;
+ uint16 _exitCursorType = 0;
+ bool _exitCursorFromData = false; // otherwise the generic puzzle exit cursor is used
+};
+
+} // End of namespace Action
+} // End of namespace Nancy
+
+#endif // NANCY_ACTION_PUZZLERECORD_H
diff --git a/engines/nancy/module.mk b/engines/nancy/module.mk
index e511f6857af..6a446f35090 100644
--- a/engines/nancy/module.mk
+++ b/engines/nancy/module.mk
@@ -15,6 +15,7 @@ MODULE_OBJS = \
action/conversation.o \
action/interactivevideo.o \
action/overlay.o \
+ action/puzzlerecord.o \
action/secondarymovie.o \
action/secondaryvideo.o \
action/puzzle/adjustpuzzle.o \
Commit: 5d39de020c1fb2f4ca65ab069a35d97e54c1e492
https://github.com/scummvm/scummvm/commit/5d39de020c1fb2f4ca65ab069a35d97e54c1e492
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2026-09-26T04:54:27+03:00
Commit Message:
NANCY: Centralize puzzle solve sound handling
Changed paths:
engines/nancy/action/puzzle/assemblypuzzle.cpp
engines/nancy/action/puzzle/assemblypuzzle.h
engines/nancy/action/puzzle/blockspuzzle.cpp
engines/nancy/action/puzzle/blockspuzzle.h
engines/nancy/action/puzzle/bombpuzzle.cpp
engines/nancy/action/puzzle/bombpuzzle.h
engines/nancy/action/puzzle/bulpuzzle.h
engines/nancy/action/puzzle/collisionpuzzle.cpp
engines/nancy/action/puzzle/collisionpuzzle.h
engines/nancy/action/puzzle/cubepuzzle.cpp
engines/nancy/action/puzzle/cubepuzzle.h
engines/nancy/action/puzzle/cuttingpuzzle.cpp
engines/nancy/action/puzzle/cuttingpuzzle.h
engines/nancy/action/puzzle/decoderpuzzle.cpp
engines/nancy/action/puzzle/decoderpuzzle.h
engines/nancy/action/puzzle/dotconnectpuzzle.cpp
engines/nancy/action/puzzle/dotconnectpuzzle.h
engines/nancy/action/puzzle/escapegridpuzzle.cpp
engines/nancy/action/puzzle/escapegridpuzzle.h
engines/nancy/action/puzzle/gridmappuzzle.cpp
engines/nancy/action/puzzle/gridmappuzzle.h
engines/nancy/action/puzzle/hamradiopuzzle.cpp
engines/nancy/action/puzzle/hamradiopuzzle.h
engines/nancy/action/puzzle/lettergridpuzzle.cpp
engines/nancy/action/puzzle/lettergridpuzzle.h
engines/nancy/action/puzzle/leverpuzzle.cpp
engines/nancy/action/puzzle/leverpuzzle.h
engines/nancy/action/puzzle/magicboxpuzzle.cpp
engines/nancy/action/puzzle/magicboxpuzzle.h
engines/nancy/action/puzzle/magnetmazepuzzle.cpp
engines/nancy/action/puzzle/magnetmazepuzzle.h
engines/nancy/action/puzzle/mazechasepuzzle.cpp
engines/nancy/action/puzzle/mazechasepuzzle.h
engines/nancy/action/puzzle/memorypuzzle.cpp
engines/nancy/action/puzzle/memorypuzzle.h
engines/nancy/action/puzzle/multibuildpuzzle.cpp
engines/nancy/action/puzzle/multibuildpuzzle.h
engines/nancy/action/puzzle/onebuildpuzzle.cpp
engines/nancy/action/puzzle/onebuildpuzzle.h
engines/nancy/action/puzzle/orderingpuzzle.cpp
engines/nancy/action/puzzle/orderingpuzzle.h
engines/nancy/action/puzzle/overridelockpuzzle.cpp
engines/nancy/action/puzzle/overridelockpuzzle.h
engines/nancy/action/puzzle/paintpuzzle.cpp
engines/nancy/action/puzzle/paintpuzzle.h
engines/nancy/action/puzzle/passwordpuzzle.cpp
engines/nancy/action/puzzle/passwordpuzzle.h
engines/nancy/action/puzzle/quizpuzzle.cpp
engines/nancy/action/puzzle/quizpuzzle.h
engines/nancy/action/puzzle/raycastpuzzle.cpp
engines/nancy/action/puzzle/raycastpuzzle.h
engines/nancy/action/puzzle/riddlepuzzle.cpp
engines/nancy/action/puzzle/riddlepuzzle.h
engines/nancy/action/puzzle/rippedletterpuzzle.cpp
engines/nancy/action/puzzle/rippedletterpuzzle.h
engines/nancy/action/puzzle/rotatinglockpuzzle.cpp
engines/nancy/action/puzzle/rotatinglockpuzzle.h
engines/nancy/action/puzzle/safedialpuzzle.cpp
engines/nancy/action/puzzle/safedialpuzzle.h
engines/nancy/action/puzzle/scalepuzzle.cpp
engines/nancy/action/puzzle/scalepuzzle.h
engines/nancy/action/puzzle/setplayerclock.cpp
engines/nancy/action/puzzle/setplayerclock.h
engines/nancy/action/puzzle/sliderpuzzle.cpp
engines/nancy/action/puzzle/sliderpuzzle.h
engines/nancy/action/puzzle/sortpuzzle.cpp
engines/nancy/action/puzzle/sortpuzzle.h
engines/nancy/action/puzzle/soundmatchpuzzle.cpp
engines/nancy/action/puzzle/soundmatchpuzzle.h
engines/nancy/action/puzzle/spigotpuzzle.cpp
engines/nancy/action/puzzle/spigotpuzzle.h
engines/nancy/action/puzzle/stepobjectspuzzle.cpp
engines/nancy/action/puzzle/stepobjectspuzzle.h
engines/nancy/action/puzzle/tangrampuzzle.cpp
engines/nancy/action/puzzle/tangrampuzzle.h
engines/nancy/action/puzzle/towerpuzzle.cpp
engines/nancy/action/puzzle/towerpuzzle.h
engines/nancy/action/puzzle/turningpuzzle.cpp
engines/nancy/action/puzzle/turningpuzzle.h
engines/nancy/action/puzzle/twodialpuzzle.cpp
engines/nancy/action/puzzle/twodialpuzzle.h
engines/nancy/action/puzzle/typingquizpuzzle.cpp
engines/nancy/action/puzzle/typingquizpuzzle.h
engines/nancy/action/puzzle/whalesurvivorpuzzle.cpp
engines/nancy/action/puzzle/whalesurvivorpuzzle.h
engines/nancy/action/puzzlerecord.cpp
engines/nancy/action/puzzlerecord.h
diff --git a/engines/nancy/action/puzzle/assemblypuzzle.cpp b/engines/nancy/action/puzzle/assemblypuzzle.cpp
index 283b6c6a14c..8d93bd5482d 100644
--- a/engines/nancy/action/puzzle/assemblypuzzle.cpp
+++ b/engines/nancy/action/puzzle/assemblypuzzle.cpp
@@ -135,8 +135,7 @@ void AssemblyPuzzle::execute() {
return;
}
- g_nancy->_sound->loadSound(_solveSound);
- g_nancy->_sound->playSound(_solveSound);
+ playSolveSound();
showSubtitle(_solveText);
NancySceneState.setEventFlag(_solveScene._flag);
_completed = true;
@@ -144,7 +143,7 @@ void AssemblyPuzzle::execute() {
_state = kActionTrigger;
break;
case kActionTrigger:
- if (g_nancy->_sound->isSoundPlaying(_solveSound)) {
+ if (isSolveSoundPlaying()) {
return;
}
@@ -160,7 +159,7 @@ void AssemblyPuzzle::execute() {
}
void AssemblyPuzzle::handleInput(NancyInput &input) {
- if (_state == kActionTrigger && _completed && g_nancy->_sound->isSoundPlaying(_solveSound)) {
+ if (_state == kActionTrigger && _completed && isSolveSoundPlaying()) {
return;
}
diff --git a/engines/nancy/action/puzzle/assemblypuzzle.h b/engines/nancy/action/puzzle/assemblypuzzle.h
index 31d37383c57..0cfe2cc8f20 100644
--- a/engines/nancy/action/puzzle/assemblypuzzle.h
+++ b/engines/nancy/action/puzzle/assemblypuzzle.h
@@ -84,7 +84,6 @@ protected:
Common::Array<SoundDescription> _wrongPieceSounds;
Common::Array<Common::String> _wrongPieceTexts;
- SoundDescription _solveSound;
Common::String _solveText;
Graphics::ManagedSurface _image;
diff --git a/engines/nancy/action/puzzle/blockspuzzle.cpp b/engines/nancy/action/puzzle/blockspuzzle.cpp
index 5349ea446dd..1a74cdf105d 100644
--- a/engines/nancy/action/puzzle/blockspuzzle.cpp
+++ b/engines/nancy/action/puzzle/blockspuzzle.cpp
@@ -308,7 +308,7 @@ void BlocksPuzzle::execute() {
_solveSound = playSoundBlock(_sounds[kSuccessSound]);
_puzzleState = kWaitSolved;
- if (_solveSound.name.empty()) {
+ if (!hasSolveSound()) {
_state = kActionTrigger;
}
@@ -356,7 +356,7 @@ void BlocksPuzzle::execute() {
break;
case kWaitSolved:
- if (!g_nancy->_sound->isSoundPlaying(_solveSound)) {
+ if (!isSolveSoundPlaying()) {
_state = kActionTrigger;
}
diff --git a/engines/nancy/action/puzzle/blockspuzzle.h b/engines/nancy/action/puzzle/blockspuzzle.h
index 3de41606aa7..d0e04190ce4 100644
--- a/engines/nancy/action/puzzle/blockspuzzle.h
+++ b/engines/nancy/action/puzzle/blockspuzzle.h
@@ -138,7 +138,6 @@ protected:
bool _solved = false;
bool _exitRequested = false;
- SoundDescription _solveSound; // the cue we wait on before changing scene
Graphics::ManagedSurface _image;
};
diff --git a/engines/nancy/action/puzzle/bombpuzzle.cpp b/engines/nancy/action/puzzle/bombpuzzle.cpp
index bfd598570c3..4debe05342e 100644
--- a/engines/nancy/action/puzzle/bombpuzzle.cpp
+++ b/engines/nancy/action/puzzle/bombpuzzle.cpp
@@ -213,8 +213,7 @@ void BombPuzzle::execute() {
if (_playerOrder.size() == _solveOrder.size()) {
_failed = false;
_state = kActionTrigger;
- g_nancy->_sound->loadSound(_solveSound);
- g_nancy->_sound->playSound(_solveSound);
+ playSolveSound();
}
break;
@@ -228,7 +227,7 @@ void BombPuzzle::execute() {
g_nancy->_sound->stopSound(_failSound);
_failSceneChange.execute();
} else {
- if (g_nancy->_sound->isSoundPlaying(_solveSound)) {
+ if (isSolveSoundPlaying()) {
return;
}
diff --git a/engines/nancy/action/puzzle/bombpuzzle.h b/engines/nancy/action/puzzle/bombpuzzle.h
index 433f00381ac..83f32e1036d 100644
--- a/engines/nancy/action/puzzle/bombpuzzle.h
+++ b/engines/nancy/action/puzzle/bombpuzzle.h
@@ -56,7 +56,6 @@ protected:
SoundDescription _snipSound;
SoundDescription _noToolSound;
uint16 _toolID = 0;
- SoundDescription _solveSound;
SceneChangeWithFlag _failSceneChange;
SoundDescription _failSound;
diff --git a/engines/nancy/action/puzzle/bulpuzzle.h b/engines/nancy/action/puzzle/bulpuzzle.h
index 0428f74817c..f28bd4a7569 100644
--- a/engines/nancy/action/puzzle/bulpuzzle.h
+++ b/engines/nancy/action/puzzle/bulpuzzle.h
@@ -110,9 +110,6 @@ protected:
SoundDescription _passSound;
SoundDescription _resetSound;
- uint16 _solveSoundDelay = 0;
- SoundDescription _solveSound;
-
uint16 _loseSoundDelay = 0;
SoundDescription _loseSound;
SceneChangeWithFlag _giveUpScene; // nancy11: separate scene reached by giving up via the exit hotspot
diff --git a/engines/nancy/action/puzzle/collisionpuzzle.cpp b/engines/nancy/action/puzzle/collisionpuzzle.cpp
index 369a3af89ca..755561c389d 100644
--- a/engines/nancy/action/puzzle/collisionpuzzle.cpp
+++ b/engines/nancy/action/puzzle/collisionpuzzle.cpp
@@ -397,13 +397,12 @@ void CollisionPuzzle::execute() {
return;
}
- g_nancy->_sound->loadSound(_solveSound);
- g_nancy->_sound->playSound(_solveSound);
+ playSolveSound();
NancySceneState.setEventFlag(_solveScene._flag);
_solveSoundPlayTime = 0;
return;
} else {
- if (g_nancy->_sound->isSoundPlaying(_solveSound)) {
+ if (isSolveSoundPlaying()) {
return;
}
diff --git a/engines/nancy/action/puzzle/collisionpuzzle.h b/engines/nancy/action/puzzle/collisionpuzzle.h
index 656deb382ca..565230eaa82 100644
--- a/engines/nancy/action/puzzle/collisionpuzzle.h
+++ b/engines/nancy/action/puzzle/collisionpuzzle.h
@@ -111,9 +111,6 @@ protected:
SoundDescription _wallHitSound;
SoundDescription _exitButtonSound;
- uint16 _solveSoundDelay = 0;
- SoundDescription _solveSound;
-
Graphics::ManagedSurface _image;
Common::Array<Piece> _pieces;
diff --git a/engines/nancy/action/puzzle/cubepuzzle.cpp b/engines/nancy/action/puzzle/cubepuzzle.cpp
index 97923cd7005..3f7c8fc622d 100644
--- a/engines/nancy/action/puzzle/cubepuzzle.cpp
+++ b/engines/nancy/action/puzzle/cubepuzzle.cpp
@@ -116,15 +116,14 @@ void CubePuzzle::execute() {
}
}
- g_nancy->_sound->loadSound(_solveSound);
- g_nancy->_sound->playSound(_solveSound);
+ playSolveSound();
NancySceneState.setEventFlag(_solveScene._flag);
_completed = true;
_state = kActionTrigger;
break;
case kActionTrigger:
- if (g_nancy->_sound->isSoundPlaying(_solveSound)) {
+ if (isSolveSoundPlaying()) {
return;
}
diff --git a/engines/nancy/action/puzzle/cubepuzzle.h b/engines/nancy/action/puzzle/cubepuzzle.h
index 644a6762eee..f413987183d 100644
--- a/engines/nancy/action/puzzle/cubepuzzle.h
+++ b/engines/nancy/action/puzzle/cubepuzzle.h
@@ -80,7 +80,6 @@ protected:
// Multiple solve scenes, one for each cube orientation
Common::Array<uint> _solveSceneIDs;
- SoundDescription _solveSound;
Graphics::ManagedSurface _image;
Misc::MouseFollowObject _curPiece;
diff --git a/engines/nancy/action/puzzle/cuttingpuzzle.cpp b/engines/nancy/action/puzzle/cuttingpuzzle.cpp
index 24acb7d9ebc..f526ba86b5c 100644
--- a/engines/nancy/action/puzzle/cuttingpuzzle.cpp
+++ b/engines/nancy/action/puzzle/cuttingpuzzle.cpp
@@ -73,9 +73,9 @@ void CuttingPuzzle::readData(Common::SeekableReadStream &stream) {
_cutSound.readNormal(stream); // +0x4a0 (49 bytes)
_solveScene.readData(stream); // +0x4d1 (25 bytes)
- _doneSoundDelaySecs = stream.readUint16LE(); // +0x4ea
+ _solveSoundDelay = stream.readUint16LE(); // +0x4ea
- _doneSound.readNormal(stream); // +0x4ec (49 bytes)
+ _solveSound.readNormal(stream); // +0x4ec (49 bytes)
_itemCheckByte = stream.readByte(); // +0x51d
_itemID = stream.readSint16LE(); // +0x51e
@@ -206,7 +206,7 @@ void CuttingPuzzle::execute() {
}
if (allMatch) {
_solved = true;
- _timerDeadline = g_system->getMillis() + (uint32)_doneSoundDelaySecs * 1000;
+ _timerDeadline = g_system->getMillis() + (uint32)_solveSoundDelay * 1000;
_subState = kWaitTimer;
break;
}
@@ -275,8 +275,7 @@ void CuttingPuzzle::execute() {
case kLatheFinished:
if (_solved) {
// Load and play the completion sound, then wait for it to finish.
- g_nancy->_sound->loadSound(_doneSound);
- g_nancy->_sound->playSound(_doneSound);
+ playSolveSound();
_subState = kWaitDoneSound;
} else {
// Not solved: finish this AR (will process outcome in kActionTrigger).
@@ -295,8 +294,8 @@ void CuttingPuzzle::execute() {
break;
case kWaitDoneSound:
- if (!g_nancy->_sound->isSoundPlaying(_doneSound)) {
- g_nancy->_sound->stopSound(_doneSound);
+ if (!isSolveSoundPlaying()) {
+ g_nancy->_sound->stopSound(_solveSound);
_state = kActionTrigger;
}
break;
diff --git a/engines/nancy/action/puzzle/cuttingpuzzle.h b/engines/nancy/action/puzzle/cuttingpuzzle.h
index 520cc7b96ed..9e42d6bfe74 100644
--- a/engines/nancy/action/puzzle/cuttingpuzzle.h
+++ b/engines/nancy/action/puzzle/cuttingpuzzle.h
@@ -105,9 +105,6 @@ protected:
SoundDescription _depthSound; // data+0x46f depth adjust sound
SoundDescription _cutSound; // data+0x4a0 groove-cutting sound
- uint16 _doneSoundDelaySecs = 0; // data+0x4ea wait before playing done sound (seconds)
- SoundDescription _doneSound; // data+0x4ec
-
byte _itemCheckByte = 0; // data+0x51d 0=no check, nonzero=require inventory item
int16 _itemID = -1; // data+0x51e
diff --git a/engines/nancy/action/puzzle/decoderpuzzle.cpp b/engines/nancy/action/puzzle/decoderpuzzle.cpp
index 9e0f1440c1a..fcba369c920 100644
--- a/engines/nancy/action/puzzle/decoderpuzzle.cpp
+++ b/engines/nancy/action/puzzle/decoderpuzzle.cpp
@@ -128,7 +128,7 @@ void DecoderPuzzle::readData(Common::SeekableReadStream &stream) {
_solveScene._flag.label = stream.readSint16LE();
_solveScene._flag.flag = stream.readByte();
- _solveSound.readData(stream); // 0x185
+ _solveSoundBlock.readData(stream); // 0x185
readExitHotspot(stream);
_exitScene._sceneChange.continueSceneSound = kContinueSceneSound;
@@ -292,7 +292,7 @@ void DecoderPuzzle::execute() {
if (_solved) {
_resetMovie.close();
_resetting = false;
- playSoundBlock(_solveSound);
+ playSoundBlock(_solveSoundBlock);
_state = kActionTrigger;
break;
}
@@ -342,7 +342,7 @@ void DecoderPuzzle::execute() {
break;
case kActionTrigger:
// The solve voiceover gets to finish first
- if (!_exitRequested && isSoundBlockPlaying(_solveSound)) {
+ if (!_exitRequested && isSoundBlockPlaying(_solveSoundBlock)) {
break;
}
diff --git a/engines/nancy/action/puzzle/decoderpuzzle.h b/engines/nancy/action/puzzle/decoderpuzzle.h
index 28d0299e448..1ed7a5cebba 100644
--- a/engines/nancy/action/puzzle/decoderpuzzle.h
+++ b/engines/nancy/action/puzzle/decoderpuzzle.h
@@ -96,7 +96,7 @@ protected:
Common::Rect _resetMovieRect; // 0x11f
RandomSoundBlock _resetSound; // 0x12f, plays while it runs
- RandomSoundBlock _solveSound; // 0x185, plays before the scene change
+ RandomSoundBlock _solveSoundBlock; // 0x185, plays before the scene change
// -- Runtime state --
MoviePlayer _resetMovie;
diff --git a/engines/nancy/action/puzzle/dotconnectpuzzle.cpp b/engines/nancy/action/puzzle/dotconnectpuzzle.cpp
index aad7ed91eb3..0e73ba5327b 100644
--- a/engines/nancy/action/puzzle/dotconnectpuzzle.cpp
+++ b/engines/nancy/action/puzzle/dotconnectpuzzle.cpp
@@ -61,8 +61,8 @@ void DotConnectPuzzle::readData(Common::SeekableReadStream &stream) {
stream.skip(2);
_solveScene._flag.label = stream.readSint16LE();
_solveScene._flag.flag = stream.readByte();
- _winDelaySec = stream.readUint16LE();
- _winSound.readNormal(stream);
+ _solveSoundDelay = stream.readUint16LE();
+ _solveSound.readNormal(stream);
_exitScene._sceneChange.readData(stream);
stream.skip(2);
@@ -118,9 +118,8 @@ void DotConnectPuzzle::execute() {
break;
case kWaitWinDelay:
if (g_system->getMillis() >= _winDelayEndTime) {
- if (_winSound.name != "NO SOUND") {
- g_nancy->_sound->loadSound(_winSound);
- g_nancy->_sound->playSound(_winSound);
+ if (hasSolveSound()) {
+ playSolveSound();
_subState = kWaitWinSound;
} else {
_subState = kExitToWin;
@@ -131,8 +130,8 @@ void DotConnectPuzzle::execute() {
_subState = kWaitWinSound;
break;
case kWaitWinSound:
- if (!g_nancy->_sound->isSoundPlaying(_winSound)) {
- g_nancy->_sound->stopSound(_winSound);
+ if (!isSolveSoundPlaying()) {
+ g_nancy->_sound->stopSound(_solveSound);
_subState = kExitToWin;
}
break;
@@ -149,7 +148,7 @@ void DotConnectPuzzle::execute() {
g_nancy->_sound->stopSound(_startHint);
g_nancy->_sound->stopSound(_tooManyLinesSound);
g_nancy->_sound->stopSound(_allCoveredSound);
- g_nancy->_sound->stopSound(_winSound);
+ g_nancy->_sound->stopSound(_solveSound);
if (_subState == kExitToWin) {
_solveScene.execute();
} else {
@@ -281,7 +280,7 @@ void DotConnectPuzzle::checkWin() {
if (allMatch) {
_subState = kWaitWinDelay;
- _winDelayEndTime = g_system->getMillis() + (uint32)_winDelaySec * 1000;
+ _winDelayEndTime = g_system->getMillis() + (uint32)_solveSoundDelay * 1000;
return;
}
diff --git a/engines/nancy/action/puzzle/dotconnectpuzzle.h b/engines/nancy/action/puzzle/dotconnectpuzzle.h
index 4032492c184..969722073af 100644
--- a/engines/nancy/action/puzzle/dotconnectpuzzle.h
+++ b/engines/nancy/action/puzzle/dotconnectpuzzle.h
@@ -76,9 +76,6 @@ protected:
SoundDescription _tooManyLinesSound;
SoundDescription _allCoveredSound;
- uint16 _winDelaySec = 0;
- SoundDescription _winSound;
-
// Runtime state
enum SubState {
diff --git a/engines/nancy/action/puzzle/escapegridpuzzle.cpp b/engines/nancy/action/puzzle/escapegridpuzzle.cpp
index 8d443b634ae..534b731879e 100644
--- a/engines/nancy/action/puzzle/escapegridpuzzle.cpp
+++ b/engines/nancy/action/puzzle/escapegridpuzzle.cpp
@@ -153,7 +153,7 @@ void EscapeGridPuzzle::readData(Common::SeekableReadStream &stream) {
_solveScene._sceneChange.continueSceneSound = kContinueSceneSound;
_solveScene._flag.label = stream.readSint16LE();
_solveScene._flag.flag = stream.readByte();
- _solveSound.readData(stream);
+ _solveSoundBlock.readData(stream);
_failScene.sceneID = stream.readUint16LE();
_failScene.frameID = stream.readUint16LE();
@@ -814,7 +814,7 @@ int EscapeGridPuzzle::checkOutcome() const {
void EscapeGridPuzzle::endPuzzle(int outcome) {
_outcome = outcome;
- _endSound = playSoundBlock(outcome == 0 ? _solveSound : _failSound);
+ _endSound = playSoundBlock(outcome == 0 ? _solveSoundBlock : _failSound);
}
bool EscapeGridPuzzle::tileRefColor(const Common::Point &cell, const Common::Point &pos, byte &r, byte &g, byte &b) const {
diff --git a/engines/nancy/action/puzzle/escapegridpuzzle.h b/engines/nancy/action/puzzle/escapegridpuzzle.h
index 2ec48eeb417..49634ff30f3 100644
--- a/engines/nancy/action/puzzle/escapegridpuzzle.h
+++ b/engines/nancy/action/puzzle/escapegridpuzzle.h
@@ -247,7 +247,7 @@ protected:
Common::Array<Character> _characters;
Common::Array<Actor> _actors;
- RandomSoundBlock _solveSound;
+ RandomSoundBlock _solveSoundBlock;
SceneChangeDescription _failScene; // an opponent got there first
FlagDescription _failFlag;
RandomSoundBlock _failSound;
diff --git a/engines/nancy/action/puzzle/gridmappuzzle.cpp b/engines/nancy/action/puzzle/gridmappuzzle.cpp
index 05e663ffa3d..f2f7ef7080f 100644
--- a/engines/nancy/action/puzzle/gridmappuzzle.cpp
+++ b/engines/nancy/action/puzzle/gridmappuzzle.cpp
@@ -98,7 +98,7 @@ void GridMapPuzzle::readData(Common::SeekableReadStream &stream) {
stream.skip(2);
_solveScene._flag.label = stream.readSint16LE();
_solveScene._flag.flag = stream.readByte();
- _winSound.readNormal(stream);
+ _solveSound.readNormal(stream);
_exitScene._sceneChange.readData(stream);
stream.skip(2);
@@ -210,17 +210,16 @@ void GridMapPuzzle::execute() {
case kPlaying:
break;
case kPlayWinSound:
- if (_winSound.name != "NO SOUND") {
- g_nancy->_sound->loadSound(_winSound);
- g_nancy->_sound->playSound(_winSound);
+ if (hasSolveSound()) {
+ playSolveSound();
_subState = kWaitWinSound;
} else {
_subState = kExitToWin;
}
break;
case kWaitWinSound:
- if (!g_nancy->_sound->isSoundPlaying(_winSound)) {
- g_nancy->_sound->stopSound(_winSound);
+ if (!isSolveSoundPlaying()) {
+ g_nancy->_sound->stopSound(_solveSound);
_subState = kExitToWin;
}
break;
@@ -236,7 +235,7 @@ void GridMapPuzzle::execute() {
g_nancy->_cursor->showCursor(true);
g_nancy->_sound->stopSound(_pickupSound);
g_nancy->_sound->stopSound(_placeSound);
- g_nancy->_sound->stopSound(_winSound);
+ g_nancy->_sound->stopSound(_solveSound);
if (_subState == kExitToWin) {
GridMapPuzzleData *gmd = (GridMapPuzzleData *)NancySceneState.getPuzzleData(GridMapPuzzleData::getTag());
if (gmd)
diff --git a/engines/nancy/action/puzzle/gridmappuzzle.h b/engines/nancy/action/puzzle/gridmappuzzle.h
index c7a87ff825d..d0b7811b8dd 100644
--- a/engines/nancy/action/puzzle/gridmappuzzle.h
+++ b/engines/nancy/action/puzzle/gridmappuzzle.h
@@ -109,7 +109,6 @@ protected:
SoundDescription _pickupSound;
SoundDescription _placeSound;
- SoundDescription _winSound;
// Runtime state
diff --git a/engines/nancy/action/puzzle/hamradiopuzzle.cpp b/engines/nancy/action/puzzle/hamradiopuzzle.cpp
index 2d2eb10c8fc..89ed821c9e6 100644
--- a/engines/nancy/action/puzzle/hamradiopuzzle.cpp
+++ b/engines/nancy/action/puzzle/hamradiopuzzle.cpp
@@ -231,7 +231,7 @@ void HamRadioPuzzle::readData(Common::SeekableReadStream &stream) {
_solveScene.readData(stream);
_solveSoundDelay = stream.readUint16LE();
- _solveSound.readData(stream);
+ _solveCCSound.readData(stream);
readRect(stream, _exitButtonDest);
readRect(stream, _exitButtonSrc);
@@ -355,7 +355,7 @@ void HamRadioPuzzle::execute() {
_solvedCodeword = true;
_curCharString.clear();
- _solveSound.loadAndPlay(); // Sound delay is ignored
+ _solveCCSound.loadAndPlay(); // Sound delay is ignored
}
}
}
diff --git a/engines/nancy/action/puzzle/hamradiopuzzle.h b/engines/nancy/action/puzzle/hamradiopuzzle.h
index ca9a5a95ad1..bbdee9696fa 100644
--- a/engines/nancy/action/puzzle/hamradiopuzzle.h
+++ b/engines/nancy/action/puzzle/hamradiopuzzle.h
@@ -99,8 +99,7 @@ protected:
CCSound _longMorseSound;
Common::Array<CCSound> _badFrequencySounds;
- uint16 _solveSoundDelay = 0; // not used
- CCSound _solveSound;
+ CCSound _solveCCSound;
Common::Rect _exitButtonDest;
Common::Rect _exitButtonSrc;
diff --git a/engines/nancy/action/puzzle/lettergridpuzzle.cpp b/engines/nancy/action/puzzle/lettergridpuzzle.cpp
index c7d4785b4d0..cd970f4a6ae 100644
--- a/engines/nancy/action/puzzle/lettergridpuzzle.cpp
+++ b/engines/nancy/action/puzzle/lettergridpuzzle.cpp
@@ -86,7 +86,7 @@ void LetterGridPuzzle::readData(Common::SeekableReadStream &stream) {
_solveScene._flag.label = stream.readSint16LE();
_solveScene._flag.flag = stream.readByte();
- _solveSound.readData(stream);
+ _solveSoundBlock.readData(stream);
readExitHotspot(stream);
_exitScene._sceneChange.continueSceneSound = kContinueSceneSound;
@@ -275,12 +275,12 @@ void LetterGridPuzzle::execute() {
// The solve sound plays out before the scene changes
if (!_solveSoundStarted) {
- playSoundBlock(_solveSound);
+ playSoundBlock(_solveSoundBlock);
_solveSoundStarted = true;
break;
}
- if (!_solveSound.names.empty() && g_nancy->_sound->isSoundPlaying((uint16)_solveSound.channel)) {
+ if (!_solveSoundBlock.names.empty() && g_nancy->_sound->isSoundPlaying((uint16)_solveSoundBlock.channel)) {
break;
}
diff --git a/engines/nancy/action/puzzle/lettergridpuzzle.h b/engines/nancy/action/puzzle/lettergridpuzzle.h
index fb9476ed2c1..e3d497b44b2 100644
--- a/engines/nancy/action/puzzle/lettergridpuzzle.h
+++ b/engines/nancy/action/puzzle/lettergridpuzzle.h
@@ -93,7 +93,7 @@ protected:
RandomSoundBlock _clickSound;
- RandomSoundBlock _solveSound; // plays out before the scene change
+ RandomSoundBlock _solveSoundBlock; // plays out before the scene change
// -- Runtime state --
Graphics::ManagedSurface _letterImage;
diff --git a/engines/nancy/action/puzzle/leverpuzzle.cpp b/engines/nancy/action/puzzle/leverpuzzle.cpp
index aa660051544..c0b6da98234 100644
--- a/engines/nancy/action/puzzle/leverpuzzle.cpp
+++ b/engines/nancy/action/puzzle/leverpuzzle.cpp
@@ -121,12 +121,11 @@ void LeverPuzzle::execute() {
break;
}
- g_nancy->_sound->loadSound(_solveSound);
- g_nancy->_sound->playSound(_solveSound);
+ playSolveSound();
_solveState = kWaitForSound;
break;
case kWaitForSound:
- if (!g_nancy->_sound->isSoundPlaying(_solveSound)) {
+ if (!isSolveSoundPlaying()) {
g_nancy->_sound->stopSound(_solveSound);
_state = kActionTrigger;
}
diff --git a/engines/nancy/action/puzzle/leverpuzzle.h b/engines/nancy/action/puzzle/leverpuzzle.h
index a13e82a8f91..50d9b3c2611 100644
--- a/engines/nancy/action/puzzle/leverpuzzle.h
+++ b/engines/nancy/action/puzzle/leverpuzzle.h
@@ -45,8 +45,6 @@ public:
Common::Array<byte> _correctSequence;
SoundDescription _moveSound;
SoundDescription _noMoveSound;
- uint16 _solveSoundDelay = 0;
- SoundDescription _solveSound;
Common::Array<byte> _playerSequence;
Common::Array<bool> _leverDirection;
diff --git a/engines/nancy/action/puzzle/magicboxpuzzle.cpp b/engines/nancy/action/puzzle/magicboxpuzzle.cpp
index a43a4fc5498..2bb1129037f 100644
--- a/engines/nancy/action/puzzle/magicboxpuzzle.cpp
+++ b/engines/nancy/action/puzzle/magicboxpuzzle.cpp
@@ -100,7 +100,7 @@ void MagicBoxPuzzle::readData(Common::SeekableReadStream &stream) {
_solveScene._sceneChange.continueSceneSound = kContinueSceneSound;
_solveScene._flag.label = stream.readSint16LE();
_solveScene._flag.flag = stream.readByte();
- _solveSound.readData(stream);
+ _solveSoundBlock.readData(stream);
_failScene.sceneID = stream.readUint16LE();
_failScene.frameID = stream.readUint16LE();
@@ -360,7 +360,7 @@ void MagicBoxPuzzle::handleInput(NancyInput &input) {
if (isSolved()) {
_solved = true;
- _endSound = playSoundBlock(_solveSound);
+ _endSound = playSoundBlock(_solveSoundBlock);
}
}
diff --git a/engines/nancy/action/puzzle/magicboxpuzzle.h b/engines/nancy/action/puzzle/magicboxpuzzle.h
index 0ea27aa3b41..e6dc518ff0d 100644
--- a/engines/nancy/action/puzzle/magicboxpuzzle.h
+++ b/engines/nancy/action/puzzle/magicboxpuzzle.h
@@ -90,7 +90,7 @@ protected:
RandomSoundBlock _sounds[kNumSounds];
- RandomSoundBlock _solveSound;
+ RandomSoundBlock _solveSoundBlock;
SceneChangeDescription _failScene;
FlagDescription _failFlag;
RandomSoundBlock _failSound;
diff --git a/engines/nancy/action/puzzle/magnetmazepuzzle.cpp b/engines/nancy/action/puzzle/magnetmazepuzzle.cpp
index c4deac9779b..cba9863b7ee 100644
--- a/engines/nancy/action/puzzle/magnetmazepuzzle.cpp
+++ b/engines/nancy/action/puzzle/magnetmazepuzzle.cpp
@@ -84,8 +84,8 @@ void MagnetMazePuzzle::readData(Common::SeekableReadStream &stream) {
stream.seek(start + 0x4a0);
_solveScene._flag.label = stream.readSint16LE();
_solveScene._flag.flag = stream.readByte();
- _winDelaySec = stream.readUint16LE();
- _winSound.readNormal(stream);
+ _solveSoundDelay = stream.readUint16LE();
+ _solveSound.readNormal(stream);
stream.seek(start + 0x4d6);
_exitScene._sceneChange.readData(stream);
@@ -157,9 +157,8 @@ void MagnetMazePuzzle::execute() {
break;
case kWaitWinDelay:
if (g_system->getMillis() >= _winDelayEndTime) {
- if (_winSound.name != "NO SOUND") {
- g_nancy->_sound->loadSound(_winSound);
- g_nancy->_sound->playSound(_winSound);
+ if (hasSolveSound()) {
+ playSolveSound();
_subState = kWaitWinSound;
} else {
_subState = kExitToWin;
@@ -167,8 +166,8 @@ void MagnetMazePuzzle::execute() {
}
break;
case kWaitWinSound:
- if (!g_nancy->_sound->isSoundPlaying(_winSound)) {
- g_nancy->_sound->stopSound(_winSound);
+ if (!isSolveSoundPlaying()) {
+ g_nancy->_sound->stopSound(_solveSound);
_subState = kExitToWin;
}
break;
@@ -184,7 +183,7 @@ void MagnetMazePuzzle::execute() {
g_nancy->_sound->stopSound(_placeSound);
g_nancy->_sound->stopSound(_resetSound);
g_nancy->_sound->stopSound(_bumpSound);
- g_nancy->_sound->stopSound(_winSound);
+ g_nancy->_sound->stopSound(_solveSound);
if (_subState == kExitToWin) {
MagnetMazePuzzleData *mmd = (MagnetMazePuzzleData *)NancySceneState.getPuzzleData(MagnetMazePuzzleData::getTag());
if (mmd)
@@ -389,7 +388,7 @@ void MagnetMazePuzzle::checkSolved() {
}
_isSolved = true;
_subState = kWaitWinDelay;
- _winDelayEndTime = g_system->getMillis() + (uint32)_winDelaySec * 1000;
+ _winDelayEndTime = g_system->getMillis() + (uint32)_solveSoundDelay * 1000;
}
void MagnetMazePuzzle::redraw() {
diff --git a/engines/nancy/action/puzzle/magnetmazepuzzle.h b/engines/nancy/action/puzzle/magnetmazepuzzle.h
index b72ddf0d855..284da19e995 100644
--- a/engines/nancy/action/puzzle/magnetmazepuzzle.h
+++ b/engines/nancy/action/puzzle/magnetmazepuzzle.h
@@ -78,9 +78,6 @@ protected:
SoundDescription _resetSound;
SoundDescription _bumpSound;
- uint16 _winDelaySec = 0;
- SoundDescription _winSound;
-
// Runtime state
enum SubState {
diff --git a/engines/nancy/action/puzzle/mazechasepuzzle.cpp b/engines/nancy/action/puzzle/mazechasepuzzle.cpp
index 606aa7ac0e9..268f393a0df 100644
--- a/engines/nancy/action/puzzle/mazechasepuzzle.cpp
+++ b/engines/nancy/action/puzzle/mazechasepuzzle.cpp
@@ -254,8 +254,7 @@ void MazeChasePuzzle::execute() {
break;
}
- g_nancy->_sound->loadSound(_solveSound);
- g_nancy->_sound->playSound(_solveSound);
+ playSolveSound();
_solved = true;
if (g_nancy->getGameType() >= kGameTypeNancy14) {
@@ -276,7 +275,7 @@ void MazeChasePuzzle::execute() {
return;
case kActionTrigger :
if (_solved) {
- if (g_nancy->_sound->isSoundPlaying(_solveSound)) {
+ if (isSolveSoundPlaying()) {
return;
}
diff --git a/engines/nancy/action/puzzle/mazechasepuzzle.h b/engines/nancy/action/puzzle/mazechasepuzzle.h
index 2f47108bb01..bc89b8e449d 100644
--- a/engines/nancy/action/puzzle/mazechasepuzzle.h
+++ b/engines/nancy/action/puzzle/mazechasepuzzle.h
@@ -107,9 +107,6 @@ protected:
SoundDescription _failSound;
SoundDescription _moveSound;
- uint16 _solveSoundDelay = 0;
- SoundDescription _solveSound;
-
Graphics::ManagedSurface _image;
Common::Array<Piece> _pieces;
diff --git a/engines/nancy/action/puzzle/memorypuzzle.cpp b/engines/nancy/action/puzzle/memorypuzzle.cpp
index a3b6f8fc9c5..48a0943ab81 100644
--- a/engines/nancy/action/puzzle/memorypuzzle.cpp
+++ b/engines/nancy/action/puzzle/memorypuzzle.cpp
@@ -88,7 +88,7 @@ void MemoryPuzzle::readData(Common::SeekableReadStream &stream) {
stream.skip(1); // 0x53a: unknown
// 0x53b: win sound
- _winSound.readNormal(stream);
+ _solveSound.readNormal(stream);
}
// Nancy 11 reworked the layout: fewer (12) face rects, a configurable grid/page count,
@@ -149,7 +149,7 @@ void MemoryPuzzle::readDataNancy11(Common::SeekableReadStream &stream) {
stream.skip(16 * 0xb6 - 0x31); // advance to block 17 @ 0xf72
_matchSound.readNormal(stream); // block 17
stream.skip((27 - 17) * 0xb6 - 0x31); // advance to the scenes @ 0x168e
- // Nancy 11 has no win sound; _winSound keeps its default "NO SOUND".
+ // Nancy 11 has no win sound; _solveSound keeps its default "NO SOUND".
// Solve scene (0x168e), then an alternate-outcome scene (0x16a8, unused). The event flags
// store a 16-bit value rather than a simple on/off.
@@ -290,9 +290,8 @@ void MemoryPuzzle::execute() {
break;
case kPlayWinSound:
- if (_winSound.name != "NO SOUND") {
- g_nancy->_sound->loadSound(_winSound);
- g_nancy->_sound->playSound(_winSound);
+ if (hasSolveSound()) {
+ playSolveSound();
_solveSubState = kWaitWinSound;
} else {
_state = kActionTrigger;
@@ -300,8 +299,8 @@ void MemoryPuzzle::execute() {
break;
case kWaitWinSound:
- if (!g_nancy->_sound->isSoundPlaying(_winSound)) {
- g_nancy->_sound->stopSound(_winSound);
+ if (!isSolveSoundPlaying()) {
+ g_nancy->_sound->stopSound(_solveSound);
_state = kActionTrigger;
}
break;
@@ -313,7 +312,7 @@ void MemoryPuzzle::execute() {
g_nancy->_sound->stopSound(_secondFlipSound);
g_nancy->_sound->stopSound(_matchSound);
g_nancy->_sound->stopSound(_noMatchSound);
- g_nancy->_sound->stopSound(_winSound);
+ g_nancy->_sound->stopSound(_solveSound);
_solveScene.execute();
finishExecution();
break;
diff --git a/engines/nancy/action/puzzle/memorypuzzle.h b/engines/nancy/action/puzzle/memorypuzzle.h
index 9fd3c93464b..936a4139624 100644
--- a/engines/nancy/action/puzzle/memorypuzzle.h
+++ b/engines/nancy/action/puzzle/memorypuzzle.h
@@ -82,7 +82,6 @@ protected:
SoundDescription _secondFlipSound;
SoundDescription _matchSound; // played when a matching pair is found
SoundDescription _noMatchSound; // pre-Nancy 11: played when a pair doesn't match
- SoundDescription _winSound;
// Runtime state
diff --git a/engines/nancy/action/puzzle/multibuildpuzzle.cpp b/engines/nancy/action/puzzle/multibuildpuzzle.cpp
index d85ff73834d..6424e8e0cd8 100644
--- a/engines/nancy/action/puzzle/multibuildpuzzle.cpp
+++ b/engines/nancy/action/puzzle/multibuildpuzzle.cpp
@@ -316,7 +316,7 @@ void MultiBuildPuzzle::execute() {
break;
case kWaitSolveSound:
- if (!g_nancy->_sound->isSoundPlaying(_solveSound)) {
+ if (!isSolveSoundPlaying()) {
g_nancy->_sound->stopSound(_solveSound);
_state = kActionTrigger;
}
diff --git a/engines/nancy/action/puzzle/multibuildpuzzle.h b/engines/nancy/action/puzzle/multibuildpuzzle.h
index 0e9cbd0a658..5c23b260992 100644
--- a/engines/nancy/action/puzzle/multibuildpuzzle.h
+++ b/engines/nancy/action/puzzle/multibuildpuzzle.h
@@ -141,7 +141,6 @@ protected:
int16 _exitCursorID1 = -1; // -1: use _puzzleExitCursor
int16 _exitCursorID2 = -1;
- SoundDescription _solveSound;
Common::String _solveTextKey; // Looked up in CONVO chunk first
Common::String _solveText; // Raw fallback used if key missing
diff --git a/engines/nancy/action/puzzle/onebuildpuzzle.cpp b/engines/nancy/action/puzzle/onebuildpuzzle.cpp
index 40579c634bf..68d26591cbe 100644
--- a/engines/nancy/action/puzzle/onebuildpuzzle.cpp
+++ b/engines/nancy/action/puzzle/onebuildpuzzle.cpp
@@ -257,7 +257,7 @@ void OneBuildPuzzle::readDataNancy12(Common::SeekableReadStream &stream) {
SoundDescription *sounds[kNumSoundsNancy13] = { &_pickupSound, &_rotateSound, &_dropSound,
&_goodPlacementSound, &_badPlacementSound,
- &_completionSound, &_closeupSound };
+ &_solveSound, &_closeupSound };
for (uint i = 0; i < numSoundBlocks; ++i) {
SoundDescription &s = *sounds[i];
s.name = blocks[i].names.empty() ? "NO SOUND" : blocks[i].names[0];
@@ -430,7 +430,7 @@ void OneBuildPuzzle::readData(Common::SeekableReadStream &stream) {
_pieceCursorType = stream.readSint16LE();
stream.skip(2);
_solveScene.readData(stream);
- _completionSound.readNormal(stream);
+ _solveSound.readNormal(stream);
// Completion caption. Only an AUTOTEXT key produces a textbox caption; the
// trailing inline string is a sound subtitle (e.g. "High pitched sound" for
@@ -456,7 +456,7 @@ void OneBuildPuzzle::execute() {
g_nancy->_sound->loadSound(_dropSound);
g_nancy->_sound->loadSound(_goodPlacementSound);
g_nancy->_sound->loadSound(_badPlacementSound);
- g_nancy->_sound->loadSound(_completionSound);
+ g_nancy->_sound->loadSound(_solveSound);
if (g_nancy->getGameType() >= kGameTypeNancy13)
g_nancy->_sound->loadSound(_closeupSound);
_state = kRun;
@@ -496,14 +496,13 @@ void OneBuildPuzzle::execute() {
break;
case kWaitCompletion:
// Waiting for completion sound to finish before scene change
- if (!g_nancy->_sound->isSoundPlaying(_completionSound)) {
+ if (!isSolveSoundPlaying()) {
_state = kActionTrigger;
}
break;
case kTriggerCompletion:
// Play completion sound/text, then wait for it to finish
- g_nancy->_sound->loadSound(_completionSound);
- g_nancy->_sound->playSound(_completionSound);
+ playSolveSound();
showSubtitle(_completionText);
_solveState = kWaitCompletion;
break;
diff --git a/engines/nancy/action/puzzle/onebuildpuzzle.h b/engines/nancy/action/puzzle/onebuildpuzzle.h
index 48c4b6ddb77..dd2a28eaa92 100644
--- a/engines/nancy/action/puzzle/onebuildpuzzle.h
+++ b/engines/nancy/action/puzzle/onebuildpuzzle.h
@@ -204,7 +204,6 @@ protected:
Common::String _badAlt2Filename;
Common::Array<Common::String> _badTexts; // 3 entries
- SoundDescription _completionSound;
Common::String _completionText;
SoundDescription _closeupSound;
diff --git a/engines/nancy/action/puzzle/orderingpuzzle.cpp b/engines/nancy/action/puzzle/orderingpuzzle.cpp
index 556cbefb3b9..0e114210945 100644
--- a/engines/nancy/action/puzzle/orderingpuzzle.cpp
+++ b/engines/nancy/action/puzzle/orderingpuzzle.cpp
@@ -444,8 +444,7 @@ void OrderingPuzzle::execute() {
_needsRedraw = true;
if (enteredKeysMatchStage()) {
- g_nancy->_sound->loadSound(_solveSound);
- g_nancy->_sound->playSound(_solveSound);
+ playSolveSound();
_stageBlinkEndTime = g_nancy->getTotalPlayTime() + 400 + _solveSoundDelay * 1000;
_stageBlinkNextToggle = g_nancy->getTotalPlayTime() + 100;
_stageSymbolVisible = !_stageDisplayBlink;
@@ -638,12 +637,11 @@ void OrderingPuzzle::execute() {
break;
}
- g_nancy->_sound->loadSound(_solveSound);
- g_nancy->_sound->playSound(_solveSound);
+ playSolveSound();
_solveState = kWaitForSound;
break;
case kWaitForSound:
- if (!g_nancy->_sound->isSoundPlaying(_solveSound)) {
+ if (!isSolveSoundPlaying()) {
_state = kActionTrigger;
}
@@ -657,7 +655,7 @@ void OrderingPuzzle::execute() {
drawStageDisplay();
}
- if (g_nancy->getTotalPlayTime() < _stageBlinkEndTime || g_nancy->_sound->isSoundPlaying(_solveSound)) {
+ if (g_nancy->getTotalPlayTime() < _stageBlinkEndTime || isSolveSoundPlaying()) {
break;
}
diff --git a/engines/nancy/action/puzzle/orderingpuzzle.h b/engines/nancy/action/puzzle/orderingpuzzle.h
index 90628314939..31c907b2ccd 100644
--- a/engines/nancy/action/puzzle/orderingpuzzle.h
+++ b/engines/nancy/action/puzzle/orderingpuzzle.h
@@ -125,9 +125,6 @@ protected:
SoundDescription _itemSound;
SoundDescription _popUpSound;
- uint16 _solveSoundDelay = 0;
- SoundDescription _solveSound;
-
SolveState _solveState = kNotSolved;
Graphics::ManagedSurface _image;
Common::Array<uint16> _clickedSequence;
diff --git a/engines/nancy/action/puzzle/overridelockpuzzle.cpp b/engines/nancy/action/puzzle/overridelockpuzzle.cpp
index 51879096ebb..f3d3cd57c94 100644
--- a/engines/nancy/action/puzzle/overridelockpuzzle.cpp
+++ b/engines/nancy/action/puzzle/overridelockpuzzle.cpp
@@ -136,8 +136,7 @@ void OverrideLockPuzzle::execute() {
if (_playerOrder.size() == _buttonOrder.size()) {
// Solved the puzzle
- g_nancy->_sound->loadSound(_solveSound);
- g_nancy->_sound->playSound(_solveSound);
+ playSolveSound();
_state = kActionTrigger;
_solveState = kSolved;
}
@@ -150,7 +149,7 @@ void OverrideLockPuzzle::execute() {
_exitScene.execute();
break;
case kSolved:
- if (g_nancy->_sound->isSoundPlaying(_solveSound)) {
+ if (isSolveSoundPlaying()) {
return;
}
diff --git a/engines/nancy/action/puzzle/overridelockpuzzle.h b/engines/nancy/action/puzzle/overridelockpuzzle.h
index db3d8160311..b5b24363855 100644
--- a/engines/nancy/action/puzzle/overridelockpuzzle.h
+++ b/engines/nancy/action/puzzle/overridelockpuzzle.h
@@ -69,8 +69,6 @@ protected:
Time _buttonPopTime;
- SoundDescription _solveSound;
-
Graphics::ManagedSurface _image;
Common::Array<byte> _buttonOrder;
diff --git a/engines/nancy/action/puzzle/paintpuzzle.cpp b/engines/nancy/action/puzzle/paintpuzzle.cpp
index 487f77708db..ddf0434f674 100644
--- a/engines/nancy/action/puzzle/paintpuzzle.cpp
+++ b/engines/nancy/action/puzzle/paintpuzzle.cpp
@@ -92,7 +92,7 @@ void PaintPuzzle::readData(Common::SeekableReadStream &stream) {
_solveScene._flag.label = stream.readSint16LE();
_solveScene._flag.flag = stream.readByte();
- _solveSound.readData(stream); // 0x150
+ _solveSoundBlock.readData(stream); // 0x150
readExitHotspots(stream, _exitHotspots);
}
@@ -473,18 +473,18 @@ void PaintPuzzle::execute() {
// No scene change: set the flag and keep the puzzle on screen, so
// the scene's own records can react to it.
_solveHandled = true;
- playSoundBlock(_solveSound);
+ playSoundBlock(_solveSoundBlock);
NancySceneState.setEventFlag(_solveScene._flag);
} else if (_takenExit >= 0 || (_solved && !_solveHandled)) {
if (_solved) {
- playSoundBlock(_solveSound);
+ playSoundBlock(_solveSoundBlock);
}
_state = kActionTrigger;
}
break;
case kActionTrigger:
// The solve sound gets to finish first
- if (_takenExit < 0 && isSoundBlockPlaying(_solveSound)) {
+ if (_takenExit < 0 && isSoundBlockPlaying(_solveSoundBlock)) {
break;
}
diff --git a/engines/nancy/action/puzzle/paintpuzzle.h b/engines/nancy/action/puzzle/paintpuzzle.h
index c4f991e9a4d..714d526eeb9 100644
--- a/engines/nancy/action/puzzle/paintpuzzle.h
+++ b/engines/nancy/action/puzzle/paintpuzzle.h
@@ -111,7 +111,7 @@ protected:
RandomSoundBlock _sounds[2]; // 0xa4/0xfa
- RandomSoundBlock _solveSound; // 0x150, plays before the solve scene change
+ RandomSoundBlock _solveSoundBlock; // 0x150, plays before the solve scene change
Common::Array<ExitHotspot> _exitHotspots;
diff --git a/engines/nancy/action/puzzle/passwordpuzzle.cpp b/engines/nancy/action/puzzle/passwordpuzzle.cpp
index 4f71ac3910a..cfffdfa3ad1 100644
--- a/engines/nancy/action/puzzle/passwordpuzzle.cpp
+++ b/engines/nancy/action/puzzle/passwordpuzzle.cpp
@@ -137,8 +137,7 @@ void PasswordPuzzle::execute() {
if (solvedCurrentInput) {
if (_passwordFieldIsActive || _passwords.size() == 0) {
- g_nancy->_sound->loadSound(_solveSound);
- g_nancy->_sound->playSound(_solveSound);
+ playSolveSound();
_solveState = kSolved;
} else {
_passwordFieldIsActive = true;
@@ -170,7 +169,7 @@ void PasswordPuzzle::execute() {
break;
case kSolved:
- if (!g_nancy->_sound->isSoundPlaying(_solveSound)) {
+ if (!isSolveSoundPlaying()) {
g_nancy->_sound->stopSound(_solveSound);
_state = kActionTrigger;
}
diff --git a/engines/nancy/action/puzzle/passwordpuzzle.h b/engines/nancy/action/puzzle/passwordpuzzle.h
index 002b1e21a00..43372610623 100644
--- a/engines/nancy/action/puzzle/passwordpuzzle.h
+++ b/engines/nancy/action/puzzle/passwordpuzzle.h
@@ -47,7 +47,6 @@ public:
// _screenPosition 0x24
Common::Array<Common::String> _names;
Common::Array<Common::String> _passwords;
- SoundDescription _solveSound;
SceneChangeWithFlag _failExitScene;
SoundDescription _failSound;
diff --git a/engines/nancy/action/puzzle/quizpuzzle.cpp b/engines/nancy/action/puzzle/quizpuzzle.cpp
index 9a8fa2ef66c..91d8723da24 100644
--- a/engines/nancy/action/puzzle/quizpuzzle.cpp
+++ b/engines/nancy/action/puzzle/quizpuzzle.cpp
@@ -40,7 +40,7 @@ QuizPuzzle::~QuizPuzzle() {
g_nancy->_input->setVKEnabled(false);
g_nancy->_sound->stopSound(_correctSound);
g_nancy->_sound->stopSound(_wrongSound);
- g_nancy->_sound->stopSound(_doneSound);
+ g_nancy->_sound->stopSound(_solveSound);
g_nancy->_sound->stopSound(_activeBoxSound);
}
@@ -105,7 +105,7 @@ void QuizPuzzle::readDataNancy8(Common::SeekableReadStream &stream) {
_wrongText = readSubtitleText(stream);
_solveScene.readData(stream);
- _doneSound.readNormal(stream);
+ _solveSound.readNormal(stream);
_doneText = readSubtitleText(stream);
_exitScene.readData(stream);
@@ -156,7 +156,7 @@ void QuizPuzzle::readDataNancy9(Common::SeekableReadStream &stream) {
_allowedChars = allowedBuf;
_solveScene.readData(stream);
- _doneSound.readNormal(stream);
+ _solveSound.readNormal(stream);
_doneText = readSubtitleText(stream);
_exitScene.readData(stream);
@@ -485,11 +485,10 @@ void QuizPuzzle::executeNancy8() {
break;
case kStartDone: {
- if (_doneSound.name == "NO SOUND") {
+ if (!hasSolveSound()) {
_internalState = kFinish;
} else {
- g_nancy->_sound->loadSound(_doneSound);
- g_nancy->_sound->playSound(_doneSound);
+ playSolveSound();
showSubtitle(_doneText);
_internalState = kWaitDone;
}
@@ -497,8 +496,8 @@ void QuizPuzzle::executeNancy8() {
}
case kWaitDone:
- if (!g_nancy->_sound->isSoundPlaying(_doneSound)) {
- g_nancy->_sound->stopSound(_doneSound);
+ if (!isSolveSoundPlaying()) {
+ g_nancy->_sound->stopSound(_solveSound);
_internalState = kFinish;
}
break;
@@ -692,11 +691,10 @@ void QuizPuzzle::executeNancy9() {
case kStartDone: {
if (isNancy15) {
_internalState = playSoundBlock(_doneSoundBlock) ? kWaitDone : kFinish;
- } else if (_doneSound.name == "NO SOUND") {
+ } else if (!hasSolveSound()) {
_internalState = kFinish;
} else {
- g_nancy->_sound->loadSound(_doneSound);
- g_nancy->_sound->playSound(_doneSound);
+ playSolveSound();
showSubtitle(_doneText);
_internalState = kWaitDone;
}
@@ -704,7 +702,7 @@ void QuizPuzzle::executeNancy9() {
}
case kWaitDone: {
- SoundDescription &sound = isNancy15 ? _activeBoxSound : _doneSound;
+ SoundDescription &sound = isNancy15 ? _activeBoxSound : _solveSound;
if (!g_nancy->_sound->isSoundPlaying(sound)) {
g_nancy->_sound->stopSound(sound);
_internalState = kFinish;
@@ -730,7 +728,7 @@ void QuizPuzzle::execute() {
}
if (g_nancy->getGameType() < kGameTypeNancy15) {
- g_nancy->_sound->loadSound(_doneSound);
+ g_nancy->_sound->loadSound(_solveSound);
}
loadSavedAnswers();
diff --git a/engines/nancy/action/puzzle/quizpuzzle.h b/engines/nancy/action/puzzle/quizpuzzle.h
index 6abe185df66..389bb526d7f 100644
--- a/engines/nancy/action/puzzle/quizpuzzle.h
+++ b/engines/nancy/action/puzzle/quizpuzzle.h
@@ -116,7 +116,6 @@ private:
uint16 _fontID = 0;
uint16 _cursorBlinkInterval = 500;
- SoundDescription _doneSound; // Nancy 8 - Nancy 14 solve sound
Common::String _doneText;
RandomSoundBlock _doneSoundBlock; // Nancy 15 solve sound
diff --git a/engines/nancy/action/puzzle/raycastpuzzle.cpp b/engines/nancy/action/puzzle/raycastpuzzle.cpp
index dd665afc4b1..6da9a00abfd 100644
--- a/engines/nancy/action/puzzle/raycastpuzzle.cpp
+++ b/engines/nancy/action/puzzle/raycastpuzzle.cpp
@@ -1119,7 +1119,7 @@ void RaycastPuzzle::execute() {
break;
case kActionTrigger:
- if (g_nancy->_sound->isSoundPlaying(_solveSound)) {
+ if (isSolveSoundPlaying()) {
return;
}
@@ -2078,8 +2078,7 @@ void RaycastPuzzle::checkExit() {
Common::Point gridPos(((uint)_playerY) >> 7, ((uint)_playerX) >> 7);
if (_infoMap[gridPos.y * _mapFullWidth + gridPos.x] == 1) {
- g_nancy->_sound->loadSound(_solveSound);
- g_nancy->_sound->playSound(_solveSound);
+ playSolveSound();
_state = kActionTrigger;
}
diff --git a/engines/nancy/action/puzzle/raycastpuzzle.h b/engines/nancy/action/puzzle/raycastpuzzle.h
index 56e87276658..ba55ab58b67 100644
--- a/engines/nancy/action/puzzle/raycastpuzzle.h
+++ b/engines/nancy/action/puzzle/raycastpuzzle.h
@@ -76,8 +76,6 @@ protected:
uint16 _unknownSoundChannelID = 0;
SoundDescription _dummySound;
- SoundDescription _solveSound;
-
Common::Array<uint32> _wallMap, _infoMap;
Common::Array<int16> _floorMap, _ceilingMap;
Common::Array<uint16> _wallLightMap, _floorCeilingLightMap, _heightMap;
diff --git a/engines/nancy/action/puzzle/riddlepuzzle.cpp b/engines/nancy/action/puzzle/riddlepuzzle.cpp
index c06ea1743f1..06d569cefa6 100644
--- a/engines/nancy/action/puzzle/riddlepuzzle.cpp
+++ b/engines/nancy/action/puzzle/riddlepuzzle.cpp
@@ -61,7 +61,7 @@ void RiddlePuzzle::readData(Common::SeekableReadStream &stream) {
_eraseSound.readNormal(stream);
_enterSound.readNormal(stream);
_solveScene.readData(stream);
- _successSound.readNormal(stream);
+ _solveSound.readNormal(stream);
_exitScene.readData(stream);
_exitSound.readNormal(stream);
readRect(stream, _exitHotspot);
@@ -175,8 +175,7 @@ void RiddlePuzzle::execute() {
if (_puzzleState->solvedRiddleIDs.size() == _riddles.size()) {
// Solved all riddles
- g_nancy->_sound->loadSound(_successSound);
- g_nancy->_sound->playSound(_successSound);
+ playSolveSound();
_solveState = kSolvedAll;
_state = kActionTrigger;
@@ -242,7 +241,7 @@ void RiddlePuzzle::execute() {
break;
case kSolvedAll:
- sound = &_successSound;
+ sound = &_solveSound;
sceneChange = &_solveScene;
break;
diff --git a/engines/nancy/action/puzzle/riddlepuzzle.h b/engines/nancy/action/puzzle/riddlepuzzle.h
index b69b3ba33a7..fd484b79d13 100644
--- a/engines/nancy/action/puzzle/riddlepuzzle.h
+++ b/engines/nancy/action/puzzle/riddlepuzzle.h
@@ -66,7 +66,6 @@ protected:
SoundDescription _typeSound;
SoundDescription _eraseSound;
SoundDescription _enterSound;
- SoundDescription _successSound;
SoundDescription _exitSound;
Common::Array<Riddle> _riddles;
diff --git a/engines/nancy/action/puzzle/rippedletterpuzzle.cpp b/engines/nancy/action/puzzle/rippedletterpuzzle.cpp
index a6b9ad7775c..653c3bf5679 100644
--- a/engines/nancy/action/puzzle/rippedletterpuzzle.cpp
+++ b/engines/nancy/action/puzzle/rippedletterpuzzle.cpp
@@ -269,12 +269,11 @@ void RippedLetterPuzzle::execute() {
}
}
- g_nancy->_sound->loadSound(_solveSound);
- g_nancy->_sound->playSound(_solveSound);
+ playSolveSound();
_solveState = kWaitForSound;
break;
case kWaitForSound :
- if (!g_nancy->_sound->isSoundPlaying(_solveSound)) {
+ if (!isSolveSoundPlaying()) {
g_nancy->_sound->stopSound(_solveSound);
_state = kActionTrigger;
}
diff --git a/engines/nancy/action/puzzle/rippedletterpuzzle.h b/engines/nancy/action/puzzle/rippedletterpuzzle.h
index 9cd6c9a3e7b..142558ece55 100644
--- a/engines/nancy/action/puzzle/rippedletterpuzzle.h
+++ b/engines/nancy/action/puzzle/rippedletterpuzzle.h
@@ -72,8 +72,6 @@ public:
SoundDescription _dropSound;
SoundDescription _rotateSound;
- SoundDescription _solveSound;
-
int16 _customCursorID = -1;
Misc::MouseFollowObject _pickedUpPiece;
diff --git a/engines/nancy/action/puzzle/rotatinglockpuzzle.cpp b/engines/nancy/action/puzzle/rotatinglockpuzzle.cpp
index 74f708fd1bc..1e582351e84 100644
--- a/engines/nancy/action/puzzle/rotatinglockpuzzle.cpp
+++ b/engines/nancy/action/puzzle/rotatinglockpuzzle.cpp
@@ -208,7 +208,7 @@ void RotatingLockPuzzle::execute() {
_solveState = kWaitForSound;
break;
case kWaitForSound:
- if (!g_nancy->_sound->isSoundPlaying(_solveSound)) {
+ if (!isSolveSoundPlaying()) {
_state = kActionTrigger;
}
diff --git a/engines/nancy/action/puzzle/rotatinglockpuzzle.h b/engines/nancy/action/puzzle/rotatinglockpuzzle.h
index 86420f5f1b8..a16a73f76f0 100644
--- a/engines/nancy/action/puzzle/rotatinglockpuzzle.h
+++ b/engines/nancy/action/puzzle/rotatinglockpuzzle.h
@@ -57,8 +57,6 @@ public:
CursorManager::CursorType _upCursorType = CursorManager::kMoveUp;
CursorManager::CursorType _downCursorType = CursorManager::kMoveDown;
SoundDescription _clickSound;
- uint16 _solveSoundDelay = 0;
- SoundDescription _solveSound;
SolveState _solveState = kNotSolved;
Graphics::ManagedSurface _image;
diff --git a/engines/nancy/action/puzzle/safedialpuzzle.cpp b/engines/nancy/action/puzzle/safedialpuzzle.cpp
index a8d392f26aa..afc8bfba946 100644
--- a/engines/nancy/action/puzzle/safedialpuzzle.cpp
+++ b/engines/nancy/action/puzzle/safedialpuzzle.cpp
@@ -192,13 +192,12 @@ void SafeDialPuzzle::execute() {
case kActionTrigger :
if (_solved) {
if (_nextAnim == 0) {
- if (g_nancy->_sound->isSoundPlaying(_solveSound)) {
+ if (isSolveSoundPlaying()) {
break;
}
} else {
if (_nextAnim < g_nancy->getTotalPlayTime()) {
- g_nancy->_sound->loadSound(_solveSound);
- g_nancy->_sound->playSound(_solveSound);
+ playSolveSound();
_nextAnim = 0;
}
break;
diff --git a/engines/nancy/action/puzzle/safedialpuzzle.h b/engines/nancy/action/puzzle/safedialpuzzle.h
index 46998f65d3b..f5b38053b2b 100644
--- a/engines/nancy/action/puzzle/safedialpuzzle.h
+++ b/engines/nancy/action/puzzle/safedialpuzzle.h
@@ -84,9 +84,6 @@ protected:
SoundDescription _selectSound;
SoundDescription _resetSound;
- uint _solveSoundDelay = 0;
- SoundDescription _solveSound;
-
Graphics::ManagedSurface _image1, _image2, _resetImage;
uint _numInbetweens = 1;
diff --git a/engines/nancy/action/puzzle/scalepuzzle.cpp b/engines/nancy/action/puzzle/scalepuzzle.cpp
index 87966172577..7066ea3a2d1 100644
--- a/engines/nancy/action/puzzle/scalepuzzle.cpp
+++ b/engines/nancy/action/puzzle/scalepuzzle.cpp
@@ -59,7 +59,7 @@ void ScalePuzzle::readData(Common::SeekableReadStream &stream) {
_solveScene._flag.label = stream.readSint16LE(); // 0x27
_solveScene._flag.flag = stream.readByte(); // 0x29
- _solveSound.readData(stream); // played once the puzzle comes out solved
+ _solveSoundBlock.readData(stream); // played once the puzzle comes out solved
// The figures to match this scene: a required coin count, the figure's number, its
// open-latch sprite and destination rects, and the sound played when it lights.
@@ -360,7 +360,7 @@ void ScalePuzzle::execute() {
} else {
// Solved: play the sound, set the solve flag, change scene (9999 = stay). The puzzle
// keeps running afterwards, so the player can still leave through the exit hotspot.
- playSoundBlock(_solveSound);
+ playSoundBlock(_solveSoundBlock);
_solveScene.execute();
_solveTriggered = true;
_state = kRun;
diff --git a/engines/nancy/action/puzzle/scalepuzzle.h b/engines/nancy/action/puzzle/scalepuzzle.h
index 1f8e4da71d4..e8a8a6e4e55 100644
--- a/engines/nancy/action/puzzle/scalepuzzle.h
+++ b/engines/nancy/action/puzzle/scalepuzzle.h
@@ -106,7 +106,7 @@ protected:
Common::Path _imageName; // 0x00
uint16 _hoverCursorType = 0; // 0x21 - raw Nancy13 cursor type over a coin
uint16 _dragCursorType = 0; // 0x23 - raw Nancy13 cursor type while carrying
- RandomSoundBlock _solveSound; // the first sound block; played once solved
+ RandomSoundBlock _solveSoundBlock; // the first sound block; played once solved
Common::Array<Target> _targets; // the figures to match in this scene
Common::Array<Coin> _coins; // the coin definitions
diff --git a/engines/nancy/action/puzzle/setplayerclock.cpp b/engines/nancy/action/puzzle/setplayerclock.cpp
index 8fe8b6db8f3..1533632305f 100644
--- a/engines/nancy/action/puzzle/setplayerclock.cpp
+++ b/engines/nancy/action/puzzle/setplayerclock.cpp
@@ -88,8 +88,8 @@ void SetPlayerClock::readData(Common::SeekableReadStream &stream) {
_buttonSound.readNormal(stream);
_solveScene.readData(stream);
- _alarmSoundDelay = stream.readUint16LE();
- _alarmSetSound.readNormal(stream);
+ _solveSoundDelay = stream.readUint16LE();
+ _solveSound.readNormal(stream);
_exitScene.readData(stream);
}
@@ -160,14 +160,13 @@ void SetPlayerClock::execute() {
// Alarm has been set, wait for timer
if (g_system->getMillis() > _sceneChangeTime) {
_sceneChangeTime = 0;
- g_nancy->_sound->loadSound(_alarmSetSound);
- g_nancy->_sound->playSound(_alarmSetSound);
+ playSolveSound();
}
}
if (_sceneChangeTime == 0) {
- if (!g_nancy->_sound->isSoundPlaying(_alarmSetSound)) {
+ if (!isSolveSoundPlaying()) {
g_nancy->_sound->stopSound(_buttonSound);
- g_nancy->_sound->stopSound(_alarmSetSound);
+ g_nancy->_sound->stopSound(_solveSound);
NancySceneState.setPlayerTime(_alarmHours * 3600000, false);
_solveScene.execute();
finishExecution();
@@ -282,7 +281,7 @@ void SetPlayerClock::handleInput(NancyInput &input) {
_clearButton = true;
_state = kActionTrigger;
_alarmState = kWait;
- _sceneChangeTime = g_system->getMillis() + (_alarmSoundDelay * 1000);
+ _sceneChangeTime = g_system->getMillis() + (_solveSoundDelay * 1000);
return;
}
}
diff --git a/engines/nancy/action/puzzle/setplayerclock.h b/engines/nancy/action/puzzle/setplayerclock.h
index cbb6aaba19a..e5ed412016d 100644
--- a/engines/nancy/action/puzzle/setplayerclock.h
+++ b/engines/nancy/action/puzzle/setplayerclock.h
@@ -74,8 +74,6 @@ protected:
Common::Rect _alarmLightSrc;
SoundDescription _buttonSound;
- uint16 _alarmSoundDelay = 0;
- SoundDescription _alarmSetSound; // NO SOUND in MHM
Graphics::ManagedSurface _image;
diff --git a/engines/nancy/action/puzzle/sliderpuzzle.cpp b/engines/nancy/action/puzzle/sliderpuzzle.cpp
index 486d432e0fc..b9fc0be2b37 100644
--- a/engines/nancy/action/puzzle/sliderpuzzle.cpp
+++ b/engines/nancy/action/puzzle/sliderpuzzle.cpp
@@ -141,12 +141,11 @@ void SliderPuzzle::execute() {
}
}
- g_nancy->_sound->loadSound(_solveSound);
- g_nancy->_sound->playSound(_solveSound);
+ playSolveSound();
_solveState = kWaitForSound;
break;
case kWaitForSound:
- if (!g_nancy->_sound->isSoundPlaying(_solveSound)) {
+ if (!isSolveSoundPlaying()) {
g_nancy->_sound->stopSound(_solveSound);
_state = kActionTrigger;
}
diff --git a/engines/nancy/action/puzzle/sliderpuzzle.h b/engines/nancy/action/puzzle/sliderpuzzle.h
index 5fc620009fd..5de868afb78 100644
--- a/engines/nancy/action/puzzle/sliderpuzzle.h
+++ b/engines/nancy/action/puzzle/sliderpuzzle.h
@@ -53,7 +53,6 @@ public:
Common::Array<Common::Array<int16>> _startTileOrder;
Common::Array<Common::Array<int16>> _correctTileOrder;
SoundDescription _clickSound;
- SoundDescription _solveSound;
bool _retainState = true;
diff --git a/engines/nancy/action/puzzle/sortpuzzle.cpp b/engines/nancy/action/puzzle/sortpuzzle.cpp
index 0fff06757b3..62b3cbe3702 100644
--- a/engines/nancy/action/puzzle/sortpuzzle.cpp
+++ b/engines/nancy/action/puzzle/sortpuzzle.cpp
@@ -107,7 +107,7 @@ void SortPuzzle::readData(Common::SeekableReadStream &stream) {
stream.skip(2);
_solveScene._flag.label = stream.readSint16LE();
_solveScene._flag.flag = stream.readByte();
- _winSound.readNormal(stream);
+ _solveSound.readNormal(stream);
_exitScene._sceneChange.readData(stream);
stream.skip(2);
@@ -168,7 +168,7 @@ void SortPuzzle::readDataNancy12(Common::SeekableReadStream &stream) {
stream.skip(2);
_solveScene._flag.label = stream.readSint16LE();
_solveScene._flag.flag = stream.readByte();
- _winSound.readNormal(stream); // 0x8bd
+ _solveSound.readNormal(stream); // 0x8bd
_exitScene._sceneChange.readData(stream); // 0x8ee
stream.skip(2);
@@ -331,17 +331,16 @@ void SortPuzzle::execute() {
case kPlaying:
break;
case kPlayWinSound:
- if (_winSound.name != "NO SOUND") {
- g_nancy->_sound->loadSound(_winSound);
- g_nancy->_sound->playSound(_winSound);
+ if (hasSolveSound()) {
+ playSolveSound();
_subState = kWaitWinSound;
} else {
_subState = kExitToWin;
}
break;
case kWaitWinSound:
- if (!g_nancy->_sound->isSoundPlaying(_winSound)) {
- g_nancy->_sound->stopSound(_winSound);
+ if (!isSolveSoundPlaying()) {
+ g_nancy->_sound->stopSound(_solveSound);
_subState = kExitToWin;
}
break;
@@ -355,7 +354,7 @@ void SortPuzzle::execute() {
case kActionTrigger:
g_nancy->_sound->stopSound(_pickupSound);
g_nancy->_sound->stopSound(_dropSound);
- g_nancy->_sound->stopSound(_winSound);
+ g_nancy->_sound->stopSound(_solveSound);
if (_subState == kExitToWin) {
SortPuzzleData *spd = (SortPuzzleData *)NancySceneState.getPuzzleData(SortPuzzleData::getTag());
if (spd) {
diff --git a/engines/nancy/action/puzzle/sortpuzzle.h b/engines/nancy/action/puzzle/sortpuzzle.h
index 6d67b620760..0b79ea0e765 100644
--- a/engines/nancy/action/puzzle/sortpuzzle.h
+++ b/engines/nancy/action/puzzle/sortpuzzle.h
@@ -114,8 +114,6 @@ protected:
SoundDescription _pickupSound;
SoundDescription _dropSound;
- SoundDescription _winSound;
-
// Runtime state
enum SubState {
diff --git a/engines/nancy/action/puzzle/soundmatchpuzzle.cpp b/engines/nancy/action/puzzle/soundmatchpuzzle.cpp
index 91e5fbcd271..f7eab474923 100644
--- a/engines/nancy/action/puzzle/soundmatchpuzzle.cpp
+++ b/engines/nancy/action/puzzle/soundmatchpuzzle.cpp
@@ -42,7 +42,7 @@ void SoundMatchPuzzle::readData(Common::SeekableReadStream &stream) {
_resetOnWrong = stream.readByte() != 0;
_solveScene.readData(stream); // 0x084
- _winSound.readNormal(stream); // 0x09d
+ _solveSound.readNormal(stream); // 0x09d
_exitScene.readData(stream); // 0x0ce
readRect(stream, _exitHotspot); // 0x0e7
@@ -139,10 +139,7 @@ void SoundMatchPuzzle::execute() {
if (_feedbackSoundRight.name == "NO SOUND" ||
!g_nancy->_sound->isSoundPlaying(_feedbackSoundRight)) {
if (_matchedPairs >= _requiredPairs) {
- if (_winSound.name != "NO SOUND") {
- g_nancy->_sound->loadSound(_winSound);
- g_nancy->_sound->playSound(_winSound);
- }
+ playSolveSound();
_solveSubState = kWinSound;
} else {
_selectedSoundButton = -1;
@@ -160,9 +157,8 @@ void SoundMatchPuzzle::execute() {
break;
case kWinSound:
- if (_winSound.name == "NO SOUND" ||
- !g_nancy->_sound->isSoundPlaying(_winSound)) {
- g_nancy->_sound->stopSound(_winSound);
+ if (!isSolveSoundPlaying()) {
+ g_nancy->_sound->stopSound(_solveSound);
_state = kActionTrigger;
}
break;
@@ -174,7 +170,7 @@ void SoundMatchPuzzle::execute() {
g_nancy->_sound->stopSound(_feedbackSoundRight);
if (_selectedSoundButton >= 0)
g_nancy->_sound->stopSound(_soundButtons[_selectedSoundButton].sound);
- g_nancy->_sound->stopSound(_winSound);
+ g_nancy->_sound->stopSound(_solveSound);
if (_isExiting)
_exitScene.execute();
else
diff --git a/engines/nancy/action/puzzle/soundmatchpuzzle.h b/engines/nancy/action/puzzle/soundmatchpuzzle.h
index a21fb50815e..28dcef1c9fc 100644
--- a/engines/nancy/action/puzzle/soundmatchpuzzle.h
+++ b/engines/nancy/action/puzzle/soundmatchpuzzle.h
@@ -56,7 +56,6 @@ protected:
SoundDescription _feedbackSoundWrong; // played on incorrect whale click
SoundDescription _feedbackSoundRight; // played on correct whale click
- SoundDescription _winSound; // played when all pairs are matched
uint16 _requiredPairs = kNumButtons; // how many matches needed to win
diff --git a/engines/nancy/action/puzzle/spigotpuzzle.cpp b/engines/nancy/action/puzzle/spigotpuzzle.cpp
index 37cac5e37d4..d6263281c2a 100644
--- a/engines/nancy/action/puzzle/spigotpuzzle.cpp
+++ b/engines/nancy/action/puzzle/spigotpuzzle.cpp
@@ -225,8 +225,7 @@ void SpigotPuzzle::execute() {
// fall through
case kRun:
if (_currentOrder == _correctOrder) {
- g_nancy->_sound->loadSound(_solveSound);
- g_nancy->_sound->playSound(_solveSound);
+ playSolveSound();
_solved = true;
_state = kActionTrigger;
}
@@ -235,7 +234,7 @@ void SpigotPuzzle::execute() {
case kActionTrigger:
if (_solved) {
// Sound delay not used
- if (g_nancy->_sound->isSoundPlaying(_solveSound)) {
+ if (isSolveSoundPlaying()) {
return;
}
diff --git a/engines/nancy/action/puzzle/spigotpuzzle.h b/engines/nancy/action/puzzle/spigotpuzzle.h
index 17a7e7b1a68..fcc71c7471b 100644
--- a/engines/nancy/action/puzzle/spigotpuzzle.h
+++ b/engines/nancy/action/puzzle/spigotpuzzle.h
@@ -72,9 +72,6 @@ protected:
SoundDescription _letterSound;
SoundDescription _spigotSound;
- uint16 _solveSoundDelay = 0;
- SoundDescription _solveSound;
-
Graphics::ManagedSurface _image;
Common::Array<uint16> _currentOrder;
diff --git a/engines/nancy/action/puzzle/stepobjectspuzzle.cpp b/engines/nancy/action/puzzle/stepobjectspuzzle.cpp
index 70998275a8f..97c3352955d 100644
--- a/engines/nancy/action/puzzle/stepobjectspuzzle.cpp
+++ b/engines/nancy/action/puzzle/stepobjectspuzzle.cpp
@@ -377,7 +377,7 @@ void StepObjectsPuzzle::execute() {
break;
case kSolved:
- if (_solveSound.name.empty() || !g_nancy->_sound->isSoundPlaying(_solveSound)) {
+ if (!isSolveSoundPlaying()) {
_state = kActionTrigger;
}
diff --git a/engines/nancy/action/puzzle/stepobjectspuzzle.h b/engines/nancy/action/puzzle/stepobjectspuzzle.h
index 7d7755209d6..cb2ae9cab40 100644
--- a/engines/nancy/action/puzzle/stepobjectspuzzle.h
+++ b/engines/nancy/action/puzzle/stepobjectspuzzle.h
@@ -131,7 +131,6 @@ protected:
bool _lastStepCorrect = false;
bool _solved = false;
bool _exitRequested = false;
- SoundDescription _solveSound;
Graphics::ManagedSurface _image;
};
diff --git a/engines/nancy/action/puzzle/tangrampuzzle.cpp b/engines/nancy/action/puzzle/tangrampuzzle.cpp
index c31d0c529c0..bfe1669f550 100644
--- a/engines/nancy/action/puzzle/tangrampuzzle.cpp
+++ b/engines/nancy/action/puzzle/tangrampuzzle.cpp
@@ -168,8 +168,7 @@ void TangramPuzzle::execute() {
}
}
- g_nancy->_sound->loadSound(_solveSound);
- g_nancy->_sound->playSound(_solveSound);
+ playSolveSound();
_solved = true;
_state = kActionTrigger;
}
@@ -177,7 +176,7 @@ void TangramPuzzle::execute() {
break;
case kActionTrigger :
if (_solved) {
- if (g_nancy->_sound->isSoundPlaying(_solveSound)) {
+ if (isSolveSoundPlaying()) {
break;
}
diff --git a/engines/nancy/action/puzzle/tangrampuzzle.h b/engines/nancy/action/puzzle/tangrampuzzle.h
index e75db89b4d6..92cb4560194 100644
--- a/engines/nancy/action/puzzle/tangrampuzzle.h
+++ b/engines/nancy/action/puzzle/tangrampuzzle.h
@@ -91,8 +91,6 @@ protected:
SoundDescription _putDownSound;
SoundDescription _rotateSound;
- SoundDescription _solveSound;
-
Graphics::ManagedSurface _tileImage;
Graphics::ManagedSurface _maskImage;
byte *_zBuffer = nullptr;
diff --git a/engines/nancy/action/puzzle/towerpuzzle.cpp b/engines/nancy/action/puzzle/towerpuzzle.cpp
index 42af8f58699..66146c59b0a 100644
--- a/engines/nancy/action/puzzle/towerpuzzle.cpp
+++ b/engines/nancy/action/puzzle/towerpuzzle.cpp
@@ -139,12 +139,11 @@ void TowerPuzzle::execute() {
}
}
- g_nancy->_sound->loadSound(_solveSound);
- g_nancy->_sound->playSound(_solveSound);
+ playSolveSound();
_solveState = kWaitForSound;
break;
case kWaitForSound :
- if (!g_nancy->_sound->isSoundPlaying(_solveSound)) {
+ if (!isSolveSoundPlaying()) {
g_nancy->_sound->stopSound(_solveSound);
_state = kActionTrigger;
}
diff --git a/engines/nancy/action/puzzle/towerpuzzle.h b/engines/nancy/action/puzzle/towerpuzzle.h
index 058ce320058..fb588b464d2 100644
--- a/engines/nancy/action/puzzle/towerpuzzle.h
+++ b/engines/nancy/action/puzzle/towerpuzzle.h
@@ -62,8 +62,6 @@ protected:
SoundDescription _takeSound;
SoundDescription _dropSound;
- SoundDescription _solveSound;
-
Graphics::ManagedSurface _image;
Misc::MouseFollowObject _heldRing;
int8 _heldRingID = -1;
diff --git a/engines/nancy/action/puzzle/turningpuzzle.cpp b/engines/nancy/action/puzzle/turningpuzzle.cpp
index 0c4ae89b0e1..80c8cab59f5 100644
--- a/engines/nancy/action/puzzle/turningpuzzle.cpp
+++ b/engines/nancy/action/puzzle/turningpuzzle.cpp
@@ -496,15 +496,14 @@ void TurningPuzzle::execute() {
if (_solveSoundDelayTime == 0) {
_solveSoundDelayTime = g_nancy->getTotalPlayTime() + (_solveSoundDelay * 1000);
} else if (g_nancy->getTotalPlayTime() > _solveSoundDelayTime) {
- g_nancy->_sound->loadSound(_solveSound);
- g_nancy->_sound->playSound(_solveSound);
+ playSolveSound();
_shouldSetSolveFlag = true;
_solveState = kWaitForSound;
}
return;
case kWaitForSound :
- if (g_nancy->_sound->isSoundPlaying(_solveSound)) {
+ if (isSolveSoundPlaying()) {
return;
}
diff --git a/engines/nancy/action/puzzle/turningpuzzle.h b/engines/nancy/action/puzzle/turningpuzzle.h
index 36466b6e870..f44741cbf18 100644
--- a/engines/nancy/action/puzzle/turningpuzzle.h
+++ b/engines/nancy/action/puzzle/turningpuzzle.h
@@ -105,9 +105,6 @@ protected:
Common::Array<uint16> _correctOrder;
- uint16 _solveSoundDelay = 0;
- SoundDescription _solveSound;
-
// -- Nancy13 only --
Common::Array<PieceType> _pieceTypes;
Common::Array<uint16> _pieceTypeIDs; // per object
diff --git a/engines/nancy/action/puzzle/twodialpuzzle.cpp b/engines/nancy/action/puzzle/twodialpuzzle.cpp
index 1c23c4a75f5..3f5157d0a10 100644
--- a/engines/nancy/action/puzzle/twodialpuzzle.cpp
+++ b/engines/nancy/action/puzzle/twodialpuzzle.cpp
@@ -152,12 +152,11 @@ void TwoDialPuzzle::execute() {
}
_solveSoundDelayTime = 0;
- g_nancy->_sound->loadSound(_solveSound);
- g_nancy->_sound->playSound(_solveSound);
+ playSolveSound();
NancySceneState.setEventFlag(_solveScene._flag);
return;
} else {
- if (g_nancy->_sound->isSoundPlaying(_solveSound)) {
+ if (isSolveSoundPlaying()) {
return;
}
@@ -225,13 +224,12 @@ void TwoDialPuzzle::runNancy12() {
break;
}
case kPlaySolveSound:
- g_nancy->_sound->loadSound(_solveSound);
- g_nancy->_sound->playSound(_solveSound);
+ playSolveSound();
_solveState = kWaitForSounds;
break;
case kWaitForSounds:
if (_isSolved) {
- if (!g_nancy->_sound->isSoundPlaying(_solveSound)) {
+ if (!isSolveSoundPlaying()) {
g_nancy->_sound->stopSound(_solveSound);
_state = kActionTrigger;
}
diff --git a/engines/nancy/action/puzzle/twodialpuzzle.h b/engines/nancy/action/puzzle/twodialpuzzle.h
index 4a601bfad2b..028719572a1 100644
--- a/engines/nancy/action/puzzle/twodialpuzzle.h
+++ b/engines/nancy/action/puzzle/twodialpuzzle.h
@@ -81,9 +81,6 @@ protected:
SoundDescription _rotateSounds[2];
- uint16 _solveSoundDelay = 0;
- SoundDescription _solveSound;
-
Graphics::ManagedSurface _image;
int16 _currentPositions[2] = { 0, 0 };
diff --git a/engines/nancy/action/puzzle/typingquizpuzzle.cpp b/engines/nancy/action/puzzle/typingquizpuzzle.cpp
index bc5d4f9a486..45dc755a329 100644
--- a/engines/nancy/action/puzzle/typingquizpuzzle.cpp
+++ b/engines/nancy/action/puzzle/typingquizpuzzle.cpp
@@ -100,7 +100,7 @@ void TypingQuizPuzzle::readData(Common::SeekableReadStream &stream) {
_solveScene._flag.label = stream.readSint16LE(); // 0x50f
_solveScene._flag.flag = g_nancy->_true;
- _winSound.readNormal(stream); // 0x511
+ _solveSound.readNormal(stream); // 0x511
_defaultScene.readData(stream); // 0x542 (20 bytes)
_defaultScene.continueSceneSound = stream.readUint16LE(); // 0x556
@@ -412,10 +412,7 @@ void TypingQuizPuzzle::execute() {
case kEvaluate:
if (_score >= (int)_effectiveTarget) {
_reachedTarget = true;
- if (_winSound.name != "NO SOUND") {
- g_nancy->_sound->loadSound(_winSound);
- g_nancy->_sound->playSound(_winSound);
- }
+ playSolveSound();
} else {
_reachedTarget = false;
_reachedThreshold = _score >= (int)_scoreThreshold;
@@ -440,7 +437,7 @@ void TypingQuizPuzzle::execute() {
g_nancy->_sound->stopSound(_popSound);
g_nancy->_sound->stopSound(_wrongSound);
g_nancy->_sound->stopSound(_escapeSound);
- g_nancy->_sound->stopSound(_winSound);
+ g_nancy->_sound->stopSound(_solveSound);
triggerSceneChange();
finishExecution();
diff --git a/engines/nancy/action/puzzle/typingquizpuzzle.h b/engines/nancy/action/puzzle/typingquizpuzzle.h
index fd53091bdd1..8b72df9ab38 100644
--- a/engines/nancy/action/puzzle/typingquizpuzzle.h
+++ b/engines/nancy/action/puzzle/typingquizpuzzle.h
@@ -123,8 +123,6 @@ private:
SoundDescription _wrongSound; // 0x497 wrong key
SoundDescription _escapeSound; // 0x4c8 balloon floated away
- SoundDescription _winSound; // 0x511 played when the target is met
-
SceneChangeDescription _defaultScene; // 0x542 (did not reach the target)
int16 _flagThreshold = -1; // 0x558 set if the partial threshold was reached
int16 _flagFail = -1; // 0x55a set otherwise
diff --git a/engines/nancy/action/puzzle/whalesurvivorpuzzle.cpp b/engines/nancy/action/puzzle/whalesurvivorpuzzle.cpp
index 4ba77af415f..c25adcac323 100644
--- a/engines/nancy/action/puzzle/whalesurvivorpuzzle.cpp
+++ b/engines/nancy/action/puzzle/whalesurvivorpuzzle.cpp
@@ -182,7 +182,7 @@ void WhaleSurvivorPuzzle::readData(Common::SeekableReadStream &stream) {
// Scenes and remaining sounds
_solveScene.readData(stream); // 0xa1b (25 bytes)
stream.skip(1); // 0xa34 padding byte
- _winSound.readNormal(stream); // 0xa35
+ _solveSound.readNormal(stream); // 0xa35
_lossScene.readData(stream); // 0xa66 (25 bytes)
stream.skip(1); // 0xa7f padding byte
_gameOverSound.readNormal(stream); // 0xa80
@@ -411,10 +411,7 @@ void WhaleSurvivorPuzzle::execute() {
case kRoundWon:
// Play win sound once, then start the countdown
- if (_winSound.name != "NO SOUND") {
- g_nancy->_sound->loadSound(_winSound);
- g_nancy->_sound->playSound(_winSound);
- }
+ playSolveSound();
_countdownEndMs = nowMs + _tryAgainDelayMs;
_executeWin = true;
_gameState = kCountdown;
@@ -459,7 +456,7 @@ void WhaleSurvivorPuzzle::execute() {
g_nancy->_sound->stopSound(_eatSound);
g_nancy->_sound->stopSound(_hurtSound);
g_nancy->_sound->stopSound(_breatheSound);
- g_nancy->_sound->stopSound(_winSound);
+ g_nancy->_sound->stopSound(_solveSound);
g_nancy->_sound->stopSound(_tryAgainSound);
g_nancy->_sound->stopSound(_gameOverSound);
diff --git a/engines/nancy/action/puzzle/whalesurvivorpuzzle.h b/engines/nancy/action/puzzle/whalesurvivorpuzzle.h
index 1ad962a35af..352145f4bd4 100644
--- a/engines/nancy/action/puzzle/whalesurvivorpuzzle.h
+++ b/engines/nancy/action/puzzle/whalesurvivorpuzzle.h
@@ -156,7 +156,6 @@ private:
SoundDescription _sound5; // 0x9ea - unused (silence)
SceneChangeWithFlag _lossScene; // 0xa1b
- SoundDescription _winSound; // 0xa35
SoundDescription _gameOverSound; // 0xa80
SoundDescription _tryAgainSound; // 0xab1
diff --git a/engines/nancy/action/puzzlerecord.cpp b/engines/nancy/action/puzzlerecord.cpp
index 03afbb03662..6688c3652fd 100644
--- a/engines/nancy/action/puzzlerecord.cpp
+++ b/engines/nancy/action/puzzlerecord.cpp
@@ -22,6 +22,7 @@
#include "engines/nancy/nancy.h"
#include "engines/nancy/cursor.h"
#include "engines/nancy/input.h"
+#include "engines/nancy/sound.h"
#include "engines/nancy/util.h"
#include "engines/nancy/state/scene.h"
@@ -85,5 +86,22 @@ bool PuzzleRecord::hoverExitHotspot(const NancyInput &input) const {
return true;
}
+bool PuzzleRecord::hasSolveSound() const {
+ return !_solveSound.name.empty() && _solveSound.name != "NO SOUND";
+}
+
+void PuzzleRecord::playSolveSound() {
+ if (!hasSolveSound()) {
+ return;
+ }
+
+ g_nancy->_sound->loadSound(_solveSound);
+ g_nancy->_sound->playSound(_solveSound);
+}
+
+bool PuzzleRecord::isSolveSoundPlaying() const {
+ return hasSolveSound() && g_nancy->_sound->isSoundPlaying(_solveSound);
+}
+
} // End of namespace Action
} // End of namespace Nancy
diff --git a/engines/nancy/action/puzzlerecord.h b/engines/nancy/action/puzzlerecord.h
index db9eabb01d8..34795d624e7 100644
--- a/engines/nancy/action/puzzlerecord.h
+++ b/engines/nancy/action/puzzlerecord.h
@@ -48,8 +48,16 @@ protected:
// Shows the exit cursor and returns true while the mouse is over the give-up hotspot
bool hoverExitHotspot(const NancyInput &input) const;
+ // A solve sound named "NO SOUND" or left empty counts as absent: it never plays,
+ // and is never reported as playing.
+ bool hasSolveSound() const;
+ void playSolveSound();
+ bool isSolveSoundPlaying() const;
+
// Scene the puzzle moves to when solved; its flag is set on solve
SceneChangeWithFlag _solveScene;
+ SoundDescription _solveSound;
+ uint16 _solveSoundDelay = 0; // units differ per puzzle
// Scene the puzzle moves to when left unsolved, e.g. via the give-up hotspot
SceneChangeWithFlag _exitScene;
Commit: f34b5c1a4e3d0053a8d604d399410a65bfa610d5
https://github.com/scummvm/scummvm/commit/f34b5c1a4e3d0053a8d604d399410a65bfa610d5
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2026-09-26T04:54:31+03:00
Commit Message:
NANCY: Place held items in the inventory in puzzles that perform this
This has only been applied to puzzles that do this in the original
engine
Changed paths:
engines/nancy/action/puzzle/angletosspuzzle.cpp
engines/nancy/action/puzzle/arcadepuzzle.cpp
engines/nancy/action/puzzle/assemblypuzzle.cpp
engines/nancy/action/puzzle/bballpuzzle.cpp
engines/nancy/action/puzzle/bulpuzzle.cpp
engines/nancy/action/puzzle/cardgamepuzzle.cpp
engines/nancy/action/puzzle/cubepuzzle.cpp
engines/nancy/action/puzzle/cuttingpuzzle.cpp
engines/nancy/action/puzzle/dotconnectpuzzle.cpp
engines/nancy/action/puzzle/hamradiopuzzle.cpp
engines/nancy/action/puzzle/matchpuzzle.cpp
engines/nancy/action/puzzle/mazechasepuzzle.cpp
engines/nancy/action/puzzle/memorypuzzle.cpp
engines/nancy/action/puzzle/mindpuzzle.cpp
engines/nancy/action/puzzle/quizpuzzle.cpp
engines/nancy/action/puzzle/sortpuzzle.cpp
engines/nancy/action/puzzle/typingquizpuzzle.cpp
engines/nancy/action/puzzle/whalesurvivorpuzzle.cpp
diff --git a/engines/nancy/action/puzzle/angletosspuzzle.cpp b/engines/nancy/action/puzzle/angletosspuzzle.cpp
index 8169c9e9173..3193b54976a 100644
--- a/engines/nancy/action/puzzle/angletosspuzzle.cpp
+++ b/engines/nancy/action/puzzle/angletosspuzzle.cpp
@@ -108,6 +108,7 @@ void AngleTossPuzzle::execute() {
init();
registerGraphics();
+ NancySceneState.setNoHeldItem();
g_nancy->_sound->loadSound(_powerSound);
g_nancy->_sound->loadSound(_squeakSound);
diff --git a/engines/nancy/action/puzzle/arcadepuzzle.cpp b/engines/nancy/action/puzzle/arcadepuzzle.cpp
index ebd0fd18c6d..f810f5af6e7 100644
--- a/engines/nancy/action/puzzle/arcadepuzzle.cpp
+++ b/engines/nancy/action/puzzle/arcadepuzzle.cpp
@@ -481,6 +481,7 @@ void ArcadePuzzle::execute() {
case kBegin:
init();
registerGraphics();
+ NancySceneState.setNoHeldItem();
// Load sounds
for (int i = 0; i < 6; ++i)
diff --git a/engines/nancy/action/puzzle/assemblypuzzle.cpp b/engines/nancy/action/puzzle/assemblypuzzle.cpp
index 8d93bd5482d..e5bcc4a60aa 100644
--- a/engines/nancy/action/puzzle/assemblypuzzle.cpp
+++ b/engines/nancy/action/puzzle/assemblypuzzle.cpp
@@ -123,6 +123,7 @@ void AssemblyPuzzle::execute() {
init();
registerGraphics();
+ NancySceneState.setNoHeldItem();
g_nancy->_sound->loadSound(_rotateSound);
g_nancy->_sound->loadSound(_pickUpSound);
diff --git a/engines/nancy/action/puzzle/bballpuzzle.cpp b/engines/nancy/action/puzzle/bballpuzzle.cpp
index 799ab572446..9f515535e55 100644
--- a/engines/nancy/action/puzzle/bballpuzzle.cpp
+++ b/engines/nancy/action/puzzle/bballpuzzle.cpp
@@ -149,6 +149,7 @@ void BBallPuzzle::execute() {
case kBegin:
init();
registerGraphics();
+ NancySceneState.setNoHeldItem();
g_nancy->_sound->loadSound(_plusSound);
g_nancy->_sound->loadSound(_minusSound);
diff --git a/engines/nancy/action/puzzle/bulpuzzle.cpp b/engines/nancy/action/puzzle/bulpuzzle.cpp
index 3e16e458c90..a363063adb5 100644
--- a/engines/nancy/action/puzzle/bulpuzzle.cpp
+++ b/engines/nancy/action/puzzle/bulpuzzle.cpp
@@ -366,6 +366,7 @@ void BulPuzzle::execute() {
case kBegin:
init();
registerGraphics();
+ NancySceneState.setNoHeldItem();
g_nancy->_sound->loadSound(_rollSound);
g_nancy->_sound->loadSound(_resetSound);
diff --git a/engines/nancy/action/puzzle/cardgamepuzzle.cpp b/engines/nancy/action/puzzle/cardgamepuzzle.cpp
index 77d4e7d0fd3..82735807937 100644
--- a/engines/nancy/action/puzzle/cardgamepuzzle.cpp
+++ b/engines/nancy/action/puzzle/cardgamepuzzle.cpp
@@ -548,6 +548,7 @@ void CardGamePuzzle::execute() {
if (_state == kBegin) {
init();
registerGraphics();
+ NancySceneState.setNoHeldItem();
// Kick off the first turn. When the AI is dealt the opening move, it asks first.
if (_startPlayer == 0) {
diff --git a/engines/nancy/action/puzzle/cubepuzzle.cpp b/engines/nancy/action/puzzle/cubepuzzle.cpp
index 3f7c8fc622d..de176459ded 100644
--- a/engines/nancy/action/puzzle/cubepuzzle.cpp
+++ b/engines/nancy/action/puzzle/cubepuzzle.cpp
@@ -102,6 +102,7 @@ void CubePuzzle::execute() {
case kBegin:
init();
registerGraphics();
+ NancySceneState.setNoHeldItem();
g_nancy->_sound->loadSound(_rotateSound);
g_nancy->_sound->loadSound(_pickUpSound);
diff --git a/engines/nancy/action/puzzle/cuttingpuzzle.cpp b/engines/nancy/action/puzzle/cuttingpuzzle.cpp
index f526ba86b5c..995722297fb 100644
--- a/engines/nancy/action/puzzle/cuttingpuzzle.cpp
+++ b/engines/nancy/action/puzzle/cuttingpuzzle.cpp
@@ -183,6 +183,11 @@ void CuttingPuzzle::execute() {
init();
registerGraphics();
+ // The item the puzzle requires stays in hand
+ if (!_itemCheckByte || NancySceneState.getHeldItem() != _itemID) {
+ NancySceneState.setNoHeldItem();
+ }
+
g_nancy->_sound->loadSound(_latheSound);
g_nancy->_sound->loadSound(_moveSound);
g_nancy->_sound->loadSound(_startStopSound);
diff --git a/engines/nancy/action/puzzle/dotconnectpuzzle.cpp b/engines/nancy/action/puzzle/dotconnectpuzzle.cpp
index 0e73ba5327b..d6ec02436f0 100644
--- a/engines/nancy/action/puzzle/dotconnectpuzzle.cpp
+++ b/engines/nancy/action/puzzle/dotconnectpuzzle.cpp
@@ -109,6 +109,7 @@ void DotConnectPuzzle::execute() {
case kBegin:
init();
registerGraphics();
+ NancySceneState.setNoHeldItem();
_state = kRun;
// fall through
diff --git a/engines/nancy/action/puzzle/hamradiopuzzle.cpp b/engines/nancy/action/puzzle/hamradiopuzzle.cpp
index 89ed821c9e6..446c25a61a7 100644
--- a/engines/nancy/action/puzzle/hamradiopuzzle.cpp
+++ b/engines/nancy/action/puzzle/hamradiopuzzle.cpp
@@ -256,6 +256,7 @@ void HamRadioPuzzle::execute() {
case kBegin :
init();
registerGraphics();
+ NancySceneState.setNoHeldItem();
g_nancy->_sound->loadSound(_digitRollSound);
setFrequency(_startFreq.frequency);
diff --git a/engines/nancy/action/puzzle/matchpuzzle.cpp b/engines/nancy/action/puzzle/matchpuzzle.cpp
index c0921448c2a..dc74a3dcc9c 100644
--- a/engines/nancy/action/puzzle/matchpuzzle.cpp
+++ b/engines/nancy/action/puzzle/matchpuzzle.cpp
@@ -363,6 +363,7 @@ void MatchPuzzle::execute() {
case kBegin:
init();
registerGraphics();
+ NancySceneState.setNoHeldItem();
if (_slotWinSound.name != "NO SOUND")
g_nancy->_sound->loadSound(_slotWinSound);
diff --git a/engines/nancy/action/puzzle/mazechasepuzzle.cpp b/engines/nancy/action/puzzle/mazechasepuzzle.cpp
index 268f393a0df..2585a82b705 100644
--- a/engines/nancy/action/puzzle/mazechasepuzzle.cpp
+++ b/engines/nancy/action/puzzle/mazechasepuzzle.cpp
@@ -231,6 +231,7 @@ void MazeChasePuzzle::execute() {
switch (_state) {
case kBegin :
init();
+ NancySceneState.setNoHeldItem();
g_nancy->_sound->loadSound(_moveSound);
g_nancy->_sound->loadSound(_failSound);
_state = kRun;
diff --git a/engines/nancy/action/puzzle/memorypuzzle.cpp b/engines/nancy/action/puzzle/memorypuzzle.cpp
index 48a0943ab81..fb2b99e517e 100644
--- a/engines/nancy/action/puzzle/memorypuzzle.cpp
+++ b/engines/nancy/action/puzzle/memorypuzzle.cpp
@@ -267,6 +267,7 @@ void MemoryPuzzle::execute() {
case kBegin:
init();
registerGraphics();
+ NancySceneState.setNoHeldItem();
if (_firstFlipSound.name != "NO SOUND")
g_nancy->_sound->loadSound(_firstFlipSound);
if (_secondFlipSound.name != "NO SOUND")
diff --git a/engines/nancy/action/puzzle/mindpuzzle.cpp b/engines/nancy/action/puzzle/mindpuzzle.cpp
index 19957baeedc..fb38e942609 100644
--- a/engines/nancy/action/puzzle/mindpuzzle.cpp
+++ b/engines/nancy/action/puzzle/mindpuzzle.cpp
@@ -266,6 +266,7 @@ void MindPuzzle::execute() {
init();
registerGraphics();
_heldBall.registerGraphics();
+ NancySceneState.setNoHeldItem();
_state = kRun;
// fall through
case kRun:
diff --git a/engines/nancy/action/puzzle/quizpuzzle.cpp b/engines/nancy/action/puzzle/quizpuzzle.cpp
index 91d8723da24..1e690e71d80 100644
--- a/engines/nancy/action/puzzle/quizpuzzle.cpp
+++ b/engines/nancy/action/puzzle/quizpuzzle.cpp
@@ -721,6 +721,7 @@ void QuizPuzzle::execute() {
case kBegin: {
init();
registerGraphics();
+ NancySceneState.setNoHeldItem();
_nextBlinkTime = g_nancy->getTotalPlayTime() + _cursorBlinkInterval;
if (g_nancy->getGameType() == kGameTypeNancy8) {
g_nancy->_sound->loadSound(_correctSound);
diff --git a/engines/nancy/action/puzzle/sortpuzzle.cpp b/engines/nancy/action/puzzle/sortpuzzle.cpp
index 62b3cbe3702..a22f4756e09 100644
--- a/engines/nancy/action/puzzle/sortpuzzle.cpp
+++ b/engines/nancy/action/puzzle/sortpuzzle.cpp
@@ -323,6 +323,7 @@ void SortPuzzle::execute() {
init();
registerGraphics();
_heldObject.registerGraphics();
+ NancySceneState.setNoHeldItem();
_state = kRun;
// fall through
diff --git a/engines/nancy/action/puzzle/typingquizpuzzle.cpp b/engines/nancy/action/puzzle/typingquizpuzzle.cpp
index 45dc755a329..a3892545df3 100644
--- a/engines/nancy/action/puzzle/typingquizpuzzle.cpp
+++ b/engines/nancy/action/puzzle/typingquizpuzzle.cpp
@@ -396,6 +396,7 @@ void TypingQuizPuzzle::execute() {
case kBegin:
init();
registerGraphics();
+ NancySceneState.setNoHeldItem();
_state = kRun;
// fall through
case kRun: {
diff --git a/engines/nancy/action/puzzle/whalesurvivorpuzzle.cpp b/engines/nancy/action/puzzle/whalesurvivorpuzzle.cpp
index c25adcac323..ec39c644d2b 100644
--- a/engines/nancy/action/puzzle/whalesurvivorpuzzle.cpp
+++ b/engines/nancy/action/puzzle/whalesurvivorpuzzle.cpp
@@ -392,6 +392,7 @@ void WhaleSurvivorPuzzle::execute() {
case kBegin:
init();
registerGraphics();
+ NancySceneState.setNoHeldItem();
_state = kRun;
// fall through
Commit: 39951813149f59c2f18718e32396e49a2ae5683d
https://github.com/scummvm/scummvm/commit/39951813149f59c2f18718e32396e49a2ae5683d
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2026-09-26T04:54:34+03:00
Commit Message:
NANCY: Centralize more sound and viewport related puzzle code
Centralize initViewportSurface(), playBoxSoundBlock() and
isSoundBlockPlaying()
This unveiled puzzles where subtitles weren't looked up for played
sounds. These use the same global code now, so subtitle lookup and
display behaves the same across all puzzles.
Changed paths:
engines/nancy/action/puzzle/angletosspuzzle.cpp
engines/nancy/action/puzzle/bballpuzzle.cpp
engines/nancy/action/puzzle/blockingpuzzle.cpp
engines/nancy/action/puzzle/blockingpuzzle.h
engines/nancy/action/puzzle/blockspuzzle.cpp
engines/nancy/action/puzzle/blockspuzzle.h
engines/nancy/action/puzzle/boardgamepuzzle.cpp
engines/nancy/action/puzzle/boardgamepuzzle.h
engines/nancy/action/puzzle/bulpuzzle.cpp
engines/nancy/action/puzzle/cardgamepuzzle.cpp
engines/nancy/action/puzzle/collisionpuzzle.cpp
engines/nancy/action/puzzle/cubepuzzle.cpp
engines/nancy/action/puzzle/decoderpuzzle.cpp
engines/nancy/action/puzzle/decoderpuzzle.h
engines/nancy/action/puzzle/drivingpuzzle.cpp
engines/nancy/action/puzzle/drivingpuzzle.h
engines/nancy/action/puzzle/dropsortpuzzle.cpp
engines/nancy/action/puzzle/dropsortpuzzle.h
engines/nancy/action/puzzle/escapegridpuzzle.cpp
engines/nancy/action/puzzle/escapegridpuzzle.h
engines/nancy/action/puzzle/hamradiopuzzle.cpp
engines/nancy/action/puzzle/hangmanpuzzle.cpp
engines/nancy/action/puzzle/hangmanpuzzle.h
engines/nancy/action/puzzle/lettergridpuzzle.cpp
engines/nancy/action/puzzle/lettergridpuzzle.h
engines/nancy/action/puzzle/magicboxpuzzle.cpp
engines/nancy/action/puzzle/magicboxpuzzle.h
engines/nancy/action/puzzle/matchpuzzle.cpp
engines/nancy/action/puzzle/matchpuzzle.h
engines/nancy/action/puzzle/mazechasepuzzle.cpp
engines/nancy/action/puzzle/minigolfpuzzle.cpp
engines/nancy/action/puzzle/minigolfpuzzle.h
engines/nancy/action/puzzle/mirrorlightpuzzle.cpp
engines/nancy/action/puzzle/mirrorlightpuzzle.h
engines/nancy/action/puzzle/necklacepuzzle.cpp
engines/nancy/action/puzzle/necklacepuzzle.h
engines/nancy/action/puzzle/overridelockpuzzle.cpp
engines/nancy/action/puzzle/pachinkopuzzle.cpp
engines/nancy/action/puzzle/pachinkopuzzle.h
engines/nancy/action/puzzle/paintpuzzle.cpp
engines/nancy/action/puzzle/paintpuzzle.h
engines/nancy/action/puzzle/pegspuzzle.cpp
engines/nancy/action/puzzle/pegspuzzle.h
engines/nancy/action/puzzle/quizpuzzle.cpp
engines/nancy/action/puzzle/quizpuzzle.h
engines/nancy/action/puzzle/rippedletterpuzzle.cpp
engines/nancy/action/puzzle/safedialpuzzle.cpp
engines/nancy/action/puzzle/scalepuzzle.cpp
engines/nancy/action/puzzle/scalepuzzle.h
engines/nancy/action/puzzle/setplayerclock.cpp
engines/nancy/action/puzzle/sewingmachinepuzzle.cpp
engines/nancy/action/puzzle/sewingmachinepuzzle.h
engines/nancy/action/puzzle/soundequalizerpuzzle.cpp
engines/nancy/action/puzzle/spigotpuzzle.cpp
engines/nancy/action/puzzle/stepobjectspuzzle.cpp
engines/nancy/action/puzzle/stepobjectspuzzle.h
engines/nancy/action/puzzle/tangrampuzzle.cpp
engines/nancy/action/puzzle/telephone.cpp
engines/nancy/action/puzzle/towerpuzzle.cpp
engines/nancy/action/puzzle/turningpuzzle.cpp
engines/nancy/action/puzzle/turningpuzzle.h
engines/nancy/action/puzzle/twodialpuzzle.cpp
engines/nancy/action/puzzle/weightsortpuzzle.cpp
engines/nancy/action/puzzle/weightsortpuzzle.h
engines/nancy/action/puzzle/wordfindpuzzle.cpp
engines/nancy/action/puzzlerecord.cpp
engines/nancy/action/puzzlerecord.h
diff --git a/engines/nancy/action/puzzle/angletosspuzzle.cpp b/engines/nancy/action/puzzle/angletosspuzzle.cpp
index 3193b54976a..ad2ee1e6594 100644
--- a/engines/nancy/action/puzzle/angletosspuzzle.cpp
+++ b/engines/nancy/action/puzzle/angletosspuzzle.cpp
@@ -33,12 +33,7 @@ namespace Nancy {
namespace Action {
void AngleTossPuzzle::init() {
- Common::Rect screenBounds = NancySceneState.getViewport().getBounds();
- _drawSurface.create(screenBounds.width(), screenBounds.height(), g_nancy->_graphics->getInputPixelFormat());
- _drawSurface.clear(g_nancy->_graphics->getTransColor());
- setTransparent(true);
- setVisible(true);
- moveTo(screenBounds);
+ initViewportSurface();
g_nancy->_resource->loadImage(_imageName, _image);
_image.setTransparentColor(_drawSurface.getTransparentColor());
diff --git a/engines/nancy/action/puzzle/bballpuzzle.cpp b/engines/nancy/action/puzzle/bballpuzzle.cpp
index 9f515535e55..234ee414c01 100644
--- a/engines/nancy/action/puzzle/bballpuzzle.cpp
+++ b/engines/nancy/action/puzzle/bballpuzzle.cpp
@@ -34,12 +34,7 @@ namespace Nancy {
namespace Action {
void BBallPuzzle::init() {
- Common::Rect screenBounds = NancySceneState.getViewport().getBounds();
- _drawSurface.create(screenBounds.width(), screenBounds.height(), g_nancy->_graphics->getInputPixelFormat());
- _drawSurface.clear(g_nancy->_graphics->getTransColor());
- setTransparent(true);
- setVisible(true);
- moveTo(screenBounds);
+ initViewportSurface();
g_nancy->_resource->loadImage(_imageName, _image);
_image.setTransparentColor(_drawSurface.getTransparentColor());
diff --git a/engines/nancy/action/puzzle/blockingpuzzle.cpp b/engines/nancy/action/puzzle/blockingpuzzle.cpp
index 8cd0999464c..0f7ea1e69a1 100644
--- a/engines/nancy/action/puzzle/blockingpuzzle.cpp
+++ b/engines/nancy/action/puzzle/blockingpuzzle.cpp
@@ -461,38 +461,5 @@ void BlockingPuzzle::handleInput(NancyInput &input) {
g_nancy->_cursor->setCursorType(CursorManager::kHotspot);
}
}
-
-void BlockingPuzzle::playSoundBlock(const RandomSoundBlock &block) {
- if (block.names.empty()) {
- return;
- }
-
- // Pick a random one of the block's names.
- uint index = block.names.size() > 1 ?
- g_nancy->_randomSource->getRandomNumber(block.names.size() - 1) : 0;
- if (block.names[index].empty() || block.names[index] == "NO SOUND") {
- return;
- }
-
- SoundDescription desc;
- desc.name = block.names[index];
- desc.channelID = block.channel;
- desc.numLoops = block.numLoops > 0 ? block.numLoops : 1;
- desc.volume = block.volume;
-
- g_nancy->_sound->loadSound(desc);
- g_nancy->_sound->playSound(desc);
-
- // The fighters' lines are CVTX captions keyed by the played sound's name
- // (autotext searched first, then convo), shown as the fight goes on.
- Common::String caption = resolveSubtitleText(desc.name, Common::String(), "AUTOTEXT");
- if (caption.empty()) {
- caption = resolveSubtitleText(desc.name, Common::String(), "CONVO");
- }
- if (!caption.empty()) {
- showSubtitle(caption);
- }
-}
-
} // End of namespace Action
} // End of namespace Nancy
diff --git a/engines/nancy/action/puzzle/blockingpuzzle.h b/engines/nancy/action/puzzle/blockingpuzzle.h
index 133c17eb648..6d30894779a 100644
--- a/engines/nancy/action/puzzle/blockingpuzzle.h
+++ b/engines/nancy/action/puzzle/blockingpuzzle.h
@@ -153,7 +153,6 @@ protected:
int cellAtPoint(const Common::Point &mousePos) const;
int resolveBlock(int attackCell, int blockCell, Common::Point &recoil) const;
void applyDamage(const Common::Point &recoil);
- void playSoundBlock(const RandomSoundBlock &block);
MoviePlayer _moviePlayer;
Graphics::ManagedSurface _overlayImage; // MOU_Fight_OVL sprite sheet
diff --git a/engines/nancy/action/puzzle/blockspuzzle.cpp b/engines/nancy/action/puzzle/blockspuzzle.cpp
index 1a74cdf105d..68a09e66128 100644
--- a/engines/nancy/action/puzzle/blockspuzzle.cpp
+++ b/engines/nancy/action/puzzle/blockspuzzle.cpp
@@ -97,12 +97,7 @@ void BlocksPuzzle::readData(Common::SeekableReadStream &stream) {
}
void BlocksPuzzle::init() {
- Common::Rect vpBounds = NancySceneState.getViewport().getBounds();
- _drawSurface.create(vpBounds.width(), vpBounds.height(), g_nancy->_graphics->getInputPixelFormat());
- _drawSurface.clear(g_nancy->_graphics->getTransColor());
- setTransparent(true);
- setVisible(true);
- moveTo(vpBounds);
+ initViewportSurface();
g_nancy->_resource->loadImage(_imageName, _image);
_image.setTransparentColor(_drawSurface.getTransparentColor());
@@ -256,34 +251,6 @@ void BlocksPuzzle::redraw() {
_needsRedraw = true;
}
-void BlocksPuzzle::setDataCursor(uint16 cursorType, bool hotspotVariant) const {
- // The ids in the AR data are raw Nancy13 cursor types, which is exactly what the
- // "set from script" path expects.
- g_nancy->_cursor->setCursorType((CursorManager::CursorType)cursorType, true, hotspotVariant);
-}
-
-SoundDescription BlocksPuzzle::playSoundBlock(const RandomSoundBlock &block) {
- SoundDescription desc;
- if (block.names.empty()) {
- return desc;
- }
-
- uint idx = block.names.size() == 1 ? 0 : g_nancy->_randomSource->getRandomNumber(block.names.size() - 1);
- const Common::String &name = block.names[idx];
- if (name.empty() || name == "NO SOUND") {
- return desc;
- }
-
- desc.name = name;
- desc.channelID = block.channel;
- desc.numLoops = block.numLoops > 0 ? block.numLoops : 1;
- desc.volume = block.volume;
-
- g_nancy->_sound->loadSound(desc);
- g_nancy->_sound->playSound(desc);
- return desc;
-}
-
void BlocksPuzzle::execute() {
switch (_state) {
case kBegin:
diff --git a/engines/nancy/action/puzzle/blockspuzzle.h b/engines/nancy/action/puzzle/blockspuzzle.h
index d0e04190ce4..796b3003ced 100644
--- a/engines/nancy/action/puzzle/blockspuzzle.h
+++ b/engines/nancy/action/puzzle/blockspuzzle.h
@@ -101,9 +101,6 @@ protected:
void updateCarried(NancyInput *input);
void startTurn();
void redraw();
- // Zone cursors take the idle sprite of their type, hover/drag cursors the hotspot one.
- void setDataCursor(uint16 cursorType, bool hotspotVariant = true) const;
- SoundDescription playSoundBlock(const RandomSoundBlock &block);
// -- File data (111-byte header) --
Common::Path _imageName; // 0x00
diff --git a/engines/nancy/action/puzzle/boardgamepuzzle.cpp b/engines/nancy/action/puzzle/boardgamepuzzle.cpp
index 493fa52db6e..4f33be264c6 100644
--- a/engines/nancy/action/puzzle/boardgamepuzzle.cpp
+++ b/engines/nancy/action/puzzle/boardgamepuzzle.cpp
@@ -132,7 +132,7 @@ void BoardGamePuzzle::redraw() {
_needsRedraw = true;
}
-void BoardGamePuzzle::playSoundBlock(uint index) {
+void BoardGamePuzzle::playSoundByIndex(uint index) {
if (index >= kNumSounds) {
return;
}
@@ -184,7 +184,7 @@ void BoardGamePuzzle::resolveMove(int button) {
_buttonUsed[button] = true;
_activeCard = button; // shows the white sprite while the move plays
_boardState = kBoardAnimating;
- playSoundBlock(kSlideSound);
+ playSoundByIndex(kSlideSound);
_moviePlayer.playRange(startFrame, endFrame);
// Full redraw once at the start so the played card turns white and the first
@@ -219,15 +219,15 @@ void BoardGamePuzzle::execute() {
redraw();
if (_solved) {
- playSoundBlock(kWinSound);
+ playSoundByIndex(kWinSound);
_resultTime = g_nancy->getTotalPlayTime();
_boardState = kBoardResult;
} else if (_lost) {
- playSoundBlock(kLoseSound);
+ playSoundByIndex(kLoseSound);
_resultTime = g_nancy->getTotalPlayTime();
_boardState = kBoardResult;
} else {
- playSoundBlock(kLandSound);
+ playSoundByIndex(kLandSound);
_boardState = kBoardWaiting;
}
}
@@ -265,7 +265,7 @@ void BoardGamePuzzle::handleInput(NancyInput &input) {
}
_resetPressed = true;
_resetPressedTime = g_nancy->getTotalPlayTime();
- playSoundBlock(kResetSound);
+ playSoundByIndex(kResetSound);
_moviePlayer.goToFrame(framePosition(_position));
redraw();
}
@@ -282,7 +282,7 @@ void BoardGamePuzzle::handleInput(NancyInput &input) {
}
g_nancy->_cursor->setCursorType(CursorManager::kHotspot);
if (input.input & NancyInput::kLeftMouseButtonUp) {
- playSoundBlock(kButtonSound);
+ playSoundByIndex(kButtonSound);
resolveMove(i);
}
return;
diff --git a/engines/nancy/action/puzzle/boardgamepuzzle.h b/engines/nancy/action/puzzle/boardgamepuzzle.h
index 8903d76b247..15a4d4a0ef8 100644
--- a/engines/nancy/action/puzzle/boardgamepuzzle.h
+++ b/engines/nancy/action/puzzle/boardgamepuzzle.h
@@ -111,7 +111,7 @@ protected:
void redraw();
void drawCard(uint index);
void resolveMove(int button);
- void playSoundBlock(uint index);
+ void playSoundByIndex(uint index);
int framePosition(int position) const { return _framesPerPosition * position + 1; }
};
diff --git a/engines/nancy/action/puzzle/bulpuzzle.cpp b/engines/nancy/action/puzzle/bulpuzzle.cpp
index a363063adb5..e30a2305ba5 100644
--- a/engines/nancy/action/puzzle/bulpuzzle.cpp
+++ b/engines/nancy/action/puzzle/bulpuzzle.cpp
@@ -36,12 +36,7 @@ namespace Nancy {
namespace Action {
void BulPuzzle::init() {
- Common::Rect screenBounds = NancySceneState.getViewport().getBounds();
- _drawSurface.create(screenBounds.width(), screenBounds.height(), g_nancy->_graphics->getInputPixelFormat());
- _drawSurface.clear(g_nancy->_graphics->getTransColor());
- setTransparent(true);
- setVisible(true);
- moveTo(screenBounds);
+ initViewportSurface();
g_nancy->_resource->loadImage(_imageName, _image);
_image.setTransparentColor(_drawSurface.getTransparentColor());
diff --git a/engines/nancy/action/puzzle/cardgamepuzzle.cpp b/engines/nancy/action/puzzle/cardgamepuzzle.cpp
index 82735807937..dc5b5e38427 100644
--- a/engines/nancy/action/puzzle/cardgamepuzzle.cpp
+++ b/engines/nancy/action/puzzle/cardgamepuzzle.cpp
@@ -503,12 +503,7 @@ void CardGamePuzzle::playVoice(const Common::String &name) {
}
void CardGamePuzzle::init() {
- Common::Rect vpBounds = NancySceneState.getViewport().getBounds();
- _drawSurface.create(vpBounds.width(), vpBounds.height(), g_nancy->_graphics->getInputPixelFormat());
- _drawSurface.clear(g_nancy->_graphics->getTransColor());
- setTransparent(true);
- setVisible(true);
- moveTo(vpBounds);
+ initViewportSurface();
g_nancy->_resource->loadImage(_imageName, _image);
_image.setTransparentColor(_drawSurface.getTransparentColor());
diff --git a/engines/nancy/action/puzzle/collisionpuzzle.cpp b/engines/nancy/action/puzzle/collisionpuzzle.cpp
index 755561c389d..ac5a746d7dc 100644
--- a/engines/nancy/action/puzzle/collisionpuzzle.cpp
+++ b/engines/nancy/action/puzzle/collisionpuzzle.cpp
@@ -34,12 +34,7 @@ namespace Nancy {
namespace Action {
void CollisionPuzzle::init() {
- Common::Rect screenBounds = NancySceneState.getViewport().getBounds();
- _drawSurface.create(screenBounds.width(), screenBounds.height(), g_nancy->_graphics->getInputPixelFormat());
- _drawSurface.clear(g_nancy->_graphics->getTransColor());
- setTransparent(true);
- setVisible(true);
- moveTo(screenBounds);
+ initViewportSurface();
g_nancy->_resource->loadImage(_imageName, _image);
_image.setTransparentColor(_drawSurface.getTransparentColor());
diff --git a/engines/nancy/action/puzzle/cubepuzzle.cpp b/engines/nancy/action/puzzle/cubepuzzle.cpp
index de176459ded..aabd52f1170 100644
--- a/engines/nancy/action/puzzle/cubepuzzle.cpp
+++ b/engines/nancy/action/puzzle/cubepuzzle.cpp
@@ -34,12 +34,7 @@ namespace Nancy {
namespace Action {
void CubePuzzle::init() {
- Common::Rect screenBounds = NancySceneState.getViewport().getBounds();
- _drawSurface.create(screenBounds.width(), screenBounds.height(), g_nancy->_graphics->getInputPixelFormat());
- _drawSurface.clear(g_nancy->_graphics->getTransColor());
- setTransparent(true);
- setVisible(true);
- moveTo(screenBounds);
+ initViewportSurface();
g_nancy->_resource->loadImage(_imageName, _image);
_image.setTransparentColor(_drawSurface.getTransparentColor());
diff --git a/engines/nancy/action/puzzle/decoderpuzzle.cpp b/engines/nancy/action/puzzle/decoderpuzzle.cpp
index fcba369c920..df278dd9d35 100644
--- a/engines/nancy/action/puzzle/decoderpuzzle.cpp
+++ b/engines/nancy/action/puzzle/decoderpuzzle.cpp
@@ -174,38 +174,6 @@ void DecoderPuzzle::onPause(bool paused) {
PuzzleRecord::onPause(paused);
}
-void DecoderPuzzle::playSoundBlock(const RandomSoundBlock &block) {
- if (block.names.empty()) {
- return;
- }
-
- uint idx = block.names.size() == 1 ? 0 : g_nancy->_randomSource->getRandomNumber(block.names.size() - 1);
- const Common::String &name = block.names[idx];
- if (name.empty() || name == "NO SOUND") {
- return;
- }
-
- SoundDescription desc;
- desc.name = name;
- desc.channelID = block.channel;
- desc.numLoops = block.numLoops > 0 ? block.numLoops : 1;
- desc.volume = block.volume;
-
- g_nancy->_sound->loadSound(desc);
- g_nancy->_sound->playSound(desc);
-
- // Voice lines carry no inline caption; it's keyed by the sound's name
- Common::String caption = resolveSubtitleText(name, Common::String(), "AUTOTEXT");
- if (caption.empty()) {
- caption = resolveSubtitleText(name, Common::String(), "CONVO");
- }
- showSubtitle(caption);
-}
-
-bool DecoderPuzzle::isSoundBlockPlaying(const RandomSoundBlock &block) const {
- return !block.names.empty() && g_nancy->_sound->isSoundPlaying((uint16)block.channel);
-}
-
bool DecoderPuzzle::decodePending(bool &noMatch) {
noMatch = false;
diff --git a/engines/nancy/action/puzzle/decoderpuzzle.h b/engines/nancy/action/puzzle/decoderpuzzle.h
index 1ed7a5cebba..73fd5e75ed5 100644
--- a/engines/nancy/action/puzzle/decoderpuzzle.h
+++ b/engines/nancy/action/puzzle/decoderpuzzle.h
@@ -68,8 +68,6 @@ protected:
static bool isAcceptedKey(byte key);
DecoderData *getPuzzleData() const;
- void playSoundBlock(const RandomSoundBlock &block);
- bool isSoundBlockPlaying(const RandomSoundBlock &block) const;
// Consumes the pending sequence. True if it produced output; sets noMatch
// when the sequence cannot lead to any substitution.
diff --git a/engines/nancy/action/puzzle/drivingpuzzle.cpp b/engines/nancy/action/puzzle/drivingpuzzle.cpp
index b6504b54a48..da0ee931ff2 100644
--- a/engines/nancy/action/puzzle/drivingpuzzle.cpp
+++ b/engines/nancy/action/puzzle/drivingpuzzle.cpp
@@ -206,7 +206,7 @@ void DrivingPuzzle::classifyZones(const Common::Array<ActionZone> &zones) {
}
}
-void DrivingPuzzle::playSoundBlock(const RandomSoundBlock &block) {
+void DrivingPuzzle::playSoundBlockRawLoops(const RandomSoundBlock &block) {
if (block.names.empty()) {
return;
}
@@ -658,7 +658,7 @@ void DrivingPuzzle::updatePhysics(int throttle, double cursorDist) {
if (_tireDamage >= kTireFlatThreshold) {
_tireDamage = 0;
_flatTirePending = true;
- playSoundBlock(_soundBlocks[0]); // tire blowout
+ playSoundBlockRawLoops(_soundBlocks[0]); // tire blowout
}
}
hole.carInside = nowInside;
@@ -712,7 +712,7 @@ void DrivingPuzzle::execute() {
if (_variant == kChase) {
classifyZones(_zones2);
}
- playSoundBlock(_soundBlocks[2]); // looping engine ambience
+ playSoundBlockRawLoops(_soundBlocks[2]); // looping engine ambience
drawScene();
_state = kRun;
break;
diff --git a/engines/nancy/action/puzzle/drivingpuzzle.h b/engines/nancy/action/puzzle/drivingpuzzle.h
index 80cc3bbdc27..e1a54ef55f0 100644
--- a/engines/nancy/action/puzzle/drivingpuzzle.h
+++ b/engines/nancy/action/puzzle/drivingpuzzle.h
@@ -192,8 +192,8 @@ protected:
// boundary zones), decoding the destination scenes and their transition effects.
void classifyZones(const Common::Array<ActionZone> &zones);
- // Plays one (randomly chosen) entry of a random-sound block.
- void playSoundBlock(const RandomSoundBlock &block);
+ // Like playSoundBlock(), but a loop count of 0 keeps looping (the engine ambience)
+ void playSoundBlockRawLoops(const RandomSoundBlock &block);
// Arms a pending exit (applied in kActionTrigger): from a destination zone (keeping
// its fade), or from a raw scene id plus an optional event flag to set.
diff --git a/engines/nancy/action/puzzle/dropsortpuzzle.cpp b/engines/nancy/action/puzzle/dropsortpuzzle.cpp
index 7c156359022..7b5e0a1ea5f 100644
--- a/engines/nancy/action/puzzle/dropsortpuzzle.cpp
+++ b/engines/nancy/action/puzzle/dropsortpuzzle.cpp
@@ -117,12 +117,7 @@ void DropSortPuzzle::readData(Common::SeekableReadStream &stream) {
}
void DropSortPuzzle::init() {
- Common::Rect vpBounds = NancySceneState.getViewport().getBounds();
- _drawSurface.create(vpBounds.width(), vpBounds.height(), g_nancy->_graphics->getInputPixelFormat());
- _drawSurface.clear(g_nancy->_graphics->getTransColor());
- setTransparent(true);
- setVisible(true);
- moveTo(vpBounds);
+ initViewportSurface();
g_nancy->_resource->loadImage(_imageName, _image);
_image.setTransparentColor(_drawSurface.getTransparentColor());
@@ -298,28 +293,6 @@ void DropSortPuzzle::drawCounter() {
font->drawString(&_drawSurface, str, _counterX, _counterY, w + 4, 0);
}
-SoundDescription DropSortPuzzle::playSoundBlock(const RandomSoundBlock &block) {
- SoundDescription desc;
- if (block.names.empty()) {
- return desc;
- }
-
- uint idx = block.names.size() == 1 ? 0 : g_nancy->_randomSource->getRandomNumber(block.names.size() - 1);
- const Common::String &name = block.names[idx];
- if (name.empty() || name == "NO SOUND") {
- return desc;
- }
-
- desc.name = name;
- desc.channelID = block.channel;
- desc.numLoops = block.numLoops > 0 ? block.numLoops : 1;
- desc.volume = block.volume;
-
- g_nancy->_sound->loadSound(desc);
- g_nancy->_sound->playSound(desc);
- return desc;
-}
-
void DropSortPuzzle::execute() {
switch (_state) {
case kBegin:
diff --git a/engines/nancy/action/puzzle/dropsortpuzzle.h b/engines/nancy/action/puzzle/dropsortpuzzle.h
index 936ab19bdb3..c17bf7ccff6 100644
--- a/engines/nancy/action/puzzle/dropsortpuzzle.h
+++ b/engines/nancy/action/puzzle/dropsortpuzzle.h
@@ -82,7 +82,6 @@ protected:
void redraw();
void drawCounter();
- SoundDescription playSoundBlock(const RandomSoundBlock &block);
// -- File data --
Common::Path _imageName; // 0x00 - overlay sprite sheet (candies, strikes)
diff --git a/engines/nancy/action/puzzle/escapegridpuzzle.cpp b/engines/nancy/action/puzzle/escapegridpuzzle.cpp
index 534b731879e..d5fba493a70 100644
--- a/engines/nancy/action/puzzle/escapegridpuzzle.cpp
+++ b/engines/nancy/action/puzzle/escapegridpuzzle.cpp
@@ -176,12 +176,7 @@ static void loadPuzzleImage(const Common::Path &name, Graphics::ManagedSurface &
}
void EscapeGridPuzzle::init() {
- Common::Rect vpBounds = NancySceneState.getViewport().getBounds();
- _drawSurface.create(vpBounds.width(), vpBounds.height(), g_nancy->_graphics->getInputPixelFormat());
- _drawSurface.clear(g_nancy->_graphics->getTransColor());
- setTransparent(true);
- setVisible(true);
- moveTo(vpBounds);
+ initViewportSurface();
uint32 transColor = _drawSurface.getTransparentColor();
@@ -900,28 +895,6 @@ bool EscapeGridPuzzle::findHoveredCell(const Common::Point &mousePos, Common::Po
return true;
}
-SoundDescription EscapeGridPuzzle::playSoundBlock(const RandomSoundBlock &block) {
- SoundDescription desc;
- if (block.names.empty()) {
- return desc;
- }
-
- uint idx = block.names.size() == 1 ? 0 : g_nancy->_randomSource->getRandomNumber(block.names.size() - 1);
- const Common::String &name = block.names[idx];
- if (name.empty() || name == "NO SOUND") {
- return desc;
- }
-
- desc.name = name;
- desc.channelID = block.channel;
- desc.numLoops = block.numLoops > 0 ? block.numLoops : 1;
- desc.volume = block.volume;
-
- g_nancy->_sound->loadSound(desc);
- g_nancy->_sound->playSound(desc);
- return desc;
-}
-
void EscapeGridPuzzle::drawAnimFrame(const Graphics::ManagedSurface &image, const Animation &anim, int32 elapsed,
const Common::Point &pos) {
if (image.empty() || anim.srcs.empty()) {
diff --git a/engines/nancy/action/puzzle/escapegridpuzzle.h b/engines/nancy/action/puzzle/escapegridpuzzle.h
index 49634ff30f3..329863e35d5 100644
--- a/engines/nancy/action/puzzle/escapegridpuzzle.h
+++ b/engines/nancy/action/puzzle/escapegridpuzzle.h
@@ -215,7 +215,6 @@ protected:
bool isCellPixel(const Common::Point &cell, const Common::Point &pos) const;
bool findHoveredCell(const Common::Point &mousePos, Common::Point &outCell) const;
- SoundDescription playSoundBlock(const RandomSoundBlock &block);
void drawAnimFrame(const Graphics::ManagedSurface &image, const Animation &anim, int32 elapsed,
const Common::Point &pos);
void drawJump(uint actor, const ActorAnim &anim);
diff --git a/engines/nancy/action/puzzle/hamradiopuzzle.cpp b/engines/nancy/action/puzzle/hamradiopuzzle.cpp
index 446c25a61a7..0982ce882bd 100644
--- a/engines/nancy/action/puzzle/hamradiopuzzle.cpp
+++ b/engines/nancy/action/puzzle/hamradiopuzzle.cpp
@@ -47,12 +47,7 @@ static const char *morseCodeTable[] = {
};
void HamRadioPuzzle::init() {
- Common::Rect screenBounds = NancySceneState.getViewport().getBounds();
- _drawSurface.create(screenBounds.width(), screenBounds.height(), g_nancy->_graphics->getInputPixelFormat());
- _drawSurface.clear(g_nancy->_graphics->getTransColor());
- setTransparent(true);
- setVisible(true);
- moveTo(screenBounds);
+ initViewportSurface();
g_nancy->_resource->loadImage(_imageName, _image);
_image.setTransparentColor(_drawSurface.getTransparentColor());
diff --git a/engines/nancy/action/puzzle/hangmanpuzzle.cpp b/engines/nancy/action/puzzle/hangmanpuzzle.cpp
index a5eb37e9ff2..a4ad0b3d379 100644
--- a/engines/nancy/action/puzzle/hangmanpuzzle.cpp
+++ b/engines/nancy/action/puzzle/hangmanpuzzle.cpp
@@ -309,35 +309,6 @@ void HangmanPuzzle::checkOutcome() {
}
}
-void HangmanPuzzle::playSoundBlock(const RandomSoundBlock &block) {
- if (block.names.empty()) {
- return;
- }
-
- uint index = block.names.size() > 1 ?
- g_nancy->_randomSource->getRandomNumber(block.names.size() - 1) : 0;
- if (block.names[index].empty() || block.names[index] == "NO SOUND") {
- return;
- }
-
- SoundDescription desc;
- desc.name = block.names[index];
- desc.channelID = block.channel;
- desc.numLoops = block.numLoops > 0 ? block.numLoops : 1;
- desc.volume = block.volume;
-
- g_nancy->_sound->loadSound(desc);
- g_nancy->_sound->playSound(desc);
-
- Common::String caption = resolveSubtitleText(desc.name, Common::String(), "AUTOTEXT");
- if (caption.empty()) {
- caption = resolveSubtitleText(desc.name, Common::String(), "CONVO");
- }
- if (!caption.empty()) {
- showSubtitle(caption);
- }
-}
-
void HangmanPuzzle::handleInput(NancyInput &input) {
if (_state != kRun) {
return;
diff --git a/engines/nancy/action/puzzle/hangmanpuzzle.h b/engines/nancy/action/puzzle/hangmanpuzzle.h
index 02bd261ce7c..a1c079c25ea 100644
--- a/engines/nancy/action/puzzle/hangmanpuzzle.h
+++ b/engines/nancy/action/puzzle/hangmanpuzzle.h
@@ -85,7 +85,6 @@ protected:
void updateFeedback();
void checkOutcome();
void redraw();
- void playSoundBlock(const RandomSoundBlock &block);
// -- File data --
Common::Path _puzzleImageName; // 0x3d
diff --git a/engines/nancy/action/puzzle/lettergridpuzzle.cpp b/engines/nancy/action/puzzle/lettergridpuzzle.cpp
index cd970f4a6ae..75c35af8e76 100644
--- a/engines/nancy/action/puzzle/lettergridpuzzle.cpp
+++ b/engines/nancy/action/puzzle/lettergridpuzzle.cpp
@@ -208,27 +208,6 @@ void LetterGridPuzzle::checkSolved() {
_solved = true;
}
-void LetterGridPuzzle::playSoundBlock(const RandomSoundBlock &block) {
- if (block.names.empty()) {
- return;
- }
-
- uint idx = block.names.size() == 1 ? 0 : g_nancy->_randomSource->getRandomNumber(block.names.size() - 1);
- const Common::String &name = block.names[idx];
- if (name.empty() || name == "NO SOUND") {
- return;
- }
-
- SoundDescription desc;
- desc.name = name;
- desc.channelID = block.channel;
- desc.numLoops = block.numLoops > 0 ? block.numLoops : 1;
- desc.volume = block.volume;
-
- g_nancy->_sound->loadSound(desc);
- g_nancy->_sound->playSound(desc);
-}
-
void LetterGridPuzzle::redraw() {
_drawSurface.clear(_drawSurface.getTransparentColor());
diff --git a/engines/nancy/action/puzzle/lettergridpuzzle.h b/engines/nancy/action/puzzle/lettergridpuzzle.h
index e3d497b44b2..938d36dbc71 100644
--- a/engines/nancy/action/puzzle/lettergridpuzzle.h
+++ b/engines/nancy/action/puzzle/lettergridpuzzle.h
@@ -71,7 +71,6 @@ protected:
bool cellAt(const Common::Point &point, uint &column, uint &row) const;
void toggleCell(uint column, uint row);
void checkSolved();
- void playSoundBlock(const RandomSoundBlock &block);
void redraw();
// -- File data --
diff --git a/engines/nancy/action/puzzle/magicboxpuzzle.cpp b/engines/nancy/action/puzzle/magicboxpuzzle.cpp
index 2bb1129037f..bdc9af3b618 100644
--- a/engines/nancy/action/puzzle/magicboxpuzzle.cpp
+++ b/engines/nancy/action/puzzle/magicboxpuzzle.cpp
@@ -114,12 +114,7 @@ void MagicBoxPuzzle::readData(Common::SeekableReadStream &stream) {
}
void MagicBoxPuzzle::init() {
- Common::Rect vpBounds = NancySceneState.getViewport().getBounds();
- _drawSurface.create(vpBounds.width(), vpBounds.height(), g_nancy->_graphics->getInputPixelFormat());
- _drawSurface.clear(g_nancy->_graphics->getTransColor());
- setTransparent(true);
- setVisible(true);
- moveTo(vpBounds);
+ initViewportSurface();
g_nancy->_resource->loadImage(_tileImageName, _tileImage);
_tileImage.setTransparentColor(_drawSurface.getTransparentColor());
@@ -238,32 +233,6 @@ void MagicBoxPuzzle::carryPiece(int piece, NancyInput &input) {
}
}
-void MagicBoxPuzzle::setDataCursor(uint16 cursorType, bool hotspotVariant) const {
- g_nancy->_cursor->setCursorType((CursorManager::CursorType)cursorType, true, hotspotVariant);
-}
-
-SoundDescription MagicBoxPuzzle::playSoundBlock(const RandomSoundBlock &block) {
- SoundDescription desc;
- if (block.names.empty()) {
- return desc;
- }
-
- uint idx = block.names.size() == 1 ? 0 : g_nancy->_randomSource->getRandomNumber(block.names.size() - 1);
- const Common::String &name = block.names[idx];
- if (name.empty() || name == "NO SOUND") {
- return desc;
- }
-
- desc.name = name;
- desc.channelID = block.channel;
- desc.numLoops = block.numLoops > 0 ? block.numLoops : 1;
- desc.volume = block.volume;
-
- g_nancy->_sound->loadSound(desc);
- g_nancy->_sound->playSound(desc);
- return desc;
-}
-
void MagicBoxPuzzle::redraw() {
_drawSurface.clear(g_nancy->_graphics->getTransColor());
diff --git a/engines/nancy/action/puzzle/magicboxpuzzle.h b/engines/nancy/action/puzzle/magicboxpuzzle.h
index e6dc518ff0d..5910992d831 100644
--- a/engines/nancy/action/puzzle/magicboxpuzzle.h
+++ b/engines/nancy/action/puzzle/magicboxpuzzle.h
@@ -58,8 +58,6 @@ protected:
void carryPiece(int piece, NancyInput &input);
Common::Rect tileSrc(int32 value) const;
- void setDataCursor(uint16 cursorType, bool hotspotVariant = true) const;
- SoundDescription playSoundBlock(const RandomSoundBlock &block);
void redraw();
static const uint kNumSounds = 10;
diff --git a/engines/nancy/action/puzzle/matchpuzzle.cpp b/engines/nancy/action/puzzle/matchpuzzle.cpp
index dc74a3dcc9c..fcea46e94d6 100644
--- a/engines/nancy/action/puzzle/matchpuzzle.cpp
+++ b/engines/nancy/action/puzzle/matchpuzzle.cpp
@@ -286,29 +286,6 @@ void MatchPuzzle::init() {
redrawAllCells();
}
-void MatchPuzzle::playSoundBlock(const RandomSoundBlock &block) {
- if (block.names.empty())
- return;
-
- uint idx = block.names.size() == 1 ? 0 : g_nancy->_randomSource->getRandomNumber(block.names.size() - 1);
- const Common::String &name = block.names[idx];
- if (name.empty() || name == "NO SOUND")
- return;
-
- SoundDescription desc;
- desc.name = name;
- desc.channelID = block.channel;
- desc.numLoops = block.numLoops > 0 ? block.numLoops : 1;
- desc.volume = block.volume;
-
- g_nancy->_sound->loadSound(desc);
- g_nancy->_sound->playSound(desc);
-}
-
-bool MatchPuzzle::isSoundBlockPlaying(const RandomSoundBlock &block) const {
- return !block.names.empty() && g_nancy->_sound->isSoundPlaying((uint16)block.channel);
-}
-
void MatchPuzzle::playMatchSound() {
if (g_nancy->getGameType() >= kGameTypeNancy14) {
playSoundBlock(_matchSound);
diff --git a/engines/nancy/action/puzzle/matchpuzzle.h b/engines/nancy/action/puzzle/matchpuzzle.h
index f1f797b8a1c..a94c633687d 100644
--- a/engines/nancy/action/puzzle/matchpuzzle.h
+++ b/engines/nancy/action/puzzle/matchpuzzle.h
@@ -91,8 +91,6 @@ protected:
void handleInputNancy14(NancyInput &input, const Common::Point &localMouse);
void drawHighScoreScreen();
void drawBoardNancy14();
- void playSoundBlock(const RandomSoundBlock &block);
- bool isSoundBlockPlaying(const RandomSoundBlock &block) const;
void startRound();
void sortHighScores();
void insertHighScore();
diff --git a/engines/nancy/action/puzzle/mazechasepuzzle.cpp b/engines/nancy/action/puzzle/mazechasepuzzle.cpp
index 2585a82b705..694f32a6cd2 100644
--- a/engines/nancy/action/puzzle/mazechasepuzzle.cpp
+++ b/engines/nancy/action/puzzle/mazechasepuzzle.cpp
@@ -34,12 +34,7 @@ namespace Nancy {
namespace Action {
void MazeChasePuzzle::init() {
- Common::Rect screenBounds = NancySceneState.getViewport().getBounds();
- _drawSurface.create(screenBounds.width(), screenBounds.height(), g_nancy->_graphics->getInputPixelFormat());
- _drawSurface.clear(g_nancy->_graphics->getTransColor());
- setTransparent(true);
- setVisible(true);
- moveTo(screenBounds);
+ initViewportSurface();
g_nancy->_resource->loadImage(_imageName, _image);
_image.setTransparentColor(_drawSurface.getTransparentColor());
diff --git a/engines/nancy/action/puzzle/minigolfpuzzle.cpp b/engines/nancy/action/puzzle/minigolfpuzzle.cpp
index e530b4b00f9..1e176bbff2a 100644
--- a/engines/nancy/action/puzzle/minigolfpuzzle.cpp
+++ b/engines/nancy/action/puzzle/minigolfpuzzle.cpp
@@ -312,27 +312,6 @@ void MinigolfPuzzle::redraw() {
_needsRedraw = true;
}
-void MinigolfPuzzle::playSoundBlock(const RandomSoundBlock &block) {
- if (block.names.empty()) {
- return;
- }
-
- uint idx = block.names.size() == 1 ? 0 : g_nancy->_randomSource->getRandomNumber(block.names.size() - 1);
- const Common::String &name = block.names[idx];
- if (name.empty() || name == "NO SOUND") {
- return;
- }
-
- SoundDescription desc;
- desc.name = name;
- desc.channelID = block.channel;
- desc.numLoops = block.numLoops > 0 ? block.numLoops : 1;
- desc.volume = block.volume;
-
- g_nancy->_sound->loadSound(desc);
- g_nancy->_sound->playSound(desc);
-}
-
void MinigolfPuzzle::aimToVelocity(double aimX, double aimY, double &vx, double &vy) const {
// Struck speed is proportional to the drag length (clamped to maxSpeed), aimed
// along the drag vector: speed = drag * kPowerScale * maxSpeed.
diff --git a/engines/nancy/action/puzzle/minigolfpuzzle.h b/engines/nancy/action/puzzle/minigolfpuzzle.h
index 325045829e9..27dcf098a75 100644
--- a/engines/nancy/action/puzzle/minigolfpuzzle.h
+++ b/engines/nancy/action/puzzle/minigolfpuzzle.h
@@ -54,7 +54,6 @@ protected:
void drawBall();
void drawGhostBall(const Common::Rect &src, const Common::Point &dest);
void drawAimPreview();
- void playSoundBlock(const RandomSoundBlock &block);
void launchBall(const Common::Point &maskCursor);
void writeStrokeCount(); // mirror _strokes into the scorecard's TableData slot
void aimToVelocity(double aimX, double aimY, double &vx, double &vy) const;
diff --git a/engines/nancy/action/puzzle/mirrorlightpuzzle.cpp b/engines/nancy/action/puzzle/mirrorlightpuzzle.cpp
index 1aa5e462cfb..cc6e40bd274 100644
--- a/engines/nancy/action/puzzle/mirrorlightpuzzle.cpp
+++ b/engines/nancy/action/puzzle/mirrorlightpuzzle.cpp
@@ -358,27 +358,6 @@ void MirrorLightPuzzle::saveMirrorAngles() {
}
}
-void MirrorLightPuzzle::playSoundBlock(const RandomSoundBlock &block) {
- if (block.names.empty()) {
- return;
- }
-
- uint idx = block.names.size() == 1 ? 0 : g_nancy->_randomSource->getRandomNumber(block.names.size() - 1);
- const Common::String &name = block.names[idx];
- if (name.empty() || name == "NO SOUND") {
- return;
- }
-
- SoundDescription desc;
- desc.name = name;
- desc.channelID = block.channel;
- desc.numLoops = block.numLoops > 0 ? block.numLoops : 1;
- desc.volume = block.volume;
-
- g_nancy->_sound->loadSound(desc);
- g_nancy->_sound->playSound(desc);
-}
-
void MirrorLightPuzzle::init() {
Common::Rect vpBounds = NancySceneState.getViewport().getBounds();
_drawSurface.create(vpBounds.width(), vpBounds.height(),
diff --git a/engines/nancy/action/puzzle/mirrorlightpuzzle.h b/engines/nancy/action/puzzle/mirrorlightpuzzle.h
index 9810476e8ec..51f8a12c448 100644
--- a/engines/nancy/action/puzzle/mirrorlightpuzzle.h
+++ b/engines/nancy/action/puzzle/mirrorlightpuzzle.h
@@ -111,7 +111,6 @@ protected:
void drawBeam();
void drawOverlays();
void redraw();
- void playSoundBlock(const RandomSoundBlock &block);
};
} // End of namespace Action
diff --git a/engines/nancy/action/puzzle/necklacepuzzle.cpp b/engines/nancy/action/puzzle/necklacepuzzle.cpp
index ddd5efb6635..1840512c44c 100644
--- a/engines/nancy/action/puzzle/necklacepuzzle.cpp
+++ b/engines/nancy/action/puzzle/necklacepuzzle.cpp
@@ -149,12 +149,7 @@ void NecklacePuzzle::readData(Common::SeekableReadStream &stream) {
}
void NecklacePuzzle::init() {
- Common::Rect vpBounds = NancySceneState.getViewport().getBounds();
- _drawSurface.create(vpBounds.width(), vpBounds.height(), g_nancy->_graphics->getInputPixelFormat());
- _drawSurface.clear(g_nancy->_graphics->getTransColor());
- setTransparent(true);
- setVisible(true);
- moveTo(vpBounds);
+ initViewportSurface();
_images.resize(_imageNames.size());
for (uint i = 0; i < _imageNames.size(); ++i) {
@@ -402,27 +397,6 @@ void NecklacePuzzle::refundBeads() {
_fallingStrand = -1;
}
-void NecklacePuzzle::playSoundBlock(const RandomSoundBlock &block) {
- if (block.names.empty()) {
- return;
- }
-
- uint idx = block.names.size() == 1 ? 0 : g_nancy->_randomSource->getRandomNumber(block.names.size() - 1);
- const Common::String &name = block.names[idx];
- if (name.empty() || name == "NO SOUND") {
- return;
- }
-
- SoundDescription desc;
- desc.name = name;
- desc.channelID = block.channel;
- desc.numLoops = block.numLoops > 0 ? block.numLoops : 1;
- desc.volume = block.volume;
-
- g_nancy->_sound->loadSound(desc);
- g_nancy->_sound->playSound(desc);
-}
-
void NecklacePuzzle::execute() {
switch (_state) {
case kBegin:
diff --git a/engines/nancy/action/puzzle/necklacepuzzle.h b/engines/nancy/action/puzzle/necklacepuzzle.h
index 09ed64d9ec5..0c0a139e7dd 100644
--- a/engines/nancy/action/puzzle/necklacepuzzle.h
+++ b/engines/nancy/action/puzzle/necklacepuzzle.h
@@ -120,7 +120,6 @@ protected:
void checkSolved();
void refundBeads();
- void playSoundBlock(const RandomSoundBlock &block);
void redraw();
void drawBeadCount(const Bead &bead);
diff --git a/engines/nancy/action/puzzle/overridelockpuzzle.cpp b/engines/nancy/action/puzzle/overridelockpuzzle.cpp
index f3d3cd57c94..86c2dff7778 100644
--- a/engines/nancy/action/puzzle/overridelockpuzzle.cpp
+++ b/engines/nancy/action/puzzle/overridelockpuzzle.cpp
@@ -36,14 +36,7 @@ namespace Nancy {
namespace Action {
void OverrideLockPuzzle::init() {
- Common::Rect bounds = NancySceneState.getViewport().getBounds();
-
- _drawSurface.create(bounds.width(), bounds.height(), g_nancy->_graphics->getInputPixelFormat());
- _drawSurface.clear(g_nancy->_graphics->getTransColor());
-
- setTransparent(true);
- setVisible(true);
- moveTo(bounds);
+ initViewportSurface();
g_nancy->_resource->loadImage(_imageName, _image);
_image.setTransparentColor(_drawSurface.getTransparentColor());
diff --git a/engines/nancy/action/puzzle/pachinkopuzzle.cpp b/engines/nancy/action/puzzle/pachinkopuzzle.cpp
index 876e4021013..4b880138791 100644
--- a/engines/nancy/action/puzzle/pachinkopuzzle.cpp
+++ b/engines/nancy/action/puzzle/pachinkopuzzle.cpp
@@ -225,12 +225,7 @@ Common::Point PachinkoPuzzle::climberAnchor(const Machine &m) const {
}
void PachinkoPuzzle::init() {
- Common::Rect vpBounds = NancySceneState.getViewport().getBounds();
- _drawSurface.create(vpBounds.width(), vpBounds.height(), g_nancy->_graphics->getInputPixelFormat());
- _drawSurface.clear(g_nancy->_graphics->getTransColor());
- setTransparent(true);
- setVisible(true);
- moveTo(vpBounds);
+ initViewportSurface();
g_nancy->_resource->loadImage(_imageName, _image);
_image.setTransparentColor(_drawSurface.getTransparentColor());
@@ -258,32 +253,6 @@ void PachinkoPuzzle::init() {
registerGraphics();
}
-SoundDescription PachinkoPuzzle::playSoundBlock(const RandomSoundBlock &block) {
- SoundDescription desc;
- if (block.names.empty()) {
- return desc;
- }
-
- uint idx = block.names.size() == 1 ? 0 : g_nancy->_randomSource->getRandomNumber(block.names.size() - 1);
- const Common::String &name = block.names[idx];
- if (name.empty() || name == "NO SOUND") {
- return desc;
- }
-
- desc.name = name;
- desc.channelID = block.channel;
- desc.numLoops = block.numLoops > 0 ? block.numLoops : 1;
- desc.volume = block.volume;
-
- g_nancy->_sound->loadSound(desc);
- g_nancy->_sound->playSound(desc);
- return desc;
-}
-
-void PachinkoPuzzle::setDataCursor(uint16 cursorType, bool hotspotVariant) const {
- g_nancy->_cursor->setCursorType((CursorManager::CursorType)cursorType, true, hotspotVariant);
-}
-
void PachinkoPuzzle::spawnBall() {
uint32 now = g_nancy->getTotalPlayTime();
uint32 elapsed = now - _spawnClickTime;
diff --git a/engines/nancy/action/puzzle/pachinkopuzzle.h b/engines/nancy/action/puzzle/pachinkopuzzle.h
index 1d3f8a5856b..b1752a3731a 100644
--- a/engines/nancy/action/puzzle/pachinkopuzzle.h
+++ b/engines/nancy/action/puzzle/pachinkopuzzle.h
@@ -108,9 +108,6 @@ protected:
bool collidePins(Ball &ball) const;
int catchInHole(const Ball &ball) const; // hole index the ball fell into, or -1
void advanceMachine(Machine &m, uint32 now);
- SoundDescription playSoundBlock(const RandomSoundBlock &block);
- // Zone cursors take the idle sprite of their type, hover/drag cursors the hotspot one.
- void setDataCursor(uint16 cursorType, bool hotspotVariant = true) const;
// -- File data --
Common::Path _imageName; // board overlay
diff --git a/engines/nancy/action/puzzle/paintpuzzle.cpp b/engines/nancy/action/puzzle/paintpuzzle.cpp
index ddf0434f674..fd3fecd47dd 100644
--- a/engines/nancy/action/puzzle/paintpuzzle.cpp
+++ b/engines/nancy/action/puzzle/paintpuzzle.cpp
@@ -360,31 +360,6 @@ void PaintPuzzle::paintRegion(uint regionIndex, int colorIndex) {
redraw();
}
-void PaintPuzzle::playSoundBlock(const RandomSoundBlock &block) {
- if (block.names.empty()) {
- return;
- }
-
- uint idx = block.names.size() == 1 ? 0 : g_nancy->_randomSource->getRandomNumber(block.names.size() - 1);
- const Common::String &name = block.names[idx];
- if (name.empty() || name == "NO SOUND") {
- return;
- }
-
- SoundDescription desc;
- desc.name = name;
- desc.channelID = block.channel;
- desc.numLoops = block.numLoops > 0 ? block.numLoops : 1;
- desc.volume = block.volume;
-
- g_nancy->_sound->loadSound(desc);
- g_nancy->_sound->playSound(desc);
-}
-
-bool PaintPuzzle::isSoundBlockPlaying(const RandomSoundBlock &block) const {
- return !block.names.empty() && g_nancy->_sound->isSoundPlaying((uint16)block.channel);
-}
-
void PaintPuzzle::handleInput(NancyInput &input) {
// A solve without a scene change leaves the puzzle playable
if (_state != kRun || (_solved && !_solveHandled)) {
diff --git a/engines/nancy/action/puzzle/paintpuzzle.h b/engines/nancy/action/puzzle/paintpuzzle.h
index 714d526eeb9..68d697e5cb6 100644
--- a/engines/nancy/action/puzzle/paintpuzzle.h
+++ b/engines/nancy/action/puzzle/paintpuzzle.h
@@ -93,8 +93,6 @@ protected:
void updateColorFlags();
void redraw();
bool isSolved() const;
- void playSoundBlock(const RandomSoundBlock &block);
- bool isSoundBlockPlaying(const RandomSoundBlock &block) const;
// -- File data --
Common::Path _imageName; // 0x3d
diff --git a/engines/nancy/action/puzzle/pegspuzzle.cpp b/engines/nancy/action/puzzle/pegspuzzle.cpp
index 5ce90fb4a27..b3f3b04701f 100644
--- a/engines/nancy/action/puzzle/pegspuzzle.cpp
+++ b/engines/nancy/action/puzzle/pegspuzzle.cpp
@@ -86,12 +86,7 @@ void PegsPuzzle::readData(Common::SeekableReadStream &stream) {
}
void PegsPuzzle::init() {
- Common::Rect vpBounds = NancySceneState.getViewport().getBounds();
- _drawSurface.create(vpBounds.width(), vpBounds.height(), g_nancy->_graphics->getInputPixelFormat());
- _drawSurface.clear(g_nancy->_graphics->getTransColor());
- setTransparent(true);
- setVisible(true);
- moveTo(vpBounds);
+ initViewportSurface();
g_nancy->_resource->loadImage(_imageName, _image);
_image.setTransparentColor(_drawSurface.getTransparentColor());
@@ -250,12 +245,6 @@ void PegsPuzzle::carryPeg(int col, int row, NancyInput &input) {
}
}
-void PegsPuzzle::setDataCursor(uint16 cursorType, bool hotspotVariant) const {
- // The ids in the AR data are raw Nancy13 cursor types, which is exactly what the
- // "set from script" path expects.
- g_nancy->_cursor->setCursorType((CursorManager::CursorType)cursorType, true, hotspotVariant);
-}
-
void PegsPuzzle::redraw() {
_drawSurface.clear(g_nancy->_graphics->getTransColor());
@@ -281,28 +270,6 @@ void PegsPuzzle::redraw() {
_needsRedraw = true;
}
-SoundDescription PegsPuzzle::playSoundBlock(const RandomSoundBlock &block) {
- SoundDescription desc;
- if (block.names.empty()) {
- return desc;
- }
-
- uint idx = block.names.size() == 1 ? 0 : g_nancy->_randomSource->getRandomNumber(block.names.size() - 1);
- const Common::String &name = block.names[idx];
- if (name.empty() || name == "NO SOUND") {
- return desc;
- }
-
- desc.name = name;
- desc.channelID = block.channel;
- desc.numLoops = block.numLoops > 0 ? block.numLoops : 1;
- desc.volume = block.volume;
-
- g_nancy->_sound->loadSound(desc);
- g_nancy->_sound->playSound(desc);
- return desc;
-}
-
void PegsPuzzle::execute() {
switch (_state) {
case kBegin:
diff --git a/engines/nancy/action/puzzle/pegspuzzle.h b/engines/nancy/action/puzzle/pegspuzzle.h
index 4ec57bfb075..339caf5edb0 100644
--- a/engines/nancy/action/puzzle/pegspuzzle.h
+++ b/engines/nancy/action/puzzle/pegspuzzle.h
@@ -72,12 +72,8 @@ protected:
void doJump(int fromCol, int fromRow, int destCol, int destRow);
void carryPeg(int col, int row, NancyInput &input);
- // The puzzle's cursors are raw Nancy13 cursor type ids stored in the AR data.
- // Zone cursors take the idle sprite of their type, hover/drag cursors the hotspot one.
- void setDataCursor(uint16 cursorType, bool hotspotVariant = true) const;
void redraw();
- SoundDescription playSoundBlock(const RandomSoundBlock &block);
// -- File data (96-byte header) --
Common::Path _imageName; // 0x00
diff --git a/engines/nancy/action/puzzle/quizpuzzle.cpp b/engines/nancy/action/puzzle/quizpuzzle.cpp
index 1e690e71d80..7744a84a6a6 100644
--- a/engines/nancy/action/puzzle/quizpuzzle.cpp
+++ b/engines/nancy/action/puzzle/quizpuzzle.cpp
@@ -348,7 +348,7 @@ bool QuizPuzzle::fitsInBox(const Box &box, const Common::String &text) const {
return font->getStringWidth(text) < box.rect.width() - kBoxTextMargin;
}
-bool QuizPuzzle::playSoundBlock(const RandomSoundBlock &block) {
+bool QuizPuzzle::playBoxSoundBlock(const RandomSoundBlock &block) {
if (block.names.empty()) {
return false;
}
@@ -571,7 +571,7 @@ void QuizPuzzle::executeNancy9() {
} else if (_pendingChar != 0) {
if (!acceptsChar(_pendingChar)) {
// Nancy 15 buzzes at characters the record does not allow
- playSoundBlock(_invalidKeySound);
+ playBoxSoundBlock(_invalidKeySound);
} else if (text.size() < getMaxTypedLength() &&
(isNancy15 || fitsInBox(box, text))) {
text += _pendingChar;
@@ -623,7 +623,7 @@ void QuizPuzzle::executeNancy9() {
}
case kStartCorrect: {
- bool playing = playSoundBlock(box.correctSound);
+ bool playing = playBoxSoundBlock(box.correctSound);
if (playing) {
showBoxSubtitle(box.correctText, _recordCorrectText);
}
@@ -662,7 +662,7 @@ void QuizPuzzle::executeNancy9() {
}
drawText();
- bool playing = playSoundBlock(box.wrongSound);
+ bool playing = playBoxSoundBlock(box.wrongSound);
if (playing) {
showBoxSubtitle(box.wrongText, _recordWrongText);
}
@@ -690,7 +690,7 @@ void QuizPuzzle::executeNancy9() {
case kStartDone: {
if (isNancy15) {
- _internalState = playSoundBlock(_doneSoundBlock) ? kWaitDone : kFinish;
+ _internalState = playBoxSoundBlock(_doneSoundBlock) ? kWaitDone : kFinish;
} else if (!hasSolveSound()) {
_internalState = kFinish;
} else {
diff --git a/engines/nancy/action/puzzle/quizpuzzle.h b/engines/nancy/action/puzzle/quizpuzzle.h
index 389bb526d7f..8005a82b11b 100644
--- a/engines/nancy/action/puzzle/quizpuzzle.h
+++ b/engines/nancy/action/puzzle/quizpuzzle.h
@@ -103,7 +103,7 @@ private:
// Picks one name out of `block` at random and starts it, tracking it in
// _activeBoxSound so the state machine can wait for it. Returns false when
// the block is empty or names no sound.
- bool playSoundBlock(const RandomSoundBlock &block);
+ bool playBoxSoundBlock(const RandomSoundBlock &block);
void showBoxSubtitle(const Common::String &perBoxText, const Common::String &perRecordText);
uint32 getSaveKey();
diff --git a/engines/nancy/action/puzzle/rippedletterpuzzle.cpp b/engines/nancy/action/puzzle/rippedletterpuzzle.cpp
index 653c3bf5679..66047f42529 100644
--- a/engines/nancy/action/puzzle/rippedletterpuzzle.cpp
+++ b/engines/nancy/action/puzzle/rippedletterpuzzle.cpp
@@ -37,12 +37,7 @@ namespace Nancy {
namespace Action {
void RippedLetterPuzzle::init() {
- Common::Rect screenBounds = NancySceneState.getViewport().getBounds();
- _drawSurface.create(screenBounds.width(), screenBounds.height(), g_nancy->_graphics->getInputPixelFormat());
- _drawSurface.clear(g_nancy->_graphics->getTransColor());
- setTransparent(true);
- setVisible(true);
- moveTo(screenBounds);
+ initViewportSurface();
g_nancy->_resource->loadImage(_imageName, _image);
diff --git a/engines/nancy/action/puzzle/safedialpuzzle.cpp b/engines/nancy/action/puzzle/safedialpuzzle.cpp
index afc8bfba946..cf54b4a9b9c 100644
--- a/engines/nancy/action/puzzle/safedialpuzzle.cpp
+++ b/engines/nancy/action/puzzle/safedialpuzzle.cpp
@@ -40,12 +40,7 @@ void SafeDialPuzzle::init() {
g_nancy->_resource->loadImage(_imageName2, _image2);
g_nancy->_resource->loadImage(_resetImageName, _resetImage);
- Common::Rect screenBounds = NancySceneState.getViewport().getBounds();
- _drawSurface.create(screenBounds.width(), screenBounds.height(), g_nancy->_graphics->getInputPixelFormat());
- _drawSurface.clear(g_nancy->_graphics->getTransColor());
- setTransparent(true);
- setVisible(true);
- moveTo(screenBounds);
+ initViewportSurface();
registerGraphics();
}
diff --git a/engines/nancy/action/puzzle/scalepuzzle.cpp b/engines/nancy/action/puzzle/scalepuzzle.cpp
index 7066ea3a2d1..14049ead3a6 100644
--- a/engines/nancy/action/puzzle/scalepuzzle.cpp
+++ b/engines/nancy/action/puzzle/scalepuzzle.cpp
@@ -108,12 +108,7 @@ void ScalePuzzle::readData(Common::SeekableReadStream &stream) {
}
void ScalePuzzle::init() {
- Common::Rect vpBounds = NancySceneState.getViewport().getBounds();
- _drawSurface.create(vpBounds.width(), vpBounds.height(), g_nancy->_graphics->getInputPixelFormat());
- _drawSurface.clear(g_nancy->_graphics->getTransColor());
- setTransparent(true);
- setVisible(true);
- moveTo(vpBounds);
+ initViewportSurface();
g_nancy->_resource->loadImage(_imageName, _image);
_image.setTransparentColor(_drawSurface.getTransparentColor());
@@ -310,33 +305,6 @@ void ScalePuzzle::redraw() {
_needsRedraw = true;
}
-void ScalePuzzle::setDataCursor(uint16 cursorType, bool hotspotVariant) const {
- // The ids in the AR data are raw Nancy13 cursor types, which is exactly what the
- // "set from script" path expects.
- g_nancy->_cursor->setCursorType((CursorManager::CursorType)cursorType, true, hotspotVariant);
-}
-
-void ScalePuzzle::playSoundBlock(const RandomSoundBlock &block) {
- if (block.names.empty()) {
- return;
- }
-
- uint idx = block.names.size() == 1 ? 0 : g_nancy->_randomSource->getRandomNumber(block.names.size() - 1);
- const Common::String &name = block.names[idx];
- if (name.empty() || name == "NO SOUND") {
- return;
- }
-
- SoundDescription desc;
- desc.name = name;
- desc.channelID = block.channel;
- desc.numLoops = block.numLoops > 0 ? block.numLoops : 1;
- desc.volume = block.volume;
-
- g_nancy->_sound->loadSound(desc);
- g_nancy->_sound->playSound(desc);
-}
-
void ScalePuzzle::execute() {
switch (_state) {
case kBegin:
diff --git a/engines/nancy/action/puzzle/scalepuzzle.h b/engines/nancy/action/puzzle/scalepuzzle.h
index e8a8a6e4e55..33677bcb235 100644
--- a/engines/nancy/action/puzzle/scalepuzzle.h
+++ b/engines/nancy/action/puzzle/scalepuzzle.h
@@ -98,9 +98,6 @@ protected:
// slots, FUN_004b6660 case 0).
void blitCentered(const Common::Rect &src, const Common::Rect &slot);
void redraw();
- // Zone cursors take the idle sprite of their type, hover/drag cursors the hotspot one.
- void setDataCursor(uint16 cursorType, bool hotspotVariant = true) const;
- void playSoundBlock(const RandomSoundBlock &block);
// -- File data --
Common::Path _imageName; // 0x00
diff --git a/engines/nancy/action/puzzle/setplayerclock.cpp b/engines/nancy/action/puzzle/setplayerclock.cpp
index 1533632305f..072e3aca487 100644
--- a/engines/nancy/action/puzzle/setplayerclock.cpp
+++ b/engines/nancy/action/puzzle/setplayerclock.cpp
@@ -41,12 +41,7 @@ SetPlayerClock::~SetPlayerClock() {
}
void SetPlayerClock::init() {
- Common::Rect screenBounds = NancySceneState.getViewport().getBounds();
- _drawSurface.create(screenBounds.width(), screenBounds.height(), g_nancy->_graphics->getInputPixelFormat());
- _drawSurface.clear(g_nancy->_graphics->getTransColor());
- setTransparent(true);
- setVisible(true);
- moveTo(screenBounds);
+ initViewportSurface();
g_nancy->_resource->loadImage(_imageName, _image);
_image.setTransparentColor(_drawSurface.getTransparentColor());
diff --git a/engines/nancy/action/puzzle/sewingmachinepuzzle.cpp b/engines/nancy/action/puzzle/sewingmachinepuzzle.cpp
index b348c02b413..00da2a7b399 100644
--- a/engines/nancy/action/puzzle/sewingmachinepuzzle.cpp
+++ b/engines/nancy/action/puzzle/sewingmachinepuzzle.cpp
@@ -81,34 +81,6 @@ void SewingMachinePuzzle::classifyZones() {
}
}
-void SewingMachinePuzzle::playSoundBlock(const RandomSoundBlock &block) {
- if (block.names.empty()) {
- return;
- }
-
- uint idx = block.names.size() == 1 ? 0 : g_nancy->_randomSource->getRandomNumber(block.names.size() - 1);
- const Common::String &name = block.names[idx];
- if (name.empty() || name == "NO SOUND") {
- return;
- }
-
- SoundDescription desc;
- desc.name = name;
- desc.channelID = block.channel;
- desc.numLoops = block.numLoops > 0 ? block.numLoops : 1;
- desc.volume = block.volume;
-
- g_nancy->_sound->loadSound(desc);
- g_nancy->_sound->playSound(desc);
-
- // The mistake lines carry no inline caption; look the subtitle up by sound name,
- // first in the Autotext table, then in the conversation table.
- Common::String text = resolveSubtitleText(name);
- if (text.empty())
- text = resolveSubtitleText(name, Common::String(), "CONVO");
- showSubtitle(text);
-}
-
Common::Point SewingMachinePuzzle::needleInStrip() const {
// The needle is fixed on screen; map it back into cloth space.
return _needleScreen - _offset;
diff --git a/engines/nancy/action/puzzle/sewingmachinepuzzle.h b/engines/nancy/action/puzzle/sewingmachinepuzzle.h
index 00485f6e872..9a8f53ebed7 100644
--- a/engines/nancy/action/puzzle/sewingmachinepuzzle.h
+++ b/engines/nancy/action/puzzle/sewingmachinepuzzle.h
@@ -54,8 +54,6 @@ protected:
// Sorts the ActionZone array into its gameplay roles.
void classifyZones();
- // Plays one entry of a random-sound block (needle/stitch cues).
- void playSoundBlock(const RandomSoundBlock &block);
// Draws the visible part of the cloth strip plus the stitches sewn so far.
void drawCloth();
diff --git a/engines/nancy/action/puzzle/soundequalizerpuzzle.cpp b/engines/nancy/action/puzzle/soundequalizerpuzzle.cpp
index ac6559968c0..a50c8329a74 100644
--- a/engines/nancy/action/puzzle/soundequalizerpuzzle.cpp
+++ b/engines/nancy/action/puzzle/soundequalizerpuzzle.cpp
@@ -61,12 +61,7 @@ SoundEqualizerPuzzle::~SoundEqualizerPuzzle() {
}
void SoundEqualizerPuzzle::init() {
- Common::Rect screenBounds = NancySceneState.getViewport().getBounds();
- _drawSurface.create(screenBounds.width(), screenBounds.height(), g_nancy->_graphics->getInputPixelFormat());
- _drawSurface.clear(g_nancy->_graphics->getTransColor());
- setTransparent(true);
- setVisible(true);
- moveTo(screenBounds);
+ initViewportSurface();
g_nancy->_resource->loadImage(_imageName, _image);
_image.setTransparentColor(_drawSurface.getTransparentColor());
diff --git a/engines/nancy/action/puzzle/spigotpuzzle.cpp b/engines/nancy/action/puzzle/spigotpuzzle.cpp
index d6263281c2a..0c147446d9d 100644
--- a/engines/nancy/action/puzzle/spigotpuzzle.cpp
+++ b/engines/nancy/action/puzzle/spigotpuzzle.cpp
@@ -34,12 +34,7 @@ namespace Nancy {
namespace Action {
void SpigotPuzzle::init() {
- Common::Rect screenBounds = NancySceneState.getViewport().getBounds();
- _drawSurface.create(screenBounds.width(), screenBounds.height(), g_nancy->_graphics->getInputPixelFormat());
- _drawSurface.clear(g_nancy->_graphics->getTransColor());
- setTransparent(true);
- setVisible(true);
- moveTo(screenBounds);
+ initViewportSurface();
g_nancy->_resource->loadImage(_imageName, _image);
registerGraphics();
diff --git a/engines/nancy/action/puzzle/stepobjectspuzzle.cpp b/engines/nancy/action/puzzle/stepobjectspuzzle.cpp
index 97c3352955d..b82a191b452 100644
--- a/engines/nancy/action/puzzle/stepobjectspuzzle.cpp
+++ b/engines/nancy/action/puzzle/stepobjectspuzzle.cpp
@@ -317,34 +317,6 @@ void StepObjectsPuzzle::redraw() {
_needsRedraw = true;
}
-void StepObjectsPuzzle::setDataCursor(uint16 cursorType, bool hotspotVariant) const {
- // The ids in the AR data are raw Nancy13 cursor types, which is exactly what the
- // "set from script" path expects.
- g_nancy->_cursor->setCursorType((CursorManager::CursorType)cursorType, true, hotspotVariant);
-}
-
-SoundDescription StepObjectsPuzzle::playSoundBlock(const RandomSoundBlock &block) {
- SoundDescription desc;
- if (block.names.empty()) {
- return desc;
- }
-
- uint idx = block.names.size() == 1 ? 0 : g_nancy->_randomSource->getRandomNumber(block.names.size() - 1);
- const Common::String &name = block.names[idx];
- if (name.empty() || name == "NO SOUND") {
- return desc;
- }
-
- desc.name = name;
- desc.channelID = block.channel;
- desc.numLoops = block.numLoops > 0 ? block.numLoops : 1;
- desc.volume = block.volume;
-
- g_nancy->_sound->loadSound(desc);
- g_nancy->_sound->playSound(desc);
- return desc;
-}
-
void StepObjectsPuzzle::execute() {
switch (_state) {
case kBegin:
diff --git a/engines/nancy/action/puzzle/stepobjectspuzzle.h b/engines/nancy/action/puzzle/stepobjectspuzzle.h
index cb2ae9cab40..69ec66d01cc 100644
--- a/engines/nancy/action/puzzle/stepobjectspuzzle.h
+++ b/engines/nancy/action/puzzle/stepobjectspuzzle.h
@@ -96,13 +96,10 @@ protected:
void drop(int row, int col);
void resetBoard();
void beginStepSound(SoundID sound, bool isDrop);
- // Zone cursors take the idle sprite of their type, hover/drag cursors the hotspot one.
- void setDataCursor(uint16 cursorType, bool hotspotVariant = true) const;
void redraw();
void putDownCarried();
void drawSprite(Graphics::ManagedSurface &dest, const Common::Rect &srcRect, const Common::Point &destPos, byte alpha);
- SoundDescription playSoundBlock(const RandomSoundBlock &block);
// File data
Common::Path _imageName;
diff --git a/engines/nancy/action/puzzle/tangrampuzzle.cpp b/engines/nancy/action/puzzle/tangrampuzzle.cpp
index bfe1669f550..db72ae85c06 100644
--- a/engines/nancy/action/puzzle/tangrampuzzle.cpp
+++ b/engines/nancy/action/puzzle/tangrampuzzle.cpp
@@ -38,12 +38,7 @@ TangramPuzzle::~TangramPuzzle() {
}
void TangramPuzzle::init() {
- Common::Rect screenBounds = NancySceneState.getViewport().getBounds();
- _drawSurface.create(screenBounds.width(), screenBounds.height(), g_nancy->_graphics->getInputPixelFormat());
- _drawSurface.clear(g_nancy->_graphics->getTransColor());
- setTransparent(true);
- setVisible(true);
- moveTo(screenBounds);
+ initViewportSurface();
g_nancy->_resource->loadImage(_tileImageName, _tileImage);
g_nancy->_resource->loadImage(_maskImageName, _maskImage);
diff --git a/engines/nancy/action/puzzle/telephone.cpp b/engines/nancy/action/puzzle/telephone.cpp
index 36403f0cca8..b81534697d0 100644
--- a/engines/nancy/action/puzzle/telephone.cpp
+++ b/engines/nancy/action/puzzle/telephone.cpp
@@ -35,12 +35,7 @@ namespace Nancy {
namespace Action {
void Telephone::init() {
- Common::Rect screenBounds = NancySceneState.getViewport().getBounds();
- _drawSurface.create(screenBounds.width(), screenBounds.height(), g_nancy->_graphics->getInputPixelFormat());
- _drawSurface.clear(g_nancy->_graphics->getTransColor());
- setTransparent(true);
- setVisible(true);
- moveTo(screenBounds);
+ initViewportSurface();
g_nancy->_resource->loadImage(_imageName, _image);
g_nancy->_resource->loadImage(_displayAnimName, _animImage);
diff --git a/engines/nancy/action/puzzle/towerpuzzle.cpp b/engines/nancy/action/puzzle/towerpuzzle.cpp
index 66146c59b0a..30a43ebded7 100644
--- a/engines/nancy/action/puzzle/towerpuzzle.cpp
+++ b/engines/nancy/action/puzzle/towerpuzzle.cpp
@@ -34,12 +34,7 @@ namespace Nancy {
namespace Action {
void TowerPuzzle::init() {
- Common::Rect screenBounds = NancySceneState.getViewport().getBounds();
- _drawSurface.create(screenBounds.width(), screenBounds.height(), g_nancy->_graphics->getInputPixelFormat());
- _drawSurface.clear(g_nancy->_graphics->getTransColor());
- setTransparent(true);
- setVisible(true);
- moveTo(screenBounds);
+ initViewportSurface();
g_nancy->_resource->loadImage(_imageName, _image);
_image.setTransparentColor(_drawSurface.getTransparentColor());
diff --git a/engines/nancy/action/puzzle/turningpuzzle.cpp b/engines/nancy/action/puzzle/turningpuzzle.cpp
index 80c8cab59f5..6804ba7807b 100644
--- a/engines/nancy/action/puzzle/turningpuzzle.cpp
+++ b/engines/nancy/action/puzzle/turningpuzzle.cpp
@@ -37,12 +37,7 @@ namespace Nancy {
namespace Action {
void TurningPuzzle::init() {
- Common::Rect screenBounds = NancySceneState.getViewport().getBounds();
- _drawSurface.create(screenBounds.width(), screenBounds.height(), g_nancy->_graphics->getInputPixelFormat());
- _drawSurface.clear(g_nancy->_graphics->getTransColor());
- setTransparent(true);
- setVisible(true);
- moveTo(screenBounds);
+ initViewportSurface();
g_nancy->_resource->loadImage(_imageName, _image);
@@ -337,28 +332,6 @@ void TurningPuzzle::drawAllObjects() {
}
}
-SoundDescription TurningPuzzle::playSoundBlock(const RandomSoundBlock &block) {
- SoundDescription desc;
- if (block.names.empty()) {
- return desc;
- }
-
- uint idx = block.names.size() == 1 ? 0 : g_nancy->_randomSource->getRandomNumber(block.names.size() - 1);
- const Common::String &name = block.names[idx];
- if (name.empty() || name == "NO SOUND") {
- return desc;
- }
-
- desc.name = name;
- desc.channelID = block.channel;
- desc.numLoops = block.numLoops > 0 ? block.numLoops : 1;
- desc.volume = block.volume;
-
- g_nancy->_sound->loadSound(desc);
- g_nancy->_sound->playSound(desc);
- return desc;
-}
-
void TurningPuzzle::readData(Common::SeekableReadStream &stream) {
if (g_nancy->getGameType() >= kGameTypeNancy13) {
readDataNancy13(stream);
diff --git a/engines/nancy/action/puzzle/turningpuzzle.h b/engines/nancy/action/puzzle/turningpuzzle.h
index f44741cbf18..92683d85082 100644
--- a/engines/nancy/action/puzzle/turningpuzzle.h
+++ b/engines/nancy/action/puzzle/turningpuzzle.h
@@ -76,7 +76,6 @@ protected:
uint numFacesOf(uint objectID) const;
uint framesPerTurnOf(uint objectID) const;
void drawAllObjects();
- SoundDescription playSoundBlock(const RandomSoundBlock &block);
void drawObject(uint objectID, uint faceID, uint frameID);
void turnLogic(uint objectID);
diff --git a/engines/nancy/action/puzzle/twodialpuzzle.cpp b/engines/nancy/action/puzzle/twodialpuzzle.cpp
index 3f5157d0a10..1064b6d144a 100644
--- a/engines/nancy/action/puzzle/twodialpuzzle.cpp
+++ b/engines/nancy/action/puzzle/twodialpuzzle.cpp
@@ -34,12 +34,7 @@ namespace Nancy {
namespace Action {
void TwoDialPuzzle::init() {
- Common::Rect screenBounds = NancySceneState.getViewport().getBounds();
- _drawSurface.create(screenBounds.width(), screenBounds.height(), g_nancy->_graphics->getInputPixelFormat());
- _drawSurface.clear(g_nancy->_graphics->getTransColor());
- setTransparent(true);
- setVisible(true);
- moveTo(screenBounds);
+ initViewportSurface();
g_nancy->_resource->loadImage(_imageName, _image);
registerGraphics();
diff --git a/engines/nancy/action/puzzle/weightsortpuzzle.cpp b/engines/nancy/action/puzzle/weightsortpuzzle.cpp
index a918fbadeef..79bd222deb1 100644
--- a/engines/nancy/action/puzzle/weightsortpuzzle.cpp
+++ b/engines/nancy/action/puzzle/weightsortpuzzle.cpp
@@ -155,12 +155,7 @@ void WeightSortPuzzle::scatterContainer(uint container) {
}
void WeightSortPuzzle::init() {
- Common::Rect vpBounds = NancySceneState.getViewport().getBounds();
- _drawSurface.create(vpBounds.width(), vpBounds.height(), g_nancy->_graphics->getInputPixelFormat());
- _drawSurface.clear(g_nancy->_graphics->getTransColor());
- setTransparent(true);
- setVisible(true);
- moveTo(vpBounds);
+ initViewportSurface();
_typeImages.resize(_objectTypes.size());
for (uint i = 0; i < _objectTypes.size(); ++i) {
@@ -362,32 +357,6 @@ void WeightSortPuzzle::carryObject(int object, NancyInput &input) {
}
}
-void WeightSortPuzzle::setDataCursor(uint16 cursorType, bool hotspotVariant) const {
- g_nancy->_cursor->setCursorType((CursorManager::CursorType)cursorType, true, hotspotVariant);
-}
-
-SoundDescription WeightSortPuzzle::playSoundBlock(const RandomSoundBlock &block) {
- SoundDescription desc;
- if (block.names.empty()) {
- return desc;
- }
-
- uint idx = block.names.size() == 1 ? 0 : g_nancy->_randomSource->getRandomNumber(block.names.size() - 1);
- const Common::String &name = block.names[idx];
- if (name.empty() || name == "NO SOUND") {
- return desc;
- }
-
- desc.name = name;
- desc.channelID = block.channel;
- desc.numLoops = block.numLoops > 0 ? block.numLoops : 1;
- desc.volume = block.volume;
-
- g_nancy->_sound->loadSound(desc);
- g_nancy->_sound->playSound(desc);
- return desc;
-}
-
void WeightSortPuzzle::redraw() {
_drawSurface.clear(g_nancy->_graphics->getTransColor());
diff --git a/engines/nancy/action/puzzle/weightsortpuzzle.h b/engines/nancy/action/puzzle/weightsortpuzzle.h
index 0f3d16c14dd..163856edd54 100644
--- a/engines/nancy/action/puzzle/weightsortpuzzle.h
+++ b/engines/nancy/action/puzzle/weightsortpuzzle.h
@@ -123,8 +123,6 @@ protected:
int reachedOutcome() const;
void carryObject(int object, NancyInput &input);
- void setDataCursor(uint16 cursorType, bool hotspotVariant = true) const;
- SoundDescription playSoundBlock(const RandomSoundBlock &block);
void redraw();
// -- File data --
diff --git a/engines/nancy/action/puzzle/wordfindpuzzle.cpp b/engines/nancy/action/puzzle/wordfindpuzzle.cpp
index dc352c68a39..38e82c03e97 100644
--- a/engines/nancy/action/puzzle/wordfindpuzzle.cpp
+++ b/engines/nancy/action/puzzle/wordfindpuzzle.cpp
@@ -176,12 +176,7 @@ void WordFindPuzzle::loadWord() {
}
void WordFindPuzzle::init() {
- Common::Rect vpBounds = NancySceneState.getViewport().getBounds();
- _drawSurface.create(vpBounds.width(), vpBounds.height(), g_nancy->_graphics->getInputPixelFormat());
- _drawSurface.clear(g_nancy->_graphics->getTransColor());
- setTransparent(true);
- setVisible(true);
- moveTo(vpBounds);
+ initViewportSurface();
// The active word carries over from earlier visits to this puzzle.
WordFindPuzzleData *data = getPuzzleData();
diff --git a/engines/nancy/action/puzzlerecord.cpp b/engines/nancy/action/puzzlerecord.cpp
index 6688c3652fd..9a6bb738997 100644
--- a/engines/nancy/action/puzzlerecord.cpp
+++ b/engines/nancy/action/puzzlerecord.cpp
@@ -19,8 +19,11 @@
*
*/
+#include "common/random.h"
+
#include "engines/nancy/nancy.h"
#include "engines/nancy/cursor.h"
+#include "engines/nancy/graphics.h"
#include "engines/nancy/input.h"
#include "engines/nancy/sound.h"
#include "engines/nancy/util.h"
@@ -57,6 +60,52 @@ Common::String PuzzleRecord::getRecordExtraInfo() const {
return info;
}
+void PuzzleRecord::initViewportSurface() {
+ Common::Rect vpBounds = NancySceneState.getViewport().getBounds();
+ _drawSurface.create(vpBounds.width(), vpBounds.height(), g_nancy->_graphics->getInputPixelFormat());
+ _drawSurface.clear(g_nancy->_graphics->getTransColor());
+ setTransparent(true);
+ setVisible(true);
+ moveTo(vpBounds);
+}
+
+void PuzzleRecord::setDataCursor(uint16 cursorType, bool hotspotVariant) const {
+ g_nancy->_cursor->setCursorType((CursorManager::CursorType)cursorType, true, hotspotVariant);
+}
+
+SoundDescription PuzzleRecord::playSoundBlock(const RandomSoundBlock &block) {
+ SoundDescription desc;
+ if (block.names.empty()) {
+ return desc;
+ }
+
+ uint idx = block.names.size() == 1 ? 0 : g_nancy->_randomSource->getRandomNumber(block.names.size() - 1);
+ const Common::String &name = block.names[idx];
+ if (name.empty() || name == "NO SOUND") {
+ return desc;
+ }
+
+ desc.name = name;
+ desc.channelID = block.channel;
+ desc.numLoops = block.numLoops > 0 ? block.numLoops : 1;
+ desc.volume = block.volume;
+
+ g_nancy->_sound->loadSound(desc);
+ g_nancy->_sound->playSound(desc);
+
+ Common::String caption = resolveSubtitleText(name);
+ if (caption.empty()) {
+ caption = resolveSubtitleText(name, Common::String(), "CONVO");
+ }
+ showSubtitle(caption);
+
+ return desc;
+}
+
+bool PuzzleRecord::isSoundBlockPlaying(const RandomSoundBlock &block) const {
+ return !block.names.empty() && g_nancy->_sound->isSoundPlaying((uint16)block.channel);
+}
+
void PuzzleRecord::readExitHotspot(Common::SeekableReadStream &stream) {
Nancy::readExitHotspot(stream, _exitHotspot, _exitCursorType, _exitScene._sceneChange, _exitScene._flag);
_exitCursorFromData = true;
@@ -70,8 +119,7 @@ bool PuzzleRecord::isExitHotspotHovered(const NancyInput &input) const {
void PuzzleRecord::setExitCursor() const {
if (_exitCursorFromData) {
// Zone cursors use the idle sprite in Nancy13, and the hotspot sprite from Nancy14 on
- g_nancy->_cursor->setCursorType((CursorManager::CursorType)_exitCursorType, true,
- g_nancy->getGameType() >= kGameTypeNancy14);
+ setDataCursor(_exitCursorType, g_nancy->getGameType() >= kGameTypeNancy14);
} else {
g_nancy->_cursor->setCursorType(g_nancy->_cursor->_puzzleExitCursor);
}
diff --git a/engines/nancy/action/puzzlerecord.h b/engines/nancy/action/puzzlerecord.h
index 34795d624e7..b678e9ef85a 100644
--- a/engines/nancy/action/puzzlerecord.h
+++ b/engines/nancy/action/puzzlerecord.h
@@ -38,6 +38,18 @@ public:
Common::String getRecordExtraInfo() const override;
protected:
+ // Creates a transparent, viewport-sized draw surface and shows it over the viewport
+ void initViewportSurface();
+
+ // The ids in the AR data are raw cursor types, which is what the "set from script" path expects
+ void setDataCursor(uint16 cursorType, bool hotspotVariant = true) const;
+
+ // Plays a random sound from the block and shows its caption, looked up by the sound's
+ // name, first in AUTOTEXT, then in CONVO. Returns the sound's description, which is
+ // left as "NO SOUND" when the block has nothing to play.
+ SoundDescription playSoundBlock(const RandomSoundBlock &block);
+ bool isSoundBlockPlaying(const RandomSoundBlock &block) const;
+
// Reads the Nancy 13+ count-prefixed give-up hotspot array into the exit fields,
// keeping only the first record.
void readExitHotspot(Common::SeekableReadStream &stream);
Commit: 32ad0fc8affd2227c9eaca43002fb1e71d3f7029
https://github.com/scummvm/scummvm/commit/32ad0fc8affd2227c9eaca43002fb1e71d3f7029
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2026-09-26T04:54:37+03:00
Commit Message:
NANCY: Centralize puzzle background image names and surfaces
Changed paths:
engines/nancy/action/puzzle/adjustpuzzle.cpp
engines/nancy/action/puzzle/adjustpuzzle.h
engines/nancy/action/puzzle/angletosspuzzle.cpp
engines/nancy/action/puzzle/angletosspuzzle.h
engines/nancy/action/puzzle/arcadepuzzle.cpp
engines/nancy/action/puzzle/arcadepuzzle.h
engines/nancy/action/puzzle/assemblypuzzle.cpp
engines/nancy/action/puzzle/assemblypuzzle.h
engines/nancy/action/puzzle/bballpuzzle.cpp
engines/nancy/action/puzzle/bballpuzzle.h
engines/nancy/action/puzzle/beadpuzzle.cpp
engines/nancy/action/puzzle/beadpuzzle.h
engines/nancy/action/puzzle/blockingpuzzle.h
engines/nancy/action/puzzle/blockspuzzle.cpp
engines/nancy/action/puzzle/blockspuzzle.h
engines/nancy/action/puzzle/boardgamepuzzle.cpp
engines/nancy/action/puzzle/boardgamepuzzle.h
engines/nancy/action/puzzle/bombpuzzle.h
engines/nancy/action/puzzle/buildpuzzle.h
engines/nancy/action/puzzle/bulpuzzle.cpp
engines/nancy/action/puzzle/bulpuzzle.h
engines/nancy/action/puzzle/cardgamepuzzle.cpp
engines/nancy/action/puzzle/cardgamepuzzle.h
engines/nancy/action/puzzle/collisionpuzzle.cpp
engines/nancy/action/puzzle/collisionpuzzle.h
engines/nancy/action/puzzle/cubepuzzle.cpp
engines/nancy/action/puzzle/cubepuzzle.h
engines/nancy/action/puzzle/dotconnectpuzzle.cpp
engines/nancy/action/puzzle/dotconnectpuzzle.h
engines/nancy/action/puzzle/drivingpuzzle.h
engines/nancy/action/puzzle/dropsortpuzzle.cpp
engines/nancy/action/puzzle/dropsortpuzzle.h
engines/nancy/action/puzzle/hamradiopuzzle.cpp
engines/nancy/action/puzzle/hamradiopuzzle.h
engines/nancy/action/puzzle/leverpuzzle.h
engines/nancy/action/puzzle/matchpuzzle.h
engines/nancy/action/puzzle/mazechasepuzzle.cpp
engines/nancy/action/puzzle/mazechasepuzzle.h
engines/nancy/action/puzzle/memorypuzzle.cpp
engines/nancy/action/puzzle/memorypuzzle.h
engines/nancy/action/puzzle/mindpuzzle.cpp
engines/nancy/action/puzzle/mindpuzzle.h
engines/nancy/action/puzzle/minigolfpuzzle.h
engines/nancy/action/puzzle/mirrorlightpuzzle.cpp
engines/nancy/action/puzzle/mirrorlightpuzzle.h
engines/nancy/action/puzzle/mouselightpuzzle.h
engines/nancy/action/puzzle/onebuildpuzzle.cpp
engines/nancy/action/puzzle/onebuildpuzzle.h
engines/nancy/action/puzzle/orderingpuzzle.h
engines/nancy/action/puzzle/overridelockpuzzle.cpp
engines/nancy/action/puzzle/overridelockpuzzle.h
engines/nancy/action/puzzle/pachinkopuzzle.cpp
engines/nancy/action/puzzle/pachinkopuzzle.h
engines/nancy/action/puzzle/paintpuzzle.h
engines/nancy/action/puzzle/pegspuzzle.cpp
engines/nancy/action/puzzle/pegspuzzle.h
engines/nancy/action/puzzle/rippedletterpuzzle.h
engines/nancy/action/puzzle/rotatinglockpuzzle.h
engines/nancy/action/puzzle/scalepuzzle.cpp
engines/nancy/action/puzzle/scalepuzzle.h
engines/nancy/action/puzzle/setplayerclock.cpp
engines/nancy/action/puzzle/setplayerclock.h
engines/nancy/action/puzzle/sewingmachinepuzzle.cpp
engines/nancy/action/puzzle/sewingmachinepuzzle.h
engines/nancy/action/puzzle/sliderpuzzle.h
engines/nancy/action/puzzle/soundequalizerpuzzle.cpp
engines/nancy/action/puzzle/soundequalizerpuzzle.h
engines/nancy/action/puzzle/spigotpuzzle.h
engines/nancy/action/puzzle/stepobjectspuzzle.h
engines/nancy/action/puzzle/telephone.h
engines/nancy/action/puzzle/towerpuzzle.cpp
engines/nancy/action/puzzle/towerpuzzle.h
engines/nancy/action/puzzle/turningpuzzle.h
engines/nancy/action/puzzle/twodialpuzzle.h
engines/nancy/action/puzzle/typingquizpuzzle.h
engines/nancy/action/puzzlerecord.cpp
engines/nancy/action/puzzlerecord.h
diff --git a/engines/nancy/action/puzzle/adjustpuzzle.cpp b/engines/nancy/action/puzzle/adjustpuzzle.cpp
index 554372c6e11..9be449b401f 100644
--- a/engines/nancy/action/puzzle/adjustpuzzle.cpp
+++ b/engines/nancy/action/puzzle/adjustpuzzle.cpp
@@ -112,8 +112,7 @@ void AdjustPuzzle::init() {
setVisible(true);
moveTo(vpBounds);
- g_nancy->_resource->loadImage(_imageName, _image);
- _image.setTransparentColor(_drawSurface.getTransparentColor());
+ loadImage();
_overlayImages.resize(_overlayNames.size());
for (uint i = 0; i < _overlayNames.size(); ++i) {
diff --git a/engines/nancy/action/puzzle/adjustpuzzle.h b/engines/nancy/action/puzzle/adjustpuzzle.h
index 8ab37d8e7b8..55500304ad2 100644
--- a/engines/nancy/action/puzzle/adjustpuzzle.h
+++ b/engines/nancy/action/puzzle/adjustpuzzle.h
@@ -81,7 +81,6 @@ protected:
void applyOutcome(const Outcome &outcome);
// -- File data --
- Common::Path _imageName; // 0x1c0
uint16 _testCursorType = 0; // 0x3d - raw Nancy14 cursor type, shown over the test control
Common::Array<Piece> _pieces; // 0x3f
@@ -106,7 +105,6 @@ protected:
Outcome _loseScene; // 0x27d (field0), scene at 0x27f
// -- Runtime state --
- Graphics::ManagedSurface _image;
Common::Array<Graphics::ManagedSurface> _overlayImages;
byte _resultIndex = 0;
bool _showResult = false;
diff --git a/engines/nancy/action/puzzle/angletosspuzzle.cpp b/engines/nancy/action/puzzle/angletosspuzzle.cpp
index ad2ee1e6594..480c1d01b6f 100644
--- a/engines/nancy/action/puzzle/angletosspuzzle.cpp
+++ b/engines/nancy/action/puzzle/angletosspuzzle.cpp
@@ -35,8 +35,7 @@ namespace Action {
void AngleTossPuzzle::init() {
initViewportSurface();
- g_nancy->_resource->loadImage(_imageName, _image);
- _image.setTransparentColor(_drawSurface.getTransparentColor());
+ loadImage();
// Draw the initial angle and power indicators.
// The throw button sprite is NOT drawn here â the static background already shows the
diff --git a/engines/nancy/action/puzzle/angletosspuzzle.h b/engines/nancy/action/puzzle/angletosspuzzle.h
index bb2d0c282ec..c7b63457ed1 100644
--- a/engines/nancy/action/puzzle/angletosspuzzle.h
+++ b/engines/nancy/action/puzzle/angletosspuzzle.h
@@ -58,8 +58,6 @@ public:
protected:
Common::String getRecordTypeName() const override { return "AngleTossPuzzle"; }
- Common::Path _imageName;
-
// data+0x21..0x2c: 6 Ã uint16.
// _initialPower/_initialAngle: starting player selection (copied to object+0x24/0x26 in original).
// _numPowers/_numAngles: UI control bounds (always 5 in practice).
@@ -113,8 +111,6 @@ protected:
int16 _winFlag = -1; // 0x23e
- Graphics::ManagedSurface _image;
-
uint16 _curPower = 0;
uint16 _curAngle = 0;
diff --git a/engines/nancy/action/puzzle/arcadepuzzle.cpp b/engines/nancy/action/puzzle/arcadepuzzle.cpp
index f810f5af6e7..5459d9f364c 100644
--- a/engines/nancy/action/puzzle/arcadepuzzle.cpp
+++ b/engines/nancy/action/puzzle/arcadepuzzle.cpp
@@ -159,8 +159,7 @@ void ArcadePuzzle::init() {
setVisible(true);
moveTo(vpBounds);
- g_nancy->_resource->loadImage(_imageName, _image);
- _image.setTransparentColor(_drawSurface.getTransparentColor());
+ loadImage();
// Determine game field bounds within viewport
int vpDataWidth = (vpBounds.right - vpBounds.left);
diff --git a/engines/nancy/action/puzzle/arcadepuzzle.h b/engines/nancy/action/puzzle/arcadepuzzle.h
index 2f9edf9af99..d1335731686 100644
--- a/engines/nancy/action/puzzle/arcadepuzzle.h
+++ b/engines/nancy/action/puzzle/arcadepuzzle.h
@@ -101,7 +101,6 @@ protected:
void drawYouWin(); // shown during the kLevelClear / kGameOverWin wait states
// ---------- Data (read from stream) ----------
- Common::Path _imageName;
uint32 _numLevelsToWin = 0;
@@ -284,7 +283,6 @@ protected:
bool _launchBall = false;
// Surfaces
- Graphics::ManagedSurface _image;
Graphics::ManagedSurface _backgroundCache; // copy of initial draw surface for erasing
};
diff --git a/engines/nancy/action/puzzle/assemblypuzzle.cpp b/engines/nancy/action/puzzle/assemblypuzzle.cpp
index e5bcc4a60aa..8029533a0ed 100644
--- a/engines/nancy/action/puzzle/assemblypuzzle.cpp
+++ b/engines/nancy/action/puzzle/assemblypuzzle.cpp
@@ -34,8 +34,7 @@ namespace Nancy {
namespace Action {
void AssemblyPuzzle::init() {
- g_nancy->_resource->loadImage(_imageName, _image);
- _image.setTransparentColor(_drawSurface.getTransparentColor());
+ loadImage();
for (uint i = 0; i < _pieces.size(); ++i) {
Piece &piece = _pieces[i];
diff --git a/engines/nancy/action/puzzle/assemblypuzzle.h b/engines/nancy/action/puzzle/assemblypuzzle.h
index 0cfe2cc8f20..2915e7ec9b9 100644
--- a/engines/nancy/action/puzzle/assemblypuzzle.h
+++ b/engines/nancy/action/puzzle/assemblypuzzle.h
@@ -66,8 +66,6 @@ protected:
int curRotation = 0;
};
- Common::Path _imageName;
-
uint16 _height = 0;
Common::Rect _cwCursorDest;
@@ -86,8 +84,6 @@ protected:
Common::String _solveText;
- Graphics::ManagedSurface _image;
-
int _pickedUpPiece = -1;
int _curRotation = 0;
uint _layersAssembled = 0;
diff --git a/engines/nancy/action/puzzle/bballpuzzle.cpp b/engines/nancy/action/puzzle/bballpuzzle.cpp
index 234ee414c01..409370ae9ef 100644
--- a/engines/nancy/action/puzzle/bballpuzzle.cpp
+++ b/engines/nancy/action/puzzle/bballpuzzle.cpp
@@ -36,8 +36,7 @@ namespace Action {
void BBallPuzzle::init() {
initViewportSurface();
- g_nancy->_resource->loadImage(_imageName, _image);
- _image.setTransparentColor(_drawSurface.getTransparentColor());
+ loadImage();
// Set up flags
if (NancySceneState.getEventFlag(_goodShootFlag, g_nancy->_true)) {
diff --git a/engines/nancy/action/puzzle/bballpuzzle.h b/engines/nancy/action/puzzle/bballpuzzle.h
index d17289d9d8d..f1ab84ddb25 100644
--- a/engines/nancy/action/puzzle/bballpuzzle.h
+++ b/engines/nancy/action/puzzle/bballpuzzle.h
@@ -44,8 +44,6 @@ public:
protected:
Common::String getRecordTypeName() const override { return "BBallPuzzle"; }
- Common::Path _imageName;
-
uint16 _positions = 0;
uint16 _powers = 0;
uint16 _angles = 0;
@@ -81,8 +79,6 @@ protected:
int16 _winFlag = 0;
- Graphics::ManagedSurface _image;
-
uint _curAngle = 0;
uint _curPower = 0;
uint _curPosition = 0;
diff --git a/engines/nancy/action/puzzle/beadpuzzle.cpp b/engines/nancy/action/puzzle/beadpuzzle.cpp
index 2de31d5a906..bb955d8e93d 100644
--- a/engines/nancy/action/puzzle/beadpuzzle.cpp
+++ b/engines/nancy/action/puzzle/beadpuzzle.cpp
@@ -107,8 +107,7 @@ void BeadPuzzle::init() {
setVisible(true);
moveTo(vpBounds);
- g_nancy->_resource->loadImage(_imageName, _image);
- _image.setTransparentColor(_drawSurface.getTransparentColor());
+ loadImage();
_placed.clear();
BeadPuzzleData *bpd = getBeadData();
diff --git a/engines/nancy/action/puzzle/beadpuzzle.h b/engines/nancy/action/puzzle/beadpuzzle.h
index 7364b7b9d69..8ffa3a9ea3b 100644
--- a/engines/nancy/action/puzzle/beadpuzzle.h
+++ b/engines/nancy/action/puzzle/beadpuzzle.h
@@ -54,8 +54,6 @@ protected:
// File data
- Common::Path _imageName;
-
uint16 _numSlots = 0;
uint16 _numBeadTypes = 0;
@@ -113,8 +111,6 @@ protected:
uint32 _perfectExitTime = 0;
bool _resultSoundPlayed = false;
- Graphics::ManagedSurface _image;
-
void redraw();
void holdBead(int16 bead, NancyInput *input);
void evaluate();
diff --git a/engines/nancy/action/puzzle/blockingpuzzle.h b/engines/nancy/action/puzzle/blockingpuzzle.h
index 6d30894779a..563d9f5898b 100644
--- a/engines/nancy/action/puzzle/blockingpuzzle.h
+++ b/engines/nancy/action/puzzle/blockingpuzzle.h
@@ -105,7 +105,6 @@ protected:
int16 _field6 = 0; // 0x154 - unknown
byte _field8 = 0; // 0x153 - combat gate flag (gates block input in the original); unused here
byte _field9 = 0; // 0x152 - combat gate flag; unused here
- Common::Path _imageName; // MOU_Fight_OVL sprite sheet
Common::Rect _controlRects[4]; // [0] = the attack-telegraph box sprite (cell-sized); [1-3] other UI
Common::Point _point; // 0x1b3 - unknown
int16 _field51 = 0; // 0x51 - unknown
diff --git a/engines/nancy/action/puzzle/blockspuzzle.cpp b/engines/nancy/action/puzzle/blockspuzzle.cpp
index 68a09e66128..5f7211ce38d 100644
--- a/engines/nancy/action/puzzle/blockspuzzle.cpp
+++ b/engines/nancy/action/puzzle/blockspuzzle.cpp
@@ -99,8 +99,7 @@ void BlocksPuzzle::readData(Common::SeekableReadStream &stream) {
void BlocksPuzzle::init() {
initViewportSurface();
- g_nancy->_resource->loadImage(_imageName, _image);
- _image.setTransparentColor(_drawSurface.getTransparentColor());
+ loadImage();
_hasTurntable = !_turntableDest.isEmpty();
diff --git a/engines/nancy/action/puzzle/blockspuzzle.h b/engines/nancy/action/puzzle/blockspuzzle.h
index 796b3003ced..d3ec5172a23 100644
--- a/engines/nancy/action/puzzle/blockspuzzle.h
+++ b/engines/nancy/action/puzzle/blockspuzzle.h
@@ -103,7 +103,6 @@ protected:
void redraw();
// -- File data (111-byte header) --
- Common::Path _imageName; // 0x00
uint16 _turnDuration = 0; // 0x21 - total ms of one rotation's tween
uint16 _carryCursorType = 0; // 0x23 - raw Nancy13 cursor types
uint16 _turnCursorType = 0; // 0x25
@@ -136,7 +135,6 @@ protected:
bool _solved = false;
bool _exitRequested = false;
- Graphics::ManagedSurface _image;
};
} // End of namespace Action
diff --git a/engines/nancy/action/puzzle/boardgamepuzzle.cpp b/engines/nancy/action/puzzle/boardgamepuzzle.cpp
index 4f33be264c6..afcf814739d 100644
--- a/engines/nancy/action/puzzle/boardgamepuzzle.cpp
+++ b/engines/nancy/action/puzzle/boardgamepuzzle.cpp
@@ -76,8 +76,7 @@ void BoardGamePuzzle::init() {
setVisible(true);
moveTo(vpBounds);
- g_nancy->_resource->loadImage(_imageName, _image);
- _image.setTransparentColor(_drawSurface.getTransparentColor());
+ loadImage();
_moviePlayer.loadFile(_movieName);
_buttonUsed.clear();
diff --git a/engines/nancy/action/puzzle/boardgamepuzzle.h b/engines/nancy/action/puzzle/boardgamepuzzle.h
index 15a4d4a0ef8..baaa0120701 100644
--- a/engines/nancy/action/puzzle/boardgamepuzzle.h
+++ b/engines/nancy/action/puzzle/boardgamepuzzle.h
@@ -63,7 +63,6 @@ protected:
};
// File data
- Common::Path _imageName;
Common::Path _movieName; // the board-game Bink movie ("..._ANIM")
Common::Rect _movieRect; // movie source/params rect (buf+0x244)
Common::Rect _boardRect; // board area within the viewport (buf+0x254)
@@ -106,8 +105,6 @@ protected:
bool _lost = false; // overshot the target
uint32 _resultTime = 0; // ms timestamp when the game ended, for the result hold
- Graphics::ManagedSurface _image;
-
void redraw();
void drawCard(uint index);
void resolveMove(int button);
diff --git a/engines/nancy/action/puzzle/bombpuzzle.h b/engines/nancy/action/puzzle/bombpuzzle.h
index 83f32e1036d..ed6e69abb50 100644
--- a/engines/nancy/action/puzzle/bombpuzzle.h
+++ b/engines/nancy/action/puzzle/bombpuzzle.h
@@ -44,7 +44,6 @@ public:
protected:
Common::String getRecordTypeName() const override { return "BombPuzzle"; }
- Common::Path _imageName;
Common::Array<Common::Rect> _wireSrcs;
Common::Array<Common::Rect> _wireDests;
Common::Array<Common::Rect> _digitSrcs;
@@ -59,7 +58,6 @@ protected:
SceneChangeWithFlag _failSceneChange;
SoundDescription _failSound;
- Graphics::ManagedSurface _image;
Common::Array<byte> _playerOrder;
Time _timerTotalTime;
diff --git a/engines/nancy/action/puzzle/buildpuzzle.h b/engines/nancy/action/puzzle/buildpuzzle.h
index 9b40a52f79f..9f7367141f8 100644
--- a/engines/nancy/action/puzzle/buildpuzzle.h
+++ b/engines/nancy/action/puzzle/buildpuzzle.h
@@ -126,7 +126,6 @@ protected:
bool locked = false; // kept by a zone that marks its pieces placed
};
- Common::Path _imageName;
Common::Path _altImageName; // empty means the main image is used for both
// Selects where a piece that is not in a zone, and any close-up, is drawn
@@ -195,7 +194,6 @@ protected:
// --- Runtime ---
- Graphics::ManagedSurface _image;
Graphics::ManagedSurface _altImage;
Graphics::ManagedSurface _pieceImage; // a kind 3 piece's own close-up art
Common::Path _pieceImageName;
diff --git a/engines/nancy/action/puzzle/bulpuzzle.cpp b/engines/nancy/action/puzzle/bulpuzzle.cpp
index e30a2305ba5..0495e625629 100644
--- a/engines/nancy/action/puzzle/bulpuzzle.cpp
+++ b/engines/nancy/action/puzzle/bulpuzzle.cpp
@@ -38,8 +38,7 @@ namespace Action {
void BulPuzzle::init() {
initViewportSurface();
- g_nancy->_resource->loadImage(_imageName, _image);
- _image.setTransparentColor(_drawSurface.getTransparentColor());
+ loadImage();
reset(false);
diff --git a/engines/nancy/action/puzzle/bulpuzzle.h b/engines/nancy/action/puzzle/bulpuzzle.h
index f28bd4a7569..d73b1fcec7a 100644
--- a/engines/nancy/action/puzzle/bulpuzzle.h
+++ b/engines/nancy/action/puzzle/bulpuzzle.h
@@ -57,8 +57,6 @@ protected:
Common::String getRecordTypeName() const override { return "BulPuzzle"; }
- Common::Path _imageName;
-
uint16 _numCells = 0;
uint16 _numPieces = 0;
uint16 _numRolls = 0;
@@ -127,8 +125,6 @@ protected:
// Nancy 11: the computer passes strategically (based on piece positions) rather than randomly
bool _aiPassStrategy = false;
- Graphics::ManagedSurface _image;
-
int16 _playerPos = 0;
int16 _playerPieces = 0;
int16 _enemyPos = 0;
diff --git a/engines/nancy/action/puzzle/cardgamepuzzle.cpp b/engines/nancy/action/puzzle/cardgamepuzzle.cpp
index dc5b5e38427..3ea772ab471 100644
--- a/engines/nancy/action/puzzle/cardgamepuzzle.cpp
+++ b/engines/nancy/action/puzzle/cardgamepuzzle.cpp
@@ -505,8 +505,7 @@ void CardGamePuzzle::playVoice(const Common::String &name) {
void CardGamePuzzle::init() {
initViewportSurface();
- g_nancy->_resource->loadImage(_imageName, _image);
- _image.setTransparentColor(_drawSurface.getTransparentColor());
+ loadImage();
// Reset board state and the shared deck (every table cell starts available)
for (int side = 0; side < 2; ++side) {
diff --git a/engines/nancy/action/puzzle/cardgamepuzzle.h b/engines/nancy/action/puzzle/cardgamepuzzle.h
index 232d4ccc4c7..b51c0d5ec79 100644
--- a/engines/nancy/action/puzzle/cardgamepuzzle.h
+++ b/engines/nancy/action/puzzle/cardgamepuzzle.h
@@ -82,8 +82,6 @@ protected:
void startMoveAnimation(const bool beforeGrid[kMaxRows][kMaxCols]);
void playVoice(const Common::String &name); // play a voiced line / SFX on the card-game channel
- Common::Path _imageName;
-
// Header flags / dimensions
byte _unknown21 = 0;
byte _switchTurnRule = 0; // data+0x22: how the turn passes after a play
@@ -155,7 +153,6 @@ protected:
uint32 _aiDelayUntil = 0;
// Runtime board state
- Graphics::ManagedSurface _image;
PlayerBoard _board[2];
byte _availMap[kMaxRows][kMaxCols]; // shared deck: 1 = card still on the table
int _deckRemaining = 0;
diff --git a/engines/nancy/action/puzzle/collisionpuzzle.cpp b/engines/nancy/action/puzzle/collisionpuzzle.cpp
index ac5a746d7dc..0c8a724d988 100644
--- a/engines/nancy/action/puzzle/collisionpuzzle.cpp
+++ b/engines/nancy/action/puzzle/collisionpuzzle.cpp
@@ -36,8 +36,7 @@ namespace Action {
void CollisionPuzzle::init() {
initViewportSurface();
- g_nancy->_resource->loadImage(_imageName, _image);
- _image.setTransparentColor(_drawSurface.getTransparentColor());
+ loadImage();
if (_puzzleType == kCollision) {
_pieces.resize(_pieceSrcs.size());
diff --git a/engines/nancy/action/puzzle/collisionpuzzle.h b/engines/nancy/action/puzzle/collisionpuzzle.h
index 565230eaa82..15b5c081d96 100644
--- a/engines/nancy/action/puzzle/collisionpuzzle.h
+++ b/engines/nancy/action/puzzle/collisionpuzzle.h
@@ -76,8 +76,6 @@ protected:
Common::Rect getScreenPosition(Common::Point gridPos);
void drawGrid();
- Common::Path _imageName;
-
Common::Array<Common::Array<uint16>> _grid;
Common::Array<Common::Point> _startLocations;
@@ -111,7 +109,6 @@ protected:
SoundDescription _wallHitSound;
SoundDescription _exitButtonSound;
- Graphics::ManagedSurface _image;
Common::Array<Piece> _pieces;
int _currentlyAnimating = -1;
diff --git a/engines/nancy/action/puzzle/cubepuzzle.cpp b/engines/nancy/action/puzzle/cubepuzzle.cpp
index aabd52f1170..029b22477c9 100644
--- a/engines/nancy/action/puzzle/cubepuzzle.cpp
+++ b/engines/nancy/action/puzzle/cubepuzzle.cpp
@@ -36,8 +36,7 @@ namespace Action {
void CubePuzzle::init() {
initViewportSurface();
- g_nancy->_resource->loadImage(_imageName, _image);
- _image.setTransparentColor(_drawSurface.getTransparentColor());
+ loadImage();
for (uint i = 0; i < 5; ++i) {
_drawSurface.blitFrom(_image, _pieceSrcs[i], _pieceDests[i]);
diff --git a/engines/nancy/action/puzzle/cubepuzzle.h b/engines/nancy/action/puzzle/cubepuzzle.h
index f413987183d..50058b56c9f 100644
--- a/engines/nancy/action/puzzle/cubepuzzle.h
+++ b/engines/nancy/action/puzzle/cubepuzzle.h
@@ -50,8 +50,6 @@ protected:
void rotateBase(int dir);
- Common::Path _imageName;
-
Common::Rect _cwCursorDest;
Common::Rect _ccwCursorDest;
@@ -81,7 +79,6 @@ protected:
// Multiple solve scenes, one for each cube orientation
Common::Array<uint> _solveSceneIDs;
- Graphics::ManagedSurface _image;
Misc::MouseFollowObject _curPiece;
Common::Array<bool> _placedPieces;
diff --git a/engines/nancy/action/puzzle/dotconnectpuzzle.cpp b/engines/nancy/action/puzzle/dotconnectpuzzle.cpp
index d6ec02436f0..3a57c7d50f7 100644
--- a/engines/nancy/action/puzzle/dotconnectpuzzle.cpp
+++ b/engines/nancy/action/puzzle/dotconnectpuzzle.cpp
@@ -81,8 +81,7 @@ void DotConnectPuzzle::init() {
setVisible(true);
moveTo(vpBounds);
- g_nancy->_resource->loadImage(_imageName, _image);
- _image.setTransparentColor(_drawSurface.getTransparentColor());
+ loadImage();
for (int i = 0; i < kNumDots; ++i)
_isActiveDot[i] = false;
diff --git a/engines/nancy/action/puzzle/dotconnectpuzzle.h b/engines/nancy/action/puzzle/dotconnectpuzzle.h
index 969722073af..b105beefeb8 100644
--- a/engines/nancy/action/puzzle/dotconnectpuzzle.h
+++ b/engines/nancy/action/puzzle/dotconnectpuzzle.h
@@ -58,8 +58,6 @@ protected:
// File data
- Common::Path _imageName;
-
Common::Rect _dotSrcRects[kNumDots];
Common::Rect _dotHighlightSrcRects[kNumDots];
@@ -100,8 +98,6 @@ protected:
uint32 _winDelayEndTime = 0;
- Graphics::ManagedSurface _image;
-
void redraw();
bool dotAlreadyUsed(int dot) const;
void onDotClicked(int dot);
diff --git a/engines/nancy/action/puzzle/drivingpuzzle.h b/engines/nancy/action/puzzle/drivingpuzzle.h
index e1a54ef55f0..4beacfe3224 100644
--- a/engines/nancy/action/puzzle/drivingpuzzle.h
+++ b/engines/nancy/action/puzzle/drivingpuzzle.h
@@ -246,7 +246,6 @@ protected:
Variant _variant;
// Three filenames decoded from the header blob.
- Common::Path _imageName; // visible town map ("MAP_Titusville")
Common::Path _collisionName; // collision mask ("MAP_TitusvilleCollision")
Common::Path _carSpriteName; // car rotation atlas ("MAP_Roadster_OVL")
@@ -327,7 +326,6 @@ protected:
double _chaserY = 0.0;
double _chaserHeading = 0.0;
- Graphics::ManagedSurface _image; // the town map
Graphics::ManagedSurface _carImage; // the player car rotation atlas
Graphics::ManagedSurface _chaseCarImage; // the chaser car rotation atlas
Graphics::ManagedSurface _collisionMask; // road/off-road mask ("MAP_TitusvilleCollision")
diff --git a/engines/nancy/action/puzzle/dropsortpuzzle.cpp b/engines/nancy/action/puzzle/dropsortpuzzle.cpp
index 7b5e0a1ea5f..0e48a7968e1 100644
--- a/engines/nancy/action/puzzle/dropsortpuzzle.cpp
+++ b/engines/nancy/action/puzzle/dropsortpuzzle.cpp
@@ -119,8 +119,7 @@ void DropSortPuzzle::readData(Common::SeekableReadStream &stream) {
void DropSortPuzzle::init() {
initViewportSurface();
- g_nancy->_resource->loadImage(_imageName, _image);
- _image.setTransparentColor(_drawSurface.getTransparentColor());
+ loadImage();
// Both animations loop for the whole puzzle.
if (_conveyorMovie.loadFile(_conveyorMovieName)) {
diff --git a/engines/nancy/action/puzzle/dropsortpuzzle.h b/engines/nancy/action/puzzle/dropsortpuzzle.h
index c17bf7ccff6..36a638ea025 100644
--- a/engines/nancy/action/puzzle/dropsortpuzzle.h
+++ b/engines/nancy/action/puzzle/dropsortpuzzle.h
@@ -84,7 +84,6 @@ protected:
void drawCounter();
// -- File data --
- Common::Path _imageName; // 0x00 - overlay sprite sheet (candies, strikes)
Common::Path _hoseMovieName; // 0x21 - hose (dispenser) animation
Common::Rect _hoseRect; // 0x42
uint32 _dispenseFrame = 0; // 0x52 - unused in this port
@@ -144,7 +143,6 @@ protected:
MoviePlayer _conveyorMovie;
MoviePlayer _hoseMovie;
- Graphics::ManagedSurface _image;
};
} // End of namespace Action
diff --git a/engines/nancy/action/puzzle/hamradiopuzzle.cpp b/engines/nancy/action/puzzle/hamradiopuzzle.cpp
index 0982ce882bd..3c95146178f 100644
--- a/engines/nancy/action/puzzle/hamradiopuzzle.cpp
+++ b/engines/nancy/action/puzzle/hamradiopuzzle.cpp
@@ -49,8 +49,7 @@ static const char *morseCodeTable[] = {
void HamRadioPuzzle::init() {
initViewportSurface();
- g_nancy->_resource->loadImage(_imageName, _image);
- _image.setTransparentColor(_drawSurface.getTransparentColor());
+ loadImage();
}
void HamRadioPuzzle::updateGraphics() {
diff --git a/engines/nancy/action/puzzle/hamradiopuzzle.h b/engines/nancy/action/puzzle/hamradiopuzzle.h
index bbdee9696fa..09739e7684d 100644
--- a/engines/nancy/action/puzzle/hamradiopuzzle.h
+++ b/engines/nancy/action/puzzle/hamradiopuzzle.h
@@ -67,8 +67,6 @@ protected:
void readData(Common::SeekableReadStream &stream, uint16 numDigits);
};
- Common::Path _imageName;
-
uint16 _numDigits = 0;
Frequency _startFreq;
@@ -109,8 +107,6 @@ protected:
Common::Array<Frequency> _otherFrequencies;
- Graphics::ManagedSurface _image;
-
// Frequency display data
bool _digitsRolling = true;
Common::Array<uint16> _curDigits;
diff --git a/engines/nancy/action/puzzle/leverpuzzle.h b/engines/nancy/action/puzzle/leverpuzzle.h
index 50d9b3c2611..59b9a8e882d 100644
--- a/engines/nancy/action/puzzle/leverpuzzle.h
+++ b/engines/nancy/action/puzzle/leverpuzzle.h
@@ -39,7 +39,6 @@ public:
void execute() override;
void handleInput(NancyInput &input) override;
- Common::Path _imageName;
Common::Array<Common::Array<Common::Rect>> _srcRects;
Common::Array<Common::Rect> _destRects;
Common::Array<byte> _correctSequence;
@@ -48,7 +47,6 @@ public:
Common::Array<byte> _playerSequence;
Common::Array<bool> _leverDirection;
- Graphics::ManagedSurface _image;
Time _solveSoundPlayTime;
SolveState _solveState = kNotSolved;
diff --git a/engines/nancy/action/puzzle/matchpuzzle.h b/engines/nancy/action/puzzle/matchpuzzle.h
index a94c633687d..03d61e52894 100644
--- a/engines/nancy/action/puzzle/matchpuzzle.h
+++ b/engines/nancy/action/puzzle/matchpuzzle.h
@@ -272,7 +272,6 @@ protected:
// Rendering
Common::Array<Common::Array<GridCell>> _grid; // _grid[col][row]
- Graphics::ManagedSurface _image; // loaded sprite sheet
Graphics::ManagedSurface _scorePanelImage; // score-panel background
Graphics::ManagedSurface _buttonsImage; // Nancy14 pressed-button graphics
Graphics::ManagedSurface _highScoreImage; // Nancy14 high score backdrop
diff --git a/engines/nancy/action/puzzle/mazechasepuzzle.cpp b/engines/nancy/action/puzzle/mazechasepuzzle.cpp
index 694f32a6cd2..76ccfd5d3a2 100644
--- a/engines/nancy/action/puzzle/mazechasepuzzle.cpp
+++ b/engines/nancy/action/puzzle/mazechasepuzzle.cpp
@@ -36,8 +36,7 @@ namespace Action {
void MazeChasePuzzle::init() {
initViewportSurface();
- g_nancy->_resource->loadImage(_imageName, _image);
- _image.setTransparentColor(_drawSurface.getTransparentColor());
+ loadImage();
for (uint i = 0; i < _startLocations.size(); ++i) {
_pieces.push_back(Piece(_z + i + 1));
diff --git a/engines/nancy/action/puzzle/mazechasepuzzle.h b/engines/nancy/action/puzzle/mazechasepuzzle.h
index bc89b8e449d..8f8866fba60 100644
--- a/engines/nancy/action/puzzle/mazechasepuzzle.h
+++ b/engines/nancy/action/puzzle/mazechasepuzzle.h
@@ -72,8 +72,6 @@ protected:
bool canMove(uint pieceID, WallType direction);
void reset();
- Common::Path _imageName;
-
Common::Point _exitPos = Common::Point(-1, -1);
Common::Array<Common::Array<uint16>> _grid;
@@ -107,7 +105,6 @@ protected:
SoundDescription _failSound;
SoundDescription _moveSound;
- Graphics::ManagedSurface _image;
Common::Array<Piece> _pieces;
int _currentAnimFrame = -1;
diff --git a/engines/nancy/action/puzzle/memorypuzzle.cpp b/engines/nancy/action/puzzle/memorypuzzle.cpp
index fb2b99e517e..16eac8ed1f8 100644
--- a/engines/nancy/action/puzzle/memorypuzzle.cpp
+++ b/engines/nancy/action/puzzle/memorypuzzle.cpp
@@ -254,8 +254,7 @@ void MemoryPuzzle::init() {
setVisible(true);
moveTo(vpBounds);
- g_nancy->_resource->loadImage(_imageName, _image);
- _image.setTransparentColor(_drawSurface.getTransparentColor());
+ loadImage();
_currentTab = 0;
initCards();
diff --git a/engines/nancy/action/puzzle/memorypuzzle.h b/engines/nancy/action/puzzle/memorypuzzle.h
index 936a4139624..0b41b29be7c 100644
--- a/engines/nancy/action/puzzle/memorypuzzle.h
+++ b/engines/nancy/action/puzzle/memorypuzzle.h
@@ -51,8 +51,6 @@ protected:
// File data
- Common::Path _imageName;
-
static const int kMaxTypes = 36; // 3 tabs x 12 pairs each
static const int kCardsPerTab = 24; // hardcoded in original
static const int kNumTabs = 3; // hardcoded in original
@@ -95,8 +93,6 @@ protected:
CardState _cards[kNumTabs * kCardsPerTab];
bool _typeUsed[kMaxTypes]; // faces already handed out while filling _cards
- Graphics::ManagedSurface _image;
-
int _currentTab = 0;
int _firstFlip = -1; // absolute card index of first face-up unmatched card
int _secondFlip = -1; // absolute card index of second (timer pending)
diff --git a/engines/nancy/action/puzzle/mindpuzzle.cpp b/engines/nancy/action/puzzle/mindpuzzle.cpp
index fb38e942609..1dce5611a83 100644
--- a/engines/nancy/action/puzzle/mindpuzzle.cpp
+++ b/engines/nancy/action/puzzle/mindpuzzle.cpp
@@ -241,8 +241,7 @@ void MindPuzzle::init() {
setVisible(true);
moveTo(vpBounds);
- g_nancy->_resource->loadImage(_imageName, _image);
- _image.setTransparentColor(_drawSurface.getTransparentColor());
+ loadImage();
for (uint r = 0; r < kMaxRows; ++r) {
for (uint s = 0; s < kSlotsPerRow; ++s) {
diff --git a/engines/nancy/action/puzzle/mindpuzzle.h b/engines/nancy/action/puzzle/mindpuzzle.h
index 69488f91c4b..94f1c314310 100644
--- a/engines/nancy/action/puzzle/mindpuzzle.h
+++ b/engines/nancy/action/puzzle/mindpuzzle.h
@@ -63,7 +63,6 @@ protected:
};
// File data
- Common::Path _imageName;
uint16 _numColors = 0;
uint16 _codeLength = 0;
@@ -97,8 +96,6 @@ protected:
SoundDescription _outcomeSound; // applause cue played once on a win
bool _outcomeStarted = false;
- Graphics::ManagedSurface _image;
-
void generateSecret();
void scoreRow(int row);
void drawPeg(int color, const Common::Rect &dest);
diff --git a/engines/nancy/action/puzzle/minigolfpuzzle.h b/engines/nancy/action/puzzle/minigolfpuzzle.h
index 27dcf098a75..76c9c58b191 100644
--- a/engines/nancy/action/puzzle/minigolfpuzzle.h
+++ b/engines/nancy/action/puzzle/minigolfpuzzle.h
@@ -134,7 +134,6 @@ protected:
double _pipeInVy = 0.0;
bool _ballHidden = false; // ball is inside a pipe (not drawn)
- Graphics::ManagedSurface _image;
Graphics::ManagedSurface _boundaryMask;
// Cosmetic overlay sprite (ActionZone type 0xd), e.g. hole 6a's broken wall.
diff --git a/engines/nancy/action/puzzle/mirrorlightpuzzle.cpp b/engines/nancy/action/puzzle/mirrorlightpuzzle.cpp
index cc6e40bd274..0a22dfcbb40 100644
--- a/engines/nancy/action/puzzle/mirrorlightpuzzle.cpp
+++ b/engines/nancy/action/puzzle/mirrorlightpuzzle.cpp
@@ -367,8 +367,7 @@ void MirrorLightPuzzle::init() {
setVisible(true);
moveTo(vpBounds);
- g_nancy->_resource->loadImage(_imageName, _image);
- _image.setTransparentColor(_drawSurface.getTransparentColor());
+ loadImage();
// Mirrors keep the angle the player last left them at.
MirrorLightData *data = (MirrorLightData *)NancySceneState.getPuzzleData(MirrorLightData::getTag());
diff --git a/engines/nancy/action/puzzle/mirrorlightpuzzle.h b/engines/nancy/action/puzzle/mirrorlightpuzzle.h
index 51f8a12c448..a2f7c4e28d9 100644
--- a/engines/nancy/action/puzzle/mirrorlightpuzzle.h
+++ b/engines/nancy/action/puzzle/mirrorlightpuzzle.h
@@ -69,7 +69,6 @@ protected:
};
// File data
- Common::Path _imageName;
int16 _beamAngle = 0; // initial beam angle (degrees)
int32 _beamOriginX = 0;
@@ -97,8 +96,6 @@ protected:
Common::Array<Common::Point> _beamPath; // traced beam polyline, in viewport coords
Common::Array<ZoneOverlay> _overlays;
- Graphics::ManagedSurface _image;
-
bool isAngleWithinLimits(const Mirror &m, double angle) const;
uint frameForAngle(double angle) const;
void drawMirror(uint index);
diff --git a/engines/nancy/action/puzzle/mouselightpuzzle.h b/engines/nancy/action/puzzle/mouselightpuzzle.h
index ea0339f0fa8..bc472b9bd08 100644
--- a/engines/nancy/action/puzzle/mouselightpuzzle.h
+++ b/engines/nancy/action/puzzle/mouselightpuzzle.h
@@ -50,7 +50,6 @@ public:
protected:
Common::String getRecordTypeName() const override { return "MouseLightPuzzle"; }
- Common::Path _imageName;
byte _radius = 0;
bool _smoothEdges = false;
diff --git a/engines/nancy/action/puzzle/onebuildpuzzle.cpp b/engines/nancy/action/puzzle/onebuildpuzzle.cpp
index 68d26591cbe..770f45cee36 100644
--- a/engines/nancy/action/puzzle/onebuildpuzzle.cpp
+++ b/engines/nancy/action/puzzle/onebuildpuzzle.cpp
@@ -43,8 +43,7 @@ static bool rectFitsIn(const Common::Rect &inner, const Common::Rect &outer, int
}
void OneBuildPuzzle::init() {
- g_nancy->_resource->loadImage(_imageName, _image);
- _image.setTransparentColor(_drawSurface.getTransparentColor());
+ loadImage();
// Post-placement animation atlas (e.g. music-box handle "GHO_SlnMBoxHandle_OVL"
// in scene 3637). Loaded only when the puzzle defines _animRectA;
diff --git a/engines/nancy/action/puzzle/onebuildpuzzle.h b/engines/nancy/action/puzzle/onebuildpuzzle.h
index dd2a28eaa92..01895ebba75 100644
--- a/engines/nancy/action/puzzle/onebuildpuzzle.h
+++ b/engines/nancy/action/puzzle/onebuildpuzzle.h
@@ -118,7 +118,6 @@ protected:
// --- File data ---
- Common::Path _imageName;
uint16 _numPieces = 0; // Number of piece descriptions in the puzzle data
uint16 _totalPieces = 0; // Number of pieces on screen; see init() for the extra ones
bool _freePlacement = false; // Wrong drop restores to previous position, not home
@@ -210,8 +209,6 @@ protected:
// --- Runtime state ---
- Graphics::ManagedSurface _image;
-
int16 _pickedUpPiece = -1; // Index of currently dragged piece, -1 if none
bool _isDragging = false; // True while a piece is attached to the cursor
bool _isSolved = false;
diff --git a/engines/nancy/action/puzzle/orderingpuzzle.h b/engines/nancy/action/puzzle/orderingpuzzle.h
index 31c907b2ccd..4f42442aead 100644
--- a/engines/nancy/action/puzzle/orderingpuzzle.h
+++ b/engines/nancy/action/puzzle/orderingpuzzle.h
@@ -63,7 +63,6 @@ protected:
bool enteredKeysMatchStage() const;
bool enteredKeysMatchDangerRecipe() const;
- Common::Path _imageName;
bool _hasSecondState = false;
bool _itemsStayDown = true;
bool _needButtonToCheckSuccess = false;
@@ -126,7 +125,6 @@ protected:
SoundDescription _popUpSound;
SolveState _solveState = kNotSolved;
- Graphics::ManagedSurface _image;
Common::Array<uint16> _clickedSequence;
Common::Array<bool> _downItems;
Common::Array<bool> _secondStateItems;
diff --git a/engines/nancy/action/puzzle/overridelockpuzzle.cpp b/engines/nancy/action/puzzle/overridelockpuzzle.cpp
index 86c2dff7778..aea502f8f4f 100644
--- a/engines/nancy/action/puzzle/overridelockpuzzle.cpp
+++ b/engines/nancy/action/puzzle/overridelockpuzzle.cpp
@@ -38,8 +38,7 @@ namespace Action {
void OverrideLockPuzzle::init() {
initViewportSurface();
- g_nancy->_resource->loadImage(_imageName, _image);
- _image.setTransparentColor(_drawSurface.getTransparentColor());
+ loadImage();
}
void OverrideLockPuzzle::readData(Common::SeekableReadStream &stream) {
diff --git a/engines/nancy/action/puzzle/overridelockpuzzle.h b/engines/nancy/action/puzzle/overridelockpuzzle.h
index b5b24363855..9304c2740b8 100644
--- a/engines/nancy/action/puzzle/overridelockpuzzle.h
+++ b/engines/nancy/action/puzzle/overridelockpuzzle.h
@@ -53,8 +53,6 @@ protected:
enum SolveState { kNotSolved, kSolved };
- Common::Path _imageName;
-
byte _popButtons = kButtonsStayDown;
byte _randomizeLights = kLightsCircular;
@@ -69,8 +67,6 @@ protected:
Time _buttonPopTime;
- Graphics::ManagedSurface _image;
-
Common::Array<byte> _buttonOrder;
Common::Array<byte> _lightsOrder;
Common::Array<byte> _playerOrder;
diff --git a/engines/nancy/action/puzzle/pachinkopuzzle.cpp b/engines/nancy/action/puzzle/pachinkopuzzle.cpp
index 4b880138791..49a3a7eb7a0 100644
--- a/engines/nancy/action/puzzle/pachinkopuzzle.cpp
+++ b/engines/nancy/action/puzzle/pachinkopuzzle.cpp
@@ -227,8 +227,7 @@ Common::Point PachinkoPuzzle::climberAnchor(const Machine &m) const {
void PachinkoPuzzle::init() {
initViewportSurface();
- g_nancy->_resource->loadImage(_imageName, _image);
- _image.setTransparentColor(_drawSurface.getTransparentColor());
+ loadImage();
if (!_ballImageName.empty()) {
g_nancy->_resource->loadImage(_ballImageName, _ballImage);
_ballImage.setTransparentColor(_drawSurface.getTransparentColor());
diff --git a/engines/nancy/action/puzzle/pachinkopuzzle.h b/engines/nancy/action/puzzle/pachinkopuzzle.h
index b1752a3731a..4d79cbdef2b 100644
--- a/engines/nancy/action/puzzle/pachinkopuzzle.h
+++ b/engines/nancy/action/puzzle/pachinkopuzzle.h
@@ -110,7 +110,6 @@ protected:
void advanceMachine(Machine &m, uint32 now);
// -- File data --
- Common::Path _imageName; // board overlay
Common::Rect _ballSrc; // ball sprite source
Common::Rect _ballEntry; // top-right entry chute (where balls appear)
@@ -156,7 +155,6 @@ protected:
SoundDescription _resultSoundDesc;
Common::Path _litImageName; // "lit" board overlay (hole highlights)
- Graphics::ManagedSurface _image; // board overlay
Graphics::ManagedSurface _ballImage; // ball sprite sheet
Graphics::ManagedSurface _litImage; // lit-hole sprites
MoviePlayer _resultMovie;
diff --git a/engines/nancy/action/puzzle/paintpuzzle.h b/engines/nancy/action/puzzle/paintpuzzle.h
index 68d697e5cb6..5469261b5e7 100644
--- a/engines/nancy/action/puzzle/paintpuzzle.h
+++ b/engines/nancy/action/puzzle/paintpuzzle.h
@@ -95,7 +95,6 @@ protected:
bool isSolved() const;
// -- File data --
- Common::Path _imageName; // 0x3d
Common::Path _objectsImageName;
uint16 _hoverCursorType = 0; // 0x5e - raw Nancy14 cursor type, shown over a color swatch
Common::Point _offset; // 0x60 (two int32) - brush sprite offset from the cursor
@@ -114,7 +113,6 @@ protected:
Common::Array<ExitHotspot> _exitHotspots;
// -- Runtime state --
- Graphics::ManagedSurface _image;
Graphics::ManagedSurface _objectsImage;
Common::Array<Graphics::ManagedSurface> _regionImages;
int _heldColor = -1;
diff --git a/engines/nancy/action/puzzle/pegspuzzle.cpp b/engines/nancy/action/puzzle/pegspuzzle.cpp
index b3f3b04701f..745f971b4e2 100644
--- a/engines/nancy/action/puzzle/pegspuzzle.cpp
+++ b/engines/nancy/action/puzzle/pegspuzzle.cpp
@@ -88,8 +88,7 @@ void PegsPuzzle::readData(Common::SeekableReadStream &stream) {
void PegsPuzzle::init() {
initViewportSurface();
- g_nancy->_resource->loadImage(_imageName, _image);
- _image.setTransparentColor(_drawSurface.getTransparentColor());
+ loadImage();
// Build the board: every hole starts with a peg, the cut-out corners are blocked,
// and one hole (usually the centre) starts empty.
diff --git a/engines/nancy/action/puzzle/pegspuzzle.h b/engines/nancy/action/puzzle/pegspuzzle.h
index 339caf5edb0..da60b5d808d 100644
--- a/engines/nancy/action/puzzle/pegspuzzle.h
+++ b/engines/nancy/action/puzzle/pegspuzzle.h
@@ -76,7 +76,6 @@ protected:
void redraw();
// -- File data (96-byte header) --
- Common::Path _imageName; // 0x00
uint16 _hoverCursorType = 0; // 0x21 - cursor while hovering a movable peg (open hand)
uint16 _dragCursorType = 0; // 0x23 - cursor while carrying a peg (pointing finger)
byte _startEmptyFlag = 0; // 0x25 - 0 => mark _startEmptyPos empty at init
@@ -109,7 +108,6 @@ protected:
uint32 _endTime = 0;
SoundDescription _endSound; // the win/lose cue we wait on before changing scene
- Graphics::ManagedSurface _image;
};
} // End of namespace Action
diff --git a/engines/nancy/action/puzzle/rippedletterpuzzle.h b/engines/nancy/action/puzzle/rippedletterpuzzle.h
index 142558ece55..5605352404b 100644
--- a/engines/nancy/action/puzzle/rippedletterpuzzle.h
+++ b/engines/nancy/action/puzzle/rippedletterpuzzle.h
@@ -44,8 +44,6 @@ public:
void execute() override;
void handleInput(NancyInput &input) override;
- Common::Path _imageName;
-
Common::Array<Common::Rect> _srcRects;
Common::Array<Common::Rect> _destRects;
@@ -76,7 +74,6 @@ public:
Misc::MouseFollowObject _pickedUpPiece;
- Graphics::ManagedSurface _image;
SolveState _solveState = kNotSolved;
RippedLetterPuzzleData *_puzzleState = nullptr;
diff --git a/engines/nancy/action/puzzle/rotatinglockpuzzle.h b/engines/nancy/action/puzzle/rotatinglockpuzzle.h
index a16a73f76f0..2c85332da90 100644
--- a/engines/nancy/action/puzzle/rotatinglockpuzzle.h
+++ b/engines/nancy/action/puzzle/rotatinglockpuzzle.h
@@ -41,7 +41,6 @@ public:
void execute() override;
void handleInput(NancyInput &input) override;
- Common::Path _imageName;
Common::Array<Common::Rect> _srcRects;
Common::Array<Common::Rect> _destRects;
Common::Array<Common::Rect> _upHotspots;
@@ -59,7 +58,6 @@ public:
SoundDescription _clickSound;
SolveState _solveState = kNotSolved;
- Graphics::ManagedSurface _image;
Common::Array<byte> _currentSequence;
Time _solveSoundPlayTime;
diff --git a/engines/nancy/action/puzzle/scalepuzzle.cpp b/engines/nancy/action/puzzle/scalepuzzle.cpp
index 14049ead3a6..babe67f68bb 100644
--- a/engines/nancy/action/puzzle/scalepuzzle.cpp
+++ b/engines/nancy/action/puzzle/scalepuzzle.cpp
@@ -110,8 +110,7 @@ void ScalePuzzle::readData(Common::SeekableReadStream &stream) {
void ScalePuzzle::init() {
initViewportSurface();
- g_nancy->_resource->loadImage(_imageName, _image);
- _image.setTransparentColor(_drawSurface.getTransparentColor());
+ loadImage();
// The indicator reads zero at the middle frame of its strip; the running total shifts it.
_indicatorZeroFrame = _indicatorFrames.size() / 2;
diff --git a/engines/nancy/action/puzzle/scalepuzzle.h b/engines/nancy/action/puzzle/scalepuzzle.h
index 33677bcb235..5e492cf9d18 100644
--- a/engines/nancy/action/puzzle/scalepuzzle.h
+++ b/engines/nancy/action/puzzle/scalepuzzle.h
@@ -100,7 +100,6 @@ protected:
void redraw();
// -- File data --
- Common::Path _imageName; // 0x00
uint16 _hoverCursorType = 0; // 0x21 - raw Nancy13 cursor type over a coin
uint16 _dragCursorType = 0; // 0x23 - raw Nancy13 cursor type while carrying
RandomSoundBlock _solveSoundBlock; // the first sound block; played once solved
@@ -135,7 +134,6 @@ protected:
bool _solveTriggered = false; // the solve flag/scene are applied only once
bool _exitRequested = false;
- Graphics::ManagedSurface _image;
};
} // End of namespace Action
diff --git a/engines/nancy/action/puzzle/setplayerclock.cpp b/engines/nancy/action/puzzle/setplayerclock.cpp
index 072e3aca487..757595d74a1 100644
--- a/engines/nancy/action/puzzle/setplayerclock.cpp
+++ b/engines/nancy/action/puzzle/setplayerclock.cpp
@@ -43,8 +43,7 @@ SetPlayerClock::~SetPlayerClock() {
void SetPlayerClock::init() {
initViewportSurface();
- g_nancy->_resource->loadImage(_imageName, _image);
- _image.setTransparentColor(_drawSurface.getTransparentColor());
+ loadImage();
}
void SetPlayerClock::readData(Common::SeekableReadStream &stream) {
diff --git a/engines/nancy/action/puzzle/setplayerclock.h b/engines/nancy/action/puzzle/setplayerclock.h
index e5ed412016d..5e8f8db655d 100644
--- a/engines/nancy/action/puzzle/setplayerclock.h
+++ b/engines/nancy/action/puzzle/setplayerclock.h
@@ -47,8 +47,6 @@ protected:
void drawTime(uint16 hours, uint16 minutes);
- Common::Path _imageName;
-
Common::Rect _minutesDest;
Common::Rect _hoursDest;
Common::Rect _AMPMDest;
@@ -75,8 +73,6 @@ protected:
SoundDescription _buttonSound;
- Graphics::ManagedSurface _image;
-
int8 _lastDrawnHours = -1;
int8 _lastDrawnMinutes = -1;
int8 _alarmHours = -1;
diff --git a/engines/nancy/action/puzzle/sewingmachinepuzzle.cpp b/engines/nancy/action/puzzle/sewingmachinepuzzle.cpp
index 00da2a7b399..ea2d0b7f48b 100644
--- a/engines/nancy/action/puzzle/sewingmachinepuzzle.cpp
+++ b/engines/nancy/action/puzzle/sewingmachinepuzzle.cpp
@@ -200,8 +200,7 @@ void SewingMachinePuzzle::init() {
setVisible(true);
moveTo(vpBounds);
- g_nancy->_resource->loadImage(_imageName, _image);
- _image.setTransparentColor(_drawSurface.getTransparentColor());
+ loadImage();
// The needle's fixed sewing point = the bottom-center of the needle overlay's
// dest rect (167,0,285,170).
diff --git a/engines/nancy/action/puzzle/sewingmachinepuzzle.h b/engines/nancy/action/puzzle/sewingmachinepuzzle.h
index 9a8f53ebed7..0ba04ff9f64 100644
--- a/engines/nancy/action/puzzle/sewingmachinepuzzle.h
+++ b/engines/nancy/action/puzzle/sewingmachinepuzzle.h
@@ -70,9 +70,6 @@ protected:
// mistake line and sets the zone's flag (edge-triggered, once per excursion).
void checkSeam();
- // Background image ("BED_Sewing_OVL").
- Common::Path _imageName;
-
// 87-byte PuzzleBase header blob: image name + two cloth regions + a direction
// vector + an extent vector (its magnitude = the seam length) + three params
// (_params[1] = stitch distance threshold, _params[2] = its hysteresis).
@@ -113,7 +110,6 @@ protected:
bool _hasSeamMask = false;
bool _offSeam = false; // the needle was off the seam last check
- Graphics::ManagedSurface _image;
Graphics::ManagedSurface _seamMask;
};
diff --git a/engines/nancy/action/puzzle/sliderpuzzle.h b/engines/nancy/action/puzzle/sliderpuzzle.h
index 5de868afb78..d51e71b75c3 100644
--- a/engines/nancy/action/puzzle/sliderpuzzle.h
+++ b/engines/nancy/action/puzzle/sliderpuzzle.h
@@ -45,7 +45,6 @@ public:
SliderPuzzleData *_puzzleState = nullptr;
- Common::Path _imageName;
uint16 _width = 0;
uint16 _height = 0;
Common::Array<Common::Array<Common::Rect>> _srcRects;
@@ -57,7 +56,6 @@ public:
bool _retainState = true;
SolveState _solveState = kNotSolved;
- Graphics::ManagedSurface _image;
bool isViewportRelative() const override { return true; }
diff --git a/engines/nancy/action/puzzle/soundequalizerpuzzle.cpp b/engines/nancy/action/puzzle/soundequalizerpuzzle.cpp
index a50c8329a74..7590df8dec8 100644
--- a/engines/nancy/action/puzzle/soundequalizerpuzzle.cpp
+++ b/engines/nancy/action/puzzle/soundequalizerpuzzle.cpp
@@ -63,8 +63,7 @@ SoundEqualizerPuzzle::~SoundEqualizerPuzzle() {
void SoundEqualizerPuzzle::init() {
initViewportSurface();
- g_nancy->_resource->loadImage(_imageName, _image);
- _image.setTransparentColor(_drawSurface.getTransparentColor());
+ loadImage();
const VIEW *viewportData = (const VIEW *)g_nancy->getEngineData("VIEW");
assert(viewportData);
diff --git a/engines/nancy/action/puzzle/soundequalizerpuzzle.h b/engines/nancy/action/puzzle/soundequalizerpuzzle.h
index dbb23144d32..ab5caa1d159 100644
--- a/engines/nancy/action/puzzle/soundequalizerpuzzle.h
+++ b/engines/nancy/action/puzzle/soundequalizerpuzzle.h
@@ -48,8 +48,6 @@ public:
void execute() override;
void handleInput(NancyInput &input) override;
- Common::Path _imageName;
-
Common::Rect _buttonSrc;
Common::Rect _buttonDest;
Common::Rect _sliderSrc;
@@ -78,7 +76,6 @@ public:
SoundDescription _exitSound;
- Graphics::ManagedSurface _image;
Common::Array<ViewportScrollbar *> _sliders;
SoundEqualizerPuzzleData *_puzzleState = nullptr;
diff --git a/engines/nancy/action/puzzle/spigotpuzzle.h b/engines/nancy/action/puzzle/spigotpuzzle.h
index fcc71c7471b..c48b61f3595 100644
--- a/engines/nancy/action/puzzle/spigotpuzzle.h
+++ b/engines/nancy/action/puzzle/spigotpuzzle.h
@@ -45,8 +45,6 @@ public:
protected:
Common::String getRecordTypeName() const override { return "SpigotPuzzle"; }
- Common::Path _imageName;
-
uint _numSpigots = 0;
uint _numLetters = 0;
uint _numInbetweens = 0;
@@ -72,8 +70,6 @@ protected:
SoundDescription _letterSound;
SoundDescription _spigotSound;
- Graphics::ManagedSurface _image;
-
Common::Array<uint16> _currentOrder;
Common::Array<uint16> _currentAnimOrder;
Common::Array<uint16> _numPulls;
diff --git a/engines/nancy/action/puzzle/stepobjectspuzzle.h b/engines/nancy/action/puzzle/stepobjectspuzzle.h
index 69ec66d01cc..aeed7ee6276 100644
--- a/engines/nancy/action/puzzle/stepobjectspuzzle.h
+++ b/engines/nancy/action/puzzle/stepobjectspuzzle.h
@@ -102,7 +102,6 @@ protected:
void drawSprite(Graphics::ManagedSurface &dest, const Common::Rect &srcRect, const Common::Point &destPos, byte alpha);
// File data
- Common::Path _imageName;
// The puzzle carries its own cursor as a raw Nancy13 cursor type id; the same
// one is used for hovering and for carrying an object.
uint16 _cursorType = 0;
@@ -129,7 +128,6 @@ protected:
bool _solved = false;
bool _exitRequested = false;
- Graphics::ManagedSurface _image;
};
} // End of namespace Action
diff --git a/engines/nancy/action/puzzle/telephone.h b/engines/nancy/action/puzzle/telephone.h
index 896b1457b67..a06c46ffc4e 100644
--- a/engines/nancy/action/puzzle/telephone.h
+++ b/engines/nancy/action/puzzle/telephone.h
@@ -68,7 +68,6 @@ public:
protected:
Common::String getRecordTypeName() const override { return _phoneType == kNewPhone ? "NewPhone" : "Telephone"; }
- Common::Path _imageName;
Common::Array<Common::Rect> _srcRects;
Common::Array<Common::Rect> _destRects;
SoundDescription _genericDialogueSound;
@@ -111,7 +110,6 @@ protected:
SoundDescription _preCallSound;
Common::Array<byte> _calledNumber;
- Graphics::ManagedSurface _image;
Graphics::ManagedSurface _animImage;
CallState _callState;
int _buttonLastPushed;
diff --git a/engines/nancy/action/puzzle/towerpuzzle.cpp b/engines/nancy/action/puzzle/towerpuzzle.cpp
index 30a43ebded7..907e9532e6e 100644
--- a/engines/nancy/action/puzzle/towerpuzzle.cpp
+++ b/engines/nancy/action/puzzle/towerpuzzle.cpp
@@ -36,8 +36,7 @@ namespace Action {
void TowerPuzzle::init() {
initViewportSurface();
- g_nancy->_resource->loadImage(_imageName, _image);
- _image.setTransparentColor(_drawSurface.getTransparentColor());
+ loadImage();
}
void TowerPuzzle::registerGraphics() {
diff --git a/engines/nancy/action/puzzle/towerpuzzle.h b/engines/nancy/action/puzzle/towerpuzzle.h
index fb588b464d2..173ca7bb19e 100644
--- a/engines/nancy/action/puzzle/towerpuzzle.h
+++ b/engines/nancy/action/puzzle/towerpuzzle.h
@@ -50,7 +50,6 @@ protected:
void drawRing(uint poleID, uint position, uint ringID, bool clear = false);
- Common::Path _imageName;
Common::Array<uint16> _numRingsByDifficulty;
Common::Array<Common::Rect> _droppedRingSrcs;
@@ -62,7 +61,6 @@ protected:
SoundDescription _takeSound;
SoundDescription _dropSound;
- Graphics::ManagedSurface _image;
Misc::MouseFollowObject _heldRing;
int8 _heldRingID = -1;
int8 _heldRingPoleID = -1;
diff --git a/engines/nancy/action/puzzle/turningpuzzle.h b/engines/nancy/action/puzzle/turningpuzzle.h
index 92683d85082..1cc679f2970 100644
--- a/engines/nancy/action/puzzle/turningpuzzle.h
+++ b/engines/nancy/action/puzzle/turningpuzzle.h
@@ -80,8 +80,6 @@ protected:
void drawObject(uint objectID, uint faceID, uint frameID);
void turnLogic(uint objectID);
- Common::Path _imageName;
-
uint16 _numFaces = 0;
uint16 _numFramesPerTurn = 0;
@@ -133,7 +131,6 @@ protected:
uint32 _timeoutTime = 0;
bool _timedOut = false;
- Graphics::ManagedSurface _image;
Common::Array<uint16> _currentOrder;
uint32 _solveSoundDelayTime = 0;
diff --git a/engines/nancy/action/puzzle/twodialpuzzle.h b/engines/nancy/action/puzzle/twodialpuzzle.h
index 028719572a1..bc5172ea69d 100644
--- a/engines/nancy/action/puzzle/twodialpuzzle.h
+++ b/engines/nancy/action/puzzle/twodialpuzzle.h
@@ -48,8 +48,6 @@ protected:
void runPreNancy12();
void runNancy12();
- Common::Path _imageName;
-
bool _isClockwise[2] = { false, false };
uint16 _startPositions[2] = { 0, 0 };
@@ -81,8 +79,6 @@ protected:
SoundDescription _rotateSounds[2];
- Graphics::ManagedSurface _image;
-
int16 _currentPositions[2] = { 0, 0 };
bool _isSolved = false;
diff --git a/engines/nancy/action/puzzle/typingquizpuzzle.h b/engines/nancy/action/puzzle/typingquizpuzzle.h
index 8b72df9ab38..d8392a71903 100644
--- a/engines/nancy/action/puzzle/typingquizpuzzle.h
+++ b/engines/nancy/action/puzzle/typingquizpuzzle.h
@@ -90,7 +90,6 @@ private:
void triggerSceneChange();
// ---- File data ----
- Common::Path _imageName; // 0x000 puzzle sprite sheet
uint16 _numImageRects = 0; // 0x021
Common::Rect _balloonSrcRects[kMaxImageRects]; // 0x023
Common::Rect _poppedSrcRect; // 0x163 burst sprite
@@ -128,7 +127,6 @@ private:
int16 _flagFail = -1; // 0x55a set otherwise
// ---- Runtime state ----
- Graphics::ManagedSurface _image;
uint16 _fontID = 0; // game default font for the balloon characters
Balloon _balloons[kMaxBalloons];
diff --git a/engines/nancy/action/puzzlerecord.cpp b/engines/nancy/action/puzzlerecord.cpp
index 9a6bb738997..a69cd823ecd 100644
--- a/engines/nancy/action/puzzlerecord.cpp
+++ b/engines/nancy/action/puzzlerecord.cpp
@@ -25,6 +25,7 @@
#include "engines/nancy/cursor.h"
#include "engines/nancy/graphics.h"
#include "engines/nancy/input.h"
+#include "engines/nancy/resource.h"
#include "engines/nancy/sound.h"
#include "engines/nancy/util.h"
@@ -55,11 +56,20 @@ static void appendSceneInfo(Common::String &info, const char *name, const SceneC
Common::String PuzzleRecord::getRecordExtraInfo() const {
Common::String info;
+ if (!_imageName.empty()) {
+ info = "Image " + _imageName.toString();
+ }
+
appendSceneInfo(info, "Solve", _solveScene);
appendSceneInfo(info, "Exit", _exitScene);
return info;
}
+void PuzzleRecord::loadImage() {
+ g_nancy->_resource->loadImage(_imageName, _image);
+ _image.setTransparentColor(_drawSurface.getTransparentColor());
+}
+
void PuzzleRecord::initViewportSurface() {
Common::Rect vpBounds = NancySceneState.getViewport().getBounds();
_drawSurface.create(vpBounds.width(), vpBounds.height(), g_nancy->_graphics->getInputPixelFormat());
diff --git a/engines/nancy/action/puzzlerecord.h b/engines/nancy/action/puzzlerecord.h
index b678e9ef85a..c30ee8dbc91 100644
--- a/engines/nancy/action/puzzlerecord.h
+++ b/engines/nancy/action/puzzlerecord.h
@@ -22,6 +22,10 @@
#ifndef NANCY_ACTION_PUZZLERECORD_H
#define NANCY_ACTION_PUZZLERECORD_H
+#include "common/path.h"
+
+#include "graphics/managed_surface.h"
+
#include "engines/nancy/commontypes.h"
#include "engines/nancy/action/actionrecord.h"
@@ -38,6 +42,9 @@ public:
Common::String getRecordExtraInfo() const override;
protected:
+ // Loads _imageName into _image, keyed to the draw surface's transparent color
+ void loadImage();
+
// Creates a transparent, viewport-sized draw surface and shows it over the viewport
void initViewportSurface();
@@ -66,6 +73,10 @@ protected:
void playSolveSound();
bool isSolveSoundPlaying() const;
+ // The puzzle's sprite sheet
+ Common::Path _imageName;
+ Graphics::ManagedSurface _image;
+
// Scene the puzzle moves to when solved; its flag is set on solve
SceneChangeWithFlag _solveScene;
SoundDescription _solveSound;
More information about the Scummvm-git-logs
mailing list