[Scummvm-git-logs] scummvm master -> d09ccda85058b214b643bce22be859dbb2131cba
mduggan
noreply at scummvm.org
Fri Nov 8 09:05:08 UTC 2024
This automated email contains information about 5 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
6024205bce DGDS: Fix Willy Beamish sound and music a bit
2e9d97ed0f DGDS: Use frame ms consistently for checks
4620c93904 DGDS: Free Shape TTM op is one-shot in Willy Beamish
56e9e7bf81 DGDS: Partly fix menu colors for Dragon EGA
d09ccda850 DGDS: Update md5 for alternate Johnny Castaway version
Commit: 6024205bce4f12d10e131b35d31fb48eab681d72
https://github.com/scummvm/scummvm/commit/6024205bce4f12d10e131b35d31fb48eab681d72
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2024-11-08T20:03:48+11:00
Commit Message:
DGDS: Fix Willy Beamish sound and music a bit
Willy beamish tries to load various music files, but actually all the music is
inside the single file. Both sound and music are SX files so we needed a
slight refactor to support them.
Changed paths:
engines/dgds/dgds.cpp
engines/dgds/dgds.h
engines/dgds/sound.cpp
engines/dgds/sound.h
engines/dgds/ttm.cpp
diff --git a/engines/dgds/dgds.cpp b/engines/dgds/dgds.cpp
index 0431c39cfaa..83c1fb74086 100644
--- a/engines/dgds/dgds.cpp
+++ b/engines/dgds/dgds.cpp
@@ -88,7 +88,8 @@ DgdsEngine::DgdsEngine(OSystem *syst, const ADGameDescription *gameDesc)
_detailLevel(kDgdsDetailHigh), _textSpeed(1), _justChangedScene1(false), _justChangedScene2(false),
_random("dgds"), _currentCursor(-1), _menuToTrigger(kMenuNone), _isLoading(true), _flipMode(false),
_rstFileName(nullptr), _difficulty(1), _menu(nullptr), _adsInterp(nullptr), _isDemo(false),
-_dragonArcade(nullptr), _chinaTank(nullptr), _chinaTrain(nullptr), _skipNextFrame(false), _gameId(GID_INVALID) {
+ _dragonArcade(nullptr), _chinaTank(nullptr), _chinaTrain(nullptr), _skipNextFrame(false),
+ _gameId(GID_INVALID), _thisFrameMs(0) {
_platform = gameDesc->platform;
_gameLang = gameDesc->language;
@@ -398,6 +399,9 @@ void DgdsEngine::loadGameFiles() {
break;
case GID_WILLY:
_gameGlobals = new WillyGlobals(_clock);
+ _soundPlayer->loadSFX("WILLYSND.SX");
+ _soundPlayer->loadMusic("WILLYMUS.SX");
+
if (_resource->hasResource("WILLY.GDS")) {
_gdsScene->load("WILLY.GDS", _resource, _decompressor);
_rstFileName = "WILLY.RST";
diff --git a/engines/dgds/dgds.h b/engines/dgds/dgds.h
index 57f4f2c5a77..c35d9106ce2 100644
--- a/engines/dgds/dgds.h
+++ b/engines/dgds/dgds.h
@@ -177,6 +177,7 @@ private:
bool _isDemo;
bool _flipMode;
bool _skipNextFrame;
+ uint32 _thisFrameMs;
public:
DgdsEngine(OSystem *syst, const ADGameDescription *gameDesc);
diff --git a/engines/dgds/sound.cpp b/engines/dgds/sound.cpp
index 5e2d40b31a4..4edab5a50f4 100644
--- a/engines/dgds/sound.cpp
+++ b/engines/dgds/sound.cpp
@@ -302,25 +302,18 @@ static void _readStrings(Common::SeekableReadStream *stream) {
}
}
-bool Sound::loadMacMusic(const Common::String &filename) {
- if (filename.hasSuffixIgnoreCase(".sng")) {
- Common::String macFileName = filename.substr(0, filename.find(".")) + ".sx";
- return loadMacMusic(macFileName);
- }
-
+bool Sound::loadSXSoundData(const Common::String &filename, Common::Array<SoundData> &dataArray, Common::HashMap<uint16, uint16> &idMap) {
if (!filename.hasSuffixIgnoreCase(".sx"))
- error("Unhandled music file type: %s", filename.c_str());
+ error("Unhandled SX file type: %s", filename.c_str());
- if (filename == _currentMusic)
- return false;
+ Common::SeekableReadStream *stream = _resource->getResource(filename);
- Common::SeekableReadStream *musicStream = _resource->getResource(filename);
- if (!musicStream) {
- warning("Music file %s not found", filename.c_str());
+ if (!stream) {
+ warning("SX file %s not found", filename.c_str());
return false;
}
- DgdsChunkReader chunk(musicStream);
+ DgdsChunkReader chunk(stream);
while (chunk.readNextHeader(EX_SX, filename)) {
if (chunk.isContainer()) {
@@ -338,7 +331,7 @@ bool Sound::loadMacMusic(const Common::String &filename) {
for (uint16 k = 0; k < count; k++) {
uint16 idx = stream->readUint16LE();
debug(" %2u: %u", k, idx);
- _musicIdMap[idx] = k;
+ idMap[idx] = k;
}
} else if (chunk.isSection(ID_TAG) || chunk.isSection(ID_FNM)) {
_readStrings(stream);
@@ -348,20 +341,28 @@ bool Sound::loadMacMusic(const Common::String &filename) {
/*uint16 type = */ stream->readUint16LE();
SoundData soundData;
soundData._data = _decompressor->decompress(stream, stream->size() - stream->pos(), soundData._size);
- _musicData.push_back(soundData);
+ dataArray.push_back(soundData);
}
}
- delete musicStream;
- _currentMusic = filename;
+ delete stream;
return true;
}
bool Sound::loadMusic(const Common::String &filename) {
if (filename == _currentMusic)
return false;
+
unloadMusic();
- loadPCSound(filename, _musicData);
+ if (filename.hasSuffixIgnoreCase(".sx")) {
+ loadSXSoundData(filename, _musicData, _musicIdMap);
+ } else if (filename.hasSuffixIgnoreCase(".sng")) {
+ _musicIdMap.clear();
+ loadSNGSoundData(filename, _musicData);
+ } else {
+ error("Unhandled music file type: %s", filename.c_str());
+ }
+
_currentMusic = filename;
debug("Sound: Loaded music %s with %d entries", filename.c_str(), _musicData.size());
return true;
@@ -370,18 +371,26 @@ bool Sound::loadMusic(const Common::String &filename) {
void Sound::loadSFX(const Common::String &filename) {
if (_sfxData.size())
error("Sound: SFX data should only be loaded once");
- loadPCSound(filename, _sfxData);
+ if (filename.hasSuffixIgnoreCase(".sx")) {
+ loadSXSoundData(filename, _sfxData, _sfxIdMap);
+ } else if (filename.hasSuffixIgnoreCase(".sng")) {
+ loadSNGSoundData(filename, _sfxData);
+ } else {
+ error("Unhandled SFX file type: %s", filename.c_str());
+ }
+
+ debug("Sound: Loaded sfx %s with %d entries", filename.c_str(), _sfxData.size());
}
-void Sound::loadPCSound(const Common::String &filename, Common::Array<SoundData> &dataArray) {
+void Sound::loadSNGSoundData(const Common::String &filename, Common::Array<SoundData> &dataArray) {
if (!filename.hasSuffixIgnoreCase(".sng"))
- error("Unhandled music file type: %s", filename.c_str());
+ error("Unhandled SNG file type: %s", filename.c_str());
- Common::SeekableReadStream *musicStream = _resource->getResource(filename);
- if (!musicStream)
+ Common::SeekableReadStream *stream = _resource->getResource(filename);
+ if (!stream)
error("Music file %s not found", filename.c_str());
- DgdsChunkReader chunk(musicStream);
+ DgdsChunkReader chunk(stream);
while (chunk.readNextHeader(EX_SNG, filename)) {
if (chunk.isContainer()) {
@@ -413,13 +422,21 @@ void Sound::loadPCSound(const Common::String &filename, Common::Array<SoundData>
}
}
- delete musicStream;
+ delete stream;
}
int Sound::mapSfxNum(int num) const {
// Fixed offset in Dragon and HoC?
if (DgdsEngine::getInstance()->getGameId() == GID_DRAGON || DgdsEngine::getInstance()->getGameId() == GID_HOC)
return num - 24;
+ else if (_sfxIdMap.contains(num))
+ return _sfxIdMap[num];
+ return num;
+}
+
+int Sound::mapMusicNum(int num) const {
+ if (_musicIdMap.contains(num))
+ return _musicIdMap[num];
return num;
}
@@ -445,8 +462,25 @@ void Sound::stopSfxByNum(int num) {
}
void Sound::playMusic(int num) {
- debug("Sound: Play music %d (%s), have %d entries", num, _currentMusic.c_str(), _musicData.size());
- playPCSound(num, _musicData, Audio::Mixer::kMusicSoundType);
+ int mappedNum = mapMusicNum(num);
+ debug("Sound: Play music %d (-> %d, %s), have %d entries", num, mappedNum, _currentMusic.c_str(), _musicData.size());
+ playPCSound(mappedNum, _musicData, Audio::Mixer::kMusicSoundType);
+}
+
+void Sound::playMusicOrSFX(int num) {
+ if (_musicIdMap.contains(num)) {
+ playMusic(num);
+ } else {
+ playSFX(num);
+ }
+}
+
+void Sound::stopMusicOrSFX(int num) {
+ if (_musicIdMap.contains(num)) {
+ stopMusic();
+ } else {
+ stopSfxByNum(num);
+ }
}
void Sound::processInitSound(uint32 obj, const SoundData &data, Audio::Mixer::SoundType soundType) {
@@ -575,10 +609,6 @@ void Sound::processPlaySound(uint32 obj, bool playBed, bool restoring, const Sou
}
void Sound::playPCSound(int num, const Common::Array<SoundData> &dataArray, Audio::Mixer::SoundType soundType) {
- if (_musicIdMap.size()) {
- num = _musicIdMap[num];
- }
-
if (num >= 0 && num < (int)dataArray.size()) {
const SoundData &data = dataArray[num];
uint32 tracks = _availableSndTracks(data._data, data._size);
diff --git a/engines/dgds/sound.h b/engines/dgds/sound.h
index 82a7bb977df..df65eb039c8 100644
--- a/engines/dgds/sound.h
+++ b/engines/dgds/sound.h
@@ -55,7 +55,6 @@ public:
void playAmigaSfx(const Common::String &filename, byte channel, byte volume);
bool loadMusic(const Common::String &filename);
- bool loadMacMusic(const Common::String &filename);
void loadSFX(const Common::String &filename);
void playMusic(int num);
@@ -64,6 +63,9 @@ public:
void playSFX(int num);
+ void playMusicOrSFX(int num);
+ void stopMusicOrSFX(int num);
+
void stopSfxForChannel(byte channel);
void stopSfxByNum(int num);
void stopAllSfx();
@@ -71,7 +73,9 @@ public:
bool playPCM(const byte *data, uint32 size);
private:
- void loadPCSound(const Common::String &filename, Common::Array<SoundData> &dataArray);
+ void loadSNGSoundData(const Common::String &filename, Common::Array<SoundData> &dataArray);
+ bool loadSXSoundData(const Common::String &filename, Common::Array<SoundData> &dataArray, Common::HashMap<uint16, uint16> &idMap);
+
void playPCSound(int num, const Common::Array<SoundData> &dataArray, Audio::Mixer::SoundType soundType);
void processInitSound(uint32 obj, const SoundData &data, Audio::Mixer::SoundType soundType);
@@ -81,6 +85,7 @@ private:
void initSoundResource(MusicEntry *newSound, const SoundData &data, Audio::Mixer::SoundType soundType);
int mapSfxNum(int num) const;
+ int mapMusicNum(int num) const;
struct Channel _channels[2];
@@ -88,6 +93,7 @@ private:
Common::HashMap<uint16, uint16> _musicIdMap;
Common::Array<SoundData> _sfxData;
+ Common::HashMap<uint16, uint16> _sfxIdMap;
Common::String _currentMusic;
diff --git a/engines/dgds/ttm.cpp b/engines/dgds/ttm.cpp
index 6da1dc54d27..979afc06843 100644
--- a/engines/dgds/ttm.cpp
+++ b/engines/dgds/ttm.cpp
@@ -640,7 +640,7 @@ void TTMInterpreter::handleOperation(TTMEnviro &env, TTMSeq &seq, uint16 op, byt
case 0x1020: // SET DELAY: i:int [0..n]
// TODO: Probably should do this accounting (as well as timeCut and dialogs)
// in game frames, not millis.
- _vm->adsInterpreter()->setScriptDelay((int)(ivals[0] * MS_PER_FRAME));
+ _vm->adsInterpreter()->setScriptDelay((int)ceil(ivals[0] * MS_PER_FRAME));
break;
case 0x1030: // SET BRUSH: id:int [-1:n]
seq._brushNum = ivals[0];
@@ -1035,7 +1035,9 @@ void TTMInterpreter::handleOperation(TTMEnviro &env, TTMSeq &seq, uint16 op, byt
break;
}
case 0xc020: { // LOAD SAMPLE: filename:str
- _vm->_soundPlayer->loadMacMusic(sval.c_str());
+ // Ignore this?
+ //_vm->_soundPlayer->loadMusic(sval.c_str());
+ //_vm->_soundPlayer->stopMusic();
break;
}
case 0xc030: { // SELECT SAMPLE: int: i
@@ -1043,7 +1045,11 @@ void TTMInterpreter::handleOperation(TTMEnviro &env, TTMSeq &seq, uint16 op, byt
break;
}
case 0xc050: { // PLAY SAMPLE: int: i
- _vm->_soundPlayer->playMusic(ivals[0]);
+ _vm->_soundPlayer->playMusicOrSFX(ivals[0]);
+ break;
+ }
+ case 0xc060: { // STOP SAMPLE: int: i
+ _vm->_soundPlayer->stopMusicOrSFX(ivals[0]);
break;
}
case 0xc210: { // LOAD RAW SFX filename:str
@@ -1101,9 +1107,6 @@ void TTMInterpreter::handleOperation(TTMEnviro &env, TTMSeq &seq, uint16 op, byt
if (_vm->_platform == Common::kPlatformAmiga) {
// TODO: remove hard-coded stuff..
_vm->_soundPlayer->playAmigaSfx("DYNAMIX.INS", 0, 255);
- } else if (_vm->_platform == Common::kPlatformMacintosh) {
- if (_vm->_soundPlayer->loadMacMusic(sval.c_str()))
- _vm->_soundPlayer->playMusic(seq._currentSongId);
} else {
if (_vm->_soundPlayer->loadMusic(sval.c_str()))
_vm->_soundPlayer->playMusic(seq._currentSongId);
Commit: 2e9d97ed0f13fbf4a4202356e7a0c847ee154f91
https://github.com/scummvm/scummvm/commit/2e9d97ed0f13fbf4a4202356e7a0c847ee154f91
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2024-11-08T20:03:48+11:00
Commit Message:
DGDS: Use frame ms consistently for checks
Some game timing events are based on ms elapsed, but we were just getting the
current ms when it was evaluated. This was not very consistent and could
potentially lead to weird problems, although in practice they were unlikely
Record the elapsed ms at the start of each frame so we can use the same
comparison point in every operation.
Changed paths:
engines/dgds/ads.cpp
engines/dgds/clock.cpp
engines/dgds/dgds.cpp
engines/dgds/dgds.h
engines/dgds/scene.cpp
engines/dgds/ttm.cpp
diff --git a/engines/dgds/ads.cpp b/engines/dgds/ads.cpp
index 1c395c2d950..d2696630b69 100644
--- a/engines/dgds/ads.cpp
+++ b/engines/dgds/ads.cpp
@@ -137,7 +137,7 @@ static const uint16 ADS_SEQ_OPCODES[] = {
bool ADSInterpreter::updateSeqTimeAndFrame(const TTMEnviro *env, Common::SharedPtr<TTMSeq> seq) {
if (seq->_timeInterval != 0) {
- uint32 now = g_engine->getTotalPlayTime();
+ uint32 now = DgdsEngine::getInstance()->getThisFrameMs();
if (now < seq->_timeNext) {
debug(10, "env %d seq %d (%s) not advancing from frame %d (now %d timeNext %d interval %d)", seq->_enviro,
seq->_seqNum, env->_tags.getValOrDefault(seq->_seqNum).c_str(), seq->_currentFrame, now, seq->_timeNext, seq->_timeInterval);
@@ -581,7 +581,7 @@ bool ADSInterpreter::handleOperation(uint16 code, Common::SeekableReadStream *sc
seq->_runFlag = kRunType1;
} else if (runCount < 0) {
// Negative run count sets the cut time
- seq->_timeCut = g_engine->getTotalPlayTime() + (-runCount * MS_PER_FRAME);
+ seq->_timeCut = DgdsEngine::getInstance()->getThisFrameMs() + (-runCount * MS_PER_FRAME);
seq->_runFlag = kRunTypeTimeLimited;
} else {
seq->_runFlag = kRunTypeMulti;
@@ -873,7 +873,7 @@ bool ADSInterpreter::run() {
seq->_lastFrame = seq->_currentFrame;
result = true;
if (_adsData->_scriptDelay != -1 && seq->_timeInterval != _adsData->_scriptDelay) {
- uint32 now = g_engine->getTotalPlayTime();
+ uint32 now = DgdsEngine::getInstance()->getThisFrameMs();
seq->_timeNext = now + _adsData->_scriptDelay;
seq->_timeInterval = _adsData->_scriptDelay;
}
@@ -909,7 +909,7 @@ bool ADSInterpreter::run() {
}
}
- if (rflag == kRunTypeTimeLimited && seq->_timeCut <= g_engine->getTotalPlayTime()) {
+ if (rflag == kRunTypeTimeLimited && seq->_timeCut <= DgdsEngine::getInstance()->getThisFrameMs()) {
seq->_runFlag = kRunTypeFinished;
}
}
diff --git a/engines/dgds/clock.cpp b/engines/dgds/clock.cpp
index 9fc80b2f53c..38c41ee993d 100644
--- a/engines/dgds/clock.cpp
+++ b/engines/dgds/clock.cpp
@@ -146,7 +146,7 @@ static const int MILLIS_PER_GAME_MIN = 5000;
static const int MILLIS_PER_TIMER_TICK = 60;
void Clock::update(bool gameRunning) {
- uint32 playTimeNow = g_engine->getTotalPlayTime();
+ uint32 playTimeNow = DgdsEngine::getInstance()->getThisFrameMs();
// These timers are updated whether or not the game is running
_gameTicksUp = playTimeNow / MILLIS_PER_TIMER_TICK;
diff --git a/engines/dgds/dgds.cpp b/engines/dgds/dgds.cpp
index 83c1fb74086..45e196bf03d 100644
--- a/engines/dgds/dgds.cpp
+++ b/engines/dgds/dgds.cpp
@@ -476,7 +476,7 @@ static void _dumpFrame(const Graphics::ManagedSurface &surf, const char *name) {
#ifdef DUMP_FRAME_DATA
/* For debugging, dump the frame contents.. */
Common::DumpFile outf;
- uint32 now = g_engine->getTotalPlayTime();
+ uint32 now = DgdsEngine::getInstance()->getThisFrameMs();
byte palbuf[768];
g_system->getPaletteManager()->grabPalette(palbuf, 0, 256);
@@ -509,6 +509,8 @@ Common::Error DgdsEngine::run() {
uint32 frameCount = 0;
while (!shouldQuit()) {
+ _thisFrameMs = getTotalPlayTime();
+
Common::EventType mouseEvent = Common::EVENT_INVALID;
while (eventMan->pollEvent(ev)) {
if (ev.type == Common::EVENT_CUSTOM_ENGINE_ACTION_START) {
@@ -611,6 +613,7 @@ Common::Error DgdsEngine::run() {
}
_clock.update(false);
} else {
+ debug(10, "**** Starting frame %d time %d ****", frameCount, _thisFrameMs);
_scene->checkForClearedDialogs();
@@ -716,20 +719,20 @@ Common::Error DgdsEngine::run() {
g_system->updateScreen();
// Limit to 30 FPS
- const uint32 thisFrameMillis = g_system->getMillis();
frameCount++;
if (_skipNextFrame) {
frameCount++;
_skipNextFrame = false;
}
- const uint32 elapsedMillis = thisFrameMillis - startMillis;
+ const uint32 thisFrameEndMillis = g_system->getMillis();
+ const uint32 elapsedMillis = thisFrameEndMillis - startMillis;
const uint32 targetMillis = (frameCount * 1000 / 30);
if (targetMillis > elapsedMillis) {
// too fast, delay
g_system->delayMillis(targetMillis - elapsedMillis);
} else if (targetMillis < elapsedMillis) {
// too slow.. adjust expectations? :)
- startMillis = g_system->getMillis();
+ startMillis = thisFrameEndMillis;
frameCount = 0;
}
@@ -850,9 +853,9 @@ Common::Error DgdsEngine::syncGame(Common::Serializer &s) {
s.syncAsByte(_justChangedScene2);
// sync engine play time to ensure various events run correctly.
- uint32 playtime = g_engine->getTotalPlayTime();
+ uint32 playtime = DgdsEngine::getInstance()->getThisFrameMs();
s.syncAsUint32LE(playtime);
- g_engine->setTotalPlayTime(playtime);
+ setTotalPlayTime(playtime);
s.syncString(_backgroundFile);
if (s.isLoading()) {
diff --git a/engines/dgds/dgds.h b/engines/dgds/dgds.h
index c35d9106ce2..435e8b6dde8 100644
--- a/engines/dgds/dgds.h
+++ b/engines/dgds/dgds.h
@@ -258,6 +258,7 @@ public:
ChinaTank *getChinaTank() { return _chinaTank; }
DragonArcade *getDragonArcade() { return _dragonArcade; }
void setSkipNextFrame() { _skipNextFrame = true; }
+ uint32 getThisFrameMs() const { return _thisFrameMs; }
static DgdsEngine *getInstance() { return static_cast<DgdsEngine *>(g_engine); }
void setFlipMode(bool mode) { _flipMode = mode; }
diff --git a/engines/dgds/scene.cpp b/engines/dgds/scene.cpp
index a4dae368ef3..96359998ed7 100644
--- a/engines/dgds/scene.cpp
+++ b/engines/dgds/scene.cpp
@@ -1463,7 +1463,7 @@ void SDSScene::showDialog(uint16 fileNum, uint16 dlgNum) {
}
bool SDSScene::checkDialogActive() {
- uint32 timeNow = g_engine->getTotalPlayTime();
+ uint32 timeNow = DgdsEngine::getInstance()->getThisFrameMs();
bool retval = false;
_sceneDialogFlags = kDlgFlagNone;
@@ -1569,7 +1569,7 @@ bool SDSScene::checkForClearedDialogs() {
bool SDSScene::drawAndUpdateDialogs(Graphics::ManagedSurface *dst) {
bool retval = false;
- const DgdsEngine *engine = static_cast<const DgdsEngine *>(g_engine);
+ const DgdsEngine *engine = DgdsEngine::getInstance();
for (auto &dlg : _dialogs) {
if (dlg.hasFlag(kDlgFlagVisible) && !dlg.hasFlag(kDlgFlagLo4) &&
!dlg.hasFlag(kDlgFlagHi20) && !dlg.hasFlag(kDlgFlagHi40)) {
@@ -1602,7 +1602,7 @@ bool SDSScene::drawAndUpdateDialogs(Graphics::ManagedSurface *dst) {
int time = delay * (9 - engine->getTextSpeed());
assert(dlg._state);
- dlg._state->_hideTime = g_engine->getTotalPlayTime() + time;
+ dlg._state->_hideTime = DgdsEngine::getInstance()->getThisFrameMs() + time;
dlg._state->_selectedAction = nullptr;
dlg.updateSelectedAction(0);
if (dlg._action.size() > 1 && !dlg._state->_selectedAction) {
diff --git a/engines/dgds/ttm.cpp b/engines/dgds/ttm.cpp
index 979afc06843..0b6774c6372 100644
--- a/engines/dgds/ttm.cpp
+++ b/engines/dgds/ttm.cpp
@@ -640,7 +640,7 @@ void TTMInterpreter::handleOperation(TTMEnviro &env, TTMSeq &seq, uint16 op, byt
case 0x1020: // SET DELAY: i:int [0..n]
// TODO: Probably should do this accounting (as well as timeCut and dialogs)
// in game frames, not millis.
- _vm->adsInterpreter()->setScriptDelay((int)ceil(ivals[0] * MS_PER_FRAME));
+ _vm->adsInterpreter()->setScriptDelay((int)round(ivals[0] * MS_PER_FRAME));
break;
case 0x1030: // SET BRUSH: id:int [-1:n]
seq._brushNum = ivals[0];
@@ -1289,8 +1289,11 @@ void TTMSeq::reset() {
_currentFontId = 0;
_currentPalId = 0;
_currentSongId = 0;
- _currentBmpId = 0;
- _currentGetPutId = 0;
+ if (DgdsEngine::getInstance()->getGameId() == GID_DRAGON) {
+ // These slots are not reset in HOC onward
+ _currentBmpId = 0;
+ _currentGetPutId = 0;
+ }
_currentFrame = _startFrame;
_gotoFrame = -1;
_drawColBG = 0xf;
Commit: 4620c93904e1a946c09db9991de2e35f8fdf34de
https://github.com/scummvm/scummvm/commit/4620c93904e1a946c09db9991de2e35f8fdf34de
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2024-11-08T20:03:48+11:00
Commit Message:
DGDS: Free Shape TTM op is one-shot in Willy Beamish
This fixes the intro cinematic after it zooms in on Willy and his opponent.
The sequence goes something like:
Frame N
FREE SHAPE
SELECT SHAPE
LOAD SHAPE
Frame N+1
DRAW BMP
The first frame is executed multiple times. If LOAD is one-shot but FREE is
not, then it frees the image the second time and does not reload it.
Changed paths:
engines/dgds/ads.cpp
engines/dgds/ttm.cpp
diff --git a/engines/dgds/ads.cpp b/engines/dgds/ads.cpp
index d2696630b69..2700c6b3995 100644
--- a/engines/dgds/ads.cpp
+++ b/engines/dgds/ads.cpp
@@ -567,8 +567,11 @@ bool ADSInterpreter::handleOperation(uint16 code, Common::SeekableReadStream *sc
Common::SharedPtr<TTMSeq> seq = findTTMSeq(enviro, seqnum);
TTMEnviro *env = findTTMEnviro(enviro);
- if (!seq || !env)
- error("ADS invalid seq requested %d %d", enviro, seqnum);
+ if (!seq || !env) {
+ // This happens in Willy Beamish FDD scene 24
+ warning("ADS op %04x invalid env + seq requested %d %d", code, enviro, seqnum);
+ break;
+ }
debug(10, "ADS 0x%04x: add scene - env %d seq %d (%s) runCount %d prop %d", code,
enviro, seqnum, env->_tags.getValOrDefault(seqnum).c_str(), runCount, unk);
diff --git a/engines/dgds/ttm.cpp b/engines/dgds/ttm.cpp
index 0b6774c6372..b51e47f163a 100644
--- a/engines/dgds/ttm.cpp
+++ b/engines/dgds/ttm.cpp
@@ -595,6 +595,10 @@ void TTMInterpreter::handleOperation(TTMEnviro &env, TTMSeq &seq, uint16 op, byt
seq._currentPalId = 0;
break;
case 0x0080: // FREE SHAPE
+ // This is a one-shot op only in Willy Beamish - in HoC and Dragon it's done every time
+ // (although it may not make any difference)
+ if (seq._executed && DgdsEngine::getInstance()->getGameId() == GID_WILLY)
+ break;
//debug("0x0080: Free from slot %d for seq %d env %d", seq._currentBmpId, seq._seqNum, env._enviro);
env._scriptShapes[seq._currentBmpId].reset();
break;
Commit: 56e9e7bf8197b20e17ce8bac4e2117250ae190ba
https://github.com/scummvm/scummvm/commit/56e9e7bf8197b20e17ce8bac4e2117250ae190ba
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2024-11-08T20:03:49+11:00
Commit Message:
DGDS: Partly fix menu colors for Dragon EGA
This is not a complete fix, buttons are still wrong.
Changed paths:
engines/dgds/detection_tables.h
engines/dgds/dgds.cpp
engines/dgds/dgds.h
engines/dgds/game_palettes.cpp
engines/dgds/request.cpp
diff --git a/engines/dgds/detection_tables.h b/engines/dgds/detection_tables.h
index dc8adb35cfa..32a90d6dcfa 100644
--- a/engines/dgds/detection_tables.h
+++ b/engines/dgds/detection_tables.h
@@ -21,6 +21,10 @@
namespace Dgds {
+enum DgdsADGFFlags {
+ ADGF_DGDS_EGA = 1,
+};
+
static const ADGameDescription gameDescriptions[] = {
// Rise of the Dragon (PC) GOG
{
@@ -93,7 +97,7 @@ static const ADGameDescription gameDescriptions[] = {
},
Common::EN_ANY,
Common::kPlatformDOS,
- ADGF_TESTING,
+ ADGF_TESTING | ADGF_DGDS_EGA,
GUIO1(GUIO_NONE)
},
@@ -108,7 +112,7 @@ static const ADGameDescription gameDescriptions[] = {
},
Common::EN_ANY,
Common::kPlatformDOS,
- ADGF_TESTING,
+ ADGF_TESTING | ADGF_DGDS_EGA,
GUIO1(GUIO_NONE)
},
@@ -292,7 +296,7 @@ static const ADGameDescription gameDescriptions[] = {
GUIO1(GUIO_NONE)
},
- // Heart of China (PC) 720kb Floppy version
+ // Heart of China (PC) EGA 720kb Floppy version
{
"china",
0,
@@ -303,11 +307,11 @@ static const ADGameDescription gameDescriptions[] = {
},
Common::EN_ANY,
Common::kPlatformDOS,
- ADGF_UNSTABLE,
+ ADGF_UNSTABLE | ADGF_DGDS_EGA,
GUIO1(GUIO_NONE)
},
- // Heart of China (PC) 1.2MB Floppy version
+ // Heart of China (PC) EGA 1.2MB Floppy version
{
"china",
0,
@@ -318,7 +322,7 @@ static const ADGameDescription gameDescriptions[] = {
},
Common::EN_ANY,
Common::kPlatformDOS,
- ADGF_UNSTABLE,
+ ADGF_UNSTABLE | ADGF_DGDS_EGA,
GUIO1(GUIO_NONE)
},
diff --git a/engines/dgds/dgds.cpp b/engines/dgds/dgds.cpp
index 45e196bf03d..0714d8cb042 100644
--- a/engines/dgds/dgds.cpp
+++ b/engines/dgds/dgds.cpp
@@ -93,6 +93,7 @@ DgdsEngine::DgdsEngine(OSystem *syst, const ADGameDescription *gameDesc)
_platform = gameDesc->platform;
_gameLang = gameDesc->language;
+ _isEGA = (gameDesc->flags & ADGF_DGDS_EGA);
if (!strcmp(gameDesc->gameId, "rise")) {
_gameId = GID_DRAGON;
diff --git a/engines/dgds/dgds.h b/engines/dgds/dgds.h
index 435e8b6dde8..2c244919340 100644
--- a/engines/dgds/dgds.h
+++ b/engines/dgds/dgds.h
@@ -175,6 +175,7 @@ private:
const char *_rstFileName;
bool _isDemo;
+ bool _isEGA;
bool _flipMode;
bool _skipNextFrame;
uint32 _thisFrameMs;
@@ -263,6 +264,8 @@ public:
static DgdsEngine *getInstance() { return static_cast<DgdsEngine *>(g_engine); }
void setFlipMode(bool mode) { _flipMode = mode; }
+ bool isEGA() const { return _isEGA; }
+
void enableKeymapper();
void disableKeymapper();
diff --git a/engines/dgds/game_palettes.cpp b/engines/dgds/game_palettes.cpp
index 0771321040a..9a1c12a32a2 100644
--- a/engines/dgds/game_palettes.cpp
+++ b/engines/dgds/game_palettes.cpp
@@ -86,12 +86,22 @@ int GamePalettes::loadPalette(const Common::String &filename) {
}
break;
} else if (chunk.isSection(ID_EGA)) {
- for (uint k = 0; k < chunk.getSize() / 2; k++) {
- byte egaCol = (chunkStream->readUint16LE() & 0xF);
- byte r = EGA_COLORS[egaCol][0];
- byte g = EGA_COLORS[egaCol][1];
- byte b = EGA_COLORS[egaCol][2];
- pal.set(k, r, g, b);
+ if (chunk.getSize() > 20) {
+ for (uint k = 0; k < chunk.getSize() / 2; k++) {
+ byte egaCol = (chunkStream->readUint16LE() & 0xF);
+ byte r = EGA_COLORS[egaCol][0];
+ byte g = EGA_COLORS[egaCol][1];
+ byte b = EGA_COLORS[egaCol][2];
+ pal.set(k, r, g, b);
+ }
+ } else {
+ for (uint k = 0; k < chunk.getSize(); k++) {
+ byte egaCol = (chunkStream->readByte());
+ byte r = EGA_COLORS[egaCol][0];
+ byte g = EGA_COLORS[egaCol][1];
+ byte b = EGA_COLORS[egaCol][2];
+ pal.set(k, r, g, b);
+ }
}
break;
} else if (chunk.isSection(ID_CGA)) {
diff --git a/engines/dgds/request.cpp b/engines/dgds/request.cpp
index e993b960228..682d1d8a576 100644
--- a/engines/dgds/request.cpp
+++ b/engines/dgds/request.cpp
@@ -883,7 +883,7 @@ void RequestData::drawBackgroundNoSliders(Graphics::ManagedSurface *dst, const C
void RequestData::fillBackground(Graphics::ManagedSurface *dst, uint16 x, uint16 y, uint16 width, uint16 height, int16 startoffset) {
DgdsEngine *engine = DgdsEngine::getInstance();
- if (engine->getGameId() == GID_DRAGON && engine->getDetailLevel() == kDgdsDetailHigh) {
+ if (engine->getGameId() == GID_DRAGON && engine->getDetailLevel() == kDgdsDetailHigh && !engine->isEGA()) {
Graphics::Surface area = dst->getSubArea(Common::Rect(Common::Point(x, y), width, height));
while (startoffset < 0)
startoffset += ARRAYSIZE(MenuBackgroundColors);
Commit: d09ccda85058b214b643bce22be859dbb2131cba
https://github.com/scummvm/scummvm/commit/d09ccda85058b214b643bce22be859dbb2131cba
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2024-11-08T20:03:49+11:00
Commit Message:
DGDS: Update md5 for alternate Johnny Castaway version
Although the exe size is the same, it has slightly different contents.
Changed paths:
engines/dgds/detection_tables.h
diff --git a/engines/dgds/detection_tables.h b/engines/dgds/detection_tables.h
index 32a90d6dcfa..87ef71701e7 100644
--- a/engines/dgds/detection_tables.h
+++ b/engines/dgds/detection_tables.h
@@ -409,7 +409,7 @@ static const ADGameDescription gameDescriptions[] = {
{
{"resource.map", 0, "374e6d05c5e0acd88fb5af748948c899", 1461},
{"resource.001", 0, "46acc7ab8f6d7f63838ffea5f87380e2", 1175645},
- {"scrantic.exe", 0, "46ce1ae10fcfa52dd964fcfc86694509", 295952},
+ {"scrantic.exe", 0, "34bd51a9697ce7ce833b90e189ef51b2", 295952},
AD_LISTEND
},
Common::EN_ANY,
More information about the Scummvm-git-logs
mailing list