예제 #1
0
reg_t
kMapKeyToDir(state_t *s, int funct_nr, int argc, reg_t *argv)
{
	reg_t obj = argv[0];

	if (GET_SEL32V(obj, type) == SCI_EVT_KEYBOARD) { /* Keyboard */
		int mover = -1;
		switch (GET_SEL32V(obj, message)) {
		case SCI_K_HOME: mover = 8; break;
		case SCI_K_UP: mover = 1; break;
		case SCI_K_PGUP: mover = 2; break;
		case SCI_K_LEFT: mover = 7; break;
		case SCI_K_CENTER:
		case 76: mover = 0; break;
		case SCI_K_RIGHT: mover = 3; break;
		case SCI_K_END: mover = 6; break;
		case SCI_K_DOWN: mover = 5; break;
		case SCI_K_PGDOWN: mover = 4; break;
		default: break;
		}

		if (mover >= 0) {
			PUT_SEL32V(obj, type, SCI_EVT_JOYSTICK);
			PUT_SEL32V(obj, message, mover);
			return make_reg(0, 1);
		} else return NULL_REG;
	}

	return s->r_acc;
}
예제 #2
0
reg_t kLocalToGlobal(EngineState *s, int funct_nr, int argc, reg_t *argv) {
	reg_t obj = argc ? argv[0] : NULL_REG; // Can this really happen? Lars

	if (obj.segment) {
		int x = GET_SEL32V(obj, x);
		int y = GET_SEL32V(obj, y);

		PUT_SEL32V(obj, x, x + s->port->zone.x);
		PUT_SEL32V(obj, y, y + s->port->zone.y);
	}

	return s->r_acc;
}
예제 #3
0
void process_sound_events(EngineState *s) { /* Get all sound events, apply their changes to the heap */
	int result;
	SongHandle handle;
	int cue;

	if (s->_version >= SCI_VERSION_01)
		return;
	/* SCI01 and later explicitly poll for everything */

	while ((result = s->_sound.sfx_poll(&handle, &cue))) {
		reg_t obj = DEFROBNICATE_HANDLE(handle);
		if (!is_object(s, obj)) {
			warning("Non-object %04x:%04x received sound signal (%d/%d)", PRINT_REG(obj), result, cue);
			return;
		}

		switch (result) {

		case SI_LOOP:
			debugC(2, kDebugLevelSound, "[process-sound] Song %04x:%04x looped (to %d)\n",
			          PRINT_REG(obj), cue);
			/*			PUT_SEL32V(obj, loops, GET_SEL32V(obj, loop) - 1);*/
			PUT_SEL32V(obj, signal, -1);
			break;

		case SI_RELATIVE_CUE:
			debugC(2, kDebugLevelSound, "[process-sound] Song %04x:%04x received relative cue %d\n",
			          PRINT_REG(obj), cue);
			PUT_SEL32V(obj, signal, cue + 0x7f);
			break;

		case SI_ABSOLUTE_CUE:
			debugC(2, kDebugLevelSound, "[process-sound] Song %04x:%04x received absolute cue %d\n",
			          PRINT_REG(obj), cue);
			PUT_SEL32V(obj, signal, cue);
			break;

		case SI_FINISHED:
			debugC(2, kDebugLevelSound, "[process-sound] Song %04x:%04x finished\n",
			          PRINT_REG(obj));
			PUT_SEL32V(obj, signal, -1);
			PUT_SEL32V(obj, state, _K_SOUND_STATUS_STOPPED);
			break;

		default:
			warning("Unexpected result from sfx_poll: %d", result);
			break;
		}
	}
}
예제 #4
0
reg_t
kGlobalToLocal(state_t *s, int funct_nr, int argc, reg_t *argv)
{
	reg_t obj = argc ? argv[0] : NULL_REG; /* Can this really happen? Lars */

	if (obj.segment) {
		int x = GET_SEL32V(obj, x);
		int y = GET_SEL32V(obj, y);

		PUT_SEL32V(obj, x, x - s->port->zone.x);
		PUT_SEL32V(obj, y, y - s->port->zone.y);
	}

	return s->r_acc;

}
예제 #5
0
reg_t
kGetEvent(state_t *s, int funct_nr, int argc, reg_t *argv)
{
	int mask = UKPV(0);
	reg_t obj = argv[1];
	sci_event_t e;
	int oldx, oldy;
	int modifier_mask = SCI_VERSION_MAJOR(s->version)==0 ? SCI_EVM_ALL
	                                                     : SCI_EVM_NO_FOOLOCK;

	if (s->kernel_opt_flags & KERNEL_OPT_FLAG_GOT_2NDEVENT) {
		/* Penalty time- too many requests to this function without
		** waiting!  */
		int delay = s->script_000->locals_block->locals[SCI_VARIABLE_GAME_SPEED].offset;

		gfxop_usleep(s->gfx_state, (1000000 * delay) / 60);
	}
  
	/*If there's a simkey pending, and the game wants a keyboard event, use the
	 *simkey instead of a normal event*/
	if (_kdebug_cheap_event_hack && (mask & SCI_EVT_KEYBOARD)) {
		PUT_SEL32V(obj, type, SCI_EVT_KEYBOARD); /*Keyboard event*/
		PUT_SEL32V(obj, message, _kdebug_cheap_event_hack);
		PUT_SEL32V(obj, modifiers, SCI_EVM_NUMLOCK); /*Numlock on*/
		PUT_SEL32V(obj, x, s->gfx_state->pointer_pos.x);
		PUT_SEL32V(obj, y, s->gfx_state->pointer_pos.y);
		_kdebug_cheap_event_hack = 0;
		return make_reg(0, 1);
	}
  
	oldx = s->gfx_state->pointer_pos.x;
	oldy = s->gfx_state->pointer_pos.y;
	e = gfxop_get_event(s->gfx_state, mask);

	s->parser_event = NULL_REG; /* Invalidate parser event */

	PUT_SEL32V(obj, x, s->gfx_state->pointer_pos.x);
	PUT_SEL32V(obj, y, s->gfx_state->pointer_pos.y);

	/*  gfxop_set_pointer_position(s->gfx_state, gfx_point(s->gfx_state->pointer_pos.x, s->gfx_state->pointer_pos.y)); */


	if (e.type)
		s->kernel_opt_flags &= ~(KERNEL_OPT_FLAG_GOT_EVENT
					 | KERNEL_OPT_FLAG_GOT_2NDEVENT);
	else {
		if (s->kernel_opt_flags & KERNEL_OPT_FLAG_GOT_EVENT)
			s->kernel_opt_flags |= KERNEL_OPT_FLAG_GOT_2NDEVENT;
		else
			s->kernel_opt_flags |= KERNEL_OPT_FLAG_GOT_EVENT;
	}

	switch(e.type)
		{
		case SCI_EVT_QUIT:
			quit_vm();
			break;

		case SCI_EVT_KEYBOARD: {

			if ((e.buckybits & SCI_EVM_LSHIFT) && (e.buckybits & SCI_EVM_RSHIFT)
			    && (e.data == '-')) {

				sciprintf("Debug mode activated\n");

				script_debug_flag = 1; /* Enter debug mode */
				_debug_seeking = _debug_step_running = 0;
				s->onscreen_console = 0;

			} else if ((e.buckybits & SCI_EVM_CTRL) && (e.data == '`')) {

				script_debug_flag = 1; /* Enter debug mode */
				_debug_seeking = _debug_step_running = 0;
				s->onscreen_console = 1;

			} else if ((e.buckybits & SCI_EVM_CTRL) && (e.data == '1')) {

				if (s->visual)
					s->visual->print(GFXW(s->visual), 0);

			} else {
				PUT_SEL32V(obj, type, SCI_EVT_KEYBOARD); /*Keyboard event*/
				s->r_acc=make_reg(0, 1);
				PUT_SEL32V(obj, message, e.character);
				/* We only care about the translated
				** character  */
				PUT_SEL32V(obj, modifiers, e.buckybits&modifier_mask);

			}
		} break;

		case SCI_EVT_MOUSE_RELEASE:
		case SCI_EVT_MOUSE_PRESS: {
			int extra_bits=0;

			if(mask & e.type) {
				switch(e.data) {
				case 2: extra_bits=SCI_EVM_LSHIFT|SCI_EVM_RSHIFT; break;
				case 3: extra_bits=SCI_EVM_CTRL;
				default:break;
				}

				PUT_SEL32V(obj, type, e.type);
				PUT_SEL32V(obj, message, 1);
				PUT_SEL32V(obj, modifiers, (e.buckybits|extra_bits)&modifier_mask);
				s->r_acc = make_reg(0, 1);
			}
		} break;

		default: {
			s->r_acc = NULL_REG; /* Unknown or no event */
		}
		}

	if ((s->r_acc.offset) && (stop_on_event)) {
		stop_on_event = 0;
		script_debug_flag = 1;
	}  

	return s->r_acc;
}
예제 #6
0
reg_t kGetEvent(EngineState *s, int funct_nr, int argc, reg_t *argv) {
	int mask = argv[0].toUint16();
	reg_t obj = argv[1];
	sci_event_t e;
	int oldx, oldy;
	int modifier_mask = s->_version <= SCI_VERSION_0 ? SCI_EVM_ALL : SCI_EVM_NO_FOOLOCK;

	if (s->kernel_opt_flags & KERNEL_OPT_FLAG_GOT_2NDEVENT) {
		// Penalty time- too many requests to this function without waiting!
		int delay = s->script_000->locals_block->_locals[SCI_VARIABLE_GAME_SPEED].offset;
		gfxop_sleep(s->gfx_state, delay * 1000 / 60);
	}

	// If there's a simkey pending, and the game wants a keyboard event, use the
	// simkey instead of a normal event
	if (g_debug_simulated_key && (mask & SCI_EVT_KEYBOARD)) {
		PUT_SEL32V(obj, type, SCI_EVT_KEYBOARD); // Keyboard event
		PUT_SEL32V(obj, message, g_debug_simulated_key);
		PUT_SEL32V(obj, modifiers, SCI_EVM_NUMLOCK); // Numlock on
		PUT_SEL32V(obj, x, s->gfx_state->pointer_pos.x);
		PUT_SEL32V(obj, y, s->gfx_state->pointer_pos.y);
		g_debug_simulated_key = 0;
		return make_reg(0, 1);
	}

	oldx = s->gfx_state->pointer_pos.x;
	oldy = s->gfx_state->pointer_pos.y;
	e = gfxop_get_event(s->gfx_state, mask);

	s->parser_event = NULL_REG; // Invalidate parser event

	PUT_SEL32V(obj, x, s->gfx_state->pointer_pos.x);
	PUT_SEL32V(obj, y, s->gfx_state->pointer_pos.y);

	//gfxop_set_pointer_position(s->gfx_state, Common::Point(s->gfx_state->pointer_pos.x, s->gfx_state->pointer_pos.y));

	if (e.type)
		s->kernel_opt_flags &= ~(KERNEL_OPT_FLAG_GOT_EVENT | KERNEL_OPT_FLAG_GOT_2NDEVENT);
	else {
		if (s->kernel_opt_flags & KERNEL_OPT_FLAG_GOT_EVENT)
			s->kernel_opt_flags |= KERNEL_OPT_FLAG_GOT_2NDEVENT;
		else
			s->kernel_opt_flags |= KERNEL_OPT_FLAG_GOT_EVENT;
	}

	switch (e.type) {
	case SCI_EVT_QUIT:
		quit_vm();
		break;

	case SCI_EVT_KEYBOARD:
		if ((e.buckybits & SCI_EVM_LSHIFT) && (e.buckybits & SCI_EVM_RSHIFT) && (e.data == '-')) {
			printf("Debug mode activated\n");
			scriptState.seeking = kDebugSeekNothing;
			scriptState.runningStep = 0;
		} else if ((e.buckybits & SCI_EVM_CTRL) && (e.data == '`')) {
			printf("Debug mode activated\n");
			scriptState.seeking = kDebugSeekNothing;
			scriptState.runningStep = 0;
		} else {
			PUT_SEL32V(obj, type, SCI_EVT_KEYBOARD); // Keyboard event
			s->r_acc = make_reg(0, 1);
			PUT_SEL32V(obj, message, e.character);
			// We only care about the translated
			// character
			PUT_SEL32V(obj, modifiers, e.buckybits&modifier_mask);
		}
		break;

	case SCI_EVT_MOUSE_RELEASE:
	case SCI_EVT_MOUSE_PRESS: {
		int extra_bits = 0;

		// track left buttton clicks, if requested
		if (e.type == SCI_EVT_MOUSE_PRESS && e.data == 1 && g_debug_track_mouse_clicks) {
			((SciEngine *)g_engine)->getSciDebugger()->DebugPrintf("Mouse clicked at %d, %d\n", 
						s->gfx_state->pointer_pos.x, s->gfx_state->pointer_pos.y);
		}

		if (mask & e.type) {
			switch (e.data) {
			case 2:
				extra_bits = SCI_EVM_LSHIFT | SCI_EVM_RSHIFT;
				break;
			case 3:
				extra_bits = SCI_EVM_CTRL;
			default:
				break;
			}

			PUT_SEL32V(obj, type, e.type);
			PUT_SEL32V(obj, message, 1);
			PUT_SEL32V(obj, modifiers, (e.buckybits | extra_bits)&modifier_mask);
			s->r_acc = make_reg(0, 1);
		}
		break;
	}

	default:
		s->r_acc = NULL_REG; // Unknown or no event
	}

	if ((s->r_acc.offset) && (scriptState.stopOnEvent)) {
		scriptState.stopOnEvent = false;

		// A SCI event occured, and we have been asked to stop, so open the debug console
		Console *con = ((Sci::SciEngine*)g_engine)->getSciDebugger();
		con->DebugPrintf("SCI event occured: ");
		switch (e.type) {
		case SCI_EVT_QUIT:
			con->DebugPrintf("quit event\n");
			break;
		case SCI_EVT_KEYBOARD:
			con->DebugPrintf("keyboard event\n");
			break;
		case SCI_EVT_MOUSE_RELEASE:
		case SCI_EVT_MOUSE_PRESS:
			con->DebugPrintf("mouse click event\n");
			break;
		default:
			con->DebugPrintf("unknown or no event (event type %d)\n", e.type);
		}

		con->attach();
		con->onFrame();
	}

	return s->r_acc;
}
예제 #7
0
reg_t kDoSound_SCI1(EngineState *s, int funct_nr, int argc, reg_t *argv) {
	uint16 command = argv[0].toUint16();
	reg_t obj = (argc > 1) ? argv[1] : NULL_REG;
	SongHandle handle = FROBNICATE_HANDLE(obj);
	int number = obj.segment ?
	             GET_SEL32V(obj, number) :
	             -1; /* We were not going to use it anyway */

#ifdef DEBUG_SOUND
	if (command != _K_SCI1_SOUND_UPDATE_CUES) {
		int i;

		debugC(2, kDebugLevelSound, "Command 0x%x", command);
		switch (command) {
		case 0:
			debugC(2, kDebugLevelSound, "[MasterVolume]");
			break;
		case 1:
			debugC(2, kDebugLevelSound, "[Mute]");
			break;
		case 2:
			debugC(2, kDebugLevelSound, "[NOP(2)]");
			break;
		case 3:
			debugC(2, kDebugLevelSound, "[GetPolyphony]");
			break;
		case 4:
			debugC(2, kDebugLevelSound, "[GetAudioCapability]");
			break;
		case 5:
			debugC(2, kDebugLevelSound, "[GlobalSuspend]");
			break;
		case 6:
			debugC(2, kDebugLevelSound, "[Init]");
			break;
		case 7:
			debugC(2, kDebugLevelSound, "[Dispose]");
			break;
		case 8:
			debugC(2, kDebugLevelSound, "[Play]");
			break;
		case 9:
			debugC(2, kDebugLevelSound, "[Stop]");
			break;
		case 10:
			debugC(2, kDebugLevelSound, "[SuspendHandle]");
			break;
		case 11:
			debugC(2, kDebugLevelSound, "[Fade]");
			break;
		case 12:
			debugC(2, kDebugLevelSound, "[Hold]");
			break;
		case 13:
			debugC(2, kDebugLevelSound, "[Unused(13)]");
			break;
		case 14:
			debugC(2, kDebugLevelSound, "[SetVolume]");
			break;
		case 15:
			debugC(2, kDebugLevelSound, "[SetPriority]");
			break;
		case 16:
			debugC(2, kDebugLevelSound, "[SetLoop]");
			break;
		case 17:
			debugC(2, kDebugLevelSound, "[UpdateCues]");
			break;
		case 18:
			debugC(2, kDebugLevelSound, "[MidiSend]");
			break;
		case 19:
			debugC(2, kDebugLevelSound, "[Reverb]");
			break;
		case 20:
			debugC(2, kDebugLevelSound, "[UpdateVolPri]");
			break;
		default:
			debugC(2, kDebugLevelSound, "[unknown]");
			break;
		}

		debugC(2, kDebugLevelSound, "(");
		for (i = 1; i < argc; i++) {
			debugC(2, kDebugLevelSound, "%04x:%04x", PRINT_REG(argv[i]));
			if (i + 1 < argc)
				debugC(2, kDebugLevelSound, ", ");
		}
		debugC(2, kDebugLevelSound, ")\n");
	}
#endif	// DEBUG_SOUND

	switch (command) {
	case _K_SCI1_SOUND_MASTER_VOLME : {
		/*int vol = UPARAM_OR_ALT (1, -1);

		 if (vol != -1)
		         s->acc = s->sound_server->command(s, SOUND_COMMAND_SET_VOLUME, 0, vol);
		 else
		         s->acc = s->sound_server->command(s, SOUND_COMMAND_GET_VOLUME, 0, 0);
			break;*/
	}
	case _K_SCI1_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);
			break;*/
	}
	case _K_SCI1_SOUND_UNUSED1 : {
		break;
	}
	case _K_SCI1_SOUND_GET_POLYPHONY : {
		/*s->acc = s->sound_server->command(s, SOUND_COMMAND_TEST, 0, 0);*/
		break;
	}
	case _K_SCI1_SOUND_GET_AUDIO_CAPABILITY : {
		// Tests for digital audio support
		return make_reg(0, 1);
	}
	case _K_SCI1_SOUND_PLAY_HANDLE : {
		int looping = GET_SEL32V(obj, loop);
		//int vol = GET_SEL32V(obj, vol);
		int pri = GET_SEL32V(obj, pri);
		int sampleLen = 0;
		Song *song = s->_sound._songlib.findSong(handle);

		if (GET_SEL32V(obj, nodePtr) && (song && number != song->_resourceNum)) {
			s->_sound.sfx_song_set_status(handle, SOUND_STATUS_STOPPED);
			s->_sound.sfx_remove_song(handle);
			PUT_SEL32(obj, nodePtr, NULL_REG);
		}

		if (!GET_SEL32V(obj, nodePtr) && obj.segment) {
			// 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)
			if (s->resmgr->testResource(ResourceId(kResourceTypeAudio, number)) &&
				s->_version >= SCI_VERSION_1_1) {
				// Found a relevant audio resource, play it
				s->_sound.stopAudio();
				warning("Initializing audio resource instead of requested sound resource %d\n", number);
				sampleLen = s->_sound.startAudio(65535, number);
				// 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);
			} else {
				if (!s->resmgr->testResource(ResourceId(kResourceTypeSound, number))) {
					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);
					PUT_SEL32V(obj, signal, -1);
					return s->r_acc;
				}
				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);
			}

			PUT_SEL32(obj, nodePtr, obj);
			PUT_SEL32(obj, handle, obj);
		}

		if (obj.segment) {
			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);
		}

		break;
	}
	case _K_SCI1_SOUND_INIT_HANDLE : {
		//int looping = GET_SEL32V(obj, loop);
		//int vol = GET_SEL32V(obj, vol);
		//int pri = GET_SEL32V(obj, pri);

		if (GET_SEL32V(obj, nodePtr)) {
			s->_sound.sfx_song_set_status(handle, SOUND_STATUS_STOPPED);
			s->_sound.sfx_remove_song(handle);
		}

		if (obj.segment && (s->resmgr->testResource(ResourceId(kResourceTypeSound, number)))) {
			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);
			PUT_SEL32(obj, nodePtr, obj);
			PUT_SEL32(obj, handle, obj);
		}
		break;
	}
	case _K_SCI1_SOUND_DISPOSE_HANDLE : {
		if (obj.segment) {
			s->_sound.sfx_song_set_status(handle, SOUND_STATUS_STOPPED);
			s->_sound.sfx_remove_song(handle);
		}
		break;
	}
	case _K_SCI1_SOUND_STOP_HANDLE : {
		PUT_SEL32V(obj, signal, -1);
		if (obj.segment) {
			s->_sound.sfx_song_set_status(handle, SOUND_STATUS_STOPPED);
		}
		break;
	}
	case _K_SCI1_SOUND_SUSPEND_HANDLE : {
		break;
	}
	case _K_SCI1_SOUND_FADE_HANDLE : {
		fade_params_t fade;
		if (obj.segment) {
			fade.final_volume = argv[2].toUint16();
			fade.ticks_per_step = argv[3].toUint16();
			fade.step_size = argv[4].toUint16();
			fade.action = argv[5].toUint16() ?
			              FADE_ACTION_FADE_AND_STOP :
			              FADE_ACTION_FADE_AND_CONT;

			s->_sound.sfx_song_set_fade(handle,  &fade);

			/* FIXME: The next couple of lines actually STOP the handle, rather
			** than fading it! */
			if (argv[5].toUint16()) {
				PUT_SEL32V(obj, signal, -1);
				PUT_SEL32V(obj, nodePtr, 0);
				PUT_SEL32V(obj, handle, 0);
				s->_sound.sfx_song_set_status(handle, SOUND_STATUS_STOPPED);
			} else {
				// FIXME: Support fade-and-continue. For now, send signal right away.
				PUT_SEL32V(obj, signal, -1);
			}
		}
		break;
	}
	case _K_SCI1_SOUND_HOLD_HANDLE : {
		int value = argv[2].toSint16();

		s->_sound.sfx_song_set_hold(handle, value);
		break;
	}
	case _K_SCI1_SOUND_UNUSED2 : {
		break;
	}
	case _K_SCI1_SOUND_SET_HANDLE_VOLUME : {
		break;
	}
	case _K_SCI1_SOUND_SET_HANDLE_PRIORITY : {
		int value = argv[2].toSint16();

		script_set_priority(s, obj, value);
		break;
	}
	case _K_SCI1_SOUND_SET_HANDLE_LOOP : {
		break;
	}
	case _K_SCI1_SOUND_UPDATE_CUES : {
		int signal = 0;
		//int min = 0;
		//int sec = 0;
		//int frame = 0;
		int result = SI_LOOP; /* small hack */
		int cue = 0;

		while (result == SI_LOOP)
			result = s->_sound.sfx_poll_specific(handle, &cue);

		switch (result) {

		case SI_ABSOLUTE_CUE:
			signal = cue;
			debugC(2, kDebugLevelSound, "[CUE] %04x:%04x Absolute Cue: %d\n",
			        PRINT_REG(obj), signal);

			PUT_SEL32V(obj, signal, signal);
			break;

		case SI_RELATIVE_CUE:
			debugC(2, kDebugLevelSound, "[CUE] %04x:%04x Relative Cue: %d\n",
			        PRINT_REG(obj), cue);

			PUT_SEL32V(obj, dataInc, cue);
			PUT_SEL32V(obj, signal, cue + 127);
			break;

		case SI_FINISHED:
			PUT_SEL32V(obj, signal, 0xffff);
			break;

		case SI_LOOP:
			break; /* Doesn't happen */
		}
		break;
	}
	case _K_SCI1_SOUND_MIDI_SEND : {
		s->_sound.sfx_send_midi(handle,
		              argv[2].toUint16(), argv[3].toUint16(), argv[4].toUint16(), argv[5].toUint16());
		break;
	}
	case _K_SCI1_SOUND_REVERB : {
		break;
	}
	case _K_SCI1_SOUND_UPDATE_VOL_PRI : {
		break;
	}
	}
	return s->r_acc;
}
예제 #8
0
reg_t kDoSound_SCI01(EngineState *s, int funct_nr, int argc, reg_t *argv) {
	uint16 command = argv[0].toUint16();
	reg_t obj = (argc > 1) ? argv[1] : NULL_REG;
	SongHandle handle = FROBNICATE_HANDLE(obj);
	int number = obj.segment ?
	             GET_SEL32V(obj, number) :
	             -1; /* We were not going to use it anyway */

#ifdef DEBUG_SOUND
	if (command != _K_SCI01_SOUND_UPDATE_CUES) {
		int i;

		debugC(2, kDebugLevelSound, "Command 0x%x", command);
		switch (command) {
		case 0:
			debugC(2, kDebugLevelSound, "[MasterVolume]");
			break;
		case 1:
			debugC(2, kDebugLevelSound, "[Mute]");
			break;
		case 2:
			debugC(2, kDebugLevelSound, "[NOP(2)]");
			break;
		case 3:
			debugC(2, kDebugLevelSound, "[GetPolyphony]");
			break;
		case 4:
			debugC(2, kDebugLevelSound, "[Update]");
			break;
		case 5:
			debugC(2, kDebugLevelSound, "[Init]");
			break;
		case 6:
			debugC(2, kDebugLevelSound, "[Dispose]");
			break;
		case 7:
			debugC(2, kDebugLevelSound, "[Play]");
			break;
		case 8:
			debugC(2, kDebugLevelSound, "[Stop]");
			break;
		case 9:
			debugC(2, kDebugLevelSound, "[Suspend]");
			break;
		case 10:
			debugC(2, kDebugLevelSound, "[Fade]");
			break;
		case 11:
			debugC(2, kDebugLevelSound, "[UpdateCues]");
			break;
		case 12:
			debugC(2, kDebugLevelSound, "[MidiSend]");
			break;
		case 13:
			debugC(2, kDebugLevelSound, "[Reverb]");
			break;
		case 14:
			debugC(2, kDebugLevelSound, "[Hold]");
			break;
		default:
			debugC(2, kDebugLevelSound, "[unknown]");
			break;
		}

		debugC(2, kDebugLevelSound, "(");
		for (i = 1; i < argc; i++) {
			debugC(2, kDebugLevelSound, "%04x:%04x", PRINT_REG(argv[i]));
			if (i + 1 < argc)
				debugC(2, kDebugLevelSound, ", ");
		}
		debugC(2, kDebugLevelSound, ")\n");
	}
#endif

	switch (command) {
	case _K_SCI01_SOUND_MASTER_VOLME : {
		int vol = (argc > 1) ? argv[1].toSint16() : -1;

		if (vol != -1)
			s->_sound.sfx_set_volume(vol << 0xf);
		else
			s->r_acc = make_reg(0, s->_sound.sfx_get_volume() >> 0xf);
		break;
	}
	case _K_SCI01_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);*/

		break;
	}
	case _K_SCI01_SOUND_UNUSED : {
		break;
	}
	case _K_SCI01_SOUND_GET_POLYPHONY : {
		s->r_acc = make_reg(0, sfx_get_player_polyphony());
		break;
	}
	case _K_SCI01_SOUND_PLAY_HANDLE : {
		int looping = GET_SEL32V(obj, loop);
		//int vol = GET_SEL32V(obj, vol);
		int pri = GET_SEL32V(obj, pri);
		RESTORE_BEHAVIOR rb = (RESTORE_BEHAVIOR) argv[2].toUint16();		/* Too lazy to look up a default value for this */

		if (obj.segment) {
			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);
			s->_sound._songlib.setSongRestoreBehavior(handle, rb);
		}

		break;
	}
	case _K_SCI01_SOUND_INIT_HANDLE : {
		//int looping = GET_SEL32V(obj, loop);
		//int vol = GET_SEL32V(obj, vol);
		//int pri = GET_SEL32V(obj, pri);

		if (obj.segment && (s->resmgr->testResource(ResourceId(kResourceTypeSound, number)))) {
			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);
			PUT_SEL32(obj, nodePtr, obj);
			PUT_SEL32(obj, handle, obj);
		}
		break;
	}
	case _K_SCI01_SOUND_DISPOSE_HANDLE : {
		if (obj.segment) {
			s->_sound.sfx_song_set_status(handle, SOUND_STATUS_STOPPED);
			s->_sound.sfx_remove_song(handle);
		}
		break;
	}
	case _K_SCI01_SOUND_UPDATE_HANDLE : {
		/* 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' */
		int looping = GET_SEL32V(obj, loop);
		//int vol = GET_SEL32V(obj, vol);
		int pri = GET_SEL32V(obj, pri);

		s->_sound.sfx_song_set_loops(handle, looping);
		s->_sound.sfx_song_renice(handle, pri);

		debugC(2, kDebugLevelSound, "[sound01-update-handle] -- CUE %04x:%04x", PRINT_REG(obj));

		PUT_SEL32V(obj, signal, signal);
		PUT_SEL32V(obj, min, min);
		PUT_SEL32V(obj, sec, sec);
		PUT_SEL32V(obj, frame, frame);

		break;
	}
	case _K_SCI01_SOUND_STOP_HANDLE : {
		PUT_SEL32V(obj, signal, -1);
		if (obj.segment) {
			s->_sound.sfx_song_set_status(handle, SOUND_STATUS_STOPPED);
		}
		break;
	}
	case _K_SCI01_SOUND_SUSPEND_HANDLE : {
		int state = argv[2].toUint16();
		int setstate = (state) ?
		               SOUND_STATUS_SUSPENDED : SOUND_STATUS_PLAYING;

		if (obj.segment) {
			s->_sound.sfx_song_set_status(handle, setstate);
		}
		break;
	}
	case _K_SCI01_SOUND_FADE_HANDLE : {
		/* There are four parameters that control the fade here.
		 * TODO: Figure out the exact semantics */

		/* FIXME: The next couple of lines actually STOP the song right away */
		PUT_SEL32V(obj, signal, -1);
		if (obj.segment) {
			s->_sound.sfx_song_set_status(handle, SOUND_STATUS_STOPPED);
		}
		break;
	}
	case _K_SCI01_SOUND_UPDATE_CUES : {
		int signal = 0;
		int min = 0;
		int sec = 0;
		int frame = 0;
		int result = SI_LOOP; /* small hack */
		int cue = 0;

		while (result == SI_LOOP)
			result = s->_sound.sfx_poll_specific(handle, &cue);

		switch (result) {

		case SI_ABSOLUTE_CUE:
			signal = cue;
			debugC(2, kDebugLevelSound, "---    [CUE] %04x:%04x Absolute Cue: %d\n",
			          PRINT_REG(obj), signal);

			PUT_SEL32V(obj, signal, signal);
			break;

		case SI_RELATIVE_CUE:
			signal = cue;
			debugC(2, kDebugLevelSound, "---    [CUE] %04x:%04x Relative Cue: %d\n",
			          PRINT_REG(obj), cue);

			/* FIXME to match commented-out semantics
			 * below, with proper storage of dataInc and
			 * signal in the iterator code. */
			PUT_SEL32V(obj, dataInc, signal);
			PUT_SEL32V(obj, signal, signal);
			break;

		case SI_FINISHED:
			debugC(2, kDebugLevelSound, "---    [FINISHED] %04x:%04x\n", PRINT_REG(obj));
			PUT_SEL32V(obj, signal, 0xffff);
			break;

		case SI_LOOP:
			break; /* Doesn't happen */
		}

		/*		switch (signal) */
		/*		{ */
		/*		case 0x00: */
		/*			if (dataInc!=GET_SEL32V(obj, dataInc)) */
		/*			{ */
		/*				PUT_SEL32V(obj, dataInc, dataInc); */
		/*				PUT_SEL32V(obj, signal, dataInc+0x7f); */
		/*			} else */
		/*			{ */
		/*				PUT_SEL32V(obj, signal, signal); */
		/*			} */
		/*			break; */
		/*		case 0xFF: /\* May be unnecessary *\/ */
		/*			s->_sound.sfx_song_set_status(*/
		/*					    handle, SOUND_STATUS_STOPPED); */
		/*			break; */
		/*		default : */
		/*			if (dataInc!=GET_SEL32V(obj, dataInc)) */
		/*			{ */
		/*				PUT_SEL32V(obj, dataInc, dataInc); */
		/*				PUT_SEL32V(obj, signal, dataInc+0x7f); */
		/*			} else */
		/*			{ */
		/*				PUT_SEL32V(obj, signal, signal); */
		/*			} */
		/*			break; */
		/*		} */

		PUT_SEL32V(obj, min, min);
		PUT_SEL32V(obj, sec, sec);
		PUT_SEL32V(obj, frame, frame);
		break;
	}
	case _K_SCI01_SOUND_MIDI_SEND : {
		int channel = argv[2].toSint16();
		int midiCmd = argv[3].toUint16() == 0xff ?
		              0xe0 : /* Pitch wheel */
		              0xb0; /* argv[3].toUint16() is actually a controller number */
		int controller = argv[3].toUint16();
		int param = argv[4].toUint16();

		s->_sound.sfx_send_midi(handle,
		              channel, midiCmd, controller, param);
		break;
	}
	case _K_SCI01_SOUND_REVERB : {
		break;
	}
	case _K_SCI01_SOUND_HOLD : {
		//int flag = argv[2].toSint16();
		break;
	}
	}

	return s->r_acc;
}
예제 #9
0
reg_t kDoSound_SCI0(EngineState *s, int funct_nr, int argc, reg_t *argv) {
	reg_t obj = (argc > 1) ? argv[1] : NULL_REG;
	uint16 command = argv[0].toUint16();
	SongHandle handle = FROBNICATE_HANDLE(obj);
	int number = obj.segment ?
	             GET_SEL32V(obj, number) :
	             -1; /* We were not going to use it anyway */

#ifdef DEBUG_SOUND
	int i;

	debugC(2, kDebugLevelSound, "Command 0x%x", command);
	switch (command) {
	case 0:
		debugC(2, kDebugLevelSound, "[InitObj]");
		break;
	case 1:
		debugC(2, kDebugLevelSound, "[Play]");
		break;
	case 2:
		debugC(2, kDebugLevelSound, "[NOP]");
		break;
	case 3:
		debugC(2, kDebugLevelSound, "[DisposeHandle]");
		break;
	case 4:
		debugC(2, kDebugLevelSound, "[SetSoundOn(?)]");
		break;
	case 5:
		debugC(2, kDebugLevelSound, "[Stop]");
		break;
	case 6:
		debugC(2, kDebugLevelSound, "[Suspend]");
		break;
	case 7:
		debugC(2, kDebugLevelSound, "[Resume]");
		break;
	case 8:
		debugC(2, kDebugLevelSound, "[Get(Set?)Volume]");
		break;
	case 9:
		debugC(2, kDebugLevelSound, "[Signal: Obj changed]");
		break;
	case 10:
		debugC(2, kDebugLevelSound, "[Fade(?)]");
		break;
	case 11:
		debugC(2, kDebugLevelSound, "[ChkDriver]");
		break;
	case 12:
		debugC(2, kDebugLevelSound, "[PlayNextSong (formerly StopAll)]");
		break;
	default:
		debugC(2, kDebugLevelSound, "[unknown]");
		break;
	}

	debugC(2, kDebugLevelSound, "(");
	for (i = 1; i < argc; i++) {
		debugC(2, kDebugLevelSound, "%04x:%04x", PRINT_REG(argv[i]));
		if (i + 1 < argc)
			debugC(2, kDebugLevelSound, ", ");
	}
	debugC(2, kDebugLevelSound, ")\n");
#endif	// DEBUG_SOUND


	switch (command) {
	case _K_SCI0_SOUND_INIT_HANDLE:
		if (obj.segment) {
			debugC(2, kDebugLevelSound, "Initializing song number %d\n", GET_SEL32V(obj, number));
			s->_sound.sfx_add_song(build_iterator(s, number, SCI_SONG_ITERATOR_TYPE_SCI0,
			                                               handle), 0, handle, number);

			PUT_SEL32V(obj, state, _K_SOUND_STATUS_INITIALIZED);
			PUT_SEL32(obj, handle, obj); /* ``sound handle'': we use the object address */
		}
		break;

	case _K_SCI0_SOUND_PLAY_HANDLE:
		if (obj.segment) {
			s->_sound.sfx_song_set_status(handle, SOUND_STATUS_PLAYING);
			s->_sound.sfx_song_set_loops(handle, GET_SEL32V(obj, loop));
			PUT_SEL32V(obj, state, _K_SOUND_STATUS_PLAYING);
		}
		break;

	case _K_SCI0_SOUND_NOP:
		break;

	case _K_SCI0_SOUND_DISPOSE_HANDLE:
		if (obj.segment) {
			s->_sound.sfx_remove_song(handle);
		}
		PUT_SEL32V(obj, handle, 0x0000);
		break;

	case _K_SCI0_SOUND_STOP_HANDLE:
		if (obj.segment) {
			s->_sound.sfx_song_set_status(handle, SOUND_STATUS_STOPPED);
			PUT_SEL32V(obj, state, SOUND_STATUS_STOPPED);
		}
		break;

	case _K_SCI0_SOUND_SUSPEND_HANDLE:
		if (obj.segment) {
			s->_sound.sfx_song_set_status(handle, SOUND_STATUS_SUSPENDED);
			PUT_SEL32V(obj, state, SOUND_STATUS_SUSPENDED);
		}
		break;

	case _K_SCI0_SOUND_RESUME_HANDLE:
		if (obj.segment) {
			s->_sound.sfx_song_set_status(handle, SOUND_STATUS_PLAYING);
			PUT_SEL32V(obj, state, SOUND_STATUS_PLAYING);
		}
		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);*/

	}
	break;

	case _K_SCI0_SOUND_VOLUME: {
		/* range from 0x0 to 0xf */
		/* parameter optional. If present, set.*/
		int vol = (argc > 1) ? argv[1].toSint16() : -1;

		if (vol != -1)
			s->_sound.sfx_set_volume(vol << 0xf);
		else
			s->r_acc = make_reg(0, s->_sound.sfx_get_volume() >> 0xf);
	}
	break;

	case _K_SCI0_SOUND_UPDATE_VOL_PRI:
		if (obj.segment) {
			s->_sound.sfx_song_set_loops(handle, GET_SEL32V(obj, loop));
			script_set_priority(s, obj, GET_SEL32V(obj, pri));
		}
		break;

	case _K_SCI0_SOUND_FADE_HANDLE:
		/*s->sound_server->command(s, SOUND_COMMAND_FADE_HANDLE, obj, 120);*/ /* Fade out in 2 secs */
		/* FIXME: The next couple of lines actually STOP the handle, rather
		** than fading it! */
		if (obj.segment) {
			s->_sound.sfx_song_set_status(handle, SOUND_STATUS_STOPPED);
			PUT_SEL32V(obj, state, SOUND_STATUS_STOPPED);
			PUT_SEL32V(obj, signal, -1);
		}
		break;

	case _K_SCI0_SOUND_GET_POLYPHONY:
		s->r_acc = make_reg(0, sfx_get_player_polyphony());
		break;

	case _K_SCI0_SOUND_PLAY_NEXT:
		/* s->_sound.sfx_all_stop();*/
		break;

	default:
		warning("Unhandled DoSound command: %x", command);

	}
	//	process_sound_events(s); /* Take care of incoming events */

	return s->r_acc;
}
예제 #10
0
reg_t kDoSync(EngineState *s, int funct_nr, int argc, reg_t *argv) {
	switch (argv[0].toUint16()) {
	case kSciAudioSyncStart: {
		ResourceId id;

		if (s->_sound._syncResource) {
			s->resmgr->unlockResource(s->_sound._syncResource);
			s->_sound._syncResource = NULL;
		}

		// 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;
		}

		s->_sound._syncResource = s->resmgr->findResource(id, 1);

		if (s->_sound._syncResource) {
			PUT_SEL32V(argv[1], syncCue, 0);
			s->_sound._syncOffset = 0;
		} else {
			warning("DoSync: failed to find resource %s", id.toString().c_str());
			// Notify the scripts to stop sound sync
			PUT_SEL32V(argv[1], syncCue, -1);
		}
		break;
	}
	case kSciAudioSyncNext: {
		Resource *res = s->_sound._syncResource;
		if (res && (s->_sound._syncOffset < res->size - 1)) {
			int16 syncCue = -1;
			int16 syncTime = (int16)READ_LE_UINT16(res->data + s->_sound._syncOffset);

			s->_sound._syncOffset += 2;

			if ((syncTime != -1) && (s->_sound._syncOffset < res->size - 1)) {
				syncCue = (int16)READ_LE_UINT16(res->data + s->_sound._syncOffset);
				s->_sound._syncOffset += 2;
			}

			PUT_SEL32V(argv[1], syncTime, syncTime);
			PUT_SEL32V(argv[1], syncCue, syncCue);
		}
		break;
	}
	case kSciAudioSyncStop:
		if (s->_sound._syncResource) {
			s->resmgr->unlockResource(s->_sound._syncResource);
			s->_sound._syncResource = NULL;
		}
		break;
	default:
		warning("DoSync: Unhandled subfunction %d", argv[0].toUint16());
	}

	return s->r_acc;
}