aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMax Horn2004-08-22 23:38:00 +0000
committerMax Horn2004-08-22 23:38:00 +0000
commitb20187a0e92a284deb62298a63017de6e63a3661 (patch)
tree8af7efb32dbcfdc1f94aa6a3835fbb517987c50c
parent45ac190548b0b0f33c8dbc391cf14869862b1dac (diff)
downloadscummvm-rg350-b20187a0e92a284deb62298a63017de6e63a3661.tar.gz
scummvm-rg350-b20187a0e92a284deb62298a63017de6e63a3661.tar.bz2
scummvm-rg350-b20187a0e92a284deb62298a63017de6e63a3661.zip
Cursor code cleanup
svn-id: r14690
-rw-r--r--scumm/cursor.cpp161
-rw-r--r--scumm/intern.h6
-rw-r--r--scumm/object.cpp48
-rw-r--r--scumm/resource_v7he.cpp2
-rw-r--r--scumm/script_v5.cpp15
-rw-r--r--scumm/script_v6.cpp6
-rw-r--r--scumm/script_v7he.cpp2
-rw-r--r--scumm/script_v8.cpp4
-rw-r--r--scumm/scumm.cpp11
-rw-r--r--scumm/scumm.h14
10 files changed, 130 insertions, 139 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
diff --git a/scumm/intern.h b/scumm/intern.h
index 2dbaafda18..97234f3da2 100644
--- a/scumm/intern.h
+++ b/scumm/intern.h
@@ -331,6 +331,8 @@ protected:
public:
ScummEngine_v6(GameDetector *detector, OSystem *syst, const ScummGameSettings &gs);
+ virtual void scummInit();
+
protected:
virtual void setupOpcodes();
virtual void executeOpcode(byte i);
@@ -354,6 +356,10 @@ protected:
void shuffleArray(int num, int minIdx, int maxIdx);
+ void setCursorFromImg(uint img, uint room, uint imgindex);
+ void useIm01Cursor(const byte *im, int w, int h);
+ void useBompCursor(const byte *im, int w, int h);
+
/* Version 6 script opcodes */
void o6_setBlastObjectWindow();
void o6_pushByte();
diff --git a/scumm/object.cpp b/scumm/object.cpp
index 8b0d6e65a5..18864ff899 100644
--- a/scumm/object.cpp
+++ b/scumm/object.cpp
@@ -1366,54 +1366,6 @@ int ScummEngine::getDistanceBetween(bool is_obj_1, int b, int c, bool is_obj_2,
return getDist(x, y, x2, y2) * 0xFF / ((i + j) / 2);
}
-void ScummEngine::setCursorImg(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("setCursorImg: Cursor image too large");
-
- bomp = findResource(MKID('BOMP'), dataptr);
- }
-
- if (bomp != NULL)
- useBompCursor(bomp, w, h);
- else
- useIm01Cursor(dataptr, w, h);
-
-}
-
void ScummEngine::nukeFlObjects(int min, int max) {
ObjectData *od;
int i;
diff --git a/scumm/resource_v7he.cpp b/scumm/resource_v7he.cpp
index a9f1442d40..1d597d581e 100644
--- a/scumm/resource_v7he.cpp
+++ b/scumm/resource_v7he.cpp
@@ -67,7 +67,7 @@ void Win32ResExtractor::setCursor(int id) {
&keycolor);
_vm->setCursorHotspot(hotspot_x, hotspot_y);
- _vm->grabCursorFromBuffer(cursor, w, h);
+ _vm->setCursorFromBuffer(cursor, w, h, w);
free(cursorRes);
free(cursor);
}
diff --git a/scumm/script_v5.cpp b/scumm/script_v5.cpp
index bffc56a2c0..41dcd6beab 100644
--- a/scumm/script_v5.cpp
+++ b/scumm/script_v5.cpp
@@ -675,15 +675,14 @@ void ScummEngine_v5::o5_cursorCommand() {
_userPut--;
break;
case 10: // SO_CURSOR_IMAGE
- i = getVarOrDirectByte(PARAM_1);
- j = getVarOrDirectByte(PARAM_2);
- // cursor image in both Looms is based on image from charset
- // omit for now.
- // FIXME: Actually: is this opcode ever called by a non-Loom game?
- // Which V3-V5 game besides Loom makes use of custom cursors, ever?
+ i = getVarOrDirectByte(PARAM_1); // Cursor number
+ j = getVarOrDirectByte(PARAM_2); // Charset letter to use
+ // Cursor image in both Looms are based on images from charset.
+ // For now we don't handle them.
if (_gameId != GID_LOOM && _gameId != GID_LOOM256) {
- warning("setCursorImg called - tell Fingolfin where you saw this!");
- setCursorImg(i, j, 1);
+ // FIXME: Actually: is this opcode ever called by a non-Loom game?
+ // Which V3-V5 game besides Loom makes use of custom cursors, ever?
+ warning("V3--V5 SO_CURSOR_IMAGE(%d,%d) called - tell Fingolfin where you saw this!", i, j);
}
break;
case 11: // SO_CURSOR_HOTSPOT
diff --git a/scumm/script_v6.cpp b/scumm/script_v6.cpp
index 21748811af..07d0235e56 100644
--- a/scumm/script_v6.cpp
+++ b/scumm/script_v6.cpp
@@ -976,7 +976,7 @@ void ScummEngine_v6::o6_cursorCommand() {
case 0x99: // SO_CURSOR_IMAGE Set cursor image
{
int room, obj = popRoomAndObj(&room);
- setCursorImg(obj, room, 1);
+ setCursorFromImg(obj, room, 1);
break;
}
case 0x9A: // SO_CURSOR_HOTSPOT Set cursor hotspot
@@ -992,7 +992,7 @@ void ScummEngine_v6::o6_cursorCommand() {
_charsetColorMap[i] = _charsetData[_string[1]._default.charset][i] = (unsigned char)args[i];
break;
case 0xD6: // SO_CURSOR_TRANSPARENT Set cursor transparent color
- makeCursorColorTransparent(pop());
+ setCursorTransparency(pop());
break;
default:
error("o6_cursorCommand: default case %x", subOp);
@@ -2567,7 +2567,7 @@ void ScummEngine_v6::o6_kernelSetFunctions() {
}
break;
case 12:
- setCursorImg(args[1], (uint) - 1, args[2]);
+ setCursorFromImg(args[1], (uint) - 1, args[2]);
break;
case 13:
derefActor(args[1], "o6_kernelSetFunctions:13")->remapActorPalette(args[2], args[3], args[4], -1);
diff --git a/scumm/script_v7he.cpp b/scumm/script_v7he.cpp
index 92429be9b2..28090ea287 100644
--- a/scumm/script_v7he.cpp
+++ b/scumm/script_v7he.cpp
@@ -749,7 +749,7 @@ void ScummEngine_v7he::o7_cursorCommand() {
_charsetColorMap[i] = _charsetData[_string[1]._default.charset][i] = (unsigned char)args[i];
break;
case 0xD6: // SO_CURSOR_TRANSPARENT Set cursor transparent color
- makeCursorColorTransparent(pop());
+ setCursorTransparency(pop());
break;
default:
error("o6_cursorCommand: default case %x", subOp);
diff --git a/scumm/script_v8.cpp b/scumm/script_v8.cpp
index 3cbfa30d68..f68dfe344a 100644
--- a/scumm/script_v8.cpp
+++ b/scumm/script_v8.cpp
@@ -730,7 +730,7 @@ void ScummEngine_v8::o8_cursorCommand() {
int idx = pop();
int room, obj;
obj = popRoomAndObj(&room);
- setCursorImg(obj, room, idx);
+ setCursorFromImg(obj, room, idx);
}
break;
case 0xE5: // SO_CURSOR_HOTSPOT Set cursor hotspot
@@ -738,7 +738,7 @@ void ScummEngine_v8::o8_cursorCommand() {
setCursorHotspot(pop(), a);
break;
case 0xE6: // SO_CURSOR_TRANSPARENT Set cursor transparent color
- makeCursorColorTransparent(pop());
+ setCursorTransparency(pop());
break;
case 0xE7: { // SO_CHARSET_SET
int charset = pop();
diff --git a/scumm/scumm.cpp b/scumm/scumm.cpp
index f77389df2d..71aa8a97db 100644
--- a/scumm/scumm.cpp
+++ b/scumm/scumm.cpp
@@ -1245,7 +1245,7 @@ void ScummEngine::scummInit() {
_flashlight.buffer = NULL;
}
- // HACK curcor hotspot is wrong
+ // HACK cursor hotspot is wrong
// Original games used
// setCursorHotspot(8, 7);
if (_gameId == GID_FUNPACK)
@@ -1306,6 +1306,15 @@ void ScummEngine::scummInit() {
_lastSaveTime = _system->get_msecs();
}
+void ScummEngine_v6::scummInit() {
+ ScummEngine::scummInit();
+
+ if (_gameId == GID_TENTACLE && res.roomno[rtRoom][60]) {
+ // HACK: For DOTT we manually set the default cursor. See also bug #786994
+ setCursorFromImg(697, 60, 1);
+ setCursorTransparency(1);
+ }
+}
void ScummEngine::initScummVars() {
diff --git a/scumm/scumm.h b/scumm/scumm.h
index cb4b187c7e..9573d41c37 100644
--- a/scumm/scumm.h
+++ b/scumm/scumm.h
@@ -374,7 +374,7 @@ public:
virtual ~ScummEngine();
// Init functions
- void scummInit();
+ virtual void scummInit();
void initScummVars();
virtual void setupScummVars();
@@ -937,17 +937,13 @@ protected:
void desaturatePalette(int hueScale, int satScale, int lightScale, int startColor, int endColor);
void setCursor(int cursor);
- void setCursorImg(uint img, uint room, uint imgindex);
void setCursorHotspot(int x, int y);
- void grabCursor(int x, int y, int w, int h);
- void grabCursor(byte *ptr, int width, int height);
- void grabCursorFromBuffer(byte *ptr, int width, int height);
- void makeCursorColorTransparent(int a);
+ void setCursorTransparency(int a);
void setupCursor();
- void decompressDefaultCursor(int index);
- void useIm01Cursor(const byte *im, int w, int h);
- void useBompCursor(const byte *im, int w, int h);
+ void setBuiltinCursor(int index);
+ void grabCursor(int x, int y, int w, int h);
+ void setCursorFromBuffer(byte *ptr, int width, int height, int pitch);
public:
void markRectAsDirty(VirtScreenNumber virt, int left, int right, int top, int bottom, int dirtybit = 0);