MOHAWK: RIVEN: Only use x mouse position to move dome sliders

Fixes Trac#10642.

The original engine will move the dome sliders whenever the player is
dragging a dome slider to the left or right regardless of y position.

In ScummVM the dome slider position would only change to the players x
mouse position when the y value was also in the slider hotspot. This
change removes the y check by making the point to be checked always
have a y value in the hotspot rect.

The x values are also bound to the max and min value that any of the
slider hotspots can have. This allows the slider to go all the way to
the left and right even if the user has gone past the slider area
to the left or right while still holding the slider.
This commit is contained in:
David Fioramonti 2018-07-24 04:30:14 -07:00 committed by Bastien Bouclet
parent 560f10c346
commit 51351111d4
2 changed files with 22 additions and 6 deletions

View File

@ -115,7 +115,7 @@ void DomeSpit::checkDomeSliders() {
void DomeSpit::checkSliderCursorChange(uint16 startHotspot) {
// Set the cursor based on _sliderState and what hotspot we're over
int16 sliderSlot = getSliderSlotAtPos(startHotspot, getMousePosition());
int16 sliderSlot = getSliderSlotClosestToPos(startHotspot, getMousePosition());
if (sliderSlot >= 0 && isSliderAtSlot(sliderSlot)) {
_vm->_cursor->setCursor(kRivenOpenHandCursor);
@ -124,10 +124,26 @@ void DomeSpit::checkSliderCursorChange(uint16 startHotspot) {
}
}
int16 DomeSpit::getSliderSlotAtPos(uint16 startHotspot, const Common::Point &pos) const {
int16 DomeSpit::getSliderSlotClosestToPos(uint16 startHotspot, const Common::Point &pos) const {
// Emperically found min x and max x hotspot are used to bound mouse position into
// the slider area vertically. This and the y mouse position being directly put into
// the slider area allows the user to move the cursor out of the slider area and still
// be able to move the slider.
int16 minXHotspot = 211; // suitable min x value hotspot for all domes
int16 maxXHotspot = 407; // suitable max x value hotspot for all domes
// Find the slider slot closest to pos. This is not necessarily the slider being moved.
for (uint16 i = 0; i < kDomeSliderSlotCount; i++) {
RivenHotspot *hotspot = _vm->getCard()->getHotspotByBlstId(startHotspot + i);
if (hotspot->containsPoint(pos)) {
Common::Rect srcRect = hotspot->getRect();
// Only the x value of mouse position being in the hotspot matters
// the y value of srcRect.top is chosen because it is in the rect.
Common::Point posBounded(pos.x, srcRect.top);
// Now clip the x value so it lies in the x extremes of the slider hotspots.
// If this is not done then the user can move the x position past the
// slider area and the slider won't go all the way to that end.
posBounded.x = CLIP<int16>(posBounded.x, minXHotspot, maxXHotspot - 1);
if (hotspot->containsPoint(posBounded)) {
return i;
}
}
@ -140,7 +156,7 @@ bool DomeSpit::isSliderAtSlot(int16 slot) const {
}
void DomeSpit::dragDomeSlider(uint16 startHotspot) {
int16 draggedSliderSlot = getSliderSlotAtPos(startHotspot, getMousePosition());
int16 draggedSliderSlot = getSliderSlotClosestToPos(startHotspot, getMousePosition());
// We're not over any slider
if (draggedSliderSlot < 0 || !isSliderAtSlot(draggedSliderSlot)) {
@ -151,7 +167,7 @@ void DomeSpit::dragDomeSlider(uint16 startHotspot) {
_vm->_cursor->setCursor(kRivenClosedHandCursor);
while (mouseIsDown() && !_vm->hasGameEnded()) {
int16 hoveredHotspot = getSliderSlotAtPos(startHotspot, getMousePosition());
int16 hoveredHotspot = getSliderSlotClosestToPos(startHotspot, getMousePosition());
if (hoveredHotspot >= 0) {
if (hoveredHotspot > draggedSliderSlot && draggedSliderSlot < 24 && !isSliderAtSlot(draggedSliderSlot + 1)) {
// We've moved the slider right one space

View File

@ -43,7 +43,7 @@ protected:
void checkSliderCursorChange(uint16 startHotspot);
void dragDomeSlider(uint16 startHotspot);
void drawDomeSliders(uint16 startHotspot);
int16 getSliderSlotAtPos(uint16 startHotspot, const Common::Point &pos) const;
int16 getSliderSlotClosestToPos(uint16 startHotspot, const Common::Point &pos) const;
bool isSliderAtSlot(int16 slot) const;
Common::String buildCardResourceName(const Common::String &name) const;