aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFilippos Karapetis2010-01-23 14:39:03 +0000
committerFilippos Karapetis2010-01-23 14:39:03 +0000
commitd6e0276119265f825bbd5ab4a418cf234d48ed82 (patch)
tree042125625524feeda486cd29bfeda12b35b5d89d
parent18a18701f7dbe9ffeaf9d0c67003090fa8d68534 (diff)
downloadscummvm-rg350-d6e0276119265f825bbd5ab4a418cf234d48ed82.tar.gz
scummvm-rg350-d6e0276119265f825bbd5ab4a418cf234d48ed82.tar.bz2
scummvm-rg350-d6e0276119265f825bbd5ab4a418cf234d48ed82.zip
Added song manipulation debug commands: songinfo, startsound, togglesound and stopallsounds. is_sample now works with the new sound code
svn-id: r47475
-rw-r--r--engines/sci/console.cpp238
-rw-r--r--engines/sci/console.h5
-rw-r--r--engines/sci/sound/music.cpp64
-rw-r--r--engines/sci/sound/music.h2
-rw-r--r--engines/sci/sound/soundcmd.cpp28
-rw-r--r--engines/sci/sound/soundcmd.h13
6 files changed, 264 insertions, 86 deletions
diff --git a/engines/sci/console.cpp b/engines/sci/console.cpp
index 1ab8e2fbb1..2a1adb3fcf 100644
--- a/engines/sci/console.cpp
+++ b/engines/sci/console.cpp
@@ -132,10 +132,13 @@ Console::Console(SciEngine *vm) : GUI::Debugger() {
DCmd_Register("gc_normalize", WRAP_METHOD(Console, cmdGCNormalize));
// Music/SFX
DCmd_Register("songlib", WRAP_METHOD(Console, cmdSongLib));
+ DCmd_Register("songinfo", WRAP_METHOD(Console, cmdSongInfo));
DCmd_Register("is_sample", WRAP_METHOD(Console, cmdIsSample));
+ DCmd_Register("startsound", WRAP_METHOD(Console, cmdStartSound));
+ DCmd_Register("togglesound", WRAP_METHOD(Console, cmdToggleSound));
+ DCmd_Register("stopallsounds", WRAP_METHOD(Console, cmdStopAllSounds));
DCmd_Register("sfx01_header", WRAP_METHOD(Console, cmdSfx01Header));
DCmd_Register("sfx01_track", WRAP_METHOD(Console, cmdSfx01Track));
- DCmd_Register("stop_sfx", WRAP_METHOD(Console, cmdStopSfx));
// Script
DCmd_Register("addresses", WRAP_METHOD(Console, cmdAddresses));
DCmd_Register("registers", WRAP_METHOD(Console, cmdRegisters));
@@ -1380,6 +1383,165 @@ bool Console::cmdSongLib(int argc, const char **argv) {
return true;
}
+bool Console::cmdSongInfo(int argc, const char **argv) {
+ if (argc != 2) {
+ DebugPrintf("Shows information about a given song in the playlist\n");
+ DebugPrintf("Usage: %s <song object>\n", argv[0]);
+ return true;
+ }
+
+ reg_t addr;
+
+ if (parse_reg_t(_vm->_gamestate, argv[1], &addr, false)) {
+ DebugPrintf("Invalid address passed.\n");
+ DebugPrintf("Check the \"addresses\" command on how to use addresses\n");
+ return true;
+ }
+
+ _vm->getEngineState()->_soundCmd->printSongInfo(addr, this);
+
+ return true;
+}
+
+bool Console::cmdStartSound(int argc, const char **argv) {
+ if (argc != 2) {
+ DebugPrintf("Adds the requested sound resource to the playlist, and starts playing it\n");
+ DebugPrintf("Usage: %s <sound resource id>\n", argv[0]);
+ return true;
+ }
+
+ int16 number = atoi(argv[1]);
+
+ if (!_vm->getResourceManager()->testResource(ResourceId(kResourceTypeSound, number))) {
+ DebugPrintf("Unable to load this sound resource, most probably it has an equivalent audio resource (SCI1.1)\n");
+ return true;
+ }
+
+ _vm->getEngineState()->_soundCmd->startNewSound(number);
+
+ return false;
+}
+
+bool Console::cmdToggleSound(int argc, const char **argv) {
+ if (argc != 3) {
+ DebugPrintf("Plays or stops the specified sound in the playlist\n");
+ DebugPrintf("Usage: %s <address> <state>\n", argv[0]);
+ DebugPrintf("Where:\n");
+ DebugPrintf("- <address> is the address of the sound to play or stop.\n");
+ DebugPrintf("- <state> is the new state (play or stop).\n");
+ DebugPrintf("Check the \"addresses\" command on how to use addresses\n");
+ return true;
+ }
+
+ reg_t id;
+
+ if (parse_reg_t(_vm->_gamestate, argv[1], &id, false)) {
+ DebugPrintf("Invalid address passed.\n");
+ DebugPrintf("Check the \"addresses\" command on how to use addresses\n");
+ return true;
+ }
+
+#ifdef USE_OLD_MUSIC_FUNCTIONS
+ int handle = id.segment << 16 | id.offset; // frobnicate handle
+
+ if (id.segment) {
+ SegManager *segMan = _vm->_gamestate->_segMan; // for PUT_SEL32V
+ _vm->_gamestate->_sound.sfx_song_set_status(handle, SOUND_STATUS_STOPPED);
+ _vm->_gamestate->_sound.sfx_remove_song(handle);
+ PUT_SEL32V(segMan, id, signal, SIGNAL_OFFSET);
+ PUT_SEL32V(segMan, id, nodePtr, 0);
+ PUT_SEL32V(segMan, id, handle, 0);
+ }
+#else
+
+ Common::String newState = argv[2];
+ newState.toLowercase();
+
+ if (newState == "play")
+ _vm->_gamestate->_soundCmd->playSound(id);
+ else if (newState == "stop")
+ _vm->_gamestate->_soundCmd->stopSound(id);
+ else
+ DebugPrintf("New state can either be 'play' or 'stop'");
+#endif
+
+ return true;
+}
+
+bool Console::cmdStopAllSounds(int argc, const char **argv) {
+#ifndef USE_OLD_MUSIC_FUNCTIONS
+ _vm->_gamestate->_soundCmd->stopAllSounds();
+#endif
+
+ DebugPrintf("All sounds have been stopped\n");
+ return true;
+}
+
+bool Console::cmdIsSample(int argc, const char **argv) {
+ if (argc != 2) {
+ DebugPrintf("Tests whether a given sound resource is a PCM sample, \n");
+ DebugPrintf("and displays information on it if it is.\n");
+ DebugPrintf("Usage: %s <sample id>\n", argv[0]);
+ return true;
+ }
+
+#ifdef USE_OLD_MUSIC_FUNCTIONS
+ Resource *song = _vm->getResourceManager()->findResource(ResourceId(kResourceTypeSound, atoi(argv[1])), 0);
+ SongIterator *songit;
+ Audio::AudioStream *data;
+
+ if (!song) {
+ DebugPrintf("Not a sound resource!\n");
+ return true;
+ }
+
+ songit = songit_new(song->data, song->size, SCI_SONG_ITERATOR_TYPE_SCI0, 0xcaffe /* What do I care about the ID? */);
+
+ if (!songit) {
+ DebugPrintf("Could not convert to song iterator!\n");
+ return true;
+ }
+
+ if ((data = songit->getAudioStream())) {
+ // TODO
+/*
+ DebugPrintf("\nIs sample (encoding %dHz/%s/%04x)", data->conf.rate, (data->conf.stereo) ?
+ ((data->conf.stereo == SFX_PCM_STEREO_LR) ? "stereo-LR" : "stereo-RL") : "mono", data->conf.format);
+*/
+ delete data;
+ } else
+ DebugPrintf("Valid song, but not a sample.\n");
+
+ delete songit;
+#else
+ int16 number = atoi(argv[1]);
+
+ if (!_vm->getResourceManager()->testResource(ResourceId(kResourceTypeSound, number))) {
+ DebugPrintf("Unable to load this sound resource, most probably it has an equivalent audio resource (SCI1.1)\n");
+ return true;
+ }
+
+ SoundResource *soundRes = new SoundResource(number, _vm->getResourceManager(), _vm->getEngineState()->detectDoSoundType());
+
+ if (!soundRes) {
+ DebugPrintf("Not a sound resource!\n");
+ return true;
+ }
+
+ SoundResource::Track *track = soundRes->getDigitalTrack();
+ if (!track || track->digitalChannelNr == -1) {
+ DebugPrintf("Valid song, but not a sample.\n");
+ delete soundRes;
+ return true;
+ }
+
+ DebugPrintf("Sample size: %d, sample rate: %d, channels: %d, digital channel number: %d\n",
+ track->digitalSampleSize, track->digitalSampleRate, track->channelCount, track->digitalChannelNr);
+#endif
+
+ return true;
+}
+
bool Console::cmdGCInvoke(int argc, const char **argv) {
DebugPrintf("Performing garbage collection...\n");
run_gc(_vm->_gamestate);
@@ -2278,47 +2440,6 @@ bool Console::cmdBreakpointExecFunction(int argc, const char **argv) {
return true;
}
-bool Console::cmdIsSample(int argc, const char **argv) {
- if (argc != 2) {
- DebugPrintf("Tests whether a given sound resource is a PCM sample, \n");
- DebugPrintf("and displays information on it if it is.\n");
- DebugPrintf("Usage: %s <sample id>\n", argv[0]);
- return true;
- }
-
-#ifdef USE_OLD_MUSIC_FUNCTIONS
- Resource *song = _vm->getResourceManager()->findResource(ResourceId(kResourceTypeSound, atoi(argv[1])), 0);
- SongIterator *songit;
- Audio::AudioStream *data;
-
- if (!song) {
- DebugPrintf("Not a sound resource!\n");
- return true;
- }
-
- songit = songit_new(song->data, song->size, SCI_SONG_ITERATOR_TYPE_SCI0, 0xcaffe /* What do I care about the ID? */);
-
- if (!songit) {
- DebugPrintf("Could not convert to song iterator!\n");
- return true;
- }
-
- if ((data = songit->getAudioStream())) {
- // TODO
-/*
- DebugPrintf("\nIs sample (encoding %dHz/%s/%04x)", data->conf.rate, (data->conf.stereo) ?
- ((data->conf.stereo == SFX_PCM_STEREO_LR) ? "stereo-LR" : "stereo-RL") : "mono", data->conf.format);
-*/
- delete data;
- } else
- DebugPrintf("Valid song, but not a sample.\n");
-
- delete songit;
-#endif
-
- return true;
-}
-
bool Console::cmdSfx01Header(int argc, const char **argv) {
if (argc != 2) {
DebugPrintf("Dumps the header of a SCI01 song\n");
@@ -2505,39 +2626,6 @@ bool Console::cmdSfx01Track(int argc, const char **argv) {
return true;
}
-bool Console::cmdStopSfx(int argc, const char **argv) {
- if (argc != 2) {
- DebugPrintf("Stops a playing sound\n");
- DebugPrintf("Usage: %s <address>\n", argv[0]);
- DebugPrintf("Where <address> is the address of the sound to stop.\n");
- DebugPrintf("Check the \"addresses\" command on how to use addresses\n");
- return true;
- }
-
- reg_t id;
-
- if (parse_reg_t(_vm->_gamestate, argv[1], &id, false)) {
- DebugPrintf("Invalid address passed.\n");
- DebugPrintf("Check the \"addresses\" command on how to use addresses\n");
- return true;
- }
-
-#ifdef USE_OLD_MUSIC_FUNCTIONS
- int handle = id.segment << 16 | id.offset; // frobnicate handle
-
- if (id.segment) {
- SegManager *segMan = _vm->_gamestate->_segMan; // for PUT_SEL32V
- _vm->_gamestate->_sound.sfx_song_set_status(handle, SOUND_STATUS_STOPPED);
- _vm->_gamestate->_sound.sfx_remove_song(handle);
- PUT_SEL32V(segMan, id, signal, SIGNAL_OFFSET);
- PUT_SEL32V(segMan, id, nodePtr, 0);
- PUT_SEL32V(segMan, id, handle, 0);
- }
-#endif
-
- return true;
-}
-
bool Console::cmdExit(int argc, const char **argv) {
if (argc != 2) {
DebugPrintf("%s game - exit gracefully\n", argv[0]);
diff --git a/engines/sci/console.h b/engines/sci/console.h
index 6829208179..c42603273c 100644
--- a/engines/sci/console.h
+++ b/engines/sci/console.h
@@ -104,10 +104,13 @@ private:
bool cmdGCNormalize(int argc, const char **argv);
// Music/SFX
bool cmdSongLib(int argc, const char **argv);
+ bool cmdSongInfo(int argc, const char **argv);
bool cmdIsSample(int argc, const char **argv);
+ bool cmdStartSound(int argc, const char **argv);
+ bool cmdToggleSound(int argc, const char **argv);
+ bool cmdStopAllSounds(int argc, const char **argv);
bool cmdSfx01Header(int argc, const char **argv);
bool cmdSfx01Track(int argc, const char **argv);
- bool cmdStopSfx(int argc, const char **argv);
// Script
bool cmdAddresses(int argc, const char **argv);
bool cmdRegisters(int argc, const char **argv);
diff --git a/engines/sci/sound/music.cpp b/engines/sci/sound/music.cpp
index ef75ba96fc..a917e36ab3 100644
--- a/engines/sci/sound/music.cpp
+++ b/engines/sci/sound/music.cpp
@@ -108,6 +108,16 @@ void SciMusic::pauseAll(bool pause) {
}
}
+void SciMusic::stopAll() {
+ Common::StackLock lock(_mutex);
+
+ const MusicList::iterator end = _playList.end();
+ for (MusicList::iterator i = _playList.begin(); i != end; ++i) {
+ soundStop(*i);
+ }
+}
+
+
void SciMusic::miditimerCallback(void *p) {
SciMusic *aud = (SciMusic *)p;
@@ -154,10 +164,8 @@ void SciMusic::sortPlayList() {
qsort(pData, _playList.size(), sizeof(MusicEntry *), &f_compare);
}
void SciMusic::soundInitSnd(MusicEntry *pSnd) {
- SoundResource::Track *track = NULL;
int channelFilterMask = 0;
-
- track = pSnd->soundRes->getTrackByType(_pMidiDrv->getPlayId(_soundVersion));
+ SoundResource::Track *track = pSnd->soundRes->getTrackByType(_pMidiDrv->getPlayId(_soundVersion));
if (track) {
// If MIDI device is selected but there is no digital track in sound resource
@@ -223,8 +231,7 @@ void SciMusic::soundPlay(MusicEntry *pSnd) {
if (pSnd->pStreamAud && !_pMixer->isSoundHandleActive(pSnd->hCurrentAud)) {
if (pSnd->loop > 1) {
pSnd->pLoopStream = new Audio::LoopingAudioStream(pSnd->pStreamAud,
- pSnd->loop, DisposeAfterUse::NO
- );
+ pSnd->loop, DisposeAfterUse::NO);
_pMixer->playInputStream(pSnd->soundType, &pSnd->hCurrentAud,
pSnd->pLoopStream, -1, pSnd->volume, 0,
DisposeAfterUse::NO);
@@ -358,12 +365,53 @@ void SciMusic::printPlayList(Console *con) {
const char *musicStatus[] = { "Stopped", "Initialized", "Paused", "Playing" };
+ for (uint32 i = 0; i < _playList.size(); i++) {
+ MusicEntry *song = _playList[i];
+ con->DebugPrintf("%d: %04x:%04x, resource id: %d, status: %s, %s type\n", i,
+ PRINT_REG(song->soundObj), song->resnum,
+ musicStatus[song->status], song->pMidiParser ? "MIDI" : "digital audio");
+ }
+}
+
+void SciMusic::printSongInfo(reg_t obj, Console *con) {
+ Common::StackLock lock(_mutex);
+
+ const char *musicStatus[] = { "Stopped", "Initialized", "Paused", "Playing" };
+
const MusicList::iterator end = _playList.end();
for (MusicList::iterator i = _playList.begin(); i != end; ++i) {
- con->DebugPrintf("%d: %04x:%04x, priority: %d, status: %s\n", i,
- PRINT_REG((*i)->soundObj), (*i)->prio,
- musicStatus[(*i)->status]);
+ MusicEntry *song = *i;
+ if (song->soundObj == obj) {
+ con->DebugPrintf("Resource id: %d, status: %s\n", song->resnum, musicStatus[song->status]);
+ con->DebugPrintf("dataInc: %d, hold: %d, loop: %d\n", song->dataInc, song->hold, song->loop);
+ con->DebugPrintf("signal: %d, priority: %d\n", song->signal, song->prio);
+ con->DebugPrintf("ticker: %d, volume: %d\n", song->ticker, song->volume);
+
+ if (song->pMidiParser) {
+ con->DebugPrintf("Type: MIDI\n");
+ if (song->soundRes) {
+ SoundResource::Track *track = song->soundRes->getTrackByType(_pMidiDrv->getPlayId(_soundVersion));
+ con->DebugPrintf("Channels: %d\n", track->channelCount);
+ }
+ } else if (song->pStreamAud || song->pLoopStream) {
+ con->DebugPrintf("Type: digital audio (%s), sound active: %s\n",
+ song->pStreamAud ? "non looping" : "looping",
+ _pMixer->isSoundHandleActive(song->hCurrentAud) ? "yes" : "no");
+ if (song->soundRes) {
+ con->DebugPrintf("Sound resource information:\n");
+ SoundResource::Track *track = song->soundRes->getTrackByType(_pMidiDrv->getPlayId(_soundVersion));
+ if (track && track->digitalChannelNr != -1) {
+ con->DebugPrintf("Sample size: %d, sample rate: %d, channels: %d, digital channel number: %d\n",
+ track->digitalSampleSize, track->digitalSampleRate, track->channelCount, track->digitalChannelNr);
+ }
+ }
+ }
+
+ return;
+ }
}
+
+ con->DebugPrintf("Song object not found in playlist");
}
MusicEntry::MusicEntry() {
diff --git a/engines/sci/sound/music.h b/engines/sci/sound/music.h
index 660aef9cad..39b6ad0d74 100644
--- a/engines/sci/sound/music.h
+++ b/engines/sci/sound/music.h
@@ -140,6 +140,7 @@ public:
void onTimer();
void clearPlayList();
void pauseAll(bool pause);
+ void stopAll();
// sound and midi functions
void soundInitSnd(MusicEntry *pSnd);
@@ -176,6 +177,7 @@ public:
}
void printPlayList(Console *con);
+ void printSongInfo(reg_t obj, Console *con);
// The following two methods are NOT thread safe - make sure that
// the mutex is always locked before calling them
diff --git a/engines/sci/sound/soundcmd.cpp b/engines/sci/sound/soundcmd.cpp
index f5fb5b4e4f..dcf4b33553 100644
--- a/engines/sci/sound/soundcmd.cpp
+++ b/engines/sci/sound/soundcmd.cpp
@@ -248,7 +248,7 @@ void SoundCommandParser::cmdInitSound(reg_t obj, int16 value) {
if (!obj.segment)
return;
- int number = obj.segment ? GET_SEL32V(_segMan, obj, number) : 0;
+ int number = GET_SEL32V(_segMan, obj, number);
#ifdef USE_OLD_MUSIC_FUNCTIONS
@@ -1072,6 +1072,32 @@ void SoundCommandParser::printPlayList(Console *con) {
#endif
}
+void SoundCommandParser::printSongInfo(reg_t obj, Console *con) {
+#ifndef USE_OLD_MUSIC_FUNCTIONS
+ _music->printSongInfo(obj, con);
+#endif
+}
+
+void SoundCommandParser::stopAllSounds() {
+#ifndef USE_OLD_MUSIC_FUNCTIONS
+ _music->stopAll();
+#endif
+}
+
+void SoundCommandParser::startNewSound(int number) {
+#ifndef USE_OLD_MUSIC_FUNCTIONS
+ Common::StackLock lock(_music->_mutex);
+
+ // Overwrite the first sound in the playlist
+ MusicEntry *song = *_music->getPlayListStart();
+ reg_t soundObj = song->soundObj;
+ cmdDisposeSound(soundObj, 0);
+ PUT_SEL32V(_segMan, soundObj, number, number);
+ cmdInitSound(soundObj, 0);
+ cmdPlaySound(soundObj, 0);
+#endif
+}
+
void SoundCommandParser::setMasterVolume(int vol) {
#ifndef USE_OLD_MUSIC_FUNCTIONS
_music->soundSetMasterVolume(vol);
diff --git a/engines/sci/sound/soundcmd.h b/engines/sci/sound/soundcmd.h
index fc80b6b3fa..41ce9517a9 100644
--- a/engines/sci/sound/soundcmd.h
+++ b/engines/sci/sound/soundcmd.h
@@ -58,13 +58,24 @@ public:
#endif
reg_t parseCommand(int argc, reg_t *argv, reg_t acc);
+
+ // Functions used for game state loading
void clearPlayList();
void syncPlayList(Common::Serializer &s);
void reconstructPlayList(int savegame_version);
- void printPlayList(Console *con);
+
+ // Functions used for the ScummVM menus
void setMasterVolume(int vol);
void pauseAll(bool pause);
+ // Debug console functions
+ void playSound(reg_t obj) { cmdPlaySound(obj, 0); }
+ void stopSound(reg_t obj) { cmdStopSound(obj, 0); }
+ void startNewSound(int number);
+ void stopAllSounds();
+ void printPlayList(Console *con);
+ void printSongInfo(reg_t obj, Console *con);
+
#ifndef USE_OLD_MUSIC_FUNCTIONS
/**
* Synchronizes the current state of the music list to the rest of the engine, so that