Initial commit
This commit is contained in:
385
engines/saga2/grabinfo.cpp
Normal file
385
engines/saga2/grabinfo.cpp
Normal file
@@ -0,0 +1,385 @@
|
||||
/* 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.
|
||||
*
|
||||
* 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 3 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
|
||||
* aint32 with this program; if not, write to the Free Software
|
||||
*
|
||||
*
|
||||
* Based on the original sources
|
||||
* Faery Tale II -- The Halls of the Dead
|
||||
* (c) 1993-1996 The Wyrmkeep Entertainment Co.
|
||||
*/
|
||||
|
||||
#include "saga2/saga2.h"
|
||||
#include "saga2/gdraw.h"
|
||||
#include "saga2/objects.h"
|
||||
#include "saga2/contain.h"
|
||||
#include "saga2/mouseimg.h"
|
||||
#include "saga2/grabinfo.h"
|
||||
|
||||
namespace Saga2 {
|
||||
|
||||
/* ===================================================================== *
|
||||
GrabInfo members
|
||||
* ===================================================================== */
|
||||
|
||||
|
||||
GrabInfo::GrabInfo() {
|
||||
_pointerMap._size.x = 0;
|
||||
_pointerMap._size.y = 0;
|
||||
_pointerMap._data = nullptr;
|
||||
|
||||
// null out the "held" object
|
||||
_grabId = Nothing;
|
||||
_grabObj = nullptr;
|
||||
_intentDoable = true;
|
||||
_intention = kIntWalkTo;
|
||||
|
||||
_textBuf[0] = '\0';
|
||||
_displayGauge = false;
|
||||
|
||||
_gaugeNumerator = _gaugeDenominator = 0;
|
||||
_moveCount = 1;
|
||||
}
|
||||
|
||||
GrabInfo::~GrabInfo() {
|
||||
if (_pointerMap._data != nullptr)
|
||||
delete[] _pointerMap._data;
|
||||
}
|
||||
|
||||
// set the move count based on val and whether the object is
|
||||
// mergeable or not.
|
||||
void GrabInfo::setMoveCount(int16 val) {
|
||||
if (_grabObj) {
|
||||
if (_grabObj->proto()->flags & ResourceObjectPrototype::kObjPropMergeable) {
|
||||
_moveCount = val;
|
||||
} else {
|
||||
_moveCount = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Make the object ID given into the mouse pointer
|
||||
void GrabInfo::grabObject(ObjectID objid, Intent in, int16 count) {
|
||||
GameObject *obj = GameObject::objectAddress(objid);
|
||||
grabObject(obj, in, count);
|
||||
}
|
||||
|
||||
|
||||
// Make the object pointer into the mouse pointer
|
||||
void GrabInfo::grabObject(GameObject *obj, Intent in, int16 count) {
|
||||
char objText[kBufSize];
|
||||
|
||||
assert(!obj->isMoving());
|
||||
|
||||
// set the number of items
|
||||
setMoveCount(count);
|
||||
|
||||
// Get address of object
|
||||
_grabObj = obj;
|
||||
_grabId = _grabObj->thisID();
|
||||
|
||||
// set the number of items
|
||||
setMoveCount(count);
|
||||
|
||||
// get the original location
|
||||
_from = _grabObj->getLocation();
|
||||
_from._context = _grabObj->IDParent();
|
||||
// de-link the object
|
||||
_grabObj->move(Location(Nowhere, Nothing));
|
||||
|
||||
setIcon();
|
||||
setIntent(in);
|
||||
|
||||
// Display the name of the grabbed object under the mouse cursor
|
||||
_grabObj->objCursorText(objText, kBufSize, _moveCount);
|
||||
setMouseText(objText);
|
||||
|
||||
clearMouseGauge();
|
||||
}
|
||||
|
||||
// this allows the mouse pointer to reference the original object
|
||||
// without removing it from the container/land
|
||||
// it does not actually copy it
|
||||
// Make the object ID given into the mouse pointer
|
||||
void GrabInfo::copyObject(ObjectID objid, Intent in, int16 count) {
|
||||
GameObject *obj = GameObject::objectAddress(objid);
|
||||
copyObject(obj, in, count);
|
||||
}
|
||||
|
||||
|
||||
// this allows the mouse pointer to reference the original object
|
||||
// without removing it from the container/land
|
||||
// it does not actually copy it
|
||||
// Make the object pointer into the mouse pointer
|
||||
void GrabInfo::copyObject(GameObject *obj, Intent in, int16 count) {
|
||||
char objText[kBufSize];
|
||||
|
||||
// set the number of items
|
||||
setMoveCount(count);
|
||||
|
||||
// Get address of object, and address of object prototype
|
||||
_grabObj = obj;
|
||||
_grabId = _grabObj->thisID();
|
||||
|
||||
// set the number of items
|
||||
setMoveCount(count);
|
||||
|
||||
_from = Nowhere;
|
||||
_from._context = Nothing;
|
||||
|
||||
setIcon();
|
||||
setIntent(in);
|
||||
|
||||
// Display the name of the grabbed object under the mouse cursor
|
||||
_grabObj->objCursorText(objText, kBufSize, _moveCount);
|
||||
setMouseText(objText);
|
||||
|
||||
clearMouseGauge();
|
||||
}
|
||||
|
||||
|
||||
// Set a new intention. All changes to intention must use this function.
|
||||
uint8 GrabInfo::setIntent(uint8 in) {
|
||||
// If intention isn't being changed, return immediately
|
||||
if (_intention != (Intent)in) {
|
||||
// Intention has changed to None
|
||||
if (in == (uint8)kIntNone && _intention != kIntNone) g_vm->_pointer->hide();
|
||||
// Intention has changed from None
|
||||
else if (in != (uint8)kIntNone && _intention == kIntNone) g_vm->_pointer->show();
|
||||
|
||||
_intention = (Intent)in;
|
||||
// Set new cursor
|
||||
setCursor();
|
||||
}
|
||||
|
||||
return in;
|
||||
}
|
||||
|
||||
|
||||
// Make the object given into the mouse pointer
|
||||
void GrabInfo::setIcon() {
|
||||
assert(
|
||||
_pointerMap._size.x == 0
|
||||
&& _pointerMap._size.y == 0
|
||||
&& _pointerMap._data == nullptr);
|
||||
|
||||
assert(_grabObj != nullptr && isObject(_grabObj));
|
||||
|
||||
Sprite *spr;
|
||||
ProtoObj *proto;
|
||||
ColorTable mainColors; // colors for object
|
||||
uint8 *mapData;
|
||||
int32 mapBytes;
|
||||
|
||||
// Get address of object, and address of object prototype
|
||||
proto = _grabObj->proto();
|
||||
|
||||
// Get address of sprite
|
||||
spr = proto->getSprite(_grabObj, ProtoObj::kObjAsMousePtr, _moveCount).sp;
|
||||
mapBytes = spr->size.x * spr->size.y;
|
||||
|
||||
if ((mapData
|
||||
= new uint8[mapBytes]())
|
||||
!= nullptr) {
|
||||
// Clear out the image data
|
||||
memset(mapData, 0, mapBytes);
|
||||
|
||||
// Build the current color table for the object
|
||||
_grabObj->getColorTranslation(mainColors);
|
||||
|
||||
_pointerMap._size = spr->size;
|
||||
_pointerMap._data = mapData;
|
||||
|
||||
_pointerOffset.x = - spr->size.x / 2;
|
||||
_pointerOffset.y = - spr->size.y / 2;
|
||||
|
||||
// Render the sprite into the bitmap
|
||||
ExpandColorMappedSprite(_pointerMap, spr, mainColors);
|
||||
} else
|
||||
error("Unable to allocate mouse image buffer");
|
||||
}
|
||||
|
||||
void GrabInfo::clearIcon() {
|
||||
assert(_grabObj == nullptr);
|
||||
|
||||
if (_pointerMap._data != nullptr) {
|
||||
delete[] _pointerMap._data;
|
||||
_pointerMap._size.x = 0;
|
||||
_pointerMap._size.y = 0;
|
||||
_pointerMap._data = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
// Changes cursor image to reflect the current state of the cursor based
|
||||
// on the _intention and _intentDoable data members.
|
||||
void GrabInfo::setCursor() {
|
||||
if (_intentDoable) {
|
||||
switch (_intention) {
|
||||
case kIntNone:
|
||||
// If _intention has been changed to none then the
|
||||
// pointer has already been hidden.
|
||||
break;
|
||||
case kIntWalkTo:
|
||||
setMouseImage(kMouseArrowImage, 0, 0);
|
||||
break;
|
||||
case kIntOpen:
|
||||
setMouseImage(kMouseArrowImage, 0, 0);
|
||||
break;
|
||||
case kIntPickUp:
|
||||
setMouseImage(kMouseGrabPtrImage, -7, -7);
|
||||
break;
|
||||
case kIntDrop:
|
||||
setMouseImage(_pointerMap, _pointerOffset.x, _pointerOffset.y);
|
||||
break;
|
||||
case kIntUse:
|
||||
setMouseImage(kMouseUsePtrImage, -7, -7);
|
||||
break;
|
||||
case kIntAttack:
|
||||
setMouseImage(kMouseAttakPtrImage, -11, -11);
|
||||
break;
|
||||
case kIntCast:
|
||||
setMouseImage(kMouseAttakPtrImage, -11, -11);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
// indicate current _intention is not doable
|
||||
setMouseImage(kMouseXPointerImage, -7, -7);
|
||||
}
|
||||
}
|
||||
|
||||
void GrabInfo::placeObject(const Location &loc) {
|
||||
_grabObj->move(loc);
|
||||
|
||||
// Turn off state variables
|
||||
_grabObj = nullptr;
|
||||
_grabId = Nothing;
|
||||
_intentDoable = true;
|
||||
setIntent(kIntWalkTo);
|
||||
clearIcon();
|
||||
|
||||
// Display the saved text
|
||||
setMouseText(_textBuf[0] != '\0' ? _textBuf : nullptr);
|
||||
|
||||
// Display the saved gauge data
|
||||
if (_displayGauge)
|
||||
setMouseGauge(_gaugeNumerator, _gaugeDenominator);
|
||||
else
|
||||
clearMouseGauge();
|
||||
}
|
||||
|
||||
// this should be use to return the object to the container
|
||||
// and/or remove the object from the cursor.
|
||||
void GrabInfo::replaceObject() {
|
||||
if (_grabObj == nullptr)
|
||||
return;
|
||||
|
||||
// if actually attached to cursor, replace
|
||||
if (_grabObj->IDParent() == Nothing) {
|
||||
// ContainerView *updateView;
|
||||
|
||||
_grabObj->move(_from);
|
||||
|
||||
// Update the ContainerView from which the object came
|
||||
// updateView = ContainerView::findPane( _grabObj->parent() );
|
||||
// if ( updateView != nullptr )
|
||||
// ( updateView->getWindow() )->update( updateView->getExtent() );
|
||||
}
|
||||
|
||||
// Turn off state variables
|
||||
_grabObj = nullptr;
|
||||
_grabId = Nothing;
|
||||
_intentDoable = true;
|
||||
setIntent(kIntWalkTo);
|
||||
clearIcon();
|
||||
|
||||
// Display the saved text
|
||||
setMouseText(_textBuf[0] != '\0' ? _textBuf : nullptr);
|
||||
|
||||
// Display the saved gauge data
|
||||
if (_displayGauge)
|
||||
setMouseGauge(_gaugeNumerator, _gaugeDenominator);
|
||||
else
|
||||
clearMouseGauge();
|
||||
}
|
||||
|
||||
|
||||
// This function is called to request a new mouse text string. If there
|
||||
// is currently no grabbed object the text will be displayed, else the
|
||||
// text pointer will simply be saved.
|
||||
void GrabInfo::setText(const char *txt) {
|
||||
if ((txt != nullptr) && strlen(txt)) {
|
||||
Common::strlcpy(_textBuf, txt, kBufSize);
|
||||
if (_grabObj == nullptr)
|
||||
setMouseText(_textBuf);
|
||||
} else {
|
||||
_textBuf[0] = '\0';
|
||||
if (_grabObj == nullptr)
|
||||
setMouseText(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
// request a change to the mouse gauge
|
||||
void GrabInfo::setGauge(int16 numerator, int16 denominator) {
|
||||
_displayGauge = true;
|
||||
_gaugeNumerator = numerator;
|
||||
_gaugeDenominator = denominator;
|
||||
if (_grabObj == nullptr)
|
||||
setMouseGauge(_gaugeNumerator, _gaugeDenominator);
|
||||
}
|
||||
|
||||
// clear the mouse gauge
|
||||
void GrabInfo::clearGauge() {
|
||||
_displayGauge = false;
|
||||
if (_grabObj == nullptr) clearMouseGauge();
|
||||
}
|
||||
|
||||
// FIXME: This code is specific to Dinotopia. Was disabled for some time and needs updating
|
||||
void cycleCursor() {
|
||||
#if 0
|
||||
if (! g_vm->_mouseInfo->cursorCyclingEnabled) // FIXME: cursorCyclingEnabled not present in GrabInfo
|
||||
return;
|
||||
|
||||
uint8 curIntent = g_vm->_mouseInfo->getIntent();
|
||||
if (++curIntent == GrabInfo::IntentCounts)
|
||||
g_vm->_mouseInfo->setIntent(1); //Set Cursor First State Skip None
|
||||
else {
|
||||
if (!walkEnabled && curIntent == GrabInfo::WalkTo) // FIXME: walkEnabled not present
|
||||
++curIntent;
|
||||
if (curIntent == GrabInfo::PickUp && g_vm->_mouseInfo->getObject() != nullptr)
|
||||
++curIntent;
|
||||
if (curIntent == GrabInfo::Drop && g_vm->_mouseInfo->getObject() == nullptr)
|
||||
++curIntent;
|
||||
if (!eyeEnabled && curIntent == GrabInfo::LookAt) // FIXME: eyeEnabled not present
|
||||
++curIntent;
|
||||
if (curIntent == GrabInfo::Navigate) {
|
||||
if (walkEnabled)
|
||||
curIntent = 1; //Set Cursor First State Skip None
|
||||
else {
|
||||
curIntent = 2;
|
||||
if (curIntent == GrabInfo::PickUp && g_vm->_mouseInfo->getObject() != nullptr)
|
||||
++curIntent;
|
||||
}
|
||||
}
|
||||
|
||||
g_vm->_mouseInfo->setIntent(curIntent); //Set Cursor To Next State
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
} // end of namespace Saga2
|
||||
Reference in New Issue
Block a user