[Scummvm-git-logs] scummvm master -> 1be746527bf3025857e5e9f1a2b21fd5fc3ae4bd

sev- noreply at scummvm.org
Tue Apr 14 22:09:15 UTC 2026


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

Summary:
b0e2f6c0b4 GUI: Add FluidScroller and VelocityTracker class for physics-based scrolling
1be746527b GUI: Implement fluid scrolling in About dialog


Commit: b0e2f6c0b4ddf60083f11ad43c00cc75bfe45f46
    https://github.com/scummvm/scummvm/commit/b0e2f6c0b4ddf60083f11ad43c00cc75bfe45f46
Author: Mohit Bankar (mohitbankar1212 at gmail.com)
Date: 2026-04-15T00:09:10+02:00

Commit Message:
GUI: Add FluidScroller and VelocityTracker class for physics-based scrolling

These utilities provide momentum, physics-based spring-back, and rubber-banding logic for fluid, iOS-style scrolling interactions.

Changed paths:
  A gui/animation/FluidScroll.cpp
  A gui/animation/FluidScroll.h
    gui/module.mk


diff --git a/gui/animation/FluidScroll.cpp b/gui/animation/FluidScroll.cpp
new file mode 100644
index 00000000000..19220415dd9
--- /dev/null
+++ b/gui/animation/FluidScroll.cpp
@@ -0,0 +1,244 @@
+/* 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/>.
+ *
+ */
+
+/*
+ * Based on the implementation by fluid-scroll repository
+ * at https://github.com/ktiays/fluid-scroll
+ */
+
+#include "common/system.h"
+#include "common/util.h"
+#include "gui/animation/FluidScroll.h"
+
+namespace GUI {
+
+const float FluidScroller::kVelocityThreshold = 0.01f;
+const float FluidScroller::kValueThreshold = 0.1f;
+const float FluidScroller::kDefaultSpringResponse = 0.575f;
+const float FluidScroller::kRubberBandCoefficient = 0.55f;
+const float FluidScroller::kRubberBandStretchFraction = 0.25f;
+const float FluidScroller::kDecelerationRate = 0.998f;
+
+FluidScroller::VelocityTracker::VelocityTracker() {
+	reset();
+}
+
+void FluidScroller::VelocityTracker::reset() {
+	index = 0;
+	count = 0;
+	memset(samples, 0, sizeof(samples));
+}
+
+void FluidScroller::VelocityTracker::addPoint(uint32 time, float position) {
+	samples[index].time = time;
+	samples[index].position = position;
+	index = (index + 1) % kHistorySize;
+	if (count < kHistorySize)
+		count++;
+}
+
+float FluidScroller::VelocityTracker::calculateVelocity() const {
+	if (count < 2)
+		return 0.0f;
+
+	// We look at the last few samples (up to 4) to determine the average velocity
+	float velocities[4];
+	int validVelocities = 0;
+
+	for (int i = 0; i < 4 && i < count - 1; ++i) {
+		int i1 = (index + kHistorySize - 1 - i) % kHistorySize; // current point
+		int i2 = (index + kHistorySize - 2 - i) % kHistorySize; // previous point
+		
+		uint32 dt = samples[i1].time - samples[i2].time;
+
+		if (dt > 0)
+			velocities[validVelocities++] = (samples[i1].position - samples[i2].position) / (float)dt;
+		else
+			break;
+	}
+
+	if (validVelocities == 0)
+		return 0.0f;
+	
+	// Weighted average of historical velocities
+	float totalVelocity = 0.0f;
+	float totalWeight = 0.0f;
+	float weight = 1.0f;
+	for (int i = 0; i < validVelocities; ++i) {
+		totalVelocity += velocities[i] * weight;
+		totalWeight += weight;
+		weight *= 0.6f;
+	}
+	return totalVelocity / totalWeight;
+}
+
+FluidScroller::FluidScroller() : 
+	_mode(kModeNone), 
+	_startTime(0), 
+	_scrollPosRaw(0.0f), 
+	_animationOffset(0.0f), 
+	_maxScroll(0.0f), 
+	_viewportHeight(0),
+	_initialVelocity(0.0f),
+	_lambda(0.0f),
+	_stretchDistance(0.0f),
+	_impactVelocity(0.0f) {
+}
+
+void FluidScroller::setBounds(float maxScroll, int viewportHeight) {
+	_maxScroll = maxScroll;
+	_viewportHeight = viewportHeight;
+}
+
+void FluidScroller::reset() {
+	_mode = kModeNone;
+	_startTime = 0;
+	_initialVelocity = 0.0f;
+	_scrollPosRaw = 0.0f;
+	_velocityTracker.reset();
+}
+
+void FluidScroller::stopAnimation() {
+	_mode = kModeNone;
+	_velocityTracker.reset();
+}
+
+void FluidScroller::feedDrag(uint32 time, int deltaY) {
+	_scrollPosRaw += (float)deltaY;
+	_velocityTracker.addPoint(time, _scrollPosRaw);
+}
+
+float FluidScroller::setPosition(float pos, bool checkBound) {
+	_scrollPosRaw = pos;
+	if (checkBound)
+		checkBoundaries();
+	return getVisualPosition();
+}
+
+void FluidScroller::startFling() {
+	float velocity = _velocityTracker.calculateVelocity();
+	
+	if (fabsf(velocity) < 0.1f) {
+		checkBoundaries();
+		return;
+	}
+
+	_mode = kModeFling;
+	_startTime = g_system->getMillis();
+	_initialVelocity = velocity;
+	_animationOffset = _scrollPosRaw;
+}
+
+void FluidScroller::absorb(float velocity, float distance) {
+	_mode = kModeSpringBack;
+	_startTime = g_system->getMillis();
+	
+	_lambda = 2.0f * (float)M_PI / kDefaultSpringResponse;
+	_stretchDistance = distance;
+
+	// Convert velocity from pixels/ms to pixels/s for the spring formula
+	_impactVelocity = velocity * 1000.0f + _lambda * distance;
+}
+
+bool FluidScroller::update(uint32 time, float &outVisualPos) {
+	if (_mode == kModeNone) {
+		outVisualPos = getVisualPosition();
+		return false;
+	}
+
+	float elapsed = (float)(time - _startTime);
+
+	if (_mode == kModeFling) {
+		float coefficient = powf(kDecelerationRate, elapsed);
+		float velocity = _initialVelocity * coefficient;
+		float offset = _initialVelocity * (1.0f / logf(kDecelerationRate)) * (coefficient - 1.0f);
+
+		if (fabsf(velocity) < kVelocityThreshold) {
+			_mode = kModeNone;
+			checkBoundaries();
+			outVisualPos = getVisualPosition();
+			return _mode != kModeNone;
+		}
+
+		_scrollPosRaw = _animationOffset + offset;
+
+		// Boundaries during fling
+		if (_scrollPosRaw < 0) {
+			absorb(velocity, _scrollPosRaw);
+			_animationOffset = 0;
+		} else if (_scrollPosRaw > _maxScroll) {
+			absorb(velocity, _scrollPosRaw - _maxScroll);
+			_animationOffset = _maxScroll;
+		}
+
+	} else if (_mode == kModeSpringBack) {
+		float t = elapsed / 1000.0f;
+		float offset = (_stretchDistance + _impactVelocity * t) * expf(-_lambda * t);
+		float velocity = getVelocityAt(t);
+
+		if (fabsf(offset) < kValueThreshold && fabsf(velocity) / 1000.0f < kVelocityThreshold) {
+			_mode = kModeNone;
+			_scrollPosRaw = _animationOffset;
+			outVisualPos = getVisualPosition();
+			return false;
+		}
+
+		_scrollPosRaw = _animationOffset + offset;
+	}
+
+	outVisualPos = getVisualPosition();
+	return true;
+}
+
+float FluidScroller::getVisualPosition() const {
+	float rubberBandRange = (float)_viewportHeight * kRubberBandStretchFraction;
+
+	if (_scrollPosRaw < 0)
+		return -calculateRubberBandOffset(-_scrollPosRaw, rubberBandRange);
+	else if (_scrollPosRaw > _maxScroll)
+		return _maxScroll + calculateRubberBandOffset(_scrollPosRaw - _maxScroll, rubberBandRange);
+	
+	return _scrollPosRaw;
+}
+
+void FluidScroller::checkBoundaries() {
+	if (_scrollPosRaw < 0) {
+		absorb(0, _scrollPosRaw);
+		_animationOffset = 0;
+	} else if (_scrollPosRaw > _maxScroll) {
+		absorb(0, _scrollPosRaw - _maxScroll);
+		_animationOffset = _maxScroll;
+	}
+}
+
+float FluidScroller::getVelocityAt(float timeInSeconds) const {
+	if (_mode != kModeSpringBack)
+		return 0.0f;
+	return (_impactVelocity - _lambda * (_stretchDistance + _impactVelocity * timeInSeconds)) * expf(-_lambda * timeInSeconds);
+}
+
+float FluidScroller::calculateRubberBandOffset(float offset, float range) {
+	if (range <= 0)
+		return 0;
+	return (1.0f - (1.0f / ((offset * kRubberBandCoefficient / range) + 1.0f))) * range;
+}
+
+} // End of namespace GUI
diff --git a/gui/animation/FluidScroll.h b/gui/animation/FluidScroll.h
new file mode 100644
index 00000000000..80f1fbb0ec7
--- /dev/null
+++ b/gui/animation/FluidScroll.h
@@ -0,0 +1,142 @@
+/* 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/>.
+ *
+ */
+
+/*
+ * Based on the implementation by fluid-scroll repository
+ * at https://github.com/ktiays/fluid-scroll
+ */
+
+#ifndef GUI_ANIMATION_FLUID_SCROLL_H
+#define GUI_ANIMATION_FLUID_SCROLL_H
+
+#include "common/scummsys.h"
+
+namespace GUI {
+
+class FluidScroller {
+public:
+	FluidScroller();
+	~FluidScroller() {}
+
+	/**
+	 * Configure the constraints for the content
+	 * @param maxScroll The maximum scrollable distance (total height - viewport height)
+	 * @param viewportHeight The height of the scrolling area, used for rubber-band range
+	 */
+	void setBounds(float maxScroll, int viewportHeight);
+
+	void reset();
+
+	// Reset the animation state (fling/spring-back), keeping current position
+	void stopAnimation();
+
+	/**
+	 * Record a pointer movement and update the raw position
+	 * @param time Current system time in ms
+	 * @param deltaY The movement since the last frame
+	 */
+	void feedDrag(uint32 time, int deltaY);
+
+	// Start a fling using the recorded velocity
+	void startFling();
+
+	// Check if there is an active animation (fling or spring-back)
+	bool isAnimating() const { return _mode != kModeNone; }
+
+	/**
+	 * Update the internal animation state
+	 * @param time Current system time in ms
+	 * @param outVisualPos The resulting visual scroll position (including rubber-banding)
+	 * @return True if an animation is active and updated
+	 */
+	bool update(uint32 time, float &outVisualPos);
+
+	float setPosition(float pos, bool checkBound = false);
+
+	// Get the current visual scroll position
+	float getVisualPosition() const;
+
+	// Trigger an elastic spring-back if the current position is out of bounds
+	void checkBoundaries();
+
+private:
+	enum Mode {
+		kModeNone,
+		kModeFling,
+		kModeSpringBack
+	};
+
+	// Velocity tracking
+	struct VelocityTracker {
+		struct Point {
+			uint32 time;
+			float position;
+		};
+		static const int kHistorySize = 20;
+		Point samples[kHistorySize];
+		int index;
+		int count;
+
+		VelocityTracker();
+		void reset();
+		void addPoint(uint32 time, float position);
+		float calculateVelocity() const;
+	};
+
+	VelocityTracker _velocityTracker;
+
+	Mode _mode;
+	uint32 _startTime;
+
+	// Scroll status
+	float _scrollPosRaw;    // Physical position (can go out of bounds)
+	float _animationOffset; // Anchor position used as the starting point for animation offsets
+	float _maxScroll;
+	int _viewportHeight;
+
+	// Fling parameter
+	float _initialVelocity;
+
+	// Spring parameters
+	float _lambda; // Spring stiffness factor
+	float _stretchDistance; // Initial distance beyond the edge when spring-back begins
+	float _impactVelocity;  // Velocity when hitting the boundary
+
+
+	float getVelocityAt(float timeInSeconds) const;
+
+	// Transition from movement to spring-back animation when hitting an edge
+	void absorb(float velocity, float distance);
+
+	// Returns the visual offset to apply when scrolled past an edge
+	static float calculateRubberBandOffset(float offset, float range);
+
+	static const float kRubberBandStretchFraction; // Maximum stretch limit as a fraction of viewport height
+	static const float kDecelerationRate; // Rate at which fling velocity slows down
+	static const float kVelocityThreshold; // Minimum velocity to keep animation running
+	static const float kValueThreshold; // Minimum value difference to keep spring active
+	static const float kDefaultSpringResponse; // Natural response time of the spring
+	static const float kRubberBandCoefficient; // Coefficient for rubber-band stiffness
+};
+
+} // End of namespace GUI
+
+#endif
diff --git a/gui/module.mk b/gui/module.mk
index c5e07660cb3..04df343de0e 100644
--- a/gui/module.mk
+++ b/gui/module.mk
@@ -36,6 +36,7 @@ MODULE_OBJS := \
 	unknown-game-dialog.o \
 	widget.o \
 	animation/Animation.o \
