LOL: - started on the ingame menu code (death menu, load menu and main menu)

- fixed regression in kyra gui code (broken menu highlighting)
- fixed minor bug in animation code

svn-id: r41557
This commit is contained in:
Florian Kagerer 2009-06-15 20:52:09 +00:00
parent f2e3ddf72a
commit 583a89be62
18 changed files with 642 additions and 96 deletions

View File

@ -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,47 @@ 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) {
printMenuText(getMenuItemLabel(menu.item[i]), menu.x + menu.item[i].labelX, menu.y + menu.item[i].labelY, menu.item[i].textColor, 0, 8);
} 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 +188,11 @@ 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;
for (int i = 0; i < menu.numberOfItems; ++i) {
if (!menu.item[i].enabled)
@ -189,8 +208,12 @@ void GUI::processHighlights(Menu &menu, int mouseX, int mouseY) {
mouseY > y1 && mouseY < y2) {
if (menu.highlightedItem != i) {
if (menu.item[menu.highlightedItem].enabled)
redrawText(menu);
// LoL doesnt't have default highlighted items.
// We use a highlightedItem value of 255 for this.
if (menu.highlightedItem != 255) {
if (menu.item[menu.highlightedItem].enabled)
redrawText(menu);
}
menu.highlightedItem = i;
redrawHighlight(menu);
@ -212,11 +235,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 +259,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 +330,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 +345,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 +419,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) {

View File

@ -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;

View File

@ -763,7 +763,7 @@ int GUI_HoF::optionsButton(Button *button) {
}
while (_displayMenu) {
processHighlights(*_currentMenu, _vm->_mouseX, _vm->_mouseY);
processHighlights(*_currentMenu);
getInput();
}
@ -908,7 +908,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 +956,7 @@ int GUI_HoF::gameOptions(Button *caller) {
}
while (_isOptionsMenu) {
processHighlights(_gameOptions, _vm->_mouseX, _vm->_mouseY);
processHighlights(_gameOptions);
getInput();
}
@ -983,7 +983,7 @@ int GUI_HoF::gameOptionsTalkie(Button *caller) {
_isOptionsMenu = true;
while (_isOptionsMenu) {
processHighlights(_gameOptions, _vm->_mouseX, _vm->_mouseY);
processHighlights(_gameOptions);
getInput();
}
@ -1175,7 +1175,7 @@ int GUI_HoF::loadMenu(Button *caller) {
_screen->updateScreen();
while (_isLoadMenu) {
processHighlights(_loadMenu, _vm->_mouseX, _vm->_mouseY);
processHighlights(_loadMenu);
getInput();
}

View File

@ -479,7 +479,7 @@ int GUI_LoK::buttonMenuCallback(Button *caller) {
}
while (_displayMenu && !_vm->shouldQuit()) {
processHighlights(_menu[_toplevelMenu], _vm->_mouseX, _vm->_mouseY);
processHighlights(_menu[_toplevelMenu]);
getInput();
}
@ -570,7 +570,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 +616,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();
}
@ -703,7 +703,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) {
@ -773,7 +773,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 +833,7 @@ int GUI_LoK::gameControlsMenu(Button *button) {
_cancelSubMenu = false;
while (_displaySubMenu && !_vm->shouldQuit()) {
processHighlights(_menu[5], _vm->_mouseX, _vm->_mouseY);
processHighlights(_menu[5]);
getInput();
}

View File

@ -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;

View File

@ -28,6 +28,11 @@
#include "kyra/lol.h"
#include "kyra/screen_lol.h"
#include "kyra/gui_lol.h"
#include "kyra/resource.h"
#include "common/savefile.h"
#include "base/version.h"
namespace Kyra {
@ -1536,10 +1541,48 @@ 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);
_gui->runMenu(_gui->_mainMenu);
_updateFlags &= 0xfffb;
setMouseCursorToItemInHand();
resetLampStatus();
gui_enableDefaultPlayfieldButtons();
enableSysTimer(2);
updateDrawPage2();
char filename[13];
snprintf(filename, sizeof(filename), "LEVEL%02d.%s", _currentLevel, _languageExt[_lang]);
if (_levelLangFile)
delete[] _levelLangFile;
_levelLangFile = _res->fileData(filename, 0);
snprintf(filename, sizeof(filename), "LANDS.%s", _languageExt[_lang]);
if (_landsFile)
delete[] _landsFile;
_landsFile = _res->fileData(filename, 0);
// if (!_speechFlag)
// enableText()
return 1;
}
@ -1826,6 +1869,9 @@ 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;
@ -1942,8 +1988,9 @@ int GUI_LoL::processButtonList(Button *buttonList, uint16 inputFlag, int8 mouseW
}
}
int mouseX = _vm->_mouseX;
int mouseY = _vm->_mouseY;
Common::Point p = _vm->getMousePos();
int mouseX = p.x;
int mouseY = p.y;
uint16 flags = 0;
@ -2164,6 +2211,275 @@ 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();
// 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 not.
uint8 hasScrollButtons = 0;
while (_displayMenu) {
_vm->_mouseX = _vm->_mouseY = 0;
if (_currentMenu == &_loadMenu || _currentMenu == &_saveMenu) {
updateSaveList(true);
Common::sort(_saveSlots.begin(), _saveSlots.end(), Common::Greater<int>());
setupSavegameNames(*_currentMenu, 4);
}
hasScrollButtons = _currentMenu->highlightedItem;
_currentMenu->highlightedItem = 255;
if (hasScrollButtons) {
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 (_currentMenu == &_mainMenu) {
Screen::FontId f = _screen->setFont(Screen::FID_6_FNT);
_screen->fprintString("SVN %s", menu.x + 8, menu.y + menu.height - 12, 204, 0, 8, gScummVMVersion);
_screen->setFont(f);
_screen->updateScreen();
}
while (!_newMenu && _displayMenu) {
processHighlights(*_currentMenu);
if (getInput()) {
if (!_newMenu)
_newMenu = _currentMenu;
else
_lastMenu = _currentMenu;
}
if (!_menuResult)
_displayMenu = false;
}
if (_newMenu != _currentMenu || !_displayMenu)
restorePage0();
_currentMenu->highlightedItem = hasScrollButtons;
if (_newMenu)
_currentMenu = _newMenu;
_newMenu = 0;
}
return _menuResult;
}
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]), header)) != 0) {
strncpy(s, header.description.c_str(), 80);
s[79] = 0;
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) {
char *dst = _vm->getLangString(menu.item[0].itemId);
const char *src = _vm->getLangString(_vm->gameFlags().isTalkie ? 10 : 18);
strcpy(dst, src);
menu.item[0].saveSlot = -2;
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;
int inputFlag = _vm->checkInput(_menuButtonList);
_vm->removeInputTop();
if (_vm->shouldQuit())
_displayMenu = false;
_vm->delay(10);
return inputFlag & 0x8000 ? 1 : 0;
}
int GUI_LoL::clickedMainMenu(Button *button) {
updateMenuButton(button);
switch (button->arg) {
case 0x4001:
_newMenu = &_loadMenu;
break;
case 0x4002:
//_newMenu = &_saveMenu;
break;
case 0x4003:
//_newMenu = &_deleteMenu;
break;
case 0x4004:
//_newMenu = &_gameOptions;
break;
case 0x42D9:
//_newMenu = &_audioOptions;
break;
case 0x4006:
//_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::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::scrollUp(Button *button) {
updateButton(button);
if (_savegameOffset > 0) {
_savegameOffset--;
_newMenu = _currentMenu;
}
return 1;
}
int GUI_LoL::scrollDown(Button *button) {
updateButton(button);
if ((uint)_savegameOffset < _saveSlots.size() - 4) {
_savegameOffset++;
_newMenu = _currentMenu;
}
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)
return 0;
return _vm->getLangString(menuItem.itemId);
}
const char *GUI_LoL::getMenuItemLabel(const MenuItem &menuItem) {
if (!menuItem.labelId)
return 0;
return _vm->getLangString(menuItem.labelId);
}
} // end of namespace Kyra
#endif // ENABLE_LOL

