[Scummvm-git-logs] scummvm master -> bf8c469fd84e4dbab92925bf32e2fc205b08f921
fracturehill
noreply at scummvm.org
Fri Jul 14 12:48:37 UTC 2023
This automated email contains information about 2 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
893545f9bf NANCY: Implement alarm clock
bf8c469fd8 NANCY: Disable UI clock in alarm clock scenes
Commit: 893545f9bf82d0196efa4e1e82a00950e1d2912c
https://github.com/scummvm/scummvm/commit/893545f9bf82d0196efa4e1e82a00950e1d2912c
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2023-07-14T15:47:34+03:00
Commit Message:
NANCY: Implement alarm clock
Implemented the SetPlayerClock action record, which
is responsible for the alarm clock introduced in nancy3.
Changed paths:
A engines/nancy/action/setplayerclock.cpp
A engines/nancy/action/setplayerclock.h
engines/nancy/action/arfactory.cpp
engines/nancy/module.mk
diff --git a/engines/nancy/action/arfactory.cpp b/engines/nancy/action/arfactory.cpp
index d94d809c34f..099a4e2af8f 100644
--- a/engines/nancy/action/arfactory.cpp
+++ b/engines/nancy/action/arfactory.cpp
@@ -36,6 +36,7 @@
#include "engines/nancy/action/overridelockpuzzle.h"
#include "engines/nancy/action/bombpuzzle.h"
#include "engines/nancy/action/soundequalizerpuzzle.h"
+#include "engines/nancy/action/setplayerclock.h"
#include "engines/nancy/state/scene.h"
@@ -153,6 +154,8 @@ ActionRecord *ActionManager::createActionRecord(uint16 type) {
return new StopSound(); // StopAndUnloadSound, but we always unload
case 160:
return new HintSystem();
+ case 170:
+ return new SetPlayerClock();
case 200:
return new SoundEqualizerPuzzle();
case 201:
diff --git a/engines/nancy/action/setplayerclock.cpp b/engines/nancy/action/setplayerclock.cpp
new file mode 100644
index 00000000000..f74a0f65252
--- /dev/null
+++ b/engines/nancy/action/setplayerclock.cpp
@@ -0,0 +1,275 @@
+/* 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/action/setplayerclock.h"
+#include "engines/nancy/state/scene.h"
+
+#include "engines/nancy/nancy.h"
+#include "engines/nancy/input.h"
+#include "engines/nancy/graphics.h"
+#include "engines/nancy/util.h"
+#include "engines/nancy/resource.h"
+#include "engines/nancy/sound.h"
+
+namespace Nancy {
+namespace Action {
+
+void SetPlayerClock::init() {
+ Common::Rect screenBounds = NancySceneState.getViewport().getBounds();
+ _drawSurface.create(screenBounds.width(), screenBounds.height(), g_nancy->_graphicsManager->getInputPixelFormat());
+ _drawSurface.clear(g_nancy->_graphicsManager->getTransColor());
+ setTransparent(true);
+ setVisible(true);
+ moveTo(screenBounds);
+
+ g_nancy->_resource->loadImage(_imageName, _image);
+ _image.setTransparentColor(_drawSurface.getTransparentColor());
+}
+
+void SetPlayerClock::readData(Common::SeekableReadStream &stream) {
+ readFilename(stream, _imageName);
+
+ readRect(stream, _minutesDest);
+ readRect(stream, _hoursDest);
+ readRect(stream, _AMPMDest);
+ readRect(stream, _timeButtonDest);
+ readRect(stream, _alarmButtonDest);
+ readRect(stream, _setButtonDest);
+ readRect(stream, _cancelButtonDest);
+ readRect(stream, _upButtonDest);
+ readRect(stream, _downButtonDest);
+ readRect(stream, _modeLightDest);
+
+ readRectArray(stream, _minutesSrc, 4);
+ readRectArray(stream, _hoursSrc, 12);
+
+ readRect(stream, _AMSrc);
+ readRect(stream, _PMSrc);
+ readRect(stream, _timeButtonSrc);
+ readRect(stream, _alarmButtonSrc);
+ readRect(stream, _setButtonSrc);
+ readRect(stream, _cancelButtonSrc);
+ readRect(stream, _upButtonSrc);
+ readRect(stream, _downButtonSrc);
+ readRect(stream, _timeLightSrc);
+ readRect(stream, _alarmLightSrc);
+
+ stream.skip(2);
+
+ _buttonSound.readNormal(stream);
+ _alarmSetScene.readData(stream);
+ _alarmSoundDelay = stream.readUint16LE();
+ _alarmRingSound.readNormal(stream);
+ _exitScene.readData(stream);
+}
+
+void SetPlayerClock::execute() {
+ switch (_state) {
+ case kBegin:
+ init();
+ registerGraphics();
+
+ g_nancy->_sound->loadSound(_buttonSound);
+ g_nancy->_sound->loadSound(_alarmRingSound);
+
+ _alarmHours = NancySceneState.getPlayerTime().getHours();
+
+ _state = kRun;
+ // fall through
+ case kRun:
+ if (_alarmState == kTimeMode) {
+ Time currentTime = NancySceneState.getPlayerTime();
+ int8 hours = currentTime.getHours();
+ int8 minutes = currentTime.getMinutes();
+
+ if (_clearButton && !g_nancy->_sound->isSoundPlaying(_buttonSound)) {
+ _drawSurface.fillRect(_timeButtonDest, _drawSurface.getTransparentColor());
+ _drawSurface.fillRect(_modeLightDest, _drawSurface.getTransparentColor());
+ _drawSurface.blitFrom(_image, _timeLightSrc, _modeLightDest);
+ _clearButton = false;
+ _needsRedraw = true;
+ }
+
+ if (_lastDrawnHours != hours || _lastDrawnMinutes / 15 != minutes / 15) {
+ drawTime(currentTime.getHours(), currentTime.getMinutes());
+ _lastDrawnHours = hours;
+ _lastDrawnMinutes = minutes;
+ }
+ } else {
+ if (_clearButton && !g_nancy->_sound->isSoundPlaying(_buttonSound)) {
+ _drawSurface.fillRect(_alarmButtonDest, _drawSurface.getTransparentColor());
+ _drawSurface.fillRect(_upButtonDest, _drawSurface.getTransparentColor());
+ _drawSurface.fillRect(_downButtonDest, _drawSurface.getTransparentColor());
+ _drawSurface.fillRect(_modeLightDest, _drawSurface.getTransparentColor());
+ _drawSurface.blitFrom(_image, _alarmLightSrc, _modeLightDest);
+ drawTime(_alarmHours, 0);
+ _clearButton = false;
+ _needsRedraw = true;
+ }
+ }
+
+ break;
+ case kActionTrigger:
+ if (g_nancy->_sound->isSoundPlaying(_buttonSound)) {
+ return;
+ }
+
+ if (_clearButton) {
+ g_nancy->_sound->stopSound(_buttonSound);
+ _drawSurface.fillRect(_setButtonDest, _drawSurface.getTransparentColor());
+ _clearButton = false;
+ }
+
+ if (_alarmState == kWait) {
+ // Alarm has been set, wait for timer
+ if (g_system->getMillis() > _sceneChangeTime) {
+ NancySceneState.setPlayerTime(_alarmHours * 3600000, false);
+ _alarmSetScene.execute();
+ finishExecution();
+ }
+ } else {
+ // Cancel button pressed, go to exit scene
+ _exitScene.execute();
+ finishExecution();
+ }
+ }
+}
+
+void SetPlayerClock::handleInput(NancyInput &input) {
+ if (_alarmState == kWait) {
+ return;
+ }
+
+ // Cancel button is active in both time and alarm mode
+ if (NancySceneState.getViewport().convertViewportToScreen(_cancelButtonDest).contains(input.mousePos)) {
+ g_nancy->_cursorManager->setCursorType(CursorManager::kHotspot);
+
+ if (input.input & NancyInput::kLeftMouseButtonUp) {
+ // Cancel button pressed
+ _drawSurface.blitFrom(_image, _cancelButtonSrc, _cancelButtonDest);
+ _needsRedraw = true;
+
+ g_nancy->_sound->playSound(_buttonSound);
+
+ _state = kActionTrigger;
+ return;
+ }
+ }
+
+ if (_alarmState == kTimeMode) {
+ // Alarm button is active only in time mode
+ if (NancySceneState.getViewport().convertViewportToScreen(_alarmButtonDest).contains(input.mousePos)) {
+ g_nancy->_cursorManager->setCursorType(CursorManager::kHotspot);
+
+ if (input.input & NancyInput::kLeftMouseButtonUp) {
+ // Alarm button pressed
+ _drawSurface.blitFrom(_image, _alarmButtonSrc, _alarmButtonDest);
+ _needsRedraw = true;
+
+ g_nancy->_sound->playSound(_buttonSound);
+ _lastDrawnHours = _lastDrawnMinutes = -1;
+
+ _alarmState = kAlarmMode;
+ _clearButton = true;
+ return;
+ }
+ }
+ } else {
+ if (NancySceneState.getViewport().convertViewportToScreen(_timeButtonDest).contains(input.mousePos)) {
+ // Time button is active only in alarm mode
+ g_nancy->_cursorManager->setCursorType(CursorManager::kHotspot);
+
+ if (input.input & NancyInput::kLeftMouseButtonUp) {
+ // Alarm button pressed
+ _drawSurface.blitFrom(_image, _timeButtonSrc, _timeButtonDest);
+ _needsRedraw = true;
+
+ g_nancy->_sound->playSound(_buttonSound);
+
+ _alarmState = kTimeMode;
+ _clearButton = true;
+ return;
+ }
+ } else if (NancySceneState.getViewport().convertViewportToScreen(_upButtonDest).contains(input.mousePos)) {
+ // Up button is active only in alarm mode
+ g_nancy->_cursorManager->setCursorType(CursorManager::kHotspot);
+
+ if (input.input & NancyInput::kLeftMouseButtonUp) {
+ // Up button pressed
+ _drawSurface.blitFrom(_image, _upButtonSrc, _upButtonDest);
+ _needsRedraw = true;
+
+ g_nancy->_sound->playSound(_buttonSound);
+ _alarmHours = _alarmHours + 1 > 23 ? 0 : _alarmHours + 1;
+
+ _clearButton = true;
+ return;
+ }
+ } else if (NancySceneState.getViewport().convertViewportToScreen(_downButtonDest).contains(input.mousePos)) {
+ // Down button is active only in alarm mode
+ g_nancy->_cursorManager->setCursorType(CursorManager::kHotspot);
+
+ if (input.input & NancyInput::kLeftMouseButtonUp) {
+ // Down button pressed
+ _drawSurface.blitFrom(_image, _downButtonSrc, _downButtonDest);
+ _needsRedraw = true;
+
+ g_nancy->_sound->playSound(_buttonSound);
+ _alarmHours = _alarmHours - 1 < 0 ? 23 : _alarmHours - 1;
+
+ _clearButton = true;
+ return;
+ }
+ } else if (NancySceneState.getViewport().convertViewportToScreen(_setButtonDest).contains(input.mousePos)) {
+ // Set button is active only in alarm mode
+ g_nancy->_cursorManager->setCursorType(CursorManager::kHotspot);
+
+ if (input.input & NancyInput::kLeftMouseButtonUp) {
+ // Down button pressed
+ _drawSurface.blitFrom(_image, _setButtonSrc, _setButtonDest);
+ _needsRedraw = true;
+
+ g_nancy->_sound->playSound(_buttonSound);
+
+ _clearButton = true;
+ _state = kActionTrigger;
+ _alarmState = kWait;
+ _sceneChangeTime = g_system->getMillis() + (_alarmSoundDelay * 1000);
+ return;
+ }
+ }
+ }
+}
+
+void SetPlayerClock::drawTime(uint16 hours, uint16 minutes) {
+ _drawSurface.fillRect(_hoursDest, _drawSurface.getTransparentColor());
+ _drawSurface.fillRect(_minutesDest, _drawSurface.getTransparentColor());
+ _drawSurface.fillRect(_AMPMDest, _drawSurface.getTransparentColor());
+
+ _drawSurface.blitFrom(_image, _hoursSrc[(hours - 1 < 0 ? 11 : hours - 1) % 12], _hoursDest);
+ _drawSurface.blitFrom(_image, _minutesSrc[minutes / 15], _minutesDest);
+ _drawSurface.blitFrom(_image, hours / 12 == 0 ? _AMSrc : _PMSrc, _AMPMDest);
+
+ _needsRedraw = true;
+}
+
+} // End of namespace Action
+} // End of namespace Nancy
diff --git a/engines/nancy/action/setplayerclock.h b/engines/nancy/action/setplayerclock.h
new file mode 100644
index 00000000000..0702bb42a94
--- /dev/null
+++ b/engines/nancy/action/setplayerclock.h
@@ -0,0 +1,95 @@
+/* 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_SETPLAYERCLOCK_H
+#define NANCY_ACTION_SETPLAYERCLOCK_H
+
+#include "engines/nancy/action/actionrecord.h"
+
+namespace Nancy {
+namespace Action {
+
+// Action record implementing an alarm clock. First used in nancy3
+class SetPlayerClock : public RenderActionRecord {
+public:
+ enum AlarmState { kTimeMode, kAlarmMode, kWait };
+ SetPlayerClock() : RenderActionRecord(7) {}
+ virtual ~SetPlayerClock() {}
+
+ void init() override;
+
+ void readData(Common::SeekableReadStream &stream) override;
+ void execute() override;
+ void handleInput(NancyInput &input) override;
+
+protected:
+ Common::String getRecordTypeName() const override { return "SetPlayerClock"; }
+ bool isViewportRelative() const override { return true; }
+
+ void drawTime(uint16 hours, uint16 minutes);
+
+ Common::String _imageName;
+
+ Common::Rect _minutesDest;
+ Common::Rect _hoursDest;
+ Common::Rect _AMPMDest;
+ Common::Rect _timeButtonDest;
+ Common::Rect _alarmButtonDest;
+ Common::Rect _setButtonDest;
+ Common::Rect _cancelButtonDest;
+ Common::Rect _upButtonDest;
+ Common::Rect _downButtonDest;
+ Common::Rect _modeLightDest;
+
+ Common::Array<Common::Rect> _minutesSrc;
+ Common::Array<Common::Rect> _hoursSrc;
+ Common::Rect _AMSrc;
+ Common::Rect _PMSrc;
+ Common::Rect _timeButtonSrc;
+ Common::Rect _alarmButtonSrc;
+ Common::Rect _setButtonSrc;
+ Common::Rect _cancelButtonSrc;
+ Common::Rect _upButtonSrc;
+ Common::Rect _downButtonSrc;
+ Common::Rect _timeLightSrc;
+ Common::Rect _alarmLightSrc;
+
+ SoundDescription _buttonSound;
+ SceneChangeWithFlag _alarmSetScene;
+ uint16 _alarmSoundDelay;
+ SoundDescription _alarmRingSound; // NO SOUND in MHM
+ SceneChangeWithFlag _exitScene;
+
+ Graphics::ManagedSurface _image;
+
+ int8 _lastDrawnHours = -1;
+ int8 _lastDrawnMinutes = -1;
+ int8 _alarmHours = -1;
+ bool _clearButton = true;
+ Time _sceneChangeTime;
+
+ AlarmState _alarmState = kTimeMode;
+};
+
+} // End of namespace Action
+} // End of namespace Nancy
+
+#endif // NANCY_ACTION_SETPLAYERCLOCK_H
diff --git a/engines/nancy/module.mk b/engines/nancy/module.mk
index d06009945d4..c2fc6266216 100644
--- a/engines/nancy/module.mk
+++ b/engines/nancy/module.mk
@@ -17,6 +17,7 @@ MODULE_OBJS = \
action/riddlepuzzle.o \
action/secondarymovie.o \
action/secondaryvideo.o \
+ action/setplayerclock.o \
action/sliderpuzzle.o \
action/soundequalizerpuzzle.o \
action/towerpuzzle.o \
Commit: bf8c469fd84e4dbab92925bf32e2fc205b08f921
https://github.com/scummvm/scummvm/commit/bf8c469fd84e4dbab92925bf32e2fc205b08f921
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2023-07-14T15:47:34+03:00
Commit Message:
NANCY: Disable UI clock in alarm clock scenes
Added facilities to disable the UI clock (in the bottom
left corner of the screen) when playing an alarm clock scene.
Changed paths:
engines/nancy/action/setplayerclock.cpp
engines/nancy/action/setplayerclock.h
engines/nancy/state/scene.h
engines/nancy/ui/clock.cpp
engines/nancy/ui/clock.h
diff --git a/engines/nancy/action/setplayerclock.cpp b/engines/nancy/action/setplayerclock.cpp
index f74a0f65252..49403395632 100644
--- a/engines/nancy/action/setplayerclock.cpp
+++ b/engines/nancy/action/setplayerclock.cpp
@@ -21,6 +21,7 @@
#include "engines/nancy/action/setplayerclock.h"
#include "engines/nancy/state/scene.h"
+#include "engines/nancy/ui/clock.h"
#include "engines/nancy/nancy.h"
#include "engines/nancy/input.h"
@@ -32,6 +33,13 @@
namespace Nancy {
namespace Action {
+SetPlayerClock::~SetPlayerClock() {
+ Nancy::UI::Clock *clock = NancySceneState.getClock();
+ if (clock) {
+ clock->lockClock(false);
+ }
+}
+
void SetPlayerClock::init() {
Common::Rect screenBounds = NancySceneState.getViewport().getBounds();
_drawSurface.create(screenBounds.width(), screenBounds.height(), g_nancy->_graphicsManager->getInputPixelFormat());
@@ -83,7 +91,7 @@ void SetPlayerClock::readData(Common::SeekableReadStream &stream) {
void SetPlayerClock::execute() {
switch (_state) {
- case kBegin:
+ case kBegin: {
init();
registerGraphics();
@@ -91,8 +99,14 @@ void SetPlayerClock::execute() {
g_nancy->_sound->loadSound(_alarmRingSound);
_alarmHours = NancySceneState.getPlayerTime().getHours();
+
+ Nancy::UI::Clock *clock = NancySceneState.getClock();
+ if (clock) {
+ clock->lockClock(true);
+ }
_state = kRun;
+ }
// fall through
case kRun:
if (_alarmState == kTimeMode) {
diff --git a/engines/nancy/action/setplayerclock.h b/engines/nancy/action/setplayerclock.h
index 0702bb42a94..d0eb9ae2fb8 100644
--- a/engines/nancy/action/setplayerclock.h
+++ b/engines/nancy/action/setplayerclock.h
@@ -32,7 +32,7 @@ class SetPlayerClock : public RenderActionRecord {
public:
enum AlarmState { kTimeMode, kAlarmMode, kWait };
SetPlayerClock() : RenderActionRecord(7) {}
- virtual ~SetPlayerClock() {}
+ virtual ~SetPlayerClock();
void init() override;
diff --git a/engines/nancy/state/scene.h b/engines/nancy/state/scene.h
index 506b0044a57..3dfedf8bd2e 100644
--- a/engines/nancy/state/scene.h
+++ b/engines/nancy/state/scene.h
@@ -176,6 +176,7 @@ public:
UI::Viewport &getViewport() { return _viewport; }
UI::Textbox &getTextbox() { return _textbox; }
UI::InventoryBox &getInventoryBox() { return _inventoryBox; }
+ UI::Clock *getClock() { return _clock; }
Action::ActionManager &getActionManager() { return _actionManager; }
diff --git a/engines/nancy/ui/clock.cpp b/engines/nancy/ui/clock.cpp
index 71487abc59a..27ec3a6fda5 100644
--- a/engines/nancy/ui/clock.cpp
+++ b/engines/nancy/ui/clock.cpp
@@ -37,7 +37,8 @@ namespace UI {
Clock::Clock() : RenderObject(g_nancy->getGameType() == kGameTypeVampire ? 11 : 10),
_animation(g_nancy->getGameType() == kGameTypeVampire ? 10 : 11, this),
_staticImage(9),
- _clockData(nullptr) {}
+ _clockData(nullptr),
+ _locked(false) {}
void Clock::init() {
Graphics::ManagedSurface &object0 = g_nancy->_graphicsManager->_object0;
@@ -99,7 +100,9 @@ void Clock::updateGraphics() {
}
void Clock::handleInput(NancyInput &input) {
- _animation.handleInput(input);
+ if (!_locked) {
+ _animation.handleInput(input);
+ }
}
void Clock::drawClockHands() {
@@ -142,7 +145,7 @@ void Clock::ClockAnim::init() {
void Clock::ClockAnim::updateGraphics() {
AnimatedButton::updateGraphics();
- if (_isOpen && !isPlaying() && g_nancy->getTotalPlayTime() > _closeTime && _isVisible) {
+ if (_isOpen && !isPlaying() && (g_nancy->getTotalPlayTime() > _closeTime || _owner->_locked) && _isVisible) {
setOpen(false);
if (g_nancy->getGameType() == kGameTypeVampire) {
_owner->_staticImage.setVisible(false);
diff --git a/engines/nancy/ui/clock.h b/engines/nancy/ui/clock.h
index 9a41bd80ec2..76361c7b42a 100644
--- a/engines/nancy/ui/clock.h
+++ b/engines/nancy/ui/clock.h
@@ -45,6 +45,9 @@ public:
void updateGraphics() override;
void handleInput(NancyInput &input);
+ // Used to disable the UI clock when a scene can change the in-game time (e.g. SetPlayerClock)
+ void lockClock(bool val) { _locked = val; }
+
void drawClockHands();
protected:
@@ -72,6 +75,7 @@ protected:
RenderObject _staticImage;
Time _playerTime;
+ bool _locked;
};
} // End of namespace UI
More information about the Scummvm-git-logs
mailing list