aboutsummaryrefslogtreecommitdiff
path: root/engines/sci
diff options
context:
space:
mode:
Diffstat (limited to 'engines/sci')
-rw-r--r--engines/sci/detection_tables.h17
-rw-r--r--engines/sci/engine/kpathing.cpp2
-rw-r--r--engines/sci/engine/kstring.cpp2
-rw-r--r--engines/sci/engine/kvideo.cpp4
-rw-r--r--engines/sci/graphics/frameout.cpp12
-rw-r--r--engines/sci/graphics/maciconbar.cpp6
-rw-r--r--engines/sci/graphics/ports.cpp4
-rw-r--r--engines/sci/graphics/screen.cpp4
-rw-r--r--engines/sci/sound/midiparser_sci.cpp29
-rw-r--r--engines/sci/sound/midiparser_sci.h1
-rw-r--r--engines/sci/sound/soundcmd.cpp20
-rw-r--r--engines/sci/video/robot_decoder.cpp2
-rw-r--r--engines/sci/video/seq_decoder.cpp4
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;
}