View File

@ -31,6 +31,48 @@
#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.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.labelX = 0; \
item.labelY = 0; \
item.keyCode = g; \
} while (0)
class LoLEngine;
class Screen_LoL;
@ -40,14 +82,60 @@ 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) {}
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 clickedDeathMenu(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[7];
Button _scrollUpButton;
Button _scrollDownButton;
Menu _mainMenu, _gameOptions, _audioOptions, _choiceMenu, _loadMenu, _saveMenu, _savenameMenu, _deathMenu;
Menu *_currentMenu, *_lastMenu, *_newMenu;
int _menuResult;
LoLEngine *_vm;
Screen_LoL *_screen;
@ -59,24 +147,10 @@ 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;
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

View File

@ -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();
}

View File

@ -601,7 +601,7 @@ int GUI_v2::saveMenu(Button *caller) {
updateAllMenuButtons();
while (_isSaveMenu) {
processHighlights(_saveMenu, _vm->_mouseX, _vm->_mouseY);
processHighlights(_saveMenu);
getInput();
}
@ -697,7 +697,7 @@ int GUI_v2::deleteMenu(Button *caller) {
updateAllMenuButtons();
while (_isDeleteMenu) {
processHighlights(_saveMenu, _vm->_mouseX, _vm->_mouseY);
processHighlights(_saveMenu);
getInput();
}
@ -749,7 +749,7 @@ 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);
if (_keyPressed.keycode == Common::KEYCODE_RETURN || _keyPressed.keycode == Common::KEYCODE_KP_ENTER || _finishNameInput) {
if (checkSavegameDescription(buffer, curPos)) {
buffer[curPos] = 0;
@ -840,7 +840,7 @@ bool GUI_v2::choiceDialog(int name, bool type) {
_choice = false;
while (_isChoiceMenu) {
processHighlights(_choiceMenu, _vm->_mouseX, _vm->_mouseY);
processHighlights(_choiceMenu);
getInput();
}

View File

@ -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;

View File

@ -436,6 +436,7 @@ Common::Error LoLEngine::init() {
_gui = new GUI_LoL(this);
assert(_gui);
_gui->initStaticData();
_txt = new TextDisplayer_LoL(this, _screen);
@ -561,7 +562,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 +592,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 +638,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) {
@ -754,13 +762,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);
@ -858,6 +859,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;
@ -3282,6 +3289,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) {

View File

@ -587,7 +587,7 @@ private:
int clickedAutomap(Button *button);
int clickedLamp(Button *button);
int clickedStatusIcon(Button *button);
const ButtonDef *_buttonData;
int _buttonDataSize;
const int16 *_buttonList1;

View File

@ -887,17 +887,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);
drawClippedLine(x1, y2, x2, y2, color2);
drawClippedLine(x1, y2 - 1, x2 - 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);
showMouse();
}

View File

@ -153,9 +153,13 @@ public:
uint8 *getPalette(int num);
// 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

View File

@ -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);
@ -956,7 +956,7 @@ uint8 *Screen_LoL::generateFadeTable(uint8 *dst, uint8 *src1, uint8 *src2, int n
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;
}
}

View File

@ -1133,7 +1133,9 @@ void TIMInterpreter_LoL::playAnimationPart(int animIndex, int firstFrame, int la
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);
}
}
@ -1166,7 +1168,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;
}
@ -1226,7 +1229,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;

View File

@ -71,11 +71,13 @@ 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
memset(_screen->getPalette(0), 0, 768);
_screen->fadePalette(_screen->getPalette(0), 0x54);
}
switch (selection) {
case 0: // New game
@ -90,7 +92,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 +103,7 @@ int LoLEngine::processPrologue() {
}
}
if (processSelection == 0 || processSelection == 3) {
if (processSelection == 0) {
_sound->loadSoundFile(0);
_sound->playTrack(6);
chooseCharacter();

View File

@ -2011,6 +2011,42 @@ 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(_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;
}
#endif // ENABLE_LOL