Initial commit
This commit is contained in:
65
engines/bagel/spacebar/baglib/area_object.cpp
Normal file
65
engines/bagel/spacebar/baglib/area_object.cpp
Normal file
@@ -0,0 +1,65 @@
|
||||
/* 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/area_object.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
/* Private methods*/
|
||||
|
||||
CBofSize CBagAreaObject::getSize() const {
|
||||
return _xSize;
|
||||
}
|
||||
|
||||
/* Public methods*/
|
||||
|
||||
CBagAreaObject::CBagAreaObject() {
|
||||
_xObjType = AREA_OBJ;
|
||||
setVisible(false);
|
||||
CBagObject::setOverCursor(4);
|
||||
}
|
||||
|
||||
CBagAreaObject::~CBagAreaObject() {
|
||||
CBagAreaObject::detach();
|
||||
}
|
||||
|
||||
ErrorCode CBagAreaObject::attach() {
|
||||
return CBagObject::attach();
|
||||
}
|
||||
|
||||
ErrorCode CBagAreaObject::detach() {
|
||||
return CBagObject::detach();
|
||||
}
|
||||
|
||||
CBofRect CBagAreaObject::getRect() {
|
||||
const CBofPoint p = getPosition();
|
||||
const CBofSize s = getSize();
|
||||
CBofRect r = CBofRect(p, s);
|
||||
return r;
|
||||
}
|
||||
|
||||
void CBagAreaObject::setSize(const CBofSize &xSize) {
|
||||
_xSize = xSize;
|
||||
}
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
53
engines/bagel/spacebar/baglib/area_object.h
Normal file
53
engines/bagel/spacebar/baglib/area_object.h
Normal file
@@ -0,0 +1,53 @@
|
||||
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BAGEL_BAGLIB_AREA_OBJECT_H
|
||||
#define BAGEL_BAGLIB_AREA_OBJECT_H
|
||||
|
||||
#include "bagel/spacebar/baglib/object.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
/**
|
||||
* CBagAreaObject is an object that can be placed within the slide window.
|
||||
*/
|
||||
class CBagAreaObject : public CBagObject {
|
||||
private:
|
||||
CBofSize _xSize;
|
||||
CBofSize getSize() const;
|
||||
|
||||
public:
|
||||
CBagAreaObject();
|
||||
~CBagAreaObject();
|
||||
|
||||
ErrorCode attach() override;
|
||||
ErrorCode detach() override;
|
||||
|
||||
CBofRect getRect() override;
|
||||
void setSize(const CBofSize &xSize) override;
|
||||
};
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
|
||||
#endif
|
||||
258
engines/bagel/spacebar/baglib/bagel.cpp
Normal file
258
engines/bagel/spacebar/baglib/bagel.cpp
Normal file
@@ -0,0 +1,258 @@
|
||||
/* 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 "common/engine_data.h"
|
||||
#include "common/file.h"
|
||||
#include "engines/engine.h"
|
||||
|
||||
#include "bagel/spacebar/baglib/bagel.h"
|
||||
#include "bagel/boflib/sound.h"
|
||||
#include "bagel/spacebar/dialogs/next_cd_dialog.h"
|
||||
#include "bagel/spacebar/dialogs/opt_window.h"
|
||||
#include "bagel/spacebar/baglib/paint_table.h"
|
||||
#include "bagel/spacebar/baglib/master_win.h"
|
||||
#include "bagel/spacebar/boflib/debug.h"
|
||||
#include "bagel/boflib/file_functions.h"
|
||||
#include "bagel/boflib/log.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
// Initialize global variables.
|
||||
//
|
||||
CBofWindow *g_hackWindow;
|
||||
|
||||
CBagel::CBagel(const BagelReg *gameReg) {
|
||||
assert(gameReg != nullptr);
|
||||
|
||||
registerGame(gameReg);
|
||||
}
|
||||
|
||||
CBagel::~CBagel() {
|
||||
assert(isValidObject(this));
|
||||
|
||||
// Release options file
|
||||
release();
|
||||
|
||||
_szAppName[0] = '\0';
|
||||
_pMainWnd = nullptr;
|
||||
_gameReg = nullptr;
|
||||
}
|
||||
|
||||
void CBagel::registerGame(const BagelReg *gameReg) {
|
||||
assert(isValidObject(this));
|
||||
_gameReg = gameReg;
|
||||
|
||||
// Init statics
|
||||
g_hackWindow = nullptr;
|
||||
|
||||
// Use registration info to init this game object
|
||||
if (gameReg != nullptr) {
|
||||
// Keep application name
|
||||
setAppName(gameReg->_gameName);
|
||||
|
||||
// Load this game's .ini file
|
||||
if (gameReg->_optionFile != nullptr)
|
||||
loadOptionFile(gameReg->_optionFile);
|
||||
}
|
||||
}
|
||||
|
||||
ErrorCode CBagel::setOption(const char *section, const char *option, const char *stringValue) {
|
||||
assert(isValidObject(this));
|
||||
return writeSetting(section, option, stringValue);
|
||||
}
|
||||
|
||||
ErrorCode CBagel::setOption(const char *section, const char *option, int intValue) {
|
||||
assert(isValidObject(this));
|
||||
return writeSetting(section, option, intValue);
|
||||
}
|
||||
|
||||
ErrorCode CBagel::getOption(const char *section, const char *option, char *stringValue, const char *defaultValue, uint32 size) {
|
||||
assert(isValidObject(this));
|
||||
return readSetting(section, option, stringValue, defaultValue, size);
|
||||
}
|
||||
|
||||
ErrorCode CBagel::getOption(const char *section, const char *option, int *intValue, int defaultValue) {
|
||||
assert(isValidObject(this));
|
||||
return readSetting(section, option, intValue, defaultValue);
|
||||
}
|
||||
|
||||
ErrorCode CBagel::getOption(const char *section, const char *option, bool *boolValue, int defaultValue) {
|
||||
assert(isValidObject(this));
|
||||
return readSetting(section, option, boolValue, defaultValue);
|
||||
}
|
||||
|
||||
ErrorCode CBagel::initialize() {
|
||||
assert(isValidObject(this));
|
||||
|
||||
// Game must already be registered with registerGame()
|
||||
assert(_gameReg != nullptr);
|
||||
|
||||
CBofApp::initialize();
|
||||
|
||||
// Initialise engine data for the game
|
||||
Common::U32String errMsg;
|
||||
if (!Common::load_engine_data("bagel.dat", "", 1, 0, errMsg)) {
|
||||
GUIErrorMessage("Could not find bagel.dat data file");
|
||||
const Common::String msg(errMsg);
|
||||
bofMessageBox("Engine Data", msg.c_str());
|
||||
_errCode = ERR_FREAD;
|
||||
return _errCode;
|
||||
}
|
||||
|
||||
Common::File paintTable;
|
||||
if (!paintTable.open("paint_table.txt")) {
|
||||
bofMessageBox("Engine Data", "Invalid Paint Table");
|
||||
_errCode = ERR_FREAD;
|
||||
return _errCode;
|
||||
}
|
||||
PaintTable::initialize(paintTable);
|
||||
|
||||
getOption("UserOptions", "WrongCDRetries", &_numRetries, 20);
|
||||
if (_numRetries < 1) {
|
||||
_numRetries = 100;
|
||||
}
|
||||
|
||||
logInfo("Initializing BAGEL");
|
||||
|
||||
// Turn off System cursor
|
||||
CBofCursor::hide();
|
||||
|
||||
// Initialize local game paths
|
||||
initLocalFilePaths();
|
||||
|
||||
// Child class must instantiate the Main Window
|
||||
return _errCode;
|
||||
}
|
||||
|
||||
ErrorCode CBagel::runApp() {
|
||||
assert(isValidObject(this));
|
||||
|
||||
// The main game window must have been created by now
|
||||
assert(_pMainWnd != nullptr);
|
||||
|
||||
return CBofApp::runApp();
|
||||
}
|
||||
|
||||
ErrorCode CBagel::shutdown() {
|
||||
assert(isValidObject(this));
|
||||
|
||||
logInfo("Shutting down BAGEL");
|
||||
|
||||
// Just in case the child class forgot to delete the main window,
|
||||
// I'll do it.
|
||||
delete _pMainWnd;
|
||||
_pMainWnd = nullptr;
|
||||
|
||||
return CBofApp::shutdown();
|
||||
}
|
||||
|
||||
|
||||
ErrorCode CBagel::initLocalFilePaths() {
|
||||
assert(isValidObject(this));
|
||||
|
||||
// Check for Installed state of game
|
||||
getOption("Startup", "InstallCode", &_installCode, BAG_INSTALL_DEFAULT);
|
||||
|
||||
return _errCode;
|
||||
}
|
||||
|
||||
ErrorCode CBagel::verifyCDInDrive(int diskId, const char *waveFile) {
|
||||
assert(isValidObject(this));
|
||||
|
||||
if (_gameReg->_numberOfCDs > 0) {
|
||||
char szBuf[MAX_DIRPATH];
|
||||
|
||||
// Find the drive that this disk is in
|
||||
Common::sprintf_s(szBuf, "DISK%d", diskId);
|
||||
Common::sprintf_s(szBuf, "$SBARDIR%sDISK%d", PATH_DELIMETER, diskId);
|
||||
|
||||
CBofString cString(szBuf, MAX_DIRPATH);
|
||||
fixPathName(cString);
|
||||
|
||||
// If the disk is not in drive, then inform the user
|
||||
int i = 0;
|
||||
while (!shouldQuit() && !fileExists(cString.getBuffer())) {
|
||||
// display a dialog box that tells the user to put the CD back into
|
||||
// the drive, or Abort.
|
||||
logInfo(buildString("Unable to find game's DiskID as '%s'", cString.getBuffer()));
|
||||
|
||||
if (i++ > _numRetries) {
|
||||
reportError(ERR_FFIND, "Could not recover from missing CD");
|
||||
break;
|
||||
}
|
||||
|
||||
// Play the Zelda "Alias, you should insert disk 1 at this time."
|
||||
if (i == 1 && waveFile != nullptr) {
|
||||
BofPlaySound(waveFile, SOUND_WAVE | SOUND_ASYNCH);
|
||||
}
|
||||
|
||||
if (g_hackWindow == nullptr) {
|
||||
showNextCDDialog(_pMainWnd, diskId);
|
||||
} else {
|
||||
showNextCDDialog(g_hackWindow, diskId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return _errCode;
|
||||
}
|
||||
|
||||
void CBagel::showNextCDDialog(CBofWindow *parentWin, int diskId) {
|
||||
CBagNextCDDialog cNextCDDialog;
|
||||
|
||||
// Use specified bitmap as this dialog's image
|
||||
CBofPalette *pPal = nullptr;
|
||||
CBofBitmap *pBmp = nullptr;
|
||||
|
||||
switch (diskId) {
|
||||
|
||||
case 1:
|
||||
pBmp = SpaceBar::loadBitmap(buildSysDir("DISK1.BMP"), pPal);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
pBmp = SpaceBar::loadBitmap(buildSysDir("DISK2.BMP"), pPal);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
pBmp = SpaceBar::loadBitmap(buildSysDir("DISK3.BMP"), pPal);
|
||||
break;
|
||||
|
||||
// Shouldn't ever get here
|
||||
default:
|
||||
assert(false);
|
||||
break;
|
||||
}
|
||||
|
||||
cNextCDDialog.setBackdrop(pBmp);
|
||||
|
||||
const CBofRect cRect = cNextCDDialog.getBackdrop()->getRect();
|
||||
|
||||
// Create the dialog box
|
||||
cNextCDDialog.create("NextCD", cRect.left, cRect.top, cRect.width(), cRect.height(), parentWin);
|
||||
cNextCDDialog.center();
|
||||
|
||||
cNextCDDialog.doModal();
|
||||
}
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
202
engines/bagel/spacebar/baglib/bagel.h
Normal file
202
engines/bagel/spacebar/baglib/bagel.h
Normal file
@@ -0,0 +1,202 @@
|
||||
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BAGEL_BAGLIB_BAGEL_H
|
||||
#define BAGEL_BAGLIB_BAGEL_H
|
||||
|
||||
#include "bagel/spacebar/boflib/app.h"
|
||||
#include "bagel/spacebar/boflib/gui/window.h"
|
||||
#include "bagel/spacebar/boflib/options.h"
|
||||
#include "bagel/boflib/error.h"
|
||||
#include "bagel/spacebar/boflib/list.h"
|
||||
#include "bagel/boflib/string.h"
|
||||
#include "bagel/spacebar/boflib/vhash_table.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
// Set a default hash table size here.
|
||||
// Note: Best performance is achieved if this value is a prime number!
|
||||
//
|
||||
#define HASH_TABLE_SIZE 131
|
||||
#define MAX_APP_NAME 128
|
||||
#define PATH_DELIMETER "/"
|
||||
#define DISK_1 1
|
||||
|
||||
#define BAG_INSTALL_DEFAULT 0 /* play entire game from where it was executed */
|
||||
|
||||
#define HOMEDIR_TOKEN "$SBARDIR" /* Change this to $HOMEDIR */
|
||||
// THE CURRENT STORAGE DEVICE OF THE GAME
|
||||
#define CURRSDEV_TOKEN "$CURRENT_SDEV"
|
||||
#define PREVSDEV_TOKEN "$PREVIOUS_SDEV"
|
||||
|
||||
// Defines default chroma color to be palette index 1
|
||||
#define DEFAULT_CHROMA_COLOR 1
|
||||
|
||||
class CBagMasterWin;
|
||||
|
||||
/**
|
||||
* Initialization structure fot CBagel app
|
||||
*/
|
||||
struct BagelReg {
|
||||
const char *_gameName; // Game Name. Ex: "The Space Bar"
|
||||
const char *_gamePath; // Relative path for the CD: "\\SPACEBAR"
|
||||
const char *_optionFile; // This game's INI file name
|
||||
const char *_saveGameFile; // Name of save game Index file.
|
||||
uint32 _ramRequired; // Amount of free RAM needed to play game
|
||||
int32 _numberOfCDs; // # of CDs used by this game
|
||||
int _requiredDepth; // Required bits per pixel to play game
|
||||
int _requiredWidth; // Minimum screen width for game
|
||||
int _requiredHeight; // Minimum screen height for game
|
||||
};
|
||||
|
||||
class CBagel : public CBofOptions, public CBofApp {
|
||||
public:
|
||||
CBagel(const BagelReg *gameReg);
|
||||
~CBagel();
|
||||
|
||||
/**
|
||||
* Registers game information for this game object
|
||||
* @param gameReg Game registration info
|
||||
*/
|
||||
void registerGame(const BagelReg *gameReg);
|
||||
|
||||
// these functions must be provided by the child class
|
||||
//
|
||||
/**
|
||||
* Initializes BAGEL, checks system resources, etc...
|
||||
* @return Error return code
|
||||
*/
|
||||
ErrorCode initialize() override;
|
||||
|
||||
/**
|
||||
* Provides main message loop (MainEventLoop)
|
||||
* @return Error return Code.
|
||||
*/
|
||||
ErrorCode runApp() override;
|
||||
|
||||
/**
|
||||
* Performs cleanup and destruction of Bagel object
|
||||
* @return Error return Code.
|
||||
*/
|
||||
ErrorCode shutdown() override;
|
||||
|
||||
/**
|
||||
* Sets specified user option in associated .INI file
|
||||
* @param section .INI section to write to
|
||||
* @param option Option to add/update
|
||||
* @param stringValue New value of option
|
||||
* @return Error return code
|
||||
*/
|
||||
ErrorCode setOption(const char *section, const char *option, const char *stringValue);
|
||||
|
||||
/**
|
||||
* Sets specified user option in associated .INI file
|
||||
* @param section .INI section to write to
|
||||
* @param option Option to add/update
|
||||
* @param intValue New value of option
|
||||
* @return Error return code
|
||||
*/
|
||||
ErrorCode setOption(const char *section, const char *option, int intValue);
|
||||
|
||||
/**
|
||||
* Gets specified user option from associated .INI file
|
||||
* @param section .INI section to read from
|
||||
* @param option Option to retrieve
|
||||
* @param stringValue Buffer to hold value
|
||||
* @param defaultValue Default value if option not found
|
||||
* @param size Length of the stringValue buffer
|
||||
* @return Error return code
|
||||
*/
|
||||
ErrorCode getOption(const char *section, const char *option, char *stringValue, const char *defaultValue, uint32 size);
|
||||
|
||||
/**
|
||||
* Gets specified user option from associated .INI file
|
||||
* @param section .INI section to read from
|
||||
* @param option Option to retrieve
|
||||
* @param intValue Buffer to hold value
|
||||
* @param defaultValue Default value if option not found
|
||||
* @return Error return code
|
||||
*/
|
||||
ErrorCode getOption(const char *section, const char *option, int *intValue, int defaultValue);
|
||||
|
||||
/**
|
||||
* Gets specified user option from associated .INI file
|
||||
* @param section .INI section to read from
|
||||
* @param option Option to retrieve
|
||||
* @param boolValue Buffer to hold value
|
||||
* @param defaultValue Default value if option not found
|
||||
* @return Error return code
|
||||
*/
|
||||
ErrorCode getOption(const char *section, const char *option, bool *boolValue, int defaultValue);
|
||||
|
||||
void setAppName(const char *newAppName) override {
|
||||
Common::strcpy_s(_szAppName, newAppName);
|
||||
}
|
||||
|
||||
CBagMasterWin *getMasterWnd() const {
|
||||
return (CBagMasterWin *)_pMainWnd;
|
||||
}
|
||||
|
||||
static CBagel *getBagApp() {
|
||||
return (CBagel *)_pBofApp;
|
||||
}
|
||||
|
||||
int getChromaColor() {
|
||||
return DEFAULT_CHROMA_COLOR;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks to make sure the Game CD is in the drive
|
||||
* @param diskId Disk number
|
||||
* @param waveFile Filename
|
||||
* @return Error return code
|
||||
*/
|
||||
ErrorCode verifyCDInDrive(int diskId, const char *waveFile);
|
||||
|
||||
static void showNextCDDialog(CBofWindow *parentWin, int diskId);
|
||||
|
||||
static CBofVHashTable<CBofString, HASH_TABLE_SIZE> *getCacheFileList() {
|
||||
return _cacheFileList;
|
||||
}
|
||||
|
||||
protected:
|
||||
/**
|
||||
* initialize full path names to files stored on local disk
|
||||
* @return Error return code
|
||||
*/
|
||||
ErrorCode initLocalFilePaths();
|
||||
|
||||
// Data members
|
||||
const BagelReg *_gameReg = nullptr;
|
||||
|
||||
int _numRetries = 20;
|
||||
int _installCode = 0;
|
||||
|
||||
private:
|
||||
static CBofVHashTable<CBofString, HASH_TABLE_SIZE> *_cacheFileList;
|
||||
};
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
|
||||
#endif
|
||||
597
engines/bagel/spacebar/baglib/base_pda.cpp
Normal file
597
engines/bagel/spacebar/baglib/base_pda.cpp
Normal file
@@ -0,0 +1,597 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "bagel/spacebar/baglib/base_pda.h"
|
||||
#include "bagel/spacebar/baglib/event_sdev.h"
|
||||
#include "bagel/spacebar/dialogs/opt_window.h"
|
||||
#include "bagel/spacebar/baglib/log_msg.h"
|
||||
#include "bagel/spacebar/baglib/bagel.h"
|
||||
#include "bagel/spacebar/baglib/master_win.h"
|
||||
#include "bagel/spacebar/baglib/moo.h"
|
||||
#include "bagel/spacebar/baglib/storage_dev_win.h"
|
||||
#include "bagel/spacebar/baglib/wield.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
// Init static members
|
||||
PdaMode SBBasePda::_pdaMode;
|
||||
PdaPos SBBasePda::_pdaPos;
|
||||
PdaMode SBBasePda::_holdMode;
|
||||
|
||||
void SBBasePda::initialize() {
|
||||
_pdaMode = PDA_NO_MODE;
|
||||
_pdaPos = PDA_POS_UNINITIALIZED;
|
||||
_holdMode = PDA_NO_MODE;
|
||||
}
|
||||
|
||||
SBBasePda::SBBasePda(CBofWindow *parent, const CBofRect & /* xRect*/, bool activated) {
|
||||
_activated = activated;
|
||||
_activating = false;
|
||||
_moveDist = 13;
|
||||
_numMoves = 10;
|
||||
|
||||
_parent = parent;
|
||||
_mooWnd = nullptr;
|
||||
_invWnd = nullptr;
|
||||
_mapWnd = nullptr;
|
||||
_logWnd = nullptr;
|
||||
|
||||
_curDisplay = nullptr;
|
||||
_holdDisplay = nullptr;
|
||||
|
||||
// Other classes need to know if we're zoomed
|
||||
setZoomed(false);
|
||||
setDeactivate(false);
|
||||
|
||||
}
|
||||
|
||||
SBBasePda::~SBBasePda() {
|
||||
_invWnd = nullptr;
|
||||
_mapWnd = nullptr;
|
||||
_logWnd = nullptr;
|
||||
_mooWnd = nullptr;
|
||||
}
|
||||
|
||||
bool SBBasePda::hideCurDisplay() {
|
||||
synchronizePdaState();
|
||||
|
||||
if (_curDisplay) {
|
||||
// If we have an inventory window
|
||||
_curDisplay->setVisible(false);
|
||||
|
||||
// Hold this info.
|
||||
_holdDisplay = _curDisplay;
|
||||
_holdMode = _pdaMode;
|
||||
|
||||
_curDisplay = nullptr;
|
||||
_pdaMode = PDA_NO_MODE;
|
||||
setPdaState();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SBBasePda::restoreCurDisplay() {
|
||||
synchronizePdaState();
|
||||
|
||||
// If we saved a display
|
||||
if (_holdDisplay) {
|
||||
// Restore the display info.
|
||||
_curDisplay = _holdDisplay;
|
||||
_pdaMode = _holdMode;
|
||||
|
||||
_curDisplay->setVisible(true);
|
||||
setPdaState();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SBBasePda::hideMovie() {
|
||||
synchronizePdaState();
|
||||
|
||||
if (_mooWnd) {
|
||||
// if we have an inventory window
|
||||
_mooWnd->setVisible(false);
|
||||
_curDisplay = nullptr;
|
||||
_pdaMode = PDA_NO_MODE;
|
||||
setPdaState();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SBBasePda::showMovie() {
|
||||
synchronizePdaState();
|
||||
|
||||
// if we're already playing a movie, then return false
|
||||
if (_pdaMode == PDA_MOO_MODE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_mooWnd) {
|
||||
if (_curDisplay) {
|
||||
// Turn off the current display
|
||||
_curDisplay->setVisible(false);
|
||||
}
|
||||
|
||||
// Save the current PDA mode so we can return to it when done.
|
||||
((CBagMoo *)_mooWnd)->savePDAMode(_pdaMode);
|
||||
((CBagMoo *)_mooWnd)->savePDAPosition(_pdaPos);
|
||||
|
||||
// Turn on the inventory
|
||||
_mooWnd->setVisible(true);
|
||||
|
||||
// Set the current display = Inventory
|
||||
_curDisplay = _mooWnd;
|
||||
_pdaMode = PDA_MOO_MODE;
|
||||
setPdaState();
|
||||
|
||||
// Set default state of movie to don't deactivate PDA
|
||||
setDeactivate(false);
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void SBBasePda::stopMovie(bool bResetPDA) const {
|
||||
if (_mooWnd && _mooWnd == _curDisplay) {
|
||||
((CBagMoo *)_mooWnd)->stopMovie(bResetPDA);
|
||||
}
|
||||
}
|
||||
|
||||
bool SBBasePda::setMovie(CBofString &movieName) const {
|
||||
if (_mooWnd) {
|
||||
((CBagMoo *)_mooWnd)->setPDAMovie(movieName);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SBBasePda::hideInventory() {
|
||||
synchronizePdaState();
|
||||
|
||||
// if we have an inventory window
|
||||
if (_invWnd) {
|
||||
_invWnd->setVisible(false);
|
||||
_curDisplay = nullptr;
|
||||
_pdaMode = PDA_NO_MODE;
|
||||
setPdaState();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SBBasePda::showInventory() {
|
||||
synchronizePdaState();
|
||||
|
||||
// if a movie is playing, then stop it.
|
||||
stopMovie(false);
|
||||
|
||||
// If we have an inventory window
|
||||
if (_invWnd) {
|
||||
if (_curDisplay) {
|
||||
// Turn off the current display
|
||||
_curDisplay->setVisible(false);
|
||||
}
|
||||
// Turn on the inventory
|
||||
_invWnd->setVisible(true);
|
||||
|
||||
// Set the current display = Inventory
|
||||
_curDisplay = _invWnd;
|
||||
_pdaMode = PDA_INV_MODE;
|
||||
setPdaState();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SBBasePda::showMap() {
|
||||
synchronizePdaState();
|
||||
|
||||
// If a movie is playing, then stop it.
|
||||
stopMovie(false);
|
||||
|
||||
// if we have a map window
|
||||
if (_mapWnd) {
|
||||
if (_curDisplay) {
|
||||
// Turn off the current display
|
||||
_curDisplay->setVisible(false);
|
||||
}
|
||||
|
||||
// Turn on the map
|
||||
_mapWnd->setVisible(true);
|
||||
|
||||
// Set the current display = Map
|
||||
_curDisplay = _mapWnd;
|
||||
_pdaMode = PDA_MAP_MODE;
|
||||
_mapWnd->attachActiveObjects();
|
||||
setPdaState();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SBBasePda::hideMap() {
|
||||
synchronizePdaState();
|
||||
|
||||
// if we have a map window
|
||||
if (_mapWnd) {
|
||||
// Turn off the Map
|
||||
_mapWnd->setVisible(false);
|
||||
|
||||
// set the current display to nullptr
|
||||
_curDisplay = nullptr;
|
||||
setPdaState();
|
||||
_pdaMode = PDA_NO_MODE;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SBBasePda::showLog() {
|
||||
if (CBagStorageDevWnd::_pEvtSDev != nullptr) {
|
||||
CBagStorageDevWnd::_pEvtSDev->evaluateExpressions();
|
||||
}
|
||||
|
||||
synchronizePdaState();
|
||||
|
||||
// If a movie is playing, then stop it.
|
||||
stopMovie(false);
|
||||
|
||||
// if we have a map window
|
||||
if (_logWnd) {
|
||||
if (_curDisplay) {
|
||||
// Turn off the current display
|
||||
_curDisplay->setVisible(false);
|
||||
}
|
||||
|
||||
// Turn on the map
|
||||
_logWnd->setVisible(true);
|
||||
|
||||
// Set the current display = Map
|
||||
_curDisplay = _logWnd;
|
||||
_pdaMode = PDA_LOG_MODE;
|
||||
_logWnd->attachActiveObjects();
|
||||
setPdaState();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SBBasePda::msgLight() {
|
||||
// If we have a map window
|
||||
if (_logWnd) {
|
||||
((CBagLog *)_logWnd)->playMsgQueue();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void *SBBasePda::pdaButtonHandler(int refId, void *info) {
|
||||
assert(info != nullptr);
|
||||
|
||||
SBBasePda *curPda = (SBBasePda *)info;
|
||||
|
||||
switch (refId) {
|
||||
case PDA_MAP:
|
||||
curPda->showMap();
|
||||
break;
|
||||
|
||||
case PDA_STASH:
|
||||
curPda->showInventory();
|
||||
break;
|
||||
|
||||
case PDA_ZOOM:
|
||||
curPda->zoom();
|
||||
break;
|
||||
|
||||
case PDA_SYSTEM: {
|
||||
CBagel *curApp = CBagel::getBagApp();
|
||||
if (curApp != nullptr) {
|
||||
CBagMasterWin *curWnd = curApp->getMasterWnd();
|
||||
if (curWnd != nullptr) {
|
||||
curWnd->postUserMessage(WM_SHOW_SYSTEM_DLG, 0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case PDA_LOG:
|
||||
curPda->showLog();
|
||||
break;
|
||||
|
||||
case PDA_OFF:
|
||||
curPda->deactivate();
|
||||
break;
|
||||
|
||||
case PDA_MSGLIGHT:
|
||||
curPda->msgLight();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
void SBBasePda::synchronizePdaState() {
|
||||
if (_pdaPos == PDA_DOWN && isActivated()) {
|
||||
deactivate();
|
||||
} else if (_pdaPos == PDA_UP && isActivated() == false) {
|
||||
activate();
|
||||
}
|
||||
}
|
||||
|
||||
void SBBasePda::activate() {
|
||||
if (!_activating) {
|
||||
_activating = _numMoves;
|
||||
_activated = true;
|
||||
}
|
||||
|
||||
_pdaPos = PDA_UP;
|
||||
setPdaState();
|
||||
}
|
||||
|
||||
void SBBasePda::deactivate() {
|
||||
if (!_activating) {
|
||||
_activating = _numMoves;
|
||||
_activated = false;
|
||||
}
|
||||
|
||||
_pdaPos = PDA_DOWN;
|
||||
setPdaState();
|
||||
}
|
||||
|
||||
void SBBasePda::setPdaState() {
|
||||
const char *pdaMode;
|
||||
const char *pdaPos;
|
||||
|
||||
CBagVar *curVar = g_VarManager->getVariable("INBAR");
|
||||
|
||||
if (curVar != nullptr) {
|
||||
// Defined as global
|
||||
pdaMode = "BARPDAMODE";
|
||||
pdaPos = "BARPDAPOSITION";
|
||||
} else {
|
||||
pdaMode = "PDAMODE";
|
||||
pdaPos = "PDAPOSITION";
|
||||
}
|
||||
|
||||
// Save the pda state and position
|
||||
curVar = g_VarManager->getVariable(pdaMode);
|
||||
if (curVar != nullptr) {
|
||||
switch (_pdaMode) {
|
||||
case PDA_NO_MODE:
|
||||
curVar->setValue("NOMODE");
|
||||
break;
|
||||
case PDA_MAP_MODE:
|
||||
curVar->setValue("MAPMODE");
|
||||
break;
|
||||
case PDA_INV_MODE:
|
||||
curVar->setValue("INVMODE");
|
||||
break;
|
||||
case PDA_LOG_MODE:
|
||||
curVar->setValue("LOGMODE");
|
||||
break;
|
||||
case PDA_MOO_MODE:
|
||||
curVar->setValue("MOOMODE");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
curVar = g_VarManager->getVariable(pdaPos);
|
||||
if (curVar != nullptr) {
|
||||
switch (_pdaPos) {
|
||||
case PDA_UP:
|
||||
curVar->setValue("UP");
|
||||
break;
|
||||
case PDA_DOWN:
|
||||
curVar->setValue("DOWN");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SBBasePda::getPdaState() {
|
||||
char localBuff[256];
|
||||
CBofString pdaState(localBuff, 256);
|
||||
const char *pdaMode;
|
||||
const char *pdaPos;
|
||||
|
||||
CBagVar *curVar = g_VarManager->getVariable("INBAR");
|
||||
|
||||
if (curVar != nullptr) {
|
||||
// Defined as global
|
||||
pdaMode = "BARPDAMODE";
|
||||
pdaPos = "BARPDAPOSITION";
|
||||
} else {
|
||||
pdaMode = "PDAMODE";
|
||||
pdaPos = "PDAPOSITION";
|
||||
}
|
||||
|
||||
curVar = g_VarManager->getVariable(pdaMode);
|
||||
if (curVar) {
|
||||
pdaState = curVar->getValue();
|
||||
// Now set the internal PDA state based on this info.
|
||||
// If we saved during a movie, then restore to map mode.
|
||||
if (pdaState.find("MAP") != -1 || pdaState.find("MOO") != -1) {
|
||||
_pdaMode = PDA_MAP_MODE;
|
||||
} else if (pdaState.find("INV") != -1) {
|
||||
_pdaMode = PDA_INV_MODE;
|
||||
} else if (pdaState.find("LOG") != -1) {
|
||||
_pdaMode = PDA_LOG_MODE;
|
||||
} else if (pdaState.find("MOO") != -1) {
|
||||
_pdaMode = PDA_MOO_MODE;
|
||||
} else {
|
||||
_pdaMode = PDA_NO_MODE;
|
||||
}
|
||||
}
|
||||
|
||||
// Get the PDA up/down position
|
||||
curVar = g_VarManager->getVariable(pdaPos);
|
||||
if (curVar) {
|
||||
pdaState = curVar->getValue();
|
||||
if (pdaState.find("UP") != -1) {
|
||||
_pdaPos = PDA_UP;
|
||||
} else {
|
||||
_pdaPos = PDA_DOWN;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#define NULL_CURSOR 0
|
||||
#define HAND_CURSOR 1
|
||||
|
||||
int SBBasePda::getProperCursor(const CBofPoint &pos, CBofRect &pdaRect) const {
|
||||
const int wieldCursor = CBagWield::getWieldCursor();
|
||||
|
||||
// Assume can't click
|
||||
const int cursorID = NULL_CURSOR;
|
||||
|
||||
// If we're in the map, return the nullptr cursor, if on the pda but not in the
|
||||
// map window, return the hand. Same rules for nomode.
|
||||
switch (_pdaMode) {
|
||||
case PDA_MAP_MODE:
|
||||
case PDA_NO_MODE:
|
||||
case PDA_MOO_MODE:
|
||||
if (_mapWnd) {
|
||||
const CBofRect pdaViewRect = _mapWnd->getRect() + pdaRect.topLeft();
|
||||
if (pdaViewRect.ptInRect(pos)) {
|
||||
if (wieldCursor >= 0) {
|
||||
return wieldCursor;
|
||||
}
|
||||
return NULL_CURSOR;
|
||||
}
|
||||
return HAND_CURSOR;
|
||||
}
|
||||
break;
|
||||
|
||||
case PDA_INV_MODE:
|
||||
case PDA_LOG_MODE:
|
||||
// Make sure our cur display is synchronized.
|
||||
assert(_pdaMode == PDA_INV_MODE ? _curDisplay == _invWnd : _curDisplay == _logWnd);
|
||||
|
||||
// If we have a display, then parouse its list and see if we're over something worth
|
||||
// mousedowning on.
|
||||
if (_curDisplay) {
|
||||
CBagObject *overObj = nullptr;
|
||||
CBofRect pdaViewRect = _curDisplay->getRect() + pdaRect.topLeft();
|
||||
if (pdaViewRect.ptInRect(pos)) {
|
||||
// Go through the list of inventory items and see if we're over any of them
|
||||
// in particular.
|
||||
CBofList<CBagObject *> *objList = _curDisplay->getObjectList();
|
||||
if (objList != nullptr) {
|
||||
// Localize pda view rect
|
||||
pdaViewRect = _curDisplay->getRect() + pdaRect.topLeft();
|
||||
|
||||
const int count = objList->getCount();
|
||||
for (int i = 0; i < count; ++i) {
|
||||
CBagObject *curObj = objList->getNodeItem(i);
|
||||
if (curObj->isActive()) {
|
||||
// localize icon rectangle
|
||||
CBofRect iconRect = curObj->getRect() + pdaViewRect.topLeft();
|
||||
if (iconRect.ptInRect(pos)) {
|
||||
overObj = curObj;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (_pdaMode == PDA_LOG_MODE) {
|
||||
if (overObj) {
|
||||
return overObj->getOverCursor();
|
||||
}
|
||||
if (wieldCursor >= 0) {
|
||||
return wieldCursor;
|
||||
}
|
||||
}
|
||||
|
||||
if (_pdaMode == PDA_INV_MODE) {
|
||||
if (wieldCursor >= 0) {
|
||||
return wieldCursor;
|
||||
}
|
||||
if (overObj) {
|
||||
return overObj->getOverCursor();
|
||||
}
|
||||
}
|
||||
|
||||
return NULL_CURSOR;
|
||||
}
|
||||
|
||||
return HAND_CURSOR;
|
||||
}
|
||||
}
|
||||
|
||||
return cursorID;
|
||||
}
|
||||
|
||||
CBofRect SBBasePda::getViewRect() const {
|
||||
return (_curDisplay == nullptr ? CBofRect() : _curDisplay->getRect());
|
||||
}
|
||||
|
||||
ErrorCode SBBasePda::attachActiveObjects() {
|
||||
if (CBagStorageDevWnd::_pEvtSDev != nullptr) {
|
||||
CBagStorageDevWnd::_pEvtSDev->evaluateExpressions();
|
||||
}
|
||||
|
||||
if (_mooWnd)
|
||||
_mooWnd->attachActiveObjects();
|
||||
if (_invWnd)
|
||||
_invWnd->attachActiveObjects();
|
||||
if (_mapWnd)
|
||||
_mapWnd->attachActiveObjects();
|
||||
if (_logWnd)
|
||||
_logWnd->attachActiveObjects();
|
||||
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
ErrorCode SBBasePda::detachActiveObjects() {
|
||||
if (_mooWnd)
|
||||
_mooWnd->detachActiveObjects();
|
||||
if (_invWnd)
|
||||
_invWnd->detachActiveObjects();
|
||||
if (_mapWnd)
|
||||
_mapWnd->detachActiveObjects();
|
||||
if (_logWnd)
|
||||
_logWnd->detachActiveObjects();
|
||||
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
203
engines/bagel/spacebar/baglib/base_pda.h
Normal file
203
engines/bagel/spacebar/baglib/base_pda.h
Normal file
@@ -0,0 +1,203 @@
|
||||
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BAGEL_BAGLIB_BASE_PDA_H
|
||||
#define BAGEL_BAGLIB_BASE_PDA_H
|
||||
|
||||
#include "bagel/spacebar/baglib/storage_dev_bmp.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
#define PDA_MAP (100)
|
||||
#define PDA_STASH (101)
|
||||
#define PDA_ZOOM (102)
|
||||
#define PDA_SYSTEM (103)
|
||||
#define PDA_LOG (104)
|
||||
#define PDA_OFF (105)
|
||||
#define PDA_MSGLIGHT (110)
|
||||
#define PDA_ZOOMFLASH "ZOOMFLASH"
|
||||
|
||||
enum PdaMode {
|
||||
PDA_NO_MODE,
|
||||
PDA_MAP_MODE,
|
||||
PDA_INV_MODE,
|
||||
PDA_LOG_MODE,
|
||||
PDA_MOO_MODE
|
||||
};
|
||||
enum PdaPos {
|
||||
PDA_POS_UNINITIALIZED,
|
||||
PDA_UP,
|
||||
PDA_DOWN
|
||||
};
|
||||
|
||||
class SBBasePda {
|
||||
protected:
|
||||
// All PDA's in the game should share the same mode
|
||||
static PdaMode _pdaMode;
|
||||
static PdaPos _pdaPos;
|
||||
int _numMoves;
|
||||
int _activating;
|
||||
bool _activated;
|
||||
int _moveDist;
|
||||
CBagStorageDevBmp *_mooWnd; // Pointer to the PDAMOVIE object
|
||||
CBagStorageDevBmp *_invWnd; // Pointer to the inventory object
|
||||
CBagStorageDevBmp *_mapWnd; // Pointer to the Map object
|
||||
CBagStorageDevBmp *_logWnd; // Pointer to the Map object
|
||||
CBagStorageDevBmp *_curDisplay; // Pointer to the object currently displayed in PDA
|
||||
CBofWindow *_parent;
|
||||
bool _zoomedFl;
|
||||
bool _deactivateFl; // should we deactivate when done w/movie?
|
||||
|
||||
// hold this info for restore method
|
||||
CBagStorageDevBmp *_holdDisplay;
|
||||
static PdaMode _holdMode;
|
||||
|
||||
public:
|
||||
SBBasePda(CBofWindow *parent = nullptr, const CBofRect &rect = CBofRect(), bool activated = false);
|
||||
virtual ~SBBasePda();
|
||||
static void initialize();
|
||||
|
||||
/**
|
||||
* Allows PDA mode to be set by script
|
||||
*/
|
||||
static void setPdaMode(PdaMode pdaMode) {
|
||||
_pdaMode = pdaMode;
|
||||
}
|
||||
static PdaMode getPdaMode() {
|
||||
return _pdaMode;
|
||||
}
|
||||
bool isActivated() const {
|
||||
return _activating ? !_activated : _activated;
|
||||
}
|
||||
bool isActivating() const {
|
||||
return _activating;
|
||||
}
|
||||
|
||||
virtual ErrorCode attachActiveObjects();
|
||||
virtual ErrorCode detachActiveObjects();
|
||||
|
||||
/**
|
||||
* Sync starting options
|
||||
*/
|
||||
void synchronizePdaState();
|
||||
|
||||
void activate();
|
||||
void deactivate();
|
||||
|
||||
/**
|
||||
* Show the inventory
|
||||
*/
|
||||
virtual bool showInventory();
|
||||
|
||||
/**
|
||||
* Hide the inventory
|
||||
*/
|
||||
virtual bool hideInventory();
|
||||
|
||||
/**
|
||||
* Show the movie window
|
||||
*/
|
||||
virtual bool showMovie();
|
||||
|
||||
/**
|
||||
* Hide the movie window
|
||||
*/
|
||||
virtual bool hideMovie();
|
||||
|
||||
/**
|
||||
* Set the movie to play
|
||||
* @param movieName Movie filename
|
||||
* @return Success/failure
|
||||
*/
|
||||
bool setMovie(CBofString &movieName) const;
|
||||
|
||||
/**
|
||||
* Stops any playing movie
|
||||
*/
|
||||
void stopMovie(bool bResetPDA) const;
|
||||
|
||||
void setDeactivate(bool b) {
|
||||
_deactivateFl = b;
|
||||
}
|
||||
|
||||
bool getDeactivate() const {
|
||||
return _deactivateFl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the map
|
||||
*/
|
||||
virtual bool showMap();
|
||||
|
||||
/**
|
||||
* Hide the map
|
||||
*/
|
||||
virtual bool hideMap();
|
||||
|
||||
/**
|
||||
* Zoom the current display
|
||||
*/
|
||||
virtual bool zoom() {
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual bool showLog();
|
||||
|
||||
virtual bool msgLight();
|
||||
|
||||
/**
|
||||
* Hide the current display and reset the _curDisplay to nullptr
|
||||
* @return Success/failure
|
||||
*/
|
||||
virtual bool hideCurDisplay();
|
||||
|
||||
/**
|
||||
* Hide the current display and reset the _curDisplay to nullptr
|
||||
* @return Success/Failure
|
||||
*/
|
||||
virtual bool restoreCurDisplay();
|
||||
|
||||
static void *pdaButtonHandler(int refId, void *info);
|
||||
|
||||
void setPdaState();
|
||||
void getPdaState();
|
||||
|
||||
void setZoomed(bool newVal) {
|
||||
_zoomedFl = newVal;
|
||||
}
|
||||
bool getZoomed() const {
|
||||
return _zoomedFl;
|
||||
}
|
||||
|
||||
int getProperCursor(const CBofPoint &pos, CBofRect &pdaRect) const;
|
||||
|
||||
/**
|
||||
* Returns the background rect
|
||||
*/
|
||||
CBofRect getViewRect() const;
|
||||
};
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
|
||||
#endif
|
||||
109
engines/bagel/spacebar/baglib/bmp_object.cpp
Normal file
109
engines/bagel/spacebar/baglib/bmp_object.cpp
Normal file
@@ -0,0 +1,109 @@
|
||||
/* 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/bmp_object.h"
|
||||
#include "bagel/spacebar/boflib/app.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
CBagBmpObject::CBagBmpObject() : CBagObject() {
|
||||
_xObjType = BMP_OBJ;
|
||||
_bmp = nullptr;
|
||||
_transparency = -1;
|
||||
|
||||
CBagObject::setOverCursor(1);
|
||||
setTimeless(true);
|
||||
}
|
||||
|
||||
CBagBmpObject::~CBagBmpObject() {
|
||||
CBagBmpObject::detach();
|
||||
}
|
||||
|
||||
ErrorCode CBagBmpObject::attach(CBofPalette *palette) {
|
||||
_bmp = new CBofBitmap(getFileName(), palette);
|
||||
|
||||
return CBagObject::attach();
|
||||
}
|
||||
|
||||
ErrorCode CBagBmpObject::detach() {
|
||||
delete _bmp;
|
||||
_bmp = nullptr;
|
||||
|
||||
return CBagObject::detach();
|
||||
}
|
||||
|
||||
CBofRect CBagBmpObject::getRect() {
|
||||
const CBofPoint curPos = getPosition();
|
||||
CBofSize size;
|
||||
if (_bmp)
|
||||
size = _bmp->getSize();
|
||||
return CBofRect(curPos, size);
|
||||
}
|
||||
|
||||
ErrorCode CBagBmpObject::update(CBofBitmap *bmp, CBofPoint pt, CBofRect *srcRect, int maskColor) {
|
||||
if (bmp) {
|
||||
_transparency = maskColor;
|
||||
if (srcRect) {
|
||||
const CBofSize size = bmp->getSize();
|
||||
if (pt.x < 0) {
|
||||
srcRect->left -= pt.x;
|
||||
pt.x = 0;
|
||||
}
|
||||
if (pt.y < 0) {
|
||||
srcRect->top -= pt.y;
|
||||
pt.y = 0;
|
||||
}
|
||||
|
||||
int offset = srcRect->right + pt.x - size.cx;
|
||||
if (offset >= 0) {
|
||||
srcRect->right -= offset + 1;
|
||||
}
|
||||
|
||||
offset = srcRect->bottom + pt.y - size.cy;
|
||||
if (offset >= 0) {
|
||||
srcRect->bottom -= offset + 1;
|
||||
}
|
||||
}
|
||||
if (_bmp->paint(bmp, pt.x, pt.y, srcRect, maskColor))
|
||||
return ERR_UNKNOWN;
|
||||
}
|
||||
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
bool CBagBmpObject::isInside(const CBofPoint &pt) {
|
||||
if (_bmp && getRect().ptInRect(pt)) {
|
||||
if (_transparency >= 0) {
|
||||
const int x = pt.x - getRect().left;
|
||||
const int y = pt.y - getRect().top;
|
||||
const int color = _bmp->readPixel(x, y);
|
||||
return color != _transparency;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
72
engines/bagel/spacebar/baglib/bmp_object.h
Normal file
72
engines/bagel/spacebar/baglib/bmp_object.h
Normal file
@@ -0,0 +1,72 @@
|
||||
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BAGEL_BAGLIB_BMP_OBJECT_H
|
||||
#define BAGEL_BAGLIB_BMP_OBJECT_H
|
||||
|
||||
#include "bagel/spacebar/baglib/object.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
/**
|
||||
* CBagBmpObject is an object that can be place within the slide window.
|
||||
*/
|
||||
class CBagBmpObject : public CBagObject {
|
||||
private:
|
||||
CBofBitmap *_bmp;
|
||||
int _transparency;
|
||||
|
||||
protected:
|
||||
void setBitmap(CBofBitmap *bmp) {
|
||||
_bmp = bmp;
|
||||
}
|
||||
|
||||
public:
|
||||
CBagBmpObject();
|
||||
virtual ~CBagBmpObject();
|
||||
|
||||
ErrorCode attach() override {
|
||||
return attach(nullptr);
|
||||
}
|
||||
|
||||
ErrorCode attach(CBofPalette *palette);
|
||||
ErrorCode detach() override;
|
||||
|
||||
bool isAttached() override {
|
||||
return _bmp != nullptr;
|
||||
}
|
||||
|
||||
bool isInside(const CBofPoint &pt) override;
|
||||
|
||||
CBofBitmap *getBitmap() const {
|
||||
return _bmp;
|
||||
}
|
||||
CBofRect getRect() override;
|
||||
|
||||
ErrorCode update(CBofBitmap *bmp, CBofPoint pt, CBofRect *srcRect = nullptr, int maskColor = -1) override;
|
||||
};
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
|
||||
#endif
|
||||
504
engines/bagel/spacebar/baglib/button_object.cpp
Normal file
504
engines/bagel/spacebar/baglib/button_object.cpp
Normal file
@@ -0,0 +1,504 @@
|
||||
/* 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/button_object.h"
|
||||
#include "bagel/spacebar/baglib/bagel.h"
|
||||
#include "bagel/spacebar/baglib/master_win.h"
|
||||
#include "bagel/spacebar/baglib/pan_window.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
CBagButtonObject::CBagButtonObject() {
|
||||
_xObjType = BUTTON_OBJ;
|
||||
_buttonType = BTN_PUSH;
|
||||
|
||||
// Set to first cel
|
||||
CBagObject::setState(0);
|
||||
|
||||
_active = false;
|
||||
_activeDown = false;
|
||||
_activeUp = false;
|
||||
|
||||
_numPos = 0;
|
||||
_dragging = false;
|
||||
setCallBack(nullptr, nullptr);
|
||||
setAlwaysUpdate(true);
|
||||
|
||||
setTimeless(true);
|
||||
}
|
||||
|
||||
CBagButtonObject::~CBagButtonObject() {
|
||||
CBagButtonObject::detach();
|
||||
}
|
||||
|
||||
ErrorCode CBagButtonObject::attach() {
|
||||
const ErrorCode errorCode = CBagSpriteObject::attach();
|
||||
|
||||
CBofSprite *curSprite = getSprite();
|
||||
if (curSprite) {
|
||||
curSprite->setAnimated(false);
|
||||
}
|
||||
|
||||
if (_buttonType == BTN_VLEVER || _buttonType == BTN_HLEVER) {
|
||||
_midPoint.x = getRect().topLeft().x + (getRect().width() / 2);
|
||||
_midPoint.y = getRect().topLeft().y + (getRect().height() / 2);
|
||||
}
|
||||
|
||||
if (curSprite && curSprite->getCelCount() == 1 && _buttonType != BTN_SLIDER) {
|
||||
// Only given down state
|
||||
setVisible(false);
|
||||
}
|
||||
|
||||
// If this is a slider button make sure it is in the correct position
|
||||
if (_buttonType == BTN_SLIDER) {
|
||||
CBofPoint NewPoint = getPosition();
|
||||
const int xIncrement = _slideRect.width() / (_numPos - 1);
|
||||
NewPoint.x = _slideRect.left + (getState() * xIncrement);
|
||||
setPosition(NewPoint);
|
||||
}
|
||||
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
ErrorCode CBagButtonObject::detach() {
|
||||
return CBagSpriteObject::detach();
|
||||
}
|
||||
|
||||
extern bool g_noMenuFl;
|
||||
|
||||
bool CBagButtonObject::runObject() {
|
||||
// Reset wield
|
||||
g_noMenuFl = false;
|
||||
|
||||
if (_buttonType == BTN_PUSH) {
|
||||
|
||||
if (_active && !_activeUp) {
|
||||
_activeUp = true;
|
||||
}
|
||||
if (getSprite() && (getSprite()->getCelCount() == 1)) {
|
||||
// Only given down state
|
||||
setVisible(false);
|
||||
}
|
||||
|
||||
// Set to first cel
|
||||
setState(0);
|
||||
}
|
||||
|
||||
runCallBack();
|
||||
|
||||
return CBagObject::runObject();
|
||||
}
|
||||
|
||||
void CBagButtonObject::onLButtonDown(uint32 /*nFlags*/, CBofPoint *point, void *) {
|
||||
if (_buttonType == BTN_PUSH) {
|
||||
if (!_active && !_activeDown) {
|
||||
_activeDown = true;
|
||||
_active = true;
|
||||
}
|
||||
if (getSprite() && (getSprite()->getCelCount() == 1)) {
|
||||
// Only given down state
|
||||
setVisible();
|
||||
}
|
||||
|
||||
// Set to clicked down
|
||||
setState(1);
|
||||
|
||||
} else if (_buttonType == BTN_HLEVER || _buttonType == BTN_VLEVER) {
|
||||
if (!_activeDown && !_activeUp) {
|
||||
if ((_buttonType == BTN_HLEVER && point->x > _midPoint.x) || // right of midpoint
|
||||
(_buttonType == BTN_VLEVER && point->y > _midPoint.y)) { // below midpoint
|
||||
_activeDown = true;
|
||||
} else {
|
||||
_activeUp = true;
|
||||
}
|
||||
}
|
||||
|
||||
} else if (_buttonType == BTN_SLIDER) {
|
||||
_dragging = true;
|
||||
}
|
||||
|
||||
setDirty();
|
||||
}
|
||||
|
||||
void CBagButtonObject::onLButtonUp(uint32 flags, CBofPoint *point, void *extraInfo) {
|
||||
CBagStorageDevWnd *pMainWin = (CBagel::getBagApp()->getMasterWnd()->getCurrentStorageDev());
|
||||
|
||||
if (pMainWin != nullptr) {
|
||||
pMainWin->setPreFilterPan(true);
|
||||
}
|
||||
|
||||
if ((_buttonType == BTN_SLIDER) && _dragging) {
|
||||
// Snap to place
|
||||
CBofPoint NewPoint = getPosition();
|
||||
|
||||
// Get the mouse point relative to the pan window
|
||||
CBagPanWindow *pWnd = (CBagPanWindow *)extraInfo;
|
||||
const CBofRect r = pWnd->getSlideBitmap()->getCurrView();
|
||||
|
||||
const int mLocX = point->x + r.left - pWnd->getViewPortPos().x;
|
||||
const int xIncrement = _slideRect.width() / (_numPos - 1);
|
||||
|
||||
int slidePos = _slideRect.left;
|
||||
int i;
|
||||
for (i = 0; (i < _numPos) && (slidePos < mLocX); i++)
|
||||
slidePos = _slideRect.left + (i * xIncrement);
|
||||
|
||||
// We Went too far
|
||||
i--;
|
||||
|
||||
// Find the previous position was closer to the mouse
|
||||
if ((i > 0) && (slidePos - mLocX > mLocX - (slidePos - xIncrement)))
|
||||
i--; // Go back one
|
||||
|
||||
NewPoint.x = _slideRect.left + (i * xIncrement);
|
||||
if (NewPoint.x < _slideRect.left) {
|
||||
NewPoint.x = _slideRect.left;
|
||||
} else if (NewPoint.x > _slideRect.right) {
|
||||
NewPoint.x = _slideRect.right;
|
||||
}
|
||||
|
||||
setPosition(NewPoint);
|
||||
if (i < 0) {
|
||||
i = 0;
|
||||
} else if (i >= _numPos) {
|
||||
i = _numPos - 1;
|
||||
}
|
||||
|
||||
setState(i);
|
||||
_dragging = false;
|
||||
|
||||
} else if (_buttonType == BTN_CHECKBOX) {
|
||||
|
||||
if (!_active) {
|
||||
_active = true;
|
||||
_activeDown = !_activeDown;
|
||||
|
||||
if (getSprite() && (getSprite()->getCelCount() == 1)) {
|
||||
// Only given down state
|
||||
setVisible(_activeDown);
|
||||
_active = false;
|
||||
}
|
||||
|
||||
if (_activeDown)
|
||||
setState(1);
|
||||
else
|
||||
setState(0);
|
||||
}
|
||||
}
|
||||
|
||||
setDirty();
|
||||
|
||||
CBagSpriteObject::onLButtonUp(flags, point, extraInfo);
|
||||
}
|
||||
|
||||
bool CBagButtonObject::onMouseMove(uint32 /*nFlags*/, CBofPoint point, void *extraInfo) {
|
||||
CBagStorageDevWnd *pMainWin = (CBagel::getBagApp()->getMasterWnd()->getCurrentStorageDev());
|
||||
|
||||
if (_buttonType == BTN_SLIDER && _dragging) {
|
||||
if (!_slideRect.isRectEmpty()) {
|
||||
if (pMainWin != nullptr) {
|
||||
pMainWin->setPreFilterPan(true);
|
||||
}
|
||||
setDirty();
|
||||
|
||||
CBofPoint NewPoint = getPosition();
|
||||
CBagPanWindow *pWnd = (CBagPanWindow *)extraInfo;
|
||||
const CBofRect r = pWnd->getSlideBitmap()->getCurrView();
|
||||
|
||||
const int mLocX = point.x + r.left - pWnd->getViewPortPos().x;
|
||||
|
||||
int NewXPos = mLocX;
|
||||
|
||||
// Constrict Dragging to width of slidebar
|
||||
if (NewXPos > _slideRect.right)
|
||||
NewXPos = _slideRect.right;
|
||||
if (NewXPos < _slideRect.left)
|
||||
NewXPos = _slideRect.left;
|
||||
|
||||
NewPoint.x = NewXPos;
|
||||
setPosition(NewPoint);
|
||||
|
||||
// We need to set the state here as well as LButtonUP
|
||||
// because there is a chance we won't get it
|
||||
const int xIncrement = _slideRect.width() / (_numPos - 1);
|
||||
const int i = (NewPoint.x - _slideRect.left) / xIncrement;
|
||||
setState(i);
|
||||
}
|
||||
}
|
||||
|
||||
if (_buttonType == BTN_PUSH) {
|
||||
if (getSprite() && (getSprite()->getCelCount() > 1)) {
|
||||
if (!this->getRect().ptInRect(point) && _active && !_activeUp) {
|
||||
_activeUp = true;
|
||||
}
|
||||
}
|
||||
if (getSprite() && (getSprite()->getCelCount() == 1)) { // Only given down state
|
||||
setVisible(false);
|
||||
}
|
||||
|
||||
setState(0); // Set to first cel
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
ErrorCode CBagButtonObject::update(CBofBitmap *bmp, CBofPoint pt, CBofRect *srcRect, int maskColor) {
|
||||
bool bDirty = false;
|
||||
|
||||
if (_buttonType == BTN_PUSH) {
|
||||
|
||||
if (getSprite() && (getSprite()->getCelCount() > 1)) {
|
||||
|
||||
if (_active) { // If the button is doing something
|
||||
if (_activeDown) {
|
||||
getSprite()->nextCel(); // Increment frame
|
||||
// If this is animated, the bring it back up immediately
|
||||
if (getSprite()->getCelIndex() == getSprite()->getCelCount() - 1 || getSprite()->getAnimated()) {
|
||||
_activeDown = false;
|
||||
}
|
||||
} else if (_activeUp) { // else (going back up)
|
||||
getSprite()->prevCel(); // decrement frame
|
||||
// If this is animated, the let it go immediately
|
||||
if (getSprite()->getCelIndex() == 0 || getSprite()->getAnimated()) {
|
||||
_activeUp = false;
|
||||
_active = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else if (_buttonType == BTN_CHECKBOX) {
|
||||
if (getSprite() && (getSprite()->getCelCount() > 1) && _active) {
|
||||
if (_activeDown) {
|
||||
getSprite()->nextCel(); // Increment frame
|
||||
if (getSprite()->getCelIndex() == getSprite()->getCelCount() - 1) {
|
||||
_active = false;
|
||||
}
|
||||
} else { // else (going back up)
|
||||
getSprite()->prevCel(); // decrement frame
|
||||
if (getSprite()->getCelIndex() == 0) {
|
||||
_active = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// For checkboxes, we have to make sure that they are always
|
||||
// redrawn as they will otherwise return to their state on the pan (in the
|
||||
// background of the closeup).
|
||||
bDirty = true;
|
||||
|
||||
} else if (_buttonType == BTN_HLEVER || _buttonType == BTN_VLEVER) {
|
||||
|
||||
if (getSprite() && (getSprite()->getCelCount() > 1)) {
|
||||
if (_activeDown) {
|
||||
if (getSprite()->getCelIndex() < (getSprite()->getCelCount() - 1))
|
||||
getSprite()->nextCel();
|
||||
_activeDown = false;
|
||||
} else if (_activeUp) {
|
||||
if (getSprite()->getCelIndex() > 0)
|
||||
getSprite()->prevCel();
|
||||
_activeUp = false;
|
||||
}
|
||||
|
||||
setState(getSprite()->getCelIndex());
|
||||
}
|
||||
}
|
||||
|
||||
if (getSprite() && ((getSprite()->getCelCount() > 1) || isVisible())) {
|
||||
const ErrorCode errorCode = CBagSpriteObject::update(bmp, pt, srcRect, maskColor);
|
||||
setDirty(bDirty);
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
return _errCode;
|
||||
}
|
||||
|
||||
void CBagButtonObject::setSize(const CBofSize &size) {
|
||||
if (_buttonType == BTN_SLIDER)
|
||||
_slideRect = CBofRect(getPosition(), size);
|
||||
|
||||
CBagSpriteObject::setSize(size);
|
||||
}
|
||||
|
||||
ParseCodes CBagButtonObject::setInfo(CBagIfstream &istr) {
|
||||
bool nObjectUpdated = false;
|
||||
|
||||
while (!istr.eof()) {
|
||||
const char ch = (char)istr.peek();
|
||||
switch (ch) {
|
||||
//
|
||||
// +n - n number of slides in sprite
|
||||
//
|
||||
case '+': {
|
||||
int cels;
|
||||
istr.getCh();
|
||||
getIntFromStream(istr, cels);
|
||||
|
||||
if (_buttonType == BTN_SLIDER)
|
||||
_numPos = cels;
|
||||
else
|
||||
setCels(cels);
|
||||
nObjectUpdated = true;
|
||||
break;
|
||||
}
|
||||
|
||||
// Handle a maximum framerate...
|
||||
case 'F': {
|
||||
char szLocalStr[256];
|
||||
szLocalStr[0] = 0;
|
||||
CBofString sStr(szLocalStr, 256);
|
||||
getAlphaNumFromStream(istr, sStr);
|
||||
|
||||
if (!sStr.find("FRAMERATE")) {
|
||||
int nFrameRate;
|
||||
istr.eatWhite();
|
||||
getIntFromStream(istr, nFrameRate);
|
||||
|
||||
// The framerate is expressed in frames/second, so do some division
|
||||
// here to store the number of milliseconds.
|
||||
|
||||
setFrameRate(1000 / nFrameRate);
|
||||
|
||||
nObjectUpdated = true;
|
||||
} else {
|
||||
putbackStringOnStream(istr, sStr);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
// AS [LINK|CLOSEUP] - how to run the link
|
||||
//
|
||||
case 'A': {
|
||||
char szLocalStr[256];
|
||||
szLocalStr[0] = 0;
|
||||
CBofString sStr(szLocalStr, 256);
|
||||
getAlphaNumFromStream(istr, sStr);
|
||||
|
||||
if (!sStr.find("AS")) {
|
||||
istr.eatWhite();
|
||||
getAlphaNumFromStream(istr, sStr);
|
||||
if (!sStr.find("PUSH")) {
|
||||
_buttonType = BTN_PUSH;
|
||||
nObjectUpdated = true;
|
||||
} else if (!sStr.find("CHECKBOX")) {
|
||||
_buttonType = BTN_CHECKBOX;
|
||||
nObjectUpdated = true;
|
||||
} else if (!sStr.find("HLEVER")) {
|
||||
_buttonType = BTN_HLEVER;
|
||||
nObjectUpdated = true;
|
||||
} else if (!sStr.find("VLEVER")) {
|
||||
_buttonType = BTN_VLEVER;
|
||||
nObjectUpdated = true;
|
||||
} else if (!sStr.find("DIAL")) {
|
||||
_buttonType = BTN_DIAL;
|
||||
nObjectUpdated = true;
|
||||
} else if (!sStr.find("SLIDER")) {
|
||||
_buttonType = BTN_SLIDER;
|
||||
nObjectUpdated = true;
|
||||
} else {
|
||||
putbackStringOnStream(istr, sStr);
|
||||
putbackStringOnStream(istr, "AS ");
|
||||
}
|
||||
} else {
|
||||
putbackStringOnStream(istr, sStr);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
// No match return from function
|
||||
//
|
||||
default: {
|
||||
const ParseCodes parseCode = CBagObject::setInfo(istr);
|
||||
if (parseCode == PARSING_DONE) {
|
||||
return PARSING_DONE;
|
||||
}
|
||||
|
||||
if (parseCode == UPDATED_OBJECT) {
|
||||
nObjectUpdated = true;
|
||||
} else { // rc==UNKNOWN_TOKEN
|
||||
if (nObjectUpdated)
|
||||
return UPDATED_OBJECT;
|
||||
|
||||
return UNKNOWN_TOKEN;
|
||||
}
|
||||
break;
|
||||
}
|
||||
} // end switch
|
||||
} // end while
|
||||
|
||||
return PARSING_DONE;
|
||||
}
|
||||
|
||||
void CBagButtonObject::setProperty(const CBofString &prop, int val) {
|
||||
if (!prop.find("STATE")) {
|
||||
if (getSprite()) {
|
||||
if (_buttonType == BTN_CHECKBOX) {
|
||||
_active = true;
|
||||
if (val == 0)
|
||||
_activeDown = false;
|
||||
else
|
||||
_activeDown = true;
|
||||
|
||||
if (getSprite()->getCelCount() == 1) { // Only given down state
|
||||
setVisible(_activeDown);
|
||||
_active = false;
|
||||
}
|
||||
|
||||
if (val == 0)
|
||||
setState(0);
|
||||
else
|
||||
setState(1);
|
||||
} else {
|
||||
if (_buttonType == BTN_SLIDER) {
|
||||
CBofPoint cPos = getPosition();
|
||||
|
||||
cPos.x = _slideRect.left + (val * (_slideRect.width() / (_numPos - 1)));
|
||||
setPosition(cPos);
|
||||
setDirty(true);
|
||||
}
|
||||
setState(val);
|
||||
getSprite()->setCel(val);
|
||||
}
|
||||
}
|
||||
} else if (!prop.find("CURR_CEL")) {
|
||||
setState(val);
|
||||
if (getSprite())
|
||||
getSprite()->setCel(val);
|
||||
} else
|
||||
CBagObject::setProperty(prop, val);
|
||||
}
|
||||
|
||||
int CBagButtonObject::getProperty(const CBofString &prop) {
|
||||
if (!prop.find("CURR_CEL")) {
|
||||
if (getSprite()) {
|
||||
return getSprite()->getCelIndex();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
return CBagObject::getProperty(prop);
|
||||
}
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
126
engines/bagel/spacebar/baglib/button_object.h
Normal file
126
engines/bagel/spacebar/baglib/button_object.h
Normal file
@@ -0,0 +1,126 @@
|
||||
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BAGEL_BAGLIB_BUTTON_OBJECT_H
|
||||
#define BAGEL_BAGLIB_BUTTON_OBJECT_H
|
||||
|
||||
#include "bagel/spacebar/baglib/sprite_object.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
#define SAVE_BTN 0
|
||||
#define CANCEL_BTN 1
|
||||
#define RESTORE_BTN 2
|
||||
#define RESTART_BTN 3
|
||||
#define QUIT_BTN 4
|
||||
|
||||
#define LINEUP_BTN 10
|
||||
#define LINEDN_BTN 11
|
||||
#define PAGEUP_BTN 12
|
||||
#define PAGEDN_BTN 13
|
||||
|
||||
/**
|
||||
* CBagButtonObject is an object that can be place within the slide window.
|
||||
*/
|
||||
class CBagButtonObject : public CBagSpriteObject {
|
||||
public:
|
||||
enum BUTTON_TYPE {
|
||||
BTN_PUSH = 0,
|
||||
BTN_CHECKBOX = 1,
|
||||
BTN_HLEVER = 2,
|
||||
BTN_VLEVER = 3,
|
||||
BTN_DIAL = 4,
|
||||
BTN_SLIDER = 5
|
||||
};
|
||||
|
||||
private:
|
||||
bool _dragging;
|
||||
CBofRect _slideRect;
|
||||
int _numPos;
|
||||
|
||||
BUTTON_TYPE _buttonType;
|
||||
bool _activeDown;
|
||||
bool _activeUp;
|
||||
bool _active;
|
||||
|
||||
CBofPoint _midPoint;
|
||||
BagFuncPtr _callbackFct;
|
||||
void *_callbackInfo; // Data to be passed to the function
|
||||
|
||||
public:
|
||||
CBagButtonObject();
|
||||
virtual ~CBagButtonObject();
|
||||
|
||||
ErrorCode attach() override;
|
||||
ErrorCode detach() override;
|
||||
|
||||
BUTTON_TYPE getButtonType() const {
|
||||
return _buttonType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes in info and then removes the relative information and returns
|
||||
* the info without the relevant info.
|
||||
*/
|
||||
ParseCodes setInfo(CBagIfstream &istr) override;
|
||||
bool runObject() override;
|
||||
|
||||
// Callback function functionality - probably can be phased out
|
||||
void setCallBack(BagFuncPtr func, void *funcInfo) {
|
||||
_callbackFct = func;
|
||||
_callbackInfo = funcInfo;
|
||||
}
|
||||
|
||||
BagFuncPtr getCallBack() override {
|
||||
return _callbackFct;
|
||||
}
|
||||
|
||||
void *getCallBackInfo() const {
|
||||
return _callbackInfo;
|
||||
}
|
||||
|
||||
bool runCallBack() override {
|
||||
if (_callbackFct) {
|
||||
_callbackFct((int)getRefId(), _callbackInfo);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void onLButtonDown(uint32 /*nFlags*/, CBofPoint *point, void *) override;
|
||||
void onLButtonUp(uint32 flags, CBofPoint *point, void *extraInfo) override;
|
||||
bool onMouseMove(uint32 /*nFlags*/, CBofPoint point, void *extraInfo) override;
|
||||
|
||||
ErrorCode update(CBofBitmap *bmp, CBofPoint pt, CBofRect *srcRect = nullptr, int maskColor = -1) override;
|
||||
|
||||
void setSize(const CBofSize &size) override;
|
||||
|
||||
void setProperty(const CBofString &prop, int val) override;
|
||||
int getProperty(const CBofString &prop) override;
|
||||
};
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
|
||||
#endif
|
||||
671
engines/bagel/spacebar/baglib/character_object.cpp
Normal file
671
engines/bagel/spacebar/baglib/character_object.cpp
Normal file
@@ -0,0 +1,671 @@
|
||||
/* 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 "common/file.h"
|
||||
#include "bagel/spacebar/baglib/character_object.h"
|
||||
#include "bagel/spacebar/baglib/storage_dev_win.h"
|
||||
#include "bagel/spacebar/baglib/master_win.h"
|
||||
#include "bagel/spacebar/baglib/pan_window.h"
|
||||
#include "bagel/bagel.h"
|
||||
#include "bagel/boflib/file_functions.h"
|
||||
#include "bagel/boflib/log.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
CBagCharacterObject *CBagCharacterObject::_pdaWand;
|
||||
bool CBagCharacterObject::_pdaAnimating;
|
||||
|
||||
void CBagCharacterObject::initialize() {
|
||||
_pdaWand = nullptr;
|
||||
_pdaAnimating = false;
|
||||
}
|
||||
|
||||
CBagCharacterObject::CBagCharacterObject() : CBagObject() {
|
||||
_xObjType = CHAR_OBJ;
|
||||
_bmpBuf = nullptr;
|
||||
_binBuf = nullptr;
|
||||
_charTransColor = -1;
|
||||
// Default is now the nullptr cursor
|
||||
CBagObject::setOverCursor(0);
|
||||
setTimeless(true);
|
||||
_startFrame = -1;
|
||||
_endFrame = -1;
|
||||
_playbackSpeed = 1;
|
||||
_numOfLoops = -1;
|
||||
_exitAtEnd = false;
|
||||
_prevFrame = -1;
|
||||
_firstFrame = true;
|
||||
_pAnim = false;
|
||||
_saveState = false;
|
||||
}
|
||||
|
||||
CBagCharacterObject::~CBagCharacterObject() {
|
||||
CBagCharacterObject::detach();
|
||||
}
|
||||
|
||||
ErrorCode CBagCharacterObject::attach() {
|
||||
char localBuff[256];
|
||||
localBuff[0] = '\0';
|
||||
CBofString filename(localBuff, 256);
|
||||
CBofPalette *smackPal = CBofApp::getApp()->getPalette();
|
||||
|
||||
filename = getFileName();
|
||||
|
||||
// Open the smacker file
|
||||
Video::SmackerDecoder *decoder = new Video::SmackerDecoder();
|
||||
decoder->setSoundType(Audio::Mixer::kSFXSoundType);
|
||||
if (!decoder->loadFile(filename.getBuffer())) {
|
||||
logError(buildString("char SmackOpen failed: %s ", filename.getBuffer()));
|
||||
delete decoder;
|
||||
return ERR_FOPEN;
|
||||
}
|
||||
|
||||
_smacker = decoder;
|
||||
|
||||
// Create an offscreen bitmap to decompress smacker into
|
||||
_firstFrame = true;
|
||||
|
||||
_bmpBuf = new CBofBitmap(_smacker->getWidth(), _smacker->getHeight(), smackPal);
|
||||
|
||||
if (smackPal != nullptr) {
|
||||
_bmpBuf->fillRect(nullptr, smackPal->getNearestIndex(RGB(255, 255, 255)));
|
||||
}
|
||||
|
||||
// Create the text filename
|
||||
filename.makeUpper();
|
||||
filename.replaceStr(".SMK", ".BIN");
|
||||
|
||||
if (_binBuf != nullptr) {
|
||||
bofFree(_binBuf);
|
||||
_binBuf = nullptr;
|
||||
}
|
||||
|
||||
// Does file exist
|
||||
if (fileExists(filename.getBuffer())) {
|
||||
CBofFile cInputFile(filename.getBuffer());
|
||||
|
||||
_binBufLen = cInputFile.getLength();
|
||||
_binBuf = (char *)bofAlloc(_binBufLen + 1);
|
||||
cInputFile.read(_binBuf, _binBufLen);
|
||||
}
|
||||
|
||||
// Set the start and stop frames if still default.
|
||||
if (_playbackSpeed > 0) {
|
||||
// Forward playback
|
||||
if (_startFrame == -1)
|
||||
_startFrame = 0;
|
||||
if (_endFrame == -1) {
|
||||
_endFrame = _smacker->getFrameCount();
|
||||
--_endFrame;
|
||||
}
|
||||
} else {
|
||||
// Reverse playback
|
||||
if (_endFrame == -1)
|
||||
_endFrame = 1;
|
||||
if (_startFrame == -1)
|
||||
_startFrame = _smacker->getFrameCount();
|
||||
|
||||
//_smacker->setReverse(true); // TODO: Not supported by SMK
|
||||
}
|
||||
|
||||
if (_saveState) {
|
||||
// Get the current state for this object
|
||||
const int nState = getState();
|
||||
|
||||
// If the state is not the default(0) then move to the correct frame
|
||||
if (nState != 0)
|
||||
setFrame(nState);
|
||||
}
|
||||
|
||||
if (_numOfLoops != 0) {
|
||||
_smacker->start();
|
||||
} else {
|
||||
_smacker->stop();
|
||||
}
|
||||
|
||||
setVisible(true);
|
||||
updatePosition();
|
||||
refreshCurrentFrame();
|
||||
|
||||
// Get chroma from main app now
|
||||
_charTransColor = CBagel::getBagApp()->getChromaColor();
|
||||
|
||||
return CBagObject::attach();
|
||||
}
|
||||
|
||||
ErrorCode CBagCharacterObject::detach() {
|
||||
if (_saveState) {
|
||||
// Save off the state/frame information as we detach
|
||||
// so that we can recreate the scene when we attach again
|
||||
if (_smacker != nullptr) {
|
||||
setState(_smacker->getCurFrame());
|
||||
}
|
||||
} else {
|
||||
// Decrement current loop from happening again
|
||||
if (_numOfLoops > 0)
|
||||
_numOfLoops--;
|
||||
}
|
||||
|
||||
if (_smacker != nullptr) {
|
||||
_smacker->close();
|
||||
delete _smacker;
|
||||
_smacker = nullptr;
|
||||
}
|
||||
|
||||
delete _bmpBuf;
|
||||
_bmpBuf = nullptr;
|
||||
|
||||
if (_binBuf != nullptr) {
|
||||
bofFree(_binBuf);
|
||||
_binBuf = nullptr;
|
||||
}
|
||||
|
||||
if (this == _pdaWand) {
|
||||
_pdaWand = nullptr;
|
||||
}
|
||||
|
||||
return CBagObject::detach();
|
||||
}
|
||||
|
||||
bool CBagCharacterObject::refreshCurrentFrame() {
|
||||
bool newFrameFl = true;
|
||||
|
||||
if (_bmpBuf != nullptr) {
|
||||
if (_smacker != nullptr) {
|
||||
// Decode the next frame
|
||||
const Graphics::Surface *surf = _smacker->decodeNextFrame();
|
||||
if (surf) {
|
||||
Graphics::ManagedSurface &destSurf = *_bmpBuf;
|
||||
|
||||
// Copy the decoded frame into the offscreen bitmap
|
||||
destSurf.setPalette(_smacker->getPalette(), 0, 256);
|
||||
destSurf.blitFrom(*surf);
|
||||
} else {
|
||||
newFrameFl = false;
|
||||
}
|
||||
|
||||
} else {
|
||||
// Return false so we don't update our position
|
||||
newFrameFl = false;
|
||||
}
|
||||
}
|
||||
|
||||
return newFrameFl;
|
||||
}
|
||||
|
||||
CBofRect CBagCharacterObject::getRect() {
|
||||
const CBofPoint pos = getPosition();
|
||||
CBofSize size;
|
||||
|
||||
if (_bmpBuf)
|
||||
size = _bmpBuf->getSize();
|
||||
|
||||
return CBofRect(pos, size);
|
||||
}
|
||||
|
||||
void CBagCharacterObject::updatePosition() {
|
||||
// We have an input file
|
||||
if (_binBuf != nullptr && _smacker != nullptr) {
|
||||
// Seek to correct place in the file
|
||||
int frame = _smacker->getCurFrame();
|
||||
|
||||
if (frame < 0)
|
||||
frame = 0;
|
||||
|
||||
int32 lSeekPos = frame * 2 * sizeof(int32);
|
||||
|
||||
// Read from our memory buffer rather than going to
|
||||
// disk for the position of the smack dudes.
|
||||
// Check that we are going to fit
|
||||
if (lSeekPos + (int32)(2 * sizeof(int32)) <= _binBufLen) {
|
||||
const int xPos = READ_LE_INT32(&_binBuf[lSeekPos]);
|
||||
lSeekPos += sizeof(int32);
|
||||
const int yPos = READ_LE_INT32(&_binBuf[lSeekPos]);
|
||||
|
||||
// A valid number was read
|
||||
if ((xPos > -1) && (yPos > -1)) {
|
||||
const CBofPoint newPos(xPos, yPos);
|
||||
setPosition(newPos);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool CBagCharacterObject::doAdvance() {
|
||||
// Assume we're not advancing
|
||||
bool doAdvanceFl = false;
|
||||
const bool pdaWandFl = (this == _pdaWand);
|
||||
|
||||
if (pdaWandFl) {
|
||||
_pdaAnimating = false;
|
||||
}
|
||||
|
||||
// If we are done looping just return with false
|
||||
if (!_numOfLoops)
|
||||
return false;
|
||||
|
||||
// If we got a background bitmap
|
||||
if (_bmpBuf != nullptr) {
|
||||
// If This Panimation is modal, or Panimations are ON, then get next frame.
|
||||
if (isModal() || !_pAnim || CBagMasterWin::getPanimations()) {
|
||||
if (_smacker->needsUpdate()) {
|
||||
doAdvanceFl = true;
|
||||
|
||||
// Paint the current frame to the BMP
|
||||
if (refreshCurrentFrame()) {
|
||||
_smacker->resetStartTime();
|
||||
// Get the current frame in the correct place
|
||||
updatePosition();
|
||||
}
|
||||
|
||||
if (_playbackSpeed > 0) {
|
||||
// We've looped
|
||||
if (_smacker->getCurFrame() == _endFrame) {
|
||||
if (_numOfLoops > 0)
|
||||
_numOfLoops--; // decrement num of loops
|
||||
|
||||
// Get next frame, will loop to beginning
|
||||
_smacker->rewind();
|
||||
_smacker->start();
|
||||
}
|
||||
} else {
|
||||
if (_smacker->getCurFrame() == _endFrame || _smacker->getCurFrame() == 1) {
|
||||
if (_numOfLoops > 0)
|
||||
_numOfLoops--; // decrement num of loops
|
||||
|
||||
// Get next frame, will loop to beginning
|
||||
setFrame(_startFrame);
|
||||
} else {
|
||||
setFrame(_smacker->getCurFrame() - 1); // HACK: Reverse playback
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (_firstFrame) {
|
||||
// Only play the first frame
|
||||
_firstFrame = false;
|
||||
|
||||
// Get the current frame in the correct place
|
||||
updatePosition();
|
||||
|
||||
// Paint the current frame to the BMP
|
||||
refreshCurrentFrame();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// We got a Bitmap
|
||||
if (pdaWandFl) {
|
||||
_pdaAnimating = doAdvanceFl;
|
||||
}
|
||||
|
||||
return doAdvanceFl;
|
||||
}
|
||||
|
||||
bool CBagCharacterObject::isInside(const CBofPoint &point) {
|
||||
if (getRect().ptInRect(point) && _charTransColor >= 0) {
|
||||
if (_bmpBuf) {
|
||||
const int x = point.x - getRect().left;
|
||||
const int y = point.y - getRect().top;
|
||||
const int color = _bmpBuf->readPixel(x, y);
|
||||
return (color != _charTransColor);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CBagCharacterObject::runObject() {
|
||||
CBagObject::runObject();
|
||||
return false;
|
||||
}
|
||||
|
||||
ErrorCode CBagCharacterObject::update(CBofBitmap *bmp, CBofPoint pt, CBofRect * /*srcRect, unused*/, int /*maskColor, unused*/) {
|
||||
// Get the original position for character
|
||||
const CBofPoint originalPos = getPosition();
|
||||
|
||||
const bool doAdvanceFl = doAdvance();
|
||||
|
||||
// If we have more frames advance this, else exit and detach if needed
|
||||
if (!doAdvanceFl && _exitAtEnd) {
|
||||
// Run the ending objects
|
||||
detach();
|
||||
}
|
||||
|
||||
if (_bmpBuf) {
|
||||
// Get the new position for the character
|
||||
const CBofPoint newPos = getPosition();
|
||||
// Get access to the current sDev
|
||||
|
||||
// Paint in the new pos
|
||||
return _bmpBuf->paint(bmp, (pt.x + (newPos.x - originalPos.x)), (pt.y + (newPos.y - originalPos.y)), nullptr, _charTransColor);
|
||||
}
|
||||
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
ParseCodes CBagCharacterObject::setInfo(CBagIfstream &istr) {
|
||||
bool objectUpdatedFl = false;
|
||||
|
||||
while (!istr.eof()) {
|
||||
const char ch = (char)istr.peek();
|
||||
switch (ch) {
|
||||
// SAVESTATE - Maintain the state of the character
|
||||
case 'K': {
|
||||
char localStr[256];
|
||||
localStr[0] = 0;
|
||||
CBofString str(localStr, 256);
|
||||
|
||||
getAlphaNumFromStream(istr, str);
|
||||
|
||||
if (!str.find("KEEPSTATE")) {
|
||||
istr.eatWhite();
|
||||
|
||||
_saveState = true;
|
||||
|
||||
objectUpdatedFl = true;
|
||||
} else {
|
||||
putbackStringOnStream(istr, str);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// LOOP n - n number of times to loop (-1 infinate)
|
||||
case 'L': {
|
||||
char localStr[256];
|
||||
localStr[0] = 0;
|
||||
CBofString str(localStr, 256);
|
||||
|
||||
getAlphaNumFromStream(istr, str);
|
||||
|
||||
if (!str.find("LOOP")) {
|
||||
istr.eatWhite();
|
||||
getIntFromStream(istr, _numOfLoops);
|
||||
objectUpdatedFl = true;
|
||||
} else {
|
||||
putbackStringOnStream(istr, str);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// SPEED n - n pace of playback (negative is backward), (0 to hold at current frame)
|
||||
case 'S': {
|
||||
char localStr[256];
|
||||
localStr[0] = 0;
|
||||
CBofString str(localStr, 256);
|
||||
|
||||
getAlphaNumFromStream(istr, str);
|
||||
|
||||
if (!str.find("SPEED")) {
|
||||
istr.eatWhite();
|
||||
getIntFromStream(istr, _playbackSpeed);
|
||||
objectUpdatedFl = true;
|
||||
} else {
|
||||
putbackStringOnStream(istr, str);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// EXITATEND - detach at end of looping (call run after objects)
|
||||
case 'E': {
|
||||
char localStr[256];
|
||||
localStr[0] = 0;
|
||||
CBofString str(localStr, 256);
|
||||
|
||||
getAlphaNumFromStream(istr, str);
|
||||
|
||||
if (!str.find("EXITATEND")) {
|
||||
istr.eatWhite();
|
||||
|
||||
_exitAtEnd = true;
|
||||
objectUpdatedFl = true;
|
||||
} else {
|
||||
putbackStringOnStream(istr, str);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// PANIM - Specifies if this object should be affected by the user
|
||||
// option Panimations On/Off
|
||||
case 'P': {
|
||||
CBofString str;
|
||||
|
||||
getAlphaNumFromStream(istr, str);
|
||||
|
||||
if (!str.find("PANIM")) {
|
||||
istr.eatWhite();
|
||||
|
||||
_pAnim = true;
|
||||
objectUpdatedFl = true;
|
||||
|
||||
} else {
|
||||
putbackStringOnStream(istr, str);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
// FRAME [start, end]- start and end frames of the move
|
||||
case 'F': {
|
||||
char localStr[256];
|
||||
localStr[0] = 0;
|
||||
CBofString str(localStr, 256);
|
||||
|
||||
getAlphaNumFromStream(istr, str);
|
||||
|
||||
if (!str.find("FRAME")) {
|
||||
CBofRect r;
|
||||
istr.eatWhite();
|
||||
|
||||
getRectFromStream(istr, r);
|
||||
|
||||
_startFrame = r.left;
|
||||
_endFrame = r.top;
|
||||
|
||||
if (r.width() && r.height()) {
|
||||
// error of some type
|
||||
}
|
||||
|
||||
objectUpdatedFl = true;
|
||||
} else {
|
||||
putbackStringOnStream(istr, str);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// No match return from function
|
||||
default: {
|
||||
const ParseCodes parseCode = CBagObject::setInfo(istr);
|
||||
if (parseCode == PARSING_DONE) {
|
||||
return PARSING_DONE;
|
||||
}
|
||||
|
||||
if (parseCode == UPDATED_OBJECT) {
|
||||
objectUpdatedFl = true;
|
||||
} else { // rc==UNKNOWN_TOKEN
|
||||
if (objectUpdatedFl)
|
||||
return UPDATED_OBJECT;
|
||||
|
||||
return UNKNOWN_TOKEN;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return PARSING_DONE;
|
||||
}
|
||||
|
||||
void CBagCharacterObject::arrangeFrames() {
|
||||
const int start = getStartFrame();
|
||||
const int end = getEndFrame();
|
||||
|
||||
if (_playbackSpeed < 0) {
|
||||
_startFrame = MAX(start, end);
|
||||
_endFrame = MIN(start, end);
|
||||
} else {
|
||||
_startFrame = MIN(start, end);
|
||||
_endFrame = MAX(start, end);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CBagCharacterObject::setNumOfLoops(int n) {
|
||||
_numOfLoops = n;
|
||||
if (_smacker != nullptr) {
|
||||
if (_numOfLoops != 0) {
|
||||
_smacker->start();
|
||||
} else {
|
||||
_smacker->stop();
|
||||
}
|
||||
}
|
||||
|
||||
// If this character is modal run until done looping
|
||||
if (isModal() && isAttached()) {
|
||||
CBagStorageDevWnd *win = CBagel::getBagApp()->getMasterWnd()->getCurrentStorageDev();
|
||||
|
||||
if (win != nullptr) {
|
||||
win->runModal(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CBagCharacterObject::setPlaybackSpeed(int n) {
|
||||
if (_playbackSpeed != n) {
|
||||
if (n < 0) {
|
||||
_startFrame++;
|
||||
_endFrame++;
|
||||
} else {
|
||||
_startFrame--;
|
||||
_endFrame--;
|
||||
}
|
||||
|
||||
_playbackSpeed = n;
|
||||
arrangeFrames();
|
||||
|
||||
int frame = getStartFrame();
|
||||
if (n < 0 && frame == (int)_smacker->getFrameCount()) {
|
||||
frame--; // HACK: Reverse rewind
|
||||
}
|
||||
setCurrentFrame(frame);
|
||||
}
|
||||
}
|
||||
|
||||
void CBagCharacterObject::setStartFrame(int n) {
|
||||
arrangeFrames();
|
||||
_startFrame = n;
|
||||
arrangeFrames();
|
||||
}
|
||||
|
||||
void CBagCharacterObject::setEndFrame(int n) {
|
||||
arrangeFrames();
|
||||
_endFrame = n;
|
||||
arrangeFrames();
|
||||
}
|
||||
|
||||
void CBagCharacterObject::setCurrentFrame(int n) {
|
||||
// Make sure that it is within specified values?
|
||||
//
|
||||
// Due to some distinctly bogus code that manipulates the
|
||||
// start and end frame, the current frame passed in can be negative, which
|
||||
// will cause slacker-smacker to go toes up, handle that here.
|
||||
|
||||
setFrame(n);
|
||||
|
||||
// Added updatePosition() because if any movies go backwards, and use
|
||||
// a .BIN file, then it would not have worked.
|
||||
updatePosition();
|
||||
|
||||
//refreshCurrentFrame();
|
||||
}
|
||||
|
||||
void CBagCharacterObject::setFrame(int n) {
|
||||
// Make sure that it is within specified values?
|
||||
if (_smacker != nullptr) {
|
||||
n--;
|
||||
n = CLIP<int>(n, 0, _smacker->getFrameCount() - 1);
|
||||
const Graphics::Surface *surf = _smacker->forceSeekToFrame(n);
|
||||
if (surf) {
|
||||
Graphics::ManagedSurface &destSurf = *_bmpBuf;
|
||||
|
||||
// Copy the decoded frame into the offscreen bitmap
|
||||
destSurf.setPalette(_smacker->getPalette(), 0, 256);
|
||||
destSurf.blitFrom(*surf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CBagCharacterObject::setProperty(const CBofString &prop, int val) {
|
||||
if (!prop.find("LOOP"))
|
||||
setNumOfLoops(val);
|
||||
else if (!prop.find("SPEED"))
|
||||
setPlaybackSpeed(val);
|
||||
else if (!prop.find("START_FRAME"))
|
||||
setStartFrame(val);
|
||||
else if (!prop.find("END_FRAME"))
|
||||
setEndFrame(val);
|
||||
else if (!prop.find("CURR_FRAME")) // This one will not work currently
|
||||
setCurrentFrame(val);
|
||||
else
|
||||
CBagObject::setProperty(prop, val);
|
||||
}
|
||||
|
||||
int CBagCharacterObject::getProperty(const CBofString &prop) {
|
||||
if (!prop.find("LOOP"))
|
||||
return getNumberOfLoops();
|
||||
|
||||
if (!prop.find("SPEED"))
|
||||
return getPlaybackSpeed();
|
||||
|
||||
if (!prop.find("START_FRAME"))
|
||||
return getStartFrame();
|
||||
|
||||
if (!prop.find("END_FRAME"))
|
||||
return getEndFrame();
|
||||
|
||||
if (!prop.find("CURR_FRAME")) // This one will not work currently
|
||||
return getCurrentFrame();
|
||||
|
||||
return CBagObject::getProperty(prop);
|
||||
}
|
||||
|
||||
void CBagCharacterObject::setPdaWand(CBagCharacterObject *pdaWand) {
|
||||
_pdaWand = pdaWand;
|
||||
}
|
||||
|
||||
bool CBagCharacterObject::pdaWandAnimating() {
|
||||
if (_pdaWand == nullptr || !_pdaWand->isAttached()) {
|
||||
CBagStorageDev *pda = g_SDevManager->getStorageDevice("BPDA_WLD");
|
||||
if (pda != nullptr) {
|
||||
CBagCharacterObject *wand = (CBagCharacterObject *)pda->getObject("WANDANIM");
|
||||
if (wand != nullptr) {
|
||||
CBagCharacterObject::setPdaWand(wand);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return _pdaAnimating;
|
||||
}
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
130
engines/bagel/spacebar/baglib/character_object.h
Normal file
130
engines/bagel/spacebar/baglib/character_object.h
Normal file
@@ -0,0 +1,130 @@
|
||||
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BAGEL_BAGLIB_BAG_CHARACTER_OBJECT_H
|
||||
#define BAGEL_BAGLIB_BAG_CHARACTER_OBJECT_H
|
||||
|
||||
#include "video/smk_decoder.h"
|
||||
#include "bagel/spacebar/baglib/object.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
class CBagCharacterObject : public CBagObject {
|
||||
protected:
|
||||
Video::SmackerDecoder *_smacker = nullptr;
|
||||
CBofBitmap *_bmpBuf = nullptr;
|
||||
int _charTransColor = 0;
|
||||
|
||||
char *_binBuf = nullptr;
|
||||
int32 _binBufLen = 0;
|
||||
|
||||
int _playbackSpeed = 0;
|
||||
int _numOfLoops = 0;
|
||||
int _startFrame = 0;
|
||||
int _endFrame = 0;
|
||||
|
||||
bool _exitAtEnd : 1;
|
||||
bool _firstFrame : 1;
|
||||
|
||||
bool _saveState : 1; // Flag to save the state/frame of the character
|
||||
bool _pAnim : 1; // If affected by Panimations On/Off setting
|
||||
|
||||
int _prevFrame = 0;
|
||||
|
||||
void setFrame(int n);
|
||||
|
||||
// Keep track of the PDA wand and the number of frames it has
|
||||
static CBagCharacterObject *_pdaWand;
|
||||
static bool _pdaAnimating;
|
||||
|
||||
public:
|
||||
CBagCharacterObject();
|
||||
virtual ~CBagCharacterObject();
|
||||
static void initialize();
|
||||
|
||||
// Return ERR_NONE if the Object had members that are properly initialized/de-initialized
|
||||
ErrorCode attach() override;
|
||||
ErrorCode detach() override;
|
||||
|
||||
CBofRect getRect() override;
|
||||
|
||||
ErrorCode update(CBofBitmap *bmp, CBofPoint pt, CBofRect *srcRect = nullptr, int maskColor = -1) override;
|
||||
|
||||
bool doAdvance();
|
||||
void updatePosition();
|
||||
bool refreshCurrentFrame();
|
||||
|
||||
bool runObject() override;
|
||||
bool isInside(const CBofPoint &point) override;
|
||||
|
||||
void arrangeFrames();
|
||||
|
||||
int getNumberOfLoops() const {
|
||||
return _numOfLoops;
|
||||
}
|
||||
int getPlaybackSpeed() const {
|
||||
return _playbackSpeed;
|
||||
}
|
||||
int getStartFrame() const {
|
||||
return _startFrame;
|
||||
}
|
||||
int getEndFrame() const {
|
||||
return _endFrame;
|
||||
}
|
||||
int getCurrentFrame() const {
|
||||
return (_smacker != nullptr) ? _smacker->getCurFrame() : -1;
|
||||
}
|
||||
|
||||
bool isModalDone() override {
|
||||
return !_numOfLoops;
|
||||
}
|
||||
|
||||
bool isPanim() const {
|
||||
return _pAnim;
|
||||
}
|
||||
|
||||
void setNumOfLoops(int n);
|
||||
void setPlaybackSpeed(int n);
|
||||
void setStartFrame(int n);
|
||||
void setEndFrame(int n);
|
||||
void setCurrentFrame(int n);
|
||||
|
||||
ParseCodes setInfo(CBagIfstream &istr) override;
|
||||
|
||||
void setProperty(const CBofString &prop, int val) override;
|
||||
int getProperty(const CBofString &prop) override;
|
||||
|
||||
// Remember the pda wand, we'll need to know about it and
|
||||
// it's total number of frames.
|
||||
static void setPdaWand(CBagCharacterObject *pdaWand);
|
||||
static bool pdaWandAnimating();
|
||||
|
||||
bool isStationary() const {
|
||||
return _binBuf != nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
|
||||
#endif
|
||||
79
engines/bagel/spacebar/baglib/chat_wnd.cpp
Normal file
79
engines/bagel/spacebar/baglib/chat_wnd.cpp
Normal file
@@ -0,0 +1,79 @@
|
||||
/* 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/chat_wnd.h"
|
||||
#include "bagel/spacebar/baglib/text_object.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
CBagChatWnd::CBagChatWnd() : CBagStorageDevWnd() {
|
||||
}
|
||||
|
||||
ErrorCode CBagChatWnd::attach() {
|
||||
assert(isValidObject(this));
|
||||
|
||||
if (CBagStorageDevWnd::attach() == ERR_NONE) {
|
||||
show();
|
||||
invalidateRect(nullptr);
|
||||
updateWindow();
|
||||
}
|
||||
|
||||
return _errCode;
|
||||
}
|
||||
|
||||
void CBagChatWnd::onTimer(uint32 /*nTimerId*/) {
|
||||
assert(isValidObject(this));
|
||||
}
|
||||
|
||||
void CBagChatWnd::onMouseMove(uint32 flags, CBofPoint *pos, void *) {
|
||||
assert(isValidObject(this));
|
||||
assert(pos != nullptr);
|
||||
|
||||
// Use default behavior 1st
|
||||
CBagStorageDevWnd::onMouseMove(flags, pos);
|
||||
|
||||
// If over a chat choice, then highlight it
|
||||
CBofList<CBagObject *> *bagObjectList = getObjectList();
|
||||
|
||||
// Run through background object list and find if the cursor is over an object
|
||||
if (bagObjectList != nullptr) {
|
||||
// Go through list backwards to find the 1st top-most object
|
||||
CBofListNode<CBagObject *> *currNode = bagObjectList->getTail();
|
||||
while (currNode != nullptr) {
|
||||
CBagObject *currNodeItem = currNode->getNodeItem();
|
||||
|
||||
if (currNodeItem->getType() == TEXT_OBJ) {
|
||||
((CBagTextObject *)currNodeItem)->setColor(4);
|
||||
currNodeItem->setDirty(true);
|
||||
|
||||
if (currNodeItem->isAttached() && currNodeItem->isInside(*pos)) {
|
||||
((CBagTextObject *)currNodeItem)->setColor(8);
|
||||
}
|
||||
}
|
||||
|
||||
currNode = currNode->_pPrev;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
47
engines/bagel/spacebar/baglib/chat_wnd.h
Normal file
47
engines/bagel/spacebar/baglib/chat_wnd.h
Normal file
@@ -0,0 +1,47 @@
|
||||
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BAGEL_BAGLIB_CHAT_WND_H
|
||||
#define BAGEL_BAGLIB_CHAT_WND_H
|
||||
|
||||
#include "bagel/spacebar/baglib/storage_dev_win.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
class CBagChatWnd : public CBagStorageDevWnd {
|
||||
public:
|
||||
CBagChatWnd();
|
||||
|
||||
/**
|
||||
* Called to overload new set backgrounds. Calls the set backdrop pure
|
||||
* virtual function by default.
|
||||
*/
|
||||
ErrorCode attach() override;
|
||||
void onTimer(uint32 timerId) override;
|
||||
void onMouseMove(uint32 flags, CBofPoint *pos, void * = nullptr) override;
|
||||
};
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
|
||||
#endif
|
||||
493
engines/bagel/spacebar/baglib/command_object.cpp
Normal file
493
engines/bagel/spacebar/baglib/command_object.cpp
Normal file
@@ -0,0 +1,493 @@
|
||||
/* 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 "gui/debugger.h"
|
||||
#include "bagel/spacebar/baglib/command_object.h"
|
||||
#include "bagel/spacebar/baglib/dossier_object.h"
|
||||
#include "bagel/spacebar/baglib/rp_object.h"
|
||||
#include "bagel/spacebar/baglib/master_win.h"
|
||||
#include "bagel/spacebar/baglib/storage_dev_win.h"
|
||||
#include "bagel/spacebar/boflib/gui/movie.h"
|
||||
#include "bagel/spacebar/baglib/dev_dlg.h"
|
||||
#include "bagel/spacebar/baglib/pan_window.h"
|
||||
#include "bagel/boflib/sound.h"
|
||||
#include "bagel/bagel.h"
|
||||
#include "bagel/boflib/file_functions.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
extern bool g_restoreObjectListFl;
|
||||
extern bool g_allowattachActiveObjectsFl;
|
||||
|
||||
CBagCommandObject::CBagCommandObject() {
|
||||
_xObjType = COMMAND_OBJ;
|
||||
setVisible(false);
|
||||
setTimeless(true);
|
||||
}
|
||||
|
||||
bool CBagCommandObject::runObject() {
|
||||
static int iteration = 0;
|
||||
bool rc = false;
|
||||
|
||||
// Don't allow more than 10 (recursively)
|
||||
if (iteration < 10) {
|
||||
iteration++;
|
||||
|
||||
CBofString srcSDev = _srcSDev;
|
||||
CBofString dstSDev = _destSDev;
|
||||
|
||||
// Check if these items should be replaced by the current sdev
|
||||
if (!srcSDev.isEmpty() && !srcSDev.find(CURRSDEV_TOKEN)) {
|
||||
srcSDev = CBagel::getBagApp()->getMasterWnd()->getCurrentStorageDev()->getName();
|
||||
}
|
||||
|
||||
if (!dstSDev.isEmpty() && !dstSDev.find(CURRSDEV_TOKEN)) {
|
||||
dstSDev = CBagel::getBagApp()->getMasterWnd()->getCurrentStorageDev()->getName();
|
||||
}
|
||||
|
||||
// Check if these items should be replaced by the previous sdev
|
||||
if (!srcSDev.isEmpty() && !srcSDev.find(PREVSDEV_TOKEN)) {
|
||||
srcSDev = CBagel::getBagApp()->getMasterWnd()->getCurrentStorageDev()->getPrevSDev();
|
||||
}
|
||||
|
||||
if (!dstSDev.isEmpty() && !dstSDev.find(PREVSDEV_TOKEN)) {
|
||||
dstSDev = CBagel::getBagApp()->getMasterWnd()->getCurrentStorageDev()->getPrevSDev();
|
||||
}
|
||||
|
||||
if (getFileName() == "REMOVE") {
|
||||
static bool removeFl = false;
|
||||
if (!removeFl) {
|
||||
removeFl = true;
|
||||
|
||||
if (!_objName.isEmpty() && !srcSDev.isEmpty()) {
|
||||
g_SDevManager->removeObject(srcSDev, _objName);
|
||||
}
|
||||
removeFl = false;
|
||||
}
|
||||
|
||||
} else if (getFileName() == "INSERT2") {
|
||||
if (!_objName.isEmpty() && !dstSDev.isEmpty()) {
|
||||
g_allowattachActiveObjectsFl = false;
|
||||
g_SDevManager->addObject(dstSDev, _objName);
|
||||
g_allowattachActiveObjectsFl = true;
|
||||
}
|
||||
|
||||
} else if (getFileName() == "INSERT") {
|
||||
if (!_objName.isEmpty() && !dstSDev.isEmpty()) {
|
||||
g_SDevManager->addObject(dstSDev, _objName);
|
||||
}
|
||||
|
||||
} else if (getFileName() == "TRANSFER") {
|
||||
|
||||
if (!_objName.isEmpty() && !srcSDev.isEmpty() && !dstSDev.isEmpty()) {
|
||||
g_SDevManager->moveObject(dstSDev, srcSDev, _objName);
|
||||
}
|
||||
|
||||
} else if (getFileName().find("FLUSHQUEUE") == 0) {
|
||||
char buffer[20];
|
||||
int slot;
|
||||
|
||||
slot = 0;
|
||||
Common::strcpy_s(buffer, getFileName());
|
||||
if (strlen(buffer) == 11) {
|
||||
slot = buffer[10] - 48;
|
||||
}
|
||||
assert(slot >= 0 && slot < 8);
|
||||
|
||||
} else if (getFileName() == "CLOSE") {
|
||||
CBagStorageDevWnd *currentSDev = CBagel::getBagApp()->getMasterWnd()->getCurrentStorageDev();
|
||||
currentSDev->close();
|
||||
|
||||
} else if (getFileName() == "UPDATE") {
|
||||
static bool updateFl = false;
|
||||
|
||||
if (!updateFl) {
|
||||
updateFl = true;
|
||||
|
||||
CBagStorageDevWnd *currentSDev = CBagel::getBagApp()->getMasterWnd()->getCurrentStorageDev();
|
||||
currentSDev->attachActiveObjects();
|
||||
|
||||
updateFl = false;
|
||||
}
|
||||
|
||||
} else if (getFileName() == "EVENTLOOP") {
|
||||
static bool eventLoopFl = false;
|
||||
|
||||
// prevent recursion
|
||||
//
|
||||
if (!eventLoopFl) {
|
||||
eventLoopFl = true;
|
||||
|
||||
CBagStorageDev *currSDev = CBagel::getBagApp()->getMasterWnd()->getCurrentStorageDev();
|
||||
if (currSDev != nullptr) {
|
||||
if (currSDev->getDeviceType() == SDEV_GAMEWIN) {
|
||||
CBagPanWindow *panWin = (CBagPanWindow *)currSDev;
|
||||
panWin->onTimer(EVAL_EXPR);
|
||||
}
|
||||
}
|
||||
eventLoopFl = false;
|
||||
}
|
||||
|
||||
} else if (getFileName() == "STOPPAINT") {
|
||||
g_allowPaintFl = false;
|
||||
|
||||
} else if (getFileName() == "REMOVEWIELD") {
|
||||
// Remove currently wielded object from the game
|
||||
if (CBagPanWindow::_pWieldBmp != nullptr) {
|
||||
CBagObject *currObj = CBagPanWindow::_pWieldBmp->getCurrObj();
|
||||
if (currObj != nullptr) {
|
||||
g_SDevManager->removeObject(CBagPanWindow::_pWieldBmp->getName(), currObj->getRefName());
|
||||
}
|
||||
}
|
||||
|
||||
} else if (getFileName() == "PAINT") {
|
||||
// Get a pointer to the current game window
|
||||
CBagStorageDevWnd *gameWin = CBagel::getBagApp()->getMasterWnd()->getCurrentStorageDev();
|
||||
|
||||
if (gameWin != nullptr) {
|
||||
gameWin->paintScreen(nullptr);
|
||||
}
|
||||
|
||||
} else if (getFileName() == "STOPWAVE") {
|
||||
CBofSound::stopWaveSounds();
|
||||
|
||||
} else if (getFileName() == "STASHWIELD") {
|
||||
// Stash the currently wielded item
|
||||
if (CBagPanWindow::_pWieldBmp != nullptr) {
|
||||
CBagObject *currObj = CBagPanWindow::_pWieldBmp->getCurrObj();
|
||||
if (currObj != nullptr) {
|
||||
g_SDevManager->moveObject("INV_WLD", CBagPanWindow::_pWieldBmp->getName(), currObj->getRefName());
|
||||
CBagPanWindow::_pWieldBmp->setCurrObj(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
} else if (getFileName() == "DEATH") {
|
||||
CBagel::getBagApp()->getMasterWnd()->postUserMessage(WM_DIE, 0);
|
||||
g_allowPaintFl = false;
|
||||
|
||||
} else if (getFileName() == "GOPAINT") {
|
||||
g_allowPaintFl = true;
|
||||
|
||||
} else if (getFileName() == "DEACTIVATEPDA") {
|
||||
|
||||
// Get a pointer to the current game window
|
||||
CBagStorageDevWnd *gameWin = (CBagel::getBagApp()->getMasterWnd()->getCurrentStorageDev());
|
||||
|
||||
// Pull down the PDA (if it exists)
|
||||
if (gameWin->getDeviceType() == SDEV_GAMEWIN) {
|
||||
((CBagPanWindow *)gameWin)->deactivatePDA();
|
||||
((CBagPanWindow *)gameWin)->waitForPDA();
|
||||
}
|
||||
|
||||
} else if (getFileName() == "ROTATETOFLY") {
|
||||
if (CBagMasterWin::getFlyThru()) {
|
||||
CBagMasterWin::setActiveCursor(6);
|
||||
CBagStorageDev *currSDev = CBagel::getBagApp()->getMasterWnd()->getCurrentStorageDev();
|
||||
if ((currSDev != nullptr) && (currSDev->getDeviceType() == SDEV_GAMEWIN)) {
|
||||
CBagPanWindow *currWin = (CBagPanWindow *)currSDev;
|
||||
CBofPoint loc = getPosition();
|
||||
currWin->rotateTo(loc);
|
||||
}
|
||||
}
|
||||
|
||||
} else if (getFileName() == "ROTATETO") {
|
||||
CBagMasterWin::setActiveCursor(6);
|
||||
CBagStorageDev *currSDev = CBagel::getBagApp()->getMasterWnd()->getCurrentStorageDev();
|
||||
if ((currSDev != nullptr) && (currSDev->getDeviceType() == SDEV_GAMEWIN)) {
|
||||
CBagPanWindow *currWin = (CBagPanWindow *)currSDev;
|
||||
CBofPoint loc = getPosition();
|
||||
currWin->rotateTo(loc);
|
||||
}
|
||||
|
||||
} else if (getFileName() == "SETQVOL") {
|
||||
CBofSound::setQVol(getPosition().x, getPosition().y);
|
||||
|
||||
} else if (getFileName() == "TURN") {
|
||||
|
||||
// Cause 1 turn to go by
|
||||
g_VarManager->incrementTimers();
|
||||
|
||||
} else if (getFileName() == "RP_UPDATE_QUEUE") {
|
||||
// Execute any waiting residue printing results.
|
||||
CBagRPObject::updateResiduePrintedQueue();
|
||||
|
||||
} else if (getFileName() == "RP_RUN_QUEUE") {
|
||||
// Execute any waiting residue printing results.
|
||||
CBagRPObject::runResiduePrintedQueue();
|
||||
|
||||
} else if (getFileName() == "RP_DEACTIVATE_RESULTS") {
|
||||
// Execute any waiting residue printing results.
|
||||
CBagRPObject::deactivateResiduePrintedQueue();
|
||||
|
||||
} else if (getFileName() == "RP_DEACTIVATE_REVIEW") {
|
||||
// Execute any waiting residue printing results.
|
||||
CBagRPObject::deactivateResiduePrintedReview();
|
||||
|
||||
} else if (getFileName() == "RP_DEACTIVATE_DOSSIER") {
|
||||
// Execute any waiting residue printing results.
|
||||
CBagDossierObject::deactivateCurDossier();
|
||||
|
||||
} else if (getFileName() == "RP_ACTIVATE_REVIEW") {
|
||||
// Execute any waiting residue printing results.
|
||||
CBagRPObject::activateResiduePrintedReview();
|
||||
|
||||
} else if (getFileName() == "SAVESTACK") {
|
||||
CBagMasterWin *pWin = CBagel::getBagApp()->getMasterWnd();
|
||||
|
||||
if (pWin != nullptr) {
|
||||
pWin->saveSDevStack();
|
||||
}
|
||||
|
||||
} else if (getFileName() == "DEATH2") {
|
||||
CBagel::getBagApp()->getMasterWnd()->postUserMessage(WM_DIE, 2);
|
||||
g_allowPaintFl = false;
|
||||
|
||||
} else if (getFileName() == "ENTRYTHUD") { // Thud
|
||||
CBofRect tmpRect(60, 50, 137, 70);
|
||||
CBofString bmpName("$SBARDIR\\GENERAL\\POPUP\\THUDPOP.BMP");
|
||||
fixPathName(bmpName);
|
||||
CDevDlg dlg;
|
||||
dlg.createWindow(bmpName, CBagel::getBagApp()->getMasterWnd(), CBofApp::getApp()->getPalette(), &tmpRect, false);
|
||||
dlg.doModal();
|
||||
dlg.destroy();
|
||||
|
||||
} else if (getFileName() == "ENTRYFLEE") { // Fleebix
|
||||
CBofRect tmpRect(35, 48, 114, 69);
|
||||
CBofString bmpName("$SBARDIR\\GENERAL\\POPUP\\FLEEDAT.BMP");
|
||||
fixPathName(bmpName);
|
||||
CDevDlg dlg;
|
||||
dlg.createWindow(bmpName, CBagel::getBagApp()->getMasterWnd(), CBofApp::getApp()->getPalette(), &tmpRect, false);
|
||||
dlg.doModal();
|
||||
dlg.destroy();
|
||||
|
||||
} else if (getFileName() == "ENTRYCLICK") { // Click's locker combo
|
||||
CBofRect tmpRect(60, 49, 138, 68);
|
||||
CBofString bmpName("$SBARDIR\\GENERAL\\POPUP\\CLICKPOP.BMP");
|
||||
fixPathName(bmpName);
|
||||
CDevDlg dlg;
|
||||
dlg.createWindow(bmpName, CBagel::getBagApp()->getMasterWnd(), CBofApp::getApp()->getPalette(), &tmpRect, false);
|
||||
dlg.doModal();
|
||||
dlg.destroy();
|
||||
|
||||
} else if (getFileName() == "ENTRYFRUIT") { // MegaWave the fruit
|
||||
CBofRect tmpRect(35, 49, 114, 68);
|
||||
CBofString bmpName("$SBARDIR\\GENERAL\\POPUP\\CLICKDAT.BMP");
|
||||
fixPathName(bmpName);
|
||||
CDevDlg dlg;
|
||||
dlg.createWindow(bmpName, CBagel::getBagApp()->getMasterWnd(), CBofApp::getApp()->getPalette(), &tmpRect, false);
|
||||
dlg.doModal();
|
||||
dlg.destroy();
|
||||
|
||||
} else if (getFileName() == "D7CODE1DLG") { // Deven-7 code word
|
||||
CBofRect tmpRect(10, 48, 189, 69);
|
||||
CBofString bmpName("$SBARDIR\\GENERAL\\POPUP\\DEVENPOP.BMP");
|
||||
fixPathName(bmpName);
|
||||
CDevDlg dlg;
|
||||
dlg.createWindow(bmpName, CBagel::getBagApp()->getMasterWnd(), CBofApp::getApp()->getPalette(), &tmpRect, true);
|
||||
dlg.doModal();
|
||||
dlg.destroy();
|
||||
|
||||
} else if (getFileName() == "SNAPTO") {
|
||||
CBagStorageDev *currSDev = CBagel::getBagApp()->getMasterWnd()->getCurrentStorageDev();
|
||||
if ((currSDev != nullptr) && (currSDev->getDeviceType() == SDEV_GAMEWIN)) {
|
||||
CBagPanWindow *currWin = (CBagPanWindow *)currSDev;
|
||||
|
||||
if (currWin->getSlideBitmap() != nullptr) {
|
||||
int x = getPosition().x;
|
||||
int y = getPosition().y;
|
||||
|
||||
CBofRect cRect;
|
||||
cRect.setRect(x, y, x + 480 - 1, y + 360 - 1);
|
||||
currWin->getSlideBitmap()->setCurrView(cRect);
|
||||
}
|
||||
}
|
||||
|
||||
} else if (getFileName() == "RESUMESOUND") {
|
||||
CBofSound::resumeSounds();
|
||||
|
||||
} else if (getFileName() == "PAUSESOUND") {
|
||||
CBofSound::pauseSounds();
|
||||
|
||||
} else if (getFileName() == "STOPMIDI") {
|
||||
CBofSound::stopMidiSounds();
|
||||
|
||||
} else if (getFileName() == "WAITWAVE") {
|
||||
CBofSound::waitWaveSounds();
|
||||
|
||||
} else if (getFileName() == "WAITMIDI") {
|
||||
CBofSound::waitMidiSounds();
|
||||
|
||||
} else if (getFileName() == "ACTIVATEPDA") {
|
||||
// Get a pointer to the current game window
|
||||
CBagStorageDevWnd *mainWin = (CBagel::getBagApp()->getMasterWnd()->getCurrentStorageDev());
|
||||
// Pull up the PDA (if it exists)
|
||||
//
|
||||
if (mainWin->getDeviceType() == SDEV_GAMEWIN) {
|
||||
((CBagPanWindow *)mainWin)->activatePDA();
|
||||
((CBagPanWindow *)mainWin)->waitForPDA();
|
||||
}
|
||||
|
||||
} else if (getFileName() == "SHOWPDALOG") {
|
||||
// Get a pointer to the current game window
|
||||
CBagPDA *pda = (CBagPDA *)g_SDevManager->getStorageDevice("BPDA_WLD");
|
||||
if (pda) {
|
||||
pda->showLog();
|
||||
}
|
||||
|
||||
} else if (getFileName() == "OBJLIST") {
|
||||
g_restoreObjectListFl = false;
|
||||
|
||||
} else if (getFileName() == "WIN") {
|
||||
CBagMasterWin *mainWin = CBagel::getBagApp()->getMasterWnd();
|
||||
|
||||
if (mainWin != nullptr) {
|
||||
CBofBitmap bmp(640, 480, CBofApp::getApp()->getPalette());
|
||||
bmp.fillRect(nullptr, COLOR_BLACK);
|
||||
|
||||
bmp.paint(mainWin, 0, 0);
|
||||
g_allowPaintFl = false;
|
||||
|
||||
CBofString smkName("$SBARDIR\\BAR\\EVGAMWIN.SMK");
|
||||
fixPathName(smkName);
|
||||
|
||||
// Play the movie only if it exists
|
||||
if (fileExists(smkName.getBuffer())) {
|
||||
bofPlayMovie(mainWin, smkName.getBuffer());
|
||||
bmp.paint(mainWin, 0, 0);
|
||||
}
|
||||
|
||||
// Display Credits
|
||||
mainWin->showCreditsDialog(mainWin);
|
||||
|
||||
// Exit the game
|
||||
CBagel::getBagApp()->getMasterWnd()->close();
|
||||
}
|
||||
|
||||
g_engine->quitGame();
|
||||
|
||||
} else if (getFileName() == "BREAK") {
|
||||
// As far as I'm aware, this can't actually happen in the game,
|
||||
// but what the heck, ScummVM has a console, let's hook it up
|
||||
g_engine->getDebugger()->attach();
|
||||
|
||||
} else {
|
||||
reportError(ERR_UNKNOWN, "Invalid RUN COMMAND = %s", (const char *)getFileName());
|
||||
}
|
||||
|
||||
rc = CBagObject::runObject();
|
||||
|
||||
iteration--;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
ParseCodes CBagCommandObject::setInfo(CBagIfstream &istr) {
|
||||
bool objectUpdatedFl = false;
|
||||
|
||||
while (!istr.eof()) {
|
||||
istr.eatWhite();
|
||||
|
||||
const char ch = (char)istr.peek();
|
||||
switch (ch) {
|
||||
//
|
||||
// OBJECT
|
||||
//
|
||||
case 'O': {
|
||||
char localBuffer[256];
|
||||
localBuffer[0] = 0;
|
||||
CBofString curStr(localBuffer, 256);
|
||||
getAlphaNumFromStream(istr, curStr);
|
||||
|
||||
if (!curStr.find("OBJECT")) {
|
||||
istr.eatWhite();
|
||||
getAlphaNumFromStream(istr, _objName);
|
||||
objectUpdatedFl = true;
|
||||
} else {
|
||||
putbackStringOnStream(istr, curStr);
|
||||
}
|
||||
break;
|
||||
}
|
||||
//
|
||||
// FROM
|
||||
//
|
||||
case 'F': {
|
||||
char localBuffer[256];
|
||||
localBuffer[0] = 0;
|
||||
CBofString curStr(localBuffer, 256);
|
||||
getAlphaNumFromStream(istr, curStr);
|
||||
|
||||
if (!curStr.find("FROM")) {
|
||||
istr.eatWhite();
|
||||
getAlphaNumFromStream(istr, _srcSDev);
|
||||
objectUpdatedFl = true;
|
||||
} else {
|
||||
putbackStringOnStream(istr, curStr);
|
||||
}
|
||||
break;
|
||||
}
|
||||
//
|
||||
// TO
|
||||
//
|
||||
case 'T': {
|
||||
char localBuffer[256];
|
||||
localBuffer[0] = 0;
|
||||
CBofString curStr(localBuffer, 256);
|
||||
getAlphaNumFromStream(istr, curStr);
|
||||
|
||||
if (!curStr.find("TO")) {
|
||||
istr.eatWhite();
|
||||
getAlphaNumFromStream(istr, _destSDev);
|
||||
objectUpdatedFl = true;
|
||||
} else {
|
||||
putbackStringOnStream(istr, curStr);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
// No match return from function
|
||||
//
|
||||
default: {
|
||||
const ParseCodes parseCode = CBagObject::setInfo(istr);
|
||||
if (parseCode == PARSING_DONE) {
|
||||
return PARSING_DONE;
|
||||
}
|
||||
|
||||
if (parseCode == UPDATED_OBJECT) {
|
||||
objectUpdatedFl = true;
|
||||
} else { // rc==UNKNOWN_TOKEN
|
||||
if (objectUpdatedFl)
|
||||
return UPDATED_OBJECT;
|
||||
|
||||
return UNKNOWN_TOKEN;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return PARSING_DONE;
|
||||
}
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
55
engines/bagel/spacebar/baglib/command_object.h
Normal file
55
engines/bagel/spacebar/baglib/command_object.h
Normal file
@@ -0,0 +1,55 @@
|
||||
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BAGEL_BAGLIB_BAG_COMMAND_OBJECT_H
|
||||
#define BAGEL_BAGLIB_BAG_COMMAND_OBJECT_H
|
||||
|
||||
#include "bagel/spacebar/baglib/object.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
/**
|
||||
* CBagCommandObject transfers objects from one location to another
|
||||
*/
|
||||
class CBagCommandObject : public CBagObject {
|
||||
private:
|
||||
CBofString _objName;
|
||||
CBofString _srcSDev;
|
||||
CBofString _destSDev;
|
||||
|
||||
public:
|
||||
CBagCommandObject();
|
||||
|
||||
/**
|
||||
* Takes in info and then removes the relative information
|
||||
* and returns the info without the relevant info.
|
||||
*/
|
||||
ParseCodes setInfo(CBagIfstream &istr) override;
|
||||
|
||||
bool runObject() override;
|
||||
};
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
|
||||
#endif
|
||||
140
engines/bagel/spacebar/baglib/cursor.cpp
Normal file
140
engines/bagel/spacebar/baglib/cursor.cpp
Normal file
@@ -0,0 +1,140 @@
|
||||
/* 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 "graphics/cursorman.h"
|
||||
#include "bagel/spacebar/baglib/cursor.h"
|
||||
#include "bagel/boflib/cursor_data.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
CBagCursor *CBagCursor::_currentCursor;
|
||||
CSystemCursor *CBagCursor::_systemCursor;
|
||||
|
||||
void CBagCursor::initialize() {
|
||||
_currentCursor = nullptr;
|
||||
_systemCursor = new CSystemCursor();
|
||||
}
|
||||
|
||||
void CBagCursor::shutdown() {
|
||||
delete _systemCursor;
|
||||
}
|
||||
|
||||
void CBagCursor::showSystemCursor() {
|
||||
_systemCursor->setCurrent();
|
||||
}
|
||||
|
||||
|
||||
CBagCursor::CBagCursor() {
|
||||
_bitmap = nullptr;
|
||||
_x = 0;
|
||||
_y = 0;
|
||||
_sharedPalFl = false;
|
||||
|
||||
// Default is that this is not a wielded cursor
|
||||
setWieldCursor(false);
|
||||
}
|
||||
|
||||
CBagCursor::CBagCursor(CBofBitmap *bmp) {
|
||||
_bitmap = nullptr;
|
||||
_x = 0;
|
||||
_y = 0;
|
||||
_sharedPalFl = false;
|
||||
|
||||
load(bmp);
|
||||
|
||||
// Default is that this is not a wielded cursor
|
||||
setWieldCursor(false);
|
||||
}
|
||||
|
||||
CBagCursor::CBagCursor(const char *fileName, bool sharedPalFl) {
|
||||
assert(fileName != nullptr);
|
||||
|
||||
_bitmap = nullptr;
|
||||
_x = 0;
|
||||
_y = 0;
|
||||
_sharedPalFl = sharedPalFl;
|
||||
strncpy(_fileName, fileName, MAX_FNAME - 1);
|
||||
|
||||
// Default is that this is not a wielded cursor
|
||||
setWieldCursor(false);
|
||||
}
|
||||
|
||||
CBagCursor::~CBagCursor() {
|
||||
assert(isValidObject(this));
|
||||
|
||||
unLoad();
|
||||
}
|
||||
|
||||
void CBagCursor::setHotspot(int x, int y) {
|
||||
_x = x;
|
||||
_y = y;
|
||||
}
|
||||
|
||||
CBofPoint CBagCursor::getHotspot() const {
|
||||
return CBofPoint(_x, _y);
|
||||
}
|
||||
|
||||
ErrorCode CBagCursor::load(CBofBitmap *bmp) {
|
||||
assert(isValidObject(this));
|
||||
assert(bmp != nullptr);
|
||||
|
||||
unLoad();
|
||||
|
||||
_bitmap = bmp;
|
||||
|
||||
return _errCode;
|
||||
}
|
||||
|
||||
ErrorCode CBagCursor::load(const char *fileName, CBofPalette *pal) {
|
||||
assert(isValidObject(this));
|
||||
assert(fileName != nullptr);
|
||||
|
||||
unLoad();
|
||||
|
||||
_bitmap = loadBitmap(fileName, pal, _sharedPalFl);
|
||||
|
||||
return _errCode;
|
||||
}
|
||||
|
||||
void CBagCursor::unLoad() {
|
||||
assert(isValidObject(this));
|
||||
|
||||
delete _bitmap;
|
||||
_bitmap = nullptr;
|
||||
}
|
||||
|
||||
void CBagCursor::setCurrent() {
|
||||
_currentCursor = this;
|
||||
CursorMan.replaceCursorPalette(_bitmap->getPalette()->getData(), 0, Graphics::PALETTE_COUNT);
|
||||
CursorMan.replaceCursor(_bitmap->getSurface(), _x, _y, 1);
|
||||
}
|
||||
|
||||
void CSystemCursor::setCurrent() {
|
||||
_currentCursor = this;
|
||||
|
||||
Graphics::PixelFormat format = Graphics::PixelFormat::createFormatCLUT8();
|
||||
CursorMan.replaceCursorPalette(CURSOR_PALETTE, 0, ARRAYSIZE(CURSOR_PALETTE) / 3);
|
||||
CursorMan.replaceCursor(ARROW_CURSOR, CURSOR_W, CURSOR_H, 0, 0, 0, true, &format);
|
||||
}
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
131
engines/bagel/spacebar/baglib/cursor.h
Normal file
131
engines/bagel/spacebar/baglib/cursor.h
Normal file
@@ -0,0 +1,131 @@
|
||||
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BAGEL_BAGLIB_CURSOR_H
|
||||
#define BAGEL_BAGLIB_CURSOR_H
|
||||
|
||||
#include "bagel/spacebar/boflib/gfx/bitmap.h"
|
||||
#include "bagel/boflib/error.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
class CSystemCursor;
|
||||
|
||||
class CBagCursor : public CBofObject, public CBofError {
|
||||
private:
|
||||
char _fileName[MAX_FNAME];
|
||||
CBofBitmap *_bitmap;
|
||||
int _x;
|
||||
int _y;
|
||||
bool _sharedPalFl;
|
||||
bool _wieldCursorFl;
|
||||
|
||||
protected:
|
||||
static CBagCursor *_currentCursor;
|
||||
static CSystemCursor *_systemCursor;
|
||||
|
||||
public:
|
||||
CBagCursor();
|
||||
CBagCursor(CBofBitmap *bmp);
|
||||
CBagCursor(const char *fileName, bool sharedPalFl = false);
|
||||
static void initialize();
|
||||
static void shutdown();
|
||||
static void showSystemCursor();
|
||||
static void hideSystemCursor() {
|
||||
_currentCursor = nullptr;
|
||||
}
|
||||
|
||||
~CBagCursor();
|
||||
|
||||
void setHotspot(int x, int y);
|
||||
|
||||
CBofPoint getHotspot() const;
|
||||
|
||||
int getX() const {
|
||||
return _x;
|
||||
}
|
||||
int getY() const {
|
||||
return _y;
|
||||
}
|
||||
|
||||
ErrorCode load() {
|
||||
return load(_fileName);
|
||||
}
|
||||
ErrorCode load(CBofBitmap *bmp);
|
||||
ErrorCode load(const char *fileName, CBofPalette *pal = nullptr);
|
||||
|
||||
void unLoad();
|
||||
|
||||
CBofBitmap *getImage() const {
|
||||
return _bitmap;
|
||||
}
|
||||
ErrorCode setImage(CBofBitmap *bmp) {
|
||||
return load(bmp);
|
||||
}
|
||||
|
||||
static CBagCursor *getCurrent() {
|
||||
return _currentCursor;
|
||||
}
|
||||
|
||||
static bool isSystemCursorVisible() {
|
||||
return _currentCursor && _currentCursor->isSystemCursor();
|
||||
}
|
||||
|
||||
/**
|
||||
* Flag whether this is a wielded cursor or not
|
||||
*/
|
||||
void setWieldCursor(bool b) {
|
||||
_wieldCursorFl = b;
|
||||
}
|
||||
bool IsWieldCursor() const {
|
||||
return _wieldCursorFl;
|
||||
}
|
||||
|
||||
void show() {
|
||||
setCurrent();
|
||||
}
|
||||
void hide() {
|
||||
_currentCursor = nullptr;
|
||||
}
|
||||
|
||||
virtual void setCurrent();
|
||||
virtual bool isSystemCursor() const {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
class CSystemCursor : public CBagCursor {
|
||||
public:
|
||||
CSystemCursor() : CBagCursor() {
|
||||
}
|
||||
|
||||
void setCurrent() override;
|
||||
bool isSystemCursor() const override {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
|
||||
#endif
|
||||
196
engines/bagel/spacebar/baglib/dev_dlg.cpp
Normal file
196
engines/bagel/spacebar/baglib/dev_dlg.cpp
Normal file
@@ -0,0 +1,196 @@
|
||||
/* 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/dev_dlg.h"
|
||||
#include "bagel/spacebar/baglib/master_win.h"
|
||||
#include "bagel/spacebar/baglib/pan_window.h"
|
||||
#include "bagel/spacebar/baglib/bagel.h"
|
||||
#include "bagel/spacebar/boflib/std_keys.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
#define MENU_DFLT_HEIGHT 20
|
||||
|
||||
CDevDlg::CDevDlg(int nButtonX, int buttonY) {
|
||||
_titleText = nullptr;
|
||||
_guessText = nullptr;
|
||||
_buttonX = nButtonX;
|
||||
_buttonY = buttonY;
|
||||
_achGuess[0] = '\0';
|
||||
_guessCount = 0;
|
||||
_useExtraFl = false;
|
||||
}
|
||||
|
||||
CDevDlg::~CDevDlg() {
|
||||
delete _titleText;
|
||||
_titleText = nullptr;
|
||||
}
|
||||
|
||||
ErrorCode CDevDlg::createWindow(const char *bmp, CBofWindow *wnd, CBofPalette *pal, CBofRect *rect, bool useExtraFl) {
|
||||
assert(isValidObject(this));
|
||||
assert(bmp != nullptr);
|
||||
assert(wnd != nullptr);
|
||||
assert(pal != nullptr);
|
||||
assert(rect != nullptr);
|
||||
|
||||
_useExtraFl = useExtraFl;
|
||||
_guessText = new CBofText();
|
||||
_guessText->setupText(rect, JUSTIFY_LEFT);
|
||||
_guessCount = 0;
|
||||
|
||||
Common::fill(_achGuess, _achGuess + ACH_GUESS_MAX_CHARS, 0);
|
||||
|
||||
CBofBitmap *bitmap = nullptr;
|
||||
|
||||
if (bmp != nullptr)
|
||||
bitmap = new CBofBitmap(bmp, pal);
|
||||
|
||||
// Fall back to original dialog on failure
|
||||
if (bitmap == nullptr) {
|
||||
bitmap = new CBofBitmap(200, 100, pal);
|
||||
assert(pal != nullptr);
|
||||
|
||||
bitmap->fillRect(nullptr, pal->getNearestIndex(RGB(92, 92, 92)));
|
||||
|
||||
CBofRect bmpRect(bitmap->getRect());
|
||||
bitmap->drawRect(&bmpRect, pal->getNearestIndex(RGB(0, 0, 0)));
|
||||
bitmap->fillRect(rect, pal->getNearestIndex(RGB(255, 255, 255)));
|
||||
}
|
||||
|
||||
CBofRect bmpRect(bitmap->getRect());
|
||||
const CBofString className = "CDevDlg";
|
||||
CBagStorageDevDlg::create(className, &bmpRect, wnd, 0);
|
||||
center();
|
||||
setBackdrop(bitmap);
|
||||
|
||||
return _errCode;
|
||||
}
|
||||
|
||||
void CDevDlg::onLButtonUp(uint32 /*nFlags*/, CBofPoint */*pPoint*/, void *) {
|
||||
}
|
||||
|
||||
void CDevDlg::onMouseMove(uint32 /*nFlags*/, CBofPoint */*pPoint*/, void *) {
|
||||
}
|
||||
|
||||
void CDevDlg::onClose() {
|
||||
assert(isValidObject(this));
|
||||
|
||||
CBagVar *varDialogReturn = g_VarManager->getVariable("DIALOGRETURN");
|
||||
if (varDialogReturn != nullptr) {
|
||||
// If we need to parse the input for 2 words (Deven-7 Code words)
|
||||
if (_useExtraFl) {
|
||||
// Find the break
|
||||
char *p = strchr(_achGuess, ',');
|
||||
if ((p != nullptr) || ((p = strchr(_achGuess, ' ')) != nullptr)) {
|
||||
*p = '\0';
|
||||
p++;
|
||||
|
||||
// Set variable 2 (DIALOGRETURN2)
|
||||
CBagVar *varDialogReturn2 = g_VarManager->getVariable("DIALOGRETURN2");
|
||||
if (varDialogReturn2 != nullptr) {
|
||||
varDialogReturn2->setValue(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Set variable 1 (DIALOGRETURN)
|
||||
varDialogReturn->setValue(_achGuess);
|
||||
}
|
||||
|
||||
delete _guessText;
|
||||
_guessText = nullptr;
|
||||
|
||||
CBagStorageDevDlg::onClose();
|
||||
}
|
||||
|
||||
void CDevDlg::onKeyHit(uint32 keyCode, uint32 repCount) {
|
||||
assert(isValidObject(this));
|
||||
|
||||
if (_guessCount < ACH_GUESS_MAX_CHARS) {
|
||||
bool paintGuessFl = false;
|
||||
const char *const MISC_KEYS = " \'$,-%.";
|
||||
|
||||
if (Common::isAlnum(keyCode) || strchr(MISC_KEYS, keyCode)) {
|
||||
_achGuess[_guessCount] = toupper(keyCode);
|
||||
_guessCount++;
|
||||
paintGuessFl = true;
|
||||
|
||||
} else if (keyCode == BKEY_BACK && (_guessCount - 1) >= 0) {
|
||||
_guessCount--;
|
||||
_achGuess[_guessCount] = 0;
|
||||
paintGuessFl = true;
|
||||
}
|
||||
|
||||
if (paintGuessFl) {
|
||||
paintText();
|
||||
}
|
||||
|
||||
// Close dialog box when enter key is hit
|
||||
if (keyCode == BKEY_ENTER) {
|
||||
onClose();
|
||||
}
|
||||
}
|
||||
|
||||
// If it maxes out, clear it
|
||||
if (_guessCount >= ACH_GUESS_MAX_CHARS) {
|
||||
Common::fill(_achGuess, _achGuess + ACH_GUESS_MAX_CHARS, 0);
|
||||
_guessCount = 0;
|
||||
}
|
||||
|
||||
CBagStorageDevDlg::onKeyHit(keyCode, repCount);
|
||||
}
|
||||
|
||||
void CDevDlg::paintText() {
|
||||
assert(isValidObject(this));
|
||||
|
||||
char achTemp[ACH_GUESS_MAX_CHARS + 1];
|
||||
snprintf(achTemp, ACH_GUESS_MAX_CHARS + 1, "%s", _achGuess);
|
||||
|
||||
_guessText->display(getBackdrop(), achTemp, 16, TEXT_MEDIUM);
|
||||
}
|
||||
|
||||
void CDevDlg::setText(CBofString &text, CBofRect *textRect) {
|
||||
assert(isValidObject(this));
|
||||
|
||||
_titleText = new CBofText;
|
||||
_titleText->setupText(textRect, JUSTIFY_CENTER, FORMAT_DEFAULT);
|
||||
_titleText->setColor(CTEXT_WHITE);
|
||||
_titleText->SetSize(FONT_14POINT);
|
||||
_titleText->setWeight(TEXT_BOLD);
|
||||
_titleText->setText(text);
|
||||
}
|
||||
|
||||
// Override on render to do the painting, but call the default anyway.
|
||||
ErrorCode CDevDlg::onRender(CBofBitmap *bmp, CBofRect *rect) {
|
||||
assert(isValidObject(this));
|
||||
|
||||
const ErrorCode errorCode = CBagStorageDevDlg::onRender(bmp, rect);
|
||||
|
||||
if (_titleText != nullptr) {
|
||||
_titleText->display(getBackdrop());
|
||||
}
|
||||
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
63
engines/bagel/spacebar/baglib/dev_dlg.h
Normal file
63
engines/bagel/spacebar/baglib/dev_dlg.h
Normal file
@@ -0,0 +1,63 @@
|
||||
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BAGEL_BAGLIB_DEV_DLG_H
|
||||
#define BAGEL_BAGLIB_DEV_DLG_H
|
||||
|
||||
#include "bagel/spacebar/baglib/storage_dev_win.h"
|
||||
#include "bagel/spacebar/boflib/gfx/text.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
#define ACH_GUESS_MAX_CHARS 40
|
||||
|
||||
class CDevDlg : public CBagStorageDevDlg {
|
||||
private:
|
||||
// for text entry:
|
||||
char _achGuess[ACH_GUESS_MAX_CHARS];
|
||||
CBofText *_guessText;
|
||||
int _guessCount;
|
||||
int _buttonX;
|
||||
int _buttonY;
|
||||
bool _useExtraFl;
|
||||
CBofText *_titleText;
|
||||
|
||||
public:
|
||||
CDevDlg(int buttonX = -1, int buttonY = -1);
|
||||
~CDevDlg();
|
||||
|
||||
ErrorCode createWindow(const char *bmp, CBofWindow *wnd, CBofPalette *pal, CBofRect *rect, bool useExtraFl);
|
||||
void paintText();
|
||||
void setText(CBofString &, CBofRect *);
|
||||
void onKeyHit(uint32 keyCode, uint32 repCount) override;
|
||||
|
||||
void onMouseMove(uint32 flags, CBofPoint *point, void * = nullptr) override;
|
||||
void onLButtonUp(uint32 flags, CBofPoint *point, void * = nullptr) override;
|
||||
void onClose() override;
|
||||
ErrorCode onRender(CBofBitmap *bmp, CBofRect *rect = nullptr) override;
|
||||
};
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
|
||||
#endif
|
||||
392
engines/bagel/spacebar/baglib/dossier_object.cpp
Normal file
392
engines/bagel/spacebar/baglib/dossier_object.cpp
Normal file
@@ -0,0 +1,392 @@
|
||||
/* 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/dossier_object.h"
|
||||
#include "bagel/spacebar/baglib/rp_object.h"
|
||||
#include "bagel/spacebar/baglib/master_win.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
CBagDossierObject *CBagDossierObject::_curDossier;
|
||||
|
||||
void CBagDossierObject::initialize() {
|
||||
_curDossier = nullptr;
|
||||
}
|
||||
|
||||
CBagDossierObject::CBagDossierObject() {
|
||||
_xObjType = DOSSIER_OBJ;
|
||||
|
||||
_dossierSetFl = false;
|
||||
_indexRect.setRect(0, 0, 0, 0);
|
||||
|
||||
// Keep track of the original text rect.
|
||||
_dossierRect.setRect(0, 0, 0, 0);
|
||||
_dosRectInitFl = false;
|
||||
|
||||
setNotActive(false);
|
||||
|
||||
// Ptr to parent rp obj nullptr for now.
|
||||
_residuePrintedObject = nullptr;
|
||||
|
||||
// Start with index line displayed
|
||||
_showIndexFl = true;
|
||||
}
|
||||
|
||||
CBagDossierObject::~CBagDossierObject() {
|
||||
}
|
||||
|
||||
ParseCodes CBagDossierObject::setInfo(CBagIfstream &istr) {
|
||||
bool objectUpdatedFl = false;
|
||||
char localBuffer[256];
|
||||
CBofString sStr(localBuffer, 256);
|
||||
|
||||
while (!istr.eof()) {
|
||||
istr.eatWhite();
|
||||
const char ch = (char)istr.peek();
|
||||
switch (ch) {
|
||||
|
||||
// SIZE n - n point size of the txt
|
||||
//
|
||||
// -or-
|
||||
//
|
||||
// SUSPECTVAR is a variable that will be in the LOGPDA list of
|
||||
// objects and will be tightly tied to residue printing. If a res print
|
||||
// yields positive results on a character then set the rp field of the
|
||||
// associated suspect object to true.
|
||||
case 'S':
|
||||
getAlphaNumFromStream(istr, sStr);
|
||||
|
||||
if (!sStr.find("SIZE")) {
|
||||
istr.eatWhite();
|
||||
int size;
|
||||
getIntFromStream(istr, size);
|
||||
setPointSize((byte)size);
|
||||
objectUpdatedFl = true;
|
||||
} else if (!sStr.find("SUSPECTVAR")) {
|
||||
istr.eatWhite();
|
||||
getAlphaNumFromStream(istr, sStr);
|
||||
_sSuspectVar = sStr;
|
||||
objectUpdatedFl = true;
|
||||
} else {
|
||||
putbackStringOnStream(istr, sStr);
|
||||
}
|
||||
break;
|
||||
|
||||
//
|
||||
// NOTACTIVE KEYWORD MEANS DON'T DO ANYTHING ON MOUSE DOWN!!!
|
||||
//
|
||||
case 'N':
|
||||
getAlphaNumFromStream(istr, sStr);
|
||||
|
||||
if (!sStr.find("NOTACTIVE")) {
|
||||
setNotActive(true);
|
||||
objectUpdatedFl = true;
|
||||
} else {
|
||||
putbackStringOnStream(istr, sStr);
|
||||
}
|
||||
break;
|
||||
|
||||
//
|
||||
// FONT MONO or DEFAULT
|
||||
//
|
||||
case 'F':
|
||||
getAlphaNumFromStream(istr, sStr);
|
||||
|
||||
if (!sStr.find("FONT")) {
|
||||
istr.eatWhite();
|
||||
int fontId;
|
||||
getIntFromStream(istr, fontId);
|
||||
fontId = MapFont(fontId);
|
||||
setFont(fontId);
|
||||
objectUpdatedFl = true;
|
||||
} else {
|
||||
putbackStringOnStream(istr, sStr);
|
||||
}
|
||||
break;
|
||||
|
||||
//
|
||||
// INDEX line, required. This is the line that will show up in the
|
||||
// log entry.
|
||||
//
|
||||
case 'I':
|
||||
getAlphaNumFromStream(istr, sStr);
|
||||
|
||||
if (!sStr.find("INDEX")) {
|
||||
istr.eatWhite();
|
||||
getAlphaNumFromStream(istr, sStr);
|
||||
|
||||
// replace underlines with spaces.
|
||||
|
||||
sStr.replaceChar('_', ' ');
|
||||
_indexLine = sStr;
|
||||
|
||||
objectUpdatedFl = true;
|
||||
|
||||
// If the next character is a '[' then we got another rect coming
|
||||
// along. This rect is for the index string.
|
||||
|
||||
istr.eatWhite();
|
||||
if ((char)istr.peek() == '[') {
|
||||
CBofRect r;
|
||||
getRectFromStream(istr, r);
|
||||
_indexRect = r;
|
||||
}
|
||||
} else {
|
||||
putbackStringOnStream(istr, sStr);
|
||||
}
|
||||
break;
|
||||
|
||||
//
|
||||
// AS [CAPTION] - how to run the link
|
||||
case 'A':
|
||||
getAlphaNumFromStream(istr, sStr);
|
||||
|
||||
if (!sStr.find("AS")) {
|
||||
istr.eatWhite();
|
||||
getAlphaNumFromStream(istr, sStr);
|
||||
if (!sStr.find("CAPTION")) {
|
||||
_bCaption = true;
|
||||
objectUpdatedFl = true;
|
||||
|
||||
} else if (!sStr.find("TITLE")) {
|
||||
_bTitle = true;
|
||||
objectUpdatedFl = true;
|
||||
|
||||
} else {
|
||||
putbackStringOnStream(istr, sStr);
|
||||
putbackStringOnStream(istr, "AS ");
|
||||
}
|
||||
} else {
|
||||
putbackStringOnStream(istr, sStr);
|
||||
}
|
||||
break;
|
||||
|
||||
//
|
||||
// COLOR n - n color index
|
||||
//
|
||||
case 'C':
|
||||
getAlphaNumFromStream(istr, sStr);
|
||||
|
||||
if (!sStr.find("COLOR")) {
|
||||
int nColor;
|
||||
istr.eatWhite();
|
||||
getIntFromStream(istr, nColor);
|
||||
setColor(nColor);
|
||||
objectUpdatedFl = true;
|
||||
} else {
|
||||
putbackStringOnStream(istr, sStr);
|
||||
}
|
||||
break;
|
||||
//
|
||||
// no match return from function
|
||||
//
|
||||
default:
|
||||
const ParseCodes parseCode = CBagObject::setInfo(istr);
|
||||
if (parseCode == PARSING_DONE) {
|
||||
return PARSING_DONE;
|
||||
}
|
||||
|
||||
if (parseCode == UPDATED_OBJECT) {
|
||||
objectUpdatedFl = true;
|
||||
} else { // rc==UNKNOWN_TOKEN
|
||||
if (objectUpdatedFl)
|
||||
return UPDATED_OBJECT;
|
||||
|
||||
return UNKNOWN_TOKEN;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return PARSING_DONE;
|
||||
}
|
||||
|
||||
// Implement attach and detach just so we can set our own attributes
|
||||
|
||||
ErrorCode CBagDossierObject::attach() {
|
||||
const ErrorCode errorCode = CBagTextObject::attach();
|
||||
|
||||
// Keep track of the original text rectangle (for the dossier).
|
||||
if (_dosRectInitFl == false) {
|
||||
_dossierRect = CBagTextObject::getRect();
|
||||
_dosRectInitFl = true;
|
||||
}
|
||||
|
||||
setVisible(false); // Don't display until needed.
|
||||
setActive(false); // Not active until we need it.
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
ErrorCode CBagDossierObject::detach() {
|
||||
const ErrorCode errorCode = CBagTextObject::detach();
|
||||
|
||||
setVisible(false); // Make this invisible, don't want it redrawn.
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
// Called to splash one of these guys to the screen
|
||||
ErrorCode CBagDossierObject::update(CBofBitmap *bmp, CBofPoint pt, CBofRect *srcRect, int n) {
|
||||
if (_showIndexFl) {
|
||||
if (_dossierSetFl == false) {
|
||||
// Set the text to be the index line.
|
||||
setPSText(&_indexLine);
|
||||
_dossierSetFl = true;
|
||||
}
|
||||
} else if (_dossierSetFl == false) {
|
||||
// Set the text to be nullptr, this forces the bagtx code to
|
||||
// paint the text file.
|
||||
setPSText(nullptr);
|
||||
|
||||
CBagTextObject::attach();
|
||||
|
||||
_dossierSetFl = true;
|
||||
}
|
||||
|
||||
return CBagTextObject::update(bmp, pt, srcRect, n);
|
||||
}
|
||||
|
||||
CBofRect CBagDossierObject::getRect() {
|
||||
CBofRect rect;
|
||||
const CBofPoint pos = getPosition();
|
||||
|
||||
if (_showIndexFl) {
|
||||
rect = _indexRect;
|
||||
rect.offsetRect(pos);
|
||||
} else {
|
||||
rect = _dossierRect;
|
||||
}
|
||||
|
||||
return rect;
|
||||
}
|
||||
|
||||
void CBagDossierObject::onLButtonUp(uint32 /*nFlags*/, CBofPoint */*xPoint*/, void */*pInfo*/) {
|
||||
// If this is an inactive object (such as "plus residue too old" or "negative")
|
||||
// then ignore the mousedown.
|
||||
|
||||
if (getNotActive()) {
|
||||
return;
|
||||
}
|
||||
|
||||
showDossierText();
|
||||
}
|
||||
|
||||
// utility routine for activating dossier objects
|
||||
void CBagDossierObject::activateDossierObject(CBagLog *logWld) {
|
||||
if (logWld) {
|
||||
logWld->activateLocalObject(this);
|
||||
}
|
||||
|
||||
if (CBagRPObject::getLogState() == RP_READ_DOSSIER) {
|
||||
setFloating(false); // This is not floating
|
||||
} else {
|
||||
setFloating(); // This is not floating
|
||||
}
|
||||
|
||||
setVisible(); // can see this thing now...
|
||||
setActive(); // make sure it counts for something
|
||||
|
||||
// Starting state will ALWAYS be index first
|
||||
_dossierSetFl = false;
|
||||
_showIndexFl = true;
|
||||
}
|
||||
|
||||
void CBagDossierObject::deactivateDossierObject(CBagLog *logWld) {
|
||||
if (CBagRPObject::getLogState() == RP_READ_DOSSIER) {
|
||||
setFloating(false); // This is not floating
|
||||
} else {
|
||||
setFloating(); // This is not floating
|
||||
}
|
||||
|
||||
setVisible(false); // Cover it up
|
||||
setActive(false); // Make sure it counts for something
|
||||
setLocal(false); // Not local anymore
|
||||
}
|
||||
|
||||
// Called from script to deactivate a dossier view screen.
|
||||
void CBagDossierObject::deactivateCurDossier() {
|
||||
// If we have a current dossier, then turn it off and activate the
|
||||
// previous rp object.
|
||||
if (_curDossier != nullptr) {
|
||||
CBagLog *logWld = nullptr;
|
||||
CBagRPObject *residuePrintedObj = ((CBagRPObject *)(_curDossier->_residuePrintedObject));
|
||||
|
||||
if (residuePrintedObj) {
|
||||
if (residuePrintedObj->zoomed()) {
|
||||
logWld = (CBagLog *)g_SDevManager->getStorageDevice(LOGZ_WLD);
|
||||
} else {
|
||||
logWld = (CBagLog *)g_SDevManager->getStorageDevice(LOG_WLD);
|
||||
}
|
||||
}
|
||||
_curDossier->deactivateDossierObject(logWld);
|
||||
|
||||
// When we hit the update code, we're gonna need to reevaluate this
|
||||
// guys current view status.
|
||||
_curDossier->_showIndexFl = true;
|
||||
_curDossier->_dossierSetFl = false;
|
||||
|
||||
((CBagRPObject *)(_curDossier->_residuePrintedObject))->activateRPObject();
|
||||
|
||||
_curDossier = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void CBagDossierObject::showDossierText() {
|
||||
// Make sure our script knows where we're going with this.
|
||||
CBagRPObject::setLogState(RP_READ_DOSSIER);
|
||||
|
||||
// We got a mouse down on one of our dossier's, so now we have to deactivate
|
||||
// everything that is in the residue print object that this dossier is
|
||||
// contained in.
|
||||
bool zoomedFl = false;
|
||||
if (_residuePrintedObject) {
|
||||
zoomedFl = ((CBagRPObject *)_residuePrintedObject)->zoomed();
|
||||
((CBagRPObject *)_residuePrintedObject)->deactivateRPObject();
|
||||
}
|
||||
|
||||
// Get the appropriate storage device
|
||||
|
||||
CBagLog *logWld;
|
||||
if (zoomedFl) {
|
||||
logWld = (CBagLog *)g_SDevManager->getStorageDevice(LOGZ_WLD);
|
||||
} else {
|
||||
logWld = (CBagLog *)g_SDevManager->getStorageDevice(LOG_WLD);
|
||||
}
|
||||
|
||||
// Now reactivate this object.
|
||||
activateDossierObject(logWld);
|
||||
|
||||
// Mark this one as our current dossier
|
||||
_curDossier = this;
|
||||
|
||||
// Make sure the text file is displayed, not the index line. See the
|
||||
// update code to see why this makes this happen.
|
||||
_dossierSetFl = false;
|
||||
_showIndexFl = false;
|
||||
|
||||
// Let the residue printing object know which one we're displaying.
|
||||
|
||||
CBagRPObject *pRPObj = (CBagRPObject *)_residuePrintedObject;
|
||||
pRPObj->setActiveDossier(this);
|
||||
}
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
90
engines/bagel/spacebar/baglib/dossier_object.h
Normal file
90
engines/bagel/spacebar/baglib/dossier_object.h
Normal file
@@ -0,0 +1,90 @@
|
||||
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BAGEL_BAGLIB_DOSSIER_OBJECT_H
|
||||
#define BAGEL_BAGLIB_DOSSIER_OBJECT_H
|
||||
|
||||
#include "bagel/spacebar/baglib/text_object.h"
|
||||
#include "bagel/spacebar/baglib/log_msg.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
class CBagDossierObject : public CBagTextObject {
|
||||
private:
|
||||
CBofString _indexLine;
|
||||
CBofRect _indexRect;
|
||||
CBofRect _dossierRect;
|
||||
CBagObject *_residuePrintedObject;
|
||||
|
||||
bool _dossierSetFl : 1;
|
||||
bool _notActiveFl : 1;
|
||||
bool _showIndexFl : 1;
|
||||
bool _dosRectInitFl : 1;
|
||||
|
||||
public:
|
||||
CBofString _sSuspectVar;
|
||||
|
||||
public:
|
||||
CBagDossierObject();
|
||||
virtual ~CBagDossierObject();
|
||||
|
||||
/**
|
||||
* Takes in info and then removes the relative information and returns
|
||||
* the info without the relevant info.
|
||||
*/
|
||||
ParseCodes setInfo(CBagIfstream &istr) override;
|
||||
|
||||
ErrorCode attach() override;
|
||||
ErrorCode detach() override;
|
||||
|
||||
ErrorCode update(CBofBitmap *, CBofPoint, CBofRect * = nullptr, int = -1) override;
|
||||
|
||||
void onLButtonUp(uint32 /*nFlags*/, CBofPoint */*xPoint*/, void * = nullptr) override; // run menu if available
|
||||
|
||||
CBofRect getRect() override;
|
||||
|
||||
void setNotActive(bool b) {
|
||||
_notActiveFl = b;
|
||||
}
|
||||
bool getNotActive() const {
|
||||
return _notActiveFl;
|
||||
}
|
||||
|
||||
void activateDossierObject(CBagLog *logWld);
|
||||
void deactivateDossierObject(CBagLog *logWld);
|
||||
|
||||
void setResiduePrintedObject(CBagObject *p) {
|
||||
_residuePrintedObject = p;
|
||||
};
|
||||
|
||||
static void deactivateCurDossier();
|
||||
void showDossierText();
|
||||
|
||||
static void initialize();
|
||||
static CBagDossierObject *_curDossier;
|
||||
};
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
|
||||
#endif
|
||||
109
engines/bagel/spacebar/baglib/event_sdev.cpp
Normal file
109
engines/bagel/spacebar/baglib/event_sdev.cpp
Normal file
@@ -0,0 +1,109 @@
|
||||
/* 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/event_sdev.h"
|
||||
#include "bagel/spacebar/baglib/pda.h"
|
||||
#include "bagel/spacebar/baglib/sound_object.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
bool CBagEventSDev::_evalTurnEventsFl;
|
||||
|
||||
ErrorCode CBagEventSDev::attach() {
|
||||
const ErrorCode errorCode = CBagStorageDev::attach();
|
||||
|
||||
// Set the firstpaint flag and attach objects to allow
|
||||
// for immediate run objects to run
|
||||
if (_bFirstPaint) {
|
||||
_bFirstPaint = false;
|
||||
attachActiveObjects();
|
||||
}
|
||||
|
||||
return errorCode;
|
||||
|
||||
}
|
||||
|
||||
ErrorCode CBagEventSDev::evaluateExpressions() {
|
||||
// If a Zelda movie is playing, don't execute the event world
|
||||
if (CBagPDA::isMoviePlaying())
|
||||
return ERR_NONE;
|
||||
|
||||
ErrorCode errorCode = ERR_NONE;
|
||||
const int count = getObjectCount();
|
||||
for (int i = 0; i < count; ++i) {
|
||||
|
||||
CBagObject *posObj = getObjectByPos(i);
|
||||
if (posObj != nullptr) {
|
||||
// Find the local Expression objects
|
||||
// This code says... only evaluate if we're in an if statement, this must be wrong.
|
||||
if (posObj->getExpression() == nullptr || posObj->getExpression()->evaluate(posObj->isNegative())) {
|
||||
if (!posObj->isAttached()) {
|
||||
posObj->setActive();
|
||||
posObj->attach();
|
||||
}
|
||||
if (posObj->isImmediateRun())
|
||||
posObj->runObject();
|
||||
|
||||
} else if (posObj->isAttached() && (posObj->getType() != SOUND_OBJ || !((CBagSoundObject *)posObj)->isPlaying())) {
|
||||
posObj->setActive(false);
|
||||
posObj->detach();
|
||||
}
|
||||
} else
|
||||
errorCode = ERR_FFIND;
|
||||
}
|
||||
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
ErrorCode CBagTurnEventSDev::evaluateExpressions() {
|
||||
// If a zelda movie is playing, don't execute the turncount world
|
||||
if (CBagPDA::isMoviePlaying()) {
|
||||
return ERR_UNKNOWN;
|
||||
}
|
||||
|
||||
ErrorCode errorCode = ERR_NONE;
|
||||
const int count = getObjectCount();
|
||||
for (int i = 0; i < count; ++i) {
|
||||
CBagObject *posObj = getObjectByPos(i);
|
||||
if (posObj != nullptr) {
|
||||
// Find the local Expression objects
|
||||
// This code says... only evaluate if we're in an if statement, this must be wrong.
|
||||
if (posObj->getExpression() == nullptr || posObj->getExpression()->evaluate(posObj->isNegative())) {
|
||||
if (!posObj->isAttached()) {
|
||||
posObj->setActive();
|
||||
posObj->attach();
|
||||
}
|
||||
if (posObj->isImmediateRun())
|
||||
posObj->runObject();
|
||||
} else if (posObj->isAttached() && (posObj->getType() != SOUND_OBJ || !((CBagSoundObject *)posObj)->isPlaying())) {
|
||||
posObj->setActive(false);
|
||||
posObj->detach();
|
||||
}
|
||||
} else
|
||||
errorCode = ERR_FFIND;
|
||||
}
|
||||
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
95
engines/bagel/spacebar/baglib/event_sdev.h
Normal file
95
engines/bagel/spacebar/baglib/event_sdev.h
Normal file
@@ -0,0 +1,95 @@
|
||||
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BAGEL_BAGLIB_EVENT_SDEV_H
|
||||
#define BAGEL_BAGLIB_EVENT_SDEV_H
|
||||
|
||||
#include "bagel/spacebar/baglib/storage_dev_win.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
class CBagEventSDev : public CBagStorageDev {
|
||||
private:
|
||||
static bool _evalTurnEventsFl;
|
||||
|
||||
public:
|
||||
CBagEventSDev() : CBagStorageDev() {
|
||||
}
|
||||
virtual ~CBagEventSDev() {
|
||||
}
|
||||
|
||||
static void initialize() {
|
||||
_evalTurnEventsFl = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called to overload new set backgrounds. Calls the set backdrop pure
|
||||
* virtual function by default.
|
||||
*/
|
||||
ErrorCode attach() override;
|
||||
|
||||
ErrorCode setBackground(CBofBitmap * /* bmp, unused */) override {
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
CBofBitmap *getBackground() override {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluate only the expression object of this storage device
|
||||
* @return Returns and error code if there is an invalid object in the list
|
||||
*/
|
||||
virtual ErrorCode evaluateExpressions();
|
||||
|
||||
// Gives timer code a method to launch tim
|
||||
static void setEvalTurnEvents(bool b = true) {
|
||||
_evalTurnEventsFl = b;
|
||||
}
|
||||
static bool getEvalTurnEvents() {
|
||||
return _evalTurnEventsFl;
|
||||
}
|
||||
};
|
||||
|
||||
class CBagTurnEventSDev : public CBagStorageDev {
|
||||
public:
|
||||
CBagTurnEventSDev() : CBagStorageDev() {
|
||||
}
|
||||
virtual ~CBagTurnEventSDev() {
|
||||
}
|
||||
|
||||
ErrorCode setBackground(CBofBitmap * /* bmp, unused */) override {
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
CBofBitmap *getBackground() override {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
virtual ErrorCode evaluateExpressions();
|
||||
};
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
|
||||
#endif
|
||||
138
engines/bagel/spacebar/baglib/exam.cpp
Normal file
138
engines/bagel/spacebar/baglib/exam.cpp
Normal file
@@ -0,0 +1,138 @@
|
||||
/* 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/exam.h"
|
||||
#include "bagel/spacebar/dialogs/opt_window.h"
|
||||
#include "bagel/spacebar/baglib/bagel.h"
|
||||
#include "bagel/spacebar/baglib/master_win.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
bool CBagExam::initExam() {
|
||||
CBofRect paintRect(155, 55, 155 + 330 - 1, 55 + 250 - 1);
|
||||
paintBitmap(CBagel::getBagApp()->getMasterWnd()->getCurrentGameWindow(), buildSysDir("SSBORDER.BMP"), &paintRect);
|
||||
|
||||
Common::Event e;
|
||||
while (g_system->getEventManager()->pollEvent(e)) {
|
||||
// Flush events, though not sure why we need it
|
||||
}
|
||||
|
||||
getParent()->disable();
|
||||
getParent()->flushAllMessages();
|
||||
|
||||
markBegEnd();
|
||||
setRotationRects();
|
||||
_bLoop = true;
|
||||
_bEscCanStop = true;
|
||||
|
||||
pause();
|
||||
|
||||
CBofCursor::show();
|
||||
doModal();
|
||||
CBofCursor::hide();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CBagExam::onReSize(CBofSize *size) {
|
||||
|
||||
CBofMovie::onReSize(size);
|
||||
setRotationRects();
|
||||
|
||||
}
|
||||
|
||||
bool CBagExam::setRotationRects() {
|
||||
// Get the windows rect
|
||||
const CBofRect clientRect = getClientRect();
|
||||
|
||||
// Left quarter of the video window
|
||||
_leftRect.left = clientRect.left;
|
||||
_leftRect.top = clientRect.top;
|
||||
_leftRect.right = clientRect.left + ((clientRect.right - clientRect.left) / 4);
|
||||
_leftRect.bottom = clientRect.bottom;
|
||||
|
||||
// Right quarter of the video window
|
||||
_rightRect.left = clientRect.right - ((clientRect.bottom - clientRect.left) / 4);
|
||||
_rightRect.top = clientRect.top;
|
||||
_rightRect.right = clientRect.right;
|
||||
_rightRect.bottom = clientRect.bottom;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CBagExam::markBegEnd() {
|
||||
_end = _pSmk->getFrameCount() - 1;
|
||||
_start = 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CBagExam::onButtonUp(uint32 /*n flags, unused */, CBofPoint */* point, unused */) {
|
||||
// Clean up and exit
|
||||
_bLoop = false;
|
||||
|
||||
stop();
|
||||
onMovieDone();
|
||||
}
|
||||
|
||||
|
||||
bool CBagExam::rotateLeft() {
|
||||
if (_eMovStatus != FORWARD)
|
||||
return play();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CBagExam::rotateRight() {
|
||||
if (_eMovStatus != REVERSE)
|
||||
return reverse();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CBagExam::rotateStop() {
|
||||
if (_eMovStatus == FORWARD || _eMovStatus == REVERSE)
|
||||
// The movie is currently playing
|
||||
return pause();
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
void CBagExam::onMouseMove(uint32 /* flags, unused */, CBofPoint *point, void */* extraInfo, unused */) {
|
||||
assert(isValidObject(this));
|
||||
assert(point != nullptr);
|
||||
|
||||
// No more cursor in Examine movies
|
||||
if (point->x <= _leftRect.right) {
|
||||
// Left rect, play reverse
|
||||
rotateLeft();
|
||||
} else if (point->x >= _rightRect.left) {
|
||||
// Right rect, play forward
|
||||
rotateRight();
|
||||
} else if (_eMovStatus == FORWARD || _eMovStatus == REVERSE) {
|
||||
rotateStop();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
100
engines/bagel/spacebar/baglib/exam.h
Normal file
100
engines/bagel/spacebar/baglib/exam.h
Normal file
@@ -0,0 +1,100 @@
|
||||
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BAGEL_BAGLIB_EXAM_H
|
||||
#define BAGEL_BAGLIB_EXAM_H
|
||||
|
||||
#include "bagel/spacebar/boflib/gui/movie.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
class CBagExam : public CBofMovie {
|
||||
protected:
|
||||
CBofRect _leftRect;
|
||||
CBofRect _rightRect;
|
||||
uint32 _start;
|
||||
uint32 _end;
|
||||
|
||||
public:
|
||||
CBagExam(CBofWindow *pParent = nullptr) : CBofMovie(pParent),
|
||||
_leftRect(0, 0, 0, 0), _rightRect(0, 0, 0, 0), _start(0), _end(0) {
|
||||
}
|
||||
CBagExam(CBofWindow *pParent, const char *sFilename) : CBofMovie(pParent, sFilename),
|
||||
_leftRect(0, 0, 0, 0), _rightRect(0, 0, 0, 0), _start(0), _end(0) {
|
||||
}
|
||||
CBagExam(CBofWindow *pParent, const char *sFilename, CBofRect *pBounds) : CBofMovie(pParent, sFilename, pBounds),
|
||||
_leftRect(0, 0, 0, 0), _rightRect(0, 0, 0, 0), _start(0), _end(0) {
|
||||
}
|
||||
~CBagExam() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize exam object after opened and ready to play
|
||||
* @return Success/failure
|
||||
*/
|
||||
virtual bool initExam();
|
||||
|
||||
/**
|
||||
* Called when the mouse is moved over window, check if the
|
||||
* cursor is in one of the rectangle and rotate object accordingly
|
||||
*/
|
||||
void onMouseMove(uint32 /* flags */, CBofPoint *point, void */* extraInfo */ = nullptr) override;
|
||||
|
||||
/**
|
||||
* Resize the examination window
|
||||
*/
|
||||
void onReSize(CBofSize *size) override;
|
||||
void onButtonUp(uint32 /* flags */, CBofPoint */* point */) override;
|
||||
|
||||
/**
|
||||
* Set the rectangles that determine "hot" mouse locations
|
||||
* @return Success/failure
|
||||
*/
|
||||
bool setRotationRects();
|
||||
|
||||
/**
|
||||
* Store off the start and end frames of the movies
|
||||
* @return Success/failure
|
||||
*/
|
||||
bool markBegEnd();
|
||||
|
||||
/**
|
||||
* Rotate the object to the right (play movie)
|
||||
*/
|
||||
bool rotateRight();
|
||||
|
||||
/**
|
||||
* Rotate the object to the left (reverse movie)
|
||||
*/
|
||||
bool rotateLeft();
|
||||
|
||||
/**
|
||||
* Stop the rotation of the object (stop movie)
|
||||
*/
|
||||
bool rotateStop();
|
||||
};
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
|
||||
#endif
|
||||
747
engines/bagel/spacebar/baglib/expression.cpp
Normal file
747
engines/bagel/spacebar/baglib/expression.cpp
Normal file
@@ -0,0 +1,747 @@
|
||||
/* 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/expression.h"
|
||||
#include "bagel/spacebar/baglib/master_win.h"
|
||||
#include "bagel/spacebar/baglib/storage_dev_win.h"
|
||||
#include "bagel/spacebar/baglib/sound_object.h"
|
||||
#include "bagel/boflib/sound.h"
|
||||
#include "bagel/bagel.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
CBagVar *CBagExpression::_tempVar; // Used as a default param
|
||||
|
||||
void CBagExpression::initialize() {
|
||||
// used as a default param
|
||||
_tempVar = new CBagVar("CBagExpr::TempVar", "", false);
|
||||
}
|
||||
|
||||
void CBagExpression::shutdown() {
|
||||
delete _tempVar;
|
||||
}
|
||||
|
||||
CBagExpression::CBagExpression(CBagExpression *prevExpr, bool prevNegFl) {
|
||||
_negativeFl = false;
|
||||
_prevExpression = prevExpr;
|
||||
_prevNegativeFl = prevNegFl;
|
||||
}
|
||||
|
||||
CBagExpression::~CBagExpression() {
|
||||
}
|
||||
|
||||
bool CBagExpression::evaluate(CBagVar *leftHandOper, CBagVar *rightHandOper, OPERATION oper, CBagVar &result) {
|
||||
bool retVal = false;
|
||||
|
||||
// If the variable is named "RANDOM", generate a random number for its value
|
||||
if (leftHandOper->getName() == "RANDOM")
|
||||
leftHandOper->setValue(g_engine->getRandomNumber());
|
||||
if (rightHandOper->getName() == "RANDOM")
|
||||
rightHandOper->setValue(g_engine->getRandomNumber());
|
||||
|
||||
switch (oper) {
|
||||
case OP_NONE:
|
||||
break;
|
||||
|
||||
case OP_ASSIGN:
|
||||
retVal = onAssign(leftHandOper, rightHandOper, result);
|
||||
break;
|
||||
|
||||
case OP_EQUAL:
|
||||
retVal = onEqual(leftHandOper, rightHandOper, result);
|
||||
break;
|
||||
|
||||
case OP_NOT_EQUAL:
|
||||
retVal = onNotEqual(leftHandOper, rightHandOper, result);
|
||||
break;
|
||||
|
||||
case OP_LESS_THAN:
|
||||
retVal = onLessThan(leftHandOper, rightHandOper, result);
|
||||
break;
|
||||
|
||||
case OP_LESS_THAN_EQUAL:
|
||||
retVal = onLessThanEqual(leftHandOper, rightHandOper, result);
|
||||
break;
|
||||
|
||||
case OP_GREATER_THAN:
|
||||
retVal = onGreaterThan(leftHandOper, rightHandOper, result);
|
||||
break;
|
||||
|
||||
case OP_GREATER_THAN_EQUAL:
|
||||
retVal = onGreaterThanEqual(leftHandOper, rightHandOper, result);
|
||||
break;
|
||||
|
||||
case OP_PLUS_ASSIGN:
|
||||
retVal = onPlusAssign(leftHandOper, rightHandOper, result);
|
||||
break;
|
||||
|
||||
case OP_MINUS_ASSIGN:
|
||||
retVal = onMinusAssign(leftHandOper, rightHandOper, result);
|
||||
break;
|
||||
|
||||
case OP_PLUS:
|
||||
retVal = onPlus(leftHandOper, rightHandOper, result);
|
||||
break;
|
||||
|
||||
case OP_MINUS:
|
||||
retVal = onMinus(leftHandOper, rightHandOper, result);
|
||||
break;
|
||||
|
||||
case OP_MULTIPLY:
|
||||
retVal = onMultiply(leftHandOper, rightHandOper, result);
|
||||
break;
|
||||
|
||||
case OP_DIVIDE:
|
||||
retVal = onDivide(leftHandOper, rightHandOper, result);
|
||||
break;
|
||||
|
||||
case OP_MOD:
|
||||
retVal = onMod(leftHandOper, rightHandOper, result);
|
||||
break;
|
||||
|
||||
case OP_CONTAINS:
|
||||
retVal = onContains(leftHandOper, rightHandOper, result);
|
||||
break;
|
||||
|
||||
case OP_HAS:
|
||||
retVal = onHas(leftHandOper, rightHandOper, result);
|
||||
break;
|
||||
|
||||
case OP_STATUS:
|
||||
retVal = onStatus(leftHandOper, rightHandOper, result);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
||||
CBagVar *CBagExpression::getVariable(int itemPos) {
|
||||
CBagVar *curVar = _varList.getNodeItem(itemPos);
|
||||
|
||||
// If the variable is a reference (OBJ.PROPERTY)
|
||||
if (curVar->isReference()) {
|
||||
char frontStr[256];
|
||||
Common::strcpy_s(frontStr, curVar->getName());
|
||||
|
||||
char *p = strstr(frontStr, "~~");
|
||||
if (p != nullptr) {
|
||||
char backStr[256];
|
||||
Common::strcpy_s(backStr, p + 2);
|
||||
*p = '\0';
|
||||
|
||||
const CBofString stringObject(frontStr, 256);
|
||||
const CBofString stringProperty(backStr, 256);
|
||||
|
||||
const int newVal = g_SDevManager->getObjectValue(stringObject, stringProperty);
|
||||
curVar->setValue(newVal);
|
||||
}
|
||||
}
|
||||
|
||||
return curVar;
|
||||
}
|
||||
|
||||
|
||||
CBagExpression::OPERATION CBagExpression::getOperation(int itemPos) {
|
||||
assert(false);
|
||||
return _operList.getNodeItem(itemPos);
|
||||
}
|
||||
|
||||
|
||||
bool CBagExpression::evaluate(bool negFl, CBagVar &result) {
|
||||
bool retVal = false;
|
||||
|
||||
// There must be an expression for every variable after the first
|
||||
assert(_varList.getCount() - 1 == _operList.getCount());
|
||||
|
||||
int count = 0;
|
||||
|
||||
CBagVar *leftHandOper = getVariable(count++);
|
||||
result = *leftHandOper;
|
||||
|
||||
bool parentCheckFl = true;
|
||||
if (_prevExpression) {
|
||||
parentCheckFl = _prevExpression->evaluate(_prevNegativeFl, result);
|
||||
}
|
||||
|
||||
if (parentCheckFl) {
|
||||
bool subValFl;
|
||||
int nodeCount = 0;
|
||||
|
||||
while (count < _varList.getCount()) {
|
||||
CBagVar *rightHandOper = getVariable(count++);
|
||||
OPERATION oper = _operList.getNodeItem(nodeCount++);
|
||||
CBagVar *rightHandOper2;
|
||||
|
||||
switch (oper) {
|
||||
case OP_AND:
|
||||
rightHandOper2 = getVariable(count++);
|
||||
oper = _operList.getNodeItem(nodeCount++);
|
||||
subValFl = evaluate(rightHandOper, rightHandOper2, oper, result);
|
||||
|
||||
retVal &= subValFl;
|
||||
break;
|
||||
|
||||
case OP_OR:
|
||||
rightHandOper2 = getVariable(count++);
|
||||
oper = _operList.getNodeItem(nodeCount++);
|
||||
subValFl = evaluate(rightHandOper, rightHandOper2, oper, result);
|
||||
|
||||
retVal |= subValFl;
|
||||
break;
|
||||
|
||||
default:
|
||||
retVal = evaluate(leftHandOper, rightHandOper, oper, result);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (negFl)
|
||||
// Evaluate before and with parent
|
||||
retVal = !retVal;
|
||||
|
||||
retVal &= parentCheckFl;
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
bool CBagExpression::evalLeftToRight(bool negFl, CBagVar &result) {
|
||||
bool retVal = false;
|
||||
OPERATION oper = OP_NONE;
|
||||
|
||||
// There must be an expression for every variable after the first
|
||||
assert(_varList.getCount() - 1 == _operList.getCount());
|
||||
|
||||
int varCount = 0;
|
||||
|
||||
CBagVar *leftHandOper = getVariable(varCount++);
|
||||
result = *leftHandOper;
|
||||
|
||||
bool parentCheckFl = true;
|
||||
if (_prevExpression) {
|
||||
parentCheckFl = _prevExpression->evaluate(_prevNegativeFl, result);
|
||||
}
|
||||
|
||||
if (parentCheckFl) {
|
||||
bool bFirstTime = true;
|
||||
int nodeCount = 0;
|
||||
while (varCount < _varList.getCount()) {
|
||||
CBagVar compLeftHandOper;
|
||||
CBagVar *rightHandOper = getVariable(varCount++);
|
||||
const OPERATION prevOper = oper; // save previous operator
|
||||
oper = _operList.getNodeItem(nodeCount++);
|
||||
|
||||
if (bFirstTime) {
|
||||
compLeftHandOper = *leftHandOper;
|
||||
bFirstTime = false;
|
||||
} else {
|
||||
// Based on what we have for a previous operator, either use
|
||||
// the left hand expression or the result of the previous expression.
|
||||
switch (prevOper) {
|
||||
case OP_MINUS:
|
||||
case OP_MULTIPLY:
|
||||
case OP_DIVIDE:
|
||||
case OP_MOD:
|
||||
case OP_PLUS:
|
||||
compLeftHandOper = result;
|
||||
break;
|
||||
case OP_NONE:
|
||||
case OP_ASSIGN:
|
||||
case OP_EQUAL:
|
||||
case OP_NOT_EQUAL:
|
||||
case OP_LESS_THAN:
|
||||
case OP_LESS_THAN_EQUAL:
|
||||
case OP_GREATER_THAN:
|
||||
case OP_GREATER_THAN_EQUAL:
|
||||
case OP_PLUS_ASSIGN:
|
||||
case OP_MINUS_ASSIGN:
|
||||
case OP_CONTAINS:
|
||||
case OP_HAS:
|
||||
case OP_STATUS:
|
||||
default:
|
||||
compLeftHandOper = *leftHandOper;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool boolVal;
|
||||
CBagVar *rightHandOper2;
|
||||
switch (oper) {
|
||||
|
||||
case OP_AND:
|
||||
rightHandOper2 = getVariable(varCount++);
|
||||
oper = _operList.getNodeItem(nodeCount++);
|
||||
boolVal = evaluate(rightHandOper, rightHandOper2, oper, result);
|
||||
|
||||
retVal &= boolVal;
|
||||
break;
|
||||
|
||||
case OP_OR:
|
||||
rightHandOper2 = getVariable(varCount++);
|
||||
oper = _operList.getNodeItem(nodeCount++);
|
||||
boolVal = evaluate(rightHandOper, rightHandOper2, oper, result);
|
||||
|
||||
// or this don't not it!!!
|
||||
retVal |= boolVal;
|
||||
break;
|
||||
|
||||
default:
|
||||
retVal = evaluate(&compLeftHandOper, rightHandOper, oper, result);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (negFl)
|
||||
// Evaluate before and with parent
|
||||
retVal = !retVal;
|
||||
|
||||
retVal &= parentCheckFl;
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
||||
bool CBagExpression::negEvaluate(CBagVar &result) {
|
||||
return evaluate(false, result);
|
||||
}
|
||||
|
||||
|
||||
bool CBagExpression::onAssign(CBagVar *leftHandOper, CBagVar *rightHandOper, CBagVar & /* resultOper, unused*/) {
|
||||
assert((leftHandOper != nullptr) && (rightHandOper != nullptr));
|
||||
|
||||
char buffer[256];
|
||||
Common::strcpy_s(buffer, rightHandOper->getValue());
|
||||
assert(strlen(buffer) < 256);
|
||||
const CBofString newLeftHandValue(buffer, 256);
|
||||
|
||||
leftHandOper->setValue(newLeftHandValue);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool CBagExpression::onEqual(CBagVar *leftHandOper, CBagVar *rightHandOper, CBagVar &resultOper) {
|
||||
assert((leftHandOper != nullptr) && (rightHandOper != nullptr));
|
||||
|
||||
const bool retVal = leftHandOper->getValue() == rightHandOper->getValue();
|
||||
resultOper.setBoolValue(retVal);
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
||||
bool CBagExpression::onNotEqual(CBagVar *leftHandOper, CBagVar *rightHandOper, CBagVar &resultOper) {
|
||||
assert((leftHandOper != nullptr) && (rightHandOper != nullptr));
|
||||
const bool retVal = leftHandOper->getValue() != rightHandOper->getValue();
|
||||
resultOper.setBoolValue(retVal);
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
||||
bool CBagExpression::onLessThan(CBagVar *leftHandOper, CBagVar *rightHandOper, CBagVar &resultOper) {
|
||||
assert((leftHandOper != nullptr) && (rightHandOper != nullptr));
|
||||
const bool retVal = leftHandOper->getNumValue() < rightHandOper->getNumValue();
|
||||
resultOper.setBoolValue(retVal);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
||||
bool CBagExpression::onGreaterThan(CBagVar *leftHandOper, CBagVar *rightHandOper, CBagVar &resultOper) {
|
||||
assert((leftHandOper != nullptr) && (rightHandOper != nullptr));
|
||||
const bool retVal = leftHandOper->getNumValue() > rightHandOper->getNumValue();
|
||||
resultOper.setBoolValue(retVal);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
||||
bool CBagExpression::onLessThanEqual(CBagVar *leftHandOper, CBagVar *rightHandOper, CBagVar &resultOper) {
|
||||
assert((leftHandOper != nullptr) && (rightHandOper != nullptr));
|
||||
const bool retVal = leftHandOper->getNumValue() <= rightHandOper->getNumValue();
|
||||
resultOper.setBoolValue(retVal);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
||||
bool CBagExpression::onGreaterThanEqual(CBagVar *leftHandOper, CBagVar *rightHandOper, CBagVar &resultOper) {
|
||||
assert((leftHandOper != nullptr) && (rightHandOper != nullptr));
|
||||
|
||||
const bool retVal = leftHandOper->getNumValue() >= rightHandOper->getNumValue();
|
||||
resultOper.setBoolValue(retVal);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
||||
bool CBagExpression::onPlusAssign(CBagVar *leftHandOper, CBagVar *rightHandOper, CBagVar &resultOper) {
|
||||
assert((leftHandOper != nullptr) && (rightHandOper != nullptr));
|
||||
|
||||
if (leftHandOper->isNumeric() && rightHandOper->isNumeric()) {
|
||||
const int leftHandNum = leftHandOper->getNumValue();
|
||||
const int rightHandNum = rightHandOper->getNumValue();
|
||||
leftHandOper->setValue(leftHandNum + rightHandNum);
|
||||
resultOper.setValue(leftHandOper->getNumValue());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool CBagExpression::onMinusAssign(CBagVar *leftHandOper, CBagVar *rightHandOper, CBagVar &resultOper) {
|
||||
assert((leftHandOper != nullptr) && (rightHandOper != nullptr));
|
||||
|
||||
if (leftHandOper->isNumeric() && rightHandOper->isNumeric()) {
|
||||
const int leftHandNum = leftHandOper->getNumValue();
|
||||
const int rightHandNum = rightHandOper->getNumValue();
|
||||
leftHandOper->setValue(leftHandNum - rightHandNum);
|
||||
resultOper.setValue(leftHandOper->getNumValue());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool CBagExpression::onContains(CBagVar *leftHandOper, CBagVar *rightHandOper, CBagVar & /* resultOper, unused */) {
|
||||
assert((leftHandOper != nullptr) && (rightHandOper != nullptr));
|
||||
|
||||
CBagStorageDev *sDev = g_SDevManager->getStorageDevice(leftHandOper->getValue());
|
||||
if (sDev == nullptr)
|
||||
return false;
|
||||
|
||||
CBagObject *curObj = sDev->getObject(rightHandOper->getValue());
|
||||
if ((curObj != nullptr) && curObj->isActive())
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CBagExpression::onHas(CBagVar *leftHandOper, CBagVar *rightHandOper, CBagVar & /* resultOper, unused */) {
|
||||
assert((leftHandOper != nullptr) && (rightHandOper != nullptr));
|
||||
|
||||
CBagStorageDev *sDev = g_SDevManager->getStorageDevice(leftHandOper->getValue());
|
||||
if (sDev == nullptr)
|
||||
return false;
|
||||
|
||||
CBagObject *curObj = sDev->getObjectByType(rightHandOper->getValue(), true);
|
||||
if (curObj == nullptr)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CBagExpression::onStatus(CBagVar *pLHOper, CBagVar * /* rightHandOper, unused */, CBagVar & /* resultOper, unused */) {
|
||||
assert(pLHOper != nullptr);
|
||||
|
||||
CBagStorageDev *sDev = g_SDevManager->getStorageDeviceContaining(pLHOper->getValue());
|
||||
if (sDev == nullptr)
|
||||
return false;
|
||||
|
||||
CBagObject *curObj = sDev->getObject(pLHOper->getValue());
|
||||
if (curObj == nullptr)
|
||||
return false;
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
bool CBagExpression::onCurrSDev(CBagVar * /* leftHandOper, unused*/, CBagVar * /* rightHandOper, unused */, CBagVar & /* resultOper, unused */) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool CBagExpression::onPlus(CBagVar *leftHandOper, CBagVar *rightHandOper, CBagVar &resultOper) {
|
||||
assert((leftHandOper != nullptr) && (rightHandOper != nullptr));
|
||||
|
||||
if (leftHandOper->isNumeric() && rightHandOper->isNumeric()) {
|
||||
const int leftHandNum = leftHandOper->getNumValue();
|
||||
const int rightHandNum = rightHandOper->getNumValue();
|
||||
resultOper.setValue(leftHandNum + rightHandNum);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool CBagExpression::onMinus(CBagVar *leftHandOper, CBagVar *rightHandOper, CBagVar &resultOper) {
|
||||
assert((leftHandOper != nullptr) && (rightHandOper != nullptr));
|
||||
|
||||
if (leftHandOper->isNumeric() && rightHandOper->isNumeric()) {
|
||||
const int leftHandNum = leftHandOper->getNumValue();
|
||||
const int rightHandNum = rightHandOper->getNumValue();
|
||||
resultOper.setValue(leftHandNum - rightHandNum);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool CBagExpression::onMultiply(CBagVar *leftHandOper, CBagVar *rightHandOper, CBagVar &resultOper) {
|
||||
assert((leftHandOper != nullptr) && (rightHandOper != nullptr));
|
||||
|
||||
if (leftHandOper->isNumeric() && rightHandOper->isNumeric()) {
|
||||
const int leftHandNum = leftHandOper->getNumValue();
|
||||
const int rightHandNum = rightHandOper->getNumValue();
|
||||
|
||||
resultOper.setValue(leftHandNum * rightHandNum);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool CBagExpression::onDivide(CBagVar *leftHandOper, CBagVar *rightHandOper, CBagVar &resultOper) {
|
||||
assert((leftHandOper != nullptr) && (rightHandOper != nullptr));
|
||||
|
||||
if (leftHandOper->isNumeric() && rightHandOper->isNumeric()) {
|
||||
const int leftHandNum = leftHandOper->getNumValue();
|
||||
const int rightHandNum = rightHandOper->getNumValue();
|
||||
|
||||
// Divide by Zero error?
|
||||
assert(rightHandNum != 0);
|
||||
|
||||
resultOper.setValue(leftHandNum / rightHandNum);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool CBagExpression::onMod(CBagVar *leftHandOper, CBagVar *rightHandOper, CBagVar &resultOper) {
|
||||
assert((leftHandOper != nullptr) && (rightHandOper != nullptr));
|
||||
|
||||
if (leftHandOper->isNumeric() && rightHandOper->isNumeric()) {
|
||||
const int leftHandNum = leftHandOper->getNumValue();
|
||||
const int rightHandNum = rightHandOper->getNumValue();
|
||||
|
||||
// Divide by Zero error?
|
||||
assert(rightHandNum != 0);
|
||||
|
||||
resultOper.setValue(leftHandNum % rightHandNum);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool CBagExpression::onAnd(CBagVar *leftHandOper, CBagVar *rightHandOper, CBagVar & /* resultOper, unused */) {
|
||||
assert((leftHandOper != nullptr) && (rightHandOper != nullptr));
|
||||
|
||||
return (!leftHandOper->getValue().find("true") && !rightHandOper->getValue().find("true"));
|
||||
}
|
||||
|
||||
|
||||
bool CBagExpression::onOr(CBagVar *leftHandOper, CBagVar *rightHandOper, CBagVar & /* resultOper, unused */) {
|
||||
assert((leftHandOper != nullptr) && (rightHandOper != nullptr));
|
||||
|
||||
return (!leftHandOper->getValue().find("true") || !rightHandOper->getValue().find("true"));
|
||||
}
|
||||
|
||||
|
||||
ParseCodes CBagExpression::setInfo(CBagIfstream &istr) {
|
||||
char buffer[256];
|
||||
buffer[0] = 0;
|
||||
CBofString tmpStr(buffer, 256);
|
||||
|
||||
ParseCodes parseCode = PARSING_DONE;
|
||||
bool doneFl = false;
|
||||
|
||||
while (!doneFl && parseCode == PARSING_DONE) {
|
||||
istr.eatWhite();
|
||||
int ch = istr.peek();
|
||||
switch (ch) {
|
||||
case '(': {
|
||||
istr.getCh();
|
||||
istr.eatWhite();
|
||||
|
||||
getAlphaNumFromStream(istr, tmpStr);
|
||||
CBagVar *curVar = g_VarManager->getVariable(tmpStr);
|
||||
if (!curVar) {
|
||||
// This must be a reference, make a new variable
|
||||
if (tmpStr.find("~~") > 0) {
|
||||
curVar = new CBagVar;
|
||||
curVar->setName(tmpStr);
|
||||
curVar->setReference();
|
||||
} else {
|
||||
// This is an error condition, constants can only be rhopers
|
||||
curVar = new CBagVar;
|
||||
curVar->setName(tmpStr);
|
||||
curVar->setValue(tmpStr);
|
||||
curVar->setConstant();
|
||||
}
|
||||
}
|
||||
_varList.addToTail(curVar);
|
||||
|
||||
istr.eatWhite();
|
||||
ch = istr.peek();
|
||||
while ((ch != ')') && parseCode == PARSING_DONE) {
|
||||
OPERATION curOper;
|
||||
getOperatorFromStream(istr, curOper);
|
||||
if (curOper == OP_NONE) {
|
||||
parseCode = UNKNOWN_TOKEN;
|
||||
break;
|
||||
}
|
||||
_operList.addToTail(curOper);
|
||||
|
||||
istr.eatWhite();
|
||||
getAlphaNumFromStream(istr, tmpStr);
|
||||
curVar = g_VarManager->getVariable(tmpStr);
|
||||
if (!curVar) {
|
||||
if (tmpStr.find("~~") > 0) {
|
||||
// This must be a reference, make a new variable
|
||||
curVar = new CBagVar;
|
||||
curVar->setName(tmpStr);
|
||||
curVar->setReference();
|
||||
} else {
|
||||
// This must be a constant, make a new variable
|
||||
curVar = new CBagVar;
|
||||
curVar->setName(tmpStr);
|
||||
curVar->setValue(tmpStr);
|
||||
curVar->setConstant();
|
||||
}
|
||||
}
|
||||
_varList.addToTail(curVar);
|
||||
|
||||
istr.eatWhite();
|
||||
ch = istr.peek();
|
||||
} // while parsing inner circle
|
||||
|
||||
if (ch == ')') {
|
||||
istr.getCh();
|
||||
doneFl = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 'N':
|
||||
getAlphaNumFromStream(istr, tmpStr);
|
||||
if (!tmpStr.find("NOT")) {
|
||||
_negativeFl = !_negativeFl;
|
||||
istr.eatWhite();
|
||||
break;
|
||||
}
|
||||
// FIXME: Is this intentional?
|
||||
// fallthrough
|
||||
default:
|
||||
parseCode = UNKNOWN_TOKEN;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (parseCode != PARSING_DONE) {
|
||||
parseAlertBox(istr, "Error in expression:", __FILE__, __LINE__);
|
||||
}
|
||||
|
||||
istr.eatWhite();
|
||||
|
||||
return parseCode;
|
||||
}
|
||||
|
||||
|
||||
ErrorCode CBagExpression::getOperatorFromStream(CBagIfstream &istr, OPERATION &oper) {
|
||||
ErrorCode errorCode = ERR_NONE;
|
||||
|
||||
char localBuff[256];
|
||||
localBuff[0] = 0;
|
||||
|
||||
CBofString localStr(localBuff, 256);
|
||||
|
||||
oper = OP_NONE;
|
||||
|
||||
istr.eatWhite();
|
||||
getOperStrFromStream(istr, localStr);
|
||||
|
||||
if (localStr.isEmpty()) {
|
||||
getAlphaNumFromStream(istr, localStr);
|
||||
istr.eatWhite();
|
||||
}
|
||||
|
||||
if (!localStr.find("-=")) {
|
||||
oper = OP_MINUS_ASSIGN;
|
||||
|
||||
} else if (!localStr.find("+=")) {
|
||||
oper = OP_PLUS_ASSIGN;
|
||||
|
||||
} else if (!localStr.find(">=")) {
|
||||
oper = OP_GREATER_THAN_EQUAL;
|
||||
|
||||
} else if (!localStr.find("<=")) {
|
||||
oper = OP_LESS_THAN_EQUAL;
|
||||
|
||||
} else if (!localStr.find("!=")) {
|
||||
oper = OP_NOT_EQUAL;
|
||||
|
||||
} else if (!localStr.find("==")) {
|
||||
oper = OP_EQUAL;
|
||||
|
||||
} else if (!localStr.find(">")) {
|
||||
oper = OP_GREATER_THAN;
|
||||
|
||||
} else if (!localStr.find("<")) {
|
||||
oper = OP_LESS_THAN;
|
||||
|
||||
} else if (!localStr.find("=")) {
|
||||
oper = OP_ASSIGN;
|
||||
|
||||
} else if (!localStr.find("+")) {
|
||||
oper = OP_PLUS;
|
||||
|
||||
} else if (!localStr.find("-")) {
|
||||
oper = OP_MINUS;
|
||||
|
||||
} else if (!localStr.find("*")) {
|
||||
oper = OP_MULTIPLY;
|
||||
|
||||
} else if (!localStr.find("/")) {
|
||||
oper = OP_DIVIDE;
|
||||
|
||||
} else if (!localStr.find("%")) {
|
||||
oper = OP_MOD;
|
||||
|
||||
} else if (!localStr.find("CONTAINS")) {
|
||||
// SDev contains object
|
||||
oper = OP_CONTAINS;
|
||||
|
||||
} else if (!localStr.find("HAS")) {
|
||||
// SDev has type of object
|
||||
oper = OP_HAS;
|
||||
|
||||
} else if (!localStr.find("OR")) {
|
||||
oper = OP_OR;
|
||||
|
||||
} else if (!localStr.find("STATUS")) {
|
||||
oper = OP_STATUS;
|
||||
|
||||
} else if (!localStr.find("AND")) {
|
||||
oper = OP_AND;
|
||||
}
|
||||
|
||||
if (oper == OP_NONE)
|
||||
errorCode = ERR_UNKNOWN;
|
||||
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
133
engines/bagel/spacebar/baglib/expression.h
Normal file
133
engines/bagel/spacebar/baglib/expression.h
Normal file
@@ -0,0 +1,133 @@
|
||||
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BAGEL_BAGLIB_EXPRESSION_H
|
||||
#define BAGEL_BAGLIB_EXPRESSION_H
|
||||
|
||||
#include "bagel/spacebar/baglib/parse_object.h"
|
||||
#include "bagel/spacebar/baglib/var.h"
|
||||
#include "bagel/spacebar/boflib/list.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
class CBagExpression : public CBagParseObject, public CBofObject {
|
||||
public:
|
||||
enum OPERATION {
|
||||
OP_NONE,
|
||||
OP_ASSIGN,
|
||||
OP_EQUAL,
|
||||
OP_NOT_EQUAL,
|
||||
OP_LESS_THAN,
|
||||
OP_LESS_THAN_EQUAL,
|
||||
OP_GREATER_THAN,
|
||||
OP_GREATER_THAN_EQUAL,
|
||||
OP_PLUS_ASSIGN,
|
||||
OP_MINUS_ASSIGN,
|
||||
OP_CONTAINS,
|
||||
OP_HAS,
|
||||
OP_CURR_SDEV,
|
||||
OP_PLUS,
|
||||
OP_MINUS,
|
||||
OP_MULTIPLY,
|
||||
OP_DIVIDE,
|
||||
OP_AND,
|
||||
OP_OR,
|
||||
OP_MOD,
|
||||
OP_STATUS
|
||||
};
|
||||
|
||||
private:
|
||||
CBofList<CBagVar *> _varList; // Right hand operator
|
||||
CBofList<OPERATION> _operList; // Operation to be preformed
|
||||
CBagExpression *_prevExpression; // Not null when when this is an enclosed expression
|
||||
|
||||
bool _prevNegativeFl; // True if the operation should return Negative results
|
||||
bool _negativeFl; // True if the operation should return Negative results
|
||||
|
||||
bool evaluate(CBagVar *leftHandOper, CBagVar *rightHandOper, OPERATION oper, CBagVar &result);
|
||||
|
||||
public:
|
||||
static CBagVar *_tempVar; // Used as a default param
|
||||
static void initialize();
|
||||
static void shutdown();
|
||||
|
||||
CBagExpression(CBagExpression *prevExpr = nullptr, bool prevNegFl = false);
|
||||
virtual ~CBagExpression();
|
||||
|
||||
bool evaluate(bool negFl = false, CBagVar &result = *_tempVar);
|
||||
|
||||
/**
|
||||
* Same as evaluate above except it evaluates left to right and preserves
|
||||
* the value of the previous evaluation in the loop. Provides partial
|
||||
* evaluation hierarchy support.
|
||||
*/
|
||||
bool evalLeftToRight(bool negFl = false, CBagVar &result = *_tempVar);
|
||||
|
||||
bool negEvaluate(CBagVar &result = *_tempVar);
|
||||
|
||||
void setNegative(bool b = true) {
|
||||
_negativeFl = b;
|
||||
}
|
||||
bool isNegative() const {
|
||||
return _negativeFl;
|
||||
}
|
||||
|
||||
CBagVar *getVariable(int itemPos);
|
||||
OPERATION getOperation(int itemPos);
|
||||
|
||||
ParseCodes setInfo(CBagIfstream &istr) override;
|
||||
ErrorCode getOperatorFromStream(CBagIfstream &istr, OPERATION &oper);
|
||||
|
||||
CBagExpression *getPrevExpression() const {
|
||||
return _prevExpression;
|
||||
}
|
||||
void setPrevExpression(CBagExpression *expr) {
|
||||
_prevExpression = expr;
|
||||
}
|
||||
|
||||
virtual bool onAssign(CBagVar *leftHandOper, CBagVar *rightHandOper, CBagVar &resultOper);
|
||||
virtual bool onEqual(CBagVar *leftHandOper, CBagVar *rightHandOper, CBagVar &resultOper);
|
||||
virtual bool onNotEqual(CBagVar *leftHandOper, CBagVar *rightHandOper, CBagVar &resultOper);
|
||||
virtual bool onLessThan(CBagVar *leftHandOper, CBagVar *rightHandOper, CBagVar &resultOper);
|
||||
virtual bool onGreaterThan(CBagVar *leftHandOper, CBagVar *rightHandOper, CBagVar &resultOper);
|
||||
virtual bool onLessThanEqual(CBagVar *leftHandOper, CBagVar *rightHandOper, CBagVar &resultOper);
|
||||
virtual bool onGreaterThanEqual(CBagVar *leftHandOper, CBagVar *rightHandOper, CBagVar &resultOper);
|
||||
virtual bool onPlusAssign(CBagVar *leftHandOper, CBagVar *rightHandOper, CBagVar &resultOper);
|
||||
virtual bool onMinusAssign(CBagVar *leftHandOper, CBagVar *rightHandOper, CBagVar &resultOper);
|
||||
virtual bool onContains(CBagVar *leftHandOper, CBagVar *rightHandOper, CBagVar &resultOper);
|
||||
virtual bool onHas(CBagVar *leftHandOper, CBagVar *rightHandOper, CBagVar &resultOper);
|
||||
virtual bool onCurrSDev(CBagVar *leftHandOper, CBagVar *rightHandOper, CBagVar &resultOper);
|
||||
virtual bool onPlus(CBagVar *leftHandOper, CBagVar *rightHandOper, CBagVar &resultOper);
|
||||
virtual bool onMinus(CBagVar *leftHandOper, CBagVar *rightHandOper, CBagVar &resultOper);
|
||||
virtual bool onMultiply(CBagVar *leftHandOper, CBagVar *rightHandOper, CBagVar &resultOper);
|
||||
virtual bool onDivide(CBagVar *leftHandOper, CBagVar *rightHandOper, CBagVar &resultOper);
|
||||
virtual bool onMod(CBagVar *leftHandOper, CBagVar *rightHandOper, CBagVar &resultOper);
|
||||
virtual bool onAnd(CBagVar *leftHandOper, CBagVar *rightHandOper, CBagVar &resultOper);
|
||||
virtual bool onOr(CBagVar *leftHandOper, CBagVar *rightHandOper, CBagVar &resultOper);
|
||||
virtual bool onStatus(CBagVar *leftHandOper, CBagVar *rightHandOper, CBagVar &resultOper);
|
||||
};
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
|
||||
#endif
|
||||
105
engines/bagel/spacebar/baglib/expression_object.cpp
Normal file
105
engines/bagel/spacebar/baglib/expression_object.cpp
Normal file
@@ -0,0 +1,105 @@
|
||||
/* 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/expression_object.h"
|
||||
#include "bagel/spacebar/baglib/master_win.h"
|
||||
#include "bagel/spacebar/baglib/var.h"
|
||||
#include "bagel/spacebar/baglib/storage_dev_win.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
CBagExpressionObject::CBagExpressionObject() : CBagObject() {
|
||||
_xObjType = EXPRESS_OBJ;
|
||||
_expression = nullptr;
|
||||
setConditional(false);
|
||||
setVisible(false);
|
||||
setTimeless(true);
|
||||
}
|
||||
|
||||
CBagExpressionObject::~CBagExpressionObject() {
|
||||
delete _expression;
|
||||
_expression = nullptr;
|
||||
|
||||
CBagObject::detach();
|
||||
}
|
||||
|
||||
bool CBagExpressionObject::runObject() {
|
||||
if (_expression != nullptr) {
|
||||
CBagVar localVar;
|
||||
_expression->evaluate(false, localVar);
|
||||
|
||||
if (!isConditional()) {
|
||||
if (getFileName().isEmpty())
|
||||
return false;
|
||||
|
||||
const int nIndex = getFileName().find("~~");
|
||||
if (nIndex > 0) {
|
||||
// This is a reference
|
||||
const CBofString objectStr = getFileName().left(nIndex);
|
||||
const CBofString propertyStr = getFileName().mid(nIndex + 2);
|
||||
|
||||
g_SDevManager->setObjectValue(objectStr, propertyStr, localVar.getNumValue());
|
||||
|
||||
} else {
|
||||
CBagVar *pVar = g_VarManager->getVariable(getFileName());
|
||||
if (pVar)
|
||||
pVar->setValue(localVar.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return CBagObject::runObject();
|
||||
}
|
||||
|
||||
ParseCodes CBagExpressionObject::setInfo(CBagIfstream &istr) {
|
||||
bool objectUpdatedFl = false;
|
||||
|
||||
while (!istr.eof()) {
|
||||
const char ch = (char)istr.peek();
|
||||
if (ch == '(') {
|
||||
//
|
||||
// AS - n number of slides in sprite
|
||||
//
|
||||
_expression = new CBagExpression();
|
||||
_expression->setInfo(istr);
|
||||
objectUpdatedFl = true;
|
||||
} else {
|
||||
const ParseCodes parseCode = CBagObject::setInfo(istr);
|
||||
if (parseCode == PARSING_DONE) {
|
||||
return PARSING_DONE;
|
||||
}
|
||||
|
||||
if (parseCode == UPDATED_OBJECT) {
|
||||
objectUpdatedFl = true;
|
||||
} else { // rc==UNKNOWN_TOKEN
|
||||
if (objectUpdatedFl)
|
||||
return UPDATED_OBJECT;
|
||||
|
||||
return UNKNOWN_TOKEN;
|
||||
}
|
||||
}
|
||||
}
|
||||
return PARSING_DONE;
|
||||
}
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
58
engines/bagel/spacebar/baglib/expression_object.h
Normal file
58
engines/bagel/spacebar/baglib/expression_object.h
Normal file
@@ -0,0 +1,58 @@
|
||||
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BAGEL_BAGLIB_EXPRESSION_OBJECT_H
|
||||
#define BAGEL_BAGLIB_EXPRESSION_OBJECT_H
|
||||
|
||||
#include "bagel/spacebar/baglib/object.h"
|
||||
#include "bagel/spacebar/baglib/expression.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
/**
|
||||
* CBagExpressionObject is an object that can be place within the slide window.
|
||||
*/
|
||||
class CBagExpressionObject : public CBagObject {
|
||||
private:
|
||||
CBagExpression *_expression;
|
||||
bool _conditionalFl;
|
||||
|
||||
public:
|
||||
CBagExpressionObject();
|
||||
virtual ~CBagExpressionObject();
|
||||
|
||||
bool runObject() override;
|
||||
ParseCodes setInfo(CBagIfstream &istr) override;
|
||||
|
||||
bool isConditional() const {
|
||||
return _conditionalFl;
|
||||
}
|
||||
void setConditional(bool b = true) {
|
||||
_conditionalFl = b;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
|
||||
#endif
|
||||
392
engines/bagel/spacebar/baglib/fmovie.cpp
Normal file
392
engines/bagel/spacebar/baglib/fmovie.cpp
Normal file
@@ -0,0 +1,392 @@
|
||||
/* 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 "graphics/cursorman.h"
|
||||
|
||||
#include "bagel/spacebar/baglib/fmovie.h"
|
||||
#include "bagel/boflib/string.h"
|
||||
#include "bagel/boflib/palette.h"
|
||||
#include "bagel/spacebar/boflib/app.h"
|
||||
#include "bagel/spacebar/baglib/master_win.h"
|
||||
#include "bagel/spacebar/baglib/pan_window.h"
|
||||
#include "bagel/spacebar/boflib/std_keys.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
CBagFMovie::CBagFMovie(CBofWindow *parent, const char *filename, CBofRect *bounds, bool useNewPalette, bool blackOutWindow) {
|
||||
// Allow movie to not shift to new palette.
|
||||
_useNewPaletteFl = useNewPalette;
|
||||
|
||||
// Black out first and last frame of flythroughs and examine movies
|
||||
_blackOutWindowFl = blackOutWindow;
|
||||
|
||||
CBagFMovie::initialize(parent);
|
||||
CBagFMovie::open(filename, bounds);
|
||||
}
|
||||
|
||||
CBagFMovie::~CBagFMovie() {
|
||||
CBagFMovie::closeMovie();
|
||||
}
|
||||
|
||||
ErrorCode CBagFMovie::initialize(CBofWindow *pParent) {
|
||||
// Movie Stuff
|
||||
_movieStatus = MOVIE_STOPPED;
|
||||
_escCanStopFl = true;
|
||||
_smackerPal = nullptr;
|
||||
_bmpBuf = nullptr;
|
||||
_filterBmp = nullptr;
|
||||
_bufferStart = nullptr;
|
||||
_bufferLength = 0;
|
||||
|
||||
// Smacker Stuff
|
||||
_smk = nullptr;
|
||||
_loopFl = false;
|
||||
|
||||
// Call dialog box creates
|
||||
if (create("MovieWin", 0, 0, 1, 1, pParent, 1) == ERR_NONE) {
|
||||
setCapture();
|
||||
}
|
||||
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
bool CBagFMovie::open(const char *filename, CBofRect *bounds) {
|
||||
// No filename, so put up an open file box
|
||||
if (filename == nullptr) {
|
||||
assert(filename);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (bounds != nullptr) {
|
||||
_cRect = *bounds;
|
||||
}
|
||||
|
||||
if (openMovie(filename)) {
|
||||
// We were given specific rect for movie
|
||||
if (bounds)
|
||||
reSize(bounds, true);
|
||||
else
|
||||
// Center the movie to the parent window
|
||||
centerRect();
|
||||
|
||||
// Paint the image to the screen.
|
||||
_filterBmp->paint(this, 0, 0);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CBagFMovie::openMovie(const char *sFilename) {
|
||||
assert(sFilename[0] != '\0');
|
||||
|
||||
if (_smk) {
|
||||
closeMovie();
|
||||
}
|
||||
_smk = new Video::SmackerDecoder();
|
||||
_smk->setSoundType(Audio::Mixer::kSFXSoundType);
|
||||
|
||||
// Opened failed ?
|
||||
if (!_smk->loadFile(sFilename)) {
|
||||
error("Movie not found=%s", sFilename);
|
||||
}
|
||||
|
||||
|
||||
// Allocate the bitmaps.
|
||||
_smackerPal = new CBofPalette();
|
||||
|
||||
_bmpBuf = new CBofBitmap(_smk->getWidth(), _smk->getHeight(), _smackerPal, false);
|
||||
|
||||
_filterBmp = new CBofBitmap(_smk->getWidth(), _smk->getHeight(), _smackerPal, false);
|
||||
_filterBmp->lock();
|
||||
|
||||
selectPalette(_smackerPal);
|
||||
|
||||
if (_bmpBuf) {
|
||||
_bmpBuf->lock();
|
||||
_bmpBuf->fillRect(nullptr, _smackerPal->getNearestIndex(CTEXT_WHITE));
|
||||
|
||||
_bufferStart = (char *)_bmpBuf->getPixelAddress(0, _bmpBuf->isTopDown() ? 0 : (_bmpBuf->height() - 1));
|
||||
_bufferLength = ABS(_bmpBuf->height() * _bmpBuf->width());
|
||||
|
||||
const Graphics::Surface *frame = _smk->decodeNextFrame();
|
||||
_smackerPal->setData(_smk->getPalette());
|
||||
if (frame) {
|
||||
_bmpBuf->getSurface().blitFrom(*frame);
|
||||
}
|
||||
}
|
||||
const bool repaintFl = true;
|
||||
|
||||
_bounds = CBofRect(0, 0, (uint16)_bmpBuf->width() - 1, (uint16)_bmpBuf->height() - 1);
|
||||
reSize(&_bounds, repaintFl);
|
||||
|
||||
CBagMasterWin *curWin = CBagel::getBagApp()->getMasterWnd();
|
||||
if (curWin != nullptr) {
|
||||
CBagStorageDevWnd *curSDev = curWin->getCurrentStorageDev();
|
||||
if ((curSDev != nullptr) && curSDev->isFiltered()) {
|
||||
const uint16 filterId = curSDev->getFilterId();
|
||||
const FilterFunction filterFunction = curSDev->getFilter();
|
||||
_bmpBuf->paint(_filterBmp);
|
||||
(*filterFunction)(filterId, _filterBmp, &_bounds);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CBagFMovie::onKeyHit(uint32 keyCode, uint32 /* repCount */) {
|
||||
if (_escCanStopFl && keyCode == BKEY_ESC) {
|
||||
// Clean up and exit
|
||||
_loopFl = false;
|
||||
stop();
|
||||
onMovieDone();
|
||||
}
|
||||
}
|
||||
|
||||
void CBagFMovie::onMainLoop() {
|
||||
if (!_smk->needsUpdate() || (_movieStatus == MOVIE_STOPPED))
|
||||
return;
|
||||
|
||||
|
||||
// Smack the current frame into the buffer
|
||||
const Graphics::Surface *frame = _smk->decodeNextFrame();
|
||||
if (_smk->hasDirtyPalette()) {
|
||||
_smackerPal->setData(_smk->getPalette());
|
||||
}
|
||||
if (frame) {
|
||||
_bmpBuf->getSurface().blitFrom(*frame);
|
||||
}
|
||||
|
||||
_bmpBuf->paint1To1(_filterBmp);
|
||||
|
||||
// Filter the bitmap.
|
||||
CBagMasterWin *curWin = CBagel::getBagApp()->getMasterWnd();
|
||||
if (curWin != nullptr) {
|
||||
CBagStorageDevWnd *curSDev = curWin->getCurrentStorageDev();
|
||||
if ((curSDev != nullptr) && curSDev->isFiltered()) {
|
||||
const uint16 filterId = curSDev->getFilterId();
|
||||
const FilterFunction filterFunction = curSDev->getFilter();
|
||||
(*filterFunction)(filterId, _filterBmp, &_bounds);
|
||||
}
|
||||
}
|
||||
|
||||
// Paint the buffer to the screen.
|
||||
_filterBmp->paint(this, 0, 0);
|
||||
|
||||
if (_movieStatus == MOVIE_FORWARD) {
|
||||
if (_smk->getCurFrame() == (int)_smk->getFrameCount() - 1) {
|
||||
if (_loopFl == false) {
|
||||
onMovieDone();
|
||||
} else {
|
||||
seekToStart();
|
||||
_smk->start();
|
||||
}
|
||||
}
|
||||
} else if (_movieStatus == MOVIE_REVERSE) {
|
||||
if (_smk->getCurFrame() == 0 || _smk->getCurFrame() == 1) {
|
||||
if (_loopFl == false) {
|
||||
onMovieDone();
|
||||
} else {
|
||||
seekToEnd();
|
||||
}
|
||||
} else {
|
||||
setFrame(_smk->getCurFrame() - 2); // HACK: Reverse playback
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CBagFMovie::onPaint(CBofRect *) {
|
||||
}
|
||||
|
||||
void CBagFMovie::closeMovie() {
|
||||
delete _smk;
|
||||
_smk = nullptr;
|
||||
|
||||
if (_filterBmp != nullptr) {
|
||||
_filterBmp->unlock();
|
||||
delete _filterBmp;
|
||||
_filterBmp = nullptr;
|
||||
}
|
||||
|
||||
if (_bmpBuf != nullptr) {
|
||||
_bmpBuf->unlock();
|
||||
delete _bmpBuf;
|
||||
_bmpBuf = nullptr;
|
||||
}
|
||||
|
||||
delete _smackerPal;
|
||||
_smackerPal = nullptr;
|
||||
|
||||
_bufferStart = nullptr;
|
||||
_bufferLength = 0;
|
||||
}
|
||||
|
||||
|
||||
void CBagFMovie::onClose() {
|
||||
closeMovie();
|
||||
CBofDialog::onClose();
|
||||
}
|
||||
|
||||
|
||||
void CBagFMovie::onMovieDone() {
|
||||
if (!_loopFl) {
|
||||
if (_bCaptured)
|
||||
releaseCapture();
|
||||
|
||||
getParent()->enable();
|
||||
_bEndDialog = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool CBagFMovie::play(bool loop, bool escCanStop) {
|
||||
_escCanStopFl = escCanStop;
|
||||
_loopFl = loop;
|
||||
|
||||
const bool retVal = play();
|
||||
|
||||
getParent()->disable();
|
||||
getParent()->flushAllMessages();
|
||||
|
||||
CursorMan.showMouse(false);
|
||||
|
||||
doModal();
|
||||
|
||||
CursorMan.showMouse(true);
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
||||
bool CBagFMovie::play() {
|
||||
if (!_smk)
|
||||
return false;
|
||||
|
||||
_smk->pauseVideo(false);
|
||||
// _smk->setReverse(false); // TODO: Not supported by SMK
|
||||
_smk->start();
|
||||
_movieStatus = MOVIE_FORWARD;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CBagFMovie::reverse(bool loop, bool escCanStop) {
|
||||
_escCanStopFl = escCanStop;
|
||||
_loopFl = loop;
|
||||
|
||||
const bool retVal = reverse();
|
||||
|
||||
getParent()->disable();
|
||||
getParent()->flushAllMessages();
|
||||
doModal();
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
bool CBagFMovie::reverse() {
|
||||
if (!_smk)
|
||||
return false;
|
||||
|
||||
_smk->pauseVideo(false);
|
||||
// _smk->setReverse(true); // TODO: Not supported by SMK
|
||||
_smk->start();
|
||||
_movieStatus = MOVIE_REVERSE;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CBagFMovie::stop() {
|
||||
if (!_smk)
|
||||
return false;
|
||||
|
||||
_smk->stop();
|
||||
_movieStatus = MOVIE_STOPPED;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CBagFMovie::pause() {
|
||||
if (!_smk)
|
||||
return false;
|
||||
|
||||
_smk->pauseVideo(true);
|
||||
_movieStatus = MOVIE_PAUSED;
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
bool CBagFMovie::seekToStart() {
|
||||
if (!_smk)
|
||||
return false;
|
||||
|
||||
_smk->rewind();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CBagFMovie::seekToEnd() {
|
||||
if (!_smk)
|
||||
return false;
|
||||
|
||||
setFrame(_smk->getFrameCount() - 2); // HACK: Reverse rewind
|
||||
return true;
|
||||
}
|
||||
|
||||
uint32 CBagFMovie::getFrame() {
|
||||
if (_smk) {
|
||||
return _smk->getCurFrame();
|
||||
}
|
||||
|
||||
return (uint32) -1;
|
||||
}
|
||||
|
||||
bool CBagFMovie::setFrame(uint32 frameNum) {
|
||||
if (!_smk)
|
||||
return false;
|
||||
|
||||
frameNum = CLIP<uint32>(frameNum, 0, _smk->getFrameCount() - 1);
|
||||
_smk->forceSeekToFrame(frameNum);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CBagFMovie::centerRect() {
|
||||
CBofRect clientRect = getParent()->getClientRect();
|
||||
const RECT parentRect = clientRect.getWinRect();
|
||||
const int clientWidth = parentRect.right - parentRect.left;
|
||||
const int clientHeight = parentRect.bottom - parentRect.top;
|
||||
|
||||
// Get Movies width and height
|
||||
const int movieWidth = _smk->getWidth();
|
||||
const int movieHeight = _smk->getHeight();
|
||||
|
||||
RECT movieBounds;
|
||||
movieBounds.left = (clientWidth - movieWidth) / 2;
|
||||
movieBounds.top = (clientHeight - movieHeight) / 2;
|
||||
movieBounds.right = movieBounds.left + movieWidth;
|
||||
movieBounds.bottom = movieBounds.top + movieHeight;
|
||||
|
||||
// Reposition the playback window
|
||||
clientRect = movieBounds;
|
||||
reSize(&clientRect, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
139
engines/bagel/spacebar/baglib/fmovie.h
Normal file
139
engines/bagel/spacebar/baglib/fmovie.h
Normal file
@@ -0,0 +1,139 @@
|
||||
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BAGEL_BAGLIB_FMOVIE_H
|
||||
#define BAGEL_BAGLIB_FMOVIE_H
|
||||
|
||||
#include "video/smk_decoder.h"
|
||||
#include "bagel/spacebar/boflib/gui/dialog.h"
|
||||
#include "bagel/boflib/rect.h"
|
||||
#include "bagel/boflib/error.h"
|
||||
#include "bagel/boflib/palette.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
class CBagFMovie : public CBofDialog {
|
||||
public:
|
||||
enum MovieStatus {
|
||||
MOVIE_STOPPED, MOVIE_PAUSED, MOVIE_FORWARD, MOVIE_REVERSE
|
||||
};
|
||||
|
||||
protected:
|
||||
Video::SmackerDecoder *_smk;
|
||||
|
||||
bool _escCanStopFl;
|
||||
bool _loopFl;
|
||||
MovieStatus _movieStatus;
|
||||
|
||||
CBofBitmap *_bmpBuf;
|
||||
CBofBitmap *_filterBmp;
|
||||
CBofPalette *_smackerPal;
|
||||
char *_bufferStart;
|
||||
int _bufferLength;
|
||||
CBofRect _bounds;
|
||||
bool _useNewPaletteFl;
|
||||
bool _blackOutWindowFl;
|
||||
|
||||
/**
|
||||
* Open the movie file, center it in parent, rewind it, and realize it's
|
||||
* palette in the background
|
||||
*/
|
||||
virtual ErrorCode initialize(CBofWindow *pParent);
|
||||
|
||||
/**
|
||||
* Open the movie file, center it in parent, rewind it, and realize it's
|
||||
* palette in the background.
|
||||
*/
|
||||
virtual bool openMovie(const char *sFilename);
|
||||
|
||||
/**
|
||||
* Close the MCI Device file
|
||||
*/
|
||||
virtual void closeMovie();
|
||||
|
||||
void onReSize(CBofSize *pSize) override {
|
||||
};
|
||||
|
||||
virtual bool play();
|
||||
virtual bool reverse();
|
||||
|
||||
void onLButtonUp(uint32 flags, CBofPoint *point, void * = nullptr) override {
|
||||
onButtonUp(flags, point);
|
||||
}
|
||||
virtual void onButtonUp(uint32 flags, CBofPoint *point) {
|
||||
};
|
||||
void onPaint(CBofRect *pRect) override;
|
||||
virtual void onMovieDone();
|
||||
void onClose() override;
|
||||
void onMainLoop() override;
|
||||
|
||||
/**
|
||||
* Catch the ESC key when hit
|
||||
*/
|
||||
void onKeyHit(uint32 keyCode, uint32 repCount) override;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Initializes Movie Object and opens movie file @ Rect
|
||||
* @param parent A pointer to the parent window
|
||||
* @param filename String containing filename of movie to be opened
|
||||
* @param bounds Location for video object relative to parent
|
||||
* @param useNewPalette
|
||||
* @param blackOutWindow
|
||||
*/
|
||||
CBagFMovie(CBofWindow *parent = nullptr, const char *filename = nullptr,
|
||||
CBofRect *bounds = nullptr, bool useNewPalette = true, bool blackOutWindow = false);
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
~CBagFMovie();
|
||||
|
||||
/**
|
||||
* Open the movie file, place it @ bounds, rewind it, and realize it's
|
||||
* palette in the background.
|
||||
*/
|
||||
virtual bool open(const char *filename = nullptr, CBofRect *bounds = nullptr);
|
||||
|
||||
virtual bool play(bool loop, bool escCanStop = true);
|
||||
virtual bool reverse(bool loop, bool escCanStop = true);
|
||||
virtual bool pause();
|
||||
virtual bool stop();
|
||||
|
||||
virtual MovieStatus status() {
|
||||
return _movieStatus;
|
||||
}
|
||||
|
||||
virtual bool seekToStart();
|
||||
virtual bool seekToEnd();
|
||||
|
||||
virtual uint32 getFrame();
|
||||
virtual bool setFrame(uint32 frameNum);
|
||||
|
||||
virtual bool centerRect();
|
||||
};
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
|
||||
#endif
|
||||
274
engines/bagel/spacebar/baglib/help.cpp
Normal file
274
engines/bagel/spacebar/baglib/help.cpp
Normal file
@@ -0,0 +1,274 @@
|
||||
/* 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/help.h"
|
||||
#include "bagel/spacebar/boflib/file.h"
|
||||
#include "bagel/spacebar/baglib/bagel.h"
|
||||
#include "bagel/spacebar/baglib/master_win.h"
|
||||
#include "bagel/boflib/file_functions.h"
|
||||
#include "bagel/boflib/log.h"
|
||||
#include "bagel/spacebar/boflib/std_keys.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
#define RULES_DIR "$SBARDIR\\GENERAL\\RULES\\"
|
||||
|
||||
#define HELP_OK_X 257
|
||||
#define HELP_OK_Y 377
|
||||
#define HELP_OK_CX 125
|
||||
#define HELP_OK_CY 30
|
||||
#define HELP_OK_UP "DONE1.BMP"
|
||||
#define HELP_OK_DOWN "DONE2.BMP"
|
||||
#define HELP_OK_FOCUS "DONE3.BMP"
|
||||
#define HELP_OK_DISABLED "DONE4.BMP"
|
||||
#define HELP_OK_ID 1
|
||||
|
||||
#define HELP_PAGE_UP_X 81
|
||||
#define HELP_PAGE_UP_Y 377
|
||||
#define HELP_PAGE_UP_CX 125
|
||||
#define HELP_PAGE_UP_CY 30
|
||||
#define HELP_PAGE_UP_UP "PAGEUP1.BMP"
|
||||
#define HELP_PAGE_UP_DOWN "PAGEUP2.BMP"
|
||||
#define HELP_PAGE_UP_FOCUS "PAGEUP3.BMP"
|
||||
#define HELP_PAGE_UP_DISABLED "PAGEUP4.BMP"
|
||||
#define HELP_PAGE_UP_ID 2
|
||||
|
||||
#define HELP_PAGE_DOWN_X 435
|
||||
#define HELP_PAGE_DOWN_Y 377
|
||||
#define HELP_PAGE_DOWN_CX 125
|
||||
#define HELP_PAGE_DOWN_CY 30
|
||||
#define HELP_PAGE_DOWN_UP "PAGEDN1.BMP"
|
||||
#define HELP_PAGE_DOWN_DOWN "PAGEDN2.BMP"
|
||||
#define HELP_PAGE_DOWN_FOCUS "PAGEDN3.BMP"
|
||||
#define HELP_PAGE_DOWN_DISABLED "PAGEDN4.BMP"
|
||||
#define HELP_PAGE_DOWN_ID 3
|
||||
|
||||
// Local functions
|
||||
const char *buildHelpDir(const char *fileName);
|
||||
|
||||
|
||||
CBagHelp::CBagHelp() {
|
||||
_textBox = nullptr;
|
||||
_okButton = nullptr;
|
||||
_pageUp = nullptr;
|
||||
_pageDown = nullptr;
|
||||
_savePalette = nullptr;
|
||||
setFlags(0);
|
||||
}
|
||||
|
||||
ErrorCode CBagHelp::attach() {
|
||||
assert(isValidObject(this));
|
||||
|
||||
// Save off the current game's palette
|
||||
_savePalette = CBofApp::getApp()->getPalette();
|
||||
|
||||
// Insert ours
|
||||
CBofPalette *backPal = _pBackdrop->getPalette();
|
||||
CBofApp::getApp()->setPalette(backPal);
|
||||
|
||||
_okButton = new CBofBmpButton;
|
||||
|
||||
CBofBitmap *upBmp = loadBitmap(buildHelpDir(HELP_OK_UP), backPal);
|
||||
CBofBitmap *downBmp = loadBitmap(buildHelpDir(HELP_OK_DOWN), backPal);
|
||||
CBofBitmap *focusBmp = loadBitmap(buildHelpDir(HELP_OK_FOCUS), backPal);
|
||||
CBofBitmap *disableBmp = loadBitmap(buildHelpDir(HELP_OK_DISABLED), backPal);
|
||||
|
||||
_okButton->loadBitmaps(upBmp, downBmp, focusBmp, disableBmp);
|
||||
_okButton->create("OK", HELP_OK_X, HELP_OK_Y, HELP_OK_CX, HELP_OK_CY, this, HELP_OK_ID);
|
||||
_okButton->show();
|
||||
|
||||
_pageUp = new CBofBmpButton;
|
||||
|
||||
upBmp = loadBitmap(buildHelpDir(HELP_PAGE_UP_UP), backPal);
|
||||
downBmp = loadBitmap(buildHelpDir(HELP_PAGE_UP_DOWN), backPal);
|
||||
focusBmp = loadBitmap(buildHelpDir(HELP_PAGE_UP_FOCUS), backPal);
|
||||
disableBmp = loadBitmap(buildHelpDir(HELP_PAGE_UP_DISABLED), backPal);
|
||||
|
||||
_pageUp->loadBitmaps(upBmp, downBmp, focusBmp, disableBmp);
|
||||
_pageUp->create("PageUp", HELP_PAGE_UP_X, HELP_PAGE_UP_Y, HELP_PAGE_UP_CX, HELP_PAGE_UP_CY, this, HELP_PAGE_UP_ID);
|
||||
_pageUp->show();
|
||||
|
||||
_pageDown = new CBofBmpButton;
|
||||
|
||||
upBmp = loadBitmap(buildHelpDir(HELP_PAGE_DOWN_UP), backPal);
|
||||
downBmp = loadBitmap(buildHelpDir(HELP_PAGE_DOWN_DOWN), backPal);
|
||||
focusBmp = loadBitmap(buildHelpDir(HELP_PAGE_DOWN_FOCUS), backPal);
|
||||
disableBmp = loadBitmap(buildHelpDir(HELP_PAGE_DOWN_DISABLED), backPal);
|
||||
|
||||
_pageDown->loadBitmaps(upBmp, downBmp, focusBmp, disableBmp);
|
||||
|
||||
_pageDown->create("PageDown", HELP_PAGE_DOWN_X, HELP_PAGE_DOWN_Y, HELP_PAGE_DOWN_CX, HELP_PAGE_DOWN_CY, this, HELP_PAGE_DOWN_ID);
|
||||
_pageDown->show();
|
||||
|
||||
CBofFile file(_textFile, CBF_BINARY | CBF_READONLY);
|
||||
|
||||
const uint32 size = file.getLength();
|
||||
char *buffer = (char *)bofCleanAlloc(size + 1);
|
||||
|
||||
file.read(buffer, size);
|
||||
|
||||
CBofRect cRect;
|
||||
cRect.setRect(120, 100, 550, 348);
|
||||
|
||||
_textBox = new CBofTextBox(this, &cRect, buffer);
|
||||
_textBox->setPageLength(18);
|
||||
|
||||
bofFree(buffer);
|
||||
|
||||
CBagCursor::showSystemCursor();
|
||||
|
||||
return _errCode;
|
||||
}
|
||||
|
||||
|
||||
ErrorCode CBagHelp::detach() {
|
||||
assert(isValidObject(this));
|
||||
|
||||
CBagCursor::hideSystemCursor();
|
||||
|
||||
delete _textBox;
|
||||
_textBox = nullptr;
|
||||
|
||||
delete _pageDown;
|
||||
_pageDown = nullptr;
|
||||
|
||||
delete _pageUp;
|
||||
_pageUp = nullptr;
|
||||
|
||||
delete _okButton;
|
||||
_okButton = nullptr;
|
||||
|
||||
CBofApp::getApp()->setPalette(_savePalette);
|
||||
|
||||
return _errCode;
|
||||
}
|
||||
|
||||
ErrorCode CBagHelp::SetHelpFile(const char *textFile) {
|
||||
assert(isValidObject(this));
|
||||
assert(textFile != nullptr);
|
||||
|
||||
_textFile = textFile;
|
||||
|
||||
return _errCode;
|
||||
}
|
||||
|
||||
|
||||
void CBagHelp::onPaint(CBofRect *rect) {
|
||||
assert(isValidObject(this));
|
||||
|
||||
paintBackdrop(rect);
|
||||
|
||||
if (_textBox != nullptr) {
|
||||
_textBox->display();
|
||||
}
|
||||
|
||||
validateAnscestors();
|
||||
}
|
||||
|
||||
|
||||
void CBagHelp::onKeyHit(uint32 keyCode, uint32 repCount) {
|
||||
assert(isValidObject(this));
|
||||
|
||||
switch (keyCode) {
|
||||
case BKEY_UP:
|
||||
if (_textBox != nullptr) {
|
||||
_textBox->lineUp();
|
||||
}
|
||||
break;
|
||||
|
||||
case BKEY_DOWN:
|
||||
if (_textBox != nullptr) {
|
||||
_textBox->lineDown();
|
||||
}
|
||||
break;
|
||||
|
||||
case BKEY_PAGEUP:
|
||||
if (_textBox != nullptr) {
|
||||
_textBox->pageUp();
|
||||
}
|
||||
break;
|
||||
|
||||
case BKEY_PAGEDOWN:
|
||||
if (_textBox != nullptr) {
|
||||
_textBox->pageDown();
|
||||
}
|
||||
break;
|
||||
|
||||
case BKEY_ESC:
|
||||
case BKEY_ENTER:
|
||||
close();
|
||||
// FIXME: missing break?
|
||||
// fallthrough
|
||||
|
||||
default:
|
||||
CBofDialog::onKeyHit(keyCode, repCount);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CBagHelp::onBofButton(CBofObject *object, int flags) {
|
||||
assert(isValidObject(this));
|
||||
assert(object != nullptr);
|
||||
|
||||
if (flags != BUTTON_CLICKED)
|
||||
return;
|
||||
|
||||
CBofBmpButton *pButton = (CBofBmpButton *)object;
|
||||
|
||||
switch (pButton->getControlID()) {
|
||||
case HELP_OK_ID:
|
||||
close();
|
||||
break;
|
||||
|
||||
case HELP_PAGE_UP_ID:
|
||||
if (_textBox != nullptr) {
|
||||
_textBox->pageUp();
|
||||
}
|
||||
break;
|
||||
|
||||
case HELP_PAGE_DOWN_ID:
|
||||
if (_textBox != nullptr) {
|
||||
_textBox->pageDown();
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
logWarning("Unknown button");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const char *buildHelpDir(const char *fileName) {
|
||||
return formPath(RULES_DIR, fileName);
|
||||
}
|
||||
|
||||
void CBagHelp::onInitDialog() {
|
||||
assert(isValidObject(this));
|
||||
|
||||
CBofDialog::onInitDialog();
|
||||
|
||||
attach();
|
||||
}
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
61
engines/bagel/spacebar/baglib/help.h
Normal file
61
engines/bagel/spacebar/baglib/help.h
Normal file
@@ -0,0 +1,61 @@
|
||||
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BAGEL_BAGLIB_HELP_H
|
||||
#define BAGEL_BAGLIB_HELP_H
|
||||
|
||||
#include "bagel/spacebar/baglib/storage_dev_win.h"
|
||||
#include "bagel/spacebar/boflib/gui/text_box.h"
|
||||
#include "bagel/spacebar/boflib/gui/button.h"
|
||||
#include "bagel/boflib/string.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
class CBagHelp : public CBofDialog {
|
||||
public:
|
||||
CBagHelp();
|
||||
|
||||
virtual ErrorCode attach();
|
||||
virtual ErrorCode detach();
|
||||
void onInitDialog() override;
|
||||
|
||||
ErrorCode SetHelpFile(const char *textFile);
|
||||
|
||||
protected:
|
||||
void onPaint(CBofRect *rect) override;
|
||||
void onBofButton(CBofObject *object, int state) override;
|
||||
void onKeyHit(uint32 keyCode, uint32 repCount) override;
|
||||
|
||||
CBofString _textFile;
|
||||
|
||||
CBofTextBox *_textBox;
|
||||
CBofBmpButton *_okButton;
|
||||
CBofBmpButton *_pageUp;
|
||||
CBofBmpButton *_pageDown;
|
||||
CBofPalette *_savePalette;
|
||||
};
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
|
||||
#endif
|
||||
112
engines/bagel/spacebar/baglib/ifstream.cpp
Normal file
112
engines/bagel/spacebar/baglib/ifstream.cpp
Normal file
@@ -0,0 +1,112 @@
|
||||
/* 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 "common/util.h"
|
||||
|
||||
#include "bagel/spacebar/baglib/ifstream.h"
|
||||
#include "bagel/boflib/stdinc.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
CBagIfstream::CBagIfstream(char *buffer, int length) {
|
||||
_currPtr = _buffer = buffer;
|
||||
_eof = buffer + length;
|
||||
_length = length;
|
||||
|
||||
_lineNumber = 1;
|
||||
_lineString = "";
|
||||
}
|
||||
|
||||
int CBagIfstream::getCh() {
|
||||
const int ch = get();
|
||||
return ch;
|
||||
}
|
||||
|
||||
int CBagIfstream::getLine(char *buffer, int length) {
|
||||
return get(buffer, length, '\n');
|
||||
}
|
||||
|
||||
void CBagIfstream::putBack() {
|
||||
if (_currPtr > _buffer)
|
||||
_currPtr--;
|
||||
}
|
||||
|
||||
int CBagIfstream::get() {
|
||||
if (_currPtr != _eof)
|
||||
return *_currPtr++;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int CBagIfstream::get(char *buffer, int count, char delimiter) {
|
||||
if (!eof()) {
|
||||
count = MIN<int>(count, _eof - _currPtr);
|
||||
|
||||
char *p = (char *)memchr(_currPtr, delimiter, count);
|
||||
if (p != nullptr) {
|
||||
count = MIN<int>(count, p - _currPtr /* + 1*/);
|
||||
}
|
||||
memcpy(buffer, _currPtr, count);
|
||||
_currPtr += count;
|
||||
assert(_currPtr <= _eof);
|
||||
|
||||
return _currPtr == _eof ? -1 : 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int CBagIfstream::peek() {
|
||||
if (_currPtr != _eof)
|
||||
return *_currPtr;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int CBagIfstream::getCh(char *ch, int count, char delimiter) {
|
||||
get(ch, count, delimiter);
|
||||
|
||||
if (delimiter == '\n') {
|
||||
_lineNumber++;
|
||||
_lineString = "";
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool CBagIfstream::eatWhite() {
|
||||
int ch = peek();
|
||||
while ((ch == ' ') || (ch == '\t') || (ch == '\r') || (ch == '\n')) {
|
||||
|
||||
if (ch == '\n') {
|
||||
_lineNumber++;
|
||||
_lineString = "";
|
||||
}
|
||||
getCh();
|
||||
ch = peek();
|
||||
}
|
||||
|
||||
return (ch != -1);
|
||||
}
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
72
engines/bagel/spacebar/baglib/ifstream.h
Normal file
72
engines/bagel/spacebar/baglib/ifstream.h
Normal file
@@ -0,0 +1,72 @@
|
||||
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BAGEL_BAGLIB_IFSTREAM_H
|
||||
#define BAGEL_BAGLIB_IFSTREAM_H
|
||||
|
||||
#include "bagel/boflib/object.h"
|
||||
#include "bagel/boflib/string.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
class CBagIfstream : public CBofObject {
|
||||
private:
|
||||
int _lineNumber;
|
||||
CBofString _lineString;
|
||||
|
||||
char *_buffer;
|
||||
char *_currPtr;
|
||||
char *_eof;
|
||||
int _length;
|
||||
|
||||
public:
|
||||
CBagIfstream(char *buffer, int length);
|
||||
virtual ~CBagIfstream() {}
|
||||
|
||||
int getCh();
|
||||
int getLine(char *buffer, int length);
|
||||
void putBack();
|
||||
int get();
|
||||
int get(char *buffer, int count, char delimiter = '\n');
|
||||
int peek();
|
||||
int getCh(char *ch, int count, char delimiter = '\n');
|
||||
bool eatWhite();
|
||||
|
||||
bool eof() const {
|
||||
return (_currPtr == _eof);
|
||||
}
|
||||
int getLineNumber() const {
|
||||
return _lineNumber;
|
||||
}
|
||||
int getSize() const {
|
||||
return _length;
|
||||
}
|
||||
const CBofString &getLineString() const {
|
||||
return _lineString;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
|
||||
#endif
|
||||
119
engines/bagel/spacebar/baglib/inv.cpp
Normal file
119
engines/bagel/spacebar/baglib/inv.cpp
Normal file
@@ -0,0 +1,119 @@
|
||||
/* 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/inv.h"
|
||||
#include "bagel/spacebar/baglib/character_object.h"
|
||||
#include "bagel/spacebar/baglib/movie_object.h"
|
||||
#include "bagel/spacebar/baglib/master_win.h"
|
||||
#include "bagel/spacebar/baglib/zoom_pda.h"
|
||||
#include "bagel/spacebar/baglib/pda.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
#define FIRS_STASH_MOV "FIRST_STASH_MOVIE"
|
||||
|
||||
bool CBagInv::_firstStashFl;
|
||||
|
||||
//
|
||||
// This is called when a object is inserted into the inventory
|
||||
// The wand on the PDA should animate
|
||||
//
|
||||
|
||||
ErrorCode CBagInv::activateLocalObject(const CBofString &objectName) {
|
||||
|
||||
CBagStorageDev *pdaSDev = g_SDevManager->getStorageDevice("BPDA_WLD");
|
||||
|
||||
// Don't do any wand animation if we are zoomed.
|
||||
SBZoomPda *zoomPda = (SBZoomPda *)g_SDevManager->getStorageDevice("BPDAZ_WLD");
|
||||
assert(zoomPda != nullptr);
|
||||
const bool zoomedFl = (zoomPda ? zoomPda->getZoomed() : false);
|
||||
|
||||
if (pdaSDev && zoomedFl == false) {
|
||||
CBagCharacterObject *wand = (CBagCharacterObject *)pdaSDev->getObject("WANDANIM");
|
||||
CBagPDA *pda = (CBagPDA *)pdaSDev;
|
||||
|
||||
if (wand) {
|
||||
wand->setPlaybackSpeed(1);
|
||||
wand->setNumOfLoops(1);
|
||||
|
||||
// Let our character anim know that this is our PDA Wand,
|
||||
// it will need to let the pda update code know that
|
||||
// it needs to get redrawn.
|
||||
CBagCharacterObject::setPdaWand(wand);
|
||||
pda->setDirty(true);
|
||||
}
|
||||
}
|
||||
|
||||
if (zoomedFl == false) {
|
||||
// Check to see if we are in the bar
|
||||
CBagVar *var = g_VarManager->getVariable("INBAR");
|
||||
if (var != nullptr) {
|
||||
var = g_VarManager->getVariable("FIRST_STASH");
|
||||
|
||||
// If this is our first stash, play the smacker associated with it.
|
||||
if ((var != nullptr) && (var->getNumValue() == 0)) {
|
||||
CBagMovieObject *pMovie = (CBagMovieObject *)getObject(FIRS_STASH_MOV);
|
||||
if (pMovie) {
|
||||
if (pMovie->isAttached() == false) {
|
||||
pMovie->attach();
|
||||
pMovie->setVisible();
|
||||
}
|
||||
|
||||
pMovie->runObject();
|
||||
}
|
||||
|
||||
var->setValue(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return CBagStorageDevBmp::activateLocalObject(objectName);
|
||||
}
|
||||
|
||||
/**
|
||||
* This is called when a object is removed from the inventory
|
||||
* The wand on the PDA should animate
|
||||
*/
|
||||
ErrorCode CBagInv::deactivateLocalObject(const CBofString &objectName) {
|
||||
CBagStorageDev *pdaSDev = g_SDevManager->getStorageDevice("BPDA_WLD");
|
||||
|
||||
// Don't do any wand animation if we are zoomed.
|
||||
SBZoomPda *zoomPDA = (SBZoomPda *)g_SDevManager->getStorageDevice("BPDAZ_WLD");
|
||||
assert(zoomPDA != nullptr);
|
||||
const bool zoomedFl = (zoomPDA ? zoomPDA->getZoomed() : false);
|
||||
|
||||
if (pdaSDev && zoomedFl == false) {
|
||||
CBagCharacterObject *wand = (CBagCharacterObject *)pdaSDev->getObject("WANDANIM");
|
||||
if (wand) {
|
||||
wand->setPlaybackSpeed(-1);
|
||||
wand->setNumOfLoops(1);
|
||||
|
||||
// Let it know our ending frame is 0, not 1.
|
||||
wand->setEndFrame(0);
|
||||
}
|
||||
}
|
||||
|
||||
return CBagStorageDevBmp::deactivateLocalObject(objectName);;
|
||||
}
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
51
engines/bagel/spacebar/baglib/inv.h
Normal file
51
engines/bagel/spacebar/baglib/inv.h
Normal file
@@ -0,0 +1,51 @@
|
||||
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BAGEL_BAGLIB_INV_H
|
||||
#define BAGEL_BAGLIB_INV_H
|
||||
|
||||
#include "bagel/spacebar/baglib/storage_dev_bmp.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
class CBagInv : public CBagStorageDevBmp {
|
||||
protected:
|
||||
static bool _firstStashFl;
|
||||
|
||||
public:
|
||||
CBagInv() : CBagStorageDevBmp() {
|
||||
}
|
||||
virtual ~CBagInv() {
|
||||
}
|
||||
static void initialize() {
|
||||
_firstStashFl = true;
|
||||
}
|
||||
|
||||
ErrorCode activateLocalObject(const CBofString &objectName) override;
|
||||
ErrorCode deactivateLocalObject(const CBofString &objectName) override;
|
||||
};
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
|
||||
#endif
|
||||
209
engines/bagel/spacebar/baglib/link_object.cpp
Normal file
209
engines/bagel/spacebar/baglib/link_object.cpp
Normal file
@@ -0,0 +1,209 @@
|
||||
/* 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/link_object.h"
|
||||
#include "bagel/spacebar/baglib/master_win.h"
|
||||
#include "bagel/spacebar/baglib/pan_window.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
extern bool g_noMenuFl;
|
||||
|
||||
CBagLinkObject::CBagLinkObject() {
|
||||
_xObjType = LINK_OBJ;
|
||||
_linkType = LINK;
|
||||
_destLocation = CBofPoint(0, 0);
|
||||
_srcLocation = CBofPoint(-1, -1);
|
||||
_fade = 0;
|
||||
|
||||
setVisible(false);
|
||||
CBagObject::setOverCursor(5);
|
||||
}
|
||||
|
||||
CBagLinkObject::~CBagLinkObject() {
|
||||
CBagObject::detach();
|
||||
}
|
||||
|
||||
CBofRect CBagLinkObject::getRect() {
|
||||
const CBofPoint p = getPosition();
|
||||
const CBofSize s = getSize();
|
||||
CBofRect r = CBofRect(p, s);
|
||||
return r;
|
||||
}
|
||||
|
||||
ParseCodes CBagLinkObject::setInfo(CBagIfstream &istr) {
|
||||
bool objectUpdatedFl = false;
|
||||
|
||||
ParseCodes returnCode = PARSING_DONE;
|
||||
bool doneFl = false;
|
||||
|
||||
while (!doneFl && !istr.eof()) {
|
||||
const char ch = (char)istr.peek();
|
||||
switch (ch) {
|
||||
//
|
||||
// @[x,y] - destination of a flythru. start point in next world
|
||||
//
|
||||
case '@': {
|
||||
CBofRect r;
|
||||
istr.getCh();
|
||||
getRectFromStream(istr, r);
|
||||
setDstLoc(r.topLeft());
|
||||
objectUpdatedFl = true;
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
// #[x,y] - start location of a flythru. start point in this world
|
||||
//
|
||||
case '#': {
|
||||
CBofRect r;
|
||||
istr.getCh();
|
||||
getRectFromStream(istr, r);
|
||||
setSrcLoc(r.topLeft());
|
||||
objectUpdatedFl = true;
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
// AS [LINK|CLOSEUP] - how to run the link
|
||||
//
|
||||
case 'A': {
|
||||
char localBuffer[256];
|
||||
localBuffer[0] = 0;
|
||||
CBofString curString(localBuffer, 256);
|
||||
getAlphaNumFromStream(istr, curString);
|
||||
|
||||
if (!curString.find("AS")) {
|
||||
istr.eatWhite();
|
||||
getAlphaNumFromStream(istr, curString);
|
||||
if (!curString.find("CLOSEUP")) {
|
||||
_linkType = CLOSEUP;
|
||||
setOverCursor(2);
|
||||
objectUpdatedFl = true;
|
||||
} else if (!curString.find("LINK")) {
|
||||
_linkType = LINK;
|
||||
objectUpdatedFl = true;
|
||||
} else {
|
||||
putbackStringOnStream(istr, curString);
|
||||
putbackStringOnStream(istr, "AS ");
|
||||
}
|
||||
} else {
|
||||
putbackStringOnStream(istr, curString);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
// FADE n
|
||||
//
|
||||
case 'F': {
|
||||
char localBuffer[256];
|
||||
localBuffer[0] = 0;
|
||||
CBofString curString(localBuffer, 256);
|
||||
getAlphaNumFromStream(istr, curString);
|
||||
|
||||
if (!curString.find("FADE")) {
|
||||
istr.eatWhite();
|
||||
getIntFromStream(istr, _fade);
|
||||
objectUpdatedFl = true;
|
||||
} else {
|
||||
putbackStringOnStream(istr, curString);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
// No match return from function
|
||||
//
|
||||
default: {
|
||||
const ParseCodes parseCode = CBagObject::setInfo(istr);
|
||||
|
||||
if (parseCode == PARSING_DONE) {
|
||||
returnCode = PARSING_DONE;
|
||||
doneFl = true;
|
||||
|
||||
} else if (parseCode == UPDATED_OBJECT) {
|
||||
objectUpdatedFl = true;
|
||||
|
||||
} else { // rc==UNKNOWN_TOKEN
|
||||
if (objectUpdatedFl)
|
||||
returnCode = UPDATED_OBJECT;
|
||||
else
|
||||
returnCode = UNKNOWN_TOKEN;
|
||||
|
||||
doneFl = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return returnCode;
|
||||
}
|
||||
|
||||
|
||||
bool CBagLinkObject::runObject() {
|
||||
// Reset Wield
|
||||
g_noMenuFl = false;
|
||||
|
||||
char buffer[256];
|
||||
buffer[0] = '\0';
|
||||
CBofString curStr(buffer, 256);
|
||||
curStr = getFileName();
|
||||
|
||||
// If this is a special link (using the last known sdev stack),
|
||||
// then find it's value, and use that instead.
|
||||
if (getFileName().find("$LASTWORLD") != -1) {
|
||||
curStr = getFileName();
|
||||
|
||||
CBagVar *var = g_VarManager->getVariable("$LASTWORLD");
|
||||
if (var != nullptr) {
|
||||
curStr.replaceStr("$LASTWORLD", var->getValue());
|
||||
}
|
||||
}
|
||||
|
||||
CBagMasterWin::setActiveCursor(6);
|
||||
|
||||
CBagStorageDevWnd *curSDev = CBagel::getBagApp()->getMasterWnd()->getCurrentStorageDev();
|
||||
|
||||
// Set the link position for the storage device we are about to jump to
|
||||
CBagStorageDev *destWin = g_SDevManager->getStorageDevice(curStr);
|
||||
if (destWin) {
|
||||
destWin->setloadFilePos(getDestLoc());
|
||||
}
|
||||
|
||||
CBagMasterWin *pMasterWin = CBagel::getBagApp()->getMasterWnd();
|
||||
if (pMasterWin) {
|
||||
pMasterWin->setCurrfadeIn(_fade);
|
||||
pMasterWin->setStorageDev(curStr);
|
||||
}
|
||||
|
||||
CBagStorageDevWnd *otherSDev = CBagel::getBagApp()->getMasterWnd()->getCurrentStorageDev();
|
||||
if (!curSDev->isCloseup() && !otherSDev->isCloseup()) {
|
||||
g_VarManager->incrementTimers();
|
||||
}
|
||||
|
||||
return CBagObject::runObject();
|
||||
}
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
82
engines/bagel/spacebar/baglib/link_object.h
Normal file
82
engines/bagel/spacebar/baglib/link_object.h
Normal file
@@ -0,0 +1,82 @@
|
||||
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BAGEL_BAGLIB_LINK_OBJECT_H
|
||||
#define BAGEL_BAGLIB_LINK_OBJECT_H
|
||||
|
||||
#include "bagel/spacebar/baglib/object.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
/**
|
||||
* CBagLinkObject is an object that can be place within the slide window.
|
||||
*/
|
||||
class CBagLinkObject : public CBagObject {
|
||||
public:
|
||||
enum LinkType {
|
||||
LINK = 0, CLOSEUP = 1
|
||||
};
|
||||
|
||||
private:
|
||||
CBofSize _size;
|
||||
CBofPoint _destLocation;
|
||||
CBofPoint _srcLocation;
|
||||
LinkType _linkType;
|
||||
int _fade;
|
||||
|
||||
public:
|
||||
CBagLinkObject();
|
||||
virtual ~CBagLinkObject();
|
||||
|
||||
// Return UPDATED_OBJECT if the Object had members that are properly initialized/de-initialized
|
||||
ParseCodes setInfo(CBagIfstream &istr) override;
|
||||
|
||||
bool runObject() override;
|
||||
|
||||
CBofRect getRect() override;
|
||||
|
||||
CBofSize getSize() const {
|
||||
return _size;
|
||||
}
|
||||
CBofPoint getDestLoc() const {
|
||||
return _destLocation;
|
||||
}
|
||||
CBofPoint getSrcLoc() const {
|
||||
return _srcLocation;
|
||||
}
|
||||
|
||||
void setSize(const CBofSize &size) override {
|
||||
_size = size;
|
||||
}
|
||||
void setDstLoc(const CBofPoint &loc) {
|
||||
_destLocation = loc;
|
||||
}
|
||||
void setSrcLoc(const CBofPoint &loc) {
|
||||
_srcLocation = loc;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
|
||||
#endif
|
||||
1069
engines/bagel/spacebar/baglib/log_msg.cpp
Normal file
1069
engines/bagel/spacebar/baglib/log_msg.cpp
Normal file
File diff suppressed because it is too large
Load Diff
261
engines/bagel/spacebar/baglib/log_msg.h
Normal file
261
engines/bagel/spacebar/baglib/log_msg.h
Normal file
@@ -0,0 +1,261 @@
|
||||
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BAGEL_BAGLIB_LOG_MSG_H
|
||||
#define BAGEL_BAGLIB_LOG_MSG_H
|
||||
|
||||
#include "bagel/spacebar/baglib/text_object.h"
|
||||
#include "bagel/spacebar/baglib/storage_dev_bmp.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
class CBagLogResidue : public CBagTextObject {
|
||||
protected:
|
||||
int _sdevWidth;
|
||||
|
||||
public:
|
||||
CBagLogResidue(int sdevWidth);
|
||||
virtual ~CBagLogResidue() {
|
||||
}
|
||||
|
||||
void setSize(const CBofSize &size) override;
|
||||
|
||||
ErrorCode update(CBofBitmap *bmp, CBofPoint pt, CBofRect *srcRect = nullptr, int maskColor = -1) override;
|
||||
};
|
||||
|
||||
#define MSG_TIME_MASK 0x3FFF
|
||||
#define MSG_PLAYED_MASK 0x4000
|
||||
|
||||
class CBagLogMsg : public CBagTextObject {
|
||||
protected:
|
||||
CBofString _msgSendee;
|
||||
CBofString _msgTimeStr;
|
||||
int _sdevWidth;
|
||||
|
||||
public:
|
||||
CBagLogMsg(int sdevWidth);
|
||||
virtual ~CBagLogMsg() {
|
||||
}
|
||||
|
||||
ErrorCode update(CBofBitmap *bmp, CBofPoint pt, CBofRect *srcRect = nullptr, int maskColor = -1) override;
|
||||
|
||||
/**
|
||||
* Takes in info and then removes the relative information and returns the info
|
||||
* without the relevant info.
|
||||
*/
|
||||
ParseCodes setInfo(CBagIfstream &istr) override;
|
||||
|
||||
void setSize(const CBofSize &size) override;
|
||||
|
||||
void setProperty(const CBofString &prop, int val) override;
|
||||
int getProperty(const CBofString &prop) override;
|
||||
|
||||
void setMsgSendee(const CBofString &sendee) {
|
||||
_msgSendee = sendee;
|
||||
}
|
||||
CBofString getMsgSendee() const {
|
||||
return _msgSendee;
|
||||
}
|
||||
|
||||
void setMsgTime(int &msgTime) {
|
||||
const int state = getState();
|
||||
setState((state & MSG_PLAYED_MASK) | (msgTime & MSG_TIME_MASK));
|
||||
}
|
||||
|
||||
int getMsgTime() {
|
||||
return getState() & MSG_TIME_MASK;
|
||||
}
|
||||
|
||||
void setMsgPlayed(bool playedFl) {
|
||||
const int state = getState();
|
||||
setState((state & MSG_TIME_MASK) | (playedFl == true ? MSG_PLAYED_MASK : 0));
|
||||
}
|
||||
bool getMsgPlayed() {
|
||||
return (getState() & MSG_PLAYED_MASK) != 0;
|
||||
}
|
||||
};
|
||||
|
||||
#define mSusChecked 0x0001
|
||||
#define mSusVoicePrinted 0x0002
|
||||
#define mSusResiduePrinted 0x0004
|
||||
|
||||
class CBagLogSuspect : public CBagTextObject {
|
||||
protected:
|
||||
int _nSdevWidth;
|
||||
|
||||
CBofString _susName;
|
||||
CBofString _susSpecies;
|
||||
CBofString _susRoom;
|
||||
|
||||
public:
|
||||
CBagLogSuspect(int sdevWidth);
|
||||
virtual ~CBagLogSuspect() {
|
||||
}
|
||||
|
||||
ErrorCode update(CBofBitmap *bmp, CBofPoint pt, CBofRect *srcRect = nullptr, int maskColor = -1) override;
|
||||
|
||||
void setSize(const CBofSize &size) override;
|
||||
|
||||
ParseCodes setInfo(CBagIfstream &istr) override;
|
||||
|
||||
void setProperty(const CBofString &prop, int val) override;
|
||||
int getProperty(const CBofString &prop) override;
|
||||
|
||||
void setSusName(const CBofString &susName) {
|
||||
_susName = susName;
|
||||
}
|
||||
void setSusSpecies(const CBofString &susSpecies) {
|
||||
_susSpecies = susSpecies;
|
||||
}
|
||||
void setSusRoom(const CBofString &susRoom) {
|
||||
_susRoom = susRoom;
|
||||
}
|
||||
|
||||
void setSusVoicePrinted(bool bVal) {
|
||||
bVal == false ? setState(getState() & ~mSusVoicePrinted) : setState(getState() | mSusVoicePrinted);
|
||||
}
|
||||
bool getSusVoicePrinted() {
|
||||
return (getState() & mSusVoicePrinted) != 0;
|
||||
}
|
||||
|
||||
void setSusResiduePrinted(bool bVal) {
|
||||
bVal == false ? setState(getState() & ~mSusResiduePrinted) : setState(getState() | mSusResiduePrinted);
|
||||
}
|
||||
bool getSusResiduePrinted() {
|
||||
return (getState() & mSusResiduePrinted) != 0;
|
||||
}
|
||||
|
||||
void setSusChecked(bool bVal) {
|
||||
bVal == false ? setState(getState() & ~mSusChecked) : setState(getState() | mSusChecked);
|
||||
}
|
||||
bool getSusChecked() {
|
||||
return (getState() & mSusChecked) != 0;
|
||||
}
|
||||
};
|
||||
|
||||
class CBagLog : public CBagStorageDevBmp {
|
||||
protected:
|
||||
// Queued messages waited to be played and inserted into SDEV
|
||||
CBofList<CBagObject *> *_queuedMsgList;
|
||||
|
||||
static CBagLog *_lastFloatPage;
|
||||
|
||||
public:
|
||||
CBagLog();
|
||||
virtual ~CBagLog();
|
||||
static void initialize() {
|
||||
_lastFloatPage = nullptr;
|
||||
}
|
||||
|
||||
CBagObject *onNewUserObject(const CBofString &initStr) override;
|
||||
|
||||
/**
|
||||
* This is different for the log sdev Object are just queued for insertion
|
||||
* and the message light starts blinking. The messages will be added
|
||||
* to the sdev when the message light is clicked
|
||||
* @return Error result code
|
||||
*/
|
||||
ErrorCode activateLocalObject(CBagObject *bagObj) override;
|
||||
|
||||
/**
|
||||
* Releases and deletes all the objects in the list
|
||||
*/
|
||||
ErrorCode releaseMsg();
|
||||
|
||||
ErrorCode playMsgQueue();
|
||||
|
||||
/**
|
||||
* Remove a (duplicate) message from the message queue
|
||||
*/
|
||||
bool removeFromMsgQueue(CBagObject *bagObj);
|
||||
|
||||
/**
|
||||
* This function arranges the objects that are considered floating
|
||||
* (no coordinates given in script). It is virtual so that derived
|
||||
* storage devices can do special things, like paging etc.
|
||||
* @return Returns the next available location in the sdev,
|
||||
* at this level the objects will go out of range of the sdev.
|
||||
*/
|
||||
CBofPoint arrangeFloater(CBofPoint &pos, CBagObject *bagObj) override;
|
||||
|
||||
int getCurFltPage();
|
||||
void setCurFltPage(int fltPage);
|
||||
|
||||
static void arrangePages();
|
||||
static void initArrangePages() {
|
||||
_lastFloatPage = nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
class CBagEnergyDetectorObject : public CBagTextObject {
|
||||
public:
|
||||
CBagEnergyDetectorObject();
|
||||
virtual ~CBagEnergyDetectorObject();
|
||||
|
||||
// Need private setinfo so we can parse energy detector fields
|
||||
ParseCodes setInfo(CBagIfstream &istr) override;
|
||||
|
||||
ErrorCode update(CBofBitmap *, CBofPoint, CBofRect *, int) override;
|
||||
|
||||
ErrorCode attach() override;
|
||||
|
||||
void setMsgTime(int &nVal) {
|
||||
setState(nVal);
|
||||
}
|
||||
int getMsgTime() {
|
||||
return getState();
|
||||
}
|
||||
|
||||
private:
|
||||
CBofString _energyTimeStr;
|
||||
CBofString _zhapsStr;
|
||||
CBofString _causeStr;
|
||||
|
||||
bool _textInitializedFl;
|
||||
};
|
||||
|
||||
// Special object, clue object.
|
||||
class CBagLogClue : public CBagTextObject {
|
||||
private:
|
||||
CBagVar *_stringVar1;
|
||||
CBagVar *_stringVar2;
|
||||
CBagVar *_stringVar3;
|
||||
CBagVar *_stringVar4;
|
||||
int _sdevWidth;
|
||||
|
||||
public:
|
||||
CBagLogClue(const CBofString &initStr, int sdevWidth, int pointSize);
|
||||
virtual ~CBagLogClue() {
|
||||
}
|
||||
|
||||
ErrorCode attach() override;
|
||||
|
||||
ParseCodes setInfo(CBagIfstream &istr) override;
|
||||
|
||||
ErrorCode update(CBofBitmap *pBmp, CBofPoint pt, CBofRect *srcRect = nullptr, int maskColor = -1) override;
|
||||
};
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
|
||||
#endif
|
||||
1998
engines/bagel/spacebar/baglib/master_win.cpp
Normal file
1998
engines/bagel/spacebar/baglib/master_win.cpp
Normal file
File diff suppressed because it is too large
Load Diff
214
engines/bagel/spacebar/baglib/master_win.h
Normal file
214
engines/bagel/spacebar/baglib/master_win.h
Normal file
@@ -0,0 +1,214 @@
|
||||
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BAGEL_BAGLIB_MASTER_WIN_H
|
||||
#define BAGEL_BAGLIB_MASTER_WIN_H
|
||||
|
||||
#include "bagel/spacebar/boflib/gfx/text.h"
|
||||
#include "bagel/spacebar/baglib/cursor.h"
|
||||
#include "bagel/boflib/string.h"
|
||||
#include "bagel/spacebar/baglib/bagel.h"
|
||||
#include "bagel/spacebar/boflib/gui/window.h"
|
||||
#include "bagel/boflib/sound.h"
|
||||
#include "bagel/spacebar/baglib/object.h"
|
||||
#include "bagel/spacebar/baglib/save_game_file.h"
|
||||
#include "bagel/spacebar/baglib/var.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
#define g_SDevManager CBagel::getBagApp()->getMasterWnd()->getStorageDevManager()
|
||||
#define g_VarManager CBagel::getBagApp()->getMasterWnd()->getVariableManager()
|
||||
|
||||
class CBagStorageDevManager;
|
||||
class CBagStorageDevWnd;
|
||||
class CBagStorageDev;
|
||||
|
||||
enum SpaceBarEventType {
|
||||
WM_ENTER_PAN_WINDOW = 1001,
|
||||
WM_ENTER_CLOSE_UP_WINDOW = 1002,
|
||||
WM_EXIT_CLOSE_UP_WINDOW = 1003,
|
||||
WM_ENTER_NEW_WLD = 1004,
|
||||
WM_DIE = 1005,
|
||||
WM_SHOW_SYSTEM_DLG = 1006
|
||||
};
|
||||
|
||||
#define MAX_CURSORS 60
|
||||
|
||||
// Some utility routines
|
||||
void setCICStatus(CBagStorageDev *sdev);
|
||||
bool getCICStatus();
|
||||
|
||||
/**
|
||||
* This is the main window that is never destroyed throughout the game.
|
||||
* It handles bringing new windows in and out of focus as well as
|
||||
* containing the parsing file and info. It also captures
|
||||
* keyboard entry and will save state information
|
||||
*/
|
||||
class CBagMasterWin : public CBofWindow, public CBagParseObject {
|
||||
protected:
|
||||
static bool _objSaveFl;
|
||||
static StObj *_objList;
|
||||
static CBagCursor *_cursorList[MAX_CURSORS];
|
||||
|
||||
CBagStorageDevWnd *_gameWindow;
|
||||
|
||||
CBofString _wldScript;
|
||||
CBofString _startWld;
|
||||
CBofString _cdChangeAudio;
|
||||
CBofString _sysScreen;
|
||||
|
||||
uint16 _diskId;
|
||||
int _fadeIn;
|
||||
CBofList<CBagStorageDev *> *_gameSDevList;
|
||||
CBagStorageDevManager *_storageDeviceList;
|
||||
CBagVarManager *_variableList; // List of variables used throughout wld
|
||||
CBofSound *_waitSound;
|
||||
static int _curCursor;
|
||||
|
||||
public:
|
||||
static int _menuCount;
|
||||
|
||||
CBagMasterWin();
|
||||
virtual ~CBagMasterWin();
|
||||
virtual ErrorCode Run();
|
||||
|
||||
ErrorCode close() override;
|
||||
|
||||
CBofString &getWldScript() {
|
||||
return _wldScript;
|
||||
}
|
||||
|
||||
static void setActiveCursor(int cursorId);
|
||||
static int getActiveCursor() {
|
||||
return _curCursor;
|
||||
}
|
||||
|
||||
// User options
|
||||
static bool getFlyThru();
|
||||
|
||||
static bool getPanimations();
|
||||
static void setPanimations(bool panimsFl);
|
||||
|
||||
static int getCorrection();
|
||||
static void setCorrection(int correction);
|
||||
|
||||
static int getPanSpeed();
|
||||
static void setPanSpeed(int speed);
|
||||
|
||||
static int getMidiVolume();
|
||||
static void setMidiVolume(int vol);
|
||||
|
||||
static int getWaveVolume();
|
||||
static void setWaveVolume(int vol);
|
||||
|
||||
static bool getMidi() {
|
||||
return getMidiVolume() != 0;
|
||||
}
|
||||
static bool getDigitalAudio() {
|
||||
return getWaveVolume() != 0;
|
||||
}
|
||||
|
||||
static void muteToggle();
|
||||
static void forcePaintScreen();
|
||||
|
||||
virtual ErrorCode showSystemDialog(bool saveFl = true);
|
||||
bool showRestartDialog(CBofWindow *win = nullptr, bool saveFl = true);
|
||||
bool showSaveDialog(CBofWindow *win, bool saveFl = true);
|
||||
bool showRestoreDialog(CBofWindow *win, bool saveFl = true);
|
||||
bool showQuitDialog(CBofWindow *win, bool saveFl = true);
|
||||
ErrorCode showCreditsDialog(CBofWindow *win, bool saveFl = true);
|
||||
|
||||
void fillSaveBuffer(StBagelSave *saveBuf);
|
||||
void doRestore(StBagelSave *saveBuf);
|
||||
|
||||
ErrorCode newGame();
|
||||
|
||||
ErrorCode loadFile(const CBofString &wldName, const CBofString &startWldName, bool restartFl = false, bool setStartFl = true);
|
||||
|
||||
ErrorCode loadFileFromStream(CBagIfstream &input, const CBofString &wldName);
|
||||
ErrorCode loadGlobalVars(const CBofString &wldName);
|
||||
|
||||
ErrorCode setCurrfadeIn(int fade) {
|
||||
_fadeIn = fade;
|
||||
return ERR_NONE;
|
||||
}
|
||||
ErrorCode setStorageDev(const CBofString &wldName, bool entry = true);
|
||||
ErrorCode gotoNewWindow(const CBofString *str);
|
||||
|
||||
uint16 getDiskID() const {
|
||||
return _diskId;
|
||||
}
|
||||
void setDiskID(uint16 id) {
|
||||
_diskId = id;
|
||||
}
|
||||
|
||||
CBofWindow *getCurrentGameWindow() const {
|
||||
return (CBofWindow *)_gameWindow;
|
||||
}
|
||||
CBagStorageDevWnd *getCurrentStorageDev() const {
|
||||
return _gameWindow;
|
||||
}
|
||||
CBagStorageDevManager *getStorageDevManager() const {
|
||||
return _storageDeviceList;
|
||||
}
|
||||
CBagVarManager *getVariableManager() const {
|
||||
return _variableList;
|
||||
}
|
||||
|
||||
virtual CBagStorageDev *onNewStorageDev(const CBofString &typestr) = 0;
|
||||
virtual CBagStorageDev *onNewStorageDev(int type) = 0;
|
||||
|
||||
virtual void onNewFilter(CBagStorageDev *, const CBofString &typeStr) = 0;
|
||||
virtual void onNewFilter(CBagStorageDev *sdev, int type) = 0;
|
||||
|
||||
virtual ErrorCode onHelp(const CBofString &helpFile, bool saveBkgFl = true, CBofWindow *parent = nullptr);
|
||||
|
||||
void onUserMessage(uint32 message, uint32 param) override;
|
||||
|
||||
void onKeyHit(uint32 keyCode, uint32 repCount) override;
|
||||
void onClose() override;
|
||||
|
||||
StObj *getObjList() {
|
||||
return _objList;
|
||||
}
|
||||
void setSaveObjs(bool saveFl) {
|
||||
_objSaveFl = saveFl;
|
||||
}
|
||||
bool isObjSave() {
|
||||
return _objSaveFl;
|
||||
}
|
||||
|
||||
void saveSDevStack();
|
||||
|
||||
// Since we do this from load file and do restore, centralize it in one location.
|
||||
void restoreActiveMessages(CBagStorageDevManager *sdevManager);
|
||||
};
|
||||
|
||||
ErrorCode waitForInput();
|
||||
|
||||
extern bool g_waitOKFl;
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
|
||||
#endif
|
||||
692
engines/bagel/spacebar/baglib/menu_dlg.cpp
Normal file
692
engines/bagel/spacebar/baglib/menu_dlg.cpp
Normal file
@@ -0,0 +1,692 @@
|
||||
/* 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/menu_dlg.h"
|
||||
#include "bagel/spacebar/baglib/pan_window.h"
|
||||
#include "bagel/spacebar/baglib/text_object.h"
|
||||
#include "bagel/spacebar/baglib/bagel.h"
|
||||
#include "bagel/spacebar/baglib/master_win.h"
|
||||
#include "bagel/spacebar/baglib/zoom_pda.h"
|
||||
#include "bagel/boflib/file_functions.h"
|
||||
#include "bagel/boflib/log.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
#define MENU_DFLT_HEIGHT 20
|
||||
|
||||
#define TIMER_CLOSE_ID 108
|
||||
#define TIMER_HACK_ID 109
|
||||
#define DELAY_DEFAULT 0
|
||||
|
||||
CBagObject *CBagMenuDlg::_pSelectedObject;
|
||||
CBofList<CBagObject *> *CBagMenu::_pUniversalObjectList; // Objects used in every menu
|
||||
int CBagMenu::_nDefaultDelay;
|
||||
|
||||
bool g_pauseTimerFl = false;
|
||||
extern bool g_bAAOk;
|
||||
|
||||
#define EXAMINEBMP "$SBARDIR\\GENERAL\\MENUS\\EXAMINE.BMP"
|
||||
|
||||
void CBagMenuDlg::initialize() {
|
||||
_pSelectedObject = nullptr;
|
||||
}
|
||||
|
||||
void CBagMenu::initialize() {
|
||||
_pUniversalObjectList = nullptr;
|
||||
_nDefaultDelay = DELAY_DEFAULT;
|
||||
}
|
||||
|
||||
CBagMenu::CBagMenu() {
|
||||
_nY = 0;
|
||||
|
||||
static bool bFirstTime = true;
|
||||
|
||||
// Get option for delay for caption boxes
|
||||
if (bFirstTime) {
|
||||
bFirstTime = false;
|
||||
|
||||
_nDefaultDelay = DELAY_DEFAULT;
|
||||
|
||||
CBagel *pBagel = (CBagel *)CBagel::getApp();
|
||||
if (pBagel != nullptr) {
|
||||
pBagel->getOption("UserOptions", "TextDelay", &_nDefaultDelay, DELAY_DEFAULT);
|
||||
|
||||
if (_nDefaultDelay < 0) {
|
||||
_nDefaultDelay = -1;
|
||||
} else if (_nDefaultDelay > 0x7FFF) {
|
||||
_nDefaultDelay = 0x7FFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_nDelay = (int16)_nDefaultDelay;
|
||||
}
|
||||
|
||||
CBagObject *CBagMenu::onNewSpriteObject(const CBofString &) {
|
||||
CBagSpriteObject *pObj = new CBagSpriteObject();
|
||||
|
||||
const CBofPoint pt(0, _nY);
|
||||
pObj->setPosition(pt);
|
||||
pObj->setTransparent(false);
|
||||
|
||||
return pObj;
|
||||
}
|
||||
|
||||
bool CBagMenu::trackPopupMenu(uint32 /*nFlags*/, int x, int y, CBofWindow *pWnd, CBofPalette * /*pPal*/, CBofRect * /*lpRect*/) {
|
||||
static int nNumCalls = 0;
|
||||
CBagMenuDlg dlg;
|
||||
CBagObject *pObj;
|
||||
int nObjectPal = -1;
|
||||
int nMenuCount = 0, nRunItems = 0, nBaseMenuLocX = 3;
|
||||
CBofList<CBagObject *> xObjList;
|
||||
int nNumItems = 0;
|
||||
CBofRect wndRect(80, 10, 80 + 480 - 1, 10 + 360 - 1);
|
||||
CBofRect objSize;
|
||||
CBofSize cWieldMenuSize;
|
||||
CBofSize menuSize(1, 1);
|
||||
CBofPoint menuLoc(4, 1);
|
||||
bool bTextOnly = true;
|
||||
int tmpVal = 0;
|
||||
CBofPoint cMouseDown(x, y);
|
||||
bool bZoomed = false;
|
||||
|
||||
nNumCalls++;
|
||||
|
||||
bool bReturn = true;
|
||||
CBofWindow *pParent = pWnd;
|
||||
int nNumWieldChoices = 0;
|
||||
|
||||
if ((getObjectList()->getCount() == 1) && (getObjectList()->getTail()->getNodeItem()->getType() == TEXT_OBJ) && (((CBagTextObject *)getObjectList()->getTail()->getNodeItem())->isCaption())) {
|
||||
nBaseMenuLocX = 0;
|
||||
|
||||
} else if (nNumCalls == 1 && _pUniversalObjectList && _pUniversalObjectList != getObjectList()) {
|
||||
for (int i = 0; i < _pUniversalObjectList->getCount(); ++i) {
|
||||
|
||||
pObj = _pUniversalObjectList->getNodeItem(i);
|
||||
|
||||
if (pObj->isLocal() && (!pObj->getExpression() || pObj->getExpression()->evaluate(pObj->isNegative()))) {
|
||||
// Only attach if not attached
|
||||
if (pObj->isAttached() == false) {
|
||||
pObj->attach();
|
||||
|
||||
// Otherwise, we need to re-calculate the size of the text object,
|
||||
// since we are gonna trash is with our own values soon.
|
||||
|
||||
} else if (pObj->getType() == TEXT_OBJ) {
|
||||
((CBagTextObject *)pObj)->recalcTextRect(((CBagTextObject *)pObj)->isCaption());
|
||||
}
|
||||
|
||||
if (!pObj->isImmediateRun()) {
|
||||
// Get the next menu items pos
|
||||
objSize = pObj->getRect();
|
||||
|
||||
if (menuSize.cx < (objSize.width() + menuLoc.x))
|
||||
menuSize.cx = (objSize.width() + menuLoc.x);
|
||||
if (menuSize.cy < (objSize.height() + menuLoc.y))
|
||||
menuSize.cy = (objSize.height() + menuLoc.y);
|
||||
|
||||
pObj->setPosition(menuLoc);
|
||||
pObj->setHighlight(false);
|
||||
|
||||
if (!nMenuCount && (pObj->getType() == TEXT_OBJ)) {
|
||||
menuLoc.y += objSize.height();
|
||||
} else {
|
||||
menuLoc.x += objSize.width();
|
||||
}
|
||||
|
||||
xObjList.addToTail(pObj);
|
||||
|
||||
nMenuCount++;
|
||||
} else {
|
||||
nRunItems++;
|
||||
pObj->runObject();
|
||||
|
||||
// This detach may cause problems in the future, if it does delete it
|
||||
// Some object may not work if detached for example midi sound
|
||||
pObj->detach();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Start non-wield menu on next row
|
||||
menuLoc.y += objSize.height();
|
||||
|
||||
nNumWieldChoices = xObjList.getCount();
|
||||
|
||||
if (nNumWieldChoices != 0) {
|
||||
cWieldMenuSize = menuSize;
|
||||
}
|
||||
}
|
||||
|
||||
bool bNoMenu = false;
|
||||
|
||||
for (int i = 0; i < getObjectList()->getCount(); ++i) {
|
||||
|
||||
pObj = getObjectList()->getNodeItem(i);
|
||||
|
||||
if (pObj->isLocal() && (!pObj->getExpression() || pObj->getExpression()->evaluate(pObj->isNegative()))) {
|
||||
// Only attach if not attached
|
||||
if (pObj->isAttached() == false) {
|
||||
pObj->attach();
|
||||
|
||||
// Otherwise, we need to re-calculate the size of the text object,
|
||||
// since we are gonna trash is with our own values soon.
|
||||
|
||||
} else if (pObj->getType() == TEXT_OBJ) {
|
||||
((CBagTextObject *)pObj)->recalcTextRect(((CBagTextObject *)pObj)->isCaption());
|
||||
}
|
||||
|
||||
if (!pObj->isImmediateRun()) {
|
||||
// Get the next menu items pos
|
||||
objSize = pObj->getRect();
|
||||
|
||||
// If it is a text object increment next position by its height
|
||||
if (pObj->getType() == TEXT_OBJ) {
|
||||
|
||||
if (tmpVal)
|
||||
// If we have a value move text to next line
|
||||
menuLoc.y += tmpVal;
|
||||
tmpVal = 0; // Text objects set the next line to be at the very beginning
|
||||
|
||||
// If we're zoomed, then do things differently
|
||||
CBagTextObject *pTXObj = (CBagTextObject *)pObj;
|
||||
if (pTXObj->isCaption()) {
|
||||
SBZoomPda *pZPDA = (SBZoomPda *)g_SDevManager->getStorageDevice("BPDAZ_WLD");
|
||||
if (pZPDA && pZPDA->getZoomed()) {
|
||||
bZoomed = true;
|
||||
|
||||
wndRect = pZPDA->getViewRect();
|
||||
}
|
||||
}
|
||||
|
||||
if (bTextOnly) {
|
||||
if (wndRect.height() <= (objSize.height() + menuLoc.y)) {
|
||||
menuLoc.y = 1;
|
||||
nBaseMenuLocX += (menuSize.cx + 2);
|
||||
menuLoc.x = nBaseMenuLocX + 1;
|
||||
}
|
||||
} else if (wndRect.height() <= ((objSize.height() + menuLoc.y) + 41)) {
|
||||
menuLoc.y = 1;
|
||||
nBaseMenuLocX += (menuSize.cx + 2);
|
||||
menuLoc.x = nBaseMenuLocX;
|
||||
}
|
||||
|
||||
// CHECKME: the previous assignment seems to indicate that the following line should be removed in order to keep this slightly different value
|
||||
menuLoc.x = (1 + nBaseMenuLocX);
|
||||
if (menuSize.cx < (objSize.width() + menuLoc.x))
|
||||
menuSize.cx = (objSize.width() + menuLoc.x);
|
||||
if (menuSize.cy < (objSize.height() + menuLoc.y))
|
||||
menuSize.cy = (objSize.height() + menuLoc.y);
|
||||
pObj->setPosition(menuLoc);
|
||||
pObj->setHighlight(false);
|
||||
|
||||
menuLoc.x = (1 + nBaseMenuLocX);
|
||||
menuLoc.y += (objSize.height() + 1);
|
||||
} else {
|
||||
// Increment next position by its width
|
||||
if (wndRect.height() <= (objSize.height() + menuLoc.y)) {
|
||||
menuLoc.y = 1;
|
||||
nBaseMenuLocX += (menuSize.cx + 2);
|
||||
menuLoc.x = nBaseMenuLocX;
|
||||
}
|
||||
|
||||
bTextOnly = false;
|
||||
|
||||
// Continue to grow menu size to max required
|
||||
if (menuSize.cx < (objSize.width() + menuLoc.x))
|
||||
menuSize.cx = (objSize.width() + menuLoc.x);
|
||||
if (menuSize.cy < (objSize.height() + menuLoc.y))
|
||||
menuSize.cy = (objSize.height() + menuLoc.y);
|
||||
|
||||
pObj->setPosition(menuLoc);
|
||||
pObj->setHighlight(false);
|
||||
|
||||
if ((nObjectPal < 0) && ((pObj->getType() == BMP_OBJ) || (pObj->getType() == SPRITE_OBJ)))
|
||||
nObjectPal = i;
|
||||
menuLoc.x += objSize.width();
|
||||
tmpVal = objSize.height();//save the obj height for use later if we get a text obj
|
||||
}
|
||||
|
||||
if (pObj->isNoMenu()) {
|
||||
bNoMenu = true;
|
||||
}
|
||||
|
||||
xObjList.addToTail(pObj);
|
||||
nNumItems++;
|
||||
|
||||
nMenuCount++;
|
||||
|
||||
} else {
|
||||
nRunItems++;
|
||||
pObj->runObject();
|
||||
if (pObj->getType() == LINK_OBJ) {
|
||||
g_bAAOk = false;
|
||||
}
|
||||
}
|
||||
} // If in local area and activated by expression
|
||||
}
|
||||
|
||||
// If we ran something and there are no other menu items just return
|
||||
if (!(nRunItems && !nMenuCount)) {
|
||||
if (nMenuCount) {
|
||||
menuLoc.y += objSize.height();
|
||||
menuLoc.x = 1;
|
||||
nMenuCount = 0;
|
||||
}
|
||||
|
||||
menuSize.cx++;
|
||||
menuSize.cy++;
|
||||
|
||||
CBofRect tmpRect(CBofPoint(x, y - menuSize.cy / 2), menuSize);
|
||||
menuSize.cy += 2;
|
||||
|
||||
// If the menu contains only one object and it is a caption style text object
|
||||
// position the dialog box at the bottom of the Game window screen
|
||||
bool bMoved = false;
|
||||
bool bCaption = false;
|
||||
int nNumChars = 0;
|
||||
if ((nNumItems == 1) && (xObjList.getTail()->getNodeItem()->getType() == TEXT_OBJ) && (((CBagTextObject *)xObjList.getTail()->getNodeItem())->isCaption())) {
|
||||
while (nNumWieldChoices-- != 0) {
|
||||
pObj = xObjList.removeHead();
|
||||
pObj->detach();
|
||||
}
|
||||
|
||||
// If we are not using the wield menu with this menu, then
|
||||
// the menu is smaller
|
||||
menuSize.cy -= cWieldMenuSize.cy;
|
||||
if (cWieldMenuSize.cy != 0)
|
||||
cWieldMenuSize.cy--;
|
||||
|
||||
bMoved = true;
|
||||
|
||||
tmpRect = wndRect;
|
||||
|
||||
tmpRect.top = tmpRect.bottom - menuSize.cy;
|
||||
bCaption = true;
|
||||
|
||||
nNumChars = ((CBagTextObject *)xObjList.getHead()->getNodeItem())->getText().getLength();
|
||||
|
||||
// Bring caption back 3 pixels
|
||||
CBofPoint cPoint;
|
||||
cPoint = xObjList.getHead()->getNodeItem()->getPosition();
|
||||
cPoint.x = 1;
|
||||
|
||||
xObjList.getHead()->getNodeItem()->setPosition(cPoint);
|
||||
|
||||
} else {
|
||||
if (bTextOnly) {
|
||||
while (nNumWieldChoices-- != 0) {
|
||||
pObj = xObjList.removeHead();
|
||||
pObj->detach();
|
||||
}
|
||||
|
||||
// If we are not using the wield menu with this menu, then
|
||||
// the menu is smaller
|
||||
menuSize.cy -= cWieldMenuSize.cy;
|
||||
bMoved = true;
|
||||
}
|
||||
|
||||
// Use the mouse pos (x,y), and add the menuSize calculated above
|
||||
tmpRect.left = x;
|
||||
tmpRect.top = y;
|
||||
tmpRect.bottom = y + menuSize.cy;
|
||||
tmpRect.right = x + menuSize.cx + 1;
|
||||
|
||||
// If the menu would go off the screen, adjust it
|
||||
while (tmpRect.top < wndRect.top) {
|
||||
tmpRect.offsetRect(0, (wndRect.top - tmpRect.top));
|
||||
}
|
||||
while (tmpRect.bottom > wndRect.bottom) {
|
||||
tmpRect.offsetRect(0, (wndRect.bottom - tmpRect.bottom));
|
||||
}
|
||||
while (tmpRect.left < wndRect.left) {
|
||||
tmpRect.right += (wndRect.left - tmpRect.left);
|
||||
tmpRect.left += (wndRect.left - tmpRect.left);
|
||||
}
|
||||
while (tmpRect.right > wndRect.right) {
|
||||
tmpRect.left -= (tmpRect.right - wndRect.right);
|
||||
tmpRect.right -= (tmpRect.right - wndRect.right);
|
||||
}
|
||||
}
|
||||
|
||||
bReturn = false;
|
||||
if (xObjList.getCount() && !bNoMenu) {
|
||||
bReturn = true;
|
||||
|
||||
dlg.setObjectList(&xObjList);
|
||||
|
||||
for (int i = 0; i < xObjList.getCount(); i++) {
|
||||
pObj = xObjList[i];
|
||||
|
||||
if (pObj->getType() == TEXT_OBJ) {
|
||||
int cx = tmpRect.size().cx - 1;
|
||||
int cy = tmpRect.size().cy - 1;
|
||||
if (!bCaption) {
|
||||
cy = ((CBagTextObject *)pObj)->getSize().cy + 2;
|
||||
}
|
||||
|
||||
pObj->setSize(CBofSize(cx, cy));
|
||||
|
||||
// Need to move the menus up when have a wielded item, but
|
||||
// not displaying the wield menu
|
||||
if (bMoved) {
|
||||
CBofPoint cPos;
|
||||
cPos = pObj->getPosition();
|
||||
cPos.y -= cWieldMenuSize.cy;
|
||||
pObj->setPosition(cPos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CBagPanWindow::flushInputEvents();
|
||||
|
||||
// If we were requested to put a dialog over the PDA, then shift it upward
|
||||
// a bit... unless of course the mousedown occurred in the PDA itself.
|
||||
CBagPDA *pPDA = (CBagPDA *)g_SDevManager->getStorageDevice("BPDA_WLD");
|
||||
|
||||
if (pPDA != nullptr && (pPDA->isActivated() && bZoomed == false)) {
|
||||
if (!pPDA->isInside(cMouseDown)) {
|
||||
CBofRect cPDARect = pPDA->getRect();
|
||||
|
||||
tmpRect.offsetRect(0, (tmpRect.bottom > cPDARect.top ? cPDARect.top - tmpRect.bottom : 0));
|
||||
|
||||
// Make sure we didn't go too far
|
||||
if (tmpRect.top < 0) {
|
||||
tmpRect.offsetRect(0, -tmpRect.top);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Force all menus to be created using a specific palette
|
||||
// that we know contains the correct colors for our menu.
|
||||
|
||||
char szBuf[256];
|
||||
Common::strcpy_s(szBuf, EXAMINEBMP);
|
||||
CBofString cString(szBuf, 256);
|
||||
fixPathName(cString);
|
||||
CBofPalette xPal;
|
||||
|
||||
xPal.loadPalette(cString);
|
||||
dlg.createDlg(pParent, &xPal, &tmpRect);
|
||||
|
||||
if (bCaption) {
|
||||
// We need to move this back to the correct position
|
||||
// because the Boflibs center dialog ALWAYS !!!!!!!!
|
||||
|
||||
// If the PDA is currently active, then we have to put the caption elsewhere,
|
||||
// or deactivate the PDA (if PDA zoomed, just place at bottom.
|
||||
if (CBagPanWindow::_pPDABmp != nullptr && CBagPanWindow::_pPDABmp->isActivated() && bZoomed == false) {
|
||||
dlg.move(wndRect.left, wndRect.top, true);
|
||||
} else {
|
||||
dlg.move(tmpRect.left, tmpRect.top, true);
|
||||
}
|
||||
|
||||
// Need to re-save the background because there is a bug with moving
|
||||
// the dialog box.
|
||||
dlg.saveBackground();
|
||||
|
||||
// Set this caption to automatically go away after specified delay
|
||||
if (_nDelay > 0) {
|
||||
dlg.setTimer(TIMER_CLOSE_ID, _nDelay + (80 * nNumChars));
|
||||
}
|
||||
} else {
|
||||
dlg.move(tmpRect.topLeft().x, tmpRect.topLeft().y, true);
|
||||
|
||||
// Need to re-save the background because there is a bug with moving
|
||||
// the dialog box.
|
||||
dlg.saveBackground();
|
||||
}
|
||||
|
||||
CBagPanWindow::flushInputEvents();
|
||||
|
||||
g_pauseTimerFl = true;
|
||||
dlg.doModal();
|
||||
g_pauseTimerFl = false;
|
||||
|
||||
pObj = dlg._pSelectedObject;
|
||||
dlg.destroy();
|
||||
|
||||
for (int i = 0; i < getObjectCount(); ++i) {
|
||||
getObjectByPos(i)->detach();
|
||||
}
|
||||
|
||||
// If our current storage device is "AS CUSTOM" then don't allow
|
||||
// the timer to get incremented.
|
||||
CBagStorageDev *pCurSDEV = CBagel::getBagApp()->getMasterWnd()->getCurrentStorageDev();
|
||||
if (pObj != nullptr) {
|
||||
pObj->runCallBack();
|
||||
|
||||
// Selecting this menu item causes a turn to go by
|
||||
if (nNumCalls == 1 && pCurSDEV->isCustom() == false) {
|
||||
g_VarManager->incrementTimers();
|
||||
}
|
||||
} else if (bCaption && (nNumCalls == 2)) {
|
||||
// Selecting this menu item causes a turn to go by
|
||||
dlg._pSelectedObject = nullptr;
|
||||
if (pCurSDEV->isCustom() == false) {
|
||||
g_VarManager->incrementTimers();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nNumCalls--;
|
||||
|
||||
return bReturn;
|
||||
}
|
||||
|
||||
bool CBagMenu::addItem(CBagObject *pObj, void *(* /*func*/)(int, void *), void */*info*/) {
|
||||
pObj->setPosition(CBofPoint(0, _nY));
|
||||
|
||||
_nY = (int16)(_nY + (int16)(pObj->getRect().height() + 1));
|
||||
addObject(pObj);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CBagMenu::deleteItem(const CBofString & /*sLabel*/) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CBagMenu::isChecked(const CBofString & /*sLabel*/, const CBofString & /*sSubLabel*/) {
|
||||
const int nRow = 0;
|
||||
const int nCol = 0;
|
||||
|
||||
return isCheckedPos(nRow, nCol);
|
||||
}
|
||||
|
||||
bool CBagMenu::isCheckedPos(int /*nRow*/, int /*nCol*/) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CBagMenu::isChecked(int /*nRefId*/) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CBagMenu::check(const CBofString & /*sLabel*/, const CBofString & /*sSubLabel*/) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CBagMenu::unCheck(const CBofString & /*sLabel*/, const CBofString & /*sSubLabel*/) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CBagMenu::check(int /*nRefId*/) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CBagMenu::unCheck(int /*nRefId*/) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CBagMenu::setUniversalObjectList(CBofList<CBagObject *> *pObjList) {
|
||||
if (_pUniversalObjectList != nullptr) {
|
||||
removeUniversalObjectList();
|
||||
}
|
||||
|
||||
_pUniversalObjectList = pObjList;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CBagMenu::removeUniversalObjectList() {
|
||||
if (_pUniversalObjectList == nullptr) {
|
||||
return true;
|
||||
}
|
||||
|
||||
_pUniversalObjectList = nullptr;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
CBagMenuDlg::CBagMenuDlg() {
|
||||
// Remove this SDEV from the storage device list so that it is not deleted
|
||||
// when we switch .WLD files, and there may still be a Dialog open.
|
||||
g_SDevManager->unregisterStorageDev(this);
|
||||
|
||||
_bAcceptInput = false;
|
||||
_bMultipleDialogs = false;
|
||||
}
|
||||
|
||||
CBagMenuDlg::~CBagMenuDlg() {
|
||||
assert(isValidObject(this));
|
||||
}
|
||||
|
||||
ErrorCode CBagMenuDlg::createDlg(CBofWindow *pWnd, CBofPalette *pPal, CBofRect *pRect) {
|
||||
CBofRect r;
|
||||
|
||||
_bMultipleDialogs = false;
|
||||
_bAcceptInput = true;
|
||||
_nReturnValue = 0;
|
||||
|
||||
if (!pRect) {
|
||||
r = pWnd->getWindowRect();
|
||||
r.offsetRect(-r.left, -r.top);
|
||||
r.bottom = r.top + MENU_DFLT_HEIGHT;
|
||||
} else {
|
||||
r = *pRect;
|
||||
}
|
||||
|
||||
CBagStorageDevDlg::create("Menu", &r, pWnd, 0);
|
||||
|
||||
CBofBitmap *pBmp = new CBofBitmap(r.width(), r.height(), pPal);
|
||||
|
||||
r.offsetRect(-r.left, -r.top);
|
||||
assert(pPal != nullptr);
|
||||
pBmp->fillRect(&r, pPal->getNearestIndex(RGB(82, 82, 82)));
|
||||
pBmp->drawRect(&r, pPal->getNearestIndex(RGB(0, 0, 0)));
|
||||
setBackdrop(pBmp);
|
||||
|
||||
return _errCode;
|
||||
}
|
||||
|
||||
|
||||
void CBagMenuDlg::onLButtonUp(uint32 nFlags, CBofPoint *pPoint, void *) {
|
||||
// We are ignoring all input until the dialog is actually visible
|
||||
if (_bAcceptInput) {
|
||||
_pSelectedObject = nullptr;
|
||||
|
||||
onClose();
|
||||
|
||||
if (_bMultipleDialogs) {
|
||||
CBofRect r = getWindowRect();
|
||||
r.offsetRect(-r.left, -r.top);
|
||||
if (r.ptInRect(*pPoint)) {
|
||||
CBagStorageDevDlg::onLButtonUp(nFlags, pPoint);
|
||||
_pSelectedObject = getLActiveObject();
|
||||
}
|
||||
|
||||
} else {
|
||||
const CBofPoint pt = devPtToViewPort(*pPoint);
|
||||
_pSelectedObject = getObject(pt);
|
||||
if (_pSelectedObject != nullptr) {
|
||||
_pSelectedObject->onLButtonUp(nFlags, pPoint);
|
||||
}
|
||||
}
|
||||
|
||||
_nReturnValue = (_pSelectedObject != nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
void CBagMenuDlg::onMouseMove(uint32 /*nFlags*/, CBofPoint *pPoint, void *) {
|
||||
CBagMasterWin::setActiveCursor(0);
|
||||
CBagObject *pObj = getObject(*pPoint);
|
||||
if (pObj != nullptr) {
|
||||
|
||||
// Switch to that cursor
|
||||
CBagMasterWin::setActiveCursor(pObj->getOverCursor());
|
||||
|
||||
if (pObj != getLActiveObject()) {
|
||||
if (pObj->getCallBack() || pObj->getMenuPtr()) {
|
||||
|
||||
pObj->setHighlight();
|
||||
if (getLActiveObject())
|
||||
getLActiveObject()->setHighlight(false);
|
||||
setLActiveObject(pObj);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CBagMenuDlg::onTimer(uint32 nID) {
|
||||
assert(isValidObject(this));
|
||||
|
||||
switch (nID) {
|
||||
// Auto close for text-Captions
|
||||
case TIMER_CLOSE_ID:
|
||||
killTimer(nID);
|
||||
close();
|
||||
break;
|
||||
|
||||
// Can now allow user input
|
||||
case TIMER_HACK_ID:
|
||||
killTimer(nID);
|
||||
_bAcceptInput = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
logWarning("Invalid Timer ID");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CBagMenuDlg::onPaint(CBofRect *pRect) {
|
||||
assert(isValidObject(this));
|
||||
|
||||
CBagStorageDevDlg::onPaint(pRect);
|
||||
|
||||
// Don't allow user input until this menu is visible
|
||||
CBagPanWindow::flushInputEvents();
|
||||
}
|
||||
|
||||
void CBagMenuDlg::onDeActivate() {
|
||||
assert(isValidObject(this));
|
||||
|
||||
close();
|
||||
}
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
105
engines/bagel/spacebar/baglib/menu_dlg.h
Normal file
105
engines/bagel/spacebar/baglib/menu_dlg.h
Normal file
@@ -0,0 +1,105 @@
|
||||
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BAGEL_BAGLIB_MENU_DLG_H
|
||||
#define BAGEL_BAGLIB_MENU_DLG_H
|
||||
|
||||
#include "bagel/spacebar/baglib/storage_dev_win.h"
|
||||
#include "bagel/spacebar/baglib/sprite_object.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
class CBagMenu : public CBagStorageDev {
|
||||
private:
|
||||
static CBofList<CBagObject *> *_pUniversalObjectList; // Objects used in every menu
|
||||
static int _nDefaultDelay;
|
||||
|
||||
int16 _nDelay;
|
||||
int16 _nY; // Replaces _nNextPos
|
||||
|
||||
public:
|
||||
CBagMenu();
|
||||
static void initialize();
|
||||
|
||||
ErrorCode setBackground(CBofBitmap * /*pBmp*/) {
|
||||
assert(false);
|
||||
return ERR_NONE;
|
||||
}
|
||||
CBofBitmap *getBackground() {
|
||||
assert(false);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool addItem(CBagObject *pObj, void *(*func)(int, void *), void *info);
|
||||
bool deleteItem(const CBofString &sLabel);
|
||||
|
||||
bool isChecked(const CBofString &sLabel, const CBofString &sSubLabel = CBofString());
|
||||
bool isChecked(int nRefId);
|
||||
bool isCheckedPos(int nRow, int nCol = -1);
|
||||
bool check(const CBofString &sLabel, const CBofString &sSubLabel = CBofString());
|
||||
bool check(int nRefId);
|
||||
bool unCheck(const CBofString &sLabel, const CBofString &sSubLabel = CBofString());
|
||||
bool unCheck(int nRefId);
|
||||
|
||||
bool trackPopupMenu(uint32 nFlags, int x, int y, CBofWindow *pWnd, CBofPalette *pPal, CBofRect *lpRect = nullptr);
|
||||
|
||||
static bool removeUniversalObjectList();
|
||||
static bool setUniversalObjectList(CBofList<CBagObject *> *pObjList);
|
||||
static CBofList<CBagObject *> *getUniversalObjectList() {
|
||||
return _pUniversalObjectList;
|
||||
}
|
||||
|
||||
CBagObject *onNewSpriteObject(const CBofString &);
|
||||
};
|
||||
|
||||
class CBagMenuDlg : public CBagStorageDevDlg {
|
||||
friend class CBagMenu;
|
||||
|
||||
private:
|
||||
bool _bMultipleDialogs;
|
||||
bool _bAcceptInput;
|
||||
|
||||
public:
|
||||
static CBagObject *_pSelectedObject;
|
||||
static void initialize();
|
||||
|
||||
CBagMenuDlg();
|
||||
virtual ~CBagMenuDlg();
|
||||
|
||||
ErrorCode createDlg(CBofWindow *pWnd, CBofPalette *pPal, CBofRect *cRect);
|
||||
|
||||
virtual void onMouseMove(uint32 nFlags, CBofPoint *pPoint, void * = nullptr);
|
||||
virtual void onLButtonUp(uint32 nFlags, CBofPoint *pPoint, void * = nullptr);
|
||||
|
||||
virtual void onDeActivate();
|
||||
|
||||
virtual void onTimer(uint32 nID);
|
||||
virtual void onPaint(CBofRect *pRect);
|
||||
};
|
||||
|
||||
extern bool g_pauseTimerFl;
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
|
||||
#endif
|
||||
122
engines/bagel/spacebar/baglib/moo.cpp
Normal file
122
engines/bagel/spacebar/baglib/moo.cpp
Normal file
@@ -0,0 +1,122 @@
|
||||
/* 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/moo.h"
|
||||
#include "bagel/spacebar/baglib/master_win.h"
|
||||
#include "bagel/spacebar/baglib/pan_window.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
CBagCharacterObject *CBagMoo::_pMovie;
|
||||
PdaMode CBagMoo::_eSavePDAMode;
|
||||
PdaPos CBagMoo::_eSavePDAPos;
|
||||
|
||||
void CBagMoo::initialize() {
|
||||
_pMovie = nullptr;
|
||||
_eSavePDAMode = PDA_NO_MODE;
|
||||
_eSavePDAPos = PDA_POS_UNINITIALIZED;
|
||||
}
|
||||
|
||||
ErrorCode CBagMoo::update(CBofBitmap *pBmp, CBofPoint /*pt*/, CBofRect *pSrcRect, int nMaskColor) {
|
||||
ErrorCode errorCode = ERR_NONE;
|
||||
|
||||
if (_pMovie) {
|
||||
// Update the movie, assume only unzoomed pda right now
|
||||
const CBofPoint cPos(116, 61);
|
||||
errorCode = _pMovie->update(pBmp, cPos, pSrcRect, nMaskColor);
|
||||
|
||||
// If we're done or we encountered an error, then roll over and die.
|
||||
if (errorCode != ERR_NONE || _pMovie->isModalDone()) {
|
||||
stopMovie(true);
|
||||
}
|
||||
}
|
||||
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
CBagMoo::~CBagMoo() {
|
||||
// Can possibly have a movie left over.
|
||||
delete _pMovie;
|
||||
_pMovie = nullptr;
|
||||
}
|
||||
|
||||
ErrorCode CBagMoo::setPDAMovie(CBofString &s) {
|
||||
// Should never happen, but just make sure.
|
||||
delete _pMovie;
|
||||
_pMovie = nullptr;
|
||||
|
||||
// Get a new movie object
|
||||
_pMovie = new CBagCharacterObject();
|
||||
|
||||
_pMovie->setFileName(s);
|
||||
|
||||
// Attach this bad baby...
|
||||
const ErrorCode errorCode = _pMovie->attach();
|
||||
if (errorCode == ERR_NONE) {
|
||||
_pMovie->setModal(false);
|
||||
_pMovie->setNumOfLoops(1);
|
||||
}
|
||||
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
void CBagMoo::stopMovie(bool bResetPDA) {
|
||||
CBagPDA *pPDA = (CBagPDA *)g_SDevManager->getStorageDevice("BPDA_WLD");
|
||||
|
||||
if (bResetPDA) {
|
||||
if (pPDA) {
|
||||
// Assume this marks the end of the movie.
|
||||
switch (_eSavePDAMode) {
|
||||
case PDA_MAP_MODE:
|
||||
pPDA->showMap();
|
||||
break;
|
||||
|
||||
case PDA_INV_MODE:
|
||||
pPDA->showInventory();
|
||||
break;
|
||||
|
||||
case PDA_LOG_MODE:
|
||||
pPDA->showLog();
|
||||
break;
|
||||
|
||||
case PDA_NO_MODE:
|
||||
default:
|
||||
pPDA->hideMovie();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (_pMovie) {
|
||||
_pMovie->detach();
|
||||
delete _pMovie;
|
||||
_pMovie = nullptr;
|
||||
}
|
||||
|
||||
// If we're done playing, then deactivate the PDA.
|
||||
if (pPDA && pPDA->getDeactivate() == true && pPDA->isActivated()) {
|
||||
pPDA->deactivate();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
76
engines/bagel/spacebar/baglib/moo.h
Normal file
76
engines/bagel/spacebar/baglib/moo.h
Normal file
@@ -0,0 +1,76 @@
|
||||
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BAGEL_BAGLIB_MOO_H
|
||||
#define BAGEL_BAGLIB_MOO_H
|
||||
|
||||
#include "bagel/spacebar/baglib/storage_dev_bmp.h"
|
||||
#include "bagel/spacebar/baglib/character_object.h"
|
||||
#include "bagel/spacebar/baglib/pda.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
class CBagMoo : public CBagStorageDevBmp {
|
||||
private:
|
||||
static CBagCharacterObject *_pMovie;
|
||||
static PdaMode _eSavePDAMode;
|
||||
static PdaPos _eSavePDAPos;
|
||||
|
||||
public:
|
||||
CBagMoo() : CBagStorageDevBmp() {
|
||||
}
|
||||
virtual ~CBagMoo();
|
||||
static void initialize();
|
||||
|
||||
ErrorCode update(CBofBitmap *pBmp, CBofPoint pt, CBofRect *pSrcRect = nullptr, int nMaskColor = -1) override;
|
||||
|
||||
// Grab the button event of the bagbmobj and send them to the cbagsdev
|
||||
void onLButtonUp(uint32 /*nFlags*/, CBofPoint */*xPoint*/, void */*info*/) override {
|
||||
}
|
||||
void onLButtonDown(uint32 /*nFlags*/, CBofPoint */*xPoint*/, void * = nullptr) override {
|
||||
}
|
||||
|
||||
// For public access to our movie object
|
||||
|
||||
ErrorCode setPDAMovie(CBofString &s);
|
||||
CBagCharacterObject *getPDAMovie() {
|
||||
return _pMovie;
|
||||
}
|
||||
|
||||
void stopMovie(bool);
|
||||
bool moviePlaying() {
|
||||
return _pMovie != nullptr;
|
||||
}
|
||||
|
||||
void savePDAMode(PdaMode pdaMode) {
|
||||
_eSavePDAMode = pdaMode;
|
||||
}
|
||||
void savePDAPosition(PdaPos pdaPos) {
|
||||
_eSavePDAPos = pdaPos;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
|
||||
#endif
|
||||
538
engines/bagel/spacebar/baglib/movie_object.cpp
Normal file
538
engines/bagel/spacebar/baglib/movie_object.cpp
Normal file
@@ -0,0 +1,538 @@
|
||||
/* 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 "common/file.h"
|
||||
#include "bagel/spacebar/baglib/movie_object.h"
|
||||
#include "bagel/spacebar/baglib/exam.h"
|
||||
#include "bagel/spacebar/baglib/master_win.h"
|
||||
#include "bagel/spacebar/baglib/pan_window.h"
|
||||
#include "bagel/boflib/sound.h"
|
||||
#include "bagel/spacebar/baglib/fmovie.h"
|
||||
#include "bagel/spacebar/baglib/zoom_pda.h"
|
||||
#include "bagel/boflib/file_functions.h"
|
||||
#include "bagel/boflib/log.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
#define SOUND_FILE_EXT_LOWER ".wav"
|
||||
#define SOUND_FILE_EXT_UPPER ".WAV"
|
||||
#define OVERRIDE_SMK "$SBARDIR\\BAR\\LOG\\OVERRIDE.SMK"
|
||||
|
||||
CBagMovieObject::CBagMovieObject() {
|
||||
_xObjType = MOVIE_OBJ;
|
||||
setVisible(true);
|
||||
_xDisplayType = dispType::MOVIE;
|
||||
_bFlyThru = false;
|
||||
|
||||
// Initialize asynch flags to be off by default.
|
||||
_nAsynchFlags = 0;
|
||||
|
||||
// Allow user to force movie not to increment (default = increment = true)
|
||||
setIncrement();
|
||||
|
||||
// Allow movie to play on a black background (default, nada).
|
||||
setOnBlack(false);
|
||||
|
||||
// Default is no associated sound.
|
||||
setAssociatedSound(nullptr);
|
||||
}
|
||||
|
||||
CBagMovieObject::~CBagMovieObject() {
|
||||
CBagObject::detach();
|
||||
|
||||
// Could still by lying around in the pda movie queue,
|
||||
// Make sure it has been removed.
|
||||
if (_xDisplayType == dispType::ASYNCH_PDA_MSG) {
|
||||
CBagPDA::removeFromMovieQueue(this);
|
||||
}
|
||||
|
||||
// If there's a sound with this guy, then trash it here.
|
||||
if (getAssociatedSound()) {
|
||||
delete getAssociatedSound();
|
||||
setAssociatedSound(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
bool CBagMovieObject::runObject() {
|
||||
CBofWindow *pNewWin = nullptr;
|
||||
SBZoomPda *pPDAz = (SBZoomPda *)g_SDevManager->getStorageDevice("BPDAZ_WLD");
|
||||
const bool bZoomed = (pPDAz == nullptr ? false : pPDAz->getZoomed());
|
||||
|
||||
// Get a pointer to the current game window
|
||||
CBagStorageDevWnd *pMainWin = CBagel::getBagApp()->getMasterWnd()->getCurrentStorageDev();
|
||||
|
||||
bool rc = true;
|
||||
if (!_bFlyThru || CBagMasterWin::getFlyThru()) {
|
||||
rc = false;
|
||||
|
||||
CBofString sFileName = getFileName();
|
||||
const int nExt = sFileName.getLength() - 4; // ".EXT"
|
||||
|
||||
if (nExt <= 0) {
|
||||
logError("Movie does not have a file name or proper extension. Please write better scripts.");
|
||||
return rc;
|
||||
}
|
||||
|
||||
//
|
||||
// This would be much cooler if it were a cast to another object type and
|
||||
// then a run. But this is a quicker fix.
|
||||
//
|
||||
enum class MovieFileType {
|
||||
NONE = 0,
|
||||
TEXT = 1,
|
||||
SOUND = 2,
|
||||
MOVIE = 3
|
||||
} nMovFileType;
|
||||
const CBofString sBaseStr = sFileName.left(nExt);
|
||||
|
||||
if (sFileName.find(".smk") > 0 || sFileName.find(".SMK") > 0) {
|
||||
nMovFileType = MovieFileType::MOVIE;
|
||||
} else if (sFileName.find(SOUND_FILE_EXT_LOWER) > 0 || sFileName.find(SOUND_FILE_EXT_UPPER) > 0) {
|
||||
nMovFileType = MovieFileType::SOUND;
|
||||
} else if (sFileName.find(".txt") > 0 || sFileName.find(".TXT") > 0) {
|
||||
nMovFileType = MovieFileType::TEXT;
|
||||
} else {
|
||||
nMovFileType = MovieFileType::NONE;
|
||||
}
|
||||
|
||||
// Look for .SMK then .WAV, then .TXT
|
||||
while (!fileExists(sFileName.getBuffer())) {
|
||||
switch (nMovFileType) {
|
||||
|
||||
case MovieFileType::MOVIE:
|
||||
sFileName = sBaseStr + SOUND_FILE_EXT_LOWER;
|
||||
nMovFileType = MovieFileType::SOUND;
|
||||
break;
|
||||
|
||||
case MovieFileType::SOUND:
|
||||
sFileName = sBaseStr + ".txt";
|
||||
nMovFileType = MovieFileType::TEXT;
|
||||
break;
|
||||
|
||||
case MovieFileType::TEXT:
|
||||
bofMessageBox(sFileName.getBuffer(), "Could not find asset");
|
||||
nMovFileType = MovieFileType::NONE;
|
||||
break;
|
||||
|
||||
// We should never get here
|
||||
case MovieFileType::NONE:
|
||||
default:
|
||||
logError(buildString("Movie does not have a correct file name: %s.", sFileName.getBuffer()));
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
if (nMovFileType == MovieFileType::MOVIE) {
|
||||
bool isFiltered = false;
|
||||
CBagMasterWin *pWnd = CBagel::getBagApp()->getMasterWnd();
|
||||
CBagStorageDevWnd *pSDevWnd = (pWnd ? pWnd->getCurrentStorageDev() : nullptr);
|
||||
|
||||
// Get the pda here, we need it so much anyway.
|
||||
CBagPDA *pPDA = (CBagPDA *)g_SDevManager->getStorageDevice("BPDA_WLD");
|
||||
|
||||
assert(pPDA != nullptr);
|
||||
|
||||
// If we have an asnych movie to play, make sure it is a good
|
||||
// time to play it, if not, then queue it up so it can play at a much better time.
|
||||
if (_xDisplayType == dispType::ASYNCH_PDA_MSG) {
|
||||
if (asynchPDAMovieCanPlay() == false) {
|
||||
pPDA->addToMovieQueue(this);
|
||||
return rc;
|
||||
}
|
||||
} else if ((pWnd != nullptr) && (pSDevWnd != nullptr)) {
|
||||
// Don't need to redraw for asynch pda messages, this just
|
||||
// messes things up in the PDA redraw code
|
||||
pSDevWnd->paintScreen(nullptr);
|
||||
isFiltered = pSDevWnd->isFiltered();
|
||||
}
|
||||
|
||||
if (_xDisplayType == dispType::EXAMINE) {
|
||||
CBofRect r(160, 60, 480, 300);
|
||||
|
||||
// Offset the rect for the movies to compensate for all screen sizes
|
||||
r.offsetRect(((CBofWindow *)pMainWin)->getWindowRect().topLeft());
|
||||
|
||||
// If we have a movie playing in the zoom pda, then black out
|
||||
// the background. Examine movies will always play with a black background
|
||||
// on the mac (prevents a palette shift).
|
||||
CBagExam *pMovie = new CBagExam(CBagel::getBagApp()->getMasterWnd()->getCurrentGameWindow(), sFileName, &r);
|
||||
|
||||
// If there is an associated sound file, then start it up here.
|
||||
CBagSoundObject *pSObj = getAssociatedSound();
|
||||
if (pSObj) {
|
||||
if (pSObj->isAttached() == false) {
|
||||
pSObj->attach();
|
||||
}
|
||||
pSObj->runObject();
|
||||
}
|
||||
|
||||
CBofWindow *wnd = CBagel::getBagApp()->getMasterWnd();
|
||||
pMovie->show();
|
||||
CBofApp::getApp()->getMainWindow()->flushAllMessages();
|
||||
wnd->flushAllMessages();
|
||||
pMovie->initExam();
|
||||
delete pMovie;
|
||||
|
||||
// As soon as we're done, detach (this will also stop the sound).
|
||||
if (pSObj) {
|
||||
pSObj->detach();
|
||||
}
|
||||
} else {
|
||||
bool bActivated = false;
|
||||
CBofRect r(80, 10, 80 + 480 - 1, 10 + 360 - 1);
|
||||
|
||||
// Offset the rect for the movies to compensate for all screen sizes
|
||||
r.offsetRect(((CBofWindow *)pMainWin)->getWindowRect().topLeft());
|
||||
|
||||
if (_xDisplayType == dispType::PDA_MSG || _xDisplayType == dispType::ASYNCH_PDA_MSG) {
|
||||
// Pull up the PDA (if it exists)
|
||||
// Only pull up the PDA if we're not playing an asynch movie
|
||||
if (_xDisplayType == dispType::PDA_MSG) {
|
||||
// Increment timer one, pda message counts as one turn
|
||||
// Allow scripter to override timer increment
|
||||
if (isIncrement()) {
|
||||
g_VarManager->incrementTimers();
|
||||
}
|
||||
}
|
||||
|
||||
if (pMainWin->getDeviceType() == SDEV_GAMEWIN) {
|
||||
// If the pda is going up or down, then wait for it
|
||||
// To do its thing before attempting to activate it.
|
||||
if (pPDA->isActivating()) {
|
||||
((CBagPanWindow *)pMainWin)->waitForPDA();
|
||||
}
|
||||
|
||||
if (pPDA->isActivated() == false) {
|
||||
bActivated = ((CBagPanWindow *)pMainWin)->activatePDA();
|
||||
((CBagPanWindow *)pMainWin)->waitForPDA();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
// Pull down the PDA (if it exists)
|
||||
if (pMainWin->getDeviceType() == SDEV_GAMEWIN) {
|
||||
((CBagPanWindow *)pMainWin)->deactivatePDA();
|
||||
((CBagPanWindow *)pMainWin)->waitForPDA();
|
||||
}
|
||||
}
|
||||
|
||||
// Use the position scripted for the movie if it exists
|
||||
// The bottom, right is unimportant because movie won't resize anyway
|
||||
CBofPoint p = CBagObject::getPosition();
|
||||
|
||||
if (p.x != -1 && p.y != -1)
|
||||
r.offsetRect(p);
|
||||
|
||||
if (isFiltered) {
|
||||
if (bZoomed) {
|
||||
pNewWin = new CBofWindow();
|
||||
pNewWin->create("BLACK", 0, 0, 640, 480, CBofApp::getApp()->getMainWindow(), 0);
|
||||
pNewWin->fillWindow(COLOR_BLACK);
|
||||
}
|
||||
|
||||
CBagFMovie *pMovie = new CBagFMovie(CBofApp::getApp()->getMainWindow(), sFileName, &r);
|
||||
|
||||
if (pMovie->errorOccurred())
|
||||
logError(buildString("Movie file could not be read: %s. How? You removed that CD again didn't you", sFileName.getBuffer()));
|
||||
else {
|
||||
pMovie->show();
|
||||
CBofApp::getApp()->getMainWindow()->flushAllMessages();
|
||||
pWnd->flushAllMessages();
|
||||
pMovie->play(false);
|
||||
}
|
||||
delete pMovie;
|
||||
pMovie = nullptr;
|
||||
|
||||
delete pNewWin;
|
||||
pNewWin = nullptr;
|
||||
} else {
|
||||
// Hack.. allow script to override some other movies.
|
||||
if ((_xDisplayType == dispType::PDA_MSG) && pMainWin->isCIC() && isDontOverride() == false) {
|
||||
|
||||
char szLocalBuff[256];
|
||||
CBofString cStr(szLocalBuff, 256);
|
||||
|
||||
// Play the override message.
|
||||
cStr = OVERRIDE_SMK;
|
||||
fixPathName(cStr);
|
||||
|
||||
sFileName = cStr;
|
||||
}
|
||||
|
||||
if (_xDisplayType == dispType::ASYNCH_PDA_MSG) {
|
||||
// Tell our PDA to switch gears to do asynch movie time.
|
||||
if (pPDA->showMovie()) { // Returns false if another movie playing
|
||||
pPDA->setMovie(sFileName); // Set the movie to play
|
||||
}
|
||||
} else {
|
||||
CBofMovie *pMovie;
|
||||
|
||||
if (bZoomed && _xDisplayType != dispType::PDA_MSG) {
|
||||
pNewWin = new CBofWindow();
|
||||
pNewWin->create("BLACK", 0, 0, 640, 480, CBofApp::getApp()->getMainWindow(), 0);
|
||||
pNewWin->show();
|
||||
pNewWin->fillWindow(COLOR_BLACK);
|
||||
}
|
||||
|
||||
// If playing a PDA message while the PDA is zoomed
|
||||
if (bZoomed && _xDisplayType == dispType::PDA_MSG) {
|
||||
// Then stretch it to fit into the PDA's viewscreen
|
||||
r.setRect(24, 47, 28 + 600 - 1, 47 + 302 - 1);
|
||||
pMovie = new CBofMovie(CBofApp::getApp()->getMainWindow(), sFileName, &r, true);
|
||||
|
||||
} else {
|
||||
// Otherwise, just play the movie normally
|
||||
pMovie = new CBofMovie(CBofApp::getApp()->getMainWindow(), sFileName, &r);
|
||||
}
|
||||
|
||||
if (pMovie->errorOccurred())
|
||||
logError(buildString("Movie file could not be read: %s. How? You removed that CD again didn't you", sFileName.getBuffer()));
|
||||
else {
|
||||
// Stop any asnych movies already playing
|
||||
pPDA->stopMovie(true);
|
||||
pMovie->show();
|
||||
CBofApp::getApp()->getMainWindow()->flushAllMessages();
|
||||
pWnd->flushAllMessages();
|
||||
pMovie->play(false);
|
||||
}
|
||||
|
||||
delete pMovie;
|
||||
pMovie = nullptr;
|
||||
|
||||
// If we put a black window up, then
|
||||
delete pNewWin;
|
||||
pNewWin = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
// Put the pda down if we brought it up. (8638)
|
||||
if (_xDisplayType != dispType::ASYNCH_PDA_MSG && bActivated) {
|
||||
((CBagPanWindow *)pMainWin)->deactivatePDA();
|
||||
((CBagPanWindow *)pMainWin)->waitForPDA();
|
||||
}
|
||||
|
||||
// If we're asynch, then let it know to deactivate when done playing.
|
||||
if (_xDisplayType == dispType::ASYNCH_PDA_MSG) {
|
||||
pPDA->setDeactivate(bActivated);
|
||||
}
|
||||
}
|
||||
|
||||
// Movies usually mark the transition from one view to another
|
||||
// but not necessarily a change of sdev's, so make sure we repaint the
|
||||
// backdrop
|
||||
pMainWin->setPreFilterPan(true);
|
||||
|
||||
} else if (nMovFileType == MovieFileType::SOUND) {
|
||||
CBofSound *pSound = new CBofSound(CBofApp::getApp()->getMainWindow(), sFileName, SOUND_WAVE);
|
||||
pSound->play();
|
||||
delete pSound;
|
||||
} else if (nMovFileType == MovieFileType::TEXT) {
|
||||
Common::File f;
|
||||
if (f.open(sFileName.getBuffer())) {
|
||||
Common::String line = f.readLine();
|
||||
|
||||
bofMessageBox(line.c_str(), "Incoming Message...");
|
||||
f.close();
|
||||
} else {
|
||||
logError(buildString("Movie TEXT file could not be read: %s. Why? because we like you ...", sFileName.getBuffer()));
|
||||
}
|
||||
}
|
||||
|
||||
rc = CBagObject::runObject();
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
ParseCodes CBagMovieObject::setInfo(CBagIfstream &istr) {
|
||||
bool nObjectUpdated = false;
|
||||
char szLocalStr[256];
|
||||
CBofString sStr(szLocalStr, 256);
|
||||
|
||||
while (!istr.eof()) {
|
||||
istr.eatWhite(); // Eat any white space between script elements
|
||||
|
||||
const char ch = (char)istr.peek();
|
||||
switch (ch) {
|
||||
//
|
||||
// AS - n number of slides in sprite
|
||||
//
|
||||
case 'A': {
|
||||
getAlphaNumFromStream(istr, sStr);
|
||||
|
||||
if (!sStr.find("AS")) {
|
||||
istr.eatWhite();
|
||||
getAlphaNumFromStream(istr, sStr);
|
||||
if (!sStr.find("EXAMINE")) {
|
||||
_xDisplayType = dispType::EXAMINE;
|
||||
} else if (!sStr.find("MOVIE")) {
|
||||
_xDisplayType = dispType::MOVIE;
|
||||
|
||||
} else if (!sStr.find("FLYTHRU")) {
|
||||
_xDisplayType = dispType::MOVIE;
|
||||
_bFlyThru = true;
|
||||
} else if (!sStr.find("PDAMSG")) {
|
||||
_xDisplayType = dispType::PDA_MSG;
|
||||
} else if (!sStr.find("ASYNCH_PDAMSG")) {
|
||||
_xDisplayType = dispType::ASYNCH_PDA_MSG;
|
||||
|
||||
// see if this improves performance any...
|
||||
setPreload(true);
|
||||
}
|
||||
}
|
||||
|
||||
nObjectUpdated = true;
|
||||
}
|
||||
break;
|
||||
|
||||
// Don't queue attribute, when set, the asynch movie either plays
|
||||
// immediately or not at all.
|
||||
case 'D': {
|
||||
getAlphaNumFromStream(istr, sStr);
|
||||
|
||||
if (!sStr.find("DONTQUEUE")) {
|
||||
setDontQueue();
|
||||
nObjectUpdated = true;
|
||||
} else if (!sStr.find("DONTOVERRIDE")) {
|
||||
setDontOverride();
|
||||
nObjectUpdated = true;
|
||||
} else if (!sStr.find("DONTINCREMENT")) {
|
||||
// Don't increment the timer when playing this movie
|
||||
setIncrement(false);
|
||||
nObjectUpdated = true;
|
||||
} else {
|
||||
putbackStringOnStream(istr, sStr);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
// Don't queue attribute, when set, the asynch movie either plays
|
||||
// immediately or not at all.
|
||||
case 'P': {
|
||||
getAlphaNumFromStream(istr, sStr);
|
||||
|
||||
if (!sStr.find("PLAYIMMEDIATE")) {
|
||||
setPlayImmediate();
|
||||
nObjectUpdated = true;
|
||||
} else {
|
||||
putbackStringOnStream(istr, sStr);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
// This is probably going to be much more important to the
|
||||
// mac version... give the option of playing the movie on a black
|
||||
// background. this solves the problem of palette shifts on examine
|
||||
// movies.
|
||||
case 'O': {
|
||||
getAlphaNumFromStream(istr, sStr);
|
||||
|
||||
if (!sStr.find("ONBLACK")) {
|
||||
setPlayImmediate();
|
||||
nObjectUpdated = true;
|
||||
} else {
|
||||
putbackStringOnStream(istr, sStr);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
// Associate a sound file with this movie (primarily for examine
|
||||
// movies).
|
||||
case 'S': {
|
||||
getAlphaNumFromStream(istr, sStr);
|
||||
if (!sStr.find("SND")) {
|
||||
nObjectUpdated = true;
|
||||
|
||||
_pSndObj = new CBagSoundObject();
|
||||
if (_pSndObj->setInfo(istr) == PARSING_DONE) {
|
||||
return PARSING_DONE;
|
||||
}
|
||||
} else {
|
||||
putbackStringOnStream(istr, sStr);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
//
|
||||
// No match return from function
|
||||
//
|
||||
default: {
|
||||
const ParseCodes parseCode = CBagObject::setInfo(istr);
|
||||
if (parseCode == PARSING_DONE) {
|
||||
return PARSING_DONE;
|
||||
}
|
||||
|
||||
if (parseCode == UPDATED_OBJECT) {
|
||||
nObjectUpdated = true;
|
||||
} else { // rc==UNKNOWN_TOKEN
|
||||
if (nObjectUpdated)
|
||||
return UPDATED_OBJECT;
|
||||
|
||||
return UNKNOWN_TOKEN;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return PARSING_DONE;
|
||||
}
|
||||
|
||||
bool CBagMovieObject::asynchPDAMovieCanPlay() {
|
||||
// Don't play movie if we're zoomed or if we're in a CIC
|
||||
// or a sound is playing or another movie is playing...
|
||||
bool bCanPlay = true;
|
||||
|
||||
// Obvious case, if it is set for immediate, return true.
|
||||
if (isPlayImmediate()) {
|
||||
return bCanPlay;
|
||||
}
|
||||
|
||||
char szLocalBuff[256];
|
||||
CBofString sStr(szLocalBuff, 256);
|
||||
|
||||
sStr = "BPDAZ_WLD";
|
||||
SBZoomPda *pPDAz = (SBZoomPda *)g_SDevManager->getStorageDevice(sStr);
|
||||
|
||||
sStr = "BPDA_WLD";
|
||||
CBagPDA *pPDA = (CBagPDA *)g_SDevManager->getStorageDevice(sStr);
|
||||
|
||||
CBagPanWindow *pMainWin = (CBagPanWindow *)(CBagel::getBagApp()->getMasterWnd()->getCurrentGameWindow());
|
||||
|
||||
// Queue this message if any one of a variety of things is happening.
|
||||
assert(pPDA != nullptr);
|
||||
assert(pPDAz != nullptr);
|
||||
|
||||
if (pPDA && pPDAz) {
|
||||
if (pPDAz->getZoomed() || // We're zoomed
|
||||
(pMainWin->isCIC() && !isDontOverride()) || // We're in a character closeup
|
||||
CBofSound::soundsPlayingNotOver() || // A sound is playing
|
||||
pPDA->getPdaMode() == PDA_MOO_MODE) { // An asynch movie is already playing
|
||||
bCanPlay = false;
|
||||
}
|
||||
}
|
||||
|
||||
return bCanPlay;
|
||||
}
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
118
engines/bagel/spacebar/baglib/movie_object.h
Normal file
118
engines/bagel/spacebar/baglib/movie_object.h
Normal file
@@ -0,0 +1,118 @@
|
||||
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BAGEL_BAGLIB_MOVIE_OBJECT_H
|
||||
#define BAGEL_BAGLIB_MOVIE_OBJECT_H
|
||||
|
||||
#include "bagel/spacebar/baglib/object.h"
|
||||
#include "bagel/spacebar/baglib/sound_object.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
#define ASYNCH_DONT_QUEUE 0x0001
|
||||
#define ASYNCH_PLAY_IMMEDIATE 0x0002
|
||||
#define ASYNCH_DONT_OVERRIDE 0x0004
|
||||
|
||||
/**
|
||||
* CBagMovieObject is an object that can be place within the slide window.
|
||||
*/
|
||||
class CBagMovieObject : public CBagObject {
|
||||
public:
|
||||
enum class dispType {
|
||||
MOVIE, EXAMINE, PDA_MSG, ASYNCH_PDA_MSG
|
||||
};
|
||||
|
||||
private:
|
||||
dispType _xDisplayType;
|
||||
byte _bFlyThru;
|
||||
int16 _nAsynchFlags;
|
||||
bool _bIncrement : 1; // Increment timer for this movie?
|
||||
bool _bOnBlack : 1; // Play movie on a black background.
|
||||
CBagSoundObject *_pSndObj; // associated sound object
|
||||
|
||||
public:
|
||||
CBagMovieObject();
|
||||
virtual ~CBagMovieObject();
|
||||
|
||||
// Associated sound object access members
|
||||
void setAssociatedSound(CBagSoundObject *p) {
|
||||
_pSndObj = p;
|
||||
}
|
||||
|
||||
CBagSoundObject *getAssociatedSound() const {
|
||||
return _pSndObj;
|
||||
}
|
||||
|
||||
ParseCodes setInfo(CBagIfstream &istr) override;
|
||||
|
||||
bool runObject() override;
|
||||
|
||||
// Return true if this asynch zelda movie can play right now
|
||||
bool asynchPDAMovieCanPlay();
|
||||
|
||||
// Special routines for handling asynch zelda movies
|
||||
void setDontQueue() {
|
||||
_nAsynchFlags |= ASYNCH_DONT_QUEUE;
|
||||
}
|
||||
|
||||
void setDontOverride() {
|
||||
_nAsynchFlags |= ASYNCH_DONT_OVERRIDE;
|
||||
}
|
||||
|
||||
void setPlayImmediate() {
|
||||
_nAsynchFlags |= ASYNCH_PLAY_IMMEDIATE;
|
||||
}
|
||||
|
||||
void setIncrement(bool b = true) {
|
||||
_bIncrement = b;
|
||||
}
|
||||
|
||||
void setOnBlack(bool b = true) {
|
||||
_bOnBlack = b;
|
||||
}
|
||||
|
||||
bool isDontQueue() const {
|
||||
return (_nAsynchFlags & ASYNCH_DONT_QUEUE) != 0;
|
||||
}
|
||||
|
||||
bool isDontOverride() const {
|
||||
return (_nAsynchFlags & ASYNCH_DONT_OVERRIDE) != 0;
|
||||
}
|
||||
|
||||
bool isPlayImmediate() const {
|
||||
return (_nAsynchFlags & ASYNCH_PLAY_IMMEDIATE) != 0;
|
||||
}
|
||||
|
||||
bool isIncrement() const {
|
||||
return _bIncrement;
|
||||
}
|
||||
|
||||
bool isOnBlack() const {
|
||||
return _bOnBlack;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
|
||||
#endif
|
||||
469
engines/bagel/spacebar/baglib/object.cpp
Normal file
469
engines/bagel/spacebar/baglib/object.cpp
Normal file
@@ -0,0 +1,469 @@
|
||||
/* 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/object.h"
|
||||
#include "bagel/spacebar/baglib/menu_dlg.h"
|
||||
#include "bagel/spacebar/baglib/master_win.h"
|
||||
#include "bagel/boflib/file_functions.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
extern bool g_noMenuFl;
|
||||
|
||||
CBofString getStringTypeOfObject(BagObjectType n) {
|
||||
switch (n) {
|
||||
case BASE_OBJ:
|
||||
return "UKN";
|
||||
case BMP_OBJ:
|
||||
return "BMP";
|
||||
case SPRITE_OBJ:
|
||||
return "SPR";
|
||||
case BUTTON_OBJ:
|
||||
return "BUT";
|
||||
case SOUND_OBJ:
|
||||
return "SND";
|
||||
case LINK_OBJ:
|
||||
return "LNK";
|
||||
case RESPRNT_OBJ:
|
||||
return "RPO";
|
||||
case DOSSIER_OBJ:
|
||||
return "DOS";
|
||||
case CHAR_OBJ:
|
||||
return "CHR";
|
||||
case AREA_OBJ:
|
||||
return "ARE";
|
||||
case MOVIE_OBJ:
|
||||
return "MOVIE";
|
||||
case VAR_OBJ:
|
||||
return "VAR";
|
||||
case COMMAND_OBJ:
|
||||
return "COMMAND";
|
||||
case THING_OBJ:
|
||||
return "TNG";
|
||||
default:
|
||||
return "UKN";
|
||||
};
|
||||
}
|
||||
|
||||
CBagObject::CBagObject() {
|
||||
_xObjType = BASE_OBJ;
|
||||
_nX = -1;
|
||||
_nY = -1;
|
||||
|
||||
// All objects now default to timeless
|
||||
_nProperties = TIMELESS;
|
||||
|
||||
_nId = 0;
|
||||
_nOverCursor = 0;
|
||||
|
||||
// Init state
|
||||
_nState = 0;
|
||||
|
||||
_pMenu = nullptr;
|
||||
_pEvalExpr = nullptr;
|
||||
_bInteractive = true;
|
||||
_bNoMenu = false;
|
||||
|
||||
// Allocate this on an as-needed basis...
|
||||
_psName = nullptr;
|
||||
|
||||
// Object is dirty by default, doesn't break anything else
|
||||
// Some objects such as the pda message light are always updated
|
||||
setDirty(true);
|
||||
setAlwaysUpdate(false);
|
||||
|
||||
// All messages start as not message waiting.
|
||||
setMsgWaiting(false);
|
||||
}
|
||||
|
||||
CBagObject::~CBagObject() {
|
||||
delete _pMenu;
|
||||
_pMenu = nullptr;
|
||||
|
||||
if (_psName && (_psName != &_sFileName)) {
|
||||
delete _psName;
|
||||
}
|
||||
|
||||
_psName = nullptr;
|
||||
}
|
||||
|
||||
ErrorCode CBagObject::attach() {
|
||||
setVisible();
|
||||
return CBagParseObject::attach();
|
||||
}
|
||||
|
||||
ErrorCode CBagObject::detach() {
|
||||
setVisible(false);
|
||||
return CBagParseObject::detach();
|
||||
}
|
||||
|
||||
ErrorCode CBagObject::update(CBofBitmap * /*pBmp*/, CBofPoint /*pt*/, CBofRect * /*pSrcRect*/, int /*nMaskColor*/) {
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
bool CBagObject::onObjInteraction(CBagObject *, CBagStorageDev *) {
|
||||
return false;
|
||||
}
|
||||
|
||||
void CBagObject::setTimeless(bool b) {
|
||||
setProperty(TIMELESS, b);
|
||||
}
|
||||
|
||||
bool CBagObject::isForeGround() {
|
||||
return isProperty(FOREGROUND);
|
||||
}
|
||||
|
||||
void CBagObject::setForeGround(bool b) {
|
||||
setProperty(FOREGROUND, b);
|
||||
}
|
||||
|
||||
int CBagObject::getProperties() {
|
||||
return _nProperties;
|
||||
}
|
||||
|
||||
void CBagObject::setProperties(int nProperties) {
|
||||
_nProperties = (uint16)nProperties;
|
||||
}
|
||||
|
||||
const CBofString *CBagObject::getInitInfo() const {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int CBagObject::getProperty(const CBofString &sProp) {
|
||||
if (!sProp.find("STATE"))
|
||||
return getState();
|
||||
|
||||
if (!sProp.find("MODAL"))
|
||||
return isModal();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CBagObject::setProperty(const CBofString &sProp, int nVal) {
|
||||
if (!sProp.find("STATE"))
|
||||
setState(nVal);
|
||||
else if (!sProp.find("TIMELESS")) {
|
||||
if (nVal)
|
||||
setTimeless();
|
||||
else
|
||||
setTimeless(false);
|
||||
} else if (!sProp.find("MODAL")) {
|
||||
if (nVal)
|
||||
setModal();
|
||||
else
|
||||
setModal(false);
|
||||
}
|
||||
}
|
||||
|
||||
void CBagObject::setProperty(BAG_OBJECT_PROPERTIES xProp, bool bVal) {
|
||||
if (bVal)
|
||||
_nProperties |= xProp;
|
||||
else
|
||||
_nProperties &= ~xProp;
|
||||
}
|
||||
|
||||
bool CBagObject::runObject() {
|
||||
if (isTimeless())
|
||||
return true;
|
||||
|
||||
g_VarManager->incrementTimers();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CBagObject::setRefId(int id) {
|
||||
assert(id >= 0 && id <= 0xFFFF);
|
||||
_nId = (uint16)id;
|
||||
}
|
||||
|
||||
void CBagObject::setOverCursor(int curs) {
|
||||
_nOverCursor = (byte)curs;
|
||||
}
|
||||
|
||||
void CBagObject::setState(int state) {
|
||||
assert(ABS(state) < 0x8000);
|
||||
_nState = (int16)state;
|
||||
}
|
||||
|
||||
void CBagObject::setPosition(const CBofPoint &pos) {
|
||||
_nX = (int16)pos.x;
|
||||
_nY = (int16)pos.y;
|
||||
}
|
||||
|
||||
ParseCodes CBagObject::setInfo(CBagIfstream &istr) {
|
||||
ParseCodes parseCode = UNKNOWN_TOKEN;
|
||||
|
||||
while (!istr.eof()) {
|
||||
istr.eatWhite();
|
||||
const char ch = (char)istr.getCh();
|
||||
switch (ch) {
|
||||
//
|
||||
// =filename.ext
|
||||
//
|
||||
case '=': {
|
||||
parseCode = UPDATED_OBJECT;
|
||||
char szLocalBuff[256];
|
||||
szLocalBuff[0] = 0;
|
||||
CBofString s(szLocalBuff, 256);
|
||||
getAlphaNumFromStream(istr, s);
|
||||
fixPathName(s);
|
||||
setFileName(s);
|
||||
break;
|
||||
}
|
||||
//
|
||||
// { menu objects .... } - Add menu items
|
||||
//
|
||||
case '{': {
|
||||
parseCode = UPDATED_OBJECT;
|
||||
if (!_pMenu) {
|
||||
_pMenu = new CBagMenu;
|
||||
|
||||
// Try to cut down the number of Storage Devices by
|
||||
// removing these unused ones from the list.
|
||||
//
|
||||
g_SDevManager->unregisterStorageDev(_pMenu);
|
||||
}
|
||||
|
||||
istr.putBack();
|
||||
|
||||
char szBuff[256];
|
||||
Common::sprintf_s(szBuff, "Menu:%d", CBagMasterWin::_menuCount++);
|
||||
CBofString s(szBuff, 256);
|
||||
|
||||
_pMenu->loadFileFromStream(istr, s, false);
|
||||
}
|
||||
break;
|
||||
//
|
||||
// ^id; - Set id
|
||||
//
|
||||
case '^': {
|
||||
parseCode = UPDATED_OBJECT;
|
||||
const char c = (char)istr.peek();
|
||||
if (Common::isDigit(c)) {
|
||||
int nId;
|
||||
getIntFromStream(istr, nId);
|
||||
setRefId(nId);
|
||||
} else {
|
||||
char szLocalBuff[256];
|
||||
szLocalBuff[0] = 0;
|
||||
CBofString s(szLocalBuff, 256);
|
||||
getAlphaNumFromStream(istr, s);
|
||||
setRefName(s);
|
||||
}
|
||||
break;
|
||||
}
|
||||
//
|
||||
// *state; - Set state
|
||||
//
|
||||
case '*': {
|
||||
parseCode = UPDATED_OBJECT;
|
||||
int nState;
|
||||
getIntFromStream(istr, nState);
|
||||
setState(nState);
|
||||
break;
|
||||
}
|
||||
//
|
||||
// %cursor; - Set cursor
|
||||
//
|
||||
case '%': {
|
||||
parseCode = UPDATED_OBJECT;
|
||||
int nCursor;
|
||||
getIntFromStream(istr, nCursor);
|
||||
setOverCursor(nCursor);
|
||||
break;
|
||||
}
|
||||
//
|
||||
// [left,top,right,bottom] - Set position
|
||||
//
|
||||
case '[': {
|
||||
parseCode = UPDATED_OBJECT;
|
||||
CBofRect r;
|
||||
istr.putBack();
|
||||
getRectFromStream(istr, r);
|
||||
setPosition(r.topLeft());
|
||||
if (r.width() && r.height())
|
||||
setSize(CBofSize(r.width(), r.height()));
|
||||
break;
|
||||
}
|
||||
//
|
||||
// IS [NOT] [MOVABLE|MODAL|VISIBLE|STRETCHABLE|HIGHLIGHT|ACTIVE|TRANSPARENT|HIDE_ON_CLICK|IMMEDIATE_RUN|LOCAL|CONSTANT_UPDATE|PRELOAD|FOREGROUND]
|
||||
//
|
||||
case 'I': {
|
||||
if (istr.peek() != 'S') {
|
||||
istr.putBack();
|
||||
|
||||
return parseCode;
|
||||
}
|
||||
char szLocalBuff[256];
|
||||
szLocalBuff[0] = 0;
|
||||
CBofString s(szLocalBuff, 256);
|
||||
bool b = true;
|
||||
istr.getCh();
|
||||
istr.eatWhite();
|
||||
getAlphaNumFromStream(istr, s);
|
||||
if (!s.find("NOT")) {
|
||||
getAlphaNumFromStream(istr, s);
|
||||
istr.eatWhite();
|
||||
b = false;
|
||||
}
|
||||
if (!s.find("MOVABLE")) {
|
||||
setMovable(b);
|
||||
} else if (!s.find("MODAL")) {
|
||||
setModal(b);
|
||||
} else if (!s.find("VISIBLE")) {
|
||||
setVisible(b);
|
||||
} else if (!s.find("STRETCHABLE")) {
|
||||
setStretchable(b);
|
||||
} else if (!s.find("HIGHLIGHT")) {
|
||||
setHighlight(b);
|
||||
} else if (!s.find("ACTIVE")) {
|
||||
setActive(b);
|
||||
} else if (!s.find("TRANSPARENT")) {
|
||||
setTransparent(b);
|
||||
} else if (!s.find("HIDE_ON_CLICK")) {
|
||||
setHideOnClick(b);
|
||||
} else if (!s.find("IMMEDIATE_RUN")) {
|
||||
setImmediateRun(b);
|
||||
} else if (!s.find("TIMELESS")) {
|
||||
setTimeless(b);
|
||||
} else if (!s.find("LOCAL")) {
|
||||
setLocal(b);
|
||||
} else if (!s.find("CONSTANT_UPDATE")) {
|
||||
setConstantUpdate(b);
|
||||
} else if (!s.find("PRELOAD")) {
|
||||
setPreload(b);
|
||||
} else if (!s.find("NOMENU")) {
|
||||
_bNoMenu = true;
|
||||
|
||||
} else if (!s.find("FOREGROUND")) {
|
||||
setForeGround(b);
|
||||
} else {
|
||||
putbackStringOnStream(istr, s);
|
||||
if (!b)
|
||||
putbackStringOnStream(istr, " NOT ");
|
||||
putbackStringOnStream(istr, "IS ");
|
||||
|
||||
return parseCode;
|
||||
}
|
||||
parseCode = UPDATED_OBJECT;
|
||||
break;
|
||||
}
|
||||
//
|
||||
// ; is the end of the line, exit this object
|
||||
//
|
||||
case ';':
|
||||
return PARSING_DONE;
|
||||
|
||||
//
|
||||
// no match return from function
|
||||
//
|
||||
default:
|
||||
istr.putBack();
|
||||
return parseCode;
|
||||
}
|
||||
}
|
||||
|
||||
return parseCode;
|
||||
}
|
||||
|
||||
void CBagObject::onLButtonUp(uint32 nFlags, CBofPoint */*xPoint*/, void *) {
|
||||
if (getMenuPtr()) {
|
||||
|
||||
CBofPoint pt = getMousePos();
|
||||
CBofWindow *pWnd = CBofApp::getApp()->getMainWindow();
|
||||
pWnd->screenToClient(&pt);
|
||||
|
||||
// Just send the mouse pos
|
||||
CBofRect r = getRect();
|
||||
getMenuPtr()->trackPopupMenu(nFlags, pt.x, pt.y, pWnd, nullptr, &r);
|
||||
|
||||
} else {
|
||||
g_noMenuFl = true;
|
||||
}
|
||||
|
||||
runObject();
|
||||
}
|
||||
|
||||
bool CBagObject::onMouseMove(uint32 /*nFlags*/, CBofPoint /*xPoint*/, void *) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CBagObject::onMouseOver(uint32, CBofPoint, void *) {
|
||||
return false;
|
||||
}
|
||||
|
||||
CBofPoint CBagObject::getPosition() {
|
||||
return CBofPoint(_nX, _nY);
|
||||
}
|
||||
|
||||
int CBagObject::getRefId() {
|
||||
return _nId;
|
||||
}
|
||||
|
||||
int CBagObject::getOverCursor() {
|
||||
return _nOverCursor;
|
||||
}
|
||||
|
||||
int CBagObject::getState() {
|
||||
return _nState;
|
||||
}
|
||||
|
||||
CBofRect CBagObject::getRect() {
|
||||
return CBofRect(_nX, _nY, _nX - 1, _nY - 1);
|
||||
}
|
||||
|
||||
const CBofString &CBagObject::getFileName() {
|
||||
return _sFileName;
|
||||
}
|
||||
|
||||
CBagMenu *CBagObject::getMenuPtr() {
|
||||
return _pMenu;
|
||||
}
|
||||
|
||||
const CBofString &CBagObject::getRefName() {
|
||||
if (_psName) {
|
||||
return *_psName;
|
||||
}
|
||||
|
||||
return _emptyString;
|
||||
}
|
||||
|
||||
// Since we have an inordinate number of bag objects that replicate the
|
||||
// filename as the objects name, if this is the case, then use a pointer
|
||||
// to the filename.
|
||||
void CBagObject::setRefName(const CBofString &s) {
|
||||
// If we got an old one hanging around then trash it.
|
||||
if (_psName && _psName != &_sFileName) {
|
||||
delete _psName;
|
||||
}
|
||||
_psName = nullptr;
|
||||
|
||||
// If it's the same as the filename, then point to the filename
|
||||
if (!_sFileName.isEmpty() && _sFileName.compare(s) == 0) {
|
||||
_psName = &_sFileName;
|
||||
} else if (!s.isEmpty()) {
|
||||
_psName = new CBofString(s);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
368
engines/bagel/spacebar/baglib/object.h
Normal file
368
engines/bagel/spacebar/baglib/object.h
Normal file
@@ -0,0 +1,368 @@
|
||||
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BAGEL_BAGLIB_OBJECT_H
|
||||
#define BAGEL_BAGLIB_OBJECT_H
|
||||
|
||||
#include "bagel/spacebar/baglib/expression.h"
|
||||
#include "bagel/spacebar/baglib/res.h"
|
||||
#include "bagel/spacebar/boflib/gfx/bitmap.h"
|
||||
#include "bagel/boflib/string.h"
|
||||
#include "bagel/spacebar/baglib/parse_object.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
class CBagObject;
|
||||
typedef void *(*BagFuncPtr)(int, void *);
|
||||
|
||||
enum BagObjectType {
|
||||
BASE_OBJ = 0x0000,
|
||||
BMP_OBJ = BOF_BMP_OBJ,
|
||||
SPRITE_OBJ = BOF_SPRITE_OBJ,
|
||||
BUTTON_OBJ = BOF_BUTTON_OBJ,
|
||||
SOUND_OBJ = BOF_SOUND_OBJ,
|
||||
LINK_OBJ = BOF_LINK_OBJ,
|
||||
TEXT_OBJ = BOF_TEXT_OBJ,
|
||||
CHAR_OBJ = BOF_CHAR_OBJ,
|
||||
VAR_OBJ = BOF_VAR_OBJ,
|
||||
AREA_OBJ = BOF_AREA_OBJ,
|
||||
EXPRESS_OBJ = BOF_EXPRESS_OBJ,
|
||||
COMMAND_OBJ = BOF_COMM_OBJ,
|
||||
MOVIE_OBJ = BOF_MOVIE_OBJ,
|
||||
THING_OBJ = BOF_THING_OBJ,
|
||||
RESPRNT_OBJ = BOF_RESPRNT_OBJ,
|
||||
DOSSIER_OBJ = BOF_DOSSIER_OBJ,
|
||||
USER_OBJ = 0x1000
|
||||
};
|
||||
|
||||
enum BAG_OBJECT_PROPERTIES {
|
||||
NONE = 0x0000,
|
||||
MOVABLE = 0x0001,
|
||||
MODAL = 0x0002,
|
||||
VISIBLE = 0x0004,
|
||||
HIGHLIGHT = 0x0008,
|
||||
ACTIVE = 0x0010,
|
||||
TRANSPAR = 0x0020,
|
||||
HIDEONCLK = 0x0040,
|
||||
IMRUN = 0x0080,
|
||||
LOCAL = 0x0100,
|
||||
NEGATIVE = 0x0200,
|
||||
CONUPDATE = 0x0400,
|
||||
STRETCH = 0x0800,
|
||||
TIMELESS = 0x1000,
|
||||
FLOATING = 0x2000,
|
||||
PRELOAD = 0x4000,
|
||||
FOREGROUND = 0x8000
|
||||
};
|
||||
|
||||
class CBagMenu;
|
||||
class CBagStorageDev;
|
||||
|
||||
CBofString getStringTypeOfObject(BagObjectType n);
|
||||
|
||||
/**
|
||||
* CBofBagObject is an object that can be place within the slide window.
|
||||
*/
|
||||
class CBagObject : public CBagParseObject, public CBofObject, public CBofError {
|
||||
private:
|
||||
CBofString _sFileName; // File name contain object look/feel data
|
||||
CBofString *_psName = nullptr; // Name of this object, needed by movable objects only, it equals file name unless specified.
|
||||
CBagMenu *_pMenu = nullptr; // Menu for the object
|
||||
CBagExpression *_pEvalExpr = nullptr; // Pointer to expression to be evaluated by
|
||||
CBofString _emptyString;
|
||||
|
||||
int16 _nState = 0; // Current state of the object
|
||||
uint16 _nId = 0; // Ref Id for an object
|
||||
|
||||
protected:
|
||||
uint16 _xObjType = AREA_OBJ;
|
||||
|
||||
private:
|
||||
uint16 _nProperties = 0; // Properties of object
|
||||
|
||||
int16 _nX = 0; // Replaces _xPosition
|
||||
int16 _nY = 0;
|
||||
|
||||
byte _nOverCursor = 0; // Ref Id for the objects over cursor
|
||||
byte _bDirty : 1; // Object needs redrawing or not?
|
||||
byte _bMsgWaiting : 1; // Event needing to be played?
|
||||
byte _bAlwaysUpdate : 1; // For message light
|
||||
byte _bNoMenu : 1; // Used by AS NOMENU
|
||||
|
||||
protected:
|
||||
byte _bInteractive = 0;
|
||||
|
||||
// Object property functionality
|
||||
bool isProperty(BAG_OBJECT_PROPERTIES xProp) {
|
||||
return _nProperties & xProp;
|
||||
}
|
||||
|
||||
void setProperty(BAG_OBJECT_PROPERTIES xProp, bool bVal);
|
||||
|
||||
public:
|
||||
CBagObject();
|
||||
virtual ~CBagObject();
|
||||
|
||||
bool isInteractive() {
|
||||
return _bInteractive;
|
||||
}
|
||||
void setInteractive(bool b) {
|
||||
_bInteractive = (byte)b;
|
||||
}
|
||||
|
||||
// Callback function functionality - probably can be phased out
|
||||
virtual bool runCallBack() {
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual BagFuncPtr getCallBack() {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Run Object is called when there is no callback and the item was selected
|
||||
virtual bool runObject();
|
||||
|
||||
void setExpression(CBagExpression *pExpr) {
|
||||
_pEvalExpr = pExpr;
|
||||
}
|
||||
CBagExpression *getExpression() const {
|
||||
return _pEvalExpr;
|
||||
}
|
||||
|
||||
// Return true if the Object had members that are properly initialized/de-initialized
|
||||
ErrorCode attach() override;
|
||||
ErrorCode detach() override;
|
||||
|
||||
BagObjectType getType() {
|
||||
return (BagObjectType)_xObjType;
|
||||
}
|
||||
void setType(BagObjectType nType) {
|
||||
_xObjType = (uint16)nType;
|
||||
}
|
||||
|
||||
// Object can be moved within a screen
|
||||
virtual bool isInside(const CBofPoint &xPoint) {
|
||||
return getRect().ptInRect(xPoint);
|
||||
}
|
||||
|
||||
// Object can be moved within a screen
|
||||
bool isMovable() {
|
||||
return isProperty(MOVABLE);
|
||||
}
|
||||
void setMovable(bool b = true) {
|
||||
setProperty(MOVABLE, b);
|
||||
}
|
||||
// Object can be stretched within a screen
|
||||
bool isStretchable() {
|
||||
return isProperty(STRETCH);
|
||||
}
|
||||
void setStretchable(bool b = true) {
|
||||
setProperty(STRETCH, b);
|
||||
}
|
||||
// Object has exclusive updates to a screen
|
||||
bool isModal() {
|
||||
return isProperty(MODAL);
|
||||
}
|
||||
void setModal(bool b = true) {
|
||||
setProperty(MODAL, b);
|
||||
}
|
||||
virtual bool isModalDone() {
|
||||
return true;
|
||||
}
|
||||
// Is object visible within scene
|
||||
bool isVisible() {
|
||||
return isProperty(VISIBLE);
|
||||
}
|
||||
void setVisible(bool b = true) {
|
||||
setProperty(VISIBLE, b);
|
||||
}
|
||||
// Should object be highlighted when the mouse is over
|
||||
bool isHighlight() {
|
||||
return isProperty(HIGHLIGHT);
|
||||
}
|
||||
void setHighlight(bool b = true) {
|
||||
setProperty(HIGHLIGHT, b);
|
||||
}
|
||||
// Is the object active in this world
|
||||
bool isActive() {
|
||||
return isProperty(ACTIVE);
|
||||
}
|
||||
void setActive(bool b = true) {
|
||||
setProperty(ACTIVE, b);
|
||||
}
|
||||
// Is the object has a transparent background
|
||||
bool isTransparent() {
|
||||
return isProperty(TRANSPAR);
|
||||
}
|
||||
|
||||
virtual void setTransparent(bool b = true) {
|
||||
setProperty(TRANSPAR, b);
|
||||
}
|
||||
// Should the object be hidden when clicked on
|
||||
bool isHideOnClick() {
|
||||
return isProperty(HIDEONCLK);
|
||||
}
|
||||
void setHideOnClick(bool b = true) {
|
||||
setProperty(HIDEONCLK, b);
|
||||
}
|
||||
// Should the object run and then be destroyed after the attach
|
||||
bool isImmediateRun() {
|
||||
return isProperty(IMRUN);
|
||||
}
|
||||
void setImmediateRun(bool b = true) {
|
||||
setProperty(IMRUN, b);
|
||||
}
|
||||
// Is the object currently local to the object
|
||||
bool isLocal() {
|
||||
return isProperty(LOCAL);
|
||||
}
|
||||
void setLocal(bool b = true) {
|
||||
setProperty(LOCAL, b);
|
||||
}
|
||||
// Is the object expression negative
|
||||
bool isNegative() {
|
||||
return isProperty(NEGATIVE);
|
||||
}
|
||||
void setNegative(bool b = true) {
|
||||
setProperty(NEGATIVE, b);
|
||||
}
|
||||
// Should the object be constantly updated, even when not on screen
|
||||
bool isConstantUpdate() {
|
||||
return isProperty(CONUPDATE);
|
||||
}
|
||||
void setConstantUpdate(bool b = true) {
|
||||
setProperty(CONUPDATE, b);
|
||||
}
|
||||
// Does this objects action take up time
|
||||
bool isTimeless() {
|
||||
return isProperty(TIMELESS);
|
||||
}
|
||||
|
||||
void setTimeless(bool b = true);
|
||||
// Does this objects have a set position/or should the sdev provide one when it is attached
|
||||
bool isFloating() {
|
||||
return isProperty(FLOATING);
|
||||
}
|
||||
void setFloating(bool b = true) {
|
||||
setProperty(FLOATING, b);
|
||||
}
|
||||
// Does this objects have a set position/or should the sdev provide one when it is attached
|
||||
bool isPreload() {
|
||||
return isProperty(PRELOAD);
|
||||
}
|
||||
void setPreload(bool b = true) {
|
||||
setProperty(PRELOAD, b);
|
||||
}
|
||||
// Does this objects have a set position/or should the sdev provide one when it is attached
|
||||
bool isForeGround();
|
||||
void setForeGround(bool b = true);
|
||||
int getProperties();
|
||||
void setProperties(int nProperties);
|
||||
|
||||
// Init variables
|
||||
virtual const CBofString *getInitInfo() const;
|
||||
virtual void setInitInfo(const CBofString &) {
|
||||
}
|
||||
virtual int getProperty(const CBofString &sProp);
|
||||
virtual void setProperty(const CBofString &, int nVal);
|
||||
|
||||
bool isDirty() {
|
||||
return _bDirty != 0;
|
||||
}
|
||||
|
||||
void setDirty(bool b = true) {
|
||||
_bDirty = (byte)b;
|
||||
}
|
||||
|
||||
// If this thing is getting purged but is awaiting playback, then mark it as such.
|
||||
bool isMsgWaiting() {
|
||||
return _bMsgWaiting != 0;
|
||||
}
|
||||
|
||||
void setMsgWaiting(bool b = true) {
|
||||
_bMsgWaiting = (byte)b;
|
||||
}
|
||||
|
||||
bool isAlwaysUpdate() {
|
||||
return _bAlwaysUpdate != 0;
|
||||
}
|
||||
|
||||
void setAlwaysUpdate(bool b = true) {
|
||||
_bAlwaysUpdate = (byte)b;
|
||||
}
|
||||
|
||||
bool isNoMenu() {
|
||||
return _bNoMenu;
|
||||
}
|
||||
|
||||
void setNoMenu(bool b = true) {
|
||||
_bNoMenu = (byte)b;
|
||||
}
|
||||
|
||||
virtual CBofPoint getPosition();
|
||||
virtual int getRefId();
|
||||
virtual int getOverCursor();
|
||||
virtual int getState();
|
||||
virtual CBofRect getRect();
|
||||
virtual const CBofString &getFileName();
|
||||
CBagMenu *getMenuPtr();
|
||||
virtual const CBofString &getRefName();
|
||||
virtual void setRefName(const CBofString &s);
|
||||
virtual void setFileName(const CBofString &s);
|
||||
virtual void setSize(const CBofSize &) {
|
||||
}
|
||||
virtual void setRefId(int id);
|
||||
virtual void setOverCursor(int curs);
|
||||
virtual void setState(int state);
|
||||
virtual void setMenuPtr(CBagMenu *pm);
|
||||
virtual void setPosition(const CBofPoint &pos);
|
||||
|
||||
/**
|
||||
* Takes in info and then removes the relative information and returns
|
||||
* UNKNOWN_TOKEN if nothing has changed
|
||||
* UPDATED_OBJECT if something has changed
|
||||
* PARSING_DONE if done processing
|
||||
*/
|
||||
ParseCodes setInfo(CBagIfstream &istr) override;
|
||||
|
||||
virtual ErrorCode update(CBofBitmap *pBmp, CBofPoint pt, CBofRect *pSrcRect = nullptr, int /*nMaskColor*/ = -1);
|
||||
virtual bool onObjInteraction(CBagObject * /*pObj*/, CBagStorageDev * /*pSDev*/);
|
||||
virtual void onLButtonDown(uint32 /*nFlags*/, CBofPoint */*xPoint*/, void * = nullptr) {
|
||||
}
|
||||
virtual void onLButtonUp(uint32 /*nFlags*/, CBofPoint */*xPoint*/, void * = nullptr); // run menu if available
|
||||
virtual bool onMouseMove(uint32 /*nFlags*/, CBofPoint /*xPoint*/, void * = nullptr);
|
||||
virtual bool onMouseOver(uint32 /*nFlags*/, CBofPoint /*xPoint*/, void * = nullptr);
|
||||
};
|
||||
|
||||
inline void CBagObject::setFileName(const CBofString &s) {
|
||||
_sFileName = s;
|
||||
}
|
||||
|
||||
inline void CBagObject::setMenuPtr(CBagMenu *pm) {
|
||||
_pMenu = pm;
|
||||
}
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
|
||||
#endif
|
||||
58
engines/bagel/spacebar/baglib/paint_table.cpp
Normal file
58
engines/bagel/spacebar/baglib/paint_table.cpp
Normal file
@@ -0,0 +1,58 @@
|
||||
|
||||
/* 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/paint_table.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
stripEnds STRIP_POINTS[153][120];
|
||||
|
||||
void PaintTable::initialize(Common::SeekableReadStream &src) {
|
||||
for (int stripNum = 0; stripNum < 153; ++stripNum) {
|
||||
// Read comment line
|
||||
Common::String line = src.readLine();
|
||||
assert(line.hasPrefix("/*"));
|
||||
|
||||
// Iterate through the following 12 lines to read the 120 points
|
||||
int pointIndex = 0;
|
||||
for (int lineNum = 0; lineNum < 12; ++lineNum) {
|
||||
line = src.readLine();
|
||||
|
||||
for (int pointNum = 0; pointNum < 10; ++pointNum, ++pointIndex) {
|
||||
// Get the point
|
||||
int y1 = 0, y2 = 0;
|
||||
const int result = sscanf(line.c_str(), "{ %d,%d}", &y1, &y2);
|
||||
assert(result == 2);
|
||||
|
||||
STRIP_POINTS[stripNum][pointIndex]._top = y1;
|
||||
STRIP_POINTS[stripNum][pointIndex]._bottom = y2;
|
||||
|
||||
// Move to next point on line
|
||||
line = Common::String(strchr(line.c_str() + 1, '{'));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
49
engines/bagel/spacebar/baglib/paint_table.h
Normal file
49
engines/bagel/spacebar/baglib/paint_table.h
Normal file
@@ -0,0 +1,49 @@
|
||||
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BAGEL_BAGLIB_PAINT_TABLE_H
|
||||
#define BAGEL_BAGLIB_PAINT_TABLE_H
|
||||
|
||||
#include "common/stream.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
struct stripEnds {
|
||||
int16 _top;
|
||||
int16 _bottom;
|
||||
};
|
||||
|
||||
extern stripEnds STRIP_POINTS[153][120];
|
||||
|
||||
class PaintTable {
|
||||
public:
|
||||
/**
|
||||
* Loads the data used for the pseudo-3d projection of panning windows
|
||||
*/
|
||||
static void initialize(Common::SeekableReadStream &src);
|
||||
};
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
|
||||
#endif
|
||||
435
engines/bagel/spacebar/baglib/pan_bitmap.cpp
Normal file
435
engines/bagel/spacebar/baglib/pan_bitmap.cpp
Normal file
@@ -0,0 +1,435 @@
|
||||
/* 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/pan_bitmap.h"
|
||||
#include "bagel/spacebar/baglib/bagel.h"
|
||||
#include "bagel/spacebar/baglib/paint_table.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
const CBofRect CBagPanBitmap::getMaxView(CBofSize s) {
|
||||
CBofRect r;
|
||||
|
||||
if (_bPanorama) {
|
||||
int h = 3 * (int)((double)width() / (MAX_DIV_VIEW * 4));
|
||||
if (h > height())
|
||||
h = height();
|
||||
|
||||
r.setRect(0, 0, (int)(width() / MAX_DIV_VIEW - 2), h - 1);
|
||||
|
||||
} else {
|
||||
r.setRect(0, 0, width() - 1, height() - 1);
|
||||
}
|
||||
|
||||
if (s.cx > 0 && r.right > s.cx) {
|
||||
// r.left = s.cx;
|
||||
r.right = s.cx - 1;
|
||||
}
|
||||
|
||||
if (s.cy > 0 && r.bottom > s.cy) {
|
||||
r.bottom = s.cy - 1;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
CBagPanBitmap::CBagPanBitmap(const char *pszFileName, CBofPalette *pPalette, const CBofRect &xViewSize) :
|
||||
CBofBitmap(pszFileName, pPalette, true) {
|
||||
int nW = width();
|
||||
int nH = height();
|
||||
|
||||
_bPanorama = false;
|
||||
_pCosineTable = nullptr;
|
||||
_bActiveScrolling = false; // The scrolling is not active
|
||||
_xDirection = kDirNONE; // Direction is not moving
|
||||
_xFOVAngle = 0;
|
||||
_nCorrWidth = 0;
|
||||
_nNumDegrees = 0;
|
||||
|
||||
|
||||
if (nW && nH) {
|
||||
CBofRect xMaxViewSize(0, 0, nW - 1, nH - 1);
|
||||
if (nW > 1000) {
|
||||
xMaxViewSize.left = (long)(nW / MAX_DIV_VIEW);
|
||||
_bPanorama = true;
|
||||
}
|
||||
|
||||
pPalette = getPalette();
|
||||
|
||||
if (xViewSize.isRectEmpty())
|
||||
_xCurrView = xMaxViewSize;
|
||||
else
|
||||
_xCurrView = xViewSize;
|
||||
|
||||
if (_xCurrView.width() > xMaxViewSize.width()) {
|
||||
_xCurrView.setRect(0, _xCurrView.top, xMaxViewSize.width() - 1, _xCurrView.bottom);
|
||||
}
|
||||
|
||||
_xRotateRate.x = (nW - _xCurrView.width()) / 64 + 1;
|
||||
_xRotateRate.y = (nH - _xCurrView.height()) / 64 + 1;
|
||||
|
||||
normalizeViewSize();
|
||||
|
||||
// If FOV is set to 0 then unity FOV is assumed (faster redraws)
|
||||
// The update parameter is set to false to avoid to update the cosine table as _nCorrWidth isn't set yet
|
||||
setFOV(DEF_FOV, false);
|
||||
|
||||
// Initialize _nCorrWidth and generate the cosine table.
|
||||
if (_bPanorama)
|
||||
setCorrWidth(4, true);
|
||||
else
|
||||
setCorrWidth(0, true);
|
||||
|
||||
_bIsValid = true;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
_bIsValid = false;
|
||||
}
|
||||
|
||||
CBagPanBitmap::~CBagPanBitmap() {
|
||||
assert(isValidObject(this));
|
||||
|
||||
delete[] _pCosineTable;
|
||||
_pCosineTable = nullptr;
|
||||
}
|
||||
|
||||
// This must be updated whenever the size, view size, or correction width changes
|
||||
void CBagPanBitmap::generateCosineTable() {
|
||||
int nWidth = 1 << _nCorrWidth;
|
||||
int offset = nWidth >> 1; // This is not really needed just more correction to move angle to center
|
||||
int viewWidth = _xCurrView.width();
|
||||
|
||||
_nNumDegrees = (viewWidth >> _nCorrWidth) + 1;
|
||||
|
||||
delete[] _pCosineTable;
|
||||
_pCosineTable = new CBofFixed[_nNumDegrees];
|
||||
|
||||
for (int i = 0; i < _nNumDegrees; i++) {
|
||||
double inArea = (double)(offset + i * nWidth) / viewWidth;
|
||||
_pCosineTable[i] = (CBofFixed)(cos(_xFOVAngle * (-1.0 + 2.0 * inArea)));
|
||||
}
|
||||
}
|
||||
|
||||
CBofRect CBagPanBitmap::getWarpSrcRect() {
|
||||
int nH2 = height() >> 1;
|
||||
|
||||
return CBofRect(_xCurrView.left,
|
||||
nH2 + (int)(*_pCosineTable * CBofFixed(_xCurrView.top - nH2)),
|
||||
_xCurrView.right,
|
||||
nH2 + (int)(*_pCosineTable * CBofFixed(_xCurrView.bottom - nH2)));
|
||||
}
|
||||
|
||||
CBofPoint CBagPanBitmap::warpedPoint(CBofPoint &xPoint) {
|
||||
CBofRect r = getRect();
|
||||
int nH2 = height() >> 1;
|
||||
int nW = width();
|
||||
int nWidth = 1 << _nCorrWidth; // It may no longer be necessary to store corr width as a shift arg
|
||||
int nCenter = r.top + nH2;
|
||||
|
||||
int nOffset = (xPoint.x - _xCurrView.left); // nWidth;
|
||||
if (nOffset < 0)
|
||||
nOffset += nW;
|
||||
nOffset /= nWidth;
|
||||
|
||||
if ((nOffset < 0) || ((xPoint.x - _xCurrView.left) > _xCurrView.width()) || (nOffset >= _nNumDegrees))
|
||||
return CBofPoint(0, 0);
|
||||
|
||||
CBofFixed srcHeight = _pCosineTable[nOffset];
|
||||
|
||||
return CBofPoint(xPoint.x, nCenter + (int)(srcHeight * CBofFixed(xPoint.y - nH2)));
|
||||
}
|
||||
|
||||
ErrorCode CBagPanBitmap::paintWarped(CBofBitmap *pBmp, const CBofRect &dstRect, const CBofRect &srcRect, const int offset, CBofBitmap *pSrcBmp, const CBofRect &preSrcRect) {
|
||||
int nH2 = _nDY >> 1;
|
||||
int nWidth = 1 << _nCorrWidth; // It may no longer be necessary to store corr width as a shift arg
|
||||
CBofFixed *pSrcHeight = &_pCosineTable[offset >> _nCorrWidth];
|
||||
CBofFixed srcTop = preSrcRect.top + srcRect.top - nH2;
|
||||
CBofFixed srcBottom = preSrcRect.top + srcRect.bottom - nH2;
|
||||
int nCenter = nH2;
|
||||
|
||||
int nTop = nCenter - preSrcRect.top;
|
||||
int nRight = (srcRect.left + nWidth) - 1;
|
||||
|
||||
CBofRect PanSrcRect;
|
||||
CBofRect WndDstRect(dstRect.left + 0, dstRect.top, (dstRect.left + 0 + nWidth) - 1, dstRect.bottom);
|
||||
|
||||
pBmp->lock();
|
||||
pSrcBmp->lock();
|
||||
|
||||
int nIncrement = 1;
|
||||
|
||||
if (nWidth < 4) {
|
||||
for (int i = 0; i < dstRect.width(); i += nWidth) {
|
||||
// Set the source
|
||||
//
|
||||
PanSrcRect.setRect(srcRect.left + i,
|
||||
nTop + (int)(*pSrcHeight * srcTop),
|
||||
nRight + i,
|
||||
nTop + (int)(*pSrcHeight * srcBottom));
|
||||
|
||||
pSrcBmp->paint(pBmp, &WndDstRect, &PanSrcRect);
|
||||
|
||||
WndDstRect.left = WndDstRect.right + 1;
|
||||
WndDstRect.right = WndDstRect.right + nWidth;
|
||||
pSrcHeight += nIncrement;
|
||||
}
|
||||
} else if (nWidth == 4) {
|
||||
int tableSlot = srcRect.top + preSrcRect.top;
|
||||
int stripNumber = 0;
|
||||
|
||||
for (int i = 0; i < dstRect.width(); i += nWidth, stripNumber++) {
|
||||
// Set the source
|
||||
PanSrcRect.setRect(srcRect.left + i,
|
||||
STRIP_POINTS[tableSlot][stripNumber]._top,
|
||||
nRight + i,
|
||||
STRIP_POINTS[tableSlot][stripNumber]._bottom);
|
||||
|
||||
pSrcBmp->paintStretch4(pBmp, &WndDstRect, &PanSrcRect);
|
||||
|
||||
WndDstRect.left = WndDstRect.right + 1;
|
||||
WndDstRect.right = WndDstRect.right + nWidth;
|
||||
}
|
||||
} else { // nWidth > 4
|
||||
for (int i = 0; i < dstRect.width(); i += nWidth) {
|
||||
// Set the source
|
||||
PanSrcRect.setRect(srcRect.left + i,
|
||||
nTop + (int)(*pSrcHeight * srcTop),
|
||||
nRight + i,
|
||||
nTop + (int)(*pSrcHeight * srcBottom));
|
||||
|
||||
pSrcBmp->paintStretchOpt(pBmp, &WndDstRect, &PanSrcRect, nWidth);
|
||||
|
||||
WndDstRect.left = WndDstRect.right + 1;
|
||||
WndDstRect.right = WndDstRect.right + nWidth;
|
||||
pSrcHeight += nIncrement;
|
||||
}
|
||||
}
|
||||
|
||||
pSrcBmp->unlock();
|
||||
pBmp->unlock();
|
||||
|
||||
return _errCode;
|
||||
}
|
||||
|
||||
ErrorCode CBagPanBitmap::paintUncorrected(CBofBitmap *pBmp, CBofRect &dstRect) {
|
||||
int tmp = _nCorrWidth;
|
||||
_nCorrWidth = 0;
|
||||
|
||||
CBofFixed fONE(1);
|
||||
CBofFixed fH2(height() / 2);
|
||||
CBofFixed fCos(_pCosineTable[0]);
|
||||
int nOffset = (int)((fONE - fCos) * fH2);
|
||||
|
||||
dstRect = getCurrView();
|
||||
CBofRect tmpRect = dstRect;
|
||||
dstRect.top -= nOffset;
|
||||
dstRect.bottom += nOffset;
|
||||
|
||||
if (dstRect.top < 0) {
|
||||
dstRect.bottom = dstRect.height() - 1;
|
||||
dstRect.top = 0;
|
||||
}
|
||||
if (dstRect.height() >= pBmp->height()) {
|
||||
dstRect.bottom = dstRect.top + pBmp->height() - 2;
|
||||
}
|
||||
_xCurrView = dstRect;
|
||||
|
||||
paint(pBmp);
|
||||
_xCurrView = tmpRect;
|
||||
|
||||
_nCorrWidth = tmp;
|
||||
|
||||
return _errCode;
|
||||
}
|
||||
|
||||
ErrorCode CBagPanBitmap::paint(CBofBitmap *pBmp, const CBofPoint xDstOffset) {
|
||||
CBofRect dstRect;
|
||||
CBofRect srcRect = _xCurrView;
|
||||
int nW = width();
|
||||
int viewWidth = _xCurrView.width();
|
||||
srcRect.right = _xCurrView.left + viewWidth - 1;
|
||||
int nOffset = srcRect.right - nW;
|
||||
|
||||
dstRect.top = xDstOffset.y;
|
||||
dstRect.bottom = dstRect.top + srcRect.height() - 1;
|
||||
|
||||
// If the right side of the view is the beginning of the panorama
|
||||
// paint the un-wrapped side (right) first.
|
||||
dstRect.left = xDstOffset.x;
|
||||
dstRect.right = xDstOffset.x + viewWidth - 1;
|
||||
|
||||
if (nOffset > 0) {
|
||||
CBofRect srcRect2 = srcRect;
|
||||
srcRect2.left = 0;
|
||||
srcRect2.right = nOffset;
|
||||
dstRect.right = xDstOffset.x + viewWidth - 1;
|
||||
dstRect.left = dstRect.right - nOffset;
|
||||
|
||||
CBofBitmap::paint(pBmp, &dstRect, &srcRect2);
|
||||
|
||||
srcRect.right = nW - 1;
|
||||
dstRect.right = dstRect.left;
|
||||
dstRect.left = xDstOffset.x;
|
||||
}
|
||||
|
||||
CBofBitmap::paint(pBmp, &dstRect, &srcRect);
|
||||
|
||||
return _errCode;
|
||||
}
|
||||
|
||||
CBagPanBitmap::Direction CBagPanBitmap::updateView() {
|
||||
if (_bActiveScrolling) {
|
||||
if (_xDirection & kDirLEFT)
|
||||
rotateRight();
|
||||
else if (_xDirection & kDirRIGHT)
|
||||
rotateLeft();
|
||||
|
||||
if (_xDirection & kDirUP)
|
||||
rotateUp();
|
||||
else if (_xDirection & kDirDOWN)
|
||||
rotateDown();
|
||||
|
||||
return _xDirection;
|
||||
}
|
||||
|
||||
return kDirNONE;
|
||||
}
|
||||
|
||||
void CBagPanBitmap::setCorrWidth(int nWidth, bool bUpdate) {
|
||||
int i = 0;
|
||||
|
||||
while (nWidth >>= 1)
|
||||
++i;
|
||||
|
||||
if (i < 6) {
|
||||
_nCorrWidth = i;
|
||||
if (bUpdate) {
|
||||
generateCosineTable();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CBagPanBitmap::rotateRight(int nXRotRate) {
|
||||
if (nXRotRate > 0)
|
||||
offsetCurrView(CBofPoint(nXRotRate, 0));
|
||||
else
|
||||
offsetCurrView(CBofPoint(_xRotateRate.x, 0));
|
||||
}
|
||||
|
||||
void CBagPanBitmap::rotateLeft(int nXRotRate) {
|
||||
if (nXRotRate > 0)
|
||||
offsetCurrView(CBofPoint(-1 * nXRotRate, 0));
|
||||
else
|
||||
offsetCurrView(CBofPoint(-1 * _xRotateRate.x, 0));
|
||||
}
|
||||
|
||||
void CBagPanBitmap::rotateUp(int nYRotRate) {
|
||||
if (nYRotRate > 0)
|
||||
offsetCurrView(CBofPoint(0, nYRotRate));
|
||||
else
|
||||
offsetCurrView(CBofPoint(0, _xRotateRate.y));
|
||||
}
|
||||
|
||||
void CBagPanBitmap::rotateDown(int nYRotRate) {
|
||||
if (nYRotRate > 0)
|
||||
offsetCurrView(CBofPoint(0, -1 * nYRotRate));
|
||||
else
|
||||
offsetCurrView(CBofPoint(0, -1 * _xRotateRate.y));
|
||||
}
|
||||
|
||||
void CBagPanBitmap::normalizeViewSize() {
|
||||
int nW = width();
|
||||
int nH = height();
|
||||
|
||||
if (_bPanorama) {
|
||||
// The CurrView can not be more than 0.25Width x Height of the Bitmap
|
||||
if ((_xCurrView.width() >= nW / MAX_DIV_VIEW) || (_xCurrView.width() <= 0))
|
||||
_xCurrView.right = (long)(_xCurrView.left + nW / MAX_DIV_VIEW - 1);
|
||||
if ((_xCurrView.height() >= nH) || (_xCurrView.height() <= 0))
|
||||
_xCurrView.bottom = _xCurrView.top + nH - 1;
|
||||
|
||||
// The Base coords of CurrView must exist within the rectangle
|
||||
while (_xCurrView.left < 0)
|
||||
_xCurrView.offsetRect(nW, 0);
|
||||
while (_xCurrView.left >= nW)
|
||||
_xCurrView.offsetRect(-1 * nW, 0);
|
||||
} else { // Not a panorama
|
||||
// The Base coords of CurrView must exist within the rectangle
|
||||
if (_xCurrView.left < 0)
|
||||
_xCurrView.offsetRect(-_xCurrView.left, 0);
|
||||
else if (_xCurrView.right > nW)
|
||||
_xCurrView.offsetRect(nW - _xCurrView.right, 0);
|
||||
}
|
||||
|
||||
// We never have up and down wrap around
|
||||
if (_xCurrView.top < 0)
|
||||
_xCurrView.offsetRect(0, -_xCurrView.top);
|
||||
if (_xCurrView.bottom >= nH)
|
||||
_xCurrView.offsetRect(0, (nH - _xCurrView.bottom) - 1);
|
||||
}
|
||||
|
||||
|
||||
void CBagPanBitmap::setCurrView(const CBofRect &xCurrView) {
|
||||
_xCurrView = xCurrView;
|
||||
normalizeViewSize();
|
||||
}
|
||||
|
||||
void CBagPanBitmap::offsetCurrView(const CBofPoint &xOffset) {
|
||||
CBofRect xCurrView = _xCurrView;
|
||||
xCurrView.offsetRect(xOffset);
|
||||
setCurrView(xCurrView);
|
||||
}
|
||||
|
||||
void CBagPanBitmap::setFOV(double degrees, bool bUpdate) {
|
||||
_xFOVAngle = degrees / 114.5916558176;
|
||||
if (bUpdate) {
|
||||
generateCosineTable();
|
||||
}
|
||||
}
|
||||
|
||||
void CBagPanBitmap::setViewSize(const CBofSize &xViewSize, bool bUpdate) {
|
||||
_xCurrView.right = _xCurrView.left + xViewSize.cx;
|
||||
_xCurrView.bottom = _xCurrView.top + xViewSize.cy;
|
||||
normalizeViewSize();
|
||||
|
||||
if (bUpdate) {
|
||||
generateCosineTable();
|
||||
}
|
||||
}
|
||||
|
||||
CBofSize CBagPanBitmap::setUnityViewSize() {
|
||||
int w = (int)(width() * _xFOVAngle / 3.14159);
|
||||
_xCurrView.setRect(0, _xCurrView.top, w, _xCurrView.bottom);
|
||||
generateCosineTable();
|
||||
return getViewSize();
|
||||
}
|
||||
|
||||
double CBagPanBitmap::setUnityFOV() {
|
||||
setFOV(360.0 * _xCurrView.width() / width(), false); // If FOV is set to 0 then unity FOV is assumed (faster redraws)
|
||||
generateCosineTable();
|
||||
return getFOV();
|
||||
}
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
134
engines/bagel/spacebar/baglib/pan_bitmap.h
Normal file
134
engines/bagel/spacebar/baglib/pan_bitmap.h
Normal file
@@ -0,0 +1,134 @@
|
||||
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BAGEL_BAGLIB_PAN_BITMAP_H
|
||||
#define BAGEL_BAGLIB_PAN_BITMAP_H
|
||||
|
||||
#include "bagel/spacebar/boflib/gfx/bitmap.h"
|
||||
#include "bagel/spacebar/boflib/fixed.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
#define MAX_DIV_VIEW (12.8 / 3) // Ratio for 480x380 Screen
|
||||
#define DEF_FOV (360 / MAX_DIV_VIEW) // 1TO1 Paint FOV
|
||||
|
||||
class CBagPanBitmap : public CBofBitmap {
|
||||
public:
|
||||
enum Direction {
|
||||
kDirNONE = 0x0,
|
||||
kDirUP = 0x01,
|
||||
kDirDOWN = 0x02,
|
||||
kDirLEFT = 0x04,
|
||||
kDirRIGHT = 0x08,
|
||||
kDirVIEW = 0x10
|
||||
};
|
||||
|
||||
private:
|
||||
CBofRect _xCurrView; // Viewport Window size (0->Width-1,0->Height-1,1->Width+Width/4,1->Height)
|
||||
double _xFOVAngle; // Field of view in radians
|
||||
CBofPoint _xRotateRate; // Rate of rotation on increment left, right ...
|
||||
bool _bActiveScrolling; // True when there should be screen updates
|
||||
bool _bPanorama; // True when the bitmap is a 360 panorama
|
||||
Direction _xDirection; // Set direction for next update
|
||||
int _nCorrWidth; // Size of each correction band
|
||||
CBofFixed *_pCosineTable; // Lookup table for cosine values
|
||||
int _nNumDegrees; // Number of lookups in the cosine table
|
||||
bool _bIsValid; // Is the bmp a valid object
|
||||
|
||||
void normalizeViewSize();
|
||||
void generateCosineTable();
|
||||
|
||||
public:
|
||||
CBagPanBitmap(const char *pszFileName, CBofPalette *pPalette, const CBofRect &xViewSize = CBofRect());
|
||||
virtual ~CBagPanBitmap();
|
||||
|
||||
bool isValid() const {
|
||||
return _bIsValid;
|
||||
}
|
||||
bool isPan() const {
|
||||
return _bPanorama;
|
||||
}
|
||||
|
||||
ErrorCode paint(CBofBitmap *pBmp, CBofPoint xDstOffset = CBofPoint(0, 0));
|
||||
ErrorCode paintUncorrected(CBofBitmap *pBmp, CBofRect &dstRect);
|
||||
ErrorCode paintWarped(CBofBitmap *pBmp, const CBofRect &dstRect, const CBofRect &srcRect, int offset = 0, CBofBitmap *pSrcBmp = nullptr, const CBofRect &preSrcRect = CBofRect());
|
||||
|
||||
CBofRect getWarpSrcRect();
|
||||
CBofPoint warpedPoint(CBofPoint &xPoint);
|
||||
|
||||
const CBofRect getMaxView(CBofSize s = CBofSize(640, 480));
|
||||
|
||||
void setCorrWidth(int nWidth, bool bUpdate = true);
|
||||
|
||||
void rotateRight(int nXRotRate = 0);
|
||||
void rotateLeft(int nXRotRate = 0);
|
||||
void rotateUp(int nYRotRate = 0);
|
||||
void rotateDown(int nYRotRate = 0);
|
||||
|
||||
Direction updateView();
|
||||
|
||||
void setCurrView(const CBofRect &xCurrView);
|
||||
void offsetCurrView(const CBofPoint &xOffset);
|
||||
void setFOV(double degrees, bool bUpdate = true);
|
||||
|
||||
void setViewSize(const CBofSize &xViewSize, bool bUpdate = true);
|
||||
CBofSize setUnityViewSize();
|
||||
double setUnityFOV();
|
||||
|
||||
double getFOV() const {
|
||||
return _xFOVAngle;
|
||||
}
|
||||
const CBofSize getViewSize() const {
|
||||
return CBofSize(_xCurrView.size());
|
||||
}
|
||||
const CBofRect getCurrView() const {
|
||||
return _xCurrView;
|
||||
}
|
||||
|
||||
Direction getDirection() const {
|
||||
return _xDirection;
|
||||
}
|
||||
|
||||
void setRotateRate(const CBofPoint &xRotRate) {
|
||||
_xRotateRate = xRotRate;
|
||||
}
|
||||
void setDirection(const Direction xDirection) {
|
||||
_xDirection = xDirection;
|
||||
}
|
||||
int getCorrWidth() {
|
||||
return _nCorrWidth;
|
||||
}
|
||||
|
||||
void activateScrolling(bool val = true) {
|
||||
_bActiveScrolling = val;
|
||||
}
|
||||
void deActivateScrolling() {
|
||||
activateScrolling(false);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
|
||||
#endif
|
||||
883
engines/bagel/spacebar/baglib/pan_window.cpp
Normal file
883
engines/bagel/spacebar/baglib/pan_window.cpp
Normal file
@@ -0,0 +1,883 @@
|
||||
/* 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/pan_window.h"
|
||||
#include "bagel/spacebar/baglib/res.h"
|
||||
#include "bagel/spacebar/baglib/master_win.h"
|
||||
#include "bagel/spacebar/baglib/bagel.h"
|
||||
#include "bagel/spacebar/baglib/wield.h"
|
||||
#include "bagel/spacebar/boflib/gfx/sprite.h"
|
||||
#include "bagel/spacebar/baglib/button_object.h"
|
||||
#include "bagel/spacebar/baglib/character_object.h"
|
||||
#include "bagel/spacebar/baglib/text_object.h"
|
||||
#include "bagel/spacebar/boflib/std_keys.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
CBagPDA *CBagPanWindow::_pPDABmp; // Pointer to the PDA object
|
||||
int CBagPanWindow::_nCorrection;
|
||||
int CBagPanWindow::_nPanSpeed;
|
||||
CBagWield *CBagPanWindow::_pWieldBmp; // Pointer to the WIELD object
|
||||
|
||||
void CBagPanWindow::initialize() {
|
||||
_pPDABmp = nullptr;
|
||||
_nCorrection = 4;
|
||||
_nPanSpeed = 1;
|
||||
_pWieldBmp = nullptr;
|
||||
}
|
||||
|
||||
CBagPanWindow::CBagPanWindow() : CBagStorageDevWnd() {
|
||||
_xViewPortPos = CBofPoint(0, 20);
|
||||
_xMovementRect.setRectEmpty();
|
||||
|
||||
_nCorrection = CBagMasterWin::getCorrection();
|
||||
_nPanSpeed = CBagMasterWin::getPanSpeed();
|
||||
_pSlideBitmap = nullptr;
|
||||
_pPalette = nullptr;
|
||||
_bPaintToBackdrop = true;
|
||||
_bStretchToScreen = false;
|
||||
_bDraggingObject = false;
|
||||
_bDraggingStart = CBofPoint(0, 0);
|
||||
_pViewPortBitmap = nullptr;
|
||||
|
||||
// Objects to be painted to the window
|
||||
_pFGObjectList = new CBofList<CBagObject *>();
|
||||
|
||||
// Declare this to be type game win, because it has a pda
|
||||
_xSDevType = SDEV_GAMEWIN;
|
||||
|
||||
// Make sure the prefilter gets called.
|
||||
setPreFilterPan(true);
|
||||
|
||||
CBagStorageDev::loadObjects();
|
||||
}
|
||||
|
||||
CBofRect CBagPanWindow::unSetSlideBitmap() {
|
||||
CBofRect viewRect;
|
||||
|
||||
setLActiveObject(nullptr);
|
||||
|
||||
if (_pSlideBitmap) {
|
||||
viewRect = _pSlideBitmap->getCurrView();
|
||||
delete _pSlideBitmap;
|
||||
_pSlideBitmap = nullptr;
|
||||
}
|
||||
if (_pViewPortBitmap) {
|
||||
delete _pViewPortBitmap;
|
||||
_pViewPortBitmap = nullptr;
|
||||
}
|
||||
|
||||
CBofSprite::closeLibrary();
|
||||
|
||||
// There is no palette right now
|
||||
CBofApp::getApp()->setPalette(nullptr);
|
||||
|
||||
return viewRect;
|
||||
}
|
||||
|
||||
CBofPalette *CBagPanWindow::setSlideBitmap(const CBofString &xSlideBmp, const CBofRect &xSlideRect) {
|
||||
if (!xSlideBmp.isEmpty()) {
|
||||
CBofRect viewRect = unSetSlideBitmap();
|
||||
CBofRect cRect = getWindowRect();
|
||||
|
||||
if ((cRect.width() <= 0) || (cRect.width() > DEF_WIDTH))
|
||||
cRect.setRect(cRect.left, cRect.top, cRect.left + DEF_WIDTH, cRect.bottom);
|
||||
|
||||
cRect.bottom = cRect.top + 3 * cRect.width() / 4 - 1;
|
||||
|
||||
if ((xSlideRect.width() <= 0) || (xSlideRect.width() > DEF_WIDTH))
|
||||
viewRect.setRect(xSlideRect.left, xSlideRect.top, xSlideRect.left + DEF_WIDTH, DEF_HEIGHT);
|
||||
else
|
||||
viewRect = xSlideRect;
|
||||
|
||||
// Open Pan bitmap
|
||||
_pSlideBitmap = new CBagPanBitmap(xSlideBmp, nullptr, viewRect);
|
||||
|
||||
// Make sure the file was found
|
||||
if (!_pSlideBitmap->isValid()) {
|
||||
_pPalette = nullptr;
|
||||
reportError(ERR_FOPEN, "Unable to open file %s", xSlideBmp.getBuffer());
|
||||
} else {
|
||||
// Set the bagel crap
|
||||
_pPalette = _pSlideBitmap->getPalette();
|
||||
CBofApp::getApp()->setPalette(_pPalette);
|
||||
CBagel::getBagApp()->getMasterWnd()->selectPalette(_pPalette);
|
||||
CBofApp::getApp()->getMainWindow()->selectPalette(_pPalette);
|
||||
selectPalette(_pPalette);
|
||||
|
||||
CBofSprite::openLibrary(_pPalette);
|
||||
|
||||
_pSlideBitmap->setCorrWidth(_nCorrection);
|
||||
|
||||
CBofBitmap *pBackDropBitmap = new CBofBitmap(DEF_WIDTH + 1, DEF_HEIGHT + 1, _pPalette);
|
||||
if (pBackDropBitmap->height() <= 0 || pBackDropBitmap->width() <= 0) {
|
||||
reportError(ERR_FOPEN, "Error opening bitmap");
|
||||
}
|
||||
_pViewPortBitmap = new CBofBitmap(DEF_WIDTH + 1, _pSlideBitmap->height() + 1, _pPalette);
|
||||
if (!_pViewPortBitmap->height() || !_pViewPortBitmap->width()) {
|
||||
reportError(ERR_FOPEN, "Error opening bitmap");
|
||||
}
|
||||
setBackdrop(pBackDropBitmap);
|
||||
|
||||
move(cRect.left, cRect.top);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return _pPalette;
|
||||
}
|
||||
|
||||
CBagPanWindow::~CBagPanWindow() {
|
||||
CBagStorageDev::releaseObjects(); // Delete all master sprite objects
|
||||
|
||||
if (_pSlideBitmap) {
|
||||
delete _pSlideBitmap;
|
||||
_pSlideBitmap = nullptr;
|
||||
}
|
||||
if (_pViewPortBitmap) {
|
||||
delete _pViewPortBitmap;
|
||||
_pViewPortBitmap = nullptr;
|
||||
}
|
||||
|
||||
CBofSprite::closeLibrary(); // Free the off screen bitmap
|
||||
|
||||
delete _pFGObjectList;
|
||||
}
|
||||
|
||||
void CBagPanWindow::onClose() {
|
||||
CBagStorageDevWnd::onClose();
|
||||
|
||||
destroyWindow(); // Destruct the main window
|
||||
}
|
||||
|
||||
ErrorCode CBagPanWindow::runModal(CBagObject *pObj) {
|
||||
if (_pSlideBitmap != nullptr) {
|
||||
|
||||
_pSlideBitmap->updateView();
|
||||
CBagStorageDevWnd::runModal(pObj);
|
||||
|
||||
// Make sure we update the entire screen after this,
|
||||
// we're not really sure what got trashed, also,
|
||||
// the cursor background will contain bogus information,
|
||||
// so make sure that gets overwritten
|
||||
setPreFilterPan(true);
|
||||
}
|
||||
|
||||
return _errCode;
|
||||
}
|
||||
|
||||
ErrorCode CBagPanWindow::onRender(CBofBitmap *pBmp, CBofRect *pRect) {
|
||||
assert(isValidObject(this));
|
||||
assert(pBmp != nullptr);
|
||||
|
||||
if (_pSlideBitmap != nullptr) {
|
||||
_pSlideBitmap->updateView();
|
||||
|
||||
CBofRect dstRect(CBofPoint(0, 0), _pSlideBitmap->getViewSize());
|
||||
CBofRect clientArea = getClientRect();
|
||||
|
||||
if (_pSlideBitmap->isPan()) {
|
||||
|
||||
// Paint uncorrected view to backdrop
|
||||
CBofRect currViewRect = _pSlideBitmap->getCurrView(); // Hold current view
|
||||
CBofRect offsetRect; // Size of viewportbmp
|
||||
CBofRect srcRect = dstRect; // Src will be same as dst
|
||||
|
||||
// If we've been given the go ahead to call prefilter, then
|
||||
// do so but don't do it again unless asked.
|
||||
if (preFilterPan()) {
|
||||
preFilter(pBmp, pRect, _pFGObjectList);
|
||||
setPreFilterPan(false);
|
||||
}
|
||||
|
||||
_pSlideBitmap->paintUncorrected(_pViewPortBitmap, offsetRect); // Paint and return size
|
||||
srcRect.offsetRect(0, currViewRect.top - offsetRect.top); // less the offset from full
|
||||
|
||||
// Paint the objects to the backdrop
|
||||
paintObjects(getObjectList(), _pViewPortBitmap, offsetRect, nullptr);
|
||||
|
||||
dstRect.offsetRect(_xViewPortPos);
|
||||
|
||||
// No correction ?
|
||||
if (_nCorrection == 0) {
|
||||
_pViewPortBitmap->paint(pBmp, &dstRect, &srcRect);
|
||||
|
||||
} else {
|
||||
// Warp the backdrop to itself
|
||||
_pSlideBitmap->paintWarped(pBmp, dstRect, srcRect, 0, _pViewPortBitmap, offsetRect);
|
||||
}
|
||||
|
||||
if (isFiltered()) {
|
||||
uint16 nFilterId = getFilterId();
|
||||
(*_pBitmapFilter)(nFilterId, pBmp, pRect);
|
||||
}
|
||||
|
||||
|
||||
// Now paint it
|
||||
paintObjects(_pFGObjectList, pBmp, clientArea, nullptr, false);
|
||||
|
||||
} else {
|
||||
// Close-Ups
|
||||
_pSlideBitmap->setCorrWidth(0, false);
|
||||
|
||||
// If we've been given the go ahead to call prefilter, then
|
||||
// do so but don't do it again unless asked.
|
||||
if (preFilterPan()) {
|
||||
preFilter(pBmp, pRect, _pFGObjectList);
|
||||
setPreFilterPan(false);
|
||||
|
||||
// Only paint the slide the first time around, if we paint
|
||||
// it in subsequent calls, then we will trash our PDA in this closeup,
|
||||
// and that will be a bad thing.
|
||||
dstRect.offsetRect(_xViewPortPos);
|
||||
((CBofBitmap *)_pSlideBitmap)->paint(pBmp, _xViewPortPos.x, _xViewPortPos.y);
|
||||
}
|
||||
|
||||
clientArea.offsetRect(-_xViewPortPos.x, -_xViewPortPos.y);
|
||||
paintObjects(getObjectList(), pBmp, clientArea, nullptr);
|
||||
|
||||
if (isFiltered()) {
|
||||
uint16 nFilterId = getFilterId();
|
||||
bool bFiltered = (*_pBitmapFilter)(nFilterId, pBmp, pRect);
|
||||
|
||||
if (bFiltered) {
|
||||
setPreFilterPan(true);
|
||||
}
|
||||
}
|
||||
|
||||
// This must be changed so that the foreground objects are actually
|
||||
// a list of child windows. The on paint message is then called with
|
||||
// the background bitmap
|
||||
paintObjects(_pFGObjectList, pBmp, clientArea, nullptr);
|
||||
|
||||
_pSlideBitmap->setCorrWidth(_nCorrection, false);
|
||||
}
|
||||
}
|
||||
|
||||
return _errCode;
|
||||
}
|
||||
|
||||
ErrorCode CBagPanWindow::paintObjects(CBofList<CBagObject *> *list, CBofBitmap *pBmp, CBofRect &viewRect, CBofList<CBofRect> *pUpdateArea, bool tempVar) {
|
||||
ErrorCode errorCode = ERR_NONE;
|
||||
|
||||
// can't use a null pointer
|
||||
assert(pBmp != nullptr);
|
||||
|
||||
int nCount = list->getCount();
|
||||
if (nCount != 0) {
|
||||
int nW = _pSlideBitmap->width();
|
||||
CBofPoint xCursorLocation = devPtToViewPort(*_xCursorLocation);
|
||||
int nMouseOverObj = -1;
|
||||
|
||||
for (int i = 0; i < nCount; ++i) {
|
||||
CBagObject *pObj = list->getNodeItem(i);
|
||||
CBofRect xBmpRect = pObj->getRect();
|
||||
|
||||
// If it is a panorama we have to check for exceeded bounds
|
||||
if (!pObj->isForeGround() && (nW > 1024) && (viewRect.right > nW) && (xBmpRect.left < (nW / 2)))
|
||||
xBmpRect.offsetRect(nW, 0);
|
||||
|
||||
CBofRect xIntrRect;
|
||||
if (xIntrRect.intersectRect(&viewRect, &xBmpRect) || pObj->isForeGround() || pObj->isModal()) {
|
||||
CBofPoint pt = xBmpRect.topLeft();
|
||||
if (!pObj->isForeGround()) {
|
||||
pt = xBmpRect.topLeft() - viewRect.topLeft();
|
||||
}
|
||||
|
||||
xIntrRect = xBmpRect;
|
||||
xIntrRect.offsetRect(-xBmpRect.left, -xBmpRect.top);
|
||||
|
||||
// Only update dirty objects...
|
||||
if (pObj->isDirty() || pObj->isAlwaysUpdate()) {
|
||||
if (!(pObj->getType() == TEXT_OBJ && ((CBagTextObject *)pObj)->isCaption() && pObj->isImmediateRun())) {
|
||||
pObj->update(pBmp, pt, &xIntrRect);
|
||||
|
||||
// If we're in a closeup and we have a character animation
|
||||
// playing, then make sure we redraw
|
||||
CBagCharacterObject *pCharObj = (CBagCharacterObject *)pObj;
|
||||
|
||||
// Only in closeups
|
||||
if (!_pSlideBitmap->isPan() && pObj->getType() == CHAR_OBJ) {
|
||||
// Handle non-modal movies also...
|
||||
if (pCharObj->getNumberOfLoops() == 1) {
|
||||
setPreFilterPan(true);
|
||||
} else if (pObj->isAttached() && // don't care if it's not running...
|
||||
(pCharObj->isStationary() == false) &&
|
||||
(pCharObj->getNumberOfLoops() != 0) && // Plays multiple or infinite (fly == -1)
|
||||
((pObj->getRect().width() != 480) &&
|
||||
(pObj->getRect().height() != 360))) {
|
||||
|
||||
// Redraw everything inside of the closeup... but not the PDA...
|
||||
// only want to redraw the closeup, not everything else.
|
||||
//
|
||||
// if our prefilter pan is already dirty, then don't mess with dirty
|
||||
// object list.
|
||||
|
||||
bool b = preFilterPan();
|
||||
setPreFilterPan(true);
|
||||
|
||||
if (!b) {
|
||||
setDirtyAllObjects(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (pUpdateArea) {
|
||||
xIntrRect.offsetRect(pt);
|
||||
pUpdateArea->addToTail(xIntrRect);
|
||||
}
|
||||
|
||||
if (pObj->getRect().ptInRect(xCursorLocation)) {
|
||||
pObj->onMouseOver(0, xCursorLocation, this);
|
||||
nMouseOverObj = i;
|
||||
}
|
||||
} // if on screen
|
||||
|
||||
} // While a valid object
|
||||
|
||||
if ((nMouseOverObj < 0) && tempVar)
|
||||
noObjectsUnderMouse();
|
||||
}
|
||||
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
// Delete the foreground objects
|
||||
void CBagPanWindow::deleteFGObjects() {
|
||||
_pFGObjectList->removeAll();
|
||||
}
|
||||
|
||||
ErrorCode CBagPanWindow::insertFGObjects(CBagObject *pBmp) {
|
||||
// Can't use a nullptr pointer
|
||||
assert(pBmp != nullptr);
|
||||
|
||||
_pFGObjectList->addToTail(pBmp);
|
||||
|
||||
return _errCode;
|
||||
}
|
||||
|
||||
CBagObject *CBagPanWindow::getFGObjects(const CBofString &sObjName) {
|
||||
int nListLen = _pFGObjectList->getCount();
|
||||
|
||||
for (int i = 0; i < nListLen; ++i) {
|
||||
CBagObject *pObj = (*_pFGObjectList)[i];
|
||||
if ((pObj->getRefName().find(sObjName)) != -1)
|
||||
return pObj;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
void CBagPanWindow::activateView() {
|
||||
if (_pSlideBitmap) {
|
||||
_pSlideBitmap->activateScrolling();
|
||||
_pSlideBitmap->setRotateRate(CBofPoint(32, 16));
|
||||
}
|
||||
}
|
||||
|
||||
void CBagPanWindow::deActivateView() {
|
||||
if (_pSlideBitmap) {
|
||||
_pSlideBitmap->deActivateScrolling();
|
||||
}
|
||||
}
|
||||
|
||||
void CBagPanWindow::enable() {
|
||||
activateView();
|
||||
}
|
||||
|
||||
void CBagPanWindow::disable() {
|
||||
flushAllMessages();
|
||||
deActivateView();
|
||||
}
|
||||
|
||||
ErrorCode CBagPanWindow::onCursorUpdate(int nCurrObj) {
|
||||
assert(isValidObject(this));
|
||||
|
||||
if (nCurrObj >= 0) {
|
||||
CBagObject *pObj = getObjectByPos(nCurrObj);
|
||||
if (pObj != nullptr)
|
||||
CBagMasterWin::setActiveCursor(pObj->getOverCursor());
|
||||
|
||||
} else if (CBagWield::getWieldCursor() >= 0) {
|
||||
CBagMasterWin::setActiveCursor(CBagWield::getWieldCursor());
|
||||
}
|
||||
|
||||
return _errCode;
|
||||
}
|
||||
|
||||
void CBagPanWindow::onKeyHit(uint32 lKey, uint32 lRepCount) {
|
||||
assert(isValidObject(this));
|
||||
|
||||
if (_pSlideBitmap != nullptr) {
|
||||
switch (lKey) {
|
||||
case BKEY_MINUS:
|
||||
if (_nCorrection == 0) {
|
||||
_nCorrection = 64;
|
||||
}
|
||||
_nCorrection >>= 1;
|
||||
_pSlideBitmap->setCorrWidth(_nCorrection);
|
||||
CBagMasterWin::setCorrection(_nCorrection);
|
||||
break;
|
||||
|
||||
case BKEY_PLUS:
|
||||
if (_nCorrection == 0) {
|
||||
_nCorrection = 1;
|
||||
|
||||
} else if ((_nCorrection <<= 1) > 32) {
|
||||
_nCorrection = 0;
|
||||
}
|
||||
_pSlideBitmap->setCorrWidth(_nCorrection);
|
||||
CBagMasterWin::setCorrection(_nCorrection);
|
||||
break;
|
||||
|
||||
case BKEY_LEFT:
|
||||
_pSlideBitmap->setRotateRate(CBofPoint(16, 8));
|
||||
_pSlideBitmap->setDirection(CBagPanBitmap::kDirRIGHT);
|
||||
break;
|
||||
|
||||
case BKEY_RIGHT:
|
||||
_pSlideBitmap->setRotateRate(CBofPoint(16, 8));
|
||||
_pSlideBitmap->setDirection(CBagPanBitmap::kDirLEFT);
|
||||
break;
|
||||
|
||||
case BKEY_UP:
|
||||
_pSlideBitmap->setRotateRate(CBofPoint(16, 8));
|
||||
_pSlideBitmap->setDirection(CBagPanBitmap::kDirDOWN);
|
||||
break;
|
||||
|
||||
case BKEY_DOWN:
|
||||
_pSlideBitmap->setRotateRate(CBofPoint(16, 8));
|
||||
_pSlideBitmap->setDirection(CBagPanBitmap::kDirUP);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
CBagStorageDevWnd::onKeyHit(lKey, lRepCount);
|
||||
}
|
||||
|
||||
void CBagPanWindow::onMouseMove(uint32 nFlags, CBofPoint *p, void *) {
|
||||
assert(isValidObject(this));
|
||||
assert(p != nullptr);
|
||||
|
||||
CBofPoint xPoint = *p;
|
||||
|
||||
CBagStorageDevWnd::onMouseMove(nFlags, &xPoint);
|
||||
|
||||
if (!isCloseup()) {
|
||||
if (_pSlideBitmap != nullptr) {
|
||||
if (_cRightRect.ptInRect(xPoint)) {
|
||||
_pSlideBitmap->setRotateRate(CBofPoint(((xPoint.x - _xMovementRect.right) * (_nPanSpeed + 1)) / 2, 0));
|
||||
_pSlideBitmap->setDirection(CBagPanBitmap::kDirLEFT);
|
||||
CBagMasterWin::setActiveCursor(BOF_RT_CURSOR);
|
||||
|
||||
} else if (_cLeftRect.ptInRect(xPoint)) {
|
||||
_pSlideBitmap->setRotateRate(CBofPoint(((_xMovementRect.left - xPoint.x) * (_nPanSpeed + 1)) / 2, 0));
|
||||
_pSlideBitmap->setDirection(CBagPanBitmap::kDirRIGHT);
|
||||
CBagMasterWin::setActiveCursor(BOF_LT_CURSOR);
|
||||
|
||||
} else if (_cBottomRect.ptInRect(xPoint)) {
|
||||
_pSlideBitmap->setRotateRate(CBofPoint(0, (xPoint.y - _xMovementRect.bottom)));
|
||||
_pSlideBitmap->setDirection(CBagPanBitmap::kDirUP);
|
||||
CBagMasterWin::setActiveCursor(BOF_DN_CURSOR);
|
||||
|
||||
} else if (_cTopRect.ptInRect(xPoint)) {
|
||||
_pSlideBitmap->setRotateRate(CBofPoint(0, (_xMovementRect.top - xPoint.y)));
|
||||
_pSlideBitmap->setDirection(CBagPanBitmap::kDirDOWN);
|
||||
CBagMasterWin::setActiveCursor(BOF_UP_CURSOR);
|
||||
|
||||
} else {
|
||||
_pSlideBitmap->setDirection(CBagPanBitmap::kDirNONE);
|
||||
}
|
||||
|
||||
if (getLActiveObject() && getLActivity()) {
|
||||
_pSlideBitmap->setDirection((CBagPanBitmap::Direction)(_pSlideBitmap->getDirection() | CBagPanBitmap::kDirVIEW));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Change cursor based on the Foreground object list
|
||||
// Run through background object list and find if the cursor is over an object
|
||||
CBofList<CBagObject *> *pList = _pFGObjectList;
|
||||
if (pList != nullptr) {
|
||||
CBagObject *pOverObj = nullptr;
|
||||
int nCount = pList->getCount();
|
||||
for (int i = 0; i < nCount; ++i) {
|
||||
CBagObject *pObj = pList->getNodeItem(i);
|
||||
|
||||
if (pObj->isInside(xPoint)) {
|
||||
pOverObj = pObj;
|
||||
}
|
||||
}
|
||||
|
||||
// If we just happen to be over the pda then let our
|
||||
// PDA code decide... oh, and we're wielding...
|
||||
if (pOverObj != nullptr) {
|
||||
int nCursorID = -1;
|
||||
|
||||
// the logz case is handled by onmousemove in zoompda
|
||||
if (pOverObj->getRefName().find("BPDA_WLD") != -1) {
|
||||
CBagPDA *pPda = (CBagPDA *)g_SDevManager->getStorageDevice(pOverObj->getRefName());
|
||||
if (pPda != nullptr) {
|
||||
CBofRect cRect = pOverObj->getRect();
|
||||
nCursorID = pPda->getProperCursor(xPoint, cRect);
|
||||
}
|
||||
}
|
||||
|
||||
// Still no luck, if we're wielding, use that cursor.
|
||||
if (nCursorID == -1) {
|
||||
nCursorID = pOverObj->getOverCursor();
|
||||
if (CBagWield::getWieldCursor() >= 0 && ((pOverObj->getRefName().find("BWIELD_WLD") != -1) || (pOverObj->getRefName().find("THUD_WLD") != -1))) {
|
||||
nCursorID = CBagWield::getWieldCursor();
|
||||
}
|
||||
}
|
||||
|
||||
CBagMasterWin::setActiveCursor(nCursorID);
|
||||
}
|
||||
}
|
||||
|
||||
if (_bDraggingObject) {
|
||||
CBagObject *pObj = _pFGObjectList->getNodeItem(_pFGObjectList->getCount() - 1);
|
||||
pObj->setPosition(xPoint);
|
||||
}
|
||||
|
||||
*_xCursorLocation = xPoint;
|
||||
}
|
||||
|
||||
void CBagPanWindow::onLButtonDown(uint32 nFlags, CBofPoint *xPoint, void *) {
|
||||
int nCount = _pFGObjectList->getCount();
|
||||
if (nCount != 0) {
|
||||
for (int i = 0; i < nCount; ++i) {
|
||||
CBagObject *pObj = _pFGObjectList->getNodeItem(i);
|
||||
|
||||
if (pObj->isInside(*xPoint)) {
|
||||
pObj->onLButtonDown(nFlags, xPoint, this);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
CBagStorageDevWnd::onLButtonDown(nFlags, xPoint);
|
||||
|
||||
MouseActivity nMA = getLActivity();
|
||||
CBagObject *pActObj = getLActiveObject();
|
||||
|
||||
if (nMA && pActObj && pActObj->isMovable()) {
|
||||
_bDraggingObject = true;
|
||||
_bDraggingStart = pActObj->getPosition();
|
||||
_pFGObjectList->addToTail(pActObj);
|
||||
}
|
||||
}
|
||||
|
||||
void CBagPanWindow::onLButtonUp(uint32 nFlags, CBofPoint *xPoint, void *) {
|
||||
MouseActivity nMA = getLActivity();
|
||||
CBagObject *pActObj = getLActiveObject();
|
||||
|
||||
if ((pActObj != nullptr) && (nMA == kMouseDRAGGING) &&
|
||||
(pActObj->getType() == BUTTON_OBJ) &&
|
||||
(((CBagButtonObject *)pActObj)->getButtonType() == CBagButtonObject::BTN_SLIDER)) {
|
||||
pActObj->onLButtonUp(nFlags, xPoint, this);
|
||||
|
||||
// We are not dragging a slider anymore
|
||||
setLActivity(kMouseNONE);
|
||||
setLActiveObject(nullptr);
|
||||
|
||||
} else {
|
||||
bool bMoved = false;
|
||||
|
||||
if (_bDraggingObject) {
|
||||
_bDraggingObject = false;
|
||||
pActObj = _pFGObjectList->removeTail();
|
||||
|
||||
int nCount = _pFGObjectList->getCount();
|
||||
if (nCount != 0) {
|
||||
for (int i = 0; i < nCount; ++i) {
|
||||
CBagObject *pObj = _pFGObjectList->getNodeItem(i);
|
||||
CBofRect xBmpRect = pObj->getRect();
|
||||
if (xBmpRect.ptInRect(*xPoint)) {
|
||||
pObj->onObjInteraction(pActObj, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (pActObj->getPosition() != _bDraggingStart) {
|
||||
pActObj->setPosition(_bDraggingStart);
|
||||
bMoved = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!bMoved) {
|
||||
// Parse backwards to get topmost obj 1st
|
||||
int nCount = _pFGObjectList->getCount();
|
||||
if (nCount != 0) {
|
||||
for (int i = nCount - 1; i >= 0; --i) {
|
||||
CBagObject *pObj = _pFGObjectList->getNodeItem(i);
|
||||
if (pObj->isInside(*xPoint)) {
|
||||
pObj->onLButtonUp(nFlags, xPoint, this);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CBagStorageDevWnd::onLButtonUp(nFlags, xPoint);
|
||||
}
|
||||
}
|
||||
|
||||
void CBagPanWindow::onSize(uint32 nType, int cx, int cy) {
|
||||
// nRange defines the distance (in pixels) from a viewport edge
|
||||
// (toward the center of the viewport) that the viewport boundary
|
||||
// rectangles begin. The boundary rectangles surround the edges
|
||||
// of the viewport. When the mouse cursor enters a boundary rectangle,
|
||||
// it's time to pan the view. Larger positive values of nRange will
|
||||
// cause the boundary rectangle to extend farther from the viewport edge.
|
||||
// A value of zero will cause the boundary rectangles to be at the edge
|
||||
// of the viewport. If nRange has a negative value, the boundary
|
||||
// rectangle will start outside the viewport rectangle.
|
||||
//
|
||||
const int nRange = 16;
|
||||
CBofRect xMaxPanBmpRect;
|
||||
|
||||
if (_pSlideBitmap)
|
||||
xMaxPanBmpRect = _pSlideBitmap->getMaxView();
|
||||
else
|
||||
xMaxPanBmpRect.setRect(0, 0, DEF_WIDTH, DEF_HEIGHT);
|
||||
|
||||
CBofPoint vp;
|
||||
CBofSize vs = CBofSize(cx, cy);
|
||||
|
||||
// Check if the current view is greater than the max view
|
||||
if (vs.cx > xMaxPanBmpRect.width())
|
||||
vs.cx = xMaxPanBmpRect.width();
|
||||
|
||||
if (_pSlideBitmap && _pSlideBitmap->width() > 480)
|
||||
vs.cy = 3 * vs.cx / 4;
|
||||
|
||||
if (vs.cy > xMaxPanBmpRect.height())
|
||||
vs.cy = xMaxPanBmpRect.height();
|
||||
|
||||
setViewPortSize(vs);
|
||||
|
||||
vp.x = (cx - vs.cx) / 2;
|
||||
vp.y = 10;
|
||||
|
||||
setViewPortPos(vp);
|
||||
|
||||
vp.x += nRange;
|
||||
vp.y += nRange;
|
||||
vs.cx -= (2 * nRange); // Subtract 2*nRange from vs because there's
|
||||
vs.cy -= (2 * nRange); // a boundary rectangle on the left and right
|
||||
// *and* the top and bottom.
|
||||
|
||||
CBofRect cRect(vp, vs);
|
||||
|
||||
_cTopRect.setRect(cRect.left, 0, cRect.right, cRect.top);
|
||||
_cBottomRect.setRect(cRect.left, cRect.bottom, cRect.right, 480 - 1);
|
||||
_cLeftRect.setRect(0, cRect.top, cRect.left, cRect.bottom);
|
||||
_cRightRect.setRect(cRect.right, cRect.top, 640 - 1, cRect.bottom);
|
||||
|
||||
setMovementRect(cRect);
|
||||
}
|
||||
|
||||
|
||||
void CBagPanWindow::OnWindowPosChanging(WindowPos *lpwndpos) {
|
||||
const int MENUNBORDER = 50;
|
||||
CBofRect xSlideBmpRect;
|
||||
|
||||
xSlideBmpRect.setRect(0, 0, DEF_WIDTH, DEF_HEIGHT);
|
||||
|
||||
if (lpwndpos->cx > xSlideBmpRect.width())
|
||||
lpwndpos->cx = xSlideBmpRect.width();
|
||||
if (lpwndpos->cy > xSlideBmpRect.height() + MENUNBORDER)
|
||||
lpwndpos->cy = xSlideBmpRect.height() + MENUNBORDER;
|
||||
}
|
||||
|
||||
void CBagPanWindow::flushInputEvents() {
|
||||
g_system->getEventManager()->purgeKeyboardEvents();
|
||||
g_system->getEventManager()->purgeMouseEvents();
|
||||
}
|
||||
|
||||
#define PAN_WIDTH 2048
|
||||
#define PAN_HEIGHT 512
|
||||
|
||||
#define HALF_PAN_WIDTH (PAN_WIDTH/2)
|
||||
|
||||
uint32 CBagPanWindow::rotateTo(CBofPoint &xPoint, int nRate) {
|
||||
assert(nRate > 0);
|
||||
|
||||
if (_pSlideBitmap && (xPoint.x != -1) && (xPoint.y != -1)) {
|
||||
CBofRect r = _pSlideBitmap->getCurrView();
|
||||
|
||||
for (;;) {
|
||||
CBofPoint xCurrPos = r.topLeft();
|
||||
int x = (xPoint.x - xCurrPos.x);
|
||||
int y = (xPoint.y - xCurrPos.y);
|
||||
|
||||
if (abs(x) > HALF_PAN_WIDTH) {
|
||||
if (x > 0) {
|
||||
x -= PAN_WIDTH;
|
||||
} else {
|
||||
x += PAN_WIDTH;
|
||||
}
|
||||
}
|
||||
|
||||
// Are we there yet?
|
||||
if (x == 0 && y == 0)
|
||||
break;
|
||||
|
||||
int nRateX = MIN(x, nRate);
|
||||
if (x < 0)
|
||||
nRateX = MAX(x, -nRate);
|
||||
|
||||
int nRateY = MIN(y, nRate);
|
||||
if (y < 0)
|
||||
nRateY = MAX(y, -nRate);
|
||||
|
||||
r.offsetRect(nRateX, nRateY);
|
||||
|
||||
_pSlideBitmap->setCurrView(r);
|
||||
paintScreen();
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
uint32 CBagPanWindow::benchmark() {
|
||||
deActivateView();
|
||||
_pSlideBitmap->activateScrolling();
|
||||
|
||||
_pSlideBitmap->setRotateRate(CBofPoint(8, 0));
|
||||
_pSlideBitmap->setDirection(CBagPanBitmap::kDirLEFT);
|
||||
|
||||
timerStart();
|
||||
for (int i = 0; i < 50; i++)
|
||||
paintScreen();
|
||||
uint32 dTime = timerStop();
|
||||
|
||||
activateView();
|
||||
return dTime;
|
||||
}
|
||||
|
||||
bool CBagPanWindow::deactivatePDA() {
|
||||
// If we have a PDA and the pda is active
|
||||
if (_pPDABmp && _pPDABmp->isActivated()) {
|
||||
// deactivate it
|
||||
_pPDABmp->deactivate();
|
||||
|
||||
// PDA successfully deactivated
|
||||
return true;
|
||||
}
|
||||
|
||||
// PDA already deactivated
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CBagPanWindow::activatePDA() {
|
||||
// If we have a BMP and the pda is not active
|
||||
if (_pPDABmp && (!_pPDABmp->isActivated() || _pPDABmp->isActivating())) {
|
||||
_pPDABmp->activate(); // activate it
|
||||
|
||||
// PDA successfully activated
|
||||
return true;
|
||||
}
|
||||
|
||||
// PDA already activated
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
const CBofPoint CBagPanWindow::devPtToViewPort(const CBofPoint &xPoint) {
|
||||
CBofRect r = _pSlideBitmap->getCurrView();
|
||||
|
||||
CBofPoint p;
|
||||
p.x = xPoint.x + r.left - _xViewPortPos.x;
|
||||
p.y = xPoint.y + r.top - _xViewPortPos.y;
|
||||
|
||||
if (_pSlideBitmap->isPan()) {
|
||||
if (p.x >= _pSlideBitmap->width())
|
||||
p.x -= _pSlideBitmap->width();
|
||||
|
||||
// If this view is being painted with a correction, we need
|
||||
// to correct the point to the warped view space.
|
||||
if (_nCorrection != 0) {
|
||||
p = _pSlideBitmap->warpedPoint(p);
|
||||
}
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
const CBofPoint CBagPanWindow::viewPortToDevPt(const CBofPoint &xPoint) {
|
||||
CBofRect r = _pSlideBitmap->getCurrView();
|
||||
CBofPoint p(xPoint.x - r.left, xPoint.y - r.top);
|
||||
|
||||
if (p.x < 0)
|
||||
p.x += _pSlideBitmap->width();
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
ErrorCode CBagPanWindow::attachActiveObjects() {
|
||||
CBagStorageDev::attachActiveObjects();
|
||||
|
||||
if (_pPDABmp != nullptr) {
|
||||
_pPDABmp->attachActiveObjects();
|
||||
}
|
||||
|
||||
return _errCode;
|
||||
}
|
||||
|
||||
void CBagPanWindow::setViewPortSize(const CBofSize &xViewSize) {
|
||||
if (_pSlideBitmap)
|
||||
_pSlideBitmap->setViewSize(xViewSize);
|
||||
}
|
||||
|
||||
const CBofRect CBagPanWindow::getViewPort() {
|
||||
CBofRect r;
|
||||
if (_pSlideBitmap)
|
||||
r = _pSlideBitmap->getCurrView();
|
||||
return r;
|
||||
}
|
||||
|
||||
const CBofSize CBagPanWindow::getViewPortSize() {
|
||||
CBofRect r;
|
||||
if (_pSlideBitmap)
|
||||
r = _pSlideBitmap->getCurrView();
|
||||
return r.size();
|
||||
}
|
||||
|
||||
void CBagPanWindow::waitForPDA() {
|
||||
// Make sure we have a non-null pda
|
||||
while (_pPDABmp && _pPDABmp->isActivating()) {
|
||||
setPreFilterPan(true);
|
||||
_pPDABmp->setDirty(true);
|
||||
paintScreen();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
220
engines/bagel/spacebar/baglib/pan_window.h
Normal file
220
engines/bagel/spacebar/baglib/pan_window.h
Normal file
@@ -0,0 +1,220 @@
|
||||
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BAGEL_BAGLIB_PAN_WINDOW_H
|
||||
#define BAGEL_BAGLIB_PAN_WINDOW_H
|
||||
|
||||
#include "bagel/spacebar/baglib/pda.h"
|
||||
#include "bagel/spacebar/baglib/storage_dev_win.h"
|
||||
#include "bagel/spacebar/baglib/wield.h"
|
||||
#include "bagel/spacebar/baglib/pan_bitmap.h"
|
||||
#include "bagel/boflib/stdinc.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
#define BOFCURS 1
|
||||
|
||||
#define DEF_WIDTH 639
|
||||
#define DEF_HEIGHT 479
|
||||
|
||||
#define EVAL_EXPR 303
|
||||
|
||||
// The height and width of the pan area
|
||||
#define PAN_AREA_WIDTH 480
|
||||
#define PAN_AREA_HEIGHT 360
|
||||
|
||||
//
|
||||
// CBagPanWindow -
|
||||
// CBagPanWindow is a window that contains a slide bitmap object. It has specialize
|
||||
// functions for handling slide bitmaps and slide objects.
|
||||
//
|
||||
class CBagPanWindow : public CBagStorageDevWnd {
|
||||
private:
|
||||
static int _nCorrection;
|
||||
static int _nPanSpeed;
|
||||
|
||||
//
|
||||
// private data members
|
||||
//
|
||||
CBofPoint _xViewPortPos; // Position of the viewport
|
||||
CBofRect _xMovementRect; // if mouse is in this region will not scroll
|
||||
CBofRect _cLeftRect;
|
||||
CBofRect _cRightRect;
|
||||
CBofRect _cTopRect;
|
||||
CBofRect _cBottomRect;
|
||||
|
||||
CBagPanBitmap *_pSlideBitmap; // Contains the full bitmap of the world
|
||||
CBofBitmap *_pViewPortBitmap; // Contains the current viewport bitmap
|
||||
CBofPalette *_pPalette;
|
||||
|
||||
CBofPoint _bDraggingStart; // Starting location of the dragged object
|
||||
bool _bDraggingObject; // Whether or not the first FG object is being dragged
|
||||
|
||||
bool _bStretchToScreen; // Whether or not the backdrop is painted full screen
|
||||
bool _bPaintToBackdrop; // Whether or not the backdrop is a extra paint surface
|
||||
|
||||
CBofList<CBagObject *> *_pFGObjectList; // Objects to be painted to the window
|
||||
|
||||
public:
|
||||
static CBagWield *_pWieldBmp; // Pointer to the WIELD object
|
||||
|
||||
CBagPanWindow();
|
||||
virtual ~CBagPanWindow();
|
||||
static void initialize();
|
||||
|
||||
ErrorCode attachActiveObjects() override;
|
||||
|
||||
ErrorCode onRender(CBofBitmap *pBmp, CBofRect *pRect = nullptr) override;
|
||||
|
||||
/**
|
||||
* The modal object is painted to the screen until it is done with
|
||||
* its modal loop. This is mainly used with characters. It is called
|
||||
* when the loop value of a modal character is set, before execution
|
||||
* of the next line of script.
|
||||
*/
|
||||
ErrorCode runModal(CBagObject *pObj) override;
|
||||
|
||||
ErrorCode insertFGObjects(CBagObject *pBmp);
|
||||
void deleteFGObjects();
|
||||
CBagObject *getFGObjects(const CBofString &sObjName);
|
||||
|
||||
CBofPalette *setSlideBitmap(const CBofString &xSlideBmp, const CBofRect &xSlideRect = CBofRect(0, 0, 0, 0));
|
||||
|
||||
/**
|
||||
* Clear the last pan bitmaps and return a rect of the current view
|
||||
*/
|
||||
CBofRect unSetSlideBitmap();
|
||||
|
||||
uint32 rotateTo(CBofPoint &xPoint, int nRate = 8);
|
||||
|
||||
void activateView();
|
||||
void deActivateView();
|
||||
|
||||
void enable() override;
|
||||
void disable() override;
|
||||
|
||||
ErrorCode paintObjects(CBofList<CBagObject *> *list, CBofBitmap *pBmp, CBofRect &viewOffsetRect,
|
||||
CBofList<CBofRect> * = nullptr, bool tempVar = true) override;
|
||||
|
||||
const CBofPoint devPtToViewPort(const CBofPoint &xPoint) override;
|
||||
const CBofPoint viewPortToDevPt(const CBofPoint &xPoint) override;
|
||||
|
||||
void setViewPortSize(const CBofSize &xViewSize);
|
||||
const CBofRect getViewPort();
|
||||
const CBofSize getViewPortSize();
|
||||
|
||||
CBagPanBitmap *getSlideBitmap() const {
|
||||
return _pSlideBitmap;
|
||||
}
|
||||
void setViewPortPos(const CBofPoint &pos) {
|
||||
_xViewPortPos = pos; // Position of the viewport
|
||||
}
|
||||
|
||||
static void setPanSpeed(int nSpeed) {
|
||||
_nPanSpeed = nSpeed;
|
||||
}
|
||||
static int getPanSpeed() {
|
||||
return _nPanSpeed;
|
||||
}
|
||||
|
||||
const CBofPoint getViewPortPos() {
|
||||
return _xViewPortPos;
|
||||
}
|
||||
|
||||
const CBofRect getMaxView() {
|
||||
return _pSlideBitmap->getMaxView();
|
||||
}
|
||||
void setMovementRect(const CBofRect &rect) {
|
||||
_xMovementRect = rect;
|
||||
}
|
||||
const CBofRect &getMovementRect() {
|
||||
return _xMovementRect;
|
||||
}
|
||||
void setPaintToBackdrop(const bool bPaint) {
|
||||
_bPaintToBackdrop = bPaint;
|
||||
}
|
||||
bool getStretchToScreen() {
|
||||
return _bStretchToScreen;
|
||||
}
|
||||
bool setStretchToScreen(bool val = true) {
|
||||
return _bStretchToScreen = val;
|
||||
}
|
||||
static int getRealCorrection() {
|
||||
return _nCorrection;
|
||||
}
|
||||
static void setRealCorrection(int n) {
|
||||
_nCorrection = n;
|
||||
}
|
||||
int getCorrection() {
|
||||
return _pSlideBitmap->getCorrWidth();
|
||||
}
|
||||
void setCorrection(int nCorr) {
|
||||
_pSlideBitmap->setCorrWidth(nCorr);
|
||||
}
|
||||
double getFOV() {
|
||||
return _pSlideBitmap->getFOV();
|
||||
}
|
||||
void setFOV(double fov) {
|
||||
_pSlideBitmap->setFOV(fov);
|
||||
}
|
||||
|
||||
CBofPalette *getPalette() {
|
||||
return _pSlideBitmap->getPalette();
|
||||
}
|
||||
|
||||
uint32 benchmark();
|
||||
|
||||
public:
|
||||
static void flushInputEvents();
|
||||
|
||||
void onClose() override;
|
||||
void onMouseMove(uint32 nFlags, CBofPoint *p, void * = nullptr) override;
|
||||
void onLButtonDown(uint32 nFlags, CBofPoint *point, void * = nullptr) override;
|
||||
void onLButtonUp(uint32 nFlags, CBofPoint *point, void * = nullptr) override;
|
||||
void onKeyHit(uint32 lKey, uint32 lRepCount) override;
|
||||
virtual void onSize(uint32 nType, int cx, int cy);
|
||||
void OnWindowPosChanging(WindowPos *lpwndpos);
|
||||
|
||||
ErrorCode onCursorUpdate(int nCurrObj) override;
|
||||
|
||||
static CBagPDA *_pPDABmp; // Pointer to the PDA object
|
||||
|
||||
/**
|
||||
* Deactivate the PDA by calling the PDA->deactivate() directly.
|
||||
* This is called from the PDA ON/OFF button
|
||||
*/
|
||||
bool deactivatePDA();
|
||||
|
||||
/**
|
||||
* Activate the PDA by calling the PDA->deactivate() directly.
|
||||
* This is called on a mouse down anywhere on the deactivated PDA.
|
||||
*/
|
||||
bool activatePDA();
|
||||
|
||||
void waitForPDA();
|
||||
};
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
|
||||
#endif
|
||||
246
engines/bagel/spacebar/baglib/parse_object.cpp
Normal file
246
engines/bagel/spacebar/baglib/parse_object.cpp
Normal file
@@ -0,0 +1,246 @@
|
||||
/* 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/parse_object.h"
|
||||
#include "bagel/spacebar/boflib/app.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
void CBagParseObject::initialize() {
|
||||
}
|
||||
|
||||
CBagParseObject::CBagParseObject() {
|
||||
_bAttached = false;
|
||||
}
|
||||
|
||||
int CBagParseObject::getIntFromStream(CBagIfstream &istr, int &nNum) {
|
||||
char ch;
|
||||
char szLocalStr[256];
|
||||
int i = 0;
|
||||
|
||||
while (Common::isDigit(ch = (char)istr.peek())) {
|
||||
ch = (char)istr.getCh();
|
||||
szLocalStr[i++] = ch;
|
||||
assert(i < 256);
|
||||
}
|
||||
|
||||
szLocalStr[i] = 0;
|
||||
nNum = atoi(szLocalStr);
|
||||
|
||||
return ch;
|
||||
}
|
||||
|
||||
int CBagParseObject::getStringFromStream(CBagIfstream &istr, CBofString &sStr, const CBofString &sEndChars, bool bPutBack) {
|
||||
bool bDone = false;
|
||||
char ch = 0;
|
||||
|
||||
sStr = "";
|
||||
|
||||
do {
|
||||
if (istr.eof())
|
||||
bDone = true;
|
||||
else
|
||||
ch = (char)istr.getCh();
|
||||
for (int i = 0; !bDone && i < sEndChars.getLength(); ++i) {
|
||||
if (sEndChars[i] == ch)
|
||||
bDone = true;
|
||||
}
|
||||
if (!bDone)
|
||||
sStr += ch;
|
||||
} while (!bDone);
|
||||
|
||||
if (bPutBack)
|
||||
istr.putBack();
|
||||
|
||||
return ch;
|
||||
}
|
||||
|
||||
int CBagParseObject::getRectFromStream(CBagIfstream &istr, CBofRect &rect) {
|
||||
char szLocalStr[256];
|
||||
szLocalStr[0] = 0;
|
||||
CBofString str(szLocalStr, 256);
|
||||
|
||||
// The first char must be a [
|
||||
char ch = (char)istr.getCh();
|
||||
if (ch != '[')
|
||||
return -1;
|
||||
|
||||
// Get the left-coord
|
||||
getStringFromStream(istr, str, ",");
|
||||
rect.left = atoi(str);
|
||||
|
||||
// Get the top-coord
|
||||
getStringFromStream(istr, str, "],", true);
|
||||
rect.top = atoi(str);
|
||||
|
||||
// If ',' then get the size coords
|
||||
ch = (char)istr.getCh();
|
||||
if (ch == ',') {
|
||||
// Get the right-coord (optional)
|
||||
getStringFromStream(istr, str, ",");
|
||||
rect.right = atoi(str);
|
||||
|
||||
// Get the bottom-coord (optional)
|
||||
getStringFromStream(istr, str, "]");
|
||||
rect.bottom = atoi(str);
|
||||
} else {
|
||||
rect.right = rect.left - 1;
|
||||
rect.bottom = rect.top - 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CBagParseObject::getAlphaNumFromStream(CBagIfstream &istr, CBofString &sStr) {
|
||||
bool bDone = false;
|
||||
char ch = 0;
|
||||
|
||||
sStr = "";
|
||||
|
||||
istr.eatWhite();
|
||||
|
||||
do {
|
||||
if (istr.eof())
|
||||
bDone = true;
|
||||
else
|
||||
ch = (char)istr.getCh();
|
||||
|
||||
if (Common::isAlnum(ch) || ch == '_' || ch == '-' || ch == '\\' || ch == '/' || ch == '.' || ch == ':' || ch == '$' || ch == 39 || ch == '~') {
|
||||
sStr += ch;
|
||||
} else {
|
||||
bDone = true;
|
||||
}
|
||||
|
||||
} while (!bDone);
|
||||
|
||||
istr.putBack();
|
||||
|
||||
return ch;
|
||||
}
|
||||
|
||||
int CBagParseObject::getOperStrFromStream(CBagIfstream &istr, CBofString &sStr) {
|
||||
bool bDone = false;
|
||||
char ch = 0;
|
||||
|
||||
sStr = "";
|
||||
|
||||
istr.eatWhite();
|
||||
|
||||
do {
|
||||
if (istr.eof())
|
||||
bDone = true;
|
||||
else
|
||||
ch = (char)istr.getCh();
|
||||
if (Common::isPunct(ch))
|
||||
sStr += ch;
|
||||
else
|
||||
bDone = true;
|
||||
} while (!bDone);
|
||||
|
||||
istr.putBack();
|
||||
|
||||
return ch;
|
||||
}
|
||||
|
||||
int CBagParseObject::getKeywordFromStream(CBagIfstream &istr, CBagParseObject::KEYWORDS &keyword) {
|
||||
keyword = CBagParseObject::UNKNOWN;
|
||||
char szLocalStr[256];
|
||||
szLocalStr[0] = 0;
|
||||
CBofString sStr(szLocalStr, 256);
|
||||
|
||||
int rc = getAlphaNumFromStream(istr, sStr);
|
||||
|
||||
if (!sStr.find("SDEV")) {
|
||||
keyword = CBagParseObject::STORAGEDEV;
|
||||
|
||||
} else if (!sStr.find("START_WLD")) {
|
||||
keyword = CBagParseObject::START_WLD;
|
||||
|
||||
} else if (!sStr.find("VAR")) {
|
||||
keyword = CBagParseObject::VARIABLE;
|
||||
|
||||
} else if (!sStr.find("DISKAUDIO")) {
|
||||
// Specify the audio that get's played when user is asked to insert another CD.
|
||||
keyword = CBagParseObject::DISKAUDIO;
|
||||
|
||||
} else if (!sStr.find("SYSSCREEN")) {
|
||||
keyword = CBagParseObject::SYSSCREEN;
|
||||
|
||||
} else if (!sStr.find("DISKID")) {
|
||||
keyword = CBagParseObject::DISKID;
|
||||
|
||||
} else if (!sStr.find("SHAREDPAL")) {
|
||||
keyword = CBagParseObject::SHAREDPAL; // Allow shared palette at front of script
|
||||
|
||||
} else if (!sStr.find("PDASTATE")) {
|
||||
keyword = CBagParseObject::PDASTATE; // allow shared palette at front of script
|
||||
|
||||
} else if (!sStr.find("CURSOR")) {
|
||||
keyword = CBagParseObject::CURSOR;
|
||||
|
||||
} else if (!sStr.find("WIELDCURSOR")) {
|
||||
keyword = CBagParseObject::WIELDCURSOR;
|
||||
|
||||
} else if (!sStr.find("REM") || !sStr.find("//")) {
|
||||
keyword = CBagParseObject::REMARK;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int CBagParseObject::putbackStringOnStream(CBagIfstream &istr, const CBofString &sStr) {
|
||||
int nLen = sStr.getLength();
|
||||
|
||||
while (nLen > 0) {
|
||||
--nLen;
|
||||
istr.putBack();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CBagParseObject::parseAlertBox(CBagIfstream &istr, const char *sTitle, const char *sFile, int nLine) {
|
||||
char str[256];
|
||||
|
||||
CBofString s = sFile;
|
||||
|
||||
Common::String tmp = Common::String::format("(%d)@%d", nLine, istr.getLineNumber());
|
||||
|
||||
s += tmp.c_str();
|
||||
|
||||
s += ":";
|
||||
s += istr.getLineString();
|
||||
|
||||
istr.getLine(str, 255);
|
||||
s += str;
|
||||
istr.getLine(str, 255);
|
||||
s += str;
|
||||
istr.getLine(str, 255);
|
||||
s += str;
|
||||
|
||||
bofMessageBox(s, sTitle);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
104
engines/bagel/spacebar/baglib/parse_object.h
Normal file
104
engines/bagel/spacebar/baglib/parse_object.h
Normal file
@@ -0,0 +1,104 @@
|
||||
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BAGEL_BAGLIB_PARSE_OBJECT_H
|
||||
#define BAGEL_BAGLIB_PARSE_OBJECT_H
|
||||
|
||||
#include "bagel/spacebar/baglib/ifstream.h"
|
||||
#include "bagel/boflib/error.h"
|
||||
#include "bagel/boflib/rect.h"
|
||||
#include "bagel/boflib/string.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
#define RECT_START_DELIM '['
|
||||
#define RECT_END_DELIM ']'
|
||||
#define RECT_VAR_DELIM ','
|
||||
|
||||
#define SDEV_START_DELIM '{'
|
||||
#define SDEV_END_DELIM '}'
|
||||
|
||||
#define OBJ_START_DELIM '='
|
||||
#define OBJ_END_DELIM ';'
|
||||
|
||||
enum ParseCodes {
|
||||
PARSING_DONE = 0, UPDATED_OBJECT, UNKNOWN_TOKEN
|
||||
};
|
||||
|
||||
class CBagParseObject {
|
||||
public:
|
||||
enum KEYWORDS {
|
||||
UNKNOWN = 0,
|
||||
STORAGEDEV,
|
||||
START_WLD,
|
||||
VARIABLE,
|
||||
REMARK,
|
||||
DISKID,
|
||||
CURSOR,
|
||||
SHAREDPAL,
|
||||
DISKAUDIO,
|
||||
PDASTATE,
|
||||
SYSSCREEN,
|
||||
WIELDCURSOR
|
||||
};
|
||||
|
||||
private:
|
||||
bool _bAttached;
|
||||
|
||||
public:
|
||||
CBagParseObject();
|
||||
virtual ~CBagParseObject() {
|
||||
}
|
||||
static void initialize();
|
||||
|
||||
virtual ErrorCode attach() {
|
||||
_bAttached = true;
|
||||
return ERR_NONE;
|
||||
}
|
||||
virtual ErrorCode detach() {
|
||||
_bAttached = false;
|
||||
return ERR_NONE;
|
||||
}
|
||||
virtual bool isAttached() {
|
||||
return _bAttached;
|
||||
}
|
||||
|
||||
virtual ParseCodes setInfo(CBagIfstream &) {
|
||||
return PARSING_DONE;
|
||||
}
|
||||
|
||||
int getStringFromStream(CBagIfstream &istr, CBofString &sStr, const CBofString &sEndChars, bool bPutBack = false);
|
||||
int getAlphaNumFromStream(CBagIfstream &istr, CBofString &sStr);
|
||||
int getOperStrFromStream(CBagIfstream &istr, CBofString &sStr);
|
||||
int getIntFromStream(CBagIfstream &istr, int &nNum);
|
||||
int getRectFromStream(CBagIfstream &istr, CBofRect &rect);
|
||||
int getKeywordFromStream(CBagIfstream &istr, KEYWORDS &keyword);
|
||||
int putbackStringOnStream(CBagIfstream &istr, const CBofString &sStr);
|
||||
|
||||
int parseAlertBox(CBagIfstream &istr, const char *sTitle, const char *sFile, int nLine);
|
||||
};
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
|
||||
#endif
|
||||
569
engines/bagel/spacebar/baglib/pda.cpp
Normal file
569
engines/bagel/spacebar/baglib/pda.cpp
Normal file
@@ -0,0 +1,569 @@
|
||||
/* 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/pda.h"
|
||||
#include "bagel/spacebar/baglib/pan_window.h"
|
||||
#include "bagel/boflib/sound.h"
|
||||
#include "bagel/spacebar/baglib/master_win.h"
|
||||
#include "bagel/spacebar/baglib/button_object.h"
|
||||
#include "bagel/spacebar/baglib/character_object.h"
|
||||
#include "bagel/spacebar/baglib/time_object.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
bool CBagPDA::_flashingFl;
|
||||
bool CBagPDA::_soundsPausedFl;
|
||||
CBofList<CBagMovieObject *> *CBagPDA::_movieList;
|
||||
|
||||
extern bool g_allowattachActiveObjectsFl;
|
||||
static bool g_bAutoUpdate;
|
||||
|
||||
void CBagPDA::initialize() {
|
||||
_flashingFl = false;
|
||||
_soundsPausedFl = false;
|
||||
_movieList = nullptr;
|
||||
|
||||
g_bAutoUpdate = false;
|
||||
}
|
||||
|
||||
CBagPDA::CBagPDA(CBofWindow *pParent, const CBofRect &xRect, bool bActivated)
|
||||
: CBagStorageDevBmp(pParent, xRect),
|
||||
SBBasePda(pParent, xRect, bActivated) {
|
||||
_xSDevType = SDEV_PDA;
|
||||
|
||||
_activeHeight = 0;
|
||||
_deactiveHeight = 0;
|
||||
}
|
||||
|
||||
void CBagPDA::addToMovieQueue(CBagMovieObject *pMObj) {
|
||||
// Make sure we've got a list.
|
||||
if (_movieList == nullptr) {
|
||||
_movieList = new CBofList<CBagMovieObject *>;
|
||||
}
|
||||
|
||||
// Handle simple case first, if it is marked for don't queue, then don't
|
||||
// add it at all. This is done to insure that insignificant movies
|
||||
// such as "have you noticed your message light has been blinking" do not
|
||||
// get queued (and subsequently play when they are no longer appropriate).
|
||||
if (pMObj->isDontQueue()) {
|
||||
return;
|
||||
}
|
||||
|
||||
assert(_movieList != nullptr);
|
||||
|
||||
// Go through the whole movie list, make sure there are no dup's of
|
||||
// this movie.
|
||||
int nCount = _movieList->getCount();
|
||||
for (int i = 0; i < nCount; i++) {
|
||||
CBagMovieObject *p = _movieList->getNodeItem(i);
|
||||
if (p->getFileName().find(pMObj->getFileName()) == 0) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
_movieList->addToTail(pMObj);
|
||||
}
|
||||
|
||||
CBagPDA::~CBagPDA() {
|
||||
assert(isValidObject(this));
|
||||
|
||||
// Does not own list item, so no need to delete individual nodes
|
||||
delete _movieList;
|
||||
_movieList = nullptr;
|
||||
}
|
||||
|
||||
ErrorCode CBagPDA::loadFile(const CBofString &sFile) {
|
||||
assert(isValidObject(this));
|
||||
|
||||
ErrorCode errorCode = CBagStorageDev::loadFile(sFile);
|
||||
|
||||
if (_mooWnd) {
|
||||
removeObject(_mooWnd);
|
||||
}
|
||||
if (_invWnd) {
|
||||
removeObject(_invWnd);
|
||||
}
|
||||
if (_mapWnd) {
|
||||
removeObject(_mapWnd);
|
||||
}
|
||||
if (_logWnd) {
|
||||
removeObject(_logWnd);
|
||||
}
|
||||
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
ErrorCode CBagPDA::attach() {
|
||||
CBagStorageDev *pSDev;
|
||||
ErrorCode errorCode = CBagStorageDevBmp::attach();
|
||||
|
||||
// Get PDA state info
|
||||
getPdaState();
|
||||
|
||||
// Calculate the position for the pda
|
||||
CBofRect bmpRect = getBitmap()->getRect();
|
||||
CBofWindow *pGameWin = CBagel::getBagApp()->getMasterWnd()->getCurrentGameWindow();
|
||||
CBofRect GameRect = pGameWin->getRect();
|
||||
|
||||
// When the pda is active it should sit flush with the bottom of the screen
|
||||
_activeHeight = GameRect.height() - bmpRect.height();
|
||||
// When it is deactivated it should be the active height less the total movement distance
|
||||
_deactiveHeight = GameRect.height() - (bmpRect.height() - (_moveDist * _numMoves));
|
||||
|
||||
// Should be allowed to not find one.
|
||||
if (!_mooWnd) {
|
||||
pSDev = g_SDevManager->getStorageDevice(MOO_WLD);
|
||||
if (pSDev != nullptr) {
|
||||
_mooWnd = (CBagStorageDevBmp *)pSDev;
|
||||
_mooWnd->setAssociateWnd(getAssociateWnd());
|
||||
_mooWnd->setTransparent(false);
|
||||
_mooWnd->setVisible(false);
|
||||
errorCode = _mooWnd->attach();
|
||||
}
|
||||
}
|
||||
|
||||
if (!_invWnd) {
|
||||
pSDev = g_SDevManager->getStorageDevice(INV_WLD);
|
||||
if (pSDev != nullptr) {
|
||||
_invWnd = (CBagStorageDevBmp *)pSDev;
|
||||
_invWnd->setAssociateWnd(getAssociateWnd());
|
||||
|
||||
_invWnd->setTransparent(false);
|
||||
_invWnd->setVisible(false);
|
||||
errorCode = _invWnd->attach();
|
||||
} else {
|
||||
bofMessageBox("No PDA INVENTORY found", __FILE__);
|
||||
errorCode = ERR_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
if (!_mapWnd) {
|
||||
pSDev = g_SDevManager->getStorageDevice(MAP_WLD);
|
||||
if (pSDev != nullptr) {
|
||||
_mapWnd = (CBagStorageDevBmp *)pSDev;
|
||||
_mapWnd->setAssociateWnd(getAssociateWnd());
|
||||
|
||||
_mapWnd->setTransparent(false);
|
||||
_mapWnd->setVisible(false);
|
||||
errorCode = _mapWnd->attach();
|
||||
} else {
|
||||
bofMessageBox("No PDA MAP found", __FILE__);
|
||||
errorCode = ERR_UNKNOWN;
|
||||
}
|
||||
}
|
||||
if (!_logWnd) {
|
||||
pSDev = g_SDevManager->getStorageDevice(LOG_WLD);
|
||||
if (pSDev != nullptr) {
|
||||
_logWnd = (CBagStorageDevBmp *)pSDev;
|
||||
_logWnd->setAssociateWnd(getAssociateWnd());
|
||||
|
||||
_logWnd->setTransparent(false);
|
||||
_logWnd->setVisible(false);
|
||||
errorCode = _logWnd->attach();
|
||||
}
|
||||
}
|
||||
if (_pdaMode == PDA_INV_MODE) {
|
||||
showInventory();
|
||||
} else if (_pdaMode == PDA_MAP_MODE) {
|
||||
showMap();
|
||||
} else if (_pdaMode == PDA_LOG_MODE) {
|
||||
showLog();
|
||||
}
|
||||
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
void CBagPDA::setPosInWindow(int cx, int cy, int nDist) {
|
||||
CBofBitmap *pBmp = getBitmap();
|
||||
|
||||
if (!pBmp)
|
||||
return;
|
||||
|
||||
CBofRect bmpRect = pBmp->getRect();
|
||||
|
||||
_moveDist = nDist;
|
||||
CBofPoint pt;
|
||||
pt.x = (cx - bmpRect.width()) / 2;
|
||||
|
||||
if (_activated)
|
||||
pt.y = cy - bmpRect.height();
|
||||
else
|
||||
pt.y = cy - bmpRect.height() + _moveDist * _numMoves;
|
||||
|
||||
setRect(CBofRect(pt.x, pt.y, pt.x + pBmp->width() - 1, pt.y + pBmp->height() - 1));
|
||||
}
|
||||
|
||||
bool CBagPDA::hideCurDisplay() {
|
||||
SBBasePda::hideCurDisplay();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CBagPDA::restoreCurDisplay() {
|
||||
SBBasePda::restoreCurDisplay();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CBagPDA::hideInventory() {
|
||||
SBBasePda::hideInventory();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CBagPDA::showInventory() {
|
||||
SBBasePda::showInventory();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
ErrorCode CBagPDA::update(CBofBitmap *pBmp, CBofPoint pt, CBofRect *pSrcRect, int /* nMaskColor */) {
|
||||
// Update the zoom button (it might need to blink).
|
||||
handleZoomButton(false);
|
||||
ErrorCode errorCode = ERR_NONE;
|
||||
|
||||
if (_hidePdaFl)
|
||||
return errorCode;
|
||||
|
||||
CBofRect r;
|
||||
CBofRect *pr = pSrcRect;
|
||||
|
||||
if (_activating) {
|
||||
|
||||
CBofPoint loc = getPosition();
|
||||
_activating--;
|
||||
|
||||
if (_activated) {
|
||||
if (loc.y > _activeHeight) {
|
||||
loc.y -= _moveDist;
|
||||
if (pSrcRect) {
|
||||
r = *pSrcRect;
|
||||
pSrcRect->bottom += _moveDist;
|
||||
pr = &r;
|
||||
}
|
||||
}
|
||||
} else if (loc.y < _deactiveHeight) {
|
||||
loc.y += _moveDist;
|
||||
if (pSrcRect) {
|
||||
r = *pSrcRect;
|
||||
pSrcRect->top -= _moveDist;
|
||||
pr = &r;
|
||||
}
|
||||
}
|
||||
|
||||
setPosition(loc);
|
||||
|
||||
pt = loc;
|
||||
}
|
||||
|
||||
// We have gotten back from a zoom and we need to straighten up
|
||||
if (SBBasePda::_pdaMode == PDA_INV_MODE && _curDisplay != _invWnd) {
|
||||
showInventory();
|
||||
|
||||
} else if (SBBasePda::_pdaMode == PDA_MAP_MODE && _curDisplay != _mapWnd) {
|
||||
|
||||
showMap();
|
||||
} else if (SBBasePda::_pdaMode == PDA_LOG_MODE && _curDisplay != _logWnd) {
|
||||
showLog();
|
||||
}
|
||||
|
||||
bool bIsMovieWaiting = isMovieWaiting();
|
||||
bool bMoviePlaying = false;
|
||||
|
||||
if ((!isActivated()) && // Must be down
|
||||
((_pdaMode == PDA_MAP_MODE) ||
|
||||
(bIsMovieWaiting && _pdaMode != PDA_MOO_MODE))) {
|
||||
|
||||
// Reset to reflect we know it happened
|
||||
setPreFiltered(false);
|
||||
|
||||
// Play the movie if it is ready.
|
||||
if (bIsMovieWaiting == true) {
|
||||
runWaitingMovie();
|
||||
}
|
||||
} else if (_pdaMode == PDA_MOO_MODE) {
|
||||
// If we're playing a pda movie, then make sure we continue to update.
|
||||
bMoviePlaying = true;
|
||||
}
|
||||
|
||||
// If the official decree from on high has been given to update, do so!
|
||||
errorCode = CBagStorageDevBmp::update(pBmp, pt, pr, _nMaskColor);
|
||||
|
||||
// If the PDA is activating then redraw our black background
|
||||
bool bWandAnimating = CBagCharacterObject::pdaWandAnimating();
|
||||
|
||||
if (isActivating() || bWandAnimating || bMoviePlaying) {
|
||||
CBagStorageDevWnd *pMainWin = (CBagel::getBagApp()->getMasterWnd()->getCurrentStorageDev());
|
||||
((CBagPanWindow *)pMainWin)->setPreFilterPan(true);
|
||||
} else if (!isActivated() && (SBBasePda::_pdaMode != PDA_MAP_MODE)) {
|
||||
// If it is not activated, then don't bother redrawing it or the objects
|
||||
// inside of it.
|
||||
setDirty(false);
|
||||
}
|
||||
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
|
||||
bool CBagPDA::isInside(const CBofPoint &xPoint) {
|
||||
CBofBitmap *pSrcBmp = getBitmap();
|
||||
|
||||
if (getRect().ptInRect(xPoint) && _nMaskColor >= 0) {
|
||||
if (pSrcBmp) {
|
||||
int x = xPoint.x - getRect().left;
|
||||
int y = xPoint.y - getRect().top;
|
||||
int c = pSrcBmp->readPixel(x, y);
|
||||
return (c != _nMaskColor);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void CBagPDA::onLButtonUp(uint32 nFlags, CBofPoint *xPoint, void *info) {
|
||||
CBagStorageDevWnd *pMainWin = (CBagel::getBagApp()->getMasterWnd()->getCurrentStorageDev());
|
||||
|
||||
if (!isActivated() && _pdaMode != PDA_INV_MODE) { // if the PDA is not active, activate it
|
||||
if (isInside(*xPoint)) {
|
||||
// Make sure the entire screen gets redrawn for an activate
|
||||
((CBagPanWindow *)pMainWin)->setPreFilterPan(true);
|
||||
|
||||
activate();
|
||||
setDirty(true);
|
||||
attachActiveObjects(); // Forces PDA to be reevaluated.
|
||||
}
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
// Else, call the default func
|
||||
CBofPoint RealPt = devPtToViewPort(*xPoint);
|
||||
|
||||
if (_curDisplay && _curDisplay->getRect().ptInRect(RealPt)) {
|
||||
_curDisplay->onLButtonUp(nFlags, &RealPt, info);
|
||||
} else {
|
||||
// if not in the PDA view port then check and make sure it is activated.
|
||||
if (SBBasePda::_pdaMode == PDA_INV_MODE && !isActivated()) {
|
||||
if (isInside(*xPoint)) {
|
||||
// Make sure the entire screen gets redrawn for an activate
|
||||
((CBagPanWindow *)pMainWin)->setPreFilterPan(true);
|
||||
|
||||
activate();
|
||||
setDirty(true);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// If it's in one of the buttons, then pass it off to the
|
||||
// sdev bmp code.
|
||||
if (isActivated()) {
|
||||
bool bButtonHit = false;
|
||||
CBofList<CBagObject *> *pList = getObjectList();
|
||||
int nCount = (pList == nullptr ? 0 : pList->getCount());
|
||||
|
||||
// Go through all the buttons and see if we hit any of them.
|
||||
for (int i = 0; i < nCount; i++) {
|
||||
CBagObject *pObj = pList->getNodeItem(i);
|
||||
if (pObj->getType() == BUTTON_OBJ && pObj->getRect().ptInRect(RealPt)) {
|
||||
bButtonHit = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Deactivate the PDA if we didn't hit a button.
|
||||
if (bButtonHit || _pdaMode == PDA_NO_MODE) {
|
||||
CBagStorageDevBmp::onLButtonUp(nFlags, xPoint, info);
|
||||
} else {
|
||||
((CBagPanWindow *)pMainWin)->setPreFilterPan(true);
|
||||
deactivate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// After a change of state, check if we should be flashing our
|
||||
// zoom button or not.
|
||||
handleZoomButton(false);
|
||||
}
|
||||
|
||||
void CBagPDA::onLButtonDown(uint32 nFlags, CBofPoint *xPoint, void *info) {
|
||||
// All we want to do here is if we had a mouse down on our
|
||||
// zoom button, then make sure we have the real zoom button current (that
|
||||
// is, if we have the inventory front and center).
|
||||
|
||||
handleZoomButton(true);
|
||||
|
||||
CBagStorageDevBmp::onLButtonDown(nFlags, xPoint, info);
|
||||
}
|
||||
|
||||
CBagObject *CBagPDA::onNewButtonObject(const CBofString &) {
|
||||
CBagButtonObject *PdaButtObj = new CBagButtonObject();
|
||||
PdaButtObj->setCallBack(pdaButtonHandler, (SBBasePda *)this);
|
||||
|
||||
return PdaButtObj;
|
||||
}
|
||||
|
||||
bool CBagPDA::paintFGObjects(CBofBitmap *pBmp) {
|
||||
if (_curDisplay) {
|
||||
// If we get here, then we are guaranteed that our pda
|
||||
// needs updating, so dirty the whole list before updating...
|
||||
// this assures that all objects will be updated (that are active).
|
||||
makeListDirty(_curDisplay->getObjectList());
|
||||
|
||||
CBofRect tmp = getRect();
|
||||
_curDisplay->update(pBmp, getPosition(), &tmp);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
CBagObject *CBagPDA::onNewUserObject(const CBofString &sInit) {
|
||||
CBagTimeObject *pTimeObj = nullptr;
|
||||
if (sInit == "TIME") {
|
||||
pTimeObj = new CBagTimeObject();
|
||||
}
|
||||
|
||||
return pTimeObj;
|
||||
}
|
||||
|
||||
void CBagPDA::handleZoomButton(bool bButtonDown) {
|
||||
CBagButtonObject *pZoomRegular = nullptr;
|
||||
CBagButtonObject *pZoomFlash = nullptr;
|
||||
|
||||
char szLocalBuff[256];
|
||||
CBofString sDevice(szLocalBuff, 256);
|
||||
sDevice = "BPDA_WLD";
|
||||
|
||||
CBagStorageDev *pPda = g_SDevManager->getStorageDevice(sDevice);
|
||||
if (pPda) {
|
||||
sDevice = PDA_ZOOMFLASH;
|
||||
pZoomFlash = (CBagButtonObject *)pPda->getObject(sDevice);
|
||||
pZoomRegular = (CBagButtonObject *)pPda->getObject(PDA_ZOOM);
|
||||
}
|
||||
|
||||
// Only change the flashing state if we're not in a button down situation
|
||||
if (pZoomFlash && pZoomRegular && pZoomRegular->getState() != 1) {
|
||||
if (bButtonDown == false && _pdaMode == PDA_INV_MODE && (_pdaPos == PDA_UP) && _invWnd && _invWnd->getNumFloatPages() > 1) {
|
||||
// Make the zoom button blink, to indicate more icons
|
||||
if (_flashingFl == false) {
|
||||
// Don't allow attachActiveObjects() to be called in here
|
||||
g_allowattachActiveObjectsFl = false;
|
||||
pPda->activateLocalObject(pZoomFlash);
|
||||
pPda->deactivateLocalObject(pZoomRegular);
|
||||
g_allowattachActiveObjectsFl = true;
|
||||
|
||||
pZoomFlash->setActive(true);
|
||||
pZoomRegular->setActive(false);
|
||||
|
||||
pZoomFlash->setAnimated(true);
|
||||
pZoomFlash->setAlwaysUpdate(true);
|
||||
|
||||
_flashingFl = true;
|
||||
}
|
||||
} else if (_flashingFl) {
|
||||
// Don't allow attachActiveObjects() to be called in here
|
||||
g_allowattachActiveObjectsFl = false;
|
||||
pPda->deactivateLocalObject(pZoomFlash);
|
||||
pPda->activateLocalObject(pZoomRegular);
|
||||
g_allowattachActiveObjectsFl = true;
|
||||
|
||||
pZoomFlash->setActive(false);
|
||||
pZoomRegular->setActive(true);
|
||||
|
||||
pZoomFlash->setAnimated(false);
|
||||
pZoomFlash->setAlwaysUpdate(false);
|
||||
|
||||
_flashingFl = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CBagPDA::removeFromMovieQueue(CBagMovieObject *pMObj) {
|
||||
if (_movieList == nullptr)
|
||||
return;
|
||||
|
||||
int nCount = _movieList->getCount();
|
||||
for (int i = 0; i < nCount; i++) {
|
||||
CBagMovieObject *p = _movieList->getNodeItem(i);
|
||||
if (pMObj == p) {
|
||||
_movieList->remove(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool CBagPDA::isMovieWaiting() {
|
||||
bool bMovieWaiting = false;
|
||||
|
||||
if (_movieList) {
|
||||
bMovieWaiting = (_movieList->getCount() > 0);
|
||||
}
|
||||
|
||||
// If our sounds are paused, and our movie is done playing,
|
||||
// then start up our sounds again.
|
||||
if (_soundsPausedFl == true && isMoviePlaying() == false) {
|
||||
CBofSound::resumeSounds();
|
||||
_soundsPausedFl = false;
|
||||
}
|
||||
|
||||
return bMovieWaiting;
|
||||
}
|
||||
|
||||
void CBagPDA::runWaitingMovie() {
|
||||
// Will only run a movie if it is ready to be run
|
||||
if (!_movieList)
|
||||
return;
|
||||
|
||||
int nCount = _movieList->getCount();
|
||||
for (int i = 0; i < nCount; i++) {
|
||||
CBagMovieObject *pMObj = _movieList->getNodeItem(i);
|
||||
if (pMObj->asynchPDAMovieCanPlay()) {
|
||||
_soundsPausedFl = true;
|
||||
// pause all sounds
|
||||
CBofSound::pauseSounds();
|
||||
pMObj->runObject();
|
||||
removeFromMovieQueue(pMObj);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ErrorCode CBagPDA::attachActiveObjects() {
|
||||
static bool bAlready = false;
|
||||
|
||||
// If not already in this function
|
||||
if (!bAlready) {
|
||||
// Stop recursion
|
||||
bAlready = true;
|
||||
|
||||
SBBasePda::attachActiveObjects();
|
||||
CBagStorageDevBmp::attachActiveObjects();
|
||||
|
||||
bAlready = false;
|
||||
}
|
||||
|
||||
return _errCode;
|
||||
}
|
||||
|
||||
ErrorCode CBagPDA::detachActiveObjects() {
|
||||
SBBasePda::detachActiveObjects();
|
||||
return CBagStorageDevBmp::detachActiveObjects();
|
||||
}
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
170
engines/bagel/spacebar/baglib/pda.h
Normal file
170
engines/bagel/spacebar/baglib/pda.h
Normal file
@@ -0,0 +1,170 @@
|
||||
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BAGEL_BAGLIB_PDA_H
|
||||
#define BAGEL_BAGLIB_PDA_H
|
||||
|
||||
#include "bagel/spacebar/baglib/base_pda.h"
|
||||
#include "bagel/spacebar/baglib/movie_object.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
#define PDA_INCREMENT 13
|
||||
|
||||
class CBagPDA : public CBagStorageDevBmp, public SBBasePda {
|
||||
protected:
|
||||
int _activeHeight;
|
||||
int _deactiveHeight;
|
||||
static bool _flashingFl;
|
||||
static bool _soundsPausedFl;
|
||||
|
||||
static CBofList<CBagMovieObject *> *_movieList;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Constructor
|
||||
* @param pParent Pointer to the parent window
|
||||
* @param xRect Rect of the pda
|
||||
* @param bActivated State of PDA whe constructed (optional)
|
||||
*/
|
||||
CBagPDA(CBofWindow *pParent = nullptr, const CBofRect &xRect = CBofRect(), bool bActivated = false);
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
virtual ~CBagPDA();
|
||||
static void initialize();
|
||||
|
||||
ErrorCode attach() override;
|
||||
|
||||
/**
|
||||
* Positions the PDA centered vertically and window
|
||||
* @param cx x position
|
||||
* @param cy y position
|
||||
* @param nDist Distance to bring move PDA
|
||||
*/
|
||||
void setPosInWindow(int cx, int cy, int nDist = PDA_INCREMENT);
|
||||
|
||||
/**
|
||||
* Update the PDA to the screen and then call CBagStorageDevBmp update
|
||||
* @param pBmp Background bitmap to paint to
|
||||
* @param pt Offset into bitmap
|
||||
* @param pSrcRect Clip rect of the object to be painted
|
||||
* @param nMaskColor Mask color for the object
|
||||
*/
|
||||
ErrorCode update(CBofBitmap *pBmp, CBofPoint pt, CBofRect *pSrcRect = nullptr, int nMaskColor = -1) override;
|
||||
|
||||
/**
|
||||
* Called to overload specific types of sprite objects
|
||||
* @param pBmp Bitmap
|
||||
* @return Success/failure
|
||||
*/
|
||||
bool paintFGObjects(CBofBitmap *pBmp) override;
|
||||
|
||||
ErrorCode loadFile(const CBofString &sFile) override;
|
||||
|
||||
/**
|
||||
* Called to overload specific types of sprite objects
|
||||
* @param sInit Init
|
||||
* @return Pointer to the new object
|
||||
*/
|
||||
CBagObject *onNewButtonObject(const CBofString &sInit) override;
|
||||
|
||||
/**
|
||||
* Called on the mouse left button down
|
||||
* Is the PDA is deactivated mouse down activates the PDA
|
||||
* else it calls CBagStorageDevBmp::onLButtonDown
|
||||
* @param nFlags Flags
|
||||
* @param xPoint X, Y position
|
||||
* @param info Optional info
|
||||
*/
|
||||
void onLButtonUp(uint32 nFlags, CBofPoint *xPoint, void *info = nullptr) override;
|
||||
|
||||
/**
|
||||
* Called on the mouse left button down
|
||||
* @param nFlags Flags
|
||||
* @param xPoint X, Y position
|
||||
* @param info Optional info
|
||||
*/
|
||||
void onLButtonDown(uint32 nFlags, CBofPoint *xPoint, void *info = nullptr) override;
|
||||
|
||||
bool isInside(const CBofPoint &xPoint) override;
|
||||
|
||||
CBagObject *onNewUserObject(const CBofString &sInit) override;
|
||||
|
||||
/**
|
||||
* Allow the movie code to queue up asynch pda messages
|
||||
* Must be before the destructor
|
||||
*/
|
||||
static void addToMovieQueue(CBagMovieObject *);
|
||||
|
||||
/**
|
||||
* Just remove this message from the queue, remember that we
|
||||
* don't own this object, so just remove it, don't delete it!!!!
|
||||
*/
|
||||
static void removeFromMovieQueue(CBagMovieObject *);
|
||||
|
||||
/**
|
||||
* Return true if a movie is waiting to play.
|
||||
*/
|
||||
static bool isMovieWaiting();
|
||||
|
||||
static bool isMoviePlaying() {
|
||||
return _pdaMode == PDA_MOO_MODE;
|
||||
}
|
||||
|
||||
static void runWaitingMovie();
|
||||
|
||||
/**
|
||||
* SHow the inventory
|
||||
*/
|
||||
bool showInventory() override;
|
||||
|
||||
/**
|
||||
* Hide the inventory
|
||||
*/
|
||||
bool hideInventory() override;
|
||||
|
||||
/**
|
||||
* Hide the current display
|
||||
*/
|
||||
bool hideCurDisplay() override;
|
||||
|
||||
/**
|
||||
* Restore display
|
||||
*/
|
||||
bool restoreCurDisplay() override;
|
||||
|
||||
ErrorCode attachActiveObjects() override;
|
||||
ErrorCode detachActiveObjects() override;
|
||||
|
||||
/**
|
||||
* Handle switching back and forth from our flashing zoom button
|
||||
*/
|
||||
void handleZoomButton(bool bButtonDown);
|
||||
};
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
|
||||
#endif
|
||||
74
engines/bagel/spacebar/baglib/res.h
Normal file
74
engines/bagel/spacebar/baglib/res.h
Normal file
@@ -0,0 +1,74 @@
|
||||
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BAGEL_BAGLIB_RES_H
|
||||
#define BAGEL_BAGLIB_RES_H
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
// This section should not change, the first cursor is always invalid
|
||||
#define BOF_INVALID 0
|
||||
|
||||
// OBJ
|
||||
// Lists object types
|
||||
#define BOF_BMP_OBJ 1
|
||||
#define BOF_SPRITE_OBJ 2
|
||||
#define BOF_BUTTON_OBJ 3
|
||||
#define BOF_SOUND_OBJ 4
|
||||
#define BOF_LINK_OBJ 5
|
||||
#define BOF_TEXT_OBJ 6
|
||||
#define BOF_CHAR_OBJ 7
|
||||
#define BOF_VAR_OBJ 8
|
||||
#define BOF_AREA_OBJ 9
|
||||
#define BOF_MOVIE_OBJ 11
|
||||
#define BOF_COMM_OBJ 12
|
||||
#define BOF_EXPRESS_OBJ 13
|
||||
#define BOF_THING_OBJ 14
|
||||
#define BOF_RESPRNT_OBJ 15
|
||||
#define BOF_DOSSIER_OBJ 16
|
||||
|
||||
// PAN
|
||||
// These CANNOT change
|
||||
|
||||
#define BOF_LT_CURSOR 14
|
||||
#define BOF_UP_CURSOR 15
|
||||
#define BOF_RT_CURSOR 16
|
||||
#define BOF_DN_CURSOR 17
|
||||
#define BOF_TAKE_HAND 18
|
||||
#define BOF_HAND 19
|
||||
|
||||
// WLD
|
||||
#define INV_WLD "INV_WLD"
|
||||
#define LOG_WLD "LOG_WLD"
|
||||
#define LOGZ_WLD "LOGZ_WLD"
|
||||
#define MAP_WLD "MAP_WLD"
|
||||
#define MOO_WLD "MOO_WLD"
|
||||
#define PDA_WLD "BPDA_WLD"
|
||||
#define PDAZ_WLD "BPDAZ_WLD"
|
||||
#define THUD_WLD "THUD_WLD"
|
||||
#define WIELD_WLD "BWIELD_WLD"
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
|
||||
#endif
|
||||
1657
engines/bagel/spacebar/baglib/rp_object.cpp
Normal file
1657
engines/bagel/spacebar/baglib/rp_object.cpp
Normal file
File diff suppressed because it is too large
Load Diff
162
engines/bagel/spacebar/baglib/rp_object.h
Normal file
162
engines/bagel/spacebar/baglib/rp_object.h
Normal file
@@ -0,0 +1,162 @@
|
||||
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BAGEL_BAGLIB_RP_OBJECT_H
|
||||
#define BAGEL_BAGLIB_RP_OBJECT_H
|
||||
|
||||
#include "bagel/spacebar/baglib/dossier_object.h"
|
||||
#include "bagel/spacebar/baglib/expression.h"
|
||||
#include "bagel/spacebar/baglib/movie_object.h"
|
||||
#include "bagel/spacebar/baglib/text_object.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
class DossierObj {
|
||||
public:
|
||||
DossierObj();
|
||||
virtual ~DossierObj();
|
||||
|
||||
CBagDossierObject *_pDossier;
|
||||
CBofString _sDossier;
|
||||
CBagExpression *_xDosExp;
|
||||
bool _bDisplayDossier;
|
||||
};
|
||||
|
||||
enum RPStates {
|
||||
RP_NO_MODE = 0,
|
||||
RP_RESULTS,
|
||||
RP_READ_DOSSIER,
|
||||
RP_REVIEW,
|
||||
RP_MAIN_MENU
|
||||
};
|
||||
|
||||
class CBagRPObject : public CBagObject {
|
||||
private:
|
||||
CBofList<DossierObj *> *_pTouchedList; // dossiers to show if alias touched it
|
||||
CBofList<DossierObj *> *_pUntouchedList; // dossiers to show if alias did not touch it
|
||||
CBagMovieObject *_pMovieObj; // a movie to play
|
||||
CBofString _sMovieObj; // Name of movie
|
||||
CBagVar *_pVarObj; // associated global var
|
||||
CBagTextObject *_pDescObj; // description of residue printed object
|
||||
CBagTextObject *_pObjectName; // description of residue printed object
|
||||
CBofString _sObjectName; // description of residue printed object
|
||||
|
||||
CBagVar *_pSaveVar; // Var to save info to
|
||||
CBagVar *_pTouchedVar; // variable indicating touched or not
|
||||
int _nRPTime; // time to execute
|
||||
|
||||
CBofRect _cOrigRect; // Original text rect
|
||||
|
||||
int16 _nCurDossier; // index of current dossier
|
||||
// member data boolS
|
||||
bool _bOrigRectInit : true; // Original text initialized
|
||||
bool _bRPReported : true; // been reported yet?
|
||||
bool _bResPrinted : true; // been submitted?
|
||||
bool _bTouched : true; // been touched?
|
||||
bool _bRPRead : true; // been read
|
||||
bool _bRPTimeSet : true; // had time residue printing occurred?
|
||||
bool _bCurVisible : true; // Current one being displayed?
|
||||
bool _bInitialized : true; // initialization state
|
||||
bool _bMoviePlayed : true; // Has the movie played yet?
|
||||
|
||||
static CBofList<CBagRPObject *> *_pRPList; // all the residue print objects
|
||||
static int32 _nLastRPQCheck; // last time we surfed the queue.
|
||||
static CBagVar *_turnCount; // Ptr to turnCount global
|
||||
static CBagVar *_pLogStateVar; // Ptr to log state global
|
||||
static CBagVar *_pPrevLogStateVar; // Ptr to prev log state global
|
||||
static CBagVar *_pBarLogPages; // Ptr to total pages global
|
||||
static CBagVar *_pPrevBarPage; //
|
||||
static CBagVar *_pCurBarPage; // current bar page
|
||||
static CBagRPObject *_pCurRPObject; // Most recent residue print object.
|
||||
static CBagRPObject *_pActivateThisGuy; // The one we want to activate
|
||||
static RPStates _eRPMode; // Current state of display
|
||||
public:
|
||||
CBagRPObject();
|
||||
virtual ~CBagRPObject();
|
||||
|
||||
ParseCodes setInfo(CBagIfstream &istr) override;
|
||||
|
||||
ErrorCode attach() override;
|
||||
ErrorCode detach() override;
|
||||
|
||||
bool runObject() override;
|
||||
|
||||
ErrorCode update(CBofBitmap *pBmp, CBofPoint pt, CBofRect *pSrcRect, int) override;
|
||||
|
||||
void onLButtonUp(uint32, CBofPoint *, void * = nullptr) override;
|
||||
|
||||
void setTouchedDos(CBofString &s, CBagExpression *x);
|
||||
void setUntouchedDos(CBofString &s, CBagExpression *x);
|
||||
|
||||
bool activateRPObject();
|
||||
void deactivateRPObject();
|
||||
|
||||
bool getTimeSet() {
|
||||
return _bRPTimeSet;
|
||||
}
|
||||
void setTimeSet(bool b) {
|
||||
_bRPTimeSet = b;
|
||||
}
|
||||
|
||||
void evaluateDossiers();
|
||||
|
||||
void saveResiduePrintedVars();
|
||||
void restoreResiduePrintedVars();
|
||||
|
||||
bool initialize();
|
||||
|
||||
CBagDossierObject *getActiveDossier();
|
||||
void setActiveDossier(CBagDossierObject *);
|
||||
|
||||
static bool addToMsgQueue(CBagRPObject *);
|
||||
|
||||
static bool zoomed();
|
||||
|
||||
// Command (bagcoobj) objects, activated from script
|
||||
static int runResiduePrintedQueue();
|
||||
static int updateResiduePrintedQueue();
|
||||
static void deactivateResiduePrintedQueue();
|
||||
|
||||
static void activateResiduePrintedReview();
|
||||
static void deactivateResiduePrintedReview();
|
||||
|
||||
static void setLogState(RPStates eLogMode);
|
||||
static RPStates getLogState();
|
||||
|
||||
static void setLogPages(int);
|
||||
|
||||
static void showResiduePrintedReview();
|
||||
static void hideResiduePrintedReview();
|
||||
|
||||
static int residuePrintedResultsWaiting();
|
||||
static void removeAllFromMsgQueue(CBagRPObject *pRPObj);
|
||||
|
||||
static void showPdaLog();
|
||||
|
||||
static void synchronizeResiduePrintedObjects(bool);
|
||||
};
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
|
||||
#endif
|
||||
317
engines/bagel/spacebar/baglib/save_game_file.cpp
Normal file
317
engines/bagel/spacebar/baglib/save_game_file.cpp
Normal file
@@ -0,0 +1,317 @@
|
||||
/* 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 "common/algorithm.h"
|
||||
#include "common/memstream.h"
|
||||
#include "common/serializer.h"
|
||||
#include "bagel/spacebar/baglib/save_game_file.h"
|
||||
#include "bagel/boflib/file_functions.h"
|
||||
#include "bagel/boflib/misc.h"
|
||||
#include "bagel/bagel.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
#define WORLD_DIR "$SBARDIR\\WLD\\%s"
|
||||
|
||||
void StSavegameHeader::synchronize(Common::Serializer &s) {
|
||||
s.syncBytes((byte *)_szTitle, MAX_SAVE_TITLE);
|
||||
s.syncBytes((byte *)_szUserName, MAX_USER_NAME);
|
||||
s.syncAsUint32LE(_bUsed);
|
||||
}
|
||||
|
||||
void StVar::synchronize(Common::Serializer &s) {
|
||||
s.syncBytes((byte *)_szName, MAX_VAR_NAME);
|
||||
s.syncBytes((byte *)_szValue, MAX_VAR_VALUE);
|
||||
s.syncAsUint16LE(_nType);
|
||||
|
||||
s.syncAsByte(_bGlobal);
|
||||
s.syncAsByte(_bConstant);
|
||||
s.syncAsByte(_bReference);
|
||||
s.syncAsByte(_bTimer);
|
||||
|
||||
s.syncAsByte(_bRandom);
|
||||
s.syncAsByte(_bNumeric);
|
||||
s.syncAsByte(_bAttached);
|
||||
|
||||
s.syncAsByte(_bUsed);
|
||||
}
|
||||
|
||||
void StVar::clear() {
|
||||
Common::fill(_szName, _szName + MAX_VAR_NAME, '\0');
|
||||
Common::fill(_szValue, _szValue + MAX_VAR_VALUE, '\0');
|
||||
|
||||
_nType = 0;
|
||||
_bGlobal = 0;
|
||||
_bConstant = 0;
|
||||
_bReference = 0;
|
||||
_bTimer = 0;
|
||||
_bRandom = 0;
|
||||
_bNumeric = 0;
|
||||
_bAttached = 0;
|
||||
_bUsed = 0;
|
||||
}
|
||||
|
||||
void StObj::synchronize(Common::Serializer &s) {
|
||||
s.syncBytes((byte *)_szName, MAX_OBJ_NAME);
|
||||
s.syncBytes((byte *)_szSDev, MAX_SDEV_NAME);
|
||||
s.syncAsUint32LE(_lState);
|
||||
|
||||
s.syncAsUint32LE(_lProperties);
|
||||
s.syncAsUint32LE(_lType);
|
||||
|
||||
s.syncAsUint32LE(_lLoop);
|
||||
s.syncAsUint32LE(_lSpeed);
|
||||
|
||||
s.syncAsByte(_bAttached);
|
||||
s.syncAsByte(_bUsed);
|
||||
|
||||
s.syncAsUint16LE(_nFlags);
|
||||
}
|
||||
|
||||
void StObj::clear() {
|
||||
Common::fill(_szName, _szName + MAX_OBJ_NAME, '\0');
|
||||
Common::fill(_szSDev, _szSDev + MAX_SDEV_NAME, '\0');
|
||||
|
||||
_lState = 0;
|
||||
_lProperties = 0;
|
||||
_lType = 0;
|
||||
_lLoop = 0;
|
||||
_lSpeed = 0;
|
||||
_bAttached = 0;
|
||||
_bUsed = 0;
|
||||
_nFlags = 0;
|
||||
}
|
||||
|
||||
void StBagelSave::synchronize(Common::Serializer &s) {
|
||||
for (int i = 0; i < MAX_VARS; ++i)
|
||||
_stVarList[i].synchronize(s);
|
||||
for (int i = 0; i < MAX_OBJS; ++i)
|
||||
_stObjList[i].synchronize(s);
|
||||
for (int i = 0; i < MAX_OBJS; ++i)
|
||||
_stObjListEx[i].synchronize(s);
|
||||
|
||||
s.syncBytes((byte *)_szScript, MAX_FNAME);
|
||||
s.syncAsUint32LE(_nLocType);
|
||||
|
||||
for (int i = 0; i < MAX_CLOSEUP_DEPTH; ++i)
|
||||
s.syncBytes((byte *)_szLocStack[i], MAX_SDEV_NAME);
|
||||
|
||||
s.syncAsUint16LE(_nLocX);
|
||||
s.syncAsUint16LE(_nLocY);
|
||||
s.syncAsUint16LE(_bUseEx);
|
||||
s.syncAsUint16LE(_nFiller);
|
||||
}
|
||||
|
||||
void StBagelSave::clear() {
|
||||
for (int i = 0; i < MAX_VARS; ++i)
|
||||
_stVarList[i].clear();
|
||||
for (int i = 0; i < MAX_OBJS; ++i) {
|
||||
_stObjList[i].clear();
|
||||
_stObjListEx[i].clear();
|
||||
}
|
||||
|
||||
Common::fill(_szScript, _szScript + MAX_FNAME, '\0');
|
||||
_nLocType = 0;
|
||||
|
||||
for (int i = 0; i < MAX_CLOSEUP_DEPTH; ++i)
|
||||
Common::fill(_szLocStack[i], _szLocStack[i] + MAX_SDEV_NAME, '\0');
|
||||
|
||||
_nLocX = 0;
|
||||
_nLocY = 0;
|
||||
_bUseEx = 0;
|
||||
_nFiller = 0;
|
||||
}
|
||||
|
||||
|
||||
CBagSaveGameFile::CBagSaveGameFile(bool isSaving) {
|
||||
setFile("spacebar.sav",
|
||||
isSaving ?
|
||||
(CDF_MEMORY | CDF_ENCRYPT | CDF_KEEPOPEN | CDF_CREATE | CDF_SAVEFILE) :
|
||||
(CDF_MEMORY | CDF_ENCRYPT | CDF_KEEPOPEN | CDF_SAVEFILE)
|
||||
);
|
||||
}
|
||||
|
||||
ErrorCode CBagSaveGameFile::writeSavedGame() {
|
||||
assert(isValidObject(this));
|
||||
|
||||
// Populate the save data
|
||||
StBagelSave *saveData = new StBagelSave();
|
||||
g_engine->_masterWin->fillSaveBuffer(saveData);
|
||||
|
||||
Common::String str = "./" + Common::String(saveData->_szScript);
|
||||
str.replace('/', '\\');
|
||||
Common::strcpy_s(saveData->_szScript, str.c_str());
|
||||
|
||||
// Set up header fields
|
||||
StSavegameHeader header;
|
||||
Common::strcpy_s(header._szTitle, "ScummVM Save");
|
||||
Common::strcpy_s(header._szUserName, "ScummVM User");
|
||||
header._bUsed = 1;
|
||||
|
||||
// Create the data buffer
|
||||
Common::MemoryWriteStreamDynamic stream(DisposeAfterUse::YES);
|
||||
Common::Serializer s(nullptr, &stream);
|
||||
|
||||
header.synchronize(s);
|
||||
stream.writeUint32LE(StBagelSave::size());
|
||||
saveData->synchronize(s);
|
||||
|
||||
// Add the record
|
||||
addRecord(stream.getData(), stream.size(), true, 0);
|
||||
|
||||
delete saveData;
|
||||
|
||||
return _errCode;
|
||||
}
|
||||
|
||||
ErrorCode CBagSaveGameFile::readSavedGame(int32 slotNum) {
|
||||
assert(isValidObject(this));
|
||||
|
||||
int32 lRecNum = findRecord(slotNum);
|
||||
if (lRecNum != -1) {
|
||||
int32 lSize = getRecSize(lRecNum);
|
||||
|
||||
if (lSize == StSavegameHeader::size()) {
|
||||
_errCode = ERR_FREAD;
|
||||
} else {
|
||||
byte *pBuf = (byte *)bofAlloc(lSize);
|
||||
readRecord(lRecNum, pBuf);
|
||||
|
||||
// Load in the savegame
|
||||
Common::MemoryReadStream stream(pBuf, lSize);
|
||||
Common::Serializer s(&stream, nullptr);
|
||||
StSavegameHeader header;
|
||||
header.synchronize(s);
|
||||
s.skip(4); // Skip save data structure size
|
||||
StBagelSave *saveData = new StBagelSave();
|
||||
saveData->synchronize(s);
|
||||
|
||||
bofFree(pBuf);
|
||||
|
||||
CBofString str(saveData->_szScript);
|
||||
fixPathName(str);
|
||||
const char *path = str.getBuffer();
|
||||
assert(!strncmp(path, "./", 2));
|
||||
Common::strcpy_s(saveData->_szScript, path + 2);
|
||||
|
||||
// Restore the game
|
||||
g_engine->_masterWin->doRestore(saveData);
|
||||
|
||||
delete saveData;
|
||||
}
|
||||
} else {
|
||||
_errCode = ERR_FREAD;
|
||||
}
|
||||
|
||||
return _errCode;
|
||||
}
|
||||
|
||||
ErrorCode CBagSaveGameFile::readTitle(int32 lSlot, StSavegameHeader *pSavedGame) {
|
||||
assert(isValidObject(this));
|
||||
|
||||
// validate input
|
||||
assert(lSlot >= 0 && lSlot < MAX_SAVED_GAMES);
|
||||
assert(pSavedGame != nullptr);
|
||||
|
||||
int32 lRecNum = findRecord(lSlot);
|
||||
|
||||
if (lRecNum != -1) {
|
||||
int32 lSize = getRecSize(lRecNum);
|
||||
|
||||
byte *pBuf = (byte *)bofAlloc(lSize);
|
||||
readRecord(lRecNum, pBuf);
|
||||
|
||||
// Fill StSavegameHeader structure with this game's saved info
|
||||
memcpy(pSavedGame, pBuf, sizeof(StSavegameHeader));
|
||||
bofFree(pBuf);
|
||||
|
||||
} else {
|
||||
reportError(ERR_UNKNOWN, "Unable to find saved game #%ld in %s", lSlot, _szFileName);
|
||||
}
|
||||
|
||||
return (_errCode);
|
||||
}
|
||||
|
||||
ErrorCode CBagSaveGameFile::readTitleOnly(int32 lSlot, char *pGameTitle) {
|
||||
assert(isValidObject(this));
|
||||
|
||||
// Validate input
|
||||
assert(lSlot >= 0 && lSlot < MAX_SAVED_GAMES);
|
||||
assert(pGameTitle != nullptr);
|
||||
|
||||
byte pBuf[MAX_SAVE_TITLE + 1];
|
||||
int32 lRecNum = findRecord(lSlot);
|
||||
if (lRecNum != -1) {
|
||||
int32 lSize = MAX_SAVE_TITLE;
|
||||
readFromFile(lRecNum, pBuf, lSize);
|
||||
|
||||
// Fill with current game title
|
||||
memcpy(pGameTitle, pBuf, lSize);
|
||||
|
||||
} else {
|
||||
reportError(ERR_UNKNOWN, "Unable to find saved game #%ld in %s", lSlot, _szFileName);
|
||||
}
|
||||
|
||||
return _errCode;
|
||||
}
|
||||
|
||||
|
||||
int32 CBagSaveGameFile::getActualNumSaves() {
|
||||
assert(isValidObject(this));
|
||||
|
||||
int32 lNumSaves = 0;
|
||||
int32 lNumRecs = getNumSavedGames();
|
||||
for (int32 i = 0; i < lNumRecs; i++) {
|
||||
StSavegameHeader stGameInfo;
|
||||
if (readTitle(i, &stGameInfo) == ERR_NONE) {
|
||||
if (stGameInfo._bUsed) {
|
||||
lNumSaves++;
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return (lNumSaves);
|
||||
}
|
||||
|
||||
bool CBagSaveGameFile::anySavedGames() {
|
||||
assert(isValidObject(this));
|
||||
|
||||
int32 lNumRecs = getNumSavedGames();
|
||||
for (int32 i = 0; i < lNumRecs; i++) {
|
||||
StSavegameHeader stGameInfo;
|
||||
if (readTitle(i, &stGameInfo) == ERR_NONE) {
|
||||
|
||||
if (stGameInfo._bUsed) {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
159
engines/bagel/spacebar/baglib/save_game_file.h
Normal file
159
engines/bagel/spacebar/baglib/save_game_file.h
Normal file
@@ -0,0 +1,159 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BAGEL_BAGLIB_SAVE_GAME_FILE_H
|
||||
#define BAGEL_BAGLIB_SAVE_GAME_FILE_H
|
||||
|
||||
#include "common/serializer.h"
|
||||
#include "bagel/spacebar/boflib/dat_file.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
#define MAX_SAVED_GAMES 40
|
||||
#define MAX_SAVE_TITLE 128
|
||||
#define MAX_USER_NAME 64
|
||||
|
||||
struct StSavegameHeader {
|
||||
char _szTitle[MAX_SAVE_TITLE] = { '\0' };
|
||||
char _szUserName[MAX_USER_NAME] = { '\0' };
|
||||
uint32 _bUsed = 0;
|
||||
|
||||
void synchronize(Common::Serializer &s);
|
||||
static int size() {
|
||||
return MAX_SAVE_TITLE + MAX_USER_NAME + 4;
|
||||
}
|
||||
};
|
||||
|
||||
#define MAX_SDEV_NAME 40
|
||||
#define MAX_CLOSEUP_DEPTH 4
|
||||
|
||||
#define MAX_VARS 1000
|
||||
#define MAX_VAR_NAME 40
|
||||
#define MAX_VAR_VALUE 60
|
||||
|
||||
struct StVar {
|
||||
char _szName[MAX_VAR_NAME];
|
||||
char _szValue[MAX_VAR_VALUE];
|
||||
uint16 _nType;
|
||||
|
||||
byte _bGlobal;
|
||||
byte _bConstant;
|
||||
byte _bReference;
|
||||
byte _bTimer;
|
||||
|
||||
byte _bRandom;
|
||||
byte _bNumeric;
|
||||
byte _bAttached;
|
||||
|
||||
byte _bUsed; // If this entry is used or not
|
||||
|
||||
void synchronize(Common::Serializer &s);
|
||||
void clear();
|
||||
};
|
||||
|
||||
#define MAX_OBJ_NAME 40
|
||||
#define MAX_SDEV_NAME 40
|
||||
#define MAX_OBJS 1000
|
||||
|
||||
struct StObj {
|
||||
char _szName[MAX_OBJ_NAME];
|
||||
char _szSDev[MAX_SDEV_NAME];
|
||||
uint32 _lState;
|
||||
|
||||
uint32 _lProperties;
|
||||
uint32 _lType;
|
||||
|
||||
uint32 _lLoop;
|
||||
uint32 _lSpeed;
|
||||
|
||||
byte _bAttached;
|
||||
byte _bUsed;
|
||||
|
||||
uint16 _nFlags; // Flags for kicks...
|
||||
|
||||
void synchronize(Common::Serializer &s);
|
||||
void clear();
|
||||
};
|
||||
|
||||
// Flags for the st_obj structure
|
||||
|
||||
#define mIsMsgWaiting 0x0001
|
||||
|
||||
/**
|
||||
* Savegame data structure
|
||||
*/
|
||||
struct StBagelSave {
|
||||
StVar _stVarList[MAX_VARS];
|
||||
StObj _stObjList[MAX_OBJS];
|
||||
StObj _stObjListEx[MAX_OBJS];
|
||||
char _szScript[MAX_FNAME]; // Name of current world file (no path)
|
||||
uint32 _nLocType; // TYPE_PAN, TYPE_CLOSEUP, etc...
|
||||
char _szLocStack[MAX_CLOSEUP_DEPTH][MAX_SDEV_NAME]; // Your storage device stack
|
||||
uint16 _nLocX; // X Location in PAN
|
||||
uint16 _nLocY; // Y Location in PAN
|
||||
uint16 _bUseEx;
|
||||
uint16 _nFiller; // Make structs align
|
||||
|
||||
void synchronize(Common::Serializer &s);
|
||||
void clear();
|
||||
|
||||
static int size() {
|
||||
return 318432;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Handles reading/writing the original savegame file that contains
|
||||
* all the saves. Used by the console save/load commands.
|
||||
*/
|
||||
class CBagSaveGameFile : public CBofDataFile {
|
||||
public:
|
||||
CBagSaveGameFile(bool isSaving);
|
||||
|
||||
int32 getNumSavedGames() const {
|
||||
return getNumberOfRecs();
|
||||
}
|
||||
int32 getActualNumSaves();
|
||||
bool anySavedGames();
|
||||
|
||||
/**
|
||||
* Saves a BAGEL game to current save game file
|
||||
*/
|
||||
ErrorCode writeSavedGame();
|
||||
|
||||
/**
|
||||
* Restore a BAGEL saved game
|
||||
*/
|
||||
ErrorCode readSavedGame(int32 slotNum);
|
||||
|
||||
/**
|
||||
* Reads a BAGEL saved game title
|
||||
*/
|
||||
ErrorCode readTitle(int32 lSlot, StSavegameHeader *pSavedGame);
|
||||
|
||||
ErrorCode readTitleOnly(int32 lSlot, char *pGameTitle);
|
||||
};
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
|
||||
#endif
|
||||
422
engines/bagel/spacebar/baglib/sound_object.cpp
Normal file
422
engines/bagel/spacebar/baglib/sound_object.cpp
Normal file
@@ -0,0 +1,422 @@
|
||||
/* 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 "common/file.h"
|
||||
#include "bagel/boflib/event_loop.h"
|
||||
#include "bagel/spacebar/baglib/sound_object.h"
|
||||
#include "bagel/bagel.h"
|
||||
#include "bagel/boflib/file_functions.h"
|
||||
#include "bagel/boflib/log.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
// There is only one allowed at a time
|
||||
CBofSound *CBagSoundObject::_pMidiSound;
|
||||
|
||||
void CBagSoundObject::initialize() {
|
||||
_pMidiSound = nullptr;
|
||||
}
|
||||
|
||||
CBagSoundObject::CBagSoundObject() {
|
||||
_xObjType = SOUND_OBJ;
|
||||
_pSound = nullptr;
|
||||
|
||||
// Assume MIX if not specified
|
||||
_wFlags = SOUND_MIX;
|
||||
|
||||
_nVol = VOLUME_INDEX_DEFAULT;
|
||||
CBagObject::setState(0);
|
||||
_bWait = false;
|
||||
|
||||
_nLoops = 1;
|
||||
|
||||
setVisible(false);
|
||||
CBagObject::setOverCursor(3);
|
||||
}
|
||||
|
||||
CBagSoundObject::~CBagSoundObject() {
|
||||
CBagSoundObject::detach();
|
||||
}
|
||||
|
||||
ErrorCode CBagSoundObject::attach(CBofWindow *pWnd) {
|
||||
newSound(pWnd);
|
||||
|
||||
return CBagObject::attach();
|
||||
}
|
||||
|
||||
void CBagSoundObject::newSound(CBofWindow *pWin) {
|
||||
killSound();
|
||||
|
||||
_pSound = new CBofSound(pWin, getFileName(), _wFlags, _nLoops);
|
||||
_pSound->setVolume(_nVol);
|
||||
_pSound->setQSlot(getState());
|
||||
}
|
||||
|
||||
void CBagSoundObject::killSound() {
|
||||
delete _pSound;
|
||||
_pSound = nullptr;
|
||||
}
|
||||
|
||||
ErrorCode CBagSoundObject::detach() {
|
||||
killSound();
|
||||
return CBagObject::detach();
|
||||
}
|
||||
|
||||
bool CBagSoundObject::runObject() {
|
||||
if (((_wFlags & SOUND_MIDI) && CBagMasterWin::getMidi()) || (((_wFlags & SOUND_WAVE) || (_wFlags & SOUND_MIX)) && CBagMasterWin::getDigitalAudio())) {
|
||||
|
||||
if (_pSound && _pMidiSound != _pSound) {
|
||||
_pSound->setQSlot(getState());
|
||||
_pSound->play();
|
||||
|
||||
// If waiting until this sound finishes
|
||||
if (_bWait) {
|
||||
// Show busy cursor
|
||||
CBagMasterWin::setActiveCursor(6);
|
||||
|
||||
EventLoop limiter(EventLoop::FORCE_REPAINT);
|
||||
while (_pSound->isPlaying()) {
|
||||
CBofSound::audioTask();
|
||||
|
||||
if (limiter.frame()) {
|
||||
_pSound->stop();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (_wFlags & SOUND_MIDI)
|
||||
_pMidiSound = _pSound;
|
||||
} else if (!(_wFlags & SOUND_MIDI)) {
|
||||
/* if no sound */
|
||||
int nExt = getFileName().getLength() - 4; // ".EXT"
|
||||
|
||||
if (nExt <= 0) {
|
||||
logError("Sound does not have a file name or proper extension. Please write better scripts.");
|
||||
return false;
|
||||
}
|
||||
|
||||
CBofString sBaseStr = getFileName().left(nExt) + ".TXT";
|
||||
|
||||
Common::File f;
|
||||
if (fileExists(sBaseStr) && f.open(sBaseStr.getBuffer())) {
|
||||
Common::String line = f.readLine();
|
||||
|
||||
bofMessageBox(line.c_str(), "Using .TXT for missing .WAV!");
|
||||
f.close();
|
||||
return true;
|
||||
}
|
||||
|
||||
logError(buildString("Sound TEXT file could not be read: %s. Why? because we like you ...", getFileName().getBuffer()));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return CBagObject::runObject();
|
||||
}
|
||||
|
||||
ParseCodes CBagSoundObject::setInfo(CBagIfstream &istr) {
|
||||
bool nObjectUpdated = false;
|
||||
|
||||
while (!istr.eof()) {
|
||||
istr.eatWhite(); // Eat any white space between script elements
|
||||
char ch = (char)istr.peek();
|
||||
switch (ch) {
|
||||
|
||||
// VOLUME
|
||||
//
|
||||
case 'V': {
|
||||
char szLocalStr[256];
|
||||
szLocalStr[0] = 0;
|
||||
CBofString sStr(szLocalStr, 256);
|
||||
|
||||
getAlphaNumFromStream(istr, sStr);
|
||||
|
||||
if (!sStr.find("VOLUME")) {
|
||||
istr.eatWhite();
|
||||
int n;
|
||||
getIntFromStream(istr, n);
|
||||
setVolume(n);
|
||||
nObjectUpdated = true;
|
||||
} else {
|
||||
putbackStringOnStream(istr, sStr);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
// AS [WAVE|MIDI] - how to run the link
|
||||
//
|
||||
case 'A': {
|
||||
char szLocalStr[256];
|
||||
szLocalStr[0] = 0;
|
||||
CBofString sStr(szLocalStr, 256); // performance improvement
|
||||
getAlphaNumFromStream(istr, sStr);
|
||||
|
||||
if (!sStr.find("AS")) {
|
||||
|
||||
istr.eatWhite();
|
||||
getAlphaNumFromStream(istr, sStr);
|
||||
|
||||
if (!sStr.find("WAVE")) {
|
||||
setWave();
|
||||
nObjectUpdated = true;
|
||||
|
||||
} else if (!sStr.find("MIDI")) {
|
||||
setMidi();
|
||||
nObjectUpdated = true;
|
||||
|
||||
} else if (!sStr.find("SYNC")) {
|
||||
setSync();
|
||||
nObjectUpdated = true;
|
||||
|
||||
} else if (!sStr.find("ASYNC")) {
|
||||
setASync();
|
||||
nObjectUpdated = true;
|
||||
|
||||
// Mix and Wait
|
||||
//
|
||||
} else if (!sStr.find("WAITMIX")) {
|
||||
|
||||
setMix();
|
||||
_bWait = true;
|
||||
nObjectUpdated = true;
|
||||
|
||||
// Queue and Wait
|
||||
//
|
||||
} else if (!sStr.find("WAITQUEUE")) {
|
||||
|
||||
setQueue();
|
||||
_bWait = true;
|
||||
nObjectUpdated = true;
|
||||
|
||||
} else if (!sStr.find("QUEUE")) {
|
||||
|
||||
setQueue();
|
||||
nObjectUpdated = true;
|
||||
|
||||
} else if (!sStr.find("MIX")) {
|
||||
setMix();
|
||||
nObjectUpdated = true;
|
||||
|
||||
} else {
|
||||
putbackStringOnStream(istr, sStr);
|
||||
putbackStringOnStream(istr, "AS ");
|
||||
}
|
||||
|
||||
} else {
|
||||
putbackStringOnStream(istr, sStr);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
// LOOP PROPERTY FOR SOUNDS
|
||||
case 'L': {
|
||||
char szLocalStr[256];
|
||||
szLocalStr[0] = 0;
|
||||
CBofString sStr(szLocalStr, 256); // performance improvement
|
||||
|
||||
getAlphaNumFromStream(istr, sStr);
|
||||
|
||||
if (!sStr.find("LOOP")) {
|
||||
istr.eatWhite();
|
||||
getIntFromStream(istr, _nLoops);
|
||||
nObjectUpdated = true;
|
||||
} else {
|
||||
putbackStringOnStream(istr, sStr);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
// Oversound attribute for sound object
|
||||
case 'S': {
|
||||
char szLocalStr[256];
|
||||
szLocalStr[0] = 0;
|
||||
CBofString sStr(szLocalStr, 256); // performance improvement
|
||||
|
||||
getAlphaNumFromStream(istr, sStr);
|
||||
|
||||
if (!sStr.find("SOUNDOVEROK")) {
|
||||
setSoundOver();
|
||||
nObjectUpdated = true;
|
||||
} else {
|
||||
putbackStringOnStream(istr, sStr);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
//
|
||||
// No match return from function
|
||||
//
|
||||
default: {
|
||||
ParseCodes parseCode = CBagObject::setInfo(istr);
|
||||
if (parseCode == PARSING_DONE) {
|
||||
return PARSING_DONE;
|
||||
}
|
||||
|
||||
if (parseCode == UPDATED_OBJECT) {
|
||||
nObjectUpdated = true;
|
||||
} else { // rc==UNKNOWN_TOKEN
|
||||
if (nObjectUpdated)
|
||||
return UPDATED_OBJECT;
|
||||
|
||||
return UNKNOWN_TOKEN;
|
||||
}
|
||||
}
|
||||
break;
|
||||
} // end switch
|
||||
|
||||
} // end while
|
||||
|
||||
return PARSING_DONE;
|
||||
}
|
||||
|
||||
void CBagSoundObject::setQueue(bool b) {
|
||||
if (b) {
|
||||
_wFlags = SOUND_MIX | SOUND_QUEUE;
|
||||
|
||||
} else {
|
||||
_wFlags &= ~SOUND_QUEUE;
|
||||
}
|
||||
}
|
||||
|
||||
int CBagSoundObject::getVolume() {
|
||||
return _nVol;
|
||||
}
|
||||
|
||||
void CBagSoundObject::setVolume(int nVol) {
|
||||
_nVol = (byte)nVol;
|
||||
if (isAttached()) {
|
||||
|
||||
if (_pSound != nullptr) {
|
||||
_pSound->setVolume(_nVol);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool CBagSoundObject::isPlaying() {
|
||||
bool bPlaying = false;
|
||||
if (_pSound != nullptr) {
|
||||
bPlaying = _pSound->playing();
|
||||
}
|
||||
|
||||
return bPlaying;
|
||||
}
|
||||
|
||||
bool CBagSoundObject::isQueued() {
|
||||
bool bQueued = false;
|
||||
if (_pSound != nullptr) {
|
||||
bQueued = _pSound->isQueued();
|
||||
}
|
||||
|
||||
return bQueued;
|
||||
}
|
||||
|
||||
void CBagSoundObject::setPlaying(bool bVal) {
|
||||
if (((_wFlags & SOUND_MIDI) && CBagMasterWin::getMidi()) || (((_wFlags & SOUND_WAVE) || (_wFlags & SOUND_MIX)) && CBagMasterWin::getDigitalAudio())) {
|
||||
|
||||
if (bVal) {
|
||||
if (_pSound && _pMidiSound != _pSound) {
|
||||
|
||||
_pSound->setQSlot(getState());
|
||||
_pSound->play();
|
||||
|
||||
// If we are supposed to wait until this audio finishes
|
||||
if (_bWait) {
|
||||
// Show busy cursor
|
||||
CBagMasterWin::setActiveCursor(6);
|
||||
|
||||
EventLoop limiter(EventLoop::FORCE_REPAINT);
|
||||
while (_pSound->isPlaying()) {
|
||||
CBofSound::audioTask();
|
||||
|
||||
if (limiter.frame()) {
|
||||
_pSound->stop();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (_wFlags & SOUND_MIDI)
|
||||
_pMidiSound = _pSound;
|
||||
}
|
||||
} else if (_pSound) {
|
||||
_pSound->stop();
|
||||
if (_wFlags & SOUND_MIDI)
|
||||
_pMidiSound = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CBagSoundObject::setNumOfLoops(int n) {
|
||||
_nLoops = n; // Only have ability to set at creation of BofSound
|
||||
}
|
||||
|
||||
int CBagSoundObject::getProperty(const CBofString &sProp) {
|
||||
if (!sProp.find("VOLUME")) {
|
||||
return getVolume();
|
||||
|
||||
}
|
||||
|
||||
if (!sProp.find("QUEUED")) {
|
||||
return isQueued();
|
||||
|
||||
}
|
||||
|
||||
if (!sProp.find("PLAYING")) {
|
||||
return isPlaying();
|
||||
|
||||
}
|
||||
|
||||
if (!sProp.find("LOOP")) {
|
||||
return _nLoops;
|
||||
}
|
||||
|
||||
return CBagObject::getProperty(sProp);
|
||||
}
|
||||
|
||||
void CBagSoundObject::setProperty(const CBofString &sProp, int nVal) {
|
||||
if (!sProp.find("VOLUME")) {
|
||||
setVolume(nVal);
|
||||
|
||||
} else if (!sProp.find("PLAYING")) {
|
||||
|
||||
if (nVal == 1)
|
||||
setPlaying();
|
||||
else
|
||||
setPlaying(false);
|
||||
|
||||
} else if (!sProp.find("LOOP")) {
|
||||
setNumOfLoops(nVal);
|
||||
} else {
|
||||
CBagObject::setProperty(sProp, nVal);
|
||||
}
|
||||
}
|
||||
|
||||
void CBagSoundObject::setSync(bool b) {
|
||||
_wFlags = SOUND_WAVE;
|
||||
if (!b)
|
||||
_wFlags |= SOUND_ASYNCH;
|
||||
}
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
125
engines/bagel/spacebar/baglib/sound_object.h
Normal file
125
engines/bagel/spacebar/baglib/sound_object.h
Normal file
@@ -0,0 +1,125 @@
|
||||
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BAGEL_BAGLIB_SOUND_OBJECT_H
|
||||
#define BAGEL_BAGLIB_SOUND_OBJECT_H
|
||||
|
||||
#include "bagel/spacebar/baglib/object.h"
|
||||
#include "bagel/spacebar/baglib/bagel.h"
|
||||
#include "bagel/boflib/sound.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
/**
|
||||
* CBagSoundObject is an object that can be place within the slide window.
|
||||
*/
|
||||
class CBagSoundObject : public CBagObject {
|
||||
private:
|
||||
static CBofSound *_pMidiSound; // There is only one allowed at a time
|
||||
CBofSound *_pSound;
|
||||
|
||||
uint16 _wFlags;
|
||||
int _nLoops;
|
||||
byte _nVol;
|
||||
|
||||
protected:
|
||||
byte _bWait;
|
||||
|
||||
public:
|
||||
CBagSoundObject();
|
||||
virtual ~CBagSoundObject();
|
||||
static void initialize();
|
||||
|
||||
void killSound();
|
||||
void newSound(CBofWindow *pWin);
|
||||
|
||||
// Return true if the Object had members that are properly initialized/de-initialized
|
||||
ErrorCode attach() override {
|
||||
return attach((CBofWindow *)CBagel::getBagApp()->getMasterWnd());
|
||||
}
|
||||
ErrorCode attach(CBofWindow *pWnd);
|
||||
bool isAttached() override {
|
||||
return _pSound != nullptr;
|
||||
}
|
||||
ErrorCode detach() override;
|
||||
|
||||
CBofSound *getLastMidi() {
|
||||
return _pMidiSound;
|
||||
}
|
||||
|
||||
CBofSound *getSound() {
|
||||
return _pSound;
|
||||
}
|
||||
|
||||
void setWave() {
|
||||
_wFlags = SOUND_WAVE;
|
||||
}
|
||||
void setMidi() {
|
||||
_wFlags = (SOUND_MIDI | SOUND_LOOP);
|
||||
}
|
||||
|
||||
// Gives ability to sound over certain sounds
|
||||
void setSoundOver() {
|
||||
_wFlags |= SOUND_OVEROK;
|
||||
}
|
||||
|
||||
void setSync(bool b = true);
|
||||
void setASync(bool b = true) {
|
||||
setSync(!b);
|
||||
}
|
||||
bool isSync() {
|
||||
return _wFlags & SOUND_ASYNCH;
|
||||
}
|
||||
|
||||
void setMix() {
|
||||
_wFlags = SOUND_MIX;
|
||||
}
|
||||
void setQueue(bool b = true);
|
||||
|
||||
bool runObject() override;
|
||||
|
||||
void setVolume(int nVol);
|
||||
int getVolume();
|
||||
|
||||
void setNumOfLoops(int n);
|
||||
|
||||
int getProperty(const CBofString &sProp) override;
|
||||
void setProperty(const CBofString &sProp, int nVal) override;
|
||||
|
||||
/**
|
||||
* Takes in info and then removes the relative information and returns
|
||||
* the info without the relevant info.
|
||||
*/
|
||||
ParseCodes setInfo(CBagIfstream &istr) override;
|
||||
|
||||
// Added properties to sound object
|
||||
bool isPlaying();
|
||||
bool isQueued();
|
||||
|
||||
void setPlaying(bool bVal = true);
|
||||
};
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
|
||||
#endif
|
||||
281
engines/bagel/spacebar/baglib/sprite_object.cpp
Normal file
281
engines/bagel/spacebar/baglib/sprite_object.cpp
Normal file
@@ -0,0 +1,281 @@
|
||||
/* 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/sprite_object.h"
|
||||
#include "bagel/spacebar/baglib/bagel.h"
|
||||
#include "bagel/spacebar/baglib/master_win.h"
|
||||
#include "bagel/spacebar/baglib/storage_dev_win.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
CBagSpriteObject::CBagSpriteObject() : CBagObject() {
|
||||
_xObjType = SPRITE_OBJ;
|
||||
_xSprite = nullptr;
|
||||
_nCels = 1;
|
||||
_nWieldCursor = -1;
|
||||
|
||||
// Transparent by default
|
||||
setTransparent();
|
||||
CBagObject::setOverCursor(1);
|
||||
setAnimated();
|
||||
setTimeless(true);
|
||||
|
||||
// implement sprite framerates
|
||||
setFrameRate(0);
|
||||
_nLastUpdate = 0;
|
||||
}
|
||||
|
||||
CBagSpriteObject::~CBagSpriteObject() {
|
||||
CBagSpriteObject::detach();
|
||||
}
|
||||
|
||||
ErrorCode CBagSpriteObject::attach() {
|
||||
// If it's not already attached
|
||||
if (!isAttached()) {
|
||||
// Could not already have a sprite
|
||||
assert(_xSprite == nullptr);
|
||||
|
||||
_xSprite = new CBofSprite();
|
||||
|
||||
if (_xSprite->loadSprite(getFileName(), getCels()) != false && (_xSprite->width() != 0) && (_xSprite->height() != 0)) {
|
||||
if (isTransparent()) {
|
||||
int nMaskColor = CBagel::getBagApp()->getChromaColor();
|
||||
|
||||
_xSprite->setMaskColor(nMaskColor);
|
||||
}
|
||||
|
||||
// Set animated of the sprite to be the same as it's parent
|
||||
_xSprite->setAnimated(isAnimated());
|
||||
|
||||
CBofPoint p = CBagObject::getPosition();
|
||||
|
||||
if (p.x == -1 && p.y == -1) // Fixed to allow for [0,0] positioning
|
||||
setFloating();
|
||||
else
|
||||
_xSprite->setPosition(p.x, p.y);
|
||||
|
||||
setProperty("CURR_CEL", getState());
|
||||
|
||||
// This might add something to the PDA, make sure it gets redrawn.
|
||||
CBagStorageDevWnd *pMainWin = (CBagel::getBagApp()->getMasterWnd()->getCurrentStorageDev());
|
||||
|
||||
if (pMainWin != nullptr) {
|
||||
pMainWin->setPreFilterPan(true);
|
||||
}
|
||||
} else {
|
||||
reportError(ERR_FOPEN, "Could Not Open Sprite: %s", _xSprite->getFileName());
|
||||
}
|
||||
}
|
||||
|
||||
return CBagObject::attach();
|
||||
}
|
||||
|
||||
ErrorCode CBagSpriteObject::detach() {
|
||||
delete _xSprite;
|
||||
_xSprite = nullptr;
|
||||
|
||||
return CBagObject::detach();
|
||||
}
|
||||
|
||||
void CBagSpriteObject::setCels(int nCels) {
|
||||
_nCels = nCels;
|
||||
if (_xSprite)
|
||||
_xSprite->setupCels(nCels);
|
||||
}
|
||||
|
||||
void CBagSpriteObject::setPosition(const CBofPoint &pos) {
|
||||
CBagObject::setPosition(pos);
|
||||
if (_xSprite)
|
||||
_xSprite->setPosition(pos.x, pos.y);
|
||||
}
|
||||
|
||||
CBofRect CBagSpriteObject::getRect() {
|
||||
CBofPoint p = getPosition();
|
||||
CBofSize s;
|
||||
if (_xSprite)
|
||||
s = _xSprite->getSize();
|
||||
return CBofRect(p, s);
|
||||
}
|
||||
|
||||
//
|
||||
// Takes in info and then removes the relative information and returns the info
|
||||
// without the relevant info.
|
||||
ParseCodes CBagSpriteObject::setInfo(CBagIfstream &istr) {
|
||||
bool nObjectUpdated = false;
|
||||
|
||||
while (!istr.eof()) {
|
||||
istr.eatWhite(); // not sure why this WAS NOT here.
|
||||
|
||||
char ch = (char)istr.peek();
|
||||
switch (ch) {
|
||||
//
|
||||
// +n - n number of slides in sprite
|
||||
//
|
||||
case '+': {
|
||||
int cels;
|
||||
istr.getCh();
|
||||
getIntFromStream(istr, cels);
|
||||
setCels(cels);
|
||||
nObjectUpdated = true;
|
||||
}
|
||||
break;
|
||||
case '#': {
|
||||
int curs;
|
||||
istr.getCh();
|
||||
getIntFromStream(istr, curs);
|
||||
setWieldCursor(curs);
|
||||
nObjectUpdated = true;
|
||||
}
|
||||
break;
|
||||
case 'N': {
|
||||
// NOANIM
|
||||
char szLocalStr[256];
|
||||
szLocalStr[0] = 0;
|
||||
CBofString sStr(szLocalStr, 256); // performance improvement
|
||||
getAlphaNumFromStream(istr, sStr);
|
||||
|
||||
if (!sStr.find("NOANIM")) {
|
||||
istr.eatWhite();
|
||||
setAnimated(false);
|
||||
nObjectUpdated = true;
|
||||
} else {
|
||||
putbackStringOnStream(istr, sStr);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
// handle a maximum framerate...
|
||||
case 'F': {
|
||||
// NOANIM
|
||||
char szLocalStr[256];
|
||||
szLocalStr[0] = 0;
|
||||
CBofString sStr(szLocalStr, 256);
|
||||
getAlphaNumFromStream(istr, sStr);
|
||||
|
||||
if (!sStr.find("FRAMERATE")) {
|
||||
int nFrameRate;
|
||||
istr.eatWhite();
|
||||
getIntFromStream(istr, nFrameRate);
|
||||
|
||||
// The frame rate is expressed in frames/second, so do some division
|
||||
// here to store the number of milliseconds.
|
||||
setFrameRate(1000 / nFrameRate);
|
||||
|
||||
nObjectUpdated = true;
|
||||
} else {
|
||||
putbackStringOnStream(istr, sStr);
|
||||
}
|
||||
}
|
||||
break;
|
||||
//
|
||||
// no match return from function
|
||||
//
|
||||
default: {
|
||||
ParseCodes parseCode = CBagObject::setInfo(istr);
|
||||
if (parseCode == PARSING_DONE) {
|
||||
return PARSING_DONE;
|
||||
}
|
||||
|
||||
if (parseCode == UPDATED_OBJECT) {
|
||||
nObjectUpdated = true;
|
||||
} else { // rc==UNKNOWN_TOKEN
|
||||
if (nObjectUpdated)
|
||||
return UPDATED_OBJECT;
|
||||
|
||||
return UNKNOWN_TOKEN;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return PARSING_DONE;
|
||||
}
|
||||
|
||||
ErrorCode CBagSpriteObject::update(CBofBitmap *pBmp, CBofPoint pt, CBofRect * /*pSrcRect*/, int) {
|
||||
if (_xSprite) {
|
||||
int nFrameInterval = getFrameRate();
|
||||
|
||||
if (nFrameInterval != 0) {
|
||||
uint32 nCurTime = getTimer();
|
||||
if (nCurTime > _nLastUpdate + nFrameInterval) {
|
||||
_xSprite->setBlockAdvance(false);
|
||||
_nLastUpdate = nCurTime;
|
||||
} else {
|
||||
_xSprite->setBlockAdvance(true);
|
||||
}
|
||||
}
|
||||
|
||||
bool bPaintResult = _xSprite->paintSprite(pBmp, pt.x, pt.y);
|
||||
|
||||
// Don't have to redraw this item...
|
||||
// setDirty (false);
|
||||
|
||||
if (!bPaintResult)
|
||||
return ERR_UNKNOWN;
|
||||
}
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
bool CBagSpriteObject::isInside(const CBofPoint &xPoint) {
|
||||
if (_xSprite && getRect().ptInRect(xPoint)) {
|
||||
if (isTransparent()) {
|
||||
int x = xPoint.x - getRect().left;
|
||||
int y = xPoint.y - getRect().top;
|
||||
int c = _xSprite->readPixel(x, y);
|
||||
int d = _xSprite->getMaskColor();
|
||||
return (c != d);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void CBagSpriteObject::setProperty(const CBofString &sProp, int nVal) {
|
||||
if (!sProp.find("STATE") || !sProp.find("CURR_CEL")) {
|
||||
setState(nVal);
|
||||
if (_xSprite)
|
||||
_xSprite->setCel(nVal);
|
||||
} else
|
||||
CBagObject::setProperty(sProp, nVal);
|
||||
}
|
||||
|
||||
int CBagSpriteObject::getProperty(const CBofString &sProp) {
|
||||
if (!sProp.find("CURR_CEL")) {
|
||||
if (_xSprite) {
|
||||
return _xSprite->getCelIndex();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
return CBagObject::getProperty(sProp);
|
||||
}
|
||||
|
||||
void CBagSpriteObject::setAnimated(bool b) {
|
||||
_bAnimated = b;
|
||||
if (_xSprite)
|
||||
_xSprite->setAnimated(b);
|
||||
}
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
97
engines/bagel/spacebar/baglib/sprite_object.h
Normal file
97
engines/bagel/spacebar/baglib/sprite_object.h
Normal file
@@ -0,0 +1,97 @@
|
||||
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BAGEL_BAGLIB_SPRITE_OBJECT_H
|
||||
#define BAGEL_BAGLIB_SPRITE_OBJECT_H
|
||||
|
||||
#include "bagel/spacebar/baglib/object.h"
|
||||
#include "bagel/spacebar/boflib/gfx/sprite.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
/**
|
||||
* CBagSpriteObject is an object that can be place within the slide window.
|
||||
*/
|
||||
class CBagSpriteObject : public CBagObject {
|
||||
private:
|
||||
CBofSprite *_xSprite;
|
||||
int _nCels;
|
||||
int _nWieldCursor; // Ref Id for the objects over cursor
|
||||
bool _bAnimated : 1;
|
||||
int _nMaxFrameRate;
|
||||
|
||||
public:
|
||||
CBagSpriteObject();
|
||||
virtual ~CBagSpriteObject();
|
||||
|
||||
ErrorCode attach() override;
|
||||
ErrorCode detach() override;
|
||||
bool isAttached() override {
|
||||
return _xSprite != nullptr;
|
||||
}
|
||||
ParseCodes setInfo(CBagIfstream &istr) override;
|
||||
|
||||
bool isInside(const CBofPoint &xPoint) override;
|
||||
|
||||
int getWieldCursor() const {
|
||||
return _nWieldCursor;
|
||||
}
|
||||
void setWieldCursor(int n) {
|
||||
_nWieldCursor = n;
|
||||
}
|
||||
|
||||
CBofSprite *getSprite() const {
|
||||
return _xSprite;
|
||||
}
|
||||
CBofRect getRect() override;
|
||||
int getCels() const {
|
||||
return _nCels;
|
||||
}
|
||||
|
||||
bool isAnimated() const {
|
||||
return _bAnimated;
|
||||
}
|
||||
|
||||
void setAnimated(bool b = true);
|
||||
void setCels(int nCels);
|
||||
void setPosition(const CBofPoint &pos) override;
|
||||
|
||||
ErrorCode update(CBofBitmap *pBmp, CBofPoint pt, CBofRect *pSrcRect = nullptr, int /*nMaskColor*/ = -1) override;
|
||||
|
||||
void setProperty(const CBofString &sProp, int nVal) override;
|
||||
int getProperty(const CBofString &sProp) override;
|
||||
|
||||
int getFrameRate() const {
|
||||
return _nMaxFrameRate;
|
||||
}
|
||||
void setFrameRate(int nFR) {
|
||||
_nMaxFrameRate = nFR;
|
||||
}
|
||||
|
||||
uint32 _nLastUpdate;
|
||||
};
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
|
||||
#endif
|
||||
157
engines/bagel/spacebar/baglib/storage_dev_bmp.cpp
Normal file
157
engines/bagel/spacebar/baglib/storage_dev_bmp.cpp
Normal file
@@ -0,0 +1,157 @@
|
||||
/* 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_bmp.h"
|
||||
#include "bagel/spacebar/baglib/bagel.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
CBagStorageDevBmp::CBagStorageDevBmp(CBofWindow *pParent, const CBofRect &xRect, bool bTrans)
|
||||
: CBagBmpObject() {
|
||||
_cSrcRect.setRect(0, 0, 0, 0);
|
||||
_bTrans = bTrans;
|
||||
_xSDevType = SDEV_BMP;
|
||||
setRect(xRect);
|
||||
_pWorkBmp = nullptr;
|
||||
_nMaskColor = CBagel::getBagApp()->getChromaColor();
|
||||
|
||||
CBagStorageDev::setAssociateWnd(pParent);
|
||||
|
||||
setVisible(); // This object is visible
|
||||
}
|
||||
|
||||
CBagStorageDevBmp::~CBagStorageDevBmp() {
|
||||
// Delete any current work bmp
|
||||
killWorkBmp();
|
||||
}
|
||||
|
||||
ErrorCode CBagStorageDevBmp::attach() {
|
||||
_nMaskColor = CBagel::getBagApp()->getChromaColor();
|
||||
return CBagStorageDev::attach();
|
||||
}
|
||||
|
||||
|
||||
ErrorCode CBagStorageDevBmp::detach() {
|
||||
killWorkBmp();
|
||||
return CBagStorageDev::detach();
|
||||
}
|
||||
|
||||
ErrorCode CBagStorageDevBmp::setBackground(CBofBitmap *pBmp) {
|
||||
if (pBmp != nullptr) {
|
||||
setBitmap(pBmp);
|
||||
setWorkBmp();
|
||||
} else {
|
||||
// Hope and pray that this is the right thing to do
|
||||
if (getBitmap()) {
|
||||
delete getBitmap();
|
||||
}
|
||||
|
||||
setBitmap(nullptr);
|
||||
killWorkBmp();
|
||||
}
|
||||
|
||||
return _errCode;
|
||||
}
|
||||
|
||||
ErrorCode CBagStorageDevBmp::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 CBagStorageDevBmp::killWorkBmp() {
|
||||
delete _pWorkBmp;
|
||||
_pWorkBmp = nullptr;
|
||||
|
||||
return _errCode;
|
||||
}
|
||||
|
||||
ErrorCode CBagStorageDevBmp::loadFileFromStream(CBagIfstream &fpInput, const CBofString &sWldName, bool bAttach) {
|
||||
setFileName(sWldName);
|
||||
setRefName(sWldName);
|
||||
|
||||
return CBagStorageDev::loadFileFromStream(fpInput, sWldName, bAttach);
|
||||
}
|
||||
|
||||
void CBagStorageDevBmp::onLButtonDown(uint32 nFlags, CBofPoint *xPoint, void *info) {
|
||||
CBagStorageDev::onLButtonDown(nFlags, xPoint, info);
|
||||
}
|
||||
|
||||
void CBagStorageDevBmp::onLButtonUp(uint32 nFlags, CBofPoint *xPoint, void *info) {
|
||||
CBagStorageDev::onLButtonUp(nFlags, xPoint, info);
|
||||
}
|
||||
|
||||
const CBofPoint CBagStorageDevBmp::devPtToViewPort(const CBofPoint &xPoint) {
|
||||
// Get the storage device rect
|
||||
CBofRect SDevDstRect = getRect();
|
||||
|
||||
// move point relative to storage device top, left
|
||||
CBofPoint p;
|
||||
p.x = xPoint.x - SDevDstRect.left;
|
||||
p.y = xPoint.y - SDevDstRect.top;
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
ErrorCode CBagStorageDevBmp::update(CBofBitmap *pBmp, CBofPoint /*xPoint*/, CBofRect * /*pSrcRect*/, int /*nMaskColor*/) {
|
||||
// if this object is visible
|
||||
if (isVisible() && isAttached()) {
|
||||
// Paint the storage device
|
||||
CBofBitmap *pSrcBmp = getBitmap();
|
||||
if (pSrcBmp != nullptr) {
|
||||
assert(getWorkBmp() != nullptr);
|
||||
// Erase everything from the background
|
||||
getWorkBmp()->paint(pSrcBmp);
|
||||
|
||||
// Paint all the objects to the background
|
||||
CBofRect r = pSrcBmp->getRect();
|
||||
paintStorageDevice(nullptr, pSrcBmp, &r);
|
||||
|
||||
// Paint child storage devices
|
||||
paintFGObjects(pSrcBmp);
|
||||
|
||||
// Paint to screen
|
||||
if (_bTrans)
|
||||
pSrcBmp->paint(pBmp, getPosition().x, getPosition().y, nullptr, _nMaskColor);
|
||||
else
|
||||
pSrcBmp->paint(pBmp, getPosition().x, getPosition().y, nullptr, -1);
|
||||
}
|
||||
}
|
||||
|
||||
// Set the firstpaint flag and attach objects to allow for immediate run objects to run
|
||||
if (_bFirstPaint) {
|
||||
_bFirstPaint = false;
|
||||
attachActiveObjects();
|
||||
}
|
||||
|
||||
return _errCode;
|
||||
}
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
108
engines/bagel/spacebar/baglib/storage_dev_bmp.h
Normal file
108
engines/bagel/spacebar/baglib/storage_dev_bmp.h
Normal file
@@ -0,0 +1,108 @@
|
||||
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BAGEL_BAGLIB_STORAGE_DEV_BMP_H
|
||||
#define BAGEL_BAGLIB_STORAGE_DEV_BMP_H
|
||||
|
||||
#include "bagel/spacebar/baglib/bmp_object.h"
|
||||
#include "bagel/spacebar/baglib/storage_dev_win.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
class CBagStorageDevBmp : public CBagBmpObject, public CBagStorageDev {
|
||||
protected:
|
||||
int _nMaskColor;
|
||||
CBofPoint _xCursorLocation; // Current cursor location in bmp.
|
||||
CBofRect _cSrcRect;
|
||||
bool _bTrans;
|
||||
CBofBitmap *_pWorkBmp;
|
||||
|
||||
public:
|
||||
CBagStorageDevBmp(CBofWindow *pParent = nullptr, const CBofRect &xRect = CBofRect(), bool bTrans = true);
|
||||
virtual ~CBagStorageDevBmp();
|
||||
|
||||
CBofBitmap *getWorkBmp() const {
|
||||
return _pWorkBmp;
|
||||
}
|
||||
ErrorCode setWorkBmp();
|
||||
ErrorCode killWorkBmp();
|
||||
|
||||
CBofRect getRect() override {
|
||||
return CBagStorageDev::getRect();
|
||||
}
|
||||
void setRect(const CBofRect &xRect) override {
|
||||
CBagStorageDev::setRect(xRect);
|
||||
}
|
||||
CBofPoint getPosition() override {
|
||||
return CBagStorageDev::getPosition();
|
||||
}
|
||||
void setPosition(const CBofPoint &pos) override {
|
||||
CBagStorageDev::setPosition(pos);
|
||||
}
|
||||
|
||||
bool getTransparent() const {
|
||||
return _bTrans;
|
||||
}
|
||||
void setTransparent(bool bTrans = true) override {
|
||||
_bTrans = bTrans;
|
||||
}
|
||||
|
||||
ErrorCode setBackground(CBofBitmap *pBmp) override;
|
||||
CBofBitmap *getBackground() override {
|
||||
return getBitmap();
|
||||
}
|
||||
|
||||
ErrorCode loadFileFromStream(CBagIfstream &fpInput, const CBofString &sWldName, bool bAttach = true) override;
|
||||
|
||||
bool isAttached() override {
|
||||
return CBagBmpObject::isAttached();
|
||||
}
|
||||
|
||||
virtual bool paintFGObjects(CBofBitmap *) {
|
||||
return true;
|
||||
}
|
||||
|
||||
ErrorCode attach() override;
|
||||
ErrorCode detach() override;
|
||||
|
||||
ErrorCode update(CBofBitmap *pBmp, CBofPoint pt, CBofRect *pSrcRect = nullptr, int nMaskColor = -1) override;
|
||||
|
||||
/**
|
||||
* Called on the mouse left button up of the bagbmobj
|
||||
* and redirected to the lbutton up of the CBagStorageDev
|
||||
*/
|
||||
void onLButtonUp(uint32 nFlags, CBofPoint *xPoint, void *info) override;
|
||||
|
||||
/**
|
||||
* Called on the mouse left button down of the bagbmobj
|
||||
* and redirected to the lbutton down of the CBagStorageDev
|
||||
*/
|
||||
void onLButtonDown(uint32 nFlags, CBofPoint *xPoint, void *info = nullptr) override;
|
||||
|
||||
const CBofPoint devPtToViewPort(const CBofPoint &xPoint) override;
|
||||
};
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
|
||||
#endif
|
||||
2049
engines/bagel/spacebar/baglib/storage_dev_win.cpp
Normal file
2049
engines/bagel/spacebar/baglib/storage_dev_win.cpp
Normal file
File diff suppressed because it is too large
Load Diff
587
engines/bagel/spacebar/baglib/storage_dev_win.h
Normal file
587
engines/bagel/spacebar/baglib/storage_dev_win.h
Normal file
@@ -0,0 +1,587 @@
|
||||
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BAGEL_BAGLIB_STORAGE_DEV_WIN_H
|
||||
#define BAGEL_BAGLIB_STORAGE_DEV_WIN_H
|
||||
|
||||
#include "bagel/spacebar/boflib/gui/dialog.h"
|
||||
#include "bagel/spacebar/boflib/list.h"
|
||||
#include "bagel/spacebar/baglib/object.h"
|
||||
#include "bagel/spacebar/baglib/save_game_file.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
#define SDEV_UNDEF 00
|
||||
#define SDEV_WND 11
|
||||
#define SDEV_DLG 22
|
||||
#define SDEV_BMP 33
|
||||
#define SDEV_PDA 44
|
||||
#define SDEV_WIELD 55
|
||||
#define SDEV_CLOSEP 66
|
||||
#define SDEV_GAMEWIN 77
|
||||
#define SDEV_ZOOMPDA 88
|
||||
|
||||
/**
|
||||
* CResource is an encapsulation of resources.
|
||||
*/
|
||||
class CResource {
|
||||
private:
|
||||
const char *_lpszResourceName;
|
||||
uint32 _nResId;
|
||||
|
||||
public:
|
||||
CResource() {
|
||||
_lpszResourceName = nullptr;
|
||||
_nResId = 0;
|
||||
}
|
||||
|
||||
void setResource(const char *lpszResourceName) {
|
||||
_lpszResourceName = lpszResourceName;
|
||||
}
|
||||
void setResource(uint32 nResId) {
|
||||
_nResId = nResId;
|
||||
}
|
||||
const char *getResourceName() const {
|
||||
return _lpszResourceName;
|
||||
}
|
||||
uint32 getResourceId() const {
|
||||
return _nResId;
|
||||
}
|
||||
};
|
||||
|
||||
// Filter function function prototype.
|
||||
typedef bool (*FilterFunction)(uint16 nFilterId, CBofBitmap *, CBofRect *);
|
||||
|
||||
/**
|
||||
* CBagPanWindow is a window that contains a slide bitmap object. It has specialize
|
||||
* functions for handling slide bitmaps and slide objects.
|
||||
*/
|
||||
class CBagStorageDev : public CBagParseObject {
|
||||
public:
|
||||
enum MouseActivity {
|
||||
kMouseNONE = 0x0000, kMouseDRAGGING = 0x0001
|
||||
};
|
||||
|
||||
private:
|
||||
CBofString _sName; // Name of this storage device
|
||||
CBofString _sBackgroundName; // Name of this storage devices background
|
||||
CBofString _sPrevSDev; // Name of the previous storage device
|
||||
|
||||
CBofRect _cDestRect; // Position of storage device
|
||||
CBofPoint _xPrevLocation; // Previous view location in bmp.
|
||||
|
||||
CBagObject *_pLActiveObject; // The last object selected on mouse down
|
||||
// CBagObject *_pRActiveObject; // The last object selected on mouse down
|
||||
|
||||
CBofList<CBagObject *> *_pObjectList; // Objects to be painted to the pan
|
||||
CBofList<CBagExpression *> *_pExpressionList; // Condition for painting to the pan
|
||||
|
||||
CBofWindow *_pAssociateWnd; // Sounds need a window
|
||||
|
||||
MouseActivity _nCurrMouseActivity; // What is up with the mouse currently
|
||||
|
||||
uint16 _nExitOnEdge; // Non zero if SDev should be closed when an outside edge is clicked on, and and prev sdev is set, _nExitOnEdge is the thickness of the edge
|
||||
|
||||
uint16 _nFilterId; // Filter id number 0 for normal view
|
||||
uint16 _nFadeId; // Fade id number 0 for no fade in
|
||||
uint16 _nDiskID;
|
||||
|
||||
protected:
|
||||
uint16 _xSDevType; // Type of storage device
|
||||
static CBofPoint *_xCursorLocation; // Current cursor location in bmp.
|
||||
static CBofRect *gRepaintRect;
|
||||
static bool _bHandledUpEvent; // Hack to stop
|
||||
static bool _hidePdaFl;
|
||||
FilterFunction _pBitmapFilter; // Pointer to the bitmap filter.
|
||||
|
||||
bool _bForeignList : true; // True if setObjectList has been called
|
||||
bool _bCloseOnOpen : true; // True if other SDev should be closed when this is opened
|
||||
bool _bCloseup : true; // true if is a closeup (includes CIC, or CHAT)
|
||||
bool _bCIC : true; // true if is a CIC
|
||||
bool _bCustom : true; // true if is a hand coded closeup
|
||||
bool _bFirstPaint : true; // run object stuff
|
||||
|
||||
static bool _bPanPreFiltered; // Let pda know if screens been prefiltered
|
||||
static bool _bDirtyAllObjects; // Dirty all objects in prefilter?
|
||||
static bool _bPreFilter;
|
||||
|
||||
int _nFloatPages; // The number of pages required to display all floating objects
|
||||
|
||||
public:
|
||||
CBagStorageDev();
|
||||
virtual ~CBagStorageDev();
|
||||
|
||||
virtual ErrorCode preFilter(CBofBitmap *pBmp, CBofRect *pRect, CBofList<CBagObject *> *pList = nullptr);
|
||||
|
||||
static void initialize();
|
||||
static void shutdown();
|
||||
|
||||
/**
|
||||
* Make all the objects in a list dirty
|
||||
*/
|
||||
void makeListDirty(CBofList<CBagObject *> *pList);
|
||||
|
||||
void setDiskID(uint16 nDiskID) {
|
||||
_nDiskID = nDiskID;
|
||||
}
|
||||
uint16 getDiskID() const {
|
||||
return _nDiskID;
|
||||
}
|
||||
|
||||
virtual ErrorCode setloadFilePos(const CBofPoint) {
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
bool isCloseup() const {
|
||||
return _bCloseup;
|
||||
}
|
||||
void setCloseup(bool b = true) {
|
||||
_bCloseup = b;
|
||||
}
|
||||
|
||||
// Set true if sdef is "AS CIC"
|
||||
bool isCIC();
|
||||
void setCIC(bool b = true) {
|
||||
_bCIC = b;
|
||||
}
|
||||
|
||||
// Set to true if this is a hand coded closeup
|
||||
bool isCustom() const {
|
||||
return _bCustom;
|
||||
}
|
||||
void setCustom(bool b = true) {
|
||||
_bCustom = b;
|
||||
}
|
||||
|
||||
int getDeviceType() const {
|
||||
return _xSDevType;
|
||||
}
|
||||
|
||||
int getObjectCount();
|
||||
CBagObject *getObjectByPos(int nIndex);
|
||||
CBagObject *getObject(int nRefId, bool bActiveOnly = false);
|
||||
CBagObject *getObject(const CBofPoint &xPoint, bool bActiveOnly = false);
|
||||
CBagObject *getObject(const CBofString &sName, bool bActiveOnly = false);
|
||||
CBagObject *getObjectByType(const CBofString &sType, bool bActiveOnly = false);
|
||||
|
||||
static CBofPoint &getLastCursorLocation() {
|
||||
return *_xCursorLocation;
|
||||
}
|
||||
CBofList<CBagObject *> *getObjectList() const {
|
||||
return _pObjectList;
|
||||
}
|
||||
void setObjectList(CBofList<CBagObject *> *pOList, CBofList<CBagExpression *> *pEList = nullptr);
|
||||
|
||||
bool contains(CBagObject *pObj, bool bActive = true);
|
||||
|
||||
// virtual CBofRect getLocation() { return CBofRect(); }
|
||||
virtual CBofRect getRect() {
|
||||
return _cDestRect;
|
||||
}
|
||||
|
||||
virtual void setRect(const CBofRect &xRect) {
|
||||
_cDestRect = xRect;
|
||||
}
|
||||
|
||||
virtual CBofPoint getPosition() {
|
||||
return _cDestRect.topLeft();
|
||||
}
|
||||
|
||||
virtual void setPosition(const CBofPoint &pos);
|
||||
|
||||
virtual ErrorCode addObject(CBagObject *pObj, int nPos = 0); // Add a new object
|
||||
virtual ErrorCode activateLocalObject(CBagObject *pObj);
|
||||
virtual ErrorCode activateLocalObject(const CBofString &sName);
|
||||
virtual ErrorCode attachActiveObjects();
|
||||
|
||||
virtual ErrorCode removeObject(CBagObject *pRObj);
|
||||
virtual ErrorCode deactivateLocalObject(CBagObject *pObj);
|
||||
virtual ErrorCode deactivateLocalObject(const CBofString &sName);
|
||||
virtual ErrorCode detachActiveObjects();
|
||||
|
||||
virtual void setHelpFilename(const CBofString &) {
|
||||
}
|
||||
|
||||
const CBofString &getName() const {
|
||||
return _sName;
|
||||
}
|
||||
void setName(const CBofString &str) {
|
||||
_sName = str;
|
||||
}
|
||||
|
||||
void setFilterId(uint16 nId) {
|
||||
_nFilterId = nId;
|
||||
}
|
||||
uint16 getFilterId() const {
|
||||
return _nFilterId;
|
||||
}
|
||||
|
||||
void setFadeId(uint16 nId) {
|
||||
_nFadeId = nId;
|
||||
}
|
||||
uint16 getFadeId() const {
|
||||
return _nFadeId;
|
||||
}
|
||||
|
||||
const CBofString &getPrevSDev() const {
|
||||
return _sPrevSDev;
|
||||
}
|
||||
const CBofPoint getPrevLoc() const {
|
||||
return _xPrevLocation;
|
||||
}
|
||||
void setPrevSDev(const CBofString &str) {
|
||||
_sPrevSDev = str;
|
||||
}
|
||||
|
||||
bool getCloseOnOpen() const {
|
||||
return _bCloseOnOpen;
|
||||
}
|
||||
void setCloseOnOpen(bool bVal) {
|
||||
_bCloseOnOpen = bVal;
|
||||
}
|
||||
|
||||
uint16 getExitOnEdge() const {
|
||||
return _nExitOnEdge;
|
||||
}
|
||||
void setExitOnEdge(uint16 nVal) {
|
||||
_nExitOnEdge = nVal;
|
||||
}
|
||||
|
||||
CBagObject *getLActiveObject() const {
|
||||
return _pLActiveObject;
|
||||
}
|
||||
// CBagObject* GetRActiveObject() { return _pRActiveObject; }
|
||||
ErrorCode setLActiveObject(CBagObject *pObj) {
|
||||
_pLActiveObject = pObj;
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
virtual ErrorCode onLActiveObject(uint32 /*nFlags*/, CBofPoint */*xPoint*/, void * = nullptr);
|
||||
|
||||
MouseActivity getLActivity() const {
|
||||
return _nCurrMouseActivity;
|
||||
}
|
||||
void setLActivity(MouseActivity ma) {
|
||||
_nCurrMouseActivity = ma;
|
||||
}
|
||||
|
||||
ErrorCode paintStorageDevice(CBofWindow *pWnd, CBofBitmap *pBmp = nullptr, CBofRect * = nullptr);
|
||||
|
||||
// The associated window describes which window to get screen information from and
|
||||
// where to paint objects and most importantly what info to send to the callbacks
|
||||
virtual void setAssociateWnd(CBofWindow *pWnd) {
|
||||
_pAssociateWnd = pWnd;
|
||||
}
|
||||
virtual CBofWindow *getAssociateWnd() {
|
||||
return _pAssociateWnd;
|
||||
}
|
||||
|
||||
ParseCodes setInfo(CBagIfstream &fpInput) override; // This function call the pure virt set background
|
||||
|
||||
virtual ErrorCode setBackground(CBofBitmap *pBmp) = 0; // This could be eliminated but is kept in to insure good class usage
|
||||
virtual CBofBitmap *getBackground() = 0; // Think about it, you can figure this out
|
||||
const CBofString &getBackgroundName() const {
|
||||
return _sBackgroundName;
|
||||
}
|
||||
|
||||
ErrorCode attach() override; // This function attaches the background and necessary bitmaps
|
||||
ErrorCode detach() override; // This function attaches the background and necessary bitmaps
|
||||
|
||||
virtual ErrorCode close();
|
||||
|
||||
virtual ErrorCode loadObjects();
|
||||
virtual ErrorCode releaseObjects();
|
||||
virtual ErrorCode noObjectsUnderMouse();
|
||||
|
||||
virtual const CBofPoint devPtToViewPort(const CBofPoint &xPoint) {
|
||||
return xPoint;
|
||||
}
|
||||
virtual const CBofPoint viewPortToDevPt(const CBofPoint &xPoint) {
|
||||
return xPoint;
|
||||
}
|
||||
|
||||
virtual ErrorCode loadFile(const CBofString &sWldName);
|
||||
virtual ErrorCode loadFileFromStream(CBagIfstream &fpInput, const CBofString &sWldName, bool bAttach = true);
|
||||
|
||||
virtual void onMouseMove(uint32 /*nFlags*/, CBofPoint */*xPoint*/, void * = nullptr);
|
||||
virtual ErrorCode onMouseOver(uint32 /*nFlags*/, CBofPoint */*xPoint*/, void * = nullptr);
|
||||
virtual void onLButtonDown(uint32 /*nFlags*/, CBofPoint */*xPoint*/, void * = nullptr);
|
||||
virtual void onLButtonUp(uint32 /*nFlags*/, CBofPoint */*xPoint*/, void * = nullptr);
|
||||
|
||||
virtual ErrorCode onCursorUpdate(int /*nCurrObj*/) {
|
||||
return ERR_NONE;
|
||||
}
|
||||
virtual CBagObject *onNewSpriteObject(const CBofString &sInit);
|
||||
virtual CBagObject *onNewBitmapObject(const CBofString &sInit);
|
||||
virtual CBagObject *onNewTextObject(const CBofString &sInit);
|
||||
virtual CBagObject *onNewLinkObject(const CBofString &sInit);
|
||||
virtual CBagObject *onNewRPObject(const CBofString &sInit);
|
||||
virtual CBagObject *onNewEDObject(const CBofString &sInit);
|
||||
virtual CBagObject *onNewDosObject(const CBofString &sInit);
|
||||
virtual CBagObject *onNewSoundObject(const CBofString &sInit);
|
||||
virtual CBagObject *onNewButtonObject(const CBofString &sInit);
|
||||
virtual CBagObject *onNewCharacterObject(const CBofString &sInit);
|
||||
virtual CBagObject *onNewMovieObject(const CBofString &);
|
||||
virtual CBagObject *onNewCommandObject(const CBofString &sInit);
|
||||
virtual CBagObject *onNewAreaObject(const CBofString &sInit);
|
||||
virtual CBagObject *onNewExpressionObject(const CBofString &sInit);
|
||||
virtual CBagObject *onNewVariableObject(const CBofString &sInit);
|
||||
virtual CBagObject *onNewUserObject(const CBofString &sInit);
|
||||
virtual CBagObject *onNewThingObject(const CBofString &sInit);
|
||||
|
||||
// Call to arrange floating object, override to customize layout
|
||||
virtual CBofPoint arrangeFloater(CBofPoint &nPos, CBagObject *pObj);
|
||||
|
||||
// Set and Get the number of pages required to display all floating objects
|
||||
int getNumFloatPages() const {
|
||||
return _nFloatPages;
|
||||
}
|
||||
void setNumFloatPages(int nFloatPages) {
|
||||
_nFloatPages = nFloatPages;
|
||||
}
|
||||
|
||||
// Correctly set the filter function for the storage device.
|
||||
//
|
||||
void onSetFilter(bool (*filterFunction)(uint16 nFilterId, CBofBitmap *, CBofRect *));
|
||||
|
||||
// Get a pointer to the filter function
|
||||
//
|
||||
FilterFunction getFilter();
|
||||
|
||||
// Predicate to test if this storage device is filtered.
|
||||
//
|
||||
bool isFiltered() const {
|
||||
return _nFilterId != 0;
|
||||
}
|
||||
|
||||
// Provide a method to get at the above vars
|
||||
static void setDirtyAllObjects(bool b) {
|
||||
_bDirtyAllObjects = b;
|
||||
}
|
||||
static bool getDirtyAllObjects() {
|
||||
return _bDirtyAllObjects;
|
||||
}
|
||||
|
||||
// Provide a method to let PDA know that it should update everything
|
||||
static void setPreFiltered(bool b = true) {
|
||||
_bPanPreFiltered = b;
|
||||
}
|
||||
static bool getPreFiltered() {
|
||||
return _bPanPreFiltered;
|
||||
}
|
||||
|
||||
// We won't always call the prefilter, just when explicitly instructed to.
|
||||
static bool preFilterPan() {
|
||||
return _bPreFilter;
|
||||
}
|
||||
static void setPreFilterPan(bool b = true) {
|
||||
_bPreFilter = b;
|
||||
_bDirtyAllObjects = b;
|
||||
}
|
||||
};
|
||||
|
||||
class CBagEventSDev;
|
||||
|
||||
//
|
||||
// CBagStorageDevWnd -
|
||||
// CBagPanWindow is a window that contains a slide bitmap object. It has specialize
|
||||
// functions for handling slide bitmaps and slide objects.
|
||||
//
|
||||
class CBagStorageDevWnd : public CBofWindow, public CBagStorageDev {
|
||||
private:
|
||||
//bool _bMadeSelection;
|
||||
bool _bOnUpdate;
|
||||
CBofBitmap *_pWorkBmp;
|
||||
CBofString _sHelpFileName; // Name of the help file for this device
|
||||
|
||||
public:
|
||||
static CBagEventSDev *_pEvtSDev; // Pointer to the Event Storage Device
|
||||
|
||||
CBagStorageDevWnd();
|
||||
virtual ~CBagStorageDevWnd();
|
||||
static void initialize() {
|
||||
_pEvtSDev = nullptr;
|
||||
}
|
||||
|
||||
ErrorCode attach() override; // This function attaches the background and necessary bitmaps
|
||||
ErrorCode detach() override; // This function attaches the background and necessary bitmaps
|
||||
|
||||
ErrorCode close() override;
|
||||
virtual ErrorCode runModal(CBagObject *pObj);
|
||||
void onTimer(uint32 nEventID) override;
|
||||
|
||||
void setOnUpdate(bool bVal = true) {
|
||||
_bOnUpdate = bVal;
|
||||
}
|
||||
bool getOnUpdate() const {
|
||||
return _bOnUpdate;
|
||||
}
|
||||
|
||||
virtual ErrorCode paintScreen(CBofRect *pRect = nullptr);
|
||||
virtual ErrorCode paintObjects(CBofList<CBagObject *> *list, CBofBitmap *pBmp,
|
||||
CBofRect &viewOffsetRect, CBofList<CBofRect> * = nullptr, bool tempVar = true);
|
||||
|
||||
virtual CBofRect getLocation() {
|
||||
return getWindowRect();
|
||||
}
|
||||
|
||||
ErrorCode setBackground(CBofBitmap *pBmp) override;
|
||||
|
||||
CBofBitmap *getBackground() override {
|
||||
return getBackdrop();
|
||||
}
|
||||
virtual CBofBitmap *getWorkBmp() {
|
||||
return _pWorkBmp;
|
||||
}
|
||||
|
||||
ErrorCode loadFile(const CBofString &sFile) override;
|
||||
|
||||
virtual const CBofString &getHelpFilename() {
|
||||
return _sHelpFileName;
|
||||
}
|
||||
|
||||
void setHelpFilename(const CBofString &s) override {
|
||||
_sHelpFileName = s;
|
||||
}
|
||||
|
||||
virtual ErrorCode onRender(CBofBitmap *pBmp, CBofRect *pRect = nullptr);
|
||||
void onPaint(CBofRect *) override;
|
||||
void onMainLoop() override;
|
||||
void onClose() override;
|
||||
void onMouseMove(uint32 nFlags, CBofPoint *, void * = nullptr) override;
|
||||
void onLButtonDown(uint32 nFlags, CBofPoint *point, void * = nullptr) override;
|
||||
void onLButtonUp(uint32 nFlags, CBofPoint *point, void * = nullptr) override;
|
||||
|
||||
void onKeyHit(uint32 lKey, uint32 nRepCount) override;
|
||||
|
||||
protected:
|
||||
virtual ErrorCode setWorkBmp();
|
||||
virtual ErrorCode killWorkBmp();
|
||||
};
|
||||
|
||||
/**
|
||||
* CBagStorageDevDlg is a window that contains a slide bitmap object.
|
||||
* It has specialize functions for handling slide bitmaps and slide objects.
|
||||
*/
|
||||
class CBagStorageDevDlg : public CBofDialog, public CBagStorageDev {
|
||||
private:
|
||||
//bool _bMadeSelection;
|
||||
CBofString _sHelpFileName; // Name of the help file for this device
|
||||
|
||||
public:
|
||||
CBagStorageDevDlg();
|
||||
|
||||
virtual ErrorCode paintScreen(CBofRect *pRect = nullptr);
|
||||
ErrorCode paintObjects(CBofList<CBagObject *> *list, CBofBitmap *pBmp,
|
||||
CBofRect &viewOffsetRect, CBofList<CBofRect> * = nullptr, bool tempVar = true);
|
||||
ErrorCode paintObjects(CBofList<CBagObject *> *list, CBofBitmap *pBmp) {
|
||||
CBofRect emptyRect;
|
||||
return paintObjects(list, pBmp, emptyRect);
|
||||
}
|
||||
|
||||
virtual CBofRect getLocation() {
|
||||
return getWindowRect();
|
||||
}
|
||||
|
||||
ErrorCode setBackground(CBofBitmap *pBmp) override {
|
||||
if (pBmp)
|
||||
return setBackdrop(pBmp);
|
||||
|
||||
killBackdrop();
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
CBofBitmap *getBackground() override {
|
||||
return getBackdrop();
|
||||
}
|
||||
|
||||
ErrorCode loadFile(const CBofString &sFile) override;
|
||||
|
||||
ErrorCode create(const char *pszName, CBofRect *pRect, CBofWindow *pParent, uint32 nControlID = 0) override;
|
||||
|
||||
ErrorCode attach() override; // This function attaches the background and necessary bitmaps
|
||||
|
||||
ErrorCode close() override;
|
||||
|
||||
virtual const CBofString &getHelpFilename() {
|
||||
return _sHelpFileName;
|
||||
}
|
||||
|
||||
void setHelpFilename(const CBofString &s) override {
|
||||
_sHelpFileName = s;
|
||||
}
|
||||
|
||||
void onMainLoop() override;
|
||||
virtual ErrorCode onRender(CBofBitmap *pBmp, CBofRect *pRect = nullptr);
|
||||
|
||||
void onPaint(CBofRect *) override;
|
||||
void onClose() override;
|
||||
void onMouseMove(uint32 nFlags, CBofPoint *, void * = nullptr) override;
|
||||
void onLButtonDown(uint32 nFlags, CBofPoint *point, void * = nullptr) override;
|
||||
void onLButtonUp(uint32 nFlags, CBofPoint *point, void * = nullptr) override;
|
||||
};
|
||||
|
||||
/**
|
||||
* Tracks all the storage devices
|
||||
*/
|
||||
class CBagStorageDevManager : public CBofObject {
|
||||
private:
|
||||
static int nSDevMngrs;
|
||||
CBofList<CBagStorageDev *> _xStorageDeviceList;
|
||||
|
||||
public:
|
||||
CBagStorageDevManager();
|
||||
~CBagStorageDevManager();
|
||||
|
||||
ErrorCode registerStorageDev(CBagStorageDev *pSDev);
|
||||
ErrorCode unregisterStorageDev(CBagStorageDev *pSDev);
|
||||
ErrorCode releaseStorageDevices();
|
||||
|
||||
int getObjectValue(const CBofString &sObject, const CBofString &sProperty);
|
||||
void setObjectValue(const CBofString &sObject, const CBofString &sProperty, int nValue);
|
||||
|
||||
int getNumStorageDevices() const {
|
||||
return _xStorageDeviceList.getCount();
|
||||
}
|
||||
|
||||
CBagStorageDev *getStorageDevice(int nIndex) {
|
||||
return _xStorageDeviceList[nIndex];
|
||||
}
|
||||
CBagStorageDev *getStorageDeviceContaining(const CBofString &sName);
|
||||
CBagStorageDev *getStorageDeviceContaining(CBagObject *pObj);
|
||||
CBagStorageDev *getStorageDevice(const CBofString &sName);
|
||||
bool moveObject(const CBofString &sDstName, const CBofString &sSrcName, const CBofString &sObjName);
|
||||
bool addObject(const CBofString &sDstName, const CBofString &sObjName);
|
||||
bool removeObject(const CBofString &sSrcName, const CBofString &sObjName);
|
||||
|
||||
void saveObjList(StObj *pObjList, int nNumEntries);
|
||||
void restoreObjList(StObj *pObjList, int nNumEntries);
|
||||
};
|
||||
|
||||
extern bool g_allowPaintFl;
|
||||
extern CBagStorageDevWnd *g_lastWindow;
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
|
||||
#endif
|
||||
613
engines/bagel/spacebar/baglib/text_object.cpp
Normal file
613
engines/bagel/spacebar/baglib/text_object.cpp
Normal file
@@ -0,0 +1,613 @@
|
||||
/* 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/text_object.h"
|
||||
#include "bagel/spacebar/baglib/master_win.h"
|
||||
#include "bagel/spacebar/baglib/pan_window.h"
|
||||
#include "bagel/spacebar/baglib/zoom_pda.h"
|
||||
#include "bagel/spacebar/baglib/base_pda.h"
|
||||
#include "bagel/spacebar/baglib/menu_dlg.h"
|
||||
#include "bagel/spacebar/baglib/bagel.h"
|
||||
#include "bagel/spacebar/baglib/rp_object.h"
|
||||
#include "bagel/spacebar/boflib/gfx/text.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
extern bool g_pauseTimerFl;
|
||||
|
||||
CBagTextObject::CBagTextObject() : CBagObject() {
|
||||
_xObjType = TEXT_OBJ;
|
||||
_nDX = 80;
|
||||
_nDY = 20;
|
||||
_psText = nullptr;
|
||||
CBagObject::setOverCursor(1); // Switch to cursor 1, 4 doesn't exist.
|
||||
|
||||
_nPointSize = 16;
|
||||
_nFGColor = CTEXT_COLOR;
|
||||
_psInitInfo = nullptr;
|
||||
_bCaption = false;
|
||||
_bTitle = false;
|
||||
_bReAttach = false;
|
||||
_nTextFont = FONT_DEFAULT;
|
||||
|
||||
setRPObject(nullptr);
|
||||
}
|
||||
|
||||
CBagTextObject::~CBagTextObject() {
|
||||
delete _psInitInfo;
|
||||
_psInitInfo = nullptr;
|
||||
|
||||
CBagTextObject::detach();
|
||||
}
|
||||
|
||||
CBofRect CBagTextObject::getRect() {
|
||||
CBofPoint p = getPosition();
|
||||
CBofSize s = getSize();
|
||||
CBofRect r = CBofRect(p, s);
|
||||
return r;
|
||||
}
|
||||
|
||||
ErrorCode CBagTextObject::update(CBofBitmap *pBmp, CBofPoint pt, CBofRect *pSrcRect, int) {
|
||||
assert(isValidObject(this));
|
||||
assert(pBmp != nullptr);
|
||||
assert(pSrcRect != nullptr);
|
||||
|
||||
// assume no error
|
||||
ErrorCode errorCode = ERR_NONE;
|
||||
|
||||
if ((pBmp != nullptr) && isAttached() && !(getText().isEmpty())) {
|
||||
|
||||
if (pBmp->getRect().ptInRect(pt)) {
|
||||
|
||||
CBofRect r(pt, pSrcRect->size());
|
||||
|
||||
int nPointSize = _nPointSize;
|
||||
int nFormat = FORMAT_CENTER_LEFT;
|
||||
if (!_bTitle) {
|
||||
byte c1 = 3;
|
||||
byte c2 = 9;
|
||||
|
||||
CBofRect cBevel;
|
||||
cBevel.intersectRect(pBmp->getRect(), r);
|
||||
|
||||
int left = cBevel.left;
|
||||
int top = cBevel.top;
|
||||
int right = cBevel.right;
|
||||
int bottom = cBevel.bottom;
|
||||
|
||||
r.left += 6;
|
||||
r.top += 3;
|
||||
r.right -= 5;
|
||||
r.bottom -= 5;
|
||||
|
||||
int i;
|
||||
for (i = 1; i <= 3; i++) {
|
||||
pBmp->line(left + i, bottom - i, right - i, bottom - i, c1);
|
||||
pBmp->line(right - i, bottom - i, right - i, top + i - 1, c1);
|
||||
}
|
||||
|
||||
for (i = 1; i <= 3; i++) {
|
||||
pBmp->line(left + i, bottom - i, left + i, top + i - 1, c2);
|
||||
pBmp->line(left + i, top + i - 1, right - i, top + i - 1, c2);
|
||||
}
|
||||
nPointSize = 16;
|
||||
nFormat = FORMAT_TOP_LEFT;
|
||||
|
||||
} else {
|
||||
r.left += 1;
|
||||
}
|
||||
|
||||
errorCode = paintText(pBmp, &r, getText(), mapWindowsPointSize(nPointSize), TEXT_NORMAL, _nFGColor, JUSTIFY_WRAP, nFormat, _nTextFont);
|
||||
|
||||
// This object does not need to be updated now...
|
||||
setDirty(false);
|
||||
}
|
||||
}
|
||||
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
ErrorCode CBagTextObject::attach() {
|
||||
assert(isValidObject(this));
|
||||
|
||||
if (!getFileName().right(4).find(".TXT") || !getFileName().right(4).find(".txt")) {
|
||||
// Prevent memory leak
|
||||
delete _psText;
|
||||
_psText = nullptr;
|
||||
|
||||
// Allocate a new string
|
||||
_psText = new CBofString;
|
||||
|
||||
CBofFile fpTextFile(getFileName());
|
||||
|
||||
if (!fpTextFile.errorOccurred()) {
|
||||
// Allocate the buffers
|
||||
uint32 nFileLen = fpTextFile.getLength();
|
||||
char *pTextBuff = (char *)bofCleanAlloc(nFileLen + 1);
|
||||
|
||||
// Read the text file into buffers
|
||||
fpTextFile.read(pTextBuff, nFileLen);
|
||||
fpTextFile.close();
|
||||
|
||||
*_psText += pTextBuff;
|
||||
|
||||
if (_psInitInfo != nullptr) {
|
||||
CBagVar *pVar = g_VarManager->getVariable(*_psInitInfo);
|
||||
|
||||
if (pVar != nullptr) {
|
||||
_bReAttach = true;
|
||||
_psText->replaceStr("%s", pVar->getValue());
|
||||
}
|
||||
}
|
||||
|
||||
bofFree(pTextBuff);
|
||||
|
||||
} else {
|
||||
reportError(ERR_FOPEN, "Failed to create a CBofFile for %s", getFileName().getBuffer());
|
||||
}
|
||||
|
||||
if (isCaption()) {
|
||||
recalcTextRect(true);
|
||||
}
|
||||
|
||||
} else {
|
||||
// The Text is in the Bagel script, rather than a .txt file
|
||||
// Prevent memory leak
|
||||
delete _psText;
|
||||
_psText = nullptr;
|
||||
|
||||
// Allocate a new string
|
||||
_psText = new CBofString;
|
||||
*_psText = getFileName();
|
||||
|
||||
// Replace any underscores with spaces
|
||||
_psText->replaceChar('_', ' ');
|
||||
|
||||
recalcTextRect(false);
|
||||
}
|
||||
|
||||
// If this guy is linked to a residue printing object, make sure he knows
|
||||
// we've been attached.
|
||||
CBagRPObject *pRPObj = (CBagRPObject *)getRPObject();
|
||||
|
||||
if (pRPObj != nullptr) {
|
||||
pRPObj->setTimeSet(false);
|
||||
}
|
||||
|
||||
return CBagObject::attach();
|
||||
}
|
||||
|
||||
ErrorCode CBagTextObject::detach() {
|
||||
assert(isValidObject(this));
|
||||
|
||||
delete _psText;
|
||||
_psText = nullptr;
|
||||
|
||||
return CBagObject::detach();
|
||||
}
|
||||
|
||||
const CBofString &CBagTextObject::getText() {
|
||||
if (_psText)
|
||||
return *_psText;
|
||||
|
||||
return getFileName();
|
||||
}
|
||||
|
||||
void CBagTextObject::setText(const CBofString &s) {
|
||||
if (_psText) {
|
||||
*_psText = s;
|
||||
} else {
|
||||
setFileName(s);
|
||||
}
|
||||
|
||||
recalcTextRect(!getFileName().right(4).find(".TXT") || !getFileName().right(4).find(".txt"));
|
||||
}
|
||||
|
||||
// Takes in info and then removes the relative information and returns the info
|
||||
// without the relevant info.
|
||||
//
|
||||
ParseCodes CBagTextObject::setInfo(CBagIfstream &istr) {
|
||||
bool nObjectUpdated = false;
|
||||
|
||||
while (!istr.eof()) {
|
||||
istr.eatWhite();
|
||||
|
||||
char ch = (char)istr.peek();
|
||||
switch (ch) {
|
||||
|
||||
//
|
||||
// VAR var - var is a BAGEL CBagVar variable (replaces all %s in text)
|
||||
//
|
||||
case 'V': {
|
||||
char szLocalStr[256];
|
||||
szLocalStr[0] = 0;
|
||||
CBofString sStr(szLocalStr, 256);
|
||||
|
||||
// Need to use this field, so no one else can
|
||||
assert(_psInitInfo == nullptr);
|
||||
|
||||
getAlphaNumFromStream(istr, sStr);
|
||||
|
||||
if (!sStr.find("VAR")) {
|
||||
istr.eatWhite();
|
||||
getAlphaNumFromStream(istr, sStr);
|
||||
setInitInfo(sStr);
|
||||
nObjectUpdated = true;
|
||||
} else {
|
||||
putbackStringOnStream(istr, sStr);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
// SIZE n - n point size of the txt
|
||||
//
|
||||
case 'S': {
|
||||
char szLocalStr[256];
|
||||
szLocalStr[0] = 0;
|
||||
CBofString sStr(szLocalStr, 256);
|
||||
|
||||
getAlphaNumFromStream(istr, sStr);
|
||||
|
||||
if (!sStr.find("SIZE")) {
|
||||
istr.eatWhite();
|
||||
int n;
|
||||
getIntFromStream(istr, n);
|
||||
_nPointSize = (byte)n;
|
||||
nObjectUpdated = true;
|
||||
|
||||
// WORKAROUND: Reduce the font size of Cilia's full-screen log
|
||||
// in ScummVM so that it fits on the screen
|
||||
if (_nPointSize == 28 && istr.getSize() == 359105)
|
||||
_nPointSize = 26;
|
||||
|
||||
} else {
|
||||
putbackStringOnStream(istr, sStr);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
// FONT MONO or DEFAULT
|
||||
//
|
||||
case 'F': {
|
||||
char szLocalStr[256];
|
||||
szLocalStr[0] = 0;
|
||||
CBofString sStr(szLocalStr, 256);
|
||||
|
||||
getAlphaNumFromStream(istr, sStr);
|
||||
|
||||
if (!sStr.find("FONT")) {
|
||||
istr.eatWhite();
|
||||
int n;
|
||||
getIntFromStream(istr, n);
|
||||
_nTextFont = MapFont(n);
|
||||
nObjectUpdated = true;
|
||||
} else {
|
||||
putbackStringOnStream(istr, sStr);
|
||||
}
|
||||
// FIXME: Missing break?
|
||||
}
|
||||
// fallthrough
|
||||
|
||||
//
|
||||
// AS [CAPTION] - how to run the link
|
||||
//
|
||||
case 'A': {
|
||||
char szLocalStr[256];
|
||||
szLocalStr[0] = 0;
|
||||
CBofString sStr(szLocalStr, 256);
|
||||
getAlphaNumFromStream(istr, sStr);
|
||||
|
||||
if (!sStr.find("AS")) {
|
||||
istr.eatWhite();
|
||||
getAlphaNumFromStream(istr, sStr);
|
||||
if (!sStr.find("CAPTION")) {
|
||||
_bCaption = true;
|
||||
nObjectUpdated = true;
|
||||
|
||||
} else if (!sStr.find("TITLE")) {
|
||||
_bTitle = true;
|
||||
nObjectUpdated = true;
|
||||
|
||||
} else {
|
||||
putbackStringOnStream(istr, sStr);
|
||||
putbackStringOnStream(istr, "AS ");
|
||||
}
|
||||
} else {
|
||||
putbackStringOnStream(istr, sStr);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
// COLOR n - n color index
|
||||
//
|
||||
case 'C': {
|
||||
char szLocalStr[256];
|
||||
szLocalStr[0] = 0;
|
||||
CBofString sStr(szLocalStr, 256);
|
||||
|
||||
getAlphaNumFromStream(istr, sStr);
|
||||
|
||||
if (!sStr.find("COLOR")) {
|
||||
int nColor;
|
||||
istr.eatWhite();
|
||||
getIntFromStream(istr, nColor);
|
||||
setColor(nColor);
|
||||
nObjectUpdated = true;
|
||||
} else {
|
||||
putbackStringOnStream(istr, sStr);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
// No match return from function
|
||||
//
|
||||
default: {
|
||||
ParseCodes parseCode = CBagObject::setInfo(istr);
|
||||
if (parseCode == PARSING_DONE) {
|
||||
return PARSING_DONE;
|
||||
}
|
||||
|
||||
if (parseCode == UPDATED_OBJECT) {
|
||||
nObjectUpdated = true;
|
||||
} else { // rc==UNKNOWN_TOKEN
|
||||
if (nObjectUpdated)
|
||||
return UPDATED_OBJECT;
|
||||
|
||||
return UNKNOWN_TOKEN;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return PARSING_DONE;
|
||||
}
|
||||
|
||||
void CBagTextObject::setColor(int nColor) {
|
||||
switch (nColor) {
|
||||
case 0:
|
||||
_nFGColor = RGB(0, 0, 0);
|
||||
break; // Black
|
||||
case 1:
|
||||
_nFGColor = RGB(226, 50, 51);
|
||||
break; // Red
|
||||
case 2:
|
||||
_nFGColor = RGB(255, 255, 255);
|
||||
break; // Yellow
|
||||
case 3:
|
||||
_nFGColor = RGB(255, 255, 255);
|
||||
break; // Green
|
||||
case 4:
|
||||
_nFGColor = RGB(255, 255, 255);
|
||||
break; // Green
|
||||
case 5:
|
||||
_nFGColor = RGB(0, 0, 255);
|
||||
break; // Blue
|
||||
case 6:
|
||||
_nFGColor = RGB(255, 0, 255);
|
||||
break;
|
||||
case 7:
|
||||
_nFGColor = CTEXT_WHITE;
|
||||
break; // White
|
||||
case 8:
|
||||
_nFGColor = CTEXT_YELLOW;
|
||||
break; // Yellow (chat highlight)
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CBagTextObject::setProperty(const CBofString &sProp, int nVal) {
|
||||
if (!sProp.find("SIZE"))
|
||||
setPointSize(nVal);
|
||||
else if (!sProp.find("FONT"))
|
||||
setFont(MapFont(nVal));
|
||||
else if (!sProp.find("COLOR"))
|
||||
setColor(nVal);
|
||||
else
|
||||
CBagObject::setProperty(sProp, nVal);
|
||||
}
|
||||
|
||||
int CBagTextObject::getProperty(const CBofString &sProp) {
|
||||
if (!sProp.find("SIZE"))
|
||||
return getPointSize();
|
||||
if (!sProp.find("FONT"))
|
||||
return getFont();
|
||||
if (!sProp.find("COLOR"))
|
||||
return getColor();
|
||||
|
||||
return CBagObject::getProperty(sProp);
|
||||
}
|
||||
|
||||
bool CBagTextObject::runObject() {
|
||||
char szLocalBuff[256];
|
||||
CBofString sStr(szLocalBuff, 256);
|
||||
|
||||
if (_bCaption && isImmediateRun()) {
|
||||
|
||||
// Re-attach this object to get any change in a variable
|
||||
// (Must be using the VAR token).
|
||||
if (_bReAttach) {
|
||||
attach();
|
||||
}
|
||||
|
||||
CBagel *pApp = CBagel::getBagApp();
|
||||
if (pApp != nullptr) {
|
||||
CBagMasterWin *pWin = pApp->getMasterWnd();
|
||||
if (pWin != nullptr) {
|
||||
CBagStorageDevWnd *pParent = pWin->getCurrentStorageDev();
|
||||
|
||||
CBofRect cRect(80, 10, 80 + 480 /*- 1 */, 10 + getRect().height() - 1 + 5);
|
||||
CBofPoint cPoint(0, 0);
|
||||
|
||||
CBofPalette *pPal = pApp->getPalette();
|
||||
CBofBitmap cBmp(cRect.width(), cRect.height(), pPal);
|
||||
|
||||
cBmp.fillRect(nullptr, pPal->getNearestIndex(RGB(92, 92, 92)));
|
||||
|
||||
CBagMenuDlg cDlg;
|
||||
cDlg.createDlg(pParent, pPal, &cRect);
|
||||
|
||||
update(cDlg.getBackdrop(), cPoint, &cRect);
|
||||
|
||||
sStr = "BPDA_WLD";
|
||||
CBagPDA *pPDA = (CBagPDA *)g_SDevManager->getStorageDevice(sStr);
|
||||
|
||||
// If we're in the zoom pda then put this box at the
|
||||
// bottom of the zoom rect.
|
||||
sStr = "BPDAZ_WLD";
|
||||
SBZoomPda *pPDAZ = (SBZoomPda *)g_SDevManager->getStorageDevice(sStr);
|
||||
|
||||
if (pPDAZ && pPDAZ->getZoomed() == true) {
|
||||
CBofRect zRect = pPDAZ->getViewRect();
|
||||
assert(zRect.height() > 0 && zRect.height() < 480);
|
||||
assert(zRect.width() > 0 && zRect.width() < 640);
|
||||
cDlg.move(80, zRect.bottom - cRect.height(), true); // xxx
|
||||
} else if ((pPDA != nullptr) && (pPDA->isActivated() || pPDA->isActivating())) {
|
||||
cDlg.move(80, 10, true);
|
||||
|
||||
} else {
|
||||
int x = 80;
|
||||
int y = 360 + 10 - cRect.height();
|
||||
cDlg.move(x, y, true);
|
||||
}
|
||||
g_pauseTimerFl = true;
|
||||
cDlg.doModal();
|
||||
g_pauseTimerFl = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int MapFont(int nFont) {
|
||||
if (nFont == 0)
|
||||
return FONT_MONO;
|
||||
|
||||
return FONT_DEFAULT;
|
||||
}
|
||||
|
||||
void CBagTextObject::onLButtonUp(uint32 nFlags, CBofPoint *xPoint, void *pv) {
|
||||
// If there's a residue printing object, then hand this guy off to
|
||||
// him, otherwise, call back to Cbagobj.
|
||||
CBagRPObject *pRPObj = (CBagRPObject *)getRPObject();
|
||||
if (pRPObj) {
|
||||
pRPObj->onLButtonUp(nFlags, xPoint, pv);
|
||||
return;
|
||||
}
|
||||
|
||||
CBagObject::onLButtonUp(nFlags, xPoint, pv);
|
||||
}
|
||||
|
||||
void CBagTextObject::recalcTextRect(bool bTextFromFile) {
|
||||
CBofRect ViewRect; // The rect of the area where objects are displayed
|
||||
CBofSize cDisplaySize; // Size of rect needed to display font
|
||||
CBofSize cSize; // Size of rect needed to display font
|
||||
|
||||
assert(_psText != nullptr);
|
||||
|
||||
// The window where the object are displayed
|
||||
CBagPanWindow *pPanWin = (CBagPanWindow *)(CBagel::getBagApp()->getMasterWnd()->getCurrentGameWindow());
|
||||
if (bTextFromFile) {
|
||||
if (pPanWin->getDeviceType() == SDEV_GAMEWIN) {
|
||||
ViewRect = pPanWin->getViewPort();
|
||||
} else {
|
||||
ViewRect = pPanWin->getClientRect();
|
||||
}
|
||||
}
|
||||
|
||||
if (ViewRect.isRectEmpty()) {
|
||||
ViewRect.setRect(80, 10, 480 + 80 - 1, 360 + 10 - 1);
|
||||
}
|
||||
|
||||
// Get the area spanned by the text (i.e. Get the pixel width and
|
||||
// height of the text string).
|
||||
CBofRect tmpRect = ViewRect;
|
||||
if (!_bTitle) {
|
||||
// Exactly match the width used in displayTextEx
|
||||
tmpRect.left += 5;
|
||||
tmpRect.right = (ViewRect.right == 640 ? PAN_AREA_WIDTH : ViewRect.right) - 5;
|
||||
}
|
||||
|
||||
CBofRect textRect = calculateTextRect(tmpRect, _psText, _nPointSize, getFont());
|
||||
CBofSize stTextSize(textRect.right, textRect.bottom);
|
||||
|
||||
if (bTextFromFile) {
|
||||
// Add fudge factor to make sure that all the text will fit, and not
|
||||
// get cut off. This may cause an extra blank line of text in some
|
||||
// captions, but tough diddles, it's still better than truncating
|
||||
// some text.
|
||||
|
||||
cSize.cx = stTextSize.cx;
|
||||
cSize.cy = stTextSize.cy;
|
||||
} else {
|
||||
cSize.cx = stTextSize.cx + 9;
|
||||
cSize.cy = stTextSize.cy + (_bTitle ? 0 : 7);
|
||||
setSize(cSize);
|
||||
}
|
||||
|
||||
if (bTextFromFile) {
|
||||
cDisplaySize.cx = ViewRect.width();
|
||||
cDisplaySize.cy = cSize.cy;
|
||||
|
||||
// If for some reason (CIC, CHAT) we got too large
|
||||
// a viewrect, cut it back to the correct width
|
||||
if (cDisplaySize.cx > PAN_AREA_WIDTH)
|
||||
cDisplaySize.cx = PAN_AREA_WIDTH;
|
||||
|
||||
// Buffer the size a little for spacing etc.
|
||||
cDisplaySize.cx -= 5;
|
||||
|
||||
// While the text is wider then the view area
|
||||
while (cSize.cx > cDisplaySize.cx) {
|
||||
// Increment Display Height to account for another line
|
||||
cDisplaySize.cy += cSize.cy;
|
||||
|
||||
// Decrement the size of text by the width of one line
|
||||
cSize.cx -= cDisplaySize.cx;
|
||||
}
|
||||
|
||||
// Add a little space at the bottom
|
||||
cDisplaySize.cy += 5;
|
||||
|
||||
setSize(cDisplaySize);
|
||||
}
|
||||
}
|
||||
|
||||
void CBagTextObject::setPSText(CBofString *p) {
|
||||
assert(isValidObject(this));
|
||||
|
||||
delete _psText;
|
||||
_psText = nullptr;
|
||||
|
||||
if (p != nullptr) {
|
||||
_psText = new CBofString(*p);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
151
engines/bagel/spacebar/baglib/text_object.h
Normal file
151
engines/bagel/spacebar/baglib/text_object.h
Normal file
@@ -0,0 +1,151 @@
|
||||
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BAGEL_BAGLIB_TEXT_OBJECT_H
|
||||
#define BAGEL_BAGLIB_TEXT_OBJECT_H
|
||||
|
||||
#include "bagel/spacebar/baglib/object.h"
|
||||
#include "bagel/spacebar/boflib/gfx/text.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
// local prototypes...
|
||||
int MapFont(int nFont);
|
||||
|
||||
/**
|
||||
* CBagTextObject is an object that can be place within the slide window.
|
||||
*/
|
||||
class CBagTextObject : public CBagObject {
|
||||
private:
|
||||
CBofString *_psInitInfo; // Aux info
|
||||
|
||||
COLORREF _nFGColor;
|
||||
|
||||
int16 _nDX;
|
||||
int16 _nDY;
|
||||
|
||||
byte _nPointSize;
|
||||
int _nTextFont;
|
||||
|
||||
CBagObject *_pRPObject;
|
||||
|
||||
protected:
|
||||
bool _bCaption : true;
|
||||
bool _bTitle : true;
|
||||
bool _bReAttach : true;
|
||||
CBofString *_psText;
|
||||
|
||||
public:
|
||||
CBagTextObject();
|
||||
virtual ~CBagTextObject();
|
||||
|
||||
CBofRect getRect() override;
|
||||
|
||||
CBofSize getSize() const {
|
||||
return CBofSize(_nDX, _nDY);
|
||||
}
|
||||
void setSize(const CBofSize &xSize) override {
|
||||
_nDX = (int16)xSize.cx;
|
||||
_nDY = (int16)xSize.cy;
|
||||
}
|
||||
|
||||
int getPointSize() const {
|
||||
return _nPointSize;
|
||||
}
|
||||
void setPointSize(int xSize) {
|
||||
assert(xSize >= 0 && xSize <= 255);
|
||||
_nPointSize = (byte)xSize;
|
||||
}
|
||||
int getColor() const {
|
||||
return 0;
|
||||
}
|
||||
void setColor(int nColor);
|
||||
|
||||
// Font support for text objects
|
||||
int getFont() const {
|
||||
return _nTextFont;
|
||||
}
|
||||
void setFont(int nFont) {
|
||||
_nTextFont = nFont;
|
||||
}
|
||||
|
||||
bool runObject() override;
|
||||
|
||||
const CBofString *getInitInfo() const override {
|
||||
return _psInitInfo;
|
||||
}
|
||||
void setInitInfo(const CBofString &info) override {
|
||||
delete _psInitInfo;
|
||||
_psInitInfo = new CBofString();
|
||||
*_psInitInfo = info;
|
||||
}
|
||||
|
||||
CBofString *getPSText() const {
|
||||
return _psText;
|
||||
}
|
||||
void setPSText(CBofString *p);
|
||||
|
||||
const CBofString &getText();
|
||||
void setText(const CBofString &s);
|
||||
|
||||
/**
|
||||
* Calculate the required bounds to display text
|
||||
*/
|
||||
void recalcTextRect(bool bTextFromFile);
|
||||
|
||||
ErrorCode update(CBofBitmap *pBmp, CBofPoint pt, CBofRect * /*pSrcRect*/ = nullptr, int /*nMaskColor*/ = -1) override;
|
||||
|
||||
ErrorCode attach() override;
|
||||
ErrorCode detach() override;
|
||||
|
||||
ParseCodes setInfo(CBagIfstream &istr) override;
|
||||
|
||||
void setProperty(const CBofString &sProp, int nVal) override;
|
||||
int getProperty(const CBofString &sProp) override;
|
||||
|
||||
bool isCaption() const {
|
||||
return _bCaption;
|
||||
}
|
||||
|
||||
void setTitle(bool b = true) {
|
||||
_bTitle = b;
|
||||
}
|
||||
bool isTitle() const {
|
||||
return _bTitle;
|
||||
}
|
||||
|
||||
// Extra stuff to handle mouse downs on floaters in the log pda/residue printing code.
|
||||
void onLButtonUp(uint32, CBofPoint *, void * = nullptr) override;
|
||||
|
||||
void setRPObject(CBagObject *prp) {
|
||||
_pRPObject = prp;
|
||||
}
|
||||
CBagObject *getRPObject() const {
|
||||
return _pRPObject;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
|
||||
#endif
|
||||
41
engines/bagel/spacebar/baglib/thing_object.h
Normal file
41
engines/bagel/spacebar/baglib/thing_object.h
Normal file
@@ -0,0 +1,41 @@
|
||||
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BAGEL_BAGLIB_THING_OBJECT_H
|
||||
#define BAGEL_BAGLIB_THING_OBJECT_H
|
||||
|
||||
#include "bagel/spacebar/baglib/character_object.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
class CBagThingObject : public CBagCharacterObject {
|
||||
public:
|
||||
CBagThingObject() {
|
||||
_xObjType = THING_OBJ;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
|
||||
#endif
|
||||
277
engines/bagel/spacebar/baglib/time_object.cpp
Normal file
277
engines/bagel/spacebar/baglib/time_object.cpp
Normal file
@@ -0,0 +1,277 @@
|
||||
/* 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/bagel.h"
|
||||
#include "bagel/spacebar/baglib/master_win.h"
|
||||
#include "bagel/spacebar/baglib/time_object.h"
|
||||
#include "bagel/boflib/log.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
CBagTimeObject::CBagTimeObject() : CBagObject() {
|
||||
_xObjType = SPRITE_OBJ;
|
||||
_xDig1 = nullptr;
|
||||
_xDig2 = nullptr;
|
||||
_xColon = nullptr;
|
||||
_xDig3 = nullptr;
|
||||
_xDig4 = nullptr;
|
||||
_nCels = 1;
|
||||
|
||||
CBagObject::setOverCursor(1);
|
||||
setTimeless(true);
|
||||
}
|
||||
|
||||
CBagTimeObject::~CBagTimeObject() {
|
||||
CBagTimeObject::detach();
|
||||
}
|
||||
|
||||
ErrorCode CBagTimeObject::attach() {
|
||||
CBofPoint p = CBagObject::getPosition();
|
||||
|
||||
_xDig1 = new CBofSprite();
|
||||
|
||||
if (_xDig1->loadSprite(getFileName(), getCels()) != 0 && (_xDig1->width() != 0) && (_xDig1->height() != 0)) {
|
||||
_xDig1->setAnimated(false);
|
||||
_xDig1->setPosition(p.x, p.y);
|
||||
|
||||
p.offset(_xDig1->width(), 0);
|
||||
|
||||
} else {
|
||||
reportError(ERR_FOPEN, "Could Not Open Dig1 Sprite: %s", _xDig1->getFileName());
|
||||
}
|
||||
|
||||
_xDig2 = new CBofSprite();
|
||||
|
||||
if (_xDig2->loadSprite(getFileName(), getCels()) != 0 && (_xDig2->width() != 0) && (_xDig2->height() != 0)) {
|
||||
_xDig2->setAnimated(false);
|
||||
_xDig2->setPosition(p.x, p.y);
|
||||
p.offset(_xDig2->width(), 0);
|
||||
} else {
|
||||
reportError(ERR_FOPEN, "Could Not Open Dig2 Sprite: %s", _xDig2->getFileName());
|
||||
}
|
||||
|
||||
_xColon = new CBofSprite();
|
||||
|
||||
if (_xColon->loadSprite(getFileName(), getCels()) != 0 && (_xColon->width() != 0) && (_xColon->height() != 0)) {
|
||||
_xColon->setAnimated(false);
|
||||
// The time sprite should start with 0 and go to 9 followed by the :
|
||||
_xColon->setCel(_nCels - 1);
|
||||
_xColon->setPosition(p.x, p.y);
|
||||
|
||||
p.offset(_xColon->width(), 0);
|
||||
} else {
|
||||
reportError(ERR_FOPEN, "Could Not Open Colon Sprite: %s", _xColon->getFileName());
|
||||
}
|
||||
|
||||
_xDig3 = new CBofSprite();
|
||||
|
||||
if (_xDig3->loadSprite(getFileName(), getCels()) != 0 && (_xDig3->width() != 0) && (_xDig3->height() != 0)) {
|
||||
_xDig3->setAnimated(false);
|
||||
_xDig3->setPosition(p.x, p.y);
|
||||
p.offset(_xDig3->width(), 0);
|
||||
} else {
|
||||
reportError(ERR_FOPEN, "Could Not Open Dig3 Sprite: %s", _xDig3->getFileName());
|
||||
}
|
||||
|
||||
_xDig4 = new CBofSprite();
|
||||
|
||||
if (_xDig4->loadSprite(getFileName(), getCels()) != 0 && (_xDig4->width() != 0) && (_xDig4->height() != 0)) {
|
||||
_xDig4->setAnimated(false);
|
||||
_xDig4->setPosition(p.x, p.y);
|
||||
p.offset(_xDig4->width(), 0);
|
||||
} else {
|
||||
reportError(ERR_FOPEN, "Could Not Open Dig4 Sprite: %s", _xDig4->getFileName());
|
||||
}
|
||||
|
||||
return CBagObject::attach();
|
||||
}
|
||||
|
||||
ErrorCode CBagTimeObject::detach() {
|
||||
delete _xDig1;
|
||||
_xDig1 = nullptr;
|
||||
|
||||
delete _xDig2;
|
||||
_xDig2 = nullptr;
|
||||
|
||||
delete _xColon;
|
||||
_xColon = nullptr;
|
||||
|
||||
delete _xDig3;
|
||||
_xDig3 = nullptr;
|
||||
|
||||
delete _xDig4;
|
||||
_xDig4 = nullptr;
|
||||
|
||||
return CBagObject::detach();
|
||||
}
|
||||
|
||||
void CBagTimeObject::setCels(int nCels) {
|
||||
_nCels = nCels;
|
||||
|
||||
if (_xDig1)
|
||||
_xDig1->setupCels(nCels);
|
||||
if (_xDig2)
|
||||
_xDig2->setupCels(nCels);
|
||||
if (_xColon)
|
||||
_xColon->setupCels(nCels);
|
||||
if (_xDig3)
|
||||
_xDig3->setupCels(nCels);
|
||||
if (_xDig4)
|
||||
_xDig4->setupCels(nCels);
|
||||
}
|
||||
|
||||
void CBagTimeObject::setPosition(const CBofPoint &pos) {
|
||||
CBagObject::setPosition(pos);
|
||||
}
|
||||
|
||||
CBofRect CBagTimeObject::getRect() {
|
||||
CBofPoint p = getPosition();
|
||||
CBofSize s;
|
||||
|
||||
if (_xDig1) {
|
||||
s = _xDig1->getSize();
|
||||
|
||||
// Increase the width to accommodate all 5 sprites
|
||||
s.cx = s.cx * 5;
|
||||
}
|
||||
return CBofRect(p, s);
|
||||
}
|
||||
|
||||
ParseCodes CBagTimeObject::setInfo(CBagIfstream &istr) {
|
||||
bool nObjectUpdated = false;
|
||||
|
||||
while (!istr.eof()) {
|
||||
istr.eatWhite();
|
||||
|
||||
char ch = (char)istr.peek();
|
||||
switch (ch) {
|
||||
//
|
||||
// +n - n number of slides in sprite
|
||||
//
|
||||
case '+': {
|
||||
int cels;
|
||||
istr.getCh();
|
||||
getIntFromStream(istr, cels);
|
||||
setCels(cels);
|
||||
nObjectUpdated = true;
|
||||
break;
|
||||
}
|
||||
|
||||
case 'V': {
|
||||
char szLocalBuff[256];
|
||||
szLocalBuff[0] = '\0';
|
||||
CBofString sStr(szLocalBuff, 256);
|
||||
|
||||
getAlphaNumFromStream(istr, sStr);
|
||||
|
||||
if (!sStr.find("VALUE")) {
|
||||
istr.eatWhite();
|
||||
char szLocalBuff1[256];
|
||||
szLocalBuff[0] = '\0';
|
||||
CBofString s(szLocalBuff1, 256);
|
||||
getAlphaNumFromStream(istr, s);
|
||||
|
||||
setVariable(s);
|
||||
|
||||
nObjectUpdated = true;
|
||||
} else {
|
||||
putbackStringOnStream(istr, sStr);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// No match return from function
|
||||
default: {
|
||||
ParseCodes parseCode = CBagObject::setInfo(istr);
|
||||
if (parseCode == PARSING_DONE) {
|
||||
return PARSING_DONE;
|
||||
}
|
||||
|
||||
if (parseCode == UPDATED_OBJECT) {
|
||||
nObjectUpdated = true;
|
||||
} else {
|
||||
// rc==UNKNOWN_TOKEN
|
||||
if (nObjectUpdated)
|
||||
return UPDATED_OBJECT;
|
||||
|
||||
return UNKNOWN_TOKEN;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return PARSING_DONE;
|
||||
}
|
||||
|
||||
ErrorCode CBagTimeObject::update(CBofBitmap *pBmp, CBofPoint pt, CBofRect * /*pSrcRect*/, int) {
|
||||
char szLocalBuff[256];
|
||||
szLocalBuff[0] = '\0';
|
||||
CBofString sTimeString(szLocalBuff, 256);
|
||||
ErrorCode errorCode = ERR_NONE;
|
||||
|
||||
CBagVar *xVar = g_VarManager->getVariable(_sVariable);
|
||||
|
||||
// If everything looks good
|
||||
if (isAttached() && xVar && !(xVar->getValue().isEmpty())) {
|
||||
int nTimeVal = xVar->getNumValue();
|
||||
sTimeString = buildString("%04d", nTimeVal);
|
||||
char sDigString[2] = "0";
|
||||
|
||||
// Digit 1
|
||||
if (_xDig1) {
|
||||
sDigString[0] = sTimeString[0];
|
||||
_xDig1->setCel(atoi(sDigString));
|
||||
_xDig1->paintSprite(pBmp, pt.x, pt.y);
|
||||
pt.offset(_xDig1->width(), 0);
|
||||
}
|
||||
// Digit 2
|
||||
if (_xDig2) {
|
||||
sDigString[0] = sTimeString[1];
|
||||
_xDig2->setCel(atoi(sDigString));
|
||||
_xDig2->paintSprite(pBmp, pt.x, pt.y);
|
||||
pt.offset(_xDig2->width(), 0);
|
||||
}
|
||||
if (_xColon) {
|
||||
_xColon->paintSprite(pBmp, pt.x, pt.y);
|
||||
pt.offset(_xColon->width(), 0);
|
||||
}
|
||||
// Digit 3
|
||||
if (_xDig3) {
|
||||
sDigString[0] = sTimeString[2];
|
||||
_xDig3->setCel(atoi(sDigString));
|
||||
_xDig3->paintSprite(pBmp, pt.x, pt.y);
|
||||
pt.offset(_xDig3->width(), 0);
|
||||
}
|
||||
// Digit 4
|
||||
if (_xDig4) {
|
||||
sDigString[0] = sTimeString[3];
|
||||
_xDig4->setCel(atoi(sDigString));
|
||||
_xDig4->paintSprite(pBmp, pt.x, pt.y);
|
||||
}
|
||||
}
|
||||
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
90
engines/bagel/spacebar/baglib/time_object.h
Normal file
90
engines/bagel/spacebar/baglib/time_object.h
Normal file
@@ -0,0 +1,90 @@
|
||||
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BAGEL_BAGLIB_TIME_OBJECT_H
|
||||
#define BAGEL_BAGLIB_TIME_OBJECT_H
|
||||
|
||||
#include "bagel/spacebar/baglib/object.h"
|
||||
#include "bagel/spacebar/boflib/gfx/bitmap.h"
|
||||
#include "bagel/spacebar/boflib/gfx/sprite.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
/**
|
||||
* CBagTimeObject is an object that can be place within the slide window.
|
||||
*/
|
||||
class CBagTimeObject : public CBagObject {
|
||||
private:
|
||||
CBofString _sVariable;
|
||||
|
||||
CBofSprite *_xDig1; // x-:--
|
||||
CBofSprite *_xDig2; // -x:--
|
||||
CBofSprite *_xColon; // --:--
|
||||
CBofSprite *_xDig3; // --:x-
|
||||
CBofSprite *_xDig4; // --:-x
|
||||
|
||||
int _nCels;
|
||||
|
||||
public:
|
||||
CBagTimeObject();
|
||||
virtual ~CBagTimeObject();
|
||||
|
||||
/**
|
||||
* Create all 5 sprite objects for the clock and set their positions
|
||||
*/
|
||||
ErrorCode attach() override;
|
||||
ErrorCode detach() override;
|
||||
bool isAttached() override {
|
||||
return _xDig1 != nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes in info and then removes the relative information and returns the info
|
||||
* without the relevant info.
|
||||
*/
|
||||
ParseCodes setInfo(CBagIfstream &istr) override;
|
||||
|
||||
CBofRect getRect() override;
|
||||
int getCels() {
|
||||
return _nCels;
|
||||
}
|
||||
|
||||
void setCels(int nCels);
|
||||
void setPosition(const CBofPoint &pos) override;
|
||||
|
||||
/**
|
||||
* Read in the value of the associated variable and set the time equal
|
||||
* to the first 4 digits of the variable if the variable is less the 4 digits
|
||||
* the time is padded with 0's if it is greater the 4 we truncate to remaining digits
|
||||
*/
|
||||
ErrorCode update(CBofBitmap *pBmp, CBofPoint pt, CBofRect *pSrcRect = nullptr, int /*nMaskColor*/ = -1) override;
|
||||
|
||||
void setVariable(const CBofString &sProp) {
|
||||
_sVariable = sProp;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
|
||||
#endif
|
||||
376
engines/bagel/spacebar/baglib/var.cpp
Normal file
376
engines/bagel/spacebar/baglib/var.cpp
Normal file
@@ -0,0 +1,376 @@
|
||||
/* 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/var.h"
|
||||
#include "bagel/spacebar/baglib/event_sdev.h"
|
||||
#include "bagel/spacebar/baglib/master_win.h"
|
||||
#include "bagel/spacebar/baglib/storage_dev_win.h"
|
||||
#include "bagel/bagel.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
static int HASHVAR(const char *p, int l);
|
||||
|
||||
int CBagVarManager::nVarMngrs;
|
||||
|
||||
void CBagVarManager::initialize() {
|
||||
nVarMngrs = 0;
|
||||
}
|
||||
|
||||
CBagVar::CBagVar() {
|
||||
setGlobal(false);
|
||||
setConstant(false);
|
||||
setReference(false);
|
||||
setTimer(false);
|
||||
setString();
|
||||
setRandom(false);
|
||||
g_VarManager->registerVariable(this);
|
||||
}
|
||||
|
||||
CBagVar::CBagVar(const CBofString &sName, const CBofString &sValue, bool bAddToList) {
|
||||
setConstant(false);
|
||||
setReference(false);
|
||||
setTimer(false);
|
||||
setString();
|
||||
setName(sName);
|
||||
|
||||
setValue(sValue);
|
||||
setRandom(false);
|
||||
setGlobal(false);
|
||||
|
||||
if (bAddToList)
|
||||
g_VarManager->registerVariable(this);
|
||||
}
|
||||
|
||||
CBagVar::~CBagVar() {
|
||||
if (CBagel::getBagApp() &&
|
||||
CBagel::getBagApp()->getMasterWnd() &&
|
||||
CBagel::getBagApp()->getMasterWnd()->getVariableManager())
|
||||
g_VarManager->unRegisterVariable(this);
|
||||
}
|
||||
|
||||
void CBagVar::setValue(const CBofString &s) {
|
||||
assert(isValidObject(this));
|
||||
|
||||
if (!_freeze) {
|
||||
if (!s.isEmpty()) {
|
||||
char c = s[0];
|
||||
if (Common::isDigit(c) || c == '-')
|
||||
setNumeric();
|
||||
}
|
||||
_sVarValue = s;
|
||||
}
|
||||
}
|
||||
|
||||
const CBofString &CBagVar::getValue() {
|
||||
assert(isValidObject(this));
|
||||
|
||||
// WORKAROUND: If you finish the Deven7 flashback without having previously
|
||||
// asked him about betting, it hangs him. Work around this by force setting
|
||||
// betting to have been discussed
|
||||
if (_sVarName == "BETWITHDEVEN") {
|
||||
if (g_VarManager->getVariable("DEVENCODE1")->getValue() != "NOTSETYET")
|
||||
// Finished flashback, so ensure betting flag is set
|
||||
_sVarValue = "1";
|
||||
}
|
||||
|
||||
// Check if these items should be replaced by the current sdev
|
||||
if (!_sVarName.isEmpty() && !_sVarName.find(CURRSDEV_TOKEN)) {
|
||||
if (CBagel::getBagApp()->getMasterWnd()->getCurrentStorageDev()) {
|
||||
_sVarValue = CBagel::getBagApp()->getMasterWnd()->getCurrentStorageDev()->getName();
|
||||
}
|
||||
} else if (!_sVarName.isEmpty() && !_sVarName.find(PREVSDEV_TOKEN)) {
|
||||
// Check if these items should be replaced by the previous sdev
|
||||
if (CBagel::getBagApp()->getMasterWnd()->getCurrentStorageDev()) {
|
||||
_sVarValue = CBagel::getBagApp()->getMasterWnd()->getCurrentStorageDev()->getPrevSDev();
|
||||
}
|
||||
}
|
||||
|
||||
return _sVarValue;
|
||||
}
|
||||
|
||||
void CBagVar::setBoolValue(bool bVal) {
|
||||
assert(isValidObject(this));
|
||||
|
||||
if (bVal)
|
||||
_sVarValue = "true";
|
||||
else
|
||||
_sVarValue = "false";
|
||||
}
|
||||
|
||||
void CBagVar::setValue(int nVal) {
|
||||
assert(isValidObject(this));
|
||||
|
||||
if (!_freeze) {
|
||||
setNumeric();
|
||||
|
||||
Common::String tmp = Common::String::format("%d", nVal);
|
||||
_sVarValue = tmp.c_str();
|
||||
}
|
||||
}
|
||||
|
||||
int CBagVar::getNumValue() {
|
||||
assert(isValidObject(this));
|
||||
|
||||
if (isRandom())
|
||||
return g_engine->getRandomNumber();
|
||||
|
||||
return atoi(_sVarValue);
|
||||
}
|
||||
|
||||
void CBagVar::increment() {
|
||||
assert(isValidObject(this));
|
||||
|
||||
if (isNumeric())
|
||||
setValue(getNumValue() + 1);
|
||||
}
|
||||
|
||||
ParseCodes CBagVar::setInfo(CBagIfstream &istr) {
|
||||
assert(isValidObject(this));
|
||||
|
||||
char szLocalStr[256];
|
||||
szLocalStr[0] = 0;
|
||||
CBofString sStr(szLocalStr, 256);
|
||||
istr.eatWhite();
|
||||
|
||||
getAlphaNumFromStream(istr, sStr);
|
||||
setName(sStr);
|
||||
|
||||
istr.eatWhite();
|
||||
|
||||
if (istr.peek() == 'A') {
|
||||
char sz2LocalStr[256];
|
||||
sz2LocalStr[0] = 0;
|
||||
sStr = CBofString(sz2LocalStr, 256);
|
||||
getAlphaNumFromStream(istr, sStr);
|
||||
|
||||
if (!sStr.find("AS")) {
|
||||
istr.eatWhite();
|
||||
getAlphaNumFromStream(istr, sStr);
|
||||
if (!sStr.find("TIMER")) {
|
||||
setTimer();
|
||||
g_VarManager->updateRegistration();
|
||||
} else if (!sStr.find("RANDOM")) {
|
||||
setRandom(true);
|
||||
g_VarManager->updateRegistration();
|
||||
} else if (!sStr.find("GLOBAL")) {
|
||||
setGlobal(true);
|
||||
g_VarManager->updateRegistration();
|
||||
} else {
|
||||
putbackStringOnStream(istr, sStr);
|
||||
putbackStringOnStream(istr, "AS ");
|
||||
}
|
||||
} else {
|
||||
putbackStringOnStream(istr, sStr);
|
||||
}
|
||||
}
|
||||
|
||||
istr.eatWhite();
|
||||
|
||||
if (istr.peek() == '=') {
|
||||
istr.getCh();
|
||||
istr.eatWhite();
|
||||
getAlphaNumFromStream(istr, sStr);
|
||||
setValue(sStr);
|
||||
}
|
||||
|
||||
istr.eatWhite();
|
||||
|
||||
return PARSING_DONE;
|
||||
}
|
||||
|
||||
CBagVarManager::CBagVarManager() {
|
||||
++nVarMngrs;
|
||||
}
|
||||
|
||||
CBagVarManager::~CBagVarManager() {
|
||||
if (nVarMngrs) {
|
||||
nVarMngrs--;
|
||||
releaseVariables();
|
||||
_xVarList.removeAll();
|
||||
|
||||
for (int i = 0; i < VAR_HASH_TABLE_SIZE; i++) {
|
||||
_xVarHashList[i].removeAll();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int HASHVAR(const char *p, int l) {
|
||||
int h = 0;
|
||||
for (int j = 0; j < l; j++) {
|
||||
h += p[j];
|
||||
}
|
||||
h %= VAR_HASH_TABLE_SIZE;
|
||||
|
||||
return h;
|
||||
}
|
||||
ErrorCode CBagVarManager::registerVariable(CBagVar *pVar) {
|
||||
_xVarList.addToTail(pVar);
|
||||
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
// Arranges the list so that timer variables are in the front
|
||||
ErrorCode CBagVarManager::updateRegistration() {
|
||||
bool bFoundLastTimer = false;
|
||||
int i;
|
||||
|
||||
// Read the timers at the beginning
|
||||
for (i = 0; i < _xVarList.getCount() && !bFoundLastTimer; ++i) {
|
||||
if (!_xVarList[i]->isTimer()) {
|
||||
bFoundLastTimer = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure there are no more timers in the list
|
||||
if (bFoundLastTimer) {
|
||||
for (/*- i determined in previous for loop -*/; i < _xVarList.getCount(); ++i) {
|
||||
if (_xVarList[i]->isTimer()) {
|
||||
CBagVar *pVar = _xVarList[i];
|
||||
_xVarList.remove(i);
|
||||
_xVarList.addToHead(pVar);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ERR_UNKNOWN;
|
||||
}
|
||||
|
||||
ErrorCode CBagVarManager::unRegisterVariable(CBagVar *pVar) {
|
||||
// Find and remove specified variable from the Var manager list
|
||||
//
|
||||
|
||||
CBofListNode<CBagVar *> *pList = _xVarList.getTail();
|
||||
while (pList != nullptr) {
|
||||
|
||||
if (pList->getNodeItem() == pVar) {
|
||||
_xVarList.remove(pList);
|
||||
break;
|
||||
}
|
||||
|
||||
pList = pList->_pPrev;
|
||||
}
|
||||
|
||||
// Remove it from the hash table also.
|
||||
char szLocalBuff[256];
|
||||
CBofString varStr(szLocalBuff, 256);
|
||||
varStr = pVar->getName();
|
||||
|
||||
// Hash it
|
||||
int nHashVal = HASHVAR(szLocalBuff, varStr.getLength());
|
||||
CBofList<CBagVar *> *pVarList = &_xVarHashList[nHashVal];
|
||||
|
||||
// Search the hash table and remove it when we're done.
|
||||
for (int i = 0; i < pVarList->getCount(); ++i) {
|
||||
CBagVar *pHashVar = pVarList->getNodeItem(i);
|
||||
if (pVar == pHashVar) {
|
||||
pVarList->remove(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
// The timers must be at the beginning of the list
|
||||
ErrorCode CBagVarManager::incrementTimers() {
|
||||
volatile bool bFoundLastTimer = false;
|
||||
|
||||
// Read the timers at the beginning
|
||||
for (int i = 0; i < _xVarList.getCount() && !bFoundLastTimer; ++i) {
|
||||
CBagVar *pVar = _xVarList[i];
|
||||
if (pVar->isTimer()) {
|
||||
|
||||
// Hack to keep the game time from exceeding 22:50
|
||||
if (pVar->getName().compareNoCase("TURNCOUNT") == 0) {
|
||||
if (pVar->getNumValue() == 2250) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
pVar->increment();
|
||||
}
|
||||
}
|
||||
|
||||
// Separate turn world out of event world and only execute when we
|
||||
// increment the timers.
|
||||
CBagEventSDev::setEvalTurnEvents(true);
|
||||
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
ErrorCode CBagVarManager::releaseVariables(bool bIncludeGlobals) {
|
||||
|
||||
if (bIncludeGlobals) {
|
||||
while (_xVarList.getCount()) {
|
||||
CBagVar *pVar = _xVarList.removeHead();
|
||||
delete pVar;
|
||||
}
|
||||
} else { // Do not include globals
|
||||
for (int i = _xVarList.getCount() - 1; i >= 0; i--) {
|
||||
CBagVar *pVar = _xVarList[i];
|
||||
if (pVar && !pVar->isGlobal()) {
|
||||
_xVarList.remove(i);
|
||||
delete pVar;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
CBagVar *CBagVarManager::getVariable(const CBofString &sName) {
|
||||
// Use the hash table to find the variable.
|
||||
char szLocalBuff[256];
|
||||
CBofString varStr(szLocalBuff, 256);
|
||||
varStr = sName;
|
||||
|
||||
int nHashVal = HASHVAR(szLocalBuff, varStr.getLength());
|
||||
|
||||
CBofList<CBagVar *> *pVarList = &_xVarHashList[nHashVal];
|
||||
for (int i = 0; i < pVarList->getCount(); ++i) {
|
||||
CBagVar *pVar = pVarList->getNodeItem(i);
|
||||
if (pVar != nullptr && (pVar->getName().getLength() == sName.getLength()) && !pVar->getName().find(sName)) {
|
||||
return pVar;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void CBagVar::setName(const CBofString &s) {
|
||||
_sVarName = s;
|
||||
|
||||
CBagel *pApp = CBagel::getBagApp();
|
||||
if (pApp) {
|
||||
CBagMasterWin *pMainWin = pApp->getMasterWnd();
|
||||
|
||||
if (!s.isEmpty() && pMainWin && pMainWin->getVariableManager()) {
|
||||
char szLocalBuff[256];
|
||||
CBofString varStr(szLocalBuff, 256);
|
||||
varStr = _sVarName;
|
||||
int nHashVal = HASHVAR(szLocalBuff, varStr.getLength());
|
||||
g_VarManager->_xVarHashList[nHashVal].addToTail(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
164
engines/bagel/spacebar/baglib/var.h
Normal file
164
engines/bagel/spacebar/baglib/var.h
Normal file
@@ -0,0 +1,164 @@
|
||||
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BAGEL_BAGLIB_VAR_H
|
||||
#define BAGEL_BAGLIB_VAR_H
|
||||
|
||||
#include "bagel/spacebar/baglib/parse_object.h"
|
||||
#include "bagel/boflib/string.h"
|
||||
#include "bagel/spacebar/boflib/list.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
class CBagVar : public CBagParseObject, public CBofObject {
|
||||
public:
|
||||
enum VARTYPE {
|
||||
STRING = 0, NUMBER = 1, BOOLEAN = 2
|
||||
};
|
||||
|
||||
private:
|
||||
CBofString _sVarName; // Name of the variable
|
||||
CBofString _sVarValue; // Value of the variable if not a reference
|
||||
VARTYPE _xVarType; // Type of variable, string
|
||||
bool _bGlobal : 1; // Is the variable a constant
|
||||
bool _bConstant : 1; // Is the variable a constant
|
||||
bool _bReference : 1; // Is the variable a reference to an objects state date
|
||||
bool _bTimer : 1; // Is the variable updated on object timer events
|
||||
bool _bRandom : 1; // Is the variable updated as a random number
|
||||
bool _freeze = false;
|
||||
|
||||
public:
|
||||
CBagVar();
|
||||
CBagVar(const CBofString &sName, const CBofString &sValue, bool bAddToList);
|
||||
virtual ~CBagVar();
|
||||
|
||||
ParseCodes setInfo(CBagIfstream &) override;
|
||||
|
||||
const CBofString &getName() {
|
||||
return _sVarName;
|
||||
}
|
||||
// const CBofString& getValue() { return _sVarValue; }
|
||||
const CBofString &getValue();
|
||||
int getNumValue();
|
||||
bool isGlobal() {
|
||||
return _bGlobal;
|
||||
}
|
||||
bool isConstant() {
|
||||
return _bConstant;
|
||||
}
|
||||
bool isNumeric() {
|
||||
return _xVarType == NUMBER;
|
||||
}
|
||||
bool isBoolean() {
|
||||
return _xVarType == BOOLEAN;
|
||||
}
|
||||
bool isString() {
|
||||
return _xVarType == STRING;
|
||||
}
|
||||
bool isReference() {
|
||||
return _bReference;
|
||||
}
|
||||
bool isTimer() {
|
||||
return _bTimer;
|
||||
}
|
||||
bool isRandom() {
|
||||
return _bRandom;
|
||||
}
|
||||
bool isFrozen() const {
|
||||
return _freeze;
|
||||
}
|
||||
VARTYPE getType() {
|
||||
return _xVarType;
|
||||
}
|
||||
|
||||
// Whenever setting the name, add this object to the hash table.
|
||||
void setName(const CBofString &s);
|
||||
void setValue(const CBofString &s);
|
||||
void setValue(int nVal);
|
||||
void setBoolValue(bool bVal);
|
||||
void setGlobal(bool bVal = true) {
|
||||
_bGlobal = bVal;
|
||||
}
|
||||
void setConstant(bool bVal = true) {
|
||||
_bConstant = bVal;
|
||||
}
|
||||
void setReference(bool bVal = true) {
|
||||
_bReference = bVal;
|
||||
}
|
||||
void setTimer(bool bVal = true) {
|
||||
_bTimer = bVal;
|
||||
}
|
||||
void setRandom(bool bVal = true) {
|
||||
_bRandom = bVal;
|
||||
}
|
||||
void setFreeze(bool bVal = true) {
|
||||
_freeze = bVal;
|
||||
}
|
||||
void setString() {
|
||||
_xVarType = STRING;
|
||||
}
|
||||
void setNumeric() {
|
||||
_xVarType = NUMBER;
|
||||
}
|
||||
void setBoolean() {
|
||||
_xVarType = BOOLEAN;
|
||||
}
|
||||
|
||||
void increment();
|
||||
};
|
||||
|
||||
// This could be templated with the storage device manager
|
||||
#define VAR_HASH_TABLE_SIZE 131
|
||||
|
||||
class CBagVarManager : public CBagParseObject, public CBofObject {
|
||||
private:
|
||||
static int nVarMngrs;
|
||||
CBofList<CBagVar *> _xVarList;
|
||||
|
||||
public:
|
||||
CBagVarManager();
|
||||
virtual ~CBagVarManager();
|
||||
static void initialize();
|
||||
|
||||
ErrorCode registerVariable(CBagVar *pVar);
|
||||
ErrorCode unRegisterVariable(CBagVar *pVar);
|
||||
ErrorCode updateRegistration();
|
||||
ErrorCode releaseVariables(bool bIncludeGlobals = true);
|
||||
|
||||
ErrorCode incrementTimers();
|
||||
CBagVar *getVariable(const CBofString &sName);
|
||||
CBagVar *getVariable(int i) {
|
||||
return _xVarList[i];
|
||||
}
|
||||
int getNumVars() {
|
||||
return _xVarList.getCount();
|
||||
}
|
||||
|
||||
// Use a hash table to lookup variables.
|
||||
CBofList<CBagVar *> _xVarHashList[VAR_HASH_TABLE_SIZE];
|
||||
};
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
|
||||
#endif
|
||||
208
engines/bagel/spacebar/baglib/variable_object.cpp
Normal file
208
engines/bagel/spacebar/baglib/variable_object.cpp
Normal file
@@ -0,0 +1,208 @@
|
||||
/* 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/variable_object.h"
|
||||
#include "bagel/spacebar/baglib/master_win.h"
|
||||
#include "bagel/spacebar/baglib/var.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
CBagVariableObject::CBagVariableObject() : CBagObject() {
|
||||
_xObjType = VAR_OBJ;
|
||||
_nPointSize = 16;
|
||||
_nFGColor = CTEXT_COLOR;
|
||||
setVisible(true);
|
||||
setTimeless(true);
|
||||
}
|
||||
|
||||
CBagVariableObject::~CBagVariableObject() {
|
||||
CBagVariableObject::detach();
|
||||
}
|
||||
|
||||
ErrorCode CBagVariableObject::attach() {
|
||||
CBagVar *xVar = g_VarManager->getVariable(getFileName());
|
||||
|
||||
if (xVar && !getRefName().isEmpty())
|
||||
xVar->setValue(getRefName());
|
||||
|
||||
return CBagObject::attach();
|
||||
}
|
||||
|
||||
ErrorCode CBagVariableObject::detach() {
|
||||
return CBagObject::detach();
|
||||
}
|
||||
|
||||
CBofRect CBagVariableObject::getRect() {
|
||||
CBofPoint p = getPosition();
|
||||
CBofSize s = getSize();
|
||||
CBofRect r = CBofRect(p, s);
|
||||
return r;
|
||||
}
|
||||
|
||||
//
|
||||
// Takes in info and then removes the relative information and returns the info
|
||||
// without the relevant info.
|
||||
ParseCodes CBagVariableObject::setInfo(CBagIfstream &istr) {
|
||||
bool nObjectUpdated = false;
|
||||
|
||||
while (!istr.eof()) {
|
||||
istr.eatWhite();
|
||||
|
||||
char ch = (char)istr.peek();
|
||||
switch (ch) {
|
||||
//
|
||||
// SIZE n - n point size of the txt
|
||||
//
|
||||
case 'S': {
|
||||
char szLocalStr[256];
|
||||
szLocalStr[0] = 0;
|
||||
CBofString sStr(szLocalStr, 256);
|
||||
|
||||
getAlphaNumFromStream(istr, sStr);
|
||||
|
||||
if (!sStr.find("SIZE")) {
|
||||
istr.eatWhite();
|
||||
getIntFromStream(istr, _nPointSize);
|
||||
nObjectUpdated = true;
|
||||
} else {
|
||||
putbackStringOnStream(istr, sStr);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
//
|
||||
// COLOR n - n color index
|
||||
//
|
||||
case 'C': {
|
||||
char szLocalStr[256];
|
||||
szLocalStr[0] = 0;
|
||||
CBofString sStr(szLocalStr, 256);
|
||||
|
||||
getAlphaNumFromStream(istr, sStr);
|
||||
|
||||
if (!sStr.find("COLOR")) {
|
||||
int nColor;
|
||||
istr.eatWhite();
|
||||
getIntFromStream(istr, nColor);
|
||||
switch (nColor) {
|
||||
case 0:
|
||||
_nFGColor = RGB(0, 0, 0);
|
||||
break; // black
|
||||
case 1:
|
||||
_nFGColor = RGB(255, 0, 0);
|
||||
break;
|
||||
case 2:
|
||||
_nFGColor = CTEXT_YELLOW;
|
||||
break;
|
||||
case 3:
|
||||
_nFGColor = RGB(0, 255, 0);
|
||||
break;
|
||||
case 4:
|
||||
_nFGColor = RGB(0, 255, 255);
|
||||
break;
|
||||
case 5:
|
||||
_nFGColor = RGB(0, 0, 255);
|
||||
break;
|
||||
case 6:
|
||||
_nFGColor = RGB(255, 0, 255);
|
||||
break;
|
||||
case 7:
|
||||
_nFGColor = CTEXT_WHITE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
nObjectUpdated = true;
|
||||
} else {
|
||||
putbackStringOnStream(istr, sStr);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
// No match return from function
|
||||
//
|
||||
default:
|
||||
ParseCodes parseCode = CBagObject::setInfo(istr);
|
||||
if (parseCode == PARSING_DONE) {
|
||||
return PARSING_DONE;
|
||||
}
|
||||
|
||||
if (parseCode == UPDATED_OBJECT) {
|
||||
nObjectUpdated = true;
|
||||
} else {
|
||||
if (nObjectUpdated)
|
||||
return UPDATED_OBJECT;
|
||||
|
||||
return UNKNOWN_TOKEN;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return PARSING_DONE;
|
||||
}
|
||||
|
||||
ErrorCode CBagVariableObject::update(CBofBitmap *pBmp, CBofPoint pt, CBofRect *pSrcRect, int) {
|
||||
ErrorCode errorCode = ERR_NONE;
|
||||
CBagVar *xVar = g_VarManager->getVariable(getFileName());
|
||||
|
||||
if (isAttached() && xVar && !(xVar->getValue().isEmpty())) {
|
||||
// FIXME: Offset for the last accessed time and # times counter in
|
||||
// entryway computer terminal. Otherwise, there's no space between
|
||||
// them and the preceding text
|
||||
Common::String name = xVar->getName().getBuffer();
|
||||
if (name.hasSuffix("_LAST") || name.hasSuffix("_TIMES"))
|
||||
pt.x += 10;
|
||||
// FIXME: Slight spacing out for Fleebix frequency display
|
||||
if (name == "NDJAM_INNERDIAL_DISPLAY")
|
||||
pt.x -= 5;
|
||||
else if (name == "NDJAM_OUTERDIAL_DISPLAY")
|
||||
pt.x += 5;
|
||||
|
||||
CBofRect r(pt, pSrcRect->size());
|
||||
errorCode = paintText(pBmp, &r, xVar->getValue(), mapFontPointSize(_nPointSize), TEXT_NORMAL, _nFGColor);
|
||||
|
||||
// Don't need to redraw!
|
||||
setDirty(false);
|
||||
}
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
ErrorCode CBagVariableObject::update(CBofWindow *pWnd, CBofPoint pt, CBofRect *pSrcRect, int) {
|
||||
ErrorCode errorCode = ERR_NONE;
|
||||
CBagVar *xVar = g_VarManager->getVariable(getFileName());
|
||||
|
||||
if (isAttached() && xVar && !(xVar->getValue().isEmpty())) {
|
||||
CBofRect r(pt, pSrcRect->size());
|
||||
|
||||
errorCode = paintText(pWnd, &r, xVar->getValue(), mapFontPointSize(_nPointSize), TEXT_NORMAL, _nFGColor);
|
||||
|
||||
// Don't need to redraw!
|
||||
setDirty(false);
|
||||
}
|
||||
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
71
engines/bagel/spacebar/baglib/variable_object.h
Normal file
71
engines/bagel/spacebar/baglib/variable_object.h
Normal file
@@ -0,0 +1,71 @@
|
||||
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BAGEL_BAGLIB_VARIABLE_OBJECT_H
|
||||
#define BAGEL_BAGLIB_VARIABLE_OBJECT_H
|
||||
|
||||
#include "bagel/spacebar/baglib/object.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
/**
|
||||
* CBagVariableObject is an object that can be place within the slide window.
|
||||
*/
|
||||
class CBagVariableObject : public CBagObject {
|
||||
private:
|
||||
CBofSize _xSize;
|
||||
int _nPointSize;
|
||||
COLORREF _nFGColor;
|
||||
|
||||
public:
|
||||
CBagVariableObject();
|
||||
virtual ~CBagVariableObject();
|
||||
|
||||
// Return true if the Object had members that are properly initialized/de-initialized
|
||||
ErrorCode attach() override;
|
||||
ErrorCode detach() override;
|
||||
|
||||
CBofRect getRect() override;
|
||||
|
||||
CBofSize getSize() {
|
||||
return _xSize;
|
||||
}
|
||||
|
||||
void setSize(const CBofSize &xSize) override {
|
||||
_xSize = xSize;
|
||||
}
|
||||
|
||||
ParseCodes setInfo(CBagIfstream &istr) override;
|
||||
|
||||
ErrorCode update(CBofBitmap *pBmp, CBofPoint pt, CBofRect *pSrcRect, int) override;
|
||||
ErrorCode update(CBofWindow *pWnd, CBofPoint pt, CBofRect *pSrcRect, int);
|
||||
|
||||
int mapFontPointSize(int size) const {
|
||||
return size;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
|
||||
#endif
|
||||
184
engines/bagel/spacebar/baglib/wield.cpp
Normal file
184
engines/bagel/spacebar/baglib/wield.cpp
Normal file
@@ -0,0 +1,184 @@
|
||||
/* 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/wield.h"
|
||||
#include "bagel/spacebar/baglib/menu_dlg.h"
|
||||
#include "bagel/spacebar/baglib/master_win.h"
|
||||
#include "bagel/spacebar/baglib/sprite_object.h"
|
||||
#include "bagel/spacebar/baglib/bagel.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
int CBagWield::_nWieldCursor = -1;
|
||||
|
||||
CBagWield::CBagWield(CBofWindow *pParent, const CBofRect &xRect) :
|
||||
CBagStorageDevBmp(pParent, xRect) {
|
||||
_xSDevType = SDEV_WIELD;
|
||||
_nObjects = 0; // This should be changed on the attach
|
||||
_pCurrObj = nullptr;
|
||||
}
|
||||
|
||||
|
||||
CBagWield::~CBagWield() {
|
||||
}
|
||||
|
||||
ErrorCode CBagWield::loadFile(const CBofString &sFile) {
|
||||
ErrorCode errorCode = CBagStorageDev::loadFile(sFile);
|
||||
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
ErrorCode CBagWield::attach() {
|
||||
CBagStorageDevBmp::attach();
|
||||
|
||||
// Take care of objects being held
|
||||
int nObjects = 0;
|
||||
_nObjects = 0;
|
||||
|
||||
for (int i = 0; i < getObjectCount(); ++i) {
|
||||
CBagObject *pObj = getObjectByPos(i);
|
||||
|
||||
if (pObj->isActive() && (pObj->getType() == BOF_SPRITE_OBJ || pObj->getType() == BOF_BMP_OBJ)) {
|
||||
if (nObjects == 0) {
|
||||
nObjects++;
|
||||
activateLocalObject(pObj);
|
||||
|
||||
} else {
|
||||
pObj->detach();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return _errCode;
|
||||
}
|
||||
|
||||
ErrorCode CBagWield::detach() {
|
||||
CBagStorageDev::detach();
|
||||
return CBagBmpObject::detach();
|
||||
}
|
||||
|
||||
bool CBagWield::onObjInteraction(CBagObject *pObj, CBagStorageDev *pSDev) {
|
||||
CBofString sObjName = pObj->getRefName();
|
||||
|
||||
if (sObjName.isEmpty())
|
||||
return false;
|
||||
|
||||
// Find the storage device
|
||||
if (CBagStorageDev::activateLocalObject(sObjName) != ERR_NONE)
|
||||
return false;
|
||||
|
||||
if (pSDev->deactivateLocalObject(sObjName) != ERR_NONE) {
|
||||
CBagStorageDev::deactivateLocalObject(sObjName);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
ErrorCode CBagWield::activateLocalObject(CBagObject *pObj) {
|
||||
ErrorCode errorCode = ERR_UNKNOWN;
|
||||
|
||||
if (pObj != nullptr) {
|
||||
// Since we can only hold one object at a time, put the object that
|
||||
// the user is currently holding into their stash (Inventory), and then
|
||||
// put the new object that they are trying to pick up into their wield.
|
||||
if (_nObjects == 1) {
|
||||
CBagObject *pPrevObj = getCurrObj();
|
||||
|
||||
if (pPrevObj != nullptr) {
|
||||
// Move current object to stash
|
||||
g_SDevManager->moveObject("INV_WLD", getName(), pPrevObj->getRefName());
|
||||
|
||||
} else {
|
||||
reportError(ERR_UNKNOWN, "Wielded Object has been lost");
|
||||
}
|
||||
|
||||
// There are no objects in wield
|
||||
_nObjects = 0;
|
||||
}
|
||||
|
||||
// Add to wield
|
||||
if (pObj->getMenuPtr() != nullptr) {
|
||||
CBagMenu::setUniversalObjectList(pObj->getMenuPtr()->getObjectList());
|
||||
}
|
||||
|
||||
if (pObj->getType() == SPRITE_OBJ) {
|
||||
setCurrObj(pObj);
|
||||
_nObjects++;
|
||||
CBagSpriteObject *pSpObj = (CBagSpriteObject *)pObj;
|
||||
setWieldCursor(pSpObj->getWieldCursor());
|
||||
}
|
||||
|
||||
// Fix for sometimes getting the wield menu instead of thud's order
|
||||
// menu. Do this by causing the wielded item to not have a location
|
||||
// on the You icon. (It's rectangle will appear empty)
|
||||
CBofPoint cPos(2056, 2056);
|
||||
pObj->setPosition(cPos);
|
||||
pObj->setFloating(false);
|
||||
|
||||
errorCode = CBagStorageDev::activateLocalObject(pObj);
|
||||
}
|
||||
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
ErrorCode CBagWield::deactivateLocalObject(CBagObject *pObj) {
|
||||
if (_nObjects == 1) {
|
||||
|
||||
if (pObj->getType() == SPRITE_OBJ) {
|
||||
setWieldCursor(-1);
|
||||
_nObjects--;
|
||||
}
|
||||
|
||||
CBagMenu::setUniversalObjectList(nullptr);
|
||||
CBagStorageDev::deactivateLocalObject(pObj);
|
||||
setCurrObj(nullptr);
|
||||
}
|
||||
|
||||
return _errCode;
|
||||
}
|
||||
|
||||
|
||||
ErrorCode CBagWield::update(CBofBitmap *pBmp, CBofPoint /*cPoint*/, CBofRect * /*pSrcRect*/, int /*nMaskColor*/) {
|
||||
assert(pBmp != nullptr);
|
||||
|
||||
// If this object is visible
|
||||
if (isVisible() && isAttached()) {
|
||||
|
||||
CBofBitmap *pYouIcon = getBackground();
|
||||
if (pYouIcon != nullptr) {
|
||||
pYouIcon->paint(pBmp, getPosition().x, getPosition().y, nullptr, DEFAULT_CHROMA_COLOR);
|
||||
setDirty(false);
|
||||
}
|
||||
}
|
||||
|
||||
// Set the firstpaint flag and attach objects to allow for immediate run objects to run
|
||||
if (_bFirstPaint) {
|
||||
_bFirstPaint = false;
|
||||
attachActiveObjects();
|
||||
}
|
||||
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
74
engines/bagel/spacebar/baglib/wield.h
Normal file
74
engines/bagel/spacebar/baglib/wield.h
Normal file
@@ -0,0 +1,74 @@
|
||||
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BAGEL_BAGLIB_WIELD_H
|
||||
#define BAGEL_BAGLIB_WIELD_H
|
||||
|
||||
#include "bagel/spacebar/baglib/storage_dev_bmp.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
class CBagWield : public CBagStorageDevBmp {
|
||||
private:
|
||||
static int _nWieldCursor;
|
||||
|
||||
CBagObject *_pCurrObj;
|
||||
int _nObjects; // The number of currently active objects
|
||||
|
||||
public:
|
||||
CBagWield(CBofWindow *pParent = nullptr, const CBofRect &xRect = CBofRect());
|
||||
virtual ~CBagWield();
|
||||
static void initialize() {
|
||||
_nWieldCursor = -1;
|
||||
}
|
||||
|
||||
CBagObject *getCurrObj() const {
|
||||
return _pCurrObj;
|
||||
}
|
||||
CBagObject *setCurrObj(CBagObject *pObj) {
|
||||
return _pCurrObj = pObj;
|
||||
}
|
||||
|
||||
static int getWieldCursor() {
|
||||
return _nWieldCursor;
|
||||
}
|
||||
static void setWieldCursor(int n) {
|
||||
_nWieldCursor = n;
|
||||
}
|
||||
|
||||
ErrorCode update(CBofBitmap *pBmp, CBofPoint pt, CBofRect *pSrcRect = nullptr, int nMaskColor = -1) override;
|
||||
|
||||
ErrorCode loadFile(const CBofString &sFile) override;
|
||||
bool onObjInteraction(CBagObject *pObj, CBagStorageDev *pSDev) override;
|
||||
|
||||
ErrorCode attach() override;
|
||||
ErrorCode detach() override;
|
||||
|
||||
ErrorCode activateLocalObject(CBagObject *pObj) override;
|
||||
ErrorCode deactivateLocalObject(CBagObject *pObj) override;
|
||||
};
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
|
||||
#endif
|
||||
318
engines/bagel/spacebar/baglib/zoom_pda.cpp
Normal file
318
engines/bagel/spacebar/baglib/zoom_pda.cpp
Normal file
@@ -0,0 +1,318 @@
|
||||
/* 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/button_object.h"
|
||||
#include "bagel/spacebar/baglib/master_win.h"
|
||||
#include "bagel/spacebar/baglib/time_object.h"
|
||||
#include "bagel/spacebar/baglib/rp_object.h"
|
||||
#include "bagel/spacebar/baglib/wield.h"
|
||||
#include "bagel/spacebar/baglib/zoom_pda.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
#define ZOOM_MOO_WLD "MOOZ_WLD"
|
||||
#define ZOOM_INV_WLD "INVZ_WLD"
|
||||
#define ZOOM_MAP_WLD "MAPZ_WLD"
|
||||
#define ZOOM_LOG_WLD "LOGZ_WLD"
|
||||
|
||||
// Keep track of updates...
|
||||
static uint32 g_lZoomPDALastUpdate;
|
||||
|
||||
void SBZoomPda::initialize() {
|
||||
g_lZoomPDALastUpdate = 0;
|
||||
}
|
||||
|
||||
SBZoomPda::SBZoomPda(CBofWindow *pParent, const CBofRect &xRect, bool bActivated)
|
||||
: CBagStorageDevWnd(),
|
||||
SBBasePda(pParent, xRect, bActivated) {
|
||||
_xSDevType = SDEV_ZOOMPDA;
|
||||
}
|
||||
|
||||
ErrorCode SBZoomPda::onRender(CBofBitmap *pBmp, CBofRect *pRect) {
|
||||
assert(isValidObject(this));
|
||||
assert(pBmp != nullptr);
|
||||
|
||||
// Paint the storage device
|
||||
if (pBmp != nullptr) {
|
||||
bool bUpdate = false;
|
||||
// Only clear the background and paint the backdrop if we've
|
||||
// been instructed to.
|
||||
|
||||
if (preFilterPan()) {
|
||||
preFilter(pBmp, pRect, (_curDisplay == nullptr ? nullptr : _curDisplay->getObjectList()));
|
||||
|
||||
// Paint our storage device the first time through and the next time
|
||||
// through, this takes care of multiple text drawing problems (trust me!).
|
||||
if (_bFirstPaint == false) {
|
||||
setPreFilterPan(false);
|
||||
}
|
||||
|
||||
if (getWorkBmp() != nullptr) {
|
||||
getWorkBmp()->paint(pBmp, pRect, pRect);
|
||||
}
|
||||
|
||||
bUpdate = true;
|
||||
}
|
||||
|
||||
paintStorageDevice(nullptr, pBmp, pRect);
|
||||
|
||||
// Paint the inventory or Map to backdrop
|
||||
if (bUpdate && (_curDisplay != nullptr))
|
||||
_curDisplay->update(pBmp, _curDisplay->getPosition(), pRect);
|
||||
}
|
||||
|
||||
return _errCode;
|
||||
}
|
||||
|
||||
ErrorCode SBZoomPda::loadFile(const CBofString &sFile) {
|
||||
ErrorCode errorCode = CBagStorageDev::loadFile(sFile);
|
||||
removeObject(_mooWnd);
|
||||
removeObject(_invWnd);
|
||||
removeObject(_mapWnd);
|
||||
removeObject(_logWnd);
|
||||
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
ErrorCode SBZoomPda::detach() {
|
||||
bool bLogZoomed = (_logWnd == _curDisplay);
|
||||
|
||||
// Other classes need to know if we're zoomed
|
||||
setZoomed(false);
|
||||
if (_invWnd) {
|
||||
_invWnd->detach();
|
||||
_invWnd = nullptr;
|
||||
}
|
||||
|
||||
if (_mooWnd) {
|
||||
_mooWnd->detach();
|
||||
_mooWnd = nullptr;
|
||||
}
|
||||
|
||||
if (_mapWnd) {
|
||||
_mapWnd->detach();
|
||||
_mapWnd = nullptr;
|
||||
}
|
||||
|
||||
if (_logWnd) {
|
||||
_logWnd->detach();
|
||||
_logWnd = nullptr;
|
||||
}
|
||||
|
||||
// Since the regular PDA does not have a detach method (it doesn't get
|
||||
// flushed out until you go to a flashback or quit the game), go through
|
||||
// the entire list of RPO's (residue print objects) and restore the saved
|
||||
// variable values. We do this so that any values that were changed in
|
||||
// the zoomed version are propagated down to the un-zoomed pda.
|
||||
|
||||
CBagRPObject::synchronizeResiduePrintedObjects(bLogZoomed);
|
||||
|
||||
CBagStorageDevWnd::detach();
|
||||
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
ErrorCode SBZoomPda::attach() {
|
||||
// Other classes need to know if we're zoomed
|
||||
setZoomed(true);
|
||||
|
||||
ErrorCode errorCode = CBagStorageDevWnd::attach();
|
||||
if (errorCode == ERR_NONE) {
|
||||
CBagStorageDev *pSDev;
|
||||
if (!_mooWnd) {
|
||||
pSDev = g_SDevManager->getStorageDevice(ZOOM_MOO_WLD);
|
||||
|
||||
if (pSDev != nullptr) {
|
||||
_mooWnd = (CBagStorageDevBmp *)pSDev;
|
||||
_mooWnd->setAssociateWnd(getAssociateWnd());
|
||||
_mooWnd->setTransparent(false);
|
||||
_mooWnd->setVisible(false);
|
||||
errorCode = _mooWnd->attach();
|
||||
}
|
||||
} else {
|
||||
// Already attached just update
|
||||
_mooWnd->attachActiveObjects();
|
||||
}
|
||||
|
||||
if (!_invWnd) {
|
||||
pSDev = g_SDevManager->getStorageDevice(ZOOM_INV_WLD);
|
||||
if (pSDev != nullptr) {
|
||||
_invWnd = (CBagStorageDevBmp *)pSDev;
|
||||
_invWnd->setAssociateWnd(getAssociateWnd());
|
||||
|
||||
_invWnd->setTransparent(false);
|
||||
_invWnd->setVisible(false);
|
||||
errorCode = _invWnd->attach();
|
||||
} else {
|
||||
bofMessageBox("No PDA INVENTORY found", __FILE__);
|
||||
errorCode = ERR_UNKNOWN;
|
||||
}
|
||||
} else {
|
||||
// Already attached just update
|
||||
_invWnd->attachActiveObjects();
|
||||
}
|
||||
|
||||
if (!_mapWnd) {
|
||||
pSDev = g_SDevManager->getStorageDevice(ZOOM_MAP_WLD);
|
||||
if (pSDev != nullptr) {
|
||||
_mapWnd = (CBagStorageDevBmp *)pSDev;
|
||||
_mapWnd->setAssociateWnd(getAssociateWnd());
|
||||
|
||||
_mapWnd->setTransparent(false);
|
||||
_mapWnd->setVisible(false);
|
||||
errorCode = _mapWnd->attach();
|
||||
} else {
|
||||
bofMessageBox("No PDA MAP found", __FILE__);
|
||||
errorCode = ERR_UNKNOWN;
|
||||
}
|
||||
} else {
|
||||
// Already attached just update
|
||||
_mapWnd->attachActiveObjects();
|
||||
}
|
||||
|
||||
if (!_logWnd) {
|
||||
pSDev = g_SDevManager->getStorageDevice(ZOOM_LOG_WLD);
|
||||
if (pSDev != nullptr) {
|
||||
_logWnd = (CBagStorageDevBmp *)pSDev;
|
||||
_logWnd->setAssociateWnd(getAssociateWnd());
|
||||
|
||||
_logWnd->setTransparent(false);
|
||||
_logWnd->setVisible(false);
|
||||
errorCode = _logWnd->attach();
|
||||
}
|
||||
} else {
|
||||
// Already attached just update
|
||||
_logWnd->attachActiveObjects();
|
||||
}
|
||||
|
||||
if (_pdaMode == PDA_INV_MODE) {
|
||||
showInventory();
|
||||
} else if (_pdaMode == PDA_MAP_MODE) {
|
||||
showMap();
|
||||
} else if (_pdaMode == PDA_LOG_MODE) {
|
||||
showLog();
|
||||
}
|
||||
|
||||
show();
|
||||
invalidateRect(nullptr);
|
||||
updateWindow();
|
||||
}
|
||||
|
||||
// Keep track of updates...
|
||||
g_lZoomPDALastUpdate = 0;
|
||||
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
CBagObject *SBZoomPda::onNewButtonObject(const CBofString &) {
|
||||
CBagButtonObject *PdaButtObj = new CBagButtonObject();
|
||||
PdaButtObj->setCallBack(pdaButtonHandler, (SBBasePda *)this);
|
||||
|
||||
return PdaButtObj;
|
||||
}
|
||||
|
||||
void SBZoomPda::onLButtonUp(uint32 nFlags, CBofPoint *xPoint, void *) {
|
||||
// Need to override the CBagStorageDevWnd::onLButtonUp(nFlags, xPoint)
|
||||
// to do our own thing.
|
||||
|
||||
*_xCursorLocation = *xPoint;
|
||||
CBofPoint xCursorLocation = devPtToViewPort(*xPoint);
|
||||
|
||||
CBagObject *pObj = getObject(xCursorLocation, true);
|
||||
if (pObj != nullptr) {
|
||||
if (pObj->isActive()) {
|
||||
pObj->onLButtonUp(nFlags, xPoint);
|
||||
setLActiveObject(pObj);
|
||||
}
|
||||
} else {
|
||||
setLActivity(kMouseNONE);
|
||||
|
||||
if (_curDisplay) {
|
||||
CBofRect offset = CBagStorageDev::getRect();
|
||||
xPoint->x -= offset.topLeft().x;
|
||||
xPoint->y -= offset.topLeft().y;
|
||||
|
||||
// Make sure this stuff is nice and dirty before calling off
|
||||
// to the button handling routine, this assures that if we go from one screen
|
||||
// to the next, then we'll get redrawn.
|
||||
setPreFilterPan(true);
|
||||
makeListDirty(_curDisplay->getObjectList());
|
||||
|
||||
_curDisplay->onLButtonUp(nFlags, xPoint, nullptr);
|
||||
} else {
|
||||
// We have no mode yet, then pass it to the default method
|
||||
if (_pdaMode == PDA_NO_MODE) {
|
||||
CBagStorageDevWnd::onLButtonUp(nFlags, xPoint);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This thing could get trashed by the underlying code...
|
||||
if (isCreated()) {
|
||||
invalidateRect(nullptr);
|
||||
updateWindow();
|
||||
}
|
||||
}
|
||||
|
||||
void SBZoomPda::onMouseMove(uint32 nFlags, CBofPoint *pPoint, void *) {
|
||||
assert(isValidObject(this));
|
||||
|
||||
CBagStorageDev::onMouseMove(nFlags, pPoint, getAssociateWnd());
|
||||
|
||||
|
||||
// This should be on update cursor virtual func
|
||||
if (getExitOnEdge() && (pPoint->x < getExitOnEdge()) && (pPoint->y < 300) && !(getPrevSDev().isEmpty())) {
|
||||
CBagMasterWin::setActiveCursor(10);
|
||||
} else {
|
||||
CBofRect cRect = getBackdrop()->getRect();
|
||||
CBagMasterWin::setActiveCursor(getProperCursor(*pPoint, cRect));
|
||||
}
|
||||
}
|
||||
|
||||
void SBZoomPda::onMainLoop() {
|
||||
uint32 nCurTime = getTimer();
|
||||
|
||||
// Force an update every 1/4 second
|
||||
if (_pdaMode == PDA_INV_MODE || _pdaMode == PDA_MAP_MODE) {
|
||||
if (nCurTime > (g_lZoomPDALastUpdate + 250)) {
|
||||
g_lZoomPDALastUpdate = nCurTime;
|
||||
|
||||
setPreFilterPan(true);
|
||||
}
|
||||
}
|
||||
|
||||
CBagStorageDevWnd::onMainLoop();
|
||||
}
|
||||
|
||||
ErrorCode SBZoomPda::attachActiveObjects() {
|
||||
SBBasePda::attachActiveObjects();
|
||||
return CBagStorageDevWnd::attachActiveObjects();
|
||||
}
|
||||
|
||||
ErrorCode SBZoomPda::detachActiveObjects() {
|
||||
SBBasePda::detachActiveObjects();
|
||||
|
||||
return CBagStorageDevWnd::detachActiveObjects();
|
||||
}
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
67
engines/bagel/spacebar/baglib/zoom_pda.h
Normal file
67
engines/bagel/spacebar/baglib/zoom_pda.h
Normal file
@@ -0,0 +1,67 @@
|
||||
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BAGEL_BAGLIB_ZOOM_PDA_H
|
||||
#define BAGEL_BAGLIB_ZOOM_PDA_H
|
||||
|
||||
#include "bagel/spacebar/baglib/storage_dev_win.h"
|
||||
#include "bagel/spacebar/baglib/base_pda.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
class SBZoomPda : public CBagStorageDevWnd, public SBBasePda {
|
||||
public:
|
||||
/**
|
||||
* Constructor
|
||||
* @param pParent Pointer to the parent window
|
||||
* @param xRect Pda in parent window
|
||||
* @param bActivated State of PDA whe constructed (optional)
|
||||
*/
|
||||
SBZoomPda(CBofWindow *pParent = nullptr, const CBofRect &xRect = CBofRect(), bool bActivated = true);
|
||||
static void initialize();
|
||||
|
||||
ErrorCode attach() override;
|
||||
ErrorCode detach() override;
|
||||
|
||||
ErrorCode loadFile(const CBofString &sFile) override;
|
||||
void onMouseMove(uint32 nFlags, CBofPoint *, void * = nullptr) override;
|
||||
|
||||
/**
|
||||
* Called to overload specific types of sprite objects
|
||||
* @retrn Pointer to the new object
|
||||
*/
|
||||
CBagObject *onNewButtonObject(const CBofString &sInit) override;
|
||||
|
||||
void onMainLoop() override;
|
||||
|
||||
void onLButtonUp(uint32 nFlags, CBofPoint *xPoint, void * = nullptr) override;
|
||||
ErrorCode onRender(CBofBitmap *pBmp, CBofRect *pRect = nullptr) override;
|
||||
|
||||
ErrorCode attachActiveObjects() override;
|
||||
ErrorCode detachActiveObjects() override;
|
||||
};
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
|
||||
#endif
|
||||
141
engines/bagel/spacebar/bib_odds_wnd.cpp
Normal file
141
engines/bagel/spacebar/bib_odds_wnd.cpp
Normal file
@@ -0,0 +1,141 @@
|
||||
/* 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/bib_odds_wnd.h"
|
||||
#include "bagel/spacebar/bibble_window.h"
|
||||
#include "bagel/spacebar/spacebar.h"
|
||||
#include "bagel/spacebar/baglib/master_win.h"
|
||||
#include "bagel/spacebar/baglib/bagel.h"
|
||||
#include "bagel/spacebar/baglib/pan_window.h"
|
||||
#include "bagel/spacebar/boflib/std_keys.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
CBagObject *SBarBibOddsWnd::_wieldedObject;
|
||||
|
||||
void SBarBibOddsWnd::initialize() {
|
||||
_wieldedObject = nullptr;
|
||||
}
|
||||
|
||||
SBarBibOddsWnd::SBarBibOddsWnd() : CBagChatWnd() {
|
||||
}
|
||||
|
||||
SBarBibOddsWnd::~SBarBibOddsWnd() {
|
||||
}
|
||||
|
||||
ErrorCode SBarBibOddsWnd::detach() {
|
||||
for (int i = 0; i < BIBBLE_NUM_BET_AREAS; i++) {
|
||||
|
||||
// The sprite object start in the script at 500
|
||||
CBagObject *pObj = getObject(500 + i);
|
||||
|
||||
if (pObj != nullptr) {
|
||||
int nPayIdx = pObj->getState();
|
||||
g_engine->g_cBetAreas[i]._nPayOff1 = PAY_OFFS[nPayIdx]._nPay1;
|
||||
g_engine->g_cBetAreas[i]._nPayOff2 = PAY_OFFS[nPayIdx]._nPay2;
|
||||
}
|
||||
}
|
||||
|
||||
if (_wieldedObject) {
|
||||
g_SDevManager->addObject(CBagPanWindow::_pWieldBmp->getName(), _wieldedObject->getRefName());
|
||||
_wieldedObject = nullptr;
|
||||
}
|
||||
|
||||
return CBagChatWnd::detach();
|
||||
}
|
||||
|
||||
void SBarBibOddsWnd::onKeyHit(uint32 lKey, uint32 lRepCount) {
|
||||
CBagVar *pVar = g_VarManager->getVariable("TORSOSTATE");
|
||||
|
||||
if (pVar != nullptr) {
|
||||
CBofString StateStr = pVar->getValue();
|
||||
if (StateStr == "MAINMENU") {
|
||||
switch (lKey) {
|
||||
case BKEY_1:
|
||||
pVar->setValue("VIDINFO");
|
||||
attachActiveObjects();
|
||||
break;
|
||||
case BKEY_2:
|
||||
pVar->setValue("SETBIBBLE");
|
||||
attachActiveObjects();
|
||||
break;
|
||||
case BKEY_3:
|
||||
pVar->setValue("BADCODE");
|
||||
attachActiveObjects();
|
||||
break;
|
||||
case BKEY_4:
|
||||
pVar->setValue("TIPS");
|
||||
attachActiveObjects();
|
||||
break;
|
||||
case BKEY_5:
|
||||
close();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
} else if (StateStr == "SETBIBBLE") {
|
||||
switch (lKey) {
|
||||
case BKEY_1:
|
||||
pVar->setValue("SETBONK");
|
||||
attachActiveObjects();
|
||||
break;
|
||||
case BKEY_2:
|
||||
pVar->setValue("SETBAB");
|
||||
attachActiveObjects();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CBagChatWnd::onKeyHit(lKey, lRepCount);
|
||||
}
|
||||
|
||||
void SBarBibOddsWnd::onMouseMove(uint32 nFlags, CBofPoint *pPoint, void *) {
|
||||
CBagStorageDevWnd::onMouseMove(nFlags, pPoint);
|
||||
}
|
||||
|
||||
ErrorCode SBarBibOddsWnd::attach() {
|
||||
assert(isValidObject(this));
|
||||
|
||||
// If we have something wielded, put it on hold for now.
|
||||
if (CBagPanWindow::_pWieldBmp != nullptr) {
|
||||
_wieldedObject = CBagPanWindow::_pWieldBmp->getCurrObj();
|
||||
if (_wieldedObject != nullptr) {
|
||||
g_SDevManager->removeObject(CBagPanWindow::_pWieldBmp->getName(), _wieldedObject->getRefName());
|
||||
}
|
||||
}
|
||||
|
||||
// Don't call CBagChatWnd::attach() - We are overriding it's behavior
|
||||
if (CBagStorageDevWnd::attach() == ERR_NONE) {
|
||||
show();
|
||||
invalidateRect(nullptr);
|
||||
updateWindow();
|
||||
}
|
||||
|
||||
return _errCode;
|
||||
}
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
51
engines/bagel/spacebar/bib_odds_wnd.h
Normal file
51
engines/bagel/spacebar/bib_odds_wnd.h
Normal file
@@ -0,0 +1,51 @@
|
||||
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BAGEL_SPACEBAR_BIB_ODDS_WND_H
|
||||
#define BAGEL_SPACEBAR_BIB_ODDS_WND_H
|
||||
|
||||
#include "bagel/spacebar/baglib/chat_wnd.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
#define NUM_PAYOFFS 16
|
||||
|
||||
class SBarBibOddsWnd : public CBagChatWnd {
|
||||
public:
|
||||
SBarBibOddsWnd();
|
||||
virtual ~SBarBibOddsWnd();
|
||||
|
||||
virtual ErrorCode attach(); // Save wielded cursor
|
||||
virtual ErrorCode detach(); // This function detaches the background and necessary bitmaps
|
||||
|
||||
void onMouseMove(uint32 nFlags, CBofPoint *xPoint, void * = nullptr);
|
||||
void onKeyHit(uint32 lKey, uint32 lRepCount);
|
||||
|
||||
static void initialize();
|
||||
static CBagObject *_wieldedObject;
|
||||
};
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
|
||||
#endif
|
||||
1154
engines/bagel/spacebar/bibble_window.cpp
Normal file
1154
engines/bagel/spacebar/bibble_window.cpp
Normal file
File diff suppressed because it is too large
Load Diff
143
engines/bagel/spacebar/bibble_window.h
Normal file
143
engines/bagel/spacebar/bibble_window.h
Normal file
@@ -0,0 +1,143 @@
|
||||
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BAGEL_SPACEBAR_BIBBLE_WINDOW_H
|
||||
#define BAGEL_SPACEBAR_BIBBLE_WINDOW_H
|
||||
|
||||
#include "bagel/spacebar/baglib/storage_dev_win.h"
|
||||
#include "bagel/spacebar/boflib/gui/text_box.h"
|
||||
#include "bagel/spacebar/boflib/gui/button.h"
|
||||
#include "bagel/spacebar/boflib/gfx/sprite.h"
|
||||
#include "bagel/boflib/sound.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
#define BIBBLE_NUM_BUTTONS 12
|
||||
#define BIBBLE_NUM_BIBBLES 3
|
||||
#define BIBBLE_NUM_SHOUTS 4
|
||||
#define BIBBLE_NUM_PAYOFFS 16
|
||||
#define BIBBLE_NUM_BET_AREAS 24
|
||||
|
||||
struct ST_PAYOFFS {
|
||||
int _nPay1;
|
||||
int _nPay2;
|
||||
};
|
||||
|
||||
struct CBetAreaDef {
|
||||
int _nBet;
|
||||
int _left;
|
||||
int _top;
|
||||
int _right;
|
||||
int _bottom;
|
||||
int _nPayOff1;
|
||||
int _nPayOff2;
|
||||
const char *_cAudioFile;
|
||||
const char *_cPayFile;
|
||||
};
|
||||
|
||||
class CBetArea : public CBofObject {
|
||||
public:
|
||||
CBetArea() {}
|
||||
CBetArea(const CBetAreaDef &def);
|
||||
|
||||
// Data members
|
||||
CBofRect _cRect;
|
||||
int _nBet = 0;
|
||||
int _nPayOff1 = 0;
|
||||
int _nPayOff2 = 0;
|
||||
bool _bWon = false;
|
||||
CBofString _cAudioFile;
|
||||
CBofString _cPayFile;
|
||||
};
|
||||
|
||||
extern CBetAreaDef BET_AREAS[BIBBLE_NUM_BET_AREAS];
|
||||
extern const ST_PAYOFFS PAY_OFFS[BIBBLE_NUM_PAYOFFS];
|
||||
|
||||
|
||||
class CBibbleWindow : public CBagStorageDevWnd {
|
||||
public:
|
||||
CBibbleWindow();
|
||||
|
||||
virtual ErrorCode attach();
|
||||
virtual ErrorCode detach();
|
||||
|
||||
virtual void onBofButton(CBofObject *pButton, int nState);
|
||||
virtual void onClose();
|
||||
|
||||
protected:
|
||||
ErrorCode playGame();
|
||||
ErrorCode bonkBibble(int nBibble, int nShout);
|
||||
|
||||
void calcOutcome();
|
||||
ErrorCode displayCredits();
|
||||
|
||||
ErrorCode highlight(CBetArea *pArea, byte nColor);
|
||||
ErrorCode unHighlight(CBetArea *pArea);
|
||||
|
||||
virtual void onLButtonDown(uint32 nFlags, CBofPoint *pPoint, void * = nullptr);
|
||||
virtual void onLButtonUp(uint32 nFlags, CBofPoint *pPoint, void * = nullptr);
|
||||
virtual void onLButtonDblClk(uint32 nFlags, CBofPoint *pPoint);
|
||||
virtual void onKeyHit(uint32 lKey, uint32 lRepCount);
|
||||
|
||||
virtual void onPaint(CBofRect *pRect);
|
||||
virtual void onMainLoop();
|
||||
virtual void onTimer(uint32 /*nTimerID*/) {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
// Data
|
||||
CBofSound *_pBkgSnd;
|
||||
CBofBmpButton *_pButtons[BIBBLE_NUM_BUTTONS];
|
||||
CBofText *_pCreditsText;
|
||||
CBofSprite *_pMasterBibble;
|
||||
CBofSprite *_pBibble[BIBBLE_NUM_BIBBLES];
|
||||
CBofSprite *_pBall;
|
||||
CBofSprite *_pArch1;
|
||||
CBofSprite *_pArch2;
|
||||
CBofSprite *_pArch3;
|
||||
CBofSound *_pShouts[BIBBLE_NUM_SHOUTS];
|
||||
uint32 _nNumCredits;
|
||||
|
||||
int _nBall1; // Which Bibble hit by ball 1
|
||||
int _nBall2; // Which Bibble hit by ball 2
|
||||
int _nBall3; // Which Bibble hit by ball 3
|
||||
|
||||
int _nBall1Said;
|
||||
int _nBall2Said;
|
||||
int _nBall3Said;
|
||||
|
||||
int _nNumShout1;
|
||||
int _nNumShout2;
|
||||
int _nNumShout3;
|
||||
int _nNumShout4;
|
||||
|
||||
int _nNumTopBonks;
|
||||
int _nNumMidBonks;
|
||||
int _nNumBotBonks;
|
||||
CBetArea *_pSelected;
|
||||
};
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
|
||||
#endif
|
||||
252
engines/bagel/spacebar/boflib/app.cpp
Normal file
252
engines/bagel/spacebar/boflib/app.cpp
Normal file
@@ -0,0 +1,252 @@
|
||||
/* 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 "graphics/framelimiter.h"
|
||||
#include "graphics/palette.h"
|
||||
#include "graphics/paletteman.h"
|
||||
#include "video/smk_decoder.h"
|
||||
|
||||
#include "bagel/spacebar/baglib/bagel.h"
|
||||
#include "bagel/spacebar/boflib/debug.h"
|
||||
#include "bagel/spacebar/boflib/app.h"
|
||||
#include "bagel/spacebar/boflib/timer.h"
|
||||
#include "bagel/spacebar/boflib/gfx/text.h"
|
||||
#include "bagel/boflib/sound.h"
|
||||
#include "bagel/bagel.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
#define DEBUG_LOG "DEBUG.LOG"
|
||||
#define DEBUG_INI "BOFFO.INI"
|
||||
|
||||
#define BOFDISP 0
|
||||
|
||||
CBofApp *CBofApp::_pBofApp;
|
||||
|
||||
CBofApp::CBofApp() {
|
||||
StartupCode();
|
||||
}
|
||||
|
||||
CBofApp::CBofApp(const char *pszAppName) {
|
||||
StartupCode();
|
||||
|
||||
setAppName(pszAppName);
|
||||
}
|
||||
|
||||
CBofApp::~CBofApp() {
|
||||
ShutDownCode();
|
||||
|
||||
_szAppName[0] = '\0';
|
||||
_pMainWnd = nullptr;
|
||||
_pPalette = nullptr;
|
||||
_pBofApp = nullptr;
|
||||
}
|
||||
|
||||
|
||||
void CBofApp::StartupCode() {
|
||||
_pBofApp = this;
|
||||
|
||||
// Open the Boffo debug options file (BOFFO.INI)
|
||||
g_pDebugOptions = new CBofDebugOptions(DEBUG_INI);
|
||||
g_pDebugOptions->readSetting("DebugOptions", "MainLoops", &_nIterations, DEFAULT_MAINLOOPS);
|
||||
|
||||
//
|
||||
// Initialize the boffo libraries
|
||||
//
|
||||
|
||||
// Init the Window library
|
||||
CBofWindow::initialize();
|
||||
|
||||
// Init the text library
|
||||
CBofText::initialize();
|
||||
}
|
||||
|
||||
|
||||
void CBofApp::ShutDownCode() {
|
||||
// Un-initialize the text library
|
||||
CBofText::shutdown();
|
||||
|
||||
// Shut down the Window library
|
||||
CBofWindow::shutdown();
|
||||
|
||||
// Kill any shared palette
|
||||
CBofPalette::setSharedPalette(nullptr);
|
||||
|
||||
if (g_pDebugOptions != nullptr) {
|
||||
delete g_pDebugOptions;
|
||||
g_pDebugOptions = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ErrorCode CBofApp::preInit() {
|
||||
if ((_pPalette == nullptr) && (_pDefPalette == nullptr)) {
|
||||
_pDefPalette = new CBofPalette();
|
||||
_pDefPalette->createDefault();
|
||||
setPalette(_pDefPalette);
|
||||
}
|
||||
|
||||
return _errCode;
|
||||
}
|
||||
|
||||
|
||||
ErrorCode CBofApp::initialize() {
|
||||
return _errCode;
|
||||
}
|
||||
|
||||
|
||||
ErrorCode CBofApp::runApp() {
|
||||
int nCount = _nIterations;
|
||||
|
||||
// Acquire and dispatch messages until we need to quit, or too many errors
|
||||
|
||||
Graphics::FrameLimiter limiter(g_system, 60, false);
|
||||
while (!g_engine->shouldQuit() && CBofError::getErrorCount() < MAX_ERRORS) {
|
||||
// Support for playing videos via the console
|
||||
if (_consoleVideo && _consoleVideo->isPlaying()) {
|
||||
if (_consoleVideo->needsUpdate()) {
|
||||
const Graphics::Surface *s = _consoleVideo->decodeNextFrame();
|
||||
Graphics::Palette pal(_consoleVideo->getPalette(), 256);
|
||||
g_engine->getScreen()->blitFrom(*s, Common::Point(0, 0), &pal);
|
||||
}
|
||||
|
||||
limiter.delayBeforeSwap();
|
||||
g_engine->getScreen()->update();
|
||||
limiter.startFrame();
|
||||
continue;
|
||||
|
||||
}
|
||||
|
||||
delete _consoleVideo;
|
||||
_consoleVideo = nullptr;
|
||||
|
||||
// Handle sounds and timers
|
||||
CBofSound::audioTask();
|
||||
CBofTimer::handleTimers();
|
||||
|
||||
if (nCount < 0) {
|
||||
nCount++;
|
||||
if (nCount == 0)
|
||||
nCount = 1;
|
||||
|
||||
} else {
|
||||
for (int i = 0; i < nCount; i++) {
|
||||
// Give each window it's own main loop (sort-of)
|
||||
CBofWindow *pWindow = CBofWindow::getWindowList();
|
||||
while (pWindow != nullptr) {
|
||||
if (shouldQuit())
|
||||
return ERR_NONE;
|
||||
|
||||
if (pWindow->isCreated()) {
|
||||
pWindow->onMainLoop();
|
||||
}
|
||||
|
||||
pWindow = (CBofWindow *)pWindow->getNext();
|
||||
}
|
||||
}
|
||||
|
||||
nCount = _nIterations;
|
||||
}
|
||||
|
||||
// Handle events
|
||||
_pMainWnd->handleEvents();
|
||||
|
||||
limiter.delayBeforeSwap();
|
||||
g_engine->getScreen()->update();
|
||||
limiter.startFrame();
|
||||
}
|
||||
|
||||
return _errCode;
|
||||
}
|
||||
|
||||
|
||||
ErrorCode CBofApp::shutdown() {
|
||||
return _errCode;
|
||||
}
|
||||
|
||||
|
||||
void CBofApp::postShutDown() {
|
||||
delete _pWindow;
|
||||
_pWindow = nullptr;
|
||||
|
||||
// No more palettes
|
||||
_pPalette = nullptr;
|
||||
|
||||
delete _pDefPalette;
|
||||
_pDefPalette = nullptr;
|
||||
}
|
||||
|
||||
void CBofApp::setPalette(CBofPalette *pPalette) {
|
||||
_pPalette = pPalette;
|
||||
|
||||
if (pPalette != nullptr) {
|
||||
if (g_system->getScreenFormat().bytesPerPixel == 1) {
|
||||
const auto &pal = pPalette->getPalette();
|
||||
g_system->getPaletteManager()->setPalette(pal._data, 0, pal._numColors);
|
||||
}
|
||||
|
||||
} else {
|
||||
// Use default palette
|
||||
_pPalette = _pDefPalette;
|
||||
}
|
||||
}
|
||||
|
||||
void CBofApp::addCursor(CBofCursor &cCursor) {
|
||||
_cCursorList.addToTail(cCursor);
|
||||
}
|
||||
|
||||
void CBofApp::delCursor(int nIndex) {
|
||||
_cCursorList.remove(nIndex);
|
||||
}
|
||||
|
||||
bool CBofApp::consolePlayVideo(const Common::Path &path) {
|
||||
delete _consoleVideo;
|
||||
|
||||
_consoleVideo = new Video::SmackerDecoder();
|
||||
_consoleVideo->setSoundType(Audio::Mixer::kSFXSoundType);
|
||||
if (_consoleVideo->loadFile(path)) {
|
||||
_consoleVideo->start();
|
||||
return true;
|
||||
|
||||
} else {
|
||||
delete _consoleVideo;
|
||||
_consoleVideo = nullptr;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Global routines
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
CBofPoint getMousePos() {
|
||||
return CBofWindow::getMousePos();
|
||||
}
|
||||
|
||||
|
||||
void bofMessageBox(const char *pszTitle, const char *pszMessage) {
|
||||
Common::String msg = Common::String::format("%s - %s", pszTitle, pszMessage);
|
||||
g_engine->errorDialog(msg.c_str());
|
||||
}
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
165
engines/bagel/spacebar/boflib/app.h
Normal file
165
engines/bagel/spacebar/boflib/app.h
Normal file
@@ -0,0 +1,165 @@
|
||||
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BAGEL_BOFLIB_APP_H
|
||||
#define BAGEL_BOFLIB_APP_H
|
||||
|
||||
#include "video/video_decoder.h"
|
||||
#include "bagel/spacebar/boflib/gui/window.h"
|
||||
#include "bagel/spacebar/boflib/gfx/cursor.h"
|
||||
#include "bagel/boflib/error.h"
|
||||
#include "bagel/spacebar/boflib/list.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
#define MAX_APP_NAME 128
|
||||
#define DEFAULT_MAINLOOPS 1
|
||||
#define kReallyFastPPC 50
|
||||
#define kReallySlowPPC 200
|
||||
|
||||
class CBofApp : public CBofError {
|
||||
private:
|
||||
CBofWindow *_pWindow = nullptr;
|
||||
CBofWindow *_captureControl = nullptr;
|
||||
CBofWindow *_focusControl = nullptr;
|
||||
Video::VideoDecoder *_consoleVideo = nullptr;
|
||||
|
||||
protected:
|
||||
void StartupCode();
|
||||
void ShutDownCode();
|
||||
|
||||
char _szAppName[MAX_APP_NAME] = { 0 };
|
||||
CBofList<CBofCursor> _cCursorList;
|
||||
CBofCursor _cDefaultCursor;
|
||||
|
||||
CBofWindow *_pMainWnd = nullptr;
|
||||
CBofPalette *_pPalette = nullptr;
|
||||
CBofPalette *_pDefPalette = nullptr;
|
||||
int _nScreenDX = 0;
|
||||
int _nScreenDY = 0;
|
||||
int _nColorDepth = 0;
|
||||
|
||||
int _nIterations = DEFAULT_MAINLOOPS;
|
||||
|
||||
static CBofApp *_pBofApp;
|
||||
|
||||
virtual bool shouldQuit() const = 0;
|
||||
|
||||
public:
|
||||
CBofApp();
|
||||
CBofApp(const char *pszAppName);
|
||||
virtual ~CBofApp();
|
||||
|
||||
ErrorCode preInit();
|
||||
void postShutDown();
|
||||
|
||||
// These functions can be overridden by the child class
|
||||
virtual ErrorCode initialize();
|
||||
virtual ErrorCode runApp();
|
||||
virtual ErrorCode shutdown();
|
||||
|
||||
virtual void setAppName(const char *pszNewAppName) {
|
||||
Common::strcpy_s(_szAppName, pszNewAppName);
|
||||
}
|
||||
|
||||
const char *getAppName() const {
|
||||
return (const char *)_szAppName;
|
||||
}
|
||||
|
||||
void setMainWindow(CBofWindow *pWnd) {
|
||||
_pMainWnd = pWnd;
|
||||
}
|
||||
CBofWindow *getMainWindow() const {
|
||||
return _pMainWnd;
|
||||
}
|
||||
|
||||
CBofWindow *getActualWindow() const {
|
||||
return _pWindow;
|
||||
}
|
||||
|
||||
void setPalette(CBofPalette *pPalette);
|
||||
|
||||
CBofPalette *getPalette() const {
|
||||
return _pPalette;
|
||||
}
|
||||
|
||||
int screenWidth() const {
|
||||
return _nScreenDX;
|
||||
}
|
||||
int screenHeight() const {
|
||||
return _nScreenDY;
|
||||
}
|
||||
int screenDepth() const {
|
||||
return _nColorDepth;
|
||||
}
|
||||
|
||||
CBofCursor getDefaultCursor() const {
|
||||
return _cDefaultCursor;
|
||||
}
|
||||
void setDefaultCursor(CBofCursor &cCursor) {
|
||||
_cDefaultCursor = cCursor;
|
||||
}
|
||||
|
||||
void addCursor(CBofCursor &cCursor);
|
||||
void delCursor(int nIndex);
|
||||
|
||||
CBofCursor getCursor(int nIndex) {
|
||||
return _cCursorList[nIndex];
|
||||
}
|
||||
int getNumberOfCursors() const {
|
||||
return _cCursorList.getCount();
|
||||
}
|
||||
|
||||
void setCaptureControl(CBofWindow *ctl) {
|
||||
_captureControl = ctl;
|
||||
}
|
||||
CBofWindow *getCaptureControl() const {
|
||||
return _captureControl;
|
||||
}
|
||||
void setFocusControl(CBofWindow *ctl) {
|
||||
_focusControl = ctl;
|
||||
}
|
||||
CBofWindow *getFocusControl() const {
|
||||
return _focusControl;
|
||||
}
|
||||
bool consolePlayVideo(const Common::Path &path);
|
||||
|
||||
static uint32 getMachineSpeed() {
|
||||
return kReallyFastPPC;
|
||||
}
|
||||
|
||||
static CBofApp *getApp() {
|
||||
return _pBofApp;
|
||||
}
|
||||
};
|
||||
|
||||
// Global routines
|
||||
//
|
||||
void bofMessageBox(const char *pszTitle, const char *pszMessage);
|
||||
|
||||
CBofPoint getMousePos();
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
|
||||
#endif
|
||||
57
engines/bagel/spacebar/boflib/array.h
Normal file
57
engines/bagel/spacebar/boflib/array.h
Normal file
@@ -0,0 +1,57 @@
|
||||
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BAGEL_BOFLIB_ARRAY_H
|
||||
#define BAGEL_BOFLIB_ARRAY_H
|
||||
|
||||
#include "common/array.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
template<class T>
|
||||
class Array : public Common::Array<T> {
|
||||
public:
|
||||
int indexOf(T t) {
|
||||
for (int i = 0; i < (int)this->size(); ++i) {
|
||||
if (this->operator[](i) == t)
|
||||
return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool contains(T t) const {
|
||||
return this->indexOf(t) != -1;
|
||||
}
|
||||
|
||||
void remove(T t) {
|
||||
int idx = this->indexOf(t);
|
||||
if (idx != -1)
|
||||
this->remove_at(idx);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
|
||||
#endif
|
||||
132
engines/bagel/spacebar/boflib/crc.cpp
Normal file
132
engines/bagel/spacebar/boflib/crc.cpp
Normal file
@@ -0,0 +1,132 @@
|
||||
/* 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/boflib/crc.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
static const uint16 crc32tabLo[256] = {
|
||||
0x0000, 0x3096, 0x612c, 0x51ba, 0xc419, 0xf48f, 0xa535, 0x95a3,
|
||||
0x8832, 0xb8a4, 0xe91e, 0xd988, 0x4c2b, 0x7cbd, 0x2d07, 0x1d91,
|
||||
0x1064, 0x20f2, 0x7148, 0x41de, 0xd47d, 0xe4eb, 0xb551, 0x85c7,
|
||||
0x9856, 0xa8c0, 0xf97a, 0xc9ec, 0x5c4f, 0x6cd9, 0x3d63, 0x0df5,
|
||||
0x20c8, 0x105e, 0x41e4, 0x7172, 0xe4d1, 0xd447, 0x85fd, 0xb56b,
|
||||
0xa8fa, 0x986c, 0xc9d6, 0xf940, 0x6ce3, 0x5c75, 0x0dcf, 0x3d59,
|
||||
0x30ac, 0x003a, 0x5180, 0x6116, 0xf4b5, 0xc423, 0x9599, 0xa50f,
|
||||
0xb89e, 0x8808, 0xd9b2, 0xe924, 0x7c87, 0x4c11, 0x1dab, 0x2d3d,
|
||||
0x4190, 0x7106, 0x20bc, 0x102a, 0x8589, 0xb51f, 0xe4a5, 0xd433,
|
||||
0xc9a2, 0xf934, 0xa88e, 0x9818, 0x0dbb, 0x3d2d, 0x6c97, 0x5c01,
|
||||
0x51f4, 0x6162, 0x30d8, 0x004e, 0x95ed, 0xa57b, 0xf4c1, 0xc457,
|
||||
0xd9c6, 0xe950, 0xb8ea, 0x887c, 0x1ddf, 0x2d49, 0x7cf3, 0x4c65,
|
||||
0x6158, 0x51ce, 0x0074, 0x30e2, 0xa541, 0x95d7, 0xc46d, 0xf4fb,
|
||||
0xe96a, 0xd9fc, 0x8846, 0xb8d0, 0x2d73, 0x1de5, 0x4c5f, 0x7cc9,
|
||||
0x713c, 0x41aa, 0x1010, 0x2086, 0xb525, 0x85b3, 0xd409, 0xe49f,
|
||||
0xf90e, 0xc998, 0x9822, 0xa8b4, 0x3d17, 0x0d81, 0x5c3b, 0x6cad,
|
||||
0x8320, 0xb3b6, 0xe20c, 0xd29a, 0x4739, 0x77af, 0x2615, 0x1683,
|
||||
0x0b12, 0x3b84, 0x6a3e, 0x5aa8, 0xcf0b, 0xff9d, 0xae27, 0x9eb1,
|
||||
0x9344, 0xa3d2, 0xf268, 0xc2fe, 0x575d, 0x67cb, 0x3671, 0x06e7,
|
||||
0x1b76, 0x2be0, 0x7a5a, 0x4acc, 0xdf6f, 0xeff9, 0xbe43, 0x8ed5,
|
||||
0xa3e8, 0x937e, 0xc2c4, 0xf252, 0x67f1, 0x5767, 0x06dd, 0x364b,
|
||||
0x2bda, 0x1b4c, 0x4af6, 0x7a60, 0xefc3, 0xdf55, 0x8eef, 0xbe79,
|
||||
0xb38c, 0x831a, 0xd2a0, 0xe236, 0x7795, 0x4703, 0x16b9, 0x262f,
|
||||
0x3bbe, 0x0b28, 0x5a92, 0x6a04, 0xffa7, 0xcf31, 0x9e8b, 0xae1d,
|
||||
0xc2b0, 0xf226, 0xa39c, 0x930a, 0x06a9, 0x363f, 0x6785, 0x5713,
|
||||
0x4a82, 0x7a14, 0x2bae, 0x1b38, 0x8e9b, 0xbe0d, 0xefb7, 0xdf21,
|
||||
0xd2d4, 0xe242, 0xb3f8, 0x836e, 0x16cd, 0x265b, 0x77e1, 0x4777,
|
||||
0x5ae6, 0x6a70, 0x3bca, 0x0b5c, 0x9eff, 0xae69, 0xffd3, 0xcf45,
|
||||
0xe278, 0xd2ee, 0x8354, 0xb3c2, 0x2661, 0x16f7, 0x474d, 0x77db,
|
||||
0x6a4a, 0x5adc, 0x0b66, 0x3bf0, 0xae53, 0x9ec5, 0xcf7f, 0xffe9,
|
||||
0xf21c, 0xc28a, 0x9330, 0xa3a6, 0x3605, 0x0693, 0x5729, 0x67bf,
|
||||
0x7a2e, 0x4ab8, 0x1b02, 0x2b94, 0xbe37, 0x8ea1, 0xdf1b, 0xef8d
|
||||
};
|
||||
|
||||
static const uint16 crc32tabHi[256] = {
|
||||
0x0000, 0x7707, 0xee0e, 0x9909, 0x076d, 0x706a, 0xe963, 0x9e64,
|
||||
0x0edb, 0x79dc, 0xe0d5, 0x97d2, 0x09b6, 0x7eb1, 0xe7b8, 0x90bf,
|
||||
0x1db7, 0x6ab0, 0xf3b9, 0x84be, 0x1ada, 0x6ddd, 0xf4d4, 0x83d3,
|
||||
0x136c, 0x646b, 0xfd62, 0x8a65, 0x1401, 0x6306, 0xfa0f, 0x8d08,
|
||||
0x3b6e, 0x4c69, 0xd560, 0xa267, 0x3c03, 0x4b04, 0xd20d, 0xa50a,
|
||||
0x35b5, 0x42b2, 0xdbbb, 0xacbc, 0x32d8, 0x45df, 0xdcd6, 0xabd1,
|
||||
0x26d9, 0x51de, 0xc8d7, 0xbfd0, 0x21b4, 0x56b3, 0xcfba, 0xb8bd,
|
||||
0x2802, 0x5f05, 0xc60c, 0xb10b, 0x2f6f, 0x5868, 0xc161, 0xb666,
|
||||
0x76dc, 0x01db, 0x98d2, 0xefd5, 0x71b1, 0x06b6, 0x9fbf, 0xe8b8,
|
||||
0x7807, 0x0f00, 0x9609, 0xe10e, 0x7f6a, 0x086d, 0x9164, 0xe663,
|
||||
0x6b6b, 0x1c6c, 0x8565, 0xf262, 0x6c06, 0x1b01, 0x8208, 0xf50f,
|
||||
0x65b0, 0x12b7, 0x8bbe, 0xfcb9, 0x62dd, 0x15da, 0x8cd3, 0xfbd4,
|
||||
0x4db2, 0x3ab5, 0xa3bc, 0xd4bb, 0x4adf, 0x3dd8, 0xa4d1, 0xd3d6,
|
||||
0x4369, 0x346e, 0xad67, 0xda60, 0x4404, 0x3303, 0xaa0a, 0xdd0d,
|
||||
0x5005, 0x2702, 0xbe0b, 0xc90c, 0x5768, 0x206f, 0xb966, 0xce61,
|
||||
0x5ede, 0x29d9, 0xb0d0, 0xc7d7, 0x59b3, 0x2eb4, 0xb7bd, 0xc0ba,
|
||||
0xedb8, 0x9abf, 0x03b6, 0x74b1, 0xead5, 0x9dd2, 0x04db, 0x73dc,
|
||||
0xe363, 0x9464, 0x0d6d, 0x7a6a, 0xe40e, 0x9309, 0x0a00, 0x7d07,
|
||||
0xf00f, 0x8708, 0x1e01, 0x6906, 0xf762, 0x8065, 0x196c, 0x6e6b,
|
||||
0xfed4, 0x89d3, 0x10da, 0x67dd, 0xf9b9, 0x8ebe, 0x17b7, 0x60b0,
|
||||
0xd6d6, 0xa1d1, 0x38d8, 0x4fdf, 0xd1bb, 0xa6bc, 0x3fb5, 0x48b2,
|
||||
0xd80d, 0xaf0a, 0x3603, 0x4104, 0xdf60, 0xa867, 0x316e, 0x4669,
|
||||
0xcb61, 0xbc66, 0x256f, 0x5268, 0xcc0c, 0xbb0b, 0x2202, 0x5505,
|
||||
0xc5ba, 0xb2bd, 0x2bb4, 0x5cb3, 0xc2d7, 0xb5d0, 0x2cd9, 0x5bde,
|
||||
0x9b64, 0xec63, 0x756a, 0x026d, 0x9c09, 0xeb0e, 0x7207, 0x0500,
|
||||
0x95bf, 0xe2b8, 0x7bb1, 0x0cb6, 0x92d2, 0xe5d5, 0x7cdc, 0x0bdb,
|
||||
0x86d3, 0xf1d4, 0x68dd, 0x1fda, 0x81be, 0xf6b9, 0x6fb0, 0x18b7,
|
||||
0x8808, 0xff0f, 0x6606, 0x1101, 0x8f65, 0xf862, 0x616b, 0x166c,
|
||||
0xa00a, 0xd70d, 0x4e04, 0x3903, 0xa767, 0xd060, 0x4969, 0x3e6e,
|
||||
0xaed1, 0xd9d6, 0x40df, 0x37d8, 0xa9bc, 0xdebb, 0x47b2, 0x30b5,
|
||||
0xbdbd, 0xcaba, 0x53b3, 0x24b4, 0xbad0, 0xcdd7, 0x54de, 0x23d9,
|
||||
0xb366, 0xc461, 0x5d68, 0x2a6f, 0xb40b, 0xc30c, 0x5a05, 0x2d02
|
||||
};
|
||||
|
||||
uint32 calculateCRC(const void *pBuffer, int32 lBufLen, uint32 lCrcValue) {
|
||||
assert(pBuffer != nullptr);
|
||||
assert(lBufLen > 0);
|
||||
|
||||
const byte *p = (const byte *)pBuffer;
|
||||
int32 i = -1;
|
||||
while (++i < lBufLen) {
|
||||
|
||||
byte c = (byte)(*p ^ (byte)lCrcValue);
|
||||
lCrcValue = (lCrcValue >> 8) ^ crc32tabLo[c] ^ ((uint32)crc32tabHi[c] << 16);
|
||||
|
||||
p++;
|
||||
}
|
||||
|
||||
return lCrcValue;
|
||||
}
|
||||
|
||||
uint32 calculateCRC(const int32 *pBuffer, int32 lBufLen, uint32 lCrcValue) {
|
||||
assert(pBuffer != nullptr);
|
||||
assert(lBufLen > 0);
|
||||
|
||||
const int32 *p = pBuffer;
|
||||
for (int i = 0; i < lBufLen; ++i) {
|
||||
uint32 val = *(const uint32 *)p++;
|
||||
|
||||
for (int j = 0; j < 4; ++j, val >>= 8) {
|
||||
byte c = (byte)((val & 0xff) ^ (byte)lCrcValue);
|
||||
lCrcValue = (lCrcValue >> 8) ^ crc32tabLo[c] ^ ((uint32)crc32tabHi[c] << 16);
|
||||
}
|
||||
}
|
||||
|
||||
return lCrcValue;
|
||||
}
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
44
engines/bagel/spacebar/boflib/crc.h
Normal file
44
engines/bagel/spacebar/boflib/crc.h
Normal file
@@ -0,0 +1,44 @@
|
||||
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BAGEL_BOFLIB_CRC_H
|
||||
#define BAGEL_BOFLIB_CRC_H
|
||||
|
||||
#include "bagel/boflib/stdinc.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
/**
|
||||
* Calculates the CRC (Cyclic Redundancy Check) for a buffer
|
||||
* @param pBuffer Pointer to buffer
|
||||
* @param lBufLen Length of this buffer
|
||||
* @param lCrcValue Previous CRC value (if running CRC)
|
||||
* @return New CRC value
|
||||
*/
|
||||
extern uint32 calculateCRC(const void *pBuffer, int32 lBufLen, uint32 lCrcValue = 0);
|
||||
extern uint32 calculateCRC(const int32 *pBuffer, int32 lBufLen, uint32 lCrcValue = 0);
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
|
||||
#endif
|
||||
820
engines/bagel/spacebar/boflib/dat_file.cpp
Normal file
820
engines/bagel/spacebar/boflib/dat_file.cpp
Normal file
@@ -0,0 +1,820 @@
|
||||
/* 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/boflib/dat_file.h"
|
||||
#include "bagel/spacebar/boflib/crc.h"
|
||||
#include "bagel/spacebar/boflib/debug.h"
|
||||
#include "bagel/boflib/log.h"
|
||||
#include "bagel/boflib/misc.h"
|
||||
#include "bagel/boflib/stdinc.h"
|
||||
#include "bagel/boflib/file_functions.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
// Local prototypes
|
||||
static uint32 CreateHashCode(const byte *);
|
||||
|
||||
void HeaderRec::synchronize(Common::Serializer &s) {
|
||||
s.syncAsSint32LE(_lOffset);
|
||||
s.syncAsSint32LE(_lLength);
|
||||
s.syncAsUint32LE(_lCrc);
|
||||
s.syncAsUint32LE(_lKey);
|
||||
}
|
||||
|
||||
void HeadInfo::synchronize(Common::Serializer &s) {
|
||||
s.syncAsSint32LE(_lNumRecs);
|
||||
s.syncAsSint32LE(_lAddress);
|
||||
s.syncAsUint32LE(_lFlags);
|
||||
s.syncAsUint32LE(_lFootCrc);
|
||||
}
|
||||
|
||||
|
||||
CBofDataFile::CBofDataFile() {
|
||||
_szFileName[0] = '\0';
|
||||
_szPassWord[0] = '\0';
|
||||
_lHeaderLength = 0;
|
||||
_lNumRecs = 0;
|
||||
_pHeader = nullptr;
|
||||
_bHeaderDirty = false;
|
||||
}
|
||||
|
||||
ErrorCode CBofDataFile::setFile(const char *pszFileName, uint32 lFlags) {
|
||||
assert(isValidObject(this));
|
||||
|
||||
// Validate input
|
||||
assert(pszFileName != nullptr);
|
||||
assert(strlen(pszFileName) < MAX_FNAME);
|
||||
|
||||
// Release any previous data-file
|
||||
releaseFile();
|
||||
|
||||
// All data files are binary, so force it
|
||||
lFlags |= CBF_BINARY;
|
||||
|
||||
// Remember the flags
|
||||
_lFlags = lFlags;
|
||||
|
||||
if (fileGetFullPath(_szFileName, pszFileName) != nullptr) {
|
||||
if (open() == ERR_NONE) {
|
||||
|
||||
// Read header block
|
||||
readHeader();
|
||||
|
||||
// Close data file if we are not keeping it open
|
||||
if (!(_lFlags & CDF_KEEPOPEN)) {
|
||||
close();
|
||||
}
|
||||
} else
|
||||
reportError(ERR_FOPEN, "Could not open file %s", _szFileName);
|
||||
|
||||
} else {
|
||||
reportError(ERR_FFIND, "Could not build full path to %s", pszFileName);
|
||||
}
|
||||
|
||||
return _errCode;
|
||||
}
|
||||
|
||||
CBofDataFile::~CBofDataFile() {
|
||||
assert(isValidObject(this));
|
||||
|
||||
releaseFile();
|
||||
}
|
||||
|
||||
ErrorCode CBofDataFile::releaseFile() {
|
||||
assert(isValidObject(this));
|
||||
|
||||
// If header was modified
|
||||
if (_bHeaderDirty) {
|
||||
// Write header to disk
|
||||
writeHeader();
|
||||
}
|
||||
|
||||
close();
|
||||
|
||||
// Free header buffer
|
||||
delete[] _pHeader;
|
||||
_pHeader = nullptr;
|
||||
|
||||
return _errCode;
|
||||
}
|
||||
|
||||
ErrorCode CBofDataFile::create() {
|
||||
assert(isValidObject(this));
|
||||
|
||||
HeadInfo stHeaderInfo;
|
||||
|
||||
// Only continue if there is no current error
|
||||
if (_errCode == ERR_NONE) {
|
||||
if (_stream != nullptr) {
|
||||
close();
|
||||
}
|
||||
|
||||
// Re-initialize
|
||||
delete[] _pHeader;
|
||||
_pHeader = nullptr;
|
||||
|
||||
_stream = nullptr;
|
||||
_lHeaderLength = 0;
|
||||
_bHeaderDirty = false;
|
||||
|
||||
stHeaderInfo._lNumRecs = _lNumRecs = 0;
|
||||
stHeaderInfo._lAddress = HeadInfo::size();
|
||||
|
||||
// Create the file
|
||||
if (CBofFile::create(_szFileName, _lFlags) == ERR_NONE) {
|
||||
// Write empty header info
|
||||
if (write(stHeaderInfo) != ERR_NONE) {
|
||||
_errCode = ERR_FWRITE;
|
||||
}
|
||||
|
||||
seek(0);
|
||||
|
||||
} else {
|
||||
_errCode = ERR_FOPEN;
|
||||
}
|
||||
}
|
||||
|
||||
return _errCode;
|
||||
}
|
||||
|
||||
ErrorCode CBofDataFile::open() {
|
||||
assert(isValidObject(this));
|
||||
|
||||
// Only continue if there is no current error
|
||||
if (_errCode == ERR_NONE && _stream == nullptr) {
|
||||
if (!(_lFlags & CDF_READONLY)) {
|
||||
if (_lFlags & CDF_SAVEFILE) {
|
||||
if (_lFlags & CDF_CREATE)
|
||||
create();
|
||||
} else if (!fileExists(_szFileName))
|
||||
create();
|
||||
}
|
||||
|
||||
if (_stream == nullptr) {
|
||||
// Open data file
|
||||
CBofFile::open(_szFileName, _lFlags);
|
||||
}
|
||||
}
|
||||
|
||||
return _errCode;
|
||||
}
|
||||
|
||||
ErrorCode CBofDataFile::close() {
|
||||
assert(isValidObject(this));
|
||||
|
||||
if (_stream != nullptr) {
|
||||
if (_bHeaderDirty) {
|
||||
writeHeader();
|
||||
}
|
||||
|
||||
CBofFile::close();
|
||||
}
|
||||
|
||||
return _errCode;
|
||||
}
|
||||
|
||||
ErrorCode CBofDataFile::readHeader() {
|
||||
assert(isValidObject(this));
|
||||
|
||||
// Only continue if there is no current error
|
||||
if (_errCode == ERR_NONE) {
|
||||
if (_stream == nullptr) {
|
||||
open();
|
||||
}
|
||||
|
||||
if (!errorOccurred()) {
|
||||
// Determine number of records in file
|
||||
HeadInfo stHeaderInfo;
|
||||
if (read(stHeaderInfo) == ERR_NONE) {
|
||||
_lNumRecs = stHeaderInfo._lNumRecs;
|
||||
_lHeaderStart = stHeaderInfo._lAddress;
|
||||
|
||||
// Length of header is number of records * header-record size
|
||||
_lHeaderLength = _lNumRecs * HeaderRec::size();
|
||||
|
||||
Common::SeekableReadStream *rs = dynamic_cast<Common::SeekableReadStream *>(_stream);
|
||||
assert(rs);
|
||||
int32 lfileLength = rs->size();
|
||||
|
||||
// Make sure header contains valid info
|
||||
if ((_lHeaderStart >= HeadInfo::size()) &&
|
||||
(_lHeaderStart <= lfileLength) && (_lHeaderLength >= 0) &&
|
||||
(_lHeaderLength < lfileLength)) {
|
||||
|
||||
// Force Encrypted, and Compress if existing file has them
|
||||
_lFlags |= stHeaderInfo._lFlags & CDF_ENCRYPT;
|
||||
_lFlags |= stHeaderInfo._lFlags & CDF_COMPRESSED;
|
||||
|
||||
if (_lHeaderLength != 0) {
|
||||
// Allocate buffer to hold header
|
||||
_pHeader = new HeaderRec[(int)_lNumRecs];
|
||||
|
||||
// Seek to start of header
|
||||
seek(_lHeaderStart);
|
||||
|
||||
// Read header
|
||||
ErrorCode errorCode = ERR_NONE;
|
||||
for (int i = 0; i < _lNumRecs && errorCode == ERR_NONE; ++i) {
|
||||
errorCode = read(_pHeader[i]);
|
||||
}
|
||||
|
||||
if (errorCode == ERR_NONE) {
|
||||
uint32 lCrc = calculateCRC(&_pHeader->_lOffset, 4 * _lNumRecs);
|
||||
|
||||
if (lCrc != stHeaderInfo._lFootCrc) {
|
||||
logError(buildString("Error: '%s' has invalid footer", _szFileName));
|
||||
_errCode = ERR_CRC;
|
||||
}
|
||||
|
||||
} else {
|
||||
logError(buildString("Error: Could not read footer in file '%s'", _szFileName));
|
||||
_errCode = ERR_FREAD;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
logError(buildString("Error: '%s' has invalid header", _szFileName));
|
||||
_errCode = ERR_FTYPE;
|
||||
}
|
||||
|
||||
} else {
|
||||
logError(buildString("Error: Could not read header in file '%s'", _szFileName));
|
||||
_errCode = ERR_FREAD;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return _errCode;
|
||||
}
|
||||
|
||||
ErrorCode CBofDataFile::writeHeader() {
|
||||
assert(isValidObject(this));
|
||||
|
||||
// Only continue if there is no current error
|
||||
if (_errCode == ERR_NONE) {
|
||||
// Open the data file if it's not already open
|
||||
if (_stream == nullptr) {
|
||||
open();
|
||||
}
|
||||
|
||||
if (_errCode == ERR_NONE) {
|
||||
// Header starts at the end of the last record
|
||||
HeaderRec *pRec = &_pHeader[_lNumRecs - 1];
|
||||
_lHeaderStart = pRec->_lOffset + pRec->_lLength;
|
||||
|
||||
HeadInfo stHeaderInfo;
|
||||
stHeaderInfo._lNumRecs = _lNumRecs;
|
||||
stHeaderInfo._lAddress = _lHeaderStart;
|
||||
stHeaderInfo._lFlags = _lFlags;
|
||||
stHeaderInfo._lFootCrc = calculateCRC(&_pHeader->_lOffset, 4 * _lNumRecs);
|
||||
|
||||
// Seek to front of file to write header info
|
||||
seekToBeginning();
|
||||
|
||||
if (write(stHeaderInfo) == ERR_NONE) {
|
||||
// Seek to start of where header is to be written
|
||||
seek(_lHeaderStart);
|
||||
|
||||
// Write header to data file
|
||||
ErrorCode errorCode = ERR_NONE;
|
||||
for (int i = 0; i < _lNumRecs && errorCode == ERR_NONE; ++i) {
|
||||
errorCode = write(_pHeader[i]);
|
||||
}
|
||||
|
||||
if (errorCode == ERR_NONE) {
|
||||
// Header is now clean
|
||||
_bHeaderDirty = false;
|
||||
|
||||
} else {
|
||||
logError(buildString("Error writing footer to file '%s'", _szFileName));
|
||||
_errCode = ERR_FWRITE;
|
||||
}
|
||||
|
||||
} else {
|
||||
logError(buildString("Error writing header to file '%s'", _szFileName));
|
||||
_errCode = ERR_FWRITE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return _errCode;
|
||||
}
|
||||
|
||||
ErrorCode CBofDataFile::readRecord(int32 lRecNum, void *pBuf) {
|
||||
assert(isValidObject(this));
|
||||
|
||||
// Only continue if there is no current error
|
||||
if (_errCode == ERR_NONE) {
|
||||
// Can't write to nullptr pointers
|
||||
assert(pBuf != nullptr);
|
||||
|
||||
// Validate record number
|
||||
assert(lRecNum >= 0 && lRecNum < _lNumRecs);
|
||||
|
||||
// Make sure we have a valid header
|
||||
assert(_pHeader != nullptr);
|
||||
// Get info about address of where record starts
|
||||
// and how large the record is.
|
||||
HeaderRec *pRecInfo = &_pHeader[(int)lRecNum];
|
||||
|
||||
// Open the data file if it's not already open
|
||||
if (_stream == nullptr) {
|
||||
open();
|
||||
}
|
||||
|
||||
if (_errCode == ERR_NONE) {
|
||||
// Seek to that point in the file
|
||||
seek(pRecInfo->_lOffset);
|
||||
|
||||
// Read in the record
|
||||
if (read(pBuf, pRecInfo->_lLength) == ERR_NONE) {
|
||||
// If this file is encrypted, then decrypt it
|
||||
if (_lFlags & CDF_ENCRYPT) {
|
||||
decrypt(pBuf, (int)pRecInfo->_lLength, _szPassWord);
|
||||
}
|
||||
|
||||
// Calculate and verify this record's CRC value
|
||||
uint32 lCrc = calculateCRC(pBuf, (int)pRecInfo->_lLength);
|
||||
|
||||
if (lCrc != pRecInfo->_lCrc) {
|
||||
_errCode = ERR_CRC;
|
||||
}
|
||||
|
||||
} else {
|
||||
logError(buildString("Error reading record %d in file '%s'", lRecNum, _szFileName));
|
||||
_errCode = ERR_FREAD;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return _errCode;
|
||||
}
|
||||
|
||||
ErrorCode CBofDataFile::readFromFile(int32 lRecNum, void *pBuf, int32 lBytes) {
|
||||
assert(isValidObject(this));
|
||||
|
||||
// Only continue if there is no current error
|
||||
if (_errCode == ERR_NONE) {
|
||||
// Can't write to nullptr pointers
|
||||
assert(pBuf != nullptr);
|
||||
|
||||
// Validate record number
|
||||
assert(lRecNum >= 0 && lRecNum < _lNumRecs);
|
||||
|
||||
// Make sure we have a valid header
|
||||
assert(_pHeader != nullptr);
|
||||
|
||||
// Get info about address of where record starts
|
||||
// and how large the record is.
|
||||
HeaderRec *pRecInfo = &_pHeader[(int)lRecNum];
|
||||
|
||||
// Open the data file if it's not already open
|
||||
if (_stream == nullptr) {
|
||||
open();
|
||||
}
|
||||
|
||||
if (_errCode == ERR_NONE) {
|
||||
// Seek to that point in the file
|
||||
seek(pRecInfo->_lOffset);
|
||||
|
||||
// Read in the requested bytes...
|
||||
if (read(pBuf, lBytes) == ERR_NONE) {
|
||||
// If this file is encrypted, then decrypt it
|
||||
if (_lFlags & CDF_ENCRYPT) {
|
||||
decryptPartial(pBuf, (int32)pRecInfo->_lLength, (int32)lBytes, _szPassWord);
|
||||
}
|
||||
|
||||
// Don't bother with a CRC as this chunk of input won't generate a proper
|
||||
// CRC anyway.
|
||||
} else {
|
||||
logError(buildString("Error reading record %u in file '%s'", lRecNum, _szFileName));
|
||||
_errCode = ERR_FREAD;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return _errCode;
|
||||
}
|
||||
|
||||
ErrorCode CBofDataFile::writeRecord(int32 lRecNum, void *pBuf, int32 lSize, bool bUpdateHeader, uint32 lKey) {
|
||||
assert(isValidObject(this));
|
||||
|
||||
// Only continue if there is no current error
|
||||
if (_errCode == ERR_NONE) {
|
||||
// Validate record number
|
||||
assert(lRecNum >= 0 && lRecNum < _lNumRecs);
|
||||
|
||||
// Validate input buffer
|
||||
assert(pBuf != nullptr);
|
||||
|
||||
// There must already be a valid header
|
||||
assert(_pHeader != nullptr);
|
||||
|
||||
if (lSize == -1)
|
||||
lSize = _pHeader[(int)lRecNum]._lLength;
|
||||
|
||||
int32 lPrevOffset = HeadInfo::size();
|
||||
int32 lPrevLength = 0;
|
||||
|
||||
if (lRecNum != 0) {
|
||||
lPrevOffset = _pHeader[(int)lRecNum - 1]._lOffset;
|
||||
lPrevLength = _pHeader[(int)lRecNum - 1]._lLength;
|
||||
}
|
||||
|
||||
HeaderRec *pRecInfo = &_pHeader[(int)lRecNum];
|
||||
|
||||
// Header needs to updated
|
||||
_bHeaderDirty = true;
|
||||
|
||||
if (_stream == nullptr) {
|
||||
open();
|
||||
}
|
||||
|
||||
// This record starts at the end of the last record
|
||||
pRecInfo->_lOffset = lPrevOffset + lPrevLength;
|
||||
|
||||
// Seek to where we want to write this record
|
||||
seek(pRecInfo->_lOffset);
|
||||
|
||||
// Calculate new hash code based on this records key
|
||||
pRecInfo->_lKey = lKey;
|
||||
if (lKey == 0xFFFFFFFF) {
|
||||
pRecInfo->_lKey = CreateHashCode((const byte *)pBuf);
|
||||
}
|
||||
|
||||
// Calculate this record's CRC value
|
||||
pRecInfo->_lCrc = calculateCRC(pBuf, lSize);
|
||||
|
||||
if (_lFlags & CDF_ENCRYPT) {
|
||||
encrypt(pBuf, lSize, _szPassWord);
|
||||
}
|
||||
|
||||
// If new record is larger then original
|
||||
if (lSize > pRecInfo->_lLength) {
|
||||
// How many bytes back do we have to write?
|
||||
int32 lDiff = lSize - pRecInfo->_lLength;
|
||||
|
||||
//
|
||||
// Move the rest of file back that many bytes
|
||||
//
|
||||
|
||||
// Read the rest of the file in chunks (of 200k or less),
|
||||
// and write each chunk back in it's new position.
|
||||
//
|
||||
int32 lBufLength = getLength() - (pRecInfo->_lOffset + pRecInfo->_lLength);
|
||||
int32 lChunkSize = MIN(lBufLength, (int32)200000);
|
||||
|
||||
// Allocate a buffer big enough for one chunk
|
||||
byte *pTmpBuf = (byte *)bofAlloc(lChunkSize);
|
||||
|
||||
// While there is data to move
|
||||
while (lBufLength > 0) {
|
||||
// Seek to beginning of the source for this chunk
|
||||
setPosition(pRecInfo->_lOffset + pRecInfo->_lLength + lBufLength - lChunkSize);
|
||||
|
||||
// Read the chunk
|
||||
read(pTmpBuf, lChunkSize);
|
||||
|
||||
// Seek to this chunks new position (offset by 'lDiff' bytes)
|
||||
setPosition(pRecInfo->_lOffset + pRecInfo->_lLength + lBufLength - lChunkSize + lDiff);
|
||||
|
||||
// Write chunk to new position
|
||||
write(pTmpBuf, lChunkSize);
|
||||
|
||||
// That much less to do next time through
|
||||
lBufLength -= lChunkSize;
|
||||
|
||||
// Last chunk is lBufLength
|
||||
lChunkSize = MIN(lBufLength, lChunkSize);
|
||||
}
|
||||
|
||||
// Don't need that temp buffer anymore
|
||||
bofFree(pTmpBuf);
|
||||
|
||||
// Tell the rest of the records that they moved
|
||||
for (int i = lRecNum + 1; i < getNumberOfRecs(); i++) {
|
||||
_pHeader[i]._lOffset += lDiff;
|
||||
}
|
||||
|
||||
// Remember it's new length
|
||||
pRecInfo->_lLength = lSize;
|
||||
|
||||
// Seek to where we want to write this record
|
||||
seek(pRecInfo->_lOffset);
|
||||
|
||||
// Write this record
|
||||
write(pBuf, lSize);
|
||||
|
||||
// If we are to update the header now
|
||||
if (bUpdateHeader) {
|
||||
writeHeader();
|
||||
}
|
||||
|
||||
} else {
|
||||
// Write this record
|
||||
if (write(pBuf, lSize) == ERR_NONE) {
|
||||
// If this record got smaller
|
||||
if (pRecInfo->_lLength > lSize) {
|
||||
// Remember it's length
|
||||
pRecInfo->_lLength = lSize;
|
||||
|
||||
int bufferSize = getMaxRecSize();
|
||||
if (bufferSize <= 0)
|
||||
fatalError(ERR_FREAD, "Invalid size read in header data");
|
||||
|
||||
// Allocate a buffer that could hold the largest record
|
||||
byte *pTmpBuf = (byte *)bofAlloc(bufferSize);
|
||||
|
||||
for (int i = (int)lRecNum + 1; i < (int)_lNumRecs - 1; i++) {
|
||||
_errCode = readRecord(i, pTmpBuf);
|
||||
if (_errCode != ERR_NONE)
|
||||
break;
|
||||
|
||||
_errCode = writeRecord(i + 1, pTmpBuf);
|
||||
if (_errCode != ERR_NONE)
|
||||
break;
|
||||
}
|
||||
|
||||
bofFree(pTmpBuf);
|
||||
}
|
||||
|
||||
// If we are to update the header now
|
||||
if (bUpdateHeader) {
|
||||
writeHeader();
|
||||
}
|
||||
|
||||
} else {
|
||||
_errCode = ERR_FWRITE;
|
||||
}
|
||||
}
|
||||
|
||||
// If this record is encrypted the decrypt it
|
||||
if (_lFlags & CDF_ENCRYPT) {
|
||||
decrypt(pBuf, (int)pRecInfo->_lLength, _szPassWord);
|
||||
}
|
||||
}
|
||||
|
||||
return _errCode;
|
||||
}
|
||||
|
||||
ErrorCode CBofDataFile::verifyRecord(int32 lRecNum) {
|
||||
assert(isValidObject(this));
|
||||
|
||||
if (_errCode == ERR_NONE) {
|
||||
// Validate record number
|
||||
assert(lRecNum >= 0 && lRecNum < _lNumRecs);
|
||||
|
||||
// Allocate space to hold this record
|
||||
void *pBuf = bofAlloc((int)getRecSize(lRecNum));
|
||||
|
||||
_errCode = readRecord(lRecNum, pBuf);
|
||||
bofFree(pBuf);
|
||||
}
|
||||
|
||||
return _errCode;
|
||||
}
|
||||
|
||||
ErrorCode CBofDataFile::verifyAllRecords() {
|
||||
assert(isValidObject(this));
|
||||
|
||||
if (_errCode == ERR_NONE) {
|
||||
int32 n = getNumberOfRecs();
|
||||
for (int32 i = 0; i < n; i++) {
|
||||
_errCode = verifyRecord(i);
|
||||
if (_errCode != ERR_NONE) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return _errCode;
|
||||
}
|
||||
|
||||
ErrorCode CBofDataFile::addRecord(void *pBuf, int32 lLength, bool bUpdateHeader, uint32 lKey) {
|
||||
assert(isValidObject(this));
|
||||
|
||||
// Only continue if there is no current error
|
||||
if (_errCode == ERR_NONE) {
|
||||
|
||||
// Validate input
|
||||
assert(pBuf != nullptr);
|
||||
assert(lLength > 0);
|
||||
|
||||
if (lLength > 0) {
|
||||
if (_stream == nullptr) {
|
||||
open();
|
||||
}
|
||||
|
||||
if (_errCode == ERR_NONE) {
|
||||
_lNumRecs++;
|
||||
|
||||
HeaderRec *pTmpHeader = new HeaderRec[(int)_lNumRecs];
|
||||
|
||||
for (int i = 0; i < _lNumRecs; ++i) {
|
||||
pTmpHeader[i]._lOffset = pTmpHeader[i]._lLength = 0;
|
||||
pTmpHeader[i]._lCrc = pTmpHeader[i]._lKey = 0;
|
||||
}
|
||||
|
||||
if (_pHeader != nullptr) {
|
||||
memcpy(pTmpHeader, _pHeader, (size_t)(HeaderRec::size() * (_lNumRecs - 1)));
|
||||
delete[] _pHeader;
|
||||
}
|
||||
|
||||
_pHeader = pTmpHeader;
|
||||
|
||||
int32 lRecNum = _lNumRecs - 1;
|
||||
HeaderRec *pCurRec = &_pHeader[lRecNum];
|
||||
int32 lPrevLength = HeadInfo::size();
|
||||
int32 lPrevOffset = 0;
|
||||
|
||||
if (lRecNum != 0) {
|
||||
lPrevLength = _pHeader[lRecNum - 1]._lLength;
|
||||
lPrevOffset = _pHeader[lRecNum - 1]._lOffset;
|
||||
}
|
||||
|
||||
pCurRec->_lLength = lLength;
|
||||
pCurRec->_lOffset = lPrevOffset + lPrevLength;
|
||||
|
||||
writeRecord(lRecNum, pBuf, lLength, bUpdateHeader, lKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return _errCode;
|
||||
}
|
||||
|
||||
int32 CBofDataFile::findRecord(uint32 lKey) {
|
||||
assert(isValidObject(this));
|
||||
|
||||
// Assume no match
|
||||
int32 lRecNum = -1;
|
||||
|
||||
// Only continue if there is no current error
|
||||
if (_errCode == ERR_NONE) {
|
||||
// Scan the header for the key matching the hash code
|
||||
for (int32 i = 0; i < _lNumRecs; i++) {
|
||||
// Header records must be valid
|
||||
assert(_pHeader != nullptr);
|
||||
|
||||
if (_pHeader[i]._lKey == lKey) {
|
||||
lRecNum = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return lRecNum;
|
||||
}
|
||||
|
||||
int32 CBofDataFile::getRecSize(int32 lRecNum) {
|
||||
assert(isValidObject(this));
|
||||
|
||||
int32 lSize = -1;
|
||||
|
||||
// Only continue if there is no current error
|
||||
if (_errCode == ERR_NONE) {
|
||||
// Validate record number
|
||||
assert(lRecNum >= 0 && lRecNum < _lNumRecs);
|
||||
|
||||
assert(_pHeader != nullptr);
|
||||
|
||||
lSize = _pHeader[lRecNum]._lLength;
|
||||
}
|
||||
|
||||
return lSize;
|
||||
}
|
||||
|
||||
int32 CBofDataFile::getMaxRecSize() const {
|
||||
assert(isValidObject(this));
|
||||
|
||||
int32 lLargest = -1;
|
||||
|
||||
// Only continue if there is no current error
|
||||
if (_errCode == ERR_NONE) {
|
||||
// Validate header
|
||||
assert(_pHeader != nullptr);
|
||||
|
||||
for (int i = 0; i < (int)_lNumRecs; i++) {
|
||||
lLargest = MAX(lLargest, _pHeader[i]._lLength);
|
||||
}
|
||||
}
|
||||
|
||||
return lLargest;
|
||||
}
|
||||
|
||||
void CBofDataFile::setPassword(const char *pszPassword) {
|
||||
assert(isValidObject(this));
|
||||
_szPassWord[0] = '\0';
|
||||
|
||||
if (pszPassword != nullptr) {
|
||||
assert(strlen(pszPassword) < MAX_PW_LEN);
|
||||
|
||||
Common::strcpy_s(_szPassWord, pszPassword);
|
||||
}
|
||||
}
|
||||
|
||||
ErrorCode CBofDataFile::read(void *pDestBuf, int32 lBytes) {
|
||||
return CBofFile::read(pDestBuf, lBytes);
|
||||
}
|
||||
|
||||
ErrorCode CBofDataFile::read(HeadInfo &rec) {
|
||||
byte buf[16];
|
||||
ErrorCode errorCode = read(&buf[0], 16);
|
||||
|
||||
Common::MemoryReadStream mem(buf, 16);
|
||||
Common::Serializer s(&mem, nullptr);
|
||||
rec.synchronize(s);
|
||||
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
ErrorCode CBofDataFile::read(HeaderRec &rec) {
|
||||
byte buf[16];
|
||||
ErrorCode errorCode = read(&buf[0], 16);
|
||||
|
||||
Common::MemoryReadStream mem(buf, 16);
|
||||
Common::Serializer s(&mem, nullptr);
|
||||
rec.synchronize(s);
|
||||
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
ErrorCode CBofDataFile::write(const void *pSrcBuf, int32 lBytes) {
|
||||
return CBofFile::write(pSrcBuf, lBytes);
|
||||
}
|
||||
|
||||
ErrorCode CBofDataFile::write(HeadInfo &rec) {
|
||||
byte buf[16];
|
||||
|
||||
Common::MemoryWriteStream mem(buf, 16);
|
||||
Common::Serializer s(nullptr, &mem);
|
||||
rec.synchronize(s);
|
||||
|
||||
return write(&buf[0], 16);
|
||||
}
|
||||
|
||||
ErrorCode CBofDataFile::write(HeaderRec &rec) {
|
||||
byte buf[16];
|
||||
|
||||
Common::MemoryWriteStream mem(buf, 16);
|
||||
Common::Serializer s(nullptr, &mem);
|
||||
rec.synchronize(s);
|
||||
|
||||
return write(&buf[0], 16);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a Hash code based on a key.
|
||||
* @param pKey Key
|
||||
* @return Hash code
|
||||
*/
|
||||
uint32 CreateHashCode(const byte *pKey) {
|
||||
// validate input
|
||||
assert(pKey != nullptr);
|
||||
|
||||
uint32 lCode = ((uint32) * pKey << 24) | ((uint32) * (pKey + 1) << 16) | ((uint32) * (pKey + 2) << 8) | *(pKey + 3);
|
||||
|
||||
return lCode;
|
||||
}
|
||||
|
||||
void SwapHeadInfo(HeadInfo *stHI) {
|
||||
// Macintosh is big endian, so we must swap our bytes
|
||||
stHI->_lNumRecs = SWAPLONG(stHI->_lNumRecs);
|
||||
stHI->_lAddress = SWAPLONG(stHI->_lAddress);
|
||||
stHI->_lFlags = SWAPLONG(stHI->_lFlags);
|
||||
stHI->_lFootCrc = SWAPLONG(stHI->_lFootCrc);
|
||||
}
|
||||
|
||||
void SwapHeaderRec(HeaderRec *stHR, int nRecords) {
|
||||
HeaderRec *p = stHR;
|
||||
for (int i = 0; i < nRecords; i++) {
|
||||
p->_lOffset = SWAPLONG(p->_lOffset);
|
||||
p->_lLength = SWAPLONG(p->_lLength);
|
||||
p->_lCrc = SWAPLONG(p->_lCrc);
|
||||
p->_lKey = SWAPLONG(p->_lKey);
|
||||
|
||||
p++;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
245
engines/bagel/spacebar/boflib/dat_file.h
Normal file
245
engines/bagel/spacebar/boflib/dat_file.h
Normal file
@@ -0,0 +1,245 @@
|
||||
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BAGEL_BOFLIB_DAT_FILE_H
|
||||
#define BAGEL_BOFLIB_DAT_FILE_H
|
||||
|
||||
#include "common/serializer.h"
|
||||
#include "bagel/spacebar/boflib/file.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
#define CDF_NOFLAGS 0x00000000
|
||||
#define CDF_READONLY CBF_READONLY // Open for Read-only access
|
||||
#define CDF_OVERWRITE CBF_OVERWRITE // *Overwrite any existing data-file
|
||||
#define CDF_SHARED CBF_SHARED // *Open for Shared access
|
||||
#define CDF_CREATE CBF_CREATE // *Create new file if not exist
|
||||
#define CDF_SAVEFILE CBF_SAVEFILE
|
||||
|
||||
#define CDF_MEMORY 0x00010000 // *header/footer should stay in memory
|
||||
#define CDF_ENCRYPT 0x00020000 // Specifies if data should use encryption
|
||||
#define CDF_KEEPOPEN 0x00040000 // File should be kept open after construction
|
||||
#define CDF_COMPRESSED 0x00080000 // *Specifies if data should be compressed
|
||||
// * = indicates feature not yet implemented
|
||||
|
||||
#define CDF_DEFAULT (CDF_MEMORY | CDF_ENCRYPT | CDF_SHARED | CDF_KEEPOPEN | CDF_READONLY)
|
||||
|
||||
#define MAX_PW_LEN 32 // Max Password length
|
||||
|
||||
struct HeaderRec {
|
||||
public:
|
||||
int32 _lOffset;
|
||||
int32 _lLength;
|
||||
uint32 _lCrc;
|
||||
uint32 _lKey;
|
||||
|
||||
void synchronize(Common::Serializer &s);
|
||||
static int size() {
|
||||
return 16;
|
||||
}
|
||||
};
|
||||
|
||||
struct HeadInfo {
|
||||
int32 _lNumRecs; // Number of records in this file
|
||||
int32 _lAddress; // starting address of footer
|
||||
uint32 _lFlags; // contains flags for this file
|
||||
uint32 _lFootCrc; // CRC of the footer
|
||||
|
||||
void synchronize(Common::Serializer &s);
|
||||
static int size() {
|
||||
return 16;
|
||||
}
|
||||
};
|
||||
|
||||
class CBofDataFile : public CBofFile {
|
||||
private:
|
||||
char _szPassWord[MAX_PW_LEN];
|
||||
int32 _lHeaderLength = 0;
|
||||
int32 _lHeaderStart = 0;
|
||||
int32 _lNumRecs = 0;
|
||||
HeaderRec *_pHeader = nullptr;
|
||||
|
||||
bool _bHeaderDirty;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Read the header (actually a footer) from the data-file.
|
||||
* @return Error return code
|
||||
*/
|
||||
ErrorCode readHeader();
|
||||
|
||||
/**
|
||||
* Writes the header (actually a footer) to the data-file.
|
||||
* @return Error return code
|
||||
*/
|
||||
ErrorCode writeHeader();
|
||||
|
||||
public:
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
CBofDataFile();
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
virtual ~CBofDataFile();
|
||||
|
||||
/**
|
||||
* Initializes a CBofDataFile with specified info
|
||||
* @param pszFileName Name of .DAT file
|
||||
* @param lFlags Flags for open, and encryption, etc.
|
||||
* @return Error return code
|
||||
*/
|
||||
ErrorCode setFile(const char *pszFileName, uint32 lFlags);
|
||||
|
||||
/**
|
||||
* Free memory used by this object
|
||||
* @return Error return code
|
||||
*/
|
||||
ErrorCode releaseFile();
|
||||
|
||||
/**
|
||||
* Retrieves size of specified record.
|
||||
* @param lRecNum Index of record to get size of
|
||||
* @return Size of specified record
|
||||
*/
|
||||
int32 getRecSize(int32 lRecNum);
|
||||
int32 getNumberOfRecs() const {
|
||||
return _lNumRecs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves size of the largest record.
|
||||
* @return Size of largest record in the data-file
|
||||
*/
|
||||
int32 getMaxRecSize() const;
|
||||
|
||||
/**
|
||||
* Opens an existing data-file, or creates a new one.
|
||||
* @return Error return code
|
||||
*/
|
||||
ErrorCode open();
|
||||
|
||||
/**
|
||||
* Closes current data-file, if it's not already closed
|
||||
* @return Error return code
|
||||
*/
|
||||
ErrorCode close() override;
|
||||
|
||||
/**
|
||||
* Destroys current data-file, if any, and starts a new empty one
|
||||
* @return Error return code
|
||||
*/
|
||||
ErrorCode create();
|
||||
|
||||
/**
|
||||
* Reads specified record from data-file.
|
||||
* @param lRecNum Record number to read
|
||||
* @param pBuf Buffer to store record
|
||||
* @return Error return code
|
||||
*/
|
||||
ErrorCode readRecord(int32 lRecNum, void *pBuf);
|
||||
|
||||
/**
|
||||
* Read a set number of bytes from the beginning of a file,
|
||||
* don't bother with a CRC, but decrypt if necessary. This is dependent upon
|
||||
* the decryption being based on a single byte ordering scheme.
|
||||
*/
|
||||
ErrorCode readFromFile(int32 lRecNum, void *pBuf, int32 lBytes);
|
||||
|
||||
/**
|
||||
* Writes specified to data-file.
|
||||
* @param lRecNum Record number to read
|
||||
* @param pBuf Buffer to write data from
|
||||
* @param lSize Size of buffer
|
||||
* @param bUpdateHeader True if header is to be committed to disk
|
||||
* @param lKey Hash key
|
||||
* @return Error return code
|
||||
*/
|
||||
ErrorCode writeRecord(int32 lRecNum, void *pBuf, int32 lSize = -1, bool bUpdateHeader = false, uint32 lKey = 0xFFFFFFFF);
|
||||
|
||||
/**
|
||||
* Verifies specified record in data-file.
|
||||
* @param lRecNum Record number to verify
|
||||
* @return Error return code
|
||||
*/
|
||||
ErrorCode verifyRecord(int32 lRecNum);
|
||||
|
||||
/**
|
||||
* Verifies all records in this file
|
||||
* @return Error return code
|
||||
*/
|
||||
ErrorCode verifyAllRecords();
|
||||
|
||||
/**
|
||||
* Adds a new record to the data-file.
|
||||
* @param pBuf Buffer to write data from
|
||||
* @param lLength Size of buffer
|
||||
* @param bUpdateHeader true if header is to be committed to disk
|
||||
* @param lKey hash Key
|
||||
* @return Error return code
|
||||
*/
|
||||
ErrorCode addRecord(void *pBuf, int32 lLength, bool bUpdateHeader = false, uint32 lKey = 0xFFFFFFFF);
|
||||
|
||||
/**
|
||||
* Finds record by it's key.
|
||||
* @param lKey Key to search records with
|
||||
* @return Index of record matching key, or -1
|
||||
*/
|
||||
int32 findRecord(uint32 lKey);
|
||||
|
||||
/**
|
||||
* Sets encryption password
|
||||
* @param pszPassword New password
|
||||
*/
|
||||
void setPassword(const char *pszPassword);
|
||||
const char *getPassword() const {
|
||||
return _szPassWord;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read from a currently open file
|
||||
* @param pDestBuf Destination buffer
|
||||
* @param lBytes Number of bytes
|
||||
* @return Error code
|
||||
*/
|
||||
ErrorCode read(void *pDestBuf, int32 lBytes) override;
|
||||
ErrorCode read(HeaderRec &rec);
|
||||
ErrorCode read(HeadInfo &rec);
|
||||
|
||||
/**
|
||||
* Write to a currently open file
|
||||
* @param pSrcBuf Source buffer
|
||||
* @param lBytes Number of bytes
|
||||
* @return Error code
|
||||
*/
|
||||
ErrorCode write(const void *pSrcBuf, int32 lBytes) override;
|
||||
ErrorCode write(HeaderRec &rec);
|
||||
ErrorCode write(HeadInfo &rec);
|
||||
};
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
|
||||
#endif
|
||||
51
engines/bagel/spacebar/boflib/debug.cpp
Normal file
51
engines/bagel/spacebar/boflib/debug.cpp
Normal file
@@ -0,0 +1,51 @@
|
||||
/* 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 "common/config-manager.h"
|
||||
#include "common/debug.h"
|
||||
#include "bagel/spacebar/boflib/debug.h"
|
||||
#include "bagel/bagel.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace SpaceBar {
|
||||
|
||||
CBofDebugOptions *g_pDebugOptions = nullptr;
|
||||
|
||||
CBofDebugOptions::CBofDebugOptions(const char *pszFileName) : CBofOptions(pszFileName) {
|
||||
// Add programmer definable debug options here
|
||||
ConfMan.registerDefault("AbortsOn", true);
|
||||
ConfMan.registerDefault("MessageBoxOn", true);
|
||||
ConfMan.registerDefault("RandomOn", true);
|
||||
ConfMan.registerDefault("DebugLevel", gDebugLevel);
|
||||
ConfMan.registerDefault("ShowIO", false);
|
||||
ConfMan.registerDefault("MessageSpy", false);
|
||||
|
||||
|
||||
readSetting("DebugOptions", "AbortsOn", &_bAbortsOn, ConfMan.getBool("AbortsOn"));
|
||||
readSetting("DebugOptions", "MessageBoxOn", &_bMessageBoxOn, ConfMan.getBool("MessageBoxOn"));
|
||||
readSetting("DebugOptions", "RandomOn", &_bRandomOn, ConfMan.getBool("RandomOn"));
|
||||
readSetting("DebugOptions", "DebugLevel", &_nDebugLevel, ConfMan.getInt("DebugLevel"));
|
||||
readSetting("DebugOptions", "ShowIO", &_bShowIO, ConfMan.getBool("ShowIO"));
|
||||
readSetting("DebugOptions", "MessageSpy", &_bShowMessages, ConfMan.getBool("MessageSpy"));
|
||||
}
|
||||
|
||||
} // namespace SpaceBar
|
||||
} // namespace Bagel
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user