From 639c02b76f591fe17ee78b6a72da46c4782fd4d5 Mon Sep 17 00:00:00 2001 From: Matthew Stewart Date: Tue, 17 Jul 2018 20:49:59 -0400 Subject: STARTREK: Fix sound, support MT32. Also jump to the first mission after the intro. --- engines/startrek/events.cpp | 159 ++++++++++++++++++++++-------------------- engines/startrek/graphics.cpp | 12 +--- engines/startrek/sound.cpp | 4 +- engines/startrek/startrek.cpp | 53 ++++++++------ engines/startrek/startrek.h | 15 +++- 5 files changed, 129 insertions(+), 114 deletions(-) (limited to 'engines') diff --git a/engines/startrek/events.cpp b/engines/startrek/events.cpp index 4685fded59..6315899efc 100644 --- a/engines/startrek/events.cpp +++ b/engines/startrek/events.cpp @@ -23,89 +23,72 @@ namespace StarTrek { -/** - * Doesn't return until an event occurs. - */ -void StarTrekEngine::pollSystemEvents(bool queueEvents) { +void StarTrekEngine::pollEvents(bool queueEvents) { Common::Event event; TrekEvent trekEvent; + while (_eventMan->pollEvent(event)) { + trekEvent.mouse = event.mouse; + trekEvent.kbd = event.kbd; + + switch (event.type) { + case Common::EVENT_QUIT: + _system->quit(); + break; - while (!queueEvents || _eventQueue.empty()) { - while (_eventMan->pollEvent(event)) { - trekEvent.mouse = event.mouse; - trekEvent.kbd = event.kbd; - - switch (event.type) { - case Common::EVENT_QUIT: - _system->quit(); - break; - - case Common::EVENT_MOUSEMOVE: - if (queueEvents) { - trekEvent.type = TREKEVENT_MOUSEMOVE; - addEventToQueue(trekEvent); - } - - // WORKAROUND: this improves the responsiveness of the mouse. - _system->updateScreen(); - break; - - case Common::EVENT_LBUTTONDOWN: - if (queueEvents) { - trekEvent.type = TREKEVENT_LBUTTONDOWN; - addEventToQueue(trekEvent); - } - break; - - case Common::EVENT_RBUTTONDOWN: - if (queueEvents) { - trekEvent.type = TREKEVENT_RBUTTONDOWN; - addEventToQueue(trekEvent); - } - break; - - case Common::EVENT_KEYDOWN: - if (queueEvents) { - trekEvent.type = TREKEVENT_KEYDOWN; - addEventToQueue(trekEvent); - } - break; - - default: - break; + case Common::EVENT_MOUSEMOVE: + if (queueEvents) { + trekEvent.type = TREKEVENT_MOUSEMOVE; + addEventToQueue(trekEvent); } - } - // Check for tick event - uint nextFrame = _frameStartMillis + 1000 / 18.206; - uint millis = _system->getMillis(); + // WORKAROUND: this improves the responsiveness of the mouse. + _system->updateScreen(); + break; - if (millis >= nextFrame) { - _clockTicks++; + case Common::EVENT_LBUTTONDOWN: + if (queueEvents) { + trekEvent.type = TREKEVENT_LBUTTONDOWN; + addEventToQueue(trekEvent); + } + break; - _frameStartMillis = millis; + case Common::EVENT_RBUTTONDOWN: + if (queueEvents) { + trekEvent.type = TREKEVENT_RBUTTONDOWN; + addEventToQueue(trekEvent); + } + break; + case Common::EVENT_KEYDOWN: if (queueEvents) { - TrekEvent tickEvent; - tickEvent.type = TREKEVENT_TICK; - tickEvent.tick = _clockTicks; - addEventToQueue(tickEvent); + trekEvent.type = TREKEVENT_KEYDOWN; + addEventToQueue(trekEvent); } - } + break; - if (queueEvents && !_eventQueue.empty()) + default: break; + } + } +} - // Wait a 60th of a second before checking for events again - int delay = 1000 / 60; - millis = _system->getMillis(); - if (millis + delay > nextFrame) - delay = nextFrame - millis; - if (delay > 0) - _system->delayMillis(delay); +void StarTrekEngine::waitForNextTick(bool queueEvents) { + pollEvents(queueEvents); - if (!queueEvents) - break; + uint nextFrame = _frameStartMillis + 1000 / 18.206; + uint millis = _system->getMillis(); + + if (millis < nextFrame) + _system->delayMillis(nextFrame - millis); + + _clockTicks++; + _frameStartMillis = nextFrame; + + if (queueEvents) { + TrekEvent tickEvent; + tickEvent.type = TREKEVENT_TICK; + tickEvent.tick = _clockTicks; + addEventToQueue(tickEvent); } } @@ -117,11 +100,35 @@ void StarTrekEngine::initializeEventsAndMouse() { // TODO: mouse } -/** - * Returns false if there is no event waiting. - */ -bool StarTrekEngine::getNextEvent(TrekEvent *e) { - pollSystemEvents(); // TODO: put this somewhere else? +bool StarTrekEngine::getNextEvent(TrekEvent *e, bool poll) { + while (poll && _eventQueue.empty()) { + pollEvents(true); + + // Check for tick event + uint nextFrame = _frameStartMillis + 1000 / 18.206; + uint millis = _system->getMillis(); + + if (millis >= nextFrame) { + _clockTicks++; + _frameStartMillis = millis; + + TrekEvent tickEvent; + tickEvent.type = TREKEVENT_TICK; + tickEvent.tick = _clockTicks; + addEventToQueue(tickEvent); + } + + if (!_eventQueue.empty()) + break; + + // Still no events; wait a 60th of a second before checking for events again + int delay = 1000 / 60; + millis = _system->getMillis(); + if (millis + delay > nextFrame) + delay = nextFrame - millis; + if (delay > 0) + _system->delayMillis(delay); + } if (_eventQueue.empty()) return false; @@ -143,8 +150,8 @@ void StarTrekEngine::removeNextEvent() { _eventQueue.pop_front(); } -bool StarTrekEngine::popNextEvent(TrekEvent *e) { - if (!getNextEvent(e)) +bool StarTrekEngine::popNextEvent(TrekEvent *e, bool poll) { + if (!getNextEvent(e, poll)) return false; removeNextEvent(); diff --git a/engines/startrek/graphics.cpp b/engines/startrek/graphics.cpp index 9b1801b47f..6fe1c8f9ba 100644 --- a/engines/startrek/graphics.cpp +++ b/engines/startrek/graphics.cpp @@ -134,11 +134,7 @@ void Graphics::loadPalette(const Common::String &paletteName) { void Graphics::fadeinScreen() { while (_paletteFadeLevel <= 100) { TrekEvent event; - do { - if (!_vm->popNextEvent(&event)) - continue; - } - while (event.type != TREKEVENT_TICK); + _vm->waitForNextTick(); setPaletteFadeLevel(_palData, _paletteFadeLevel); _paletteFadeLevel += 10; @@ -150,11 +146,7 @@ void Graphics::fadeinScreen() { void Graphics::fadeoutScreen() { while (_paletteFadeLevel >= 0) { TrekEvent event; - do { - if (!_vm->popNextEvent(&event)) - continue; - } - while (event.type != TREKEVENT_TICK); + _vm->waitForNextTick(); setPaletteFadeLevel(_palData, _paletteFadeLevel); _paletteFadeLevel -= 10; diff --git a/engines/startrek/sound.cpp b/engines/startrek/sound.cpp index b07fc68892..3d141499d3 100644 --- a/engines/startrek/sound.cpp +++ b/engines/startrek/sound.cpp @@ -36,7 +36,7 @@ namespace StarTrek { Sound::Sound(StarTrekEngine *vm) : _vm(vm) { if (_vm->getPlatform() == Common::kPlatformDOS || _vm->getPlatform() == Common::kPlatformMacintosh) { - _midiDevice = MidiDriver::detectDevice(MDT_PCSPK|MDT_ADLIB|MDT_MIDI); + _midiDevice = MidiDriver::detectDevice(MDT_PCSPK | MDT_ADLIB | MDT_MIDI | MDT_PREFER_MT32); _midiDriver = MidiDriver::createMidi(_midiDevice); _midiDriver->open(); _midiDriver->setTimerCallback(this, Sound::midiDriverCallback); @@ -366,7 +366,7 @@ void Sound::clearMidiSlot(int slot) { // Static callback method void Sound::midiDriverCallback(void *data) { Sound *s = (Sound*)data; - for (int i = NUM_MIDI_SLOTS; i < NUM_MIDI_SLOTS; i++) + for (int i = 0; i < NUM_MIDI_SLOTS; i++) s->_midiSlots[i].midiParser->onTimer(); // TODO: put this somewhere other than the midi callback... diff --git a/engines/startrek/startrek.cpp b/engines/startrek/startrek.cpp index f53ba176fb..a6addb799b 100644 --- a/engines/startrek/startrek.cpp +++ b/engines/startrek/startrek.cpp @@ -87,7 +87,7 @@ StarTrekEngine::StarTrekEngine(OSystem *syst, const StarTrekGameDescription *gam _missionToLoad = "DEMON"; _roomIndexToLoad = 0; - _showSubtitles = false; // TODO: test + _showSubtitles = true; // TODO: test for (int i = 0; i < NUM_OBJECTS; i++) _itemList[i] = g_itemList[i]; @@ -116,13 +116,14 @@ Common::Error StarTrekEngine::run() { _frameIndex = 0; playIntro(); + debug("DONE"); _frameIndex = 0; _gameMode = -1; _lastGameMode = -1; - runGameMode(GAMEMODE_START); + runGameMode(GAMEMODE_AWAYMISSION); return Common::kNoError; } @@ -229,11 +230,11 @@ void StarTrekEngine::playIntro() { uint32 clockTicks = _clockTicks; - Sprite sprite; - _gfx->addSprite(&sprite); - sprite.setXYAndPriority(0, 0, 12); - sprite.bitmap = _gfx->loadBitmap("blank"); - sprite.drawPriority2 = 16; + Sprite subtitleSprite; + _gfx->addSprite(&subtitleSprite); + subtitleSprite.setXYAndPriority(0, 0, 12); + subtitleSprite.bitmap = _gfx->loadBitmap("blank"); + subtitleSprite.drawPriority2 = 16; int index = 12; while (index >= 0) { @@ -268,7 +269,7 @@ void StarTrekEngine::playIntro() { clockTicks += 540; while (_clockTicks < clockTicks && _sound->isMidiPlaying()) { - pollSystemEvents(false); + waitForNextTick(true); } // TODO: MT audio file @@ -281,16 +282,18 @@ void StarTrekEngine::playIntro() { int32 starfieldZoomSpeed; int16 frame = 0; - bool buttonPressed = 0; + bool buttonPressed = false; while (frame != 0x180 || (_sound->isMidiPlaying() && !buttonPressed)) { - TrekEvent event; - while (popNextEvent(&event)) { - if (event.type == TREKEVENT_KEYDOWN) { - _gfx->fadeoutScreen(); - buttonPressed = true; - } else if (event.type == TREKEVENT_TICK) - break; + if (!buttonPressed) { + TrekEvent event; + while (popNextEvent(&event, false)) { + if (event.type == TREKEVENT_KEYDOWN) { + _gfx->fadeoutScreen(); + buttonPressed = true; + } else if (event.type == TREKEVENT_TICK) + break; + } } switch (frame) { @@ -302,15 +305,20 @@ void StarTrekEngine::playIntro() { case 30: _sound->playVoc("kirkintr"); - loadSubtitleSprite(0, &sprite); + loadSubtitleSprite(0, &subtitleSprite); break; case 36: - loadSubtitleSprite(1, &sprite); + loadSubtitleSprite(1, &subtitleSprite); break; case 42: - loadSubtitleSprite(-1, &sprite); + loadSubtitleSprite(-1, &subtitleSprite); + break; + + case 378: + _gfx->delSprite(&subtitleSprite); + _byte_45b3c = 1; break; } @@ -321,7 +329,7 @@ void StarTrekEngine::playIntro() { clockTicks += 3; while (_clockTicks < clockTicks) - pollSystemEvents(false); + waitForNextTick(); } _starfieldPosition.z += starfieldZoomSpeed; @@ -418,10 +426,9 @@ void StarTrekEngine::drawStarfield() { file->seek(fileOffset, SEEK_SET); SharedPtr bitmap = SharedPtr(new Bitmap(file)); - if (!drawRect.isEmpty()) { + if (!drawRect.isEmpty()) _gfx->drawBitmapToBackground(starRect, drawRect, bitmap); - bitmap.reset(); - } + bitmap.reset(); } else { star->active = false; diff --git a/engines/startrek/startrek.h b/engines/startrek/startrek.h index 21981e2382..d5000f79ea 100644 --- a/engines/startrek/startrek.h +++ b/engines/startrek/startrek.h @@ -339,11 +339,20 @@ public: // Events public: - void pollSystemEvents(bool queueEvents = true); + /** + * Checks for all events, and updates Star Trek's event queue if queueEvents is set. + * This does not account for "tick" events (getNextEvent/popNextEvent handle that). + */ + void pollEvents(bool queueEvents = true); + void waitForNextTick(bool queueEvents = true); void initializeEventsAndMouse(); - bool getNextEvent(TrekEvent *e); + /** + * Returns false if there is no event waiting. If "poll" is true, this always returns + * something (waits until an event occurs if necessary). + */ + bool getNextEvent(TrekEvent *e, bool poll = true); void removeNextEvent(); - bool popNextEvent(TrekEvent *e); + bool popNextEvent(TrekEvent *e, bool poll = true); void addEventToQueue(const TrekEvent &e); void clearEventBuffer(); void updateEvents(); -- cgit v1.2.3