diff options
Diffstat (limited to 'engines')
-rw-r--r-- | engines/dreamweb/dreamgen.cpp | 221 | ||||
-rw-r--r-- | engines/dreamweb/dreamgen.h | 12 | ||||
-rw-r--r-- | engines/dreamweb/module.mk | 2 | ||||
-rw-r--r-- | engines/dreamweb/print.cpp | 251 | ||||
-rw-r--r-- | engines/dreamweb/sprite.cpp | 533 | ||||
-rw-r--r-- | engines/dreamweb/structs.h | 3 | ||||
-rw-r--r-- | engines/dreamweb/stubs.cpp | 791 | ||||
-rw-r--r-- | engines/dreamweb/stubs.h | 17 |
8 files changed, 870 insertions, 960 deletions
diff --git a/engines/dreamweb/dreamgen.cpp b/engines/dreamweb/dreamgen.cpp index c05cab5238..9fa7f16995 100644 --- a/engines/dreamweb/dreamgen.cpp +++ b/engines/dreamweb/dreamgen.cpp @@ -2395,24 +2395,6 @@ decdir: es.byte(bx+29) = 0; } -void DreamGenContext::facerightway() { - STACK_CHECK; - push(es); - push(bx); - getroomspaths(); - al = data.byte(kManspath); - ah = 0; - _add(ax, ax); - _add(ax, ax); - _add(ax, ax); - _add(bx, ax); - al = es.byte(bx+7); - data.byte(kTurntoface) = al; - data.byte(kLeavedirection) = al; - bx = pop(); - es = pop(); -} - void DreamGenContext::checkforexit() { STACK_CHECK; cl = data.byte(kRyanx); @@ -2984,160 +2966,6 @@ void DreamGenContext::widedoor() { dodoor(); } -void DreamGenContext::lockeddoorway() { - STACK_CHECK; - al = data.byte(kRyanx); - ah = data.byte(kRyany); - cl = es.byte(bx+10); - ch = es.byte(bx+11); - _cmp(al, cl); - if (!flags.c()) - goto rtofdoor2; - _sub(al, cl); - _cmp(al, -24); - if (!flags.c()) - goto upordown2; - goto shutdoor2; -rtofdoor2: - _sub(al, cl); - _cmp(al, 10); - if (!flags.c()) - goto shutdoor2; -upordown2: - _cmp(ah, ch); - if (!flags.c()) - goto botofdoor2; - _sub(ah, ch); - _cmp(ah, -30); - if (flags.c()) - goto shutdoor2; - goto opendoor2; -botofdoor2: - _sub(ah, ch); - _cmp(ah, 12); - if (!flags.c()) - goto shutdoor2; -opendoor2: - _cmp(data.byte(kThroughdoor), 1); - if (flags.z()) - goto mustbeopen; - _cmp(data.byte(kLockstatus), 1); - if (flags.z()) - goto shutdoor; -mustbeopen: - cl = es.byte(bx+19); - _cmp(cl, 1); - if (!flags.z()) - goto notdoorsound4; - al = 0; - playchannel1(); -notdoorsound4: - _cmp(cl, 6); - if (!flags.z()) - goto noturnonyet; - al = data.byte(kDoorpath); - push(es); - push(bx); - turnpathon(); - bx = pop(); - es = pop(); -noturnonyet: - cl = es.byte(bx+19); - _cmp(data.byte(kThroughdoor), 1); - if (!flags.z()) - goto notthrough2; - _cmp(cl, 0); - if (!flags.z()) - goto notthrough2; - cl = 6; -notthrough2: - _inc(cl); - ch = 0; - push(di); - _add(di, cx); - al = ds.byte(di+18); - _cmp(al, 255); - if (!flags.z()) - goto atlast3; - _dec(di); - _dec(cl); -atlast3: - es.byte(bx+19) = cl; - al = ds.byte(di+18); - di = pop(); - es.byte(bx+15) = al; - ds.byte(di+17) = al; - _cmp(cl, 5); - if (!flags.z()) - return /* (justshutting) */; - data.byte(kThroughdoor) = 1; - return; -shutdoor2: - cl = es.byte(bx+19); - _cmp(cl, 5); - if (!flags.z()) - goto notdoorsound3; - al = 1; - playchannel1(); -notdoorsound3: - _cmp(cl, 0); - if (flags.z()) - goto atlast4; - _dec(cl); - es.byte(bx+19) = cl; -atlast4: - ch = 0; - data.byte(kThroughdoor) = 0; - push(di); - _add(di, cx); - al = ds.byte(di+18); - di = pop(); - es.byte(bx+15) = al; - ds.byte(di+17) = al; - _cmp(cl, 0); - if (!flags.z()) - return /* (notlocky) */; - al = data.byte(kDoorpath); - push(es); - push(bx); - turnpathoff(); - bx = pop(); - es = pop(); - data.byte(kLockstatus) = 1; - return; -/*continuing to unbounded code: shutdoor from dodoor:60-87*/ -shutdoor: - cl = es.byte(bx+19); - _cmp(cl, 5); - if (!flags.z()) - goto notdoorsound1; - al = 1; - _cmp(data.byte(kReallocation), 5); - if (!flags.z()) - goto nothoteldoor1; - al = 13; -nothoteldoor1: - playchannel1(); -notdoorsound1: - _cmp(cl, 0); - if (flags.z()) - goto atlast2; - _dec(cl); - es.byte(bx+19) = cl; -atlast2: - ch = 0; - push(di); - _add(di, cx); - al = ds.byte(di+18); - di = pop(); - es.byte(bx+15) = al; - ds.byte(di+17) = al; - _cmp(cl, 5); - if (!flags.z()) - return /* (notnearly) */; - data.byte(kThroughdoor) = 0; -} - void DreamGenContext::updatepeople() { STACK_CHECK; es = data.word(kBuffers); @@ -7648,40 +7476,6 @@ blankframe: goto showobsloop; } -void DreamGenContext::makebackob() { - STACK_CHECK; - _cmp(data.byte(kNewobs), 0); - if (flags.z()) - return /* (nomake) */; - al = es.byte(si+5); - ah = es.byte(si+8); - push(si); - push(ax); - push(si); - ax = data.word(kObjectx); - bx = data.word(kObjecty); - ah = bl; - si = ax; - cx = 49520; - dx = data.word(kSetframes); - di = (0); - makesprite(); - ax = pop(); - es.word(bx+20) = ax; - ax = pop(); - _cmp(al, 255); - if (!flags.z()) - goto usedpriority; - al = 0; -usedpriority: - es.byte(bx+23) = al; - es.byte(bx+30) = ah; - es.byte(bx+16) = 0; - es.byte(bx+18) = 0; - es.byte(bx+19) = 0; - si = pop(); -} - void DreamGenContext::showallfree() { STACK_CHECK; es = data.word(kBuffers); @@ -18720,17 +18514,6 @@ success: data.byte(kTurndirection) = 0; } -void DreamGenContext::getroomspaths() { - STACK_CHECK; - al = data.byte(kRoomnum); - ah = 0; - cx = 144; - _mul(cx); - es = data.word(kReels); - bx = (0); - _add(bx, ax); -} - void DreamGenContext::copyname() { STACK_CHECK; push(di); @@ -21062,7 +20845,6 @@ void DreamGenContext::__dispatch_call(uint16 addr) { case addr_findsource: findsource(); break; case addr_mainman: mainman(); break; case addr_aboutturn: aboutturn(); break; - case addr_facerightway: facerightway(); break; case addr_checkforexit: checkforexit(); break; case addr_adjustdown: adjustdown(); break; case addr_adjustup: adjustup(); break; @@ -21080,7 +20862,6 @@ void DreamGenContext::__dispatch_call(uint16 addr) { case addr_constant: constant(); break; case addr_doorway: doorway(); break; case addr_widedoor: widedoor(); break; - case addr_lockeddoorway: lockeddoorway(); break; case addr_updatepeople: updatepeople(); break; case addr_getreelframeax: getreelframeax(); break; case addr_reelsonscreen: reelsonscreen(); break; @@ -21231,7 +21012,6 @@ void DreamGenContext::__dispatch_call(uint16 addr) { case addr_addlength: addlength(); break; case addr_drawflags: drawflags(); break; case addr_showallobs: showallobs(); break; - case addr_makebackob: makebackob(); break; case addr_showallfree: showallfree(); break; case addr_showallex: showallex(); break; case addr_calcfrframe: calcfrframe(); break; @@ -21612,7 +21392,6 @@ void DreamGenContext::__dispatch_call(uint16 addr) { case addr_checkdest: checkdest(); break; case addr_bresenhams: bresenhams(); break; case addr_workoutframes: workoutframes(); break; - case addr_getroomspaths: getroomspaths(); break; case addr_copyname: copyname(); break; case addr_findobname: findobname(); break; case addr_showicon: showicon(); break; diff --git a/engines/dreamweb/dreamgen.h b/engines/dreamweb/dreamgen.h index c2aa204942..2b7149621b 100644 --- a/engines/dreamweb/dreamgen.h +++ b/engines/dreamweb/dreamgen.h @@ -123,7 +123,6 @@ public: static const uint16 addr_showicon = 0xca64; static const uint16 addr_findobname = 0xca60; static const uint16 addr_copyname = 0xca5c; - static const uint16 addr_getroomspaths = 0xca58; static const uint16 addr_workoutframes = 0xca54; static const uint16 addr_bresenhams = 0xca50; static const uint16 addr_checkdest = 0xca4c; @@ -506,7 +505,6 @@ public: static const uint16 addr_calcfrframe = 0xc454; static const uint16 addr_showallex = 0xc450; static const uint16 addr_showallfree = 0xc44c; - static const uint16 addr_makebackob = 0xc448; static const uint16 addr_showallobs = 0xc444; static const uint16 addr_drawflags = 0xc43c; static const uint16 addr_addlength = 0xc438; @@ -657,7 +655,6 @@ public: static const uint16 addr_reelsonscreen = 0xc1a0; static const uint16 addr_getreelframeax = 0xc19c; static const uint16 addr_updatepeople = 0xc198; - static const uint16 addr_lockeddoorway = 0xc194; static const uint16 addr_widedoor = 0xc18c; static const uint16 addr_doorway = 0xc188; static const uint16 addr_constant = 0xc184; @@ -675,7 +672,6 @@ public: static const uint16 addr_adjustup = 0xc150; static const uint16 addr_adjustdown = 0xc14c; static const uint16 addr_checkforexit = 0xc148; - static const uint16 addr_facerightway = 0xc144; static const uint16 addr_aboutturn = 0xc13c; static const uint16 addr_mainman = 0xc138; static const uint16 addr_findsource = 0xc130; @@ -1338,7 +1334,7 @@ public: void clearbuffers(); void neterror(); void storeit(); - void lockeddoorway(); + //void lockeddoorway(); void isitworn(); //void putundertimed(); void dumpmap(); @@ -1514,7 +1510,7 @@ public: void fillopen(); //void usetimedtext(); void delsprite(); - void getroomspaths(); + //void getroomspaths(); //void dumptextline(); void fadescreendownhalf(); void useplate(); @@ -1562,7 +1558,7 @@ public: void discops(); //void printdirect(); void delthisone(); - void makebackob(); + //void makebackob(); void middlepanel(); void dumpwatch(); void saveload(); @@ -1903,7 +1899,7 @@ public: void checkdest(); //void initman(); void loadpalfromiff(); - void facerightway(); + //void facerightway(); void startup1(); void findlen(); void showsymbol(); diff --git a/engines/dreamweb/module.mk b/engines/dreamweb/module.mk index 3b0c7f3325..9c8106db90 100644 --- a/engines/dreamweb/module.mk +++ b/engines/dreamweb/module.mk @@ -5,6 +5,8 @@ MODULE_OBJS := \ detection.o \ dreamweb.o \ dreamgen.o \ + print.o \ + sprite.o \ stubs.o # This module can be built as a plugin diff --git a/engines/dreamweb/print.cpp b/engines/dreamweb/print.cpp new file mode 100644 index 0000000000..882b4578ce --- /dev/null +++ b/engines/dreamweb/print.cpp @@ -0,0 +1,251 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "dreamweb/dreamweb.h" +#include "engines/util.h" +#include "graphics/surface.h" + +namespace DreamGen { + +void DreamGenContext::printboth() { + uint16 x = di; + printboth(ds, &x, bx, al, ah); + di = x; +} + +void DreamGenContext::printboth(uint16 src, uint16 *x, uint16 y, uint8 c, uint8 nextChar) { + uint16 newX = *x; + uint8 width, height; + printchar(src, &newX, y, c, nextChar, &width, &height); + multidump(*x, y, width, height); + *x = newX; +} + +uint8 DreamGenContext::getnextword(const uint8 *string, uint8 *totalWidth, uint8 *charCount) { + *totalWidth = 0; + *charCount = 0; + while(true) { + uint8 firstChar = *string; + ++string; + ++*charCount; + if ((firstChar == ':') || (firstChar == 0)) { //endall + *totalWidth += 6; + return 1; + } + if (firstChar == 32) { //endword + *totalWidth += 6; + return 0; + } + firstChar = engine->modifyChar(firstChar); + if (firstChar != 255) { + uint8 secondChar = *string; + uint8 width = ds.byte(6*(firstChar - 32 + data.word(kCharshift))); + width = kernchars(firstChar, secondChar, width); + *totalWidth += width; + } + } +} + +void DreamGenContext::getnextword() { + uint8 totalWidth, charCount; + al = getnextword(es.ptr(di, 0), &totalWidth, &charCount); + bl = totalWidth; + bh = charCount; + di += charCount; +} + +void DreamGenContext::printchar() { + uint16 x = di; + uint8 width, height; + printchar(ds, &x, bx, al, ah, &width, &height); + di = x; + cl = width; + ch = height; +} + +void DreamGenContext::printchar(uint16 src, uint16* x, uint16 y, uint8 c, uint8 nextChar, uint8 *width, uint8 *height) { + if (c == 255) + return; + push(si); + push(di); + if (data.byte(kForeignrelease) != 0) + y -= 3; + uint16 tmp = c - 32 + data.word(kCharshift); + showframe(src, *x, y, tmp & 0x1ff, (tmp >> 8) & 0xfe, width, height); + di = pop(); + si = pop(); + _cmp(data.byte(kKerning), 0); + if (flags.z()) + *width = kernchars(c, nextChar, *width); + (*x) += *width; +} + +void DreamGenContext::printslow() { + al = printslow(di, bx, dl, (bool)(dl & 1)); +} + +uint8 DreamGenContext::printslow(uint16 x, uint16 y, uint8 maxWidth, bool centered) { + data.byte(kPointerframe) = 1; + data.byte(kPointermode) = 3; + ds = data.word(kCharset1); + do { + uint16 offset = x; + uint16 charCount = getnumber(si, maxWidth, centered, &offset); + do { + push(si); + push(es); + uint8 c0 = es.byte(si); + uint8 c1 = es.byte(si+1); + uint8 c2 = es.byte(si+2); + push(es); + push(ds); + c0 = engine->modifyChar(c0); + printboth(ds, &offset, y, c0, c1); + ds = pop(); + es = pop(); + ++si; + if ((c1 == 0) || (c1 == ':')) { + es = pop(); + si = pop(); + return 0; + } + if (charCount != 1) { + push(ds); + push(es); + c1 = engine->modifyChar(c1); + data.word(kCharshift) = 91; + uint16 offset2 = offset; + printboth(ds, &offset2, y, c1, c2); + data.word(kCharshift) = 0; + es = pop(); + ds = pop(); + for (int i=0; i<2; ++i) { + waitframes(); + if (ax == 0) + continue; + if (ax != data.word(kOldbutton)) { + es = pop(); + si = pop(); + return 1; + } + } + } + + es = pop(); + si = pop(); + ++si; + --charCount; + } while (charCount); + y += 10; + } while (true); +} + +void DreamGenContext::printdirect() { + uint16 y = bx; + printdirect(di, &y, dl, (bool)(dl & 1)); + bx = y; +} + +void DreamGenContext::printdirect(uint16 x, uint16 *y, uint8 maxWidth, bool centered) { + data.word(kLastxpos) = x; + ds = data.word(kCurrentset); + while (true) { + uint16 offset = x; + uint8 charCount = getnumber(si, maxWidth, centered, &offset); + uint16 i = offset; + do { + uint8 c = es.byte(si); + uint8 nextChar = es.byte(si+1); + ++si; + if ((c == 0) || (c == ':')) { + return; + } + c = engine->modifyChar(c); + uint8 width, height; + printchar(ds, &i, *y, c, nextChar, &width, &height); + data.word(kLastxpos) = i; + --charCount; + } while(charCount); + *y += data.word(kLinespacing); + } +} + +void DreamGenContext::getnumber() { + uint16 offset = di; + cl = getnumber(si, dl, (bool)(dl & 1), &offset); + di = offset; +} + +uint8 DreamGenContext::getnumber(uint16 index, uint16 maxWidth, bool centered, uint16* offset) { + uint8 totalWidth = 0; + uint8 charCount = 0; + while (true) { + uint8 wordTotalWidth, wordCharCount; + uint8 done = getnextword(es.ptr(index, 0), &wordTotalWidth, &wordCharCount); + index += wordCharCount; + + if (done == 1) { //endoftext + ax = totalWidth + wordTotalWidth - 10; + if (ax < maxWidth) { + totalWidth += wordTotalWidth; + charCount += wordCharCount; + } + + if (centered) { + ax = (maxWidth & 0xfe) + 2 + 20 - totalWidth; + ax /= 2; + } else { + ax = 0; + } + *offset += ax; + return charCount; + } + ax = totalWidth + wordTotalWidth - 10; + if (ax >= maxWidth) { //gotoverend + if (centered) { + ax = (maxWidth & 0xfe) - totalWidth + 20; + ax /= 2; + } else { + ax = 0; + } + *offset += ax; + return charCount; + } + totalWidth += wordTotalWidth; + charCount += wordCharCount; + } +} + +uint8 DreamGenContext::kernchars(uint8 firstChar, uint8 secondChar, uint8 width) { + if ((firstChar == 'a') || (al == 'u')) { + if ((secondChar == 'n') || (secondChar == 't') || (secondChar == 'r') || (secondChar == 'i') || (secondChar == 'l')) + return width-1; + } + return width; +} + +void DreamGenContext::kernchars() { + cl = kernchars(al, ah, cl); +} + +} /*namespace dreamgen */ + diff --git a/engines/dreamweb/sprite.cpp b/engines/dreamweb/sprite.cpp new file mode 100644 index 0000000000..d6347b62bf --- /dev/null +++ b/engines/dreamweb/sprite.cpp @@ -0,0 +1,533 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "dreamweb/dreamweb.h" +#include "engines/util.h" +#include "graphics/surface.h" + +namespace DreamGen { + +Sprite *DreamGenContext::spritetable() { + push(es); + es = data.word(kBuffers); + Sprite *sprite = (Sprite *)es.ptr(kSpritetable, 16 * sizeof(Sprite)); + es = pop(); + return sprite; +} + +void DreamGenContext::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 (READ_LE_UINT16(&sprite.updateCallback) == 0x0ffff) + continue; + if (priority != sprite.priority) + continue; + if (sprite.hidden == 1) + continue; + printasprite(&sprite); + } + } +} + +void DreamGenContext::printasprite(const Sprite *sprite) { + uint16 x, y; + if (sprite->y >= 220) { + y = data.word(kMapady) - (256 - sprite->y); + } else { + y = sprite->y + data.word(kMapady); + } + + if (sprite->x >= 220) { + x = data.word(kMapadx) - (256 - sprite->x); + } else { + x = sprite->x + data.word(kMapadx); + } + + uint8 c; + if (sprite->b29 != 0) + c = 8; + else + c = 0; + uint8 width, height; + showframe(READ_LE_UINT16(&sprite->w6), x, y, sprite->b15, c, &width, &height); +} + +void DreamGenContext::clearsprites() { + memset(spritetable(), 0xff, sizeof(Sprite) * 16); +} + +Sprite *DreamGenContext::makesprite(uint8 x, uint8 y, uint16 updateCallback, uint16 somethingInDx, uint16 somethingInDi) { + Sprite *sprite = spritetable(); + while (sprite->b15 != 0xff) { // NB: No boundchecking in the original code either + ++sprite; + } + + WRITE_LE_UINT16(&sprite->updateCallback, updateCallback); + sprite->x = x; + sprite->y = y; + WRITE_LE_UINT16(&sprite->w6, somethingInDx); + WRITE_LE_UINT16(&sprite->w8, somethingInDi); + sprite->w2 = 0xffff; + sprite->b15 = 0; + sprite->delay = 0; + return sprite; +} + +void DreamGenContext::makesprite() { // NB: returns new sprite in es:bx + Sprite *sprite = makesprite(si & 0xff, si >> 8, cx, dx, di); + + // Recover es:bx from sprite + es = data.word(kBuffers); + bx = kSpritetable; + Sprite *sprites = (Sprite *)es.ptr(bx, sizeof(Sprite) * 16); + bx += sizeof(Sprite) * (sprite - sprites); + // +} + +void DreamGenContext::spriteupdate() { + Sprite *sprites = spritetable(); + sprites[0].hidden = data.byte(kRyanon); + + Sprite *sprite = sprites; + for (size_t i=0; i < 16; ++i) { + uint16 updateCallback = READ_LE_UINT16(&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++ + mainmanCPP(sprite); + else { + assert(updateCallback == addr_backobject); + backobject(sprite); + } + } + + if (data.byte(kNowinnewroom) == 1) + break; + ++sprite; + } +} + +void DreamGenContext::initman() { + Sprite *sprite = makesprite(data.byte(kRyanx), data.byte(kRyany), addr_mainman, data.word(kMainsprites), 0); + sprite->priority = 4; + sprite->b22 = 0; + sprite->b29 = 0; +} + +void DreamGenContext::mainmanCPP(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); + // + + if (data.byte(kResetmanxy) == 1) { + data.byte(kResetmanxy) = 0; + sprite->x = data.byte(kRyanx); + sprite->y = data.byte(kRyany); + sprite->b29 = 0; + } + --sprite->b22; + if (sprite->b22 != 0xff) { + ds = pop(); + es = pop(); + return; + } + sprite->b22 = 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(); + } + data.byte(kTurndirection) = 0; + if (data.byte(kLinepointer) == 254) { + sprite->b29 = 0; + } else { + ++sprite->b29; + if (sprite->b29 == 11) + sprite->b29 = 1; + walking(sprite); + if (data.byte(kLinepointer) != 254) { + if ((data.byte(kFacing) & 1) == 0) + walking(sprite); + else if ((sprite->b29 != 2) && (sprite->b29 != 7)) + walking(sprite); + } + if (data.byte(kLinepointer) == 254) { + if (data.byte(kTurntoface) == data.byte(kFacing)) { + data.byte(kReasseschanges) = 1; + if (data.byte(kFacing) == data.byte(kLeavedirection)) + checkforexit(); + } + } + } + } + static const uint8 facelist[] = { 0,60,33,71,11,82,22,93 }; + sprite->b15 = sprite->b29 + facelist[data.byte(kFacing)]; + data.byte(kRyanx) = sprite->x; + data.byte(kRyany) = sprite->y; + + ds = pop(); + es = pop(); +} + +void DreamGenContext::walking() { + Sprite *sprite = (Sprite *)es.ptr(bx, sizeof(Sprite)); + walking(sprite); +} + +void DreamGenContext::walking(Sprite *sprite) { + uint8 comp; + if (data.byte(kLinedirection) != 0) { + --data.byte(kLinepointer); + comp = 200; + } else { + ++data.byte(kLinepointer); + comp = data.byte(kLinelength); + } + if (data.byte(kLinepointer) < comp) { + sprite->x = data.byte(kLinedata + data.byte(kLinepointer) * 2 + 0); + sprite->y = data.byte(kLinedata + data.byte(kLinepointer) * 2 + 1); + return; + } + + data.byte(kLinepointer) = 254; + data.byte(kManspath) = data.byte(kDestination); + if (data.byte(kDestination) == data.byte(kFinaldest)) { + facerightway(); + return; + } + data.byte(kDestination) = data.byte(kFinaldest); + push(es); + push(bx); + autosetwalk(); + bx = pop(); + es = pop(); +} + +void DreamGenContext::aboutturn(Sprite *sprite) { + bool incdir = true; + + if (data.byte(kTurndirection) == 1) + incdir = true; + else if ((int8)data.byte(kTurndirection) == -1) + incdir = false; + else { + if (data.byte(kFacing) < data.byte(kTurntoface)) { + uint8 delta = data.byte(kTurntoface) - data.byte(kFacing); + if (delta >= 4) + incdir = false; + else + incdir = true; + } else { + uint8 delta = data.byte(kFacing) - data.byte(kTurntoface); + if (delta >= 4) + incdir = true; + else + incdir = false; + } + } + + if (incdir) { + data.byte(kTurndirection) = 1; + data.byte(kFacing) = (data.byte(kFacing) + 1) & 7; + sprite->b29 = 0; + } else { + data.byte(kTurndirection) = -1; + data.byte(kFacing) = (data.byte(kFacing) - 1) & 7; + sprite->b29 = 0; + } +} + +void DreamGenContext::backobject(Sprite *sprite) { + push(ds); + + ds = data.word(kSetdat); + di = READ_LE_UINT16(&sprite->obj_data); + ObjData *objData = (ObjData *)ds.ptr(di, 0); + + if (sprite->delay != 0) { + --sprite->delay; + ds = pop(); + return; + } + + sprite->delay = objData->delay; + if (objData->type == 6) + widedoor(sprite, objData); + else if (objData->type == 5) + random(sprite, objData); + else if (objData->type == 4) + lockeddoorway(sprite, objData); + else if (objData->type == 3) + liftsprite(sprite, objData); + else if (objData->type == 2) + doorway(sprite, objData); + else if (objData->type == 1) + constant(sprite, objData); + else + steady(sprite, objData); + + ds = pop(); +} + +void DreamGenContext::constant(Sprite *sprite, ObjData *objData) { + ++sprite->frame; + if (objData->b18[sprite->frame] == 255) { + sprite->frame = 0; + } + uint8 b18 = objData->b18[sprite->frame]; + objData->b17 = b18; + sprite->b15 = b18; +} + +void DreamGenContext::random(Sprite *sprite, ObjData *objData) { + randomnum1(); + uint16 r = ax; + sprite->b15 = objData->b18[r&7]; +} + +void DreamGenContext::doorway(Sprite *sprite, ObjData *objData) { + data.byte(kDoorcheck1) = -24; + data.byte(kDoorcheck2) = 10; + data.byte(kDoorcheck3) = -30; + data.byte(kDoorcheck4) = 10; + dodoor(sprite, objData); +} + +void DreamGenContext::widedoor(Sprite *sprite, ObjData *objData) { + data.byte(kDoorcheck1) = -24; + data.byte(kDoorcheck2) = 24; + data.byte(kDoorcheck3) = -30; + data.byte(kDoorcheck4) = 24; + dodoor(sprite, objData); +} + +void DreamGenContext::dodoor() { + Sprite *sprite = (Sprite *)es.ptr(bx, sizeof(Sprite)); + ObjData *objData = (ObjData *)ds.ptr(di, 0); + dodoor(sprite, objData); +} + +void DreamGenContext::dodoor(Sprite *sprite, ObjData *objData) { + uint8 ryanx = data.byte(kRyanx); + uint8 ryany = data.byte(kRyany); + int8 deltax = ryanx - sprite->x; + int8 deltay = ryany - sprite->y; + if (ryanx < sprite->x) { + if (deltax < (int8)data.byte(kDoorcheck1)) + goto shutdoor; + } else { + if (deltax >= data.byte(kDoorcheck2)) + goto shutdoor; + } + if (ryany < sprite->y) { + if (deltay < (int8)data.byte(kDoorcheck3)) + goto shutdoor; + } else { + if (deltay >= data.byte(kDoorcheck4)) + goto shutdoor; + } +//opendoor: + if ((data.byte(kThroughdoor) == 1) && (sprite->frame == 0)) + sprite->frame = 6; + + ++sprite->frame; + if (sprite->frame == 1) { //doorsound2 + if (data.byte(kReallocation) == 5) //hoteldoor2 + al = 13; + else + al = 0; + playchannel1(); + } + if (objData->b18[sprite->frame] == 255) { + --sprite->frame; + } + sprite->b15 = objData->b17 = objData->b18[sprite->frame]; + data.byte(kThroughdoor) = 1; + return; +shutdoor: + if (sprite->frame == 5) { //doorsound1; + if (data.byte(kReallocation) == 5) //hoteldoor1 + al = 13; + else + al = 1; + playchannel1(); + } + if (sprite->frame != 0) { + --sprite->frame; + } + sprite->b15 = objData->b17 = objData->b18[sprite->frame]; + if (sprite->frame == 5) //nearly + data.byte(kThroughdoor) = 0; +} + +void DreamGenContext::steady(Sprite *sprite, ObjData *objData) { + uint8 b18 = objData->b18[0]; + objData->b17 = b18; + sprite->b15 = b18; +} + +void DreamGenContext::lockeddoorway() { + Sprite *sprite = (Sprite *)es.ptr(bx, sizeof(Sprite)); + ObjData *objData = (ObjData *)ds.ptr(di, 0); + lockeddoorway(sprite, objData); +} + +void DreamGenContext::lockeddoorway(Sprite *sprite, ObjData *objData) { + if (data.byte(kRyanx) < sprite->x) { + if (sprite->x - data.byte(kRyanx) > 24) + goto shutdoor2; + } else { + if (data.byte(kRyanx) - sprite->x >= 10) + goto shutdoor2; + } + + if (data.byte(kRyany) < sprite->y) { + if (sprite->y - data.byte(kRyany) > 30) + goto shutdoor2; + } else { + if (data.byte(kRyany) - sprite->y >= 12) + goto shutdoor2; + } + + if (data.byte(kThroughdoor) != 1) { + if (data.byte(kLockstatus) == 1) + goto shutdoor2; + } + + if (sprite->frame == 1) { + al = 0; + playchannel1(); + } + + if (sprite->frame == 6) { + turnpathonCPP(data.byte(kDoorpath)); + } + + if ((data.byte(kThroughdoor) == 1) && (sprite->frame == 0)) { + sprite->frame = 6; + } + + ++sprite->frame; + if (objData->b18[sprite->frame] == 255) { + --sprite->frame; + } + + sprite->b15 = objData->b17 = objData->b18[sprite->frame]; + if (sprite->frame == 5) + data.byte(kThroughdoor) = 1; + return; + +shutdoor2: + if (sprite->frame == 5) { + al = 1; + playchannel1(); + } + + if (sprite->frame != 0) { + --sprite->frame; + } + + data.byte(kThroughdoor) = 0; + sprite->b15 = objData->b17 = objData->b18[sprite->frame]; + + if (sprite->frame == 0) { + turnpathoffCPP(data.byte(kDoorpath)); + data.byte(kLockstatus) = 1; + } +} + +void DreamGenContext::liftsprite() { + Sprite *sprite = (Sprite *)es.ptr(bx, sizeof(Sprite)); + ObjData *objData = (ObjData *)ds.ptr(di, 0); + liftsprite(sprite, objData); +} + +void DreamGenContext::liftsprite(Sprite *sprite, ObjData *objData) { + uint8 liftFlag = data.byte(kLiftflag); + if (liftFlag == 0) { //liftclosed + turnpathoffCPP(data.byte(kLiftpath)); + + if (data.byte(kCounttoopen) != 0) { + _dec(data.byte(kCounttoopen)); + if (data.byte(kCounttoopen) == 0) + data.byte(kLiftflag) = 3; + } + sprite->frame = 0; + sprite->b15 = objData->b17 = objData->b18[sprite->frame]; + } + else if (liftFlag == 1) { //liftopen + turnpathonCPP(data.byte(kLiftpath)); + + if (data.byte(kCounttoclose) != 0) { + _dec(data.byte(kCounttoclose)); + if (data.byte(kCounttoclose) == 0) + data.byte(kLiftflag) = 2; + } + sprite->frame = 12; + sprite->b15 = objData->b17 = objData->b18[sprite->frame]; + } + else if (liftFlag == 3) { //openlift + if (sprite->frame == 12) { + data.byte(kLiftflag) = 1; + return; + } + ++sprite->frame; + if (sprite->frame == 1) { + al = 2; + liftnoise(); + } + sprite->b15 = objData->b17 = objData->b18[sprite->frame]; + } else { //closeLift + assert(liftFlag == 2); + if (sprite->frame == 0) { + data.byte(kLiftflag) = 0; + return; + } + --sprite->frame; + if (sprite->frame == 11) { + al = 3; + liftnoise(); + } + sprite->b15 = objData->b17 = objData->b18[sprite->frame]; + } +} + +void DreamGenContext::facerightway() { + uint8 *paths = getroomspathsCPP(); + uint8 dir = paths[8 * data.byte(kManspath) + 7]; + data.byte(kTurntoface) = dir; + data.byte(kLeavedirection) = dir; +} + +} /*namespace dreamgen */ + diff --git a/engines/dreamweb/structs.h b/engines/dreamweb/structs.h index e274375cf4..ac304ae2c2 100644 --- a/engines/dreamweb/structs.h +++ b/engines/dreamweb/structs.h @@ -31,7 +31,8 @@ struct Sprite { uint16 w12; uint8 b14; uint8 b15; - uint16 w16; + uint8 b16; + uint8 b17; uint8 delay; uint8 frame; uint16 obj_data; diff --git a/engines/dreamweb/stubs.cpp b/engines/dreamweb/stubs.cpp index 3c058259a8..688ad82d92 100644 --- a/engines/dreamweb/stubs.cpp +++ b/engines/dreamweb/stubs.cpp @@ -35,6 +35,14 @@ Common::String getFilename(Context &context) { return name; } +uint8 *DreamGenContext::workspace() { + push(es); + es = data.word(kWorkspace); + uint8 *result = es.ptr(0, 0); + es = pop(); + return result; +} + void DreamGenContext::multiget() { multiget(di, bx, cl, ch); } @@ -97,9 +105,8 @@ void DreamGenContext::multidump() { } void DreamGenContext::worktoscreen() { - ds = data.word(kWorkspace); uint size = 320 * 200; - engine->blit(ds.ptr(0, size), 320, 0, 0, 320, 200); + engine->blit(workspace(), 320, 0, 0, 320, 200); di = si = size; cx = 0; } @@ -246,84 +253,6 @@ void DreamGenContext::setmouse() { data.word(kOldpointerx) = 0xffff; } -void DreamGenContext::printboth() { - uint16 x = di; - printboth(es, ds, &x, bx, al); - di = x; -} - -void DreamGenContext::printboth(uint16 dst, uint16 src, uint16 *x, uint16 y, uint8 c) { - uint16 newX = *x; - uint8 width, height; - printchar(dst, src, &newX, y, c, &width, &height); - multidump(*x, y, width, height); - *x = newX; -} - -uint8 DreamGenContext::getnextword(const uint8 *string, uint8 *totalWidth, uint8 *charCount) { - *totalWidth = 0; - *charCount = 0; - while(true) { - uint8 firstChar = *string; - ++string; - ++*charCount; - if ((firstChar == ':') || (firstChar == 0)) { //endall - *totalWidth += 6; - return 1; - } - if (firstChar == 32) { //endword - *totalWidth += 6; - return 0; - } - firstChar = engine->modifyChar(firstChar); - if (firstChar != 255) { - uint8 secondChar = *string; - uint8 width = ds.byte(6*(firstChar - 32 + data.word(kCharshift))); - width = kernchars(firstChar, secondChar, width); - *totalWidth += width; - } - } -} - -void DreamGenContext::getnextword() { - uint8 totalWidth, charCount; - al = getnextword(es.ptr(di, 0), &totalWidth, &charCount); - bl = totalWidth; - bh = charCount; - di += charCount; -} - -void DreamGenContext::printchar() { - uint16 x = di; - uint8 width, height; - printchar(es, ds, &x, bx, al, &width, &height); - di = x; - cl = width; - ch = height; -} - -void DreamGenContext::printchar(uint16 dst, uint16 src, uint16* x, uint16 y, uint8 c, uint8 *width, uint8 *height) { - if (c == 255) - return; - push(si); - push(di); - push(ax); - if (data.byte(kForeignrelease) != 0) - y -= 3; - showframe(dst, src, *x, y, c - 32 + data.word(kCharshift), 0, width, height); - ax = pop(); - di = pop(); - si = pop(); - _cmp(data.byte(kKerning), 0); - if (flags.z()) - *width = kernchars(c, ah, *width); - (*x) += *width; -} - -void DreamGenContext::printslow() { - al = printslow(di, bx, dl, (bool)(dl & 1)); -} - void DreamGenContext::dumptextline() { if (data.byte(kNewtextline) != 1) return; @@ -335,93 +264,6 @@ void DreamGenContext::dumptextline() { multidump(x, y, 228, 13); } -uint8 DreamGenContext::printslow(uint16 x, uint16 y, uint8 maxWidth, bool centered) { - data.byte(kPointerframe) = 1; - data.byte(kPointermode) = 3; - ds = data.word(kCharset1); - do { - uint16 offset = x; - uint16 charCount = getnumber(si, maxWidth, centered, &offset); - do { - push(si); - push(es); - uint8 c0 = es.byte(si); - push(es); - push(ds); - c0 = engine->modifyChar(c0); - printboth(es, ds, &offset, y, c0); - ds = pop(); - es = pop(); - uint8 c1 = es.byte(si+1); - ++si; - if ((c1 == 0) || (c1 == ':')) { - es = pop(); - si = pop(); - return 0; - } - if (charCount != 1) { - push(ds); - push(es); - c1 = engine->modifyChar(c1); - data.word(kCharshift) = 91; - uint16 offset2 = offset; - printboth(es, ds, &offset2, y, c1); - data.word(kCharshift) = 0; - es = pop(); - ds = pop(); - for (int i=0; i<2; ++i) { - waitframes(); - if (ax == 0) - continue; - if (ax != data.word(kOldbutton)) { - es = pop(); - si = pop(); - return 1; - } - } - } - - es = pop(); - si = pop(); - ++si; - --charCount; - } while (charCount); - y += 10; - } while (true); -} - -void DreamGenContext::printdirect() { - uint16 y = bx; - printdirect(di, &y, dl, (bool)(dl & 1)); - bx = y; -} - -void DreamGenContext::printdirect(uint16 x, uint16 *y, uint8 maxWidth, bool centered) { - data.word(kLastxpos) = x; - ds = data.word(kCurrentset); - while (true) { - uint16 offset = x; - uint8 charCount = getnumber(si, maxWidth, centered, &offset); - uint16 i = offset; - do { - uint8 c = es.byte(si); - ++si; - if ((c == 0) || (c == ':')) { - return; - } - c = engine->modifyChar(c); - ah = es.byte(si); // get next char for kerning - uint8 width, height; - push(es); - printchar(es, ds, &i, *y, c, &width, &height); - es = pop(); - data.word(kLastxpos) = i; - --charCount; - } while(charCount); - *y += data.word(kLinespacing); - } -} - void DreamGenContext::getundertimed() { uint16 y = data.byte(kTimedy); if (data.byte(kForeignrelease)) @@ -462,64 +304,6 @@ void DreamGenContext::usetimedtext() { data.byte(kNeedtodumptimed) = 1; } -void DreamGenContext::getnumber() { - uint16 offset = di; - cl = getnumber(si, dl, (bool)(dl & 1), &offset); - di = offset; -} - -uint8 DreamGenContext::getnumber(uint16 index, uint16 maxWidth, bool centered, uint16* offset) { - uint8 totalWidth = 0; - uint8 charCount = 0; - while (true) { - uint8 wordTotalWidth, wordCharCount; - uint8 done = getnextword(es.ptr(index, 0), &wordTotalWidth, &wordCharCount); - index += wordCharCount; - - if (done == 1) { //endoftext - ax = totalWidth + wordTotalWidth - 10; - if (ax < maxWidth) { - totalWidth += wordTotalWidth; - charCount += wordCharCount; - } - - if (centered) { - ax = (maxWidth & 0xfe) + 2 + 20 - totalWidth; - ax /= 2; - } else { - ax = 0; - } - *offset += ax; - return charCount; - } - ax = totalWidth + wordTotalWidth - 10; - if (ax >= maxWidth) { //gotoverend - if (centered) { - ax = (maxWidth & 0xfe) - totalWidth + 20; - ax /= 2; - } else { - ax = 0; - } - *offset += ax; - return charCount; - } - totalWidth += wordTotalWidth; - charCount += wordCharCount; - } -} - -uint8 DreamGenContext::kernchars(uint8 firstChar, uint8 secondChar, uint8 width) { - if ((firstChar == 'a') || (al == 'u')) { - if ((secondChar == 'n') || (secondChar == 't') || (secondChar == 'r') || (secondChar == 'i') || (secondChar == 'l')) - return width-1; - } - return width; -} - -void DreamGenContext::kernchars() { - cl = kernchars(al, ah, cl); -} - void DreamGenContext::gettime() { TimeDate t; g_system->getTimeAndDate(t); @@ -857,19 +641,6 @@ void DreamGenContext::showpcx() { pcxFile.close(); } -/* -void DreamGenContext::frameoutv() { - uint16 pitch = dx; - uint16 width = cx & 0xff; - uint16 height = cx >> 8; - - const uint8 *src = ds.ptr(si, width * height); - uint8 *dst = es.ptr(0, pitch * height); - - frameoutv(dst, src, pitch, width, height, di, bx); -} -*/ - void DreamGenContext::frameoutv(uint8 *dst, const uint8 *src, uint16 pitch, uint16 width, uint16 height, uint16 x, uint16 y) { // NB : These resilience checks were not in the original engine, but did they result in undefined behaviour // or was something broken during porting to C++? @@ -900,32 +671,11 @@ void DreamGenContext::frameoutv(uint8 *dst, const uint8 *src, uint16 pitch, uint } } -Sprite *DreamGenContext::spritetable() { - push(es); - push(bx); - - es = data.word(kBuffers); - bx = kSpritetable; - Sprite *sprite = (Sprite *)es.ptr(bx, 16 * sizeof(Sprite)); - - bx = pop(); - es = pop(); - - return sprite; -} - -void DreamGenContext::showframe(uint16 dst, uint16 src, uint16 x, uint16 y, uint16 frameNumber, uint8 effectsFlag, uint8 *width, uint8 *height) { - // frameNumber takes up 9 bits of ax, and effectsFlag 7. - assert(!(effectsFlag & 1)); - - es = dst; +void DreamGenContext::showframe(uint16 src, uint16 x, uint16 y, uint16 frameNumber, uint8 effectsFlag, uint8 *width, uint8 *height) { ds = src; - di = x; - bx = y; - ax = frameNumber | (effectsFlag << 8); + ah = effectsFlag; - - si = (ax & 0x1ff) * 6; + si = frameNumber * 6; if (ds.word(si) == 0) { *width = 0; *height = 0; @@ -934,111 +684,59 @@ void DreamGenContext::showframe(uint16 dst, uint16 src, uint16 x, uint16 y, uint //notblankshow: if ((effectsFlag & 128) == 0) { - di += ds.byte(si + 4); - bx += ds.byte(si + 5); + x += ds.byte(si + 4); + y += ds.byte(si + 5); } //skipoffsets: - cx = ds.word(si + 0); - *width = cl; - *height = ch; + + *width = ds.byte(si + 0); + *height = ds.byte(si + 1); si = ds.word(si+2) + 2080; + const uint8 *pSrc = ds.ptr(si, *width * *height); if (effectsFlag) { if (effectsFlag & 128) { //centred - di -= *width / 2; - bx -= *height / 2; + x -= *width / 2; + y -= *height / 2; } if (effectsFlag & 64) { //diffdest - frameoutfx(es.ptr(0, dx * *height), ds.ptr(si, *width * *height), dx, *width, *height, di, bx); + frameoutfx(es.ptr(0, dx * *height), pSrc, dx, *width, *height, x, y); return; } if (effectsFlag & 8) { //printlist + /* push(ax); - ax = di - data.word(kMapadx); - push(bx); - bx -= data.word(kMapady); - ah = bl; - bx = pop(); + al = x - data.word(kMapadx); + ah = y - data.word(kMapady); //addtoprintlist(); // NB: Commented in the original asm ax = pop(); + */ } if (effectsFlag & 4) { //flippedx - es = data.word(kWorkspace); - frameoutfx(es.ptr(0, 320 * *height), ds.ptr(si, *width * *height), 320, *width, *height, di, bx); + frameoutfx(workspace(), pSrc, 320, *width, *height, x, y); return; } if (effectsFlag & 2) { //nomask - es = data.word(kWorkspace); - frameoutnm(es.ptr(0, 320 * *height), ds.ptr(si, *width * *height), 320, *width, *height, di, bx); + frameoutnm(workspace(), pSrc, 320, *width, *height, x, y); return; } if (effectsFlag & 32) { - es = data.word(kWorkspace); - frameoutbh(es.ptr(0, 320 * *height), ds.ptr(si, *width * *height), 320, *width, *height, di, bx); + frameoutbh(workspace(), pSrc, 320, *width, *height, x, y); return; } } //noeffects: - es = data.word(kWorkspace); - frameoutv(es.ptr(0, 65536), ds.ptr(si, *width * *height), 320, *width, *height, di, bx); + frameoutv(workspace(), pSrc, 320, *width, *height, x, y); return; } void DreamGenContext::showframe() { uint8 width, height; - showframe(es, ds, di, bx, ax & 0x1ff, ah & 0xfe, &width, &height); + showframe(ds, di, bx, ax & 0x1ff, ah & 0xfe, &width, &height); cl = width; ch = height; } -void DreamGenContext::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 (READ_LE_UINT16(&sprite.updateCallback) == 0x0ffff) - continue; - if (priority != sprite.priority) - continue; - if (sprite.hidden == 1) - continue; - printasprite(&sprite); - } - } -} - -void DreamGenContext::printasprite(const Sprite *sprite) { - push(es); - push(bx); - ds = READ_LE_UINT16(&sprite->w6); - ax = sprite->y; - if (al >= 220) { - bx = data.word(kMapady) - (256 - al); - } else { - bx = ax + data.word(kMapady); - } - - ax = sprite->x; - if (al >= 220) { - di = data.word(kMapadx) - (256 - al); - } else { - di = ax + data.word(kMapadx); - } - - uint8 c; - if (sprite->b29 != 0) - c = 8; - else - c = 0; - uint8 width, height; - showframe(es, ds, di, bx, sprite->b15, c, &width, &height); - cl = width; - ch = height; - - bx = pop(); - es = pop(); -} - void DreamGenContext::eraseoldobs() { if (data.byte(kNewobs) == 0) return; @@ -1052,343 +750,6 @@ void DreamGenContext::eraseoldobs() { } } -void DreamGenContext::clearsprites() { - memset(spritetable(), 0xff, sizeof(Sprite) * 16); -} - -Sprite *DreamGenContext::makesprite(uint8 x, uint8 y, uint16 updateCallback, uint16 somethingInDx, uint16 somethingInDi) { - Sprite *sprite = spritetable(); - while (sprite->b15 != 0xff) { // NB: No boundchecking in the original code either - ++sprite; - } - - WRITE_LE_UINT16(&sprite->updateCallback, updateCallback); - sprite->x = x; - sprite->y = y; - WRITE_LE_UINT16(&sprite->w6, somethingInDx); - WRITE_LE_UINT16(&sprite->w8, somethingInDi); - sprite->w2 = 0xffff; - sprite->b15 = 0; - sprite->delay = 0; - return sprite; -} - -void DreamGenContext::makesprite() { // NB: returns new sprite in es:bx - Sprite *sprite = makesprite(si & 0xff, si >> 8, cx, dx, di); - - // Recover es:bx from sprite - es = data.word(kBuffers); - bx = kSpritetable; - Sprite *sprites = (Sprite *)es.ptr(bx, sizeof(Sprite) * 16); - bx += sizeof(Sprite) * (sprite - sprites); - // -} - -void DreamGenContext::spriteupdate() { - Sprite *sprites = spritetable(); - sprites[0].hidden = data.byte(kRyanon); - - Sprite *sprite = sprites; - for (size_t i=0; i < 16; ++i) { - uint16 updateCallback = READ_LE_UINT16(&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++ - mainmanCPP(sprite); - else { - assert(updateCallback == addr_backobject); - backobject(sprite); - } - } - - if (data.byte(kNowinnewroom) == 1) - break; - ++sprite; - } -} - -void DreamGenContext::initman() { - Sprite *sprite = makesprite(data.byte(kRyanx), data.byte(kRyany), addr_mainman, data.word(kMainsprites), 0); - sprite->priority = 4; - sprite->b22 = 0; - sprite->b29 = 0; - - // 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 DreamGenContext::mainmanCPP(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); - // - - if (data.byte(kResetmanxy) == 1) { - data.byte(kResetmanxy) = 0; - sprite->x = data.byte(kRyanx); - sprite->y = data.byte(kRyany); - sprite->b29 = 0; - } - --sprite->b22; - if (sprite->b22 != 0xff) { - ds = pop(); - es = pop(); - return; - } - sprite->b22 = 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(); - } - data.byte(kTurndirection) = 0; - if (data.byte(kLinepointer) == 254) { - sprite->b29 = 0; - } else { - ++sprite->b29; - if (sprite->b29 == 11) - sprite->b29 = 1; - walking(); - if (data.byte(kLinepointer) != 254) { - if ((data.byte(kFacing) & 1) == 0) - walking(); - else if ((sprite->b29 != 2) && (sprite->b29 != 7)) - walking(); - } - if (data.byte(kLinepointer) == 254) { - if (data.byte(kTurntoface) == data.byte(kFacing)) { - data.byte(kReasseschanges) = 1; - if (data.byte(kFacing) == data.byte(kLeavedirection)) - checkforexit(); - } - } - } - } - static const uint8 facelist[] = { 0,60,33,71,11,82,22,93 }; - sprite->b15 = sprite->b29 + facelist[data.byte(kFacing)]; - data.byte(kRyanx) = sprite->x; - data.byte(kRyany) = sprite->y; - - ds = pop(); - es = pop(); -} - -void DreamGenContext::walking() { - Sprite *sprite = (Sprite *)es.ptr(bx, sizeof(Sprite)); - - uint8 comp; - if (data.byte(kLinedirection) != 0) { - --data.byte(kLinepointer); - comp = 200; - } else { - ++data.byte(kLinepointer); - comp = data.byte(kLinelength); - } - if (data.byte(kLinepointer) < comp) { - sprite->x = data.byte(kLinedata + data.byte(kLinepointer) * 2 + 0); - sprite->y = data.byte(kLinedata + data.byte(kLinepointer) * 2 + 1); - return; - } - - data.byte(kLinepointer) = 254; - data.byte(kManspath) = data.byte(kDestination); - if (data.byte(kDestination) == data.byte(kFinaldest)) { - facerightway(); - return; - } - data.byte(kDestination) = data.byte(kFinaldest); - push(es); - push(bx); - autosetwalk(); - bx = pop(); - es = pop(); -} - -void DreamGenContext::aboutturn(Sprite *sprite) { - bool incdir = true; - - if (data.byte(kTurndirection) == 1) - incdir = true; - else if ((int8)data.byte(kTurndirection) == -1) - incdir = false; - else { - if (data.byte(kFacing) < data.byte(kTurntoface)) { - uint8 delta = data.byte(kTurntoface) - data.byte(kFacing); - if (delta >= 4) - incdir = false; - else - incdir = true; - } else { - uint8 delta = data.byte(kFacing) - data.byte(kTurntoface); - if (delta >= 4) - incdir = true; - else - incdir = false; - } - } - - if (incdir) { - data.byte(kTurndirection) = 1; - data.byte(kFacing) = (data.byte(kFacing) + 1) & 7; - sprite->b29 = 0; - } else { - data.byte(kTurndirection) = -1; - data.byte(kFacing) = (data.byte(kFacing) - 1) & 7; - sprite->b29 = 0; - } -} - -void DreamGenContext::backobject(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); - // - - ds = data.word(kSetdat); - di = READ_LE_UINT16(&sprite->obj_data); - ObjData *objData = (ObjData *)ds.ptr(di, 0); - - if (sprite->delay != 0) { - --sprite->delay; - ds = pop(); - es = pop(); - return; - } - - sprite->delay = objData->delay; - if (objData->type == 6) - widedoor(sprite, objData); - else if (objData->type == 5) - random(sprite, objData); - else if (objData->type == 4) - lockeddoorway(); - else if (objData->type == 3) - liftsprite(sprite, objData); - else if (objData->type == 2) - doorway(sprite, objData); - else if (objData->type == 1) - constant(sprite, objData); - else - steady(sprite, objData); - - ds = pop(); - es = pop(); -} - -void DreamGenContext::constant(Sprite *sprite, ObjData *objData) { - ++sprite->frame; - if (objData->b18[sprite->frame] == 255) { - sprite->frame = 0; - } - uint8 b18 = objData->b18[sprite->frame]; - objData->b17 = b18; - sprite->b15 = b18; -} - -void DreamGenContext::random(Sprite *sprite, ObjData *objData) { - randomnum1(); - uint16 r = ax; - sprite->b15 = objData->b18[r&7]; -} - -void DreamGenContext::doorway(Sprite *sprite, ObjData *objData) { - data.byte(kDoorcheck1) = -24; - data.byte(kDoorcheck2) = 10; - data.byte(kDoorcheck3) = -30; - data.byte(kDoorcheck4) = 10; - dodoor(sprite, objData); -} - -void DreamGenContext::widedoor(Sprite *sprite, ObjData *objData) { - data.byte(kDoorcheck1) = -24; - data.byte(kDoorcheck2) = 24; - data.byte(kDoorcheck3) = -30; - data.byte(kDoorcheck4) = 24; - dodoor(sprite, objData); -} - -void DreamGenContext::dodoor() { - Sprite *sprite = (Sprite *)es.ptr(bx, sizeof(Sprite)); - ObjData *objData = (ObjData *)ds.ptr(di, 0); - dodoor(sprite, objData); -} - -void DreamGenContext::dodoor(Sprite *sprite, ObjData *objData) { - uint8 ryanx = data.byte(kRyanx); - uint8 ryany = data.byte(kRyany); - int8 deltax = ryanx - sprite->x; - int8 deltay = ryany - sprite->y; - if (ryanx < sprite->x) { - if (deltax < (int8)data.byte(kDoorcheck1)) - goto shutdoor; - } else { - if (deltax >= data.byte(kDoorcheck2)) - goto shutdoor; - } - if (ryany < sprite->y) { - if (deltay < (int8)data.byte(kDoorcheck3)) - goto shutdoor; - } else { - if (deltay >= data.byte(kDoorcheck4)) - goto shutdoor; - } -//opendoor: - if ((data.byte(kThroughdoor) == 1) && (sprite->frame == 0)) - sprite->frame = 6; - - ++sprite->frame; - if (sprite->frame == 1) { //doorsound2 - if (data.byte(kReallocation) == 5) //hoteldoor2 - al = 13; - else - al = 0; - playchannel1(); - } - if (objData->b18[sprite->frame] == 255) { - --sprite->frame; - } - sprite->b15 = objData->b17 = objData->b18[sprite->frame]; - data.byte(kThroughdoor) = 1; - return; -shutdoor: - if (sprite->frame == 5) { //doorsound1; - if (data.byte(kReallocation) == 5) //hoteldoor1 - al = 13; - else - al = 1; - playchannel1(); - } - if (sprite->frame != 0) { - --sprite->frame; - } - sprite->b15 = objData->b17 = objData->b18[sprite->frame]; - if (sprite->frame == 5) //nearly - data.byte(kThroughdoor) = 0; -} - -void DreamGenContext::steady(Sprite *sprite, ObjData *objData) { - uint8 b18 = objData->b18[0]; - objData->b17 = b18; - sprite->b15 = b18; -} - void DreamGenContext::turnpathonCPP(uint8 param) { al = param; push(es); @@ -1407,62 +768,6 @@ void DreamGenContext::turnpathoffCPP(uint8 param) { es = pop(); } -void DreamGenContext::liftsprite() { - Sprite *sprite = (Sprite *)es.ptr(bx, sizeof(Sprite)); - ObjData *objData = (ObjData *)ds.ptr(di, 0); - liftsprite(sprite, objData); -} - -void DreamGenContext::liftsprite(Sprite *sprite, ObjData *objData) { - uint8 liftFlag = data.byte(kLiftflag); - if (liftFlag == 0) { //liftclosed - turnpathoffCPP(data.byte(kLiftpath)); - - if (data.byte(kCounttoopen) != 0) { - _dec(data.byte(kCounttoopen)); - if (data.byte(kCounttoopen) == 0) - data.byte(kLiftflag) = 3; - } - sprite->frame = 0; - sprite->b15 = objData->b17 = objData->b18[sprite->frame]; - } - else if (liftFlag == 1) { //liftopen - turnpathonCPP(data.byte(kLiftpath)); - - if (data.byte(kCounttoclose) != 0) { - _dec(data.byte(kCounttoclose)); - if (data.byte(kCounttoclose) == 0) - data.byte(kLiftflag) = 2; - } - sprite->frame = 12; - sprite->b15 = objData->b17 = objData->b18[sprite->frame]; - } - else if (liftFlag == 3) { //openlift - if (sprite->frame == 12) { - data.byte(kLiftflag) = 1; - return; - } - ++sprite->frame; - if (sprite->frame == 1) { - al = 2; - liftnoise(); - } - sprite->b15 = objData->b17 = objData->b18[sprite->frame]; - } else { //closeLift - assert(liftFlag == 2); - if (sprite->frame == 0) { - data.byte(kLiftflag) = 0; - return; - } - --sprite->frame; - if (sprite->frame == 11) { - al = 3; - liftnoise(); - } - sprite->b15 = objData->b17 = objData->b18[sprite->frame]; - } -} - void DreamGenContext::modifychar() { al = engine->modifyChar(al); } @@ -1506,5 +811,41 @@ void DreamGenContext::cancelch1() { engine->stopSound(1); } +void DreamGenContext::getroomspaths() { + es = data.word(kReels); + bx = data.byte(kRoomnum) * 144; +} + +uint8 *DreamGenContext::getroomspathsCPP() { + push(es); + es = data.word(kReels); + void *result = es.ptr(data.byte(kRoomnum) * 144, 144); + es = pop(); + return (uint8 *)result; +} + +void DreamGenContext::makebackob() { + if (data.byte(kNewobs) == 0) + return; + uint8 priority = es.byte(si+5); + uint8 type = es.byte(si+8); + Sprite *sprite = makesprite(data.word(kObjectx), data.word(kObjecty), addr_backobject, data.word(kSetframes), 0); + + // Recover es:bx from sprite + es = data.word(kBuffers); + bx = kSpritetable; + Sprite *sprites = (Sprite *)es.ptr(bx, sizeof(Sprite) * 16); + bx += sizeof(Sprite) * (sprite - sprites); + // + WRITE_LE_UINT16(&sprite->obj_data, si); + if (priority == 255) + priority = 0; + sprite->priority = priority; + sprite->type = type; + sprite->b16 = 0; + sprite->delay = 0; + sprite->frame = 0; +} + } /*namespace dreamgen */ diff --git a/engines/dreamweb/stubs.h b/engines/dreamweb/stubs.h index b633684f4d..3a00c16d4d 100644 --- a/engines/dreamweb/stubs.h +++ b/engines/dreamweb/stubs.h @@ -19,7 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * */ - + uint8 *workspace(); void multidump(); void multidump(uint16 x, uint16 y, uint8 width, uint8 height); void frameoutv(uint8 *dst, const uint8 *src, uint16 pitch, uint16 width, uint16 height, uint16 x, uint16 y); @@ -41,9 +41,9 @@ void getnextword(); uint8 getnextword(const uint8 *string, uint8 *totalWidth, uint8 *charCount); void printboth(); - void printboth(uint16 dst, uint16 src, uint16 *x, uint16 y, uint8 c); + void printboth(uint16 src, uint16 *x, uint16 y, uint8 c, uint8 nextChar); void printchar(); - void printchar(uint16 dst, uint16 src, uint16 *x, uint16 y, uint8 c, uint8 *width, uint8 *height); + void printchar(uint16 src, uint16 *x, uint16 y, uint8 c, uint8 nextChar, uint8 *width, uint8 *height); void printdirect(); void printdirect(uint16 x, uint16 *y, uint8 maxWidth, bool centered); void usetimedtext(); @@ -53,12 +53,12 @@ void printslow(); void dumptextline(); void getnumber(); - uint8 getnumber(uint16 index, uint16 maxWidth, bool centered, uint16* offset); + uint8 getnumber(uint16 index, uint16 maxWidth, bool centered, uint16 *offset); void kernchars(); uint8 kernchars(uint8 firstChar, uint8 secondChar, uint8 width); Sprite *spritetable(); void showframe(); - void showframe(uint16 dst, uint16 src, uint16 x, uint16 y, uint16 frameNumber, uint8 effectsFlag, uint8 *width, uint8 *height); + void showframe(uint16 src, uint16 x, uint16 y, uint16 frameNumber, uint8 effectsFlag, uint8 *width, uint8 *height); void printasprite(const Sprite *sprite); void width160(); void multiput(uint16 x, uint16 y, uint8 width, uint8 height); @@ -70,7 +70,9 @@ void spriteupdate(); void initman(); void mainmanCPP(Sprite *sprite); + void facerightway(); void walking(); + void walking(Sprite *sprite); void aboutturn(Sprite *sprite); void backobject(Sprite *sprite); void constant(Sprite *sprite, ObjData *objData); @@ -80,10 +82,15 @@ void dodoor(Sprite *sprite, ObjData *objData); void doorway(Sprite *sprite, ObjData *objData); void widedoor(Sprite *sprite, ObjData *objData); + void lockeddoorway(); + void lockeddoorway(Sprite *sprite, ObjData *objData); void liftsprite(); void liftsprite(Sprite *sprite, ObjData *objData); void turnpathonCPP(uint8 param); void turnpathoffCPP(uint8 param); + void getroomspaths(); + uint8 *getroomspathsCPP(); + void makebackob(); void modifychar(); void lockmon(); void cancelch0(); |