Initial commit
This commit is contained in:
597
engines/bagel/spacebar/baglib/base_pda.cpp
Normal file
597
engines/bagel/spacebar/baglib/base_pda.cpp
Normal file
@@ -0,0 +1,597 @@
|
||||
/* 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 "bagel/spacebar/baglib/base_pda.h"
|
||||
#include "bagel/spacebar/baglib/event_sdev.h"
|
||||
#include "bagel/spacebar/dialogs/opt_window.h"
|
||||
#include "bagel/spacebar/baglib/log_msg.h"
|
||||
#include "bagel/spacebar/baglib/bagel.h"
|
||||
#include "bagel/spacebar/baglib/master_win.h"
|
||||
#include "bagel/spacebar/baglib/moo.h"
|
||||
#include "bagel/spacebar/baglib/storage_dev_win.h"
|
||||
#include "bagel/spacebar/baglib/wield.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
// Init static members
|
||||
PdaMode SBBasePda::_pdaMode;
|
||||
PdaPos SBBasePda::_pdaPos;
|
||||
PdaMode SBBasePda::_holdMode;
|
||||
|
||||
void SBBasePda::initialize() {
|
||||
_pdaMode = PDA_NO_MODE;
|
||||
_pdaPos = PDA_POS_UNINITIALIZED;
|
||||
_holdMode = PDA_NO_MODE;
|
||||
}
|
||||
|
||||
SBBasePda::SBBasePda(CBofWindow *parent, const CBofRect & /* xRect*/, bool activated) {
|
||||
_activated = activated;
|
||||
_activating = false;
|
||||
_moveDist = 13;
|
||||
_numMoves = 10;
|
||||
|
||||
_parent = parent;
|
||||
_mooWnd = nullptr;
|
||||
_invWnd = nullptr;
|
||||
_mapWnd = nullptr;
|
||||
_logWnd = nullptr;
|
||||
|
||||
_curDisplay = nullptr;
|
||||
_holdDisplay = nullptr;
|
||||
|
||||
// Other classes need to know if we're zoomed
|
||||
setZoomed(false);
|
||||
setDeactivate(false);
|
||||
|
||||
}
|
||||
|
||||
SBBasePda::~SBBasePda() {
|
||||
_invWnd = nullptr;
|
||||
_mapWnd = nullptr;
|
||||
_logWnd = nullptr;
|
||||
_mooWnd = nullptr;
|
||||
}
|
||||
|
||||
bool SBBasePda::hideCurDisplay() {
|
||||
synchronizePdaState();
|
||||
|
||||
if (_curDisplay) {
|
||||
// If we have an inventory window
|
||||
_curDisplay->setVisible(false);
|
||||
|
||||
// Hold this info.
|
||||
_holdDisplay = _curDisplay;
|
||||
_holdMode = _pdaMode;
|
||||
|
||||
_curDisplay = nullptr;
|
||||
_pdaMode = PDA_NO_MODE;
|
||||
setPdaState();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SBBasePda::restoreCurDisplay() {
|
||||
synchronizePdaState();
|
||||
|
||||
// If we saved a display
|
||||
if (_holdDisplay) {
|
||||
// Restore the display info.
|
||||
_curDisplay = _holdDisplay;
|
||||
_pdaMode = _holdMode;
|
||||
|
||||
_curDisplay->setVisible(true);
|
||||
setPdaState();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SBBasePda::hideMovie() {
|
||||
synchronizePdaState();
|
||||
|
||||
if (_mooWnd) {
|
||||
// if we have an inventory window
|
||||
_mooWnd->setVisible(false);
|
||||
_curDisplay = nullptr;
|
||||
_pdaMode = PDA_NO_MODE;
|
||||
setPdaState();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SBBasePda::showMovie() {
|
||||
synchronizePdaState();
|
||||
|
||||
// if we're already playing a movie, then return false
|
||||
if (_pdaMode == PDA_MOO_MODE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_mooWnd) {
|
||||
if (_curDisplay) {
|
||||
// Turn off the current display
|
||||
_curDisplay->setVisible(false);
|
||||
}
|
||||
|
||||
// Save the current PDA mode so we can return to it when done.
|
||||
((CBagMoo *)_mooWnd)->savePDAMode(_pdaMode);
|
||||
((CBagMoo *)_mooWnd)->savePDAPosition(_pdaPos);
|
||||
|
||||
// Turn on the inventory
|
||||
_mooWnd->setVisible(true);
|
||||
|
||||
// Set the current display = Inventory
|
||||
_curDisplay = _mooWnd;
|
||||
_pdaMode = PDA_MOO_MODE;
|
||||
setPdaState();
|
||||
|
||||
// Set default state of movie to don't deactivate PDA
|
||||
setDeactivate(false);
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void SBBasePda::stopMovie(bool bResetPDA) const {
|
||||
if (_mooWnd && _mooWnd == _curDisplay) {
|
||||
((CBagMoo *)_mooWnd)->stopMovie(bResetPDA);
|
||||
}
|
||||
}
|
||||
|
||||
bool SBBasePda::setMovie(CBofString &movieName) const {
|
||||
if (_mooWnd) {
|
||||
((CBagMoo *)_mooWnd)->setPDAMovie(movieName);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SBBasePda::hideInventory() {
|
||||
synchronizePdaState();
|
||||
|
||||
// if we have an inventory window
|
||||
if (_invWnd) {
|
||||
_invWnd->setVisible(false);
|
||||
_curDisplay = nullptr;
|
||||
_pdaMode = PDA_NO_MODE;
|
||||
setPdaState();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SBBasePda::showInventory() {
|
||||
synchronizePdaState();
|
||||
|
||||
// if a movie is playing, then stop it.
|
||||
stopMovie(false);
|
||||
|
||||
// If we have an inventory window
|
||||
if (_invWnd) {
|
||||
if (_curDisplay) {
|
||||
// Turn off the current display
|
||||
_curDisplay->setVisible(false);
|
||||
}
|
||||
// Turn on the inventory
|
||||
_invWnd->setVisible(true);
|
||||
|
||||
// Set the current display = Inventory
|
||||
_curDisplay = _invWnd;
|
||||
_pdaMode = PDA_INV_MODE;
|
||||
setPdaState();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SBBasePda::showMap() {
|
||||
synchronizePdaState();
|
||||
|
||||
// If a movie is playing, then stop it.
|
||||
stopMovie(false);
|
||||
|
||||
// if we have a map window
|
||||
if (_mapWnd) {
|
||||
if (_curDisplay) {
|
||||
// Turn off the current display
|
||||
_curDisplay->setVisible(false);
|
||||
}
|
||||
|
||||
// Turn on the map
|
||||
_mapWnd->setVisible(true);
|
||||
|
||||
// Set the current display = Map
|
||||
_curDisplay = _mapWnd;
|
||||
_pdaMode = PDA_MAP_MODE;
|
||||
_mapWnd->attachActiveObjects();
|
||||
setPdaState();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SBBasePda::hideMap() {
|
||||
synchronizePdaState();
|
||||
|
||||
// if we have a map window
|
||||
if (_mapWnd) {
|
||||
// Turn off the Map
|
||||
_mapWnd->setVisible(false);
|
||||
|
||||
// set the current display to nullptr
|
||||
_curDisplay = nullptr;
|
||||
setPdaState();
|
||||
_pdaMode = PDA_NO_MODE;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SBBasePda::showLog() {
|
||||
if (CBagStorageDevWnd::_pEvtSDev != nullptr) {
|
||||
CBagStorageDevWnd::_pEvtSDev->evaluateExpressions();
|
||||
}
|
||||
|
||||
synchronizePdaState();
|
||||
|
||||
// If a movie is playing, then stop it.
|
||||
stopMovie(false);
|
||||
|
||||
// if we have a map window
|
||||
if (_logWnd) {
|
||||
if (_curDisplay) {
|
||||
// Turn off the current display
|
||||
_curDisplay->setVisible(false);
|
||||
}
|
||||
|
||||
// Turn on the map
|
||||
_logWnd->setVisible(true);
|
||||
|
||||
// Set the current display = Map
|
||||
_curDisplay = _logWnd;
|
||||
_pdaMode = PDA_LOG_MODE;
|
||||
_logWnd->attachActiveObjects();
|
||||
setPdaState();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SBBasePda::msgLight() {
|
||||
// If we have a map window
|
||||
if (_logWnd) {
|
||||
((CBagLog *)_logWnd)->playMsgQueue();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void *SBBasePda::pdaButtonHandler(int refId, void *info) {
|
||||
assert(info != nullptr);
|
||||
|
||||
SBBasePda *curPda = (SBBasePda *)info;
|
||||
|
||||
switch (refId) {
|
||||
case PDA_MAP:
|
||||
curPda->showMap();
|
||||
break;
|
||||
|
||||
case PDA_STASH:
|
||||
curPda->showInventory();
|
||||
break;
|
||||
|
||||
case PDA_ZOOM:
|
||||
curPda->zoom();
|
||||
break;
|
||||
|
||||
case PDA_SYSTEM: {
|
||||
CBagel *curApp = CBagel::getBagApp();
|
||||
if (curApp != nullptr) {
|
||||
CBagMasterWin *curWnd = curApp->getMasterWnd();
|
||||
if (curWnd != nullptr) {
|
||||
curWnd->postUserMessage(WM_SHOW_SYSTEM_DLG, 0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case PDA_LOG:
|
||||
curPda->showLog();
|
||||
break;
|
||||
|
||||
case PDA_OFF:
|
||||
curPda->deactivate();
|
||||
break;
|
||||
|
||||
case PDA_MSGLIGHT:
|
||||
curPda->msgLight();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
void SBBasePda::synchronizePdaState() {
|
||||
if (_pdaPos == PDA_DOWN && isActivated()) {
|
||||
deactivate();
|
||||
} else if (_pdaPos == PDA_UP && isActivated() == false) {
|
||||
activate();
|
||||
}
|
||||
}
|
||||
|
||||
void SBBasePda::activate() {
|
||||
if (!_activating) {
|
||||
_activating = _numMoves;
|
||||
_activated = true;
|
||||
}
|
||||
|
||||
_pdaPos = PDA_UP;
|
||||
setPdaState();
|
||||
}
|
||||
|
||||
void SBBasePda::deactivate() {
|
||||
if (!_activating) {
|
||||
_activating = _numMoves;
|
||||
_activated = false;
|
||||
}
|
||||
|
||||
_pdaPos = PDA_DOWN;
|
||||
setPdaState();
|
||||
}
|
||||
|
||||
void SBBasePda::setPdaState() {
|
||||
const char *pdaMode;
|
||||
const char *pdaPos;
|
||||
|
||||
CBagVar *curVar = g_VarManager->getVariable("INBAR");
|
||||
|
||||
if (curVar != nullptr) {
|
||||
// Defined as global
|
||||
pdaMode = "BARPDAMODE";
|
||||
pdaPos = "BARPDAPOSITION";
|
||||
} else {
|
||||
pdaMode = "PDAMODE";
|
||||
pdaPos = "PDAPOSITION";
|
||||
}
|
||||
|
||||
// Save the pda state and position
|
||||
curVar = g_VarManager->getVariable(pdaMode);
|
||||
if (curVar != nullptr) {
|
||||
switch (_pdaMode) {
|
||||
case PDA_NO_MODE:
|
||||
curVar->setValue("NOMODE");
|
||||
break;
|
||||
case PDA_MAP_MODE:
|
||||
curVar->setValue("MAPMODE");
|
||||
break;
|
||||
case PDA_INV_MODE:
|
||||
curVar->setValue("INVMODE");
|
||||
break;
|
||||
case PDA_LOG_MODE:
|
||||
curVar->setValue("LOGMODE");
|
||||
break;
|
||||
case PDA_MOO_MODE:
|
||||
curVar->setValue("MOOMODE");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
curVar = g_VarManager->getVariable(pdaPos);
|
||||
if (curVar != nullptr) {
|
||||
switch (_pdaPos) {
|
||||
case PDA_UP:
|
||||
curVar->setValue("UP");
|
||||
break;
|
||||
case PDA_DOWN:
|
||||
curVar->setValue("DOWN");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SBBasePda::getPdaState() {
|
||||
char localBuff[256];
|
||||
CBofString pdaState(localBuff, 256);
|
||||
const char *pdaMode;
|
||||
const char *pdaPos;
|
||||
|
||||
CBagVar *curVar = g_VarManager->getVariable("INBAR");
|
||||
|
||||
if (curVar != nullptr) {
|
||||
// Defined as global
|
||||
pdaMode = "BARPDAMODE";
|
||||
pdaPos = "BARPDAPOSITION";
|
||||
} else {
|
||||
pdaMode = "PDAMODE";
|
||||
pdaPos = "PDAPOSITION";
|
||||
}
|
||||
|
||||
curVar = g_VarManager->getVariable(pdaMode);
|
||||
if (curVar) {
|
||||
pdaState = curVar->getValue();
|
||||
// Now set the internal PDA state based on this info.
|
||||
// If we saved during a movie, then restore to map mode.
|
||||
if (pdaState.find("MAP") != -1 || pdaState.find("MOO") != -1) {
|
||||
_pdaMode = PDA_MAP_MODE;
|
||||
} else if (pdaState.find("INV") != -1) {
|
||||
_pdaMode = PDA_INV_MODE;
|
||||
} else if (pdaState.find("LOG") != -1) {
|
||||
_pdaMode = PDA_LOG_MODE;
|
||||
} else if (pdaState.find("MOO") != -1) {
|
||||
_pdaMode = PDA_MOO_MODE;
|
||||
} else {
|
||||
_pdaMode = PDA_NO_MODE;
|
||||
}
|
||||
}
|
||||
|
||||
// Get the PDA up/down position
|
||||
curVar = g_VarManager->getVariable(pdaPos);
|
||||
if (curVar) {
|
||||
pdaState = curVar->getValue();
|
||||
if (pdaState.find("UP") != -1) {
|
||||
_pdaPos = PDA_UP;
|
||||
} else {
|
||||
_pdaPos = PDA_DOWN;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#define NULL_CURSOR 0
|
||||
#define HAND_CURSOR 1
|
||||
|
||||
int SBBasePda::getProperCursor(const CBofPoint &pos, CBofRect &pdaRect) const {
|
||||
const int wieldCursor = CBagWield::getWieldCursor();
|
||||
|
||||
// Assume can't click
|
||||
const int cursorID = NULL_CURSOR;
|
||||
|
||||
// If we're in the map, return the nullptr cursor, if on the pda but not in the
|
||||
// map window, return the hand. Same rules for nomode.
|
||||
switch (_pdaMode) {
|
||||
case PDA_MAP_MODE:
|
||||
case PDA_NO_MODE:
|
||||
case PDA_MOO_MODE:
|
||||
if (_mapWnd) {
|
||||
const CBofRect pdaViewRect = _mapWnd->getRect() + pdaRect.topLeft();
|
||||
if (pdaViewRect.ptInRect(pos)) {
|
||||
if (wieldCursor >= 0) {
|
||||
return wieldCursor;
|
||||
}
|
||||
return NULL_CURSOR;
|
||||
}
|
||||
return HAND_CURSOR;
|
||||
}
|
||||
break;
|
||||
|
||||
case PDA_INV_MODE:
|
||||
case PDA_LOG_MODE:
|
||||
// Make sure our cur display is synchronized.
|
||||
assert(_pdaMode == PDA_INV_MODE ? _curDisplay == _invWnd : _curDisplay == _logWnd);
|
||||
|
||||
// If we have a display, then parouse its list and see if we're over something worth
|
||||
// mousedowning on.
|
||||
if (_curDisplay) {
|
||||
CBagObject *overObj = nullptr;
|
||||
CBofRect pdaViewRect = _curDisplay->getRect() + pdaRect.topLeft();
|
||||
if (pdaViewRect.ptInRect(pos)) {
|
||||
// Go through the list of inventory items and see if we're over any of them
|
||||
// in particular.
|
||||
CBofList<CBagObject *> *objList = _curDisplay->getObjectList();
|
||||
if (objList != nullptr) {
|
||||
// Localize pda view rect
|
||||
pdaViewRect = _curDisplay->getRect() + pdaRect.topLeft();
|
||||
|
||||
const int count = objList->getCount();
|
||||
for (int i = 0; i < count; ++i) {
|
||||
CBagObject *curObj = objList->getNodeItem(i);
|
||||
if (curObj->isActive()) {
|
||||
// localize icon rectangle
|
||||
CBofRect iconRect = curObj->getRect() + pdaViewRect.topLeft();
|
||||
if (iconRect.ptInRect(pos)) {
|
||||
overObj = curObj;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (_pdaMode == PDA_LOG_MODE) {
|
||||
if (overObj) {
|
||||
return overObj->getOverCursor();
|
||||
}
|
||||
if (wieldCursor >= 0) {
|
||||
return wieldCursor;
|
||||
}
|
||||
}
|
||||
|
||||
if (_pdaMode == PDA_INV_MODE) {
|
||||
if (wieldCursor >= 0) {
|
||||
return wieldCursor;
|
||||
}
|
||||
if (overObj) {
|
||||
return overObj->getOverCursor();
|
||||
}
|
||||
}
|
||||
|
||||
return NULL_CURSOR;
|
||||
}
|
||||
|
||||
return HAND_CURSOR;
|
||||
}
|
||||
}
|
||||
|
||||
return cursorID;
|
||||
}
|
||||
|
||||
CBofRect SBBasePda::getViewRect() const {
|
||||
return (_curDisplay == nullptr ? CBofRect() : _curDisplay->getRect());
|
||||
}
|
||||
|
||||
ErrorCode SBBasePda::attachActiveObjects() {
|
||||
if (CBagStorageDevWnd::_pEvtSDev != nullptr) {
|
||||
CBagStorageDevWnd::_pEvtSDev->evaluateExpressions();
|
||||
}
|
||||
|
||||
if (_mooWnd)
|
||||
_mooWnd->attachActiveObjects();
|
||||
if (_invWnd)
|
||||
_invWnd->attachActiveObjects();
|
||||
if (_mapWnd)
|
||||
_mapWnd->attachActiveObjects();
|
||||
if (_logWnd)
|
||||
_logWnd->attachActiveObjects();
|
||||
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
ErrorCode SBBasePda::detachActiveObjects() {
|
||||
if (_mooWnd)
|
||||
_mooWnd->detachActiveObjects();
|
||||
if (_invWnd)
|
||||
_invWnd->detachActiveObjects();
|
||||
if (_mapWnd)
|
||||
_mapWnd->detachActiveObjects();
|
||||
if (_logWnd)
|
||||
_logWnd->detachActiveObjects();
|
||||
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
Reference in New Issue
Block a user