aboutsummaryrefslogtreecommitdiff
path: root/engines/dreamweb/object.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/dreamweb/object.cpp')
-rw-r--r--engines/dreamweb/object.cpp420
1 files changed, 401 insertions, 19 deletions
diff --git a/engines/dreamweb/object.cpp b/engines/dreamweb/object.cpp
index 44be58c168..9fe94c4bd4 100644
--- a/engines/dreamweb/object.cpp
+++ b/engines/dreamweb/object.cpp
@@ -24,7 +24,27 @@
namespace DreamGen {
-void DreamGenContext::fillRyan() {
+void DreamBase::showRyanPage() {
+ showFrame(engine->icons1(), kInventx + 167, kInventy - 12, 12, 0);
+ showFrame(engine->icons1(), kInventx + 167 + 18 * data.byte(kRyanpage), kInventy - 12, 13 + data.byte(kRyanpage), 0);
+}
+
+void DreamBase::findAllRyan(uint8 *inv) {
+ memset(inv, 0xff, 60);
+ for (size_t i = 0; i < kNumexobjects; ++i) {
+ DynObject *extra = getExAd(i);
+ if (extra->mapad[0] != 4)
+ continue;
+ if (extra->mapad[1] != 0xff)
+ continue;
+ uint8 slot = extra->mapad[2];
+ assert(slot < 30);
+ inv[2 * slot + 0] = i;
+ inv[2 * slot + 1] = 4;
+ }
+}
+
+void DreamBase::fillRyan() {
uint8 *inv = getSegment(data.word(kBuffers)).ptr(kRyaninvlist, 60);
findAllRyan(inv);
inv += data.byte(kRyanpage) * 2 * 10;
@@ -42,7 +62,7 @@ void DreamGenContext::isItWorn() {
flags._z = isItWorn((const DynObject *)es.ptr(bx, sizeof(DynObject)));
}
-bool DreamGenContext::isItWorn(const DynObject *object) {
+bool DreamBase::isItWorn(const DynObject *object) {
return (object->id[0] == 'W'-'A') && (object->id[1] == 'E'-'A');
}
@@ -72,7 +92,7 @@ void DreamGenContext::obToInv() {
obToInv(al, ah, di, bx);
}
-void DreamGenContext::obToInv(uint8 index, uint8 flag, uint16 x, uint16 y) {
+void DreamBase::obToInv(uint8 index, uint8 flag, uint16 x, uint16 y) {
showFrame(engine->icons1(), x - 2, y - 1, 10, 0);
if (index == 0xff)
return;
@@ -87,11 +107,11 @@ void DreamGenContext::obToInv(uint8 index, uint8 flag, uint16 x, uint16 y) {
showFrame(engine->icons1(), x - 3, y - 2, 7, 0);
}
-void DreamGenContext::obPicture() {
- if (data.byte(kObjecttype) == 1)
+void DreamBase::obPicture() {
+ if (data.byte(kObjecttype) == kSetObjectType1)
return;
Frame *frames;
- if (data.byte(kObjecttype) == 4)
+ if (data.byte(kObjecttype) == kExObjectType)
frames = (Frame *)getSegment(data.word(kExtras)).ptr(0, 0);
else
frames = (Frame *)getSegment(data.word(kFreeframes)).ptr(0, 0);
@@ -99,7 +119,7 @@ void DreamGenContext::obPicture() {
showFrame(frames, 160, 68, frame, 0x80);
}
-void DreamGenContext::obIcons() {
+void DreamBase::obIcons() {
uint8 value1, value2;
getAnyAd(&value1, &value2);
if (value1 != 0xff) {
@@ -113,6 +133,7 @@ void DreamGenContext::obIcons() {
void DreamGenContext::examineOb(bool examineAgain) {
data.byte(kPointermode) = 0;
data.word(kTimecount) = 0;
+
while (true) {
if (examineAgain) {
data.byte(kInmaparea) = 0;
@@ -120,8 +141,7 @@ void DreamGenContext::examineOb(bool examineAgain) {
data.byte(kOpenedob) = 255;
data.byte(kOpenedtype) = 255;
data.byte(kInvopen) = 0;
- al = data.byte(kCommandtype);
- data.byte(kObjecttype) = al;
+ data.byte(kObjecttype) = data.byte(kCommandtype);
data.byte(kItemframe) = 0;
data.byte(kPointerframe) = 0;
createPanel();
@@ -135,7 +155,7 @@ void DreamGenContext::examineOb(bool examineAgain) {
data.byte(kCommandtype) = 255;
readMouse();
showPointer();
- workToScreen();
+ workToScreenCPP();
delPointer();
examineAgain = false;
}
@@ -147,6 +167,7 @@ void DreamGenContext::examineOb(bool examineAgain) {
dumpTextLine();
delPointer();
data.byte(kGetback) = 0;
+
switch (data.byte(kInvopen)) {
case 0: {
RectWithCallback examList[] = {
@@ -154,22 +175,22 @@ void DreamGenContext::examineOb(bool examineAgain) {
{ 260,300,0,44,&DreamGenContext::useObject },
{ 210,254,0,44,&DreamGenContext::selectOpenOb },
{ 144,176,64,96,&DreamGenContext::setPickup },
- { 0,50,50,200,&DreamGenContext::examineInventory },
- { 0,320,0,200,&DreamGenContext::blank },
+ { 0,50,50,200,&DreamBase::examineInventory },
+ { 0,320,0,200,&DreamBase::blank },
{ 0xFFFF,0,0,0,0 }
};
checkCoords(examList);
break;
}
case 1: {
- // NB: This table contains the non-constant openChangeSize!
+ // Note: This table contains the non-constant _openChangeSize!
RectWithCallback invList1[] = {
{ 273,320,157,198,&DreamGenContext::getBackFromOb },
{ 255,294,0,24,&DreamGenContext::dropObject },
{ kInventx+167,kInventx+167+(18*3),kInventy-18,kInventy-2,&DreamGenContext::incRyanPage },
- { kInventx, data.word(offset_openchangesize),kInventy+100,kInventy+100+kItempicsize,&DreamGenContext::useOpened },
- { kInventx,kInventx+(5*kItempicsize), kInventy,kInventy+(2*kItempicsize),&DreamGenContext::inToInv },
- { 0,320,0,200,&DreamGenContext::blank },
+ { kInventx,_openChangeSize,kInventy+100,kInventy+100+kItempicsize,&DreamGenContext::useOpened },
+ { kInventx,kInventx+(5*kItempicsize),kInventy,kInventy+(2*kItempicsize),&DreamGenContext::inToInv },
+ { 0,320,0,200,&DreamBase::blank },
{ 0xFFFF,0,0,0,0 }
};
checkCoords(invList1);
@@ -180,13 +201,14 @@ void DreamGenContext::examineOb(bool examineAgain) {
{ 273,320,157,198,&DreamGenContext::getBackFromOb },
{ kInventx+167,kInventx+167+(18*3),kInventy-18,kInventy-2,&DreamGenContext::incRyanPage },
{ kInventx,kInventx+(5*kItempicsize), kInventy,kInventy+(2*kItempicsize),&DreamGenContext::selectOb },
- { 0,320,0,200,&DreamGenContext::blank },
+ { 0,320,0,200,&DreamBase::blank },
{ 0xFFFF,0,0,0,0 }
};
checkCoords(withList1);
break;
}
}
+
if (data.byte(kQuitrequested) != 0)
break;
if (data.byte(kExamagain) != 0)
@@ -238,7 +260,7 @@ void DreamGenContext::inventory() {
openInv();
readMouse();
showPointer();
- workToScreen();
+ workToScreenCPP();
delPointer();
data.byte(kOpenedob) = 255;
examineOb(false);
@@ -256,11 +278,371 @@ void DreamGenContext::transferText() {
data.word(kExtextpos) += len + 1;
}
-void DreamGenContext::getBackFromOb() {
+void DreamBase::getBackFromOb() {
if (data.byte(kPickup) != 1)
getBack1();
else
blank();
}
+void DreamGenContext::getOpenedSize() {
+ //ax = getOpenedSizeCPP();
+
+ // We need to call the ASM-style versions of get*Ad, as these also set
+ // bx and es
+
+ al = data.byte(kOpenedob);
+
+ switch (data.byte(kOpenedtype)) {
+ case 4:
+ getExAd();
+ ax = es.word(bx+7);
+ break;
+ case 2:
+ getFreeAd();
+ ax = es.word(bx+7);
+ break;
+ default:
+ getSetAd();
+ ax = es.word(bx+3);
+ break;
+ }
+}
+
+byte DreamGenContext::getOpenedSizeCPP() {
+ byte obj = data.byte(kOpenedob);
+ switch (data.byte(kOpenedtype)) {
+ case 4:
+ return getExAd(obj)->slotCount;
+ case 2:
+ return getFreeAd(obj)->slotCount;
+ default:
+ return getSetAd(obj)->slotCount;
+ }
+}
+
+void DreamGenContext::openOb() {
+ uint8 commandLine[64] = "OBJECT NAME ONE ";
+
+ copyName(data.byte(kOpenedtype), data.byte(kOpenedob), commandLine);
+
+ printMessage(kInventx, kInventy+86, 62, 240, false);
+
+ al = printDirect(commandLine, data.word(kLastxpos) + 5, kInventy+86, 220, false);
+
+ fillOpen();
+ _openChangeSize = getOpenedSizeCPP() * kItempicsize + kInventx;
+}
+
+void DreamGenContext::identifyOb() {
+ if (data.word(kWatchingtime) != 0) {
+ blank();
+ return;
+ }
+
+ ax = data.word(kMousex) - data.word(kMapadx);
+ bx = data.word(kMousey) - data.word(kMapady);
+
+ if (ax >= 22 * 8 || bx >= 20 * 8) {
+ blank();
+ return;
+ }
+
+ data.byte(kInmaparea) = 1;
+ ah = bl;
+ push(ax);
+ findPathOfPoint();
+ data.byte(kPointerspath) = dl;
+ ax = pop();
+ push(ax);
+ findFirstPath();
+ data.byte(kPointerfirstpath) = al;
+ ax = pop();
+
+ byte x = al;
+ byte y = ah;
+
+ if (checkIfEx(x, y) || checkIfFree(x, y) ||
+ checkIfPerson(x, y) || checkIfSet(x, y))
+ return; // finishidentify
+
+ x = (data.word(kMousex) - data.word(kMapadx)) & 0xFF;
+ y = (data.word(kMousey) - data.word(kMapady)) & 0xFF;
+ byte flag, flagEx, type, flagX, flagY;
+
+ checkOne(x, y, &flag, &flagEx, &type, &flagX, &flagY);
+
+ if (type != 0 && data.byte(kMandead) != 1)
+ obName(type, 3);
+ else
+ blank();
+}
+
+uint16 DreamGenContext::findInvPosCPP() {
+ uint16 x = data.word(kMousex) - kInventx;
+ uint16 y = data.word(kMousey) - kInventy;
+ uint16 pos = (x / kItempicsize) + (y / kItempicsize) * 5;
+ uint16 invPos = data.byte(kRyanpage) * 10 + pos;
+ data.byte(kLastinvpos) = invPos & 0xFF;
+ return invPos * 2 + kRyaninvlist;
+}
+
+void DreamGenContext::findInvPos() {
+ bx = findInvPosCPP();
+ es = data.word(kBuffers);
+}
+
+void DreamGenContext::selectOb() {
+ es = data.word(kBuffers);
+
+ uint16 objectId = es.word(findInvPosCPP());
+ if ((objectId & 0xFF) == 255) {
+ blank();
+ return;
+ }
+
+ data.byte(kWithobject) = objectId & 0x00FF;
+ data.byte(kWithtype) = objectId >> 8;
+
+ if (objectId == data.word(kOldsubject)) {
+ if (data.byte(kCommandtype) == 221) {
+ // Object already selected
+ if (data.word(kMousebutton) != data.word(kOldbutton) && (data.word(kMousebutton) & 1)) {
+ delPointer();
+ data.byte(kInvopen) = 0;
+ useRoutine();
+ }
+ return;
+ } else {
+ data.byte(kCommandtype) = 221;
+ }
+ }
+
+ data.word(kOldsubject) = objectId;
+ commandWithOb(0, data.byte(kWithtype), data.byte(kWithobject));
+
+ if (data.word(kMousebutton) != data.word(kOldbutton) && (data.word(kMousebutton) & 1)) {
+ delPointer();
+ data.byte(kInvopen) = 0;
+ useRoutine();
+ }
+}
+
+void DreamGenContext::setPickup() {
+ if (data.byte(kObjecttype) != kSetObjectType1 && data.byte(kObjecttype) != kSetObjectType3) {
+ // The original called getAnyAd() here. However, since object types
+ // 1 and 3 are excluded, the resulting object is a DynObject
+ uint8 dummy;
+ DynObject *object = (DynObject *)getAnyAd(&dummy, &dummy);
+ if (object->mapad[0] == 4) {
+ blank();
+ return;
+ }
+ } else {
+ blank();
+ return;
+ }
+
+ if (data.byte(kCommandtype) != 209) {
+ data.byte(kCommandtype) = 209;
+ commandWithOb(33, data.byte(kObjecttype), data.byte(kCommand));
+ }
+
+ if (data.word(kMousebutton) != 1 || data.word(kMousebutton) == data.word(kOldbutton))
+ return;
+
+ createPanel();
+ showPanel();
+ showMan();
+ showExit();
+ examIcon();
+ data.byte(kPickup) = 1;
+ data.byte(kInvopen) = 2;
+
+ if (data.byte(kObjecttype) != kExObjectType) {
+ data.byte(kItemframe) = data.byte(kCommand);
+ data.byte(kOpenedob) = 255;
+ transferToEx();
+ data.byte(kItemframe) = al;
+ data.byte(kObjecttype) = kExObjectType;
+ DynObject *object = getExAd(data.byte(kItemframe));
+ object->mapad[0] = 20;
+ object->mapad[1] = 255;
+ } else {
+ data.byte(kItemframe) = data.byte(kCommand);
+ data.byte(kOpenedob) = 255;
+ }
+
+ openInv();
+ workToScreenM();
+}
+
+void DreamGenContext::deleteExFrame() {
+ deleteExFrame(al);
+}
+
+void DreamBase::deleteExFrame(uint8 frameNum) {
+ Frame *frame = (Frame *)getSegment(data.word(kExtras)).ptr(kExframedata + sizeof(Frame)*frameNum, sizeof(Frame));
+
+ uint16 frameSize = frame->width * frame->height;
+ // Note: the original asm didn't subtract frameSize from remainder
+ uint16 remainder = kExframeslen - frame->ptr() - frameSize;
+ uint16 startOff = kExframes + frame->ptr();
+ uint16 endOff = startOff + frameSize;
+
+ // Shift frame data after this one down
+ memmove(getSegment(data.word(kExtras)).ptr(startOff, remainder), getSegment(data.word(kExtras)).ptr(endOff, remainder), remainder);
+
+ // Combined frame data is now frameSize smaller
+ data.word(kExframepos) -= frameSize;
+
+ // Adjust all frame pointers pointing into the shifted data
+ for (unsigned int i = 0; i < 3*kNumexobjects; ++i) {
+ frame = (Frame *)getSegment(data.word(kExtras)).ptr(kExframedata + sizeof(Frame)*i, sizeof(Frame));
+ if (frame->ptr() >= startOff)
+ frame->setPtr(frame->ptr() - frameSize);
+ }
+}
+
+void DreamGenContext::deleteExText() {
+ deleteExText(al);
+}
+
+void DreamBase::deleteExText(uint8 textNum) {
+ uint16 offset = getSegment(data.word(kExtras)).word(kExtextdat + 2*textNum);
+
+ uint16 startOff = kExtext + offset;
+ uint16 textSize = strlen((char *)getSegment(data.word(kExtras)).ptr(startOff, 0)) + 1;
+ uint16 endOff = startOff + textSize;
+ uint16 remainder = kExtextlen - offset - textSize;
+
+ // Shift text data after this one down
+ memmove(getSegment(data.word(kExtras)).ptr(startOff, remainder), getSegment(data.word(kExtras)).ptr(endOff, remainder), remainder);
+
+ // Combined text data is now frameSize smaller
+ data.word(kExtextpos) -= textSize;
+
+ // Adjust all text pointers pointing into the shifted data
+ for (unsigned int i = 0; i < kNumexobjects; ++i) {
+ uint16 t = getSegment(data.word(kExtras)).word(kExtextdat + 2*i);
+ if (t >= offset + textSize)
+ getSegment(data.word(kExtras)).word(kExtextdat + 2*i) = t - textSize;
+ }
+}
+
+// This takes es:di and cl as input, but es:di always points to getExAd(cl)
+void DreamGenContext::deleteExObject() {
+ deleteExObject(cl);
+}
+
+void DreamBase::deleteExObject(uint8 index) {
+ DynObject *obj = getExAd(index);
+
+ memset(obj, 0xFF, sizeof(DynObject));
+
+ deleteExFrame(3*index);
+ deleteExFrame(3*index + 1);
+
+ deleteExText(index);
+
+ for (uint8 i = 0; i < kNumexobjects; ++i) {
+ DynObject *t = getExAd(index);
+ // Is this object contained in the one we've just deleted?
+ if (t->mapad[0] == 4 && t->mapad[1] == index)
+ deleteExObject(i);
+ }
+}
+
+void DreamBase::removeObFromInv() {
+ if (data.byte(kCommand) == 100)
+ return; // object doesn't exit
+
+ assert(data.byte(kObjecttype) == kExObjectType);
+
+ deleteExObject(data.byte(kCommand));
+}
+
+void DreamGenContext::inToInv() {
+ if (!data.byte(kPickup)) {
+ outOfInv();
+ return;
+ }
+
+ findInvPos();
+ ax = es.word(bx);
+
+ if (al != 255) {
+ swapWithInv();
+ return;
+ }
+
+ al = data.byte(kItemframe);
+ ah = data.byte(kObjecttype);
+
+ if (ax == data.word(kOldsubject) && data.byte(kCommandtype) != 220)
+ data.byte(kCommandtype) = 220;
+
+ data.word(kOldsubject) = ax;
+ commandWithOb(35, data.byte(kObjecttype), data.byte(kItemframe));
+
+ if (data.word(kMousebutton) == data.word(kOldbutton) || !(data.word(kMousebutton) & 1))
+ return; // notletgo2
+
+ delPointer();
+ DynObject *object = getExAd(data.byte(kItemframe));
+ object->mapad[0] = 4;
+ object->mapad[1] = 255;
+ object->mapad[2] = data.byte(kLastinvpos);
+ data.byte(kPickup) = 0;
+ fillRyan();
+ readMouse();
+ showPointer();
+ outOfInv();
+ workToScreen();
+ delPointer();
+}
+
+void DreamGenContext::outOfInv() {
+ findInvPos();
+ ax = es.word(bx);
+
+ if (al == 255) {
+ blank();
+ return;
+ }
+
+ if (data.word(kMousebutton) == 2) {
+ reExFromInv();
+ return;
+ }
+
+ if (ax == data.word(kOldsubject) && data.byte(kCommandtype) != 221)
+ data.byte(kCommandtype) = 221;
+
+ data.word(kOldsubject) = ax;
+ commandWithOb(36, ah, al);
+
+ if (data.word(kMousebutton) == data.word(kOldbutton))
+ return; // notletgo
+
+ if (!(data.word(kMousebutton) & 1))
+ return;
+
+ delPointer();
+ data.byte(kPickup) = 1;
+ findInvPos();
+ ax = es.word(bx);
+ data.byte(kItemframe) = al;
+ data.byte(kObjecttype) = ah;
+ DynObject *object = getExAd(data.byte(kItemframe));
+ object->mapad[0] = 20;
+ object->mapad[1] = 255;
+ fillRyan();
+ readMouse();
+ showPointer();
+ inToInv();
+ workToScreen();
+ delPointer();
+}
+
} // End of namespace DreamGen