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

mikrosk noreply at scummvm.org
Mon Dec 30 17:38:07 UTC 2024


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:
b779b2038f JANITORIAL: ATARI: Unify enum names
a4ed12b04d BACKENDS: ATARI: Cleanup overlay code


Commit: b779b2038fd923b0cdf524facde938f15727541d
    https://github.com/scummvm/scummvm/commit/b779b2038fd923b0cdf524facde938f15727541d
Author: Miro Kropacek (miro.kropacek at gmail.com)
Date: 2024-12-30T18:37:54+01:00

Commit Message:
JANITORIAL: ATARI: Unify enum names

Changed paths:
    backends/graphics/atari/atari-graphics.cpp
    backends/graphics/atari/atari-graphics.h


diff --git a/backends/graphics/atari/atari-graphics.cpp b/backends/graphics/atari/atari-graphics.cpp
index 491898a2492..cc989e1baea 100644
--- a/backends/graphics/atari/atari-graphics.cpp
+++ b/backends/graphics/atari/atari-graphics.cpp
@@ -364,7 +364,7 @@ bool AtariGraphicsManager::getFeatureState(OSystem::Feature f) const {
 bool AtariGraphicsManager::setGraphicsMode(int mode, uint flags) {
 	atari_debug("setGraphicsMode: %d, %d", mode, flags);
 
-	_pendingState.mode = (GraphicsMode)mode;
+	_pendingState.mode = mode;
 
 	if (!_pendingState.inTransaction)
 		return endGFXTransaction() == OSystem::kTransactionSuccess;
@@ -400,8 +400,8 @@ OSystem::TransactionError AtariGraphicsManager::endGFXTransaction() {
 	int error = OSystem::TransactionError::kTransactionSuccess;
 	bool hasPendingGraphicsMode = false;	// no need to have a global flag
 
-	if (_pendingState.mode != GraphicsMode::Unknown) {
-		if (_pendingState.mode < GraphicsMode::DirectRendering || _pendingState.mode > GraphicsMode::TripleBuffering) {
+	if (_pendingState.mode != kUnknownMode) {
+		if (_pendingState.mode < kDirectRendering || _pendingState.mode > kTripleBuffering) {
 			error |= OSystem::TransactionError::kTransactionModeSwitchFailed;
 		} else if (_currentState.mode != _pendingState.mode) {
 			hasPendingGraphicsMode = true;
@@ -424,7 +424,7 @@ OSystem::TransactionError AtariGraphicsManager::endGFXTransaction() {
 		error |= OSystem::TransactionError::kTransactionFormatNotSupported;
 
 	if (error != OSystem::TransactionError::kTransactionSuccess) {
-		atari_warning("endGFXTransaction failed: %02x", (int)error);
+		atari_warning("endGFXTransaction failed: %02x", error);
 		_pendingScreenChanges.clearTransaction();
 		return static_cast<OSystem::TransactionError>(error);
 	}
@@ -457,11 +457,11 @@ OSystem::TransactionError AtariGraphicsManager::endGFXTransaction() {
 		_chunkySurface.init(_currentState.width, _currentState.height, _currentState.width,
 			_chunkySurface.getPixels(), _currentState.format);
 
-		_screen[FRONT_BUFFER]->reset(_currentState.width, _currentState.height, 8, true);
-		_screen[BACK_BUFFER1]->reset(_currentState.width, _currentState.height, 8, true);
-		_screen[BACK_BUFFER2]->reset(_currentState.width, _currentState.height, 8, true);
-		_workScreen = _screen[_currentState.mode <= GraphicsMode::SingleBuffering ? FRONT_BUFFER : BACK_BUFFER1];
-		_pendingScreenChanges.setScreenSurface(&_screen[FRONT_BUFFER]->surf);
+		_screen[kFrontBuffer]->reset(_currentState.width, _currentState.height, 8, true);
+		_screen[kBackBuffer1]->reset(_currentState.width, _currentState.height, 8, true);
+		_screen[kBackBuffer2]->reset(_currentState.width, _currentState.height, 8, true);
+		_workScreen = _screen[_currentState.mode <= kSingleBuffering ? kFrontBuffer : kBackBuffer1];
+		_pendingScreenChanges.setScreenSurface(&_screen[kFrontBuffer]->surf);
 
 		_palette.clear();
 		_pendingScreenChanges.queuePalette();
@@ -526,8 +526,8 @@ void AtariGraphicsManager::copyRectToScreen(const void *buf, int pitch, int x, i
 
 	copyRectToScreenInternal(buf, pitch, x, y, w, h,
 		PIXELFORMAT_CLUT8,
-		_currentState.mode == GraphicsMode::DirectRendering,
-		_currentState.mode == GraphicsMode::TripleBuffering);
+		_currentState.mode == kDirectRendering,
+		_currentState.mode == kTripleBuffering);
 }
 
 // this is not really locking anything but it's an useful function
@@ -537,7 +537,7 @@ Graphics::Surface *AtariGraphicsManager::lockScreen() {
 
 	if (isOverlayVisible() && !isOverlayDirectRendering())
 		return &_overlaySurface;
-	else if ((isOverlayVisible() && isOverlayDirectRendering()) || _currentState.mode == GraphicsMode::DirectRendering)
+	else if ((isOverlayVisible() && isOverlayDirectRendering()) || _currentState.mode == kDirectRendering)
 		return _workScreen->offsettedSurf;
 	else
 		return &_chunkySurface;
@@ -552,9 +552,9 @@ void AtariGraphicsManager::unlockScreen() {
 	const Common::Rect rect = alignRect(0, 0, dstSurface.w, dstSurface.h);
 	_workScreen->addDirtyRect(dstSurface, rect, directRendering);
 
-	if (_currentState.mode == GraphicsMode::TripleBuffering) {
-		_screen[BACK_BUFFER2]->addDirtyRect(dstSurface, rect, directRendering);
-		_screen[FRONT_BUFFER]->addDirtyRect(dstSurface, rect, directRendering);
+	if (_currentState.mode == kTripleBuffering) {
+		_screen[kBackBuffer2]->addDirtyRect(dstSurface, rect, directRendering);
+		_screen[kFrontBuffer]->addDirtyRect(dstSurface, rect, directRendering);
 	}
 }
 
@@ -625,27 +625,27 @@ void AtariGraphicsManager::updateScreen() {
 	bool screenUpdated = false;
 
 	if (isOverlayVisible()) {
-		assert(_workScreen == _screen[OVERLAY_BUFFER]);
+		assert(_workScreen == _screen[kOverlayBuffer]);
 		if (isOverlayDirectRendering())
 			screenUpdated = updateScreenInternal(Graphics::Surface());
 		else
 			screenUpdated = updateScreenInternal(_overlaySurface);
 	} else {
 		switch (_currentState.mode) {
-		case GraphicsMode::DirectRendering:
-			assert(_workScreen == _screen[FRONT_BUFFER]);
+		case kDirectRendering:
+			assert(_workScreen == _screen[kFrontBuffer]);
 			screenUpdated = updateScreenInternal(Graphics::Surface());
 			break;
-		case GraphicsMode::SingleBuffering:
-			assert(_workScreen == _screen[FRONT_BUFFER]);
+		case kSingleBuffering:
+			assert(_workScreen == _screen[kFrontBuffer]);
 			screenUpdated = updateScreenInternal(_chunkySurface);
 			break;
-		case GraphicsMode::TripleBuffering:
-			assert(_workScreen == _screen[BACK_BUFFER1]);
+		case kTripleBuffering:
+			assert(_workScreen == _screen[kBackBuffer1]);
 			screenUpdated = updateScreenInternal(_chunkySurface);
 			break;
 		default:
-			atari_warning("Unknown graphics mode %d", (int)_currentState.mode);
+			atari_warning("Unknown graphics mode %d", _currentState.mode);
 		}
 	}
 
@@ -667,7 +667,7 @@ void AtariGraphicsManager::updateScreen() {
 
 	if (screenUpdated
 		&& !isOverlayVisible()
-		&& _currentState.mode == GraphicsMode::TripleBuffering) {
+		&& _currentState.mode == kTripleBuffering) {
 		// Triple buffer:
 		// - alternate BACK_BUFFER1 and BACK_BUFFER2
 		// - present BACK_BUFFER1 (as BACK_BUFFER2)
@@ -676,19 +676,19 @@ void AtariGraphicsManager::updateScreen() {
 
 		if (s_screenSurf == nullptr) {
 			// BACK_BUFFER2 has been set; guard it from overwriting while presented
-			Screen *tmp = _screen[BACK_BUFFER2];
-			_screen[BACK_BUFFER2] = _screen[FRONT_BUFFER];
-			_screen[FRONT_BUFFER] = tmp;
+			Screen *tmp = _screen[kBackBuffer2];
+			_screen[kBackBuffer2] = _screen[kFrontBuffer];
+			_screen[kFrontBuffer] = tmp;
 		}
 
 		// swap back buffers
-		Screen *tmp = _screen[BACK_BUFFER1];
-		_screen[BACK_BUFFER1] = _screen[BACK_BUFFER2];
-		_screen[BACK_BUFFER2] = tmp;
+		Screen *tmp = _screen[kBackBuffer1];
+		_screen[kBackBuffer1] = _screen[kBackBuffer2];
+		_screen[kBackBuffer2] = tmp;
 
 		// queue BACK_BUFFER2 with the most recent frame content
-		_pendingScreenChanges.setScreenSurface(&_screen[BACK_BUFFER2]->surf);
-		_workScreen = _screen[BACK_BUFFER1];
+		_pendingScreenChanges.setScreenSurface(&_screen[kBackBuffer2]->surf);
+		_workScreen = _screen[kBackBuffer1];
 	}
 
 #ifdef SCREEN_ACTIVE
@@ -732,12 +732,12 @@ void AtariGraphicsManager::showOverlay(bool inGUI) {
 	if (_overlayVisible)
 		return;
 
-	if (_currentState.mode == GraphicsMode::DirectRendering) {
+	if (_currentState.mode == kDirectRendering) {
 		_workScreen->cursor.restoreBackground(Graphics::Surface(), true);
 	}
 
 	_oldWorkScreen = _workScreen;
-	_workScreen = _screen[OVERLAY_BUFFER];
+	_workScreen = _screen[kOverlayBuffer];
 	_pendingScreenChanges.setScreenSurface(&_workScreen->surf);
 
 	// do not cache dirtyRects and oldCursorRect
@@ -768,7 +768,7 @@ void AtariGraphicsManager::hideOverlay() {
 
 	// BACK_BUFFER2 is intentional: regardless of the state before calling showOverlay(),
 	// this always contains the next desired frame buffer to show
-	_pendingScreenChanges.setScreenSurface(&_screen[_currentState.mode == GraphicsMode::TripleBuffering ? BACK_BUFFER2 : FRONT_BUFFER]->surf);
+	_pendingScreenChanges.setScreenSurface(&_screen[_currentState.mode == kTripleBuffering ? kBackBuffer2 : kFrontBuffer]->surf);
 	_workScreen = _oldWorkScreen;
 	_oldWorkScreen = nullptr;
 
@@ -799,7 +799,7 @@ void AtariGraphicsManager::clearOverlay() {
 		return;
 
 	const Graphics::Surface &sourceSurface =
-		_currentState.mode == GraphicsMode::DirectRendering ? *_screen[FRONT_BUFFER]->offsettedSurf : _chunkySurface;
+		_currentState.mode == kDirectRendering ? *_screen[kFrontBuffer]->offsettedSurf : _chunkySurface;
 
 	const bool upscale = _overlaySurface.w / sourceSurface.w >= 2 && _overlaySurface.h / sourceSurface.h >= 2;
 
@@ -867,7 +867,7 @@ void AtariGraphicsManager::clearOverlay() {
 	// right rect
 	_overlaySurface.fillRect(Common::Rect(_overlaySurface.w - hzOffset, vOffset, _overlaySurface.w, _overlaySurface.h - vOffset), 0);
 
-	_screen[OVERLAY_BUFFER]->addDirtyRect(_overlaySurface, Common::Rect(_overlaySurface.w, _overlaySurface.h), false);
+	_screen[kOverlayBuffer]->addDirtyRect(_overlaySurface, Common::Rect(_overlaySurface.w, _overlaySurface.h), false);
 }
 
 void AtariGraphicsManager::grabOverlay(Graphics::Surface &surface) const {
@@ -901,9 +901,9 @@ bool AtariGraphicsManager::showMouse(bool visible) {
 
 	bool last = _workScreen->cursor.setVisible(visible);
 
-	if (!isOverlayVisible() && _currentState.mode == GraphicsMode::TripleBuffering) {
-		_screen[BACK_BUFFER2]->cursor.setVisible(visible);
-		_screen[FRONT_BUFFER]->cursor.setVisible(visible);
+	if (!isOverlayVisible() && _currentState.mode == kTripleBuffering) {
+		_screen[kBackBuffer2]->cursor.setVisible(visible);
+		_screen[kFrontBuffer]->cursor.setVisible(visible);
 	}
 
 	// don't rely on engines to call it (if they don't it confuses the cursor restore logic)
@@ -917,9 +917,9 @@ void AtariGraphicsManager::warpMouse(int x, int y) {
 
 	_workScreen->cursor.setPosition(x, y);
 
-	if (!isOverlayVisible() && _currentState.mode == GraphicsMode::TripleBuffering) {
-		_screen[BACK_BUFFER2]->cursor.setPosition(x, y);
-		_screen[FRONT_BUFFER]->cursor.setPosition(x, y);
+	if (!isOverlayVisible() && _currentState.mode == kTripleBuffering) {
+		_screen[kBackBuffer2]->cursor.setPosition(x, y);
+		_screen[kFrontBuffer]->cursor.setPosition(x, y);
 	}
 }
 
@@ -935,9 +935,9 @@ void AtariGraphicsManager::setMouseCursor(const void *buf, uint w, uint h, int h
 
 	_workScreen->cursor.setSurface(buf, (int)w, (int)h, hotspotX, hotspotY, keycolor);
 
-	if (!isOverlayVisible() && _currentState.mode == GraphicsMode::TripleBuffering) {
-		_screen[BACK_BUFFER2]->cursor.setSurface(buf, (int)w, (int)h, hotspotX, hotspotY, keycolor);
-		_screen[FRONT_BUFFER]->cursor.setSurface(buf, (int)w, (int)h, hotspotX, hotspotY, keycolor);
+	if (!isOverlayVisible() && _currentState.mode == kTripleBuffering) {
+		_screen[kBackBuffer2]->cursor.setSurface(buf, (int)w, (int)h, hotspotX, hotspotY, keycolor);
+		_screen[kFrontBuffer]->cursor.setSurface(buf, (int)w, (int)h, hotspotX, hotspotY, keycolor);
 	}
 }
 
@@ -953,9 +953,9 @@ void AtariGraphicsManager::setCursorPalette(const byte *colors, uint start, uint
 void AtariGraphicsManager::updateMousePosition(int deltaX, int deltaY) {
 	_workScreen->cursor.updatePosition(deltaX, deltaY);
 
-	if (!isOverlayVisible() && _currentState.mode == GraphicsMode::TripleBuffering) {
-		_screen[BACK_BUFFER2]->cursor.updatePosition(deltaX, deltaY);
-		_screen[FRONT_BUFFER]->cursor.updatePosition(deltaX, deltaY);
+	if (!isOverlayVisible() && _currentState.mode == kTripleBuffering) {
+		_screen[kBackBuffer2]->cursor.updatePosition(deltaX, deltaY);
+		_screen[kFrontBuffer]->cursor.updatePosition(deltaX, deltaY);
 	}
 }
 
@@ -965,8 +965,8 @@ bool AtariGraphicsManager::notifyEvent(const Common::Event &event) {
 	case Common::EVENT_QUIT:
 		if (isOverlayVisible()) {
 			// clear work screen: this is needed if *next* game shows an error upon startup
-			Graphics::Surface &surf = _currentState.mode == GraphicsMode::DirectRendering
-				? *_screen[FRONT_BUFFER]->offsettedSurf
+			Graphics::Surface &surf = _currentState.mode == kDirectRendering
+				? *_screen[kFrontBuffer]->offsettedSurf
 				: _chunkySurface;
 			surf.fillRect(Common::Rect(surf.w, surf.h), 0);
 
@@ -1014,12 +1014,12 @@ Common::Keymap *AtariGraphicsManager::getKeymap() const {
 }
 
 void AtariGraphicsManager::allocateSurfaces() {
-	for (int i : { FRONT_BUFFER, BACK_BUFFER1, BACK_BUFFER2 }) {
+	for (int i : { kFrontBuffer, kBackBuffer1, kBackBuffer2 }) {
 		_screen[i] = new Screen(this, getMaximumScreenWidth(), getMaximumScreenHeight(), PIXELFORMAT_CLUT8, &_palette);
 	}
 
 	// overlay is the default screen upon start
-	_workScreen = _screen[OVERLAY_BUFFER] = new Screen(this, getOverlayWidth(), getOverlayHeight(), getOverlayFormat(), &_overlayPalette);
+	_workScreen = _screen[kOverlayBuffer] = new Screen(this, getOverlayWidth(), getOverlayHeight(), getOverlayFormat(), &_overlayPalette);
 	_workScreen->reset(getOverlayWidth(), getOverlayHeight(), getBitsPerPixel(getOverlayFormat()), true);
 	_pendingScreenChanges.setScreenSurface(&_workScreen->surf);
 
@@ -1028,7 +1028,7 @@ void AtariGraphicsManager::allocateSurfaces() {
 }
 
 void AtariGraphicsManager::freeSurfaces() {
-	for (int i : { FRONT_BUFFER, BACK_BUFFER1, BACK_BUFFER2, OVERLAY_BUFFER }) {
+	for (int i : { kFrontBuffer, kBackBuffer1, kBackBuffer2, kOverlayBuffer }) {
 		delete _screen[i];
 		_screen[i] = nullptr;
 	}
@@ -1082,8 +1082,8 @@ void AtariGraphicsManager::copyRectToScreenInternal(const void *buf, int pitch,
 	_workScreen->addDirtyRect(dstSurface, rect, directRendering);
 
 	if (tripleBuffer) {
-		_screen[BACK_BUFFER2]->addDirtyRect(dstSurface, rect, directRendering);
-		_screen[FRONT_BUFFER]->addDirtyRect(dstSurface, rect, directRendering);
+		_screen[kBackBuffer2]->addDirtyRect(dstSurface, rect, directRendering);
+		_screen[kFrontBuffer]->addDirtyRect(dstSurface, rect, directRendering);
 	}
 
 	if (directRendering) {
@@ -1111,7 +1111,7 @@ bool AtariGraphicsManager::isOverlayDirectRendering() const {
 	// (on SuperVidel we always want to use shading/transparency but its direct rendering is fine and supported)
 	return !hasSuperVidel()
 #ifndef DISABLE_FANCY_THEMES
-		   && (ConfMan.getActiveDomain() == nullptr || _currentState.mode == GraphicsMode::DirectRendering)
+		   && (ConfMan.getActiveDomain() == nullptr || _currentState.mode == kDirectRendering)
 #endif
 		;
 }
diff --git a/backends/graphics/atari/atari-graphics.h b/backends/graphics/atari/atari-graphics.h
index 0a8a843d5b3..e5907bef44b 100644
--- a/backends/graphics/atari/atari-graphics.h
+++ b/backends/graphics/atari/atari-graphics.h
@@ -52,16 +52,16 @@ public:
 
 	const OSystem::GraphicsMode *getSupportedGraphicsModes() const override {
 		static const OSystem::GraphicsMode graphicsModes[] = {
-			{ "direct", "Direct rendering", (int)GraphicsMode::DirectRendering },
-			{ "single", "Single buffering", (int)GraphicsMode::SingleBuffering },
-			{ "triple", "Triple buffering", (int)GraphicsMode::TripleBuffering },
+			{ "direct", "Direct rendering", kDirectRendering },
+			{ "single", "Single buffering", kSingleBuffering },
+			{ "triple", "Triple buffering", kTripleBuffering },
 			{ nullptr, nullptr, 0 }
 		};
 		return graphicsModes;
 	}
-	int getDefaultGraphicsMode() const override { return (int)GraphicsMode::TripleBuffering; }
+	int getDefaultGraphicsMode() const override { return kTripleBuffering; }
 	bool setGraphicsMode(int mode, uint flags = OSystem::kGfxModeNoFlags) override;
-	int getGraphicsMode() const override { return (int)_currentState.mode; }
+	int getGraphicsMode() const override { return _currentState.mode; }
 
 	void initSize(uint width, uint height, const Graphics::PixelFormat *format = NULL) override;
 
@@ -114,11 +114,11 @@ protected:
 	void freeSurfaces();
 
 private:
-	enum class GraphicsMode : int {
-		Unknown			= -1,
-		DirectRendering = 0,
-		SingleBuffering = 1,
-		TripleBuffering = 3
+	enum {
+		kUnknownMode		= -1,
+		kDirectRendering	= 0,
+		kSingleBuffering	= 1,
+		kTripleBuffering	= 3
 	};
 
 	enum CustomEventAction {
@@ -181,14 +181,14 @@ private:
 	struct GraphicsState {
 		GraphicsState()
 			: inTransaction(false)
-			, mode(GraphicsMode::Unknown)
+			, mode(kUnknownMode)
 			, width(0)
 			, height(0)
 			, format(Graphics::PixelFormat()) {
 		}
 
 		bool inTransaction;
-		GraphicsMode mode;
+		int mode;
 		int width;
 		int height;
 		Graphics::PixelFormat format;
@@ -202,13 +202,13 @@ private:
 	PendingScreenChanges _pendingScreenChanges;
 
 	enum {
-		FRONT_BUFFER,
-		BACK_BUFFER1,
-		BACK_BUFFER2,
-		OVERLAY_BUFFER,
-		BUFFER_COUNT
+		kFrontBuffer	= 0,
+		kBackBuffer1	= 1,
+		kBackBuffer2	= 2,
+		kOverlayBuffer	= 3,
+		kBufferCount
 	};
-	Screen *_screen[BUFFER_COUNT] = {};
+	Screen *_screen[kBufferCount] = {};
 	Screen *_workScreen = nullptr;
 	Screen *_oldWorkScreen = nullptr;	// used in hideOverlay()
 


Commit: a4ed12b04db8cf5737174cd9100f97ddf855c609
    https://github.com/scummvm/scummvm/commit/a4ed12b04db8cf5737174cd9100f97ddf855c609
Author: Miro Kropacek (miro.kropacek at gmail.com)
Date: 2024-12-30T18:37:55+01:00

Commit Message:
BACKENDS: ATARI: Cleanup overlay code

Pretending that the manager starts in the overlay mode was really
confusing.

Also, the concept of _workScreen seemed great in theory but lead to
various subtle errors which were very hard to debug (related to cursor
handling, resolution changing etc).

Changed paths:
    backends/graphics/atari/atari-graphics.cpp
    backends/graphics/atari/atari-graphics.h
    backends/graphics/atari/atari-pendingscreenchanges.cpp
    backends/graphics/atari/atari-pendingscreenchanges.h
    backends/platform/atari/osystem_atari.cpp


diff --git a/backends/graphics/atari/atari-graphics.cpp b/backends/graphics/atari/atari-graphics.cpp
index cc989e1baea..84c8c1c59ea 100644
--- a/backends/graphics/atari/atari-graphics.cpp
+++ b/backends/graphics/atari/atari-graphics.cpp
@@ -244,8 +244,12 @@ AtariGraphicsManager::AtariGraphicsManager()
 
 	// Generate RGB332/RGB121 palette for the overlay
 	const Graphics::PixelFormat &format = getOverlayFormat();
-	const int paletteSize = getOverlayPaletteSize();
-	for (int i = 0; i < paletteSize; i++) {
+#ifndef DISABLE_FANCY_THEMES
+		const int overlayPaletteSize = _tt ? 16 : 256;
+#else
+		const int overlayPaletteSize = 16;
+#endif
+	for (int i = 0; i < overlayPaletteSize; i++) {
 		if (_tt) {
 			// Bits 15-12    Bits 11-8     Bits 7-4      Bits 3-0
 			// Reserved      Red           Green         Blue
@@ -258,6 +262,7 @@ AtariGraphicsManager::AtariGraphicsManager()
 			_overlayPalette.falcon[i].blue  |= ((i >> format.bShift) & format.bMax()) << format.bLoss;
 		}
 	}
+	_overlayPalette.entries = overlayPaletteSize;
 
 	if (_tt) {
 		s_oldRez = Getrez();
@@ -326,7 +331,7 @@ void AtariGraphicsManager::setFeatureState(OSystem::Feature f, bool enable) {
 	if (!hasFeature(f))
 		return;
 
-	// flags must be set to _pendingScreenChanges here
+	// flags must be queued in _pendingScreenChanges here
 
 	switch (f) {
 	case OSystem::Feature::kFeatureAspectRatioCorrection:
@@ -334,7 +339,7 @@ void AtariGraphicsManager::setFeatureState(OSystem::Feature f, bool enable) {
 		if (_aspectRatioCorrection != enable) {
 			_aspectRatioCorrection = enable;
 
-			if (!_overlayVisible) {
+			if (_overlayState == kOverlayHidden) {
 				_pendingScreenChanges.queueAspectRatioCorrection();
 
 				if (!_pendingState.inTransaction)
@@ -380,6 +385,13 @@ void AtariGraphicsManager::initSize(uint width, uint height, const Graphics::Pix
 	_pendingState.height = height;
 	_pendingState.format = format ? *format : PIXELFORMAT_CLUT8;
 
+	if (_pendingState.width == 0 || _pendingState.height == 0) {
+		// special case: initSize(0,0) implies a reinit so e.g. changing graphics mode
+		// from UI doesn't automatically trigger setting s_screenSurf
+		_currentState.width  = _pendingState.width;
+		_currentState.height = _pendingState.height;
+	}
+
 	if (!_pendingState.inTransaction)
 		endGFXTransaction();
 }
@@ -398,7 +410,8 @@ OSystem::TransactionError AtariGraphicsManager::endGFXTransaction() {
 	_pendingState.inTransaction = false;
 
 	int error = OSystem::TransactionError::kTransactionSuccess;
-	bool hasPendingGraphicsMode = false;	// no need to have a global flag
+	bool hasPendingGraphicsMode = false;
+	bool hasPendingSize = false;
 
 	if (_pendingState.mode != kUnknownMode) {
 		if (_pendingState.mode < kDirectRendering || _pendingState.mode > kTripleBuffering) {
@@ -414,8 +427,9 @@ OSystem::TransactionError AtariGraphicsManager::endGFXTransaction() {
 		} else if (_pendingState.width % 16 != 0 && !hasSuperVidel()) {
 			atari_warning("Requested width not divisible by 16, please report");
 			error |= OSystem::TransactionError::kTransactionSizeChangeFailed;
-		} else if (_overlayVisible || _currentState.width != _pendingState.width || _currentState.height != _pendingState.height) {
-			_pendingScreenChanges.queueVideoMode();
+		} else if (_overlayState == kOverlayIgnoredHide || _currentState.width != _pendingState.width || _currentState.height != _pendingState.height) {
+			// if kOverlayIgnoredHide and with valid w/h, force a video mode reset
+			hasPendingSize = true;
 		}
 	}
 
@@ -432,39 +446,41 @@ OSystem::TransactionError AtariGraphicsManager::endGFXTransaction() {
 	if (hasPendingGraphicsMode)
 		_currentState.mode = _pendingState.mode;
 
-	if (_pendingScreenChanges.videoMode()) {
+	if (hasPendingSize) {
 		_currentState.width  = _pendingState.width;
 		_currentState.height = _pendingState.height;
 		_currentState.format = _pendingState.format;
-
-		if (_overlayVisible) {
-			_checkUnalignedPitch = true;
-			_ignoreHideOverlay = false;
-			_overlayVisible = false;
-			// if being in the overlay, reset everything (same as hideOverlay() does)
-			// s_screenSurf will be set below
-			_pendingScreenChanges.queueAll();
-		}
-	} else if (_overlayVisible) {
-		// don't exit overlay unless there is real video mode to be set
-		_ignoreHideOverlay = true;
-		_pendingState = GraphicsState();
-		_pendingScreenChanges.clearTransaction();
-		return OSystem::kTransactionSuccess;
 	}
 
-	if (_pendingScreenChanges.videoMode() || hasPendingGraphicsMode) {
+	if ((hasPendingGraphicsMode || hasPendingSize) && _currentState.isValid()) {
 		_chunkySurface.init(_currentState.width, _currentState.height, _currentState.width,
 			_chunkySurface.getPixels(), _currentState.format);
 
 		_screen[kFrontBuffer]->reset(_currentState.width, _currentState.height, 8, true);
-		_screen[kBackBuffer1]->reset(_currentState.width, _currentState.height, 8, true);
-		_screen[kBackBuffer2]->reset(_currentState.width, _currentState.height, 8, true);
-		_workScreen = _screen[_currentState.mode <= kSingleBuffering ? kFrontBuffer : kBackBuffer1];
+		if (_currentState.mode > kSingleBuffering) {
+			_screen[kBackBuffer1]->reset(_currentState.width, _currentState.height, 8, true);
+			_screen[kBackBuffer2]->reset(_currentState.width, _currentState.height, 8, true);
+		}
+
+		if (hasPendingSize)
+			_pendingScreenChanges.queueVideoMode();
+
 		_pendingScreenChanges.setScreenSurface(&_screen[kFrontBuffer]->surf);
 
 		_palette.clear();
+		// TODO: maybe we could update real start/num values
+		_palette.entries = 256;
 		_pendingScreenChanges.queuePalette();
+
+		if (_overlayState == kOverlayIgnoredHide) {
+			_checkUnalignedPitch = true;
+			_overlayState = kOverlayHidden;
+			_ignoreHideOverlay = false;
+			_pendingScreenChanges.queueAll();
+		}
+	} else {
+		// clear any queued transaction changes from feature flags (e.g. aspect ratio correction)
+		_pendingScreenChanges.clearTransaction();
 	}
 
 	_pendingState = GraphicsState();
@@ -524,42 +540,38 @@ void AtariGraphicsManager::grabPalette(byte *colors, uint start, uint num) const
 void AtariGraphicsManager::copyRectToScreen(const void *buf, int pitch, int x, int y, int w, int h) {
 	//atari_debug("copyRectToScreen: %d, %d, %d(%d), %d", x, y, w, pitch, h);
 
-	copyRectToScreenInternal(buf, pitch, x, y, w, h,
-		PIXELFORMAT_CLUT8,
-		_currentState.mode == kDirectRendering,
-		_currentState.mode == kTripleBuffering);
+	Graphics::Surface &dstSurface = *lockScreen();
+
+	copyRectToScreenInternal(
+		dstSurface,
+		buf, pitch, x, y, w, h,
+		_currentState.format, _currentState.mode == kDirectRendering);
+
+	unlockScreenInternal(
+		dstSurface,
+		x, y, w, h);
 }
 
-// this is not really locking anything but it's an useful function
-// to return current rendering surface :)
 Graphics::Surface *AtariGraphicsManager::lockScreen() {
 	//atari_debug("lockScreen");
 
-	if (isOverlayVisible() && !isOverlayDirectRendering())
-		return &_overlaySurface;
-	else if ((isOverlayVisible() && isOverlayDirectRendering()) || _currentState.mode == kDirectRendering)
-		return _workScreen->offsettedSurf;
-	else
-		return &_chunkySurface;
+	return _currentState.mode == kDirectRendering
+		? _screen[kFrontBuffer]->offsettedSurf
+		: &_chunkySurface;
 }
 
 void AtariGraphicsManager::unlockScreen() {
-	//atari_debug("unlockScreen: %d x %d", _workScreen->surf.w, _workScreen->surf.h);
-
 	const Graphics::Surface &dstSurface = *lockScreen();
 
-	const bool directRendering = (dstSurface.getPixels() != _chunkySurface.getPixels());
-	const Common::Rect rect = alignRect(0, 0, dstSurface.w, dstSurface.h);
-	_workScreen->addDirtyRect(dstSurface, rect, directRendering);
+	//atari_debug("unlockScreen: %d x %d", dstSurface.w, dstSurface.h);
 
-	if (_currentState.mode == kTripleBuffering) {
-		_screen[kBackBuffer2]->addDirtyRect(dstSurface, rect, directRendering);
-		_screen[kFrontBuffer]->addDirtyRect(dstSurface, rect, directRendering);
-	}
+	unlockScreenInternal(
+		dstSurface,
+		0, 0, dstSurface.w, dstSurface.h);
 }
 
 void AtariGraphicsManager::fillScreen(uint32 col) {
-	//atari_debug("fillScreen: %d", col);
+	atari_debug("fillScreen: %d", col);
 
 	Graphics::Surface *screen = lockScreen();
 
@@ -620,53 +632,46 @@ void AtariGraphicsManager::updateScreen() {
 		_checkUnalignedPitch = false;
 	}
 
-	_workScreen->cursor.update();
-
-	bool screenUpdated = false;
-
-	if (isOverlayVisible()) {
-		assert(_workScreen == _screen[kOverlayBuffer]);
-		if (isOverlayDirectRendering())
-			screenUpdated = updateScreenInternal(Graphics::Surface());
-		else
-			screenUpdated = updateScreenInternal(_overlaySurface);
+	Screen *workScreen = nullptr;
+	Graphics::Surface *srcSurface = nullptr;
+	if (_overlayState == kOverlayVisible || _overlayState == kOverlayIgnoredHide) {
+		workScreen = _screen[kOverlayBuffer];
+		if (!isOverlayDirectRendering())
+			srcSurface = &_overlaySurface;
 	} else {
 		switch (_currentState.mode) {
 		case kDirectRendering:
-			assert(_workScreen == _screen[kFrontBuffer]);
-			screenUpdated = updateScreenInternal(Graphics::Surface());
+			workScreen = _screen[kFrontBuffer];
 			break;
 		case kSingleBuffering:
-			assert(_workScreen == _screen[kFrontBuffer]);
-			screenUpdated = updateScreenInternal(_chunkySurface);
+			workScreen = _screen[kFrontBuffer];
+			srcSurface = &_chunkySurface;
 			break;
 		case kTripleBuffering:
-			assert(_workScreen == _screen[kBackBuffer1]);
-			screenUpdated = updateScreenInternal(_chunkySurface);
+			workScreen = _screen[kBackBuffer1];
+			srcSurface = &_chunkySurface;
 			break;
 		default:
 			atari_warning("Unknown graphics mode %d", _currentState.mode);
 		}
 	}
 
-	_workScreen->clearDirtyRects();
+	assert(workScreen);
+	workScreen->cursor.update();
 
-	if (_overlayPending) {
-		atari_debug("Forcing overlay pending state");
-		// must be done here because first updateScreen() is not called from showOverlay()
-		_pendingScreenChanges.queueAll();
-		_overlayPending = false;
-	}
+	bool screenUpdated = updateScreenInternal(workScreen, srcSurface ? *srcSurface : Graphics::Surface());
+
+	workScreen->clearDirtyRects();
 
 #ifdef SCREEN_ACTIVE
 	// this assume that the screen surface is not going to be used yet
-	_pendingScreenChanges.applyBeforeVblLock();
+	_pendingScreenChanges.applyBeforeVblLock(*workScreen);
 #endif
 
 	set_sysvar_to_short(vblsem, 0);  // lock vbl
 
 	if (screenUpdated
-		&& !isOverlayVisible()
+		&& _overlayState == kOverlayHidden
 		&& _currentState.mode == kTripleBuffering) {
 		// Triple buffer:
 		// - alternate BACK_BUFFER1 and BACK_BUFFER2
@@ -688,11 +693,11 @@ void AtariGraphicsManager::updateScreen() {
 
 		// queue BACK_BUFFER2 with the most recent frame content
 		_pendingScreenChanges.setScreenSurface(&_screen[kBackBuffer2]->surf);
-		_workScreen = _screen[kBackBuffer1];
+		// BACK_BUFFER1 is now current (work) buffer
 	}
 
 #ifdef SCREEN_ACTIVE
-	_pendingScreenChanges.applyAfterVblLock();
+	_pendingScreenChanges.applyAfterVblLock(*workScreen);
 #endif
 
 	if (_pendingScreenChanges.screenSurface()) {
@@ -727,52 +732,53 @@ void AtariGraphicsManager::setShakePos(int shakeXOffset, int shakeYOffset) {
 }
 
 void AtariGraphicsManager::showOverlay(bool inGUI) {
-	atari_debug("showOverlay (visible: %d)", _overlayVisible);
+	atari_debug("showOverlay (state: %d, inGUI: %d)", _overlayState, inGUI);
 
-	if (_overlayVisible)
+	if (_overlayState == kOverlayVisible)
 		return;
 
+	if (_overlayState == kOverlayIgnoredHide) {
+		_overlayState = kOverlayVisible;
+		return;
+	}
+
 	if (_currentState.mode == kDirectRendering) {
-		_workScreen->cursor.restoreBackground(Graphics::Surface(), true);
+		_screen[kFrontBuffer]->cursor.restoreBackground(Graphics::Surface(), true);
 	}
 
-	_oldWorkScreen = _workScreen;
-	_workScreen = _screen[kOverlayBuffer];
-	_pendingScreenChanges.setScreenSurface(&_workScreen->surf);
+	_pendingScreenChanges.setScreenSurface(&_screen[kOverlayBuffer]->surf);
 
 	// do not cache dirtyRects and oldCursorRect
-	_workScreen->reset(getOverlayWidth(), getOverlayHeight(), getBitsPerPixel(getOverlayFormat()), false);
+	_screen[kOverlayBuffer]->reset(getOverlayWidth(), getOverlayHeight(), getBitsPerPixel(getOverlayFormat()), false);
 
-	_overlayVisible = true;
+	_overlayState = kOverlayVisible;
 
 	if (!_pendingScreenChanges.empty()) {
 		warning("showOverlay: _pendingScreenChanges is %02x", _pendingScreenChanges.get());
 	}
-	//_pendingScreenChanges.queueAll();	// must be called in updateScreen() ...
-	_overlayPending = true;
+	_pendingScreenChanges.queueAll();
 	updateScreen();
 }
 
 void AtariGraphicsManager::hideOverlay() {
-	atari_debug("hideOverlay (ignore: %d, visible: %d)", _ignoreHideOverlay, _overlayVisible);
+	atari_debug("hideOverlay (ignore: %d, state: %d)", _ignoreHideOverlay, _overlayState);
+
+	assert(_overlayState != kOverlayIgnoredHide);
 
-	if (!_overlayVisible)
+	if (_overlayState == kOverlayHidden)
 		return;
 
 	if (_ignoreHideOverlay) {
-		// faster than _workScreen->reset()
-		_workScreen->clearDirtyRects();
-		_workScreen->cursor.reset();
+		_overlayState = kOverlayIgnoredHide;
 		return;
 	}
 
 	// BACK_BUFFER2 is intentional: regardless of the state before calling showOverlay(),
 	// this always contains the next desired frame buffer to show
-	_pendingScreenChanges.setScreenSurface(&_screen[_currentState.mode == kTripleBuffering ? kBackBuffer2 : kFrontBuffer]->surf);
-	_workScreen = _oldWorkScreen;
-	_oldWorkScreen = nullptr;
+	_pendingScreenChanges.setScreenSurface(
+		&_screen[_currentState.mode == kTripleBuffering ? kBackBuffer2 : kFrontBuffer]->surf);
 
-	_overlayVisible = false;
+	_overlayState = kOverlayHidden;
 
 	if (!_pendingScreenChanges.empty()) {
 		warning("hideOverlay: _pendingScreenChanges is %02x", _pendingScreenChanges.get());
@@ -795,7 +801,7 @@ void AtariGraphicsManager::clearOverlay() {
 
 	atari_debug("clearOverlay");
 
-	if (!_overlayVisible)
+	if (!isOverlayVisible())
 		return;
 
 	const Graphics::Surface &sourceSurface =
@@ -890,18 +896,33 @@ void AtariGraphicsManager::grabOverlay(Graphics::Surface &surface) const {
 void AtariGraphicsManager::copyRectToOverlay(const void *buf, int pitch, int x, int y, int w, int h) {
 	//atari_debug("copyRectToOverlay: %d, %d, %d(%d), %d", x, y, w, pitch, h);
 
-	copyRectToScreenInternal(buf, pitch, x, y, w, h,
+	const bool directRendering = isOverlayDirectRendering();
+
+	Graphics::Surface &dstSurface = directRendering
+		? *_screen[kOverlayBuffer]->offsettedSurf
+		: _overlaySurface;
+
+	copyRectToScreenInternal(
+		dstSurface,
+		buf, pitch, x, y, w, h,
 		getOverlayFormat(),
-		isOverlayDirectRendering(),
-		false);
+		directRendering);
+
+	const Common::Rect rect = alignRect(x, y, w, h);
+	_screen[kOverlayBuffer]->addDirtyRect(dstSurface, rect, directRendering);
 }
 
 bool AtariGraphicsManager::showMouse(bool visible) {
 	//atari_debug("showMouse: %d", visible);
 
-	bool last = _workScreen->cursor.setVisible(visible);
+	bool last;
 
-	if (!isOverlayVisible() && _currentState.mode == kTripleBuffering) {
+	if (isOverlayVisible()) {
+		last = _screen[kOverlayBuffer]->cursor.setVisible(visible);
+	} else if (_currentState.mode <= kSingleBuffering) {
+		last = _screen[kFrontBuffer]->cursor.setVisible(visible);
+	} else {
+		last = _screen[kBackBuffer1]->cursor.setVisible(visible);
 		_screen[kBackBuffer2]->cursor.setVisible(visible);
 		_screen[kFrontBuffer]->cursor.setVisible(visible);
 	}
@@ -915,9 +936,12 @@ bool AtariGraphicsManager::showMouse(bool visible) {
 void AtariGraphicsManager::warpMouse(int x, int y) {
 	//atari_debug("warpMouse: %d, %d", x, y);
 
-	_workScreen->cursor.setPosition(x, y);
-
-	if (!isOverlayVisible() && _currentState.mode == kTripleBuffering) {
+	if (isOverlayVisible()) {
+		_screen[kOverlayBuffer]->cursor.setPosition(x, y);
+	} else if (_currentState.mode <= kSingleBuffering) {
+		_screen[kFrontBuffer]->cursor.setPosition(x, y);
+	} else {
+		_screen[kBackBuffer1]->cursor.setPosition(x, y);
 		_screen[kBackBuffer2]->cursor.setPosition(x, y);
 		_screen[kFrontBuffer]->cursor.setPosition(x, y);
 	}
@@ -933,9 +957,12 @@ void AtariGraphicsManager::setMouseCursor(const void *buf, uint w, uint h, int h
 	if (format)
 		assert(*format == PIXELFORMAT_CLUT8);
 
-	_workScreen->cursor.setSurface(buf, (int)w, (int)h, hotspotX, hotspotY, keycolor);
-
-	if (!isOverlayVisible() && _currentState.mode == kTripleBuffering) {
+	if (isOverlayVisible()) {
+		_screen[kOverlayBuffer]->cursor.setSurface(buf, (int)w, (int)h, hotspotX, hotspotY, keycolor);
+	} else if (_currentState.mode <= kSingleBuffering) {
+		_screen[kFrontBuffer]->cursor.setSurface(buf, (int)w, (int)h, hotspotX, hotspotY, keycolor);
+	} else {
+		_screen[kBackBuffer1]->cursor.setSurface(buf, (int)w, (int)h, hotspotX, hotspotY, keycolor);
 		_screen[kBackBuffer2]->cursor.setSurface(buf, (int)w, (int)h, hotspotX, hotspotY, keycolor);
 		_screen[kFrontBuffer]->cursor.setSurface(buf, (int)w, (int)h, hotspotX, hotspotY, keycolor);
 	}
@@ -946,14 +973,17 @@ void AtariGraphicsManager::setCursorPalette(const byte *colors, uint start, uint
 
 	if (isOverlayVisible()) {
 		// cursor palette is supported only in the overlay
-		_workScreen->cursor.setPalette(colors, start, num);
+		_screen[kOverlayBuffer]->cursor.setPalette(colors, start, num);
 	}
 }
 
 void AtariGraphicsManager::updateMousePosition(int deltaX, int deltaY) {
-	_workScreen->cursor.updatePosition(deltaX, deltaY);
-
-	if (!isOverlayVisible() && _currentState.mode == kTripleBuffering) {
+	if (isOverlayVisible()) {
+		_screen[kOverlayBuffer]->cursor.updatePosition(deltaX, deltaY);
+	} else if (_currentState.mode <= kSingleBuffering) {
+		_screen[kFrontBuffer]->cursor.updatePosition(deltaX, deltaY);
+	} else {
+		_screen[kBackBuffer1]->cursor.updatePosition(deltaX, deltaY);
 		_screen[kBackBuffer2]->cursor.updatePosition(deltaX, deltaY);
 		_screen[kFrontBuffer]->cursor.updatePosition(deltaX, deltaY);
 	}
@@ -962,8 +992,8 @@ void AtariGraphicsManager::updateMousePosition(int deltaX, int deltaY) {
 bool AtariGraphicsManager::notifyEvent(const Common::Event &event) {
 	switch (event.type) {
 	case Common::EVENT_RETURN_TO_LAUNCHER:
-	case Common::EVENT_QUIT:
 		if (isOverlayVisible()) {
+			debug("Return to launcher from overlay");
 			// clear work screen: this is needed if *next* game shows an error upon startup
 			Graphics::Surface &surf = _currentState.mode == kDirectRendering
 				? *_screen[kFrontBuffer]->offsettedSurf
@@ -981,7 +1011,7 @@ bool AtariGraphicsManager::notifyEvent(const Common::Event &event) {
 			if (hasFeature(OSystem::Feature::kFeatureAspectRatioCorrection)) {
 				_aspectRatioCorrection = !_aspectRatioCorrection;
 
-				if (!_overlayVisible) {
+				if (_overlayState == kOverlayHidden) {
 					_pendingScreenChanges.queueAspectRatioCorrection();
 
 					updateScreen();
@@ -1017,11 +1047,7 @@ void AtariGraphicsManager::allocateSurfaces() {
 	for (int i : { kFrontBuffer, kBackBuffer1, kBackBuffer2 }) {
 		_screen[i] = new Screen(this, getMaximumScreenWidth(), getMaximumScreenHeight(), PIXELFORMAT_CLUT8, &_palette);
 	}
-
-	// overlay is the default screen upon start
-	_workScreen = _screen[kOverlayBuffer] = new Screen(this, getOverlayWidth(), getOverlayHeight(), getOverlayFormat(), &_overlayPalette);
-	_workScreen->reset(getOverlayWidth(), getOverlayHeight(), getBitsPerPixel(getOverlayFormat()), true);
-	_pendingScreenChanges.setScreenSurface(&_workScreen->surf);
+	_screen[kOverlayBuffer] = new Screen(this, getOverlayWidth(), getOverlayHeight(), getOverlayFormat(), &_overlayPalette);
 
 	_chunkySurface.create(getMaximumScreenWidth(), getMaximumScreenHeight(), PIXELFORMAT_CLUT8);
 	_overlaySurface.create(getOverlayWidth(), getOverlayHeight(), getOverlayFormat());
@@ -1032,18 +1058,28 @@ void AtariGraphicsManager::freeSurfaces() {
 		delete _screen[i];
 		_screen[i] = nullptr;
 	}
-	_workScreen = nullptr;
 
 	_chunkySurface.free();
 	_overlaySurface.free();
 }
 
-bool AtariGraphicsManager::updateScreenInternal(const Graphics::Surface &srcSurface) {
+void AtariGraphicsManager::unlockScreenInternal(const Graphics::Surface &dstSurface, int x, int y, int w, int h) {
+	const bool directRendering = _currentState.mode == kDirectRendering;
+	const Common::Rect rect = alignRect(x, y, w, h);
+	_screen[kFrontBuffer]->addDirtyRect(dstSurface, rect, directRendering);
+
+	if (_currentState.mode > kSingleBuffering) {
+		_screen[kBackBuffer1]->addDirtyRect(dstSurface, rect, directRendering);
+		_screen[kBackBuffer2]->addDirtyRect(dstSurface, rect, directRendering);
+	}
+}
+
+bool AtariGraphicsManager::updateScreenInternal(Screen *dstScreen, const Graphics::Surface &srcSurface) {
 	//atari_debug("updateScreenInternal");
 
-	const Screen::DirtyRects &dirtyRects = _workScreen->dirtyRects;
-	Graphics::Surface *dstSurface        = _workScreen->offsettedSurf;
-	Cursor &cursor                       = _workScreen->cursor;
+	const Screen::DirtyRects &dirtyRects = dstScreen->dirtyRects;
+	Graphics::Surface *dstSurface        = dstScreen->offsettedSurf;
+	Cursor &cursor                       = dstScreen->cursor;
 
 	const bool directRendering           = srcSurface.getPixels() == nullptr;
 	const int dstBitsPerPixel            = getBitsPerPixel(dstSurface->format);
@@ -1051,7 +1087,7 @@ bool AtariGraphicsManager::updateScreenInternal(const Graphics::Surface &srcSurf
 	bool updated = false;
 
 	const bool cursorDrawEnabled = cursor.isVisible();
-	bool forceCursorDraw = cursorDrawEnabled && (_workScreen->fullRedraw || cursor.isChanged());
+	bool forceCursorDraw = cursorDrawEnabled && (dstScreen->fullRedraw || cursor.isChanged());
 
 	lockSuperBlitter();
 
@@ -1074,17 +1110,10 @@ bool AtariGraphicsManager::updateScreenInternal(const Graphics::Surface &srcSurf
 	return updated;
 }
 
-void AtariGraphicsManager::copyRectToScreenInternal(const void *buf, int pitch, int x, int y, int w, int h,
-													const Graphics::PixelFormat &format, bool directRendering, bool tripleBuffer) {
-	Graphics::Surface &dstSurface = *lockScreen();
-
+void AtariGraphicsManager::copyRectToScreenInternal(Graphics::Surface &dstSurface,
+													const void *buf, int pitch, int x, int y, int w, int h,
+													const Graphics::PixelFormat &format, bool directRendering) {
 	const Common::Rect rect = alignRect(x, y, w, h);
-	_workScreen->addDirtyRect(dstSurface, rect, directRendering);
-
-	if (tripleBuffer) {
-		_screen[kBackBuffer2]->addDirtyRect(dstSurface, rect, directRendering);
-		_screen[kFrontBuffer]->addDirtyRect(dstSurface, rect, directRendering);
-	}
 
 	if (directRendering) {
 		// TODO: mask the unaligned parts and copy the rest
diff --git a/backends/graphics/atari/atari-graphics.h b/backends/graphics/atari/atari-graphics.h
index e5907bef44b..fd437228d3d 100644
--- a/backends/graphics/atari/atari-graphics.h
+++ b/backends/graphics/atari/atari-graphics.h
@@ -86,7 +86,7 @@ public:
 
 	void showOverlay(bool inGUI) override;
 	void hideOverlay() override;
-	bool isOverlayVisible() const override { return _overlayVisible; }
+	bool isOverlayVisible() const override { return _overlayState == kOverlayVisible; }
 	Graphics::PixelFormat getOverlayFormat() const override;
 	void clearOverlay() override;
 	void grabOverlay(Graphics::Surface &surface) const override;
@@ -100,7 +100,14 @@ public:
 						bool dontScale = false, const Graphics::PixelFormat *format = NULL, const byte *mask = NULL) override;
 	void setCursorPalette(const byte *colors, uint start, uint num) override;
 
-	Common::Point getMousePosition() const { return _workScreen->cursor.getPosition(); }
+	Common::Point getMousePosition() const {
+		if (isOverlayVisible()) {
+			return _screen[kOverlayBuffer]->cursor.getPosition();
+		} else {
+			// kFrontBuffer is always up to date
+			return _screen[kFrontBuffer]->cursor.getPosition();
+		}
+	}
 	void updateMousePosition(int deltaX, int deltaY);
 
 	bool notifyEvent(const Common::Event &event) override;
@@ -133,10 +140,12 @@ private:
 	int16 getMaximumScreenWidth() const { return _tt ? 320 : (_vgaMonitor ? 320 : 320*1.2); }
 #endif
 
-	bool updateScreenInternal(const Graphics::Surface &srcSurface);
-
-	void copyRectToScreenInternal(const void *buf, int pitch, int x, int y, int w, int h,
-								  const Graphics::PixelFormat &format, bool directRendering, bool tripleBuffer);
+	void unlockScreenInternal(const Graphics::Surface &dstSurface,
+							  int x, int y, int w, int h);
+	bool updateScreenInternal(Screen *dstScreen, const Graphics::Surface &srcSurface);
+	void copyRectToScreenInternal(Graphics::Surface &dstSurface,
+								  const void *buf, int pitch, int x, int y, int w, int h,
+								  const Graphics::PixelFormat &format, bool directRendering);
 
 	int getBitsPerPixel(const Graphics::PixelFormat &format) const;
 
@@ -166,14 +175,6 @@ private:
 		return alignRect(rect.left, rect.top, rect.width(), rect.height());
 	}
 
-	int getOverlayPaletteSize() const {
-#ifndef DISABLE_FANCY_THEMES
-		return _tt ? 16 : 256;
-#else
-		return 16;
-#endif
-	}
-
 	bool _vgaMonitor = true;
 	bool _tt = false;
 	bool _checkUnalignedPitch = false;
@@ -187,6 +188,10 @@ private:
 			, format(Graphics::PixelFormat()) {
 		}
 
+		bool isValid() const {
+			return mode != kUnknownMode && width > 0 && height > 0 && format.bytesPerPixel != 0;
+		}
+
 		bool inTransaction;
 		int mode;
 		int width;
@@ -209,13 +214,15 @@ private:
 		kBufferCount
 	};
 	Screen *_screen[kBufferCount] = {};
-	Screen *_workScreen = nullptr;
-	Screen *_oldWorkScreen = nullptr;	// used in hideOverlay()
 
 	Graphics::Surface _chunkySurface;
 
-	bool _overlayVisible = true;
-	bool _overlayPending = true;
+	enum {
+		kOverlayVisible,
+		kOverlayIgnoredHide,
+		kOverlayHidden
+	};
+	int _overlayState = kOverlayHidden;
 	bool _ignoreHideOverlay = true;
 	Graphics::Surface _overlaySurface;
 
diff --git a/backends/graphics/atari/atari-pendingscreenchanges.cpp b/backends/graphics/atari/atari-pendingscreenchanges.cpp
index e0e05c093da..921e6d31188 100644
--- a/backends/graphics/atari/atari-pendingscreenchanges.cpp
+++ b/backends/graphics/atari/atari-pendingscreenchanges.cpp
@@ -44,7 +44,8 @@ void PendingScreenChanges::queueAll() {
  * VsetMode() - explicitly calls Vsync()
  */
 
-void PendingScreenChanges::applyBeforeVblLock() {
+void PendingScreenChanges::applyBeforeVblLock(const Screen &screen) {
+	_mode = screen.mode;	// avoid modifying 'Screen' content
 	_resetSuperVidel = false;
 	_switchToBlackPalette = (_changes & kVideoMode);
 
@@ -53,19 +54,19 @@ void PendingScreenChanges::applyBeforeVblLock() {
 	_shrinkVidelVisibleArea.second = false;
 
 	if (_changes & kAspectRatioCorrection) {
-		processAspectRatioCorrection();
+		processAspectRatioCorrection(screen);
 		_changes &= ~kAspectRatioCorrection;
 	}
 
 	_switchToBlackPalette |= _resetSuperVidel;
 
 	if (_changes & kVideoMode) {
-		processVideoMode();
+		processVideoMode(screen);
 		// don't reset kVideoMode yet
 	}
 }
 
-void PendingScreenChanges::applyAfterVblLock() {
+void PendingScreenChanges::applyAfterVblLock(const Screen &screen) {
 	// VBL doesn't process new palette nor screen address updates
 
 	if (_changes & kShakeScreen) {
@@ -79,9 +80,9 @@ void PendingScreenChanges::applyAfterVblLock() {
 			if (_manager->_tt) {
 				if (_changes & kPalette)
 					Vsync();
-				EsetPalette(0, _manager->isOverlayVisible() ? _manager->getOverlayPaletteSize() : 256, _manager->_workScreen->palette->tt);
+				EsetPalette(0, screen.palette->entries, screen.palette->tt);
 			} else {
-				VsetRGB(0, _manager->isOverlayVisible() ? _manager->getOverlayPaletteSize() : 256, _manager->_workScreen->palette->falcon);
+				VsetRGB(0, screen.palette->entries, screen.palette->falcon);
 				if (_changes & kPalette)
 					Vsync();
 			}
@@ -93,27 +94,28 @@ void PendingScreenChanges::applyAfterVblLock() {
 	assert(_changes == kNone);
 }
 
-void PendingScreenChanges::processAspectRatioCorrection() {
+void PendingScreenChanges::processAspectRatioCorrection(const Screen &screen) {
 	assert(!_manager->_tt);
+	assert(_mode != -1);
 
 	if (_manager->_aspectRatioCorrection && _manager->_currentState.height == 200 && !_manager->isOverlayVisible()) {
 		// apply machine-specific aspect ratio correction
 		if (!_manager->_vgaMonitor) {
-			_manager->_workScreen->mode &= ~PAL;
+			_mode &= ~PAL;
 			// 60 Hz
-			_manager->_workScreen->mode |= NTSC;
+			_mode |= NTSC;
 			_changes |= kVideoMode;
 		} else {
 			_aspectRatioCorrectionYOffset =
-				std::make_pair((_manager->_workScreen->surf.h - 2*MAX_V_SHAKE - _manager->_workScreen->offsettedSurf->h) / 2, true);
+				std::make_pair((screen.surf.h - 2*MAX_V_SHAKE - screen.offsettedSurf->h) / 2, true);
 			_shrinkVidelVisibleArea = std::make_pair(true, true);
 		}
 	} else {
 		// reset back to default mode
 		if (!_manager->_vgaMonitor) {
-			_manager->_workScreen->mode &= ~NTSC;
+			_mode &= ~NTSC;
 			// 50 Hz
-			_manager->_workScreen->mode |= PAL;
+			_mode |= PAL;
 			_changes |= kVideoMode;
 		} else {
 			_aspectRatioCorrectionYOffset = std::make_pair(0, true);
@@ -131,28 +133,28 @@ void PendingScreenChanges::processAspectRatioCorrection() {
 	_setScreenOffsets = std::make_pair(true, true);
 }
 
-void PendingScreenChanges::processVideoMode() {
+void PendingScreenChanges::processVideoMode(const Screen &screen) {
 	// changing video mode implies an additional Vsync(): there's no way to change resolution
 	// and set new screen address (and/or shake offsets etc) in one go
-	if (_manager->_workScreen->rez != -1) {
+	if (screen.rez != -1) {
 		if (_switchToBlackPalette) {
 			static uint16 black[256];
-			EsetPalette(0, _manager->isOverlayVisible() ? _manager->getOverlayPaletteSize() : 256, black);
+			EsetPalette(0, screen.palette->entries, black);
 		}
 
 		// unfortunately this reinitializes VDI, too
-		Setscreen(SCR_NOCHANGE, SCR_NOCHANGE, _manager->_workScreen->rez);
-	} else if (_manager->_workScreen->mode != -1) {
+		Setscreen(SCR_NOCHANGE, SCR_NOCHANGE, screen.rez);
+	} else if (_mode != -1) {
 		if (_switchToBlackPalette) {
 			static _RGB black[256];
-			VsetRGB(0, _manager->isOverlayVisible() ? _manager->getOverlayPaletteSize() : 256, black);
+			VsetRGB(0, screen.palette->entries, black);
 		}
 
 		  // VsetMode() must be called first: it resets all hz/v, scrolling and line width registers
 		if (_resetSuperVidel)
 			VsetMode(SVEXT | SVEXT_BASERES(0) | COL80 | BPS8C);	// resync to proper 640x480
 
-		atari_debug("VsetMode: %04x", _manager->_workScreen->mode);
-		VsetMode(_manager->_workScreen->mode);
+		atari_debug("VsetMode: %04x", _mode);
+		VsetMode(_mode);
 	}
 }
diff --git a/backends/graphics/atari/atari-pendingscreenchanges.h b/backends/graphics/atari/atari-pendingscreenchanges.h
index 227814a28e3..b1915432999 100644
--- a/backends/graphics/atari/atari-pendingscreenchanges.h
+++ b/backends/graphics/atari/atari-pendingscreenchanges.h
@@ -25,13 +25,14 @@
 #include <utility>
 
 class AtariGraphicsManager;
+class Screen;
 namespace Graphics {
 class Surface;
 }
 
 class PendingScreenChanges {
 public:
-	PendingScreenChanges(AtariGraphicsManager *manager)
+	PendingScreenChanges(const AtariGraphicsManager *manager)
 		: _manager(manager) {
 	}
 
@@ -60,10 +61,6 @@ public:
 	int get() const {
 		return _changes;
 	}
-
-	bool videoMode() const {
-		return _changes & kVideoMode;
-	}
 	bool empty() const {
 		return _changes == kNone;
 	}
@@ -81,12 +78,12 @@ public:
 		return _shrinkVidelVisibleArea;
 	}
 
-	void applyBeforeVblLock();
-	void applyAfterVblLock();
+	void applyBeforeVblLock(const Screen &screen);
+	void applyAfterVblLock(const Screen &screen);
 
 private:
-	void processAspectRatioCorrection();
-	void processVideoMode();
+	void processAspectRatioCorrection(const Screen &screen);
+	void processVideoMode(const Screen &screen);
 
 	enum Change {
 		kNone                  = 0,
@@ -99,10 +96,11 @@ private:
 	};
 	int _changes = kNone;
 
-	AtariGraphicsManager *_manager;
+	const AtariGraphicsManager *_manager;
 
 	Graphics::Surface *_surface = nullptr;
 
+	int _mode;
 	bool _resetSuperVidel;
 	bool _switchToBlackPalette;
 
diff --git a/backends/platform/atari/osystem_atari.cpp b/backends/platform/atari/osystem_atari.cpp
index 4827d1df3cd..597001fab2d 100644
--- a/backends/platform/atari/osystem_atari.cpp
+++ b/backends/platform/atari/osystem_atari.cpp
@@ -396,7 +396,7 @@ Common::HardwareInputSet *OSystem_Atari::getHardwareInputSet() {
 void OSystem_Atari::quit() {
 	atari_debug("OSystem_Atari::quit()");
 
-	g_system->destroy();
+	destroy();
 }
 
 void OSystem_Atari::logMessage(LogMessageType::Type type, const char *message) {
@@ -461,26 +461,16 @@ Common::Path OSystem_Atari::getDefaultConfigFileName() {
 void OSystem_Atari::update() {
 	// avoid a recursion loop if a timer callback decides to call OSystem::delayMillis()
 	static bool inTimer = false;
-	// flag to print the warning only once
-	static bool checkGameDomain = true;
-
-	if (!checkGameDomain) {
-		checkGameDomain = g_system->isOverlayVisible();
-	}
 
 	if (!inTimer) {
 		inTimer = true;
 		((DefaultTimerManager *)_timerManager)->checkTimers();
 		inTimer = false;
-	} else if (checkGameDomain) {
+	} else {
 		const Common::ConfigManager::Domain *activeDomain = ConfMan.getActiveDomain();
-		if (activeDomain) {
-			atari_warning("%s/%s calls update() from timer",
-				activeDomain->getValOrDefault("engineid").c_str(),
-				activeDomain->getValOrDefault("gameid").c_str());
-
-			checkGameDomain = false;
-		}
+		warning("%s/%s calls update() from timer",
+			activeDomain->getValOrDefault("engineid").c_str(),
+			activeDomain->getValOrDefault("gameid").c_str());
 	}
 
 	((AtariMixerManager *)_mixerManager)->update();




More information about the Scummvm-git-logs mailing list