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.
This commit is contained in:
Donovan Watteau 2021-02-18 08:55:07 +01:00 committed by Filippos Karapetis
parent b36386226e
commit b40541d0fb
4 changed files with 20 additions and 13 deletions

View File

@ -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);

View File

@ -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() {

View File

@ -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.
}
}

View File

@ -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