diff options
Diffstat (limited to 'engines/sci')
44 files changed, 228 insertions, 138 deletions
diff --git a/engines/sci/console.cpp b/engines/sci/console.cpp index 7c351c6220..419f5e1415 100644 --- a/engines/sci/console.cpp +++ b/engines/sci/console.cpp @@ -442,7 +442,7 @@ ResourceType parseResourceType(const char *resid) { } bool Console::cmdGetVersion(int argc, const char **argv) { - const char *viewTypeDesc[] = { "Unknown", "EGA", "VGA", "VGA SCI1.1", "Amiga" }; + const char *viewTypeDesc[] = { "Unknown", "EGA", "Amiga ECS 32 colors", "Amiga AGA 64 colors", "VGA", "VGA SCI1.1" }; bool hasVocab997 = g_sci->getResMan()->testResource(ResourceId(kResourceTypeVocab, VOCAB_RESOURCE_SELECTORS)) ? true : false; Common::String gameVersion = "N/A"; @@ -1532,7 +1532,7 @@ bool Console::cmdUndither(int argc, const char **argv) { } bool flag = atoi(argv[1]) ? true : false; - _engine->_gfxScreen->debugUnditherSetState(flag); + _engine->_gfxScreen->enableUndithering(flag); if (flag) DebugPrintf("undithering ENABLED\n"); else diff --git a/engines/sci/decompressor.cpp b/engines/sci/decompressor.cpp index 73d4ed4198..c122fceeb0 100644 --- a/engines/sci/decompressor.cpp +++ b/engines/sci/decompressor.cpp @@ -28,9 +28,8 @@ #include "common/dcl.h" #include "common/util.h" #include "common/endian.h" -#include "common/debug.h" -#include "common/debug-channels.h" #include "common/stream.h" +#include "common/textconsole.h" #include "sci/decompressor.h" #include "sci/sci.h" diff --git a/engines/sci/decompressor.h b/engines/sci/decompressor.h index 88e24fcc47..8b6f955ddb 100644 --- a/engines/sci/decompressor.h +++ b/engines/sci/decompressor.h @@ -28,7 +28,9 @@ #include "common/scummsys.h" -namespace Common { class ReadStream; } +namespace Common { +class ReadStream; +} namespace Sci { diff --git a/engines/sci/engine/kfile.cpp b/engines/sci/engine/kfile.cpp index 82522a6e77..0e2f64257a 100644 --- a/engines/sci/engine/kfile.cpp +++ b/engines/sci/engine/kfile.cpp @@ -28,6 +28,7 @@ #include "common/file.h" #include "common/str.h" #include "common/savefile.h" +#include "common/system.h" #include "common/translation.h" #include "gui/saveload.h" diff --git a/engines/sci/engine/kmisc.cpp b/engines/sci/engine/kmisc.cpp index 907e0ba2e4..80425224bf 100644 --- a/engines/sci/engine/kmisc.cpp +++ b/engines/sci/engine/kmisc.cpp @@ -411,7 +411,8 @@ reg_t kMacPlatform(EngineState *s, int argc, reg_t *argv) { return kIconBar(s, argc - 1, argv + 1); case 7: // Unknown, but always return -1 return SIGNAL_REG; - case 1: // Unknown, calls QuickDraw region functions (KQ5, QFG1VGA) + case 1: // Unknown, calls QuickDraw region functions (KQ5, QFG1VGA, Dr. Brain 1) + break; // removed warning, as it produces a lot of spam in the console case 2: // Unknown, "UseNextWaitEvent" (Various) case 3: // Unknown, "ProcessOpenDocuments" (Various) case 5: // Unknown, plays a sound (KQ7) diff --git a/engines/sci/engine/kmovement.cpp b/engines/sci/engine/kmovement.cpp index f93a6716b9..f4392df8f2 100644 --- a/engines/sci/engine/kmovement.cpp +++ b/engines/sci/engine/kmovement.cpp @@ -128,7 +128,7 @@ reg_t kSetJump(EngineState *s, int argc, reg_t *argv) { debugC(kDebugLevelBresen, "c: %d, tmp: %d", c, tmp); // Compute x step - if (tmp != 0) + if (tmp != 0 && dx != 0) vx = (int16)((float)(dx * sqrt(gy / (2.0 * tmp)))); else vx = 0; diff --git a/engines/sci/engine/ksound.cpp b/engines/sci/engine/ksound.cpp index 911713d0bd..7fb6ac296e 100644 --- a/engines/sci/engine/ksound.cpp +++ b/engines/sci/engine/ksound.cpp @@ -32,6 +32,7 @@ #include "sci/sound/soundcmd.h" #include "audio/mixer.h" +#include "common/system.h" namespace Sci { diff --git a/engines/sci/engine/kstring.cpp b/engines/sci/engine/kstring.cpp index d9bb1c3531..e79af70158 100644 --- a/engines/sci/engine/kstring.cpp +++ b/engines/sci/engine/kstring.cpp @@ -175,7 +175,7 @@ reg_t kReadNumber(EngineState *s, int argc, reg_t *argv) { #define ALIGN_NONE 0 #define ALIGN_RIGHT 1 #define ALIGN_LEFT -1 -#define ALIGN_CENTRE 2 +#define ALIGN_CENTER 2 /* Format(targ_address, textresnr, index_inside_res, ...) ** or @@ -246,7 +246,7 @@ reg_t kFormat(EngineState *s, int argc, reg_t *argv) { if (xfer == '0') fillchar = '0'; else if (xfer == '=') - align = ALIGN_CENTRE; + align = ALIGN_CENTER; else if (isdigit(xfer) || (xfer == '-')) source--; // Go to start of length argument @@ -258,7 +258,7 @@ reg_t kFormat(EngineState *s, int argc, reg_t *argv) { if (str_leng < 0) { align = ALIGN_LEFT; str_leng = -str_leng; - } else if (align != ALIGN_CENTRE) + } else if (align != ALIGN_CENTER) align = ALIGN_RIGHT; xfer = *source++; @@ -298,7 +298,7 @@ reg_t kFormat(EngineState *s, int argc, reg_t *argv) { *target++ = ' '; /* Format into the text */ break; - case ALIGN_CENTRE: { + case ALIGN_CENTER: { int half_extralen = extralen >> 1; while (half_extralen-- > 0) *target++ = ' '; /* Format into the text */ @@ -315,7 +315,7 @@ reg_t kFormat(EngineState *s, int argc, reg_t *argv) { switch (align) { - case ALIGN_CENTRE: { + case ALIGN_CENTER: { int half_extralen; align = 0; half_extralen = extralen - (extralen >> 1); diff --git a/engines/sci/engine/kvideo.cpp b/engines/sci/engine/kvideo.cpp index 6a411d8e23..a8d4437148 100644 --- a/engines/sci/engine/kvideo.cpp +++ b/engines/sci/engine/kvideo.cpp @@ -29,7 +29,14 @@ #include "sci/graphics/cursor.h" #include "sci/graphics/palette.h" #include "sci/graphics/screen.h" -#include "graphics/cursorman.h" +#include "common/events.h" +#include "common/keyboard.h" +#include "common/str.h" +#include "common/system.h" +#include "common/textconsole.h" +#include "graphics/pixelformat.h" +#include "graphics/surface.h" +#include "video/video_decoder.h" #include "video/avi_decoder.h" #include "video/qt_decoder.h" #include "sci/video/seq_decoder.h" diff --git a/engines/sci/engine/object.h b/engines/sci/engine/object.h index 81d5b2c983..8ae06f2707 100644 --- a/engines/sci/engine/object.h +++ b/engines/sci/engine/object.h @@ -28,6 +28,7 @@ #include "common/array.h" #include "common/serializer.h" +#include "common/textconsole.h" #include "sci/sci.h" // for the SCI versions #include "sci/engine/vm_types.h" // for reg_t diff --git a/engines/sci/engine/script.cpp b/engines/sci/engine/script.cpp index fb96518f19..25bf91c3ad 100644 --- a/engines/sci/engine/script.cpp +++ b/engines/sci/engine/script.cpp @@ -611,7 +611,7 @@ void Script::initialiseObjectsSci0(SegManager *segMan, SegmentId segmentId) { // #3150767. // Same happens with script 764, it seems to // contain junk towards its end. - _objects.erase(addr.toUint16() + (getSciVersion() < SCI_VERSION_1_1) ? 8 : 0); + _objects.erase(addr.toUint16() - SCRIPT_OBJECT_MAGIC_OFFSET); } else { error("Failed to locate base object for object at %04X:%04X", PRINT_REG(addr)); } diff --git a/engines/sci/engine/script_patches.cpp b/engines/sci/engine/script_patches.cpp index 54ae88a17e..06540e6f43 100644 --- a/engines/sci/engine/script_patches.cpp +++ b/engines/sci/engine/script_patches.cpp @@ -874,9 +874,50 @@ const uint16 qfg3PatchDialogCrash[] = { PATCH_END }; +// Part of script 47 that handles the barter icon checks for the wrong local. +// The local is supposed to contain the value returned by a previous kDisplay +// call, but since the wrong one is checked, it contains junk instead. We +// remove that check here (this doesn't affect the game at all). This occurs +// when attempting to purchase something from a vendor and the barter button is +// available (e.g. when buying the robe or meat from the associated vendors). +// Fixes bug #3292251. +const byte qfg3BarterCrash[] = { + 22, + 0x83, 0x10, // lal 10 ---> BUG! Wrong local + 0x30, 0x11, 0x00, // bnt 0011 ---> the accumulator will now contain garbage, so this check fails + 0x35, 0x00, // ldi 00 + 0xa5, 0x00, // sat 00 + 0x39, 0x03, // pushi 03 + 0x5b, 0x04, 0x00, // lea 04 00 + 0x36, // push + 0x39, 0x6c, // pushi 6c + 0x8b, 0x10, // lsl 10 ---> local 10 contains garbage, so the call below will fail + 0x43, 0x1b, 0x06 // callk Display[1b] 06 +}; + +// Same as above, but for local 0x11 +const byte qfg3BarterCrash2[] = { + 18, + 0x83, 0x11, // lal 11 ---> BUG! Wrong local + 0x30, 0x0d, 0x00, // bnt 000d ---> the accumulator will now contain garbage, so this check fails + 0x39, 0x03, // pushi 03 + 0x5b, 0x04, 0x00, // lea 04 00 + 0x36, // push + 0x39, 0x6c, // pushi 6c + 0x8b, 0x11, // lsl 11 ---> local 11 contains garbage, so the call below will fail + 0x43, 0x1b, 0x06 // callk Display[1b] 06 +}; + +const uint16 qfg3PatchBarterCrash[] = { + 0x35, 0x00, // ldi 00 ---> the accumulator will always be zero, so the problematic code won't run + PATCH_END +}; + // script, description, magic DWORD, adjust const SciScriptSignature qfg3Signatures[] = { { 23, "dialog crash", 1, PATCH_MAGICDWORD(0xe7, 0x03, 0x22, 0x33), -1, qfg3DialogCrash, qfg3PatchDialogCrash }, + { 47, "barter crash", 1, PATCH_MAGICDWORD(0x83, 0x10, 0x30, 0x11), 0, qfg3BarterCrash, qfg3PatchBarterCrash }, + { 47, "barter crash 2", 1, PATCH_MAGICDWORD(0x83, 0x11, 0x30, 0x0d), 0, qfg3BarterCrash2, qfg3PatchBarterCrash }, { 944, "import dialog continuous calls", 1, PATCH_MAGICDWORD(0x2a, 0x31, 0x0b, 0x7a), -1, qfg3SignatureImportDialog, qfg3PatchImportDialog }, SCI_SIGNATUREENTRY_TERMINATOR }; diff --git a/engines/sci/engine/state.h b/engines/sci/engine/state.h index d91118ec1e..cd6d56500a 100644 --- a/engines/sci/engine/state.h +++ b/engines/sci/engine/state.h @@ -32,8 +32,8 @@ #include "common/str-array.h" namespace Common { - class SeekableReadStream; - class WriteStream; +class SeekableReadStream; +class WriteStream; } #include "sci/sci.h" diff --git a/engines/sci/engine/vm.cpp b/engines/sci/engine/vm.cpp index d209a0ca5b..b441815014 100644 --- a/engines/sci/engine/vm.cpp +++ b/engines/sci/engine/vm.cpp @@ -25,8 +25,6 @@ #include "common/debug.h" #include "common/debug-channels.h" -#include "common/stack.h" -#include "common/config-manager.h" #include "sci/sci.h" #include "sci/console.h" diff --git a/engines/sci/engine/workarounds.cpp b/engines/sci/engine/workarounds.cpp index 0fba7a59e3..20d6cd0dd0 100644 --- a/engines/sci/engine/workarounds.cpp +++ b/engines/sci/engine/workarounds.cpp @@ -74,6 +74,11 @@ const SciWorkaroundEntry uninitializedReadWorkarounds[] = { { GID_HOYLE4, -1, 0, 0, NULL, "open", -1, -1, { WORKAROUND_FAKE, 0 } }, // when selecting "Control" from the menu (temp vars 0-3) - bug #3039294 { GID_HOYLE4, 910, 18, 0, NULL, "init", -1, 0, { WORKAROUND_FAKE, 0 } }, // during tutorial - bug #3042756 { GID_HOYLE4, 910, 910, 0, NULL, "setup", -1, 3, { WORKAROUND_FAKE, 0 } }, // when selecting "Tutorial" from the main menu - bug #3039294 + { GID_HOYLE4, 700, 718, 0, "compete_tree", "doit", -1, 75, { WORKAROUND_FAKE, 0 } }, // when placing a bid in bridge - bug #3292332 + { GID_HOYLE4, 700, 716, 0, "other1_tree", "doit", -1, 46, { WORKAROUND_FAKE, 0 } }, // sometimes when placing a bid in bridge + { GID_HOYLE4, 700, 700, 1, "BridgeHand", "calcQTS", -1, 3, { WORKAROUND_FAKE, 0 } }, // sometimes when placing a bid in bridge + { GID_HOYLE4, 300, 300, 0, "", "export 2", 0x1d4d, 0, { WORKAROUND_FAKE, 0 } }, // after passing around cards in hearts + { GID_HOYLE4, 400, 400, 1, "GinHand", "calcRuns", -1, 4, { WORKAROUND_FAKE, 0 } }, // sometimes while playing Gin Rummy (e.g. when knocking and placing a card) - bug #3292334 { GID_ISLANDBRAIN, 100, 937, 0, "IconBar", "dispatchEvent", -1, 58, { WORKAROUND_FAKE, 0 } }, // when using ENTER at the startup menu - bug #3045225 { GID_ISLANDBRAIN, 140, 140, 0, "piece", "init", -1, 3, { WORKAROUND_FAKE, 1 } }, // first puzzle right at the start, some initialization variable. bnt is done on it, and it should be non-0 { GID_ISLANDBRAIN, 200, 268, 0, "anElement", "select", -1, 0, { WORKAROUND_FAKE, 0 } }, // elements puzzle, gets used before super TextIcon @@ -251,6 +256,7 @@ const SciWorkaroundEntry kGetAngle_workarounds[] = { // gameID, room,script,lvl, object-name, method-name, call,index, workaround const SciWorkaroundEntry kFindKey_workarounds[] = { { GID_ECOQUEST2, 100, 999, 0, "myList", "contains", -1, 0, { WORKAROUND_FAKE, 0 } }, // When Noah Greene gives Adam the Ecorder, and just before the game gives a demonstration, a null reference to a list is passed - bug #3035186 + { GID_HOYLE4, 300, 999, 0, "Piles", "contains", -1, 0, { WORKAROUND_FAKE, 0 } }, // When passing the three cards in Hearts, a null reference to a list is passed - bug #3292333 SCI_WORKAROUNDENTRY_TERMINATOR }; diff --git a/engines/sci/graphics/cursor.cpp b/engines/sci/graphics/cursor.cpp index 3b95a5c955..d4d7dcfd4f 100644 --- a/engines/sci/graphics/cursor.cpp +++ b/engines/sci/graphics/cursor.cpp @@ -25,11 +25,11 @@ #include "common/config-manager.h" #include "common/events.h" -#include "common/macresman.h" #include "common/memstream.h" #include "common/system.h" #include "common/util.h" #include "graphics/cursorman.h" +#include "graphics/maccursor.h" #include "sci/sci.h" #include "sci/event.h" @@ -473,49 +473,19 @@ void GfxCursor::kernelSetMacCursor(GuiResourceId viewNum, int loopNum, int celNu assert(resource); - if (resource->size == 32 * 2 + 4) { - // Mac CURS cursor - // See http://developer.apple.com/legacy/mac/library/documentation/mac/QuickDraw/QuickDraw-402.html - // for more information. - byte *cursorBitmap = new byte[16 * 16]; - byte *data = resource->data; - - // Get B&W data - for (byte i = 0; i < 32; i++) { - byte imageByte = *data++; - for (byte b = 0; b < 8; b++) - cursorBitmap[i * 8 + b] = (byte)((imageByte & (0x80 >> b)) > 0 ? 1 : 2); - } - - // Apply mask data - for (byte i = 0; i < 32; i++) { - byte imageByte = *data++; - for (byte b = 0; b < 8; b++) - if ((imageByte & (0x80 >> b)) == 0) - cursorBitmap[i * 8 + b] = 0; // Doesn't matter, just is transparent - } - - uint16 hotspotY = READ_BE_UINT16(data); - uint16 hotspotX = READ_BE_UINT16(data + 2); - - static const byte cursorPalette[] = { 0x00, 0x00, 0x00, 0xff, 0xff, 0xff }; - - CursorMan.replaceCursor(cursorBitmap, 16, 16, hotspotX, hotspotY, 0); - CursorMan.replaceCursorPalette(cursorPalette, 1, 2); + Common::MemoryReadStream resStream(resource->data, resource->size); + Graphics::MacCursor *macCursor = new Graphics::MacCursor(); - delete[] cursorBitmap; - } else { - // Mac crsr cursor - byte *cursorBitmap, *palette; - int width, height, hotspotX, hotspotY, palSize, keycolor; - Common::MemoryReadStream resStream(resource->data, resource->size); - Common::MacResManager::convertCrsrCursor(&resStream, &cursorBitmap, width, height, hotspotX, hotspotY, keycolor, true, &palette, palSize); - CursorMan.replaceCursor(cursorBitmap, width, height, hotspotX, hotspotY, keycolor); - CursorMan.replaceCursorPalette(palette, 0, palSize); - delete[] cursorBitmap; - delete[] palette; + if (!macCursor->readFromStream(resStream)) { + warning("Failed to load Mac cursor %d", viewNum); + return; } + CursorMan.replaceCursor(macCursor->getSurface(), macCursor->getWidth(), macCursor->getHeight(), + macCursor->getHotspotX(), macCursor->getHotspotY(), macCursor->getKeyColor()); + CursorMan.replaceCursorPalette(macCursor->getPalette(), 0, 256); + + delete macCursor; kernelShow(); } diff --git a/engines/sci/graphics/fontsjis.h b/engines/sci/graphics/fontsjis.h index 684e6cac5e..5538b5c2c5 100644 --- a/engines/sci/graphics/fontsjis.h +++ b/engines/sci/graphics/fontsjis.h @@ -29,7 +29,7 @@ #include "sci/graphics/helpers.h" namespace Graphics { - class FontSJIS; +class FontSJIS; } namespace Sci { diff --git a/engines/sci/graphics/frameout.cpp b/engines/sci/graphics/frameout.cpp index dd55b3b060..7fafe843fd 100644 --- a/engines/sci/graphics/frameout.cpp +++ b/engines/sci/graphics/frameout.cpp @@ -23,9 +23,15 @@ * */ -#include "common/util.h" -#include "common/stack.h" -#include "graphics/primitives.h" +#include "common/algorithm.h" +#include "common/events.h" +#include "common/keyboard.h" +#include "common/list_intern.h" +#include "common/str.h" +#include "common/system.h" +#include "common/textconsole.h" +#include "engines/engine.h" +#include "graphics/surface.h" #include "sci/sci.h" #include "sci/engine/kernel.h" diff --git a/engines/sci/graphics/maciconbar.h b/engines/sci/graphics/maciconbar.h index 3ac5475147..72609d19ab 100644 --- a/engines/sci/graphics/maciconbar.h +++ b/engines/sci/graphics/maciconbar.h @@ -31,7 +31,7 @@ #include "sci/engine/vm.h" namespace Graphics { - struct Surface; +struct Surface; } namespace Sci { diff --git a/engines/sci/graphics/paint.cpp b/engines/sci/graphics/paint.cpp index c347da3c0f..27a0bdfc44 100644 --- a/engines/sci/graphics/paint.cpp +++ b/engines/sci/graphics/paint.cpp @@ -23,8 +23,6 @@ * */ -#include "common/util.h" -#include "common/stack.h" #include "graphics/primitives.h" #include "sci/sci.h" diff --git a/engines/sci/graphics/paint16.cpp b/engines/sci/graphics/paint16.cpp index ff738fc3b9..5172f7cdc0 100644 --- a/engines/sci/graphics/paint16.cpp +++ b/engines/sci/graphics/paint16.cpp @@ -23,11 +23,6 @@ * */ -#include "common/util.h" -#include "common/stack.h" -#include "common/system.h" -#include "graphics/primitives.h" - #include "sci/sci.h" #include "sci/engine/features.h" #include "sci/engine/state.h" @@ -302,6 +297,11 @@ void GfxPaint16::bitsShow(const Common::Rect &rect) { return; _ports->offsetRect(workerRect); + + // We adjust the left/right coordinates to even coordinates + workerRect.left &= 0xFFFE; // round down + workerRect.right = (workerRect.right + 1) & 0xFFFE; // round up + _screen->copyRectToScreen(workerRect); } @@ -472,6 +472,7 @@ void GfxPaint16::kernelGraphRedrawBox(Common::Rect rect) { #define SCI_DISPLAY_RESTOREUNDER 108 #define SCI_DISPLAY_DUMMY1 114 // used in longbow demo/qfg1 ega demo, not supported in sierra sci - no parameters #define SCI_DISPLAY_DUMMY2 115 // used in longbow demo, not supported in sierra sci - has 1 parameter +#define SCI_DISPLAY_DUMMY3 117 // used in qfg1 ega demo, not supported in sierra sci - no parameters #define SCI_DISPLAY_DONTSHOWBITS 121 reg_t GfxPaint16::kernelDisplay(const char *text, int argc, reg_t *argv) { @@ -542,9 +543,10 @@ reg_t GfxPaint16::kernelDisplay(const char *text, int argc, reg_t *argv) { break; // 2 Dummy functions, longbow-demo is using those several times but sierra sci doesn't support them at all - // The Quest for Glory 1 EGA demo also calls kDisplay(114) + // The Quest for Glory 1 EGA demo also calls kDisplay(114) and kDisplay(117) case SCI_DISPLAY_DUMMY1: case SCI_DISPLAY_DUMMY2: + case SCI_DISPLAY_DUMMY3: if (!g_sci->isDemo() || (g_sci->getGameId() != GID_LONGBOW && g_sci->getGameId() != GID_QFG1)) error("Unknown kDisplay argument %d", displayArg.offset); if (displayArg.offset == SCI_DISPLAY_DUMMY2) { diff --git a/engines/sci/graphics/paint32.cpp b/engines/sci/graphics/paint32.cpp index 69a278eb8b..f277436631 100644 --- a/engines/sci/graphics/paint32.cpp +++ b/engines/sci/graphics/paint32.cpp @@ -23,11 +23,6 @@ * */ -#include "common/util.h" -#include "common/stack.h" - -#include "graphics/primitives.h" - #include "sci/sci.h" #include "sci/engine/state.h" #include "sci/engine/selector.h" diff --git a/engines/sci/graphics/palette.cpp b/engines/sci/graphics/palette.cpp index 0433479a09..42551e9369 100644 --- a/engines/sci/graphics/palette.cpp +++ b/engines/sci/graphics/palette.cpp @@ -28,6 +28,8 @@ #include "common/util.h" #include "common/system.h" +#include "graphics/palette.h" + #include "sci/sci.h" #include "sci/engine/state.h" #include "sci/graphics/cache.h" diff --git a/engines/sci/graphics/picture.cpp b/engines/sci/graphics/picture.cpp index 82aae5399f..8cdd46268a 100644 --- a/engines/sci/graphics/picture.cpp +++ b/engines/sci/graphics/picture.cpp @@ -509,10 +509,12 @@ void GfxPicture::drawVectorData(byte *data, int dataSize) { memcpy(&EGApriority, &vector_defaultEGApriority, sizeof(vector_defaultEGApriority)); if (g_sci->getGameId() == GID_ICEMAN) { - // WORKAROUND: we remove certain visual&priority lines in underwater rooms of iceman, when not dithering the - // picture. Normally those lines aren't shown, because they share the same color as the dithered - // fill color combination. When not dithering, those lines would appear and get distracting. - if ((_screen->getUnditherState()) && ((_resourceId >= 53 && _resourceId <= 58) || (_resourceId == 61))) + // WORKAROUND: we remove certain visual&priority lines in underwater + // rooms of iceman, when not dithering the picture. Normally those + // lines aren't shown, because they share the same color as the + // dithered fill color combination. When not dithering, those lines + // would appear and get distracting. + if ((_screen->isUnditheringEnabled()) && ((_resourceId >= 53 && _resourceId <= 58) || (_resourceId == 61))) icemanDrawFix = true; } if (g_sci->getGameId() == GID_KQ5) { @@ -618,14 +620,17 @@ void GfxPicture::drawVectorData(byte *data, int dataSize) { } break; - // Pattern opcodes are handled in sierra sci1.1+ as actual NOPs and normally they definitely should not occur - // inside picture data for such games + // Pattern opcodes are handled in sierra sci1.1+ as actual NOPs and + // normally they definitely should not occur inside picture data for + // such games. case PIC_OP_SET_PATTERN: if (_resourceType >= SCI_PICTURE_TYPE_SCI11) { if (g_sci->getGameId() == GID_SQ4) { - // WORKAROUND: For SQ4 / for some pictures handle this like a terminator - // This picture includes garbage data, first a set pattern w/o parameter and then short pattern - // I guess that garbage is a left over from the sq4-floppy (sci1) to sq4-cd (sci1.1) conversion + // WORKAROUND: For SQ4 / for some pictures handle this like + // a terminator. This picture includes garbage data, first a + // set pattern w/o parameter and then short pattern. I guess + // that garbage is a left over from the sq4-floppy (sci1) to + // sq4-cd (sci1.1) conversion. switch (_resourceId) { case 35: case 381: @@ -857,7 +862,8 @@ void GfxPicture::vectorGetPatternTexture(byte *data, int &curPos, int16 pattern_ } } -// Do not replace w/ some generic code. This algo really needs to behave exactly as the one from sierra +// WARNING: Do not replace the following code with something else, like generic +// code. This algo really needs to behave exactly as the one from sierra. void GfxPicture::vectorFloodFill(int16 x, int16 y, byte color, byte priority, byte control) { Port *curPort = _ports->getPort(); Common::Stack<Common::Point> stack; diff --git a/engines/sci/graphics/portrait.cpp b/engines/sci/graphics/portrait.cpp index 6e9df2f019..3f9ebaa07a 100644 --- a/engines/sci/graphics/portrait.cpp +++ b/engines/sci/graphics/portrait.cpp @@ -24,9 +24,7 @@ */ #include "common/archive.h" -#include "common/util.h" -#include "common/stack.h" -#include "graphics/primitives.h" +#include "common/system.h" #include "sci/sci.h" #include "sci/event.h" diff --git a/engines/sci/graphics/screen.cpp b/engines/sci/graphics/screen.cpp index f619780c7c..56e6759fac 100644 --- a/engines/sci/graphics/screen.cpp +++ b/engines/sci/graphics/screen.cpp @@ -111,7 +111,7 @@ GfxScreen::GfxScreen(ResourceManager *resMan) : _resMan(resMan) { _picNotValid = 0; _picNotValidSci11 = 0; - _unditherState = true; + _unditheringEnabled = true; _fontIsUpscaled = false; if (_resMan->getViewType() != kViewEga) { @@ -560,7 +560,7 @@ void GfxScreen::dither(bool addToFlag) { byte *visualPtr = _visualScreen; byte *displayPtr = _displayScreen; - if (!_unditherState) { + if (!_unditheringEnabled) { // Do dithering on visual and display-screen for (y = 0; y < _height; y++) { for (x = 0; x < _width; x++) { @@ -624,13 +624,13 @@ void GfxScreen::ditherForceDitheredColor(byte color) { _ditheredPicColors[color] = 256; } -void GfxScreen::debugUnditherSetState(bool flag) { - _unditherState = flag; +void GfxScreen::enableUndithering(bool flag) { + _unditheringEnabled = flag; } int16 *GfxScreen::unditherGetDitheredBgColors() { - if (_unditherState) - return (int16 *)&_ditheredPicColors; + if (_unditheringEnabled) + return _ditheredPicColors; else return NULL; } diff --git a/engines/sci/graphics/screen.h b/engines/sci/graphics/screen.h index 89ad52e0ac..bfe0a50b81 100644 --- a/engines/sci/graphics/screen.h +++ b/engines/sci/graphics/screen.h @@ -95,9 +95,10 @@ public: return _upscaledHires; } - bool getUnditherState() const { - return _unditherState; + bool isUnditheringEnabled() const { + return _unditheringEnabled; } + void enableUndithering(bool flag); void putKanjiChar(Graphics::FontSJIS *commonFont, int16 x, int16 y, uint16 chr, byte color); byte getVisual(int x, int y); @@ -119,7 +120,6 @@ public: // Force a color combination as a dithered color void ditherForceDitheredColor(byte color); - void debugUnditherSetState(bool flag); int16 *unditherGetDitheredBgColors(); void debugShowMap(int mapNo); @@ -151,7 +151,10 @@ private: void setVerticalShakePos(uint16 shakePos); - bool _unditherState; + /** + * If this flag is true, undithering is enabled, otherwise disabled. + */ + bool _unditheringEnabled; int16 _ditheredPicColors[DITHERED_BG_COLORS_SIZE]; // These screens have the real resolution of the game engine (320x200 for @@ -161,13 +164,13 @@ private: byte *_priorityScreen; byte *_controlScreen; - // This screen is the one that is actually displayed to the user. It may be - // 640x400 for japanese SCI1 games. SCI0 games may be undithered in here. - // Only read from this buffer for Save/ShowBits usage. + /** + * This screen is the one that is actually displayed to the user. It may be + * 640x400 for japanese SCI1 games. SCI0 games may be undithered in here. + * Only read from this buffer for Save/ShowBits usage. + */ byte *_displayScreen; - Common::Rect getScaledRect(Common::Rect rect); - ResourceManager *_resMan; /** @@ -176,16 +179,22 @@ private: */ byte *_activeScreen; - // This variable defines, if upscaled hires is active and what upscaled mode - // is used. + /** + * This variable defines, if upscaled hires is active and what upscaled mode + * is used. + */ GfxScreenUpscaledMode _upscaledHires; - // This here holds a translation for vertical coordinates between native - // (visual) and actual (display) screen. + /** + * This here holds a translation for vertical coordinates between native + * (visual) and actual (display) screen. + */ int _upscaledMapping[SCI_SCREEN_UPSCALEDMAXHEIGHT + 1]; - // This defines whether or not the font we're drawing is already scaled - // to the screen size (and we therefore should not upscale it ourselves). + /** + * This defines whether or not the font we're drawing is already scaled + * to the screen size (and we therefore should not upscale it ourselves). + */ bool _fontIsUpscaled; uint16 getLowResScreenHeight(); diff --git a/engines/sci/graphics/transitions.cpp b/engines/sci/graphics/transitions.cpp index fb124055d6..dde1be13ab 100644 --- a/engines/sci/graphics/transitions.cpp +++ b/engines/sci/graphics/transitions.cpp @@ -24,9 +24,8 @@ */ #include "common/events.h" -#include "common/util.h" -#include "common/stack.h" #include "common/system.h" +#include "graphics/palette.h" #include "graphics/surface.h" #include "sci/sci.h" diff --git a/engines/sci/parser/grammar.cpp b/engines/sci/parser/grammar.cpp index 77db56adba..b330a432e3 100644 --- a/engines/sci/parser/grammar.cpp +++ b/engines/sci/parser/grammar.cpp @@ -31,6 +31,7 @@ #include "sci/parser/vocabulary.h" #include "sci/console.h" #include "common/array.h" +#include "common/textconsole.h" namespace Sci { diff --git a/engines/sci/resource.cpp b/engines/sci/resource.cpp index 4caa77b0ae..a48ae0fad7 100644 --- a/engines/sci/resource.cpp +++ b/engines/sci/resource.cpp @@ -28,6 +28,7 @@ #include "common/file.h" #include "common/fs.h" #include "common/macresman.h" +#include "common/textconsole.h" #include "sci/resource.h" #include "sci/resource_intern.h" @@ -1275,7 +1276,7 @@ ResVersion ResourceManager::detectVolVersion() { // SCI32 volume format: {bResType wResNumber dwPacked dwUnpacked wCompression} = 13 bytes // Try to parse volume with SCI0 scheme to see if it make sense // Checking 1MB of data should be enough to determine the version - uint16 resId, wCompression; + uint16 wCompression; uint32 dwPacked, dwUnpacked; ResVersion curVersion = kResVersionSci0Sci1Early; bool failed = false; @@ -1285,7 +1286,7 @@ ResVersion ResourceManager::detectVolVersion() { while (!fileStream->eos() && fileStream->pos() < 0x100000) { if (curVersion > kResVersionSci0Sci1Early) fileStream->readByte(); - resId = fileStream->readUint16LE(); + fileStream->skip(2); // resId dwPacked = (curVersion < kResVersionSci2) ? fileStream->readUint16LE() : fileStream->readUint32LE(); dwUnpacked = (curVersion < kResVersionSci2) ? fileStream->readUint16LE() : fileStream->readUint32LE(); diff --git a/engines/sci/resource_audio.cpp b/engines/sci/resource_audio.cpp index 6e74553f56..1e0b9c0ddf 100644 --- a/engines/sci/resource_audio.cpp +++ b/engines/sci/resource_audio.cpp @@ -27,6 +27,7 @@ #include "common/archive.h" #include "common/file.h" +#include "common/textconsole.h" #include "sci/resource.h" #include "sci/resource_intern.h" diff --git a/engines/sci/resource_intern.h b/engines/sci/resource_intern.h index 98cca6283c..969e250e62 100644 --- a/engines/sci/resource_intern.h +++ b/engines/sci/resource_intern.h @@ -29,7 +29,7 @@ #include "sci/resource.h" namespace Common { - class MacResManager; +class MacResManager; } namespace Sci { diff --git a/engines/sci/sci.cpp b/engines/sci/sci.cpp index 85c2eced19..8a81ea7240 100644 --- a/engines/sci/sci.cpp +++ b/engines/sci/sci.cpp @@ -218,7 +218,7 @@ Common::Error SciEngine::run() { // Initialize the game screen _gfxScreen = new GfxScreen(_resMan); - _gfxScreen->debugUnditherSetState(ConfMan.getBool("disable_dithering")); + _gfxScreen->enableUndithering(ConfMan.getBool("disable_dithering")); // Create debugger console. It requires GFX to be initialized _console = new Console(this); diff --git a/engines/sci/sound/drivers/adlib.cpp b/engines/sci/sound/drivers/adlib.cpp index 65a8e2e3da..f00c99d5b5 100644 --- a/engines/sci/sound/drivers/adlib.cpp +++ b/engines/sci/sound/drivers/adlib.cpp @@ -26,6 +26,8 @@ #include "sci/sci.h" #include "common/file.h" +#include "common/system.h" +#include "common/textconsole.h" #include "audio/fmopl.h" #include "audio/softsynth/emumidi.h" diff --git a/engines/sci/sound/drivers/amigamac.cpp b/engines/sci/sound/drivers/amigamac.cpp index d64dfac23c..7ee8d21f86 100644 --- a/engines/sci/sound/drivers/amigamac.cpp +++ b/engines/sci/sound/drivers/amigamac.cpp @@ -30,6 +30,8 @@ #include "common/file.h" #include "common/frac.h" #include "common/memstream.h" +#include "common/system.h" +#include "common/textconsole.h" #include "common/util.h" namespace Sci { @@ -132,6 +134,7 @@ private: }; bool _isSci1; + bool _isSci1Early; // KQ1 Amiga, patch 5 bool _playSwitch; int _masterVolume; int _frequency; @@ -557,6 +560,7 @@ uint32 MidiDriver_AmigaMac::property(int prop, uint32 param) { int MidiDriver_AmigaMac::open() { _isSci1 = false; + _isSci1Early = false; for (int i = 0; i < 48; i++) _freqTable[i] = pow(2, i / (double)48); @@ -589,9 +593,15 @@ int MidiDriver_AmigaMac::open() { } else { ResourceManager *resMan = g_sci->getResMan(); - Resource *resource = resMan->findResource(ResourceId(kResourceTypePatch, 7), false); + Resource *resource = resMan->findResource(ResourceId(kResourceTypePatch, 7), false); // Mac if (!resource) - resource = resMan->findResource(ResourceId(kResourceTypePatch, 9), false); + resource = resMan->findResource(ResourceId(kResourceTypePatch, 9), false); // Amiga + + if (!resource) { + resource = resMan->findResource(ResourceId(kResourceTypePatch, 5), false); // KQ1 Amiga + if (resource) + _isSci1Early = true; + } // If we have a patch by this point, it's SCI1 if (resource) @@ -896,6 +906,9 @@ bool MidiDriver_AmigaMac::loadInstrumentsSCI0Mac(Common::SeekableReadStream &fil bool MidiDriver_AmigaMac::loadInstrumentsSCI1(Common::SeekableReadStream &file) { _bank.size = 128; + if (_isSci1Early) + file.skip(4); // TODO: What is this offset for? + Common::Array<uint32> instrumentOffsets; instrumentOffsets.resize(_bank.size); _bank.instruments.resize(_bank.size); @@ -908,11 +921,17 @@ bool MidiDriver_AmigaMac::loadInstrumentsSCI1(Common::SeekableReadStream &file) if (instrumentOffsets[i] == 0) continue; - file.seek(instrumentOffsets[i]); + file.seek(instrumentOffsets[i] + (_isSci1Early ? 4 : 0)); // Read in the instrument name file.read(_bank.instruments[i].name, 10); // last two bytes are always 0 + // TODO: Finish off support of SCI1 early patches (patch.005 - KQ1 Amiga) + if (_isSci1Early) { + warning("Music patch 5 isn't supported yet - ignoring instrument %d", i); + continue; + } + for (uint32 j = 0; ; j++) { InstrumentSample *sample = new InstrumentSample; memset(sample, 0, sizeof(InstrumentSample)); diff --git a/engines/sci/sound/drivers/cms.cpp b/engines/sci/sound/drivers/cms.cpp index 051fa7f1fd..47c59a1e3d 100644 --- a/engines/sci/sound/drivers/cms.cpp +++ b/engines/sci/sound/drivers/cms.cpp @@ -29,6 +29,8 @@ #include "audio/softsynth/cms.h" #include "audio/mixer.h" +#include "common/system.h" + #include "sci/resource.h" namespace Sci { diff --git a/engines/sci/sound/drivers/fb01.cpp b/engines/sci/sound/drivers/fb01.cpp index 971c2ff92d..f217738bb2 100644 --- a/engines/sci/sound/drivers/fb01.cpp +++ b/engines/sci/sound/drivers/fb01.cpp @@ -30,6 +30,7 @@ #include "common/file.h" #include "common/system.h" +#include "common/textconsole.h" namespace Sci { diff --git a/engines/sci/sound/drivers/midi.cpp b/engines/sci/sound/drivers/midi.cpp index 9eef867aeb..f36aac3a2a 100644 --- a/engines/sci/sound/drivers/midi.cpp +++ b/engines/sci/sound/drivers/midi.cpp @@ -745,7 +745,7 @@ uint8 MidiPlayer_Midi::getGmInstrument(const Mt32ToGmMap &Mt32Ins) { void MidiPlayer_Midi::mapMt32ToGm(byte *data, size_t size) { // FIXME: Clean this up int memtimbres, patches; - uint8 group, number, keyshift, finetune, bender_range; + uint8 group, number, keyshift, /*finetune,*/ bender_range; uint8 *patchpointer; uint32 pos; int i; @@ -784,7 +784,7 @@ void MidiPlayer_Midi::mapMt32ToGm(byte *data, size_t size) { group = *patchpointer; number = *(patchpointer + 1); keyshift = *(patchpointer + 2); - finetune = *(patchpointer + 3); + //finetune = *(patchpointer + 3); bender_range = *(patchpointer + 4); debugCN(kDebugLevelSound, " [%03d] ", i); diff --git a/engines/sci/sound/drivers/pcjr.cpp b/engines/sci/sound/drivers/pcjr.cpp index 063332577e..4b1efb3c87 100644 --- a/engines/sci/sound/drivers/pcjr.cpp +++ b/engines/sci/sound/drivers/pcjr.cpp @@ -27,6 +27,9 @@ #include "audio/softsynth/emumidi.h" +#include "common/debug.h" +#include "common/system.h" + namespace Sci { #define VOLUME_SHIFT 3 diff --git a/engines/sci/sound/soundcmd.cpp b/engines/sci/sound/soundcmd.cpp index 9ad964b67e..a2b09eab4c 100644 --- a/engines/sci/sound/soundcmd.cpp +++ b/engines/sci/sound/soundcmd.cpp @@ -325,14 +325,6 @@ reg_t SoundCommandParser::kDoSoundFade(int argc, reg_t *argv, reg_t acc) { return acc; } - // If the current volume of the slot is the same as the target volume, - // return without performing any fading. This fixes the music in room - // 406 in KQ6 (bug #3267956), where the game scripts ask for the background - // music to be played, and then faded to volume 127 (but the music is - // already at volume 127) and subsequently stopped. - if (argc >= 4 && musicSlot->volume == CLIP<uint16>(argv[1].toUint16(), 0, MUSIC_VOLUME_MAX)) - return acc; - switch (argc) { case 1: // SCI0 // SCI0 fades out all the time and when fadeout is done it will also @@ -353,7 +345,25 @@ reg_t SoundCommandParser::kDoSoundFade(int argc, reg_t *argv, reg_t acc) { musicSlot->fadeStep = volume > musicSlot->fadeTo ? -5 : 5; musicSlot->fadeTickerStep = argv[2].toUint16() * 16667 / _music->soundGetTempo(); musicSlot->fadeTicker = 0; - musicSlot->stopAfterFading = (argc == 5) ? (argv[4].toUint16() != 0) : false; + + if (argc == 5) { + // TODO: We currently treat this argument as a boolean, but may + // have to handle different non-zero values differently. (e.g., + // some KQ6 scripts pass 3 here) + musicSlot->stopAfterFading = (argv[4].toUint16() != 0); + } else { + musicSlot->stopAfterFading = false; + } + + // WORKAROUND/HACK: In the labyrinth in KQ6, when falling in the pit and + // lighting the lantern, the game scripts perform a fade in of the game + // music, but set it to stop after fading. Remove that flag here. This is + // marked as both a workaround and a hack because this issue could be a + // problem with our fading code and an incorrect handling of that + // parameter, or a script bug in that scene. Fixes bug #3267956. + if (g_sci->getGameId() == GID_KQ6 && g_sci->getEngineState()->currentRoomNumber() == 406 && + musicSlot->resourceId == 400) + musicSlot->stopAfterFading = false; break; default: diff --git a/engines/sci/video/robot_decoder.cpp b/engines/sci/video/robot_decoder.cpp index ecdce3bd6b..debc75dffd 100644 --- a/engines/sci/video/robot_decoder.cpp +++ b/engines/sci/video/robot_decoder.cpp @@ -23,11 +23,10 @@ * */ -#include "common/debug.h" -#include "common/endian.h" #include "common/archive.h" #include "common/stream.h" #include "common/system.h" +#include "common/textconsole.h" #include "common/util.h" #include "graphics/surface.h" @@ -126,7 +125,7 @@ bool RobotDecoder::loadStream(Common::SeekableReadStream *stream) { readPaletteChunk(_header.paletteDataSize); readFrameSizesChunk(); calculateVideoDimensions(); - _surface->create(_width, _height, 1); + _surface->create(_width, _height, Graphics::PixelFormat::createFormatCLUT8()); return true; } diff --git a/engines/sci/video/robot_decoder.h b/engines/sci/video/robot_decoder.h index 52bf0bad07..aeb638e019 100644 --- a/engines/sci/video/robot_decoder.h +++ b/engines/sci/video/robot_decoder.h @@ -32,6 +32,7 @@ #include "common/substream.h" #include "audio/audiostream.h" #include "audio/mixer.h" +#include "graphics/pixelformat.h" #include "video/video_decoder.h" namespace Sci { diff --git a/engines/sci/video/seq_decoder.cpp b/engines/sci/video/seq_decoder.cpp index 0e69a9a352..7168496893 100644 --- a/engines/sci/video/seq_decoder.cpp +++ b/engines/sci/video/seq_decoder.cpp @@ -23,12 +23,10 @@ * */ -#include "common/debug.h" #include "common/endian.h" -#include "common/archive.h" #include "common/stream.h" #include "common/system.h" -#include "common/util.h" +#include "common/textconsole.h" #include "graphics/surface.h" @@ -61,7 +59,7 @@ bool SeqDecoder::loadStream(Common::SeekableReadStream *stream) { _fileStream = stream; _surface = new Graphics::Surface(); - _surface->create(SEQ_SCREEN_WIDTH, SEQ_SCREEN_HEIGHT, 1); + _surface->create(SEQ_SCREEN_WIDTH, SEQ_SCREEN_HEIGHT, Graphics::PixelFormat::createFormatCLUT8()); _frameCount = _fileStream->readUint16LE(); diff --git a/engines/sci/video/seq_decoder.h b/engines/sci/video/seq_decoder.h index 70aaa661ae..70d3985ec5 100644 --- a/engines/sci/video/seq_decoder.h +++ b/engines/sci/video/seq_decoder.h @@ -26,8 +26,18 @@ #ifndef SCI_VIDEO_SEQ_DECODER_H #define SCI_VIDEO_SEQ_DECODER_H +#include "common/rational.h" +#include "graphics/pixelformat.h" #include "video/video_decoder.h" +namespace Common { +class SeekableReadStream; +} + +namespace Graphics { +struct Surface; +} + namespace Sci { /** |