[Scummvm-git-logs] scummvm master -> 1870433daf4046dce910754595f94850bca7d72e
mikrosk
noreply at scummvm.org
Sat Apr 8 18:28:19 UTC 2023
This automated email contains information about 4 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
a4e85dab01 BACKENDS: ATARI: Remove double buffering & vsync
eec6139f55 PORTS: Remove target executable before copy
740aefcedf BACKENDS: ATARI: Re-enable DOSBOX OPL
1870433daf BACKENDS: ATARI: Refactor & optimize dirty rects
Commit: a4e85dab01b1c4b50f2a4f721a2012436c91cc74
https://github.com/scummvm/scummvm/commit/a4e85dab01b1c4b50f2a4f721a2012436c91cc74
Author: Miro Kropacek (miro.kropacek at gmail.com)
Date: 2023-04-08T20:27:43+02:00
Commit Message:
BACKENDS: ATARI: Remove double buffering & vsync
ScummVM engines are not built for synchronous screen locking (i.e.
updateScreen() can't be really used for any sort of blocking updates
otherwise performance suffers).
Single buffering now means deliberate tearing as a speed optimization
and triple buffering provides a tearingless picture with slight overhead.
Changed paths:
backends/events/atari/atari-events.cpp
backends/graphics/atari/atari-graphics-asm.S
backends/graphics/atari/atari-graphics-supervidel.h
backends/graphics/atari/atari-graphics-videl.h
backends/graphics/atari/atari-graphics.cpp
backends/graphics/atari/atari-graphics.h
backends/platform/atari/osystem_atari.cpp
backends/platform/atari/readme.txt
diff --git a/backends/events/atari/atari-events.cpp b/backends/events/atari/atari-events.cpp
index 1eeccb7f7e0..01c6841362c 100644
--- a/backends/events/atari/atari-events.cpp
+++ b/backends/events/atari/atari-events.cpp
@@ -104,29 +104,6 @@ bool AtariEventSource::pollEvent(Common::Event &event) {
if (!_graphicsManager)
return false;
- static uint32 startMillis = _system->getMillis();
- static uint32 oldMillis = _system->getMillis();
- uint32 curMillis = _system->getMillis();
-
- uint32 diff = curMillis - oldMillis;
- oldMillis = curMillis;
-
- if (diff > 0) {
- static float avgFpsSum;
- static int avgFpsCount;
-
- avgFpsSum += 1000.0f / diff;
- avgFpsCount++;
-
- if (curMillis - startMillis >= 1000) {
- float avgFps = avgFpsSum / avgFpsCount;
- //debug("*** Average FPS in 1s: %f ***", avgFps);
- startMillis = curMillis;
- avgFpsSum = 0;
- avgFpsCount = 0;
- }
- }
-
_system->update();
if ((g_atari_ikbd_mouse_buttons_state & 0x01) && !_oldRmbDown) {
diff --git a/backends/graphics/atari/atari-graphics-asm.S b/backends/graphics/atari/atari-graphics-asm.S
index 7da4549a8ed..5d79334cec2 100644
--- a/backends/graphics/atari/atari-graphics-asm.S
+++ b/backends/graphics/atari/atari-graphics-asm.S
@@ -31,8 +31,6 @@
.globl _asm_screen_set_vram
.globl _asm_screen_set_scp_res
- .globl _vbl_counter
-
.text
| extern void asm_screen_tt_save(void);
@@ -268,7 +266,6 @@ vbl:
addq.l #1,0x0462.w | _vbclock
addq.l #1,0x0466.w | _frclock
- addq.l #1,_vbl_counter | to avoid accessing protected memory
tst.w has_pending_scp
beq.b vbl_no_pending_scp
@@ -352,6 +349,3 @@ save_pal:
ds.l 256+16/2 | old colours (sized for falcon+ste palette)
save_video:
ds.b 32+12+2 | old video regs (size of falcon regs)
-
-_vbl_counter:
- ds.l 1
diff --git a/backends/graphics/atari/atari-graphics-supervidel.h b/backends/graphics/atari/atari-graphics-supervidel.h
index ff612aa3da7..4d31a32b525 100644
--- a/backends/graphics/atari/atari-graphics-supervidel.h
+++ b/backends/graphics/atari/atari-graphics-supervidel.h
@@ -62,10 +62,9 @@ public:
virtual const OSystem::GraphicsMode *getSupportedGraphicsModes() const override {
static const OSystem::GraphicsMode graphicsModes[] = {
- {"direct", "Direct rendering", 0},
- {"single", "Single buffering", 1},
- {"double", "Double buffering", 2},
- {"triple", "Triple buffering", 3},
+ {"direct", "Direct rendering", (int)GraphicsMode::DirectRendering},
+ {"single", "Single buffering", (int)GraphicsMode::SingleBuffering},
+ {"triple", "Triple buffering", (int)GraphicsMode::TripleBuffering},
{nullptr, nullptr, 0 }
};
return graphicsModes;
diff --git a/backends/graphics/atari/atari-graphics-videl.h b/backends/graphics/atari/atari-graphics-videl.h
index 4b14db6e81b..c9906c33568 100644
--- a/backends/graphics/atari/atari-graphics-videl.h
+++ b/backends/graphics/atari/atari-graphics-videl.h
@@ -41,9 +41,8 @@ public:
virtual const OSystem::GraphicsMode *getSupportedGraphicsModes() const override {
static const OSystem::GraphicsMode graphicsModes[] = {
- {"single", "Single buffering", 1},
- {"double", "Double buffering", 2},
- {"triple", "Triple buffering", 3},
+ {"single", "Single buffering", (int)GraphicsMode::SingleBuffering},
+ {"triple", "Triple buffering", (int)GraphicsMode::TripleBuffering},
{nullptr, nullptr, 0 }
};
return graphicsModes;
diff --git a/backends/graphics/atari/atari-graphics.cpp b/backends/graphics/atari/atari-graphics.cpp
index 05803492fa4..a02077b489d 100644
--- a/backends/graphics/atari/atari-graphics.cpp
+++ b/backends/graphics/atari/atari-graphics.cpp
@@ -93,9 +93,6 @@ bool AtariGraphicsManager::hasFeature(OSystem::Feature f) const {
//debug("hasFeature(kFeatureCursorPalette): %d", isOverlayVisible());
//return isOverlayVisible();
return true;
- case OSystem::Feature::kFeatureVSync:
- //debug("hasFeature(kFeatureVSync): %d", _vsync);
- return true;
default:
return false;
}
@@ -108,10 +105,6 @@ void AtariGraphicsManager::setFeatureState(OSystem::Feature f, bool enable) {
_oldAspectRatioCorrection = _aspectRatioCorrection;
_aspectRatioCorrection = enable;
break;
- case OSystem::Feature::kFeatureVSync:
- debug("setFeatureState(kFeatureVSync): %d", enable);
- _guiVsync = std::make_pair(enable, true);
- break;
default:
[[fallthrough]];
}
@@ -126,17 +119,6 @@ bool AtariGraphicsManager::getFeatureState(OSystem::Feature f) const {
//debug("getFeatureState(kFeatureCursorPalette): %d", isOverlayVisible());
//return isOverlayVisible();
return true;
- case OSystem::Feature::kFeatureVSync:
- //debug("getFeatureState(kFeatureVSync): based on mode %d", (int)_currentState.mode);
- switch (_currentState.mode) {
- case GraphicsMode::DirectRendering:
- case GraphicsMode::SingleBuffering:
- return _guiVsync.second ? _guiVsync.first : ConfMan.getBool("vsync");
- case GraphicsMode::DoubleBuffering:
- return true;
- case GraphicsMode::TripleBuffering:
- return false;
- }
default:
return false;
}
@@ -228,8 +210,6 @@ OSystem::TransactionError AtariGraphicsManager::endGFXTransaction() {
_currentState = _pendingState;
- debug("endGFXTransaction: vsync: %d (based on mode %d)", getFeatureState(OSystem::Feature::kFeatureVSync), (int)_currentState.mode);
-
return OSystem::kTransactionSuccess;
}
@@ -258,10 +238,7 @@ void AtariGraphicsManager::copyRectToScreen(const void *buf, int pitch, int x, i
_dirtyScreenRect = Common::Rect(x, y, x + w, y + h);
- auto vsync = _guiVsync;
- _guiVsync = std::make_pair(false, true);
updateScreen();
- _guiVsync = vsync;
}
}
@@ -277,10 +254,7 @@ void AtariGraphicsManager::unlockScreen() {
} else {
_dirtyScreenRect = Common::Rect(_screenSurface.w, _screenSurface.h);
- auto vsync = _guiVsync;
- _guiVsync = std::make_pair(false, true);
updateScreen();
- _guiVsync = vsync;
}
}
@@ -341,35 +315,20 @@ void AtariGraphicsManager::updateScreen() {
screenUpdated = updateBuffered(_chunkySurface, _screenSurface, _workScreen->dirtyRects);
assert(_workScreen == _buffer[BACK_BUFFER1]);
- if (_currentState.mode == GraphicsMode::DoubleBuffering) {
- // apply dirty rects from previous frame
- if (!_buffer[FRONT_BUFFER]->dirtyRects.empty()) {
- screenUpdated |= updateBuffered(_chunkySurface, _screenSurface, _buffer[FRONT_BUFFER]->dirtyRects);
- // clear the least recent dirty rects
- _buffer[FRONT_BUFFER]->dirtyRects.clear();
- }
-
- if (screenUpdated) {
- ScreenInfo *tmp = _buffer[FRONT_BUFFER];
- _buffer[FRONT_BUFFER] = _buffer[BACK_BUFFER1];
- _buffer[BACK_BUFFER1] = tmp;
- }
- } else if (_currentState.mode == GraphicsMode::TripleBuffering) {
- // apply dirty rects from previous frame
- if (!_buffer[BACK_BUFFER2]->dirtyRects.empty()) {
- screenUpdated |= updateBuffered(_chunkySurface, _screenSurface, _buffer[BACK_BUFFER2]->dirtyRects);
- // clear the least recent dirty rects
- _buffer[BACK_BUFFER2]->dirtyRects.clear();
- }
+ // apply dirty rects from previous frame
+ if (!_buffer[BACK_BUFFER2]->dirtyRects.empty()) {
+ screenUpdated |= updateBuffered(_chunkySurface, _screenSurface, _buffer[BACK_BUFFER2]->dirtyRects);
+ // clear the least recent dirty rects
+ _buffer[BACK_BUFFER2]->dirtyRects.clear();
+ }
- // render into BACK_BUFFER1 and/or BACK_BUFFER2 and set the most recent one
- if (screenUpdated) {
- _buffer[FRONT_BUFFER] = _buffer[BACK_BUFFER1];
+ // render into BACK_BUFFER1 and/or BACK_BUFFER2 and set the most recent one
+ if (screenUpdated) {
+ _buffer[FRONT_BUFFER] = _buffer[BACK_BUFFER1];
- ScreenInfo *tmp = _buffer[BACK_BUFFER1];
- _buffer[BACK_BUFFER1] = _buffer[BACK_BUFFER2];
- _buffer[BACK_BUFFER2] = tmp;
- }
+ ScreenInfo *tmp = _buffer[BACK_BUFFER1];
+ _buffer[BACK_BUFFER1] = _buffer[BACK_BUFFER2];
+ _buffer[BACK_BUFFER2] = tmp;
}
// finish blitting before setting new screen address
@@ -414,9 +373,6 @@ void AtariGraphicsManager::updateScreen() {
}
_oldAspectRatioCorrection = _aspectRatioCorrection;
}
-
- if (!isOverlayVisible() && (getFeatureState(OSystem::Feature::kFeatureVSync) & screenUpdated))
- waitForVbl();
#endif
//debug("end of updateScreen");
}
@@ -681,13 +637,6 @@ void AtariGraphicsManager::setVidelResolution() const {
}
}
-void AtariGraphicsManager::waitForVbl() const {
- extern volatile uint32 vbl_counter;
- uint32 counter = vbl_counter;
-
- while (counter == vbl_counter);
-}
-
bool AtariGraphicsManager::updateDirect() {
bool &cursorPositionChanged = _workScreen->cursorPositionChanged;
bool &cursorSurfaceChanged = _workScreen->cursorSurfaceChanged;
@@ -759,7 +708,7 @@ bool AtariGraphicsManager::updateDirect() {
bool AtariGraphicsManager::updateBuffered(const Graphics::Surface &srcSurface, Graphics::Surface &dstSurface, const DirtyRects &dirtyRects) {
// workscreen related setting; these are used even if called repeatedly
- // for double and triple buffering
+ // for triple buffering
bool &cursorPositionChanged = _workScreen->cursorPositionChanged;
bool &cursorSurfaceChanged = _workScreen->cursorSurfaceChanged;
Common::Rect &oldCursorRect = _workScreen->oldCursorRect;
diff --git a/backends/graphics/atari/atari-graphics.h b/backends/graphics/atari/atari-graphics.h
index bcfc3284303..e72f66b2b3d 100644
--- a/backends/graphics/atari/atari-graphics.h
+++ b/backends/graphics/atari/atari-graphics.h
@@ -25,7 +25,6 @@
#include "backends/graphics/graphics.h"
#include <mint/osbind.h>
-#include <utility> // std::pair
#include <vector>
#include "common/events.h"
@@ -106,10 +105,9 @@ protected:
void freeSurfaces();
enum class GraphicsMode : int {
- DirectRendering,
- SingleBuffering,
- DoubleBuffering,
- TripleBuffering
+ DirectRendering = 0,
+ SingleBuffering = 1,
+ TripleBuffering = 3
};
struct GraphicsState {
@@ -141,7 +139,6 @@ private:
};
void setVidelResolution() const;
- void waitForVbl() const;
bool updateDirect();
bool updateBuffered(const Graphics::Surface &srcSurface, Graphics::Surface &dstSurface, const DirtyRects &dirtyRects);
@@ -191,7 +188,6 @@ private:
bool _vgaMonitor = true;
bool _aspectRatioCorrection = false;
bool _oldAspectRatioCorrection = false;
- std::pair<bool, bool> _guiVsync; // poor man's std::optional (first - value, second - has_value)
GraphicsState _currentState{ (GraphicsMode)getDefaultGraphicsMode() };
diff --git a/backends/platform/atari/osystem_atari.cpp b/backends/platform/atari/osystem_atari.cpp
index 04385b4eaa5..05b26790a79 100644
--- a/backends/platform/atari/osystem_atari.cpp
+++ b/backends/platform/atari/osystem_atari.cpp
@@ -171,9 +171,8 @@ void OSystem_Atari::delayMillis(uint msecs) {
}
void OSystem_Atari::getTimeAndDate(TimeDate &td, bool skipRecord) const {
- debug("getTimeAndDate");
+ //debug("getTimeAndDate");
time_t curTime = time(0);
- // TODO: if too slow (e.g. when calling RandomSource::RandomSource()), rewrite
struct tm t = *localtime(&curTime);
td.tm_sec = t.tm_sec;
td.tm_min = t.tm_min;
diff --git a/backends/platform/atari/readme.txt b/backends/platform/atari/readme.txt
index fcc173bfcd8..b5ff12760b3 100644
--- a/backends/platform/atari/readme.txt
+++ b/backends/platform/atari/readme.txt
@@ -53,7 +53,7 @@ less hungry games even a CT2/DFB at 50 MHz or the AfterBurner040 could be enough).
change is the exclusion of the 16bpp games (those are mostly hi-res anyway)
but games in 640x480 at 8bpp work nicely.
-- Direct rendering and single/double/triple buffering support.
+- Direct rendering and single/triple buffering support.
- Custom (and optimal) drawing routines (especially for the cursor).
@@ -99,20 +99,14 @@ Graphics modes
This topic is more complex than it looks. ScummVM renders game graphics using
rectangles and this port offers following options to render them:
-Direct rendering (vsync on/off) - present only with the SuperVidel
-Single buffering (vsync on/off)
-Double buffering (vsync always on, the checkbox is ignored)
-Triple buffering (vsync always off, the checkbox is ignored)
+Direct rendering (present only with the SuperVidel)
+Single buffering
+Triple buffering
Direct rendering:
~~~~~~~~~~~~~~~~~
-This is direct writing of the pixels into (SuperVidel's) screen buffer. Since
-the updates are supplied as rectangles and not the whole screen there's no way
-to implement direct writing *and* double/triple buffering. Vsync() only
-synchronizes the point when the rendering process begins - if it takes more
-than the time reserved for the vertical blank interrupt (what happens
-with most of the games), you'll see screen tearing.
+This is direct writing of the pixels into (SuperVidel's) screen buffer.
Pros:
@@ -143,9 +137,7 @@ This is very similar to the previous mode with the difference that the engine
uses an intermediate buffer for storing the rectangles but yet it remembers
which ones they were. It works also on plain Videl and applies the chunky to
planar process to each one of the rectangles separately, avoiding fullscreen
-updates (but if such is needed, there is an optimized code path for it). Vsync()
-is used the same way as in the previous mode, i.e. screen tearing is still
-possible.
+updates (but if such is needed, there is an optimized code path for it).
Pros:
@@ -161,45 +153,10 @@ Cons:
SuperBlitter used: yes, for rectangle blitting to screen and cursor restoration.
Sometimes also for generic copying between buffers (see above).
-Double buffering:
-~~~~~~~~~~~~~~~~~
-
-The most common rendering mode. It extends the idea of single buffering - it
-renders into two buffers, one is visible while the other one is used for
-updating. At the end of the update process the two buffers are swapped, so the
-newly updated one is displayed. By definition, Vsync() must be always enabled
-(the buffers are swapped in the vertical blank handler) otherwise you'd see
-screen tearing.
-
-Pros:
-
-- stable frame rate, leading to fixed e.g. 30 FPS rendering for the whole time
- if game takes, say, 1.7 - 1.9 frames per update
-
-- no screen tearing in any situation
-
-Cons:
-
-- if there is too many smaller rectangles, it can be less efficient than
- single buffering
-
-- frame rate is set to 60/30/15/etc FPS so you can see big irregular jumps
- between 30 and 15 FPS for example; this is happening when screen updates take
- variable amount of time but since Vsync() is always called, the rendering
- pipeline has to wait until the next frame even if only 1% of the frame time
- has been used.
-
-SuperBlitter used: yes, for rectangle blitting to screen and cursor restoration.
-Sometimes also for generic copying between buffers (see above).
-
Triple buffering:
~~~~~~~~~~~~~~~~~
-Best of both worlds - screen tearing is avoided thanks to using of multiple
-buffers and the rendering pipeline doesn't have to wait until Vsync() (therefore
-this flag is ignored).
-
-Please note that Atari backend uses "true" triple buffering as described in
+This is the "true" triple buffering as described in
https://en.wikipedia.org/wiki/Multiple_buffering#Triple_buffering and not "swap
chain" as described in https://en.wikipedia.org/wiki/Swap_chain. The latter
would be slightly slower as three buffers would need to be updated instead of
@@ -207,6 +164,8 @@ two.
Pros:
+- no screen tearing
+
- best compromise between performance and visual experience
- works well with both higher and lower frame rates
@@ -219,8 +178,7 @@ Cons:
- slightly irregular frame rate (depends solely on the game's complexity)
- in case of extremely fast rendering, one or more frames are dropped in favor
- of showing only the most recent one (unlikely; double buffer guaranties that
- every frame is shown, no matter how insignificant)
+ of showing only the most recent one
SuperBlitter used: yes, for rectangle blitting to screen and cursor restoration.
Sometimes also for generic copying between buffers (see above).
@@ -315,14 +273,6 @@ Please note that it is not that bad, you surely can play The Secret of Monkey
Island with AdLib enabled (but the CD/talkie versions sound better and
are cheaper to play ;)).
-Vsync in GUI
-~~~~~~~~~~~~
-
-Carefully with the vsync option. It can easily cripple direct/single buffer
-rendering by 10-15 FPS if not used with caution. That happens if a game takes,
-say, 1.2 frames per update (so causing screen tearing anyway and rendering the
-option useless) but Vsync() forces it to wait 2 full frames instead.
-
Slow GUI
~~~~~~~~
@@ -374,9 +324,6 @@ Future plans
- add support for the TT030; this would be easily possible when I rewrite the
renderer with a more flexible resolution switching
-- ignore (queue) updateScreen() calls to avoid aggressive drawing / buffer
- switching from some engines; update every X ms instead
-
- don't hardcode some of the buffers for cacheing purposes, determine the size
based on amount of free RAM
Commit: eec6139f5511fa38ba2a29dd291ade4d6cd857d6
https://github.com/scummvm/scummvm/commit/eec6139f5511fa38ba2a29dd291ade4d6cd857d6
Author: Miro Kropacek (miro.kropacek at gmail.com)
Date: 2023-04-08T20:27:44+02:00
Commit Message:
PORTS: Remove target executable before copy
This speeds up the install process considerably when the executable is
non-stripped (huge).
Changed paths:
ports.mk
diff --git a/ports.mk b/ports.mk
index f41d717bf6a..7ce2ebcc09d 100644
--- a/ports.mk
+++ b/ports.mk
@@ -59,6 +59,7 @@ endif
dist-generic: $(EXECUTABLE) $(PLUGINS)
mkdir -p ./dist-generic/scummvm/data
mkdir -p ./dist-generic/scummvm/doc
+ rm -f ./dist-generic/scummvm/$(EXECUTABLE)
cp $(EXECUTABLE) ./dist-generic/scummvm
ifeq ($(BACKEND), atari)
m68k-atari-mint-flags -S ./dist-generic/scummvm/$(EXECUTABLE)
Commit: 740aefcedfc485aebe92c6b7064748a97810434d
https://github.com/scummvm/scummvm/commit/740aefcedfc485aebe92c6b7064748a97810434d
Author: Miro Kropacek (miro.kropacek at gmail.com)
Date: 2023-04-08T20:27:44+02:00
Commit Message:
BACKENDS: ATARI: Re-enable DOSBOX OPL
After hearing the difference between MAME and DOSBOX OPL I have decided
to keep it available. Some games select it by default (and therefore
the game takes more CPU time) but the reason is valid.
Changed paths:
configure
diff --git a/configure b/configure
index 1714ac2e179..00554044ba2 100755
--- a/configure
+++ b/configure
@@ -3974,7 +3974,7 @@ case $_backend in
#append_var DEFINES "-DDISABLE_FANCY_THEMES"
append_var DEFINES "-DDISABLE_SID"
append_var DEFINES "-DDISABLE_NES_APU"
- append_var DEFINES "-DDISABLE_DOSBOX_OPL"
+ #append_var DEFINES "-DDISABLE_DOSBOX_OPL"
append_var ASFLAGS "-m68030"
append_var CXXFLAGS "-m68020-60"
append_var LDFLAGS "-m68020-60"
Commit: 1870433daf4046dce910754595f94850bca7d72e
https://github.com/scummvm/scummvm/commit/1870433daf4046dce910754595f94850bca7d72e
Author: Miro Kropacek (miro.kropacek at gmail.com)
Date: 2023-04-08T20:27:44+02:00
Commit Message:
BACKENDS: ATARI: Refactor & optimize dirty rects
This was long overdue. From my observation dirty rects don't need much
care, usually game engines already prepare them in a good shape (no
overlapping).
Also the overhead of calling the rect version of C2P isn't as big as I
was fearing, 256 64x64 rectangles are blitted roughly as quickly
as blitting one 1 MB block.
Removal of the rects traversal significantly speeds up Eco Quest for
instance.
Changed paths:
backends/graphics/atari/atari-graphics-supervidel.h
backends/graphics/atari/atari-graphics.cpp
backends/graphics/atari/atari-graphics.h
diff --git a/backends/graphics/atari/atari-graphics-supervidel.h b/backends/graphics/atari/atari-graphics-supervidel.h
index 4d31a32b525..72391b1e4c4 100644
--- a/backends/graphics/atari/atari-graphics-supervidel.h
+++ b/backends/graphics/atari/atari-graphics-supervidel.h
@@ -70,7 +70,7 @@ public:
return graphicsModes;
}
-protected:
+private:
AtariMemAlloc getStRamAllocFunc() const override {
return [](size_t bytes) {
uintptr ptr = Mxalloc(bytes, MX_STRAM);
@@ -85,7 +85,6 @@ protected:
return [](void *ptr) { Mfree((uintptr)ptr & 0x00FFFFFF); };
}
-private:
static long hasSvRamBoosted() {
register long ret __asm__ ("d0") = 0;
diff --git a/backends/graphics/atari/atari-graphics.cpp b/backends/graphics/atari/atari-graphics.cpp
index a02077b489d..640e5d5e109 100644
--- a/backends/graphics/atari/atari-graphics.cpp
+++ b/backends/graphics/atari/atari-graphics.cpp
@@ -24,7 +24,6 @@
#include <mint/cookie.h>
#include <mint/falcon.h>
#include <mint/osbind.h>
-#include <utility>
#include "backends/graphics/atari/atari-graphics-asm.h"
#include "backends/graphics/atari/atari-graphics-superblitter.h"
@@ -176,26 +175,16 @@ OSystem::TransactionError AtariGraphicsManager::endGFXTransaction() {
_chunkySurface.init(_pendingState.width, _pendingState.height, _pendingState.width,
_chunkySurface.getPixels(), _pendingState.format);
- _buffer[FRONT_BUFFER]->reset();
- _buffer[BACK_BUFFER1]->reset();
- _buffer[BACK_BUFFER2]->reset();
+ _screen[FRONT_BUFFER]->reset(_pendingState.width, _pendingState.height);
+ _screen[BACK_BUFFER1]->reset(_pendingState.width, _pendingState.height);
+ _screen[BACK_BUFFER2]->reset(_pendingState.width, _pendingState.height);
- _workScreen = _buffer[_pendingState.mode <= GraphicsMode::SingleBuffering ? FRONT_BUFFER : BACK_BUFFER1];
- _screenSurface.init(_pendingState.width, _pendingState.height, _pendingState.width,
- _workScreen->p, _screenSurface.format);
+ _workScreen = _screen[_pendingState.mode <= GraphicsMode::SingleBuffering ? FRONT_BUFFER : BACK_BUFFER1];
// in case of resolution change from GUI
if (_oldWorkScreen)
_oldWorkScreen = _workScreen;
- // some games do not initialize their viewport entirely
- if (_pendingState.mode != GraphicsMode::DirectRendering) {
- memset(_chunkySurface.getPixels(), 0, _chunkySurface.h * _chunkySurface.pitch);
- addDirtyRect(_chunkySurface, _workScreen->dirtyRects, Common::Rect(_chunkySurface.w, _chunkySurface.h));
- } else {
- memset(_screenSurface.getPixels(), 0, _screenSurface.h * _screenSurface.pitch);
- }
-
memset(_palette, 0, sizeof(_palette));
_pendingScreenChange = kPendingScreenChangeScreen | kPendingScreenChangePalette;
@@ -231,12 +220,11 @@ void AtariGraphicsManager::copyRectToScreen(const void *buf, int pitch, int x, i
if (_currentState.mode != GraphicsMode::DirectRendering) {
_chunkySurface.copyRectToSurface(buf, pitch, x, y, w, h);
- addDirtyRect(_chunkySurface, _workScreen->dirtyRects, Common::Rect(x, y, x + w, y + h));
+ _workScreen->addDirtyRect(Common::Rect(x, y, x + w, y + h));
} else {
// TODO: c2p with 16pix align
- _screenSurface.copyRectToSurface(buf, pitch, x, y, w, h);
-
- _dirtyScreenRect = Common::Rect(x, y, x + w, y + h);
+ _workScreen->surf.copyRectToSurface(buf, pitch, x, y, w, h);
+ _workScreen->addDirtyRect(Common::Rect(x, y, x + w, y + h));
updateScreen();
}
@@ -245,17 +233,16 @@ void AtariGraphicsManager::copyRectToScreen(const void *buf, int pitch, int x, i
Graphics::Surface *AtariGraphicsManager::lockScreen() {
//debug("lockScreen");
- return _currentState.mode != GraphicsMode::DirectRendering ? &_chunkySurface : &_screenSurface;
+ return _currentState.mode != GraphicsMode::DirectRendering ? &_chunkySurface : &_workScreen->surf;
}
void AtariGraphicsManager::unlockScreen() {
- if (_currentState.mode != GraphicsMode::DirectRendering) {
- addDirtyRect(_chunkySurface, _workScreen->dirtyRects, Common::Rect(_chunkySurface.w, _chunkySurface.h));
- } else {
- _dirtyScreenRect = Common::Rect(_screenSurface.w, _screenSurface.h);
+ //debug("unlockScreen: %d x %d", _workScreen->surf.w, _workScreen->surf.h);
+
+ _workScreen->addDirtyRect(Common::Rect(_workScreen->surf.w, _workScreen->surf.h));
+ if (_currentState.mode == GraphicsMode::DirectRendering)
updateScreen();
- }
}
void AtariGraphicsManager::fillScreen(uint32 col) {
@@ -285,8 +272,7 @@ void AtariGraphicsManager::updateScreen() {
}
// updates outOfScreen OR srcRect/dstRect (only if visible/needed)
- _cursor.update(isOverlayVisible() ? _screenOverlaySurface : _screenSurface,
- _workScreen->cursorPositionChanged || _workScreen->cursorSurfaceChanged);
+ _cursor.update(_workScreen->surf, _workScreen->cursorPositionChanged || _workScreen->cursorSurfaceChanged);
bool screenUpdated;
@@ -295,50 +281,58 @@ void AtariGraphicsManager::updateScreen() {
assert(_currentState.mode >= GraphicsMode::DirectRendering && _currentState.mode <= GraphicsMode::TripleBuffering);
if (isOverlayVisible()) {
- screenUpdated = updateBuffered(_overlaySurface, _screenOverlaySurface, _workScreen->dirtyRects);
- assert(_workScreen == _buffer[OVERLAY_BUFFER]);
+ screenUpdated = updateBuffered(_overlaySurface, _workScreen->dirtyRects);
+ assert(_workScreen == _screen[OVERLAY_BUFFER]);
- _workScreen->dirtyRects.clear();
+ _workScreen->clearDirtyRects();
unlockSuperBlitter();
} else if (_currentState.mode == GraphicsMode::DirectRendering) {
screenUpdated = updateDirect();
- assert(_workScreen == _buffer[FRONT_BUFFER]);
+ assert(_workScreen == _screen[FRONT_BUFFER]);
+ _workScreen->clearDirtyRects();
unlockSuperBlitter();
} else if (_currentState.mode == GraphicsMode::SingleBuffering) {
- screenUpdated = updateBuffered(_chunkySurface, _screenSurface, _workScreen->dirtyRects);
- assert(_workScreen == _buffer[FRONT_BUFFER]);
+ screenUpdated = updateBuffered(_chunkySurface, _workScreen->dirtyRects);
+ assert(_workScreen == _screen[FRONT_BUFFER]);
- _workScreen->dirtyRects.clear();
+ _workScreen->clearDirtyRects();
unlockSuperBlitter();
} else {
- screenUpdated = updateBuffered(_chunkySurface, _screenSurface, _workScreen->dirtyRects);
- assert(_workScreen == _buffer[BACK_BUFFER1]);
-
- // apply dirty rects from previous frame
- if (!_buffer[BACK_BUFFER2]->dirtyRects.empty()) {
- screenUpdated |= updateBuffered(_chunkySurface, _screenSurface, _buffer[BACK_BUFFER2]->dirtyRects);
- // clear the least recent dirty rects
- _buffer[BACK_BUFFER2]->dirtyRects.clear();
+ assert(_workScreen == _screen[BACK_BUFFER1]);
+
+ if (_workScreen->fullRedrawPending) {
+ // scheduled fullscreen redraw in this frame...
+ screenUpdated = updateBuffered(_chunkySurface, _workScreen->dirtyRects);
+ } else if (_screen[BACK_BUFFER2]->fullRedrawPending) {
+ // scheduled fullscreen redraw in previous frame...
+ screenUpdated = updateBuffered(_chunkySurface, _screen[BACK_BUFFER2]->dirtyRects);
+ } else {
+ screenUpdated = updateBuffered(_chunkySurface, _workScreen->dirtyRects);
+ // apply dirty rects from previous frame
+ if (!_screen[BACK_BUFFER2]->dirtyRects.empty())
+ screenUpdated |= updateBuffered(_chunkySurface, _screen[BACK_BUFFER2]->dirtyRects);
}
+ // clear the least recent dirty rects
+ _screen[BACK_BUFFER2]->clearDirtyRects();
+
// render into BACK_BUFFER1 and/or BACK_BUFFER2 and set the most recent one
if (screenUpdated) {
- _buffer[FRONT_BUFFER] = _buffer[BACK_BUFFER1];
+ _screen[FRONT_BUFFER] = _screen[BACK_BUFFER1];
- ScreenInfo *tmp = _buffer[BACK_BUFFER1];
- _buffer[BACK_BUFFER1] = _buffer[BACK_BUFFER2];
- _buffer[BACK_BUFFER2] = tmp;
+ Screen *tmp = _screen[BACK_BUFFER1];
+ _screen[BACK_BUFFER1] = _screen[BACK_BUFFER2];
+ _screen[BACK_BUFFER2] = tmp;
}
// finish blitting before setting new screen address
unlockSuperBlitter();
#ifdef SCREEN_ACTIVE
- asm_screen_set_vram(_buffer[FRONT_BUFFER]->p);
+ asm_screen_set_vram(_screen[FRONT_BUFFER]->surf.getPixels());
#endif
- _workScreen = _buffer[BACK_BUFFER1];
- _screenSurface.setPixels(_workScreen->p);
+ _workScreen = _screen[BACK_BUFFER1];
}
#ifdef SCREEN_ACTIVE
@@ -350,14 +344,14 @@ void AtariGraphicsManager::updateScreen() {
else
asm_screen_set_scp_res(scp_640x480x8_rgb);
- asm_screen_set_vram(_screenOverlaySurface.getPixels());
+ asm_screen_set_vram(_screen[OVERLAY_BUFFER]->surf.getPixels());
asm_screen_set_falcon_palette(_overlayPalette);
resolutionChanged = true;
}
if (_pendingScreenChange & kPendingScreenChangeScreen) {
setVidelResolution();
- asm_screen_set_vram(_buffer[FRONT_BUFFER]->p);
+ asm_screen_set_vram(_screen[FRONT_BUFFER]->surf.getPixels());
resolutionChanged = true;
}
@@ -400,7 +394,7 @@ void AtariGraphicsManager::showOverlay(bool inGUI) {
_cursor.swap();
_oldWorkScreen = _workScreen;
- _workScreen = _buffer[OVERLAY_BUFFER];
+ _workScreen = _screen[OVERLAY_BUFFER];
_overlayVisible = true;
}
@@ -415,7 +409,7 @@ void AtariGraphicsManager::hideOverlay() {
_pendingScreenChange |= (kPendingScreenChangeScreen | kPendingScreenChangePalette);
// do not cache dirtyRects and oldCursorRect
- _workScreen->reset();
+ _workScreen->reset(getOverlayWidth(), getOverlayHeight());
_workScreen = _oldWorkScreen;
_oldWorkScreen = nullptr;
@@ -433,7 +427,8 @@ void AtariGraphicsManager::clearOverlay() {
if (!_overlayVisible)
return;
- const Graphics::Surface &sourceSurface = _currentState.mode == GraphicsMode::DirectRendering ? _screenSurface : _chunkySurface;
+ const Graphics::Surface &sourceSurface =
+ _currentState.mode == GraphicsMode::DirectRendering ? _screen[FRONT_BUFFER]->surf : _chunkySurface;
int w = sourceSurface.w;
int h = sourceSurface.h;
@@ -487,7 +482,7 @@ void AtariGraphicsManager::clearOverlay() {
memset(_overlaySurface.getBasePtr(0, _overlaySurface.h - vOffset), 0, _overlaySurface.pitch * vOffset);
- addDirtyRect(_overlaySurface, _buffer[OVERLAY_BUFFER]->dirtyRects, Common::Rect(_overlaySurface.w, _overlaySurface.h));
+ _screen[OVERLAY_BUFFER]->addDirtyRect(Common::Rect(_screen[OVERLAY_BUFFER]->surf.w, _screen[OVERLAY_BUFFER]->surf.h));
}
void AtariGraphicsManager::grabOverlay(Graphics::Surface &surface) const {
@@ -500,8 +495,7 @@ void AtariGraphicsManager::copyRectToOverlay(const void *buf, int pitch, int x,
//debug("copyRectToOverlay: %d, %d, %d, %d, %d", pitch, x, y, w, h);
_overlaySurface.copyRectToSurface(buf, pitch, x, y, w, h);
-
- addDirtyRect(_overlaySurface, _buffer[OVERLAY_BUFFER]->dirtyRects, Common::Rect(x, y, x + w, y + h));
+ _screen[OVERLAY_BUFFER]->addDirtyRect(Common::Rect(x, y, x + w, y + h));
}
bool AtariGraphicsManager::showMouse(bool visible) {
@@ -543,7 +537,7 @@ void AtariGraphicsManager::setCursorPalette(const byte *colors, uint start, uint
}
void AtariGraphicsManager::updateMousePosition(int deltaX, int deltaY) {
- _cursor.updatePosition(deltaX, deltaY, isOverlayVisible() ? _screenOverlaySurface : _screenSurface);
+ _cursor.updatePosition(deltaX, deltaY, _workScreen->surf);
cursorPositionChanged();
}
@@ -577,26 +571,19 @@ Common::Keymap *AtariGraphicsManager::getKeymap() const {
void AtariGraphicsManager::allocateSurfaces() {
for (int i : { FRONT_BUFFER, BACK_BUFFER1, BACK_BUFFER2 }) {
- allocateAtariSurface(_screenSurface, SCREEN_WIDTH, SCREEN_HEIGHT, PIXELFORMAT_CLUT8, getStRamAllocFunc());
- _buffer[i] = new ScreenInfo((byte *)_screenSurface.getPixels());
+ _screen[i] = new Screen(this, SCREEN_WIDTH, SCREEN_HEIGHT, PIXELFORMAT_CLUT8);
}
+ _screen[OVERLAY_BUFFER] = new Screen(this, getOverlayWidth(), getOverlayHeight(), getOverlayFormat());
_chunkySurface.create(SCREEN_WIDTH, SCREEN_HEIGHT, PIXELFORMAT_CLUT8);
-
- allocateAtariSurface(_screenOverlaySurface, getOverlayWidth(), getOverlayHeight(), getOverlayFormat(), getStRamAllocFunc());
- _buffer[OVERLAY_BUFFER] = new ScreenInfo((byte *)_screenOverlaySurface.getPixels());
-
_overlaySurface.create(getOverlayWidth(), getOverlayHeight(), getOverlayFormat());
}
void AtariGraphicsManager::freeSurfaces() {
for (int i : { FRONT_BUFFER, BACK_BUFFER1, BACK_BUFFER2, OVERLAY_BUFFER }) {
- freeAtariSurface(_buffer[i]->p, getStRamFreeFunc());
- delete _buffer[i];
- _buffer[i] = nullptr;
+ delete _screen[i];
+ _screen[i] = nullptr;
}
- _screenSurface = Graphics::Surface();
- _screenOverlaySurface = Graphics::Surface();
_workScreen = nullptr;
_chunkySurface.free();
@@ -607,29 +594,29 @@ void AtariGraphicsManager::setVidelResolution() const {
if (_vgaMonitor) {
// TODO: aspect ratio correction
// TODO: supervidel 320x240...
- if (_screenSurface.w == 320) {
- if (_screenSurface.h == 200)
+ if (_workScreen->surf.w == 320) {
+ if (_workScreen->surf.h == 200)
asm_screen_set_scp_res(scp_320x200x8_vga);
else
asm_screen_set_scp_res(scp_320x240x8_vga);
} else {
- if (_screenSurface.h == 400)
+ if (_workScreen->surf.h == 400)
asm_screen_set_scp_res(scp_640x400x8_vga);
else
asm_screen_set_scp_res(scp_640x480x8_vga);
}
} else {
- if (_screenSurface.w == 320) {
- if (_screenSurface.h == 240)
+ if (_workScreen->surf.w == 320) {
+ if (_workScreen->surf.h == 240)
asm_screen_set_scp_res(scp_320x240x8_rgb);
- else if (_screenSurface.h == 200 && _aspectRatioCorrection)
+ else if (_workScreen->surf.h == 200 && _aspectRatioCorrection)
asm_screen_set_scp_res(scp_320x200x8_rgb60);
else
asm_screen_set_scp_res(scp_320x200x8_rgb);
} else {
- if (_screenSurface.h == 480)
+ if (_workScreen->surf.h == 480)
asm_screen_set_scp_res(scp_640x480x8_rgb);
- else if (_screenSurface.h == 400 && _aspectRatioCorrection)
+ else if (_workScreen->surf.h == 400 && _aspectRatioCorrection)
asm_screen_set_scp_res(scp_640x400x8_rgb60);
else
asm_screen_set_scp_res(scp_640x400x8_rgb);
@@ -638,6 +625,7 @@ void AtariGraphicsManager::setVidelResolution() const {
}
bool AtariGraphicsManager::updateDirect() {
+ const Common::Rect &dirtyScreenRect = _workScreen->dirtyRects.empty() ? Common::Rect() : _workScreen->dirtyRects.front();
bool &cursorPositionChanged = _workScreen->cursorPositionChanged;
bool &cursorSurfaceChanged = _workScreen->cursorSurfaceChanged;
Common::Rect &oldCursorRect = _workScreen->oldCursorRect;
@@ -649,16 +637,16 @@ bool AtariGraphicsManager::updateDirect() {
bool drawCursor = cursorPositionChanged || cursorSurfaceChanged;
- if (!drawCursor && _cursor.visible && !_dirtyScreenRect.isEmpty())
- drawCursor = _dirtyScreenRect.intersects(_cursor.dstRect);
+ if (!drawCursor && _cursor.visible && !dirtyScreenRect.isEmpty())
+ drawCursor = dirtyScreenRect.intersects(_cursor.dstRect);
static Graphics::Surface cachedCursorSurface;
- if (!oldCursorRect.isEmpty() && !_dirtyScreenRect.isEmpty()) {
- const Common::Rect intersectingRect = _dirtyScreenRect.findIntersectingRect(oldCursorRect);
+ if (!oldCursorRect.isEmpty() && !dirtyScreenRect.isEmpty()) {
+ const Common::Rect intersectingRect = dirtyScreenRect.findIntersectingRect(oldCursorRect);
if (!intersectingRect.isEmpty()) {
// update cached surface
- const Graphics::Surface intersectingScreenSurface = _screenSurface.getSubArea(intersectingRect);
+ const Graphics::Surface intersectingScreenSurface = _workScreen->surf.getSubArea(intersectingRect);
cachedCursorSurface.copyRectToSurface(
intersectingScreenSurface,
intersectingRect.left - oldCursorRect.left,
@@ -667,10 +655,8 @@ bool AtariGraphicsManager::updateDirect() {
}
}
- _dirtyScreenRect = Common::Rect();
-
if ((cursorPositionChanged || !_cursor.visible) && !oldCursorRect.isEmpty()) {
- _screenSurface.copyRectToSurface(
+ _workScreen->surf.copyRectToSurface(
cachedCursorSurface,
oldCursorRect.left, oldCursorRect.top,
Common::Rect(oldCursorRect.width(), oldCursorRect.height()));
@@ -687,11 +673,11 @@ bool AtariGraphicsManager::updateDirect() {
cachedCursorSurface.create(_cursor.dstRect.width(), _cursor.dstRect.height(), _cursor.surface.format);
}
- // background has been restored, so it's safe to read _screenSurface
+ // background has been restored, so it's safe to read _workScreen
if (oldCursorRect.isEmpty())
- cachedCursorSurface.copyRectToSurface(_screenSurface, 0, 0, _cursor.dstRect);
+ cachedCursorSurface.copyRectToSurface(_workScreen->surf, 0, 0, _cursor.dstRect);
- _screenSurface.copyRectToSurfaceWithKey(
+ _workScreen->surf.copyRectToSurfaceWithKey(
_cursor.surface,
_cursor.dstRect.left, _cursor.dstRect.top,
_cursor.srcRect,
@@ -706,12 +692,14 @@ bool AtariGraphicsManager::updateDirect() {
return updated;
}
-bool AtariGraphicsManager::updateBuffered(const Graphics::Surface &srcSurface, Graphics::Surface &dstSurface, const DirtyRects &dirtyRects) {
- // workscreen related setting; these are used even if called repeatedly
- // for triple buffering
- bool &cursorPositionChanged = _workScreen->cursorPositionChanged;
- bool &cursorSurfaceChanged = _workScreen->cursorSurfaceChanged;
- Common::Rect &oldCursorRect = _workScreen->oldCursorRect;
+bool AtariGraphicsManager::updateBuffered(const Graphics::Surface &srcSurface, const DirtyRects &dirtyRects) {
+ //debug("updateBuffered: %d", dirtyRects.size());
+
+ // workscreen related setting; these are used even if called repeatedly for triple buffering
+ Graphics::Surface &dstSurface = _workScreen->surf;
+ bool &cursorPositionChanged = _workScreen->cursorPositionChanged;
+ bool &cursorSurfaceChanged = _workScreen->cursorSurfaceChanged;
+ Common::Rect &oldCursorRect = _workScreen->oldCursorRect;
bool updated = false;
bool drawCursor = cursorPositionChanged || cursorSurfaceChanged;;
@@ -756,52 +744,50 @@ bool AtariGraphicsManager::updateBuffered(const Graphics::Surface &srcSurface, G
return updated;
}
-void AtariGraphicsManager::allocateAtariSurface(Graphics::Surface &surface,
- int width, int height, const Graphics::PixelFormat &format,
- const AtariMemAlloc &allocFunc) {
- constexpr size_t ALIGN = 16; // 16 bytes
+AtariGraphicsManager::Screen::Screen(AtariGraphicsManager *manager, int width, int height, const Graphics::PixelFormat &format)
+ : _manager(manager) {
+ const AtariMemAlloc &allocFunc = _manager->getStRamAllocFunc();
- surface.init(width, height, (width * format.bytesPerPixel + ALIGN - 1) & (-ALIGN), nullptr, format);
+ surf.init(width, height, (width * format.bytesPerPixel + ALIGN - 1) & (-ALIGN), nullptr, format);
- void *pixelsUnaligned = allocFunc(sizeof(uintptr) + (surface.h * surface.pitch) + ALIGN - 1);
+ void *pixelsUnaligned = allocFunc(sizeof(uintptr) + (surf.h * surf.pitch) + ALIGN - 1);
if (!pixelsUnaligned) {
error("Failed to allocate memory in ST RAM");
}
- surface.setPixels((void *)(((uintptr)pixelsUnaligned + sizeof(uintptr) + ALIGN - 1) & (-ALIGN)));
+ surf.setPixels((void *)(((uintptr)pixelsUnaligned + sizeof(uintptr) + ALIGN - 1) & (-ALIGN)));
- // store the unaligned pointer for later free()
- *((uintptr *)surface.getPixels() - 1) = (uintptr)pixelsUnaligned;
+ // store the unaligned pointer for later release
+ *((uintptr *)surf.getPixels() - 1) = (uintptr)pixelsUnaligned;
- memset(surface.getPixels(), 0, surface.h * surface.pitch);
+ memset(surf.getPixels(), 0, surf.h * surf.pitch);
}
-void AtariGraphicsManager::freeAtariSurface(byte *ptr, const AtariMemFree &freeFunc) {
- freeFunc((void *)*((uintptr *)ptr - 1));
+AtariGraphicsManager::Screen::~Screen() {
+ const AtariMemFree &freeFunc = _manager->getStRamFreeFunc();
+
+ freeFunc((void *)*((uintptr *)surf.getPixels() - 1));
}
-void AtariGraphicsManager::addDirtyRect(const Graphics::Surface &surface,
- DirtyRects &rects, Common::Rect rect) const {
- alignRect(surface, rect);
+void AtariGraphicsManager::Screen::addDirtyRect(Common::Rect rect) {
+ if (_fullRedraw)
+ return;
- if (rect.width() == surface.w && rect.height() == surface.h) {
- //debug("addDirtyRect: purge");
+ _manager->alignRect(surf, rect);
- rects.clear();
- rects.push_back(rect);
- return;
- }
+ // TODO: this assumes that screen resolution == chunky buffer resolution
+ if ((rect.width() == surf.w && rect.height() == surf.h)
+ || dirtyRects.size() == dirtyRects.capacity()) {
+ //debug("addDirtyRect[%d]: purge %d x %d", (int)dirtyRects.size(), surf.w, surf.h);
- for (const Common::Rect &r : rects) {
- if (r.contains(rect)) {
- return;
- }
- }
+ dirtyRects.clear();
+ dirtyRects.push_back(Common::Rect(surf.w, surf.h));
- // TODO: what is r.rect contains some rect from rects => delete that rect instead
- // (it is costly in Common::Array...)
+ _fullRedraw = true;
+ return;
+ }
- rects.push_back(rect);
+ dirtyRects.push_back(rect);
}
void AtariGraphicsManager::Cursor::update(const Graphics::Surface &screen, bool isModified) {
diff --git a/backends/graphics/atari/atari-graphics.h b/backends/graphics/atari/atari-graphics.h
index e72f66b2b3d..8b52f1bce22 100644
--- a/backends/graphics/atari/atari-graphics.h
+++ b/backends/graphics/atari/atari-graphics.h
@@ -93,14 +93,6 @@ protected:
typedef void* (*AtariMemAlloc)(size_t bytes);
typedef void (*AtariMemFree)(void *ptr);
- virtual AtariMemAlloc getStRamAllocFunc() const {
- return [](size_t bytes) { return (void*)Mxalloc(bytes, MX_STRAM); };
- }
-
- virtual AtariMemFree getStRamFreeFunc() const {
- return [](void *ptr) { Mfree(ptr); };
- }
-
void allocateSurfaces();
void freeSurfaces();
@@ -131,6 +123,13 @@ private:
SCREEN_HEIGHT = 480
};
+ virtual AtariMemAlloc getStRamAllocFunc() const {
+ return [](size_t bytes) { return (void*)Mxalloc(bytes, MX_STRAM); };
+ }
+ virtual AtariMemFree getStRamFreeFunc() const {
+ return [](void *ptr) { Mfree(ptr); };
+ }
+
// use std::vector as its clear() doesn't reset capacity
using DirtyRects = std::vector<Common::Rect>;
@@ -141,13 +140,7 @@ private:
void setVidelResolution() const;
bool updateDirect();
- bool updateBuffered(const Graphics::Surface &srcSurface, Graphics::Surface &dstSurface, const DirtyRects &dirtyRects);
-
- void allocateAtariSurface(Graphics::Surface &surface,
- int width, int height, const Graphics::PixelFormat &format,
- const AtariMemAlloc &allocFunc);
-
- void freeAtariSurface(byte *ptr, const AtariMemFree &freeFunc);
+ bool updateBuffered(const Graphics::Surface &srcSurface, const DirtyRects &dirtyRects);
virtual void copyRectToSurface(Graphics::Surface &dstSurface,
const Graphics::Surface &srcSurface, int destX, int destY,
@@ -161,26 +154,24 @@ private:
}
virtual void alignRect(const Graphics::Surface &srcSurface, Common::Rect &rect) const {}
- void addDirtyRect(const Graphics::Surface &surface, DirtyRects &rects, Common::Rect rect) const;
-
void cursorPositionChanged() {
if (_overlayVisible) {
- _buffer[OVERLAY_BUFFER]->cursorPositionChanged = true;
+ _screen[OVERLAY_BUFFER]->cursorPositionChanged = true;
} else {
- _buffer[FRONT_BUFFER]->cursorPositionChanged
- = _buffer[BACK_BUFFER1]->cursorPositionChanged
- = _buffer[BACK_BUFFER2]->cursorPositionChanged
+ _screen[FRONT_BUFFER]->cursorPositionChanged
+ = _screen[BACK_BUFFER1]->cursorPositionChanged
+ = _screen[BACK_BUFFER2]->cursorPositionChanged
= true;
}
}
void cursorSurfaceChanged() {
if (_overlayVisible) {
- _buffer[OVERLAY_BUFFER]->cursorSurfaceChanged = true;
+ _screen[OVERLAY_BUFFER]->cursorSurfaceChanged = true;
} else {
- _buffer[FRONT_BUFFER]->cursorSurfaceChanged
- = _buffer[BACK_BUFFER1]->cursorSurfaceChanged
- = _buffer[BACK_BUFFER2]->cursorSurfaceChanged
+ _screen[FRONT_BUFFER]->cursorSurfaceChanged
+ = _screen[BACK_BUFFER1]->cursorSurfaceChanged
+ = _screen[BACK_BUFFER2]->cursorSurfaceChanged
= true;
}
}
@@ -207,33 +198,51 @@ private:
BUFFER_COUNT
};
- struct ScreenInfo {
- ScreenInfo(byte *p_)
- : p(p_) {
- }
+ struct Screen {
+ Screen(AtariGraphicsManager *manager, int width, int height, const Graphics::PixelFormat &format);
+ ~Screen();
- void reset() {
+ void reset(int width, int height) {
cursorPositionChanged = true;
cursorSurfaceChanged = false;
- dirtyRects.clear();
+ clearDirtyRects();
oldCursorRect = Common::Rect();
+
+ // erase old screen
+ surf.fillRect(Common::Rect(surf.w, surf.h), 0);
+ // set new dimensions
+ surf.pitch = width;
+ surf.w = width;
+ surf.h = height;
+ }
+
+ void addDirtyRect(Common::Rect rect);
+
+ void clearDirtyRects() {
+ dirtyRects.clear();
+ _fullRedraw = false;
}
- byte *p;
+ const bool &fullRedrawPending = _fullRedraw;
+
+ Graphics::Surface surf;
bool cursorPositionChanged = true;
bool cursorSurfaceChanged = false;
- DirtyRects dirtyRects = DirtyRects(100); // reserve 100 rects
+ DirtyRects dirtyRects = DirtyRects(512); // reserve 512 rects
Common::Rect oldCursorRect;
+
+ private:
+ static constexpr size_t ALIGN = 16; // 16 bytes
+
+ bool _fullRedraw = false;
+ AtariGraphicsManager *_manager;
};
- ScreenInfo *_buffer[BUFFER_COUNT] = {};
- ScreenInfo *_workScreen = nullptr;
- ScreenInfo *_oldWorkScreen = nullptr; // used in hideOverlay()
+ Screen *_screen[BUFFER_COUNT] = {};
+ Screen *_workScreen = nullptr;
+ Screen *_oldWorkScreen = nullptr; // used in hideOverlay()
- Graphics::Surface _screenSurface;
- Common::Rect _dirtyScreenRect; // direct rendering only
Graphics::Surface _chunkySurface;
- Graphics::Surface _screenOverlaySurface;
bool _overlayVisible = false;
Graphics::Surface _overlaySurface;
More information about the Scummvm-git-logs
mailing list