[Scummvm-git-logs] scummvm master -> 7a3862b44bf44939af7f3350451b7d08604d111d
scemino
noreply at scummvm.org
Sun May 5 19:15:28 UTC 2024
This automated email contains information about 4 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
c49960fed5 TWP: Add Goto next/previous object
213af70cc6 TWP: Use correct gamepad mapping
9105713b42 TWP: Fix unchecked return value in getUserPref function.
7a3862b44b TWP: Add Select Verb/Inventory
Commit: c49960fed5eaa72d97733332b3da1d6189e6c23b
https://github.com/scummvm/scummvm/commit/c49960fed5eaa72d97733332b3da1d6189e6c23b
Author: scemino (scemino74 at gmail.com)
Date: 2024-05-05T21:15:17+02:00
Commit Message:
TWP: Add Goto next/previous object
Changed paths:
engines/twp/actions.h
engines/twp/metaengine.cpp
engines/twp/object.cpp
engines/twp/twp.cpp
diff --git a/engines/twp/actions.h b/engines/twp/actions.h
index 472d692f5ff..9d5c40a402f 100644
--- a/engines/twp/actions.h
+++ b/engines/twp/actions.h
@@ -31,6 +31,8 @@ enum TwpAction {
kMoveRight,
kMoveUp,
kMoveDown,
+ kGotoNextObject,
+ kGotoPreviousObject,
kSkipCutscene,
kSelectActor1,
kSelectActor2,
diff --git a/engines/twp/metaengine.cpp b/engines/twp/metaengine.cpp
index 0494eb40c2c..145a6fd8dc3 100644
--- a/engines/twp/metaengine.cpp
+++ b/engines/twp/metaengine.cpp
@@ -153,6 +153,8 @@ Common::Array<Common::Keymap *> TwpMetaEngine::initKeymaps(const char *target) c
{Common::kStandardActionMoveRight, _s("Right"), Twp::kMoveRight, "RIGHT|JOY_RIGHT", Common::EVENT_INVALID, Common::KEYCODE_RIGHT},
{Common::kStandardActionMoveUp, _s("Up"), Twp::kMoveUp, "UP|JOY_UP", Common::EVENT_INVALID, Common::KEYCODE_UP},
{Common::kStandardActionMoveDown, _s("Down"), Twp::kMoveDown, "DOWN|JOY_DOWN", Common::EVENT_INVALID, Common::KEYCODE_DOWN},
+ {"GOTONPREVOBJECT", _s("Go to previous object"), Twp::kGotoPreviousObject, "JOY_LEFT_SHOULDER", Common::EVENT_INVALID, Common::KEYCODE_INVALID},
+ {"GOTONEXTOBJECT", _s("Go to next object"), Twp::kGotoNextObject, "JOY_RIGHT_SHOULDER", Common::EVENT_INVALID, Common::KEYCODE_INVALID},
{"SKIPCUTSCENE", _s("Skip cutscene"), Twp::kSkipCutscene, "ESCAPE", Common::EVENT_INVALID, Common::KEYCODE_INVALID},
{"SELECTACTOR1", _s("Select Actor 1"), Twp::kSelectActor1, "1", Common::EVENT_INVALID, Common::KEYCODE_INVALID},
{"SELECTACTOR2", _s("Select Actor 2"), Twp::kSelectActor2, "2", Common::EVENT_INVALID, Common::KEYCODE_INVALID},
diff --git a/engines/twp/object.cpp b/engines/twp/object.cpp
index 3ea740f8f14..292cdb9a2d9 100644
--- a/engines/twp/object.cpp
+++ b/engines/twp/object.cpp
@@ -505,7 +505,7 @@ bool Object::inInventory() {
}
bool Object::contains(const Math::Vector2d &pos) {
- Math::Vector2d p = pos - _node->getPos() - _node->getOffset();
+ Math::Vector2d p = pos - _node->getAbsPos();
return _hotspot.contains(p.getX(), p.getY());
}
diff --git a/engines/twp/twp.cpp b/engines/twp/twp.cpp
index 5bff288b697..dd5c678448c 100644
--- a/engines/twp/twp.cpp
+++ b/engines/twp/twp.cpp
@@ -60,6 +60,118 @@ namespace Twp {
TwpEngine *g_twp;
+struct GetNoun {
+ GetNoun(int verbId, Common::SharedPtr<Object> &obj) : _verbId(verbId), _noun(obj) {
+ _noun = nullptr;
+ }
+
+ bool operator()(Common::SharedPtr<Object> obj) {
+ if (((_verbId == VERB_TALKTO) || (_verbId == VERB_WALKTO) || !g_twp->_resManager->isActor(obj->getId())) && (obj->_node->getZSort() <= _zOrder)) {
+ _noun = obj;
+ _zOrder = obj->_node->getZSort();
+ }
+ return false;
+ }
+
+public:
+ Common::SharedPtr<Object> &_noun;
+ int _zOrder = INT_MAX;
+ const int _verbId;
+};
+
+struct GetUseNoun2 {
+ explicit GetUseNoun2(Common::SharedPtr<Object> &obj) : _noun2(obj) {
+ _noun2 = nullptr;
+ }
+
+ bool operator()(Common::SharedPtr<Object> obj) {
+ if (obj->_node->getZSort() <= _zOrder) {
+ if ((obj != g_twp->_actor) && (g_twp->_noun2 != obj)) {
+ _noun2 = obj;
+ _zOrder = obj->_node->getZSort();
+ }
+ }
+ return false;
+ }
+
+public:
+ Common::SharedPtr<Object> &_noun2;
+ int _zOrder = INT_MAX;
+};
+
+struct GetGiveableNoun2 {
+ explicit GetGiveableNoun2(Common::SharedPtr<Object> &obj) : _noun2(obj) {
+ _noun2 = nullptr;
+ }
+
+ bool operator()(Common::SharedPtr<Object> obj) {
+ if ((obj != g_twp->_actor) && (obj->getFlags() & GIVEABLE) && (g_twp->_noun2 != obj)) {
+ _noun2 = obj;
+ return true;
+ }
+ return false;
+ }
+
+public:
+ Common::SharedPtr<Object> &_noun2;
+};
+
+struct InInventory {
+ explicit InInventory(Common::SharedPtr<Object> &obj) : _obj(obj) { _obj = nullptr; }
+ bool operator()(Common::SharedPtr<Object> obj) {
+ if (obj->inInventory()) {
+ _obj = obj;
+ return true;
+ }
+ return false;
+ }
+
+public:
+ Common::SharedPtr<Object> &_obj;
+};
+
+typedef struct ObjPos {
+ ObjPos(Common::SharedPtr<Object> obj, const Math::Vector2d &pos, float distance, int index) : _obj(obj), _pos(pos), _distance(distance), _index(index) {}
+ float _distance = 0.f;
+ Math::Vector2d _pos;
+ Common::SharedPtr<Object> _obj;
+ int _index;
+} ObjPos;
+
+struct ObjPosComparer {
+ bool operator()(const ObjPos &x, const ObjPos &y) const {
+ return x._distance < y._distance;
+ }
+};
+
+struct GetByZOrder {
+ explicit GetByZOrder(Common::SharedPtr<Object> &result) : _result(result) {
+ result = nullptr;
+ }
+
+ bool operator()(Common::SharedPtr<Object> obj) {
+ if (obj->_node->getZSort() <= _zOrder) {
+ if (!g_twp->_resManager->isActor(obj->getId()) || !obj->_key.empty()) {
+ _result = obj;
+ _zOrder = obj->_node->getZSort();
+ }
+ }
+ return false;
+ }
+
+public:
+ Common::SharedPtr<Object> &_result;
+
+private:
+ int _zOrder = INT_MAX;
+};
+
+struct DefineObjectParams {
+ HSQUIRRELVM v;
+ bool pseudo;
+ Common::SharedPtr<Room> room;
+};
+
TwpEngine::TwpEngine(OSystem *syst, const TwpGameDescription *gameDesc)
: Engine(syst),
_gameDescription(gameDesc),
@@ -326,20 +438,6 @@ void objsAt(Math::Vector2d pos, TFunc func) {
}
}
-struct InInventory {
- explicit InInventory(Common::SharedPtr<Object> &obj) : _obj(obj) { _obj = nullptr; }
- bool operator()(Common::SharedPtr<Object> obj) {
- if (obj->inInventory()) {
- _obj = obj;
- return true;
- }
- return false;
- }
-
-public:
- Common::SharedPtr<Object> &_obj;
-};
-
Common::SharedPtr<Object> inventoryAt(Math::Vector2d pos) {
Common::SharedPtr<Object> result;
objsAt(Common::move(pos), InInventory(result));
@@ -390,62 +488,6 @@ Common::Array<ActorSwitcherSlot> TwpEngine::actorSwitcherSlots() {
return result;
}
-struct GetNoun {
- GetNoun(int verbId, Common::SharedPtr<Object> &obj) : _verbId(verbId), _noun(obj) {
- _noun = nullptr;
- }
-
- bool operator()(Common::SharedPtr<Object> obj) {
- if (((_verbId == VERB_TALKTO) || (_verbId == VERB_WALKTO) || !g_twp->_resManager->isActor(obj->getId())) && (obj->_node->getZSort() <= _zOrder)) {
- _noun = obj;
- _zOrder = obj->_node->getZSort();
- }
- return false;
- }
-
-public:
- Common::SharedPtr<Object> &_noun;
- int _zOrder = INT_MAX;
- const int _verbId;
-};
-
-struct GetUseNoun2 {
- explicit GetUseNoun2(Common::SharedPtr<Object> &obj) : _noun2(obj) {
- _noun2 = nullptr;
- }
-
- bool operator()(Common::SharedPtr<Object> obj) {
- if (obj->_node->getZSort() <= _zOrder) {
- if ((obj != g_twp->_actor) && (g_twp->_noun2 != obj)) {
- _noun2 = obj;
- _zOrder = obj->_node->getZSort();
- }
- }
- return false;
- }
-
-public:
- Common::SharedPtr<Object> &_noun2;
- int _zOrder = INT_MAX;
-};
-
-struct GetGiveableNoun2 {
- explicit GetGiveableNoun2(Common::SharedPtr<Object> &obj) : _noun2(obj) {
- _noun2 = nullptr;
- }
-
- bool operator()(Common::SharedPtr<Object> obj) {
- if ((obj != g_twp->_actor) && (obj->getFlags() & GIVEABLE) && (g_twp->_noun2 != obj)) {
- _noun2 = obj;
- return true;
- }
- return false;
- }
-
-public:
- Common::SharedPtr<Object> &_noun2;
-};
-
void TwpEngine::update(float elapsed) {
const uint32 startUpdateTime = _system->getMillis();
_time += elapsed;
@@ -797,6 +839,75 @@ static void setVerbAction(int verbSlot) {
g_twp->_hud->selectVerb(slot->verbSlots[verbSlot]._verb);
}
+static bool isOnScreen(Common::SharedPtr<Object> obj) {
+ Math::Vector2d pos = obj->_node->getPos() - g_twp->getGfx().cameraPos();
+ Math::Vector2d size = g_twp->getGfx().camera();
+ return Common::Rect(0.0f, 0.0f, size.getX(), size.getY()).contains(pos.getX(), pos.getY());
+}
+
+static void gotoObject(bool next) {
+ if (!g_twp->_room || !g_twp->_inputState._inputActive || !g_twp->_inputState._showCursor)
+ return;
+
+ // get all objects touchable and on screen and get their distance to the actor
+ Math::Vector2d actorPos(g_twp->_actor->_node->getAbsPos());
+ Common::Array<ObjPos> objPos;
+ for (size_t i = 0; i < g_twp->_room->_layers.size(); i++) {
+ Common::SharedPtr<Layer> layer = g_twp->_room->_layers[i];
+ for (size_t j = 0; j < layer->_objects.size(); j++) {
+ Common::SharedPtr<Object> obj(layer->_objects[j]);
+ if (g_twp->_resManager->isActor(obj->getId()) || !obj->isTouchable() || !isOnScreen(obj))
+ continue;
+
+ Math::Vector2d pos(obj->_node->getAbsPos());
+ if (pos == Math::Vector2d())
+ continue;
+
+ Common::Rect hotspot = obj->_hotspot;
+ Math::Vector2d center(hotspot.left + hotspot.width() / 2.f, hotspot.top + hotspot.height() / 2.f);
+ pos += center;
+ const float d = actorPos.getX() - pos.getX();
+ objPos.push_back(ObjPos(obj, pos, d, j));
+ }
+ }
+
+ if (objPos.empty())
+ return;
+
+ // sort these objects by distance
+ Common::sort(objPos.begin(), objPos.end(), ObjPosComparer());
+
+ // find between them if the cursor is currently on one object if so find the next object
+ int index = 0;
+ int zsort = INT_MAX;
+ int objIndex = INT_MAX;
+ Math::Vector2d mousePos(g_twp->screenToRoom(g_twp->winToScreen(g_twp->_cursor.pos)));
+ for (size_t i = 0; i < objPos.size(); i++) {
+ if (objPos[i]._obj->contains(mousePos)) {
+ const int objZ = objPos[i]._obj->_node->getZSort();
+ if (objZ > zsort)
+ continue;
+ if (objZ == zsort && objPos[i]._index >= objIndex)
+ continue;
+ objIndex = objPos[i]._index;
+ zsort = objZ;
+ if (next) {
+ index = (i + 1) % objPos.size();
+ } else {
+ index = i - 1;
+ if (index < 0) {
+ index = objPos.size() - 1;
+ }
+ }
+ }
+ }
+
+ // move the cursor to this object
+ Math::Vector2d pos(objPos[index]._pos);
+ pos = g_twp->roomToScreen(pos);
+ g_twp->_moveCursorTo.reset(new MoveCursorTo(g_twp->screenToWin(pos), 0.1f));
+}
+
Common::Error TwpEngine::run() {
const Common::String &gameTarget = ConfMan.getActiveDomainName();
AchMan.setActiveDomain(getMetaEngine()->getAchievementsInfo(gameTarget));
@@ -891,6 +1002,10 @@ Common::Error TwpEngine::run() {
case TwpAction::kSkipCutscene:
skipCutscene();
break;
+ case TwpAction::kGotoNextObject:
+ case TwpAction::kGotoPreviousObject:
+ gotoObject((TwpAction)e.customType == TwpAction::kGotoNextObject);
+ break;
case TwpAction::kSelectActor1:
case TwpAction::kSelectActor2:
case TwpAction::kSelectActor3:
@@ -1164,12 +1279,6 @@ Common::Error TwpEngine::saveGameStream(Common::WriteStream *stream, bool isAuto
return Common::kNoError;
}
-struct DefineObjectParams {
- HSQUIRRELVM v;
- bool pseudo;
- Common::SharedPtr<Room> room;
-};
-
static void onGetPairs(const Common::String &k, HSQOBJECT &oTable, void *data) {
DefineObjectParams *params = static_cast<DefineObjectParams *>(data);
if (oTable._type == OT_TABLE) {
@@ -1581,28 +1690,6 @@ void TwpEngine::fadeTo(FadeEffect effect, float duration, bool fadeToSep) {
_fadeShader->_elapsed = 0.f;
}
-struct GetByZOrder {
- explicit GetByZOrder(Common::SharedPtr<Object> &result) : _result(result) {
- result = nullptr;
- }
-
- bool operator()(Common::SharedPtr<Object> obj) {
- if (obj->_node->getZSort() <= _zOrder) {
- if (!g_twp->_resManager->isActor(obj->getId()) || !obj->_key.empty()) {
- _result = obj;
- _zOrder = obj->_node->getZSort();
- }
- }
- return false;
- }
-
-public:
- Common::SharedPtr<Object> &_result;
-
-private:
- int _zOrder = INT_MAX;
-};
-
Common::SharedPtr<Object> TwpEngine::objAt(const Math::Vector2d &pos) {
Common::SharedPtr<Object> result;
objsAt(pos, GetByZOrder(result));
Commit: 213af70cc6716cb3655611b7fa709251d5e9e47c
https://github.com/scummvm/scummvm/commit/213af70cc6716cb3655611b7fa709251d5e9e47c
Author: scemino (scemino74 at gmail.com)
Date: 2024-05-05T21:15:17+02:00
Commit Message:
TWP: Use correct gamepad mapping
Changed paths:
engines/twp/metaengine.cpp
diff --git a/engines/twp/metaengine.cpp b/engines/twp/metaengine.cpp
index 145a6fd8dc3..e725beb68f5 100644
--- a/engines/twp/metaengine.cpp
+++ b/engines/twp/metaengine.cpp
@@ -149,13 +149,13 @@ Common::Array<Common::Keymap *> TwpMetaEngine::initKeymaps(const char *target) c
} actions[] = {
{"ACTION", _s("Action"), Twp::kDefaultAction, "MOUSE_LEFT|JOY_A|RETURN", Common::EVENT_LBUTTONDOWN, Common::KEYCODE_INVALID},
{"SELECTHIGHLIGHTEDVERB", _s("Select highlighted verb"), Twp::kSelectHighlightedVerb, "MOUSE_RIGHT|JOY_X", Common::EVENT_RBUTTONDOWN, Common::KEYCODE_INVALID},
- {Common::kStandardActionMoveLeft, _s("Left"), Twp::kMoveLeft, "LEFT|JOY_LEFT", Common::EVENT_INVALID, Common::KEYCODE_LEFT},
- {Common::kStandardActionMoveRight, _s("Right"), Twp::kMoveRight, "RIGHT|JOY_RIGHT", Common::EVENT_INVALID, Common::KEYCODE_RIGHT},
- {Common::kStandardActionMoveUp, _s("Up"), Twp::kMoveUp, "UP|JOY_UP", Common::EVENT_INVALID, Common::KEYCODE_UP},
- {Common::kStandardActionMoveDown, _s("Down"), Twp::kMoveDown, "DOWN|JOY_DOWN", Common::EVENT_INVALID, Common::KEYCODE_DOWN},
+ {Common::kStandardActionMoveLeft, _s("Left"), Twp::kMoveLeft, "LEFT|JOY_LEFT_STICK_X-", Common::EVENT_INVALID, Common::KEYCODE_LEFT},
+ {Common::kStandardActionMoveRight, _s("Right"), Twp::kMoveRight, "RIGHT|JOY_LEFT_STICK_X+", Common::EVENT_INVALID, Common::KEYCODE_RIGHT},
+ {Common::kStandardActionMoveUp, _s("Up"), Twp::kMoveUp, "UP|JOY_LEFT_STICK_Y-", Common::EVENT_INVALID, Common::KEYCODE_UP},
+ {Common::kStandardActionMoveDown, _s("Down"), Twp::kMoveDown, "DOWN|JOY_LEFT_STICK_Y+", Common::EVENT_INVALID, Common::KEYCODE_DOWN},
{"GOTONPREVOBJECT", _s("Go to previous object"), Twp::kGotoPreviousObject, "JOY_LEFT_SHOULDER", Common::EVENT_INVALID, Common::KEYCODE_INVALID},
{"GOTONEXTOBJECT", _s("Go to next object"), Twp::kGotoNextObject, "JOY_RIGHT_SHOULDER", Common::EVENT_INVALID, Common::KEYCODE_INVALID},
- {"SKIPCUTSCENE", _s("Skip cutscene"), Twp::kSkipCutscene, "ESCAPE", Common::EVENT_INVALID, Common::KEYCODE_INVALID},
+ {"SKIPCUTSCENE", _s("Skip cutscene"), Twp::kSkipCutscene, "ESCAPE|JOY_Y", Common::EVENT_INVALID, Common::KEYCODE_INVALID},
{"SELECTACTOR1", _s("Select Actor 1"), Twp::kSelectActor1, "1", Common::EVENT_INVALID, Common::KEYCODE_INVALID},
{"SELECTACTOR2", _s("Select Actor 2"), Twp::kSelectActor2, "2", Common::EVENT_INVALID, Common::KEYCODE_INVALID},
{"SELECTACTOR3", _s("Select Actor 3"), Twp::kSelectActor3, "3", Common::EVENT_INVALID, Common::KEYCODE_INVALID},
@@ -167,9 +167,9 @@ Common::Array<Common::Keymap *> TwpMetaEngine::initKeymaps(const char *target) c
{"SELECTCHOICE4", _s("Select Choice 4"), Twp::kSelectChoice4, "4", Common::EVENT_INVALID, Common::KEYCODE_INVALID},
{"SELECTCHOICE5", _s("Select Choice 5"), Twp::kSelectChoice5, "5", Common::EVENT_INVALID, Common::KEYCODE_INVALID},
{"SELECTCHOICE6", _s("Select Choice 6"), Twp::kSelectChoice6, "6", Common::EVENT_INVALID, Common::KEYCODE_INVALID},
- {"SELECTNEXTACTOR", _s("Select Next Actor"), Twp::kSelectNextActor, "0", Common::EVENT_INVALID, Common::KEYCODE_INVALID},
- {"SELECTPREVACTOR", _s("Select Previous Actor"), Twp::kSelectPreviousActor, "9", Common::EVENT_INVALID, Common::KEYCODE_INVALID},
- {"SKIPTEXT", _s("Skip Text"), Twp::kSkipText, "MOUSE_MIDDLE|PERIOD|JOY_Y", Common::EVENT_INVALID, Common::KEYCODE_INVALID},
+ {"SELECTNEXTACTOR", _s("Select Next Actor"), Twp::kSelectNextActor, "0|JOY_RIGHT_TRIGGER", Common::EVENT_INVALID, Common::KEYCODE_INVALID},
+ {"SELECTPREVACTOR", _s("Select Previous Actor"), Twp::kSelectPreviousActor, "9|JOY_LEFT_TRIGGER", Common::EVENT_INVALID, Common::KEYCODE_INVALID},
+ {"SKIPTEXT", _s("Skip Text"), Twp::kSkipText, "MOUSE_MIDDLE|PERIOD|JOY_B", Common::EVENT_INVALID, Common::KEYCODE_INVALID},
{"SHOWHOTSPOTS", _s("Show hotspots"), Twp::kShowHotspots, "TAB", Common::EVENT_INVALID, Common::KEYCODE_INVALID},
{"OPEN", _s("Open"), Twp::kOpen, "q", Common::EVENT_INVALID, Common::KEYCODE_INVALID},
{"CLOSE", _s("Close"), Twp::kClose, "a", Common::EVENT_INVALID, Common::KEYCODE_INVALID},
Commit: 9105713b42cfa2a2fb91c85c7671a9f0fc345c46
https://github.com/scummvm/scummvm/commit/9105713b42cfa2a2fb91c85c7671a9f0fc345c46
Author: scemino (scemino74 at gmail.com)
Date: 2024-05-05T21:15:17+02:00
Commit Message:
TWP: Fix unchecked return value in getUserPref function.
Coverity CID 1544403
Changed paths:
engines/twp/genlib.cpp
diff --git a/engines/twp/genlib.cpp b/engines/twp/genlib.cpp
index 29e03955f2d..416926a4dfc 100644
--- a/engines/twp/genlib.cpp
+++ b/engines/twp/genlib.cpp
@@ -371,13 +371,17 @@ static SQInteger getUserPref(HSQUIRRELVM v) {
SQObjectType type = sq_gettype(v, 3);
if (type == SQObjectType::OT_STRING) {
Common::String str;
- sqget(v, 3, str);
+ if (SQ_FAILED(sqget(v, 3, str))) {
+ return sq_throwerror(v, _SC("failed to get string"));
+ }
sqpush(v, ConfMan.hasKey(key) ? ConfMan.get(key) : str);
return 1;
}
if (type == SQObjectType::OT_INTEGER) {
SQInteger integer;
- sqget(v, 3, integer);
+ if (SQ_FAILED(sqget(v, 3, integer))) {
+ return sq_throwerror(v, _SC("failed to get integer"));
+ }
if (ConfMan.hasKey(key)) {
Common::String value = ConfMan.get(key);
bool bValue = false;
@@ -394,7 +398,9 @@ static SQInteger getUserPref(HSQUIRRELVM v) {
}
if (type == SQObjectType::OT_FLOAT) {
SQFloat fl;
- sqget(v, 3, fl);
+ if (SQ_FAILED(sqget(v, 3, fl))) {
+ return sq_throwerror(v, _SC("failed to get float"));
+ }
sqpush(v, ConfMan.hasKey(key) ? atof(ConfMan.get(key).c_str()) : fl);
return 1;
}
Commit: 7a3862b44bf44939af7f3350451b7d08604d111d
https://github.com/scummvm/scummvm/commit/7a3862b44bf44939af7f3350451b7d08604d111d
Author: scemino (scemino74 at gmail.com)
Date: 2024-05-05T21:15:17+02:00
Commit Message:
TWP: Add Select Verb/Inventory
Changed paths:
engines/twp/actions.h
engines/twp/hud.cpp
engines/twp/hud.h
engines/twp/metaengine.cpp
engines/twp/scenegraph.cpp
engines/twp/scenegraph.h
engines/twp/twp.cpp
diff --git a/engines/twp/actions.h b/engines/twp/actions.h
index 9d5c40a402f..5ceda046c75 100644
--- a/engines/twp/actions.h
+++ b/engines/twp/actions.h
@@ -33,6 +33,10 @@ enum TwpAction {
kMoveDown,
kGotoNextObject,
kGotoPreviousObject,
+ kSelectVerbInventoryLeft,
+ kSelectVerbInventoryRight,
+ kSelectVerbInventoryUp,
+ kSelectVerbInventoryDown,
kSkipCutscene,
kSelectActor1,
kSelectActor2,
diff --git a/engines/twp/hud.cpp b/engines/twp/hud.cpp
index d4057d6c965..4e022a40c0c 100644
--- a/engines/twp/hud.cpp
+++ b/engines/twp/hud.cpp
@@ -279,4 +279,14 @@ void Hud::setVisible(bool visible) {
}
}
+Math::Vector2d Hud::getVerbPos(const VerbSlot &verbSlot) const {
+ SpriteSheet *verbSheet = g_twp->_resManager->spriteSheet("VerbSheet");
+ bool retroVerbs = ConfMan.getBool("retroVerbs");
+ Common::String verbSuffix = retroVerbs ? "_retro" : "";
+ Common::String lang = ConfMan.get("language");
+ const SpriteSheetFrame &verbFrame = verbSheet->getFrame(Common::String::format("%s%s_%s", verbSlot._verb.image.c_str(), verbSuffix.c_str(), lang.c_str()));
+ Common::Rect r = verbFrame.spriteSourceSize;
+ return Math::Vector2d(r.left + r.width() / 2.f, r.top + r.height() / 2.f);
+}
+
} // namespace Twp
diff --git a/engines/twp/hud.h b/engines/twp/hud.h
index d7617c44f87..c74674dbd58 100644
--- a/engines/twp/hud.h
+++ b/engines/twp/hud.h
@@ -126,6 +126,8 @@ public:
void setVisible(bool visible) override;
void selectVerb(const Verb &verb);
+ Math::Vector2d getVerbPos(const VerbSlot &verbSlot) const;
+
private:
void drawCore(const Math::Matrix4 &trsf) final;
void drawSprite(const SpriteSheetFrame &sf, Texture *texture, const Color &color, const Math::Matrix4 &trsf);
diff --git a/engines/twp/metaengine.cpp b/engines/twp/metaengine.cpp
index e725beb68f5..d0359ac707d 100644
--- a/engines/twp/metaengine.cpp
+++ b/engines/twp/metaengine.cpp
@@ -155,6 +155,10 @@ Common::Array<Common::Keymap *> TwpMetaEngine::initKeymaps(const char *target) c
{Common::kStandardActionMoveDown, _s("Down"), Twp::kMoveDown, "DOWN|JOY_LEFT_STICK_Y+", Common::EVENT_INVALID, Common::KEYCODE_DOWN},
{"GOTONPREVOBJECT", _s("Go to previous object"), Twp::kGotoPreviousObject, "JOY_LEFT_SHOULDER", Common::EVENT_INVALID, Common::KEYCODE_INVALID},
{"GOTONEXTOBJECT", _s("Go to next object"), Twp::kGotoNextObject, "JOY_RIGHT_SHOULDER", Common::EVENT_INVALID, Common::KEYCODE_INVALID},
+ {"SELVERBINVENOTRYLEFT", _s("Select verb/item Left"), Twp::kSelectVerbInventoryLeft, "JOY_LEFT", Common::EVENT_INVALID, Common::KEYCODE_INVALID},
+ {"SELVERBINVENOTRYRIGHT", _s("Select verb/item Right"), Twp::kSelectVerbInventoryRight, "JOY_RIGHT", Common::EVENT_INVALID, Common::KEYCODE_INVALID},
+ {"SELVERBINVENOTRYUP", _s("Select verb/item Up"), Twp::kSelectVerbInventoryUp, "JOY_UP", Common::EVENT_INVALID, Common::KEYCODE_INVALID},
+ {"SELVERBINVENOTRYDOWN", _s("Select verb/item Down"), Twp::kSelectVerbInventoryDown, "JOY_DOWN", Common::EVENT_INVALID, Common::KEYCODE_INVALID},
{"SKIPCUTSCENE", _s("Skip cutscene"), Twp::kSkipCutscene, "ESCAPE|JOY_Y", Common::EVENT_INVALID, Common::KEYCODE_INVALID},
{"SELECTACTOR1", _s("Select Actor 1"), Twp::kSelectActor1, "1", Common::EVENT_INVALID, Common::KEYCODE_INVALID},
{"SELECTACTOR2", _s("Select Actor 2"), Twp::kSelectActor2, "2", Common::EVENT_INVALID, Common::KEYCODE_INVALID},
diff --git a/engines/twp/scenegraph.cpp b/engines/twp/scenegraph.cpp
index 1717c9f8f70..df9054f9847 100644
--- a/engines/twp/scenegraph.cpp
+++ b/engines/twp/scenegraph.cpp
@@ -611,6 +611,19 @@ Math::Vector2d Inventory::getPos(Common::SharedPtr<Object> inv) const {
return {};
}
+Math::Vector2d Inventory::getPos(int i) const {
+ assert((i >= 0) && (i < 8));
+ return Math::Vector2d(_itemRects[i].left + _itemRects[i].width() / 2.f, _itemRects[i].top + _itemRects[i].height() / 2.f);
+}
+
+int Inventory::getOverIndex() const {
+ for (int i = 0; i < NUMOBJECTS; i++) {
+ if (_inventoryOver[i])
+ return i;
+ }
+ return -1;
+}
+
void Inventory::drawSprite(const SpriteSheetFrame &sf, Texture *texture, const Color &color, const Math::Matrix4 &t) {
Math::Matrix4 trsf(t);
Math::Vector3d pos(sf.spriteSourceSize.left - sf.sourceSize.getX() / 2.f, -sf.spriteSourceSize.height() - sf.spriteSourceSize.top + sf.sourceSize.getY() / 2.f, 0.f);
@@ -746,6 +759,8 @@ void Inventory::update(float elapsed, Common::SharedPtr<Object> actor, const Col
_shake[i] = Common::ScopedPtr<Motor>(new ShakeInventory(_shakeOffset[i], 0.4f));
_inventoryOver[i] = true;
}
+ } else {
+ _inventoryOver[i] = true;
}
} else {
_inventoryOver[i] = false;
diff --git a/engines/twp/scenegraph.h b/engines/twp/scenegraph.h
index 7202762176f..4fbc4cb70f9 100644
--- a/engines/twp/scenegraph.h
+++ b/engines/twp/scenegraph.h
@@ -1,4 +1,3 @@
-
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
@@ -301,6 +300,8 @@ public:
bool isOver() const { return _over; }
Common::SharedPtr<Object> getObject() const { return _obj; }
Math::Vector2d getPos(Common::SharedPtr<Object> inv) const;
+ Math::Vector2d getPos(int index) const;
+ int getOverIndex() const;
void setVisible(bool visible) override;
diff --git a/engines/twp/twp.cpp b/engines/twp/twp.cpp
index dd5c678448c..013009caf03 100644
--- a/engines/twp/twp.cpp
+++ b/engines/twp/twp.cpp
@@ -845,6 +845,10 @@ static bool isOnScreen(Common::SharedPtr<Object> obj) {
return Common::Rect(0.0f, 0.0f, size.getX(), size.getY()).contains(pos.getX(), pos.getY());
}
+static void moveCursorTo(const Math::Vector2d &pos) {
+ g_twp->_moveCursorTo.reset(new MoveCursorTo(pos, 0.1f));
+}
+
static void gotoObject(bool next) {
if (!g_twp->_room || !g_twp->_inputState._inputActive || !g_twp->_inputState._showCursor)
return;
@@ -905,7 +909,108 @@ static void gotoObject(bool next) {
// move the cursor to this object
Math::Vector2d pos(objPos[index]._pos);
pos = g_twp->roomToScreen(pos);
- g_twp->_moveCursorTo.reset(new MoveCursorTo(g_twp->screenToWin(pos), 0.1f));
+ moveCursorTo(g_twp->screenToWin(pos));
+}
+
+static void selectVerbInventory(int direction) {
+ if (!g_twp->_room || !g_twp->_inputState._inputActive || !g_twp->_hud->isVisible())
+ return;
+
+ ActorSlot *slot = g_twp->_hud->actorSlot(g_twp->_actor);
+ if (!slot)
+ return;
+
+ if (g_twp->_uiInv.isOver()) {
+ int invIndex = g_twp->_uiInv.getOverIndex();
+ if (invIndex != -1) {
+ switch (direction) {
+ case 0: // Left
+ {
+ if (invIndex == 0) {
+ moveCursorTo(g_twp->_hud->getVerbPos(slot->verbSlots[7]));
+ return;
+ }
+ if (invIndex == 4) {
+ moveCursorTo(g_twp->_hud->getVerbPos(slot->verbSlots[8]));
+ return;
+ }
+ invIndex--;
+ } break;
+ case 1: // Right
+ {
+ if (invIndex == 3 || invIndex == 7)
+ return;
+ invIndex++;
+ } break;
+ case 2: // Up
+ {
+ if (invIndex < 4) {
+ g_twp->_actor->inventoryScrollUp();
+ return;
+ }
+ invIndex -= 4;
+ } break;
+ case 3: // Down
+ if (invIndex > 3) {
+ g_twp->_actor->inventoryScrollDown();
+ return;
+ }
+ invIndex += 4;
+ break;
+ }
+ moveCursorTo(g_twp->screenToWin(g_twp->_uiInv.getPos(invIndex)));
+ return;
+ }
+ }
+
+ // get the verb where the cursor is
+ int id = 0;
+ for (int i = 1; i < MAX_VERBS; i++) {
+ const VerbSlot &verbSlot = slot->verbSlots[i];
+ if (verbSlot._over) {
+ id = i;
+ break;
+ }
+ }
+
+ if (!id) {
+ const VerbSlot &verbSlot = slot->verbSlots[5];
+ Math::Vector2d pos(g_twp->_hud->getVerbPos(verbSlot));
+ moveCursorTo(pos);
+ return;
+ }
+
+ switch (direction) {
+ case 0: // Left
+ {
+ if (id < 4)
+ break;
+ id -= 3;
+ } break;
+ case 1: // Right
+ {
+ if (id > 6) {
+ moveCursorTo(g_twp->screenToWin(g_twp->_uiInv.getPos(id == 7 ? 0 : 4)));
+ return;
+ }
+ id += 3;
+ } break;
+ case 2: // Up
+ {
+ if ((id % 3) == 1)
+ break;
+ id--;
+ } break;
+ case 3: // Down
+ if ((id % 3) == 0)
+ break;
+ id++;
+ break;
+ }
+
+ const VerbSlot &verbSlot = slot->verbSlots[id];
+ Math::Vector2d pos(g_twp->_hud->getVerbPos(verbSlot));
+ moveCursorTo(pos);
}
Common::Error TwpEngine::run() {
@@ -1006,6 +1111,12 @@ Common::Error TwpEngine::run() {
case TwpAction::kGotoPreviousObject:
gotoObject((TwpAction)e.customType == TwpAction::kGotoNextObject);
break;
+ case TwpAction::kSelectVerbInventoryLeft:
+ case TwpAction::kSelectVerbInventoryRight:
+ case TwpAction::kSelectVerbInventoryUp:
+ case TwpAction::kSelectVerbInventoryDown:
+ selectVerbInventory(e.customType - (int)TwpAction::kSelectVerbInventoryLeft);
+ break;
case TwpAction::kSelectActor1:
case TwpAction::kSelectActor2:
case TwpAction::kSelectActor3:
@@ -1095,14 +1206,14 @@ Common::Error TwpEngine::run() {
break;
case Common::KEYCODE_UP:
if (_dialog->getState() == WaitingForChoice) {
- _moveCursorTo.reset(new MoveCursorTo(screenToWin(_dialog->getPreviousChoicePos(winToScreen(_cursor.pos))), 0.1f));
+ moveCursorTo(screenToWin(_dialog->getPreviousChoicePos(winToScreen(_cursor.pos))));
} else {
_cursor.holdUp = true;
}
break;
case Common::KEYCODE_DOWN:
if (_dialog->getState() == WaitingForChoice) {
- _moveCursorTo.reset(new MoveCursorTo(screenToWin(_dialog->getNextChoicePos(winToScreen(_cursor.pos))), 0.1f));
+ moveCursorTo(screenToWin(_dialog->getNextChoicePos(winToScreen(_cursor.pos))));
} else {
_cursor.holdDown = true;
}
More information about the Scummvm-git-logs
mailing list