diff options
Diffstat (limited to 'engines/startrek/text.cpp')
-rw-r--r-- | engines/startrek/text.cpp | 259 |
1 files changed, 185 insertions, 74 deletions
diff --git a/engines/startrek/text.cpp b/engines/startrek/text.cpp index b7a642caca..8c4f05ca1e 100644 --- a/engines/startrek/text.cpp +++ b/engines/startrek/text.cpp @@ -26,22 +26,39 @@ #include "startrek/graphics.h" -// List of events that can be returned by handleTextboxEvents. -enum TextEvent { - TEXTEVENT_RCLICK_OFFBUTTON = -4, - TEXTEVENT_ENABLEINPUT, // Makes buttons selectable (occurs after a delay) - TEXTEVENT_RCLICK_ONBUTTON, - TEXTEVENT_LCLICK_OFFBUTTON, - TEXTEVENT_CONFIRM = 0, - TEXTEVENT_SCROLLUP, - TEXTEVENT_SCROLLDOWN, - TEXTEVENT_PREVCHOICE, - TEXTEVENT_NEXTCHOICE, - TEXTEVENT_SCROLLUP_ONELINE, - TEXTEVENT_SCROLLDOWN_ONELINE, - TEXTEVENT_GOTO_TOP, - TEXTEVENT_GOTO_BOTTOM, - TEXTEVENT_SPEECH_DONE +// Special events that can be returned by handleMenuEvents. +enum MenuEvent { + MENUEVENT_RCLICK_OFFBUTTON = -4, + MENUEVENT_ENABLEINPUT, // Makes buttons selectable (occurs after a delay) + MENUEVENT_RCLICK_ONBUTTON, + MENUEVENT_LCLICK_OFFBUTTON, +}; + +// Buttons for standard text display +enum TextButtons { + TEXTBUTTON_CONFIRM = 0, + TEXTBUTTON_SCROLLUP, + TEXTBUTTON_SCROLLDOWN, + TEXTBUTTON_PREVCHOICE, + TEXTBUTTON_NEXTCHOICE, + TEXTBUTTON_SCROLLUP_ONELINE, + TEXTBUTTON_SCROLLDOWN_ONELINE, + TEXTBUTTON_GOTO_TOP, + TEXTBUTTON_GOTO_BOTTOM, + TEXTBUTTON_SPEECH_DONE // "Virtual" button? +}; + +// Buttons for option menu (corresponding to button indices, not button retvals, which are +// different for some reason) +enum OptionMenuButtons { + OPTIONBUTTON_TEXT, + OPTIONBUTTON_SAVE, + OPTIONBUTTON_LOAD, + OPTIONBUTTON_ENABLEMUSIC, + OPTIONBUTTON_DISABLEMUSIC, + OPTIONBUTTON_ENABLESFX, + OPTIONBUTTON_DISABLESFX, + OPTIONBUTTON_QUIT }; namespace StarTrek { @@ -88,13 +105,13 @@ int Graphics::showText(TextGetterFunc textGetter, uintptr var, int xoffset, int int choiceIndex = 0; int scrollOffset = 0; if (tmpTextDisplayMode != TEXTDISPLAY_WAIT && tmpTextDisplayMode != TEXTDISPLAY_SUBTITLES - && numChoices == 1 && _vm->_sfxEnabled && !_vm->_audioEnabled) + && numChoices == 1 && _vm->_sfxEnabled && !_vm->_sfxWorking) _textboxHasMultipleChoices = false; else _textboxHasMultipleChoices = true; if (tmpTextDisplayMode >= TEXTDISPLAY_WAIT && tmpTextDisplayMode <= TEXTDISPLAY_NONE - && _vm->_sfxEnabled && !_vm->_audioEnabled) + && _vm->_sfxEnabled && !_vm->_sfxWorking) _textboxVar6 = true; else _textboxVar6 = false; @@ -106,7 +123,7 @@ int Graphics::showText(TextGetterFunc textGetter, uintptr var, int xoffset, int // TODO } else { - loadMenuButtons("textbtns", xoffset+0x96, yoffset-0x11); + loadMenuButtons("textbtns", xoffset + 0x96, yoffset - 0x11); Common::Point oldMousePos = getMousePos(); SharedPtr<Bitmap> oldMouseBitmap = _mouseBitmap; @@ -114,35 +131,35 @@ int Graphics::showText(TextGetterFunc textGetter, uintptr var, int xoffset, int _vm->_system->warpMouse(xoffset + 0xde, yoffset - 0x08); setMouseCursor(loadBitmap("pushbtn")); - uint16 tmpTextboxVar7 = _textboxVar7; - _textboxVar7 = 0; + bool tmpMouseControllingShip = _vm->_mouseControllingShip; + _vm->_mouseControllingShip = false; int var80 = (numChoices > 1 ? 0x18 : 0); // TODO: sub_288FB function call - disableMenuButton(0x0002); // Disable scroll up + disableMenuButtons(1 << TEXTBUTTON_SCROLLUP); // Disable scroll up if (var7c == 0) { // Disable done button - disableMenuButton(0x0001); + disableMenuButtons(1 << TEXTBUTTON_CONFIRM); } if (!loopChoices) { // Disable prev button - disableMenuButton(0x0008); + disableMenuButtons(1 << TEXTBUTTON_PREVCHOICE); } bool doneShowingText = false; // Loop until text is done being displayed while (!doneShowingText) { - int textboxReturnCode = handleTextboxEvents(var7c, true); + int textboxReturnCode = handleMenuEvents(var7c, true); if (var7c == 0) { - enableMenuButton(0x0001); + enableMenuButtons(1 << TEXTBUTTON_CONFIRM); } switch(textboxReturnCode) { - case TEXTEVENT_RCLICK_OFFBUTTON: - case TEXTEVENT_RCLICK_ONBUTTON: + case MENUEVENT_RCLICK_OFFBUTTON: + case MENUEVENT_RCLICK_ONBUTTON: if (var7c == 0) { doneShowingText = true; if (arg10) @@ -150,50 +167,50 @@ int Graphics::showText(TextGetterFunc textGetter, uintptr var, int xoffset, int } break; - case TEXTEVENT_CONFIRM: + case TEXTBUTTON_CONFIRM: doneShowingText = true; break; - case TEXTEVENT_SCROLLUP: + case TEXTBUTTON_SCROLLUP: scrollOffset -= numTextboxLines; goto readjustScrollUp; - case TEXTEVENT_SCROLLDOWN: + case TEXTBUTTON_SCROLLDOWN: scrollOffset += numTextboxLines; goto readjustScrollDown; - case TEXTEVENT_SCROLLUP_ONELINE: + case TEXTBUTTON_SCROLLUP_ONELINE: scrollOffset--; goto readjustScrollUp; - case TEXTEVENT_SCROLLDOWN_ONELINE: + case TEXTBUTTON_SCROLLDOWN_ONELINE: scrollOffset++; goto readjustScrollDown; - case TEXTEVENT_GOTO_TOP: + case TEXTBUTTON_GOTO_TOP: scrollOffset = 0; goto readjustScrollUp; - case TEXTEVENT_GOTO_BOTTOM: + case TEXTBUTTON_GOTO_BOTTOM: scrollOffset = numTextLines - numTextboxLines; goto readjustScrollDown; readjustScrollUp: - enableMenuButton(0x0004); + enableMenuButtons(1 << TEXTBUTTON_SCROLLDOWN); if (scrollOffset < 0) scrollOffset = 0; if (scrollOffset == 0) - disableMenuButton(0x0002); + disableMenuButtons(1 << TEXTBUTTON_SCROLLUP); goto readjustScroll; readjustScrollDown: - enableMenuButton(0x0002); + enableMenuButtons(1 << TEXTBUTTON_SCROLLUP); if (scrollOffset >= numTextLines) scrollOffset -= numTextboxLines; if (scrollOffset > numTextLines-1) scrollOffset = numTextLines-1; if (scrollOffset+numTextboxLines >= numTextLines) - disableMenuButton(0x0004); + disableMenuButtons(1 << TEXTBUTTON_SCROLLDOWN); goto readjustScroll; readjustScroll: @@ -206,23 +223,23 @@ readjustScroll: numChoicesWithNames != 0); break; - case TEXTEVENT_PREVCHOICE: + case TEXTBUTTON_PREVCHOICE: choiceIndex--; if (!loopChoices && choiceIndex == 0) { - disableMenuButton(0x0008); + disableMenuButtons(1 << TEXTBUTTON_PREVCHOICE); } else { if (choiceIndex < 0) choiceIndex = numChoices-1; } - enableMenuButton(0x0010); + enableMenuButtons(1 << TEXTBUTTON_NEXTCHOICE); goto reloadText; - case TEXTEVENT_NEXTCHOICE: - enableMenuButton(0x0008); + case TEXTBUTTON_NEXTCHOICE: + enableMenuButtons(1 << TEXTBUTTON_PREVCHOICE); choiceIndex++; if (!loopChoices && choiceIndex == numChoices-1) { - disableMenuButton(0x0010); + disableMenuButtons(1 << TEXTBUTTON_NEXTCHOICE); } else { choiceIndex %= numChoices; @@ -238,18 +255,18 @@ reloadText: else { // sub_288FB(0x001F); } - enableMenuButton(0x0004); - disableMenuButton(0x0002); + enableMenuButtons(1 << TEXTBUTTON_SCROLLDOWN); + disableMenuButtons(1 << TEXTBUTTON_SCROLLUP); textboxSprite.bitmapChanged = true; break; - case TEXTEVENT_SPEECH_DONE: + case TEXTBUTTON_SPEECH_DONE: if (numChoices == 1) doneShowingText = true; break; - case TEXTEVENT_ENABLEINPUT: - case TEXTEVENT_LCLICK_OFFBUTTON: + case MENUEVENT_ENABLEINPUT: + case MENUEVENT_LCLICK_OFFBUTTON: default: break; } @@ -258,10 +275,10 @@ reloadText: setMouseCursor(oldMouseBitmap); _vm->_system->warpMouse(oldMousePos.x, oldMousePos.y); - _textboxVar7 = tmpTextboxVar7; - // sub_29326(); - textboxSprite.field16 = 1; - textboxSprite.bitmapChanged = 1; + _vm->_mouseControllingShip = tmpMouseControllingShip; + unloadMenuButtons(); + textboxSprite.field16 = true; + textboxSprite.bitmapChanged = true; drawAllSprites(); delSprite(&textboxSprite); @@ -273,7 +290,11 @@ reloadText: return choiceIndex; } -int Graphics::handleTextboxEvents(uint32 ticksUntilClickingEnabled, bool arg4) { +/** + * This returns either a special menu event (negative number) or the retval of the button + * clicked (usually an index, always positive). + */ +int Graphics::handleMenuEvents(uint32 ticksUntilClickingEnabled, bool arg4) { // TODO: finish uint32 tickWhenClickingEnabled = _vm->_clockTicks + ticksUntilClickingEnabled; @@ -316,14 +337,14 @@ int Graphics::handleTextboxEvents(uint32 ticksUntilClickingEnabled, bool arg4) { if (_vm->_finishedPlayingSpeech != 0) { _vm->_finishedPlayingSpeech = 0; if (_textDisplayMode != TEXTDISPLAY_WAIT) { - return TEXTEVENT_SPEECH_DONE; + return TEXTBUTTON_SPEECH_DONE; } } // sub_1E88C(); _textboxVar3++; if (ticksUntilClickingEnabled != 0 && _vm->_clockTicks >= tickWhenClickingEnabled) - return TEXTEVENT_ENABLEINPUT; + return MENUEVENT_ENABLEINPUT; break; } @@ -336,7 +357,7 @@ int Graphics::handleTextboxEvents(uint32 ticksUntilClickingEnabled, bool arg4) { Common::Point mouse = getMousePos(); if (getMenuButtonAt(*_activeMenu, mouse.x, mouse.y) == -1) { _vm->playSoundEffectIndex(0x10); - return TEXTEVENT_LCLICK_OFFBUTTON; + return MENUEVENT_LCLICK_OFFBUTTON; } } break; @@ -559,14 +580,14 @@ String Graphics::readLineFormattedText(TextGetterFunc textGetter, uintptr var, i String headerText; String text = (this->*textGetter)(choiceIndex, var, &headerText); - if (_textDisplayMode == TEXTDISPLAY_NONE && _vm->_sfxEnabled && _vm->_audioEnabled) { + if (_textDisplayMode == TEXTDISPLAY_NONE && _vm->_sfxEnabled && _vm->_sfxWorking) { uint32 oldSize = text.size(); text = playTextAudio(text); if (oldSize != text.size()) _textboxHasMultipleChoices = true; } else if ((_textDisplayMode == TEXTDISPLAY_WAIT || _textDisplayMode == TEXTDISPLAY_SUBTITLES) - && _vm->_sfxEnabled && _vm->_audioEnabled) { + && _vm->_sfxEnabled && _vm->_sfxWorking) { text = playTextAudio(text); } else { @@ -732,7 +753,7 @@ String Graphics::playTextAudio(const String &str) { * Returns the index of the button at the given position, or -1 if none. */ int Graphics::getMenuButtonAt(const Menu &menu, int x, int y) { - for (int i=0; i<menu.numButtons; i++) { + for (int i = 0; i < menu.numButtons; i++) { const Sprite &spr = menu.sprites[i]; if (spr.drawMode != 2) @@ -780,7 +801,13 @@ void Graphics::drawMenuButtonOutline(SharedPtr<Bitmap> bitmap, byte color) { } } +/** + * Loads a .MNU file, which is a list of buttons to display. + */ void Graphics::loadMenuButtons(String mnuFilename, int xpos, int ypos) { + if (_activeMenu == nullptr) + _keyboardControlsMouseOutsideMenu = _vm->_keyboardControlsMouse; + SharedPtr<Menu> oldMenu = _activeMenu; _activeMenu = SharedPtr<Menu>(new Menu()); _activeMenu->nextMenu = oldMenu; @@ -790,7 +817,7 @@ void Graphics::loadMenuButtons(String mnuFilename, int xpos, int ypos) { _activeMenu->menuFile = stream; _activeMenu->numButtons = _activeMenu->menuFile->size()/16; - for (int i=0; i<_activeMenu->numButtons; i++) { + for (int i = 0; i < _activeMenu->numButtons; i++) { memset(&_activeMenu->sprites[i], 0, sizeof(Sprite)); addSprite(&_activeMenu->sprites[i]); _activeMenu->sprites[i].drawMode = 2; @@ -814,25 +841,49 @@ void Graphics::loadMenuButtons(String mnuFilename, int xpos, int ypos) { if (_activeMenu->retvals[_activeMenu->numButtons-1] == 0) { // Set default retvals for buttons - for (int i=0; i<_activeMenu->numButtons; i++) + for (int i = 0; i < _activeMenu->numButtons; i++) _activeMenu->retvals[i] = i; } _activeMenu->selectedButton = -1; _activeMenu->disabledButtons = 0; - _textboxButtonVar4 = 0; + _vm->_keyboardControlsMouse = false; } -// Values for standard text displays: -// 0x0001: Disable done button -// 0x0002: Disable scroll up -// 0x0004: Disable scroll down -// 0x0008: Disable prev choice -// 0x0010: Disable next choice -void Graphics::disableMenuButton(uint32 bits) { +void Graphics::unloadMenuButtons() { + if (_activeMenu->selectedButton != -1) + drawMenuButtonOutline(_activeMenu->sprites[_activeMenu->selectedButton].bitmap, 0x00); + + for (int i = 0; i < _activeMenu->numButtons; i++) { + Sprite *sprite = &_activeMenu->sprites[i]; + if (sprite->drawMode == 2) { + sprite->field16 = true; + sprite->bitmapChanged = true; + } + } + + drawAllSprites(); + + for (int i = 0; i < _activeMenu->numButtons; i++) { + Sprite *sprite = &_activeMenu->sprites[i]; + sprite->bitmap.reset(); + if (sprite->drawMode == 2) + delSprite(sprite); + } + + _activeMenu = _activeMenu->nextMenu; + + if (_activeMenu == nullptr) + _vm->_keyboardControlsMouse = _keyboardControlsMouseOutsideMenu; +} + +/** + * Disables the given bitmask of buttons. + */ +void Graphics::disableMenuButtons(uint32 bits) { _activeMenu->disabledButtons |= bits; if (_activeMenu->selectedButton != -1 - && (_activeMenu->disabledButtons & (1<<_activeMenu->selectedButton))) { + && (_activeMenu->disabledButtons & (1 << _activeMenu->selectedButton))) { Sprite *sprite = &_activeMenu->sprites[_activeMenu->selectedButton]; drawMenuButtonOutline(sprite->bitmap, 0x00); @@ -841,15 +892,75 @@ void Graphics::disableMenuButton(uint32 bits) { } } -void Graphics::enableMenuButton(uint32 bits) { +void Graphics::enableMenuButtons(uint32 bits) { _activeMenu->disabledButtons &= ~bits; } + +void Graphics::showOptionsMenu(int x, int y) { + bool tmpMouseControllingShip = _vm->_mouseControllingShip; + _vm->_mouseControllingShip = false; + + Common::Point oldMousePos = getMousePos(); + SharedPtr<Bitmap> oldMouseBitmap = _mouseBitmap; + + setMouseCursor(loadBitmap("options")); + loadMenuButtons("options", x, y); + + uint32 disabledButtons = 0; + if (_vm->_musicWorking) { + if (_vm->_musicEnabled) + disabledButtons |= (1 << OPTIONBUTTON_ENABLEMUSIC); + else + disabledButtons |= (1 << OPTIONBUTTON_DISABLEMUSIC); + } + else + disabledButtons |= (1 << OPTIONBUTTON_ENABLEMUSIC) | (1 << OPTIONBUTTON_DISABLEMUSIC); + + if (_vm->_sfxWorking) { + if (_vm->_sfxEnabled) + disabledButtons |= (1 << OPTIONBUTTON_ENABLESFX); + else + disabledButtons |= (1 << OPTIONBUTTON_DISABLESFX); + } + else + disabledButtons |= (1 << OPTIONBUTTON_ENABLESFX) | (1 << OPTIONBUTTON_DISABLESFX); + + disableMenuButtons(disabledButtons); + // sub_28b5d(); + int event = handleMenuEvents(0, false); + + unloadMenuButtons(); + _vm->_mouseControllingShip = tmpMouseControllingShip; + setMouseCursor(oldMouseBitmap); + + if (event != MENUEVENT_LCLICK_OFFBUTTON && event != MENUEVENT_RCLICK_OFFBUTTON) + _vm->_system->warpMouse(oldMousePos.x, oldMousePos.y); + + + // Can't use OPTIONBUTTON constants since the button retvals differ from the button + // indices... + switch(event) { // TODO + case 0: // Save + case 1: // Load + case 2: // Enable music + case 3: // Disable music + case 4: // Enable sfx + case 5: // Disable sfx + case 6: // Quit + case 7: // Text + showTextConfigurationMenu(true); + break; + default: + break; + } +} + /** * This can be called from startup or from the options menu. * On startup, this tries to load the setting without user input. */ -void Graphics::openTextConfigurationMenu(bool fromOptionMenu) { +void Graphics::showTextConfigurationMenu(bool fromOptionMenu) { const char *options[] = { // TODO: languages... "Text display", "Text subtitles.", |