diff options
author | Max Horn | 2004-01-04 14:35:46 +0000 |
---|---|---|
committer | Max Horn | 2004-01-04 14:35:46 +0000 |
commit | 2ce4d13c048ec5b2cec8fd78071a39d14888af63 (patch) | |
tree | 19abbbab592ecd583a5c9b6909e2ea3e9b608696 /scumm/cursor.cpp | |
parent | 694f02155cba6b7f8ed5cd5d4170eba935e9dcc6 (diff) | |
download | scummvm-rg350-2ce4d13c048ec5b2cec8fd78071a39d14888af63.tar.gz scummvm-rg350-2ce4d13c048ec5b2cec8fd78071a39d14888af63.tar.bz2 scummvm-rg350-2ce4d13c048ec5b2cec8fd78071a39d14888af63.zip |
split out cursor/palette code into separate source files
svn-id: r12138
Diffstat (limited to 'scumm/cursor.cpp')
-rw-r--r-- | scumm/cursor.cpp | 314 |
1 files changed, 314 insertions, 0 deletions
diff --git a/scumm/cursor.cpp b/scumm/cursor.cpp new file mode 100644 index 0000000000..9a8ae5a4fa --- /dev/null +++ b/scumm/cursor.cpp @@ -0,0 +1,314 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2001 Ludvig Strigeus + * Copyright (C) 2001-2003 The ScummVM project + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * $Header$ + * + */ + +#include "stdafx.h" +#include "scumm/bomp.h" +#include "scumm/scumm.h" + + +namespace Scumm { + +/* + * Mouse cursor cycle colors (for the default crosshair). + */ +static const byte default_v1_cursor_colors[4] = { + 1, 1, 12, 11 +}; + +static const byte default_cursor_colors[4] = { + 15, 15, 7, 8 +}; + + + +static const uint16 default_cursor_images[5][16] = { + /* cross-hair */ + { 0x0080, 0x0080, 0x0080, 0x0080, 0x0080, 0x0080, 0x0000, 0x7e3f, + 0x0000, 0x0080, 0x0080, 0x0080, 0x0080, 0x0080, 0x0080, 0x0000 }, + /* hourglass */ + { 0x0000, 0x7ffe, 0x6006, 0x300c, 0x1818, 0x0c30, 0x0660, 0x03c0, + 0x0660, 0x0c30, 0x1998, 0x33cc, 0x67e6, 0x7ffe, 0x0000, 0x0000 }, + /* arrow */ + { 0x0000, 0x4000, 0x6000, 0x7000, 0x7800, 0x7c00, 0x7e00, 0x7f00, + 0x7f80, 0x78c0, 0x7c00, 0x4600, 0x0600, 0x0300, 0x0300, 0x0180 }, + /* hand */ + { 0x1e00, 0x1200, 0x1200, 0x1200, 0x1200, 0x13ff, 0x1249, 0x1249, + 0xf249, 0x9001, 0x9001, 0x9001, 0x8001, 0x8001, 0x8001, 0xffff }, + /* cross-hair zak256 - chrilith palmos */ +/* + { 0x0080, 0x0080, 0x02a0, 0x01c0, 0x0080, 0x1004, 0x0808, 0x7c1f, + 0x0808, 0x1004, 0x0080, 0x01c0, 0x02a0, 0x0080, 0x0080, 0x0000 }, +*/ + { 0x0080, 0x02a0, 0x01c0, 0x0080, 0x0000, 0x2002, 0x1004, 0x780f, + 0x1004, 0x2002, 0x0000, 0x0080, 0x01c0, 0x02a0, 0x0080, 0x0000 }, +}; + +static const byte default_cursor_hotspots[10] = { + 8, 7, 8, 7, 1, 1, 5, 0, + 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::grabCursor(int x, int y, int w, int h) { + VirtScreen *vs = findVirtScreen(y); + + if (vs == NULL) { + warning("grabCursor: invalid Y %d", y); + return; + } + + grabCursor(vs->screenPtr + (y - vs->topline) * vs->width + x, w, h); + +} + +void ScummEngine::grabCursor(byte *ptr, int width, int height) { + uint size; + byte *dst; + + size = width * height; + if (size > sizeof(_grabbedCursor)) + error("grabCursor: grabbed cursor too big"); + + _cursor.width = width; + _cursor.height = height; + _cursor.animate = 0; + + dst = _grabbedCursor; + for (; height; height--) { + memcpy(dst, ptr, width); + dst += width; + ptr += _screenWidth; + } + + updateCursor(); +} + +void ScummEngine::useIm01Cursor(const byte *im, int w, int h) { + VirtScreen *vs = &virtscr[0]; + byte *buf, *dst; + const byte *src; + int i; + + w *= 8; + h *= 8; + + dst = buf = (byte *) malloc(w * h); + src = vs->screenPtr + vs->xstart; + + for (i = 0; i < h; i++) { + memcpy(dst, src, w); + dst += w; + src += vs->width; + } + + drawBox(0, 0, w - 1, h - 1, 0xFF); + + vs->alloctwobuffers = false; + gdi.disableZBuffer(); + gdi.drawBitmap(im, vs, _screenStartStrip, 0, w, h, 0, w / 8, 0); + vs->alloctwobuffers = true; + gdi.enableZBuffer(); + + grabCursor(vs->screenPtr + vs->xstart, w, h); + + src = buf; + dst = vs->screenPtr + vs->xstart; + + for (i = 0; i < h; i++) { + memcpy(dst, src, w); + dst += vs->width; + src += w; + } + + 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; + // FIXME this hacks around offset cursor in the humongous games + if (_features & GF_HUMONGOUS) { + _cursor.hotspotX += 15; + _cursor.hotspotY += 15; + } +} + +void ScummEngine::updateCursor() { + _system->set_mouse_cursor(_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) { + uint size; + + width *= 8; + height *= 8; + + size = width * height; + if (size > sizeof(_grabbedCursor)) + error("useBompCursor: cursor too big (%d)", size); + + _cursor.width = width; + _cursor.height = height; + _cursor.animate = 0; + + // Skip the header + if (_version == 8) { + im += 16; + } else { + im += 18; + } + decompressBomp(_grabbedCursor, im, width, height); + + updateCursor(); +} + +void ScummEngine::decompressDefaultCursor(int idx) { + int i, j; + byte color; + + memset(_grabbedCursor, 0xFF, sizeof(_grabbedCursor)); + + if (_version == 1) + color = default_v1_cursor_colors[idx]; + else + color = default_cursor_colors[idx]; + + // FIXME: None of the stock cursors are right for Loom. Why is that? + + if (_gameId == GID_LOOM || _gameId == GID_LOOM256) { + int w = 0; + + _cursor.width = 8; + _cursor.height = 8; + _cursor.hotspotX = 0; + _cursor.hotspotY = 0; + + for (i = 0; i < 8; i++) { + w += (i >= 6) ? -2 : 1; + for (j = 0; j < w; j++) + _grabbedCursor[i * 8 + j] = color; + } + } else if (_version <= 2) { + _cursor.width = 23; + _cursor.height = 21; + _cursor.hotspotX = 11; + _cursor.hotspotY = 10; + + byte *hotspot = _grabbedCursor + _cursor.hotspotY * _cursor.width + _cursor.hotspotX; + + // Crosshair, slightly assymetric + + for (i = 0; i < 7; i++) { + *(hotspot - 5 - i) = color; + *(hotspot + 5 + i) = color; + } + + for (i = 0; i < 8; i++) { + *(hotspot - _cursor.width * (3 + i)) = color; + *(hotspot + _cursor.width * (3 + i)) = color; + } + + // Arrow heads, diagonal lines + + for (i = 1; i <= 3; i++) { + *(hotspot - _cursor.width * i - 5 - i) = color; + *(hotspot + _cursor.width * i - 5 - i) = color; + *(hotspot - _cursor.width * i + 5 + i) = color; + *(hotspot + _cursor.width * i + 5 + i) = color; + *(hotspot - _cursor.width * (i + 3) - i) = color; + *(hotspot - _cursor.width * (i + 3) + i) = color; + *(hotspot + _cursor.width * (i + 3) - i) = color; + *(hotspot + _cursor.width * (i + 3) + i) = color; + } + + // Final touches + + *(hotspot - _cursor.width - 7) = color; + *(hotspot - _cursor.width + 7) = color; + *(hotspot + _cursor.width - 7) = color; + *(hotspot + _cursor.width + 7) = color; + *(hotspot - (_cursor.width * 5) - 1) = color; + *(hotspot - (_cursor.width * 5) + 1) = color; + *(hotspot + (_cursor.width * 5) - 1) = color; + *(hotspot + (_cursor.width * 5) + 1) = color; + } else { + byte currentCursor = _currentCursor; + +#ifdef __PALM_OS__ + if (_gameId == GID_ZAK256 && currentCursor == 0) + currentCursor = 4; +#endif + + _cursor.width = 16; + _cursor.height = 16; + _cursor.hotspotX = default_cursor_hotspots[2 * currentCursor]; + _cursor.hotspotY = default_cursor_hotspots[2 * currentCursor + 1]; + + for (i = 0; i < 16; i++) { + for (j = 0; j < 16; j++) { + if (default_cursor_images[currentCursor][i] & (1 << j)) + _grabbedCursor[16 * i + 15 - j] = color; + } + } + } + + 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(); +} + +} // End of namespace Scumm |