diff options
author | Matthew Hoops | 2010-05-18 04:17:58 +0000 |
---|---|---|
committer | Matthew Hoops | 2010-05-18 04:17:58 +0000 |
commit | 3dda73d9a2b65da0dad2d184c52f5ebbee682b59 (patch) | |
tree | b6169db546b692ff9ef889826deda4bfa0b76bf4 /engines/sci/graphics | |
parent | 0fe2ba6a0dd1bc7a3edda7ed8deaeba10f39ab9b (diff) | |
download | scummvm-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.cpp | 52 | ||||
-rw-r--r-- | engines/sci/graphics/cursor.h | 1 | ||||
-rw-r--r-- | engines/sci/graphics/view.cpp | 87 |
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); |