aboutsummaryrefslogtreecommitdiff
path: root/scumm/cursor.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'scumm/cursor.cpp')
-rw-r--r--scumm/cursor.cpp161
1 files changed, 95 insertions, 66 deletions
diff --git a/scumm/cursor.cpp b/scumm/cursor.cpp
index 5cf17bc66f..2b53c48da7 100644
--- a/scumm/cursor.cpp
+++ b/scumm/cursor.cpp
@@ -21,6 +21,8 @@
#include "stdafx.h"
#include "scumm/bomp.h"
+#include "scumm/intern.h"
+#include "scumm/object.h"
#include "scumm/scumm.h"
@@ -66,16 +68,48 @@ static const byte default_cursor_hotspots[10] = {
8, 7, //zak256
};
-
void ScummEngine::setupCursor() {
_cursor.animate = 1;
- if (_gameId == GID_TENTACLE && res.roomno[rtRoom][60]) {
- // HACK: For DOTT we manually set the default cursor. See also bug #786994
- setCursorImg(697, 60, 1);
- makeCursorColorTransparent(1);
+}
+
+void ScummEngine::animateCursor() {
+ if (_cursor.animate) {
+ if (!(_cursor.animateIndex & 0x1)) {
+ setBuiltinCursor((_cursor.animateIndex >> 1) & 3);
+ }
+ _cursor.animateIndex++;
}
}
+void ScummEngine::setCursor(int cursor) {
+ if (cursor >= 0 && cursor <= 3)
+ _currentCursor = cursor;
+ else
+ warning("setCursor(%d)", cursor);
+}
+
+void ScummEngine::setCursorHotspot(int x, int y) {
+ _cursor.hotspotX = x;
+ _cursor.hotspotY = y;
+}
+
+void ScummEngine::setCursorTransparency(int a) {
+ int i, size;
+
+ size = _cursor.width * _cursor.height;
+
+ for (i = 0; i < size; i++)
+ if (_grabbedCursor[i] == (byte)a)
+ _grabbedCursor[i] = 0xFF;
+
+ updateCursor();
+}
+
+void ScummEngine::updateCursor() {
+ _system->setMouseCursor(_grabbedCursor, _cursor.width, _cursor.height,
+ _cursor.hotspotX, _cursor.hotspotY);
+}
+
void ScummEngine::grabCursor(int x, int y, int w, int h) {
VirtScreen *vs = findVirtScreen(y);
@@ -84,11 +118,10 @@ void ScummEngine::grabCursor(int x, int y, int w, int h) {
return;
}
- grabCursor((byte *)vs->pixels + (y - vs->topline) * vs->pitch + x, w, h);
-
+ setCursorFromBuffer((byte *)vs->pixels + (y - vs->topline) * vs->pitch + x, w, h, vs->pitch);
}
-void ScummEngine::grabCursor(byte *ptr, int width, int height) {
+void ScummEngine::setCursorFromBuffer(byte *ptr, int width, int height, int pitch) {
uint size;
byte *dst;
@@ -110,7 +143,54 @@ void ScummEngine::grabCursor(byte *ptr, int width, int height) {
updateCursor();
}
-void ScummEngine::useIm01Cursor(const byte *im, int w, int h) {
+void ScummEngine_v6::setCursorFromImg(uint img, uint room, uint imgindex) {
+ int w, h;
+ const byte *dataptr, *bomp;
+ uint32 size;
+ FindObjectInRoom foir;
+
+ if (room == (uint) - 1)
+ room = getObjectRoom(img);
+
+ findObjectInRoom(&foir, foCodeHeader | foImageHeader | foCheckAlreadyLoaded, img, room);
+
+ if (_version == 8) {
+ setCursorHotspot(READ_LE_UINT32(&foir.imhd->v8.hotspot[0].x),
+ READ_LE_UINT32(&foir.imhd->v8.hotspot[0].y));
+ w = READ_LE_UINT32(&foir.imhd->v8.width) / 8;
+ h = READ_LE_UINT32(&foir.imhd->v8.height) / 8;
+ } else if (_version == 7) {
+ setCursorHotspot(READ_LE_UINT16(&foir.imhd->v7.hotspot[0].x),
+ READ_LE_UINT16(&foir.imhd->v7.hotspot[0].y));
+ w = READ_LE_UINT16(&foir.imhd->v7.width) / 8;
+ h = READ_LE_UINT16(&foir.imhd->v7.height) / 8;
+ } else {
+ if (!(_features & GF_HUMONGOUS))
+ setCursorHotspot(READ_LE_UINT16(&foir.imhd->old.hotspot[0].x),
+ READ_LE_UINT16(&foir.imhd->old.hotspot[0].y));
+ w = READ_LE_UINT16(&foir.cdhd->v6.w) / 8;
+ h = READ_LE_UINT16(&foir.cdhd->v6.h) / 8;
+ }
+
+ dataptr = getObjectImage(foir.obim, imgindex);
+ assert(dataptr);
+ if (_version == 8) {
+ bomp = dataptr;
+ } else {
+ size = READ_BE_UINT32(dataptr + 4);
+ if (size > sizeof(_grabbedCursor))
+ error("setCursorFromImg: Cursor image too large");
+
+ bomp = findResource(MKID('BOMP'), dataptr);
+ }
+
+ if (bomp != NULL)
+ useBompCursor(bomp, w, h);
+ else
+ useIm01Cursor(dataptr, w, h);
+}
+
+void ScummEngine_v6::useIm01Cursor(const byte *im, int w, int h) {
VirtScreen *vs = &virtscr[0];
byte *buf, *dst;
const byte *src;
@@ -139,7 +219,7 @@ void ScummEngine::useIm01Cursor(const byte *im, int w, int h) {
gdi.enableZBuffer();
// Grab the data we just drew and setup the cursor with it
- grabCursor(vs->getPixels(0, 0), w, h);
+ setCursorFromBuffer(vs->getPixels(0, 0), w, h, vs->pitch);
// Restore the screen content
src = buf;
@@ -154,33 +234,7 @@ void ScummEngine::useIm01Cursor(const byte *im, int w, int h) {
free(buf);
}
-void ScummEngine::setCursor(int cursor) {
- if (cursor >= 0 && cursor <= 3)
- _currentCursor = cursor;
- else
- warning("setCursor(%d)", cursor);
-}
-
-void ScummEngine::setCursorHotspot(int x, int y) {
- _cursor.hotspotX = x;
- _cursor.hotspotY = y;
-}
-
-void ScummEngine::updateCursor() {
- _system->setMouseCursor(_grabbedCursor, _cursor.width, _cursor.height,
- _cursor.hotspotX, _cursor.hotspotY);
-}
-
-void ScummEngine::animateCursor() {
- if (_cursor.animate) {
- if (!(_cursor.animateIndex & 0x1)) {
- decompressDefaultCursor((_cursor.animateIndex >> 1) & 3);
- }
- _cursor.animateIndex++;
- }
-}
-
-void ScummEngine::useBompCursor(const byte *im, int width, int height) {
+void ScummEngine_v6::useBompCursor(const byte *im, int width, int height) {
uint size;
width *= 8;
@@ -205,7 +259,7 @@ void ScummEngine::useBompCursor(const byte *im, int width, int height) {
updateCursor();
}
-void ScummEngine::decompressDefaultCursor(int idx) {
+void ScummEngine::setBuiltinCursor(int idx) {
int i, j;
byte color;
@@ -217,6 +271,9 @@ void ScummEngine::decompressDefaultCursor(int idx) {
color = default_cursor_colors[idx];
// FIXME: None of the stock cursors are right for Loom. Why is that?
+ // Fingolfing says: because it sets different cursor shapes --
+ // check the SO_CURSOR_IMAGE opcode in script_v5.cpp; if we implement
+ // that, this problem should be gone...
if (_gameId == GID_LOOM || _gameId == GID_LOOM256) {
int w = 0;
@@ -300,32 +357,4 @@ void ScummEngine::decompressDefaultCursor(int idx) {
updateCursor();
}
-void ScummEngine::makeCursorColorTransparent(int a) {
- int i, size;
-
- size = _cursor.width * _cursor.height;
-
- for (i = 0; i < size; i++)
- if (_grabbedCursor[i] == (byte)a)
- _grabbedCursor[i] = 0xFF;
-
- updateCursor();
-}
-
-void ScummEngine::grabCursorFromBuffer(byte *ptr, int width, int height) {
- uint size;
-
- size = width * height;
- if (size > sizeof(_grabbedCursor))
- error("grabCursor: grabbed cursor too big");
-
- _cursor.width = width;
- _cursor.height = height;
- _cursor.animate = 0;
-
- memcpy(_grabbedCursor, ptr, width * height);
-
- updateCursor();
-}
-
} // End of namespace Scumm