From b40541d0fba66441a141b9f7b23a0ff6d73aba0d Mon Sep 17 00:00:00 2001 From: Donovan Watteau Date: Thu, 18 Feb 2021 08:55:07 +0100 Subject: [PATCH] DRAGONS: Incomplete attempt at improving big-endian compatibility It seems that screen content must be written in native endianness here, not in little-endian. This appears to fix most scenes, cutscenes, and the bag. Shadows, menus, and text are still wrong. Audio hasn't been tested yet. See https://bugs.scummvm.org/ticket/11710. --- engines/dragons/bag.cpp | 2 +- engines/dragons/font.cpp | 2 +- engines/dragons/screen.cpp | 22 +++++++++++----------- engines/dragons/screen.h | 7 +++++++ 4 files changed, 20 insertions(+), 13 deletions(-) diff --git a/engines/dragons/bag.cpp b/engines/dragons/bag.cpp index 73d625647f7..65bdba69b01 100644 --- a/engines/dragons/bag.cpp +++ b/engines/dragons/bag.cpp @@ -71,7 +71,7 @@ void Bag::load(BigfileArchive *bigFileArchive) { } else { //c = (uint16)(((uint)c & 0x1f) << 10) | (uint16)(((uint)c & 0x7c00) >> 10) | c & 0x3e0; } - WRITE_LE_UINT16(&pal[i * 2], c); + WRITE_SCREEN(&pal[i * 2], c); } stream.seek(0x308); diff --git a/engines/dragons/font.cpp b/engines/dragons/font.cpp index a093ce462b6..24e8d15b5d4 100644 --- a/engines/dragons/font.cpp +++ b/engines/dragons/font.cpp @@ -160,7 +160,7 @@ Font *FontManager::loadFont(uint16 index, Common::SeekableReadStream &stream) { void updatePalEntry(uint16 *pal, uint16 index, uint16 newValue) { newValue = (uint16)(((uint16)newValue & 0x1f) << 10) | (uint16)(((uint16)newValue & 0x7c00) >> 10) | (newValue & 0x3e0) | (newValue & 0x8000); - WRITE_LE_INT16(pal + index, newValue); + WRITE_SCREEN(pal + index, newValue); } void FontManager::updatePalette() { diff --git a/engines/dragons/screen.cpp b/engines/dragons/screen.cpp index cca0a97ff5a..368e3e7e8b9 100644 --- a/engines/dragons/screen.cpp +++ b/engines/dragons/screen.cpp @@ -162,7 +162,7 @@ void Screen::copyRectToSurface(const void *buffer, int srcPitch, int srcWidth, i dst[j * 2] = src[srcIdx * 2]; dst[j * 2 + 1] = src[srcIdx * 2 + 1]; } else { - WRITE_LE_UINT16(&dst[j * 2], alphaBlendRGB555(READ_LE_INT16(&src[srcIdx * 2]), READ_LE_INT16(&dst[j * 2]), 128)); + WRITE_SCREEN(&dst[j * 2], alphaBlendRGB555(READ_LE_INT16(&src[srcIdx * 2]), READ_LE_INT16(&dst[j * 2]), 128)); // semi-transparent pixels. } } @@ -190,10 +190,10 @@ void Screen::copyRectToSurface8bpp(const void *buffer, const byte* palette, int if (c != 0) { if (!(c & 0x8000) || alpha == NONE) { // only copy opaque pixels - WRITE_LE_UINT16(&dst[j * 2], c & ~0x8000); + WRITE_SCREEN(&dst[j * 2], c & ~0x8000); } else { // semi-transparent pixels. - WRITE_LE_UINT16(&dst[j * 2], alpha == NORMAL + WRITE_SCREEN(&dst[j * 2], alpha == NORMAL ? alphaBlendRGB555(c & 0x7fff, READ_LE_INT16(&dst[j * 2]) & 0x7fff, 128) : alphaBlendAdditiveRGB555(c & 0x7fff, READ_LE_INT16(&dst[j * 2]) & 0x7fff)); } @@ -247,9 +247,9 @@ void Screen::drawScaledSprite(Graphics::Surface *destSurface, const byte *source if (c != 0) { if (!(c & 0x8000u) || alpha == NONE) { // only copy opaque pixels - WRITE_LE_UINT16(wdst, c & ~0x8000); + WRITE_SCREEN(wdst, c & ~0x8000); } else { - WRITE_LE_UINT16(wdst, alphaBlendRGB555(c & 0x7fffu, READ_LE_UINT16(wdst) & 0x7fffu, 128)); + WRITE_SCREEN(wdst, alphaBlendRGB555(c & 0x7fffu, READ_LE_UINT16(wdst) & 0x7fffu, 128)); // semi-transparent pixels. } } @@ -357,7 +357,7 @@ void Screen::loadPalette(uint16 paletteNum, const byte *palette) { uint16 c = READ_LE_INT16(&_palettes[paletteNum][i * 2]); if ((c & ~0x8000) == 0) { if (!isTransPalette) { - WRITE_LE_UINT16(&_palettes[paletteNum][i * 2], 0x8000); + WRITE_SCREEN(&_palettes[paletteNum][i * 2], 0x8000); } } else { //TODO is this needed? see load_palette_into_frame_buffer() @@ -365,13 +365,13 @@ void Screen::loadPalette(uint16 paletteNum, const byte *palette) { // (c & 0x3e0) | (c & 0x8000); } } - WRITE_LE_UINT16(&_palettes[paletteNum][0], 0); + WRITE_SCREEN(&_palettes[paletteNum][0], 0); } void Screen::setPaletteRecord(uint16 paletteNum, uint16 offset, uint16 newValue) { assert(paletteNum < DRAGONS_NUM_PALETTES); assert(offset < 256); - WRITE_LE_UINT16(&_palettes[paletteNum][offset * 2], newValue); + WRITE_SCREEN(&_palettes[paletteNum][offset * 2], newValue); } byte *Screen::getPalette(uint16 paletteNum) { @@ -408,7 +408,7 @@ void Screen::copyRectToSurface8bppWrappedY(const Graphics::Surface &srcSurface, for (int j = 0; j < DRAGONS_SCREEN_WIDTH; j++) { uint16 c = READ_LE_UINT16(&palette[src[j] * 2]); if (c != 0) { - WRITE_LE_UINT16(&dst[j * 2], c & ~0x8000); + WRITE_SCREEN(&dst[j * 2], c & ~0x8000); } } dst += _backSurface->pitch; @@ -430,9 +430,9 @@ void Screen::copyRectToSurface8bppWrappedX(const Graphics::Surface &srcSurface, if (c != 0) { if (!(c & 0x8000) || alpha == NONE) { // only copy opaque pixels - WRITE_LE_UINT16(&dst[j * 2], c & ~0x8000); + WRITE_SCREEN(&dst[j * 2], c & ~0x8000); } else { - WRITE_LE_UINT16(&dst[j * 2], alpha == NORMAL ? alphaBlendRGB555(c, READ_LE_INT16(&dst[j * 2]), 128) : alphaBlendAdditiveRGB555(c, READ_LE_INT16(&dst[j * 2]))); + WRITE_SCREEN(&dst[j * 2], alpha == NORMAL ? alphaBlendRGB555(c, READ_LE_INT16(&dst[j * 2]), 128) : alphaBlendAdditiveRGB555(c, READ_LE_INT16(&dst[j * 2]))); // semi-transparent pixels. } } diff --git a/engines/dragons/screen.h b/engines/dragons/screen.h index b395f74f7b4..9e24be02217 100644 --- a/engines/dragons/screen.h +++ b/engines/dragons/screen.h @@ -24,6 +24,7 @@ #include "graphics/surface.h" #include "graphics/pixelformat.h" +#include "common/scummsys.h" #include "common/rect.h" namespace Dragons { @@ -35,6 +36,12 @@ namespace Dragons { #define DRAGONS_NUM_FLAT_QUADS 0xf +#ifdef SCUMM_BIG_ENDIAN + #define WRITE_SCREEN WRITE_BE_UINT16 +#else + #define WRITE_SCREEN WRITE_LE_UINT16 +#endif + enum AlphaBlendMode { NONE, NORMAL, // 50% x Back + 50% x Sprite