aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTorbjörn Andersson2006-05-25 22:51:42 +0000
committerTorbjörn Andersson2006-05-25 22:51:42 +0000
commit8062eb6ec33e32012da28f0cd06b8f9334c26937 (patch)
tree088c83206fbb0e4feea93ebeada0a505599572bb
parentd56c65bf4a47007dc874b70eb04be9ed7de27b01 (diff)
downloadscummvm-rg350-8062eb6ec33e32012da28f0cd06b8f9334c26937.tar.gz
scummvm-rg350-8062eb6ec33e32012da28f0cd06b8f9334c26937.tar.bz2
scummvm-rg350-8062eb6ec33e32012da28f0cd06b8f9334c26937.zip
Set and show/hide mouse cursors through a "cursor manager" (analogous to the
recently added (cursor) palette manager) so that the cursor can be properly restored after returning from the GUI. If there's any C++ magic that can keep the backend functions from being called by anything else than these managing classes, that would probably be a good idea. Also, since the cursor manager keeps a copy of the cursor image, perhaps there are at least some backends that will no longer need to? svn-id: r22639
-rw-r--r--engines/agi/agi.cpp4
-rw-r--r--engines/agi/graphics.cpp4
-rw-r--r--engines/cine/cine.cpp4
-rw-r--r--engines/cine/gfx.cpp4
-rw-r--r--engines/kyra/screen.cpp11
-rw-r--r--engines/lure/events.cpp9
-rw-r--r--engines/queen/display.cpp8
-rw-r--r--engines/saga/gfx.cpp7
-rw-r--r--engines/scumm/cursor.cpp3
-rw-r--r--engines/scumm/scumm.cpp4
-rw-r--r--engines/scumm/smush/smush_player.cpp6
-rw-r--r--engines/simon/animation.cpp4
-rw-r--r--engines/simon/cursor.cpp12
-rw-r--r--engines/sky/mouse.cpp7
-rw-r--r--engines/sword1/mouse.cpp10
-rw-r--r--engines/sword2/mouse.cpp12
-rw-r--r--graphics/cursorman.cpp108
-rw-r--r--graphics/cursorman.h120
-rw-r--r--graphics/module.mk1
-rw-r--r--gui/ThemeNew.cpp3
-rw-r--r--gui/newgui.cpp8
-rw-r--r--gui/newgui.h1
22 files changed, 303 insertions, 47 deletions
diff --git a/engines/agi/agi.cpp b/engines/agi/agi.cpp
index f03c403e0f..16aa3fa975 100644
--- a/engines/agi/agi.cpp
+++ b/engines/agi/agi.cpp
@@ -31,6 +31,8 @@
#include "backends/fs/fs.h"
+#include "graphics/cursorman.h"
+
#include "sound/mididrv.h"
#include "sound/mixer.h"
@@ -547,7 +549,7 @@ int AgiEngine::init() {
}
int AgiEngine::go() {
- _system->showMouse(true);
+ CursorMan.showMouse(true);
report(" \nAGI engine " VERSION " is ready.\n");
if (game.state < STATE_LOADED) {
diff --git a/engines/agi/graphics.cpp b/engines/agi/graphics.cpp
index c9fca743fd..3b9c754d97 100644
--- a/engines/agi/graphics.cpp
+++ b/engines/agi/graphics.cpp
@@ -24,6 +24,8 @@
#include "common/stdafx.h"
+#include "graphics/cursorman.h"
+
#include "agi/agi.h"
#include "agi/graphics.h"
@@ -428,7 +430,7 @@ int init_video() {
}
++src;
}
- g_system->setMouseCursor(mouseCursor, 16, 16, 1, 1);
+ CursorMan.replaceCursor(mouseCursor, 16, 16, 1, 1);
return err_OK;
}
diff --git a/engines/cine/cine.cpp b/engines/cine/cine.cpp
index cb61fbf1cd..644caecb6e 100644
--- a/engines/cine/cine.cpp
+++ b/engines/cine/cine.cpp
@@ -32,6 +32,8 @@
#include "backends/fs/fs.h"
+#include "graphics/cursorman.h"
+
#include "sound/mididrv.h"
#include "sound/mixer.h"
@@ -171,7 +173,7 @@ int CineEngine::init() {
}
int CineEngine::go() {
- _system->showMouse(true);
+ CursorMan.showMouse(true);
mainLoop(1);
diff --git a/engines/cine/gfx.cpp b/engines/cine/gfx.cpp
index 3c365e6e86..cc8f9ffe07 100644
--- a/engines/cine/gfx.cpp
+++ b/engines/cine/gfx.cpp
@@ -27,6 +27,8 @@
#include "common/system.h"
+#include "graphics/cursorman.h"
+
namespace Cine {
byte *screenBuffer;
@@ -116,7 +118,7 @@ void setMouseCursor(int cursor) {
}
++src;
}
- g_system->setMouseCursor(mouseCursor, 16, 16, mc->hotspotX, mc->hotspotY);
+ CursorMan.replaceCursor(mouseCursor, 16, 16, mc->hotspotX, mc->hotspotY);
currentMouseCursor = cursor;
}
}
diff --git a/engines/kyra/screen.cpp b/engines/kyra/screen.cpp
index 51687151af..d8a844c65e 100644
--- a/engines/kyra/screen.cpp
+++ b/engines/kyra/screen.cpp
@@ -23,6 +23,7 @@
#include "common/stdafx.h"
#include "common/endian.h"
#include "common/system.h"
+#include "graphics/cursorman.h"
#include "kyra/screen.h"
#include "kyra/kyra.h"
@@ -1834,7 +1835,7 @@ int Screen::getRectSize(int x, int y) {
void Screen::hideMouse() {
debugC(9, kDebugLevelScreen, "Screen::hideMouse()");
++_mouseLockCount;
- _system->showMouse(false);
+ CursorMan.showMouse(false);
}
void Screen::showMouse() {
@@ -1845,7 +1846,7 @@ void Screen::showMouse() {
// that the mouse cursor won't do a little dance catching
// up with the mouse movements when entering a new room.
_vm->delay(0);
- _system->showMouse(true);
+ CursorMan.showMouse(true);
}
if (_mouseLockCount > 0)
@@ -1879,10 +1880,10 @@ void Screen::setMouseCursor(int x, int y, byte *shape) {
fillRect(0, 0, mouseWidth, mouseHeight, 0, 8);
drawShape(8, shape, 0, 0, 0, 0);
- _system->showMouse(false);
+ CursorMan.showMouse(false);
copyRegionToBuffer(8, 0, 0, mouseWidth, mouseHeight, cursor);
- _system->setMouseCursor(cursor, mouseWidth, mouseHeight, x, y, 0);
- _system->showMouse(true);
+ CursorMan.replaceCursor(cursor, mouseWidth, mouseHeight, x, y, 0);
+ CursorMan.showMouse(true);
free(cursor);
// makes sure that the cursor is drawn
diff --git a/engines/lure/events.cpp b/engines/lure/events.cpp
index 660fb76693..30e393c1ee 100644
--- a/engines/lure/events.cpp
+++ b/engines/lure/events.cpp
@@ -20,6 +20,8 @@
*
*/
+#include "graphics/cursorman.h"
+
#include "lure/events.h"
#include "lure/system.h"
#include "lure/res.h"
@@ -70,11 +72,11 @@ void Mouse::handleEvent(OSystem::Event event) {
void Mouse::cursorOn() {
- System::getReference().showMouse(true);
+ CursorMan.showMouse(true);
}
void Mouse::cursorOff() {
- System::getReference().showMouse(false);
+ CursorMan.showMouse(false);
}
void Mouse::setCursorNum(uint8 cursorNum) {
@@ -89,11 +91,10 @@ void Mouse::setCursorNum(uint8 cursorNum) {
void Mouse::setCursorNum(uint8 cursorNum, int hotspotX, int hotspotY) {
Resources &res = Resources::getReference();
- OSystem &system = System::getReference();
_cursorNum = cursorNum;
byte *cursorAddr = res.getCursor(cursorNum);
- system.setMouseCursor(cursorAddr, CURSOR_WIDTH, CURSOR_HEIGHT, hotspotX, hotspotY, 0);
+ CursorMan.replaceCursor(cursorAddr, CURSOR_WIDTH, CURSOR_HEIGHT, hotspotX, hotspotY, 0);
}
void Mouse::setPosition(int newX, int newY) {
diff --git a/engines/queen/display.cpp b/engines/queen/display.cpp
index d66f7a6934..237c42e86e 100644
--- a/engines/queen/display.cpp
+++ b/engines/queen/display.cpp
@@ -22,8 +22,10 @@
#include "common/stdafx.h"
#include "common/system.h"
-#include "queen/display.h"
+#include "graphics/cursorman.h"
+
+#include "queen/display.h"
#include "queen/input.h"
#include "queen/logic.h"
#include "queen/queen.h"
@@ -780,11 +782,11 @@ void Display::setDirtyBlock(uint16 x, uint16 y, uint16 w, uint16 h) {
}
void Display::setMouseCursor(uint8 *buf, uint16 w, uint16 h) {
- _system->setMouseCursor(buf, w, h, 1, 1, 0);
+ CursorMan.replaceCursor(buf, w, h, 1, 1, 0);
}
void Display::showMouseCursor(bool show) {
- _system->showMouse(show);
+ CursorMan.showMouse(show);
}
void Display::initFont() {
diff --git a/engines/saga/gfx.cpp b/engines/saga/gfx.cpp
index b70b8c95f0..12b951d485 100644
--- a/engines/saga/gfx.cpp
+++ b/engines/saga/gfx.cpp
@@ -33,6 +33,7 @@
#include "saga/stream.h"
#include "common/system.h"
+#include "graphics/cursorman.h"
namespace Saga {
@@ -392,7 +393,7 @@ void Gfx::blackToPal(PalEntry *srcPal, double percent) {
}
void Gfx::showCursor(bool state) {
- g_system->showMouse(state);
+ CursorMan.showMouse(state);
}
void Gfx::setCursor(CursorType cursorType) {
@@ -411,7 +412,7 @@ void Gfx::setCursor(CursorType cursorType) {
0, 0, 0, A, 0, 0, 0,
};
- _system->setMouseCursor(cursor_img, CURSOR_W, CURSOR_H, 3, 3, 0);
+ CursorMan.replaceCursor(cursor_img, CURSOR_W, CURSOR_H, 3, 3, 0);
} else {
uint32 resourceId;
@@ -450,7 +451,7 @@ void Gfx::setCursor(CursorType cursorType) {
}
// Note: Hard-coded hotspot
- _system->setMouseCursor(image, width, height, 15, 15, 0);
+ CursorMan.replaceCursor(image, width, height, 15, 15, 0);
free(image);
free(resource);
diff --git a/engines/scumm/cursor.cpp b/engines/scumm/cursor.cpp
index 2e624144ad..2371ce860c 100644
--- a/engines/scumm/cursor.cpp
+++ b/engines/scumm/cursor.cpp
@@ -23,6 +23,7 @@
#include "common/stdafx.h"
#include "common/system.h"
#include "common/util.h"
+#include "graphics/cursorman.h"
#include "graphics/paletteman.h"
#include "scumm/bomp.h"
#include "scumm/charset.h"
@@ -102,7 +103,7 @@ void ScummEngine_v6::setCursorTransparency(int a) {
void ScummEngine::updateCursor() {
const int transColor = (_game.heversion >= 80) ? 5 : 255;
- _system->setMouseCursor(_grabbedCursor, _cursor.width, _cursor.height,
+ CursorMan.replaceCursor(_grabbedCursor, _cursor.width, _cursor.height,
_cursor.hotspotX, _cursor.hotspotY,
(_game.platform == Common::kPlatformNES ? _grabbedCursor[63] : transColor),
(_game.heversion == 70 ? 2 : 1));
diff --git a/engines/scumm/scumm.cpp b/engines/scumm/scumm.cpp
index 98dfb2c446..7704a0a2c1 100644
--- a/engines/scumm/scumm.cpp
+++ b/engines/scumm/scumm.cpp
@@ -32,6 +32,8 @@
#include "gui/message.h"
#include "gui/newgui.h"
+#include "graphics/cursorman.h"
+
#include "scumm/akos.h"
#include "scumm/charset.h"
#include "scumm/costume.h"
@@ -1787,7 +1789,7 @@ load_game:
animateCursor();
/* show or hide mouse */
- _system->showMouse(_cursor.state > 0);
+ CursorMan.showMouse(_cursor.state > 0);
#ifndef DISABLE_HE
if (_game.heversion >= 90) {
diff --git a/engines/scumm/smush/smush_player.cpp b/engines/scumm/smush/smush_player.cpp
index 76dc32284b..c7bb980985 100644
--- a/engines/scumm/smush/smush_player.cpp
+++ b/engines/scumm/smush/smush_player.cpp
@@ -30,6 +30,8 @@
#include "common/timer.h"
#include "common/util.h"
+#include "graphics/cursorman.h"
+
#include "scumm/bomp.h"
#include "scumm/file.h"
#include "scumm/imuse_digi/dimuse.h"
@@ -1304,7 +1306,7 @@ void SmushPlayer::play(const char *filename, int32 offset, int32 startFrame) {
_palDirtyMax = -1;
// Hide mouse
- bool oldMouseState = _vm->_system->showMouse(false);
+ bool oldMouseState = CursorMan.showMouse(false);
// Load the video
_seekFile = filename;
@@ -1379,7 +1381,7 @@ void SmushPlayer::play(const char *filename, int32 offset, int32 startFrame) {
release();
// Reset mouse state
- _vm->_system->showMouse(oldMouseState);
+ CursorMan.showMouse(oldMouseState);
}
} // End of namespace Scumm
diff --git a/engines/simon/animation.cpp b/engines/simon/animation.cpp
index 385c20473a..6bc3c813fd 100644
--- a/engines/simon/animation.cpp
+++ b/engines/simon/animation.cpp
@@ -26,6 +26,8 @@
#include "common/endian.h"
#include "common/system.h"
+#include "graphics/cursorman.h"
+
#include "simon/animation.h"
#include "simon/intern.h"
#include "simon/simon.h"
@@ -87,7 +89,7 @@ bool MoviePlayer::load(const char *filename) {
}
debug(0, "Playing video %s", filename2);
- _vm->_system->showMouse(false);
+ CursorMan.showMouse(false);
if ((_vm->getPlatform() == Common::kPlatformAmiga || _vm->getPlatform() == Common::kPlatformMacintosh) &&
_vm->_language != Common::EN_ANY) {
diff --git a/engines/simon/cursor.cpp b/engines/simon/cursor.cpp
index ff331e5390..d2d0df3d30 100644
--- a/engines/simon/cursor.cpp
+++ b/engines/simon/cursor.cpp
@@ -25,6 +25,8 @@
#include "common/system.h"
+#include "graphics/cursorman.h"
+
#include "simon/simon.h"
namespace Simon {
@@ -226,9 +228,9 @@ static const byte _simon2_cursors[10][256] = {
void SimonEngine::drawMousePointer() {
if (getGameType() == GType_SIMON2) {
- _system->setMouseCursor(_simon2_cursors[_mouseCursor], 16, 16, 7, 7);
+ CursorMan.replaceCursor(_simon2_cursors[_mouseCursor], 16, 16, 7, 7);
} else {
- _system->setMouseCursor(_simon1_cursor, 16, 16, 0, 0);
+ CursorMan.replaceCursor(_simon1_cursor, 16, 16, 0, 0);
}
}
@@ -236,11 +238,11 @@ void SimonEngine::handleMouseMoved() {
uint x;
if (_mouseHideCount) {
- _system->showMouse(false);
+ CursorMan.showMouse(false);
return;
}
- _system->showMouse(true);
+ CursorMan.showMouse(true);
pollMouseXY();
if (_mouseX <= 0)
@@ -433,7 +435,7 @@ void SimonEngine::drawMousePointer_FF() {
offs = cursor * 32 + _mouseAnim * 2;
drawMousePart(image, _mouseOffs[offs], _mouseOffs[offs + 1]);
- _system->setMouseCursor(_mouseData, kMaxCursorWidth, kMaxCursorHeight, 19, 19, 0);
+ CursorMan.replaceCursor(_mouseData, kMaxCursorWidth, kMaxCursorHeight, 19, 19, 0);
}
}
diff --git a/engines/sky/mouse.cpp b/engines/sky/mouse.cpp
index dd906b5b2d..d3a212a764 100644
--- a/engines/sky/mouse.cpp
+++ b/engines/sky/mouse.cpp
@@ -22,6 +22,7 @@
#include "common/stdafx.h"
#include "common/system.h"
+#include "graphics/cursorman.h"
#include "sky/disk.h"
#include "sky/logic.h"
#include "sky/mouse.h"
@@ -191,11 +192,11 @@ void Mouse::spriteMouse(uint16 frameNum, uint8 mouseX, uint8 mouseY) {
uint16 mouseWidth = ((struct dataFileHeader *)_miceData)->s_width;
uint16 mouseHeight = ((struct dataFileHeader *)_miceData)->s_height;
- _system->setMouseCursor(newCursor, mouseWidth, mouseHeight, mouseX, mouseY, 0);
+ CursorMan.replaceCursor(newCursor, mouseWidth, mouseHeight, mouseX, mouseY, 0);
if (frameNum == MOUSE_BLANK)
- _system->showMouse(false);
+ CursorMan.showMouse(false);
else
- _system->showMouse(true);
+ CursorMan.showMouse(true);
}
void Mouse::mouseEngine(uint16 mouseX, uint16 mouseY) {
diff --git a/engines/sword1/mouse.cpp b/engines/sword1/mouse.cpp
index 6b72d2238a..eefdf99466 100644
--- a/engines/sword1/mouse.cpp
+++ b/engines/sword1/mouse.cpp
@@ -24,6 +24,8 @@
#include "common/endian.h"
#include "common/system.h"
+#include "graphics/cursorman.h"
+
#include "sword1/mouse.h"
#include "sword1/menu.h"
#include "sword1/screen.h"
@@ -63,7 +65,7 @@ void Mouse::initialize(void) {
for (uint8 cnt = 0; cnt < 17; cnt++) // force res manager to keep mouse
_resMan->resOpen(MSE_POINTER + cnt); // cursors in memory all the time
- _system->showMouse(false);
+ CursorMan.showMouse(false);
createPointer(0, 0);
}
@@ -251,10 +253,10 @@ void Mouse::setPointer(uint32 resId, uint32 rate) {
createPointer(resId, _currentLuggageId);
if ((resId == 0) || (!(Logic::_scriptVars[MOUSE_STATUS] & 1) && (!_mouseOverride))) {
- _system->showMouse(false);
+ CursorMan.showMouse(false);
} else {
animate();
- _system->showMouse(true);
+ CursorMan.showMouse(true);
}
}
@@ -269,7 +271,7 @@ void Mouse::animate(void) {
_frame = (_frame + 1) % _currentPtr->numFrames;
uint8 *ptrData = (uint8*)_currentPtr + sizeof(MousePtr);
ptrData += _frame * _currentPtr->sizeX * _currentPtr->sizeY;
- _system->setMouseCursor(ptrData, _currentPtr->sizeX, _currentPtr->sizeY, _currentPtr->hotSpotX, _currentPtr->hotSpotY);
+ CursorMan.replaceCursor(ptrData, _currentPtr->sizeX, _currentPtr->sizeY, _currentPtr->hotSpotX, _currentPtr->hotSpotY);
}
}
diff --git a/engines/sword2/mouse.cpp b/engines/sword2/mouse.cpp
index 2aba77b15c..d17b98624e 100644
--- a/engines/sword2/mouse.cpp
+++ b/engines/sword2/mouse.cpp
@@ -22,6 +22,8 @@
#include "common/stdafx.h"
#include "common/system.h"
+#include "graphics/cursorman.h"
+
#include "sword2/sword2.h"
#include "sword2/console.h"
#include "sword2/controls.h"
@@ -1525,7 +1527,7 @@ void Mouse::drawMouse() {
decompressMouse(mouseData, _mouseAnim.data, _mouseFrame,
_mouseAnim.mousew, _mouseAnim.mouseh, mouse_width);
- _vm->_system->setMouseCursor(mouseData, mouse_width, mouse_height, hotspot_x, hotspot_y, 0);
+ CursorMan.replaceCursor(mouseData, mouse_width, mouse_height, hotspot_x, hotspot_y, 0);
free(mouseData);
}
@@ -1585,12 +1587,12 @@ int32 Mouse::setMouseAnim(byte *ma, int32 size, int32 mouseFlash) {
animateMouse();
drawMouse();
- _vm->_system->showMouse(true);
+ CursorMan.showMouse(true);
} else {
if (_luggageAnim.data)
drawMouse();
else
- _vm->_system->showMouse(false);
+ CursorMan.showMouse(false);
}
return RD_OK;
@@ -1626,12 +1628,12 @@ int32 Mouse::setLuggageAnim(byte *ma, int32 size) {
animateMouse();
drawMouse();
- _vm->_system->showMouse(true);
+ CursorMan.showMouse(true);
} else {
if (_mouseAnim.data)
drawMouse();
else
- _vm->_system->showMouse(false);
+ CursorMan.showMouse(false);
}
return RD_OK;
diff --git a/graphics/cursorman.cpp b/graphics/cursorman.cpp
new file mode 100644
index 0000000000..c1b8e38a92
--- /dev/null
+++ b/graphics/cursorman.cpp
@@ -0,0 +1,108 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ */
+
+#include "graphics/cursorman.h"
+
+#include "common/system.h"
+#include "common/stack.h"
+
+DECLARE_SINGLETON(Graphics::CursorManager);
+
+namespace Graphics {
+
+static bool g_initialized = false;
+
+CursorManager::CursorManager() {
+ if (!g_initialized) {
+ g_initialized = true;
+ _cursorStack.clear();
+ }
+}
+
+bool CursorManager::isVisible() {
+ if (_cursorStack.empty())
+ return false;
+ return _cursorStack.top()->_visible;
+}
+
+bool CursorManager::showMouse(bool visible) {
+ if (_cursorStack.empty())
+ return false;
+
+ _cursorStack.top()->_visible = visible;
+ return g_system->showMouse(visible);
+}
+
+void CursorManager::pushCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, byte keycolor, int targetScale) {
+ Cursor *cur = new Cursor(buf, w, h, hotspotX, hotspotY, keycolor, targetScale);
+
+ cur->_visible = isVisible();
+ _cursorStack.push(cur);
+
+ if (buf) {
+ g_system->setMouseCursor(cur->_data, w, h, hotspotX, hotspotY, keycolor, targetScale);
+ }
+}
+
+void CursorManager::popCursor() {
+ if (_cursorStack.empty())
+ return;
+
+ Cursor *cur = _cursorStack.pop();
+ delete cur;
+
+ if (!_cursorStack.empty()) {
+ cur = _cursorStack.top();
+ g_system->setMouseCursor(cur->_data, cur->_width, cur->_height, cur->_hotspotX, cur->_hotspotY, cur->_keycolor, cur->_targetScale);
+ }
+
+ g_system->showMouse(isVisible());
+}
+
+void CursorManager::replaceCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, byte keycolor, int targetScale) {
+ if (_cursorStack.empty()) {
+ pushCursor(buf, w, h, hotspotX, hotspotY, keycolor, targetScale);
+ return;
+ }
+
+ Cursor *cur = _cursorStack.top();
+ uint size = w * h;
+
+ if (cur->_size < size) {
+ delete cur->_data;
+ cur->_data = new byte[size];
+ cur->_size = size;
+ }
+
+ if (buf && cur->_data)
+ memcpy(cur->_data, buf, size);
+
+ cur->_width = w;
+ cur->_height = h;
+ cur->_hotspotX = hotspotX;
+ cur->_hotspotY = hotspotY;
+ cur->_keycolor = keycolor;
+ cur->_targetScale = targetScale;
+
+ g_system->setMouseCursor(cur->_data, w, h, hotspotX, hotspotY, keycolor, targetScale);
+}
+
+} // End of namespace Graphics
diff --git a/graphics/cursorman.h b/graphics/cursorman.h
new file mode 100644
index 0000000000..f86883f1e1
--- /dev/null
+++ b/graphics/cursorman.h
@@ -0,0 +1,120 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ */
+
+#ifndef GRAPHICS_CURSORMAN_H
+#define GRAPHICS_CURSORMAN_H
+
+#include "common/stdafx.h"
+#include "common/scummsys.h"
+#include "common/stack.h"
+#include "common/singleton.h"
+
+namespace Graphics {
+
+class CursorManager : public Common::Singleton<CursorManager> {
+public:
+ bool isVisible();
+ bool showMouse(bool visible);
+
+ /**
+ * Push a new cursor onto the stack, and set it in the backend. A local
+ * copy will be made of the cursor data, so the original buffer can be
+ * safely freed afterwards.
+ *
+ * @param buf the new cursor data
+ * @param w the width
+ * @param h the height
+ * @param hotspotX the hotspot X coordinate
+ * @param hotspotY the hotspot Y coordinate
+ * @param keycolor the index for the transparent color
+ * @param targetScale the scale for which the cursor is designed
+ *
+ * @note It is ok for the buffer to be a NULL pointer. It is sometimes
+ * useful to push a "dummy" cursor and modify it later. The
+ * cursor will be added to the stack, but not to the backend.
+ */
+ void pushCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, byte keycolor = 255, int targetScale = 1);
+
+ /**
+ * Pop a cursor from the stack, and restore the previous one to the
+ * backend. If there is no previous cursor, the cursor is hidden.
+ */
+ void popCursor();
+
+ /**
+ * Replace the current cursor on the stack. If the stack is empty, the
+ * cursor is pushed instead. It's a slightly more optimized way of
+ * popping the old cursor before pushing the new one.
+ *
+ * @param buf the new cursor data
+ * @param w the width
+ * @param h the height
+ * @param hotspotX the hotspot X coordinate
+ * @param hotspotY the hotspot Y coordinate
+ * @param keycolor the index for the transparent color
+ * @param targetScale the scale for which the cursor is designed
+ */
+ void replaceCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, byte keycolor = 255, int targetScale = 1);
+
+private:
+ friend class Common::Singleton<SingletonBaseType>;
+ CursorManager();
+
+ struct Cursor {
+ byte *_data;
+ bool _visible;
+ uint _width;
+ uint _height;
+ int _hotspotX;
+ int _hotspotY;
+ byte _keycolor;
+ byte _targetScale;
+
+ uint _size;
+
+ Cursor(const byte *data, uint w, uint h, int hotspotX, int hotspotY, byte keycolor = 255, int targetScale = 1) {
+ _size = w * h;
+ _data = new byte[_size];
+ if (data && _data)
+ memcpy(_data, data, _size);
+ _width = w;
+ _height = h;
+ _hotspotX = hotspotX;
+ _hotspotY = hotspotY;
+ _keycolor = keycolor;
+ _targetScale = targetScale;
+ }
+
+ ~Cursor() {
+ delete [] _data;
+ }
+ };
+
+ Common::Stack<Cursor *> _cursorStack;
+};
+
+
+} // End of namespace Graphics
+
+/** Shortcut for accessing the cursor manager. */
+#define CursorMan (::Graphics::CursorManager::instance())
+
+#endif
diff --git a/graphics/module.mk b/graphics/module.mk
index 1bf6536448..d5566996d7 100644
--- a/graphics/module.mk
+++ b/graphics/module.mk
@@ -2,6 +2,7 @@ MODULE := graphics
MODULE_OBJS := \
animation.o \
+ cursorman.o \
font.o \
fontman.o \
fonts/consolefont.o \
diff --git a/gui/ThemeNew.cpp b/gui/ThemeNew.cpp
index 0ff6b45fa4..ca50e5d11a 100644
--- a/gui/ThemeNew.cpp
+++ b/gui/ThemeNew.cpp
@@ -27,6 +27,7 @@
#include "graphics/imageman.h"
#include "graphics/imagedec.h"
#include "graphics/colormasks.h"
+#include "graphics/cursorman.h"
#include "graphics/paletteman.h"
#include "common/config-manager.h"
@@ -1549,7 +1550,7 @@ OverlayColor ThemeNew::calcDimColor(OverlayColor col) {
void ThemeNew::setUpCursor() {
PaletteMan.pushCursorPalette(_cursorPal, 0, MAX_CURS_COLORS);
- _system->setMouseCursor(_cursor, _cursorWidth, _cursorHeight, _cursorHotspotX, _cursorHotspotY, 255, _cursorTargetScale);
+ CursorMan.pushCursor(_cursor, _cursorWidth, _cursorHeight, _cursorHotspotX, _cursorHotspotY, 255, _cursorTargetScale);
}
void ThemeNew::createCursor() {
diff --git a/gui/newgui.cpp b/gui/newgui.cpp
index db45d94e3c..f0d58d8982 100644
--- a/gui/newgui.cpp
+++ b/gui/newgui.cpp
@@ -22,6 +22,7 @@
#include "common/stdafx.h"
#include "common/system.h"
#include "common/util.h"
+#include "graphics/cursorman.h"
#include "graphics/paletteman.h"
#include "gui/newgui.h"
#include "gui/dialog.h"
@@ -156,6 +157,7 @@ void NewGui::runLoop() {
};
PaletteMan.pushCursorPalette(palette, 0, 4);
+ CursorMan.pushCursor(NULL, 0, 0, 0, 0);
}
while (!_dialogStack.empty() && activeDialog == _dialogStack.top()) {
@@ -286,8 +288,6 @@ void NewGui::runLoop() {
void NewGui::saveState() {
// Backup old cursor
- _oldCursorMode = _system->showMouse(true);
-
_currentKeyDown.keycode = 0;
_lastClick.x = _lastClick.y = 0;
_lastClick.time = 0;
@@ -297,7 +297,7 @@ void NewGui::saveState() {
}
void NewGui::restoreState() {
- _system->showMouse(_oldCursorMode);
+ CursorMan.popCursor();
_system->updateScreen();
@@ -333,7 +333,7 @@ void NewGui::animateCursor() {
}
}
- _system->setMouseCursor(_cursor, 16, 16, 7, 7);
+ CursorMan.replaceCursor(_cursor, 16, 16, 7, 7);
_cursorAnimateTimer = time;
_cursorAnimateCounter = (_cursorAnimateCounter + 1) % 4;
diff --git a/gui/newgui.h b/gui/newgui.h
index 58bdf4715b..055f616131 100644
--- a/gui/newgui.h
+++ b/gui/newgui.h
@@ -107,7 +107,6 @@ protected:
} _lastClick;
// mouse cursor state
- bool _oldCursorMode;
int _cursorAnimateCounter;
int _cursorAnimateTimer;
byte _cursor[2048];