scummvm/sword2/driver/_mouse.cpp
Torbjörn Andersson fc970b3c75 Removed the buffering of mouse and keyboard events. I don't think any of
our other engines do this, so there is little reason for BS2 to. I did add
a filtering mechanism so that mouse button releases and scroll wheeling is
ignored during normal gameplay, but I don't know if that was necessary
either.

Since this left little more than an empty husk where the Input class used
to be, I've eliminated that class and buried its remains in Sword2Engine.

svn-id: r13812
2004-05-09 13:32:04 +00:00

224 lines
5.4 KiB
C++

/* Copyright (C) 1994-2004 Revolution Software Ltd
*
* 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 "common/stdafx.h"
#include "sword2/sword2.h"
#include "sword2/driver/d_draw.h"
namespace Sword2 {
#define MOUSEFLASHFRAME 6
void Graphics::decompressMouse(byte *decomp, byte *comp, int width, int height, int pitch, int xOff, int yOff) {
int32 size = width * height;
int32 i = 0;
int x = 0;
int y = 0;
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 Graphics::drawMouse(void) {
byte mouseData[MAX_MOUSE_W * MAX_MOUSE_H];
if (!_mouseAnim && !_luggageAnim)
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) {
hotspot_x = _mouseAnim->xHotSpot;
hotspot_y = _mouseAnim->yHotSpot;
mouse_width = _mouseAnim->mousew;
mouse_height = _mouseAnim->mouseh;
}
if (_luggageAnim) {
if (!_mouseAnim) {
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 && _luggageAnim) {
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)
decompressMouse(mouseData, (byte *) _luggageAnim + READ_LE_UINT32(_luggageOffset), _luggageAnim->mousew,
_luggageAnim->mouseh, mouse_width, deltaX, deltaY);
if (_mouseAnim)
decompressMouse(mouseData, _mouseSprite, _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 Graphics::animateMouse(void) {
uint8 prevMouseFrame = _mouseFrame;
if (!_mouseAnim)
return RDERR_UNKNOWN;
if (++_mouseFrame == _mouseAnim->noAnimFrames)
_mouseFrame = MOUSEFLASHFRAME;
_mouseSprite = (byte *) _mouseAnim + READ_LE_UINT32(_mouseOffsets + _mouseFrame);
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 Graphics::setMouseAnim(byte *ma, int32 size, int32 mouseFlash) {
if (_mouseAnim) {
free(_mouseAnim);
_mouseAnim = NULL;
}
if (ma) {
if (mouseFlash == RDMOUSE_FLASH)
_mouseFrame = 0;
else
_mouseFrame = MOUSEFLASHFRAME;
_mouseAnim = (MouseAnim *) malloc(size);
if (!_mouseAnim)
return RDERR_OUTOFMEMORY;
memcpy((byte *) _mouseAnim, ma, size);
_mouseOffsets = (int32 *) ((byte *) _mouseAnim + sizeof(MouseAnim));
animateMouse();
drawMouse();
_vm->_system->showMouse(true);
} else {
if (_luggageAnim)
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 Graphics::setLuggageAnim(byte *ma, int32 size) {
if (_luggageAnim) {
free(_luggageAnim);
_luggageAnim = NULL;
}
if (ma) {
_luggageAnim = (MouseAnim *) malloc(size);
if (!_luggageAnim)
return RDERR_OUTOFMEMORY;
memcpy((byte *) _luggageAnim, ma, size);
_luggageOffset = (int32 *) ((byte *) _luggageAnim + sizeof(MouseAnim));
animateMouse();
drawMouse();
_vm->_system->showMouse(true);
} else {
if (_mouseAnim)
drawMouse();
else
_vm->_system->showMouse(false);
}
return RD_OK;
}
} // End of namespace Sword2