[Scummvm-git-logs] scummvm master -> 403b55c5ba7535ded50fe0c304b775cedfa4e312
mduggan
noreply at scummvm.org
Sun Jul 21 10:01:10 UTC 2024
This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
403b55c5ba DGDS: Add support for both-button ops
Commit: 403b55c5ba7535ded50fe0c304b775cedfa4e312
https://github.com/scummvm/scummvm/commit/403b55c5ba7535ded50fe0c304b775cedfa4e312
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2024-07-21T19:58:38+10:00
Commit Message:
DGDS: Add support for both-button ops
This allows you to shoot the snakes in HoC.
Changed paths:
engines/dgds/dgds.cpp
engines/dgds/inventory.cpp
engines/dgds/scene.cpp
engines/dgds/scene.h
engines/dgds/ttm.cpp
diff --git a/engines/dgds/dgds.cpp b/engines/dgds/dgds.cpp
index cf75726e6af..7eab4bc9d90 100644
--- a/engines/dgds/dgds.cpp
+++ b/engines/dgds/dgds.cpp
@@ -494,7 +494,8 @@ Common::Error DgdsEngine::run() {
break;
}
} else if (ev.type == Common::EVENT_LBUTTONDOWN || ev.type == Common::EVENT_LBUTTONUP
- || ev.type == Common::EVENT_RBUTTONUP || ev.type == Common::EVENT_MOUSEMOVE) {
+ || ev.type == Common::EVENT_RBUTTONDOWN || ev.type == Common::EVENT_RBUTTONUP
+ || ev.type == Common::EVENT_MOUSEMOVE) {
mouseEvent = ev.type;
_lastMouse = ev.mouse;
}
@@ -584,6 +585,9 @@ Common::Error DgdsEngine::run() {
case Common::EVENT_LBUTTONUP:
_scene->mouseLUp(_lastMouse);
break;
+ case Common::EVENT_RBUTTONDOWN:
+ _scene->mouseRDown(_lastMouse);
+ break;
case Common::EVENT_RBUTTONUP:
_scene->mouseRUp(_lastMouse);
break;
diff --git a/engines/dgds/inventory.cpp b/engines/dgds/inventory.cpp
index c5dfc2a76cb..1f2c8d09489 100644
--- a/engines/dgds/inventory.cpp
+++ b/engines/dgds/inventory.cpp
@@ -378,7 +378,7 @@ void Inventory::mouseLUp(const Common::Point &pt) {
break;
}
}
- } else if (_changeCharBtn && _changeCharBtn->isVisible() && _changeCharBtn->containsPoint(pt)) {
+ } else if (_changeCharBtn && _changeCharBtn->containsPoint(pt)) {
int16 prevChar = gds->getGlobal(0x33);
gds->setGlobal(0x33, gds->getGlobal(0x34));
gds->setGlobal(0x34, prevChar);
diff --git a/engines/dgds/scene.cpp b/engines/dgds/scene.cpp
index fb5f6e124be..300c590a0e0 100644
--- a/engines/dgds/scene.cpp
+++ b/engines/dgds/scene.cpp
@@ -181,7 +181,7 @@ Common::String GameItem::dump(const Common::String &indent) const {
indent.c_str(), super.c_str(), indent.c_str(), _altCursor,
_iconNum, _inSceneNum, _flags, _quality);
str += _dumpStructList(indent, "onDragFinishedOps", onDragFinishedOps);
- str += _dumpStructList(indent, "opList5", opList5);
+ str += _dumpStructList(indent, "onBothButtonsOps", onBothButtonsOps);
str += "\n";
str += indent + ">";
return str;
@@ -313,7 +313,7 @@ bool Scene::readGameItemList(Common::SeekableReadStream *s, Common::Array<GameIt
if (!isVersionUnder(" 1.204")) {
dst._altCursor = s->readUint16LE();
readOpList(s, dst.onDragFinishedOps);
- readOpList(s, dst.opList5);
+ readOpList(s, dst.onBothButtonsOps);
}
}
return !s->err();
@@ -903,7 +903,7 @@ bool Scene::checkConditions(const Common::Array<SceneConditions> &conds) const {
bool SDSScene::_dlgWithFlagLo8IsClosing = false;;
DialogFlags SDSScene::_sceneDialogFlags = kDlgFlagNone;
-SDSScene::SDSScene() : _num(-1), _dragItem(nullptr), _shouldClearDlg(false), _ignoreMouseUp(false), _field6_0x14(0) {
+SDSScene::SDSScene() : _num(-1), _dragItem(nullptr), _shouldClearDlg(false), _ignoreMouseUp(false), _field6_0x14(0), _rbuttonDown(false) {
}
bool SDSScene::load(const Common::String &filename, ResourceManager *resourceManager, Decompressor *decompressor) {
@@ -1630,12 +1630,18 @@ void SDSScene::globalOps(const Common::Array<uint16> &args) {
void SDSScene::mouseMoved(const Common::Point &pt) {
Dialog *dlg = getVisibleDialog();
const HotArea *area = findAreaUnderMouse(pt);
+ DgdsEngine *engine = static_cast<DgdsEngine *>(g_engine);
int16 cursorNum = (!dlg && area) ? area->_cursorNum : 0;
- if (_dragItem)
+ if (_dragItem) {
cursorNum = _dragItem->_iconNum;
+ } else if (_rbuttonDown) {
+ GameItem *activeItem = engine->getGDSScene()->getActiveItem();
+ if (activeItem)
+ cursorNum = activeItem->_altCursor;
+ }
- static_cast<DgdsEngine *>(g_engine)->setMouseCursor(cursorNum);
+ engine->setMouseCursor(cursorNum);
}
void SDSScene::mouseLDown(const Common::Point &pt) {
@@ -1664,6 +1670,20 @@ void SDSScene::mouseLDown(const Common::Point &pt) {
}
}
+static bool _isInRect(const Common::Point &pt, const DgdsRect rect) {
+ return rect.x <= pt.x && (rect.x + rect.width) > pt.x
+ && rect.y <= pt.y && (rect.y + rect.height) > pt.y;
+}
+
+static const ObjectInteraction * _findInteraction(const Common::Array<ObjectInteraction> &interList, int16 droppedNum, int16 targetNum) {
+ for (const auto &i : interList) {
+ if (i.matches(droppedNum, targetNum)) {
+ return &i;
+ }
+ }
+ return nullptr;
+}
+
void SDSScene::mouseLUp(const Common::Point &pt) {
if (_ignoreMouseUp) {
debug(9, "Ignoring mouseup at %d,%d as it was used to clear a dialog", pt.x, pt.y);
@@ -1684,14 +1704,16 @@ void SDSScene::mouseLUp(const Common::Point &pt) {
area->_rect.width, area->_rect.height, area->_cursorNum);
DgdsEngine *engine = static_cast<DgdsEngine *>(g_engine);
- engine->setMouseCursor(area->_cursorNum);
+ if (!_rbuttonDown)
+ engine->setMouseCursor(area->_cursorNum);
+
+ GDSScene *gds = engine->getGDSScene();
if (area && area->_num == 0) {
debug("Mouseup on inventory.");
engine->getInventory()->open();
} else if (area && area->_num == 0xffff) {
debug("Mouseup on swap characters.");
- GDSScene *gds = engine->getGDSScene();
bool haveInvBtn = _hotAreaList.size() && _hotAreaList.front()._num == 0;
if (haveInvBtn)
removeInvButtonFromHotAreaList();
@@ -1701,33 +1723,34 @@ void SDSScene::mouseLUp(const Common::Point &pt) {
if (haveInvBtn)
addInvButtonToHotAreaList();
} else {
- debug(" --> exec %d click ops for area %d", area->onLClickOps.size(), area->_num);
- if ((area->_num == 58 || area->_num == 62) && engine->getScene()->getNum() == 53 && engine->getGameId() == GID_HOC) {
- // FIXME: Handle gun (crosshair icon, action on snakes)
- warning("HACK for the snake scene");
- GDSScene *gds = engine->getGDSScene();
- gds->setGlobal(126, 1); // kill left snake
- gds->setGlobal(132, 1); // kill right snake
- gds->setGlobal(110, 86); // save Kate and open balcony door
- return;
- }
- int16 addmins = engine->getGameGlobals()->getGameMinsToAddOnLClick();
- runOps(area->onLClickOps, addmins);
- }
-}
-
-static bool _isInRect(const Common::Point &pt, const DgdsRect rect) {
- return rect.x <= pt.x && (rect.x + rect.width) > pt.x
- && rect.y <= pt.y && (rect.y + rect.height) > pt.y;
-}
-
-static const ObjectInteraction * _findInteraction(const Common::Array<ObjectInteraction> &interList, int16 droppedNum, int16 targetNum) {
- for (const auto &i : interList) {
- if (i.matches(droppedNum, targetNum)) {
- return &i;
+ if (_rbuttonDown) {
+ debug(" --> exec %d both-button click ops for area %d", area->onLClickOps.size(), area->_num);
+ // A both-button-click event, find the interaction list.
+ const GameItem *activeItem = engine->getGDSScene()->getActiveItem();
+ if (activeItem) {
+ if (!runOps(activeItem->onBothButtonsOps))
+ return;
+ if (area) {
+ const GameItem *destItem = dynamic_cast<const GameItem *>(area);
+ const ObjectInteraction *i;
+ if (destItem) {
+ i =_findInteraction(gds->getObjInteractions2(), activeItem->_num, area->_num);
+ } else {
+ i = _findInteraction(_objInteractions2, activeItem->_num, area->_num);
+ }
+ if (i) {
+ debug(" --> exec %d both-click ops for item combo %d", i->opList.size(), activeItem->_num);
+ if (!runOps(i->opList, engine->getGameGlobals()->getGameMinsToAddOnObjInteraction()))
+ return;
+ }
+ }
+ }
+ } else {
+ debug(" --> exec %d click ops for area %d", area->onLClickOps.size(), area->_num);
+ int16 addmins = engine->getGameGlobals()->getGameMinsToAddOnLClick();
+ runOps(area->onLClickOps, addmins);
}
}
- return nullptr;
}
void SDSScene::onDragFinish(const Common::Point &pt) {
@@ -1750,7 +1773,7 @@ void SDSScene::onDragFinish(const Common::Point &pt) {
for (const auto &item : gdsScene->getGameItems()) {
if (item._inSceneNum == _num && _isInRect(pt, item._rect)) {
debug("Dragged item %d onto item %d @ (%d, %d)", dragItem->_num, item._num, pt.x, pt.y);
- const ObjectInteraction *i = _findInteraction(gdsScene->getObjInteractions2(), dragItem->_num, item._num);
+ const ObjectInteraction *i = _findInteraction(gdsScene->getObjInteractions1(), dragItem->_num, item._num);
if (i) {
debug(" --> exec %d drag ops for item %d", i->opList.size(), item._num);
if (!runOps(i->opList, globals->getGameMinsToAddOnObjInteraction()))
@@ -1770,7 +1793,7 @@ void SDSScene::onDragFinish(const Common::Point &pt) {
if (engine->getGameId() == GID_HOC)
dragItem->_quality = Inventory::HOC_CHARACTER_QUALS[gdsScene->getGlobal(0x33)];
- const ObjectInteraction *i = _findInteraction(scene->getObjInteractions1(), dragItem->_num, 0xffff);
+ const ObjectInteraction *i = _findInteraction(gdsScene->getObjInteractions1(), dragItem->_num, 0xffff);
if (i) {
debug(" --> exec %d drag ops for area %d", i->opList.size(), 0xffff);
if (!runOps(i->opList, globals->getGameMinsToAddOnObjInteraction()))
@@ -1782,7 +1805,7 @@ void SDSScene::onDragFinish(const Common::Point &pt) {
if (engine->getGameId() == GID_HOC)
dragItem->_quality = Inventory::HOC_CHARACTER_QUALS[gdsScene->getGlobal(0x34)];
- const ObjectInteraction *i = _findInteraction(scene->getObjInteractions1(), dragItem->_num, 0xffff);
+ const ObjectInteraction *i = _findInteraction(gdsScene->getObjInteractions1(), dragItem->_num, 0xffff);
if (i) {
debug(" --> exec %d drag ops for area %d", i->opList.size(), 0xffff);
if (!runOps(i->opList, globals->getGameMinsToAddOnObjInteraction()))
@@ -1808,8 +1831,12 @@ void SDSScene::onDragFinish(const Common::Point &pt) {
_dragItem = nullptr;
}
+void SDSScene::mouseRDown(const Common::Point &pt) {
+ _rbuttonDown = true;
+}
void SDSScene::mouseRUp(const Common::Point &pt) {
+ _rbuttonDown = false;
Dialog *dlg = getVisibleDialog();
if (dlg) {
// HACK: Check for dialog action selection! for now, just close
@@ -1818,6 +1845,9 @@ void SDSScene::mouseRUp(const Common::Point &pt) {
return;
}
+ // Update the cursor..
+ mouseMoved(pt);
+
const HotArea *area = findAreaUnderMouse(pt);
if (!area)
return;
@@ -1825,21 +1855,20 @@ void SDSScene::mouseRUp(const Common::Point &pt) {
DgdsEngine *engine = static_cast<DgdsEngine *>(g_engine);
if (area->_num == 0) {
- debug("Right mouseup on inventory.");
+ debug("Mouse RUp on inventory.");
engine->getInventory()->setShowZoomBox(true);
engine->getInventory()->open();
- return;
} else if (area->_num == 0xffff) {
- debug("Right mouseup on character swap.");
+ debug("Mouse RUp on character swap.");
int16 swapDlgFile = engine->getGDSScene()->getGlobal(0x36);
int16 swapDlgNum = engine->getGDSScene()->getGlobal(0x35);
if (swapDlgFile && swapDlgNum)
showDialog(swapDlgFile, swapDlgNum);
- return;
+ } else {
+ int16 addmins = engine->getGameGlobals()->getGameMinsToAddOnLClick();
+ debug("Mouse RUp on area %d, run %d ops (+%d mins)", area->_num, area->onRClickOps.size(), addmins);
+ runOps(area->onRClickOps, addmins);
}
-
- int16 addmins = engine->getGameGlobals()->getGameMinsToAddOnLClick();
- runOps(area->onRClickOps, addmins);
}
Dialog *SDSScene::getVisibleDialog() {
@@ -2163,9 +2192,9 @@ bool GDSScene::parse(Common::SeekableReadStream *stream) {
_iconFile = stream->readString();
readMouseHotspotList(stream, _cursorList);
readGameItemList(stream, _gameItems);
- readObjInteractionList(stream, _objInteractions2);
+ readObjInteractionList(stream, _objInteractions1);
if (isVersionOver(" 1.205"))
- readObjInteractionList(stream, _objInteractions1);
+ readObjInteractionList(stream, _objInteractions2);
if (isVersionOver(" 1.218")) {
_field38 = stream->readUint16LE();
@@ -2324,6 +2353,17 @@ int GDSScene::countItemsInScene2() const {
return result;
}
+GameItem *GDSScene::getActiveItem() {
+ int16 itemNum = getGlobal(0x60);
+ if (!itemNum)
+ return nullptr;
+ for (auto &item : _gameItems) {
+ if (item._num == itemNum)
+ return &item;
+ }
+ return nullptr;
+}
+
Common::Error GDSScene::syncState(Common::Serializer &s) {
// Only items and globals are stateful - everything else is stateless.
// Game should already be loaded at this point so the lsits are already
diff --git a/engines/dgds/scene.h b/engines/dgds/scene.h
index 842938d91a2..c63d1118a04 100644
--- a/engines/dgds/scene.h
+++ b/engines/dgds/scene.h
@@ -160,7 +160,7 @@ public:
class GameItem : public HotArea {
public:
Common::Array<SceneOp> onDragFinishedOps;
- Common::Array<SceneOp> opList5;
+ Common::Array<SceneOp> onBothButtonsOps;
uint16 _altCursor;
uint16 _iconNum;
@@ -377,6 +377,7 @@ public:
Common::Error syncState(Common::Serializer &s) override;
void initIconSizes();
+ GameItem *getActiveItem();
private:
Common::String _iconFile;
@@ -386,8 +387,8 @@ private:
Common::Array<SceneOp> _onChangeSceneOps;
Common::Array<MouseCursor> _cursorList;
Common::Array<PerSceneGlobal> _perSceneGlobals;
- Common::Array<ObjectInteraction> _objInteractions1;
Common::Array<ObjectInteraction> _objInteractions2;
+ Common::Array<ObjectInteraction> _objInteractions1;
// Additional fields that appear in Willy Beamish (unused in others)
uint16 _field38;
@@ -423,6 +424,7 @@ public:
void mouseMoved(const Common::Point &pt);
void mouseLDown(const Common::Point &pt);
void mouseLUp(const Common::Point &pt);
+ void mouseRDown(const Common::Point &pt);
void mouseRUp(const Common::Point &pt);
void addInvButtonToHotAreaList();
@@ -497,6 +499,7 @@ private:
GameItem *_dragItem;
bool _shouldClearDlg;
bool _ignoreMouseUp;
+ bool _rbuttonDown;
static bool _dlgWithFlagLo8IsClosing;
static DialogFlags _sceneDialogFlags;
diff --git a/engines/dgds/ttm.cpp b/engines/dgds/ttm.cpp
index 9eb36798d34..fcdad7d0e64 100644
--- a/engines/dgds/ttm.cpp
+++ b/engines/dgds/ttm.cpp
@@ -158,11 +158,13 @@ static const char *ttmOpName(uint16 op) {
case 0x2000: return "SET DRAW COLORS";
case 0x2010: return "SET FRAME";
case 0x2020: return "SET RANDOM DELAY";
+ case 0x2030: return "SET SCROLL 2030??";
case 0x2300: return "PAL SET BLOCK SWAP 0";
case 0x2310: return "PAL SET BLOCK SWAP 1";
case 0x2320: return "PAL SET BLOCK SWAP 2";
case 0x2400: return "PAL DO BLOCK SWAP";
case 0x3000: return "GOSUB";
+ case 0x3100: return "SCROLL 3100??";
case 0x4000: return "SET CLIP WINDOW";
case 0x4110: return "FADE OUT";
case 0x4120: return "FADE IN";
@@ -199,6 +201,7 @@ static const char *ttmOpName(uint16 op) {
case 0xa520: return "DRAW SPRITE FLIPH";
case 0xa530: return "DRAW SPRITE FLIPHV";
case 0xa600: return "DRAW GETPUT";
+ case 0xa700: return "DRAW A700??";
case 0xaf00: return "DRAW FLOOD FILL";
case 0xaf10: return "DRAW EMPTY POLY";
case 0xaf20: return "DRAW FILLED POLY";
@@ -603,7 +606,7 @@ void TTMInterpreter::handleOperation(TTMEnviro &env, TTMSeq &seq, uint16 op, byt
break;
warning("TODO: 0x%04x Palette do block swaps 0x%x, 0x%x", op, ivals[0], ivals[1]);
break;
- case 0x3000: {
+ case 0x3000: { // GOSUB ??,??,frame
_stackDepth++;
bool prevHitOp0110Val = _vm->adsInterpreter()->getHitTTMOp0110();
int32 target = findGOTOTarget(env, seq, ivals[2]);
@@ -613,7 +616,8 @@ void TTMInterpreter::handleOperation(TTMEnviro &env, TTMSeq &seq, uint16 op, byt
env.scr->seek(env._frameOffsets[target]);
// TODO: Set some other render-related globals here
- warning("TODO: TTM 0x3000 GOSUB %d %d, use other args", ivals[0], ivals[1]);
+ if (ivals[0] || ivals[1])
+ warning("TODO: TTM 0x3000 GOSUB use offsets (%d, %d)", ivals[0], ivals[1]);
run(env, seq);
env.scr->seek(prevPos);
@@ -624,6 +628,11 @@ void TTMInterpreter::handleOperation(TTMEnviro &env, TTMSeq &seq, uint16 op, byt
_stackDepth--;
break;
}
+ case 0x3100: { // SCROLL ??,??,??
+ if (seq._executed) // this is a one-shot op.
+ break;
+ warning("TODO: TTM 0x3100 SCROLL %d %d %d", ivals[0], ivals[1], ivals[2]);
+ }
case 0x4000: // SET CLIP WINDOW x,y,x2,y2:int [0..320,0..200]
// NOTE: params are xmax/ymax, NOT w/h
seq._drawWin = Common::Rect(ivals[0], ivals[1], ivals[2], ivals[3]);
More information about the Scummvm-git-logs
mailing list