282 lines
6.5 KiB
C++
282 lines
6.5 KiB
C++
/* 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
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*
|
|
*/
|
|
|
|
#include "bagel/spacebar/baglib/sprite_object.h"
|
|
#include "bagel/spacebar/baglib/bagel.h"
|
|
#include "bagel/spacebar/baglib/master_win.h"
|
|
#include "bagel/spacebar/baglib/storage_dev_win.h"
|
|
|
|
namespace Bagel {
|
|
namespace SpaceBar {
|
|
|
|
CBagSpriteObject::CBagSpriteObject() : CBagObject() {
|
|
_xObjType = SPRITE_OBJ;
|
|
_xSprite = nullptr;
|
|
_nCels = 1;
|
|
_nWieldCursor = -1;
|
|
|
|
// Transparent by default
|
|
setTransparent();
|
|
CBagObject::setOverCursor(1);
|
|
setAnimated();
|
|
setTimeless(true);
|
|
|
|
// implement sprite framerates
|
|
setFrameRate(0);
|
|
_nLastUpdate = 0;
|
|
}
|
|
|
|
CBagSpriteObject::~CBagSpriteObject() {
|
|
CBagSpriteObject::detach();
|
|
}
|
|
|
|
ErrorCode CBagSpriteObject::attach() {
|
|
// If it's not already attached
|
|
if (!isAttached()) {
|
|
// Could not already have a sprite
|
|
assert(_xSprite == nullptr);
|
|
|
|
_xSprite = new CBofSprite();
|
|
|
|
if (_xSprite->loadSprite(getFileName(), getCels()) != false && (_xSprite->width() != 0) && (_xSprite->height() != 0)) {
|
|
if (isTransparent()) {
|
|
int nMaskColor = CBagel::getBagApp()->getChromaColor();
|
|
|
|
_xSprite->setMaskColor(nMaskColor);
|
|
}
|
|
|
|
// Set animated of the sprite to be the same as it's parent
|
|
_xSprite->setAnimated(isAnimated());
|
|
|
|
CBofPoint p = CBagObject::getPosition();
|
|
|
|
if (p.x == -1 && p.y == -1) // Fixed to allow for [0,0] positioning
|
|
setFloating();
|
|
else
|
|
_xSprite->setPosition(p.x, p.y);
|
|
|
|
setProperty("CURR_CEL", getState());
|
|
|
|
// This might add something to the PDA, make sure it gets redrawn.
|
|
CBagStorageDevWnd *pMainWin = (CBagel::getBagApp()->getMasterWnd()->getCurrentStorageDev());
|
|
|
|
if (pMainWin != nullptr) {
|
|
pMainWin->setPreFilterPan(true);
|
|
}
|
|
} else {
|
|
reportError(ERR_FOPEN, "Could Not Open Sprite: %s", _xSprite->getFileName());
|
|
}
|
|
}
|
|
|
|
return CBagObject::attach();
|
|
}
|
|
|
|
ErrorCode CBagSpriteObject::detach() {
|
|
delete _xSprite;
|
|
_xSprite = nullptr;
|
|
|
|
return CBagObject::detach();
|
|
}
|
|
|
|
void CBagSpriteObject::setCels(int nCels) {
|
|
_nCels = nCels;
|
|
if (_xSprite)
|
|
_xSprite->setupCels(nCels);
|
|
}
|
|
|
|
void CBagSpriteObject::setPosition(const CBofPoint &pos) {
|
|
CBagObject::setPosition(pos);
|
|
if (_xSprite)
|
|
_xSprite->setPosition(pos.x, pos.y);
|
|
}
|
|
|
|
CBofRect CBagSpriteObject::getRect() {
|
|
CBofPoint p = getPosition();
|
|
CBofSize s;
|
|
if (_xSprite)
|
|
s = _xSprite->getSize();
|
|
return CBofRect(p, s);
|
|
}
|
|
|
|
//
|
|
// Takes in info and then removes the relative information and returns the info
|
|
// without the relevant info.
|
|
ParseCodes CBagSpriteObject::setInfo(CBagIfstream &istr) {
|
|
bool nObjectUpdated = false;
|
|
|
|
while (!istr.eof()) {
|
|
istr.eatWhite(); // not sure why this WAS NOT here.
|
|
|
|
char ch = (char)istr.peek();
|
|
switch (ch) {
|
|
//
|
|
// +n - n number of slides in sprite
|
|
//
|
|
case '+': {
|
|
int cels;
|
|
istr.getCh();
|
|
getIntFromStream(istr, cels);
|
|
setCels(cels);
|
|
nObjectUpdated = true;
|
|
}
|
|
break;
|
|
case '#': {
|
|
int curs;
|
|
istr.getCh();
|
|
getIntFromStream(istr, curs);
|
|
setWieldCursor(curs);
|
|
nObjectUpdated = true;
|
|
}
|
|
break;
|
|
case 'N': {
|
|
// NOANIM
|
|
char szLocalStr[256];
|
|
szLocalStr[0] = 0;
|
|
CBofString sStr(szLocalStr, 256); // performance improvement
|
|
getAlphaNumFromStream(istr, sStr);
|
|
|
|
if (!sStr.find("NOANIM")) {
|
|
istr.eatWhite();
|
|
setAnimated(false);
|
|
nObjectUpdated = true;
|
|
} else {
|
|
putbackStringOnStream(istr, sStr);
|
|
}
|
|
}
|
|
break;
|
|
|
|
// handle a maximum framerate...
|
|
case 'F': {
|
|
// NOANIM
|
|
char szLocalStr[256];
|
|
szLocalStr[0] = 0;
|
|
CBofString sStr(szLocalStr, 256);
|
|
getAlphaNumFromStream(istr, sStr);
|
|
|
|
if (!sStr.find("FRAMERATE")) {
|
|
int nFrameRate;
|
|
istr.eatWhite();
|
|
getIntFromStream(istr, nFrameRate);
|
|
|
|
// The frame rate is expressed in frames/second, so do some division
|
|
// here to store the number of milliseconds.
|
|
setFrameRate(1000 / nFrameRate);
|
|
|
|
nObjectUpdated = true;
|
|
} else {
|
|
putbackStringOnStream(istr, sStr);
|
|
}
|
|
}
|
|
break;
|
|
//
|
|
// no match return from function
|
|
//
|
|
default: {
|
|
ParseCodes parseCode = CBagObject::setInfo(istr);
|
|
if (parseCode == PARSING_DONE) {
|
|
return PARSING_DONE;
|
|
}
|
|
|
|
if (parseCode == UPDATED_OBJECT) {
|
|
nObjectUpdated = true;
|
|
} else { // rc==UNKNOWN_TOKEN
|
|
if (nObjectUpdated)
|
|
return UPDATED_OBJECT;
|
|
|
|
return UNKNOWN_TOKEN;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
return PARSING_DONE;
|
|
}
|
|
|
|
ErrorCode CBagSpriteObject::update(CBofBitmap *pBmp, CBofPoint pt, CBofRect * /*pSrcRect*/, int) {
|
|
if (_xSprite) {
|
|
int nFrameInterval = getFrameRate();
|
|
|
|
if (nFrameInterval != 0) {
|
|
uint32 nCurTime = getTimer();
|
|
if (nCurTime > _nLastUpdate + nFrameInterval) {
|
|
_xSprite->setBlockAdvance(false);
|
|
_nLastUpdate = nCurTime;
|
|
} else {
|
|
_xSprite->setBlockAdvance(true);
|
|
}
|
|
}
|
|
|
|
bool bPaintResult = _xSprite->paintSprite(pBmp, pt.x, pt.y);
|
|
|
|
// Don't have to redraw this item...
|
|
// setDirty (false);
|
|
|
|
if (!bPaintResult)
|
|
return ERR_UNKNOWN;
|
|
}
|
|
return ERR_NONE;
|
|
}
|
|
|
|
bool CBagSpriteObject::isInside(const CBofPoint &xPoint) {
|
|
if (_xSprite && getRect().ptInRect(xPoint)) {
|
|
if (isTransparent()) {
|
|
int x = xPoint.x - getRect().left;
|
|
int y = xPoint.y - getRect().top;
|
|
int c = _xSprite->readPixel(x, y);
|
|
int d = _xSprite->getMaskColor();
|
|
return (c != d);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void CBagSpriteObject::setProperty(const CBofString &sProp, int nVal) {
|
|
if (!sProp.find("STATE") || !sProp.find("CURR_CEL")) {
|
|
setState(nVal);
|
|
if (_xSprite)
|
|
_xSprite->setCel(nVal);
|
|
} else
|
|
CBagObject::setProperty(sProp, nVal);
|
|
}
|
|
|
|
int CBagSpriteObject::getProperty(const CBofString &sProp) {
|
|
if (!sProp.find("CURR_CEL")) {
|
|
if (_xSprite) {
|
|
return _xSprite->getCelIndex();
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
return CBagObject::getProperty(sProp);
|
|
}
|
|
|
|
void CBagSpriteObject::setAnimated(bool b) {
|
|
_bAnimated = b;
|
|
if (_xSprite)
|
|
_xSprite->setAnimated(b);
|
|
}
|
|
|
|
} // namespace SpaceBar
|
|
} // namespace Bagel
|