2009-02-17 15:02:16 +00:00
|
|
|
/* 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 2
|
|
|
|
* 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, write to the Free Software
|
|
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
|
|
*
|
|
|
|
* $URL$
|
|
|
|
* $Id$
|
|
|
|
*
|
|
|
|
*/
|
2009-02-15 06:10:59 +00:00
|
|
|
|
2009-05-14 12:38:50 +00:00
|
|
|
#include "sci/sci.h"
|
2009-02-27 02:23:40 +00:00
|
|
|
#include "sci/engine/state.h"
|
2009-05-28 22:02:45 +00:00
|
|
|
#include "sci/sfx/iterator.h"
|
|
|
|
#include "sci/sfx/misc.h"
|
2009-02-24 05:51:55 +00:00
|
|
|
#include "sci/engine/kernel.h"
|
2009-04-25 08:50:42 +00:00
|
|
|
#include "sci/engine/vm.h" // for Object
|
2009-02-15 06:10:59 +00:00
|
|
|
|
2009-05-22 22:19:15 +00:00
|
|
|
#include "sound/mixer.h"
|
|
|
|
|
2009-02-21 10:23:36 +00:00
|
|
|
namespace Sci {
|
|
|
|
|
2009-09-17 16:49:31 +00:00
|
|
|
/* Sound status */
|
|
|
|
enum {
|
|
|
|
_K_SOUND_STATUS_STOPPED = 0,
|
|
|
|
_K_SOUND_STATUS_INITIALIZED = 1,
|
|
|
|
_K_SOUND_STATUS_PAUSED = 2,
|
|
|
|
_K_SOUND_STATUS_PLAYING = 3
|
|
|
|
};
|
|
|
|
|
2009-05-28 11:15:09 +00:00
|
|
|
enum {
|
|
|
|
_K_SCI0_SOUND_INIT_HANDLE = 0,
|
|
|
|
_K_SCI0_SOUND_PLAY_HANDLE = 1,
|
|
|
|
_K_SCI0_SOUND_NOP = 2,
|
|
|
|
_K_SCI0_SOUND_DISPOSE_HANDLE = 3,
|
|
|
|
_K_SCI0_SOUND_MUTE_SOUND = 4,
|
|
|
|
_K_SCI0_SOUND_STOP_HANDLE = 5,
|
|
|
|
_K_SCI0_SOUND_SUSPEND_HANDLE = 6,
|
|
|
|
_K_SCI0_SOUND_RESUME_HANDLE = 7,
|
|
|
|
_K_SCI0_SOUND_VOLUME = 8,
|
|
|
|
_K_SCI0_SOUND_UPDATE_VOL_PRI = 9,
|
|
|
|
_K_SCI0_SOUND_FADE_HANDLE = 10,
|
|
|
|
_K_SCI0_SOUND_GET_POLYPHONY = 11,
|
|
|
|
_K_SCI0_SOUND_PLAY_NEXT = 12
|
|
|
|
};
|
|
|
|
|
|
|
|
enum {
|
|
|
|
_K_SCI01_SOUND_MASTER_VOLME = 0, /* Set/Get */
|
|
|
|
_K_SCI01_SOUND_MUTE_SOUND = 1,
|
|
|
|
_K_SCI01_SOUND_UNUSED = 2,
|
|
|
|
_K_SCI01_SOUND_GET_POLYPHONY = 3,
|
|
|
|
_K_SCI01_SOUND_UPDATE_HANDLE = 4,
|
|
|
|
_K_SCI01_SOUND_INIT_HANDLE = 5,
|
|
|
|
_K_SCI01_SOUND_DISPOSE_HANDLE = 6,
|
|
|
|
_K_SCI01_SOUND_PLAY_HANDLE = 7,
|
|
|
|
_K_SCI01_SOUND_STOP_HANDLE = 8,
|
|
|
|
_K_SCI01_SOUND_SUSPEND_HANDLE = 9, /* or resume */
|
|
|
|
_K_SCI01_SOUND_FADE_HANDLE = 10,
|
|
|
|
_K_SCI01_SOUND_UPDATE_CUES = 11,
|
|
|
|
_K_SCI01_SOUND_MIDI_SEND = 12,
|
|
|
|
_K_SCI01_SOUND_REVERB = 13, /* Get/Set */
|
|
|
|
_K_SCI01_SOUND_HOLD = 14
|
|
|
|
};
|
|
|
|
|
|
|
|
enum {
|
|
|
|
_K_SCI1_SOUND_MASTER_VOLME = 0, /* Set/Get */
|
|
|
|
_K_SCI1_SOUND_MUTE_SOUND = 1,
|
|
|
|
_K_SCI1_SOUND_UNUSED1 = 2,
|
|
|
|
_K_SCI1_SOUND_GET_POLYPHONY = 3,
|
|
|
|
_K_SCI1_SOUND_GET_AUDIO_CAPABILITY = 4,
|
|
|
|
_K_SCI1_SOUND_SUSPEND_SOUND = 5,
|
|
|
|
_K_SCI1_SOUND_INIT_HANDLE = 6,
|
|
|
|
_K_SCI1_SOUND_DISPOSE_HANDLE = 7,
|
|
|
|
_K_SCI1_SOUND_PLAY_HANDLE = 8,
|
|
|
|
_K_SCI1_SOUND_STOP_HANDLE = 9,
|
|
|
|
_K_SCI1_SOUND_SUSPEND_HANDLE = 10, /* or resume */
|
|
|
|
_K_SCI1_SOUND_FADE_HANDLE = 11,
|
|
|
|
_K_SCI1_SOUND_HOLD_HANDLE = 12,
|
|
|
|
_K_SCI1_SOUND_UNUSED2 = 13,
|
|
|
|
_K_SCI1_SOUND_SET_HANDLE_VOLUME = 14,
|
|
|
|
_K_SCI1_SOUND_SET_HANDLE_PRIORITY = 15,
|
|
|
|
_K_SCI1_SOUND_SET_HANDLE_LOOP = 16,
|
|
|
|
_K_SCI1_SOUND_UPDATE_CUES = 17,
|
|
|
|
_K_SCI1_SOUND_MIDI_SEND = 18,
|
|
|
|
_K_SCI1_SOUND_REVERB = 19, /* Get/Set */
|
|
|
|
_K_SCI1_SOUND_UPDATE_VOL_PRI = 20
|
|
|
|
};
|
2009-02-15 06:10:59 +00:00
|
|
|
|
2009-04-26 02:00:36 +00:00
|
|
|
enum AudioCommands {
|
|
|
|
// TODO: find the difference between kSci1AudioWPlay and kSci1AudioPlay
|
2009-05-27 09:07:08 +00:00
|
|
|
kSciAudioWPlay = 1, /* Plays an audio stream */
|
|
|
|
kSciAudioPlay = 2, /* Plays an audio stream */
|
|
|
|
kSciAudioStop = 3, /* Stops an audio stream */
|
|
|
|
kSciAudioPause = 4, /* Pauses an audio stream */
|
|
|
|
kSciAudioResume = 5, /* Resumes an audio stream */
|
|
|
|
kSciAudioPosition = 6, /* Return current position in audio stream */
|
|
|
|
kSciAudioRate = 7, /* Return audio rate */
|
|
|
|
kSciAudioVolume = 8, /* Return audio volume */
|
2009-10-25 03:26:20 +00:00
|
|
|
kSciAudioLanguage = 9, /* Return audio language */
|
|
|
|
kSciAudioCD = 10 /* Plays SCI1.1 CD audio */
|
2009-05-27 09:07:08 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
enum AudioSyncCommands {
|
|
|
|
kSciAudioSyncStart = 0,
|
|
|
|
kSciAudioSyncNext = 1,
|
|
|
|
kSciAudioSyncStop = 2
|
2009-04-26 02:00:36 +00:00
|
|
|
};
|
2009-02-15 06:10:59 +00:00
|
|
|
|
|
|
|
#define SCI1_SOUND_FLAG_MAY_PAUSE 1 /* Only here for completeness; The interpreter doesn't touch this bit */
|
|
|
|
#define SCI1_SOUND_FLAG_SCRIPTED_PRI 2 /* but does touch this */
|
2009-05-30 15:40:49 +00:00
|
|
|
//#define DEBUG_SOUND // enable for sound debugging
|
2009-02-15 06:10:59 +00:00
|
|
|
|
|
|
|
#define FROBNICATE_HANDLE(reg) ((reg).segment << 16 | (reg).offset)
|
|
|
|
#define DEFROBNICATE_HANDLE(handle) (make_reg((handle >> 16) & 0xffff, handle & 0xffff))
|
|
|
|
|
|
|
|
|
2009-02-27 12:59:02 +00:00
|
|
|
static void script_set_priority(EngineState *s, reg_t obj, int priority) {
|
2009-10-04 18:38:18 +00:00
|
|
|
SegManager *segMan = s->_segMan;
|
2009-10-18 19:42:56 +00:00
|
|
|
int song_nr = GET_SEL32V(segMan, obj, number);
|
2009-09-02 12:02:37 +00:00
|
|
|
Resource *song = s->resMan->findResource(ResourceId(kResourceTypeSound, song_nr), 0);
|
2009-10-18 19:42:56 +00:00
|
|
|
int flags = GET_SEL32V(segMan, obj, flags);
|
2009-02-15 06:10:59 +00:00
|
|
|
|
2009-02-15 22:28:12 +00:00
|
|
|
if (priority == -1) {
|
2009-02-15 06:10:59 +00:00
|
|
|
if (song->data[0] == 0xf0)
|
2009-02-15 22:28:12 +00:00
|
|
|
priority = song->data[1];
|
|
|
|
else
|
2009-02-20 20:11:12 +00:00
|
|
|
warning("Attempt to unset song priority when there is no built-in value");
|
2009-02-15 06:10:59 +00:00
|
|
|
|
|
|
|
flags &= ~SCI1_SOUND_FLAG_SCRIPTED_PRI;
|
|
|
|
} else flags |= SCI1_SOUND_FLAG_SCRIPTED_PRI;
|
|
|
|
|
2009-05-28 22:48:15 +00:00
|
|
|
s->_sound.sfx_song_renice(FROBNICATE_HANDLE(obj), priority);
|
2009-10-18 19:42:56 +00:00
|
|
|
PUT_SEL32V(segMan, obj, flags, flags);
|
2009-02-15 06:10:59 +00:00
|
|
|
}
|
|
|
|
|
2009-05-12 23:32:32 +00:00
|
|
|
SongIterator *build_iterator(EngineState *s, int song_nr, SongIteratorType type, songit_id_t id) {
|
2009-09-02 12:02:37 +00:00
|
|
|
Resource *song = s->resMan->findResource(ResourceId(kResourceTypeSound, song_nr), 0);
|
2009-02-15 06:10:59 +00:00
|
|
|
|
|
|
|
if (!song)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
return songit_new(song->data, song->size, type, id);
|
|
|
|
}
|
|
|
|
|
2009-07-11 06:53:39 +00:00
|
|
|
SongIterator *build_timeriterator(EngineState *s, int delta) {
|
|
|
|
return new_timer_iterator(delta);
|
|
|
|
}
|
2009-02-15 06:10:59 +00:00
|
|
|
|
2009-02-27 12:59:02 +00:00
|
|
|
void process_sound_events(EngineState *s) { /* Get all sound events, apply their changes to the heap */
|
2009-02-15 06:10:59 +00:00
|
|
|
int result;
|
2009-06-07 17:06:32 +00:00
|
|
|
SongHandle handle;
|
2009-02-15 06:10:59 +00:00
|
|
|
int cue;
|
2009-10-04 18:38:18 +00:00
|
|
|
SegManager *segMan = s->_segMan;
|
2009-02-15 06:10:59 +00:00
|
|
|
|
2009-09-23 10:55:35 +00:00
|
|
|
if (getSciVersion() > SCI_VERSION_01)
|
2009-02-15 06:10:59 +00:00
|
|
|
return;
|
2009-08-16 19:18:19 +00:00
|
|
|
/* SCI1 and later explicitly poll for everything */
|
2009-02-15 06:10:59 +00:00
|
|
|
|
2009-05-28 22:48:15 +00:00
|
|
|
while ((result = s->_sound.sfx_poll(&handle, &cue))) {
|
2009-02-15 06:10:59 +00:00
|
|
|
reg_t obj = DEFROBNICATE_HANDLE(handle);
|
2009-10-04 18:38:18 +00:00
|
|
|
if (!s->_segMan->isObject(obj)) {
|
2009-05-21 17:18:46 +00:00
|
|
|
warning("Non-object %04x:%04x received sound signal (%d/%d)", PRINT_REG(obj), result, cue);
|
2009-02-15 06:10:59 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (result) {
|
|
|
|
|
|
|
|
case SI_LOOP:
|
2009-05-30 15:40:49 +00:00
|
|
|
debugC(2, kDebugLevelSound, "[process-sound] Song %04x:%04x looped (to %d)\n",
|
2009-02-15 22:28:12 +00:00
|
|
|
PRINT_REG(obj), cue);
|
2009-10-18 19:42:56 +00:00
|
|
|
/* PUT_SEL32V(segMan, obj, loops, GET_SEL32V(segMan, obj, loop) - 1);*/
|
|
|
|
PUT_SEL32V(segMan, obj, signal, SIGNAL_OFFSET);
|
2009-02-15 06:10:59 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case SI_RELATIVE_CUE:
|
2009-05-30 15:40:49 +00:00
|
|
|
debugC(2, kDebugLevelSound, "[process-sound] Song %04x:%04x received relative cue %d\n",
|
2009-02-15 22:28:12 +00:00
|
|
|
PRINT_REG(obj), cue);
|
2009-10-18 19:42:56 +00:00
|
|
|
PUT_SEL32V(segMan, obj, signal, cue + 0x7f);
|
2009-02-15 06:10:59 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case SI_ABSOLUTE_CUE:
|
2009-05-30 15:40:49 +00:00
|
|
|
debugC(2, kDebugLevelSound, "[process-sound] Song %04x:%04x received absolute cue %d\n",
|
2009-02-15 22:28:12 +00:00
|
|
|
PRINT_REG(obj), cue);
|
2009-10-18 19:42:56 +00:00
|
|
|
PUT_SEL32V(segMan, obj, signal, cue);
|
2009-02-15 06:10:59 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case SI_FINISHED:
|
2009-05-30 15:40:49 +00:00
|
|
|
debugC(2, kDebugLevelSound, "[process-sound] Song %04x:%04x finished\n",
|
2009-02-15 22:28:12 +00:00
|
|
|
PRINT_REG(obj));
|
2009-10-18 19:42:56 +00:00
|
|
|
PUT_SEL32V(segMan, obj, signal, SIGNAL_OFFSET);
|
|
|
|
PUT_SEL32V(segMan, obj, state, _K_SOUND_STATUS_STOPPED);
|
2009-02-15 06:10:59 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
2009-07-06 10:39:22 +00:00
|
|
|
warning("Unexpected result from sfx_poll: %d", result);
|
2009-02-15 06:10:59 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-09-02 11:33:25 +00:00
|
|
|
static reg_t kDoSoundSci0(EngineState *s, int argc, reg_t *argv) {
|
2009-10-04 18:38:18 +00:00
|
|
|
SegManager *segMan = s->_segMan;
|
2009-06-07 16:50:34 +00:00
|
|
|
reg_t obj = (argc > 1) ? argv[1] : NULL_REG;
|
2009-06-07 15:53:30 +00:00
|
|
|
uint16 command = argv[0].toUint16();
|
2009-06-07 17:06:32 +00:00
|
|
|
SongHandle handle = FROBNICATE_HANDLE(obj);
|
2009-02-15 22:28:12 +00:00
|
|
|
int number = obj.segment ?
|
2009-10-18 19:42:56 +00:00
|
|
|
GET_SEL32V(segMan, obj, number) :
|
2009-02-15 22:28:12 +00:00
|
|
|
-1; /* We were not going to use it anyway */
|
2009-02-15 06:10:59 +00:00
|
|
|
|
2009-05-30 15:40:49 +00:00
|
|
|
#ifdef DEBUG_SOUND
|
|
|
|
int i;
|
2009-02-15 06:10:59 +00:00
|
|
|
|
2009-05-30 15:40:49 +00:00
|
|
|
debugC(2, kDebugLevelSound, "Command 0x%x", command);
|
|
|
|
switch (command) {
|
|
|
|
case 0:
|
2009-07-06 10:39:22 +00:00
|
|
|
debugC(2, kDebugLevelSound, "[InitObj]");
|
2009-05-30 15:40:49 +00:00
|
|
|
break;
|
|
|
|
case 1:
|
2009-07-06 10:39:22 +00:00
|
|
|
debugC(2, kDebugLevelSound, "[Play]");
|
2009-05-30 15:40:49 +00:00
|
|
|
break;
|
|
|
|
case 2:
|
2009-07-06 10:39:22 +00:00
|
|
|
debugC(2, kDebugLevelSound, "[NOP]");
|
2009-05-30 15:40:49 +00:00
|
|
|
break;
|
|
|
|
case 3:
|
2009-07-06 10:39:22 +00:00
|
|
|
debugC(2, kDebugLevelSound, "[DisposeHandle]");
|
2009-05-30 15:40:49 +00:00
|
|
|
break;
|
|
|
|
case 4:
|
2009-07-06 10:39:22 +00:00
|
|
|
debugC(2, kDebugLevelSound, "[SetSoundOn(?)]");
|
2009-05-30 15:40:49 +00:00
|
|
|
break;
|
|
|
|
case 5:
|
2009-07-06 10:39:22 +00:00
|
|
|
debugC(2, kDebugLevelSound, "[Stop]");
|
2009-05-30 15:40:49 +00:00
|
|
|
break;
|
|
|
|
case 6:
|
2009-07-06 10:39:22 +00:00
|
|
|
debugC(2, kDebugLevelSound, "[Suspend]");
|
2009-05-30 15:40:49 +00:00
|
|
|
break;
|
|
|
|
case 7:
|
2009-07-06 10:39:22 +00:00
|
|
|
debugC(2, kDebugLevelSound, "[Resume]");
|
2009-05-30 15:40:49 +00:00
|
|
|
break;
|
|
|
|
case 8:
|
2009-07-06 10:39:22 +00:00
|
|
|
debugC(2, kDebugLevelSound, "[Get(Set?)Volume]");
|
2009-05-30 15:40:49 +00:00
|
|
|
break;
|
|
|
|
case 9:
|
2009-07-06 10:39:22 +00:00
|
|
|
debugC(2, kDebugLevelSound, "[Signal: Obj changed]");
|
2009-05-30 15:40:49 +00:00
|
|
|
break;
|
|
|
|
case 10:
|
2009-07-06 10:39:22 +00:00
|
|
|
debugC(2, kDebugLevelSound, "[Fade(?)]");
|
2009-05-30 15:40:49 +00:00
|
|
|
break;
|
|
|
|
case 11:
|
2009-07-06 10:39:22 +00:00
|
|
|
debugC(2, kDebugLevelSound, "[ChkDriver]");
|
2009-05-30 15:40:49 +00:00
|
|
|
break;
|
|
|
|
case 12:
|
2009-07-06 10:39:22 +00:00
|
|
|
debugC(2, kDebugLevelSound, "[PlayNextSong (formerly StopAll)]");
|
2009-05-30 15:40:49 +00:00
|
|
|
break;
|
|
|
|
default:
|
2009-07-06 10:39:22 +00:00
|
|
|
debugC(2, kDebugLevelSound, "[unknown]");
|
2009-05-30 15:40:49 +00:00
|
|
|
break;
|
|
|
|
}
|
2009-02-15 06:10:59 +00:00
|
|
|
|
2009-07-06 10:39:22 +00:00
|
|
|
debugC(2, kDebugLevelSound, "(");
|
2009-05-30 15:40:49 +00:00
|
|
|
for (i = 1; i < argc; i++) {
|
2009-07-06 10:39:22 +00:00
|
|
|
debugC(2, kDebugLevelSound, "%04x:%04x", PRINT_REG(argv[i]));
|
2009-05-30 15:40:49 +00:00
|
|
|
if (i + 1 < argc)
|
2009-07-06 10:39:22 +00:00
|
|
|
debugC(2, kDebugLevelSound, ", ");
|
2009-02-15 06:10:59 +00:00
|
|
|
}
|
2009-07-06 10:39:22 +00:00
|
|
|
debugC(2, kDebugLevelSound, ")\n");
|
2009-05-30 15:40:49 +00:00
|
|
|
#endif // DEBUG_SOUND
|
2009-02-15 06:10:59 +00:00
|
|
|
|
|
|
|
|
|
|
|
switch (command) {
|
|
|
|
case _K_SCI0_SOUND_INIT_HANDLE:
|
|
|
|
if (obj.segment) {
|
2009-10-18 19:42:56 +00:00
|
|
|
debugC(2, kDebugLevelSound, "Initializing song number %d\n", GET_SEL32V(segMan, obj, number));
|
2009-05-31 15:34:23 +00:00
|
|
|
s->_sound.sfx_add_song(build_iterator(s, number, SCI_SONG_ITERATOR_TYPE_SCI0,
|
|
|
|
handle), 0, handle, number);
|
|
|
|
|
2009-10-18 19:42:56 +00:00
|
|
|
PUT_SEL32V(segMan, obj, state, _K_SOUND_STATUS_INITIALIZED);
|
|
|
|
PUT_SEL32(segMan, obj, handle, obj); /* ``sound handle'': we use the object address */
|
2009-02-15 06:10:59 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case _K_SCI0_SOUND_PLAY_HANDLE:
|
|
|
|
if (obj.segment) {
|
2009-05-28 22:48:15 +00:00
|
|
|
s->_sound.sfx_song_set_status(handle, SOUND_STATUS_PLAYING);
|
2009-10-18 19:42:56 +00:00
|
|
|
s->_sound.sfx_song_set_loops(handle, GET_SEL32V(segMan, obj, loop));
|
|
|
|
PUT_SEL32V(segMan, obj, state, _K_SOUND_STATUS_PLAYING);
|
2009-02-15 06:10:59 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case _K_SCI0_SOUND_NOP:
|
|
|
|
break;
|
|
|
|
|
|
|
|
case _K_SCI0_SOUND_DISPOSE_HANDLE:
|
|
|
|
if (obj.segment) {
|
2009-05-28 22:48:15 +00:00
|
|
|
s->_sound.sfx_remove_song(handle);
|
2009-02-15 06:10:59 +00:00
|
|
|
}
|
2009-10-18 19:42:56 +00:00
|
|
|
PUT_SEL32V(segMan, obj, handle, 0x0000);
|
2009-02-15 06:10:59 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case _K_SCI0_SOUND_STOP_HANDLE:
|
|
|
|
if (obj.segment) {
|
2009-05-28 22:48:15 +00:00
|
|
|
s->_sound.sfx_song_set_status(handle, SOUND_STATUS_STOPPED);
|
2009-10-18 19:42:56 +00:00
|
|
|
PUT_SEL32V(segMan, obj, state, SOUND_STATUS_STOPPED);
|
2009-02-15 06:10:59 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case _K_SCI0_SOUND_SUSPEND_HANDLE:
|
|
|
|
if (obj.segment) {
|
2009-05-28 22:48:15 +00:00
|
|
|
s->_sound.sfx_song_set_status(handle, SOUND_STATUS_SUSPENDED);
|
2009-10-18 19:42:56 +00:00
|
|
|
PUT_SEL32V(segMan, obj, state, SOUND_STATUS_SUSPENDED);
|
2009-02-15 06:10:59 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case _K_SCI0_SOUND_RESUME_HANDLE:
|
|
|
|
if (obj.segment) {
|
2009-05-28 22:48:15 +00:00
|
|
|
s->_sound.sfx_song_set_status(handle, SOUND_STATUS_PLAYING);
|
2009-10-18 19:42:56 +00:00
|
|
|
PUT_SEL32V(segMan, obj, state, SOUND_STATUS_PLAYING);
|
2009-02-15 06:10:59 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case _K_SCI0_SOUND_MUTE_SOUND: {
|
|
|
|
/* if there's a parameter, we're setting it. Otherwise,
|
|
|
|
we're querying it. */
|
|
|
|
/*int param = UPARAM_OR_ALT(1,-1);
|
|
|
|
|
|
|
|
if (param != -1)
|
|
|
|
s->acc = s->sound_server->command(s, SOUND_COMMAND_SET_MUTE, 0, param);
|
|
|
|
else
|
|
|
|
s->acc = s->sound_server->command(s, SOUND_COMMAND_GET_MUTE, 0, 0);*/
|
|
|
|
|
|
|
|
}
|
2009-02-15 22:28:12 +00:00
|
|
|
break;
|
2009-02-15 06:10:59 +00:00
|
|
|
|
|
|
|
case _K_SCI0_SOUND_VOLUME: {
|
|
|
|
/* range from 0x0 to 0xf */
|
|
|
|
/* parameter optional. If present, set.*/
|
2009-06-07 16:50:34 +00:00
|
|
|
int vol = (argc > 1) ? argv[1].toSint16() : -1;
|
2009-02-15 06:10:59 +00:00
|
|
|
|
|
|
|
if (vol != -1)
|
2009-10-22 07:18:37 +00:00
|
|
|
s->_sound.sfx_setVolume(vol);
|
2009-02-15 06:10:59 +00:00
|
|
|
else
|
2009-10-22 07:18:37 +00:00
|
|
|
s->r_acc = make_reg(0, s->_sound.sfx_getVolume());
|
2009-02-15 06:10:59 +00:00
|
|
|
}
|
2009-02-15 22:28:12 +00:00
|
|
|
break;
|
2009-02-15 06:10:59 +00:00
|
|
|
|
|
|
|
case _K_SCI0_SOUND_UPDATE_VOL_PRI:
|
|
|
|
if (obj.segment) {
|
2009-10-18 19:42:56 +00:00
|
|
|
s->_sound.sfx_song_set_loops(handle, GET_SEL32V(segMan, obj, loop));
|
|
|
|
script_set_priority(s, obj, GET_SEL32V(segMan, obj, pri));
|
2009-02-15 06:10:59 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case _K_SCI0_SOUND_FADE_HANDLE:
|
|
|
|
/*s->sound_server->command(s, SOUND_COMMAND_FADE_HANDLE, obj, 120);*/ /* Fade out in 2 secs */
|
2009-02-15 22:28:12 +00:00
|
|
|
/* FIXME: The next couple of lines actually STOP the handle, rather
|
|
|
|
** than fading it! */
|
2009-02-15 06:10:59 +00:00
|
|
|
if (obj.segment) {
|
2009-05-28 22:48:15 +00:00
|
|
|
s->_sound.sfx_song_set_status(handle, SOUND_STATUS_STOPPED);
|
2009-10-18 19:42:56 +00:00
|
|
|
PUT_SEL32V(segMan, obj, state, SOUND_STATUS_STOPPED);
|
|
|
|
PUT_SEL32V(segMan, obj, signal, SIGNAL_OFFSET);
|
2009-02-15 06:10:59 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case _K_SCI0_SOUND_GET_POLYPHONY:
|
2009-10-13 18:51:59 +00:00
|
|
|
s->r_acc = make_reg(0, s->_sound.sfx_get_player_polyphony());
|
2009-02-15 06:10:59 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case _K_SCI0_SOUND_PLAY_NEXT:
|
2009-05-28 22:48:15 +00:00
|
|
|
/* s->_sound.sfx_all_stop();*/
|
2009-02-15 06:10:59 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
2009-02-20 20:11:12 +00:00
|
|
|
warning("Unhandled DoSound command: %x", command);
|
2009-02-15 06:10:59 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
// process_sound_events(s); /* Take care of incoming events */
|
|
|
|
|
|
|
|
return s->r_acc;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-09-02 11:33:25 +00:00
|
|
|
static reg_t kDoSoundSci1Early(EngineState *s, int argc, reg_t *argv) {
|
2009-10-04 18:38:18 +00:00
|
|
|
SegManager *segMan = s->_segMan;
|
2009-06-07 15:53:30 +00:00
|
|
|
uint16 command = argv[0].toUint16();
|
2009-06-07 16:50:34 +00:00
|
|
|
reg_t obj = (argc > 1) ? argv[1] : NULL_REG;
|
2009-06-07 17:06:32 +00:00
|
|
|
SongHandle handle = FROBNICATE_HANDLE(obj);
|
2009-02-15 22:28:12 +00:00
|
|
|
int number = obj.segment ?
|
2009-10-18 19:42:56 +00:00
|
|
|
GET_SEL32V(segMan, obj, number) :
|
2009-02-15 22:28:12 +00:00
|
|
|
-1; /* We were not going to use it anyway */
|
2009-02-15 06:10:59 +00:00
|
|
|
|
2009-05-30 15:40:49 +00:00
|
|
|
#ifdef DEBUG_SOUND
|
|
|
|
if (command != _K_SCI01_SOUND_UPDATE_CUES) {
|
2009-02-15 06:10:59 +00:00
|
|
|
int i;
|
|
|
|
|
2009-05-30 15:40:49 +00:00
|
|
|
debugC(2, kDebugLevelSound, "Command 0x%x", command);
|
2009-02-15 06:10:59 +00:00
|
|
|
switch (command) {
|
2009-02-15 22:28:12 +00:00
|
|
|
case 0:
|
2009-07-06 10:39:22 +00:00
|
|
|
debugC(2, kDebugLevelSound, "[MasterVolume]");
|
2009-02-15 22:28:12 +00:00
|
|
|
break;
|
|
|
|
case 1:
|
2009-07-06 10:39:22 +00:00
|
|
|
debugC(2, kDebugLevelSound, "[Mute]");
|
2009-02-15 22:28:12 +00:00
|
|
|
break;
|
|
|
|
case 2:
|
2009-07-06 10:39:22 +00:00
|
|
|
debugC(2, kDebugLevelSound, "[NOP(2)]");
|
2009-02-15 22:28:12 +00:00
|
|
|
break;
|
|
|
|
case 3:
|
2009-07-06 10:39:22 +00:00
|
|
|
debugC(2, kDebugLevelSound, "[GetPolyphony]");
|
2009-02-15 22:28:12 +00:00
|
|
|
break;
|
|
|
|
case 4:
|
2009-07-06 10:39:22 +00:00
|
|
|
debugC(2, kDebugLevelSound, "[Update]");
|
2009-02-15 22:28:12 +00:00
|
|
|
break;
|
|
|
|
case 5:
|
2009-07-06 10:39:22 +00:00
|
|
|
debugC(2, kDebugLevelSound, "[Init]");
|
2009-02-15 22:28:12 +00:00
|
|
|
break;
|
|
|
|
case 6:
|
2009-07-06 10:39:22 +00:00
|
|
|
debugC(2, kDebugLevelSound, "[Dispose]");
|
2009-02-15 22:28:12 +00:00
|
|
|
break;
|
|
|
|
case 7:
|
2009-07-06 10:39:22 +00:00
|
|
|
debugC(2, kDebugLevelSound, "[Play]");
|
2009-02-15 22:28:12 +00:00
|
|
|
break;
|
|
|
|
case 8:
|
2009-07-06 10:39:22 +00:00
|
|
|
debugC(2, kDebugLevelSound, "[Stop]");
|
2009-02-15 22:28:12 +00:00
|
|
|
break;
|
|
|
|
case 9:
|
2009-07-06 10:39:22 +00:00
|
|
|
debugC(2, kDebugLevelSound, "[Suspend]");
|
2009-02-15 22:28:12 +00:00
|
|
|
break;
|
|
|
|
case 10:
|
2009-07-06 10:39:22 +00:00
|
|
|
debugC(2, kDebugLevelSound, "[Fade]");
|
2009-02-15 22:28:12 +00:00
|
|
|
break;
|
|
|
|
case 11:
|
2009-07-06 10:39:22 +00:00
|
|
|
debugC(2, kDebugLevelSound, "[UpdateCues]");
|
2009-02-15 22:28:12 +00:00
|
|
|
break;
|
|
|
|
case 12:
|
2009-07-06 10:39:22 +00:00
|
|
|
debugC(2, kDebugLevelSound, "[MidiSend]");
|
2009-02-15 22:28:12 +00:00
|
|
|
break;
|
|
|
|
case 13:
|
2009-07-06 10:39:22 +00:00
|
|
|
debugC(2, kDebugLevelSound, "[Reverb]");
|
2009-02-15 22:28:12 +00:00
|
|
|
break;
|
|
|
|
case 14:
|
2009-07-06 10:39:22 +00:00
|
|
|
debugC(2, kDebugLevelSound, "[Hold]");
|
2009-02-15 22:28:12 +00:00
|
|
|
break;
|
|
|
|
default:
|
2009-07-06 10:39:22 +00:00
|
|
|
debugC(2, kDebugLevelSound, "[unknown]");
|
2009-02-15 22:28:12 +00:00
|
|
|
break;
|
2009-02-15 06:10:59 +00:00
|
|
|
}
|
|
|
|
|
2009-07-06 10:39:22 +00:00
|
|
|
debugC(2, kDebugLevelSound, "(");
|
2009-02-15 06:10:59 +00:00
|
|
|
for (i = 1; i < argc; i++) {
|
2009-07-06 10:39:22 +00:00
|
|
|
debugC(2, kDebugLevelSound, "%04x:%04x", PRINT_REG(argv[i]));
|
2009-02-15 06:10:59 +00:00
|
|
|
if (i + 1 < argc)
|
2009-07-06 10:39:22 +00:00
|
|
|
debugC(2, kDebugLevelSound, ", ");
|
2009-02-15 06:10:59 +00:00
|
|
|
}
|
2009-07-06 10:39:22 +00:00
|
|
|
debugC(2, kDebugLevelSound, ")\n");
|
2009-02-15 06:10:59 +00:00
|
|
|
}
|
2009-05-30 15:40:49 +00:00
|
|
|
#endif
|
2009-02-15 06:10:59 +00:00
|
|
|
|
2009-02-15 22:28:12 +00:00
|
|
|
switch (command) {
|
|
|
|
case _K_SCI01_SOUND_MASTER_VOLME : {
|
2009-06-07 16:50:34 +00:00
|
|
|
int vol = (argc > 1) ? argv[1].toSint16() : -1;
|
2009-02-15 06:10:59 +00:00
|
|
|
|
|
|
|
if (vol != -1)
|
2009-10-22 07:18:37 +00:00
|
|
|
s->_sound.sfx_setVolume(vol);
|
2009-02-15 06:10:59 +00:00
|
|
|
else
|
2009-10-22 07:18:37 +00:00
|
|
|
s->r_acc = make_reg(0, s->_sound.sfx_getVolume());
|
2009-02-15 06:10:59 +00:00
|
|
|
break;
|
|
|
|
}
|
2009-02-15 22:28:12 +00:00
|
|
|
case _K_SCI01_SOUND_MUTE_SOUND : {
|
2009-02-15 06:10:59 +00:00
|
|
|
/* if there's a parameter, we're setting it. Otherwise,
|
|
|
|
we're querying it. */
|
|
|
|
/*int param = UPARAM_OR_ALT(1,-1);
|
|
|
|
|
|
|
|
if (param != -1)
|
|
|
|
s->acc = s->sound_server->command(s, SOUND_COMMAND_SET_MUTE, 0, param);
|
|
|
|
else
|
|
|
|
s->acc = s->sound_server->command(s, SOUND_COMMAND_GET_MUTE, 0, 0);*/
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
2009-02-15 22:28:12 +00:00
|
|
|
case _K_SCI01_SOUND_UNUSED : {
|
2009-02-15 06:10:59 +00:00
|
|
|
break;
|
|
|
|
}
|
2009-02-15 22:28:12 +00:00
|
|
|
case _K_SCI01_SOUND_GET_POLYPHONY : {
|
2009-10-13 18:51:59 +00:00
|
|
|
s->r_acc = make_reg(0, s->_sound.sfx_get_player_polyphony());
|
2009-02-15 06:10:59 +00:00
|
|
|
break;
|
|
|
|
}
|
2009-02-15 22:28:12 +00:00
|
|
|
case _K_SCI01_SOUND_PLAY_HANDLE : {
|
2009-10-18 19:42:56 +00:00
|
|
|
int looping = GET_SEL32V(segMan, obj, loop);
|
|
|
|
//int vol = GET_SEL32V(segMan, obj, vol);
|
|
|
|
int pri = GET_SEL32V(segMan, obj, pri);
|
2009-06-07 15:53:30 +00:00
|
|
|
RESTORE_BEHAVIOR rb = (RESTORE_BEHAVIOR) argv[2].toUint16(); /* Too lazy to look up a default value for this */
|
2009-02-15 06:10:59 +00:00
|
|
|
|
|
|
|
if (obj.segment) {
|
2009-05-28 22:48:15 +00:00
|
|
|
s->_sound.sfx_song_set_status(handle, SOUND_STATUS_PLAYING);
|
|
|
|
s->_sound.sfx_song_set_loops(handle, looping);
|
|
|
|
s->_sound.sfx_song_renice(handle, pri);
|
2009-06-07 17:06:51 +00:00
|
|
|
s->_sound._songlib.setSongRestoreBehavior(handle, rb);
|
2009-10-18 19:42:56 +00:00
|
|
|
PUT_SEL32V(segMan, obj, signal, 0);
|
2009-02-15 06:10:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
2009-02-15 22:28:12 +00:00
|
|
|
case _K_SCI01_SOUND_INIT_HANDLE : {
|
2009-10-18 19:42:56 +00:00
|
|
|
//int looping = GET_SEL32V(segMan, obj, loop);
|
|
|
|
//int vol = GET_SEL32V(segMan, obj, vol);
|
|
|
|
//int pri = GET_SEL32V(segMan, obj, pri);
|
2009-02-15 06:10:59 +00:00
|
|
|
|
2009-09-02 12:02:37 +00:00
|
|
|
if (obj.segment && (s->resMan->testResource(ResourceId(kResourceTypeSound, number)))) {
|
2009-07-06 10:39:22 +00:00
|
|
|
debugC(2, kDebugLevelSound, "Initializing song number %d\n", number);
|
2009-05-31 15:34:23 +00:00
|
|
|
s->_sound.sfx_add_song(build_iterator(s, number, SCI_SONG_ITERATOR_TYPE_SCI1,
|
|
|
|
handle), 0, handle, number);
|
2009-10-18 19:42:56 +00:00
|
|
|
PUT_SEL32(segMan, obj, nodePtr, obj);
|
|
|
|
PUT_SEL32(segMan, obj, handle, obj);
|
2009-02-15 06:10:59 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
2009-02-15 22:28:12 +00:00
|
|
|
case _K_SCI01_SOUND_DISPOSE_HANDLE : {
|
2009-02-15 06:10:59 +00:00
|
|
|
if (obj.segment) {
|
2009-05-28 22:48:15 +00:00
|
|
|
s->_sound.sfx_song_set_status(handle, SOUND_STATUS_STOPPED);
|
|
|
|
s->_sound.sfx_remove_song(handle);
|
2009-02-15 06:10:59 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
2009-02-15 22:28:12 +00:00
|
|
|
case _K_SCI01_SOUND_UPDATE_HANDLE : {
|
2009-02-15 06:10:59 +00:00
|
|
|
/* FIXME: Get these from the sound server */
|
|
|
|
int signal = 0;
|
|
|
|
int min = 0;
|
|
|
|
int sec = 0;
|
|
|
|
int frame = 0;
|
|
|
|
|
|
|
|
/* FIXME: Update the sound server state with 'vol' */
|
2009-10-18 19:42:56 +00:00
|
|
|
int looping = GET_SEL32V(segMan, obj, loop);
|
|
|
|
//int vol = GET_SEL32V(segMan, obj, vol);
|
|
|
|
int pri = GET_SEL32V(segMan, obj, pri);
|
2009-02-15 06:10:59 +00:00
|
|
|
|
2009-05-28 22:48:15 +00:00
|
|
|
s->_sound.sfx_song_set_loops(handle, looping);
|
|
|
|
s->_sound.sfx_song_renice(handle, pri);
|
2009-02-15 06:10:59 +00:00
|
|
|
|
2009-05-30 17:30:54 +00:00
|
|
|
debugC(2, kDebugLevelSound, "[sound01-update-handle] -- CUE %04x:%04x", PRINT_REG(obj));
|
2009-02-15 06:10:59 +00:00
|
|
|
|
2009-10-18 19:42:56 +00:00
|
|
|
PUT_SEL32V(segMan, obj, signal, signal);
|
|
|
|
PUT_SEL32V(segMan, obj, min, min);
|
|
|
|
PUT_SEL32V(segMan, obj, sec, sec);
|
|
|
|
PUT_SEL32V(segMan, obj, frame, frame);
|
2009-02-15 06:10:59 +00:00
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
2009-02-15 22:28:12 +00:00
|
|
|
case _K_SCI01_SOUND_STOP_HANDLE : {
|
2009-10-18 19:42:56 +00:00
|
|
|
PUT_SEL32V(segMan, obj, signal, SIGNAL_OFFSET);
|
2009-02-15 06:10:59 +00:00
|
|
|
if (obj.segment) {
|
2009-05-28 22:48:15 +00:00
|
|
|
s->_sound.sfx_song_set_status(handle, SOUND_STATUS_STOPPED);
|
2009-02-15 06:10:59 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
2009-02-15 22:28:12 +00:00
|
|
|
case _K_SCI01_SOUND_SUSPEND_HANDLE : {
|
2009-06-07 15:53:30 +00:00
|
|
|
int state = argv[2].toUint16();
|
2009-02-15 22:28:12 +00:00
|
|
|
int setstate = (state) ?
|
|
|
|
SOUND_STATUS_SUSPENDED : SOUND_STATUS_PLAYING;
|
2009-02-15 06:10:59 +00:00
|
|
|
|
|
|
|
if (obj.segment) {
|
2009-05-28 22:48:15 +00:00
|
|
|
s->_sound.sfx_song_set_status(handle, setstate);
|
2009-02-15 06:10:59 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
2009-02-15 22:28:12 +00:00
|
|
|
case _K_SCI01_SOUND_FADE_HANDLE : {
|
2009-02-15 06:10:59 +00:00
|
|
|
/* There are four parameters that control the fade here.
|
|
|
|
* TODO: Figure out the exact semantics */
|
|
|
|
|
2009-02-15 22:28:12 +00:00
|
|
|
/* FIXME: The next couple of lines actually STOP the song right away */
|
2009-10-18 19:42:56 +00:00
|
|
|
PUT_SEL32V(segMan, obj, signal, SIGNAL_OFFSET);
|
2009-02-15 06:10:59 +00:00
|
|
|
if (obj.segment) {
|
2009-05-28 22:48:15 +00:00
|
|
|
s->_sound.sfx_song_set_status(handle, SOUND_STATUS_STOPPED);
|
2009-02-15 06:10:59 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
2009-02-15 22:28:12 +00:00
|
|
|
case _K_SCI01_SOUND_UPDATE_CUES : {
|
2009-02-15 06:10:59 +00:00
|
|
|
int signal = 0;
|
|
|
|
int min = 0;
|
|
|
|
int sec = 0;
|
|
|
|
int frame = 0;
|
|
|
|
int result = SI_LOOP; /* small hack */
|
2009-02-15 14:26:33 +00:00
|
|
|
int cue = 0;
|
2009-02-15 06:10:59 +00:00
|
|
|
|
|
|
|
while (result == SI_LOOP)
|
2009-05-28 22:48:15 +00:00
|
|
|
result = s->_sound.sfx_poll_specific(handle, &cue);
|
2009-02-15 06:10:59 +00:00
|
|
|
|
|
|
|
switch (result) {
|
|
|
|
|
|
|
|
case SI_ABSOLUTE_CUE:
|
|
|
|
signal = cue;
|
2009-05-30 15:40:49 +00:00
|
|
|
debugC(2, kDebugLevelSound, "--- [CUE] %04x:%04x Absolute Cue: %d\n",
|
2009-02-15 22:28:12 +00:00
|
|
|
PRINT_REG(obj), signal);
|
2009-02-15 06:10:59 +00:00
|
|
|
|
2009-10-18 19:42:56 +00:00
|
|
|
PUT_SEL32V(segMan, obj, signal, signal);
|
2009-02-15 06:10:59 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case SI_RELATIVE_CUE:
|
|
|
|
signal = cue;
|
2009-05-30 15:40:49 +00:00
|
|
|
debugC(2, kDebugLevelSound, "--- [CUE] %04x:%04x Relative Cue: %d\n",
|
2009-02-15 22:28:12 +00:00
|
|
|
PRINT_REG(obj), cue);
|
2009-02-15 06:10:59 +00:00
|
|
|
|
|
|
|
/* FIXME to match commented-out semantics
|
|
|
|
* below, with proper storage of dataInc and
|
|
|
|
* signal in the iterator code. */
|
2009-10-18 19:42:56 +00:00
|
|
|
PUT_SEL32V(segMan, obj, dataInc, signal);
|
|
|
|
PUT_SEL32V(segMan, obj, signal, signal);
|
2009-02-15 06:10:59 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case SI_FINISHED:
|
2009-05-30 15:40:49 +00:00
|
|
|
debugC(2, kDebugLevelSound, "--- [FINISHED] %04x:%04x\n", PRINT_REG(obj));
|
2009-10-18 19:42:56 +00:00
|
|
|
PUT_SEL32V(segMan, obj, signal, SIGNAL_OFFSET);
|
2009-02-15 06:10:59 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case SI_LOOP:
|
|
|
|
break; /* Doesn't happen */
|
|
|
|
}
|
|
|
|
|
2009-02-22 13:11:43 +00:00
|
|
|
/* switch (signal) */
|
|
|
|
/* { */
|
|
|
|
/* case 0x00: */
|
2009-10-18 19:42:56 +00:00
|
|
|
/* if (dataInc!=GET_SEL32V(segMan, obj, dataInc)) */
|
2009-02-22 13:11:43 +00:00
|
|
|
/* { */
|
2009-10-18 19:42:56 +00:00
|
|
|
/* PUT_SEL32V(segMan, obj, dataInc, dataInc); */
|
|
|
|
/* PUT_SEL32V(segMan, obj, signal, dataInc+0x7f); */
|
2009-02-22 13:11:43 +00:00
|
|
|
/* } else */
|
|
|
|
/* { */
|
2009-10-18 19:42:56 +00:00
|
|
|
/* PUT_SEL32V(segMan, obj, signal, signal); */
|
2009-02-22 13:11:43 +00:00
|
|
|
/* } */
|
|
|
|
/* break; */
|
|
|
|
/* case 0xFF: /\* May be unnecessary *\/ */
|
2009-05-28 22:48:15 +00:00
|
|
|
/* s->_sound.sfx_song_set_status(*/
|
2009-02-22 13:11:43 +00:00
|
|
|
/* handle, SOUND_STATUS_STOPPED); */
|
|
|
|
/* break; */
|
|
|
|
/* default : */
|
2009-10-18 19:42:56 +00:00
|
|
|
/* if (dataInc!=GET_SEL32V(segMan, obj, dataInc)) */
|
2009-02-22 13:11:43 +00:00
|
|
|
/* { */
|
2009-10-18 19:42:56 +00:00
|
|
|
/* PUT_SEL32V(segMan, obj, dataInc, dataInc); */
|
|
|
|
/* PUT_SEL32V(segMan, obj, signal, dataInc+0x7f); */
|
2009-02-22 13:11:43 +00:00
|
|
|
/* } else */
|
|
|
|
/* { */
|
2009-10-18 19:42:56 +00:00
|
|
|
/* PUT_SEL32V(segMan, obj, signal, signal); */
|
2009-02-22 13:11:43 +00:00
|
|
|
/* } */
|
|
|
|
/* break; */
|
|
|
|
/* } */
|
2009-02-15 06:10:59 +00:00
|
|
|
|
2009-10-18 19:42:56 +00:00
|
|
|
PUT_SEL32V(segMan, obj, min, min);
|
|
|
|
PUT_SEL32V(segMan, obj, sec, sec);
|
|
|
|
PUT_SEL32V(segMan, obj, frame, frame);
|
2009-02-15 06:10:59 +00:00
|
|
|
break;
|
|
|
|
}
|
2009-02-15 22:28:12 +00:00
|
|
|
case _K_SCI01_SOUND_MIDI_SEND : {
|
2009-06-07 15:53:30 +00:00
|
|
|
int channel = argv[2].toSint16();
|
|
|
|
int midiCmd = argv[3].toUint16() == 0xff ?
|
2009-02-15 22:28:12 +00:00
|
|
|
0xe0 : /* Pitch wheel */
|
2009-06-07 15:53:30 +00:00
|
|
|
0xb0; /* argv[3].toUint16() is actually a controller number */
|
|
|
|
int controller = argv[3].toUint16();
|
|
|
|
int param = argv[4].toUint16();
|
2009-02-15 06:10:59 +00:00
|
|
|
|
2009-05-28 22:48:15 +00:00
|
|
|
s->_sound.sfx_send_midi(handle,
|
2009-02-15 22:28:12 +00:00
|
|
|
channel, midiCmd, controller, param);
|
2009-02-15 06:10:59 +00:00
|
|
|
break;
|
|
|
|
}
|
2009-02-15 22:28:12 +00:00
|
|
|
case _K_SCI01_SOUND_REVERB : {
|
2009-02-15 06:10:59 +00:00
|
|
|
break;
|
|
|
|
}
|
2009-02-15 22:28:12 +00:00
|
|
|
case _K_SCI01_SOUND_HOLD : {
|
2009-06-07 15:53:30 +00:00
|
|
|
//int flag = argv[2].toSint16();
|
2009-02-15 06:10:59 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return s->r_acc;
|
|
|
|
}
|
|
|
|
|
2009-09-02 11:33:25 +00:00
|
|
|
static reg_t kDoSoundSci1Late(EngineState *s, int argc, reg_t *argv) {
|
2009-10-04 18:38:18 +00:00
|
|
|
SegManager *segMan = s->_segMan;
|
2009-06-07 15:53:30 +00:00
|
|
|
uint16 command = argv[0].toUint16();
|
2009-06-07 16:50:34 +00:00
|
|
|
reg_t obj = (argc > 1) ? argv[1] : NULL_REG;
|
2009-06-07 17:06:32 +00:00
|
|
|
SongHandle handle = FROBNICATE_HANDLE(obj);
|
2009-02-15 22:28:12 +00:00
|
|
|
int number = obj.segment ?
|
2009-10-18 19:42:56 +00:00
|
|
|
GET_SEL32V(segMan, obj, number) :
|
2009-02-15 22:28:12 +00:00
|
|
|
-1; /* We were not going to use it anyway */
|
2009-02-15 06:10:59 +00:00
|
|
|
|
2009-05-30 15:40:49 +00:00
|
|
|
#ifdef DEBUG_SOUND
|
|
|
|
if (command != _K_SCI1_SOUND_UPDATE_CUES) {
|
2009-02-15 06:10:59 +00:00
|
|
|
int i;
|
|
|
|
|
2009-05-30 15:40:49 +00:00
|
|
|
debugC(2, kDebugLevelSound, "Command 0x%x", command);
|
2009-02-15 06:10:59 +00:00
|
|
|
switch (command) {
|
2009-02-15 22:28:12 +00:00
|
|
|
case 0:
|
2009-07-06 10:39:22 +00:00
|
|
|
debugC(2, kDebugLevelSound, "[MasterVolume]");
|
2009-02-15 22:28:12 +00:00
|
|
|
break;
|
|
|
|
case 1:
|
2009-07-06 10:39:22 +00:00
|
|
|
debugC(2, kDebugLevelSound, "[Mute]");
|
2009-02-15 22:28:12 +00:00
|
|
|
break;
|
|
|
|
case 2:
|
2009-07-06 10:39:22 +00:00
|
|
|
debugC(2, kDebugLevelSound, "[NOP(2)]");
|
2009-02-15 22:28:12 +00:00
|
|
|
break;
|
|
|
|
case 3:
|
2009-07-06 10:39:22 +00:00
|
|
|
debugC(2, kDebugLevelSound, "[GetPolyphony]");
|
2009-02-15 22:28:12 +00:00
|
|
|
break;
|
|
|
|
case 4:
|
2009-07-06 10:39:22 +00:00
|
|
|
debugC(2, kDebugLevelSound, "[GetAudioCapability]");
|
2009-02-15 22:28:12 +00:00
|
|
|
break;
|
|
|
|
case 5:
|
2009-07-06 10:39:22 +00:00
|
|
|
debugC(2, kDebugLevelSound, "[GlobalSuspend]");
|
2009-02-15 22:28:12 +00:00
|
|
|
break;
|
|
|
|
case 6:
|
2009-07-06 10:39:22 +00:00
|
|
|
debugC(2, kDebugLevelSound, "[Init]");
|
2009-02-15 22:28:12 +00:00
|
|
|
break;
|
|
|
|
case 7:
|
2009-07-06 10:39:22 +00:00
|
|
|
debugC(2, kDebugLevelSound, "[Dispose]");
|
2009-02-15 22:28:12 +00:00
|
|
|
break;
|
|
|
|
case 8:
|
2009-07-06 10:39:22 +00:00
|
|
|
debugC(2, kDebugLevelSound, "[Play]");
|
2009-02-15 22:28:12 +00:00
|
|
|
break;
|
|
|
|
case 9:
|
2009-07-06 10:39:22 +00:00
|
|
|
debugC(2, kDebugLevelSound, "[Stop]");
|
2009-02-15 22:28:12 +00:00
|
|
|
break;
|
|
|
|
case 10:
|
2009-07-06 10:39:22 +00:00
|
|
|
debugC(2, kDebugLevelSound, "[SuspendHandle]");
|
2009-02-15 22:28:12 +00:00
|
|
|
break;
|
|
|
|
case 11:
|
2009-07-06 10:39:22 +00:00
|
|
|
debugC(2, kDebugLevelSound, "[Fade]");
|
2009-02-15 22:28:12 +00:00
|
|
|
break;
|
|
|
|
case 12:
|
2009-07-06 10:39:22 +00:00
|
|
|
debugC(2, kDebugLevelSound, "[Hold]");
|
2009-02-15 22:28:12 +00:00
|
|
|
break;
|
|
|
|
case 13:
|
2009-07-06 10:39:22 +00:00
|
|
|
debugC(2, kDebugLevelSound, "[Unused(13)]");
|
2009-02-15 22:28:12 +00:00
|
|
|
break;
|
|
|
|
case 14:
|
2009-07-06 10:39:22 +00:00
|
|
|
debugC(2, kDebugLevelSound, "[SetVolume]");
|
2009-02-15 22:28:12 +00:00
|
|
|
break;
|
|
|
|
case 15:
|
2009-07-06 10:39:22 +00:00
|
|
|
debugC(2, kDebugLevelSound, "[SetPriority]");
|
2009-02-15 22:28:12 +00:00
|
|
|
break;
|
|
|
|
case 16:
|
2009-07-06 10:39:22 +00:00
|
|
|
debugC(2, kDebugLevelSound, "[SetLoop]");
|
2009-02-15 22:28:12 +00:00
|
|
|
break;
|
|
|
|
case 17:
|
2009-07-06 10:39:22 +00:00
|
|
|
debugC(2, kDebugLevelSound, "[UpdateCues]");
|
2009-02-15 22:28:12 +00:00
|
|
|
break;
|
|
|
|
case 18:
|
2009-07-06 10:39:22 +00:00
|
|
|
debugC(2, kDebugLevelSound, "[MidiSend]");
|
2009-02-15 22:28:12 +00:00
|
|
|
break;
|
|
|
|
case 19:
|
2009-07-06 10:39:22 +00:00
|
|
|
debugC(2, kDebugLevelSound, "[Reverb]");
|
2009-02-15 22:28:12 +00:00
|
|
|
break;
|
|
|
|
case 20:
|
2009-07-06 10:39:22 +00:00
|
|
|
debugC(2, kDebugLevelSound, "[UpdateVolPri]");
|
2009-02-15 22:28:12 +00:00
|
|
|
break;
|
|
|
|
default:
|
2009-07-06 10:39:22 +00:00
|
|
|
debugC(2, kDebugLevelSound, "[unknown]");
|
2009-02-15 22:28:12 +00:00
|
|
|
break;
|
2009-02-15 06:10:59 +00:00
|
|
|
}
|
|
|
|
|
2009-07-06 10:39:22 +00:00
|
|
|
debugC(2, kDebugLevelSound, "(");
|
2009-02-15 06:10:59 +00:00
|
|
|
for (i = 1; i < argc; i++) {
|
2009-07-06 10:39:22 +00:00
|
|
|
debugC(2, kDebugLevelSound, "%04x:%04x", PRINT_REG(argv[i]));
|
2009-02-15 06:10:59 +00:00
|
|
|
if (i + 1 < argc)
|
2009-07-06 10:39:22 +00:00
|
|
|
debugC(2, kDebugLevelSound, ", ");
|
2009-02-15 06:10:59 +00:00
|
|
|
}
|
2009-07-06 10:39:22 +00:00
|
|
|
debugC(2, kDebugLevelSound, ")\n");
|
2009-02-15 06:10:59 +00:00
|
|
|
}
|
2009-05-30 15:40:49 +00:00
|
|
|
#endif // DEBUG_SOUND
|
2009-02-15 06:10:59 +00:00
|
|
|
|
2009-02-15 22:28:12 +00:00
|
|
|
switch (command) {
|
|
|
|
case _K_SCI1_SOUND_MASTER_VOLME : {
|
2009-10-22 07:18:37 +00:00
|
|
|
int vol = (argc > 1 ? argv[1].offset : -1);
|
2009-02-15 06:10:59 +00:00
|
|
|
|
2009-10-22 07:18:37 +00:00
|
|
|
if (vol != -1)
|
|
|
|
s->_sound.sfx_setVolume(vol);
|
|
|
|
|
|
|
|
s->r_acc = make_reg(0, s->_sound.sfx_getVolume());
|
|
|
|
break;
|
2009-02-15 06:10:59 +00:00
|
|
|
}
|
2009-02-15 22:28:12 +00:00
|
|
|
case _K_SCI1_SOUND_MUTE_SOUND : {
|
2009-02-15 06:10:59 +00:00
|
|
|
/* if there's a parameter, we're setting it. Otherwise,
|
|
|
|
we're querying it. */
|
|
|
|
/*int param = UPARAM_OR_ALT(1,-1);
|
|
|
|
|
|
|
|
if (param != -1)
|
|
|
|
s->acc = s->sound_server->command(s, SOUND_COMMAND_SET_MUTE, 0, param);
|
|
|
|
else
|
|
|
|
s->acc = s->sound_server->command(s, SOUND_COMMAND_GET_MUTE, 0, 0);
|
|
|
|
break;*/
|
|
|
|
}
|
2009-02-15 22:28:12 +00:00
|
|
|
case _K_SCI1_SOUND_UNUSED1 : {
|
2009-02-15 06:10:59 +00:00
|
|
|
break;
|
|
|
|
}
|
2009-02-15 22:28:12 +00:00
|
|
|
case _K_SCI1_SOUND_GET_POLYPHONY : {
|
2009-02-15 06:10:59 +00:00
|
|
|
/*s->acc = s->sound_server->command(s, SOUND_COMMAND_TEST, 0, 0);*/
|
|
|
|
break;
|
|
|
|
}
|
2009-02-15 22:28:12 +00:00
|
|
|
case _K_SCI1_SOUND_GET_AUDIO_CAPABILITY : {
|
2009-05-26 00:03:41 +00:00
|
|
|
// Tests for digital audio support
|
|
|
|
return make_reg(0, 1);
|
2009-02-15 06:10:59 +00:00
|
|
|
}
|
2009-02-15 22:28:12 +00:00
|
|
|
case _K_SCI1_SOUND_PLAY_HANDLE : {
|
2009-10-18 19:42:56 +00:00
|
|
|
int looping = GET_SEL32V(segMan, obj, loop);
|
|
|
|
//int vol = GET_SEL32V(segMan, obj, vol);
|
|
|
|
int pri = GET_SEL32V(segMan, obj, pri);
|
2009-07-11 06:53:39 +00:00
|
|
|
int sampleLen = 0;
|
2009-06-07 17:06:51 +00:00
|
|
|
Song *song = s->_sound._songlib.findSong(handle);
|
2009-02-15 06:10:59 +00:00
|
|
|
|
2009-10-18 19:42:56 +00:00
|
|
|
if (GET_SEL32V(segMan, obj, nodePtr) && (song && number != song->_resourceNum)) {
|
2009-05-28 22:48:15 +00:00
|
|
|
s->_sound.sfx_song_set_status(handle, SOUND_STATUS_STOPPED);
|
|
|
|
s->_sound.sfx_remove_song(handle);
|
2009-10-18 19:42:56 +00:00
|
|
|
PUT_SEL32(segMan, obj, nodePtr, NULL_REG);
|
2009-02-15 06:10:59 +00:00
|
|
|
}
|
|
|
|
|
2009-10-18 19:42:56 +00:00
|
|
|
if (!GET_SEL32V(segMan, obj, nodePtr) && obj.segment) {
|
2009-07-06 15:50:44 +00:00
|
|
|
// In SCI1.1 games, sound effects are started from here. If we can find
|
|
|
|
// a relevant audio resource, play it, otherwise switch to synthesized
|
|
|
|
// effects. If the resource exists, play it using map 65535 (sound
|
|
|
|
// effects map)
|
2009-09-02 12:02:37 +00:00
|
|
|
if (s->resMan->testResource(ResourceId(kResourceTypeAudio, number)) &&
|
2009-09-23 10:55:35 +00:00
|
|
|
getSciVersion() >= SCI_VERSION_1_1) {
|
2009-07-06 15:50:44 +00:00
|
|
|
// Found a relevant audio resource, play it
|
2009-11-04 09:36:18 +00:00
|
|
|
s->_audio->stopAudio();
|
2009-09-06 12:59:34 +00:00
|
|
|
warning("Initializing audio resource instead of requested sound resource %d", number);
|
2009-11-04 09:36:18 +00:00
|
|
|
sampleLen = s->_audio->startAudio(65535, number);
|
2009-07-11 06:53:39 +00:00
|
|
|
// Also create iterator, that will fire SI_FINISHED event, when the sound is done playing
|
|
|
|
s->_sound.sfx_add_song(build_timeriterator(s, sampleLen), 0, handle, number);
|
2009-07-06 15:50:44 +00:00
|
|
|
} else {
|
2009-09-02 12:02:37 +00:00
|
|
|
if (!s->resMan->testResource(ResourceId(kResourceTypeSound, number))) {
|
2009-07-06 12:44:55 +00:00
|
|
|
warning("Could not open song number %d", number);
|
|
|
|
// Send a "stop handle" event so that the engine won't wait forever here
|
|
|
|
s->_sound.sfx_song_set_status(handle, SOUND_STATUS_STOPPED);
|
2009-10-18 19:42:56 +00:00
|
|
|
PUT_SEL32V(segMan, obj, signal, SIGNAL_OFFSET);
|
2009-07-06 15:50:44 +00:00
|
|
|
return s->r_acc;
|
2009-07-06 12:44:55 +00:00
|
|
|
}
|
2009-07-11 06:53:39 +00:00
|
|
|
debugC(2, kDebugLevelSound, "Initializing song number %d\n", number);
|
|
|
|
s->_sound.sfx_add_song(build_iterator(s, number, SCI_SONG_ITERATOR_TYPE_SCI1,
|
|
|
|
handle), 0, handle, number);
|
2009-02-15 06:10:59 +00:00
|
|
|
}
|
|
|
|
|
2009-10-18 19:42:56 +00:00
|
|
|
PUT_SEL32(segMan, obj, nodePtr, obj);
|
|
|
|
PUT_SEL32(segMan, obj, handle, obj);
|
2009-02-15 06:10:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (obj.segment) {
|
2009-05-28 22:48:15 +00:00
|
|
|
s->_sound.sfx_song_set_status(handle, SOUND_STATUS_PLAYING);
|
|
|
|
s->_sound.sfx_song_set_loops(handle, looping);
|
|
|
|
s->_sound.sfx_song_renice(handle, pri);
|
2009-10-18 19:42:56 +00:00
|
|
|
PUT_SEL32V(segMan, obj, signal, 0);
|
2009-02-15 06:10:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
2009-02-15 22:28:12 +00:00
|
|
|
case _K_SCI1_SOUND_INIT_HANDLE : {
|
2009-10-18 19:42:56 +00:00
|
|
|
//int looping = GET_SEL32V(segMan, obj, loop);
|
|
|
|
//int vol = GET_SEL32V(segMan, obj, vol);
|
|
|
|
//int pri = GET_SEL32V(segMan, obj, pri);
|
2009-02-15 06:10:59 +00:00
|
|
|
|
2009-10-18 19:42:56 +00:00
|
|
|
if (GET_SEL32V(segMan, obj, nodePtr)) {
|
2009-05-28 22:48:15 +00:00
|
|
|
s->_sound.sfx_song_set_status(handle, SOUND_STATUS_STOPPED);
|
|
|
|
s->_sound.sfx_remove_song(handle);
|
2009-02-15 06:10:59 +00:00
|
|
|
}
|
|
|
|
|
2009-09-02 12:02:37 +00:00
|
|
|
if (obj.segment && (s->resMan->testResource(ResourceId(kResourceTypeSound, number)))) {
|
2009-07-06 10:39:22 +00:00
|
|
|
debugC(2, kDebugLevelSound, "Initializing song number %d\n", number);
|
2009-05-31 15:34:23 +00:00
|
|
|
s->_sound.sfx_add_song(build_iterator(s, number, SCI_SONG_ITERATOR_TYPE_SCI1,
|
|
|
|
handle), 0, handle, number);
|
2009-10-18 19:42:56 +00:00
|
|
|
PUT_SEL32(segMan, obj, nodePtr, obj);
|
|
|
|
PUT_SEL32(segMan, obj, handle, obj);
|
2009-02-15 06:10:59 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
2009-02-15 22:28:12 +00:00
|
|
|
case _K_SCI1_SOUND_DISPOSE_HANDLE : {
|
2009-02-15 06:10:59 +00:00
|
|
|
if (obj.segment) {
|
2009-05-28 22:48:15 +00:00
|
|
|
s->_sound.sfx_song_set_status(handle, SOUND_STATUS_STOPPED);
|
|
|
|
s->_sound.sfx_remove_song(handle);
|
2009-02-15 06:10:59 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
2009-02-15 22:28:12 +00:00
|
|
|
case _K_SCI1_SOUND_STOP_HANDLE : {
|
2009-10-18 19:42:56 +00:00
|
|
|
PUT_SEL32V(segMan, obj, signal, SIGNAL_OFFSET);
|
2009-02-15 06:10:59 +00:00
|
|
|
if (obj.segment) {
|
2009-05-28 22:48:15 +00:00
|
|
|
s->_sound.sfx_song_set_status(handle, SOUND_STATUS_STOPPED);
|
2009-02-15 06:10:59 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
2009-02-15 22:28:12 +00:00
|
|
|
case _K_SCI1_SOUND_SUSPEND_HANDLE : {
|
2009-02-15 06:10:59 +00:00
|
|
|
break;
|
|
|
|
}
|
2009-02-15 22:28:12 +00:00
|
|
|
case _K_SCI1_SOUND_FADE_HANDLE : {
|
2009-02-15 06:10:59 +00:00
|
|
|
fade_params_t fade;
|
|
|
|
if (obj.segment) {
|
2009-06-07 15:53:30 +00:00
|
|
|
fade.final_volume = argv[2].toUint16();
|
|
|
|
fade.ticks_per_step = argv[3].toUint16();
|
|
|
|
fade.step_size = argv[4].toUint16();
|
|
|
|
fade.action = argv[5].toUint16() ?
|
2009-02-15 22:28:12 +00:00
|
|
|
FADE_ACTION_FADE_AND_STOP :
|
|
|
|
FADE_ACTION_FADE_AND_CONT;
|
2009-02-15 06:10:59 +00:00
|
|
|
|
2009-05-28 22:48:15 +00:00
|
|
|
s->_sound.sfx_song_set_fade(handle, &fade);
|
2009-02-15 06:10:59 +00:00
|
|
|
|
|
|
|
/* FIXME: The next couple of lines actually STOP the handle, rather
|
|
|
|
** than fading it! */
|
2009-06-07 15:53:30 +00:00
|
|
|
if (argv[5].toUint16()) {
|
2009-10-18 20:33:02 +00:00
|
|
|
PUT_SEL32V(segMan, obj, signal, SIGNAL_OFFSET);
|
2009-05-28 22:48:15 +00:00
|
|
|
s->_sound.sfx_song_set_status(handle, SOUND_STATUS_STOPPED);
|
2009-05-12 12:56:22 +00:00
|
|
|
} else {
|
|
|
|
// FIXME: Support fade-and-continue. For now, send signal right away.
|
2009-10-18 19:42:56 +00:00
|
|
|
PUT_SEL32V(segMan, obj, signal, SIGNAL_OFFSET);
|
2009-02-15 06:10:59 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
2009-02-15 22:28:12 +00:00
|
|
|
case _K_SCI1_SOUND_HOLD_HANDLE : {
|
2009-06-07 15:53:30 +00:00
|
|
|
int value = argv[2].toSint16();
|
2009-02-15 06:10:59 +00:00
|
|
|
|
2009-05-28 22:48:15 +00:00
|
|
|
s->_sound.sfx_song_set_hold(handle, value);
|
2009-02-15 06:10:59 +00:00
|
|
|
break;
|
|
|
|
}
|
2009-02-15 22:28:12 +00:00
|
|
|
case _K_SCI1_SOUND_UNUSED2 : {
|
2009-02-15 06:10:59 +00:00
|
|
|
break;
|
|
|
|
}
|
2009-02-15 22:28:12 +00:00
|
|
|
case _K_SCI1_SOUND_SET_HANDLE_VOLUME : {
|
2009-02-15 06:10:59 +00:00
|
|
|
break;
|
|
|
|
}
|
2009-02-15 22:28:12 +00:00
|
|
|
case _K_SCI1_SOUND_SET_HANDLE_PRIORITY : {
|
2009-06-07 15:53:30 +00:00
|
|
|
int value = argv[2].toSint16();
|
2009-02-15 06:10:59 +00:00
|
|
|
|
|
|
|
script_set_priority(s, obj, value);
|
|
|
|
break;
|
|
|
|
}
|
2009-02-15 22:28:12 +00:00
|
|
|
case _K_SCI1_SOUND_SET_HANDLE_LOOP : {
|
2009-10-18 19:42:56 +00:00
|
|
|
if (!GET_SEL32(segMan, obj, nodePtr).isNull()) {
|
2009-10-11 02:47:07 +00:00
|
|
|
uint16 looping = argv[2].toUint16();
|
|
|
|
|
|
|
|
if (looping < 65535)
|
|
|
|
looping = 1;
|
|
|
|
|
|
|
|
s->_sound.sfx_song_set_loops(handle, looping);
|
2009-10-18 19:42:56 +00:00
|
|
|
PUT_SEL32V(segMan, obj, loop, looping);
|
2009-10-11 02:47:07 +00:00
|
|
|
}
|
2009-02-15 06:10:59 +00:00
|
|
|
break;
|
|
|
|
}
|
2009-02-15 22:28:12 +00:00
|
|
|
case _K_SCI1_SOUND_UPDATE_CUES : {
|
2009-02-15 06:10:59 +00:00
|
|
|
int signal = 0;
|
2009-02-15 15:24:43 +00:00
|
|
|
//int min = 0;
|
|
|
|
//int sec = 0;
|
|
|
|
//int frame = 0;
|
2009-02-15 06:10:59 +00:00
|
|
|
int result = SI_LOOP; /* small hack */
|
2009-02-15 10:24:32 +00:00
|
|
|
int cue = 0;
|
2009-02-15 06:10:59 +00:00
|
|
|
|
|
|
|
while (result == SI_LOOP)
|
2009-05-28 22:48:15 +00:00
|
|
|
result = s->_sound.sfx_poll_specific(handle, &cue);
|
2009-02-15 06:10:59 +00:00
|
|
|
|
|
|
|
switch (result) {
|
|
|
|
|
|
|
|
case SI_ABSOLUTE_CUE:
|
|
|
|
signal = cue;
|
2009-07-07 20:43:27 +00:00
|
|
|
debugC(2, kDebugLevelSound, "[CUE] %04x:%04x Absolute Cue: %d\n",
|
2009-02-15 22:28:12 +00:00
|
|
|
PRINT_REG(obj), signal);
|
2009-02-15 06:10:59 +00:00
|
|
|
|
2009-10-18 19:42:56 +00:00
|
|
|
PUT_SEL32V(segMan, obj, signal, signal);
|
2009-02-15 06:10:59 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case SI_RELATIVE_CUE:
|
2009-07-07 20:43:27 +00:00
|
|
|
debugC(2, kDebugLevelSound, "[CUE] %04x:%04x Relative Cue: %d\n",
|
2009-02-15 22:28:12 +00:00
|
|
|
PRINT_REG(obj), cue);
|
2009-02-15 06:10:59 +00:00
|
|
|
|
2009-10-18 19:42:56 +00:00
|
|
|
PUT_SEL32V(segMan, obj, dataInc, cue);
|
|
|
|
PUT_SEL32V(segMan, obj, signal, cue + 127);
|
2009-02-15 06:10:59 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case SI_FINISHED:
|
2009-10-18 19:42:56 +00:00
|
|
|
PUT_SEL32V(segMan, obj, signal, SIGNAL_OFFSET);
|
2009-02-15 06:10:59 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case SI_LOOP:
|
|
|
|
break; /* Doesn't happen */
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
2009-02-15 22:28:12 +00:00
|
|
|
case _K_SCI1_SOUND_MIDI_SEND : {
|
2009-05-28 22:48:15 +00:00
|
|
|
s->_sound.sfx_send_midi(handle,
|
2009-06-07 15:53:30 +00:00
|
|
|
argv[2].toUint16(), argv[3].toUint16(), argv[4].toUint16(), argv[5].toUint16());
|
2009-02-15 06:10:59 +00:00
|
|
|
break;
|
|
|
|
}
|
2009-02-15 22:28:12 +00:00
|
|
|
case _K_SCI1_SOUND_REVERB : {
|
2009-02-15 06:10:59 +00:00
|
|
|
break;
|
|
|
|
}
|
2009-02-15 22:28:12 +00:00
|
|
|
case _K_SCI1_SOUND_UPDATE_VOL_PRI : {
|
2009-02-15 06:10:59 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return s->r_acc;
|
|
|
|
}
|
|
|
|
|
2009-07-06 12:44:55 +00:00
|
|
|
/**
|
|
|
|
* Used for synthesized music playback
|
|
|
|
*/
|
- Changed the unimplemented debug SCI kernel functions (InspectObj, ShowSends, ShowObjs, ShowFree, StackUsage and Profiler) to be dummy functions - we have our own debugger, and don't use these functions for debugging
- Removed the function number parameter from all kernel functions, as it's no longer needed, and removed the FAKE_FUNCT_NR hack
- Removed kUnknown() and kStub()
- Dummy/unknown kernel functions are no longer invoked, and a warning is shown instead, with the paremeters passed to them
Note: there is an evil hack used for debugging scripts in invoke_selector(), which probably no longer works now
svn-id: r44461
2009-09-29 14:24:07 +00:00
|
|
|
reg_t kDoSound(EngineState *s, int argc, reg_t *argv) {
|
2009-09-30 16:16:53 +00:00
|
|
|
switch (s->detectDoSoundType()) {
|
2009-08-30 01:37:52 +00:00
|
|
|
case SCI_VERSION_0_EARLY:
|
2009-09-02 11:33:25 +00:00
|
|
|
return kDoSoundSci0(s, argc, argv);
|
2009-08-30 01:37:52 +00:00
|
|
|
case SCI_VERSION_1_EARLY:
|
2009-09-02 11:33:25 +00:00
|
|
|
return kDoSoundSci1Early(s, argc, argv);
|
2009-08-30 01:37:52 +00:00
|
|
|
case SCI_VERSION_1_LATE:
|
2009-09-02 11:33:25 +00:00
|
|
|
return kDoSoundSci1Late(s, argc, argv);
|
2009-08-17 15:49:22 +00:00
|
|
|
default:
|
|
|
|
warning("Unknown DoSound type");
|
|
|
|
return NULL_REG;
|
|
|
|
}
|
2009-02-15 06:10:59 +00:00
|
|
|
}
|
|
|
|
|
2009-10-25 03:26:20 +00:00
|
|
|
reg_t kDoCdAudio(EngineState *s, int argc, reg_t *argv) {
|
|
|
|
switch (argv[0].toUint16()) {
|
|
|
|
case kSciAudioWPlay:
|
|
|
|
case kSciAudioPlay: {
|
2009-11-04 11:22:46 +00:00
|
|
|
if (argc < 2)
|
|
|
|
return NULL_REG;
|
2009-10-25 03:26:20 +00:00
|
|
|
|
2009-11-04 11:22:46 +00:00
|
|
|
uint16 track = argv[1].toUint16() - 1;
|
|
|
|
uint32 startFrame = (argc > 2) ? argv[2].toUint16() * 75 : 0;
|
|
|
|
uint32 totalFrames = (argc > 3) ? argv[3].toUint16() * 75 : 0;
|
2009-10-25 03:26:20 +00:00
|
|
|
|
2009-11-04 11:22:46 +00:00
|
|
|
return make_reg(0, s->_audio->audioCdPlay(track, startFrame, totalFrames));
|
2009-10-25 03:26:20 +00:00
|
|
|
}
|
|
|
|
case kSciAudioStop:
|
2009-11-04 11:22:46 +00:00
|
|
|
s->_audio->audioCdStop();
|
2009-10-25 03:26:20 +00:00
|
|
|
|
|
|
|
if (getSciVersion() == SCI_VERSION_1_1)
|
|
|
|
return make_reg(0, 1);
|
|
|
|
|
|
|
|
break;
|
|
|
|
case kSciAudioPause:
|
|
|
|
warning("Can't pause CD Audio");
|
|
|
|
break;
|
|
|
|
case kSciAudioResume:
|
|
|
|
// This seems to be hacked up to update the CD instead of resuming
|
|
|
|
// audio like kDoAudio does.
|
2009-11-04 11:22:46 +00:00
|
|
|
s->_audio->audioCdUpdate();
|
2009-10-25 03:26:20 +00:00
|
|
|
break;
|
|
|
|
case kSciAudioPosition:
|
2009-11-04 11:22:46 +00:00
|
|
|
return make_reg(0, s->_audio->audioCdPosition());
|
2009-10-25 03:26:20 +00:00
|
|
|
case kSciAudioRate: // No need to set the audio rate
|
|
|
|
case kSciAudioVolume: // The speech setting isn't used by CD Audio
|
|
|
|
case kSciAudioLanguage: // No need to set the language
|
|
|
|
break;
|
|
|
|
case kSciAudioCD:
|
|
|
|
// Init
|
|
|
|
return make_reg(0, 1);
|
|
|
|
default:
|
|
|
|
warning("kCdDoAudio: Unhandled case %d", argv[0].toUint16());
|
|
|
|
}
|
|
|
|
|
|
|
|
return s->r_acc;
|
|
|
|
}
|
|
|
|
|
2009-07-06 12:44:55 +00:00
|
|
|
/**
|
|
|
|
* Used for speech playback and digital soundtracks in CD games
|
|
|
|
*/
|
- Changed the unimplemented debug SCI kernel functions (InspectObj, ShowSends, ShowObjs, ShowFree, StackUsage and Profiler) to be dummy functions - we have our own debugger, and don't use these functions for debugging
- Removed the function number parameter from all kernel functions, as it's no longer needed, and removed the FAKE_FUNCT_NR hack
- Removed kUnknown() and kStub()
- Dummy/unknown kernel functions are no longer invoked, and a warning is shown instead, with the paremeters passed to them
Note: there is an evil hack used for debugging scripts in invoke_selector(), which probably no longer works now
svn-id: r44461
2009-09-29 14:24:07 +00:00
|
|
|
reg_t kDoAudio(EngineState *s, int argc, reg_t *argv) {
|
2009-10-25 03:26:20 +00:00
|
|
|
// JonesCD uses different functions based on the cdaudio.map file
|
|
|
|
// to use red book tracks.
|
|
|
|
if (s->usesCdTrack())
|
|
|
|
return kDoCdAudio(s, argc, argv);
|
|
|
|
|
2009-05-22 22:19:15 +00:00
|
|
|
Audio::Mixer *mixer = g_system->getMixer();
|
2009-05-25 11:44:24 +00:00
|
|
|
|
2009-06-07 15:53:30 +00:00
|
|
|
switch (argv[0].toUint16()) {
|
2009-05-27 09:07:08 +00:00
|
|
|
case kSciAudioWPlay:
|
2009-06-12 23:46:23 +00:00
|
|
|
case kSciAudioPlay: {
|
|
|
|
uint16 module;
|
|
|
|
uint32 number;
|
|
|
|
|
2009-11-04 09:36:18 +00:00
|
|
|
s->_audio->stopAudio();
|
2009-06-12 23:46:23 +00:00
|
|
|
|
|
|
|
if (argc == 2) {
|
|
|
|
module = 65535;
|
|
|
|
number = argv[1].toUint16();
|
|
|
|
} else if (argc == 6) {
|
|
|
|
module = argv[1].toUint16();
|
|
|
|
number = ((argv[2].toUint16() & 0xff) << 24) | ((argv[3].toUint16() & 0xff) << 16) |
|
|
|
|
((argv[4].toUint16() & 0xff) << 8) | (argv[5].toUint16() & 0xff);
|
|
|
|
} else {
|
2009-05-27 08:48:57 +00:00
|
|
|
warning("kDoAudio: Play called with an unknown number of parameters (%d)", argc);
|
2009-06-12 23:46:23 +00:00
|
|
|
return NULL_REG;
|
2009-05-25 10:30:19 +00:00
|
|
|
}
|
2009-06-12 23:46:23 +00:00
|
|
|
|
2009-11-04 09:36:18 +00:00
|
|
|
return make_reg(0, s->_audio->startAudio(module, number)); // return sample length in ticks
|
2009-06-12 23:46:23 +00:00
|
|
|
}
|
2009-05-27 09:07:08 +00:00
|
|
|
case kSciAudioStop:
|
2009-11-04 09:36:18 +00:00
|
|
|
s->_audio->stopAudio();
|
2009-04-26 02:00:36 +00:00
|
|
|
break;
|
2009-05-27 09:07:08 +00:00
|
|
|
case kSciAudioPause:
|
2009-11-04 09:36:18 +00:00
|
|
|
s->_audio->pauseAudio();
|
2009-04-26 02:00:36 +00:00
|
|
|
break;
|
2009-05-27 09:07:08 +00:00
|
|
|
case kSciAudioResume:
|
2009-11-04 09:36:18 +00:00
|
|
|
s->_audio->resumeAudio();
|
2009-04-26 02:00:36 +00:00
|
|
|
break;
|
2009-05-27 09:07:08 +00:00
|
|
|
case kSciAudioPosition:
|
2009-11-04 09:36:18 +00:00
|
|
|
return make_reg(0, s->_audio->getAudioPosition());
|
2009-05-27 09:07:08 +00:00
|
|
|
case kSciAudioRate:
|
2009-11-04 09:36:18 +00:00
|
|
|
s->_audio->setAudioRate(argv[1].toUint16());
|
2009-04-26 02:00:36 +00:00
|
|
|
break;
|
2009-05-27 09:07:08 +00:00
|
|
|
case kSciAudioVolume:
|
2009-06-07 15:53:30 +00:00
|
|
|
mixer->setVolumeForSoundType(Audio::Mixer::kSpeechSoundType, argv[1].toUint16());
|
2009-04-26 02:00:36 +00:00
|
|
|
break;
|
2009-05-27 09:07:08 +00:00
|
|
|
case kSciAudioLanguage:
|
2009-05-26 00:03:41 +00:00
|
|
|
if (argc == 1) {
|
|
|
|
// In SCI1.1: tests for digital audio support
|
|
|
|
return make_reg(0, 1);
|
|
|
|
} else {
|
2009-09-02 12:02:37 +00:00
|
|
|
s->resMan->setAudioLanguage(argv[1].toSint16());
|
2009-05-26 00:03:41 +00:00
|
|
|
}
|
2009-04-26 02:00:36 +00:00
|
|
|
break;
|
2009-10-25 03:26:20 +00:00
|
|
|
case kSciAudioCD:
|
|
|
|
return kDoCdAudio(s, argc - 1, argv + 1);
|
2009-05-22 22:19:15 +00:00
|
|
|
default:
|
2009-06-07 15:53:30 +00:00
|
|
|
warning("kDoAudio: Unhandled case %d", argv[0].toUint16());
|
2009-02-15 06:10:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return s->r_acc;
|
|
|
|
}
|
|
|
|
|
- Changed the unimplemented debug SCI kernel functions (InspectObj, ShowSends, ShowObjs, ShowFree, StackUsage and Profiler) to be dummy functions - we have our own debugger, and don't use these functions for debugging
- Removed the function number parameter from all kernel functions, as it's no longer needed, and removed the FAKE_FUNCT_NR hack
- Removed kUnknown() and kStub()
- Dummy/unknown kernel functions are no longer invoked, and a warning is shown instead, with the paremeters passed to them
Note: there is an evil hack used for debugging scripts in invoke_selector(), which probably no longer works now
svn-id: r44461
2009-09-29 14:24:07 +00:00
|
|
|
reg_t kDoSync(EngineState *s, int argc, reg_t *argv) {
|
2009-10-04 18:38:18 +00:00
|
|
|
SegManager *segMan = s->_segMan;
|
2009-06-07 15:53:30 +00:00
|
|
|
switch (argv[0].toUint16()) {
|
2009-06-07 19:15:55 +00:00
|
|
|
case kSciAudioSyncStart: {
|
|
|
|
ResourceId id;
|
|
|
|
|
2009-11-04 10:20:25 +00:00
|
|
|
s->_audio->stopSoundSync();
|
2009-06-07 19:15:55 +00:00
|
|
|
|
|
|
|
// Load sound sync resource and lock it
|
|
|
|
if (argc == 3) {
|
|
|
|
id = ResourceId(kResourceTypeSync, argv[2].toUint16());
|
|
|
|
} else if (argc == 7) {
|
|
|
|
id = ResourceId(kResourceTypeSync36, argv[2].toUint16(), argv[3].toUint16(), argv[4].toUint16(),
|
|
|
|
argv[5].toUint16(), argv[6].toUint16());
|
|
|
|
} else {
|
|
|
|
warning("kDoSync: Start called with an unknown number of parameters (%d)", argc);
|
|
|
|
return s->r_acc;
|
|
|
|
}
|
2009-04-25 08:50:42 +00:00
|
|
|
|
2009-11-04 10:20:25 +00:00
|
|
|
s->_audio->setSoundSync(id, argv[1], segMan);
|
2009-04-25 08:50:42 +00:00
|
|
|
break;
|
2009-06-07 19:15:55 +00:00
|
|
|
}
|
2009-11-04 10:20:25 +00:00
|
|
|
case kSciAudioSyncNext:
|
|
|
|
s->_audio->doSoundSync(argv[1], segMan);
|
2009-04-25 08:50:42 +00:00
|
|
|
break;
|
2009-05-27 09:07:08 +00:00
|
|
|
case kSciAudioSyncStop:
|
2009-11-04 10:20:25 +00:00
|
|
|
s->_audio->stopSoundSync();
|
2009-04-25 08:50:42 +00:00
|
|
|
break;
|
2009-05-27 09:07:08 +00:00
|
|
|
default:
|
2009-06-12 23:46:23 +00:00
|
|
|
warning("DoSync: Unhandled subfunction %d", argv[0].toUint16());
|
2009-04-25 08:50:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return s->r_acc;
|
|
|
|
}
|
|
|
|
|
2009-02-21 10:23:36 +00:00
|
|
|
} // End of namespace Sci
|