[Scummvm-cvs-logs] scummvm master -> 8c1ca6548d9dd656f093f7b7962612715c0bf5e9

bluegr md5 at scummvm.org
Sun May 20 19:17:18 CEST 2012


This automated email contains information about 4 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
6f9e49faeb SCI: Add another workaround for the map scene in TMM
fceeca2666 SCI: Change sci_opcodes to CamelCase
f8c24b5d88 SCI: Split the SCI32 graphics kernel functions in a separate file
8c1ca6548d SAGA: Fix bug #3528338 - "ITE: Subtitles always shown in introduction"


Commit: 6f9e49faeb1e6e2839fce4b0ef4cd418ecdb8573
    https://github.com/scummvm/scummvm/commit/6f9e49faeb1e6e2839fce4b0ef4cd418ecdb8573
Author: Filippos Karapetis (md5 at scummvm.org)
Date: 2012-05-20T10:16:11-07:00

Commit Message:
SCI: Add another workaround for the map scene in TMM

Thanks to TMM for details on reproducing this

Changed paths:
    engines/sci/engine/workarounds.cpp



diff --git a/engines/sci/engine/workarounds.cpp b/engines/sci/engine/workarounds.cpp
index 4a0aea8..81c6fbb 100644
--- a/engines/sci/engine/workarounds.cpp
+++ b/engines/sci/engine/workarounds.cpp
@@ -321,8 +321,9 @@ const SciWorkaroundEntry kGraphRedrawBox_workarounds[] = {
 //    gameID,           room,script,lvl,          object-name, method-name,    call,index,                workaround
 const SciWorkaroundEntry kGraphUpdateBox_workarounds[] = {
 	{ GID_ECOQUEST2,     100,   333,  0,        "showEcorder", "changeState",    -1,    0, { WORKAROUND_STILLCALL, 0 } }, // necessary workaround for our ecorder script patch, because there isn't enough space to patch the function
-	{ GID_PQ3,           202,   202,  0,            "MapEdit", "movePt",         -1,    0, { WORKAROUND_STILLCALL, 0 } }, // when plotting crimes, gets called with 2 extra parameters - bug #3038077
 	{ GID_PQ3,           202,   202,  0,            "MapEdit", "addPt",          -1,    0, { WORKAROUND_STILLCALL, 0 } }, // when plotting crimes, gets called with 2 extra parameters - bug #3038077
+	{ GID_PQ3,           202,   202,  0,            "MapEdit", "movePt",         -1,    0, { WORKAROUND_STILLCALL, 0 } }, // when plotting crimes, gets called with 2 extra parameters - bug #3038077
+	{ GID_PQ3,           202,   202,  0,            "MapEdit", "dispose",        -1,    0, { WORKAROUND_STILLCALL, 0 } }, // when plotting crimes, gets called with 2 extra parameters
 	SCI_WORKAROUNDENTRY_TERMINATOR
 };
 


Commit: fceeca266600b82c0ef3ab4488a93f7509ff8d96
    https://github.com/scummvm/scummvm/commit/fceeca266600b82c0ef3ab4488a93f7509ff8d96
Author: Filippos Karapetis (md5 at scummvm.org)
Date: 2012-05-20T10:16:13-07:00

Commit Message:
SCI: Change sci_opcodes to CamelCase

Changed paths:
    engines/sci/engine/vm.h



diff --git a/engines/sci/engine/vm.h b/engines/sci/engine/vm.h
index 334d224..23f5a09 100644
--- a/engines/sci/engine/vm.h
+++ b/engines/sci/engine/vm.h
@@ -139,7 +139,7 @@ enum {
 	GC_INTERVAL = 0x8000
 };
 
-enum sci_opcodes {
+enum sciOpcodes {
 	op_bnot     = 0x00,	// 000
 	op_add      = 0x01,	// 001
 	op_sub      = 0x02,	// 002


Commit: f8c24b5d8847f512c559ff5b5d7e385eebecd79e
    https://github.com/scummvm/scummvm/commit/f8c24b5d8847f512c559ff5b5d7e385eebecd79e
Author: Filippos Karapetis (md5 at scummvm.org)
Date: 2012-05-20T10:16:15-07:00

Commit Message:
SCI: Split the SCI32 graphics kernel functions in a separate file

Changed paths:
  A engines/sci/engine/kgraphics32.cpp
    engines/sci/engine/kgraphics.cpp
    engines/sci/module.mk



diff --git a/engines/sci/engine/kgraphics.cpp b/engines/sci/engine/kgraphics.cpp
index caae562..8bf7be4 100644
--- a/engines/sci/engine/kgraphics.cpp
+++ b/engines/sci/engine/kgraphics.cpp
@@ -25,12 +25,10 @@
 #include "engines/util.h"
 #include "graphics/cursorman.h"
 #include "graphics/surface.h"
-#include "graphics/palette.h"	// temporary, for the fadeIn()/fadeOut() functions below
 
 #include "gui/message.h"
 
 #include "sci/sci.h"
-#include "sci/debug.h"	// for g_debug_sleeptime_factor
 #include "sci/event.h"
 #include "sci/resource.h"
 #include "sci/engine/features.h"
@@ -50,10 +48,7 @@
 #include "sci/graphics/text16.h"
 #include "sci/graphics/view.h"
 #ifdef ENABLE_SCI32
-#include "sci/graphics/controls32.h"
-#include "sci/graphics/font.h"	// TODO: remove once kBitmap is moved in a separate class
 #include "sci/graphics/text32.h"
-#include "sci/graphics/frameout.h"
 #endif
 
 namespace Sci {
@@ -1275,622 +1270,4 @@ reg_t kRemapColors(EngineState *s, int argc, reg_t *argv) {
 	return s->r_acc;
 }
 
-#ifdef ENABLE_SCI32
-
-reg_t kIsHiRes(EngineState *s, int argc, reg_t *argv) {
-	// Returns 0 if the screen width or height is less than 640 or 400,
-	// respectively.
-	if (g_system->getWidth() < 640 || g_system->getHeight() < 400)
-		return make_reg(0, 0);
-
-	return make_reg(0, 1);
-}
-
-// SCI32 variant, can't work like sci16 variants
-reg_t kCantBeHere32(EngineState *s, int argc, reg_t *argv) {
-	// TODO
-//	reg_t curObject = argv[0];
-//	reg_t listReference = (argc > 1) ? argv[1] : NULL_REG;
-
-	return NULL_REG;
-}
-
-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;
-}
-
-reg_t kUpdateScreenItem(EngineState *s, int argc, reg_t *argv) {
-	g_sci->_gfxFrameout->kernelUpdateScreenItem(argv[0]);
-	return s->r_acc;
-}
-
-reg_t kDeleteScreenItem(EngineState *s, int argc, reg_t *argv) {
-	g_sci->_gfxFrameout->kernelDeleteScreenItem(argv[0]);
-	return s->r_acc;
-}
-
-reg_t kAddPlane(EngineState *s, int argc, reg_t *argv) {
-	g_sci->_gfxFrameout->kernelAddPlane(argv[0]);
-	return s->r_acc;
-}
-
-reg_t kDeletePlane(EngineState *s, int argc, reg_t *argv) {
-	g_sci->_gfxFrameout->kernelDeletePlane(argv[0]);
-	return s->r_acc;
-}
-
-reg_t kUpdatePlane(EngineState *s, int argc, reg_t *argv) {
-	g_sci->_gfxFrameout->kernelUpdatePlane(argv[0]);
-	return s->r_acc;
-}
-
-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();
-
-	g_sci->_gfxFrameout->kernelAddPicAt(planeObj, pictureId, pictureX, pictureY);
-	return s->r_acc;
-}
-
-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) {
-	g_sci->_gfxFrameout->kernelFrameout();
-	return NULL_REG;
-}
-
-reg_t kObjectIntersect(EngineState *s, int argc, reg_t *argv) {
-	Common::Rect objRect1 = g_sci->_gfxCompare->getNSRect(argv[0]);
-	Common::Rect objRect2 = g_sci->_gfxCompare->getNSRect(argv[1]);
-	return make_reg(0, objRect1.intersects(objRect2));
-}
-
-// 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];
-	uint16 illegalBits = argv[3].offset;
-	Common::Rect nsRect = g_sci->_gfxCompare->getNSRect(targetObject, true);
-
-	// we assume that x, y are local coordinates
-
-	bool contained = nsRect.contains(x, y);
-	if (contained && illegalBits) {
-		// If illegalbits are set, we check the color of the pixel that got clicked on
-		//  for now, we return false if the pixel is transparent
-		//  although illegalBits may get differently set, don't know yet how this really works out
-		uint16 viewId = readSelectorValue(s->_segMan, targetObject, SELECTOR(view));
-		int16 loopNo = readSelectorValue(s->_segMan, targetObject, SELECTOR(loop));
-		int16 celNo = readSelectorValue(s->_segMan, targetObject, SELECTOR(cel));
-		if (g_sci->_gfxCompare->kernelIsItSkip(viewId, loopNo, celNo, Common::Point(x - nsRect.left, y - nsRect.top)))
-			contained = false;
-	}
-	return make_reg(0, contained);
-}
-
-reg_t kCreateTextBitmap(EngineState *s, int argc, reg_t *argv) {
-	switch (argv[0].toUint16()) {
-	case 0: {
-		if (argc != 4) {
-			warning("kCreateTextBitmap(0): expected 4 arguments, got %i", argc);
-			return NULL_REG;
-		}
-		reg_t object = argv[3];
-		Common::String text = s->_segMan->getString(readSelector(s->_segMan, object, SELECTOR(text)));
-		debugC(kDebugLevelStrings, "kCreateTextBitmap case 0 (%04x:%04x, %04x:%04x, %04x:%04x)",
-				PRINT_REG(argv[1]), PRINT_REG(argv[2]), PRINT_REG(argv[3]));
-		debugC(kDebugLevelStrings, "%s", text.c_str());
-		uint16 maxWidth = argv[1].toUint16();	// nsRight - nsLeft + 1
-		uint16 maxHeight = argv[2].toUint16();	// nsBottom - nsTop + 1
-		return g_sci->_gfxText32->createTextBitmap(object, maxWidth, maxHeight);
-	}
-	case 1: {
-		if (argc != 2) {
-			warning("kCreateTextBitmap(1): expected 2 arguments, got %i", argc);
-			return NULL_REG;
-		}
-		reg_t object = argv[1];
-		Common::String text = s->_segMan->getString(readSelector(s->_segMan, object, SELECTOR(text)));
-		debugC(kDebugLevelStrings, "kCreateTextBitmap case 1 (%04x:%04x)", PRINT_REG(argv[1]));
-		debugC(kDebugLevelStrings, "%s", text.c_str());
-		return g_sci->_gfxText32->createTextBitmap(object);
-	}
-	default:
-		warning("CreateTextBitmap(%d)", argv[0].toUint16());
-		return NULL_REG;
-	}
-}
-
-reg_t kDisposeTextBitmap(EngineState *s, int argc, reg_t *argv) {
-	g_sci->_gfxText32->disposeTextBitmap(argv[0]);
-	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;
-}
-
-// Taken from the SCI16 GfxTransitions class
-static void fadeOut() {
-	byte oldPalette[3 * 256], workPalette[3 * 256];
-	int16 stepNr, colorNr;
-	// Sierra did not fade in/out color 255 for sci1.1, but they used it in
-	//  several pictures (e.g. qfg3 demo/intro), so the fading looked weird
-	int16 tillColorNr = getSciVersion() >= SCI_VERSION_1_1 ? 255 : 254;
-
-	g_system->getPaletteManager()->grabPalette(oldPalette, 0, 256);
-
-	for (stepNr = 100; stepNr >= 0; stepNr -= 10) {
-		for (colorNr = 1; colorNr <= tillColorNr; colorNr++) {
-			if (g_sci->_gfxPalette->colorIsFromMacClut(colorNr)) {
-				workPalette[colorNr * 3 + 0] = oldPalette[colorNr * 3];
-				workPalette[colorNr * 3 + 1] = oldPalette[colorNr * 3 + 1];
-				workPalette[colorNr * 3 + 2] = oldPalette[colorNr * 3 + 2];
-			} else {
-				workPalette[colorNr * 3 + 0] = oldPalette[colorNr * 3] * stepNr / 100;
-				workPalette[colorNr * 3 + 1] = oldPalette[colorNr * 3 + 1] * stepNr / 100;
-				workPalette[colorNr * 3 + 2] = oldPalette[colorNr * 3 + 2] * stepNr / 100;
-			}
-		}
-		g_system->getPaletteManager()->setPalette(workPalette + 3, 1, tillColorNr);
-		g_sci->getEngineState()->wait(2);
-	}
-}
-
-// Taken from the SCI16 GfxTransitions class
-static void fadeIn() {
-	int16 stepNr;
-	// Sierra did not fade in/out color 255 for sci1.1, but they used it in
-	//  several pictures (e.g. qfg3 demo/intro), so the fading looked weird
-	int16 tillColorNr = getSciVersion() >= SCI_VERSION_1_1 ? 255 : 254;
-
-	for (stepNr = 0; stepNr <= 100; stepNr += 10) {
-		g_sci->_gfxPalette->kernelSetIntensity(1, tillColorNr + 1, stepNr, true);
-		g_sci->getEngineState()->wait(2);
-	}
-}
-
-/**
- * Used for scene transitions, replacing (but reusing parts of) the old
- * transition code.
- */
-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
-	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
-	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?)
-	}
-
-	if (showStyle > 15) {
-		warning("kSetShowStyle: Illegal style %d for plane %04x:%04x", showStyle, PRINT_REG(planeObj));
-		return s->r_acc;
-	}
-
-	// TODO: Proper implementation. This is a very basic version. I'm not even
-	// sure if the rest of the styles will work with this mechanism.
-
-	// Check if the passed parameters are the ones we expect
-	if (showStyle == 13 || showStyle == 14) {	// fade out / fade in
-		if (seconds != 1)
-			warning("kSetShowStyle(fade): seconds isn't 1, it's %d", seconds);
-		if (backColor != 0 && backColor != 0xFFFF)
-			warning("kSetShowStyle(fade): backColor isn't 0 or 0xFFFF, it's %d", backColor);
-		if (priority != 200)
-			warning("kSetShowStyle(fade): priority isn't 200, it's %d", priority);
-		if (animate != 0)
-			warning("kSetShowStyle(fade): animate isn't 0, it's %d", animate);
-		if (refFrame != 0)
-			warning("kSetShowStyle(fade): refFrame isn't 0, it's %d", refFrame);
-		if (divisions >= 0 && divisions != 20)
-			warning("kSetShowStyle(fade): divisions isn't 20, it's %d", divisions);
-	}
-
-	// TODO: Check if the plane is in the list of planes to draw
-
-	switch (showStyle) {
-	//case 0:	// no transition, perhaps? (like in the previous SCI versions)
-	case 13:	// fade out
-		// TODO: Temporary implementation, which ignores all additional parameters
-		fadeOut();
-		break;
-	case 14:	// fade in
-		// TODO: Temporary implementation, which ignores all additional parameters
-		g_sci->_gfxFrameout->kernelFrameout();	// draw new scene before fading in
-		fadeIn();
-		break;
-	default:
-		// TODO: This is all a stub/skeleton, thus we're invoking kStub() for now
-		kStub(s, argc, argv);
-		break;
-	}
-
-	return s->r_acc;
-}
-
-reg_t kCelInfo(EngineState *s, int argc, reg_t *argv) {
-	// Used by Shivers 1, room 23601 to determine what blocks on the red door puzzle board
-	// are occupied by pieces already
-
-	switch (argv[0].toUint16()) {	// subops 0 - 4
-		// 0 - return the view
-		// 1 - return the loop
-		// 2, 3 - nop
-		case 4: {
-			GuiResourceId viewId = argv[1].toSint16();
-			int16 loopNo = argv[2].toSint16();
-			int16 celNo = argv[3].toSint16();
-			int16 x = argv[4].toUint16();
-			int16 y = argv[5].toUint16();
-			byte color = g_sci->_gfxCache->kernelViewGetColorAtCoordinate(viewId, loopNo, celNo, x, y);
-			return make_reg(0, color);
-		}
-		default: {
-			kStub(s, argc, argv);
-			return s->r_acc;
-		}
-	}
-}
-
-reg_t kScrollWindow(EngineState *s, int argc, reg_t *argv) {
-	// Used by Phantasmagoria 1 and SQ6. In SQ6, it is used for the messages
-	// shown in the scroll window at the bottom of the screen.
-
-	// TODO: This is all a stub/skeleton, thus we're invoking kStub() for now
-	kStub(s, argc, argv);
-
-	switch (argv[0].toUint16()) {
-	case 0:	// Init
-		// 2 parameters
-		// argv[1] points to the scroll object (e.g. textScroller in SQ6)
-		// argv[2] is an integer (e.g. 0x32)
-		break;
-	case 1: // Show message
-		// 5 or 6 parameters
-		// Seems to be called with 5 parameters when the narrator speaks, and
-		// with 6 when Roger speaks
-		// argv[1] unknown (usually 0)
-		// argv[2] the text to show
-		// argv[3] a small integer (e.g. 0x32)
-		// argv[4] a small integer (e.g. 0x54)
-		// argv[5] optional, unknown (usually 0)
-		warning("kScrollWindow: '%s'", s->_segMan->getString(argv[2]).c_str());
-		break;
-	case 2: // Clear
-		// 2 parameters
-		// TODO
-		break;
-	case 3: // Page up
-		// 2 parameters
-		// TODO
-		break;
-	case 4: // Page down
-		// 2 parameters
-		// TODO
-		break;
-	case 5: // Up arrow
-		// 2 parameters
-		// TODO
-		break;
-	case 6: // Down arrow
-		// 2 parameters
-		// TODO
-		break;
-	case 7: // Home
-		// 2 parameters
-		// TODO
-		break;
-	case 8: // End
-		// 2 parameters
-		// TODO
-		break;
-	case 9: // Resize
-		// 3 parameters
-		// TODO
-		break;
-	case 10: // Where
-		// 3 parameters
-		// TODO
-		break;
-	case 11: // Go
-		// 4 parameters
-		// TODO
-		break;
-	case 12: // Insert
-		// 7 parameters
-		// TODO
-		break;
-	case 13: // Delete
-		// 3 parameters
-		// TODO
-		break;
-	case 14: // Modify
-		// 7 or 8 parameters
-		// TODO
-		break;
-	case 15: // Hide
-		// 2 parameters
-		// TODO
-		break;
-	case 16: // Show
-		// 2 parameters
-		// TODO
-		break;
-	case 17: // Destroy
-		// 2 parameters
-		// TODO
-		break;
-	case 18: // Text
-		// 2 parameters
-		// TODO
-		break;
-	case 19: // Reconstruct
-		// 3 parameters
-		// TODO
-		break;
-	default:
-		error("kScrollWindow: unknown subop %d", argv[0].toUint16());
-		break;
-	}
-
-	return s->r_acc;
-}
-
-reg_t kSetFontRes(EngineState *s, int argc, reg_t *argv) {
-	// TODO: This defines the resolution that the fonts are supposed to be displayed
-	// in. Currently, this is only used for showing high-res fonts in GK1 Mac, but
-	// should be extended to handle other font resolutions such as those
-
-	int xResolution = argv[0].toUint16();
-	//int yResolution = argv[1].toUint16();
-
-	g_sci->_gfxScreen->setFontIsUpscaled(xResolution == 640 &&
-			g_sci->_gfxScreen->getUpscaledHires() != GFX_SCREEN_UPSCALED_DISABLED);
-
-	return s->r_acc;
-}
-
-reg_t kFont(EngineState *s, int argc, reg_t *argv) {
-	// Handle font settings for SCI2.1
-
-	switch (argv[0].toUint16()) {
-	case 1:
-		// Set font resolution
-		return kSetFontRes(s, argc - 1, argv + 1);
-	default:
-		warning("kFont: unknown subop %d", argv[0].toUint16());
-	}
-
-	return s->r_acc;
-}
-
-// TODO: Eventually, all of the kBitmap operations should be put
-// in a separate class
-
-#define BITMAP_HEADER_SIZE 46
-
-reg_t kBitmap(EngineState *s, int argc, reg_t *argv) {
-	// Used for bitmap operations in SCI2.1 and SCI3.
-	// This is the SCI2.1 version, the functionality seems to have changed in SCI3.
-
-	switch (argv[0].toUint16()) {
-	case 0:	// init bitmap surface
-		{
-		// 6 params, called e.g. from TextView::init() in Torin's Passage,
-		// script 64890 and TransView::init() in script 64884
-		uint16 width = argv[1].toUint16();
-		uint16 height = argv[2].toUint16();
-		//uint16 skip = argv[3].toUint16();
-		uint16 back = argv[4].toUint16();	// usually equals skip
-		//uint16 width2 = (argc >= 6) ? argv[5].toUint16() : 0;
-		//uint16 height2 = (argc >= 7) ? argv[6].toUint16() : 0;
-		//uint16 transparentFlag = (argc >= 8) ? argv[7].toUint16() : 0;
-
-		// TODO: skip, width2, height2, transparentFlag
-		// (used for transparent bitmaps)
-		int entrySize = width * height + BITMAP_HEADER_SIZE;
-		reg_t memoryId = s->_segMan->allocateHunkEntry("Bitmap()", entrySize);
-		byte *memoryPtr = s->_segMan->getHunkPointer(memoryId);
-		memset(memoryPtr, 0, BITMAP_HEADER_SIZE);	// zero out the bitmap header
-		memset(memoryPtr + BITMAP_HEADER_SIZE, back, width * height);
-		// Save totalWidth, totalHeight
-		// TODO: Save the whole bitmap header, like SSCI does
-		WRITE_LE_UINT16(memoryPtr, width);
-		WRITE_LE_UINT16(memoryPtr + 2, height);
-		return memoryId;
-		}
-		break;
-	case 1:	// dispose text bitmap surface
-		return kDisposeTextBitmap(s, argc - 1, argv + 1);
-	case 2:	// dispose bitmap surface, with extra param
-		// 2 params, called e.g. from MenuItem::dispose in Torin's Passage,
-		// script 64893
-		warning("kBitmap(2), unk1 %d, bitmap ptr %04x:%04x", argv[1].toUint16(), PRINT_REG(argv[2]));
-		break;
-	case 3:	// tiled surface
-		{
-		// 6 params, called e.g. from TiledBitmap::resize() in Torin's Passage,
-		// script 64869
-		reg_t hunkId = argv[1];	// obtained from kBitmap(0)
-		// The tiled view seems to always have 2 loops.
-		// These loops need to have 1 cel in loop 0 and 8 cels in loop 1.
-		uint16 viewNum = argv[2].toUint16();	// vTiles selector
-		uint16 loop = argv[3].toUint16();
-		uint16 cel = argv[4].toUint16();
-		uint16 x = argv[5].toUint16();
-		uint16 y = argv[6].toUint16();
-
-		byte *memoryPtr = s->_segMan->getHunkPointer(hunkId);
-		// Get totalWidth, totalHeight
-		uint16 totalWidth = READ_LE_UINT16(memoryPtr);
-		uint16 totalHeight = READ_LE_UINT16(memoryPtr + 2);
-		byte *bitmap = memoryPtr + BITMAP_HEADER_SIZE;
-
-		GfxView *view = g_sci->_gfxCache->getView(viewNum);
-		uint16 tileWidth = view->getWidth(loop, cel);
-		uint16 tileHeight = view->getHeight(loop, cel);
-		const byte *tileBitmap = view->getBitmap(loop, cel);
-		uint16 width = MIN<uint16>(totalWidth - x, tileWidth);
-		uint16 height = MIN<uint16>(totalHeight - y, tileHeight);
-
-		for (uint16 curY = 0; curY < height; curY++) {
-			for (uint16 curX = 0; curX < width; curX++) {
-				bitmap[(curY + y) * totalWidth + (curX + x)] = tileBitmap[curY * tileWidth + curX];
-			}
-		}
-
-		}
-		break;
-	case 4:	// add text to bitmap
-		{
-		// 13 params, called e.g. from TextButton::createBitmap() in Torin's Passage,
-		// script 64894
-		reg_t hunkId = argv[1];	// obtained from kBitmap(0)
-		Common::String text = s->_segMan->getString(argv[2]);
-		uint16 textX = argv[3].toUint16();
-		uint16 textY = argv[4].toUint16();
-		//reg_t unk5 = argv[5];
-		//reg_t unk6 = argv[6];
-		//reg_t unk7 = argv[7];	// skip?
-		//reg_t unk8 = argv[8];	// back?
-		//reg_t unk9 = argv[9];
-		uint16 fontId = argv[10].toUint16();
-		//uint16 mode = argv[11].toUint16();
-		uint16 dimmed = argv[12].toUint16();
-		//warning("kBitmap(4): bitmap ptr %04x:%04x, font %d, mode %d, dimmed %d - text: \"%s\"",
-		//		PRINT_REG(bitmapPtr), font, mode, dimmed, text.c_str());
-		uint16 foreColor = 255;	// TODO
-
-		byte *memoryPtr = s->_segMan->getHunkPointer(hunkId);
-		// Get totalWidth, totalHeight
-		uint16 totalWidth = READ_LE_UINT16(memoryPtr);
-		uint16 totalHeight = READ_LE_UINT16(memoryPtr + 2);
-		byte *bitmap = memoryPtr + BITMAP_HEADER_SIZE;
-
-		GfxFont *font = g_sci->_gfxCache->getFont(fontId);
-
-		int16 charCount = 0;
-		uint16 curX = textX, curY = textY;
-		const char *txt = text.c_str();
-
-		while (*txt) {
-			charCount = g_sci->_gfxText32->GetLongest(txt, totalWidth, font);
-			if (charCount == 0)
-				break;
-
-			for (int i = 0; i < charCount; i++) {
-				unsigned char curChar = txt[i];
-				font->drawToBuffer(curChar, curY, curX, foreColor, dimmed, bitmap, totalWidth, totalHeight);
-				curX += font->getCharWidth(curChar);
-			}
-
-			curX = textX;
-			curY += font->getHeight();
-			txt += charCount;
-			while (*txt == ' ')
-				txt++; // skip over breaking spaces
-		}
-
-		}
-		break;
-	case 5:	// fill with color
-		{
-		// 6 params, called e.g. from TextView::init() and TextView::draw()
-		// in Torin's Passage, script 64890
-		reg_t hunkId = argv[1];	// obtained from kBitmap(0)
-		uint16 x = argv[2].toUint16();
-		uint16 y = argv[3].toUint16();
-		uint16 fillWidth = argv[4].toUint16();	// width - 1
-		uint16 fillHeight = argv[5].toUint16();	// height - 1
-		uint16 back = argv[6].toUint16();
-
-		byte *memoryPtr = s->_segMan->getHunkPointer(hunkId);
-		// Get totalWidth, totalHeight
-		uint16 totalWidth = READ_LE_UINT16(memoryPtr);
-		uint16 totalHeight = READ_LE_UINT16(memoryPtr + 2);
-		uint16 width = MIN<uint16>(totalWidth - x, fillWidth);
-		uint16 height = MIN<uint16>(totalHeight - y, fillHeight);
-		byte *bitmap = memoryPtr + BITMAP_HEADER_SIZE;
-
-		for (uint16 curY = 0; curY < height; curY++) {
-			for (uint16 curX = 0; curX < width; curX++) {
-				bitmap[(curY + y) * totalWidth + (curX + x)] = back;
-			}
-		}
-
-		}
-		break;
-	default:
-		kStub(s, argc, argv);
-		break;
-	}
-
-	return s->r_acc;
-}
-
-// Used for edit boxes in save/load dialogs. It's a rewritten version of kEditControl,
-// but it handles events on its own, using an internal loop, instead of using SCI
-// scripts for event management like kEditControl does. Called by script 64914,
-// DEdit::hilite().
-reg_t kEditText(EngineState *s, int argc, reg_t *argv) {
-	reg_t controlObject = argv[0];
-
-	if (!controlObject.isNull()) {
-		g_sci->_gfxControls32->kernelTexteditChange(controlObject);
-	}
-
-	return s->r_acc;
-}
-
-#endif
-
 } // End of namespace Sci
