aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWalter van Niftrik2009-08-30 01:38:14 +0000
committerWalter van Niftrik2009-08-30 01:38:14 +0000
commit40d6119fd5c8a61ffb11c7744dc60f4a07388d6d (patch)
tree786d65264ebc5cf2b3d301a9da96e17965a5f16c
parentcf5483c3d862a1076943a9b7d986b38e3d1908de (diff)
downloadscummvm-rg350-40d6119fd5c8a61ffb11c7744dc60f4a07388d6d.tar.gz
scummvm-rg350-40d6119fd5c8a61ffb11c7744dc60f4a07388d6d.tar.bz2
scummvm-rg350-40d6119fd5c8a61ffb11c7744dc60f4a07388d6d.zip
SCI: Add support for SetCursor with 4 args.
svn-id: r43813
-rw-r--r--engines/sci/engine/kgraphics.cpp18
-rw-r--r--engines/sci/gfx/operations.cpp34
-rw-r--r--engines/sci/gfx/operations.h10
3 files changed, 59 insertions, 3 deletions
diff --git a/engines/sci/engine/kgraphics.cpp b/engines/sci/engine/kgraphics.cpp
index 89fed9d2d8..16818a9f4d 100644
--- a/engines/sci/engine/kgraphics.cpp
+++ b/engines/sci/engine/kgraphics.cpp
@@ -326,9 +326,23 @@ static reg_t kSetCursorSci11(EngineState *s, int funct_nr, int argc, reg_t *argv
CursorMan.showMouse(argv[0].toSint16() != 0);
break;
case 2:
- GFX_ASSERT(gfxop_set_pointer_position(s->gfx_state,
- Common::Point(argv[0].toUint16(), argv[1].toUint16())));
+ GFX_ASSERT(gfxop_set_pointer_position(s->gfx_state,
+ Common::Point(argv[0].toUint16() + s->port->_bounds.x, argv[1].toUint16() + s->port->_bounds.y)));
break;
+ case 4: {
+ int16 top = argv[0].toSint16();
+ int16 left = argv[1].toSint16();
+ int16 bottom = argv[2].toSint16();
+ int16 right = argv[3].toSint16();
+
+ if ((right >= left) && (bottom >= top)) {
+ Common::Rect rect = Common::Rect(left, top, right + 1, bottom + 1);
+ GFX_ASSERT(gfxop_set_pointer_zone(s->gfx_state, rect));
+ } else {
+ warning("kSetCursor: Ignoring invalid mouse zone (%i, %i)-(%i, %i)", left, top, right, bottom);
+ }
+ break;
+ }
case 5:
case 9:
hotspot = new Common::Point(argv[3].toSint16(), argv[4].toSint16());
diff --git a/engines/sci/gfx/operations.cpp b/engines/sci/gfx/operations.cpp
index b3a1be68d1..a23bae5350 100644
--- a/engines/sci/gfx/operations.cpp
+++ b/engines/sci/gfx/operations.cpp
@@ -258,9 +258,32 @@ static int _gfxop_draw_pixmap(GfxDriver *driver, gfx_pixmap_t *pxm, int priority
}
static void _gfxop_full_pointer_refresh(GfxState *state) {
+ bool clipped = false;
Common::Point mousePoint = g_system->getEventManager()->getMousePos();
+
state->pointer_pos.x = mousePoint.x / state->driver->getMode()->xfact;
state->pointer_pos.y = mousePoint.y / state->driver->getMode()->yfact;
+
+ if (state->pointer_pos.x < state->pointerZone.left) {
+ state->pointer_pos.x = state->pointerZone.left;
+ clipped = true;
+ } else if (state->pointer_pos.x >= state->pointerZone.right) {
+ state->pointer_pos.x = state->pointerZone.right - 1;
+ clipped = true;
+ }
+
+ if (state->pointer_pos.y < state->pointerZone.top) {
+ state->pointer_pos.y = state->pointerZone.top;
+ clipped = true;
+ } else if (state->pointer_pos.y >= state->pointerZone.bottom) {
+ state->pointer_pos.y = state->pointerZone.bottom - 1;
+ clipped = true;
+ }
+
+ // FIXME: Do this only when mouse is grabbed?
+ if (clipped)
+ g_system->warpMouse(state->pointer_pos.x * state->driver->getMode()->xfact,
+ state->pointer_pos.y * state->driver->getMode()->yfact);
}
static int _gfxop_buffer_propagate_box(GfxState *state, rect_t box, gfx_buffer_t buffer);
@@ -427,6 +450,7 @@ int gfxop_init(int version, GfxState *state,
state->gfxResMan = new GfxResManager(state->options, state->driver, resManager);
gfxop_set_clip_zone(state, gfx_rect(0, 0, 320, 200));
+ state->pointerZone = Common::Rect(0, 0, 320, 200);
init_aux_pixmap(&(state->control_map));
init_aux_pixmap(&(state->priority_map));
@@ -1194,10 +1218,18 @@ int gfxop_set_pointer_position(GfxState *state, Common::Point pos) {
g_system->warpMouse(pos.x * state->driver->getMode()->xfact, pos.y * state->driver->getMode()->yfact);
- _gfxop_full_pointer_refresh(state);
+ // Trigger event reading to make sure the mouse coordinates will
+ // actually have changed the next time we read them.
+ gfxop_get_event(state, SCI_EVT_PEEK);
+
return 0;
}
+int gfxop_set_pointer_zone(GfxState *state, Common::Rect rect) {
+ state->pointerZone = rect;
+ return GFX_OK;
+}
+
#define SCANCODE_ROWS_NR 3
struct scancode_row {
diff --git a/engines/sci/gfx/operations.h b/engines/sci/gfx/operations.h
index ec0a810224..865b420681 100644
--- a/engines/sci/gfx/operations.h
+++ b/engines/sci/gfx/operations.h
@@ -94,6 +94,7 @@ struct GfxState {
gfx_options_t *options;
Common::Point pointer_pos; /**< Mouse pointer coordinates */
+ Common::Rect pointerZone; /**< Rectangle in which the pointer can move */
rect_t clip_zone_unscaled; /**< The current UNSCALED clipping zone */
rect_t clip_zone; /**< The current SCALED clipping zone; a cached scaled version of clip_zone_unscaled */
@@ -424,6 +425,15 @@ int gfxop_set_pointer_view(GfxState *state, int nr, int loop, int cel, Common::P
int gfxop_set_pointer_position(GfxState *state, Common::Point pos);
/**
+ * Limits the mouse movement to a given rectangle.
+ *
+ * @param[in] state The affected state
+ * @param[in] rect The rectangle
+ * @return Any error code or GFX_OK
+ */
+int gfxop_set_pointer_zone(GfxState *state, Common::Rect rect);
+
+/**
* Retrieves the next input event from the driver.
*
* @param[in] state The affected state