aboutsummaryrefslogtreecommitdiff
path: root/engines/kyra
diff options
context:
space:
mode:
Diffstat (limited to 'engines/kyra')
-rw-r--r--engines/kyra/animator_mr.cpp2
-rw-r--r--engines/kyra/debugger.cpp16
-rw-r--r--engines/kyra/gui.cpp112
-rw-r--r--engines/kyra/gui.h9
-rw-r--r--engines/kyra/gui_hof.cpp48
-rw-r--r--engines/kyra/gui_lok.cpp41
-rw-r--r--engines/kyra/gui_lok.h2
-rw-r--r--engines/kyra/gui_lol.cpp675
-rw-r--r--engines/kyra/gui_lol.h116
-rw-r--r--engines/kyra/gui_mr.cpp44
-rw-r--r--engines/kyra/gui_v2.cpp34
-rw-r--r--engines/kyra/gui_v2.h2
-rw-r--r--engines/kyra/items_hof.cpp8
-rw-r--r--engines/kyra/items_lol.cpp2
-rw-r--r--engines/kyra/kyra_hof.cpp33
-rw-r--r--engines/kyra/kyra_lok.cpp10
-rw-r--r--engines/kyra/kyra_lok.h1
-rw-r--r--engines/kyra/kyra_mr.cpp79
-rw-r--r--engines/kyra/kyra_mr.h1
-rw-r--r--engines/kyra/kyra_v1.cpp24
-rw-r--r--engines/kyra/kyra_v1.h8
-rw-r--r--engines/kyra/lol.cpp440
-rw-r--r--engines/kyra/lol.h27
-rw-r--r--engines/kyra/saveload.cpp3
-rw-r--r--engines/kyra/scene_hof.cpp18
-rw-r--r--engines/kyra/scene_lok.cpp12
-rw-r--r--engines/kyra/scene_lol.cpp57
-rw-r--r--engines/kyra/scene_mr.cpp22
-rw-r--r--engines/kyra/screen.cpp689
-rw-r--r--engines/kyra/screen.h151
-rw-r--r--engines/kyra/screen_hof.cpp6
-rw-r--r--engines/kyra/screen_hof.h2
-rw-r--r--engines/kyra/screen_lok.cpp213
-rw-r--r--engines/kyra/screen_lok.h32
-rw-r--r--engines/kyra/screen_lol.cpp99
-rw-r--r--engines/kyra/screen_lol.h13
-rw-r--r--engines/kyra/screen_v2.cpp176
-rw-r--r--engines/kyra/screen_v2.h9
-rw-r--r--engines/kyra/script.cpp86
-rw-r--r--engines/kyra/script.h11
-rw-r--r--engines/kyra/script_hof.cpp46
-rw-r--r--engines/kyra/script_lok.cpp63
-rw-r--r--engines/kyra/script_lol.cpp110
-rw-r--r--engines/kyra/script_mr.cpp7
-rw-r--r--engines/kyra/script_tim.cpp144
-rw-r--r--engines/kyra/script_tim.h7
-rw-r--r--engines/kyra/seqplayer.cpp40
-rw-r--r--engines/kyra/sequences_hof.cpp153
-rw-r--r--engines/kyra/sequences_lok.cpp111
-rw-r--r--engines/kyra/sequences_lol.cpp116
-rw-r--r--engines/kyra/sound_lol.cpp11
-rw-r--r--engines/kyra/sound_midi.cpp4
-rw-r--r--engines/kyra/sound_towns.cpp8
-rw-r--r--engines/kyra/sprites.cpp12
-rw-r--r--engines/kyra/sprites_lol.cpp4
-rw-r--r--engines/kyra/staticres.cpp144
-rw-r--r--engines/kyra/text_lok.cpp22
-rw-r--r--engines/kyra/text_lol.cpp18
-rw-r--r--engines/kyra/text_lol.h9
-rw-r--r--engines/kyra/text_mr.cpp2
-rw-r--r--engines/kyra/util.cpp63
-rw-r--r--engines/kyra/util.h10
-rw-r--r--engines/kyra/vqa.cpp25
-rw-r--r--engines/kyra/vqa.h14
-rw-r--r--engines/kyra/wsamovie.cpp136
-rw-r--r--engines/kyra/wsamovie.h28
66 files changed, 3131 insertions, 1509 deletions
diff --git a/engines/kyra/animator_mr.cpp b/engines/kyra/animator_mr.cpp
index d7139a9e70..faf1b150a2 100644
--- a/engines/kyra/animator_mr.cpp
+++ b/engines/kyra/animator_mr.cpp
@@ -119,7 +119,7 @@ void KyraEngine_MR::drawSceneAnimObject(AnimObj *obj, int x, int y, int layer) {
flags |= 0x8000;
x = obj->xPos2 - _sceneAnimMovie[obj->animNum]->xAdd();
y = obj->yPos2 - _sceneAnimMovie[obj->animNum]->yAdd();
- _sceneAnimMovie[obj->animNum]->displayFrame(obj->shapeIndex3, 2, x, y, flags | layer);
+ _sceneAnimMovie[obj->animNum]->displayFrame(obj->shapeIndex3, 2, x, y, flags | layer, 0, 0);
}
}
}
diff --git a/engines/kyra/debugger.cpp b/engines/kyra/debugger.cpp
index e0c2c0aa77..d71f7b8b25 100644
--- a/engines/kyra/debugger.cpp
+++ b/engines/kyra/debugger.cpp
@@ -69,7 +69,7 @@ bool Debugger::cmd_setScreenDebug(int argc, const char **argv) {
}
bool Debugger::cmd_loadPalette(int argc, const char **argv) {
- uint8 palette[768];
+ Palette palette(_vm->screen()->getPalette(0).getNumColors());
if (argc <= 1) {
DebugPrintf("Use load_palette <file> [start_col] [end_col]\n");
@@ -80,7 +80,7 @@ bool Debugger::cmd_loadPalette(int argc, const char **argv) {
uint8 buffer[320*200];
_vm->screen()->copyRegionToBuffer(5, 0, 0, 320, 200, buffer);
_vm->screen()->loadBitmap(argv[1], 5, 5, 0);
- memcpy(palette, _vm->screen()->getCPagePtr(5), 768);
+ palette.copy(_vm->screen()->getCPagePtr(5), 0, 256);
_vm->screen()->copyBlockToPage(5, 0, 0, 320, 200, buffer);
} else if (!_vm->screen()->loadPalette(argv[1], palette)) {
DebugPrintf("ERROR: Palette '%s' not found!\n", argv[1]);
@@ -88,16 +88,16 @@ bool Debugger::cmd_loadPalette(int argc, const char **argv) {
}
int startCol = 0;
- int endCol = 255;
+ int endCol = palette.getNumColors();
if (argc > 2)
- startCol = MIN(255, MAX(0, atoi(argv[2])));
+ startCol = MIN(palette.getNumColors(), MAX(0, atoi(argv[2])));
if (argc > 3)
- endCol = MIN(255, MAX(0, atoi(argv[3])));
+ endCol = MIN(palette.getNumColors(), MAX(0, atoi(argv[3])));
if (startCol > 0)
- memcpy(palette, _vm->screen()->getScreenPalette(), startCol*3);
- if (endCol < 255)
- memcpy(palette + endCol * 3, _vm->screen()->getScreenPalette() + endCol * 3, (255-endCol)*3);
+ palette.copy(_vm->screen()->getPalette(0), 0, startCol);
+ if (endCol < palette.getNumColors())
+ palette.copy(_vm->screen()->getPalette(0), endCol);
_vm->screen()->setScreenPalette(palette);
_vm->screen()->updateScreen();
diff --git a/engines/kyra/gui.cpp b/engines/kyra/gui.cpp
index faea2c9a72..85d974f675 100644
--- a/engines/kyra/gui.cpp
+++ b/engines/kyra/gui.cpp
@@ -83,17 +83,21 @@ void GUI::initMenu(Menu &menu) {
int menu_y2 = menu.height + menu.y - 1;
_screen->fillRect(menu.x + 2, menu.y + 2, menu_x2 - 2, menu_y2 - 2, menu.bkgdColor);
- _screen->drawShadedBox(menu.x, menu.y, menu_x2, menu_y2, menu.color1, menu.color2);
+ _screen->drawShadedBox(menu.x, menu.y, menu_x2, menu_y2, menu.color1, menu.color2, _vm->gameFlags().gameID == GI_LOL ? Screen::kShadeTypeLol : Screen::kShadeTypeKyra);
if (menu.titleX != -1)
textX = menu.titleX;
else
- textX = _text->getCenterStringX(getMenuTitle(menu), menu.x, menu_x2);
+ textX = getMenuCenterStringX(getMenuTitle(menu), menu.x, menu_x2);
textY = menu.y + menu.titleY;
- _text->printText(getMenuTitle(menu), textX - 1, textY + 1, defaultColor1(), defaultColor2(), 0);
- _text->printText(getMenuTitle(menu), textX, textY, menu.textColor, 0, 0);
+ if (_vm->gameFlags().gameID == GI_LOL) {
+ printMenuText(getMenuTitle(menu), textX, textY, menu.textColor, 0, 9);
+ } else {
+ printMenuText(getMenuTitle(menu), textX - 1, textY + 1, defaultColor1(), defaultColor2(), 0);
+ printMenuText(getMenuTitle(menu), textX, textY, menu.textColor, 0, 0);
+ }
int x1, y1, x2, y2;
for (int i = 0; i < menu.numberOfItems; ++i) {
@@ -114,35 +118,49 @@ void GUI::initMenu(Menu &menu) {
menuButtonData->width = menu.item[i].width - 1;
menuButtonData->height = menu.item[i].height - 1;
menuButtonData->buttonCallback = menu.item[i].callback;
- menuButtonData->keyCode = menu.item[i].unk1F;
+ menuButtonData->keyCode = menu.item[i].keyCode;
menuButtonData->keyCode2 = 0;
+ menuButtonData->arg = menu.item[i].itemId;
_menuButtonList = addButtonToList(_menuButtonList, menuButtonData);
}
_screen->fillRect(x1, y1, x2, y2, menu.item[i].bkgdColor);
- _screen->drawShadedBox(x1, y1, x2, y2, menu.item[i].color1, menu.item[i].color2);
+ _screen->drawShadedBox(x1, y1, x2, y2, menu.item[i].color1, menu.item[i].color2, _vm->gameFlags().gameID == GI_LOL ? Screen::kShadeTypeLol : Screen::kShadeTypeKyra);
if (getMenuItemTitle(menu.item[i])) {
if (menu.item[i].titleX != -1)
textX = x1 + menu.item[i].titleX + 3;
else
- textX = _text->getCenterStringX(getMenuItemTitle(menu.item[i]), x1, x2);
+ textX = getMenuCenterStringX(getMenuItemTitle(menu.item[i]), x1, x2);
textY = y1 + 2;
- _text->printText(getMenuItemTitle(menu.item[i]), textX - 1, textY + 1, defaultColor1(), 0, 0);
-
- if (i == menu.highlightedItem)
- _text->printText(getMenuItemTitle(menu.item[i]), textX, textY, menu.item[i].highlightColor, 0, 0);
- else
- _text->printText(getMenuItemTitle(menu.item[i]), textX, textY, menu.item[i].textColor, 0, 0);
+ if (_vm->gameFlags().gameID == GI_LOL) {
+ textY++;
+ if (i == menu.highlightedItem)
+ printMenuText(getMenuItemTitle(menu.item[i]), textX, textY, menu.item[i].highlightColor, 0, 8);
+ else
+ printMenuText(getMenuItemTitle(menu.item[i]), textX, textY, menu.item[i].textColor, 0, 8);
+ } else {
+ printMenuText(getMenuItemTitle(menu.item[i]), textX - 1, textY + 1, defaultColor1(), 0, 0);
+ if (i == menu.highlightedItem)
+ printMenuText(getMenuItemTitle(menu.item[i]), textX, textY, menu.item[i].highlightColor, 0, 0);
+ else
+ printMenuText(getMenuItemTitle(menu.item[i]), textX, textY, menu.item[i].textColor, 0, 0);
+ }
}
}
for (int i = 0; i < menu.numberOfItems; ++i) {
if (getMenuItemLabel(menu.item[i])) {
- _text->printText(getMenuItemLabel(menu.item[i]), menu.x + menu.item[i].labelX - 1, menu.y + menu.item[i].labelY + 1, defaultColor1(), 0, 0);
- _text->printText(getMenuItemLabel(menu.item[i]), menu.x + menu.item[i].labelX, menu.y + menu.item[i].labelY, menu.item[i].textColor, 0, 0);
+ if (_vm->gameFlags().gameID == GI_LOL) {
+ menu.item[i].labelX = menu.item[i].x - 1;
+ menu.item[i].labelY = menu.item[i].y + 3;
+ printMenuText(getMenuItemLabel(menu.item[i]), menu.x + menu.item[i].labelX, menu.y + menu.item[i].labelY, menu.item[i].textColor, 0, 10);
+ } else {
+ printMenuText(getMenuItemLabel(menu.item[i]), menu.x + menu.item[i].labelX - 1, menu.y + menu.item[i].labelY + 1, defaultColor1(), 0, 0);
+ printMenuText(getMenuItemLabel(menu.item[i]), menu.x + menu.item[i].labelX, menu.y + menu.item[i].labelY, menu.item[i].textColor, 0, 0);
+ }
}
}
@@ -172,8 +190,22 @@ void GUI::initMenu(Menu &menu) {
_screen->updateScreen();
}
-void GUI::processHighlights(Menu &menu, int mouseX, int mouseY) {
+void GUI::processHighlights(Menu &menu) {
int x1, y1, x2, y2;
+ Common::Point p = _vm->getMousePos();
+ int mouseX = p.x;
+ int mouseY = p.y;
+
+ if (_vm->_flags.gameID == GI_LOL && menu.highlightedItem != 255) {
+ // LoL doesnt't have default highlighted items.
+ // We use a highlightedItem value of 255 for this.
+
+ // With LoL no highlighting should take place unless the
+ // mouse cursor moves over a button. The highlighting should end
+ // when the mouse cursor leaves the button.
+ if (menu.item[menu.highlightedItem].enabled)
+ redrawText(menu);
+ }
for (int i = 0; i < menu.numberOfItems; ++i) {
if (!menu.item[i].enabled)
@@ -188,9 +220,11 @@ void GUI::processHighlights(Menu &menu, int mouseX, int mouseY) {
if (mouseX > x1 && mouseX < x2 &&
mouseY > y1 && mouseY < y2) {
- if (menu.highlightedItem != i) {
- if (menu.item[menu.highlightedItem].enabled)
- redrawText(menu);
+ if (menu.highlightedItem != i || _vm->_flags.gameID == GI_LOL) {
+ if (_vm->_flags.gameID != GI_LOL) {
+ if (menu.item[menu.highlightedItem].enabled)
+ redrawText(menu);
+ }
menu.highlightedItem = i;
redrawHighlight(menu);
@@ -212,11 +246,16 @@ void GUI::redrawText(const Menu &menu) {
if (menu.item[i].titleX >= 0)
textX = x1 + menu.item[i].titleX + 3;
else
- textX = _text->getCenterStringX(getMenuItemTitle(menu.item[i]), x1, x2);
+ textX = getMenuCenterStringX(getMenuItemTitle(menu.item[i]), x1, x2);
int textY = y1 + 2;
- _text->printText(getMenuItemTitle(menu.item[i]), textX - 1, textY + 1, defaultColor1(), 0, 0);
- _text->printText(getMenuItemTitle(menu.item[i]), textX, textY, menu.item[i].textColor, 0, 0);
+ if (_vm->gameFlags().gameID == GI_LOL) {
+ textY++;
+ printMenuText(getMenuItemTitle(menu.item[i]), textX, textY, menu.item[i].textColor, 0, 8);
+ } else {
+ printMenuText(getMenuItemTitle(menu.item[i]), textX - 1, textY + 1, defaultColor1(), 0, 0);
+ printMenuText(getMenuItemTitle(menu.item[i]), textX, textY, menu.item[i].textColor, 0, 0);
+ }
}
void GUI::redrawHighlight(const Menu &menu) {
@@ -231,11 +270,17 @@ void GUI::redrawHighlight(const Menu &menu) {
if (menu.item[i].titleX != -1)
textX = x1 + menu.item[i].titleX + 3;
else
- textX = _text->getCenterStringX(getMenuItemTitle(menu.item[i]), x1, x2);
+ textX = getMenuCenterStringX(getMenuItemTitle(menu.item[i]), x1, x2);
int textY = y1 + 2;
- _text->printText(getMenuItemTitle(menu.item[i]), textX - 1, textY + 1, defaultColor1(), 0, 0);
- _text->printText(getMenuItemTitle(menu.item[i]), textX, textY, menu.item[i].highlightColor, 0, 0);
+
+ if (_vm->gameFlags().gameID == GI_LOL) {
+ textY++;
+ printMenuText(getMenuItemTitle(menu.item[i]), textX, textY, menu.item[i].highlightColor, 0, 8);
+ } else {
+ printMenuText(getMenuItemTitle(menu.item[i]), textX - 1, textY + 1, defaultColor1(), 0, 0);
+ printMenuText(getMenuItemTitle(menu.item[i]), textX, textY, menu.item[i].highlightColor, 0, 0);
+ }
}
void GUI::updateAllMenuButtons() {
@@ -296,7 +341,7 @@ int GUI::redrawShadedButtonCallback(Button *button) {
return 0;
}
-void GUI::updateSaveList() {
+void GUI::updateSaveList(bool excludeQuickSaves) {
Common::String pattern = _vm->_targetName + ".???";
Common::StringList saveFileList = _vm->_saveFileMan->listSavefiles(pattern);
_saveSlots.clear();
@@ -311,6 +356,8 @@ void GUI::updateSaveList() {
s1 -= '0';
s2 -= '0';
s3 -= '0';
+ if (excludeQuickSaves && s1 == 9 && s2 == 9)
+ continue;
_saveSlots.push_back(s1*100+s2*10+s3);
}
@@ -383,6 +430,14 @@ void GUI::checkTextfieldInput() {
_vm->_system->delayMillis(3);
}
+void GUI::printMenuText(const char *str, int x, int y, uint8 c0, uint8 c1, uint8 c2, Screen::FontId font) {
+ _text->printText(str, x, y, c0, c1, c2, font);
+}
+
+int GUI::getMenuCenterStringX(const char *str, int x1, int x2) {
+ return _text->getCenterStringX(str, x1, x2);
+}
+
#pragma mark -
MainMenu::MainMenu(KyraEngine_v1 *vm) : _vm(vm), _screen(0) {
@@ -404,7 +459,7 @@ void MainMenu::updateAnimation() {
if (now > _nextUpdate) {
_nextUpdate = now + _anim.delay * _vm->tickLength();
- _anim.anim->displayFrame(_animIntern.curFrame, 0, 0, 0);
+ _anim.anim->displayFrame(_animIntern.curFrame, 0, 0, 0, 0, 0, 0);
_animIntern.curFrame += _animIntern.direction ;
if (_animIntern.curFrame < _anim.startFrame) {
_animIntern.curFrame = _anim.startFrame;
@@ -421,8 +476,9 @@ void MainMenu::updateAnimation() {
bool MainMenu::getInput() {
Common::Event event;
+ Common::EventManager *eventMan = _vm->getEventManager();
- while (_system->getEventManager()->pollEvent(event)) {
+ while (eventMan->pollEvent(event)) {
switch (event.type) {
case Common::EVENT_LBUTTONUP:
return true;
diff --git a/engines/kyra/gui.h b/engines/kyra/gui.h
index f83620c8f9..3989062506 100644
--- a/engines/kyra/gui.h
+++ b/engines/kyra/gui.h
@@ -114,7 +114,7 @@ struct MenuItem {
uint16 labelId;
int16 labelX, labelY;
- uint16 unk1F;
+ uint16 keyCode;
};
struct Menu {
@@ -161,7 +161,7 @@ public:
virtual void initMenuLayout(Menu &menu);
void initMenu(Menu &menu);
- void processHighlights(Menu &menu, int mouseX, int mouseY);
+ void processHighlights(Menu &menu);
// utilities for thumbnail creation
virtual void createScreenThumbnail(Graphics::Surface &dst) = 0;
@@ -176,6 +176,9 @@ protected:
bool _displaySubMenu;
bool _cancelSubMenu;
+ virtual void printMenuText(const char *str, int x, int y, uint8 c0, uint8 c1, uint8 c2, Screen::FontId font=Screen::FID_8_FNT);
+ virtual int getMenuCenterStringX(const char *str, int x1, int x2);
+
Button::Callback _redrawShadedButtonFunctor;
Button::Callback _redrawButtonFunctor;
@@ -201,7 +204,7 @@ protected:
void redrawHighlight(const Menu &menu);
Common::Array<int> _saveSlots;
- void updateSaveList();
+ void updateSaveList(bool excludeQuickSaves = false);
int getNextSavegameSlot();
uint32 _lastScreenUpdate;
diff --git a/engines/kyra/gui_hof.cpp b/engines/kyra/gui_hof.cpp
index a37ac7b306..69e7419757 100644
--- a/engines/kyra/gui_hof.cpp
+++ b/engines/kyra/gui_hof.cpp
@@ -95,7 +95,11 @@ const char *GUI_HoF::getMenuItemTitle(const MenuItem &menuItem) {
if (!menuItem.itemId)
return 0;
- return _vm->getTableString(menuItem.itemId, _vm->_optionsBuffer, 1);
+ // Strings 41-45 are menu labels, those must be handled uncompressed!
+ if (menuItem.itemId >= 41 && menuItem.itemId <= 45)
+ return _vm->getTableString(menuItem.itemId, _vm->_optionsBuffer, 0);
+ else
+ return _vm->getTableString(menuItem.itemId, _vm->_optionsBuffer, 1);
}
const char *GUI_HoF::getMenuItemLabel(const MenuItem &menuItem) {
@@ -272,7 +276,7 @@ void KyraEngine_HoF::redrawInventory(int page) {
}
void KyraEngine_HoF::scrollInventoryWheel() {
- WSAMovie_v2 movie(this, _screen);
+ WSAMovie_v2 movie(this);
movie.open("INVWHEEL.WSA", 0, 0);
int frames = movie.opened() ? movie.frames() : 6;
memcpy(_screenBuffer, _screen->getCPagePtr(2), 64000);
@@ -287,7 +291,7 @@ void KyraEngine_HoF::scrollInventoryWheel() {
for (int i = 0; i <= 6 && !breakFlag; ++i) {
if (movie.opened()) {
_screen->hideMouse();
- movie.displayFrame(i % frames, 0, 0, 0, 0);
+ movie.displayFrame(i % frames, 0, 0, 0, 0, 0, 0);
_screen->showMouse();
_screen->updateScreen();
}
@@ -361,9 +365,9 @@ int KyraEngine_HoF::bookButton(Button *button) {
_screen->showMouse();
}
- memcpy(_screen->getPalette(2), _screen->getPalette(0), 768);
+ _screen->copyPalette(2, 0);
_screen->fadeToBlack(7, &_updateFunctor);
- _res->loadFileToBuf("_BOOK.COL", _screen->getPalette(0), 768);
+ _screen->loadPalette("_BOOK.COL", _screen->getPalette(0));
loadBookBkgd();
showBookPage();
_screen->copyRegion(0, 0, 0, 0, 0x140, 0xC8, 2, 0, Screen::CR_NO_P_CHECK);
@@ -389,7 +393,7 @@ int KyraEngine_HoF::bookButton(Button *button) {
}
setHandItem(_itemInHand);
- memcpy(_screen->getPalette(0), _screen->getPalette(2), 768);
+ _screen->copyPalette(0, 2);
_screen->fadePalette(_screen->getPalette(0), 7, &_updateFunctor);
_screen->showMouse();
@@ -700,7 +704,6 @@ int GUI_HoF::optionsButton(Button *button) {
int oldHandItem = _vm->_itemInHand;
_screen->setMouseCursor(0, 0, _vm->getShapePtr(0));
_vm->displayInvWsaLastFrame();
- //XXX
_displayMenu = true;
for (uint i = 0; i < ARRAYSIZE(_menuButtons); ++i) {
@@ -763,7 +766,7 @@ int GUI_HoF::optionsButton(Button *button) {
}
while (_displayMenu) {
- processHighlights(*_currentMenu, _vm->_mouseX, _vm->_mouseY);
+ processHighlights(*_currentMenu);
getInput();
}
@@ -796,16 +799,11 @@ void GUI_HoF::createScreenThumbnail(Graphics::Surface &dst) {
}
void GUI_HoF::setupPalette() {
- memcpy(_screen->getPalette(1), _screen->getPalette(0), 768);
-
- uint8 *palette = _screen->getPalette(0);
- for (int i = 0; i < 768; ++i)
- palette[i] >>= 1;
-
- static const uint8 guiPal[] = { 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFc, 0xFD, 0xFE };
+ _screen->copyPalette(1, 0);
- for (uint i = 0; i < ARRAYSIZE(guiPal); ++i)
- memcpy(_screen->getPalette(0)+guiPal[i]*3, _screen->getPalette(1)+guiPal[i]*3, 3);
+ Palette &pal = _screen->getPalette(0);
+ for (int i = 0; i < 741; ++i)
+ pal[i] >>= 1;
if (_isDeathMenu)
_screen->fadePalette(_screen->getPalette(0), 0x64);
@@ -814,7 +812,7 @@ void GUI_HoF::setupPalette() {
}
void GUI_HoF::restorePalette() {
- memcpy(_screen->getPalette(0), _screen->getPalette(1), 768);
+ _screen->copyPalette(0, 1);
_screen->setScreenPalette(_screen->getPalette(0));
}
@@ -851,8 +849,7 @@ void GUI_HoF::drawSliderBar(int slider, const uint8 *shape) {
position = _vm->_configTextspeed;
}
- position = MAX(2, position);
- position = MIN(97, position);
+ position = CLIP(position, 2, 97);
_screen->drawShape(0, shape, x+position, y, 0, 0);
}
@@ -908,7 +905,7 @@ int GUI_HoF::audioOptions(Button *caller) {
updateAllMenuButtons();
bool speechEnabled = _vm->speechEnabled();
while (_isOptionsMenu) {
- processHighlights(_audioOptions, _vm->_mouseX, _vm->_mouseY);
+ processHighlights(_audioOptions);
getInput();
}
@@ -956,7 +953,7 @@ int GUI_HoF::gameOptions(Button *caller) {
}
while (_isOptionsMenu) {
- processHighlights(_gameOptions, _vm->_mouseX, _vm->_mouseY);
+ processHighlights(_gameOptions);
getInput();
}
@@ -983,7 +980,7 @@ int GUI_HoF::gameOptionsTalkie(Button *caller) {
_isOptionsMenu = true;
while (_isOptionsMenu) {
- processHighlights(_gameOptions, _vm->_mouseX, _vm->_mouseY);
+ processHighlights(_gameOptions);
getInput();
}
@@ -1094,8 +1091,7 @@ int GUI_HoF::sliderHandler(Button *caller) {
else
newVolume = _vm->_mouseX - caller->x - 7;
- newVolume = MAX(2, newVolume);
- newVolume = MIN(97, newVolume);
+ newVolume = CLIP(newVolume, 2, 97);
if (newVolume == oldVolume)
return 0;
@@ -1175,7 +1171,7 @@ int GUI_HoF::loadMenu(Button *caller) {
_screen->updateScreen();
while (_isLoadMenu) {
- processHighlights(_loadMenu, _vm->_mouseX, _vm->_mouseY);
+ processHighlights(_loadMenu);
getInput();
}
diff --git a/engines/kyra/gui_lok.cpp b/engines/kyra/gui_lok.cpp
index 560bc6c2f2..9f42697ec7 100644
--- a/engines/kyra/gui_lok.cpp
+++ b/engines/kyra/gui_lok.cpp
@@ -31,6 +31,7 @@
#include "kyra/sound.h"
#include "kyra/gui_lok.h"
#include "kyra/timer.h"
+#include "kyra/util.h"
#include "common/config-manager.h"
#include "common/savefile.h"
@@ -86,7 +87,6 @@ int KyraEngine_LoK::buttonInventoryCallback(Button *caller) {
}
}
_screen->updateScreen();
- // XXX clearKyrandiaButtonIO
return 0;
}
@@ -182,7 +182,6 @@ int KyraEngine_LoK::buttonAmuletCallback(Button *caller) {
break;
}
_unkAmuletVar = 0;
- // XXX clearKyrandiaButtonIO (!used before every return in this function!)
return 1;
}
@@ -479,7 +478,7 @@ int GUI_LoK::buttonMenuCallback(Button *caller) {
}
while (_displayMenu && !_vm->shouldQuit()) {
- processHighlights(_menu[_toplevelMenu], _vm->_mouseX, _vm->_mouseY);
+ processHighlights(_menu[_toplevelMenu]);
getInput();
}
@@ -538,6 +537,9 @@ void GUI_LoK::setupSavegames(Menu &menu, int num) {
if ((in = _vm->openSaveForReading(_vm->getSavegameFilename(_saveSlots[i + _savegameOffset]), header))) {
strncpy(savenames[i], header.description.c_str(), ARRAYSIZE(savenames[0]));
savenames[i][34] = 0;
+
+ Util::convertISOToDOS(savenames[i]);
+
menu.item[i].itemString = savenames[i];
menu.item[i].enabled = 1;
menu.item[i].saveSlot = _saveSlots[i + _savegameOffset];
@@ -570,7 +572,7 @@ int GUI_LoK::saveGameMenu(Button *button) {
_cancelSubMenu = false;
while (_displaySubMenu && !_vm->shouldQuit()) {
- processHighlights(_menu[2], _vm->_mouseX, _vm->_mouseY);
+ processHighlights(_menu[2]);
getInput();
}
@@ -616,7 +618,7 @@ int GUI_LoK::loadGameMenu(Button *button) {
_vm->_gameToLoad = -1;
while (_displaySubMenu && !_vm->shouldQuit()) {
- processHighlights(_menu[2], _vm->_mouseX, _vm->_mouseY);
+ processHighlights(_menu[2]);
getInput();
}
@@ -654,9 +656,12 @@ void GUI_LoK::updateSavegameString() {
if (_keyPressed.keycode) {
length = strlen(_savegameName);
- if (_keyPressed.ascii > 31 && _keyPressed.ascii < 127) {
+ char inputKey = _keyPressed.ascii;
+ Util::convertISOToDOS(inputKey);
+
+ if ((uint8)inputKey > 31 && (uint8)inputKey < 226) {
if (length < ARRAYSIZE(_savegameName)-1) {
- _savegameName[length] = _keyPressed.ascii;
+ _savegameName[length] = inputKey;
_savegameName[length+1] = 0;
redrawTextfield();
}
@@ -703,7 +708,7 @@ int GUI_LoK::saveGame(Button *button) {
while (_displaySubMenu && !_vm->shouldQuit()) {
checkTextfieldInput();
updateSavegameString();
- processHighlights(_menu[3], _vm->_mouseX, _vm->_mouseY);
+ processHighlights(_menu[3]);
}
if (_cancelSubMenu) {
@@ -715,6 +720,8 @@ int GUI_LoK::saveGame(Button *button) {
if (_savegameOffset == 0 && _vm->_gameToLoad == 0)
_vm->_gameToLoad = getNextSavegameSlot();
if (_vm->_gameToLoad > 0) {
+ Util::convertDOSToISO(_savegameName);
+
Graphics::Surface thumb;
createScreenThumbnail(thumb);
_vm->saveGameState(_vm->_gameToLoad, _savegameName, &thumb);
@@ -773,7 +780,7 @@ bool GUI_LoK::quitConfirm(const char *str) {
_cancelSubMenu = true;
while (_displaySubMenu && !_vm->shouldQuit()) {
- processHighlights(_menu[1], _vm->_mouseX, _vm->_mouseY);
+ processHighlights(_menu[1]);
getInput();
}
@@ -833,7 +840,7 @@ int GUI_LoK::gameControlsMenu(Button *button) {
_cancelSubMenu = false;
while (_displaySubMenu && !_vm->shouldQuit()) {
- processHighlights(_menu[5], _vm->_mouseX, _vm->_mouseY);
+ processHighlights(_menu[5]);
getInput();
}
@@ -1015,25 +1022,25 @@ void GUI_LoK::fadePalette() {
static const int16 menuPalIndexes[] = {248, 249, 250, 251, 252, 253, 254, -1};
int index = 0;
- memcpy(_screen->getPalette(2), _screen->_currentPalette, 768);
+ _screen->copyPalette(2, 0);
for (int i = 0; i < 768; i++)
- _screen->_currentPalette[i] >>= 1;
+ _screen->getPalette(0)[i] >>= 1;
while (menuPalIndexes[index] != -1) {
- memcpy(&_screen->_currentPalette[menuPalIndexes[index]*3], &_screen->getPalette(2)[menuPalIndexes[index]*3], 3);
- index++;
+ _screen->getPalette(0).copy(_screen->getPalette(2), menuPalIndexes[index], 1);
+ ++index;
}
- _screen->fadePalette(_screen->_currentPalette, 2);
+ _screen->fadePalette(_screen->getPalette(0), 2);
}
void GUI_LoK::restorePalette() {
if (_vm->gameFlags().platform == Common::kPlatformAmiga)
return;
- memcpy(_screen->_currentPalette, _screen->getPalette(2), 768);
- _screen->fadePalette(_screen->_currentPalette, 2);
+ _screen->copyPalette(0, 2);
+ _screen->fadePalette(_screen->getPalette(0), 2);
}
#pragma mark -
diff --git a/engines/kyra/gui_lok.h b/engines/kyra/gui_lok.h
index eec57f5546..5982ef1ce2 100644
--- a/engines/kyra/gui_lok.h
+++ b/engines/kyra/gui_lok.h
@@ -89,7 +89,7 @@ namespace Kyra {
item.labelString = r; \
item.labelX = s; \
item.labelY = t; \
- item.unk1F = v; \
+ item.keyCode = v; \
} while (0)
class KyraEngine_LoK;
diff --git a/engines/kyra/gui_lol.cpp b/engines/kyra/gui_lol.cpp
index af8bc6aa97..5e03f3d9bb 100644
--- a/engines/kyra/gui_lol.cpp
+++ b/engines/kyra/gui_lol.cpp
@@ -28,6 +28,14 @@
#include "kyra/lol.h"
#include "kyra/screen_lol.h"
#include "kyra/gui_lol.h"
+#include "kyra/resource.h"
+#include "kyra/util.h"
+
+#include "common/savefile.h"
+#include "common/config-manager.h"
+#include "graphics/scaler.h"
+
+#include "base/version.h"
namespace Kyra {
@@ -577,7 +585,7 @@ void LoLEngine::gui_drawCompass() {
}
int LoLEngine::gui_enableControls() {
- _floatingMouseArrowControl = 0;
+ _floatingCursorControl = 0;
if (!_currentControlMode) {
for (int i = 76; i < 85; i++)
@@ -592,7 +600,7 @@ int LoLEngine::gui_disableControls(int controlMode) {
if (_currentControlMode)
return 0;
- _floatingMouseArrowControl = (controlMode & 2) ? 2 : 1;
+ _floatingCursorControl = (controlMode & 2) ? 2 : 1;
gui_toggleFightButtons(true);
@@ -1364,7 +1372,7 @@ int LoLEngine::clickedInventorySlot(Button *button) {
(_itemsInPlay[hItem].itemPropertyIndex == 220 || _itemsInPlay[slotItem].itemPropertyIndex == 220)) {
// merge ruby of truth
- WSAMovie_v2 *wsa = new WSAMovie_v2(this, _screen);
+ WSAMovie_v2 *wsa = new WSAMovie_v2(this);
wsa->open("truth.wsa", 0, 0);
_screen->hideMouse();
@@ -1377,7 +1385,7 @@ int LoLEngine::clickedInventorySlot(Button *button) {
for (int i = 0; i < 25; i++) {
uint32 delayTimer = _system->getMillis() + 7 * _tickLength;
_screen->copyRegion(button->x, button->y - 3, 0, 0, 25, 27, 2, 2);
- wsa->displayFrame(i, 2, 0, 0, 0x4000);
+ wsa->displayFrame(i, 2, 0, 0, 0x4000, 0, 0);
_screen->copyRegion(0, 0, button->x, button->y - 3, 25, 27, 2, 0);
_screen->updateScreen();
delayUntil(delayTimer);
@@ -1536,10 +1544,43 @@ int LoLEngine::clickedSceneThrowItem(Button *button) {
}
int LoLEngine::clickedOptions(Button *button) {
+ removeInputTop();
gui_toggleButtonDisplayMode(76, 1);
+ _updateFlags |= 4;
+
+ Button b;
+ b.data0Val2 = b.data1Val2 = b.data2Val2 = 0xfe;
+ b.data0Val3 = b.data1Val3 = b.data2Val3 = 0x01;
+
+ if (_weaponsDisabled)
+ clickedExitCharInventory(&b);
+
+ initTextFading(0, 1);
+ updatePortraits();
+ setLampMode(true);
+ setMouseCursorToIcon(0);
+ disableSysTimer(2);
+
gui_toggleButtonDisplayMode(76, 0);
+ bool speechWasEnabled = speechEnabled();
+ _gui->runMenu(_gui->_mainMenu);
+
+ _updateFlags &= 0xfffb;
+ setMouseCursorToItemInHand();
+ resetLampStatus();
+ gui_enableDefaultPlayfieldButtons();
+ enableSysTimer(2);
+ updateDrawPage2();
+
+ gui_drawPlayField();
+
+ if (speechWasEnabled && !textEnabled() && (!speechEnabled() || getVolume(kVolumeSpeech) == 2))
+ _configVoice = 0;
+
+ writeSettings();
+
return 1;
}
@@ -1773,7 +1814,7 @@ int LoLEngine::clickedAutomap(Button *button) {
displayAutomap();
gui_drawPlayField();
- setPaletteBrightness(_screen->_currentPalette, _brightness, _lampEffect);
+ setPaletteBrightness(_screen->getPalette(0), _brightness, _lampEffect);
return 1;
}
@@ -1801,7 +1842,7 @@ int LoLEngine::clickedLamp(Button *button) {
}
if (_brightness)
- setPaletteBrightness(_screen->_currentPalette, _brightness, _lampEffect);
+ setPaletteBrightness(_screen->getPalette(0), _brightness, _lampEffect);
return 1;
}
@@ -1826,9 +1867,13 @@ int LoLEngine::clickedStatusIcon(Button *button) {
GUI_LoL::GUI_LoL(LoLEngine *vm) : GUI(vm), _vm(vm), _screen(vm->_screen) {
_scrollUpFunctor = BUTTON_FUNCTOR(GUI_LoL, this, &GUI_LoL::scrollUp);
_scrollDownFunctor = BUTTON_FUNCTOR(GUI_LoL, this, &GUI_LoL::scrollDown);
+ _redrawButtonFunctor = BUTTON_FUNCTOR(GUI, this, &GUI::redrawButtonCallback);
+ _redrawShadedButtonFunctor = BUTTON_FUNCTOR(GUI, this, &GUI::redrawShadedButtonCallback);
+
_specialProcessButton = _backUpButtonList = 0;
_flagsModifier = 0;
_mouseClick = 0;
+ _sliderSfx = 11;
_buttonListChanged = false;
}
@@ -2164,6 +2209,624 @@ int GUI_LoL::processButtonList(Button *buttonList, uint16 inputFlag, int8 mouseW
return returnValue;
}
+int GUI_LoL::redrawButtonCallback(Button *button) {
+ if (!_displayMenu)
+ return 0;
+
+ _screen->drawBox(button->x + 1, button->y + 1, button->x + button->width - 1, button->y + button->height - 1, 225);
+ return 0;
+}
+
+int GUI_LoL::redrawShadedButtonCallback(Button *button) {
+ if (!_displayMenu)
+ return 0;
+
+ _screen->drawShadedBox(button->x, button->y, button->x + button->width, button->y + button->height, 223, 227, Screen::kShadeTypeLol);
+ return 0;
+}
+
+int GUI_LoL::runMenu(Menu &menu) {
+ _currentMenu = &menu;
+ _lastMenu = _currentMenu;
+ _newMenu = 0;
+ _displayMenu = true;
+ _menuResult = 1;
+ _savegameOffset = 0;
+ backupPage0();
+
+ const ScreenDim *d = _screen->getScreenDim(8);
+ uint32 textCursorTimer = 0;
+ uint8 textCursorStatus = 1;
+ int wW = _screen->getCharWidth('W');
+ int fW = (d->w << 3) - wW;
+ int fC = 0;
+
+ // LoL doesnt't have default higlighted items. No item should be
+ // highlighted when entering a new menu.
+ // Instead, the respevtive struct entry is used to determine whether
+ // a menu has scroll buttons or slider bars.
+ uint8 hasSpecialButtons = 0;
+
+ while (_displayMenu) {
+ _vm->_mouseX = _vm->_mouseY = 0;
+
+ if (_currentMenu == &_loadMenu || _currentMenu == &_saveMenu || _currentMenu == &_deleteMenu) {
+ updateSaveList(true);
+ Common::sort(_saveSlots.begin(), _saveSlots.end(), Common::Greater<int>());
+ setupSavegameNames(*_currentMenu, 4);
+ }
+
+ hasSpecialButtons = _currentMenu->highlightedItem;
+ _currentMenu->highlightedItem = 255;
+
+ if (_currentMenu == &_gameOptions) {
+ char *s = (char *)_vm->_tempBuffer5120;
+ strncpy(s, _vm->getLangString(0x406f + _vm->_monsterDifficulty), 30);
+ s[29] = 0;
+ _currentMenu->item[0].itemString = s;
+ s += (strlen(s) + 1);
+
+ strncpy(s, _vm->getLangString(_vm->_smoothScrollingEnabled ? 0x4068 : 0x4069), 30);
+ s[29] = 0;
+ _currentMenu->item[1].itemString = s;
+ s += (strlen(s) + 1);
+
+ strncpy(s, _vm->getLangString(_vm->_floatingCursorsEnabled ? 0x4068 : 0x4069), 30);
+ s[29] = 0;
+ _currentMenu->item[2].itemString = s;
+ s += (strlen(s) + 1);
+
+ strncpy(s, _vm->getLangString(0x42d6 + _vm->_lang), 30);
+ s[29] = 0;
+ _currentMenu->item[3].itemString = s;
+ s += (strlen(s) + 1);
+
+ strncpy(s, _vm->getLangString(_vm->textEnabled() ? 0x4068 : 0x4069), 30);
+ s[29] = 0;
+ _currentMenu->item[4].itemString = s;
+ s += (strlen(s) + 1);
+ }
+
+ if (hasSpecialButtons == 1) {
+ if (_savegameOffset == 0) {
+ _scrollUpButton.data0ShapePtr = _scrollUpButton.data1ShapePtr = _scrollUpButton.data2ShapePtr = 0;
+ } else {
+ _scrollUpButton.data0ShapePtr = _vm->_gameShapes[17];
+ _scrollUpButton.data1ShapePtr = _scrollUpButton.data2ShapePtr = _vm->_gameShapes[19];
+ }
+ if ((uint)_savegameOffset == _saveSlots.size() - 4) {
+ _scrollDownButton.data0ShapePtr = _scrollDownButton.data1ShapePtr = _scrollDownButton.data2ShapePtr = 0;
+ } else {
+ _scrollDownButton.data0ShapePtr = _vm->_gameShapes[18];
+ _scrollDownButton.data1ShapePtr = _scrollDownButton.data2ShapePtr = _vm->_gameShapes[20];
+ }
+ }
+
+ for (uint i = 0; i < _currentMenu->numberOfItems; ++i) {
+ _menuButtons[i].data0Val1 = _menuButtons[i].data1Val1 = _menuButtons[i].data2Val1 = 4;
+ _menuButtons[i].data0Callback = _redrawShadedButtonFunctor;
+ _menuButtons[i].data1Callback = _menuButtons[i].data2Callback = _redrawButtonFunctor;
+ _menuButtons[i].flags = 0x4487;
+ _menuButtons[i].flags2 = 0;
+ }
+
+ initMenu(*_currentMenu);
+
+ if (hasSpecialButtons == 2) {
+ static const uint8 oX[] = { 0, 10, 124 };
+ static const uint8 oW[] = { 10, 114, 10 };
+
+ for (int i = 1; i < 4; ++i) {
+ int tX = _currentMenu->x + _currentMenu->item[i].x;
+ int tY = _currentMenu->y + _currentMenu->item[i].y;
+
+ for (int ii = 0; ii < 3; ++ii) {
+ Button *b = getButtonListData() + 1 + (i - 1) * 3 + ii;
+ b->nextButton = 0;
+ b->data0Val2 = b->data1Val2 = b->data2Val2 = 0xfe;
+ b->data0Val3 = b->data1Val3 = b->data2Val3 = 0x01;
+
+ b->index = ii;
+ b->keyCode = b->keyCode2 = 0;
+
+ b->x = tX + oX[ii];
+ b->y = tY;
+ b->width = oW[ii];
+ b->height = _currentMenu->item[i].height;
+
+ b->data0Val1 = b->data1Val1 = b->data2Val1 = 0;
+ b->flags = (ii == 1) ? 0x6606 : 0x4406;
+
+ b->dimTableIndex = 0;
+
+ b->buttonCallback = _currentMenu->item[i].callback;
+ b->arg = _currentMenu->item[i].itemId;
+
+ _menuButtonList = addButtonToList(_menuButtonList, b);
+
+ processButton(b);
+ updateButton(b);
+ }
+
+ _currentMenu->item[i].labelX = _currentMenu->item[i].x - 5;
+ _currentMenu->item[i].labelY = _currentMenu->item[i].y + 3;
+
+ printMenuText(getMenuItemLabel(_currentMenu->item[i]), _currentMenu->x + _currentMenu->item[i].labelX, _currentMenu->y + _currentMenu->item[i].labelY, _currentMenu->item[i].textColor, 0, 10);
+
+ int volume = _vm->getVolume((KyraEngine_v1::kVolumeEntry)(i - 1));
+ _screen->drawShape(_screen->_curPage, _vm->_gameShapes[85], tX , tY, 0, 0x10);
+ _screen->drawShape(_screen->_curPage, _vm->_gameShapes[87], tX + 2 + oX[1], tY, 0, 0x10);
+ _screen->drawShape(_screen->_curPage, _vm->_gameShapes[86], tX + oX[1] + volume, tY, 0, 0x10);
+ }
+
+ _screen->updateScreen();
+ }
+
+ if (_currentMenu == &_mainMenu) {
+ Screen::FontId f = _screen->setFont(Screen::FID_6_FNT);
+ _screen->fprintString("%s", menu.x + 8, menu.y + menu.height - 12, 204, 0, 8, gScummVMVersion);
+ _screen->setFont(f);
+ _screen->updateScreen();
+ }
+
+ if (_currentMenu == &_savenameMenu) {
+ int mx = (d->sx << 3) - 1;
+ int my = d->sy - 1;
+ int mw = (d->w << 3) + 1;
+ int mh = d->h + 1;
+ _screen->drawShadedBox(mx, my, mx + mw, my + mh, 227, 223, Screen::kShadeTypeLol);
+ int pg = _screen->setCurPage(0);
+ _vm->_txt->clearDim(8);
+ textCursorTimer = 0;
+ textCursorStatus = 0;
+
+ fC = _screen->getTextWidth(_saveDescription);
+ while (fC >= fW) {
+ _saveDescription[strlen(_saveDescription) - 1] = 0;
+ fC = _screen->getTextWidth(_saveDescription);
+ }
+
+ _screen->fprintString(_saveDescription, (d->sx << 3), d->sy + 2, d->unk8, d->unkA, 0);
+ _screen->fillRect((d->sx << 3) + fC, d->sy, (d->sx << 3) + fC + wW, d->sy + d->h - 1, d->unk8, 0);
+ _screen->setCurPage(pg);
+ }
+
+ while (!_newMenu && _displayMenu) {
+ processHighlights(*_currentMenu);
+
+ if (_currentMenu == &_savenameMenu) {
+ if (textCursorTimer <= _vm->_system->getMillis()) {
+ fC = _screen->getTextWidth(_saveDescription);
+ textCursorStatus ^= 1;
+ textCursorTimer = _vm->_system->getMillis() + 20 * _vm->_tickLength;
+ _screen->fillRect((d->sx << 3) + fC, d->sy, (d->sx << 3) + fC + wW, d->sy + d->h - 1, textCursorStatus ? d->unk8 : d->unkA, 0);
+ _screen->updateScreen();
+ }
+ }
+
+ if (getInput()) {
+ if (!_newMenu)
+ _newMenu = (_currentMenu != &_audioOptions) ? _currentMenu : 0;
+ else
+ _lastMenu = _menuResult == -1 ? _lastMenu : _currentMenu;
+ }
+
+ if (!_menuResult)
+ _displayMenu = false;
+ }
+
+ if (_newMenu != _currentMenu || !_displayMenu)
+ restorePage0();
+
+ _currentMenu->highlightedItem = hasSpecialButtons;
+
+ if (_newMenu)
+ _currentMenu = _newMenu;
+
+ _newMenu = 0;
+ }
+
+ return _menuResult;
+}
+
+void GUI_LoL::createScreenThumbnail(Graphics::Surface &dst) {
+ uint8 *screenPal = new uint8[768];
+ _screen->getRealPalette(1, screenPal);
+ ::createThumbnail(&dst, _screen->getCPagePtr(7), Screen::SCREEN_W, Screen::SCREEN_H, screenPal);
+ delete[] screenPal;
+}
+
+void GUI_LoL::backupPage0() {
+ _screen->copyPage(0, 7);
+}
+
+void GUI_LoL::restorePage0() {
+ _screen->copyPage(7, 0);
+ _screen->updateScreen();
+}
+
+void GUI_LoL::setupSavegameNames(Menu &menu, int num) {
+ char *s = (char *)_vm->_tempBuffer5120;
+
+ for (int i = 0; i < num; ++i) {
+ menu.item[i].saveSlot = -1;
+ menu.item[i].enabled = false;
+ }
+
+ int startSlot = 0;
+ if (&menu == &_saveMenu && _savegameOffset == 0)
+ startSlot = 1;
+
+ KyraEngine_v1::SaveHeader header;
+ Common::InSaveFile *in;
+ for (int i = startSlot; i < num && uint(_savegameOffset + i) < _saveSlots.size(); ++i) {
+ if ((in = _vm->openSaveForReading(_vm->getSavegameFilename(_saveSlots[i + _savegameOffset - startSlot]), header)) != 0) {
+ strncpy(s, header.description.c_str(), 80);
+ s[79] = 0;
+
+ Util::convertISOToDOS(s);
+
+ menu.item[i].itemString = s;
+ s += (strlen(s) + 1);
+ menu.item[i].saveSlot = _saveSlots[i + _savegameOffset];
+ menu.item[i].enabled = true;
+ delete in;
+ }
+ }
+
+ if (_savegameOffset == 0) {
+ if (&menu == &_saveMenu) {
+ strcpy(s, _vm->getLangString(0x4010));
+ menu.item[0].itemString = s;
+ menu.item[0].saveSlot = -3;
+ menu.item[0].enabled = true;
+ }
+ }
+}
+
+void GUI_LoL::printMenuText(const char *str, int x, int y, uint8 c0, uint8 c1, uint8 flags, Screen::FontId font) {
+ _screen->fprintString(str, x, y, c0, c1, flags);
+}
+
+int GUI_LoL::getMenuCenterStringX(const char *str, int x1, int x2) {
+ if (!str)
+ return 0;
+
+ int strWidth = _screen->getTextWidth(str);
+ int w = x2 - x1 + 1;
+ return x1 + (w - strWidth) / 2;
+}
+
+int GUI_LoL::getInput() {
+ if (!_displayMenu)
+ return 0;
+
+ Common::Point p = _vm->getMousePos();
+ _vm->_mouseX = p.x;
+ _vm->_mouseY = p.y;
+
+ if (_currentMenu == &_savenameMenu) {
+ _vm->updateInput();
+
+ for (Common::List<KyraEngine_v1::Event>::const_iterator evt = _vm->_eventList.begin(); evt != _vm->_eventList.end(); evt++) {
+ if (evt->event.type == Common::EVENT_KEYDOWN)
+ _keyPressed = evt->event.kbd;
+ }
+ }
+
+ int inputFlag = _vm->checkInput(_menuButtonList);
+
+ if (_currentMenu == &_savenameMenu && _keyPressed.ascii){
+ char inputKey = _keyPressed.ascii;
+ Util::convertISOToDOS(inputKey);
+
+ if ((uint8)inputKey > 31 && (uint8)inputKey < 226) {
+ _saveDescription[strlen(_saveDescription) + 1] = 0;
+ _saveDescription[strlen(_saveDescription)] = inputKey;
+ inputFlag |= 0x8000;
+ } else if (_keyPressed.keycode == Common::KEYCODE_BACKSPACE && strlen(_saveDescription)) {
+ _saveDescription[strlen(_saveDescription) - 1] = 0;
+ inputFlag |= 0x8000;
+ }
+ }
+
+ _vm->removeInputTop();
+ _keyPressed.reset();
+
+ if (_vm->shouldQuit())
+ _displayMenu = false;
+
+ _vm->delay(8);
+ return inputFlag & 0x8000 ? 1 : 0;
+}
+
+int GUI_LoL::clickedMainMenu(Button *button) {
+ updateMenuButton(button);
+ switch (button->arg) {
+ case 0x4001:
+ _savegameOffset = 0;
+ _newMenu = &_loadMenu;
+ break;
+ case 0x4002:
+ _savegameOffset = 0;
+ _newMenu = &_saveMenu;
+ break;
+ case 0x4003:
+ _savegameOffset = 0;
+ _newMenu = &_deleteMenu;
+ break;
+ case 0x4004:
+ _newMenu = &_gameOptions;
+ break;
+ case 0x42D9:
+ _newMenu = &_audioOptions;
+ break;
+ case 0x4006:
+ _choiceMenu.menuNameId = 0x400a;
+ _newMenu = &_choiceMenu;
+ break;
+ case 0x4005:
+ _displayMenu = false;
+ break;
+ }
+ return 1;
+}
+
+int GUI_LoL::clickedLoadMenu(Button *button) {
+ updateMenuButton(button);
+
+ if (button->arg == 0x4011) {
+ if (_currentMenu != _lastMenu)
+ _newMenu = _lastMenu;
+ else
+ _menuResult = 0;
+ return 1;
+ }
+
+ int16 s = (int16)button->arg;
+ _vm->_gameToLoad = _loadMenu.item[-s - 2].saveSlot;
+ _displayMenu = false;
+
+ return 1;
+}
+
+int GUI_LoL::clickedSaveMenu(Button *button) {
+ updateMenuButton(button);
+
+ if (button->arg == 0x4011) {
+ _newMenu = &_mainMenu;
+ return 1;
+ }
+
+ _newMenu = &_savenameMenu;
+ int16 s = (int16)button->arg;
+ _menuResult = _saveMenu.item[-s - 2].saveSlot + 1;
+ _saveDescription = (char*)_vm->_tempBuffer5120 + 1000;
+ _saveDescription[0] = 0;
+ if (_saveMenu.item[-s - 2].saveSlot != -3)
+ strcpy(_saveDescription, _saveMenu.item[-s - 2].itemString);
+
+ return 1;
+}
+
+int GUI_LoL::clickedDeleteMenu(Button *button) {
+ updateMenuButton(button);
+
+ if (button->arg == 0x4011) {
+ _newMenu = &_mainMenu;
+ return 1;
+ }
+
+ _choiceMenu.menuNameId = 0x400b;
+ _newMenu = &_choiceMenu;
+ int16 s = (int16)button->arg;
+ _menuResult = _deleteMenu.item[-s - 2].saveSlot + 1;
+
+ return 1;
+}
+
+int GUI_LoL::clickedOptionsMenu(Button *button) {
+ updateMenuButton(button);
+
+ switch (button->arg) {
+ case 0xfff7:
+ _vm->_monsterDifficulty = ++_vm->_monsterDifficulty % 3;
+ break;
+ case 0xfff6:
+ _vm->_smoothScrollingEnabled ^= true;
+ break;
+ case 0xfff5:
+ _vm->_floatingCursorsEnabled ^= true;
+ break;
+ case 0xfff4:
+ _vm->_lang = ++_vm->_lang % 3;
+ break;
+ case 0xfff3:
+ _vm->_configVoice ^= 1;
+ break;
+ case 0x4072:
+ char filename[13];
+ snprintf(filename, sizeof(filename), "LEVEL%02d.%s", _vm->_currentLevel, _vm->_languageExt[_vm->_lang]);
+ if (_vm->_levelLangFile)
+ delete[] _vm->_levelLangFile;
+ _vm->_levelLangFile = _vm->resource()->fileData(filename, 0);
+ snprintf(filename, sizeof(filename), "LANDS.%s", _vm->_languageExt[_vm->_lang]);
+ if (_vm->_landsFile)
+ delete[] _vm->_landsFile;
+ _vm->_landsFile = _vm->resource()->fileData(filename, 0);
+ _newMenu = _lastMenu;
+ break;
+ }
+
+ return 1;
+}
+
+int GUI_LoL::clickedAudioMenu(Button *button) {
+ updateMenuButton(button);
+
+ if (button->arg == 0x4072) {
+ _newMenu = _lastMenu;
+ return 1;
+ }
+
+ int tX = button->x;
+ const int oldVolume = _vm->getVolume((KyraEngine_v1::kVolumeEntry)(button->arg - 3));
+ int newVolume = oldVolume;
+
+ if (button->index == 0) {
+ newVolume -= 10;
+ tX += 10;
+ } else if (button->index == 1) {
+ newVolume = _vm->_mouseX - (tX + 7);
+ } else if (button->index == 2) {
+ newVolume += 10;
+ tX -= 114;
+ }
+
+ newVolume = CLIP(newVolume, 2, 102);
+
+ if (newVolume == oldVolume) {
+ _screen->updateScreen();
+ return 0;
+ }
+
+ _screen->drawShape(0, _vm->_gameShapes[87], tX + oldVolume, button->y, 0, 0x10);
+ // Temporary HACK
+ const int volumeDrawX = _vm->convertVolumeFromMixer(_vm->convertVolumeToMixer(newVolume));
+ _screen->drawShape(0, _vm->_gameShapes[86], tX + volumeDrawX, button->y, 0, 0x10);
+ _screen->updateScreen();
+
+ _vm->snd_stopSpeech(0);
+
+ _vm->setVolume((KyraEngine_v1::kVolumeEntry)(button->arg - 3), newVolume);
+
+ if (newVolume) {
+ if (button->arg == 4) {
+ _vm->snd_playSoundEffect(_sliderSfx, -1);
+ int16 vocIndex = (int16)READ_LE_UINT16(&_vm->_ingameSoundIndex[_sliderSfx * 2]);
+ do {
+ ++_sliderSfx;
+ if (_sliderSfx < 47)
+ _sliderSfx++;
+ if (vocIndex == 199)
+ _sliderSfx = 11;
+ vocIndex = (int16)READ_LE_UINT16(&_vm->_ingameSoundIndex[_sliderSfx * 2]);
+ if (vocIndex == -1)
+ continue;
+ if (!scumm_stricmp(_vm->_ingameSoundList[vocIndex], "EMPTY"))
+ continue;
+ break;
+ } while (1);
+ } else if (button->arg == 5) {
+ _vm->_lastSpeechId = -1;
+ _vm->snd_playCharacterSpeech(0x42e0, 0, 0);
+ }
+ }
+
+ return 1;
+}
+
+int GUI_LoL::clickedDeathMenu(Button *button) {
+ updateMenuButton(button);
+ if (button->arg == _deathMenu.item[0].itemId) {
+ _vm->quitGame();
+ } else if (button->arg == _deathMenu.item[1].itemId) {
+ _newMenu = &_loadMenu;
+ }
+ return 1;
+}
+
+int GUI_LoL::clickedSavenameMenu(Button *button) {
+ updateMenuButton(button);
+ if (button->arg == _savenameMenu.item[0].itemId) {
+
+ Util::convertDOSToISO(_saveDescription);
+
+ int slot = _menuResult == -2 ? getNextSavegameSlot() : _menuResult;
+ Graphics::Surface thumb;
+ createScreenThumbnail(thumb);
+ _vm->saveGameState(slot, _saveDescription, &thumb);
+ thumb.free();
+
+ _displayMenu = false;
+
+ } else if (button->arg == _savenameMenu.item[1].itemId) {
+ _newMenu = &_saveMenu;
+ }
+
+ return 1;
+}
+
+int GUI_LoL::clickedChoiceMenu(Button *button) {
+ updateMenuButton(button);
+ if (button->arg == _choiceMenu.item[0].itemId) {
+ if (_lastMenu == &_mainMenu) {
+ _vm->quitGame();
+ } else if (_lastMenu == &_deleteMenu) {
+ _vm->_saveFileMan->removeSavefile(_vm->getSavegameFilename(_menuResult - 1));
+ Common::Array<int>::iterator i = Common::find(_saveSlots.begin(), _saveSlots.end(), _menuResult);
+ while (i != _saveSlots.end()) {
+ ++i;
+ if (i == _saveSlots.end())
+ break;
+ // We are only renaming all savefiles until we get some slots missing
+ // Also not rename quicksave slot filenames
+ if (*(i-1) != *i || *i >= 990)
+ break;
+ Common::String oldName = _vm->getSavegameFilename(*i);
+ Common::String newName = _vm->getSavegameFilename(*i-1);
+ _vm->_saveFileMan->renameSavefile(oldName, newName);
+ }
+ _newMenu = &_mainMenu;
+ }
+ } else if (button->arg == _choiceMenu.item[1].itemId) {
+ _newMenu = &_mainMenu;
+ }
+ return 1;
+}
+
+int GUI_LoL::scrollUp(Button *button) {
+ updateButton(button);
+ if (_savegameOffset > 0) {
+ _savegameOffset--;
+ _newMenu = _currentMenu;
+ _menuResult = -1;
+ }
+ return 1;
+}
+
+int GUI_LoL::scrollDown(Button *button) {
+ updateButton(button);
+ if ((uint)_savegameOffset < _saveSlots.size() - 4) {
+ _savegameOffset++;
+ _newMenu = _currentMenu;
+ _menuResult = -1;
+ }
+ return 1;
+}
+
+const char *GUI_LoL::getMenuTitle(const Menu &menu) {
+ if (!menu.menuNameId)
+ return 0;
+ return _vm->getLangString(menu.menuNameId);
+}
+
+const char *GUI_LoL::getMenuItemTitle(const MenuItem &menuItem) {
+ if (menuItem.itemId & 0x8000 && menuItem.itemString)
+ return menuItem.itemString;
+ else if (menuItem.itemId & 0x8000 || !menuItem.itemId)
+ return 0;
+ return _vm->getLangString(menuItem.itemId);
+}
+
+const char *GUI_LoL::getMenuItemLabel(const MenuItem &menuItem) {
+ if (menuItem.labelId & 0x8000 && menuItem.labelString)
+ return menuItem.labelString;
+ else if (menuItem.labelId & 0x8000 || !menuItem.labelId)
+ return 0;
+ return _vm->getLangString(menuItem.labelId);
+}
+
} // end of namespace Kyra
#endif // ENABLE_LOL
diff --git a/engines/kyra/gui_lol.h b/engines/kyra/gui_lol.h
index 631e29bd3b..832199f23e 100644
--- a/engines/kyra/gui_lol.h
+++ b/engines/kyra/gui_lol.h
@@ -31,6 +31,50 @@
#include "kyra/gui.h"
namespace Kyra {
+#define GUI_LOL_MENU(menu, a, b, c, d, e, f, g, i) \
+ do { \
+ const ScreenDim *dim = _screen->getScreenDim(a); \
+ menu.x = (dim->sx << 3); \
+ menu.y = (dim->sy); \
+ menu.width = (dim->w << 3); \
+ menu.height = (dim->h); \
+ menu.bkgdColor = 225; \
+ menu.color1 = 223; \
+ menu.color2 = 227; \
+ menu.menuNameId = b; \
+ menu.highlightedItem = c; \
+ menu.numberOfItems = d; \
+ menu.titleX = (dim->sx << 3) + (dim->w << 2); \
+ menu.titleY = 6; \
+ menu.textColor = 254; \
+ menu.scrollUpButtonX = e; \
+ menu.scrollUpButtonY = f; \
+ menu.scrollDownButtonX = g; \
+ menu.scrollDownButtonY = i; \
+ } while (0)
+
+ #define GUI_LOL_MENU_ITEM(item, a, b, c, d, e, f, g) \
+ do { \
+ item.enabled = 1; \
+ item.itemId = a; \
+ item.itemString = 0; \
+ item.x = b; \
+ item.y = c; \
+ item.width = d; \
+ item.height = e; \
+ item.textColor = 204; \
+ item.highlightColor = 254; \
+ item.titleX = -1; \
+ item.bkgdColor = 225; \
+ item.color1 = 223; \
+ item.color2 = 227; \
+ item.saveSlot = 0; \
+ item.labelId = f; \
+ item.labelString = 0; \
+ item.labelX = 0; \
+ item.labelY = 0; \
+ item.keyCode = g; \
+ } while (0)
class LoLEngine;
class Screen_LoL;
@@ -40,14 +84,67 @@ class GUI_LoL : public GUI {
public:
GUI_LoL(LoLEngine *vm);
+ void initStaticData();
+
// button specific
void processButton(Button *button);
int processButtonList(Button *buttonList, uint16 inputFlags, int8 mouseWheel);
+ int redrawShadedButtonCallback(Button *button);
+ int redrawButtonCallback(Button *button);
+
+ int runMenu(Menu &menu);
+
// utilities for thumbnail creation
- void createScreenThumbnail(Graphics::Surface &dst) {}
+ void createScreenThumbnail(Graphics::Surface &dst);
private:
+ void backupPage0();
+ void restorePage0();
+
+ void setupSavegameNames(Menu &menu, int num);
+
+ void printMenuText(const char *str, int x, int y, uint8 c0, uint8 c1, uint8 flags, Screen::FontId font=Screen::FID_9_FNT);
+ int getMenuCenterStringX(const char *str, int x1, int x2);
+
+ int getInput();
+
+ int clickedMainMenu(Button *button);
+ int clickedLoadMenu(Button *button);
+ int clickedSaveMenu(Button *button);
+ int clickedDeleteMenu(Button *button);
+ int clickedOptionsMenu(Button *button);
+ int clickedAudioMenu(Button *button);
+ int clickedDeathMenu(Button *button);
+ int clickedSavenameMenu(Button *button);
+ int clickedChoiceMenu(Button *button);
+
+ int scrollUp(Button *button);
+ int scrollDown(Button *button);
+
+ Button *getButtonListData() { return _menuButtons; }
+ Button *getScrollUpButton() { return &_scrollUpButton; }
+ Button *getScrollDownButton() { return &_scrollDownButton; }
+
+
+ Button::Callback getScrollUpButtonHandler() const { return _scrollUpFunctor; }
+ Button::Callback getScrollDownButtonHandler() const { return _scrollDownFunctor; }
+
+ uint8 defaultColor1() const { return 0xFE; }
+ uint8 defaultColor2() const { return 0x00; }
+
+ const char *getMenuTitle(const Menu &menu);
+ const char *getMenuItemTitle(const MenuItem &menuItem);
+ const char *getMenuItemLabel(const MenuItem &menuItem);
+
+ Button _menuButtons[10];
+ Button _scrollUpButton;
+ Button _scrollDownButton;
+ Menu _mainMenu, _gameOptions, _audioOptions, _choiceMenu, _loadMenu, _saveMenu, _deleteMenu, _savenameMenu, _deathMenu;
+ Menu *_currentMenu, *_lastMenu, *_newMenu;
+ int _menuResult;
+ char *_saveDescription;
+
LoLEngine *_vm;
Screen_LoL *_screen;
@@ -59,24 +156,11 @@ private:
uint16 _flagsModifier;
uint8 _mouseClick;
- int scrollUp(Button *button) { return 0; }
- int scrollDown(Button *button) { return 0; }
-
- Button *getButtonListData() { return 0; }
- Button *getScrollUpButton() { return 0; }
- Button *getScrollDownButton() { return 0; }
+ int _savegameOffset;
+ int _sliderSfx;
Button::Callback _scrollUpFunctor;
Button::Callback _scrollDownFunctor;
- Button::Callback getScrollUpButtonHandler() const { return _scrollUpFunctor; }
- Button::Callback getScrollDownButtonHandler() const { return _scrollDownFunctor; }
-
- uint8 defaultColor1() const { return 0; }
- uint8 defaultColor2() const { return 0; }
-
- const char *getMenuTitle(const Menu &menu) { return 0; }
- const char *getMenuItemTitle(const MenuItem &menuItem) { return 0; }
- const char *getMenuItemLabel(const MenuItem &menuItem) { return 0; }
};
} // end of namespace Kyra
diff --git a/engines/kyra/gui_mr.cpp b/engines/kyra/gui_mr.cpp
index c4d804c14d..e7001ed31f 100644
--- a/engines/kyra/gui_mr.cpp
+++ b/engines/kyra/gui_mr.cpp
@@ -352,10 +352,10 @@ void KyraEngine_MR::drawMalcolmsMoodPointer(int frame, int page) {
frame = 13;
if (page == 0) {
- _invWsa->displayFrame(frame, 0, 0, 0, 0);
+ _invWsa->displayFrame(frame, 0, 0, 0, 0, 0, 0);
_screen->updateScreen();
} else if (page == 30) {
- _invWsa->displayFrame(frame, 2, 0, -144, 0);
+ _invWsa->displayFrame(frame, 2, 0, -144, 0, 0, 0);
}
_invWsaFrame = frame;
@@ -674,21 +674,21 @@ void KyraEngine_MR::showAlbum() {
_screen->copyRegionToBuffer(0, 0, 0, 320, 200, _screenBuffer);
_screen->copyRegionToBuffer(4, 0, 0, 320, 200, _album.backUpPage);
- memcpy(_screen->getPalette(1), _screen->getPalette(0), 768);
+ _screen->copyPalette(1, 0);
_screen->fadeToBlack(9);
int itemInHand = _itemInHand;
removeHandItem();
- _res->loadFileToBuf("ALBUM.COL", _screen->getPalette(0), 768);
+ _screen->loadPalette("ALBUM.COL", _screen->getPalette(0));
loadAlbumPage();
loadAlbumPageWSA();
if (_album.leftPage.wsa->opened())
- _album.leftPage.wsa->displayFrame(_album.leftPage.curFrame, 2, _albumWSAX[_album.nextPage+0], _albumWSAY[_album.nextPage+0], 0x4000);
+ _album.leftPage.wsa->displayFrame(_album.leftPage.curFrame, 2, _albumWSAX[_album.nextPage+0], _albumWSAY[_album.nextPage+0], 0x4000, 0, 0);
if (_album.rightPage.wsa->opened())
- _album.rightPage.wsa->displayFrame(_album.rightPage.curFrame, 2, _albumWSAX[_album.nextPage+1], _albumWSAY[_album.nextPage+1], 0x4000);
+ _album.rightPage.wsa->displayFrame(_album.rightPage.curFrame, 2, _albumWSAX[_album.nextPage+1], _albumWSAY[_album.nextPage+1], 0x4000, 0, 0);
printAlbumPageText();
_screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 0, Screen::CR_NO_P_CHECK);
@@ -707,7 +707,7 @@ void KyraEngine_MR::showAlbum() {
_screen->copyBlockToPage(0, 0, 0, 320, 200, _screenBuffer);
_screen->copyBlockToPage(4, 0, 0, 320, 200, _album.backUpPage);
- memcpy(_screen->getPalette(0), _screen->getPalette(1), 768);
+ _screen->copyPalette(0, 1);
_screen->fadePalette(_screen->getPalette(0), 9);
delete[] _album.backUpRect;
@@ -843,10 +843,10 @@ void KyraEngine_MR::processAlbum() {
loadAlbumPageWSA();
if (_album.leftPage.wsa->opened())
- _album.leftPage.wsa->displayFrame(_album.leftPage.curFrame, 2, _albumWSAX[_album.nextPage+0], _albumWSAY[_album.nextPage+0], 0x4000);
+ _album.leftPage.wsa->displayFrame(_album.leftPage.curFrame, 2, _albumWSAX[_album.nextPage+0], _albumWSAY[_album.nextPage+0], 0x4000, 0, 0);
if (_album.rightPage.wsa->opened())
- _album.rightPage.wsa->displayFrame(_album.rightPage.curFrame, 2, _albumWSAX[_album.nextPage+1], _albumWSAY[_album.nextPage+1], 0x4000);
+ _album.rightPage.wsa->displayFrame(_album.rightPage.curFrame, 2, _albumWSAX[_album.nextPage+1], _albumWSAY[_album.nextPage+1], 0x4000, 0, 0);
printAlbumPageText();
@@ -899,7 +899,7 @@ void KyraEngine_MR::albumUpdateAnims() {
nextRun = _album.leftPage.timer + 5 * _tickLength;
if (nextRun < _system->getMillis() && _album.leftPage.wsa->opened()) {
- _album.leftPage.wsa->displayFrame(_album.leftPage.curFrame, 2, _albumWSAX[_album.nextPage+0], _albumWSAY[_album.nextPage+0], 0x4000);
+ _album.leftPage.wsa->displayFrame(_album.leftPage.curFrame, 2, _albumWSAX[_album.nextPage+0], _albumWSAY[_album.nextPage+0], 0x4000, 0, 0);
_screen->copyRegion(40, 17, 40, 17, 87, 73, 2, 0, Screen::CR_NO_P_CHECK);
++_album.leftPage.curFrame;
@@ -918,7 +918,7 @@ void KyraEngine_MR::albumUpdateAnims() {
nextRun = _album.rightPage.timer + 5 * _tickLength;
if (nextRun < _system->getMillis() && _album.rightPage.wsa->opened()) {
- _album.rightPage.wsa->displayFrame(_album.rightPage.curFrame, 2, _albumWSAX[_album.nextPage+1], _albumWSAY[_album.nextPage+1], 0x4000);
+ _album.rightPage.wsa->displayFrame(_album.rightPage.curFrame, 2, _albumWSAX[_album.nextPage+1], _albumWSAY[_album.nextPage+1], 0x4000, 0, 0);
_screen->copyRegion(194, 20, 194, 20, 85, 69, 2, 0, Screen::CR_NO_P_CHECK);
++_album.rightPage.curFrame;
@@ -936,13 +936,13 @@ void KyraEngine_MR::albumUpdateAnims() {
void KyraEngine_MR::albumAnim1() {
for (int i = 6; i >= 3; --i) {
albumRestoreRect();
- _album.wsa->displayFrame(i, 2, -100, 90, 0x4000);
+ _album.wsa->displayFrame(i, 2, -100, 90, 0x4000, 0, 0);
albumUpdateRect();
delayWithTicks(1);
}
albumRestoreRect();
- _album.wsa->displayFrame(14, 2, -100, 90, 0x4000);
+ _album.wsa->displayFrame(14, 2, -100, 90, 0x4000, 0, 0);
albumUpdateRect();
delayWithTicks(1);
}
@@ -950,7 +950,7 @@ void KyraEngine_MR::albumAnim1() {
void KyraEngine_MR::albumAnim2() {
for (int i = 3; i <= 6; ++i) {
albumRestoreRect();
- _album.wsa->displayFrame(i, 2, -100, 90, 0x4000);
+ _album.wsa->displayFrame(i, 2, -100, 90, 0x4000, 0, 0);
albumUpdateRect();
delayWithTicks(1);
}
@@ -1269,7 +1269,7 @@ int GUI_MR::optionsButton(Button *button) {
}
while (_displayMenu) {
- processHighlights(*_currentMenu, _vm->_mouseX, _vm->_mouseY);
+ processHighlights(*_currentMenu);
getInput();
}
@@ -1312,7 +1312,7 @@ int GUI_MR::loadMenu(Button *caller) {
_screen->updateScreen();
while (_isLoadMenu) {
- processHighlights(_loadMenu, _vm->_mouseX, _vm->_mouseY);
+ processHighlights(_loadMenu);
getInput();
}
@@ -1362,7 +1362,7 @@ int GUI_MR::gameOptions(Button *caller) {
_isOptionsMenu = true;
while (_isOptionsMenu) {
- processHighlights(_gameOptions, _vm->_mouseX, _vm->_mouseY);
+ processHighlights(_gameOptions);
getInput();
}
@@ -1525,7 +1525,7 @@ int GUI_MR::audioOptions(Button *caller) {
updateAllMenuButtons();
bool speechEnabled = _vm->speechEnabled();
while (_isOptionsMenu) {
- processHighlights(_audioOptions, _vm->_mouseX, _vm->_mouseY);
+ processHighlights(_audioOptions);
getInput();
}
@@ -1554,7 +1554,7 @@ int GUI_MR::sliderHandler(Button *caller) {
assert(button >= 0 && button <= 3);
- int oldVolume = _vm->getVolume(KyraEngine_v1::kVolumeEntry(button));
+ const int oldVolume = _vm->getVolume(KyraEngine_v1::kVolumeEntry(button));
int newVolume = oldVolume;
if (caller->index >= 24 && caller->index <= 27)
@@ -1564,8 +1564,7 @@ int GUI_MR::sliderHandler(Button *caller) {
else
newVolume = _vm->_mouseX - caller->x - 7;
- newVolume = MAX(2, newVolume);
- newVolume = MIN(97, newVolume);
+ newVolume = CLIP(newVolume, 2, 97);
if (newVolume == oldVolume)
return 0;
@@ -1621,8 +1620,7 @@ void GUI_MR::drawSliderBar(int slider, const uint8 *shape) {
int position = _vm->getVolume(KyraEngine_v1::kVolumeEntry(slider));
- position = MAX(2, position);
- position = MIN(97, position);
+ position = CLIP(position, 2, 97);
_screen->drawShape(0, shape, x+position, y, 0, 0);
}
diff --git a/engines/kyra/gui_v2.cpp b/engines/kyra/gui_v2.cpp
index 7e3d2b5afb..e5c8637fb5 100644
--- a/engines/kyra/gui_v2.cpp
+++ b/engines/kyra/gui_v2.cpp
@@ -27,6 +27,7 @@
#include "kyra/kyra_v2.h"
#include "kyra/screen_v2.h"
#include "kyra/text.h"
+#include "kyra/util.h"
#include "common/savefile.h"
@@ -158,8 +159,9 @@ int GUI_v2::processButtonList(Button *buttonList, uint16 inputFlag, int8 mouseWh
}
}
- int mouseX = _vm->_mouseX;
- int mouseY = _vm->_mouseY;
+ Common::Point p = _vm->getMousePos();
+ int mouseX = _vm->_mouseX = p.x;
+ int mouseY = _vm->_mouseY = p.y;
uint16 flags = 0;
@@ -454,8 +456,11 @@ void GUI_v2::setupSavegameNames(Menu &menu, int num) {
Common::InSaveFile *in;
for (int i = startSlot; i < num && uint(_savegameOffset + i) < _saveSlots.size(); ++i) {
if ((in = _vm->openSaveForReading(_vm->getSavegameFilename(_saveSlots[i + _savegameOffset]), header)) != 0) {
- strncpy(getTableString(menu.item[i].itemId), header.description.c_str(), 80);
- getTableString(menu.item[i].itemId)[79] = 0;
+ char *s = getTableString(menu.item[i].itemId);
+ strncpy(s, header.description.c_str(), 80);
+ s[79] = 0;
+ Util::convertISOToDOS(s);
+
menu.item[i].saveSlot = _saveSlots[i + _savegameOffset];
menu.item[i].enabled = true;
delete in;
@@ -601,7 +606,7 @@ int GUI_v2::saveMenu(Button *caller) {
updateAllMenuButtons();
while (_isSaveMenu) {
- processHighlights(_saveMenu, _vm->_mouseX, _vm->_mouseY);
+ processHighlights(_saveMenu);
getInput();
}
@@ -620,6 +625,7 @@ int GUI_v2::saveMenu(Button *caller) {
Graphics::Surface thumb;
createScreenThumbnail(thumb);
+ Util::convertDOSToISO(_saveDescription);
_vm->saveGameState(_saveSlot, _saveDescription, &thumb);
thumb.free();
@@ -697,7 +703,7 @@ int GUI_v2::deleteMenu(Button *caller) {
updateAllMenuButtons();
while (_isDeleteMenu) {
- processHighlights(_saveMenu, _vm->_mouseX, _vm->_mouseY);
+ processHighlights(_saveMenu);
getInput();
}
@@ -749,7 +755,11 @@ const char *GUI_v2::nameInputProcess(char *buffer, int x, int y, uint8 c1, uint8
_cancelNameInput = _finishNameInput = false;
while (running && !_vm->shouldQuit()) {
checkTextfieldInput();
- processHighlights(_savenameMenu, _vm->_mouseX, _vm->_mouseY);
+ processHighlights(_savenameMenu);
+
+ char inputKey = _keyPressed.ascii;
+ Util::convertISOToDOS(inputKey);
+
if (_keyPressed.keycode == Common::KEYCODE_RETURN || _keyPressed.keycode == Common::KEYCODE_KP_ENTER || _finishNameInput) {
if (checkSavegameDescription(buffer, curPos)) {
buffer[curPos] = 0;
@@ -767,12 +777,12 @@ const char *GUI_v2::nameInputProcess(char *buffer, int x, int y, uint8 c1, uint8
drawTextfieldBlock(x2, y2, c3);
_screen->updateScreen();
_lastScreenUpdate = _vm->_system->getMillis();
- } else if (_keyPressed.ascii > 31 && _keyPressed.ascii < 127 && curPos < bufferSize) {
- if (x2 + getCharWidth(_keyPressed.ascii) + 7 < 0x11F) {
- buffer[curPos] = _keyPressed.ascii;
+ } else if ((uint8)inputKey > 31 && (uint8)inputKey < 226 && curPos < bufferSize) {
+ if (x2 + getCharWidth(inputKey) + 7 < 0x11F) {
+ buffer[curPos] = inputKey;
const char text[2] = { buffer[curPos], 0 };
_text->printText(text, x2, y2, c1, c2, c2);
- x2 += getCharWidth(_keyPressed.ascii);
+ x2 += getCharWidth(inputKey);
drawTextfieldBlock(x2, y2, c3);
++curPos;
_screen->updateScreen();
@@ -840,7 +850,7 @@ bool GUI_v2::choiceDialog(int name, bool type) {
_choice = false;
while (_isChoiceMenu) {
- processHighlights(_choiceMenu, _vm->_mouseX, _vm->_mouseY);
+ processHighlights(_choiceMenu);
getInput();
}
diff --git a/engines/kyra/gui_v2.h b/engines/kyra/gui_v2.h
index ec30640b88..9af4572e4d 100644
--- a/engines/kyra/gui_v2.h
+++ b/engines/kyra/gui_v2.h
@@ -96,7 +96,7 @@ namespace Kyra {
item.labelId = n; \
item.labelX = o; \
item.labelY = p; \
- item.unk1F = q; \
+ item.keyCode = q; \
} while (0)
class KyraEngine_v2;
diff --git a/engines/kyra/items_hof.cpp b/engines/kyra/items_hof.cpp
index 9d18829252..13e269f363 100644
--- a/engines/kyra/items_hof.cpp
+++ b/engines/kyra/items_hof.cpp
@@ -238,9 +238,7 @@ void KyraEngine_HoF::itemDropDown(int startX, int startY, int dstX, int dstY, in
_screen->drawShape(0, itemShape, curX, curY-16, 0, 0);
_screen->updateScreen();
- // XXX: original doesn't update game state while delaying
- // our implementation *could* do it, so maybe check this again
- delayUntil(endDelay);
+ delayUntil(endDelay, false, true);
}
if (dstX != dstY || (dstY - startY > 16)) {
@@ -275,9 +273,7 @@ void KyraEngine_HoF::itemDropDown(int startX, int startY, int dstX, int dstY, in
_screen->drawShape(0, itemShape, x, y, 0, 0);
_screen->updateScreen();
- // XXX: original doesn't update game state while delaying
- // our implementation *could* do it, so maybe check this again
- delayUntil(endDelay);
+ delayUntil(endDelay, false, true);
}
restoreGfxRect24x24(x, y);
diff --git a/engines/kyra/items_lol.cpp b/engines/kyra/items_lol.cpp
index e75a13c870..c0ddd0c860 100644
--- a/engines/kyra/items_lol.cpp
+++ b/engines/kyra/items_lol.cpp
@@ -477,7 +477,7 @@ void LoLEngine::objectFlightProcessHits(FlyingObject *t, int x, int y, int objec
r = getNearestPartyMemberFromPos(x, y);
runItemScript(t->attackerId, t->item, 0x8000, r, 0);
}
- }
+ }
}
void LoLEngine::updateFlyingObject(FlyingObject *t) {
diff --git a/engines/kyra/kyra_hof.cpp b/engines/kyra/kyra_hof.cpp
index c2c36dcc95..5c41989713 100644
--- a/engines/kyra/kyra_hof.cpp
+++ b/engines/kyra/kyra_hof.cpp
@@ -381,10 +381,10 @@ void KyraEngine_HoF::startup() {
memset(_sceneAnims, 0, sizeof(_sceneAnims));
for (int i = 0; i < ARRAYSIZE(_sceneAnimMovie); ++i)
- _sceneAnimMovie[i] = new WSAMovie_v2(this, _screen);
+ _sceneAnimMovie[i] = new WSAMovie_v2(this);
memset(_wsaSlots, 0, sizeof(_wsaSlots));
for (int i = 0; i < ARRAYSIZE(_wsaSlots); ++i)
- _wsaSlots[i] = new WSAMovie_v2(this, _screen);
+ _wsaSlots[i] = new WSAMovie_v2(this);
_screen->_curPage = 0;
@@ -415,7 +415,7 @@ void KyraEngine_HoF::startup() {
setupLangButtonShapes();
loadInventoryShapes();
- _res->loadFileToBuf("PALETTE.COL", _screen->_currentPalette, 0x300);
+ _screen->loadPalette("PALETTE.COL", _screen->getPalette(0));
_screen->loadBitmap("_PLAYFLD.CPS", 3, 3, 0);
_screen->copyPage(3, 0);
_screen->showMouse();
@@ -451,7 +451,6 @@ void KyraEngine_HoF::startup() {
(*_inventoryButtons[0].buttonCallback)(&_inventoryButtons[0]);
setNextIdleAnimTimer();
- //XXX
setWalkspeed(_configWalkspeed);
}
@@ -643,8 +642,6 @@ bool KyraEngine_HoF::handleInputUnkSub(int x, int y) {
while (_emc->isValid(&_sceneScriptState))
_emc->run(&_sceneScriptState);
- //XXXsys_unkKeyboad (flush? wait? whatever...)
-
if (queryGameFlag(0x1ED)) {
_sound->beginFadeOut();
_screen->fadeToBlack();
@@ -919,9 +916,9 @@ void KyraEngine_HoF::showMessage(const char *string, int16 palIndex) {
if (string) {
if (palIndex != -1 || _fadeMessagePalette) {
palIndex *= 3;
- memcpy(_messagePal, _screen->_currentPalette + palIndex, 3);
- memmove(_screen->_currentPalette + 765, _screen->_currentPalette + palIndex, 3);
- _screen->setScreenPalette(_screen->_currentPalette);
+ memcpy(_messagePal, _screen->getPalette(0).getData() + palIndex, 3);
+ _screen->getPalette(0).copy(_screen->getPalette(0), palIndex / 3, 1, 255);
+ _screen->setScreenPalette(_screen->getPalette(0));
}
int x = _text->getCenterStringX(string, 0, 320);
@@ -978,7 +975,7 @@ void KyraEngine_HoF::fadeMessagePalette() {
}
if (updatePalette) {
- memcpy(_screen->getPalette(0) + 765, _messagePal, 3);
+ _screen->getPalette(0).copy(_messagePal, 0, 1, 255);
_screen->setScreenPalette(_screen->getPalette(0));
} else {
_fadeMessagePalette = false;
@@ -1139,7 +1136,7 @@ void KyraEngine_HoF::updateCharPal(int unk1) {
if (palEntry != _charPalEntry && unk1) {
const uint8 *src = &_scenePal[(palEntry << 4) * 3];
- uint8 *ptr = _screen->getPalette(0) + 336;
+ uint8 *ptr = _screen->getPalette(0).getData() + 336;
for (int i = 0; i < 48; ++i) {
*ptr -= (*ptr - *src) >> 1;
++ptr;
@@ -1149,7 +1146,7 @@ void KyraEngine_HoF::updateCharPal(int unk1) {
unkVar1 = true;
_charPalEntry = palEntry;
} else if (unkVar1 || !unk1) {
- memcpy(_screen->getPalette(0) + 336, &_scenePal[(palEntry << 4) * 3], 48);
+ _screen->getPalette(0).copy(_scenePal, palEntry << 4, 16, 112);
_screen->setScreenPalette(_screen->getPalette(0));
unkVar1 = false;
}
@@ -1550,7 +1547,7 @@ void KyraEngine_HoF::loadInvWsa(const char *filename, int run_, int delayTime, i
wsaFlags |= 2;
if (!_invWsa.wsa)
- _invWsa.wsa = new WSAMovie_v2(this, _screen);
+ _invWsa.wsa = new WSAMovie_v2(this);
if (!_invWsa.wsa->open(filename, wsaFlags, 0))
error("Couldn't open inventory WSA file '%s'", filename);
@@ -1656,12 +1653,12 @@ void KyraEngine_HoF::displayInvWsaLastFrame() {
#pragma mark -
void KyraEngine_HoF::setCauldronState(uint8 state, bool paletteFade) {
- memcpy(_screen->getPalette(2), _screen->getPalette(0), 768);
+ _screen->copyPalette(2, 0);
Common::SeekableReadStream *file = _res->createReadStream("_POTIONS.PAL");
if (!file)
error("Couldn't load cauldron palette");
file->seek(state*18, SEEK_SET);
- file->read(_screen->getPalette(2)+723, 18);
+ _screen->getPalette(0).loadVGAPalette(*file, 241, 6);
delete file;
file = 0;
@@ -1673,7 +1670,7 @@ void KyraEngine_HoF::setCauldronState(uint8 state, bool paletteFade) {
_screen->updateScreen();
}
- memcpy(_screen->getPalette(0)+723, _screen->getPalette(2)+723, 18);
+ _screen->getPalette(0).copy(_screen->getPalette(2), 241, 6);
_cauldronState = state;
_cauldronUseCount = 0;
//if (state == 5)
@@ -1833,11 +1830,11 @@ void KyraEngine_HoF::cauldronRndPaletteFade() {
if (!file)
error("Couldn't load cauldron palette");
file->seek(index*18, SEEK_SET);
- file->read(_screen->getPalette(0)+723, 18);
+ _screen->getPalette(0).loadVGAPalette(*file, 241, 6);
snd_playSoundEffect(0x6A);
_screen->fadePalette(_screen->getPalette(0), 0x1E, &_updateFunctor);
file->seek(0, SEEK_SET);
- file->read(_screen->getPalette(0)+723, 18);
+ _screen->getPalette(0).loadVGAPalette(*file, 241, 6);
delete file;
_screen->fadePalette(_screen->getPalette(0), 0x1E, &_updateFunctor);
}
diff --git a/engines/kyra/kyra_lok.cpp b/engines/kyra/kyra_lok.cpp
index fcd35e7282..e5ca52abcc 100644
--- a/engines/kyra/kyra_lok.cpp
+++ b/engines/kyra/kyra_lok.cpp
@@ -157,7 +157,10 @@ KyraEngine_LoK::~KyraEngine_LoK() {
}
Common::Error KyraEngine_LoK::init() {
- _screen = new Screen_LoK(this, _system);
+ if (_flags.platform == Common::kPlatformPC98 && _flags.useHiResOverlay && ConfMan.getBool("16_color"))
+ _screen = new Screen_LoK_16(this, _system);
+ else
+ _screen = new Screen_LoK(this, _system);
assert(_screen);
_screen->setResolution();
@@ -358,7 +361,7 @@ void KyraEngine_LoK::startup() {
loadButtonShapes();
initMainButtonList();
loadMainScreen();
- _screen->loadPalette("PALETTE.COL", _screen->_currentPalette);
+ _screen->loadPalette("PALETTE.COL", _screen->getPalette(0));
// XXX
_animator->initAnimStateList();
@@ -906,6 +909,9 @@ void KyraEngine_LoK::registerDefaultSettings() {
// Most settings already have sensible defaults. This one, however, is
// specific to the Kyra engine.
ConfMan.registerDefault("walkspeed", 2);
+
+ if (_flags.platform == Common::kPlatformPC98 && _flags.useHiResOverlay)
+ ConfMan.registerDefault("16_color", false);
}
void KyraEngine_LoK::readSettings() {
diff --git a/engines/kyra/kyra_lok.h b/engines/kyra/kyra_lok.h
index a0f38c3acc..a905c5521b 100644
--- a/engines/kyra/kyra_lok.h
+++ b/engines/kyra/kyra_lok.h
@@ -113,7 +113,6 @@ public:
KyraEngine_LoK(OSystem *system, const GameFlags &flags);
~KyraEngine_LoK();
- //TODO: proper extended implementation of KyraEngine_v1::pauseEngineIntern.
// _sprites and _seqplayer should be paused here too, to avoid some animation glitches,
// also parts of the hardcoded Malcolm fight might need some special handling.
diff --git a/engines/kyra/kyra_mr.cpp b/engines/kyra/kyra_mr.cpp
index f2ea0c91df..871edd578d 100644
--- a/engines/kyra/kyra_mr.cpp
+++ b/engines/kyra/kyra_mr.cpp
@@ -230,7 +230,7 @@ Common::Error KyraEngine_MR::init() {
_screen->setAnimBlockPtr(3500);
_screen->setScreenDim(0);
- _res->loadFileToBuf("PALETTE.COL", _screen->getPalette(0), 768);
+ _screen->loadPalette("PALETTE.COL", _screen->getPalette(0));
_screen->setScreenPalette(_screen->getPalette(0));
return Common::kNoError;
@@ -269,19 +269,18 @@ Common::Error KyraEngine_MR::go() {
_screen->setScreenPalette(_screen->getPalette(0));
- // XXX
playMenuAudioFile();
for (int i = 0; i < 64 && !shouldQuit(); ++i) {
uint32 nextRun = _system->getMillis() + 3 * _tickLength;
- _menuAnim->displayFrame(i, 0, 0, 0, 0);
+ _menuAnim->displayFrame(i, 0, 0, 0, 0, 0, 0);
_screen->updateScreen();
delayUntil(nextRun);
}
for (int i = 64; i > 29 && !shouldQuit(); --i) {
uint32 nextRun = _system->getMillis() + 3 * _tickLength;
- _menuAnim->displayFrame(i, 0, 0, 0, 0);
+ _menuAnim->displayFrame(i, 0, 0, 0, 0, 0, 0);
_screen->updateScreen();
delayUntil(nextRun);
}
@@ -327,9 +326,9 @@ Common::Error KyraEngine_MR::go() {
}
void KyraEngine_MR::initMainMenu() {
- _menuAnim = new WSAMovie_v2(this, _screen);
- _menuAnim->open("REVENGE.WSA", 1, _screen->getPalette(0));
- memset(_screen->getPalette(0), 0, 3);
+ _menuAnim = new WSAMovie_v2(this);
+ _menuAnim->open("REVENGE.WSA", 1, &_screen->getPalette(0));
+ _screen->getPalette(0).fill(0, 1, 0);
_menu = new MainMenu(this);
MainMenu::StaticData data = {
@@ -378,7 +377,7 @@ void KyraEngine_MR::playVQA(const char *name) {
}
_screen->hideMouse();
- memcpy(_screen->getPalette(1), _screen->getPalette(0), 768);
+ _screen->copyPalette(1, 0);
fadeOutMusic(60);
_screen->fadeToBlack(60);
_screen->clearPage(0);
@@ -390,12 +389,11 @@ void KyraEngine_MR::playVQA(const char *name) {
_soundDigital->stopAllSounds();
_screen->showMouse();
- uint8 pal[768];
// Taken from original, it used '1' here too
- memset(pal, 1, sizeof(pal));
- _screen->setScreenPalette(pal);
+ _screen->getPalette(0).fill(0, 256, 1);
+ _screen->setScreenPalette(_screen->getPalette(0));
_screen->clearPage(0);
- memcpy(_screen->getPalette(0), _screen->getPalette(1), 768);
+ _screen->copyPalette(0, 1);
_wasPlayingVQA = true;
}
}
@@ -541,11 +539,11 @@ void KyraEngine_MR::initMouseShapes() {
}
void KyraEngine_MR::startup() {
- _album.wsa = new WSAMovie_v2(this, _screen);
+ _album.wsa = new WSAMovie_v2(this);
assert(_album.wsa);
- _album.leftPage.wsa = new WSAMovie_v2(this, _screen);
+ _album.leftPage.wsa = new WSAMovie_v2(this);
assert(_album.leftPage.wsa);
- _album.rightPage.wsa = new WSAMovie_v2(this, _screen);
+ _album.rightPage.wsa = new WSAMovie_v2(this);
assert(_album.rightPage.wsa);
musicUpdate(0);
@@ -559,9 +557,7 @@ void KyraEngine_MR::startup() {
_screen->setFont(Screen::FID_6_FNT);
_stringBuffer = new char[500];
- //XXX
musicUpdate(0);
- //XXX
allocAnimObjects(1, 16, 50);
musicUpdate(0);
@@ -586,19 +582,16 @@ void KyraEngine_MR::startup() {
error("couldn't load _ACTOR");
musicUpdate(0);
- //XXX
- musicUpdate(0);
openTalkFile(0);
musicUpdate(0);
_currentTalkFile = 0;
openTalkFile(1);
- //XXX
loadCostPal();
musicUpdate(0);
for (int i = 0; i < 16; ++i) {
_sceneAnims[i].flags = 0;
- _sceneAnimMovie[i] = new WSAMovie_v2(this, _screen);
+ _sceneAnimMovie[i] = new WSAMovie_v2(this);
assert(_sceneAnimMovie[i]);
}
@@ -627,7 +620,7 @@ void KyraEngine_MR::startup() {
loadInterfaceShapes();
musicUpdate(0);
- _res->loadFileToBuf("PALETTE.COL", _screen->getPalette(0), 768);
+ _screen->loadPalette("PALETTE.COL", _screen->getPalette(0));
_paletteOverlay = new uint8[256];
_screen->generateOverlay(_screen->getPalette(0), _paletteOverlay, 0xF0, 0x19);
@@ -655,7 +648,7 @@ void KyraEngine_MR::startup() {
musicUpdate(0);
runStartupScript(1, 0);
_res->exists("MOODOMTR.WSA", true);
- _invWsa = new WSAMovie_v2(this, _screen);
+ _invWsa = new WSAMovie_v2(this);
assert(_invWsa);
_invWsa->open("MOODOMTR.WSA", 1, 0);
_invWsaFrame = 6;
@@ -899,40 +892,30 @@ void KyraEngine_MR::updateCharAnimFrame(int character, int *table) {
void KyraEngine_MR::updateCharPal(int unk1) {
int layer = _screen->getLayer(_mainCharacter.x1, _mainCharacter.y1) - 1;
const uint8 *src = _costPalBuffer + _characterShapeFile * 72;
- uint8 *dst = _screen->getPalette(0) + 432;
+ Palette &dst = _screen->getPalette(0);
const int8 *sceneDatPal = &_sceneDatPalette[layer * 3];
if (layer != _lastCharPalLayer && unk1) {
- for (int i = 0, j = 0; i < 72; ++i) {
- uint8 col = *dst;
- int8 addCol = *src + *sceneDatPal;
- addCol = MAX<int8>(0, MIN<int8>(addCol, 63));
- addCol = (col - addCol) >> 1;
- *dst -= addCol;
- ++dst;
- ++src;
- ++sceneDatPal;
- ++j;
- if (j > 3) {
- sceneDatPal = &_sceneDatPalette[layer * 3];
- j = 0;
+ for (int i = 144; i < 168; ++i) {
+ for (int j = 0; j < 3; ++j) {
+ uint8 col = dst[i * 3 + j];
+ int subCol = src[(i - 144) * 3 + j] + sceneDatPal[j];
+ subCol = CLIP(subCol, 0, 63);
+ subCol = (col - subCol) / 2;
+ dst[i * 3 + j] -= subCol;
}
}
+
_charPalUpdate = true;
_screen->setScreenPalette(_screen->getPalette(0));
_lastCharPalLayer = layer;
} else if (_charPalUpdate || !unk1) {
- memcpy(dst, src, 72);
-
- for (int i = 0, j = 0; i < 72; ++i) {
- uint8 col = *dst + *sceneDatPal;
- *dst = MAX<int8>(0, MIN<int8>(col, 63));
- ++dst;
- ++sceneDatPal;
- ++j;
- if (j >= 3) {
- sceneDatPal = &_sceneDatPalette[layer * 3];
- j = 0;
+ dst.copy(_costPalBuffer, _characterShapeFile * 24, 24, 144);
+
+ for (int i = 144; i < 168; ++i) {
+ for (int j = 0; j < 3; ++j) {
+ int col = dst[i * 3 + j] + sceneDatPal[j];
+ dst[i * 3 + j] = CLIP(col, 0, 63);
}
}
diff --git a/engines/kyra/kyra_mr.h b/engines/kyra/kyra_mr.h
index 6c06a84433..88bfb8c89b 100644
--- a/engines/kyra/kyra_mr.h
+++ b/engines/kyra/kyra_mr.h
@@ -50,7 +50,6 @@ public:
KyraEngine_MR(OSystem *system, const GameFlags &flags);
~KyraEngine_MR();
- //TODO: proper extended implementation of KyraEngine_v2::pauseEngineIntern.
// Idle animation time, item animations and album animations should be taken
// care of, but since those would just produce minor glitches it's not that
// important.
diff --git a/engines/kyra/kyra_v1.cpp b/engines/kyra/kyra_v1.cpp
index d9fc8f9d66..80872877d5 100644
--- a/engines/kyra/kyra_v1.cpp
+++ b/engines/kyra/kyra_v1.cpp
@@ -81,7 +81,7 @@ KyraEngine_v1::KyraEngine_v1(OSystem *system, const GameFlags &flags)
Common::addDebugChannel(kDebugLevelMovie, "Movie", "Movie debug level");
Common::addDebugChannel(kDebugLevelTimer, "Timer", "Timer debug level");
- system->getEventManager()->registerRandomSource(_rnd, "kyra");
+ _eventMan->registerRandomSource(_rnd, "kyra");
}
::GUI::Debugger *KyraEngine_v1::getDebugger() {
@@ -94,8 +94,6 @@ void KyraEngine_v1::pauseEngineIntern(bool pause) {
}
Common::Error KyraEngine_v1::init() {
- registerDefaultSettings();
-
// Setup mixer
_mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, ConfMan.getInt("sfx_volume"));
_mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, ConfMan.getInt("music_volume"));
@@ -278,10 +276,10 @@ int KyraEngine_v1::checkInput(Button *buttonList, bool mainLoop, int eventFlag)
} else {
switch(event.kbd.keycode) {
case Common::KEYCODE_SPACE:
- keys = 43;
+ keys = 61;
break;
case Common::KEYCODE_RETURN:
- keys = 61;
+ keys = 43;
break;
case Common::KEYCODE_UP:
case Common::KEYCODE_KP8:
@@ -594,27 +592,27 @@ bool KyraEngine_v1::textEnabled() {
return !_flags.isTalkie || (_configVoice == 0 || _configVoice == 2);
}
-inline int convertValueToMixer(int value) {
+int KyraEngine_v1::convertVolumeToMixer(int value) {
value -= 2;
return (value * Audio::Mixer::kMaxMixerVolume) / 95;
}
-inline int convertValueFromMixer(int value) {
+int KyraEngine_v1::convertVolumeFromMixer(int value) {
return (value * 95) / Audio::Mixer::kMaxMixerVolume + 2;
}
void KyraEngine_v1::setVolume(kVolumeEntry vol, uint8 value) {
switch (vol) {
case kVolumeMusic:
- ConfMan.setInt("music_volume", convertValueToMixer(value));
+ ConfMan.setInt("music_volume", convertVolumeToMixer(value));
break;
case kVolumeSfx:
- ConfMan.setInt("sfx_volume", convertValueToMixer(value));
+ ConfMan.setInt("sfx_volume", convertVolumeToMixer(value));
break;
case kVolumeSpeech:
- ConfMan.setInt("speech_volume", convertValueToMixer(value));
+ ConfMan.setInt("speech_volume", convertVolumeToMixer(value));
break;
}
@@ -629,16 +627,16 @@ void KyraEngine_v1::setVolume(kVolumeEntry vol, uint8 value) {
uint8 KyraEngine_v1::getVolume(kVolumeEntry vol) {
switch (vol) {
case kVolumeMusic:
- return convertValueFromMixer(ConfMan.getInt("music_volume"));
+ return convertVolumeFromMixer(ConfMan.getInt("music_volume"));
break;
case kVolumeSfx:
- return convertValueFromMixer(ConfMan.getInt("sfx_volume"));
+ return convertVolumeFromMixer(ConfMan.getInt("sfx_volume"));
break;
case kVolumeSpeech:
if (speechEnabled())
- return convertValueFromMixer(ConfMan.getInt("speech_volume"));
+ return convertVolumeFromMixer(ConfMan.getInt("speech_volume"));
else
return 2;
break;
diff --git a/engines/kyra/kyra_v1.h b/engines/kyra/kyra_v1.h
index b45f21dd89..5ece70e3f1 100644
--- a/engines/kyra/kyra_v1.h
+++ b/engines/kyra/kyra_v1.h
@@ -153,7 +153,7 @@ public:
kVolumeSpeech = 2
};
- // volume reaches from 2 to 97
+ // volume reaches per default from 2 to 97
void setVolume(kVolumeEntry vol, uint8 value);
uint8 getVolume(kVolumeEntry vol);
@@ -181,13 +181,16 @@ protected:
// Engine APIs
virtual Common::Error init();
virtual Common::Error go() = 0;
+
virtual Common::Error run() {
Common::Error err;
+ registerDefaultSettings();
err = init();
if (err != Common::kNoError)
return err;
return go();
}
+
virtual ::GUI::Debugger *getDebugger();
virtual bool hasFeature(EngineFeature f) const;
virtual void pauseEngineIntern(bool pause);
@@ -289,6 +292,9 @@ protected:
const int8 *_trackMap;
int _trackMapSize;
+ virtual int convertVolumeToMixer(int value);
+ virtual int convertVolumeFromMixer(int value);
+
// pathfinder
virtual int findWay(int x, int y, int toX, int toY, int *moveTable, int moveTableSize);
int findSubPath(int x, int y, int toX, int toY, int *moveTable, int start, int end);
diff --git a/engines/kyra/lol.cpp b/engines/kyra/lol.cpp
index 3461fa5da9..020e1ea3ea 100644
--- a/engines/kyra/lol.cpp
+++ b/engines/kyra/lol.cpp
@@ -82,7 +82,7 @@ LoLEngine::LoLEngine(OSystem *system, const GameFlags &flags) : KyraEngine_v1(sy
_curTlkFile = -1;
_lastSpeaker = _lastSpeechId = _nextSpeechId = _nextSpeaker = -1;
- memset(_moneyColumnHeight, 0, 5);
+ memset(_moneyColumnHeight, 0, sizeof(_moneyColumnHeight));
_credits = 0;
_itemsInPlay = 0;
@@ -200,7 +200,7 @@ LoLEngine::LoLEngine(OSystem *system, const GameFlags &flags) : KyraEngine_v1(sy
_partyPosX = _partyPosY = 0;
_shpDmX = _shpDmY = _dmScaleW = _dmScaleH = 0;
- _floatingMouseArrowControl = 0;
+ _floatingCursorControl = _currentFloatingCursor = 0;
memset(_activeTim, 0, sizeof(_activeTim));
memset(_openDoorState, 0, sizeof(_openDoorState));
@@ -222,10 +222,6 @@ LoLEngine::LoLEngine(OSystem *system, const GameFlags &flags) : KyraEngine_v1(sy
_preserveEvents = false;
_buttonList1 = _buttonList2 = _buttonList3 = _buttonList4 = _buttonList5 = _buttonList6 = _buttonList7 = _buttonList8 = 0;
- _monsterDifficulty = 1;
- _smoothScrollingEnabled = true;
- _floatingCursorsEnabled = false;
-
memset(_lvlTempData, 0, sizeof(_lvlTempData));
_mapOverlay = 0;
@@ -436,6 +432,7 @@ Common::Error LoLEngine::init() {
_gui = new GUI_LoL(this);
assert(_gui);
+ _gui->initStaticData();
_txt = new TextDisplayer_LoL(this, _screen);
@@ -456,8 +453,6 @@ Common::Error LoLEngine::init() {
if (!_sound->init())
error("Couldn't init sound");
- _speechFlag = speechEnabled() ? 0x48 : 0;
-
_wllVmpMap = new uint8[80];
memset(_wllVmpMap, 0, 80);
_wllShapeMap = new int8[80];
@@ -561,7 +556,7 @@ Common::Error LoLEngine::go() {
// Usually fonts etc. would be setup by the prologue code, if we skip
// the prologue code we need to setup them manually here.
- if (_gameToLoad != -1) {
+ if (_gameToLoad != -1 && action != 3) {
preInit();
_screen->setFont(Screen::FID_9_FNT);
}
@@ -591,8 +586,6 @@ Common::Error LoLEngine::go() {
if (loadGameState(_gameToLoad) != Common::kNoError)
error("Couldn't load game slot %d on startup", _gameToLoad);
_gameToLoad = -1;
- } else if (action == 3) {
- // XXX
}
_screen->_fadeFlag = 3;
@@ -639,6 +632,15 @@ void LoLEngine::loadItemIconShapes() {
_itemIconShapes[i] = _screen->makeShapeCopy(shp, i);
_screen->setMouseCursor(0, 0, _itemIconShapes[0]);
+
+ if (!_gameShapes) {
+ _screen->loadBitmap("GAMESHP.SHP", 3, 3, 0);
+ shp = _screen->getCPagePtr(3);
+ _numGameShapes = READ_LE_UINT16(shp);
+ _gameShapes = new uint8*[_numGameShapes];
+ for (int i = 0; i < _numGameShapes; i++)
+ _gameShapes[i] = _screen->makeShapeCopy(shp, i);
+ }
}
void LoLEngine::setMouseCursorToIcon(int icon) {
@@ -661,6 +663,53 @@ bool LoLEngine::posWithinRect(int mouseX, int mouseY, int x1, int y1, int x2, in
return true;
}
+void LoLEngine::checkFloatingPointerRegions() {
+ if (!_floatingCursorsEnabled)
+ return;
+
+ int t = -1;
+
+ Common::Point p = getMousePos();
+
+ if (!(_updateFlags & 4) & !_floatingCursorControl) {
+ if (posWithinRect(p.x, p.y, 96, 0, 303, 136)) {
+ if (!posWithinRect(p.x, p.y, 128, 16, 271, 119)) {
+ if (posWithinRect(p.x, p.y, 112, 0, 287, 15))
+ t = 0;
+ if (posWithinRect(p.x, p.y, 272, 88, 303, 319))
+ t = 1;
+ if (posWithinRect(p.x, p.y, 112, 110, 287, 135))
+ t = 2;
+ if (posWithinRect(p.x, p.y, 96, 88, 127, 119))
+ t = 3;
+ if (posWithinRect(p.x, p.y, 96, 16, 127, 87))
+ t = 4;
+ if (posWithinRect(p.x, p.y, 272, 16, 303, 87))
+ t = 5;
+
+ if (t < 4) {
+ int d = (_currentDirection + t) & 3;
+ if (!checkBlockPassability(calcNewBlockPosition(_currentBlock, d), d))
+ t = 6;
+ }
+ }
+ }
+ }
+
+ if (t == _currentFloatingCursor)
+ return;
+
+ if (t == -1) {
+ setMouseCursorToItemInHand();
+ } else {
+ static const uint8 floatingPtrX[] = { 7, 13, 7, 0, 0, 15, 7 };
+ static const uint8 floatingPtrY[] = { 0, 7, 12, 7, 6, 6, 7 };
+ _screen->setMouseCursor(floatingPtrX[t], floatingPtrY[t], _gameShapes[10 + t]);
+ }
+
+ _currentFloatingCursor = t;
+}
+
uint8 *LoLEngine::getItemIconShapePtr(int index) {
int ix = _itemProperties[_itemsInPlay[index].itemPropertyIndex].shpIndex;
if (_itemProperties[_itemsInPlay[index].itemPropertyIndex].flags & 0x200)
@@ -714,7 +763,7 @@ int LoLEngine::mainMenu() {
assert(menu);
menu->init(data[dataIndex], MainMenu::Animation());
- int selection = menu->handle(_flags.isTalkie ? (hasSave ? 17 : 6) : (hasSave ? 6 : 18));
+ int selection = menu->handle(_flags.isTalkie ? (hasSave ? 19 : 6) : (hasSave ? 6 : 20));
delete menu;
_screen->setScreenDim(0);
@@ -729,20 +778,20 @@ int LoLEngine::mainMenu() {
void LoLEngine::startup() {
_screen->clearPage(0);
- _screen->loadBitmap("PLAYFLD.CPS", 3, 3, _screen->_currentPalette);
- uint8 *tmpPal = new uint8[0x300];
- memcpy(tmpPal, _screen->_currentPalette, 0x300);
- memset(_screen->_currentPalette, 0x3f, 0x180);
- memcpy(_screen->_currentPalette + 3, tmpPal + 3, 3);
- memset(_screen->_currentPalette + 0x240, 0x3f, 12);
- _screen->generateOverlay(_screen->_currentPalette, _screen->_paletteOverlay1, 1, 96);
- _screen->generateOverlay(_screen->_currentPalette, _screen->_paletteOverlay2, 144, 65);
- memcpy(_screen->_currentPalette, tmpPal, 0x300);
- delete[] tmpPal;
+ Palette &pal = _screen->getPalette(0);
+ _screen->loadBitmap("PLAYFLD.CPS", 3, 3, &pal);
- memset(_screen->getPalette(1), 0, 0x300);
- memset(_screen->getPalette(2), 0, 0x300);
+ _screen->copyPalette(1, 0);
+ pal.fill(0, 1, 0x3F);
+ pal.fill(2, 126, 0x3F);
+ pal.fill(192, 4, 0x3F);
+ _screen->generateOverlay(pal, _screen->_paletteOverlay1, 1, 96);
+ _screen->generateOverlay(pal, _screen->_paletteOverlay2, 144, 65);
+ _screen->copyPalette(0, 1);
+
+ _screen->getPalette(1).clear();
+ _screen->getPalette(2).clear();
loadItemIconShapes();
_screen->setMouseCursor(0, 0, _itemIconShapes[0x85]);
@@ -754,13 +803,6 @@ void LoLEngine::startup() {
for (int i = 0; i < _numItemShapes; i++)
_itemShapes[i] = _screen->makeShapeCopy(shp, i);
- _screen->loadBitmap("GAMESHP.SHP", 3, 3, 0);
- shp = _screen->getCPagePtr(3);
- _numGameShapes = READ_LE_UINT16(shp);
- _gameShapes = new uint8*[_numGameShapes];
- for (int i = 0; i < _numGameShapes; i++)
- _gameShapes[i] = _screen->makeShapeCopy(shp, i);
-
_screen->loadBitmap("THROWN.SHP", 3, 3, 0);
shp = _screen->getCPagePtr(3);
_numThrownShapes = READ_LE_UINT16(shp);
@@ -808,9 +850,6 @@ void LoLEngine::startup() {
_loadSuppFilesFlag = 1;
- _txt->setAnimParameters("<MORE>", 10, 31, 0);
- _txt->setAnimFlag(true);
-
_sound->loadSfxFile("LORESFX");
setMouseCursorToItemInHand();
@@ -822,12 +861,6 @@ void LoLEngine::startupNew() {
_compassDirection = _compassDirectionIndex = -1;
_lastMouseRegion = -1;
-
- /*
- _unk5 = 1;
- _unk6 = 1;
- _unk7 = 1
- _unk8 = 1*/
_currentLevel = 1;
giveCredits(41, 0);
@@ -858,6 +891,12 @@ void LoLEngine::runLoop() {
_flagsTable[73] |= 0x08;
while (!shouldQuit() && _runFlag) {
+ if (_gameToLoad != -1) {
+ if (loadGameState(_gameToLoad) != Common::kNoError)
+ error("Couldn't load game slot %d", _gameToLoad);
+ _gameToLoad = -1;
+ }
+
if (_nextScriptFunc) {
runLevelScript(_nextScriptFunc, 2);
_nextScriptFunc = 0;
@@ -865,7 +904,7 @@ void LoLEngine::runLoop() {
_timer->update();
- //checkFloatingPointerRegions();
+ checkFloatingPointerRegions();
gui_updateInput();
update();
@@ -884,6 +923,55 @@ void LoLEngine::runLoop() {
}
}
+void LoLEngine::registerDefaultSettings() {
+ KyraEngine_v1::registerDefaultSettings();
+
+ // Most settings already have sensible defaults. This one, however, is
+ // specific to the LoL engine.
+ ConfMan.registerDefault("floating_cursors", false);
+ ConfMan.registerDefault("smooth_scrolling", true);
+ ConfMan.registerDefault("monster_difficulty", 1);
+}
+
+void LoLEngine::writeSettings() {
+ ConfMan.setInt("monster_difficulty", _monsterDifficulty);
+ ConfMan.setBool("floating_cursors", _floatingCursorsEnabled);
+ ConfMan.setBool("smooth_scrolling", _smoothScrollingEnabled);
+
+ switch (_lang) {
+ case 1:
+ _flags.lang = Common::FR_FRA;
+ break;
+
+ case 2:
+ _flags.lang = Common::DE_DEU;
+ break;
+
+ case 3:
+ _flags.lang = Common::JA_JPN;
+ break;
+
+ case 0:
+ default:
+ _flags.lang = Common::EN_ANY;
+ }
+
+ if (_flags.lang == _flags.replacedLang && _flags.fanLang != Common::UNK_LANG)
+ _flags.lang = _flags.fanLang;
+
+ ConfMan.set("language", Common::getLanguageCode(_flags.lang));
+
+ KyraEngine_v1::writeSettings();
+}
+
+void LoLEngine::readSettings() {
+ _monsterDifficulty = ConfMan.getInt("monster_difficulty");
+ _smoothScrollingEnabled = ConfMan.getBool("smooth_scrolling");
+ _floatingCursorsEnabled = ConfMan.getBool("floating_cursors");
+
+ KyraEngine_v1::readSettings();
+}
+
void LoLEngine::update() {
updateSequenceBackgroundAnimations();
@@ -1095,7 +1183,7 @@ void LoLEngine::updatePortraitSpeechAnim() {
f -= 5;
f += 7;
- if (_speechFlag) {
+ if (speechEnabled()) {
if (snd_updateCharacterSpeech() == 2)
_updatePortraitSpeechAnimDuration = 2;
else
@@ -1233,7 +1321,7 @@ void LoLEngine::setCharacterMagicOrHitPoints(int charNum, int type, int points,
if (charNum > 3)
return;
-
+
LoLCharacter *c = &_characters[charNum];
if (!(c->flags & 1))
return;
@@ -1421,7 +1509,7 @@ void LoLEngine::gui_specialSceneSuspendControls(int controlMode) {
_specialSceneFlag = 1;
_currentControlMode = controlMode;
calcCharPortraitXpos();
- //checkMouseRegions();
+ checkFloatingPointerRegions();
}
void LoLEngine::gui_specialSceneRestoreControls(int restoreLamp) {
@@ -1431,7 +1519,7 @@ void LoLEngine::gui_specialSceneRestoreControls(int restoreLamp) {
}
_updateFlags &= 0xfffe;
_specialSceneFlag = 0;
- //checkMouseRegions();
+ checkFloatingPointerRegions();
}
void LoLEngine::restoreAfterSceneWindowDialogue(int redraw) {
@@ -1450,7 +1538,7 @@ void LoLEngine::restoreAfterSceneWindowDialogue(int redraw) {
if (_screen->_fadeFlag != 2)
_screen->fadeClearSceneWindow(10);
gui_drawPlayField();
- setPaletteBrightness(_screen->_currentPalette, _brightness, _lampEffect);
+ setPaletteBrightness(_screen->getPalette(0), _brightness, _lampEffect);
_screen->_fadeFlag = 0;
}
@@ -1584,15 +1672,16 @@ void LoLEngine::transformRegion(int x1, int y1, int x2, int y2, int w, int h, in
}
}
-void LoLEngine::setPaletteBrightness(uint8 *palette, int brightness, int modifier) {
- generateBrightnessPalette(palette, _screen->getPalette(1), brightness, modifier);
+void LoLEngine::setPaletteBrightness(const Palette &srcPal, int brightness, int modifier) {
+ generateBrightnessPalette(srcPal, _screen->getPalette(1), brightness, modifier);
_screen->fadePalette(_screen->getPalette(1), 5, 0);
_screen->_fadeFlag = 0;
}
-void LoLEngine::generateBrightnessPalette(uint8 *src, uint8 *dst, int brightness, int modifier) {
- memcpy(dst, src, 0x300);
+void LoLEngine::generateBrightnessPalette(const Palette &src, Palette &dst, int brightness, int modifier) {
+ dst.copy(src);
_screen->loadSpecialColors(dst);
+
brightness = (8 - brightness) << 5;
if (modifier >= 0 && modifier < 8 && (_flagsTable[31] & 0x08)) {
brightness = 256 - ((((modifier & 0xfffe) << 5) * (256 - brightness)) >> 8);
@@ -1606,26 +1695,21 @@ void LoLEngine::generateBrightnessPalette(uint8 *src, uint8 *dst, int brightness
}
}
-void LoLEngine::generateFlashPalette(uint8 *src, uint8 *dst, int colorFlags) {
- if (!src || !dst)
- return;
-
- memcpy(dst, src, 6);
-
- uint8 *s = src + 6;
- uint8 *d = dst + 6;
+void LoLEngine::generateFlashPalette(const Palette &src, Palette &dst, int colorFlags) {
+ dst.copy(src, 0, 2);
for (int i = 2; i < 128; i++) {
for (int ii = 0; ii < 3; ii++) {
- uint8 t = *s++ & 0x3f;
+ uint8 t = src[i * 3 + ii] & 0x3f;
if (colorFlags & (1 << ii))
t += ((0x3f - t) >> 1);
else
t -= (t >> 1);
- *d++ = t;
+ dst[i * 3 + ii] = t;
}
}
- memcpy(d, s, 384);
+
+ dst.copy(src, 128);
}
void LoLEngine::updateSequenceBackgroundAnimations() {
@@ -1790,32 +1874,6 @@ void LoLEngine::delay(uint32 millis, bool doUpdate, bool) {
}
}
-uint8 LoLEngine::getRandomNumberSpecial() {
- uint8 a = _rndSpecial & 0xff;
- uint8 b = (_rndSpecial >> 8) & 0xff;
- uint8 c = (_rndSpecial >> 16) & 0xff;
-
- a >>= 1;
-
- uint as = a & 1;
- uint bs = (b >> 7) ? 0 : 1;
- uint cs = c >> 7;
-
- a >>= 1;
- c = (c << 1) | as;
- b = (b << 1) | cs;
-
- a -= ((_rndSpecial & 0xff) - bs);
- as = a & 1;
- a >>= 1;
-
- a = ((_rndSpecial & 0xff) >> 1) | (as << 7);
-
- _rndSpecial = (_rndSpecial & 0xff000000) | (c << 16) | (b << 8) | a;
-
- return a ^ b;
-}
-
void LoLEngine::updateEnvironmentalSfx(int soundId) {
snd_processEnvironmentalSoundEffect(soundId, _currentBlock);
}
@@ -1919,7 +1977,7 @@ int LoLEngine::castHealOnSingleCharacter(ActiveSpell *a) {
}
int LoLEngine::processMagicSpark(int charNum, int spellLevel) {
- WSAMovie_v2 *mov = new WSAMovie_v2(this, _screen);
+ WSAMovie_v2 *mov = new WSAMovie_v2(this);
_screen->copyPage(0, 12);
mov->open("spark1.wsa", 0, 0);
@@ -2120,25 +2178,24 @@ int LoLEngine::processMagicIce(int charNum, int spellLevel) {
gui_drawScene(0);
_screen->copyPage(0, 12);
- uint8 *tpal = new uint8[768];
- uint8 *swampCol = new uint8[768];
+ Palette tpal(768), swampCol(768);
if (_currentLevel == 11 && !(_flagsTable[52] & 0x04)) {
- uint8 *sc = _screen->_currentPalette;
- uint8 *dc = _screen->getPalette(2);
+ uint8 *sc = _screen->getPalette(0).getData();
+ uint8 *dc = _screen->getPalette(2).getData();
for (int i = 1; i < 768; i++)
SWAP(sc[i], dc[i]);
+
_flagsTable[52] |= 0x04;
static const uint8 freezeTimes[] = { 20, 28, 40, 60 };
setCharacterUpdateEvent(charNum, 8, freezeTimes[spellLevel], 1);
}
- uint8 *sc = _res->fileData("swampice.col", 0);
- memcpy(swampCol, sc, 384);
- uint8 *s = _screen->getPalette(1);
- for (int i = 384; i < 768; i++)
- swampCol[i] = tpal[i] = s[i] & 0x3f;
+ _screen->loadPalette("SWAMPICE.COL", swampCol);
+ tpal.copy(_screen->getPalette(1), 128);
+ swampCol.copy(_screen->getPalette(1), 128);
+ Palette &s = _screen->getPalette(1);
for (int i = 1; i < 128; i++) {
tpal[i * 3] = 0;
uint16 v = (s[i * 3] + s[i * 3 + 1] + s[i * 3 + 2]) / 3;
@@ -2148,24 +2205,25 @@ int LoLEngine::processMagicIce(int charNum, int spellLevel) {
if (tpal[i * 3 + 2] > 0x3f)
tpal[i * 3 + 2] = 0x3f;
}
+
generateBrightnessPalette(tpal, tpal, _brightness, _lampEffect);
generateBrightnessPalette(swampCol, swampCol, _brightness, _lampEffect);
swampCol[0] = swampCol[1] = swampCol[2] = tpal[0] = tpal[1] = tpal[2] = 0;
- generateBrightnessPalette(_screen->_currentPalette, s, _brightness, _lampEffect);
+ generateBrightnessPalette(_screen->getPalette(0), s, _brightness, _lampEffect);
int sX = 112;
int sY = 0;
- WSAMovie_v2 *mov = new WSAMovie_v2(this, _screen);
+ WSAMovie_v2 *mov = new WSAMovie_v2(this);
if (spellLevel == 0) {
sX = 0;
} if (spellLevel == 1 || spellLevel == 2) {
- mov->open("snow.wsa", 1, 0);
+ mov->open("SNOW.WSA", 1, 0);
if (!mov->opened())
error("Ice: Unable to load snow.wsa");
} if (spellLevel == 3) {
- mov->open("ice.wsa", 1, 0);
+ mov->open("ICE.WSA", 1, 0);
if (!mov->opened())
error("Ice: Unable to load ice.wsa");
sX = 136;
@@ -2174,9 +2232,9 @@ int LoLEngine::processMagicIce(int charNum, int spellLevel) {
snd_playSoundEffect(71, -1);
- playSpellAnimation(0, 0, 0, 2, 0, 0, 0, s, tpal, 40, false);
+ playSpellAnimation(0, 0, 0, 2, 0, 0, 0, s.getData(), tpal.getData(), 40, false);
- _screen->fadePaletteStep(s, tpal, _system->getMillis(), _tickLength);
+ _screen->fadePaletteStep(s.getData(), tpal.getData(), _system->getMillis(), _tickLength);
if (mov->opened()) {
int r = true;
if (spellLevel > 2) {
@@ -2241,22 +2299,19 @@ int LoLEngine::processMagicIce(int charNum, int spellLevel) {
enableSysTimer(2);
if (_currentLevel != 11)
- generateBrightnessPalette(_screen->_currentPalette, swampCol, _brightness, _lampEffect);
+ generateBrightnessPalette(_screen->getPalette(0), swampCol, _brightness, _lampEffect);
- playSpellAnimation(0, 0, 0, 2, 0, 0, 0, tpal, swampCol, 40, 0);
+ playSpellAnimation(0, 0, 0, 2, 0, 0, 0, tpal.getData(), swampCol.getData(), 40, 0);
- _screen->fadePaletteStep(tpal, swampCol, _system->getMillis(), _tickLength);
+ _screen->fadePaletteStep(tpal.getData(), swampCol.getData(), _system->getMillis(), _tickLength);
if (breakWall)
- breakIceWall(tpal, swampCol);
+ breakIceWall(tpal.getData(), swampCol.getData());
static const uint8 freezeTime[] = { 20, 28, 40, 60 };
if (_currentLevel == 11)
setCharacterUpdateEvent(charNum, 8, freezeTime[spellLevel], 1);
- delete[] sc;
- delete[] swampCol;
- delete[] tpal;
_screen->setCurPage(cp);
return 1;
}
@@ -2417,7 +2472,7 @@ int LoLEngine::processMagicHandOfFate(int spellLevel) {
int cp = _screen->setCurPage(2);
_screen->copyPage(0, 12);
- WSAMovie_v2 *mov = new WSAMovie_v2(this, _screen);
+ WSAMovie_v2 *mov = new WSAMovie_v2(this);
mov->open("hand.wsa", 1, 0);
if (!mov->opened())
error("Hand: Unable to load HAND.WSA");
@@ -2495,8 +2550,8 @@ int LoLEngine::processMagicHandOfFate(int spellLevel) {
int LoLEngine::processMagicMistOfDoom(int charNum, int spellLevel) {
static const uint8 mistDamage[] = { 30, 70, 110, 200 };
-
- _envSfxUseQueue = true;
+
+ _envSfxUseQueue = true;
inflictMagicalDamageForBlock(calcNewBlockPosition(_currentBlock, _currentDirection), charNum, mistDamage[spellLevel], 0x80);
_envSfxUseQueue = false;
@@ -2509,7 +2564,7 @@ int LoLEngine::processMagicMistOfDoom(int charNum, int spellLevel) {
char wsafile[13];
snprintf(wsafile, 13, "mists%0d.wsa", spellLevel + 1);
- WSAMovie_v2 *mov = new WSAMovie_v2(this, _screen);
+ WSAMovie_v2 *mov = new WSAMovie_v2(this);
mov->open(wsafile, 1, 0);
if (!mov->opened())
error("Mist: Unable to load mists.wsa");
@@ -2541,7 +2596,7 @@ int LoLEngine::processMagicLightning(int charNum, int spellLevel) {
char wsafile[13];
snprintf(wsafile, 13, "litning%d.wsa", spellLevel + 1);
- WSAMovie_v2 *mov = new WSAMovie_v2(this, _screen);
+ WSAMovie_v2 *mov = new WSAMovie_v2(this);
mov->open(wsafile, 1, 0);
if (!mov->opened())
error("Litning: Unable to load litning.wsa");
@@ -2570,7 +2625,7 @@ int LoLEngine::processMagicFog() {
int cp = _screen->setCurPage(2);
_screen->copyPage(0, 12);
- WSAMovie_v2 *mov = new WSAMovie_v2(this, _screen);
+ WSAMovie_v2 *mov = new WSAMovie_v2(this);
int numFrames = mov->open("fog.wsa", 0, 0);
if (!mov->opened())
error("Fog: Unable to load fog.wsa");
@@ -2646,7 +2701,7 @@ int LoLEngine::processMagicSwarm(int charNum, int damage) {
_monsters[destIds[i]].fightCurTick = destTicks[i];
}
- WSAMovie_v2 *mov = new WSAMovie_v2(this, _screen);
+ WSAMovie_v2 *mov = new WSAMovie_v2(this);
mov->open("swarm.wsa", 0, 0);
if (!mov->opened())
@@ -2671,7 +2726,7 @@ int LoLEngine::processMagicSwarm(int charNum, int damage) {
int LoLEngine::processMagicVaelansCube() {
uint8 *tmpPal1 = new uint8[768];
uint8 *tmpPal2 = new uint8[768];
- uint8 *sp1 = _screen->getPalette(1);
+ uint8 *sp1 = _screen->getPalette(1).getData();
memcpy(tmpPal1, sp1, 768);
memcpy(tmpPal2, sp1, 768);
@@ -2734,7 +2789,7 @@ int LoLEngine::processMagicGuardian(int charNum) {
_screen->copyPage(0, 2);
_screen->copyPage(2, 12);
- WSAMovie_v2 *mov = new WSAMovie_v2(this, _screen);
+ WSAMovie_v2 *mov = new WSAMovie_v2(this);
mov->open("guardian.wsa", 0, 0);
if (!mov->opened())
error("Guardian: Unable to load guardian.wsa");
@@ -2742,7 +2797,7 @@ int LoLEngine::processMagicGuardian(int charNum) {
playSpellAnimation(mov, 0, 37, 2, 112, 0, 0, 0, 0, 0, false);
_screen->copyPage(2, 12);
-
+
uint16 bl = calcNewBlockPosition(_currentBlock, _currentDirection);
int res = (_levelBlockProperties[bl].assignedObjects & 0x8000) ? 1 : 0;
inflictMagicalDamageForBlock(bl, charNum, 200, 0x80);
@@ -2754,7 +2809,7 @@ int LoLEngine::processMagicGuardian(int charNum) {
_screen->copyPage(2, 12);
snd_playSoundEffect(176, -1);
playSpellAnimation(mov, 38, 48, 8, 112, 0, 0, 0, 0, 0, false);
-
+
mov->close();
delete mov;
@@ -2771,20 +2826,22 @@ void LoLEngine::callbackProcessMagicSwarm(WSAMovie_v2 *mov, int x, int y) {
}
void LoLEngine::callbackProcessMagicLightning(WSAMovie_v2 *mov, int x, int y) {
- uint8 *tpal = new uint8[768];
if (_lightningDiv == 2)
shakeScene(1, 2, 3, 0);
- uint8 *p1 = _screen->getPalette(1);
+ const Palette &p1 = _screen->getPalette(1);
if (_lightningSfxFrame % _lightningDiv) {
_screen->setScreenPalette(p1);
} else {
- memcpy(tpal, p1, 768);
+ Palette tpal(p1.getNumColors());
+ tpal.copy(p1);
+
for (int i = 6; i < 384; i++) {
uint16 v = (tpal[i] * 120) / 64;
tpal[i] = (v < 64) ? v : 63;
}
+
_screen->setScreenPalette(tpal);
}
@@ -2799,7 +2856,55 @@ void LoLEngine::callbackProcessMagicLightning(WSAMovie_v2 *mov, int x, int y) {
}
_lightningSfxFrame++;
- delete[] tpal;
+}
+
+void LoLEngine::drinkBezelCup(int numUses, int charNum) {
+ int cp = _screen->setCurPage(2);
+ snd_playSoundEffect(73, -1);
+
+ WSAMovie_v2 *mov = new WSAMovie_v2(this);
+ mov->open("bezel.wsa", 0, 0);
+ if (!mov->opened())
+ error("Bezel: Unable to load bezel.wsa");
+
+ int x = _activeCharsXpos[charNum] - 11;
+ int y = 124;
+ int w = mov->width();
+ int h = mov->height();
+
+ _screen->copyRegion(x, y, 0, 0, w, h, 0, 2, Screen::CR_NO_P_CHECK);
+
+ static const uint8 bezelAnimData[] = { 0, 26, 20, 27, 61, 55, 62, 92, 86, 93, 131, 125 };
+ int frm = bezelAnimData[numUses * 3];
+ int hpDiff = _characters[charNum].hitPointsMax - _characters[charNum].hitPointsCur;
+ uint16 step = 0;
+
+ do {
+ step = (step & 0xff) + (hpDiff * 256) / (bezelAnimData[numUses * 3 + 2]);
+ increaseCharacterHitpoints(charNum, step / 256, true);
+ gui_drawCharPortraitWithStats(charNum);
+
+ uint32 etime = _system->getMillis() + 4 * _tickLength;
+
+ _screen->copyRegion(0, 0, x, y, w, h, 2, 2, Screen::CR_NO_P_CHECK);
+ mov->displayFrame(frm, 2, x, y, 0x5000, _trueLightTable1, _trueLightTable2);
+ _screen->copyRegion(x, y, x, y, w, h, 2, 0, Screen::CR_NO_P_CHECK);
+ _screen->updateScreen();
+
+ delayUntil(etime);
+ } while (++frm < bezelAnimData[numUses * 3 + 1]);
+
+ _characters[charNum].hitPointsCur = _characters[charNum].hitPointsMax;
+ _screen->copyRegion(0, 0, x, y, w, h, 2, 2, Screen::CR_NO_P_CHECK);
+ removeCharacterEffects(&_characters[charNum], 4, 4);
+ gui_drawCharPortraitWithStats(charNum);
+ _screen->copyRegion(x, y, x, y, w, h, 2, 0, Screen::CR_NO_P_CHECK);
+ _screen->updateScreen();
+
+ mov->close();
+ delete mov;
+
+ _screen->setCurPage(cp);
}
void LoLEngine::addSpellToScroll(int spell, int charNum) {
@@ -2871,7 +2976,7 @@ void LoLEngine::transferSpellToScollAnimation(int charNum, int spell, int slot)
snd_playSoundEffect(_updateSpellBookAnimData[(spell << 2) + 3], -1);
snd_playSoundEffect(95, -1);
- WSAMovie_v2 *mov = new WSAMovie_v2(this, _screen);
+ WSAMovie_v2 *mov = new WSAMovie_v2(this);
mov->open("getspell.wsa", 0, 0);
if (!mov->opened())
@@ -3282,6 +3387,52 @@ int LoLEngine::calcInflictableDamagePerItem(int16 attacker, int16 target, uint16
}
void LoLEngine::checkForPartyDeath() {
+ Button b;
+ b.data0Val2 = b.data1Val2 = b.data2Val2 = 0xfe;
+ b.data0Val3 = b.data1Val3 = b.data2Val3 = 0x01;
+
+ for (int i = 0; i < 4; i++) {
+ if (!(_characters[i].flags & 1) || _characters[i].hitPointsCur <= 0)
+ continue;
+ return;
+ }
+
+ if (_weaponsDisabled)
+ clickedExitCharInventory(&b);
+
+ gui_drawAllCharPortraitsWithStats();
+
+ if (_partyDamageFlags & 0x40) {
+ _screen->fadeToBlack(40);
+ for (int i = 0; i < 4; i++) {
+ if (_characters[i].flags & 1)
+ increaseCharacterHitpoints(i, 1, true);
+ }
+ gui_drawAllCharPortraitsWithStats();
+ _screen->fadeToPalette1(40);
+
+ } else {
+ _screen->fadeClearSceneWindow(10);
+ restoreAfterSpecialScene(0, 1, 1, 0);
+
+ snd_playTrack(325);
+ updatePortraits();
+ initTextFading(0, 1);
+ setMouseCursorToIcon(0);
+ _updateFlags |= 4;
+ setLampMode(true);
+ disableSysTimer(2);
+
+ _gui->runMenu(_gui->_deathMenu);
+
+ setMouseCursorToItemInHand();
+ _updateFlags &= 0xfffb;
+ resetLampStatus();
+
+ gui_enableDefaultPlayfieldButtons();
+ enableSysTimer(2);
+ updateDrawPage2();
+ }
}
void LoLEngine::applyMonsterAttackSkill(MonsterInPlay *monster, int16 target, int16 damage) {
@@ -3499,16 +3650,16 @@ void LoLEngine::restoreSwampPalette() {
if (_currentLevel != 11)
return;
- uint8 *s = _screen->getPalette(2);
- uint8 *d = _screen->_currentPalette;
- uint8 *d2 = _screen->getPalette(1);
+ uint8 *s = _screen->getPalette(2).getData();
+ uint8 *d = _screen->getPalette(0).getData();
+ uint8 *d2 = _screen->getPalette(1).getData();
for (int i = 1; i < 768; i++)
SWAP(s[i], d[i]);
- generateBrightnessPalette(d, d2, _brightness, _lampEffect);
- _screen->loadSpecialColors(s);
- _screen->loadSpecialColors(d2);
+ generateBrightnessPalette(_screen->getPalette(0), _screen->getPalette(1), _brightness, _lampEffect);
+ _screen->loadSpecialColors(_screen->getPalette(2));
+ _screen->loadSpecialColors(_screen->getPalette(1));
playSpellAnimation(0, 0, 0, 2, 0, 0, 0, s, d2, 40, 0);
}
@@ -3529,7 +3680,7 @@ void LoLEngine::launchMagicViper() {
_screen->copyPage(0, 12);
snd_playSoundEffect(148, -1);
- WSAMovie_v2 *mov = new WSAMovie_v2(this, _screen);
+ WSAMovie_v2 *mov = new WSAMovie_v2(this);
int numFrames = mov->open("viper.wsa", 1, 0);
if (!mov->opened())
error("Viper: Unable to load viper.wsa");
@@ -3579,7 +3730,7 @@ void LoLEngine::breakIceWall(uint8 *pal1, uint8 *pal2) {
gui_drawScene(2);
_screen->copyPage(2, 10);
- WSAMovie_v2 *mov = new WSAMovie_v2(this, _screen);
+ WSAMovie_v2 *mov = new WSAMovie_v2(this);
int numFrames = mov->open("shatter.wsa", 1, 0);
if (!mov->opened())
error("Shatter: Unable to load shatter.wsa");
@@ -3681,7 +3832,7 @@ void LoLEngine::displayAutomap() {
uint8 *tmpWll = new uint8[80];
memcpy(tmpWll, _wllBuffer4, 80);
- _screen->loadBitmap("parch.cps", 2, 2, _screen->getPalette(3));
+ _screen->loadBitmap("parch.cps", 2, 2, &_screen->getPalette(3));
_screen->loadBitmap("autobut.shp", 3, 5, 0);
const uint8 *shp = _screen->getCPagePtr(5);
@@ -3848,12 +3999,17 @@ void LoLEngine::loadMapLegendData(int level) {
}
void LoLEngine::drawMapPage(int pageNum) {
+ // WORKAROUND for French version. The Text does not always properly fit the screen there.
+ int8 textOffset = (_lang == 1) ? -2 : 0;
+
for (int i = 0; i < 2; i++) {
- _screen->loadBitmap("parch.cps", pageNum, pageNum, _screen->getPalette(3));
+ _screen->loadBitmap("parch.cps", pageNum, pageNum, &_screen->getPalette(3));
+ if (_lang == 1)
+ _screen->copyRegion(236, 16, 236 + textOffset, 16, -textOffset, 1, pageNum, pageNum, Screen::CR_NO_P_CHECK);
int cp = _screen->setCurPage(pageNum);
Screen::FontId of = _screen->setFont(Screen::FID_9_FNT);
- _screen->printText(getLangString(_autoMapStrings[_currentMapLevel]), 236, 8, 1, 0);
+ _screen->printText(getLangString(_autoMapStrings[_currentMapLevel]), 236 + textOffset, 8, 1, 0);
uint16 blX = mapGetStartPosX();
uint16 bl = (mapGetStartPosY() << 5) + blX;
@@ -3932,7 +4088,7 @@ void LoLEngine::drawMapPage(int pageNum) {
if (l[2] == 0xffff)
continue;
- printMapText(l[2], 244, (tY << 3) + 22);
+ printMapText(l[2], 244 + textOffset, (tY << 3) + 22);
if (l[5] == 0xffff) {
tY++;
@@ -3942,7 +4098,7 @@ void LoLEngine::drawMapPage(int pageNum) {
uint16 cbl2 = l[3] + (l[4] << 5);
_levelBlockProperties[cbl2].flags |= 7;
_screen->drawShape(2, _automapShapes[l[5] << 2], (l[3] - sx) * 7 + _automapTopLeftX - 3, (l[4] - sy) * 6 + _automapTopLeftY - 3, 0, 0);
- _screen->drawShape(2, _automapShapes[l[5] << 2], 231, (tY << 3) + 19, 0, 0);
+ _screen->drawShape(2, _automapShapes[l[5] << 2], 231 + textOffset, (tY << 3) + 19, 0, 0);
tY++;
}
@@ -3951,9 +4107,9 @@ void LoLEngine::drawMapPage(int pageNum) {
for (int ii = 0; ii < 11; ii++) {
if (!_defaultLegendData[ii].enable)
continue;
- _screen->copyBlockAndApplyOverlay(_screen->_curPage, 235, (tY << 3) + 21, _screen->_curPage, 235, (tY << 3) + 21, 7, 6, 0, _mapOverlay);
- _screen->drawShape(_screen->_curPage, _automapShapes[_defaultLegendData[ii].shapeIndex << 2], 232, (tY << 3) + 18 + _defaultLegendData[ii].x, 0, 0);
- printMapText(_defaultLegendData[ii].stringId, 244, (tY << 3) + 22);
+ _screen->copyBlockAndApplyOverlay(_screen->_curPage, 235, (tY << 3) + 21, _screen->_curPage, 235 + textOffset, (tY << 3) + 21, 7, 6, 0, _mapOverlay);
+ _screen->drawShape(_screen->_curPage, _automapShapes[_defaultLegendData[ii].shapeIndex << 2], 232 + textOffset, (tY << 3) + 18 + _defaultLegendData[ii].x, 0, 0);
+ printMapText(_defaultLegendData[ii].stringId, 244 + textOffset, (tY << 3) + 22);
tY++;
}
diff --git a/engines/kyra/lol.h b/engines/kyra/lol.h
index 45795a7cab..12000c31fa 100644
--- a/engines/kyra/lol.h
+++ b/engines/kyra/lol.h
@@ -307,6 +307,7 @@ public:
Screen *screen();
GUI *gui() const;
+
private:
Screen_LoL *_screen;
GUI_LoL *_gui;
@@ -326,6 +327,10 @@ private:
void startup();
void startupNew();
+ void registerDefaultSettings();
+ void writeSettings();
+ void readSettings();
+
// options
int _monsterDifficulty;
bool _smoothScrollingEnabled;
@@ -342,7 +347,9 @@ private:
uint8 *getItemIconShapePtr(int index);
bool posWithinRect(int mouseX, int mouseY, int x1, int y1, int x2, int y2);
- int _floatingMouseArrowControl;
+ void checkFloatingPointerRegions();
+ int _floatingCursorControl;
+ int _currentFloatingCursor;
// intro + character selection
int processPrologue();
@@ -441,6 +448,9 @@ private:
int _timer3Para;
// sound
+ int convertVolumeToMixer(int value);
+ int convertVolumeFromMixer(int value);
+
void loadTalkFile(int index);
void snd_playVoiceFile(int track) {}
bool snd_playCharacterSpeech(int id, int8 speaker, int);
@@ -473,7 +483,6 @@ private:
Common::List<Audio::AudioStream*> _speechList;
int _curTlkFile;
- int _speechFlag;
char **_ingameSoundList;
int _ingameSoundListSize;
@@ -772,11 +781,12 @@ private:
int olol_getNextActiveCharacter(EMCState *script);
int olol_paralyzePoisonCharacter(EMCState *script);
int olol_drawCharPortrait(EMCState *script);
- int olol_removeInventoryItem(EMCState *script);
+ int olol_removeInventoryItem(EMCState *script);
int olol_getAnimationLastPart(EMCState *script);
int olol_assignSpecialGuiShape(EMCState *script);
int olol_findInventoryItem(EMCState *script);
int olol_restoreFadePalette(EMCState *script);
+ int olol_drinkBezelCup(EMCState *script);
int olol_changeItemTypeOrFlag(EMCState *script);
int olol_placeInventoryItemInHand(EMCState *script);
int olol_castSpell(EMCState *script);
@@ -862,9 +872,9 @@ private:
void toggleSelectedCharacterFrame(bool mode);
void fadeText();
void transformRegion(int x1, int y1, int x2, int y2, int w, int h, int srcPage, int dstPage);
- void setPaletteBrightness(uint8 *palette, int brightness, int modifier);
- void generateBrightnessPalette(uint8 *src, uint8 *dst, int brightness, int modifier);
- void generateFlashPalette(uint8 *src, uint8 *dst, int colorFlags);
+ void setPaletteBrightness(const Palette &srcPal, int brightness, int modifier);
+ void generateBrightnessPalette(const Palette &src, Palette &dst, int brightness, int modifier);
+ void generateFlashPalette(const Palette &src, Palette &dst, int colorFlags);
void updateSequenceBackgroundAnimations();
bool _dialogueField;
@@ -905,7 +915,7 @@ private:
void setCharacterMagicOrHitPoints(int charNum, int type, int points, int mode);
void increaseExperience(int charNum, int skill, uint32 points);
- void increaseCharacterHitpoints(int charNum, int points, bool unk);
+ void increaseCharacterHitpoints(int charNum, int points, bool ignoreDeath);
LoLCharacter *_characters;
uint16 _activeCharsXpos[3];
@@ -1303,7 +1313,6 @@ private:
// misc
void delay(uint32 millis, bool doUpdate = false, bool isMainLoop = false);
- uint8 getRandomNumberSpecial();
uint8 _compassBroken;
uint8 _drainMagic;
@@ -1349,6 +1358,8 @@ private:
void callbackProcessMagicSwarm(WSAMovie_v2 *mov, int x, int y);
void callbackProcessMagicLightning(WSAMovie_v2 *mov, int x, int y);
+ void drinkBezelCup(int a, int charNum);
+
void addSpellToScroll(int spell, int charNum);
void transferSpellToScollAnimation(int charNum, int spell, int slot);
diff --git a/engines/kyra/saveload.cpp b/engines/kyra/saveload.cpp
index 79665068f6..ecd6bbe450 100644
--- a/engines/kyra/saveload.cpp
+++ b/engines/kyra/saveload.cpp
@@ -29,6 +29,7 @@
#include "graphics/thumbnail.h"
#include "kyra/kyra_v1.h"
+#include "kyra/util.h"
#define CURRENT_SAVE_VERSION 16
@@ -65,6 +66,8 @@ KyraEngine_v1::kReadSaveHeaderError KyraEngine_v1::readSaveHeader(Common::Seekab
in->read(descriptionBuffer, descriptionSize[i]);
descriptionBuffer[descriptionSize[i]] = 0;
+ Util::convertDOSToISO(descriptionBuffer);
+
type = in->readUint32BE();
header.version = in->readUint16LE();
if (type == MKID_BE('MBL3') && header.version == 100) {
diff --git a/engines/kyra/scene_hof.cpp b/engines/kyra/scene_hof.cpp
index fed7877c0b..2d15af92fd 100644
--- a/engines/kyra/scene_hof.cpp
+++ b/engines/kyra/scene_hof.cpp
@@ -330,9 +330,6 @@ int KyraEngine_HoF::trySceneChange(int *moveTable, int unk1, int updateChar) {
updateCharacterAnim(0);
refreshAnimObjectsIfNeed();
- if (!changedScene && !_unk4) {
- //XXX
- }
return changedScene;
}
@@ -396,14 +393,14 @@ void KyraEngine_HoF::unloadScene() {
void KyraEngine_HoF::loadScenePal() {
uint16 sceneId = _mainCharacter.sceneId;
- memcpy(_screen->getPalette(1), _screen->getPalette(0), 768);
+ _screen->copyPalette(1, 0);
char filename[14];
strcpy(filename, _sceneList[sceneId].filename1);
strcat(filename, ".COL");
_screen->loadBitmap(filename, 3, 3, 0);
- memcpy(_screen->getPalette(1), _screen->getCPagePtr(3), 384);
- memset(_screen->getPalette(1), 0, 3);
+ _screen->getPalette(1).copy(_screen->getCPagePtr(3), 0, 128);
+ _screen->getPalette(1).fill(0, 1, 0);
memcpy(_scenePal, _screen->getCPagePtr(3)+336, 432);
}
@@ -669,7 +666,7 @@ void KyraEngine_HoF::initSceneScreen(int unk1) {
}
if (_noScriptEnter) {
- memset(_screen->getPalette(0), 0, 384);
+ _screen->getPalette(0).fill(0, 128, 0);
_screen->setScreenPalette(_screen->getPalette(0));
}
@@ -677,7 +674,7 @@ void KyraEngine_HoF::initSceneScreen(int unk1) {
if (_noScriptEnter) {
_screen->setScreenPalette(_screen->getPalette(1));
- memcpy(_screen->getPalette(0), _screen->getPalette(1), 384);
+ _screen->getPalette(0).copy(_screen->getPalette(1), 0, 128);
}
updateCharPal(0);
@@ -695,10 +692,7 @@ void KyraEngine_HoF::freeSceneShapePtrs() {
}
void KyraEngine_HoF::fadeScenePal(int srcIndex, int delayTime) {
- uint8 *dst = _screen->getPalette(0) + 336;
- const uint8 *src = _scenePal + (srcIndex << 4)*3;
- memcpy(dst, src, 48);
-
+ _screen->getPalette(0).copy(_scenePal, srcIndex << 4, 16, 112);
_screen->fadePalette(_screen->getPalette(0), delayTime, &_updateFunctor);
}
diff --git a/engines/kyra/scene_lok.cpp b/engines/kyra/scene_lok.cpp
index 345998e40e..fc1ca41189 100644
--- a/engines/kyra/scene_lok.cpp
+++ b/engines/kyra/scene_lok.cpp
@@ -406,7 +406,7 @@ void KyraEngine_LoK::startSceneScript(int brandonAlive) {
_screen->clearPage(3);
_res->exists(fileNameBuffer, true);
// FIXME: check this hack for amiga version
- _screen->loadBitmap(fileNameBuffer, 3, 3, (_flags.platform == Common::kPlatformAmiga ? _screen->getPalette(0) : 0));
+ _screen->loadBitmap(fileNameBuffer, 3, 3, (_flags.platform == Common::kPlatformAmiga ? &_screen->getPalette(0) : 0));
_sprites->loadSceneShapes();
_exitListPtr = 0;
@@ -770,7 +770,7 @@ void KyraEngine_LoK::initSceneObjectList(int brandonAlive) {
void KyraEngine_LoK::initSceneScreen(int brandonAlive) {
if (_flags.platform == Common::kPlatformAmiga) {
if (_unkScreenVar1 && !queryGameFlag(0xF0)) {
- memset(_screen->getPalette(2), 0, 32*3);
+ _screen->getPalette(2).clear();
if (_currentCharacter->sceneId != 117 || !queryGameFlag(0xB3))
_screen->setScreenPalette(_screen->getPalette(2));
}
@@ -782,10 +782,10 @@ void KyraEngine_LoK::initSceneScreen(int brandonAlive) {
if (_unkScreenVar1 && !queryGameFlag(0xA0)) {
if (_currentCharacter->sceneId == 45 && _paletteChanged)
- memcpy(_screen->getPalette(0) + 12*3, _screen->getPalette(4) + 12*3, 2);
+ _screen->getPalette(0).copy(_screen->getPalette(4), 12, 1);
if (_currentCharacter->sceneId >= 229 && _currentCharacter->sceneId <= 245 && (_brandonStatusBit & 1))
- memcpy(_screen->getPalette(0), _screen->getPalette(0) + 320*3, 64);
+ _screen->copyPalette(0, 10);
_screen->setScreenPalette(_screen->getPalette(0));
}
@@ -807,10 +807,10 @@ void KyraEngine_LoK::initSceneScreen(int brandonAlive) {
if (_unkScreenVar1 && _paletteChanged) {
if (!queryGameFlag(0xA0)) {
- memcpy(_screen->getPalette(0) + 684, _screen->getPalette(1) + 684, 60);
+ _screen->getPalette(0).copy(_screen->getPalette(1), 228, 20);
_screen->setScreenPalette(_screen->getPalette(0));
} else {
- memset(_screen->getPalette(0), 0, 768);
+ _screen->getPalette(0).clear();
}
}
}
diff --git a/engines/kyra/scene_lol.cpp b/engines/kyra/scene_lol.cpp
index 0236e4fa7d..945495517f 100644
--- a/engines/kyra/scene_lol.cpp
+++ b/engines/kyra/scene_lol.cpp
@@ -86,7 +86,7 @@ void LoLEngine::loadLevel(int index) {
addLevelItems();
deleteMonstersFromBlock(_currentBlock);
- _screen->generateGrayOverlay(_screen->_currentPalette, _screen->_grayOverlay, 32, 16, 0, 0, 128, true);
+ _screen->generateGrayOverlay(_screen->getPalette(0), _screen->_grayOverlay, 32, 16, 0, 0, 128, true);
_sceneDefaultUpdate = 0;
if (_screen->_fadeFlag == 3)
@@ -94,7 +94,7 @@ void LoLEngine::loadLevel(int index) {
gui_drawPlayField();
- setPaletteBrightness(_screen->_currentPalette, _brightness, _lampEffect);
+ setPaletteBrightness(_screen->getPalette(0), _brightness, _lampEffect);
setMouseCursorToItemInHand();
snd_playTrack(_curMusicTheme);
@@ -379,28 +379,24 @@ void LoLEngine::loadLevelGraphics(const char *file, int specialColor, int weight
v += 128;
if (_lastOverridePalFilePtr) {
- uint8 *tpal = _res->fileData(_lastOverridePalFilePtr, 0);
- memcpy(_screen->_currentPalette, tpal, 384);
- delete[] tpal;
+ _res->loadFileToBuf(_lastOverridePalFilePtr, _screen->getPalette(0).getData(), 384);
} else {
- memcpy(_screen->_currentPalette, v, 384);
+ _screen->getPalette(0).copy(v, 0, 128);
}
v += 384;
/*uint8 tmpPal = new uint8[384];
- memcpy(tmpPal, _screen->_currentPalette + 384, 384);
- memset(_screen->_currentPalette + 384, 0xff, 384);
- memcpy(_screen->_currentPalette + 384, tmpPal, 384);*/
+ memcpy(tmpPal, _screen->getPalette(0) + 384, 384);
+ memset(_screen->getPalette(0) + 384, 0xff, 384);
+ memcpy(_screen->getPalette(0) + 384, tmpPal, 384);*/
if (_currentLevel == 11) {
- uint8 *swampPal = _res->fileData("SWAMPICE.COL", 0);
- memcpy(_screen->getPalette(2), swampPal, 384);
- memcpy(_screen->getPalette(2) + 384, _screen->_currentPalette + 384, 384);
- delete[] swampPal;
+ _screen->loadPalette("SWAMPICE.COL", _screen->getPalette(2));
+ _screen->getPalette(2).copy(_screen->getPalette(0), 128);
if (_flagsTable[52] & 0x04) {
- uint8 *pal0 = _screen->_currentPalette;
- uint8 *pal2 = _screen->getPalette(2);
+ uint8 *pal0 = _screen->getPalette(0).getData();
+ uint8 *pal2 = _screen->getPalette(2).getData();
for (int i = 1; i < 768; i++)
SWAP(pal0[i], pal2[i]);
}
@@ -427,7 +423,7 @@ void LoLEngine::loadLevelGraphics(const char *file, int specialColor, int weight
for (int i = 0; i < 7; i++) {
weight = 100 - (i * _lastSpecialColorWeight);
weight = (weight > 0) ? (weight * 255) / 100 : 0;
- _screen->generateLevelOverlay(_screen->_currentPalette, _screen->getLevelOverlay(i), _lastSpecialColor, weight);
+ _screen->generateLevelOverlay(_screen->getPalette(0), _screen->getLevelOverlay(i), _lastSpecialColor, weight);
for (int ii = 0; ii < 128; ii++) {
if (_screen->getLevelOverlay(i)[ii] == 255)
@@ -442,7 +438,7 @@ void LoLEngine::loadLevelGraphics(const char *file, int specialColor, int weight
_screen->getLevelOverlay(7)[i] = i & 0xff;
_loadSuppFilesFlag = 0;
- generateBrightnessPalette(_screen->_currentPalette, _screen->getPalette(1), _brightness, _lampEffect);
+ generateBrightnessPalette(_screen->getPalette(0), _screen->getPalette(1), _brightness, _lampEffect);
char tname[13];
snprintf(tname, sizeof(tname), "LEVEL%.02d.TLC", _currentLevel);
@@ -548,14 +544,14 @@ void LoLEngine::updateLampStatus() {
if (!_brightness || !_lampOilStatus) {
newLampEffect = 8;
if (newLampEffect != _lampEffect && _screen->_fadeFlag == 0)
- setPaletteBrightness(_screen->_currentPalette, _brightness, newLampEffect);
+ setPaletteBrightness(_screen->getPalette(0), _brightness, newLampEffect);
} else {
tmpOilStatus = (_lampOilStatus < 100) ? _lampOilStatus : 100;
newLampEffect = (3 - ((tmpOilStatus - 1) / 25)) << 1;
if (_lampEffect == -1) {
if (_screen->_fadeFlag == 0)
- setPaletteBrightness(_screen->_currentPalette, _brightness, newLampEffect);
+ setPaletteBrightness(_screen->getPalette(0), _brightness, newLampEffect);
_lampStatusTimer = _system->getMillis() + (10 + _rnd.getRandomNumberRng(1, 30)) * _tickLength;
} else {
if ((_lampEffect & 0xfe) == (newLampEffect & 0xfe)) {
@@ -567,7 +563,7 @@ void LoLEngine::updateLampStatus() {
}
} else {
if (_screen->_fadeFlag == 0)
- setPaletteBrightness(_screen->_currentPalette, _lampEffect, newLampEffect);
+ setPaletteBrightness(_screen->getPalette(0), _lampEffect, newLampEffect);
}
}
}
@@ -604,7 +600,7 @@ void LoLEngine::updateCompass() {
if (_compassStep)
_compassStep -= (((ABS(_compassStep) >> 4) + 2) * dir);
- int16 d = _compassBroken ? ((int8)getRandomNumberSpecial() - _compassDirection) : (_currentDirection << 6) - _compassDirection;
+ int16 d = _compassBroken ? (int8(_rnd.getRandomNumber(255)) - _compassDirection) : (_currentDirection << 6) - _compassDirection;
if (d <= -128)
d += 256;
if (d >= 128)
@@ -1261,8 +1257,8 @@ void LoLEngine::shakeScene(int duration, int width, int height, int restore) {
while (endTime > _system->getMillis()) {
uint32 delayTimer = _system->getMillis() + 2 * _tickLength;
- int s1 = width ? (getRandomNumberSpecial() % (width << 1)) - width : 0;
- int s2 = height ? (getRandomNumberSpecial() % (height << 1)) - height : 0;
+ int s1 = width ? (_rnd.getRandomNumber(255) % (width << 1)) - width : 0;
+ int s2 = height ? (_rnd.getRandomNumber(255) % (height << 1)) - height : 0;
int x1, y1, x2, y2, w, h;
if (s1 >= 0) {
@@ -1308,11 +1304,11 @@ void LoLEngine::processGasExplosion(int soundId) {
uint16 targetBlock = 0;
int dist = getSpellTargetBlock(_currentBlock, _currentDirection, 3, targetBlock);
- uint8 *p1 = _screen->getPalette(1);
- uint8 *p2 = _screen->getPalette(3);
+ uint8 *p1 = _screen->getPalette(1).getData();
+ uint8 *p2 = _screen->getPalette(3).getData();
if (dist) {
- WSAMovie_v2 *mov = new WSAMovie_v2(this, _screen);
+ WSAMovie_v2 *mov = new WSAMovie_v2(this);
char file[13];
snprintf(file, 13, "gasexp%0d.wsa", dist);
mov->open(file, 1, 0);
@@ -1331,11 +1327,11 @@ void LoLEngine::processGasExplosion(int soundId) {
p2[i * 3] = 0x3f;
uint32 ctime = _system->getMillis();
- while (_screen->fadePaletteStep(_screen->_currentPalette, p2, _system->getMillis() - ctime, 10))
+ while (_screen->fadePaletteStep(_screen->getPalette(0).getData(), p2, _system->getMillis() - ctime, 10))
updateInput();
ctime = _system->getMillis();
- while (_screen->fadePaletteStep(p2, _screen->_currentPalette, _system->getMillis() - ctime, 50))
+ while (_screen->fadePaletteStep(p2, _screen->getPalette(0).getData(), _system->getMillis() - ctime, 50))
updateInput();
}
@@ -1437,7 +1433,7 @@ void LoLEngine::prepareSpecialScene(int fieldType, int hasDialogue, int suspendG
gui_disableControls(controlMode);
if (fadeFlag) {
- memcpy(_screen->getPalette(3) + 384, _screen->_currentPalette + 384, 384);
+ _screen->getPalette(3).copy(_screen->getPalette(0), 128);
_screen->loadSpecialColors(_screen->getPalette(3));
_screen->fadePalette(_screen->getPalette(3), 10);
_screen->_fadeFlag = 0;
@@ -1495,7 +1491,7 @@ int LoLEngine::restoreAfterSpecialScene(int fadeFlag, int redrawPlayField, int r
if (redrawPlayField)
gui_drawPlayField();
- setPaletteBrightness(_screen->_currentPalette, _brightness, _lampEffect);
+ setPaletteBrightness(_screen->getPalette(0), _brightness, _lampEffect);
} else {
_currentControlMode = 0;
@@ -1517,6 +1513,7 @@ void LoLEngine::setSequenceButtons(int x, int y, int w, int h, int enableFlags)
_seqWindowY2 = y + h;
int offs = _itemInHand ? 10 : 0;
_screen->setMouseCursor(offs, offs, getItemIconShapePtr(_itemInHand));
+ _currentFloatingCursor = -1;
if (w == 320) {
setLampMode(0);
_lampStatusSuspended = true;
diff --git a/engines/kyra/scene_mr.cpp b/engines/kyra/scene_mr.cpp
index 07a7aa0d07..a68dcfb394 100644
--- a/engines/kyra/scene_mr.cpp
+++ b/engines/kyra/scene_mr.cpp
@@ -48,10 +48,8 @@ void KyraEngine_MR::enterNewScene(uint16 sceneId, int facing, int unk1, int unk2
}
musicUpdate(0);
- if (!unk3) {
- //XXX
+ if (!unk3)
musicUpdate(0);
- }
if (unk1) {
int x = _mainCharacter.x1;
@@ -88,7 +86,7 @@ void KyraEngine_MR::enterNewScene(uint16 sceneId, int facing, int unk1, int unk2
newSoundFile = true;
}
- //XXX
+ _chatAltFlag = false;
if (!unk3) {
_emc->init(&_sceneScriptState, &_sceneScriptData);
@@ -328,25 +326,23 @@ void KyraEngine_MR::freeSceneShapes() {
void KyraEngine_MR::loadScenePal() {
char filename[16];
- memcpy(_screen->getPalette(2), _screen->getPalette(0), 768);
+ _screen->copyPalette(2, 0);
strcpy(filename, _sceneList[_mainCharacter.sceneId].filename1);
strcat(filename, ".COL");
_screen->loadBitmap(filename, 3, 3, 0);
- memcpy(_screen->getPalette(2), _screen->getCPagePtr(3), 432);
- memset(_screen->getPalette(2), 0, 3);
+ _screen->getPalette(2).copy(_screen->getCPagePtr(3), 0, 144);
+ _screen->getPalette(2).fill(0, 1, 0);
for (int i = 144; i <= 167; ++i) {
- uint8 *palette = _screen->getPalette(2) + i * 3;
+ uint8 *palette = _screen->getPalette(2).getData() + i * 3;
palette[0] = palette[2] = 63;
palette[1] = 0;
}
_screen->generateOverlay(_screen->getPalette(2), _paletteOverlay, 0xF0, 0x19);
- uint8 *palette = _screen->getPalette(2) + 432;
- const uint8 *costPal = _costPalBuffer + _characterShapeFile * 72;
- memcpy(palette, costPal, 24*3);
+ _screen->getPalette(2).copy(_costPalBuffer, _characterShapeFile * 24, 24, 144);
}
void KyraEngine_MR::loadSceneMsc() {
@@ -609,7 +605,7 @@ void KyraEngine_MR::initSceneScreen(int unk1) {
}
if (_noScriptEnter) {
- memset(_screen->getPalette(0), 0, 432);
+ _screen->getPalette(0).fill(0, 144, 0);
if (!_wasPlayingVQA)
_screen->setScreenPalette(_screen->getPalette(0));
}
@@ -619,7 +615,7 @@ void KyraEngine_MR::initSceneScreen(int unk1) {
if (_noScriptEnter) {
if (!_wasPlayingVQA)
_screen->setScreenPalette(_screen->getPalette(2));
- memcpy(_screen->getPalette(0), _screen->getPalette(2), 432);
+ _screen->getPalette(0).copy(_screen->getPalette(2), 0, 144);
if (_wasPlayingVQA) {
_screen->fadeFromBlack(0x3C);
_wasPlayingVQA = false;
diff --git a/engines/kyra/screen.cpp b/engines/kyra/screen.cpp
index 2b3a9366e6..fa54bffa98 100644
--- a/engines/kyra/screen.cpp
+++ b/engines/kyra/screen.cpp
@@ -34,9 +34,15 @@
namespace Kyra {
Screen::Screen(KyraEngine_v1 *vm, OSystem *system)
- : _system(system), _vm(vm), _sjisInvisibleColor(0) {
+ : _system(system), _vm(vm), _sjisInvisibleColor(0),
+ _cursorColorKey((vm->gameFlags().gameID == GI_KYRA1) ? 0xFF : 0x00) {
_debugEnabled = false;
_maskMinY = _maskMaxY = -1;
+
+ _drawShapeVar1 = 0;
+ _drawShapeVar3 = 1;
+ _drawShapeVar4 = 0;
+ _drawShapeVar5 = 0;
}
Screen::~Screen() {
@@ -52,15 +58,13 @@ Screen::~Screen() {
delete[] _sjisFontData;
delete[] _sjisTempPage;
- delete[] _currentPalette;
- delete[] _screenPalette;
+ delete _screenPalette;
+ delete _internFadePalette;
delete[] _decodeShapeBuffer;
delete[] _animBlockPtr;
- if (_vm->gameFlags().platform != Common::kPlatformAmiga) {
- for (int i = 0; i < ARRAYSIZE(_palettes); ++i)
- delete[] _palettes[i];
- }
+ for (uint i = 0; i < _palettes.size(); ++i)
+ delete _palettes[i];
CursorMan.popAllCursors();
}
@@ -123,30 +127,38 @@ bool Screen::init() {
memset(_shapePages, 0, sizeof(_shapePages));
- memset(_palettes, 0, sizeof(_palettes));
- _screenPalette = new uint8[768];
+ const int paletteCount = (_vm->gameFlags().platform == Common::kPlatformAmiga) ? 12 : 4;
+ const int numColors = _use16ColorMode ? 16 : ((_vm->gameFlags().platform == Common::kPlatformAmiga) ? 32 : 256);
+
+ _screenPalette = new Palette(numColors);
assert(_screenPalette);
- memset(_screenPalette, 0, 768);
- if (_vm->gameFlags().platform == Common::kPlatformAmiga) {
- _currentPalette = new uint8[1248];
- assert(_currentPalette);
- memset(_currentPalette, 0, 1248);
+ _palettes.resize(paletteCount);
+ for (int i = 0; i < paletteCount; ++i) {
+ _palettes[i] = new Palette(numColors);
+ assert(_palettes[i]);
+ }
- for (int i = 0; i < 6; ++i)
- _palettes[i] = _currentPalette + (i+1)*96;
- } else {
- _currentPalette = new uint8[768];
- assert(_currentPalette);
- memset(_currentPalette, 0, 768);
- for (int i = 0; i < 3; ++i) {
- _palettes[i] = new uint8[768];
- assert(_palettes[i]);
- memset(_palettes[i], 0, 768);
+ _internFadePalette = new Palette(numColors);
+ assert(_internFadePalette);
+
+ setScreenPalette(getPalette(0));
+
+ // We setup the PC98 text mode palette at [16, 24], since that will be used
+ // for KANJI characters in Lands of Lore.
+ if (_use16ColorMode && _vm->gameFlags().platform == Common::kPlatformPC98) {
+ uint8 palette[8 * 4];
+
+ for (int i = 0; i < 8; ++i) {
+ palette[i * 4 + 0] = ((i >> 1) & 1) * 0xFF;
+ palette[i * 4 + 1] = ((i >> 2) & 1) * 0xFF;
+ palette[i * 4 + 2] = ((i >> 0) & 1) * 0xFF;
+ palette[i * 4 + 3] = 0;
+
+ _system->setPalette(palette, 16, 8);
}
}
- setScreenPalette(_currentPalette);
_curDim = 0;
_charWidth = 0;
_charOffset = 0;
@@ -339,6 +351,148 @@ void Screen::clearCurPage() {
clearOverlayPage(_curPage);
}
+void Screen::copyWsaRect(int x, int y, int w, int h, int dimState, int plotFunc, const uint8 *src,
+ int unk1, const uint8 *unkPtr1, const uint8 *unkPtr2) {
+ uint8 *dstPtr = getPagePtr(_curPage);
+ uint8 *origDst = dstPtr;
+
+ const ScreenDim *dim = getScreenDim(dimState);
+ int dimX1 = dim->sx << 3;
+ int dimX2 = dim->w << 3;
+ dimX2 += dimX1;
+
+ int dimY1 = dim->sy;
+ int dimY2 = dim->h;
+ dimY2 += dimY1;
+
+ int temp = y - dimY1;
+ if (temp < 0) {
+ if ((temp += h) <= 0)
+ return;
+ else {
+ SWAP(temp, h);
+ y += temp - h;
+ src += (temp - h) * w;
+ }
+ }
+
+ temp = dimY2 - y;
+ if (temp <= 0)
+ return;
+
+ if (temp < h)
+ h = temp;
+
+ int srcOffset = 0;
+ temp = x - dimX1;
+ if (temp < 0) {
+ temp = -temp;
+ srcOffset = temp;
+ x += temp;
+ w -= temp;
+ }
+
+ int srcAdd = 0;
+
+ temp = dimX2 - x;
+ if (temp <= 0)
+ return;
+
+ if (temp < w) {
+ SWAP(w, temp);
+ temp -= w;
+ srcAdd = temp;
+ }
+
+ dstPtr += y * SCREEN_W + x;
+ uint8 *dst = dstPtr;
+
+ if (_curPage == 0 || _curPage == 1)
+ addDirtyRect(x, y, w, h);
+
+ clearOverlayRect(_curPage, x, y, w, h);
+
+ temp = h;
+ int curY = y;
+ while (h--) {
+ src += srcOffset;
+ ++curY;
+ int cW = w;
+
+ switch (plotFunc) {
+ case 0:
+ memcpy(dst, src, cW);
+ dst += cW; src += cW;
+ break;
+
+ case 1:
+ while (cW--) {
+ uint8 d = *src++;
+ uint8 t = unkPtr1[d];
+ if (t != 0xFF)
+ d = unkPtr2[*dst + (t << 8)];
+ *dst++ = d;
+ }
+ break;
+
+ case 4:
+ while (cW--) {
+ uint8 d = *src++;
+ if (d)
+ *dst = d;
+ ++dst;
+ }
+ break;
+
+ case 5:
+ while (cW--) {
+ uint8 d = *src++;
+ if (d) {
+ uint8 t = unkPtr1[d];
+ if (t != 0xFF)
+ d = unkPtr2[*dst + (t << 8)];
+ *dst = d;
+ }
+ ++dst;
+ }
+ break;
+
+ case 8:
+ case 9:
+ while (cW--) {
+ uint8 d = *src++;
+ uint8 t = _shapePages[0][dst - origDst] & 7;
+ if (unk1 < t && (curY > _maskMinY && curY < _maskMaxY))
+ d = _shapePages[1][dst - origDst];
+ *dst++ = d;
+ }
+ break;
+
+ case 12:
+ case 13:
+ while (cW--) {
+ uint8 d = *src++;
+ if (d) {
+ uint8 t = _shapePages[0][dst - origDst] & 7;
+ if (unk1 < t && (curY > _maskMinY && curY < _maskMaxY))
+ d = _shapePages[1][dst - origDst];
+ *dst++ = d;
+ } else {
+ d = _shapePages[1][dst - origDst];
+ *dst++ = d;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ dst = (dstPtr += SCREEN_W);
+ src += srcAdd;
+ }
+}
+
uint8 Screen::getPagePixel(int pageNum, int x, int y) {
assert(pageNum < SCREEN_PAGE_NUM);
assert(x >= 0 && x < SCREEN_W && y >= 0 && y < SCREEN_H);
@@ -354,26 +508,25 @@ void Screen::setPagePixel(int pageNum, int x, int y, uint8 color) {
}
void Screen::fadeFromBlack(int delay, const UpdateFunctor *upFunc) {
- fadePalette(_currentPalette, delay, upFunc);
+ fadePalette(getPalette(0), delay, upFunc);
}
void Screen::fadeToBlack(int delay, const UpdateFunctor *upFunc) {
- uint8 blackPal[768];
- memset(blackPal, 0, 768);
- fadePalette(blackPal, delay, upFunc);
+ Palette pal(getPalette(0).getNumColors());
+ fadePalette(pal, delay, upFunc);
}
-void Screen::fadePalette(const uint8 *palData, int delay, const UpdateFunctor *upFunc) {
+void Screen::fadePalette(const Palette &pal, int delay, const UpdateFunctor *upFunc) {
updateScreen();
int diff = 0, delayInc = 0;
- getFadeParams(palData, delay, delayInc, diff);
+ getFadeParams(pal, delay, delayInc, diff);
int delayAcc = 0;
while (!_vm->shouldQuit()) {
delayAcc += delayInc;
- int refreshed = fadePalStep(palData, diff);
+ int refreshed = fadePalStep(pal, diff);
if (upFunc && upFunc->isValid())
(*upFunc)();
@@ -388,7 +541,7 @@ void Screen::fadePalette(const uint8 *palData, int delay, const UpdateFunctor *u
}
if (_vm->shouldQuit()) {
- setScreenPalette(palData);
+ setScreenPalette(pal);
if (upFunc && upFunc->isValid())
(*upFunc)();
else
@@ -396,12 +549,11 @@ void Screen::fadePalette(const uint8 *palData, int delay, const UpdateFunctor *u
}
}
-void Screen::getFadeParams(const uint8 *palette, int delay, int &delayInc, int &diff) {
+void Screen::getFadeParams(const Palette &pal, int delay, int &delayInc, int &diff) {
uint8 maxDiff = 0;
- const int colors = (_vm->gameFlags().platform == Common::kPlatformAmiga ? 32 : 256) * 3;
- for (int i = 0; i < colors; ++i) {
- diff = ABS(palette[i] - _screenPalette[i]);
+ for (int i = 0; i < pal.getNumColors() * 3; ++i) {
+ diff = ABS(pal[i] - (*_screenPalette)[i]);
maxDiff = MAX<uint8>(maxDiff, diff);
}
@@ -417,17 +569,14 @@ void Screen::getFadeParams(const uint8 *palette, int delay, int &delayInc, int &
}
}
-int Screen::fadePalStep(const uint8 *palette, int diff) {
- const int colors = (_vm->gameFlags().platform == Common::kPlatformAmiga ? 32 : (_use16ColorMode ? 16 : 256)) * 3;
-
- uint8 fadePal[768];
- memcpy(fadePal, _screenPalette, colors);
+int Screen::fadePalStep(const Palette &pal, int diff) {
+ _internFadePalette->copy(*_screenPalette);
bool needRefresh = false;
- for (int i = 0; i < colors; ++i) {
- int c1 = palette[i];
- int c2 = fadePal[i];
+ for (int i = 0; i < pal.getNumColors() * 3; ++i) {
+ int c1 = pal[i];
+ int c2 = (*_internFadePalette)[i];
if (c1 != c2) {
needRefresh = true;
if (c1 > c2) {
@@ -442,26 +591,26 @@ int Screen::fadePalStep(const uint8 *palette, int diff) {
c2 = c1;
}
- fadePal[i] = (uint8)c2;
+ (*_internFadePalette)[i] = (uint8)c2;
}
}
if (needRefresh)
- setScreenPalette(fadePal);
+ setScreenPalette(*_internFadePalette);
return needRefresh ? 1 : 0;
}
void Screen::setPaletteIndex(uint8 index, uint8 red, uint8 green, uint8 blue) {
- _currentPalette[index * 3 + 0] = red;
- _currentPalette[index * 3 + 1] = green;
- _currentPalette[index * 3 + 2] = blue;
- setScreenPalette(_currentPalette);
+ getPalette(0)[index * 3 + 0] = red;
+ getPalette(0)[index * 3 + 1] = green;
+ getPalette(0)[index * 3 + 2] = blue;
+ setScreenPalette(getPalette(0));
}
void Screen::getRealPalette(int num, uint8 *dst) {
const int colors = (_vm->gameFlags().platform == Common::kPlatformAmiga ? 32 : 256);
- const uint8 *palData = getPalette(num);
+ const uint8 *palData = getPalette(num).getData();
if (!palData) {
memset(dst, 0, colors * 3);
@@ -469,46 +618,26 @@ void Screen::getRealPalette(int num, uint8 *dst) {
}
for (int i = 0; i < colors; ++i) {
- dst[0] = (palData[0] << 2) | (palData[0] & 3);
- dst[1] = (palData[1] << 2) | (palData[1] & 3);
- dst[2] = (palData[2] << 2) | (palData[2] & 3);
+ dst[0] = (palData[0] * 0xFF) / 0x3F;
+ dst[1] = (palData[1] * 0xFF) / 0x3F;
+ dst[2] = (palData[2] * 0xFF) / 0x3F;
dst += 3;
palData += 3;
}
}
-void Screen::setScreenPalette(const uint8 *palData) {
- const int colors = (_vm->gameFlags().platform == Common::kPlatformAmiga ? 32 : 256);
-
+void Screen::setScreenPalette(const Palette &pal) {
uint8 screenPal[256 * 4];
- if (palData != _screenPalette)
- memcpy(_screenPalette, palData, colors*3);
+ _screenPalette->copy(pal);
- if (_use16ColorMode && _vm->gameFlags().platform == Common::kPlatformPC98) {
- for (int l = 0; l < 1024; l += 64) {
- const uint8 *tp = palData;
- for (int i = 0; i < 16; ++i) {
- screenPal[l + 4 * i + 0] = palData[1];
- screenPal[l + 4 * i + 1] = palData[0];
- screenPal[l + 4 * i + 2] = palData[2];
- screenPal[l + 4 * i + 3] = 0;
- palData += 3;
- }
- palData = tp;
- }
- } else {
- if (palData != _screenPalette)
- memcpy(_screenPalette, palData, colors*3);
- for (int i = 0; i < colors; ++i) {
- screenPal[4 * i + 0] = (palData[0] << 2) | (palData[0] & 3);
- screenPal[4 * i + 1] = (palData[1] << 2) | (palData[1] & 3);
- screenPal[4 * i + 2] = (palData[2] << 2) | (palData[2] & 3);
- screenPal[4 * i + 3] = 0;
- palData += 3;
- }
+ for (int i = 0; i < pal.getNumColors(); ++i) {
+ screenPal[4 * i + 0] = (pal[i * 3 + 0] * 0xFF) / 0x3F;
+ screenPal[4 * i + 1] = (pal[i * 3 + 1] * 0xFF) / 0x3F;
+ screenPal[4 * i + 2] = (pal[i * 3 + 2] * 0xFF) / 0x3F;
+ screenPal[4 * i + 3] = 0;
}
- _system->setPalette(screenPal, 0, colors);
+ _system->setPalette(screenPal, 0, pal.getNumColors());
}
void Screen::copyToPage0(int y, int h, uint8 page, uint8 *seqBuf) {
@@ -656,63 +785,6 @@ void Screen::copyBlockToPage(int pageNum, int x, int y, int w, int h, const uint
}
}
-void Screen::copyFromCurPageBlock(int x, int y, int w, int h, const uint8 *src) {
- if (x < 0)
- x = 0;
- else if (x >= 40)
- return;
-
- if (x + w > 40)
- w = 40 - x;
-
- if (y < 0)
- y = 0;
- else if (y >= 200)
- return;
-
- if (y + h > 200)
- h = 200 - y;
-
- uint8 *dst = getPagePtr(_curPage) + y * SCREEN_W + x * 8;
-
- if (_curPage == 0 || _curPage == 1)
- addDirtyRect(x*8, y, w*8, h);
-
- clearOverlayRect(_curPage, x*8, y, w*8, h);
-
- while (h--) {
- memcpy(dst, src, w*8);
- dst += SCREEN_W;
- src += w*8;
- }
-}
-
-void Screen::copyCurPageBlock(int x, int y, int w, int h, uint8 *dst) {
- assert(dst);
- if (x < 0)
- x = 0;
- else if (x >= 40)
- return;
-
- if (x + w > 40)
- w = 40 - x;
-
- if (y < 0)
- y = 0;
- else if (y >= 200)
- return;
-
- if (y + h > 200)
- h = 200 - y;
-
- const uint8 *src = getPagePtr(_curPage) + y * SCREEN_W + x * 8;
- while (h--) {
- memcpy(dst, src, w*8);
- dst += w*8;
- src += SCREEN_W;
- }
-}
-
void Screen::shuffleScreen(int sx, int sy, int w, int h, int srcPage, int dstPage, int ticks, bool transparent) {
assert(sx >= 0 && w <= SCREEN_W);
int x;
@@ -802,17 +874,26 @@ void Screen::drawBox(int x1, int y1, int x2, int y2, int color) {
drawClippedLine(x1, y2, x2, y2, color);
}
-void Screen::drawShadedBox(int x1, int y1, int x2, int y2, int color1, int color2) {
+void Screen::drawShadedBox(int x1, int y1, int x2, int y2, int color1, int color2, ShadeType shadeType) {
assert(x1 >= 0 && y1 >= 0);
hideMouse();
fillRect(x1, y1, x2, y1 + 1, color1);
- fillRect(x2 - 1, y1, x2, y2, color1);
+ if (shadeType == kShadeTypeLol)
+ fillRect(x1, y1, x1 + 1, y2, color1);
+ else
+ fillRect(x2 - 1, y1, x2, y2, color1);
- drawClippedLine(x1, y1, x1, y2, color2);
- drawClippedLine(x1 + 1, y1 + 1, x1 + 1, y2 - 1, color2);
+ if (shadeType == kShadeTypeLol) {
+ drawClippedLine(x2, y1, x2, y2, color2);
+ drawClippedLine(x2 - 1, y1 + 1, x2 - 1, y2 - 1, color2);
+ drawClippedLine(x1 + 1, y2 - 1, x2, y2 - 1, color2);
+ } else {
+ drawClippedLine(x1, y1, x1, y2, color2);
+ drawClippedLine(x1 + 1, y1 + 1, x1 + 1, y2 - 1, color2);
+ drawClippedLine(x1, y2 - 1, x2 - 1, y2 - 1, color2);
+ }
drawClippedLine(x1, y2, x2, y2, color2);
- drawClippedLine(x1, y2 - 1, x2 - 1, y2 - 1, color2);
showMouse();
}
@@ -909,11 +990,13 @@ bool Screen::loadFont(FontId fontId, const char *filename) {
error("Invalid font data (file '%s', fontSig: %.04X)", filename, fontSig);
fnt->charWidthTable = fontData + READ_LE_UINT16(fontData + 8);
- fnt->charSizeOffset = READ_LE_UINT16(fontData + 4);
+ fnt->fontDescOffset = READ_LE_UINT16(fontData + 4);
fnt->charBitmapOffset = READ_LE_UINT16(fontData + 6);
fnt->charWidthTableOffset = READ_LE_UINT16(fontData + 8);
fnt->charHeightTableOffset = READ_LE_UINT16(fontData + 0xC);
+ fnt->lastGlyph = *(fnt->fontData + fnt->fontDescOffset + 3);
+
return true;
}
@@ -927,23 +1010,30 @@ int Screen::getFontHeight() const {
// FIXME: add font support for amiga version
if (_vm->gameFlags().platform == Common::kPlatformAmiga)
return 0;
- return *(_fonts[_currentFont].fontData + _fonts[_currentFont].charSizeOffset + 4);
+
+ return *(_fonts[_currentFont].fontData + _fonts[_currentFont].fontDescOffset + 4);
}
int Screen::getFontWidth() const {
// FIXME: add font support for amiga version
if (_vm->gameFlags().platform == Common::kPlatformAmiga)
return 0;
- return *(_fonts[_currentFont].fontData + _fonts[_currentFont].charSizeOffset + 5);
+
+ return *(_fonts[_currentFont].fontData + _fonts[_currentFont].fontDescOffset + 5);
}
int Screen::getCharWidth(uint16 c) const {
// FIXME: add font support for amiga version
if (_vm->gameFlags().platform == Common::kPlatformAmiga)
return 0;
+
if (c & 0xFF00)
return SJIS_CHARSIZE >> 1;
- return (int)_fonts[_currentFont].charWidthTable[c] + _charWidth;
+
+ if (_fonts[_currentFont].lastGlyph < c)
+ return 0;
+ else
+ return (int)_fonts[_currentFont].charWidthTable[c] + _charWidth;
}
int Screen::getTextWidth(const char *str) const {
@@ -986,8 +1076,7 @@ void Screen::printText(const char *str, int x, int y, uint8 color1, uint8 color2
cmap[1] = color1;
setTextColor(cmap, 0, 1);
- Font *fnt = &_fonts[_currentFont];
- const uint8 charHeightFnt = *(fnt->fontData + fnt->charSizeOffset + 4);
+ const uint8 charHeightFnt = getFontHeight();
uint8 charHeight = 0;
if (x < 0)
@@ -1037,6 +1126,10 @@ void Screen::printText(const char *str, int x, int y, uint8 color1, uint8 color2
void Screen::drawCharANSI(uint8 c, int x, int y) {
Font *fnt = &_fonts[_currentFont];
+
+ if (c > fnt->lastGlyph)
+ return;
+
uint8 *dst = getPagePtr(_curPage) + y * SCREEN_W + x;
uint16 bitmapOffset = READ_LE_UINT16(fnt->fontData + fnt->charBitmapOffset + c * 2);
@@ -1044,15 +1137,16 @@ void Screen::drawCharANSI(uint8 c, int x, int y) {
return;
uint8 charWidth = *(fnt->fontData + fnt->charWidthTableOffset + c);
- if (charWidth + x > SCREEN_W)
+ if (!charWidth || charWidth + x > SCREEN_W)
return;
- uint8 charH0 = *(fnt->fontData + fnt->charSizeOffset + 4);
- if (charH0 + y > SCREEN_H)
+ uint8 charH0 = getFontHeight();
+ if (!charH0 || charH0 + y > SCREEN_H)
return;
uint8 charH1 = *(fnt->fontData + fnt->charHeightTableOffset + c * 2);
uint8 charH2 = *(fnt->fontData + fnt->charHeightTableOffset + c * 2 + 1);
+
charH0 -= charH1 + charH2;
const uint8 *src = fnt->fontData + bitmapOffset;
@@ -1097,15 +1191,17 @@ void Screen::drawCharANSI(uint8 c, int x, int y) {
}
if (_curPage == 0 || _curPage == 1)
- addDirtyRect(x, y, charWidth, *(fnt->fontData + fnt->charSizeOffset + 4));
+ addDirtyRect(x, y, charWidth, getFontHeight());
}
void Screen::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y, int sd, int flags, ...) {
if (!shapeData)
return;
- int f = _vm->gameFlags().useAltShapeHeader ? 2 : 0;
- if (shapeData[f] & 1)
+ if (_vm->gameFlags().useAltShapeHeader)
+ shapeData += 2;
+
+ if (*shapeData & 1)
flags |= 0x400;
va_list args;
@@ -1115,11 +1211,6 @@ void Screen::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y, int
1, 3, 2, 5, 4, 3, 2, 1
};
- _drawShapeVar1 = 0;
- _drawShapeVar3 = 1;
- _drawShapeVar4 = 0;
- _drawShapeVar5 = 0;
-
_dsTable = 0;
_dsTableLoopCount = 0;
_dsTable2 = 0;
@@ -1145,8 +1236,8 @@ void Screen::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y, int
}
if (flags & 0x200) {
- _drawShapeVar1 += 1;
- _drawShapeVar1 &= 7;
+ ++_drawShapeVar1;
+ _drawShapeVar1 &= (_vm->gameFlags().gameID == GI_KYRA1) ? 0x7 : 0xF;
_drawShapeVar3 = drawShapeVar2[_drawShapeVar1];
_drawShapeVar4 = 0;
_drawShapeVar5 = 256;
@@ -1237,12 +1328,12 @@ void Screen::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y, int
int scaleCounterV = 0;
- f = flags & 0x0f;
- _dsProcessMargin = dsMarginFunc[f];
- _dsScaleSkip = dsSkipFunc[f];
- _dsProcessLine = dsLineFunc[f];
+ const int drawFunc = flags & 0x0f;
+ _dsProcessMargin = dsMarginFunc[drawFunc];
+ _dsScaleSkip = dsSkipFunc[drawFunc];
+ _dsProcessLine = dsLineFunc[drawFunc];
- int ppc = (flags >> 8) & 0x3F;
+ const int ppc = (flags >> 8) & 0x3F;
_dsPlot = dsPlotFunc[ppc];
DsPlotFunc dsPlot2 = dsPlotFunc[ppc], dsPlot3 = dsPlotFunc[ppc];
if (flags & 0x800)
@@ -1274,8 +1365,6 @@ void Screen::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y, int
int y2 = y1 + dsDim->h;
- if (_vm->gameFlags().useAltShapeHeader)
- src += 2;
uint16 shapeFlags = READ_LE_UINT16(src); src += 2;
int shapeHeight = *src++;
@@ -1318,8 +1407,6 @@ void Screen::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y, int
int t = (flags & 2) ? y2 - y - shapeHeight : y - y1;
- const uint8 *s = src;
-
if (t < 0) {
shapeHeight += t;
if (shapeHeight <= 0) {
@@ -1328,23 +1415,29 @@ void Screen::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y, int
}
t *= -1;
- uint8 *tmp = dst;
+ const uint8 *srcBackUp = 0;
do {
_dsOffscreenScaleVal1 = 0;
+ srcBackUp = src;
_dsTmpWidth = shapeWidth;
+
int cnt = shapeWidth;
- (this->*_dsScaleSkip)(tmp, s, cnt);
+ (this->*_dsScaleSkip)(dst, src, cnt);
+
scaleCounterV += _dsScaleH;
- if (!(scaleCounterV & 0xff00))
- continue;
- uint8 r = scaleCounterV >> 8;
- scaleCounterV &= 0xff;
- t -= r;
- } while (t > 0);
-
- if (t < 0)
+
+ if (scaleCounterV & 0xFF00) {
+ uint8 r = scaleCounterV >> 8;
+ scaleCounterV &= 0xFF;
+ t -= r;
+ }
+ } while (!(scaleCounterV & 0xFF00) && (t > 0));
+
+ if (t < 0) {
+ src = srcBackUp;
scaleCounterV += (-t << 8);
+ }
if (!(flags & 2))
y = y1;
@@ -1409,6 +1502,9 @@ void Screen::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y, int
_dsOffscreenLeft /= _dsScaleW;
}
+ if (shapeHeight <= 0 || shpWidthScaled1 <= 0)
+ return;
+
if (pageNum == 0 || pageNum == 1)
addDirtyRect(x, y, shpWidthScaled1, shapeHeight);
clearOverlayRect(pageNum, x, y, shpWidthScaled1, shapeHeight);
@@ -1422,28 +1518,28 @@ void Screen::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y, int
if (!(scaleCounterV & 0xFF00)) {
_dsTmpWidth = shapeWidth;
int cnt = shapeWidth;
- (this->*_dsScaleSkip)(d, s, cnt);
+ (this->*_dsScaleSkip)(d, src, cnt);
}
}
- const uint8 *b_src = s;
+ const uint8 *b_src = src;
do {
- s = b_src;
+ src = b_src;
_dsTmpWidth = shapeWidth;
int cnt = _dsOffscreenLeft;
- int scaleState = (this->*_dsProcessMargin)(d, s, cnt);
+ int scaleState = (this->*_dsProcessMargin)(d, src, cnt);
if (_dsTmpWidth) {
cnt += shpWidthScaled1;
if (cnt > 0) {
if (flags & 0x800)
normalPlot = (curY > _maskMinY && curY < _maskMaxY);
_dsPlot = normalPlot ? dsPlot2 : dsPlot3;
- (this->*_dsProcessLine)(d, s, cnt, scaleState);
+ (this->*_dsProcessLine)(d, src, cnt, scaleState);
}
cnt += _dsOffscreenRight;
if (cnt)
- (this->*_dsScaleSkip)(d, s, cnt);
+ (this->*_dsScaleSkip)(d, src, cnt);
}
dst += dsPitch;
d = dst;
@@ -2492,9 +2588,14 @@ void Screen::hideMouse() {
}
void Screen::showMouse() {
- if (_mouseLockCount == 1)
+ if (_mouseLockCount == 1) {
CursorMan.showMouse(true);
+ // We need to call OSystem::updateScreen here, else the mouse cursor
+ // will only be visible on mouse movment.
+ _system->updateScreen();
+ }
+
if (_mouseLockCount > 0)
_mouseLockCount--;
}
@@ -2531,12 +2632,11 @@ void Screen::setMouseCursor(int x, int y, const byte *shape) {
y <<= 1;
mouseWidth <<= 1;
mouseHeight <<= 1;
- fillRect(mouseWidth, 0, mouseWidth, mouseHeight, 0, 8);
}
uint8 *cursor = new uint8[mouseHeight * mouseWidth];
- fillRect(0, 0, mouseWidth, mouseHeight, 0, 8);
+ fillRect(0, 0, mouseWidth, mouseHeight, _cursorColorKey, 8);
drawShape(8, shape, 0, 0, 0, 0);
int xOffset = 0;
@@ -2544,11 +2644,14 @@ void Screen::setMouseCursor(int x, int y, const byte *shape) {
if (_vm->gameFlags().useHiResOverlay) {
xOffset = mouseWidth;
scale2x(getPagePtr(8) + mouseWidth, SCREEN_W, getPagePtr(8), SCREEN_W, mouseWidth, mouseHeight);
+ postProcessCursor(getPagePtr(8) + mouseWidth, mouseWidth, mouseHeight, SCREEN_W);
+ } else {
+ postProcessCursor(getPagePtr(8), mouseWidth, mouseHeight, SCREEN_W);
}
CursorMan.showMouse(false);
copyRegionToBuffer(8, xOffset, 0, mouseWidth, mouseHeight, cursor);
- CursorMan.replaceCursor(cursor, mouseWidth, mouseHeight, x, y, 0);
+ CursorMan.replaceCursor(cursor, mouseWidth, mouseHeight, x, y, _cursorColorKey);
if (isMouseVisible())
CursorMan.showMouse(true);
delete[] cursor;
@@ -2560,12 +2663,13 @@ void Screen::setMouseCursor(int x, int y, const byte *shape) {
_system->updateScreen();
}
-uint8 *Screen::getPalette(int num) {
- assert(num >= 0 && num < (_vm->gameFlags().platform == Common::kPlatformAmiga ? 6 : 4));
- if (num == 0)
- return _currentPalette;
+Palette &Screen::getPalette(int num) {
+ assert(num >= 0 && (uint)num < _palettes.size());
+ return *_palettes[num];
+}
- return _palettes[num-1];
+void Screen::copyPalette(const int dst, const int src) {
+ getPalette(dst).copy(getPalette(src));
}
byte Screen::getShapeFlag1(int x, int y) {
@@ -2685,7 +2789,7 @@ void Screen::shakeScreen(int times) {
}
}
-void Screen::loadBitmap(const char *filename, int tempPage, int dstPage, uint8 *palData, bool skip) {
+void Screen::loadBitmap(const char *filename, int tempPage, int dstPage, Palette *pal, bool skip) {
uint32 fileSize;
uint8 *srcData = _vm->resource()->fileData(filename, &fileSize);
@@ -2702,9 +2806,8 @@ void Screen::loadBitmap(const char *filename, int tempPage, int dstPage, uint8 *
uint32 imgSize = scumm_stricmp(ext, "CMP") ? READ_LE_UINT32(srcData + 4) : READ_LE_UINT16(srcData);
uint16 palSize = READ_LE_UINT16(srcData + 8);
- if (palData && palSize) {
- loadPalette(srcData + 10, palData, palSize);
- }
+ if (pal && palSize)
+ loadPalette(srcData + 10, *pal, palSize);
uint8 *srcPtr = srcData + 10 + palSize;
uint8 *dstData = getPagePtr(dstPage);
@@ -2738,38 +2841,62 @@ void Screen::loadBitmap(const char *filename, int tempPage, int dstPage, uint8 *
delete[] srcData;
}
-bool Screen::loadPalette(const char *filename, uint8 *palData) {
- uint32 fileSize = 0;
- uint8 *srcData = _vm->resource()->fileData(filename, &fileSize);
- if (!srcData)
+bool Screen::loadPalette(const char *filename, Palette &pal) {
+ Common::SeekableReadStream *stream = _vm->resource()->createReadStream(filename);
+
+ if (!stream)
return false;
- if (palData && fileSize) {
- loadPalette(srcData, palData, fileSize);
- }
- delete[] srcData;
+ debugC(3, kDebugLevelScreen, "Screen::loadPalette('%s', %p)", filename, (const void *)&pal);
+
+ if (_vm->gameFlags().platform == Common::kPlatformAmiga)
+ pal.loadAmigaPalette(*stream, 0, stream->size() / Palette::kAmigaBytesPerColor);
+ else if (_vm->gameFlags().platform == Common::kPlatformPC98 && _use16ColorMode)
+ pal.loadPC98Palette(*stream, 0, stream->size() / Palette::kPC98BytesPerColor);
+ else
+ pal.loadVGAPalette(*stream, 0, stream->size() / Palette::kVGABytesPerColor);
+
+ delete stream;
return true;
}
-void Screen::loadPalette(const byte *data, uint8 *palData, int bytes) {
+bool Screen::loadPaletteTable(const char *filename, int firstPalette) {
+ Common::SeekableReadStream *stream = _vm->resource()->createReadStream(filename);
+
+ if (!stream)
+ return false;
+
+ debugC(3, kDebugLevelScreen, "Screen::loadPaletteTable('%s', %d)", filename, firstPalette);
+
if (_vm->gameFlags().platform == Common::kPlatformAmiga) {
- assert(bytes % 2 == 0);
- assert(bytes / 2 <= 256);
- bytes >>= 1;
- const uint16 *src = (const uint16 *)data;
- for (int i = 0; i < bytes; ++i) {
- uint16 col = READ_BE_UINT16(src); ++src;
- palData[2] = (col & 0xF) << 2; col >>= 4;
- palData[1] = (col & 0xF) << 2; col >>= 4;
- palData[0] = (col & 0xF) << 2; col >>= 4;
- palData += 3;
- }
- } else if (_use16ColorMode) {
- for (int i = 0; i < bytes; ++i)
- palData[i] = ((data[i] & 0xF) << 4) | (data[i] & 0xF0);
+ const int numColors = getPalette(firstPalette).getNumColors();
+ const int palSize = getPalette(firstPalette).getNumColors() * Palette::kAmigaBytesPerColor;
+ const int numPals = stream->size() / palSize;
+
+ for (int i = 0; i < numPals; ++i)
+ getPalette(i + firstPalette).loadAmigaPalette(*stream, 0, numColors);
} else {
- memcpy(palData, data, bytes);
+ const int numColors = getPalette(firstPalette).getNumColors();
+ const int palSize = getPalette(firstPalette).getNumColors() * Palette::kVGABytesPerColor;
+ const int numPals = stream->size() / palSize;
+
+ for (int i = 0; i < numPals; ++i)
+ getPalette(i + firstPalette).loadVGAPalette(*stream, 0, numColors);
}
+
+ delete stream;
+ return true;
+}
+
+void Screen::loadPalette(const byte *data, Palette &pal, int bytes) {
+ Common::MemoryReadStream stream(data, bytes, false);
+
+ if (_vm->gameFlags().platform == Common::kPlatformAmiga)
+ pal.loadAmigaPalette(stream, 0, stream.size() / Palette::kAmigaBytesPerColor);
+ else if (_vm->gameFlags().platform == Common::kPlatformPC98 && _use16ColorMode)
+ pal.loadPC98Palette(stream, 0, stream.size() / Palette::kPC98BytesPerColor);
+ else
+ pal.loadVGAPalette(stream, 0, stream.size() / Palette::kVGABytesPerColor);
}
// dirty rect handling
@@ -2967,8 +3094,17 @@ int SJIStoFMTChunk(int f, int s) { // copied from scumm\charset.cpp
} // end of anonymous namespace
void Screen::drawCharSJIS(uint16 c, int x, int y) {
- int color1 = _textColorsMap[1];
- int color2 = _textColorsMap[0];
+ int color1, color2;
+
+ if (_use16ColorMode) {
+ // PC98 16 color games specify a color value which is for the
+ // PC98 text mode palette, thus we need to remap it.
+ color1 = ((_textColorsMap[1] >> 5) & 0x7) + 16;
+ color2 = ((_textColorsMap[0] >> 5) & 0x7) + 16;
+ } else {
+ color1 = _textColorsMap[1];
+ color2 = _textColorsMap[0];
+ }
memset(_sjisTempPage2, _sjisInvisibleColor, 324);
memset(_sjisSourceChar, 0, 36);
@@ -3139,5 +3275,102 @@ void Screen::drawCharSJIS(uint16 c, int x, int y) {
#pragma mark -
+Palette::Palette(const int numColors) : _palData(0), _numColors(numColors) {
+ _palData = new uint8[numColors * 3];
+ assert(_palData);
+
+ memset(_palData, 0, numColors * 3);
+}
+
+Palette::~Palette() {
+ delete[] _palData;
+ _palData = 0;
+}
+
+void Palette::loadVGAPalette(Common::ReadStream &stream, int startIndex, int colors) {
+ assert(startIndex + colors <= _numColors);
+
+ stream.read(_palData + startIndex * 3, colors * 3);
+}
+
+void Palette::loadAmigaPalette(Common::ReadStream &stream, int startIndex, int colors) {
+ assert(startIndex + colors <= _numColors);
+
+ for (int i = 0; i < colors; ++i) {
+ uint16 col = stream.readUint16BE();
+ _palData[(i + startIndex) * 3 + 2] = ((col & 0xF) * 0xFF) / 0x3F; col >>= 4;
+ _palData[(i + startIndex) * 3 + 1] = ((col & 0xF) * 0xFF) / 0x3F; col >>= 4;
+ _palData[(i + startIndex) * 3 + 0] = ((col & 0xF) * 0xFF) / 0x3F; col >>= 4;
+ }
+}
+
+void Palette::loadPC98Palette(Common::ReadStream &stream, int startIndex, int colors) {
+ assert(startIndex + colors <= _numColors);
+
+ for (int i = 0; i < colors; ++i) {
+ const byte g = stream.readByte(), r = stream.readByte(), b = stream.readByte();
+
+ _palData[(i + startIndex) * 3 + 0] = ((r & 0x0F) * 0x3F) / 0x0F;
+ _palData[(i + startIndex) * 3 + 1] = ((g & 0x0F) * 0x3F) / 0x0F;
+ _palData[(i + startIndex) * 3 + 2] = ((b & 0x0F) * 0x3F) / 0x0F;
+ }
+}
+
+void Palette::clear() {
+ memset(_palData, 0, _numColors * 3);
+}
+
+void Palette::fill(int firstCol, int numCols, uint8 value) {
+ assert(firstCol >= 0 && firstCol + numCols <= _numColors);
+
+ memset(_palData + firstCol * 3, CLIP<int>(value, 0, 63), numCols * 3);
+}
+
+void Palette::copy(const Palette &source, int firstCol, int numCols, int dstStart) {
+ if (numCols == -1)
+ numCols = MIN(source.getNumColors(), _numColors) - firstCol;
+ if (dstStart == -1)
+ dstStart = firstCol;
+
+ assert(numCols >= 0 && numCols <= _numColors);
+ assert(firstCol >= 0 && firstCol <= source.getNumColors());
+ assert(dstStart >= 0 && dstStart + numCols <= _numColors);
+
+ memcpy(_palData + dstStart * 3, source._palData + firstCol * 3, numCols * 3);
+}
+
+void Palette::copy(const uint8 *source, int firstCol, int numCols, int dstStart) {
+ if (source == _palData)
+ return;
+
+ if (dstStart == -1)
+ dstStart = firstCol;
+
+ assert(numCols >= 0 && numCols <= _numColors);
+ assert(firstCol >= 0);
+ assert(dstStart >= 0 && dstStart + numCols <= _numColors);
+
+ memcpy(_palData + dstStart * 3, source + firstCol * 3, numCols * 3);
+}
+
+uint8 *Palette::fetchRealPalette() const {
+ uint8 *buffer = new uint8[_numColors * 3];
+ assert(buffer);
+
+ uint8 *dst = buffer;
+ const uint8 *palData = _palData;
+
+ for (int i = 0; i < _numColors; ++i) {
+ dst[0] = (palData[0] << 2) | (palData[0] & 3);
+ dst[1] = (palData[1] << 2) | (palData[1] & 3);
+ dst[2] = (palData[2] << 2) | (palData[2] & 3);
+
+ dst += 3;
+ palData += 3;
+ }
+
+ return buffer;
+}
+
} // End of namespace Kyra
diff --git a/engines/kyra/screen.h b/engines/kyra/screen.h
index 1691c73a90..390d058bb8 100644
--- a/engines/kyra/screen.h
+++ b/engines/kyra/screen.h
@@ -29,7 +29,9 @@
#include "common/util.h"
#include "common/func.h"
#include "common/list.h"
+#include "common/array.h"
#include "common/rect.h"
+#include "common/stream.h"
class OSystem;
@@ -53,10 +55,112 @@ struct ScreenDim {
struct Font {
uint8 *fontData;
uint8 *charWidthTable;
- uint16 charSizeOffset;
+ uint16 fontDescOffset;
uint16 charBitmapOffset;
uint16 charWidthTableOffset;
uint16 charHeightTableOffset;
+
+ uint8 lastGlyph;
+};
+
+/**
+ * A class that manages KYRA palettes.
+ *
+ * This class stores the palette data as VGA RGB internally.
+ */
+class Palette {
+public:
+ Palette(const int numColors);
+ ~Palette();
+
+ enum {
+ kVGABytesPerColor = 3,
+ kPC98BytesPerColor = 3,
+ kAmigaBytesPerColor = 2
+ };
+
+ /**
+ * Load a VGA palette from the given stream.
+ */
+ void loadVGAPalette(Common::ReadStream &stream, int startIndex, int colors);
+
+ /**
+ * Load a AMIGA palette from the given stream.
+ */
+ void loadAmigaPalette(Common::ReadStream &stream, int startIndex, int colors);
+
+ /**
+ * Load a PC98 16 color palette from the given stream.
+ */
+ void loadPC98Palette(Common::ReadStream &stream, int startIndex, int colors);
+
+ /**
+ * Return the number of colors this palette manages.
+ */
+ int getNumColors() const { return _numColors; }
+
+ /**
+ * Set all palette colors to black.
+ */
+ void clear();
+
+ /**
+ * Fill the given indexes with the given component value.
+ *
+ * @param firstCol the first color, which should be overwritten.
+ * @param numCols number of colors, which schould be overwritten.
+ * @param value color component value, which should be stored.
+ */
+ void fill(int firstCol, int numCols, uint8 value);
+
+ /**
+ * Copy data from another palette.
+ *
+ * @param source palette to copy data from.
+ * @param firstCol the first color of the source which should be copied.
+ * @param numCols number of colors, which should be copied. -1 all remaining colors.
+ * @param dstStart the first color, which should be ovewritten. If -1 firstCol will be used as start.
+ */
+ void copy(const Palette &source, int firstCol = 0, int numCols = -1, int dstStart = -1);
+
+ /**
+ * Copy data from a raw VGA palette.
+ *
+ * @param source source buffer
+ * @param firstCol the first color of the source which should be copied.
+ * @param numCols number of colors, which should be copied.
+ * @param dstStart the first color, which should be ovewritten. If -1 firstCol will be used as start.
+ */
+ void copy(const uint8 *source, int firstCol, int numCols, int dstStart = -1);
+
+ /**
+ * Fetch a RGB palette.
+ *
+ * @return a pointer to the RGB palette data, the client must delete[] it.
+ */
+ uint8 *fetchRealPalette() const;
+
+ //XXX
+ uint8 &operator[](const int index) {
+ assert(index >= 0 && index <= _numColors * 3);
+ return _palData[index];
+ }
+
+ const uint8 &operator[](const int index) const {
+ assert(index >= 0 && index <= _numColors * 3);
+ return _palData[index];
+ }
+
+ /**
+ * Gets raw access to the palette.
+ *
+ * TODO: Get rid of this.
+ */
+ uint8 *getData() { return _palData; }
+ const uint8 *getData() const { return _palData; }
+private:
+ uint8 *_palData;
+ const int _numColors;
};
class Screen {
@@ -110,12 +214,11 @@ public:
// page cur. functions
int setCurPage(int pageNum);
-
- void copyFromCurPageBlock(int x, int y, int w, int h, const uint8 *src);
- void copyCurPageBlock(int x, int y, int w, int h, uint8 *dst);
-
void clearCurPage();
+ void copyWsaRect(int x, int y, int w, int h, int dimState, int plotFunc, const uint8 *src,
+ int unk1, const uint8 *unkPtr1, const uint8 *unkPtr2);
+
// page 0 functions
void copyToPage0(int y, int h, uint8 page, uint8 *seqBuf);
void shakeScreen(int times);
@@ -142,21 +245,25 @@ public:
void fadeFromBlack(int delay=0x54, const UpdateFunctor *upFunc = 0);
void fadeToBlack(int delay=0x54, const UpdateFunctor *upFunc = 0);
- void fadePalette(const uint8 *palData, int delay, const UpdateFunctor *upFunc = 0);
- virtual void getFadeParams(const uint8 *palette, int delay, int &delayInc, int &diff);
- int fadePalStep(const uint8 *palette, int diff);
+ virtual void fadePalette(const Palette &pal, int delay, const UpdateFunctor *upFunc = 0);
+ virtual void getFadeParams(const Palette &pal, int delay, int &delayInc, int &diff);
+ virtual int fadePalStep(const Palette &pal, int diff);
void setPaletteIndex(uint8 index, uint8 red, uint8 green, uint8 blue);
- void setScreenPalette(const uint8 *palData);
- const uint8 *getScreenPalette() const { return _screenPalette; }
+ virtual void setScreenPalette(const Palette &pal);
void getRealPalette(int num, uint8 *dst);
- uint8 *getPalette(int num);
+ Palette &getPalette(int num);
+ void copyPalette(const int dst, const int src);
// gui specific (processing on _curPage)
+ enum ShadeType {
+ kShadeTypeKyra,
+ kShadeTypeLol
+ };
void drawLine(bool vertical, int x, int y, int length, int color);
void drawClippedLine(int x1, int y1, int x2, int y2, int color);
- void drawShadedBox(int x1, int y1, int x2, int y2, int color1, int color2);
+ void drawShadedBox(int x1, int y1, int x2, int y2, int color1, int color2, ShadeType shadeType = kShadeTypeKyra);
void drawBox(int x1, int y1, int x2, int y2, int color);
// font/text handling
@@ -199,10 +306,11 @@ public:
void rectClip(int &x, int &y, int w, int h);
// misc
- void loadBitmap(const char *filename, int tempPage, int dstPage, uint8 *palData, bool skip=false);
+ void loadBitmap(const char *filename, int tempPage, int dstPage, Palette *pal, bool skip=false);
- bool loadPalette(const char *filename, uint8 *palData);
- void loadPalette(const byte *data, uint8 *palData, int bytes);
+ bool loadPalette(const char *filename, Palette &pal);
+ bool loadPaletteTable(const char *filename, int firstPalette);
+ void loadPalette(const byte *data, Palette &pal, int bytes);
void setAnimBlockPtr(int size);
@@ -220,7 +328,6 @@ public:
int _charWidth;
int _charOffset;
int _curPage;
- uint8 *_currentPalette;
uint8 *_shapePages[2];
int _maskMinY, _maskMaxY;
FontId _currentFont;
@@ -231,6 +338,7 @@ public:
static uint decodeFrame4(const uint8 *src, uint8 *dst, uint32 dstSize);
static void decodeFrameDelta(uint8 *dst, const uint8 *src, bool noXor = false);
static void decodeFrameDeltaPage(uint8 *dst, const uint8 *src, const int pitch, bool noXor);
+
static void convertAmigaGfx(uint8 *data, int w, int h, bool offscreen = true);
static void convertAmigaMsc(uint8 *data);
@@ -240,7 +348,7 @@ protected:
void updateDirtyRectsOvl();
void scale2x(byte *dst, int dstPitch, const byte *src, int srcPitch, int w, int h);
- void mergeOverlay(int x, int y, int w, int h);
+ virtual void mergeOverlay(int x, int y, int w, int h);
// overlay specific
byte *getOverlayPtr(int pageNum);
@@ -275,8 +383,9 @@ protected:
uint8 *_sjisSourceChar;
uint8 _sjisInvisibleColor;
- uint8 *_screenPalette;
- uint8 *_palettes[6];
+ Palette *_screenPalette;
+ Common::Array<Palette *> _palettes;
+ Palette *_internFadePalette;
Font _fonts[FID_NUM];
uint8 _textColorsMap[16];
@@ -287,7 +396,11 @@ protected:
uint8 *_animBlockPtr;
int _animBlockSize;
+ // mouse handling
int _mouseLockCount;
+ const uint8 _cursorColorKey;
+
+ virtual void postProcessCursor(uint8 *data, int w, int h, int pitch) {};
enum {
kMaxDirtyRects = 50
diff --git a/engines/kyra/screen_hof.cpp b/engines/kyra/screen_hof.cpp
index 206f8beb87..516cb5bc41 100644
--- a/engines/kyra/screen_hof.cpp
+++ b/engines/kyra/screen_hof.cpp
@@ -44,8 +44,8 @@ const ScreenDim *Screen_HoF::getScreenDim(int dim) {
return &_screenDimTable[dim];
}
-void Screen_HoF::generateGrayOverlay(const uint8 *srcPal, uint8 *grayOverlay, int factor, int addR, int addG, int addB, int lastColor, bool flag) {
- uint8 tmpPal[768];
+void Screen_HoF::generateGrayOverlay(const Palette &srcPal, uint8 *grayOverlay, int factor, int addR, int addG, int addB, int lastColor, bool flag) {
+ Palette tmpPal(lastColor);
for (int i = 0; i != lastColor; i++) {
if (flag) {
@@ -63,7 +63,7 @@ void Screen_HoF::generateGrayOverlay(const uint8 *srcPal, uint8 *grayOverlay, in
}
for (int i = 0; i < lastColor; i++)
- grayOverlay[i] = findLeastDifferentColor(tmpPal + 3 * i, srcPal, lastColor);
+ grayOverlay[i] = findLeastDifferentColor(tmpPal.getData() + 3 * i, srcPal, 0, lastColor);
}
void Screen_HoF::cmpFadeFrameStep(int srcPage, int srcW, int srcH, int srcX, int srcY, int dstPage, int dstW,
diff --git a/engines/kyra/screen_hof.h b/engines/kyra/screen_hof.h
index 088e8b7f55..1c17a424b3 100644
--- a/engines/kyra/screen_hof.h
+++ b/engines/kyra/screen_hof.h
@@ -41,7 +41,7 @@ public:
const ScreenDim *getScreenDim(int dim);
// sequence player
- void generateGrayOverlay(const uint8 *srcPal, uint8 *grayOverlay, int factor, int addR, int addG, int addB, int lastColor, bool flag);
+ void generateGrayOverlay(const Palette &pal, uint8 *grayOverlay, int factor, int addR, int addG, int addB, int lastColor, bool flag);
void cmpFadeFrameStep(int srcPage, int srcW, int srcH, int srcX, int srcY, int dstPage, int dstW, int dstH, int dstX, int dstY, int cmpW, int cmpH, int cmpPage);
void copyPageMemory(int srcPage, int srcPos, int dstPage, int dstPos, int numBytes);
void copyRegionEx(int srcPage, int srcW, int srcH, int dstPage, int dstX,int dstY, int dstW, int dstH, const ScreenDim *d, bool flag = false);
diff --git a/engines/kyra/screen_lok.cpp b/engines/kyra/screen_lok.cpp
index 6d97db2f28..9fdeae1398 100644
--- a/engines/kyra/screen_lok.cpp
+++ b/engines/kyra/screen_lok.cpp
@@ -26,8 +26,9 @@
#include "kyra/kyra_lok.h"
#include "kyra/screen_lok.h"
-namespace Kyra {
+#include "graphics/cursorman.h"
+namespace Kyra {
Screen_LoK::Screen_LoK(KyraEngine_LoK *vm, OSystem *system)
: Screen(vm, system) {
@@ -80,13 +81,15 @@ const ScreenDim *Screen_LoK::getScreenDim(int dim) {
void Screen_LoK::fadeSpecialPalette(int palIndex, int startIndex, int size, int fadeTime) {
assert(_vm->palTable1()[palIndex]);
- assert(_currentPalette);
- uint8 tempPal[768];
- memcpy(tempPal, _currentPalette, 768);
- memcpy(&tempPal[startIndex*3], _vm->palTable1()[palIndex], size*3);
+
+ Palette tempPal(getPalette(0).getNumColors());
+ tempPal.copy(getPalette(0));
+ tempPal.copy(_vm->palTable1()[palIndex], 0, size, startIndex);
+
fadePalette(tempPal, fadeTime*18);
- memcpy(&_currentPalette[startIndex*3], &tempPal[startIndex*3], size*3);
- setScreenPalette(_currentPalette);
+
+ getPalette(0).copy(tempPal, startIndex, size);
+ setScreenPalette(getPalette(0));
_system->updateScreen();
}
@@ -237,4 +240,200 @@ int Screen_LoK::getRectSize(int x, int y) {
return ((x*y) << 3);
}
+#pragma mark -
+
+Screen_LoK_16::Screen_LoK_16(KyraEngine_LoK *vm, OSystem *system) : Screen_LoK(vm, system) {
+ memset(_paletteDither, 0, sizeof(_paletteDither));
+}
+
+void Screen_LoK_16::setScreenPalette(const Palette &pal) {
+ _screenPalette->copy(pal);
+
+ for (int i = 0; i < 256; ++i)
+ paletteMap(i, pal[i * 3 + 0] << 2, pal[i * 3 + 1] << 2, pal[i * 3 + 2] << 2);
+
+ set16ColorPalette(_palette16);
+}
+
+void Screen_LoK_16::fadePalette(const Palette &pal, int delay, const UpdateFunctor *upFunc) {
+ uint8 notBlackFlag = 0;
+ for (int i = 0; i < 768; ++i) {
+ if ((*_screenPalette)[i])
+ notBlackFlag |= 1;
+ if (pal[i])
+ notBlackFlag |= 2;
+ }
+
+ if (notBlackFlag == 1 || notBlackFlag == 2) {
+ bool upFade = false;
+
+ for (int i = 0; i < 768; ++i) {
+ if ((*_screenPalette)[i] < pal[i]) {
+ upFade = true;
+ break;
+ }
+ }
+
+ if (upFade) {
+ for (int i = 0; i < 256; ++i)
+ paletteMap(i, pal[i * 3 + 0] << 2, pal[i * 3 + 1] << 2, pal[i * 3 + 2] << 2);
+ _forceFullUpdate = true;
+ }
+
+ uint8 color16Palette[16 * 3];
+
+ if (upFade)
+ memset(color16Palette, 0, sizeof(color16Palette));
+ else
+ memcpy(color16Palette, _palette16, sizeof(color16Palette));
+
+ set16ColorPalette(color16Palette);
+ updateScreen();
+
+ for (int i = 0; i < 16; ++i) {
+ set16ColorPalette(color16Palette);
+
+ for (int k = 0; k < 48; ++k) {
+ if (upFade) {
+ if (color16Palette[k] < _palette16[k])
+ ++color16Palette[k];
+ } else {
+ if (color16Palette[k] > 0)
+ --color16Palette[k];
+ }
+ }
+
+ if (upFunc && upFunc->isValid())
+ (*upFunc)();
+ else
+ _system->updateScreen();
+
+ _vm->delay((delay >> 5) * _vm->tickLength());
+ }
+ }
+
+ setScreenPalette(pal);
+}
+
+void Screen_LoK_16::getFadeParams(const Palette &pal, int delay, int &delayInc, int &diff) {
+ error("Screen_LoK_16::getFadeParams called");
+}
+
+int Screen_LoK_16::fadePalStep(const Palette &pal, int diff) {
+ error("Screen_LoK_16::fadePalStep called");
+ return 0;
+}
+
+void Screen_LoK_16::paletteMap(uint8 idx, int r, int g, int b) {
+ const int red = r;
+ const int green = g;
+ const int blue = b;
+
+ uint16 rgbDiff = 1000;
+ int rDiff = 0, gDiff = 0, bDiff = 0;
+
+ int index1 = -1;
+
+ for (int i = 0; i < 16; ++i) {
+ const int realR = _palette16[i * 3 + 0] << 4;
+ const int realG = _palette16[i * 3 + 1] << 4;
+ const int realB = _palette16[i * 3 + 2] << 4;
+
+ uint16 diff = ABS(r - realR) + ABS(g - realG) + ABS(b - realB);
+
+ if (diff < rgbDiff) {
+ rgbDiff = diff;
+ index1 = i;
+
+ rDiff = r - realR;
+ gDiff = g - realG;
+ bDiff = b - realB;
+ }
+ }
+
+ r = rDiff / 4 + red;
+ g = gDiff / 4 + green;
+ b = bDiff / 4 + blue;
+
+ rgbDiff = 1000;
+ int index2 = -1;
+
+ for (int i = 0; i < 16; ++i) {
+ const int realR = _palette16[i * 3 + 0] << 4;
+ const int realG = _palette16[i * 3 + 1] << 4;
+ const int realB = _palette16[i * 3 + 2] << 4;
+
+ uint16 diff = ABS(r - realR) + ABS(g - realG) + ABS(b - realB);
+
+ if (diff < rgbDiff) {
+ rgbDiff = diff;
+ index2 = i;
+ }
+ }
+
+ _paletteDither[idx].bestMatch = index1;
+ _paletteDither[idx].invertMatch = index2;
+}
+
+void Screen_LoK_16::convertTo16Colors(uint8 *page, int w, int h, int pitch, int keyColor) {
+ const int rowAdd = pitch * 2 - w;
+
+ uint8 *row1 = page;
+ uint8 *row2 = page + pitch;
+
+ for (int i = 0; i < h; i += 2) {
+ for (int k = 0; k < w; k += 2) {
+ if (keyColor == -1 || keyColor != *row1) {
+ const PaletteDither &dither = _paletteDither[*row1];
+
+ *row1++ = dither.bestMatch;
+ *row1++ = dither.invertMatch;
+ *row2++ = dither.invertMatch;
+ *row2++ = dither.bestMatch;
+ } else {
+ row1 += 2;
+ row2 += 2;
+ }
+ }
+
+ row1 += rowAdd;
+ row2 += rowAdd;
+ }
+}
+
+void Screen_LoK_16::mergeOverlay(int x, int y, int w, int h) {
+ byte *dst = _sjisOverlayPtrs[0] + y * 640 + x;
+
+ // We do a game screen rect to 16 color dithering here. It is
+ // important that we do not dither the overlay, since else the
+ // japanese fonts will look wrong.
+ convertTo16Colors(dst, w, h, 640);
+
+ const byte *src = _sjisOverlayPtrs[1] + y * 640 + x;
+
+ int add = 640 - w;
+
+ while (h--) {
+ for (x = 0; x < w; ++x, ++dst) {
+ byte col = *src++;
+ if (col != _sjisInvisibleColor)
+ *dst = _paletteDither[col].bestMatch;
+ }
+ dst += add;
+ src += add;
+ }
+}
+
+void Screen_LoK_16::set16ColorPalette(const uint8 *pal) {
+ uint8 palette[16 * 4];
+ for (int i = 0; i < 16; ++i) {
+ palette[i * 4 + 0] = (pal[i * 3 + 0] * 0xFF) / 0x0F;
+ palette[i * 4 + 1] = (pal[i * 3 + 1] * 0xFF) / 0x0F;
+ palette[i * 4 + 2] = (pal[i * 3 + 2] * 0xFF) / 0x0F;
+ palette[i * 4 + 3] = 0;
+ }
+
+ _system->setPalette(palette, 0, 16);
+}
+
} // end of namespace Kyra
diff --git a/engines/kyra/screen_lok.h b/engines/kyra/screen_lok.h
index d74da66df5..4eb22df374 100644
--- a/engines/kyra/screen_lok.h
+++ b/engines/kyra/screen_lok.h
@@ -77,6 +77,38 @@ protected:
uint8 *_saveLoadPageOvl[8];
};
+class Screen_LoK_16 : public Screen_LoK {
+public:
+ Screen_LoK_16(KyraEngine_LoK *vm, OSystem *system);
+
+ void setScreenPalette(const Palette &pal);
+
+ void fadePalette(const Palette &pal, int delay, const UpdateFunctor *upFunc = 0);
+ void getFadeParams(const Palette &pal, int delay, int &delayInc, int &diff);
+ int fadePalStep(const Palette &pal, int diff);
+private:
+ void updateDirtyRectsOvl();
+
+ void convertTo16Colors(uint8 *page, int w, int h, int pitch, int keyColor = -1);
+ void postProcessCursor(uint8 *data, int width, int height, int pitch) {
+ convertTo16Colors(data, width, height, pitch, _cursorColorKey);
+ }
+ void mergeOverlay(int x, int y, int w, int h);
+
+ void set16ColorPalette(const uint8 *pal);
+
+ void paletteMap(uint8 idx, int r, int g, int b);
+
+ struct PaletteDither {
+ uint8 bestMatch;
+ uint8 invertMatch;
+ };
+
+ PaletteDither _paletteDither[256];
+
+ static const uint8 _palette16[48];
+};
+
} // end of namespace Kyra
#endif
diff --git a/engines/kyra/screen_lol.cpp b/engines/kyra/screen_lol.cpp
index 3f3aef72fe..b9bf9961c5 100644
--- a/engines/kyra/screen_lol.cpp
+++ b/engines/kyra/screen_lol.cpp
@@ -105,7 +105,7 @@ void Screen_LoL::fprintString(const char *format, int x, int y, uint8 col1, uint
va_end(vaList);
if (flags & 1)
- x -= getTextWidth(string) >> 1;
+ x -= (getTextWidth(string) >> 1);
if (flags & 2)
x -= getTextWidth(string);
@@ -144,8 +144,8 @@ void Screen_LoL::fprintStringIntro(const char *format, int x, int y, uint8 c1, u
printText(buffer, x, y, c1, c2);
}
-void Screen_LoL::generateGrayOverlay(const uint8 *srcPal, uint8 *grayOverlay, int factor, int addR, int addG, int addB, int lastColor, bool skipSpecialColors) {
- uint8 tmpPal[768];
+void Screen_LoL::generateGrayOverlay(const Palette &srcPal, uint8 *grayOverlay, int factor, int addR, int addG, int addB, int lastColor, bool skipSpecialColors) {
+ Palette tmpPal(lastColor);
for (int i = 0; i != lastColor; i++) {
int v = (((srcPal[3 * i] & 0x3f) * factor) / 0x40) + addR;
@@ -157,11 +157,11 @@ void Screen_LoL::generateGrayOverlay(const uint8 *srcPal, uint8 *grayOverlay, in
}
for (int i = 0; i < lastColor; i++)
- grayOverlay[i] = findLeastDifferentColor(tmpPal + 3 * i, srcPal, lastColor, skipSpecialColors);
+ grayOverlay[i] = findLeastDifferentColor(tmpPal.getData() + 3 * i, srcPal, 0, lastColor, skipSpecialColors);
}
-uint8 *Screen_LoL::generateLevelOverlay(const uint8 *srcPal, uint8 *ovl, int opColor, int weight) {
- if (!srcPal || !ovl)
+uint8 *Screen_LoL::generateLevelOverlay(const Palette &srcPal, uint8 *ovl, int opColor, int weight) {
+ if (!ovl)
return ovl;
if (weight > 255)
@@ -186,7 +186,7 @@ uint8 *Screen_LoL::generateLevelOverlay(const uint8 *srcPal, uint8 *ovl, int opC
int m = 0x7fff;
int ii = 127;
int x = 1;
- const uint8 *s = srcPal + 3;
+ const uint8 *s = srcPal.getData() + 3;
do {
if (i == x) {
@@ -282,14 +282,13 @@ void Screen_LoL::fadeClearSceneWindow(int delay) {
if (_fadeFlag == 1)
return;
- uint8 *tpal = new uint8[768];
+ Palette tpal(getPalette(0).getNumColors());
+ tpal.copy(getPalette(0), 128);
- memcpy(tpal, _currentPalette, 768);
- memset(tpal, 0, 384);
loadSpecialColors(tpal);
fadePalette(tpal, delay);
+
fillRect(112, 0, 288, 120, 0);
- delete[] tpal;
_fadeFlag = 1;
}
@@ -838,18 +837,18 @@ void Screen_LoL::fadeToBlack(int delay, const UpdateFunctor *upFunc) {
}
void Screen_LoL::fadeToPalette1(int delay) {
- loadSpecialColors(_palettes[0]);
- fadePalette(_palettes[0], delay);
+ loadSpecialColors(getPalette(1));
+ fadePalette(getPalette(1), delay);
_fadeFlag = 0;
}
-void Screen_LoL::loadSpecialColors(uint8 *destPalette) {
- memcpy(destPalette + 0x240, _screenPalette + 0x240, 12);
+void Screen_LoL::loadSpecialColors(Palette &dst) {
+ dst.copy(*_screenPalette, 192, 4);
}
void Screen_LoL::copyColor(int dstColorIndex, int srcColorIndex) {
- uint8 *s = _screenPalette + srcColorIndex * 3;
- uint8 *d = _screenPalette + dstColorIndex * 3;
+ uint8 *s = _screenPalette->getData() + srcColorIndex * 3;
+ uint8 *d = _screenPalette->getData() + dstColorIndex * 3;
memcpy(d, s, 3);
uint8 ci[4];
@@ -862,9 +861,9 @@ void Screen_LoL::copyColor(int dstColorIndex, int srcColorIndex) {
}
bool Screen_LoL::fadeColor(int dstColorIndex, int srcColorIndex, uint32 elapsedTime, uint32 targetTime) {
- uint8 *dst = _screenPalette + 3 * dstColorIndex;
- uint8 *src = _screenPalette + 3 * srcColorIndex;
- uint8 *p = getPalette(1) + 3 * dstColorIndex;
+ const uint8 *dst = _screenPalette->getData() + 3 * dstColorIndex;
+ const uint8 *src = _screenPalette->getData() + 3 * srcColorIndex;
+ uint8 *p = getPalette(1).getData() + 3 * dstColorIndex;
bool res = false;
@@ -897,22 +896,21 @@ bool Screen_LoL::fadeColor(int dstColorIndex, int srcColorIndex, uint32 elapsedT
p++;
}
- uint8 tpal[768];
- memcpy(tpal, _screenPalette, 768);
- memcpy(tpal + dstColorIndex * 3, tmpPalEntry, 3);
- setScreenPalette(tpal);
+ _internFadePalette->copy(*_screenPalette);
+ _internFadePalette->copy(tmpPalEntry, 0, 1, dstColorIndex);
+ setScreenPalette(*_internFadePalette);
updateScreen();
return res;
}
bool Screen_LoL::fadePaletteStep(uint8 *pal1, uint8 *pal2, uint32 elapsedTime, uint32 targetTime) {
- uint8 tpal[768];
- uint8 *p1 = _palettes[0];
+ Palette &p1 = getPalette(1);
bool res = false;
for (int i = 0; i < 768; i++) {
uint8 out = 0;
+
if (elapsedTime < targetTime) {
int32 d = ((pal2[i] & 0x3f) - (pal1[i] & 0x3f));
if (d)
@@ -925,10 +923,10 @@ bool Screen_LoL::fadePaletteStep(uint8 *pal1, uint8 *pal2, uint32 elapsedTime, u
res = false;
}
- tpal[i] = out;
+ (*_internFadePalette)[i] = out;
}
- setScreenPalette(tpal);
+ setScreenPalette(*_internFadePalette);
updateScreen();
return res;
@@ -936,7 +934,7 @@ bool Screen_LoL::fadePaletteStep(uint8 *pal1, uint8 *pal2, uint32 elapsedTime, u
uint8 *Screen_LoL::generateFadeTable(uint8 *dst, uint8 *src1, uint8 *src2, int numTabs) {
if (!src1)
- src1 = _screenPalette;
+ src1 = _screenPalette->getData();
uint8 *p1 = dst;
uint8 *p2 = src1;
@@ -949,14 +947,14 @@ uint8 *Screen_LoL::generateFadeTable(uint8 *dst, uint8 *src1, uint8 *src2, int n
int16 t = 0;
int16 d = 256 / numTabs;
-
+
for (int i = 1; i < numTabs - 1; i++) {
p2 = src1;
p3 = p1;
t += d;
for (int ii = 0; ii < 768; ii++) {
- int val = (((int8)*p3++ * t) >> 8) + (int8)*p2++;
+ int16 val = (((int8)*p3++ * t) >> 8) + (int8)*p2++;
*dst++ = (uint8)val;
}
}
@@ -972,6 +970,45 @@ uint8 Screen_LoL::getShapePaletteSize(const uint8 *shp) {
return shp[10];
}
+void Screen_LoL::mergeOverlay(int x, int y, int w, int h) {
+ // For now we convert to 16 colors on overlay merging. If that gives
+ // any problems, like Screen functionallity not prepared for the
+ // format PC98 16 color uses, we'll need to think of a better way.
+ //
+ // We must do this before merging the overlay, else the font colors
+ // will be wrong.
+ if (_use16ColorMode)
+ convertPC98Gfx(_sjisOverlayPtrs[0] + y * 640 + x, w, h, 640);
+
+ Screen_v2::mergeOverlay(x, y, w, h);
+}
+
+void Screen_LoL::convertPC98Gfx(uint8 *data, int w, int h, int pitch) {
+ while (h--) {
+ for (int i = 0; i < w; ++i) {
+ *data = _paletteConvTable[*data];
+ ++data;
+ }
+
+ data += pitch - w;
+ }
+}
+
+void Screen_LoL::postProcessCursor(uint8 *data, int w, int h, int pitch) {
+ if (!_use16ColorMode)
+ return;
+
+ while (h--) {
+ for (int i = 0; i < w; ++i) {
+ if (*data != _cursorColorKey)
+ *data = _paletteConvTable[*data];
+ ++data;
+ }
+
+ data += pitch - w;
+ }
+}
+
} // end of namespace Kyra
#endif // ENABLE_LOL
diff --git a/engines/kyra/screen_lol.h b/engines/kyra/screen_lol.h
index 017af4ba48..db355977f8 100644
--- a/engines/kyra/screen_lol.h
+++ b/engines/kyra/screen_lol.h
@@ -70,14 +70,14 @@ public:
// palette stuff
void fadeToBlack(int delay=0x54, const UpdateFunctor *upFunc = 0);
void fadeToPalette1(int delay);
- void loadSpecialColors(uint8 *destPalette);
+ void loadSpecialColors(Palette &dst);
void copyColor(int dstColorIndex, int srcColorIndex);
bool fadeColor(int dstColorIndex, int srcColorIndex, uint32 elapsedTime, uint32 targetTime);
bool fadePaletteStep(uint8 *pal1, uint8 *pal2, uint32 elapsedTime, uint32 targetTime);
uint8 *generateFadeTable(uint8 *dst, uint8 *src1, uint8 *src2, int numTabs);
- void generateGrayOverlay(const uint8 *srcPal, uint8 *grayOverlay, int factor, int addR, int addG, int addB, int lastColor, bool skipSpecialColors);
- uint8 *generateLevelOverlay(const uint8 *srcPal, uint8 *ovl, int opColor, int weight);
+ void generateGrayOverlay(const Palette &Pal, uint8 *grayOverlay, int factor, int addR, int addG, int addB, int lastColor, bool skipSpecialColors);
+ uint8 *generateLevelOverlay(const Palette &Pal, uint8 *ovl, int opColor, int weight);
uint8 *getLevelOverlay(int index) { return _levelOverlays[index]; }
void copyBlockAndApplyOverlay(int page1, int x1, int y1, int page2, int x2, int y2, int w, int h, int dim, uint8 *ovl);
@@ -92,6 +92,9 @@ public:
uint8 *_grayOverlay;
int _fadeFlag;
+ // PC98 specific
+ static void convertPC98Gfx(uint8 *data, int w, int h, int pitch);
+
private:
LoLEngine *_vm;
@@ -106,6 +109,10 @@ private:
uint8 *_levelOverlays[8];
+ static const uint8 _paletteConvTable[256];
+ void mergeOverlay(int x, int y, int w, int h);
+ void postProcessCursor(uint8 *data, int width, int height, int pitch);
+
// magic atlas
void calcBoundariesIntern(int dstX, int dstY, int c, int d);
diff --git a/engines/kyra/screen_v2.cpp b/engines/kyra/screen_v2.cpp
index a4e014e8c1..177d7d66dd 100644
--- a/engines/kyra/screen_v2.cpp
+++ b/engines/kyra/screen_v2.cpp
@@ -38,39 +38,38 @@ Screen_v2::~Screen_v2() {
delete[] _wsaFrameAnimBuffer;
}
-uint8 *Screen_v2::generateOverlay(const uint8 *palette, uint8 *buffer, int startColor, uint16 factor) {
- if (!palette || !buffer)
+uint8 *Screen_v2::generateOverlay(const Palette &pal, uint8 *buffer, int startColor, uint16 factor) {
+ if (!buffer)
return buffer;
factor = MIN<uint16>(255, factor);
factor >>= 1;
factor &= 0xFF;
- const byte col1 = palette[startColor * 3 + 0];
- const byte col2 = palette[startColor * 3 + 1];
- const byte col3 = palette[startColor * 3 + 2];
+ const byte col1 = pal[startColor * 3 + 0];
+ const byte col2 = pal[startColor * 3 + 1];
+ const byte col3 = pal[startColor * 3 + 2];
uint8 *dst = buffer;
*dst++ = 0;
for (int i = 1; i != 255; ++i) {
uint8 processedPalette[3];
- const uint8 *src = palette + i*3;
byte col;
- col = *src++;
+ col = pal[i * 3 + 0];
col -= ((((col - col1) * factor) << 1) >> 8) & 0xFF;
processedPalette[0] = col;
- col = *src++;
+ col = pal[i * 3 + 1];
col -= ((((col - col2) * factor) << 1) >> 8) & 0xFF;
processedPalette[1] = col;
- col = *src++;
+ col = pal[i * 3 + 2];
col -= ((((col - col3) * factor) << 1) >> 8) & 0xFF;
processedPalette[2] = col;
- *dst++ = findLeastDifferentColor(processedPalette, palette+3, 255)+1;
+ *dst++ = findLeastDifferentColor(processedPalette, pal, 1, 255) + 1;
}
return buffer;
@@ -90,7 +89,7 @@ void Screen_v2::applyOverlay(int x, int y, int w, int h, int pageNum, const uint
}
}
-int Screen_v2::findLeastDifferentColor(const uint8 *paletteEntry, const uint8 *palette, uint16 numColors, bool skipSpecialColors) {
+int Screen_v2::findLeastDifferentColor(const uint8 *paletteEntry, const Palette &pal, uint8 firstColor, uint16 numColors, bool skipSpecialColors) {
int m = 0x7fff;
int r = 0x101;
@@ -98,11 +97,11 @@ int Screen_v2::findLeastDifferentColor(const uint8 *paletteEntry, const uint8 *p
if (skipSpecialColors && i >= 0xc0 && i <= 0xc3)
continue;
- int v = paletteEntry[0] - *palette++;
+ int v = paletteEntry[0] - pal[(i + firstColor) * 3 + 0];
int c = v * v;
- v = paletteEntry[1] - *palette++;
+ v = paletteEntry[1] - pal[(i + firstColor) * 3 + 1];
c += (v * v);
- v = paletteEntry[2] - *palette++;
+ v = paletteEntry[2] - pal[(i + firstColor) * 3 + 2];
c += (v * v);
if (c <= m) {
@@ -114,12 +113,11 @@ int Screen_v2::findLeastDifferentColor(const uint8 *paletteEntry, const uint8 *p
return r;
}
-void Screen_v2::getFadeParams(const uint8 *palette, int delay, int &delayInc, int &diff) {
+void Screen_v2::getFadeParams(const Palette &pal, int delay, int &delayInc, int &diff) {
int maxDiff = 0;
diff = 0;
- int len = _use16ColorMode ? 48 : 768;
- for (int i = 0; i < len; ++i) {
- diff = ABS(palette[i] - _screenPalette[i]);
+ for (int i = 0; i < pal.getNumColors() * 3; ++i) {
+ diff = ABS(pal[i] - (*_screenPalette)[i]);
maxDiff = MAX(maxDiff, diff);
}
@@ -137,148 +135,6 @@ void Screen_v2::getFadeParams(const uint8 *palette, int delay, int &delayInc, in
}
}
-void Screen_v2::copyWsaRect(int x, int y, int w, int h, int dimState, int plotFunc, const uint8 *src,
- int unk1, const uint8 *unkPtr1, const uint8 *unkPtr2) {
- uint8 *dstPtr = getPagePtr(_curPage);
- uint8 *origDst = dstPtr;
-
- const ScreenDim *dim = getScreenDim(dimState);
- int dimX1 = dim->sx << 3;
- int dimX2 = dim->w << 3;
- dimX2 += dimX1;
-
- int dimY1 = dim->sy;
- int dimY2 = dim->h;
- dimY2 += dimY1;
-
- int temp = y - dimY1;
- if (temp < 0) {
- if ((temp += h) <= 0)
- return;
- else {
- SWAP(temp, h);
- y += temp - h;
- src += (temp - h) * w;
- }
- }
-
- temp = dimY2 - y;
- if (temp <= 0)
- return;
-
- if (temp < h)
- h = temp;
-
- int srcOffset = 0;
- temp = x - dimX1;
- if (temp < 0) {
- temp = -temp;
- srcOffset = temp;
- x += temp;
- w -= temp;
- }
-
- int srcAdd = 0;
-
- temp = dimX2 - x;
- if (temp <= 0)
- return;
-
- if (temp < w) {
- SWAP(w, temp);
- temp -= w;
- srcAdd = temp;
- }
-
- dstPtr += y * SCREEN_W + x;
- uint8 *dst = dstPtr;
-
- if (_curPage == 0 || _curPage == 1)
- addDirtyRect(x, y, w, h);
-
- clearOverlayRect(_curPage, x, y, w, h);
-
- temp = h;
- int curY = y;
- while (h--) {
- src += srcOffset;
- ++curY;
- int cW = w;
-
- switch (plotFunc) {
- case 0:
- memcpy(dst, src, cW);
- dst += cW; src += cW;
- break;
-
- case 1:
- while (cW--) {
- uint8 d = *src++;
- uint8 t = unkPtr1[d];
- if (t != 0xFF)
- d = unkPtr2[*dst + (t << 8)];
- *dst++ = d;
- }
- break;
-
- case 4:
- while (cW--) {
- uint8 d = *src++;
- if (d)
- *dst = d;
- ++dst;
- }
- break;
-
- case 5:
- while (cW--) {
- uint8 d = *src++;
- if (d) {
- uint8 t = unkPtr1[d];
- if (t != 0xFF)
- d = unkPtr2[*dst + (t << 8)];
- *dst = d;
- }
- ++dst;
- }
- break;
-
- case 8:
- case 9:
- while (cW--) {
- uint8 d = *src++;
- uint8 t = _shapePages[0][dst - origDst] & 7;
- if (unk1 < t && (curY > _maskMinY && curY < _maskMaxY))
- d = _shapePages[1][dst - origDst];
- *dst++ = d;
- }
- break;
-
- case 12:
- case 13:
- while (cW--) {
- uint8 d = *src++;
- if (d) {
- uint8 t = _shapePages[0][dst - origDst] & 7;
- if (unk1 < t && (curY > _maskMinY && curY < _maskMaxY))
- d = _shapePages[1][dst - origDst];
- *dst++ = d;
- } else {
- d = _shapePages[1][dst - origDst];
- *dst++ = d;
- }
- }
- break;
-
- default:
- break;
- }
-
- dst = (dstPtr += SCREEN_W);
- src += srcAdd;
- }
-}
-
const uint8 *Screen_v2::getPtrToShape(const uint8 *shpFile, int shape) {
uint16 shapes = READ_LE_UINT16(shpFile);
diff --git a/engines/kyra/screen_v2.h b/engines/kyra/screen_v2.h
index 18bac764ec..3aa726334c 100644
--- a/engines/kyra/screen_v2.h
+++ b/engines/kyra/screen_v2.h
@@ -37,17 +37,14 @@ public:
~Screen_v2();
// screen page handling
- void copyWsaRect(int x, int y, int w, int h, int dimState, int plotFunc, const uint8 *src,
- int unk1, const uint8 *unkPtr1, const uint8 *unkPtr2);
-
void checkedPageUpdate(int srcPage, int dstPage);
// palette handling
- uint8 *generateOverlay(const uint8 *palette, uint8 *buffer, int color, uint16 factor);
+ uint8 *generateOverlay(const Palette &pal, uint8 *buffer, int color, uint16 factor);
void applyOverlay(int x, int y, int w, int h, int pageNum, const uint8 *overlay);
- int findLeastDifferentColor(const uint8 *paletteEntry, const uint8 *palette, uint16 numColors, bool skipSpecialColors = false);
+ int findLeastDifferentColor(const uint8 *paletteEntry, const Palette &pal, uint8 firstColor, uint16 numColors, bool skipSpecialColors = false);
- virtual void getFadeParams(const uint8 *palette, int delay, int &delayInc, int &diff);
+ virtual void getFadeParams(const Palette &pal, int delay, int &delayInc, int &diff);
// shape handling
uint8 *getPtrToShape(uint8 *shpFile, int shape);
diff --git a/engines/kyra/script.cpp b/engines/kyra/script.cpp
index 9035708f5e..0473f03591 100644
--- a/engines/kyra/script.cpp
+++ b/engines/kyra/script.cpp
@@ -66,6 +66,42 @@ EMCInterpreter::EMCInterpreter(KyraEngine_v1 *vm) : _vm(vm) {
#undef OPCODE
}
+bool EMCInterpreter::callback(Common::IFFChunk &chunk) {
+ switch (chunk._type) {
+ case MKID_BE('TEXT'):
+ _scriptData->text = new byte[chunk._size];
+ assert(_scriptData->text);
+ if (chunk._stream->read(_scriptData->text, chunk._size) != chunk._size)
+ error("Couldn't read TEXT chunk from file '%s'", _filename);
+ break;
+
+ case MKID_BE('ORDR'):
+ _scriptData->ordr = new uint16[chunk._size >> 1];
+ assert(_scriptData->ordr);
+ if (chunk._stream->read(_scriptData->ordr, chunk._size) != chunk._size)
+ error("Couldn't read ORDR chunk from file '%s'", _filename);
+
+ for (int i = (chunk._size >> 1) - 1; i >= 0; --i)
+ _scriptData->ordr[i] = READ_BE_UINT16(&_scriptData->ordr[i]);
+ break;
+
+ case MKID_BE('DATA'):
+ _scriptData->data = new uint16[chunk._size >> 1];
+ assert(_scriptData->data);
+ if (chunk._stream->read(_scriptData->data, chunk._size) != chunk._size)
+ error("Couldn't read DATA chunk from file '%s'", _filename);
+
+ for (int i = (chunk._size >> 1) - 1; i >= 0; --i)
+ _scriptData->data[i] = READ_BE_UINT16(&_scriptData->data[i]);
+ break;
+
+ default:
+ warning("Unexpected chunk '%s' of size %d found in file '%s'", Common::ID2string(chunk._type), chunk._size, _filename);
+ }
+
+ return false;
+}
+
bool EMCInterpreter::load(const char *filename, EMCData *scriptData, const Common::Array<const Opcode*> *opcodes) {
Common::SeekableReadStream *stream = _vm->resource()->createReadStream(filename);
if (!stream) {
@@ -75,47 +111,17 @@ bool EMCInterpreter::load(const char *filename, EMCData *scriptData, const Commo
memset(scriptData, 0, sizeof(EMCData));
+ _scriptData = scriptData;
+ _filename = filename;
+
IFFParser iff(*stream);
- Common::IFFChunk *chunk = 0;
-
- while ((chunk = iff.nextChunk()) != 0) {
- switch (chunk->id) {
- case MKID_BE('TEXT'):
- scriptData->text = new byte[chunk->size];
- assert(scriptData->text);
- if (chunk->read(scriptData->text, chunk->size) != chunk->size)
- error("Couldn't read TEXT chunk from file '%s'", filename);
- break;
-
- case MKID_BE('ORDR'):
- scriptData->ordr = new uint16[chunk->size >> 1];
- assert(scriptData->ordr);
- if (chunk->read(scriptData->ordr, chunk->size) != chunk->size)
- error("Couldn't read ORDR chunk from file '%s'", filename);
-
- for (int i = (chunk->size >> 1) - 1; i >= 0; --i)
- scriptData->ordr[i] = READ_BE_UINT16(&scriptData->ordr[i]);
- break;
-
- case MKID_BE('DATA'):
- scriptData->data = new uint16[chunk->size >> 1];
- assert(scriptData->data);
- if (chunk->read(scriptData->data, chunk->size) != chunk->size)
- error("Couldn't read DATA chunk from file '%s'", filename);
-
- for (int i = (chunk->size >> 1) - 1; i >= 0; --i)
- scriptData->data[i] = READ_BE_UINT16(&scriptData->data[i]);
- break;
-
- default:
- warning("Unexpected chunk '%s' of size %d found in file '%s'", Common::ID2string(chunk->id), chunk->size, filename);
- }
- }
+ Common::Functor1Mem< Common::IFFChunk &, bool, EMCInterpreter > c(this, &EMCInterpreter::callback);
+ iff.parse(c);
- if (!scriptData->ordr)
+ if (!_scriptData->ordr)
error("No ORDR chunk found in file: '%s'", filename);
- if (!scriptData->data)
+ if (!_scriptData->data)
error("No DATA chunk found in file: '%s'", filename);
if (stream->err())
@@ -123,10 +129,10 @@ bool EMCInterpreter::load(const char *filename, EMCData *scriptData, const Commo
delete stream;
- scriptData->sysFuncs = opcodes;
+ _scriptData->sysFuncs = opcodes;
- strncpy(scriptData->filename, filename, 13);
- scriptData->filename[12] = 0;
+ strncpy(_scriptData->filename, filename, 13);
+ _scriptData->filename[12] = 0;
return true;
}
diff --git a/engines/kyra/script.h b/engines/kyra/script.h
index 88bbe86c4d..862cfb7d97 100644
--- a/engines/kyra/script.h
+++ b/engines/kyra/script.h
@@ -70,7 +70,7 @@ class KyraEngine_v1;
class IFFParser : public Common::IFFParser {
public:
- IFFParser(Common::SeekableReadStream &input) : Common::IFFParser(input) {
+ IFFParser(Common::ReadStream &input) : Common::IFFParser(&input) {
// It seems Westwood missunderstood the 'size' field of the FORM chunk.
//
// For EMC scripts (type EMC2) it's filesize instead of filesize - 8,
@@ -84,9 +84,9 @@ public:
// Both lead to some problems in our IFF parser, either reading after the end
// of file or producing a "Chunk overread" error message. To work around this
// we need to adjust the size field properly.
- if (_typeId == MKID_BE('EMC2'))
+ if (_formType == MKID_BE('EMC2'))
_formChunk.size -= 8;
- else if (_typeId == MKID_BE('AVFS'))
+ else if (_formType == MKID_BE('AVFS'))
_formChunk.size += 4;
}
};
@@ -108,6 +108,11 @@ protected:
KyraEngine_v1 *_vm;
int16 _parameter;
+ const char *_filename;
+ EMCData *_scriptData;
+
+ bool callback(Common::IFFChunk &chunk);
+
typedef void (EMCInterpreter::*OpcodeProc)(EMCState *);
struct OpcodeEntry {
OpcodeProc proc;
diff --git a/engines/kyra/script_hof.cpp b/engines/kyra/script_hof.cpp
index b2a581cece..1b8c1d32b3 100644
--- a/engines/kyra/script_hof.cpp
+++ b/engines/kyra/script_hof.cpp
@@ -146,7 +146,7 @@ int KyraEngine_HoF::o2_meanWhileScene(EMCState *script) {
const char *palfile = stackPosString(1);
_screen->loadBitmap(cpsfile, 3, 3, 0);
- memcpy(_screen->getPalette(2), _screen->_currentPalette, 768);
+ _screen->copyPalette(2, 0);
_screen->loadPalette(palfile, _screen->getPalette(2));
_screen->fillRect(0, 0, 319, 199, 207);
_screen->setScreenPalette(_screen->getPalette(2));
@@ -559,14 +559,14 @@ int KyraEngine_HoF::o2_enableAnimObject(EMCState *script) {
int KyraEngine_HoF::o2_loadPalette384(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_loadPalette384(%p) ('%s')", (const void *)script, stackPosString(0));
- memcpy(_screen->getPalette(1), _screen->getPalette(0), 768);
- _res->loadFileToBuf(stackPosString(0), _screen->getPalette(1), 384);
+ _screen->copyPalette(1, 0);
+ _res->loadFileToBuf(stackPosString(0), _screen->getPalette(1).getData(), 384);
return 0;
}
int KyraEngine_HoF::o2_setPalette384(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_setPalette384(%p) ()", (const void *)script);
- memcpy(_screen->getPalette(0), _screen->getPalette(1), 384);
+ _screen->getPalette(0).copy(_screen->getPalette(1), 0, 128);
_screen->setScreenPalette(_screen->getPalette(0));
return 0;
}
@@ -774,13 +774,13 @@ int KyraEngine_HoF::o2_showLetter(EMCState *script) {
displayInvWsaLastFrame();
backUpPage0();
- memcpy(_screen->getPalette(2), _screen->getPalette(0), 768);
+ _screen->copyPalette(2, 0);
_screen->clearPage(3);
_screen->loadBitmap("_NOTE.CPS", 3, 3, 0);
sprintf(filename, "_NTEPAL%.1d.COL", letter+1);
- _res->loadFileToBuf(filename, _screen->getPalette(0), 768);
+ _screen->loadPalette(filename, _screen->getPalette(0));
_screen->fadeToBlack(0x14);
@@ -819,7 +819,7 @@ int KyraEngine_HoF::o2_showLetter(EMCState *script) {
_screen->hideMouse();
_screen->fadeToBlack(0x14);
restorePage0();
- memcpy(_screen->getPalette(0), _screen->getPalette(2), 768);
+ _screen->copyPalette(0, 2);
_screen->fadePalette(_screen->getPalette(0), 0x14);
setHandItem(_itemInHand);
_screen->showMouse();
@@ -1125,25 +1125,25 @@ int KyraEngine_HoF::o2_resetInputColorCode(EMCState *script) {
int KyraEngine_HoF::o2_mushroomEffect(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_mushroomEffect(%p)", (const void *)script);
- memcpy(_screen->getPalette(2), _screen->_currentPalette, 768);
+ _screen->copyPalette(2, 0);
for (int i = 1; i < 768; i += 3)
- _screen->_currentPalette[i] = 0;
+ _screen->getPalette(0)[i] = 0;
snd_playSoundEffect(106);
- _screen->fadePalette(_screen->_currentPalette, 90, &_updateFunctor);
- memcpy(_screen->_currentPalette, _screen->getPalette(2), 768);
+ _screen->fadePalette(_screen->getPalette(0), 90, &_updateFunctor);
+ _screen->copyPalette(0, 2);
for (int i = 0; i < 768; i += 3) {
- _screen->_currentPalette[i] = _screen->_currentPalette[i + 1] = 0;
- _screen->_currentPalette[i + 2] += (((int8)_screen->_currentPalette[i + 2]) >> 1);
- if (_screen->_currentPalette[i + 2] > 63)
- _screen->_currentPalette[i + 2] = 63;
+ _screen->getPalette(0)[i] = _screen->getPalette(0)[i + 1] = 0;
+ _screen->getPalette(0)[i + 2] += (((int8)_screen->getPalette(0)[i + 2]) >> 1);
+ if (_screen->getPalette(0)[i + 2] > 63)
+ _screen->getPalette(0)[i + 2] = 63;
}
snd_playSoundEffect(106);
- _screen->fadePalette(_screen->_currentPalette, 90, &_updateFunctor);
+ _screen->fadePalette(_screen->getPalette(0), 90, &_updateFunctor);
- memcpy(_screen->_currentPalette, _screen->getPalette(2), 768);
- _screen->fadePalette(_screen->_currentPalette, 30, &_updateFunctor);
+ _screen->copyPalette(0, 2);
+ _screen->fadePalette(_screen->getPalette(0), 30, &_updateFunctor);
return 0;
}
@@ -1262,19 +1262,23 @@ int KyraEngine_HoF::o2_stopSceneAnimation(EMCState *script) {
int KyraEngine_HoF::o2_processPaletteIndex(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "KyraEngine_HoF::o2_processPaletteIndex(%p) (%d, %d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5));
- uint8 *palette = _screen->getPalette(0);
+ Palette &palette = _screen->getPalette(0);
+
const int index = stackPos(0);
const bool updatePalette = (stackPos(4) != 0);
const int delayTime = stackPos(5);
+
palette[index*3+0] = (stackPos(1) * 0x3F) / 100;
palette[index*3+1] = (stackPos(2) * 0x3F) / 100;
palette[index*3+2] = (stackPos(3) * 0x3F) / 100;
+
if (updatePalette) {
if (delayTime > 0)
_screen->fadePalette(palette, delayTime, &_updateFunctor);
else
_screen->setScreenPalette(palette);
}
+
return 0;
}
@@ -1396,7 +1400,7 @@ int KyraEngine_HoF::o2_demoFinale(EMCState *script) {
assert(strings);
_screen->clearPage(0);
- _screen->loadPalette("THANKS.COL", _screen->_currentPalette);
+ _screen->loadPalette("THANKS.COL", _screen->getPalette(0));
_screen->loadBitmap("THANKS.CPS", 3, 3, 0);
_screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 0);
@@ -1406,7 +1410,7 @@ int KyraEngine_HoF::o2_demoFinale(EMCState *script) {
for (int i = 0; i < 6; i++)
_text->printText(strings[i], _text->getCenterStringX(strings[i], 1, 319), y + i * 10, 255, 207, 0);
- _screen->setScreenPalette(_screen->_currentPalette);
+ _screen->setScreenPalette(_screen->getPalette(0));
_screen->updateScreen();
_eventList.clear();
diff --git a/engines/kyra/script_lok.cpp b/engines/kyra/script_lok.cpp
index 03a5d4efc1..849c6b776d 100644
--- a/engines/kyra/script_lok.cpp
+++ b/engines/kyra/script_lok.cpp
@@ -231,7 +231,8 @@ int KyraEngine_LoK::o1_fadeSpecialPalette(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_fadeSpecialPalette(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2));
if (_currentCharacter->sceneId != 45) {
if (stackPos(0) == 13) {
- memcpy(_screen->getPalette(0), _screen->getPalette(0) + 384*3, 32*3);
+ // TODO: Check this!
+ _screen->copyPalette(0, 12);
_screen->setScreenPalette(_screen->getPalette(0));
}
} else {
@@ -427,7 +428,7 @@ int KyraEngine_LoK::o1_runWSAFromBeginningToEnd(EMCState *script) {
int wsaFrame = 0;
while (running) {
- _movieObjects[wsaIndex]->displayFrame(wsaFrame++, 0, xpos, ypos);
+ _movieObjects[wsaIndex]->displayFrame(wsaFrame++, 0, xpos, ypos, 0, 0, 0);
_animator->_updateScreen = true;
if (wsaFrame >= _movieObjects[wsaIndex]->frames())
running = false;
@@ -458,7 +459,7 @@ int KyraEngine_LoK::o1_displayWSAFrame(EMCState *script) {
int waitTime = stackPos(3);
int wsaIndex = stackPos(4);
_screen->hideMouse();
- _movieObjects[wsaIndex]->displayFrame(frame, 0, xpos, ypos);
+ _movieObjects[wsaIndex]->displayFrame(frame, 0, xpos, ypos, 0, 0, 0);
_animator->_updateScreen = true;
uint32 continueTime = waitTime * _tickLength + _system->getMillis();
while (_system->getMillis() < continueTime) {
@@ -500,7 +501,7 @@ int KyraEngine_LoK::o1_runWSAFrames(EMCState *script) {
_screen->hideMouse();
for (; startFrame <= endFrame; ++startFrame) {
uint32 nextRun = _system->getMillis() + delayTime * _tickLength;
- _movieObjects[wsaIndex]->displayFrame(startFrame, 0, xpos, ypos);
+ _movieObjects[wsaIndex]->displayFrame(startFrame, 0, xpos, ypos, 0, 0, 0);
_animator->_updateScreen = true;
while (_system->getMillis() < nextRun) {
_sprites->updateSceneAnims();
@@ -578,7 +579,7 @@ int KyraEngine_LoK::o1_restoreAllObjectBackgrounds(EMCState *script) {
int KyraEngine_LoK::o1_setCustomPaletteRange(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_setCustomPaletteRange(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2));
- memcpy(_screen->getPalette(1) + stackPos(1)*3, _specialPalettes[stackPos(0)], stackPos(2)*3);
+ _screen->getPalette(1).copy(_specialPalettes[stackPos(0)], 0, stackPos(2), stackPos(1));
return 0;
}
@@ -682,7 +683,7 @@ int KyraEngine_LoK::o1_displayWSAFrameOnHidPage(EMCState *script) {
_screen->hideMouse();
uint32 continueTime = waitTime * _tickLength + _system->getMillis();
- _movieObjects[wsaIndex]->displayFrame(frame, 2, xpos, ypos);
+ _movieObjects[wsaIndex]->displayFrame(frame, 2, xpos, ypos, 0, 0, 0);
_animator->_updateScreen = true;
while (_system->getMillis() < continueTime) {
_sprites->updateSceneAnims();
@@ -753,7 +754,7 @@ int KyraEngine_LoK::o1_displayWSASequentialFrames(EMCState *script) {
// what shouldn't happen. So we're not updating the screen for this special
// case too.
if (startFrame == 18 && endFrame == 18 && _currentRoom == 45) {
- _movieObjects[wsaIndex]->displayFrame(18, 0, xpos, ypos);
+ _movieObjects[wsaIndex]->displayFrame(18, 0, xpos, ypos, 0, 0, 0);
delay(waitTime * _tickLength);
return 0;
}
@@ -765,7 +766,7 @@ int KyraEngine_LoK::o1_displayWSASequentialFrames(EMCState *script) {
int frame = startFrame;
while (endFrame >= frame) {
uint32 continueTime = waitTime * _tickLength + _system->getMillis();
- _movieObjects[wsaIndex]->displayFrame(frame, 0, xpos, ypos);
+ _movieObjects[wsaIndex]->displayFrame(frame, 0, xpos, ypos, 0, 0, 0);
if (waitTime)
_animator->_updateScreen = true;
while (_system->getMillis() < continueTime) {
@@ -783,7 +784,7 @@ int KyraEngine_LoK::o1_displayWSASequentialFrames(EMCState *script) {
int frame = startFrame;
while (endFrame <= frame) {
uint32 continueTime = waitTime * _tickLength + _system->getMillis();
- _movieObjects[wsaIndex]->displayFrame(frame, 0, xpos, ypos);
+ _movieObjects[wsaIndex]->displayFrame(frame, 0, xpos, ypos, 0, 0, 0);
if (waitTime)
_animator->_updateScreen = true;
while (_system->getMillis() < continueTime) {
@@ -912,8 +913,6 @@ int KyraEngine_LoK::o1_placeCharacterInOtherScene(EMCState *script) {
int KyraEngine_LoK::o1_getKey(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_getKey(%p) ()", (const void *)script);
- // TODO: Check this implementation
-
while (true) {
delay(10);
@@ -1243,8 +1242,8 @@ int KyraEngine_LoK::o1_setFireberryGlowPalette(EMCState *script) {
palIndex = 14;
}
}
- const uint8 *palette = _specialPalettes[palIndex];
- memcpy(_screen->getPalette(1) + 684, palette, 44);
+
+ _screen->getPalette(1).copy(_specialPalettes[palIndex], 0, 15, 228);
return 0;
}
@@ -1276,7 +1275,7 @@ int KyraEngine_LoK::o1_makeAmuletAppear(EMCState *script) {
if (code == 14)
snd_playSoundEffect(0x73);
- amulet.displayFrame(code, 0, 224, 152);
+ amulet.displayFrame(code, 0, 224, 152, 0, 0, 0);
_animator->_updateScreen = true;
while (_system->getMillis() < nextTime) {
@@ -1501,40 +1500,38 @@ int KyraEngine_LoK::o1_setNoDrawShapesFlag(EMCState *script) {
int KyraEngine_LoK::o1_fadeEntirePalette(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_fadeEntirePalette(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
int cmd = stackPos(0);
- uint8 *fadePal = 0;
+
+ int fadePal = 0;
if (_flags.platform == Common::kPlatformAmiga) {
if (cmd == 0) {
- fadePal = _screen->getPalette(2);
- memset(fadePal, 0, 32*3);
- memcpy(_screen->getPalette(4), _screen->getPalette(0), 32*3);
+ _screen->getPalette(2).clear();
+ fadePal = 2;
+ _screen->copyPalette(4, 0);
} else if (cmd == 1) {
- fadePal = _screen->getPalette(0);
- memcpy(_screen->getPalette(0), _screen->getPalette(4), 32*3);
+ fadePal = 0;
+ _screen->copyPalette(0, 4);
} else if (cmd == 2) {
- fadePal = _screen->getPalette(0);
- memset(_screen->getPalette(2), 0, 32*3);
+ fadePal = 0;
+ _screen->getPalette(2).clear();
}
} else {
if (cmd == 0) {
- fadePal = _screen->getPalette(2);
- uint8 *screenPal = _screen->getPalette(0);
- uint8 *backUpPal = _screen->getPalette(3);
-
- memcpy(backUpPal, screenPal, sizeof(uint8)*768);
- memset(fadePal, 0, sizeof(uint8)*768);
+ fadePal = 2;
+ _screen->getPalette(2).clear();
+ _screen->copyPalette(3, 0);
} else if (cmd == 1) {
- //fadePal = _screen->getPalette(3);
+ //fadePal = 3;
warning("unimplemented o1_fadeEntirePalette function");
return 0;
} else if (cmd == 2) {
- memset(_screen->getPalette(2), 0, 768);
- memcpy(_screen->getPalette(0), _screen->getPalette(1), 768);
- fadePal = _screen->getPalette(0);
+ _screen->getPalette(2).clear();
+ _screen->copyPalette(0, 1);
+ fadePal = 0;
}
}
- _screen->fadePalette(fadePal, stackPos(1));
+ _screen->fadePalette(_screen->getPalette(fadePal), stackPos(1));
return 0;
}
diff --git a/engines/kyra/script_lol.cpp b/engines/kyra/script_lol.cpp
index 3d57b23181..a606419722 100644
--- a/engines/kyra/script_lol.cpp
+++ b/engines/kyra/script_lol.cpp
@@ -609,7 +609,7 @@ int LoLEngine::olol_fadePalette(EMCState *script) {
int LoLEngine::olol_loadBitmap(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_clearDialogueField(%p) (%s, %d)", (const void *)script, stackPosString(0), stackPos(1));
- _screen->loadBitmap(stackPosString(0), 3, 3, _screen->getPalette(3));
+ _screen->loadBitmap(stackPosString(0), 3, 3, &_screen->getPalette(3));
if (stackPos(1) != 2)
_screen->copyPage(3, stackPos(1));
return 1;
@@ -663,7 +663,7 @@ int LoLEngine::olol_getGlobalVar(EMCState *script) {
case 12:
return _drainMagic;
case 13:
- return _speechFlag;
+ return getVolume(kVolumeSpeech) - 2;
default:
break;
}
@@ -864,7 +864,7 @@ int LoLEngine::olol_fadeClearSceneWindow(EMCState *script) {
int LoLEngine::olol_fadeSequencePalette(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_fadeSequencePalette(%p)", (const void *)script);
- memcpy(_screen->getPalette(3) + 0x180, _screen->_currentPalette + 0x180, 0x180);
+ _screen->getPalette(3).copy(_screen->getPalette(0), 128);
_screen->loadSpecialColors(_screen->getPalette(3));
_screen->fadePalette(_screen->getPalette(3), 10);
_screen->_fadeFlag = 0;
@@ -876,7 +876,7 @@ int LoLEngine::olol_redrawPlayfield(EMCState *script) {
if (_screen->_fadeFlag != 2)
_screen->fadeClearSceneWindow(10);
gui_drawPlayField();
- setPaletteBrightness(_screen->_currentPalette, _brightness, _lampEffect);
+ setPaletteBrightness(_screen->getPalette(0), _brightness, _lampEffect);
_screen->_fadeFlag = 0;
return 1;
}
@@ -1276,7 +1276,7 @@ int LoLEngine::olol_getMonsterStat(EMCState *script) {
int LoLEngine::olol_releaseMonsterShapes(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_releaseMonsterShapes(%p)", (const void *)script);
for (int i = 0; i < 3; i++)
- releaseMonsterShapes(i);
+ releaseMonsterShapes(i);
return 0;
}
@@ -1399,17 +1399,17 @@ int LoLEngine::olol_playEndSequence(EMCState *script){
if (_characters[0].id == -9)
c = 1;
else if (_characters[0].id == -5)
- c = 3;
+ c = 3;
else if (_characters[0].id == -1)
c = 2;
while (snd_updateCharacterSpeech())
delay(_tickLength);
-
+
_eventList.clear();
_screen->hideMouse();
- memset(_screen->getPalette(1), 0, 768);
-
+ _screen->getPalette(1).clear();
+
showOutro(c, (_monsterDifficulty == 2));
quitGame();
@@ -1428,7 +1428,7 @@ int LoLEngine::olol_setPaletteBrightness(EMCState *script) {
uint16 old = _brightness;
_brightness = stackPos(0);
if (stackPos(1) == 1)
- setPaletteBrightness(_screen->_currentPalette, stackPos(0), _lampEffect);
+ setPaletteBrightness(_screen->getPalette(0), stackPos(0), _lampEffect);
return old;
}
@@ -1994,10 +1994,16 @@ int LoLEngine::olol_findInventoryItem(EMCState *script) {
return -1;
}
+int LoLEngine::olol_drinkBezelCup(EMCState *script) {
+ debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_drinkBezelCup(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
+ drinkBezelCup(3 - stackPos(0), stackPos(1));
+ return 1;
+}
+
int LoLEngine::olol_restoreFadePalette(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_restoreFadePalette(%p)", (const void *)script);
- memcpy(_screen->_currentPalette, _screen->getPalette(1), 384);
- _screen->fadePalette(_screen->_currentPalette, 10);
+ _screen->getPalette(0).copy(_screen->getPalette(1), 0, 128);
+ _screen->fadePalette(_screen->getPalette(0), 10);
_screen->_fadeFlag = 0;
return 1;
}
@@ -2095,27 +2101,29 @@ int LoLEngine::olol_increaseSkill(EMCState *script) {
int LoLEngine::olol_paletteFlash(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_paletteFlash(%p) (%d)", (const void *)script, stackPos(0));
- uint8 *s = _screen->getPalette(1);
- uint8 *d = _screen->getPalette(3);
+ Palette &p1 = _screen->getPalette(1);
+ Palette &p2 = _screen->getPalette(3);
+
uint8 ovl[256];
- generateFlashPalette(s, d, stackPos(0));
- _screen->loadSpecialColors(s);
- _screen->loadSpecialColors(d);
+ generateFlashPalette(p1, p2, stackPos(0));
+ _screen->loadSpecialColors(p1);
+ _screen->loadSpecialColors(p2);
if (_smoothScrollModeNormal) {
for (int i = 0; i < 256; i++)
ovl[i] = i;
ovl[1] = 6;
+
_screen->copyRegion(112, 0, 112, 0, 176, 120, 0, 2);
_screen->applyOverlay(112, 0, 176, 120, 0, ovl);
}
- _screen->setScreenPalette(d);
+ _screen->setScreenPalette(p2);
_screen->updateScreen();
delay(2 * _tickLength);
- _screen->setScreenPalette(s);
+ _screen->setScreenPalette(p1);
if (_smoothScrollModeNormal)
_screen->copyRegion(112, 0, 112, 0, 176, 120, 2, 0);
@@ -2126,55 +2134,65 @@ int LoLEngine::olol_paletteFlash(EMCState *script) {
int LoLEngine::olol_restoreMagicShroud(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_restoreMagicShroud(%p)", (const void *)script);
- WSAMovie_v2 *mov = new WSAMovie_v2(this, _screen);
+ WSAMovie_v2 *mov = new WSAMovie_v2(this);
mov->open("DARKLITE.WSA", 2, 0);
if (!mov->opened())
return 0;
_screen->hideMouse();
+ // TODO: This function could need some major cleanup to work with our
+ // new palette code without needless conversions.
uint8 *fadeTab = new uint8[21504];
uint8 *tpal1 = fadeTab;
uint8 *tpal2 = tpal1 + 768;
uint8 *tpal3 = tpal2 + 768;
uint8 *tpal4 = 0;
- _screen->loadPalette("LITEPAL1.COL", tpal1);
+ _res->loadFileToBuf("LITEPAL1.COL", tpal1, 768);
tpal2 = _screen->generateFadeTable(tpal3, 0, tpal1, 21);
- _screen->loadPalette("LITEPAL2.COL", tpal2);
+ _res->loadFileToBuf("LITEPAL2.COL", tpal2, 768);
tpal4 = tpal2;
tpal2 += 768;
- _screen->loadPalette("LITEPAL3.COL", tpal1);
+ _res->loadFileToBuf("LITEPAL3.COL", tpal1, 768);
_screen->generateFadeTable(tpal2, tpal4, tpal1, 4);
+ Palette pal(768);
+
for (int i = 0; i < 21; i++) {
uint32 etime = _system->getMillis() + 20 * _tickLength;
- mov->displayFrame(i, 0, 0, 0, 0);
+ mov->displayFrame(i, 0, 0, 0, 0, 0, 0);
_screen->updateScreen();
- _screen->setScreenPalette(tpal3);
+
+ pal.copy(tpal3, 0, 256);
+ _screen->setScreenPalette(pal);
tpal3 += 768;
+
if (i == 2 || i == 5 || i == 8 || i == 11 || i == 13 || i == 15 || i == 17 || i == 19)
snd_playSoundEffect(95, -1);
delayUntil(etime);
}
+ pal.copy(tpal3, 0, 256);
snd_playSoundEffect(91, -1);
- _screen->fadePalette(tpal3, 300);
+ _screen->fadePalette(pal, 300);
tpal3 += 768;
for (int i = 22; i < 38; i++) {
uint32 etime = _system->getMillis() + 12 * _tickLength;
- mov->displayFrame(i, 0, 0, 0, 0);
+ mov->displayFrame(i, 0, 0, 0, 0, 0, 0);
_screen->updateScreen();
if (i == 22 || i == 24 || i == 28 || i == 32) {
snd_playSoundEffect(131, -1);
- _screen->setScreenPalette(tpal3);
+
+ pal.copy(tpal3, 0, 256);
+ _screen->setScreenPalette(pal);
tpal3 += 768;
}
delayUntil(etime);
}
mov->close();
- delete mov;
+ delete mov;
delete[] fadeTab;
_screen->showMouse();
@@ -2297,7 +2315,7 @@ int LoLEngine::tlol_loadPalette(const TIM *tim, const uint16 *param) {
int LoLEngine::tlol_setupPaletteFadeEx(const TIM *tim, const uint16 *param) {
debugC(3, kDebugLevelScriptFuncs, "LoLEngine::tlol_setupPaletteFadeEx(%p, %p) (%d)", (const void *)tim, (const void *)param, param[0]);
- memcpy(_screen->getPalette(0), _screen->getPalette(1), 768);
+ _screen->copyPalette(0, 1);
_screen->getFadeParams(_screen->getPalette(0), param[0], _tim->_palDelayInc, _tim->_palDiff);
_tim->_palDelayAcc = 0;
@@ -2375,7 +2393,6 @@ int LoLEngine::tlol_setPartyPosition(const TIM *tim, const uint16 *param) {
int LoLEngine::tlol_fadeClearWindow(const TIM *tim, const uint16 *param) {
debugC(3, kDebugLevelScriptFuncs, "LoLEngine::tlol_fadeClearWindow(%p, %p) (%d)", (const void *)tim, (const void *)param, param[0]);
- uint8 *tmp = 0;
switch (param[0]) {
case 0:
@@ -2383,10 +2400,9 @@ int LoLEngine::tlol_fadeClearWindow(const TIM *tim, const uint16 *param) {
break;
case 1:
- tmp = _screen->getPalette(3);
- memcpy(tmp + 0x180, _screen->_currentPalette + 0x180, 0x180);
- _screen->loadSpecialColors(tmp);
- _screen->fadePalette(tmp, 10);
+ _screen->getPalette(3).copy(_screen->getPalette(0), 128);
+ _screen->loadSpecialColors(_screen->getPalette(3));
+ _screen->fadePalette(_screen->getPalette(3), 10);
_screen->_fadeFlag = 0;
break;
@@ -2395,9 +2411,8 @@ int LoLEngine::tlol_fadeClearWindow(const TIM *tim, const uint16 *param) {
break;
case 3:
- tmp = _screen->getPalette(3);
- _screen->loadSpecialColors(tmp);
- _screen->fadePalette(tmp, 10);
+ _screen->loadSpecialColors(_screen->getPalette(3));
+ _screen->fadePalette(_screen->getPalette(3), 10);
_screen->_fadeFlag = 0;
break;
@@ -2405,13 +2420,12 @@ int LoLEngine::tlol_fadeClearWindow(const TIM *tim, const uint16 *param) {
if (_screen->_fadeFlag != 2)
_screen->fadeClearSceneWindow(10);
gui_drawPlayField();
- setPaletteBrightness(_screen->_currentPalette, _brightness, _lampEffect);
+ setPaletteBrightness(_screen->getPalette(0), _brightness, _lampEffect);
_screen->_fadeFlag = 0;
break;
case 5:
- tmp = _screen->getPalette(3);
- _screen->loadSpecialColors(tmp);
+ _screen->loadSpecialColors(_screen->getPalette(3));
_screen->fadePalette(_screen->getPalette(1), 10);
_screen->_fadeFlag = 0;
break;
@@ -2511,7 +2525,7 @@ int LoLEngine::tlol_fadeInScene(const TIM *tim, const uint16 *param) {
strcpy(filename, sceneFile);
strcat(filename, ".CPS");
- _screen->loadBitmap(filename, 7, 5, _screen->getPalette(0));
+ _screen->loadBitmap(filename, 7, 5, &_screen->getPalette(0));
filename[0] = 0;
@@ -2547,9 +2561,11 @@ int LoLEngine::tlol_unusedResourceFunc(const TIM *tim, const uint16 *param) {
int LoLEngine::tlol_fadeInPalette(const TIM *tim, const uint16 *param) {
debugC(3, kDebugLevelScriptFuncs, "LoLEngine::tlol_fadeInPalette(%p, %p) (%d, %d)", (const void *)tim, (const void *)param, param[0], param[1]);
const char *bitmap = (const char *)(tim->text + READ_LE_UINT16(tim->text + (param[0]<<1)));
- uint8 palette[768];
- _screen->loadBitmap(bitmap, 3, 3, palette);
- _screen->fadePalette(palette, param[1]);
+
+ Palette pal(_screen->getPalette(0).getNumColors());
+ _screen->loadBitmap(bitmap, 3, 3, &pal);
+ _screen->fadePalette(pal, param[1]);
+
return 1;
}
@@ -2566,7 +2582,7 @@ int LoLEngine::tlol_displayAnimFrame(const TIM *tim, const uint16 *param) {
if (param[1] == 0xFFFF) {
_screen->copyRegion(0, 0, 0, 0, 320, 200, 0, 2, Screen::CR_NO_P_CHECK);
} else {
- anim->wsa->displayFrame(param[1], 2, anim->x, anim->y, 0);
+ anim->wsa->displayFrame(param[1], 2, anim->x, anim->y, 0, 0, 0);
_screen->copyRegion(anim->wsa->xAdd(), anim->wsa->yAdd(), anim->wsa->xAdd(), anim->wsa->yAdd(), anim->wsa->width(), anim->wsa->height(), 2, 0);
}
@@ -2852,7 +2868,7 @@ void LoLEngine::setupOpcodeTable() {
// 0xA8
OpcodeUnImpl();
OpcodeUnImpl();
- OpcodeUnImpl();
+ Opcode(olol_drinkBezelCup);
Opcode(olol_changeItemTypeOrFlag);
// 0xAC
diff --git a/engines/kyra/script_mr.cpp b/engines/kyra/script_mr.cpp
index 558d703f15..1800bd1939 100644
--- a/engines/kyra/script_mr.cpp
+++ b/engines/kyra/script_mr.cpp
@@ -381,13 +381,10 @@ int KyraEngine_MR::o3_checkInRect(EMCState *script) {
y += desc[1];
}
- if (x >= x1 && x <= x2 && y >= y1 && y <= y2) {
- //XXX
+ if (x >= x1 && x <= x2 && y >= y1 && y <= y2)
return 1;
- } else {
- //XXX
+ else
return 0;
- }
}
int KyraEngine_MR::o3_updateConversations(EMCState *script) {
diff --git a/engines/kyra/script_tim.cpp b/engines/kyra/script_tim.cpp
index e9ca23a4c9..424a62aaf8 100644
--- a/engines/kyra/script_tim.cpp
+++ b/engines/kyra/script_tim.cpp
@@ -116,6 +116,33 @@ TIMInterpreter::~TIMInterpreter() {
delete[] _animations;
}
+bool TIMInterpreter::callback(Common::IFFChunk &chunk) {
+ switch (chunk._type) {
+ case MKID_BE('TEXT'):
+ _tim->text = new byte[chunk._size];
+ assert(_tim->text);
+ if (chunk._stream->read(_tim->text, chunk._size) != chunk._size)
+ error("Couldn't read TEXT chunk from file '%s'", _filename);
+ break;
+
+ case MKID_BE('AVTL'):
+ _avtlChunkSize = chunk._size >> 1;
+ _tim->avtl = new uint16[_avtlChunkSize];
+ assert(_tim->avtl);
+ if (chunk._stream->read(_tim->avtl, chunk._size) != chunk._size)
+ error("Couldn't read AVTL chunk from file '%s'", _filename);
+
+ for (int i = _avtlChunkSize - 1; i >= 0; --i)
+ _tim->avtl[i] = READ_LE_UINT16(&_tim->avtl[i]);
+ break;
+
+ default:
+ warning("Unexpected chunk '%s' of size %d found in file '%s'", Common::ID2string(chunk._type), chunk._size, _filename);
+ }
+
+ return false;
+}
+
TIM *TIMInterpreter::load(const char *filename, const Common::Array<const TIMOpcode *> *opcodes) {
if (!_vm->resource()->exists(filename))
return 0;
@@ -124,44 +151,21 @@ TIM *TIMInterpreter::load(const char *filename, const Common::Array<const TIMOpc
if (!stream)
error("Couldn't open TIM file '%s'", filename);
- IFFParser iff(*stream);
- Common::IFFChunk *chunk = 0;
-
- TIM *tim = new TIM;
- assert(tim);
- memset(tim, 0, sizeof(TIM));
+ _avtlChunkSize = 0;
+ _filename = filename;
- tim->procFunc = -1;
- tim->opcodes = opcodes;
+ _tim = new TIM;
+ assert(_tim);
+ memset(_tim, 0, sizeof(TIM));
- int avtlChunkSize = 0;
-
- while ((chunk = iff.nextChunk()) != 0) {
- switch (chunk->id) {
- case MKID_BE('TEXT'):
- tim->text = new byte[chunk->size];
- assert(tim->text);
- if (chunk->read(tim->text, chunk->size) != chunk->size)
- error("Couldn't read TEXT chunk from file '%s'", filename);
- break;
-
- case MKID_BE('AVTL'):
- avtlChunkSize = chunk->size >> 1;
- tim->avtl = new uint16[avtlChunkSize];
- assert(tim->avtl);
- if (chunk->read(tim->avtl, chunk->size) != chunk->size)
- error("Couldn't read AVTL chunk from file '%s'", filename);
-
- for (int i = avtlChunkSize - 1; i >= 0; --i)
- tim->avtl[i] = READ_LE_UINT16(&tim->avtl[i]);
- break;
+ _tim->procFunc = -1;
+ _tim->opcodes = opcodes;
- default:
- warning("Unexpected chunk '%s' of size %d found in file '%s'", Common::ID2string(chunk->id), chunk->size, filename);
- }
- }
+ IFFParser iff(*stream);
+ Common::Functor1Mem< Common::IFFChunk &, bool, TIMInterpreter > c(this, &TIMInterpreter::callback);
+ iff.parse(c);
- if (!tim->avtl)
+ if (!_tim->avtl)
error("No AVTL chunk found in file: '%s'", filename);
if (stream->err())
@@ -169,17 +173,17 @@ TIM *TIMInterpreter::load(const char *filename, const Common::Array<const TIMOpc
delete stream;
- int num = (avtlChunkSize < TIM::kCountFuncs) ? avtlChunkSize : (int)TIM::kCountFuncs;
+ int num = (_avtlChunkSize < TIM::kCountFuncs) ? _avtlChunkSize : (int)TIM::kCountFuncs;
for (int i = 0; i < num; ++i)
- tim->func[i].avtl = tim->avtl + tim->avtl[i];
+ _tim->func[i].avtl = _tim->avtl + _tim->avtl[i];
- strncpy(tim->filename, filename, 13);
- tim->filename[12] = 0;
+ strncpy(_tim->filename, filename, 13);
+ _tim->filename[12] = 0;
- tim->isLoLOutro = (_vm->gameFlags().gameID == GI_LOL) && !scumm_stricmp(filename, "LOLFINAL.TIM");
- tim->lolCharacter = 0;
+ _tim->isLoLOutro = (_vm->gameFlags().gameID == GI_LOL) && !scumm_stricmp(filename, "LOLFINAL.TIM");
+ _tim->lolCharacter = 0;
- return tim;
+ return _tim;
}
void TIMInterpreter::unload(TIM *&tim) const {
@@ -300,13 +304,15 @@ void TIMInterpreter::displayText(uint16 textId, int16 flags) {
memcpy(filename, text+1, end-1-text);
}
- if (filename[0])
+ const bool isPC98 = (_vm->gameFlags().platform == Common::kPlatformPC98);
+ if (filename[0] && (_vm->speechEnabled() || isPC98))
_vm->sound()->voicePlay(filename);
if (text[0] == '$')
text = strchr(text + 1, '$') + 1;
- setupTextPalette((flags < 0) ? 1 : flags, 0);
+ if (!isPC98)
+ setupTextPalette((flags < 0) ? 1 : flags, 0);
if (flags < 0) {
static const uint8 colorMap[] = { 0x00, 0xF0, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
@@ -324,7 +330,7 @@ void TIMInterpreter::displayText(uint16 textId, int16 flags) {
char *str = text;
int heightAdd = 0;
- while (str[0]) {
+ while (str[0] && _vm->textEnabled()) {
char *nextLine = strchr(str, '\r');
backupChar = 0;
@@ -335,10 +341,16 @@ void TIMInterpreter::displayText(uint16 textId, int16 flags) {
int width = _screen->getTextWidth(str);
- if (flags >= 0)
- _screen->printText(str, (320 - width) >> 1, 160 + heightAdd, 0xF0, 0x00);
- else
+ if (flags >= 0) {
+ if (isPC98) {
+ static const uint8 colorMap[] = { 0xE1, 0xE1, 0xC1, 0xA1, 0x81, 0x61 };
+ _screen->printText(str, (320 - width) >> 1, 160 + heightAdd, colorMap[flags], 0x00);
+ } else {
+ _screen->printText(str, (320 - width) >> 1, 160 + heightAdd, 0xF0, 0x00);
+ }
+ } else {
_screen->printText(str, (320 - width) >> 1, 188, 0xF0, 0x00);
+ }
heightAdd += _screen->getFontHeight();
str += strlen(str);
@@ -423,7 +435,7 @@ void TIMInterpreter::setupTextPalette(uint index, int fadePalette) {
};
for (int i = 0; i < 15; ++i) {
- uint8 *palette = _screen->getPalette(0) + (240 + i) * 3;
+ uint8 *palette = _screen->getPalette(0).getData() + (240 + i) * 3;
uint8 c1 = (((15 - i) << 2) * palTable[index*3+0]) / 100;
uint8 c2 = (((15 - i) << 2) * palTable[index*3+1]) / 100;
@@ -471,10 +483,10 @@ TIMInterpreter::Animation *TIMInterpreter::initAnimStruct(int index, const char
if (isLoLDemo)
anim->wsa = new WSAMovie_v1(_vm);
else
- anim->wsa = new WSAMovie_v2(_vm, _screen);
+ anim->wsa = new WSAMovie_v2(_vm);
assert(anim->wsa);
- anim->wsa->open(file, wsaOpenFlags, (index == 1) ? _screen->getPalette(0) : 0);
+ anim->wsa->open(file, wsaOpenFlags, (index == 1) ? &_screen->getPalette(0) : 0);
}
if (anim->wsa && anim->wsa->opened()) {
@@ -511,14 +523,14 @@ TIMInterpreter::Animation *TIMInterpreter::initAnimStruct(int index, const char
snprintf(file, 32, "%s.CPS", filename);
if (_vm->resource()->exists(file)) {
- _screen->loadBitmap(file, 3, 3, _screen->getPalette(0));
+ _screen->loadBitmap(file, 3, 3, &_screen->getPalette(0));
_screen->copyRegion(0, 0, 0, 0, 320, 200, 2, _drawPage2, Screen::CR_NO_P_CHECK);
if (_drawPage2)
_screen->checkedPageUpdate(8, 4);
_screen->updateScreen();
}
- anim->wsa->displayFrame(0, 0, x, y, 0);
+ anim->wsa->displayFrame(0, 0, x, y, 0, 0, 0);
}
if (wsaFlags & 2)
@@ -535,7 +547,7 @@ TIMInterpreter::Animation *TIMInterpreter::initAnimStruct(int index, const char
snprintf(file, 32, "%s.CPS", filename);
if (_vm->resource()->exists(file)) {
- _screen->loadBitmap(file, 3, 3, _screen->getPalette(0));
+ _screen->loadBitmap(file, 3, 3, &_screen->getPalette(0));
_screen->copyRegion(0, 0, 0, 0, 320, 200, 2, _drawPage2, Screen::CR_NO_P_CHECK);
if (_drawPage2)
_screen->checkedPageUpdate(8, 4);
@@ -941,21 +953,21 @@ TIMInterpreter::Animation *TIMInterpreter_LoL::initAnimStruct(int index, const c
snprintf(file, 32, "%s.WSA", filename);
if (_vm->resource()->exists(file)) {
- anim->wsa = new WSAMovie_v2(_vm, TIMInterpreter::_screen);
+ anim->wsa = new WSAMovie_v2(_vm);
assert(anim->wsa);
- anim->wsa->open(file, wsaOpenFlags, _screen->getPalette(3));
+ anim->wsa->open(file, wsaOpenFlags, &_screen->getPalette(3));
}
if (wsaFlags & 1) {
if (_screen->_fadeFlag != 1)
_screen->fadeClearSceneWindow(10);
- memcpy(_screen->getPalette(3) + 384, _screen->_currentPalette + 384, 384);
+ _screen->getPalette(3).copy(_screen->getPalette(0), 128, 128);
} else if (wsaFlags & 2) {
_screen->fadeToBlack(10);
}
if (wsaFlags & 7)
- anim->wsa->displayFrame(0, 0, x, y, 0);
+ anim->wsa->displayFrame(0, 0, x, y, 0, 0, 0);
if (wsaFlags & 3) {
_screen->loadSpecialColors(_screen->getPalette(3));
@@ -1000,7 +1012,7 @@ void TIMInterpreter_LoL::advanceToOpcode(int opcode) {
void TIMInterpreter_LoL::drawDialogueBox(int numStr, const char *s1, const char *s2, const char *s3) {
_screen->setScreenDim(5);
- if (numStr == 1 && _vm->_speechFlag) {
+ if (numStr == 1 && _vm->speechEnabled()) {
_dialogueNumButtons = 0;
_dialogueButtonString[0] = _dialogueButtonString[1] = _dialogueButtonString[2] = 0;
} else {
@@ -1051,7 +1063,7 @@ void TIMInterpreter_LoL::startBackgroundAnimation(int animIndex, int part) {
// WORKAROUND for some bugged scripts that will try to display frames of non-existent animations
if (anim->wsa)
- anim->wsa->displayFrame(anim->curFrame - 1, 0, anim->x, anim->y, 0);
+ anim->wsa->displayFrame(anim->curFrame - 1, 0, anim->x, anim->y, 0, 0, 0);
}
void TIMInterpreter_LoL::stopBackgroundAnimation(int animIndex) {
@@ -1110,7 +1122,7 @@ void TIMInterpreter_LoL::updateBackgroundAnimation(int animIndex) {
anim->nextFrame += (anim->frameDelay * _vm->_tickLength);
- anim->wsa->displayFrame(anim->curFrame - 1, 0, anim->x, anim->y, 0);
+ anim->wsa->displayFrame(anim->curFrame - 1, 0, anim->x, anim->y, 0, 0, 0);
anim->nextFrame += _system->getMillis();
}
@@ -1126,10 +1138,12 @@ void TIMInterpreter_LoL::playAnimationPart(int animIndex, int firstFrame, int la
_screen->copyRegion(112, 0, 112, 0, 176, 120, 2, 0);
_screen->updateScreen();
} else {
- anim->wsa->displayFrame(i - 1, 0, anim->x, anim->y, 0);
+ anim->wsa->displayFrame(i - 1, 0, anim->x, anim->y, 0, 0, 0);
_screen->updateScreen();
}
- _vm->delayUntil(next);
+ int32 del = (int32)(next - _system->getMillis());
+ if (del > 0)
+ _vm->delay(del, true);
}
}
@@ -1162,7 +1176,8 @@ uint16 TIMInterpreter_LoL::processDialogue() {
int x = _dialogueButtonPosX;
for (int i = 0; i < _dialogueNumButtons; i++) {
- if (_vm->posWithinRect(_vm->_mouseX, _vm->_mouseY, x, _dialogueButtonPosY, x + 74, _dialogueButtonPosY + 9)) {
+ Common::Point p = _vm->getMousePos();
+ if (_vm->posWithinRect(p.x, p.y, x, _dialogueButtonPosY, x + 74, _dialogueButtonPosY + 9)) {
_dialogueHighlightedButton = i;
break;
}
@@ -1222,7 +1237,8 @@ uint16 TIMInterpreter_LoL::processDialogue() {
x = _dialogueButtonPosX;
for (int i = 0; i < _dialogueNumButtons; i++) {
- if (_vm->posWithinRect(_vm->_mouseX, _vm->_mouseY, x, _dialogueButtonPosY, x + 74, _dialogueButtonPosY + 9)) {
+ Common::Point p = _vm->getMousePos();
+ if (_vm->posWithinRect(p.x, p.y, x, _dialogueButtonPosY, x + 74, _dialogueButtonPosY + 9)) {
_dialogueHighlightedButton = i;
res = _dialogueHighlightedButton + 1;
break;
diff --git a/engines/kyra/script_tim.h b/engines/kyra/script_tim.h
index 10337b4b09..40049c3dec 100644
--- a/engines/kyra/script_tim.h
+++ b/engines/kyra/script_tim.h
@@ -121,6 +121,8 @@ public:
TIM *load(const char *filename, const Common::Array<const TIMOpcode*> *opcodes);
void unload(TIM *&tim) const;
+ bool callback(Common::IFFChunk &chunk);
+
virtual Animation *initAnimStruct(int index, const char *filename, int x, int y, int, int offscreenBuffer, uint16 wsaFlags);
virtual int freeAnimStruct(int index);
@@ -169,6 +171,11 @@ protected:
bool _finished;
+ // used when loading
+ int _avtlChunkSize;
+ const char *_filename;
+ TIM *_tim;
+
Common::String _vocFiles[120];
Animation *_animations;
diff --git a/engines/kyra/seqplayer.cpp b/engines/kyra/seqplayer.cpp
index 54d6f2cbe3..2145591c03 100644
--- a/engines/kyra/seqplayer.cpp
+++ b/engines/kyra/seqplayer.cpp
@@ -92,7 +92,7 @@ uint8 *SeqPlayer::setPanPages(int pageNum, int shape) {
}
void SeqPlayer::makeHandShapes() {
- _screen->loadBitmap("WRITING.CPS", 3, 3, _screen->_currentPalette);
+ _screen->loadBitmap("WRITING.CPS", 3, 3, &_screen->getPalette(0));
if (_vm->gameFlags().platform == Common::kPlatformMacintosh || _vm->gameFlags().platform == Common::kPlatformAmiga) {
freeHandShapes();
@@ -148,7 +148,7 @@ void SeqPlayer::s1_wsaPlayFrame() {
_seqMovies[wsaObj].pos.x = READ_LE_UINT16(_seqData); _seqData += 2;
_seqMovies[wsaObj].pos.y = *_seqData++;
assert(_seqMovies[wsaObj].movie);
- _seqMovies[wsaObj].movie->displayFrame(frame, _seqMovies[wsaObj].page, _seqMovies[wsaObj].pos.x, _seqMovies[wsaObj].pos.y);
+ _seqMovies[wsaObj].movie->displayFrame(frame, _seqMovies[wsaObj].page, _seqMovies[wsaObj].pos.x, _seqMovies[wsaObj].pos.y, 0, 0, 0);
_seqMovies[wsaObj].frame = frame;
}
@@ -160,7 +160,7 @@ void SeqPlayer::s1_wsaPlayNextFrame() {
frame = 0;
_seqMovies[wsaObj].frame = 0;
}
- _seqMovies[wsaObj].movie->displayFrame(frame, _seqMovies[wsaObj].page, _seqMovies[wsaObj].pos.x, _seqMovies[wsaObj].pos.y);
+ _seqMovies[wsaObj].movie->displayFrame(frame, _seqMovies[wsaObj].page, _seqMovies[wsaObj].pos.x, _seqMovies[wsaObj].pos.y, 0, 0, 0);
}
void SeqPlayer::s1_wsaPlayPrevFrame() {
@@ -171,7 +171,7 @@ void SeqPlayer::s1_wsaPlayPrevFrame() {
frame = _seqMovies[wsaObj].numFrames;
_seqMovies[wsaObj].frame = frame;
} else {
- _seqMovies[wsaObj].movie->displayFrame(frame, _seqMovies[wsaObj].page, _seqMovies[wsaObj].pos.x, _seqMovies[wsaObj].pos.y);
+ _seqMovies[wsaObj].movie->displayFrame(frame, _seqMovies[wsaObj].page, _seqMovies[wsaObj].pos.x, _seqMovies[wsaObj].pos.y, 0, 0, 0);
}
}
@@ -194,21 +194,18 @@ void SeqPlayer::s1_copyWaitTicks() {
void SeqPlayer::s1_shuffleScreen() {
_screen->shuffleScreen(0, 16, 320, 128, 2, 0, 0, false);
- _screen->_curPage = 2;
if (_specialBuffer)
- _screen->copyCurPageBlock(0, 16, 40, 128, _specialBuffer);
+ _screen->copyRegionToBuffer(2, 0, 16, 320, 128, _specialBuffer);
_screen->_curPage = 0;
}
void SeqPlayer::s1_copyView() {
- int y = 128;
- if (!_copyViewOffs)
- y -= 8;
+ int h = !_copyViewOffs ? 120 : 128;
if (_specialBuffer && !_copyViewOffs)
- _screen->copyToPage0(16, y, 3, _specialBuffer);
+ _screen->copyToPage0(16, h, 3, _specialBuffer);
else
- _screen->copyRegion(0, 16, 0, 16, 320, y, 2, 0);
+ _screen->copyRegion(0, 16, 0, 16, 320, h, 2, 0);
}
void SeqPlayer::s1_loopInit() {
@@ -244,25 +241,21 @@ void SeqPlayer::s1_loadPalette() {
if (_vm->gameFlags().platform == Common::kPlatformAmiga) {
if (!colNum)
- memcpy(_screen->_currentPalette, _screen->_currentPalette + 576, 3*32);
+ _screen->copyPalette(0, 6);
else if (colNum == 3)
- memcpy(_screen->_currentPalette, _screen->_currentPalette + 672, 3*32);
+ _screen->copyPalette(0, 7);
else if (colNum == 4)
- memcpy(_screen->_currentPalette, _screen->_currentPalette + 288, 3*32);
+ _screen->copyPalette(0, 3);
- _screen->setScreenPalette(_screen->_currentPalette);
+ _screen->setScreenPalette(_screen->getPalette(0));
} else {
- uint32 fileSize;
- uint8 *srcData;
- srcData = _res->fileData(_vm->seqCOLTable()[colNum], &fileSize);
- memcpy(_screen->_currentPalette, srcData, fileSize);
- delete[] srcData;
+ _screen->loadPalette(_vm->seqCOLTable()[colNum], _screen->getPalette(0));
}
}
void SeqPlayer::s1_loadBitmap() {
uint8 cpsNum = *_seqData++;
- _screen->loadBitmap(_vm->seqCPSTable()[cpsNum], 3, 3, _screen->_currentPalette);
+ _screen->loadBitmap(_vm->seqCPSTable()[cpsNum], 3, 3, &_screen->getPalette(0));
}
void SeqPlayer::s1_fadeToBlack() {
@@ -449,10 +442,7 @@ void SeqPlayer::s1_allocTempBuffer() {
if (!_specialBuffer && !_copyViewOffs) {
_specialBuffer = new uint8[40960];
assert(_specialBuffer);
- int page = _screen->_curPage;
- _screen->_curPage = 0;
- _screen->copyCurPageBlock(0, 0, 320, 128, _specialBuffer);
- _screen->_curPage = page;
+ _screen->copyRegionToBuffer(2, 0, 16, 320, 128, _specialBuffer);
}
}
}
diff --git a/engines/kyra/sequences_hof.cpp b/engines/kyra/sequences_hof.cpp
index 4e53399fbf..90b2fdd580 100644
--- a/engines/kyra/sequences_hof.cpp
+++ b/engines/kyra/sequences_hof.cpp
@@ -62,7 +62,7 @@ void KyraEngine_HoF::seq_playSequences(int startSeq, int endSeq) {
int oldPage = _screen->setCurPage(2);
for (int i = 0; i < 4; ++i)
- memset(_screen->getPalette(i), 0, 0x300);
+ _screen->getPalette(i).clear();
_screen->clearPage(10);
_screen->clearPage(12);
@@ -77,7 +77,7 @@ void KyraEngine_HoF::seq_playSequences(int startSeq, int endSeq) {
for (int seqNum = startSeq; seqNum <= endSeq && !((skipFlag() && allowSkip) || shouldQuit() || (_abortIntroFlag && allowSkip) || _menuChoice); seqNum++) {
_screen->clearPage(0);
_screen->clearPage(8);
- memcpy(_screen->getPalette(1), _screen->getPalette(0), 0x300);
+ _screen->copyPalette(1, 0);
_seqFrameCounter = 0;
_seqStartTime = _system->getMillis();
@@ -87,7 +87,7 @@ void KyraEngine_HoF::seq_playSequences(int startSeq, int endSeq) {
SeqProc cb = _callbackS[seqNum];
if (cseq.flags & 2) {
- _screen->loadBitmap(cseq.cpsFile, 2, 2, _screen->getPalette(0));
+ _screen->loadBitmap(cseq.cpsFile, 2, 2, &_screen->getPalette(0));
_screen->setScreenPalette(_screen->getPalette(0));
} else {
_screen->setCurPage(2);
@@ -100,9 +100,9 @@ void KyraEngine_HoF::seq_playSequences(int startSeq, int endSeq) {
if (cseq.flags & 1) {
_seqWsa->close();
- _seqWsa->open(cseq.wsaFile, 0, _screen->getPalette(0));
+ _seqWsa->open(cseq.wsaFile, 0, &_screen->getPalette(0));
_screen->setScreenPalette(_screen->getPalette(0));
- _seqWsa->displayFrame(0, 2, cseq.xPos, cseq.yPos, 0);
+ _seqWsa->displayFrame(0, 2, cseq.xPos, cseq.yPos, 0, 0, 0);
}
if (cseq.flags & 4) {
@@ -174,7 +174,7 @@ void KyraEngine_HoF::seq_playSequences(int startSeq, int endSeq) {
if (_seqWsa) {
int f = _seqWsaCurrentFrame % _seqWsa->frames();
- _seqWsa->displayFrame(f, 2, cseq.xPos, cseq.yPos, 0);
+ _seqWsa->displayFrame(f, 2, cseq.xPos, cseq.yPos, 0, 0, 0);
}
_screen->copyPage(2, 12);
@@ -361,7 +361,7 @@ int KyraEngine_HoF::seq_introTitle(WSAMovie_v2 *wsaObj, int x, int y, int frm) {
}
int KyraEngine_HoF::seq_introOverview(WSAMovie_v2 *wsaObj, int x, int y, int frm) {
- uint8 *tmpPal = &(_screen->getPalette(3)[0x101]);
+ uint8 *tmpPal = _screen->getPalette(3).getData() + 0x101;
memset(tmpPal, 0, 256);
_seqSubFrameEndTimeInternal = 0;
uint32 now = 0;
@@ -372,9 +372,9 @@ int KyraEngine_HoF::seq_introOverview(WSAMovie_v2 *wsaObj, int x, int y, int frm
_sound->playTrack(4);
_seqSubFrameEndTimeInternal = _system->getMillis() + 60 * _tickLength;
- _seqTextColor[1] = _screen->findLeastDifferentColor(_seqTextColorPresets, _screen->getPalette(0) + 3, 255) & 0xff;
+ _seqTextColor[1] = _screen->findLeastDifferentColor(_seqTextColorPresets, _screen->getPalette(0), 1, 255) & 0xff;
memset(_seqTextColorMap, _seqTextColor[1], 16);
- _seqTextColorMap[1] = _seqTextColor[0] = _screen->findLeastDifferentColor(_seqTextColorPresets + 3, _screen->getPalette(0) + 3, 255) & 0xff;
+ _seqTextColorMap[1] = _seqTextColor[0] = _screen->findLeastDifferentColor(_seqTextColorPresets + 3, _screen->getPalette(0), 1, 255) & 0xff;
_screen->setTextColorMap(_seqTextColorMap);
@@ -384,7 +384,7 @@ int KyraEngine_HoF::seq_introOverview(WSAMovie_v2 *wsaObj, int x, int y, int frm
break;
case 1:
- _screen->generateGrayOverlay(_screen->getPalette(0), _screen->getPalette(3), 0x40, 0, 0, 0, 0x100, true);
+ _screen->generateGrayOverlay(_screen->getPalette(0), _screen->getPalette(3).getData(), 0x40, 0, 0, 0, 0x100, true);
for (int i = 0; i < 256; i++)
tmpPal[_screen->getPalette(3)[i]] = 1;
@@ -417,7 +417,7 @@ int KyraEngine_HoF::seq_introOverview(WSAMovie_v2 *wsaObj, int x, int y, int frm
case 201:
_screen->setScreenPalette(_screen->getPalette(2));
_screen->updateScreen();
- _screen->applyOverlay(0, 0, 320, 200, 2, _screen->getPalette(3));
+ _screen->applyOverlay(0, 0, 320, 200, 2, _screen->getPalette(3).getData());
_screen->copyPage(2, 12);
_screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 0);
_screen->setScreenPalette(_screen->getPalette(0));
@@ -465,10 +465,10 @@ int KyraEngine_HoF::seq_introLibrary(WSAMovie_v2 *wsaObj, int x, int y, int frm)
_seqSubframePlaying = true;
_sound->playTrack(5);
- _screen->generateGrayOverlay(_screen->getPalette(0), _screen->getPalette(3), 0x24, 0, 0, 0, 0x100, false);
- _seqTextColor[1] = _screen->findLeastDifferentColor(_seqTextColorPresets, _screen->getPalette(0) + 3, 255) & 0xff;
+ _screen->generateGrayOverlay(_screen->getPalette(0), _screen->getPalette(3).getData(), 0x24, 0, 0, 0, 0x100, false);
+ _seqTextColor[1] = _screen->findLeastDifferentColor(_seqTextColorPresets, _screen->getPalette(0), 1, 255) & 0xff;
memset(_seqTextColorMap, _seqTextColor[1], 16);
- _seqTextColorMap[1] = _seqTextColor[0] = _screen->findLeastDifferentColor(_seqTextColorPresets + 3, _screen->getPalette(0) + 3, 255) & 0xff;
+ _seqTextColorMap[1] = _seqTextColor[0] = _screen->findLeastDifferentColor(_seqTextColorPresets + 3, _screen->getPalette(0), 1, 255) & 0xff;
_screen->setTextColorMap(_seqTextColorMap);
break;
@@ -482,7 +482,7 @@ int KyraEngine_HoF::seq_introLibrary(WSAMovie_v2 *wsaObj, int x, int y, int frm)
seq_waitForTextsTimeout();
_screen->copyPage(12, 2);
- _screen->applyOverlay(0, 0, 320, 200, 2, _screen->getPalette(3));
+ _screen->applyOverlay(0, 0, 320, 200, 2, _screen->getPalette(3).getData());
_screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 0);
_screen->updateScreen();
_screen->copyPage(2, 12);
@@ -503,7 +503,7 @@ int KyraEngine_HoF::seq_introLibrary(WSAMovie_v2 *wsaObj, int x, int y, int frm)
case 340:
seq_resetActiveWSA(0);
- _screen->applyOverlay(0, 0, 320, 200, 2, _screen->getPalette(3));
+ _screen->applyOverlay(0, 0, 320, 200, 2, _screen->getPalette(3).getData());
_screen->copyPage(2, 12);
_screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 0);
_screen->updateScreen();
@@ -539,10 +539,10 @@ int KyraEngine_HoF::seq_introHand(WSAMovie_v2 *wsaObj, int x, int y, int frm) {
_seqSubframePlaying = true;
_sound->playTrack(6);
- _screen->generateGrayOverlay(_screen->getPalette(0), _screen->getPalette(3), 0x24, 0, 0, 0, 0x100, false);
- _seqTextColor[1] = _screen->findLeastDifferentColor(_seqTextColorPresets, _screen->getPalette(0) + 3, 255) & 0xff;
+ _screen->generateGrayOverlay(_screen->getPalette(0), _screen->getPalette(3).getData(), 0x24, 0, 0, 0, 0x100, false);
+ _seqTextColor[1] = _screen->findLeastDifferentColor(_seqTextColorPresets, _screen->getPalette(0), 1, 255) & 0xff;
memset(_seqTextColorMap, _seqTextColor[1], 16);
- _seqTextColorMap[1] = _seqTextColor[0] = _screen->findLeastDifferentColor(_seqTextColorPresets + 3, _screen->getPalette(0) + 3, 255) & 0xff;
+ _seqTextColorMap[1] = _seqTextColor[0] = _screen->findLeastDifferentColor(_seqTextColorPresets + 3, _screen->getPalette(0), 1, 255) & 0xff;
_screen->setTextColorMap(_seqTextColorMap);
break;
@@ -556,7 +556,7 @@ int KyraEngine_HoF::seq_introHand(WSAMovie_v2 *wsaObj, int x, int y, int frm) {
case 201:
seq_waitForTextsTimeout();
- _screen->applyOverlay(0, 0, 320, 200, 2, _screen->getPalette(3));
+ _screen->applyOverlay(0, 0, 320, 200, 2, _screen->getPalette(3).getData());
_screen->copyPage(2, 12);
_screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 0);
_screen->updateScreen();
@@ -631,9 +631,9 @@ int KyraEngine_HoF::seq_introPoint(WSAMovie_v2 *wsaObj, int x, int y, int frm) {
_seqTextColor[1] = 0xf7;
memset(_seqTextColorMap, _seqTextColor[1], 16);
- _seqTextColorMap[1] = _seqTextColor[0] = _screen->findLeastDifferentColor(_seqTextColorPresets + 3, _screen->getPalette(0) + 3, 255) & 0xff;
+ _seqTextColorMap[1] = _seqTextColor[0] = _screen->findLeastDifferentColor(_seqTextColorPresets + 3, _screen->getPalette(0), 1, 255) & 0xff;
_screen->setTextColorMap(_seqTextColorMap);
- _screen->generateGrayOverlay(_screen->getPalette(0), _screen->getPalette(3), 0x24, 0, 0, 0, 0x100, false);
+ _screen->generateGrayOverlay(_screen->getPalette(0), _screen->getPalette(3).getData(), 0x24, 0, 0, 0, 0x100, false);
break;
case 1:
@@ -661,7 +661,7 @@ int KyraEngine_HoF::seq_introZanfaun(WSAMovie_v2 *wsaObj, int x, int y, int frm)
_seqTextColor[1] = 0xfd;
memset(_seqTextColorMap, _seqTextColor[1], 16);
- _seqTextColorMap[1] = _seqTextColor[0] = _screen->findLeastDifferentColor(_seqTextColorPresets + 3, _screen->getPalette(0) + 3, 255) & 0xff;
+ _seqTextColorMap[1] = _seqTextColor[0] = _screen->findLeastDifferentColor(_seqTextColorPresets + 3, _screen->getPalette(0), 1, 255) & 0xff;
_screen->setTextColorMap(_seqTextColorMap);
break;
@@ -831,7 +831,7 @@ int KyraEngine_HoF::seq_finaleFunters(WSAMovie_v2 *wsaObj, int x, int y, int frm
case 0:
_sound->playTrack(3);
- _seqTextColor[1] = _screen->findLeastDifferentColor(_seqTextColorPresets, _screen->getPalette(0) + 3, 255) & 0xff;
+ _seqTextColor[1] = _screen->findLeastDifferentColor(_seqTextColorPresets, _screen->getPalette(0), 1, 255) & 0xff;
memset(_seqTextColorMap, _seqTextColor[1], 16);
_seqTextColor[0] = _seqTextColorMap[1] = 0xff;
_screen->setTextColorMap(_seqTextColorMap);
@@ -924,7 +924,7 @@ int KyraEngine_HoF::seq_finaleFerb(WSAMovie_v2 *wsaObj, int x, int y, int frm) {
break;
case 0:
- _seqTextColor[1] = _screen->findLeastDifferentColor(_seqTextColorPresets, _screen->getPalette(0) + 3, 255) & 0xff;
+ _seqTextColor[1] = _screen->findLeastDifferentColor(_seqTextColorPresets, _screen->getPalette(0), 1, 255) & 0xff;
memset(_seqTextColorMap, _seqTextColor[1], 16);
_seqTextColor[0] = _seqTextColorMap[1] = 255;
_screen->setTextColorMap(_seqTextColorMap);
@@ -1006,7 +1006,7 @@ int KyraEngine_HoF::seq_finaleFish(WSAMovie_v2 *wsaObj, int x, int y, int frm) {
break;
case 0:
- _seqTextColor[1] = _screen->findLeastDifferentColor(_seqTextColorPresets, _screen->getPalette(0) + 3, 255) & 0xff;
+ _seqTextColor[1] = _screen->findLeastDifferentColor(_seqTextColorPresets, _screen->getPalette(0), 1, 255) & 0xff;
memset(_seqTextColorMap, _seqTextColor[1], 16);
_seqTextColor[0] = _seqTextColorMap[1] = 0xff;
_screen->setTextColorMap(_seqTextColorMap);
@@ -1096,7 +1096,7 @@ int KyraEngine_HoF::seq_finaleFheep(WSAMovie_v2 *wsaObj, int x, int y, int frm)
break;
case 0:
- _seqTextColor[1] = _screen->findLeastDifferentColor(_seqTextColorPresets, _screen->getPalette(0) + 3, 255) & 0xff;
+ _seqTextColor[1] = _screen->findLeastDifferentColor(_seqTextColorPresets, _screen->getPalette(0), 1, 255) & 0xff;
memset(_seqTextColorMap, _seqTextColor[1], 16);
_seqTextColor[0] = _seqTextColorMap[1] = 0xff;
_screen->setTextColorMap(_seqTextColorMap);
@@ -1172,9 +1172,9 @@ int KyraEngine_HoF::seq_finaleFarmer(WSAMovie_v2 *wsaObj, int x, int y, int frm)
break;
case 0:
- _seqTextColor[1] = 1 + (_screen->findLeastDifferentColor(_seqTextColorPresets, _screen->getPalette(0) + 3, 254) & 0xff);
+ _seqTextColor[1] = 1 + (_screen->findLeastDifferentColor(_seqTextColorPresets, _screen->getPalette(0), 1, 254) & 0xff);
memset(_seqTextColorMap, _seqTextColor[1], 16);
- _seqTextColorMap[1] = _seqTextColor[0] = 1 + (_screen->findLeastDifferentColor(_seqTextColorPresets + 3, _screen->getPalette(0) + 3, 254) & 0xff);
+ _seqTextColorMap[1] = _seqTextColor[0] = 1 + (_screen->findLeastDifferentColor(_seqTextColorPresets + 3, _screen->getPalette(0), 1, 254) & 0xff);
_screen->setTextColorMap(_seqTextColorMap);
seq_playTalkText(_flags.isTalkie ? 30 : 26);
break;
@@ -1339,7 +1339,7 @@ int KyraEngine_HoF::seq_finaleFirates(WSAMovie_v2 *wsaObj, int x, int y, int frm
break;
case 0:
- _seqTextColor[1] = _screen->findLeastDifferentColor(_seqTextColorPresets, _screen->getPalette(0) + 3, 255) & 0xff;
+ _seqTextColor[1] = _screen->findLeastDifferentColor(_seqTextColorPresets, _screen->getPalette(0), 1, 255) & 0xff;
memset(_seqTextColorMap, _seqTextColor[1], 16);
_seqTextColor[0] = _seqTextColorMap[1] = 0xff;
_screen->setTextColorMap(_seqTextColorMap);
@@ -1426,7 +1426,7 @@ int KyraEngine_HoF::seq_finaleFrash(WSAMovie_v2 *wsaObj, int x, int y, int frm)
case 0:
if (_seqFrameCounter == 1) {
_sound->playTrack(4);
- _seqTextColor[1] = _screen->findLeastDifferentColor(_seqTextColorPresets, _screen->getPalette(0) + 3, 255) & 0xff;
+ _seqTextColor[1] = _screen->findLeastDifferentColor(_seqTextColorPresets, _screen->getPalette(0), 1, 255) & 0xff;
memset(_seqTextColorMap, _seqTextColor[1], 16);
_seqTextColor[0] = _seqTextColorMap[1] = 0xff;
_screen->setTextColorMap(_seqTextColorMap);
@@ -1501,7 +1501,7 @@ void KyraEngine_HoF::seq_finaleActorScreen() {
static const uint8 colormap[] = {0, 0, 102, 102, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
static const ScreenDim d = { 0x00, 0x0C, 0x28, 0xB4, 0xFF, 0x00, 0x00, 0x00 };
- _screen->loadBitmap("finale.cps", 3, 3, _screen->_currentPalette);
+ _screen->loadBitmap("finale.cps", 3, 3, &_screen->getPalette(0));
_screen->setFont(Screen::FID_GOLDFONT_FNT);
int talkieCreditsSize, talkieCreditsSpecialSize;
@@ -1781,19 +1781,21 @@ int KyraEngine_HoF::seq_demoDig(WSAMovie_v2 *wsaObj, int x, int y, int frm) {
#ifdef ENABLE_LOL
int KyraEngine_HoF::seq_lolDemoScene1(WSAMovie_v2 *wsaObj, int x, int y, int frm) {
- uint8 *tmpPal = _screen->getPalette(2);
+ Palette &tmpPal = _screen->getPalette(2);
if (!(_seqFrameCounter % 100)) {
if (_seqFrameCounter == 0) {
_sound->haltTrack();
_sound->playTrack(6);
}
- memcpy(tmpPal, _screen->getPalette(0), 0x300);
+ tmpPal.copy(_screen->getPalette(0));
+
for (int i = 3; i < 0x300; i++) {
tmpPal[i] = ((int)tmpPal[i] * 120) / 64;
if (tmpPal[i] > 0x3f)
tmpPal[i] = 0x3f;
}
+
seq_playTalkText(_rnd.getRandomBit());
_screen->setScreenPalette(tmpPal);
_screen->updateScreen();
@@ -1926,13 +1928,15 @@ int KyraEngine_HoF::seq_lolDemoScene6(WSAMovie_v2 *wsaObj, int x, int y, int frm
if (_seqFrameCounter % 175) {
_screen->setScreenPalette(_screen->getPalette(0));
} else {
- uint8 *tmpPal = _screen->getPalette(2);
- memcpy(tmpPal, _screen->getPalette(0), 0x300);
+ Palette &tmpPal = _screen->getPalette(2);
+ tmpPal.copy(_screen->getPalette(0));
+
for (int i = 3; i < 0x300; i++) {
tmpPal[i] = ((int)tmpPal[i] * 120) / 64;
if (tmpPal[i] > 0x3f)
tmpPal[i] = 0x3f;
}
+
seq_playTalkText(_rnd.getRandomBit());
_screen->setScreenPalette(tmpPal);
_screen->updateScreen();
@@ -2045,37 +2049,35 @@ char *KyraEngine_HoF::seq_preprocessString(const char *srcStr, int width) {
}
void KyraEngine_HoF::seq_sequenceCommand(int command) {
- uint8 pal[768];
-
for (int i = 0; i < 8; i++)
seq_resetActiveWSA(i);
switch (command) {
case 0:
- memset(pal, 0, 0x300);
- _screen->fadePalette(pal, 36);
- memcpy(_screen->getPalette(0), pal, 0x300);
- memcpy(_screen->getPalette(1), pal, 0x300);
+ _screen->fadeToBlack(36);
+ _screen->getPalette(0).clear();
+ _screen->getPalette(1).clear();
break;
case 1:
- memset(pal, 0x3F, 0x300);
seq_playTalkText(_rnd.getRandomBit());
- _screen->fadePalette(pal, 16);
- memcpy(_screen->getPalette(0), pal, 0x300);
- memcpy(_screen->getPalette(1), pal, 0x300);
+
+ _screen->getPalette(0).fill(0, 256, 0x3F);
+ _screen->fadePalette(_screen->getPalette(0), 16);
+
+ _screen->copyPalette(1, 0);
break;
case 3:
_screen->copyPage(2, 0);
_screen->fadePalette(_screen->getPalette(0), 16);
- memcpy(_screen->getPalette(1), _screen->getPalette(0), 0x300);
+ _screen->copyPalette(1, 0);
break;
case 4:
_screen->copyPage(2, 0);
_screen->fadePalette(_screen->getPalette(0), 36);
- memcpy(_screen->getPalette(1), _screen->getPalette(0), 0x300);
+ _screen->copyPalette(1, 0);
break;
case 5:
@@ -2093,17 +2095,17 @@ void KyraEngine_HoF::seq_sequenceCommand(int command) {
break;
case 8:
- memset(pal, 0, 0x300);
- _screen->fadePalette(pal, 16);
- memcpy(_screen->getPalette(0), pal, 0x300);
- memcpy(_screen->getPalette(1), pal, 0x300);
+ _screen->fadeToBlack(16);
+ _screen->getPalette(0).clear();
+ _screen->getPalette(1).clear();
delay(120 * _tickLength);
break;
- case 9:
- for (int i = 0; i < 0x100; i++) {
- int pv = (_screen->getPalette(0)[3 * i] + _screen->getPalette(0)[3 * i + 1] + _screen->getPalette(0)[3 * i + 2]) / 3;
+ case 9: {
+ Palette &pal = _screen->getPalette(0);
+ for (int i = 0; i < 256; i++) {
+ int pv = (pal[3 * i] + pal[3 * i + 1] + pal[3 * i + 2]) / 3;
pal[3 * i] = pal[3 * i + 1] = pal[3 * i + 2] = pv & 0xff;
}
@@ -2112,9 +2114,8 @@ void KyraEngine_HoF::seq_sequenceCommand(int command) {
//pal[3 * i] = pal[3 * i + 1] = pal[3 * i + 2] = 0x3f;
_screen->fadePalette(pal, 64);
- memcpy(_screen->getPalette(0), pal, 0x300);
- memcpy(_screen->getPalette(1), pal, 0x300);
- break;
+ _screen->copyPalette(1, 0);
+ } break;
default:
break;
@@ -2201,7 +2202,7 @@ void KyraEngine_HoF::seq_loadNestedSequence(int wsaNum, int seqNum) {
NestedSequence s = _sequences->seqn[seqNum];
if (!_activeWSA[wsaNum].movie) {
- _activeWSA[wsaNum].movie = new WSAMovie_v2(this, _screen);
+ _activeWSA[wsaNum].movie = new WSAMovie_v2(this);
assert(_activeWSA[wsaNum].movie);
}
@@ -2246,7 +2247,7 @@ void KyraEngine_HoF::seq_nestedSequenceFrame(int command, int wsaNum) {
case 0:
xa = -_activeWSA[wsaNum].movie->xAdd();
ya = -_activeWSA[wsaNum].movie->yAdd();
- _activeWSA[wsaNum].movie->displayFrame(0, 8, xa, ya, 0);
+ _activeWSA[wsaNum].movie->displayFrame(0, 8, xa, ya, 0, 0, 0);
seq_animatedSubFrame(8, 2, 7, 8, _activeWSA[wsaNum].movie->xAdd(), _activeWSA[wsaNum].movie->yAdd(),
_activeWSA[wsaNum].movie->width(), _activeWSA[wsaNum].movie->height(), 1, 2);
break;
@@ -2254,7 +2255,7 @@ void KyraEngine_HoF::seq_nestedSequenceFrame(int command, int wsaNum) {
case 1:
xa = -_activeWSA[wsaNum].movie->xAdd();
ya = -_activeWSA[wsaNum].movie->yAdd();
- _activeWSA[wsaNum].movie->displayFrame(0, 8, xa, ya, 0);
+ _activeWSA[wsaNum].movie->displayFrame(0, 8, xa, ya, 0, 0, 0);
seq_animatedSubFrame(8, 2, 7, 8, _activeWSA[wsaNum].movie->xAdd(), _activeWSA[wsaNum].movie->yAdd(),
_activeWSA[wsaNum].movie->width(), _activeWSA[wsaNum].movie->height(), 1, 1);
break;
@@ -2263,21 +2264,21 @@ void KyraEngine_HoF::seq_nestedSequenceFrame(int command, int wsaNum) {
seq_waitForTextsTimeout();
xa = -_activeWSA[wsaNum].movie->xAdd();
ya = -_activeWSA[wsaNum].movie->yAdd();
- _activeWSA[wsaNum].movie->displayFrame(0x15, 8, xa, ya, 0);
+ _activeWSA[wsaNum].movie->displayFrame(0x15, 8, xa, ya, 0, 0, 0);
seq_animatedSubFrame(8, 2, 7, 8, _activeWSA[wsaNum].movie->xAdd(), _activeWSA[wsaNum].movie->yAdd(),
_activeWSA[wsaNum].movie->width(), _activeWSA[wsaNum].movie->height(), 0, 2);
break;
case 3:
_screen->copyPage(2, 10);
- _activeWSA[wsaNum].movie->displayFrame(0, 2, 0, 0, 0);
+ _activeWSA[wsaNum].movie->displayFrame(0, 2, 0, 0, 0, 0, 0);
_screen->copyPage(2, 12);
seq_cmpFadeFrame("scene2.cmp");
break;
case 4:
_screen->copyPage(2, 10);
- _activeWSA[wsaNum].movie->displayFrame(0, 2, 0, 0, 0);
+ _activeWSA[wsaNum].movie->displayFrame(0, 2, 0, 0, 0, 0, 0);
_screen->copyPage(2, 12);
seq_cmpFadeFrame("scene3.cmp");
break;
@@ -2364,10 +2365,10 @@ bool KyraEngine_HoF::seq_processNextSubFrame(int wsaNum) {
if (_activeWSA[wsaNum].movie) {
if (_activeWSA[wsaNum].flags & 0x20) {
- _activeWSA[wsaNum].movie->displayFrame(_activeWSA[wsaNum].control[currentFrame].index, 2, _activeWSA[wsaNum].x, _activeWSA[wsaNum].y, 0x4000);
+ _activeWSA[wsaNum].movie->displayFrame(_activeWSA[wsaNum].control[currentFrame].index, 2, _activeWSA[wsaNum].x, _activeWSA[wsaNum].y, 0x4000, 0, 0);
_activeWSA[wsaNum].frameDelay = _activeWSA[wsaNum].control[currentFrame].delay;
} else {
- _activeWSA[wsaNum].movie->displayFrame(currentFrame % _activeWSA[wsaNum].movie->frames(), 2, _activeWSA[wsaNum].x, _activeWSA[wsaNum].y, 0x4000);
+ _activeWSA[wsaNum].movie->displayFrame(currentFrame % _activeWSA[wsaNum].movie->frames(), 2, _activeWSA[wsaNum].x, _activeWSA[wsaNum].y, 0x4000, 0, 0);
}
}
@@ -2477,7 +2478,7 @@ void KyraEngine_HoF::seq_playWsaSyncDialogue(uint16 strIndex, uint16 vocIndex, i
_seqWsaChatFrameTimeout = _seqEndTime = _system->getMillis() + _seqFrameDelay * _tickLength;
if (wsa)
- wsa->displayFrame(curframe % wsa->frames(), 2, wsaXpos, wsaYpos, 0);
+ wsa->displayFrame(curframe % wsa->frames(), 2, wsaXpos, wsaYpos, 0, 0, 0);
_screen->copyPage(2, 12);
@@ -2663,9 +2664,9 @@ void KyraEngine_HoF::seq_displayScrollText(uint8 *data, const ScreenDim *d, int
if (palCycle) {
for (int col = 133; col > 112; col--)
- memcpy(_screen->_currentPalette + (col * 3), _screen->_currentPalette + ((col - 1) * 3), 3);
- memcpy(_screen->_currentPalette + 336, _screen->_currentPalette + 399, 3);
- _screen->setScreenPalette(_screen->_currentPalette);
+ _screen->getPalette(0).copy(_screen->getPalette(0), col - 1, 1, col);
+ _screen->getPalette(0).copy(_screen->getPalette(0), 133, 1, 112);
+ _screen->setScreenPalette(_screen->getPalette(0));
}
delayUntil(_seqSubFrameEndTimeInternal);
@@ -2721,32 +2722,32 @@ void KyraEngine_HoF::seq_scrollPage(int bottom, int top) {
}
void KyraEngine_HoF::seq_showStarcraftLogo() {
- WSAMovie_v2 *ci = new WSAMovie_v2(this, _screen);
+ WSAMovie_v2 *ci = new WSAMovie_v2(this);
assert(ci);
_screen->clearPage(2);
_res->loadPakFile("INTROGEN.PAK");
- int endframe = ci->open("ci.wsa", 0, _screen->_currentPalette);
+ int endframe = ci->open("ci.wsa", 0, &_screen->getPalette(0));
_res->unloadPakFile("INTROGEN.PAK");
if (!ci->opened()) {
delete ci;
return;
}
_screen->hideMouse();
- ci->displayFrame(0, 2, 0, 0, 0);
+ ci->displayFrame(0, 2, 0, 0, 0, 0, 0);
_screen->copyPage(2, 0);
_screen->fadeFromBlack();
for (int i = 1; i < endframe; i++) {
_seqEndTime = _system->getMillis() + 50;
if (skipFlag())
break;
- ci->displayFrame(i, 2, 0, 0, 0);
+ ci->displayFrame(i, 2, 0, 0, 0, 0, 0);
_screen->copyPage(2, 0);
_screen->updateScreen();
delay(_seqEndTime - _system->getMillis());
}
if (!skipFlag()) {
_seqEndTime = _system->getMillis() + 50;
- ci->displayFrame(0, 2, 0, 0, 0);
+ ci->displayFrame(0, 2, 0, 0, 0, 0, 0);
_screen->copyPage(2, 0);
_screen->updateScreen();
delay(_seqEndTime - _system->getMillis());
@@ -2760,7 +2761,7 @@ void KyraEngine_HoF::seq_showStarcraftLogo() {
void KyraEngine_HoF::seq_init() {
_seqProcessedString = new char[200];
- _seqWsa = new WSAMovie_v2(this, _screen);
+ _seqWsa = new WSAMovie_v2(this);
_activeWSA = new ActiveWSA[8];
_activeText = new ActiveText[10];
diff --git a/engines/kyra/sequences_lok.cpp b/engines/kyra/sequences_lok.cpp
index 12ede98ad4..d483409090 100644
--- a/engines/kyra/sequences_lok.cpp
+++ b/engines/kyra/sequences_lok.cpp
@@ -42,7 +42,7 @@ namespace Kyra {
void KyraEngine_LoK::seq_demo() {
snd_playTheme(0, 2);
- _screen->loadBitmap("START.CPS", 7, 7, _screen->_currentPalette);
+ _screen->loadBitmap("START.CPS", 7, 7, &_screen->getPalette(0));
_screen->copyRegion(0, 0, 0, 0, 320, 200, 6, 0, Screen::CR_NO_P_CHECK);
_screen->updateScreen();
_screen->fadeFromBlack();
@@ -50,8 +50,8 @@ void KyraEngine_LoK::seq_demo() {
_screen->fadeToBlack();
_screen->clearPage(0);
- _screen->loadBitmap("TOP.CPS", 7, 7, NULL);
- _screen->loadBitmap("BOTTOM.CPS", 5, 5, _screen->_currentPalette);
+ _screen->loadBitmap("TOP.CPS", 7, 7, 0);
+ _screen->loadBitmap("BOTTOM.CPS", 5, 5, &_screen->getPalette(0));
_screen->copyRegion(0, 91, 0, 8, 320, 103, 6, 0);
_screen->copyRegion(0, 0, 0, 111, 320, 64, 6, 0);
_screen->updateScreen();
@@ -77,7 +77,7 @@ void KyraEngine_LoK::seq_demo() {
_seq->playSequence(_seq_Demo4, true);
_screen->clearPage(0);
- _screen->loadBitmap("FINAL.CPS", 7, 7, _screen->_currentPalette);
+ _screen->loadBitmap("FINAL.CPS", 7, 7, &_screen->getPalette(0));
_screen->_curPage = 0;
_screen->copyRegion(0, 0, 0, 0, 320, 200, 6, 0);
_screen->updateScreen();
@@ -128,7 +128,7 @@ void KyraEngine_LoK::seq_intro() {
void KyraEngine_LoK::seq_introLogos() {
if (_flags.platform == Common::kPlatformFMTowns || _flags.platform == Common::kPlatformPC98) {
- _screen->loadBitmap("LOGO.CPS", 3, 3, _screen->_currentPalette);
+ _screen->loadBitmap("LOGO.CPS", 3, 3, &_screen->getPalette(0));
_screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 0);
_screen->updateScreen();
_screen->fadeFromBlack();
@@ -141,7 +141,7 @@ void KyraEngine_LoK::seq_introLogos() {
_screen->clearPage(0);
if (_flags.platform == Common::kPlatformAmiga) {
- _screen->loadPalette("INTRO.PAL", _screen->_currentPalette);
+ _screen->loadPaletteTable("INTRO.PAL", 0);
_screen->loadBitmap("BOTTOM.CPS", 3, 5, 0);
_screen->loadBitmap("TOP.CPS", 3, 3, 0);
_screen->copyRegion(0, 0, 0, 111, 320, 64, 2, 0);
@@ -149,7 +149,7 @@ void KyraEngine_LoK::seq_introLogos() {
_screen->copyRegion(0, 0, 0, 0, 320, 190, 0, 2);
} else {
_screen->loadBitmap("TOP.CPS", 7, 7, 0);
- _screen->loadBitmap("BOTTOM.CPS", 5, 5, _screen->_currentPalette);
+ _screen->loadBitmap("BOTTOM.CPS", 5, 5, &_screen->getPalette(0));
_screen->copyRegion(0, 91, 0, 8, 320, 103, 6, 0);
_screen->copyRegion(0, 0, 0, 111, 320, 64, 6, 0);
}
@@ -166,8 +166,8 @@ void KyraEngine_LoK::seq_introLogos() {
delay(60 * _tickLength);
if (_flags.platform == Common::kPlatformAmiga) {
- memcpy(_screen->_currentPalette, _screen->_currentPalette + 3*32, 3*32);
- _screen->setScreenPalette(_screen->_currentPalette);
+ _screen->copyPalette(0, 1);
+ _screen->setScreenPalette(_screen->getPalette(0));
}
if ((_seq->playSequence(_seq_KyrandiaLogo, skipFlag()) && !seq_skipSequence()) || shouldQuit()) {
@@ -181,7 +181,7 @@ void KyraEngine_LoK::seq_introLogos() {
return;
if (_flags.platform == Common::kPlatformAmiga) {
- memcpy(_screen->_currentPalette, _screen->_currentPalette + 3*64, 3*32);
+ _screen->copyPalette(0, 2);
_screen->fadeToBlack();
_screen->copyRegion(0, 0, 0, 0, 320, 200, 4, 0);
_screen->fadeFromBlack();
@@ -236,22 +236,22 @@ void KyraEngine_LoK::seq_introStory() {
return;
if (_flags.lang == Common::EN_ANY && !_flags.isTalkie && (_flags.platform == Common::kPlatformPC || _flags.platform == Common::kPlatformAmiga))
- _screen->loadBitmap("TEXT.CPS", 3, 3, _screen->_currentPalette);
+ _screen->loadBitmap("TEXT.CPS", 3, 3, &_screen->getPalette(0));
else if (_flags.lang == Common::EN_ANY || _flags.lang == Common::JA_JPN)
- _screen->loadBitmap("TEXT_ENG.CPS", 3, 3, _screen->_currentPalette);
+ _screen->loadBitmap("TEXT_ENG.CPS", 3, 3, &_screen->getPalette(0));
else if (_flags.lang == Common::DE_DEU)
- _screen->loadBitmap("TEXT_GER.CPS", 3, 3, _screen->_currentPalette);
+ _screen->loadBitmap("TEXT_GER.CPS", 3, 3, &_screen->getPalette(0));
else if (_flags.lang == Common::FR_FRA)
- _screen->loadBitmap("TEXT_FRE.CPS", 3, 3, _screen->_currentPalette);
+ _screen->loadBitmap("TEXT_FRE.CPS", 3, 3, &_screen->getPalette(0));
else if (_flags.lang == Common::ES_ESP)
- _screen->loadBitmap("TEXT_SPA.CPS", 3, 3, _screen->_currentPalette);
+ _screen->loadBitmap("TEXT_SPA.CPS", 3, 3, &_screen->getPalette(0));
else if (_flags.lang == Common::IT_ITA && !_flags.isTalkie)
- _screen->loadBitmap("TEXT_ITA.CPS", 3, 3, _screen->_currentPalette);
+ _screen->loadBitmap("TEXT_ITA.CPS", 3, 3, &_screen->getPalette(0));
else if (_flags.lang == Common::IT_ITA && _flags.isTalkie)
- _screen->loadBitmap("TEXT_ENG.CPS", 3, 3, _screen->_currentPalette);
+ _screen->loadBitmap("TEXT_ENG.CPS", 3, 3, &_screen->getPalette(0));
else
warning("no story graphics file found");
- _screen->setScreenPalette(_screen->_currentPalette);
+ _screen->setScreenPalette(_screen->getPalette(0));
_screen->copyRegion(0, 0, 0, 0, 320, 200, 3, 0);
if (_flags.lang == Common::JA_JPN) {
@@ -569,12 +569,9 @@ void KyraEngine_LoK::seq_winterScroll1() {
_sprites->_anims[i].play = false;
_animator->sprites()[i].active = 0;
}
- uint8 tmpPal[768];
- memcpy(tmpPal, _screen->_currentPalette, 768);
- memcpy(&tmpPal[684], palTable2()[0], 60);
- _screen->fadePalette(tmpPal, 72);
- memcpy(&_screen->_currentPalette[684], palTable2()[0], 60);
- _screen->setScreenPalette(_screen->_currentPalette);
+ _screen->getPalette(0).copy(palTable2()[0], 0, 20, 228);
+ _screen->fadePalette(_screen->getPalette(0), 72);
+ _screen->setScreenPalette(_screen->getPalette(0));
setGameFlag(0xB3);
} else {
delayWithTicks(120);
@@ -950,8 +947,8 @@ int KyraEngine_LoK::seq_playEnd() {
_screen->hideMouse();
_screen->fadeSpecialPalette(32, 228, 20, 60);
delay(60 * _tickLength);
- _screen->loadBitmap("GEMHEAL.CPS", 3, 3, _screen->_currentPalette);
- _screen->setScreenPalette(_screen->_currentPalette);
+ _screen->loadBitmap("GEMHEAL.CPS", 3, 3, &_screen->getPalette(0));
+ _screen->setScreenPalette(_screen->getPalette(0));
_screen->shuffleScreen(8, 8, 304, 128, 2, 0, 1, 0);
uint32 nextTime = _system->getMillis() + 120 * _tickLength;
_finalA = new WSAMovie_v1(this);
@@ -966,7 +963,7 @@ int KyraEngine_LoK::seq_playEnd() {
else if (i == 20)
snd_playSoundEffect(0x0E);
nextTime = _system->getMillis() + 8 * _tickLength;
- _finalA->displayFrame(i, 0, 8, 8);
+ _finalA->displayFrame(i, 0, 8, 8, 0, 0, 0);
_screen->updateScreen();
}
delete _finalA;
@@ -1004,14 +1001,14 @@ void KyraEngine_LoK::seq_playEnding() {
_screen->hideMouse();
_screen->_curPage = 0;
_screen->fadeToBlack();
- _screen->loadBitmap("REUNION.CPS", 3, 3, _screen->_currentPalette);
+ _screen->loadBitmap("REUNION.CPS", 3, 3, &_screen->getPalette(0));
_screen->copyRegion(8, 8, 8, 8, 304, 128, 2, 0);
_screen->_curPage = 0;
// XXX
assert(_homeString);
drawSentenceCommand(_homeString[0], 179);
- memset(_screen->getPalette(2), 0, sizeof(uint8)*768);
+ _screen->getPalette(2).clear();
_screen->setScreenPalette(_screen->getPalette(2));
_seqPlayerFlag = true;
@@ -1045,7 +1042,7 @@ void KyraEngine_LoK::seq_playCredits() {
} else
_screen->setFont(Screen::FID_8_FNT);
- _screen->loadBitmap("CHALET.CPS", 4, 4, _screen->_currentPalette);
+ _screen->loadBitmap("CHALET.CPS", 4, 4, &_screen->getPalette(0));
_screen->setCurPage(0);
_screen->clearCurPage();
@@ -1123,10 +1120,10 @@ void KyraEngine_LoK::seq_playCredits() {
_screen->setCurPage(2);
- memset(_screen->getPalette(2), 0, sizeof(uint8)*768);
+ _screen->getPalette(2).clear();
_screen->setScreenPalette(_screen->getPalette(2));
_screen->copyRegion(8, 32, 8, 32, 312, 128, 4, 0, Screen::CR_NO_P_CHECK);
- _screen->fadePalette(_screen->_currentPalette, 0x5A);
+ _screen->fadePalette(_screen->getPalette(0), 0x5A);
Common::Event event;
bool finished = false;
@@ -1198,7 +1195,7 @@ int KyraEngine_LoK::handleMalcolmFlag() {
case 2:
if (_system->getMillis() >= timer2) {
- _finalA->displayFrame(frame, 0, 8, 46);
+ _finalA->displayFrame(frame, 0, 8, 46, 0, 0, 0);
_screen->updateScreen();
timer2 = _system->getMillis() + 8 * _tickLength;
++frame;
@@ -1213,7 +1210,7 @@ int KyraEngine_LoK::handleMalcolmFlag() {
if (_system->getMillis() < timer1) {
if (_system->getMillis() >= timer2) {
frame = _rnd.getRandomNumberRng(14, 17);
- _finalA->displayFrame(frame, 0, 8, 46);
+ _finalA->displayFrame(frame, 0, 8, 46, 0, 0, 0);
_screen->updateScreen();
timer2 = _system->getMillis() + 8 * _tickLength;
}
@@ -1225,7 +1222,7 @@ int KyraEngine_LoK::handleMalcolmFlag() {
case 4:
if (_system->getMillis() >= timer2) {
- _finalA->displayFrame(frame, 0, 8, 46);
+ _finalA->displayFrame(frame, 0, 8, 46, 0, 0, 0);
_screen->updateScreen();
timer2 = _system->getMillis() + 8 * _tickLength;
++frame;
@@ -1239,7 +1236,7 @@ int KyraEngine_LoK::handleMalcolmFlag() {
case 5:
if (_system->getMillis() >= timer2) {
- _finalA->displayFrame(frame, 0, 8, 46);
+ _finalA->displayFrame(frame, 0, 8, 46, 0, 0, 0);
_screen->updateScreen();
timer2 = _system->getMillis() + 8 * _tickLength;
++frame;
@@ -1253,7 +1250,7 @@ int KyraEngine_LoK::handleMalcolmFlag() {
case 6:
if (_unkEndSeqVar4) {
if (frame <= 33 && _system->getMillis() >= timer2) {
- _finalA->displayFrame(frame, 0, 8, 46);
+ _finalA->displayFrame(frame, 0, 8, 46, 0, 0, 0);
_screen->updateScreen();
timer2 = _system->getMillis() + 8 * _tickLength;
++frame;
@@ -1278,7 +1275,7 @@ int KyraEngine_LoK::handleMalcolmFlag() {
case 8:
if (_system->getMillis() >= timer2) {
- _finalA->displayFrame(frame, 0, 8, 46);
+ _finalA->displayFrame(frame, 0, 8, 46, 0, 0, 0);
_screen->updateScreen();
timer2 = _system->getMillis() + 8 * _tickLength;
++frame;
@@ -1295,7 +1292,7 @@ int KyraEngine_LoK::handleMalcolmFlag() {
snd_playSoundEffect(12);
for (int i = 0; i < 18; ++i) {
timer2 = _system->getMillis() + 4 * _tickLength;
- _finalC->displayFrame(i, 0, 16, 50);
+ _finalC->displayFrame(i, 0, 16, 50, 0, 0, 0);
_screen->updateScreen();
delayUntil(timer2);
}
@@ -1353,7 +1350,7 @@ int KyraEngine_LoK::handleBeadState() {
switch (_beadStateVar) {
case 0:
if (beadState1.x != -1 && _endSequenceBackUpRect) {
- _screen->copyFromCurPageBlock(beadState1.x >> 3, beadState1.y, beadState1.width, beadState1.height, _endSequenceBackUpRect);
+ _screen->copyBlockToPage(_screen->_curPage, beadState1.x, beadState1.y, beadState1.width << 3, beadState1.height, _endSequenceBackUpRect);
_screen->addBitBlitRect(beadState1.x, beadState1.y, beadState1.width2, beadState1.height);
}
@@ -1367,7 +1364,7 @@ int KyraEngine_LoK::handleBeadState() {
case 1:
if (beadState1.x != -1) {
if (_endSequenceBackUpRect) {
- _screen->copyFromCurPageBlock(beadState1.x >> 3, beadState1.y, beadState1.width, beadState1.height, _endSequenceBackUpRect);
+ _screen->copyBlockToPage(_screen->_curPage, beadState1.x, beadState1.y, beadState1.width << 3, beadState1.height, _endSequenceBackUpRect);
_screen->addBitBlitRect(beadState1.x, beadState1.y, beadState1.width2, beadState1.height);
}
beadState1.x = -1;
@@ -1402,14 +1399,14 @@ int KyraEngine_LoK::handleBeadState() {
beadState1.dstY = beadState1.y;
return 0;
} else {
- _screen->copyFromCurPageBlock(beadState1.x >> 3, beadState1.y, beadState1.width, beadState1.height, _endSequenceBackUpRect);
+ _screen->copyBlockToPage(_screen->_curPage, beadState1.x, beadState1.y, beadState1.width << 3, beadState1.height, _endSequenceBackUpRect);
_screen->addBitBlitRect(beadState1.x, beadState1.y, beadState1.width2, beadState1.height);
beadState1.x = x;
beadState1.y = y;
}
}
- _screen->copyCurPageBlock(x >> 3, y, beadState1.width, beadState1.height, _endSequenceBackUpRect);
+ _screen->copyRegionToBuffer(_screen->_curPage, x, y, beadState1.width << 3, beadState1.height, _endSequenceBackUpRect);
_screen->drawShape(2, _panPagesTable[_lastDisplayedPanPage++], x, y, 0, 0);
if (_lastDisplayedPanPage > 17)
@@ -1422,12 +1419,12 @@ int KyraEngine_LoK::handleBeadState() {
case 3:
if (_system->getMillis() >= timer1) {
timer1 = _system->getMillis() + 4 * _tickLength;
- _screen->copyFromCurPageBlock(beadState1.x >> 3, beadState1.y, beadState1.width, beadState1.height, _endSequenceBackUpRect);
+ _screen->copyBlockToPage(_screen->_curPage, beadState1.x, beadState1.y, beadState1.width << 3, beadState1.height, _endSequenceBackUpRect);
_screen->addBitBlitRect(beadState1.x, beadState1.y, beadState1.width2, beadState1.height);
beadState1.x = beadState1.dstX + table1[beadState1.tableIndex];
beadState1.y = beadState1.dstY + table2[beadState1.tableIndex];
- _screen->copyCurPageBlock(beadState1.x >> 3, beadState1.y, beadState1.width, beadState1.height, _endSequenceBackUpRect);
+ _screen->copyRegionToBuffer(_screen->_curPage, beadState1.x, beadState1.y, beadState1.width << 3, beadState1.height, _endSequenceBackUpRect);
_screen->drawShape(2, _panPagesTable[_lastDisplayedPanPage++], beadState1.x, beadState1.y, 0, 0);
if (_lastDisplayedPanPage >= 17)
@@ -1476,11 +1473,11 @@ int KyraEngine_LoK::handleBeadState() {
_beadStateVar = 0;
}
} else {
- _screen->copyFromCurPageBlock(beadState1.x >> 3, beadState1.y, beadState1.width, beadState1.height, _endSequenceBackUpRect);
+ _screen->copyBlockToPage(_screen->_curPage, beadState1.x >> 3, beadState1.y, beadState1.width, beadState1.height, _endSequenceBackUpRect);
_screen->addBitBlitRect(beadState1.x, beadState1.y, beadState1.width2, beadState1.height);
beadState1.x = x;
beadState1.y = y;
- _screen->copyCurPageBlock(beadState1.x >> 3, beadState1.y, beadState1.width, beadState1.height, _endSequenceBackUpRect);
+ _screen->copyRegionToBuffer(_screen->_curPage, beadState1.x, beadState1.y, beadState1.width << 3, beadState1.height, _endSequenceBackUpRect);
_screen->drawShape(2, _panPagesTable[_lastDisplayedPanPage++], x, y, 0, 0);
if (_lastDisplayedPanPage > 17) {
_lastDisplayedPanPage = 0;
@@ -1496,24 +1493,24 @@ int KyraEngine_LoK::handleBeadState() {
int x = 0, y = 0;
if (processBead(beadState1.x, beadState1.y, x, y, &beadState2)) {
if (beadState2.dstX == 290) {
- _screen->copyFromCurPageBlock(beadState1.x >> 3, beadState1.y, beadState1.width, beadState1.height, _endSequenceBackUpRect);
+ _screen->copyBlockToPage(_screen->_curPage, beadState1.x, beadState1.y, beadState1.width << 3, beadState1.height, _endSequenceBackUpRect);
uint32 nextRun = 0;
for (int i = 0; i < 8; ++i) {
nextRun = _system->getMillis() + _tickLength;
- _finalB->displayFrame(i, 0, 224, 8);
+ _finalB->displayFrame(i, 0, 224, 8, 0, 0, 0);
_screen->updateScreen();
delayUntil(nextRun);
}
snd_playSoundEffect(0x0D);
for (int i = 7; i >= 0; --i) {
nextRun = _system->getMillis() + _tickLength;
- _finalB->displayFrame(i, 0, 224, 8);
+ _finalB->displayFrame(i, 0, 224, 8, 0, 0, 0);
_screen->updateScreen();
delayUntil(nextRun);
}
initBeadState(beadState1.x, beadState1.y, 63, 60, 12, &beadState2);
} else {
- _screen->copyFromCurPageBlock(beadState1.x >> 3, beadState1.y, beadState1.width, beadState1.height, _endSequenceBackUpRect);
+ _screen->copyBlockToPage(_screen->_curPage, beadState1.x, beadState1.y, beadState1.width << 3, beadState1.height, _endSequenceBackUpRect);
_screen->addBitBlitRect(beadState1.x, beadState1.y, beadState1.width2, beadState1.height);
beadState1.x = -1;
beadState1.tableIndex = 0;
@@ -1521,11 +1518,11 @@ int KyraEngine_LoK::handleBeadState() {
_malcolmFlag = 9;
}
} else {
- _screen->copyFromCurPageBlock(beadState1.x >> 3, beadState1.y, beadState1.width, beadState1.height, _endSequenceBackUpRect);
+ _screen->copyBlockToPage(_screen->_curPage, beadState1.x, beadState1.y, beadState1.width << 3, beadState1.height, _endSequenceBackUpRect);
_screen->addBitBlitRect(beadState1.x, beadState1.y, beadState1.width2, beadState1.height);
beadState1.x = x;
beadState1.y = y;
- _screen->copyCurPageBlock(beadState1.x >> 3, beadState1.y, beadState1.width, beadState1.height, _endSequenceBackUpRect);
+ _screen->copyRegionToBuffer(_screen->_curPage, beadState1.x, beadState1.y, beadState1.width << 3, beadState1.height, _endSequenceBackUpRect);
_screen->drawShape(2, _panPagesTable[_lastDisplayedPanPage++], x, y, 0, 0);
if (_lastDisplayedPanPage > 17)
_lastDisplayedPanPage = 0;
@@ -1679,11 +1676,11 @@ void KyraEngine_LoK::updateKyragemFading() {
_kyragemFadingState.timerCount = _system->getMillis() + 4 * _tickLength;
int palPos = 684;
for (int i = 0; i < 20; ++i) {
- _screen->_currentPalette[palPos++] = kyraGemPalette[i + _kyragemFadingState.rOffset];
- _screen->_currentPalette[palPos++] = kyraGemPalette[i + _kyragemFadingState.gOffset];
- _screen->_currentPalette[palPos++] = kyraGemPalette[i + _kyragemFadingState.bOffset];
+ _screen->getPalette(0)[palPos++] = kyraGemPalette[i + _kyragemFadingState.rOffset];
+ _screen->getPalette(0)[palPos++] = kyraGemPalette[i + _kyragemFadingState.gOffset];
+ _screen->getPalette(0)[palPos++] = kyraGemPalette[i + _kyragemFadingState.bOffset];
}
- _screen->setScreenPalette(_screen->_currentPalette);
+ _screen->setScreenPalette(_screen->getPalette(0));
_animator->_updateScreen = true;
switch (_kyragemFadingState.nextOperation) {
case 0:
diff --git a/engines/kyra/sequences_lol.cpp b/engines/kyra/sequences_lol.cpp
index 849a325560..beea129f66 100644
--- a/engines/kyra/sequences_lol.cpp
+++ b/engines/kyra/sequences_lol.cpp
@@ -43,7 +43,7 @@ int LoLEngine::processPrologue() {
if (_flags.isDemo) {
_screen->fadePalette(_screen->getPalette(1), 30, 0);
- _screen->loadBitmap("FINAL.CPS", 2, 2, _screen->getPalette(0));
+ _screen->loadBitmap("FINAL.CPS", 2, 2, &_screen->getPalette(0));
_screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 0, Screen::CR_NO_P_CHECK);
_screen->fadePalette(_screen->getPalette(0), 30, 0);
delayWithTicks(300);
@@ -57,7 +57,7 @@ int LoLEngine::processPrologue() {
int processSelection = -1;
while (!shouldQuit() && processSelection == -1) {
- _screen->loadBitmap("TITLE.CPS", 2, 2, _screen->getPalette(0));
+ _screen->loadBitmap("TITLE.CPS", 2, 2, &_screen->getPalette(0));
_screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 0, Screen::CR_NO_P_CHECK);
_screen->setFont(Screen::FID_6_FNT);
@@ -71,11 +71,14 @@ int LoLEngine::processPrologue() {
_eventList.clear();
int selection = mainMenu();
- _screen->hideMouse();
- // Unlike the original, we add a nice fade to black
- memset(_screen->getPalette(0), 0, 768);
- _screen->fadePalette(_screen->getPalette(0), 0x54);
+ if (selection != 3) {
+ _screen->hideMouse();
+
+ // Unlike the original, we add a nice fade to black
+ _screen->getPalette(0).clear();
+ _screen->fadeToBlack(0x54);
+ }
switch (selection) {
case 0: // New game
@@ -90,7 +93,8 @@ int LoLEngine::processPrologue() {
break;
case 3: // Load game
- //processSelection = 3;
+ if (_gui->runMenu(_gui->_loadMenu))
+ processSelection = 3;
break;
case 4: // Quit game
@@ -100,7 +104,7 @@ int LoLEngine::processPrologue() {
}
}
- if (processSelection == 0 || processSelection == 3) {
+ if (processSelection == 0) {
_sound->loadSoundFile(0);
_sound->playTrack(6);
chooseCharacter();
@@ -131,7 +135,6 @@ void LoLEngine::setupPrologueData(bool load) {
const char * const *fileList = _flags.isTalkie ? fileListCD :
(_flags.useInstallerPackage ? fileListFloppy : fileListFloppyExtracted);
-
char filename[32];
for (uint i = 0; fileList[i]; ++i) {
filename[0] = '\0';
@@ -155,7 +158,7 @@ void LoLEngine::setupPrologueData(bool load) {
_screen->clearPage(3);
if (load) {
- _chargenWSA = new WSAMovie_v2(this, _screen);
+ _chargenWSA = new WSAMovie_v2(this);
assert(_chargenWSA);
//_charSelection = -1;
@@ -165,7 +168,7 @@ void LoLEngine::setupPrologueData(bool load) {
_selectionAnimFrames[1] = _selectionAnimFrames[3] = 1;
memset(_selectionAnimTimers, 0, sizeof(_selectionAnimTimers));
- memset(_screen->getPalette(1), 0, 768);
+ _screen->getPalette(1).clear();
_sound->setSoundList(&_soundData[kMusicIntro]);
@@ -181,9 +184,8 @@ void LoLEngine::setupPrologueData(bool load) {
} else {
delete _chargenWSA; _chargenWSA = 0;
- uint8 *pal = _screen->getPalette(0);
- memset(pal, 0, 768);
- _screen->setScreenPalette(pal);
+ _screen->getPalette(0).clear();
+ _screen->setScreenPalette(_screen->getPalette(0));
if (shouldQuit())
return;
@@ -200,9 +202,8 @@ void LoLEngine::showIntro() {
if (_flags.platform == Common::kPlatformPC98)
showStarcraftLogo();
- uint8 *pal = _screen->getPalette(0);
- memset(pal, 0, 768);
- _screen->setScreenPalette(pal);
+ _screen->getPalette(0).clear();
+ _screen->setScreenPalette(_screen->getPalette(0));
_screen->clearPage(0);
_screen->clearPage(4);
@@ -274,8 +275,8 @@ int LoLEngine::chooseCharacter() {
while (!_screen->isMouseVisible())
_screen->showMouse();
- _screen->loadBitmap("CHAR.CPS", 2, 2, _screen->getPalette(0));
- _screen->loadBitmap("BACKGRND.CPS", 4, 4, _screen->getPalette(0));
+ _screen->loadBitmap("CHAR.CPS", 2, 2, &_screen->getPalette(0));
+ _screen->loadBitmap("BACKGRND.CPS", 4, 4, &_screen->getPalette(0));
if (!_chargenWSA->open("CHARGEN.WSA", 1, 0))
error("Couldn't load CHARGEN.WSA");
@@ -368,7 +369,7 @@ void LoLEngine::kingSelectionIntro() {
_sound->voicePlay("KING01", &_speechHandle);
int index = 4;
- while ((!_speechFlag || (_speechFlag && _sound->voiceIsPlaying(&_speechHandle))) && _charSelection == -1 && !shouldQuit() && !skipFlag()) {
+ while ((!speechEnabled() || (speechEnabled() && _sound->voiceIsPlaying(&_speechHandle))) && _charSelection == -1 && !shouldQuit() && !skipFlag()) {
index = MAX(index, 4);
_chargenWSA->displayFrame(_chargenFrameTable[index], 0, 113, 0, 0, 0, 0);
@@ -384,7 +385,7 @@ void LoLEngine::kingSelectionIntro() {
_system->delayMillis(10);
}
- if (_speechFlag)
+ if (speechEnabled())
index = (index + 1) % 22;
else if (++index >= 27)
break;
@@ -407,7 +408,7 @@ void LoLEngine::kingSelectionReminder() {
_sound->voicePlay("KING02", &_speechHandle);
int index = 0;
- while ((!_speechFlag || (_speechFlag && _sound->voiceIsPlaying(&_speechHandle))) && _charSelection == -1 && !shouldQuit() && index < 15) {
+ while ((!speechEnabled() || (speechEnabled() && _sound->voiceIsPlaying(&_speechHandle))) && _charSelection == -1 && !shouldQuit() && index < 15) {
_chargenWSA->displayFrame(_chargenFrameTable[index+9], 0, 113, 0, 0, 0, 0);
_screen->copyRegion(_selectionPosTable[_reminderChar1IdxTable[index]*2+0], _selectionPosTable[_reminderChar1IdxTable[index]*2+1], _charPreviews[0].x, _charPreviews[0].y, 32, 32, 4, 0);
_screen->copyRegion(_selectionPosTable[_reminderChar2IdxTable[index]*2+0], _selectionPosTable[_reminderChar2IdxTable[index]*2+1], _charPreviews[1].x, _charPreviews[1].y, 32, 32, 4, 0);
@@ -421,7 +422,7 @@ void LoLEngine::kingSelectionReminder() {
_system->delayMillis(10);
}
- if (_speechFlag)
+ if (speechEnabled())
index = (index + 1) % 22;
else if (++index >= 27)
break;
@@ -434,7 +435,7 @@ void LoLEngine::kingSelectionOutro() {
_sound->voicePlay("KING03", &_speechHandle);
int index = 0;
- while ((!_speechFlag || (_speechFlag && _sound->voiceIsPlaying(&_speechHandle))) && !shouldQuit() && !skipFlag()) {
+ while ((!speechEnabled() || (speechEnabled() && _sound->voiceIsPlaying(&_speechHandle))) && !shouldQuit() && !skipFlag()) {
index = MAX(index, 4);
_chargenWSA->displayFrame(_chargenFrameTable[index], 0, 113, 0, 0, 0, 0);
@@ -446,7 +447,7 @@ void LoLEngine::kingSelectionOutro() {
_system->delayMillis(10);
}
- if (_speechFlag)
+ if (speechEnabled())
index = (index + 1) % 22;
else if (++index >= 27)
break;
@@ -581,13 +582,13 @@ void LoLEngine::selectionCharInfoIntro(char *file) {
bool processAnim = true;
while (_charSelectionInfoResult == -1 && !shouldQuit()) {
- if (_speechFlag && !_sound->isVoicePresent(file))
+ if (speechEnabled() && !_sound->isVoicePresent(file))
break;
_sound->voicePlay(file, &_speechHandle);
int i = 0;
- while ((!_speechFlag || (_speechFlag && _sound->voiceIsPlaying(&_speechHandle))) && _charSelectionInfoResult == -1 && !shouldQuit()) {
+ while ((!speechEnabled() || (speechEnabled() && _sound->voiceIsPlaying(&_speechHandle))) && _charSelectionInfoResult == -1 && !shouldQuit()) {
_screen->drawShape(0, _screen->getPtrToShape(_screen->getCPagePtr(9), _charInfoFrameTable[i]), 11, 130, 0, 0);
_screen->updateScreen();
@@ -597,7 +598,7 @@ void LoLEngine::selectionCharInfoIntro(char *file) {
_system->delayMillis(10);
}
- if (_speechFlag || processAnim)
+ if (speechEnabled() || processAnim)
i = (i + 1) % 32;
if (i == 0)
processAnim = false;
@@ -641,19 +642,19 @@ int LoLEngine::selectionCharAccept() {
}
void LoLEngine::showStarcraftLogo() {
- WSAMovie_v2 *ci = new WSAMovie_v2(this, _screen);
+ WSAMovie_v2 *ci = new WSAMovie_v2(this);
assert(ci);
_screen->clearPage(0);
_screen->clearPage(2);
- int endframe = ci->open("ci01.wsa", 0, _screen->_currentPalette);
+ int endframe = ci->open("ci01.wsa", 0, &_screen->getPalette(0));
if (!ci->opened()) {
delete ci;
return;
}
_screen->hideMouse();
- ci->displayFrame(0, 2, 32, 80, 0);
+ ci->displayFrame(0, 2, 32, 80, 0, 0, 0);
_screen->copyPage(2, 0);
_screen->fadeFromBlack();
int inputFlag = 0;
@@ -661,7 +662,7 @@ void LoLEngine::showStarcraftLogo() {
inputFlag = checkInput(0) & 0xff;
if (shouldQuit() || inputFlag)
break;
- ci->displayFrame(i, 2, 32, 80, 0);
+ ci->displayFrame(i, 2, 32, 80, 0, 0, 0);
_screen->copyPage(2, 0);
_screen->updateScreen();
delay(4 * _tickLength);
@@ -725,9 +726,8 @@ void LoLEngine::setupEpilogueData(bool load) {
if (_flags.platform == Common::kPlatformPC98)
_sound->loadSoundFile("SOUND.DAT");
} else {
- uint8 *pal = _screen->getPalette(0);
- memset(pal, 0, 768);
- _screen->setScreenPalette(pal);
+ _screen->getPalette(0).clear();
+ _screen->setScreenPalette(_screen->getPalette(0));
if (shouldQuit())
return;
@@ -742,9 +742,8 @@ void LoLEngine::showOutro(int character, bool maxDifficulty) {
TIMInterpreter *timBackUp = _tim;
_tim = new TIMInterpreter(this, _screen, _system);
- uint8 *pal = _screen->getPalette(0);
- memset(pal, 0, 768);
- _screen->setScreenPalette(pal);
+ _screen->getPalette(0).clear();
+ _screen->setScreenPalette(_screen->getPalette(0));
_screen->clearPage(0);
_screen->clearPage(4);
@@ -803,25 +802,24 @@ void LoLEngine::showOutro(int character, bool maxDifficulty) {
switch (character) {
case 0:
- _screen->loadBitmap("KIERAN.CPS", 3, 3, _screen->getPalette(0));
+ _screen->loadBitmap("KIERAN.CPS", 3, 3, &_screen->getPalette(0));
break;
case 1:
- _screen->loadBitmap("AK'SHEL.CPS", 3, 3, _screen->getPalette(0));
+ _screen->loadBitmap("AK'SHEL.CPS", 3, 3, &_screen->getPalette(0));
break;
case 2:
- _screen->loadBitmap("MICHAEL.CPS", 3, 3, _screen->getPalette(0));
+ _screen->loadBitmap("MICHAEL.CPS", 3, 3, &_screen->getPalette(0));
break;
case 3:
- _screen->loadBitmap("CONRAD.CPS", 3, 3, _screen->getPalette(0));
+ _screen->loadBitmap("CONRAD.CPS", 3, 3, &_screen->getPalette(0));
break;
default:
_screen->clearPage(3);
- memset(_screen->getPalette(0), 0, 768);
- break;
+ _screen->getPalette(0).clear();
}
_screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 0, Screen::CR_NO_P_CHECK);
@@ -856,8 +854,8 @@ void LoLEngine::showCredits() {
_screen->setTextColorMap(colorMap);
_screen->_charWidth = 0;
- _screen->loadBitmap("ROOM.CPS", 2, 2, _screen->getPalette(0));
- memset(_screen->getPalette(0) + 764, 0, 3);
+ _screen->loadBitmap("ROOM.CPS", 2, 2, &_screen->getPalette(0));
+ _screen->getPalette(0).fill(255, 1, 0);
_screen->fadeToBlack(30);
_screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 0, Screen::CR_NO_P_CHECK);
@@ -865,7 +863,7 @@ void LoLEngine::showCredits() {
_screen->_charOffset = 0;
char *credits = (char *)_res->fileData("CREDITS.TXT", 0);
- processCredits(credits, 19, 4, 5);
+ processCredits(credits, 21, 4, 5);
delete[] credits;
uint32 endTime = _system->getMillis() + 120 * _tickLength;
@@ -895,8 +893,8 @@ void LoLEngine::processCredits(char *t, int dimState, int page, int delayTime) {
uint8 *doorShape = _screen->makeShapeCopy(_screen->getCPagePtr(5), 0);
assert(doorShape);
- _screen->drawShape(0, doorShape, 0, 0, 20, 0x10);
- _screen->drawShape(0, doorShape, 0, 0, 21, 0x11);
+ _screen->drawShape(0, doorShape, 0, 0, 22, 0x10);
+ _screen->drawShape(0, doorShape, 0, 0, 23, 0x11);
int curShapeFile = 0;
uint8 *shapes[12];
@@ -906,7 +904,7 @@ void LoLEngine::processCredits(char *t, int dimState, int page, int delayTime) {
uint8 *monsterPal = _res->fileData("MONSTERS.PAL", 0);
assert(monsterPal);
- memcpy(_screen->getPalette(0) + 88 * 3, monsterPal + 0 * 3, 40 * 3);
+ _screen->getPalette(0).copy(monsterPal, 0, 40, 88);
_screen->fadePalette(_screen->getPalette(0), 30);
uint32 waitTimer = _system->getMillis();
@@ -1042,8 +1040,8 @@ void LoLEngine::processCredits(char *t, int dimState, int page, int delayTime) {
} else {
if (!monsterAnimFrame && doorRedraw) {
_screen->copyRegion(0, 0, 0, 0, 320, 200, 2, page, Screen::CR_NO_P_CHECK);
- _screen->drawShape(page, doorShape, 0, 0, 20, 0x10);
- _screen->drawShape(page, doorShape, 0, 0, 21, 0x11);
+ _screen->drawShape(page, doorShape, 0, 0, 22, 0x10);
+ _screen->drawShape(page, doorShape, 0, 0, 23, 0x11);
--frameCounter;
doorRedraw = false;
@@ -1062,32 +1060,32 @@ void LoLEngine::processCredits(char *t, int dimState, int page, int delayTime) {
bool isRightMonster = ((curShapeFile - 1) & 1) != 0;
if (isRightMonster) {
- doorSD = 21;
+ doorSD = 23;
doorX = _outroRightDoorPos[monsterAnimFrame * 2 + 0];
doorY = _outroRightDoorPos[monsterAnimFrame * 2 + 1];
monsterX = _outroRightMonsterPos[monsterAnimFrame * 2 + 0];
monsterY = _outroRightMonsterPos[monsterAnimFrame * 2 + 1];
- _screen->drawShape(page, doorShape, 0, 0, 20, 0x10);
+ _screen->drawShape(page, doorShape, 0, 0, 22, 0x10);
} else {
- doorSD = 20;
+ doorSD = 22;
doorX = _outroLeftDoorPos[monsterAnimFrame * 2 + 0];
doorY = _outroLeftDoorPos[monsterAnimFrame * 2 + 1];
monsterX = _outroLeftMonsterPos[monsterAnimFrame * 2 + 0];
monsterY = _outroLeftMonsterPos[monsterAnimFrame * 2 + 1];
- _screen->drawShape(page, doorShape, 0, 0, 21, 0x11);
+ _screen->drawShape(page, doorShape, 0, 0, 23, 0x11);
}
if (monsterAnimFrame >= 8)
- _screen->drawShape(page, doorShape, doorX, doorY, doorSD, (doorSD == 20) ? 0 : 1);
+ _screen->drawShape(page, doorShape, doorX, doorY, doorSD, (doorSD == 22) ? 0 : 1);
_screen->drawShape(page, monsterShape, monsterX, monsterY, 0, 0x104 | ((!isRightMonster | (monsterAnimFrame < 20)) ? 0 : 1), _outroShapeTable, 1, _outroMonsterScaleTableX[monsterAnimFrame], _outroMonsterScaleTableY[monsterAnimFrame]);
if (monsterAnimFrame < 8)
- _screen->drawShape(page, doorShape, doorX, doorY, doorSD, (doorSD == 20) ? 0 : 1);
+ _screen->drawShape(page, doorShape, doorX, doorY, doorSD, (doorSD == 22) ? 0 : 1);
_screen->copyRegion(0, 0, 0, 0, 320, 200, page, 6, Screen::CR_NO_P_CHECK);
doorRedraw = true;
@@ -1129,7 +1127,7 @@ void LoLEngine::processCredits(char *t, int dimState, int page, int delayTime) {
curShapeFile = curShapeFile % 28;
loadOutroShapes(curShapeFile, shapes);
- memcpy(_screen->getPalette(0) + 88 * 3, monsterPal + curShapeFile * 40 * 3, 40 * 3);
+ _screen->getPalette(0).copy(monsterPal, curShapeFile * 40, 40, 88);
_screen->setScreenPalette(_screen->getPalette(0));
needNewShape = false;
diff --git a/engines/kyra/sound_lol.cpp b/engines/kyra/sound_lol.cpp
index 3f87036849..63a42837aa 100644
--- a/engines/kyra/sound_lol.cpp
+++ b/engines/kyra/sound_lol.cpp
@@ -34,7 +34,7 @@
namespace Kyra {
bool LoLEngine::snd_playCharacterSpeech(int id, int8 speaker, int) {
- if (!_speechFlag)
+ if (!speechEnabled())
return false;
if (speaker < 65) {
@@ -304,6 +304,15 @@ int LoLEngine::snd_stopMusic() {
return snd_playTrack(-1);
}
+int LoLEngine::convertVolumeToMixer(int value) {
+ value -= 2;
+ return (value * Audio::Mixer::kMaxMixerVolume) / 100;
+}
+
+int LoLEngine::convertVolumeFromMixer(int value) {
+ return (value * 100) / Audio::Mixer::kMaxMixerVolume + 2;
+}
+
} // end of namespace Kyra
#endif // ENABLE_LOL
diff --git a/engines/kyra/sound_midi.cpp b/engines/kyra/sound_midi.cpp
index f798251525..451b77cec2 100644
--- a/engines/kyra/sound_midi.cpp
+++ b/engines/kyra/sound_midi.cpp
@@ -311,10 +311,8 @@ void MidiOutput::sendSysEx(const byte p1, const byte p2, const byte p3, const by
}
void MidiOutput::metaEvent(byte type, byte *data, uint16 length) {
- if (type == 0x2F) { // End of Track
+ if (type == 0x2F) // End of Track
deinitSource(_curSource);
- //XXX
- }
_output->metaEvent(type, data, length);
}
diff --git a/engines/kyra/sound_towns.cpp b/engines/kyra/sound_towns.cpp
index 1980f62d7c..fe0a44c052 100644
--- a/engines/kyra/sound_towns.cpp
+++ b/engines/kyra/sound_towns.cpp
@@ -1504,7 +1504,7 @@ public:
private:
void updatesRegs();
- uint8 _updateRequestBuf[32];
+ uint8 _updateRequestBuf[64];
int _updateRequest;
int _rand;
@@ -2657,7 +2657,7 @@ void TownsPC98_OpnSquareSineSource::writeReg(uint8 address, uint8 value, bool fo
}
if (!force) {
- if (_updateRequest == 31) {
+ if (_updateRequest >= 63) {
warning("TownsPC98_OpnSquareSineSource: event buffer overflow");
_updateRequest = -1;
}
@@ -3420,6 +3420,8 @@ TownsPC98_OpnDriver::TownsPC98_OpnDriver(Audio::Mixer *mixer, OpnType type) : To
}
TownsPC98_OpnDriver::~TownsPC98_OpnDriver() {
+ reset();
+
if (_channels) {
for (int i = 0; i < _numChan; i++)
delete _channels[i];
@@ -4120,7 +4122,7 @@ void SoundPC98::playSoundEffect(uint8 track) {
// This has been disabled for now since I don't know
// how to make up the correct track number. It probably
// needs a map.
- //_driver->loadSoundEffectData(_sfxTrackData, track);
+ _driver->loadSoundEffectData(_sfxTrackData, track);
}
diff --git a/engines/kyra/sprites.cpp b/engines/kyra/sprites.cpp
index 147ded3cfd..3cc632a391 100644
--- a/engines/kyra/sprites.cpp
+++ b/engines/kyra/sprites.cpp
@@ -47,7 +47,7 @@ Sprites::Sprites(KyraEngine_LoK *vm, OSystem *system) {
_spriteDefStart = 0;
memset(_drawLayerTable, 0, sizeof(_drawLayerTable));
_sceneAnimatorBeaconFlag = 0;
- system->getEventManager()->registerRandomSource(_rnd, "kyraSprites");
+ _vm->getEventManager()->registerRandomSource(_rnd, "kyraSprites");
}
Sprites::~Sprites() {
@@ -420,16 +420,16 @@ void Sprites::loadDat(const char *filename, SceneExits &exits) {
if (_vm->gameFlags().platform == Common::kPlatformAmiga) {
if (_vm->queryGameFlag(0xA0))
- memcpy(_screen->getPalette(3), _screen->getPalette(4), 32*3);
+ _screen->copyPalette(3, 4);
else
- memcpy(_screen->getPalette(3), _screen->getPalette(0), 32*3);
+ _screen->copyPalette(3, 0);
} else {
if (_vm->queryGameFlag(0xA0))
- memcpy(_screen->getPalette(1), _screen->getPalette(3), 768);
+ _screen->copyPalette(1, 3);
else
- memcpy(_screen->getPalette(1), _screen->getPalette(0), 768);
+ _screen->copyPalette(1, 0);
- _screen->loadPalette(_dat + 0x17, _screen->getPalette(1) + 684, 60);
+ _screen->getPalette(1).copy(_dat + 0x17, 0, 20, 228);
}
uint8 *data = _dat + 0x6B;
diff --git a/engines/kyra/sprites_lol.cpp b/engines/kyra/sprites_lol.cpp
index 732a8bb2ca..8cee1dc5fc 100644
--- a/engines/kyra/sprites_lol.cpp
+++ b/engines/kyra/sprites_lol.cpp
@@ -784,7 +784,7 @@ int LoLEngine::getMonsterCurFrame(MonsterInPlay *m, uint16 dirFlags) {
default:
return m->damageReceived ? 5 : m->currentSubFrame;
}
-
+
break;
default:
break;
@@ -1092,7 +1092,7 @@ void LoLEngine::updateMonster(MonsterInPlay *monster) {
setMonsterMode(monster, 7);
if ((monster->mode != 11) && (monster->mode != 14)) {
- if (!(getRandomNumberSpecial() & 3)) {
+ if (!(_rnd.getRandomNumber(255) & 3)) {
monster->shiftStep = (++monster->shiftStep) & 0x0f;
checkSceneUpdateNeed(monster->block);
}
diff --git a/engines/kyra/staticres.cpp b/engines/kyra/staticres.cpp
index 3f41768c3c..e8597c8326 100644
--- a/engines/kyra/staticres.cpp
+++ b/engines/kyra/staticres.cpp
@@ -1584,7 +1584,7 @@ void KyraEngine_LoK::loadMainScreen(int page) {
_screen->clearPage(page);
if (_flags.lang == Common::EN_ANY && !_flags.isTalkie && (_flags.platform == Common::kPlatformPC || _flags.platform == Common::kPlatformAmiga))
- _screen->loadBitmap("MAIN15.CPS", page, page, _screen->getPalette(0));
+ _screen->loadBitmap("MAIN15.CPS", page, page, &_screen->getPalette(0));
else if (_flags.lang == Common::EN_ANY || _flags.lang == Common::JA_JPN || (_flags.isTalkie && _flags.lang == Common::IT_ITA))
_screen->loadBitmap("MAIN_ENG.CPS", page, page, 0);
else if (_flags.lang == Common::FR_FRA)
@@ -1599,7 +1599,7 @@ void KyraEngine_LoK::loadMainScreen(int page) {
warning("no main graphics file found");
if (_flags.platform == Common::kPlatformAmiga)
- memcpy(_screen->getPalette(1), _screen->getPalette(0), 32*3);
+ _screen->copyPalette(1, 0);
_screen->copyRegion(0, 0, 0, 0, 320, 200, page, 0);
}
@@ -2011,9 +2011,108 @@ void LoLEngine::initStaticResource() {
#undef cb
}
+void GUI_LoL::initStaticData() {
+ GUI_V2_BUTTON(_scrollUpButton, 20, 96, 0, 1, 1, 1, 0x4487, 0, 0, 0, 25, 16, 0xfe, 0x01, 0xfe, 0x01, 0xfe, 0x01, 0);
+ GUI_V2_BUTTON(_scrollDownButton, 21, 98, 0, 1, 1, 1, 0x4487, 0, 0, 0, 25, 16, 0xfe, 0x01, 0xfe, 0x01, 0xfe, 0x01, 0);
+
+ for (uint i = 0; i < ARRAYSIZE(_menuButtons); ++i)
+ GUI_V2_BUTTON(_menuButtons[i], i, 0, 0, 0, 0, 0, 0x4487, 0, 0, 0, 0, 0, 0xfe, 0x01, 0xfe, 0x01, 0xfe, 0x01, 0);
+
+ GUI_LOL_MENU(_mainMenu, 9, 0x4000, 0, 7, -1, -1, -1, -1);
+ GUI_LOL_MENU_ITEM(_mainMenu.item[0], 0x4001, 16, 23, 176, 15, 0, 0);
+ GUI_LOL_MENU_ITEM(_mainMenu.item[1], 0x4002, 16, 40, 176, 15, 0, 0);
+ GUI_LOL_MENU_ITEM(_mainMenu.item[2], 0x4003, 16, 57, 176, 15, 0, 0);
+ GUI_LOL_MENU_ITEM(_mainMenu.item[3], 0x4004, 16, 74, 176, 15, 0, 0);
+ GUI_LOL_MENU_ITEM(_mainMenu.item[4], 0x42D9, 16, 91, 176, 15, 0, 0);
+ GUI_LOL_MENU_ITEM(_mainMenu.item[5], 0x4006, 16, 108, 176, 15, 0, 0);
+ GUI_LOL_MENU_ITEM(_mainMenu.item[6], 0x4005, 88, 127, 104, 15, 0, 110);
+ Button::Callback mainMenuFunctor = BUTTON_FUNCTOR(GUI_LoL, this, &GUI_LoL::clickedMainMenu);
+ for (int i = 0; i < 7; ++i)
+ _mainMenu.item[i].callback = mainMenuFunctor;
+
+ GUI_LOL_MENU(_loadMenu, 10, 0x400e, 1, 5, 128, 20, 128, 118);
+ GUI_LOL_MENU_ITEM(_loadMenu.item[0], 0xfffe, 8, 39, 256, 15, 0, 0);
+ GUI_LOL_MENU_ITEM(_loadMenu.item[1], 0xfffd, 8, 56, 256, 15, 0, 0);
+ GUI_LOL_MENU_ITEM(_loadMenu.item[2], 0xfffc, 8, 73, 256, 15, 0, 0);
+ GUI_LOL_MENU_ITEM(_loadMenu.item[3], 0xfffb, 8, 90, 256, 15, 0, 0);
+ GUI_LOL_MENU_ITEM(_loadMenu.item[4], 0x4011, 168, 118, 96, 15, 0, 110);
+ Button::Callback loadMenuFunctor = BUTTON_FUNCTOR(GUI_LoL, this, &GUI_LoL::clickedLoadMenu);
+ for (int i = 0; i < 5; ++i)
+ _loadMenu.item[i].callback = loadMenuFunctor;
+
+ GUI_LOL_MENU(_saveMenu, 10, 0x400d, 1, 5, 128, 20, 128, 118);
+ GUI_LOL_MENU_ITEM(_saveMenu.item[0], 0xfffe, 8, 39, 256, 15, 0, 0);
+ GUI_LOL_MENU_ITEM(_saveMenu.item[1], 0xfffd, 8, 56, 256, 15, 0, 0);
+ GUI_LOL_MENU_ITEM(_saveMenu.item[2], 0xfffc, 8, 73, 256, 15, 0, 0);
+ GUI_LOL_MENU_ITEM(_saveMenu.item[3], 0xfffb, 8, 90, 256, 15, 0, 0);
+ GUI_LOL_MENU_ITEM(_saveMenu.item[4], 0x4011, 168, 118, 96, 15, 0, 110);
+ Button::Callback saveMenuFunctor = BUTTON_FUNCTOR(GUI_LoL, this, &GUI_LoL::clickedSaveMenu);
+ for (int i = 0; i < 5; ++i)
+ _saveMenu.item[i].callback = saveMenuFunctor;
+
+ GUI_LOL_MENU(_deleteMenu, 10, 0x400f, 1, 5, 128, 20, 128, 118);
+ GUI_LOL_MENU_ITEM(_deleteMenu.item[0], 0xfffe, 8, 39, 256, 15, 0, 0);
+ GUI_LOL_MENU_ITEM(_deleteMenu.item[1], 0xfffd, 8, 56, 256, 15, 0, 0);
+ GUI_LOL_MENU_ITEM(_deleteMenu.item[2], 0xfffc, 8, 73, 256, 15, 0, 0);
+ GUI_LOL_MENU_ITEM(_deleteMenu.item[3], 0xfffb, 8, 90, 256, 15, 0, 0);
+ GUI_LOL_MENU_ITEM(_deleteMenu.item[4], 0x4011, 168, 118, 96, 15, 0, 110);
+ Button::Callback deleteMenuFunctor = BUTTON_FUNCTOR(GUI_LoL, this, &GUI_LoL::clickedDeleteMenu);
+ for (int i = 0; i < 5; ++i)
+ _deleteMenu.item[i].callback = deleteMenuFunctor;
+
+ GUI_LOL_MENU(_gameOptions, 17, 0x400c, 0, 6, -1, -1, -1, -1);
+ GUI_LOL_MENU_ITEM(_gameOptions.item[0], 0xfff7, 120, 22, 80, 15, 0x406e, 0);
+ GUI_LOL_MENU_ITEM(_gameOptions.item[1], 0xfff6, 120, 39, 80, 15, 0x406c, 0);
+ GUI_LOL_MENU_ITEM(_gameOptions.item[2], 0xfff5, 120, 56, 80, 15, 0x406d, 0);
+ GUI_LOL_MENU_ITEM(_gameOptions.item[3], 0xfff4, 120, 73, 80, 15, 0x42d5, 0);
+ GUI_LOL_MENU_ITEM(_gameOptions.item[4], 0xfff3, 120, 90, 80, 15, 0x42d2, 0);
+ GUI_LOL_MENU_ITEM(_gameOptions.item[5], 0x4072, 104, 110, 96, 15, 0, 110);
+ Button::Callback optionsMenuFunctor = BUTTON_FUNCTOR(GUI_LoL, this, &GUI_LoL::clickedOptionsMenu);
+ for (int i = 0; i < 6; ++i)
+ _gameOptions.item[i].callback = optionsMenuFunctor;
+
+ GUI_LOL_MENU(_audioOptions, 18, 0x42d9, 2, 1, -1, -1, -1, -1);
+ GUI_LOL_MENU_ITEM(_audioOptions.item[0], 0x4072, 152, 76, 96, 15, 0, 110);
+ GUI_LOL_MENU_ITEM(_audioOptions.item[1], 3, 128, 22, 114, 14, 0x42db, 0);
+ GUI_LOL_MENU_ITEM(_audioOptions.item[2], 4, 128, 39, 114, 14, 0x42da, 0);
+ GUI_LOL_MENU_ITEM(_audioOptions.item[3], 5, 128, 56, 114, 14, 0x42dc, 0);
+ Button::Callback audioMenuFunctor = BUTTON_FUNCTOR(GUI_LoL, this, &GUI_LoL::clickedAudioMenu);
+ for (int i = 0; i < 4; ++i)
+ _audioOptions.item[i].callback = audioMenuFunctor;
+
+ GUI_LOL_MENU(_deathMenu, 11, 0x4013, 0, 2, -1, -1, -1, -1);
+ GUI_LOL_MENU_ITEM(_deathMenu.item[0], 0x4006, 8, 30, 104, 15, 0, 0);
+ GUI_LOL_MENU_ITEM(_deathMenu.item[1], 0x4001, 176, 30, 104, 15, 0, 0);
+ Button::Callback deathMenuFunctor = BUTTON_FUNCTOR(GUI_LoL, this, &GUI_LoL::clickedDeathMenu);
+ for (int i = 0; i < 2; ++i)
+ _deathMenu.item[i].callback = deathMenuFunctor;
+
+ GUI_LOL_MENU(_savenameMenu, 7, 0x4053, 0, 2, -1, -1, -1, -1);
+ GUI_LOL_MENU_ITEM(_savenameMenu.item[0], 0x4012, 8, 38, 72, 15, 0, 43);
+ GUI_LOL_MENU_ITEM(_savenameMenu.item[1], 0x4011, 176, 38, 72, 15, 0, 110);
+ Button::Callback savenameMenuFunctor = BUTTON_FUNCTOR(GUI_LoL, this, &GUI_LoL::clickedSavenameMenu);
+ for (int i = 0; i < 2; ++i)
+ _savenameMenu.item[i].callback = savenameMenuFunctor;
+
+ GUI_LOL_MENU(_choiceMenu, 11, 0, 0, 2, -1, -1, -1, -1);
+ GUI_LOL_MENU_ITEM(_choiceMenu.item[0], 0x4007, 8, 30, 72, 15, 0, 0);
+ GUI_LOL_MENU_ITEM(_choiceMenu.item[1], 0x4008, 208, 30, 72, 15, 0, 0);
+ Button::Callback choiceMenuFunctor = BUTTON_FUNCTOR(GUI_LoL, this, &GUI_LoL::clickedChoiceMenu);
+ for (int i = 0; i < 2; ++i)
+ _choiceMenu.item[i].callback = choiceMenuFunctor;
+}
#endif // ENABLE_LOL
+const uint8 Screen_LoK_16::_palette16[48] = {
+ 0x00, 0x00, 0x00, 0x02, 0x07, 0x0B, 0x0C, 0x06, 0x04,
+ 0x0E, 0x09, 0x07, 0x00, 0x06, 0x03, 0x00, 0x0C, 0x07,
+ 0x0A, 0x0A, 0x0A, 0x08, 0x03, 0x03, 0x02, 0x02, 0x02,
+ 0x08, 0x0B, 0x0E, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x0A,
+ 0x05, 0x05, 0x05, 0x00, 0x0F, 0x0F, 0x0F, 0x0D, 0x00,
+ 0x0F, 0x0F, 0x0F
+};
+
const ScreenDim Screen_LoK::_screenDimTable[] = {
{ 0x00, 0x00, 0x28, 0xC8, 0x0F, 0x0C, 0x00, 0x00 },
{ 0x08, 0x48, 0x18, 0x38, 0x0F, 0x0C, 0x00, 0x00 },
@@ -3018,6 +3117,8 @@ const ScreenDim Screen_LoL::_screenDimTable256C[] = {
{ 0x0D, 0xA2, 0x18, 0x0C, 0xFE, 0x01, 0x00, 0x00 },
{ 0x0F, 0x06, 0x14, 0x6E, 0x01, 0x00, 0x00, 0x00 },
{ 0x1A, 0xBE, 0x0A, 0x07, 0xFE, 0x01, 0x00, 0x00 },
+ { 0x07, 0x21, 0x1A, 0x85, 0x00, 0x00, 0x00, 0x00 },
+ { 0x03, 0x32, 0x22, 0x62, 0x00, 0x00, 0x00, 0x00 },
{ 0x0B, 0x8C, 0x10, 0x33, 0x3D, 0x01, 0x00, 0x00 }, // Main menu box (5 entries, CD version only)
{ 0x0B, 0x8C, 0x10, 0x23, 0x3D, 0x01, 0x00, 0x00 }, // Main menu box (3 entries, floppy version only)
@@ -3045,6 +3146,8 @@ const ScreenDim Screen_LoL::_screenDimTable16C[] = {
{ 0x0D, 0xA2, 0x18, 0x0C, 0x33, 0x44, 0x00, 0x00 },
{ 0x0F, 0x06, 0x14, 0x6E, 0x44, 0x00, 0x00, 0x00 },
{ 0x1A, 0xBE, 0x0A, 0x07, 0x33, 0x44, 0x00, 0x00 },
+ { 0x07, 0x21, 0x1A, 0x85, 0x00, 0x00, 0x00, 0x00 },
+ { 0x03, 0x32, 0x22, 0x62, 0x00, 0x00, 0x00, 0x00 },
{ 0x0B, 0x8C, 0x10, 0x33, 0x33, 0x44, 0x00, 0x00 }, // Main menu box (5 entries, not used here)
{ 0x0B, 0x8C, 0x10, 0x23, 0x33, 0x44, 0x00, 0x00 }, // Main menu box (3 entries)
@@ -3056,6 +3159,42 @@ const ScreenDim Screen_LoL::_screenDimTable16C[] = {
const int Screen_LoL::_screenDimTableCount = ARRAYSIZE(Screen_LoL::_screenDimTable256C);
+// 256 -> 16 color conversion table
+const uint8 Screen_LoL::_paletteConvTable[256] = {
+ 0x0, 0x1, 0x0, 0x3, 0x0, 0x5, 0x0, 0x7,
+ 0x0, 0x9, 0x0, 0xB, 0x0, 0xD, 0x0, 0xF,
+ 0x1, 0x1, 0x1, 0x3, 0x1, 0x5, 0x1, 0x7,
+ 0x1, 0x9, 0x1, 0xB, 0x1, 0xD, 0x1, 0xF,
+ 0x2, 0x1, 0x2, 0x3, 0x2, 0x5, 0x2, 0x7,
+ 0x2, 0x9, 0x2, 0xB, 0x2, 0xD, 0x2, 0xF,
+ 0x3, 0x1, 0x3, 0x3, 0x3, 0x5, 0x3, 0x7,
+ 0x3, 0x9, 0x3, 0xB, 0x3, 0xD, 0x3, 0xF,
+ 0x4, 0x1, 0x4, 0x3, 0x4, 0x5, 0x4, 0x7,
+ 0x4, 0x9, 0x4, 0xB, 0x4, 0xD, 0x4, 0xF,
+ 0x5, 0x1, 0x5, 0x3, 0x5, 0x5, 0x5, 0x7,
+ 0x5, 0x9, 0x5, 0xB, 0x5, 0xD, 0x5, 0xF,
+ 0x6, 0x1, 0x6, 0x3, 0x6, 0x5, 0x6, 0x7,
+ 0x6, 0x9, 0x6, 0xB, 0x6, 0xD, 0x6, 0xF,
+ 0x7, 0x1, 0x7, 0x3, 0x7, 0x5, 0x7, 0x7,
+ 0x7, 0x9, 0x7, 0xB, 0x7, 0xD, 0x7, 0xF,
+ 0x8, 0x1, 0x8, 0x3, 0x8, 0x5, 0x8, 0x7,
+ 0x8, 0x9, 0x8, 0xB, 0x8, 0xD, 0x8, 0xF,
+ 0x9, 0x1, 0x9, 0x3, 0x9, 0x5, 0x9, 0x7,
+ 0x9, 0x9, 0x9, 0xB, 0x9, 0xD, 0x9, 0xF,
+ 0xA, 0x1, 0xA, 0x3, 0xA, 0x5, 0xA, 0x7,
+ 0xA, 0x9, 0xA, 0xB, 0xA, 0xD, 0xA, 0xF,
+ 0xB, 0x1, 0xB, 0x3, 0xB, 0x5, 0xB, 0x7,
+ 0xB, 0x9, 0xB, 0xB, 0xB, 0xD, 0xB, 0xF,
+ 0xC, 0x1, 0xC, 0x3, 0xC, 0x5, 0xC, 0x7,
+ 0xC, 0x9, 0xC, 0xB, 0xC, 0xD, 0xC, 0xF,
+ 0xD, 0x1, 0xD, 0x3, 0xD, 0x5, 0xD, 0x7,
+ 0xD, 0x9, 0xD, 0xB, 0xD, 0xD, 0xD, 0xF,
+ 0xE, 0x1, 0xE, 0x3, 0xE, 0x5, 0xE, 0x7,
+ 0xE, 0x9, 0xE, 0xB, 0xE, 0xD, 0xE, 0xF,
+ 0xF, 0x1, 0xF, 0x3, 0xF, 0x5, 0xF, 0x7,
+ 0xF, 0x9, 0xF, 0xB, 0xF, 0xD, 0xF, 0xF
+};
+
const char * const LoLEngine::_languageExt[] = {
"ENG",
"FRE",
@@ -3241,4 +3380,3 @@ const int LoLEngine::_outroMonsterScaleTableY[] = {
#endif // ENABLE_LOL
} // End of namespace Kyra
-
diff --git a/engines/kyra/text_lok.cpp b/engines/kyra/text_lok.cpp
index 6b1cb4eca2..3f4bfb65ac 100644
--- a/engines/kyra/text_lok.cpp
+++ b/engines/kyra/text_lok.cpp
@@ -39,12 +39,9 @@ void KyraEngine_LoK::waitForChatToFinish(int vocFile, int16 chatDuration, const
uint8 currPage;
Common::Event event;
- //while (towns_isEscKeyPressed() )
- //towns_getKey();
-
uint32 timeToEnd = strlen(chatStr) * 8 * _tickLength + _system->getMillis();
- if (_configVoice == 0 && chatDuration != -1) {
+ if (textEnabled() && !speechEnabled() && chatDuration != -1) {
switch (_configTextspeed) {
case 0:
chatDuration *= 2;
@@ -136,7 +133,6 @@ void KyraEngine_LoK::waitForChatToFinish(int vocFile, int16 chatDuration, const
_timer->enable(15);
_timer->enable(18);
_timer->enable(19);
- //clearKyrandiaButtonIO();
}
void KyraEngine_LoK::endCharacterChat(int8 charNum, int16 convoInitialized) {
@@ -329,11 +325,11 @@ void KyraEngine_LoK::drawSentenceCommand(const char *sentence, int color) {
_screen->fillRect(8, 143, 311, 152, 12);
if (_startSentencePalIndex != color || _fadeText != false) {
- _currSentenceColor[0] = _screen->_currentPalette[765] = _screen->_currentPalette[color*3];
- _currSentenceColor[1] = _screen->_currentPalette[766] = _screen->_currentPalette[color*3+1];
- _currSentenceColor[2] = _screen->_currentPalette[767] = _screen->_currentPalette[color*3+2];
+ _currSentenceColor[0] = _screen->getPalette(0)[765] = _screen->getPalette(0)[color*3];
+ _currSentenceColor[1] = _screen->getPalette(0)[766] = _screen->getPalette(0)[color*3+1];
+ _currSentenceColor[2] = _screen->getPalette(0)[767] = _screen->getPalette(0)[color*3+2];
- _screen->setScreenPalette(_screen->_currentPalette);
+ _screen->setScreenPalette(_screen->getPalette(0));
_startSentencePalIndex = 0;
}
@@ -368,10 +364,10 @@ void KyraEngine_LoK::updateTextFade() {
}
}
- _screen->_currentPalette[765] = _currSentenceColor[0];
- _screen->_currentPalette[766] = _currSentenceColor[1];
- _screen->_currentPalette[767] = _currSentenceColor[2];
- _screen->setScreenPalette(_screen->_currentPalette);
+ _screen->getPalette(0)[765] = _currSentenceColor[0];
+ _screen->getPalette(0)[766] = _currSentenceColor[1];
+ _screen->getPalette(0)[767] = _currSentenceColor[2];
+ _screen->setScreenPalette(_screen->getPalette(0));
if (finished) {
_fadeText = false;
diff --git a/engines/kyra/text_lol.cpp b/engines/kyra/text_lol.cpp
index 7ce12f47c7..2174bcc441 100644
--- a/engines/kyra/text_lol.cpp
+++ b/engines/kyra/text_lol.cpp
@@ -33,8 +33,8 @@
namespace Kyra {
TextDisplayer_LoL::TextDisplayer_LoL(LoLEngine *vm, Screen_LoL *screen) : _vm(vm), _screen(screen),
- _scriptParameter(0), _animWidth(0), _animColor1(0), _animColor2(0), _animFlag(true), _lineCount(0),
- _printFlag(false), _lineWidth(0), _numCharsTotal(0), _numCharsLeft(0), _numCharsPrinted(0) {
+ _scriptParameter(0), _lineCount(0), _printFlag(false), _lineWidth(0), _numCharsTotal(0),
+ _numCharsLeft(0), _numCharsPrinted(0) {
memset(_stringParameters, 0, 15 * sizeof(char *));
_buffer = new char[600];
@@ -138,7 +138,7 @@ void TextDisplayer_LoL::resetDimTextPositions(int dim) {
_textDimData[dim].line = 0;
}
-void TextDisplayer_LoL::setAnimParameters(const char *str, int x, uint8 col1, uint8 col2) {
+/*void TextDisplayer_LoL::setAnimParameters(const char *str, int x, uint8 col1, uint8 col2) {
static const char defaultStr[] = "<MORE>";
if (str) {
@@ -152,7 +152,7 @@ void TextDisplayer_LoL::setAnimParameters(const char *str, int x, uint8 col1, ui
_animColor1 = 0;
_animColor2 = 0;
}
-}
+}*/
void TextDisplayer_LoL::printDialogueText(int dim, char *str, EMCState *script, const uint16 *paramList, int16 paramIndex) {
int oldDim = 0;
@@ -496,7 +496,7 @@ void TextDisplayer_LoL::printLine(char *str) {
int lines = (sd->h - _screen->_charOffset) / fh;
while (_textDimData[sdx].line >= lines) {
- if (lines <= _lineCount && _animFlag) {
+ if (lines <= _lineCount) {
_lineCount = 0;
textPageBreak();
_numCharsPrinted = 0;
@@ -521,8 +521,8 @@ void TextDisplayer_LoL::printLine(char *str) {
char c = 0;
if ((lw + _textDimData[sdx].column) > w) {
- if ((lines - 1) <= _lineCount && _animFlag)
- w -= (_animWidth * (_screen->getFontWidth() + _screen->_charWidth));
+ if ((lines - 1) <= _lineCount)
+ w -= (10 * (_screen->getFontWidth() + _screen->_charWidth));
w -= _textDimData[sdx].column;
@@ -608,7 +608,7 @@ void TextDisplayer_LoL::textPageBreak() {
}
uint32 speechPartTime = 0;
- if (_vm->_speechFlag && _vm->_activeVoiceFileTotalTime && _numCharsTotal)
+ if (_vm->speechEnabled() && _vm->_activeVoiceFileTotalTime && _numCharsTotal)
speechPartTime = _vm->_system->getMillis() + ((_numCharsPrinted * _vm->_activeVoiceFileTotalTime) / _numCharsTotal);
const ScreenDim *dim = _screen->getScreenDim(_screen->curDimIndex());
@@ -643,7 +643,7 @@ void TextDisplayer_LoL::textPageBreak() {
while (!inputFlag) {
_vm->update();
- if (_vm->_speechFlag) {
+ if (_vm->speechEnabled()) {
if (((_vm->_system->getMillis() > speechPartTime) || (_vm->snd_updateCharacterSpeech() != 2)) && speechPartTime) {
loop = false;
inputFlag = 43;
diff --git a/engines/kyra/text_lol.h b/engines/kyra/text_lol.h
index fc707843aa..06c13e1fef 100644
--- a/engines/kyra/text_lol.h
+++ b/engines/kyra/text_lol.h
@@ -40,9 +40,6 @@ public:
TextDisplayer_LoL(LoLEngine *vm, Screen_LoL *screen);
~TextDisplayer_LoL();
- void setAnimParameters(const char *str, int x, uint8 col1, uint8 col2);
- void setAnimFlag(bool flag) { _animFlag = flag; }
-
void setupField(bool mode);
void expandField();
@@ -80,12 +77,6 @@ private:
uint32 _numCharsLeft;
uint32 _numCharsPrinted;
- const char *_animString;
- int16 _animWidth;
- uint8 _animColor1;
- uint8 _animColor2;
-
- bool _animFlag;
bool _printFlag;
LoLEngine *_vm;
diff --git a/engines/kyra/text_mr.cpp b/engines/kyra/text_mr.cpp
index e28d97d154..40f651ab01 100644
--- a/engines/kyra/text_mr.cpp
+++ b/engines/kyra/text_mr.cpp
@@ -581,7 +581,7 @@ void KyraEngine_MR::albumChatWaitToFinish() {
frame = 13;
albumRestoreRect();
- _album.wsa->displayFrame(frame, 2, -100, 90, 0x4000);
+ _album.wsa->displayFrame(frame, 2, -100, 90, 0x4000, 0, 0);
albumUpdateRect();
nextFrame = _system->getMillis() + _rnd.getRandomNumberRng(4, 8) * _tickLength;
diff --git a/engines/kyra/util.cpp b/engines/kyra/util.cpp
index 794a1c78e3..fe02ba49ba 100644
--- a/engines/kyra/util.cpp
+++ b/engines/kyra/util.cpp
@@ -85,5 +85,68 @@ void Util::decodeString2(const char *src, char *dst) {
*dst = 0;
}
+void Util::convertDOSToISO(char *str) {
+ uint8 *s = (uint8 *)str;
+
+ for (; *s; ++s) {
+ if (*s >= 128) {
+ uint8 c = _charMapDOSToISO[*s - 128];
+
+ if (!c)
+ c = 0x20;
+
+ *s = c;
+ }
+ }
+}
+
+void Util::convertISOToDOS(char *str) {
+ while (*str)
+ convertISOToDOS(*str++);
+}
+
+void Util::convertISOToDOS(char &c) {
+ uint8 code = (uint8)c;
+ if (code >= 128) {
+ code = _charMapISOToDOS[code - 128];
+ if (!code)
+ code = 0x20;
+ }
+
+ c = code;
+}
+
+// CP850 to ISO-8859-1 (borrowed from engines/saga/font_map.cpp)
+const uint8 Util::_charMapDOSToISO[128] = {
+ 199, 252, 233, 226, 228, 224, 229, 231, 234, 235, 232,
+ 239, 238, 236, 196, 197, 201, 230, 198, 244, 246, 242,
+ 251, 249, 255, 214, 220, 248, 163, 216, 215, 0, 225,
+ 237, 243, 250, 241, 209, 170, 186, 191, 174, 172, 189,
+ 188, 161, 171, 187, 0, 0, 0, 0, 0, 193, 194,
+ 192, 169, 0, 0, 0, 0, 162, 165, 0, 0, 0,
+ 0, 0, 0, 0, 227, 195, 0, 0, 0, 0, 0,
+ 0, 0, 164, 240, 208, 202, 203, 200, 0, 205, 206,
+ 207, 0, 0, 0, 0, 166, 204, 0, 211, 223, 212,
+ 210, 245, 213, 181, 254, 222, 218, 219, 217, 253, 221,
+ 175, 180, 173, 177, 0, 190, 182, 167, 247, 184, 176,
+ 168, 183, 185, 179, 178, 0, 160
+};
+
+// ISO-8859-1 to CP850
+const uint8 Util::_charMapISOToDOS[128] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255,
+ 173, 189, 156, 207, 190, 221, 245, 249, 184, 166, 174,
+ 170, 240, 169, 238, 248, 241, 253, 252, 239, 230, 244,
+ 250, 247, 251, 167, 175, 172, 171, 243, 168, 183, 181,
+ 182, 199, 142, 143, 146, 128, 212, 144, 210, 211, 222,
+ 214, 215, 216, 209, 165, 227, 224, 226, 229, 153, 158,
+ 157, 235, 233, 234, 154, 237, 232, 225, 133, 160, 131,
+ 198, 132, 134, 145, 135, 138, 130, 136, 137, 141, 161,
+ 140, 139, 208, 164, 149, 162, 147, 228, 148, 246, 155,
+ 151, 163, 150, 129, 236, 231, 152
+};
+
} // end of namespace Kyra
diff --git a/engines/kyra/util.h b/engines/kyra/util.h
index ee869d9c04..6850a4d757 100644
--- a/engines/kyra/util.h
+++ b/engines/kyra/util.h
@@ -34,6 +34,16 @@ class Util {
public:
static int decodeString1(const char *src, char *dst);
static void decodeString2(const char *src, char *dst);
+
+ // Since our current GUI font uses ISO-8859-1, this
+ // conversion functionallty uses that as a base.
+ static void convertDOSToISO(char *str);
+ static void convertISOToDOS(char *str);
+ static void convertISOToDOS(char &c);
+
+private:
+ static const uint8 _charMapDOSToISO[128];
+ static const uint8 _charMapISOToDOS[128];
};
} // end of namespace Kyra
diff --git a/engines/kyra/vqa.cpp b/engines/kyra/vqa.cpp
index 0b8f9c99a2..1225bc9976 100644
--- a/engines/kyra/vqa.cpp
+++ b/engines/kyra/vqa.cpp
@@ -32,12 +32,14 @@
// The jung2.vqa movie does work, but only thanks to a grotesque hack.
+#include "kyra/vqa.h"
+
#include "common/system.h"
#include "sound/audiostream.h"
#include "sound/mixer.h"
+
#include "kyra/sound.h"
#include "kyra/screen.h"
-#include "kyra/vqa.h"
#include "kyra/resource.h"
namespace Kyra {
@@ -45,6 +47,7 @@ namespace Kyra {
VQAMovie::VQAMovie(KyraEngine_v1 *vm, OSystem *system) {
_system = system;
_vm = vm;
+ _screen = _vm->screen();
_opened = false;
_x = _y = _drawPage = -1;
}
@@ -474,13 +477,13 @@ void VQAMovie::displayFrame(uint frameNum) {
case MKID_BE('CPL0'): // Palette
assert(size <= 3 * 256);
- _file->read(_vm->screen()->_currentPalette, size);
+ _file->read(_screen->getPalette(0).getData(), size);
break;
case MKID_BE('CPLZ'): // Palette
inbuf = (byte *)allocBuffer(0, size);
_file->read(inbuf, size);
- Screen::decodeFrame4(inbuf, _vm->screen()->_currentPalette, 768);
+ Screen::decodeFrame4(inbuf, _screen->getPalette(0).getData(), 768);
break;
case MKID_BE('VPT0'): // Frame data
@@ -520,9 +523,8 @@ void VQAMovie::displayFrame(uint frameNum) {
// The frame has been decoded
- if (_frameInfo[frameNum] & 0x80000000) {
- _vm->screen()->setScreenPalette(_vm->screen()->_currentPalette);
- }
+ if (_frameInfo[frameNum] & 0x80000000)
+ _screen->setScreenPalette(_screen->getPalette(0));
int blockPitch = _header.width / _header.blockW;
@@ -562,7 +564,7 @@ void VQAMovie::displayFrame(uint frameNum) {
_partialCodeBookSize = 0;
}
- _vm->screen()->copyBlockToPage(_drawPage, _x, _y, _header.width, _header.height, _frame);
+ _screen->copyBlockToPage(_drawPage, _x, _y, _header.width, _header.height, _frame);
}
void VQAMovie::play() {
@@ -638,6 +640,7 @@ void VQAMovie::play() {
}
_vm->_mixer->playInputStream(Audio::Mixer::kSFXSoundType, &_sound, _stream);
+ Common::EventManager *eventMan = _vm->getEventManager();
for (uint i = 0; i < _header.numFrames; i++) {
displayFrame(i);
@@ -656,17 +659,17 @@ void VQAMovie::play() {
break;
Common::Event event;
-
- Common::EventManager *eventMan = _system->getEventManager();
while (eventMan->pollEvent(event)) {
switch (event.type) {
case Common::EVENT_KEYDOWN:
- if (event.kbd.ascii == 27)
+ if (event.kbd.keycode == Common::KEYCODE_ESCAPE)
return;
break;
+
case Common::EVENT_RTL:
case Common::EVENT_QUIT:
return;
+
default:
break;
}
@@ -675,7 +678,7 @@ void VQAMovie::play() {
_system->delayMillis(10);
}
- _vm->screen()->updateScreen();
+ _screen->updateScreen();
}
// TODO: Wait for the sound to finish?
diff --git a/engines/kyra/vqa.h b/engines/kyra/vqa.h
index 46d3bd48fb..98e279bd29 100644
--- a/engines/kyra/vqa.h
+++ b/engines/kyra/vqa.h
@@ -26,13 +26,24 @@
#ifndef KYRA_VQA_H
#define KYRA_VQA_H
-#include "common/stream.h"
+#include "common/scummsys.h"
+
+#include "sound/mixer.h"
class OSystem;
+namespace Audio {
+class AppendableAudioStream;
+} // end of namespace Audio
+
+namespace Common {
+class SeekableReadStream;
+} // end of namespace Common
+
namespace Kyra {
class KyraEngine_v1;
+class Screen;
class VQAMovie {
public:
@@ -57,6 +68,7 @@ public:
protected:
OSystem *_system;
KyraEngine_v1 *_vm;
+ Screen *_screen;
bool _opened;
int _x, _y;
diff --git a/engines/kyra/wsamovie.cpp b/engines/kyra/wsamovie.cpp
index 26638b8172..ef3fd1a966 100644
--- a/engines/kyra/wsamovie.cpp
+++ b/engines/kyra/wsamovie.cpp
@@ -38,7 +38,7 @@ namespace Kyra {
WSAMovie_v1::WSAMovie_v1(KyraEngine_v1 *vm) : Movie(vm) {}
WSAMovie_v1::~WSAMovie_v1() { close(); }
-int WSAMovie_v1::open(const char *filename, int offscreenDecode, uint8 *palBuf) {
+int WSAMovie_v1::open(const char *filename, int offscreenDecode, Palette *palBuf) {
close();
uint32 flags = 0;
@@ -64,7 +64,7 @@ int WSAMovie_v1::open(const char *filename, int offscreenDecode, uint8 *palBuf)
offsPal = 0x300;
_flags |= WF_HAS_PALETTE;
if (palBuf)
- memcpy(palBuf, wsaData + 8 + (_numFrames << 2), 0x300);
+ _screen->loadPalette(wsaData + 8 + ((_numFrames << 2) & 0xFFFF), *palBuf, 0x300);
}
if (offscreenDecode) {
@@ -137,19 +137,19 @@ void WSAMovie_v1::close() {
}
}
-void WSAMovie_v1::displayFrame(int frameNum, int pageNum, int x, int y, ...) {
- if (frameNum >= _numFrames || !_opened)
+void WSAMovie_v1::displayFrame(int frameNum, int pageNum, int x, int y, uint16 flags, const uint8 *table1, const uint8 *table2) {
+ if (frameNum >= _numFrames || frameNum < 0 || !_opened)
return;
_x = x;
_y = y;
_drawPage = pageNum;
- uint8 *dst;
+ uint8 *dst = 0;
if (_flags & WF_OFFSCREEN_DECODE)
dst = _offscreenBuffer;
else
- dst = _vm->screen()->getPageRect(_drawPage, _x, _y, _width, _height);
+ dst = _screen->getPageRect(_drawPage, _x, _y, _width, _height);
if (_currentFrame == _numFrames) {
if (!(_flags & WF_NO_FIRST_FRAME)) {
@@ -200,8 +200,16 @@ void WSAMovie_v1::displayFrame(int frameNum, int pageNum, int x, int y, ...) {
// display
_currentFrame = frameNum;
- if (_flags & WF_OFFSCREEN_DECODE)
- _vm->screen()->copyBlockToPage(_drawPage, _x, _y, _width, _height, _offscreenBuffer);
+ if (_flags & WF_OFFSCREEN_DECODE) {
+ int pageBackUp = _screen->setCurPage(_drawPage);
+
+ int plotFunc = (flags & 0xFF00) >> 12;
+ int unk1 = flags & 0xFF;
+
+ _screen->copyWsaRect(_x, _y, _width, _height, 0, plotFunc, _offscreenBuffer, unk1, table1, table2);
+
+ _screen->_curPage = pageBackUp;
+ }
}
void WSAMovie_v1::processFrame(int frameNum, uint8 *dst) {
@@ -220,7 +228,7 @@ void WSAMovie_v1::processFrame(int frameNum, uint8 *dst) {
WSAMovieAmiga::WSAMovieAmiga(KyraEngine_v1 *vm) : WSAMovie_v1(vm), _buffer(0) {}
-int WSAMovieAmiga::open(const char *filename, int offscreenDecode, uint8 *palBuf) {
+int WSAMovieAmiga::open(const char *filename, int offscreenDecode, Palette *palBuf) {
int res = WSAMovie_v1::open(filename, offscreenDecode, palBuf);
if (!res)
@@ -239,7 +247,7 @@ void WSAMovieAmiga::close() {
WSAMovie_v1::close();
}
-void WSAMovieAmiga::displayFrame(int frameNum, int pageNum, int x, int y, ...) {
+void WSAMovieAmiga::displayFrame(int frameNum, int pageNum, int x, int y, uint16 flags, const uint8 *table1, const uint8 *table2) {
if (frameNum >= _numFrames || frameNum < 0 || !_opened)
return;
@@ -266,7 +274,7 @@ void WSAMovieAmiga::displayFrame(int frameNum, int pageNum, int x, int y, ...) {
dst = _buffer;
} else {
- _vm->screen()->copyBlockToPage(_drawPage, _x, _y, _width, _height, _buffer);
+ _screen->copyBlockToPage(_drawPage, _x, _y, _width, _height, _buffer);
}
}
_currentFrame = 0;
@@ -311,8 +319,16 @@ void WSAMovieAmiga::displayFrame(int frameNum, int pageNum, int x, int y, ...) {
// display
_currentFrame = frameNum;
- if (_flags & WF_OFFSCREEN_DECODE)
- _vm->screen()->copyBlockToPage(_drawPage, _x, _y, _width, _height, _offscreenBuffer);
+ if (_flags & WF_OFFSCREEN_DECODE) {
+ int pageBackUp = _screen->setCurPage(_drawPage);
+
+ int plotFunc = (flags & 0xFF00) >> 12;
+ int unk1 = flags & 0xFF;
+
+ _screen->copyWsaRect(_x, _y, _width, _height, 0, plotFunc, _offscreenBuffer, unk1, table1, table2);
+
+ _screen->_curPage = pageBackUp;
+ }
}
void WSAMovieAmiga::processFrame(int frameNum, uint8 *dst) {
@@ -334,7 +350,7 @@ void WSAMovieAmiga::processFrame(int frameNum, uint8 *dst) {
dst = _offscreenBuffer;
dstPitch = _width;
} else {
- dst = _vm->screen()->getPageRect(_drawPage, _x, _y, _width, _height);
+ dst = _screen->getPageRect(_drawPage, _x, _y, _width, _height);
dstPitch = Screen::SCREEN_W;
}
@@ -347,9 +363,9 @@ void WSAMovieAmiga::processFrame(int frameNum, uint8 *dst) {
#pragma mark -
-WSAMovie_v2::WSAMovie_v2(KyraEngine_v1 *vm, Screen_v2 *screen) : WSAMovie_v1(vm), _screen(screen), _xAdd(0), _yAdd(0) {}
+WSAMovie_v2::WSAMovie_v2(KyraEngine_v1 *vm) : WSAMovie_v1(vm), _xAdd(0), _yAdd(0) {}
-int WSAMovie_v2::open(const char *filename, int unk1, uint8 *palBuf) {
+int WSAMovie_v2::open(const char *filename, int unk1, Palette *palBuf) {
close();
uint32 flags = 0;
@@ -376,7 +392,7 @@ int WSAMovie_v2::open(const char *filename, int unk1, uint8 *palBuf) {
offsPal = 0x300;
_flags |= WF_HAS_PALETTE;
if (palBuf)
- _vm->screen()->loadPalette(wsaData + 8 + ((_numFrames << 2) & 0xFFFF), palBuf, 0x300);
+ _screen->loadPalette(wsaData + 8 + ((_numFrames << 2) & 0xFFFF), *palBuf, 0x300);
}
if (flags & 2) {
@@ -384,7 +400,7 @@ int WSAMovie_v2::open(const char *filename, int unk1, uint8 *palBuf) {
offsPal = 0x30;
_flags |= WF_HAS_PALETTE;
if (palBuf)
- _vm->screen()->loadPalette(wsaData + 8 + ((_numFrames << 2) & 0xFFFF), palBuf, 0x30);
+ _screen->loadPalette(wsaData + 8 + ((_numFrames << 2) & 0xFFFF), *palBuf, 0x30);
}
_flags |= WF_XOR;
@@ -448,90 +464,6 @@ int WSAMovie_v2::open(const char *filename, int unk1, uint8 *palBuf) {
return _numFrames;
}
-void WSAMovie_v2::displayFrame(int frameNum, int pageNum, int x, int y, ...) {
- if (frameNum >= _numFrames || frameNum < 0 || !_opened)
- return;
-
- _x = x + _xAdd;
- _y = y + _yAdd;
- _drawPage = pageNum;
-
- uint8 *dst = 0;
- if (_flags & WF_OFFSCREEN_DECODE)
- dst = _offscreenBuffer;
- else
- dst = _screen->getPageRect(_drawPage, _x, _y, _width, _height);
-
- if (_currentFrame == _numFrames) {
- if (!(_flags & WF_NO_FIRST_FRAME)) {
- if (_flags & WF_OFFSCREEN_DECODE)
- Screen::decodeFrameDelta(dst, _deltaBuffer);
- else
- Screen::decodeFrameDeltaPage(dst, _deltaBuffer, _width, (_flags & WF_XOR) == 0);
- }
- _currentFrame = 0;
- }
-
- // try to reduce the number of needed frame operations
- int diffCount = ABS(_currentFrame - frameNum);
- int frameStep = 1;
- int frameCount;
- if (_currentFrame < frameNum) {
- frameCount = _numFrames - frameNum + _currentFrame;
- if (diffCount > frameCount && !(_flags & WF_NO_LAST_FRAME))
- frameStep = -1;
- else
- frameCount = diffCount;
- } else {
- frameCount = _numFrames - _currentFrame + frameNum;
- if (frameCount >= diffCount || (_flags & WF_NO_LAST_FRAME)) {
- frameStep = -1;
- frameCount = diffCount;
- }
- }
-
- // process
- if (frameStep > 0) {
- uint16 cf = _currentFrame;
- while (frameCount--) {
- cf += frameStep;
- processFrame(cf, dst);
- if (cf == _numFrames)
- cf = 0;
- }
- } else {
- uint16 cf = _currentFrame;
- while (frameCount--) {
- if (cf == 0)
- cf = _numFrames;
- processFrame(cf, dst);
- cf += frameStep;
- }
- }
-
- // display
- _currentFrame = frameNum;
- if (_flags & WF_OFFSCREEN_DECODE) {
- int pageBackUp = _screen->_curPage;
- _screen->_curPage = _drawPage;
-
- va_list args;
- va_start(args, y);
-
- int copyParam = va_arg(args, int);
- int plotFunc = (copyParam & 0xFF00) >> 12;
- int unk1 = copyParam & 0xFF;
-
- const uint8 *unkPtr1 = va_arg(args, const uint8*);
- const uint8 *unkPtr2 = va_arg(args, const uint8*);
- va_end(args);
-
- _screen->copyWsaRect(_x, _y, _width, _height, 0, plotFunc, _offscreenBuffer, unk1, unkPtr1, unkPtr2);
-
- _screen->_curPage = pageBackUp;
- }
-}
-
} // end of namespace Kyra
diff --git a/engines/kyra/wsamovie.h b/engines/kyra/wsamovie.h
index fdceca1cd8..49ac5a28fe 100644
--- a/engines/kyra/wsamovie.h
+++ b/engines/kyra/wsamovie.h
@@ -26,6 +26,7 @@
#ifndef KYRA_WSAMOVIE_H
#define KYRA_WSAMOVIE_H
+
namespace Audio {
class AppendableAudioStream;
class SoundHandle;
@@ -34,10 +35,11 @@ class SoundHandle;
namespace Kyra {
class KyraEngine_v1;
class Screen_v2;
+class Palette;
class Movie {
public:
- Movie(KyraEngine_v1 *vm) : _vm(vm), _opened(false), _x(-1), _y(-1), _drawPage(-1) {}
+ Movie(KyraEngine_v1 *vm) : _vm(vm), _screen(vm->screen()), _opened(false), _x(-1), _y(-1), _drawPage(-1) {}
virtual ~Movie() {}
virtual bool opened() { return _opened; }
@@ -48,15 +50,16 @@ public:
virtual int width() const = 0;
virtual int height() const = 0;
- virtual int open(const char *filename, int offscreen, uint8 *palette) = 0;
+ virtual int open(const char *filename, int offscreen, Palette *palette) = 0;
virtual void close() = 0;
virtual int frames() = 0;
- virtual void displayFrame(int frameNum, int pageNum, int x, int y, ...) = 0;
+ virtual void displayFrame(int frameNum, int pageNum, int x, int y, uint16 flags, const uint8 *table1, const uint8 *table2) = 0;
protected:
KyraEngine_v1 *_vm;
+ Screen *_screen;
bool _opened;
int _x, _y;
@@ -71,12 +74,12 @@ public:
int width() const { return _width; }
int height() const { return _height; }
- virtual int open(const char *filename, int offscreen, uint8 *palette);
+ virtual int open(const char *filename, int offscreen, Palette *palette);
virtual void close();
virtual int frames() { return _opened ? _numFrames : -1; }
- virtual void displayFrame(int frameNum, int pageNum, int x, int y, ...);
+ virtual void displayFrame(int frameNum, int pageNum, int x, int y, uint16 flags, const uint8 *table1, const uint8 *table2);
enum WSAFlags {
WF_OFFSCREEN_DECODE = 0x10,
@@ -104,10 +107,10 @@ protected:
class WSAMovieAmiga : public WSAMovie_v1 {
public:
WSAMovieAmiga(KyraEngine_v1 *vm);
- int open(const char *filename, int offscreen, uint8 *palette);
+ int open(const char *filename, int offscreen, Palette *palette);
void close();
- void displayFrame(int frameNum, int pageNum, int x, int y, ...);
+ void displayFrame(int frameNum, int pageNum, int x, int y, uint16 flags, const uint8 *table1, const uint8 *table2);
private:
void processFrame(int frameNum, uint8 *dst);
@@ -116,11 +119,12 @@ private:
class WSAMovie_v2 : public WSAMovie_v1 {
public:
- WSAMovie_v2(KyraEngine_v1 *vm, Screen_v2 *screen);
-
- int open(const char *filename, int unk1, uint8 *palette);
+ WSAMovie_v2(KyraEngine_v1 *vm);
- virtual void displayFrame(int frameNum, int pageNum, int x, int y, ...);
+ int open(const char *filename, int unk1, Palette *palette);
+ virtual void displayFrame(int frameNum, int pageNum, int x, int y, uint16 flags, const uint8 *table1, const uint8 *table2) {
+ WSAMovie_v1::displayFrame(frameNum, pageNum, x + _xAdd, y + _yAdd, flags, table1, table2);
+ }
int xAdd() const { return _xAdd; }
int yAdd() const { return _yAdd; }
@@ -128,8 +132,6 @@ public:
void setWidth(int w) { _width = w; }
void setHeight(int h) { _height = h; }
protected:
- Screen_v2 *_screen;
-
int16 _xAdd;
int16 _yAdd;
};