mirror of
https://github.com/libretro/scummvm.git
synced 2025-03-02 08:19:19 +00:00
DIRECTOR: Add CD loading delay quirk
Spaceship Warlock is optimised for very slow disk reads; quite a lot of movie changes will be preceded by a music cue and a still image, knowing that the system will take a couple of seconds to read the next file. As a compromise, add a fake delay of [file size]*1000/150000 ms to movie switches. This can be short-circuited by clicking the mouse, so it is still possible to navigate around quickly.
This commit is contained in:
parent
d3ffe66fe5
commit
b163dba86d
@ -101,6 +101,8 @@ DirectorEngine::DirectorEngine(OSystem *syst, const DirectorGameDescription *gam
|
||||
_forceDate.tm_mon = -1;
|
||||
_forceDate.tm_year = -1;
|
||||
_forceDate.tm_wday = -1;
|
||||
_loadSlowdownFactor = 0;
|
||||
_loadSlowdownCooldownTime = 0;
|
||||
|
||||
_wm = nullptr;
|
||||
|
||||
|
@ -228,12 +228,13 @@ public:
|
||||
bool desktopEnabled();
|
||||
|
||||
// events.cpp
|
||||
bool processEvents(bool captureClick = false);
|
||||
bool processEvents(bool captureClick = false, bool skipWindowManager = false);
|
||||
void processEventQUIT();
|
||||
uint32 getMacTicks();
|
||||
|
||||
// game-quirks.cpp
|
||||
void gameQuirks(const char *target, Common::Platform platform);
|
||||
void loadSlowdownCooloff(uint32 delay = 2000);
|
||||
|
||||
void delayMillis(uint32 delay);
|
||||
|
||||
@ -282,6 +283,8 @@ public:
|
||||
// used for quirks
|
||||
byte _fpsLimit;
|
||||
TimeDate _forceDate;
|
||||
uint32 _loadSlowdownFactor;
|
||||
uint32 _loadSlowdownCooldownTime;
|
||||
|
||||
private:
|
||||
byte _currentPalette[768];
|
||||
|
@ -40,14 +40,14 @@ namespace Director {
|
||||
|
||||
uint32 DirectorEngine::getMacTicks() { return (g_system->getMillis() * 60 / 1000.) - _tickBaseline; }
|
||||
|
||||
bool DirectorEngine::processEvents(bool captureClick) {
|
||||
bool DirectorEngine::processEvents(bool captureClick, bool skipWindowManager) {
|
||||
debugC(5, kDebugEvents, "\n@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
|
||||
debugC(5, kDebugEvents, "@@@@ Processing events");
|
||||
debugC(5, kDebugEvents, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n");
|
||||
|
||||
Common::Event event;
|
||||
while (g_system->getEventManager()->pollEvent(event)) {
|
||||
if (!_wm->processEvent(event)) {
|
||||
if (skipWindowManager || !_wm->processEvent(event)) {
|
||||
// We only want to handle these events if the event
|
||||
// wasn't handled by the window manager.
|
||||
switch (event.type) {
|
||||
@ -71,7 +71,7 @@ bool DirectorEngine::processEvents(bool captureClick) {
|
||||
if (captureClick)
|
||||
return true;
|
||||
break;
|
||||
case Common::EVENT_LBUTTONDOWN:
|
||||
case Common::EVENT_LBUTTONUP:
|
||||
if (captureClick)
|
||||
return true;
|
||||
break;
|
||||
@ -261,6 +261,7 @@ bool Movie::processEvent(Common::Event &event) {
|
||||
|
||||
_currentHiliteChannelId = 0;
|
||||
_mouseDownWasInButton = false;
|
||||
g_director->loadSlowdownCooloff();
|
||||
return true;
|
||||
|
||||
case Common::EVENT_KEYDOWN:
|
||||
@ -276,6 +277,7 @@ bool Movie::processEvent(Common::Event &event) {
|
||||
_lastTimeOut = _lastEventTime;
|
||||
|
||||
queueUserEvent(kEventKeyDown);
|
||||
g_director->loadSlowdownCooloff();
|
||||
return true;
|
||||
|
||||
case Common::EVENT_KEYUP:
|
||||
|
@ -100,6 +100,11 @@ struct SaveFilePath {
|
||||
};
|
||||
|
||||
|
||||
static void quirkWarlock() {
|
||||
g_director->_loadSlowdownFactor = 150000; // emulate a 1x CD drive
|
||||
g_director->_fpsLimit = 15;
|
||||
}
|
||||
|
||||
static void quirkLimit15FPS() {
|
||||
g_director->_fpsLimit = 15;
|
||||
}
|
||||
@ -175,6 +180,12 @@ struct Quirk {
|
||||
Common::Platform platform;
|
||||
void (*quirk)();
|
||||
} quirks[] = {
|
||||
// Spaceship Warlock is designed to run as quickly as possible on a
|
||||
// single speed CD drive; there's often content just before a movie
|
||||
// transition which would otherwise get skipped past.
|
||||
{ "warlock", Common::kPlatformMacintosh, &quirkWarlock },
|
||||
{ "warlock", Common::kPlatformWindows, &quirkWarlock },
|
||||
|
||||
// Eastern Mind sets the score to play back at a high frame rate,
|
||||
// however the developers were using slow hardware, so some
|
||||
// animations play back much faster than intended.
|
||||
@ -253,6 +264,11 @@ void DirectorEngine::gameQuirks(const char *target, Common::Platform platform) {
|
||||
}
|
||||
}
|
||||
|
||||
void DirectorEngine::loadSlowdownCooloff(uint32 delay) {
|
||||
if (_loadSlowdownFactor)
|
||||
_loadSlowdownCooldownTime = g_system->getMillis() + delay;
|
||||
}
|
||||
|
||||
/*****************
|
||||
* CachedArchive
|
||||
*****************/
|
||||
|
@ -500,6 +500,7 @@ Common::String rectifyRelativePath(const Common::String &path, const Common::Pat
|
||||
}
|
||||
Common::String result = "@:" + Common::Path::joinComponents(components).toString(g_director->_dirSeparator);
|
||||
debug(9, "rectifyRelativePath(): '%s' + '%s' => '%s'", base.toString(g_director->_dirSeparator).c_str(), path.c_str(), result.c_str());
|
||||
warning("rectifyRelativePath(): '%s' + '%s' => '%s'", base.toString(g_director->_dirSeparator).c_str(), path.c_str(), result.c_str());
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -443,6 +443,32 @@ bool Window::loadNextMovie() {
|
||||
return false;
|
||||
|
||||
probeResources(mov);
|
||||
|
||||
// Artificial delay for games that expect slow media, e.g. Spaceship Warlock
|
||||
if (g_director->_loadSlowdownFactor && !debugChannelSet(-1, kDebugFast)) {
|
||||
// Check that we're not cooling down from skipping a delay.
|
||||
if (g_system->getMillis() > g_director->_loadSlowdownCooldownTime) {
|
||||
uint32 delay = mov->getFileSize() * 1000 / g_director->_loadSlowdownFactor;
|
||||
debugC(5, kDebugLoading, "Slowing load of next movie by %d ms", delay);
|
||||
while (delay != 0) {
|
||||
uint32 dec = MIN((uint32)10, delay);
|
||||
// Skip delay if mouse is clicked
|
||||
if (g_director->processEvents(true, true)) {
|
||||
g_director->loadSlowdownCooloff();
|
||||
break;
|
||||
}
|
||||
g_director->_wm->replaceCursor(Graphics::kMacCursorWatch);
|
||||
g_director->draw();
|
||||
g_system->delayMillis(dec);
|
||||
delay -= dec;
|
||||
}
|
||||
}
|
||||
// If this movie switch is within the cooldown time,
|
||||
// don't add a delay. This is to allow for rapid navigation.
|
||||
// User input events will call loadSlowdownCooloff() and
|
||||
// extend the cooldown time.
|
||||
}
|
||||
|
||||
_currentMovie = new Movie(this);
|
||||
_currentMovie->setArchive(mov);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user