BACKENDS: ATARI: Use RGB332 for the overlay

This commit is contained in:
Miro Kropacek 2023-02-26 01:21:47 +01:00
parent 6c5e3dbfd5
commit 52f8bd45e2
9 changed files with 141 additions and 282 deletions

View File

@ -213,16 +213,19 @@ set_tt_palette_loop:
dbra d0,set_tt_palette_loop
rts
| extern void asm_screen_set_falcon_palette(const uint32 pPalette[256]);
| extern void asm_screen_set_falcon_palette(const byte pPalette[256*3]);
|
_asm_screen_set_falcon_palette:
move.l (4,sp),a0
lea pending_palette,a1
moveq #256/2-1,d0
move.w #256-1,d0
set_falcon_palette_loop:
move.l (a0)+,(a1)+
move.l (a0)+,(a1)+
clr.l d1
move.w (a0)+,d1
swap d1
move.b (a0)+,d1
move.l d1,(a1)+
dbra d0,set_falcon_palette_loop
addq.w #1,has_pending_palette

View File

@ -51,9 +51,9 @@ void asm_screen_falcon_restore(void);
void asm_screen_set_tt_palette(const uint16 pPalette[256]);
/**
* Set Atari Falcon palette.
* @param pPalette 256 palette entries (RRRRRRrr GGGGGGgg 00000000 BBBBBBbb)
* @param pPalette 256 palette entries (RRRRRRRR GGGGGGGG BBBBBBBB)
*/
void asm_screen_set_falcon_palette(const uint32 pPalette[256]);
void asm_screen_set_falcon_palette(const byte pPalette[256*3]);
/**
* Set Atari TT/Falcon video base.

View File

@ -71,9 +71,6 @@ public:
return graphicsModes;
}
int16 getOverlayHeight() const override { return 2 * OVERLAY_HEIGHT; }
int16 getOverlayWidth() const override { return 2 * OVERLAY_WIDTH; }
protected:
AtariMemAlloc getStRamAllocFunc() const override {
return [](size_t bytes) {
@ -96,9 +93,9 @@ private:
dstSurface.copyRectToSurface(srcSurface, destX, destY, subRect);
}
void copyRectToSurfaceWithKey(Graphics::Surface &dstSurface,
void copyRectToSurfaceWithKey(Graphics::Surface &dstSurface, const Graphics::Surface &bgSurface,
const Graphics::Surface &srcSurface, int destX, int destY,
const Common::Rect &subRect, uint32 key) const override {
const Common::Rect &subRect, uint32 key, const byte srcPalette[256*3]) const override {
dstSurface.copyRectToSurfaceWithKey(srcSurface, destX, destY, subRect, key);
}

View File

@ -64,9 +64,6 @@ public:
return AtariGraphicsManager::endGFXTransaction();
}
int16 getOverlayHeight() const override { return _vgaMonitor ? OVERLAY_HEIGHT : 2 * OVERLAY_HEIGHT; }
int16 getOverlayWidth() const override { return _vgaMonitor ? OVERLAY_WIDTH : 2 * OVERLAY_WIDTH; }
private:
void copyRectToSurface(Graphics::Surface &dstSurface,
const Graphics::Surface &srcSurface, int destX, int destY,
@ -91,12 +88,9 @@ private:
}
}
// TODO: allow specifying different background than _chunkySurface?
// TODO: alignRect and this function could be perhaps better if we know that all surfaces
// are aligned on 16px and their pitch is % 16 as well?
void copyRectToSurfaceWithKey(Graphics::Surface &dstSurface,
void copyRectToSurfaceWithKey(Graphics::Surface &dstSurface, const Graphics::Surface &bgSurface,
const Graphics::Surface &srcSurface, int destX, int destY,
const Common::Rect &subRect, uint32 key) const override {
const Common::Rect &subRect, uint32 key, 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
@ -105,22 +99,52 @@ private:
const int deltaX = destX - backgroundRect.left;
backgroundRect.right = (backgroundRect.right + deltaX + 15) & 0xfff0;
if (backgroundRect.right > _chunkySurface.w)
backgroundRect.right = _chunkySurface.w;
if (backgroundRect.right > bgSurface.w)
backgroundRect.right = bgSurface.w;
static Graphics::Surface cachedSurface;
if (cachedSurface.w != backgroundRect.width() || cachedSurface.h != backgroundRect.height()) {
if (cachedSurface.w != backgroundRect.width()
|| cachedSurface.h != backgroundRect.height()
|| cachedSurface.format != bgSurface.format) {
cachedSurface.create(
backgroundRect.width(),
backgroundRect.height(),
_chunkySurface.format);
bgSurface.format);
}
// copy background
cachedSurface.copyRectToSurface(_chunkySurface, 0, 0, backgroundRect);
cachedSurface.copyRectToSurface(bgSurface, 0, 0, backgroundRect);
// copy cursor
cachedSurface.copyRectToSurfaceWithKey(srcSurface, deltaX, 0, subRect, key);
if (cachedSurface.format == PIXELFORMAT_RGB332) {
assert(srcSurface.format == PIXELFORMAT_CLUT8);
// Convert CLUT8 to RGB332 palette and do copyRectToSurfaceWithKey() at the same time
const byte *src = (const byte*)srcSurface.getBasePtr(subRect.left, subRect.top);
byte *dst = (byte*)cachedSurface.getBasePtr(deltaX, 0);
const int16 w = subRect.width();
const int16 h = subRect.height();
for (int16 y = 0; y < h; ++y) {
for (int16 x = 0; x < w; ++x) {
const uint32 color = *src++;
if (color != key) {
*dst++ = (srcPalette[color*3 + 0] & 0xe0)
| ((srcPalette[color*3 + 1] >> 3) & 0x1c)
| ((srcPalette[color*3 + 2] >> 6) & 0x03);
} else {
dst++;
}
}
src += (srcSurface.pitch - w);
dst += (cachedSurface.pitch - w);
}
} else {
cachedSurface.copyRectToSurfaceWithKey(srcSurface, deltaX, 0, subRect, key);
}
copyRectToSurface(
dstSurface,

View File

@ -63,6 +63,13 @@ AtariGraphicsManager::AtariGraphicsManager() {
ConfMan.flushToDisk();
// Generate RGB332 palette for the overlay
for (uint i = 0; i < 256; i++) {
_overlayPalette[i*3 + 0] = ((i >> 5) & 7) << 5;
_overlayPalette[i*3 + 1] = ((i >> 2) & 7) << 5;
_overlayPalette[i*3 + 2] = (i & 3) << 6;
}
g_system->getEventManager()->getEventDispatcher()->registerObserver(this, 10, false);
}
@ -76,8 +83,13 @@ bool AtariGraphicsManager::hasFeature(OSystem::Feature f) const {
debug("hasFeature(kFeatureAspectRatioCorrection): %d", !_vgaMonitor);
return !_vgaMonitor;
case OSystem::Feature::kFeatureCursorPalette:
debug("hasFeature(kFeatureCursorPalette): %d", isOverlayVisible());
return isOverlayVisible();
// XXX: pretend to have cursor palette all the time, this function
// can get called (and it is) any time, before and after showOverlay()
// (overlay cursor uses the cross if kFeatureCursorPalette returns false
// here too soon)
//debug("hasFeature(kFeatureCursorPalette): %d", isOverlayVisible());
//return isOverlayVisible();
return true;
case OSystem::Feature::kFeatureVSync:
debug("hasFeature(kFeatureVSync): %d", _vsync);
return true;
@ -109,7 +121,8 @@ bool AtariGraphicsManager::getFeatureState(OSystem::Feature f) const {
return _aspectRatioCorrection;
case OSystem::Feature::kFeatureCursorPalette:
//debug("getFeatureState(kFeatureCursorPalette): %d", isOverlayVisible());
return isOverlayVisible();
//return isOverlayVisible();
return true;
case OSystem::Feature::kFeatureVSync:
//debug("getFeatureState(kFeatureVSync): %d", _vsync);
return _vsync;
@ -134,7 +147,7 @@ void AtariGraphicsManager::initSize(uint width, uint height, const Graphics::Pix
_pendingState.width = width;
_pendingState.height = height;
_pendingState.format = format ? *format : PIXELFORMAT8;
_pendingState.format = format ? *format : PIXELFORMAT_CLUT8;
}
void AtariGraphicsManager::beginGFXTransaction() {
@ -150,7 +163,7 @@ OSystem::TransactionError AtariGraphicsManager::endGFXTransaction() {
//if (_pendingState == _currentState)
// return static_cast<OSystem::TransactionError>(error);
if (_pendingState.format != PIXELFORMAT8)
if (_pendingState.format != PIXELFORMAT_CLUT8)
error |= OSystem::TransactionError::kTransactionFormatNotSupported;
// TODO: Several engines support unusual resolutions like 256x240 (NES Maniac Mansion),
@ -354,17 +367,13 @@ void AtariGraphicsManager::updateScreen() {
bool resolutionChanged = false;
if (_pendingScreenChange & kPendingScreenChangeOverlay) {
if (_vgaMonitor) {
if (getOverlayWidth() == 640 && getOverlayHeight() == 480)
asm_screen_set_scp_res(scp_640x480x16_vga);
else
asm_screen_set_scp_res(scp_320x240x16_vga);
} else {
//asm_screen_set_scp_res(scp_320x240x16_rgb);
asm_screen_set_scp_res(scp_640x480x16_rgb);
}
if (_vgaMonitor)
asm_screen_set_scp_res(scp_640x480x8_vga);
else
asm_screen_set_scp_res(scp_640x480x8_rgb);
asm_screen_set_vram(_screenOverlaySurface.getPixels());
asm_screen_set_falcon_palette(_overlayPalette);
resolutionChanged = true;
}
@ -374,16 +383,8 @@ void AtariGraphicsManager::updateScreen() {
resolutionChanged = true;
}
if ((_pendingScreenChange & kPendingScreenChangePalette) && !isOverlayVisible()) {
static uint falconPalette[256];
for (uint i = 0; i < 256; ++i) {
// RRRRRRRR GGGGGGGG BBBBBBBB -> RRRRRRrr GGGGGGgg 00000000 BBBBBBbb
falconPalette[i] = (_palette[i * 3 + 0] << 24) | (_palette[i * 3 + 1] << 16) | _palette[i * 3 + 2];
}
#ifdef SCREEN_ACTIVE
asm_screen_set_falcon_palette(falconPalette);
#endif
if (_pendingScreenChange & kPendingScreenChangePalette) {
asm_screen_set_falcon_palette(_palette);
}
_pendingScreenChange = kPendingScreenChangeNone;
@ -411,7 +412,7 @@ void AtariGraphicsManager::showOverlay(bool inGUI) {
if (_overlayVisible)
return;
_pendingScreenChange &= ~kPendingScreenChangeScreen;
_pendingScreenChange &= ~(kPendingScreenChangeScreen | kPendingScreenChangePalette);
_pendingScreenChange |= kPendingScreenChangeOverlay;
_cursor.swap();
@ -433,7 +434,7 @@ void AtariGraphicsManager::hideOverlay() {
return;
_pendingScreenChange &= ~kPendingScreenChangeOverlay;
_pendingScreenChange |= kPendingScreenChangeScreen;
_pendingScreenChange |= (kPendingScreenChangeScreen | kPendingScreenChangePalette);
_cursor.swap();
// don't fool game cursor logic (especially direct rendering)
@ -463,29 +464,44 @@ void AtariGraphicsManager::clearOverlay() {
vOffset = (480 - 400) / 2;
}
ScaleMode scaleMode;
if (w == _overlaySurface.w && h == _overlaySurface.h) {
scaleMode = ScaleMode::NONE;
} else if (w / _overlaySurface.w == 2 && h / _overlaySurface.h == 2) {
scaleMode = ScaleMode::DOWNSCALE;
vOffset /= 2;
} else if (_overlaySurface.w / w == 2 && _overlaySurface.h / h == 2) {
scaleMode = ScaleMode::UPSCALE;
bool upscale = false;
if (_overlaySurface.w / w == 2 && _overlaySurface.h / h == 2) {
upscale = true;
vOffset *= 2;
} else {
warning("Unknown overlay (%d, %d) / screen (%d, %d) ratio: ",
} else if (vOffset != 0) {
warning("Unknown overlay (%d, %d) / screen (%d, %d) ratio",
_overlaySurface.w, _overlaySurface.h, w, h);
return;
}
memset(_overlaySurface.getBasePtr(0, 0), 0, _overlaySurface.pitch * vOffset);
copySurface8ToSurface16(
sourceSurface,
_palette,
_overlaySurface,
0, vOffset,
Common::Rect(sourceSurface.w, sourceSurface.h),
scaleMode);
// Transpose from game palette to RGB332 (overlay palette)
const byte *src = (const byte*)sourceSurface.getPixels();
byte *dst = (byte*)_overlaySurface.getBasePtr(0, vOffset);
for (int y = 0; y < sourceSurface.h; y++) {
for (int x = 0; x < sourceSurface.w; x++) {
const byte col = *src++;
const byte pixel = (_palette[3*col + 0] & 0xe0)
| ((_palette[3*col + 1] >> 3) & 0x1c)
| ((_palette[3*col + 2] >> 6) & 0x03);
if (upscale) {
*(dst + _overlaySurface.pitch) = pixel;
*dst++ = pixel;
*(dst + _overlaySurface.pitch) = pixel;
*dst++ = pixel;
} else {
*dst++ = pixel;
}
}
if (upscale)
dst += _overlaySurface.pitch;
}
memset(_overlaySurface.getBasePtr(0, _overlaySurface.h - vOffset), 0, _overlaySurface.pitch * vOffset);
handleModifiedRect(_overlaySurface, Common::Rect(_overlaySurface.w, _overlaySurface.h), _modifiedOverlayRects);
@ -530,7 +546,7 @@ void AtariGraphicsManager::setMouseCursor(const void *buf, uint w, uint h, int h
if (mask)
warning("AtariGraphicsManager::setMouseCursor: Masks are not supported");
const Graphics::PixelFormat cursorFormat = format ? *format : PIXELFORMAT8;
const Graphics::PixelFormat cursorFormat = format ? *format : PIXELFORMAT_CLUT8;
_cursor.setSurface(buf, (int)w, (int)h, hotspotX, hotspotY, keycolor, cursorFormat);
}
@ -576,14 +592,14 @@ Common::Keymap *AtariGraphicsManager::getKeymap() const {
void AtariGraphicsManager::allocateSurfaces() {
for (int i = 0; i < SCREENS; ++i) {
if (!(_screen[i] = allocateAtariSurface(_screenSurface,
SCREEN_WIDTH, SCREEN_HEIGHT, PIXELFORMAT8,
SCREEN_WIDTH, SCREEN_HEIGHT, PIXELFORMAT_CLUT8,
getStRamAllocFunc())))
error("Failed to allocate screen memory in ST RAM");
_screenAligned[i] = (byte*)_screenSurface.getPixels();
}
_screenSurface.setPixels(_screenAligned[getDefaultGraphicsMode() <= 1 ? FRONT_BUFFER : BACK_BUFFER1]);
_chunkySurface.create(SCREEN_WIDTH, SCREEN_HEIGHT, PIXELFORMAT8);
_chunkySurface.create(SCREEN_WIDTH, SCREEN_HEIGHT, PIXELFORMAT_CLUT8);
if (!(_overlayScreen = allocateAtariSurface(_screenOverlaySurface,
getOverlayWidth(), getOverlayHeight(), getOverlayFormat(),
@ -658,7 +674,7 @@ bool AtariGraphicsManager::updateOverlay() {
if (!drawCursor && !_cursor.outOfScreen && _cursor.visible)
drawCursor = rect.intersects(_cursor.dstRect);
_screenOverlaySurface.copyRectToSurface(_overlaySurface, rect.left, rect.top, rect);
copyRectToSurface(_screenOverlaySurface, _overlaySurface, rect.left, rect.top, rect);
_modifiedOverlayRects.pop_back();
@ -669,7 +685,8 @@ bool AtariGraphicsManager::updateOverlay() {
return updated;
if ((_cursor.positionChanged || !_cursor.visible) && !_oldCursorRect.isEmpty()) {
_screenOverlaySurface.copyRectToSurface(_overlaySurface, _oldCursorRect.left, _oldCursorRect.top, _oldCursorRect);
alignRect(_screenOverlaySurface, _oldCursorRect);
copyRectToSurface(_screenOverlaySurface, _overlaySurface, _oldCursorRect.left, _oldCursorRect.top, _oldCursorRect);
_oldCursorRect = Common::Rect();
updated = true;
@ -677,14 +694,10 @@ bool AtariGraphicsManager::updateOverlay() {
if (drawCursor && _cursor.visible) {
//debug("Redraw cursor (overlay): %d %d %d %d", _cursor.dstRect.left, _cursor.dstRect.top, _cursor.dstRect.width(), _cursor.dstRect.height());
copySurface8ToSurface16WithKey(
_cursor.surface,
_cursor.palette,
_screenOverlaySurface,
copyRectToSurfaceWithKey(
_screenOverlaySurface, _overlaySurface, _cursor.surface,
_cursor.dstRect.left, _cursor.dstRect.top,
_cursor.srcRect,
_cursor.keycolor);
_cursor.srcRect, _cursor.keycolor, _cursor.palette);
_cursor.positionChanged = _cursor.surfaceChanged = false;
_oldCursorRect = _cursor.dstRect;
@ -795,9 +808,9 @@ bool AtariGraphicsManager::updateSingleBuffer() {
if (drawCursor && _cursor.visible) {
//debug("Redraw cursor (single): %d %d %d %d", _cursor.dstRect.left, _cursor.dstRect.top, _cursor.dstRect.width(), _cursor.dstRect.height());
copyRectToSurfaceWithKey(
_screenSurface, _cursor.surface,
_screenSurface, _chunkySurface, _cursor.surface,
_cursor.dstRect.left, _cursor.dstRect.top,
_cursor.srcRect, _cursor.keycolor);
_cursor.srcRect, _cursor.keycolor, _cursor.palette);
_cursor.positionChanged = _cursor.surfaceChanged = false;
_oldCursorRect = _cursor.dstRect;
@ -849,9 +862,9 @@ bool AtariGraphicsManager::updateDoubleAndTripleBuffer() {
//debug("Redraw cursor (double/triple): %d %d %d %d", _cursor.dstRect.left, _cursor.dstRect.top, _cursor.dstRect.width(), _cursor.dstRect.height());
copyRectToSurfaceWithKey(
frontBufferScreenSurface, _cursor.surface,
frontBufferScreenSurface, _chunkySurface, _cursor.surface,
_cursor.dstRect.left, _cursor.dstRect.top,
_cursor.srcRect, _cursor.keycolor);
_cursor.srcRect, _cursor.keycolor, _cursor.palette);
_cursor.positionChanged = _cursor.surfaceChanged = false;
_oldCursorRect = _cursor.dstRect;
@ -882,100 +895,10 @@ void AtariGraphicsManager::freeAtariSurface(byte *ptr, Graphics::Surface &surfac
freeFunc(ptr);
}
void AtariGraphicsManager::copySurface8ToSurface16(
const Graphics::Surface &srcSurface, const byte *srcPalette,
Graphics::Surface &dstSurface, int destX, int destY,
const Common::Rect subRect, ScaleMode scaleMode) const {
assert(srcSurface.format.bytesPerPixel == 1);
assert(dstSurface.format.bytesPerPixel == 2);
// faster (no memory (re-)allocation) version of Surface::convertTo()
const int w = subRect.width();
const int h = subRect.height();
const int srcScale = scaleMode == ScaleMode::DOWNSCALE ? 2 : 1;
const byte *srcRow = (const byte*)srcSurface.getBasePtr(subRect.left * srcScale, subRect.top * srcScale);
uint16 *dstRow = (uint16*)dstSurface.getBasePtr(destX, destY); // already upscaled if needed
static uint32 srcPaletteMap[256];
Graphics::convertPaletteToMap(srcPaletteMap, srcPalette, 256, dstSurface.format);
// optimized paths for each case...
if (scaleMode == ScaleMode::NONE) {
for (int y = 0; y < h; y++) {
for (int x = 0; x < w; x++) {
*dstRow++ = srcPaletteMap[*srcRow++];
}
srcRow += srcSurface.w - w;
dstRow += dstSurface.w - w;
}
} else if (scaleMode == ScaleMode::DOWNSCALE) {
for (int y = 0; y < h / 2; y++) {
for (int x = 0; x < w / 2; x++) {
*dstRow++ = srcPaletteMap[*srcRow];
srcRow += 2;
}
srcRow += srcSurface.w - w + srcSurface.w;
dstRow += dstSurface.w - w / 2;
}
} else if (scaleMode == ScaleMode::UPSCALE) {
for (int y = 0; y < h; y++) {
for (int x = 0; x < w; x++) {
const uint16 pixel = srcPaletteMap[*srcRow++];
*(dstRow + dstSurface.w) = pixel;
*dstRow++ = pixel;
*(dstRow + dstSurface.w) = pixel;
*dstRow++ = pixel;
}
srcRow += srcSurface.w - w;
dstRow += dstSurface.w - w * 2 + dstSurface.w;
}
}
}
void AtariGraphicsManager::copySurface8ToSurface16WithKey(
const Graphics::Surface &srcSurface, const byte *srcPalette,
Graphics::Surface &dstSurface, int destX, int destY,
const Common::Rect subRect, uint32 key) const {
assert(srcSurface.format.bytesPerPixel == 1);
assert(dstSurface.format.bytesPerPixel == 2);
// faster (no memory (re-)allocation) version of Surface::convertTo()
const int w = subRect.width();
const int h = subRect.height();
const byte *srcRow = (const byte *)srcSurface.getBasePtr(subRect.left, subRect.top);
uint16 *dstRow = (uint16 *)dstSurface.getBasePtr(destX, destY);
static uint32 srcPaletteMap[256];
Graphics::convertPaletteToMap(srcPaletteMap, srcPalette, 256, dstSurface.format);
const uint16 keyColor = srcPaletteMap[key];
for (int y = 0; y < h; y++) {
for (int x = 0; x < w; x++) {
const uint16 pixel = srcPaletteMap[*srcRow++];
if (pixel != keyColor) {
*dstRow++ = pixel;
} else {
dstRow++;
}
}
srcRow += srcSurface.w - w;
dstRow += dstSurface.w - w;
}
}
void AtariGraphicsManager::handleModifiedRect(
const Graphics::Surface &surface,
Common::Rect rect, Common::Array<Common::Rect> &rects) const {
if (_currentState.mode == GraphicsMode::SingleBuffering)
if (_currentState.mode == GraphicsMode::SingleBuffering || isOverlayVisible())
alignRect(surface, rect);
if (rect.width() == surface.w && rect.height() == surface.h) {
@ -1034,7 +957,8 @@ void AtariGraphicsManager::Cursor::updatePosition(int deltaX, int deltaY, const
positionChanged = true;
}
void AtariGraphicsManager::Cursor::setSurface(const void *buf, int w, int h, int _hotspotX, int _hotspotY, uint32 _keycolor, const Graphics::PixelFormat &format) {
void AtariGraphicsManager::Cursor::setSurface(const void *buf, int w, int h, int hotspotX_, int hotspotY_, uint32 keycolor_,
const Graphics::PixelFormat &format) {
if (w == 0 || h == 0 || buf == nullptr) {
if (surface.getPixels())
surface.free();
@ -1044,11 +968,11 @@ void AtariGraphicsManager::Cursor::setSurface(const void *buf, int w, int h, int
if (surface.w != w || surface.h != h || surface.format != format)
surface.create(w, h, format);
surface.copyRectToSurface(buf, w * format.bytesPerPixel, 0, 0, w, h);
surface.copyRectToSurface(buf, w * surface.format.bytesPerPixel, 0, 0, w, h);
hotspotX = _hotspotX;
hotspotY = _hotspotY;
keycolor = _keycolor;
hotspotX = hotspotX_;
hotspotY = hotspotY_;
keycolor = keycolor_;
surfaceChanged = true;
}

View File

@ -35,10 +35,6 @@
constexpr int SCREEN_WIDTH = 640;
constexpr int SCREEN_HEIGHT = 480;
// minimum overlay dimensions
constexpr int OVERLAY_WIDTH = 320;
constexpr int OVERLAY_HEIGHT = 240;
class AtariGraphicsManager : public GraphicsManager, Common::EventObserver {
public:
AtariGraphicsManager();
@ -75,10 +71,12 @@ public:
void showOverlay(bool inGUI) override;
void hideOverlay() override;
bool isOverlayVisible() const override { return _overlayVisible; }
Graphics::PixelFormat getOverlayFormat() const override { return Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0); }
Graphics::PixelFormat getOverlayFormat() const override { return PIXELFORMAT_RGB332; }
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;
int16 getOverlayHeight() const override { return 480; }
int16 getOverlayWidth() const override { return 640; }
bool showMouse(bool visible) override;
void warpMouse(int x, int y) override;
@ -93,7 +91,8 @@ public:
Common::Keymap *getKeymap() const;
protected:
const Graphics::PixelFormat PIXELFORMAT8 = Graphics::PixelFormat::createFormatCLUT8();
const Graphics::PixelFormat PIXELFORMAT_CLUT8 = Graphics::PixelFormat::createFormatCLUT8();
const Graphics::PixelFormat PIXELFORMAT_RGB332 = Graphics::PixelFormat(1, 3, 3, 2, 0, 5, 2, 0, 0);
typedef void* (*AtariMemAlloc)(size_t bytes);
typedef void (*AtariMemFree)(void *ptr);
@ -141,8 +140,6 @@ protected:
static const int BACK_BUFFER1 = 1;
static const int BACK_BUFFER2 = 2;
Graphics::Surface _chunkySurface; // for Videl's copyRectToSurfaceWithKey
private:
enum CustomEventAction {
kActionToggleAspectRatioCorrection = 100,
@ -165,27 +162,13 @@ private:
virtual void copyRectToSurface(Graphics::Surface &dstSurface,
const Graphics::Surface &srcSurface, int destX, int destY,
const Common::Rect &subRect) const = 0;
virtual void copyRectToSurfaceWithKey(Graphics::Surface &dstSurface,
virtual void copyRectToSurfaceWithKey(Graphics::Surface &dstSurface, const Graphics::Surface &bgSurface,
const Graphics::Surface &srcSurface, int destX, int destY,
const Common::Rect &subRect, uint32 key) const = 0;
const Common::Rect &subRect, uint32 key, const byte srcPalette[256*3]) const = 0;
virtual void alignRect(const Graphics::Surface &srcSurface, Common::Rect &rect) const {}
enum class ScaleMode {
NONE,
UPSCALE,
DOWNSCALE
};
void copySurface8ToSurface16(const Graphics::Surface &srcSurface, const byte *srcPalette,
Graphics::Surface &dstSurface, int destX, int destY,
const Common::Rect subRect, ScaleMode scaleMode) const;
void copySurface8ToSurface16WithKey(const Graphics::Surface &srcSurface, const byte* srcPalette,
Graphics::Surface &dstSurface, int destX, int destY,
const Common::Rect subRect, uint32 key) const;
void handleModifiedRect(const Graphics::Surface &surface, Common::Rect rect, Common::Array<Common::Rect> &rects) const;
void updateCursorRect();
bool _aspectRatioCorrection = false;
bool _oldAspectRatioCorrection = false;
bool _vsync = true;
@ -206,6 +189,7 @@ private:
Common::Rect _modifiedScreenRect; // direct rendering only
bool _screenModified = false; // double/triple buffering only
Graphics::Surface _chunkySurface;
Common::Array<Common::Rect> _modifiedChunkyRects;
byte *_overlayScreen = nullptr; // for Mfree() purposes only
@ -265,7 +249,7 @@ private:
Common::Rect srcRect;
Common::Rect dstRect;
// palette (only used for 16bpp screen surfaces)
// palette (only used for the overlay)
byte palette[256*3] = {};
private:
@ -279,6 +263,7 @@ private:
Common::Rect _oldCursorRect;
byte _palette[256*3] = {};
byte _overlayPalette[256*3] = {};
};
#endif

View File

@ -108,40 +108,6 @@ byte scp_320x240x8_vga[] = {
0x00, 0xa0
};
const byte scp_320x240x16_rgb[] = {
0x53, 0x43, 0x50, 0x4e, 0x00, 0x09, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x48, 0x7a, 0xb0, 0x00, 0xa9, 0xc1, 0x08, 0x00, 0xc2, 0x8c, 0xb0,
0x01, 0x64, 0x05, 0x00, 0x01, 0xf4, 0x00, 0x00, 0x3d, 0x09, 0x00, 0x00,
0x00, 0xc0, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x2c,
0x00, 0xf0, 0x00, 0x03, 0x00, 0x01, 0x00, 0x00, 0x01, 0xe8, 0x48, 0x00,
0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xfe, 0x00, 0x99, 0x00, 0x59, 0x00, 0x38, 0x00, 0x99,
0x00, 0xd9, 0x02, 0x71, 0x02, 0x39, 0x00, 0x59, 0x00, 0x59, 0x02, 0x39,
0x02, 0x6b, 0x02, 0x00, 0x01, 0x81, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x01, 0x40
};
const byte scp_320x240x16_vga[] = {
0x53, 0x43, 0x50, 0x4e, 0x00, 0x09, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x3a, 0x2f, 0x00, 0x00, 0x19, 0x74, 0x90, 0x00, 0x46, 0x4e, 0x20,
0x00, 0x2a, 0x02, 0x80, 0x02, 0x58, 0x00, 0x00, 0x7a, 0xee, 0x00, 0x00,
0x00, 0x3e, 0x00, 0x00, 0x03, 0xc1, 0x00, 0x00, 0x01, 0xb2, 0x00, 0x1e,
0x01, 0xe0, 0x00, 0x03, 0x00, 0x02, 0x00, 0x01, 0x01, 0xe8, 0x48, 0x00,
0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xc6, 0x00, 0x8d, 0x00, 0x15, 0x02, 0xac, 0x00, 0x8d,
0x00, 0x97, 0x04, 0x19, 0x03, 0xfd, 0x00, 0x3f, 0x00, 0x3d, 0x03, 0xfd,
0x04, 0x15, 0x02, 0x00, 0x01, 0x86, 0x00, 0x00, 0x01, 0x00, 0x00, 0x05,
0x01, 0x40
};
const byte scp_640x400x8_rgb[] = {
0x53, 0x43, 0x50, 0x4e, 0x00, 0x09, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@ -226,37 +192,3 @@ byte scp_640x480x8_vga[] = {
0x04, 0x15, 0x02, 0x00, 0x01, 0x86, 0x00, 0x00, 0x00, 0x10, 0x00, 0x08,
0x01, 0x40
};
const byte scp_640x480x16_rgb[] = {
0x53, 0x43, 0x50, 0x4e, 0x00, 0x09, 0x00, 0x01, 0x36, 0x34, 0x30, 0x2a,
0x34, 0x38, 0x30, 0x2c, 0x20, 0x54, 0x72, 0x75, 0x65, 0x20, 0x43, 0x6f,
0x6c, 0x6f, 0x72, 0x2c, 0x20, 0x35, 0x30, 0x2e, 0x30, 0x20, 0x48, 0x7a,
0x20, 0x28, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6c, 0x2e, 0x29, 0x2c, 0x20,
0x31, 0x35, 0x36, 0x32, 0x35, 0x20, 0x48, 0x7a, 0x00, 0x00, 0x00, 0x00,
0x00, 0x48, 0x7a, 0xb0, 0x00, 0xa9, 0xc1, 0x08, 0x00, 0xc3, 0x80, 0xd4,
0x01, 0x64, 0x05, 0x00, 0x01, 0xf4, 0x00, 0x00, 0x3d, 0x09, 0x00, 0x00,
0x00, 0xc0, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x2c,
0x00, 0xf0, 0x00, 0x03, 0x00, 0x01, 0x00, 0x00, 0x01, 0xe8, 0x48, 0x00,
0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x01, 0xfe, 0x01, 0x32, 0x00, 0xb2, 0x00, 0x81, 0x01, 0x32,
0x01, 0xb3, 0x02, 0x70, 0x02, 0x39, 0x00, 0x59, 0x00, 0x58, 0x02, 0x38,
0x02, 0x6b, 0x02, 0x00, 0x01, 0x81, 0x00, 0x00, 0x01, 0x00, 0x00, 0x06,
0x02, 0x80
};
const byte scp_640x480x16_vga[] = {
0x53, 0x43, 0x50, 0x4e, 0x00, 0x09, 0x00, 0x02, 0x36, 0x34, 0x30, 0x2a,
0x34, 0x38, 0x30, 0x2c, 0x20, 0x54, 0x72, 0x75, 0x65, 0x20, 0x43, 0x6f,
0x6c, 0x6f, 0x72, 0x2c, 0x20, 0x36, 0x30, 0x2e, 0x30, 0x20, 0x48, 0x7a,
0x2c, 0x20, 0x33, 0x31, 0x34, 0x37, 0x30, 0x20, 0x48, 0x7a, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x3a, 0x2f, 0x00, 0x00, 0x1a, 0xaa, 0xe0, 0x00, 0x45, 0x17, 0xd0,
0x00, 0x2c, 0x02, 0x80, 0x02, 0x58, 0x00, 0x00, 0x7a, 0xee, 0x00, 0x00,
0x00, 0x3e, 0x00, 0x00, 0x03, 0xc1, 0x00, 0x00, 0x01, 0x93, 0x00, 0x1f,
0x01, 0xe0, 0x00, 0x03, 0x00, 0x02, 0x00, 0x01, 0x01, 0xe8, 0x48, 0x00,
0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xc6, 0x00, 0x8e, 0x00, 0x16, 0x02, 0xb5, 0x00, 0x8e,
0x00, 0x97, 0x04, 0x19, 0x03, 0xff, 0x00, 0x3f, 0x00, 0x3f, 0x03, 0xff,
0x04, 0x15, 0x02, 0x00, 0x01, 0x86, 0x00, 0x00, 0x01, 0x00, 0x00, 0x08,
0x02, 0x80
};

View File

@ -32,8 +32,6 @@ extern byte scp_320x200x8_vga[SCP_SIZE];
extern const byte scp_320x240x8_rgb[SCP_SIZE];
extern byte scp_320x240x8_vga[SCP_SIZE];
extern const byte scp_320x240x16_rgb[SCP_SIZE];
extern const byte scp_320x240x16_vga[SCP_SIZE];
extern const byte scp_640x400x8_rgb[SCP_SIZE];
extern const byte scp_640x400x8_rgb60[SCP_SIZE];
@ -41,7 +39,5 @@ extern byte scp_640x400x8_vga[SCP_SIZE];
extern const byte scp_640x480x8_rgb[SCP_SIZE];
extern byte scp_640x480x8_vga[SCP_SIZE];
extern const byte scp_640x480x16_rgb[SCP_SIZE];
extern const byte scp_640x480x16_vga[SCP_SIZE];
#endif

View File

@ -58,8 +58,8 @@ less hungry games even a CT2/DFB@50 MHz or the AfterBurner040 could be enough).
- Custom (and optimal) drawing routines (especially for the cursor).
- Custom (Super)Videl resolutions for the best possible performance and visual
experience (320x240 in RGB, chunky modes with SuperVidel, 640x480@16bpp for
the overlay in RGB/SuperVidel, ...)
experience (320x240 in RGB, chunky modes with SuperVidel, 640x480@8bpp for
the overlay, ...)
- Custom (hardware based) aspect ratio correction (!)
@ -373,8 +373,6 @@ Future plans
- unified file paths in scummvm.ini
- 8bpp overlay (and get rid of all that 16bpp handling code)
- profiling :) (see also https://github.com/scummvm/scummvm/pull/2382)
- DSP-based sample mixer
@ -412,7 +410,7 @@ Future plans
Closing words
------------
-------------
I have opened a pull request with all of my code
(https://github.com/scummvm/scummvm/pull/4687) so who knows, maybe ScummVM