Every functionality has been implemented (audio options, text options, saving and loading). The only thing currently missing from the menu is the thumbnail handling.
272 lines
6.4 KiB
C++
272 lines
6.4 KiB
C++
/* ScummVM - Graphic Adventure Engine
|
|
*
|
|
* ScummVM is the legal property of its developers, whose names
|
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
|
* file distributed with this source distribution.
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*
|
|
*/
|
|
|
|
#include "scumm/imuse_digi/dimuse_engine.h"
|
|
|
|
namespace Scumm {
|
|
|
|
// We have some uintptr arguments as commands 28, 29 and 30 actually require pointer arguments
|
|
// Unfortunately this makes function calls for other command a little less pretty...
|
|
int IMuseDigital::cmdsHandleCmd(int cmd, uint8 *ptr, int a, int b, int c, int d, int e,
|
|
int f, int g, int h, int i, int j, int k, int l, int m, int n) {
|
|
|
|
// Convert the character constant (single quotes '') to string
|
|
char marker[5];
|
|
if (!_isEarlyDiMUSE && (cmd == 17 || cmd == 18 || cmd == 19)) {
|
|
for (int index = 0; index < 4; index++) {
|
|
#if defined SCUMM_BIG_ENDIAN
|
|
marker[index] = (b >> (8 * index)) & 0xff;
|
|
#elif defined SCUMM_LITTLE_ENDIAN
|
|
marker[3 - index] = (b >> (8 * index)) & 0xff;
|
|
#endif
|
|
}
|
|
marker[4] = '\0';
|
|
}
|
|
|
|
switch (cmd) {
|
|
case 0:
|
|
return cmdsInit();
|
|
case 3:
|
|
return cmdsPause();
|
|
case 4:
|
|
return cmdsResume();
|
|
case 7:
|
|
return _groupsHandler->setGroupVol(a, b);
|
|
case 8:
|
|
cmdsStartSound(a, b);
|
|
break;
|
|
case 9:
|
|
cmdsStopSound(a);
|
|
break;
|
|
case 10:
|
|
cmdsStopAllSounds();
|
|
break;
|
|
case 11:
|
|
return cmdsGetNextSound(a);
|
|
case 12:
|
|
cmdsSetParam(a, b, c);
|
|
break;
|
|
case 13:
|
|
return cmdsGetParam(a, b);
|
|
case 14:
|
|
return _fadesHandler->fadeParam(a, b, c, d);
|
|
case 15:
|
|
return cmdsSetHook(a, b);
|
|
case 16:
|
|
return cmdsGetHook(a);
|
|
case 17:
|
|
return _triggersHandler->setTrigger(a, marker, c, d, e, f, g, h, i, j, k, l, m, n);
|
|
case 18:
|
|
return _triggersHandler->checkTrigger(a, marker, c);
|
|
case 19:
|
|
return _triggersHandler->clearTrigger(a, marker, c);
|
|
case 20:
|
|
return _triggersHandler->deferCommand(a, b, c, d, e, f, g, h, i, j, k, l, m, n);
|
|
case 21:
|
|
_vm->_sound->extractSyncsFromDiMUSEMarker((char *)ptr);
|
|
break;
|
|
case 25:
|
|
return waveStartStream(a, b, c);
|
|
case 26:
|
|
if (_isEarlyDiMUSE)
|
|
return waveSwitchStream(a, b, ptr, d, e);
|
|
else
|
|
return waveSwitchStream(a, b, c, d, e);
|
|
case 27:
|
|
return waveProcessStreams();
|
|
case 29:
|
|
return waveFeedStream(a, ptr, c, d);
|
|
default:
|
|
debug(5, "IMuseDigital::cmdsHandleCmd(): bogus/unused opcode ignored (%d).", cmd);
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int IMuseDigital::cmdsInit() {
|
|
_cmdsRunning60HzCount = 0;
|
|
_cmdsRunning10HzCount = 0;
|
|
|
|
if (_groupsHandler->init() || _fadesHandler->init() ||
|
|
_triggersHandler->init() || waveInit()) {
|
|
return -1;
|
|
}
|
|
|
|
_cmdsPauseCount = 0;
|
|
return 48;
|
|
}
|
|
|
|
int IMuseDigital::cmdsDeinit() {
|
|
waveTerminate();
|
|
waveOutDeinit();
|
|
_triggersHandler->deinit();
|
|
_fadesHandler->deinit();
|
|
_cmdsPauseCount = 0;
|
|
_cmdsRunning60HzCount = 0;
|
|
_cmdsRunning10HzCount = 0;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int IMuseDigital::cmdsTerminate() {
|
|
return 0;
|
|
}
|
|
|
|
int IMuseDigital::cmdsPause() {
|
|
int result = 0;
|
|
|
|
if (_cmdsPauseCount == 0) {
|
|
result = wavePause();
|
|
}
|
|
|
|
if (!result) {
|
|
result = _cmdsPauseCount + 1;
|
|
}
|
|
_cmdsPauseCount++;
|
|
|
|
return result;
|
|
}
|
|
|
|
int IMuseDigital::cmdsResume() {
|
|
int result = 0;
|
|
|
|
if (_cmdsPauseCount == 1) {
|
|
result = waveResume();
|
|
}
|
|
|
|
if (_cmdsPauseCount != 0) {
|
|
_cmdsPauseCount--;
|
|
}
|
|
|
|
if (!result) {
|
|
result = _cmdsPauseCount;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
void IMuseDigital::cmdsSaveLoad(Common::Serializer &ser) {
|
|
// Serialize in this order:
|
|
// - Open files
|
|
// - Fades
|
|
// - Triggers
|
|
// - Pass the control to waveSaveLoad and then tracksSaveLoad, which will serialize:
|
|
// - Dispatches
|
|
// - Tracks (with SYNCs, if the game is COMI)
|
|
// - State and sequence info
|
|
// - Attributes
|
|
// - Full Throttle's music cue ID
|
|
|
|
_filesHandler->saveLoad(ser);
|
|
_fadesHandler->saveLoad(ser);
|
|
_triggersHandler->saveLoad(ser);
|
|
waveSaveLoad(ser);
|
|
ser.syncAsSint32LE(_curMusicState, VER(103));
|
|
ser.syncAsSint32LE(_curMusicSeq, VER(103));
|
|
ser.syncAsSint32LE(_nextSeqToPlay, VER(103));
|
|
ser.syncAsByte(_radioChatterSFX, VER(103));
|
|
ser.syncArray(_attributes, 188, Common::Serializer::Sint32LE, VER(103));
|
|
ser.syncAsSint32LE(_curMusicCue, VER(103));
|
|
}
|
|
|
|
int IMuseDigital::cmdsStartSound(int soundId, int priority) {
|
|
uint8 *src = _filesHandler->getSoundAddrData(soundId);
|
|
|
|
if (src == nullptr) {
|
|
debug(5, "IMuseDigital::cmdsStartSound(): ERROR: resource address for sound %d is NULL", soundId);
|
|
return -1;
|
|
}
|
|
|
|
// Check for the "Creative Voice File" header
|
|
if (_isEarlyDiMUSE && READ_BE_UINT32(src) == MKTAG('C', 'r', 'e', 'a'))
|
|
return waveStartSound(soundId, priority);
|
|
|
|
// Check for the "iMUS" header
|
|
if (READ_BE_UINT32(src) == MKTAG('i', 'M', 'U', 'S'))
|
|
return waveStartSound(soundId, priority);
|
|
|
|
return -1;
|
|
}
|
|
|
|
int IMuseDigital::cmdsStopSound(int soundId) {
|
|
int result = _filesHandler->getNextSound(soundId);
|
|
|
|
if (result != 2)
|
|
return -1;
|
|
|
|
return waveStopSound(soundId);
|
|
}
|
|
|
|
int IMuseDigital::cmdsStopAllSounds() {
|
|
return _triggersHandler->clearAllTriggers() | waveStopAllSounds();
|
|
}
|
|
|
|
int IMuseDigital::cmdsGetNextSound(int soundId) {
|
|
return waveGetNextSound(soundId);
|
|
}
|
|
|
|
int IMuseDigital::cmdsSetParam(int soundId, int subCmd, int value) {
|
|
int result = _filesHandler->getNextSound(soundId);
|
|
|
|
if (result != 2)
|
|
return -1;
|
|
|
|
return waveSetParam(soundId, subCmd, value);
|
|
}
|
|
|
|
int IMuseDigital::cmdsGetParam(int soundId, int subCmd) {
|
|
int result = _filesHandler->getNextSound(soundId);
|
|
|
|
if (subCmd != 0) {
|
|
if (subCmd == DIMUSE_P_TRIGS_SNDS) {
|
|
return _triggersHandler->countPendingSounds(soundId);
|
|
}
|
|
|
|
if (result == 2) {
|
|
return waveGetParam(soundId, subCmd);
|
|
}
|
|
|
|
result = (subCmd == DIMUSE_P_SND_TRACK_NUM) - 1;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
int IMuseDigital::cmdsSetHook(int soundId, int hookId) {
|
|
int result = _filesHandler->getNextSound(soundId);
|
|
|
|
if (result != 2)
|
|
return -1;
|
|
|
|
return waveSetHook(soundId, hookId);
|
|
}
|
|
|
|
int IMuseDigital::cmdsGetHook(int soundId) {
|
|
int result = _filesHandler->getNextSound(soundId);
|
|
|
|
if (result != 2)
|
|
return -1;
|
|
|
|
return waveGetHook(soundId);
|
|
}
|
|
|
|
} // End of namespace Scumm
|