2050 lines
50 KiB
C++
2050 lines
50 KiB
C++
/* 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/storage_dev_win.h"
|
|
#include "bagel/boflib/misc.h"
|
|
#include "bagel/boflib/error.h"
|
|
#include "bagel/spacebar/boflib/gfx/sprite.h"
|
|
#include "bagel/boflib/event_loop.h"
|
|
#include "bagel/spacebar/baglib/bagel.h"
|
|
#include "bagel/spacebar/baglib/master_win.h"
|
|
#include "bagel/spacebar/baglib/wield.h"
|
|
#include "bagel/spacebar/baglib/menu_dlg.h"
|
|
#include "bagel/spacebar/baglib/log_msg.h"
|
|
#include "bagel/spacebar/baglib/event_sdev.h"
|
|
|
|
// Objects up the yang
|
|
#include "bagel/spacebar/baglib/area_object.h"
|
|
#include "bagel/spacebar/baglib/bmp_object.h"
|
|
#include "bagel/spacebar/baglib/button_object.h"
|
|
#include "bagel/spacebar/baglib/character_object.h"
|
|
#include "bagel/spacebar/baglib/command_object.h"
|
|
#include "bagel/spacebar/baglib/expression_object.h"
|
|
#include "bagel/spacebar/baglib/link_object.h"
|
|
#include "bagel/spacebar/baglib/movie_object.h"
|
|
#include "bagel/spacebar/baglib/sound_object.h"
|
|
#include "bagel/spacebar/baglib/sprite_object.h"
|
|
#include "bagel/spacebar/baglib/text_object.h"
|
|
#include "bagel/spacebar/baglib/variable_object.h"
|
|
#include "bagel/spacebar/baglib/thing_object.h"
|
|
#include "bagel/spacebar/baglib/rp_object.h"
|
|
#include "bagel/spacebar/baglib/dossier_object.h"
|
|
#include "bagel/spacebar/baglib/pan_window.h"
|
|
#include "bagel/bagel.h"
|
|
#include "bagel/boflib/file_functions.h"
|
|
|
|
namespace Bagel {
|
|
namespace SpaceBar {
|
|
|
|
// Globals (hacks)
|
|
bool g_allowPaintFl = true;
|
|
bool g_bAAOk = true; // Prevent attachActiveObjects() after a RUN LNK
|
|
bool g_allowattachActiveObjectsFl = true; // Prevent attachActiveObjects() after a RUN LNK
|
|
CBagStorageDevWnd *g_lastWindow = nullptr;
|
|
extern bool g_pauseTimerFl;
|
|
extern bool g_waitOKFl;
|
|
|
|
// Statics
|
|
CBagEventSDev *CBagStorageDevWnd::_pEvtSDev = nullptr; // Pointer to the EventSDev
|
|
CBofPoint *CBagStorageDev::_xCursorLocation;
|
|
CBofRect *CBagStorageDev::gRepaintRect;
|
|
bool CBagStorageDev::_hidePdaFl = false;
|
|
bool CBagStorageDev::_bHandledUpEvent = false;
|
|
|
|
// Dirty object variables
|
|
bool CBagStorageDev::_bPanPreFiltered = false;
|
|
bool CBagStorageDev::_bDirtyAllObjects = false;
|
|
bool CBagStorageDev::_bPreFilter = false;
|
|
|
|
int CBagStorageDevManager::nSDevMngrs = 0;
|
|
|
|
// Local globals
|
|
static int gLastBackgroundUpdate = 0;
|
|
|
|
#define kCursWidth 55
|
|
|
|
void CBagStorageDev::initialize() {
|
|
g_allowPaintFl = true;
|
|
g_bAAOk = true;
|
|
g_allowattachActiveObjectsFl = true;
|
|
g_lastWindow = nullptr;
|
|
|
|
_xCursorLocation = new CBofPoint();
|
|
gRepaintRect = new CBofRect();
|
|
_hidePdaFl = false;
|
|
_bHandledUpEvent = false;
|
|
|
|
_bPanPreFiltered = false;
|
|
_bDirtyAllObjects = false;
|
|
_bPreFilter = false;
|
|
|
|
gLastBackgroundUpdate = 0;
|
|
}
|
|
|
|
void CBagStorageDev::shutdown() {
|
|
delete _xCursorLocation;
|
|
delete gRepaintRect;
|
|
}
|
|
|
|
CBagStorageDev::CBagStorageDev() {
|
|
_pLActiveObject = nullptr; // The last object selected on mouse down
|
|
|
|
_pAssociateWnd = nullptr; // The associate window for attaching sounds
|
|
|
|
_bForeignList = false;
|
|
_pObjectList = new CBofList<CBagObject *>;
|
|
_pExpressionList = nullptr;
|
|
_nDiskID = 1;
|
|
_bCloseup = false;
|
|
_bCIC = false;
|
|
|
|
// run object stuff
|
|
_bFirstPaint = true;
|
|
_nFloatPages = 0;
|
|
_xSDevType = SDEV_UNDEF;
|
|
_pBitmapFilter = nullptr;
|
|
|
|
setCloseOnOpen(false);
|
|
setExitOnEdge(0);
|
|
setFilterId(0);
|
|
setFadeId(0);
|
|
|
|
// Default is this thing is not a customized sdev.
|
|
setCustom(false);
|
|
|
|
// Make sure all objects that are prefiltered are dirty
|
|
setDirtyAllObjects(true);
|
|
|
|
// Not sure what the hell is going on here...
|
|
setLActivity(kMouseNONE);
|
|
|
|
g_SDevManager->registerStorageDev(this);
|
|
}
|
|
|
|
CBagStorageDev::~CBagStorageDev() {
|
|
if (!_bForeignList) {
|
|
|
|
if (_pObjectList != nullptr) {
|
|
// Delete all master sprite objects
|
|
CBagStorageDev::releaseObjects();
|
|
delete _pObjectList;
|
|
_pObjectList = nullptr;
|
|
}
|
|
if (_pExpressionList) {
|
|
while (_pExpressionList->getCount()) {
|
|
CBagExpression *pExp = _pExpressionList->removeHead();
|
|
delete pExp;
|
|
}
|
|
delete _pExpressionList;
|
|
_pExpressionList = nullptr;
|
|
}
|
|
} // If the lists belong to this storage device
|
|
|
|
g_SDevManager->unregisterStorageDev(this);
|
|
|
|
if (CBagStorageDevWnd::_pEvtSDev == this) {
|
|
CBagStorageDevWnd::_pEvtSDev = nullptr;
|
|
}
|
|
}
|
|
|
|
|
|
void CBagStorageDev::setPosition(const CBofPoint &pos) {
|
|
CBofRect OrigRect = getRect(); // Get the destination (screen) rect
|
|
|
|
_cDestRect.setRect(pos.x, pos.y,
|
|
pos.x + OrigRect.width() - 1,
|
|
pos.y + OrigRect.height() - 1);
|
|
}
|
|
|
|
|
|
bool CBagStorageDev::contains(CBagObject *pObj, bool bActive) {
|
|
int nCount = getObjectCount();
|
|
if (nCount != 0) {
|
|
for (int i = 0; i < nCount; ++i) {
|
|
if (pObj == getObjectByPos(i)) {
|
|
if (bActive && (pObj->isActive()))
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
|
|
ErrorCode CBagStorageDev::addObject(CBagObject *pObj, int /*nPos*/) {
|
|
ErrorCode errorCode = ERR_NONE;
|
|
|
|
// can't use a null pointer
|
|
assert(pObj != nullptr);
|
|
|
|
_pObjectList->addToTail(pObj);
|
|
|
|
return errorCode;
|
|
}
|
|
|
|
|
|
ErrorCode CBagStorageDev::removeObject(CBagObject *pRObj) {
|
|
ErrorCode errorCode = ERR_NONE;
|
|
|
|
if (!_bForeignList) {
|
|
int nCount = getObjectCount();
|
|
for (int i = 0; i < nCount; ++i) {
|
|
if (pRObj == getObjectByPos(i)) {
|
|
_pObjectList->remove(i);
|
|
return errorCode;
|
|
}
|
|
}
|
|
}
|
|
|
|
return errorCode;
|
|
}
|
|
|
|
|
|
ErrorCode CBagStorageDev::activateLocalObject(CBagObject *pObj) {
|
|
ErrorCode errCode = ERR_NONE;
|
|
|
|
if (pObj != nullptr) {
|
|
pObj->setLocal();
|
|
if (!pObj->isActive() && (!pObj->getExpression() || pObj->getExpression()->evaluate(pObj->isNegative()))) {
|
|
pObj->setActive();
|
|
pObj->attach();
|
|
|
|
// Perform an update and arrange objects in the storage device
|
|
if (g_allowattachActiveObjectsFl) {
|
|
attachActiveObjects();
|
|
}
|
|
}
|
|
} else {
|
|
errCode = ERR_FFIND;
|
|
}
|
|
|
|
return errCode;
|
|
}
|
|
|
|
|
|
ErrorCode CBagStorageDev::activateLocalObject(const CBofString &sName) {
|
|
// can't use a empty string
|
|
assert(!sName.isEmpty());
|
|
|
|
return activateLocalObject(getObject(sName));
|
|
}
|
|
|
|
ErrorCode CBagStorageDev::deactivateLocalObject(CBagObject *pObj) {
|
|
ErrorCode errorCode = ERR_NONE;
|
|
|
|
if (pObj != nullptr) {
|
|
pObj->setLocal(false);
|
|
if (pObj->isActive()) {
|
|
pObj->setActive(false);
|
|
pObj->detach();
|
|
}
|
|
} else {
|
|
errorCode = ERR_FFIND;
|
|
}
|
|
|
|
return errorCode;
|
|
}
|
|
|
|
|
|
ErrorCode CBagStorageDev::deactivateLocalObject(const CBofString &sName) {
|
|
// Can't use a empty string
|
|
assert(!sName.isEmpty());
|
|
|
|
return deactivateLocalObject(getObject(sName));
|
|
}
|
|
|
|
|
|
CBofPoint CBagStorageDev::arrangeFloater(CBofPoint &nPos, CBagObject *pObj) {
|
|
CBofPoint NextPos = nPos;
|
|
|
|
if (getBackground() != nullptr) {
|
|
int nBackWidth = getBackground()->width();
|
|
int nBackHeight = getBackground()->height();
|
|
int nObjWidth = pObj->getRect().width();
|
|
int nObjHeight = pObj->getRect().height();
|
|
|
|
// Check to see if the whole object can fit in, if it can't wrap
|
|
if (NextPos.x > (nBackWidth - nObjWidth)) {
|
|
NextPos.x = 0;
|
|
NextPos.y += pObj->getRect().height();
|
|
}
|
|
pObj->setPosition(NextPos);
|
|
|
|
// Always round this figure up...
|
|
|
|
int nPageNum = ((NextPos.y + nObjHeight) / nBackHeight);
|
|
if (((NextPos.y + nObjHeight) % nBackHeight) != 0) {
|
|
nPageNum++;
|
|
}
|
|
|
|
setNumFloatPages(nPageNum);
|
|
|
|
NextPos.x += pObj->getRect().width();
|
|
}
|
|
|
|
return NextPos;
|
|
}
|
|
|
|
|
|
ErrorCode CBagStorageDev::attachActiveObjects() {
|
|
ErrorCode errorCode = ERR_NONE;
|
|
CBofPoint nArrangePos(0, 0); // Removed 5,5 padding
|
|
|
|
CBagLog::initArrangePages();
|
|
|
|
int nCount = getObjectCount();
|
|
if (nCount != 0) {
|
|
for (int i = 0; i < nCount; ++i) {
|
|
if (g_engine->shouldQuit())
|
|
return ERR_NONE;
|
|
|
|
CBagObject *pObj = getObjectByPos(i);
|
|
if (pObj != nullptr) {
|
|
if (pObj->isLocal() && (!pObj->getExpression() || pObj->getExpression()->evaluate(pObj->isNegative()))) {
|
|
if (!pObj->isAttached()) {
|
|
pObj->setActive();
|
|
pObj->attach();
|
|
}
|
|
|
|
// If we have already painted the storage device once
|
|
if (pObj->isImmediateRun()) {
|
|
|
|
if (_bFirstPaint == false) {
|
|
|
|
pObj->runObject();
|
|
|
|
if (pObj->getType() == LINK_OBJ) {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (pObj->isFloating()) {
|
|
nArrangePos = arrangeFloater(nArrangePos, pObj);
|
|
}
|
|
} else if (pObj->isAttached()) {
|
|
|
|
if (pObj->getType() != SOUND_OBJ || !((CBagSoundObject *)pObj)->isPlaying()) {
|
|
pObj->setActive(false);
|
|
pObj->detach();
|
|
}
|
|
}
|
|
} else
|
|
errorCode = ERR_FFIND;
|
|
}
|
|
}
|
|
|
|
CBagLog::arrangePages();
|
|
|
|
return errorCode;
|
|
}
|
|
|
|
ErrorCode CBagStorageDev::detachActiveObjects() {
|
|
ErrorCode errorCode = ERR_NONE;
|
|
int nCount = getObjectCount();
|
|
|
|
if (nCount != 0) {
|
|
for (int i = 0; i < nCount; ++i) {
|
|
CBagObject *pObj = getObjectByPos(i);
|
|
if (pObj != nullptr) {
|
|
if (pObj->isAttached()) {
|
|
// If this object is not removed from memory, then
|
|
// make sure it is drawn next time it is activated.
|
|
pObj->setDirty(true);
|
|
pObj->detach();
|
|
}
|
|
} else
|
|
errorCode = ERR_FFIND;
|
|
}
|
|
}
|
|
return errorCode;
|
|
}
|
|
|
|
ErrorCode CBagStorageDev::loadObjects() {
|
|
ErrorCode errorCode = ERR_NONE;
|
|
return errorCode;
|
|
}
|
|
|
|
ErrorCode CBagStorageDev::releaseObjects() {
|
|
ErrorCode errorCode = ERR_NONE;
|
|
int nCount = getObjectCount();
|
|
|
|
if (!_bForeignList) {
|
|
if (nCount) {
|
|
for (int i = 0; i < nCount; ++i) {
|
|
CBagObject *pObj = _pObjectList->removeHead();
|
|
delete pObj;
|
|
}
|
|
}
|
|
|
|
_pObjectList->removeAll();
|
|
}
|
|
return errorCode;
|
|
}
|
|
|
|
|
|
void CBagStorageDev::setObjectList(CBofList<CBagObject *> *pOList, CBofList<CBagExpression *> *pEList) {
|
|
delete _pObjectList;
|
|
|
|
_bForeignList = true;
|
|
_pObjectList = pOList;
|
|
_pExpressionList = pEList;
|
|
}
|
|
|
|
|
|
ErrorCode CBagStorageDev::paintStorageDevice(CBofWindow * /*pWnd*/, CBofBitmap *pBmp, CBofRect * /*pRect*/) {
|
|
bool bMouseOverObj = false;
|
|
int nCount = getObjectCount();
|
|
|
|
if (nCount) {
|
|
CBofWindow *pWnd1 = CBagel::getBagApp()->getMasterWnd();
|
|
if (pWnd1)
|
|
pWnd1->screenToClient(&*_xCursorLocation);
|
|
|
|
for (int i = 0; i < nCount; ++i) {
|
|
CBagObject *pObj = getObjectByPos(i);
|
|
if (pObj->isAttached()) {
|
|
CBofRect xBmpRect = pObj->getRect();
|
|
CBofPoint pt = xBmpRect.topLeft();
|
|
xBmpRect.offsetRect(-pt.x, -pt.y);
|
|
|
|
if (pObj->isVisible()) {
|
|
if (pBmp) {
|
|
// Only update dirty objects...
|
|
if (pObj->isDirty() || pObj->isAlwaysUpdate()) {
|
|
pObj->update(pBmp, pt, &xBmpRect);
|
|
}
|
|
}
|
|
}
|
|
|
|
// if it is visible update it
|
|
if (pObj->getRect().ptInRect(*_xCursorLocation)) {
|
|
pObj->onMouseOver(0, *_xCursorLocation, this);
|
|
bMouseOverObj = true;
|
|
} // if on screen
|
|
} // If the object is attached
|
|
|
|
} // While a valid object
|
|
} // if there is any valid objects
|
|
|
|
if (!bMouseOverObj)
|
|
noObjectsUnderMouse();
|
|
|
|
return ERR_NONE;
|
|
}
|
|
|
|
ErrorCode CBagStorageDev::onLActiveObject(uint32 /*nFlags*/, CBofPoint */*xPoint*/, void */*vpInfo*/) {
|
|
return ERR_NONE;
|
|
}
|
|
|
|
|
|
ErrorCode CBagStorageDev::noObjectsUnderMouse() {
|
|
return ERR_NONE;
|
|
}
|
|
|
|
void CBagStorageDev::onMouseMove(uint32 nFlags, CBofPoint *xPoint, void *vpInfo) {
|
|
*_xCursorLocation = *xPoint;
|
|
|
|
if (getLActiveObject() && getLActivity()) {
|
|
getLActiveObject()->onMouseMove(nFlags, *xPoint, vpInfo);
|
|
}
|
|
}
|
|
|
|
|
|
ErrorCode CBagStorageDev::onMouseOver(uint32 /*nFlags*/, CBofPoint */*xPoint*/, void *) {
|
|
return ERR_NONE;
|
|
}
|
|
|
|
|
|
void CBagStorageDev::onLButtonDown(uint32 nFlags, CBofPoint *xPoint, void *vpInfo) {
|
|
if (CBagPDA::isMoviePlaying() && CBagMasterWin::getActiveCursor() == 6) {
|
|
return;
|
|
}
|
|
|
|
*_xCursorLocation = *xPoint;
|
|
CBofPoint xCursorLocation = devPtToViewPort(*xPoint);
|
|
|
|
setLActivity(kMouseNONE);
|
|
|
|
CBagObject *pObj = getObject(xCursorLocation, true);
|
|
if ((pObj != nullptr) && (pObj->isActive())) {
|
|
pObj->onLButtonDown(nFlags, xPoint, vpInfo);
|
|
setLActivity(kMouseDRAGGING);
|
|
}
|
|
|
|
setLActiveObject(pObj);
|
|
}
|
|
|
|
// TODO: This is a global, move it to the main class
|
|
bool g_noMenuFl = false;
|
|
|
|
|
|
void CBagStorageDev::onLButtonUp(uint32 nFlags, CBofPoint *xPoint, void *vpInfo) {
|
|
char szLocalBuff[256];
|
|
CBofString sCurrSDev(szLocalBuff, 256);
|
|
|
|
if (CBagPDA::isMoviePlaying() && CBagMasterWin::getActiveCursor() == 6) {
|
|
return;
|
|
}
|
|
|
|
sCurrSDev = CBagel::getBagApp()->getMasterWnd()->getCurrentStorageDev()->getName();
|
|
|
|
*_xCursorLocation = *xPoint;
|
|
CBofPoint xCursorLocation = devPtToViewPort(*xPoint);
|
|
|
|
bool bUseWield = true;
|
|
CBagObject *pObj = getObject(xCursorLocation, true);
|
|
if (pObj != nullptr) {
|
|
bUseWield = false;
|
|
|
|
g_noMenuFl = false;
|
|
if (pObj->isActive()) {
|
|
pObj->onLButtonUp(nFlags, xPoint, vpInfo);
|
|
|
|
if (g_noMenuFl) {
|
|
g_noMenuFl = false;
|
|
bUseWield = true;
|
|
}
|
|
setLActiveObject(pObj);
|
|
}
|
|
_bHandledUpEvent = true;
|
|
}
|
|
|
|
if (bUseWield) {
|
|
|
|
CBagel *pApp = CBagel::getBagApp();
|
|
if (pApp != nullptr) {
|
|
CBagPanWindow *pWin = (CBagPanWindow *)pApp->getMasterWnd();
|
|
if (pWin != nullptr) {
|
|
if (pWin->_pWieldBmp != nullptr) {
|
|
pObj = pWin->_pWieldBmp->getCurrObj();
|
|
if ((pObj != nullptr) && pObj->isActive()) {
|
|
pObj->onLButtonUp(nFlags, xPoint, vpInfo);
|
|
setLActiveObject(pObj);
|
|
_bHandledUpEvent = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
setLActivity(kMouseNONE);
|
|
|
|
if (g_bAAOk && (sCurrSDev == (CBagel::getBagApp()->getMasterWnd()->getCurrentStorageDev()->getName()))) {
|
|
attachActiveObjects();
|
|
}
|
|
|
|
g_bAAOk = true;
|
|
}
|
|
|
|
|
|
ErrorCode CBagStorageDev::loadFile(const CBofString &sWldName) {
|
|
char szLocalBuff[256];
|
|
CBofString sWldFileName(szLocalBuff, 256);
|
|
|
|
sWldFileName = sWldName;
|
|
|
|
fixPathName(sWldFileName);
|
|
|
|
// Force buffer to be big enough so that the entire script
|
|
// is pre-loaded
|
|
int nLength = fileLength(sWldFileName);
|
|
if (nLength <= 0)
|
|
error("Unable to open or read %s", sWldFileName.getBuffer());
|
|
|
|
char *pBuf = (char *)bofAlloc(nLength);
|
|
CBagIfstream fpInput(pBuf, nLength);
|
|
|
|
CBofFile cFile;
|
|
cFile.open(sWldFileName);
|
|
cFile.read(pBuf, nLength);
|
|
cFile.close();
|
|
|
|
CBagStorageDev::loadFileFromStream(fpInput, sWldFileName);
|
|
|
|
bofFree(pBuf);
|
|
|
|
// Add everything to the window
|
|
return ERR_NONE;
|
|
}
|
|
|
|
|
|
ErrorCode CBagStorageDev::loadFileFromStream(CBagIfstream &fpInput, const CBofString &sWldName, bool bAttach) {
|
|
char szWorkStr[256];
|
|
char szStr[256];
|
|
szWorkStr[0] = 0;
|
|
szStr[0] = 0;
|
|
CBofString sWorkStr(szWorkStr, 256);
|
|
CBofString str(szStr, 256);
|
|
CBagExpression *pActiveExpr = nullptr;
|
|
CBofList<bool> bElseExprList;
|
|
|
|
releaseObjects();
|
|
|
|
setName(sWldName);
|
|
|
|
fpInput.eatWhite();
|
|
int ch = fpInput.getCh();
|
|
if (ch != SDEV_START_DELIM) {
|
|
char szWarningMsg[256];
|
|
CBofString s(szWarningMsg, 256);
|
|
|
|
s = "Warning: { expected: at start of storage device: ";
|
|
s += sWldName;
|
|
bofMessageBox(s.getBuffer(), "Warning");
|
|
|
|
fpInput.putBack();
|
|
}
|
|
|
|
fpInput.eatWhite();
|
|
|
|
while (/*fpInput &&*/ !fpInput.eof() && !(fpInput.peek() == SDEV_END_DELIM)) {
|
|
bool bOperSet = false; // Set if an operator was found
|
|
bool bHoldActivation = false; // Set if the object should be held
|
|
bool bRunActivation = true; // Set if the object should be run instantly on attach
|
|
|
|
// Get Operator SET or HOLD or RUN; on none RUN is default
|
|
getAlphaNumFromStream(fpInput, sWorkStr);
|
|
|
|
if (sWorkStr.isEmpty()) {
|
|
parseAlertBox(fpInput, "Error in line No Operator:", __FILE__, __LINE__);
|
|
|
|
bOperSet = true;
|
|
}
|
|
|
|
if (!sWorkStr.find("SET")) {
|
|
bRunActivation = false;
|
|
bOperSet = true;
|
|
} else if (!sWorkStr.find("HOLD")) {
|
|
bHoldActivation = true;
|
|
bOperSet = true;
|
|
} else if (!sWorkStr.find("RUN")) {
|
|
bOperSet = true;
|
|
}
|
|
|
|
fpInput.eatWhite();
|
|
|
|
if (bOperSet) {
|
|
// If we are not doing the default RUN get next argument
|
|
getAlphaNumFromStream(fpInput, sWorkStr);
|
|
}
|
|
|
|
if (sWorkStr.isEmpty()) {
|
|
parseAlertBox(fpInput, "Error in line:", __FILE__, __LINE__);
|
|
}
|
|
|
|
fpInput.eatWhite();
|
|
|
|
CBagObject *pObj = nullptr;
|
|
|
|
if (!sWorkStr.find("BKG")) {
|
|
setInfo(fpInput);
|
|
if (bAttach && attach()) {
|
|
assert(false);
|
|
}
|
|
|
|
} else if (!sWorkStr.find("DISKID")) {
|
|
fpInput.eatWhite();
|
|
ch = (char)fpInput.getCh();
|
|
if (ch == '=') {
|
|
getAlphaNumFromStream(fpInput, str);
|
|
fpInput.eatWhite();
|
|
_nDiskID = (uint16)atoi(str);
|
|
if (fpInput.peek() == ';') {
|
|
fpInput.getCh();
|
|
}
|
|
}
|
|
} else if (!sWorkStr.find("HELP")) {
|
|
fpInput.eatWhite();
|
|
ch = (char)fpInput.getCh();
|
|
if (ch == '=') {
|
|
getAlphaNumFromStream(fpInput, str);
|
|
fpInput.eatWhite();
|
|
|
|
setHelpFilename(str);
|
|
|
|
if (fpInput.peek() == ';') {
|
|
fpInput.getCh();
|
|
}
|
|
}
|
|
} else if (!sWorkStr.find("ENDIF")) {
|
|
if (bElseExprList.isEmpty()) {
|
|
parseAlertBox(fpInput, "Error: ENDIF without IF", __FILE__, __LINE__);
|
|
} else {
|
|
bElseExprList.removeHead();
|
|
}
|
|
if (pActiveExpr) {
|
|
pActiveExpr = pActiveExpr->getPrevExpression();
|
|
} else {
|
|
CBofString str2("Unexpected ENDIF:");
|
|
str2 += sWldName;
|
|
parseAlertBox(fpInput, str2.getBuffer(), __FILE__, __LINE__);
|
|
}
|
|
} else if (!sWorkStr.find("IF")) {
|
|
// Added a bPrevNeg to keep track of nested else-if's
|
|
bool bPrevNeg = false;
|
|
if (bElseExprList.getHead())
|
|
bPrevNeg = bElseExprList.getHead()->getNodeItem();
|
|
|
|
bElseExprList.addToHead((bool) false);
|
|
|
|
// Added a bPrevNeg to keep track of nested else-if's
|
|
CBagExpression *pExp = new CBagExpression(pActiveExpr, bPrevNeg);
|
|
|
|
pExp->setInfo(fpInput);
|
|
if (!_pExpressionList)
|
|
_pExpressionList = new CBofList<CBagExpression * >;
|
|
|
|
_pExpressionList->addToTail(pExp);
|
|
pActiveExpr = pExp;
|
|
} else if (!sWorkStr.find("ELSE")) {
|
|
if (bElseExprList.isEmpty()) {
|
|
parseAlertBox(fpInput, "Error: ELSE without IF", __FILE__, __LINE__);
|
|
} else {
|
|
bElseExprList.removeHead();
|
|
bElseExprList.addToHead((bool) true);
|
|
}
|
|
} else if (!sWorkStr.find("BMP")) {
|
|
getStringFromStream(fpInput, sWorkStr, "=", true);
|
|
pObj = onNewSpriteObject(sWorkStr);
|
|
} else if (!sWorkStr.find("SPR")) {
|
|
getStringFromStream(fpInput, sWorkStr, "=", true);
|
|
pObj = onNewSpriteObject(sWorkStr);
|
|
} else if (!sWorkStr.find("LNK")) {
|
|
getStringFromStream(fpInput, sWorkStr, "=", true);
|
|
pObj = onNewLinkObject(sWorkStr);
|
|
|
|
} else if (!sWorkStr.find("RPO")) {
|
|
// Allow residue printing objects
|
|
getStringFromStream(fpInput, sWorkStr, "=", true);
|
|
pObj = onNewRPObject(sWorkStr);
|
|
|
|
} else if (!sWorkStr.find("EDO")) {
|
|
getStringFromStream(fpInput, sWorkStr, "=", true);
|
|
pObj = onNewEDObject(sWorkStr);
|
|
|
|
} else if (!sWorkStr.find("DOS")) {
|
|
getStringFromStream(fpInput, sWorkStr, "=", true);
|
|
pObj = onNewDosObject(sWorkStr);
|
|
} else if (!sWorkStr.find("SND")) {
|
|
getStringFromStream(fpInput, sWorkStr, "=", true);
|
|
pObj = onNewSoundObject(sWorkStr);
|
|
} else if (!sWorkStr.find("BUT")) {
|
|
getStringFromStream(fpInput, sWorkStr, "=", true);
|
|
pObj = onNewButtonObject(sWorkStr);
|
|
} else if (!sWorkStr.find("CHR")) {
|
|
getStringFromStream(fpInput, sWorkStr, "=", true);
|
|
pObj = onNewCharacterObject(sWorkStr);
|
|
} else if (!sWorkStr.find("TNG")) {
|
|
getStringFromStream(fpInput, sWorkStr, "=", true);
|
|
pObj = onNewThingObject(sWorkStr);
|
|
} else if (!sWorkStr.find("ARE")) {
|
|
getStringFromStream(fpInput, sWorkStr, "=", true);
|
|
pObj = onNewAreaObject(sWorkStr);
|
|
} else if (!sWorkStr.find("VAR")) {
|
|
getStringFromStream(fpInput, sWorkStr, "=", true);
|
|
pObj = onNewVariableObject(sWorkStr);
|
|
} else if (!sWorkStr.find("TXT")) {
|
|
getStringFromStream(fpInput, sWorkStr, "=", true);
|
|
pObj = onNewTextObject(sWorkStr);
|
|
} else if (!sWorkStr.find("MOVIE")) {
|
|
getStringFromStream(fpInput, sWorkStr, "=", true);
|
|
pObj = onNewMovieObject(sWorkStr);
|
|
} else if (!sWorkStr.find("COMMAND")) {
|
|
getStringFromStream(fpInput, sWorkStr, "=", true);
|
|
pObj = onNewCommandObject(sWorkStr);
|
|
} else if (!sWorkStr.find("EXPR")) {
|
|
getStringFromStream(fpInput, sWorkStr, "=", true);
|
|
pObj = onNewExpressionObject(sWorkStr);
|
|
} else if (!sWorkStr.find("REM") || !sWorkStr.find("//")) {
|
|
char s[256];
|
|
fpInput.getCh(s, 256);
|
|
} else {
|
|
pObj = onNewUserObject(sWorkStr);
|
|
}
|
|
|
|
if (pObj != nullptr) {
|
|
assert(CBofObject::isValidObject(pObj));
|
|
|
|
if (!bElseExprList.isEmpty() && bElseExprList[0]) {
|
|
pObj->setNegative();
|
|
} else if (pActiveExpr && pActiveExpr->isNegative()) {
|
|
// If there is an active expression that is negative
|
|
// i.e if NOT( blah blah blah)
|
|
pObj->setNegative();
|
|
}
|
|
|
|
// Determine if the object is an active object in this world
|
|
if (!bHoldActivation) {
|
|
pObj->setLocal();
|
|
if (!pActiveExpr || pActiveExpr->evaluate(pObj->isNegative())) {
|
|
pObj->setActive();
|
|
}
|
|
}
|
|
if (bRunActivation) {
|
|
pObj->setImmediateRun();
|
|
}
|
|
|
|
pObj->setInfo(fpInput);
|
|
pObj->setExpression(pActiveExpr);
|
|
|
|
addObject(pObj);
|
|
}
|
|
|
|
fpInput.eatWhite();
|
|
|
|
} // While not eof
|
|
|
|
if (fpInput.peek() == SDEV_END_DELIM)
|
|
fpInput.getCh();
|
|
|
|
fpInput.eatWhite();
|
|
|
|
if (pActiveExpr) {
|
|
CBofString str2("Mismatch in IF/ENDIF:");
|
|
str2 += sWldName;
|
|
parseAlertBox(fpInput, str2.getBuffer(), __FILE__, __LINE__);
|
|
|
|
return ERR_UNKNOWN;
|
|
}
|
|
|
|
if (bAttach)
|
|
return attachActiveObjects();
|
|
|
|
// Add everything to the window
|
|
return ERR_NONE;
|
|
}
|
|
|
|
|
|
int CBagStorageDev::getObjectCount() {
|
|
if (_pObjectList != nullptr) {
|
|
return _pObjectList->getCount();
|
|
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
CBagObject *CBagStorageDev::getObjectByPos(int nIndex) {
|
|
assert(_pObjectList != nullptr);
|
|
assert((nIndex >= 0) && (nIndex < _pObjectList->getCount()));
|
|
|
|
return _pObjectList->getNodeItem(nIndex);
|
|
}
|
|
|
|
|
|
CBagObject *CBagStorageDev::getObject(int nRefId, bool bActiveOnly) {
|
|
assert(_pObjectList != nullptr);
|
|
|
|
int nListLen = _pObjectList->getCount();
|
|
|
|
for (int i = 0; i < nListLen; ++i) {
|
|
CBagObject *pObj = getObjectByPos(i);
|
|
|
|
if ((pObj->getRefId() == nRefId) && (!bActiveOnly || (pObj->isActive() && pObj->isAttached())))
|
|
return pObj;
|
|
}
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
|
|
CBagObject *CBagStorageDev::getObject(const CBofString &sName, bool bActiveOnly) {
|
|
assert(_pObjectList != nullptr);
|
|
|
|
CBagObject *pObjFound = nullptr;
|
|
CBofListNode<CBagObject *> *pNode = _pObjectList->getHead();
|
|
while (pNode != nullptr) {
|
|
CBagObject *pObj = pNode->getNodeItem();
|
|
|
|
if (pObj->getRefName().compare(sName) == 0) {
|
|
pObjFound = pObj;
|
|
break;
|
|
}
|
|
|
|
pNode = pNode->_pNext;
|
|
}
|
|
if (bActiveOnly && (pObjFound != nullptr) && !pObjFound->isActive())
|
|
pObjFound = nullptr;
|
|
|
|
return pObjFound;
|
|
}
|
|
|
|
|
|
CBagObject *CBagStorageDev::getObjectByType(const CBofString &sType, bool bActiveOnly) {
|
|
assert(_pObjectList != nullptr);
|
|
|
|
int nListLen = _pObjectList->getCount();
|
|
|
|
for (int i = 0; i < nListLen; ++i) {
|
|
CBagObject *pObj = getObjectByPos(i);
|
|
|
|
if (bActiveOnly) {
|
|
if (pObj->isActive() && !getStringTypeOfObject(pObj->getType()).find(sType))
|
|
return pObj;
|
|
} else if (!getStringTypeOfObject(pObj->getType()).find(sType))
|
|
return pObj;
|
|
}
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
|
|
CBagObject *CBagStorageDev::getObject(const CBofPoint &xPoint, bool bActiveOnly) {
|
|
int nCount = getObjectCount();
|
|
|
|
// Resolve in reverse order since the last painted is on top
|
|
if (nCount != 0) {
|
|
for (int i = nCount - 1; i >= 0; --i) {
|
|
CBagObject *pObj = getObjectByPos(i);
|
|
|
|
if (pObj->isInside(xPoint) && (!bActiveOnly || (pObj->isActive() && pObj->isAttached())))
|
|
return pObj;
|
|
}
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
|
|
ParseCodes CBagStorageDev::setInfo(CBagIfstream &fpInput) {
|
|
char szStr[256];
|
|
szStr[0] = 0;
|
|
CBofString str(szStr, 256);
|
|
|
|
fpInput.eatWhite();
|
|
|
|
char ch = (char)fpInput.getCh();
|
|
if (ch == '=') {
|
|
getAlphaNumFromStream(fpInput, str);
|
|
fpInput.eatWhite();
|
|
|
|
fixPathName(str);
|
|
|
|
_sBackgroundName = str;
|
|
|
|
if (fpInput.peek() == ';') {
|
|
fpInput.getCh();
|
|
}
|
|
}
|
|
|
|
return PARSING_DONE;
|
|
}
|
|
|
|
|
|
ErrorCode CBagStorageDev::attach() {
|
|
// Assume no error
|
|
ErrorCode errorCode = ERR_NONE;
|
|
|
|
_bFirstPaint = true;
|
|
|
|
if (!_sBackgroundName.isEmpty()) {
|
|
CBofBitmap *pBmp = new CBofBitmap(_sBackgroundName);
|
|
|
|
if (!pBmp->errorOccurred()) {
|
|
setBackground(pBmp);
|
|
errorCode = attachActiveObjects();
|
|
} else {
|
|
errorCode = ERR_FOPEN;
|
|
}
|
|
}
|
|
|
|
return errorCode;
|
|
}
|
|
|
|
|
|
ErrorCode CBagStorageDev::detach() {
|
|
// Must force people to not use a bad App's palette
|
|
CBofApp::getApp()->setPalette(nullptr);
|
|
setBackground(nullptr);
|
|
|
|
// Notify the main window that we need to redraw the background filter.
|
|
CBagStorageDevWnd *pMainWin = (CBagel::getBagApp()->getMasterWnd()->getCurrentStorageDev());
|
|
if (pMainWin != nullptr) {
|
|
((CBagPanWindow *)pMainWin)->setPreFilterPan(true);
|
|
}
|
|
|
|
return detachActiveObjects();
|
|
}
|
|
|
|
|
|
ErrorCode CBagStorageDev::close() {
|
|
return ERR_NONE;
|
|
}
|
|
|
|
|
|
CBagObject *CBagStorageDev::onNewSpriteObject(const CBofString &) {
|
|
return new CBagSpriteObject();
|
|
}
|
|
|
|
|
|
CBagObject *CBagStorageDev::onNewBitmapObject(const CBofString &) {
|
|
return new CBagBmpObject();
|
|
}
|
|
|
|
|
|
CBagObject *CBagStorageDev::onNewLinkObject(const CBofString &) {
|
|
return new CBagLinkObject();
|
|
}
|
|
|
|
CBagObject *CBagStorageDev::onNewRPObject(const CBofString &) {
|
|
return new CBagRPObject();
|
|
}
|
|
|
|
CBagObject *CBagStorageDev::onNewEDObject(const CBofString &) {
|
|
return new CBagEnergyDetectorObject();
|
|
}
|
|
|
|
CBagObject *CBagStorageDev::onNewDosObject(const CBofString &) {
|
|
return new CBagDossierObject();
|
|
}
|
|
|
|
CBagObject *CBagStorageDev::onNewTextObject(const CBofString &) {
|
|
return new CBagTextObject();
|
|
}
|
|
|
|
CBagObject *CBagStorageDev::onNewSoundObject(const CBofString &) {
|
|
return new CBagSoundObject();
|
|
}
|
|
|
|
|
|
CBagObject *CBagStorageDev::onNewButtonObject(const CBofString &) {
|
|
return new CBagButtonObject();
|
|
}
|
|
|
|
|
|
CBagObject *CBagStorageDev::onNewCharacterObject(const CBofString &) {
|
|
return new CBagCharacterObject();
|
|
}
|
|
|
|
CBagObject *CBagStorageDev::onNewThingObject(const CBofString &) {
|
|
return new CBagThingObject();
|
|
}
|
|
|
|
CBagObject *CBagStorageDev::onNewMovieObject(const CBofString &) {
|
|
return new CBagMovieObject();
|
|
}
|
|
|
|
CBagObject *CBagStorageDev::onNewCommandObject(const CBofString &) {
|
|
return new CBagCommandObject();
|
|
}
|
|
|
|
|
|
CBagObject *CBagStorageDev::onNewAreaObject(const CBofString &) {
|
|
return new CBagAreaObject();
|
|
}
|
|
|
|
|
|
CBagObject *CBagStorageDev::onNewExpressionObject(const CBofString &) {
|
|
return new CBagExpressionObject();
|
|
}
|
|
|
|
|
|
CBagObject *CBagStorageDev::onNewVariableObject(const CBofString &) {
|
|
return new CBagVariableObject();
|
|
}
|
|
|
|
|
|
CBagObject *CBagStorageDev::onNewUserObject(const CBofString &sInit) {
|
|
char szLocalBuff[256];
|
|
CBofString s(szLocalBuff, 256);
|
|
|
|
s = sInit;
|
|
bofMessageBox(s.getBuffer(), "Could not find object type");
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
void CBagStorageDev::onSetFilter(bool (*filterFunction)(uint16 nFilterId, CBofBitmap *, CBofRect *)) {
|
|
_pBitmapFilter = filterFunction;
|
|
}
|
|
|
|
FilterFunction CBagStorageDev::getFilter() {
|
|
return _pBitmapFilter;
|
|
}
|
|
|
|
|
|
ErrorCode CBagStorageDev::preFilter(CBofBitmap *pBmp, CBofRect *pRect, CBofList<CBagObject *> *pList) {
|
|
if (pBmp != nullptr) {
|
|
|
|
// If we are not dirtying all the objects, then only fill up the viewport.
|
|
CBofRect viewPortRect(80, 10, 559, 369);
|
|
CBofRect *fillRect;
|
|
if (getDirtyAllObjects()) {
|
|
fillRect = pRect;
|
|
} else {
|
|
fillRect = &viewPortRect;
|
|
}
|
|
|
|
pBmp->fillRect(fillRect, 0);
|
|
}
|
|
|
|
// Let pda know that we've been prefiltered
|
|
setPreFiltered(true);
|
|
|
|
if (getDirtyAllObjects()) {
|
|
makeListDirty(_pObjectList);
|
|
makeListDirty(pList);
|
|
} else {
|
|
setDirtyAllObjects(true);
|
|
}
|
|
|
|
return ERR_NONE;
|
|
}
|
|
|
|
|
|
void CBagStorageDev::makeListDirty(CBofList<CBagObject *> *pList) {
|
|
if (pList) {
|
|
int nCount = pList->getCount();
|
|
if (nCount != 0) {
|
|
|
|
for (int i = 0; i < nCount; ++i) {
|
|
CBagObject *pObj = pList->getNodeItem(i);
|
|
pObj->setDirty(true);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* CBagStorageDevWnd -
|
|
*
|
|
*
|
|
*****************************************************************************/
|
|
|
|
CBagStorageDevWnd::CBagStorageDevWnd() : CBofWindow() {
|
|
setOnUpdate(true);
|
|
setCloseOnOpen(false);
|
|
_pWorkBmp = nullptr;
|
|
|
|
// Set a default help file for when there is not one specified
|
|
_sHelpFileName = "$SBARDIR\\GENERAL\\RULES\\DEFAULT.TXT";
|
|
fixPathName(_sHelpFileName);
|
|
|
|
_xSDevType = SDEV_WND;
|
|
}
|
|
|
|
|
|
CBagStorageDevWnd::~CBagStorageDevWnd() {
|
|
assert(isValidObject(this));
|
|
|
|
CBagStorageDevWnd::killWorkBmp();
|
|
}
|
|
|
|
|
|
ErrorCode CBagStorageDevWnd::attach() {
|
|
char szLocalBuff[256];
|
|
CBofString s(szLocalBuff, 256);
|
|
|
|
s = getName();
|
|
|
|
if (!getBackgroundName().isEmpty()) {
|
|
// This should actually be moved to sbarapp, but the load file will then
|
|
// need to be removed from the constructor.
|
|
//CBofApp::getApp()->setMainWindow(this);
|
|
|
|
// Associate this window with callbacks so that any public member function can
|
|
// be accessed by objects inserted into this class.
|
|
setAssociateWnd(this);
|
|
|
|
CBofBitmap *pBmp = new CBofBitmap(getBackgroundName());
|
|
|
|
if ((pBmp->height() <= 0) || (pBmp->width() <= 0)) {
|
|
reportError(ERR_FOPEN, "BarComputer Background Opened Failed");
|
|
} else {
|
|
|
|
setBackground(pBmp);
|
|
|
|
// Set the bagel crap
|
|
CBofPalette *pPalette = pBmp->getPalette();
|
|
CBofApp::getApp()->setPalette(pPalette);
|
|
CBofSprite::openLibrary(pPalette);
|
|
|
|
CBofRect r = pBmp->getRect();
|
|
|
|
if (r.width() && r.height()) {
|
|
create(s.getBuffer(), &r, CBagel::getBagApp()->getMasterWnd());
|
|
|
|
} else {
|
|
create(s.getBuffer(), nullptr, CBagel::getBagApp()->getMasterWnd());
|
|
}
|
|
|
|
show();
|
|
|
|
attachActiveObjects();
|
|
}
|
|
|
|
} else {
|
|
reportError(ERR_UNKNOWN, "No background for this storage device window");
|
|
}
|
|
|
|
setPreFilterPan(true);
|
|
g_lastWindow = this;
|
|
|
|
CBagStorageDev *pSDev = g_SDevManager->getStorageDevice("EVT_WLD");
|
|
|
|
if (pSDev != nullptr) {
|
|
// Have we allocated one yet ?
|
|
if (_pEvtSDev == nullptr) {
|
|
_pEvtSDev = (CBagEventSDev *)pSDev;
|
|
_pEvtSDev->setAssociateWnd(this);
|
|
if (!_pEvtSDev->isAttached())
|
|
_pEvtSDev->attach();
|
|
|
|
setTimer(EVAL_EXPR, 1000);
|
|
g_pauseTimerFl = false;
|
|
|
|
} else {
|
|
// We already allocated one
|
|
// We just need to re-associate the parent window and reset the timer
|
|
_pEvtSDev->setAssociateWnd(this);
|
|
|
|
setTimer(EVAL_EXPR, 1000);
|
|
g_pauseTimerFl = false;
|
|
}
|
|
}
|
|
|
|
return _errCode;
|
|
}
|
|
|
|
void CBagStorageDevWnd::onTimer(uint32 nEventID) {
|
|
assert(isValidObject(this));
|
|
static bool bAlready = false;
|
|
|
|
if (!g_pauseTimerFl) {
|
|
// Don't allow recursion
|
|
if (!bAlready) {
|
|
bAlready = true;
|
|
// Evaluate the event storage device IF MOVIE NOT PLAYING
|
|
if ((CBofApp::getApp()->getMainWindow())->isEnabled() && nEventID == EVAL_EXPR) {
|
|
if (_pEvtSDev != nullptr) {
|
|
_pEvtSDev->evaluateExpressions();
|
|
|
|
// If our turncount was updated, then execute the event world
|
|
// for the turncount dependent storage device.
|
|
if (CBagEventSDev::getEvalTurnEvents() == true) {
|
|
CBagEventSDev::setEvalTurnEvents(false);
|
|
CBagTurnEventSDev *pSDev = (CBagTurnEventSDev *) g_SDevManager->getStorageDevice("TURN_WLD");
|
|
if (pSDev != nullptr) {
|
|
// If unable to execute event world, try again next time through.
|
|
if (pSDev->evaluateExpressions() == ERR_UNKNOWN) {
|
|
CBagEventSDev::setEvalTurnEvents(true);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
g_waitOKFl = true;
|
|
}
|
|
bAlready = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
ErrorCode CBagStorageDevWnd::detach() {
|
|
detachActiveObjects();
|
|
|
|
CBofApp::getApp()->setPalette(nullptr);
|
|
|
|
setBackground(nullptr);
|
|
CBofSprite::closeLibrary();
|
|
CBagStorageDev::detach();
|
|
|
|
killTimer(EVAL_EXPR);
|
|
|
|
destroy();
|
|
|
|
return _errCode;
|
|
}
|
|
|
|
ErrorCode CBagStorageDevWnd::close() {
|
|
CBagel::getBagApp()->getMasterWnd()->setStorageDev(getPrevSDev(), false);
|
|
|
|
return _errCode;
|
|
}
|
|
|
|
|
|
ErrorCode CBagStorageDevWnd::setBackground(CBofBitmap *pBmp) {
|
|
if (pBmp) {
|
|
setBackdrop(pBmp);
|
|
setWorkBmp();
|
|
} else {
|
|
killBackdrop();
|
|
killWorkBmp();
|
|
}
|
|
return _errCode;
|
|
}
|
|
|
|
|
|
ErrorCode CBagStorageDevWnd::setWorkBmp() {
|
|
// Delete any previous work area
|
|
killWorkBmp();
|
|
|
|
CBofBitmap *pBmp = getBackground();
|
|
if (pBmp != nullptr) {
|
|
_pWorkBmp = new CBofBitmap(pBmp->width(), pBmp->height(), pBmp->getPalette());
|
|
pBmp->paint(_pWorkBmp);
|
|
}
|
|
|
|
return _errCode;
|
|
}
|
|
|
|
|
|
ErrorCode CBagStorageDevWnd::killWorkBmp() {
|
|
delete _pWorkBmp;
|
|
_pWorkBmp = nullptr;
|
|
|
|
return _errCode;
|
|
}
|
|
|
|
void CBagStorageDevWnd::onPaint(CBofRect *) {
|
|
assert(isValidObject(this));
|
|
|
|
paintScreen();
|
|
}
|
|
|
|
void CBagStorageDevWnd::onMainLoop() {
|
|
assert(isValidObject(this));
|
|
|
|
paintScreen();
|
|
|
|
g_lastWindow = this;
|
|
}
|
|
|
|
ErrorCode CBagStorageDevWnd::paintScreen(CBofRect *pRect) {
|
|
assert(isValidObject(this));
|
|
|
|
if (_pBackdrop != nullptr) {
|
|
onRender(_pBackdrop, pRect);
|
|
|
|
if (g_allowPaintFl) {
|
|
_pBackdrop->paint(this, pRect, pRect);
|
|
}
|
|
}
|
|
|
|
if (_bFirstPaint) {
|
|
_bFirstPaint = false;
|
|
attachActiveObjects();
|
|
}
|
|
|
|
return _errCode;
|
|
}
|
|
|
|
|
|
ErrorCode CBagStorageDevWnd::onRender(CBofBitmap *pBmp, CBofRect *pRect) {
|
|
assert(isValidObject(this));
|
|
assert(pBmp != nullptr);
|
|
|
|
if (preFilterPan()) {
|
|
preFilter(pBmp, pRect, nullptr);
|
|
setPreFilterPan(false);
|
|
|
|
if (_pWorkBmp != nullptr) {
|
|
_pWorkBmp->paint(pBmp, pRect, pRect);
|
|
}
|
|
}
|
|
|
|
paintStorageDevice(this, pBmp, pRect);
|
|
|
|
|
|
if (isFiltered()) {
|
|
uint16 nFilterId = getFilterId();
|
|
(*_pBitmapFilter)(nFilterId, pBmp, pRect);
|
|
}
|
|
|
|
return _errCode;
|
|
}
|
|
|
|
|
|
ErrorCode CBagStorageDevWnd::runModal(CBagObject *pObj) {
|
|
assert(pObj != nullptr);
|
|
|
|
if (pObj->isModal() && pObj->isActive()) {
|
|
|
|
EventLoop eventLoop;
|
|
CBofBitmap *pBmp = getBackdrop();
|
|
|
|
if (pBmp != nullptr) {
|
|
while (!g_engine->shouldQuit() && !pObj->isModalDone()) {
|
|
// Make sure we redraw each and every frame!
|
|
setPreFilterPan(true);
|
|
onRender(pBmp, nullptr);
|
|
if (g_allowPaintFl) {
|
|
pBmp->paint(this, 0, 0);
|
|
}
|
|
|
|
if (eventLoop.frame())
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
return _errCode;
|
|
}
|
|
|
|
|
|
|
|
ErrorCode CBagStorageDevWnd::paintObjects(CBofList<CBagObject *> * /*list*/, CBofBitmap * /*pBmp*/, CBofRect & /*viewRect*/, CBofList<CBofRect> * /*pUpdateArea*/, bool /*tempVar*/) {
|
|
return _errCode;
|
|
}
|
|
|
|
ErrorCode CBagStorageDevWnd::loadFile(const CBofString &sFile) {
|
|
char szWldFile[256];
|
|
szWldFile[0] = 0;
|
|
CBofString sWldFile(szWldFile, 256); // performance improvement
|
|
|
|
if (sFile.isEmpty())
|
|
sWldFile = "StoreDev.Wld";
|
|
else
|
|
sWldFile = sFile;
|
|
|
|
fixPathName(sWldFile);
|
|
|
|
// Force buffer to be big enough so that the entire script
|
|
// is pre-loaded
|
|
int nLength = fileLength(sWldFile);
|
|
if (nLength <= 0)
|
|
reportError(ERR_FOPEN, "Unable to open file %s", sWldFile.getBuffer());
|
|
else {
|
|
char *pBuf = (char *)bofAlloc(nLength);
|
|
CBagIfstream fpInput(pBuf, nLength);
|
|
|
|
CBofFile cFile;
|
|
cFile.open(sWldFile);
|
|
cFile.read(pBuf, nLength);
|
|
cFile.close();
|
|
|
|
CBagStorageDev::loadFileFromStream(fpInput, sWldFile);
|
|
|
|
// If the window.isCreated()
|
|
//
|
|
if (isCreated())
|
|
invalidateRect(nullptr);
|
|
|
|
bofFree(pBuf);
|
|
}
|
|
|
|
// Add everything to the window
|
|
|
|
return _errCode;
|
|
}
|
|
|
|
|
|
void CBagStorageDevWnd::onClose() {
|
|
CBofWindow::onClose();
|
|
// destruct the main window
|
|
destroyWindow();
|
|
}
|
|
|
|
void CBagStorageDevWnd::onMouseMove(uint32 n, CBofPoint *pPoint, void *) {
|
|
CBagStorageDev::onMouseMove(n, pPoint, getAssociateWnd());
|
|
|
|
if (CBagCursor::isSystemCursorVisible())
|
|
return;
|
|
|
|
CBagMasterWin::setActiveCursor(0);
|
|
|
|
// If a zelda movie is playing then just give 'em the wait cursor
|
|
// as we're not gonna allow them to do squat anyway.
|
|
if (CBagPDA::isMoviePlaying()) {
|
|
CBagMasterWin::setActiveCursor(6);
|
|
return;
|
|
}
|
|
|
|
if (getExitOnEdge() && (pPoint->x < getExitOnEdge()) && (pPoint->y < 360 + 10) && !(getPrevSDev().isEmpty())) {
|
|
CBagMasterWin::setActiveCursor(10);
|
|
|
|
} else {
|
|
// Added wield cursors
|
|
bool bWield = false;
|
|
if (CBagWield::getWieldCursor() >= 0 && !CBagCursor::isSystemCursorVisible()) {
|
|
CBagMasterWin::setActiveCursor(CBagWield::getWieldCursor());
|
|
bWield = true;
|
|
}
|
|
|
|
// Run through background object list and find if the cursor is over an object
|
|
CBofList<CBagObject *> *pList = getObjectList();
|
|
if (pList != nullptr) {
|
|
CBofPoint cCursorLocation = devPtToViewPort(*_xCursorLocation);
|
|
|
|
// Go through list backwards to find the 1st top-most object
|
|
CBofListNode<CBagObject *> *pNode = pList->getTail();
|
|
while (pNode != nullptr) {
|
|
CBagObject *pObj = pNode->getNodeItem();
|
|
|
|
// Change cursor as long as it's not a link to a closeup, or
|
|
// link to another Pan, or a text menu, or button.
|
|
//
|
|
if (pObj->isAttached() && pObj->isInside(cCursorLocation)) {
|
|
int nCursor = pObj->getOverCursor();
|
|
if (!bWield || (nCursor == 2 || nCursor == 5 || nCursor == 55 || pObj->getType() == TEXT_OBJ || pObj->getType() == BUTTON_OBJ)) {
|
|
CBagMasterWin::setActiveCursor(nCursor);
|
|
}
|
|
break;
|
|
}
|
|
|
|
pNode = pNode->_pPrev;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void CBagStorageDevWnd::onLButtonDown(uint32 nFlags, CBofPoint *xPoint, void *) {
|
|
// If asynch movie playing in PDA don't react to mouse down (8033)
|
|
// if it's not a wait cursor, then allow the user to access that hotspot.
|
|
if (CBagPDA::isMoviePlaying() && CBagMasterWin::getActiveCursor() == 6) {
|
|
return;
|
|
}
|
|
|
|
CBagStorageDev::onLButtonDown(nFlags, xPoint, getAssociateWnd());
|
|
CBofWindow::onLButtonDown(nFlags, xPoint);
|
|
}
|
|
|
|
void CBagStorageDevWnd::onLButtonUp(uint32 nFlags, CBofPoint *xPoint, void *) {
|
|
// If asynch movie playing in PDA don't react to mouse down (8033)
|
|
// if it's not a wait cursor, then allow the user to access that hotspot.
|
|
if (CBagPDA::isMoviePlaying() && CBagMasterWin::getActiveCursor() == 6) {
|
|
return;
|
|
}
|
|
|
|
// React to a mouse up, it will probably involve drawing a new window...
|
|
setPreFilterPan(true);
|
|
|
|
if (getExitOnEdge() && xPoint->x < getExitOnEdge() && !(getPrevSDev().isEmpty())) {
|
|
// Set the initial location as the last full panoramas position
|
|
close();
|
|
|
|
} else {
|
|
CBagStorageDev::onLButtonUp(nFlags, xPoint, getAssociateWnd());
|
|
CBofWindow::onLButtonUp(nFlags, xPoint);
|
|
}
|
|
}
|
|
|
|
void CBagStorageDevWnd::onKeyHit(uint32 lKey, uint32 nRepCount) {
|
|
CBofWindow::onKeyHit(lKey, nRepCount);
|
|
}
|
|
|
|
|
|
CBagStorageDevDlg::CBagStorageDevDlg() : CBofDialog() {
|
|
_xSDevType = SDEV_DLG;
|
|
|
|
// Set a default help file for when there is not one specified
|
|
//
|
|
_sHelpFileName = "$SBARDIR\\GENERAL\\RULES\\DEFAULT.TXT";
|
|
fixPathName(_sHelpFileName);
|
|
}
|
|
|
|
|
|
ErrorCode CBagStorageDevDlg::attach() {
|
|
assert(isValidObject(this));
|
|
|
|
CBagStorageDev::attach();
|
|
|
|
char szLocalBuff[256];
|
|
CBofString s(szLocalBuff, 256);
|
|
s = getName();
|
|
|
|
CBofBitmap *pBmp = getBackground();
|
|
CBofRect r;
|
|
if (pBmp)
|
|
r = pBmp->getRect();
|
|
|
|
if (r.width() && r.height()) {
|
|
create(s.getBuffer(), &r, CBagel::getBagApp()->getMasterWnd());
|
|
|
|
} else {
|
|
create(s.getBuffer(), nullptr, CBagel::getBagApp()->getMasterWnd());
|
|
}
|
|
|
|
setPreFilterPan(true);
|
|
|
|
CBofDialog::doModal();
|
|
|
|
destroy();
|
|
|
|
return _errCode;
|
|
}
|
|
|
|
|
|
ErrorCode CBagStorageDevDlg::close() {
|
|
releaseCapture();
|
|
|
|
CBofDialog::close();
|
|
|
|
return _errCode;
|
|
}
|
|
|
|
|
|
ErrorCode CBagStorageDevDlg::onRender(CBofBitmap *pBmp, CBofRect *pRect) {
|
|
assert(isValidObject(this));
|
|
assert(pBmp != nullptr);
|
|
|
|
paintStorageDevice(this, pBmp, pRect);
|
|
|
|
if (isFiltered()) {
|
|
uint16 nFilterId = getFilterId();
|
|
(*_pBitmapFilter)(nFilterId, pBmp, pRect);
|
|
}
|
|
|
|
return _errCode;
|
|
}
|
|
|
|
|
|
void CBagStorageDevDlg::onMainLoop() {
|
|
assert(isValidObject(this));
|
|
|
|
// The background of a storage device might be in motion, i.e. it
|
|
// might need updates, but since it is a background screen, it probably isn't that
|
|
// important, so we'll update it 4 times / second.
|
|
|
|
int nCurTime = getTimer();
|
|
gLastBackgroundUpdate = nCurTime;
|
|
if (g_lastWindow) {
|
|
g_lastWindow->setPreFilterPan(true);
|
|
}
|
|
|
|
paintScreen();
|
|
}
|
|
|
|
|
|
void CBagStorageDevDlg::onPaint(CBofRect *) {
|
|
assert(isValidObject(this));
|
|
|
|
paintScreen();
|
|
|
|
validateAnscestors();
|
|
|
|
CBagPanWindow::flushInputEvents();
|
|
}
|
|
|
|
|
|
ErrorCode CBagStorageDevDlg::paintScreen(CBofRect *pRect) {
|
|
assert(isValidObject(this));
|
|
|
|
if (_pBackdrop != nullptr) {
|
|
CBagStorageDevWnd *pWin = g_lastWindow;
|
|
|
|
if (pWin != nullptr) {
|
|
CBofBitmap *pBmp = pWin->getBackdrop();
|
|
|
|
if (pBmp != nullptr) {
|
|
// Don't redraw the background window unless we have to.
|
|
if (pWin->preFilterPan()) {
|
|
CBofBitmap *pWorkBmp = pWin->getWorkBmp();
|
|
if (pWorkBmp != nullptr) {
|
|
pWorkBmp->paint(pBmp, pRect, pRect);
|
|
}
|
|
|
|
pWin->onRender(pBmp, pRect);
|
|
}
|
|
|
|
onRender(_pBackdrop, pRect);
|
|
CBofRect wrect(getWindowRect());
|
|
_pBackdrop->paint(pBmp, &wrect, nullptr);
|
|
|
|
if (g_allowPaintFl) {
|
|
pBmp->paint(pWin, pRect, pRect);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Set the firstpaint flag and attach objects
|
|
// to allow for immediate run objects to run
|
|
if (_bFirstPaint) {
|
|
_bFirstPaint = false;
|
|
attachActiveObjects();
|
|
}
|
|
|
|
return _errCode;
|
|
}
|
|
|
|
|
|
ErrorCode CBagStorageDevDlg::paintObjects(CBofList<CBagObject *> * /*list*/, CBofBitmap * /*pBmp*/, CBofRect & /*viewRect*/, CBofList<CBofRect> * /*pUpdateArea*/, bool /*tempVar*/) {
|
|
return _errCode;
|
|
}
|
|
|
|
|
|
ErrorCode CBagStorageDevDlg::loadFile(const CBofString &sFile) {
|
|
char szWldFile[256];
|
|
szWldFile[0] = 0;
|
|
CBofString sWldFile(szWldFile, 256);
|
|
|
|
if (sFile.isEmpty())
|
|
sWldFile = "StoreDev.Wld";
|
|
else
|
|
sWldFile = sFile;
|
|
|
|
fixPathName(sWldFile);
|
|
|
|
// Force buffer to be big enough so that the entire script is pre-loaded
|
|
int nLength = fileLength(sWldFile);
|
|
if (nLength <= 0)
|
|
reportError(ERR_FOPEN, "Unable to open file %s", sWldFile.getBuffer());
|
|
else {
|
|
char *pBuf = (char *)bofAlloc(nLength);
|
|
CBagIfstream fpInput(pBuf, nLength);
|
|
|
|
CBofFile cFile;
|
|
cFile.open(sWldFile);
|
|
cFile.read(pBuf, nLength);
|
|
cFile.close();
|
|
|
|
CBagStorageDev::loadFileFromStream(fpInput, sWldFile);
|
|
|
|
bofFree(pBuf);
|
|
|
|
if (isCreated())
|
|
invalidateRect(nullptr);
|
|
}
|
|
// Add everything to the window
|
|
return _errCode;
|
|
}
|
|
|
|
ErrorCode CBagStorageDevDlg::create(const char *pszName, CBofRect *pRect, CBofWindow *pParent, uint32 nControlID) {
|
|
ErrorCode errorCode = CBofDialog::create(pszName, pRect, pParent, nControlID);
|
|
setCapture();
|
|
return errorCode;
|
|
}
|
|
|
|
|
|
void CBagStorageDevDlg::onClose() {
|
|
delete _pDlgBackground;
|
|
_pDlgBackground = nullptr;
|
|
|
|
// Since our sdevdlg doesn't have a detach active objects
|
|
// method, we will have to manually take all the existing objects and
|
|
// tell them to redraw themselves should they ever be called on in life
|
|
// to do as such.
|
|
int nCount = getObjectCount();
|
|
for (int i = 0; i < nCount; ++i) {
|
|
CBagObject *pObj = getObjectByPos(i);
|
|
if (pObj != nullptr) {
|
|
pObj->setDirty(true);
|
|
}
|
|
}
|
|
|
|
CBofDialog::onClose();
|
|
|
|
destroy(); // Destruct the main window
|
|
|
|
// Our dlog may have dirtied our backdrop, make sure it is redrawn.
|
|
if (g_lastWindow != nullptr) {
|
|
g_lastWindow->setPreFilterPan(true);
|
|
g_lastWindow->paintScreen(nullptr);
|
|
|
|
// This is fairly shameful, but for some reason, some
|
|
// updates don't work in the above paintscreen and must be updated the
|
|
// next time through. Don't know why, would love to find out, but
|
|
// running out of time.
|
|
g_lastWindow->setPreFilterPan(true);
|
|
}
|
|
}
|
|
|
|
void CBagStorageDevDlg::onMouseMove(uint32 n, CBofPoint *xPoint, void *) {
|
|
CBagStorageDev::onMouseMove(n, xPoint, getAssociateWnd());
|
|
}
|
|
|
|
void CBagStorageDevDlg::onLButtonDown(uint32 nFlags, CBofPoint *xPoint, void *) {
|
|
CBagStorageDev::onLButtonDown(nFlags, xPoint, getAssociateWnd());
|
|
CBofDialog::onLButtonDown(nFlags, xPoint);
|
|
}
|
|
|
|
void CBagStorageDevDlg::onLButtonUp(uint32 nFlags, CBofPoint *xPoint, void *) {
|
|
if (CBofDialog::getRect().ptInRect(*xPoint)) {
|
|
CBagStorageDev::onLButtonUp(nFlags, xPoint, getAssociateWnd());
|
|
CBofDialog::onLButtonUp(nFlags, xPoint);
|
|
} else {
|
|
close();
|
|
}
|
|
}
|
|
|
|
CBagStorageDevManager::CBagStorageDevManager() {
|
|
++nSDevMngrs;
|
|
assert(nSDevMngrs < 2);
|
|
}
|
|
|
|
CBagStorageDevManager::~CBagStorageDevManager() {
|
|
assert(isValidObject(this));
|
|
--nSDevMngrs;
|
|
assert(nSDevMngrs >= 0);
|
|
releaseStorageDevices();
|
|
_xStorageDeviceList.removeAll();
|
|
}
|
|
|
|
ErrorCode CBagStorageDevManager::registerStorageDev(CBagStorageDev *pSDev) {
|
|
assert(isValidObject(this));
|
|
|
|
_xStorageDeviceList.addToTail(pSDev);
|
|
|
|
return ERR_NONE;
|
|
}
|
|
|
|
ErrorCode CBagStorageDevManager::unregisterStorageDev(CBagStorageDev *pSDev) {
|
|
assert(isValidObject(this));
|
|
|
|
CBofListNode<CBagStorageDev *> *pList = _xStorageDeviceList.getHead();
|
|
while (pList != nullptr) {
|
|
if (pSDev == pList->getNodeItem()) {
|
|
_xStorageDeviceList.remove(pList);
|
|
break;
|
|
}
|
|
|
|
pList = pList->_pNext;
|
|
}
|
|
return ERR_NONE;
|
|
}
|
|
|
|
ErrorCode CBagStorageDevManager::releaseStorageDevices() {
|
|
assert(isValidObject(this));
|
|
|
|
while (_xStorageDeviceList.getCount()) {
|
|
CBagStorageDev *pSDev = _xStorageDeviceList[0];
|
|
|
|
// The CBagStorageDev destructor will remove it from the list
|
|
delete pSDev;
|
|
}
|
|
|
|
return ERR_NONE;
|
|
}
|
|
|
|
CBagStorageDev *CBagStorageDevManager::getStorageDeviceContaining(CBagObject *pObj) {
|
|
assert(isValidObject(this));
|
|
|
|
for (int i = 0; i < _xStorageDeviceList.getCount(); ++i) {
|
|
CBagStorageDev *pSDev = _xStorageDeviceList[i];
|
|
if (pSDev && pSDev->contains(pObj))
|
|
return _xStorageDeviceList[i];
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
CBagStorageDev *CBagStorageDevManager::getStorageDeviceContaining(const CBofString &sName) {
|
|
assert(isValidObject(this));
|
|
|
|
for (int i = 0; i < _xStorageDeviceList.getCount(); ++i) {
|
|
CBagStorageDev *pSDev = _xStorageDeviceList[i];
|
|
if (pSDev && pSDev->getObject(sName))
|
|
return _xStorageDeviceList[i];
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
CBagStorageDev *CBagStorageDevManager::getStorageDevice(const CBofString &sName) {
|
|
assert(isValidObject(this));
|
|
|
|
for (int i = 0; i < _xStorageDeviceList.getCount(); ++i) {
|
|
CBagStorageDev *pSDev = _xStorageDeviceList[i];
|
|
if (pSDev && (pSDev->getName().getLength() == sName.getLength()) &&
|
|
!pSDev->getName().find(sName))
|
|
return _xStorageDeviceList[i];
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
bool CBagStorageDevManager::moveObject(const CBofString &sDstName, const CBofString &sSrcName, const CBofString &sObjName) {
|
|
assert(isValidObject(this));
|
|
|
|
CBagStorageDev *pDstSDev = g_SDevManager->getStorageDevice(sDstName);
|
|
|
|
// Find the storage device
|
|
if (pDstSDev == nullptr)
|
|
return false;
|
|
|
|
CBagStorageDev *pSrcSDev = g_SDevManager->getStorageDevice(sSrcName);
|
|
if (pSrcSDev == nullptr)
|
|
return false;
|
|
|
|
// Find the storage device
|
|
if (pDstSDev->activateLocalObject(sObjName) != ERR_NONE)
|
|
return false;
|
|
|
|
if (pSrcSDev->deactivateLocalObject(sObjName) != ERR_NONE) {
|
|
pDstSDev->deactivateLocalObject(sObjName);
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool CBagStorageDevManager::addObject(const CBofString &sDstName, const CBofString &sObjName) {
|
|
assert(isValidObject(this));
|
|
|
|
CBagStorageDev *pDstSDev = g_SDevManager->getStorageDevice(sDstName);
|
|
|
|
// Find the storage device
|
|
if (pDstSDev == nullptr)
|
|
return false;
|
|
|
|
// Find the storage device
|
|
if (pDstSDev->activateLocalObject(sObjName) != ERR_NONE)
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
bool CBagStorageDevManager::removeObject(const CBofString &sSrcName, const CBofString &sObjName) {
|
|
assert(isValidObject(this));
|
|
|
|
CBagStorageDev *pSrcSDev = g_SDevManager->getStorageDevice(sSrcName);
|
|
|
|
// Find the storage device
|
|
if (pSrcSDev == nullptr)
|
|
return false;
|
|
|
|
// Find the storage device
|
|
if (pSrcSDev->deactivateLocalObject(sObjName) != ERR_NONE)
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
int CBagStorageDevManager::getObjectValue(const CBofString &sObject, const CBofString &sProperty) {
|
|
assert(isValidObject(this));
|
|
|
|
for (int i = 0; i < _xStorageDeviceList.getCount(); ++i) {
|
|
CBagStorageDev *pSDev = _xStorageDeviceList[i];
|
|
|
|
if (pSDev) {
|
|
CBagObject *pObj = pSDev->getObject(sObject);
|
|
if (pObj != nullptr)
|
|
return pObj->getProperty(sProperty);
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
// Set object will set a property to a numeric value or set the object to a string value -
|
|
// I am too lazy to write two funtions
|
|
void CBagStorageDevManager::setObjectValue(const CBofString &sObject, const CBofString &sProperty, int nValue/*=DO_NOT_USE_THIS_VALUE*/) {
|
|
assert(isValidObject(this));
|
|
|
|
// Make sure that all objects are set and not just one?
|
|
// Make sure that the first object is changed?
|
|
for (int i = 0; i < _xStorageDeviceList.getCount(); ++i) {
|
|
CBagStorageDev *pSDev = _xStorageDeviceList[i];
|
|
|
|
if (pSDev) {
|
|
CBagObject *pObj = pSDev->getObject(sObject);
|
|
if (pObj != nullptr) {
|
|
pObj->setProperty(sProperty, nValue);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void CBagStorageDevManager::saveObjList(StObj *pObjList, int nNumEntries) {
|
|
assert(isValidObject(this));
|
|
assert(pObjList != nullptr);
|
|
|
|
|
|
int k = 0;
|
|
int n = getNumStorageDevices();
|
|
for (int i = 0; i < n; i++) {
|
|
CBagStorageDev *pSDev = getStorageDevice(i);
|
|
if (pSDev != nullptr) {
|
|
|
|
int m = pSDev->getObjectCount();
|
|
for (int j = 0; j < m; j++) {
|
|
CBagObject *pObj = pSDev->getObjectByPos(j);
|
|
|
|
if (!pObj->getRefName().isEmpty()) {
|
|
assert(strlen(pObj->getRefName()) < MAX_OBJ_NAME);
|
|
Common::strlcpy((pObjList + k)->_szName, pObj->getRefName(), MAX_OBJ_NAME);
|
|
|
|
// We MUST have put something in here
|
|
assert((pObjList + k)->_szName[0] != '\0');
|
|
|
|
assert(strlen(pSDev->getName()) < MAX_SDEV_NAME);
|
|
Common::strlcpy((pObjList + k)->_szSDev, pSDev->getName(), MAX_SDEV_NAME);
|
|
|
|
// Save if this guy is waiting to play
|
|
(pObjList + k)->_nFlags = (uint16)(pObj->isMsgWaiting() ? mIsMsgWaiting : 0);
|
|
(pObjList + k)->_lState = pObj->getState();
|
|
(pObjList + k)->_lProperties = pObj->getProperties();
|
|
(pObjList + k)->_lType = pObj->getType();
|
|
(pObjList + k)->_bUsed = 1;
|
|
|
|
k++;
|
|
assert(k < nNumEntries);
|
|
|
|
// This is pretty dangerous, put up an error
|
|
if (k >= nNumEntries) {
|
|
bofMessageBox("saveObjList encountered too many objects", "Internal Error");
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void CBagStorageDevManager::restoreObjList(StObj *pObjList, int nNumEntries) {
|
|
assert(isValidObject(this));
|
|
assert(pObjList != nullptr);
|
|
|
|
// Restore the state of all objects
|
|
for (int i = 0; i < nNumEntries; i++) {
|
|
if ((pObjList + i)->_bUsed) {
|
|
CBagStorageDev *pSDev = getStorageDevice((pObjList + i)->_szSDev);
|
|
if (pSDev != nullptr) {
|
|
CBagObject *pObj = pSDev->getObject((pObjList + i)->_szName);
|
|
if (pObj != nullptr) {
|
|
pObj->setProperties((pObjList + i)->_lProperties);
|
|
pObj->setState((pObjList + i)->_lState);
|
|
pObj->setType((BagObjectType)(pObjList + i)->_lType);
|
|
|
|
pObj->setMsgWaiting(((pObjList + i)->_nFlags & mIsMsgWaiting) == mIsMsgWaiting);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
bool CBagStorageDev::isCIC() {
|
|
// Slightly more complicated then before... if we're in a CIC, then return true,
|
|
// however, if we're in the zoompda, then return the previous SDEV's cic value.
|
|
if (_bCIC != false) {
|
|
return true;
|
|
}
|
|
|
|
char szLocalBuff[256];
|
|
CBofString sStr(szLocalBuff, 256);
|
|
|
|
sStr = "BPDAZ_WLD";
|
|
if (_sName == sStr) {
|
|
return getCICStatus();
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
} // namespace SpaceBar
|
|
} // namespace Bagel
|