2004-04-12 21:40:49 +00:00
|
|
|
/* ScummVM - Scumm Interpreter
|
2005-01-01 16:20:17 +00:00
|
|
|
* Copyright (C) 2004-2005 The ScummVM project
|
2004-04-12 21:40:49 +00:00
|
|
|
*
|
|
|
|
* The ReInherit Engine is (C)2000-2003 by Daniel Balsom.
|
|
|
|
*
|
|
|
|
* 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 2
|
|
|
|
* 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, write to the Free Software
|
|
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
|
|
*
|
|
|
|
* $Header$
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2004-05-01 09:37:24 +00:00
|
|
|
// Game interface module
|
2004-08-02 16:20:35 +00:00
|
|
|
#include "saga/saga.h"
|
2004-04-12 21:40:49 +00:00
|
|
|
|
2004-08-02 16:20:35 +00:00
|
|
|
#include "saga/gfx.h"
|
|
|
|
#include "saga/actor.h"
|
2004-08-10 18:31:33 +00:00
|
|
|
#include "saga/console.h"
|
2004-08-03 00:06:18 +00:00
|
|
|
#include "saga/font.h"
|
2004-08-02 16:20:35 +00:00
|
|
|
#include "saga/objectmap.h"
|
2004-11-07 14:15:41 +00:00
|
|
|
#include "saga/objectdata.h"
|
2004-08-02 16:20:35 +00:00
|
|
|
#include "saga/rscfile_mod.h"
|
2004-10-05 02:16:26 +00:00
|
|
|
#include "saga/scene.h"
|
2004-08-12 23:57:45 +00:00
|
|
|
#include "saga/script.h"
|
2004-08-03 01:07:34 +00:00
|
|
|
#include "saga/sprite.h"
|
2004-04-12 21:40:49 +00:00
|
|
|
|
2004-08-02 16:20:35 +00:00
|
|
|
#include "saga/interface.h"
|
2004-04-12 21:40:49 +00:00
|
|
|
|
|
|
|
namespace Saga {
|
|
|
|
|
2005-01-13 22:42:49 +00:00
|
|
|
static int verbTypeToTextStringsIdLUT[kVerbTypesMax] = {
|
|
|
|
-1,
|
|
|
|
kTextPickUp,
|
|
|
|
kTextLookAt,
|
|
|
|
kTextWalkTo,
|
|
|
|
kTextTalkTo,
|
|
|
|
kTextOpen,
|
|
|
|
kTextClose,
|
|
|
|
kTextGive,
|
|
|
|
kTextUse,
|
|
|
|
-1,
|
|
|
|
-1,
|
|
|
|
-1,
|
|
|
|
-1,
|
|
|
|
-1,
|
|
|
|
-1
|
2004-04-12 21:40:49 +00:00
|
|
|
};
|
|
|
|
|
2004-08-06 01:39:17 +00:00
|
|
|
Interface::Interface(SagaEngine *vm) : _vm(vm), _initialized(false) {
|
2005-01-13 22:42:49 +00:00
|
|
|
byte *resource;
|
|
|
|
size_t resourceLength;
|
2004-04-12 21:40:49 +00:00
|
|
|
int result;
|
2005-01-13 22:42:49 +00:00
|
|
|
int i;
|
2004-04-12 21:40:49 +00:00
|
|
|
|
2004-08-06 01:39:17 +00:00
|
|
|
if (_initialized) {
|
|
|
|
return;
|
2004-04-12 21:40:49 +00:00
|
|
|
}
|
|
|
|
|
2005-01-15 20:12:49 +00:00
|
|
|
_iThread = _vm->_script->createThread();
|
2004-08-06 01:39:17 +00:00
|
|
|
if (_iThread == NULL) {
|
2005-01-13 22:42:49 +00:00
|
|
|
error("Interface::Interface(): Error creating script thread for game interface module");
|
2004-04-12 21:40:49 +00:00
|
|
|
}
|
|
|
|
|
2004-05-01 09:37:24 +00:00
|
|
|
// Load interface module resource file context
|
2004-12-22 13:09:47 +00:00
|
|
|
_interfaceContext = _vm->getFileContext(GAME_RESOURCEFILE, 0);
|
2004-11-15 03:03:48 +00:00
|
|
|
if (_interfaceContext == NULL) {
|
2005-01-13 22:42:49 +00:00
|
|
|
error("Interface::Interface(): unable to load resource");
|
2004-04-12 21:40:49 +00:00
|
|
|
}
|
2005-01-13 22:42:49 +00:00
|
|
|
|
|
|
|
_mainPanel.buttons = _vm->getDisplayInfo().mainPanelButtons;
|
|
|
|
_mainPanel.buttonsCount = _vm->getDisplayInfo().mainPanelButtonsCount;
|
2004-04-12 21:40:49 +00:00
|
|
|
|
2005-01-13 22:42:49 +00:00
|
|
|
for (i = 0; i < kVerbTypesMax; i++) {
|
|
|
|
_verbTypeToPanelButton[i] = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (i = 0; i < _mainPanel.buttonsCount; i++) {
|
|
|
|
if (_mainPanel.buttons[i].type == kPanelButtonVerb) {
|
|
|
|
_verbTypeToPanelButton[_mainPanel.buttons[i].id] = &_mainPanel.buttons[i];
|
|
|
|
}
|
2004-04-12 21:40:49 +00:00
|
|
|
}
|
|
|
|
|
2005-01-13 22:42:49 +00:00
|
|
|
result = RSC_LoadResource(_interfaceContext, _vm->getResourceDescription()->mainPanelResourceId, &resource, &resourceLength);
|
|
|
|
if ((result != SUCCESS) || (resourceLength == 0)) {
|
|
|
|
error("Interface::Interface(): unable to load mainPanel resource");
|
2004-04-12 21:40:49 +00:00
|
|
|
}
|
2005-01-13 22:42:49 +00:00
|
|
|
_vm->decodeBGImage(resource, resourceLength, &_mainPanel.image,
|
|
|
|
&_mainPanel.imageLength, &_mainPanel.imageWidth, &_mainPanel.imageHeight);
|
|
|
|
|
|
|
|
RSC_FreeResource(resource);
|
2004-04-12 21:40:49 +00:00
|
|
|
|
2005-01-13 22:42:49 +00:00
|
|
|
result = RSC_LoadResource(_interfaceContext, _vm->getResourceDescription()->conversePanelResourceId, &resource, &resourceLength);
|
|
|
|
if ((result != SUCCESS) || (resourceLength == 0)) {
|
|
|
|
error("Interface::Interface unable to load conversePanel resource");
|
2004-04-12 21:40:49 +00:00
|
|
|
}
|
2005-01-13 22:42:49 +00:00
|
|
|
_vm->decodeBGImage(resource, resourceLength, &_conversePanel.image,
|
|
|
|
&_conversePanel.imageLength, &_conversePanel.imageWidth, &_conversePanel.imageHeight);
|
|
|
|
RSC_FreeResource(resource);
|
2004-04-12 21:40:49 +00:00
|
|
|
|
2005-01-13 22:42:49 +00:00
|
|
|
if (_vm->_sprite->loadList(RID_ITE_COMMAND_BUTTONSPRITES, _mainPanel.sprites) != SUCCESS) { //TODO: move constant to ResourceDescription
|
|
|
|
error("Interface::Interface(): Unable to load sprite list");
|
2005-01-09 15:07:49 +00:00
|
|
|
}
|
2005-01-13 22:42:49 +00:00
|
|
|
|
|
|
|
if (_vm->_sprite->loadList(RID_ITE_DEFAULT_PORTRAITS, _defPortraits) != SUCCESS) { //TODO: move constant to ResourceDescription
|
|
|
|
error("Interface::Interface(): Unable to load sprite list");
|
2005-01-09 15:07:49 +00:00
|
|
|
}
|
2004-04-12 21:40:49 +00:00
|
|
|
|
|
|
|
|
2005-01-13 22:42:49 +00:00
|
|
|
_mainPanel.x = 0; //TODO: move constant to DisplayInfo
|
2005-01-09 23:41:22 +00:00
|
|
|
_mainPanel.y = 149;
|
2005-01-13 22:42:49 +00:00
|
|
|
_mainPanel.currentButton = NULL;
|
2004-04-12 21:40:49 +00:00
|
|
|
|
2005-01-13 22:42:49 +00:00
|
|
|
_conversePanel.x = 0; //TODO: move constant to DisplayInfo
|
2005-01-09 23:41:22 +00:00
|
|
|
_conversePanel.y = 149;
|
2005-01-13 22:42:49 +00:00
|
|
|
_conversePanel.currentButton = NULL;
|
2004-04-12 21:40:49 +00:00
|
|
|
|
2004-10-21 06:49:11 +00:00
|
|
|
_leftPortrait = 0;
|
|
|
|
_rightPortrait = 0;
|
2004-04-12 21:40:49 +00:00
|
|
|
|
2005-01-07 00:57:43 +00:00
|
|
|
_active = false;
|
|
|
|
_panelMode = _lockedMode = kPanelNull;
|
|
|
|
_savedMode = -1;
|
2005-01-06 14:02:53 +00:00
|
|
|
_inMainMode = false;
|
2004-08-06 01:39:17 +00:00
|
|
|
*_statusText = 0;
|
2004-04-12 21:40:49 +00:00
|
|
|
|
2004-11-07 14:15:41 +00:00
|
|
|
_inventoryCount = 0;
|
|
|
|
_inventorySize = ITE_INVENTORY_SIZE;
|
|
|
|
|
|
|
|
_inventory = (uint16 *)calloc(_inventorySize, sizeof(uint16));
|
|
|
|
if (_inventory == NULL) {
|
2005-01-13 22:42:49 +00:00
|
|
|
error("Interface::Interface(): not enough memory");
|
2004-11-07 14:15:41 +00:00
|
|
|
}
|
|
|
|
|
2004-08-06 01:39:17 +00:00
|
|
|
_initialized = true;
|
2004-04-12 21:40:49 +00:00
|
|
|
}
|
|
|
|
|
2004-08-06 01:39:17 +00:00
|
|
|
Interface::~Interface(void) {
|
2004-11-07 14:15:41 +00:00
|
|
|
free(_inventory);
|
2005-01-09 15:07:49 +00:00
|
|
|
|
2005-01-09 23:41:22 +00:00
|
|
|
_mainPanel.sprites.freeMem();
|
2005-01-09 15:07:49 +00:00
|
|
|
_defPortraits.freeMem();
|
|
|
|
_scenePortraits.freeMem();
|
2004-08-06 01:39:17 +00:00
|
|
|
_initialized = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
int Interface::activate() {
|
2005-01-07 00:57:43 +00:00
|
|
|
if (!_active) {
|
|
|
|
_active = true;
|
|
|
|
_vm->_script->_skipSpeeches = false;
|
|
|
|
_vm->_gfx->showCursor(true);
|
|
|
|
unlockMode();
|
|
|
|
if (_panelMode == kPanelMain)
|
|
|
|
;// show save reminder
|
|
|
|
draw();
|
|
|
|
}
|
2004-04-12 21:40:49 +00:00
|
|
|
|
2004-10-27 21:32:28 +00:00
|
|
|
return SUCCESS;
|
2004-04-12 21:40:49 +00:00
|
|
|
}
|
|
|
|
|
2004-08-06 01:39:17 +00:00
|
|
|
int Interface::deactivate() {
|
2005-01-07 00:57:43 +00:00
|
|
|
if (_active) {
|
|
|
|
_active = false;
|
|
|
|
_vm->_gfx->showCursor(false);
|
|
|
|
lockMode();
|
|
|
|
setMode(kPanelNull);
|
|
|
|
}
|
2004-04-12 21:40:49 +00:00
|
|
|
|
2004-10-27 21:32:28 +00:00
|
|
|
return SUCCESS;
|
2004-04-12 21:40:49 +00:00
|
|
|
}
|
|
|
|
|
2005-01-07 00:57:43 +00:00
|
|
|
void Interface::rememberMode() {
|
|
|
|
assert (_savedMode == -1);
|
|
|
|
|
|
|
|
_savedMode = _panelMode;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Interface::restoreMode() {
|
|
|
|
assert (_savedMode != -1);
|
2004-10-21 06:49:11 +00:00
|
|
|
|
2005-01-07 00:57:43 +00:00
|
|
|
_panelMode = _savedMode;
|
|
|
|
_savedMode = -1;
|
|
|
|
|
|
|
|
draw();
|
|
|
|
}
|
|
|
|
|
|
|
|
int Interface::setMode(int mode, bool force) {
|
|
|
|
// TODO: Is this where we should hide/show the mouse cursor?
|
2005-01-09 23:41:22 +00:00
|
|
|
int newMode = mode;
|
2005-01-06 14:02:53 +00:00
|
|
|
|
2005-01-09 23:41:22 +00:00
|
|
|
if (mode == kPanelConverse) {
|
2005-01-06 14:02:53 +00:00
|
|
|
_inMainMode = false;
|
2005-01-09 23:41:22 +00:00
|
|
|
} else {
|
|
|
|
if (mode == kPanelInventory) {
|
|
|
|
_inMainMode = true;
|
|
|
|
newMode = kPanelMain;
|
|
|
|
}
|
2005-01-07 00:57:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// This lets us to prevents actors to pop up during initial
|
|
|
|
// scene fade in.
|
|
|
|
if (_savedMode != -1 && !force) {
|
2005-01-09 23:41:22 +00:00
|
|
|
_savedMode = newMode;
|
|
|
|
debug(0, "Saved mode: %d. my mode is %d", newMode, _panelMode);
|
2005-01-06 14:49:47 +00:00
|
|
|
}
|
2005-01-07 00:57:43 +00:00
|
|
|
else
|
2005-01-09 23:41:22 +00:00
|
|
|
_panelMode = newMode;
|
2005-01-13 22:42:49 +00:00
|
|
|
|
|
|
|
if (_panelMode == kPanelMain) {
|
|
|
|
_mainPanel.currentButton = NULL;
|
|
|
|
} else {
|
|
|
|
if (_panelMode == kPanelConverse) {
|
|
|
|
_conversePanel.currentButton = NULL;
|
|
|
|
}
|
|
|
|
}
|
2005-01-06 14:02:53 +00:00
|
|
|
|
2004-10-21 06:49:11 +00:00
|
|
|
draw();
|
|
|
|
|
2004-10-27 21:32:28 +00:00
|
|
|
return SUCCESS;
|
2004-10-21 06:49:11 +00:00
|
|
|
}
|
|
|
|
|
2005-01-13 22:42:49 +00:00
|
|
|
bool Interface::processKeyCode(int keyCode) {
|
|
|
|
int i;
|
|
|
|
switch (_panelMode) {
|
|
|
|
case kPanelNull:
|
|
|
|
if (keyCode == 27) {// Esc
|
|
|
|
if (_vm->_scene->isInDemo()) {
|
|
|
|
_vm->_scene->skipScene();
|
|
|
|
} else {
|
|
|
|
_vm->_actor->abortAllSpeeches();
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case kPanelMain:
|
|
|
|
for (i = 0; i < kVerbTypesMax; i++) {
|
|
|
|
if (_verbTypeToPanelButton[i] != NULL) {
|
|
|
|
if (_verbTypeToPanelButton[i]->keyChar == keyCode) {
|
|
|
|
_vm->_script->setVerb(_verbTypeToPanelButton[i]->id);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2004-08-06 01:39:17 +00:00
|
|
|
int Interface::setStatusText(const char *new_txt) {
|
2004-04-12 21:40:49 +00:00
|
|
|
assert(new_txt != NULL);
|
|
|
|
|
2004-10-27 21:32:28 +00:00
|
|
|
strncpy(_statusText, new_txt, STATUS_TEXT_LEN);
|
2004-04-12 21:40:49 +00:00
|
|
|
|
2004-10-27 21:32:28 +00:00
|
|
|
return SUCCESS;
|
2004-04-12 21:40:49 +00:00
|
|
|
}
|
|
|
|
|
2005-01-09 15:07:49 +00:00
|
|
|
int Interface::loadScenePortraits(int resourceId) {
|
|
|
|
_scenePortraits.freeMem();
|
2004-10-21 06:49:11 +00:00
|
|
|
|
2005-01-09 15:07:49 +00:00
|
|
|
return _vm->_sprite->loadList(resourceId, _scenePortraits);
|
2004-10-21 06:49:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int Interface::setLeftPortrait(int portrait) {
|
|
|
|
_leftPortrait = portrait;
|
|
|
|
draw();
|
|
|
|
|
2004-10-27 21:32:28 +00:00
|
|
|
return SUCCESS;
|
2004-10-21 06:49:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int Interface::setRightPortrait(int portrait) {
|
|
|
|
_rightPortrait = portrait;
|
|
|
|
draw();
|
|
|
|
|
2004-10-27 21:32:28 +00:00
|
|
|
return SUCCESS;
|
2004-10-21 06:49:11 +00:00
|
|
|
}
|
|
|
|
|
2004-08-06 01:39:17 +00:00
|
|
|
int Interface::draw() {
|
2005-01-09 23:41:22 +00:00
|
|
|
SURFACE *backBuffer;
|
2005-01-13 22:42:49 +00:00
|
|
|
int i;
|
2004-04-12 21:40:49 +00:00
|
|
|
|
2005-01-09 23:41:22 +00:00
|
|
|
Point base;
|
|
|
|
Point leftPortraitPoint;
|
|
|
|
Point rightPortraitPoint;
|
2004-10-04 23:09:38 +00:00
|
|
|
Point origin;
|
2004-04-12 21:40:49 +00:00
|
|
|
|
2005-01-09 23:41:22 +00:00
|
|
|
backBuffer = _vm->_gfx->getBackBuffer();
|
2004-04-12 21:40:49 +00:00
|
|
|
|
2005-01-07 21:13:26 +00:00
|
|
|
if (_vm->_scene->isInDemo() || _panelMode == kPanelFade)
|
2004-10-27 21:32:28 +00:00
|
|
|
return SUCCESS;
|
2004-04-12 21:40:49 +00:00
|
|
|
|
|
|
|
|
2005-01-09 23:41:22 +00:00
|
|
|
drawStatusBar(backBuffer);
|
2004-04-12 21:40:49 +00:00
|
|
|
|
2005-01-02 20:29:27 +00:00
|
|
|
if (_panelMode == kPanelMain) {
|
2005-01-09 23:41:22 +00:00
|
|
|
base.x = _mainPanel.x;
|
|
|
|
base.y = _mainPanel.y;
|
2004-04-12 21:40:49 +00:00
|
|
|
|
|
|
|
origin.x = 0;
|
2005-01-13 22:42:49 +00:00
|
|
|
origin.y = _vm->getDisplayHeight() - _mainPanel.imageHeight;
|
2004-04-12 21:40:49 +00:00
|
|
|
|
2005-01-13 22:42:49 +00:00
|
|
|
bufToSurface(backBuffer, _mainPanel.image, _mainPanel.imageWidth, _mainPanel.imageHeight, NULL, &origin);
|
|
|
|
//here we will draw verbs
|
|
|
|
for (i = 0; i < kVerbTypesMax; i++) {
|
|
|
|
if (_verbTypeToPanelButton[i] != NULL) {
|
|
|
|
drawPanelButtonText(backBuffer, &_mainPanel, _verbTypeToPanelButton[i], _vm->getDisplayInfo().verbTextColor, _vm->getDisplayInfo().verbTextShadowColor);
|
|
|
|
}
|
|
|
|
}
|
2004-04-12 21:40:49 +00:00
|
|
|
} else {
|
2005-01-09 23:41:22 +00:00
|
|
|
base.x = _conversePanel.x;
|
|
|
|
base.y = _conversePanel.y;
|
2004-04-12 21:40:49 +00:00
|
|
|
|
|
|
|
origin.x = 0;
|
2005-01-13 22:42:49 +00:00
|
|
|
origin.y = _vm->getDisplayHeight() - _mainPanel.imageHeight;
|
2004-04-12 21:40:49 +00:00
|
|
|
|
2005-01-13 22:42:49 +00:00
|
|
|
bufToSurface(backBuffer, _conversePanel.image, _conversePanel.imageWidth,
|
|
|
|
_conversePanel.imageHeight, NULL, &origin);
|
2004-04-12 21:40:49 +00:00
|
|
|
}
|
|
|
|
|
2005-01-06 14:02:53 +00:00
|
|
|
if (_panelMode == kPanelMain || _panelMode == kPanelConverse ||
|
2005-01-09 23:41:22 +00:00
|
|
|
_lockedMode == kPanelMain || _lockedMode == kPanelConverse) {
|
2005-01-13 22:42:49 +00:00
|
|
|
leftPortraitPoint.x = base.x + _vm->getDisplayInfo().leftPortraitXOffset;
|
|
|
|
leftPortraitPoint.y = base.y + _vm->getDisplayInfo().leftPortraitYOffset;
|
2005-01-09 23:41:22 +00:00
|
|
|
_vm->_sprite->draw(backBuffer, _defPortraits, _leftPortrait, leftPortraitPoint, 256);
|
|
|
|
}
|
|
|
|
|
2004-10-21 06:49:11 +00:00
|
|
|
|
2005-01-13 22:42:49 +00:00
|
|
|
if (!_inMainMode && _vm->getDisplayInfo().rightPortraitXOffset >= 0) {
|
|
|
|
rightPortraitPoint.x = base.x + _vm->getDisplayInfo().rightPortraitXOffset;
|
|
|
|
rightPortraitPoint.y = base.y + _vm->getDisplayInfo().rightPortraitYOffset;
|
2004-10-21 06:49:11 +00:00
|
|
|
|
2005-01-09 23:41:22 +00:00
|
|
|
_vm->_sprite->draw(backBuffer, _scenePortraits, _rightPortrait, rightPortraitPoint, 256);
|
2004-10-21 06:49:11 +00:00
|
|
|
}
|
2004-04-12 21:40:49 +00:00
|
|
|
|
2005-01-09 23:41:22 +00:00
|
|
|
if (_inMainMode) {
|
2005-01-06 14:02:53 +00:00
|
|
|
drawInventory();
|
2005-01-09 23:41:22 +00:00
|
|
|
}
|
2004-10-27 21:32:28 +00:00
|
|
|
return SUCCESS;
|
2004-04-12 21:40:49 +00:00
|
|
|
}
|
|
|
|
|
2005-01-15 20:12:49 +00:00
|
|
|
int Interface::update(const Point& mousePoint, int updateFlag) {
|
2005-01-13 22:42:49 +00:00
|
|
|
SURFACE *backBuffer;
|
2004-04-12 21:40:49 +00:00
|
|
|
|
|
|
|
|
2005-01-07 21:13:26 +00:00
|
|
|
if (_vm->_scene->isInDemo() || _panelMode == kPanelFade)
|
2004-10-27 21:32:28 +00:00
|
|
|
return SUCCESS;
|
2004-04-12 21:40:49 +00:00
|
|
|
|
2005-01-13 22:42:49 +00:00
|
|
|
|
|
|
|
backBuffer = _vm->_gfx->getBackBuffer();
|
2004-04-12 21:40:49 +00:00
|
|
|
|
|
|
|
|
2005-01-15 20:12:49 +00:00
|
|
|
if (_panelMode == kPanelMain) {
|
|
|
|
if (updateFlag == UPDATE_MOUSEMOVE) {
|
|
|
|
|
|
|
|
if (mousePoint.y < _vm->getSceneHeight()) {
|
|
|
|
//handlePlayfieldUpdate(backBuffer, imousePointer);
|
|
|
|
_vm->_script->whichObject(mousePoint);
|
2005-01-13 22:42:49 +00:00
|
|
|
} else {
|
2005-01-15 20:12:49 +00:00
|
|
|
if (_lastMousePoint.y < _vm->getSceneHeight()) {
|
|
|
|
_vm->_script->setNonPlayfieldVerb();
|
2005-01-13 22:42:49 +00:00
|
|
|
}
|
2005-01-15 20:12:49 +00:00
|
|
|
handleCommandUpdate(backBuffer, mousePoint);
|
2005-01-13 22:42:49 +00:00
|
|
|
}
|
2005-01-15 20:12:49 +00:00
|
|
|
|
2005-01-13 22:42:49 +00:00
|
|
|
} else {
|
2005-01-15 20:12:49 +00:00
|
|
|
|
|
|
|
if (updateFlag == UPDATE_MOUSECLICK) {
|
|
|
|
if (mousePoint.y < _vm->getSceneHeight()) {
|
|
|
|
handlePlayfieldClick(backBuffer, mousePoint);
|
|
|
|
} else {
|
|
|
|
handleCommandClick(backBuffer, mousePoint);
|
2005-01-13 22:42:49 +00:00
|
|
|
}
|
2004-10-21 06:49:11 +00:00
|
|
|
}
|
2004-04-12 21:40:49 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-01-13 22:42:49 +00:00
|
|
|
drawStatusBar(backBuffer);
|
2005-01-15 20:12:49 +00:00
|
|
|
_lastMousePoint = mousePoint;
|
2004-10-27 21:32:28 +00:00
|
|
|
return SUCCESS;
|
2004-04-12 21:40:49 +00:00
|
|
|
}
|
|
|
|
|
2004-10-27 21:32:28 +00:00
|
|
|
int Interface::drawStatusBar(SURFACE *ds) {
|
2004-10-04 23:09:38 +00:00
|
|
|
Rect rect;
|
2004-04-12 21:40:49 +00:00
|
|
|
|
|
|
|
int string_w;
|
|
|
|
|
2004-11-25 07:18:35 +00:00
|
|
|
// Disable this for IHNM for now, since that game uses the full screen
|
|
|
|
// in some cases.
|
|
|
|
|
2005-01-11 21:10:36 +00:00
|
|
|
if (_vm->getGameType() == GType_IHNM) {
|
2004-11-25 07:18:35 +00:00
|
|
|
return SUCCESS;
|
|
|
|
}
|
|
|
|
|
2004-04-12 21:40:49 +00:00
|
|
|
|
2004-05-01 09:37:24 +00:00
|
|
|
// Erase background of status bar
|
2004-04-25 15:14:46 +00:00
|
|
|
rect.left = 0;
|
2005-01-11 21:10:36 +00:00
|
|
|
rect.top = _vm->getDisplayInfo().statusY;
|
2005-01-09 23:41:22 +00:00
|
|
|
rect.right = _vm->getDisplayWidth();
|
2005-01-11 21:10:36 +00:00
|
|
|
rect.bottom = _vm->getDisplayInfo().statusY + _vm->getDisplayInfo().statusHeight;
|
2004-04-12 21:40:49 +00:00
|
|
|
|
2005-01-11 21:10:36 +00:00
|
|
|
drawRect(ds, &rect, _vm->getDisplayInfo().statusBGColor);
|
2004-04-12 21:40:49 +00:00
|
|
|
|
2004-08-06 01:39:17 +00:00
|
|
|
string_w = _vm->_font->getStringWidth(SMALL_FONT_ID, _statusText, 0, 0);
|
2004-04-12 21:40:49 +00:00
|
|
|
|
2005-01-11 21:10:36 +00:00
|
|
|
_vm->_font->draw(SMALL_FONT_ID, ds, _statusText, 0, (_vm->getDisplayInfo().statusWidth / 2) - (string_w / 2),
|
|
|
|
_vm->getDisplayInfo().statusY + _vm->getDisplayInfo().statusTextY, _vm->getDisplayInfo().statusTextColor, 0, 0);
|
2004-04-12 21:40:49 +00:00
|
|
|
|
2004-10-27 21:32:28 +00:00
|
|
|
return SUCCESS;
|
2004-04-12 21:40:49 +00:00
|
|
|
}
|
|
|
|
|
2005-01-15 20:12:49 +00:00
|
|
|
void Interface::handleCommandClick(SURFACE *ds, const Point& mousePoint) {
|
2004-04-12 21:40:49 +00:00
|
|
|
|
2005-01-13 22:42:49 +00:00
|
|
|
PanelButton *panelButton;
|
2004-04-12 21:40:49 +00:00
|
|
|
|
2005-01-15 20:12:49 +00:00
|
|
|
panelButton = verbHitTest(mousePoint);
|
2005-01-13 22:42:49 +00:00
|
|
|
if (panelButton) {
|
|
|
|
_vm->_script->setVerb(panelButton->id);
|
|
|
|
return;
|
2004-04-12 21:40:49 +00:00
|
|
|
}
|
2005-01-13 22:42:49 +00:00
|
|
|
}
|
2004-04-12 21:40:49 +00:00
|
|
|
|
2005-01-15 20:12:49 +00:00
|
|
|
void Interface::handleCommandUpdate(SURFACE *ds, const Point& mousePoint) {
|
2005-01-13 22:42:49 +00:00
|
|
|
PanelButton *panelButton;
|
2004-04-12 21:40:49 +00:00
|
|
|
|
2005-01-15 20:12:49 +00:00
|
|
|
panelButton = verbHitTest(mousePoint);
|
2005-01-13 22:42:49 +00:00
|
|
|
if (_mainPanel.currentButton != panelButton) {
|
|
|
|
if (_mainPanel.currentButton) {
|
|
|
|
drawVerb(_mainPanel.currentButton->id, 0);
|
2004-04-12 21:40:49 +00:00
|
|
|
}
|
2005-01-13 22:42:49 +00:00
|
|
|
if (panelButton) {
|
|
|
|
drawVerb(panelButton->id, 1);
|
2004-04-12 21:40:49 +00:00
|
|
|
}
|
|
|
|
}
|
2005-01-13 22:42:49 +00:00
|
|
|
_mainPanel.currentButton = panelButton;
|
|
|
|
if (panelButton) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
/* hit_button = inventoryTest(imousePointer, &ibutton_num);
|
2004-11-07 14:15:41 +00:00
|
|
|
|
|
|
|
if (hit_button == SUCCESS) {
|
|
|
|
// Hovering over an inventory object
|
|
|
|
return SUCCESS;
|
2005-01-13 22:42:49 +00:00
|
|
|
}*/
|
2004-04-12 21:40:49 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2004-10-27 21:32:28 +00:00
|
|
|
int Interface::handlePlayfieldClick(SURFACE *ds, const Point& imousePt) {
|
2005-01-04 16:10:43 +00:00
|
|
|
// return SUCCESS;
|
|
|
|
|
2004-10-07 23:26:41 +00:00
|
|
|
int objectNum;
|
2004-04-30 23:02:23 +00:00
|
|
|
uint16 object_flags = 0;
|
2004-04-12 21:40:49 +00:00
|
|
|
|
2005-01-13 22:42:49 +00:00
|
|
|
// int script_num;
|
2005-01-15 20:12:49 +00:00
|
|
|
Location location;
|
2004-04-12 21:40:49 +00:00
|
|
|
|
2004-10-07 23:26:41 +00:00
|
|
|
objectNum = _vm->_scene->_objectMap->hitTest(imousePt);
|
2004-04-12 21:40:49 +00:00
|
|
|
|
2004-10-07 23:26:41 +00:00
|
|
|
if (objectNum == -1) {
|
2004-05-01 09:37:24 +00:00
|
|
|
// Player clicked on empty spot - walk here regardless of verb
|
2005-01-04 16:10:43 +00:00
|
|
|
location.fromScreenPoint(imousePt);
|
2004-12-24 20:44:39 +00:00
|
|
|
|
2005-01-04 16:10:43 +00:00
|
|
|
_vm->_actor->actorWalkTo(ID_PROTAG, location);
|
2004-10-27 21:32:28 +00:00
|
|
|
return SUCCESS;
|
2004-04-12 21:40:49 +00:00
|
|
|
}
|
|
|
|
|
2004-10-07 23:26:41 +00:00
|
|
|
object_flags = _vm->_scene->_objectMap->getFlags(objectNum);
|
2004-04-12 21:40:49 +00:00
|
|
|
|
2005-01-04 16:10:43 +00:00
|
|
|
if (object_flags & kHitZoneExit) { // FIXME. This is wrong
|
2005-01-13 22:42:49 +00:00
|
|
|
/* if ((script_num = _vm->_scene->_objectMap->getEPNum(objectNum)) != -1) {
|
2004-05-01 09:37:24 +00:00
|
|
|
// Set active verb in script module
|
2004-12-22 21:04:50 +00:00
|
|
|
_vm->_script->putWord(4, 4, I_VerbData[_activeVerb].s_verb);
|
2004-04-12 21:40:49 +00:00
|
|
|
|
2004-05-01 09:37:24 +00:00
|
|
|
// Execute object script if present
|
2004-04-12 21:40:49 +00:00
|
|
|
if (script_num != 0) {
|
2004-08-12 23:57:45 +00:00
|
|
|
_vm->_script->SThreadExecute(_iThread, script_num);
|
2004-04-12 21:40:49 +00:00
|
|
|
}
|
2005-01-13 22:42:49 +00:00
|
|
|
}*/
|
2004-04-12 21:40:49 +00:00
|
|
|
} else {
|
2004-05-01 09:37:24 +00:00
|
|
|
// Not a normal scene object - walk to it as if it weren't there
|
2005-01-04 16:10:43 +00:00
|
|
|
location.fromScreenPoint(imousePt);
|
2004-12-24 20:44:39 +00:00
|
|
|
|
2005-01-04 16:10:43 +00:00
|
|
|
_vm->_actor->actorWalkTo(ID_PROTAG, location);
|
2004-04-12 21:40:49 +00:00
|
|
|
}
|
|
|
|
|
2005-01-04 16:10:43 +00:00
|
|
|
return SUCCESS;
|
2004-04-12 21:40:49 +00:00
|
|
|
}
|
|
|
|
|
2004-10-27 21:32:28 +00:00
|
|
|
int Interface::handlePlayfieldUpdate(SURFACE *ds, const Point& imousePt) {
|
2004-12-24 21:16:24 +00:00
|
|
|
return SUCCESS;
|
2004-12-24 20:44:39 +00:00
|
|
|
/*
|
2004-04-12 21:40:49 +00:00
|
|
|
const char *object_name;
|
2004-10-07 23:26:41 +00:00
|
|
|
int objectNum;
|
2004-04-30 23:02:23 +00:00
|
|
|
uint16 object_flags = 0;
|
2004-04-12 21:40:49 +00:00
|
|
|
|
2004-10-27 21:32:28 +00:00
|
|
|
char new_status[STATUS_TEXT_LEN];
|
2004-04-12 21:40:49 +00:00
|
|
|
|
|
|
|
new_status[0] = 0;
|
|
|
|
|
2004-10-07 23:26:41 +00:00
|
|
|
objectNum = _vm->_scene->_objectMap->hitTest(imousePt);
|
2004-04-12 21:40:49 +00:00
|
|
|
|
2004-10-07 23:26:41 +00:00
|
|
|
if (objectNum == -1) {
|
2004-05-01 09:37:24 +00:00
|
|
|
// Cursor over nothing - just display current verb
|
2004-08-06 01:39:17 +00:00
|
|
|
setStatusText(I_VerbData[_activeVerb].verb_str);
|
2004-10-27 21:32:28 +00:00
|
|
|
return SUCCESS;
|
2004-04-12 21:40:49 +00:00
|
|
|
}
|
|
|
|
|
2004-10-07 23:26:41 +00:00
|
|
|
object_flags = _vm->_scene->_objectMap->getFlags(objectNum);
|
|
|
|
object_name = _vm->_scene->_objectMap->getName(objectNum);
|
2004-04-12 21:40:49 +00:00
|
|
|
|
2004-10-08 01:22:39 +00:00
|
|
|
if (object_flags & OBJECT_EXIT) { // FIXME. This is wrong
|
2004-05-01 09:37:24 +00:00
|
|
|
// Normal scene object - display as subject of verb
|
2004-10-27 21:32:28 +00:00
|
|
|
snprintf(new_status, STATUS_TEXT_LEN, "%s %s", I_VerbData[_activeVerb].verb_str, object_name);
|
2004-04-12 21:40:49 +00:00
|
|
|
} else {
|
2004-05-01 09:37:24 +00:00
|
|
|
// Not normal scene object - override verb as we can only
|
|
|
|
// walk to this object
|
2004-10-27 21:32:28 +00:00
|
|
|
snprintf(new_status, STATUS_TEXT_LEN, "%s %s", I_VerbData[I_VERB_WALKTO].verb_str, object_name);
|
2004-04-12 21:40:49 +00:00
|
|
|
}
|
|
|
|
|
2004-08-06 01:39:17 +00:00
|
|
|
setStatusText(new_status);
|
2004-04-12 21:40:49 +00:00
|
|
|
|
2004-10-27 21:32:28 +00:00
|
|
|
return SUCCESS;
|
2004-12-24 20:44:39 +00:00
|
|
|
*/
|
2004-04-12 21:40:49 +00:00
|
|
|
}
|
|
|
|
|
2005-01-15 20:12:49 +00:00
|
|
|
PanelButton *Interface::verbHitTest(const Point& mousePoint) {
|
2005-01-13 22:42:49 +00:00
|
|
|
PanelButton *panelButton;
|
|
|
|
Rect rect;
|
2004-04-12 21:40:49 +00:00
|
|
|
int i;
|
2005-01-13 22:42:49 +00:00
|
|
|
for (i = 0; i < kVerbTypesMax; i++) {
|
|
|
|
panelButton = _verbTypeToPanelButton[i];
|
|
|
|
if (panelButton != NULL) {
|
|
|
|
rect.left = _mainPanel.x + panelButton->xOffset;
|
|
|
|
rect.right = rect.left + panelButton->width;
|
|
|
|
rect.top = _mainPanel.y + panelButton->yOffset;
|
|
|
|
rect.bottom = rect.top + panelButton->height;
|
2005-01-15 20:12:49 +00:00
|
|
|
if (rect.contains(mousePoint))
|
2005-01-13 22:42:49 +00:00
|
|
|
return panelButton;
|
2004-04-12 21:40:49 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-01-13 22:42:49 +00:00
|
|
|
return NULL;
|
2004-04-12 21:40:49 +00:00
|
|
|
}
|
|
|
|
|
2004-11-07 14:15:41 +00:00
|
|
|
void Interface::addToInventory(int sprite) {
|
|
|
|
if (_inventoryCount < _inventorySize) {
|
|
|
|
for (int i = _inventoryCount; i > 0; i--) {
|
|
|
|
_inventory[i] = _inventory[i - 1];
|
|
|
|
}
|
|
|
|
|
|
|
|
_inventory[0] = sprite;
|
|
|
|
_inventoryCount++;
|
|
|
|
draw();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Interface::removeFromInventory(int sprite) {
|
|
|
|
for (int i = 0; i < _inventoryCount; i++) {
|
|
|
|
if (_inventory[i] == sprite) {
|
|
|
|
int j;
|
|
|
|
|
|
|
|
for (j = i; i < _inventoryCount; j++) {
|
|
|
|
_inventory[j] = _inventory[j + 1];
|
|
|
|
}
|
|
|
|
|
|
|
|
_inventory[j] = 0;
|
|
|
|
_inventoryCount--;
|
|
|
|
draw();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Interface::drawInventory() {
|
2005-01-02 20:29:27 +00:00
|
|
|
if (_panelMode != kPanelMain)
|
2004-11-07 14:15:41 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
SURFACE *back_buf = _vm->_gfx->getBackBuffer();
|
|
|
|
|
|
|
|
// TODO: Inventory scrolling
|
|
|
|
|
|
|
|
int row = 0;
|
|
|
|
int col = 0;
|
|
|
|
|
2005-01-13 22:42:49 +00:00
|
|
|
int x = _vm->getDisplayInfo().inventoryX + _vm->getDisplayInfo().inventoryIconXOffset;
|
|
|
|
int y = _vm->getDisplayInfo().inventoryY + _vm->getDisplayInfo().inventoryIconYOffset;
|
2005-01-11 21:10:36 +00:00
|
|
|
int width = _vm->getDisplayInfo().inventoryIconWidth + _vm->getDisplayInfo().inventoryXSpacing;
|
|
|
|
int height = _vm->getDisplayInfo().inventoryIconHeight + _vm->getDisplayInfo().inventoryYSpacing;
|
2004-12-19 13:38:11 +00:00
|
|
|
Point drawPoint;
|
2004-11-07 14:15:41 +00:00
|
|
|
|
|
|
|
for (int i = 0; i < _inventoryCount; i++) {
|
|
|
|
if (_inventory[i] >= ARRAYSIZE(ObjectTable)) {
|
|
|
|
continue;
|
|
|
|
}
|
2004-12-19 13:38:11 +00:00
|
|
|
drawPoint.x = x + col * width;
|
|
|
|
drawPoint.y = y + row * height;
|
2004-11-07 14:15:41 +00:00
|
|
|
|
2005-01-08 20:30:07 +00:00
|
|
|
_vm->_sprite->draw(back_buf, _vm->_sprite->_mainSprites,
|
2004-11-07 14:15:41 +00:00
|
|
|
ObjectTable[_inventory[i]].spritelistRn,
|
2004-12-22 21:04:50 +00:00
|
|
|
drawPoint, 256);
|
2004-11-07 14:15:41 +00:00
|
|
|
|
2005-01-11 21:10:36 +00:00
|
|
|
if (++col >= _vm->getDisplayInfo().inventoryColumns) {
|
|
|
|
if (++row >= _vm->getDisplayInfo().inventoryRows) {
|
2004-11-07 14:15:41 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
col = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int Interface::inventoryTest(const Point& imousePt, int *ibutton) {
|
|
|
|
int row = 0;
|
|
|
|
int col = 0;
|
|
|
|
|
2005-01-11 21:10:36 +00:00
|
|
|
int xbase = _vm->getDisplayInfo().inventoryX;
|
|
|
|
int ybase = _vm->getDisplayInfo().inventoryY;
|
|
|
|
int width = _vm->getDisplayInfo().inventoryIconWidth + _vm->getDisplayInfo().inventoryXSpacing;
|
|
|
|
int height = _vm->getDisplayInfo().inventoryIconHeight + _vm->getDisplayInfo().inventoryYSpacing;
|
2004-11-07 14:15:41 +00:00
|
|
|
|
|
|
|
for (int i = 0; i < _inventoryCount; i++) {
|
|
|
|
int x = xbase + col * width;
|
|
|
|
int y = ybase + row * height;
|
|
|
|
|
2005-01-11 21:10:36 +00:00
|
|
|
if (imousePt.x >= x && imousePt.x < x + _vm->getDisplayInfo().inventoryIconWidth && imousePt.y >= y && imousePt.y < y + _vm->getDisplayInfo().inventoryIconHeight) {
|
2004-11-07 14:15:41 +00:00
|
|
|
*ibutton = i;
|
|
|
|
return SUCCESS;
|
|
|
|
}
|
|
|
|
|
2005-01-11 21:10:36 +00:00
|
|
|
if (++col >= _vm->getDisplayInfo().inventoryColumns) {
|
|
|
|
if (++row >= _vm->getDisplayInfo().inventoryRows) {
|
2004-11-07 14:15:41 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
col = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return FAILURE;
|
|
|
|
}
|
|
|
|
|
2005-01-15 20:12:49 +00:00
|
|
|
|
2005-01-09 23:41:22 +00:00
|
|
|
void Interface::drawVerb(int verb, int state) {
|
2005-01-13 22:42:49 +00:00
|
|
|
SURFACE *backBuffer;
|
|
|
|
PanelButton * panelButton;
|
|
|
|
PanelButton * rightButtonVerbPanelButton;
|
|
|
|
PanelButton * currentVerbPanelButton;
|
|
|
|
int textColor;
|
|
|
|
int spriteNumber;
|
|
|
|
Point point;
|
|
|
|
|
|
|
|
backBuffer = _vm->_gfx->getBackBuffer();
|
|
|
|
|
|
|
|
panelButton = getPanelButtonByVerbType(verb);
|
|
|
|
rightButtonVerbPanelButton = getPanelButtonByVerbType(_vm->_script->getRightButtonVerb());
|
|
|
|
currentVerbPanelButton = getPanelButtonByVerbType(_vm->_script->getCurrentVerb());
|
|
|
|
|
|
|
|
if (panelButton == NULL) {
|
|
|
|
warning("panelButton == NULL");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (state == 2) {
|
|
|
|
state = (_mainPanel.currentButton == panelButton) ? 1 : 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (state) {
|
|
|
|
textColor = _vm->getDisplayInfo().verbTextActiveColor;
|
|
|
|
} else {
|
|
|
|
if (panelButton == rightButtonVerbPanelButton) {
|
|
|
|
textColor = _vm->getDisplayInfo().verbTextActiveColor;
|
|
|
|
} else {
|
|
|
|
textColor = _vm->getDisplayInfo().verbTextColor;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (panelButton == currentVerbPanelButton) {
|
|
|
|
spriteNumber = panelButton->downSpriteNumber;
|
|
|
|
} else {
|
|
|
|
spriteNumber = panelButton->upSpriteNumber;
|
|
|
|
}
|
|
|
|
point.x = _mainPanel.x + panelButton->xOffset;
|
|
|
|
point.y = _mainPanel.y + panelButton->yOffset;
|
|
|
|
|
|
|
|
_vm->_sprite->draw(backBuffer, _mainPanel.sprites, spriteNumber, point, 256);
|
|
|
|
|
|
|
|
drawPanelButtonText(backBuffer, &_mainPanel, panelButton, textColor, _vm->getDisplayInfo().verbTextShadowColor);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Interface::drawPanelButtonText(SURFACE *ds, InterfacePanel *panel, PanelButton *panelButton, int textColor, int textShadowColor) {
|
|
|
|
const char *text;
|
|
|
|
int textWidth;
|
|
|
|
Point point;
|
|
|
|
int textId;
|
|
|
|
|
|
|
|
textId = verbTypeToTextStringsIdLUT[panelButton->id];
|
|
|
|
|
|
|
|
if (textId == -1)
|
|
|
|
error("textId == -1");
|
|
|
|
|
|
|
|
text = _vm->getTextString(textId);
|
|
|
|
|
|
|
|
|
|
|
|
textWidth = _vm->_font->getStringWidth(SMALL_FONT_ID, text, 0, 0);
|
|
|
|
|
|
|
|
point.x = panel->x + panelButton->xOffset + (panelButton->width / 2) - (textWidth / 2);
|
|
|
|
point.y = panel->y + panelButton->yOffset + 1;
|
|
|
|
|
|
|
|
_vm->_font->draw(SMALL_FONT_ID, ds, text, 0, point.x , point.y, textColor, textShadowColor, (textShadowColor != 0) ? FONT_SHADOW : 0);
|
2005-01-09 23:41:22 +00:00
|
|
|
}
|
|
|
|
|
2005-01-10 22:51:01 +00:00
|
|
|
// Converse stuff
|
|
|
|
void Interface::converseClear(void) {
|
|
|
|
for (int i = 0; i < CONVERSE_MAX_TEXTS; i++) {
|
|
|
|
if (_converseText[i].text)
|
|
|
|
free(_converseText[i].text);
|
|
|
|
_converseText[i].text = NULL;
|
|
|
|
_converseText[i].stringNum = -1;
|
|
|
|
_converseText[i].replyId = 0;
|
|
|
|
_converseText[i].replyFlags = 0;
|
|
|
|
_converseText[i].replyBit = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
_converseTextCount = 0;
|
|
|
|
_converseStrCount = 0;
|
|
|
|
_converseStartPos = 0;
|
|
|
|
_converseEndPos = 0;
|
|
|
|
_conversePos = -1;
|
2005-01-11 00:51:58 +00:00
|
|
|
|
|
|
|
for (int i = 0; i < CONVERSE_TEXT_LINES; i++) {
|
|
|
|
_converseLastColors[0][i] = 0;
|
|
|
|
_converseLastColors[1][i] = 0;
|
|
|
|
}
|
2005-01-10 22:51:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool Interface::converseAddText(const char *text, int replyId, byte replyFlags, int replyBit) {
|
|
|
|
int count = 0; // count how many pieces of text per string
|
|
|
|
char temp[128];
|
|
|
|
|
|
|
|
assert(strlen(text) < 128);
|
|
|
|
|
|
|
|
strncpy(temp, text, 128);
|
|
|
|
|
|
|
|
while (1) {
|
|
|
|
int i;
|
|
|
|
int len = strlen(temp);
|
|
|
|
|
|
|
|
for (i = len; i >= 0; i--) {
|
|
|
|
byte c = temp[i];
|
|
|
|
|
|
|
|
if ((c == ' ' || c == '\0')
|
|
|
|
&& _vm->_font->getStringWidth(SMALL_FONT_ID, temp, i, 0)
|
|
|
|
<= CONVERSE_MAX_TEXT_WIDTH)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (i < 0)
|
|
|
|
return true;
|
|
|
|
|
|
|
|
if (_converseTextCount == CONVERSE_MAX_TEXTS)
|
|
|
|
return true;
|
|
|
|
|
|
|
|
_converseText[_converseTextCount].text = (char *)malloc(i + 1);
|
|
|
|
strncpy(_converseText[_converseTextCount].text, temp, i);
|
|
|
|
|
|
|
|
_converseText[_converseTextCount].text[i] = 0;
|
|
|
|
_converseText[_converseTextCount].textNum = count;
|
|
|
|
_converseText[_converseTextCount].stringNum = _converseStrCount;
|
|
|
|
_converseText[_converseTextCount].replyId = replyId;
|
|
|
|
_converseText[_converseTextCount].replyFlags = replyFlags;
|
|
|
|
_converseText[_converseTextCount].replyBit = replyBit;
|
|
|
|
|
|
|
|
_converseTextCount++;
|
|
|
|
count++;
|
|
|
|
|
|
|
|
if (len == i)
|
|
|
|
break;
|
|
|
|
|
|
|
|
strncpy(temp, &temp[i + 1], len - i);
|
|
|
|
}
|
|
|
|
|
|
|
|
_converseStrCount++;
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
enum converseColors {
|
|
|
|
kColorBrightWhite = 0x2,
|
2005-01-11 00:51:58 +00:00
|
|
|
kColorGrey = 0xa,
|
|
|
|
kColorDarkGrey = 0xb,
|
2005-01-10 22:51:01 +00:00
|
|
|
kColorGreen = 0xba,
|
|
|
|
kColorBlack = 0xf,
|
|
|
|
kColorBlue = 0x93
|
|
|
|
};
|
|
|
|
|
|
|
|
void Interface::converseDisplayText(int pos) {
|
|
|
|
int end;
|
|
|
|
|
|
|
|
if (pos >= _converseTextCount)
|
|
|
|
pos = _converseTextCount - 1;
|
|
|
|
if (pos < 0)
|
|
|
|
pos = 0;
|
|
|
|
|
|
|
|
_converseStartPos = pos;
|
|
|
|
|
|
|
|
end = _converseTextCount - CONVERSE_TEXT_LINES;
|
|
|
|
|
|
|
|
if (end < 0)
|
|
|
|
end = 0;
|
|
|
|
|
|
|
|
_converseEndPos = end;
|
|
|
|
|
|
|
|
converseDisplayTextLine(kColorBrightWhite, false, true);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Interface::converseSetTextLines(int row, int textcolor, bool btnDown) {
|
|
|
|
_conversePos = row + _converseStartPos;
|
|
|
|
if (_conversePos >= _converseTextCount)
|
|
|
|
_conversePos = -1;
|
|
|
|
|
|
|
|
converseDisplayTextLine(textcolor, btnDown, false);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Interface::converseDisplayTextLine(int textcolor, bool btnDown, bool rebuild) {
|
2005-01-11 00:51:58 +00:00
|
|
|
int x = 52; // FIXME: remove hardcoded value
|
|
|
|
int y = 6; // FIXME: remove hardcoded value
|
|
|
|
int pos = _converseStartPos;
|
|
|
|
byte textcolors[2][CONVERSE_TEXT_LINES];
|
|
|
|
SURFACE *ds;
|
|
|
|
|
|
|
|
ds = _vm->_gfx->getBackBuffer(); // FIXME: probably best to move this out
|
|
|
|
|
|
|
|
for (int i = 0; i < CONVERSE_TEXT_LINES; i++) {
|
|
|
|
int relpos = pos + i;
|
|
|
|
|
|
|
|
if (_conversePos >= 0
|
|
|
|
&& _converseText[_conversePos].stringNum
|
|
|
|
== _converseText[relpos].stringNum) {
|
|
|
|
textcolors[0][i] = textcolor;
|
|
|
|
textcolors[1][i] = (!btnDown) ? kColorDarkGrey : kColorGrey;
|
|
|
|
} else {
|
|
|
|
textcolors[0][i] = kColorBlue;
|
|
|
|
textcolors[1][i] = kColorDarkGrey;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// if no colors have changed, exit
|
|
|
|
if (!rebuild && memcmp(textcolors, _converseLastColors, sizeof(textcolors)) == 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
memcpy(_converseLastColors, textcolors, sizeof(textcolors));
|
|
|
|
|
|
|
|
Rect rect(8, CONVERSE_TEXT_LINES * CONVERSE_TEXT_HEIGHT);
|
|
|
|
int scrx = _conversePanel.x + x;
|
|
|
|
|
|
|
|
rect.moveTo(_conversePanel.x + x, _conversePanel.y + y);
|
|
|
|
|
|
|
|
drawRect(ds, &rect, kColorDarkGrey);
|
|
|
|
|
|
|
|
rect.top = rect.left = 0;
|
|
|
|
rect.right = CONVERSE_MAX_TEXT_WIDTH;
|
|
|
|
rect.bottom = CONVERSE_TEXT_HEIGHT;
|
|
|
|
|
|
|
|
for (int i = 0; i < CONVERSE_TEXT_LINES; i++) {
|
|
|
|
byte foregnd = textcolors[0][i];
|
|
|
|
byte backgnd = textcolors[1][i];
|
|
|
|
int relpos = pos + i;
|
|
|
|
|
|
|
|
rect.moveTo(_conversePanel.x + x + 7 + 1,
|
|
|
|
_conversePanel.y + y + i * CONVERSE_TEXT_HEIGHT);
|
|
|
|
|
|
|
|
drawRect(ds, &rect, backgnd);
|
|
|
|
|
|
|
|
if (_converseTextCount > i) {
|
|
|
|
const char *str = _converseText[relpos].text;
|
2005-01-11 21:10:36 +00:00
|
|
|
char bullet[] = { (char)0xb7, 0 };
|
2005-01-11 00:51:58 +00:00
|
|
|
int scry = i * CONVERSE_TEXT_HEIGHT + _conversePanel.y + y;
|
|
|
|
byte tcolor, bcolor;
|
|
|
|
|
|
|
|
if (_converseText[relpos].textNum == 0) { // first entry
|
|
|
|
tcolor = kColorGreen;
|
|
|
|
bcolor = kColorBlack;
|
|
|
|
_vm->_font->draw(SMALL_FONT_ID, ds, bullet, strlen(bullet),
|
|
|
|
scrx + 2, scry, tcolor, bcolor, FONT_SHADOW | FONT_DONTMAP);
|
|
|
|
}
|
|
|
|
_vm->_font->draw(SMALL_FONT_ID, ds, str, strlen(str),
|
|
|
|
scrx + 9, scry, foregnd, kColorBlack, FONT_SHADOW);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// FIXME: TODO: arrows
|
2005-01-10 22:51:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void Interface::converseChangePos(int chg) {
|
|
|
|
if ((chg < 0 && _converseStartPos + chg >= 0) ||
|
|
|
|
(chg > 0 && _converseStartPos < _converseEndPos)) {
|
|
|
|
_converseStartPos += chg;
|
|
|
|
converseDisplayTextLine(kColorBlue, false, true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Interface::converseSetPos(void) {
|
|
|
|
Converse *ct;
|
|
|
|
int selection = 1; // = keyStroke - '1'; // FIXME
|
|
|
|
|
|
|
|
if (selection >= _converseTextCount)
|
|
|
|
return;
|
|
|
|
|
|
|
|
// FIXME: wait until Andrew defines proper color
|
|
|
|
converseSetTextLines(selection, kColorBrightWhite, false);
|
|
|
|
|
|
|
|
ct = &_converseText[_conversePos];
|
|
|
|
// FIXME: TODO: finish dialog thread
|
|
|
|
|
|
|
|
// FIXME: TODO: Puzzle
|
|
|
|
|
|
|
|
_conversePos = -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-04-12 21:40:49 +00:00
|
|
|
} // End of namespace Saga
|