aboutsummaryrefslogtreecommitdiff
path: root/engines/sci/engine/kgraphics.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/sci/engine/kgraphics.cpp')
-rw-r--r--engines/sci/engine/kgraphics.cpp264
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