diff options
Diffstat (limited to 'engines/dreamweb/sprite.cpp')
-rw-r--r-- | engines/dreamweb/sprite.cpp | 176 |
1 files changed, 57 insertions, 119 deletions
diff --git a/engines/dreamweb/sprite.cpp b/engines/dreamweb/sprite.cpp index cc6b09fd68..f23804b395 100644 --- a/engines/dreamweb/sprite.cpp +++ b/engines/dreamweb/sprite.cpp @@ -24,18 +24,12 @@ namespace DreamGen { -Sprite *DreamBase::spriteTable() { - Sprite *sprite = (Sprite *)getSegment(data.word(kBuffers)).ptr(kSpritetable, 16 * sizeof(Sprite)); - return sprite; -} - void DreamBase::printSprites() { for (size_t priority = 0; priority < 7; ++priority) { - Sprite *sprites = spriteTable(); - for (size_t j = 0; j < 16; ++j) { - const Sprite &sprite = sprites[j]; - if (sprite.updateCallback() == 0x0ffff) - continue; + Common::List<Sprite>::const_iterator i; + for (i = _spriteTable.begin(); i != _spriteTable.end(); ++i) { + const Sprite &sprite = *i; + assert(sprite._updateCallback != 0x0ffff); if (priority != sprite.priority) continue; if (sprite.hidden == 1) @@ -64,24 +58,27 @@ void DreamBase::printASprite(const Sprite *sprite) { c = 8; else c = 0; - showFrame((const Frame *)getSegment(sprite->frameData()).ptr(0, 0), x, y, sprite->frameNumber, c); + showFrame((const Frame *)getSegment(sprite->_frameData).ptr(0, 0), x, y, sprite->frameNumber, c); } void DreamBase::clearSprites() { - memset(spriteTable(), 0xff, sizeof(Sprite) * 16); + _spriteTable.clear(); } 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; - } + // Note: the original didn't append sprites here, but filled up the + // first unused entry. This can change the order of entries, but since they + // are drawn based on the priority field, this shouldn't matter. + _spriteTable.push_back(Sprite()); + Sprite *sprite = &_spriteTable.back(); + + memset(sprite, 0xff, sizeof(Sprite)); - sprite->setUpdateCallback(updateCallback); + sprite->_updateCallback = updateCallback; sprite->x = x; sprite->y = y; - sprite->setFrameData(frameData); - WRITE_LE_UINT16(&sprite->w8, somethingInDi); + sprite->_frameData = frameData; + sprite->w8 = somethingInDi; sprite->w2 = 0xffff; sprite->frameNumber = 0; sprite->delay = 0; @@ -89,25 +86,25 @@ Sprite *DreamBase::makeSprite(uint8 x, uint8 y, uint16 updateCallback, uint16 fr } void DreamBase::spriteUpdate() { - Sprite *sprites = spriteTable(); - sprites[0].hidden = data.byte(kRyanon); - - Sprite *sprite = sprites; - for (size_t i=0; i < 16; ++i) { - uint16 updateCallback = sprite->updateCallback(); - if (updateCallback != 0xffff) { - sprite->w24 = sprite->w2; - if (updateCallback == addr_mainman) // NB : Let's consider the callback as an enum while more code is not ported to C++ - mainMan(sprite); - else { - assert(updateCallback == addr_backobject); - backObject(sprite); - } + // During the intro the sprite table can be empty + if (!_spriteTable.empty()) + _spriteTable.front().hidden = data.byte(kRyanon); + + Common::List<Sprite>::iterator i; + for (i = _spriteTable.begin(); i != _spriteTable.end(); ++i) { + Sprite &sprite = *i; + assert(sprite._updateCallback != 0xffff); + + sprite.w24 = sprite.w2; + if (sprite._updateCallback == addr_mainman) // NB : Let's consider the callback as an enum while more code is not ported to C++ + mainMan(&sprite); + else { + assert(sprite._updateCallback == addr_backobject); + backObject(&sprite); } if (data.byte(kNowinnewroom) == 1) break; - ++sprite; } } @@ -228,7 +225,7 @@ void DreamBase::aboutTurn(Sprite *sprite) { } void DreamBase::backObject(Sprite *sprite) { - SetObject *objData = (SetObject *)getSegment(data.word(kSetdat)).ptr(sprite->objData(), 0); + SetObject *objData = (SetObject *)getSegment(data.word(kSetdat)).ptr(sprite->_objData, 0); if (sprite->delay != 0) { --sprite->delay; @@ -474,25 +471,26 @@ const Frame *DreamBase::getReelFrameAX(uint16 frame) { } void DreamBase::showRain() { - Rain *rain = (Rain *)getSegment(data.word(kBuffers)).ptr(kRainlist, 0); + Common::List<Rain>::iterator i; // Do nothing if there's no rain at all - if (rain->x == 255) + if (_rainList.empty()) return; 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; - uint16 offset = (rain->w3() - rain->b5) & 511; - rain->setW3(offset); + for (i = _rainList.begin(); i != _rainList.end(); ++i) { + Rain &rain = *i; + uint16 y = rain.y + data.word(kMapady) + data.word(kMapystart); + uint16 x = rain.x + data.word(kMapadx) + data.word(kMapxstart); + uint16 size = rain.size; + uint16 offset = (rain.w3 - rain.b5) & 511; + rain.w3 = offset; const uint8 *src = frameData + offset; uint8 *dst = workspace() + y * 320 + x; - for (uint16 i = 0; i < size; ++i) { - uint8 v = src[i]; + for (uint16 j = 0; j < size; ++j) { + uint8 v = src[j]; if (v != 0) *dst = v; dst += 320-1; // advance diagonally @@ -538,21 +536,10 @@ void DreamBase::moveMap(uint8 param) { data.byte(kNowinnewroom) = 1; } -void DreamGenContext::checkOne() { - uint8 flag, flagEx, type, flagX, flagY; - checkOne(cl, ch, &flag, &flagEx, &type, &flagX, &flagY); - - cl = flag; - ch = flagEx; - dl = flagX; - dh = flagY; - al = type; -} - 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); + const uint8 *tileData = &_mapFlags[(*flagY * 11 + *flagX) * 3]; *flag = tileData[0]; *flagEx = tileData[1]; *type = tileData[2]; @@ -567,18 +554,20 @@ uint8 DreamBase::getBlockOfPixel(uint8 x, uint8 y) { return type; } -Rain *DreamBase::splitIntoLines(uint8 x, uint8 y, Rain *rain) { +void DreamBase::splitIntoLines(uint8 x, uint8 y) { do { + Rain rain; + // Look for line start while (!getBlockOfPixel(x, y)) { --x; ++y; if (x == 0 || y >= data.byte(kMapysize)) - return rain; + return; } - rain->x = x; - rain->y = y; + rain.x = x; + rain.y = y; uint8 length = 1; @@ -591,14 +580,11 @@ Rain *DreamBase::splitIntoLines(uint8 x, uint8 y, Rain *rain) { ++length; } - rain->size = length; - rain->w3_lo = engine->randomNumber(); - rain->w3_hi = engine->randomNumber(); - rain->b5 = (engine->randomNumber() & 3) + 4; - ++rain; + rain.size = length; + rain.w3 = (engine->randomNumber() << 8) | engine->randomNumber(); + rain.b5 = (engine->randomNumber() & 3) + 4; + _rainList.push_back(rain); } while (x > 0 && y < data.byte(kMapysize)); - - return rain; } struct RainLocation { @@ -640,8 +626,7 @@ static const RainLocation rainLocationList[] = { void DreamBase::initRain() { const RainLocation *r = rainLocationList; - Rain *rainList = (Rain *)getSegment(data.word(kBuffers)).ptr(kRainlist, 0); - Rain *rain = rainList; + _rainList.clear(); uint8 rainSpacing = 0; @@ -656,7 +641,6 @@ void DreamBase::initRain() { if (rainSpacing == 0) { // location not found in rainLocationList: no rain - rain->x = 0xff; return; } @@ -672,7 +656,7 @@ void DreamBase::initRain() { if (x >= data.byte(kMapxsize)) break; - rain = splitIntoLines(x, 0, rain); + splitIntoLines(x, 0); } while (true); // start lines of rain from side of screen @@ -687,10 +671,8 @@ void DreamBase::initRain() { if (y >= data.byte(kMapysize)) break; - rain = splitIntoLines(data.byte(kMapxsize) - 1, y, rain); + splitIntoLines(data.byte(kMapxsize) - 1, y); } while (true); - - rain->x = 0xff; } void DreamBase::intro1Text() { @@ -723,50 +705,6 @@ void DreamBase::intro3Text(uint16 nextReelPointer) { setupTimedTemp(46, 82, 36, 56, 100, 1); } -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; |