aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--scumm/gfx.cpp6
-rw-r--r--scumm/gfx.h12
-rw-r--r--scumm/object.cpp89
-rw-r--r--scumm/script_v8.cpp21
-rw-r--r--scumm/scumm.h2
-rw-r--r--scumm/vars.cpp3
6 files changed, 106 insertions, 27 deletions
diff --git a/scumm/gfx.cpp b/scumm/gfx.cpp
index 39042907d0..eac9c9d593 100644
--- a/scumm/gfx.cpp
+++ b/scumm/gfx.cpp
@@ -3085,12 +3085,14 @@ void Scumm::useBompCursor(byte *im, int width, int height)
size = width * height;
if (size > sizeof(_grabbedCursor))
- error("useBompCursor: cursor too big");
+ error("useBompCursor: cursor too big (%d)", size);
_cursor.width = width;
_cursor.height = height;
_cursor.animate = 0;
+ // FIXME - why exactly the +10 ? Is that to account for block headers or something?
+ // Should be documented and verified that this is appropriate for V8 bomps, or not.
decompressBomp(_grabbedCursor, im + 10, width, height);
updateCursor();
@@ -3312,6 +3314,8 @@ void Scumm::decompressBomp(byte *dst, byte *src, int w, int h)
int len, num;
byte code, color;
+
+ // FIXME - why this +8? To skip some kind of header? Is this right for V8 ?
src += 8;
do {
diff --git a/scumm/gfx.h b/scumm/gfx.h
index ead63a8ea4..a908646e66 100644
--- a/scumm/gfx.h
+++ b/scumm/gfx.h
@@ -83,8 +83,16 @@ struct BlastObject { /* BlastObjects to draw */
#endif
struct BompHeader { /* Bomp header */
- uint16 unk;
- uint16 width, height;
+ union {
+ struct {
+ uint16 unk;
+ uint16 width, height;
+ } GCC_PACK old;
+
+ struct {
+ uint32 width, height;
+ } GCC_PACK v8;
+ } GCC_PACK;
} GCC_PACK;
#if !defined(__GNUC__)
diff --git a/scumm/object.cpp b/scumm/object.cpp
index a28f7fdd36..5c2653cf85 100644
--- a/scumm/object.cpp
+++ b/scumm/object.cpp
@@ -884,6 +884,9 @@ void Scumm::findObjectInRoom(FindObjectInRoom *fo, byte findWhat, uint id, uint
if (numobj > _numLocalObjects)
error("findObjectInRoom: More (%d) than %d objects in room %d", numobj, _numLocalObjects, room);
+ if (_features & GF_AFTER_V7) {
+ roomptr = getResourceAddress(rtRoomScripts, room);
+ }
if (findWhat & foCodeHeader) {
searchptr = roomptr;
for (i = 0;;) {
@@ -920,6 +923,7 @@ void Scumm::findObjectInRoom(FindObjectInRoom *fo, byte findWhat, uint id, uint
}
}
+ roomptr = fo->roomptr;
if (findWhat & foImageHeader) {
searchptr = roomptr;
for (i = 0;;) {
@@ -1169,15 +1173,38 @@ void Scumm::setCursorImg(uint img, uint room, uint imgindex)
h = READ_LE_UINT16(&foir.cdhd->v6.h) >> 3;
}
- dataptr = findResource(IMxx_tags[imgindex], foir.obim);
- if (dataptr == NULL)
- error("setCursorImg: No such image");
+ // TODO - for V8 don't use IMxx_tags. Rather, we do something similiar to the V8
+ // code in drawBlastObject. It would be *much* nicer if we could aggregate this
+ // common code into some helper functions, instead of having long convuluted
+ // cases scattered all over the place.
+ if (_features & GF_AFTER_V8) {
+ dataptr = findResource(MKID('IMAG'), foir.obim);
+ assert(dataptr);
+
+ dataptr = findResource(MKID('WRAP'), dataptr);
+ assert(dataptr);
+
+ dataptr = findResource(MKID('OFFS'), dataptr);
+ assert(dataptr);
- size = READ_BE_UINT32_UNALIGNED(dataptr + 4);
- if (size > sizeof(_grabbedCursor))
- error("setCursorImg: Cursor image too large");
+ dataptr += READ_LE_UINT32(dataptr + 4 + 4*imgindex);
+ // TODO - distinguish between SMAP and BOMP here?
- if ((bomp = findResource(MKID('BOMP'), dataptr)) != NULL)
+ // HACK - adjust dataptr here until bomp code gets adjusted for V8
+ bomp = dataptr + 2;
+ } else {
+ dataptr = findResource(IMxx_tags[imgindex], foir.obim);
+ if (dataptr == NULL)
+ error("setCursorImg: No such image");
+
+ size = READ_BE_UINT32_UNALIGNED(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);
@@ -1270,23 +1297,53 @@ void Scumm::drawBlastObject(BlastObject *eo)
if (!ptr)
error("BlastObject object %d image not found", eo->number);
- img = findResource(IMxx_tags[eo->image], ptr);
- if (!img)
- img = findResource(IMxx_tags[1], ptr); // Backward compatibility with samnmax blast objects
- if (!img)
- error("blast-object %d invalid image %d (1-x)", eo->number, eo->image);
+ if (_features & GF_AFTER_V8) {
+ // The OBIM contains an IMAG, which in turn contains a WRAP, which contains
+ // an OFFS chunk and multiple BOMP chunks. To find the right BOMP, we can
+ // either use the offsets in the OFFS chunk, or iterate over all BOMPs we find.
+ // Here we use the first method.
+ img = findResource(MKID('IMAG'), ptr);
+ assert(img);
+
+ img = findResource(MKID('WRAP'), img);
+ assert(img);
+
+ img = findResource(MKID('OFFS'), img);
+ assert(img);
+
+ bomp = img + READ_LE_UINT32(img + 4 + 4*eo->image) + 8;
+ } else {
+ img = findResource(IMxx_tags[eo->image], ptr);
+ if (!img)
+ img = findResource(IMxx_tags[1], ptr); // Backward compatibility with samnmax blast objects
+
+ if (!img)
+ error("blast-object %d invalid image %d (1-x)", eo->number, eo->image);
+
+ bomp = findResourceData(MKID('BOMP'), img);
+ }
- bomp = findResourceData(MKID('BOMP'), img);
if (!bomp)
error("object %d is not a blast object", eo->number);
- bdd.srcwidth = READ_LE_UINT16(&((BompHeader *)bomp)->width);
- bdd.srcheight = READ_LE_UINT16(&((BompHeader *)bomp)->height);
+ hexdump(bomp,32);
+ if (_features & GF_AFTER_V8) {
+ bdd.srcwidth = READ_LE_UINT32(&((BompHeader *)bomp)->v8.width);
+ bdd.srcheight = READ_LE_UINT32(&((BompHeader *)bomp)->v8.height);
+ } else {
+ bdd.srcwidth = READ_LE_UINT16(&((BompHeader *)bomp)->old.width);
+ bdd.srcheight = READ_LE_UINT16(&((BompHeader *)bomp)->old.height);
+ }
+
bdd.out = vs->screenPtr + vs->xstart;
bdd.outwidth = vs->width;
bdd.outheight = vs->height;
- bdd.dataptr = bomp + 10;
+ if (_features & GF_AFTER_V8) {
+ bdd.dataptr = bomp + 8; // Why this? See also useBompCursor
+ } else {
+ bdd.dataptr = bomp + 10; // Why this? See also useBompCursor
+ }
bdd.x = eo->posX;
bdd.y = eo->posY;
bdd.scale_x = (byte)eo->scaleX;
diff --git a/scumm/script_v8.cpp b/scumm/script_v8.cpp
index 3b3b21d874..6382833d4f 100644
--- a/scumm/script_v8.cpp
+++ b/scumm/script_v8.cpp
@@ -513,7 +513,7 @@ void Scumm_v8::decodeParseString(int m, int n)
byte buffer[1024];
_msgPtrToAdd = buffer;
_scriptPointer = _messagePtr = addMessageToStack(_messagePtr);
- printf("Message(%d): '%s'\n", m, buffer);
+// printf("Message(%d): '%s'\n", m, buffer);
break;
case 0xD2: // SO_PRINT_WRAP Set print wordwrap
error("decodeParseString: SO_PRINT_MUMBLE");
@@ -714,10 +714,12 @@ void Scumm_v8::o8_cursorCommand()
break;
case 0xE4: // SO_CURSOR_IMAGE Set cursor image
{
- int room, obj = popRoomAndObj(&room);
+ int idx = pop();
+ int room, obj;
+ obj = popRoomAndObj(&room);
// FIXME
- printf("setCursorImg(%d, %d, 1)\n", obj, room);
-// setCursorImg(obj, room, 1);
+ printf("setCursorImg(%d, %d, %d)\n", obj, room, idx);
+ setCursorImg(obj, room, idx);
}
break;
case 0xE5: // SO_CURSOR_HOTSPOT Set cursor hotspot
@@ -1141,6 +1143,13 @@ void Scumm_v8::o8_kludge()
case 108:
// warning("o8_kludge: PaletteBuildRedirection(%d, %d, %d, %d, %d, %d)", args[1], args[2], args[3], args[4], args[5], args[6]);
break;
+ case 118:
+ enqueueObject(args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8], 3);
+ break;
+ case 119:
+ enqueueObject(args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8], 0);
+ break;
+
case 12:
case 13:
case 14:
@@ -1158,8 +1167,6 @@ void Scumm_v8::o8_kludge()
case 33:
case 34:
case 109:
- case 118:
- case 119:
default:
warning("o8_kludge: default case %d", args[0]);
}
@@ -1187,7 +1194,7 @@ void Scumm_v8::o8_kludge2()
default:
// FIXME - hack!
push(0);
- warning("o8_kludge2: default case %d", args[0]);
+// warning("o8_kludge2: default case %d", args[0]);
}
}
diff --git a/scumm/scumm.h b/scumm/scumm.h
index c89fae7682..ae95680274 100644
--- a/scumm/scumm.h
+++ b/scumm/scumm.h
@@ -712,7 +712,7 @@ public:
byte animate, animateIndex;
int8 state;
} _cursor;
- byte _grabbedCursor[2048];
+ byte _grabbedCursor[8192];
byte _currentCursor;
byte _newEffect, _switchRoomEffect2, _switchRoomEffect;
diff --git a/scumm/vars.cpp b/scumm/vars.cpp
index 58324b3ce3..a6a5598c8f 100644
--- a/scumm/vars.cpp
+++ b/scumm/vars.cpp
@@ -247,4 +247,7 @@ void Scumm_v8::setupScummVars()
VAR_CAMERA_SPEED_Y = 108;
VAR_CAMERA_ACCEL_X = 109;
VAR_CAMERA_ACCEL_Y = 110;
+
+ // var 266, 290 and 301 have something to do with cursor images, since various scripts
+ // have setCursorImg(var290,2) or setCursorImg(var266,1) or setCursorImg(var301,1)
}