diff --git a/engines/sci/engine/kgraphics32.cpp b/engines/sci/engine/kgraphics32.cpp
new file mode 100644
index 0000000..178c5d6
--- /dev/null
+++ b/engines/sci/engine/kgraphics32.cpp
@@ -0,0 +1,679 @@
+/* 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.
+
+ * 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.
+
+ * 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"
+
+#include "engines/util.h"
+#include "graphics/cursorman.h"
+#include "graphics/surface.h"
+#include "graphics/palette.h"	// temporary, for the fadeIn()/fadeOut() functions below
+
+#include "gui/message.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/cursor.h"
+#include "sci/graphics/palette.h"
+#include "sci/graphics/paint16.h"
+#include "sci/graphics/picture.h"
+#include "sci/graphics/ports.h"
+#include "sci/graphics/screen.h"
+#include "sci/graphics/text16.h"
+#include "sci/graphics/view.h"
+#ifdef ENABLE_SCI32
+#include "sci/graphics/controls32.h"
+#include "sci/graphics/font.h"	// TODO: remove once kBitmap is moved in a separate class
+#include "sci/graphics/text32.h"
+#include "sci/graphics/frameout.h"
+#endif
+
+namespace Sci {
+#ifdef ENABLE_SCI32
+
+extern void showScummVMDialog(const Common::String &message);
+
+reg_t kIsHiRes(EngineState *s, int argc, reg_t *argv) {
+	// Returns 0 if the screen width or height is less than 640 or 400,
+	// respectively.
+	if (g_system->getWidth() < 640 || g_system->getHeight() < 400)
+		return make_reg(0, 0);
+
+	return make_reg(0, 1);
+}
+
+// SCI32 variant, can't work like sci16 variants
+reg_t kCantBeHere32(EngineState *s, int argc, reg_t *argv) {
+	// TODO
+//	reg_t curObject = argv[0];
+//	reg_t listReference = (argc > 1) ? argv[1] : NULL_REG;
+
+	return NULL_REG;
+}
+
+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;
+}
+
+reg_t kUpdateScreenItem(EngineState *s, int argc, reg_t *argv) {
+	g_sci->_gfxFrameout->kernelUpdateScreenItem(argv[0]);
+	return s->r_acc;
+}
+
+reg_t kDeleteScreenItem(EngineState *s, int argc, reg_t *argv) {
+	g_sci->_gfxFrameout->kernelDeleteScreenItem(argv[0]);
+	return s->r_acc;
+}
+
+reg_t kAddPlane(EngineState *s, int argc, reg_t *argv) {
+	g_sci->_gfxFrameout->kernelAddPlane(argv[0]);
+	return s->r_acc;
+}
+
+reg_t kDeletePlane(EngineState *s, int argc, reg_t *argv) {
+	g_sci->_gfxFrameout->kernelDeletePlane(argv[0]);
+	return s->r_acc;
+}
+
+reg_t kUpdatePlane(EngineState *s, int argc, reg_t *argv) {
+	g_sci->_gfxFrameout->kernelUpdatePlane(argv[0]);
+	return s->r_acc;
+}
+
+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();
+
+	g_sci->_gfxFrameout->kernelAddPicAt(planeObj, pictureId, pictureX, pictureY);
+	return s->r_acc;
+}
+
+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) {
+	g_sci->_gfxFrameout->kernelFrameout();
+	return NULL_REG;
+}
+
+reg_t kObjectIntersect(EngineState *s, int argc, reg_t *argv) {
+	Common::Rect objRect1 = g_sci->_gfxCompare->getNSRect(argv[0]);
+	Common::Rect objRect2 = g_sci->_gfxCompare->getNSRect(argv[1]);
+	return make_reg(0, objRect1.intersects(objRect2));
+}
+
+// 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];
+	uint16 illegalBits = argv[3].offset;
+	Common::Rect nsRect = g_sci->_gfxCompare->getNSRect(targetObject, true);
+
+	// we assume that x, y are local coordinates
+
+	bool contained = nsRect.contains(x, y);
+	if (contained && illegalBits) {
+		// If illegalbits are set, we check the color of the pixel that got clicked on
+		//  for now, we return false if the pixel is transparent
+		//  although illegalBits may get differently set, don't know yet how this really works out
+		uint16 viewId = readSelectorValue(s->_segMan, targetObject, SELECTOR(view));
+		int16 loopNo = readSelectorValue(s->_segMan, targetObject, SELECTOR(loop));
+		int16 celNo = readSelectorValue(s->_segMan, targetObject, SELECTOR(cel));
+		if (g_sci->_gfxCompare->kernelIsItSkip(viewId, loopNo, celNo, Common::Point(x - nsRect.left, y - nsRect.top)))
+			contained = false;
+	}
+	return make_reg(0, contained);
+}
+
+reg_t kCreateTextBitmap(EngineState *s, int argc, reg_t *argv) {
+	switch (argv[0].toUint16()) {
+	case 0: {
+		if (argc != 4) {
+			warning("kCreateTextBitmap(0): expected 4 arguments, got %i", argc);
+			return NULL_REG;
+		}
+		reg_t object = argv[3];
+		Common::String text = s->_segMan->getString(readSelector(s->_segMan, object, SELECTOR(text)));
+		debugC(kDebugLevelStrings, "kCreateTextBitmap case 0 (%04x:%04x, %04x:%04x, %04x:%04x)",
+				PRINT_REG(argv[1]), PRINT_REG(argv[2]), PRINT_REG(argv[3]));
+		debugC(kDebugLevelStrings, "%s", text.c_str());
+		uint16 maxWidth = argv[1].toUint16();	// nsRight - nsLeft + 1
+		uint16 maxHeight = argv[2].toUint16();	// nsBottom - nsTop + 1
+		return g_sci->_gfxText32->createTextBitmap(object, maxWidth, maxHeight);
+	}
+	case 1: {
+		if (argc != 2) {
+			warning("kCreateTextBitmap(1): expected 2 arguments, got %i", argc);
+			return NULL_REG;
+		}
+		reg_t object = argv[1];
+		Common::String text = s->_segMan->getString(readSelector(s->_segMan, object, SELECTOR(text)));
+		debugC(kDebugLevelStrings, "kCreateTextBitmap case 1 (%04x:%04x)", PRINT_REG(argv[1]));
+		debugC(kDebugLevelStrings, "%s", text.c_str());
+		return g_sci->_gfxText32->createTextBitmap(object);
+	}
+	default:
+		warning("CreateTextBitmap(%d)", argv[0].toUint16());
+		return NULL_REG;
+	}
+}
+
+reg_t kDisposeTextBitmap(EngineState *s, int argc, reg_t *argv) {
+	g_sci->_gfxText32->disposeTextBitmap(argv[0]);
+	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;
+}
+
+// Taken from the SCI16 GfxTransitions class
+static void fadeOut() {
+	byte oldPalette[3 * 256], workPalette[3 * 256];
+	int16 stepNr, colorNr;
+	// Sierra did not fade in/out color 255 for sci1.1, but they used it in
+	//  several pictures (e.g. qfg3 demo/intro), so the fading looked weird
+	int16 tillColorNr = getSciVersion() >= SCI_VERSION_1_1 ? 255 : 254;
+
+	g_system->getPaletteManager()->grabPalette(oldPalette, 0, 256);
+
+	for (stepNr = 100; stepNr >= 0; stepNr -= 10) {
+		for (colorNr = 1; colorNr <= tillColorNr; colorNr++) {
+			if (g_sci->_gfxPalette->colorIsFromMacClut(colorNr)) {
+				workPalette[colorNr * 3 + 0] = oldPalette[colorNr * 3];
+				workPalette[colorNr * 3 + 1] = oldPalette[colorNr * 3 + 1];
+				workPalette[colorNr * 3 + 2] = oldPalette[colorNr * 3 + 2];
+			} else {
+				workPalette[colorNr * 3 + 0] = oldPalette[colorNr * 3] * stepNr / 100;
+				workPalette[colorNr * 3 + 1] = oldPalette[colorNr * 3 + 1] * stepNr / 100;
+				workPalette[colorNr * 3 + 2] = oldPalette[colorNr * 3 + 2] * stepNr / 100;
+			}
+		}
+		g_system->getPaletteManager()->setPalette(workPalette + 3, 1, tillColorNr);
+		g_sci->getEngineState()->wait(2);
+	}
+}
+
+// Taken from the SCI16 GfxTransitions class
+static void fadeIn() {
+	int16 stepNr;
+	// Sierra did not fade in/out color 255 for sci1.1, but they used it in
+	//  several pictures (e.g. qfg3 demo/intro), so the fading looked weird
+	int16 tillColorNr = getSciVersion() >= SCI_VERSION_1_1 ? 255 : 254;
+
+	for (stepNr = 0; stepNr <= 100; stepNr += 10) {
+		g_sci->_gfxPalette->kernelSetIntensity(1, tillColorNr + 1, stepNr, true);
+		g_sci->getEngineState()->wait(2);
+	}
+}
+
+/**
+ * Used for scene transitions, replacing (but reusing parts of) the old
+ * transition code.
+ */
+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
+	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
+	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?)
+	}
+
+	if (showStyle > 15) {
+		warning("kSetShowStyle: Illegal style %d for plane %04x:%04x", showStyle, PRINT_REG(planeObj));
+		return s->r_acc;
+	}
+
+	// TODO: Proper implementation. This is a very basic version. I'm not even
+	// sure if the rest of the styles will work with this mechanism.
+
+	// Check if the passed parameters are the ones we expect
+	if (showStyle == 13 || showStyle == 14) {	// fade out / fade in
+		if (seconds != 1)
+			warning("kSetShowStyle(fade): seconds isn't 1, it's %d", seconds);
+		if (backColor != 0 && backColor != 0xFFFF)
+			warning("kSetShowStyle(fade): backColor isn't 0 or 0xFFFF, it's %d", backColor);
+		if (priority != 200)
+			warning("kSetShowStyle(fade): priority isn't 200, it's %d", priority);
+		if (animate != 0)
+			warning("kSetShowStyle(fade): animate isn't 0, it's %d", animate);
+		if (refFrame != 0)
+			warning("kSetShowStyle(fade): refFrame isn't 0, it's %d", refFrame);
+		if (divisions >= 0 && divisions != 20)
+			warning("kSetShowStyle(fade): divisions isn't 20, it's %d", divisions);
+	}
+
+	// TODO: Check if the plane is in the list of planes to draw
+
+	switch (showStyle) {
+	//case 0:	// no transition, perhaps? (like in the previous SCI versions)
+	case 13:	// fade out
+		// TODO: Temporary implementation, which ignores all additional parameters
+		fadeOut();
+		break;
+	case 14:	// fade in
+		// TODO: Temporary implementation, which ignores all additional parameters
+		g_sci->_gfxFrameout->kernelFrameout();	// draw new scene before fading in
+		fadeIn();
+		break;
+	default:
+		// TODO: This is all a stub/skeleton, thus we're invoking kStub() for now
+		kStub(s, argc, argv);
+		break;
+	}
+
+	return s->r_acc;
+}
+
+reg_t kCelInfo(EngineState *s, int argc, reg_t *argv) {
+	// Used by Shivers 1, room 23601 to determine what blocks on the red door puzzle board
+	// are occupied by pieces already
+
+	switch (argv[0].toUint16()) {	// subops 0 - 4
+		// 0 - return the view
+		// 1 - return the loop
+		// 2, 3 - nop
+		case 4: {
+			GuiResourceId viewId = argv[1].toSint16();
+			int16 loopNo = argv[2].toSint16();
+			int16 celNo = argv[3].toSint16();
+			int16 x = argv[4].toUint16();
+			int16 y = argv[5].toUint16();
+			byte color = g_sci->_gfxCache->kernelViewGetColorAtCoordinate(viewId, loopNo, celNo, x, y);
+			return make_reg(0, color);
+		}
+		default: {
+			kStub(s, argc, argv);
+			return s->r_acc;
+		}
+	}
+}
+
+reg_t kScrollWindow(EngineState *s, int argc, reg_t *argv) {
+	// Used by Phantasmagoria 1 and SQ6. In SQ6, it is used for the messages
+	// shown in the scroll window at the bottom of the screen.
+
+	// TODO: This is all a stub/skeleton, thus we're invoking kStub() for now
+	kStub(s, argc, argv);
+
+	switch (argv[0].toUint16()) {
+	case 0:	// Init
+		// 2 parameters
+		// argv[1] points to the scroll object (e.g. textScroller in SQ6)
+		// argv[2] is an integer (e.g. 0x32)
+		break;
+	case 1: // Show message
+		// 5 or 6 parameters
+		// Seems to be called with 5 parameters when the narrator speaks, and
+		// with 6 when Roger speaks
+		// argv[1] unknown (usually 0)
+		// argv[2] the text to show
+		// argv[3] a small integer (e.g. 0x32)
+		// argv[4] a small integer (e.g. 0x54)
+		// argv[5] optional, unknown (usually 0)
+		warning("kScrollWindow: '%s'", s->_segMan->getString(argv[2]).c_str());
+		break;
+	case 2: // Clear
+		// 2 parameters
+		// TODO
+		break;
+	case 3: // Page up
+		// 2 parameters
+		// TODO
+		break;
+	case 4: // Page down
+		// 2 parameters
+		// TODO
+		break;
+	case 5: // Up arrow
+		// 2 parameters
+		// TODO
+		break;
+	case 6: // Down arrow
+		// 2 parameters
+		// TODO
+		break;
+	case 7: // Home
+		// 2 parameters
+		// TODO
+		break;
+	case 8: // End
+		// 2 parameters
+		// TODO
+		break;
+	case 9: // Resize
+		// 3 parameters
+		// TODO
+		break;
+	case 10: // Where
+		// 3 parameters
+		// TODO
+		break;
+	case 11: // Go
+		// 4 parameters
+		// TODO
+		break;
+	case 12: // Insert
+		// 7 parameters
+		// TODO
+		break;
+	case 13: // Delete
+		// 3 parameters
+		// TODO
+		break;
+	case 14: // Modify
+		// 7 or 8 parameters
+		// TODO
+		break;
+	case 15: // Hide
+		// 2 parameters
+		// TODO
+		break;
+	case 16: // Show
+		// 2 parameters
+		// TODO
+		break;
+	case 17: // Destroy
+		// 2 parameters
+		// TODO
+		break;
+	case 18: // Text
+		// 2 parameters
+		// TODO
+		break;
+	case 19: // Reconstruct
+		// 3 parameters
+		// TODO
+		break;
+	default:
+		error("kScrollWindow: unknown subop %d", argv[0].toUint16());
+		break;
+	}
+
+	return s->r_acc;
+}
+
+reg_t kSetFontRes(EngineState *s, int argc, reg_t *argv) {
+	// TODO: This defines the resolution that the fonts are supposed to be displayed
+	// in. Currently, this is only used for showing high-res fonts in GK1 Mac, but
+	// should be extended to handle other font resolutions such as those
+
+	int xResolution = argv[0].toUint16();
+	//int yResolution = argv[1].toUint16();
+
+	g_sci->_gfxScreen->setFontIsUpscaled(xResolution == 640 &&
+			g_sci->_gfxScreen->getUpscaledHires() != GFX_SCREEN_UPSCALED_DISABLED);
+
+	return s->r_acc;
+}
+
+reg_t kFont(EngineState *s, int argc, reg_t *argv) {
+	// Handle font settings for SCI2.1
+
+	switch (argv[0].toUint16()) {
+	case 1:
+		// Set font resolution
+		return kSetFontRes(s, argc - 1, argv + 1);
+	default:
+		warning("kFont: unknown subop %d", argv[0].toUint16());
+	}
+
+	return s->r_acc;
+}
+
+// TODO: Eventually, all of the kBitmap operations should be put
+// in a separate class
+
+#define BITMAP_HEADER_SIZE 46
+
+reg_t kBitmap(EngineState *s, int argc, reg_t *argv) {
+	// Used for bitmap operations in SCI2.1 and SCI3.
+	// This is the SCI2.1 version, the functionality seems to have changed in SCI3.
+
+	switch (argv[0].toUint16()) {
+	case 0:	// init bitmap surface
+		{
+		// 6 params, called e.g. from TextView::init() in Torin's Passage,
+		// script 64890 and TransView::init() in script 64884
+		uint16 width = argv[1].toUint16();
+		uint16 height = argv[2].toUint16();
+		//uint16 skip = argv[3].toUint16();
+		uint16 back = argv[4].toUint16();	// usually equals skip
+		//uint16 width2 = (argc >= 6) ? argv[5].toUint16() : 0;
+		//uint16 height2 = (argc >= 7) ? argv[6].toUint16() : 0;
+		//uint16 transparentFlag = (argc >= 8) ? argv[7].toUint16() : 0;
+
+		// TODO: skip, width2, height2, transparentFlag
+		// (used for transparent bitmaps)
+		int entrySize = width * height + BITMAP_HEADER_SIZE;
+		reg_t memoryId = s->_segMan->allocateHunkEntry("Bitmap()", entrySize);
+		byte *memoryPtr = s->_segMan->getHunkPointer(memoryId);
+		memset(memoryPtr, 0, BITMAP_HEADER_SIZE);	// zero out the bitmap header
+		memset(memoryPtr + BITMAP_HEADER_SIZE, back, width * height);
+		// Save totalWidth, totalHeight
+		// TODO: Save the whole bitmap header, like SSCI does
+		WRITE_LE_UINT16(memoryPtr, width);
+		WRITE_LE_UINT16(memoryPtr + 2, height);
+		return memoryId;
+		}
+		break;
+	case 1:	// dispose text bitmap surface
+		return kDisposeTextBitmap(s, argc - 1, argv + 1);
+	case 2:	// dispose bitmap surface, with extra param
+		// 2 params, called e.g. from MenuItem::dispose in Torin's Passage,
+		// script 64893
+		warning("kBitmap(2), unk1 %d, bitmap ptr %04x:%04x", argv[1].toUint16(), PRINT_REG(argv[2]));
+		break;
+	case 3:	// tiled surface
+		{
+		// 6 params, called e.g. from TiledBitmap::resize() in Torin's Passage,
+		// script 64869
+		reg_t hunkId = argv[1];	// obtained from kBitmap(0)
+		// The tiled view seems to always have 2 loops.
+		// These loops need to have 1 cel in loop 0 and 8 cels in loop 1.
+		uint16 viewNum = argv[2].toUint16();	// vTiles selector
+		uint16 loop = argv[3].toUint16();
+		uint16 cel = argv[4].toUint16();
+		uint16 x = argv[5].toUint16();
+		uint16 y = argv[6].toUint16();
+
+		byte *memoryPtr = s->_segMan->getHunkPointer(hunkId);
+		// Get totalWidth, totalHeight
+		uint16 totalWidth = READ_LE_UINT16(memoryPtr);
+		uint16 totalHeight = READ_LE_UINT16(memoryPtr + 2);
+		byte *bitmap = memoryPtr + BITMAP_HEADER_SIZE;
+
+		GfxView *view = g_sci->_gfxCache->getView(viewNum);
+		uint16 tileWidth = view->getWidth(loop, cel);
+		uint16 tileHeight = view->getHeight(loop, cel);
+		const byte *tileBitmap = view->getBitmap(loop, cel);
+		uint16 width = MIN<uint16>(totalWidth - x, tileWidth);
+		uint16 height = MIN<uint16>(totalHeight - y, tileHeight);
+
+		for (uint16 curY = 0; curY < height; curY++) {
+			for (uint16 curX = 0; curX < width; curX++) {
+				bitmap[(curY + y) * totalWidth + (curX + x)] = tileBitmap[curY * tileWidth + curX];
+			}
+		}
+
+		}
+		break;
+	case 4:	// add text to bitmap
+		{
+		// 13 params, called e.g. from TextButton::createBitmap() in Torin's Passage,
+		// script 64894
+		reg_t hunkId = argv[1];	// obtained from kBitmap(0)
+		Common::String text = s->_segMan->getString(argv[2]);
+		uint16 textX = argv[3].toUint16();
+		uint16 textY = argv[4].toUint16();
+		//reg_t unk5 = argv[5];
+		//reg_t unk6 = argv[6];
+		//reg_t unk7 = argv[7];	// skip?
+		//reg_t unk8 = argv[8];	// back?
+		//reg_t unk9 = argv[9];
+		uint16 fontId = argv[10].toUint16();
+		//uint16 mode = argv[11].toUint16();
+		uint16 dimmed = argv[12].toUint16();
+		//warning("kBitmap(4): bitmap ptr %04x:%04x, font %d, mode %d, dimmed %d - text: \"%s\"",
+		//		PRINT_REG(bitmapPtr), font, mode, dimmed, text.c_str());
+		uint16 foreColor = 255;	// TODO
+
+		byte *memoryPtr = s->_segMan->getHunkPointer(hunkId);
+		// Get totalWidth, totalHeight
+		uint16 totalWidth = READ_LE_UINT16(memoryPtr);
+		uint16 totalHeight = READ_LE_UINT16(memoryPtr + 2);
+		byte *bitmap = memoryPtr + BITMAP_HEADER_SIZE;
+
+		GfxFont *font = g_sci->_gfxCache->getFont(fontId);
+
+		int16 charCount = 0;
+		uint16 curX = textX, curY = textY;
+		const char *txt = text.c_str();
+
+		while (*txt) {
+			charCount = g_sci->_gfxText32->GetLongest(txt, totalWidth, font);
+			if (charCount == 0)
+				break;
+
+			for (int i = 0; i < charCount; i++) {
+				unsigned char curChar = txt[i];
+				font->drawToBuffer(curChar, curY, curX, foreColor, dimmed, bitmap, totalWidth, totalHeight);
+				curX += font->getCharWidth(curChar);
+			}
+
+			curX = textX;
+			curY += font->getHeight();
+			txt += charCount;
+			while (*txt == ' ')
+				txt++; // skip over breaking spaces
+		}
+
+		}
+		break;
+	case 5:	// fill with color
+		{
+		// 6 params, called e.g. from TextView::init() and TextView::draw()
+		// in Torin's Passage, script 64890
+		reg_t hunkId = argv[1];	// obtained from kBitmap(0)
+		uint16 x = argv[2].toUint16();
+		uint16 y = argv[3].toUint16();
+		uint16 fillWidth = argv[4].toUint16();	// width - 1
+		uint16 fillHeight = argv[5].toUint16();	// height - 1
+		uint16 back = argv[6].toUint16();
+
+		byte *memoryPtr = s->_segMan->getHunkPointer(hunkId);
+		// Get totalWidth, totalHeight
+		uint16 totalWidth = READ_LE_UINT16(memoryPtr);
+		uint16 totalHeight = READ_LE_UINT16(memoryPtr + 2);
+		uint16 width = MIN<uint16>(totalWidth - x, fillWidth);
+		uint16 height = MIN<uint16>(totalHeight - y, fillHeight);
+		byte *bitmap = memoryPtr + BITMAP_HEADER_SIZE;
+
+		for (uint16 curY = 0; curY < height; curY++) {
+			for (uint16 curX = 0; curX < width; curX++) {
+				bitmap[(curY + y) * totalWidth + (curX + x)] = back;
+			}
+		}
+
+		}
+		break;
+	default:
+		kStub(s, argc, argv);
+		break;
+	}
+
+	return s->r_acc;
+}
+
+// Used for edit boxes in save/load dialogs. It's a rewritten version of kEditControl,
+// but it handles events on its own, using an internal loop, instead of using SCI
+// scripts for event management like kEditControl does. Called by script 64914,
+// DEdit::hilite().
+reg_t kEditText(EngineState *s, int argc, reg_t *argv) {
+	reg_t controlObject = argv[0];
+
+	if (!controlObject.isNull()) {
+		g_sci->_gfxControls32->kernelTexteditChange(controlObject);
+	}
+
+	return s->r_acc;
+}
+
+#endif
+
+} // End of namespace Sci
diff --git a/engines/sci/module.mk b/engines/sci/module.mk
index 90a0f33..2842e47 100644
--- a/engines/sci/module.mk
+++ b/engines/sci/module.mk
@@ -81,6 +81,7 @@ ifdef ENABLE_SCI32
 MODULE_OBJS += \
 	graphics/controls32.o \
 	graphics/frameout.o \
