diff options
Diffstat (limited to 'engines/dreamweb/sprite.cpp')
-rw-r--r-- | engines/dreamweb/sprite.cpp | 316 |
1 files changed, 184 insertions, 132 deletions
diff --git a/engines/dreamweb/sprite.cpp b/engines/dreamweb/sprite.cpp index 14794a81a8..cc6b09fd68 100644 --- a/engines/dreamweb/sprite.cpp +++ b/engines/dreamweb/sprite.cpp @@ -24,12 +24,12 @@ namespace DreamGen { -Sprite *DreamGenContext::spriteTable() { +Sprite *DreamBase::spriteTable() { Sprite *sprite = (Sprite *)getSegment(data.word(kBuffers)).ptr(kSpritetable, 16 * sizeof(Sprite)); return sprite; } -void DreamGenContext::printSprites() { +void DreamBase::printSprites() { for (size_t priority = 0; priority < 7; ++priority) { Sprite *sprites = spriteTable(); for (size_t j = 0; j < 16; ++j) { @@ -45,7 +45,7 @@ void DreamGenContext::printSprites() { } } -void DreamGenContext::printASprite(const Sprite *sprite) { +void DreamBase::printASprite(const Sprite *sprite) { uint16 x, y; if (sprite->y >= 220) { y = data.word(kMapady) - (256 - sprite->y); @@ -67,11 +67,11 @@ void DreamGenContext::printASprite(const Sprite *sprite) { showFrame((const Frame *)getSegment(sprite->frameData()).ptr(0, 0), x, y, sprite->frameNumber, c); } -void DreamGenContext::clearSprites() { +void DreamBase::clearSprites() { memset(spriteTable(), 0xff, sizeof(Sprite) * 16); } -Sprite *DreamGenContext::makeSprite(uint8 x, uint8 y, uint16 updateCallback, uint16 frameData, uint16 somethingInDi) { +Sprite *DreamBase::makeSprite(uint8 x, uint8 y, uint16 updateCallback, uint16 frameData, uint16 somethingInDi) { Sprite *sprite = spriteTable(); while (sprite->frameNumber != 0xff) { // NB: No boundchecking in the original code either ++sprite; @@ -88,7 +88,7 @@ Sprite *DreamGenContext::makeSprite(uint8 x, uint8 y, uint16 updateCallback, uin return sprite; } -void DreamGenContext::spriteUpdate() { +void DreamBase::spriteUpdate() { Sprite *sprites = spriteTable(); sprites[0].hidden = data.byte(kRyanon); @@ -111,48 +111,33 @@ void DreamGenContext::spriteUpdate() { } } -void DreamGenContext::initMan() { +void DreamBase::initMan() { Sprite *sprite = makeSprite(data.byte(kRyanx), data.byte(kRyany), addr_mainman, data.word(kMainsprites), 0); sprite->priority = 4; sprite->speed = 0; sprite->walkFrame = 0; } -void DreamGenContext::mainMan() { - assert(false); -} - -void DreamGenContext::mainMan(Sprite *sprite) { - push(es); - push(ds); - - // Recover es:bx from sprite - es = data.word(kBuffers); - bx = kSpritetable; - Sprite *sprites = (Sprite *)es.ptr(bx, sizeof(Sprite) * 16); - bx += 32 * (sprite - sprites); - // - +void DreamBase::mainMan(Sprite *sprite) { if (data.byte(kResetmanxy) == 1) { data.byte(kResetmanxy) = 0; sprite->x = data.byte(kRyanx); sprite->y = data.byte(kRyany); sprite->walkFrame = 0; } + --sprite->speed; - if (sprite->speed != 0xff) { - ds = pop(); - es = pop(); + if (sprite->speed != 0xff) return; - } sprite->speed = 0; + if (data.byte(kTurntoface) != data.byte(kFacing)) { aboutTurn(sprite); } else { if ((data.byte(kTurndirection) != 0) && (data.byte(kLinepointer) == 254)) { data.byte(kReasseschanges) = 1; if (data.byte(kFacing) == data.byte(kLeavedirection)) - checkForExit(); + checkForExit(sprite); } data.byte(kTurndirection) = 0; if (data.byte(kLinepointer) == 254) { @@ -172,7 +157,7 @@ void DreamGenContext::mainMan(Sprite *sprite) { if (data.byte(kTurntoface) == data.byte(kFacing)) { data.byte(kReasseschanges) = 1; if (data.byte(kFacing) == data.byte(kLeavedirection)) - checkForExit(); + checkForExit(sprite); } } } @@ -181,12 +166,9 @@ void DreamGenContext::mainMan(Sprite *sprite) { sprite->frameNumber = sprite->walkFrame + facelist[data.byte(kFacing)]; data.byte(kRyanx) = sprite->x; data.byte(kRyany) = sprite->y; - - ds = pop(); - es = pop(); } -void DreamGenContext::walking(Sprite *sprite) { +void DreamBase::walking(Sprite *sprite) { uint8 comp; if (data.byte(kLinedirection) != 0) { --data.byte(kLinepointer); @@ -208,14 +190,10 @@ void DreamGenContext::walking(Sprite *sprite) { return; } data.byte(kDestination) = data.byte(kFinaldest); - push(es); - push(bx); autoSetWalk(); - bx = pop(); - es = pop(); } -void DreamGenContext::aboutTurn(Sprite *sprite) { +void DreamBase::aboutTurn(Sprite *sprite) { bool incdir = true; if (data.byte(kTurndirection) == 1) @@ -249,11 +227,7 @@ void DreamGenContext::aboutTurn(Sprite *sprite) { } } -void DreamGenContext::backObject() { - assert(false); -} - -void DreamGenContext::backObject(Sprite *sprite) { +void DreamBase::backObject(Sprite *sprite) { SetObject *objData = (SetObject *)getSegment(data.word(kSetdat)).ptr(sprite->objData(), 0); if (sprite->delay != 0) { @@ -278,7 +252,7 @@ void DreamGenContext::backObject(Sprite *sprite) { steady(sprite, objData); } -void DreamGenContext::constant(Sprite *sprite, SetObject *objData) { +void DreamBase::constant(Sprite *sprite, SetObject *objData) { ++sprite->animFrame; if (objData->frames[sprite->animFrame] == 255) { sprite->animFrame = 0; @@ -288,22 +262,22 @@ void DreamGenContext::constant(Sprite *sprite, SetObject *objData) { sprite->frameNumber = frame; } -void DreamGenContext::randomSprite(Sprite *sprite, SetObject *objData) { +void DreamBase::randomSprite(Sprite *sprite, SetObject *objData) { uint8 r = engine->randomNumber(); sprite->frameNumber = objData->frames[r&7]; } -void DreamGenContext::doorway(Sprite *sprite, SetObject *objData) { +void DreamBase::doorway(Sprite *sprite, SetObject *objData) { Common::Rect check(-24, -30, 10, 10); doDoor(sprite, objData, check); } -void DreamGenContext::wideDoor(Sprite *sprite, SetObject *objData) { +void DreamBase::wideDoor(Sprite *sprite, SetObject *objData) { Common::Rect check(-24, -30, 24, 24); doDoor(sprite, objData, check); } -void DreamGenContext::doDoor(Sprite *sprite, SetObject *objData, Common::Rect check) { +void DreamBase::doDoor(Sprite *sprite, SetObject *objData, Common::Rect check) { int ryanx = data.byte(kRyanx); int ryany = data.byte(kRyany); @@ -352,13 +326,13 @@ void DreamGenContext::doDoor(Sprite *sprite, SetObject *objData, Common::Rect ch } } -void DreamGenContext::steady(Sprite *sprite, SetObject *objData) { +void DreamBase::steady(Sprite *sprite, SetObject *objData) { uint8 frame = objData->frames[0]; objData->index = frame; sprite->frameNumber = frame; } -void DreamGenContext::lockedDoorway(Sprite *sprite, SetObject *objData) { +void DreamBase::lockedDoorway(Sprite *sprite, SetObject *objData) { int ryanx = data.byte(kRyanx); int ryany = data.byte(kRyany); @@ -409,13 +383,13 @@ void DreamGenContext::lockedDoorway(Sprite *sprite, SetObject *objData) { } } -void DreamGenContext::liftSprite(Sprite *sprite, SetObject *objData) { +void DreamBase::liftSprite(Sprite *sprite, SetObject *objData) { uint8 liftFlag = data.byte(kLiftflag); if (liftFlag == 0) { //liftclosed turnPathOff(data.byte(kLiftpath)); if (data.byte(kCounttoopen) != 0) { - _dec(data.byte(kCounttoopen)); + data.byte(kCounttoopen)--; if (data.byte(kCounttoopen) == 0) data.byte(kLiftflag) = 3; } @@ -426,7 +400,7 @@ void DreamGenContext::liftSprite(Sprite *sprite, SetObject *objData) { turnPathOn(data.byte(kLiftpath)); if (data.byte(kCounttoclose) != 0) { - _dec(data.byte(kCounttoclose)); + data.byte(kCounttoclose)--; if (data.byte(kCounttoclose) == 0) data.byte(kLiftflag) = 2; } @@ -457,86 +431,67 @@ void DreamGenContext::liftSprite(Sprite *sprite, SetObject *objData) { } } -void DreamGenContext::faceRightWay() { - PathNode *paths = getRoomsPaths()->nodes; - uint8 dir = paths[data.byte(kManspath)].dir; - data.byte(kTurntoface) = dir; - data.byte(kLeavedirection) = dir; +Reel *DreamBase::getReelStart(uint16 reelPointer) { + Reel *reel = (Reel *)getSegment(data.word(kReels)).ptr(kReellist + reelPointer * sizeof(Reel) * 8, sizeof(Reel)); + return reel; } -// Locate the reel segment (reel1, reel2, reel3) this frame is stored in. -// The return value is a pointer to the start of the segment. -// data.word(kCurrentframe) - data.word(kTakeoff) is the number of the frame -// inside that segment -Frame *DreamGenContext::findSource() { - uint16 currentFrame = data.word(kCurrentframe); - if (currentFrame < 160) { - data.word(kTakeoff) = 0; - return (Frame *)getSegment(data.word(kReel1)).ptr(0, 0); - } else if (currentFrame < 320) { - data.word(kTakeoff) = 160; - return (Frame *)getSegment(data.word(kReel2)).ptr(0, 0); +// Locate the reel segment (reel1, reel2, reel3) this frame is stored in, +// and adjust the frame number relative to this segment. +const Frame *DreamBase::findSource(uint16 &frame) { + uint16 base; + if (frame < 160) { + base = data.word(kReel1); + } else if (frame < 320) { + frame -= 160; + base = data.word(kReel2); } else { - data.word(kTakeoff) = 320; - return (Frame *)getSegment(data.word(kReel3)).ptr(0, 0); + frame -= 320; + base = data.word(kReel3); } + return (const Frame *)getSegment(base).ptr(0, (frame+1)*sizeof(Frame)); } -Reel *DreamGenContext::getReelStart() { - Reel *reel = (Reel *)getSegment(data.word(kReels)).ptr(kReellist + data.word(kReelpointer) * sizeof(Reel) * 8, sizeof(Reel)); - return reel; -} - -void DreamGenContext::showReelFrame(Reel *reel) { +void DreamBase::showReelFrame(Reel *reel) { uint16 x = reel->x + data.word(kMapadx); uint16 y = reel->y + data.word(kMapady); - data.word(kCurrentframe) = reel->frame(); - Frame *source = findSource(); - uint16 frame = data.word(kCurrentframe) - data.word(kTakeoff); - showFrame(source, x, y, frame, 8); -} - -void DreamGenContext::showGameReel() { - showGameReel((ReelRoutine *)es.ptr(bx, sizeof(ReelRoutine))); + uint16 frame = reel->frame(); + const Frame *base = findSource(frame); + showFrame(base, x, y, frame, 8); } -void DreamGenContext::showGameReel(ReelRoutine *routine) { +void DreamBase::showGameReel(ReelRoutine *routine) { uint16 reelPointer = routine->reelPointer(); if (reelPointer >= 512) return; - data.word(kReelpointer) = reelPointer; - plotReel(); - routine->setReelPointer(data.word(kReelpointer)); + plotReel(reelPointer); + routine->setReelPointer(reelPointer); } -const Frame *DreamGenContext::getReelFrameAX(uint16 frame) { - data.word(kCurrentframe) = frame; - Frame *source = findSource(); - uint16 offset = data.word(kCurrentframe) - data.word(kTakeoff); - return source + offset; +const Frame *DreamBase::getReelFrameAX(uint16 frame) { + const Frame *base = findSource(frame); + return base + frame; } -void DreamGenContext::showRain() { +void DreamBase::showRain() { Rain *rain = (Rain *)getSegment(data.word(kBuffers)).ptr(kRainlist, 0); // Do nothing if there's no rain at all if (rain->x == 255) return; - ds = data.word(kMainsprites); - si = 6*58; // Frame 58 - ax = ds.word(si+2); // Frame::ptr - si = ax + 2080; + const Frame *frame = (const Frame *)getSegment(data.word(kMainsprites)).ptr(58 * sizeof(Frame), sizeof(Frame)); + const uint8 *frameData = getSegment(data.word(kMainsprites)).ptr(kFrframes + frame->ptr(), 512); for (; rain->x != 255; ++rain) { uint16 y = rain->y + data.word(kMapady) + data.word(kMapystart); uint16 x = rain->x + data.word(kMapadx) + data.word(kMapxstart); uint16 size = rain->size; - ax = ((uint16)(rain->w3() - rain->b5)) & 511; - rain->setW3(ax); - const uint8 *src = ds.ptr(si, 0) + ax; + uint16 offset = (rain->w3() - rain->b5) & 511; + rain->setW3(offset); + const uint8 *src = frameData + offset; uint8 *dst = workspace() + y * 320 + x; - for(uint16 i = 0; i < size; ++i) { + for (uint16 i = 0; i < size; ++i) { uint8 v = src[i]; if (v != 0) *dst = v; @@ -562,7 +517,7 @@ void DreamGenContext::showRain() { playChannel1(soundIndex); } -void DreamGenContext::moveMap(uint8 param) { +void DreamBase::moveMap(uint8 param) { switch (param) { case 32: data.byte(kMapy) -= 20; @@ -594,7 +549,7 @@ void DreamGenContext::checkOne() { al = type; } -void DreamGenContext::checkOne(uint8 x, uint8 y, uint8 *flag, uint8 *flagEx, uint8 *type, uint8 *flagX, uint8 *flagY) { +void DreamBase::checkOne(uint8 x, uint8 y, uint8 *flag, uint8 *flagEx, uint8 *type, uint8 *flagX, uint8 *flagY) { *flagX = x / 16; *flagY = y / 16; const uint8 *tileData = getSegment(data.word(kBuffers)).ptr(kMapflags + (*flagY * 11 + *flagX) * 3, 3); @@ -603,11 +558,7 @@ void DreamGenContext::checkOne(uint8 x, uint8 y, uint8 *flag, uint8 *flagEx, uin *type = tileData[2]; } -void DreamGenContext::getBlockOfPixel() { - al = getBlockOfPixel(cl, ch); -} - -uint8 DreamGenContext::getBlockOfPixel(uint8 x, uint8 y) { +uint8 DreamBase::getBlockOfPixel(uint8 x, uint8 y) { uint8 flag, flagEx, type, flagX, flagY; checkOne(x + data.word(kMapxstart), y + data.word(kMapystart), &flag, &flagEx, &type, &flagX, &flagY); if (flag & 1) @@ -616,7 +567,7 @@ uint8 DreamGenContext::getBlockOfPixel(uint8 x, uint8 y) { return type; } -Rain *DreamGenContext::splitIntoLines(uint8 x, uint8 y, Rain *rain) { +Rain *DreamBase::splitIntoLines(uint8 x, uint8 y, Rain *rain) { do { // Look for line start while (!getBlockOfPixel(x, y)) { @@ -687,7 +638,7 @@ static const RainLocation rainLocationList[] = { { 255,0,0,0 } }; -void DreamGenContext::initRain() { +void DreamBase::initRain() { const RainLocation *r = rainLocationList; Rain *rainList = (Rain *)getSegment(data.word(kBuffers)).ptr(kRainlist, 0); Rain *rain = rainList; @@ -742,7 +693,7 @@ void DreamGenContext::initRain() { rain->x = 0xff; } -void DreamGenContext::intro1Text() { +void DreamBase::intro1Text() { if (data.byte(kIntrocount) != 2 && data.byte(kIntrocount) != 4 && data.byte(kIntrocount) != 6) return; @@ -758,21 +709,65 @@ void DreamGenContext::intro1Text() { } } -void DreamGenContext::intro2Text() { - if (ax == 5) +void DreamBase::intro2Text(uint16 nextReelPointer) { + if (nextReelPointer == 5) setupTimedTemp(43, 82, 34, 40, 90, 1); - else if (ax == 15) + else if (nextReelPointer == 15) setupTimedTemp(44, 82, 34, 40, 90, 1); } -void DreamGenContext::intro3Text() { - if (ax == 107) +void DreamBase::intro3Text(uint16 nextReelPointer) { + if (nextReelPointer == 107) setupTimedTemp(45, 82, 36, 56, 100, 1); - else if (ax == (isCD() ? 108 : 109)) + else if (nextReelPointer == (isCD() ? 108 : 109)) setupTimedTemp(46, 82, 36, 56, 100, 1); } -void DreamGenContext::monks2text() { +void DreamBase::rollEndCredits() { + playChannel0(16, 255); + data.byte(kVolume) = 7; + data.byte(kVolumeto) = 0; + data.byte(kVolumedirection) = (byte)-1; + + multiGet(mapStore(), 75, 20, 160, 160); + + const uint8 *string = getTextInFile1(3); + const int linespacing = data.word(kLinespacing); + + for (int i = 0; i < 254; ++i) { + // Output the text, initially with an offset of 10 pixels, + // then move it up one pixel until we shifted it by a complete + // line of text. + for (int j = 0; j < linespacing; ++j) { + vSync(); + multiPut(mapStore(), 75, 20, 160, 160); + vSync(); + + // Output up to 18 lines of text + uint16 y = 10 - j; + const uint8 *tmp_str = string; + for (int k = 0; k < 18; ++k) { + DreamBase::printDirect(&tmp_str, 75, &y, 160 + 1, true); + y += linespacing; + } + + vSync(); + multiDump(75, 20, 160, 160); + } + + // Skip to the next text line + byte c; + do { + c = *string++; + } while (c != ':' && c != 0); + } + hangOn(100); + panelToMap(); + fadeScreenUpHalf(); +} + + +void DreamBase::monks2text() { bool isGermanCD = isCD() && engine->getLanguage() == Common::DE_DEU; if (data.byte(kIntrocount) == 1) @@ -809,7 +804,7 @@ void DreamGenContext::monks2text() { setupTimedTemp(18, 82, 36, 160, 120, 1); } -void DreamGenContext::textForEnd() { +void DreamBase::textForEnd() { if (data.byte(kIntrocount) == 20) setupTimedTemp(0, 83, 34, 20, 60, 1); else if (data.byte(kIntrocount) == (isCD() ? 50 : 65)) @@ -818,14 +813,14 @@ void DreamGenContext::textForEnd() { setupTimedTemp(2, 83, 34, 20, 60, 1); } -void DreamGenContext::textForMonkHelper(uint8 textIndex, uint8 voiceIndex, uint8 x, uint8 y, uint16 countToTimed, uint16 timeCount) { +void DreamBase::textForMonkHelper(uint8 textIndex, uint8 voiceIndex, uint8 x, uint8 y, uint16 countToTimed, uint16 timeCount) { if (isCD() && data.byte(kCh1playing) != 255) data.byte(kIntrocount)--; else setupTimedTemp(textIndex, voiceIndex, x, y, countToTimed, timeCount); } -void DreamGenContext::textForMonk() { +void DreamBase::textForMonk() { if (data.byte(kIntrocount) == 1) textForMonkHelper(19, 82, 68, 154, 120, 1); else if (data.byte(kIntrocount) == 5) @@ -861,7 +856,7 @@ void DreamGenContext::textForMonk() { } } -void DreamGenContext::reelsOnScreen() { +void DreamBase::reelsOnScreen() { reconstruct(); updatePeople(); watchReel(); @@ -869,7 +864,7 @@ void DreamGenContext::reelsOnScreen() { useTimedText(); } -void DreamGenContext::reconstruct() { +void DreamBase::reconstruct() { if (data.byte(kHavedoneobs) == 0) return; data.byte(kNewobs) = 1; @@ -1133,14 +1128,14 @@ static const ReelSound *g_roomByRoom[] = { }; -void DreamGenContext::soundOnReels() { +void DreamBase::soundOnReels(uint16 reelPointer) { const ReelSound *r = g_roomByRoom[data.byte(kReallocation)]; if (engine->getLanguage() == Common::DE_DEU && r == g_roomSound29) r = g_roomSound29_German; for (; r->_sample != 255; ++r) { - if (r->_reelPointer != data.word(kReelpointer)) + if (r->_reelPointer != reelPointer) continue; if (r->_reelPointer == data.word(kLastsoundreel)) continue; @@ -1156,11 +1151,11 @@ void DreamGenContext::soundOnReels() { playChannel0(r->_sample & 63, 255); } - if (data.word(kReelpointer) != data.word(kLastsoundreel)) + if (data.word(kLastsoundreel) != reelPointer) data.word(kLastsoundreel) = (uint16)-1; } -void DreamGenContext::clearBeforeLoad() { +void DreamBase::clearBeforeLoad() { if (data.byte(kRoomloaded) != 1) return /* (noclear) */; @@ -1182,13 +1177,13 @@ void DreamGenContext::clearBeforeLoad() { data.byte(kRoomloaded) = 0; } -void DreamGenContext::clearReels() { +void DreamBase::clearReels() { deallocateMem(data.word(kReel1)); deallocateMem(data.word(kReel2)); deallocateMem(data.word(kReel3)); } -void DreamGenContext::getRidOfReels() { +void DreamBase::getRidOfReels() { if (data.byte(kRoomloaded) == 0) return /* (dontgetrid) */; @@ -1197,11 +1192,68 @@ void DreamGenContext::getRidOfReels() { deallocateMem(data.word(kReel3)); } -void DreamGenContext::liftNoise(uint8 index) { +void DreamBase::liftNoise(uint8 index) { if (data.byte(kReallocation) == 5 || data.byte(kReallocation) == 21) playChannel1(13); // hiss noise else playChannel1(index); } +void DreamBase::checkForExit(Sprite *sprite) { + uint8 flag, flagEx, type, flagX, flagY; + checkOne(data.byte(kRyanx) + 12, data.byte(kRyany) + 12, &flag, &flagEx, &type, &flagX, &flagY); + data.byte(kLastflag) = flag; + + if (flag & 64) { + data.byte(kAutolocation) = flagEx; + return; + } + + if (!(flag & 32)) { + if (flag & 4) { + // adjust left + data.byte(kLastflag) = 0; + data.byte(kMapx) -= 11; + sprite->x = 16 * flagEx; + data.byte(kNowinnewroom) = 1; + } else if (flag & 2) { + // adjust right + data.byte(kMapx) += 11; + sprite->x = 16 * flagEx - 2; + data.byte(kNowinnewroom) = 1; + } else if (flag & 8) { + // adjust down + data.byte(kMapy) += 10; + sprite->y = 16 * flagEx; + data.byte(kNowinnewroom) = 1; + } else if (flag & 16) { + // adjust up + data.byte(kMapy) -= 10; + sprite->y = 16 * flagEx; + data.byte(kNowinnewroom) = 1; + } + + return; + } + + if (data.byte(kReallocation) == 2) { + // Can't leave Louis' until you found shoes + + int shoeCount = 0; + if (isRyanHolding("WETA")) shoeCount++; + if (isRyanHolding("WETB")) shoeCount++; + + if (shoeCount < 2) { + uint8 text = shoeCount ? 43 : 42; + setupTimedUse(text, 80, 10, 68, 64); + + data.byte(kTurntoface) = (data.byte(kFacing) + 4) & 7; + return; + } + + } + + data.byte(kNeedtotravel) = 1; +} + } // End of namespace DreamGen |