[Scummvm-git-logs] scummvm master -> eb64b14b81a723b3b692f95e1179f28356594e67
mikrosk
noreply at scummvm.org
Wed Jun 25 21:51:02 UTC 2025
This automated email contains information about 17 new commits which have been
pushed to the 'scummvm' repo located at https://api.github.com/repos/scummvm/scummvm .
Summary:
e75b607579 JANITORIAL: Correct indentation
757ae0f58d JANITORIAL: Clarify DisposablePtr::reset()
f08bba77a8 JANITORIAL: Silence a few warnings
1bbd298799 BACKENDS: ATARI: Remove some .dat files
d452beff82 BACKENDS: ATARI: Remove g_unalignedPitch workaround
28507ee8a7 BACKENDS: ATARI: Cleanup fillScreen()
b3074272da BACKENDS: ATARI: Separate SuperVidel code
3dc861cf12 GRAPHICS: ATARI: Add specialized keyBlitLogic
3dd96ec7c5 BACKENDS: ATARI: Use hardware-accelerated cursor blitting
fbbecd55f3 GRAPHICS: Make Graphics::PixelFormat::createFormatCLUT8 constexpr
0520570a7b BACKENDS: ATARI: Move getBitsPerPixel from AtariGraphicsManager to AtariSurface
ee437e2a42 BACKENDS: ATARI: Move alignRect from AtariGraphicsManager to AtariSurface
f27f045aac BACKENDS: ATARI: Remove references to AtariGraphicsManager from Screen and Cursor
e575d1360e BACKENDS: ATARI: Make purpose of _xOffset more explicit
3f47c7a8ce BACKENDS: ATARI: Let Cursor access only AtariSurface instead of Screen
25d125bdc0 BACKENDS: ATARI: Avoid redefinition warning
eb64b14b81 BACKENDS: ATARI: Implement proper cursor clipping
Commit: e75b607579e0243f9eae672f853362c3e980832c
https://github.com/scummvm/scummvm/commit/e75b607579e0243f9eae672f853362c3e980832c
Author: Miro Kropacek (miro.kropacek at gmail.com)
Date: 2025-06-25T23:50:34+02:00
Commit Message:
JANITORIAL: Correct indentation
Changed paths:
backends/graphics/atari/atari-c2p-asm.S
diff --git a/backends/graphics/atari/atari-c2p-asm.S b/backends/graphics/atari/atari-c2p-asm.S
index bab5460f58e..5c0f9a9e366 100644
--- a/backends/graphics/atari/atari-c2p-asm.S
+++ b/backends/graphics/atari/atari-c2p-asm.S
@@ -36,13 +36,13 @@
| void asm_c2p1x1_8(const byte *pChunky, const byte *pChunkyEnd, byte *pScreen);
SYM(asm_c2p1x1_8):
#ifdef __FASTCALL__
- | a0: chunky
- move.l a1,d0 | chunky end
- move.l 4(sp),a1 | screen
+ | a0: chunky
+ move.l a1,d0 | chunky end
+ move.l 4(sp),a1 | screen
#else
- move.l (4,sp),a0 | chunky
- move.l (8,sp),d0 | chunky end
- move.l (12,sp),a1 | screen
+ move.l (4,sp),a0 | chunky
+ move.l (8,sp),d0 | chunky end
+ move.l (12,sp),a1 | screen
#endif
movem.l d2-d7/a2-a6,-(sp)
move.l d0,a2
@@ -238,26 +238,25 @@ c2p1x1_8_start:
| void asm_c2p1x1_8_tt(const byte *pChunky, const byte *pChunkyEnd, byte *pScreen, uint32 screenPitch);
SYM(asm_c2p1x1_8_tt):
- movem.l d2-d7/a2-a6,-(sp) | 6 + 5 = 11 longs
+ movem.l d2-d7/a2-a6,-(sp) | 6 + 5 = 11 longs
#ifdef __FASTCALL__
- | a0: chunky
- move.l a1,a2 | a2: chunky end
- move.l (11*4+4,sp),a1 | a1: screen
- | d0.l: screen pitch (double width)
+ | a0: chunky
+ move.l a1,a2 | a2: chunky end
+ move.l (11*4+4,sp),a1 | a1: screen
+ | d0.l: screen pitch (double width)
#else
- move.l (11*4+4,sp),a0 | a0: chunky
- move.l (11*4+8,sp),a2 | a2: chunky end
- move.l (11*4+12,sp),a1 | a1: screen
- move.l (11*4+16,sp),d0 | d0.l: screen pitch (double width)
+ move.l (11*4+4,sp),a0 | a0: chunky
+ move.l (11*4+8,sp),a2 | a2: chunky end
+ move.l (11*4+12,sp),a1 | a1: screen
+ move.l (11*4+16,sp),d0 | d0.l: screen pitch (double width)
#endif
-
move.l sp,old_sp
move.l d0,screen_pitch
lsr.l #1,d0
- lea (a1,d0.l),a7 | a7: end of first dst line
+ lea (a1,d0.l),a7 | a7: end of first dst line
move.l d0,screen_offset
@@ -460,28 +459,27 @@ c2p1x1_8_tt_start:
| void asm_c2p1x1_8_rect(const byte *pChunky, const byte *pChunkyEnd, uint32 chunkyWidth, uint32 chunkyPitch, byte *pScreen, uint32 screenPitch);
SYM(asm_c2p1x1_8_rect):
- movem.l d2-d7/a2-a6,-(sp) | 6 + 5 = 11 longs
+ movem.l d2-d7/a2-a6,-(sp) | 6 + 5 = 11 longs
#ifdef __FASTCALL__
- | a0: chunky
+ | a0: chunky
move.l a1,chunky_end
- | d0.l: chunky width
- move.l (11*4+4,sp),a1 | a1: screen
- exg d1,d2 | d2.l: chunky pitch
- | d1.l: screen pitch
+ | d0.l: chunky width
+ move.l (11*4+4,sp),a1 | a1: screen
+ exg d1,d2 | d2.l: chunky pitch
+ | d1.l: screen pitch
#else
- move.l (11*4+4,sp),a0 | a0: chunky
+ move.l (11*4+4,sp),a0 | a0: chunky
move.l (11*4+8,sp),chunky_end
- move.l (11*4+12,sp),d0 | d0.l: chunky width
- move.l (11*4+16,sp),d2 | d2.l: chunky pitch
- move.l (11*4+20,sp),a1 | a1: screen
- move.l (11*4+24,sp),d1 | d1.l: screen pitch
+ move.l (11*4+12,sp),d0 | d0.l: chunky width
+ move.l (11*4+16,sp),d2 | d2.l: chunky pitch
+ move.l (11*4+20,sp),a1 | a1: screen
+ move.l (11*4+24,sp),d1 | d1.l: screen pitch
#endif
-
move.l sp,old_sp
- lea (a0,d0.l),a2 | a2: end of first src line
- lea (a1,d0.l),a7 | a7: end of first dst line
+ lea (a0,d0.l),a2 | a2: end of first src line
+ lea (a1,d0.l),a7 | a7: end of first dst line
move.l d1,screen_pitch
@@ -604,7 +602,7 @@ c2p1x1_8_rect_pix16:
| b7b6b5b4f7f6f5f4 j7j6j5j4n7n6n5n4 d7d6d5d4h7h6h5h4 l7l6l5l4p7p6p5p4
| b3b2b1b0f3f2f1f0 j3j2j1j0n3n2n1n0 d3d2d1d0h3h2h1h0 l3l2l1l0p3p2p1p0
- cmp.l a1,a7 | end of dst line?
+ cmp.l a1,a7 | end of dst line?
bne.s c2p1x1_8_rect_start
add.l (screen_offset,pc),a1
@@ -677,7 +675,7 @@ c2p1x1_8_rect_start:
move.l d1,a4
move.l d3,a3
- cmp.l a0,a2 | end of src line?
+ cmp.l a0,a2 | end of src line?
bne c2p1x1_8_rect_pix16
cmp.l (chunky_end,pc),a2
@@ -702,13 +700,13 @@ c2p1x1_8_rect_done:
| void asm_c2p1x1_4(const byte *pChunky, const byte *pChunkyEnd, byte *pScreen);
SYM(asm_c2p1x1_4):
#ifdef __FASTCALL__
- | a0: chunky
- move.l a1,d0 | chunky end
- move.l 4(sp),a1 | screen
+ | a0: chunky
+ move.l a1,d0 | chunky end
+ move.l 4(sp),a1 | screen
#else
- move.l (4,sp),a0 | chunky
- move.l (8,sp),d0 | chunky end
- move.l (12,sp),a1 | screen
+ move.l (4,sp),a0 | chunky
+ move.l (8,sp),d0 | chunky end
+ move.l (12,sp),a1 | screen
#endif
movem.l d2-d7/a2-a6,-(sp)
move.l d0,a2
@@ -803,31 +801,30 @@ c2p1x1_4_start:
| void asm_c2p1x1_4_rect(const byte *pChunky, const byte *pChunkyEnd, uint32 chunkyWidth, uint32 chunkyPitch, byte *pScreen, uint32 screenPitch);
SYM(asm_c2p1x1_4_rect):
- movem.l d2-d7/a2-a6,-(sp) | 6 + 5 = 11 longs
+ movem.l d2-d7/a2-a6,-(sp) | 6 + 5 = 11 longs
#ifdef __FASTCALL__
- | a0: chunky
+ | a0: chunky
move.l a1,chunky_end
- | d0.l: chunky width
- move.l (11*4+4,sp),a1 | a1: screen
- exg d1,d2 | d2.l: chunky pitch
- | d1.l: screen pitch
+ | d0.l: chunky width
+ move.l (11*4+4,sp),a1 | a1: screen
+ exg d1,d2 | d2.l: chunky pitch
+ | d1.l: screen pitch
#else
- move.l (11*4+4,sp),a0 | a0: chunky
+ move.l (11*4+4,sp),a0 | a0: chunky
move.l (11*4+8,sp),chunky_end
- move.l (11*4+12,sp),d0 | d0.l: chunky width
- move.l (11*4+16,sp),d2 | d2.l: chunky pitch
- move.l (11*4+20,sp),a1 | a1: screen
- move.l (11*4+24,sp),d1 | d1.l: screen pitch
+ move.l (11*4+12,sp),d0 | d0.l: chunky width
+ move.l (11*4+16,sp),d2 | d2.l: chunky pitch
+ move.l (11*4+20,sp),a1 | a1: screen
+ move.l (11*4+24,sp),d1 | d1.l: screen pitch
#endif
-
move.l sp,old_sp
- move.l d0,d3 | d3.l: screen width
- lsr.l #1,d3 |
+ move.l d0,d3 | d3.l: screen width
+ lsr.l #1,d3 |
- lea (a0,d0.l),a2 | a2: end of first src line
- lea (a1,d3.l),a7 | a7: end of first dst line
+ lea (a0,d0.l),a2 | a2: end of first src line
+ lea (a1,d3.l),a7 | a7: end of first dst line
move.l d1,screen_pitch
@@ -865,7 +862,7 @@ c2p1x1_4_rect_pix16:
or.l d3,d1
move.l a6,(a1)+
- cmp.l a1,a7 | end of dst line?
+ cmp.l a1,a7 | end of dst line?
bne.s c2p1x1_4_rect_start
add.l (screen_offset,pc),a1
@@ -924,7 +921,7 @@ c2p1x1_4_rect_start:
move.l d1,a5
move.l d0,a6
- cmp.l a0,a2 | end of src line?
+ cmp.l a0,a2 | end of src line?
bne.s c2p1x1_4_rect_pix16
cmp.l (chunky_end,pc),a2
Commit: 757ae0f58d548d1ef3780821a2b3295b0e9d7b94
https://github.com/scummvm/scummvm/commit/757ae0f58d548d1ef3780821a2b3295b0e9d7b94
Author: Miro Kropacek (miro.kropacek at gmail.com)
Date: 2025-06-25T23:50:34+02:00
Commit Message:
JANITORIAL: Clarify DisposablePtr::reset()
Changed paths:
common/ptr.h
diff --git a/common/ptr.h b/common/ptr.h
index a33edcb1107..dd08d13e027 100644
--- a/common/ptr.h
+++ b/common/ptr.h
@@ -602,7 +602,7 @@ public:
}
/**
- * Resets the pointer with the new value. Old object will be destroyed
+ * Resets the pointer with the new value. Old object will be destroyed.
*/
void reset(PointerType o = nullptr) {
DL()(_pointer);
@@ -680,7 +680,7 @@ public:
bool operator_bool() const { return _pointer != nullptr; }
/**
- * Resets the pointer with the new value. Old object will be destroyed
+ * Resets the pointer with the new value. Old object will be destroyed if flagged as disposable.
*/
void reset(PointerType o, DisposeAfterUse::Flag dispose) {
if (_dispose) DL()(_pointer);
@@ -690,7 +690,7 @@ public:
}
/**
- * Clears the pointer. Old object will be destroyed
+ * Clears the pointer. Old object will be destroyed if flagged as disposable.
*/
void reset() {
reset(nullptr, DisposeAfterUse::NO);
Commit: f08bba77a85595bf096249adbca326267fd56498
https://github.com/scummvm/scummvm/commit/f08bba77a85595bf096249adbca326267fd56498
Author: Miro Kropacek (miro.kropacek at gmail.com)
Date: 2025-06-25T23:50:34+02:00
Commit Message:
JANITORIAL: Silence a few warnings
This shaves off 250 out of 320 KB stderr log when asserts are
disabled.
Changed paths:
engines/mm/xeen/resources.h
diff --git a/engines/mm/xeen/resources.h b/engines/mm/xeen/resources.h
index a3bab477052..ccbc8a2ae3c 100644
--- a/engines/mm/xeen/resources.h
+++ b/engines/mm/xeen/resources.h
@@ -63,12 +63,14 @@ class Resources {
void syncStrings(const char **str, int count) {
uint tag = readUint32LE();
assert(tag == MKTAG(count, 0, 0, 0));
+ (void)tag;
for (int idx = 0; idx < count; ++idx)
syncString(str[idx]);
}
void syncStrings2D(const char **str, int count1, int count2) {
uint tag = readUint32LE();
assert(tag == MKTAG(count1, count2, 0, 0));
+ (void)tag;
for (int idx = 0; idx < count1 * count2; ++idx)
syncString(str[idx]);
}
@@ -78,30 +80,35 @@ class Resources {
void syncNumbers(int *vals, int count) {
uint tag = readUint32LE();
assert(tag == MKTAG(count, 0, 0, 0));
+ (void)tag;
for (int idx = 0; idx < count; ++idx)
vals[idx] = readSint32LE();
}
void syncNumbers2D(int *vals, int count1, int count2) {
uint tag = readUint32LE();
assert(tag == MKTAG(count1, count2, 0, 0));
+ (void)tag;
for (int idx = 0; idx < count1 * count2; ++idx)
vals[idx] = readSint32LE();
}
void syncNumbers3D(int *vals, int count1, int count2, int count3) {
uint tag = readUint32LE();
assert(tag == MKTAG(count1, count2, count3, 0));
+ (void)tag;
for (int idx = 0; idx < count1 * count2 * count3; ++idx)
vals[idx] = readSint32LE();
}
void syncNumbers4D(int *vals, int count1, int count2, int count3, int count4) {
uint tag = readUint32LE();
assert(tag == MKTAG(count1, count2, count3, count4));
+ (void)tag;
for (int idx = 0; idx < count1 * count2 * count3 * count4; ++idx)
vals[idx] = readSint32LE();
}
void syncBytes2D(byte *vals, int count1, int count2) {
uint tag = readUint32LE();
assert(tag == MKTAG(count1, count2, 0, 0));
+ (void)tag;
read(vals, count1 * count2);
}
};
Commit: 1bbd29879914e3cef06e78f6fc621a66d9ab4d40
https://github.com/scummvm/scummvm/commit/1bbd29879914e3cef06e78f6fc621a66d9ab4d40
Author: Miro Kropacek (miro.kropacek at gmail.com)
Date: 2025-06-25T23:50:34+02:00
Commit Message:
BACKENDS: ATARI: Remove some .dat files
Those are not used in Atari port and just take space and annoy users
with their long filenames.
Changed paths:
backends/platform/atari/build-release.sh
backends/platform/atari/build-release030.sh
diff --git a/backends/platform/atari/build-release.sh b/backends/platform/atari/build-release.sh
index 1e6d591d1d4..59d2484b112 100755
--- a/backends/platform/atari/build-release.sh
+++ b/backends/platform/atari/build-release.sh
@@ -56,7 +56,7 @@ ${PLATFORM}-nm -C dist-generic/scummvm/scummvm.ttp | grep -vF ' .L' | grep ' [Tt
${PLATFORM}-strip -s dist-generic/scummvm/scummvm.ttp
# remove unused files; absent gui-icons.dat massively speeds up startup time (used for the grid mode)
-rm dist-generic/scummvm/data/{achievements,encoding,gui-icons,macgui,shaders}.dat
+rm dist-generic/scummvm/data/{achievements,classicmacfonts,encoding,gui-icons,hadesch_translations,macgui,prince_translation,shaders}.dat
# rename remaining files still not fitting into the 8+3 limit (this has to be supported by the backend, too)
mv dist-generic/scummvm/data/cryomni3d.dat dist-generic/scummvm/data/cryomni3.dat
diff --git a/backends/platform/atari/build-release030.sh b/backends/platform/atari/build-release030.sh
index 8391f3619ae..4f35abe3ab3 100755
--- a/backends/platform/atari/build-release030.sh
+++ b/backends/platform/atari/build-release030.sh
@@ -58,7 +58,7 @@ ${PLATFORM}-nm -C dist-generic/scummvm/scummvm.ttp | grep -vF ' .L' | grep ' [Tt
${PLATFORM}-strip -s dist-generic/scummvm/scummvm.ttp
# remove unused files
-rm dist-generic/scummvm/data/*.zip dist-generic/scummvm/data/{achievements,encoding,gui-icons,macgui,shaders}.dat
+rm dist-generic/scummvm/data/*.zip dist-generic/scummvm/data/{achievements,classicmacfonts,encoding,gui-icons,macgui,shaders}.dat
# rename remaining files still not fitting into the 8+3 limit (this has to be supported by the backend, too)
mv dist-generic/scummvm/data/supernova.dat dist-generic/scummvm/data/supernov.dat
Commit: d452beff828945bcfca58de162e7d28c9875a6f4
https://github.com/scummvm/scummvm/commit/d452beff828945bcfca58de162e7d28c9875a6f4
Author: Miro Kropacek (miro.kropacek at gmail.com)
Date: 2025-06-25T23:50:34+02:00
Commit Message:
BACKENDS: ATARI: Remove g_unalignedPitch workaround
It causes more harm than good and I don't think it helps with
performance that much either. Its only semi-valid use case was C2P
direct rendering for sprites (which nobody uses). However, direct
rendering in its current form is about to be removed in a near future,
so...
Changed paths:
backends/graphics/atari/atari-cursor.cpp
backends/graphics/atari/atari-graphics.cpp
backends/platform/atari/osystem_atari.cpp
graphics/blit/blit-atari.cpp
diff --git a/backends/graphics/atari/atari-cursor.cpp b/backends/graphics/atari/atari-cursor.cpp
index 5637c07d6d6..1cc488103b4 100644
--- a/backends/graphics/atari/atari-cursor.cpp
+++ b/backends/graphics/atari/atari-cursor.cpp
@@ -140,12 +140,7 @@ void Cursor::convertSurfaceTo(const Graphics::PixelFormat &format) {
}
_surface.create(cursorWidth, cursorHeight, format);
-
- extern bool g_unalignedPitch;
- const bool old_unalignedPitch = g_unalignedPitch;
- g_unalignedPitch = true;
_surfaceMask.create(_surface.w / 8, _surface.h, format); // 1 bpl
- g_unalignedPitch = old_unalignedPitch;
}
const int srcRectWidth = _srcRect.width();
diff --git a/backends/graphics/atari/atari-graphics.cpp b/backends/graphics/atari/atari-graphics.cpp
index 77f4e462d26..70907377ca0 100644
--- a/backends/graphics/atari/atari-graphics.cpp
+++ b/backends/graphics/atari/atari-graphics.cpp
@@ -431,17 +431,13 @@ OSystem::TransactionError AtariGraphicsManager::endGFXTransaction() {
}
if (_pendingState.width > 0 && _pendingState.height > 0) {
- extern bool g_unalignedPitch;
-
if (_pendingState.width > getMaximumScreenWidth() || _pendingState.height > getMaximumScreenHeight()) {
error |= OSystem::TransactionError::kTransactionSizeChangeFailed;
} else if (((hasPendingGraphicsMode && _pendingState.mode == kDirectRendering)
|| (!hasPendingGraphicsMode && _currentState.mode == kDirectRendering))
- && (_pendingState.width % 16 != 0 || g_unalignedPitch)
+ && _pendingState.width % 16 != 0
&& !hasSuperVidel()) {
atari_warning("Engine surfaces not divisible by 16, aborting");
- // engineDone is not called
- g_unalignedPitch = false;
error |= OSystem::TransactionError::kTransactionSizeChangeFailed;
} else if (_overlayState == kOverlayIgnoredHide || _currentState.width != _pendingState.width || _currentState.height != _pendingState.height) {
// if kOverlayIgnoredHide and with valid w/h, force a video mode reset
diff --git a/backends/platform/atari/osystem_atari.cpp b/backends/platform/atari/osystem_atari.cpp
index d6d0b6b8b64..663a8a47cd4 100644
--- a/backends/platform/atari/osystem_atari.cpp
+++ b/backends/platform/atari/osystem_atari.cpp
@@ -66,7 +66,6 @@
*/
#include "backends/fs/atari/atari-fs-factory.h"
-bool g_unalignedPitch = false;
bool g_gameEngineActive = false;
extern "C" void atari_kbdvec(void *);
@@ -354,40 +353,12 @@ void OSystem_Atari::engineInit() {
//atari_debug("engineInit");
g_gameEngineActive = true;
-
- const Common::ConfigManager::Domain *activeDomain = ConfMan.getActiveDomain();
- assert(activeDomain);
-
- // FIXME: Some engines are too bound to linear surfaces that it is very
- // hard to repair them. So instead of polluting the engine with
- // Surface::init() & delete[] Surface::getPixels() just use this hack.
- const Common::String engineId = activeDomain->getValOrDefault("engineid");
- const Common::String gameId = activeDomain->getValOrDefault("gameid");
-
- atari_debug("checking %s/%s", engineId.c_str(), gameId.c_str());
-
- if (engineId == "composer"
- || engineId == "dgds"
- || engineId == "hypno"
- || engineId == "mohawk"
- || engineId == "parallaction"
- || engineId == "private"
- || (engineId == "sci"
- && (gameId == "phantasmagoria" || gameId == "shivers"))
- || engineId == "sherlock"
- || engineId == "teenagent"
- || engineId == "tsage") {
- g_unalignedPitch = true;
- } else {
- g_unalignedPitch = false;
- }
}
void OSystem_Atari::engineDone() {
//atari_debug("engineDone");
g_gameEngineActive = false;
- g_unalignedPitch = false;
}
Common::MutexInternal *OSystem_Atari::createMutex() {
diff --git a/graphics/blit/blit-atari.cpp b/graphics/blit/blit-atari.cpp
index 62fd61cd0e7..e4d807a2e12 100644
--- a/graphics/blit/blit-atari.cpp
+++ b/graphics/blit/blit-atari.cpp
@@ -92,8 +92,6 @@ void unlockSuperBlitter() {
#endif
}
-// see osystem-atari.cpp
-extern bool g_unalignedPitch;
// see atari-graphics.cpp
extern mspace g_mspace;
@@ -110,10 +108,7 @@ void Surface::create(int16 width, int16 height, const PixelFormat &f) {
w = width;
h = height;
format = f;
- // align pitch to a 16-byte boundary for a possible C2P conversion
- pitch = g_unalignedPitch
- ? w * format.bytesPerPixel
- : (w * format.bytesPerPixel + ALIGN - 1) & (-ALIGN);
+ pitch = w * format.bytesPerPixel;
if (width && height) {
#ifdef USE_SV_BLITTER
Commit: 28507ee8a7aae41ec227dd5c5cf9409f269aab23
https://github.com/scummvm/scummvm/commit/28507ee8a7aae41ec227dd5c5cf9409f269aab23
Author: Miro Kropacek (miro.kropacek at gmail.com)
Date: 2025-06-25T23:50:34+02:00
Commit Message:
BACKENDS: ATARI: Cleanup fillScreen()
The workaround for Eco Quest was misguided, I was updating whole screen
every time!
Changed paths:
backends/graphics/atari/atari-graphics.cpp
diff --git a/backends/graphics/atari/atari-graphics.cpp b/backends/graphics/atari/atari-graphics.cpp
index 70907377ca0..6f7020952e1 100644
--- a/backends/graphics/atari/atari-graphics.cpp
+++ b/backends/graphics/atari/atari-graphics.cpp
@@ -611,27 +611,27 @@ void AtariGraphicsManager::unlockScreen() {
void AtariGraphicsManager::fillScreen(uint32 col) {
atari_debug("fillScreen: %d", col);
- Graphics::Surface *screen = lockScreen();
+ Graphics::Surface &dstSurface = *lockScreen();
- screen->fillRect(Common::Rect(screen->w, screen->h), col);
+ addDirtyRectToScreens(
+ dstSurface,
+ 0, 0, dstSurface.w, dstSurface.h,
+ _currentState.mode == kDirectRendering);
- unlockScreen();
+ dstSurface.fillRect(Common::Rect(dstSurface.w, dstSurface.h), col);
}
void AtariGraphicsManager::fillScreen(const Common::Rect &r, uint32 col) {
//atari_debug("fillScreen: %dx%d %d", r.width(), r.height(), col);
- Graphics::Surface *screen = lockScreen();
+ Graphics::Surface &dstSurface = *lockScreen();
- if (r.width() == 1 && r.height() == 1) {
- // handle special case for e.g. Eco Quest's intro
- byte *ptr = (byte *)screen->getBasePtr(r.left, r.top);
- *ptr = col;
- } else {
- screen->fillRect(r, col);
- }
+ addDirtyRectToScreens(
+ dstSurface,
+ r.left, r.top, r.width(), r.height(),
+ _currentState.mode == kDirectRendering);
- unlockScreen();
+ dstSurface.fillRect(r, col);
}
void AtariGraphicsManager::updateScreen() {
@@ -1017,10 +1017,7 @@ bool AtariGraphicsManager::notifyEvent(const Common::Event &event) {
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
- : _chunkySurfaceOffsetted;
- surf.fillRect(Common::Rect(surf.w, surf.h), 0);
+ fillScreen(0);
_ignoreHideOverlay = true;
// gui manager would want to hide overlay, set game cursor etc
Commit: b3074272daef0a0a0a739db5a4fec71ea37354d0
https://github.com/scummvm/scummvm/commit/b3074272daef0a0a0a739db5a4fec71ea37354d0
Author: Miro Kropacek (miro.kropacek at gmail.com)
Date: 2025-06-25T23:50:34+02:00
Commit Message:
BACKENDS: ATARI: Separate SuperVidel code
- Introduce AtariSurface: a surface which represents either a
bitplane-based or pixel-based surface (on SuperVidel, as an inherited
SuperVidelSurface). Screen::surf / Screen::offsettedSurf are its
instances.
- Graphics::Surface::create / free now handle all Atari-related surfaces
via dlmalloc: ST RAM (TT/Falcon), VRAM (SuperVidel - 0xA0xxxxxx) and
VRAM for generic surfaces (SuperBlitter - 0xA1xxxxxx or ST/TT RAM).
This allowed me to remove all the hacky stuff from atari-graphics and
atari-superblitter.h.
- blit-atari.cpp now contains only blitting code
(SuperBlitter/move16/fallback), SV code is in
atari-supervidel.{cpp,h}.
- Take advantage of Common::ScopedPtr and Graphics::ManagedSurface's
dispose flag for Screen::surf as well Graphics::ManagedSurface's
ownership for Screen::offsettedSurf.
- Improve recoverability if an error/assert happens in
AtariGraphicsManager's c-tor/d-tor.
Changed paths:
A backends/graphics/atari/atari-supervidel.cpp
A backends/graphics/atari/atari-supervidel.h
A backends/graphics/atari/atari-surface.cpp
A backends/graphics/atari/atari-surface.h
R backends/graphics/atari/atari-graphics-superblitter.h
R backends/graphics/atari/atari-graphics-supervidel.h
R backends/graphics/atari/atari-graphics-videl.h
backends/graphics/atari/atari-cursor.cpp
backends/graphics/atari/atari-cursor.h
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/graphics/atari/atari-screen.cpp
backends/graphics/atari/atari-screen.h
backends/module.mk
backends/platform/atari/osystem_atari.cpp
backends/platform/atari/osystem_atari.h
graphics/blit/blit-atari.cpp
graphics/surface.cpp
diff --git a/backends/graphics/atari/atari-cursor.cpp b/backends/graphics/atari/atari-cursor.cpp
index 1cc488103b4..7e04cf00341 100644
--- a/backends/graphics/atari/atari-cursor.cpp
+++ b/backends/graphics/atari/atari-cursor.cpp
@@ -21,20 +21,17 @@
#include "atari-cursor.h"
-#include <cassert>
-
#include "atari-graphics.h"
#include "atari-screen.h"
+#include "atari-supervidel.h"
+#include "atari-surface.h"
//#include "backends/platform/atari/atari-debug.h"
byte Cursor::_palette[256*3] = {};
-Cursor::Cursor(const AtariGraphicsManager *manager, const Screen *screen, int x, int y)
+Cursor::Cursor(const AtariGraphicsManager *manager, const Screen *screen)
: _manager(manager)
- , _parentScreen(screen)
- , _boundingSurf(screen->offsettedSurf)
- , _x(x)
- , _y(y) {
+ , _parentScreen(screen) {
}
void Cursor::update() {
@@ -219,7 +216,7 @@ void Cursor::saveBackground() {
// as this is used only for direct rendering, we don't need to worry about offsettedSurf
// having different dimensions than the source surface
- Graphics::Surface &dstSurface = *_parentScreen->offsettedSurf;
+ const Graphics::Surface &dstSurface = *_parentScreen->offsettedSurf;
//atari_debug("Cursor::saveBackground: %d %d %d %d", _savedRect.left, _savedRect.top, _savedRect.width(), _savedRect.height());
@@ -234,27 +231,27 @@ void Cursor::saveBackground() {
}
void Cursor::draw() {
- Graphics::Surface &dstSurface = *_parentScreen->offsettedSurf;
- const int dstBitsPerPixel = _manager->getBitsPerPixel(dstSurface.format);
+ auto &dstSurface = *_parentScreen->offsettedSurf;
+ const int dstBitsPerPixel = _manager->getBitsPerPixel(dstSurface.format);
//atari_debug("Cursor::draw: %d %d %d %d", _dstRect.left, _dstRect.top, _dstRect.width(), _dstRect.height());
if (_surfaceChanged || _srcRect.width() != _previousSrcRect.width()) {
_previousSrcRect = _srcRect;
- // TODO: some sort of in-place C2P directly into convertSurfaceTo() ...
convertSurfaceTo(dstSurface.format);
- {
- // c2p in-place (will do nothing on regular Surface::copyRectToSurface)
- Graphics::Surface surf;
- surf.init(
- _surface.w,
- _surface.h,
- _surface.pitch * dstBitsPerPixel / 8, // 4bpp is not byte per pixel anymore
- _surface.getPixels(),
- _surface.format);
- _manager->copyRectToSurface(
- surf, _surface,
+
+ if (!g_hasSuperVidel) {
+ // C2P in-place (TODO: merge with convertSurfaceTo)
+ AtariSurface surf(dstBitsPerPixel);
+ surf.w = _surface.w;
+ surf.h = _surface.h;
+ surf.pitch = _surface.pitch * dstBitsPerPixel / 8; // 4bpp is not byte per pixel anymore
+ surf.setPixels(_surface.getPixels());
+ surf.format = _surface.format;
+
+ surf.copyRectToSurface(
+ _surface,
0, 0,
Common::Rect(_surface.w, _surface.h));
}
@@ -262,8 +259,7 @@ void Cursor::draw() {
// don't use _srcRect.right as 'x2' as this must be aligned first
// (_surface.w is recalculated thanks to convertSurfaceTo())
- _manager->drawMaskedSprite(
- dstSurface,
+ dstSurface.drawMaskedSprite(
_surface, _surfaceMask,
_dstRect.left + _xOffset, _dstRect.top,
Common::Rect(0, _srcRect.top, _surface.w, _srcRect.bottom));
@@ -281,9 +277,9 @@ void Cursor::restoreBackground() {
// as this is used only for direct rendering, we don't need to worry about offsettedSurf
// having different dimensions than the source surface
- Graphics::Surface &dstSurface = *_parentScreen->offsettedSurf;
+ Graphics::Surface &dstSurface = *_parentScreen->offsettedSurf->surfacePtr();
- // restore native pixels (i.e. bitplanes)
+ // restore native bitplanes or pixels, so it must be a Graphics::Surface to copy to
dstSurface.copyRectToSurface(
_savedBackground,
_savedRect.left, _savedRect.top,
diff --git a/backends/graphics/atari/atari-cursor.h b/backends/graphics/atari/atari-cursor.h
index 7413182e549..3bbb56b4ecc 100644
--- a/backends/graphics/atari/atari-cursor.h
+++ b/backends/graphics/atari/atari-cursor.h
@@ -22,8 +22,6 @@
#ifndef BACKENDS_GRAPHICS_ATARI_CURSOR_H
#define BACKENDS_GRAPHICS_ATARI_CURSOR_H
-#include "common/rect.h"
-#include "common/scummsys.h"
#include "graphics/surface.h"
//#include "backends/platform/atari/atari-debug.h"
@@ -37,7 +35,7 @@ struct Screen;
// These always get updates by ScummVM, no need to differentiate between engines and the overlay.
struct Cursor {
- Cursor(const AtariGraphicsManager *manager, const Screen *screen, int x, int y);
+ Cursor(const AtariGraphicsManager *manager, const Screen *screen);
void reset(const Graphics::Surface *boundingSurf, int xOffset) {
_boundingSurf = boundingSurf;
@@ -108,7 +106,7 @@ private:
const AtariGraphicsManager *_manager;
const Screen *_parentScreen;
- const Graphics::Surface *_boundingSurf;
+ const Graphics::Surface *_boundingSurf = nullptr;
int _xOffset = 0;
bool _positionChanged = true;
@@ -116,8 +114,8 @@ private:
bool _visibilityChanged = false;
bool _visible = false;
- int _x;
- int _y;
+ int _x = 0;
+ int _y = 0;
bool _outOfScreen = true;
Common::Rect _srcRect;
Common::Rect _dstRect;
diff --git a/backends/graphics/atari/atari-graphics-supervidel.h b/backends/graphics/atari/atari-graphics-supervidel.h
deleted file mode 100644
index 9a34f3d24a8..00000000000
--- a/backends/graphics/atari/atari-graphics-supervidel.h
+++ /dev/null
@@ -1,178 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#ifndef BACKENDS_GRAPHICS_ATARI_SUPERVIDEL_H
-#define BACKENDS_GRAPHICS_ATARI_SUPERVIDEL_H
-
-#ifdef USE_SUPERVIDEL
-
-#include "backends/graphics/atari/atari-graphics.h"
-
-#include <mint/osbind.h>
-
-#ifdef USE_SV_BLITTER
-#include <mint/trap14.h>
-#define ct60_vm(mode, value) (long)trap_14_wwl((short)0xc60e, (short)(mode), (long)(value))
-#define ct60_vmalloc(value) ct60_vm(0, value)
-#define ct60_vmfree(value) ct60_vm(1, value)
-
-#include "backends/platform/atari/dlmalloc.h"
-extern mspace g_mspace;
-#endif
-
-#include "backends/graphics/atari/atari-graphics-superblitter.h"
-#include "backends/platform/atari/atari-debug.h"
-#include "common/scummsys.h"
-
-class AtariSuperVidelManager : public AtariGraphicsManager {
-public:
- AtariSuperVidelManager() {
-#ifdef USE_SV_BLITTER
- atari_debug("SuperVidel FW Revision: %d, using %s", superVidelFwVersion, superVidelFwVersion >= 9
- ? "fast async FIFO" : "slower sync blitting");
-#else
- atari_debug("SuperVidel FW Revision: %d, SuperBlitter not used", superVidelFwVersion);
-#endif
- if (Supexec(hasSvRamBoosted))
- atari_debug("SV_XBIOS has the pmmu boost enabled");
- else
- atari_warning("SV_XBIOS has the pmmu boost disabled, set 'pmmu_boost = true' in C:\\SV.INF");
-
-#ifdef USE_SV_BLITTER
- size_t vramSize = ct60_vmalloc(-1) - (16 * 1024 * 1024); // SV XBIOS seems to forget the initial 16 MB ST RAM mirror
- _vramBase = vramSize > 0 ? (void *)ct60_vmalloc(vramSize) : nullptr;
- if (_vramBase) {
- g_mspace = create_mspace_with_base(_vramBase, vramSize, 0);
- atari_debug("Allocated VRAM at %p (%ld bytes)", _vramBase, vramSize);
- }
-
- if (!g_mspace)
- atari_warning("VRAM allocation failed");
-#endif
- // using virtual methods so must be done here
- allocateSurfaces();
- }
-
- ~AtariSuperVidelManager() {
- // using virtual methods so must be done here
- freeSurfaces();
-
-#ifdef USE_SV_BLITTER
- if (_vramBase) {
- destroy_mspace(g_mspace);
- g_mspace = nullptr;
-
- ct60_vmfree(_vramBase);
- _vramBase = nullptr;
- }
-#endif
- }
-
-private:
- AtariMemAlloc getStRamAllocFunc() const override {
- return [](size_t bytes) {
- uintptr ptr = Mxalloc(bytes, MX_STRAM);
-
- if (ptr != 0)
- ptr |= 0xA0000000;
-
- return (void *)ptr;
- };
- }
- AtariMemFree getStRamFreeFunc() const override {
- return [](void *ptr) { Mfree((uintptr)ptr & 0x00FFFFFF); };
- }
-
- void drawMaskedSprite(Graphics::Surface &dstSurface,
- const Graphics::Surface &srcSurface, const Graphics::Surface &srcMask,
- int destX, int destY,
- const Common::Rect &subRect) const override {
- assert(dstSurface.format == Graphics::PixelFormat::createFormatCLUT8());
- assert(subRect.width() % 16 == 0);
- assert(subRect.width() == srcSurface.w);
-
- const byte *src = (const byte *)srcSurface.getBasePtr(subRect.left, subRect.top);
- const uint16 *mask = (const uint16 *)srcMask.getBasePtr(subRect.left, subRect.top);
- byte *dst = (byte *)dstSurface.getBasePtr(destX, destY);
-
- const int h = subRect.height();
- const int w = subRect.width();
- const int dstOffset = dstSurface.pitch - w;
-
- for (int j = 0; j < h; ++j) {
- for (int i = 0; i < w; i += 16, mask++) {
- const uint16 m = *mask;
-
- if (m == 0xFFFF) {
- // all 16 pixels transparent
- src += 16;
- dst += 16;
- continue;
- }
-
- for (int k = 0; k < 16; ++k) {
- const uint16 bit = 1 << (15 - k);
-
- if (m & bit) {
- // transparent
- src++;
- dst++;
- } else {
- *dst++ = *src++;
- }
- }
- }
-
- dst += dstOffset;
- }
- }
-
- static long hasSvRamBoosted() {
- register long ret __asm__ ("d0") = 0;
-
- __asm__ volatile(
- "\tmovec %%itt0,%%d1\n"
- "\tcmp.l #0xA007E060,%%d1\n"
- "\tbne.s 1f\n"
-
- "\tmovec %%dtt0,%%d1\n"
- "\tcmp.l #0xA007E060,%%d1\n"
- "\tbne.s 1f\n"
-
- "\tmoveq #1,%%d0\n"
-
- "1:\n"
- : "=g"(ret) /* outputs */
- : /* inputs */
- : __CLOBBER_RETURN("d0") "d1", "cc"
- );
-
- return ret;
- }
-
-#ifdef USE_SV_BLITTER
- void *_vramBase = nullptr;
-#endif
-};
-
-#endif // USE_SUPERVIDEL
-
-#endif
diff --git a/backends/graphics/atari/atari-graphics-videl.h b/backends/graphics/atari/atari-graphics-videl.h
deleted file mode 100644
index 15126436e67..00000000000
--- a/backends/graphics/atari/atari-graphics-videl.h
+++ /dev/null
@@ -1,121 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#ifndef BACKENDS_GRAPHICS_ATARI_VIDEL_H
-#define BACKENDS_GRAPHICS_ATARI_VIDEL_H
-
-#include "backends/graphics/atari/atari-graphics.h"
-
-#include "backends/graphics/atari/atari-c2p-asm.h"
-#include "backends/graphics/atari/atari-graphics-asm.h"
-#include "common/system.h"
-
-class AtariVidelManager : public AtariGraphicsManager {
-public:
- AtariVidelManager() {
- // using virtual methods so must be done here
- allocateSurfaces();
- }
-
- ~AtariVidelManager() {
- // using virtual methods so must be done here
- freeSurfaces();
- }
-
-private:
- void copyRectToSurface(Graphics::Surface &dstSurface, const Graphics::Surface &srcSurface,
- int destX, int destY,
- const Common::Rect &subRect) const override {
- assert(subRect.left % 16 == 0);
- assert(subRect.width() % 16 == 0);
- assert(destX % 16 == 0);
- assert(srcSurface.format == dstSurface.format);
-
- const int bitsPerPixel = getBitsPerPixel(dstSurface.format);
-
- // 'pChunkyEnd' is a delicate parameter: the c2p routine compares it to the address register
- // used for pixel reading; two common mistakes:
- // 1. (subRect.left, subRect.bottom) = beginning of the next line *including the offset*
- // 2. (subRect.right, subRect.bottom) = even worse, end of the *next* line, not current one
- const byte *pChunky = (const byte *)srcSurface.getBasePtr(subRect.left, subRect.top);
- const byte *pChunkyEnd = (const byte *)srcSurface.getBasePtr(subRect.right, subRect.bottom-1);
-
- byte *pScreen = (byte *)dstSurface.getPixels() + destY * dstSurface.pitch + destX * bitsPerPixel/8;
-
- if (bitsPerPixel == 8) {
- if (srcSurface.pitch == subRect.width()) {
- if (srcSurface.pitch == dstSurface.pitch) {
- asm_c2p1x1_8(pChunky, pChunkyEnd, pScreen);
- return;
- } else if (srcSurface.pitch == dstSurface.pitch/2) {
- asm_c2p1x1_8_tt(pChunky, pChunkyEnd, pScreen, dstSurface.pitch);
- return;
- }
- }
-
- asm_c2p1x1_8_rect(
- pChunky, pChunkyEnd,
- subRect.width(),
- srcSurface.pitch,
- pScreen,
- dstSurface.pitch);
- } else {
- if (srcSurface.pitch == subRect.width() && srcSurface.pitch/2 == dstSurface.pitch) {
- asm_c2p1x1_4(pChunky, pChunkyEnd, pScreen);
- return;
- }
-
- asm_c2p1x1_4_rect(
- pChunky, pChunkyEnd,
- subRect.width(),
- srcSurface.pitch,
- pScreen,
- dstSurface.pitch);
- }
- }
-
- void drawMaskedSprite(Graphics::Surface &dstSurface,
- const Graphics::Surface &srcSurface, const Graphics::Surface &srcMask,
- int destX, int destY,
- const Common::Rect &subRect) const override {
- assert(subRect.width() % 16 == 0);
- assert(subRect.width() == srcSurface.w);
- assert(srcSurface.format == dstSurface.format);
-
- const int bitsPerPixel = getBitsPerPixel(dstSurface.format);
-
- if (bitsPerPixel == 4) {
- asm_draw_4bpl_sprite(
- (uint16 *)dstSurface.getPixels(), (const uint16 *)srcSurface.getBasePtr(subRect.left, subRect.top),
- (const uint16 *)srcMask.getBasePtr(subRect.left, subRect.top),
- destX, destY,
- dstSurface.pitch, subRect.width(), subRect.height());
- } else if (bitsPerPixel == 8) {
- asm_draw_8bpl_sprite(
- (uint16 *)dstSurface.getPixels(), (const uint16 *)srcSurface.getBasePtr(subRect.left, subRect.top),
- (const uint16 *)srcMask.getBasePtr(subRect.left, subRect.top),
- destX, destY,
- dstSurface.pitch, subRect.width(), subRect.height());
- }
- }
-};
-
-#endif
diff --git a/backends/graphics/atari/atari-graphics.cpp b/backends/graphics/atari/atari-graphics.cpp
index 6f7020952e1..bdabe154b56 100644
--- a/backends/graphics/atari/atari-graphics.cpp
+++ b/backends/graphics/atari/atari-graphics.cpp
@@ -29,22 +29,18 @@
#include <mint/sysvars.h>
#include "backends/platform/atari/atari-debug.h"
-#include "backends/platform/atari/dlmalloc.h"
#include "backends/keymapper/action.h"
#include "backends/keymapper/keymap.h"
#include "common/config-manager.h"
#include "common/str.h"
#include "common/translation.h"
#include "engines/engine.h"
-#include "graphics/blit.h"
#include "gui/ThemeEngine.h"
-#include "atari-graphics-superblitter.h"
+#include "atari-surface.h"
#define SCREEN_ACTIVE
-mspace g_mspace = nullptr;
-
static const Graphics::PixelFormat PIXELFORMAT_CLUT8 = Graphics::PixelFormat::createFormatCLUT8();
static const Graphics::PixelFormat PIXELFORMAT_RGB332 = Graphics::PixelFormat(1, 3, 3, 2, 0, 5, 2, 0, 0);
static const Graphics::PixelFormat PIXELFORMAT_RGB121 = Graphics::PixelFormat(1, 1, 2, 1, 0, 3, 1, 0, 0);
@@ -54,7 +50,7 @@ static void shrinkVidelVisibleArea() {
// In case of 320x240, the number is still 480 but data is fetched
// only for 240 lines so it doesn't make a difference to us.
#ifdef SCREEN_ACTIVE
- if (hasSuperVidel()) {
+ if (g_hasSuperVidel) {
const int vOffset = ((480 - 400) / 2) * 2; // *2 because of half-lines
// VDB = VBE = VDB + paddding/2
@@ -83,11 +79,11 @@ static int s_shakeYOffset;
static int s_aspectRatioCorrectionYOffset;
static bool s_shrinkVidelVisibleArea;
static bool s_setScreenOffsets;
-static Graphics::Surface *s_screenSurf;
+static AtariSurface *s_screenSurf;
static void VblHandler() {
// for easier querying
- static Graphics::Surface *surf;
+ static AtariSurface *surf;
if (s_screenSurf)
surf = s_screenSurf;
@@ -172,17 +168,22 @@ static Palette s_oldPalette;
void AtariGraphicsShutdown() {
Supexec(UninstallVblHandler);
+ AtariSurfaceDeinit();
+
+#ifdef SCREEN_ACTIVE
if (s_oldRez != -1) {
Setscreen(SCR_NOCHANGE, s_oldPhysbase, s_oldRez);
EsetPalette(0, s_oldPalette.entries, s_oldPalette.tt);
+
+ s_oldRez = -1;
} else if (s_oldMode != -1) {
static _RGB black[256];
VsetRGB(0, 256, black);
VsetScreen(SCR_NOCHANGE, s_oldPhysbase, SCR_NOCHANGE, SCR_NOCHANGE);
- if (hasSuperVidel()) {
+ if (g_hasSuperVidel) {
// SuperVidel XBIOS does not restore those (unlike TOS/EmuTOS)
long ssp = Super(SUP_SET);
//*((volatile char *)0xFFFF8265) = 0;
@@ -194,7 +195,10 @@ void AtariGraphicsShutdown() {
VsetMode(s_oldMode);
VsetRGB(0, s_oldPalette.entries, s_oldPalette.falcon);
+
+ s_oldMode = -1;
}
+#endif
}
AtariGraphicsManager::AtariGraphicsManager()
@@ -291,6 +295,14 @@ AtariGraphicsManager::AtariGraphicsManager()
}
s_oldPhysbase = Physbase();
+ AtariSurfaceInit();
+
+ allocateSurfaces();
+
+ if (!Supexec(InstallVblHandler)) {
+ error("VBL handler was not installed");
+ }
+
g_system->getEventManager()->getEventDispatcher()->registerObserver(this, 10, false);
}
@@ -299,6 +311,12 @@ AtariGraphicsManager::~AtariGraphicsManager() {
g_system->getEventManager()->getEventDispatcher()->unregisterObserver(this);
+ // this must be done here, too otherwise freeSurfaces() could release a surface
+ // still accessed by the vbl handler
+ Supexec(UninstallVblHandler);
+
+ freeSurfaces();
+
AtariGraphicsShutdown();
}
@@ -402,19 +420,6 @@ void AtariGraphicsManager::beginGFXTransaction() {
OSystem::TransactionError AtariGraphicsManager::endGFXTransaction() {
atari_debug("endGFXTransaction");
- {
- // this can't be done in the c-tor because if the c-tor called error(),
- // its d-tor wouldn't be called => the vbl handler wouldn't be uninstalled
- // (for the same reason we don't do any resolution changes in the c-tor)
- static bool vblHandlerInstalled;
- if (!vblHandlerInstalled) {
- if (!Supexec(InstallVblHandler)) {
- error("VBL handler was not installed");
- }
- vblHandlerInstalled = true;
- }
- }
-
_pendingState.inTransaction = false;
_ignoreCursorChanges = false;
@@ -436,7 +441,7 @@ OSystem::TransactionError AtariGraphicsManager::endGFXTransaction() {
} else if (((hasPendingGraphicsMode && _pendingState.mode == kDirectRendering)
|| (!hasPendingGraphicsMode && _currentState.mode == kDirectRendering))
&& _pendingState.width % 16 != 0
- && !hasSuperVidel()) {
+ && !g_hasSuperVidel) {
atari_warning("Engine surfaces not divisible by 16, aborting");
error |= OSystem::TransactionError::kTransactionSizeChangeFailed;
} else if (_overlayState == kOverlayIgnoredHide || _currentState.width != _pendingState.width || _currentState.height != _pendingState.height) {
@@ -467,7 +472,7 @@ OSystem::TransactionError AtariGraphicsManager::endGFXTransaction() {
if ((hasPendingGraphicsMode || hasPendingSize) && _currentState.isValid()) {
int c2pWidth = _currentState.width;
- if (!hasSuperVidel()) {
+ if (!g_hasSuperVidel) {
// make sure that c2p width is always divisible by 16
c2pWidth = (c2pWidth + 15) & -16;
}
@@ -480,26 +485,23 @@ OSystem::TransactionError AtariGraphicsManager::endGFXTransaction() {
_chunkySurfaceOffsetted.init(_currentState.width, _currentState.height, c2pWidth,
_chunkySurface.getBasePtr(xOffset, 0), _currentState.format);
- Common::Point oldCursorPosition = _screen[kFrontBuffer]->cursor.getPosition();
-
- _screen[kFrontBuffer]->reset(c2pWidth, _currentState.height, 8, _chunkySurfaceOffsetted, xOffset, true);
+ _screen[kFrontBuffer]->reset(c2pWidth, _currentState.height, _chunkySurfaceOffsetted, xOffset, true);
if (_currentState.mode > kSingleBuffering) {
- _screen[kBackBuffer1]->reset(c2pWidth, _currentState.height, 8, _chunkySurfaceOffsetted, xOffset, true);
- _screen[kBackBuffer2]->reset(c2pWidth, _currentState.height, 8, _chunkySurfaceOffsetted, xOffset, true);
+ _screen[kBackBuffer1]->reset(c2pWidth, _currentState.height, _chunkySurfaceOffsetted, xOffset, true);
+ _screen[kBackBuffer2]->reset(c2pWidth, _currentState.height, _chunkySurfaceOffsetted, xOffset, true);
}
{
- Common::Event event;
+ Common::Event event = {};
event.type = Common::EVENT_MOUSEMOVE;
event.mouse = _screen[kFrontBuffer]->cursor.getPosition();
- event.relMouse = event.mouse - oldCursorPosition;
g_system->getEventManager()->pushEvent(event);
}
if (hasPendingSize)
_pendingScreenChanges.queueVideoMode();
- _pendingScreenChanges.setScreenSurface(&_screen[kFrontBuffer]->surf);
+ _pendingScreenChanges.setScreenSurface(_screen[kFrontBuffer]->surf.get());
_palette.clear();
// TODO: maybe we could update real start/num values
@@ -582,18 +584,20 @@ void AtariGraphicsManager::copyRectToScreen(const void *buf, int pitch, int x, i
x, y, w, h,
directRendering);
- copyRectToScreenInternal(
- dstSurface,
- buf, pitch, x, y, w, h,
- _currentState.format,
- directRendering);
+ if (directRendering && !g_hasSuperVidel) {
+ copyRectToScreenInternal(
+ *_screen[kFrontBuffer]->offsettedSurf,
+ (const byte *)buf, pitch, x, y, w, h);
+ } else {
+ dstSurface.copyRectToSurface(buf, pitch, x, y, w, h);
+ }
}
Graphics::Surface *AtariGraphicsManager::lockScreen() {
//atari_debug("lockScreen");
return _currentState.mode == kDirectRendering
- ? _screen[kFrontBuffer]->offsettedSurf
+ ? _screen[kFrontBuffer]->offsettedSurf->surfacePtr()
: &_chunkySurfaceOffsetted;
}
@@ -666,7 +670,7 @@ void AtariGraphicsManager::updateScreen() {
assert(workScreen);
- bool screenUpdated = updateScreenInternal(workScreen, srcSurface ? *srcSurface : Graphics::Surface());
+ bool screenUpdated = updateScreenInternal(workScreen, srcSurface);
#ifdef SCREEN_ACTIVE
// this assume that the screen surface is not going to be used yet
@@ -697,7 +701,7 @@ void AtariGraphicsManager::updateScreen() {
_screen[kBackBuffer2] = tmp;
// queue BACK_BUFFER2 with the most recent frame content
- _pendingScreenChanges.setScreenSurface(&_screen[kBackBuffer2]->surf);
+ _pendingScreenChanges.setScreenSurface(_screen[kBackBuffer2]->surf.get());
// BACK_BUFFER1 is now current (work) buffer
}
@@ -750,12 +754,11 @@ void AtariGraphicsManager::showOverlay(bool inGUI) {
_screen[kFrontBuffer]->cursor.flushBackground(Common::Rect(), true);
}
- _pendingScreenChanges.setScreenSurface(&_screen[kOverlayBuffer]->surf);
+ _pendingScreenChanges.setScreenSurface(_screen[kOverlayBuffer]->surf.get());
// do not cache dirtyRects and saved cursor rect
_screen[kOverlayBuffer]->reset(
getOverlayWidth(), getOverlayHeight(),
- getBitsPerPixel(getOverlayFormat()),
*lockOverlay(), 0,
false);
@@ -784,7 +787,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 == kTripleBuffering ? kBackBuffer2 : kFrontBuffer]->surf);
+ _screen[_currentState.mode == kTripleBuffering ? kBackBuffer2 : kFrontBuffer]->surf.get());
_overlayState = kOverlayHidden;
@@ -894,10 +897,7 @@ void AtariGraphicsManager::grabOverlay(Graphics::Surface &surface) const {
assert(surface.h >= _overlaySurface.h);
assert(surface.format.bytesPerPixel == _overlaySurface.format.bytesPerPixel);
- const byte *src = (const byte *)_overlaySurface.getPixels();
- byte *dst = (byte *)surface.getPixels();
- Graphics::copyBlit(dst, src, surface.pitch,
- _overlaySurface.pitch, _overlaySurface.w, _overlaySurface.h, _overlaySurface.format.bytesPerPixel);
+ surface.copyRectToSurface(_overlaySurface, 0, 0, Common::Rect(_overlaySurface.w, _overlaySurface.h));
}
}
@@ -906,6 +906,7 @@ void AtariGraphicsManager::copyRectToOverlay(const void *buf, int pitch, int x,
Graphics::Surface &dstSurface = *lockOverlay();
+ // if true, SuperVidel is not present
const bool directRendering = isOverlayDirectRendering();
_screen[kOverlayBuffer]->addDirtyRect(
@@ -913,19 +914,21 @@ void AtariGraphicsManager::copyRectToOverlay(const void *buf, int pitch, int x,
x, y, w, h,
directRendering);
- copyRectToScreenInternal(
- dstSurface,
- buf, pitch, x, y, w, h,
- getOverlayFormat(),
- directRendering);
+ if (directRendering) {
+ copyRectToScreenInternal(
+ *_screen[kOverlayBuffer]->offsettedSurf,
+ (const byte *)buf, pitch, x, y, w, h);
+ } else {
+ dstSurface.copyRectToSurface(buf, pitch, x, y, w, h);
+ }
}
Graphics::Surface *AtariGraphicsManager::lockOverlay() {
//atari_debug("lockOverlay");
return isOverlayDirectRendering()
- ? _screen[kOverlayBuffer]->offsettedSurf
- : &_overlaySurface;
+ ? _screen[kOverlayBuffer]->offsettedSurf->surfacePtr()
+ : &_overlaySurface;
}
bool AtariGraphicsManager::showMouse(bool visible) {
@@ -1073,6 +1076,8 @@ void AtariGraphicsManager::allocateSurfaces() {
_screen[i] = new Screen(this, getMaximumScreenWidth(), getMaximumScreenHeight(), PIXELFORMAT_CLUT8, &_palette);
}
_screen[kOverlayBuffer] = new Screen(this, getOverlayWidth(), getOverlayHeight(), getOverlayFormat(), &_overlayPalette);
+ // initial position
+ _screen[kOverlayBuffer]->cursor.setPosition(getOverlayWidth() / 2, getOverlayHeight() / 2);
_chunkySurface.create(getMaximumScreenWidth(), getMaximumScreenHeight(), PIXELFORMAT_CLUT8);
_chunkySurfaceOffsetted = _chunkySurface;
@@ -1099,23 +1104,21 @@ void AtariGraphicsManager::addDirtyRectToScreens(const Graphics::Surface &dstSur
}
}
-bool AtariGraphicsManager::updateScreenInternal(Screen *dstScreen, const Graphics::Surface &srcSurface) {
+bool AtariGraphicsManager::updateScreenInternal(Screen *dstScreen, const Graphics::Surface *srcSurface) {
//atari_debug("updateScreenInternal");
const Screen::DirtyRects &dirtyRects = dstScreen->dirtyRects;
- Graphics::Surface *dstSurface = dstScreen->offsettedSurf;
+ auto &dstSurface = *dstScreen->offsettedSurf;
Cursor &cursor = dstScreen->cursor;
- const bool directRendering = srcSurface.getPixels() == nullptr;
-
bool updated = false;
- lockSuperBlitter();
+ LockSuperBlitter();
if (cursor.isChanged()) {
- const Common::Rect cursorBackgroundRect = cursor.flushBackground(Common::Rect(), directRendering);
+ const Common::Rect cursorBackgroundRect = cursor.flushBackground(Common::Rect(), srcSurface == nullptr);
if (!cursorBackgroundRect.isEmpty()) {
- copyRectToSurface(*dstSurface, srcSurface, cursorBackgroundRect.left, cursorBackgroundRect.top, cursorBackgroundRect);
+ dstSurface.copyRectToSurface(*srcSurface, cursorBackgroundRect.left, cursorBackgroundRect.top, cursorBackgroundRect);
updated |= true;
}
}
@@ -1125,9 +1128,9 @@ bool AtariGraphicsManager::updateScreenInternal(Screen *dstScreen, const Graphic
const bool drawCursor = cursor.isVisible() && (dstScreen->fullRedraw || cursor.isChanged());
- if (!directRendering) {
+ if (srcSurface) {
for (auto it = dirtyRects.begin(); it != dirtyRects.end(); ++it) {
- copyRectToSurface(*dstSurface, srcSurface, it->left, it->top, *it);
+ dstSurface.copyRectToSurface(*srcSurface, it->left, it->top, *it);
}
updated |= !dirtyRects.empty();
} else if (drawCursor) {
@@ -1135,7 +1138,7 @@ bool AtariGraphicsManager::updateScreenInternal(Screen *dstScreen, const Graphic
}
// unlock here because cursor.draw() is a software blit
- unlockSuperBlitter();
+ UnlockSuperBlitter();
if (drawCursor) {
cursor.draw();
@@ -1147,23 +1150,12 @@ bool AtariGraphicsManager::updateScreenInternal(Screen *dstScreen, const Graphic
return updated;
}
-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) {
- if (directRendering) {
- const Common::Rect rect = alignRect(x, y, x + w, y + h);
-
- // TODO: mask the unaligned parts and copy the rest
- Graphics::Surface srcSurface;
- byte *srcBuf = (byte *)const_cast<void *>(buf);
- srcBuf -= (x - rect.left); // HACK: this assumes pointer to a complete buffer
- srcSurface.init(rect.width(), rect.height(), pitch, srcBuf, format);
-
- copyRectToSurface(
- dstSurface, srcSurface,
- rect.left, rect.top,
- Common::Rect(rect.width(), rect.height()));
- } else {
- dstSurface.copyRectToSurface(buf, pitch, x, y, w, h);
- }
+void AtariGraphicsManager::copyRectToScreenInternal(AtariSurface &dstSurface,
+ const byte *buf, int pitch, int x, int y, int w, int h) {
+ const Common::Rect rect = alignRect(x, y, x + w, y + h);
+
+ // TODO: mask the unaligned parts and copy the rest
+ buf -= (x - rect.left); // HACK: this assumes pointer to a complete buffer
+
+ dstSurface.copyRectToSurface(buf, pitch, rect.left, rect.top, rect.width(), rect.height());
}
diff --git a/backends/graphics/atari/atari-graphics.h b/backends/graphics/atari/atari-graphics.h
index 96ed4f0d06c..449bbfe5c89 100644
--- a/backends/graphics/atari/atari-graphics.h
+++ b/backends/graphics/atari/atari-graphics.h
@@ -25,20 +25,17 @@
#include "backends/graphics/graphics.h"
#include "common/events.h"
-#include <mint/osbind.h>
-
-#include "common/rect.h"
#include "graphics/surface.h"
#include "atari-cursor.h"
-#include "atari-graphics-superblitter.h"
#include "atari-pendingscreenchanges.h"
#include "atari-screen.h"
+#include "atari-supervidel.h"
#define MAX_HZ_SHAKE 16 // Falcon only
#define MAX_V_SHAKE 16
-class AtariGraphicsManager : public GraphicsManager, Common::EventObserver {
+class AtariGraphicsManager final : public GraphicsManager, Common::EventObserver {
friend class Cursor;
friend class PendingScreenChanges;
friend class Screen;
@@ -114,14 +111,6 @@ public:
bool notifyEvent(const Common::Event &event) override;
Common::Keymap *getKeymap() const;
-protected:
- typedef void* (*AtariMemAlloc)(size_t bytes);
- typedef void (*AtariMemFree)(void *ptr);
-
- int getBitsPerPixel(const Graphics::PixelFormat &format) const;
- void allocateSurfaces();
- void freeSurfaces();
-
private:
enum {
kUnknownMode = -1,
@@ -134,6 +123,10 @@ private:
kActionToggleAspectRatioCorrection = 100,
};
+ int getBitsPerPixel(const Graphics::PixelFormat &format) const;
+ void allocateSurfaces();
+ void freeSurfaces();
+
#ifndef DISABLE_FANCY_THEMES
int16 getMaximumScreenHeight() const { return 480; }
int16 getMaximumScreenWidth() const { return _tt ? 320 : (_vgaMonitor ? 640 : 640*1.2); }
@@ -144,18 +137,18 @@ private:
void addDirtyRectToScreens(const Graphics::Surface &dstSurface,
int x, int y, int w, int h, bool directRendering);
- 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);
+ bool updateScreenInternal(Screen *dstScreen, const Graphics::Surface *srcSurface);
+ void copyRectToScreenInternal(AtariSurface &dstSurface,
+ const byte *buf, int pitch, int x, int y, int w, int h);
bool isOverlayDirectRendering() const {
+#ifndef DISABLE_FANCY_THEMES
// see osystem_atari.cpp
extern bool g_gameEngineActive;
-
+#endif
// overlay is direct rendered if in the launcher or if game is directly rendered
- // (on SuperVidel we always want to use shading/transparency but its direct rendering is fine and supported)
- return !hasSuperVidel()
+ // (on SuperVidel we always want to use _overlaySurface as source for background pixels)
+ return !g_hasSuperVidel
#ifndef DISABLE_FANCY_THEMES
&& (!g_gameEngineActive || _currentState.mode == kDirectRendering)
#endif
@@ -166,35 +159,17 @@ private:
Common::Rect alignRect(int x1, int y1, int x2, int y2) const {
// make non-virtual for performance reasons
- return hasSuperVidel()
+ return g_hasSuperVidel
? Common::Rect(x1, y1, x2, y2)
: Common::Rect(x1 & (-16), y1, (x2 + 15) & (-16), y2);
}
Common::Rect alignRect(const Common::Rect &rect) const {
// make non-virtual for performance reasons
- return hasSuperVidel()
+ return g_hasSuperVidel
? rect
: Common::Rect(rect.left & (-16), rect.top, (rect.right + 15) & (-16), rect.bottom);
}
- virtual AtariMemAlloc getStRamAllocFunc() const {
- return [](size_t bytes) { return (void *)Mxalloc(bytes, MX_STRAM); };
- }
- virtual AtariMemFree getStRamFreeFunc() const {
- return [](void *ptr) { Mfree(ptr); };
- }
-
- virtual void copyRectToSurface(Graphics::Surface &dstSurface, const Graphics::Surface &srcSurface,
- int destX, int destY,
- const Common::Rect &subRect) const {
- dstSurface.copyRectToSurface(srcSurface, destX, destY, subRect);
- }
-
- virtual void drawMaskedSprite(Graphics::Surface &dstSurface,
- const Graphics::Surface &srcSurface, const Graphics::Surface &srcMask,
- int destX, int destY,
- const Common::Rect &subRect) const = 0;
-
bool _vgaMonitor = true;
bool _tt = false;
diff --git a/backends/graphics/atari/atari-pendingscreenchanges.cpp b/backends/graphics/atari/atari-pendingscreenchanges.cpp
index 732b4bece39..b4c3c1ad7c9 100644
--- a/backends/graphics/atari/atari-pendingscreenchanges.cpp
+++ b/backends/graphics/atari/atari-pendingscreenchanges.cpp
@@ -28,7 +28,7 @@
#include "graphics/surface.h"
#include "atari-graphics.h"
-#include "atari-graphics-superblitter.h"
+#include "atari-supervidel.h"
void PendingScreenChanges::queueAll() {
_changes |= kAll;
@@ -107,7 +107,7 @@ void PendingScreenChanges::processAspectRatioCorrection(const Screen &screen) {
_changes |= kVideoMode;
} else {
_aspectRatioCorrectionYOffset =
- std::make_pair((screen.surf.h - 2*MAX_V_SHAKE - screen.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 {
@@ -121,7 +121,7 @@ void PendingScreenChanges::processAspectRatioCorrection(const Screen &screen) {
_aspectRatioCorrectionYOffset = std::make_pair(0, true);
_shrinkVidelVisibleArea = std::make_pair(false, true);
- if (hasSuperVidel())
+ if (g_hasSuperVidel)
_resetSuperVidel = true;
// kPendingVideoMode will reset the shrunken Videl area
diff --git a/backends/graphics/atari/atari-pendingscreenchanges.h b/backends/graphics/atari/atari-pendingscreenchanges.h
index b1915432999..1342c877af2 100644
--- a/backends/graphics/atari/atari-pendingscreenchanges.h
+++ b/backends/graphics/atari/atari-pendingscreenchanges.h
@@ -25,10 +25,8 @@
#include <utility>
class AtariGraphicsManager;
+class AtariSurface;
class Screen;
-namespace Graphics {
-class Surface;
-}
class PendingScreenChanges {
public:
@@ -40,7 +38,7 @@ public:
_changes &= ~kTransaction;
}
- void setScreenSurface(Graphics::Surface *surface) {
+ void setScreenSurface(AtariSurface *surface) {
_surface = surface;
}
@@ -65,7 +63,7 @@ public:
return _changes == kNone;
}
- Graphics::Surface *screenSurface() const {
+ AtariSurface *screenSurface() const {
return _surface;
}
const std::pair<int, bool>& aspectRatioCorrectionYOffset() const {
@@ -98,7 +96,7 @@ private:
const AtariGraphicsManager *_manager;
- Graphics::Surface *_surface = nullptr;
+ AtariSurface *_surface = nullptr;
int _mode;
bool _resetSuperVidel;
diff --git a/backends/graphics/atari/atari-screen.cpp b/backends/graphics/atari/atari-screen.cpp
index dd591a2965d..06801215386 100644
--- a/backends/graphics/atari/atari-screen.cpp
+++ b/backends/graphics/atari/atari-screen.cpp
@@ -24,48 +24,43 @@
#include <mint/falcon.h>
#include "atari-graphics.h"
-#include "atari-graphics-superblitter.h"
+#include "atari-supervidel.h"
+#include "atari-surface.h"
#include "backends/platform/atari/atari-debug.h"
Screen::Screen(AtariGraphicsManager *manager, int width, int height, const Graphics::PixelFormat &format, const Palette *palette_)
: _manager(manager)
- , cursor(manager, this, width / 2, height / 2)
+ , cursor(manager, this)
, palette(palette_) {
- const AtariGraphicsManager::AtariMemAlloc &allocFunc = _manager->getStRamAllocFunc();
-
- surf.init(
- width + (_manager->_tt ? 0 : 2 * MAX_HZ_SHAKE),
- height + 2 * MAX_V_SHAKE,
- (width + (_manager->_tt ? 0 : 2 * MAX_HZ_SHAKE)) * _manager->getBitsPerPixel(format) / 8,
- nullptr,
- format);
-
- void *pixelsUnaligned = allocFunc(sizeof(uintptr) + (surf.h * surf.pitch) + ALIGN - 1);
- if (!pixelsUnaligned) {
- error("Failed to allocate memory in ST RAM");
- }
-
- // TODO: use mspace_calloc similar as what we do with SuperVidel
- surf.setPixels((void *)(((uintptr)pixelsUnaligned + sizeof(uintptr) + ALIGN - 1) & (-ALIGN)));
-
- // store the unaligned pointer for later release
- *((uintptr *)surf.getPixels() - 1) = (uintptr)pixelsUnaligned;
-
- memset(surf.getPixels(), 0, surf.h * surf.pitch);
- _offsettedSurf.init(
- width, height, surf.pitch,
- surf.getBasePtr((surf.w - width) / 2, (surf.h - height) / 2),
- surf.format);
-}
+ const int bitsPerPixel = _manager->getBitsPerPixel(format);
-Screen::~Screen() {
- const AtariGraphicsManager::AtariMemFree &freeFunc = _manager->getStRamFreeFunc();
+ if (g_hasSuperVidel) {
+ surf.reset(new SuperVidelSurface(
+ width + 2 * MAX_HZ_SHAKE,
+ height + 2 * MAX_V_SHAKE,
+ format,
+ bitsPerPixel));
+ _offsettedSurf.reset(new SuperVidelSurface(bitsPerPixel));
+ } else {
+ surf.reset(new AtariSurface(
+ width + (_manager->_tt ? 0 : 2 * MAX_HZ_SHAKE),
+ height + 2 * MAX_V_SHAKE,
+ format,
+ bitsPerPixel));
+ _offsettedSurf.reset(new AtariSurface(bitsPerPixel));
+ }
- freeFunc((void *)*((uintptr *)surf.getPixels() - 1));
+ _offsettedSurf->create(
+ *surf,
+ Common::Rect(
+ Common::Point(
+ (surf->w - width) / 2, // left
+ (surf->h - height) / 2), // top
+ width, height));
}
-void Screen::reset(int width, int height, int bitsPerPixel, const Graphics::Surface &boundingSurf, int xOffset, bool resetCursorPosition) {
+void Screen::reset(int width, int height, const Graphics::Surface &boundingSurf, int xOffset, bool resetCursorPosition) {
_xOffset = xOffset;
clearDirtyRects();
@@ -75,67 +70,72 @@ void Screen::reset(int width, int height, int bitsPerPixel, const Graphics::Surf
rez = -1;
mode = -1;
+ const int bitsPerPixel = _manager->getBitsPerPixel(surf->format);
+
// erase old screen
- _offsettedSurf.fillRect(Common::Rect(_offsettedSurf.w, _offsettedSurf.h), 0);
+ _offsettedSurf->fillRect(_offsettedSurf->getBounds(), 0);
if (_manager->_tt) {
if (width <= 320 && height <= 240) {
- surf.w = 320;
- surf.h = 240 + 2 * MAX_V_SHAKE;
- surf.pitch = 2 * surf.w * bitsPerPixel / 8;
+ surf->w = 320;
+ surf->h = 240 + 2 * MAX_V_SHAKE;
+ surf->pitch = 2 * surf->w * bitsPerPixel / 8;
rez = kRezValueTTLow;
} else {
- surf.w = 640;
- surf.h = 480 + 2 * MAX_V_SHAKE;
- surf.pitch = surf.w * bitsPerPixel / 8;
+ surf->w = 640;
+ surf->h = 480 + 2 * MAX_V_SHAKE;
+ surf->pitch = surf->w * bitsPerPixel / 8;
rez = kRezValueTTMid;
}
} else {
mode = VsetMode(VM_INQUIRE) & PAL;
if (_manager->_vgaMonitor) {
- mode |= VGA | (bitsPerPixel == 4 ? BPS4 : (hasSuperVidel() ? BPS8C : BPS8));
+ mode |= VGA | (bitsPerPixel == 4 ? BPS4 : (g_hasSuperVidel ? BPS8C : BPS8));
if (width <= 320 && height <= 240) {
- surf.w = 320;
- surf.h = 240;
+ surf->w = 320;
+ surf->h = 240;
mode |= VERTFLAG | COL40;
} else {
- surf.w = 640;
- surf.h = 480;
+ surf->w = 640;
+ surf->h = 480;
mode |= COL80;
}
} else {
mode |= TV | (bitsPerPixel == 4 ? BPS4 : BPS8);
if (width <= 320 && height <= 200) {
- surf.w = 320;
- surf.h = 200;
+ surf->w = 320;
+ surf->h = 200;
mode |= COL40;
} else if (width <= 320*1.2 && height <= 200*1.2) {
- surf.w = 320*1.2;
- surf.h = 200*1.2;
+ surf->w = 320*1.2;
+ surf->h = 200*1.2;
mode |= OVERSCAN | COL40;
} else if (width <= 640 && height <= 400) {
- surf.w = 640;
- surf.h = 400;
+ surf->w = 640;
+ surf->h = 400;
mode |= VERTFLAG | COL80;
} else {
- surf.w = 640*1.2;
- surf.h = 400*1.2;
+ surf->w = 640*1.2;
+ surf->h = 400*1.2;
mode |= VERTFLAG | OVERSCAN | COL80;
}
}
- surf.w += 2 * MAX_HZ_SHAKE;
- surf.h += 2 * MAX_V_SHAKE;
- surf.pitch = surf.w * bitsPerPixel / 8;
+ surf->w += 2 * MAX_HZ_SHAKE;
+ surf->h += 2 * MAX_V_SHAKE;
+ surf->pitch = surf->w * bitsPerPixel / 8;
}
- _offsettedSurf.init(
- width, height, surf.pitch,
- surf.getBasePtr((surf.w - width) / 2, (surf.h - height) / 2),
- surf.format);
+ _offsettedSurf->create(
+ *surf,
+ Common::Rect(
+ Common::Point(
+ (surf->w - width) / 2, // left
+ (surf->h - height) / 2), // top
+ width, height));
}
void Screen::addDirtyRect(const Graphics::Surface &srcSurface, int x, int y, int w, int h, bool directRendering) {
diff --git a/backends/graphics/atari/atari-screen.h b/backends/graphics/atari/atari-screen.h
index 2cd49e0d8aa..ce7812e433a 100644
--- a/backends/graphics/atari/atari-screen.h
+++ b/backends/graphics/atari/atari-screen.h
@@ -23,12 +23,12 @@
#define BACKENDS_GRAPHICS_ATARI_SCREEN_H
#include <unordered_set>
-#include <mint/ostruct.h>
+#include <mint/ostruct.h> // _RGB
-#include "common/rect.h"
-#include "graphics/surface.h"
+#include "common/ptr.h"
#include "atari-cursor.h"
+#include "atari-surface.h"
template<>
struct std::hash<Common::Rect>
@@ -44,26 +44,25 @@ class AtariGraphicsManager;
class Palette {
public:
void clear() {
- memset(data, 0, sizeof(data));
+ memset(_data, 0, sizeof(_data));
entries = 0;
}
- uint16 *const tt = reinterpret_cast<uint16*>(data);
- _RGB *const falcon = reinterpret_cast<_RGB*>(data);
+ uint16 *const tt = reinterpret_cast<uint16*>(_data);
+ _RGB *const falcon = reinterpret_cast<_RGB*>(_data);
int entries = 0;
private:
- byte data[256*4] = {};
+ byte _data[256*4] = {};
};
struct Screen {
using DirtyRects = std::unordered_set<Common::Rect>;
Screen(AtariGraphicsManager *manager, int width, int height, const Graphics::PixelFormat &format, const Palette *palette);
- ~Screen();
- void reset(int width, int height, int bitsPerPixel, const Graphics::Surface &boundingSurf, int xOffset, bool resetCursorPosition);
+ void reset(int width, int height, const Graphics::Surface &boundingSurf, int xOffset, bool resetCursorPosition);
// must be called before any rectangle drawing
void addDirtyRect(const Graphics::Surface &srcSurface, int x, int y, int w, int h, bool directRendering);
@@ -72,7 +71,7 @@ struct Screen {
fullRedraw = false;
}
- Graphics::Surface surf;
+ Common::ScopedPtr<AtariSurface> surf;
const Palette *palette;
DirtyRects dirtyRects;
bool fullRedraw = false;
@@ -81,7 +80,7 @@ struct Screen {
int rez = -1;
int mode = -1;
- Graphics::Surface *const offsettedSurf = &_offsettedSurf;
+ const Common::ScopedPtr<AtariSurface> &offsettedSurf = _offsettedSurf;
private:
static constexpr size_t ALIGN = 16; // 16 bytes
@@ -97,7 +96,7 @@ private:
const AtariGraphicsManager *_manager;
- Graphics::Surface _offsettedSurf;
+ Common::ScopedPtr<AtariSurface> _offsettedSurf;
int _xOffset = 0;
};
diff --git a/backends/graphics/atari/atari-graphics-superblitter.h b/backends/graphics/atari/atari-supervidel.cpp
similarity index 55%
rename from backends/graphics/atari/atari-graphics-superblitter.h
rename to backends/graphics/atari/atari-supervidel.cpp
index 32be0380750..d9bfef5ac98 100644
--- a/backends/graphics/atari/atari-graphics-superblitter.h
+++ b/backends/graphics/atari/atari-supervidel.cpp
@@ -19,36 +19,48 @@
*
*/
-#ifndef BACKENDS_GRAPHICS_ATARI_SUPERBLITTER_H
-#define BACKENDS_GRAPHICS_ATARI_SUPERBLITTER_H
+#include "atari-supervidel.h"
-#ifdef USE_SUPERVIDEL
+#include "common/scummsys.h"
-#include <mint/cookie.h>
-#include <mint/falcon.h>
+bool g_hasSuperVidel = false;
-// bits 9:0
-#define SV_VERSION ((volatile long *)0x8001007C)
+#ifdef USE_SUPERVIDEL
-inline static bool hasSuperVidel() {
- // this works also on the TT
- static bool hasSuperVidel = Getcookie(C_SupV, NULL) == C_FOUND && VgetMonitor() == MON_VGA;
- return hasSuperVidel;
-}
+#ifdef USE_SV_BLITTER
+int g_superVidelFwVersion = 0;
-static int superVidelFwVersion = hasSuperVidel() ? *SV_VERSION & 0x01ff : 0;
+static bool isSuperBlitterLocked;
-#else
+void SyncSuperBlitter() {
+ // if externally locked, let the owner decide when to sync (unlock)
+ if (isSuperBlitterLocked)
+ return;
-constexpr bool hasSuperVidel() {
- return false;
+ // while FIFO not empty...
+ if (g_superVidelFwVersion >= 9)
+ while (!(*SV_BLITTER_FIFO & 1));
+ // while busy blitting...
+ while (*SV_BLITTER_CONTROL & 1);
}
+#endif // USE_SV_BLITTER
-constexpr int superVidelFwVersion = 0;
+void LockSuperBlitter() {
+#ifdef USE_SV_BLITTER
+ assert(!isSuperBlitterLocked);
-#endif // USE_SUPERVIDEL
+ isSuperBlitterLocked = true;
+#endif
+}
-void lockSuperBlitter();
-void unlockSuperBlitter();
+void UnlockSuperBlitter() {
+#ifdef USE_SV_BLITTER
+ assert(isSuperBlitterLocked);
+ isSuperBlitterLocked = false;
+ if (g_hasSuperVidel)
+ SyncSuperBlitter();
#endif
+}
+
+#endif // USE_SUPERVIDEL
diff --git a/backends/graphics/atari/atari-supervidel.h b/backends/graphics/atari/atari-supervidel.h
new file mode 100644
index 00000000000..c2725c4d718
--- /dev/null
+++ b/backends/graphics/atari/atari-supervidel.h
@@ -0,0 +1,67 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef BACKENDS_GRAPHICS_ATARI_SUPERVIDEL_H
+#define BACKENDS_GRAPHICS_ATARI_SUPERVIDEL_H
+
+#ifdef USE_SUPERVIDEL
+
+// bits 26:0
+#define SV_BLITTER_SRC1 ((volatile long *)0x80010058)
+#define SV_BLITTER_SRC2 ((volatile long *)0x8001005C)
+#define SV_BLITTER_DST ((volatile long *)0x80010060)
+// The amount of bytes that are to be copied in a horizontal line, minus 1
+#define SV_BLITTER_COUNT ((volatile long *)0x80010064)
+// The amount of bytes that are to be added to the line start address after a line has been copied, in order to reach the next one
+#define SV_BLITTER_SRC1_OFFSET ((volatile long *)0x80010068)
+#define SV_BLITTER_SRC2_OFFSET ((volatile long *)0x8001006C)
+#define SV_BLITTER_DST_OFFSET ((volatile long *)0x80010070)
+// bits 11:0 - The amount of horizontal lines to do
+#define SV_BLITTER_MASK_AND_LINES ((volatile long *)0x80010074)
+// bit 0 - busy / start
+// bits 4:1 - blit mode
+#define SV_BLITTER_CONTROL ((volatile long *)0x80010078)
+// bits 9:0
+#define SV_VERSION ((volatile long *)0x8001007C)
+// bit 0 - empty (read only)
+// bit 1 - full (read only)
+// bits 31:0 - data (write only)
+#define SV_BLITTER_FIFO ((volatile long *)0x80010080)
+
+#ifdef USE_SV_BLITTER
+extern int g_superVidelFwVersion;
+
+void SyncSuperBlitter();
+#endif // USE_SV_BLITTER
+
+void LockSuperBlitter();
+void UnlockSuperBlitter();
+
+#else
+
+static inline void LockSuperBlitter() {}
+static inline void UnlockSuperBlitter() {}
+
+#endif // USE_SUPERVIDEL
+
+extern bool g_hasSuperVidel;
+
+#endif // BACKENDS_GRAPHICS_ATARI_SUPERVIDEL_H
diff --git a/backends/graphics/atari/atari-surface.cpp b/backends/graphics/atari/atari-surface.cpp
new file mode 100644
index 00000000000..efa9dcc9c0e
--- /dev/null
+++ b/backends/graphics/atari/atari-surface.cpp
@@ -0,0 +1,365 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "atari-surface.h"
+#include "graphics/surface.h"
+
+#include <mint/cookie.h>
+#include <mint/falcon.h>
+#include <mint/trap14.h>
+#define ct60_vm(mode, value) (long)trap_14_wwl((short)0xc60e, (short)(mode), (long)(value))
+#define ct60_vmalloc(value) ct60_vm(0, value)
+#define ct60_vmfree(value) ct60_vm(1, value)
+
+#include "backends/graphics/atari/atari-c2p-asm.h"
+#include "backends/graphics/atari/atari-graphics-asm.h"
+#include "backends/graphics/atari/atari-supervidel.h"
+#include "backends/platform/atari/atari-debug.h"
+#include "backends/platform/atari/dlmalloc.h"
+#include "common/textconsole.h" // error()
+
+static struct MemoryPool {
+ void create() {
+ if (base)
+ _mspace = create_mspace_with_base((void *)base, size, 0);
+
+ if (_mspace)
+ atari_debug("Allocated mspace at 0x%08lx (%ld bytes)", base, size);
+ else
+ error("mspace allocation failed at 0x%08lx (%ld bytes)", base, size);
+ }
+
+ void destroy() {
+ if (_mspace) {
+ destroy_mspace(_mspace);
+ _mspace = nullptr;
+ }
+ }
+
+ void *malloc(size_t bytes) {
+ assert(_mspace);
+ return mspace_malloc(_mspace, bytes);
+ }
+
+ void *calloc(size_t n_elements, size_t elem_size) {
+ assert(_mspace);
+ return mspace_calloc(_mspace, n_elements, elem_size);
+ }
+
+ void free(void *mem) {
+ assert(_mspace);
+ mspace_free(_mspace, mem);
+ }
+
+ long base;
+ long size;
+
+private:
+ mspace _mspace;
+} s_videoRamPool, s_blitterPool;
+
+static MemoryPool *s_currentPool;
+
+namespace Graphics {
+
+void Surface::create(int16 width, int16 height, const PixelFormat &f) {
+ assert(width >= 0 && height >= 0);
+ free();
+
+ w = width;
+ h = height;
+ format = f;
+ pitch = w * format.bytesPerPixel;
+
+ if (width && height) {
+ if (s_currentPool) {
+ pixels = s_currentPool->calloc(height * pitch, format.bytesPerPixel);
+ if (!pixels)
+ error("Not enough VRAM to allocate a surface");
+
+ if (s_currentPool == &s_blitterPool) {
+ assert(pixels >= (void *)0xA1000000);
+ } else if (s_currentPool == &s_videoRamPool) {
+#ifdef USE_SUPERVIDEL
+ if (g_hasSuperVidel)
+ assert(pixels >= (void *)0xA0000000 && pixels < (void *)0xA1000000);
+ else
+#endif
+ assert(pixels < (void *)0x01000000);
+ }
+ } else {
+ pixels = ::calloc(height * pitch, format.bytesPerPixel);
+ if (!pixels)
+ error("Not enough RAM to allocate a surface");
+ }
+
+ assert(((uintptr)pixels & (MALLOC_ALIGNMENT - 1)) == 0);
+ }
+}
+
+void Surface::free() {
+ if (pixels) {
+ if (s_currentPool)
+ s_currentPool->free(pixels);
+ else
+ ::free(pixels);
+
+ pixels = nullptr;
+ }
+
+ w = h = pitch = 0;
+ format = PixelFormat();
+}
+
+} // End of namespace Graphics
+
+///////////////////////////////////////////////////////////////////////////////
+
+AtariSurface::AtariSurface(int bitsPerPixel)
+ : _bitsPerPixel(bitsPerPixel) {
+}
+
+AtariSurface::AtariSurface(int16 width, int16 height, const Graphics::PixelFormat &pixelFormat, int bitsPerPixel)
+ : _bitsPerPixel(bitsPerPixel) {
+ create(width, height, pixelFormat);
+}
+
+AtariSurface::~AtariSurface() {
+ free();
+}
+
+void AtariSurface::create(int16 width, int16 height, const Graphics::PixelFormat &pixelFormat) {
+ MemoryPool *oldPool = s_currentPool;
+ s_currentPool = &s_videoRamPool;
+
+ Graphics::ManagedSurface::create(width * _bitsPerPixel / 8, height, pixelFormat);
+ w = width;
+
+ s_currentPool = oldPool;
+}
+
+void AtariSurface::free() {
+ MemoryPool *oldPool = s_currentPool;
+ s_currentPool = &s_videoRamPool;
+
+ Graphics::ManagedSurface::free();
+
+ s_currentPool = oldPool;
+}
+
+void AtariSurface::copyRectToSurface(const void *buffer, int srcPitch, int destX, int destY, int width, int height) {
+ assert(width % 16 == 0);
+ assert(destX % 16 == 0);
+
+ // 'pChunkyEnd' is a delicate parameter: the c2p routine compares it to the address register
+ // used for pixel reading; two common mistakes:
+ // 1. (subRect.left, subRect.bottom) = beginning of the next line *including the offset*
+ // 2. (subRect.right, subRect.bottom) = even worse, end of the *next* line, not current one
+ const byte *pChunky = (const byte *)buffer;
+ const byte *pChunkyEnd = pChunky + (height - 1) * srcPitch + width * format.bytesPerPixel;
+
+ byte *pScreen = (byte *)getPixels() + destY * pitch + destX * _bitsPerPixel/8;
+
+ if (_bitsPerPixel == 8) {
+ if (srcPitch == width) {
+ if (srcPitch == pitch) {
+ asm_c2p1x1_8(pChunky, pChunkyEnd, pScreen);
+ return;
+ } else if (srcPitch == pitch/2) {
+ asm_c2p1x1_8_tt(pChunky, pChunkyEnd, pScreen, pitch);
+ return;
+ }
+ }
+
+ asm_c2p1x1_8_rect(
+ pChunky, pChunkyEnd,
+ width,
+ srcPitch,
+ pScreen,
+ pitch);
+ } else {
+ if (srcPitch == width && srcPitch/2 == pitch) {
+ asm_c2p1x1_4(pChunky, pChunkyEnd, pScreen);
+ return;
+ }
+
+ asm_c2p1x1_4_rect(
+ pChunky, pChunkyEnd,
+ width,
+ srcPitch,
+ pScreen,
+ pitch);
+ }
+}
+
+void AtariSurface::drawMaskedSprite(
+ const Graphics::Surface &srcSurface, const Graphics::Surface &srcMask,
+ int destX, int destY,
+ const Common::Rect &subRect) {
+ assert(subRect.width() % 16 == 0);
+ assert(subRect.width() == srcSurface.w);
+ assert(srcSurface.format == format);
+
+ if (_bitsPerPixel == 4) {
+ asm_draw_4bpl_sprite(
+ (uint16 *)getPixels(), (const uint16 *)srcSurface.getBasePtr(subRect.left, subRect.top),
+ (const uint16 *)srcMask.getBasePtr(subRect.left, subRect.top),
+ destX, destY,
+ pitch, subRect.width(), subRect.height());
+ } else if (_bitsPerPixel == 8) {
+ asm_draw_8bpl_sprite(
+ (uint16 *)getPixels(), (const uint16 *)srcSurface.getBasePtr(subRect.left, subRect.top),
+ (const uint16 *)srcMask.getBasePtr(subRect.left, subRect.top),
+ destX, destY,
+ pitch, subRect.width(), subRect.height());
+ }
+}
+
+void SuperVidelSurface::drawMaskedSprite(
+ const Graphics::Surface &srcSurface, const Graphics::Surface &srcMask,
+ int destX, int destY,
+ const Common::Rect &subRect) {
+ assert(subRect.width() % 16 == 0);
+ assert(subRect.width() == srcSurface.w);
+ assert(srcSurface.format == format);
+ assert(_bitsPerPixel == 8);
+
+ const byte *src = (const byte *)srcSurface.getBasePtr(subRect.left, subRect.top);
+ const uint16 *mask = (const uint16 *)srcMask.getBasePtr(subRect.left, subRect.top);
+ byte *dst = (byte *)getBasePtr(destX, destY);
+
+ const int height = subRect.height();
+ const int width = subRect.width();
+ const int dstOffset = pitch - width;
+
+ for (int j = 0; j < height; ++j) {
+ for (int i = 0; i < width; i += 16, mask++) {
+ const uint16 m = *mask;
+
+ if (m == 0xFFFF) {
+ // all 16 pixels transparent
+ src += 16;
+ dst += 16;
+ continue;
+ }
+
+ for (int k = 0; k < 16; ++k) {
+ const uint16 bit = 1 << (15 - k);
+
+ if (m & bit) {
+ // transparent
+ src++;
+ dst++;
+ } else {
+ *dst++ = *src++;
+ }
+ }
+ }
+
+ dst += dstOffset;
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+#ifdef USE_SUPERVIDEL
+static long hasSvRamBoosted() {
+ register long ret __asm__ ("d0") = 0;
+
+ __asm__ volatile(
+ "\tmovec %%itt0,%%d1\n"
+ "\tcmp.l #0xA007E060,%%d1\n"
+ "\tbne.s 1f\n"
+
+ "\tmovec %%dtt0,%%d1\n"
+ "\tcmp.l #0xA007E060,%%d1\n"
+ "\tbne.s 1f\n"
+
+ "\tmoveq #1,%%d0\n"
+
+ "1:\n"
+ : "=g"(ret) /* outputs */
+ : /* inputs */
+ : __CLOBBER_RETURN("d0") "d1", "cc"
+ );
+
+ return ret;
+}
+#endif // USE_SUPERVIDEL
+
+void AtariSurfaceInit() {
+#ifdef USE_SUPERVIDEL
+ g_hasSuperVidel = Getcookie(C_SupV, NULL) == C_FOUND && VgetMonitor() == MON_VGA;
+
+ if (g_hasSuperVidel) {
+#ifdef USE_SV_BLITTER
+ g_superVidelFwVersion = *SV_VERSION & 0x01ff;
+
+ atari_debug("SuperVidel FW Revision: %d, using %s", g_superVidelFwVersion,
+ g_superVidelFwVersion >= 9 ? "fast async FIFO" : "slower sync blitting");
+#else
+ atari_debug("SuperVidel FW Revision: %d, SuperBlitter not used", *SV_VERSION & 0x01ff);
+#endif
+ if (Supexec(hasSvRamBoosted))
+ atari_debug("SV_XBIOS has the pmmu boost enabled");
+ else
+ atari_warning("SV_XBIOS has the pmmu boost disabled, set 'pmmu_boost = true' in C:\\SV.INF");
+
+#ifdef USE_SV_BLITTER
+ s_blitterPool.size = ct60_vmalloc(-1) - (16 * 1024 * 1024); // SV XBIOS seems to forget the initial 16 MB ST RAM mirror
+ s_blitterPool.base = s_blitterPool.size > 0 ? ct60_vmalloc(s_blitterPool.size) : 0;
+ s_blitterPool.create();
+ // default pool is either null or blitter
+ s_currentPool = &s_blitterPool;
+#endif
+ }
+#endif // USE_SUPERVIDEL
+
+ s_videoRamPool.size = 2 * 1024 * 1024; // allocate 2 MiB, leave the rest for SDMA / Blitter usage
+ s_videoRamPool.base = s_videoRamPool.size > 0 ? Mxalloc(s_videoRamPool.size, MX_STRAM) : 0;
+#ifdef USE_SUPERVIDEL
+ if (g_hasSuperVidel && s_videoRamPool.base)
+ s_videoRamPool.base |= 0xA0000000;
+#endif
+ s_videoRamPool.create();
+}
+
+void AtariSurfaceDeinit() {
+ s_videoRamPool.destroy();
+ if (s_videoRamPool.base) {
+#ifdef USE_SUPERVIDEL
+ if (g_hasSuperVidel)
+ s_videoRamPool.base &= 0x00FFFFFF;
+#endif
+ Mfree(s_videoRamPool.base);
+ s_videoRamPool.base = 0;
+ s_videoRamPool.size = 0;
+ }
+
+#ifdef USE_SV_BLITTER
+ s_blitterPool.destroy();
+ if (s_blitterPool.base) {
+ ct60_vmfree(s_blitterPool.base);
+ s_blitterPool.base = 0;
+ s_blitterPool.size = 0;
+ }
+#endif
+}
diff --git a/backends/graphics/atari/atari-surface.h b/backends/graphics/atari/atari-surface.h
new file mode 100644
index 00000000000..62bcca36883
--- /dev/null
+++ b/backends/graphics/atari/atari-surface.h
@@ -0,0 +1,84 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef BACKENDS_GRAPHICS_ATARI_SURFACE_H
+#define BACKENDS_GRAPHICS_ATARI_SURFACE_H
+
+#include "graphics/managed_surface.h"
+
+class AtariSurface : public Graphics::ManagedSurface {
+public:
+ AtariSurface(int bitsPerPixel);
+ AtariSurface(int16 width, int16 height, const Graphics::PixelFormat &pixelFormat, int bitsPerPixel);
+ ~AtariSurface() override;
+
+ using Graphics::ManagedSurface::create;
+ void create(int16 width, int16 height, const Graphics::PixelFormat &pixelFormat) final override;
+ void free() final override;
+
+ void addDirtyRect(const Common::Rect &r) final override {};
+
+ // no override as ManagedSurface::copyRectToSurface is not a virtual function!
+ virtual void copyRectToSurface(const void *buffer, int srcPitch, int destX, int destY, int width, int height);
+ virtual void copyRectToSurface(const Graphics::Surface &srcSurface, int destX, int destY, const Common::Rect &subRect) {
+ assert(subRect.left % 16 == 0);
+ assert(srcSurface.format == format);
+
+ copyRectToSurface(
+ srcSurface.getBasePtr(subRect.left, subRect.top), srcSurface.pitch,
+ destX, destY,
+ subRect.width(), subRect.height());
+ }
+
+ virtual void drawMaskedSprite(const Graphics::Surface &srcSurface, const Graphics::Surface &srcMask,
+ int destX, int destY,
+ const Common::Rect &subRect);
+
+protected:
+ int _bitsPerPixel = 0;
+};
+
+class SuperVidelSurface final : public AtariSurface {
+public:
+ SuperVidelSurface(int bitsPerPixel)
+ : AtariSurface(bitsPerPixel) {
+ }
+ SuperVidelSurface(int16 width, int16 height, const Graphics::PixelFormat &pixelFormat, int bitsPerPixel)
+ : AtariSurface(width, height, pixelFormat, bitsPerPixel) {
+ }
+
+ //using Graphics::ManagedSurface::copyRectToSurface;
+ void copyRectToSurface(const void *buffer, int srcPitch, int destX, int destY, int width, int height) override {
+ Graphics::ManagedSurface::copyRectToSurface(buffer, srcPitch, destX, destY, width, height);
+ }
+ void copyRectToSurface(const Graphics::Surface &srcSurface, int destX, int destY, const Common::Rect &subRect) override {
+ Graphics::ManagedSurface::copyRectToSurface(srcSurface, destX, destY, subRect);
+ }
+
+ void drawMaskedSprite(const Graphics::Surface &srcSurface, const Graphics::Surface &srcMask,
+ int destX, int destY,
+ const Common::Rect &subRect) override;
+};
+
+void AtariSurfaceInit();
+void AtariSurfaceDeinit();
+
+#endif // BACKENDS_GRAPHICS_ATARI_SURFACE_H
diff --git a/backends/module.mk b/backends/module.mk
index e73da595cbc..66c7ecc37d1 100644
--- a/backends/module.mk
+++ b/backends/module.mk
@@ -387,6 +387,8 @@ MODULE_OBJS += \
graphics/atari/atari-graphics-asm.o \
graphics/atari/atari-pendingscreenchanges.o \
graphics/atari/atari-screen.o \
+ graphics/atari/atari-supervidel.o \
+ graphics/atari/atari-surface.o \
mixer/atari/atari-mixer.o
endif
diff --git a/backends/platform/atari/osystem_atari.cpp b/backends/platform/atari/osystem_atari.cpp
index 663a8a47cd4..464e66d2029 100644
--- a/backends/platform/atari/osystem_atari.cpp
+++ b/backends/platform/atari/osystem_atari.cpp
@@ -46,10 +46,6 @@
#include "common/config-manager.h"
#include "backends/events/atari/atari-events.h"
#include "backends/events/default/default-events.h"
-#include "backends/graphics/atari/atari-graphics-asm.h"
-#include "backends/graphics/atari/atari-graphics-superblitter.h"
-#include "backends/graphics/atari/atari-graphics-supervidel.h"
-#include "backends/graphics/atari/atari-graphics-videl.h"
#include "backends/graphics/atari/atari-graphics.h"
#include "backends/keymapper/hardware-input.h"
#include "backends/mixer/atari/atari-mixer.h"
@@ -78,10 +74,11 @@ extern void nf_init(void);
extern void nf_print(const char* msg);
static int s_app_id = -1;
+static void (*s_old_procterm)(void) = nullptr;
static volatile uint32 counter_200hz;
-static bool exit_already_called = false;
+static bool s_dtor_already_called = false;
static long atari_200hz_init(void)
{
@@ -129,11 +126,7 @@ static long atari_200hz_shutdown(void)
}
static void critical_restore() {
- extern void AtariAudioShutdown();
- extern void AtariGraphicsShutdown();
-
- AtariAudioShutdown();
- AtariGraphicsShutdown();
+ //atari_debug("critical_restore()");
Supexec(atari_200hz_shutdown);
@@ -154,12 +147,25 @@ static void critical_restore() {
graf_mouse(M_ON, NULL);
}
#endif
+
+ // avoid infinite recursion if either of the shutdown procedures fails
+ (void)Setexc(VEC_PROCTERM, s_old_procterm);
+
+ extern void AtariAudioShutdown();
+ extern void AtariGraphicsShutdown();
+
+ AtariAudioShutdown();
+ AtariGraphicsShutdown();
}
// called on normal program termination (via exit() or returning from main())
static void exit_restore() {
- if (!exit_already_called)
+ // causes a crash upon termination
+ //atari_debug("exit_restore()");
+
+ if (!s_dtor_already_called)
g_system->destroy();
+ // else critical_restore() will be called, too
}
OSystem_Atari::OSystem_Atari() {
@@ -218,13 +224,15 @@ OSystem_Atari::OSystem_Atari() {
// protect against sudden exit()
atexit(exit_restore);
// protect against sudden crash
- _old_procterm = Setexc(VEC_PROCTERM, -1);
+ s_old_procterm = Setexc(VEC_PROCTERM, -1);
(void)Setexc(VEC_PROCTERM, critical_restore);
}
OSystem_Atari::~OSystem_Atari() {
atari_debug("OSystem_Atari::~OSystem_Atari()");
+ s_dtor_already_called = true;
+
// _audiocdManager needs to be deleted before _mixerManager to avoid a crash.
delete _audiocdManager;
_audiocdManager = nullptr;
@@ -271,11 +279,12 @@ OSystem_Atari::~OSystem_Atari() {
}
// graceful exit
- exit_already_called = true;
- (void)Setexc(VEC_PROCTERM, _old_procterm);
+ (void)Setexc(VEC_PROCTERM, s_old_procterm);
}
void OSystem_Atari::initBackend() {
+ atari_debug("OSystem_Atari::initBackend()");
+
s_app_id = appl_init();
if (s_app_id != -1) {
// get the ID of the current physical screen workstation
@@ -314,13 +323,7 @@ void OSystem_Atari::initBackend() {
_eventManager = new DefaultEventManager(makeKeyboardRepeatingEventSource(atariEventSource));
// AtariGraphicsManager needs _eventManager ready
- AtariGraphicsManager *atariGraphicsManager;
-#ifdef USE_SUPERVIDEL
- if (hasSuperVidel())
- atariGraphicsManager = new AtariSuperVidelManager();
- else
-#endif
- atariGraphicsManager = new AtariVidelManager();
+ AtariGraphicsManager *atariGraphicsManager = new AtariGraphicsManager();
_graphicsManager = atariGraphicsManager;
atariEventSource->setGraphicsManager(atariGraphicsManager);
@@ -410,7 +413,17 @@ Common::HardwareInputSet *OSystem_Atari::getHardwareInputSet() {
void OSystem_Atari::quit() {
atari_debug("OSystem_Atari::quit()");
- destroy();
+ if (!s_dtor_already_called)
+ destroy();
+}
+
+void OSystem_Atari::fatalError() {
+ atari_debug("OSystem_Atari::fatalError()");
+
+ quit();
+
+ // let exit_restore() and critical_restore() handle the recovery
+ exit(1);
}
void OSystem_Atari::logMessage(LogMessageType::Type type, const char *message) {
diff --git a/backends/platform/atari/osystem_atari.h b/backends/platform/atari/osystem_atari.h
index c3be4d8e1a6..b45f4413b7f 100644
--- a/backends/platform/atari/osystem_atari.h
+++ b/backends/platform/atari/osystem_atari.h
@@ -24,7 +24,7 @@
#include "backends/modular-backend.h"
-class OSystem_Atari : public ModularMixerBackend, public ModularGraphicsBackend {
+class OSystem_Atari final : public ModularMixerBackend, public ModularGraphicsBackend {
public:
OSystem_Atari();
virtual ~OSystem_Atari();
@@ -43,6 +43,7 @@ public:
Common::HardwareInputSet *getHardwareInputSet() override;
void quit() override;
+ void fatalError() override;
void logMessage(LogMessageType::Type type, const char *message) override;
@@ -59,8 +60,6 @@ private:
int16 _vdi_handle;
int _vdi_width;
int _vdi_height;
-
- void (*_old_procterm)(void) = nullptr;
};
#endif
diff --git a/graphics/blit/blit-atari.cpp b/graphics/blit/blit-atari.cpp
index e4d807a2e12..6e4540b537f 100644
--- a/graphics/blit/blit-atari.cpp
+++ b/graphics/blit/blit-atari.cpp
@@ -20,51 +20,13 @@
*/
#include "graphics/blit.h"
-#include "graphics/surface.h"
-#include "backends/platform/atari/dlmalloc.h"
-#include <cstdlib> // malloc
-#include <cstring> // memcpy, memset
#include <mint/cookie.h>
-#include "backends/graphics/atari/atari-graphics-superblitter.h"
-#include "common/textconsole.h" // error
+#include "backends/graphics/atari/atari-supervidel.h"
+#include "backends/platform/atari/dlmalloc.h" // MALLOC_ALIGNMENT
-// bits 26:0
-#define SV_BLITTER_SRC1 ((volatile long *)0x80010058)
-#define SV_BLITTER_SRC2 ((volatile long *)0x8001005C)
-#define SV_BLITTER_DST ((volatile long *)0x80010060)
-// The amount of bytes that are to be copied in a horizontal line, minus 1
-#define SV_BLITTER_COUNT ((volatile long *)0x80010064)
-// The amount of bytes that are to be added to the line start address after a line has been copied, in order to reach the next one
-#define SV_BLITTER_SRC1_OFFSET ((volatile long *)0x80010068)
-#define SV_BLITTER_SRC2_OFFSET ((volatile long *)0x8001006C)
-#define SV_BLITTER_DST_OFFSET ((volatile long *)0x80010070)
-// bits 11:0 - The amount of horizontal lines to do
-#define SV_BLITTER_MASK_AND_LINES ((volatile long *)0x80010074)
-// bit 0 - busy / start
-// bits 4:1 - blit mode
-#define SV_BLITTER_CONTROL ((volatile long *)0x80010078)
-// bit 0 - empty (read only)
-// bit 1 - full (read only)
-// bits 31:0 - data (write only)
-#define SV_BLITTER_FIFO ((volatile long *)0x80010080)
-
-#ifdef USE_SV_BLITTER
-static bool isSuperBlitterLocked;
-
-static void syncSuperBlitter() {
- // if externally locked, let the owner decide when to sync (unlock)
- if (isSuperBlitterLocked)
- return;
-
- // while FIFO not empty...
- if (superVidelFwVersion >= 9)
- while (!(*SV_BLITTER_FIFO & 1));
- // while busy blitting...
- while (*SV_BLITTER_CONTROL & 1);
-}
-#endif
+static_assert(MALLOC_ALIGNMENT == 16, "MALLOC_ALIGNMENT must be == 16");
#ifdef USE_MOVE16
static inline bool hasMove16() {
@@ -72,80 +34,15 @@ static inline bool hasMove16() {
static bool hasMove16 = Getcookie(C__CPU, &val) == C_FOUND && val >= 40;
return hasMove16;
}
-#endif
-
-void lockSuperBlitter() {
-#ifdef USE_SV_BLITTER
- assert(!isSuperBlitterLocked);
- isSuperBlitterLocked = true;
-#endif
+template<typename T>
+constexpr bool isAligned(T val) {
+ return (reinterpret_cast<uintptr>(val) & (MALLOC_ALIGNMENT - 1)) == 0;
}
-
-void unlockSuperBlitter() {
-#ifdef USE_SV_BLITTER
- assert(isSuperBlitterLocked);
-
- isSuperBlitterLocked = false;
- if (hasSuperVidel())
- syncSuperBlitter();
#endif
-}
-
-// see atari-graphics.cpp
-extern mspace g_mspace;
namespace Graphics {
-constexpr size_t ALIGN = 16; // 16 bytes
-
-// hijack surface overrides here as well as these are tightly related
-// to the blitting routine below
-void Surface::create(int16 width, int16 height, const PixelFormat &f) {
- assert(width >= 0 && height >= 0);
- free();
-
- w = width;
- h = height;
- format = f;
- pitch = w * format.bytesPerPixel;
-
- if (width && height) {
-#ifdef USE_SV_BLITTER
- if (g_mspace) {
- pixels = mspace_calloc(g_mspace, height * pitch, f.bytesPerPixel);
-
- if (!pixels)
- error("Not enough memory to allocate a surface");
-
- assert(pixels >= (void *)0xA0000000);
- } else {
-#else
- {
-#endif
- pixels = ::calloc(height * pitch, f.bytesPerPixel);
- if (!pixels)
- error("Not enough memory to allocate a surface");
-
- assert(((uintptr)pixels & (ALIGN - 1)) == 0);
- }
- }
-}
-
-void Surface::free() {
-#ifdef USE_SV_BLITTER
- if (g_mspace)
- mspace_free(g_mspace, pixels);
- else
-#endif
- if (pixels)
- ::free(pixels);
-
- pixels = nullptr;
- w = h = pitch = 0;
- format = PixelFormat();
-}
-
// Function to blit a rect (version optimized for Atari Falcon with SuperVidel's SuperBlitter)
void copyBlit(byte *dst, const byte *src,
const uint dstPitch, const uint srcPitch,
@@ -156,7 +53,7 @@ void copyBlit(byte *dst, const byte *src,
#ifdef USE_SV_BLITTER
if (((uintptr)src & 0xFF000000) >= 0xA0000000 && ((uintptr)dst & 0xFF000000) >= 0xA0000000) {
- if (superVidelFwVersion >= 9) {
+ if (g_superVidelFwVersion >= 9) {
*SV_BLITTER_FIFO = (long)src; // SV_BLITTER_SRC1
*SV_BLITTER_FIFO = 0x00000000; // SV_BLITTER_SRC2
*SV_BLITTER_FIFO = (long)dst; // SV_BLITTER_DST
@@ -181,12 +78,12 @@ void copyBlit(byte *dst, const byte *src,
*SV_BLITTER_CONTROL = 0x01;
}
- syncSuperBlitter();
+ SyncSuperBlitter();
} else
#endif
if (dstPitch == srcPitch && dstPitch == (w * bytesPerPixel)) {
#ifdef USE_MOVE16
- if (hasMove16() && ((uintptr)src & (ALIGN - 1)) == 0 && ((uintptr)dst & (ALIGN - 1)) == 0) {
+ if (hasMove16() && isAligned(src) && isAligned(dst)) {
__asm__ volatile(
" move.l %2,%%d0\n"
" lsr.l #4,%%d0\n"
@@ -216,8 +113,8 @@ void copyBlit(byte *dst, const byte *src,
" move16 (%0)+,(%1)+\n"
"2:\n"
" dbra %%d0,1b\n"
- // handle also the unlikely case when 'dstPitch'
- // is not divisible by 16 but 'src' and 'dst' are
+ // handle also the case when 'dstPitch' is not
+ // divisible by 16 but 'src' and 'dst' are
"3:\n"
" moveq #0x0f,%%d0\n"
" and.l %2,%%d0\n"
@@ -252,8 +149,7 @@ void copyBlit(byte *dst, const byte *src,
}
} else {
#ifdef USE_MOVE16
- if (hasMove16() && ((uintptr)src & (ALIGN - 1)) == 0 && ((uintptr)dst & (ALIGN - 1)) == 0
- && (srcPitch & (ALIGN - 1)) == 0 && (dstPitch & (ALIGN - 1)) == 0) {
+ if (hasMove16() && isAligned(src) && isAligned(dst) && isAligned(srcPitch) && isAligned(dstPitch)) {
__asm__ volatile(
" move.l %2,%%d0\n"
diff --git a/graphics/surface.cpp b/graphics/surface.cpp
index 06899051d65..540fa4dbf79 100644
--- a/graphics/surface.cpp
+++ b/graphics/surface.cpp
@@ -137,7 +137,7 @@ void Surface::drawEllipse(int x0, int y0, int x1, int y1, uint32 color, bool fil
error("Surface::drawEllipse: bytesPerPixel must be 1, 2, or 4, got %d", format.bytesPerPixel);
}
-// see graphics/blit/blit-atari.cpp
+// see backends/graphics/atari/atari-surface.cpp
#ifndef ATARI
void Surface::create(int16 width, int16 height, const PixelFormat &f) {
assert(width >= 0 && height >= 0);
Commit: 3dc861cf127e3824c48661418757384021f2d1aa
https://github.com/scummvm/scummvm/commit/3dc861cf127e3824c48661418757384021f2d1aa
Author: Miro Kropacek (miro.kropacek at gmail.com)
Date: 2025-06-25T23:50:34+02:00
Commit Message:
GRAPHICS: ATARI: Add specialized keyBlitLogic
Changed paths:
graphics/blit/blit-atari.cpp
graphics/blit/blit.cpp
diff --git a/graphics/blit/blit-atari.cpp b/graphics/blit/blit-atari.cpp
index 6e4540b537f..bfd45a39d4a 100644
--- a/graphics/blit/blit-atari.cpp
+++ b/graphics/blit/blit-atari.cpp
@@ -43,6 +43,55 @@ constexpr bool isAligned(T val) {
namespace Graphics {
+// Function to blit a rect with a transparent color key
+void keyBlitLogicAtari(byte *dst, const byte *src, const uint w, const uint h,
+ const uint srcDelta, const uint dstDelta, const uint32 key) {
+#ifdef USE_SV_BLITTER
+ if (key == 0 && ((uintptr)src & 0xFF000000) >= 0xA0000000 && ((uintptr)dst & 0xFF000000) >= 0xA0000000) {
+ if (g_superVidelFwVersion >= 9) {
+ *SV_BLITTER_FIFO = (long)src; // SV_BLITTER_SRC1
+ *SV_BLITTER_FIFO = (long)src; // SV_BLITTER_SRC2
+ *SV_BLITTER_FIFO = (long)dst; // SV_BLITTER_DST
+ *SV_BLITTER_FIFO = w - 1; // SV_BLITTER_COUNT
+ *SV_BLITTER_FIFO = srcDelta + w; // SV_BLITTER_SRC1_OFFSET
+ *SV_BLITTER_FIFO = srcDelta + w; // SV_BLITTER_SRC2_OFFSET
+ *SV_BLITTER_FIFO = dstDelta + w; // SV_BLITTER_DST_OFFSET
+ *SV_BLITTER_FIFO = h; // SV_BLITTER_MASK_AND_LINES
+ *SV_BLITTER_FIFO = 0x03; // SV_BLITTER_CONTROL
+ } else {
+ // make sure the blitter is idle
+ while (*SV_BLITTER_CONTROL & 1);
+
+ *SV_BLITTER_SRC1 = (long)src;
+ *SV_BLITTER_SRC2 = (long)src;
+ *SV_BLITTER_DST = (long)dst;
+ *SV_BLITTER_COUNT = w - 1;
+ *SV_BLITTER_SRC1_OFFSET = srcDelta + w;
+ *SV_BLITTER_SRC2_OFFSET = srcDelta + w;
+ *SV_BLITTER_DST_OFFSET = dstDelta + w;
+ *SV_BLITTER_MASK_AND_LINES = h;
+ *SV_BLITTER_CONTROL = 0x03;
+ }
+
+ SyncSuperBlitter();
+ } else
+#endif
+ {
+ for (uint y = 0; y < h; ++y) {
+ for (uint x = 0; x < w; ++x) {
+ const uint32 color = *src++;
+ if (color != key)
+ *dst++ = color;
+ else
+ dst++;
+ }
+
+ src += srcDelta;
+ dst += dstDelta;
+ }
+ }
+}
+
// Function to blit a rect (version optimized for Atari Falcon with SuperVidel's SuperBlitter)
void copyBlit(byte *dst, const byte *src,
const uint dstPitch, const uint srcPitch,
diff --git a/graphics/blit/blit.cpp b/graphics/blit/blit.cpp
index 6b73aa4610f..0d42547efc6 100644
--- a/graphics/blit/blit.cpp
+++ b/graphics/blit/blit.cpp
@@ -26,7 +26,10 @@
namespace Graphics {
// see graphics/blit/blit-atari.cpp
-#ifndef ATARI
+#ifdef ATARI
+extern void keyBlitLogicAtari(byte *dst, const byte *src, const uint w, const uint h,
+ const uint srcDelta, const uint dstDelta, const uint32 key);
+#else
// Function to blit a rect
void copyBlit(byte *dst, const byte *src,
const uint dstPitch, const uint srcPitch,
@@ -83,6 +86,14 @@ inline void keyBlitLogic(byte *dst, const byte *src, const uint w, const uint h,
}
}
+#ifdef ATARI
+template<>
+inline void keyBlitLogic<uint8, 1>(byte *dst, const byte *src, const uint w, const uint h,
+ const uint srcDelta, const uint dstDelta, const uint32 key) {
+ keyBlitLogicAtari(dst, src, w, h, srcDelta, dstDelta, key);
+}
+#endif
+
} // End of anonymous namespace
// Function to blit a rect with a transparent color key
Commit: 3dd96ec7c5f24dbcb97b076900f6ecb36f6d36ed
https://github.com/scummvm/scummvm/commit/3dd96ec7c5f24dbcb97b076900f6ecb36f6d36ed
Author: Miro Kropacek (miro.kropacek at gmail.com)
Date: 2025-06-25T23:50:34+02:00
Commit Message:
BACKENDS: ATARI: Use hardware-accelerated cursor blitting
Changed paths:
backends/graphics/atari/atari-cursor.cpp
backends/graphics/atari/atari-cursor.h
backends/graphics/atari/atari-graphics.cpp
backends/graphics/atari/atari-screen.cpp
backends/graphics/atari/atari-supervidel.cpp
backends/graphics/atari/atari-supervidel.h
backends/graphics/atari/atari-surface.cpp
backends/graphics/atari/atari-surface.h
graphics/blit/blit-atari.cpp
diff --git a/backends/graphics/atari/atari-cursor.cpp b/backends/graphics/atari/atari-cursor.cpp
index 7e04cf00341..7069fb49c20 100644
--- a/backends/graphics/atari/atari-cursor.cpp
+++ b/backends/graphics/atari/atari-cursor.cpp
@@ -27,11 +27,31 @@
#include "atari-surface.h"
//#include "backends/platform/atari/atari-debug.h"
-byte Cursor::_palette[256*3] = {};
+bool Cursor::_globalSurfaceChanged;
+
+byte Cursor::_palette[256*3];
+
+const byte *Cursor::_buf;
+int Cursor::_width;
+int Cursor::_height;
+int Cursor::_hotspotX;
+int Cursor::_hotspotY;
+uint32 Cursor::_keycolor;
+
+Graphics::Surface Cursor::_surface;
+Graphics::Surface Cursor::_surfaceMask;
Cursor::Cursor(const AtariGraphicsManager *manager, const Screen *screen)
- : _manager(manager)
- , _parentScreen(screen) {
+ : _manager(manager)
+ , _parentScreen(screen) {
+}
+
+Cursor::~Cursor() {
+ _savedBackground.free();
+ // beware, called multiple times (they have to be destroyed before
+ // AtariSurfaceDeinit() is called)
+ _surface.free();
+ _surfaceMask.free();
}
void Cursor::update() {
@@ -98,7 +118,7 @@ void Cursor::updatePosition(int deltaX, int deltaY) {
_positionChanged = true;
}
-void Cursor::setSurface(const void *buf, int w, int h, int hotspotX, int hotspotY, uint32 keycolor) {
+/* static */ void Cursor::setSurface(const void *buf, int w, int h, int hotspotX, int hotspotY, uint32 keycolor) {
if (w == 0 || h == 0 || buf == nullptr) {
_buf = nullptr;
return;
@@ -111,79 +131,97 @@ void Cursor::setSurface(const void *buf, int w, int h, int hotspotX, int hotspot
_hotspotY = hotspotY;
_keycolor = keycolor;
- _surfaceChanged = true;
+ _globalSurfaceChanged = true;
}
-void Cursor::setPalette(const byte *colors, uint start, uint num) {
+/* static */ void Cursor::setPalette(const byte *colors, uint start, uint num) {
memcpy(&_palette[start * 3], colors, num * 3);
- _surfaceChanged = true;
+ _globalSurfaceChanged = true;
}
void Cursor::convertSurfaceTo(const Graphics::PixelFormat &format) {
- const int cursorWidth = (_srcRect.width() + 15) & (-16);
+ static int rShift, gShift, bShift;
+ static int rMask, gMask, bMask;
+
+ // TODO: maintain a max width
+ const int cursorWidth = g_hasSuperVidel ? _width : ((_srcRect.width() + 15) & (-16));
const int cursorHeight = _height;
const bool isCLUT8 = format.isCLUT8();
if (_surface.w != cursorWidth || _surface.h != cursorHeight || _surface.format != format) {
if (!isCLUT8 && _surface.format != format) {
- _rShift = format.rLoss - format.rShift;
- _gShift = format.gLoss - format.gShift;
- _bShift = format.bLoss - format.bShift;
+ rShift = format.rLoss - format.rShift;
+ gShift = format.gLoss - format.gShift;
+ bShift = format.bLoss - format.bShift;
- _rMask = format.rMax() << format.rShift;
- _gMask = format.gMax() << format.gShift;
- _bMask = format.bMax() << format.bShift;
+ rMask = format.rMax() << format.rShift;
+ gMask = format.gMax() << format.gShift;
+ bMask = format.bMax() << format.bShift;
}
- _surface.create(cursorWidth, cursorHeight, format);
- _surfaceMask.create(_surface.w / 8, _surface.h, format); // 1 bpl
+ _surface.create(cursorWidth, cursorHeight, format); // keep it 8bpl even if bitsPerPixel == 4...
+ _surfaceMask.create(g_hasSuperVidel ? _surface.w : _surface.w / 8, _surface.h, format); // 1 bpl
}
- const int srcRectWidth = _srcRect.width();
+ const int srcRectWidth = g_hasSuperVidel ? _width : _srcRect.width();
- const byte *src = _buf + _srcRect.left;
+ const byte *src = g_hasSuperVidel ? _buf : _buf + _srcRect.left;
byte *dst = (byte *)_surface.getPixels();
- uint16 *dstMask = (uint16 *)_surfaceMask.getPixels();
+ byte *dstMask = (byte *)_surfaceMask.getPixels();
+ uint16 *dstMask16 = (uint16 *)_surfaceMask.getPixels();
const int srcPadding = _width - srcRectWidth;
const int dstPadding = _surface.w - srcRectWidth;
+ uint16 mask16 = 0xffff;
+ uint16 invertedBit = 0x7fff;
+
for (int j = 0; j < cursorHeight; ++j) {
for (int i = 0; i < srcRectWidth; ++i) {
const uint32 color = *src++;
- const uint16 bit = 1 << (15 - (i % 16));
if (color != _keycolor) {
if (!isCLUT8) {
// Convert CLUT8 to RGB332/RGB121 palette
- *dst++ = ((_palette[color*3 + 0] >> _rShift) & _rMask)
- | ((_palette[color*3 + 1] >> _gShift) & _gMask)
- | ((_palette[color*3 + 2] >> _bShift) & _bMask);
+ *dst++ = ((_palette[color*3 + 0] >> rShift) & rMask)
+ | ((_palette[color*3 + 1] >> gShift) & gMask)
+ | ((_palette[color*3 + 2] >> bShift) & bMask);
} else {
*dst++ = color;
}
- // clear bit
- *dstMask &= ~bit;
+ if (g_hasSuperVidel)
+ *dstMask++ = 0xff;
+ else
+ mask16 &= invertedBit;
} else {
*dst++ = 0x00;
- // set bit
- *dstMask |= bit;
+ if (g_hasSuperVidel)
+ *dstMask++ = 0x00;
+ }
+
+ if (!g_hasSuperVidel && invertedBit == 0xfffe) {
+ *dstMask16++ = mask16;
+ mask16 = 0xffff;
}
- if (bit == 0x0001)
- dstMask++;
+ // ror.w #1,invertedBit
+ invertedBit = (invertedBit >> 1) | (invertedBit << (sizeof (invertedBit) * 8 - 1));
}
src += srcPadding;
if (dstPadding) {
+ assert(!g_hasSuperVidel);
+
+ // this is at most 15 pixels
memset(dst, 0x00, dstPadding);
dst += dstPadding;
- *dstMask |= ((1 << dstPadding) - 1);
- dstMask++;
+ *dstMask16++ = mask16;
+ mask16 = 0xffff;
+ invertedBit = 0x7fff;
}
}
}
@@ -220,7 +258,7 @@ void Cursor::saveBackground() {
//atari_debug("Cursor::saveBackground: %d %d %d %d", _savedRect.left, _savedRect.top, _savedRect.width(), _savedRect.height());
- // save native pixels (i.e. bitplanes)
+ // save native bitplanes or pixels, so it must be a Graphics::Surface to copy from
if (_savedBackground.w != _savedRect.width()
|| _savedBackground.h != _savedRect.height()
|| _savedBackground.format != dstSurface.format) {
@@ -236,13 +274,13 @@ void Cursor::draw() {
//atari_debug("Cursor::draw: %d %d %d %d", _dstRect.left, _dstRect.top, _dstRect.width(), _dstRect.height());
- if (_surfaceChanged || _srcRect.width() != _previousSrcRect.width()) {
+ if (_globalSurfaceChanged || _srcRect.width() != _previousSrcRect.width()) {
_previousSrcRect = _srcRect;
convertSurfaceTo(dstSurface.format);
if (!g_hasSuperVidel) {
- // C2P in-place (TODO: merge with convertSurfaceTo)
+ // C2P in-place
AtariSurface surf(dstBitsPerPixel);
surf.w = _surface.w;
surf.h = _surface.h;
@@ -255,14 +293,17 @@ void Cursor::draw() {
0, 0,
Common::Rect(_surface.w, _surface.h));
}
+
+ _globalSurfaceChanged = false;
}
- // don't use _srcRect.right as 'x2' as this must be aligned first
- // (_surface.w is recalculated thanks to convertSurfaceTo())
dstSurface.drawMaskedSprite(
_surface, _surfaceMask,
_dstRect.left + _xOffset, _dstRect.top,
- Common::Rect(0, _srcRect.top, _surface.w, _srcRect.bottom));
+ g_hasSuperVidel
+ ? _srcRect
+ // TODO: _srcRect and add clipping to AtariSurface::drawMaskedSprite
+ : Common::Rect(0, _srcRect.top, _surface.w, _srcRect.bottom));
_visibilityChanged = _positionChanged = _surfaceChanged = false;
}
diff --git a/backends/graphics/atari/atari-cursor.h b/backends/graphics/atari/atari-cursor.h
index 3bbb56b4ecc..7f07940beb8 100644
--- a/backends/graphics/atari/atari-cursor.h
+++ b/backends/graphics/atari/atari-cursor.h
@@ -23,7 +23,6 @@
#define BACKENDS_GRAPHICS_ATARI_CURSOR_H
#include "graphics/surface.h"
-//#include "backends/platform/atari/atari-debug.h"
class AtariGraphicsManager;
struct Screen;
@@ -36,6 +35,7 @@ struct Screen;
struct Cursor {
Cursor(const AtariGraphicsManager *manager, const Screen *screen);
+ ~Cursor();
void reset(const Graphics::Surface *boundingSurf, int xOffset) {
_boundingSurf = boundingSurf;
@@ -65,6 +65,9 @@ struct Cursor {
return last;
}
+ void setSurfaceChanged() {
+ _surfaceChanged = true;
+ }
// position
Common::Point getPosition() const {
@@ -84,9 +87,8 @@ struct Cursor {
void updatePosition(int deltaX, int deltaY);
// surface
- void setSurface(const void *buf, int w, int h, int hotspotX, int hotspotY, uint32 keycolor);
- void setPalette(const byte *colors, uint start, uint num);
- void convertSurfaceTo(const Graphics::PixelFormat &format);
+ static void setSurface(const void *buf, int w, int h, int hotspotX, int hotspotY, uint32 keycolor);
+ static void setPalette(const byte *colors, uint start, uint num);
bool isVisible() const {
return !_outOfScreen && _visible;
@@ -100,17 +102,16 @@ struct Cursor {
void draw();
private:
+ void convertSurfaceTo(const Graphics::PixelFormat &format);
void restoreBackground();
- static byte _palette[256*3];
-
const AtariGraphicsManager *_manager;
const Screen *_parentScreen;
const Graphics::Surface *_boundingSurf = nullptr;
int _xOffset = 0;
- bool _positionChanged = true;
- bool _surfaceChanged = true;
+ bool _positionChanged = false;
+ bool _surfaceChanged = false;
bool _visibilityChanged = false;
bool _visible = false;
@@ -126,21 +127,19 @@ private:
Common::Rect _alignedDstRect;
// related to 'surface'
- const byte *_buf = nullptr;
- int _width;
- int _height;
- int _hotspotX;
- int _hotspotY;
- uint32 _keycolor;
-
- // TODO: make all surface-related variables and functions static, similar to _palette/
- // but there's a catch: we still need _surfaceChanged instantiated and convertTo may
- // be called when clipping changes. Perhaps Cursor should be a singleton and those
- // flags moved to Screen...
- Graphics::Surface _surface;
- Graphics::Surface _surfaceMask;
- int _rShift, _gShift, _bShift;
- int _rMask, _gMask, _bMask;
+ static bool _globalSurfaceChanged;
+
+ static byte _palette[256*3];
+
+ static const byte *_buf;
+ static int _width;
+ static int _height;
+ static int _hotspotX;
+ static int _hotspotY;
+ static uint32 _keycolor;
+
+ static Graphics::Surface _surface;
+ static Graphics::Surface _surfaceMask;
};
#endif // BACKENDS_GRAPHICS_ATARI_CURSOR_H
diff --git a/backends/graphics/atari/atari-graphics.cpp b/backends/graphics/atari/atari-graphics.cpp
index bdabe154b56..e51d89f8aff 100644
--- a/backends/graphics/atari/atari-graphics.cpp
+++ b/backends/graphics/atari/atari-graphics.cpp
@@ -756,6 +756,8 @@ void AtariGraphicsManager::showOverlay(bool inGUI) {
_pendingScreenChanges.setScreenSurface(_screen[kOverlayBuffer]->surf.get());
+ // cursor is reset before calling showOverlay()
+
// do not cache dirtyRects and saved cursor rect
_screen[kOverlayBuffer]->reset(
getOverlayWidth(), getOverlayHeight(),
@@ -789,6 +791,9 @@ void AtariGraphicsManager::hideOverlay() {
_pendingScreenChanges.setScreenSurface(
_screen[_currentState.mode == kTripleBuffering ? kBackBuffer2 : kFrontBuffer]->surf.get());
+ // reset cursor as its srcSurface has been just changed so wait for cursor surface to be updated
+ Cursor::setSurface(nullptr, 0, 0, 0, 0, 0);
+
_overlayState = kOverlayHidden;
if (!_pendingScreenChanges.empty()) {
@@ -984,20 +989,24 @@ void AtariGraphicsManager::setMouseCursor(const void *buf, uint w, uint h, int h
if (format)
assert(*format == PIXELFORMAT_CLUT8);
- _screen[kOverlayBuffer]->cursor.setSurface(buf, (int)w, (int)h, hotspotX, hotspotY, keycolor);
- _screen[kFrontBuffer]->cursor.setSurface(buf, (int)w, (int)h, hotspotX, hotspotY, keycolor);
+ Cursor::setSurface(buf, (int)w, (int)h, hotspotX, hotspotY, keycolor);
+
+ _screen[kOverlayBuffer]->cursor.setSurfaceChanged();
+ _screen[kFrontBuffer]->cursor.setSurfaceChanged();
if (_currentState.mode == kTripleBuffering) {
- _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[kBackBuffer1]->cursor.setSurfaceChanged();
+ _screen[kBackBuffer2]->cursor.setSurfaceChanged();
}
}
void AtariGraphicsManager::setCursorPalette(const byte *colors, uint start, uint num) {
atari_debug("setCursorPalette: %d, %d", start, num);
+ Cursor::setPalette(colors, start, num);
+
// cursor palette is supported only in the overlay
- _screen[kOverlayBuffer]->cursor.setPalette(colors, start, num);
+ _screen[kOverlayBuffer]->cursor.setSurfaceChanged();
}
void AtariGraphicsManager::updateMousePosition(int deltaX, int deltaY) {
@@ -1137,9 +1146,6 @@ bool AtariGraphicsManager::updateScreenInternal(Screen *dstScreen, const Graphic
cursor.saveBackground();
}
- // unlock here because cursor.draw() is a software blit
- UnlockSuperBlitter();
-
if (drawCursor) {
cursor.draw();
updated |= true;
@@ -1147,6 +1153,8 @@ bool AtariGraphicsManager::updateScreenInternal(Screen *dstScreen, const Graphic
dstScreen->clearDirtyRects();
+ UnlockSuperBlitter();
+
return updated;
}
diff --git a/backends/graphics/atari/atari-screen.cpp b/backends/graphics/atari/atari-screen.cpp
index 06801215386..b180bddb3f5 100644
--- a/backends/graphics/atari/atari-screen.cpp
+++ b/backends/graphics/atari/atari-screen.cpp
@@ -35,6 +35,7 @@ Screen::Screen(AtariGraphicsManager *manager, int width, int height, const Graph
const int bitsPerPixel = _manager->getBitsPerPixel(format);
+#ifdef USE_SUPERVIDEL
if (g_hasSuperVidel) {
surf.reset(new SuperVidelSurface(
width + 2 * MAX_HZ_SHAKE,
@@ -42,7 +43,9 @@ Screen::Screen(AtariGraphicsManager *manager, int width, int height, const Graph
format,
bitsPerPixel));
_offsettedSurf.reset(new SuperVidelSurface(bitsPerPixel));
- } else {
+ } else
+#endif
+ {
surf.reset(new AtariSurface(
width + (_manager->_tt ? 0 : 2 * MAX_HZ_SHAKE),
height + 2 * MAX_V_SHAKE,
diff --git a/backends/graphics/atari/atari-supervidel.cpp b/backends/graphics/atari/atari-supervidel.cpp
index d9bfef5ac98..e4ca55c0e19 100644
--- a/backends/graphics/atari/atari-supervidel.cpp
+++ b/backends/graphics/atari/atari-supervidel.cpp
@@ -29,6 +29,7 @@ bool g_hasSuperVidel = false;
#ifdef USE_SV_BLITTER
int g_superVidelFwVersion = 0;
+const byte *g_blitMask = nullptr;
static bool isSuperBlitterLocked;
diff --git a/backends/graphics/atari/atari-supervidel.h b/backends/graphics/atari/atari-supervidel.h
index c2725c4d718..90aa9e0f459 100644
--- a/backends/graphics/atari/atari-supervidel.h
+++ b/backends/graphics/atari/atari-supervidel.h
@@ -22,6 +22,8 @@
#ifndef BACKENDS_GRAPHICS_ATARI_SUPERVIDEL_H
#define BACKENDS_GRAPHICS_ATARI_SUPERVIDEL_H
+#include "common/scummsys.h"
+
#ifdef USE_SUPERVIDEL
// bits 26:0
@@ -48,6 +50,7 @@
#ifdef USE_SV_BLITTER
extern int g_superVidelFwVersion;
+extern const byte *g_blitMask;
void SyncSuperBlitter();
#endif // USE_SV_BLITTER
diff --git a/backends/graphics/atari/atari-surface.cpp b/backends/graphics/atari/atari-surface.cpp
index efa9dcc9c0e..cb52f21d153 100644
--- a/backends/graphics/atari/atari-surface.cpp
+++ b/backends/graphics/atari/atari-surface.cpp
@@ -233,51 +233,6 @@ void AtariSurface::drawMaskedSprite(
}
}
-void SuperVidelSurface::drawMaskedSprite(
- const Graphics::Surface &srcSurface, const Graphics::Surface &srcMask,
- int destX, int destY,
- const Common::Rect &subRect) {
- assert(subRect.width() % 16 == 0);
- assert(subRect.width() == srcSurface.w);
- assert(srcSurface.format == format);
- assert(_bitsPerPixel == 8);
-
- const byte *src = (const byte *)srcSurface.getBasePtr(subRect.left, subRect.top);
- const uint16 *mask = (const uint16 *)srcMask.getBasePtr(subRect.left, subRect.top);
- byte *dst = (byte *)getBasePtr(destX, destY);
-
- const int height = subRect.height();
- const int width = subRect.width();
- const int dstOffset = pitch - width;
-
- for (int j = 0; j < height; ++j) {
- for (int i = 0; i < width; i += 16, mask++) {
- const uint16 m = *mask;
-
- if (m == 0xFFFF) {
- // all 16 pixels transparent
- src += 16;
- dst += 16;
- continue;
- }
-
- for (int k = 0; k < 16; ++k) {
- const uint16 bit = 1 << (15 - k);
-
- if (m & bit) {
- // transparent
- src++;
- dst++;
- } else {
- *dst++ = *src++;
- }
- }
- }
-
- dst += dstOffset;
- }
-}
-
///////////////////////////////////////////////////////////////////////////////
#ifdef USE_SUPERVIDEL
diff --git a/backends/graphics/atari/atari-surface.h b/backends/graphics/atari/atari-surface.h
index 62bcca36883..82198a29223 100644
--- a/backends/graphics/atari/atari-surface.h
+++ b/backends/graphics/atari/atari-surface.h
@@ -24,6 +24,8 @@
#include "graphics/managed_surface.h"
+#include "backends/graphics/atari/atari-supervidel.h"
+
class AtariSurface : public Graphics::ManagedSurface {
public:
AtariSurface(int bitsPerPixel);
@@ -56,6 +58,7 @@ protected:
int _bitsPerPixel = 0;
};
+#ifdef USE_SUPERVIDEL
class SuperVidelSurface final : public AtariSurface {
public:
SuperVidelSurface(int bitsPerPixel)
@@ -75,8 +78,17 @@ public:
void drawMaskedSprite(const Graphics::Surface &srcSurface, const Graphics::Surface &srcMask,
int destX, int destY,
- const Common::Rect &subRect) override;
+ const Common::Rect &subRect) override {
+#ifdef USE_SV_BLITTER
+ g_blitMask = (const byte *)srcMask.getBasePtr(subRect.left, subRect.top);
+#endif
+ copyRectToSurfaceWithKey(srcSurface, destX, destY, subRect, 0);
+#ifdef USE_SV_BLITTER
+ g_blitMask = nullptr;
+#endif
+ }
};
+#endif
void AtariSurfaceInit();
void AtariSurfaceDeinit();
diff --git a/graphics/blit/blit-atari.cpp b/graphics/blit/blit-atari.cpp
index bfd45a39d4a..15e266990a7 100644
--- a/graphics/blit/blit-atari.cpp
+++ b/graphics/blit/blit-atari.cpp
@@ -50,7 +50,7 @@ void keyBlitLogicAtari(byte *dst, const byte *src, const uint w, const uint h,
if (key == 0 && ((uintptr)src & 0xFF000000) >= 0xA0000000 && ((uintptr)dst & 0xFF000000) >= 0xA0000000) {
if (g_superVidelFwVersion >= 9) {
*SV_BLITTER_FIFO = (long)src; // SV_BLITTER_SRC1
- *SV_BLITTER_FIFO = (long)src; // SV_BLITTER_SRC2
+ *SV_BLITTER_FIFO = (long)(g_blitMask ? g_blitMask : src); // SV_BLITTER_SRC2
*SV_BLITTER_FIFO = (long)dst; // SV_BLITTER_DST
*SV_BLITTER_FIFO = w - 1; // SV_BLITTER_COUNT
*SV_BLITTER_FIFO = srcDelta + w; // SV_BLITTER_SRC1_OFFSET
@@ -63,7 +63,7 @@ void keyBlitLogicAtari(byte *dst, const byte *src, const uint w, const uint h,
while (*SV_BLITTER_CONTROL & 1);
*SV_BLITTER_SRC1 = (long)src;
- *SV_BLITTER_SRC2 = (long)src;
+ *SV_BLITTER_SRC2 = (long)(g_blitMask ? g_blitMask : src);
*SV_BLITTER_DST = (long)dst;
*SV_BLITTER_COUNT = w - 1;
*SV_BLITTER_SRC1_OFFSET = srcDelta + w;
Commit: fbbecd55f38fdc1a6c839ebcde37b0514662fc98
https://github.com/scummvm/scummvm/commit/fbbecd55f38fdc1a6c839ebcde37b0514662fc98
Author: Miro Kropacek (miro.kropacek at gmail.com)
Date: 2025-06-25T23:50:34+02:00
Commit Message:
GRAPHICS: Make Graphics::PixelFormat::createFormatCLUT8 constexpr
Changed paths:
graphics/pixelformat.h
diff --git a/graphics/pixelformat.h b/graphics/pixelformat.h
index e2609e84b9f..6b1b12fe040 100644
--- a/graphics/pixelformat.h
+++ b/graphics/pixelformat.h
@@ -181,7 +181,7 @@ struct PixelFormat {
}
/** Define a CLUT8 pixel format. */
- static inline PixelFormat createFormatCLUT8() {
+ static constexpr inline PixelFormat createFormatCLUT8() {
return PixelFormat(1, 0, 0, 0, 0, 0, 0, 0, 0);
}
Commit: 0520570a7b6f31ab419dcbe5a8cd5094a56c97d5
https://github.com/scummvm/scummvm/commit/0520570a7b6f31ab419dcbe5a8cd5094a56c97d5
Author: Miro Kropacek (miro.kropacek at gmail.com)
Date: 2025-06-25T23:50:35+02:00
Commit Message:
BACKENDS: ATARI: Move getBitsPerPixel from AtariGraphicsManager to AtariSurface
Changed paths:
backends/graphics/atari/atari-cursor.cpp
backends/graphics/atari/atari-graphics.cpp
backends/graphics/atari/atari-graphics.h
backends/graphics/atari/atari-screen.cpp
backends/graphics/atari/atari-surface.cpp
backends/graphics/atari/atari-surface.h
diff --git a/backends/graphics/atari/atari-cursor.cpp b/backends/graphics/atari/atari-cursor.cpp
index 7069fb49c20..6b7b3e02983 100644
--- a/backends/graphics/atari/atari-cursor.cpp
+++ b/backends/graphics/atari/atari-cursor.cpp
@@ -78,7 +78,7 @@ void Cursor::update() {
assert(_srcRect.width() == _dstRect.width());
assert(_srcRect.height() == _dstRect.height());
- const int dstBitsPerPixel = _manager->getBitsPerPixel(_parentScreen->offsettedSurf->format);
+ const int dstBitsPerPixel = _parentScreen->offsettedSurf->getBitsPerPixel();
// non-direct rendering never uses 4bpp but maybe in the future ...
_savedRect = _manager->alignRect(
@@ -269,8 +269,8 @@ void Cursor::saveBackground() {
}
void Cursor::draw() {
- auto &dstSurface = *_parentScreen->offsettedSurf;
- const int dstBitsPerPixel = _manager->getBitsPerPixel(dstSurface.format);
+ AtariSurface &dstSurface = *_parentScreen->offsettedSurf;
+ const int dstBitsPerPixel = dstSurface.getBitsPerPixel();
//atari_debug("Cursor::draw: %d %d %d %d", _dstRect.left, _dstRect.top, _dstRect.width(), _dstRect.height());
@@ -281,7 +281,7 @@ void Cursor::draw() {
if (!g_hasSuperVidel) {
// C2P in-place
- AtariSurface surf(dstBitsPerPixel);
+ AtariSurface surf;
surf.w = _surface.w;
surf.h = _surface.h;
surf.pitch = _surface.pitch * dstBitsPerPixel / 8; // 4bpp is not byte per pixel anymore
diff --git a/backends/graphics/atari/atari-graphics.cpp b/backends/graphics/atari/atari-graphics.cpp
index e51d89f8aff..fc2bbfa49af 100644
--- a/backends/graphics/atari/atari-graphics.cpp
+++ b/backends/graphics/atari/atari-graphics.cpp
@@ -41,10 +41,6 @@
#define SCREEN_ACTIVE
-static const Graphics::PixelFormat PIXELFORMAT_CLUT8 = Graphics::PixelFormat::createFormatCLUT8();
-static const Graphics::PixelFormat PIXELFORMAT_RGB332 = Graphics::PixelFormat(1, 3, 3, 2, 0, 5, 2, 0, 0);
-static const Graphics::PixelFormat PIXELFORMAT_RGB121 = Graphics::PixelFormat(1, 1, 2, 1, 0, 3, 1, 0, 0);
-
static void shrinkVidelVisibleArea() {
// Active VGA screen area consists of 960 half-lines, i.e. 480 raster lines.
// In case of 320x240, the number is still 480 but data is fetched
@@ -1076,10 +1072,6 @@ Common::Keymap *AtariGraphicsManager::getKeymap() const {
return keymap;
}
-int AtariGraphicsManager::getBitsPerPixel(const Graphics::PixelFormat &format) const {
- return format == PIXELFORMAT_RGB121 ? 4 : 8;
-}
-
void AtariGraphicsManager::allocateSurfaces() {
for (int i : { kFrontBuffer, kBackBuffer1, kBackBuffer2 }) {
_screen[i] = new Screen(this, getMaximumScreenWidth(), getMaximumScreenHeight(), PIXELFORMAT_CLUT8, &_palette);
diff --git a/backends/graphics/atari/atari-graphics.h b/backends/graphics/atari/atari-graphics.h
index 449bbfe5c89..6406e0381c2 100644
--- a/backends/graphics/atari/atari-graphics.h
+++ b/backends/graphics/atari/atari-graphics.h
@@ -123,7 +123,6 @@ private:
kActionToggleAspectRatioCorrection = 100,
};
- int getBitsPerPixel(const Graphics::PixelFormat &format) const;
void allocateSurfaces();
void freeSurfaces();
diff --git a/backends/graphics/atari/atari-screen.cpp b/backends/graphics/atari/atari-screen.cpp
index b180bddb3f5..1d2826fa626 100644
--- a/backends/graphics/atari/atari-screen.cpp
+++ b/backends/graphics/atari/atari-screen.cpp
@@ -25,7 +25,6 @@
#include "atari-graphics.h"
#include "atari-supervidel.h"
-#include "atari-surface.h"
#include "backends/platform/atari/atari-debug.h"
Screen::Screen(AtariGraphicsManager *manager, int width, int height, const Graphics::PixelFormat &format, const Palette *palette_)
@@ -33,25 +32,21 @@ Screen::Screen(AtariGraphicsManager *manager, int width, int height, const Graph
, cursor(manager, this)
, palette(palette_) {
- const int bitsPerPixel = _manager->getBitsPerPixel(format);
-
#ifdef USE_SUPERVIDEL
if (g_hasSuperVidel) {
surf.reset(new SuperVidelSurface(
width + 2 * MAX_HZ_SHAKE,
height + 2 * MAX_V_SHAKE,
- format,
- bitsPerPixel));
- _offsettedSurf.reset(new SuperVidelSurface(bitsPerPixel));
+ format));
+ _offsettedSurf.reset(new SuperVidelSurface());
} else
#endif
{
surf.reset(new AtariSurface(
width + (_manager->_tt ? 0 : 2 * MAX_HZ_SHAKE),
height + 2 * MAX_V_SHAKE,
- format,
- bitsPerPixel));
- _offsettedSurf.reset(new AtariSurface(bitsPerPixel));
+ format));
+ _offsettedSurf.reset(new AtariSurface());
}
_offsettedSurf->create(
@@ -73,7 +68,7 @@ void Screen::reset(int width, int height, const Graphics::Surface &boundingSurf,
rez = -1;
mode = -1;
- const int bitsPerPixel = _manager->getBitsPerPixel(surf->format);
+ const int bitsPerPixel = surf->getBitsPerPixel();
// erase old screen
_offsettedSurf->fillRect(_offsettedSurf->getBounds(), 0);
diff --git a/backends/graphics/atari/atari-surface.cpp b/backends/graphics/atari/atari-surface.cpp
index cb52f21d153..e204a237698 100644
--- a/backends/graphics/atari/atari-surface.cpp
+++ b/backends/graphics/atari/atari-surface.cpp
@@ -133,12 +133,7 @@ void Surface::free() {
///////////////////////////////////////////////////////////////////////////////
-AtariSurface::AtariSurface(int bitsPerPixel)
- : _bitsPerPixel(bitsPerPixel) {
-}
-
-AtariSurface::AtariSurface(int16 width, int16 height, const Graphics::PixelFormat &pixelFormat, int bitsPerPixel)
- : _bitsPerPixel(bitsPerPixel) {
+AtariSurface::AtariSurface(int16 width, int16 height, const Graphics::PixelFormat &pixelFormat) {
create(width, height, pixelFormat);
}
@@ -150,7 +145,7 @@ void AtariSurface::create(int16 width, int16 height, const Graphics::PixelFormat
MemoryPool *oldPool = s_currentPool;
s_currentPool = &s_videoRamPool;
- Graphics::ManagedSurface::create(width * _bitsPerPixel / 8, height, pixelFormat);
+ Graphics::ManagedSurface::create(width * (format == PIXELFORMAT_RGB121 ? 4 : 8) / 8, height, pixelFormat);
w = width;
s_currentPool = oldPool;
@@ -176,9 +171,9 @@ void AtariSurface::copyRectToSurface(const void *buffer, int srcPitch, int destX
const byte *pChunky = (const byte *)buffer;
const byte *pChunkyEnd = pChunky + (height - 1) * srcPitch + width * format.bytesPerPixel;
- byte *pScreen = (byte *)getPixels() + destY * pitch + destX * _bitsPerPixel/8;
+ byte *pScreen = (byte *)getPixels() + destY * pitch + destX * getBitsPerPixel()/8;
- if (_bitsPerPixel == 8) {
+ if (getBitsPerPixel() == 8) {
if (srcPitch == width) {
if (srcPitch == pitch) {
asm_c2p1x1_8(pChunky, pChunkyEnd, pScreen);
@@ -218,13 +213,13 @@ void AtariSurface::drawMaskedSprite(
assert(subRect.width() == srcSurface.w);
assert(srcSurface.format == format);
- if (_bitsPerPixel == 4) {
+ if (getBitsPerPixel() == 4) {
asm_draw_4bpl_sprite(
(uint16 *)getPixels(), (const uint16 *)srcSurface.getBasePtr(subRect.left, subRect.top),
(const uint16 *)srcMask.getBasePtr(subRect.left, subRect.top),
destX, destY,
pitch, subRect.width(), subRect.height());
- } else if (_bitsPerPixel == 8) {
+ } else if (getBitsPerPixel() == 8) {
asm_draw_8bpl_sprite(
(uint16 *)getPixels(), (const uint16 *)srcSurface.getBasePtr(subRect.left, subRect.top),
(const uint16 *)srcMask.getBasePtr(subRect.left, subRect.top),
diff --git a/backends/graphics/atari/atari-surface.h b/backends/graphics/atari/atari-surface.h
index 82198a29223..20962fcbed1 100644
--- a/backends/graphics/atari/atari-surface.h
+++ b/backends/graphics/atari/atari-surface.h
@@ -26,10 +26,14 @@
#include "backends/graphics/atari/atari-supervidel.h"
+constexpr Graphics::PixelFormat PIXELFORMAT_CLUT8 = Graphics::PixelFormat::createFormatCLUT8();
+constexpr Graphics::PixelFormat PIXELFORMAT_RGB332 = Graphics::PixelFormat(1, 3, 3, 2, 0, 5, 2, 0, 0);
+constexpr Graphics::PixelFormat PIXELFORMAT_RGB121 = Graphics::PixelFormat(1, 1, 2, 1, 0, 3, 1, 0, 0);
+
class AtariSurface : public Graphics::ManagedSurface {
public:
- AtariSurface(int bitsPerPixel);
- AtariSurface(int16 width, int16 height, const Graphics::PixelFormat &pixelFormat, int bitsPerPixel);
+ AtariSurface() = default;
+ AtariSurface(int16 width, int16 height, const Graphics::PixelFormat &pixelFormat);
~AtariSurface() override;
using Graphics::ManagedSurface::create;
@@ -54,18 +58,17 @@ public:
int destX, int destY,
const Common::Rect &subRect);
-protected:
- int _bitsPerPixel = 0;
+ int getBitsPerPixel() const {
+ return format == PIXELFORMAT_RGB121 ? 4 : 8;
+ }
};
#ifdef USE_SUPERVIDEL
class SuperVidelSurface final : public AtariSurface {
public:
- SuperVidelSurface(int bitsPerPixel)
- : AtariSurface(bitsPerPixel) {
- }
- SuperVidelSurface(int16 width, int16 height, const Graphics::PixelFormat &pixelFormat, int bitsPerPixel)
- : AtariSurface(width, height, pixelFormat, bitsPerPixel) {
+ SuperVidelSurface() = default;
+ SuperVidelSurface(int16 width, int16 height, const Graphics::PixelFormat &pixelFormat)
+ : AtariSurface(width, height, pixelFormat) {
}
//using Graphics::ManagedSurface::copyRectToSurface;
Commit: ee437e2a4282e8db1bce37846dac869cb4ee3485
https://github.com/scummvm/scummvm/commit/ee437e2a4282e8db1bce37846dac869cb4ee3485
Author: Miro Kropacek (miro.kropacek at gmail.com)
Date: 2025-06-25T23:50:35+02:00
Commit Message:
BACKENDS: ATARI: Move alignRect from AtariGraphicsManager to AtariSurface
And make it static.
Changed paths:
backends/graphics/atari/atari-cursor.cpp
backends/graphics/atari/atari-graphics.cpp
backends/graphics/atari/atari-graphics.h
backends/graphics/atari/atari-screen.cpp
backends/graphics/atari/atari-surface.h
diff --git a/backends/graphics/atari/atari-cursor.cpp b/backends/graphics/atari/atari-cursor.cpp
index 6b7b3e02983..5ecbe6c1214 100644
--- a/backends/graphics/atari/atari-cursor.cpp
+++ b/backends/graphics/atari/atari-cursor.cpp
@@ -81,14 +81,14 @@ void Cursor::update() {
const int dstBitsPerPixel = _parentScreen->offsettedSurf->getBitsPerPixel();
// non-direct rendering never uses 4bpp but maybe in the future ...
- _savedRect = _manager->alignRect(
+ _savedRect = AtariSurface::alignRect(
_dstRect.left * dstBitsPerPixel / 8, // fake 4bpp by 8bpp's x/2
_dstRect.top,
_dstRect.right * dstBitsPerPixel / 8, // fake 4bpp by 8bpp's width/2
_dstRect.bottom);
// this is used only in flushBackground()
- _alignedDstRect = _manager->alignRect(
+ _alignedDstRect = AtariSurface::alignRect(
_dstRect.left + _xOffset,
_dstRect.top,
_dstRect.right + _xOffset,
diff --git a/backends/graphics/atari/atari-graphics.cpp b/backends/graphics/atari/atari-graphics.cpp
index fc2bbfa49af..a0a992f19cb 100644
--- a/backends/graphics/atari/atari-graphics.cpp
+++ b/backends/graphics/atari/atari-graphics.cpp
@@ -1152,7 +1152,7 @@ bool AtariGraphicsManager::updateScreenInternal(Screen *dstScreen, const Graphic
void AtariGraphicsManager::copyRectToScreenInternal(AtariSurface &dstSurface,
const byte *buf, int pitch, int x, int y, int w, int h) {
- const Common::Rect rect = alignRect(x, y, x + w, y + h);
+ const Common::Rect rect = AtariSurface::alignRect(x, y, x + w, y + h);
// TODO: mask the unaligned parts and copy the rest
buf -= (x - rect.left); // HACK: this assumes pointer to a complete buffer
diff --git a/backends/graphics/atari/atari-graphics.h b/backends/graphics/atari/atari-graphics.h
index 6406e0381c2..b517e446d93 100644
--- a/backends/graphics/atari/atari-graphics.h
+++ b/backends/graphics/atari/atari-graphics.h
@@ -156,19 +156,6 @@ private:
Graphics::Surface *lockOverlay();
- Common::Rect alignRect(int x1, int y1, int x2, int y2) const {
- // make non-virtual for performance reasons
- return g_hasSuperVidel
- ? Common::Rect(x1, y1, x2, y2)
- : Common::Rect(x1 & (-16), y1, (x2 + 15) & (-16), y2);
- }
- Common::Rect alignRect(const Common::Rect &rect) const {
- // make non-virtual for performance reasons
- return g_hasSuperVidel
- ? rect
- : Common::Rect(rect.left & (-16), rect.top, (rect.right + 15) & (-16), rect.bottom);
- }
-
bool _vgaMonitor = true;
bool _tt = false;
diff --git a/backends/graphics/atari/atari-screen.cpp b/backends/graphics/atari/atari-screen.cpp
index 1d2826fa626..49749a4f201 100644
--- a/backends/graphics/atari/atari-screen.cpp
+++ b/backends/graphics/atari/atari-screen.cpp
@@ -147,13 +147,13 @@ void Screen::addDirtyRect(const Graphics::Surface &srcSurface, int x, int y, int
dirtyRects.clear();
// don't use x/y/w/h, the 2nd expression may be true
// also, it's ok if e.g. w = 630 gets aligned to w = 640, nothing is drawn in 630~639
- dirtyRects.insert(_manager->alignRect(_xOffset, 0, _xOffset + srcSurface.w, srcSurface.h));
+ dirtyRects.insert(AtariSurface::alignRect(_xOffset, 0, _xOffset + srcSurface.w, srcSurface.h));
cursor.reset(&srcSurface, _xOffset);
fullRedraw = true;
} else {
- const Common::Rect alignedRect = _manager->alignRect(x + _xOffset, y, x + _xOffset + w, y + h);
+ const Common::Rect alignedRect = AtariSurface::alignRect(x + _xOffset, y, x + _xOffset + w, y + h);
dirtyRects.insert(alignedRect);
diff --git a/backends/graphics/atari/atari-surface.h b/backends/graphics/atari/atari-surface.h
index 20962fcbed1..7bd5df84541 100644
--- a/backends/graphics/atari/atari-surface.h
+++ b/backends/graphics/atari/atari-surface.h
@@ -61,6 +61,19 @@ public:
int getBitsPerPixel() const {
return format == PIXELFORMAT_RGB121 ? 4 : 8;
}
+
+ static Common::Rect alignRect(int x1, int y1, int x2, int y2) {
+ // make non-virtual for performance reasons
+ return g_hasSuperVidel
+ ? Common::Rect(x1, y1, x2, y2)
+ : Common::Rect(x1 & (-16), y1, (x2 + 15) & (-16), y2);
+ }
+ static Common::Rect alignRect(const Common::Rect &rect) {
+ // make non-virtual for performance reasons
+ return g_hasSuperVidel
+ ? rect
+ : Common::Rect(rect.left & (-16), rect.top, (rect.right + 15) & (-16), rect.bottom);
+ }
};
#ifdef USE_SUPERVIDEL
Commit: f27f045aac0bbd267d4d26605cb8d59da555e834
https://github.com/scummvm/scummvm/commit/f27f045aac0bbd267d4d26605cb8d59da555e834
Author: Miro Kropacek (miro.kropacek at gmail.com)
Date: 2025-06-25T23:50:35+02:00
Commit Message:
BACKENDS: ATARI: Remove references to AtariGraphicsManager from Screen and Cursor
Changed paths:
backends/graphics/atari/atari-cursor.cpp
backends/graphics/atari/atari-cursor.h
backends/graphics/atari/atari-graphics.cpp
backends/graphics/atari/atari-graphics.h
backends/graphics/atari/atari-pendingscreenchanges.h
backends/graphics/atari/atari-screen.cpp
backends/graphics/atari/atari-screen.h
diff --git a/backends/graphics/atari/atari-cursor.cpp b/backends/graphics/atari/atari-cursor.cpp
index 5ecbe6c1214..b271dad7fa5 100644
--- a/backends/graphics/atari/atari-cursor.cpp
+++ b/backends/graphics/atari/atari-cursor.cpp
@@ -21,7 +21,6 @@
#include "atari-cursor.h"
-#include "atari-graphics.h"
#include "atari-screen.h"
#include "atari-supervidel.h"
#include "atari-surface.h"
@@ -41,9 +40,8 @@ uint32 Cursor::_keycolor;
Graphics::Surface Cursor::_surface;
Graphics::Surface Cursor::_surfaceMask;
-Cursor::Cursor(const AtariGraphicsManager *manager, const Screen *screen)
- : _manager(manager)
- , _parentScreen(screen) {
+Cursor::Cursor(const Screen *screen)
+ : _parentScreen(screen) {
}
Cursor::~Cursor() {
@@ -87,7 +85,8 @@ void Cursor::update() {
_dstRect.right * dstBitsPerPixel / 8, // fake 4bpp by 8bpp's width/2
_dstRect.bottom);
- // this is used only in flushBackground()
+ // this is used only in flushBackground() for comparison with rects
+ // passed by Screen::addDirtyRect (aligned and shifted by the same offset)
_alignedDstRect = AtariSurface::alignRect(
_dstRect.left + _xOffset,
_dstRect.top,
diff --git a/backends/graphics/atari/atari-cursor.h b/backends/graphics/atari/atari-cursor.h
index 7f07940beb8..46c4dff8702 100644
--- a/backends/graphics/atari/atari-cursor.h
+++ b/backends/graphics/atari/atari-cursor.h
@@ -24,7 +24,6 @@
#include "graphics/surface.h"
-class AtariGraphicsManager;
struct Screen;
// Global state consists of:
@@ -34,7 +33,7 @@ struct Screen;
// These always get updates by ScummVM, no need to differentiate between engines and the overlay.
struct Cursor {
- Cursor(const AtariGraphicsManager *manager, const Screen *screen);
+ Cursor(const Screen *screen);
~Cursor();
void reset(const Graphics::Surface *boundingSurf, int xOffset) {
@@ -105,7 +104,6 @@ private:
void convertSurfaceTo(const Graphics::PixelFormat &format);
void restoreBackground();
- const AtariGraphicsManager *_manager;
const Screen *_parentScreen;
const Graphics::Surface *_boundingSurf = nullptr;
int _xOffset = 0;
diff --git a/backends/graphics/atari/atari-graphics.cpp b/backends/graphics/atari/atari-graphics.cpp
index a0a992f19cb..b5c17c106f2 100644
--- a/backends/graphics/atari/atari-graphics.cpp
+++ b/backends/graphics/atari/atari-graphics.cpp
@@ -1074,9 +1074,9 @@ Common::Keymap *AtariGraphicsManager::getKeymap() const {
void AtariGraphicsManager::allocateSurfaces() {
for (int i : { kFrontBuffer, kBackBuffer1, kBackBuffer2 }) {
- _screen[i] = new Screen(this, getMaximumScreenWidth(), getMaximumScreenHeight(), PIXELFORMAT_CLUT8, &_palette);
+ _screen[i] = new Screen(_tt, getMaximumScreenWidth(), getMaximumScreenHeight(), PIXELFORMAT_CLUT8, &_palette);
}
- _screen[kOverlayBuffer] = new Screen(this, getOverlayWidth(), getOverlayHeight(), getOverlayFormat(), &_overlayPalette);
+ _screen[kOverlayBuffer] = new Screen(_tt, getOverlayWidth(), getOverlayHeight(), getOverlayFormat(), &_overlayPalette);
// initial position
_screen[kOverlayBuffer]->cursor.setPosition(getOverlayWidth() / 2, getOverlayHeight() / 2);
diff --git a/backends/graphics/atari/atari-graphics.h b/backends/graphics/atari/atari-graphics.h
index b517e446d93..26cb3b87fb9 100644
--- a/backends/graphics/atari/atari-graphics.h
+++ b/backends/graphics/atari/atari-graphics.h
@@ -36,9 +36,7 @@
#define MAX_V_SHAKE 16
class AtariGraphicsManager final : public GraphicsManager, Common::EventObserver {
- friend class Cursor;
friend class PendingScreenChanges;
- friend class Screen;
public:
AtariGraphicsManager();
diff --git a/backends/graphics/atari/atari-pendingscreenchanges.h b/backends/graphics/atari/atari-pendingscreenchanges.h
index 1342c877af2..c26145fbf52 100644
--- a/backends/graphics/atari/atari-pendingscreenchanges.h
+++ b/backends/graphics/atari/atari-pendingscreenchanges.h
@@ -106,7 +106,6 @@ private:
std::pair<int, bool> _aspectRatioCorrectionYOffset;
std::pair<bool, bool> _setScreenOffsets;
std::pair<bool, bool> _shrinkVidelVisibleArea;
-
};
#endif // ATARI-PENDINGSCREENCHANGES_H
diff --git a/backends/graphics/atari/atari-screen.cpp b/backends/graphics/atari/atari-screen.cpp
index 49749a4f201..0da9a47c466 100644
--- a/backends/graphics/atari/atari-screen.cpp
+++ b/backends/graphics/atari/atari-screen.cpp
@@ -23,14 +23,14 @@
#include <mint/falcon.h>
-#include "atari-graphics.h"
+#include "atari-graphics.h" // MAX_HZ_SHAKE, MAX_V_SHAKE
#include "atari-supervidel.h"
#include "backends/platform/atari/atari-debug.h"
-Screen::Screen(AtariGraphicsManager *manager, int width, int height, const Graphics::PixelFormat &format, const Palette *palette_)
- : _manager(manager)
- , cursor(manager, this)
- , palette(palette_) {
+Screen::Screen(bool tt, int width, int height, const Graphics::PixelFormat &format, const Palette *palette_)
+ : cursor(this)
+ , palette(palette_)
+ , _tt(tt) {
#ifdef USE_SUPERVIDEL
if (g_hasSuperVidel) {
@@ -43,7 +43,7 @@ Screen::Screen(AtariGraphicsManager *manager, int width, int height, const Graph
#endif
{
surf.reset(new AtariSurface(
- width + (_manager->_tt ? 0 : 2 * MAX_HZ_SHAKE),
+ width + (_tt ? 0 : 2 * MAX_HZ_SHAKE),
height + 2 * MAX_V_SHAKE,
format));
_offsettedSurf.reset(new AtariSurface());
@@ -73,7 +73,7 @@ void Screen::reset(int width, int height, const Graphics::Surface &boundingSurf,
// erase old screen
_offsettedSurf->fillRect(_offsettedSurf->getBounds(), 0);
- if (_manager->_tt) {
+ if (_tt) {
if (width <= 320 && height <= 240) {
surf->w = 320;
surf->h = 240 + 2 * MAX_V_SHAKE;
@@ -88,7 +88,7 @@ void Screen::reset(int width, int height, const Graphics::Surface &boundingSurf,
} else {
mode = VsetMode(VM_INQUIRE) & PAL;
- if (_manager->_vgaMonitor) {
+ if (VgetMonitor() == MON_VGA) {
mode |= VGA | (bitsPerPixel == 4 ? BPS4 : (g_hasSuperVidel ? BPS8C : BPS8));
if (width <= 320 && height <= 240) {
diff --git a/backends/graphics/atari/atari-screen.h b/backends/graphics/atari/atari-screen.h
index ce7812e433a..d20b050f0e9 100644
--- a/backends/graphics/atari/atari-screen.h
+++ b/backends/graphics/atari/atari-screen.h
@@ -39,8 +39,6 @@ struct std::hash<Common::Rect>
}
};
-class AtariGraphicsManager;
-
class Palette {
public:
void clear() {
@@ -60,7 +58,7 @@ private:
struct Screen {
using DirtyRects = std::unordered_set<Common::Rect>;
- Screen(AtariGraphicsManager *manager, int width, int height, const Graphics::PixelFormat &format, const Palette *palette);
+ Screen(bool tt, int width, int height, const Graphics::PixelFormat &format, const Palette *palette);
void reset(int width, int height, const Graphics::Surface &boundingSurf, int xOffset, bool resetCursorPosition);
// must be called before any rectangle drawing
@@ -94,8 +92,7 @@ private:
kRezValueTTHigh = 6 // 1280x960 at 1bpp, TT palette
};
- const AtariGraphicsManager *_manager;
-
+ bool _tt;
Common::ScopedPtr<AtariSurface> _offsettedSurf;
int _xOffset = 0;
};
Commit: e575d1360e81fe95b99893df1a9cb56d071608b7
https://github.com/scummvm/scummvm/commit/e575d1360e81fe95b99893df1a9cb56d071608b7
Author: Miro Kropacek (miro.kropacek at gmail.com)
Date: 2025-06-25T23:50:35+02:00
Commit Message:
BACKENDS: ATARI: Make purpose of _xOffset more explicit
This also cleans up Screen::reset() a bit.
Get rid of the reset cursor flag, it's not that useful in the overlay.
Changed paths:
backends/graphics/atari/atari-cursor.cpp
backends/graphics/atari/atari-cursor.h
backends/graphics/atari/atari-graphics.cpp
backends/graphics/atari/atari-screen.cpp
backends/graphics/atari/atari-screen.h
diff --git a/backends/graphics/atari/atari-cursor.cpp b/backends/graphics/atari/atari-cursor.cpp
index b271dad7fa5..5be9a1c741a 100644
--- a/backends/graphics/atari/atari-cursor.cpp
+++ b/backends/graphics/atari/atari-cursor.cpp
@@ -77,6 +77,7 @@ void Cursor::update() {
assert(_srcRect.height() == _dstRect.height());
const int dstBitsPerPixel = _parentScreen->offsettedSurf->getBitsPerPixel();
+ const int xOffset = (_parentScreen->offsettedSurf->w - _boundingSurf->w) / 2;
// non-direct rendering never uses 4bpp but maybe in the future ...
_savedRect = AtariSurface::alignRect(
@@ -88,9 +89,9 @@ void Cursor::update() {
// this is used only in flushBackground() for comparison with rects
// passed by Screen::addDirtyRect (aligned and shifted by the same offset)
_alignedDstRect = AtariSurface::alignRect(
- _dstRect.left + _xOffset,
+ _dstRect.left + xOffset,
_dstRect.top,
- _dstRect.right + _xOffset,
+ _dstRect.right + xOffset,
_dstRect.bottom);
}
}
@@ -270,6 +271,7 @@ void Cursor::saveBackground() {
void Cursor::draw() {
AtariSurface &dstSurface = *_parentScreen->offsettedSurf;
const int dstBitsPerPixel = dstSurface.getBitsPerPixel();
+ const int xOffset = (dstSurface.w - _boundingSurf->w) / 2;
//atari_debug("Cursor::draw: %d %d %d %d", _dstRect.left, _dstRect.top, _dstRect.width(), _dstRect.height());
@@ -298,7 +300,7 @@ void Cursor::draw() {
dstSurface.drawMaskedSprite(
_surface, _surfaceMask,
- _dstRect.left + _xOffset, _dstRect.top,
+ _dstRect.left + xOffset, _dstRect.top,
g_hasSuperVidel
? _srcRect
// TODO: _srcRect and add clipping to AtariSurface::drawMaskedSprite
diff --git a/backends/graphics/atari/atari-cursor.h b/backends/graphics/atari/atari-cursor.h
index 46c4dff8702..f022f13a945 100644
--- a/backends/graphics/atari/atari-cursor.h
+++ b/backends/graphics/atari/atari-cursor.h
@@ -36,9 +36,8 @@ struct Cursor {
Cursor(const Screen *screen);
~Cursor();
- void reset(const Graphics::Surface *boundingSurf, int xOffset) {
+ void reset(const Graphics::Surface *boundingSurf) {
_boundingSurf = boundingSurf;
- _xOffset = xOffset;
_positionChanged = true;
_surfaceChanged = true;
@@ -106,7 +105,6 @@ private:
const Screen *_parentScreen;
const Graphics::Surface *_boundingSurf = nullptr;
- int _xOffset = 0;
bool _positionChanged = false;
bool _surfaceChanged = false;
diff --git a/backends/graphics/atari/atari-graphics.cpp b/backends/graphics/atari/atari-graphics.cpp
index b5c17c106f2..685f02e3c5e 100644
--- a/backends/graphics/atari/atari-graphics.cpp
+++ b/backends/graphics/atari/atari-graphics.cpp
@@ -481,10 +481,10 @@ OSystem::TransactionError AtariGraphicsManager::endGFXTransaction() {
_chunkySurfaceOffsetted.init(_currentState.width, _currentState.height, c2pWidth,
_chunkySurface.getBasePtr(xOffset, 0), _currentState.format);
- _screen[kFrontBuffer]->reset(c2pWidth, _currentState.height, _chunkySurfaceOffsetted, xOffset, true);
+ _screen[kFrontBuffer]->reset(c2pWidth, _currentState.height, _chunkySurfaceOffsetted);
if (_currentState.mode > kSingleBuffering) {
- _screen[kBackBuffer1]->reset(c2pWidth, _currentState.height, _chunkySurfaceOffsetted, xOffset, true);
- _screen[kBackBuffer2]->reset(c2pWidth, _currentState.height, _chunkySurfaceOffsetted, xOffset, true);
+ _screen[kBackBuffer1]->reset(c2pWidth, _currentState.height, _chunkySurfaceOffsetted);
+ _screen[kBackBuffer2]->reset(c2pWidth, _currentState.height, _chunkySurfaceOffsetted);
}
{
@@ -754,11 +754,7 @@ void AtariGraphicsManager::showOverlay(bool inGUI) {
// cursor is reset before calling showOverlay()
- // do not cache dirtyRects and saved cursor rect
- _screen[kOverlayBuffer]->reset(
- getOverlayWidth(), getOverlayHeight(),
- *lockOverlay(), 0,
- false);
+ _screen[kOverlayBuffer]->reset(getOverlayWidth(), getOverlayHeight(), *lockOverlay());
_overlayState = kOverlayVisible;
diff --git a/backends/graphics/atari/atari-screen.cpp b/backends/graphics/atari/atari-screen.cpp
index 0da9a47c466..a6c5ba5aab6 100644
--- a/backends/graphics/atari/atari-screen.cpp
+++ b/backends/graphics/atari/atari-screen.cpp
@@ -58,13 +58,10 @@ Screen::Screen(bool tt, int width, int height, const Graphics::PixelFormat &form
width, height));
}
-void Screen::reset(int width, int height, const Graphics::Surface &boundingSurf, int xOffset, bool resetCursorPosition) {
- _xOffset = xOffset;
-
+void Screen::reset(int width, int height, const Graphics::Surface &boundingSurf) {
clearDirtyRects();
- cursor.reset(&boundingSurf, xOffset);
- if (resetCursorPosition)
- cursor.setPosition(boundingSurf.w / 2, boundingSurf.h / 2);
+ cursor.reset(&boundingSurf);
+ cursor.setPosition(boundingSurf.w / 2, boundingSurf.h / 2);
rez = -1;
mode = -1;
@@ -140,6 +137,10 @@ void Screen::addDirtyRect(const Graphics::Surface &srcSurface, int x, int y, int
if (fullRedraw)
return;
+ // x,y are relative to srcSurface but screen's width is always aligned to 16 bytes
+ // so both dirty rects and cursor must be drawn in its coordinates
+ const int xOffset = (_offsettedSurf->w - srcSurface.w) / 2;
+
if ((w == srcSurface.w && h == srcSurface.h)
|| dirtyRects.size() == 128) { // 320x200 can hold at most 250 16x16 rectangles
//atari_debug("addDirtyRect[%d]: purge %d x %d", (int)dirtyRects.size(), srcSurface.w, srcSurface.h);
@@ -147,13 +148,13 @@ void Screen::addDirtyRect(const Graphics::Surface &srcSurface, int x, int y, int
dirtyRects.clear();
// don't use x/y/w/h, the 2nd expression may be true
// also, it's ok if e.g. w = 630 gets aligned to w = 640, nothing is drawn in 630~639
- dirtyRects.insert(AtariSurface::alignRect(_xOffset, 0, _xOffset + srcSurface.w, srcSurface.h));
+ dirtyRects.insert(AtariSurface::alignRect(xOffset, 0, xOffset + srcSurface.w, srcSurface.h));
- cursor.reset(&srcSurface, _xOffset);
+ cursor.reset(&srcSurface);
fullRedraw = true;
} else {
- const Common::Rect alignedRect = AtariSurface::alignRect(x + _xOffset, y, x + _xOffset + w, y + h);
+ const Common::Rect alignedRect = AtariSurface::alignRect(x + xOffset, y, x + xOffset + w, y + h);
dirtyRects.insert(alignedRect);
diff --git a/backends/graphics/atari/atari-screen.h b/backends/graphics/atari/atari-screen.h
index d20b050f0e9..20f5cfeb6aa 100644
--- a/backends/graphics/atari/atari-screen.h
+++ b/backends/graphics/atari/atari-screen.h
@@ -60,7 +60,7 @@ struct Screen {
Screen(bool tt, int width, int height, const Graphics::PixelFormat &format, const Palette *palette);
- void reset(int width, int height, const Graphics::Surface &boundingSurf, int xOffset, bool resetCursorPosition);
+ void reset(int width, int height, const Graphics::Surface &boundingSurf);
// must be called before any rectangle drawing
void addDirtyRect(const Graphics::Surface &srcSurface, int x, int y, int w, int h, bool directRendering);
@@ -94,7 +94,6 @@ private:
bool _tt;
Common::ScopedPtr<AtariSurface> _offsettedSurf;
- int _xOffset = 0;
};
#endif // BACKENDS_GRAPHICS_ATARI_SCREEN_H
Commit: 3f47c7a8ced0fc302e9bf88393c26919fae71937
https://github.com/scummvm/scummvm/commit/3f47c7a8ced0fc302e9bf88393c26919fae71937
Author: Miro Kropacek (miro.kropacek at gmail.com)
Date: 2025-06-25T23:50:35+02:00
Commit Message:
BACKENDS: ATARI: Let Cursor access only AtariSurface instead of Screen
Changed paths:
backends/graphics/atari/atari-cursor.cpp
backends/graphics/atari/atari-cursor.h
backends/graphics/atari/atari-graphics.cpp
backends/graphics/atari/atari-graphics.h
backends/graphics/atari/atari-screen.cpp
backends/graphics/atari/atari-surface.cpp
graphics/blit/blit-atari.cpp
diff --git a/backends/graphics/atari/atari-cursor.cpp b/backends/graphics/atari/atari-cursor.cpp
index 5be9a1c741a..daee5389246 100644
--- a/backends/graphics/atari/atari-cursor.cpp
+++ b/backends/graphics/atari/atari-cursor.cpp
@@ -21,7 +21,6 @@
#include "atari-cursor.h"
-#include "atari-screen.h"
#include "atari-supervidel.h"
#include "atari-surface.h"
//#include "backends/platform/atari/atari-debug.h"
@@ -40,16 +39,14 @@ uint32 Cursor::_keycolor;
Graphics::Surface Cursor::_surface;
Graphics::Surface Cursor::_surfaceMask;
-Cursor::Cursor(const Screen *screen)
- : _parentScreen(screen) {
-}
-
Cursor::~Cursor() {
_savedBackground.free();
// beware, called multiple times (they have to be destroyed before
// AtariSurfaceDeinit() is called)
- _surface.free();
- _surfaceMask.free();
+ if (_surface.getPixels())
+ _surface.free();
+ if (_surface.getPixels())
+ _surfaceMask.free();
}
void Cursor::update() {
@@ -76,8 +73,8 @@ void Cursor::update() {
assert(_srcRect.width() == _dstRect.width());
assert(_srcRect.height() == _dstRect.height());
- const int dstBitsPerPixel = _parentScreen->offsettedSurf->getBitsPerPixel();
- const int xOffset = (_parentScreen->offsettedSurf->w - _boundingSurf->w) / 2;
+ const int dstBitsPerPixel = _screenSurf->getBitsPerPixel();
+ const int xOffset = (_screenSurf->w - _boundingSurf->w) / 2;
// non-direct rendering never uses 4bpp but maybe in the future ...
_savedRect = AtariSurface::alignRect(
@@ -160,8 +157,12 @@ void Cursor::convertSurfaceTo(const Graphics::PixelFormat &format) {
bMask = format.bMax() << format.bShift;
}
- _surface.create(cursorWidth, cursorHeight, format); // keep it 8bpl even if bitsPerPixel == 4...
- _surfaceMask.create(g_hasSuperVidel ? _surface.w : _surface.w / 8, _surface.h, format); // 1 bpl
+ // always 8-bit as this is both 8-bit src and 4-bit dst for C2P
+ _surface.create(cursorWidth, cursorHeight, format);
+ assert(_surface.pitch == _surface.w);
+ // always 8-bit or 1-bit
+ _surfaceMask.create(g_hasSuperVidel ? _surface.w : _surface.w / 8, _surface.h, PIXELFORMAT_CLUT8);
+ _surfaceMask.w = _surface.w;
}
const int srcRectWidth = g_hasSuperVidel ? _width : _srcRect.width();
@@ -254,7 +255,7 @@ void Cursor::saveBackground() {
// as this is used only for direct rendering, we don't need to worry about offsettedSurf
// having different dimensions than the source surface
- const Graphics::Surface &dstSurface = *_parentScreen->offsettedSurf;
+ const Graphics::Surface &dstSurface = *_screenSurf;
//atari_debug("Cursor::saveBackground: %d %d %d %d", _savedRect.left, _savedRect.top, _savedRect.width(), _savedRect.height());
@@ -269,7 +270,7 @@ void Cursor::saveBackground() {
}
void Cursor::draw() {
- AtariSurface &dstSurface = *_parentScreen->offsettedSurf;
+ AtariSurface &dstSurface = *_screenSurf;
const int dstBitsPerPixel = dstSurface.getBitsPerPixel();
const int xOffset = (dstSurface.w - _boundingSurf->w) / 2;
@@ -319,7 +320,7 @@ void Cursor::restoreBackground() {
// as this is used only for direct rendering, we don't need to worry about offsettedSurf
// having different dimensions than the source surface
- Graphics::Surface &dstSurface = *_parentScreen->offsettedSurf->surfacePtr();
+ Graphics::Surface &dstSurface = *_screenSurf->surfacePtr();
// restore native bitplanes or pixels, so it must be a Graphics::Surface to copy to
dstSurface.copyRectToSurface(
diff --git a/backends/graphics/atari/atari-cursor.h b/backends/graphics/atari/atari-cursor.h
index f022f13a945..4d5ed0c1d15 100644
--- a/backends/graphics/atari/atari-cursor.h
+++ b/backends/graphics/atari/atari-cursor.h
@@ -24,7 +24,7 @@
#include "graphics/surface.h"
-struct Screen;
+class AtariSurface;
// Global state consists of:
// - palette (used for the overlay only atm)
@@ -33,10 +33,10 @@ struct Screen;
// These always get updates by ScummVM, no need to differentiate between engines and the overlay.
struct Cursor {
- Cursor(const Screen *screen);
~Cursor();
- void reset(const Graphics::Surface *boundingSurf) {
+ void reset(AtariSurface* screenSurf, const Graphics::Surface *boundingSurf) {
+ _screenSurf = screenSurf;
_boundingSurf = boundingSurf;
_positionChanged = true;
@@ -103,7 +103,7 @@ private:
void convertSurfaceTo(const Graphics::PixelFormat &format);
void restoreBackground();
- const Screen *_parentScreen;
+ AtariSurface *_screenSurf;
const Graphics::Surface *_boundingSurf = nullptr;
bool _positionChanged = false;
diff --git a/backends/graphics/atari/atari-graphics.cpp b/backends/graphics/atari/atari-graphics.cpp
index 685f02e3c5e..ab685248f58 100644
--- a/backends/graphics/atari/atari-graphics.cpp
+++ b/backends/graphics/atari/atari-graphics.cpp
@@ -25,16 +25,13 @@
#include <mint/cookie.h>
#include <mint/falcon.h>
-#include <mint/osbind.h>
#include <mint/sysvars.h>
#include "backends/platform/atari/atari-debug.h"
#include "backends/keymapper/action.h"
#include "backends/keymapper/keymap.h"
#include "common/config-manager.h"
-#include "common/str.h"
#include "common/translation.h"
-#include "engines/engine.h"
#include "gui/ThemeEngine.h"
#include "atari-surface.h"
@@ -581,7 +578,7 @@ void AtariGraphicsManager::copyRectToScreen(const void *buf, int pitch, int x, i
directRendering);
if (directRendering && !g_hasSuperVidel) {
- copyRectToScreenInternal(
+ copyRectToAtariSurface(
*_screen[kFrontBuffer]->offsettedSurf,
(const byte *)buf, pitch, x, y, w, h);
} else {
@@ -912,7 +909,7 @@ void AtariGraphicsManager::copyRectToOverlay(const void *buf, int pitch, int x,
directRendering);
if (directRendering) {
- copyRectToScreenInternal(
+ copyRectToAtariSurface(
*_screen[kOverlayBuffer]->offsettedSurf,
(const byte *)buf, pitch, x, y, w, h);
} else {
@@ -1146,8 +1143,8 @@ bool AtariGraphicsManager::updateScreenInternal(Screen *dstScreen, const Graphic
return updated;
}
-void AtariGraphicsManager::copyRectToScreenInternal(AtariSurface &dstSurface,
- const byte *buf, int pitch, int x, int y, int w, int h) {
+void AtariGraphicsManager::copyRectToAtariSurface(AtariSurface &dstSurface,
+ const byte *buf, int pitch, int x, int y, int w, int h) {
const Common::Rect rect = AtariSurface::alignRect(x, y, x + w, y + h);
// 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 26cb3b87fb9..fa4c3edfc28 100644
--- a/backends/graphics/atari/atari-graphics.h
+++ b/backends/graphics/atari/atari-graphics.h
@@ -135,8 +135,8 @@ private:
void addDirtyRectToScreens(const Graphics::Surface &dstSurface,
int x, int y, int w, int h, bool directRendering);
bool updateScreenInternal(Screen *dstScreen, const Graphics::Surface *srcSurface);
- void copyRectToScreenInternal(AtariSurface &dstSurface,
- const byte *buf, int pitch, int x, int y, int w, int h);
+ void copyRectToAtariSurface(AtariSurface &dstSurface,
+ const byte *buf, int pitch, int x, int y, int w, int h);
bool isOverlayDirectRendering() const {
#ifndef DISABLE_FANCY_THEMES
diff --git a/backends/graphics/atari/atari-screen.cpp b/backends/graphics/atari/atari-screen.cpp
index a6c5ba5aab6..9df7b421add 100644
--- a/backends/graphics/atari/atari-screen.cpp
+++ b/backends/graphics/atari/atari-screen.cpp
@@ -23,13 +23,12 @@
#include <mint/falcon.h>
-#include "atari-graphics.h" // MAX_HZ_SHAKE, MAX_V_SHAKE
-#include "atari-supervidel.h"
-#include "backends/platform/atari/atari-debug.h"
+#include "atari-graphics.h" // MAX_HZ_SHAKE, MAX_V_SHAKE
+#include "atari-supervidel.h" // g_hasSuperVidel
+//#include "backends/platform/atari/atari-debug.h"
Screen::Screen(bool tt, int width, int height, const Graphics::PixelFormat &format, const Palette *palette_)
- : cursor(this)
- , palette(palette_)
+ : palette(palette_)
, _tt(tt) {
#ifdef USE_SUPERVIDEL
@@ -60,8 +59,7 @@ Screen::Screen(bool tt, int width, int height, const Graphics::PixelFormat &form
void Screen::reset(int width, int height, const Graphics::Surface &boundingSurf) {
clearDirtyRects();
- cursor.reset(&boundingSurf);
- cursor.setPosition(boundingSurf.w / 2, boundingSurf.h / 2);
+
rez = -1;
mode = -1;
@@ -131,29 +129,31 @@ void Screen::reset(int width, int height, const Graphics::Surface &boundingSurf)
(surf->w - width) / 2, // left
(surf->h - height) / 2), // top
width, height));
+
+ cursor.reset(_offsettedSurf.get(), &boundingSurf);
+ cursor.setPosition(boundingSurf.w / 2, boundingSurf.h / 2);
}
void Screen::addDirtyRect(const Graphics::Surface &srcSurface, int x, int y, int w, int h, bool directRendering) {
if (fullRedraw)
return;
- // x,y are relative to srcSurface but screen's width is always aligned to 16 bytes
- // so both dirty rects and cursor must be drawn in its coordinates
- const int xOffset = (_offsettedSurf->w - srcSurface.w) / 2;
-
if ((w == srcSurface.w && h == srcSurface.h)
|| dirtyRects.size() == 128) { // 320x200 can hold at most 250 16x16 rectangles
//atari_debug("addDirtyRect[%d]: purge %d x %d", (int)dirtyRects.size(), srcSurface.w, srcSurface.h);
dirtyRects.clear();
- // don't use x/y/w/h, the 2nd expression may be true
- // also, it's ok if e.g. w = 630 gets aligned to w = 640, nothing is drawn in 630~639
- dirtyRects.insert(AtariSurface::alignRect(xOffset, 0, xOffset + srcSurface.w, srcSurface.h));
+ // even if srcSurface.w != _offsettedSurf.w, alignRect would lead to the same result
+ dirtyRects.insert(_offsettedSurf->getBounds());
- cursor.reset(&srcSurface);
+ cursor.reset(_offsettedSurf.get(), &srcSurface);
fullRedraw = true;
} else {
+ // x,y are relative to srcSurface but screen's width is always aligned to 16 bytes
+ // so both dirty rects and cursor must be drawn in screen coordinates
+ const int xOffset = (_offsettedSurf->w - srcSurface.w) / 2;
+
const Common::Rect alignedRect = AtariSurface::alignRect(x + xOffset, y, x + xOffset + w, y + h);
dirtyRects.insert(alignedRect);
diff --git a/backends/graphics/atari/atari-surface.cpp b/backends/graphics/atari/atari-surface.cpp
index e204a237698..992293815db 100644
--- a/backends/graphics/atari/atari-surface.cpp
+++ b/backends/graphics/atari/atari-surface.cpp
@@ -163,15 +163,12 @@ void AtariSurface::free() {
void AtariSurface::copyRectToSurface(const void *buffer, int srcPitch, int destX, int destY, int width, int height) {
assert(width % 16 == 0);
assert(destX % 16 == 0);
+ assert(format.bytesPerPixel == 1);
- // 'pChunkyEnd' is a delicate parameter: the c2p routine compares it to the address register
- // used for pixel reading; two common mistakes:
- // 1. (subRect.left, subRect.bottom) = beginning of the next line *including the offset*
- // 2. (subRect.right, subRect.bottom) = even worse, end of the *next* line, not current one
const byte *pChunky = (const byte *)buffer;
- const byte *pChunkyEnd = pChunky + (height - 1) * srcPitch + width * format.bytesPerPixel;
+ const byte *pChunkyEnd = pChunky + (height - 1) * srcPitch + width;
- byte *pScreen = (byte *)getPixels() + destY * pitch + destX * getBitsPerPixel()/8;
+ byte *pScreen = (byte *)getBasePtr(0, destY) + destX * getBitsPerPixel()/8;
if (getBitsPerPixel() == 8) {
if (srcPitch == width) {
@@ -212,15 +209,17 @@ void AtariSurface::drawMaskedSprite(
assert(subRect.width() % 16 == 0);
assert(subRect.width() == srcSurface.w);
assert(srcSurface.format == format);
+ assert(srcSurface.w == srcMask.w);
+ assert(srcSurface.h == srcMask.h);
- if (getBitsPerPixel() == 4) {
- asm_draw_4bpl_sprite(
+ if (getBitsPerPixel() == 8) {
+ asm_draw_8bpl_sprite(
(uint16 *)getPixels(), (const uint16 *)srcSurface.getBasePtr(subRect.left, subRect.top),
(const uint16 *)srcMask.getBasePtr(subRect.left, subRect.top),
destX, destY,
pitch, subRect.width(), subRect.height());
- } else if (getBitsPerPixel() == 8) {
- asm_draw_8bpl_sprite(
+ } else {
+ asm_draw_4bpl_sprite(
(uint16 *)getPixels(), (const uint16 *)srcSurface.getBasePtr(subRect.left, subRect.top),
(const uint16 *)srcMask.getBasePtr(subRect.left, subRect.top),
destX, destY,
diff --git a/graphics/blit/blit-atari.cpp b/graphics/blit/blit-atari.cpp
index 15e266990a7..e8cfa81a272 100644
--- a/graphics/blit/blit-atari.cpp
+++ b/graphics/blit/blit-atari.cpp
@@ -47,7 +47,7 @@ namespace Graphics {
void keyBlitLogicAtari(byte *dst, const byte *src, const uint w, const uint h,
const uint srcDelta, const uint dstDelta, const uint32 key) {
#ifdef USE_SV_BLITTER
- if (key == 0 && ((uintptr)src & 0xFF000000) >= 0xA0000000 && ((uintptr)dst & 0xFF000000) >= 0xA0000000) {
+ if (key == 0 && (uintptr)src >= 0xA0000000 && (uintptr)dst >= 0xA0000000) {
if (g_superVidelFwVersion >= 9) {
*SV_BLITTER_FIFO = (long)src; // SV_BLITTER_SRC1
*SV_BLITTER_FIFO = (long)(g_blitMask ? g_blitMask : src); // SV_BLITTER_SRC2
@@ -101,7 +101,7 @@ void copyBlit(byte *dst, const byte *src,
return;
#ifdef USE_SV_BLITTER
- if (((uintptr)src & 0xFF000000) >= 0xA0000000 && ((uintptr)dst & 0xFF000000) >= 0xA0000000) {
+ if ((uintptr)src >= 0xA0000000 && (uintptr)dst >= 0xA0000000) {
if (g_superVidelFwVersion >= 9) {
*SV_BLITTER_FIFO = (long)src; // SV_BLITTER_SRC1
*SV_BLITTER_FIFO = 0x00000000; // SV_BLITTER_SRC2
Commit: 25d125bdc0196e7516816776fe5c046a49f9fae1
https://github.com/scummvm/scummvm/commit/25d125bdc0196e7516816776fe5c046a49f9fae1
Author: Miro Kropacek (miro.kropacek at gmail.com)
Date: 2025-06-25T23:50:35+02:00
Commit Message:
BACKENDS: ATARI: Avoid redefinition warning
DISABLE_FANCY_THEMES implies DISABLE_LAUNCHERDISPLAY_GRID.
Changed paths:
backends/platform/atari/build-release.sh
configure
diff --git a/backends/platform/atari/build-release.sh b/backends/platform/atari/build-release.sh
index 59d2484b112..2a58eeaa569 100755
--- a/backends/platform/atari/build-release.sh
+++ b/backends/platform/atari/build-release.sh
@@ -10,7 +10,8 @@ PLATFORM=m68k-atari-mintelf
FASTCALL=false
export ASFLAGS="-m68020-60"
-export CXXFLAGS="-m68020-60 -DUSE_MOVE16 -DUSE_SUPERVIDEL -DUSE_SV_BLITTER"
+export CXXFLAGS="-m68020-60 -DUSE_MOVE16 -DUSE_SUPERVIDEL -DUSE_SV_BLITTER -DDISABLE_LAUNCHERDISPLAY_GRID"
+
export LDFLAGS="-m68020-60"
export PKG_CONFIG_LIBDIR="$(${PLATFORM}-gcc -print-sysroot)/usr/lib/m68020-60/pkgconfig"
diff --git a/configure b/configure
index b41409714f7..4641381f771 100755
--- a/configure
+++ b/configure
@@ -4090,7 +4090,6 @@ case $_backend in
;;
atari)
define_in_config_if_yes yes "ATARI"
- append_var DEFINES "-DDISABLE_LAUNCHERDISPLAY_GRID"
append_var DEFINES "-DDISABLE_NES_APU"
#append_var DEFINES "-DDISABLE_DOSBOX_OPL"
append_var LIBS "-lgem"
Commit: eb64b14b81a723b3b692f95e1179f28356594e67
https://github.com/scummvm/scummvm/commit/eb64b14b81a723b3b692f95e1179f28356594e67
Author: Miro Kropacek (miro.kropacek at gmail.com)
Date: 2025-06-25T23:50:35+02:00
Commit Message:
BACKENDS: ATARI: Implement proper cursor clipping
Previous implementation had to create a new surface every time srcRect
has been changed and as a bonus, it would (harmlessly but still) do a
read-modify-write past the screen buffer.
Changed paths:
backends/graphics/atari/atari-cursor.cpp
backends/graphics/atari/atari-cursor.h
backends/graphics/atari/atari-graphics-asm.S
backends/graphics/atari/atari-graphics-asm.h
backends/graphics/atari/atari-surface.cpp
backends/graphics/atari/atari-surface.h
diff --git a/backends/graphics/atari/atari-cursor.cpp b/backends/graphics/atari/atari-cursor.cpp
index daee5389246..28597229fe6 100644
--- a/backends/graphics/atari/atari-cursor.cpp
+++ b/backends/graphics/atari/atari-cursor.cpp
@@ -137,12 +137,11 @@ void Cursor::updatePosition(int deltaX, int deltaY) {
_globalSurfaceChanged = true;
}
-void Cursor::convertSurfaceTo(const Graphics::PixelFormat &format) {
+/* static */ void Cursor::convertSurfaceTo(const Graphics::PixelFormat &format) {
static int rShift, gShift, bShift;
static int rMask, gMask, bMask;
- // TODO: maintain a max width
- const int cursorWidth = g_hasSuperVidel ? _width : ((_srcRect.width() + 15) & (-16));
+ const int cursorWidth = g_hasSuperVidel ? _width : ((_width + 15) & (-16));
const int cursorHeight = _height;
const bool isCLUT8 = format.isCLUT8();
@@ -165,20 +164,17 @@ void Cursor::convertSurfaceTo(const Graphics::PixelFormat &format) {
_surfaceMask.w = _surface.w;
}
- const int srcRectWidth = g_hasSuperVidel ? _width : _srcRect.width();
-
- const byte *src = g_hasSuperVidel ? _buf : _buf + _srcRect.left;
+ const byte *src = _buf;
byte *dst = (byte *)_surface.getPixels();
byte *dstMask = (byte *)_surfaceMask.getPixels();
uint16 *dstMask16 = (uint16 *)_surfaceMask.getPixels();
- const int srcPadding = _width - srcRectWidth;
- const int dstPadding = _surface.w - srcRectWidth;
+ const int dstPadding = _surface.w - _width;
uint16 mask16 = 0xffff;
uint16 invertedBit = 0x7fff;
- for (int j = 0; j < cursorHeight; ++j) {
- for (int i = 0; i < srcRectWidth; ++i) {
+ for (int j = 0; j < _height; ++j) {
+ for (int i = 0; i < _width; ++i) {
const uint32 color = *src++;
if (color != _keycolor) {
@@ -211,8 +207,6 @@ void Cursor::convertSurfaceTo(const Graphics::PixelFormat &format) {
invertedBit = (invertedBit >> 1) | (invertedBit << (sizeof (invertedBit) * 8 - 1));
}
- src += srcPadding;
-
if (dstPadding) {
assert(!g_hasSuperVidel);
@@ -272,13 +266,10 @@ void Cursor::saveBackground() {
void Cursor::draw() {
AtariSurface &dstSurface = *_screenSurf;
const int dstBitsPerPixel = dstSurface.getBitsPerPixel();
- const int xOffset = (dstSurface.w - _boundingSurf->w) / 2;
//atari_debug("Cursor::draw: %d %d %d %d", _dstRect.left, _dstRect.top, _dstRect.width(), _dstRect.height());
- if (_globalSurfaceChanged || _srcRect.width() != _previousSrcRect.width()) {
- _previousSrcRect = _srcRect;
-
+ if (_globalSurfaceChanged) {
convertSurfaceTo(dstSurface.format);
if (!g_hasSuperVidel) {
@@ -300,12 +291,9 @@ void Cursor::draw() {
}
dstSurface.drawMaskedSprite(
- _surface, _surfaceMask,
- _dstRect.left + xOffset, _dstRect.top,
- g_hasSuperVidel
- ? _srcRect
- // TODO: _srcRect and add clipping to AtariSurface::drawMaskedSprite
- : Common::Rect(0, _srcRect.top, _surface.w, _srcRect.bottom));
+ _surface, _surfaceMask, *_boundingSurf,
+ _dstRect.left, _dstRect.top,
+ _srcRect);
_visibilityChanged = _positionChanged = _surfaceChanged = false;
}
diff --git a/backends/graphics/atari/atari-cursor.h b/backends/graphics/atari/atari-cursor.h
index 4d5ed0c1d15..5daf26470af 100644
--- a/backends/graphics/atari/atari-cursor.h
+++ b/backends/graphics/atari/atari-cursor.h
@@ -43,7 +43,7 @@ struct Cursor {
_surfaceChanged = true;
_visibilityChanged = false;
- _savedRect = _previousSrcRect = _alignedDstRect = Common::Rect();
+ _savedRect = _alignedDstRect = Common::Rect();
}
// updates outOfScreen OR srcRect/dstRect (only if visible/needed)
@@ -100,7 +100,7 @@ struct Cursor {
void draw();
private:
- void convertSurfaceTo(const Graphics::PixelFormat &format);
+ static void convertSurfaceTo(const Graphics::PixelFormat &format);
void restoreBackground();
AtariSurface *_screenSurf;
@@ -119,7 +119,6 @@ private:
Graphics::Surface _savedBackground;
Common::Rect _savedRect;
- Common::Rect _previousSrcRect;
Common::Rect _alignedDstRect;
// related to 'surface'
diff --git a/backends/graphics/atari/atari-graphics-asm.S b/backends/graphics/atari/atari-graphics-asm.S
index 772a47d8683..72e30b27a41 100644
--- a/backends/graphics/atari/atari-graphics-asm.S
+++ b/backends/graphics/atari/atari-graphics-asm.S
@@ -26,34 +26,45 @@
.text
+skip_first_pix16:
+ dc.b 0
+skip_last_pix16:
+ dc.b 0
+
| extern void asm_draw_4bpl_sprite(uint16 *dstBuffer, const uint16 *srcBuffer, const uint16 *srcMask,
-| uint destX, uint destY, uint dstPitch, uint w, uint h);
-|
+| uint destX, uint destY, uint dstPitch, uint srcPitch, uint w, uint h,
+| bool skipFirstPix16, bool skipLastPix16);
SYM(asm_draw_4bpl_sprite):
- movem.l d0-d7/a0-a2,-(sp) | 11 longs
+ movem.l d2-d7/a2,-(sp) | 7 longs
#ifdef __FASTCALL__
move.l a0,a2 | a2: dstBuffer
| a1: srcBuffer
- move.l (4+11*4,sp),a0 | a0: srcMask
+ move.l (4+7*4,sp),a0 | a0: srcMask
| d0.w: destX
| d1.w: destY
move.l d2,d3 | d3.w: dstPitch
- ext.l d3 | d3.l: dstPitch
- move.l (8+11*4,sp),d6 | d6.w: w
- lsr.w #4,d6 | d6.w: w/16
- move.l (12+11*4,sp),d7 | d7.w: h
+ move.l (8+7*4,sp),d4 | d4.w: srcPitch
+ move.l (12+7*4,sp),d6 | d6.w: w
+ move.l (16+7*4,sp),d7 | d7.w: h
+ tst.l (20+7*4,sp) | skipFirstPix16?
+ sne skip_first_pix16
+ tst.l (24+7*4,sp) | skipLastPix16?
+ sne skip_last_pix16
#else
- move.l (4+11*4,sp),a2 | a2: dstBuffer
- move.l (8+11*4,sp),a1 | a1: srcBuffer
- move.l (12+11*4,sp),a0 | a0: srcMask
- move.l (16+11*4,sp),d0 | d0.w: destX
- move.l (20+11*4,sp),d1 | d1.w: destY
- move.l (24+11*4,sp),d3 | d3.w: dstPitch
- ext.l d3 | d3.l: dstPitch
- move.l (28+11*4,sp),d6 | d6.w: w
- lsr.w #4,d6 | d6.w: w/16
- move.l (32+11*4,sp),d7 | d7.w: h
+ move.l (4+7*4,sp),a2 | a2: dstBuffer
+ move.l (8+7*4,sp),a1 | a1: srcBuffer
+ move.l (12+7*4,sp),a0 | a0: srcMask
+ move.l (16+7*4,sp),d0 | d0.w: destX
+ move.l (20+7*4,sp),d1 | d1.w: destY
+ move.l (24+7*4,sp),d3 | d3.w: dstPitch
+ move.l (28+7*4,sp),d4 | d4.w: srcPitch
+ move.l (32+7*4,sp),d6 | d6.w: w
+ move.l (36+7*4,sp),d7 | d7.w: h
+ tst.l (40+7*4,sp) | skipFirstPix16?
+ sne skip_first_pix16
+ tst.l (44+7*4,sp) | skipLastPix16?
+ sne skip_last_pix16
#endif
| Draws a 4 bitplane sprite at any position on screen.
@@ -67,216 +78,433 @@ SYM(asm_draw_4bpl_sprite):
| a1: address of bitmapdata
| a2: screen start address
- move.w d0,d2 | / Calculate the
- andi.w #0b111111110000,d0 | | number of bits
- sub.w d0,d2 | \ to shift right.
- lsr.w #1,d0 | / Add x-position to
- adda.w d0,a2 | \ screenaddress.
- mulu.w d3,d1 | / Add y-position to
- adda.l d1,a2 | \ screenaddress.
- move.w d6,d1 | / Prepare
- lsl.w #3,d1 | | offset
- move.l d3,d4 | | to next
- sub.w d1,d4 | \ screenline.
- subq.w #1,d7 | Adjust for dbra.
- subq.w #1,d6 | Adjust for dbra.
- move.w d6,d5 | Backup xloopcount in d5.w.
- moveq #16,d1 | Size of two chunks.
-
+ move.w d0,d2 | / Calculate the
+ andi.w #0b111111110000,d0 | | number of bits
+ sub.w d0,d2 | \ to shift right.
+ lsr.w #1,d0 | / Add x-position to
+ adda.w d0,a2 | \ screenaddress.
+ mulu.w d3,d1 | / Add y-position to
+ adda.l d1,a2 | \ screenaddress.
+ lsr.w #1,d6
+ sub.w d6,d3 | / Prepare offset to next
+ ext.l d3 | \ destination line.
+ sub.w d6,d4 | / Prepare offset to next
+ ext.l d4 | \ source line.
+ subq.w #1,d7 | Adjust for dbra.
+ lsr.w #3,d6 | d6.w: w/16
+ subq.w #1,d6 | Adjust for dbra.
+ move.w d6,d5 | Backup xloopcount in d5.w.
+
+ tst.b (skip_first_pix16,pc)
+ jeq 1f
+ subq.w #1,d5
+1:
+ tst.b (skip_last_pix16,pc)
+ jeq 2f
+ subq.w #1,d5
+2:
sprite4_yloop:
- move.w d5,d6 | Restore xloop counter.
+ move.w d5,d6 | Restore xloop counter.
+
+ tst.b (skip_first_pix16,pc)
+ jeq 1f
+
+ moveq #16,d1
+ sub.w d2,d1
+
+ moveq #0xffffffff,d0 | Prepare for maskshifting.
+ move.w (a0)+,d0 | Get 16pixel mask in d0.w.
+ rol.l d1,d0 | Shift it!
+ addq.l #8,a2
+ and.w d0,(a2)+ | Mask overspill bitplane 0.
+ and.w d0,(a2)+ | Mask overspill bitplane 1.
+ and.w d0,(a2)+ | Mask overspill bitplane 2.
+ and.w d0,(a2)+ | Mask overspill bitplane 3.
+ subq.l #8,a2 | Return to blockstart.
+
+ moveq #0,d0 | Prepare for bitmapshifting.
+ move.w (a1)+,d0 | Get bitplaneword in d0.w.
+ rol.l d1,d0 | Shift it.
+ or.w d0,(a2)+ | Paint overspill bitplane 0.
+
+ moveq #0,d0 | Prepare for bitmapshifting.
+ move.w (a1)+,d0 | Get bitplaneword in d0.w.
+ rol.l d1,d0 | Shift it.
+ or.w d0,(a2)+ | Paint overspill bitplane 1.
+
+ moveq #0,d0 | Prepare for bitmapshifting.
+ move.w (a1)+,d0 | Get bitplaneword in d0.w.
+ rol.l d1,d0 | Shift it.
+ or.w d0,(a2)+ | Paint overspill bitplane 2.
+
+ moveq #0,d0 | Prepare for bitmapshifting.
+ move.w (a1)+,d0 | Get bitplaneword in d0.w.
+ rol.l d1,d0 | Shift it.
+ or.w d0,(a2)+ | Paint overspill bitplane 3.
+
+ subq.l #8,a2
+
+1: tst.w d6
+ jmi sprite4_xloop_done
sprite4_xloop:
- moveq #0xffffffff,d0 | Prepare for maskshifting.
- move.w (a0)+,d0 | Get 16pixel mask in d0.w.
- ror.l d2,d0 | Shift it!
- and.w d0,(a2)+ | Mask bitplane 0.
- and.w d0,(a2)+ | Mask bitplane 1.
- and.w d0,(a2)+ | Mask bitplane 2.
- and.w d0,(a2)+ | Mask bitplane 3.
- swap d0 | Get overspill in loword.
- and.w d0,(a2)+ | Mask overspill bitplane 0.
- and.w d0,(a2)+ | Mask overspill bitplane 1.
- and.w d0,(a2)+ | Mask overspill bitplane 2.
- and.w d0,(a2)+ | Mask overspill bitplane 3.
- suba.l d1,a2 | Return to blockstart.
-
- moveq #0,d0 | Prepare for bitmapshifting.
- move.w (a1)+,d0 | Get bitplaneword in d0.w.
- ror.l d2,d0 | Shift it.
- or.w d0,(a2)+ | Paint bitplane 0.
- swap d0 | Get overspill in loword.
- or.w d0,6(a2) | Paint overspill bitplane 0.
-
- moveq #0,d0 | Prepare for bitmapshifting.
- move.w (a1)+,d0 | Get bitplaneword in d0.w.
- ror.l d2,d0 | Shift it.
- or.w d0,(a2)+ | Paint bitplane 1.
- swap d0 | Get overspill in loword.
- or.w d0,6(a2) | Paint overspill bitplane 1.
-
- moveq #0,d0 | Prepare for bitmapshifting.
- move.w (a1)+,d0 | Get bitplaneword in d0.w.
- ror.l d2,d0 | Shift it.
- or.w d0,(a2)+ | Paint bitplane 2.
- swap d0 | Get overspill in loword.
- or.w d0,6(a2) | Paint overspill bitplane 2.
-
- moveq #0,d0 | Prepare for bitmapshifting.
- move.w (a1)+,d0 | Get bitplaneword in d0.w.
- ror.l d2,d0 | Shift it.
- or.w d0,(a2)+ | Paint bitplane 3.
- swap d0 | Get overspill in loword.
- or.w d0,6(a2) | Paint overspill bitplane 3.
-
- dbra d6,sprite4_xloop | Loop until blocks done.
-
- adda.l d4,a2 | Goto next screenline.
- dbra d7,sprite4_yloop | Loop until lines done.
-
- movem.l (sp)+,d0-d7/a0-a2
+ moveq #0xffffffff,d0 | Prepare for maskshifting.
+ move.w (a0)+,d0 | Get 16pixel mask in d0.w.
+ ror.l d2,d0 | Shift it!
+ and.w d0,(a2)+ | Mask bitplane 0.
+ and.w d0,(a2)+ | Mask bitplane 1.
+ and.w d0,(a2)+ | Mask bitplane 2.
+ and.w d0,(a2)+ | Mask bitplane 3.
+ swap d0 | Get overspill in loword.
+ and.w d0,(a2)+ | Mask overspill bitplane 0.
+ and.w d0,(a2)+ | Mask overspill bitplane 1.
+ and.w d0,(a2)+ | Mask overspill bitplane 2.
+ and.w d0,(a2)+ | Mask overspill bitplane 3.
+ lea (-16,a2),a2 | Return to blockstart.
+
+ moveq #0,d0 | Prepare for bitmapshifting.
+ move.w (a1)+,d0 | Get bitplaneword in d0.w.
+ ror.l d2,d0 | Shift it.
+ or.w d0,(a2)+ | Paint bitplane 0.
+ swap d0 | Get overspill in loword.
+ or.w d0,6(a2) | Paint overspill bitplane 0.
+
+ moveq #0,d0 | Prepare for bitmapshifting.
+ move.w (a1)+,d0 | Get bitplaneword in d0.w.
+ ror.l d2,d0 | Shift it.
+ or.w d0,(a2)+ | Paint bitplane 1.
+ swap d0 | Get overspill in loword.
+ or.w d0,6(a2) | Paint overspill bitplane 1.
+
+ moveq #0,d0 | Prepare for bitmapshifting.
+ move.w (a1)+,d0 | Get bitplaneword in d0.w.
+ ror.l d2,d0 | Shift it.
+ or.w d0,(a2)+ | Paint bitplane 2.
+ swap d0 | Get overspill in loword.
+ or.w d0,6(a2) | Paint overspill bitplane 2.
+
+ moveq #0,d0 | Prepare for bitmapshifting.
+ move.w (a1)+,d0 | Get bitplaneword in d0.w.
+ ror.l d2,d0 | Shift it.
+ or.w d0,(a2)+ | Paint bitplane 3.
+ swap d0 | Get overspill in loword.
+ or.w d0,6(a2) | Paint overspill bitplane 3.
+
+ dbra d6,sprite4_xloop | Loop until blocks done.
+
+sprite4_xloop_done:
+ tst.b (skip_last_pix16,pc)
+ jeq 1f
+
+ moveq #0xffffffff,d0 | Prepare for maskshifting.
+ move.w (a0)+,d0 | Get 16pixel mask in d0.w.
+ ror.l d2,d0 | Shift it!
+ and.w d0,(a2)+ | Mask bitplane 0.
+ and.w d0,(a2)+ | Mask bitplane 1.
+ and.w d0,(a2)+ | Mask bitplane 2.
+ and.w d0,(a2)+ | Mask bitplane 3.
+ subq.l #8,a2 | Return to blockstart.
+
+ moveq #0,d0 | Prepare for bitmapshifting.
+ move.w (a1)+,d0 | Get bitplaneword in d0.w.
+ ror.l d2,d0 | Shift it.
+ or.w d0,(a2)+ | Paint bitplane 0.
+
+ moveq #0,d0 | Prepare for bitmapshifting.
+ move.w (a1)+,d0 | Get bitplaneword in d0.w.
+ ror.l d2,d0 | Shift it.
+ or.w d0,(a2)+ | Paint bitplane 1.
+
+ moveq #0,d0 | Prepare for bitmapshifting.
+ move.w (a1)+,d0 | Get bitplaneword in d0.w.
+ ror.l d2,d0 | Shift it.
+ or.w d0,(a2)+ | Paint bitplane 2.
+
+ moveq #0,d0 | Prepare for bitmapshifting.
+ move.w (a1)+,d0 | Get bitplaneword in d0.w.
+ ror.l d2,d0 | Shift it.
+ or.w d0,(a2)+ | Paint bitplane 3.
+
+1: move.l d4,d0
+ asr.l #2,d0
+ adda.l d0,a0
+ adda.l d4,a1
+ adda.l d3,a2 | Goto next screenline.
+ dbra d7,sprite4_yloop | Loop until lines done.
+
+ movem.l (sp)+,d2-d7/a2
rts
| extern void asm_draw_8bpl_sprite(uint16 *dstBuffer, const uint16 *srcBuffer, const uint16 *srcMask,
-| uint destX, uint destY, uint dstPitch, uint w, uint h);
-|
+| uint destX, uint destY, uint dstPitch, uint srcPitch, uint w, uint h,
+| bool skipFirstPix16, bool skipLastPix16);
SYM(asm_draw_8bpl_sprite):
- movem.l d0-d7/a0-a2,-(sp) | 11 longs
+ movem.l d2-d7/a2,-(sp) | 7 longs
#ifdef __FASTCALL__
move.l a0,a2 | a2: dstBuffer
| a1: srcBuffer
- move.l (4+11*4,sp),a0 | a0: srcMask
+ move.l (4+7*4,sp),a0 | a0: srcMask
| d0.w: destX
| d1.w: destY
move.l d2,d3 | d3.w: dstPitch
- ext.l d3 | d3.l: dstPitch
- move.l (8+11*4,sp),d6 | d6.w: w
- lsr.w #4,d6 | d6.w: w/16
- move.l (12+11*4,sp),d7 | d7.w: h
+ move.l (8+7*4,sp),d4 | d4.w: srcPitch
+ move.l (12+7*4,sp),d6 | d6.w: w
+ move.l (16+7*4,sp),d7 | d7.w: h
+ tst.l (20+7*4,sp) | skipFirstPix16?
+ sne skip_first_pix16
+ tst.l (24+7*4,sp) | skipLastPix16?
+ sne skip_last_pix16
#else
- move.l (4+11*4,sp),a2 | a2: dstBuffer
- move.l (8+11*4,sp),a1 | a1: srcBuffer
- move.l (12+11*4,sp),a0 | a0: srcMask
- move.l (16+11*4,sp),d0 | d0.w: destX
- move.l (20+11*4,sp),d1 | d1.w: destY
- move.l (24+11*4,sp),d3 | d3.w: dstPitch
- ext.l d3 | d3.l: dstPitch
- move.l (28+11*4,sp),d6 | d6.w: w
- lsr.w #4,d6 | d6.w: w/16
- move.l (32+11*4,sp),d7 | d7.w: h
+ move.l (4+7*4,sp),a2 | a2: dstBuffer
+ move.l (8+7*4,sp),a1 | a1: srcBuffer
+ move.l (12+7*4,sp),a0 | a0: srcMask
+ move.l (16+7*4,sp),d0 | d0.w: destX
+ move.l (20+7*4,sp),d1 | d1.w: destY
+ move.l (24+7*4,sp),d3 | d3.w: dstPitch
+ move.l (28+7*4,sp),d4 | d4.w: srcPitch
+ move.l (32+7*4,sp),d6 | d6.w: w
+ move.l (36+7*4,sp),d7 | d7.w: h
+ tst.l (40+7*4,sp) | skipFirstPix16?
+ sne skip_first_pix16
+ tst.l (45+7*4,sp) | skipLastPix16?
+ sne skip_last_pix16
#endif
-
- move.w d0,d2 | / Calculate the
- andi.w #0b111111110000,d0 | | number of bits
- sub.w d0,d2 | \ to shift right.
- adda.w d0,a2 | Add x-position to screenaddress.
- mulu.w d3,d1 | / Add y-position to
- adda.l d1,a2 | \ screenaddress.
- move.w d6,d1 | / Prepare
- lsl.w #4,d1 | | offset
- move.l d3,d4 | | to next
- sub.w d1,d4 | \ screenline.
- subq.w #1,d7 | Adjust for dbra.
- subq.w #1,d6 | Adjust for dbra.
- move.w d6,d5 | Backup xloopcount in d5.w.
- moveq #32,d1 | Size of two chunks.
-
+ move.w d0,d2 | / Calculate the
+ andi.w #0b111111110000,d0 | | number of bits
+ sub.w d0,d2 | \ to shift right.
+ adda.w d0,a2 | Add x-position to screenaddress.
+ mulu.w d3,d1 | / Add y-position to
+ adda.l d1,a2 | \ screenaddress.
+ sub.w d6,d3 | / Prepare offset to next
+ ext.l d3 | \ destination line.
+ sub.w d6,d4 | / Prepare offset to next
+ ext.l d4 | \ source line.
+ subq.w #1,d7 | Adjust for dbra.
+ lsr.w #4,d6 | d6.w: w/16
+ subq.w #1,d6 | Adjust for dbra.
+ move.w d6,d5 | Backup xloopcount in d5.w.
+
+ tst.b (skip_first_pix16,pc)
+ jeq 1f
+ subq.w #1,d5
+1:
+ tst.b (skip_last_pix16,pc)
+ jeq 2f
+ subq.w #1,d5
+2:
sprite8_yloop:
- move.w d5,d6 | Restore xloop counter.
+ move.w d5,d6 | Restore xloop counter.
+
+ tst.b (skip_first_pix16,pc)
+ jeq 1f
+
+ moveq #16,d1
+ sub.w d2,d1
+
+ moveq #0xffffffff,d0 | Prepare for maskshifting.
+ move.w (a0)+,d0 | Get 16pixel mask in d0.w.
+ rol.l d1,d0 | Shift it!
+ lea (16,a2),a2
+ and.w d0,(a2)+ | Mask overspill bitplane 0.
+ and.w d0,(a2)+ | Mask overspill bitplane 1.
+ and.w d0,(a2)+ | Mask overspill bitplane 2.
+ and.w d0,(a2)+ | Mask overspill bitplane 3.
+ and.w d0,(a2)+ | Mask overspill bitplane 4.
+ and.w d0,(a2)+ | Mask overspill bitplane 5.
+ and.w d0,(a2)+ | Mask overspill bitplane 6.
+ and.w d0,(a2)+ | Mask overspill bitplane 7.
+ lea (-16,a2),a2 | Return to blockstart.
+
+ moveq #0,d0 | Prepare for bitmapshifting.
+ move.w (a1)+,d0 | Get bitplaneword in d0.w.
+ rol.l d1,d0 | Shift it.
+ or.w d0,(a2)+ | Paint overspill bitplane 0.
+
+ moveq #0,d0 | Prepare for bitmapshifting.
+ move.w (a1)+,d0 | Get bitplaneword in d0.w.
+ rol.l d1,d0 | Shift it.
+ or.w d0,(a2)+ | Paint overspill bitplane 1.
+
+ moveq #0,d0 | Prepare for bitmapshifting.
+ move.w (a1)+,d0 | Get bitplaneword in d0.w.
+ rol.l d1,d0 | Shift it.
+ or.w d0,(a2)+ | Paint overspill bitplane 2.
+
+ moveq #0,d0 | Prepare for bitmapshifting.
+ move.w (a1)+,d0 | Get bitplaneword in d0.w.
+ rol.l d1,d0 | Shift it.
+ or.w d0,(a2)+ | Paint overspill bitplane 3.
+
+ moveq #0,d0 | Prepare for bitmapshifting.
+ move.w (a1)+,d0 | Get bitplaneword in d0.w.
+ rol.l d1,d0 | Shift it.
+ or.w d0,(a2)+ | Paint overspill bitplane 4.
+
+ moveq #0,d0 | Prepare for bitmapshifting.
+ move.w (a1)+,d0 | Get bitplaneword in d0.w.
+ rol.l d1,d0 | Shift it.
+ or.w d0,(a2)+ | Paint overspill bitplane 5.
+
+ moveq #0,d0 | Prepare for bitmapshifting.
+ move.w (a1)+,d0 | Get bitplaneword in d0.w.
+ rol.l d1,d0 | Shift it.
+ or.w d0,(a2)+ | Paint overspill bitplane 6.
+
+ moveq #0,d0 | Prepare for bitmapshifting.
+ move.w (a1)+,d0 | Get bitplaneword in d0.w.
+ rol.l d1,d0 | Shift it.
+ or.w d0,(a2)+ | Paint overspill bitplane 7.
+
+ lea (-16,a2),a2
+
+1: tst.w d6
+ jmi sprite8_xloop_done
sprite8_xloop:
- moveq #0xffffffff,d0 | Prepare for maskshifting.
- move.w (a0)+,d0 | Get 16pixel mask in d0.w.
- ror.l d2,d0 | Shift it!
- and.w d0,(a2)+ | Mask bitplane 0.
- and.w d0,(a2)+ | Mask bitplane 1.
- and.w d0,(a2)+ | Mask bitplane 2.
- and.w d0,(a2)+ | Mask bitplane 3.
- and.w d0,(a2)+ | Mask bitplane 4.
- and.w d0,(a2)+ | Mask bitplane 5.
- and.w d0,(a2)+ | Mask bitplane 6.
- and.w d0,(a2)+ | Mask bitplane 7.
- swap d0 | Get overspill in loword.
- and.w d0,(a2)+ | Mask overspill bitplane 0.
- and.w d0,(a2)+ | Mask overspill bitplane 1.
- and.w d0,(a2)+ | Mask overspill bitplane 2.
- and.w d0,(a2)+ | Mask overspill bitplane 3.
- and.w d0,(a2)+ | Mask overspill bitplane 4.
- and.w d0,(a2)+ | Mask overspill bitplane 5.
- and.w d0,(a2)+ | Mask overspill bitplane 6.
- and.w d0,(a2)+ | Mask overspill bitplane 7.
- suba.l d1,a2 | Return to blockstart.
-
- moveq #0,d0 | Prepare for bitmapshifting.
- move.w (a1)+,d0 | Get bitplaneword in d0.w.
- ror.l d2,d0 | Shift it.
- or.w d0,(a2)+ | Paint bitplane 0.
- swap d0 | Get overspill in loword.
- or.w d0,14(a2) | Paint overspill bitplane 0.
-
- moveq #0,d0 | Prepare for bitmapshifting.
- move.w (a1)+,d0 | Get bitplaneword in d0.w.
- ror.l d2,d0 | Shift it.
- or.w d0,(a2)+ | Paint bitplane 1.
- swap d0 | Get overspill in loword.
- or.w d0,14(a2) | Paint overspill bitplane 1.
-
- moveq #0,d0 | Prepare for bitmapshifting.
- move.w (a1)+,d0 | Get bitplaneword in d0.w.
- ror.l d2,d0 | Shift it.
- or.w d0,(a2)+ | Paint bitplane 2.
- swap d0 | Get overspill in loword.
- or.w d0,14(a2) | Paint overspill bitplane 2.
-
- moveq #0,d0 | Prepare for bitmapshifting.
- move.w (a1)+,d0 | Get bitplaneword in d0.w.
- ror.l d2,d0 | Shift it.
- or.w d0,(a2)+ | Paint bitplane 3.
- swap d0 | Get overspill in loword.
- or.w d0,14(a2) | Paint overspill bitplane 3.
-
- moveq #0,d0 | Prepare for bitmapshifting.
- move.w (a1)+,d0 | Get bitplaneword in d0.w.
- ror.l d2,d0 | Shift it.
- or.w d0,(a2)+ | Paint bitplane 4.
- swap d0 | Get overspill in loword.
- or.w d0,14(a2) | Paint overspill bitplane 4.
-
- moveq #0,d0 | Prepare for bitmapshifting.
- move.w (a1)+,d0 | Get bitplaneword in d0.w.
- ror.l d2,d0 | Shift it.
- or.w d0,(a2)+ | Paint bitplane 5.
- swap d0 | Get overspill in loword.
- or.w d0,14(a2) | Paint overspill bitplane 5.
-
- moveq #0,d0 | Prepare for bitmapshifting.
- move.w (a1)+,d0 | Get bitplaneword in d0.w.
- ror.l d2,d0 | Shift it.
- or.w d0,(a2)+ | Paint bitplane 6.
- swap d0 | Get overspill in loword.
- or.w d0,14(a2) | Paint overspill bitplane 6.
-
- moveq #0,d0 | Prepare for bitmapshifting.
- move.w (a1)+,d0 | Get bitplaneword in d0.w.
- ror.l d2,d0 | Shift it.
- or.w d0,(a2)+ | Paint bitplane 7.
- swap d0 | Get overspill in loword.
- or.w d0,14(a2) | Paint overspill bitplane 7.
-
- dbra d6,sprite8_xloop | Loop until blocks done.
-
- adda.l d4,a2 | Goto next screenline.
- dbra d7,sprite8_yloop | Loop until lines done.
-
- movem.l (sp)+,d0-d7/a0-a2
+ moveq #0xffffffff,d0 | Prepare for maskshifting.
+ move.w (a0)+,d0 | Get 16pixel mask in d0.w.
+ ror.l d2,d0 | Shift it!
+ and.w d0,(a2)+ | Mask bitplane 0.
+ and.w d0,(a2)+ | Mask bitplane 1.
+ and.w d0,(a2)+ | Mask bitplane 2.
+ and.w d0,(a2)+ | Mask bitplane 3.
+ and.w d0,(a2)+ | Mask bitplane 4.
+ and.w d0,(a2)+ | Mask bitplane 5.
+ and.w d0,(a2)+ | Mask bitplane 6.
+ and.w d0,(a2)+ | Mask bitplane 7.
+ swap d0 | Get overspill in loword.
+ and.w d0,(a2)+ | Mask overspill bitplane 0.
+ and.w d0,(a2)+ | Mask overspill bitplane 1.
+ and.w d0,(a2)+ | Mask overspill bitplane 2.
+ and.w d0,(a2)+ | Mask overspill bitplane 3.
+ and.w d0,(a2)+ | Mask overspill bitplane 4.
+ and.w d0,(a2)+ | Mask overspill bitplane 5.
+ and.w d0,(a2)+ | Mask overspill bitplane 6.
+ and.w d0,(a2)+ | Mask overspill bitplane 7.
+ lea (-32,a2),a2 | Return to blockstart.
+
+ moveq #0,d0 | Prepare for bitmapshifting.
+ move.w (a1)+,d0 | Get bitplaneword in d0.w.
+ ror.l d2,d0 | Shift it.
+ or.w d0,(a2)+ | Paint bitplane 0.
+ swap d0 | Get overspill in loword.
+ or.w d0,14(a2) | Paint overspill bitplane 0.
+
+ moveq #0,d0 | Prepare for bitmapshifting.
+ move.w (a1)+,d0 | Get bitplaneword in d0.w.
+ ror.l d2,d0 | Shift it.
+ or.w d0,(a2)+ | Paint bitplane 1.
+ swap d0 | Get overspill in loword.
+ or.w d0,14(a2) | Paint overspill bitplane 1.
+
+ moveq #0,d0 | Prepare for bitmapshifting.
+ move.w (a1)+,d0 | Get bitplaneword in d0.w.
+ ror.l d2,d0 | Shift it.
+ or.w d0,(a2)+ | Paint bitplane 2.
+ swap d0 | Get overspill in loword.
+ or.w d0,14(a2) | Paint overspill bitplane 2.
+
+ moveq #0,d0 | Prepare for bitmapshifting.
+ move.w (a1)+,d0 | Get bitplaneword in d0.w.
+ ror.l d2,d0 | Shift it.
+ or.w d0,(a2)+ | Paint bitplane 3.
+ swap d0 | Get overspill in loword.
+ or.w d0,14(a2) | Paint overspill bitplane 3.
+
+ moveq #0,d0 | Prepare for bitmapshifting.
+ move.w (a1)+,d0 | Get bitplaneword in d0.w.
+ ror.l d2,d0 | Shift it.
+ or.w d0,(a2)+ | Paint bitplane 4.
+ swap d0 | Get overspill in loword.
+ or.w d0,14(a2) | Paint overspill bitplane 4.
+
+ moveq #0,d0 | Prepare for bitmapshifting.
+ move.w (a1)+,d0 | Get bitplaneword in d0.w.
+ ror.l d2,d0 | Shift it.
+ or.w d0,(a2)+ | Paint bitplane 5.
+ swap d0 | Get overspill in loword.
+ or.w d0,14(a2) | Paint overspill bitplane 5.
+
+ moveq #0,d0 | Prepare for bitmapshifting.
+ move.w (a1)+,d0 | Get bitplaneword in d0.w.
+ ror.l d2,d0 | Shift it.
+ or.w d0,(a2)+ | Paint bitplane 6.
+ swap d0 | Get overspill in loword.
+ or.w d0,14(a2) | Paint overspill bitplane 6.
+
+ moveq #0,d0 | Prepare for bitmapshifting.
+ move.w (a1)+,d0 | Get bitplaneword in d0.w.
+ ror.l d2,d0 | Shift it.
+ or.w d0,(a2)+ | Paint bitplane 7.
+ swap d0 | Get overspill in loword.
+ or.w d0,14(a2) | Paint overspill bitplane 7.
+
+ dbra d6,sprite8_xloop | Loop until blocks done.
+
+sprite8_xloop_done:
+ tst.b (skip_last_pix16,pc)
+ jeq 1f
+
+ moveq #0xffffffff,d0 | Prepare for maskshifting.
+ move.w (a0)+,d0 | Get 16pixel mask in d0.w.
+ ror.l d2,d0 | Shift it!
+ and.w d0,(a2)+ | Mask bitplane 0.
+ and.w d0,(a2)+ | Mask bitplane 1.
+ and.w d0,(a2)+ | Mask bitplane 2.
+ and.w d0,(a2)+ | Mask bitplane 3.
+ and.w d0,(a2)+ | Mask bitplane 4.
+ and.w d0,(a2)+ | Mask bitplane 5.
+ and.w d0,(a2)+ | Mask bitplane 6.
+ and.w d0,(a2)+ | Mask bitplane 7.
+ lea (-16,a2),a2 | Return to blockstart.
+
+ moveq #0,d0 | Prepare for bitmapshifting.
+ move.w (a1)+,d0 | Get bitplaneword in d0.w.
+ ror.l d2,d0 | Shift it.
+ or.w d0,(a2)+ | Paint bitplane 0.
+
+ moveq #0,d0 | Prepare for bitmapshifting.
+ move.w (a1)+,d0 | Get bitplaneword in d0.w.
+ ror.l d2,d0 | Shift it.
+ or.w d0,(a2)+ | Paint bitplane 1.
+
+ moveq #0,d0 | Prepare for bitmapshifting.
+ move.w (a1)+,d0 | Get bitplaneword in d0.w.
+ ror.l d2,d0 | Shift it.
+ or.w d0,(a2)+ | Paint bitplane 2.
+
+ moveq #0,d0 | Prepare for bitmapshifting.
+ move.w (a1)+,d0 | Get bitplaneword in d0.w.
+ ror.l d2,d0 | Shift it.
+ or.w d0,(a2)+ | Paint bitplane 3.
+
+ moveq #0,d0 | Prepare for bitmapshifting.
+ move.w (a1)+,d0 | Get bitplaneword in d0.w.
+ ror.l d2,d0 | Shift it.
+ or.w d0,(a2)+ | Paint bitplane 4.
+
+ moveq #0,d0 | Prepare for bitmapshifting.
+ move.w (a1)+,d0 | Get bitplaneword in d0.w.
+ ror.l d2,d0 | Shift it.
+ or.w d0,(a2)+ | Paint bitplane 5.
+
+ moveq #0,d0 | Prepare for bitmapshifting.
+ move.w (a1)+,d0 | Get bitplaneword in d0.w.
+ ror.l d2,d0 | Shift it.
+ or.w d0,(a2)+ | Paint bitplane 6.
+
+ moveq #0,d0 | Prepare for bitmapshifting.
+ move.w (a1)+,d0 | Get bitplaneword in d0.w.
+ ror.l d2,d0 | Shift it.
+ or.w d0,(a2)+ | Paint bitplane 7.
+
+1: move.l d4,d0
+ asr.l #3,d0
+ adda.l d0,a0
+ adda.l d4,a1
+ adda.l d3,a2 | Goto next screenline.
+ dbra d7,sprite8_yloop | Loop until lines done.
+
+ movem.l (sp)+,d2-d7/a2
rts
-
-
- .bss
- .even
-
-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)
diff --git a/backends/graphics/atari/atari-graphics-asm.h b/backends/graphics/atari/atari-graphics-asm.h
index 51a8bd40900..949575e7d43 100644
--- a/backends/graphics/atari/atari-graphics-asm.h
+++ b/backends/graphics/atari/atari-graphics-asm.h
@@ -35,11 +35,15 @@ extern "C" {
* @param destX sprite's X position (in pixels)
* @param destY sprite's Y position (in pixels)
* @param dstPitch destination buffer's pitch (in bytes)
+ * @param srcPitch source buffer's pitch (in bytes)
* @param w sprite's width (in pixels)
* @param h sprite's height (in pixels)
+ * @param skipFirstPix16 do not write first 16 pixels
+ * @param skipLastPix16 do not write last 16 pixels
*/
void asm_draw_4bpl_sprite(uint16 *dstBuffer, const uint16 *srcBuffer, const uint16 *srcMask,
- uint destX, uint destY, uint dstPitch, uint w, uint h);
+ uint destX, uint destY, uint dstPitch, uint srcPitch, uint w, uint h,
+ bool skipFirstPix16, bool skipLastPix16);
/**
* Copy 8bpl sprite into 8bpl buffer. Sprite's width must be multiply of 16.
*
@@ -49,11 +53,15 @@ void asm_draw_4bpl_sprite(uint16 *dstBuffer, const uint16 *srcBuffer, const uint
* @param destX sprite's X position (in pixels)
* @param destY sprite's Y position (in pixels)
* @param dstPitch destination buffer's pitch (in bytes)
+ * @param srcPitch source buffer's pitch (in bytes)
* @param w sprite's width (in pixels)
* @param h sprite's height (in pixels)
+ * @param skipFirstPix16 do not write first 16 pixels
+ * @param skipLastPix16 do not write last 16 pixels
*/
void asm_draw_8bpl_sprite(uint16 *dstBuffer, const uint16 *srcBuffer, const uint16 *srcMask,
- uint destX, uint destY, uint dstPitch, uint w, uint h);
+ uint destX, uint destY, uint dstPitch, uint srcPitch, uint w, uint h,
+ bool skipFirstPix16, bool skipLastPix16);
}
diff --git a/backends/graphics/atari/atari-surface.cpp b/backends/graphics/atari/atari-surface.cpp
index 992293815db..14997e1b1cf 100644
--- a/backends/graphics/atari/atari-surface.cpp
+++ b/backends/graphics/atari/atari-surface.cpp
@@ -204,26 +204,59 @@ void AtariSurface::copyRectToSurface(const void *buffer, int srcPitch, int destX
void AtariSurface::drawMaskedSprite(
const Graphics::Surface &srcSurface, const Graphics::Surface &srcMask,
+ const Graphics::Surface &boundingSurface,
int destX, int destY,
const Common::Rect &subRect) {
- assert(subRect.width() % 16 == 0);
- assert(subRect.width() == srcSurface.w);
assert(srcSurface.format == format);
assert(srcSurface.w == srcMask.w);
assert(srcSurface.h == srcMask.h);
+ bool skipFirstPix16 = false;
+ bool skipLastPix16 = false;
+
+ int srcSurfaceLeft = 0;
+ int srcSurfaceWidth = srcSurface.w;
+ int dstSurfaceLeft = 0;
+
+ if (subRect.left > 0) {
+ skipFirstPix16 = true;
+
+ const int offset = subRect.left & (-16);
+ srcSurfaceLeft += offset;
+ srcSurfaceWidth -= offset;
+
+ destX = 16 - (subRect.left & (16-1));
+ dstSurfaceLeft -= 16;
+ }
+
+ if (destX + srcSurfaceWidth > boundingSurface.w) {
+ skipLastPix16 = true;
+
+ const int offset = (destX + srcSurfaceWidth - boundingSurface.w) & (-16);
+ srcSurfaceWidth -= offset;
+ }
+
+ assert(srcSurfaceLeft % 16 == 0);
+ assert(srcSurfaceWidth % 16 == 0);
+
+ destX += (this->w - boundingSurface.w) / 2;
+
if (getBitsPerPixel() == 8) {
asm_draw_8bpl_sprite(
- (uint16 *)getPixels(), (const uint16 *)srcSurface.getBasePtr(subRect.left, subRect.top),
- (const uint16 *)srcMask.getBasePtr(subRect.left, subRect.top),
+ (uint16 *)getBasePtr(dstSurfaceLeft, 0),
+ (const uint16 *)srcSurface.getBasePtr(srcSurfaceLeft, subRect.top),
+ (const uint16 *)srcMask.getBasePtr(srcSurfaceLeft / 8, subRect.top),
destX, destY,
- pitch, subRect.width(), subRect.height());
+ pitch, srcSurface.w, srcSurfaceWidth, subRect.height(),
+ skipFirstPix16, skipLastPix16);
} else {
asm_draw_4bpl_sprite(
- (uint16 *)getPixels(), (const uint16 *)srcSurface.getBasePtr(subRect.left, subRect.top),
- (const uint16 *)srcMask.getBasePtr(subRect.left, subRect.top),
+ (uint16 *)getBasePtr(dstSurfaceLeft / 2, 0),
+ (const uint16 *)srcSurface.getBasePtr(srcSurfaceLeft / 2, subRect.top),
+ (const uint16 *)srcMask.getBasePtr(srcSurfaceLeft / 8, subRect.top),
destX, destY,
- pitch, subRect.width(), subRect.height());
+ pitch, srcSurface.w / 2, srcSurfaceWidth, subRect.height(),
+ skipFirstPix16, skipLastPix16);
}
}
diff --git a/backends/graphics/atari/atari-surface.h b/backends/graphics/atari/atari-surface.h
index 7bd5df84541..10d7e766d04 100644
--- a/backends/graphics/atari/atari-surface.h
+++ b/backends/graphics/atari/atari-surface.h
@@ -55,6 +55,7 @@ public:
}
virtual void drawMaskedSprite(const Graphics::Surface &srcSurface, const Graphics::Surface &srcMask,
+ const Graphics::Surface &boundingSurface,
int destX, int destY,
const Common::Rect &subRect);
@@ -93,6 +94,7 @@ public:
}
void drawMaskedSprite(const Graphics::Surface &srcSurface, const Graphics::Surface &srcMask,
+ const Graphics::Surface &boundingSurface,
int destX, int destY,
const Common::Rect &subRect) override {
#ifdef USE_SV_BLITTER
More information about the Scummvm-git-logs
mailing list