mirror of
https://github.com/libretro/scummvm.git
synced 2025-05-13 09:36:21 +00:00
FREESCAPE: allow to change the palette of title and border per level using managed surfaces
This commit is contained in:
parent
3c9cbb3fe0
commit
22fcff4ece
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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() {
|
||||
|
@ -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
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user