diff options
author | Borja Lorente | 2016-06-20 01:30:39 +0200 |
---|---|---|
committer | Borja Lorente | 2016-08-14 18:29:56 +0200 |
commit | 60d5ef5c5b875269f29cd817481de7e162f4966a (patch) | |
tree | 705bce6e209a5be3689b3f7fc028b2610c507124 /engines | |
parent | 96f9910c79849c980a09ff733f4710ba9d414dc9 (diff) | |
download | scummvm-rg350-60d5ef5c5b875269f29cd817481de7e162f4966a.tar.gz scummvm-rg350-60d5ef5c5b875269f29cd817481de7e162f4966a.tar.bz2 scummvm-rg350-60d5ef5c5b875269f29cd817481de7e162f4966a.zip |
MACVENTURE: Begin implementing object queue
Diffstat (limited to 'engines')
-rw-r--r-- | engines/macventure/gui.cpp | 144 | ||||
-rw-r--r-- | engines/macventure/gui.h | 21 | ||||
-rw-r--r-- | engines/macventure/macventure.cpp | 149 | ||||
-rw-r--r-- | engines/macventure/macventure.h | 25 | ||||
-rw-r--r-- | engines/macventure/script.cpp | 3 | ||||
-rw-r--r-- | engines/macventure/world.cpp | 54 | ||||
-rw-r--r-- | engines/macventure/world.h | 11 |
7 files changed, 315 insertions, 92 deletions
diff --git a/engines/macventure/gui.cpp b/engines/macventure/gui.cpp index 4ca3de70b3..1a468eb93c 100644 --- a/engines/macventure/gui.cpp +++ b/engines/macventure/gui.cpp @@ -99,23 +99,44 @@ bool Gui::processEvent(Common::Event &event) { } const WindowData& Gui::getWindowData(WindowReference reference) { - assert(_windowData); - - Common::List<WindowData>::const_iterator iter = _windowData->begin(); - while (iter->refcon != reference && iter != _windowData->end()) { - iter++; - } - - if (iter->refcon == reference) - return *iter; - - error("Could not locate the desired window data"); + return findWindowData(reference); } const Graphics::Font& Gui::getCurrentFont() { return *_wm.getFont("Chicago-12", Graphics::FontManager::kBigGUIFont); } +void Gui::bringToFront(WindowReference winID) { + // FIXME: There has to be a better way to do this, maybe with the _wm + switch (winID) { + case MacVenture::kCommandsWindow: + _controlsWindow->setActive(true); + break; + case MacVenture::kMainGameWindow: + _mainGameWindow->setActive(true); + break; + case MacVenture::kOutConsoleWindow: + _outConsoleWindow->setActive(true); + break; + case MacVenture::kSelfWindow: + _selfWindow->setActive(true); + break; + case MacVenture::kExitsWindow: + _exitsWindow->setActive(true); + break; + case MacVenture::kDiplomaWindow: + _diplomaWindow->setActive(true); + break; + default: + break; + } +} + +void Gui::setWindowTitle(WindowReference winID, Common::String string) { + findWindowData(winID).title = string; + findWindowData(winID).titleLength = string.size(); +} + void Gui::initGUI() { _screen.create(kScreenWidth, kScreenHeight, Graphics::PixelFormat::createFormatCLUT8()); _wm.setScreen(&_screen); @@ -191,13 +212,6 @@ void Gui::initWindows() { _diplomaWindow->getSurface()->fillRect(_diplomaWindow->getSurface()->getBounds(), kColorGreen2); */ - // Inventory Window - _inventoryWindow = _wm.addWindow(false, true, true); - _inventoryWindow->setDimensions(getWindowData(kInventoryWindow).bounds); - _inventoryWindow->setActive(false); - _inventoryWindow->setCallback(inventoryWindowCallback, this); - loadBorder(_inventoryWindow, "border_command.bmp", false); - } void Gui::loadBorder(Graphics::MacWindow * target, Common::String filename, bool active) { @@ -324,9 +338,10 @@ bool Gui::loadWindows() { res->readUint32BE(); // Skip the true id. For some reason it's reading 0 data.titleLength = res->readByte(); if (data.titleLength) { - data.title = new char[data.titleLength + 1]; - res->read(data.title, data.titleLength); - data.title[data.titleLength] = '\0'; + char* newTitle = new char[data.titleLength + 1]; + res->read(newTitle, data.titleLength); + newTitle[data.titleLength] = '\0'; + data.title = Common::String(newTitle); } debug(5, "Window loaded: %s", data.title); @@ -334,28 +349,9 @@ bool Gui::loadWindows() { _windowData->push_back(data); } - loadInventoryWindow(); - return true; } -void Gui::loadInventoryWindow() { - WindowData data; - GlobalSettings settings = _engine->getGlobalSettings(); - data.bounds = Common::Rect( - settings.invLeft, - settings.invTop, - settings.invLeft + settings.invWidth, - settings.invTop + settings.invHeight); - data.title = "Inventory"; - data.visible = true; - data.hasCloseBox = false; - data.refcon = kInventoryWindow; - data.titleLength = 10; - - _windowData->push_back(data); -} - bool Gui::loadControls() { Common::MacResIDArray resArray; Common::SeekableReadStream *res; @@ -456,7 +452,21 @@ void Gui::drawMainGameWindow() { } void Gui::drawSelfWindow() { + warning("drawSelfWindow: Unimplemented"); +} + +WindowData & Gui::findWindowData(WindowReference reference) { + assert(_windowData); + + Common::List<WindowData>::iterator iter = _windowData->begin(); + while (iter->refcon != reference && iter != _windowData->end()) { + iter++; + } + + if (iter->refcon == reference) + return *iter; + error("Could not locate the desired window data"); } @@ -561,12 +571,60 @@ void Gui::handleMenuAction(MenuAction action) { } } +void Gui::updateWindow(WindowReference winID, bool containerOpen) { + if (winID > 0x90) return; + if (winID == kSelfWindow || containerOpen) { + if (winID == kMainGameWindow) { + warning("Unimplemented: draw main game window"); + } else { + warning("Unimplemented: fill window with background"); + } + WindowData &data = findWindowData(winID); + Common::Array<ObjID> children = data.children; + for (Common::Array<ObjID>::const_iterator it = children.begin(); it != children.end(); it++) { + warning("Unimplemented: draw object %x", *it); + } + if (data.type == kZoomDoc && data.updateScroll) { + warning("Unimplemented: update scroll"); + } + } +} + +WindowReference Gui::createInventoryWindow() { + Graphics::MacWindow *newWindow = _wm.addWindow(true, true, true); + WindowData newData; + GlobalSettings settings = _engine->getGlobalSettings(); + newData.refcon = (WindowReference)ABS(_inventoryWindows.size()); // This is a hack + + if (_windowData->back().refcon < 0x80) { // There is already another inventory window + newData.bounds = _windowData->back().bounds; // Inventory windows are always last + newData.bounds.translate(newData.bounds.left + settings.invOffsetX, newData.bounds.top + settings.invOffsetY); + } else { + newData.bounds = Common::Rect( + settings.invLeft, + settings.invTop, + settings.invLeft + settings.invWidth, + settings.invTop + settings.invHeight); + } + newData.type = kZoomDoc; + newData.hasCloseBox = true; + newData.visible = true; + _windowData->push_back(newData); + + newWindow->setDimensions(newData.bounds); + newWindow->setCallback(inventoryWindowCallback, this); + loadBorder(newWindow, "border_self_inac.bmp", false); + loadBorder(newWindow, "border_self_act.bmp", true); + _inventoryWindows.push_back(newWindow); + return newData.refcon; +} + bool Gui::processCommandEvents(WindowClick click, Common::Event &event) { if (event.type == Common::EVENT_LBUTTONUP) { - if (_engine->isPaused()) + if (_engine->isPaused()) return true; - + Common::Point position( event.mouse.x - _controlsWindow->getDimensions().left, event.mouse.y - _controlsWindow->getDimensions().top); @@ -583,7 +641,7 @@ bool Gui::processCommandEvents(WindowClick click, Common::Event &event) { _engine->selectControl((ControlReference)data.getData().refcon); _engine->activateCommand((ControlReference)data.getData().refcon); _engine->refreshReady(); - _engine->preparedToRun(); + _engine->preparedToRun(); } return false; } diff --git a/engines/macventure/gui.h b/engines/macventure/gui.h index 4d760e8382..b107b1584f 100644 --- a/engines/macventure/gui.h +++ b/engines/macventure/gui.h @@ -32,6 +32,7 @@ namespace MacVenture { using namespace Graphics::MacGUIConstants; using namespace Graphics::MacWindowConstants; class MacVentureEngine; +typedef uint32 ObjID; //namespace MacVentureMenuActions { enum MenuAction { @@ -59,8 +60,7 @@ enum WindowReference { kOutConsoleWindow = 0x82, kSelfWindow = 0x83, kExitsWindow = 0x84, - kDiplomaWindow = 0x85, - kInventoryWindow = 0x90 // Not in the files, but here for convenience + kDiplomaWindow = 0x85 }; enum MVWindowType { @@ -85,7 +85,9 @@ struct WindowData { uint16 hasCloseBox; WindowReference refcon; uint8 titleLength; - char* title; + Common::String title; + Common::Array<ObjID> children; + bool updateScroll; }; enum ControlReference { @@ -132,6 +134,9 @@ public: void draw(); bool processEvent(Common::Event &event); void handleMenuAction(MenuAction action); + void updateWindow(WindowReference winID, bool containerOpen); + + WindowReference createInventoryWindow(); // Event processors bool processCommandEvents(WindowClick click, Common::Event &event); @@ -145,6 +150,10 @@ public: const Graphics::Font& getCurrentFont(); + // Modifiers + void bringToFront(WindowReference window); + void setWindowTitle(WindowReference winID, Common::String string); + // Ugly switches BorderBounds borderBounds(MVWindowType type); @@ -165,7 +174,7 @@ private: // Attributes Graphics::MacWindow *_selfWindow; Graphics::MacWindow *_exitsWindow; Graphics::MacWindow *_diplomaWindow; - Graphics::MacWindow *_inventoryWindow; + Common::Array<Graphics::MacWindow*> _inventoryWindows; Graphics::Menu *_menu; private: // Methods @@ -178,7 +187,6 @@ private: // Methods // Loaders bool loadMenus(); bool loadWindows(); - void loadInventoryWindow(); bool loadControls(); void loadBorder(Graphics::MacWindow * target, Common::String filename, bool active); @@ -188,6 +196,9 @@ private: // Methods void drawMainGameWindow(); void drawSelfWindow(); + // Finders + WindowData& findWindowData(WindowReference reference); + }; class CommandButton { diff --git a/engines/macventure/macventure.cpp b/engines/macventure/macventure.cpp index f2a2f43f51..6e477d4b05 100644 --- a/engines/macventure/macventure.cpp +++ b/engines/macventure/macventure.cpp @@ -171,7 +171,7 @@ void MacVentureEngine::activateCommand(ControlReference id) { } void MacVentureEngine::refreshReady() { - switch (objectsToApplyCommand()) { + switch (getInvolvedObjects()) { case 0: // No selected object _cmdReady = true; break; @@ -201,16 +201,18 @@ void MacVentureEngine::loseGame() { _gameState = kGameStateLosing; } -void MacVentureEngine::enqueueObject(ObjID id) { +void MacVentureEngine::enqueueObject(ObjectQueueID type, ObjID objID) { 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); + obj.id = type; + obj.object = objID; + obj.parent = _world->getObjAttr(objID, kAttrParentObject); + obj.x = _world->getObjAttr(objID, kAttrPosX); + obj.y = _world->getObjAttr(objID, kAttrPosY); + obj.exitx = _world->getObjAttr(objID, kAttrExitX); + obj.exity = _world->getObjAttr(objID, kAttrExitY); + obj.hidden = _world->getObjAttr(objID, kAttrHiddenExit); + obj.offsecreen = _world->getObjAttr(objID, kAttrInvisible); + obj.invisible = _world->getObjAttr(objID, kAttrUnclickable); _objQueue.push_back(obj); } @@ -300,16 +302,58 @@ bool MacVentureEngine::updateState() { } void MacVentureEngine::revert() { + warning("revert: unimplemented"); } void MacVentureEngine::runObjQueue() { - + warning("runObjQueue: not fully implemented"); + while (!_objQueue.empty()) { + uint32 biggest = 0; + uint32 index = 0; + uint32 temp; + for (uint i = 0; i < _objQueue.size(); i++) { + temp = _objQueue[i].id; + if (temp > biggest) { + biggest = temp; + index = i; + } + } + QueuedObject obj = _objQueue[index]; + _objQueue.remove_at(index); + switch (obj.id) { + case 0x2: + focusObjectWindow(obj.object); + break; + case 0x3: + openObject(obj.object); + break; + case 0x4: + closeObject(obj.object); + break; + case 0x7: + checkObject(obj.object); + break; + case 0x8: + reflectSwap(obj.object); + break; + case 0xc: + _world->setObjAttr(_gui->getWindowData(kMainGameWindow).refcon, kAttrContainerOpen, 0); + _world->setObjAttr(_world->getObjAttr(1, kAttrParentObject), kAttrContainerOpen, 1); + break; + case 0xd: + toggleExits(); + break; + case 0xe: + zoomObject(obj.object); + break; + } + } } void MacVentureEngine::updateControls() { if (_activeControl) _activeControl = kNoCommand; - // toggleExits(); + toggleExits(); // resetVars(); } @@ -322,6 +366,52 @@ void MacVentureEngine::resetVars() { _cmdReady = false; } +void MacVentureEngine::focusObjectWindow(ObjID objID) { + if (objID) { + WindowReference win = getObjWindow(objID); + if (win) + _gui->bringToFront(win); + } +} + +void MacVentureEngine::openObject(ObjID objID) { + if (getObjWindow(objID)) return; + if (objID == _world->getObjAttr(1, kAttrParentObject)) { + //_gui->setRefcon(objID, kMainGameWindow); // FIXME: Find better name + _gui->updateWindow(kMainGameWindow, _world->getObjAttr(objID, kAttrContainerOpen)); + //_gui->drawExits(); + _gui->setWindowTitle(kMainGameWindow, _world->getText(objID)); + } else { // Open inventory window + Common::Point p(_world->getObjAttr(objID, kAttrPosX), _world->getObjAttr(objID, kAttrPosY)); + //getParentWin(obj).localToGlobal(p); + //globalToDesktop(p); + WindowReference invID = _gui->createInventoryWindow(); + _gui->setWindowTitle(invID, _world->getText(objID)); + //_gui->setRefCon(objID, invID); + _gui->updateWindow(invID, _world->getObjAttr(objID, kAttrContainerOpen)); + } +} + +void MacVentureEngine::closeObject(ObjID objID) { + warning("closeObject: unimplemented"); +} + +void MacVentureEngine::checkObject(ObjID objID) { + warning("checkObject: unimplemented"); +} + +void MacVentureEngine::reflectSwap(ObjID objID) { + warning("reflectSwap: unimplemented"); +} + +void MacVentureEngine::toggleExits() { + warning("toggleExits: unimplemented"); +} + +void MacVentureEngine::zoomObject(ObjID objID) { + warning("zoomObject: unimplemented"); +} + ControlAction MacVenture::MacVentureEngine::referenceToAction(ControlReference id) { switch (id) { case MacVenture::kControlExitBox: @@ -347,10 +437,6 @@ ControlAction MacVenture::MacVentureEngine::referenceToAction(ControlReference i } } -uint MacVentureEngine::objectsToApplyCommand() { - return uint(); -} - // Data retrieval bool MacVentureEngine::isPaused() { @@ -382,6 +468,37 @@ uint32 MacVentureEngine::randBetween(uint32 min, uint32 max) { return _rnd->getRandomNumber(max - min) + min; } +uint32 MacVentureEngine::getInvolvedObjects() { + return (_selectedControl ? _globalSettings.cmdArgCnts[_selectedControl - 1] : 3000); +} + +WindowReference MacVentureEngine::getObjWindow(ObjID objID) { + switch (objID) { + case 0xfffc: return kExitsWindow; + case 0xfffd: return kSelfWindow; + case 0xfffe: return kOutConsoleWindow; + case 0xffff: return kCommandsWindow; + } + + return findObjWindow(objID); +} + +WindowReference MacVentureEngine::findObjWindow(ObjID objID) { + return kMainGameWindow; +} + +Common::Point MacVentureEngine::getDeltaPoint() { + return _deltaPoint; +} + +ObjID MacVentureEngine::getDestObject() { + return _destObject; +} + +ControlAction MacVentureEngine::getSelectedControl() { + return _selectedControl; +} + // Data loading bool MacVentureEngine::loadGlobalSettings() { diff --git a/engines/macventure/macventure.h b/engines/macventure/macventure.h index 3ae195aef0..aabcdcb8ac 100644 --- a/engines/macventure/macventure.h +++ b/engines/macventure/macventure.h @@ -164,7 +164,7 @@ public: bool updateState(); void revert(); - void enqueueObject(ObjID id); + void enqueueObject(ObjectQueueID type, ObjID objID); void enqueueText(TextQueueID type, ObjID target, ObjID source, ObjID text); void runObjQueue(); @@ -178,6 +178,13 @@ public: bool isOldText() const; const HuffmanLists *getDecodingHuffman() const; uint32 randBetween(uint32 min, uint32 max); + uint32 getInvolvedObjects(); + WindowReference getObjWindow(ObjID objID); + WindowReference findObjWindow(ObjID objID); + + Common::Point getDeltaPoint(); + ObjID getDestObject(); + ControlAction getSelectedControl(); private: void processEvents(); @@ -187,13 +194,21 @@ private: void updateControls(); void resetVars(); + // Object queue methods + void focusObjectWindow(ObjID objID); + void openObject(ObjID objID); + void closeObject(ObjID objID); + void checkObject(ObjID objID); + void reflectSwap(ObjID objID); + void toggleExits(); + void zoomObject(ObjID objID); + // Data loading bool loadGlobalSettings(); bool loadTextHuffman(); // Utils ControlAction referenceToAction(ControlReference id); - uint objectsToApplyCommand(); const char* getGameFileName() const; @@ -222,9 +237,9 @@ private: // Attributes bool _haltedAtEnd, _haltedInSelection; bool _gameChanged; - Common::List<QueuedObject> _objQueue; - Common::List<QueuedObject> _soundQueue; - Common::List<QueuedObject> _textQueue; + Common::Array<QueuedObject> _objQueue; + Common::Array<QueuedObject> _soundQueue; + Common::Array<QueuedObject> _textQueue; // Selections ObjID _destObject; diff --git a/engines/macventure/script.cpp b/engines/macventure/script.cpp index b0d5ef0011..5702c9f1ad 100644 --- a/engines/macventure/script.cpp +++ b/engines/macventure/script.cpp @@ -151,6 +151,7 @@ bool ScriptEngine::runFunc(EngineFrame *frame) { byte op; while (script.hasNext()) { op = script.fetch(); + debug(8, "SCRIPT: I'm running operation %x", op); if (!(op & 0x80)) { state->push(op); } else { @@ -900,7 +901,7 @@ void ScriptEngine::opbcCALL(EngineState * state, EngineFrame * frame, ScriptAsse void ScriptEngine::opbdFOOB(EngineState * state, EngineFrame * frame) { word obj = state->pop(); - _engine->enqueueObject(obj); + _engine->enqueueObject(kFocusWindow, obj); } void ScriptEngine::opbeSWOB(EngineState * state, EngineFrame * frame) { diff --git a/engines/macventure/world.cpp b/engines/macventure/world.cpp index 2f603c5ddc..c7b103efd7 100644 --- a/engines/macventure/world.cpp +++ b/engines/macventure/world.cpp @@ -68,7 +68,7 @@ void World::setObjAttr(ObjID objID, uint32 attrID, Attribute value) { setParent(objID, value); if (attrID < kAttrOtherDoor) - _engine->enqueueObject(objID); + _engine->enqueueObject(kUpdateObject, objID); uint32 idx = _engine->getGlobalSettings().attrIndices[attrID]; value <<= _engine->getGlobalSettings().attrShifts[attrID]; @@ -80,7 +80,29 @@ void World::setObjAttr(ObjID objID, uint32 attrID, Attribute value) { } bool MacVenture::World::isObjActive(ObjID obj) { - return false; + ObjID destObj = _engine->getDestObject(); + Common::Point p = _engine->getDeltaPoint(); + ControlAction selectedControl = _engine->getSelectedControl(); + if (!getAncestor(obj)) return false; // If our ancestor is the garbage (obj 0), we're inactive + if (_engine->getInvolvedObjects() >= 2 && // If (we need > 1 objs for the command) && + destObj > 0 && // we have a destination object && + !getAncestor(destObj)) // but that destination object is in the garbage + return false; + if (selectedControl != kMoveObject) return true; // We only need one + // Handle move object + if (!isObjDraggable(obj)) return false; // We can't move it + if (getObjAttr(1, kAttrParentObject) != destObj) return true; // if the target is not the player's parent, we can go + Common::Rect rect(kScreenWidth, kScreenHeight); + rect.top -= getObjAttr(obj, kAttrPosY) + p.y; + rect.left -= getObjAttr(obj, kAttrPosX) + p.x; + return intersects(obj, rect); +} + +ObjID World::getAncestor(ObjID objID) { + ObjID root = getObjAttr(1, kAttrParentObject); + while (objID != 0 && objID != 1 && objID != root) + objID = getObjAttr(objID, kAttrParentObject); + return objID; } Common::Array<ObjID> World::getFamily(ObjID objID, bool recursive) { @@ -102,21 +124,6 @@ Common::Array<ObjID> World::getChildren(ObjID objID, bool recursive) { return Common::Array<ObjID>(); } -WindowReference World::getObjWindow(ObjID objID) { - switch (objID) { - case 0xfffc: return kExitsWindow; - case 0xfffd: return kSelfWindow; - case 0xfffe: return kOutConsoleWindow; - case 0xffff: return kCommandsWindow; - } - - return findObjWindow(objID); -} - -WindowReference World::findObjWindow(ObjID objID) { - return kMainGameWindow; -} - Attribute World::getGlobal(uint32 attrID) { return _saveGame->getGlobals()[attrID]; } @@ -130,7 +137,7 @@ void World::updateObj(ObjID objID) { if (getObjAttr(1, kAttrParentObject) == objID) { win = kMainGameWindow; } else { - win = getObjWindow(objID); + win = _engine->getObjWindow(objID); } if (win) { //focusObjWin(objID); @@ -152,6 +159,17 @@ Common::String World::getText(ObjID objID) { } +bool World::isObjDraggable(ObjID objID) { + return (getObjAttr(objID, kAttrInvisible) == 0 && + getObjAttr(objID, kAttrUnclickable) == 0 && + getObjAttr(objID, kAttrUndraggable) == 0); +} + +bool World::intersects(ObjID objID, Common::Rect rect) { + warning("Intersects: unimplemented"); + return true; +} + bool World::loadStartGameFileName() { Common::SeekableReadStream *res; diff --git a/engines/macventure/world.h b/engines/macventure/world.h index 370582665b..fe45508623 100644 --- a/engines/macventure/world.h +++ b/engines/macventure/world.h @@ -101,13 +101,16 @@ public: Attribute getGlobal(uint32 attrID); Common::String getText(ObjID objID); - bool isObjActive(ObjID obj); + bool isObjActive(ObjID objID); + + ObjID getAncestor(ObjID objID); Common::Array<ObjID> getFamily(ObjID objID, bool recursive); - Common::Array<ObjID> getChildren(ObjID objID, bool recursive); - WindowReference getObjWindow(ObjID objID); - WindowReference findObjWindow(ObjID objID); + Common::Array<ObjID> getChildren(ObjID objID, bool recursive); private: + bool isObjDraggable(ObjID objID); + bool intersects(ObjID objID, Common::Rect rect); + bool loadStartGameFileName(); void calculateObjectRelations(); void setParent(ObjID child, ObjID newParent); |