aboutsummaryrefslogtreecommitdiff
path: root/engines/dreamweb/stubs.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/dreamweb/stubs.cpp')
-rw-r--r--engines/dreamweb/stubs.cpp1503
1 files changed, 464 insertions, 1039 deletions
diff --git a/engines/dreamweb/stubs.cpp b/engines/dreamweb/stubs.cpp
index 5ba3796e30..c978d8d475 100644
--- a/engines/dreamweb/stubs.cpp
+++ b/engines/dreamweb/stubs.cpp
@@ -174,7 +174,7 @@ void DreamGenContext::dreamweb() {
}
}
-Common::String getFilename(Context &context) {
+static Common::String getFilename(Context &context) {
uint16 name_ptr = context.dx;
Common::String name;
uint8 c;
@@ -183,126 +183,6 @@ Common::String getFilename(Context &context) {
return name;
}
-void DreamGenContext::multiget() {
- multiget(di, bx, cl, ch);
-}
-
-void DreamGenContext::multiget(uint16 x, uint16 y, uint8 w, uint8 h) {
- unsigned src = x + y * kScreenwidth;
- unsigned dst = (uint16)si;
- es = ds;
- ds = data.word(kWorkspace);
- if (y + h > 200)
- h = 200 - y;
- if (x + w > 320)
- w = 320 - x;
- //debug(1, "multiget %u,%u %ux%u -> segment: %04x->%04x", x, y, w, h, (uint16)ds, (uint16)es);
- for(unsigned l = 0; l < h; ++l) {
- uint8 *src_p = ds.ptr(src + kScreenwidth * l, w);
- uint8 *dst_p = es.ptr(dst + w * l, w);
- memcpy(dst_p, src_p, w);
- }
- si += w * h;
- di = src + kScreenwidth * h;
- cx = 0;
-}
-
-void DreamGenContext::multiput() {
- multiput(di, bx, cl, ch);
-}
-
-void DreamGenContext::multiput(uint16 x, uint16 y, uint8 w, uint8 h) {
- unsigned src = (uint16)si;
- unsigned dst = x + y * kScreenwidth;
- es = data.word(kWorkspace);
- if (y + h > 200)
- h = 200 - y;
- if (x + w > 320)
- w = 320 - x;
- //debug(1, "multiput %ux%u -> segment: %04x->%04x", w, h, (uint16)ds, (uint16)es);
- for(unsigned l = 0; l < h; ++l) {
- uint8 *src_p = ds.ptr(src + w * l, w);
- uint8 *dst_p = es.ptr(dst + kScreenwidth * l, w);
- memcpy(dst_p, src_p, w);
- }
- si += w * h;
- di = dst + kScreenwidth * h;
- cx = 0;
-}
-
-void DreamGenContext::multidump(uint16 x, uint16 y, uint8 width, uint8 height) {
- ds = data.word(kWorkspace);
- unsigned offset = x + y * kScreenwidth;
- //debug(1, "multidump %ux%u(segment: %04x) -> %d,%d(address: %d)", w, h, (uint16)ds, x, y, offset);
- engine->blit(ds.ptr(offset, width * height), kScreenwidth, x, y, width, height);
-}
-
-void DreamGenContext::multidump() {
- multidump(di, bx, cl, ch);
- unsigned offset = di + bx * kScreenwidth;
- si = di = offset + ch * kScreenwidth;
- cx = 0;
-}
-
-void DreamGenContext::worktoscreen() {
- ds = data.word(kWorkspace);
- uint size = 320 * 200;
- engine->blit(ds.ptr(0, size), 320, 0, 0, 320, 200);
- di = si = size;
- cx = 0;
-}
-
-void DreamGenContext::printundermon() {
- engine->printUnderMonitor();
-}
-
-void DreamGenContext::cls() {
- engine->cls();
-}
-
-void DreamGenContext::frameoutnm(uint8 *dst, const uint8 *src, uint16 pitch, uint16 width, uint16 height, uint16 x, uint16 y) {
- dst += pitch * y + x;
-
- for (uint16 j = 0; j < height; ++j) {
- memcpy(dst, src, width);
- dst += pitch;
- src += width;
- }
-}
-
-void DreamGenContext::frameoutbh(uint8 *dst, const uint8 *src, uint16 pitch, uint16 width, uint16 height, uint16 x, uint16 y) {
- uint16 stride = pitch - width;
- dst += y * pitch + x;
-
- for (uint16 i = 0; i < height; ++i) {
- for (uint16 j = 0; j < width; ++j) {
- if (*dst == 0xff) {
- *dst = *src;
- }
- ++src;
- ++dst;
- }
- dst += stride;
- }
-}
-
-void DreamGenContext::frameoutfx(uint8 *dst, const uint8 *src, uint16 pitch, uint16 width, uint16 height, uint16 x, uint16 y) {
- uint16 stride = pitch - width;
- dst += y * pitch + x;
- dst -= width;
-
- for (uint16 j = 0; j < height; ++j) {
- for (uint16 i = 0; i < width; ++i) {
- uint8 pixel = src[width - i - 1];
- if (pixel)
- *dst = pixel;
- ++dst;
- }
- src += width;
- dst += stride;
- }
-}
-
void DreamGenContext::seecommandtail() {
data.word(kSoundbaseadd) = 0x220;
data.byte(kSoundint) = 5;
@@ -394,84 +274,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;
@@ -483,100 +285,13 @@ 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))
y -= 3;
ds = data.word(kBuffers);
si = kUndertimedtext;
- multiget(data.byte(kTimedx), y, 240, kUndertimedysize);
+ multiget(ds.ptr(si, 0), data.byte(kTimedx), y, 240, kUndertimedysize);
}
void DreamGenContext::putundertimed() {
@@ -585,7 +300,7 @@ void DreamGenContext::putundertimed() {
y -= 3;
ds = data.word(kBuffers);
si = kUndertimedtext;
- multiput(data.byte(kTimedx), y, 240, kUndertimedysize);
+ multiput(ds.ptr(si, 0), data.byte(kTimedx), y, 240, kUndertimedysize);
}
void DreamGenContext::usetimedtext() {
@@ -605,67 +320,62 @@ void DreamGenContext::usetimedtext() {
es = data.word(kTimedseg);
si = data.word(kTimedoffset);
+ const uint8 *string = es.ptr(si, 0);
uint16 y = data.byte(kTimedy);
- printdirect(data.byte(kTimedx), &y, 237, true);
+ printdirect(&string, data.byte(kTimedx), &y, 237, true);
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;
+void DreamGenContext::setuptimedtemp() {
+ setuptimedtemp(al, ah, bl, bh, cx, dx);
+}
+
+void DreamGenContext::setuptimedtemp(uint8 textIndex, uint8 voiceIndex, uint8 x, uint8 y, uint16 countToTimed, uint16 timeCount) {
+#if 1 // if cd
+ if (voiceIndex != 0) {
+ push(ax);
+ push(bx);
+ push(cx);
+ push(dx);
+ dl = 'T';
+ dh = voiceIndex;
+ cl = 'T';
+ ah = 0;
+ loadspeech();
+ if (data.byte(kSpeechloaded) == 1) {
+ al = 50+12;
+ playchannel1();
}
- totalWidth += wordTotalWidth;
- charCount += wordCharCount;
+ dx = pop();
+ cx = pop();
+ bx = pop();
+ ax = pop();
+ if ((data.byte(kSpeechloaded) == 1) && (data.byte(kSubtitles) != 1))
+ return;
}
-}
+#endif
-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;
-}
+ if (data.word(kTimecount) != 0)
+ return;
+ data.byte(kTimedy) = y;
+ data.byte(kTimedx) = x;
+ data.word(kCounttotimed) = countToTimed;
+ data.word(kTimecount) = timeCount + countToTimed;
+ data.word(kTimedseg) = data.word(kTextfile1);
+ data.word(kTimedoffset) = kTextstart + segRef(data.word(kTextfile1)).word(textIndex * 2);
+ const uint8 *string = segRef(data.word(kTextfile1)).ptr(data.word(kTimedoffset), 0);
+ debug(1, "setuptimedtemp: (%d, %d) => '%s'", textIndex, voiceIndex, string);
+}
+
+void DreamGenContext::dumptimedtext() {
+ if (data.byte(kNeedtodumptimed) != 1)
+ return;
+ uint8 y = data.byte(kTimedy);
+ if (data.byte(kForeignrelease) != 0)
+ y -= 3;
-void DreamGenContext::kernchars() {
- cl = kernchars(al, ah, cl);
+ multidump(data.byte(kTimedx), y, 240, kUndertimedysize);
+ data.byte(kNeedtodumptimed) = 0;
}
void DreamGenContext::gettime() {
@@ -681,12 +391,17 @@ void DreamGenContext::gettime() {
}
void DreamGenContext::allocatemem() {
- uint size = (bx + 2) * 16;
+ ax = allocatemem(bx);
+}
+
+uint16 DreamGenContext::allocatemem(uint16 paragraphs) {
+ uint size = (paragraphs + 2) * 16;
debug(1, "allocate mem, %u bytes", size);
flags._c = false;
SegmentRef seg = allocateSegment(size);
- ax = (uint16)seg;
- debug(1, "\tsegment address -> %04x", (uint16)ax);
+ uint16 result = (uint16)seg;
+ debug(1, "\tsegment address -> %04x", result);
+ return result;
}
void DreamGenContext::deallocatemem() {
@@ -880,349 +595,96 @@ void DreamGenContext::fadedos() {
engine->fadeDos();
}
-void DreamGenContext::doshake() {
- uint8 &counter = data.byte(kShakecounter);
- _cmp(counter, 48);
- if (flags.z())
- return;
-
- _add(counter, 1);
- static const int shakeTable[] = {
- 0, -2, 3, -2, 0, 2, 4, -1,
- 1, -3, 3, 2, 0, -2, 3, -2,
- 0, 2, 4, -1, 1, -3, 3, 2,
- 0, -2, 3, -2, 0, 2, 4, -1,
-
- 1, -3, 3, 2, 0, -2, 3, -2,
- 0, 2, 4, -1, 1, -3, 3, 2,
- 0, -2, 3, -2, 0, 2, 4, -1,
- 1, -3, 3, 2, 0, -2, 3, -2,
-
- 0, 2, 4, -1, 1, -3, 3, 2,
- 0, -2, 3, -2, 0, 2, 4, -1,
- 1, -3, 3, 2, 0, -2, 3, -2,
- 0, 2, 4, -1, 1, -3, 3, 2,
-
- 0, -2, 3, -2, 0, 2, 4, -1,
- 1, -3, 3, 0,
- };
- int offset = shakeTable[counter];
- engine->setShakePos(offset >= 0 ? offset : -offset);
-}
-
-void DreamGenContext::vsync() {
- push(ax);
- push(bx);
- push(cx);
- push(dx);
- push(si);
- push(di);
- push(es);
- push(ds);
- engine->waitForVSync();
- ds = pop();
- es = pop();
- di = pop();
- si = pop();
- dx = pop();
- cx = pop();
- bx = pop();
- ax = pop();
-}
-
-void DreamGenContext::setmode() {
- vsync();
- initGraphics(320, 200, false);
-}
-
-void DreamGenContext::showpcx() {
- Common::String name = getFilename(*this);
- Common::File pcxFile;
-
- if (!pcxFile.open(name)) {
- warning("showpcx: Could not open '%s'", name.c_str());
- return;
- }
-
- uint8 *maingamepal;
- int i, j;
-
- // Read the 16-color palette into the 'maingamepal' buffer. Note that
- // the color components have to be adjusted from 8 to 6 bits.
-
- pcxFile.seek(16, SEEK_SET);
- es = data.word(kBuffers);
- maingamepal = es.ptr(kMaingamepal, 768);
- pcxFile.read(maingamepal, 48);
-
- memset(maingamepal + 48, 0xff, 720);
- for (i = 0; i < 48; i++) {
- maingamepal[i] >>= 2;
- }
-
- // Decode the image data.
-
- Graphics::Surface *s = g_system->lockScreen();
- Common::Rect rect(640, 480);
-
- s->fillRect(rect, 0);
- pcxFile.seek(128, SEEK_SET);
-
- for (int y = 0; y < 480; y++) {
- byte *dst = (byte *)s->getBasePtr(0, y);
- int decoded = 0;
-
- while (decoded < 320) {
- byte col = pcxFile.readByte();
- byte len;
-
- if ((col & 0xc0) == 0xc0) {
- len = col & 0x3f;
- col = pcxFile.readByte();
- } else {
- len = 1;
- }
-
- // The image uses 16 colors and is stored as four bit
- // planes, one for each bit of the color, least
- // significant bit plane first.
-
- for (i = 0; i < len; i++) {
- int plane = decoded / 80;
- int pos = decoded % 80;
-
- for (j = 0; j < 8; j++) {
- byte bit = (col >> (7 - j)) & 1;
- dst[8 * pos + j] |= (bit << plane);
- }
-
- decoded++;
- }
- }
- }
-
- g_system->unlockScreen();
- 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++?
- assert(pitch == 320);
-
- if(x >= 320)
- return;
- if(y >= 200)
+void DreamGenContext::eraseoldobs() {
+ if (data.byte(kNewobs) == 0)
return;
- if(x + width > 320) {
- width = 320 - x;
- }
- if(y + height > 200) {
- height = 200 - y;
- }
- uint16 stride = pitch - width;
- dst += pitch * y + x;
-
- for (uint16 j = 0; j < height; ++j) {
- for (uint16 i = 0; i < width; ++i) {
- uint8 pixel = *src++;
- if (pixel)
- *dst = pixel;
- ++dst;
+ Sprite *sprites = spritetable();
+ for (size_t i=0; i < 16; ++i) {
+ Sprite &sprite = sprites[i];
+ if (sprite.objData() != 0xffff) {
+ memset(&sprite, 0xff, sizeof(Sprite));
}
- dst += stride;
}
}
-Sprite *DreamGenContext::spritetable() {
+void DreamGenContext::turnpathonCPP(uint8 param) {
+ al = param;
push(es);
push(bx);
-
- es = data.word(kBuffers);
- bx = kSpritetable;
- Sprite *sprite = (Sprite *)es.ptr(bx, 16 * sizeof(Sprite));
-
+ turnpathon();
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;
- ds = src;
- di = x;
- bx = y;
- ax = frameNumber | (effectsFlag << 8);
-
-
- si = (ax & 0x1ff) * 6;
- if (ds.word(si) == 0) {
- *width = 0;
- *height = 0;
- return;
- }
-
-//notblankshow:
- if ((effectsFlag & 128) == 0) {
- di += ds.byte(si + 4);
- bx += ds.byte(si + 5);
- }
-//skipoffsets:
- cx = ds.word(si + 0);
- *width = cl;
- *height = ch;
- si = ds.word(si+2) + 2080;
-
- if (effectsFlag) {
- if (effectsFlag & 128) { //centred
- di -= *width / 2;
- bx -= *height / 2;
- }
- if (effectsFlag & 64) { //diffdest
- frameoutfx(es.ptr(0, dx * *height), ds.ptr(si, *width * *height), dx, *width, *height, di, bx);
- return;
- }
- if (effectsFlag & 8) { //printlist
- push(ax);
- ax = di - data.word(kMapadx);
- push(bx);
- bx -= data.word(kMapady);
- ah = bl;
- bx = pop();
- //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);
- 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);
- return;
- }
- if (effectsFlag & 32) {
- es = data.word(kWorkspace);
- frameoutbh(es.ptr(0, 320 * *height), ds.ptr(si, *width * *height), 320, *width, *height, di, bx);
- return;
- }
- }
-//noeffects:
- es = data.word(kWorkspace);
- frameoutv(es.ptr(0, 65536), ds.ptr(si, *width * *height), 320, *width, *height, di, bx);
- return;
}
-void DreamGenContext::showframe() {
- uint8 width, height;
- showframe(es, 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) {
+void DreamGenContext::turnpathoffCPP(uint8 param) {
+ al = param;
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;
-
+ turnpathoff();
bx = pop();
es = pop();
}
-void DreamGenContext::eraseoldobs() {
- if (data.byte(kNewobs) == 0)
- return;
+void DreamGenContext::modifychar() {
+ al = engine->modifyChar(al);
+}
- Sprite *sprites = spritetable();
- for (size_t i=0; i < 16; ++i) {
- Sprite &sprite = sprites[i];
- if (READ_LE_UINT16(&sprite.obj_data) != 0xffff) {
- memset(&sprite, 0xff, sizeof(Sprite));
+void DreamGenContext::lockmon() {
+ // Pressing space pauses text output in the monitor. We use the "hard"
+ // key because calling readkey() drains characters from the input
+ // buffer, we we want the user to be able to type ahead while the text
+ // is being printed.
+ if (data.byte(kLasthardkey) == 57) {
+ // Clear the keyboard buffer. Otherwise the space that caused
+ // the pause will be read immediately unpause the game.
+ do {
+ readkey();
+ } while (data.byte(kCurrentkey) != 0);
+
+ locklighton();
+ while (!engine->shouldQuit()) {
+ engine->waitForVSync();
+ readkey();
+ if (data.byte(kCurrentkey) == ' ')
+ break;
}
+ // Forget the last "hard" key, otherwise the space that caused
+ // the unpausing will immediately re-pause the game.
+ data.byte(kLasthardkey) = 0;
+ locklightoff();
}
}
-void DreamGenContext::clearsprites() {
- memset(spritetable(), 0xff, sizeof(Sprite) * 16);
+void DreamGenContext::cancelch0() {
+ data.byte(kCh0repeat) = 0;
+ data.word(kCh0blockstocopy) = 0;
+ data.byte(kCh0playing) = 255;
+ engine->stopSound(0);
}
-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;
- }
+void DreamGenContext::cancelch1() {
+ data.word(kCh1blockstocopy) = 0;
+ data.byte(kCh1playing) = 255;
+ engine->stopSound(1);
+}
- 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::getroomspaths() {
+ es = data.word(kReels);
+ bx = data.byte(kRoomnum) * 144;
+}
+
+uint8 *DreamGenContext::getroomspathsCPP() {
+ void *result = segRef(data.word(kReels)).ptr(data.byte(kRoomnum) * 144, 144);
+ return (uint8 *)result;
}
-void DreamGenContext::makesprite() { // NB: returns new sprite in es:bx
- Sprite *sprite = makesprite(si & 0xff, si >> 8, cx, dx, di);
+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);
@@ -1230,428 +692,391 @@ void DreamGenContext::makesprite() { // NB: returns new sprite in es:bx
Sprite *sprites = (Sprite *)es.ptr(bx, sizeof(Sprite) * 16);
bx += sizeof(Sprite) * (sprite - sprites);
//
+ sprite->setObjData(si);
+ if (priority == 255)
+ priority = 0;
+ sprite->priority = priority;
+ sprite->type = type;
+ sprite->b16 = 0;
+ sprite->delay = 0;
+ sprite->frame = 0;
}
-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::getroomdata() {
+ bx = kRoomdata + sizeof(Room) * al;
}
-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::getroomdata(uint8 roomIndex) {
+ getroomdata(roomIndex);
}
-void DreamGenContext::mainmanCPP(Sprite *sprite) {
- push(es);
- push(ds);
+void DreamGenContext::startloading() {
+ const Room *room = (Room *)cs.ptr(bx, sizeof(Room));
+ startloading(room);
+}
- // 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::readheader() {
+ ax = engine->readFromFile(cs.ptr(kFileheader, kHeaderlen), kHeaderlen);
+ es = cs;
+ di = kFiledata;
+}
- 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;
+void DreamGenContext::startloading(const Room *room) {
+ data.byte(kCombatcount) = 0;
+ data.byte(kRoomssample) = room->roomsSample;
+ data.byte(kMapx) = room->mapX;
+ data.byte(kMapy) = room->mapY;
+ data.byte(kLiftflag) = room->liftFlag;
+ data.byte(kManspath) = room->b21;
+ data.byte(kDestination) = room->b21;
+ data.byte(kFinaldest) = room->b21;
+ data.byte(kFacing) = room->b22;
+ data.byte(kTurntoface) = room->b22;
+ data.byte(kCounttoopen) = room->countToOpen;
+ data.byte(kLiftpath) = room->liftPath;
+ data.byte(kDoorpath) = room->doorPath;
+ data.byte(kLastweapon) = -1;
+ al = room->b27;
+ push(ax);
+ al = room->b31;
+ ah = data.byte(kReallocation);
+ data.byte(kReallocation) = al;
+ dx = bx;
+ Common::String name = getFilename(*this);
+ engine->openFile(name);
+ cs.word(kHandle) = 1; //only one handle
+ flags._c = false;
+ readheader();
+ allocateload();
+ ds = ax;
+ data.word(kBackdrop) = ax;
+ dx = (0);
+ loadseg();
+ ds = data.word(kWorkspace);
+ dx = (0);
+ cx = 132*66;
+ al = 0;
+ fillspace();
+ loadseg();
+ sortoutmap();
+ allocateload();
+ data.word(kSetframes) = ax;
+ ds = ax;
+ dx = (0);
+ loadseg();
+ ds = data.word(kSetdat);
+ dx = 0;
+ cx = (64*128);
+ al = 255;
+ fillspace();
+ loadseg();
+ allocateload();
+ data.word(kReel1) = ax;
+ ds = ax;
+ dx = 0;
+ loadseg();
+ allocateload();
+ data.word(kReel2) = ax;
+ ds = ax;
+ dx = 0;
+ loadseg();
+ allocateload();
+ data.word(kReel3) = ax;
+ ds = ax;
+ dx = 0;
+ loadseg();
+ allocateload();
+ data.word(kReels) = ax;
+ ds = ax;
+ dx = 0;
+ loadseg();
+ allocateload();
+ data.word(kPeople) = ax;
+ ds = ax;
+ dx = 0;
+ loadseg();
+ allocateload();
+ data.word(kSetdesc) = ax;
+ ds = ax;
+ dx = 0;
+ loadseg();
+ allocateload();
+ data.word(kBlockdesc) = ax;
+ ds = ax;
+ dx = 0;
+ loadseg();
+ allocateload();
+ data.word(kRoomdesc) = ax;
+ ds = ax;
+ dx = 0;
+ loadseg();
+ allocateload();
+ data.word(kFreeframes) = ax;
+ ds = ax;
+ dx = 0;
+ loadseg();
+ ds = data.word(kFreedat);
+ dx = 0;
+ cx = (16*80);
+ al = 255;
+ fillspace();
+ loadseg();
+ allocateload();
+ data.word(kFreedesc) = ax;
+ ds = ax;
+ dx = (0);
+ loadseg();
+ closefile();
+ findroominloc();
+ deletetaken();
+ setallchanges();
+ autoappear();
+ al = data.byte(kNewlocation);
+ getroomdata();
+ data.byte(kLastweapon) = -1;
+ data.byte(kMandead) = 0;
+ data.word(kLookcounter) = 160;
+ data.byte(kNewlocation) = 255;
+ data.byte(kLinepointer) = 254;
+ ax = pop();
+ if (al != 255) {
+ data.byte(kManspath) = al;
+ push(bx);
+ autosetwalk();
+ bx = pop();
}
- sprite->b22 = 0;
- if (data.byte(kTurntoface) != data.byte(kFacing)) {
- aboutturn(sprite);
+ findxyfrompath();
+}
+
+void DreamGenContext::fillspace() {
+ memset(ds.ptr(dx, cx), al, cx);
+}
+
+void DreamGenContext::dealwithspecial(uint8 firstParam, uint8 secondParam) {
+ uint8 type = firstParam - 220;
+ if (type == 0) {
+ al = secondParam;
+ placesetobject();
+ data.byte(kHavedoneobs) = 1;
+ } else if (type == 1) {
+ al = secondParam;
+ removesetobject();
+ data.byte(kHavedoneobs) = 1;
+ } else if (type == 2) {
+ al = secondParam;
+ placefreeobject();
+ data.byte(kHavedoneobs) = 1;
+ } else if (type == 3) {
+ al = secondParam;
+ removefreeobject();
+ data.byte(kHavedoneobs) = 1;
+ } else if (type == 4) {
+ switchryanoff();
+ } else if (type == 5) {
+ data.byte(kTurntoface) = secondParam;
+ data.byte(kFacing) = secondParam;
+ switchryanon();
+ } else if (type == 6) {
+ data.byte(kNewlocation) = secondParam;
} 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();
- }
- }
- }
+ movemap(secondParam);
}
- 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;
+void DreamGenContext::plotreel() {
+ Reel *reel = getreelstart();
+ while (true) {
+ if (reel->x < 220)
+ break;
+ if (reel->x == 255)
+ break;
+ dealwithspecial(reel->x, reel->y);
+ ++data.word(kReelpointer);
+ reel += 8;
}
- data.byte(kLinepointer) = 254;
- data.byte(kManspath) = data.byte(kDestination);
- if (data.byte(kDestination) == data.byte(kFinaldest)) {
- facerightway();
- return;
+ for (size_t i = 0; i < 8; ++i) {
+ if (reel->frame() != 0xffff)
+ showreelframe(reel);
+ ++reel;
}
- data.byte(kDestination) = data.byte(kFinaldest);
- push(es);
- push(bx);
- autosetwalk();
- bx = pop();
- es = pop();
+ soundonreels();
}
-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;
+void DreamGenContext::crosshair() {
+ uint8 frame;
+ if ((data.byte(kCommandtype) != 3) && (data.byte(kCommandtype) < 10)) {
+ frame = 9;
} else {
- data.byte(kTurndirection) = -1;
- data.byte(kFacing) = (data.byte(kFacing) - 1) & 7;
- sprite->b29 = 0;
+ frame = 29;
}
+ const Frame *src = (const Frame *)segRef(data.word(kIcons1)).ptr(0, 0);
+ uint8 width, height;
+ showframe(src, kZoomx + 24, kZoomy + 19, frame, 0, &width, &height);
}
-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);
+void DreamGenContext::deltextline() {
+ uint16 x = data.word(kTextaddressx);
+ uint16 y = data.word(kTextaddressy);
+ if (data.byte(kForeignrelease) != 0)
+ y -= 3;
+ multiput(segRef(data.word(kBuffers)).ptr(kTextunder, 0), x, y, kUndertextsizex, kUndertextsizey);
+}
- if (sprite->delay != 0) {
- --sprite->delay;
- ds = pop();
- es = pop();
+void DreamGenContext::autosetwalk() {
+ al = data.byte(kManspath);
+ if (data.byte(kFinaldest) == al)
+ return;
+ const uint8 *roomsPaths = getroomspathsCPP();
+ checkdest(roomsPaths);
+ data.word(kLinestartx) = roomsPaths[data.byte(kManspath) * 8 + 0] - 12;
+ data.word(kLinestarty) = roomsPaths[data.byte(kManspath) * 8 + 1] - 12;
+ data.word(kLineendx) = roomsPaths[data.byte(kDestination) * 8 + 0] - 12;
+ data.word(kLineendy) = roomsPaths[data.byte(kDestination) * 8 + 1] - 12;
+ bresenhams();
+ if (data.byte(kLinedirection) != 0) {
+ data.byte(kLinepointer) = data.byte(kLinelength) - 1;
+ data.byte(kLinedirection) = 1;
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;
+ data.byte(kLinepointer) = 0;
+}
+
+void DreamGenContext::checkdest(const uint8 *roomsPaths) {
+ const uint8 *p = roomsPaths + 12 * 8;
+ ah = data.byte(kManspath) << 4;
+ al = data.byte(kDestination);
+ uint8 destination = data.byte(kDestination);
+ for (size_t i = 0; i < 24; ++i) {
+ dh = p[0] & 0xf0;
+ dl = p[0] & 0x0f;
+ if (ax == dx) {
+ data.byte(kDestination) = p[1] & 0x0f;
+ return;
+ }
+ dl = (p[0] & 0xf0) >> 4;
+ dh = (p[0] & 0x0f) << 4;
+ if (ax == dx) {
+ destination = p[1] & 0x0f;
+ }
+ p += 2;
}
- 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;
+ data.byte(kDestination) = destination;
+}
+
+void DreamGenContext::checkifperson() {
+ flags._z = not checkifperson(al, ah);
+}
+
+bool DreamGenContext::checkifperson(uint8 x, uint8 y) {
+ People *people = (People *)segRef(data.word(kBuffers)).ptr(kPeoplelist, 0);
+
+ for (size_t i = 0; i < 12; ++i, ++people) {
+ if (people->b4 == 255)
+ continue;
+ data.word(kReelpointer) = people->w0();
+ Reel *reel = getreelstart();
+ if (reel->frame() == 0xffff)
+ ++reel;
+ const Frame *frame = getreelframeax(reel->frame());
+ uint8 xmin = reel->x + frame->x;
+ uint8 ymin = reel->y + frame->y;
+ uint8 xmax = xmin + frame->width;
+ uint8 ymax = ymin + frame->height;
+ if (x < xmin)
+ continue;
+ if (y < ymin)
+ continue;
+ if (x >= xmax)
+ continue;
+ if (y >= ymax)
+ continue;
+ data.word(kPersondata) = people->w2();
+ al = people->b4;
+ ah = 5;
+ obname();
+ return true;
}
- if (ryany < sprite->y) {
- if (deltay < (int8)data.byte(kDoorcheck3))
- goto shutdoor;
+ return false;
+}
+
+const uint8 *DreamGenContext::findobname(uint8 type, uint8 index) {
+ if (type == 5) {
+ uint16 i = 64 * 2 * (index & 127);
+ uint16 offset = segRef(data.word(kPeople)).word(kPersontxtdat + i) + kPersontext;
+ return segRef(data.word(kPeople)).ptr(offset, 0);
+ } else if (type == 4) {
+ uint16 offset = segRef(data.word(kExtras)).word(kExtextdat + index * 2) + kExtext;
+ return segRef(data.word(kExtras)).ptr(offset, 0);
+ } else if (type == 2) {
+ uint16 offset = segRef(data.word(kFreedesc)).word(kFreetextdat + index * 2) + kFreetext;
+ return segRef(data.word(kFreedesc)).ptr(offset, 0);
+ } else if (type == 1) {
+ uint16 offset = segRef(data.word(kSetdesc)).word(kSettextdat + index * 2) + kSettext;
+ return segRef(data.word(kSetdesc)).ptr(offset, 0);
} 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;
+ uint16 offset = segRef(data.word(kBlockdesc)).word(kBlocktextdat + index * 2) + kBlocktext;
+ return segRef(data.word(kBlockdesc)).ptr(offset, 0);
}
- 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);
- push(bx);
- turnpathon();
- bx = pop();
- es = pop();
}
-void DreamGenContext::turnpathoffCPP(uint8 param) {
- al = param;
- push(es);
- push(bx);
- turnpathoff();
- bx = pop();
- es = pop();
+void DreamGenContext::copyname() {
+ copyname(ah, al, cs.ptr(di, 0));
}
-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::copyname(uint8 type, uint8 index, uint8 *dst) {
+ const uint8 *src = findobname(type, index);
+ size_t i;
+ for (i = 0; i < 28; ++i) {
+ char c = src[i];
+ if (c == ':')
+ break;
+ if (c == 0)
+ break;
+ dst[i] = c;
}
+ dst[i] = 0;
}
-void DreamGenContext::modifychar() {
- al = engine->modifyChar(al);
+void DreamGenContext::commandwithob() {
+ commandwithob(al, bh, bl);
}
-void DreamGenContext::lockmon() {
- // Pressing space pauses text output in the monitor. We use the "hard"
- // key because calling readkey() drains characters from the input
- // buffer, we we want the user to be able to type ahead while the text
- // is being printed.
- if (data.byte(kLasthardkey) == 57) {
- // Clear the keyboard buffer. Otherwise the space that caused
- // the pause will be read immediately unpause the game.
- do {
- readkey();
- } while (data.byte(kCurrentkey) != 0);
-
- locklighton();
- while (!engine->shouldQuit()) {
- engine->waitForVSync();
- readkey();
- if (data.byte(kCurrentkey) == ' ')
- break;
- }
- // Forget the last "hard" key, otherwise the space that caused
- // the unpausing will immediately re-pause the game.
- data.byte(kLasthardkey) = 0;
- locklightoff();
+void DreamGenContext::commandwithob(uint8 command, uint8 type, uint8 index) {
+ uint8 commandLine[64] = "OBJECT NAME ONE ";
+ deltextline();
+ uint16 commandText = kTextstart + segRef(data.word(kCommandtext)).word(command * 2);
+ uint8 textLen = data.byte(kTextlen);
+ {
+ uint16 y = data.word(kTextaddressy);
+ const uint8 *string = segRef(data.word(kCommandtext)).ptr(commandText, 0);
+ printdirect(&string, data.word(kTextaddressx), &y, textLen, (bool)(textLen & 1));
}
+ copyname(type, index, commandLine);
+ uint16 x = data.word(kLastxpos);
+ if (command != 0)
+ x += 5;
+ {
+ uint16 y = data.word(kTextaddressy);
+ const uint8 *string = commandLine;
+ printdirect(&string, x, &y, textLen, (bool)(textLen & 1));
+ }
+ data.byte(kNewtextline) = 1;
}
-void DreamGenContext::cancelch0() {
- data.byte(kCh0repeat) = 0;
- data.word(kCh0blockstocopy) = 0;
- data.byte(kCh0playing) = 255;
- engine->stopSound(0);
+void DreamGenContext::showpanel() {
+ Frame *frame = (Frame *)segRef(data.word(kIcons1)).ptr(0, sizeof(Frame));
+ uint8 width, height;
+ showframe(frame, 72, 0, 19, 0, &width, &height);
+ showframe(frame, 192, 0, 19, 0, &width, &height);
}
-void DreamGenContext::cancelch1() {
- data.word(kCh1blockstocopy) = 0;
- data.byte(kCh1playing) = 255;
- engine->stopSound(1);
+bool DreamGenContext::isCD() {
+ // The original sources has two codepaths depending if the game is 'if cd' or not
+ // This is a hack to guess which version to use with the assumption that if we have a cd version
+ // we managed to load the speech. At least it is isolated in this function and can be changed.
+ // Maybe detect the version during game id?
+ return (data.byte(kSpeechloaded) == 1);
}
-
} /*namespace dreamgen */
+