aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
authorathrxx2019-03-26 22:37:50 +0100
committerathrxx2019-04-13 18:55:01 +0200
commit69f2e0caaa3b7257318f2e9943d233da45bfab80 (patch)
tree4fbd19a73fd00d6bac849185388f76b32ab986fe /engines
parentcbe81aa021bab1082ee6a652cbd15fe323ea2069 (diff)
downloadscummvm-rg350-69f2e0caaa3b7257318f2e9943d233da45bfab80.tar.gz
scummvm-rg350-69f2e0caaa3b7257318f2e9943d233da45bfab80.tar.bz2
scummvm-rg350-69f2e0caaa3b7257318f2e9943d233da45bfab80.zip
KYRA: (EOB2/Amiga) - fix ingame colors
Diffstat (limited to 'engines')
-rw-r--r--engines/kyra/engine/darkmoon.cpp3
-rw-r--r--engines/kyra/engine/eobcommon.cpp17
-rw-r--r--engines/kyra/engine/scene_eob.cpp10
-rw-r--r--engines/kyra/engine/scene_rpg.cpp12
-rw-r--r--engines/kyra/engine/sprites_eob.cpp3
-rw-r--r--engines/kyra/graphics/screen.cpp12
-rw-r--r--engines/kyra/graphics/screen.h1
-rw-r--r--engines/kyra/graphics/screen_eob.cpp57
-rw-r--r--engines/kyra/graphics/screen_eob.h7
-rw-r--r--engines/kyra/gui/gui_eob.cpp13
-rw-r--r--engines/kyra/script/script_eob.cpp3
-rw-r--r--engines/kyra/sequence/sequences_darkmoon.cpp3
12 files changed, 116 insertions, 25 deletions
diff --git a/engines/kyra/engine/darkmoon.cpp b/engines/kyra/engine/darkmoon.cpp
index c7a91c7fd5..8d621b9bc9 100644
--- a/engines/kyra/engine/darkmoon.cpp
+++ b/engines/kyra/engine/darkmoon.cpp
@@ -153,6 +153,9 @@ void DarkMoonEngine::updateUsedCharacterHandItem(int charIndex, int slot) {
}
void DarkMoonEngine::generateMonsterPalettes(const char *file, int16 monsterIndex) {
+ if (_flags.platform == Common::kPlatformAmiga)
+ return;
+
int cp = _screen->setCurPage(2);
_screen->loadShapeSetBitmap(file, 3, 3);
uint8 tmpPal[16];
diff --git a/engines/kyra/engine/eobcommon.cpp b/engines/kyra/engine/eobcommon.cpp
index 1c75c78d70..798bfb6a93 100644
--- a/engines/kyra/engine/eobcommon.cpp
+++ b/engines/kyra/engine/eobcommon.cpp
@@ -1639,12 +1639,15 @@ void EoBCoreEngine::drawSequenceBitmap(const char *file, int destRect, int x1, i
static const uint8 frameH[] = { 96, 121 };
int page = ((flags & 2) || destRect) ? 0 : 6;
+ int amigaPalIndex = (x1 ? 1 : 0) + (y1 ? 2 : 0) + 1;
if (scumm_stricmp(_dialogueLastBitmap, file)) {
_screen->clearPage(2);
if (!destRect) {
if (!(flags & 1)) {
_screen->loadEoBBitmap("BORDER", 0, 3, 3, 2);
+ if (_flags.platform == Common::kPlatformAmiga)
+ _screen->copyRegion(0, 0, 0, 0, 320, 122, 2, 0, Screen::CR_NO_P_CHECK);
_screen->copyRegion(0, 0, 0, 0, 184, 121, 2, page, Screen::CR_NO_P_CHECK);
} else {
_screen->copyRegion(0, 0, 0, 0, 184, 121, 0, page, Screen::CR_NO_P_CHECK);
@@ -1658,13 +1661,25 @@ void EoBCoreEngine::drawSequenceBitmap(const char *file, int destRect, int x1, i
strcpy(_dialogueLastBitmap, file);
}
+ if (_flags.platform == Common::kPlatformAmiga) {
+ int cp = _screen->setCurPage(0);
+ if (!_dialogueFieldAmiga)
+ gui_drawDialogueBox();
+ _screen->drawClippedLine(0, 120, 319, 120, 9);
+ _screen->drawClippedLine(0, 121, 319, 121, guiSettings()->colors.fill);
+ _screen->setPagePixel(0, 319, 121, 9);
+ _screen->setCurPage(cp);
+ _screen->setupDualPalettesSplitScreen(_screen->getPalette(amigaPalIndex), _screen->getPalette(7));
+ _dialogueFieldAmiga = true;
+ }
+
if (flags & 2)
_screen->crossFadeRegion(x1 << 3, y1, frameX[destRect] << 3, frameY[destRect], frameW[destRect] << 3, frameH[destRect], 2, page);
else
_screen->copyRegion(x1 << 3, y1, frameX[destRect] << 3, frameY[destRect], frameW[destRect] << 3, frameH[destRect], 2, page, Screen::CR_NO_P_CHECK);
if (page == 6)
- _screen->copyRegion(0, 0, 0, 0, 184, 121, 6, 0, Screen::CR_NO_P_CHECK);
+ _screen->copyRegion(0, 0, 0, 0, 184, (_flags.platform == Common::kPlatformAmiga) ? 110 : 121, 6, 0, Screen::CR_NO_P_CHECK);
_screen->updateScreen();
}
diff --git a/engines/kyra/engine/scene_eob.cpp b/engines/kyra/engine/scene_eob.cpp
index 9a2f4e2f93..7f3c464939 100644
--- a/engines/kyra/engine/scene_eob.cpp
+++ b/engines/kyra/engine/scene_eob.cpp
@@ -96,7 +96,7 @@ void EoBCoreEngine::loadLevel(int level, int sub) {
loadVcnData(gfxFile.c_str(), (_flags.gameID == GI_EOB1 && _flags.platform == Common::kPlatformDOS) ? _cgaMappingLevel[_cgaLevelMappingIndex[level - 1]] : 0);
_screen->loadEoBBitmap("INVENT", _cgaMappingInv, 5, 3, 2);
- if (_flags.platform == Common::kPlatformAmiga)
+ if (_flags.platform == Common::kPlatformAmiga && _flags.gameID == GI_EOB1)
_screen->getPalette(0).copy(_screen->getPalette(1), 1, 5, 1);
delayUntil(end);
@@ -190,8 +190,8 @@ Common::String EoBCoreEngine::initLevelData(int sub) {
_screen->enableShapeBackgroundFading(false);
}
- if (_flags.platform != Common::kPlatformAmiga && (_flags.gameID == GI_EOB2 || _configRenderMode != Common::kRenderEGA))
- _screen->loadPalette(tmpStr.c_str(), _screen->getPalette(0));
+ if (_flags.gameID == GI_EOB2 || (_flags.platform != Common::kPlatformAmiga && _configRenderMode != Common::kRenderCGA && _configRenderMode != Common::kRenderEGA))
+ _screen->loadPalette(tmpStr.c_str(), _screen->getPalette(_flags.platform == Common::kPlatformAmiga ? 6 : 0));
if (_flags.platform == Common::kPlatformFMTowns) {
uint16 *src = (uint16*)_screen->getPalette(0).getData();
@@ -368,7 +368,7 @@ void EoBCoreEngine::loadVcnData(const char *file, const uint8 *cgaMapping) {
}
}
} else {
- if (!(_flags.gameID == GI_EOB1 && _configRenderMode == Common::kRenderEGA))
+ if (_flags.platform != Common::kPlatformAmiga && !(_flags.gameID == GI_EOB1 && _configRenderMode == Common::kRenderEGA))
memcpy(_vcnColTable, colMap, 32);
memcpy(_vcnBlocks, pos, vcnSize);
@@ -546,7 +546,7 @@ void EoBCoreEngine::drawScene(int refresh) {
if (_sceneDrawPage2) {
if (refresh)
- _screen->fillRect(0, 0, 176, 120, 12);
+ _screen->fillRect(0, 0, 176, 120, guiSettings()->colors.guiColorBlack);
if (!_loading)
_screen->setScreenPalette(_screen->getPalette(0));
diff --git a/engines/kyra/engine/scene_rpg.cpp b/engines/kyra/engine/scene_rpg.cpp
index 4c0a97e7c7..1bb777f51c 100644
--- a/engines/kyra/engine/scene_rpg.cpp
+++ b/engines/kyra/engine/scene_rpg.cpp
@@ -534,20 +534,20 @@ void KyraRpgEngine::vcnDraw_bw_trans_hiCol(uint8 *&dst, const uint8 *&src) {
void KyraRpgEngine::vcnDraw_fw_Amiga(uint8 *&dst, const uint8 *&src) {
for (int blockX = 0; blockX < 8; blockX++) {
- *dst = 0;
+ uint8 col = 0;
for (int i = 0; i < 5; ++i)
- *dst |= (((src[i] & (0x80 >> blockX)) >> (7 - blockX)) << i);
- dst++;
+ col |= (((src[i] & (0x80 >> blockX)) >> (7 - blockX)) << i);
+ *dst++ = col;
}
src += 5;
}
void KyraRpgEngine::vcnDraw_bw_Amiga(uint8 *&dst, const uint8 *&src) {
for (int blockX = 7; blockX >= 0; blockX--) {
- *dst = 0;
+ uint8 col = 0;
for (int i = 0; i < 5; ++i)
- *dst |= (((src[i] & (0x80 >> blockX)) >> (7 - blockX)) << i);
- dst++;
+ col |= (((src[i] & (0x80 >> blockX)) >> (7 - blockX)) << i);
+ *dst++ = col;
}
src += 5;
}
diff --git a/engines/kyra/engine/sprites_eob.cpp b/engines/kyra/engine/sprites_eob.cpp
index 5e2e58ea85..f7e65f2133 100644
--- a/engines/kyra/engine/sprites_eob.cpp
+++ b/engines/kyra/engine/sprites_eob.cpp
@@ -363,6 +363,7 @@ void EoBCoreEngine::drawBlockObject(int flipped, int page, const uint8 *shape, i
const ScreenDim *d = _screen->getScreenDim(sd);
if (_flags.gameID == GI_EOB1)
x &= ~1;
+
_screen->drawShape(page, shape, x - (d->sx << 3), y - d->sy, sd, flipped | (ovl ? 2 : 0), ovl);
}
@@ -373,7 +374,7 @@ void EoBCoreEngine::drawMonsterShape(const uint8 *shape, int x, int y, int flipp
ovl = _monsterFlashOverlay;
else if (_flags.gameID == GI_EOB2 && flags & 0x20)
ovl = _monsterStoneOverlay;
- else if (palIndex != -1)
+ else if (palIndex != -1 && _flags.platform != Common::kPlatformAmiga)
ovl = _monsterPalettes[palIndex];
drawBlockObject(flipped, 2, shape, x, y, 5, ovl);
diff --git a/engines/kyra/graphics/screen.cpp b/engines/kyra/graphics/screen.cpp
index ea0871f317..b69cc07e77 100644
--- a/engines/kyra/graphics/screen.cpp
+++ b/engines/kyra/graphics/screen.cpp
@@ -100,6 +100,8 @@ bool Screen::init() {
_useSJIS = false;
_use16ColorMode = _vm->gameFlags().use16ColorMode;
_isAmiga = (_vm->gameFlags().platform == Common::kPlatformAmiga);
+ // Amiga copper palette magic requires the use of more than 32 colors for some purposes.
+ _useAmigaExtraColors = (_isAmiga && _vm->game() == GI_EOB2);
// We only check the "render_mode" setting for both Eye of the Beholder
// games here, since all the other games do not support the render_mode
@@ -174,14 +176,18 @@ bool Screen::init() {
const int paletteCount = _isAmiga ? 13 : 4;
// We allow 256 color palettes in EGA mode, since original EOB II code does the same and requires it
const int numColors = _use16ColorMode ? 16 : (_isAmiga ? 32 : (_renderMode == Common::kRenderCGA ? 4 : 256));
+ const int numColorsInternal = _useAmigaExtraColors ? 64 : numColors;
_interfacePaletteEnabled = false;
- _screenPalette = new Palette(numColors);
+ _screenPalette = new Palette(numColorsInternal);
assert(_screenPalette);
_palettes.resize(paletteCount);
- for (int i = 0; i < paletteCount; ++i) {
+ _palettes[0] = new Palette(numColorsInternal);
+ assert(_palettes[0]);
+
+ for (int i = 1; i < paletteCount; ++i) {
_palettes[i] = new Palette(numColors);
assert(_palettes[i]);
}
@@ -195,7 +201,7 @@ bool Screen::init() {
Screen::setScreenPalette(pal);
}
- _internFadePalette = new Palette(numColors);
+ _internFadePalette = new Palette(numColorsInternal);
assert(_internFadePalette);
setScreenPalette(getPalette(0));
diff --git a/engines/kyra/graphics/screen.h b/engines/kyra/graphics/screen.h
index b6706cd14f..b1b2d86e48 100644
--- a/engines/kyra/graphics/screen.h
+++ b/engines/kyra/graphics/screen.h
@@ -687,6 +687,7 @@ protected:
bool _useHiResEGADithering;
bool _useHiColorScreen;
bool _isAmiga;
+ bool _useAmigaExtraColors;
Common::RenderMode _renderMode;
int _bytesPerPixel;
int _screenPageSize;
diff --git a/engines/kyra/graphics/screen_eob.cpp b/engines/kyra/graphics/screen_eob.cpp
index 2e2674d9dd..0e5596221e 100644
--- a/engines/kyra/graphics/screen_eob.cpp
+++ b/engines/kyra/graphics/screen_eob.cpp
@@ -62,7 +62,7 @@ Screen_EoB::Screen_EoB(EoBCoreEngine *vm, OSystem *system) : Screen(vm, system,
_egaDitheringTempPage = 0;
_cgaMappingDefault = 0;
_cgaDitheringTables[0] = _cgaDitheringTables[1] = 0;
- _useHiResEGADithering = false;
+ _useHiResEGADithering = _dualPaletteMode = false;
}
Screen_EoB::~Screen_EoB() {
@@ -165,6 +165,13 @@ void Screen_EoB::setMouseCursor(int x, int y, const byte *shape, const uint8 *ov
else
copyRegionToBuffer(6, 0, 0, mouseW, mouseH, cursor);
+ // Mouse cursor post processing for EOB II Amiga
+ if (_dualPaletteMode) {
+ int len = mouseW * mouseH;
+ while (--len > -1)
+ cursor[len] |= 0x20;
+ }
+
// Mouse cursor post processing for CGA mode. Unlike the original (which uses drawShape for the mouse cursor)
// the cursor manager cannot know whether a pixel value of 0 is supposed to be black or transparent. Thus, we
// go over the transparency mask again and turn the black pixels to color 4.
@@ -280,7 +287,7 @@ void Screen_EoB::loadEoBBitmap(const char *file, const uint8 *cgaMapping, int te
}
if (!loadAlternative)
- loadBitmap(tmp.c_str(), tempPage, destPage, 0);
+ loadBitmap(tmp.c_str(), tempPage, destPage, _vm->gameFlags().platform == Common::kPlatformAmiga ? _palettes[0] : 0);
} else {
loadAlternative = true;
@@ -1643,23 +1650,63 @@ void Screen_EoB::loadSpecialAmigaCPS(const char *fileName, int destPage, bool is
convertAmigaGfx(_pagePtrs[destPage], 320, 200);
}
+void Screen_EoB::setupDualPalettesSplitScreen(Palette &top, Palette &bottom) {
+ // The original supports simultaneous fading of both palettes, but doesn't make any use of that
+ // feature. The fade rate is always set to 0. So I see no need to implement that.
+ _palettes[0]->copy(top, 0, 32, 0);
+ _palettes[0]->copy(bottom, 0, 32, 32);
+ setScreenPalette(*_palettes[0]);
+ _dualPaletteMode = _forceFullUpdate = true;
+}
+
+void Screen_EoB::disableDualPalettesSplitScreen() {
+ _dualPaletteMode = false;
+ _forceFullUpdate = true;
+}
+
void Screen_EoB::updateDirtyRects() {
- if (!_useHiResEGADithering) {
+ if (!_useHiResEGADithering && !_dualPaletteMode) {
Screen::updateDirtyRects();
return;
}
- if (_forceFullUpdate) {
+ if (_dualPaletteMode && _forceFullUpdate) {
+ uint32 *pos = (uint32*)(_pagePtrs[0] + 120 * SCREEN_W);
+ uint16 h = 80 * (SCREEN_W >> 2);
+ while (h--)
+ *pos++ |= 0x20202020;
+ _system->copyRectToScreen(getCPagePtr(0), SCREEN_W, 0, 0, SCREEN_W, SCREEN_H);
+
+ } else if (_dualPaletteMode) {
+ Common::List<Common::Rect>::iterator it;
+ for (it = _dirtyRects.begin(); it != _dirtyRects.end(); ++it) {
+ if (it->bottom > 119) {
+ int16 startY = MAX<int16>(120, it->top);
+ int16 h = it->bottom - startY + 1;
+ int16 w = it->width();
+ uint8 *pos = _pagePtrs[0] + startY * SCREEN_W + it->left;
+ while (h--) {
+ for (int x = 0; x < w; ++x)
+ *pos++ |= 0x20;
+ pos += (SCREEN_W - w);
+ }
+ }
+ _system->copyRectToScreen(_pagePtrs[0] + it->top * SCREEN_W + it->left, SCREEN_W, it->left, it->top, it->width(), it->height());
+ }
+
+ } else if (_forceFullUpdate) {
ditherRect(getCPagePtr(0), _egaDitheringTempPage, SCREEN_W * 2, SCREEN_W, SCREEN_H);
_system->copyRectToScreen(_egaDitheringTempPage, SCREEN_W * 2, 0, 0, SCREEN_W * 2, SCREEN_H * 2);
+
} else {
- const byte *page0 = getCPagePtr(0);
+ const uint8 *page0 = getCPagePtr(0);
Common::List<Common::Rect>::iterator it;
for (it = _dirtyRects.begin(); it != _dirtyRects.end(); ++it) {
ditherRect(page0 + it->top * SCREEN_W + it->left, _egaDitheringTempPage, SCREEN_W * 2, it->width(), it->height());
_system->copyRectToScreen(_egaDitheringTempPage, SCREEN_W * 2, it->left * 2, it->top * 2, it->width() * 2, it->height() * 2);
}
}
+
_forceFullUpdate = false;
_dirtyRects.clear();
}
diff --git a/engines/kyra/graphics/screen_eob.h b/engines/kyra/graphics/screen_eob.h
index 66efc25cc0..5df67df506 100644
--- a/engines/kyra/graphics/screen_eob.h
+++ b/engines/kyra/graphics/screen_eob.h
@@ -93,6 +93,12 @@ public:
// Amiga specific
void loadSpecialAmigaCPS(const char *fileName, int destPage, bool isGraphics);
+ // This is a simple way of emulating the Amiga copper list palette magic for more than 32 colors.
+ // I use colors 32 to 63 for these extra colors (which the Amiga copper sends to the color
+ // registers on the fly at vertical beam position 120).
+ void setupDualPalettesSplitScreen(Palette &top, Palette &bottom);
+ void disableDualPalettesSplitScreen();
+
private:
void updateDirtyRects();
void ditherRect(const uint8 *src, uint8 *dst, int dstPitch, int srcW, int srcH, int colorKey = -1);
@@ -122,6 +128,7 @@ private:
uint8 *_dsTempPage;
uint8 *_shpBuffer;
uint8 *_convertHiColorBuffer;
+ bool _dualPaletteMode;
uint16 *_cgaDitheringTables[2];
const uint8 *_cgaMappingDefault;
diff --git a/engines/kyra/gui/gui_eob.cpp b/engines/kyra/gui/gui_eob.cpp
index bfde732ffe..981a33fb52 100644
--- a/engines/kyra/gui/gui_eob.cpp
+++ b/engines/kyra/gui/gui_eob.cpp
@@ -61,8 +61,15 @@ void EoBCoreEngine::gui_drawPlayField(bool refresh) {
_screen->updateScreen();
_screen->loadEoBBitmap("INVENT", _cgaMappingInv, 5, 3, 2);
- if (_flags.platform == Common::kPlatformAmiga)
- _screen->getPalette(0).copy(_screen->getPalette(1), 1, 5, 1);
+
+ if (_flags.platform == Common::kPlatformAmiga) {
+ if (_flags.gameID == GI_EOB1) {
+ _screen->getPalette(0).copy(_screen->getPalette(1), 1, 5, 1);
+ } else {
+ _screen->setupDualPalettesSplitScreen(_screen->getPalette(6), _screen->getPalette(1));
+ _screen->getPalette(7).copy(_screen->getPalette(1), 0, 32);
+ }
+ }
}
void EoBCoreEngine::gui_restorePlayField() {
@@ -3233,7 +3240,7 @@ void GUI_EoB::runMemorizePrayMenu(int charIndex, int spellType) {
if (updateDesc) {
updateDesc = false;
_screen->set16bitShadingLevel(4);
- _screen->printShadedText(Common::String::format(_vm->_menuStringsMgc[1], np[lastHighLightButton] - numAssignedSpellsPerBookPage[lastHighLightButton], np[lastHighLightButton]).c_str(), 8, 38, 9, _vm->guiSettings()->colors.fill, _vm->guiSettings()->colors.guiColorBlack);
+ _screen->printShadedText(Common::String::format(_vm->_menuStringsMgc[1], np[lastHighLightButton] - numAssignedSpellsPerBookPage[lastHighLightButton], np[lastHighLightButton]).c_str(), 8, 38, _vm->guiSettings()->colors.guiColorLightBlue, _vm->guiSettings()->colors.fill, _vm->guiSettings()->colors.guiColorBlack);
_screen->set16bitShadingLevel(0);
}
diff --git a/engines/kyra/script/script_eob.cpp b/engines/kyra/script/script_eob.cpp
index b063b08a6e..1c96a53498 100644
--- a/engines/kyra/script/script_eob.cpp
+++ b/engines/kyra/script/script_eob.cpp
@@ -1319,6 +1319,9 @@ int EoBInfProcessor::oeob_loadNewLevelOrMonsters(int8 *data) {
_vm->gui_drawAllCharPortraitsWithStats();
_subroutineStackPos = 0;
+ if (_vm->_flags.gameID == GI_EOB2 && _vm->_flags.platform == Common::kPlatformAmiga)
+ _vm->gui_restorePlayField();
+
} else {
cmd = *pos++;
_vm->releaseMonsterShapes(cmd * 18, 18);
diff --git a/engines/kyra/sequence/sequences_darkmoon.cpp b/engines/kyra/sequence/sequences_darkmoon.cpp
index b92eb74fde..7a581e55ba 100644
--- a/engines/kyra/sequence/sequences_darkmoon.cpp
+++ b/engines/kyra/sequence/sequences_darkmoon.cpp
@@ -160,6 +160,7 @@ int DarkMoonEngine::mainMenu() {
_screen->_curPage = op;
_screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 0, Screen::CR_NO_P_CHECK);
_screen->shadeRect(78, 99, 249, 141, 4);
+ _screen->showMouse();
_screen->updateScreen();
_allowImport = true;
menuChoice = mainMenuLoop();
@@ -1201,6 +1202,7 @@ DarkmoonSequenceHelper::DarkmoonSequenceHelper(OSystem *system, DarkMoonEngine *
}
_screen->enableHiColorMode(false);
+ _screen->disableDualPalettesSplitScreen();
int numColors = 256;
if (_vm->_flags.platform == Common::kPlatformAmiga) {
@@ -1296,7 +1298,6 @@ DarkmoonSequenceHelper::~DarkmoonSequenceHelper() {
_screen->enableHiColorMode(true);
_screen->clearCurPage();
_screen->setFont(_prevFont);
- _screen->showMouse();
_screen->updateScreen();
_system->delayMillis(150);