diff options
Diffstat (limited to 'engines/sci/engine')
-rw-r--r-- | engines/sci/engine/kgraphics32.cpp | 186 | ||||
-rw-r--r-- | engines/sci/engine/object.h | 36 | ||||
-rw-r--r-- | engines/sci/engine/selector.cpp | 11 | ||||
-rw-r--r-- | engines/sci/engine/selector.h | 2 | ||||
-rw-r--r-- | engines/sci/engine/vm_types.cpp | 14 | ||||
-rw-r--r-- | engines/sci/engine/vm_types.h | 13 |
6 files changed, 148 insertions, 114 deletions
diff --git a/engines/sci/engine/kgraphics32.cpp b/engines/sci/engine/kgraphics32.cpp index 8d41393a9e..93e8b90ecc 100644 --- a/engines/sci/engine/kgraphics32.cpp +++ b/engines/sci/engine/kgraphics32.cpp @@ -80,21 +80,18 @@ reg_t kCantBeHere32(EngineState *s, int argc, reg_t *argv) { } reg_t kAddScreenItem(EngineState *s, int argc, reg_t *argv) { - if (g_sci->_gfxFrameout->findScreenItem(argv[0]) == NULL) - g_sci->_gfxFrameout->kernelAddScreenItem(argv[0]); - else - g_sci->_gfxFrameout->kernelUpdateScreenItem(argv[0]); - return s->r_acc; + g_sci->_gfxFrameout->kernelAddScreenItem(argv[0]); + return NULL_REG; } reg_t kUpdateScreenItem(EngineState *s, int argc, reg_t *argv) { g_sci->_gfxFrameout->kernelUpdateScreenItem(argv[0]); - return s->r_acc; + return NULL_REG; } reg_t kDeleteScreenItem(EngineState *s, int argc, reg_t *argv) { g_sci->_gfxFrameout->kernelDeleteScreenItem(argv[0]); - return s->r_acc; + return NULL_REG; } reg_t kAddPlane(EngineState *s, int argc, reg_t *argv) { @@ -115,11 +112,12 @@ reg_t kUpdatePlane(EngineState *s, int argc, reg_t *argv) { reg_t kAddPicAt(EngineState *s, int argc, reg_t *argv) { reg_t planeObj = argv[0]; GuiResourceId pictureId = argv[1].toUint16(); - int16 pictureX = argv[2].toSint16(); - int16 pictureY = argv[3].toSint16(); + int16 x = argv[2].toSint16(); + int16 y = argv[3].toSint16(); + bool mirrorX = argc > 4 ? argv[4].toSint16() : false; - g_sci->_gfxFrameout->kernelAddPicAt(planeObj, pictureId, pictureX, pictureY); - return s->r_acc; + g_sci->_gfxFrameout->kernelAddPicAt(planeObj, pictureId, x, y, mirrorX); + return NULL_REG; } reg_t kGetHighPlanePri(EngineState *s, int argc, reg_t *argv) { @@ -127,43 +125,13 @@ reg_t kGetHighPlanePri(EngineState *s, int argc, reg_t *argv) { } reg_t kFrameOut(EngineState *s, int argc, reg_t *argv) { -/* TODO: Transcribed from SCI engine disassembly. - GraphicsMgr &graphicsMgr = g_sci->_graphicsMgr; - if (graphicsMgr.palMorphNeeded) { - graphicsMgr.PalMorphFrameOut(&g_PalStyleRanges, false); - } - else { - // TODO: Not sure if this is a pointer or not yet. - if (g_ScrollState != nullptr) { - kFrameOutDoScroll(); - } - - bool showBits = true; - if (argc == 1) { - showBits = (bool) argv[0].toUint16(); - } - - rect SOL_Rect = { .left = 0, .top = 0, .right = UINT32_MAX, .bottom = UINT32_MAX }; - graphicsMgr.FrameOut(showBits, &rect); - } -*/ - g_sci->_gfxFrameout->kernelFrameout(); + bool showBits = argc > 0 ? argv[0].toUint16() : true; + g_sci->_gfxFrameout->kernelFrameout(showBits); return NULL_REG; } reg_t kSetPalStyleRange(EngineState *s, int argc, reg_t *argv) { -/* TODO: Transcribed from SCI engine disassembly. - uint16 start = argv[0].toUint16(); - uint16 end = argv[1].toUint16(); - if (end <= start) { - uint16 index = start; - while (index <= end) { - g_PalStyleRanges[index] = 0; - } - } -*/ - - kStub(s, argc, argv); + g_sci->_gfxFrameout->kernelSetPalStyleRange(argv[0].toUint16(), argv[1].toUint16()); return NULL_REG; } @@ -266,72 +234,59 @@ reg_t kWinHelp(EngineState *s, int argc, reg_t *argv) { } /** - * Used for scene transitions, replacing (but reusing parts of) the old - * transition code. + * Causes an immediate plane transition with an optional transition + * effect */ reg_t kSetShowStyle(EngineState *s, int argc, reg_t *argv) { - // Can be called with 7 or 8 parameters - // The style defines which transition to perform. Related to the transition - // tables inside graphics/transitions.cpp - uint16 showStyle = argv[0].toUint16(); // 0 - 15 - reg_t planeObj = argv[1]; // the affected plane - Common::String planeObjName = s->_segMan->getObjectName(planeObj); - uint16 seconds = argv[2].toUint16(); // seconds that the transition lasts - uint16 backColor = argv[3].toUint16(); // target back color(?). When fading out, it's 0x0000. When fading in, it's 0xffff - int16 priority = argv[4].toSint16(); // always 0xc8 (200) when fading in/out - uint16 animate = argv[5].toUint16(); // boolean, animate or not while the transition lasts - uint16 refFrame = argv[6].toUint16(); // refFrame, always 0 when fading in/out + ShowStyleType type = (ShowStyleType)argv[0].toUint16(); + reg_t planeObj = argv[1]; + int16 seconds = argv[2].toSint16(); + // NOTE: This value seems to indicate whether the transition is an + // “exit” transition (0) or an “enter” transition (-1) for fade + // transitions. For other types of transitions, it indicates a palette + // index value to use when filling the screen. + int16 back = argv[3].toSint16(); + int16 priority = argv[4].toSint16(); + int16 animate = argv[5].toSint16(); + // TODO: Rename to frameOutNow? + int16 refFrame = argv[6].toSint16(); + int16 blackScreen; + reg_t pFadeArray; int16 divisions; - // If the game has the pFadeArray selector, another parameter is used here, - // before the optional last parameter - bool hasFadeArray = g_sci->getKernel()->findSelector("pFadeArray") > 0; - if (hasFadeArray) { - // argv[7] - divisions = (argc >= 9) ? argv[8].toSint16() : -1; // divisions (transition steps?) - } else { - divisions = (argc >= 8) ? argv[7].toSint16() : -1; // divisions (transition steps?) + // SCI 2–2.1early + if (getSciVersion() < SCI_VERSION_2_1_MIDDLE) { + blackScreen = 0; + pFadeArray = NULL_REG; + divisions = argc > 7 ? argv[7].toSint16() : -1; } - - if (showStyle > 15) { - warning("kSetShowStyle: Illegal style %d for plane %04x:%04x", showStyle, PRINT_REG(planeObj)); - return s->r_acc; + // SCI 2.1mid–2.1late + else if (getSciVersion() < SCI_VERSION_3) { + blackScreen = 0; + pFadeArray = argc > 7 ? argv[7] : NULL_REG; + divisions = argc > 8 ? argv[8].toSint16() : -1; + } + // SCI 3 + else { + blackScreen = argv[7].toSint16(); + pFadeArray = argc > 8 ? argv[8] : NULL_REG; + divisions = argc > 9 ? argv[9].toSint16() : -1; } - // GK1 calls fadeout (13) / fadein (14) with the following parameters: - // seconds: 1 - // backColor: 0 / -1 - // fade: 200 - // animate: 0 - // refFrame: 0 - // divisions: 0 / 20 - - // TODO: Check if the plane is in the list of planes to draw - - Common::String effectName = "unknown"; +// TODO: Reuse later for SCI2 and SCI3 implementation and then discard +// warning("kSetShowStyle: effect %d, plane: %04x:%04x (%s), sec: %d, " +// "dir: %d, prio: %d, animate: %d, ref frame: %d, black screen: %d, " +// "pFadeArray: %04x:%04x (%s), divisions: %d", +// type, PRINT_REG(planeObj), s->_segMan->getObjectName(planeObj), seconds, +// back, priority, animate, refFrame, blackScreen, +// PRINT_REG(pFadeArray), s->_segMan->getObjectName(pFadeArray), divisions); - switch (showStyle) { - case 0: // no transition / show - effectName = "show"; - break; - case 13: // fade out - effectName = "fade out"; - // TODO - break; - case 14: // fade in - effectName = "fade in"; - // TODO - break; - default: - // TODO - break; - } + // NOTE: The order of planeObj and showStyle are reversed + // because this is how SCI3 called the corresponding method + // on the KernelMgr + g_sci->_gfxFrameout->kernelSetShowStyle(argc, planeObj, type, seconds, back, priority, animate, refFrame, pFadeArray, divisions, blackScreen); - warning("kSetShowStyle: effect %d (%s) - plane: %04x:%04x (%s), sec: %d, " - "back: %d, prio: %d, animate: %d, ref frame: %d, divisions: %d", - showStyle, effectName.c_str(), PRINT_REG(planeObj), planeObjName.c_str(), - seconds, backColor, priority, animate, refFrame, divisions); - return s->r_acc; + return NULL_REG; } reg_t kCelInfo(EngineState *s, int argc, reg_t *argv) { @@ -359,6 +314,8 @@ reg_t kCelInfo(EngineState *s, int argc, reg_t *argv) { } reg_t kScrollWindow(EngineState *s, int argc, reg_t *argv) { + return kStub(s, argc, argv); +#if 0 // Used by SQ6 and LSL6 hires for the text area in the bottom of the // screen. The relevant scripts also exist in Phantasmagoria 1, but they're // unused. This is always called by scripts 64906 (ScrollerWindow) and @@ -464,6 +421,7 @@ reg_t kScrollWindow(EngineState *s, int argc, reg_t *argv) { } return s->r_acc; +#endif } reg_t kSetFontRes(EngineState *s, int argc, reg_t *argv) { @@ -497,6 +455,8 @@ reg_t kFont(EngineState *s, int argc, reg_t *argv) { // TODO: Eventually, all of the kBitmap operations should be put // in a separate class +// NOTE: This size is correct only for SCI2.1mid; the size for +// SCI2/2.1early is 36 #define BITMAP_HEADER_SIZE 46 reg_t kBitmap(EngineState *s, int argc, reg_t *argv) { @@ -673,6 +633,8 @@ reg_t kEditText(EngineState *s, int argc, reg_t *argv) { } reg_t kAddLine(EngineState *s, int argc, reg_t *argv) { + return kStub(s, argc, argv); +#if 0 reg_t plane = argv[0]; Common::Point startPoint(argv[1].toUint16(), argv[2].toUint16()); Common::Point endPoint(argv[3].toUint16(), argv[4].toUint16()); @@ -681,10 +643,15 @@ reg_t kAddLine(EngineState *s, int argc, reg_t *argv) { byte priority = (byte)argv[7].toUint16(); byte control = (byte)argv[8].toUint16(); // argv[9] is unknown (usually a small number, 1 or 2). Thickness, perhaps? - return g_sci->_gfxFrameout->addPlaneLine(plane, startPoint, endPoint, color, priority, control); +// return g_sci->_gfxFrameout->addPlaneLine(plane, startPoint, endPoint, color, priority, control); + return s->r_acc; +#endif } reg_t kUpdateLine(EngineState *s, int argc, reg_t *argv) { + return kStub(s, argc, argv); + +#if 0 reg_t hunkId = argv[0]; reg_t plane = argv[1]; Common::Point startPoint(argv[2].toUint16(), argv[3].toUint16()); @@ -694,14 +661,18 @@ reg_t kUpdateLine(EngineState *s, int argc, reg_t *argv) { byte priority = (byte)argv[8].toUint16(); byte control = (byte)argv[9].toUint16(); // argv[10] is unknown (usually a small number, 1 or 2). Thickness, perhaps? - g_sci->_gfxFrameout->updatePlaneLine(plane, hunkId, startPoint, endPoint, color, priority, control); +// g_sci->_gfxFrameout->updatePlaneLine(plane, hunkId, startPoint, endPoint, color, priority, control); return s->r_acc; +#endif } reg_t kDeleteLine(EngineState *s, int argc, reg_t *argv) { + return kStub(s, argc, argv); +#if 0 reg_t hunkId = argv[0]; reg_t plane = argv[1]; - g_sci->_gfxFrameout->deletePlaneLine(plane, hunkId); +// g_sci->_gfxFrameout->deletePlaneLine(plane, hunkId); return s->r_acc; +#endif } reg_t kSetScroll(EngineState *s, int argc, reg_t *argv) { @@ -730,12 +701,7 @@ reg_t kSetScroll(EngineState *s, int argc, reg_t *argv) { // Used by SQ6, script 900, the datacorder reprogramming puzzle (from room 270) reg_t kMorphOn(EngineState *s, int argc, reg_t *argv) { - // TODO: g_sci->_gfxManager->palMorphIsOn = true - // This function sets the palMorphIsOn flag which causes kFrameOut to use - // an alternative FrameOut function (GraphicsMgr::PalMorphFrameOut instead - // of GraphicsMgr::FrameOut). At the end of the frame, kFrameOut sets the - // palMorphIsOn flag back to false. - kStub(s, argc, argv); + g_sci->_gfxFrameout->_palMorphIsOn = true; return NULL_REG; } diff --git a/engines/sci/engine/object.h b/engines/sci/engine/object.h index 0ae7ed2cab..cc9f5ebb52 100644 --- a/engines/sci/engine/object.h +++ b/engines/sci/engine/object.h @@ -41,8 +41,21 @@ enum { }; enum infoSelectorFlags { - kInfoFlagClone = 0x0001, - kInfoFlagClass = 0x8000 + kInfoFlagClone = 0x0001, +#ifdef ENABLE_SCI32 + /** + * When set, indicates to game scripts that a screen + * item can be updated. + */ + kInfoFlagViewVisible = 0x0008, // TODO: "dirty" ? + + /** + * When set, the object has an associated screen item in + * the rendering tree. + */ + kInfoFlagViewInserted = 0x0010, +#endif + kInfoFlagClass = 0x8000 }; enum ObjectOffsets { @@ -120,7 +133,24 @@ public: _infoSelectorSci3 = info; } - // No setter for the -info- selector +#ifdef ENABLE_SCI32 + void setInfoSelectorFlag(infoSelectorFlags flag) { + if (getSciVersion() < SCI_VERSION_3) { + _variables[_offset + 2] |= flag; + } else { + _infoSelectorSci3 |= flag; + } + } + + // NOTE: In real engine, -info- is treated as byte size + void clearInfoSelectorFlag(infoSelectorFlags flag) { + if (getSciVersion() < SCI_VERSION_3) { + _variables[_offset + 2] &= ~flag; + } else { + _infoSelectorSci3 &= ~flag; + } + } +#endif reg_t getNameSelector() const { if (getSciVersion() < SCI_VERSION_3) diff --git a/engines/sci/engine/selector.cpp b/engines/sci/engine/selector.cpp index 910f1f885f..05a9e6c980 100644 --- a/engines/sci/engine/selector.cpp +++ b/engines/sci/engine/selector.cpp @@ -187,6 +187,7 @@ void Kernel::mapSelectors() { FIND_SELECTOR(inLeft); FIND_SELECTOR(inBottom); FIND_SELECTOR(inRight); + FIND_SELECTOR(magnifier); #endif } @@ -211,8 +212,16 @@ void writeSelector(SegManager *segMan, reg_t object, Selector selectorId, reg_t if (lookupSelector(segMan, object, selectorId, &address, NULL) != kSelectorVariable) error("Selector '%s' of object at %04x:%04x could not be" " written to", g_sci->getKernel()->getSelectorName(selectorId).c_str(), PRINT_REG(object)); - else + else { *address.getPointer(segMan) = value; +#ifdef ENABLE_SCI32 + // TODO: Make this correct for all SCI versions + // Selectors 26 through 44 are selectors for View script objects + if (getSciVersion() >= SCI_VERSION_2 && selectorId >= 26 && selectorId <= 44) { + segMan->getObject(object)->setInfoSelectorFlag(kInfoFlagViewVisible); + } +#endif + } } void invokeSelector(EngineState *s, reg_t object, int selectorId, diff --git a/engines/sci/engine/selector.h b/engines/sci/engine/selector.h index b3dd393708..a8b195f245 100644 --- a/engines/sci/engine/selector.h +++ b/engines/sci/engine/selector.h @@ -153,6 +153,8 @@ struct SelectorCache { Selector useInsetRect; Selector inTop, inLeft, inBottom, inRight; + + Selector magnifier; #endif }; diff --git a/engines/sci/engine/vm_types.cpp b/engines/sci/engine/vm_types.cpp index cf008c45e1..53a5a5c507 100644 --- a/engines/sci/engine/vm_types.cpp +++ b/engines/sci/engine/vm_types.cpp @@ -210,6 +210,20 @@ reg_t reg_t::operator^(const reg_t right) const { return lookForWorkaround(right, "bitwise XOR"); } +#ifdef ENABLE_SCI32 +reg_t reg_t::operator&(int16 right) const { + return *this & make_reg(0, right); +} + +reg_t reg_t::operator|(int16 right) const { + return *this | make_reg(0, right); +} + +reg_t reg_t::operator^(int16 right) const { + return *this ^ make_reg(0, right); +} +#endif + int reg_t::cmp(const reg_t right, bool treatAsUnsigned) const { if (getSegment() == right.getSegment()) { // can compare things in the same segment if (treatAsUnsigned || !isNumber()) diff --git a/engines/sci/engine/vm_types.h b/engines/sci/engine/vm_types.h index af78bd0b84..a646478a8e 100644 --- a/engines/sci/engine/vm_types.h +++ b/engines/sci/engine/vm_types.h @@ -136,6 +136,19 @@ struct reg_t { reg_t operator|(const reg_t right) const; reg_t operator^(const reg_t right) const; +#ifdef ENABLE_SCI32 + reg_t operator&(int16 right) const; + reg_t operator|(int16 right) const; + reg_t operator^(int16 right) const; + + void operator&=(const reg_t &right) { *this = *this & right; } + void operator|=(const reg_t &right) { *this = *this | right; } + void operator^=(const reg_t &right) { *this = *this ^ right; } + void operator&=(int16 right) { *this = *this & right; } + void operator|=(int16 right) { *this = *this | right; } + void operator^=(int16 right) { *this = *this ^ right; } +#endif + private: /** * Compares two reg_t's. |