void DreamGenContext::showallex() { data.word(kListpos) = kExlist; memset(segRef(data.word(kBuffers)).ptr(kExlist, 100 * 5), 0xff, 100 * 5); data.word(kFrsegment) = data.word(kExtras); data.word(kDataad) = kExframedata; data.word(kFramesad) = kExframes; data.byte(kCurrentex) = 0; DynObject *objects = (DynObject *)segRef(data.word(kExtras)).ptr(kExdata, sizeof(DynObject)); for (size_t i = 0; i < 100; ++i, ++data.byte(kCurrentex)) { DynObject *object = objects + i; if (object->mapad[0] == 0xff) continue; if (object->currentLocation != data.byte(kReallocation)) continue; if (getmapad(object->mapad) == 0) continue; data.word(kCurrentframe) = 3 * data.byte(kCurrentex); uint8 width, height; calcfrframe(&width, &height); uint16 x, y; finalframe(&x, &y); if ((width != 0) || (height != 0)) { showframe((Frame *)segRef(data.word(kFrsegment)).ptr(0, 0), x + data.word(kMapadx), y + data.word(kMapady), data.word(kCurrentframe) & 0xff, 0); ObjPos *objPos = (ObjPos *)segRef(data.word(kBuffers)).ptr(data.word(kListpos), sizeof(ObjPos)); objPos->xMin = data.byte(kSavex); objPos->yMin = data.byte(kSavey); objPos->xMax = data.byte(kSavesize + 0) + data.byte(kSavex); objPos->yMax = data.byte(kSavesize + 1) + data.byte(kSavey); objPos->index = i; data.word(kListpos) += sizeof(ObjPos); } } }
void DreamGenContext::showallfree() { data.word(kListpos) = kFreelist; ObjPos *listPos = (ObjPos *)segRef(data.word(kBuffers)).ptr(kFreelist, 80 * sizeof(ObjPos)); memset(listPos, 0xff, 80 * sizeof(ObjPos)); data.word(kFrsegment) = data.word(kFreeframes); data.word(kDataad) = kFrframedata; data.word(kFramesad) = kFrframes; data.byte(kCurrentfree) = 0; const DynObject *freeObjects = (const DynObject *)segRef(data.word(kFreedat)).ptr(0, 0); for(size_t i = 0; i < 80; ++i) { uint8 mapad = getmapad(freeObjects[i].mapad); if (mapad != 0) { data.word(kCurrentframe) = 3 * data.byte(kCurrentfree); uint8 width, height; calcfrframe(&width, &height); uint16 x, y; finalframe(&x, &y); if ((width != 0) || (height != 0)) { x += data.word(kMapadx); y += data.word(kMapady); showframe((Frame *)segRef(data.word(kFrsegment)).ptr(0, 0), x, y, data.word(kCurrentframe) & 0xff, 0); ObjPos *objPos = (ObjPos *)segRef(data.word(kBuffers)).ptr(data.word(kListpos), sizeof(ObjPos)); objPos->xMin = data.byte(kSavex); objPos->yMin = data.byte(kSavey); objPos->xMax = data.byte(kSavex) + data.byte(kSavesize+0); objPos->yMax = data.byte(kSavey) + data.byte(kSavesize+1); objPos->index = i; data.word(kListpos) += sizeof(ObjPos); } } ++data.byte(kCurrentfree); } }
void DreamGenContext::commandonly(uint8 command) { deltextline(); uint16 index = command * 2; uint16 offset = kTextstart + segRef(data.word(kCommandtext)).word(index); uint16 y = data.word(kTextaddressy); const uint8 *string = segRef(data.word(kCommandtext)).ptr(offset, 0); printdirect(&string, data.word(kTextaddressx), &y, data.byte(kTextlen), (bool)(data.byte(kTextlen) & 1)); data.byte(kNewtextline) = 1; }
void DreamGenContext::obicons() { uint8 value1, value2; getanyad(&value1, &value2); if (value1 == 0xff) { showframe((Frame *)segRef(data.word(kIcons2)).ptr(0, 0), 260, 1, 1, 0); } else { showframe((Frame *)segRef(data.word(kIcons2)).ptr(0, 0), 210, 1, 4, 0); } }
void DreamGenContext::deletetaken() { const DynObject *extraObjects = (const DynObject *)segRef(data.word(kExtras)).ptr(kExdata, 0); DynObject *freeObjects = (DynObject *)segRef(data.word(kFreedat)).ptr(0, 0); for(size_t i = 0; i < kNumexobjects; ++i) { uint8 location = extraObjects[i].initialLocation; if (location == data.byte(kReallocation)) { uint8 index = extraObjects[i].index; freeObjects[index].mapad[0] = 0xfe; } } }
void DreamGenContext::obpicture() { if (data.byte(kObjecttype) == 1) return; Frame *frames; if (data.byte(kObjecttype) == 4) frames = (Frame *)segRef(data.word(kExtras)).ptr(0, 0); else frames = (Frame *)segRef(data.word(kFreeframes)).ptr(0, 0); uint8 frame = 3 * data.byte(kCommand) + 1; showframe(frames, 160, 68, frame, 0x80); }
void DreamGenContext::drawflags() { uint8 *mapFlags = segRef(data.word(kBuffers)).ptr(kMapflags, 0); const uint8 *mapData = segRef(data.word(kMapdata)).ptr(kMap + data.byte(kMapy) * kMapwidth + data.byte(kMapx), 0); const uint8 *backdropFlags = segRef(data.word(kBackdrop)).ptr(kFlags, 0); for (size_t i = 0; i < 10; ++i) { for (size_t j = 0; j < 11; ++j) { uint8 tile = mapData[i * kMapwidth + j]; mapFlags[0] = backdropFlags[2 * tile + 0]; mapFlags[1] = backdropFlags[2 * tile + 1]; mapFlags[2] = tile; mapFlags += 3; } } }
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->reelPointer(); 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->routinePointer(); obname(people->b4, 5); return true; } return false; }
void DreamGenContext::getdimension(uint8 *mapXstart, uint8 *mapYstart, uint8 *mapXsize, uint8 *mapYsize) { const uint8 *mapFlags = segRef(data.word(kBuffers)).ptr(kMapflags, 0); uint8 yStart = 0; while (! addalong(mapFlags + 3 * 11 * yStart)) ++yStart; uint8 xStart = 0; while (! addlength(mapFlags + 3 * xStart)) ++xStart; uint8 yEnd = 10; while (! addalong(mapFlags + 3 * 11 * (yEnd - 1))) --yEnd; uint8 xEnd = 11; while (! addlength(mapFlags + 3 * (xEnd - 1))) --xEnd; *mapXstart = xStart; *mapYstart = yStart; *mapXsize = xEnd - xStart; *mapYsize = yEnd - yStart; data.word(kMapxstart) = xStart << 4; data.word(kMapystart) = yStart << 4; data.byte(kMapxsize) = *mapXsize << 4; data.byte(kMapysize) = *mapYsize << 4; }
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); }
void DreamGenContext::setallchanges() { Change *change = (Change *)segRef(data.word(kBuffers)).ptr(kListofchanges, sizeof(Change)); while (change->index != 0xff) { if (change->location == data.byte(kReallocation)) dochange(change->index, change->value, change->type); ++change; } }
void DreamGenContext::delpointer() { if (data.word(kOldpointerx) == 0xffff) return; data.word(kDelherex) = data.word(kOldpointerx); data.word(kDelherey) = data.word(kOldpointery); data.byte(kDelxs) = data.byte(kPointerxs); data.byte(kDelys) = data.byte(kPointerys); multiput(segRef(data.word(kBuffers)).ptr(kPointerback, 0), data.word(kDelherex), data.word(kDelherey), data.byte(kPointerxs), data.byte(kPointerys)); }
void DreamGenContext::calcfrframe(uint8* width, uint8* height) { const Frame *frame = (const Frame *)segRef(data.word(kFrsegment)).ptr(data.word(kCurrentframe) * sizeof(Frame), sizeof(Frame)); data.word(kSavesource) = data.word(kFramesad) + frame->ptr(); data.byte(kSavesize+0) = frame->width; data.byte(kSavesize+1) = frame->height; data.word(kOffsetx) = frame->x; data.word(kOffsety) = frame->y; *width = frame->width; *height = frame->height; }
void DreamGenContext::showpointer() { showblink(); const Frame *icons1 = ((const Frame *)segRef(data.word(kIcons1)).ptr(0, 0)); uint16 x = data.word(kMousex); data.word(kOldpointerx) = data.word(kMousex); uint16 y = data.word(kMousey); data.word(kOldpointery) = data.word(kMousey); if (data.byte(kPickup) == 1) { const Frame *frames; if (data.byte(kObjecttype) != 4) frames = (const Frame *)segRef(data.word(kFreeframes)).ptr(0, 0); else frames = (const Frame *)segRef(data.word(kExtras)).ptr(0, 0); const Frame *frame = frames + (3 * data.byte(kItemframe) + 1); uint8 width = frame->width; uint8 height = frame->height; if (width < 12) width = 12; if (height < 12) height = 12; data.byte(kPointerxs) = width; data.byte(kPointerys) = height; uint16 xMin = (x >= width / 2) ? x - width / 2 : 0; uint16 yMin = (y >= height / 2) ? y - height / 2 : 0; data.word(kOldpointerx) = xMin; data.word(kOldpointery) = yMin; multiget(segRef(data.word(kBuffers)).ptr(kPointerback, 0), xMin, yMin, width, height); showframe(frames, x, y, 3 * data.byte(kItemframe) + 1, 128); showframe(icons1, x, y, 3, 128); } else { const Frame *frame = icons1 + (data.byte(kPointerframe) + 20); uint8 width = frame->width; uint8 height = frame->height; if (width < 12) width = 12; if (height < 12) height = 12; data.byte(kPointerxs) = width; data.byte(kPointerys) = height; multiget(segRef(data.word(kBuffers)).ptr(kPointerback, 0), x, y, width, height); showframe(icons1, x, y, data.byte(kPointerframe) + 20, 0); } }
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 { uint16 offset = segRef(data.word(kBlockdesc)).word(kBlocktextdat + index * 2) + kBlocktext; return segRef(data.word(kBlockdesc)).ptr(offset, 0); } }
void DreamGenContext::crosshair() { uint8 frame; if ((data.byte(kCommandtype) != 3) && (data.byte(kCommandtype) < 10)) { frame = 9; } else { frame = 29; } const Frame *src = (const Frame *)segRef(data.word(kIcons1)).ptr(0, 0); showframe(src, kZoomx + 24, kZoomy + 19, frame, 0); }
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::getexpos() { es = data.word(kExtras); const DynObject *objects = (const DynObject *)segRef(data.word(kExtras)).ptr(kExdata, sizeof(DynObject)); for (size_t i = 0; i < kNumexobjects; ++i) { if (objects[i].mapad[0] == 0xff) { data.byte(kExpos) = i; di = kExdata + i * sizeof(DynObject); return; } } data.byte(kExpos) = kNumexobjects; di = kExdata + kNumexobjects * sizeof(DynObject); }
void DreamGenContext::showallobs() { data.word(kListpos) = kSetlist; memset(segRef(data.word(kBuffers)).ptr(kSetlist, 0), 0xff, 128 * 5); data.word(kFrsegment) = data.word(kSetframes); data.word(kDataad) = kFramedata; data.word(kFramesad) = kFrames; const Frame *frames = (const Frame *)segRef(data.word(kFrsegment)).ptr(0, 0); SetObject *setEntries = (SetObject *)segRef(data.word(kSetdat)).ptr(0, 128 * sizeof(SetObject)); for (size_t i = 0; i < 128; ++i) { SetObject *setEntry = setEntries + i; if (getmapad(setEntry->mapad) == 0) continue; uint8 currentFrame = setEntry->b18[0]; data.word(kCurrentframe) = currentFrame; if (currentFrame == 0xff) continue; calcfrframe(); uint16 x, y; finalframe(&x, &y); setEntry->index = setEntry->b18[0]; if ((setEntry->type == 0) && (setEntry->priority != 5) && (setEntry->priority != 6)) { x += data.word(kMapadx); y += data.word(kMapady); showframe(frames, x, y, data.word(kCurrentframe), 0); } else makebackob(setEntry); ObjPos *objPos = (ObjPos *)segRef(data.word(kBuffers)).ptr(data.word(kListpos), sizeof(ObjPos)); objPos->xMin = data.byte(kSavex); objPos->yMin = data.byte(kSavey); objPos->xMax = data.byte(kSavex) + data.byte(kSavesize+0); objPos->yMax = data.byte(kSavey) + data.byte(kSavesize+1); objPos->index = i; data.word(kListpos) += sizeof(ObjPos); } }
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(); } dx = pop(); cx = pop(); bx = pop(); ax = pop(); if ((data.byte(kSpeechloaded) == 1) && (data.byte(kSubtitles) != 1)) return; } #endif 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::findormake(uint8 index, uint8 value, uint8 type) { Change *change = (Change *)segRef(data.word(kBuffers)).ptr(kListofchanges, sizeof(Change)); while (true) { if (change->index == 0xff) { change->index = index; change->location = data.byte(kReallocation); change->value = value; change->type = type; return; } if ((index == change->index) && (data.byte(kReallocation) == change->location) && (type == change->type)) { change->value = value; return; } ++change; } }
bool DreamGenContext::checkiffree(uint8 x, uint8 y) { const ObjPos *freeList = (const ObjPos *)segRef(data.word(kBuffers)).ptr(kFreelist, 80 * sizeof(ObjPos)); for (size_t i = 0; i < 80; ++i) { const ObjPos *objPos = freeList + 79 - i; if (objPos->index == 0xff) continue; if (x < objPos->xMin) continue; if (x >= objPos->xMax) continue; if (y < objPos->yMin) continue; if (y >= objPos->yMax) continue; obname(objPos->index, 2); return true; } return false; }
bool DreamGenContext::checkifex(uint8 x, uint8 y) { const ObjPos *exList = (const ObjPos *)segRef(data.word(kBuffers)).ptr(kExlist, 100 * sizeof(ObjPos)); for (size_t i = 0; i < 100; ++i) { const ObjPos *objPos = exList + 99 - i; if (objPos->index == 0xff) continue; if (x < objPos->xMin) continue; if (x >= objPos->xMax) continue; if (y < objPos->yMin) continue; if (y >= objPos->yMax) continue; obname(objPos->index, 4); return true; } return false; }
void DreamGenContext::makebackob(SetObject *objData) { if (data.byte(kNewobs) == 0) return; uint8 priority = objData->priority; uint8 type = objData->type; Sprite *sprite = makesprite(data.word(kObjectx), data.word(kObjecty), addr_backobject, data.word(kSetframes), 0); uint16 objDataOffset = (uint8 *)objData - segRef(data.word(kSetdat)).ptr(0, 0); assert(objDataOffset % sizeof(SetObject) == 0); assert(objDataOffset < 128 * sizeof(SetObject)); sprite->setObjData(objDataOffset); if (priority == 255) priority = 0; sprite->priority = priority; sprite->type = type; sprite->b16 = 0; sprite->delay = 0; sprite->frame = 0; }
void DreamGenContext::showblink() { if (data.byte(kManisoffscreen) == 1) return; ++data.byte(kBlinkcount); if (data.byte(kShadeson) != 0) return; if (data.byte(kReallocation) >= 50) // eyesshut return; if (data.byte(kBlinkcount) != 3) return; data.byte(kBlinkcount) = 0; uint8 blinkFrame = data.byte(kBlinkframe); ++blinkFrame; // Implicit %256 data.byte(kBlinkframe) = blinkFrame; if (blinkFrame > 6) blinkFrame = 6; static const uint8 blinkTab[] = { 16,18,18,17,16,16,16 }; uint8 width, height; showframe((Frame *)segRef(data.word(kIcons1)).ptr(0, 0), 44, 32, blinkTab[blinkFrame], 0, &width, &height); }
uint8 DreamGenContext::printslow(const uint8 *string, uint16 x, uint16 y, uint8 maxWidth, bool centered) { data.byte(kPointerframe) = 1; data.byte(kPointermode) = 3; const Frame* charSet = (const Frame *)segRef(data.word(kCharset1)).ptr(0, 0); do { uint16 offset = x; uint16 charCount = getnumber(charSet, string, maxWidth, centered, &offset); do { uint8 c0 = string[0]; uint8 c1 = string[1]; uint8 c2 = string[2]; c0 = engine->modifyChar(c0); printboth(charSet, &offset, y, c0, c1); if ((c1 == 0) || (c1 == ':')) { return 0; } if (charCount != 1) { c1 = engine->modifyChar(c1); data.word(kCharshift) = 91; uint16 offset2 = offset; printboth(charSet, &offset2, y, c1, c2); data.word(kCharshift) = 0; for (int i=0; i<2; ++i) { uint16 mouseState = waitframes(); if (mouseState == 0) continue; if (mouseState != data.word(kOldbutton)) { return 1; } } } ++string; --charCount; } while (charCount); y += 10; } while (true); }
void DreamGenContext::printdirect(const uint8** string, uint16 x, uint16 *y, uint8 maxWidth, bool centered) { data.word(kLastxpos) = x; const Frame *charSet = (const Frame *)segRef(data.word(kCurrentset)).ptr(0, 0); while (true) { uint16 offset = x; uint8 charCount = getnumber(charSet, *string, maxWidth, centered, &offset); uint16 i = offset; do { uint8 c = (*string)[0]; uint8 nextChar = (*string)[1]; ++(*string); if ((c == 0) || (c == ':')) { return; } c = engine->modifyChar(c); uint8 width, height; printchar(charSet, &i, *y, c, nextChar, &width, &height); data.word(kLastxpos) = i; --charCount; } while(charCount); *y += data.word(kLinespacing); } }
RoomPaths *DreamGenContext::getroomspaths() { void *result = segRef(data.word(kReels)).ptr(data.byte(kRoomnum) * 144, 144); return (RoomPaths *)result; }
void DreamGenContext::turnanypathoff(uint8 param, uint8 room) { findormake(param, 0x00, room + 100); PathNode *paths = (PathNode *)segRef(data.word(kReels)).ptr(kPathdata + 144 * room, 0); paths[param].on = 0x00; }
void DreamGenContext::printmessage(uint16 x, uint16 y, uint8 index, uint8 maxWidth, bool centered) { uint16 offset = kTextstart + segRef(data.word(kCommandtext)).word(index * 2); const uint8 *string = segRef(data.word(kCommandtext)).ptr(offset, 0); printdirect(&string, x, &y, maxWidth, centered); }