aboutsummaryrefslogtreecommitdiff
path: root/engines/sword2/mouse.cpp
diff options
context:
space:
mode:
authorTorbjörn Andersson2006-02-12 21:41:34 +0000
committerTorbjörn Andersson2006-02-12 21:41:34 +0000
commit441ead453ad59680ceb34826904c8b753b23dee2 (patch)
tree493c78e497ea51ba2f124394ae8aa4819c4fd5c7 /engines/sword2/mouse.cpp
parentd1a5345169f36ea9f86ff3b0cf4cff8f911d5acf (diff)
downloadscummvm-rg350-441ead453ad59680ceb34826904c8b753b23dee2.tar.gz
scummvm-rg350-441ead453ad59680ceb34826904c8b753b23dee2.tar.bz2
scummvm-rg350-441ead453ad59680ceb34826904c8b753b23dee2.zip
Merged _mouse.cpp and mouse.cpp into mouse.cpp
svn-id: r20659
Diffstat (limited to 'engines/sword2/mouse.cpp')
-rw-r--r--engines/sword2/mouse.cpp217
1 files changed, 217 insertions, 0 deletions
diff --git a/engines/sword2/mouse.cpp b/engines/sword2/mouse.cpp
index 83a8b1faf2..81419c39e0 100644
--- a/engines/sword2/mouse.cpp
+++ b/engines/sword2/mouse.cpp
@@ -20,6 +20,8 @@
*/
#include "common/stdafx.h"
+#include "common/system.h"
+
#include "sword2/sword2.h"
#include "sword2/console.h"
#include "sword2/controls.h"
@@ -1434,4 +1436,219 @@ void Mouse::unpauseGame() {
setLuggage(_realLuggageItem);
}
+// This is the maximum mouse cursor size in the SDL backend
+#define MAX_MOUSE_W 80
+#define MAX_MOUSE_H 80
+
+#define MOUSEFLASHFRAME 6
+
+void Mouse::decompressMouse(byte *decomp, byte *comp, uint8 frame, int width, int height, int pitch, int xOff, int yOff) {
+ int32 size = width * height;
+ int32 i = 0;
+ int x = 0;
+ int y = 0;
+
+ comp = comp + READ_LE_UINT32(comp + frame * 4) - MOUSE_ANIM_HEADER_SIZE;
+
+ while (i < size) {
+ if (*comp > 183) {
+ decomp[(y + yOff) * pitch + x + xOff] = *comp++;
+ if (++x >= width) {
+ x = 0;
+ y++;
+ }
+ i++;
+ } else {
+ x += *comp;
+ while (x >= width) {
+ y++;
+ x -= width;
+ }
+ i += *comp++;
+ }
+ }
+}
+
+void Mouse::drawMouse() {
+ byte mouseData[MAX_MOUSE_W * MAX_MOUSE_H];
+
+ if (!_mouseAnim.data && !_luggageAnim.data)
+ return;
+
+ // When an object is used in the game, the mouse cursor should be a
+ // combination of a standard mouse cursor and a luggage cursor.
+ //
+ // However, judging by the original code luggage cursors can also
+ // appear on their own. I have no idea which cases though.
+
+ uint16 mouse_width = 0;
+ uint16 mouse_height = 0;
+ uint16 hotspot_x = 0;
+ uint16 hotspot_y = 0;
+ int deltaX = 0;
+ int deltaY = 0;
+
+ if (_mouseAnim.data) {
+ hotspot_x = _mouseAnim.xHotSpot;
+ hotspot_y = _mouseAnim.yHotSpot;
+ mouse_width = _mouseAnim.mousew;
+ mouse_height = _mouseAnim.mouseh;
+ }
+
+ if (_luggageAnim.data) {
+ if (!_mouseAnim.data) {
+ hotspot_x = _luggageAnim.xHotSpot;
+ hotspot_y = _luggageAnim.yHotSpot;
+ }
+ if (_luggageAnim.mousew > mouse_width)
+ mouse_width = _luggageAnim.mousew;
+ if (_luggageAnim.mouseh > mouse_height)
+ mouse_height = _luggageAnim.mouseh;
+ }
+
+ if (_mouseAnim.data && _luggageAnim.data) {
+ deltaX = _mouseAnim.xHotSpot - _luggageAnim.xHotSpot;
+ deltaY = _mouseAnim.yHotSpot - _luggageAnim.yHotSpot;
+ }
+
+ assert(deltaX >= 0);
+ assert(deltaY >= 0);
+
+ // HACK for maximum cursor size. (The SDL backend imposes this
+ // restriction)
+
+ if (mouse_width + deltaX > MAX_MOUSE_W)
+ deltaX = 80 - mouse_width;
+ if (mouse_height + deltaY > MAX_MOUSE_H)
+ deltaY = 80 - mouse_height;
+
+ mouse_width += deltaX;
+ mouse_height += deltaY;
+
+ if ((uint32)(mouse_width * mouse_height) > sizeof(mouseData)) {
+ warning("Mouse cursor too large");
+ return;
+ }
+
+ memset(mouseData, 0, mouse_width * mouse_height);
+
+ if (_luggageAnim.data)
+ decompressMouse(mouseData, _luggageAnim.data, 0,
+ _luggageAnim.mousew, _luggageAnim.mouseh,
+ mouse_width, deltaX, deltaY);
+
+ if (_mouseAnim.data)
+ decompressMouse(mouseData, _mouseAnim.data, _mouseFrame,
+ _mouseAnim.mousew, _mouseAnim.mouseh, mouse_width);
+
+ _vm->_system->setMouseCursor(mouseData, mouse_width, mouse_height, hotspot_x, hotspot_y, 0);
+}
+
+/**
+ * Animates the current mouse pointer
+ */
+
+int32 Mouse::animateMouse() {
+ uint8 prevMouseFrame = _mouseFrame;
+
+ if (!_mouseAnim.data)
+ return RDERR_UNKNOWN;
+
+ if (++_mouseFrame == _mouseAnim.noAnimFrames)
+ _mouseFrame = MOUSEFLASHFRAME;
+
+ if (_mouseFrame != prevMouseFrame)
+ drawMouse();
+
+ return RD_OK;
+}
+
+/**
+ * Sets the mouse cursor animation.
+ * @param ma a pointer to the animation data, or NULL to clear the current one
+ * @param size the size of the mouse animation data
+ * @param mouseFlash RDMOUSE_FLASH or RDMOUSE_NOFLASH, depending on whether
+ * or not there is a lead-in animation
+ */
+
+int32 Mouse::setMouseAnim(byte *ma, int32 size, int32 mouseFlash) {
+ free(_mouseAnim.data);
+ _mouseAnim.data = NULL;
+
+ if (ma) {
+ if (mouseFlash == RDMOUSE_FLASH)
+ _mouseFrame = 0;
+ else
+ _mouseFrame = MOUSEFLASHFRAME;
+
+ Common::MemoryReadStream readS(ma, size);
+
+ _mouseAnim.runTimeComp = readS.readByte();
+ _mouseAnim.noAnimFrames = readS.readByte();
+ _mouseAnim.xHotSpot = readS.readSByte();
+ _mouseAnim.yHotSpot = readS.readSByte();
+ _mouseAnim.mousew = readS.readByte();
+ _mouseAnim.mouseh = readS.readByte();
+
+ _mouseAnim.data = (byte *)malloc(size - MOUSE_ANIM_HEADER_SIZE);
+ if (!_mouseAnim.data)
+ return RDERR_OUTOFMEMORY;
+
+ readS.read(_mouseAnim.data, size - MOUSE_ANIM_HEADER_SIZE);
+
+ animateMouse();
+ drawMouse();
+
+ _vm->_system->showMouse(true);
+ } else {
+ if (_luggageAnim.data)
+ drawMouse();
+ else
+ _vm->_system->showMouse(false);
+ }
+
+ return RD_OK;
+}
+
+/**
+ * Sets the "luggage" animation to accompany the mouse animation. Luggage
+ * sprites are of the same format as mouse sprites.
+ * @param ma a pointer to the animation data, or NULL to clear the current one
+ * @param size the size of the animation data
+ */
+
+int32 Mouse::setLuggageAnim(byte *ma, int32 size) {
+ free(_luggageAnim.data);
+ _luggageAnim.data = NULL;
+
+ if (ma) {
+ Common::MemoryReadStream readS(ma, size);
+
+ _luggageAnim.runTimeComp = readS.readByte();
+ _luggageAnim.noAnimFrames = readS.readByte();
+ _luggageAnim.xHotSpot = readS.readSByte();
+ _luggageAnim.yHotSpot = readS.readSByte();
+ _luggageAnim.mousew = readS.readByte();
+ _luggageAnim.mouseh = readS.readByte();
+
+ _luggageAnim.data = (byte *)malloc(size - MOUSE_ANIM_HEADER_SIZE);
+ if (!_luggageAnim.data)
+ return RDERR_OUTOFMEMORY;
+
+ readS.read(_luggageAnim.data, size - MOUSE_ANIM_HEADER_SIZE);
+
+ animateMouse();
+ drawMouse();
+
+ _vm->_system->showMouse(true);
+ } else {
+ if (_mouseAnim.data)
+ drawMouse();
+ else
+ _vm->_system->showMouse(false);
+ }
+
+ return RD_OK;
+}
+
} // End of namespace Sword2