2016-06-03 21:58:25 +02:00
|
|
|
/* 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 2
|
|
|
|
* of the License, or (at your option) any later version.
|
|
|
|
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
|
|
*
|
|
|
|
*/
|
2016-06-04 20:53:01 +02:00
|
|
|
|
2016-06-05 20:55:29 +02:00
|
|
|
#include "common/system.h"
|
2016-06-05 20:45:14 +02:00
|
|
|
#include "common/debug-channels.h"
|
|
|
|
#include "common/debug.h"
|
2016-06-04 20:53:01 +02:00
|
|
|
#include "common/error.h"
|
2016-06-05 20:45:14 +02:00
|
|
|
#include "engines/util.h"
|
2016-06-04 20:53:01 +02:00
|
|
|
|
|
|
|
#include "macventure/macventure.h"
|
|
|
|
|
2016-06-08 16:07:53 +02:00
|
|
|
// To move
|
|
|
|
#include "common/file.h"
|
|
|
|
|
2016-06-04 20:53:01 +02:00
|
|
|
namespace MacVenture {
|
|
|
|
|
2016-06-08 16:07:53 +02:00
|
|
|
enum {
|
|
|
|
kMaxMenuTitleLength = 30
|
|
|
|
};
|
|
|
|
|
2016-06-04 20:53:01 +02:00
|
|
|
MacVentureEngine::MacVentureEngine(OSystem *syst, const ADGameDescription *gameDesc) : Engine(syst) {
|
|
|
|
_gameDescription = gameDesc;
|
2016-06-05 20:45:14 +02:00
|
|
|
_rnd = new Common::RandomSource("macventure");
|
|
|
|
|
|
|
|
_debugger= NULL;
|
2016-06-17 15:55:23 +02:00
|
|
|
_gui = NULL;
|
2016-06-05 20:45:14 +02:00
|
|
|
|
|
|
|
debug("MacVenture::MacVentureEngine()");
|
2016-06-04 20:53:01 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
MacVentureEngine::~MacVentureEngine() {
|
2016-06-05 20:45:14 +02:00
|
|
|
debug("MacVenture::~MacVentureEngine()");
|
|
|
|
|
|
|
|
DebugMan.clearAllDebugChannels();
|
|
|
|
delete _rnd;
|
|
|
|
delete _debugger;
|
2016-06-08 11:02:21 +02:00
|
|
|
delete _gui;
|
2016-06-16 23:04:10 +02:00
|
|
|
delete _scriptEngine;
|
2016-06-16 18:17:45 +02:00
|
|
|
|
2016-06-16 23:04:10 +02:00
|
|
|
if (_filenames)
|
2016-06-16 18:17:45 +02:00
|
|
|
delete _filenames;
|
2016-06-16 23:04:10 +02:00
|
|
|
|
2016-06-17 20:46:22 +02:00
|
|
|
if (_decodingArticles)
|
|
|
|
delete _decodingArticles;
|
|
|
|
|
2016-06-16 19:02:14 +02:00
|
|
|
if (_textHuffman)
|
|
|
|
delete _textHuffman;
|
2016-06-04 20:53:01 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
Common::Error MacVentureEngine::run() {
|
2016-06-05 20:45:14 +02:00
|
|
|
debug("MacVenture::MacVentureEngine::init()");
|
|
|
|
|
2016-06-08 11:02:21 +02:00
|
|
|
initGraphics(kScreenWidth, kScreenHeight, true);
|
2016-06-05 20:45:14 +02:00
|
|
|
|
|
|
|
_debugger = new Console(this);
|
|
|
|
|
|
|
|
// Additional setup.
|
2016-06-08 17:13:02 +02:00
|
|
|
debug("MacVentureEngine::init");
|
2016-06-05 20:55:29 +02:00
|
|
|
|
2016-06-08 11:17:56 +02:00
|
|
|
_resourceManager = new Common::MacResManager();
|
|
|
|
if (!_resourceManager->open(getGameFileName()))
|
|
|
|
error("Could not open %s as a resource fork", getGameFileName());
|
|
|
|
|
2016-06-16 19:02:14 +02:00
|
|
|
// Engine-wide loading
|
2016-06-12 23:08:24 +02:00
|
|
|
if (!loadGlobalSettings())
|
|
|
|
error("Could not load the engine settings");
|
|
|
|
|
2016-06-16 19:02:14 +02:00
|
|
|
_oldTextEncoding = !loadTextHuffman();
|
2016-06-16 23:04:10 +02:00
|
|
|
|
2016-06-16 18:17:45 +02:00
|
|
|
_filenames = new StringTable(this, _resourceManager, kFilenamesStringTableID);
|
2016-06-17 20:46:22 +02:00
|
|
|
_decodingArticles = new StringTable(this, _resourceManager, kCommonArticlesStringTableID);
|
2016-06-16 23:04:10 +02:00
|
|
|
|
2016-06-16 18:17:45 +02:00
|
|
|
// Big class instantiation
|
2016-06-08 17:13:02 +02:00
|
|
|
_gui = new Gui(this, _resourceManager);
|
2016-06-13 20:29:08 +02:00
|
|
|
_world = new World(this, _resourceManager);
|
2016-06-16 23:04:10 +02:00
|
|
|
_scriptEngine = new ScriptEngine();
|
2016-06-08 16:07:53 +02:00
|
|
|
|
2016-06-16 23:04:10 +02:00
|
|
|
_paused = false;
|
|
|
|
_halted = true;
|
|
|
|
_cmdReady = false;
|
|
|
|
_haltedAtEnd = false;
|
|
|
|
_haltedInSelection = false;
|
2016-06-17 21:47:40 +02:00
|
|
|
|
|
|
|
//if !savegame
|
|
|
|
_cmdReady = true;
|
|
|
|
_selectedControl = kStartOrResume;
|
|
|
|
ObjID playerParent = _world->getObjAttr(1, kAttrParentObject);
|
|
|
|
_currentSelection.push_back(playerParent);// Push the parent of the player
|
|
|
|
_world->setObjAttr(playerParent, 6, 1);
|
|
|
|
|
2016-06-17 12:53:32 +02:00
|
|
|
_prepared = true;
|
2016-06-16 20:33:02 +02:00
|
|
|
while (!(_gameState == kGameStateQuitting)) {
|
2016-06-05 20:55:29 +02:00
|
|
|
processEvents();
|
2016-06-16 23:04:10 +02:00
|
|
|
|
2016-06-17 12:53:32 +02:00
|
|
|
if (_prepared) {
|
|
|
|
_prepared = false;
|
|
|
|
|
|
|
|
if (!_halted) {
|
|
|
|
_gui->draw();
|
|
|
|
}
|
2016-06-16 23:04:10 +02:00
|
|
|
|
2016-06-17 12:53:32 +02:00
|
|
|
if (_cmdReady || _halted) {
|
|
|
|
_halted = false;
|
|
|
|
if (runScriptEngine()) {
|
|
|
|
_halted = true;
|
|
|
|
_paused = true;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
_paused = false;
|
|
|
|
if (!updateState()) {
|
|
|
|
updateControls();
|
|
|
|
}
|
2016-06-16 23:04:10 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-06-17 12:53:32 +02:00
|
|
|
if (_gameState == kGameStateWinnig || _gameState == kGameStateLosing) {
|
|
|
|
endGame();
|
|
|
|
}
|
2016-06-16 23:04:10 +02:00
|
|
|
}
|
2016-06-05 20:55:29 +02:00
|
|
|
|
|
|
|
g_system->updateScreen();
|
|
|
|
g_system->delayMillis(50);
|
|
|
|
}
|
2016-06-05 20:45:14 +02:00
|
|
|
|
|
|
|
return Common::kNoError;
|
2016-06-04 20:53:01 +02:00
|
|
|
}
|
|
|
|
|
2016-06-12 23:13:55 +02:00
|
|
|
void MacVentureEngine::requestQuit() {
|
2016-06-16 23:04:10 +02:00
|
|
|
// TODO: Display save game dialog and such
|
2016-06-16 20:33:02 +02:00
|
|
|
_gameState = kGameStateQuitting;
|
2016-06-12 23:13:55 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void MacVentureEngine::requestUnpause() {
|
|
|
|
_paused = false;
|
2016-06-16 23:04:10 +02:00
|
|
|
_gameState = kGameStatePlaying;
|
2016-06-12 23:13:55 +02:00
|
|
|
}
|
|
|
|
|
2016-06-17 12:44:52 +02:00
|
|
|
void MacVentureEngine::selectControl(ControlReference id) {
|
|
|
|
ControlAction action = referenceToAction(id);
|
2016-06-17 15:55:23 +02:00
|
|
|
debug(4, "Select control %x", action);
|
2016-06-17 12:44:52 +02:00
|
|
|
_selectedControl = action;
|
|
|
|
}
|
|
|
|
|
|
|
|
void MacVentureEngine::activateCommand(ControlReference id) {
|
|
|
|
ControlAction action = referenceToAction(id);
|
|
|
|
if (action != _activeControl) {
|
2016-06-17 12:53:32 +02:00
|
|
|
if (_activeControl)
|
2016-06-17 12:44:52 +02:00
|
|
|
_activeControl = kNoCommand;
|
|
|
|
_activeControl = action;
|
|
|
|
}
|
2016-06-17 15:55:23 +02:00
|
|
|
debug(4, "Activating Command %x... Command %x is active", action, _activeControl);
|
2016-06-17 12:44:52 +02:00
|
|
|
}
|
|
|
|
|
2016-06-17 12:53:32 +02:00
|
|
|
void MacVentureEngine::refreshReady() {
|
|
|
|
switch (objectsToApplyCommand()) {
|
|
|
|
case 0: // No selected object
|
|
|
|
_cmdReady = true;
|
|
|
|
break;
|
|
|
|
case 1: // We have some selected object
|
|
|
|
_cmdReady = _currentSelection.size() != 0;
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
if (_destObject > 0) // We have a destination seleted
|
|
|
|
_cmdReady = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void MacVentureEngine::preparedToRun() {
|
|
|
|
_prepared = true;
|
|
|
|
}
|
|
|
|
|
2016-06-17 21:47:40 +02:00
|
|
|
void MacVentureEngine::gameChanged() {
|
|
|
|
_gameChanged = true;
|
|
|
|
}
|
|
|
|
|
2016-06-16 23:04:10 +02:00
|
|
|
void MacVentureEngine::enqueueObject(ObjID id) {
|
|
|
|
QueuedObject obj;
|
|
|
|
obj.parent = _world->getObjAttr(id, kAttrParentObject);
|
|
|
|
obj.x = _world->getObjAttr(id, kAttrPosX);
|
|
|
|
obj.y = _world->getObjAttr(id, kAttrPosY);
|
|
|
|
obj.exitx = _world->getObjAttr(id, kAttrExitX);
|
|
|
|
obj.exity = _world->getObjAttr(id, kAttrExitY);
|
|
|
|
obj.hidden = _world->getObjAttr(id, kAttrHiddenExit);
|
|
|
|
obj.offsecreen = _world->getObjAttr(id, kAttrInvisible);
|
|
|
|
obj.invisible = _world->getObjAttr(id, kAttrUnclickable);
|
|
|
|
_objQueue.push_back(obj);
|
2016-06-12 23:13:55 +02:00
|
|
|
}
|
|
|
|
|
2016-06-16 23:04:10 +02:00
|
|
|
const GlobalSettings& MacVentureEngine::getGlobalSettings() const {
|
|
|
|
return _globalSettings;
|
2016-06-12 23:13:55 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-06-16 23:04:10 +02:00
|
|
|
// Private engine methods
|
2016-06-12 23:13:55 +02:00
|
|
|
void MacVentureEngine::processEvents() {
|
|
|
|
Common::Event event;
|
|
|
|
|
|
|
|
while (_eventMan->pollEvent(event)) {
|
|
|
|
if (_gui->processEvent(event))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
switch (event.type) {
|
2016-06-16 23:04:10 +02:00
|
|
|
case Common::EVENT_QUIT:
|
2016-06-16 20:33:02 +02:00
|
|
|
_gameState = kGameStateQuitting;
|
2016-06-12 23:13:55 +02:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-06-16 23:04:10 +02:00
|
|
|
bool MacVenture::MacVentureEngine::runScriptEngine() {
|
2016-06-17 15:55:23 +02:00
|
|
|
debug(4, "MAIN: Running script engine");
|
2016-06-16 23:04:10 +02:00
|
|
|
if (_haltedAtEnd) {
|
|
|
|
_haltedAtEnd = false;
|
|
|
|
if (_scriptEngine->resume()) {
|
|
|
|
_haltedAtEnd = true;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (_haltedInSelection) {
|
|
|
|
_haltedInSelection = false;
|
|
|
|
if (_scriptEngine->resume()) {
|
|
|
|
_haltedInSelection = true;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
if (updateState())
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
while (!_currentSelection.empty()) {
|
|
|
|
ObjID obj = _currentSelection.front();
|
|
|
|
_currentSelection.pop_front();
|
|
|
|
if ((_gameState == kGameStateInit || _gameState == kGameStatePlaying) && _world->isObjActive(obj)) {
|
|
|
|
if (_scriptEngine->runControl(_selectedControl, obj, _destObject, _deltaPoint)) {
|
|
|
|
_haltedInSelection = true;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
if (updateState()) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (_selectedControl == 1)
|
|
|
|
_gameChanged = false;
|
|
|
|
|
|
|
|
else if (_gameState == kGameStateInit || _gameState == kGameStatePlaying){
|
|
|
|
if (_scriptEngine->runControl(kTick, _selectedControl, _destObject, _deltaPoint)) {
|
|
|
|
_haltedAtEnd = true;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void MacVentureEngine::endGame() {
|
|
|
|
requestQuit();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool MacVentureEngine::updateState() {
|
|
|
|
runObjQueue();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void MacVentureEngine::runObjQueue() {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void MacVentureEngine::updateControls() {
|
|
|
|
if (_activeControl)
|
|
|
|
_activeControl = kNoCommand;
|
|
|
|
// toggleExits();
|
|
|
|
// resetVars();
|
|
|
|
}
|
|
|
|
|
|
|
|
void MacVentureEngine::resetVars() {
|
|
|
|
_selectedControl = kNoCommand;
|
|
|
|
_activeControl = kNoCommand;
|
|
|
|
_currentSelection.clear();
|
|
|
|
_destObject = 0;
|
|
|
|
_deltaPoint = Common::Point(0, 0);
|
|
|
|
_cmdReady = false;
|
|
|
|
}
|
|
|
|
|
2016-06-17 12:44:52 +02:00
|
|
|
ControlAction MacVenture::MacVentureEngine::referenceToAction(ControlReference id) {
|
|
|
|
switch (id) {
|
|
|
|
case MacVenture::kControlExitBox:
|
|
|
|
return kActivateObject;//??
|
|
|
|
case MacVenture::kControlExamine:
|
|
|
|
return kExamine;
|
|
|
|
case MacVenture::kControlOpen:
|
|
|
|
return kOpen;
|
|
|
|
case MacVenture::kControlClose:
|
|
|
|
return kClose;
|
|
|
|
case MacVenture::kControlSpeak:
|
|
|
|
return kSpeak;
|
|
|
|
case MacVenture::kControlOperate:
|
|
|
|
return kOperate;
|
|
|
|
case MacVenture::kControlGo:
|
|
|
|
return kGo;
|
|
|
|
case MacVenture::kControlHit:
|
|
|
|
return kHit;
|
|
|
|
case MacVenture::kControlConsume:
|
|
|
|
return kConsume;
|
|
|
|
default:
|
|
|
|
return kNoCommand;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-06-17 12:53:32 +02:00
|
|
|
uint MacVentureEngine::objectsToApplyCommand() {
|
|
|
|
return uint();
|
|
|
|
}
|
|
|
|
|
2016-06-16 23:04:10 +02:00
|
|
|
// Data retrieval
|
|
|
|
|
|
|
|
bool MacVentureEngine::isPaused() {
|
|
|
|
return _paused;
|
|
|
|
}
|
|
|
|
|
|
|
|
Common::String MacVentureEngine::getCommandsPausedString() const {
|
|
|
|
return Common::String("Click to continue");
|
|
|
|
}
|
|
|
|
|
2016-06-16 18:17:45 +02:00
|
|
|
Common::String MacVentureEngine::getFilePath(FilePathID id) const {
|
|
|
|
const Common::Array<Common::String> *names = _filenames->getStrings();
|
|
|
|
if (id <= 3) { // We don't want a file in the subdirectory
|
|
|
|
return Common::String((*names)[id]);
|
|
|
|
} else { // We want a game file
|
|
|
|
return Common::String((*names)[3] + "/" + (*names)[id]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-06-17 15:55:23 +02:00
|
|
|
bool MacVentureEngine::isOldText() const {
|
|
|
|
return _oldTextEncoding;
|
|
|
|
}
|
|
|
|
|
|
|
|
const HuffmanLists * MacVentureEngine::getDecodingHuffman() const {
|
|
|
|
return _textHuffman;
|
|
|
|
}
|
|
|
|
|
2016-06-12 23:13:55 +02:00
|
|
|
// Data loading
|
|
|
|
|
2016-06-12 23:08:24 +02:00
|
|
|
bool MacVentureEngine::loadGlobalSettings() {
|
|
|
|
Common::MacResIDArray resArray;
|
|
|
|
Common::SeekableReadStream *res;
|
|
|
|
|
|
|
|
if ((resArray = _resourceManager->getResIDArray(MKTAG('G', 'N', 'R', 'L'))).size() == 0)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
res = _resourceManager->getResource(MKTAG('G', 'N', 'R', 'L'), kGlobalSettingsID);
|
|
|
|
if (res) {
|
|
|
|
_globalSettings.numObjects = res->readUint16BE();
|
|
|
|
_globalSettings.numGlobals = res->readUint16BE();
|
|
|
|
_globalSettings.numCommands = res->readUint16BE();
|
|
|
|
_globalSettings.numAttributes = res->readUint16BE();
|
|
|
|
_globalSettings.numGroups = res->readUint16BE();
|
|
|
|
res->readUint16BE(); // unknown
|
|
|
|
_globalSettings.invTop = res->readUint16BE();
|
|
|
|
_globalSettings.invLeft = res->readUint16BE();
|
|
|
|
_globalSettings.invWidth = res->readUint16BE();
|
|
|
|
_globalSettings.invHeight = res->readUint16BE();
|
|
|
|
_globalSettings.invOffsetY = res->readUint16BE();
|
|
|
|
_globalSettings.invOffsetX = res->readSint16BE();
|
|
|
|
_globalSettings.defaultFont = res->readUint16BE();
|
|
|
|
_globalSettings.defaultSize = res->readUint16BE();
|
|
|
|
|
|
|
|
_globalSettings.attrIndices = new uint8[_globalSettings.numAttributes];
|
|
|
|
res->read(_globalSettings.attrIndices, _globalSettings.numAttributes);
|
|
|
|
|
|
|
|
_globalSettings.attrMasks = new uint16[_globalSettings.numAttributes];
|
|
|
|
for (int i = 0; i < _globalSettings.numAttributes; i++)
|
|
|
|
_globalSettings.attrMasks[i] = res->readUint16BE();
|
|
|
|
|
|
|
|
_globalSettings.attrShifts = new uint8[_globalSettings.numAttributes];
|
|
|
|
res->read(_globalSettings.attrShifts, _globalSettings.numAttributes);
|
|
|
|
|
|
|
|
_globalSettings.cmdArgCnts = new uint8[_globalSettings.numCommands];
|
|
|
|
res->read(_globalSettings.cmdArgCnts, _globalSettings.numCommands);
|
|
|
|
|
2016-06-12 23:13:55 +02:00
|
|
|
_globalSettings.commands = new uint8[_globalSettings.numCommands];
|
|
|
|
res->read(_globalSettings.commands, _globalSettings.numCommands);
|
2016-06-12 23:08:24 +02:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2016-06-16 19:02:14 +02:00
|
|
|
bool MacVentureEngine::loadTextHuffman() {
|
|
|
|
Common::MacResIDArray resArray;
|
|
|
|
Common::SeekableReadStream *res;
|
|
|
|
|
|
|
|
if ((resArray = _resourceManager->getResIDArray(MKTAG('G', 'N', 'R', 'L'))).size() == 0)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
res = _resourceManager->getResource(MKTAG('G', 'N', 'R', 'L'), kTextHuffmanTableID);
|
|
|
|
if (res) {
|
|
|
|
uint32 numEntries = res->readUint16BE();
|
|
|
|
res->readUint16BE(); // Skip
|
|
|
|
|
|
|
|
uint32 *masks = new uint32[numEntries];
|
|
|
|
for (uint i = 0; i < numEntries - 1; i++)
|
|
|
|
// For some reason there are one lass mask than entries
|
|
|
|
masks[i] = res->readUint16BE();
|
|
|
|
|
2016-06-17 15:55:23 +02:00
|
|
|
uint32 *lengths = new uint32[numEntries];
|
2016-06-16 19:02:14 +02:00
|
|
|
for (uint i = 0; i < numEntries; i++)
|
|
|
|
lengths[i] = res->readByte();
|
|
|
|
|
|
|
|
uint32 *values = new uint32[numEntries];
|
|
|
|
for (uint i = 0; i < numEntries; i++)
|
|
|
|
values[i] = res->readByte();
|
|
|
|
|
2016-06-17 15:55:23 +02:00
|
|
|
_textHuffman = new HuffmanLists(numEntries, lengths, masks, values);
|
|
|
|
debug(4, "Text is huffman-encoded");
|
2016-06-16 19:02:14 +02:00
|
|
|
return true;
|
2016-06-16 23:04:10 +02:00
|
|
|
}
|
|
|
|
return false;
|
2016-06-16 19:02:14 +02:00
|
|
|
}
|
2016-06-08 11:17:56 +02:00
|
|
|
|
2016-06-16 20:33:02 +02:00
|
|
|
|
|
|
|
|
2016-06-04 20:53:01 +02:00
|
|
|
} // End of namespace MacVenture
|