aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGregory Montoir2004-09-18 00:36:17 +0000
committerGregory Montoir2004-09-18 00:36:17 +0000
commit22b2cfa00255dcb282c88817f5b33c0999473ab7 (patch)
treeb032b16ba1bd4d0c2f1614153f774a95488a2922
parent48fb2878871488c5c4bfc3e674e68873e1c5a2a6 (diff)
downloadscummvm-rg350-22b2cfa00255dcb282c88817f5b33c0999473ab7.tar.gz
scummvm-rg350-22b2cfa00255dcb282c88817f5b33c0999473ab7.tar.bz2
scummvm-rg350-22b2cfa00255dcb282c88817f5b33c0999473ab7.zip
preliminar AuxQueue support (freddemo intro), some glitches though
svn-id: r15149
-rw-r--r--scumm/actor.cpp113
-rw-r--r--scumm/actor.h1
-rw-r--r--scumm/akos.cpp8
-rw-r--r--scumm/gfx.cpp143
-rw-r--r--scumm/gfx.h6
-rw-r--r--scumm/palette.cpp1
-rw-r--r--scumm/script_v7he.cpp17
-rw-r--r--scumm/scumm.cpp19
-rw-r--r--scumm/scumm.h22
9 files changed, 302 insertions, 28 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[] = {
diff --git a/scumm/actor.h b/scumm/actor.h
index 66381fe353..8e839dc3fb 100644
--- a/scumm/actor.h
+++ b/scumm/actor.h
@@ -125,6 +125,7 @@ public:
CostumeData cost;
uint32 condMask;
bool talkUnk;
+ AuxBlock auxBlock;
protected:
byte palette[256];
int elevation;
diff --git a/scumm/akos.cpp b/scumm/akos.cpp
index 27a130c6a7..f2b498e05d 100644
--- a/scumm/akos.cpp
+++ b/scumm/akos.cpp
@@ -1245,7 +1245,7 @@ byte AkosRenderer::codec32(int xmoveCur, int ymoveCur) {
if (_draw_bottom < dst.bottom)
_draw_bottom = dst.bottom;
- _vm->gdi.decompressImageHE(_outptr, _outwidth, &dst, _srcptr, &src);
+ _vm->gdi.decompressWizImage(_outptr, _outwidth, &dst, _srcptr, &src);
return 0;
}
@@ -1381,7 +1381,7 @@ bool ScummEngine::akos_increaseAnim(Actor *a, int chan, const byte *aksq, const
curpos += aksq[curpos + 2];
break;
case AKC_C08E:
- //akos_queCommand(7, a, GB(2), 0);
+ akos_queCommand(7, a, GW(2), 0);
curpos += 4;
break;
default:
@@ -1674,7 +1674,9 @@ void ScummEngine::akos_processQueue() {
a->offs_y = param_2;
break;
case 7:
- if (param_1 != 0) {
+ if (_heversion >= 72) {
+ queueAuxEntry(a->number, param_1);
+ } else if (param_1 != 0) {
if (_imuseDigital) {
_imuseDigital->setVolume(param_1, param_2);
}
diff --git a/scumm/gfx.cpp b/scumm/gfx.cpp
index bcbc26c2f7..9ddf3fc35c 100644
--- a/scumm/gfx.cpp
+++ b/scumm/gfx.cpp
@@ -1481,11 +1481,11 @@ void Gdi::copyWizImage(uint8 *dst, const uint8 *src, int dst_w, int dst_h, int s
r2.bottom -= diff;
}
if (r1.isValidRect() && r2.isValidRect()) {
- decompressImageHE(dst, dst_w, &r2, src, &r1);
+ decompressWizImage(dst, dst_w, &r2, src, &r1);
}
}
-void Gdi::decompressImageHE(uint8 *dst, int dstWidth, const Common::Rect *dstRect, const uint8 *src, const Common::Rect *srcRect) {
+void Gdi::decompressWizImage(uint8 *dst, int dstPitch, const Common::Rect *dstRect, const uint8 *src, const Common::Rect *srcRect) {
const uint8 *dataPtr, *dataPtrNext;
uint8 *dstPtr, *dstPtrNext;
uint32 code;
@@ -1493,7 +1493,7 @@ void Gdi::decompressImageHE(uint8 *dst, int dstWidth, const Common::Rect *dstRec
int h, w, xoff;
uint16 off;
- dstPtr = dst + dstRect->left + dstRect->top * dstWidth;
+ dstPtr = dst + dstRect->left + dstRect->top * dstPitch;
dataPtr = src;
h = srcRect->top;
while (h--) {
@@ -1513,7 +1513,7 @@ void Gdi::decompressImageHE(uint8 *dst, int dstWidth, const Common::Rect *dstRec
xoff = srcRect->left;
off = READ_LE_UINT16(dataPtr);
w = srcRect->right - srcRect->left + 1;
- dstPtrNext = dstWidth + dstPtr;
+ dstPtrNext = dstPitch + dstPtr;
dataPtrNext = off + 2 + dataPtr;
dataPtr += 2;
if (off == 0) goto dec_next;
@@ -1589,6 +1589,141 @@ dec_next:
}
}
+void Gdi::copyAuxImage(uint8 *dst1, uint8 *dst2, const uint8 *src, int dstw, int dsth, int srcx, int srcy, int srcw, int srch, Common::Rect *rect) {
+ Common::Rect r1(0, 0, srcw - 1, srch - 1);
+ Common::Rect r2(srcx, srcy, srcx + srcw - 1, srcy + srch - 1);
+ Common::Rect r3;
+ int diff;
+
+ if (rect) {
+ r3 = *rect;
+ Common::Rect r4(0, 0, dstw - 1, dsth - 1);
+ if (!r3.intersects(r4)) {
+ return;
+ }
+ } else {
+ r3 = Common::Rect(0, 0, dstw - 1, dsth - 1);
+ }
+ diff = r2.left - r3.left;
+ if (diff < 0) {
+ r1.left -= diff;
+ r2.left -= diff;
+ }
+ diff = r2.right - r3.right;
+ if (diff > 0) {
+ r1.right -= diff;
+ r2.right -= diff;
+ }
+ diff = r2.top - r3.top;
+ if (diff < 0) {
+ r1.top -= diff;
+ r2.top -= diff;
+ }
+ diff = r2.bottom - r3.bottom;
+ if (diff > 0) {
+ r1.bottom -= diff;
+ r2.bottom -= diff;
+ }
+ if (r1.isValidRect() && r2.isValidRect()) {
+ decompressAuxImage(dst1, dst2, dstw, &r2, src, &r1);
+ }
+}
+
+void Gdi::decompressAuxImage(uint8 *dst1, uint8 *dst2, int dstPitch, const Common::Rect *dstRect, const uint8 *src, const Common::Rect *srcRect) {
+ uint8 *dstCur2, *dstCur1;
+ const uint8 *srcCur;
+ uint8 code;
+
+ int w = srcRect->right - srcRect->left + 1;
+ int h = srcRect->bottom - srcRect->top + 1;
+ int off = dstRect->top * dstPitch + dstRect->left;
+
+ dst1 += off;
+ dst2 += off;
+
+ int n = srcRect->top;
+ while (n--) {
+ src += READ_LE_UINT16(src) + 2;
+ }
+
+ while (h--) {
+ uint16 var_8 = READ_LE_UINT16(src);
+ if (var_8) {
+ int rw = w;
+ int xoff = srcRect->left;
+ srcCur = src + 2;
+ dstCur1 = dst1;
+ dstCur2 = dst2;
+ while (xoff > 0) {
+ code = *srcCur++;
+ if (code & 1) {
+ code >>= 1;
+ if (code > xoff) {
+ code -= xoff;
+ goto dec_sub1;
+ }
+ xoff -= code;
+ } else if (code & 2) {
+ code = (code >> 2) + 1;
+ if (code > xoff) {
+ code -= xoff;
+ goto dec_sub2;
+ }
+ xoff -= code;
+ ++srcCur;
+ } else {
+ code = (code >> 2) + 1;
+ if (code > xoff) {
+ code -= xoff;
+ srcCur += xoff;
+ goto dec_sub3;
+ }
+ xoff -= code;
+ srcCur += code;
+ }
+ }
+ while (rw > 0) {
+ code = *srcCur++;
+ if (code & 1) {
+ code >>= 1;
+dec_sub1: dstCur1 += code;
+ dstCur2 += code;
+ rw -= code;
+ } else if (code & 2) {
+ code = (code >> 2) + 1;
+dec_sub2: rw -= code;
+ if (rw >= 0) {
+ memset(dstCur1, *srcCur++, code);
+ dstCur1 += code;
+ dstCur2 += code;
+ } else {
+ code += rw;
+ memset(dstCur1, *srcCur, code);
+ }
+ } else {
+ code = (code >> 2) + 1;
+dec_sub3: rw -= code;
+ if (rw >= 0) {
+ memcpy(dstCur1, dstCur2, code);
+ dstCur1 += code;
+ dstCur2 += code;
+ } else {
+ code += rw;
+ memcpy(dstCur1, dstCur2, code);
+ }
+ }
+ }
+ src += var_8 + 2;
+ dst1 += dstPitch;
+ dst2 += dstPitch;
+ } else {
+ src += 2;
+ dst1 += dstPitch;
+ dst2 += dstPitch;
+ }
+ }
+}
+
void Gdi::copyVirtScreenBuffers(Common::Rect rect) {
int rw = rect.right - rect.left + 1;
int rh = rect.bottom - rect.top + 1;
diff --git a/scumm/gfx.h b/scumm/gfx.h
index 06a9fa9f04..5dcfe48374 100644
--- a/scumm/gfx.h
+++ b/scumm/gfx.h
@@ -275,8 +275,10 @@ public:
StripTable *generateStripTable(const byte *src, int width, int height, StripTable *table);
void drawBMAPBg(const byte *ptr, VirtScreen *vs, int startstrip, int width);
void drawBMAPObject(const byte *ptr, VirtScreen *vs, int obj, int x, int y, int w, int h);
- void copyWizImage(uint8 *dst, const uint8 *src, int dstw, int dsth, int srcx, int srcy, int srcw, int srch, Common::Rect *pr);
- void decompressImageHE(uint8 *dst, int dstWidth, const Common::Rect *dstRect, const uint8 *src, const Common::Rect *srcRect);
+ void copyWizImage(uint8 *dst, const uint8 *src, int dstw, int dsth, int srcx, int srcy, int srcw, int srch, Common::Rect *rect);
+ void decompressWizImage(uint8 *dst, int dstPitch, const Common::Rect *dstRect, const uint8 *src, const Common::Rect *srcRect);
+ void copyAuxImage(uint8 *dst1, uint8 *dst2, const uint8 *src, int dstw, int dsth, int srcx, int srcy, int srcw, int srch, Common::Rect *rect);
+ void decompressAuxImage(uint8 *dst1, uint8 *dst2, int dstPitch, const Common::Rect *dstRect, const uint8 *src, const Common::Rect *srcRect);
void copyVirtScreenBuffers(Common::Rect rect);
void disableZBuffer() { _zbufferDisabled = true; }
diff --git a/scumm/palette.cpp b/scumm/palette.cpp
index 983adf6380..5f4ed3b09d 100644
--- a/scumm/palette.cpp
+++ b/scumm/palette.cpp
@@ -785,7 +785,6 @@ const byte *ScummEngine::findPalInPals(const byte *pal, int idx) {
return NULL;
size = getResourceDataSize(offs) / 4;
-
if ((uint32)idx >= (uint32)size)
return NULL;
diff --git a/scumm/script_v7he.cpp b/scumm/script_v7he.cpp
index 37a9460eb1..1267255000 100644
--- a/scumm/script_v7he.cpp
+++ b/scumm/script_v7he.cpp
@@ -745,8 +745,9 @@ void ScummEngine_v7he::o7_kernelSetFunctions() {
// Fatty Bear's Birthday Surprise
virtScreenLoad(args[1], args[2], args[3], args[4], args[5]);
break;
- case 20:
- // erase aux animation actor?
+ case 20: // HE72+
+ a = derefActor(args[1], "o7_kernelSetFunctions: 20");
+ queueAuxBlock(a);
break;
case 21:
_skipDrawObject = 1;
@@ -759,19 +760,11 @@ void ScummEngine_v7he::o7_kernelSetFunctions() {
_fullRedraw = 1;
break;
case 24:
- if (_heversion <= 72) {
- _skipProcessActors = 1;
- } else {
- //Pause aux animation
- }
+ _skipProcessActors = 1;
_fullRedraw = 1;
break;
case 25:
- if (_heversion <= 72) {
- _skipProcessActors = 0;
- } else {
- //Resume aux animation
- }
+ _skipProcessActors = 0;
_fullRedraw = 1;
break;
case 30:
diff --git a/scumm/scumm.cpp b/scumm/scumm.cpp
index 1ffaa2a72b..d6d84b5909 100644
--- a/scumm/scumm.cpp
+++ b/scumm/scumm.cpp
@@ -691,6 +691,10 @@ ScummEngine::ScummEngine(GameDetector *detector, OSystem *syst, const ScummGameS
_skipDrawObject = 0;
_skipProcessActors = 0;
+ _auxBlocksNum = 0;
+ memset(_auxBlocks, 0, sizeof(_auxBlocks));
+ _auxEntriesNum = 0;
+ memset(_auxEntries, 0, sizeof(_auxEntries));
_heSndSoundId = 0;
_heSndOffset = 0;
_heSndChannel = 0;
@@ -1820,8 +1824,14 @@ load_game:
drawFlashlight();
setActorRedrawFlags();
}
-
- processActors();
+ if (_heversion >= 72) {
+ preProcessAuxQueue();
+ processActors();
+ postProcessAuxQueue();
+ } else {
+ processActors();
+ }
+
_fullRedraw = false;
if (_version >= 4 && _heversion <= 60)
cyclePalette();
@@ -2329,9 +2339,8 @@ void ScummEngine::startScene(int room, Actor *a, int objectNr) {
stopCycle(0);
_sound->processSoundQues();
- if (_heversion >= 70 && _WizPolygons) {
- for (i = 0; i < _WizNumPolygons; i++)
- memset(&_WizPolygons[i], 0, sizeof(WizPolygon));
+ if (_heversion >= 70 && _WizPolygons) {
+ memset(_WizPolygons, 0, _WizNumPolygons * sizeof(WizPolygon));
}
for (i = 0; i < _numRoomVariables; i++)
diff --git a/scumm/scumm.h b/scumm/scumm.h
index 7e27a2b002..aae2e11def 100644
--- a/scumm/scumm.h
+++ b/scumm/scumm.h
@@ -329,6 +329,16 @@ struct WizPolygon {
bool flag;
};
+struct AuxBlock {
+ bool visible;
+ Common::Rect r;
+};
+
+struct AuxEntry {
+ int actorNum;
+ int subIndex;
+};
+
class ScummEngine : public Engine {
friend class ScummDebugger;
friend class SmushPlayer;
@@ -839,6 +849,18 @@ protected:
bool isCostumeInUse(int i) const;
public:
+ /* Actor AuxQueue stuff (HE) */
+ AuxBlock _auxBlocks[16];
+ uint16 _auxBlocksNum;
+ AuxEntry _auxEntries[16];
+ uint16 _auxEntriesNum;
+
+ void preProcessAuxQueue();
+ void postProcessAuxQueue();
+ void queueAuxBlock(Actor *a);
+ void queueAuxEntry(int actorNum, int subIndex);
+
+public:
/* Actor talking stuff */
byte _actorToPrintStrFor, _V1_talkingActor;
int _sentenceNum;