+	animation/FluidScroll.o \
 	animation/RepeatAnimationWrapper.o \
 	animation/SequenceAnimationComposite.o \
 	widgets/editable.o \


Commit: 1be746527bf3025857e5e9f1a2b21fd5fc3ae4bd
    https://github.com/scummvm/scummvm/commit/1be746527bf3025857e5e9f1a2b21fd5fc3ae4bd
Author: Mohit Bankar (mohitbankar1212 at gmail.com)
Date: 2026-04-15T00:09:10+02:00

Commit Message:
GUI: Implement fluid scrolling in About dialog

Changed paths:
    gui/about.cpp
    gui/about.h


diff --git a/gui/about.cpp b/gui/about.cpp
index dcee678d062..64634d7e58e 100644
--- a/gui/about.cpp
+++ b/gui/about.cpp
@@ -32,6 +32,7 @@
 #include "gui/gui-manager.h"
 #include "gui/ThemeEval.h"
 #include "gui/widgets/scrollbar.h"
+#include "gui/animation/FluidScroll.h"
 #include "gui/widget.h"
 
 namespace GUI {
@@ -88,14 +89,19 @@ static const char *const gpl_text[] = {
 
 AboutDialog::AboutDialog(bool inGame)
 	: Dialog(10, 20, 300, 174),
-	  _scrollPos(0), _scrollTime(0), _willClose(false), _autoScroll(true), _inGame(inGame),
+	  _scrollPos(0.0f), _scrollTime(0), _willClose(false), _autoScroll(true), _inGame(inGame),
 	  _isDragging(false), _dragLastY(0) {
 
+	_fluidScroller = new FluidScroller();	
 	_scrollbar = nullptr;
 	_closeButton = nullptr;
 	reflowLayout();
 }
 
+AboutDialog::~AboutDialog() {
+	delete _fluidScroller;
+}
+
 void AboutDialog::buildLines() {
 	_lines.clear();
 
@@ -251,9 +257,10 @@ void AboutDialog::addLine(const Common::U32String &str) {
 
 void AboutDialog::open() {
 	_scrollTime = g_system->getMillis() + kScrollStartDelay;
-	_scrollPos = 0;
+	_scrollPos = 0.0f;
 	_willClose = false;
 
+	_fluidScroller->reset();
 	Dialog::open();
 }
 
@@ -275,9 +282,14 @@ void AboutDialog::drawDialog(DrawLayer layerToDraw) {
 	// TODO: Maybe prerender all of the text into another surface,
 	//       and then simply compose that over the screen surface
 	//       in the right way. Should be even faster...
-	const int firstLine = _scrollPos / _lineHeight;
-	const int lastLine = MIN((_scrollPos + (_textRect.height())) / _lineHeight + 1, (uint32)_lines.size());
-	int y = _y + _textRect.top - (_scrollPos % _lineHeight);
+	float visualScrollPos = _fluidScroller->getVisualPosition();
+	int firstLine = (int)floorf(visualScrollPos / (float)_lineHeight);
+	int lastLine = (int)floorf((visualScrollPos + (float)_textRect.height()) / (float)_lineHeight) + 1;
+	firstLine = CLIP(firstLine, 0, (int)_lines.size());
+	lastLine = CLIP(lastLine, 0, (int)_lines.size());
+
+	float yOffset = visualScrollPos - (float)firstLine * (float)_lineHeight;
+	int y = _y + _textRect.top - (int)yOffset;
 
 	for (int line = firstLine; line < lastLine; line++) {
 		Common::U32String str = _lines[line];
@@ -341,6 +353,18 @@ void AboutDialog::drawDialog(DrawLayer layerToDraw) {
 
 void AboutDialog::handleTickle() {
 	const uint32 t = g_system->getMillis();
+
+	if (_fluidScroller->update(t, _scrollPos)) {
+		if (_scrollbar) {
+			_scrollbar->_currentPos = (int)_scrollPos;
+			_scrollbar->recalc();
+		}
+		drawDialog(kDrawLayerForeground);
+		// Update scrollTime to prevent jump (if auto-scroll resumes)
+		_scrollTime = t;
+		return;
+	}
+
 	int scrollOffset = ((int)t - (int)_scrollTime) / kScrollMillisPerPixel;
 	if (_autoScroll && scrollOffset > 0) {
 		int modifiers = g_system->getEventManager()->getModifierState();
@@ -355,13 +379,16 @@ void AboutDialog::handleTickle() {
 		_scrollTime = t;
 
 		if (_scrollPos < 0) {
-			_scrollPos = 0;
-		} else if ((uint32)_scrollPos > _lines.size() * _lineHeight) {
-			_scrollPos = 0;
+			_scrollPos = 0.0f;
+		} else if (_scrollPos > (float)_lines.size() * (float)_lineHeight) {
+			_scrollPos = 0.0f;
 			_scrollTime += kScrollStartDelay;
 		}
+
+		_fluidScroller->setPosition(_scrollPos);
+
 		if (_scrollbar) {
-			_scrollbar->_currentPos = _scrollPos;
+			_scrollbar->_currentPos = (int)_scrollPos;
 			_scrollbar->recalc();
 		}
 		drawDialog(kDrawLayerForeground);
@@ -369,7 +396,10 @@ void AboutDialog::handleTickle() {
 }
 
 void AboutDialog::handleMouseUp(int x, int y, int button, int clickCount) {
-	_isDragging = false;
+	if (_isDragging) {
+		_isDragging = false;
+		_fluidScroller->startFling();
+	}
 	Dialog::handleMouseUp(x, y, button, clickCount);
 }
 
@@ -377,6 +407,8 @@ void AboutDialog::handleMouseDown(int x, int y, int button, int clickCount) {
 	if (button == 1 && !findWidget(x, y)) {
 		_isDragging = true;
 		_dragLastY = y;
+		_autoScroll = false;
+		_fluidScroller->stopAnimation();
 	}
 	Dialog::handleMouseDown(x, y, button, clickCount);
 }
@@ -388,27 +420,19 @@ void AboutDialog::handleMouseMoved(int x, int y, int button) {
 
 		if (deltaY != 0) {
 			_autoScroll = false;
-			int buttonHeight = g_gui.xmlEval()->getVar("Globals.Button.Height", 24);
-			int visibleHeight = _scrollbar ? _scrollbar->_entriesPerPage : (_h - buttonHeight - 20 - _yOff);
-			int maxScroll = MAX(0, (int)(_lines.size() * _lineHeight) - visibleHeight);
-
-			_scrollPos += deltaY;
-
-			if (_scrollPos < 0)
-				_scrollPos = 0;
-			else if (_scrollPos > maxScroll)
-				_scrollPos = maxScroll;
+			_fluidScroller->feedDrag(g_system->getMillis(), deltaY);
+			_scrollPos = _fluidScroller->getVisualPosition();
 
 			if (_scrollbar) {
-				_scrollbar->_currentPos = _scrollPos;
+				_scrollbar->_currentPos = (int)_scrollPos;
 				_scrollbar->recalc();
 			}
 
 			drawDialog(kDrawLayerForeground);
 		}
+	} else {
+		Dialog::handleMouseMoved(x, y, button);
 	}
-
-	Dialog::handleMouseMoved(x, y, button);
 }
 
 void AboutDialog::handleMouseWheel(int x, int y, int direction) {
@@ -418,19 +442,13 @@ void AboutDialog::handleMouseWheel(int x, int y, int direction) {
 		return;
 
 	_autoScroll = false;
-
-	int buttonHeight = g_gui.xmlEval()->getVar("Globals.Button.Height", 24);
-	int visibleHeight = _scrollbar ? _scrollbar->_entriesPerPage : (_h - buttonHeight - 20 - _yOff);
-	int maxScroll = MAX(0, (int)(_lines.size() * _lineHeight) - visibleHeight);
+	_fluidScroller->stopAnimation();
 
 	_scrollPos += stepping;
-	if (_scrollPos < 0)
-		_scrollPos = 0;
-	else if (_scrollPos > maxScroll)
-		_scrollPos = maxScroll;
+	_scrollPos = _fluidScroller->setPosition(_scrollPos, true);
 
 	if (_scrollbar) {
-		_scrollbar->_currentPos = _scrollPos;
+		_scrollbar->_currentPos = (int)_scrollPos;
 		_scrollbar->recalc();
 	}
 
@@ -439,8 +457,10 @@ void AboutDialog::handleMouseWheel(int x, int y, int direction) {
 
 void AboutDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) {
 	if (cmd == kSetPositionCmd) {
-		_scrollPos = data;
+		_scrollPos = (float)data;
 		_autoScroll = false;
+		_fluidScroller->stopAnimation();
+		_scrollPos = _fluidScroller->setPosition(_scrollPos, false);
 		drawDialog(kDrawLayerForeground);
 	} else if (cmd == kCloseCmd) {
 		close();
@@ -522,6 +542,9 @@ void AboutDialog::reflowLayout() {
 	screenArea.constrain(_x, _y, _w, _h);
 
 	buildLines();
+
+	int maxScroll = MAX(0, (int)(_lines.size() * _lineHeight) - _textRect.height());
+	_fluidScroller->setBounds((float)maxScroll, _textRect.height());
 }
 
 
diff --git a/gui/about.h b/gui/about.h
index 253a9982b12..693c6ec2516 100644
--- a/gui/about.h
+++ b/gui/about.h
@@ -33,10 +33,11 @@ namespace GUI {
 class EEHandler;
 class ScrollBarWidget;
 class ButtonWidget;
+class FluidScroller;
 
 class AboutDialog : public Dialog {
 protected:
-	int	       _scrollPos;
+	float	       _scrollPos;
 	uint32         _scrollTime;
 	Common::U32StringArray _lines;
 	uint32         _lineHeight;
@@ -48,6 +49,7 @@ protected:
 	bool _isDragging;
 	int _dragLastY;
 
+	FluidScroller *_fluidScroller;
 	ScrollBarWidget *_scrollbar;
 	ButtonWidget *_closeButton;
 	Common::Rect _textRect;
@@ -59,6 +61,7 @@ protected:
 
 public:
 	AboutDialog(bool inGame = false);
+	~AboutDialog() override;
 
 	void open() override;
 	void close() override;




More information about the Scummvm-git-logs mailing list