diff options
Diffstat (limited to 'engines/sci/engine/kgraphics.cpp')
-rw-r--r-- | engines/sci/engine/kgraphics.cpp | 264 |
1 files changed, 138 insertions, 126 deletions
diff --git a/engines/sci/engine/kgraphics.cpp b/engines/sci/engine/kgraphics.cpp index 02891dde9e..282ca0f842 100644 --- a/engines/sci/engine/kgraphics.cpp +++ b/engines/sci/engine/kgraphics.cpp @@ -129,8 +129,7 @@ static reg_t kSetCursorSci11(EngineState *s, int argc, reg_t *argv) { g_sci->_gfxCursor->kernelHide(); break; case -1: - // TODO: Special case at least in kq6, check disassembly - // Does something with magCursor, which is set on argc = 10, which we don't support + g_sci->_gfxCursor->kernelClearZoomZone(); break; case -2: g_sci->_gfxCursor->kernelResetMoveZone(); @@ -184,15 +183,10 @@ static reg_t kSetCursorSci11(EngineState *s, int argc, reg_t *argv) { break; case 10: // Freddy pharkas, when using the whiskey glass to read the prescription (bug #3034973) - // magnifier support, disabled using argc == 1, argv == -1 - warning("kSetCursor: unsupported magnifier"); - // we just set the view cursor currently - g_sci->_gfxCursor->kernelSetView(argv[5].toUint16(), argv[6].toUint16(), argv[7].toUint16(), hotspot); - // argv[0] -> 1, 2, 4 -> maybe magnification multiplier - // argv[1-4] -> rect for magnification - // argv[5, 6, 7] -> view resource for cursor - // argv[8] -> picture resource for mag - // argv[9] -> color for magnifier replacement + g_sci->_gfxCursor->kernelSetZoomZone(argv[0].toUint16(), + Common::Rect(argv[1].toUint16(), argv[2].toUint16(), argv[3].toUint16(), argv[4].toUint16()), + argv[5].toUint16(), argv[6].toUint16(), argv[7].toUint16(), + argv[8].toUint16(), argv[9].toUint16()); break; default : error("kSetCursor: Unhandled case: %d arguments given", argc); @@ -347,6 +341,11 @@ reg_t kTextSize(EngineState *s, int argc, reg_t *argv) { int maxwidth = (argc > 3) ? argv[3].toUint16() : 0; int font_nr = argv[2].toUint16(); + if (!dest) { + debugC(2, kDebugLevelStrings, "GetTextSize: Empty destination"); + return s->r_acc; + } + Common::String sep_str; const char *sep = NULL; if ((argc > 4) && (argv[4].segment)) { @@ -356,7 +355,7 @@ reg_t kTextSize(EngineState *s, int argc, reg_t *argv) { dest[0] = dest[1] = NULL_REG; - if (text.empty() || !dest) { // Empty text + if (text.empty()) { // Empty text dest[2] = dest[3] = make_reg(0, 0); debugC(2, kDebugLevelStrings, "GetTextSize: Empty string"); return s->r_acc; @@ -808,6 +807,7 @@ void _k_GenericDrawControl(EngineState *s, reg_t controlObject, bool hilite) { alignment = readSelectorValue(s->_segMan, controlObject, SELECTOR(mode)); debugC(2, kDebugLevelGraphics, "drawing text %04x:%04x ('%s') to %d,%d, mode=%d", PRINT_REG(controlObject), text.c_str(), x, y, alignment); g_sci->_gfxControls->kernelDrawText(rect, controlObject, g_sci->strSplit(text.c_str()).c_str(), fontId, alignment, style, hilite); + s->r_acc = g_sci->_gfxText16->allocAndFillReferenceRectArray(); return; case SCI_CONTROLS_TYPE_TEXTEDIT: @@ -903,6 +903,10 @@ reg_t kDrawControl(EngineState *s, int argc, reg_t *argv) { reg_t controlObject = argv[0]; Common::String objName = s->_segMan->getObjectName(controlObject); + // Most of the time, we won't return anything to the caller + // but |r| textcodes will trigger creation of rects in memory and will then set s->r_acc + s->r_acc = NULL_REG; + // Disable the "Change Directory" button, as we don't allow the game engine to // change the directory where saved games are placed // "changeDirItem" is used in the import windows of QFG2&3 @@ -941,7 +945,7 @@ reg_t kDrawControl(EngineState *s, int argc, reg_t *argv) { } _k_GenericDrawControl(s, controlObject, false); - return NULL_REG; + return s->r_acc; } reg_t kHiliteControl(EngineState *s, int argc, reg_t *argv) { @@ -1191,6 +1195,57 @@ reg_t kShow(EngineState *s, int argc, reg_t *argv) { return s->r_acc; } +reg_t kRemapColors(EngineState *s, int argc, reg_t *argv) { + // TODO: This is all a stub/skeleton, thus we're invoking kStub() for now + kStub(s, argc, argv); + + uint16 operation = argv[0].toUint16(); + + switch (operation) { + case 0: { // Initialize remapping to base. 0 turns remapping off. + //int16 unk1 = (argc >= 2) ? argv[1].toSint16() : 0; + } + break; + case 1: { // unknown + // The demo of QFG4 calls this with 1+3 parameters, thus there are differences here + //int16 unk1 = argv[1].toSint16(); + //int16 unk2 = argv[2].toSint16(); + //int16 unk3 = argv[3].toSint16(); + //uint16 unk4 = argv[4].toUint16(); + //uint16 unk5 = (argc >= 6) ? argv[5].toUint16() : 0; + } + break; + case 2: { // remap by percent + //int16 unk1 = argv[1].toSint16(); + //uint16 percent = argv[2].toUint16(); + //uint16 unk3 = (argc >= 4) ? argv[3].toUint16() : 0; + } + break; + case 3: { // remap to gray + //int16 unk1 = argv[1].toSint16(); + //int16 percent = argv[2].toSint16(); // 0 - 100 + //uint16 unk3 = (argc >= 4) ? argv[3].toUint16() : 0; + } + break; + case 4: { // unknown + //int16 unk1 = argv[1].toSint16(); + //uint16 unk2 = argv[2].toUint16(); + //uint16 unk3 = argv[3].toUint16(); + //uint16 unk4 = (argc >= 5) ? argv[4].toUint16() : 0; + } + break; + case 5: { // increment color + //int16 unk1 = argv[1].toSint16(); + //uint16 unk2 = argv[2].toUint16(); + } + break; + default: + break; + } + + return s->r_acc; +} + #ifdef ENABLE_SCI32 reg_t kIsHiRes(EngineState *s, int argc, reg_t *argv) { @@ -1211,69 +1266,38 @@ reg_t kCantBeHere32(EngineState *s, int argc, reg_t *argv) { } reg_t kAddScreenItem(EngineState *s, int argc, reg_t *argv) { - reg_t viewObj = argv[0]; - - g_sci->_gfxFrameout->kernelAddScreenItem(viewObj); - return NULL_REG; + g_sci->_gfxFrameout->kernelAddScreenItem(argv[0]); + return s->r_acc; } reg_t kUpdateScreenItem(EngineState *s, int argc, reg_t *argv) { - //reg_t viewObj = argv[0]; - - //warning("kUpdateScreenItem, object %04x:%04x, view %d, loop %d, cel %d, pri %d", PRINT_REG(viewObj), viewId, loopNo, celNo, priority); - return NULL_REG; + g_sci->_gfxFrameout->kernelUpdateScreenItem(argv[0]); + return s->r_acc; } reg_t kDeleteScreenItem(EngineState *s, int argc, reg_t *argv) { - reg_t viewObj = argv[0]; - - g_sci->_gfxFrameout->kernelDeleteScreenItem(viewObj); - - /* - reg_t viewObj = argv[0]; - uint16 viewId = readSelectorValue(s->_segMan, viewObj, SELECTOR(view)); - int16 loopNo = readSelectorValue(s->_segMan, viewObj, SELECTOR(loop)); - int16 celNo = readSelectorValue(s->_segMan, viewObj, SELECTOR(cel)); - //int16 leftPos = 0; - //int16 topPos = 0; - int16 priority = readSelectorValue(s->_segMan, viewObj, SELECTOR(priority)); - //int16 control = 0; - */ - - // TODO - - //warning("kDeleteScreenItem, view %d, loop %d, cel %d, pri %d", viewId, loopNo, celNo, priority); - return NULL_REG; + g_sci->_gfxFrameout->kernelDeleteScreenItem(argv[0]); + return s->r_acc; } reg_t kAddPlane(EngineState *s, int argc, reg_t *argv) { - reg_t planeObj = argv[0]; - - g_sci->_gfxFrameout->kernelAddPlane(planeObj); - return NULL_REG; + g_sci->_gfxFrameout->kernelAddPlane(argv[0]); + return s->r_acc; } reg_t kDeletePlane(EngineState *s, int argc, reg_t *argv) { - reg_t planeObj = argv[0]; - - g_sci->_gfxFrameout->kernelDeletePlane(planeObj); - return NULL_REG; + g_sci->_gfxFrameout->kernelDeletePlane(argv[0]); + return s->r_acc; } reg_t kUpdatePlane(EngineState *s, int argc, reg_t *argv) { - reg_t planeObj = argv[0]; - - g_sci->_gfxFrameout->kernelUpdatePlane(planeObj); + g_sci->_gfxFrameout->kernelUpdatePlane(argv[0]); return s->r_acc; } reg_t kRepaintPlane(EngineState *s, int argc, reg_t *argv) { - reg_t picObj = argv[0]; - - // TODO - - warning("kRepaintPlane object %04x:%04x", PRINT_REG(picObj)); - return NULL_REG; + g_sci->_gfxFrameout->kernelRepaintPlane(argv[0]); + return s->r_acc; } reg_t kAddPicAt(EngineState *s, int argc, reg_t *argv) { @@ -1300,9 +1324,8 @@ reg_t kFrameOut(EngineState *s, int argc, reg_t *argv) { return NULL_REG; } -reg_t kOnMe(EngineState *s, int argc, reg_t *argv) { - // Tests if the cursor is on the passed object - +// Tests if the coordinate is on the passed object +reg_t kIsOnMe(EngineState *s, int argc, reg_t *argv) { uint16 x = argv[0].toUint16(); uint16 y = argv[1].toUint16(); reg_t targetObject = argv[2]; @@ -1335,75 +1358,9 @@ reg_t kOnMe(EngineState *s, int argc, reg_t *argv) { if (g_sci->_gfxCompare->kernelIsItSkip(viewId, loopNo, celNo, Common::Point(x - nsRect.left, y - nsRect.top))) contained = false; } -// these hacks shouldn't be needed anymore -// uint16 itemX = readSelectorValue(s->_segMan, targetObject, SELECTOR(x)); -// uint16 itemY = readSelectorValue(s->_segMan, targetObject, SELECTOR(y)); - - // If top and left are negative, we need to adjust coordinates by - // the item's x and y (e.g. happens in GK1, day 1, with detective - // Mosely's hotspot in his office) - -// if (nsRect.left < 0) -// nsRect.translate(itemX, 0); -// -// if (nsRect.top < 0) -// nsRect.translate(0, itemY); - -// // HACK: nsLeft and nsTop can be invalid, so try and fix them here -// // using x and y (e.g. with the inventory screen in GK1) -// if (nsRect.left == itemY && nsRect.top == itemX) { -// // Swap the values, as they're inversed (eh???) -// nsRect.left = itemX; -// nsRect.top = itemY; -// } - return make_reg(0, contained); } -reg_t kIsOnMe(EngineState *s, int argc, reg_t *argv) { - // Tests if the cursor is on the passed object, after adjusting the - // coordinates of the object according to the object's plane - - uint16 x = argv[0].toUint16(); - uint16 y = argv[1].toUint16(); - reg_t targetObject = argv[2]; - // TODO: argv[3] - it's usually 0 - Common::Rect nsRect; - - // Get the bounding rectangle of the object - nsRect.left = readSelectorValue(s->_segMan, targetObject, SELECTOR(nsLeft)); - nsRect.top = readSelectorValue(s->_segMan, targetObject, SELECTOR(nsTop)); - nsRect.right = readSelectorValue(s->_segMan, targetObject, SELECTOR(nsRight)); - nsRect.bottom = readSelectorValue(s->_segMan, targetObject, SELECTOR(nsBottom)); - - // Get the object's plane -#if 0 - reg_t planeObject = readSelector(s->_segMan, targetObject, SELECTOR(plane)); - if (!planeObject.isNull()) { - //uint16 itemX = readSelectorValue(s->_segMan, targetObject, SELECTOR(x)); - //uint16 itemY = readSelectorValue(s->_segMan, targetObject, SELECTOR(y)); - uint16 planeResY = readSelectorValue(s->_segMan, planeObject, SELECTOR(resY)); - uint16 planeResX = readSelectorValue(s->_segMan, planeObject, SELECTOR(resX)); - uint16 planeTop = readSelectorValue(s->_segMan, planeObject, SELECTOR(top)); - uint16 planeLeft = readSelectorValue(s->_segMan, planeObject, SELECTOR(left)); - planeTop = (planeTop * g_sci->_gfxScreen->getHeight()) / planeResY; - planeLeft = (planeLeft * g_sci->_gfxScreen->getWidth()) / planeResX; - - // Adjust the bounding rectangle of the object by the object's - // actual X, Y coordinates - nsRect.top = ((nsRect.top * g_sci->_gfxScreen->getHeight()) / planeResY); - nsRect.left = ((nsRect.left * g_sci->_gfxScreen->getWidth()) / planeResX); - nsRect.bottom = ((nsRect.bottom * g_sci->_gfxScreen->getHeight()) / planeResY); - nsRect.right = ((nsRect.right * g_sci->_gfxScreen->getWidth()) / planeResX); - - nsRect.translate(planeLeft, planeTop); - } -#endif - //warning("kIsOnMe: (%d, %d) on object %04x:%04x, parameter %d", argv[0].toUint16(), argv[1].toUint16(), PRINT_REG(argv[2]), argv[3].toUint16()); - - return make_reg(0, nsRect.contains(x, y)); -} - reg_t kCreateTextBitmap(EngineState *s, int argc, reg_t *argv) { // TODO: argument 0 is usually 0, and arguments 1 and 2 are usually 1 switch (argv[0].toUint16()) { @@ -1460,6 +1417,61 @@ reg_t kRobot(EngineState *s, int argc, reg_t *argv) { return s->r_acc; } +reg_t kGetWindowsOption(EngineState *s, int argc, reg_t *argv) { + uint16 windowsOption = argv[0].toUint16(); + switch (windowsOption) { + case 0: + // Title bar on/off in Phantasmagoria, we return 0 (off) + return NULL_REG; + default: + warning("GetWindowsOption: Unknown option %d", windowsOption); + return NULL_REG; + } +} + +reg_t kWinHelp(EngineState *s, int argc, reg_t *argv) { + switch (argv[0].toUint16()) { + case 1: + // Load a help file + // Maybe in the future we can implement this, but for now this message should suffice + showScummVMDialog("Please use an external viewer to open the game's help file: " + s->_segMan->getString(argv[1])); + break; + case 2: + // Looks like some init function + break; + default: + warning("Unknown kWinHelp subop %d", argv[0].toUint16()); + } + + return s->r_acc; +} + +/** + * Used to programmatically mass set properties of the target plane + */ +reg_t kSetShowStyle(EngineState *s, int argc, reg_t *argv) { + // TODO: This is all a stub/skeleton, thus we're invoking kStub() for now + kStub(s, argc, argv); + + // showStyle matches the style selector of the associated plane object + uint16 showStyle = argv[0].toUint16(); // 0 - 15 + reg_t planeObj = argv[1]; + //argv[2] + //int16 priority = argv[3].toSint16(); + //argv[4] + //argv[5] + //argv[6] + //argv[7] + //int16 unk8 = (argc >= 9) ? argv[8].toSint16() : 0; + + if (showStyle > 15) { + warning("kSetShowStyle: Illegal style %d for plane %04x:%04x", showStyle, PRINT_REG(planeObj)); + return s->r_acc; + } + + return s->r_acc; +} + #endif } // End of namespace Sci |