Initial commit
This commit is contained in:
250
engines/stark/ui/world/actionmenu.cpp
Normal file
250
engines/stark/ui/world/actionmenu.cpp
Normal file
@@ -0,0 +1,250 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "engines/stark/ui/world/actionmenu.h"
|
||||
#include "engines/stark/ui/cursor.h"
|
||||
#include "engines/stark/ui/world/gamewindow.h"
|
||||
#include "engines/stark/ui/world/inventorywindow.h"
|
||||
#include "engines/stark/gfx/driver.h"
|
||||
#include "engines/stark/resources/anim.h"
|
||||
#include "engines/stark/resources/item.h"
|
||||
#include "engines/stark/resources/knowledgeset.h"
|
||||
#include "engines/stark/resources/level.h"
|
||||
#include "engines/stark/resources/pattable.h"
|
||||
#include "engines/stark/resources/sound.h"
|
||||
#include "engines/stark/services/services.h"
|
||||
#include "engines/stark/services/gameinterface.h"
|
||||
#include "engines/stark/services/staticprovider.h"
|
||||
#include "engines/stark/services/global.h"
|
||||
#include "engines/stark/scene.h"
|
||||
#include "engines/stark/visual/image.h"
|
||||
#include "engines/stark/visual/text.h"
|
||||
|
||||
|
||||
namespace Stark {
|
||||
|
||||
static const int kAutoCloseSuspended = -1;
|
||||
static const int kAutoCloseDisabled = -2;
|
||||
static const int kAutoCloseDelay = 200;
|
||||
|
||||
ActionMenu::ActionMenu(Gfx::Driver *gfx, Cursor *cursor) :
|
||||
Window(gfx, cursor),
|
||||
_fromInventory(false),
|
||||
_itemDescription(nullptr),
|
||||
_item(nullptr),
|
||||
_inventory(nullptr),
|
||||
_activeMenuType(kActionNoneM),
|
||||
_autoCloseTimeRemaining(kAutoCloseDisabled) {
|
||||
|
||||
_background = StarkStaticProvider->getUIElement(StaticProvider::kActionMenuBg);
|
||||
|
||||
_itemDescription = new VisualText(gfx);
|
||||
_itemDescription->setColor(Gfx::Color(0xFF, 0xFF, 0xFF));
|
||||
_itemDescription->setBackgroundColor(Gfx::Color(0x00, 0x00, 0x00, 0x80));
|
||||
_itemDescription->setFont(FontProvider::kSmallFont);
|
||||
_itemDescription->setTargetWidth(96);
|
||||
|
||||
_buttons[kActionHand].action = Resources::PATTable::kActionUse;
|
||||
_buttons[kActionHand].rect = Common::Rect(90, 15, 126, 63);
|
||||
_buttons[kActionEye].action = Resources::PATTable::kActionLook;
|
||||
_buttons[kActionEye].rect = Common::Rect(5, 77, 51, 110);
|
||||
_buttons[kActionMouth].action = Resources::PATTable::kActionTalk;
|
||||
_buttons[kActionMouth].rect = Common::Rect(42, 35, 83, 74);
|
||||
|
||||
_actionMouthHoverSound = StarkStaticProvider->getUISound(StaticProvider::kActionMouthHover);
|
||||
_actionMouthHoverSound->setLooping(false);
|
||||
_actionHoverSound = StarkStaticProvider->getUISound(StaticProvider::kActionHover);
|
||||
|
||||
clearActions();
|
||||
}
|
||||
|
||||
ActionMenu::~ActionMenu() {
|
||||
delete _itemDescription;
|
||||
}
|
||||
|
||||
void ActionMenu::open(Resources::ItemVisual *item, const Common::Point &itemRelativePos) {
|
||||
_visible = true;
|
||||
|
||||
Common::Point mousePos = _cursor->getMousePosition();
|
||||
|
||||
_position = computePosition(mousePos);
|
||||
|
||||
_itemRelativePos = itemRelativePos;
|
||||
_item = item;
|
||||
_fromInventory = item->getSubType() == Resources::Item::kItemInventory;
|
||||
|
||||
if (_fromInventory) {
|
||||
_itemDescription->setText(StarkGameInterface->getItemTitle(item));
|
||||
} else {
|
||||
_itemDescription->setText(StarkGameInterface->getItemTitleAt(item, itemRelativePos));
|
||||
}
|
||||
|
||||
_cursor->setMouseHint("");
|
||||
|
||||
clearActions();
|
||||
|
||||
Resources::ActionArray possible;
|
||||
if (_fromInventory) {
|
||||
possible = StarkGameInterface->listActionsPossibleForObject(_item);
|
||||
} else {
|
||||
possible = StarkGameInterface->listActionsPossibleForObjectAt(_item, _itemRelativePos);
|
||||
}
|
||||
|
||||
for (uint i = 0; i < possible.size(); i++) {
|
||||
enableAction(possible[i]);
|
||||
}
|
||||
|
||||
if (_fromInventory) {
|
||||
// All inventory items can be picked up
|
||||
enableAction(Resources::PATTable::kActionUse);
|
||||
}
|
||||
}
|
||||
|
||||
void ActionMenu::close() {
|
||||
_visible = false;
|
||||
_item = nullptr;
|
||||
_activeMenuType = kActionNoneM;
|
||||
_actionHoverSound->stop();
|
||||
}
|
||||
|
||||
Common::Rect ActionMenu::computePosition(const Common::Point &mouse) const {
|
||||
Common::Rect position = Common::Rect::center(mouse.x, mouse.y, 160, 111);
|
||||
|
||||
Common::Rect gameWindowRect(Gfx::Driver::kGameViewportWidth, Gfx::Driver::kGameViewportHeight);
|
||||
gameWindowRect.translate(0, Gfx::Driver::kTopBorderHeight);
|
||||
|
||||
if (position.top < gameWindowRect.top) position.translate(0, gameWindowRect.top - position.top);
|
||||
if (position.left < gameWindowRect.left) position.translate(gameWindowRect.left - position.left, 0);
|
||||
if (position.bottom > gameWindowRect.bottom) position.translate(0, gameWindowRect.bottom - position.bottom);
|
||||
if (position.right > gameWindowRect.right) position.translate(gameWindowRect.right - position.right, 0);
|
||||
|
||||
return position;
|
||||
}
|
||||
|
||||
void ActionMenu::onRender() {
|
||||
_background->render(Common::Point(0, 0), false);
|
||||
|
||||
for (uint i = 0; i < ARRAYSIZE(_buttons); i++) {
|
||||
if (_buttons[i].enabled) {
|
||||
VisualImageXMG *visual = StarkGameInterface->getActionImage(_buttons[i].action, (int32)i == _activeMenuType);
|
||||
visual->render(Common::Point(_buttons[i].rect.left, _buttons[i].rect.top), false);
|
||||
}
|
||||
}
|
||||
|
||||
Common::Rect descriptionSize = _itemDescription->getRect();
|
||||
int descriptionX = 60 + (_itemDescription->getTargetWidth() - descriptionSize.width()) / 2;
|
||||
int descriptionY = _position.height() - descriptionSize.height();
|
||||
|
||||
_itemDescription->render(Common::Point(descriptionX, descriptionY));
|
||||
}
|
||||
|
||||
void ActionMenu::clearActions() {
|
||||
for (uint i = 0; i < ARRAYSIZE(_buttons); i++) {
|
||||
_buttons[i].enabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
void ActionMenu::enableAction(uint32 action) {
|
||||
for (uint j = 0; j < ARRAYSIZE(_buttons); j++) {
|
||||
if (_buttons[j].action == action) {
|
||||
_buttons[j].enabled = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ActionMenu::updateActionSound() {
|
||||
if (_activeMenuType == kActionNoneM) {
|
||||
_actionHoverSound->stop();
|
||||
return;
|
||||
}
|
||||
_actionHoverSound->play();
|
||||
if (_activeMenuType == kActionMouth) {
|
||||
_actionMouthHoverSound->play();
|
||||
}
|
||||
}
|
||||
|
||||
void ActionMenu::onMouseMove(const Common::Point &pos) {
|
||||
int32 prevActive = _activeMenuType;
|
||||
int32 newActive = kActionNoneM;
|
||||
for (uint i = 0; i < ARRAYSIZE(_buttons); i++) {
|
||||
if (_buttons[i].enabled && _buttons[i].rect.contains(pos)) {
|
||||
newActive = i;
|
||||
}
|
||||
}
|
||||
|
||||
if (newActive != prevActive) {
|
||||
_activeMenuType = newActive;
|
||||
if (_activeMenuType == kActionNoneM) {
|
||||
_cursor->setCursorType(Cursor::kDefault);
|
||||
} else {
|
||||
_cursor->setCursorType(Cursor::kActive);
|
||||
}
|
||||
updateActionSound();
|
||||
}
|
||||
|
||||
_autoCloseTimeRemaining = kAutoCloseSuspended;
|
||||
}
|
||||
|
||||
void ActionMenu::onClick(const Common::Point &pos) {
|
||||
assert(_item);
|
||||
|
||||
for (uint i = 0; i < ARRAYSIZE(_buttons); i++) {
|
||||
if (_buttons[i].enabled && _buttons[i].rect.contains(pos)) {
|
||||
|
||||
if (_fromInventory && i == kActionHand) {
|
||||
_inventory->setSelectedInventoryItem(_item->getIndex());
|
||||
} else {
|
||||
if (_fromInventory) {
|
||||
StarkGameInterface->itemDoAction(_item, _buttons[i].action);
|
||||
} else {
|
||||
StarkGameInterface->itemDoActionAt(_item, _buttons[i].action, _itemRelativePos);
|
||||
}
|
||||
}
|
||||
|
||||
close();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ActionMenu::setInventory(InventoryWindow *inventory) {
|
||||
_inventory = inventory;
|
||||
}
|
||||
|
||||
void ActionMenu::onGameLoop() {
|
||||
if (!isMouseInside() && _autoCloseTimeRemaining == kAutoCloseSuspended) {
|
||||
_autoCloseTimeRemaining = kAutoCloseDelay;
|
||||
} else if (_autoCloseTimeRemaining >= 0) {
|
||||
_autoCloseTimeRemaining -= StarkGlobal->getMillisecondsPerGameloop();
|
||||
|
||||
if (_autoCloseTimeRemaining <= 0) {
|
||||
_autoCloseTimeRemaining = kAutoCloseSuspended;
|
||||
close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ActionMenu::onScreenChanged() {
|
||||
_itemDescription->reset();
|
||||
}
|
||||
|
||||
} // End of namespace Stark
|
||||
Reference in New Issue
Block a user