[Scummvm-git-logs] scummvm master -> e8e166204ad4cee3297895c0b02b3106253bc38d
mduggan
noreply at scummvm.org
Sat Jan 25 06:00:49 UTC 2025
This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
e8e166204a DGDS: More head rendering fixes for Willy Beamish
Commit: e8e166204ad4cee3297895c0b02b3106253bc38d
https://github.com/scummvm/scummvm/commit/e8e166204ad4cee3297895c0b02b3106253bc38d
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2025-01-25T16:55:57+11:00
Commit Message:
DGDS: More head rendering fixes for Willy Beamish
Willy Beamish should pause script execution while waiting for a response in a
dialog, but not in dialogs with no head.
Heads should also have an "opening" state for one frame before they are
considered visible. This avoids a frame of overlap with the previous one, just
like dialogs do. Without this, eg, the background is not rendered behind the
teacher after returning from the principal's office during the opening
sequence.
These fixes bring Willy Beamish rendering very close to the original.
Changed paths:
engines/dgds/dgds.cpp
engines/dgds/dgds.h
engines/dgds/head.cpp
engines/dgds/head.h
engines/dgds/scene.cpp
engines/dgds/scene.h
engines/dgds/scene_op.cpp
engines/dgds/scene_op.h
engines/dgds/ttm.cpp
diff --git a/engines/dgds/dgds.cpp b/engines/dgds/dgds.cpp
index 77cf29eecab..d384aa671c2 100644
--- a/engines/dgds/dgds.cpp
+++ b/engines/dgds/dgds.cpp
@@ -85,7 +85,7 @@ DgdsEngine::DgdsEngine(OSystem *syst, const ADGameDescription *gameDesc)
: Engine(syst), _fontManager(nullptr), _console(nullptr), _inventory(nullptr),
_soundPlayer(nullptr), _decompressor(nullptr), _scene(nullptr), _shellGame(nullptr),
_hocIntro(nullptr), _gdsScene(nullptr), _resource(nullptr), _gamePals(nullptr), _gameGlobals(nullptr),
- _detailLevel(kDgdsDetailHigh), _textSpeed(1), _justChangedScene1(false), _justChangedScene2(false),
+ _detailLevel(kDgdsDetailHigh), _textSpeed(1), _justChangedScene1(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), _isAltDlgColors(false),
@@ -255,7 +255,6 @@ bool DgdsEngine::changeScene(int sceneNum) {
_scene->runEnterSceneOps();
_justChangedScene1 = true;
- _justChangedScene2 = true;
return true;
}
@@ -607,7 +606,7 @@ void DgdsEngine::dimPalForWillyDialog(bool force) {
static const int FADE_STARTCOL = 0x40;
static const int FADE_NUMCOLS = 0xC0;
- if (force || _scene->hasVisibleHead() ) {
+ if (force || _scene->hasVisibleHead()) {
fade = 0x80;
} else {
fade = 0;
@@ -677,12 +676,17 @@ Common::Error DgdsEngine::run() {
} else {
debug(10, "**** Starting frame %d time %d ****", frameCount, _thisFrameMs);
- _scene->checkForClearedDialogs();
+ bool clearedDlg = _scene->checkForClearedDialogs();
- _gdsScene->runPreTickOps();
- _scene->runPreTickOps();
+ // Willy pauses script execution when the palette is faded by an active
+ // talking head is active
+ bool shouldRunScripts = !(_lastGlobalFade > 0 && !clearedDlg);
- _compositionBuffer.blitFrom(_backgroundBuffer);
+ if (shouldRunScripts) {
+ _gdsScene->runPreTickOps();
+ _scene->runPreTickOps();
+ _compositionBuffer.blitFrom(_backgroundBuffer);
+ }
if (_inventory->isOpen() && (_scene->getNum() == 2 || getGameId() == GID_WILLY)) {
int invCount = _gdsScene->countItemsInInventory();
@@ -690,7 +694,7 @@ Common::Error DgdsEngine::run() {
}
// Don't draw stored buffer over Willy Beamish inventory
- if (!(_inventory->isOpen() && getGameId() == GID_WILLY))
+ if (shouldRunScripts && !(_inventory->isOpen() && getGameId() == GID_WILLY))
_compositionBuffer.transBlitFrom(_storedAreaBuffer);
//
@@ -704,7 +708,7 @@ Common::Error DgdsEngine::run() {
dumpFrame(_compositionBuffer, "comp-before-ads");
- if (!_inventory->isOpen() || (_inventory->isZoomVisible() && getGameId() != GID_WILLY))
+ if (shouldRunScripts && (!_inventory->isOpen() || (_inventory->isZoomVisible() && getGameId() != GID_WILLY)))
_adsInterp->run();
if (_inventory->isOpen()) {
@@ -746,12 +750,15 @@ Common::Error DgdsEngine::run() {
}
}
- // TODO: Hard-coded logic to match Rise of the Dragon, check others
- if (getGameId() != GID_DRAGON || _scene->getNum() != 55)
- _gdsScene->runPostTickOps();
+ if (shouldRunScripts) {
+ // This is hard-coded in Rise of the Dragon, others always run the ops if the game is active.
+ bool shouldRunPostTickOps = (getGameId() != GID_DRAGON || _scene->getNum() != 55);
+ if (shouldRunPostTickOps)
+ _gdsScene->runPostTickOps();
- _scene->runPostTickOps();
- _scene->checkTriggers();
+ _scene->runPostTickOps();
+ _scene->checkTriggers();
+ }
dumpFrame(_backgroundBuffer, "back");
dumpFrame(_storedAreaBuffer, "stor");
@@ -772,24 +779,23 @@ Common::Error DgdsEngine::run() {
if (getGameId() == GID_WILLY) {
if (!justChangedScene1())
- _scene->drawVisibleHeads(&_compositionBuffer);
+ _scene->drawAndUpdateHeads(&_compositionBuffer);
_scene->drawAndUpdateDialogs(&_compositionBuffer);
_scene->updateHotAreasFromDynamicRects();
} else {
_scene->drawAndUpdateDialogs(&_compositionBuffer);
if (!justChangedScene1())
- _scene->drawVisibleHeads(&_compositionBuffer);
+ _scene->drawAndUpdateHeads(&_compositionBuffer);
}
dumpFrame(_compositionBuffer, "comp-with-dlg");
- bool gameRunning = (!haveActiveDialog && _gameGlobals->getGlobal(0x57) /* TODO: && _dragItem == nullptr*/);
- _clock.update(gameRunning);
+ bool gameRunning = (!haveActiveDialog && _gameGlobals->getGlobal(0x57));
+ _clock.update(gameRunning && shouldRunScripts);
g_system->copyRectToScreen(_compositionBuffer.getPixels(), SCREEN_WIDTH, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
_justChangedScene1 = false;
- _justChangedScene2 = false;
}
// Mouse event is now handled.
@@ -959,7 +965,8 @@ Common::Error DgdsEngine::syncGame(Common::Serializer &s) {
s.syncAsSint16LE(_textSpeed);
s.syncAsByte(_justChangedScene1);
- s.syncAsByte(_justChangedScene2);
+ byte dummy = 0;
+ s.syncAsByte(dummy); // this was originally _justChangedScene2, but it's never used.
// sync engine play time to ensure various events run correctly.
s.syncAsUint32LE(_thisFrameMs);
diff --git a/engines/dgds/dgds.h b/engines/dgds/dgds.h
index 418d9eee821..af278241892 100644
--- a/engines/dgds/dgds.h
+++ b/engines/dgds/dgds.h
@@ -121,14 +121,15 @@ enum DragonArcadeKeyEvent {
class DgdsEngine : public Engine {
public:
- Common::Platform _platform;
- Common::Language _gameLang;
Sound *_soundPlayer;
Graphics::ManagedSurface _compositionBuffer;
static const byte HOC_CHAR_SWAP_ICONS[];
private:
+ Common::Platform _platform;
+ Common::Language _gameLang;
+
Console *_console;
ResourceManager *_resource;
@@ -166,7 +167,8 @@ private:
int _difficulty;
bool _justChangedScene1;
- bool _justChangedScene2;
+ // There is another flag in Rise of the Dragon, but it seems to never be used for anything?
+ //bool _justChangedScene2;
Common::RandomSource _random;
Common::Point _lastMouse; // originals start mouse at 0,0.
@@ -187,7 +189,7 @@ private:
bool _flipMode;
uint32 _thisFrameMs;
int16 _lastGlobalFade; // Only used in Willy Beamish
- uint _lastGlobalFadedPal;
+ uint _lastGlobalFadedPal; // Only used in Willy Beamish
bool _debugShowHotAreas;
@@ -235,7 +237,6 @@ public:
void setShowClock(bool val);
bool justChangedScene1() const { return _justChangedScene1; }
- bool justChangedScene2() const { return _justChangedScene2; }
Common::Point getLastMouse() const { return _lastMouse; }
Common::Point getLastMouseMinusHot() const;
diff --git a/engines/dgds/head.cpp b/engines/dgds/head.cpp
index 81c39f39f23..ba129c3a569 100644
--- a/engines/dgds/head.cpp
+++ b/engines/dgds/head.cpp
@@ -127,9 +127,9 @@ void TalkDataHead::drawHeadType3(Graphics::ManagedSurface *dst, const Image &img
}
}
-void TalkDataHead::updateHead() {
- warning("TODO: Update head");
- _flags = static_cast<HeadFlags>(_flags & ~(kHeadFlag1 | kHeadFlag8 | kHeadFlag10 | kHeadFlagVisible));
+void TalkDataHead::clearHead() {
+ warning("TODO: Clear head");
+ _flags = static_cast<HeadFlags>(_flags & ~(kHeadFlagFinished | kHeadFlag8 | kHeadFlag10 | kHeadFlagVisible));
/* This seems to just be a "needs redraw" flag, but we always redraw
for (auto tds : _talkData) {
@@ -145,24 +145,28 @@ void TalkDataHead::updateHead() {
}
-void TalkData::updateVisibleHeads() {
+void TalkData::clearVisibleHeads() {
for (auto &head : _heads) {
if (head._flags & kHeadFlagVisible)
- head.updateHead();
+ head.clearHead();
}
}
-void TalkData::drawVisibleHeads(Graphics::ManagedSurface *dst) const {
- for (const auto &h : _heads) {
- if ((h._flags & kHeadFlagVisible) && !(h._flags & kHeadFlag40)) {
- h.drawHead(dst, *this);
+void TalkData::drawAndUpdateVisibleHeads(Graphics::ManagedSurface *dst) {
+ for (auto &h : _heads) {
+ if (h._flags & kHeadFlagVisible) {
+ if (!(h._flags & kHeadFlagOpening)) {
+ h.drawHead(dst, *this);
+ } else {
+ h._flags = static_cast<HeadFlags>(h._flags & ~kHeadFlagOpening);
+ }
}
}
}
bool TalkData::hasVisibleHead() const {
for (const auto &h : _heads) {
- if (h._flags & kHeadFlagVisible)
+ if (h._flags & kHeadFlagVisible && !(h._flags & kHeadFlagOpening))
return true;
}
return false;
diff --git a/engines/dgds/head.h b/engines/dgds/head.h
index 25476a473b4..5446945cdf8 100644
--- a/engines/dgds/head.h
+++ b/engines/dgds/head.h
@@ -53,13 +53,13 @@ public:
enum HeadFlags {
kHeadFlagNone = 0,
- kHeadFlag1 = 1,
+ kHeadFlagFinished = 1,
kHeadFlag2 = 2,
kHeadFlag4 = 4,
kHeadFlag8 = 8,
kHeadFlag10 = 0x10,
kHeadFlagVisible = 0x20,
- kHeadFlag40 = 0x40,
+ kHeadFlagOpening = 0x40,
kHeadFlag80 = 0x80,
};
@@ -70,7 +70,7 @@ public:
TalkDataHead() : _num(0), _drawType(0), _drawCol(0), _flags(kHeadFlagNone) {}
Common::String dump(const Common::String &indent) const;
- void updateHead();
+ void clearHead();
void drawHead(Graphics::ManagedSurface *dst, const TalkData &data) const;
void drawHeadType1(Graphics::ManagedSurface *dst, const Image &img) const;
@@ -100,8 +100,8 @@ public:
uint16 _val;
Common::String _bmpFile;
- void updateVisibleHeads();
- void drawVisibleHeads(Graphics::ManagedSurface *dst) const;
+ void clearVisibleHeads();
+ void drawAndUpdateVisibleHeads(Graphics::ManagedSurface *dst);
bool hasVisibleHead() const;
};
diff --git a/engines/dgds/scene.cpp b/engines/dgds/scene.cpp
index 47c4be39bfa..32d72ce6fe9 100644
--- a/engines/dgds/scene.cpp
+++ b/engines/dgds/scene.cpp
@@ -871,15 +871,15 @@ bool SDSScene::freeTalkData(uint16 num) {
return result;
}
-void SDSScene::updateVisibleTalkers() {
+void SDSScene::clearVisibleTalkers() {
for (auto &data : _talkData) {
- data.updateVisibleHeads();
+ data.clearVisibleHeads();
}
}
-void SDSScene::drawVisibleHeads(Graphics::ManagedSurface *dst) {
- for (const auto &tds : _talkData) {
- tds.drawVisibleHeads(dst);
+void SDSScene::drawAndUpdateHeads(Graphics::ManagedSurface *dst) {
+ for (auto &tds : _talkData) {
+ tds.drawAndUpdateVisibleHeads(dst);
}
if (_conversation.isForDlg(getVisibleDialog())) {
@@ -897,7 +897,7 @@ bool SDSScene::hasVisibleHead() const {
bool SDSScene::loadTalkDataAndSetFlags(uint16 talknum, uint16 headnum) {
- updateVisibleTalkers();
+ clearVisibleTalkers();
_conversation._drawRect = DgdsRect();
if (loadTalkData(talknum)) {
@@ -910,8 +910,8 @@ bool SDSScene::loadTalkDataAndSetFlags(uint16 talknum, uint16 headnum) {
continue;
_conversation._drawRect = head._rect;
- head._flags = static_cast<HeadFlags>(head._flags & ~(kHeadFlag1 | kHeadFlag10));
- head._flags = static_cast<HeadFlags>(head._flags | (kHeadFlag8 | kHeadFlagVisible));
+ head._flags = static_cast<HeadFlags>(head._flags & ~(kHeadFlagFinished | kHeadFlag10));
+ head._flags = static_cast<HeadFlags>(head._flags | (kHeadFlag8 | kHeadFlagVisible | kHeadFlagOpening));
break;
}
break;
diff --git a/engines/dgds/scene.h b/engines/dgds/scene.h
index cb148da9318..ed0f35a1e1e 100644
--- a/engines/dgds/scene.h
+++ b/engines/dgds/scene.h
@@ -319,9 +319,9 @@ public:
void freeDialogData(uint16 num);
bool loadTalkData(uint16 num);
bool freeTalkData(uint16 num);
- void updateVisibleTalkers();
+ void clearVisibleTalkers();
bool loadTalkDataAndSetFlags(uint16 talknum, uint16 headnum);
- void drawVisibleHeads(Graphics::ManagedSurface *dst);
+ void drawAndUpdateHeads(Graphics::ManagedSurface *dst);
bool hasVisibleHead() const;
// dragon-specific scene ops
diff --git a/engines/dgds/scene_op.cpp b/engines/dgds/scene_op.cpp
index 176d747bcb6..09ff7216a97 100644
--- a/engines/dgds/scene_op.cpp
+++ b/engines/dgds/scene_op.cpp
@@ -59,7 +59,7 @@ static Common::String _sceneOpCodeName(SceneOpCode code) {
case kSceneOpShowMouse: return "showMouse";
case kSceneOpHideMouse: return "hideMouse";
case kSceneOpLoadTalkDataAndSetFlags: return "loadTalkDataAndSetFlags";
- case kSceneOpDrawVisibleTalkHeads: return "drawVisibleTalksHeads";
+ case kSceneOpClearVisibleTalkHeads: return "clearVisibleTalksHeads";
case kSceneOpLoadTalkData: return "loadTalkData";
case kSceneOpLoadDDSData: return "loadDDSData";
case kSceneOpFreeDDSData: return "freeDDSData";
@@ -263,8 +263,8 @@ bool SceneOp::runCommonOp() const {
case kSceneOpLoadTalkDataAndSetFlags: // args: tdsnum to load, headnum
engine->getScene()->loadTalkDataAndSetFlags(_args[0], _args[1]);
break;
- case kSceneOpDrawVisibleTalkHeads: // args: none
- engine->getScene()->updateVisibleTalkers();
+ case kSceneOpClearVisibleTalkHeads: // args: none
+ engine->getScene()->clearVisibleTalkers();
break;
case kSceneOpLoadTalkData: // args: tds num to load
engine->getScene()->loadTalkData(_args[0]);
diff --git a/engines/dgds/scene_op.h b/engines/dgds/scene_op.h
index 33325d80eda..a3f653879b7 100644
--- a/engines/dgds/scene_op.h
+++ b/engines/dgds/scene_op.h
@@ -53,7 +53,7 @@ enum SceneOpCode {
// Op 20 onward are common, but not in dragon
kSceneOpLoadTalkDataAndSetFlags = 20, // args: tdsnum to load, headnum
- kSceneOpDrawVisibleTalkHeads = 21, // args: none
+ kSceneOpClearVisibleTalkHeads = 21, // args: none
kSceneOpLoadTalkData = 22, // args: tds num to load
kSceneOpLoadDDSData = 24, // args: dds num to load
kSceneOpFreeDDSData = 25, // args: dds num to free
diff --git a/engines/dgds/ttm.cpp b/engines/dgds/ttm.cpp
index 5d87acad335..ffdbeff61f3 100644
--- a/engines/dgds/ttm.cpp
+++ b/engines/dgds/ttm.cpp
@@ -1179,7 +1179,7 @@ void TTMInterpreter::handleOperation(TTMEnviro &env, TTMSeq &seq, uint16 op, byt
if (seq._executed) // this is a one-shot op
break;
- if (_vm->_platform == Common::kPlatformAmiga) {
+ if (_vm->getPlatform() == Common::kPlatformAmiga) {
// TODO: remove hard-coded stuff..
_vm->_soundPlayer->playAmigaSfx("DYNAMIX.INS", 0, 255);
} else {
More information about the Scummvm-git-logs
mailing list