aboutsummaryrefslogtreecommitdiff
path: root/engines/sci/graphics
diff options
context:
space:
mode:
authorMatthew Hoops2010-05-18 04:17:58 +0000
committerMatthew Hoops2010-05-18 04:17:58 +0000
commit3dda73d9a2b65da0dad2d184c52f5ebbee682b59 (patch)
treeb6169db546b692ff9ef889826deda4bfa0b76bf4 /engines/sci/graphics
parent0fe2ba6a0dd1bc7a3edda7ed8deaeba10f39ab9b (diff)
downloadscummvm-rg350-3dda73d9a2b65da0dad2d184c52f5ebbee682b59.tar.gz
scummvm-rg350-3dda73d9a2b65da0dad2d184c52f5ebbee682b59.tar.bz2
scummvm-rg350-3dda73d9a2b65da0dad2d184c52f5ebbee682b59.zip
Add initial support for KQ6 Mac. Wrapper functions for read/writing to pointers are now used (found in util.*) for code that has different endianness in SCI1.1+ Mac games. Add support for Mac 'snd ' and 'CURS' resources. QFG1 Mac is not yet playable due to script compression.
svn-id: r49070
Diffstat (limited to 'engines/sci/graphics')
-rw-r--r--engines/sci/graphics/cursor.cpp52
-rw-r--r--engines/sci/graphics/cursor.h1
-rw-r--r--engines/sci/graphics/view.cpp87
3 files changed, 99 insertions, 41 deletions
diff --git a/engines/sci/graphics/cursor.cpp b/engines/sci/graphics/cursor.cpp
index e756c773ed..2f8393f9ac 100644
--- a/engines/sci/graphics/cursor.cpp
+++ b/engines/sci/graphics/cursor.cpp
@@ -205,6 +205,58 @@ void GfxCursor::kernelSetView(GuiResourceId viewNum, int loopNum, int celNum, Co
delete cursorHotspot;
}
+void GfxCursor::kernelSetMacCursor(GuiResourceId viewNum, int loopNum, int celNum, Common::Point *hotspot) {
+ // See http://developer.apple.com/legacy/mac/library/documentation/mac/QuickDraw/QuickDraw-402.html
+ // for more information.
+
+ // View 998 seems to be a fake resource used to call for for the Mac CURS resources
+ // For other resources, they're still in the views, so use them.
+ if (viewNum != 998) {
+ kernelSetView(viewNum, loopNum, celNum, hotspot);
+ return;
+ }
+
+ // TODO: What about the 2000 resources? Inventory items? How to handle?
+ // TODO: What games does this work for? At least it does for KQ6.
+ // TODO: Stop asking rhetorical questions.
+
+ Resource *resource = _resMan->findResource(ResourceId(kResourceTypeCursor, 1000 + celNum), false);
+
+ if (!resource) {
+ warning("CURS %d not found", 1000 + celNum);
+ return;
+ }
+
+ assert(resource);
+
+ byte *cursorBitmap = new byte[16 * 16];
+ byte *data = resource->data;
+
+ // Get B&W data
+ for (byte i = 0; i < 32; i++) {
+ byte imageByte = *data++;
+ for (byte b = 0; b < 8; b++)
+ cursorBitmap[i * 8 + b] = (byte)((imageByte & (0x80 >> b)) > 0 ? 0x00 : 0xFF);
+ }
+
+ // Apply mask data
+ for (byte i = 0; i < 32; i++) {
+ byte imageByte = *data++;
+ for (byte b = 0; b < 8; b++)
+ if ((imageByte & (0x80 >> b)) == 0)
+ cursorBitmap[i * 8 + b] = SCI_CURSOR_SCI0_TRANSPARENCYCOLOR; // Doesn't matter, just is transparent
+ }
+
+ uint16 hotspotX = READ_BE_UINT16(data);
+ uint16 hotspotY = READ_BE_UINT16(data + 2);
+
+ CursorMan.replaceCursor(cursorBitmap, 16, 16, hotspotX, hotspotY, SCI_CURSOR_SCI0_TRANSPARENCYCOLOR);
+
+ delete[] cursorBitmap;
+
+ kernelShow();
+}
+
void GfxCursor::setPosition(Common::Point pos) {
if (!_upscaledHires) {
g_system->warpMouse(pos.x, pos.y);
diff --git a/engines/sci/graphics/cursor.h b/engines/sci/graphics/cursor.h
index c0b5f9a478..6d92b3cf5f 100644
--- a/engines/sci/graphics/cursor.h
+++ b/engines/sci/graphics/cursor.h
@@ -52,6 +52,7 @@ public:
bool isVisible();
void kernelSetShape(GuiResourceId resourceId);
void kernelSetView(GuiResourceId viewNum, int loopNum, int celNum, Common::Point *hotspot);
+ void kernelSetMacCursor(GuiResourceId viewNum, int loopNum, int celNum, Common::Point *hotspot);
void setPosition(Common::Point pos);
Common::Point getPosition();
void refreshPosition();
diff --git a/engines/sci/graphics/view.cpp b/engines/sci/graphics/view.cpp
index 5ce323751c..2ba14fbd8f 100644
--- a/engines/sci/graphics/view.cpp
+++ b/engines/sci/graphics/view.cpp
@@ -24,6 +24,7 @@
*/
#include "sci/sci.h"
+#include "sci/util.h"
#include "sci/engine/state.h"
#include "sci/graphics/screen.h"
#include "sci/graphics/palette.h"
@@ -168,11 +169,11 @@ void GfxView::initData(GuiResourceId resourceId) {
case kViewVga11: // View-format SCI1.1+
// HeaderSize:WORD LoopCount:BYTE Unknown:BYTE Version:WORD Unknown:WORD PaletteOffset:WORD
- headerSize = READ_LE_UINT16(_resourceData + 0) + 2; // headerSize is not part of the header, so its added
+ headerSize = READ_SCI11ENDIAN_UINT16(_resourceData + 0) + 2; // headerSize is not part of the header, so its added
assert(headerSize >= 16);
_loopCount = _resourceData[2];
assert(_loopCount);
- palOffset = READ_LE_UINT32(_resourceData + 8);
+ palOffset = READ_SCI11ENDIAN_UINT32(_resourceData + 8);
// FIXME: After LoopCount there is another byte and its set for view 50 within Laura Bow 2 CD, check what it means
loopData = _resourceData + headerSize;
@@ -203,22 +204,24 @@ void GfxView::initData(GuiResourceId resourceId) {
celCount = loopData[2];
_loop[loopNo].celCount = celCount;
- celData = _resourceData + READ_LE_UINT32(loopData + 12);
+ celData = _resourceData + READ_SCI11ENDIAN_UINT32(loopData + 12);
// read cel info
_loop[loopNo].cel = new CelInfo[celCount];
for (celNo = 0; celNo < celCount; celNo++) {
cel = &_loop[loopNo].cel[celNo];
- cel->width = READ_LE_UINT16(celData);
- assert(cel->width);
- cel->height = READ_LE_UINT16(celData + 2);
- assert(cel->height);
- cel->displaceX = READ_LE_UINT16(celData + 4);
- cel->displaceY = READ_LE_UINT16(celData + 6);
+ cel->width = READ_SCI11ENDIAN_UINT16(celData);
+ cel->height = READ_SCI11ENDIAN_UINT16(celData + 2);
+ cel->displaceX = READ_SCI11ENDIAN_UINT16(celData + 4);
+ cel->displaceY = READ_SCI11ENDIAN_UINT16(celData + 6);
+
+ assert(cel->width && cel->height);
+
cel->clearKey = celData[8];
cel->offsetEGA = 0;
- cel->offsetRLE = READ_LE_UINT32(celData + 24);
- cel->offsetLiteral = READ_LE_UINT32(celData + 28);
+ cel->offsetRLE = READ_SCI11ENDIAN_UINT32(celData + 24);
+ cel->offsetLiteral = READ_SCI11ENDIAN_UINT32(celData + 28);
+
cel->rawBitmap = 0;
if (_loop[loopNo].mirrorFlag)
cel->displaceX = -cel->displaceX;
@@ -351,39 +354,41 @@ void GfxView::unpackCel(int16 loopNo, int16 celNo, byte *outPtr, uint32 pixelCou
} else {
literalPtr = _resourceData + celInfo->offsetLiteral;
if (celInfo->offsetRLE) {
- // decompression for data that has separate rle and literal streams
- while (pixelNo < pixelCount) {
- pixel = *rlePtr++;
- runLength = pixel & 0x3F;
- switch (pixel & 0xC0) {
- case 0: // copy bytes as-is
- while (runLength-- && pixelNo < pixelCount)
- outPtr[pixelNo++] = *literalPtr++;
- break;
- case 0x80: // fill with color
- memset(outPtr + pixelNo, *literalPtr++, MIN<uint32>(runLength, pixelCount - pixelNo));
- pixelNo += runLength;
- break;
- case 0xC0: // fill with transparent
+ if (g_sci->getPlatform() == Common::kPlatformMacintosh && getSciVersion() >= SCI_VERSION_1_1) {
+ // Crazy-Ass compression for SCI1.1+ Mac
+ while (pixelNo < pixelCount) {
+ uint32 pixelLine = pixelNo;
+ runLength = *rlePtr++;
pixelNo += runLength;
- break;
+ runLength = *rlePtr++;
+ while (runLength-- && pixelNo < pixelCount) {
+ outPtr[pixelNo] = *literalPtr++;
+ if (outPtr[pixelNo] == 255)
+ outPtr[pixelNo] = 0;
+ pixelNo++;
+ }
+ pixelNo = pixelLine + celInfo->width;
+ }
+ } else {
+ // decompression for data that has separate rle and literal streams
+ while (pixelNo < pixelCount) {
+ pixel = *rlePtr++;
+ runLength = pixel & 0x3F;
+ switch (pixel & 0xC0) {
+ case 0: // copy bytes as-is
+ while (runLength-- && pixelNo < pixelCount)
+ outPtr[pixelNo++] = *literalPtr++;
+ break;
+ case 0x80: // fill with color
+ memset(outPtr + pixelNo, *literalPtr++, MIN<uint32>(runLength, pixelCount - pixelNo));
+ pixelNo += runLength;
+ break;
+ case 0xC0: // fill with transparent
+ pixelNo += runLength;
+ break;
+ }
}
}
- // Crazy-Ass mac compression for clone2727
- // uint32 pixelLine;
- // while (pixelNo < pixelCount) {
- // pixelLine = pixelNo;
- // runLength = *rlePtr++;
- // pixelNo += runLength;
- // runLength = *rlePtr++;
- // while (runLength-- && pixelNo < pixelCount) {
- // outPtr[pixelNo] = *literalPtr++;
- // if (outPtr[pixelNo] == 255)
- // outPtr[pixelNo] = 0;
- // pixelNo++;
- // }
- // pixelNo = pixelLine + celInfo->width;
- // }
} else {
// literal stream only, so no compression
memcpy(outPtr, literalPtr, pixelCount);