From 5a7ca3553ca480021c0992e83e9644eeeba2f724 Mon Sep 17 00:00:00 2001 From: Matthew Hoops Date: Thu, 8 Sep 2011 20:38:12 -0400 Subject: PEGASUS: Create separate Cursor class for cursors --- engines/pegasus/cursor.cpp | 179 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 179 insertions(+) create mode 100755 engines/pegasus/cursor.cpp (limited to 'engines/pegasus/cursor.cpp') diff --git a/engines/pegasus/cursor.cpp b/engines/pegasus/cursor.cpp new file mode 100755 index 0000000000..c0af27bdce --- /dev/null +++ b/engines/pegasus/cursor.cpp @@ -0,0 +1,179 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * Additional copyright for this file: + * Copyright (C) 1995-1997 Presto Studios, Inc. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "common/events.h" +#include "common/stream.h" +#include "common/system.h" +#include "graphics/cursorman.h" +#include "graphics/pict.h" +#include "graphics/surface.h" + +#include "pegasus/cursor.h" +#include "pegasus/pegasus.h" + +namespace Pegasus { + +Cursor::Cursor() { + _cursorObscured = false; + _index = -1; +} + +Cursor::~Cursor() { + for (uint32 i = 0; i < _info.size(); i++) { + if (_info[i].surface) { + _info[i].surface->free(); + delete _info[i].surface; + } + delete[] _info[i].palette; + } +} + +void Cursor::addCursorFrames(uint16 id) { + PegasusEngine *vm = (PegasusEngine *)g_engine; + Common::SeekableReadStream *cursStream = vm->_resFork->getResource(MKTAG('C', 'u', 'r', 's'), id); + if (!cursStream) + error("Could not load cursor frames set %d", id); + + uint16 frameCount = cursStream->readUint16BE(); + for (uint16 i = 0; i < frameCount; i++) { + CursorInfo info; + info.tag = cursStream->readUint16BE(); + info.hotspot.x = cursStream->readUint16BE(); + info.hotspot.y = cursStream->readUint16BE(); + info.surface = 0; + info.palette = 0; + info.colorCount = 0; + _info.push_back(info); + } + + delete cursStream; + + setCurrentFrameIndex(0); +} + +void Cursor::setCurrentFrameIndex(int32 index) { + if (_index != index) { + _index = index; + if (index != -1) { + loadCursorImage(_info[index]); + CursorMan.replaceCursorPalette(_info[index].palette, 0, _info[index].colorCount); + CursorMan.replaceCursor((byte *)_info[index].surface->pixels, _info[index].surface->w, _info[index].surface->h, _info[index].hotspot.x, _info[index].hotspot.y, 0); + } + } +} + +int32 Cursor::getCurrentFrameIndex() const { + return _index; +} + +void Cursor::show() { + if (!isVisible()) + CursorMan.showMouse(true); + + _cursorObscured = false; +} + +void Cursor::hide() { + CursorMan.showMouse(false); + setCurrentFrameIndex(0); +} + +void Cursor::hideUntilMoved() { + if (!_cursorObscured) { + hide(); + _cursorObscured = true; + } +} + +void Cursor::useIdleTime() { + if (g_system->getEventManager()->getMousePos() != _cursorLocation) { + _cursorLocation = g_system->getEventManager()->getMousePos(); + if (_index != -1 && _cursorObscured) + show(); + } +} + +void Cursor::getCursorLocation(Common::Point &pt) const { + pt = _cursorLocation; +} + +bool Cursor::isVisible() { + return CursorMan.isVisible(); +} + +void Cursor::loadCursorImage(CursorInfo &cursorInfo) { + if (cursorInfo.surface) + return; + + cursorInfo.surface = new Graphics::Surface(); + + PegasusEngine *vm = (PegasusEngine *)g_engine; + Common::SeekableReadStream *cicnStream = vm->_resFork->getResource(MKTAG('c', 'i', 'c', 'n'), cursorInfo.tag); + + if (!cicnStream) + error("Failed to find color icon %d", cursorInfo.tag); + + // PixMap section + Graphics::PictDecoder::PixMap pixMap = Graphics::PictDecoder::readPixMap(cicnStream); + + // Mask section + cicnStream->readUint32BE(); // mask baseAddr + uint16 maskRowBytes = cicnStream->readUint16BE(); // mask rowBytes + cicnStream->skip(3 * 2); // mask rect + /* uint16 maskHeight = */ cicnStream->readUint16BE(); + + // Bitmap section + cicnStream->readUint32BE(); // baseAddr + uint16 rowBytes = cicnStream->readUint16BE(); + cicnStream->readUint16BE(); // top + cicnStream->readUint16BE(); // left + uint16 height = cicnStream->readUint16BE(); // bottom + cicnStream->readUint16BE(); // right + + // Data section + cicnStream->readUint32BE(); // icon handle + cicnStream->skip(maskRowBytes * height); // FIXME: maskHeight doesn't work here, though the specs say it should + cicnStream->skip(rowBytes * height); + + // Palette section + cicnStream->readUint32BE(); // always 0 + cicnStream->readUint16BE(); // always 0 + cursorInfo.colorCount = cicnStream->readUint16BE() + 1; + + cursorInfo.palette = new byte[256 * cursorInfo.colorCount]; + for (uint16 i = 0; i < cursorInfo.colorCount; i++) { + cicnStream->readUint16BE(); + cursorInfo.palette[i * 3] = cicnStream->readUint16BE() >> 8; + cursorInfo.palette[i * 3 + 1] = cicnStream->readUint16BE() >> 8; + cursorInfo.palette[i * 3 + 2] = cicnStream->readUint16BE() >> 8; + } + + // PixMap data + cursorInfo.surface->create(pixMap.rowBytes, pixMap.bounds.height(), Graphics::PixelFormat::createFormatCLUT8()); + cicnStream->read(cursorInfo.surface->pixels, pixMap.rowBytes * pixMap.bounds.height()); + delete cicnStream; +} + +} // End of namespace Pegasus -- cgit v1.2.3 From fdd50e8414070055e77bf61fcc5837841af2b014 Mon Sep 17 00:00:00 2001 From: Matthew Hoops Date: Thu, 29 Sep 2011 23:29:53 -0400 Subject: PEGASUS: Fix cursor not showing up --- engines/pegasus/cursor.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'engines/pegasus/cursor.cpp') diff --git a/engines/pegasus/cursor.cpp b/engines/pegasus/cursor.cpp index c0af27bdce..9fa921a48e 100755 --- a/engines/pegasus/cursor.cpp +++ b/engines/pegasus/cursor.cpp @@ -38,6 +38,7 @@ namespace Pegasus { Cursor::Cursor() { _cursorObscured = false; _index = -1; + startIdling(); } Cursor::~Cursor() { @@ -48,6 +49,8 @@ Cursor::~Cursor() { } delete[] _info[i].palette; } + + stopIdling(); } void Cursor::addCursorFrames(uint16 id) { -- cgit v1.2.3 From 23c7b9f0dc93181a388fb577e26fb9505c8f852f Mon Sep 17 00:00:00 2001 From: Matthew Hoops Date: Fri, 30 Sep 2011 01:14:11 -0400 Subject: PEGASUS: Introduce better cursor update code --- engines/pegasus/cursor.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'engines/pegasus/cursor.cpp') diff --git a/engines/pegasus/cursor.cpp b/engines/pegasus/cursor.cpp index 9fa921a48e..ee3ab87268 100755 --- a/engines/pegasus/cursor.cpp +++ b/engines/pegasus/cursor.cpp @@ -31,6 +31,7 @@ #include "graphics/surface.h" #include "pegasus/cursor.h" +#include "pegasus/graphics.h" #include "pegasus/pegasus.h" namespace Pegasus { @@ -83,6 +84,7 @@ void Cursor::setCurrentFrameIndex(int32 index) { loadCursorImage(_info[index]); CursorMan.replaceCursorPalette(_info[index].palette, 0, _info[index].colorCount); CursorMan.replaceCursor((byte *)_info[index].surface->pixels, _info[index].surface->w, _info[index].surface->h, _info[index].hotspot.x, _info[index].hotspot.y, 0); + ((PegasusEngine *)g_engine)->_gfx->markCursorAsDirty(); } } } @@ -96,6 +98,7 @@ void Cursor::show() { CursorMan.showMouse(true); _cursorObscured = false; + ((PegasusEngine *)g_engine)->_gfx->markCursorAsDirty(); } void Cursor::hide() { @@ -115,6 +118,7 @@ void Cursor::useIdleTime() { _cursorLocation = g_system->getEventManager()->getMousePos(); if (_index != -1 && _cursorObscured) show(); + ((PegasusEngine *)g_engine)->_gfx->markCursorAsDirty(); } } -- cgit v1.2.3 From 6550d851843d794f0b50185e1fdbb4f1108734a3 Mon Sep 17 00:00:00 2001 From: Matthew Hoops Date: Fri, 28 Oct 2011 13:26:43 -0400 Subject: PEGASUS: Fix 1bpp cicn cursors --- engines/pegasus/cursor.cpp | 32 +++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) (limited to 'engines/pegasus/cursor.cpp') diff --git a/engines/pegasus/cursor.cpp b/engines/pegasus/cursor.cpp index ee3ab87268..430b319e33 100755 --- a/engines/pegasus/cursor.cpp +++ b/engines/pegasus/cursor.cpp @@ -169,7 +169,7 @@ void Cursor::loadCursorImage(CursorInfo &cursorInfo) { cicnStream->readUint16BE(); // always 0 cursorInfo.colorCount = cicnStream->readUint16BE() + 1; - cursorInfo.palette = new byte[256 * cursorInfo.colorCount]; + cursorInfo.palette = new byte[cursorInfo.colorCount * 3]; for (uint16 i = 0; i < cursorInfo.colorCount; i++) { cicnStream->readUint16BE(); cursorInfo.palette[i * 3] = cicnStream->readUint16BE() >> 8; @@ -178,8 +178,34 @@ void Cursor::loadCursorImage(CursorInfo &cursorInfo) { } // PixMap data - cursorInfo.surface->create(pixMap.rowBytes, pixMap.bounds.height(), Graphics::PixelFormat::createFormatCLUT8()); - cicnStream->read(cursorInfo.surface->pixels, pixMap.rowBytes * pixMap.bounds.height()); + if (pixMap.pixelSize == 8) { + cursorInfo.surface->create(pixMap.rowBytes, pixMap.bounds.height(), Graphics::PixelFormat::createFormatCLUT8()); + cicnStream->read(cursorInfo.surface->pixels, pixMap.rowBytes * pixMap.bounds.height()); + + // While this looks sensible, it actually doesn't work for some cursors + // (ie. the 'can grab' hand) + //cursorInfo.surface->w = pixMap.bounds.width(); + } else if (pixMap.pixelSize == 1) { + cursorInfo.surface->create(pixMap.bounds.width(), pixMap.bounds.height(), Graphics::PixelFormat::createFormatCLUT8()); + + for (int y = 0; y < pixMap.bounds.height(); y++) { + byte *line = (byte *)cursorInfo.surface->getBasePtr(0, y); + + for (int x = 0; x < pixMap.bounds.width();) { + byte b = cicnStream->readByte(); + + for (int i = 0; i < 8; i++) { + *line++ = ((b & (1 << (7 - i))) != 0) ? 1 : 0; + + if (++x == pixMap.bounds.width()) + break; + } + } + } + } else { + error("Unhandled %dbpp cicn images", pixMap.pixelSize); + } + delete cicnStream; } -- cgit v1.2.3 From 983bd16bb78b1a6aa8872f2086dbcbca6954f2fb Mon Sep 17 00:00:00 2001 From: Matthew Hoops Date: Tue, 3 Apr 2012 15:23:08 -0400 Subject: PEGASUS: Fix file permissions --- engines/pegasus/cursor.cpp | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 engines/pegasus/cursor.cpp (limited to 'engines/pegasus/cursor.cpp') diff --git a/engines/pegasus/cursor.cpp b/engines/pegasus/cursor.cpp old mode 100755 new mode 100644 -- cgit v1.2.3 From 6ae0ff377894ea3188fc1f2c9ffc5c75a12907dd Mon Sep 17 00:00:00 2001 From: Matthew Hoops Date: Tue, 10 Apr 2012 14:47:16 -0400 Subject: PEGASUS: Mark the cursor as dirty when hiding it too --- engines/pegasus/cursor.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'engines/pegasus/cursor.cpp') diff --git a/engines/pegasus/cursor.cpp b/engines/pegasus/cursor.cpp index ea5fc74501..205336a00b 100644 --- a/engines/pegasus/cursor.cpp +++ b/engines/pegasus/cursor.cpp @@ -104,6 +104,7 @@ void Cursor::show() { void Cursor::hide() { CursorMan.showMouse(false); setCurrentFrameIndex(0); + ((PegasusEngine *)g_engine)->_gfx->markCursorAsDirty(); } void Cursor::hideUntilMoved() { -- cgit v1.2.3 From a6c6c74350bb673c178d9756a1625ca128d24f21 Mon Sep 17 00:00:00 2001 From: Johannes Schickel Date: Wed, 26 Sep 2012 04:10:32 +0200 Subject: PEGASUS: Remove trailing whitespaces. Powered by: git ls-files "*.cpp" "*.h" | xargs sed -i -e 's/[ \t]*$//' --- engines/pegasus/cursor.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'engines/pegasus/cursor.cpp') diff --git a/engines/pegasus/cursor.cpp b/engines/pegasus/cursor.cpp index 205336a00b..5babdf34af 100644 --- a/engines/pegasus/cursor.cpp +++ b/engines/pegasus/cursor.cpp @@ -142,10 +142,10 @@ void Cursor::loadCursorImage(CursorInfo &cursorInfo) { if (!cicnStream) error("Failed to find color icon %d", cursorInfo.tag); - + // PixMap section Graphics::PICTDecoder::PixMap pixMap = Graphics::PICTDecoder::readPixMap(*cicnStream); - + // Mask section cicnStream->readUint32BE(); // mask baseAddr uint16 maskRowBytes = cicnStream->readUint16BE(); // mask rowBytes @@ -159,17 +159,17 @@ void Cursor::loadCursorImage(CursorInfo &cursorInfo) { cicnStream->readUint16BE(); // left uint16 height = cicnStream->readUint16BE(); // bottom cicnStream->readUint16BE(); // right - + // Data section cicnStream->readUint32BE(); // icon handle cicnStream->skip(maskRowBytes * height); // FIXME: maskHeight doesn't work here, though the specs say it should cicnStream->skip(rowBytes * height); - + // Palette section cicnStream->readUint32BE(); // always 0 cicnStream->readUint16BE(); // always 0 cursorInfo.colorCount = cicnStream->readUint16BE() + 1; - + cursorInfo.palette = new byte[cursorInfo.colorCount * 3]; for (uint16 i = 0; i < cursorInfo.colorCount; i++) { cicnStream->readUint16BE(); @@ -177,7 +177,7 @@ void Cursor::loadCursorImage(CursorInfo &cursorInfo) { cursorInfo.palette[i * 3 + 1] = cicnStream->readUint16BE() >> 8; cursorInfo.palette[i * 3 + 2] = cicnStream->readUint16BE() >> 8; } - + // PixMap data if (pixMap.pixelSize == 8) { cursorInfo.surface->create(pixMap.rowBytes, pixMap.bounds.height(), Graphics::PixelFormat::createFormatCLUT8()); -- cgit v1.2.3