[Scummvm-git-logs] scummvm master -> b231384f9bb5d3b6932f14d9f8b46829bb2eb799
mgerhardy
noreply at scummvm.org
Fri Sep 13 15:07:45 UTC 2024
This automated email contains information about 8 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
ef7b4edb9f TWINE: renamed music related methods
69c5c3a43c TWINE: updated the music code and renamed methods and variables...
37cac532dd TWINE: fixed demo menu handling for music
d6a0b5fb47 TWINE: fixed mouse cursor config var handling
faeef14bec TWINE: improved mouse support for behaviour switch and inventory
2f10fb20f8 TWINE: renamed methods to match original source
78b15a7e89 TWINE: LBA2: prepare body and anim parser for lba2
b231384f9b TWINE: LBA2: the scene index needs a small offset
Commit: ef7b4edb9f23ffbca2f2607c2460ec946a298f36
https://github.com/scummvm/scummvm/commit/ef7b4edb9f23ffbca2f2607c2460ec946a298f36
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2024-09-13T17:07:29+02:00
Commit Message:
TWINE: renamed music related methods
Changed paths:
engines/twine/audio/music.cpp
engines/twine/audio/music.h
engines/twine/debugger/console.cpp
engines/twine/menu/menu.cpp
engines/twine/menu/menuoptions.cpp
engines/twine/movies.cpp
engines/twine/renderer/screens.cpp
engines/twine/scene/gamestate.cpp
engines/twine/scene/scene.cpp
engines/twine/script/script_life.cpp
engines/twine/script/script_life_v1.cpp
engines/twine/twine.cpp
diff --git a/engines/twine/audio/music.cpp b/engines/twine/audio/music.cpp
index c8cf1fd4f9b..86bae9ecd5f 100644
--- a/engines/twine/audio/music.cpp
+++ b/engines/twine/audio/music.cpp
@@ -147,7 +147,7 @@ static const char *musicTracksLba2[] = {
"LOGADPCM"
};
-bool Music::playTrackMusicCd(int32 track) {
+bool Music::playCdTrack(int32 track) {
if (!_engine->_cfgfile.UseCD) {
return false;
}
@@ -176,12 +176,12 @@ bool Music::playTrackMusicCd(int32 track) {
return cdrom->play(track, 1, 0, 0);
}
-void Music::stopTrackMusicCd() {
+void Music::stopMusicCD() {
AudioCDManager *cdrom = g_system->getAudioCDManager();
cdrom->stop();
}
-bool Music::playTrackMusic(int32 track) {
+bool Music::playAllMusic(int32 track) {
if (track == -1) {
stopMusic();
return true;
@@ -195,12 +195,12 @@ bool Music::playTrackMusic(int32 track) {
}
stopMusic();
- if (playTrackMusicCd(track)) {
+ if (playCdTrack(track)) {
currentMusic = track;
debug("Play cd music track %i", track);
return true;
}
- if (playMidiMusic(track)) {
+ if (playMidiFile(track)) {
currentMusic = track;
debug("Play midi music track %i", track);
return true;
@@ -215,10 +215,10 @@ void Music::stopTrackMusic() {
}
musicFadeOut();
- stopTrackMusicCd();
+ stopMusicCD();
}
-bool Music::playMidiMusic(int32 midiIdx, int32 loop) {
+bool Music::playMidiFile(int32 midiIdx) {
if (!_engine->_cfgfile.Sound) {
debug("sound disabled - skip playing %i", midiIdx);
return false;
@@ -233,8 +233,9 @@ bool Music::playMidiMusic(int32 midiIdx, int32 loop) {
currentMusic = midiIdx;
musicFadeOut();
- stopMidiMusic();
+ stopMusicMidi();
+ const int32 loop = 1;
if (_engine->isDotEmuEnhanced() || _engine->isLba1Classic()) {
Common::Path trackName(Common::String::format("lba1-%02i", midiIdx + 1));
Audio::SeekableAudioStream *stream = Audio::SeekableAudioStream::openStreamFile(trackName);
@@ -266,8 +267,8 @@ bool Music::playMidiMusic(int32 midiIdx, int32 loop) {
return true;
}
-void Music::stopMidiMusic() {
- if (_engine->isDotEmuEnhanced() || _engine->isLba1Classic()) {
+void Music::stopMusicMidi() {
+ if (_engine->isDotEmuEnhanced() || _engine->isLba1Classic() || _engine->isLBA2()) {
_engine->_system->getMixer()->stopHandle(_midiHandle);
}
@@ -284,7 +285,7 @@ bool Music::initCdrom() {
void Music::stopMusic() {
stopTrackMusic();
- stopMidiMusic();
+ stopMusicMidi();
currentMusic = -1;
}
diff --git a/engines/twine/audio/music.h b/engines/twine/audio/music.h
index d580553e2a8..7e847b96ef1 100644
--- a/engines/twine/audio/music.h
+++ b/engines/twine/audio/music.h
@@ -50,7 +50,7 @@ private:
uint8 *midiPtr = nullptr;
Audio::SoundHandle _midiHandle;
/** Track number of the current playing music */
- int32 currentMusic = -1;
+ int32 currentMusic = -1; // NumXmi, CurrentMusicCD
public:
// TODO: implement the handling
int32 _nextMusic = -1; // lba2: NextMusic
@@ -61,9 +61,9 @@ private:
* Play CD music
* @param track track number to play
*/
- bool playTrackMusicCd(int32 track);
+ bool playCdTrack(int32 track);
/** Stop CD music */
- void stopTrackMusicCd();
+ void stopMusicCD();
public:
Music(TwinEEngine *engine);
@@ -77,7 +77,7 @@ public:
* Generic play music, according with settings it plays CD or high quality sounds instead
* @param track track number to play
*/
- bool playTrackMusic(int32 track);
+ bool playAllMusic(int32 track);
/** Generic stop music according with settings */
void stopTrackMusic();
/**
@@ -85,9 +85,9 @@ public:
* @param midiIdx music index under mini_mi_win.hqr
* @note valid indices for lba1 are [1-32]
*/
- bool playMidiMusic(int32 midiIdx, int32 loop = 1);
+ bool playMidiFile(int32 midiIdx);
/** Stop MIDI music */
- void stopMidiMusic();
+ void stopMusicMidi();
/** Initialize CD-Rom */
bool initCdrom();
diff --git a/engines/twine/debugger/console.cpp b/engines/twine/debugger/console.cpp
index 0cc05f58e11..e614069af4f 100644
--- a/engines/twine/debugger/console.cpp
+++ b/engines/twine/debugger/console.cpp
@@ -395,7 +395,7 @@ bool TwinEConsole::doPlayMidi(int argc, const char **argv) {
return true;
}
int newMidiIndex = atoi(argv[1]);
- _engine->_music->playMidiMusic(newMidiIndex);
+ _engine->_music->playMidiFile(newMidiIndex);
return true;
}
@@ -405,7 +405,7 @@ bool TwinEConsole::doPlayMusic(int argc, const char **argv) {
return true;
}
int newMusicTrackIndex = atoi(argv[1]);
- _engine->_music->playTrackMusic(newMusicTrackIndex);
+ _engine->_music->playAllMusic(newMusicTrackIndex);
return true;
}
diff --git a/engines/twine/menu/menu.cpp b/engines/twine/menu/menu.cpp
index f76e17db430..27f167388af 100644
--- a/engines/twine/menu/menu.cpp
+++ b/engines/twine/menu/menu.cpp
@@ -794,7 +794,7 @@ int32 Menu::optionsMenu() {
_engine->restoreFrontBuffer();
_engine->_sound->stopSamples();
- _engine->_music->playTrackMusic(9); // LBA's Theme
+ _engine->_music->playAllMusic(9); // LBA's Theme
ScopedCursor scoped(_engine);
for (;;) {
@@ -897,9 +897,9 @@ EngineState Menu::run() {
_engine->_text->initDial(TextBankId::Options_and_menus);
if (_engine->isLBA1()) {
- _engine->_music->playTrackMusic(9); // LBA's Theme
+ _engine->_music->playAllMusic(9); // LBA's Theme
} else {
- _engine->_music->playTrackMusic(6); // LBA2's Theme
+ _engine->_music->playAllMusic(6); // LBA2's Theme
}
_engine->_sound->stopSamples();
diff --git a/engines/twine/menu/menuoptions.cpp b/engines/twine/menu/menuoptions.cpp
index cfe9ee8bd04..910a634521d 100644
--- a/engines/twine/menu/menuoptions.cpp
+++ b/engines/twine/menu/menuoptions.cpp
@@ -80,7 +80,7 @@ void MenuOptions::newGame() {
_engine->_screens->clearScreen();
if (!aborted) {
- _engine->_music->playMidiMusic(1);
+ _engine->_music->playMidiFile(1);
_engine->_movie->playMovie(FLA_INTROD);
}
diff --git a/engines/twine/movies.cpp b/engines/twine/movies.cpp
index cac69de1097..c24bda3d57b 100644
--- a/engines/twine/movies.cpp
+++ b/engines/twine/movies.cpp
@@ -195,7 +195,7 @@ void Movies::processFrame() {
int16 innerOpcpde = stream.readSint16LE();
switch (innerOpcpde) {
case 1: // fla flute
- _engine->_music->playMidiMusic(26);
+ _engine->_music->playMidiFile(26);
break;
case 2:
// FLA movies don't use cross fade
@@ -211,7 +211,7 @@ void Movies::processFrame() {
break;
case 4:
// TODO: fade out for 1 second before we stop it
- _engine->_music->stopMidiMusic();
+ _engine->_music->stopMusicMidi();
break;
}
break;
diff --git a/engines/twine/renderer/screens.cpp b/engines/twine/renderer/screens.cpp
index 9235ab3f177..380b33d2528 100644
--- a/engines/twine/renderer/screens.cpp
+++ b/engines/twine/renderer/screens.cpp
@@ -51,7 +51,7 @@ int32 Screens::mapLba2Palette(int32 palIndex) {
}
bool Screens::adelineLogo() {
- _engine->_music->playMidiMusic(31);
+ _engine->_music->playMidiFile(31);
return loadImageDelay(_engine->_resources->adelineLogo(), 7);
}
diff --git a/engines/twine/scene/gamestate.cpp b/engines/twine/scene/gamestate.cpp
index 882a39c08cb..d70c4a3cc64 100644
--- a/engines/twine/scene/gamestate.cpp
+++ b/engines/twine/scene/gamestate.cpp
@@ -524,7 +524,7 @@ void GameState::processGameoverAnimation() {
}
_engine->_sound->stopSamples();
- _engine->_music->stopMidiMusic(); // stop fade music
+ _engine->_music->stopMusicMidi(); // stop fade music
_engine->_renderer->setProjection(_engine->width() / 2, _engine->height() / 2, 128, 200, 200);
int32 startLbaTime = _engine->timerRef;
const Common::Rect &rect = _engine->centerOnScreen(_engine->width() / 2, _engine->height() / 2);
diff --git a/engines/twine/scene/scene.cpp b/engines/twine/scene/scene.cpp
index d5c59624f33..25df4d33fb5 100644
--- a/engines/twine/scene/scene.cpp
+++ b/engines/twine/scene/scene.cpp
@@ -639,7 +639,7 @@ void Scene::changeScene() {
if (_sceneMusic != -1) {
debug(2, "Scene %i music track id: %i", _currentSceneIdx, _sceneMusic);
- _engine->_music->playTrackMusic(_sceneMusic);
+ _engine->_music->playAllMusic(_sceneMusic);
}
_engine->_gameState->handleLateGameItems();
}
@@ -675,11 +675,11 @@ void Scene::initSceneVars() {
void Scene::playSceneMusic() {
if (_engine->isLBA1()) {
if (_currentSceneIdx == LBA1SceneId::Tippet_Island_Twinsun_Cafe && _engine->_gameState->hasArrivedHamalayi()) {
- _engine->_music->playTrackMusic(8);
+ _engine->_music->playAllMusic(8);
return;
}
}
- _engine->_music->playMidiMusic(_sceneMusic);
+ _engine->_music->playMidiFile(_sceneMusic);
}
void Scene::processEnvironmentSound() {
diff --git a/engines/twine/script/script_life.cpp b/engines/twine/script/script_life.cpp
index 244fa7cbc66..835f71dd98c 100644
--- a/engines/twine/script/script_life.cpp
+++ b/engines/twine/script/script_life.cpp
@@ -1981,7 +1981,7 @@ int32 ScriptLife::lTHE_END(TwinEEngine *engine, LifeScriptContext &ctx) {
int32 ScriptLife::lPLAY_CD_TRACK(TwinEEngine *engine, LifeScriptContext &ctx) {
const int32 track = ctx.stream.readByte();
debugC(3, kDebugLevels::kDebugScripts, "LIFE::PLAY_CD_TRACK(%i)", (int)track);
- engine->_music->playTrackMusic(track);
+ engine->_music->playAllMusic(track);
return 0;
}
diff --git a/engines/twine/script/script_life_v1.cpp b/engines/twine/script/script_life_v1.cpp
index 645f9b96dca..db1169fdc7c 100644
--- a/engines/twine/script/script_life_v1.cpp
+++ b/engines/twine/script/script_life_v1.cpp
@@ -54,7 +54,7 @@ int32 ScriptLifeV1::lBUBBLE_OFF(TwinEEngine *engine, LifeScriptContext &ctx) {
*/
int32 ScriptLifeV1::lPLAY_MIDI(TwinEEngine *engine, LifeScriptContext &ctx) {
const int32 midiIdx = ctx.stream.readByte();
- engine->_music->playMidiMusic(midiIdx); // TODO: improve this
+ engine->_music->playMidiFile(midiIdx); // TODO: improve this
debugC(3, kDebugLevels::kDebugScripts, "LIFE::PLAY_MIDI(%i)", (int)midiIdx);
return 0;
}
@@ -65,7 +65,7 @@ int32 ScriptLifeV1::lPLAY_MIDI(TwinEEngine *engine, LifeScriptContext &ctx) {
*/
int32 ScriptLifeV1::lMIDI_OFF(TwinEEngine *engine, LifeScriptContext &ctx) {
debugC(3, kDebugLevels::kDebugScripts, "LIFE::MIDI_OFF()");
- engine->_music->stopMidiMusic();
+ engine->_music->stopMusicMidi();
return 0;
}
diff --git a/engines/twine/twine.cpp b/engines/twine/twine.cpp
index a317c5dc7d9..062606e0d8b 100644
--- a/engines/twine/twine.cpp
+++ b/engines/twine/twine.cpp
@@ -387,7 +387,7 @@ Common::Error TwinEEngine::run() {
_sound->stopSamples();
_music->stopTrackMusic();
- _music->stopMidiMusic();
+ _music->stopMusicMidi();
return Common::kNoError;
}
Commit: 69c5c3a43c4444d82b0982fb28061914d0f03aed
https://github.com/scummvm/scummvm/commit/69c5c3a43c4444d82b0982fb28061914d0f03aed
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2024-09-13T17:07:29+02:00
Commit Message:
TWINE: updated the music code and renamed methods and variables...
to match the original source code
This should fix issue https://bugs.scummvm.org/ticket/14669 - but it's hard to say due to the many
different versions that are out there
Changed paths:
engines/twine/audio/music.cpp
engines/twine/audio/music.h
engines/twine/debugger/console.cpp
engines/twine/menu/menu.cpp
engines/twine/menu/menu.h
engines/twine/menu/menuoptions.cpp
engines/twine/scene/gamestate.cpp
engines/twine/scene/scene.cpp
engines/twine/scene/scene.h
engines/twine/script/script_life.cpp
engines/twine/script/script_life_v1.cpp
engines/twine/script/script_life_v2.cpp
engines/twine/twine.cpp
engines/twine/twine.h
diff --git a/engines/twine/audio/music.cpp b/engines/twine/audio/music.cpp
index 86bae9ecd5f..02947635285 100644
--- a/engines/twine/audio/music.cpp
+++ b/engines/twine/audio/music.cpp
@@ -60,7 +60,7 @@ namespace TwinE {
* </pre>
*/
-TwinEMidiPlayer::TwinEMidiPlayer(TwinEEngine* engine) : _engine(engine) {
+TwinEMidiPlayer::TwinEMidiPlayer(TwinEEngine *engine) : _engine(engine) {
MidiPlayer::createDriver();
int ret = _driver->open();
@@ -101,64 +101,80 @@ void TwinEMidiPlayer::play(byte *buf, int size, bool loop) {
Music::Music(TwinEEngine *engine) : _engine(engine), _midiPlayer(engine) {
}
-void Music::musicVolume(int32 volume) {
- _engine->_system->getMixer()->setVolumeForSoundType(Audio::Mixer::SoundType::kMusicSoundType, volume);
- _midiPlayer.setVolume(volume);
-}
-
-void Music::musicFadeIn() {
- int volume = _engine->_system->getMixer()->getVolumeForSoundType(Audio::Mixer::SoundType::kMusicSoundType);
- // TODO implement fade in
- musicVolume(volume);
+int32 Music::getLengthTrackCDR(int track) const {
+ // TODO:
+ return -1;
}
-void Music::musicFadeOut() {
- int volume = _engine->_system->getMixer()->getVolumeForSoundType(Audio::Mixer::SoundType::kMusicSoundType);
- // TODO implement fade out
- musicVolume(volume);
-}
+bool Music::playMidi(int32 midiIdx) {
+ const int32 loop = 1;
+ if (_engine->isDotEmuEnhanced() || _engine->isLba1Classic()) {
+ Common::Path trackName(Common::String::format("lba1-%02i", midiIdx + 1));
+ Audio::SeekableAudioStream *stream = Audio::SeekableAudioStream::openStreamFile(trackName);
+ if (stream != nullptr) {
+ const int volume = _engine->_system->getMixer()->getVolumeForSoundType(Audio::Mixer::kMusicSoundType);
+ _engine->_system->getMixer()->playStream(Audio::Mixer::kMusicSoundType, &_midiHandle,
+ Audio::makeLoopingAudioStream(stream, loop), volume);
+ return true;
+ }
+ }
-static const char *musicTracksLba2[] = {
- "",
- "TADPCM1",
- "TADPCM2",
- "TADPCM3",
- "TADPCM4",
- "TADPCM5",
- "JADPCM01",
- "", // Track6.wav
- "JADPCM02",
- "JADPCM03",
- "JADPCM04",
- "JADPCM05",
- "JADPCM06",
- "JADPCM07",
- "JADPCM08",
- "JADPCM09",
- "JADPCM10",
- "JADPCM11",
- "JADPCM12",
- "JADPCM13",
- "JADPCM14",
- "JADPCM15",
- "JADPCM16",
- "JADPCM17",
- "JADPCM18",
- "LOGADPCM"
-};
+ const char *filename;
+ if (_engine->_cfgfile.MidiType == MIDIFILE_DOS) {
+ filename = Resources::HQR_MIDI_MI_DOS_FILE;
+ } else if (_engine->_cfgfile.MidiType == MIDIFILE_WIN) {
+ filename = Resources::HQR_MIDI_MI_WIN_FILE;
+ } else {
+ debug("midi disabled - skip playing %i", midiIdx);
+ return false;
+ }
-bool Music::playCdTrack(int32 track) {
- if (!_engine->_cfgfile.UseCD) {
+ int32 midiSize = HQR::getAllocEntry(&midiPtr, filename, midiIdx);
+ if (midiSize == 0) {
+ debug("Could not find midi file for index %i", midiIdx);
return false;
}
+ debug("Play midi file for index %i", midiIdx);
+ _midiPlayer.play(midiPtr, midiSize, loop == 0 || loop > 1);
+ return true;
+}
+bool Music::playTrackCDR(int32 track) {
if (_engine->isLBA2()) {
+ static const char *musicTracksLba2[] = {
+ "",
+ "TADPCM1",
+ "TADPCM2",
+ "TADPCM3",
+ "TADPCM4",
+ "TADPCM5",
+ "JADPCM01",
+ "", // Track6.wav
+ "JADPCM02",
+ "JADPCM03",
+ "JADPCM04",
+ "JADPCM05",
+ "JADPCM06",
+ "JADPCM07",
+ "JADPCM08",
+ "JADPCM09",
+ "JADPCM10",
+ "JADPCM11",
+ "JADPCM12",
+ "JADPCM13",
+ "JADPCM14",
+ "JADPCM15",
+ "JADPCM16",
+ "JADPCM17",
+ "JADPCM18",
+ "LOGADPCM"};
+
const char *basename = musicTracksLba2[track];
Audio::SeekableAudioStream *stream = Audio::SeekableAudioStream::openStreamFile(basename);
if (stream != nullptr) {
const int volume = _engine->_system->getMixer()->getVolumeForSoundType(Audio::Mixer::kMusicSoundType);
_engine->_system->getMixer()->playStream(Audio::Mixer::kMusicSoundType, &_midiHandle,
- Audio::makeLoopingAudioStream(stream, 1), volume);
+ Audio::makeLoopingAudioStream(stream, 1), volume);
debug(3, "Play audio track %s for track id %i", basename, track);
return true;
}
@@ -170,10 +186,18 @@ bool Music::playCdTrack(int32 track) {
}
AudioCDManager *cdrom = g_system->getAudioCDManager();
- if (_engine->isDotEmuEnhanced() || _engine->isLba1Classic()) {
- track += 1;
- }
- return cdrom->play(track, 1, 0, 0);
+ return cdrom->play(track + 1, 1, 0, 0);
+}
+
+bool Music::initCdrom() {
+ AudioCDManager *cdrom = g_system->getAudioCDManager();
+ return cdrom->open();
+}
+
+void Music::stopMusic() {
+ stopMusicCD();
+ stopMusicMidi();
+ numXmi = -1;
}
void Music::stopMusicCD() {
@@ -181,7 +205,23 @@ void Music::stopMusicCD() {
cdrom->stop();
}
-bool Music::playAllMusic(int32 track) {
+void Music::fadeMusicMidi(uint32 time) {
+ // TODO implement fade out
+ stopMusicMidi();
+}
+
+void Music::stopMusicMidi() {
+ if (_engine->isDotEmuEnhanced() || _engine->isLba1Classic() || _engine->isLBA2()) {
+ _engine->_system->getMixer()->stopHandle(_midiHandle);
+ }
+
+ _midiPlayer.stop();
+ free(midiPtr);
+ midiPtr = nullptr;
+ numXmi = -1;
+}
+
+bool Music::playMusic(int32 track) {
if (track == -1) {
stopMusic();
return true;
@@ -190,103 +230,101 @@ bool Music::playAllMusic(int32 track) {
return false;
}
- if (track == currentMusic) {
- return true;
- }
-
- stopMusic();
- if (playCdTrack(track)) {
- currentMusic = track;
- debug("Play cd music track %i", track);
- return true;
- }
- if (playMidiFile(track)) {
- currentMusic = track;
- debug("Play midi music track %i", track);
- return true;
+ if (_engine->isCDROM()) {
+ if (_flagVoiceCD || track < 1 || track > 9) {
+ if (playMidiFile(track)) {
+ debug("Play midi music track %i", track);
+ return true;
+ }
+ } else {
+ if (playCdTrack(track)) {
+ debug("Play cd music track %i", track);
+ return true;
+ }
+ }
+ } else {
+ if (playMidiFile(track)) {
+ debug("Play midi music track %i", track);
+ return true;
+ }
}
warning("Failed to play track %i", track);
return false;
}
-void Music::stopTrackMusic() {
- if (!_engine->_cfgfile.Sound) {
- return;
- }
-
- musicFadeOut();
- stopMusicCD();
-}
-
bool Music::playMidiFile(int32 midiIdx) {
if (!_engine->_cfgfile.Sound) {
debug("sound disabled - skip playing %i", midiIdx);
return false;
}
- if (midiIdx == currentMusic) {
- debug("already playing %i", midiIdx);
- return true;
+ if (_engine->isCDROM()) {
+ stopMusicCD();
}
- stopMusic();
- currentMusic = midiIdx;
-
- musicFadeOut();
- stopMusicMidi();
-
- const int32 loop = 1;
- if (_engine->isDotEmuEnhanced() || _engine->isLba1Classic()) {
- Common::Path trackName(Common::String::format("lba1-%02i", midiIdx + 1));
- Audio::SeekableAudioStream *stream = Audio::SeekableAudioStream::openStreamFile(trackName);
- if (stream != nullptr) {
- const int volume = _engine->_system->getMixer()->getVolumeForSoundType(Audio::Mixer::kMusicSoundType);
- _engine->_system->getMixer()->playStream(Audio::Mixer::kMusicSoundType, &_midiHandle,
- Audio::makeLoopingAudioStream(stream, loop), volume);
- return true;
+ if (midiIdx != numXmi || !isMidiPlaying()) {
+ stopMusicMidi();
+ numXmi = midiIdx;
+ if (!playMidi(midiIdx)) {
+ return false;
}
+ // volumeMidi(100);
}
+ return true;
+}
- const char *filename;
- if (_engine->_cfgfile.MidiType == MIDIFILE_DOS) {
- filename = Resources::HQR_MIDI_MI_DOS_FILE;
- } else if (_engine->_cfgfile.MidiType == MIDIFILE_WIN){
- filename = Resources::HQR_MIDI_MI_WIN_FILE;
- } else {
- debug("midi disabled - skip playing %i", midiIdx);
- return false;
+int32 Music::getMusicCD() {
+ AudioCDManager *cdrom = g_system->getAudioCDManager();
+ // if (_engine->_system->getMillis() > endMusicCD) {
+ if (!cdrom->isPlaying()) {
+ currentMusicCD = -1;
}
+ return currentMusicCD;
+}
- int32 midiSize = HQR::getAllocEntry(&midiPtr, filename, midiIdx);
- if (midiSize == 0) {
- debug("Could not find midi file for index %i", midiIdx);
- return false;
+bool Music::playCdTrack(int32 track) {
+ fadeMusicMidi(1);
+ numXmi = -1;
+
+ if (track != getMusicCD()) {
+ stopMusicCD();
+ // TODO: endMusicCD = _engine->toSeconds(getLengthTrackCDR(track + 1)) / 75 + _engine->toSeconds(1);
+ if (playTrackCDR(track)) {
+ // TODO: endMusicCD += _engine->_system->getMillis();
+ currentMusicCD = track;
+ }
}
- debug("Play midi file for index %i", midiIdx);
- _midiPlayer.play(midiPtr, midiSize, loop == 0 || loop > 1);
return true;
}
-void Music::stopMusicMidi() {
- if (_engine->isDotEmuEnhanced() || _engine->isLba1Classic() || _engine->isLBA2()) {
- _engine->_system->getMixer()->stopHandle(_midiHandle);
+void Music::playAllMusic(int num) {
+ if (num != numXmi || !isMidiPlaying()) {
+ stopMusicMidi();
+ numXmi = num;
+ playMidi(num);
+ // volumeMidi(100);
+ }
+ if (num != getMusicCD()) {
+ stopMusicCD();
+ // TODO: endMusicCD = _engine->toSeconds(getLengthTrackCDR(num + 1)) / 75 + _engine->toSeconds(1);
+ if (playTrackCDR(num)) {
+ // TODO: endMusicCD += _engine->_system->getMillis();
+ currentMusicCD = num;
+ }
}
-
- _midiPlayer.stop();
- free(midiPtr);
- midiPtr = nullptr;
}
-bool Music::initCdrom() {
- AudioCDManager* cdrom = g_system->getAudioCDManager();
- _engine->_cfgfile.UseCD = cdrom->open();
- return _engine->_cfgfile.UseCD;
+bool Music::isMidiPlaying() const {
+ if (_engine->isDotEmuEnhanced() || _engine->isLba1Classic()) {
+ return _engine->_system->getMixer()->isSoundHandleActive(_midiHandle);
+ }
+
+ return _midiPlayer.isPlaying();
}
-void Music::stopMusic() {
- stopTrackMusic();
- stopMusicMidi();
- currentMusic = -1;
+void Music::musicVolume(int32 volume) {
+ _engine->_system->getMixer()->setVolumeForSoundType(Audio::Mixer::SoundType::kMusicSoundType, volume);
+ _midiPlayer.setVolume(volume);
}
} // namespace TwinE
diff --git a/engines/twine/audio/music.h b/engines/twine/audio/music.h
index 7e847b96ef1..4a4d67f7925 100644
--- a/engines/twine/audio/music.h
+++ b/engines/twine/audio/music.h
@@ -43,27 +43,27 @@ private:
TwinEEngine *_engine;
TwinEMidiPlayer _midiPlayer;
- void musicFadeIn();
- void musicFadeOut();
+ void fadeMusicMidi(uint32 time = 1);
/** Auxiliar midi pointer to */
uint8 *midiPtr = nullptr;
Audio::SoundHandle _midiHandle;
/** Track number of the current playing music */
- int32 currentMusic = -1; // NumXmi, CurrentMusicCD
+ int32 numXmi = -1;
+ int32 currentMusicCD = -1;
+ // int32 endMusicCD = -1;
+ const bool _flagVoiceCD = false;
public:
// TODO: implement the handling
int32 _nextMusic = -1; // lba2: NextMusic
int32 _nextMusicTimer; // lba2: NextMusicTimer
bool _stopLastMusic = false; // lba2: StopLastMusic
private:
- /**
- * Play CD music
- * @param track track number to play
- */
- bool playCdTrack(int32 track);
/** Stop CD music */
void stopMusicCD();
+ bool playMidi(int32 midiIdx);
+ int32 getLengthTrackCDR(int track) const;
+ bool playTrackCDR(int32 track);
public:
Music(TwinEEngine *engine);
@@ -73,19 +73,25 @@ public:
*/
void musicVolume(int32 volume);
+ /**
+ * Play CD music
+ * @param track track number to play
+ */
+ bool playCdTrack(int32 track);
/**
* Generic play music, according with settings it plays CD or high quality sounds instead
* @param track track number to play
*/
- bool playAllMusic(int32 track);
- /** Generic stop music according with settings */
- void stopTrackMusic();
+ bool playMusic(int32 track);
/**
* Play MIDI music
* @param midiIdx music index under mini_mi_win.hqr
* @note valid indices for lba1 are [1-32]
*/
bool playMidiFile(int32 midiIdx);
+
+ void playAllMusic(int track);
+
/** Stop MIDI music */
void stopMusicMidi();
@@ -94,6 +100,9 @@ public:
/** Stop MIDI and Track music */
void stopMusic();
+
+ bool isMidiPlaying() const;
+ int32 getMusicCD();
};
} // namespace TwinE
diff --git a/engines/twine/debugger/console.cpp b/engines/twine/debugger/console.cpp
index e614069af4f..4553c9ac29c 100644
--- a/engines/twine/debugger/console.cpp
+++ b/engines/twine/debugger/console.cpp
@@ -405,7 +405,7 @@ bool TwinEConsole::doPlayMusic(int argc, const char **argv) {
return true;
}
int newMusicTrackIndex = atoi(argv[1]);
- _engine->_music->playAllMusic(newMusicTrackIndex);
+ _engine->_music->playMusic(newMusicTrackIndex);
return true;
}
@@ -421,7 +421,7 @@ bool TwinEConsole::doChangeScene(int argc, const char **argv) {
}
_engine->_scene->_needChangeScene = atoi(argv[1]);
_engine->_scene->_heroPositionType = ScenePositionType::kScene;
- _engine->_scene->changeScene();
+ _engine->_scene->changeCube();
return true;
}
diff --git a/engines/twine/menu/menu.cpp b/engines/twine/menu/menu.cpp
index 27f167388af..af79295caea 100644
--- a/engines/twine/menu/menu.cpp
+++ b/engines/twine/menu/menu.cpp
@@ -447,7 +447,7 @@ int16 Menu::drawButtons(MenuSettings *menuSettings, bool hover) {
return mouseActiveButton;
}
-int32 Menu::processMenu(MenuSettings *menuSettings) {
+int32 Menu::doGameMenu(MenuSettings *menuSettings) {
int16 currentButton = menuSettings->getActiveButton();
bool buttonsNeedRedraw = true;
const int32 numEntry = menuSettings->getButtonCount();
@@ -694,7 +694,7 @@ int32 Menu::advoptionsMenu() {
ScopedCursor scoped(_engine);
for (;;) {
- switch (processMenu(&_advOptionsMenuState)) {
+ switch (doGameMenu(&_advOptionsMenuState)) {
case (int32)TextId::kReturnMenu: {
return 0;
}
@@ -718,7 +718,7 @@ int32 Menu::savemanageMenu() {
ScopedCursor scoped(_engine);
for (;;) {
- switch (processMenu(&_saveManageMenuState)) {
+ switch (doGameMenu(&_saveManageMenuState)) {
case (int32)TextId::kReturnMenu:
return 0;
case (int32)TextId::kCreateSaveGame:
@@ -738,12 +738,20 @@ int32 Menu::savemanageMenu() {
return 0;
}
-int32 Menu::volumeMenu() {
+int32 Menu::volumeOptions() {
_engine->restoreFrontBuffer();
+ if (_engine->isLBA1()) {
+ if (_engine->isCDROM()) {
+ _engine->_music->playAllMusic(9);
+ } else {
+ _engine->_music->playMidiFile(9);
+ }
+ }
+
ScopedCursor scoped(_engine);
for (;;) {
- switch (processMenu(&_volumeMenuState)) {
+ switch (doGameMenu(&_volumeMenuState)) {
case (int32)TextId::kReturnMenu:
return 0;
case kQuitEngine:
@@ -766,7 +774,7 @@ int32 Menu::languageMenu() {
ScopedCursor scoped(_engine);
for (;;) {
- switch (processMenu(&_languageMenuState)) {
+ switch (doGameMenu(&_languageMenuState)) {
case (int32)TextId::kReturnMenu:
return 0;
case kQuitEngine:
@@ -794,17 +802,17 @@ int32 Menu::optionsMenu() {
_engine->restoreFrontBuffer();
_engine->_sound->stopSamples();
- _engine->_music->playAllMusic(9); // LBA's Theme
+ _engine->_music->playMusic(9); // LBA's Theme
ScopedCursor scoped(_engine);
for (;;) {
- switch (processMenu(&_optionsMenuState)) {
+ switch (doGameMenu(&_optionsMenuState)) {
case (int32)TextId::kReturnGame:
case (int32)TextId::kReturnMenu: {
return 0;
}
case (int32)TextId::kVolumeSettings: {
- checkMenuQuit(volumeMenu()) break;
+ checkMenuQuit(volumeOptions()) break;
}
case (int32)TextId::kCustomLanguageOption: {
checkMenuQuit(languageMenu()) break;
@@ -830,7 +838,7 @@ int32 Menu::newGameClassicMenu() {
ScopedCursor scoped(_engine);
for (;;) {
- switch (processMenu(&_newGameMenuState)) {
+ switch (doGameMenu(&_newGameMenuState)) {
case (int32)TextId::kReturnGame:
case (int32)TextId::kReturnMenu: {
return 0;
@@ -896,15 +904,19 @@ EngineState Menu::run() {
FrameMarker frame(_engine);
_engine->_text->initDial(TextBankId::Options_and_menus);
+ _engine->_sound->stopSamples();
if (_engine->isLBA1()) {
- _engine->_music->playAllMusic(9); // LBA's Theme
+ if (_engine->isCDROM()) {
+ _engine->_music->playCdTrack(9); // LBA's Theme
+ } else {
+ _engine->_music->playMidiFile(9); // LBA's Theme
+ }
} else {
- _engine->_music->playAllMusic(6); // LBA2's Theme
+ _engine->_music->playMusic(6); // LBA2's Theme
}
- _engine->_sound->stopSamples();
ScopedCursor scoped(_engine);
- switch (processMenu(&_mainMenuState)) {
+ switch (doGameMenu(&_mainMenuState)) {
case (int32)TextId::toNewGame:
case (int32)TextId::kNewGame: {
if (_engine->isLba1Classic()) {
@@ -960,7 +972,7 @@ int32 Menu::giveupMenu() {
do {
FrameMarker frame(_engine);
_engine->_text->initDial(TextBankId::Options_and_menus);
- menuId = processMenu(localMenu);
+ menuId = doGameMenu(localMenu);
switch (menuId) {
case (int32)TextId::kContinue:
_engine->_sound->resumeSamples();
diff --git a/engines/twine/menu/menu.h b/engines/twine/menu/menu.h
index 24b0e560807..4689127c220 100644
--- a/engines/twine/menu/menu.h
+++ b/engines/twine/menu/menu.h
@@ -181,7 +181,7 @@ private:
/** Used to run the advanced options menu */
int32 advoptionsMenu();
/** Used to run the volume menu */
- int32 volumeMenu();
+ int32 volumeOptions();
int32 languageMenu();
/** Used to run the save game management menu */
int32 savemanageMenu();
@@ -226,7 +226,7 @@ public:
* @param menuSettings menu settings array with the information to build the menu options
* @return pressed menu button identification
*/
- int32 processMenu(MenuSettings *menuSettings);
+ int32 doGameMenu(MenuSettings *menuSettings);
bool init();
diff --git a/engines/twine/menu/menuoptions.cpp b/engines/twine/menu/menuoptions.cpp
index 910a634521d..0a124f1cf03 100644
--- a/engines/twine/menu/menuoptions.cpp
+++ b/engines/twine/menu/menuoptions.cpp
@@ -379,7 +379,7 @@ int MenuOptions::chooseSave(TextId textIdx, bool showEmptySlots) {
}
}
- const int32 id = _engine->_menu->processMenu(&saveFiles);
+ const int32 id = _engine->_menu->doGameMenu(&saveFiles);
switch (id) {
case kQuitEngine:
case (int32)TextId::kReturnMenu:
diff --git a/engines/twine/scene/gamestate.cpp b/engines/twine/scene/gamestate.cpp
index d70c4a3cc64..3442e8c522b 100644
--- a/engines/twine/scene/gamestate.cpp
+++ b/engines/twine/scene/gamestate.cpp
@@ -487,7 +487,7 @@ void GameState::processGameChoices(TextId choiceIdx) {
_engine->_text->drawAskQuestion(choiceIdx);
- _engine->_menu->processMenu(&_gameChoicesSettings);
+ _engine->_menu->doGameMenu(&_gameChoicesSettings);
const int16 activeButton = _gameChoicesSettings.getActiveButton();
_choiceAnswer = _gameChoices[activeButton];
diff --git a/engines/twine/scene/scene.cpp b/engines/twine/scene/scene.cpp
index 25df4d33fb5..da24815b642 100644
--- a/engines/twine/scene/scene.cpp
+++ b/engines/twine/scene/scene.cpp
@@ -206,7 +206,7 @@ bool Scene::loadSceneLBA2() {
_sampleMinDelay = stream.readUint16LE();
_sampleMinDelayRnd = stream.readUint16LE();
- _sceneMusic = stream.readByte();
+ _cubeJingle = stream.readByte();
// load hero properties
_sceneHeroPos.x = stream.readSint16LE();
@@ -339,7 +339,7 @@ bool Scene::loadSceneLBA1() {
_sampleMinDelay = stream.readUint16LE();
_sampleMinDelayRnd = stream.readUint16LE();
- _sceneMusic = stream.readByte();
+ _cubeJingle = stream.readByte();
// load hero properties
_sceneHeroPos.x = (int16)stream.readUint16LE();
@@ -519,8 +519,7 @@ void Scene::dumpSceneScripts() const {
}
}
-// ChangeCube
-void Scene::changeScene() {
+void Scene::changeCube() {
if (_engine->isLBA1()) {
if (_enableEnhancements) {
if (_currentSceneIdx == LBA1SceneId::Citadel_Island_Harbor && _needChangeScene == LBA1SceneId::Principal_Island_Harbor) {
@@ -637,9 +636,9 @@ void Scene::changeScene() {
_zoneHeroPos = IVec3();
_sampleAmbienceTime = 0;
- if (_sceneMusic != -1) {
- debug(2, "Scene %i music track id: %i", _currentSceneIdx, _sceneMusic);
- _engine->_music->playAllMusic(_sceneMusic);
+ debug(2, "Scene %i music track id: %i", _currentSceneIdx, _cubeJingle);
+ if (_cubeJingle != 255) {
+ _engine->_music->playMusic(_cubeJingle);
}
_engine->_gameState->handleLateGameItems();
}
@@ -675,11 +674,15 @@ void Scene::initSceneVars() {
void Scene::playSceneMusic() {
if (_engine->isLBA1()) {
if (_currentSceneIdx == LBA1SceneId::Tippet_Island_Twinsun_Cafe && _engine->_gameState->hasArrivedHamalayi()) {
- _engine->_music->playAllMusic(8);
+ if (_engine->isCDROM()) {
+ _engine->_music->playCdTrack(8);
+ } else {
+ _engine->_music->playMusic(_cubeJingle);
+ }
return;
}
}
- _engine->_music->playMidiFile(_sceneMusic);
+ _engine->_music->playMidiFile(_cubeJingle);
}
void Scene::processEnvironmentSound() {
diff --git a/engines/twine/scene/scene.h b/engines/twine/scene/scene.h
index d5bf6d66b7b..7789280017f 100644
--- a/engines/twine/scene/scene.h
+++ b/engines/twine/scene/scene.h
@@ -147,7 +147,7 @@ private:
int16 _samplePlayed = 0;
public:
- int16 _sceneMusic = 0; // CubeJingle
+ int16 _cubeJingle = 0;
private:
IVec3 _sceneHeroPos;
IVec3 _zoneHeroPos;
@@ -222,7 +222,7 @@ public:
void reloadCurrentScene();
/** Change to another scene */
- void changeScene();
+ void changeCube();
/** For the buggy to get the 2D coordinates of an exterior cube in the map */
bool loadSceneCubeXY(int sceneNum, int32 *cubeX, int32 *cubeY);
diff --git a/engines/twine/script/script_life.cpp b/engines/twine/script/script_life.cpp
index 835f71dd98c..6210082ea5c 100644
--- a/engines/twine/script/script_life.cpp
+++ b/engines/twine/script/script_life.cpp
@@ -1981,7 +1981,7 @@ int32 ScriptLife::lTHE_END(TwinEEngine *engine, LifeScriptContext &ctx) {
int32 ScriptLife::lPLAY_CD_TRACK(TwinEEngine *engine, LifeScriptContext &ctx) {
const int32 track = ctx.stream.readByte();
debugC(3, kDebugLevels::kDebugScripts, "LIFE::PLAY_CD_TRACK(%i)", (int)track);
- engine->_music->playAllMusic(track);
+ engine->_music->playCdTrack(track);
return 0;
}
diff --git a/engines/twine/script/script_life_v1.cpp b/engines/twine/script/script_life_v1.cpp
index db1169fdc7c..0461d1f606b 100644
--- a/engines/twine/script/script_life_v1.cpp
+++ b/engines/twine/script/script_life_v1.cpp
@@ -54,7 +54,7 @@ int32 ScriptLifeV1::lBUBBLE_OFF(TwinEEngine *engine, LifeScriptContext &ctx) {
*/
int32 ScriptLifeV1::lPLAY_MIDI(TwinEEngine *engine, LifeScriptContext &ctx) {
const int32 midiIdx = ctx.stream.readByte();
- engine->_music->playMidiFile(midiIdx); // TODO: improve this
+ engine->_music->playMusic(midiIdx);
debugC(3, kDebugLevels::kDebugScripts, "LIFE::PLAY_MIDI(%i)", (int)midiIdx);
return 0;
}
diff --git a/engines/twine/script/script_life_v2.cpp b/engines/twine/script/script_life_v2.cpp
index ecc88aa85b3..79cad5abc0a 100644
--- a/engines/twine/script/script_life_v2.cpp
+++ b/engines/twine/script/script_life_v2.cpp
@@ -220,7 +220,7 @@ int32 ScriptLifeV2::lPLAY_MUSIC(TwinEEngine *engine, LifeScriptContext &ctx) {
debugC(3, kDebugLevels::kDebugScripts, "LIFE::lPLAY_MUSIC()");
const int32 val = lPLAY_CD_TRACK(engine, ctx);
if (engine->isLBA2()) {
- engine->_scene->_sceneMusic = 255;
+ engine->_scene->_cubeJingle = 255;
engine->_music->_nextMusic = -1;
if (engine->_gameState->hasGameFlag(157) > 0) {
engine->_music->_stopLastMusic = false;
diff --git a/engines/twine/twine.cpp b/engines/twine/twine.cpp
index 062606e0d8b..d3b2720db4d 100644
--- a/engines/twine/twine.cpp
+++ b/engines/twine/twine.cpp
@@ -386,8 +386,7 @@ Common::Error TwinEEngine::run() {
ConfMan.setInt("polygondetails", _cfgfile.PolygonDetails);
_sound->stopSamples();
- _music->stopTrackMusic();
- _music->stopMusicMidi();
+ _music->stopMusic();
return Common::kNoError;
}
@@ -510,7 +509,6 @@ void TwinEEngine::initConfigurations() {
_cfgfile.Movie = CONF_MOVIE_FLAGIF;
}
- _cfgfile.UseCD = ConfGetBoolOrDefault("usecd", false);
_cfgfile.Sound = ConfGetBoolOrDefault("sound", true);
_cfgfile.Fps = ConfGetIntOrDefault("fps", DEFAULT_FRAMES_PER_SECOND);
_cfgfile.Debug = ConfGetBoolOrDefault("debug", false);
@@ -528,7 +526,6 @@ void TwinEEngine::initConfigurations() {
if (ttsMan != nullptr)
ttsMan->enable(ConfGetBoolOrDefault("tts_narrator", false));
- debug(1, "UseCD: %s", (_cfgfile.UseCD ? "true" : "false"));
debug(1, "Sound: %s", (_cfgfile.Sound ? "true" : "false"));
debug(1, "Movie: %i", _cfgfile.Movie);
debug(1, "Fps: %i", _cfgfile.Fps);
@@ -859,11 +856,11 @@ bool TwinEEngine::runGameEngine() { // mainLoopInteration
if (!isMod() && isDemo() && isLBA1()) {
// the demo only has these scenes
if (_scene->_needChangeScene != LBA1SceneId::Citadel_Island_Prison && _scene->_needChangeScene != LBA1SceneId::Citadel_Island_outside_the_citadel && _scene->_needChangeScene != LBA1SceneId::Citadel_Island_near_the_tavern) {
- // TODO: PlayMidiFile(6);
+ _music->playMidiFile(6);
return true;
}
}
- _scene->changeScene();
+ _scene->changeCube();
}
_movements->update();
@@ -871,7 +868,15 @@ bool TwinEEngine::runGameEngine() { // mainLoopInteration
_debug->processDebug();
if (_menuOptions->canShowCredits) {
- // TODO: if current music playing != 8, than play_track(8);
+ if (isLBA1()) {
+ if (isCDROM()) {
+ if (_music->getMusicCD() != 8) {
+ _music->playCdTrack(8);
+ }
+ } else if (!_music->isMidiPlaying()) {
+ _music->playMidiFile(9);
+ }
+ }
if (_input->toggleAbortAction()) {
return true;
}
diff --git a/engines/twine/twine.h b/engines/twine/twine.h
index 3c44890fc50..db4db7dd456 100644
--- a/engines/twine/twine.h
+++ b/engines/twine/twine.h
@@ -98,8 +98,6 @@ struct ConfigFile {
MidiFileType MidiType = MIDIFILE_NONE;
/** Game version */
int32 Version = EUROPE_VERSION;
- /** If you want to use the LBA CD or not */
- int32 UseCD = 0;
/** Allow various sound types */
int32 Sound = 0;
/** Allow various movie types */
Commit: 37cac532ddc00bce55ec87a13c68c90054e6d93a
https://github.com/scummvm/scummvm/commit/37cac532ddc00bce55ec87a13c68c90054e6d93a
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2024-09-13T17:07:29+02:00
Commit Message:
TWINE: fixed demo menu handling for music
Changed paths:
engines/twine/audio/music.cpp
engines/twine/detection.cpp
engines/twine/detection.h
engines/twine/menu/menu.cpp
engines/twine/menu/menu.h
engines/twine/menu/menuoptions.cpp
engines/twine/menu/menuoptions.h
engines/twine/metaengine.cpp
engines/twine/scene/gamestate.cpp
engines/twine/twine.cpp
diff --git a/engines/twine/audio/music.cpp b/engines/twine/audio/music.cpp
index 02947635285..f68a2ac0828 100644
--- a/engines/twine/audio/music.cpp
+++ b/engines/twine/audio/music.cpp
@@ -93,6 +93,7 @@ void TwinEMidiPlayer::play(byte *buf, int size, bool loop) {
_parser->property(MidiParser::mpCenterPitchWheelOnUnload, 1);
syncVolume();
+ debug("play midi with volume: %i", getVolume());
_isLooping = loop;
_isPlaying = true;
@@ -109,12 +110,16 @@ int32 Music::getLengthTrackCDR(int track) const {
bool Music::playMidi(int32 midiIdx) {
const int32 loop = 1;
if (_engine->isDotEmuEnhanced() || _engine->isLba1Classic()) {
- Common::Path trackName(Common::String::format("lba1-%02i", midiIdx + 1));
+ // the midi tracks are stored in the lba1-xx files and the adeline logo jingle
+ // is in lba1-32.xx - while the midiIdx is 31
+ const int32 trackOffset = 1;
+ Common::Path trackName(Common::String::format("lba1-%02i", midiIdx + trackOffset));
Audio::SeekableAudioStream *stream = Audio::SeekableAudioStream::openStreamFile(trackName);
if (stream != nullptr) {
const int volume = _engine->_system->getMixer()->getVolumeForSoundType(Audio::Mixer::kMusicSoundType);
_engine->_system->getMixer()->playStream(Audio::Mixer::kMusicSoundType, &_midiHandle,
Audio::makeLoopingAudioStream(stream, loop), volume);
+ debug("Play midi music track %i", midiIdx);
return true;
}
}
@@ -197,7 +202,6 @@ bool Music::initCdrom() {
void Music::stopMusic() {
stopMusicCD();
stopMusicMidi();
- numXmi = -1;
}
void Music::stopMusicCD() {
@@ -233,18 +237,15 @@ bool Music::playMusic(int32 track) {
if (_engine->isCDROM()) {
if (_flagVoiceCD || track < 1 || track > 9) {
if (playMidiFile(track)) {
- debug("Play midi music track %i", track);
return true;
}
} else {
if (playCdTrack(track)) {
- debug("Play cd music track %i", track);
return true;
}
}
} else {
if (playMidiFile(track)) {
- debug("Play midi music track %i", track);
return true;
}
}
@@ -288,9 +289,10 @@ bool Music::playCdTrack(int32 track) {
if (track != getMusicCD()) {
stopMusicCD();
- // TODO: endMusicCD = _engine->toSeconds(getLengthTrackCDR(track + 1)) / 75 + _engine->toSeconds(1);
+ // TODO: endMusicCD = _engine->toSeconds(getLengthTrackCDR(track)) / 75 + _engine->toSeconds(1);
if (playTrackCDR(track)) {
// TODO: endMusicCD += _engine->_system->getMillis();
+ debug("Play cd music track %i", track);
currentMusicCD = track;
}
}
@@ -306,7 +308,7 @@ void Music::playAllMusic(int num) {
}
if (num != getMusicCD()) {
stopMusicCD();
- // TODO: endMusicCD = _engine->toSeconds(getLengthTrackCDR(num + 1)) / 75 + _engine->toSeconds(1);
+ // TODO: endMusicCD = _engine->toSeconds(getLengthTrackCDR(num)) / 75 + _engine->toSeconds(1);
if (playTrackCDR(num)) {
// TODO: endMusicCD += _engine->_system->getMillis();
currentMusicCD = num;
diff --git a/engines/twine/detection.cpp b/engines/twine/detection.cpp
index 10c252ab3ef..3d4ad4f4bc5 100644
--- a/engines/twine/detection.cpp
+++ b/engines/twine/detection.cpp
@@ -416,7 +416,7 @@ static const ADGameDescription twineGameDescriptions[] = {
class TwinEMetaEngineDetection : public AdvancedMetaEngineDetection<ADGameDescription> {
public:
TwinEMetaEngineDetection() : AdvancedMetaEngineDetection(twineGameDescriptions, twineGames) {
- _guiOptions = GUIO12(GAMEOPTION_WALL_COLLISION, GAMEOPTION_DISABLE_SAVE_MENU, GAMEOPTION_DEBUG, GAMEOPTION_AUDIO_CD, GAMEOPTION_SOUND, GAMEOPTION_VOICES, GAMEOPTION_TEXT, GAMEOPTION_MOVIES, GAMEOPTION_MOUSE, GAMEOPTION_USA_VERSION, GAMEOPTION_HIGH_RESOLUTION, GAMEOPTION_TEXT_TO_SPEECH);
+ _guiOptions = GUIO11(GAMEOPTION_WALL_COLLISION, GAMEOPTION_DISABLE_SAVE_MENU, GAMEOPTION_DEBUG, GAMEOPTION_SOUND, GAMEOPTION_VOICES, GAMEOPTION_TEXT, GAMEOPTION_MOVIES, GAMEOPTION_MOUSE, GAMEOPTION_USA_VERSION, GAMEOPTION_HIGH_RESOLUTION, GAMEOPTION_TEXT_TO_SPEECH);
}
const char *getName() const override {
diff --git a/engines/twine/detection.h b/engines/twine/detection.h
index ad5978872ee..d9388f9e938 100644
--- a/engines/twine/detection.h
+++ b/engines/twine/detection.h
@@ -44,15 +44,14 @@ enum TwineFeatureFlags {
#define GAMEOPTION_WALL_COLLISION GUIO_GAMEOPTIONS1
#define GAMEOPTION_DISABLE_SAVE_MENU GUIO_GAMEOPTIONS2
#define GAMEOPTION_DEBUG GUIO_GAMEOPTIONS3
-#define GAMEOPTION_AUDIO_CD GUIO_GAMEOPTIONS4
-#define GAMEOPTION_SOUND GUIO_GAMEOPTIONS5
-#define GAMEOPTION_VOICES GUIO_GAMEOPTIONS6
-#define GAMEOPTION_TEXT GUIO_GAMEOPTIONS7
-#define GAMEOPTION_MOVIES GUIO_GAMEOPTIONS8
-#define GAMEOPTION_MOUSE GUIO_GAMEOPTIONS9
-#define GAMEOPTION_USA_VERSION GUIO_GAMEOPTIONS10
-#define GAMEOPTION_HIGH_RESOLUTION GUIO_GAMEOPTIONS11
-#define GAMEOPTION_TEXT_TO_SPEECH GUIO_GAMEOPTIONS12
+#define GAMEOPTION_SOUND GUIO_GAMEOPTIONS4
+#define GAMEOPTION_VOICES GUIO_GAMEOPTIONS5
+#define GAMEOPTION_TEXT GUIO_GAMEOPTIONS6
+#define GAMEOPTION_MOVIES GUIO_GAMEOPTIONS7
+#define GAMEOPTION_MOUSE GUIO_GAMEOPTIONS8
+#define GAMEOPTION_USA_VERSION GUIO_GAMEOPTIONS9
+#define GAMEOPTION_HIGH_RESOLUTION GUIO_GAMEOPTIONS10
+#define GAMEOPTION_TEXT_TO_SPEECH GUIO_GAMEOPTIONS11
} // End of namespace TwinE
diff --git a/engines/twine/menu/menu.cpp b/engines/twine/menu/menu.cpp
index af79295caea..1cf116221b2 100644
--- a/engines/twine/menu/menu.cpp
+++ b/engines/twine/menu/menu.cpp
@@ -31,22 +31,22 @@
#include "common/system.h"
#include "common/util.h"
#include "graphics/cursorman.h"
-#include "twine/scene/actor.h"
-#include "twine/scene/animations.h"
#include "twine/audio/music.h"
#include "twine/audio/sound.h"
-#include "twine/movies.h"
-#include "twine/scene/gamestate.h"
-#include "twine/scene/grid.h"
-#include "twine/resources/hqr.h"
#include "twine/input.h"
#include "twine/menu/interface.h"
#include "twine/menu/menuoptions.h"
-#include "twine/scene/movements.h"
+#include "twine/movies.h"
#include "twine/renderer/redraw.h"
#include "twine/renderer/renderer.h"
#include "twine/renderer/screens.h"
+#include "twine/resources/hqr.h"
#include "twine/resources/resources.h"
+#include "twine/scene/actor.h"
+#include "twine/scene/animations.h"
+#include "twine/scene/gamestate.h"
+#include "twine/scene/grid.h"
+#include "twine/scene/movements.h"
#include "twine/scene/scene.h"
#include "twine/shared.h"
#include "twine/text.h"
@@ -79,7 +79,6 @@ enum MenuButtonTypesEnum {
if ((callMenu) == kQuitEngine) { \
return kQuitEngine; \
}
-#define kBackground 9999
namespace _priv {
@@ -219,12 +218,12 @@ void Menu::plasmaEffectRenderFrame() {
/* Here we calculate the average of all 8 neighbour pixel values */
int16 c;
- c = _plasmaEffectPtr[(i - 1) + (j - 1) * PLASMA_WIDTH]; //top-left
- c += _plasmaEffectPtr[(i + 0) + (j - 1) * PLASMA_WIDTH]; //top
- c += _plasmaEffectPtr[(i + 1) + (j - 1) * PLASMA_WIDTH]; //top-right
+ c = _plasmaEffectPtr[(i - 1) + (j - 1) * PLASMA_WIDTH]; // top-left
+ c += _plasmaEffectPtr[(i + 0) + (j - 1) * PLASMA_WIDTH]; // top
+ c += _plasmaEffectPtr[(i + 1) + (j - 1) * PLASMA_WIDTH]; // top-right
- c += _plasmaEffectPtr[(i - 1) + (j + 0) * PLASMA_WIDTH]; //left
- c += _plasmaEffectPtr[(i + 1) + (j + 0) * PLASMA_WIDTH]; //right
+ c += _plasmaEffectPtr[(i - 1) + (j + 0) * PLASMA_WIDTH]; // left
+ c += _plasmaEffectPtr[(i + 1) + (j + 0) * PLASMA_WIDTH]; // right
c += _plasmaEffectPtr[(i - 1) + (j + 1) * PLASMA_WIDTH]; // bottom-left
c += _plasmaEffectPtr[(i + 0) + (j + 1) * PLASMA_WIDTH]; // bottom
@@ -235,7 +234,7 @@ void Menu::plasmaEffectRenderFrame() {
c = (c >> 3) | ((c & 0x0003) << 13);
if (!(c & 0x6500) &&
- (j >= (PLASMA_HEIGHT - 4) || c > 0)) {
+ (j >= (PLASMA_HEIGHT - 4) || c > 0)) {
c--; /*fade this pixel*/
}
@@ -277,8 +276,8 @@ void Menu::processPlasmaEffect(const Common::Rect &rect, int32 color) {
}
void Menu::drawRectBorders(const Common::Rect &rect, int32 colorLeftTop, int32 colorRightBottom) {
- _engine->_interface->drawLine(rect.left, rect.top, rect.right, rect.top, colorLeftTop); // top line
- _engine->_interface->drawLine(rect.left, rect.top, rect.left, rect.bottom, colorLeftTop); // left line
+ _engine->_interface->drawLine(rect.left, rect.top, rect.right, rect.top, colorLeftTop); // top line
+ _engine->_interface->drawLine(rect.left, rect.top, rect.left, rect.bottom, colorLeftTop); // left line
_engine->_interface->drawLine(rect.right, rect.top + 1, rect.right, rect.bottom, colorRightBottom); // right line
_engine->_interface->drawLine(rect.left + 1, rect.bottom, rect.right, rect.bottom, colorRightBottom); // bottom line
}
@@ -447,6 +446,28 @@ int16 Menu::drawButtons(MenuSettings *menuSettings, bool hover) {
return mouseActiveButton;
}
+void Menu::menuDemo() {
+ // TODO: lba2 only show the credits only in the main menu and you could force it by pressing shift+c
+ // TODO: lba2 has a cd audio track (2) for the credits
+ _engine->_menuOptions->showCredits();
+ if (_engine->_movie->playMovie(FLA_DRAGON3)) {
+ if (!_engine->_screens->loadImageDelay(TwineImage(Resources::HQR_RESS_FILE, 15, 16), 3)) {
+ if (!_engine->_screens->loadImageDelay(TwineImage(Resources::HQR_RESS_FILE, 17, 18), 3)) {
+ if (!_engine->_screens->loadImageDelay(TwineImage(Resources::HQR_RESS_FILE, 19, 20), 3)) {
+ if (_engine->_movie->playMovie(FLA_BATEAU)) {
+ if (_engine->_cfgfile.Version == USA_VERSION) {
+ _engine->_screens->loadImageDelay(_engine->_resources->relentLogo(), 3);
+ } else {
+ _engine->_screens->loadImageDelay(_engine->_resources->lbaLogo(), 3);
+ }
+ _engine->_screens->adelineLogo();
+ }
+ }
+ }
+ }
+ }
+}
+
int32 Menu::doGameMenu(MenuSettings *menuSettings) {
int16 currentButton = menuSettings->getActiveButton();
bool buttonsNeedRedraw = true;
@@ -660,29 +681,14 @@ int32 Menu::doGameMenu(MenuSettings *menuSettings) {
}
startMillis = loopMillis;
}
- if (!_engine->_scene->isGameRunning() && loopMillis - startMillis > 11650) {
- // TODO: lba2 only show the credits only in the main menu and you could force it by pressing shift+c
- // TODO: lba2 has a cd audio track (2) for the credits
- _engine->_menuOptions->showCredits();
- if (_engine->_movie->playMovie(FLA_DRAGON3)) {
- if (!_engine->_screens->loadImageDelay(TwineImage(Resources::HQR_RESS_FILE, 15, 16), 3)) {
- if (!_engine->_screens->loadImageDelay(TwineImage(Resources::HQR_RESS_FILE, 17, 18), 3)) {
- if (!_engine->_screens->loadImageDelay(TwineImage(Resources::HQR_RESS_FILE, 19, 20), 3)) {
- if (_engine->_movie->playMovie(FLA_BATEAU)) {
- if (_engine->_cfgfile.Version == USA_VERSION) {
- _engine->_screens->loadImageDelay(_engine->_resources->relentLogo(), 3);
- } else {
- _engine->_screens->loadImageDelay(_engine->_resources->lbaLogo(), 3);
- }
- _engine->_screens->adelineLogo();
- }
- }
- }
- }
+ if (menuSettings == &_mainMenuState) {
+ uint32 idleTime = 60 * 3 + 53 * 1000;
+ if (_engine->isDemo()) {
+ idleTime = 60 * 1000;
+ }
+ if (loopMillis - startMillis > idleTime) {
+ return kDemoMenu;
}
- _engine->_text->initDial(TextBankId::Options_and_menus);
- startMillis = _engine->_system->getMillis();
- _engine->_screens->loadMenuImage(false);
}
} while (!_engine->_input->toggleActionIfActive(TwinEActionType::UIEnter));
@@ -802,7 +808,14 @@ int32 Menu::optionsMenu() {
_engine->restoreFrontBuffer();
_engine->_sound->stopSamples();
- _engine->_music->playMusic(9); // LBA's Theme
+ if (_engine->isLBA1()) {
+ // LBA's Theme
+ if (_engine->isCDROM()) {
+ _engine->_music->playCdTrack(9);
+ } else {
+ _engine->_music->playMidiFile(9);
+ }
+ }
ScopedCursor scoped(_engine);
for (;;) {
@@ -942,8 +955,9 @@ EngineState Menu::run() {
optionsMenu();
break;
}
- case kBackground: {
- _engine->_screens->loadMenuImage();
+ case kDemoMenu: {
+ menuDemo();
+ _engine->_screens->loadMenuImage(false);
break;
}
case (int32)TextId::kQuit:
@@ -1351,7 +1365,7 @@ void Menu::processInventoryMenu() {
ProgressiveTextState textState = ProgressiveTextState::ContinueRunning;
bool updateItemText = true;
- //ScopedCursor scopedCursor(_engine);
+ // ScopedCursor scopedCursor(_engine);
ScopedKeyMap scopedKeyMap(_engine, uiKeyMapId);
for (;;) {
FrameMarker frame(_engine, 66);
diff --git a/engines/twine/menu/menu.h b/engines/twine/menu/menu.h
index 4689127c220..b809399c7c6 100644
--- a/engines/twine/menu/menu.h
+++ b/engines/twine/menu/menu.h
@@ -30,6 +30,7 @@ namespace TwinE {
#define MAX_BUTTONS 10
#define PLASMA_WIDTH 320
#define PLASMA_HEIGHT 50
+#define kDemoMenu 9999
#define kQuitEngine 9998
class BodyData;
@@ -226,6 +227,7 @@ public:
* @param menuSettings menu settings array with the information to build the menu options
* @return pressed menu button identification
*/
+ void menuDemo();
int32 doGameMenu(MenuSettings *menuSettings);
bool init();
diff --git a/engines/twine/menu/menuoptions.cpp b/engines/twine/menu/menuoptions.cpp
index 0a124f1cf03..9cda9713d17 100644
--- a/engines/twine/menu/menuoptions.cpp
+++ b/engines/twine/menu/menuoptions.cpp
@@ -105,10 +105,10 @@ void MenuOptions::showCredits() {
_engine->_scene->_currentSceneIdx = LBA1SceneId::Credits_List_Sequence;
_engine->_scene->_needChangeScene = LBA1SceneId::Credits_List_Sequence;
- canShowCredits = true;
+ flagCredits = true;
_engine->gameEngineLoop();
_engine->_scene->stopRunningGame();
- canShowCredits = false;
+ flagCredits = false;
_engine->_cfgfile.ShadowMode = tmpShadowMode;
diff --git a/engines/twine/menu/menuoptions.h b/engines/twine/menu/menuoptions.h
index 81c8d98d362..c7945f2de9e 100644
--- a/engines/twine/menu/menuoptions.h
+++ b/engines/twine/menu/menuoptions.h
@@ -54,7 +54,7 @@ public:
void showEndSequence();
void showCredits();
- bool canShowCredits = false;
+ bool flagCredits = false;
char _saveGameName[32] {'\0'};
diff --git a/engines/twine/metaengine.cpp b/engines/twine/metaengine.cpp
index c1120a437e8..e56b17c1309 100644
--- a/engines/twine/metaengine.cpp
+++ b/engines/twine/metaengine.cpp
@@ -72,17 +72,6 @@ static const ADExtraGuiOptionsMap twineOptionsList[] = {
0
}
},
- {
- GAMEOPTION_AUDIO_CD,
- {
- _s("Enable audio CD"),
- _s("Enable the original audio cd track"),
- "usecd",
- false,
- 0,
- 0
- }
- },
{
GAMEOPTION_SOUND,
{
diff --git a/engines/twine/scene/gamestate.cpp b/engines/twine/scene/gamestate.cpp
index 3442e8c522b..d9cddbdae21 100644
--- a/engines/twine/scene/gamestate.cpp
+++ b/engines/twine/scene/gamestate.cpp
@@ -120,7 +120,7 @@ void GameState::initEngineVars() {
_engine->_scene->_needChangeScene = LBA1SceneId::Citadel_Island_Prison;
_engine->_sceneLoopState = SceneLoopState::Continue;
_engine->_scene->_mecaPenguinIdx = -1;
- _engine->_menuOptions->canShowCredits = false;
+ _engine->_menuOptions->flagCredits = false;
_inventoryNumLeafs = 0;
_inventoryNumLeafsBox = 2;
diff --git a/engines/twine/twine.cpp b/engines/twine/twine.cpp
index d3b2720db4d..ba58429b30b 100644
--- a/engines/twine/twine.cpp
+++ b/engines/twine/twine.cpp
@@ -867,7 +867,7 @@ bool TwinEEngine::runGameEngine() { // mainLoopInteration
_debug->processDebug();
- if (_menuOptions->canShowCredits) {
+ if (_menuOptions->flagCredits) {
if (isLBA1()) {
if (isCDROM()) {
if (_music->getMusicCD() != 8) {
Commit: d6a0b5fb47a7e5e2eadad4e1388f46bf15397562
https://github.com/scummvm/scummvm/commit/d6a0b5fb47a7e5e2eadad4e1388f46bf15397562
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2024-09-13T17:07:29+02:00
Commit Message:
TWINE: fixed mouse cursor config var handling
Changed paths:
engines/twine/twine.cpp
engines/twine/twine.h
diff --git a/engines/twine/twine.cpp b/engines/twine/twine.cpp
index ba58429b30b..5fbcea04073 100644
--- a/engines/twine/twine.cpp
+++ b/engines/twine/twine.cpp
@@ -512,7 +512,7 @@ void TwinEEngine::initConfigurations() {
_cfgfile.Sound = ConfGetBoolOrDefault("sound", true);
_cfgfile.Fps = ConfGetIntOrDefault("fps", DEFAULT_FRAMES_PER_SECOND);
_cfgfile.Debug = ConfGetBoolOrDefault("debug", false);
- _cfgfile.Mouse = ConfGetIntOrDefault("mouse", true);
+ _cfgfile.Mouse = ConfGetBoolOrDefault("mouse", true);
_cfgfile.UseAutoSaving = ConfGetBoolOrDefault("useautosaving", false);
_cfgfile.WallCollision = ConfGetBoolOrDefault("wallcollision", false);
diff --git a/engines/twine/twine.h b/engines/twine/twine.h
index db4db7dd456..26fa2cc311b 100644
--- a/engines/twine/twine.h
+++ b/engines/twine/twine.h
@@ -110,7 +110,7 @@ struct ConfigFile {
bool WallCollision = false;
/** Use original autosaving system or save when you want */
bool UseAutoSaving = false;
- bool Mouse = false;
+ bool Mouse = true;
// these settings can be changed in-game - and must be persisted
/** Shadow mode type, value: all, character only, none */
Commit: faeef14bec7fc96ae36182d023658e298e2acf1e
https://github.com/scummvm/scummvm/commit/faeef14bec7fc96ae36182d023658e298e2acf1e
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2024-09-13T17:07:29+02:00
Commit Message:
TWINE: improved mouse support for behaviour switch and inventory
Changed paths:
engines/twine/input.cpp
engines/twine/input.h
engines/twine/menu/menu.cpp
engines/twine/menu/menu.h
engines/twine/twine.cpp
diff --git a/engines/twine/input.cpp b/engines/twine/input.cpp
index f6d8cd82ee6..15d28ea928a 100644
--- a/engines/twine/input.cpp
+++ b/engines/twine/input.cpp
@@ -45,7 +45,9 @@ ScopedKeyMap::~ScopedKeyMap() {
}
}
-Input::Input(TwinEEngine *engine) : _engine(engine) {}
+Input::Input(TwinEEngine *engine) : _engine(engine) {
+ resetLastHoveredMousePosition();
+}
bool Input::isActionActive(TwinEActionType actionType, bool onlyFirstTime) const {
if (onlyFirstTime) {
@@ -172,12 +174,23 @@ Common::Point Input::getMousePositions() const {
return g_system->getEventManager()->getMousePos();
}
-bool Input::isMouseHovering(const Common::Rect &rect) const {
+bool Input::isMouseHovering(const Common::Rect &rect, bool onlyIfMoved) {
if (!_engine->_cfgfile.Mouse) {
return false;
}
const Common::Point &point = getMousePositions();
- return rect.contains(point);
+ if (onlyIfMoved && _lastMousePos == point) {
+ return false;
+ }
+ if (rect.contains(point)) {
+ _lastMousePos = point;
+ return true;
+ }
+ return false;
+}
+
+void Input::resetLastHoveredMousePosition() {
+ _lastMousePos = Common::Point(-1, -1);
}
} // namespace TwinE
diff --git a/engines/twine/input.h b/engines/twine/input.h
index bd088ca43e7..3d7a536b8d3 100644
--- a/engines/twine/input.h
+++ b/engines/twine/input.h
@@ -116,6 +116,7 @@ private:
Common::String _currentKeyMap;
uint8 _actionStates[TwinEActionType::Max]{false};
+ Common::Point _lastMousePos;
public:
Input(TwinEEngine *engine);
@@ -137,7 +138,8 @@ public:
*/
bool isActionActive(TwinEActionType actionType, bool onlyFirstTime = true) const;
- bool isMouseHovering(const Common::Rect &rect) const;
+ void resetLastHoveredMousePosition();
+ bool isMouseHovering(const Common::Rect &rect, bool onlyIfMoved = true);
/**
* @brief If the action is active, the internal state is reset and a following call of this method won't return
diff --git a/engines/twine/menu/menu.cpp b/engines/twine/menu/menu.cpp
index 1cf116221b2..3b5560a36ee 100644
--- a/engines/twine/menu/menu.cpp
+++ b/engines/twine/menu/menu.cpp
@@ -473,8 +473,6 @@ int32 Menu::doGameMenu(MenuSettings *menuSettings) {
bool buttonsNeedRedraw = true;
const int32 numEntry = menuSettings->getButtonCount();
int32 maxButton = numEntry - 1;
- Common::Point mousepos = _engine->_input->getMousePositions();
- bool useMouse = true;
_engine->_input->enableKeyMap(uiKeyMapId);
@@ -490,18 +488,11 @@ int32 Menu::doGameMenu(MenuSettings *menuSettings) {
const uint32 loopMillis = _engine->_system->getMillis();
_engine->readKeys();
- Common::Point newmousepos = _engine->_input->getMousePositions();
- if (mousepos != newmousepos) {
- useMouse = true;
- mousepos = newmousepos;
- }
-
if (_engine->_input->toggleActionIfActive(TwinEActionType::UIDown)) {
currentButton++;
if (currentButton == numEntry) { // if current button is the last, than next button is the first
currentButton = 0;
}
- useMouse = false;
buttonsNeedRedraw = true;
startMillis = loopMillis;
} else if (_engine->_input->toggleActionIfActive(TwinEActionType::UIUp)) {
@@ -509,7 +500,6 @@ int32 Menu::doGameMenu(MenuSettings *menuSettings) {
if (currentButton < 0) { // if current button is the first, than previous button is the last
currentButton = maxButton;
}
- useMouse = false;
buttonsNeedRedraw = true;
startMillis = loopMillis;
}
@@ -654,7 +644,7 @@ int32 Menu::doGameMenu(MenuSettings *menuSettings) {
if (buttonsNeedRedraw) {
// draw all buttons
const int16 mouseButtonHovered = drawButtons(menuSettings, false);
- if (useMouse && mouseButtonHovered != -1) {
+ if (mouseButtonHovered != -1) {
currentButton = mouseButtonHovered;
}
menuSettings->setActiveButton(currentButton);
@@ -662,7 +652,7 @@ int32 Menu::doGameMenu(MenuSettings *menuSettings) {
// draw plasma effect for the current selected button
const int16 mouseButtonHovered = drawButtons(menuSettings, true);
- if (useMouse && mouseButtonHovered != -1) {
+ if (mouseButtonHovered != -1) {
if (mouseButtonHovered != currentButton) {
buttonsNeedRedraw = true;
}
@@ -1105,6 +1095,9 @@ Common::Rect Menu::calcBehaviourRect(int32 left, int32 top, HeroBehaviourType be
}
bool Menu::isBehaviourHovered(int32 left, int32 top, HeroBehaviourType behaviour) const {
+ if (!_engine->_cfgfile.Mouse) {
+ return false;
+ }
const Common::Rect &boxRect = calcBehaviourRect(left, top, behaviour);
return _engine->_input->isMouseHovering(boxRect);
}
@@ -1235,9 +1228,7 @@ void Menu::processBehaviourMenu(bool behaviourMenu) {
int32 tmpTime = _engine->timerRef;
-#if 0
ScopedCursor scopedCursor(_engine);
-#endif
ScopedKeyMap scopedKeyMap(_engine, uiKeyMapId);
while (_engine->_input->isActionActive(TwinEActionType::BehaviourMenu) || _engine->_input->isQuickBehaviourActionActive()) {
FrameMarker frame(_engine, 50);
@@ -1246,17 +1237,15 @@ void Menu::processBehaviourMenu(bool behaviourMenu) {
break;
}
-#if 0
- if (isBehaviourHovered(HeroBehaviourType::kNormal)) {
- _engine->_actor->heroBehaviour = HeroBehaviourType::kNormal;
- } else if (isBehaviourHovered(HeroBehaviourType::kAthletic)) {
- _engine->_actor->heroBehaviour = HeroBehaviourType::kAthletic;
- } else if (isBehaviourHovered(HeroBehaviourType::kAggressive)) {
- _engine->_actor->heroBehaviour = HeroBehaviourType::kAggressive;
- } else if (isBehaviourHovered(HeroBehaviourType::kDiscrete)) {
- _engine->_actor->heroBehaviour = HeroBehaviourType::kDiscrete;
+ if (isBehaviourHovered(left, top, HeroBehaviourType::kNormal)) {
+ _engine->_actor->_heroBehaviour = HeroBehaviourType::kNormal;
+ } else if (isBehaviourHovered(left, top, HeroBehaviourType::kAthletic)) {
+ _engine->_actor->_heroBehaviour = HeroBehaviourType::kAthletic;
+ } else if (isBehaviourHovered(left, top, HeroBehaviourType::kAggressive)) {
+ _engine->_actor->_heroBehaviour = HeroBehaviourType::kAggressive;
+ } else if (isBehaviourHovered(left, top, HeroBehaviourType::kDiscrete)) {
+ _engine->_actor->_heroBehaviour = HeroBehaviourType::kDiscrete;
}
-#endif
int heroBehaviour = (int)_engine->_actor->_heroBehaviour;
if (_engine->_input->toggleActionIfActive(TwinEActionType::UILeft)) {
@@ -1298,7 +1287,7 @@ void Menu::processBehaviourMenu(bool behaviourMenu) {
_engine->_text->initSceneTextBank();
}
-void Menu::drawItem(int32 left, int32 top, int32 item) {
+Common::Rect Menu::calcItemRect(int32 left, int32 top, int32 item, int32 *centerX, int32 *centerY) const {
const int32 itemWidth = 74;
const int32 itemHeight = 64;
const int32 itemPadding = 11;
@@ -1306,7 +1295,18 @@ void Menu::drawItem(int32 left, int32 top, int32 item) {
const int32 itemHeightHalf = itemHeight / 2;
const int32 itemX = (item / 4) * (itemWidth + itemPadding) + left + itemWidthHalf + itemPadding - 1;
const int32 itemY = (item % 4) * (itemHeight + itemPadding) + top + itemHeightHalf + itemPadding - 1;
- const Common::Rect rect(itemX - itemWidthHalf, itemY - itemHeightHalf, itemX + itemWidthHalf, itemY + itemHeightHalf);
+ if (centerX) {
+ *centerX = itemX;
+ }
+ if (centerY) {
+ *centerY = itemY;
+ }
+ return Common::Rect(itemX - itemWidthHalf, itemY - itemHeightHalf, itemX + itemWidthHalf, itemY + itemHeightHalf);
+}
+
+void Menu::drawItem(int32 left, int32 top, int32 item) {
+ int32 itemX, itemY;
+ const Common::Rect rect = calcItemRect(left, top, item, &itemX, &itemY);
const int32 color = _inventorySelectedItem == item ? _inventorySelectedColor : COLOR_BLACK;
_engine->_interface->drawFilledRect(rect, color);
@@ -1330,7 +1330,6 @@ void Menu::drawInventoryItems(int32 left, int32 top) {
const Common::Rect rect(left, top, left + 605, top + 310);
_engine->_interface->drawTransparentBox(rect, 4);
drawRectBorders(rect);
-
for (int32 item = 0; item < NUM_INVENTORY_ITEMS; item++) {
drawItem(left, top, item);
}
@@ -1365,7 +1364,7 @@ void Menu::processInventoryMenu() {
ProgressiveTextState textState = ProgressiveTextState::ContinueRunning;
bool updateItemText = true;
- // ScopedCursor scopedCursor(_engine);
+ ScopedCursor scopedCursor(_engine);
ScopedKeyMap scopedKeyMap(_engine, uiKeyMapId);
for (;;) {
FrameMarker frame(_engine, 66);
@@ -1376,6 +1375,16 @@ void Menu::processInventoryMenu() {
break;
}
+ for (int32 item = 0; item < NUM_INVENTORY_ITEMS; item++) {
+ const Common::Rect &rect = calcItemRect(left, top, item);
+ if (_engine->_input->isMouseHovering(rect)) {
+ _inventorySelectedItem = item;
+ drawItem(left, top, prevSelectedItem);
+ updateItemText = true;
+ break;
+ }
+ }
+
const bool cursorDown = _engine->_input->toggleActionIfActive(TwinEActionType::UIDown);
const bool cursorUp = _engine->_input->toggleActionIfActive(TwinEActionType::UIUp);
const bool cursorLeft = _engine->_input->toggleActionIfActive(TwinEActionType::UILeft);
diff --git a/engines/twine/menu/menu.h b/engines/twine/menu/menu.h
index b809399c7c6..c7cf2cc4403 100644
--- a/engines/twine/menu/menu.h
+++ b/engines/twine/menu/menu.h
@@ -193,6 +193,7 @@ private:
void drawInventoryItems(int32 left, int32 top);
void prepareAndDrawBehaviour(int32 left, int32 top, int32 angle, HeroBehaviourType behaviour); // DrawComportement
void drawBehaviourMenu(int32 left, int32 top, int32 angle); // DrawMenuComportement
+ Common::Rect calcItemRect(int32 left, int32 top, int32 item, int32 *centerX = nullptr, int32 *centerY = nullptr) const;
void drawItem(int32 left, int32 top, int32 item);
void drawSpriteAndString(int32 left, int32 top, const SpriteData &spriteData, const Common::String &str, int32 color = COLOR_GOLD);
diff --git a/engines/twine/twine.cpp b/engines/twine/twine.cpp
index 5fbcea04073..e4c12f999ce 100644
--- a/engines/twine/twine.cpp
+++ b/engines/twine/twine.cpp
@@ -92,6 +92,7 @@ ScopedCursor::ScopedCursor(TwinEEngine *engine) : _engine(engine) {
ScopedCursor::~ScopedCursor() {
_engine->popMouseCursorVisible();
+ _engine->_input->resetLastHoveredMousePosition();
}
FrameMarker::FrameMarker(TwinEEngine *engine, uint32 fps) : _engine(engine), _fps(fps) {
Commit: 2f10fb20f8c02f311a5e919b887164c7097e5ac0
https://github.com/scummvm/scummvm/commit/2f10fb20f8c02f311a5e919b887164c7097e5ac0
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2024-09-13T17:07:29+02:00
Commit Message:
TWINE: renamed methods to match original source
Changed paths:
engines/twine/menu/menu.cpp
engines/twine/menu/menu.h
engines/twine/text.cpp
diff --git a/engines/twine/menu/menu.cpp b/engines/twine/menu/menu.cpp
index 3b5560a36ee..8576d4ba9f9 100644
--- a/engines/twine/menu/menu.cpp
+++ b/engines/twine/menu/menu.cpp
@@ -1304,7 +1304,7 @@ Common::Rect Menu::calcItemRect(int32 left, int32 top, int32 item, int32 *center
return Common::Rect(itemX - itemWidthHalf, itemY - itemHeightHalf, itemX + itemWidthHalf, itemY + itemHeightHalf);
}
-void Menu::drawItem(int32 left, int32 top, int32 item) {
+void Menu::drawOneInventory(int32 left, int32 top, int32 item) {
int32 itemX, itemY;
const Common::Rect rect = calcItemRect(left, top, item, &itemX, &itemY);
const int32 color = _inventorySelectedItem == item ? _inventorySelectedColor : COLOR_BLACK;
@@ -1326,12 +1326,12 @@ void Menu::drawItem(int32 left, int32 top, int32 item) {
drawRectBorders(rect);
}
-void Menu::drawInventoryItems(int32 left, int32 top) {
+void Menu::drawListInventory(int32 left, int32 top) {
const Common::Rect rect(left, top, left + 605, top + 310);
_engine->_interface->drawTransparentBox(rect, 4);
drawRectBorders(rect);
for (int32 item = 0; item < NUM_INVENTORY_ITEMS; item++) {
- drawItem(left, top, item);
+ drawOneInventory(left, top, item);
}
_engine->_interface->unsetClip();
}
@@ -1354,7 +1354,7 @@ void Menu::processInventoryMenu() {
const int32 left = _engine->width() / 2 - 303;
const int32 top = _engine->height() / 2 - 210;
- drawInventoryItems(left, top);
+ drawListInventory(left, top);
_engine->_text->initDial(TextBankId::Inventory_Intro_and_Holomap);
@@ -1379,7 +1379,7 @@ void Menu::processInventoryMenu() {
const Common::Rect &rect = calcItemRect(left, top, item);
if (_engine->_input->isMouseHovering(rect)) {
_inventorySelectedItem = item;
- drawItem(left, top, prevSelectedItem);
+ drawOneInventory(left, top, prevSelectedItem);
updateItemText = true;
break;
}
@@ -1395,28 +1395,28 @@ void Menu::processInventoryMenu() {
if (_inventorySelectedItem >= NUM_INVENTORY_ITEMS) {
_inventorySelectedItem = 0;
}
- drawItem(left, top, prevSelectedItem);
+ drawOneInventory(left, top, prevSelectedItem);
updateItemText = true;
} else if (cursorUp) {
_inventorySelectedItem--;
if (_inventorySelectedItem < 0) {
_inventorySelectedItem = NUM_INVENTORY_ITEMS - 1;
}
- drawItem(left, top, prevSelectedItem);
+ drawOneInventory(left, top, prevSelectedItem);
updateItemText = true;
} else if (cursorLeft) {
_inventorySelectedItem -= 4;
if (_inventorySelectedItem < 0) {
_inventorySelectedItem += NUM_INVENTORY_ITEMS;
}
- drawItem(left, top, prevSelectedItem);
+ drawOneInventory(left, top, prevSelectedItem);
updateItemText = true;
} else if (cursorRight) {
_inventorySelectedItem += 4;
if (_inventorySelectedItem >= NUM_INVENTORY_ITEMS) {
_inventorySelectedItem -= NUM_INVENTORY_ITEMS;
}
- drawItem(left, top, prevSelectedItem);
+ drawOneInventory(left, top, prevSelectedItem);
updateItemText = true;
}
@@ -1448,12 +1448,12 @@ void Menu::processInventoryMenu() {
}
}
- drawItem(left, top, _inventorySelectedItem);
+ drawOneInventory(left, top, _inventorySelectedItem);
if (_inventorySelectedItem < NUM_INVENTORY_ITEMS && _engine->_input->toggleActionIfActive(TwinEActionType::UIEnter) && _engine->_gameState->hasItem((InventoryItems)_inventorySelectedItem) && !_engine->_gameState->inventoryDisabled()) {
_engine->_loopInventoryItem = _inventorySelectedItem;
_inventorySelectedColor = COLOR_91;
- drawItem(left, top, _inventorySelectedItem);
+ drawOneInventory(left, top, _inventorySelectedItem);
break;
}
}
diff --git a/engines/twine/menu/menu.h b/engines/twine/menu/menu.h
index c7cf2cc4403..de1e49fb5bb 100644
--- a/engines/twine/menu/menu.h
+++ b/engines/twine/menu/menu.h
@@ -190,11 +190,12 @@ private:
Common::Rect calcBehaviourRect(int32 left, int32 top, HeroBehaviourType behaviour) const;
bool isBehaviourHovered(int32 left, int32 top, HeroBehaviourType behaviour) const;
void drawBehaviour(int32 left, int32 top, HeroBehaviourType behaviour, int32 angle, bool cantDrawBox);
- void drawInventoryItems(int32 left, int32 top);
+ void drawListInventory(int32 left, int32 top);
void prepareAndDrawBehaviour(int32 left, int32 top, int32 angle, HeroBehaviourType behaviour); // DrawComportement
void drawBehaviourMenu(int32 left, int32 top, int32 angle); // DrawMenuComportement
Common::Rect calcItemRect(int32 left, int32 top, int32 item, int32 *centerX = nullptr, int32 *centerY = nullptr) const;
- void drawItem(int32 left, int32 top, int32 item);
+ // draw the 2d sprite of the item
+ void drawOneInventory(int32 left, int32 top, int32 item);
void drawSpriteAndString(int32 left, int32 top, const SpriteData &spriteData, const Common::String &str, int32 color = COLOR_GOLD);
diff --git a/engines/twine/text.cpp b/engines/twine/text.cpp
index d0f9df4e5ac..7ff7845d86c 100644
--- a/engines/twine/text.cpp
+++ b/engines/twine/text.cpp
@@ -350,12 +350,12 @@ void Text::initDialogueBox() {
}
// TODO: this blits a few pixels too much when switching an item in the inventory menu.
-void Text::initInventoryDialogueBox() {
+void Text::initInventoryDialogueBox() { // SecondInitDialWindow
_engine->blitWorkToFront(_dialTextBox);
_fadeInCharactersPos = 0;
}
-void Text::initInventoryText(InventoryItems index) {
+void Text::initInventoryText(InventoryItems index) { // OpenDialNoWindow
// 100 if the offset for the inventory item descriptions
initText((TextId)(100 + (int)index));
}
Commit: 78b15a7e89996b502f9250e3a1fc8127311d9c0a
https://github.com/scummvm/scummvm/commit/78b15a7e89996b502f9250e3a1fc8127311d9c0a
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2024-09-13T17:07:29+02:00
Commit Message:
TWINE: LBA2: prepare body and anim parser for lba2
Changed paths:
engines/twine/menu/menu.cpp
engines/twine/parser/entity.cpp
engines/twine/parser/entity.h
engines/twine/scene/actor.cpp
engines/twine/shared.h
diff --git a/engines/twine/menu/menu.cpp b/engines/twine/menu/menu.cpp
index 8576d4ba9f9..e043b9ca7df 100644
--- a/engines/twine/menu/menu.cpp
+++ b/engines/twine/menu/menu.cpp
@@ -249,6 +249,10 @@ void Menu::plasmaEffectRenderFrame() {
}
void Menu::processPlasmaEffect(const Common::Rect &rect, int32 color) {
+ if (_engine->isLBA2()) {
+ // TODO: effects are handled differently here.
+ return;
+ }
const int32 max_value = color + 15;
plasmaEffectRenderFrame();
diff --git a/engines/twine/parser/entity.cpp b/engines/twine/parser/entity.cpp
index d2eca34dcbd..5256b5eb62e 100644
--- a/engines/twine/parser/entity.cpp
+++ b/engines/twine/parser/entity.cpp
@@ -21,10 +21,11 @@
#include "twine/parser/entity.h"
#include "common/stream.h"
+#include "twine/shared.h"
namespace TwinE {
-bool EntityData::loadBody(Common::SeekableReadStream &stream) {
+bool EntityData::loadBody(Common::SeekableReadStream &stream, bool lba1) {
EntityBody body;
body.index = stream.readByte();
const int64 pos = stream.pos();
@@ -47,9 +48,13 @@ bool EntityData::loadBody(Common::SeekableReadStream &stream) {
return !stream.err();
}
-bool EntityData::loadAnim(Common::SeekableReadStream &stream) {
+bool EntityData::loadAnim(Common::SeekableReadStream &stream, bool lba1) {
EntityAnim anim;
- anim.animation = (AnimationTypes)stream.readByte();
+ if (lba1) {
+ anim.animation = (AnimationTypes)stream.readByte();
+ } else {
+ anim.animation = (AnimationTypes)stream.readUint16LE();
+ }
const int64 pos = stream.pos();
uint8 size = stream.readByte();
anim.animIndex = stream.readSint16LE();
@@ -82,6 +87,11 @@ bool EntityData::loadAnim(Common::SeekableReadStream &stream) {
action.animFrame = stream.readByte();
action.sampleIndex = stream.readSint16LE();
action.repeat = stream.readSint16LE();
+ if (!lba1) {
+ action.decal = stream.readSint16LE();
+ action.sampleVolume = stream.readByte();
+ action.frequency = stream.readSint16LE();
+ }
break;
case ActionType::ACTION_THROW_SEARCH:
action.animFrame = stream.readByte();
@@ -99,6 +109,7 @@ bool EntityData::loadAnim(Common::SeekableReadStream &stream) {
action.xAngle = ToAngle(stream.readSint16LE());
action.yAngle = ToAngle(stream.readSint16LE());
action.xRotPoint = stream.readSint16LE();
+ // TODO: does lba2 need a scaling here for xRotPoint?
action.extraAngle = ToAngle(stream.readByte());
action.strength = stream.readByte();
break;
@@ -109,8 +120,12 @@ bool EntityData::loadAnim(Common::SeekableReadStream &stream) {
break;
case ActionType::ACTION_SAMPLE_STOP:
action.animFrame = stream.readByte();
- action.sampleIndex = stream.readByte();
- stream.skip(1);
+ if (lba1) {
+ action.sampleIndex = stream.readByte();
+ stream.skip(1);
+ } else {
+ action.sampleIndex = stream.readUint16LE();
+ }
break;
case ActionType::ACTION_THROW_3D:
case ActionType::ACTION_THROW_3D_ALPHA:
@@ -148,6 +163,104 @@ bool EntityData::loadAnim(Common::SeekableReadStream &stream) {
default:
break;
}
+ if (!lba1) {
+ switch (action.type) {
+ case ActionType::ACTION_ZV:
+ action.animFrame = stream.readByte();
+ action.bbox.mins.x = stream.readSint16LE();
+ action.bbox.mins.y = stream.readSint16LE();
+ action.bbox.mins.z = stream.readSint16LE();
+ action.bbox.maxs.x = stream.readSint16LE();
+ action.bbox.maxs.y = stream.readSint16LE();
+ action.bbox.maxs.z = stream.readSint16LE();
+ break;
+ case ActionType::ACTION_SUPER_HIT:
+ action.animFrame = stream.readByte();
+ action.strength = stream.readByte();
+ action.superHitX = stream.readSint16LE();
+ action.superHitY = stream.readSint16LE();
+ action.superHitZ = stream.readSint16LE();
+ action.sizeSuperHit = stream.readSint16LE();
+ break;
+ case ActionType::ACTION_THROW_OBJ_3D:
+ action.animFrame = stream.readByte();
+ action.distanceX = stream.readSint16LE();
+ action.distanceY = stream.readSint16LE();
+ action.distanceZ = stream.readSint16LE();
+ action.spriteIndex = stream.readByte();
+ action.xAngle = ToAngle(stream.readSint16LE());
+ action.yAngle = ToAngle(stream.readSint16LE());
+ action.xRotPoint = stream.readSint16LE();
+ action.extraAngle = ToAngle(stream.readByte());
+ action.strength = stream.readByte();
+ break;
+ case ActionType::ACTION_NEW_SAMPLE:
+ action.animFrame = stream.readByte();
+ action.sampleIndex = stream.readSint16LE();
+ action.frequency = stream.readSint16LE();
+ break;
+ case ActionType::ACTION_THROW_DART:
+ action.animFrame = stream.readByte();
+ action.distanceY = stream.readSint16LE();
+ action.xAngle = ToAngle(stream.readSint16LE());
+ action.speed = stream.readSint16LE();
+ action.weight = stream.readSByte();
+ break;
+ case ActionType::ACTION_SHIELD:
+ action.animFrame = stream.readByte();
+ action.lastAnimFrame = stream.readByte();
+ break;
+ case ActionType::ACTION_FLOW_3D:
+ case ActionType::ACTION_THROW_3D_CONQUE:
+ action.animFrame = stream.readByte();
+ action.xAngle = ToAngle(stream.readSint16LE());
+ action.yHeight = stream.readSint16LE();
+ action.yAngle = ToAngle(stream.readSint16LE());
+ action.spriteIndex = stream.readByte();
+ break;
+ case ActionType::ACTION_IMPACT:
+ case ActionType::ACTION_RENVOYABLE:
+ action.animFrame = stream.readByte();
+ action.strength = stream.readSint16LE();
+ break;
+ case ActionType::ACTION_SCALE:
+ action.animFrame = stream.readByte();
+ action.scale = stream.readSint32LE();
+ break;
+ case ActionType::ACTION_IMPACT_3D:
+ action.animFrame = stream.readByte();
+ action.xAngle = ToAngle(stream.readSint16LE());
+ action.yHeight = stream.readSint16LE();
+ action.yAngle = ToAngle(stream.readSint16LE());
+ action.spriteIndex = stream.readSint16LE();
+ break;
+ case ActionType::ACTION_THROW_MAGIC_EXTRA:
+ action.animFrame = stream.readByte();
+ action.pointIndex = stream.readSint16LE();
+ action.spriteIndex = stream.readByte();
+ action.xAngle = ToAngle(stream.readSint16LE());
+ action.speed = stream.readSint16LE();
+ action.weight = stream.readSByte();
+ break;
+ case ActionType::ACTION_ZV_ANIMIT:
+ case ActionType::ACTION_RENVOIE:
+ case ActionType::ACTION_TRANSPARENT:
+ case ActionType::ACTION_SAMPLE_MAGIC:
+ case ActionType::ACTION_LEFT_JUMP:
+ case ActionType::ACTION_RIGHT_JUMP:
+ case ActionType::ACTION_THROW_FOUDRE:
+ action.animFrame = stream.readByte();
+ /* empty */
+ break;
+ case ActionType::ACTION_PATH:
+ case ActionType::ACTION_FLOW:
+ default:
+ break;
+ }
+ }
+ if (action.type > ActionType::ACTION_THROW_FOUDRE) {
+ error("Unknown action type %d", (int)action.type);
+ }
anim._actions.push_back(action);
}
_animations.push_back(anim);
@@ -165,11 +278,11 @@ bool EntityData::loadFromStream(Common::SeekableReadStream &stream, bool lba1) {
do {
const uint8 opcode = stream.readByte();
if (opcode == 1) {
- if (!loadBody(stream)) {
+ if (!loadBody(stream, lba1)) {
return false;
}
} else if (opcode == 3) {
- if (!loadAnim(stream)) {
+ if (!loadAnim(stream, lba1)) {
return false;
}
} else if (opcode == 0xFF) {
@@ -180,8 +293,8 @@ bool EntityData::loadFromStream(Common::SeekableReadStream &stream, bool lba1) {
return true;
}
-const Common::Array<EntityAnim::Action>* EntityData::getActions(AnimationTypes animation) const {
- for (const EntityAnim& anim : _animations) {
+const Common::Array<EntityAnim::Action> *EntityData::getActions(AnimationTypes animation) const {
+ for (const EntityAnim &anim : _animations) {
if (anim.animation == animation) {
if (anim._actions.empty()) {
return nullptr;
@@ -192,8 +305,8 @@ const Common::Array<EntityAnim::Action>* EntityData::getActions(AnimationTypes a
return nullptr;
}
-const EntityBody* EntityData::getBody(const int index) const {
- for (const EntityBody& body : _bodies) {
+const EntityBody *EntityData::getBody(const int index) const {
+ for (const EntityBody &body : _bodies) {
if (body.index == index) {
return &body;
}
@@ -202,7 +315,7 @@ const EntityBody* EntityData::getBody(const int index) const {
}
int32 EntityData::getAnimIndex(AnimationTypes animation) const {
- for (const EntityAnim& anim : _animations) {
+ for (const EntityAnim &anim : _animations) {
if (anim.animation == animation) {
return anim.animIndex;
}
diff --git a/engines/twine/parser/entity.h b/engines/twine/parser/entity.h
index 9fbc91822f0..7fe923328ee 100644
--- a/engines/twine/parser/entity.h
+++ b/engines/twine/parser/entity.h
@@ -43,6 +43,12 @@ struct EntityAnim {
struct Action {
ActionType type = ActionType::ACTION_NOP;
uint8 animFrame = 0;
+ uint8 lastAnimFrame = 0;
+ int8 weight = 0;
+ byte sampleVolume = 0;
+ int16 pointIndex = 0;
+ int16 spriteIndex = 0;
+ uint8 targetActor = 0;
int16 sampleIndex = 0;
int16 frequency = 0;
int16 xAngle = 0;
@@ -55,9 +61,15 @@ struct EntityAnim {
int16 distanceY = 0;
int16 distanceZ = 0;
int16 yHeight = 0;
- uint8 spriteIndex = 0;
- uint8 targetActor = 0;
int16 repeat = 0;
+ int16 speed = 0;
+ int16 superHitX = 0;
+ int16 superHitY = 0;
+ int16 superHitZ = 0;
+ int16 sizeSuperHit = 0;
+ int16 decal = 0;
+ int32 scale = 0;
+ BoundingBox bbox;
};
Common::Array<Action> _actions;
@@ -71,8 +83,8 @@ private:
Common::Array<EntityBody> _bodies;
Common::Array<EntityAnim> _animations;
- bool loadBody(Common::SeekableReadStream &stream);
- bool loadAnim(Common::SeekableReadStream &stream);
+ bool loadBody(Common::SeekableReadStream &stream, bool lba1);
+ bool loadAnim(Common::SeekableReadStream &stream, bool lba1);
protected:
void reset() override;
diff --git a/engines/twine/scene/actor.cpp b/engines/twine/scene/actor.cpp
index ccd057a156c..be51590936b 100644
--- a/engines/twine/scene/actor.cpp
+++ b/engines/twine/scene/actor.cpp
@@ -70,7 +70,11 @@ void Actor::restartHeroScene() {
}
void Actor::loadBehaviourEntity(ActorStruct *actor, EntityData &entityData, int16 &bodyAnimIndex, int32 index) {
- if (!entityData.loadFromHQR(Resources::HQR_FILE3D_FILE, index, _engine->isLBA1())) {
+ TwineResource modelRes(Resources::HQR_FILE3D_FILE, index);
+ if (_engine->isLBA2()) {
+ modelRes = TwineResource(Resources::HQR_RESS_FILE, index + 44);
+ }
+ if (!entityData.loadFromHQR(modelRes, _engine->isLBA1())) {
error("Failed to load actor 3d data for index: %i", index);
}
@@ -503,7 +507,11 @@ void ActorStruct::loadModel(int32 modelIndex, bool lba1) {
_body = modelIndex;
if (!_staticFlags.bSprite3D) {
debug(1, "Init actor with model %i", modelIndex);
- if (!_entityData.loadFromHQR(Resources::HQR_FILE3D_FILE, modelIndex, lba1)) {
+ TwineResource modelRes(Resources::HQR_FILE3D_FILE, modelIndex);
+ if (!lba1) {
+ modelRes = TwineResource(Resources::HQR_RESS_FILE, modelIndex + 44);
+ }
+ if (!_entityData.loadFromHQR(modelRes, lba1)) {
error("Failed to load entity data for index %i", modelIndex);
}
_entityDataPtr = &_entityData;
diff --git a/engines/twine/shared.h b/engines/twine/shared.h
index a0a303a2ced..38508542da8 100644
--- a/engines/twine/shared.h
+++ b/engines/twine/shared.h
@@ -678,7 +678,7 @@ enum InventoryItems {
struct TwineResource {
const char *hqr;
- const int32 index;
+ int32 index;
constexpr TwineResource(const char *_hqr, int32 _index) : hqr(_hqr), index(_index) {
}
Commit: b231384f9bb5d3b6932f14d9f8b46829bb2eb799
https://github.com/scummvm/scummvm/commit/b231384f9bb5d3b6932f14d9f8b46829bb2eb799
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2024-09-13T17:07:29+02:00
Commit Message:
TWINE: LBA2: the scene index needs a small offset
moved entity data parsing into resource class
Changed paths:
engines/twine/parser/entity.cpp
engines/twine/resources/resources.cpp
engines/twine/resources/resources.h
engines/twine/scene/actor.cpp
engines/twine/scene/actor.h
engines/twine/scene/scene.cpp
engines/twine/scene/scene.h
engines/twine/text.cpp
diff --git a/engines/twine/parser/entity.cpp b/engines/twine/parser/entity.cpp
index 5256b5eb62e..79f41f2002e 100644
--- a/engines/twine/parser/entity.cpp
+++ b/engines/twine/parser/entity.cpp
@@ -197,6 +197,8 @@ bool EntityData::loadAnim(Common::SeekableReadStream &stream, bool lba1) {
case ActionType::ACTION_NEW_SAMPLE:
action.animFrame = stream.readByte();
action.sampleIndex = stream.readSint16LE();
+ action.decal = stream.readSint16LE();
+ action.sampleVolume = stream.readByte();
action.frequency = stream.readSint16LE();
break;
case ActionType::ACTION_THROW_DART:
diff --git a/engines/twine/resources/resources.cpp b/engines/twine/resources/resources.cpp
index 660f1b3d5a4..7e81b2d64ac 100644
--- a/engines/twine/resources/resources.cpp
+++ b/engines/twine/resources/resources.cpp
@@ -66,6 +66,25 @@ void Resources::preloadAnim3DS() {
_anim3DSData.loadFromHQR(Resources::HQR_ANIM3DS_FILE, index, _engine->isLBA1());
}
+void Resources::loadEntityData(EntityData &entityData, int32 &index) {
+ if (_engine->isLBA1()) {
+ TwineResource modelRes(Resources::HQR_FILE3D_FILE, index);
+ if (!entityData.loadFromHQR(modelRes, _engine->isLBA1())) {
+ error("Failed to load actor 3d data for index: %i", index);
+ }
+ } else {
+ // TODO: don't allocate each time
+ TwineResource modelRes(Resources::HQR_RESS_FILE, 44);
+ uint8 *file3dBuf = nullptr;
+ const int32 holomapImageSize = HQR::getAllocEntry(&file3dBuf, modelRes);
+ if (!entityData.loadFromBuffer((uint8 *)(file3dBuf + *(((uint32 *)file3dBuf) + (index))), holomapImageSize, _engine->isLBA1())) {
+ delete file3dBuf;
+ error("Failed to load actor 3d data for index: %i", index);
+ }
+ delete file3dBuf;
+ }
+}
+
const T_ANIM_3DS *Resources::getAnim(int index) const {
if (index < 0 || index >= (int)_anim3DSData.getAnims().size()) {
return nullptr;
diff --git a/engines/twine/resources/resources.h b/engines/twine/resources/resources.h
index 98575400024..1567ef08a52 100644
--- a/engines/twine/resources/resources.h
+++ b/engines/twine/resources/resources.h
@@ -196,6 +196,7 @@ public:
void initResources();
const Trajectory *getTrajectory(int index) const;
+ void loadEntityData(EntityData &entityData, int32 &index);
const TextEntry *getText(TextBankId textBankId, TextId index) const;
const T_ANIM_3DS *getAnim(int index) const;
diff --git a/engines/twine/scene/actor.cpp b/engines/twine/scene/actor.cpp
index be51590936b..f1fbe5a1497 100644
--- a/engines/twine/scene/actor.cpp
+++ b/engines/twine/scene/actor.cpp
@@ -70,14 +70,7 @@ void Actor::restartHeroScene() {
}
void Actor::loadBehaviourEntity(ActorStruct *actor, EntityData &entityData, int16 &bodyAnimIndex, int32 index) {
- TwineResource modelRes(Resources::HQR_FILE3D_FILE, index);
- if (_engine->isLBA2()) {
- modelRes = TwineResource(Resources::HQR_RESS_FILE, index + 44);
- }
- if (!entityData.loadFromHQR(modelRes, _engine->isLBA1())) {
- error("Failed to load actor 3d data for index: %i", index);
- }
-
+ _engine->_resources->loadEntityData(entityData, index);
actor->_entityDataPtr = &entityData;
bodyAnimIndex = entityData.getAnimIndex(AnimationTypes::kStanding);
if (bodyAnimIndex == -1) {
@@ -503,23 +496,6 @@ void Actor::posObjectAroundAnother(uint8 numsrc, uint8 numtopos) {
#endif
}
-void ActorStruct::loadModel(int32 modelIndex, bool lba1) {
- _body = modelIndex;
- if (!_staticFlags.bSprite3D) {
- debug(1, "Init actor with model %i", modelIndex);
- TwineResource modelRes(Resources::HQR_FILE3D_FILE, modelIndex);
- if (!lba1) {
- modelRes = TwineResource(Resources::HQR_RESS_FILE, modelIndex + 44);
- }
- if (!_entityData.loadFromHQR(modelRes, lba1)) {
- error("Failed to load entity data for index %i", modelIndex);
- }
- _entityDataPtr = &_entityData;
- } else {
- _entityDataPtr = nullptr;
- }
-}
-
int16 ActorMoveStruct::getRealValueFromTime(int32 time) {
if (timeValue) {
const int32 delta = time - memoTicks;
diff --git a/engines/twine/scene/actor.h b/engines/twine/scene/actor.h
index b25bd62db79..4c5610c43be 100644
--- a/engines/twine/scene/actor.h
+++ b/engines/twine/scene/actor.h
@@ -146,13 +146,12 @@ private:
bool _brickCausesDamage = false;
int32 _maxLife;
- EntityData _entityData;
-
public:
ActorStruct(int maxLife = 0) : _lifePoint(maxLife), _maxLife(maxLife) {}
StaticFlagsStruct _staticFlags; // Flags
DynamicFlagsStruct _workFlags; // WorkFlags
+ EntityData _entityData;
inline ShapeType brickShape() const { return _col; }
inline void setCollision(ShapeType shapeType) {
_col = shapeType;
@@ -160,7 +159,6 @@ public:
}
inline void setBrickCausesDamage() { _brickCausesDamage = true; }
inline bool brickCausesDamage() { return _brickCausesDamage; }
- void loadModel(int32 modelIndex, bool lba1);
void addLife(int32 val);
diff --git a/engines/twine/scene/scene.cpp b/engines/twine/scene/scene.cpp
index da24815b642..8e97158c254 100644
--- a/engines/twine/scene/scene.cpp
+++ b/engines/twine/scene/scene.cpp
@@ -179,6 +179,17 @@ bool Scene::loadSceneCubeXY(int numcube, int32 *cubex, int32 *cubey) {
return false;
}
+void Scene::loadModel(ActorStruct &actor, int32 modelIndex, bool lba1) {
+ actor._body = modelIndex;
+ if (!actor._staticFlags.bSprite3D) {
+ debug(1, "Init actor with model %i", modelIndex);
+ _engine->_resources->loadEntityData(actor._entityData, modelIndex);
+ actor._entityDataPtr = &actor._entityData;
+ } else {
+ actor._entityDataPtr = nullptr;
+ }
+}
+
bool Scene::loadSceneLBA2() {
Common::MemoryReadStream stream(_currentScene, _currentSceneSize);
_island = stream.readByte();
@@ -230,7 +241,7 @@ bool Scene::loadSceneLBA2() {
ActorStruct *act = &_sceneActors[a];
setActorStaticFlags(act, stream.readUint32LE());
- act->loadModel((int16)stream.readUint16LE(), false);
+ loadModel(*act, (int16)stream.readUint16LE(), false);
act->_genBody = (BodyType)stream.readSint16LE();
act->_genAnim = (AnimationTypes)stream.readByte();
@@ -362,7 +373,7 @@ bool Scene::loadSceneLBA1() {
ActorStruct *act = &_sceneActors[a];
setActorStaticFlags(act, stream.readUint16LE());
- act->loadModel(stream.readUint16LE(), true);
+ loadModel(*act, stream.readUint16LE(), true);
act->_genBody = (BodyType)stream.readByte();
act->_genAnim = (AnimationTypes)stream.readByte();
@@ -467,6 +478,9 @@ bool Scene::loadSceneLBA1() {
bool Scene::initScene(int32 index) {
// load scene from file
+ if (_engine->isLBA2()) {
+ index++;
+ }
_currentSceneSize = HQR::getAllocEntry(&_currentScene, Resources::HQR_SCENE_FILE, index);
if (_currentSceneSize == 0) {
return false;
diff --git a/engines/twine/scene/scene.h b/engines/twine/scene/scene.h
index 7789280017f..db191260faf 100644
--- a/engines/twine/scene/scene.h
+++ b/engines/twine/scene/scene.h
@@ -117,6 +117,8 @@ class Scene {
private:
TwinEEngine *_engine;
+ void loadModel(ActorStruct &actor, int32 modelIndex, bool lba1);
+
/** Process zone extra bonus */
void processZoneExtraBonus(ZoneStruct *zone);
void setActorStaticFlags(ActorStruct *act, uint32 staticFlags);
diff --git a/engines/twine/text.cpp b/engines/twine/text.cpp
index 7ff7845d86c..caca662db53 100644
--- a/engines/twine/text.cpp
+++ b/engines/twine/text.cpp
@@ -173,7 +173,8 @@ void Text::initDial(TextBankId bankIdx) {
}
void Text::initSceneTextBank() {
- initDial((TextBankId)((int)_engine->_scene->_sceneTextBank + (int)TextBankId::Citadel_Island));
+ const int textBankId = (int)_engine->_scene->_sceneTextBank;
+ initDial((TextBankId)(textBankId + (int)TextBankId::Citadel_Island));
}
void Text::drawCharacter(int32 x, int32 y, uint16 character) {
More information about the Scummvm-git-logs
mailing list