aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--AUTHORS3
-rw-r--r--README4
-rw-r--r--backends/graphics/surfacesdl/surfacesdl-graphics.cpp41
-rw-r--r--backends/graphics/surfacesdl/surfacesdl-graphics.h2
-rw-r--r--backends/platform/symbian/AdaptAllMMPs.pl2
-rw-r--r--backends/platform/symbian/BuildPackageUpload_LocalSettings.pl42
-rwxr-xr-xdevtools/credits.pl4
-rw-r--r--engines/access/char.cpp2
-rw-r--r--engines/access/screen.cpp3
-rw-r--r--engines/access/sound.cpp33
-rw-r--r--engines/access/sound.h13
-rw-r--r--engines/agi/console.cpp2
-rw-r--r--engines/agi/cycle.cpp20
-rw-r--r--engines/agi/op_cmd.cpp16
-rw-r--r--engines/agi/opcodes.cpp4
-rw-r--r--engines/agi/opcodes.h2
-rw-r--r--engines/sword25/configure.engine2
-rw-r--r--gui/credits.h2
18 files changed, 130 insertions, 67 deletions
diff --git a/AUTHORS b/AUTHORS
index 8f814fde5e..f5d62c2e14 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -738,3 +738,6 @@ Special thanks to
two Lost Files of Sherlock Holmes games. James M. Ferguson and Barry
Duncan for their tenacious efforts to recover the sources.
+ The mindFactory team for writing Broken Sword 2.5, a splendid fan-made
+ sequel, and for sharing the source code with us.
+
diff --git a/README b/README
index 2a1d7c390e..a34856c81e 100644
--- a/README
+++ b/README
@@ -160,7 +160,7 @@ reproducible, and still occurs in the latest git/Daily build version.
Also check the known problems list (below) and the compatibility list
on our website for that game, to ensure the issue is not already known:
- http://www.scummvm.org/compatibility_stable.php
+ http://scummvm.org/compatibility/
Please do not report bugs on games that are not listed as being
completeable in the 'Supported Games' section, or compatibility list. We
@@ -2434,7 +2434,7 @@ currently we have only x86 MMX optimized versions, and they will not
compile on other processors.
On Win9x/NT/XP, you can define USE_WINDBG and attach WinDbg to browse
-debug messages (see http://www.sysinternals.com/ntw2k/freeware/debugview.shtml).
+debug messages (see https://technet.microsoft.com/en-us/sysinternals/debugview.aspx).
GCC and MinGW32:
diff --git a/backends/graphics/surfacesdl/surfacesdl-graphics.cpp b/backends/graphics/surfacesdl/surfacesdl-graphics.cpp
index 9cb14525ee..e45773e5d7 100644
--- a/backends/graphics/surfacesdl/surfacesdl-graphics.cpp
+++ b/backends/graphics/surfacesdl/surfacesdl-graphics.cpp
@@ -125,6 +125,7 @@ SurfaceSdlGraphicsManager::SurfaceSdlGraphicsManager(SdlEventSource *sdlEventSou
_hwscreen(0),
#if SDL_VERSION_ATLEAST(2, 0, 0)
_renderer(nullptr), _screenTexture(nullptr),
+ _viewportX(0), _viewportY(0), _mouseScaleX(1.0f), _mouseScaleY(1.0f),
#else
_originalBitsPerPixel(0),
#endif
@@ -2353,6 +2354,16 @@ void SurfaceSdlGraphicsManager::notifyVideoExpose() {
}
void SurfaceSdlGraphicsManager::transformMouseCoordinates(Common::Point &point) {
+#if SDL_VERSION_ATLEAST(2, 0, 0)
+ // In fullscreen mode we can easily get coordinates outside the actual
+ // screen area. For example, if black bars are added left/right we can end
+ // up with negative x coordinates if the user moves the mouse inside the
+ // black bar. Here, we post process the received cooridnates to give the
+ // user the feeling the black bars do not exist.
+ point.x = (int)((point.x + _viewportX) * _mouseScaleX);
+ point.y = (int)((point.y + _viewportY) * _mouseScaleY);
+#endif
+
if (!_overlayVisible) {
point.x /= _videoMode.scaleFactor;
point.y /= _videoMode.scaleFactor;
@@ -2380,7 +2391,8 @@ void SurfaceSdlGraphicsManager::deinitializeRenderer() {
SDL_Surface *SurfaceSdlGraphicsManager::SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags) {
deinitializeRenderer();
- if (!_window->createWindow(width, height, (flags & SDL_FULLSCREEN) ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0)) {
+ const bool isFullscreen = (flags & SDL_FULLSCREEN) != 0;
+ if (!_window->createWindow(width, height, isFullscreen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0)) {
return nullptr;
}
@@ -2390,6 +2402,33 @@ SDL_Surface *SurfaceSdlGraphicsManager::SDL_SetVideoMode(int width, int height,
return nullptr;
}
+ // We set the logical renderer size to the requested resolution in
+ // fullscreen. This assures that SDL2 adds black bars if needed to prevent
+ // stretching.
+ if (isFullscreen && SDL_RenderSetLogicalSize(_renderer, width, height) < 0) {
+ deinitializeRenderer();
+ return nullptr;
+ }
+
+ // To provide smooth mouse handling in case black borders are added, we
+ // obtain the actual window size and the internal renderer scaling.
+ // Based on this we calculate scale factors to scale received mouse
+ // coordinates into actual screen area coordinates.
+ float scaleX = 0, scaleY = 0;
+ SDL_RenderGetScale(_renderer, &scaleX, &scaleY);
+ int windowWidth = 1, windowHeight = 1;
+ SDL_GetWindowSize(_window->getSDLWindow(), &windowWidth, &windowHeight);
+
+ _mouseScaleX = (width * scaleX) / windowWidth;
+ _mouseScaleY = (height * scaleY) / windowHeight;
+
+ // Obtain viewport top left coordinates to transform received coordinates
+ // into visible area coordinates (i.e. including black borders).
+ SDL_Rect viewport;
+ SDL_RenderGetViewport(_renderer, &viewport);
+ _viewportX = viewport.x;
+ _viewportY = viewport.y;
+
_screenTexture = SDL_CreateTexture(_renderer, SDL_PIXELFORMAT_RGB565, SDL_TEXTUREACCESS_STREAMING, width, height);
if (!_screenTexture) {
deinitializeRenderer();
diff --git a/backends/graphics/surfacesdl/surfacesdl-graphics.h b/backends/graphics/surfacesdl/surfacesdl-graphics.h
index 2431ce8664..07ff4e5926 100644
--- a/backends/graphics/surfacesdl/surfacesdl-graphics.h
+++ b/backends/graphics/surfacesdl/surfacesdl-graphics.h
@@ -171,6 +171,8 @@ protected:
* around this API to keep the code paths as close as possible. */
SDL_Renderer *_renderer;
SDL_Texture *_screenTexture;
+ int _viewportX, _viewportY;
+ float _mouseScaleX, _mouseScaleY;
void deinitializeRenderer();
SDL_Surface *SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags);
diff --git a/backends/platform/symbian/AdaptAllMMPs.pl b/backends/platform/symbian/AdaptAllMMPs.pl
index 6b9f918a51..a836b764d2 100644
--- a/backends/platform/symbian/AdaptAllMMPs.pl
+++ b/backends/platform/symbian/AdaptAllMMPs.pl
@@ -56,6 +56,7 @@ chdir("../../../");
"mmp/scummvm_lastexpress.mmp",
"mmp/scummvm_mads.mmp",
"mmp/scummvm_prince.mmp",
+ "mmp/scummvm_sherlock.mmp",
"mmp/scummvm_sword25.mmp",
"mmp/scummvm_testbed.mmp",
"mmp/scummvm_zvision.mmp",
@@ -203,6 +204,7 @@ ParseModule("_lastexpress","lastexpress", \@section_empty);
ParseModule("_m4", "m4", \@section_empty);
ParseModule("_mads" ,"mads", \@section_empty);
ParseModule("_prince" ,"prince", \@section_empty);
+ParseModule("_sherlock" ,"sherlock", \@section_empty);
ParseModule("_sword25" ,"sword25", \@section_empty);
ParseModule("_testbed" ,"testbed", \@section_empty);
ParseModule("_zvision" ,"zvision", \@section_empty);
diff --git a/backends/platform/symbian/BuildPackageUpload_LocalSettings.pl b/backends/platform/symbian/BuildPackageUpload_LocalSettings.pl
index 8c19631524..10bcf0340a 100644
--- a/backends/platform/symbian/BuildPackageUpload_LocalSettings.pl
+++ b/backends/platform/symbian/BuildPackageUpload_LocalSettings.pl
@@ -1,36 +1,32 @@
##################################################################################################################
+#### sword25 ignored because of incompatible resolution 800*600
@WorkingEngines = qw(
- agos agi cine cge composer cruise draci dreamweb
- drascula hugo gob groovie hopkins kyra lastexpress
- lure made mohawk mortevielle neverhood parallaction
- pegasus queen saga sci scumm sky sword1 sword2
- teenagent tinsel toltecs tony toon touche tsage
- tucker voyeur wintermute
- access avalanche bbvs cge2 fullpipe mads prince
- testbed zvision
+ access agi agos avalanche bbvs cge cge2
+ cine composer cruise draci drascula
+ dreamweb fullpipe gob groovie hopkins
+ hugo kyra lastexpress lure made mads
+ mohawk mortevielle neverhood parallaction
+ pegasus prince queen saga sci scumm
+ sherlock sky sword1 sword2 teenagent
+ testbed tinsel toltecs tony toon touche
+ tsage tucker voyeur wintermute zvision
);
-
-#### sword25 yet not added
-
-#### In progress engines are :
-#### access avalanche bbvs cge2 fullpipe mads prince
-#### testbed zvision
@WorkingEngines_1st = qw(
- cine composer cruise drascula groovie
- lastexpress made parallaction queen saga
- scumm touche tucker wintermute voyeur
- access avalanche cge2 zvision
+ access agi agos cge2 cine composer cruise
+ drascula gob groovie kyra lastexpress made
+ neverhood parallaction queen saga scumm
+ touche tucker voyeur wintermute
);
@WorkingEngines_2nd = qw(
- agi agos cge draci dreamweb gob hopkins
- hugo kyra lure mohawk mortevielle neverhood
- pegasus sci sky sword1 sword2 teenagent
- tinsel tsage toltecs tony toon
- bbvs fullpipe mads prince testbed
+ avalanche bbvs cge draci dreamweb fullpipe
+ hopkins hugo lure mads mohawk mortevielle
+ pegasus prince sci sherlock sky sword1 sword2
+ teenagent testbed tinsel toltecs tony toon
+ tsage zvision
);
#### sword25 yet not added
diff --git a/devtools/credits.pl b/devtools/credits.pl
index f5d8542ae8..1a038c7dee 100755
--- a/devtools/credits.pl
+++ b/devtools/credits.pl
@@ -1309,6 +1309,10 @@ begin_credits("Credits");
"Electronic Arts for providing the source code of the two Lost Files of Sherlock Holmes games. ".
"James M. Ferguson and Barry Duncan for their tenacious efforts to recover the sources.");
+ add_paragraph(
+ "The mindFactory team for writing Broken Sword 2.5, a splendid fan-made sequel, and for sharing ".
+ "the source code with us.");
+
end_section();
end_credits();
diff --git a/engines/access/char.cpp b/engines/access/char.cpp
index 3e95208fe5..2afb81db30 100644
--- a/engines/access/char.cpp
+++ b/engines/access/char.cpp
@@ -31,7 +31,7 @@ CharEntry::CharEntry(const byte *data, AccessEngine *vm) {
Common::MemoryReadStream s(data, 999);
_charFlag = s.readByte();
- if (vm->getGameID() != GType_Amazon || vm->isDemo()) {
+ if (vm->getGameID() != GType_Amazon || !vm->isCD()) {
_screenFile.load(s);
_estabIndex = s.readSint16LE();
} else {
diff --git a/engines/access/screen.cpp b/engines/access/screen.cpp
index e6d43d0156..b46f31f65a 100644
--- a/engines/access/screen.cpp
+++ b/engines/access/screen.cpp
@@ -89,6 +89,9 @@ void Screen::setPanel(int num) {
}
void Screen::updateScreen() {
+ if (_vm->_startup > 0)
+ return;
+
// Merge the dirty rects
mergeDirtyRects();
diff --git a/engines/access/sound.cpp b/engines/access/sound.cpp
index b3317cee5f..38f544de4e 100644
--- a/engines/access/sound.cpp
+++ b/engines/access/sound.cpp
@@ -51,11 +51,20 @@ void SoundManager::clearSounds() {
_mixer->stopHandle(_effectsHandle);
while (_queue.size()) {
- delete _queue[0];
+ delete _queue[0]._stream;
_queue.remove_at(0);
}
}
+bool SoundManager::isSoundQueued(int soundId) const {
+ for (uint idx = 0; idx < _queue.size(); ++idx) {
+ if (_queue[idx]._soundId == soundId)
+ return true;
+ }
+
+ return false;
+}
+
void SoundManager::loadSoundTable(int idx, int fileNum, int subfile, int priority) {
debugC(1, kDebugSound, "loadSoundTable(%d, %d, %d)", idx, fileNum, subfile);
@@ -77,12 +86,15 @@ Resource *SoundManager::loadSound(int fileNum, int subfile) {
void SoundManager::playSound(int soundIndex, bool loop) {
debugC(1, kDebugSound, "playSound(%d, %d)", soundIndex, loop);
+ if (isSoundQueued(soundIndex))
+ // Prevent duplicate copies of a sound from being queued
+ return;
int priority = _soundTable[soundIndex]._priority;
- playSound(_soundTable[soundIndex]._res, priority, loop);
+ playSound(_soundTable[soundIndex]._res, priority, loop, soundIndex);
}
-void SoundManager::playSound(Resource *res, int priority, bool loop) {
+void SoundManager::playSound(Resource *res, int priority, bool loop, int soundIndex) {
debugC(1, kDebugSound, "playSound");
byte *resourceData = res->data();
@@ -109,7 +121,7 @@ void SoundManager::playSound(Resource *res, int priority, bool loop) {
byte internalSampleRate = resourceData[5];
int sampleSize = READ_LE_UINT16(resourceData + 7);
- assert( (sampleSize + 32) == res->_size);
+ assert( (sampleSize + 32) <= res->_size);
int sampleRate = 0;
switch (internalSampleRate) {
@@ -139,14 +151,15 @@ void SoundManager::playSound(Resource *res, int priority, bool loop) {
error("Unknown format");
if (loop) {
- _queue.push_back(new Audio::LoopingAudioStream(audioStream, 0, DisposeAfterUse::NO));
+ _queue.push_back(QueuedSound(new Audio::LoopingAudioStream(audioStream, 0,
+ DisposeAfterUse::NO), soundIndex));
} else {
- _queue.push_back(audioStream);
+ _queue.push_back(QueuedSound(audioStream, soundIndex));
}
if (!_mixer->isSoundHandleActive(_effectsHandle))
_mixer->playStream(Audio::Mixer::kSFXSoundType, &_effectsHandle,
- _queue[0], -1, _mixer->kMaxChannelVolume, 0,
+ _queue[0]._stream, -1, _mixer->kMaxChannelVolume, 0,
DisposeAfterUse::NO);
}
@@ -156,12 +169,12 @@ void SoundManager::checkSoundQueue() {
if (_queue.empty() || _mixer->isSoundHandleActive(_effectsHandle))
return;
- delete _queue[0];
+ delete _queue[0]._stream;
_queue.remove_at(0);
- if (_queue.size() && _queue[0])
+ if (_queue.size() && _queue[0]._stream)
_mixer->playStream(Audio::Mixer::kSFXSoundType, &_effectsHandle,
- _queue[0], -1, _mixer->kMaxChannelVolume, 0,
+ _queue[0]._stream, -1, _mixer->kMaxChannelVolume, 0,
DisposeAfterUse::NO);
}
diff --git a/engines/access/sound.h b/engines/access/sound.h
index e11a6b9730..b372e566d2 100644
--- a/engines/access/sound.h
+++ b/engines/access/sound.h
@@ -45,15 +45,24 @@ struct SoundEntry {
};
class SoundManager {
+ struct QueuedSound {
+ Audio::AudioStream *_stream;
+ int _soundId;
+
+ QueuedSound() : _stream(nullptr), _soundId(-1) {}
+ QueuedSound(Audio::AudioStream *stream, int soundId) : _stream(stream), _soundId(soundId) {}
+ };
private:
AccessEngine *_vm;
Audio::Mixer *_mixer;
Audio::SoundHandle _effectsHandle;
- Common::Array<Audio::AudioStream *> _queue;
+ Common::Array<QueuedSound> _queue;
void clearSounds();
- void playSound(Resource *res, int priority, bool loop);
+ void playSound(Resource *res, int priority, bool loop, int soundIndex = -1);
+
+ bool isSoundQueued(int soundId) const;
public:
Common::Array<SoundEntry> _soundTable;
bool _playingSound;
diff --git a/engines/agi/console.cpp b/engines/agi/console.cpp
index 7995938d99..89838b3be9 100644
--- a/engines/agi/console.cpp
+++ b/engines/agi/console.cpp
@@ -143,7 +143,6 @@ bool Console::Cmd_Version(int argc, const char **argv) {
const char *wordScanPtr = NULL;
const char *wordStartPtr = NULL;
const char *versionStartPtr = NULL;
- const char *versionPtr = NULL;
int wordLen = 0;
char curChar = 0;
int versionLen = 0;
@@ -179,7 +178,6 @@ bool Console::Cmd_Version(int argc, const char **argv) {
// Now scan this text for version information
wordScanPtr = scriptTextPtr;
- versionPtr = NULL;
do {
curChar = *wordScanPtr;
diff --git a/engines/agi/cycle.cpp b/engines/agi/cycle.cpp
index 6b34605364..145b827160 100644
--- a/engines/agi/cycle.cpp
+++ b/engines/agi/cycle.cpp
@@ -84,13 +84,23 @@ void AgiEngine::newRoom(int n) {
break;
}
- _game.vars[vBorderTouchEgo] = 0;
- setflag(fNewRoomExec, true);
+ if (getVersion() < 0x2000) {
+ warning("STUB: NewRoom(%d)", n);
- _game.exitAllLogics = true;
+ v->flags &= ~fDidntMove;
+ // animateObject(0);
+ agiLoadResource(rVIEW, _game.viewTable[0].currentView);
+ setView(&_game.viewTable[0], _game.viewTable[0].currentView);
- writeStatus();
- writePrompt();
+ } else {
+ _game.vars[vBorderTouchEgo] = 0;
+ setflag(fNewRoomExec, true);
+
+ _game.exitAllLogics = true;
+
+ writeStatus();
+ writePrompt();
+ }
}
void AgiEngine::resetControllers() {
diff --git a/engines/agi/op_cmd.cpp b/engines/agi/op_cmd.cpp
index 662454f3c1..bf2a2ed77b 100644
--- a/engines/agi/op_cmd.cpp
+++ b/engines/agi/op_cmd.cpp
@@ -1711,22 +1711,6 @@ void cmdCallV1(AgiGame *state, uint8 *p) {
_v[13] = 1;
}
-void cmdNewRoomV1(AgiGame *state, uint8 *p) {
- warning("cmdNewRoomV1()");
- state->_vm->agiLoadResource(rLOGIC, p0);
- state->max_logics = 1;
- state->logic_list[1] = p0;
- _v[13] = 1;
-}
-
-void cmdNewRoomVV1(AgiGame *state, uint8 *p) {
- warning("cmdNewRoomVV1()");
- state->_vm->agiLoadResource(rLOGIC, _v[p0]);
- state->max_logics = 1;
- state->logic_list[1] = _v[p0];
- _v[13] = 1;
-}
-
void cmdUnknown(AgiGame *state, uint8 *p) {
warning("Skipping unknown opcode %2X", *(code + ip - 1));
}
diff --git a/engines/agi/opcodes.cpp b/engines/agi/opcodes.cpp
index 621fbb8e82..0d7d180ec9 100644
--- a/engines/agi/opcodes.cpp
+++ b/engines/agi/opcodes.cpp
@@ -60,7 +60,7 @@ AgiInstruction insV1[] = {
{ "subv", "vv", &cmdSubV }, // 08
{ "load.view", "n", &cmdLoadView }, // 09
{ "animate.obj", "n", &cmdAnimateObj }, // 0A
- { "new.room", "n", &cmdNewRoomV1 }, // 0B
+ { "new.room", "n", &cmdNewRoom }, // 0B
{ "draw.pic", "v", &cmdDrawPicV1 }, // 0C
{ "print", "s", &cmdPrint }, // 0D TODO
{ "status", "", &cmdStatus }, // 0E TODO
@@ -112,7 +112,7 @@ AgiInstruction insV1[] = {
{ "set.v", "v", &cmdSetV }, // 3C
{ "reset.v", "v", &cmdResetV }, // 3D
{ "toggle.v", "v", &cmdToggleV }, // 3E
- { "new.room.v", "v", &cmdNewRoomVV1 }, // 3F TODO
+ { "new.room.v", "v", &cmdNewRoom }, // 3F
{ "call", "n", &cmdCallV1 }, // 40 TODO
{ "quit", "", &cmdQuitV1 }, // 41
{ "set.speed", "v", &cmdSetSpeed }, // 42
diff --git a/engines/agi/opcodes.h b/engines/agi/opcodes.h
index 6bd31c339a..5466bc6ee0 100644
--- a/engines/agi/opcodes.h
+++ b/engines/agi/opcodes.h
@@ -237,8 +237,6 @@ void cmdAdjEgoMoveToXY(AgiGame *state, uint8 *p);
void cmdSetSpeed(AgiGame *state, uint8 *p);
void cmdSetItemView(AgiGame *state, uint8 *p);
void cmdCallV1(AgiGame *state, uint8 *p);
-void cmdNewRoomV1(AgiGame *state, uint8 *p);
-void cmdNewRoomVV1(AgiGame *state, uint8 *p);
void cmdUnknown(AgiGame *state, uint8 *p);
void condEqual(AgiGame *state, uint8 *p);
diff --git a/engines/sword25/configure.engine b/engines/sword25/configure.engine
index 1729bbeb33..6a9428c758 100644
--- a/engines/sword25/configure.engine
+++ b/engines/sword25/configure.engine
@@ -1,3 +1,3 @@
# This file is included from the main "configure" script
# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
-add_engine sword25 "Broken Sword 2.5" no "" "" "png zlib 16bit"
+add_engine sword25 "Broken Sword 2.5" yes "" "" "png zlib 16bit"
diff --git a/gui/credits.h b/gui/credits.h
index 2e66a7065e..72fe3fa951 100644
--- a/gui/credits.h
+++ b/gui/credits.h
@@ -889,5 +889,7 @@ static const char *credits[] = {
"C0""",
"C0""Electronic Arts IP Preservation Team, particularly Stefan Serbicki, and Vasyl Tsvirkunov of Electronic Arts for providing the source code of the two Lost Files of Sherlock Holmes games. James M. Ferguson and Barry Duncan for their tenacious efforts to recover the sources.",
"C0""",
+"C0""The mindFactory team for writing Broken Sword 2.5, a splendid fan-made sequel, and for sharing the source code with us.",
+"C0""",
"",
};