aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--devtools/tasmrecover/dreamweb/sprite.asm2
-rwxr-xr-xdevtools/tasmrecover/tasm-recover6
-rw-r--r--engines/dreamweb/dreamgen.cpp221
-rw-r--r--engines/dreamweb/dreamgen.h12
-rw-r--r--engines/dreamweb/module.mk2
-rw-r--r--engines/dreamweb/print.cpp251
-rw-r--r--engines/dreamweb/sprite.cpp533
-rw-r--r--engines/dreamweb/structs.h3
-rw-r--r--engines/dreamweb/stubs.cpp791
-rw-r--r--engines/dreamweb/stubs.h17
10 files changed, 876 insertions, 962 deletions
diff --git a/devtools/tasmrecover/dreamweb/sprite.asm b/devtools/tasmrecover/dreamweb/sprite.asm
index 45f807da3f..9b214eaa0a 100644
--- a/devtools/tasmrecover/dreamweb/sprite.asm
+++ b/devtools/tasmrecover/dreamweb/sprite.asm
@@ -4226,7 +4226,7 @@ botofdoor2: sub ah,ch
opendoor2: cmp throughdoor,1
jz mustbeopen
cmp lockstatus,1
- jz shutdoor
+ jz shutdoor2
mustbeopen: mov cl,[es:bx+19]
cmp cl,1
jnz notdoorsound4
diff --git a/devtools/tasmrecover/tasm-recover b/devtools/tasmrecover/tasm-recover
index 413be6caf1..f550cb0826 100755
--- a/devtools/tasmrecover/tasm-recover
+++ b/devtools/tasmrecover/tasm-recover
@@ -67,11 +67,15 @@ generator = cpp(context, "DreamGen", blacklist = [
'walking',
'spriteupdate',
'dodoor',
+ 'lockeddoorway',
'liftsprite',
'frameoutv',
'modifychar',
'lockmon',
'cancelch0',
- 'cancelch1'
+ 'cancelch1',
+ 'getroomspaths',
+ 'makebackob',
+ 'facerightway',
])
generator.generate('dreamweb') #start routine
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();