mirror of
https://github.com/scummvm/scummvm.git
synced 2026-06-20 05:45:29 +00:00
2073 lines
50 KiB
C++
2073 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/baglib/storage_dev_win.h"
|
|
#include "bagel/boflib/misc.h"
|
|
#include "bagel/boflib/error.h"
|
|
#include "bagel/boflib/gfx/sprite.h"
|
|
#include "bagel/boflib/event_loop.h"
|
|
#include "bagel/baglib/bagel.h"
|
|
#include "bagel/baglib/master_win.h"
|
|
#include "bagel/baglib/wield.h"
|
|
#include "bagel/baglib/menu_dlg.h"
|
|
#include "bagel/baglib/log_msg.h"
|
|
#include "bagel/baglib/event_sdev.h"
|
|
|
|
// Objects up the yang
|
|
#include "bagel/baglib/area_object.h"
|
|
#include "bagel/baglib/bmp_object.h"
|
|
#include "bagel/baglib/button_object.h"
|
|
#include "bagel/baglib/character_object.h"
|
|
#include "bagel/baglib/command_object.h"
|
|
#include "bagel/baglib/expression_object.h"
|
|
#include "bagel/baglib/link_object.h"
|
|
#include "bagel/baglib/movie_object.h"
|
|
#include "bagel/baglib/sound_object.h"
|
|
#include "bagel/baglib/sprite_object.h"
|
|
#include "bagel/baglib/text_object.h"
|
|
#include "bagel/baglib/variable_object.h"
|
|
#include "bagel/baglib/thing_object.h"
|
|
#include "bagel/baglib/rp_object.h"
|
|
#include "bagel/baglib/dossier_object.h"
|
|
#include "bagel/baglib/pan_window.h"
|
|
#include "bagel/bagel.h"
|
|
#include "bagel/boflib/file_functions.h"
|
|
|
|
namespace Bagel {
|
|
|
|
// Globals (hacks)
|
|
bool g_bAllowPaint = true;
|
|
bool g_bAAOk = true; // Prevent AttachActiveObjects() after a RUN LNK
|
|
bool g_bAllowAAO = true; // Prevent AttachActiveObjects() after a RUN LNK
|
|
CBagStorageDevWnd *g_pLastWindow = nullptr;
|
|
extern bool g_bPauseTimer;
|
|
extern bool g_bWaitOK;
|
|
|
|
// Statics
|
|
CBagEventSDev *CBagStorageDevWnd::m_pEvtSDev = nullptr; // Pointer to the EventSDev
|
|
CBofPoint *CBagStorageDev::m_xCursorLocation;
|
|
CBofRect *CBagStorageDev::gRepaintRect;
|
|
bool CBagStorageDev::m_bHidePDA = false;
|
|
bool CBagStorageDev::m_bHandledUpEvent = false;
|
|
|
|
// Dirty object variables
|
|
bool CBagStorageDev::m_bPanPreFiltered = false;
|
|
bool CBagStorageDev::m_bDirtyAllObjects = false;
|
|
bool CBagStorageDev::m_bPreFilter = false;
|
|
|
|
int CBagStorageDevManager::nSDevMngrs = 0;
|
|
|
|
// Local globals
|
|
static int gLastBackgroundUpdate = 0;
|
|
|
|
#define kCursWidth 55
|
|
|
|
void CBagStorageDev::initialize() {
|
|
g_bAllowPaint = true;
|
|
g_bAAOk = true;
|
|
g_bAllowAAO = true;
|
|
g_pLastWindow = nullptr;
|
|
|
|
m_xCursorLocation = new CBofPoint();
|
|
gRepaintRect = new CBofRect();
|
|
m_bHidePDA = false;
|
|
m_bHandledUpEvent = false;
|
|
|
|
m_bPanPreFiltered = false;
|
|
m_bDirtyAllObjects = false;
|
|
m_bPreFilter = false;
|
|
|
|
gLastBackgroundUpdate = 0;
|
|
}
|
|
|
|
void CBagStorageDev::shutdown() {
|
|
delete m_xCursorLocation;
|
|
delete gRepaintRect;
|
|
}
|
|
|
|
CBagStorageDev::CBagStorageDev() {
|
|
m_pLActiveObject = nullptr; // The last object selected on mouse down
|
|
|
|
m_pAssociateWnd = nullptr; // The associate window for attaching sounds
|
|
|
|
m_bForiegnList = false;
|
|
m_pObjectList = new CBofList<CBagObject *>;
|
|
m_pExpressionList = nullptr;
|
|
m_nDiskID = 1;
|
|
m_bCloseup = false;
|
|
m_bCIC = false;
|
|
|
|
// run object stuff
|
|
m_bFirstPaint = true;
|
|
|
|
m_nFloatPages = 0;
|
|
|
|
m_xSDevType = SDEV_UNDEF;
|
|
|
|
m_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);
|
|
|
|
SDEVMNGR->RegisterStorageDev(this);
|
|
}
|
|
|
|
CBagStorageDev::~CBagStorageDev() {
|
|
if (!m_bForiegnList) {
|
|
|
|
if (m_pObjectList != nullptr) {
|
|
ReleaseObjects(); // Delete all master sprite objects
|
|
delete m_pObjectList;
|
|
m_pObjectList = nullptr;
|
|
}
|
|
if (m_pExpressionList) {
|
|
while (m_pExpressionList->GetCount()) {
|
|
CBagExpression *pExp = m_pExpressionList->RemoveHead();
|
|
delete pExp;
|
|
}
|
|
delete m_pExpressionList;
|
|
m_pExpressionList = nullptr;
|
|
}
|
|
} // If the lists belong to this storage device
|
|
|
|
SDEVMNGR->UnRegisterStorageDev(this);
|
|
|
|
if (CBagStorageDevWnd::m_pEvtSDev == this) {
|
|
CBagStorageDevWnd::m_pEvtSDev = nullptr;
|
|
}
|
|
}
|
|
|
|
|
|
void CBagStorageDev::SetPosition(const CBofPoint &pos) {
|
|
CBofRect OrigRect = GetRect(); // Get the destination (screen) rect
|
|
|
|
m_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 errCode = ERR_NONE;
|
|
|
|
// can't use a null pointer
|
|
Assert(pObj != nullptr);
|
|
|
|
m_pObjectList->AddToTail(pObj);
|
|
|
|
return errCode;
|
|
}
|
|
|
|
|
|
ErrorCode CBagStorageDev::RemoveObject(CBagObject *pRObj) {
|
|
ErrorCode errCode = ERR_NONE;
|
|
|
|
if (!m_bForiegnList) {
|
|
int nCount = GetObjectCount();
|
|
for (int i = 0; i < nCount; ++i) {
|
|
if (pRObj == GetObjectByPos(i)) {
|
|
m_pObjectList->Remove(i);
|
|
return errCode;
|
|
}
|
|
}
|
|
}
|
|
|
|
return errCode;
|
|
}
|
|
|
|
|
|
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();
|
|
|
|
// Preform an update and arrange objects in the storage device
|
|
if (g_bAllowAAO) {
|
|
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 errCode = ERR_NONE;
|
|
|
|
if (pObj != nullptr) {
|
|
pObj->SetLocal(false);
|
|
if (pObj->IsActive()) {
|
|
pObj->SetActive(false);
|
|
pObj->Detach();
|
|
}
|
|
} else {
|
|
errCode = ERR_FFIND;
|
|
}
|
|
|
|
return errCode;
|
|
}
|
|
|
|
|
|
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 nPageNum = 0;
|
|
|
|
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...
|
|
|
|
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 errCode = ERR_NONE;
|
|
CBofPoint nArrangePos(0, 0); // Removed 5,5 padding
|
|
|
|
CBagLog::InitArrangePages();
|
|
|
|
int nCount = GetObjectCount();
|
|
if (nCount != 0) {
|
|
SetContainsModal(false);
|
|
|
|
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 (m_bFirstPaint == false) {
|
|
|
|
pObj->RunObject();
|
|
|
|
if (pObj->GetType() == LINKOBJ) {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if (pObj->IsModal())
|
|
SetContainsModal(true);
|
|
if (pObj->IsFloating()) {
|
|
nArrangePos = ArrangeFloater(nArrangePos, pObj);
|
|
}
|
|
} else if (pObj->IsAttached()) {
|
|
|
|
if (pObj->GetType() != SOUNDOBJ || !((CBagSoundObject *)pObj)->IsPlaying()) {
|
|
pObj->SetActive(false);
|
|
pObj->Detach();
|
|
}
|
|
}
|
|
} else
|
|
errCode = ERR_FFIND;
|
|
}
|
|
}
|
|
|
|
CBagLog::ArrangePages();
|
|
|
|
return errCode;
|
|
}
|
|
|
|
ErrorCode CBagStorageDev::DetachActiveObjects() {
|
|
ErrorCode errCode = 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
|
|
errCode = ERR_FFIND;
|
|
}
|
|
}
|
|
return errCode;
|
|
}
|
|
|
|
ErrorCode CBagStorageDev::LoadObjects() {
|
|
ErrorCode errCode = ERR_NONE;
|
|
return errCode;
|
|
}
|
|
|
|
ErrorCode CBagStorageDev::ReleaseObjects() {
|
|
ErrorCode errCode = ERR_NONE;
|
|
int nCount = GetObjectCount();
|
|
|
|
if (!m_bForiegnList) {
|
|
if (nCount) {
|
|
for (int i = 0; i < nCount; ++i) {
|
|
CBagObject *pObj = m_pObjectList->RemoveHead();
|
|
delete pObj;
|
|
}
|
|
}
|
|
|
|
m_pObjectList->RemoveAll();
|
|
}
|
|
return errCode;
|
|
}
|
|
|
|
|
|
void CBagStorageDev::SetObjectList(CBofList<CBagObject *> *pOList, CBofList<CBagExpression *> *pEList) {
|
|
delete m_pObjectList;
|
|
|
|
m_bForiegnList = true;
|
|
m_pObjectList = pOList;
|
|
m_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(&*m_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(*m_xCursorLocation)) {
|
|
pObj->OnMouseOver(0, *m_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) {
|
|
*m_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;
|
|
}
|
|
|
|
*m_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);
|
|
}
|
|
|
|
bool g_bNoMenu = 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();
|
|
|
|
*m_xCursorLocation = *xPoint;
|
|
CBofPoint xCursorLocation = DevPtToViewPort(*xPoint);
|
|
|
|
bool bUseWield = true;
|
|
CBagObject *pObj = GetObject(xCursorLocation, true);
|
|
if (pObj != nullptr) {
|
|
bUseWield = false;
|
|
|
|
g_bNoMenu = false;
|
|
if (pObj->IsActive()) {
|
|
pObj->OnLButtonUp(nFlags, xPoint, vpInfo);
|
|
|
|
if (g_bNoMenu) {
|
|
g_bNoMenu = false;
|
|
bUseWield = true;
|
|
}
|
|
SetLActiveObject(pObj);
|
|
}
|
|
m_bHandledUpEvent = true;
|
|
}
|
|
|
|
if (bUseWield) {
|
|
|
|
CBagel *pApp = CBagel::GetBagApp();
|
|
if (pApp != nullptr) {
|
|
CBagPanWindow *pWin = (CBagPanWindow *)pApp->GetMasterWnd();
|
|
if (pWin != nullptr) {
|
|
if (pWin->m_pWieldBmp != nullptr) {
|
|
pObj = pWin->m_pWieldBmp->GetCurrObj();
|
|
if ((pObj != nullptr) && pObj->IsActive()) {
|
|
pObj->OnLButtonUp(nFlags, xPoint, vpInfo);
|
|
SetLActiveObject(pObj);
|
|
m_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;
|
|
|
|
MACROREPLACE(sWldFileName);
|
|
|
|
// Force buffer to be big enough so that the entire script
|
|
// is pre-loaded
|
|
int nLength = FileLength(sWldFileName);
|
|
char *pBuf = (char *)BofAlloc(nLength);
|
|
if (pBuf != nullptr) {
|
|
bof_ifstream 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(bof_ifstream &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.Get();
|
|
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((char)ch);
|
|
}
|
|
|
|
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;
|
|
bHoldActivation = false;
|
|
bOperSet = true;
|
|
} else if (!sWorkStr.Find("HOLD")) {
|
|
bRunActivation = true;
|
|
bHoldActivation = true;
|
|
bOperSet = true;
|
|
} else if (!sWorkStr.Find("RUN")) {
|
|
bRunActivation = true;
|
|
bHoldActivation = false;
|
|
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.Get();
|
|
if (ch == '=') {
|
|
GetAlphaNumFromStream(fpInput, str);
|
|
fpInput.EatWhite();
|
|
m_nDiskID = (uint16)atoi(str);
|
|
if (fpInput.peek() == ';') {
|
|
fpInput.Get();
|
|
}
|
|
}
|
|
} else if (!sWorkStr.Find("HELP")) {
|
|
fpInput.EatWhite();
|
|
ch = (char)fpInput.Get();
|
|
if (ch == '=') {
|
|
GetAlphaNumFromStream(fpInput, str);
|
|
fpInput.EatWhite();
|
|
|
|
SetHelpFilename(str);
|
|
|
|
if (fpInput.peek() == ';') {
|
|
fpInput.Get();
|
|
}
|
|
}
|
|
} 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);
|
|
|
|
Assert(pExp != nullptr);
|
|
pExp->SetInfo(fpInput);
|
|
if (!m_pExpressionList)
|
|
m_pExpressionList = new CBofList<CBagExpression * >;
|
|
Assert(m_pExpressionList != nullptr);
|
|
m_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.Get(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.Get();
|
|
|
|
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 (m_pObjectList != nullptr) {
|
|
return m_pObjectList->GetCount();
|
|
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
CBagObject *CBagStorageDev::GetObjectByPos(int nIndex) {
|
|
Assert(m_pObjectList != nullptr);
|
|
Assert((nIndex >= 0) && (nIndex < m_pObjectList->GetCount()));
|
|
|
|
return m_pObjectList->GetNodeItem(nIndex);
|
|
}
|
|
|
|
|
|
CBagObject *CBagStorageDev::GetObject(int nRefId, bool bActiveOnly) {
|
|
Assert(m_pObjectList != nullptr);
|
|
|
|
int nListLen = m_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(m_pObjectList != nullptr);
|
|
|
|
CBagObject *pObjFound = nullptr;
|
|
CBofListNode<CBagObject *> *pNode = m_pObjectList->GetHead();
|
|
while (pNode != nullptr) {
|
|
CBagObject *pObj = pNode->GetNodeItem();
|
|
|
|
if (pObj->GetRefName().Compare(sName) == 0) {
|
|
pObjFound = pObj;
|
|
break;
|
|
}
|
|
|
|
pNode = pNode->m_pNext;
|
|
}
|
|
if (bActiveOnly && (pObjFound != nullptr) && !pObjFound->IsActive())
|
|
pObjFound = nullptr;
|
|
|
|
return pObjFound;
|
|
}
|
|
|
|
|
|
CBagObject *CBagStorageDev::GetObjectByType(const CBofString &sType, bool bActiveOnly) {
|
|
Assert(m_pObjectList != nullptr);
|
|
|
|
int nListLen = m_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;
|
|
}
|
|
|
|
|
|
void CBagStorageDev::HandleError(ErrorCode errCode) {
|
|
}
|
|
|
|
|
|
PARSE_CODES CBagStorageDev::SetInfo(bof_ifstream &fpInput) {
|
|
char szStr[256];
|
|
szStr[0] = 0;
|
|
CBofString str(szStr, 256);
|
|
|
|
fpInput.EatWhite();
|
|
|
|
char ch = (char)fpInput.Get();
|
|
if (ch == '=') {
|
|
GetAlphaNumFromStream(fpInput, str);
|
|
fpInput.EatWhite();
|
|
|
|
MACROREPLACE(str);
|
|
|
|
m_sBackgroundName = str;
|
|
|
|
if (fpInput.peek() == ';') {
|
|
fpInput.Get();
|
|
}
|
|
}
|
|
|
|
return PARSING_DONE;
|
|
}
|
|
|
|
|
|
ErrorCode CBagStorageDev::Attach() {
|
|
// Assume no error
|
|
ErrorCode errCode = ERR_NONE;
|
|
|
|
m_bFirstPaint = true;
|
|
|
|
if (!m_sBackgroundName.IsEmpty()) {
|
|
CBofBitmap *pBmp = new CBofBitmap(m_sBackgroundName);
|
|
|
|
if ((pBmp != nullptr) && !pBmp->ErrorOccurred()) {
|
|
SetBackground(pBmp);
|
|
errCode = AttachActiveObjects();
|
|
} else {
|
|
errCode = ERR_FOPEN;
|
|
}
|
|
}
|
|
|
|
return errCode;
|
|
}
|
|
|
|
|
|
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 &str) {
|
|
char szLocalBuff[256];
|
|
CBofString s(szLocalBuff, 256);
|
|
|
|
s = str;
|
|
|
|
BofMessageBox(s.GetBuffer(), "Could not find object type");
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
void CBagStorageDev::OnSetFilter(bool (*filterFunction)(const uint16 nFilterid, CBofBitmap *, CBofRect *)) {
|
|
m_pBitmapFilter = filterFunction;
|
|
}
|
|
|
|
FilterFunction CBagStorageDev::GetFilter() {
|
|
return m_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, RGB(0, 0, 0));
|
|
}
|
|
|
|
// Let pda know that we've been prefiltered
|
|
SetPreFiltered(true);
|
|
|
|
if (GetDirtyAllObjects()) {
|
|
MakeListDirty(m_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);
|
|
m_pWorkBmp = nullptr;
|
|
|
|
// Set a default help file for when there is not one specified
|
|
m_sHelpFileName = "$SBARDIR\\GENERAL\\RULES\\DEFAULT.TXT";
|
|
MACROREPLACE(m_sHelpFileName);
|
|
|
|
m_xSDevType = SDEV_WND;
|
|
}
|
|
|
|
|
|
CBagStorageDevWnd::~CBagStorageDevWnd() {
|
|
Assert(IsValidObject(this));
|
|
|
|
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 == nullptr) || (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_pLastWindow = this;
|
|
|
|
CBagStorageDev *pSDev = SDEVMNGR->GetStorageDevice("EVT_WLD");
|
|
|
|
if (pSDev != nullptr) {
|
|
// Have we allocated one yet ?
|
|
if (m_pEvtSDev == nullptr) {
|
|
m_pEvtSDev = (CBagEventSDev *)pSDev;
|
|
m_pEvtSDev->SetAssociateWnd(this);
|
|
if (!m_pEvtSDev->IsAttached())
|
|
m_pEvtSDev->Attach();
|
|
|
|
SetTimer(EVAL_EXPR, 1000);
|
|
g_bPauseTimer = false;
|
|
|
|
} else {
|
|
// We already allocated one
|
|
// We just need to re-associate the parent window and reset the timer
|
|
m_pEvtSDev->SetAssociateWnd(this);
|
|
|
|
SetTimer(EVAL_EXPR, 1000);
|
|
g_bPauseTimer = false;
|
|
}
|
|
}
|
|
|
|
return m_errCode;
|
|
}
|
|
|
|
void CBagStorageDevWnd::OnTimer(uint32 nEventID) {
|
|
Assert(IsValidObject(this));
|
|
static bool bAlready = false;
|
|
|
|
if (!g_bPauseTimer) {
|
|
// 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 (m_pEvtSDev != nullptr) {
|
|
m_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 *) SDEVMNGR->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_bWaitOK = true;
|
|
}
|
|
bAlready = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
ErrorCode CBagStorageDevWnd::Detach() {
|
|
DetachActiveObjects();
|
|
|
|
CBofApp::GetApp()->SetPalette(nullptr);
|
|
|
|
SetBackground(nullptr);
|
|
CBofSprite::CloseLibrary();
|
|
CBagStorageDev::Detach();
|
|
|
|
KillTimer(EVAL_EXPR);
|
|
|
|
Destroy();
|
|
|
|
return m_errCode;
|
|
}
|
|
|
|
ErrorCode CBagStorageDevWnd::Close() {
|
|
CBagel::GetBagApp()->GetMasterWnd()->SetStorageDev(GetPrevSDev(), false);
|
|
|
|
return m_errCode;
|
|
}
|
|
|
|
|
|
ErrorCode CBagStorageDevWnd::SetBackground(CBofBitmap *pBmp) {
|
|
if (pBmp) {
|
|
SetBackdrop(pBmp);
|
|
SetWorkBmp();
|
|
} else {
|
|
KillBackdrop();
|
|
KillWorkBmp();
|
|
}
|
|
return m_errCode;
|
|
}
|
|
|
|
|
|
ErrorCode CBagStorageDevWnd::SetWorkBmp() {
|
|
// Delete any previous work area
|
|
KillWorkBmp();
|
|
|
|
CBofBitmap *pBmp = GetBackground();
|
|
if (pBmp != nullptr) {
|
|
m_pWorkBmp = new CBofBitmap(pBmp->Width(), pBmp->Height(), pBmp->GetPalette());
|
|
pBmp->Paint(m_pWorkBmp);
|
|
}
|
|
|
|
return m_errCode;
|
|
}
|
|
|
|
|
|
ErrorCode CBagStorageDevWnd::KillWorkBmp() {
|
|
if (m_pWorkBmp != nullptr) {
|
|
delete m_pWorkBmp;
|
|
m_pWorkBmp = nullptr;
|
|
}
|
|
|
|
return m_errCode;
|
|
}
|
|
|
|
void CBagStorageDevWnd::OnPaint(CBofRect *) {
|
|
Assert(IsValidObject(this));
|
|
|
|
PaintScreen();
|
|
}
|
|
|
|
void CBagStorageDevWnd::OnMainLoop() {
|
|
Assert(IsValidObject(this));
|
|
|
|
PaintScreen();
|
|
|
|
g_pLastWindow = this;
|
|
}
|
|
|
|
ErrorCode CBagStorageDevWnd::PaintScreen(CBofRect *pRect) {
|
|
Assert(IsValidObject(this));
|
|
|
|
if (m_pBackdrop != nullptr) {
|
|
OnRender(m_pBackdrop, pRect);
|
|
|
|
if (g_bAllowPaint) {
|
|
m_pBackdrop->Paint(this, pRect, pRect);
|
|
}
|
|
}
|
|
|
|
if (m_bFirstPaint) {
|
|
m_bFirstPaint = false;
|
|
AttachActiveObjects();
|
|
}
|
|
|
|
return m_errCode;
|
|
}
|
|
|
|
|
|
ErrorCode CBagStorageDevWnd::OnRender(CBofBitmap *pBmp, CBofRect *pRect) {
|
|
Assert(IsValidObject(this));
|
|
Assert(pBmp != nullptr);
|
|
|
|
if (PreFilterPan()) {
|
|
PreFilter(pBmp, pRect, nullptr);
|
|
SetPreFilterPan(false);
|
|
|
|
if (m_pWorkBmp != nullptr) {
|
|
m_pWorkBmp->Paint(pBmp, pRect, pRect);
|
|
}
|
|
}
|
|
|
|
PaintStorageDevice(this, pBmp, pRect);
|
|
|
|
|
|
if (IsFiltered()) {
|
|
uint16 nFilterId = GetFilterId();
|
|
(*m_pBitmapFilter)(nFilterId, pBmp, pRect);
|
|
}
|
|
|
|
return m_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_bAllowPaint) {
|
|
pBmp->Paint(this, 0, 0);
|
|
}
|
|
|
|
if (eventLoop.frame())
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
return m_errCode;
|
|
}
|
|
|
|
|
|
|
|
ErrorCode CBagStorageDevWnd::PaintObjects(CBofList<CBagObject *> * /*list*/, CBofBitmap * /*pBmp*/, CBofRect & /*viewRect*/, CBofList<CBofRect> * /*pUpdateArea*/, bool /*tempVar*/) {
|
|
return m_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;
|
|
|
|
MACROREPLACE(sWldFile);
|
|
|
|
// Force buffer to be big enough so that the entire script
|
|
// is pre-loaded
|
|
int nLength = FileLength(sWldFile);
|
|
char *pBuf = (char *)BofAlloc(nLength);
|
|
if (pBuf != nullptr) {
|
|
bof_ifstream 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);
|
|
|
|
} else {
|
|
ReportError(ERR_MEMORY);
|
|
}
|
|
|
|
// Add everything to the window
|
|
|
|
return m_errCode;
|
|
}
|
|
|
|
|
|
void CBagStorageDevWnd::OnClose() {
|
|
CBofWindow::OnClose();
|
|
DestroyWindow(); // destruct the main window
|
|
}
|
|
|
|
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 thru background object list and find if the cursor is over an object
|
|
CBofList<CBagObject *> *pList = GetObjectList();
|
|
if (pList != nullptr) {
|
|
CBofPoint cCursorLocation = DevPtToViewPort(*m_xCursorLocation);
|
|
|
|
// Go thru 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() == TEXTOBJ || pObj->GetType() == BUTTONOBJ)) {
|
|
CBagMasterWin::SetActiveCursor(nCursor);
|
|
}
|
|
break;
|
|
}
|
|
|
|
pNode = pNode->m_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() {
|
|
m_xSDevType = SDEV_DLG;
|
|
|
|
// Set a default help file for when there is not one specified
|
|
//
|
|
m_sHelpFileName = "$SBARDIR\\GENERAL\\RULES\\DEFAULT.TXT";
|
|
MACROREPLACE(m_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 m_errCode;
|
|
}
|
|
|
|
|
|
ErrorCode CBagStorageDevDlg::Close() {
|
|
ReleaseCapture();
|
|
|
|
CBofDialog::Close();
|
|
|
|
return m_errCode;
|
|
}
|
|
|
|
|
|
ErrorCode CBagStorageDevDlg::OnRender(CBofBitmap *pBmp, CBofRect *pRect) {
|
|
Assert(IsValidObject(this));
|
|
Assert(pBmp != nullptr);
|
|
|
|
PaintStorageDevice(this, pBmp, pRect);
|
|
|
|
if (IsFiltered()) {
|
|
uint16 nFilterId = GetFilterId();
|
|
(*m_pBitmapFilter)(nFilterId, pBmp, pRect);
|
|
}
|
|
|
|
return m_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_pLastWindow) {
|
|
g_pLastWindow->SetPreFilterPan(true);
|
|
}
|
|
|
|
PaintScreen();
|
|
}
|
|
|
|
|
|
void CBagStorageDevDlg::OnPaint(CBofRect *) {
|
|
Assert(IsValidObject(this));
|
|
|
|
PaintScreen();
|
|
|
|
ValidateAnscestors();
|
|
|
|
CBagPanWindow::FlushInputEvents();
|
|
}
|
|
|
|
|
|
ErrorCode CBagStorageDevDlg::PaintScreen(CBofRect *pRect) {
|
|
Assert(IsValidObject(this));
|
|
|
|
if (m_pBackdrop != nullptr) {
|
|
CBagStorageDevWnd *pWin = g_pLastWindow;
|
|
|
|
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(m_pBackdrop, pRect);
|
|
CBofRect wrect(GetWindowRect());
|
|
m_pBackdrop->Paint(pBmp, &wrect, nullptr);
|
|
|
|
if (g_bAllowPaint) {
|
|
pBmp->Paint(pWin, pRect, pRect);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Set the firstpaint flag and attach objects
|
|
// to allow for immediate run objects to run
|
|
if (m_bFirstPaint) {
|
|
m_bFirstPaint = false;
|
|
AttachActiveObjects();
|
|
}
|
|
|
|
return m_errCode;
|
|
}
|
|
|
|
|
|
ErrorCode CBagStorageDevDlg::PaintObjects(CBofList<CBagObject *> * /*list*/, CBofBitmap * /*pBmp*/, CBofRect & /*viewRect*/, CBofList<CBofRect> * /*pUpdateArea*/, bool /*tempVar*/) {
|
|
return m_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;
|
|
|
|
MACROREPLACE(sWldFile);
|
|
|
|
// Force buffer to be big enough so that the entire script is pre-loaded
|
|
int nLength = FileLength(sWldFile);
|
|
char *pBuf = (char *)BofAlloc(nLength);
|
|
if (pBuf != nullptr) {
|
|
bof_ifstream 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 m_errCode;
|
|
}
|
|
|
|
ErrorCode CBagStorageDevDlg::Create(const char *pszName, int x, int y, int nWidth, int nHeight, CBofWindow *pParent, uint32 nControlID) {
|
|
ErrorCode rc = CBofDialog::Create(pszName, x, y, nWidth, nHeight, pParent, nControlID);
|
|
SetCapture();
|
|
return rc;
|
|
}
|
|
|
|
ErrorCode CBagStorageDevDlg::Create(const char *pszName, CBofRect *pRect, CBofWindow *pParent, uint32 nControlID) {
|
|
ErrorCode rc = CBofDialog::Create(pszName, pRect, pParent, nControlID);
|
|
SetCapture();
|
|
return rc;
|
|
}
|
|
|
|
|
|
void CBagStorageDevDlg::OnClose() {
|
|
if (_pDlgBackground != nullptr) {
|
|
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();
|
|
if (nCount != 0) {
|
|
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_pLastWindow != nullptr) {
|
|
g_pLastWindow->SetPreFilterPan(true);
|
|
g_pLastWindow->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_pLastWindow->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() {
|
|
Assert(++nSDevMngrs < 2);
|
|
}
|
|
|
|
CBagStorageDevManager::~CBagStorageDevManager() {
|
|
Assert(IsValidObject(this));
|
|
|
|
Assert(--nSDevMngrs >= 0);
|
|
ReleaseStorageDevices();
|
|
m_xStorageDeviceList.RemoveAll();
|
|
}
|
|
|
|
ErrorCode CBagStorageDevManager::RegisterStorageDev(CBagStorageDev *pSDev) {
|
|
Assert(IsValidObject(this));
|
|
|
|
m_xStorageDeviceList.AddToTail(pSDev);
|
|
|
|
return ERR_NONE;
|
|
}
|
|
|
|
ErrorCode CBagStorageDevManager::UnRegisterStorageDev(CBagStorageDev *pSDev) {
|
|
Assert(IsValidObject(this));
|
|
|
|
CBofListNode<CBagStorageDev *> *pList = m_xStorageDeviceList.GetHead();
|
|
while (pList != nullptr) {
|
|
if (pSDev == pList->GetNodeItem()) {
|
|
m_xStorageDeviceList.Remove(pList);
|
|
break;
|
|
}
|
|
|
|
pList = pList->m_pNext;
|
|
}
|
|
return ERR_NONE;
|
|
}
|
|
|
|
ErrorCode CBagStorageDevManager::ReleaseStorageDevices() {
|
|
Assert(IsValidObject(this));
|
|
|
|
while (m_xStorageDeviceList.GetCount()) {
|
|
CBagStorageDev *pSDev = m_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 < m_xStorageDeviceList.GetCount(); ++i) {
|
|
CBagStorageDev *pSDev = m_xStorageDeviceList[i];
|
|
if (pSDev && pSDev->Contains(pObj))
|
|
return m_xStorageDeviceList[i];
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
CBagStorageDev *CBagStorageDevManager::GetStorageDeviceContaining(const CBofString &sName) {
|
|
Assert(IsValidObject(this));
|
|
|
|
for (int i = 0; i < m_xStorageDeviceList.GetCount(); ++i) {
|
|
CBagStorageDev *pSDev = m_xStorageDeviceList[i];
|
|
if (pSDev && pSDev->GetObject(sName))
|
|
return m_xStorageDeviceList[i];
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
CBagStorageDev *CBagStorageDevManager::GetStorageDevice(const CBofString &sName) {
|
|
Assert(IsValidObject(this));
|
|
|
|
for (int i = 0; i < m_xStorageDeviceList.GetCount(); ++i) {
|
|
CBagStorageDev *pSDev = m_xStorageDeviceList[i];
|
|
if (pSDev && (pSDev->GetName().GetLength() == sName.GetLength()) &&
|
|
!pSDev->GetName().Find(sName))
|
|
return m_xStorageDeviceList[i];
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
bool CBagStorageDevManager::MoveObject(const CBofString &sDstName, const CBofString &sSrcName, const CBofString &sObjName) {
|
|
Assert(IsValidObject(this));
|
|
|
|
CBagStorageDev *pDstSDev = SDEVMNGR->GetStorageDevice(sDstName);
|
|
|
|
// Find the storage device
|
|
if (pDstSDev == nullptr)
|
|
return false;
|
|
|
|
CBagStorageDev *pSrcSDev = SDEVMNGR->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 = SDEVMNGR->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 = SDEVMNGR->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 < m_xStorageDeviceList.GetCount(); ++i) {
|
|
CBagStorageDev *pSDev = m_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 < m_xStorageDeviceList.GetCount(); ++i) {
|
|
CBagStorageDev *pSDev = m_xStorageDeviceList[i];
|
|
|
|
if (pSDev) {
|
|
CBagObject *pObj = pSDev->GetObject(sObject);
|
|
if (pObj != nullptr) {
|
|
pObj->SetProperty(sProperty, nValue);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void CBagStorageDevManager::SaveObjList(ST_OBJ *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);
|
|
strncpy((pObjList + k)->m_szName, pObj->GetRefName(), MAX_OBJ_NAME);
|
|
|
|
// We MUST have put something in here
|
|
Assert((pObjList + k)->m_szName[0] != '\0');
|
|
|
|
Assert(strlen(pSDev->GetName()) < MAX_SDEV_NAME);
|
|
strncpy((pObjList + k)->m_szSDev, pSDev->GetName(), MAX_SDEV_NAME);
|
|
|
|
// Save if this guy is waiting to play
|
|
(pObjList + k)->m_nFlags = (uint16)(pObj->IsMsgWaiting() ? mIsMsgWaiting : 0);
|
|
(pObjList + k)->m_lState = pObj->GetState();
|
|
(pObjList + k)->m_lProperties = pObj->GetProperties();
|
|
(pObjList + k)->m_lType = pObj->GetType();
|
|
(pObjList + k)->m_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(ST_OBJ *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)->m_bUsed) {
|
|
CBagStorageDev *pSDev = GetStorageDevice((pObjList + i)->m_szSDev);
|
|
if (pSDev != nullptr) {
|
|
CBagObject *pObj = pSDev->GetObject((pObjList + i)->m_szName);
|
|
if (pObj != nullptr) {
|
|
pObj->SetProperties((pObjList + i)->m_lProperties);
|
|
pObj->SetState((pObjList + i)->m_lState);
|
|
pObj->SetType((BAG_OBJECT_TYPE)(pObjList + i)->m_lType);
|
|
|
|
pObj->SetMsgWaiting(((pObjList + i)->m_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 (m_bCIC != false) {
|
|
return true;
|
|
}
|
|
|
|
char szLocalBuff[256];
|
|
CBofString sStr(szLocalBuff, 256);
|
|
|
|
sStr = "BPDAZ_WLD";
|
|
if (m_sName == sStr) {
|
|
return GetCICStatus();
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
} // namespace Bagel
|