aboutsummaryrefslogtreecommitdiff
path: root/scumm/actor.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'scumm/actor.cpp')
-rw-r--r--scumm/actor.cpp113
1 files changed, 112 insertions, 1 deletions
diff --git a/scumm/actor.cpp b/scumm/actor.cpp
index e37456ab40..b4db39afe4 100644
--- a/scumm/actor.cpp
+++ b/scumm/actor.cpp
@@ -137,6 +137,8 @@ void Actor::initActor(int mode) {
clipOverride = _vm->_actorClipOverride;
+ auxBlock.visible = false;
+
_vm->_classData[number] = (_vm->_version >= 7) ? _vm->_classData[0] : 0;
}
@@ -492,8 +494,10 @@ void Actor::startAnimActor(int f) {
// Causes Zak to lose his body in several scenes, see bug #771508
if (_vm->_version >= 3 && f == initFrame)
cost.reset();
- if (_vm->_features & GF_NEW_COSTUMES)
+ if (_vm->_features & GF_NEW_COSTUMES) {
+ auxBlock.visible = false;
_vm->akos_decodeData(this, f, (uint) - 1);
+ }
else
_vm->cost_decodeData(this, f, (uint) - 1);
frame = f;
@@ -602,6 +606,12 @@ void Actor::putActor(int dstX, int dstY, byte newRoom) {
}
adjustActorPos();
} else {
+ if (_vm->_heversion >= 72) {
+ if (auxBlock.visible) {
+ _vm->queueAuxBlock(this);
+ auxBlock.visible = false;
+ }
+ }
hideActor();
}
} else {
@@ -1356,6 +1366,12 @@ void Actor::setActorCostume(int c) {
memset(animVariable, 0, sizeof(animVariable));
costume = c;
+ if (_vm->_heversion >= 72) {
+ if (auxBlock.visible) {
+ _vm->queueAuxBlock(this);
+ }
+ }
+
if (visible) {
if (costume) {
_vm->ensureResourceLoaded(rtCostume, costume);
@@ -1869,6 +1885,101 @@ bool Actor::isTalkConditionSet(int slot) {
return condMask & (1 << (slot - 1));
}
+void ScummEngine::preProcessAuxQueue() {
+ if (!_skipProcessActors) {
+ for (int i = 0; i < _auxBlocksNum; ++i) {
+ AuxBlock *ab = &_auxBlocks[i];
+ assert(ab->r.top <= ab->r.bottom);
+ if (ab->visible) {
+ gdi.copyVirtScreenBuffers(ab->r);
+ }
+ }
+ }
+ _auxBlocksNum = 0;
+}
+
+void ScummEngine::postProcessAuxQueue() {
+ if (!_skipProcessActors) {
+ for (int i = 0; i < _auxEntriesNum; ++i) {
+ AuxEntry *ae = &_auxEntries[i];
+ if (ae->actorNum != -1) {
+ Actor *a = derefActor(ae->actorNum, "postProcessAuxQueue");
+ const uint8 *cost = getResourceAddress(rtCostume, a->costume);
+
+ int dy = a->offs_y + a->_pos.y - a->getElevation();
+ int dx = a->offs_x + a->_pos.x;
+
+ const uint8 *akax = findResource(MKID('AKAX'), cost);
+ if (!akax) {
+ error("No AKAX block for actor %d", ae->actorNum);
+ }
+ const uint8 *auxd = findPalInPals(akax, ae->subIndex) - _resourceHeaderSize;
+ if (!auxd) {
+ error("No AUXD block for actor %d", ae->actorNum);
+ }
+ const uint8 *axfd = findResourceData(MKID('AXFD'), auxd);
+ if (!axfd) {
+ error("No AXFD block for actor %d", ae->actorNum);
+ } else {
+ uint16 comp = READ_LE_UINT16(axfd);
+ if (comp == 1 || comp == 16) {
+ int x1 = (int16)READ_LE_UINT16(axfd + 2) + dx;
+ int y1 = (int16)READ_LE_UINT16(axfd + 4) + dy;
+ int x2 = (int16)READ_LE_UINT16(axfd + 6);
+ int y2 = (int16)READ_LE_UINT16(axfd + 8);
+ VirtScreen *pvs = &virtscr[kMainVirtScreen];
+ uint8 *dst1 = pvs->getPixels(0, 0);
+ uint8 *dst2 = pvs->getBackPixels(0, 0);
+ switch (comp) {
+ case 1:
+ gdi.copyAuxImage(dst1, dst2, axfd + 10, pvs->w, pvs->h, x1, y1, x2, y2, 0);
+ break;
+ default:
+ warning("unimplemented compression type %d", comp);
+ break;
+ }
+ }
+ }
+ const uint8 *axur = findResourceData(MKID('AXUR'), auxd);
+ if (axur) {
+ uint16 n = READ_LE_UINT16(axur); axur += 2;
+ while (n--) {
+ int x = (int16)READ_LE_UINT16(axur + 0) + dx;
+ int y = (int16)READ_LE_UINT16(axur + 2) + dy;
+ int w = (int16)READ_LE_UINT16(axur + 4) + dx;
+ int h = (int16)READ_LE_UINT16(axur + 6) + dy;
+ markRectAsDirty(kMainVirtScreen, x, w, y, h);
+ axur += 8;
+ }
+ }
+ const uint8 *axer = findResourceData(MKID('AXER'), auxd);
+ if (axer) {
+ a->auxBlock.visible = true;
+ a->auxBlock.r.left = (int16)READ_LE_UINT16(axer + 0) + dx;
+ a->auxBlock.r.top = (int16)READ_LE_UINT16(axer + 2) + dy;
+ a->auxBlock.r.right = (int16)READ_LE_UINT16(axer + 4) + dx;
+ a->auxBlock.r.bottom = (int16)READ_LE_UINT16(axer + 6) + dy;
+ }
+ }
+ }
+ }
+ _auxEntriesNum = 0;
+}
+
+void ScummEngine::queueAuxBlock(Actor *a) {
+ assert(_auxBlocksNum < ARRAYSIZE(_auxBlocks));
+ _auxBlocks[_auxBlocksNum] = a->auxBlock;
+ ++_auxBlocksNum;
+}
+
+void ScummEngine::queueAuxEntry(int actorNum, int subIndex) {
+ assert(_auxEntriesNum < ARRAYSIZE(_auxEntries));
+ AuxEntry *ae = &_auxEntries[_auxEntriesNum];
+ ae->actorNum = actorNum;
+ ae->subIndex = subIndex;
+ ++_auxEntriesNum;
+}
+
const SaveLoadEntry *Actor::getSaveLoadEntries() {
static const SaveLoadEntry actorEntries[] = {