Initial commit
This commit is contained in:
515
engines/tsage/ringworld/ringworld_dialogs.cpp
Normal file
515
engines/tsage/ringworld/ringworld_dialogs.cpp
Normal file
@@ -0,0 +1,515 @@
|
||||
/* 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 "tsage/tsage.h"
|
||||
#include "tsage/core.h"
|
||||
#include "tsage/dialogs.h"
|
||||
#include "tsage/staticres.h"
|
||||
#include "tsage/globals.h"
|
||||
#include "tsage/ringworld/ringworld_dialogs.h"
|
||||
#include "tsage/ringworld/ringworld_logic.h"
|
||||
|
||||
namespace TsAGE {
|
||||
|
||||
namespace Ringworld {
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
#define BUTTON_WIDTH 28
|
||||
#define BUTTON_HEIGHT 29
|
||||
|
||||
RightClickButton::RightClickButton(int buttonIndex, int xp, int yp) : GfxButton() {
|
||||
_buttonIndex = buttonIndex;
|
||||
this->_bounds.left = xp;
|
||||
this->_bounds.top = yp;
|
||||
this->_bounds.setWidth(BUTTON_WIDTH);
|
||||
this->_bounds.setHeight(BUTTON_HEIGHT);
|
||||
_savedButton = NULL;
|
||||
}
|
||||
|
||||
void RightClickButton::highlight() {
|
||||
if (_savedButton) {
|
||||
// Button was previously highlighted, so de-highlight by restoring saved area
|
||||
g_globals->gfxManager().copyFrom(*_savedButton, _bounds.left, _bounds.top);
|
||||
delete _savedButton;
|
||||
_savedButton = NULL;
|
||||
} else {
|
||||
// Highlight button by getting the needed highlighted image resource
|
||||
_savedButton = surfaceGetArea(g_globals->gfxManager().getSurface(), _bounds);
|
||||
|
||||
uint size;
|
||||
byte *imgData = g_resourceManager->getSubResource(7, 2, _buttonIndex, &size);
|
||||
|
||||
GfxSurface btnSelected = surfaceFromRes(imgData);
|
||||
g_globals->gfxManager().copyFrom(btnSelected, _bounds.left, _bounds.top);
|
||||
|
||||
DEALLOCATE(imgData);
|
||||
}
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* This dialog implements the right-click dialog
|
||||
*/
|
||||
RightClickDialog::RightClickDialog() : GfxDialog(),
|
||||
_walkButton(1, 48, 12), _lookButton(2, 31, 29), _useButton(3, 65, 29),
|
||||
_talkButton(4, 14, 47), _inventoryButton(5, 48, 47), _optionsButton(6, 83, 47) {
|
||||
Rect rectArea, dialogRect;
|
||||
|
||||
// Set the palette and change the cursor
|
||||
_gfxManager.setDialogPalette();
|
||||
g_globals->_events.setCursor(CURSOR_ARROW);
|
||||
|
||||
// Get the dialog image
|
||||
_surface = surfaceFromRes(7, 1, 1);
|
||||
|
||||
// Set the dialog position
|
||||
dialogRect.resize(_surface, 0, 0, 100);
|
||||
dialogRect.center(g_globals->_events._mousePos.x, g_globals->_events._mousePos.y);
|
||||
|
||||
// Ensure the dialog will be entirely on-screen
|
||||
Rect screenRect = g_globals->gfxManager()._bounds;
|
||||
screenRect.collapse(4, 4);
|
||||
dialogRect.contain(screenRect);
|
||||
|
||||
_bounds = dialogRect;
|
||||
_gfxManager._bounds = _bounds;
|
||||
|
||||
_highlightedButton = NULL;
|
||||
_selectedAction = -1;
|
||||
}
|
||||
|
||||
RightClickDialog::~RightClickDialog() {
|
||||
}
|
||||
|
||||
RightClickButton *RightClickDialog::findButton(const Common::Point &pt) {
|
||||
RightClickButton *btnList[] = { &_walkButton, &_lookButton, &_useButton, &_talkButton, &_inventoryButton, &_optionsButton };
|
||||
|
||||
for (int i = 0; i < 6; ++i) {
|
||||
btnList[i]->_owner = this;
|
||||
|
||||
if (btnList[i]->_bounds.contains(pt))
|
||||
return btnList[i];
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void RightClickDialog::draw() {
|
||||
// Save the covered background area
|
||||
_savedArea = surfaceGetArea(g_globals->_gfxManagerInstance.getSurface(), _bounds);
|
||||
|
||||
// Draw the dialog image
|
||||
g_globals->gfxManager().copyFrom(_surface, _bounds.left, _bounds.top);
|
||||
}
|
||||
|
||||
bool RightClickDialog::process(Event &event) {
|
||||
switch (event.eventType) {
|
||||
case EVENT_MOUSE_MOVE: {
|
||||
// Check whether a button is highlighted
|
||||
RightClickButton *btn = findButton(event.mousePos);
|
||||
|
||||
if (btn != _highlightedButton) {
|
||||
// De-highlight any previously selected button
|
||||
if (_highlightedButton) {
|
||||
_highlightedButton->highlight();
|
||||
_highlightedButton = NULL;
|
||||
}
|
||||
if (btn) {
|
||||
// Highlight the new button
|
||||
btn->highlight();
|
||||
_highlightedButton = btn;
|
||||
}
|
||||
}
|
||||
event.handled = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
case EVENT_BUTTON_DOWN:
|
||||
// If a button is highlighted, then flag the selected button index
|
||||
if (_highlightedButton)
|
||||
_selectedAction = _highlightedButton->_buttonIndex;
|
||||
else
|
||||
_selectedAction = _lookButton._buttonIndex;
|
||||
event.handled = true;
|
||||
return true;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void RightClickDialog::execute() {
|
||||
// Draw the dialog
|
||||
draw();
|
||||
|
||||
// Dialog event handler loop
|
||||
_gfxManager.activate();
|
||||
|
||||
while (!g_vm->shouldQuit() && (_selectedAction == -1)) {
|
||||
Event evt;
|
||||
while (g_globals->_events.getEvent(evt, EVENT_MOUSE_MOVE | EVENT_BUTTON_DOWN)) {
|
||||
evt.mousePos.x -= _bounds.left;
|
||||
evt.mousePos.y -= _bounds.top;
|
||||
|
||||
process(evt);
|
||||
}
|
||||
|
||||
g_system->delayMillis(10);
|
||||
GLOBALS._screen.update();
|
||||
}
|
||||
|
||||
_gfxManager.deactivate();
|
||||
|
||||
// Execute the specified action
|
||||
switch (_selectedAction) {
|
||||
case 1:
|
||||
// Look action
|
||||
g_globals->_events.setCursor(CURSOR_LOOK);
|
||||
break;
|
||||
case 2:
|
||||
// Walk action
|
||||
g_globals->_events.setCursor(CURSOR_WALK);
|
||||
break;
|
||||
case 3:
|
||||
// Use cursor
|
||||
g_globals->_events.setCursor(CURSOR_USE);
|
||||
break;
|
||||
case 4:
|
||||
// Talk cursor
|
||||
g_globals->_events.setCursor(CURSOR_TALK);
|
||||
break;
|
||||
case 5:
|
||||
// Inventory dialog
|
||||
InventoryDialog::show();
|
||||
break;
|
||||
case 6:
|
||||
// Dialog options
|
||||
Ringworld::OptionsDialog::show();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
void OptionsDialog::show() {
|
||||
OptionsDialog *dlg = new OptionsDialog();
|
||||
dlg->draw();
|
||||
|
||||
GfxButton *btn = dlg->execute();
|
||||
|
||||
if (btn == &dlg->_btnQuit) {
|
||||
// Quit game
|
||||
int rc;
|
||||
if (g_vm->getLanguage() == Common::ES_ESP) {
|
||||
rc = MessageDialog::show(ESP_QUIT_CONFIRM_1_MSG, ESP_CANCEL_BTN_STRING, ESP_QUIT_BTN_STRING);
|
||||
} else if (g_vm->getLanguage() == Common::RU_RUS) {
|
||||
rc = MessageDialog::show(RUS_QUIT_CONFIRM_MSG, RUS_CANCEL_BTN_STRING, RUS_QUIT_BTN_STRING);
|
||||
} else {
|
||||
rc = MessageDialog::show(QUIT_CONFIRM_MSG, CANCEL_BTN_STRING, QUIT_BTN_STRING);
|
||||
}
|
||||
if (rc == 1) {
|
||||
g_vm->quitGame();
|
||||
}
|
||||
} else if (btn == &dlg->_btnRestart) {
|
||||
// Restart game
|
||||
g_globals->_game->restartGame();
|
||||
} else if (btn == &dlg->_btnSound) {
|
||||
// Sound dialog
|
||||
SoundDialog::execute();
|
||||
} else if (btn == &dlg->_btnSave) {
|
||||
// Save button
|
||||
g_globals->_game->saveGame();
|
||||
} else if (btn == &dlg->_btnRestore) {
|
||||
// Restore button
|
||||
g_globals->_game->restoreGame();
|
||||
}
|
||||
|
||||
dlg->remove();
|
||||
delete dlg;
|
||||
}
|
||||
|
||||
OptionsDialog::OptionsDialog() {
|
||||
// Set the element text
|
||||
if (g_vm->getLanguage() == Common::ES_ESP) {
|
||||
_gfxMessage.set(ESP_OPTIONS_MSG, 140, ALIGN_LEFT);
|
||||
_btnRestore.setText(ESP_RESTORE_BTN_STRING);
|
||||
_btnSave.setText(ESP_SAVE_BTN_STRING);
|
||||
_btnRestart.setText(ESP_RESTART_BTN_1_STRING);
|
||||
_btnQuit.setText(ESP_QUIT_BTN_STRING);
|
||||
_btnSound.setText(ESP_SOUND_BTN_STRING);
|
||||
_btnResume.setText(ESP_RESUME_BTN_STRING);
|
||||
} else if (g_vm->getLanguage() == Common::RU_RUS) {
|
||||
_gfxMessage.set(RUS_OPTIONS_MSG, 140, ALIGN_LEFT);
|
||||
_btnRestore.setText(RUS_RESTORE_BTN_STRING);
|
||||
_btnSave.setText(RUS_SAVE_BTN_STRING);
|
||||
_btnRestart.setText(RUS_RESTART_BTN_STRING);
|
||||
_btnQuit.setText(RUS_QUIT_BTN_STRING);
|
||||
_btnSound.setText(RUS_SOUND_BTN_STRING);
|
||||
_btnResume.setText(RUS_RESUME_BTN_STRING);
|
||||
} else {
|
||||
_gfxMessage.set(OPTIONS_MSG, 140, ALIGN_LEFT);
|
||||
_btnRestore.setText(RESTORE_BTN_STRING);
|
||||
_btnSave.setText(SAVE_BTN_STRING);
|
||||
_btnRestart.setText(RESTART_BTN_STRING);
|
||||
_btnQuit.setText(QUIT_BTN_STRING);
|
||||
_btnSound.setText(SOUND_BTN_STRING);
|
||||
_btnResume.setText(RESUME_BTN_STRING);
|
||||
}
|
||||
|
||||
// Set position of the elements
|
||||
_gfxMessage._bounds.moveTo(0, 1);
|
||||
_btnRestore._bounds.moveTo(0, _gfxMessage._bounds.bottom + 1);
|
||||
_btnSave._bounds.moveTo(0, _btnRestore._bounds.bottom + 1);
|
||||
_btnRestart._bounds.moveTo(0, _btnSave._bounds.bottom + 1);
|
||||
_btnQuit._bounds.moveTo(0, _btnRestart._bounds.bottom + 1);
|
||||
_btnSound._bounds.moveTo(0, _btnQuit._bounds.bottom + 1);
|
||||
_btnResume._bounds.moveTo(0, _btnSound._bounds.bottom + 1);
|
||||
|
||||
// Set all the buttons to the widest button
|
||||
GfxButton *btnList[6] = {&_btnRestore, &_btnSave, &_btnRestart, &_btnQuit, &_btnSound, &_btnResume};
|
||||
int16 btnWidth = 0;
|
||||
for (int idx = 0; idx < 6; ++idx)
|
||||
btnWidth = MAX(btnWidth, btnList[idx]->_bounds.width());
|
||||
for (int idx = 0; idx < 6; ++idx)
|
||||
btnList[idx]->_bounds.setWidth(btnWidth);
|
||||
|
||||
// Add the items to the dialog
|
||||
addElements(&_gfxMessage, &_btnRestore, &_btnSave, &_btnRestart, &_btnQuit, &_btnSound, &_btnResume, NULL);
|
||||
|
||||
// Set the dialog size and position
|
||||
frame();
|
||||
setCenter(160, 100);
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
bool GfxInvImage::process(Event &event) {
|
||||
if (!event.handled && (event.eventType == EVENT_BUTTON_DOWN)) {
|
||||
event.handled = _bounds.contains(event.mousePos);
|
||||
return event.handled;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
void InventoryDialog::show() {
|
||||
// Determine how many items are in the player's inventory
|
||||
int itemCount = 0;
|
||||
SynchronizedList<InvObject *>::iterator i;
|
||||
for (i = RING_INVENTORY._itemList.begin(); i != RING_INVENTORY._itemList.end(); ++i) {
|
||||
if ((*i)->inInventory())
|
||||
++itemCount;
|
||||
}
|
||||
|
||||
if (itemCount == 0) {
|
||||
if (g_vm->getLanguage() == Common::ES_ESP) {
|
||||
MessageDialog::show(ESP_INV_EMPTY_MSG, ESP_OK_BTN_STRING);
|
||||
} else if (g_vm->getLanguage() == Common::RU_RUS) {
|
||||
MessageDialog::show(RUS_INV_EMPTY_MSG, RUS_OK_BTN_STRING);
|
||||
} else {
|
||||
MessageDialog::show(INV_EMPTY_MSG, OK_BTN_STRING);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
InventoryDialog *dlg = new InventoryDialog();
|
||||
dlg->draw();
|
||||
dlg->execute();
|
||||
delete dlg;
|
||||
}
|
||||
|
||||
InventoryDialog::InventoryDialog() {
|
||||
// Determine the maximum size of the image of any item in the player's inventory
|
||||
int imgWidth = 0, imgHeight = 0;
|
||||
|
||||
SynchronizedList<InvObject *>::iterator i;
|
||||
for (i = RING_INVENTORY._itemList.begin(); i != RING_INVENTORY._itemList.end(); ++i) {
|
||||
InvObject *invObject = *i;
|
||||
if (invObject->inInventory()) {
|
||||
// Get the image for the item
|
||||
GfxSurface itemSurface = surfaceFromRes(invObject->_displayResNum, invObject->_rlbNum, invObject->_cursorNum);
|
||||
|
||||
// Maintain the dimensions of the largest item image
|
||||
imgWidth = MAX(imgWidth, (int)itemSurface.getBounds().width());
|
||||
imgHeight = MAX(imgHeight, (int)itemSurface.getBounds().height());
|
||||
|
||||
// Add the item to the display list
|
||||
GfxInvImage *img = new GfxInvImage();
|
||||
_images.push_back(img);
|
||||
img->setDetails(invObject->_displayResNum, invObject->_rlbNum, invObject->_cursorNum);
|
||||
img->_invObject = invObject;
|
||||
add(img);
|
||||
}
|
||||
}
|
||||
assert(_images.size() > 0);
|
||||
|
||||
// Figure out the number of columns/rows to show all the items
|
||||
int cellsSize = 3;
|
||||
while ((cellsSize * cellsSize) < (int)_images.size())
|
||||
++cellsSize;
|
||||
|
||||
// Set the position of each inventory item to be displayed
|
||||
int cellX = 0;
|
||||
Common::Point pt(0, 0);
|
||||
|
||||
for (uint idx = 0; idx < _images.size(); ++idx) {
|
||||
if (cellX == cellsSize) {
|
||||
// Move to the start of the next line
|
||||
pt.x = 0;
|
||||
pt.y += imgHeight + 2;
|
||||
cellX = 0;
|
||||
}
|
||||
|
||||
_images[idx]->_bounds.moveTo(pt.x, pt.y);
|
||||
|
||||
pt.x += imgWidth + 2;
|
||||
++cellX;
|
||||
}
|
||||
|
||||
// Set up the buttons
|
||||
pt.y += imgHeight + 2;
|
||||
if (g_vm->getLanguage() == Common::ES_ESP) {
|
||||
_btnOk.setText(ESP_OK_BTN_STRING);
|
||||
_btnLook.setText(ESP_LOOK_BTN_STRING);
|
||||
} else if (g_vm->getLanguage() == Common::RU_RUS) {
|
||||
_btnOk.setText(RUS_OK_BTN_STRING);
|
||||
_btnLook.setText(RUS_LOOK_BTN_STRING);
|
||||
} else {
|
||||
_btnOk.setText(OK_BTN_STRING);
|
||||
_btnLook.setText(LOOK_BTN_STRING);
|
||||
}
|
||||
_btnOk._bounds.moveTo((imgWidth + 2) * cellsSize - _btnOk._bounds.width(), pt.y);
|
||||
_btnLook._bounds.moveTo(_btnOk._bounds.left - _btnLook._bounds.width() - 2, _btnOk._bounds.top);
|
||||
addElements(&_btnLook, &_btnOk, NULL);
|
||||
|
||||
frame();
|
||||
setCenter(SCREEN_CENTER_X, SCREEN_CENTER_Y);
|
||||
}
|
||||
|
||||
InventoryDialog::~InventoryDialog() {
|
||||
for (uint idx = 0; idx < _images.size(); ++idx)
|
||||
delete _images[idx];
|
||||
}
|
||||
|
||||
void InventoryDialog::execute() {
|
||||
if ((RING_INVENTORY._selectedItem) && RING_INVENTORY._selectedItem->inInventory())
|
||||
RING_INVENTORY._selectedItem->setCursor();
|
||||
|
||||
bool lookFlag = false;
|
||||
_gfxManager.activate();
|
||||
|
||||
while (!g_vm->shouldQuit()) {
|
||||
// Get events
|
||||
Event event;
|
||||
while (!g_globals->_events.getEvent(event) && !g_vm->shouldQuit()) {
|
||||
g_system->delayMillis(10);
|
||||
GLOBALS._screen.update();
|
||||
}
|
||||
if (g_vm->shouldQuit())
|
||||
break;
|
||||
|
||||
GfxElement *hiliteObj = nullptr;
|
||||
if ((event.eventType == EVENT_BUTTON_DOWN) && !_bounds.contains(event.mousePos))
|
||||
break;
|
||||
|
||||
// Pass event to elements
|
||||
event.mousePos.x -= _gfxManager._bounds.left;
|
||||
event.mousePos.y -= _gfxManager._bounds.top;
|
||||
|
||||
for (GfxElementList::iterator i = _elements.begin(); i != _elements.end(); ++i) {
|
||||
if ((*i)->process(event))
|
||||
hiliteObj = *i;
|
||||
}
|
||||
|
||||
if (!event.handled && (event.eventType == EVENT_CUSTOM_ACTIONSTART)) {
|
||||
if ((event.customType == kActionReturn) || (event.customType == kActionEscape)) {
|
||||
// Exit the dialog
|
||||
//hiliteObj = &_btnOk;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (hiliteObj == &_btnOk) {
|
||||
// Ok button clicked
|
||||
if (lookFlag)
|
||||
g_globals->_events.setCursor(CURSOR_WALK);
|
||||
break;
|
||||
} else if (hiliteObj == &_btnLook) {
|
||||
// Look button clicked
|
||||
if (g_vm->getLanguage() == Common::ES_ESP) {
|
||||
if (_btnLook._message == ESP_LOOK_BTN_STRING) {
|
||||
_btnLook._message = ESP_PICK_BTN_STRING;
|
||||
lookFlag = 1;
|
||||
g_globals->_events.setCursor(CURSOR_LOOK);
|
||||
} else {
|
||||
_btnLook._message = ESP_LOOK_BTN_STRING;
|
||||
lookFlag = 0;
|
||||
g_globals->_events.setCursor(CURSOR_WALK);
|
||||
}
|
||||
} else if (g_vm->getLanguage() == Common::RU_RUS) {
|
||||
if (_btnLook._message == RUS_LOOK_BTN_STRING) {
|
||||
_btnLook._message = RUS_PICK_BTN_STRING;
|
||||
lookFlag = 1;
|
||||
g_globals->_events.setCursor(CURSOR_LOOK);
|
||||
} else {
|
||||
_btnLook._message = RUS_LOOK_BTN_STRING;
|
||||
lookFlag = 0;
|
||||
g_globals->_events.setCursor(CURSOR_WALK);
|
||||
}
|
||||
} else {
|
||||
if (_btnLook._message == LOOK_BTN_STRING) {
|
||||
_btnLook._message = PICK_BTN_STRING;
|
||||
lookFlag = 1;
|
||||
g_globals->_events.setCursor(CURSOR_LOOK);
|
||||
} else {
|
||||
_btnLook._message = LOOK_BTN_STRING;
|
||||
lookFlag = 0;
|
||||
g_globals->_events.setCursor(CURSOR_WALK);
|
||||
}
|
||||
}
|
||||
|
||||
hiliteObj->draw();
|
||||
} else if (hiliteObj) {
|
||||
// Inventory item selected
|
||||
InvObject *invObject = static_cast<GfxInvImage *>(hiliteObj)->_invObject;
|
||||
if (lookFlag) {
|
||||
g_globals->_screen.displayText(invObject->_description);
|
||||
} else {
|
||||
RING_INVENTORY._selectedItem = invObject;
|
||||
invObject->setCursor();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_gfxManager.deactivate();
|
||||
}
|
||||
|
||||
} // End of namespace Ringworld
|
||||
|
||||
} // End of namespace TsAGE
|
||||
Reference in New Issue
Block a user