2012-05-20 19:57:34 +03:00
|
|
|
|
/* ScummVM - Graphic Adventure Engine
|
|
|
|
|
*
|
|
|
|
|
* ScummVM is the legal property of its developers, whose names
|
|
|
|
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
|
|
|
|
* file distributed with this source distribution.
|
|
|
|
|
*
|
|
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
|
* as published by the Free Software Foundation; either version 2
|
|
|
|
|
* of the License, or (at your option) any later version.
|
2014-02-18 02:34:24 +01:00
|
|
|
|
*
|
2012-05-20 19:57:34 +03:00
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
* GNU General Public License for more details.
|
2014-02-18 02:34:24 +01:00
|
|
|
|
*
|
2012-05-20 19:57:34 +03:00
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
|
* along with this program; if not, write to the Free Software
|
|
|
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include "common/system.h"
|
2017-05-07 14:29:35 -05:00
|
|
|
|
#include "common/translation.h"
|
2012-05-20 19:57:34 +03:00
|
|
|
|
|
|
|
|
|
#include "engines/util.h"
|
|
|
|
|
#include "graphics/cursorman.h"
|
|
|
|
|
#include "graphics/surface.h"
|
|
|
|
|
|
|
|
|
|
#include "sci/sci.h"
|
|
|
|
|
#include "sci/event.h"
|
|
|
|
|
#include "sci/resource.h"
|
|
|
|
|
#include "sci/engine/features.h"
|
|
|
|
|
#include "sci/engine/state.h"
|
|
|
|
|
#include "sci/engine/selector.h"
|
|
|
|
|
#include "sci/engine/kernel.h"
|
|
|
|
|
#include "sci/graphics/animate.h"
|
|
|
|
|
#include "sci/graphics/cache.h"
|
|
|
|
|
#include "sci/graphics/compare.h"
|
|
|
|
|
#include "sci/graphics/controls16.h"
|
|
|
|
|
#include "sci/graphics/palette.h"
|
|
|
|
|
#include "sci/graphics/paint16.h"
|
|
|
|
|
#include "sci/graphics/picture.h"
|
|
|
|
|
#include "sci/graphics/ports.h"
|
2016-03-11 05:10:32 +02:00
|
|
|
|
#include "sci/graphics/remap.h"
|
2012-05-20 19:57:34 +03:00
|
|
|
|
#include "sci/graphics/screen.h"
|
|
|
|
|
#include "sci/graphics/text16.h"
|
|
|
|
|
#include "sci/graphics/view.h"
|
|
|
|
|
#ifdef ENABLE_SCI32
|
2016-07-31 13:41:05 -05:00
|
|
|
|
#include "sci/graphics/cursor32.h"
|
2016-03-03 20:31:10 -06:00
|
|
|
|
#include "sci/graphics/celobj32.h"
|
2012-05-20 19:57:34 +03:00
|
|
|
|
#include "sci/graphics/controls32.h"
|
|
|
|
|
#include "sci/graphics/font.h" // TODO: remove once kBitmap is moved in a separate class
|
|
|
|
|
#include "sci/graphics/frameout.h"
|
2016-06-18 20:48:10 -05:00
|
|
|
|
#include "sci/graphics/paint32.h"
|
2016-03-03 20:31:10 -06:00
|
|
|
|
#include "sci/graphics/palette32.h"
|
2016-06-25 14:19:47 -05:00
|
|
|
|
#include "sci/graphics/remap32.h"
|
2016-03-03 20:31:10 -06:00
|
|
|
|
#include "sci/graphics/text32.h"
|
2016-07-25 11:06:27 -05:00
|
|
|
|
#include "sci/graphics/transitions32.h"
|
2012-05-20 19:57:34 +03:00
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
namespace Sci {
|
|
|
|
|
#ifdef ENABLE_SCI32
|
|
|
|
|
|
|
|
|
|
extern void showScummVMDialog(const Common::String &message);
|
|
|
|
|
|
2016-07-31 15:19:29 -05:00
|
|
|
|
reg_t kBaseSetter32(EngineState *s, int argc, reg_t *argv) {
|
|
|
|
|
reg_t object = argv[0];
|
|
|
|
|
|
|
|
|
|
const GuiResourceId viewId = readSelectorValue(s->_segMan, object, SELECTOR(view));
|
|
|
|
|
const int16 loopNo = readSelectorValue(s->_segMan, object, SELECTOR(loop));
|
|
|
|
|
const int16 celNo = readSelectorValue(s->_segMan, object, SELECTOR(cel));
|
|
|
|
|
const int16 x = readSelectorValue(s->_segMan, object, SELECTOR(x));
|
|
|
|
|
const int16 y = readSelectorValue(s->_segMan, object, SELECTOR(y));
|
|
|
|
|
|
|
|
|
|
CelObjView celObj(viewId, loopNo, celNo);
|
|
|
|
|
|
SCI32: Fix bad text rendering in RAMA
In SCI3, Sierra removed the ability of the main renderer to
automatically scale CelObjs with different source resolutions.
Instead, in SCI3, all CelObjs are treated as having the same
resolution as the screen (i.e. 640x480).
In all SCI3 games other than RAMA, keeping the code paths for
resolution-dependent scaling is not a problem because all the
assets and game code are correctly designed to use the same
640x480 resolution throughout. RAMA, on the other hand, was
written with the text subsystem set to a resolution of 630x450
(Phant1's screen resolution), and in SSCI, resolution-dependent
scaling code was not removed from the *text* subsystem. As a
result, RAMA's game scripts rely on the slightly larger scaled
dimensions coming out of the text system when determining the size
of screen items for rendering, and then also rely on the main
renderer ignoring the 630x450 resolution baked into the bitmaps
generated by the text subsystem when drawing them to the screen.
2017-09-29 14:57:22 -05:00
|
|
|
|
Ratio scaleX;
|
2017-09-30 00:03:05 -05:00
|
|
|
|
if (getSciVersion() < SCI_VERSION_2_1_LATE) {
|
2017-10-06 22:05:57 -05:00
|
|
|
|
const int16 scriptWidth = g_sci->_gfxFrameout->getScriptWidth();
|
SCI32: Fix bad text rendering in RAMA
In SCI3, Sierra removed the ability of the main renderer to
automatically scale CelObjs with different source resolutions.
Instead, in SCI3, all CelObjs are treated as having the same
resolution as the screen (i.e. 640x480).
In all SCI3 games other than RAMA, keeping the code paths for
resolution-dependent scaling is not a problem because all the
assets and game code are correctly designed to use the same
640x480 resolution throughout. RAMA, on the other hand, was
written with the text subsystem set to a resolution of 630x450
(Phant1's screen resolution), and in SSCI, resolution-dependent
scaling code was not removed from the *text* subsystem. As a
result, RAMA's game scripts rely on the slightly larger scaled
dimensions coming out of the text system when determining the size
of screen items for rendering, and then also rely on the main
renderer ignoring the 630x450 resolution baked into the bitmaps
generated by the text subsystem when drawing them to the screen.
2017-09-29 14:57:22 -05:00
|
|
|
|
scaleX = Ratio(scriptWidth, celObj._xResolution);
|
|
|
|
|
}
|
2016-07-31 15:19:29 -05:00
|
|
|
|
|
|
|
|
|
int16 brLeft;
|
|
|
|
|
|
|
|
|
|
if (celObj._mirrorX) {
|
2016-10-09 10:52:08 -05:00
|
|
|
|
brLeft = x - ((celObj._width - celObj._origin.x) * scaleX).toInt();
|
2016-07-31 15:19:29 -05:00
|
|
|
|
} else {
|
2016-10-09 10:52:08 -05:00
|
|
|
|
brLeft = x - (celObj._origin.x * scaleX).toInt();
|
2016-07-31 15:19:29 -05:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const int16 brRight = brLeft + (celObj._width * scaleX).toInt() - 1;
|
|
|
|
|
|
|
|
|
|
writeSelectorValue(s->_segMan, object, SELECTOR(brLeft), brLeft);
|
|
|
|
|
writeSelectorValue(s->_segMan, object, SELECTOR(brRight), brRight);
|
|
|
|
|
writeSelectorValue(s->_segMan, object, SELECTOR(brBottom), y + 1);
|
|
|
|
|
writeSelectorValue(s->_segMan, object, SELECTOR(brTop), y + 1 - readSelectorValue(s->_segMan, object, SELECTOR(yStep)));
|
|
|
|
|
|
|
|
|
|
return s->r_acc;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
reg_t kSetNowSeen32(EngineState *s, int argc, reg_t *argv) {
|
2016-08-14 16:20:31 -05:00
|
|
|
|
const bool found = g_sci->_gfxFrameout->kernelSetNowSeen(argv[0]);
|
|
|
|
|
|
2017-10-05 23:21:05 -05:00
|
|
|
|
// MGDX is assumed to use the older kSetNowSeen since it was released before
|
|
|
|
|
// SQ6, but this has not been verified since it cannot be disassembled at
|
|
|
|
|
// the moment (Phar Lap Windows-only release)
|
2017-07-09 17:25:17 +02:00
|
|
|
|
// (See also getNowSeenRect)
|
2016-08-14 16:20:31 -05:00
|
|
|
|
if (getSciVersion() <= SCI_VERSION_2_1_EARLY ||
|
|
|
|
|
g_sci->getGameId() == GID_SQ6 ||
|
|
|
|
|
g_sci->getGameId() == GID_MOTHERGOOSEHIRES) {
|
|
|
|
|
|
|
|
|
|
return s->r_acc;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return make_reg(0, found);
|
2016-07-31 15:19:29 -05:00
|
|
|
|
}
|
|
|
|
|
|
2016-07-31 13:41:05 -05:00
|
|
|
|
reg_t kSetCursor32(EngineState *s, int argc, reg_t *argv) {
|
|
|
|
|
switch (argc) {
|
|
|
|
|
case 1: {
|
|
|
|
|
if (argv[0].toSint16() == -2) {
|
|
|
|
|
g_sci->_gfxCursor32->clearRestrictedArea();
|
|
|
|
|
} else {
|
|
|
|
|
if (argv[0].isNull()) {
|
|
|
|
|
g_sci->_gfxCursor32->hide();
|
|
|
|
|
} else {
|
|
|
|
|
g_sci->_gfxCursor32->show();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case 2: {
|
|
|
|
|
const Common::Point position(argv[0].toSint16(), argv[1].toSint16());
|
|
|
|
|
g_sci->_gfxCursor32->setPosition(position);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case 3: {
|
|
|
|
|
g_sci->_gfxCursor32->setView(argv[0].toUint16(), argv[1].toSint16(), argv[2].toSint16());
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case 4: {
|
|
|
|
|
const Common::Rect restrictRect(argv[0].toSint16(),
|
|
|
|
|
argv[1].toSint16(),
|
|
|
|
|
argv[2].toSint16() + 1,
|
|
|
|
|
argv[3].toSint16() + 1);
|
|
|
|
|
g_sci->_gfxCursor32->setRestrictedArea(restrictRect);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
default:
|
|
|
|
|
error("kSetCursor: Invalid number of arguments (%d)", argc);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return s->r_acc;
|
|
|
|
|
}
|
|
|
|
|
|
2016-08-02 09:49:04 -05:00
|
|
|
|
reg_t kShakeScreen32(EngineState *s, int argc, reg_t *argv) {
|
|
|
|
|
g_sci->_gfxFrameout->shakeScreen(argv[0].toSint16(), (ShakeDirection)argv[1].toSint16());
|
|
|
|
|
return s->r_acc;
|
|
|
|
|
}
|
|
|
|
|
|
2012-05-20 19:57:34 +03:00
|
|
|
|
reg_t kIsHiRes(EngineState *s, int argc, reg_t *argv) {
|
2017-10-06 22:05:57 -05:00
|
|
|
|
const GfxFrameout *gfxFrameout = g_sci->_gfxFrameout;
|
|
|
|
|
if (gfxFrameout->getScreenWidth() < 640 || gfxFrameout->getScreenHeight() < 400) {
|
|
|
|
|
return NULL_REG;
|
|
|
|
|
}
|
2012-05-20 19:57:34 +03:00
|
|
|
|
|
2017-10-06 22:05:57 -05:00
|
|
|
|
return TRUE_REG;
|
2012-05-20 19:57:34 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
reg_t kAddScreenItem(EngineState *s, int argc, reg_t *argv) {
|
2016-03-10 14:05:55 -06:00
|
|
|
|
debugC(6, kDebugLevelGraphics, "kAddScreenItem %x:%x (%s)", PRINT_REG(argv[0]), s->_segMan->getObjectName(argv[0]));
|
2016-01-18 00:12:47 -06:00
|
|
|
|
g_sci->_gfxFrameout->kernelAddScreenItem(argv[0]);
|
2016-03-20 09:31:28 -05:00
|
|
|
|
return s->r_acc;
|
2012-05-20 19:57:34 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
reg_t kUpdateScreenItem(EngineState *s, int argc, reg_t *argv) {
|
2016-03-10 14:05:55 -06:00
|
|
|
|
debugC(7, kDebugLevelGraphics, "kUpdateScreenItem %x:%x (%s)", PRINT_REG(argv[0]), s->_segMan->getObjectName(argv[0]));
|
2012-05-20 19:57:34 +03:00
|
|
|
|
g_sci->_gfxFrameout->kernelUpdateScreenItem(argv[0]);
|
2016-03-20 09:31:28 -05:00
|
|
|
|
return s->r_acc;
|
2012-05-20 19:57:34 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
reg_t kDeleteScreenItem(EngineState *s, int argc, reg_t *argv) {
|
2016-03-10 14:05:55 -06:00
|
|
|
|
debugC(6, kDebugLevelGraphics, "kDeleteScreenItem %x:%x (%s)", PRINT_REG(argv[0]), s->_segMan->getObjectName(argv[0]));
|
2012-05-20 19:57:34 +03:00
|
|
|
|
g_sci->_gfxFrameout->kernelDeleteScreenItem(argv[0]);
|
2016-03-20 09:31:28 -05:00
|
|
|
|
return s->r_acc;
|
2012-05-20 19:57:34 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
reg_t kAddPlane(EngineState *s, int argc, reg_t *argv) {
|
2016-03-10 14:05:55 -06:00
|
|
|
|
debugC(6, kDebugLevelGraphics, "kAddPlane %x:%x (%s)", PRINT_REG(argv[0]), s->_segMan->getObjectName(argv[0]));
|
2012-05-20 19:57:34 +03:00
|
|
|
|
g_sci->_gfxFrameout->kernelAddPlane(argv[0]);
|
|
|
|
|
return s->r_acc;
|
|
|
|
|
}
|
|
|
|
|
|
2016-02-21 14:14:11 +01:00
|
|
|
|
reg_t kUpdatePlane(EngineState *s, int argc, reg_t *argv) {
|
2016-03-10 14:05:55 -06:00
|
|
|
|
debugC(7, kDebugLevelGraphics, "kUpdatePlane %x:%x (%s)", PRINT_REG(argv[0]), s->_segMan->getObjectName(argv[0]));
|
2016-02-21 14:14:11 +01:00
|
|
|
|
g_sci->_gfxFrameout->kernelUpdatePlane(argv[0]);
|
2012-05-20 19:57:34 +03:00
|
|
|
|
return s->r_acc;
|
|
|
|
|
}
|
|
|
|
|
|
2016-02-21 14:14:11 +01:00
|
|
|
|
reg_t kDeletePlane(EngineState *s, int argc, reg_t *argv) {
|
2016-03-10 14:05:55 -06:00
|
|
|
|
debugC(6, kDebugLevelGraphics, "kDeletePlane %x:%x (%s)", PRINT_REG(argv[0]), s->_segMan->getObjectName(argv[0]));
|
2016-02-21 14:14:11 +01:00
|
|
|
|
g_sci->_gfxFrameout->kernelDeletePlane(argv[0]);
|
2012-05-20 19:57:34 +03:00
|
|
|
|
return s->r_acc;
|
|
|
|
|
}
|
|
|
|
|
|
2016-03-10 15:48:48 -06:00
|
|
|
|
reg_t kMovePlaneItems(EngineState *s, int argc, reg_t *argv) {
|
|
|
|
|
const reg_t plane = argv[0];
|
|
|
|
|
const int16 deltaX = argv[1].toSint16();
|
|
|
|
|
const int16 deltaY = argv[2].toSint16();
|
|
|
|
|
const bool scrollPics = argc > 3 ? argv[3].toUint16() : false;
|
|
|
|
|
|
|
|
|
|
g_sci->_gfxFrameout->kernelMovePlaneItems(plane, deltaX, deltaY, scrollPics);
|
2016-03-20 09:31:28 -05:00
|
|
|
|
return s->r_acc;
|
2016-03-10 15:48:48 -06:00
|
|
|
|
}
|
|
|
|
|
|
2012-05-20 19:57:34 +03:00
|
|
|
|
reg_t kAddPicAt(EngineState *s, int argc, reg_t *argv) {
|
|
|
|
|
reg_t planeObj = argv[0];
|
|
|
|
|
GuiResourceId pictureId = argv[1].toUint16();
|
2016-01-18 00:12:47 -06:00
|
|
|
|
int16 x = argv[2].toSint16();
|
|
|
|
|
int16 y = argv[3].toSint16();
|
|
|
|
|
bool mirrorX = argc > 4 ? argv[4].toSint16() : false;
|
2016-07-25 13:40:51 -05:00
|
|
|
|
bool deleteDuplicate = argc > 5 ? argv[5].toSint16() : true;
|
2012-05-20 19:57:34 +03:00
|
|
|
|
|
2016-07-25 13:40:51 -05:00
|
|
|
|
g_sci->_gfxFrameout->kernelAddPicAt(planeObj, pictureId, x, y, mirrorX, deleteDuplicate);
|
2016-03-20 09:31:28 -05:00
|
|
|
|
return s->r_acc;
|
2012-05-20 19:57:34 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
reg_t kGetHighPlanePri(EngineState *s, int argc, reg_t *argv) {
|
|
|
|
|
return make_reg(0, g_sci->_gfxFrameout->kernelGetHighPlanePri());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
reg_t kFrameOut(EngineState *s, int argc, reg_t *argv) {
|
2016-01-18 00:12:47 -06:00
|
|
|
|
bool showBits = argc > 0 ? argv[0].toUint16() : true;
|
2016-03-02 14:02:15 -06:00
|
|
|
|
g_sci->_gfxFrameout->kernelFrameOut(showBits);
|
SCI32: Detect and handle tight loops around kGetEvent
In SSCI, mouse events are received through a hardware interrupt
and the cursor is drawn directly to the graphics card by the
interrupt handler. This allows game scripts to omit calls to
kFrameOut without stopping the mouse cursor from being redrawn
in response to mouse movement.
ScummVM, in contrast, needs to poll for events and submit screen
updates explicitly from the main thread. Submitting screen updates
may block on vsync, which means that this call should really only
be made once per frame, just after the game has finished updating
its back buffer. The closest signal in SCI32 for having completed
drawing a frame is the kFrameOut call, so this is where the
update is submitted (by calling OSystem::updateScreen).
The problem with the approach in ScummVM is that, even though the
mouse position is being updated (by calls to kGetEvent) and drawn
to the backend's back buffer (by GfxCursor32::drawToHardware),
OSystem::updateScreen is never called during game loops that omit
calls to kFrameOut.
This commit introduces a workaround that looks at the number of
times kGetEvent is called between calls to kFrameOut. If the
number of kGetEvent calls is higher than usual (where "usual"
seems to be 0 or 1), we assume that the game is running one of
these tight event loops, and kGetEvent starts calling
OSystem::updateScreen until the next kFrameOut call. We also
then start throttling the calls to kGetEvent to keep CPU usage
down. This fixes at least two such known loops:
1. When interacting with the menu bar at the top of the screen
in LSL6hires;
2. When restoring a game in Phant2 and sitting on the "click mouse"
screen.
A similar workaround may also be needed for kGetTime, though loops
around kGetTime should preferably be replaced using a script patch
to call kWait instead.
2017-05-06 16:37:11 -05:00
|
|
|
|
s->_eventCounter = 0;
|
2016-03-20 09:31:28 -05:00
|
|
|
|
return s->r_acc;
|
2012-05-20 19:57:34 +03:00
|
|
|
|
}
|
|
|
|
|
|
2016-01-06 20:03:04 -06:00
|
|
|
|
reg_t kSetPalStyleRange(EngineState *s, int argc, reg_t *argv) {
|
2016-07-25 11:06:27 -05:00
|
|
|
|
g_sci->_gfxTransitions32->kernelSetPalStyleRange(argv[0].toUint16(), argv[1].toUint16());
|
2016-03-20 09:31:28 -05:00
|
|
|
|
return s->r_acc;
|
2016-01-06 20:03:04 -06:00
|
|
|
|
}
|
|
|
|
|
|
2012-05-20 19:57:34 +03:00
|
|
|
|
reg_t kObjectIntersect(EngineState *s, int argc, reg_t *argv) {
|
2017-07-09 17:25:17 +02:00
|
|
|
|
int16 area = g_sci->_gfxFrameout->kernelObjectIntersect(argv[0], argv[1]);
|
|
|
|
|
return make_reg(0, area);
|
2012-05-20 19:57:34 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
reg_t kIsOnMe(EngineState *s, int argc, reg_t *argv) {
|
2016-03-08 10:27:15 -06:00
|
|
|
|
int16 x = argv[0].toSint16();
|
|
|
|
|
int16 y = argv[1].toSint16();
|
|
|
|
|
reg_t object = argv[2];
|
|
|
|
|
bool checkPixel = argv[3].toSint16();
|
2016-02-20 05:38:22 +01:00
|
|
|
|
|
2016-03-08 10:27:15 -06:00
|
|
|
|
return g_sci->_gfxFrameout->kernelIsOnMe(object, Common::Point(x, y), checkPixel);
|
2012-05-20 19:57:34 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
reg_t kCreateTextBitmap(EngineState *s, int argc, reg_t *argv) {
|
2016-02-14 12:07:30 -06:00
|
|
|
|
SegManager *segMan = s->_segMan;
|
|
|
|
|
|
|
|
|
|
int16 subop = argv[0].toUint16();
|
|
|
|
|
|
2016-02-19 02:36:12 +02:00
|
|
|
|
int16 width = 0;
|
|
|
|
|
int16 height = 0;
|
2016-02-14 12:07:30 -06:00
|
|
|
|
reg_t object;
|
|
|
|
|
|
|
|
|
|
if (subop == 0) {
|
|
|
|
|
width = argv[1].toUint16();
|
|
|
|
|
height = argv[2].toUint16();
|
|
|
|
|
object = argv[3];
|
|
|
|
|
} else if (subop == 1) {
|
|
|
|
|
object = argv[1];
|
|
|
|
|
} else {
|
|
|
|
|
warning("Invalid kCreateTextBitmap subop %d", subop);
|
2012-05-20 19:57:34 +03:00
|
|
|
|
return NULL_REG;
|
|
|
|
|
}
|
2016-02-14 12:07:30 -06:00
|
|
|
|
|
|
|
|
|
Common::String text = segMan->getString(readSelector(segMan, object, SELECTOR(text)));
|
|
|
|
|
int16 foreColor = readSelectorValue(segMan, object, SELECTOR(fore));
|
|
|
|
|
int16 backColor = readSelectorValue(segMan, object, SELECTOR(back));
|
|
|
|
|
int16 skipColor = readSelectorValue(segMan, object, SELECTOR(skip));
|
|
|
|
|
GuiResourceId fontId = (GuiResourceId)readSelectorValue(segMan, object, SELECTOR(font));
|
|
|
|
|
int16 borderColor = readSelectorValue(segMan, object, SELECTOR(borderColor));
|
|
|
|
|
int16 dimmed = readSelectorValue(segMan, object, SELECTOR(dimmed));
|
|
|
|
|
|
|
|
|
|
Common::Rect rect(
|
|
|
|
|
readSelectorValue(segMan, object, SELECTOR(textLeft)),
|
|
|
|
|
readSelectorValue(segMan, object, SELECTOR(textTop)),
|
2016-02-18 00:07:28 -06:00
|
|
|
|
readSelectorValue(segMan, object, SELECTOR(textRight)) + 1,
|
|
|
|
|
readSelectorValue(segMan, object, SELECTOR(textBottom)) + 1
|
2016-02-14 12:07:30 -06:00
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
if (subop == 0) {
|
|
|
|
|
TextAlign alignment = (TextAlign)readSelectorValue(segMan, object, SELECTOR(mode));
|
2016-07-20 10:40:02 -05:00
|
|
|
|
return g_sci->_gfxText32->createFontBitmap(width, height, rect, text, foreColor, backColor, skipColor, fontId, alignment, borderColor, dimmed, true, true);
|
2016-02-14 12:07:30 -06:00
|
|
|
|
} else {
|
|
|
|
|
CelInfo32 celInfo;
|
|
|
|
|
celInfo.type = kCelTypeView;
|
|
|
|
|
celInfo.resourceId = readSelectorValue(segMan, object, SELECTOR(view));
|
|
|
|
|
celInfo.loopNo = readSelectorValue(segMan, object, SELECTOR(loop));
|
|
|
|
|
celInfo.celNo = readSelectorValue(segMan, object, SELECTOR(cel));
|
2016-07-20 10:40:02 -05:00
|
|
|
|
return g_sci->_gfxText32->createFontBitmap(celInfo, rect, text, foreColor, backColor, fontId, skipColor, borderColor, dimmed, true);
|
2016-02-14 12:07:30 -06:00
|
|
|
|
}
|
2012-05-20 19:57:34 +03:00
|
|
|
|
}
|
|
|
|
|
|
2016-02-28 21:19:06 -06:00
|
|
|
|
reg_t kText(EngineState *s, int argc, reg_t *argv) {
|
|
|
|
|
if (!s)
|
|
|
|
|
return make_reg(0, getSciVersion());
|
|
|
|
|
error("not supposed to call this");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
reg_t kTextSize32(EngineState *s, int argc, reg_t *argv) {
|
|
|
|
|
g_sci->_gfxText32->setFont(argv[2].toUint16());
|
|
|
|
|
|
2016-09-04 16:30:47 -05:00
|
|
|
|
SciArray *rect = s->_segMan->lookupArray(argv[0]);
|
2016-05-27 18:59:12 -05:00
|
|
|
|
if (rect == nullptr) {
|
|
|
|
|
error("kTextSize: %04x:%04x cannot be dereferenced", PRINT_REG(argv[0]));
|
|
|
|
|
}
|
2016-02-28 21:19:06 -06:00
|
|
|
|
|
|
|
|
|
Common::String text = s->_segMan->getString(argv[1]);
|
|
|
|
|
int16 maxWidth = argc > 3 ? argv[3].toSint16() : 0;
|
|
|
|
|
bool doScaling = argc > 4 ? argv[4].toSint16() : true;
|
|
|
|
|
|
|
|
|
|
Common::Rect textRect = g_sci->_gfxText32->getTextSize(text, maxWidth, doScaling);
|
2016-09-04 16:30:47 -05:00
|
|
|
|
|
|
|
|
|
reg_t value[4] = {
|
|
|
|
|
make_reg(0, textRect.left),
|
|
|
|
|
make_reg(0, textRect.top),
|
|
|
|
|
make_reg(0, textRect.right - 1),
|
|
|
|
|
make_reg(0, textRect.bottom - 1) };
|
|
|
|
|
|
|
|
|
|
rect->setElements(0, 4, value);
|
2016-03-20 09:31:28 -05:00
|
|
|
|
return s->r_acc;
|
2016-02-28 21:19:06 -06:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
reg_t kTextWidth(EngineState *s, int argc, reg_t *argv) {
|
|
|
|
|
g_sci->_gfxText32->setFont(argv[1].toUint16());
|
|
|
|
|
Common::String text = s->_segMan->getString(argv[0]);
|
|
|
|
|
return make_reg(0, g_sci->_gfxText32->getStringWidth(text));
|
|
|
|
|
}
|
|
|
|
|
|
2012-05-20 19:57:34 +03:00
|
|
|
|
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
|
2017-05-07 14:29:35 -05:00
|
|
|
|
showScummVMDialog(Common::String::format(_("Please use an external viewer to open the game's help file: %s"), s->_segMan->getString(argv[1]).c_str()));
|
2012-05-20 19:57:34 +03:00
|
|
|
|
break;
|
|
|
|
|
case 2:
|
|
|
|
|
// Looks like some init function
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
warning("Unknown kWinHelp subop %d", argv[0].toUint16());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return s->r_acc;
|
|
|
|
|
}
|
|
|
|
|
|
2016-06-18 21:06:16 -05:00
|
|
|
|
reg_t kMessageBox(EngineState *s, int argc, reg_t *argv) {
|
|
|
|
|
return g_sci->_gfxControls32->kernelMessageBox(s->_segMan->getString(argv[0]), s->_segMan->getString(argv[1]), argv[2].toUint16());
|
|
|
|
|
}
|
|
|
|
|
|
2012-05-20 19:57:34 +03:00
|
|
|
|
/**
|
2016-01-18 00:12:47 -06:00
|
|
|
|
* Causes an immediate plane transition with an optional transition
|
|
|
|
|
* effect
|
2012-05-20 19:57:34 +03:00
|
|
|
|
*/
|
|
|
|
|
reg_t kSetShowStyle(EngineState *s, int argc, reg_t *argv) {
|
2016-08-19 15:18:02 -05:00
|
|
|
|
const uint16 type = argv[0].toUint16();
|
2016-01-18 00:12:47 -06:00
|
|
|
|
reg_t planeObj = argv[1];
|
|
|
|
|
int16 seconds = argv[2].toSint16();
|
2017-10-05 21:41:29 -05:00
|
|
|
|
// This value indicates 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.
|
2016-01-18 00:12:47 -06:00
|
|
|
|
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;
|
2012-05-20 19:57:34 +03:00
|
|
|
|
int16 divisions;
|
|
|
|
|
|
2016-01-18 00:12:47 -06:00
|
|
|
|
// SCI 2–2.1early
|
|
|
|
|
if (getSciVersion() < SCI_VERSION_2_1_MIDDLE) {
|
|
|
|
|
blackScreen = 0;
|
|
|
|
|
pFadeArray = NULL_REG;
|
|
|
|
|
divisions = argc > 7 ? argv[7].toSint16() : -1;
|
2012-05-20 19:57:34 +03:00
|
|
|
|
}
|
2017-01-02 10:13:02 -06:00
|
|
|
|
// SCI 2.1mid
|
|
|
|
|
else if (getSciVersion() < SCI_VERSION_2_1_LATE) {
|
2016-01-18 00:12:47 -06:00
|
|
|
|
blackScreen = 0;
|
|
|
|
|
pFadeArray = argc > 7 ? argv[7] : NULL_REG;
|
|
|
|
|
divisions = argc > 8 ? argv[8].toSint16() : -1;
|
|
|
|
|
}
|
2017-01-02 10:13:02 -06:00
|
|
|
|
// SCI 2.1late-3
|
2016-01-18 00:12:47 -06:00
|
|
|
|
else {
|
|
|
|
|
blackScreen = argv[7].toSint16();
|
|
|
|
|
pFadeArray = argc > 8 ? argv[8] : NULL_REG;
|
|
|
|
|
divisions = argc > 9 ? argv[9].toSint16() : -1;
|
2012-05-20 19:57:34 +03:00
|
|
|
|
}
|
|
|
|
|
|
2016-08-19 15:18:02 -05:00
|
|
|
|
if ((getSciVersion() < SCI_VERSION_2_1_MIDDLE && g_sci->getGameId() != GID_KQ7 && type == 15) || type > 15) {
|
|
|
|
|
error("Illegal show style %d for plane %04x:%04x", type, PRINT_REG(planeObj));
|
|
|
|
|
}
|
|
|
|
|
|
2017-10-05 21:41:29 -05:00
|
|
|
|
// The order of planeObj and showStyle are reversed because this is how
|
|
|
|
|
// SSCI3 called the corresponding method on the KernelMgr
|
2016-08-19 15:18:02 -05:00
|
|
|
|
g_sci->_gfxTransitions32->kernelSetShowStyle(argc, planeObj, (ShowStyleType)type, seconds, back, priority, animate, refFrame, pFadeArray, divisions, blackScreen);
|
2012-07-04 02:15:39 +03:00
|
|
|
|
|
2016-03-20 09:31:28 -05:00
|
|
|
|
return s->r_acc;
|
2012-05-20 19:57:34 +03:00
|
|
|
|
}
|
|
|
|
|
|
2016-03-12 18:49:19 -06:00
|
|
|
|
reg_t kCelHigh32(EngineState *s, int argc, reg_t *argv) {
|
2017-10-06 22:05:57 -05:00
|
|
|
|
const GuiResourceId resourceId = argv[0].toUint16();
|
|
|
|
|
const int16 loopNo = argv[1].toSint16();
|
|
|
|
|
const int16 celNo = argv[2].toSint16();
|
|
|
|
|
const CelObjView celObj(resourceId, loopNo, celNo);
|
SCI32: Fix bad text rendering in RAMA
In SCI3, Sierra removed the ability of the main renderer to
automatically scale CelObjs with different source resolutions.
Instead, in SCI3, all CelObjs are treated as having the same
resolution as the screen (i.e. 640x480).
In all SCI3 games other than RAMA, keeping the code paths for
resolution-dependent scaling is not a problem because all the
assets and game code are correctly designed to use the same
640x480 resolution throughout. RAMA, on the other hand, was
written with the text subsystem set to a resolution of 630x450
(Phant1's screen resolution), and in SSCI, resolution-dependent
scaling code was not removed from the *text* subsystem. As a
result, RAMA's game scripts rely on the slightly larger scaled
dimensions coming out of the text system when determining the size
of screen items for rendering, and then also rely on the main
renderer ignoring the 630x450 resolution baked into the bitmaps
generated by the text subsystem when drawing them to the screen.
2017-09-29 14:57:22 -05:00
|
|
|
|
int16 height = celObj._height;
|
2017-09-30 00:03:05 -05:00
|
|
|
|
if (getSciVersion() < SCI_VERSION_2_1_LATE) {
|
2017-10-06 22:05:57 -05:00
|
|
|
|
height = mulru(height, Ratio(g_sci->_gfxFrameout->getScriptHeight(), celObj._yResolution));
|
SCI32: Fix bad text rendering in RAMA
In SCI3, Sierra removed the ability of the main renderer to
automatically scale CelObjs with different source resolutions.
Instead, in SCI3, all CelObjs are treated as having the same
resolution as the screen (i.e. 640x480).
In all SCI3 games other than RAMA, keeping the code paths for
resolution-dependent scaling is not a problem because all the
assets and game code are correctly designed to use the same
640x480 resolution throughout. RAMA, on the other hand, was
written with the text subsystem set to a resolution of 630x450
(Phant1's screen resolution), and in SSCI, resolution-dependent
scaling code was not removed from the *text* subsystem. As a
result, RAMA's game scripts rely on the slightly larger scaled
dimensions coming out of the text system when determining the size
of screen items for rendering, and then also rely on the main
renderer ignoring the 630x450 resolution baked into the bitmaps
generated by the text subsystem when drawing them to the screen.
2017-09-29 14:57:22 -05:00
|
|
|
|
}
|
|
|
|
|
return make_reg(0, height);
|
2016-03-12 18:49:19 -06:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
reg_t kCelWide32(EngineState *s, int argc, reg_t *argv) {
|
2017-10-06 22:05:57 -05:00
|
|
|
|
const GuiResourceId resourceId = argv[0].toUint16();
|
|
|
|
|
const int16 loopNo = argv[1].toSint16();
|
|
|
|
|
const int16 celNo = argv[2].toSint16();
|
|
|
|
|
const CelObjView celObj(resourceId, loopNo, celNo);
|
SCI32: Fix bad text rendering in RAMA
In SCI3, Sierra removed the ability of the main renderer to
automatically scale CelObjs with different source resolutions.
Instead, in SCI3, all CelObjs are treated as having the same
resolution as the screen (i.e. 640x480).
In all SCI3 games other than RAMA, keeping the code paths for
resolution-dependent scaling is not a problem because all the
assets and game code are correctly designed to use the same
640x480 resolution throughout. RAMA, on the other hand, was
written with the text subsystem set to a resolution of 630x450
(Phant1's screen resolution), and in SSCI, resolution-dependent
scaling code was not removed from the *text* subsystem. As a
result, RAMA's game scripts rely on the slightly larger scaled
dimensions coming out of the text system when determining the size
of screen items for rendering, and then also rely on the main
renderer ignoring the 630x450 resolution baked into the bitmaps
generated by the text subsystem when drawing them to the screen.
2017-09-29 14:57:22 -05:00
|
|
|
|
int16 width = celObj._width;
|
2017-09-30 00:03:05 -05:00
|
|
|
|
if (getSciVersion() < SCI_VERSION_2_1_LATE) {
|
2017-10-06 22:05:57 -05:00
|
|
|
|
width = mulru(width, Ratio(g_sci->_gfxFrameout->getScriptWidth(), celObj._xResolution));
|
SCI32: Fix bad text rendering in RAMA
In SCI3, Sierra removed the ability of the main renderer to
automatically scale CelObjs with different source resolutions.
Instead, in SCI3, all CelObjs are treated as having the same
resolution as the screen (i.e. 640x480).
In all SCI3 games other than RAMA, keeping the code paths for
resolution-dependent scaling is not a problem because all the
assets and game code are correctly designed to use the same
640x480 resolution throughout. RAMA, on the other hand, was
written with the text subsystem set to a resolution of 630x450
(Phant1's screen resolution), and in SSCI, resolution-dependent
scaling code was not removed from the *text* subsystem. As a
result, RAMA's game scripts rely on the slightly larger scaled
dimensions coming out of the text system when determining the size
of screen items for rendering, and then also rely on the main
renderer ignoring the 630x450 resolution baked into the bitmaps
generated by the text subsystem when drawing them to the screen.
2017-09-29 14:57:22 -05:00
|
|
|
|
}
|
|
|
|
|
return make_reg(0, width);
|
2016-03-12 18:49:19 -06:00
|
|
|
|
}
|
|
|
|
|
|
2017-01-02 23:29:25 -06:00
|
|
|
|
// Used by Shivers 1, room 23601 to determine what blocks on the red door
|
|
|
|
|
// puzzle board are occupied by pieces already, and by Phantasmagoria 2 when
|
|
|
|
|
// saving the game from the in-game UI
|
2012-05-20 19:57:34 +03:00
|
|
|
|
reg_t kCelInfo(EngineState *s, int argc, reg_t *argv) {
|
2017-01-02 23:29:25 -06:00
|
|
|
|
if (!s)
|
|
|
|
|
return make_reg(0, getSciVersion());
|
|
|
|
|
error("not supposed to call this");
|
|
|
|
|
}
|
2016-03-13 23:38:26 -05:00
|
|
|
|
|
2017-01-02 23:29:25 -06:00
|
|
|
|
reg_t kCelInfoGetOriginX(EngineState *s, int argc, reg_t *argv) {
|
|
|
|
|
CelObjView view(argv[0].toUint16(), argv[1].toSint16(), argv[2].toSint16());
|
|
|
|
|
return make_reg(0, view._origin.x);
|
|
|
|
|
}
|
2016-03-13 23:38:26 -05:00
|
|
|
|
|
2017-01-02 23:29:25 -06:00
|
|
|
|
reg_t kCelInfoGetOriginY(EngineState *s, int argc, reg_t *argv) {
|
|
|
|
|
CelObjView view(argv[0].toUint16(), argv[1].toSint16(), argv[2].toSint16());
|
|
|
|
|
return make_reg(0, view._origin.y);
|
|
|
|
|
}
|
2016-03-13 23:38:26 -05:00
|
|
|
|
|
2017-01-02 23:29:25 -06:00
|
|
|
|
reg_t kCelInfoGetPixel(EngineState *s, int argc, reg_t *argv) {
|
|
|
|
|
CelObjView view(argv[0].toUint16(), argv[1].toSint16(), argv[2].toSint16());
|
2017-05-02 11:00:45 -05:00
|
|
|
|
return make_reg(0, view.readPixel(argv[3].toSint16(), argv[4].toSint16(), view._mirrorX));
|
2012-05-20 19:57:34 +03:00
|
|
|
|
}
|
|
|
|
|
|
2017-08-04 18:53:00 -05:00
|
|
|
|
// Used by Lighthouse, room 800, script 16, when in the weapon-building puzzle
|
|
|
|
|
reg_t kCelLink(EngineState *s, int argc, reg_t *argv) {
|
|
|
|
|
if (!s)
|
|
|
|
|
return make_reg(0, getSciVersion());
|
|
|
|
|
error("not supposed to call this");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
reg_t kCelLinkGetX(EngineState *s, int argc, reg_t *argv) {
|
|
|
|
|
CelObjView view(argv[0].toUint16(), argv[1].toSint16(), argv[2].toSint16());
|
|
|
|
|
return make_reg(0, view.getLinkPosition(argv[3].toSint16()).x);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
reg_t kCelLinkGetY(EngineState *s, int argc, reg_t *argv) {
|
|
|
|
|
CelObjView view(argv[0].toUint16(), argv[1].toSint16(), argv[2].toSint16());
|
|
|
|
|
return make_reg(0, view.getLinkPosition(argv[3].toSint16()).y);
|
|
|
|
|
}
|
|
|
|
|
|
2012-05-20 19:57:34 +03:00
|
|
|
|
reg_t kScrollWindow(EngineState *s, int argc, reg_t *argv) {
|
2016-02-16 01:36:10 -06:00
|
|
|
|
if (!s)
|
|
|
|
|
return make_reg(0, getSciVersion());
|
|
|
|
|
error("not supposed to call this");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
reg_t kScrollWindowCreate(EngineState *s, int argc, reg_t *argv) {
|
2016-03-20 16:53:58 +01:00
|
|
|
|
const reg_t object = argv[0];
|
|
|
|
|
const uint16 maxNumEntries = argv[1].toUint16();
|
|
|
|
|
|
|
|
|
|
SegManager *segMan = s->_segMan;
|
|
|
|
|
const int16 borderColor = readSelectorValue(segMan, object, SELECTOR(borderColor));
|
|
|
|
|
const TextAlign alignment = (TextAlign)readSelectorValue(segMan, object, SELECTOR(mode));
|
|
|
|
|
const GuiResourceId fontId = (GuiResourceId)readSelectorValue(segMan, object, SELECTOR(font));
|
|
|
|
|
const int16 backColor = readSelectorValue(segMan, object, SELECTOR(back));
|
|
|
|
|
const int16 foreColor = readSelectorValue(segMan, object, SELECTOR(fore));
|
|
|
|
|
const reg_t plane = readSelector(segMan, object, SELECTOR(plane));
|
|
|
|
|
|
|
|
|
|
Common::Rect rect;
|
2016-11-27 10:53:06 -06:00
|
|
|
|
|
|
|
|
|
if (g_sci->_features->usesAlternateSelectors()) {
|
|
|
|
|
rect.left = readSelectorValue(segMan, object, SELECTOR(left));
|
|
|
|
|
rect.top = readSelectorValue(segMan, object, SELECTOR(top));
|
|
|
|
|
rect.right = readSelectorValue(segMan, object, SELECTOR(right)) + 1;
|
|
|
|
|
rect.bottom = readSelectorValue(segMan, object, SELECTOR(bottom)) + 1;
|
|
|
|
|
} else {
|
|
|
|
|
rect.left = readSelectorValue(segMan, object, SELECTOR(nsLeft));
|
|
|
|
|
rect.top = readSelectorValue(segMan, object, SELECTOR(nsTop));
|
|
|
|
|
rect.right = readSelectorValue(segMan, object, SELECTOR(nsRight)) + 1;
|
|
|
|
|
rect.bottom = readSelectorValue(segMan, object, SELECTOR(nsBottom)) + 1;
|
|
|
|
|
}
|
2016-03-20 16:53:58 +01:00
|
|
|
|
const Common::Point position(rect.left, rect.top);
|
|
|
|
|
|
|
|
|
|
return g_sci->_gfxControls32->makeScrollWindow(rect, position, plane, foreColor, backColor, fontId, alignment, borderColor, maxNumEntries);
|
2016-02-16 01:36:10 -06:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
reg_t kScrollWindowAdd(EngineState *s, int argc, reg_t *argv) {
|
2016-03-20 16:53:58 +01:00
|
|
|
|
ScrollWindow *scrollWindow = g_sci->_gfxControls32->getScrollWindow(argv[0]);
|
|
|
|
|
|
|
|
|
|
const Common::String text = s->_segMan->getString(argv[1]);
|
|
|
|
|
const GuiResourceId fontId = argv[2].toSint16();
|
|
|
|
|
const int16 color = argv[3].toSint16();
|
|
|
|
|
const TextAlign alignment = (TextAlign)argv[4].toSint16();
|
|
|
|
|
const bool scrollTo = argc > 5 ? (bool)argv[5].toUint16() : true;
|
|
|
|
|
|
|
|
|
|
return scrollWindow->add(text, fontId, color, alignment, scrollTo);
|
2016-02-16 01:36:10 -06:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
reg_t kScrollWindowWhere(EngineState *s, int argc, reg_t *argv) {
|
2016-03-20 16:53:58 +01:00
|
|
|
|
ScrollWindow *scrollWindow = g_sci->_gfxControls32->getScrollWindow(argv[0]);
|
|
|
|
|
|
|
|
|
|
const uint16 where = (argv[1].toUint16() * scrollWindow->where()).toInt();
|
|
|
|
|
|
|
|
|
|
return make_reg(0, where);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
reg_t kScrollWindowGo(EngineState *s, int argc, reg_t *argv) {
|
|
|
|
|
ScrollWindow *scrollWindow = g_sci->_gfxControls32->getScrollWindow(argv[0]);
|
|
|
|
|
|
|
|
|
|
const Ratio scrollTop(argv[1].toSint16(), argv[2].toSint16());
|
|
|
|
|
scrollWindow->go(scrollTop);
|
|
|
|
|
|
|
|
|
|
return s->r_acc;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
reg_t kScrollWindowModify(EngineState *s, int argc, reg_t *argv) {
|
|
|
|
|
ScrollWindow *scrollWindow = g_sci->_gfxControls32->getScrollWindow(argv[0]);
|
|
|
|
|
|
|
|
|
|
const reg_t entryId = argv[1];
|
|
|
|
|
const Common::String newText = s->_segMan->getString(argv[2]);
|
|
|
|
|
const GuiResourceId fontId = argv[3].toSint16();
|
|
|
|
|
const int16 color = argv[4].toSint16();
|
|
|
|
|
const TextAlign alignment = (TextAlign)argv[5].toSint16();
|
|
|
|
|
const bool scrollTo = argc > 6 ? (bool)argv[6].toUint16() : true;
|
|
|
|
|
|
|
|
|
|
return scrollWindow->modify(entryId, newText, fontId, color, alignment, scrollTo);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
reg_t kScrollWindowHide(EngineState *s, int argc, reg_t *argv) {
|
|
|
|
|
ScrollWindow *scrollWindow = g_sci->_gfxControls32->getScrollWindow(argv[0]);
|
|
|
|
|
|
|
|
|
|
scrollWindow->hide();
|
|
|
|
|
|
|
|
|
|
return s->r_acc;
|
2016-02-16 01:36:10 -06:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
reg_t kScrollWindowShow(EngineState *s, int argc, reg_t *argv) {
|
2016-03-20 16:53:58 +01:00
|
|
|
|
ScrollWindow *scrollWindow = g_sci->_gfxControls32->getScrollWindow(argv[0]);
|
|
|
|
|
|
|
|
|
|
scrollWindow->show();
|
|
|
|
|
|
|
|
|
|
return s->r_acc;
|
2016-02-16 01:36:10 -06:00
|
|
|
|
}
|
|
|
|
|
|
2016-03-20 16:53:58 +01:00
|
|
|
|
reg_t kScrollWindowPageUp(EngineState *s, int argc, reg_t *argv) {
|
|
|
|
|
ScrollWindow *scrollWindow = g_sci->_gfxControls32->getScrollWindow(argv[0]);
|
|
|
|
|
|
|
|
|
|
scrollWindow->pageUp();
|
|
|
|
|
|
|
|
|
|
return s->r_acc;
|
2016-02-16 01:36:10 -06:00
|
|
|
|
}
|
|
|
|
|
|
2016-03-20 16:53:58 +01:00
|
|
|
|
reg_t kScrollWindowPageDown(EngineState *s, int argc, reg_t *argv) {
|
|
|
|
|
ScrollWindow *scrollWindow = g_sci->_gfxControls32->getScrollWindow(argv[0]);
|
|
|
|
|
|
|
|
|
|
scrollWindow->pageDown();
|
|
|
|
|
|
|
|
|
|
return s->r_acc;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
reg_t kScrollWindowUpArrow(EngineState *s, int argc, reg_t *argv) {
|
|
|
|
|
ScrollWindow *scrollWindow = g_sci->_gfxControls32->getScrollWindow(argv[0]);
|
|
|
|
|
|
|
|
|
|
scrollWindow->upArrow();
|
|
|
|
|
|
|
|
|
|
return s->r_acc;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
reg_t kScrollWindowDownArrow(EngineState *s, int argc, reg_t *argv) {
|
|
|
|
|
ScrollWindow *scrollWindow = g_sci->_gfxControls32->getScrollWindow(argv[0]);
|
|
|
|
|
|
|
|
|
|
scrollWindow->downArrow();
|
|
|
|
|
|
|
|
|
|
return s->r_acc;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
reg_t kScrollWindowHome(EngineState *s, int argc, reg_t *argv) {
|
|
|
|
|
ScrollWindow *scrollWindow = g_sci->_gfxControls32->getScrollWindow(argv[0]);
|
|
|
|
|
|
|
|
|
|
scrollWindow->home();
|
|
|
|
|
|
|
|
|
|
return s->r_acc;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
reg_t kScrollWindowEnd(EngineState *s, int argc, reg_t *argv) {
|
|
|
|
|
ScrollWindow *scrollWindow = g_sci->_gfxControls32->getScrollWindow(argv[0]);
|
|
|
|
|
|
|
|
|
|
scrollWindow->end();
|
|
|
|
|
|
|
|
|
|
return s->r_acc;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
reg_t kScrollWindowDestroy(EngineState *s, int argc, reg_t *argv) {
|
|
|
|
|
g_sci->_gfxControls32->destroyScrollWindow(argv[0]);
|
2012-05-20 19:57:34 +03:00
|
|
|
|
|
|
|
|
|
return s->r_acc;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
reg_t kFont(EngineState *s, int argc, reg_t *argv) {
|
2016-02-28 21:19:06 -06:00
|
|
|
|
if (!s)
|
|
|
|
|
return make_reg(0, getSciVersion());
|
|
|
|
|
error("not supposed to call this");
|
|
|
|
|
}
|
2012-05-20 19:57:34 +03:00
|
|
|
|
|
2017-02-07 15:27:15 -06:00
|
|
|
|
reg_t kPointSize(EngineState *s, int argc, reg_t *argv) {
|
2016-02-28 21:19:06 -06:00
|
|
|
|
g_sci->_gfxText32->setFont(argv[0].toUint16());
|
2017-02-07 15:27:15 -06:00
|
|
|
|
return make_reg(0, g_sci->_gfxText32->getScaledFontHeight());
|
2012-05-20 19:57:34 +03:00
|
|
|
|
}
|
|
|
|
|
|
2016-02-14 12:07:30 -06:00
|
|
|
|
reg_t kSetFontRes(EngineState *s, int argc, reg_t *argv) {
|
2016-10-09 10:52:08 -05:00
|
|
|
|
g_sci->_gfxText32->_xResolution = argv[0].toUint16();
|
|
|
|
|
g_sci->_gfxText32->_yResolution = argv[1].toUint16();
|
2016-03-20 09:31:28 -05:00
|
|
|
|
return s->r_acc;
|
2016-02-14 12:07:30 -06:00
|
|
|
|
}
|
|
|
|
|
|
2016-03-03 20:31:10 -06:00
|
|
|
|
reg_t kBitmap(EngineState *s, int argc, reg_t *argv) {
|
|
|
|
|
if (!s)
|
|
|
|
|
return make_reg(0, getSciVersion());
|
|
|
|
|
error("not supposed to call this");
|
|
|
|
|
}
|
2012-05-20 19:57:34 +03:00
|
|
|
|
|
2016-03-03 20:31:10 -06:00
|
|
|
|
reg_t kBitmapCreate(EngineState *s, int argc, reg_t *argv) {
|
|
|
|
|
int16 width = argv[0].toSint16();
|
|
|
|
|
int16 height = argv[1].toSint16();
|
|
|
|
|
int16 skipColor = argv[2].toSint16();
|
|
|
|
|
int16 backColor = argv[3].toSint16();
|
2016-10-09 10:52:08 -05:00
|
|
|
|
int16 xResolution = argc > 4 ? argv[4].toSint16() : g_sci->_gfxText32->_xResolution;
|
|
|
|
|
int16 yResolution = argc > 5 ? argv[5].toSint16() : g_sci->_gfxText32->_yResolution;
|
2016-03-03 20:31:10 -06:00
|
|
|
|
bool useRemap = argc > 6 ? argv[6].toSint16() : false;
|
2012-05-20 19:57:34 +03:00
|
|
|
|
|
2016-07-29 15:48:14 -05:00
|
|
|
|
reg_t bitmapId;
|
2016-10-09 10:52:08 -05:00
|
|
|
|
SciBitmap &bitmap = *s->_segMan->allocateBitmap(&bitmapId, width, height, skipColor, 0, 0, xResolution, yResolution, 0, useRemap, true);
|
2016-03-07 20:48:31 -06:00
|
|
|
|
memset(bitmap.getPixels(), backColor, width * height);
|
2016-07-29 15:48:14 -05:00
|
|
|
|
return bitmapId;
|
2016-03-03 20:31:10 -06:00
|
|
|
|
}
|
2012-05-20 19:57:34 +03:00
|
|
|
|
|
2016-03-03 20:31:10 -06:00
|
|
|
|
reg_t kBitmapDestroy(EngineState *s, int argc, reg_t *argv) {
|
2017-01-05 12:22:22 -06:00
|
|
|
|
if (s->_segMan->isValidAddr(argv[0], SEG_TYPE_BITMAP)) {
|
|
|
|
|
s->_segMan->freeBitmap(argv[0]);
|
2016-08-27 11:41:02 -05:00
|
|
|
|
}
|
2016-03-20 09:31:28 -05:00
|
|
|
|
return s->r_acc;
|
2016-03-03 20:31:10 -06:00
|
|
|
|
}
|
2012-05-20 19:57:34 +03:00
|
|
|
|
|
2016-03-03 20:31:10 -06:00
|
|
|
|
reg_t kBitmapDrawView(EngineState *s, int argc, reg_t *argv) {
|
2016-07-29 15:48:14 -05:00
|
|
|
|
SciBitmap &bitmap = *s->_segMan->lookupBitmap(argv[0]);
|
2016-06-21 16:09:30 -05:00
|
|
|
|
CelObjView view(argv[1].toUint16(), argv[2].toSint16(), argv[3].toSint16());
|
2016-03-03 20:31:10 -06:00
|
|
|
|
|
2016-06-21 16:09:30 -05:00
|
|
|
|
const int16 x = argc > 4 ? argv[4].toSint16() : 0;
|
|
|
|
|
const int16 y = argc > 5 ? argv[5].toSint16() : 0;
|
|
|
|
|
const int16 alignX = argc > 7 ? argv[7].toSint16() : -1;
|
|
|
|
|
const int16 alignY = argc > 8 ? argv[8].toSint16() : -1;
|
2016-03-03 20:31:10 -06:00
|
|
|
|
|
2016-06-21 16:09:30 -05:00
|
|
|
|
Common::Point position(
|
2016-10-09 10:52:08 -05:00
|
|
|
|
x == -1 ? bitmap.getOrigin().x : x,
|
|
|
|
|
y == -1 ? bitmap.getOrigin().y : y
|
2016-06-21 16:09:30 -05:00
|
|
|
|
);
|
2012-05-20 19:57:34 +03:00
|
|
|
|
|
2016-10-09 10:52:08 -05:00
|
|
|
|
position.x -= alignX == -1 ? view._origin.x : alignX;
|
|
|
|
|
position.y -= alignY == -1 ? view._origin.y : alignY;
|
2016-06-21 16:09:30 -05:00
|
|
|
|
|
|
|
|
|
Common::Rect drawRect(
|
|
|
|
|
position.x,
|
|
|
|
|
position.y,
|
|
|
|
|
position.x + view._width,
|
|
|
|
|
position.y + view._height
|
|
|
|
|
);
|
|
|
|
|
drawRect.clip(Common::Rect(bitmap.getWidth(), bitmap.getHeight()));
|
|
|
|
|
view.draw(bitmap.getBuffer(), drawRect, position, view._mirrorX);
|
|
|
|
|
return s->r_acc;
|
2016-03-03 20:31:10 -06:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
reg_t kBitmapDrawText(EngineState *s, int argc, reg_t *argv) {
|
|
|
|
|
// called e.g. from TextButton::createBitmap() in Torin's Passage, script 64894
|
|
|
|
|
|
2016-07-29 15:48:14 -05:00
|
|
|
|
SciBitmap &bitmap = *s->_segMan->lookupBitmap(argv[0]);
|
2016-03-07 20:50:24 -06:00
|
|
|
|
Common::String text = s->_segMan->getString(argv[1]);
|
|
|
|
|
Common::Rect textRect(
|
|
|
|
|
argv[2].toSint16(),
|
|
|
|
|
argv[3].toSint16(),
|
|
|
|
|
argv[4].toSint16() + 1,
|
|
|
|
|
argv[5].toSint16() + 1
|
|
|
|
|
);
|
|
|
|
|
int16 foreColor = argv[6].toSint16();
|
|
|
|
|
int16 backColor = argv[7].toSint16();
|
|
|
|
|
int16 skipColor = argv[8].toSint16();
|
|
|
|
|
GuiResourceId fontId = (GuiResourceId)argv[9].toUint16();
|
|
|
|
|
TextAlign alignment = (TextAlign)argv[10].toSint16();
|
|
|
|
|
int16 borderColor = argv[11].toSint16();
|
|
|
|
|
bool dimmed = argv[12].toUint16();
|
|
|
|
|
|
|
|
|
|
textRect.clip(Common::Rect(bitmap.getWidth(), bitmap.getHeight()));
|
|
|
|
|
|
2016-07-20 10:40:02 -05:00
|
|
|
|
reg_t textBitmapObject = g_sci->_gfxText32->createFontBitmap(textRect.width(), textRect.height(), Common::Rect(textRect.width(), textRect.height()), text, foreColor, backColor, skipColor, fontId, alignment, borderColor, dimmed, false, false);
|
2016-03-07 20:50:24 -06:00
|
|
|
|
CelObjMem textCel(textBitmapObject);
|
2016-06-21 16:00:05 -05:00
|
|
|
|
textCel.draw(bitmap.getBuffer(), textRect, Common::Point(textRect.left, textRect.top), false);
|
2016-07-29 15:48:14 -05:00
|
|
|
|
s->_segMan->freeBitmap(textBitmapObject);
|
2016-03-07 20:50:24 -06:00
|
|
|
|
|
2016-03-20 09:31:28 -05:00
|
|
|
|
return s->r_acc;
|
2016-03-03 20:31:10 -06:00
|
|
|
|
}
|
2012-05-20 19:57:34 +03:00
|
|
|
|
|
2016-03-03 20:31:10 -06:00
|
|
|
|
reg_t kBitmapDrawColor(EngineState *s, int argc, reg_t *argv) {
|
|
|
|
|
// called e.g. from TextView::init() and TextView::draw() in Torin's Passage, script 64890
|
|
|
|
|
|
2016-07-29 15:48:14 -05:00
|
|
|
|
SciBitmap &bitmap = *s->_segMan->lookupBitmap(argv[0]);
|
2016-03-14 10:22:00 -05:00
|
|
|
|
Common::Rect fillRect(
|
|
|
|
|
argv[1].toSint16(),
|
|
|
|
|
argv[2].toSint16(),
|
|
|
|
|
argv[3].toSint16() + 1,
|
|
|
|
|
argv[4].toSint16() + 1
|
|
|
|
|
);
|
2016-03-03 20:31:10 -06:00
|
|
|
|
|
2016-06-21 16:00:05 -05:00
|
|
|
|
bitmap.getBuffer().fillRect(fillRect, argv[5].toSint16());
|
2016-03-20 09:31:28 -05:00
|
|
|
|
return s->r_acc;
|
2016-03-03 20:31:10 -06:00
|
|
|
|
}
|
2012-05-20 19:57:34 +03:00
|
|
|
|
|
2016-10-09 10:52:08 -05:00
|
|
|
|
reg_t kBitmapSetOrigin(EngineState *s, int argc, reg_t *argv) {
|
2016-07-29 15:48:14 -05:00
|
|
|
|
SciBitmap &bitmap = *s->_segMan->lookupBitmap(argv[0]);
|
2016-10-09 10:52:08 -05:00
|
|
|
|
bitmap.setOrigin(Common::Point(argv[1].toSint16(), argv[2].toSint16()));
|
2016-03-15 11:29:24 +02:00
|
|
|
|
return s->r_acc;
|
2016-03-03 20:31:10 -06:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
reg_t kBitmapCreateFromView(EngineState *s, int argc, reg_t *argv) {
|
2016-09-24 21:17:25 -05:00
|
|
|
|
CelObjView view(argv[0].toUint16(), argv[1].toSint16(), argv[2].toSint16());
|
2016-10-09 10:52:08 -05:00
|
|
|
|
const uint8 skipColor = argc > 3 && argv[3].toSint16() != -1 ? argv[3].toSint16() : view._skipColor;
|
|
|
|
|
const uint8 backColor = argc > 4 && argv[4].toSint16() != -1 ? argv[4].toSint16() : view._skipColor;
|
2016-09-24 21:17:25 -05:00
|
|
|
|
const bool useRemap = argc > 5 ? (bool)argv[5].toSint16() : false;
|
2016-03-03 20:31:10 -06:00
|
|
|
|
|
2016-09-24 21:17:25 -05:00
|
|
|
|
reg_t bitmapId;
|
2016-10-09 10:52:08 -05:00
|
|
|
|
SciBitmap &bitmap = *s->_segMan->allocateBitmap(&bitmapId, view._width, view._height, skipColor, 0, 0, view._xResolution, view._yResolution, 0, useRemap, true);
|
2016-09-24 21:17:25 -05:00
|
|
|
|
Buffer &buffer = bitmap.getBuffer();
|
|
|
|
|
|
|
|
|
|
const Common::Rect viewRect(view._width, view._height);
|
|
|
|
|
buffer.fillRect(viewRect, backColor);
|
|
|
|
|
view.draw(buffer, viewRect, Common::Point(0, 0), view._mirrorX);
|
|
|
|
|
|
|
|
|
|
if (argc > 6 && !argv[6].isNull()) {
|
|
|
|
|
reg_t clutHandle = argv[6];
|
|
|
|
|
if (s->_segMan->isObject(clutHandle)) {
|
|
|
|
|
clutHandle = readSelector(s->_segMan, clutHandle, SELECTOR(data));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SciArray &clut = *s->_segMan->lookupArray(clutHandle);
|
|
|
|
|
bitmap.applyRemap(clut);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return bitmapId;
|
2016-03-03 20:31:10 -06:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
reg_t kBitmapGetInfo(EngineState *s, int argc, reg_t *argv) {
|
2016-09-24 21:17:25 -05:00
|
|
|
|
SciBitmap &bitmap = *s->_segMan->lookupBitmap(argv[0]);
|
2016-03-03 20:31:10 -06:00
|
|
|
|
|
2016-09-24 21:17:25 -05:00
|
|
|
|
if (argc == 1) {
|
|
|
|
|
return make_reg(0, bitmap.getWidth());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int32 offset;
|
|
|
|
|
if (argc == 2) {
|
|
|
|
|
offset = argv[1].toUint16();
|
|
|
|
|
} else {
|
|
|
|
|
const int16 x = argv[1].toSint16();
|
|
|
|
|
const int16 y = argv[2].toSint16();
|
|
|
|
|
offset = y * bitmap.getWidth() + x;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
assert(offset >= 0 && offset < bitmap.getWidth() * bitmap.getHeight());
|
|
|
|
|
const uint8 color = bitmap.getPixels()[offset];
|
|
|
|
|
return make_reg(0, color);
|
2016-03-03 20:31:10 -06:00
|
|
|
|
}
|
|
|
|
|
|
2016-03-05 23:56:38 -06:00
|
|
|
|
reg_t kEditText(EngineState *s, int argc, reg_t *argv) {
|
|
|
|
|
return g_sci->_gfxControls32->kernelEditText(argv[0]);
|
2012-05-20 19:57:34 +03:00
|
|
|
|
}
|
|
|
|
|
|
2012-06-09 15:36:36 +03:00
|
|
|
|
reg_t kAddLine(EngineState *s, int argc, reg_t *argv) {
|
2016-06-18 20:48:10 -05:00
|
|
|
|
const reg_t plane = argv[0];
|
|
|
|
|
const Common::Point startPoint(argv[1].toSint16(), argv[2].toSint16());
|
|
|
|
|
const Common::Point endPoint(argv[3].toSint16(), argv[4].toSint16());
|
|
|
|
|
|
|
|
|
|
int16 priority;
|
|
|
|
|
uint8 color;
|
|
|
|
|
LineStyle style;
|
|
|
|
|
uint16 pattern;
|
|
|
|
|
uint8 thickness;
|
|
|
|
|
|
|
|
|
|
if (argc == 10) {
|
|
|
|
|
priority = argv[5].toSint16();
|
|
|
|
|
color = (uint8)argv[6].toUint16();
|
|
|
|
|
style = (LineStyle)argv[7].toSint16();
|
|
|
|
|
pattern = argv[8].toUint16();
|
|
|
|
|
thickness = (uint8)argv[9].toUint16();
|
|
|
|
|
} else {
|
|
|
|
|
priority = 1000;
|
|
|
|
|
color = 255;
|
|
|
|
|
style = kLineStyleSolid;
|
|
|
|
|
pattern = 0;
|
|
|
|
|
thickness = 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return g_sci->_gfxPaint32->kernelAddLine(plane, startPoint, endPoint, priority, color, style, pattern, thickness);
|
2012-06-09 15:36:36 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
reg_t kUpdateLine(EngineState *s, int argc, reg_t *argv) {
|
2016-06-18 20:48:10 -05:00
|
|
|
|
const reg_t screenItemObject = argv[0];
|
|
|
|
|
const reg_t planeObject = argv[1];
|
|
|
|
|
const Common::Point startPoint(argv[2].toSint16(), argv[3].toSint16());
|
|
|
|
|
const Common::Point endPoint(argv[4].toSint16(), argv[5].toSint16());
|
|
|
|
|
|
|
|
|
|
int16 priority;
|
|
|
|
|
uint8 color;
|
|
|
|
|
LineStyle style;
|
|
|
|
|
uint16 pattern;
|
|
|
|
|
uint8 thickness;
|
|
|
|
|
|
|
|
|
|
Plane *plane = g_sci->_gfxFrameout->getPlanes().findByObject(planeObject);
|
|
|
|
|
if (plane == nullptr) {
|
|
|
|
|
error("kUpdateLine: Plane %04x:%04x not found", PRINT_REG(planeObject));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ScreenItem *screenItem = plane->_screenItemList.findByObject(screenItemObject);
|
|
|
|
|
if (screenItem == nullptr) {
|
|
|
|
|
error("kUpdateLine: Screen item %04x:%04x not found", PRINT_REG(screenItemObject));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (argc == 11) {
|
|
|
|
|
priority = argv[6].toSint16();
|
|
|
|
|
color = (uint8)argv[7].toUint16();
|
|
|
|
|
style = (LineStyle)argv[8].toSint16();
|
|
|
|
|
pattern = argv[9].toUint16();
|
|
|
|
|
thickness = (uint8)argv[10].toUint16();
|
|
|
|
|
} else {
|
|
|
|
|
priority = screenItem->_priority;
|
|
|
|
|
color = screenItem->_celInfo.color;
|
|
|
|
|
style = kLineStyleSolid;
|
|
|
|
|
pattern = 0;
|
|
|
|
|
thickness = 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
g_sci->_gfxPaint32->kernelUpdateLine(screenItem, plane, startPoint, endPoint, priority, color, style, pattern, thickness);
|
2016-01-18 00:12:47 -06:00
|
|
|
|
|
2012-06-09 15:36:36 +03:00
|
|
|
|
return s->r_acc;
|
|
|
|
|
}
|
2016-06-18 20:48:10 -05:00
|
|
|
|
|
2012-06-09 15:36:36 +03:00
|
|
|
|
reg_t kDeleteLine(EngineState *s, int argc, reg_t *argv) {
|
2016-06-18 20:48:10 -05:00
|
|
|
|
g_sci->_gfxPaint32->kernelDeleteLine(argv[0], argv[1]);
|
2012-06-09 15:36:36 +03:00
|
|
|
|
return s->r_acc;
|
|
|
|
|
}
|
|
|
|
|
|
2016-07-25 11:06:27 -05:00
|
|
|
|
// Used by LSL6hires intro (room 110)
|
2012-07-05 13:42:00 +03:00
|
|
|
|
reg_t kSetScroll(EngineState *s, int argc, reg_t *argv) {
|
2016-07-25 11:06:27 -05:00
|
|
|
|
const reg_t plane = argv[0];
|
|
|
|
|
const int16 deltaX = argv[1].toSint16();
|
|
|
|
|
const int16 deltaY = argv[2].toSint16();
|
|
|
|
|
const GuiResourceId pictureId = argv[3].toUint16();
|
|
|
|
|
const bool animate = argv[4].toUint16();
|
2017-10-05 21:41:29 -05:00
|
|
|
|
// argv[5] was some speed argument, but it was not actually used by SSCI, so
|
|
|
|
|
// we ignore it here
|
2016-07-25 11:06:27 -05:00
|
|
|
|
const bool mirrorX = argc > 6 ? (bool)argv[6].toUint16() : false;
|
|
|
|
|
|
|
|
|
|
g_sci->_gfxTransitions32->kernelSetScroll(plane, deltaX, deltaY, pictureId, animate, mirrorX);
|
|
|
|
|
return s->r_acc;
|
2012-07-05 13:42:00 +03:00
|
|
|
|
}
|
|
|
|
|
|
2016-01-14 12:05:29 -06:00
|
|
|
|
// Used by SQ6, script 900, the datacorder reprogramming puzzle (from room 270)
|
|
|
|
|
reg_t kMorphOn(EngineState *s, int argc, reg_t *argv) {
|
2016-01-18 00:12:47 -06:00
|
|
|
|
g_sci->_gfxFrameout->_palMorphIsOn = true;
|
2016-03-20 09:31:28 -05:00
|
|
|
|
return s->r_acc;
|
2016-01-14 10:50:41 -06:00
|
|
|
|
}
|
2016-01-14 12:05:29 -06:00
|
|
|
|
|
2016-07-09 12:41:12 -05:00
|
|
|
|
reg_t kPaletteSetFromResource32(EngineState *s, int argc, reg_t *argv) {
|
|
|
|
|
const GuiResourceId paletteId = argv[0].toUint16();
|
|
|
|
|
g_sci->_gfxPalette32->loadPalette(paletteId);
|
|
|
|
|
return s->r_acc;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
reg_t kPaletteFindColor32(EngineState *s, int argc, reg_t *argv) {
|
|
|
|
|
const uint8 r = argv[0].toUint16();
|
|
|
|
|
const uint8 g = argv[1].toUint16();
|
|
|
|
|
const uint8 b = argv[2].toUint16();
|
|
|
|
|
return make_reg(0, g_sci->_gfxPalette32->matchColor(r, g, b));
|
|
|
|
|
}
|
|
|
|
|
|
2016-08-22 19:04:26 +03:00
|
|
|
|
reg_t kPaletteSetGamma(EngineState *s, int argc, reg_t *argv) {
|
2017-02-24 12:15:57 -06:00
|
|
|
|
g_sci->_gfxPalette32->setGamma(argv[0].toSint16());
|
2016-08-22 19:04:26 +03:00
|
|
|
|
return s->r_acc;
|
|
|
|
|
}
|
|
|
|
|
|
2016-01-14 10:50:41 -06:00
|
|
|
|
reg_t kPaletteSetFade(EngineState *s, int argc, reg_t *argv) {
|
2016-09-28 13:05:50 -05:00
|
|
|
|
const uint16 fromColor = argv[0].toUint16();
|
|
|
|
|
const uint16 toColor = argv[1].toUint16();
|
|
|
|
|
const uint16 percent = argv[2].toUint16();
|
2016-01-14 10:50:41 -06:00
|
|
|
|
g_sci->_gfxPalette32->setFade(percent, fromColor, toColor);
|
2016-03-20 09:31:28 -05:00
|
|
|
|
return s->r_acc;
|
2013-01-10 23:43:36 +02:00
|
|
|
|
}
|
|
|
|
|
|
2016-01-14 10:50:41 -06:00
|
|
|
|
reg_t kPalVarySetVary(EngineState *s, int argc, reg_t *argv) {
|
2016-09-28 13:05:50 -05:00
|
|
|
|
const GuiResourceId paletteId = argv[0].toUint16();
|
|
|
|
|
const int32 time = argc > 1 ? argv[1].toSint16() * 60 : 0;
|
|
|
|
|
const int16 percent = argc > 2 ? argv[2].toSint16() : 100;
|
2016-01-14 10:50:41 -06:00
|
|
|
|
int16 fromColor;
|
|
|
|
|
int16 toColor;
|
|
|
|
|
|
2017-02-24 12:15:57 -06:00
|
|
|
|
if (g_sci->_features->hasMidPaletteCode() && argc > 4) {
|
2016-01-14 10:50:41 -06:00
|
|
|
|
fromColor = argv[3].toSint16();
|
|
|
|
|
toColor = argv[4].toSint16();
|
|
|
|
|
} else {
|
|
|
|
|
fromColor = toColor = -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
g_sci->_gfxPalette32->kernelPalVarySet(paletteId, percent, time, fromColor, toColor);
|
2016-03-20 09:31:28 -05:00
|
|
|
|
return s->r_acc;
|
2016-01-14 10:50:41 -06:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
reg_t kPalVarySetPercent(EngineState *s, int argc, reg_t *argv) {
|
2016-09-28 13:05:50 -05:00
|
|
|
|
const int32 time = argc > 0 ? argv[0].toSint16() * 60 : 0;
|
|
|
|
|
const int16 percent = argc > 1 ? argv[1].toSint16() : 0;
|
|
|
|
|
g_sci->_gfxPalette32->setVaryPercent(percent, time);
|
2016-03-20 09:31:28 -05:00
|
|
|
|
return s->r_acc;
|
2016-01-14 10:50:41 -06:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
reg_t kPalVaryGetPercent(EngineState *s, int argc, reg_t *argv) {
|
|
|
|
|
return make_reg(0, g_sci->_gfxPalette32->getVaryPercent());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
reg_t kPalVaryOff(EngineState *s, int argc, reg_t *argv) {
|
|
|
|
|
g_sci->_gfxPalette32->varyOff();
|
2016-03-20 09:31:28 -05:00
|
|
|
|
return s->r_acc;
|
2016-01-14 10:50:41 -06:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
reg_t kPalVaryMergeTarget(EngineState *s, int argc, reg_t *argv) {
|
2016-09-28 13:05:50 -05:00
|
|
|
|
const GuiResourceId paletteId = argv[0].toUint16();
|
2016-01-14 10:50:41 -06:00
|
|
|
|
g_sci->_gfxPalette32->kernelPalVaryMergeTarget(paletteId);
|
|
|
|
|
return make_reg(0, g_sci->_gfxPalette32->getVaryPercent());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
reg_t kPalVarySetTime(EngineState *s, int argc, reg_t *argv) {
|
2016-09-28 13:05:50 -05:00
|
|
|
|
const int32 time = argv[0].toSint16() * 60;
|
2016-01-14 10:50:41 -06:00
|
|
|
|
g_sci->_gfxPalette32->setVaryTime(time);
|
2016-03-20 09:31:28 -05:00
|
|
|
|
return s->r_acc;
|
2016-01-14 10:50:41 -06:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
reg_t kPalVarySetTarget(EngineState *s, int argc, reg_t *argv) {
|
2016-09-28 13:05:50 -05:00
|
|
|
|
const GuiResourceId paletteId = argv[0].toUint16();
|
2016-01-14 10:50:41 -06:00
|
|
|
|
g_sci->_gfxPalette32->kernelPalVarySetTarget(paletteId);
|
|
|
|
|
return make_reg(0, g_sci->_gfxPalette32->getVaryPercent());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
reg_t kPalVarySetStart(EngineState *s, int argc, reg_t *argv) {
|
2016-09-28 13:05:50 -05:00
|
|
|
|
const GuiResourceId paletteId = argv[0].toUint16();
|
2016-01-14 10:50:41 -06:00
|
|
|
|
g_sci->_gfxPalette32->kernelPalVarySetStart(paletteId);
|
|
|
|
|
return make_reg(0, g_sci->_gfxPalette32->getVaryPercent());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
reg_t kPalVaryMergeStart(EngineState *s, int argc, reg_t *argv) {
|
2016-09-28 13:05:50 -05:00
|
|
|
|
const GuiResourceId paletteId = argv[0].toUint16();
|
2016-01-14 10:50:41 -06:00
|
|
|
|
g_sci->_gfxPalette32->kernelPalVaryMergeStart(paletteId);
|
|
|
|
|
return make_reg(0, g_sci->_gfxPalette32->getVaryPercent());
|
2013-01-10 23:43:36 +02:00
|
|
|
|
}
|
|
|
|
|
|
2012-07-05 13:42:00 +03:00
|
|
|
|
reg_t kPalCycle(EngineState *s, int argc, reg_t *argv) {
|
2016-07-09 12:40:47 -05:00
|
|
|
|
if (!s)
|
|
|
|
|
return make_reg(0, getSciVersion());
|
|
|
|
|
error("not supposed to call this");
|
|
|
|
|
}
|
2012-07-05 13:42:00 +03:00
|
|
|
|
|
2016-07-09 12:40:47 -05:00
|
|
|
|
reg_t kPalCycleSetCycle(EngineState *s, int argc, reg_t *argv) {
|
|
|
|
|
const uint16 fromColor = argv[0].toUint16();
|
|
|
|
|
const uint16 toColor = argv[1].toUint16();
|
|
|
|
|
const int16 direction = argv[2].toSint16();
|
|
|
|
|
const uint16 delay = argc > 3 ? argv[3].toUint16() : 0;
|
|
|
|
|
g_sci->_gfxPalette32->setCycle(fromColor, toColor, direction, delay);
|
|
|
|
|
return s->r_acc;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
reg_t kPalCycleDoCycle(EngineState *s, int argc, reg_t *argv) {
|
|
|
|
|
const uint16 fromColor = argv[0].toUint16();
|
|
|
|
|
const int16 speed = argc > 1 ? argv[1].toSint16() : 1;
|
|
|
|
|
g_sci->_gfxPalette32->doCycle(fromColor, speed);
|
|
|
|
|
return s->r_acc;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
reg_t kPalCyclePause(EngineState *s, int argc, reg_t *argv) {
|
|
|
|
|
if (argc == 0) {
|
|
|
|
|
g_sci->_gfxPalette32->cycleAllPause();
|
|
|
|
|
} else {
|
|
|
|
|
const uint16 fromColor = argv[0].toUint16();
|
|
|
|
|
g_sci->_gfxPalette32->cyclePause(fromColor);
|
2012-07-05 13:42:00 +03:00
|
|
|
|
}
|
2016-07-09 12:40:47 -05:00
|
|
|
|
return s->r_acc;
|
|
|
|
|
}
|
2012-07-05 13:42:00 +03:00
|
|
|
|
|
2016-07-09 12:40:47 -05:00
|
|
|
|
reg_t kPalCycleOn(EngineState *s, int argc, reg_t *argv) {
|
|
|
|
|
if (argc == 0) {
|
|
|
|
|
g_sci->_gfxPalette32->cycleAllOn();
|
|
|
|
|
} else {
|
|
|
|
|
const uint16 fromColor = argv[0].toUint16();
|
|
|
|
|
g_sci->_gfxPalette32->cycleOn(fromColor);
|
|
|
|
|
}
|
|
|
|
|
return s->r_acc;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
reg_t kPalCycleOff(EngineState *s, int argc, reg_t *argv) {
|
|
|
|
|
if (argc == 0) {
|
|
|
|
|
g_sci->_gfxPalette32->cycleAllOff();
|
|
|
|
|
} else {
|
|
|
|
|
const uint16 fromColor = argv[0].toUint16();
|
|
|
|
|
g_sci->_gfxPalette32->cycleOff(fromColor);
|
|
|
|
|
}
|
2012-07-05 13:42:00 +03:00
|
|
|
|
return s->r_acc;
|
|
|
|
|
}
|
|
|
|
|
|
2016-06-25 14:19:47 -05:00
|
|
|
|
reg_t kRemapColors32(EngineState *s, int argc, reg_t *argv) {
|
2016-03-11 05:10:32 +02:00
|
|
|
|
if (!s)
|
|
|
|
|
return make_reg(0, getSciVersion());
|
|
|
|
|
error("not supposed to call this");
|
|
|
|
|
}
|
2012-07-25 01:32:34 +03:00
|
|
|
|
|
2016-06-25 14:19:47 -05:00
|
|
|
|
reg_t kRemapColorsOff(EngineState *s, int argc, reg_t *argv) {
|
|
|
|
|
if (argc == 0) {
|
|
|
|
|
g_sci->_gfxRemap32->remapAllOff();
|
|
|
|
|
} else {
|
|
|
|
|
const uint8 color = argv[0].toUint16();
|
|
|
|
|
g_sci->_gfxRemap32->remapOff(color);
|
|
|
|
|
}
|
2016-03-11 05:10:32 +02:00
|
|
|
|
return s->r_acc;
|
|
|
|
|
}
|
2012-07-24 00:16:42 +03:00
|
|
|
|
|
2016-06-25 14:19:47 -05:00
|
|
|
|
reg_t kRemapColorsByRange(EngineState *s, int argc, reg_t *argv) {
|
|
|
|
|
const uint8 color = argv[0].toUint16();
|
|
|
|
|
const int16 from = argv[1].toSint16();
|
|
|
|
|
const int16 to = argv[2].toSint16();
|
|
|
|
|
const int16 base = argv[3].toSint16();
|
2017-10-06 15:14:49 -05:00
|
|
|
|
// There is an optional last parameter after `base` which was only used by
|
|
|
|
|
// the priority map debugger which does not exist in release versions of
|
|
|
|
|
// SSCI
|
2016-06-25 14:19:47 -05:00
|
|
|
|
g_sci->_gfxRemap32->remapByRange(color, from, to, base);
|
2016-03-11 05:10:32 +02:00
|
|
|
|
return s->r_acc;
|
|
|
|
|
}
|
|
|
|
|
|
2016-06-25 14:19:47 -05:00
|
|
|
|
reg_t kRemapColorsByPercent(EngineState *s, int argc, reg_t *argv) {
|
|
|
|
|
const uint8 color = argv[0].toUint16();
|
|
|
|
|
const int16 percent = argv[1].toSint16();
|
2017-10-06 15:14:49 -05:00
|
|
|
|
// There is an optional last parameter after `percent` which was only used
|
|
|
|
|
// by the priority map debugger, which does not exist in release versions of
|
|
|
|
|
// SSCI
|
2016-06-25 14:19:47 -05:00
|
|
|
|
g_sci->_gfxRemap32->remapByPercent(color, percent);
|
2016-03-11 05:10:32 +02:00
|
|
|
|
return s->r_acc;
|
|
|
|
|
}
|
|
|
|
|
|
2016-06-25 14:19:47 -05:00
|
|
|
|
reg_t kRemapColorsToGray(EngineState *s, int argc, reg_t *argv) {
|
|
|
|
|
const uint8 color = argv[0].toUint16();
|
|
|
|
|
const int16 gray = argv[1].toSint16();
|
2017-10-06 15:14:49 -05:00
|
|
|
|
// There is an optional last parameter after `gray` which was only used by
|
|
|
|
|
// the priority map debugger, which does not exist in release versions of
|
|
|
|
|
// SSCI
|
2016-06-25 14:19:47 -05:00
|
|
|
|
g_sci->_gfxRemap32->remapToGray(color, gray);
|
2016-03-11 05:10:32 +02:00
|
|
|
|
return s->r_acc;
|
|
|
|
|
}
|
|
|
|
|
|
2016-06-25 14:19:47 -05:00
|
|
|
|
reg_t kRemapColorsToPercentGray(EngineState *s, int argc, reg_t *argv) {
|
|
|
|
|
const uint8 color = argv[0].toUint16();
|
|
|
|
|
const int16 gray = argv[1].toSint16();
|
|
|
|
|
const int16 percent = argv[2].toSint16();
|
2017-10-06 15:14:49 -05:00
|
|
|
|
// There is an optional last parameter after `percent` which was only used
|
|
|
|
|
// by the priority map debugger, which does not exist in release versions of
|
|
|
|
|
// SSCI
|
2016-06-25 14:19:47 -05:00
|
|
|
|
g_sci->_gfxRemap32->remapToPercentGray(color, gray, percent);
|
2016-03-11 05:10:32 +02:00
|
|
|
|
return s->r_acc;
|
|
|
|
|
}
|
2012-07-24 00:16:42 +03:00
|
|
|
|
|
2016-06-25 14:19:47 -05:00
|
|
|
|
reg_t kRemapColorsBlockRange(EngineState *s, int argc, reg_t *argv) {
|
|
|
|
|
const uint8 from = argv[0].toUint16();
|
|
|
|
|
const uint8 count = argv[1].toUint16();
|
|
|
|
|
g_sci->_gfxRemap32->blockRange(from, count);
|
2012-07-24 00:16:42 +03:00
|
|
|
|
return s->r_acc;
|
|
|
|
|
}
|
|
|
|
|
|
2012-05-20 19:57:34 +03:00
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
} // End of namespace Sci
|