diff options
Diffstat (limited to 'engines/sci')
-rw-r--r-- | engines/sci/detection_tables.h | 17 | ||||
-rw-r--r-- | engines/sci/engine/kpathing.cpp | 2 | ||||
-rw-r--r-- | engines/sci/engine/kstring.cpp | 2 | ||||
-rw-r--r-- | engines/sci/engine/kvideo.cpp | 4 | ||||
-rw-r--r-- | engines/sci/graphics/frameout.cpp | 12 | ||||
-rw-r--r-- | engines/sci/graphics/maciconbar.cpp | 6 | ||||
-rw-r--r-- | engines/sci/graphics/ports.cpp | 4 | ||||
-rw-r--r-- | engines/sci/graphics/screen.cpp | 4 | ||||
-rw-r--r-- | engines/sci/sound/midiparser_sci.cpp | 29 | ||||
-rw-r--r-- | engines/sci/sound/midiparser_sci.h | 1 | ||||
-rw-r--r-- | engines/sci/sound/soundcmd.cpp | 20 | ||||
-rw-r--r-- | engines/sci/video/robot_decoder.cpp | 2 | ||||
-rw-r--r-- | engines/sci/video/seq_decoder.cpp | 4 |
13 files changed, 79 insertions, 28 deletions
diff --git a/engines/sci/detection_tables.h b/engines/sci/detection_tables.h index 66164a1937..7c4638a992 100644 --- a/engines/sci/detection_tables.h +++ b/engines/sci/detection_tables.h @@ -1054,6 +1054,23 @@ static const struct ADGameDescription SciGameDescriptions[] = { AD_LISTEND}, Common::EN_ANY, Common::kPlatformWindows, ADGF_CD, GUIO4(GUIO_MIDIGM, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_FB01_MIDI, GAMEOPTION_JONES_CDAUDIO) }, + // Jones in the Fast Lane - English DOS US CD (alternate version) + // Supplied by collector9 in bug #3614668 + {"jones", "CD", { + {"resource.map", 0, "4344ff3f796707843b992adec2c87663", 4878}, + {"resource.001", 0, "3876da2ce16fb7dea2f5d943d946fa84", 1652062}, + AD_LISTEND}, + Common::EN_ANY, Common::kPlatformDOS, ADGF_CD, GUIO1(GAMEOPTION_JONES_CDAUDIO) }, + + // Jones in the Fast Lane - English DOS US CD (alternate version) + // Same entry as the DOS version above. This one is used for the alternate + // General MIDI music tracks in the Windows version + {"jones", "CD", { + {"resource.map", 0, "4344ff3f796707843b992adec2c87663", 4878}, + {"resource.001", 0, "3876da2ce16fb7dea2f5d943d946fa84", 1652062}, + AD_LISTEND}, + Common::EN_ANY, Common::kPlatformWindows, ADGF_CD, GUIO4(GUIO_MIDIGM, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_FB01_MIDI, GAMEOPTION_JONES_CDAUDIO) }, + // King's Quest 1 SCI Remake - English Amiga (from www.back2roots.org) // Executable scanning reports "1.003.007" // SCI interpreter version 0.001.010 diff --git a/engines/sci/engine/kpathing.cpp b/engines/sci/engine/kpathing.cpp index 64793efa6c..3c223bebbe 100644 --- a/engines/sci/engine/kpathing.cpp +++ b/engines/sci/engine/kpathing.cpp @@ -1966,7 +1966,7 @@ static bool isVertexCovered(const Patch &p, unsigned int wi) { // ---w1--1----p----w2--2---- // ^ \ (inside) if (wi > p.indexw1 && wi <= p.indexw2) - return true; + return true; // v / (outside) // ---w2--2----p----w1--1---- diff --git a/engines/sci/engine/kstring.cpp b/engines/sci/engine/kstring.cpp index 15a9f54996..d72b1d1772 100644 --- a/engines/sci/engine/kstring.cpp +++ b/engines/sci/engine/kstring.cpp @@ -551,7 +551,7 @@ reg_t kMessage(EngineState *s, int argc, reg_t *argv) { // NOTE: To fix a corrupted jar object, type "send Glass_Jar message 52" // in the debugger. if (g_sci->getGameId() == GID_PEPPER && func == 0 && argc >= 6 && module == 894 && - tuple.noun == 26 && tuple.cond == 0 && tuple.seq == 1 && + tuple.noun == 26 && tuple.cond == 0 && tuple.seq == 1 && !s->_msgState->getMessage(module, tuple, NULL_REG)) tuple.verb = 0; diff --git a/engines/sci/engine/kvideo.cpp b/engines/sci/engine/kvideo.cpp index 9b0cb38f51..3964ccc1f8 100644 --- a/engines/sci/engine/kvideo.cpp +++ b/engines/sci/engine/kvideo.cpp @@ -103,10 +103,10 @@ void playVideo(Video::VideoDecoder *videoDecoder, VideoState videoState) { if (frame) { if (scaleBuffer) { // TODO: Probably should do aspect ratio correction in e.g. GK1 Windows - g_sci->_gfxScreen->scale2x((byte *)frame->pixels, scaleBuffer, videoDecoder->getWidth(), videoDecoder->getHeight(), bytesPerPixel); + g_sci->_gfxScreen->scale2x((const byte *)frame->getPixels(), scaleBuffer, videoDecoder->getWidth(), videoDecoder->getHeight(), bytesPerPixel); g_system->copyRectToScreen(scaleBuffer, pitch, x, y, width, height); } else { - g_system->copyRectToScreen(frame->pixels, frame->pitch, x, y, width, height); + g_system->copyRectToScreen(frame->getPixels(), frame->pitch, x, y, width, height); } if (videoDecoder->hasDirtyPalette()) { diff --git a/engines/sci/graphics/frameout.cpp b/engines/sci/graphics/frameout.cpp index bf1ce6da64..76510fa53b 100644 --- a/engines/sci/graphics/frameout.cpp +++ b/engines/sci/graphics/frameout.cpp @@ -532,7 +532,7 @@ void GfxFrameout::showVideo() { if (videoDecoder->needsUpdate()) { const Graphics::Surface *frame = videoDecoder->decodeNextFrame(); if (frame) { - g_system->copyRectToScreen(frame->pixels, frame->pitch, x, y, frame->w, frame->h); + g_system->copyRectToScreen(frame->getPixels(), frame->pitch, x, y, frame->w, frame->h); if (videoDecoder->hasDirtyPalette()) g_system->getPaletteManager()->setPalette(videoDecoder->getPalette(), 0, 256); @@ -745,7 +745,7 @@ void GfxFrameout::kernelFrameout() { // Process global scaling, if needed. // TODO: Seems like SCI32 always processes global scaling for scaled objects // TODO: We can only process symmetrical scaling for now (i.e. same value for scaleX/scaleY) - if ((itemEntry->scaleSignal & kScaleSignalDoScaling32) && + if ((itemEntry->scaleSignal & kScaleSignalDoScaling32) && !(itemEntry->scaleSignal & kScaleSignalDisableGlobalScaling32) && (itemEntry->scaleX == itemEntry->scaleY) && itemEntry->scaleX != 128) @@ -779,6 +779,14 @@ void GfxFrameout::kernelFrameout() { _coordAdjuster->fromDisplayToScript(nsRect.bottom, nsRect.right); g_sci->_gfxCompare->setNSRect(itemEntry->object, nsRect); } + + // TODO: For some reason, the top left nsRect coordinates get + // swapped in the GK1 inventory screen, investigate why. + // HACK: Fix the coordinates by explicitly setting them here. + Common::Rect objNSRect = g_sci->_gfxCompare->getNSRect(itemEntry->object); + if (objNSRect.top == nsRect.left && objNSRect.left == nsRect.top && nsRect.top != 0 && nsRect.left != 0) { + g_sci->_gfxCompare->setNSRect(itemEntry->object, nsRect); + } } // Don't attempt to draw sprites that are outside the visible diff --git a/engines/sci/graphics/maciconbar.cpp b/engines/sci/graphics/maciconbar.cpp index dfb50b0edb..4df80b289f 100644 --- a/engines/sci/graphics/maciconbar.cpp +++ b/engines/sci/graphics/maciconbar.cpp @@ -129,7 +129,7 @@ void GfxMacIconBar::drawIcon(uint16 iconIndex, bool selected) { void GfxMacIconBar::drawEnabledImage(Graphics::Surface *surface, const Common::Rect &rect) { if (surface) - g_system->copyRectToScreen(surface->pixels, surface->pitch, rect.left, rect.top, rect.width(), rect.height()); + g_system->copyRectToScreen(surface->getPixels(), surface->pitch, rect.left, rect.top, rect.width(), rect.height()); } void GfxMacIconBar::drawDisabledImage(Graphics::Surface *surface, const Common::Rect &rect) { @@ -153,7 +153,7 @@ void GfxMacIconBar::drawDisabledImage(Graphics::Surface *surface, const Common:: *((byte *)newSurf.getBasePtr(j, i)) = 0; } - g_system->copyRectToScreen(newSurf.pixels, newSurf.pitch, rect.left, rect.top, rect.width(), rect.height()); + g_system->copyRectToScreen(newSurf.getPixels(), newSurf.pitch, rect.left, rect.top, rect.width(), rect.height()); newSurf.free(); } @@ -224,7 +224,7 @@ Graphics::Surface *GfxMacIconBar::createImage(uint32 iconIndex, bool isSelected) } void GfxMacIconBar::remapColors(Graphics::Surface *surf, const byte *palette) { - byte *pixels = (byte *)surf->pixels; + byte *pixels = (byte *)surf->getPixels(); // Remap to the screen palette for (uint16 i = 0; i < surf->w * surf->h; i++) { diff --git a/engines/sci/graphics/ports.cpp b/engines/sci/graphics/ports.cpp index 527e2ae973..6d9dc03195 100644 --- a/engines/sci/graphics/ports.cpp +++ b/engines/sci/graphics/ports.cpp @@ -116,7 +116,7 @@ void GfxPorts::init(bool usesOldGfxFunctions, GfxPaint16 *paint16, GfxText16 *te setPort(_wmgrPort); // SCI0 games till kq4 (.502 - not including) did not adjust against _wmgrPort in kNewWindow // We leave _wmgrPort top at 0, so the adjustment wont get done - if (!g_sci->_features->usesOldGfxFunctions()) { + if (!_usesOldGfxFunctions) { setOrigin(0, offTop); _wmgrPort->rect.bottom = _screen->getHeight() - offTop; } else { @@ -131,7 +131,7 @@ void GfxPorts::init(bool usesOldGfxFunctions, GfxPaint16 *paint16, GfxText16 *te _picWind = addWindow(Common::Rect(0, offTop, _screen->getWidth(), _screen->getHeight()), 0, 0, SCI_WINDOWMGR_STYLE_TRANSPARENT | SCI_WINDOWMGR_STYLE_NOFRAME, 0, true); // For SCI0 games till kq4 (.502 - not including) we set _picWind top to offTop instead // Because of the menu/status bar - if (g_sci->_features->usesOldGfxFunctions()) + if (_usesOldGfxFunctions) _picWind->top = offTop; kernelInitPriorityBands(); diff --git a/engines/sci/graphics/screen.cpp b/engines/sci/graphics/screen.cpp index 74503c0c77..7b92bc89eb 100644 --- a/engines/sci/graphics/screen.cpp +++ b/engines/sci/graphics/screen.cpp @@ -170,14 +170,14 @@ void GfxScreen::copyToScreen() { void GfxScreen::copyFromScreen(byte *buffer) { // TODO this ignores the pitch Graphics::Surface *screen = g_system->lockScreen(); - memcpy(buffer, screen->pixels, _displayPixels); + memcpy(buffer, screen->getPixels(), _displayPixels); g_system->unlockScreen(); } void GfxScreen::kernelSyncWithFramebuffer() { // TODO this ignores the pitch Graphics::Surface *screen = g_system->lockScreen(); - memcpy(_displayScreen, screen->pixels, _displayPixels); + memcpy(_displayScreen, screen->getPixels(), _displayPixels); g_system->unlockScreen(); } diff --git a/engines/sci/sound/midiparser_sci.cpp b/engines/sci/sound/midiparser_sci.cpp index 9546b1503f..9653d9ccff 100644 --- a/engines/sci/sound/midiparser_sci.cpp +++ b/engines/sci/sound/midiparser_sci.cpp @@ -57,6 +57,7 @@ MidiParser_SCI::MidiParser_SCI(SciVersion soundVersion, SciMusic *music) : _signalToSet = 0; _dataincAdd = false; _dataincToAdd = 0; + _jumpToHoldTick = false; _resetOnPause = false; _pSnd = 0; } @@ -452,6 +453,10 @@ void MidiParser_SCI::parseNextEvent(EventInfo &info) { debugC(4, kDebugLevelSound, "signal %04x", _signalToSet); } + if (_jumpToHoldTick) { + _jumpToHoldTick = false; + jumpToTick(_loopTick, false, false); + } info.start = _position._playPos; info.delta = 0; @@ -486,6 +491,10 @@ void MidiParser_SCI::parseNextEvent(EventInfo &info) { // though, so ignoring these signals in SCI0 games will result // in glitches (e.g. the intro of LB1 Amiga gets stuck - bug // #3297883). Refer to MusicEntry::setSignal() in sound/music.cpp. + // FIXME: SSCI doesn't start playing at the very beginning + // of the stream, but at a fixed location a few commands later. + // That is probably why this signal isn't triggered + // immediately there. if (_soundVersion <= SCI_VERSION_0_LATE || _position._playTick || info.delta) { _signalSet = true; @@ -531,10 +540,15 @@ void MidiParser_SCI::parseNextEvent(EventInfo &info) { // Check if the hold ID marker is the same as the hold ID // marker set for that song by cmdSetSoundHold. // If it is, loop back, but don't stop notes when jumping. + // We need to wait for the delta of the current event before + // jumping, thus the jump will be performed on the next + // parseNextEvent() call, like with the signal set events. + // In LSL6, room 360, song 381, this ends up jumping forward + // one tick (the hold marker occurs at playtick 27, with + // _loopTick being 15 and the event itself having a delta of + // 13, total = 28) - bug #3614566. if (info.basic.param2 == _pSnd->hold) { - uint32 extraDelta = info.delta; - jumpToTick(_loopTick, false, false); - _nextEvent.delta += extraDelta; + _jumpToHoldTick = true; } break; case kUpdateCue: @@ -637,7 +651,14 @@ void MidiParser_SCI::parseNextEvent(EventInfo &info) { // (e.g. song 110, during the intro). The original interpreter // treats this case as an infinite loop (bug #3311911). if (_pSnd->loop || _pSnd->hold > 0) { - // We need to play it again... + // TODO: this jump is also vulnerable to the same lockup as + // the MIDI hold one above. However, we can't perform the + // jump on the next tick like with the MIDI hold jump above, + // as there aren't any subsequent MIDI events after this one. + // This assert is here to detect cases where the song ends + // up jumping forward, like with bug #3614566 (see above). + assert(_loopTick + info.delta < _position._playTick); + uint32 extraDelta = info.delta; jumpToTick(_loopTick); _nextEvent.delta += extraDelta; diff --git a/engines/sci/sound/midiparser_sci.h b/engines/sci/sound/midiparser_sci.h index d3fd337644..7bd68994c8 100644 --- a/engines/sci/sound/midiparser_sci.h +++ b/engines/sci/sound/midiparser_sci.h @@ -110,6 +110,7 @@ protected: int16 _signalToSet; bool _dataincAdd; int16 _dataincToAdd; + bool _jumpToHoldTick; bool _resetOnPause; bool _channelUsed[16]; diff --git a/engines/sci/sound/soundcmd.cpp b/engines/sci/sound/soundcmd.cpp index daba976f50..b0102a002b 100644 --- a/engines/sci/sound/soundcmd.cpp +++ b/engines/sci/sound/soundcmd.cpp @@ -530,17 +530,21 @@ void SoundCommandParser::processUpdateCues(reg_t obj) { } reg_t SoundCommandParser::kDoSoundSendMidi(int argc, reg_t *argv, reg_t acc) { + // The 4 parameter variant of this call is used in at least LSL1VGA, room + // 110 (Lefty's bar), to distort the music when Larry is drunk and stands + // up - bug #3614447. reg_t obj = argv[0]; byte channel = argv[1].toUint16() & 0xf; - byte midiCmd = argv[2].toUint16() & 0xff; + byte midiCmd = (argc == 5) ? argv[2].toUint16() & 0xff : 0xB0; // 0xB0: controller + uint16 controller = (argc == 5) ? argv[3].toUint16() : argv[2].toUint16(); + uint16 param = (argc == 5) ? argv[4].toUint16() : argv[3].toUint16(); - // TODO: first there is a 4-parameter variant of this call which needs to get reversed - // second the current code isn't 100% accurate, sierra sci does checks on the 4th parameter - if (argc == 4) - return acc; - - uint16 controller = argv[3].toUint16(); - uint16 param = argv[4].toUint16(); + if (argc == 4 && controller == 0xFF) { + midiCmd = 0xE0; // 0xE0: pitch wheel + uint16 pitch = CLIP<uint16>(argv[3].toSint16() + 0x2000, 0x0000, 0x3FFF); + controller = pitch & 0x7F; + param = pitch >> 7; + } debugC(kDebugLevelSound, "kDoSound(sendMidi): %04x:%04x, %d, %d, %d, %d", PRINT_REG(obj), channel, midiCmd, controller, param); if (channel) diff --git a/engines/sci/video/robot_decoder.cpp b/engines/sci/video/robot_decoder.cpp index 0337a8d306..a567ece2ea 100644 --- a/engines/sci/video/robot_decoder.cpp +++ b/engines/sci/video/robot_decoder.cpp @@ -210,7 +210,7 @@ void RobotDecoder::readNextPacket() { // Copy over the decompressed frame byte *inFrame = decompressedFrame; - byte *outFrame = (byte *)surface->pixels; + byte *outFrame = (byte *)surface->getPixels(); // Black out the surface memset(outFrame, 0, surface->w * surface->h); diff --git a/engines/sci/video/seq_decoder.cpp b/engines/sci/video/seq_decoder.cpp index a7b6346eca..54603ec1f1 100644 --- a/engines/sci/video/seq_decoder.cpp +++ b/engines/sci/video/seq_decoder.cpp @@ -119,7 +119,7 @@ const Graphics::Surface *SEQDecoder::SEQVideoTrack::decodeNextFrame() { _fileStream->seek(offset); if (frameType == kSeqFrameFull) { - byte *dst = (byte *)_surface->pixels + frameTop * SEQ_SCREEN_WIDTH + frameLeft; + byte *dst = (byte *)_surface->getBasePtr(frameLeft, frameTop); byte *linebuf = new byte[frameWidth]; @@ -133,7 +133,7 @@ const Graphics::Surface *SEQDecoder::SEQVideoTrack::decodeNextFrame() { } else { byte *buf = new byte[frameSize]; _fileStream->read(buf, frameSize); - decodeFrame(buf, rleSize, buf + rleSize, frameSize - rleSize, (byte *)_surface->pixels + SEQ_SCREEN_WIDTH * frameTop, frameLeft, frameWidth, frameHeight, colorKey); + decodeFrame(buf, rleSize, buf + rleSize, frameSize - rleSize, (byte *)_surface->getBasePtr(0, frameTop), frameLeft, frameWidth, frameHeight, colorKey); delete[] buf; } |