+	engine/kgraphics32.o \
 	graphics/paint32.o \
 	graphics/text32.o \
 	video/robot_decoder.o


Commit: 8c1ca6548d9dd656f093f7b7962612715c0bf5e9
    https://github.com/scummvm/scummvm/commit/8c1ca6548d9dd656f093f7b7962612715c0bf5e9
Author: Filippos Karapetis (md5 at scummvm.org)
Date: 2012-05-20T10:16:16-07:00

Commit Message:
SAGA: Fix bug #3528338 - "ITE: Subtitles always shown in introduction"

Changed paths:
    engines/saga/introproc_ite.cpp



diff --git a/engines/saga/introproc_ite.cpp b/engines/saga/introproc_ite.cpp
index 9248f2b..484ebe1 100644
--- a/engines/saga/introproc_ite.cpp
+++ b/engines/saga/introproc_ite.cpp
@@ -126,21 +126,25 @@ EventColumns *Scene::ITEQueueDialogue(EventColumns *eventColumns, int n_dialogue
 		textEntry.text = dialogue[i].i_str;
 		entry = _vm->_scene->_textList.addEntry(textEntry);
 
-		// Display text
-		event.type = kEvTOneshot;
-		event.code = kTextEvent;
-		event.op = kEventDisplay;
-		event.data = entry;
-		event.time = (i == 0) ? 0 : VOICE_PAD;
-		eventColumns = _vm->_events->chain(eventColumns, event);
+		if (_vm->_subtitlesEnabled) {
+			// Display text
+			event.type = kEvTOneshot;
+			event.code = kTextEvent;
+			event.op = kEventDisplay;
+			event.data = entry;
+			event.time = (i == 0) ? 0 : VOICE_PAD;
+			eventColumns = _vm->_events->chain(eventColumns, event);
+		}
 
-		// Play voice
-		event.type = kEvTOneshot;
-		event.code = kVoiceEvent;
-		event.op = kEventPlay;
-		event.param = dialogue[i].i_voice_rn;
-		event.time = 0;
-		_vm->_events->chain(eventColumns, event);
+		if (_vm->_voicesEnabled) {
+			// Play voice
+			event.type = kEvTOneshot;
+			event.code = kVoiceEvent;
+			event.op = kEventPlay;
+			event.param = dialogue[i].i_voice_rn;
+			event.time = 0;
+			_vm->_events->chain(eventColumns, event);
+		}
 
 		voice_len = _vm->_sndRes->getVoiceLength(dialogue[i].i_voice_rn);
 		if (voice_len < 0) {






More information about the Scummvm-git-logs mailing list