diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp index d989f6fe573..27567e85686 100644 --- a/engines/freescape/freescape.cpp +++ b/engines/freescape/freescape.cpp @@ -193,16 +193,12 @@ void FreescapeEngine::drawBorder() { void FreescapeEngine::drawTitle() { _gfx->setViewport(_fullscreenViewArea); - if (isSpectrum()) { - Graphics::ManagedSurface *title = new Graphics::ManagedSurface(); - title->create(320, 200, _title->format); - title->copyRectToSurface(*_title, (320 - _title->w) / 2, (200 - _title->h) / 2, Common::Rect(_title->w, _title->h)); - _title->free(); - delete _title; - _title = title; + if (!_titleTexture) { + Graphics::Surface *title = _gfx->convertImageFormatIfNecessary(_title); + _titleTexture = _gfx->createTexture(title); + title->free(); + delete title; } - if (!_titleTexture) - _titleTexture = _gfx->createTexture(&_title->rawSurface()); _gfx->drawTexturedRect2D(_fullscreenViewArea, _fullscreenViewArea, _titleTexture); _gfx->setViewport(_viewArea); } @@ -540,8 +536,6 @@ Common::Error FreescapeEngine::run() { initGameState(); loadColorPalette(); - _gfx->convertImageFormatIfNecessary(_title); - _gfx->convertImageFormatIfNecessary(_border); g_system->lockMouse(true); // Simple main event loop @@ -597,28 +591,37 @@ void FreescapeEngine::titleScreen() {} void FreescapeEngine::borderScreen() {} void FreescapeEngine::loadBorder() { - if (_border) - _borderTexture = _gfx->createTexture(&_border->rawSurface()); + if (_border) { + Graphics::Surface *border = _gfx->convertImageFormatIfNecessary(_border); + _borderTexture = _gfx->createTexture(border); + border->free(); + delete border; + } } void FreescapeEngine::processBorder() { if (_border) { if (_borderTexture) delete _borderTexture; + Graphics::Surface *border = _gfx->convertImageFormatIfNecessary(_border); + uint32 gray = _gfx->_texturePixelFormat.ARGBToColor(0x00, 0xA0, 0xA0, 0xA0); - _border->fillRect(_viewArea, gray); + border->fillRect(_viewArea, gray); // Replace black pixel for transparent ones - uint32 black = _border->format.ARGBToColor(0xFF, 0x00, 0x00, 0x00); - uint32 transparent = _border->format.ARGBToColor(0x00, 0x00, 0x00, 0x00); + uint32 black = border->format.ARGBToColor(0xFF, 0x00, 0x00, 0x00); + uint32 transparent = border->format.ARGBToColor(0x00, 0x00, 0x00, 0x00); - for (int i = 0; i < _border->w; i++) { - for (int j = 0; j < _border->h; j++) { - if (_border->getPixel(i, j) == black) - _border->setPixel(i, j, transparent); + for (int i = 0; i < border->w; i++) { + for (int j = 0; j < border->h; j++) { + if (border->getPixel(i, j) == black) + border->setPixel(i, j, transparent); } } - _borderTexture = _gfx->createTexture(&_border->rawSurface()); + + _borderTexture = _gfx->createTexture(border); + border->free(); + delete border; } } diff --git a/engines/freescape/games/driller/driller.cpp b/engines/freescape/games/driller/driller.cpp index 97ce479a819..c1e33edd9e2 100644 --- a/engines/freescape/games/driller/driller.cpp +++ b/engines/freescape/games/driller/driller.cpp @@ -29,59 +29,6 @@ namespace Freescape { -enum { - kDrillerCGAPalettePinkBlue = 0, - kDrillerCGAPaletteRedGreen = 1, -}; - -static const struct CGAPalettteEntry { - int areaId; - int palette; -} rawCGAPaletteTable[] { - {1, kDrillerCGAPaletteRedGreen}, - {2, kDrillerCGAPalettePinkBlue}, - {3, kDrillerCGAPaletteRedGreen}, - {4, kDrillerCGAPalettePinkBlue}, - {5, kDrillerCGAPaletteRedGreen}, - {6, kDrillerCGAPalettePinkBlue}, - {7, kDrillerCGAPaletteRedGreen}, - {8, kDrillerCGAPalettePinkBlue}, - {9, kDrillerCGAPaletteRedGreen}, - {10, kDrillerCGAPalettePinkBlue}, - {11, kDrillerCGAPaletteRedGreen}, - {12, kDrillerCGAPalettePinkBlue}, - - {14, kDrillerCGAPalettePinkBlue}, - - {16, kDrillerCGAPalettePinkBlue}, - - {19, kDrillerCGAPaletteRedGreen}, - {20, kDrillerCGAPalettePinkBlue}, - {21, kDrillerCGAPaletteRedGreen}, - {22, kDrillerCGAPalettePinkBlue}, - {23, kDrillerCGAPaletteRedGreen}, - - {28, kDrillerCGAPalettePinkBlue}, - - {32, kDrillerCGAPalettePinkBlue}, - {127, kDrillerCGAPaletteRedGreen}, - {0, 0} // This marks the end -}; - -byte kDrillerCGAPalettePinkBlueData[4][3] = { - {0x00, 0x00, 0x00}, - {0x00, 0xaa, 0xaa}, - {0xaa, 0x00, 0xaa}, - {0xaa, 0xaa, 0xaa}, -}; - -byte kDrillerCGAPaletteRedGreenData[4][3] = { - {0x00, 0x00, 0x00}, - {0x00, 0xaa, 0x00}, - {0xaa, 0x00, 0x00}, - {0xaa, 0x55, 0x00}, -}; - enum { kDrillerNoRig = 0, kDrillerRigInPlace = 1, @@ -147,7 +94,7 @@ void DrillerEngine::titleScreen() { if (isDOS() && isDemo()) // Demo will not show any title screen return; - if (isAmiga() || isAtariST()) // These releases has their own screens + if (isAmiga() || isAtariST()) // TODO: implement these with their own animations return; if (_title) { @@ -161,7 +108,7 @@ void DrillerEngine::borderScreen() { if (isDOS() && isDemo()) // Demo will not show the border return; - if (isAmiga() || isAtariST()) // These releases has their own screens + if (isAmiga() || isAtariST()) // TODO: implement these with their own animations return; if (_border) { @@ -346,47 +293,6 @@ void DrillerEngine::loadAssetsFullGame() { void DrillerEngine::processBorder() { FreescapeEngine::processBorder(); - if (isDOS() && _renderMode == Common::kRenderCGA) { // Replace some colors for the CGA borders - uint32 color1 = _border->format.ARGBToColor(0xFF, 0xAA, 0x00, 0xAA); - uint32 color2 = _border->format.ARGBToColor(0xFF, 0xAA, 0x55, 0x00); - - uint32 colorA = _border->format.ARGBToColor(0xFF, 0x00, 0xAA, 0xAA); - uint32 colorB = _border->format.ARGBToColor(0xFF, 0x00, 0xAA, 0x00); - - uint32 colorX = _border->format.ARGBToColor(0xFF, 0xAA, 0xAA, 0xAA); - uint32 colorY = _border->format.ARGBToColor(0xFF, 0xAA, 0x00, 0x00); - - Graphics::Surface *borderRedGreen = new Graphics::Surface(); - borderRedGreen->create(1, 1, _border->format); - borderRedGreen->copyFrom(*_border); - - for (int i = 0; i < _border->w; i++) { - for (int j = 0; j < _border->h; j++) { - if (borderRedGreen->getPixel(i, j) == color1) - borderRedGreen->setPixel(i, j, color2); - else if (borderRedGreen->getPixel(i, j) == colorA) - borderRedGreen->setPixel(i, j, colorB); - else if (borderRedGreen->getPixel(i, j) == colorX) - borderRedGreen->setPixel(i, j, colorY); - - } - } - Texture *borderTextureRedGreen = _gfx->createTexture(borderRedGreen); - - const CGAPalettteEntry *entry = rawCGAPaletteTable; - while (entry->areaId) { - - if (entry->palette == kDrillerCGAPaletteRedGreen) { - _borderCGAByArea[entry->areaId] = borderTextureRedGreen; - _paletteCGAByArea[entry->areaId] = (byte *)kDrillerCGAPaletteRedGreenData; - } else if (entry->palette == kDrillerCGAPalettePinkBlue) { - _borderCGAByArea[entry->areaId] = _borderTexture; - _paletteCGAByArea[entry->areaId] = (byte *)kDrillerCGAPalettePinkBlueData; - } else - error("Invalid CGA palette to use"); - entry++; - } - } } void DrillerEngine::drawUI() { diff --git a/engines/freescape/games/palettes.cpp b/engines/freescape/games/palettes.cpp index 1f4c8766fe6..97d4cfbf94c 100644 --- a/engines/freescape/games/palettes.cpp +++ b/engines/freescape/games/palettes.cpp @@ -155,6 +155,59 @@ void FreescapeEngine::loadPalettes(Common::SeekableReadStream *file, int offset) } } +enum { + kDrillerCGAPalettePinkBlue = 0, + kDrillerCGAPaletteRedGreen = 1, +}; + +static const struct CGAPalettteEntry { + int areaId; + int palette; +} rawCGAPaletteTable[] { + {1, kDrillerCGAPaletteRedGreen}, + {2, kDrillerCGAPalettePinkBlue}, + {3, kDrillerCGAPaletteRedGreen}, + {4, kDrillerCGAPalettePinkBlue}, + {5, kDrillerCGAPaletteRedGreen}, + {6, kDrillerCGAPalettePinkBlue}, + {7, kDrillerCGAPaletteRedGreen}, + {8, kDrillerCGAPalettePinkBlue}, + {9, kDrillerCGAPaletteRedGreen}, + {10, kDrillerCGAPalettePinkBlue}, + {11, kDrillerCGAPaletteRedGreen}, + {12, kDrillerCGAPalettePinkBlue}, + + {14, kDrillerCGAPalettePinkBlue}, + + {16, kDrillerCGAPalettePinkBlue}, + + {19, kDrillerCGAPaletteRedGreen}, + {20, kDrillerCGAPalettePinkBlue}, + {21, kDrillerCGAPaletteRedGreen}, + {22, kDrillerCGAPalettePinkBlue}, + {23, kDrillerCGAPaletteRedGreen}, + + {28, kDrillerCGAPalettePinkBlue}, + + {32, kDrillerCGAPalettePinkBlue}, + {127, kDrillerCGAPaletteRedGreen}, + {0, 0} // This marks the end +}; + +byte kDrillerCGAPalettePinkBlueData[4][3] = { + {0x00, 0x00, 0x00}, + {0x00, 0xaa, 0xaa}, + {0xaa, 0x00, 0xaa}, + {0xaa, 0xaa, 0xaa}, +}; + +byte kDrillerCGAPaletteRedGreenData[4][3] = { + {0x00, 0x00, 0x00}, + {0x00, 0xaa, 0x00}, + {0xaa, 0x00, 0x00}, + {0xaa, 0x55, 0x00}, +}; + void FreescapeEngine::swapPalette(uint16 levelID) { if (isAmiga() || isAtariST()) _gfx->_palette = _paletteByArea[levelID]; @@ -163,11 +216,28 @@ void FreescapeEngine::swapPalette(uint16 levelID) { _gfx->_paperColor = _areaMap[levelID]->_paperColor; _gfx->_underFireBackgroundColor = _areaMap[levelID]->_underFireBackgroundColor; } else if (isDOS() && _renderMode == Common::kRenderCGA) { - assert(_borderCGAByArea.contains(levelID)); - assert(_paletteCGAByArea.contains(levelID)); - _borderTexture = _borderCGAByArea.getVal(levelID); - _gfx->_palette = _paletteCGAByArea.getVal(levelID); + const CGAPalettteEntry *entry = rawCGAPaletteTable; + while (entry->areaId) { + if (entry->areaId == levelID) { + if (entry->palette == kDrillerCGAPaletteRedGreen) { + _gfx->_palette = (byte *)kDrillerCGAPaletteRedGreenData; + } else if (entry->palette == kDrillerCGAPalettePinkBlue) { + _gfx->_palette = (byte *)kDrillerCGAPalettePinkBlueData; + } else + error("Invalid CGA palette to use"); + break; + } + entry++; + } + + assert(entry->areaId == levelID); + _border->setPalette(_gfx->_palette, 0, 4); + processBorder(); + } else if (isDOS() && _renderMode == Common::kRenderEGA) { + _border->setPalette(_gfx->_palette, 0, 4); + processBorder(); } + } } // End of namespace Freescape diff --git a/engines/freescape/gfx.cpp b/engines/freescape/gfx.cpp index aeb830a9119..c0db20465c1 100644 --- a/engines/freescape/gfx.cpp +++ b/engines/freescape/gfx.cpp @@ -342,16 +342,18 @@ void Renderer::flipVertical(Graphics::Surface *s) { } } -void Renderer::convertImageFormatIfNecessary(Graphics::ManagedSurface *surface) { - if (!surface) - return; +Graphics::Surface *Renderer::convertImageFormatIfNecessary(Graphics::ManagedSurface *msurface) { + if (!msurface) + return nullptr; - if (surface->format != _texturePixelFormat) { - byte *palette = (byte *)malloc(sizeof(byte) * 16 * 3); - surface->grabPalette(palette, 0, 16); // Maximum should be 16 colours - surface->convertToInPlace(_texturePixelFormat, palette); - free(palette); - } + assert(msurface->format != _texturePixelFormat); + Graphics::Surface *surface = new Graphics::Surface(); + surface->copyFrom(msurface->rawSurface()); + byte *palette = (byte *)malloc(sizeof(byte) * 16 * 3); + msurface->grabPalette(palette, 0, 16); // Maximum should be 16 colours + surface->convertToInPlace(_texturePixelFormat, palette); + free(palette); + return surface; } Common::Rect Renderer::viewport() const { diff --git a/engines/freescape/gfx.h b/engines/freescape/gfx.h index 074ce8be090..867da87b0f0 100644 --- a/engines/freescape/gfx.h +++ b/engines/freescape/gfx.h @@ -77,7 +77,7 @@ public: virtual void polygonOffset(bool enabled) = 0; virtual Texture *createTexture(const Graphics::Surface *surface) = 0; - void convertImageFormatIfNecessary(Graphics::ManagedSurface *surface); + Graphics::Surface *convertImageFormatIfNecessary(Graphics::ManagedSurface *surface); virtual void freeTexture(Texture *texture) = 0; virtual void drawTexturedRect2D(const Common::Rect &screenRect, const Common::Rect &textureRect, Texture *texture) = 0; diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp index b62a5e6d28f..d9e1157be65 100644 --- a/engines/freescape/loaders/8bitBinaryLoader.cpp +++ b/engines/freescape/loaders/8bitBinaryLoader.cpp @@ -310,6 +310,7 @@ void FreescapeEngine::renderPixels8bitBinImage(Graphics::ManagedSurface *surface if (acc & pixels) { int previousColor = surface->getPixel(i, j); surface->setPixel(i, j, previousColor + color); + assert(previousColor + color < 16); } i++; acc = acc >> 1;