scummvm/scumm/sprite_he.cpp

1352 lines
40 KiB
C++
Raw Normal View History

/* ScummVM - Scumm Interpreter
* Copyright (C) 2001 Ludvig Strigeus
* Copyright (C) 2001-2005 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* $Header$
*
*/
#include "stdafx.h"
#include "scumm/intern.h"
#include "scumm/resource.h"
#include "scumm/scumm.h"
#include "scumm/sprite_he.h"
2005-04-02 14:24:43 +00:00
#include "scumm/usage_bits.h"
#include "scumm/wiz_he.h"
namespace Scumm {
void ScummEngine_v90he::allocateArrays() {
ScummEngine::allocateArrays();
spritesAllocTables(_numSprites, MAX(64, _numSprites / 4), 64);
}
void ScummEngine_v90he::getSpriteBounds(int spriteId, bool checkGroup, Common::Rect &bound) {
checkRange(_varNumSprites, 1, spriteId, "Invalid sprite %d");
int16 spr_wiz_x, spr_wiz_y;
int angle, zoom, x1, y1;
int32 w, h;
SpriteInfo *spi = &_spriteTable[spriteId];
loadImgSpot(spi->resId, spi->resState, spr_wiz_x, spr_wiz_y);
if (checkGroup && spi->groupNum) {
SpriteGroup *spg = &_spriteGroups[spi->groupNum];
if (spg->scaling) {
x1 = spi->tx * spg->scaleX - spr_wiz_x + spg->tx;
y1 = spi->ty * spg->scaleY - spr_wiz_y + spg->ty;
} else {
x1 = spi->tx - spr_wiz_x + spg->tx;
y1 = spi->ty - spr_wiz_y + spg->ty;
}
} else {
x1 = spi->tx - spr_wiz_x;
y1 = spi->ty - spr_wiz_y;
}
if (spi->resId) {
angle = spi->angle;
zoom = spi->zoom;
getWizImageDim(spi->resId, spi->resState, w, h);
if (!(spi->flags & (kSFZoomed | kSFRotated))) {
bound.left = x1;
bound.top = y1;
bound.right = x1 + w;
bound.bottom = y1 + h;
} else {
Common::Point pts[4];
pts[1].x = pts[2].x = w / 2 - 1;
pts[0].x = pts[0].y = pts[1].y = pts[3].x = -w / 2;
pts[2].y = pts[3].y = h / 2 - 1;
if ((spi->flags & kSFZoomed) && zoom) {
for (int j = 0; j < 4; ++j) {
pts[j].x = pts[j].x * zoom / 256;
pts[j].y = pts[j].y * zoom / 256;
}
}
if ((spi->flags & kSFRotated) && angle)
_wiz.polygonRotatePoints(pts, 4, angle);
for (int j = 0; j < 4; ++j) {
pts[j].x += x1;
pts[j].y += y1;
}
_wiz.polygonCalcBoundBox(pts, 4, bound);
}
} else {
bound.left = 1234;
bound.top = 1234;
bound.right = -1234;
bound.bottom = -1234;
}
}
//
// spriteInfoGet functions
//
int ScummEngine_v90he::findSpriteWithClassOf(int x_pos, int y_pos, int spriteGroupId, int type, int num, int *args) {
bool cond;
int code, classId, x, y;
debug(1, "findSprite: x %d, y %d, spriteGroup %d, type %d, num %d", x_pos, y_pos, spriteGroupId, type, num);
for (int i = (_numSpritesToProcess - 1); i >= 0; i--) {
SpriteInfo *spi = _activeSpritesTable[i];
if (!spi->curResId)
continue;
if (spriteGroupId && spi->groupNum != spriteGroupId)
continue;
cond = true;
for (int j = 0; j < num; j++) {
code = classId = args[j];
classId &= 0x7F;
checkRange(32, 1, classId, "class %d out of range in statement");
if (code & 0x80) {
if (!(spi->classFlags & (1 << (classId - 1))))
cond = 0;
} else {
if ((spi->classFlags & (1 << (classId - 1))))
cond = 0;
}
}
if (!cond)
continue;
if (type) {
if (spi->bbox.left > spi->bbox.right)
continue;
if (spi->bbox.top > spi->bbox.bottom)
continue;
if (spi->bbox.left > x_pos)
continue;
if (spi->bbox.top > y_pos)
continue;
if (spi->bbox.right < x_pos)
continue;
if (spi->bbox.bottom < y_pos)
continue;
return spi->id;
} else {
int resId, resState, angle, zoom;
int32 w, h;
resId = spi->curResId;
if (spi->field_80) {
int16 x1, x2, y1, y2;
resState = spi->curImageState / getWizImageStates(spi->field_80);
x = x_pos - spi->pos.x;
y = y_pos - spi->pos.y;
loadImgSpot(spi->curResId, resState, x1, y1);
loadImgSpot(spi->field_80, resState, x2, y2);
x += (x2 - x1);
y += (y2 - y1);
} else {
if (spi->bbox.left > spi->bbox.right)
continue;
if (spi->bbox.top > spi->bbox.bottom)
continue;
if (spi->bbox.left > x_pos)
continue;
if (spi->bbox.top > y_pos)
continue;
if (spi->bbox.right < x_pos)
continue;
if (spi->bbox.bottom < y_pos)
continue;
x = x_pos - spi->pos.x;
y = y_pos - spi->pos.y;
resState = spi->curImageState;
}
angle = spi->curAngle;
2005-03-06 04:31:02 +00:00
zoom = spi->cur_zoom;
if ((spi->flags & kSFZoomed) || (spi->flags & kSFRotated)) {
if (spi->flags & kSFZoomed && zoom) {
x = x * 256 / zoom;
y = y * 256 / zoom;
}
if (spi->flags & kSFRotated && angle) {
angle = (360 - angle) % 360;
Common::Point pts[1];
_wiz.polygonRotatePoints(pts, 1, angle);
}
getWizImageDim(resId, resState, w, h);
x += w / 2;
y += h / 2;
}
if(isWizPixelNonTransparent(resId, resState, x, y, spi->imgFlags))
return spi->id;
}
}
2005-02-22 01:25:53 +00:00
return 0;
}
int ScummEngine_v90he::spriteInfoGet_classFlags(int spriteId, int num, int *args) {
2005-02-22 01:25:53 +00:00
checkRange(_varNumSprites, 1, spriteId, "Invalid sprite %d");
int code, classId;
2005-02-24 08:26:58 +00:00
if (num == 0)
return _spriteTable[spriteId].classFlags;
for (int i = 0; i < num; i++) {
code = classId = args[i];
classId &= 0x7F;
2005-02-24 08:26:58 +00:00
checkRange(32, 1, classId, "class %d out of range in statement");
if (code & 0x80) {
if (!(_spriteTable[spriteId].classFlags & (1 << (classId - 1))))
return 0;
} else {
if ((_spriteTable[spriteId].classFlags & (1 << (classId - 1))))
return 0;
}
2005-02-23 12:04:42 +00:00
}
return 1;
2005-02-22 01:25:53 +00:00
}
2005-03-29 14:11:08 +00:00
int ScummEngine_v90he::spriteInfoGet_flagDoubleBuffered(int spriteId) {
2005-02-22 01:25:53 +00:00
checkRange(_varNumSprites, 1, spriteId, "Invalid sprite %d");
return ((_spriteTable[spriteId].flags & kSFDoubleBuffered) != 0) ? 1 : 0;
}
int ScummEngine_v90he::spriteInfoGet_flagYFlipped(int spriteId) {
2005-02-22 01:25:53 +00:00
checkRange(_varNumSprites, 1, spriteId, "Invalid sprite %d");
return ((_spriteTable[spriteId].flags & kSFYFlipped) != 0) ? 1 : 0;
}
int ScummEngine_v90he::spriteInfoGet_flagXFlipped(int spriteId) {
2005-02-22 01:25:53 +00:00
checkRange(_varNumSprites, 1, spriteId, "Invalid sprite %d");
return ((_spriteTable[spriteId].flags & kSFXFlipped) != 0) ? 1 : 0;
}
int ScummEngine_v90he::spriteInfoGet_flagActive(int spriteId) {
2005-02-22 01:25:53 +00:00
checkRange(_varNumSprites, 1, spriteId, "Invalid sprite %d");
return ((_spriteTable[spriteId].flags & kSFActive) != 0) ? 1 : 0;
}
2005-03-29 14:11:08 +00:00
int ScummEngine_v90he::spriteInfoGet_flagNeedPaletteRemap(int spriteId) {
2005-02-22 01:25:53 +00:00
checkRange(_varNumSprites, 1, spriteId, "Invalid sprite %d");
return ((_spriteTable[spriteId].flags & kSFNeedPaletteRemap) != 0) ? 1 : 0;
}
int ScummEngine_v90he::spriteInfoGet_flags_22(int spriteId) {
2005-02-22 01:25:53 +00:00
checkRange(_varNumSprites, 1, spriteId, "Invalid sprite %d");
return ((_spriteTable[spriteId].flags & kSFDelayed) != 0) ? 1 : 0;
}
int ScummEngine_v90he::spriteInfoGet_flagMarkDirty(int spriteId) {
2005-02-22 01:25:53 +00:00
checkRange(_varNumSprites, 1, spriteId, "Invalid sprite %d");
return ((_spriteTable[spriteId].flags & kSFMarkDirty) != 0) ? 1 : 0;
}
int ScummEngine_v90he::spriteInfoGet_flagHasImage(int spriteId) {
2005-02-22 01:25:53 +00:00
checkRange(_varNumSprites, 1, spriteId, "Invalid sprite %d");
return ((_spriteTable[spriteId].flags & kSFImageless) != 0) ? 1 : 0;
}
2005-02-21 00:34:00 +00:00
int ScummEngine_v90he::spriteInfoGet_resId(int spriteId) {
2005-02-22 01:25:53 +00:00
checkRange(_varNumSprites, 1, spriteId, "Invalid sprite %d");
return _spriteTable[spriteId].resId;
}
2005-02-21 00:34:00 +00:00
int ScummEngine_v90he::spriteInfoGet_resState(int spriteId) {
2005-02-22 01:25:53 +00:00
checkRange(_varNumSprites, 1, spriteId, "Invalid sprite %d");
return _spriteTable[spriteId].resState;
}
2005-02-21 00:34:00 +00:00
int ScummEngine_v90he::spriteInfoGet_groupNum(int spriteId) {
2005-02-22 01:25:53 +00:00
checkRange(_varNumSprites, 1, spriteId, "Invalid sprite %d");
return _spriteTable[spriteId].groupNum;
}
int ScummEngine_v90he::spriteInfoGet_paletteNum(int spriteId) {
2005-02-22 01:25:53 +00:00
checkRange(_varNumSprites, 1, spriteId, "Invalid sprite %d");
2005-02-21 04:53:34 +00:00
return _spriteTable[spriteId].paletteNum;
2005-02-21 04:53:34 +00:00
}
int ScummEngine_v90he::spriteInfoGet_zorderPriority(int spriteId) {
2005-02-22 01:25:53 +00:00
checkRange(_varNumSprites, 1, spriteId, "Invalid sprite %d");
return _spriteTable[spriteId].zorderPriority;
}
2005-02-21 00:34:00 +00:00
int ScummEngine_v90he::spriteInfoGet_grp_tx(int spriteId) {
2005-02-22 01:25:53 +00:00
checkRange(_varNumSprites, 1, spriteId, "Invalid sprite %d");
if (_spriteTable[spriteId].groupNum)
return _spriteTable[spriteId].tx + _spriteGroups[_spriteTable[spriteId].groupNum].tx;
else
2005-02-21 00:34:00 +00:00
return _spriteTable[spriteId].tx;
}
2005-02-21 00:34:00 +00:00
int ScummEngine_v90he::spriteInfoGet_grp_ty(int spriteId) {
2005-02-22 01:25:53 +00:00
checkRange(_varNumSprites, 1, spriteId, "Invalid sprite %d");
if (_spriteTable[spriteId].groupNum)
return _spriteTable[spriteId].ty + _spriteGroups[_spriteTable[spriteId].groupNum].ty;
else
2005-02-21 00:34:00 +00:00
return _spriteTable[spriteId].ty;
}
2005-02-21 00:34:00 +00:00
int ScummEngine_v90he::spriteInfoGet_field_44(int spriteId) {
2005-02-22 01:25:53 +00:00
checkRange(_varNumSprites, 1, spriteId, "Invalid sprite %d");
2005-02-21 00:34:00 +00:00
return _spriteTable[spriteId].field_44;
}
2005-02-21 00:34:00 +00:00
int ScummEngine_v90he::spriteInfoGet_field_54(int spriteId) {
2005-02-22 01:25:53 +00:00
checkRange(_varNumSprites, 1, spriteId, "Invalid sprite %d");
return _spriteTable[spriteId].xmapNum;
}
2005-02-21 00:34:00 +00:00
int ScummEngine_v90he::spriteInfoGet_wizSize(int spriteId) {
2005-02-22 01:25:53 +00:00
checkRange(_varNumSprites, 1, spriteId, "Invalid sprite %d");
2005-02-21 00:34:00 +00:00
return _spriteTable[spriteId].res_wiz_states;
}
2005-02-21 00:34:00 +00:00
int ScummEngine_v90he::spriteInfoGet_zoom(int spriteId) {
2005-02-22 01:25:53 +00:00
checkRange(_varNumSprites, 1, spriteId, "Invalid sprite %d");
2005-02-21 00:34:00 +00:00
return _spriteTable[spriteId].zoom;
}
int ScummEngine_v90he::spriteInfoGet_delayAmount(int spriteId) {
2005-02-22 01:25:53 +00:00
checkRange(_varNumSprites, 1, spriteId, "Invalid sprite %d");
return _spriteTable[spriteId].delayAmount;
}
2005-02-21 04:53:34 +00:00
int ScummEngine_v90he::spriteInfoGet_field_7C(int spriteId) {
2005-02-22 01:25:53 +00:00
checkRange(_varNumSprites, 1, spriteId, "Invalid sprite %d");
2005-02-21 04:53:34 +00:00
return _spriteTable[spriteId].field_7C;
}
2005-02-21 00:34:00 +00:00
int ScummEngine_v90he::spriteInfoGet_field_80(int spriteId) {
2005-02-22 01:25:53 +00:00
checkRange(_varNumSprites, 1, spriteId, "Invalid sprite %d");
2005-02-21 00:34:00 +00:00
return _spriteTable[spriteId].field_80;
}
int ScummEngine_v90he::spriteInfoGet_field_88(int spriteId, int type) {
checkRange(_varNumSprites, 1, spriteId, "Invalid sprite %d");
if (type == 0x7B)
return _spriteTable[spriteId].field_88;
else
return 0;
}
2005-02-21 00:34:00 +00:00
void ScummEngine_v90he::getSpriteImageDim(int spriteId, int32 &w, int32 &h) {
2005-02-22 01:25:53 +00:00
checkRange(_varNumSprites, 1, spriteId, "Invalid sprite %d");
2005-02-20 23:55:11 +00:00
if (_spriteTable[spriteId].resId) {
getWizImageDim(_spriteTable[spriteId].resId, _spriteTable[spriteId].resState, w, h);
} else {
w = 0;
h = 0;
}
2005-02-20 23:55:11 +00:00
}
2005-02-21 00:34:00 +00:00
void ScummEngine_v90he::spriteInfoGet_tx_ty(int spriteId, int32 &tx, int32 &ty) {
2005-02-22 01:25:53 +00:00
checkRange(_varNumSprites, 1, spriteId, "Invalid sprite %d");
2005-02-21 00:34:00 +00:00
tx = _spriteTable[spriteId].tx;
ty = _spriteTable[spriteId].ty;
}
2005-02-23 04:05:22 +00:00
void ScummEngine_v90he::spriteInfoGet_dx_dy(int spriteId, int32 &dx, int32 &dy) {
2005-02-22 01:25:53 +00:00
checkRange(_varNumSprites, 1, spriteId, "Invalid sprite %d");
2005-02-23 04:05:22 +00:00
dx = _spriteTable[spriteId].dx;
dy = _spriteTable[spriteId].dy;
}
//
// spriteGroupGet functions
//
2005-02-21 02:37:05 +00:00
int ScummEngine_v90he::spriteGroupGet_allocateGroupSpritesList(int spriteGroupId) {
int i, j = 0, sprites = 0;
checkRange(_varNumSpriteGroups, 1, spriteGroupId, "Invalid sprite group %d");
2005-02-21 02:37:05 +00:00
for (i = 1; i < _varNumSprites; i++) {
if (_spriteTable[i].groupNum == spriteGroupId)
sprites++;
}
if (!sprites)
return 0;
writeVar(0, 0);
defineArray(0, kDwordArray, 0, 0, 0, sprites);
writeArray(0, 0, 0, sprites);
for (i = (_varNumSprites - 1); i > 0; i--) {
if (_spriteTable[i].groupNum == spriteGroupId)
writeArray(0, 0, ++j, i);
}
return readVar(0);
2005-02-21 02:37:05 +00:00
}
int ScummEngine_v90he::spriteGroupGet_zorderPriority(int spriteGroupId) {
checkRange(_varNumSpriteGroups, 1, spriteGroupId, "Invalid sprite group %d");
return _spriteGroups[spriteGroupId].zorderPriority;
}
2005-02-21 02:37:05 +00:00
int ScummEngine_v90he::spriteGroupGet_field_20(int spriteGroupId) {
checkRange(_varNumSpriteGroups, 1, spriteGroupId, "Invalid sprite group %d");
return _spriteGroups[spriteGroupId].dstResNum;
}
int ScummEngine_v90he::spriteGroupGet_scale_x_ratio_mul(int spriteGroupId) {
checkRange(_varNumSpriteGroups, 1, spriteGroupId, "Invalid sprite group %d");
return _spriteGroups[spriteGroupId].scale_x_ratio_mul;
}
int ScummEngine_v90he::spriteGroupGet_scale_x_ratio_div(int spriteGroupId) {
checkRange(_varNumSpriteGroups, 1, spriteGroupId, "Invalid sprite group %d");
return _spriteGroups[spriteGroupId].scale_x_ratio_div;
}
int ScummEngine_v90he::spriteGroupGet_scale_y_ratio_mul(int spriteGroupId) {
checkRange(_varNumSpriteGroups, 1, spriteGroupId, "Invalid sprite group %d");
return _spriteGroups[spriteGroupId].scale_y_ratio_mul;
}
int ScummEngine_v90he::spriteGroupGet_scale_y_ratio_div(int spriteGroupId) {
checkRange(_varNumSpriteGroups, 1, spriteGroupId, "Invalid sprite group %d");
return _spriteGroups[spriteGroupId].scale_y_ratio_div;
}
2005-02-21 02:37:05 +00:00
void ScummEngine_v90he::spriteGroupGet_tx_ty(int spriteGroupId, int32 &tx, int32 &ty) {
checkRange(_varNumSpriteGroups, 1, spriteGroupId, "Invalid sprite group %d");
2005-02-21 02:37:05 +00:00
tx = _spriteGroups[spriteGroupId].tx;
ty = _spriteGroups[spriteGroupId].ty;
}
//
// spriteInfoSet functions
//
void ScummEngine_v90he::spriteInfoSet_paletteNum(int spriteId, int value) {
2005-02-21 00:34:00 +00:00
checkRange(_varNumSprites, 1, spriteId, "Invalid sprite %d");
if (_spriteTable[spriteId].paletteNum != value) {
_spriteTable[spriteId].paletteNum = value;
_spriteTable[spriteId].flags |= kSFChanged | kSFNeedRedraw;
}
}
2005-02-21 00:34:00 +00:00
void ScummEngine_v90he::spriteInfoSet_field_7C(int spriteId, int value) {
checkRange(_varNumSprites, 1, spriteId, "Invalid sprite %d");
2005-02-21 00:34:00 +00:00
if (_spriteTable[spriteId].field_7C != value) {
_spriteTable[spriteId].field_7C = value;
_spriteTable[spriteId].flags |= kSFChanged | kSFNeedRedraw;
}
}
2005-02-21 00:34:00 +00:00
void ScummEngine_v90he::spriteInfoSet_field_80(int spriteId, int value) {
checkRange(_varNumSprites, 1, spriteId, "Invalid sprite %d");
2005-02-21 00:34:00 +00:00
_spriteTable[spriteId].field_80 = value;
}
2005-02-26 01:39:52 +00:00
void ScummEngine_v90he::spriteInfoSet_resState(int spriteId, int state) {
2005-02-21 02:37:05 +00:00
checkRange(_varNumSprites, 1, spriteId, "Invalid sprite %d");
if (_spriteTable[spriteId].resId) {
2005-02-26 01:39:52 +00:00
int res_wiz_states = _spriteTable[spriteId].res_wiz_states - 1;
state = MAX(0, state);
state = MIN(state, res_wiz_states);
if (_spriteTable[spriteId].resState != state) {
_spriteTable[spriteId].resState = state;
_spriteTable[spriteId].flags |= kSFChanged | kSFNeedRedraw;
}
}
}
2005-02-21 02:37:05 +00:00
void ScummEngine_v90he::spriteInfoSet_tx_ty(int spriteId, int value1, int value2) {
checkRange(_varNumSprites, 1, spriteId, "Invalid sprite %d");
2005-02-21 02:37:05 +00:00
if (_spriteTable[spriteId].tx != value1 || _spriteTable[spriteId].ty != value2) {
_spriteTable[spriteId].tx = value1;
_spriteTable[spriteId].ty = value2;
_spriteTable[spriteId].flags |= kSFChanged | kSFNeedRedraw;
}
}
2005-02-21 02:37:05 +00:00
void ScummEngine_v90he::spriteInfoSet_groupNum(int spriteId, int value) {
checkRange(_varNumSprites, 1, spriteId, "Invalid sprite %d");
2005-02-21 12:43:18 +00:00
checkRange(_varNumSpriteGroups, 0, value, "Invalid sprite group %d");
_spriteTable[spriteId].groupNum = value;
_spriteTable[spriteId].flags |= kSFChanged | kSFNeedRedraw;
}
2005-02-23 04:05:22 +00:00
void ScummEngine_v90he::spriteInfoSet_dx_dy(int spriteId, int value1, int value2) {
2005-02-21 02:37:05 +00:00
checkRange(_varNumSprites, 1, spriteId, "Invalid sprite %d");
_spriteTable[spriteId].dx = value1;
_spriteTable[spriteId].dy = value2;
}
2005-02-21 02:37:05 +00:00
void ScummEngine_v90he::spriteInfoSet_field_54(int spriteId, int value) {
checkRange(_varNumSprites, 1, spriteId, "Invalid sprite %d");
_spriteTable[spriteId].xmapNum = value;
if (_spriteTable[spriteId].resId)
_spriteTable[spriteId].flags |= kSFChanged | kSFNeedRedraw;
}
2005-02-21 02:37:05 +00:00
void ScummEngine_v90he::spriteInfoSet_field_44(int spriteId, int value1, int value2) {
checkRange(_varNumSprites, 1, spriteId, "Invalid sprite %d");
2005-02-21 02:37:05 +00:00
_spriteTable[spriteId].field_44 = value2;
}
void ScummEngine_v90he::spriteInfoSet_zorderPriority(int spriteId, int value) {
2005-02-21 02:37:05 +00:00
checkRange(_varNumSprites, 1, spriteId, "Invalid sprite %d");
_spriteTable[spriteId].zorderPriority = value;
}
2005-02-21 02:37:05 +00:00
void ScummEngine_v90he::spriteInfoSet_Inc_tx_ty(int spriteId, int value1, int value2) {
checkRange(_varNumSprites, 1, spriteId, "Invalid sprite %d");
2005-02-21 02:37:05 +00:00
_spriteTable[spriteId].tx += value1;
_spriteTable[spriteId].ty += value2;
if (value1 || value2)
_spriteTable[spriteId].flags |= kSFChanged | kSFNeedRedraw;
}
2005-02-21 02:37:05 +00:00
void ScummEngine_v90he::spriteInfoSet_zoom(int spriteId, int value) {
checkRange(_varNumSprites, 1, spriteId, "Invalid sprite %d");
2005-02-21 02:37:05 +00:00
_spriteTable[spriteId].flags |= kSFZoomed;
2005-02-21 02:37:05 +00:00
if (_spriteTable[spriteId].zoom != value) {
_spriteTable[spriteId].zoom = value;
if (_spriteTable[spriteId].resId)
_spriteTable[spriteId].flags |= kSFChanged | kSFNeedRedraw;
}
}
2005-02-21 02:37:05 +00:00
void ScummEngine_v90he::spriteInfoSet_rotAngle(int spriteId, int value) {
checkRange(_varNumSprites, 1, spriteId, "Invalid sprite %d");
2005-02-21 02:37:05 +00:00
_spriteTable[spriteId].flags |= kSFRotated;
if (_spriteTable[spriteId].angle != value) {
_spriteTable[spriteId].angle = value;
if (_spriteTable[spriteId].resId)
_spriteTable[spriteId].flags |= kSFChanged | kSFNeedRedraw;
}
}
2005-03-29 14:11:08 +00:00
void ScummEngine_v90he::spriteInfoSet_flagDoubleBuffered(int spriteId, int value) {
2005-02-21 02:37:05 +00:00
checkRange(_varNumSprites, 1, spriteId, "Invalid sprite %d");
int oldFlags = _spriteTable[spriteId].flags;
if (value)
_spriteTable[spriteId].flags |= kSFDoubleBuffered;
else
_spriteTable[spriteId].flags &= ~kSFDoubleBuffered;
if (_spriteTable[spriteId].resId && _spriteTable[spriteId].flags != oldFlags)
_spriteTable[spriteId].flags |= kSFChanged | kSFNeedRedraw;
}
2005-03-17 09:42:31 +00:00
void ScummEngine_v90he::spriteInfoSet_flagYFlipped(int spriteId, int value) {
2005-02-21 02:37:05 +00:00
checkRange(_varNumSprites, 1, spriteId, "Invalid sprite %d");
int oldFlags = _spriteTable[spriteId].flags;
if (value)
_spriteTable[spriteId].flags |= kSFYFlipped;
else
_spriteTable[spriteId].flags &= ~kSFYFlipped;
if (_spriteTable[spriteId].resId && _spriteTable[spriteId].flags != oldFlags)
_spriteTable[spriteId].flags |= kSFChanged | kSFNeedRedraw;
}
2005-03-17 09:42:31 +00:00
void ScummEngine_v90he::spriteInfoSet_flagXFlipped(int spriteId, int value) {
2005-02-21 02:37:05 +00:00
checkRange(_varNumSprites, 1, spriteId, "Invalid sprite %d");
int oldFlags = _spriteTable[spriteId].flags;
if (value)
_spriteTable[spriteId].flags |= kSFXFlipped;
else
_spriteTable[spriteId].flags &= ~kSFXFlipped;
if (_spriteTable[spriteId].resId && _spriteTable[spriteId].flags != oldFlags)
_spriteTable[spriteId].flags |= kSFChanged | kSFNeedRedraw;
}
void ScummEngine_v90he::spriteInfoSet_flagActive(int spriteId, int value) {
2005-02-21 02:37:05 +00:00
checkRange(_varNumSprites, 1, spriteId, "Invalid sprite %d");
if (value)
_spriteTable[spriteId].flags |= kSFActive;
else
_spriteTable[spriteId].flags &= ~kSFActive;
}
2005-03-29 14:11:08 +00:00
void ScummEngine_v90he::spriteInfoSet_flagNeedPaletteRemap(int spriteId, int value) {
2005-02-21 02:37:05 +00:00
checkRange(_varNumSprites, 1, spriteId, "Invalid sprite %d");
int oldFlags = _spriteTable[spriteId].flags;
if (value)
_spriteTable[spriteId].flags |= kSFNeedPaletteRemap;
else
_spriteTable[spriteId].flags &= ~kSFNeedPaletteRemap;
if (_spriteTable[spriteId].resId && _spriteTable[spriteId].flags != oldFlags)
_spriteTable[spriteId].flags |= kSFChanged | kSFNeedRedraw;
}
2005-03-17 09:42:31 +00:00
void ScummEngine_v90he::spriteInfoSet_flag22(int spriteId, int value) {
2005-02-21 02:37:05 +00:00
checkRange(_varNumSprites, 1, spriteId, "Invalid sprite %d");
if (value)
_spriteTable[spriteId].flags |= kSFDelayed;
else
_spriteTable[spriteId].flags &= ~kSFDelayed;
}
void ScummEngine_v90he::spriteInfoSet_flagMarkDirty(int spriteId, int value) {
2005-02-21 02:37:05 +00:00
checkRange(_varNumSprites, 1, spriteId, "Invalid sprite %d");
if (value)
_spriteTable[spriteId].flags |= kSFMarkDirty | kSFBlitDirectly;
else
_spriteTable[spriteId].flags &= ~(kSFMarkDirty | kSFBlitDirectly);
}
void ScummEngine_v90he::spriteInfoSet_flagHasImage(int spriteId, int value) {
2005-02-21 02:37:05 +00:00
checkRange(_varNumSprites, 1, spriteId, "Invalid sprite %d");
// Note that condition is inverted
if (!value)
_spriteTable[spriteId].flags |= kSFImageless;
else
_spriteTable[spriteId].flags &= ~kSFImageless;
}
void ScummEngine_v90he::spriteInfoSet_delay(int spriteId, int value) {
2005-02-21 02:37:05 +00:00
checkRange(_varNumSprites, 1, spriteId, "Invalid sprite %d");
_spriteTable[spriteId].delayAmount = value;
_spriteTable[spriteId].delayCount = value;
}
2005-02-23 11:15:41 +00:00
void ScummEngine_v90he::spriteInfoSet_setClassFlags(int spriteId, int value) {
checkRange(_varNumSprites, 1, spriteId, "Invalid sprite %d");
_spriteTable[spriteId].classFlags = value;
2005-02-23 11:15:41 +00:00
}
void ScummEngine_v90he::spriteInfoSet_setClassFlag(int spriteId, int classId, int toggle) {
2005-02-22 22:23:10 +00:00
checkRange(_varNumSprites, 1, spriteId, "Invalid sprite %d");
checkRange(32, 1, classId, "class %d out of range in statement");
if (toggle) {
_spriteTable[spriteId].classFlags |= (1 << (classId - 1));
2005-02-22 22:23:10 +00:00
} else {
_spriteTable[spriteId].classFlags &= ~(1 << (classId - 1));
2005-02-22 22:23:10 +00:00
}
}
void ScummEngine_v90he::spriteInfoSet_resetClassFlags(int spriteId) {
2005-02-22 22:23:10 +00:00
checkRange(_varNumSprites, 1, spriteId, "Invalid sprite %d");
_spriteTable[spriteId].classFlags = 0;
2005-02-22 22:23:10 +00:00
}
void ScummEngine_v90he::spriteInfoSet_field_88(int spriteId, int type, int value) {
checkRange(_varNumSprites, 1, spriteId, "Invalid sprite %d");
if (type == 0x7B) {
_spriteTable[spriteId].field_88 = value;
_spriteTable[spriteId].flags |= kSFChanged | kSFNeedRedraw;
}
}
void ScummEngine_v90he::spriteInfoSet_resetSprite(int spriteId) {
2005-02-21 02:37:05 +00:00
checkRange(_varNumSprites, 1, spriteId, "Invalid sprite %d");
_spriteTable[spriteId].angle = 0;
_spriteTable[spriteId].zoom = 0;
int tmp = 0;
spriteAddImageToList(spriteId, 1, &tmp);
_spriteTable[spriteId].xmapNum = 0;
_spriteTable[spriteId].tx = 0;
_spriteTable[spriteId].ty = 0;
_spriteTable[spriteId].flags &= ~(kSFYFlipped | kSFXFlipped);
_spriteTable[spriteId].flags |= kSFChanged | kSFNeedRedraw;
_spriteTable[spriteId].dx = 0;
_spriteTable[spriteId].dy = 0;
_spriteTable[spriteId].field_44 = 0;
_spriteTable[spriteId].groupNum = 0;
_spriteTable[spriteId].delayAmount = 0;
_spriteTable[spriteId].delayCount = 0;
_spriteTable[spriteId].classFlags = 0;
_spriteTable[spriteId].paletteNum = 0;
_spriteTable[spriteId].field_7C = 0;
_spriteTable[spriteId].field_80 = 0;
_spriteTable[spriteId].zorderPriority = 0;
_spriteTable[spriteId].field_88 = 0;
}
void ScummEngine_v90he::spriteAddImageToList(int spriteId, int imageNum, int *spriteIdptr) {
2005-02-25 02:07:22 +00:00
int origResId, origResWizStates;
checkRange(_varNumSprites, 1, spriteId, "Invalid sprite %d");
origResId = _spriteTable[spriteId].resId;
2005-02-25 02:07:22 +00:00
origResWizStates = _spriteTable[spriteId].res_wiz_states;
_spriteTable[spriteId].resId = *spriteIdptr;
_spriteTable[spriteId].field_74 = 0;
_spriteTable[spriteId].resState = 0;
if (_spriteTable[spriteId].resId) {
_spriteTable[spriteId].res_wiz_states = getWizImageStates(_spriteTable[spriteId].resId);
_spriteTable[spriteId].flags |= kSFActive | kSFDelayed | kSFMarkDirty | kSFBlitDirectly;
if (_spriteTable[spriteId].resId != origResId || _spriteTable[spriteId].res_wiz_states != origResWizStates)
2005-02-28 04:34:22 +00:00
_spriteTable[spriteId].flags |= kSFChanged | kSFNeedRedraw;
} else {
if (_spriteTable[spriteId].flags & kSFImageless)
_spriteTable[spriteId].flags = 0;
else
_spriteTable[spriteId].flags = kSFChanged | kSFBlitDirectly;
_spriteTable[spriteId].curResId = 0;
_spriteTable[spriteId].curImageState = 0;
_spriteTable[spriteId].res_wiz_states = 0;
}
}
//
// spriteGroupSet functions
//
2005-02-23 04:35:20 +00:00
void ScummEngine_v90he::redrawSpriteGroup(int spriteGroupId) {
for (int i = 0; i < _numSpritesToProcess; ++i) {
SpriteInfo *spi = _activeSpritesTable[i];
if (spi->groupNum == spriteGroupId) {
spi->flags |= kSFChanged | kSFNeedRedraw;
2005-02-23 04:35:20 +00:00
}
}
}
void ScummEngine_v90he::spriteGroupSet_case0_0(int spriteGroupId, int value1, int value2) {
checkRange(_varNumSpriteGroups, 1, spriteGroupId, "Invalid sprite group %d");
for (int i = 1; i < _varNumSprites; i++) {
if (_spriteTable[i].groupNum == spriteGroupId) {
_spriteTable[i].tx += value1;
_spriteTable[i].ty += value2;
if (value1 || value2)
_spriteTable[i].flags |= kSFChanged | kSFNeedRedraw;
}
}
}
void ScummEngine_v90he::spriteGroupSet_case0_1(int spriteGroupId, int value) {
checkRange(_varNumSpriteGroups, 1, spriteGroupId, "Invalid sprite group %d");
for (int i = 1; i < _varNumSprites; i++) {
if (_spriteTable[i].groupNum == spriteGroupId)
_spriteTable[i].zorderPriority = value;
}
}
void ScummEngine_v90he::spriteGroupSet_case0_2(int spriteGroupId, int value) {
checkRange(_varNumSpriteGroups, 1, spriteGroupId, "Invalid sprite group %d");
for (int i = 1; i < _varNumSprites; i++) {
if (_spriteTable[i].groupNum == spriteGroupId) {
_spriteTable[i].groupNum = value;
_spriteTable[i].flags |= kSFChanged | kSFNeedRedraw;
}
}
}
void ScummEngine_v90he::spriteGroupSet_case0_3(int spriteGroupId, int value) {
checkRange(_varNumSpriteGroups, 1, spriteGroupId, "Invalid sprite group %d");
for (int i = 1; i < _varNumSprites; i++) {
if (_spriteTable[i].groupNum == spriteGroupId) {
if (value)
_spriteTable[i].flags |= kSFMarkDirty | kSFBlitDirectly;
else
_spriteTable[i].flags &= ~(kSFMarkDirty | kSFBlitDirectly);
}
}
}
void ScummEngine_v90he::spriteGroupSet_case0_4(int spriteGroupId) {
checkRange(_varNumSpriteGroups, 1, spriteGroupId, "Invalid sprite group %d");
2005-02-23 04:05:22 +00:00
for (int i = 1; i < _varNumSprites; i++) {
if (_spriteTable[i].groupNum == spriteGroupId)
2005-02-23 04:05:22 +00:00
spriteInfoSet_resetSprite(i);
}
}
void ScummEngine_v90he::spriteGroupSet_case0_5(int spriteGroupId, int value) {
checkRange(_varNumSpriteGroups, 1, spriteGroupId, "Invalid sprite group %d");
for (int i = 1; i < _varNumSprites; i++) {
if (_spriteTable[i].groupNum == spriteGroupId) {
_spriteTable[i].delayAmount = value;
_spriteTable[i].delayCount = value;
}
}
}
void ScummEngine_v90he::spriteGroupSet_case0_6(int spriteGroupId, int value) {
checkRange(_varNumSpriteGroups, 1, spriteGroupId, "Invalid sprite group %d");
for (int i = 1; i < _varNumSprites; i++) {
if (_spriteTable[i].groupNum == spriteGroupId) {
if (value)
_spriteTable[i].flags |= kSFDelayed;
else
_spriteTable[i].flags &= ~kSFDelayed;
}
}
}
void ScummEngine_v90he::spriteGroupSet_case0_7(int spriteGroupId, int value) {
checkRange(_varNumSpriteGroups, 1, spriteGroupId, "Invalid sprite group %d");
for (int i = 1; i < _varNumSprites; i++) {
if (_spriteTable[i].groupNum == spriteGroupId) {
_spriteTable[i].xmapNum = value;
if (_spriteTable[i].resId)
_spriteTable[i].flags |= kSFChanged | kSFNeedRedraw;
}
}
}
2005-02-28 04:17:17 +00:00
void ScummEngine_v90he::spriteGroupSet_bbox(int spriteGroupId, int x1, int y1, int x2, int y2) {
checkRange(_varNumSpriteGroups, 1, spriteGroupId, "Invalid sprite group %d");
2005-02-23 04:05:22 +00:00
2005-02-28 04:17:17 +00:00
_spriteGroups[spriteGroupId].flags |= kSGFClipBox;
_spriteGroups[spriteGroupId].bbox.left = x1;
_spriteGroups[spriteGroupId].bbox.top = y1;
_spriteGroups[spriteGroupId].bbox.right = x2;
_spriteGroups[spriteGroupId].bbox.bottom = y2;
2005-02-23 04:05:22 +00:00
2005-02-23 04:35:20 +00:00
redrawSpriteGroup(spriteGroupId);
}
2005-02-28 04:17:17 +00:00
void ScummEngine_v90he::spriteGroupSet_zorderPriority(int spriteGroupId, int value) {
checkRange(_varNumSpriteGroups, 1, spriteGroupId, "Invalid sprite group %d");
2005-02-23 04:05:22 +00:00
2005-02-28 04:34:22 +00:00
if (_spriteGroups[spriteGroupId].zorderPriority != value) {
_spriteGroups[spriteGroupId].zorderPriority = value;
redrawSpriteGroup(spriteGroupId);
}
}
2005-02-28 04:17:17 +00:00
void ScummEngine_v90he::spriteGroupSet_tx_ty(int spriteGroupId, int value1, int value2) {
checkRange(_varNumSpriteGroups, 1, spriteGroupId, "Invalid sprite group %d");
2005-02-23 04:05:22 +00:00
2005-02-28 04:34:22 +00:00
if (_spriteGroups[spriteGroupId].tx != value1 || _spriteGroups[spriteGroupId].ty != value2) {
_spriteGroups[spriteGroupId].tx = value1;
_spriteGroups[spriteGroupId].ty = value2;
redrawSpriteGroup(spriteGroupId);
}
}
2005-02-28 04:17:17 +00:00
void ScummEngine_v90he::spriteGroupSet_inc_tx_ty(int spriteGroupId, int value1, int value2) {
checkRange(_varNumSpriteGroups, 1, spriteGroupId, "Invalid sprite group %d");
2005-02-23 04:05:22 +00:00
if (value1 || value2) {
_spriteGroups[spriteGroupId].tx += value1;
_spriteGroups[spriteGroupId].ty += value2;
redrawSpriteGroup(spriteGroupId);
}
}
2005-02-28 04:17:17 +00:00
void ScummEngine_v90he::spriteGroupSet_field_20(int spriteGroupId, int value) {
checkRange(_varNumSpriteGroups, 1, spriteGroupId, "Invalid sprite group %d");
if (_spriteGroups[spriteGroupId].dstResNum != value) {
_spriteGroups[spriteGroupId].dstResNum = value;
2005-02-28 04:34:22 +00:00
redrawSpriteGroup(spriteGroupId);
}
}
2005-02-28 04:34:22 +00:00
void ScummEngine_v90he::spriteGroupSet_scaling(int spriteGroupId) {
2005-02-28 04:17:17 +00:00
if ((_spriteGroups[spriteGroupId].scale_x_ratio_mul != _spriteGroups[spriteGroupId].scale_x_ratio_div) || (_spriteGroups[spriteGroupId].scale_y_ratio_mul != _spriteGroups[spriteGroupId].scale_y_ratio_div))
_spriteGroups[spriteGroupId].scaling = 1;
else
_spriteGroups[spriteGroupId].scaling = 0;
}
2005-02-28 04:34:22 +00:00
void ScummEngine_v90he::spriteGroupSet_scale_x_ratio_mul(int spriteGroupId, int value) {
checkRange(_varNumSpriteGroups, 1, spriteGroupId, "Invalid sprite group %d");
2005-02-28 04:34:22 +00:00
if (_spriteGroups[spriteGroupId].scale_x_ratio_mul != value) {
_spriteGroups[spriteGroupId].scale_x_ratio_mul = value;
_spriteGroups[spriteGroupId].scaleX = _spriteGroups[spriteGroupId].scale_x_ratio_mul / _spriteGroups[spriteGroupId].scale_x_ratio_div;
2005-02-28 04:34:22 +00:00
spriteGroupSet_scaling(spriteGroupId);
redrawSpriteGroup(spriteGroupId);
}
}
2005-02-28 04:34:22 +00:00
void ScummEngine_v90he::spriteGroupSet_scale_x_ratio_div(int spriteGroupId, int value) {
checkRange(_varNumSpriteGroups, 1, spriteGroupId, "Invalid sprite group %d");
2005-02-28 04:17:17 +00:00
if (value == 0)
error("spriteGroupSet_scale_x_ratio_div: Divisor must not be 0");
2005-02-28 04:34:22 +00:00
if (_spriteGroups[spriteGroupId].scale_x_ratio_div != value) {
_spriteGroups[spriteGroupId].scale_x_ratio_div = value;
_spriteGroups[spriteGroupId].scaleX = _spriteGroups[spriteGroupId].scale_x_ratio_mul / _spriteGroups[spriteGroupId].scale_x_ratio_div;
2005-02-28 04:34:22 +00:00
spriteGroupSet_scaling(spriteGroupId);
redrawSpriteGroup(spriteGroupId);
}
}
2005-02-28 04:17:17 +00:00
void ScummEngine_v90he::spriteGroupSet_scale_y_ratio_mul(int spriteGroupId, int value) {
checkRange(_varNumSpriteGroups, 1, spriteGroupId, "Invalid sprite group %d");
2005-02-28 04:34:22 +00:00
if (_spriteGroups[spriteGroupId].scale_y_ratio_mul != value) {
_spriteGroups[spriteGroupId].scale_y_ratio_mul = value;
_spriteGroups[spriteGroupId].scaleY = _spriteGroups[spriteGroupId].scale_y_ratio_mul / _spriteGroups[spriteGroupId].scale_y_ratio_div;
2005-02-28 04:34:22 +00:00
spriteGroupSet_scaling(spriteGroupId);
redrawSpriteGroup(spriteGroupId);
}
}
2005-02-28 04:17:17 +00:00
void ScummEngine_v90he::spriteGroupSet_scale_y_ratio_div(int spriteGroupId, int value) {
checkRange(_varNumSpriteGroups, 1, spriteGroupId, "Invalid sprite group %d");
if (value == 0)
error("spriteGroupSet_scale_y_ratio_div: Divisor must not be 0");
2005-02-28 04:34:22 +00:00
if (_spriteGroups[spriteGroupId].scale_y_ratio_div != value) {
_spriteGroups[spriteGroupId].scale_y_ratio_div = value;
_spriteGroups[spriteGroupId].scaleY = _spriteGroups[spriteGroupId].scale_y_ratio_mul / _spriteGroups[spriteGroupId].scale_y_ratio_div;
2005-02-28 04:34:22 +00:00
spriteGroupSet_scaling(spriteGroupId);
redrawSpriteGroup(spriteGroupId);
}
}
void ScummEngine_v90he::spriteGroupSet_flagClipBoxAnd(int spriteGroupId) {
checkRange(_varNumSpriteGroups, 1, spriteGroupId, "Invalid sprite group %d");
_spriteGroups[spriteGroupId].flags &= ~(kSGFClipBox);
2005-02-23 04:35:20 +00:00
redrawSpriteGroup(spriteGroupId);
}
void ScummEngine_v90he::spritesAllocTables(int numSprites, int numGroups, int numMaxSprites) {
_varNumSpriteGroups = numGroups;
_numSpritesToProcess = 0;
_varNumSprites = numSprites;
_varMaxSprites = numMaxSprites;
_spriteGroups = (SpriteGroup *)malloc((_varNumSpriteGroups + 1) * sizeof(SpriteGroup));
_spriteTable = (SpriteInfo *)malloc((_varNumSprites + 1) * sizeof(SpriteInfo));
_activeSpritesTable = (SpriteInfo **)malloc((_varNumSprites + 1) * sizeof(SpriteInfo *));
}
void ScummEngine_v90he::spritesResetGroup(int spriteGroupId) {
checkRange(_varNumSpriteGroups, 1, spriteGroupId, "Invalid sprite group %d");
SpriteGroup *spg = &_spriteGroups[spriteGroupId];
spg->zorderPriority = 0;
spg->tx = spg->ty = 0;
spg->flags &= ~kSGFClipBox;
redrawSpriteGroup(spriteGroupId);
spg->dstResNum = 0;
spg->scaling = 0;
spg->scaleX = 0x3F800000;
spg->scale_x_ratio_mul = 1;
spg->scale_x_ratio_div = 1;
spg->scaleY = 0x3F800000;
spg->scale_y_ratio_mul = 1;
spg->scale_y_ratio_div = 1;
2005-02-23 04:35:20 +00:00
}
void ScummEngine_v90he::spritesResetTables(bool refreshScreen) {
memset(_spriteTable, 0, (_varNumSprites + 1) * sizeof(SpriteInfo));
memset(_spriteGroups, 0, (_varNumSpriteGroups + 1) * sizeof(SpriteGroup));
for (int curGrp = 1; curGrp < _varNumSpriteGroups; ++curGrp)
spritesResetGroup(curGrp);
if (refreshScreen) {
gdi.copyVirtScreenBuffers(Common::Rect(_screenWidth, _screenHeight));
}
_numSpritesToProcess = 0;
}
void ScummEngine_v90he::spritesBlitToScreen() {
int xmin, xmax, ymin, ymax;
xmin = ymin = 1234;
xmax = ymax = -1234;
bool firstLoop = true;
bool refreshScreen = false;
for (int i = 0; i < _numSpritesToProcess; ++i) {
SpriteInfo *spi = _activeSpritesTable[i];
if (!(spi->flags & kSFImageless) && (spi->flags & kSFChanged)) {
spi->flags &= ~kSFChanged;
if (spi->bbox.left <= spi->bbox.right && spi->bbox.top <= spi->bbox.bottom) {
if (spi->flags & kSFBlitDirectly) {
2005-04-02 14:24:43 +00:00
gdi.copyVirtScreenBuffers(spi->bbox, USAGE_BIT_RESTORED);
} else if (firstLoop) {
xmin = spi->bbox.left;
ymin = spi->bbox.top;
xmax = spi->bbox.right;
ymax = spi->bbox.bottom;
firstLoop = false;
refreshScreen = true;
} else {
2005-03-06 01:41:25 +00:00
if (xmin > spi->bbox.left) {
xmin = spi->bbox.left;
}
2005-03-06 01:41:25 +00:00
if (ymin > spi->bbox.top) {
ymin = spi->bbox.top;
}
2005-03-06 01:41:25 +00:00
if (xmax < spi->bbox.right) {
xmax = spi->bbox.right;
}
2005-03-06 01:41:25 +00:00
if (ymax < spi->bbox.bottom) {
ymax = spi->bbox.bottom;
}
refreshScreen = true;
}
if (!(spi->flags & (kSFNeedRedraw | kSF30)) && spi->resId)
2005-03-09 01:05:08 +00:00
spi->flags |= kSFNeedRedraw;
}
}
}
if (refreshScreen) {
2005-04-02 14:24:43 +00:00
gdi.copyVirtScreenBuffers(Common::Rect(xmin, ymin, xmax, ymax), USAGE_BIT_RESTORED);
}
}
void ScummEngine_v90he::spritesMarkDirty(bool unkFlag) {
VirtScreen *vs0 = &virtscr[kMainVirtScreen];
for (int i = 0; i < _numSpritesToProcess; ++i) {
SpriteInfo *spi = _activeSpritesTable[i];
if (!(spi->flags & (kSFNeedRedraw | kSF30))) {
if ((!unkFlag || spi->zorderPriority >= 0) && (spi->flags & kSFMarkDirty)) {
bool needRedraw = false;
int lp = MIN(79, spi->bbox.left / 8);
int rp = MIN(79, (spi->bbox.right + 7) / 8);
for (; lp <= rp; ++lp) {
if (vs0->tdirty[lp] < vs0->h && spi->bbox.bottom >= vs0->bdirty[lp] && spi->bbox.top <= vs0->tdirty[lp]) {
needRedraw = true;
break;
}
}
if (needRedraw) {
spi->flags |= kSFNeedRedraw;
}
}
}
}
}
void ScummEngine_v90he::spritesUpdateImages() {
for (int i = 0; i < _numSpritesToProcess; ++i) {
SpriteInfo *spi = _activeSpritesTable[i];
if (spi->dx || spi->dy) {
int tx = spi->tx;
int ty = spi->ty;
spi->tx += spi->dx;
spi->ty += spi->dy;
if (tx != spi->tx || ty != spi->ty) {
spi->flags |= kSFChanged | kSFNeedRedraw;
}
}
if (spi->flags & kSFDelayed) {
if (spi->delayAmount) {
--spi->delayCount;
if (spi->delayCount)
continue;
spi->delayCount = spi->delayAmount;
}
int resState = spi->resState;
++spi->resState;
if (spi->resState >= spi->res_wiz_states) {
spi->resState = 0;
if (resState == 0)
continue;
}
spi->flags |= kSFChanged | kSFNeedRedraw;
}
}
}
static int compareSprTable(const void *a, const void *b) {
const SpriteInfo *spr1 = *(const SpriteInfo *const*)a;
const SpriteInfo *spr2 = *(const SpriteInfo *const*)b;
if (spr1->zorder > spr2->zorder)
return 1;
if (spr1->zorder < spr2->zorder)
return -1;
return 0;
}
void ScummEngine_v90he::spritesSortActiveSprites() {
int groupZorder;
_numSpritesToProcess = 0;
if (_varNumSprites <= 1)
return;
for (int i = 1; i < _varNumSprites; i++) {
SpriteInfo *spi = &_spriteTable[i];
if (spi->flags & kSFActive) {
if (!(spi->flags & kSFMarkDirty)) {
if (!(spi->flags & kSF30))
spi->flags |= kSFNeedRedraw;
if (!(spi->flags & kSFImageless))
spi->flags |= kSFChanged;
}
if (spi->groupNum)
groupZorder = _spriteGroups[spi->groupNum].zorderPriority;
else
groupZorder = 0;
spi->id = i;
spi->zorder = spi->zorderPriority + groupZorder;
_activeSpritesTable[_numSpritesToProcess++] = spi;
}
}
if (_numSpritesToProcess < 2)
return;
qsort(_activeSpritesTable, _numSpritesToProcess, sizeof(SpriteInfo *), compareSprTable);
}
void ScummEngine_v90he::spritesProcessWiz(bool arg) {
int spr_flags;
int16 spr_wiz_x, spr_wiz_y;
int resId, resState;
Common::Rect *bboxPtr;
int angle, zoom;
int32 w, h;
WizParameters wiz;
for (int i = 0; i < _numSpritesToProcess; i++) {
SpriteInfo *spi = _activeSpritesTable[i];
2005-04-02 14:24:43 +00:00
if (!(spi->flags & kSFNeedRedraw))
continue;
spr_flags = spi->flags;
if (arg) {
if (spi->zorder >= 0)
2005-02-26 00:35:23 +00:00
return;
} else {
if (spi->zorder < 0)
2005-02-26 00:35:23 +00:00
continue;
}
spi->flags &= ~kSFNeedRedraw;
resId = spi->resId;
resState = spi->resState;
loadImgSpot(spi->resId, spi->resState, spr_wiz_x, spr_wiz_y);
if (spi->groupNum) {
SpriteGroup *spg = &_spriteGroups[spi->groupNum];
if (spg->scaling) {
wiz.img.x1 = spi->tx * spg->scaleX - spr_wiz_x + spg->tx;
wiz.img.y1 = spi->ty * spg->scaleY - spr_wiz_y + spg->ty;
} else {
wiz.img.x1 = spi->tx - spr_wiz_x + spg->tx;
wiz.img.y1 = spi->ty - spr_wiz_y + spg->ty;
}
} else {
wiz.img.x1 = spi->tx - spr_wiz_x;
wiz.img.y1 = spi->ty - spr_wiz_y;
}
spi->curImageState = wiz.img.state = resState;
spi->curResId = wiz.img.resNum = resId;
wiz.processFlags = kWPFNewState | kWPFSetPos;
spi->curAngle = spi->angle;
2005-03-06 04:31:02 +00:00
spi->cur_zoom = spi->zoom;
spi->pos.x = wiz.img.x1;
spi->pos.y = wiz.img.y1;
bboxPtr = &spi->bbox;
if (resId) {
angle = spi->angle;
zoom = spi->zoom;
getWizImageDim(resId, resState, w, h);
if (!(spi->flags & (kSFZoomed | kSFRotated))) {
bboxPtr->left = wiz.img.x1;
bboxPtr->top = wiz.img.y1;
bboxPtr->right = wiz.img.x1 + w;
bboxPtr->bottom = wiz.img.y1 + h;
} else {
Common::Point pts[4];
pts[1].x = pts[2].x = w / 2 - 1;
pts[0].x = pts[0].y = pts[1].y = pts[3].x = -w / 2;
pts[2].y = pts[3].y = h / 2 - 1;
if ((spi->flags & kSFZoomed) && zoom) {
for (int j = 0; j < 4; ++j) {
pts[j].x = pts[j].x * zoom / 256;
pts[j].y = pts[j].y * zoom / 256;
}
}
if ((spi->flags & kSFRotated) && angle)
_wiz.polygonRotatePoints(pts, 4, angle);
for (int j = 0; j < 4; ++j) {
pts[j].x += wiz.img.x1;
pts[j].y += wiz.img.y1;
}
_wiz.polygonCalcBoundBox(pts, 4, spi->bbox);
}
} else {
bboxPtr->left = 1234;
bboxPtr->top = 1234;
bboxPtr->right = -1234;
bboxPtr->bottom = -1234;
}
2005-03-23 21:55:11 +00:00
wiz.img.flags = kWIFMarkBufferDirty;
if (spr_flags & kSFXFlipped)
wiz.img.flags |= kWIFFlipX;
if (spr_flags & kSFYFlipped)
wiz.img.flags |= kWIFFlipY;
if (spr_flags & kSFDoubleBuffered) {
2005-03-23 21:55:11 +00:00
wiz.img.flags &= ~kWIFMarkBufferDirty;
wiz.img.flags |= kWIFBlitToFrontVideoBuffer;
}
if (spi->xmapNum) {
wiz.img.flags |= 0x200;
wiz.processFlags |= 4;
wiz.xmapNum = spi->xmapNum;
}
if (spr_flags & kSFNeedPaletteRemap)
2005-03-23 21:55:11 +00:00
wiz.img.flags |= kWIFRemapPalette;
if (spi->field_7C) {
wiz.processFlags |= 0x80000;
wiz.unk_178 = spi->field_7C;
}
wiz.processFlags |= kWPFNewFlags;
if (spr_flags & kSFRotated) {
wiz.processFlags |= kWPFRotate;
wiz.angle = spi->angle;
}
if (spr_flags & kSFZoomed) {
wiz.processFlags |= kWPFZoom;
wiz.zoom = spi->zoom;
}
spi->imgFlags = wiz.img.flags;
if (spi->groupNum && (_spriteGroups[spi->groupNum].flags & kSGFClipBox)) {
if (spi->bbox.intersects(_spriteGroups[spi->groupNum].bbox)) {
spi->bbox.clip(_spriteGroups[spi->groupNum].bbox);
wiz.processFlags |= kWPFClipBox;
wiz.box = spi->bbox;
} else {
bboxPtr->left = 1234;
bboxPtr->top = 1234;
bboxPtr->right = -1234;
bboxPtr->bottom = -1234;
continue;
}
}
if (spi->paletteNum) {
wiz.processFlags |= kWPFPaletteNum;
wiz.img.paletteNum = spi->paletteNum;
}
if (spi->resId && spi->groupNum && _spriteGroups[spi->groupNum].dstResNum) {
wiz.processFlags |= kWPFDstResNum;
wiz.dstResNum = _spriteGroups[spi->groupNum].dstResNum;
}
displayWizComplexImage(&wiz);
}
}
} // End of namespace Scumm