From c6230ebbf5bc0a80e50a58e6652c828b75c83dcf Mon Sep 17 00:00:00 2001 From: athrxx Date: Wed, 20 Feb 2019 23:26:19 +0100 Subject: KYRA: (EOB1/Amiga) - improve scaled item handling --- engines/kyra/engine/eobcommon.cpp | 64 ++++++++++++++++++++++++++++++++++-- engines/kyra/engine/eobcommon.h | 3 ++ engines/kyra/engine/scene_eob.cpp | 2 +- engines/kyra/engine/sprites_eob.cpp | 25 +++++++++++--- engines/kyra/graphics/screen_eob.cpp | 3 +- 5 files changed, 87 insertions(+), 10 deletions(-) diff --git a/engines/kyra/engine/eobcommon.cpp b/engines/kyra/engine/eobcommon.cpp index a184b7ff3e..c7aaf400b1 100644 --- a/engines/kyra/engine/eobcommon.cpp +++ b/engines/kyra/engine/eobcommon.cpp @@ -65,6 +65,10 @@ EoBCoreEngine::EoBCoreEngine(OSystem *system, const GameFlags &flags) : KyraRpgE _redSplatShape = _greenSplatShape = _deadCharShape = _disabledCharGrid = 0; _blackBoxSmallGrid = _weaponSlotGrid = _blackBoxWideGrid = _lightningColumnShape = 0; + memset(_largeItemShapesScl, 0, sizeof(_largeItemShapesScl)); + memset(_smallItemShapesScl, 0, sizeof(_smallItemShapesScl)); + memset(_thrownItemShapesScl, 0, sizeof(_thrownItemShapesScl)); + _monsterAcHitChanceTable1 = _monsterAcHitChanceTable2 = 0; _monsterDustStrings = 0; @@ -733,6 +737,14 @@ void EoBCoreEngine::loadItemsAndDecorationsShapes() { _screen->loadShapeSetBitmap("ITEML1", 5, 3); for (int i = 0; i < _numLargeItemShapes; i++) _largeItemShapes[i] = _screen->encodeShape((i / div) << 3, (i % div) * mul, 8, 24, false, _cgaMappingItemsL); + + if (_flags.gameID == GI_EOB1) { + for (int c = 0; c < 3; ++c) { + _largeItemShapesScl[c] = new const uint8*[_numLargeItemShapes]; + for (int i = 0; i < _numLargeItemShapes; i++) + _largeItemShapesScl[c][i] = _screen->encodeShape((i / div) << 3, (i % div) * mul + 24 + (c << 4), 6 - 2 * c, 16 - ((c >> 1) << 3), false, _cgaMappingItemsL); + } + } } _smallItemShapes = new const uint8*[_numSmallItemShapes]; @@ -743,11 +755,21 @@ void EoBCoreEngine::loadItemsAndDecorationsShapes() { _screen->loadShapeSetBitmap("ITEMS1", 5, 3); for (int i = 0; i < _numSmallItemShapes; i++) _smallItemShapes[i] = _screen->encodeShape((i / div) << 2, (i % div) * mul, 4, 24, false, _cgaMappingItemsS); + + if (_flags.gameID == GI_EOB1) { + for (int c = 0; c < 3; ++c) { + _smallItemShapesScl[c] = new const uint8*[_numSmallItemShapes]; + for (int i = 0; i < _numSmallItemShapes; i++) + _smallItemShapesScl[c][i] = _screen->encodeShape((i / div) << 2, (i % div) * mul + 24 + (c << 4), 3 - c, 16 - ((c >> 1) << 3), false, _cgaMappingItemsS); + } + } } _thrownItemShapes = new const uint8*[_numThrownItemShapes]; - _spellShapes = new const uint8*[4]; + if (_flags.gameID == GI_EOB2) + _spellShapes = new const uint8*[4]; _firebeamShapes = new const uint8*[3]; + if (_flags.platform == Common::kPlatformFMTowns && _flags.gameID == GI_EOB2) { for (int i = 0; i < _numThrownItemShapes; i++) _thrownItemShapes[i] = _staticres->loadRawData(kEoB2ThrownShapeData00 + i, size); @@ -761,8 +783,17 @@ void EoBCoreEngine::loadItemsAndDecorationsShapes() { _screen->loadShapeSetBitmap("THROWN", 5, 3); for (int i = 0; i < _numThrownItemShapes; i++) _thrownItemShapes[i] = _screen->encodeShape((i / div) << 2, (i % div) * mul, 4, 24, false, _cgaMappingThrown); - for (int i = 0; i < 4; i++) - _spellShapes[i] = _screen->encodeShape(8, i << 5, 6, 32, false, _cgaMappingThrown); + + if (_flags.gameID == GI_EOB1) { + for (int c = 0; c < 3; ++c) { + _thrownItemShapesScl[c] = new const uint8*[_numThrownItemShapes]; + for (int i = 0; i < _numThrownItemShapes; i++) + _thrownItemShapesScl[c][i] = _screen->encodeShape((i / div) << 2, (i % div) * mul + 24 + (c << 4), 3 - c, 16 - ((c >> 1) << 3), false, _cgaMappingThrown); + } + } else { + for (int i = 0; i < 4; i++) + _spellShapes[i] = _screen->encodeShape(8, i << 5, 6, 32, false, _cgaMappingThrown); + } _firebeamShapes[0] = _screen->encodeShape(16, 0, 4, 24, false, _cgaMappingThrown); _firebeamShapes[1] = _screen->encodeShape(16, 24, 4, 24, false, _cgaMappingThrown); @@ -943,6 +974,33 @@ void EoBCoreEngine::releaseItemsAndDecorationsShapes() { delete[] _teleporterShapes; delete[] _compassShapes; delete[] _firebeamShapes; + + for (int i = 0; i < 3; ++i) { + if (_largeItemShapesScl[i]) { + for (int ii = 0; ii < _numLargeItemShapes; ++ii) { + if (_largeItemShapesScl[i][ii]) + delete[] _largeItemShapesScl[i][ii]; + } + } + + if (_smallItemShapesScl[i]) { + for (int ii = 0; ii < _numSmallItemShapes; ++ii) { + if (_smallItemShapesScl[i][ii]) + delete[] _smallItemShapesScl[i][ii]; + } + } + + if (_thrownItemShapesScl[i]) { + for (int ii = 0; ii < _numThrownItemShapes; ++ii) { + if (_thrownItemShapesScl[i][ii]) + delete[] _thrownItemShapesScl[i][ii]; + } + } + + delete[] _largeItemShapesScl[i]; + delete[] _smallItemShapesScl[i]; + delete[] _thrownItemShapesScl[i]; + } } void EoBCoreEngine::setHandItem(Item itemIndex) { diff --git a/engines/kyra/engine/eobcommon.h b/engines/kyra/engine/eobcommon.h index 3d71fe09c0..b9785ac1bf 100644 --- a/engines/kyra/engine/eobcommon.h +++ b/engines/kyra/engine/eobcommon.h @@ -283,6 +283,9 @@ protected: const uint8 **_largeItemShapes; const uint8 **_smallItemShapes; const uint8 **_thrownItemShapes; + const uint8 **_largeItemShapesScl[3]; + const uint8 **_smallItemShapesScl[3]; + const uint8 **_thrownItemShapesScl[3]; const int _numLargeItemShapes; const int _numSmallItemShapes; const int _numThrownItemShapes; diff --git a/engines/kyra/engine/scene_eob.cpp b/engines/kyra/engine/scene_eob.cpp index fb334bf791..7eab7ce55f 100644 --- a/engines/kyra/engine/scene_eob.cpp +++ b/engines/kyra/engine/scene_eob.cpp @@ -189,7 +189,7 @@ Common::String EoBCoreEngine::initLevelData(int sub) { _screen->createFadeTable16bit(src, (uint16*)_greyFadingTable, 0, 85); _screen->setScreenPalette(_screen->getPalette(0)); } else if (_flags.platform == Common::kPlatformAmiga) { - + // Amiga versions don't have shape shading } else if (_configRenderMode != Common::kRenderCGA) { Palette backupPal(256); backupPal.copy(_screen->getPalette(0), 224, 32, 224); diff --git a/engines/kyra/engine/sprites_eob.cpp b/engines/kyra/engine/sprites_eob.cpp index 540710e1ac..5e2e58ea85 100644 --- a/engines/kyra/engine/sprites_eob.cpp +++ b/engines/kyra/engine/sprites_eob.cpp @@ -453,7 +453,12 @@ void EoBCoreEngine::drawBlockItems(int index) { } if (scaleSteps >= 0) { - const uint8 *shp = _screen->scaleShape(_dscItemShapeMap[itm->icon] < _numLargeItemShapes ? _largeItemShapes[_dscItemShapeMap[itm->icon]] : (_dscItemShapeMap[itm->icon] < 15 ? 0 : _smallItemShapes[_dscItemShapeMap[itm->icon] - 15]), scaleSteps); + const uint8 *shp = 0; + if (_flags.gameID == GI_EOB2 || scaleSteps == 0) + shp = _screen->scaleShape(_dscItemShapeMap[itm->icon] < _numLargeItemShapes ? _largeItemShapes[_dscItemShapeMap[itm->icon]] : (_dscItemShapeMap[itm->icon] < 15 ? 0 : _smallItemShapes[_dscItemShapeMap[itm->icon] - 15]), scaleSteps); + else + shp = _dscItemShapeMap[itm->icon] < _numLargeItemShapes ? _largeItemShapesScl[scaleSteps - 1][_dscItemShapeMap[itm->icon]] : (_dscItemShapeMap[itm->icon] < 15 ? 0 : _smallItemShapesScl[scaleSteps - 1][_dscItemShapeMap[itm->icon] - 15]); + x = x + (itemPosFin[o & 7] << 1) - ((shp[2] << 3) >> 1); y -= shp[1]; @@ -658,16 +663,25 @@ void EoBCoreEngine::drawFlyingObjects(int index) { int dirOffs = (fo->direction == _currentDirection) ? 0 : ((fo->direction == (_currentDirection ^ 2)) ? 1 : -1); if (dirOffs == -1 || _flightObjShpMap[shpIx] == -1) { - shp = shpIx < _numLargeItemShapes ? _largeItemShapes[shpIx] : (shpIx < 15 ? 0 : _smallItemShapes[shpIx - 15]); + if (_flags.gameID == GI_EOB2 || sclValue == 0) + shp = shpIx < _numLargeItemShapes ? _largeItemShapes[shpIx] : (shpIx < 15 ? 0 : _smallItemShapes[shpIx - 15]); + else + shp = shpIx < _numLargeItemShapes ? _largeItemShapesScl[sclValue - 1][shpIx] : (shpIx < 15 ? 0 : _smallItemShapesScl[sclValue - 1][shpIx - 15]); flipped = fo->direction == ((_currentDirection + 1) & 3) ? 1 : 0; } else { - shp = (_flightObjShpMap[shpIx] + dirOffs) < _numThrownItemShapes ? _thrownItemShapes[_flightObjShpMap[shpIx] + dirOffs] : _spellShapes[_flightObjShpMap[shpIx - _numThrownItemShapes] + dirOffs]; + if (_flags.gameID == GI_EOB2 || sclValue == 0) + shp = (_flightObjShpMap[shpIx] + dirOffs) < _numThrownItemShapes ? _thrownItemShapes[_flightObjShpMap[shpIx] + dirOffs] : _spellShapes[_flightObjShpMap[shpIx - _numThrownItemShapes] + dirOffs]; + else + shp = (_flightObjShpMap[shpIx] + dirOffs) < _numThrownItemShapes ? _thrownItemShapesScl[sclValue - 1][_flightObjShpMap[shpIx] + dirOffs] : 0; flipped = _flightObjFlipIndex[(fo->direction << 2) + (fo->curPos & 3)]; } } else { noFade = true; - shp = (fo->objectType < _numThrownItemShapes) ? _thrownItemShapes[fo->objectType] : _spellShapes[fo->objectType - _numThrownItemShapes]; + if (_flags.gameID == GI_EOB2 || sclValue == 0) + shp = (fo->objectType < _numThrownItemShapes) ? _thrownItemShapes[fo->objectType] : _spellShapes[fo->objectType - _numThrownItemShapes]; + else + shp = (fo->objectType < _numThrownItemShapes) ? _thrownItemShapesScl[sclValue - 1][fo->objectType] : 0; flipped = _flightObjFlipIndex[(fo->direction << 2) + (fo->curPos & 3)]; if (fo->flags & 0x40) { @@ -678,7 +692,8 @@ void EoBCoreEngine::drawFlyingObjects(int index) { assert(shp); - shp = _screen->scaleShape(shp, sclValue); + if (_flags.gameID == GI_EOB2 || sclValue == 0) + shp = _screen->scaleShape(shp, sclValue); if (noFade) { _screen->setShapeFadingLevel(0); diff --git a/engines/kyra/graphics/screen_eob.cpp b/engines/kyra/graphics/screen_eob.cpp index 823740cc6a..90e2d1f41f 100644 --- a/engines/kyra/graphics/screen_eob.cpp +++ b/engines/kyra/graphics/screen_eob.cpp @@ -1534,7 +1534,7 @@ void Screen_EoB::drawShapeSetPixel(uint8 *dst, uint8 col) { if (_bytesPerPixel == 2) { *(uint16*)dst = _16bitPalette[(_dsShapeFadingLevel << 8) + col]; return; - } else if ((_renderMode != Common::kRenderCGA && _renderMode != Common::kRenderEGA) || _useHiResEGADithering) { + } else if ((!_isAmiga && _renderMode != Common::kRenderCGA && _renderMode != Common::kRenderEGA) || _useHiResEGADithering) { if (_dsBackgroundFading) { if (_dsShapeFadingLevel) { col = *dst; @@ -1545,6 +1545,7 @@ void Screen_EoB::drawShapeSetPixel(uint8 *dst, uint8 col) { } if (_dsShapeFadingLevel) { + assert(_dsShapeFadingTable); uint8 cnt = _dsShapeFadingLevel; while (cnt--) col = _dsShapeFadingTable[col]; -- cgit v1.2.3