[Scummvm-git-logs] scummvm master -> d9a5de0fe6c156e4bc92799a2e4f9d67a23694cc
mikrosk
noreply at scummvm.org
Wed Jul 19 20:21:06 UTC 2023
This automated email contains information about 2 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
f85fde7707 ENGINES: ALL: Use new CursorMan API where applicable
d9a5de0fe6 BACKEND: ATARI: Screen shaking and some fixes
Commit: f85fde77077e2798c3f7d053233e88f261bfb42a
https://github.com/scummvm/scummvm/commit/f85fde77077e2798c3f7d053233e88f261bfb42a
Author: Miro Kropacek (miro.kropacek at gmail.com)
Date: 2023-07-19T22:22:11+02:00
Commit Message:
ENGINES: ALL: Use new CursorMan API where applicable
This makes code not only cleaner but also friendly to 8-bit surfaces
where pitch != width.
Changed paths:
engines/access/events.cpp
engines/avalanche/graphics.cpp
engines/glk/events.cpp
engines/hypno/cursors.cpp
engines/mm/mm1/utils/mouse.cpp
engines/mm/xeen/events.cpp
engines/mohawk/cursors.cpp
engines/nancy/cursor.cpp
engines/neverhood/mouse.cpp
engines/pegasus/cursor.cpp
engines/sherlock/events.cpp
engines/titanic/support/mouse_cursor.cpp
engines/ultima/shared/core/mouse_cursor.cpp
engines/ultima/ultima4/gfx/screen.cpp
diff --git a/engines/access/events.cpp b/engines/access/events.cpp
index 1d9731f8edb..323a78dbdb3 100644
--- a/engines/access/events.cpp
+++ b/engines/access/events.cpp
@@ -69,8 +69,7 @@ void EventsManager::setCursor(CursorType cursorId) {
if (cursorId == CURSOR_INVENTORY) {
// Set the cursor
- CursorMan.replaceCursor(_invCursor.getPixels(), _invCursor.w, _invCursor.h,
- _invCursor.w / 2, _invCursor.h / 2, 0);
+ CursorMan.replaceCursor(_invCursor, _invCursor.w / 2, _invCursor.h / 2, 0);
} else {
// Get a pointer to the mouse data to use, and get the cursor hotspot
const byte *srcP = &_vm->_res->CURSORS[cursorId][0];
@@ -106,8 +105,7 @@ void EventsManager::setCursor(CursorType cursorId) {
}
// Set the cursor
- CursorMan.replaceCursor(cursorSurface.getPixels(), CURSOR_WIDTH, CURSOR_HEIGHT,
- hotspotX, hotspotY, 0);
+ CursorMan.replaceCursor(cursorSurface, hotspotX, hotspotY, 0);
// Free the cursor surface
cursorSurface.free();
diff --git a/engines/avalanche/graphics.cpp b/engines/avalanche/graphics.cpp
index 62e9ffefb48..f8e1ec3540b 100644
--- a/engines/avalanche/graphics.cpp
+++ b/engines/avalanche/graphics.cpp
@@ -163,7 +163,7 @@ void GraphicManager::loadMouse(byte which) {
mask.free();
f.close();
- CursorMan.replaceCursor(cursor.getPixels(), 16, 32, kMouseHotSpots[which]._horizontal, kMouseHotSpots[which]._vertical * 2, 255, false);
+ CursorMan.replaceCursor(cursor, kMouseHotSpots[which]._horizontal, kMouseHotSpots[which]._vertical * 2, 255, false);
cursor.free();
}
diff --git a/engines/glk/events.cpp b/engines/glk/events.cpp
index cf0a3c772b4..5d6c6aa9c22 100644
--- a/engines/glk/events.cpp
+++ b/engines/glk/events.cpp
@@ -410,7 +410,7 @@ void Events::setCursor(CursorId cursorId) {
const Surface &s = _cursors[cursorId];
const int TRANSPARENT = s.format.RGBToColor(TRANSPARENT_RGB, TRANSPARENT_RGB, TRANSPARENT_RGB);
- CursorMan.replaceCursor(s.getPixels(), s.w, s.h, s._hotspot.x, s._hotspot.y, TRANSPARENT, true, &s.format);
+ CursorMan.replaceCursor(s, s._hotspot.x, s._hotspot.y, TRANSPARENT, true);
}
_cursorId = cursorId;
diff --git a/engines/hypno/cursors.cpp b/engines/hypno/cursors.cpp
index 6da21b888dd..6291beec966 100644
--- a/engines/hypno/cursors.cpp
+++ b/engines/hypno/cursors.cpp
@@ -153,7 +153,7 @@ void HypnoEngine::changeCursor(const Common::String &cursor, uint32 n, bool cent
Graphics::Surface *entry = decodeFrame(cursor, n, &palette);
uint32 hotspotX = centerCursor ? entry->w / 2 : 0;
uint32 hotspotY = centerCursor ? entry->h / 2 : 0;
- CursorMan.replaceCursor(entry->getPixels(), entry->w, entry->h, hotspotX, hotspotY, 0, false, &_pixelFormat);
+ CursorMan.replaceCursor(*entry, hotspotX, hotspotY, 0, false);
CursorMan.replaceCursorPalette(palette, 0, 256);
entry->free();
delete entry;
@@ -163,7 +163,7 @@ void HypnoEngine::changeCursor(const Common::String &cursor, uint32 n, bool cent
void HypnoEngine::changeCursor(const Graphics::Surface &entry, byte *palette, bool centerCursor) {
uint32 hotspotX = centerCursor ? entry.w / 2 : 0;
uint32 hotspotY = centerCursor ? entry.h / 2 : 0;
- CursorMan.replaceCursor(entry.getPixels(), entry.w, entry.h, hotspotX, hotspotY, 0, false, &_pixelFormat);
+ CursorMan.replaceCursor(entry, hotspotX, hotspotY, 0, false);
CursorMan.replaceCursorPalette(palette, 0, 256);
CursorMan.showMouse(true);
}
diff --git a/engines/mm/mm1/utils/mouse.cpp b/engines/mm/mm1/utils/mouse.cpp
index b99dad2fe40..85d0b2e4b06 100644
--- a/engines/mm/mm1/utils/mouse.cpp
+++ b/engines/mm/mm1/utils/mouse.cpp
@@ -33,7 +33,7 @@ void Mouse::setCursor(int cursorId) {
Shared::Xeen::XSurface cursor;
_sprites.draw(cursor, cursorId, Common::Point(0, 0), Shared::Xeen::SPRFLAG_RESIZE);
- CursorMan.replaceCursor(cursor.getPixels(), cursor.w, cursor.h, 0, 0, 0);
+ CursorMan.replaceCursor(cursor, 0, 0, 0);
showCursor();
}
diff --git a/engines/mm/xeen/events.cpp b/engines/mm/xeen/events.cpp
index ad130361694..160edc45cb0 100644
--- a/engines/mm/xeen/events.cpp
+++ b/engines/mm/xeen/events.cpp
@@ -44,7 +44,7 @@ void EventsManager::setCursor(int cursorId) {
XSurface cursor;
_sprites.draw(cursor, cursorId, Common::Point(0, 0), SPRFLAG_RESIZE);
- CursorMan.replaceCursor(cursor.getPixels(), cursor.w, cursor.h, 0, 0, 0);
+ CursorMan.replaceCursor(cursor, 0, 0, 0);
showCursor();
}
diff --git a/engines/mohawk/cursors.cpp b/engines/mohawk/cursors.cpp
index b1c7f6a9c7d..d37edc82ba2 100644
--- a/engines/mohawk/cursors.cpp
+++ b/engines/mohawk/cursors.cpp
@@ -122,7 +122,7 @@ void MystCursorManager::setCursor(uint16 id) {
} else {
transparentColor = 255;
}
- CursorMan.replaceCursor(surface->getPixels(), surface->w, surface->h, hotspotX, hotspotY, transparentColor);
+ CursorMan.replaceCursor(*surface, hotspotX, hotspotY, transparentColor);
// We're using the screen palette for the original game, but we need
// to use this for any 8bpp cursor in ME.
@@ -130,7 +130,7 @@ void MystCursorManager::setCursor(uint16 id) {
CursorMan.replaceCursorPalette(mhkSurface->getPalette(), 0, 256);
} else {
Graphics::PixelFormat pixelFormat = g_system->getScreenFormat();
- CursorMan.replaceCursor(surface->getPixels(), surface->w, surface->h, hotspotX, hotspotY, pixelFormat.RGBToColor(255, 255, 255), false, &pixelFormat);
+ CursorMan.replaceCursor(*surface, hotspotX, hotspotY, pixelFormat.RGBToColor(255, 255, 255), false);
}
}
diff --git a/engines/nancy/cursor.cpp b/engines/nancy/cursor.cpp
index 7bcfeefc91e..51c1fb25356 100644
--- a/engines/nancy/cursor.cpp
+++ b/engines/nancy/cursor.cpp
@@ -202,7 +202,7 @@ void CursorManager::applyCursor() {
transColor = temp.format.RGBToColor(r, g, b);
}
- CursorMan.replaceCursor(temp.getPixels(), temp.w, temp.h, hotspot.x, hotspot.y, transColor, false, &temp.format);
+ CursorMan.replaceCursor(temp, hotspot.x, hotspot.y, transColor, false);
}
void CursorManager::showCursor(bool shouldShow) {
diff --git a/engines/neverhood/mouse.cpp b/engines/neverhood/mouse.cpp
index fc7eb43b221..1d8678398ad 100644
--- a/engines/neverhood/mouse.cpp
+++ b/engines/neverhood/mouse.cpp
@@ -184,8 +184,7 @@ void Mouse::updateCursor() {
_drawOffset = _mouseCursorResource.getRect();
_surface->drawMouseCursorResource(_mouseCursorResource, _frameNum / 2);
Graphics::Surface *cursorSurface = _surface->getSurface();
- CursorMan.replaceCursor((const byte*)cursorSurface->getPixels(),
- cursorSurface->w, cursorSurface->h, -_drawOffset.x, -_drawOffset.y, 0);
+ CursorMan.replaceCursor(*cursorSurface, -_drawOffset.x, -_drawOffset.y, 0);
}
}
diff --git a/engines/pegasus/cursor.cpp b/engines/pegasus/cursor.cpp
index 25bf2583757..b4c790ff39b 100644
--- a/engines/pegasus/cursor.cpp
+++ b/engines/pegasus/cursor.cpp
@@ -83,9 +83,9 @@ void Cursor::setCurrentFrameIndex(int32 index) {
if (_info[index].surface->format.bytesPerPixel == 1) {
CursorMan.replaceCursorPalette(_info[index].palette, 0, _info[index].colorCount);
- CursorMan.replaceCursor(_info[index].surface->getPixels(), _info[index].surface->w, _info[index].surface->h, _info[index].hotspot.x, _info[index].hotspot.y, 0);
+ CursorMan.replaceCursor(*_info[index].surface, _info[index].hotspot.x, _info[index].hotspot.y, 0);
} else {
- CursorMan.replaceCursor(_info[index].surface->getPixels(), _info[index].surface->w, _info[index].surface->h, _info[index].hotspot.x, _info[index].hotspot.y, _info[index].surface->format.RGBToColor(0xFF, 0xFF, 0xFF), false, &_info[index].surface->format);
+ CursorMan.replaceCursor(*_info[index].surface, _info[index].hotspot.x, _info[index].hotspot.y, _info[index].surface->format.RGBToColor(0xFF, 0xFF, 0xFF), false);
}
}
}
diff --git a/engines/sherlock/events.cpp b/engines/sherlock/events.cpp
index 459dd4a785b..8360066b3d2 100644
--- a/engines/sherlock/events.cpp
+++ b/engines/sherlock/events.cpp
@@ -96,9 +96,9 @@ void Events::setCursor(const Graphics::Surface &src, int hotspotX, int hotspotY)
if (!IS_3DO) {
// PC 8-bit palettized
- CursorMan.replaceCursor(src.getPixels(), src.w, src.h, hotspotX, hotspotY, 0xff);
+ CursorMan.replaceCursor(src, hotspotX, hotspotY, 0xff);
} else if (!_vm->_isScreenDoubled) {
- CursorMan.replaceCursor(src.getPixels(), src.w, src.h, hotspotX, hotspotY, 0x0000, false, &src.format);
+ CursorMan.replaceCursor(src, hotspotX, hotspotY, 0x0000, false);
} else {
Graphics::Surface tempSurface;
tempSurface.create(2 * src.w, 2 * src.h, src.format);
@@ -115,7 +115,7 @@ void Events::setCursor(const Graphics::Surface &src, int hotspotX, int hotspotY)
}
// 3DO RGB565
- CursorMan.replaceCursor(tempSurface.getPixels(), tempSurface.w, tempSurface.h, 2 * hotspotX, 2 * hotspotY, 0x0000, false, &src.format);
+ CursorMan.replaceCursor(tempSurface, 2 * hotspotX, 2 * hotspotY, 0x0000, false);
tempSurface.free();
}
diff --git a/engines/titanic/support/mouse_cursor.cpp b/engines/titanic/support/mouse_cursor.cpp
index bb88ea279f9..bf987d8924e 100644
--- a/engines/titanic/support/mouse_cursor.cpp
+++ b/engines/titanic/support/mouse_cursor.cpp
@@ -151,8 +151,7 @@ void CMouseCursor::setCursor(CursorId cursorId) {
_cursorId = cursorId;
// Set the cursor
- CursorMan.replaceCursor(ce._surface->getPixels(), CURSOR_SIZE, CURSOR_SIZE,
- ce._centroid.x, ce._centroid.y, 0, false, &ce._surface->format);
+ CursorMan.replaceCursor(*ce._surface, ce._centroid.x, ce._centroid.y, 0, false);
}
}
diff --git a/engines/ultima/shared/core/mouse_cursor.cpp b/engines/ultima/shared/core/mouse_cursor.cpp
index 3215aa45713..41fb3605f35 100644
--- a/engines/ultima/shared/core/mouse_cursor.cpp
+++ b/engines/ultima/shared/core/mouse_cursor.cpp
@@ -92,8 +92,7 @@ void MouseCursor::setCursor(int cursorId) {
}
// Pass the generated surface onto the ScummVM cursor manager
- CursorMan.replaceCursor(s.getPixels(), CURSOR_WIDTH, CURSOR_HEIGHT,
- data._hotspot.x, data._hotspot.y, 0xff);
+ CursorMan.replaceCursor(s, data._hotspot.x, data._hotspot.y, 0xff);
}
void MouseCursor::show() {
diff --git a/engines/ultima/ultima4/gfx/screen.cpp b/engines/ultima/ultima4/gfx/screen.cpp
index c14b6f840a1..ece26fe20eb 100644
--- a/engines/ultima/ultima4/gfx/screen.cpp
+++ b/engines/ultima/ultima4/gfx/screen.cpp
@@ -158,9 +158,7 @@ void Screen::loadMouseCursors() {
// Set the default initial cursor
const uint TRANSPARENT = format.RGBToColor(0x80, 0x80, 0x80);
MouseCursorSurface *c = _mouseCursors[MC_DEFAULT];
- CursorMan.pushCursor(c->getPixels(),
- MOUSE_CURSOR_SIZE, MOUSE_CURSOR_SIZE,
- c->_hotspot.x, c->_hotspot.y, TRANSPARENT, false, &format);
+ CursorMan.pushCursor(*c, c->_hotspot.x, c->_hotspot.y, TRANSPARENT, false);
CursorMan.showMouse(true);
} else {
@@ -179,8 +177,7 @@ void Screen::setMouseCursor(MouseCursor cursor) {
_currentMouseCursor = cursor;
const uint TRANSPARENT = format.RGBToColor(0x80, 0x80, 0x80);
- CursorMan.replaceCursor(c->getPixels(), MOUSE_CURSOR_SIZE, MOUSE_CURSOR_SIZE,
- c->_hotspot.x, c->_hotspot.y, TRANSPARENT, false, &format);
+ CursorMan.replaceCursor(*c, c->_hotspot.x, c->_hotspot.y, TRANSPARENT, false);
}
}
Commit: d9a5de0fe6c156e4bc92799a2e4f9d67a23694cc
https://github.com/scummvm/scummvm/commit/d9a5de0fe6c156e4bc92799a2e4f9d67a23694cc
Author: Miro Kropacek (miro.kropacek at gmail.com)
Date: 2023-07-19T22:22:11+02:00
Commit Message:
BACKEND: ATARI: Screen shaking and some fixes
- surface setup for optimized 4-bit C2P routine wasn't properly detected
- STFA pretends to support Falcon sampling frequencies on TT leading to
suboptimal sample mixing
- delayMillis() should check also for other events (fixes Future Wars)
but avoid doing it for SCI as its MIDI timer would call itself in a
recursive loop
- SuperVidel doesn't need to use VsetScreen() in VBL anymore
- Wetlands, Teen Agent, Shivers and Private Eye need non-aligned
surface widths
- However Wetlands and Private Eye use setCursorPalette, see
https://bugs.scummvm.org/ticket/14524
- Added warning for Phantasmagoria's 630x450, nothing can be done there
as the game also requires non-aligned surfaces and at the same time
the buffer has to be aligned on 16 bytes.
- BDF scaling disabled by default
Changed paths:
backends/graphics/atari/atari-graphics-supervidel.h
backends/graphics/atari/atari-graphics-videl.h
backends/graphics/atari/atari-graphics.cpp
backends/graphics/atari/atari-graphics.h
backends/mixer/atari/atari-mixer.cpp
backends/platform/atari/osystem_atari.cpp
backends/platform/atari/osystem_atari.h
backends/platform/atari/readme.txt
diff --git a/backends/graphics/atari/atari-graphics-supervidel.h b/backends/graphics/atari/atari-graphics-supervidel.h
index 25bcc01a179..afa1026b725 100644
--- a/backends/graphics/atari/atari-graphics-supervidel.h
+++ b/backends/graphics/atari/atari-graphics-supervidel.h
@@ -80,6 +80,10 @@ private:
return [](void *ptr) { Mfree((uintptr)ptr & 0x00FFFFFF); };
}
+ Common::Rect alignRect(int x, int y, int w, int h) const override {
+ return Common::Rect(x, y, x + w, y + h);
+ }
+
static long hasSvRamBoosted() {
register long ret __asm__ ("d0") = 0;
diff --git a/backends/graphics/atari/atari-graphics-videl.h b/backends/graphics/atari/atari-graphics-videl.h
index 72832d8746a..3da10048576 100644
--- a/backends/graphics/atari/atari-graphics-videl.h
+++ b/backends/graphics/atari/atari-graphics-videl.h
@@ -64,28 +64,25 @@ public:
}
private:
- void copyRectToSurface(Graphics::Surface &dstSurface,
- const Graphics::Surface &srcSurface, int destX, int destY,
+ void copyRectToSurface(Graphics::Surface &dstSurface, int dstBitsPerPixel, const Graphics::Surface &srcSurface,
+ int destX, int destY,
const Common::Rect &subRect) const override {
// '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);
+ const byte *pChunky = (const byte *)srcSurface.getBasePtr(subRect.left, subRect.top);
+ const byte *pChunkyEnd = (const byte *)srcSurface.getBasePtr(subRect.right, subRect.bottom-1);
- const uint32 bitsPerPixel = dstSurface.format.isCLUT8() || dstSurface.format == PIXELFORMAT_RGB332 ? 8 : 4;
- const uint32 screenPitch = dstSurface.pitch * bitsPerPixel/8;
+ byte *pScreen = (byte *)dstSurface.getPixels() + destY * dstSurface.pitch + destX * dstBitsPerPixel/8;
- byte *pScreen = (byte *)dstSurface.getPixels() + destY * screenPitch + destX * bitsPerPixel/8;
-
- if (bitsPerPixel == 8) {
+ if (dstBitsPerPixel == 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, screenPitch);
+ asm_c2p1x1_8_tt(pChunky, pChunkyEnd, pScreen, dstSurface.pitch);
return;
}
}
@@ -95,10 +92,9 @@ private:
subRect.width(),
srcSurface.pitch,
pScreen,
- screenPitch);
+ dstSurface.pitch);
} else {
- // compare unmodified dst pitch
- if (srcSurface.pitch == subRect.width() && srcSurface.pitch == dstSurface.pitch) {
+ if (srcSurface.pitch == subRect.width() && srcSurface.pitch/2 == dstSurface.pitch) {
asm_c2p1x1_4(pChunky, pChunkyEnd, pScreen);
return;
}
@@ -108,23 +104,15 @@ private:
subRect.width(),
srcSurface.pitch,
pScreen,
- screenPitch);
+ dstSurface.pitch);
}
}
- void copyRectToSurfaceWithKey(Graphics::Surface &dstSurface, const Graphics::Surface &srcSurface,
- int destX, int destY, const Common::Rect &subRect, uint32 key,
+ void copyRectToSurfaceWithKey(Graphics::Surface &dstSurface, int dstBitsPerPixel, const Graphics::Surface &srcSurface,
+ int destX, int destY,
+ const Common::Rect &subRect, uint32 key,
const Graphics::Surface &bgSurface, const byte srcPalette[256*3]) const override {
- Common::Rect backgroundRect(destX, destY, destX + subRect.width(), destY + subRect.height());
-
- // ensure that background's left and right lie on a 16px boundary and double the width if needed
- backgroundRect.moveTo(backgroundRect.left & 0xfff0, backgroundRect.top);
-
- const int deltaX = destX - backgroundRect.left;
-
- backgroundRect.right = (backgroundRect.right + deltaX + 15) & 0xfff0;
- if (backgroundRect.right > bgSurface.w)
- backgroundRect.right = bgSurface.w;
+ const Common::Rect backgroundRect = alignRect(destX, destY, subRect.width(), subRect.height());
static Graphics::Surface cachedSurface;
@@ -141,14 +129,17 @@ private:
cachedSurface.copyRectToSurface(bgSurface, 0, 0, backgroundRect);
// copy cursor
- convertRectToSurfaceWithKey(cachedSurface, srcSurface, deltaX, 0, subRect, key, srcPalette);
+ convertRectToSurfaceWithKey(cachedSurface, srcSurface, destX - backgroundRect.left, 0, subRect, key, srcPalette);
copyRectToSurface(
- dstSurface,
- cachedSurface,
+ dstSurface, dstBitsPerPixel, cachedSurface,
backgroundRect.left, backgroundRect.top,
Common::Rect(cachedSurface.w, cachedSurface.h));
}
+
+ Common::Rect alignRect(int x, int y, int w, int h) const override {
+ return Common::Rect(x & 0xfff0, y, (x + w + 15) & 0xfff0, y + h);
+ }
};
#endif
diff --git a/backends/graphics/atari/atari-graphics.cpp b/backends/graphics/atari/atari-graphics.cpp
index 9778277f714..14722fc7d7b 100644
--- a/backends/graphics/atari/atari-graphics.cpp
+++ b/backends/graphics/atari/atari-graphics.cpp
@@ -42,27 +42,51 @@
#define SCREEN_ACTIVE
+#define MAX_HZ_SHAKE 16 // Falcon only
+#define MAX_V_SHAKE 16
+
bool g_unalignedPitch = false;
-// this is how screenptr should have been handled in TOS...
-#undef screenptr
-static volatile uintptr screenptr;
+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 bool s_tt;
+static int s_shakeXOffset;
+static int s_shakeYOffset;
+
+static Graphics::Surface *s_screenSurf;
static void VblHandler() {
- if (screenptr) {
+ if (s_screenSurf) {
#ifdef SCREEN_ACTIVE
- if (hasSuperVidel()) {
- // SuperVidel's XBIOS seems to switch to Super mode with BS8C...
- VsetScreen(SCR_NOCHANGE, screenptr, SCR_NOCHANGE, SCR_NOCHANGE);
- } else {
- union { byte c[4]; uintptr p; } sptr;
- sptr.p = screenptr;
+ const int bitsPerPixel = (s_screenSurf->format == PIXELFORMAT_RGB121 ? 4 : 8);
+ uintptr p = (uintptr)s_screenSurf->getBasePtr(0, MAX_V_SHAKE + s_shakeYOffset);
+
+ if (!s_tt) {
+ s_shakeXOffset = -s_shakeXOffset;
- *((volatile byte *)0xFFFF8201) = sptr.c[1];
- *((volatile byte *)0xFFFF8203) = sptr.c[2];
- *((volatile byte *)0xFFFF820D) = sptr.c[3];
+ if (s_shakeXOffset >= 0) {
+ p += MAX_HZ_SHAKE;
+ *((volatile char *)0xFFFF8265) = s_shakeXOffset;
+ } else {
+ *((volatile char *)0xFFFF8265) = MAX_HZ_SHAKE + s_shakeXOffset;
+ }
+
+ // subtract 4 or 8 words if scrolling
+ *((volatile short *)0xFFFF820E) = s_shakeXOffset == 0
+ ? (2 * MAX_HZ_SHAKE * bitsPerPixel / 8) / 2
+ : (2 * MAX_HZ_SHAKE * bitsPerPixel / 8) / 2 - bitsPerPixel;
}
+
+
+ union { byte c[4]; uintptr p; } sptr;
+ sptr.p = p;
+
+ *((volatile byte *)0xFFFF8201) = sptr.c[1];
+ *((volatile byte *)0xFFFF8203) = sptr.c[2];
+ *((volatile byte *)0xFFFF820D) = sptr.c[3];
#endif
- screenptr = 0;
+ s_screenSurf = nullptr;
}
}
@@ -132,10 +156,14 @@ AtariGraphicsManager::AtariGraphicsManager() {
vdo >>= 16;
_tt = (vdo == VDO_TT);
+ s_tt = _tt;
if (!_tt)
_vgaMonitor = VgetMonitor() == MON_VGA;
+ // no BDF scaling please
+ ConfMan.registerDefault("gui_disable_fixed_font_scaling", true);
+
// make the standard GUI renderer default (!DISABLE_FANCY_THEMES implies anti-aliased rendering in ThemeEngine.cpp)
// (and without DISABLE_FANCY_THEMES we can't use 640x480 themes)
const char *standardThemeEngineName = GUI::ThemeEngine::findModeConfigName(GUI::ThemeEngine::kGfxStandard);
@@ -148,7 +176,6 @@ AtariGraphicsManager::AtariGraphicsManager() {
#ifndef DISABLE_FANCY_THEMES
// make "themes" the default theme path
- ConfMan.registerDefault("themepath", "themes");
if (!ConfMan.hasKey("themepath"))
ConfMan.set("themepath", "themes");
#endif
@@ -276,6 +303,11 @@ OSystem::TransactionError AtariGraphicsManager::endGFXTransaction() {
if (_pendingState.width > getMaximumScreenWidth() || _pendingState.height > getMaximumScreenHeight())
error |= OSystem::TransactionError::kTransactionSizeChangeFailed;
+ if (_pendingState.width % 16 != 0 && !hasSuperVidel()) {
+ warning("Requested width not divisible by 16, please report");
+ error |= OSystem::TransactionError::kTransactionSizeChangeFailed;
+ }
+
if (error != OSystem::TransactionError::kTransactionSuccess) {
warning("endGFXTransaction failed: %02x", (int)error);
// all our errors are fatal but engine.cpp takes only this one seriously
@@ -289,10 +321,12 @@ OSystem::TransactionError AtariGraphicsManager::endGFXTransaction() {
_screen[FRONT_BUFFER]->reset(_pendingState.width, _pendingState.height, 8);
_screen[BACK_BUFFER1]->reset(_pendingState.width, _pendingState.height, 8);
_screen[BACK_BUFFER2]->reset(_pendingState.width, _pendingState.height, 8);
- screenptr = 0;
-
_workScreen = _screen[_pendingState.mode <= GraphicsMode::SingleBuffering ? FRONT_BUFFER : BACK_BUFFER1];
+ s_screenSurf = nullptr;
+ s_shakeXOffset = 0;
+ s_shakeYOffset = 0;
+
// in case of resolution change from GUI
if (_oldWorkScreen)
_oldWorkScreen = _workScreen;
@@ -364,17 +398,21 @@ void AtariGraphicsManager::copyRectToScreen(const void *buf, int pitch, int x, i
//debug("copyRectToScreen: %d, %d, %d(%d), %d", x, y, w, pitch, h);
Graphics::Surface &dstSurface = *lockScreen();
- const Common::Rect rect = Common::Rect(x, y, x + w, y + h);
- dstSurface.copyRectToSurface(buf, pitch, x, y, w, h);
+ const Common::Rect rect = alignRect(x, y, w, h);
_workScreen->addDirtyRect(dstSurface, rect);
+ if (_currentState.mode == GraphicsMode::TripleBuffering) {
+ _screen[BACK_BUFFER2]->addDirtyRect(dstSurface, rect);
+ _screen[FRONT_BUFFER]->addDirtyRect(dstSurface, rect);
+ }
+
+ // no need to align so far...
+ dstSurface.copyRectToSurface(buf, pitch, x, y, w, h);
+
if (_currentState.mode == GraphicsMode::DirectRendering) {
// TODO: c2p with 16pix align
updateScreen();
- } else if (_currentState.mode == GraphicsMode::TripleBuffering) {
- _screen[BACK_BUFFER2]->addDirtyRect(dstSurface, rect);
- _screen[FRONT_BUFFER]->addDirtyRect(dstSurface, rect);
}
}
@@ -395,16 +433,16 @@ void AtariGraphicsManager::unlockScreen() {
//debug("unlockScreen: %d x %d", _workScreen->surf.w, _workScreen->surf.h);
const Graphics::Surface &dstSurface = *lockScreen();
- const Common::Rect rect = Common::Rect(dstSurface.w, dstSurface.h);
+ const Common::Rect rect = alignRect(0, 0, dstSurface.w, dstSurface.h);
_workScreen->addDirtyRect(dstSurface, rect);
- if (_currentState.mode == GraphicsMode::DirectRendering)
- updateScreen();
- else if (_currentState.mode == GraphicsMode::TripleBuffering) {
+ if (_currentState.mode == GraphicsMode::TripleBuffering) {
_screen[BACK_BUFFER2]->addDirtyRect(dstSurface, rect);
_screen[FRONT_BUFFER]->addDirtyRect(dstSurface, rect);
}
+
+ updateScreen();
}
void AtariGraphicsManager::fillScreen(uint32 col) {
@@ -427,10 +465,16 @@ void AtariGraphicsManager::updateScreen() {
// 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.
- Common::String engineId = activeDomain->getValOrDefault("engineid");
- if (engineId == "parallaction"
+ const Common::String engineId = activeDomain->getValOrDefault("engineid");
+ const Common::String gameId = activeDomain->getValOrDefault("gameid");
+ if (engineId == "hypno"
|| engineId == "mohawk"
+ || engineId == "parallaction"
+ || engineId == "private"
+ || (engineId == "sci"
+ && (gameId == "phantasmagoria" || gameId == "shivers"))
|| engineId == "sherlock"
+ || engineId == "teenagent"
|| engineId == "tsage") {
g_unalignedPitch = true;
}
@@ -446,29 +490,40 @@ void AtariGraphicsManager::updateScreen() {
if (isOverlayVisible()) {
assert(_workScreen == _screen[OVERLAY_BUFFER]);
- screenUpdated = updateScreenInternal(_overlaySurface);
+ screenUpdated = updateScreenInternal<false>(_overlaySurface);
} else {
switch (_currentState.mode) {
case GraphicsMode::DirectRendering:
assert(_workScreen == _screen[FRONT_BUFFER]);
- screenUpdated = updateScreenInternal(Graphics::Surface());
+ screenUpdated = updateScreenInternal<true>(Graphics::Surface());
break;
case GraphicsMode::SingleBuffering:
assert(_workScreen == _screen[FRONT_BUFFER]);
- screenUpdated = updateScreenInternal(_chunkySurface);
+ screenUpdated = updateScreenInternal<false>(_chunkySurface);
break;
case GraphicsMode::TripleBuffering:
assert(_workScreen == _screen[BACK_BUFFER1]);
- screenUpdated = updateScreenInternal(_chunkySurface);
+ screenUpdated = updateScreenInternal<false>(_chunkySurface);
break;
}
}
_workScreen->clearDirtyRects();
+#ifdef SCREEN_ACTIVE
+ // first change video mode so we can modify video regs later
+ if (_pendingScreenChange & kPendingScreenChangeMode) {
+ if (_workScreen->rez != -1) {
+ // unfortunately this reinitializes VDI, too
+ Setscreen(SCR_NOCHANGE, SCR_NOCHANGE, _workScreen->rez);
+ } else if (_workScreen->mode != -1) {
+ VsetMode(_workScreen->mode);
+ }
+ }
+
if (_pendingScreenChange & kPendingScreenChangeScreen) {
- // can't call (V)SetScreen without Vsync()
- screenptr = (uintptr)(isOverlayVisible() ? _workScreen->surf.getPixels() : _screen[FRONT_BUFFER]->surf.getPixels());
+ // calling (V)SetScreen without Vsync() is dangerous (at least on Falcon)
+ s_screenSurf = isOverlayVisible() ? &_screen[OVERLAY_BUFFER]->surf : &_screen[FRONT_BUFFER]->surf;
} else if (screenUpdated && !isOverlayVisible() && _currentState.mode == GraphicsMode::TripleBuffering) {
// Triple buffer:
// - alternate BACK_BUFFER1 and BACK_BUFFER2
@@ -498,7 +553,7 @@ void AtariGraphicsManager::updateScreen() {
_screen[BACK_BUFFER2] = tmp;
// queue BACK_BUFFER2 with the most recent frame content
- screenptr = (uintptr)_screen[BACK_BUFFER2]->surf.getPixels();
+ s_screenSurf = &_screen[BACK_BUFFER2]->surf;
set_sysvar_to_short(vblsem, 1); // unlock vbl
@@ -507,19 +562,6 @@ void AtariGraphicsManager::updateScreen() {
// FRONT_BUFFER is displayed and still contains previously finished frame
}
-#ifdef SCREEN_ACTIVE
- if (_pendingScreenChange & kPendingScreenChangeMode) {
- // Avoid changing video registers in the middle of rendering...
- Vsync();
-
- if (_workScreen->rez != -1) {
- // unfortunately this reinitializes VDI, too
- Setscreen(SCR_NOCHANGE, SCR_NOCHANGE, _workScreen->rez);
- } else if (_workScreen->mode != -1) {
- VsetMode(_workScreen->mode);
- }
- }
-
if (_pendingScreenChange & kPendingScreenChangePalette) {
if (_tt)
EsetPalette(0, isOverlayVisible() ? getOverlayPaletteSize() : 256, _workScreen->palette->tt);
@@ -562,7 +604,18 @@ void AtariGraphicsManager::updateScreen() {
}
void AtariGraphicsManager::setShakePos(int shakeXOffset, int shakeYOffset) {
- debug("setShakePos: %d, %d", shakeXOffset, shakeYOffset);
+ //debug("setShakePos: %d, %d", shakeXOffset, shakeYOffset);
+
+ if (_tt) {
+ // as TT can't horizontally shake anything, do it at least vertically
+ s_shakeYOffset = (shakeYOffset == 0 && shakeXOffset != 0) ? shakeXOffset : shakeYOffset;
+ } else {
+ s_shakeXOffset = shakeXOffset;
+ s_shakeYOffset = shakeYOffset;
+ }
+
+ _pendingScreenChange |= kPendingScreenChangeScreen;
+ updateScreen();
}
void AtariGraphicsManager::showOverlay(bool inGUI) {
@@ -585,7 +638,7 @@ void AtariGraphicsManager::showOverlay(bool inGUI) {
_workScreen = _screen[OVERLAY_BUFFER];
// do not cache dirtyRects and oldCursorRect
- int bitsPerPixel = getOverlayFormat().isCLUT8() || getOverlayFormat() == PIXELFORMAT_RGB332 ? 8 : 4;
+ const int bitsPerPixel = getBitsPerPixel(getOverlayFormat());
_workScreen->reset(getOverlayWidth(), getOverlayHeight(), bitsPerPixel);
_pendingScreenChange = kPendingScreenChangeMode | kPendingScreenChangeScreen | kPendingScreenChangePalette;
@@ -615,6 +668,14 @@ void AtariGraphicsManager::hideOverlay() {
updateScreen();
}
+Graphics::PixelFormat AtariGraphicsManager::getOverlayFormat() const {
+#ifndef DISABLE_FANCY_THEMES
+ return _tt ? PIXELFORMAT_RGB121 : PIXELFORMAT_RGB332;
+#else
+ return PIXELFORMAT_RGB121;
+#endif
+}
+
void AtariGraphicsManager::clearOverlay() {
debug("clearOverlay");
@@ -625,15 +686,15 @@ void AtariGraphicsManager::clearOverlay() {
const Graphics::Surface &sourceSurface =
_currentState.mode == GraphicsMode::DirectRendering ? *_screen[FRONT_BUFFER]->offsettedSurf : _chunkySurface;
- bool upscale = _overlaySurface.w / sourceSurface.w >= 2 && _overlaySurface.h / sourceSurface.h >= 2;
+ const bool upscale = _overlaySurface.w / sourceSurface.w >= 2 && _overlaySurface.h / sourceSurface.h >= 2;
- int w = upscale ? sourceSurface.w * 2 : sourceSurface.w;
- int h = upscale ? sourceSurface.h * 2 : sourceSurface.h;
+ const int w = upscale ? sourceSurface.w * 2 : sourceSurface.w;
+ const int h = upscale ? sourceSurface.h * 2 : sourceSurface.h;
- int hzOffset = (_overlaySurface.w - w) / 2;
- int vOffset = (_overlaySurface.h - h) / 2;
+ const int hzOffset = (_overlaySurface.w - w) / 2;
+ const int vOffset = (_overlaySurface.h - h) / 2;
- int pitch = hzOffset * 2 + (upscale ? _overlaySurface.pitch : 0);
+ const int pitch = hzOffset * 2 + (upscale ? _overlaySurface.pitch : 0);
// Transpose from game palette to RGB332/RGB121 (overlay palette)
const byte *src = (const byte*)sourceSurface.getPixels();
@@ -641,11 +702,11 @@ void AtariGraphicsManager::clearOverlay() {
// for TT: 8/4/0 + (xLoss - 4) + xShift
static const int rShift = (_tt ? (8 - 4) : 0)
- + _overlaySurface.format.rLoss - _overlaySurface.format.rShift;
+ + _overlaySurface.format.rLoss - _overlaySurface.format.rShift;
static const int gShift = (_tt ? (4 - 4) : 0)
- + _overlaySurface.format.gLoss - _overlaySurface.format.gShift;
+ + _overlaySurface.format.gLoss - _overlaySurface.format.gShift;
static const int bShift = (_tt ? (0 - 4) : 0)
- + _overlaySurface.format.bLoss - _overlaySurface.format.bShift;
+ + _overlaySurface.format.bLoss - _overlaySurface.format.bShift;
static const int rMask = _overlaySurface.format.rMax() << _overlaySurface.format.rShift;
static const int gMask = _overlaySurface.format.gMax() << _overlaySurface.format.gShift;
@@ -717,8 +778,12 @@ void AtariGraphicsManager::grabOverlay(Graphics::Surface &surface) const {
void AtariGraphicsManager::copyRectToOverlay(const void *buf, int pitch, int x, int y, int w, int h) {
//debug("copyRectToOverlay: %d, %d, %d(%d), %d", x, y, w, pitch, h);
- _overlaySurface.copyRectToSurface(buf, pitch, x, y, w, h);
- _screen[OVERLAY_BUFFER]->addDirtyRect(_overlaySurface, Common::Rect(x, y, x + w, y + h));
+ Graphics::Surface *dstSurface = lockScreen();
+
+ const Common::Rect rect = alignRect(x, y, w, h);
+ _workScreen->addDirtyRect(*dstSurface, rect);
+
+ dstSurface->copyRectToSurface(buf, pitch, x, y, w, h);
}
bool AtariGraphicsManager::showMouse(bool visible) {
@@ -868,8 +933,13 @@ void AtariGraphicsManager::convertRectToSurfaceWithKey(Graphics::Surface &dstSur
}
}
+int AtariGraphicsManager::getBitsPerPixel(const Graphics::PixelFormat &format) const {
+ return format == PIXELFORMAT_RGB121 ? 4 : 8;
+}
+
+template <bool directRendering> // hopefully compiler optimizes all the branching out
bool AtariGraphicsManager::updateScreenInternal(const Graphics::Surface &srcSurface) {
- //debug("updateScreenInternal: %d", (int)dirtyRects.size());
+ //debug("updateScreenInternal");
const DirtyRects &dirtyRects = _workScreen->dirtyRects;
Graphics::Surface *dstSurface = _workScreen->offsettedSurf;
@@ -878,12 +948,8 @@ bool AtariGraphicsManager::updateScreenInternal(const Graphics::Surface &srcSurf
bool &cursorVisibilityChanged = _workScreen->cursorVisibilityChanged;
Common::Rect &oldCursorRect = _workScreen->oldCursorRect;
const bool &fullRedraw = _workScreen->fullRedraw;
-#ifndef DISABLE_FANCY_THEMES
- const bool directRendering = !isOverlayVisible() && _currentState.mode == GraphicsMode::DirectRendering;
-#else
- // hopefully compiler optimizes all the branching out
- const bool directRendering = false;
-#endif
+
+ const int dstBitsPerPixel = getBitsPerPixel(dstSurface->format);
bool updated = false;
@@ -906,7 +972,7 @@ bool AtariGraphicsManager::updateScreenInternal(const Graphics::Surface &srcSurf
restoreCursor = !it->contains(oldCursorRect);
if (!directRendering) {
- copyRectToSurface(*dstSurface, srcSurface, it->left, it->top, *it);
+ copyRectToSurface(*dstSurface, dstBitsPerPixel, srcSurface, it->left, it->top, *it);
updated = true;
} else if (!oldCursorRect.isEmpty()) {
const Common::Rect intersectingRect = it->findIntersectingRect(oldCursorRect);
@@ -932,12 +998,12 @@ bool AtariGraphicsManager::updateScreenInternal(const Graphics::Surface &srcSurf
oldCursorRect.right = (oldCursorRect.right + 15) & 0xfff0;
copyRectToSurface(
- *dstSurface, srcSurface,
+ *dstSurface, dstBitsPerPixel, srcSurface,
oldCursorRect.left, oldCursorRect.top,
oldCursorRect);
} else {
copyRectToSurface(
- *dstSurface, cachedCursorSurface,
+ *dstSurface, dstBitsPerPixel, cachedCursorSurface,
oldCursorRect.left, oldCursorRect.top,
Common::Rect(oldCursorRect.width(), oldCursorRect.height()));
}
@@ -962,7 +1028,7 @@ bool AtariGraphicsManager::updateScreenInternal(const Graphics::Surface &srcSurf
}
copyRectToSurfaceWithKey(
- *dstSurface, _cursor.surface,
+ *dstSurface, dstBitsPerPixel, _cursor.surface,
_cursor.dstRect.left, _cursor.dstRect.top,
_cursor.srcRect,
_cursor.keycolor,
@@ -985,7 +1051,12 @@ AtariGraphicsManager::Screen::Screen(AtariGraphicsManager *manager, int width, i
palette = palette_;
- surf.init(width, height, width * format.bytesPerPixel, nullptr, format);
+ width += (_manager->_tt ? 0 : 2 * MAX_HZ_SHAKE);
+ height += 2 * MAX_V_SHAKE;
+
+ const int bitsPerPixel = _manager->getBitsPerPixel(format);
+
+ surf.init(width, height, width * bitsPerPixel / 8, nullptr, format);
void *pixelsUnaligned = allocFunc(sizeof(uintptr) + (surf.h * surf.pitch) + ALIGN - 1);
if (!pixelsUnaligned) {
@@ -999,7 +1070,7 @@ AtariGraphicsManager::Screen::Screen(AtariGraphicsManager *manager, int width, i
memset(surf.getPixels(), 0, surf.h * surf.pitch);
- _offsettedSurf.init(surf.w, surf.h, surf.pitch, surf.getPixels(), surf.format);
+ _offsettedSurf.init(surf.w, surf.h, surf.pitch, surf.getBasePtr(_manager->_tt ? 0 : MAX_HZ_SHAKE, MAX_V_SHAKE), surf.format);
}
AtariGraphicsManager::Screen::~Screen() {
@@ -1018,18 +1089,18 @@ void AtariGraphicsManager::Screen::reset(int width, int height, int bitsPerPixel
mode = -1;
// erase old screen
- surf.fillRect(Common::Rect(surf.w, surf.h), 0);
+ _offsettedSurf.fillRect(Common::Rect(_offsettedSurf.w, _offsettedSurf.h), 0);
if (_manager->_tt) {
if (width <= 320 && height <= 240) {
surf.w = 320;
- surf.h = 240;
- surf.pitch = 2*surf.w;
+ surf.h = 240 + 2 * MAX_V_SHAKE;
+ surf.pitch = 2 * surf.w * bitsPerPixel / 8;
rez = kRezValueTTLow;
} else {
surf.w = 640;
- surf.h = 480;
- surf.pitch = surf.w;
+ surf.h = 480 + 2 * MAX_V_SHAKE;
+ surf.pitch = surf.w * bitsPerPixel / 8;
rez = kRezValueTTMid;
}
} else {
@@ -1048,7 +1119,7 @@ void AtariGraphicsManager::Screen::reset(int width, int height, int bitsPerPixel
mode |= COL80;
}
} else {
- mode |= TV | BPS8;
+ mode |= TV | (bitsPerPixel == 4 ? BPS4 : BPS8);
if (width <= 320 && height <= 200) {
surf.w = 320;
@@ -1069,20 +1140,21 @@ void AtariGraphicsManager::Screen::reset(int width, int height, int bitsPerPixel
}
}
- surf.pitch = surf.w;
+ 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.init(
+ width, height, surf.pitch,
+ surf.getBasePtr((surf.w - width) / 2, (surf.h - height) / 2),
+ surf.format);
}
-void AtariGraphicsManager::Screen::addDirtyRect(const Graphics::Surface &srcSurface, Common::Rect rect) {
+void AtariGraphicsManager::Screen::addDirtyRect(const Graphics::Surface &srcSurface, const Common::Rect &rect) {
if (fullRedraw)
return;
- // align on 16px (i.e. 16 bytes -> optimize for C2P, MOVE16 or just 16-byte cache lines)
- rect.left &= 0xfff0;
- rect.right = (rect.right + 15) & 0xfff0;
-
if ((rect.width() == srcSurface.w && rect.height() == srcSurface.h)
|| dirtyRects.size() == 128) { // 320x200 can hold at most 250 16x16 rectangles
//debug("addDirtyRect[%d]: purge %d x %d", (int)dirtyRects.size(), srcSurface.w, srcSurface.h);
@@ -1094,7 +1166,7 @@ void AtariGraphicsManager::Screen::addDirtyRect(const Graphics::Surface &srcSurf
return;
}
- dirtyRects.emplace(std::move(rect));
+ dirtyRects.insert(rect);
}
void AtariGraphicsManager::Cursor::update(const Graphics::Surface &screen, bool isModified) {
diff --git a/backends/graphics/atari/atari-graphics.h b/backends/graphics/atari/atari-graphics.h
index 17e465f08cf..5f9d56d8783 100644
--- a/backends/graphics/atari/atari-graphics.h
+++ b/backends/graphics/atari/atari-graphics.h
@@ -79,13 +79,7 @@ public:
void showOverlay(bool inGUI) override;
void hideOverlay() override;
bool isOverlayVisible() const override { return _overlayVisible; }
- Graphics::PixelFormat getOverlayFormat() const override {
-#ifndef DISABLE_FANCY_THEMES
- return _tt ? PIXELFORMAT_RGB121 : PIXELFORMAT_RGB332;
-#else
- return PIXELFORMAT_RGB121;
-#endif
- }
+ Graphics::PixelFormat getOverlayFormat() const override;
void clearOverlay() override;
void grabOverlay(Graphics::Surface &surface) const override;
void copyRectToOverlay(const void *buf, int pitch, int x, int y, int w, int h) override;
@@ -105,10 +99,6 @@ public:
Common::Keymap *getKeymap() const;
protected:
- const Graphics::PixelFormat PIXELFORMAT_CLUT8 = Graphics::PixelFormat::createFormatCLUT8();
- const Graphics::PixelFormat PIXELFORMAT_RGB332 = Graphics::PixelFormat(1, 3, 3, 2, 0, 5, 2, 0, 0);
- const Graphics::PixelFormat PIXELFORMAT_RGB121 = Graphics::PixelFormat(1, 1, 2, 1, 0, 3, 1, 0, 0);
-
typedef void* (*AtariMemAlloc)(size_t bytes);
typedef void (*AtariMemFree)(void *ptr);
@@ -157,8 +147,11 @@ private:
int16 getMaximumScreenHeight() const { return 480; }
int16 getMaximumScreenWidth() const { return _tt ? 320 : (_vgaMonitor ? 640 : 640*1.2); }
+ template <bool directRendering>
bool updateScreenInternal(const Graphics::Surface &srcSurface);
+ inline int getBitsPerPixel(const Graphics::PixelFormat &format) const;
+
virtual AtariMemAlloc getStRamAllocFunc() const {
return [](size_t bytes) { return (void*)Mxalloc(bytes, MX_STRAM); };
}
@@ -166,17 +159,20 @@ private:
return [](void *ptr) { Mfree(ptr); };
}
- virtual void copyRectToSurface(Graphics::Surface &dstSurface,
- const Graphics::Surface &srcSurface, int destX, int destY,
+ virtual void copyRectToSurface(Graphics::Surface &dstSurface, int dstBitsPerPixel, const Graphics::Surface &srcSurface,
+ int destX, int destY,
const Common::Rect &subRect) const {
dstSurface.copyRectToSurface(srcSurface, destX, destY, subRect);
}
- virtual void copyRectToSurfaceWithKey(Graphics::Surface &dstSurface, const Graphics::Surface &srcSurface,
- int destX, int destY, const Common::Rect &subRect, uint32 key,
+ virtual void copyRectToSurfaceWithKey(Graphics::Surface &dstSurface, int dstBitsPerPixel, const Graphics::Surface &srcSurface,
+ int destX, int destY,
+ const Common::Rect &subRect, uint32 key,
const Graphics::Surface &bgSurface, const byte srcPalette[256*3]) const {
convertRectToSurfaceWithKey(dstSurface, srcSurface, destX, destY, subRect, key, srcPalette);
}
+ virtual Common::Rect alignRect(int x, int y, int w, int h) const = 0;
+
void cursorPositionChanged() {
if (_overlayVisible) {
_screen[OVERLAY_BUFFER]->cursorPositionChanged = true;
@@ -259,7 +255,8 @@ private:
~Screen();
void reset(int width, int height, int bitsPerPixel);
- void addDirtyRect(const Graphics::Surface &srcSurface, Common::Rect rect);
+ // must be called before any rectangle drawing
+ void addDirtyRect(const Graphics::Surface &srcSurface, const Common::Rect &rect);
void clearDirtyRects() {
dirtyRects.clear();
diff --git a/backends/mixer/atari/atari-mixer.cpp b/backends/mixer/atari/atari-mixer.cpp
index e6a07cc127a..b7009e5547c 100644
--- a/backends/mixer/atari/atari-mixer.cpp
+++ b/backends/mixer/atari/atari-mixer.cpp
@@ -66,7 +66,7 @@ AtariMixerManager::~AtariMixerManager() {
}
void AtariMixerManager::init() {
- long cookie;
+ long cookie, stfa = 0;
bool useDevconnectReturnValue = Getcookie(C__SND, &cookie) == C_FOUND && (cookie & SND_EXT) != 0;
int clk;
@@ -75,9 +75,62 @@ void AtariMixerManager::init() {
error("Sound system is locked");
// try XBIOS APIs which do not set SND_EXT in _SND
- useDevconnectReturnValue |= (Getcookie(C_STFA, &cookie) == C_FOUND); // STFA
+ useDevconnectReturnValue |= (Getcookie(C_STFA, &stfa) == C_FOUND); // STFA
useDevconnectReturnValue |= (Getcookie(C_McSn, &cookie) == C_FOUND); // X-SOUND, MacSound
+ bool forceSoundCmd = false;
+ if (stfa) {
+ // see http://removers.free.fr/softs/stfa.php#STFA
+ struct STFA_control {
+ uint16 sound_enable;
+ uint16 sound_control;
+ uint16 sound_output;
+ uint32 sound_start;
+ uint32 sound_current;
+ uint32 sound_end;
+ uint16 version;
+ uint32 old_vbl;
+ uint32 old_timerA;
+ uint32 old_mfp_status;
+ uint32 stfa_vbl;
+ uint32 drivers_list;
+ uint32 play_stop;
+ uint16 timer_a_setting;
+ uint32 set_frequency;
+ uint16 frequency_treshold;
+ uint32 custom_freq_table;
+ int16 stfa_on_off;
+ uint32 new_drivers_list;
+ uint32 old_bit_2_of_cookie_snd;
+ uint32 it;
+ } __attribute__((packed));
+
+ STFA_control *stfaControl = (STFA_control *)stfa;
+ if (stfaControl->version < 0x0200) {
+ error("Your STFA version is too old, please upgrade to at least 2.00");
+ }
+ if (stfaControl->stfa_on_off == -1) {
+ // emulating 16-bit playback, force TT frequencies
+ enum {
+ MCH_ST = 0,
+ MCH_STE,
+ MCH_TT,
+ MCH_FALCON,
+ MCH_CLONE,
+ MCH_ARANYM
+ };
+
+ long mch = MCH_ST<<16;
+ Getcookie(C__MCH, &mch);
+ mch >>= 16;
+
+ if (mch == MCH_TT) {
+ debug("Forcing STE/TT compatible frequency");
+ forceSoundCmd = true;
+ }
+ }
+ }
+
// reset connection matrix (and other settings)
Sndstatus(SND_RESET);
@@ -118,7 +171,7 @@ void AtariMixerManager::init() {
}
// first try to use Devconnect() with a Falcon prescaler
- if (Devconnect(DMAPLAY, DAC, CLK25M, clk, NO_SHAKE) != 0) {
+ if (forceSoundCmd || Devconnect(DMAPLAY, DAC, CLK25M, clk, NO_SHAKE) != 0) {
// the return value is broken on Falcon
if (useDevconnectReturnValue) {
if (Devconnect(DMAPLAY, DAC, CLK25M, CLKOLD, NO_SHAKE) == 0) {
diff --git a/backends/platform/atari/osystem_atari.cpp b/backends/platform/atari/osystem_atari.cpp
index 8d5f1b2110d..06a5575da5d 100644
--- a/backends/platform/atari/osystem_atari.cpp
+++ b/backends/platform/atari/osystem_atari.cpp
@@ -291,7 +291,9 @@ uint32 OSystem_Atari::getMillis(bool skipRecord) {
void OSystem_Atari::delayMillis(uint msecs) {
const uint32 threshold = getMillis() + msecs;
- while (getMillis() < threshold);
+ while (getMillis() < threshold) {
+ update();
+ }
}
void OSystem_Atari::getTimeAndDate(TimeDate &td, bool skipRecord) const {
@@ -391,7 +393,14 @@ Common::String OSystem_Atari::getDefaultConfigFileName() {
}
void OSystem_Atari::update() {
- ((DefaultTimerManager *)_timerManager)->checkTimers();
+ // FIXME: SCI MIDI calls delayMillis() from a timer leading to an infitite recursion loop here
+ const Common::ConfigManager::Domain *activeDomain = ConfMan.getActiveDomain();
+ if (!activeDomain || activeDomain->getValOrDefault("engineid") != "sci" || !_inTimer) {
+ _inTimer = true;
+ ((DefaultTimerManager *)_timerManager)->checkTimers();
+ _inTimer = false;
+ }
+
if (_useNullMixer)
((NullMixerManager *)_mixerManager)->update();
else
diff --git a/backends/platform/atari/osystem_atari.h b/backends/platform/atari/osystem_atari.h
index 898115b7379..f6d3708da44 100644
--- a/backends/platform/atari/osystem_atari.h
+++ b/backends/platform/atari/osystem_atari.h
@@ -54,6 +54,7 @@ private:
bool _videoInitialized = false;
bool _timerInitialized = false;
bool _useNullMixer = false;
+ bool _inTimer = false;
};
#endif
diff --git a/backends/platform/atari/readme.txt b/backends/platform/atari/readme.txt
index a2c30d8a7c2..bf2e6120743 100644
--- a/backends/platform/atari/readme.txt
+++ b/backends/platform/atari/readme.txt
@@ -262,10 +262,10 @@ or "FM_medium_quality=true" into scummvm.ini if you want to experiment with a
better quality synthesis, otherwise the lowest quality will be used (applies
for MAME OPL only).
-On the TT, in 95% of cases it makes sense to use ScummVM only if you own a
+On the TT, in most cases it makes sense to use ScummVM only if you own a
native MIDI synthesizer (like mt32-pi: https://github.com/dwhinham/mt32-pi).
-MIDI emulation is out of question and STFA is usually slow to mix samples, too
-=> stick with games with MIDI sounds or at least don't install/enable STFA.
+MIDI emulation is out of question and STFA takes a good chunk of CPU time for
+downsampling to 8-bit resolution which could be utilized elsewhere.
CD music slows everything down
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -343,6 +343,9 @@ Known issues
fact that TT offers only 320x480 in 256 colours. Possibly fixable by a Timer
B interrupt.
+- horizontal screen shaking doesn't work on TT because TT Shifter doesn't
+ support fine scrolling.
+
- tooltips in overlay are sometimes drawn with corrupted background.
- the talkie version of MI1 needs to be merged from two sources: first generate
More information about the Scummvm-git-logs
mailing list