[Scummvm-git-logs] scummvm master -> 30717e261a1f0a55bcd9067d0ea2191d3a165d3d
neuromancer
noreply at scummvm.org
Thu Jun 25 12:55:05 UTC 2026
This automated email contains information about 3 new commits which have been
pushed to the 'scummvm' repo located at https://api.github.com/repos/scummvm/scummvm .
Summary:
5a77120d68 EEM: better palette cycling in map of EEM2 Mac
f25af05a60 EEM: correctly place hotspots in EEM2 Mac
30717e261a EEM: voiceover support for EEM2 Mac
Commit: 5a77120d68d04d2d366831a49e7adf95511d826a
https://github.com/scummvm/scummvm/commit/5a77120d68d04d2d366831a49e7adf95511d826a
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2026-06-25T14:54:44+02:00
Commit Message:
EEM: better palette cycling in map of EEM2 Mac
Changed paths:
engines/eem/ui.cpp
diff --git a/engines/eem/ui.cpp b/engines/eem/ui.cpp
index 89f88c1431e..fff43073d73 100644
--- a/engines/eem/ui.cpp
+++ b/engines/eem/ui.cpp
@@ -199,6 +199,8 @@ bool readBigMapEntryInfo(const byte *entry, bool floppy, bool macintosh,
return true;
}
+const uint32 kMacMapColorCycleDelayMs = 25 * 1000 / 60;
+
bool loadMacBigMapPixels(Common::Array<byte> &mapPixels,
uint16 &mapW, uint16 &mapH) {
DBDArchive bigMapArchive;
@@ -3761,12 +3763,6 @@ void EEMEngine::doBigMap() {
if (!_mystery.isLoaded())
return;
- if (isMacintosh()) {
- for (uint i = 0; i < _mystery.numSites() &&
- i < Mystery::kVisitedSiteCap; i++)
- _mystery._onSites[i] = 1;
- }
-
if (isLondon()) {
_mystery._pendingSiteJump = 0;
_mystery._siteReturnDepth = 0;
@@ -3782,6 +3778,7 @@ void EEMEngine::doBigMap() {
const uint32 mapStartTick = g_system->getMillis();
drawBigMapOverview(0);
uint32 mapLastTick = mapStartTick;
+ uint32 mapLastCycleTick = mapStartTick;
const bool mac = isMacintosh();
const Common::Rect bigMapWindowBase(0, 0, 247, 192);
@@ -3835,12 +3832,24 @@ void EEMEngine::doBigMap() {
break;
const uint32 now = g_system->getMillis();
- if (now - mapLastTick >= 100) {
+ if (mac && isLondon() &&
+ now - mapLastCycleTick >= kMacMapColorCycleDelayMs) {
+ mapLastCycleTick = now;
+ // Mac `_UpdateBigMap` rotates ColorTable entries 0xef..0xf2
+ // and 0xfc..0xff. Redraw immediately so Mac endpoint art maps
+ // its black pixels to the current black slot after the cycle.
+ cyclePaletteRangeReverse(0xef, 0xf2);
+ cyclePaletteRangeReverse(0xfc, 0xff);
+ drawBigMapOverview(now - mapStartTick);
+ mapLastTick = now;
+ } else if (now - mapLastTick >= 100) {
mapLastTick = now;
drawBigMapOverview(now - mapStartTick);
if (isLondon()) {
- cyclePaletteRangeReverse(0xf4, 0xf9);
- cyclePaletteRangeReverse(0xfa, 0xff);
+ if (!mac) {
+ cyclePaletteRangeReverse(0xf4, 0xf9);
+ cyclePaletteRangeReverse(0xfa, 0xff);
+ }
} else {
cyclePaletteRangeReverse(0xf7, 0xfa);
cyclePaletteRangeReverse(0xfb, 0xfe);
@@ -3902,6 +3911,7 @@ void EEMEngine::doBigMap() {
const uint32 detailStartTick = g_system->getMillis();
drawBigMapDetail(scrollX, scrollY, mapPixels, mapW, mapH, 0);
uint32 detailLastTick = detailStartTick;
+ uint32 detailLastCycleTick = detailStartTick;
bool returnToOverview = false;
const Common::Rect returnBase(252, 43, kScreenWidth, kScreenHeight);
@@ -3949,7 +3959,7 @@ void EEMEngine::doBigMap() {
while (!shouldQuit() && !returnToOverview) {
Common::Event ev;
bool dirty = false;
- bool frameTick = false;
+ bool cycleTick = false;
while (g_system->getEventManager()->pollEvent(ev)) {
if (ev.type == Common::EVENT_QUIT ||
ev.type == Common::EVENT_RETURN_TO_LAUNCHER) {
@@ -4085,15 +4095,28 @@ void EEMEngine::doBigMap() {
if (now - detailLastTick >= 100) {
detailLastTick = now;
dirty = true;
- frameTick = true;
+ }
+ if (isLondon()) {
+ const uint32 cycleDelay = mac ? kMacMapColorCycleDelayMs : 100;
+ if (now - detailLastCycleTick >= cycleDelay) {
+ detailLastCycleTick = now;
+ cycleTick = true;
+ dirty = true;
+ }
+ }
+ if (cycleTick && isLondon()) {
+ if (mac) {
+ cyclePaletteRangeReverse(0xe9, 0xeb);
+ cyclePaletteRangeReverse(0xec, 0xef);
+ cyclePaletteRangeReverse(0xf0, 0xf2);
+ } else {
+ cyclePaletteRangeReverse(0xee, 0xf2);
+ cyclePaletteRangeReverse(0xea, 0xed);
+ }
}
if (dirty)
drawBigMapDetail(scrollX, scrollY, mapPixels, mapW, mapH,
now - detailStartTick);
- if (frameTick && isLondon()) {
- cyclePaletteRangeReverse(0xee, 0xf2);
- cyclePaletteRangeReverse(0xea, 0xed);
- }
g_system->updateScreen();
g_system->delayMillis(10);
}
@@ -4399,8 +4422,11 @@ void EEMEngine::drawBigMapOverview(uint32 elapsedMs) {
scratch.clear();
Picture frame;
- if (_picsArchive.getPicture(0x42, frame))
+ if (_picsArchive.getPicture(0x42, frame)) {
+ if (mac)
+ remapMacSurfaceEndpoints(frame.surface, getMacSpritePaletteMap());
scratch.simpleBlitFrom(frame.surface);
+ }
// Marker PICs from `_main`:
// EEM1 CD @ 1a35:0f59: Done=0x20d, Site=0xc5, Crime=0xc6.
@@ -4463,9 +4489,14 @@ void EEMEngine::drawBigMapOverview(uint32 elapsedMs) {
const uint frameIdx = bigMapPartnerFrameAtTick((uint)mapAnim.size(),
elapsedMs, isLondon());
- blitAnimFrameAnchored(scratch.surfacePtr(), mapAnim[frameIdx],
- mac ? scaleX(0xfd) : 0xfd,
- mac ? scaleY(0x50) : 0x50);
+ const int anchorX = mac ? scaleX(0xfd) : 0xfd;
+ const int anchorY = mac ? scaleY(0x50) : 0x50;
+ if (mac)
+ blitMacAnimFrameAnchored(scratch.surfacePtr(), mapAnim[frameIdx],
+ anchorX, anchorY);
+ else
+ blitAnimFrameAnchored(scratch.surfacePtr(), mapAnim[frameIdx],
+ anchorX, anchorY);
}
g_system->copyRectToScreen(scratch.getPixels(), scratch.pitch,
Commit: f25af05a60d12e9fabc8490b4b5ad15f4c1aefc9
https://github.com/scummvm/scummvm/commit/f25af05a60d12e9fabc8490b4b5ad15f4c1aefc9
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2026-06-25T14:54:44+02:00
Commit Message:
EEM: correctly place hotspots in EEM2 Mac
Changed paths:
engines/eem/clues.cpp
engines/eem/site.cpp
diff --git a/engines/eem/clues.cpp b/engines/eem/clues.cpp
index 6eaa7bc151f..398e1064b15 100644
--- a/engines/eem/clues.cpp
+++ b/engines/eem/clues.cpp
@@ -377,10 +377,9 @@ void EEMEngine::doChoosePartner() {
void EEMEngine::playLondonInitCluesAnim(uint16 caseType, const Picture &bg,
bool haveBriefingBg) {
const bool mac = isMacintosh();
- const uint introAni = mac ? 0x17
+ const uint introAni = mac ? (_partner == kPartnerJake ? 0x18 : 0x1c)
: (_partner == kPartnerJake ? 0x18 : 0x71);
- const uint introScript = mac ? (_partner == kPartnerJake ? 0x18 : 0x1c)
- : 0x18;
+ const uint introScript = mac ? 0x17 : 0x18;
const int kAnchorX = mac ? 0x14c : 0xd2;
const int kAnchorY = mac ? (_partner == kPartnerJake ? 0x78 : 0x76)
: 0x3f;
diff --git a/engines/eem/site.cpp b/engines/eem/site.cpp
index 57afddc5199..22df42a435a 100644
--- a/engines/eem/site.cpp
+++ b/engines/eem/site.cpp
@@ -1903,7 +1903,7 @@ int SiteScreen::hotspotAtPoint(uint siteNum, int x, int y) const {
const bool compact = _vm &&
(_vm->isFloppy() || (_mystery && _mystery->usesCompactMacData()));
const uint stride = compact ? 8 : 14;
- const bool mac = _vm && _mystery && _mystery->usesCompactMacData();
+ const bool mac = _vm && _vm->isMacintosh();
for (uint i = 0; i < count; i++) {
const byte *r = spots + i * stride;
Common::Rect rect;
Commit: 30717e261a1f0a55bcd9067d0ea2191d3a165d3d
https://github.com/scummvm/scummvm/commit/30717e261a1f0a55bcd9067d0ea2191d3a165d3d
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2026-06-25T14:54:44+02:00
Commit Message:
EEM: voiceover support for EEM2 Mac
Changed paths:
engines/eem/audio.cpp
engines/eem/audio.h
engines/eem/site.cpp
diff --git a/engines/eem/audio.cpp b/engines/eem/audio.cpp
index b84844d9712..5db6134304e 100644
--- a/engines/eem/audio.cpp
+++ b/engines/eem/audio.cpp
@@ -88,6 +88,93 @@ uint16 macSndResourceIdForPath(const Common::Path &path) {
return 0;
}
+Audio::SeekableAudioStream *makeMacCsndStream(Common::SeekableReadStream *stream,
+ DisposeAfterUse::Flag disposeAfterUse) {
+ if (!stream)
+ return nullptr;
+
+ if (stream->size() < 4) {
+ if (disposeAfterUse == DisposeAfterUse::YES)
+ delete stream;
+ warning("makeMacCsndStream: resource too short");
+ return nullptr;
+ }
+
+ const uint32 decodedSize = stream->readUint32BE();
+ const uint32 packedSize = (uint32)(stream->size() - stream->pos());
+ Common::Array<byte> packed;
+ packed.resize(packedSize);
+ if (stream->read(packed.data(), packedSize) != packedSize) {
+ if (disposeAfterUse == DisposeAfterUse::YES)
+ delete stream;
+ warning("makeMacCsndStream: short packed read (%u bytes)", packedSize);
+ return nullptr;
+ }
+ if (disposeAfterUse == DisposeAfterUse::YES)
+ delete stream;
+
+ byte *decoded = (byte *)malloc(decodedSize);
+ if (!decoded) {
+ warning("makeMacCsndStream: oom (%u bytes)", decodedSize);
+ return nullptr;
+ }
+
+ uint32 src = 0;
+ uint32 dst = 0;
+ bool ok = true;
+ while (ok && dst < decodedSize && src < packedSize) {
+ byte flags = packed[src++];
+ for (uint bit = 0; bit < 8 && dst < decodedSize; bit++, flags >>= 1) {
+ if (flags & 1) {
+ if (src >= packedSize) {
+ ok = false;
+ break;
+ }
+ decoded[dst++] = packed[src++];
+ } else {
+ if (src + 1 >= packedSize) {
+ ok = false;
+ break;
+ }
+ const uint16 token = ((uint16)packed[src] << 8) | packed[src + 1];
+ src += 2;
+ int32 copyPos = (int32)dst + (int32)(token & 0x0fff) - 0x1000;
+ uint count = ((token >> 12) & 0x0f) + 3;
+ while (count-- && dst < decodedSize) {
+ if (copyPos < 0 || (uint32)copyPos >= dst) {
+ ok = false;
+ break;
+ }
+ decoded[dst++] = decoded[copyPos++];
+ }
+ }
+ }
+ }
+
+ if (!ok || dst != decodedSize) {
+ warning("makeMacCsndStream: decoded %u of %u bytes", dst, decodedSize);
+ free(decoded);
+ return nullptr;
+ }
+
+ if (decodedSize != 0) {
+ byte acc = decoded[0];
+ for (uint32 i = 1; i < decodedSize; i++) {
+ acc = (byte)(acc + decoded[i]);
+ decoded[i] = acc;
+ }
+ }
+
+ Common::MemoryReadStream *sndStream =
+ new Common::MemoryReadStream(decoded, decodedSize,
+ DisposeAfterUse::YES);
+ Audio::SeekableAudioStream *audioStream =
+ Audio::makeMacSndStream(sndStream, DisposeAfterUse::YES);
+ if (!audioStream)
+ delete sndStream;
+ return audioStream;
+}
+
AudioPlayer::~AudioPlayer() {
stopAll();
}
@@ -202,12 +289,8 @@ bool AudioPlayer::initMysterySounds(uint mysteryNum) {
cleanMysterySounds();
- if (_isMacintosh) {
- debugC(2, kDebugSound,
- "AudioPlayer: Mac release has no SDB/SDX bundle for mystery %u",
- mysteryNum);
- return true;
- }
+ if (_isMacintosh)
+ return initMacMysterySounds(mysteryNum);
if (!readSdxIndex(sdxPath)) {
_sdxIndex.clear();
@@ -224,9 +307,41 @@ void AudioPlayer::cleanMysterySounds() {
stopSpool();
_sdxIndex.clear();
_sdbPath = Common::Path();
+ _macMysterySoundPath = Common::Path();
_currentMystery = -1;
}
+bool AudioPlayer::initMacMysterySounds(uint mysteryNum) {
+ const uint16 firstResourceId = 1001;
+ const Common::Path candidates[2] = {
+ Common::Path(Common::String::format("M%02u.DBD", mysteryNum)),
+ Common::Path(Common::String::format("M%02u.CPD", mysteryNum))
+ };
+
+ for (uint i = 0; i < ARRAYSIZE(candidates); i++) {
+ Common::SeekableReadStream *stream =
+ openMacResource(candidates[i], MKTAG('c', 's', 'n', 'd'),
+ firstResourceId);
+ if (!stream) {
+ stream = openMacResource(candidates[i], MKTAG('s', 'n', 'd', ' '),
+ firstResourceId);
+ }
+ if (!stream)
+ continue;
+
+ delete stream;
+ _macMysterySoundPath = candidates[i];
+ _currentMystery = (int)mysteryNum;
+ debugC(1, kDebugSound, "AudioPlayer: Mac mystery %u sounds from %s",
+ mysteryNum, _macMysterySoundPath.toString().c_str());
+ return true;
+ }
+
+ warning("AudioPlayer: Mac mystery sound file for mystery %u missing",
+ mysteryNum);
+ return false;
+}
+
void AudioPlayer::playMacSnd(uint16 resourceId, Audio::SoundHandle &handle,
Audio::Mixer::SoundType type) {
Common::SeekableReadStream *stream =
@@ -313,6 +428,10 @@ void AudioPlayer::spoolSound(uint num) {
"AudioPlayer: spoolSound(%u) skipped (no mystery sounds)", num);
return;
}
+ if (_isMacintosh) {
+ playMacMysterySound(num);
+ return;
+ }
if (num >= _sdxIndex.size()) {
warning("AudioPlayer: spoolSound(%u) â index out of range (%u)",
num, (uint)_sdxIndex.size());
@@ -405,6 +524,47 @@ void AudioPlayer::spoolSound(uint num) {
Audio::Mixer::kSFXSoundType);
}
+bool AudioPlayer::playMacMysterySound(uint num) {
+ if (_macMysterySoundPath.empty())
+ return false;
+
+ const uint16 resourceId = (uint16)(1001 + num);
+ bool compressed = true;
+ Common::SeekableReadStream *stream =
+ openMacResource(_macMysterySoundPath, MKTAG('c', 's', 'n', 'd'),
+ resourceId);
+ if (!stream) {
+ compressed = false;
+ stream = openMacResource(_macMysterySoundPath,
+ MKTAG('s', 'n', 'd', ' '), resourceId);
+ }
+ if (!stream) {
+ warning("AudioPlayer: Mac mystery sound resource %u missing in %s",
+ resourceId, _macMysterySoundPath.toString().c_str());
+ return false;
+ }
+
+ stopSpool();
+
+ Audio::SeekableAudioStream *audioStream = compressed
+ ? makeMacCsndStream(stream, DisposeAfterUse::YES)
+ : Audio::makeMacSndStream(stream, DisposeAfterUse::YES);
+ if (!audioStream) {
+ if (!compressed)
+ delete stream;
+ warning("AudioPlayer: Mac mystery sound resource %u is not playable",
+ resourceId);
+ return false;
+ }
+
+ _mixer->playStream(Audio::Mixer::kSFXSoundType, &_spoolHandle,
+ audioStream, -1, Audio::Mixer::kMaxChannelVolume,
+ 0, DisposeAfterUse::YES);
+ debugC(1, kDebugSound, "AudioPlayer: playMacMysterySound(%u, %s)",
+ resourceId, compressed ? "csnd" : "snd");
+ return true;
+}
+
bool AudioPlayer::isSpoolPlaying() const {
return _mixer->isSoundHandleActive(_spoolHandle);
}
diff --git a/engines/eem/audio.h b/engines/eem/audio.h
index dc6298190c8..e2f8778c97e 100644
--- a/engines/eem/audio.h
+++ b/engines/eem/audio.h
@@ -39,11 +39,14 @@ class EEMEngine;
*
* - VOC files (THUNDER.VOC, PHONE.VOC, JEN.VOC/JAKE.VOC): _LoadSoundName +
* _PlayVoice @ 1ff1:0299 / 1ff1:023e via _AIL_play_VOC_file.
- * - Mystery spool stream: _InitMysterySounds @ 202f:05cb opens M%d.SDX/.SDB.
+ * - DOS mystery spool stream: _InitMysterySounds @ 202f:05cb opens M%d.SDX/.SDB.
* Each SDX entry is (offset, compSize, uncompSize). Equal sizes => raw PCM
* (_UncompressedSound @ 202f:03e6); otherwise PKWARE DCL Implode
* (_DeCompressSound @ 202f:02ad). Each blob starts with SB Time Constant +
* AIL block count, then 8-bit unsigned PCM.
+ * - Mac mystery spool streams live in M%02d.DBD/M%02d.CPD resource forks.
+ * The executable tries compressed 'csnd' by resource id, then falls back to
+ * plain 'snd '; ids are 1001 + the zero-based mystery voice slot.
*
* M60.SDB/SDX holds the 19 voiceovers between ANIM01..ANIM20 in
* _DoOpeningAnims (loaded via _InitMysterySounds(0x3c)).
@@ -82,8 +85,8 @@ public:
/// Common slots: 12 = PHONESL.VOC, 20 = partner intro, 25 = THUNDER.VOC.
void playFloppyVoiceSlot(uint slot, uint partner);
- /// Loads M%u.SDX into memory and remembers the matching M%u.SDB path.
- /// Mirrors _InitMysterySounds @ 202f:05cb.
+ /// Loads the current mystery voice bundle. DOS uses M%u.SDX/M%u.SDB;
+ /// Mac uses M%02u.DBD/M%02u.CPD 'csnd'/'snd ' resources.
bool initMysterySounds(uint mysteryNum);
/// _CleanMysterySounds @ 202f:05a5.
@@ -128,6 +131,8 @@ private:
};
bool readSdxIndex(const Common::Path &sdxPath);
+ bool initMacMysterySounds(uint mysteryNum);
+ bool playMacMysterySound(uint num);
void playMacSnd(uint16 resourceId, Audio::SoundHandle &handle,
Audio::Mixer::SoundType type);
void playPcmBuffer(byte *pcm, uint32 size, uint sampleRate,
@@ -141,6 +146,7 @@ private:
Common::Array<SoundEntry> _sdxIndex;
Common::Path _sdbPath;
+ Common::Path _macMysterySoundPath;
int _currentMystery = -1;
bool _voiceEnabled = true;
bool _isMacintosh = false;
diff --git a/engines/eem/site.cpp b/engines/eem/site.cpp
index 22df42a435a..d9f888732ce 100644
--- a/engines/eem/site.cpp
+++ b/engines/eem/site.cpp
@@ -345,6 +345,19 @@ const uint16 kWaitAnimsLondon[7][6] = {
{ 0x06, 0x2d, 2, 2, 78, 78 }, // 6
};
+// EEM2 Mac site loop uses its own `_WaitAnims` A5 table
+// (`lea (-0x2040,A5)` in FUN_0000d042; data @ 0x153e). These are native
+// Mac 512x384 anchors, not a scale transform of the DOS table.
+const uint16 kMacWaitAnimsLondon[7][6] = {
+ { 0x00, 0x0a, 0, 3, 150, 150 }, // 0
+ { 0x03, 0x0c, 1, 3, 120, 128 }, // 1
+ { 0x01, 0x0b, 13, 5, 151, 151 }, // 2
+ { 0x04, 0x0d, 2, 5, 148, 152 }, // 3
+ { 0x02, 0x10, 20, 7, 146, 152 }, // 4
+ { 0x05, 0x1b, (uint16)-3, 4, 151, 154 }, // 5
+ { 0x06, 0x1a, 5, 5, 149, 152 }, // 6
+};
+
// Animation script table (`_AnimationSequences @ 29be:22d4`)
// Script byte format:
// 0x80 = restart (loop back to index 0; terminator for one-shots)
@@ -1289,18 +1302,51 @@ bool SiteScreen::enterSiteAnim() {
if (_vm->isLondon()) {
const uint animId = (partner == 0) ? 7 : 0xf;
- const int anchorY = (partner == 0) ? 0x50 : 0x4e;
+ int anchorX = mac ? (int)(int16)kMacWaitAnimsLondon[0][2 + partner] : 0;
+ int anchorY = mac ? (int)(int16)kMacWaitAnimsLondon[0][4 + partner]
+ : ((partner == 0) ? 0x50 : 0x4e);
+ bool alignToIdleBottom = false;
+ int idleBottom = 0;
Animation anim;
if (!_vm->getAni().loadAnimation(animId, anim) || anim.empty())
return false;
+ if (mac) {
+ uint16 idleAnimId = 0;
+ int idleX = 0;
+ int idleY = 0;
+ Animation idleAnim;
+ if (partnerIdleAnimParams(_mystery->_siteNumber, idleAnimId,
+ idleX, idleY) &&
+ _vm->getAni().loadAnimation(idleAnimId, idleAnim) &&
+ !idleAnim.empty()) {
+ const uint idleFrame =
+ partnerFrameAtTick(idleAnimId, (uint)idleAnim.size(), 0);
+ if (idleFrame < idleAnim.size()) {
+ const Picture &idle = idleAnim[idleFrame];
+ anchorX = idleX;
+ anchorY = idleY;
+ idleBottom = idleY - (int)(int16)idle.rowoff +
+ idle.surface.h;
+ alignToIdleBottom = true;
+ }
+ }
+ }
for (uint frameIdx = 0;
frameIdx < anim.size() && !_vm->shouldQuit();
frameIdx++) {
+ const Picture &frame = anim[frameIdx];
+ const int frameY = alignToIdleBottom
+ ? idleBottom - frame.surface.h + (int)(int16)frame.rowoff
+ : anchorY;
Graphics::ManagedSurface scratch(sw, sh,
Graphics::PixelFormat::createFormatCLUT8());
scratch.simpleBlitFrom(bg);
- blitAnimFrameAnchored(scratch.surfacePtr(), anim[frameIdx],
- 0, anchorY);
+ if (mac)
+ blitMacAnimFrameAnchored(scratch.surfacePtr(), frame,
+ anchorX, frameY, macPaletteMap);
+ else
+ blitAnimFrameAnchored(scratch.surfacePtr(), frame,
+ anchorX, frameY);
g_system->copyRectToScreen(scratch.getPixels(), scratch.pitch,
0, 0, sw, sh);
g_system->updateScreen();
@@ -1654,8 +1700,10 @@ bool SiteScreen::partnerIdleAnimParams(uint siteNum, uint16 &animId,
}
} else {
const uint16 speaker = READ_LE_UINT16(site + 8);
- const uint16 (*waitTable)[6] = _vm->isLondon()
- ? kWaitAnimsLondon : kWaitAnims;
+ const uint16 (*waitTable)[6] = kWaitAnims;
+ if (_vm->isLondon())
+ waitTable = _vm->isMacintosh()
+ ? kMacWaitAnimsLondon : kWaitAnimsLondon;
if (speaker >= ARRAYSIZE(kWaitAnims))
return false;
animId = waitTable[speaker][0 + partner];
@@ -2061,7 +2109,14 @@ bool EEMEngine::loadKdAnim(uint16 num, Animation &anim, int &px, int &py,
if (num >= ARRAYSIZE(kKdAnimTable))
return false;
- const uint16 (*kdTable)[6] = isLondon() ? kKdAnimTableLondon : kKdAnimTable;
+ const uint16 (*kdTable)[6] = kKdAnimTable;
+ if (isLondon()) {
+ // EEM2 Mac FUN_0000ce6e indexes `_WaitAnims + 1`
+ // (`lea (-0x2034,A5)`), so KD gestures share the Mac idle anchors
+ // for speaker rows 1..6.
+ kdTable = isMacintosh()
+ ? kMacWaitAnimsLondon + 1 : kKdAnimTableLondon;
+ }
const uint partner = (_partner == kPartnerJake) ? 0 : 1;
animId = kdTable[num][partner];
px = (int)kdTable[num][2 + partner];
More information about the Scummvm-git-logs
mailing list